summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--NEWS6
-rw-r--r--metaentry.c49
-rw-r--r--metaentry.h2
-rw-r--r--metastore.19
-rw-r--r--metastore.c15
-rw-r--r--metastore.h1
7 files changed, 79 insertions, 5 deletions
diff --git a/Makefile b/Makefile
index 4ee6fb7..7eaa7c2 100644
--- a/Makefile
+++ b/Makefile
@@ -19,7 +19,7 @@
#
CC = gcc
CFLAGS += -g -Wall -pedantic -std=c99 -D_FILE_OFFSET_BITS=64 -O2
-LDFLAGS +=
+LDFLAGS += -lbsd
INCLUDES =
INSTALL = install -c
INSTALL_PROGRAM = ${INSTALL}
diff --git a/NEWS b/NEWS
index 4dbd0f5..7cf7a77 100644
--- a/NEWS
+++ b/NEWS
@@ -7,6 +7,10 @@ Latest stuff (planned release date: 2015-09-??)
* Empty directories not present in metadata can be now removed when
applying stored metadata if -E / --remove-empty-dirs option is used.
+ * Stored metadata (in .metadata file by default) and real metadata
+ (from filesystem) can be now dumped in human-readable form using new
+ action: -d / --dump. Please do not rely on its current format!
+
* Scripts in example/ directory do not require bash anymore and there
is a new example for post checkout hook.
@@ -14,6 +18,8 @@ Latest stuff (planned release date: 2015-09-??)
As long as your libc provides sys/xattr.h (glibc does it since v2.3),
everything should be fine.
+ * Dependency on libbsd has been added. It's used by dump action.
+
Old times (2007-2014)
------------------------------------------------------------------------
diff --git a/metaentry.c b/metaentry.c
index 2064f29..f3ba692 100644
--- a/metaentry.c
+++ b/metaentry.c
@@ -32,6 +32,8 @@
#include <fcntl.h>
#include <stdint.h>
#include <errno.h>
+#include <bsd/string.h>
+#include <time.h>
#include "metastore.h"
#include "metaentry.h"
@@ -626,3 +628,50 @@ mentries_compare(struct metahash *mhashreal,
}
}
+/* Dumps given metadata */
+void
+mentries_dump(struct metahash *mhash)
+{
+ const struct metaentry *mentry;
+ char mode[11 + 1] = "";
+ char date[12 + 2 + 2 + 2*1 + 1 + 2 + 2 + 2 + 2*1 + 1] = "";
+ char zone[5 + 1] = "";
+ struct tm cal;
+
+ for (int key = 0; key < HASH_INDEXES; key++) {
+ for (mentry = mhash->bucket[key]; mentry; mentry = mentry->next) {
+ strmode(mentry->mode, mode);
+ localtime_r(&mentry->mtime, &cal);
+ strftime(date, sizeof(date), "%F %T", &cal);
+ strftime(zone, sizeof(zone), "%z", &cal);
+ printf("%s\t%s\t%s\t%s.%09ld %s\t%s%s\n",
+ mode,
+ mentry->owner, mentry->group,
+ date, mentry->mtimensec, zone,
+ mentry->path, S_ISDIR(mentry->mode) ? "/" : "");
+ for (int i = 0; i < mentry->xattrs; i++) {
+ printf("\t\t\t\t%s%s\t%s=",
+ mentry->path, S_ISDIR(mentry->mode) ? "/" : "",
+ mentry->xattr_names[i]);
+ ssize_t p = 0;
+ for (; p < mentry->xattr_lvalues[i]; p++) {
+ const char ch = mentry->xattr_values[i][p];
+ if ((unsigned)(ch - 32) > 126 - 32) {
+ p = -1;
+ break;
+ }
+ }
+ if (p >= 0)
+ printf("\"%.*s\"\n",
+ (int)mentry->xattr_lvalues[i],
+ mentry->xattr_values[i]);
+ else {
+ printf("0x");
+ for (p = 0; p < mentry->xattr_lvalues[i]; p++)
+ printf("%02hhx", (char)mentry->xattr_values[i][p]);
+ printf("\n");
+ }
+ }
+ }
+ }
+}
diff --git a/metaentry.h b/metaentry.h
index f402bc7..666c5af 100644
--- a/metaentry.h
+++ b/metaentry.h
@@ -92,4 +92,6 @@ void mentries_compare(struct metahash *mhashreal,
int cmp),
msettings *st);
+void mentries_dump(struct metahash *mhash);
+
#endif /* METAENTRY_H */
diff --git a/metastore.1 b/metastore.1
index d6c561e..7651b91 100644
--- a/metastore.1
+++ b/metastore.1
@@ -26,6 +26,15 @@ Saves the current metadata to ./.metadata or to the specified file
.B \-a, \-\-apply
Attempts to apply the stored metadata to the file system.
.TP
+.B \-d, \-\-dump
+Dumps stored (if no \fIPATH\fR is given) or real metadata (if \fIPATH\fR is
+present, e.g. \fB./\fR) in human-readable form.
+
+This action is meant only as a helpful debugging facility or merge conflict
+helper. Do not ever compare its output generated using different metastore
+version. Do not rely on current output format (especially in batch scripts),
+because it may change in future without prior notice.
+.TP
.B \-h, \-\-help
Prints a help message and exits.
.\"
diff --git a/metastore.c b/metastore.c
index ec3083f..2956cab 100644
--- a/metastore.c
+++ b/metastore.c
@@ -407,6 +407,8 @@ usage(const char *arg0, const char *message)
" -c, --compare Show differences between stored and real metadata\n"
" -s, --save Save current metadata\n"
" -a, --apply Apply stored metadata\n"
+" -d, --dump Dump stored (if no PATH is given) or real metadata\n"
+" (if PATH is present, e.g. ./) in human-readable form\n"
" -h, --help Help message (this text)\n"
"\n"
"Valid OPTIONS are:\n"
@@ -427,6 +429,7 @@ static struct option long_options[] = {
{ "compare", no_argument, NULL, 'c' },
{ "save", no_argument, NULL, 's' },
{ "apply", no_argument, NULL, 'a' },
+ { "dump", no_argument, NULL, 'd' },
{ "help", no_argument, NULL, 'h' },
{ "verbose", no_argument, NULL, 'v' },
{ "quiet", no_argument, NULL, 'q' },
@@ -451,7 +454,7 @@ main(int argc, char **argv)
i = 0;
while (1) {
int option_index = 0;
- c = getopt_long(argc, argv, "csahvqmeEgf:",
+ c = getopt_long(argc, argv, "csadhvqmeEgf:",
long_options, &option_index);
if (c == -1)
break;
@@ -459,6 +462,7 @@ main(int argc, char **argv)
case 'c': /* compare */ action |= ACTION_DIFF; i++; break;
case 's': /* save */ action |= ACTION_SAVE; i++; break;
case 'a': /* apply */ action |= ACTION_APPLY; i++; break;
+ case 'd': /* dump */ action |= ACTION_DUMP; i++; break;
case 'h': /* help */ action |= ACTION_HELP; i++; break;
case 'v': /* verbose */ adjust_verbosity(1); break;
case 'q': /* quiet */ adjust_verbosity(-1); break;
@@ -489,7 +493,7 @@ main(int argc, char **argv)
usage(argv[0], NULL);
/* Perform action */
- if (action & ACTIONS_READING) {
+ if (action & ACTIONS_READING && !(action == ACTION_DUMP && optind < argc)) {
mentries_fromfile(&stored, settings.metafile);
if (!stored) {
msg(MSG_CRITICAL, "Failed to load metadata from %s\n",
@@ -501,11 +505,11 @@ main(int argc, char **argv)
if (optind < argc) {
while (optind < argc)
mentries_recurse_path(argv[optind++], &real, &settings);
- } else {
+ } else if (action != ACTION_DUMP) {
mentries_recurse_path(".", &real, &settings);
}
- if (!real) {
+ if (!real && (action != ACTION_DUMP || optind < argc)) {
msg(MSG_CRITICAL,
"Failed to load metadata from file system\n");
exit(EXIT_FAILURE);
@@ -525,6 +529,9 @@ main(int argc, char **argv)
if (settings.do_removeemptydirs)
fixup_newemptydirs();
break;
+ case ACTION_DUMP:
+ mentries_dump(real ? real : stored);
+ break;
}
exit(EXIT_SUCCESS);
diff --git a/metastore.h b/metastore.h
index 9dbd19e..384808d 100644
--- a/metastore.h
+++ b/metastore.h
@@ -32,6 +32,7 @@
/* Utility defines for the action to take */
#define ACTION_APPLY 0x01
#define ACTION_DIFF 0x02
+#define ACTION_DUMP 0x04
#define ACTION_SAVE 0x10
#define ACTION_HELP 0x80