From 5c7cac85c9324a201b4a5d426903f4b5b0e497c7 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Wed, 17 Feb 2021 11:48:03 +0100 Subject: [PATCH] hardlink: fix indention The original Julian's hardlink.c code is pretty readable, but for util-linux we use a little different indention (aka Linux kernel coding style). Signed-off-by: Karel Zak --- misc-utils/hardlink.c | 1165 +++++++++++++++++++++-------------------- 1 file changed, 591 insertions(+), 574 deletions(-) diff --git a/misc-utils/hardlink.c b/misc-utils/hardlink.c index ef2852a19..2a1fd6f6f 100644 --- a/misc-utils/hardlink.c +++ b/misc-utils/hardlink.c @@ -23,19 +23,19 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -#define _POSIX_C_SOURCE 200112L /* POSIX functions */ -#define _XOPEN_SOURCE 600 /* nftw() */ +#define _POSIX_C_SOURCE 200112L /* POSIX functions */ +#define _XOPEN_SOURCE 600 /* nftw() */ -#include /* stat */ -#include /* stat */ -#include /* getrlimit, getrusage */ -#include /* getrlimit, getrusage */ -#include /* posix_fadvise */ -#include /* ftw */ -#include /* tsearch() and friends */ +#include /* stat */ +#include /* stat */ +#include /* getrlimit, getrusage */ +#include /* getrlimit, getrusage */ +#include /* posix_fadvise */ +#include /* ftw */ +#include /* tsearch() and friends */ #include /* SIG*, sigaction */ #include /* getopt_long() */ -#include /* tolower() */ +#include /* tolower() */ #include "nls.h" #include "c.h" @@ -48,13 +48,13 @@ #ifdef HAVE_PCRE2_POSIX # include # undef REG_NOSUB -# define REG_NOSUB 0 /* we do want backreferences in PCRE mode */ +# define REG_NOSUB 0 /* we do want backreferences in PCRE mode */ #else -# include /* regcomp(), regsearch() */ +# include /* regcomp(), regsearch() */ #endif #ifdef HAVE_SYS_XATTR_H -# include /* listxattr, getxattr */ +# include /* listxattr, getxattr */ #endif static int quiet; /* don't print anything */ @@ -69,19 +69,19 @@ static int quiet; /* don't print anything */ * This contains all information we need about a file. */ struct file { - struct stat st; - struct file *next; - struct link { - struct link *next; - int basename; + struct stat st; + struct file *next; + struct link { + struct link *next; + int basename; #if __STDC_VERSION__ >= 199901L - char path[]; + char path[]; #elif __GNUC__ - char path[0]; + char path[0]; #else - char path[1]; + char path[1]; #endif - } *links; + } *links; }; /** @@ -92,10 +92,10 @@ struct file { * @JLOG_VERBOSE2: Verbosity 3 */ enum log_level { - JLOG_SUMMARY, - JLOG_INFO, - JLOG_VERBOSE1, - JLOG_VERBOSE2 + JLOG_SUMMARY, + JLOG_INFO, + JLOG_VERBOSE1, + JLOG_VERBOSE2 }; /** @@ -109,13 +109,13 @@ enum log_level { * @start_time: The time we started at */ static struct statistics { - int started; - size_t files; - size_t linked; - size_t xattr_comparisons; - size_t comparisons; - double saved; - struct timeval start_time; + int started; + size_t files; + size_t linked; + size_t xattr_comparisons; + size_t comparisons; + double saved; + struct timeval start_time; } stats; /** @@ -135,29 +135,30 @@ static struct statistics { * @min_size: Minimum size of files to consider. (default = 1 byte) */ static struct options { - struct regex_link { - regex_t preg; - struct regex_link *next; - } *include, *exclude; - signed int verbosity; - unsigned int respect_mode:1; - unsigned int respect_owner:1; - unsigned int respect_name:1; - unsigned int respect_time:1; - unsigned int respect_xattrs:1; - unsigned int maximise:1; - unsigned int minimise:1; - unsigned int keep_oldest:1; - unsigned int dry_run:1; - uintmax_t min_size; + struct regex_link { + regex_t preg; + struct regex_link *next; + } *include, *exclude; + + signed int verbosity; + unsigned int respect_mode:1; + unsigned int respect_owner:1; + unsigned int respect_name:1; + unsigned int respect_time:1; + unsigned int respect_xattrs:1; + unsigned int maximise:1; + unsigned int minimise:1; + unsigned int keep_oldest:1; + unsigned int dry_run:1; + uintmax_t min_size; } opts = { - /* default setting */ - .respect_mode = TRUE, - .respect_owner = TRUE, - .respect_time = TRUE, - .respect_xattrs = FALSE, - .keep_oldest = FALSE, - .min_size = 1 + /* default setting */ + .respect_mode = TRUE, + .respect_owner = TRUE, + .respect_time = TRUE, + .respect_xattrs = FALSE, + .keep_oldest = FALSE, + .min_size = 1 }; /* @@ -182,18 +183,18 @@ static int last_signal; * @level: The log level * @format: A format string for printf() */ -__attribute__ ((format(printf, 2, 3))) +__attribute__((format(printf, 2, 3))) static void jlog(enum log_level level, const char *format, ...) { - va_list args; + va_list args; - if (quiet || level > (unsigned int) opts.verbosity) - return; + if (quiet || level > (unsigned int)opts.verbosity) + return; - va_start(args, format); - vfprintf(stdout, format, args); - va_end(args); - fputc('\n', stdout); + va_start(args, format); + vfprintf(stdout, format, args); + va_end(args); + fputc('\n', stdout); } /** @@ -215,10 +216,11 @@ static void jlog(enum log_level level, const char *format, ...) */ static int regexec_any(struct regex_link *pregs, const char *what) { - for (; pregs != NULL; pregs = pregs->next) - if (regexec(&pregs->preg, what, 0, NULL, 0) == 0) - return TRUE; - return FALSE; + for (; pregs != NULL; pregs = pregs->next) { + if (regexec(&pregs->preg, what, 0, NULL, 0) == 0) + return TRUE; + } + return FALSE; } /** @@ -230,16 +232,16 @@ static int regexec_any(struct regex_link *pregs, const char *what) */ static int compare_nodes(const void *_a, const void *_b) { - const struct file *a = _a; - const struct file *b = _b; - int diff = 0; + const struct file *a = _a; + const struct file *b = _b; + int diff = 0; - if (diff == 0) - diff = CMP(a->st.st_dev, b->st.st_dev); - if (diff == 0) - diff = CMP(a->st.st_size, b->st.st_size); + if (diff == 0) + diff = CMP(a->st.st_dev, b->st.st_dev); + if (diff == 0) + diff = CMP(a->st.st_size, b->st.st_size); - return diff; + return diff; } /** @@ -251,23 +253,23 @@ static int compare_nodes(const void *_a, const void *_b) */ static int compare_nodes_ino(const void *_a, const void *_b) { - const struct file *a = _a; - const struct file *b = _b; - int diff = 0; + const struct file *a = _a; + const struct file *b = _b; + int diff = 0; - if (diff == 0) - diff = CMP(a->st.st_dev, b->st.st_dev); - if (diff == 0) - diff = CMP(a->st.st_ino, b->st.st_ino); + if (diff == 0) + diff = CMP(a->st.st_dev, b->st.st_dev); + if (diff == 0) + diff = CMP(a->st.st_ino, b->st.st_ino); - /* If opts.respect_name is used, we will restrict a struct file to - * contain only links with the same basename to keep the rest simple. - */ - if (diff == 0 && opts.respect_name) - diff = strcmp(a->links->path + a->links->basename, - b->links->path + b->links->basename); + /* If opts.respect_name is used, we will restrict a struct file to + * contain only links with the same basename to keep the rest simple. + */ + if (diff == 0 && opts.respect_name) + diff = strcmp(a->links->path + a->links->basename, + b->links->path + b->links->basename); - return diff; + return diff; } /** @@ -275,30 +277,33 @@ static int compare_nodes_ino(const void *_a, const void *_b) */ static void print_stats(void) { - struct timeval end = { 0, 0 }, delta = { 0, 0 }; - char *ssz; + struct timeval end = { 0, 0 }, delta = { 0, 0 }; + char *ssz; - gettime_monotonic(&end); - timersub(&end, &stats.start_time, &delta); + gettime_monotonic(&end); + timersub(&end, &stats.start_time, &delta); + + jlog(JLOG_SUMMARY, "%-15s %s", _("Mode:"), + opts.dry_run ? _("dry-run") : _("real")); + jlog(JLOG_SUMMARY, "%-15s %zu", _("Files:"), stats.files); + jlog(JLOG_SUMMARY, _("%-15s %zu files"), _("Linked:"), stats.linked); - jlog(JLOG_SUMMARY, "%-15s %s", _("Mode:"), - opts.dry_run ? _("dry-run") : _("real")); - jlog(JLOG_SUMMARY, "%-15s %zu", _("Files:"), stats.files); - jlog(JLOG_SUMMARY, _("%-15s %zu files"), _("Linked:"), stats.linked); #ifdef HAVE_SYS_XATTR_H - jlog(JLOG_SUMMARY, _("%-15s %zu xattrs"), _("Compared:"), stats.xattr_comparisons); + jlog(JLOG_SUMMARY, _("%-15s %zu xattrs"), _("Compared:"), + stats.xattr_comparisons); #endif - jlog(JLOG_SUMMARY, _("%-15s %zu files"), _("Compared:"), stats.comparisons); + jlog(JLOG_SUMMARY, _("%-15s %zu files"), _("Compared:"), + stats.comparisons); - ssz = size_to_human_string(SIZE_SUFFIX_3LETTER| - SIZE_SUFFIX_SPACE| - SIZE_DECIMAL_2DIGITS, stats.saved); + ssz = size_to_human_string(SIZE_SUFFIX_3LETTER | + SIZE_SUFFIX_SPACE | + SIZE_DECIMAL_2DIGITS, stats.saved); - jlog(JLOG_SUMMARY, "%-15s %s", _("Saved:"), ssz); - free(ssz); + jlog(JLOG_SUMMARY, "%-15s %s", _("Saved:"), ssz); + free(ssz); - jlog(JLOG_SUMMARY, _("%-15s %ld.%06ld seconds"), _("Duration:"), - (long)delta.tv_sec, (long)delta.tv_usec); + jlog(JLOG_SUMMARY, _("%-15s %ld.%06ld seconds"), _("Duration:"), + (long)delta.tv_sec, (long)delta.tv_usec); } /** @@ -308,18 +313,18 @@ static void print_stats(void) */ static int handle_interrupt(void) { - switch (last_signal) { - case SIGINT: - case SIGTERM: - return TRUE; - case SIGUSR1: - print_stats(); - putchar('\n'); - break; - } + switch (last_signal) { + case SIGINT: + case SIGTERM: + return TRUE; + case SIGUSR1: + print_stats(); + putchar('\n'); + break; + } - last_signal = 0; - return FALSE; + last_signal = 0; + return FALSE; } #ifdef HAVE_SYS_XATTR_H @@ -332,12 +337,12 @@ static int handle_interrupt(void) */ static ssize_t llistxattr_or_die(const char *path, char *list, size_t size) { - ssize_t len = llistxattr(path, list, size); + ssize_t len = llistxattr(path, list, size); - if (len < 0 && errno != ENOTSUP) - err(EXIT_FAILURE, _("cannot get xattr names for %s"), path); + if (len < 0 && errno != ENOTSUP) + err(EXIT_FAILURE, _("cannot get xattr names for %s"), path); - return len; + return len; } /** @@ -345,15 +350,16 @@ static ssize_t llistxattr_or_die(const char *path, char *list, size_t size) * * This does the same thing as lgetxattr() except that it aborts upon error. */ -static ssize_t lgetxattr_or_die(const char *path, const char *name, void *value, - size_t size) +static ssize_t lgetxattr_or_die(const char *path, + const char *name, void *value, size_t size) { - ssize_t len = lgetxattr(path, name, value, size); + ssize_t len = lgetxattr(path, name, value, size); - if (len < 0) - err(EXIT_FAILURE, _("cannot get xattr value of %s for %s"), name, path); + if (len < 0) + err(EXIT_FAILURE, _("cannot get xattr value of %s for %s"), + name, path); - return len; + return len; } /** @@ -365,13 +371,13 @@ static ssize_t lgetxattr_or_die(const char *path, const char *name, void *value, */ static int get_xattr_name_count(const char *const names, ssize_t len) { - int count = 0; - const char *name; + int count = 0; + const char *name; - for (name = names; name < (names + len); name += strlen(name) + 1) - count++; + for (name = names; name < (names + len); name += strlen(name) + 1) + count++; - return count; + return count; } /** @@ -380,7 +386,7 @@ static int get_xattr_name_count(const char *const names, ssize_t len) */ static int cmp_xattr_name_ptrs(const void *ptr1, const void *ptr2) { - return strcmp(*(char *const *) ptr1, *(char *const *) ptr2); + return strcmp(*(char *const *)ptr1, *(char *const *)ptr2); } /** @@ -392,17 +398,17 @@ static int cmp_xattr_name_ptrs(const void *ptr1, const void *ptr2) */ static const char **get_sorted_xattr_name_table(const char *names, int n) { - const char **table = xmalloc(n * sizeof(char *)); - int i; + const char **table = xmalloc(n * sizeof(char *)); + int i; - for (i = 0; i < n; i++) { - table[i] = names; - names += strlen(names) + 1; - } + for (i = 0; i < n; i++) { + table[i] = names; + names += strlen(names) + 1; + } - qsort(table, n, sizeof(char *), cmp_xattr_name_ptrs); + qsort(table, n, sizeof(char *), cmp_xattr_name_ptrs); - return table; + return table; } /** @@ -414,102 +420,104 @@ static const char **get_sorted_xattr_name_table(const char *names, int n) */ static int file_xattrs_equal(const struct file *a, const struct file *b) { - ssize_t len_a; - ssize_t len_b; - char *names_a = NULL; - char *names_b = NULL; - int n_a; - int n_b; - const char **name_ptrs_a = NULL; - const char **name_ptrs_b = NULL; - void *value_a = NULL; - void *value_b = NULL; - int ret = FALSE; - int i; + ssize_t len_a; + ssize_t len_b; + char *names_a = NULL; + char *names_b = NULL; + int n_a; + int n_b; + const char **name_ptrs_a = NULL; + const char **name_ptrs_b = NULL; + void *value_a = NULL; + void *value_b = NULL; + int ret = FALSE; + int i; - assert(a->links != NULL); - assert(b->links != NULL); + assert(a->links != NULL); + assert(b->links != NULL); - jlog(JLOG_VERBOSE1, _("Comparing xattrs of %s to %s"), a->links->path, - b->links->path); + jlog(JLOG_VERBOSE1, _("Comparing xattrs of %s to %s"), a->links->path, + b->links->path); - stats.xattr_comparisons++; + stats.xattr_comparisons++; - len_a = llistxattr_or_die(a->links->path, NULL, 0); - len_b = llistxattr_or_die(b->links->path, NULL, 0); + len_a = llistxattr_or_die(a->links->path, NULL, 0); + len_b = llistxattr_or_die(b->links->path, NULL, 0); - if (len_a <= 0 && len_b <= 0) - return TRUE; // xattrs not supported or neither file has any + if (len_a <= 0 && len_b <= 0) + return TRUE; // xattrs not supported or neither file has any - if (len_a != len_b) - return FALSE; // total lengths of xattr names differ + if (len_a != len_b) + return FALSE; // total lengths of xattr names differ - names_a = xmalloc(len_a); - names_b = xmalloc(len_b); + names_a = xmalloc(len_a); + names_b = xmalloc(len_b); - len_a = llistxattr_or_die(a->links->path, names_a, len_a); - len_b = llistxattr_or_die(b->links->path, names_b, len_b); - assert((len_a > 0) && (len_a == len_b)); + len_a = llistxattr_or_die(a->links->path, names_a, len_a); + len_b = llistxattr_or_die(b->links->path, names_b, len_b); + assert((len_a > 0) && (len_a == len_b)); - n_a = get_xattr_name_count(names_a, len_a); - n_b = get_xattr_name_count(names_b, len_b); + n_a = get_xattr_name_count(names_a, len_a); + n_b = get_xattr_name_count(names_b, len_b); - if (n_a != n_b) - goto exit; // numbers of xattrs differ + if (n_a != n_b) + goto exit; // numbers of xattrs differ - name_ptrs_a = get_sorted_xattr_name_table(names_a, n_a); - name_ptrs_b = get_sorted_xattr_name_table(names_b, n_b); + name_ptrs_a = get_sorted_xattr_name_table(names_a, n_a); + name_ptrs_b = get_sorted_xattr_name_table(names_b, n_b); - // We now have two sorted tables of xattr names. + // We now have two sorted tables of xattr names. - for (i = 0; i < n_a; i++) { - if (handle_interrupt()) - goto exit; // user wants to quit + for (i = 0; i < n_a; i++) { + if (handle_interrupt()) + goto exit; // user wants to quit - if (strcmp(name_ptrs_a[i], name_ptrs_b[i]) != 0) - goto exit; // names at same slot differ + if (strcmp(name_ptrs_a[i], name_ptrs_b[i]) != 0) + goto exit; // names at same slot differ - len_a = lgetxattr_or_die(a->links->path, name_ptrs_a[i], NULL, 0); - len_b = lgetxattr_or_die(b->links->path, name_ptrs_b[i], NULL, 0); + len_a = + lgetxattr_or_die(a->links->path, name_ptrs_a[i], NULL, 0); + len_b = + lgetxattr_or_die(b->links->path, name_ptrs_b[i], NULL, 0); - if (len_a != len_b) - goto exit; // xattrs with same name, different value lengths + if (len_a != len_b) + goto exit; // xattrs with same name, different value lengths - value_a = xmalloc(len_a); - value_b = xmalloc(len_b); + value_a = xmalloc(len_a); + value_b = xmalloc(len_b); - len_a = lgetxattr_or_die(a->links->path, name_ptrs_a[i], - value_a, len_a); - len_b = lgetxattr_or_die(b->links->path, name_ptrs_b[i], - value_b, len_b); - assert((len_a >= 0) && (len_a == len_b)); + len_a = lgetxattr_or_die(a->links->path, name_ptrs_a[i], + value_a, len_a); + len_b = lgetxattr_or_die(b->links->path, name_ptrs_b[i], + value_b, len_b); + assert((len_a >= 0) && (len_a == len_b)); - if (memcmp(value_a, value_b, len_a) != 0) - goto exit; // xattrs with same name, different values + if (memcmp(value_a, value_b, len_a) != 0) + goto exit; // xattrs with same name, different values - free(value_a); - free(value_b); - value_a = NULL; - value_b = NULL; - } + free(value_a); + free(value_b); + value_a = NULL; + value_b = NULL; + } - ret = TRUE; + ret = TRUE; - exit: - free(names_a); - free(names_b); - free(name_ptrs_a); - free(name_ptrs_b); - free(value_a); - free(value_b); - return ret; + exit: + free(names_a); + free(names_b); + free(name_ptrs_a); + free(name_ptrs_b); + free(value_a); + free(value_b); + return ret; } -#else +#else /* !HAVE_SYS_XATTR_H */ static int file_xattrs_equal(const struct file *a, const struct file *b) { - return TRUE; + return TRUE; } -#endif +#endif /* HAVE_SYS_XATTR_H */ /** * file_contents_equal - Compare contents of two files for equality @@ -520,63 +528,65 @@ static int file_xattrs_equal(const struct file *a, const struct file *b) */ static int file_contents_equal(const struct file *a, const struct file *b) { - FILE *fa = NULL; - FILE *fb = NULL; - char buf_a[8192]; - char buf_b[8192]; - int cmp = 0; /* zero => equal */ - off_t off = 0; /* current offset */ + FILE *fa = NULL; + FILE *fb = NULL; + char buf_a[8192]; + char buf_b[8192]; + int cmp = 0; /* zero => equal */ + off_t off = 0; /* current offset */ - assert(a->links != NULL); - assert(b->links != NULL); + assert(a->links != NULL); + assert(b->links != NULL); - jlog(JLOG_VERBOSE1, _("Comparing %s to %s"), a->links->path, b->links->path); + jlog(JLOG_VERBOSE1, _("Comparing %s to %s"), a->links->path, + b->links->path); - stats.comparisons++; + stats.comparisons++; - if ((fa = fopen(a->links->path, "rb")) == NULL) - goto err; - if ((fb = fopen(b->links->path, "rb")) == NULL) - goto err; + if ((fa = fopen(a->links->path, "rb")) == NULL) + goto err; + if ((fb = fopen(b->links->path, "rb")) == NULL) + goto err; #if defined(POSIX_FADV_SEQUENTIAL) && defined(HAVE_POSIX_FADVISE) - posix_fadvise(fileno(fa), 0, 0, POSIX_FADV_SEQUENTIAL); - posix_fadvise(fileno(fb), 0, 0, POSIX_FADV_SEQUENTIAL); + posix_fadvise(fileno(fa), 0, 0, POSIX_FADV_SEQUENTIAL); + posix_fadvise(fileno(fb), 0, 0, POSIX_FADV_SEQUENTIAL); #endif - while (!handle_interrupt() && cmp == 0) { - size_t ca; - size_t cb; + while (!handle_interrupt() && cmp == 0) { + size_t ca; + size_t cb; - ca = fread(buf_a, 1, sizeof(buf_a), fa); - if (ca < sizeof(buf_a) && ferror(fa)) - goto err; + ca = fread(buf_a, 1, sizeof(buf_a), fa); + if (ca < sizeof(buf_a) && ferror(fa)) + goto err; - cb = fread(buf_b, 1, sizeof(buf_b), fb); - if (cb < sizeof(buf_b) && ferror(fb)) - goto err; + cb = fread(buf_b, 1, sizeof(buf_b), fb); + if (cb < sizeof(buf_b) && ferror(fb)) + goto err; - off += ca; + off += ca; - if ((ca != cb || ca == 0)) { - cmp = CMP(ca, cb); - break; - } - cmp = memcmp(buf_a, buf_b, ca); - } - out: - if (fa != NULL) - fclose(fa); - if (fb != NULL) - fclose(fb); - return !handle_interrupt() && cmp == 0; - err: - if (fa == NULL || fb == NULL) - warn(_("cannot open %s"), fa ? b->links->path : a->links->path); - else - warn(_("cannot read %s"), ferror(fa) ? a->links->path : b->links->path); - cmp = 1; - goto out; + if ((ca != cb || ca == 0)) { + cmp = CMP(ca, cb); + break; + } + cmp = memcmp(buf_a, buf_b, ca); + } + out: + if (fa != NULL) + fclose(fa); + if (fb != NULL) + fclose(fb); + return !handle_interrupt() && cmp == 0; + err: + if (fa == NULL || fb == NULL) + warn(_("cannot open %s"), fa ? b->links->path : a->links->path); + else + warn(_("cannot read %s"), + ferror(fa) ? a->links->path : b->links->path); + cmp = 1; + goto out; } /** @@ -590,20 +600,20 @@ static int file_contents_equal(const struct file *a, const struct file *b) */ static int file_may_link_to(const struct file *a, const struct file *b) { - return (a->st.st_size != 0 && - a->st.st_size == b->st.st_size && - a->links != NULL && b->links != NULL && - a->st.st_dev == b->st.st_dev && - a->st.st_ino != b->st.st_ino && - (!opts.respect_mode || a->st.st_mode == b->st.st_mode) && - (!opts.respect_owner || a->st.st_uid == b->st.st_uid) && - (!opts.respect_owner || a->st.st_gid == b->st.st_gid) && - (!opts.respect_time || a->st.st_mtime == b->st.st_mtime) && - (!opts.respect_name - || strcmp(a->links->path + a->links->basename, - b->links->path + b->links->basename) == 0) && - (!opts.respect_xattrs || file_xattrs_equal(a, b)) && - file_contents_equal(a, b)); + return (a->st.st_size != 0 && + a->st.st_size == b->st.st_size && + a->links != NULL && b->links != NULL && + a->st.st_dev == b->st.st_dev && + a->st.st_ino != b->st.st_ino && + (!opts.respect_mode || a->st.st_mode == b->st.st_mode) && + (!opts.respect_owner || a->st.st_uid == b->st.st_uid) && + (!opts.respect_owner || a->st.st_gid == b->st.st_gid) && + (!opts.respect_time || a->st.st_mtime == b->st.st_mtime) && + (!opts.respect_name + || strcmp(a->links->path + a->links->basename, + b->links->path + b->links->basename) == 0) && + (!opts.respect_xattrs || file_xattrs_equal(a, b)) && + file_contents_equal(a, b)); } /** @@ -617,21 +627,21 @@ static int file_may_link_to(const struct file *a, const struct file *b) */ static int file_compare(const struct file *a, const struct file *b) { - int res = 0; - if (a->st.st_dev == b->st.st_dev && a->st.st_ino == b->st.st_ino) - return 0; + int res = 0; + if (a->st.st_dev == b->st.st_dev && a->st.st_ino == b->st.st_ino) + return 0; - if (res == 0 && opts.maximise) - res = CMP(a->st.st_nlink, b->st.st_nlink); - if (res == 0 && opts.minimise) - res = CMP(b->st.st_nlink, a->st.st_nlink); - if (res == 0) - res = opts.keep_oldest ? CMP(b->st.st_mtime, a->st.st_mtime) - : CMP(a->st.st_mtime, b->st.st_mtime); - if (res == 0) - res = CMP(b->st.st_ino, a->st.st_ino); + if (res == 0 && opts.maximise) + res = CMP(a->st.st_nlink, b->st.st_nlink); + if (res == 0 && opts.minimise) + res = CMP(b->st.st_nlink, a->st.st_nlink); + if (res == 0) + res = opts.keep_oldest ? CMP(b->st.st_mtime, a->st.st_mtime) + : CMP(a->st.st_mtime, b->st.st_mtime); + if (res == 0) + res = CMP(b->st.st_ino, a->st.st_ino); - return res; + return res; } /** @@ -645,62 +655,67 @@ static int file_compare(const struct file *a, const struct file *b) */ static int file_link(struct file *a, struct file *b) { - char *ssz; + char *ssz; - file_link: - assert(a->links != NULL); - assert(b->links != NULL); + file_link: + assert(a->links != NULL); + assert(b->links != NULL); - ssz = size_to_human_string(SIZE_SUFFIX_3LETTER| - SIZE_SUFFIX_SPACE| - SIZE_DECIMAL_2DIGITS, a->st.st_size); - jlog(JLOG_INFO, _("%sLinking %s to %s (-%s)"), - opts.dry_run ? _("[DryRun] ") : "", a->links->path, b->links->path, ssz); - free(ssz); + ssz = size_to_human_string(SIZE_SUFFIX_3LETTER | + SIZE_SUFFIX_SPACE | + SIZE_DECIMAL_2DIGITS, a->st.st_size); + jlog(JLOG_INFO, _("%sLinking %s to %s (-%s)"), + opts.dry_run ? _("[DryRun] ") : "", a->links->path, b->links->path, + ssz); + free(ssz); - if (!opts.dry_run) { - size_t len = strlen(b->links->path) + strlen(".hardlink-temporary") + 1; - char *new_path = xmalloc(len); + if (!opts.dry_run) { + size_t len = + strlen(b->links->path) + strlen(".hardlink-temporary") + 1; + char *new_path = xmalloc(len); - snprintf(new_path, len, "%s.hardlink-temporary", b->links->path); + snprintf(new_path, len, "%s.hardlink-temporary", + b->links->path); - if (link(a->links->path, new_path) != 0) { - warn(_("cannot link %s to %s"), a->links->path, new_path); - free(new_path); - return FALSE; - } else if (rename(new_path, b->links->path) != 0) { - warn(_("cannot rename %s to %s"), a->links->path, new_path); - unlink(new_path); /* cleanup failed rename */ - free(new_path); - return FALSE; - } - free(new_path); - } + if (link(a->links->path, new_path) != 0) { + warn(_("cannot link %s to %s"), a->links->path, + new_path); + free(new_path); + return FALSE; + } else if (rename(new_path, b->links->path) != 0) { + warn(_("cannot rename %s to %s"), a->links->path, + new_path); + unlink(new_path); /* cleanup failed rename */ + free(new_path); + return FALSE; + } + free(new_path); + } - /* Update statistics */ - stats.linked++; + /* Update statistics */ + stats.linked++; - /* Increase the link count of this file, and set stat() of other file */ - a->st.st_nlink++; - b->st.st_nlink--; + /* Increase the link count of this file, and set stat() of other file */ + a->st.st_nlink++; + b->st.st_nlink--; - if (b->st.st_nlink == 0) - stats.saved += a->st.st_size; + if (b->st.st_nlink == 0) + stats.saved += a->st.st_size; - /* Move the link from file b to a */ - { - struct link *new_link = b->links; + /* Move the link from file b to a */ + { + struct link *new_link = b->links; - b->links = b->links->next; - new_link->next = a->links->next; - a->links->next = new_link; - } + b->links = b->links->next; + new_link->next = a->links->next; + a->links->next = new_link; + } - // Do it again - if (b->links) - goto file_link; + /* Do it again */ + if (b->links) + goto file_link; - return TRUE; + return TRUE; } /** @@ -713,95 +728,97 @@ static int file_link(struct file *a, struct file *b) * Called by nftw() for the files. See the manual page for nftw() for * further information. */ -static int inserter(const char *fpath, const struct stat *sb, int typeflag, - struct FTW *ftwbuf) +static int inserter(const char *fpath, const struct stat *sb, + int typeflag, struct FTW *ftwbuf) { - struct file *fil; - struct file **node; - size_t pathlen; - int included; - int excluded; + struct file *fil; + struct file **node; + size_t pathlen; + int included; + int excluded; - if (handle_interrupt()) - return 1; - if (typeflag == FTW_DNR || typeflag == FTW_NS) - warn(_("cannot read %s"), fpath); - if (typeflag != FTW_F || !S_ISREG(sb->st_mode)) - return 0; + if (handle_interrupt()) + return 1; + if (typeflag == FTW_DNR || typeflag == FTW_NS) + warn(_("cannot read %s"), fpath); + if (typeflag != FTW_F || !S_ISREG(sb->st_mode)) + return 0; - included = regexec_any(opts.include, fpath); - excluded = regexec_any(opts.exclude, fpath); + included = regexec_any(opts.include, fpath); + excluded = regexec_any(opts.exclude, fpath); - if ((opts.exclude && excluded && !included) || - (!opts.exclude && opts.include && !included)) - return 0; + if ((opts.exclude && excluded && !included) || + (!opts.exclude && opts.include && !included)) + return 0; - stats.files++; + stats.files++; - if ((uintmax_t) sb->st_size < opts.min_size) { - jlog(JLOG_VERBOSE1, _("Skipped %s (smaller than configured size)"), fpath); - return 0; - } + if ((uintmax_t) sb->st_size < opts.min_size) { + jlog(JLOG_VERBOSE1, + _("Skipped %s (smaller than configured size)"), fpath); + return 0; + } - jlog(JLOG_VERBOSE2, _("Visiting %s (file %zu)"), fpath, stats.files); + jlog(JLOG_VERBOSE2, _("Visiting %s (file %zu)"), fpath, stats.files); - pathlen = strlen(fpath) + 1; + pathlen = strlen(fpath) + 1; - fil = xcalloc(1, sizeof(*fil)); - fil->links = xcalloc(1, sizeof(struct link) + pathlen); + fil = xcalloc(1, sizeof(*fil)); + fil->links = xcalloc(1, sizeof(struct link) + pathlen); - fil->st = *sb; - fil->links->basename = ftwbuf->base; - fil->links->next = NULL; + fil->st = *sb; + fil->links->basename = ftwbuf->base; + fil->links->next = NULL; - memcpy(fil->links->path, fpath, pathlen); + memcpy(fil->links->path, fpath, pathlen); - node = tsearch(fil, &files_by_ino, compare_nodes_ino); + node = tsearch(fil, &files_by_ino, compare_nodes_ino); - if (node == NULL) - goto fail; + if (node == NULL) + goto fail; - if (*node != fil) { - /* Already known inode, add link to inode information */ - assert((*node)->st.st_dev == sb->st_dev); - assert((*node)->st.st_ino == sb->st_ino); + if (*node != fil) { + /* Already known inode, add link to inode information */ + assert((*node)->st.st_dev == sb->st_dev); + assert((*node)->st.st_ino == sb->st_ino); - fil->links->next = (*node)->links; - (*node)->links = fil->links; + fil->links->next = (*node)->links; + (*node)->links = fil->links; - free(fil); - } else { - /* New inode, insert into by-size table */ - node = tsearch(fil, &files, compare_nodes); + free(fil); + } else { + /* New inode, insert into by-size table */ + node = tsearch(fil, &files, compare_nodes); - if (node == NULL) - goto fail; + if (node == NULL) + goto fail; - if (*node != fil) { - struct file *l; + if (*node != fil) { + struct file *l; - if (file_compare(fil, *node) >= 0) { - fil->next = *node; - *node = fil; - } else { - for (l = *node; l != NULL; l = l->next) { - if (l->next != NULL && file_compare(fil, l->next) < 0) - continue; + if (file_compare(fil, *node) >= 0) { + fil->next = *node; + *node = fil; + } else { + for (l = *node; l != NULL; l = l->next) { + if (l->next != NULL + && file_compare(fil, l->next) < 0) + continue; - fil->next = l->next; - l->next = fil; + fil->next = l->next; + l->next = fil; - break; - } - } - } - } + break; + } + } + } + } - return 0; + return 0; -fail: - warn(_("cannot continue")); /* probably ENOMEM */ - return 0; + fail: + warn(_("cannot continue")); /* probably ENOMEM */ + return 0; } /** @@ -816,34 +833,35 @@ fail: */ static void visitor(const void *nodep, const VISIT which, const int depth) { - struct file *master = *(struct file **) nodep; - struct file *other; + struct file *master = *(struct file **)nodep; + struct file *other; - (void) depth; + (void)depth; - if (which != leaf && which != endorder) - return; + if (which != leaf && which != endorder) + return; - for (; master != NULL; master = master->next) { - if (handle_interrupt()) - exit(EXIT_FAILURE); - if (master->links == NULL) - continue; + for (; master != NULL; master = master->next) { + if (handle_interrupt()) + exit(EXIT_FAILURE); + if (master->links == NULL) + continue; - for (other = master->next; other != NULL; other = other->next) { - if (handle_interrupt()) - exit(EXIT_FAILURE); + for (other = master->next; other != NULL; other = other->next) { + if (handle_interrupt()) + exit(EXIT_FAILURE); - assert(other != other->next); - assert(other->st.st_size == master->st.st_size); + assert(other != other->next); + assert(other->st.st_size == master->st.st_size); - if (other->links == NULL || !file_may_link_to(master, other)) - continue; + if (other->links == NULL + || !file_may_link_to(master, other)) + continue; - if (!file_link(master, other) && errno == EMLINK) - master = other; - } - } + if (!file_link(master, other) && errno == EMLINK) + master = other; + } + } } /** @@ -851,41 +869,41 @@ static void visitor(const void *nodep, const VISIT which, const int depth) */ static void __attribute__((__noreturn__)) usage(void) { - FILE *out = stdout; + FILE *out = stdout; - fputs(USAGE_HEADER, out); - fprintf(out, _(" %s [options] | ...\n"), program_invocation_short_name); + fputs(USAGE_HEADER, out); + fprintf(out, _(" %s [options] | ...\n"), + program_invocation_short_name); - fputs(USAGE_SEPARATOR, out); - fputs(_("Consolidate duplicate files using hardlinks.\n"), out); + fputs(USAGE_SEPARATOR, out); + fputs(_("Consolidate duplicate files using hardlinks.\n"), out); - fputs(USAGE_OPTIONS, out); - fputs(_(" -v, --verbose verbose output (repeat for more verbosity)\n"), out); - fputs(_(" -q, --quiet quiet mode - don't print anything\n" - fputs(_(" -n, --dry-run don't actually link anything\n"), out); - fputs(_(" -f, --respect-name filenames have to be identical\n"), out); - fputs(_(" -p, --ignore-mode ignore changes of file mode\n"), out); - fputs(_(" -o, --ignore-owner ignore owner changes\n"), out); - fputs(_(" -t, --ignore-time ignore timestamps (when testing for equality)\n"), out); + fputs(USAGE_OPTIONS, out); + fputs(_(" -v, --verbose verbose output (repeat for more verbosity)\n"), out); + fputs(_(" -q, --quiet quiet mode - don't print anything\n"), out); + fputs(_(" -n, --dry-run don't actually link anything\n"), out); + fputs(_(" -f, --respect-name filenames have to be identical\n"), out); + fputs(_(" -p, --ignore-mode ignore changes of file mode\n"), out); + fputs(_(" -o, --ignore-owner ignore owner changes\n"), out); + fputs(_(" -t, --ignore-time ignore timestamps (when testing for equality)\n"), out); #ifdef HAVE_SYS_XATTR_H - fputs(_(" -X, --respect-xattrs respect extended attributes\n"), out); + fputs(_(" -X, --respect-xattrs respect extended attributes\n"), out); #endif - fputs(_(" -m, --maximize maximize the hardlink count, remove the file with\n" - " lowest hardlink count\n"), out); - fputs(_(" -M, --minimize reverse the meaning of -m\n"), out); - fputs(_(" -O, --keep-oldest keep the oldest file of multiple equal files\n" - " (lower precedence than minimize/maximize)\n"), out); - fputs(_(" -x, --exclude regular expression to exclude files\n"), out); - fputs(_(" -i, --include regular expression to include files/dirs\n"), out); - fputs(_(" -s, --minimum-size minimum size for files.\n"), out); - fputs(_(" -c, --content compare only file contents, same as -pot\n"), out); + fputs(_(" -m, --maximize maximize the hardlink count, remove the file with\n" + " lowest hardlink count\n"), out); + fputs(_(" -M, --minimize reverse the meaning of -m\n"), out); + fputs(_(" -O, --keep-oldest keep the oldest file of multiple equal files\n" + " (lower precedence than minimize/maximize)\n"), out); + fputs(_(" -x, --exclude regular expression to exclude files\n"), out); + fputs(_(" -i, --include regular expression to include files/dirs\n"), out); + fputs(_(" -s, --minimum-size minimum size for files.\n"), out); + fputs(_(" -c, --content compare only file contents, same as -pot\n"), out); - fputs(USAGE_SEPARATOR, out); - printf(USAGE_HELP_OPTIONS(28)); + fputs(USAGE_SEPARATOR, out); + printf(USAGE_HELP_OPTIONS(28)); + printf(USAGE_MAN_TAIL("hardlink(1)")); - printf(USAGE_MAN_TAIL("hardlink(1)")); - - exit(EXIT_SUCCESS); + exit(EXIT_SUCCESS); } /** @@ -895,21 +913,21 @@ static void __attribute__((__noreturn__)) usage(void) */ static void register_regex(struct regex_link **pregs, const char *regex) { - struct regex_link *link = xmalloc(sizeof(*link)); - int err; + struct regex_link *link; + int err; - if ((err = regcomp(&link->preg, regex, REG_NOSUB | REG_EXTENDED)) != 0) { - size_t size = regerror(err, &link->preg, NULL, 0); - char *buf = xmalloc(size + 1); + link = xmalloc(sizeof(*link)); - regerror(err, &link->preg, buf, size); + if ((err = regcomp(&link->preg, regex, REG_NOSUB | REG_EXTENDED)) != 0) { + size_t size = regerror(err, &link->preg, NULL, 0); + char *buf = xmalloc(size + 1); - errx(EXIT_FAILURE, _("could not compile regular expression %s: %s"), - regex, buf); - } + regerror(err, &link->preg, buf, size); - link->next = *pregs; - *pregs = link; + errx(EXIT_FAILURE, _("could not compile regular expression %s: %s"), + regex, buf); + } + link->next = *pregs; *pregs = link; } /** @@ -919,152 +937,151 @@ static void register_regex(struct regex_link **pregs, const char *regex) */ static int parse_options(int argc, char *argv[]) { - static const char optstr[] = "VhvnfpotXcmMOx:i:s:q"; - static const struct option long_options[] = { - {"version", no_argument, NULL, 'V'}, - {"help", no_argument, NULL, 'h'}, - {"verbose", no_argument, NULL, 'v'}, - {"dry-run", no_argument, NULL, 'n'}, - {"respect-name", no_argument, NULL, 'f'}, - {"ignore-mode", no_argument, NULL, 'p'}, - {"ignore-owner", no_argument, NULL, 'o'}, - {"ignore-time", no_argument, NULL, 't'}, - {"respect-xattrs", no_argument, NULL, 'X'}, - {"maximize", no_argument, NULL, 'm'}, - {"minimize", no_argument, NULL, 'M'}, - {"keep-oldest", no_argument, NULL, 'O'}, - {"exclude", required_argument, NULL, 'x'}, - {"include", required_argument, NULL, 'i'}, - {"minimum-size", required_argument, NULL, 's'}, - {"content", no_argument, NULL, 'c'}, - {"quiet", no_argument, NULL, 'q'}, - {NULL, 0, NULL, 0} - }; - static const ul_excl_t excl[] = { - { 'q','v' }, - { 0 } - }; - int excl_st[ARRAY_SIZE(excl)] = UL_EXCL_STATUS_INIT; - int c; + static const char optstr[] = "VhvnfpotXcmMOx:i:s:q"; + static const struct option long_options[] = { + {"version", no_argument, NULL, 'V'}, + {"help", no_argument, NULL, 'h'}, + {"verbose", no_argument, NULL, 'v'}, + {"dry-run", no_argument, NULL, 'n'}, + {"respect-name", no_argument, NULL, 'f'}, + {"ignore-mode", no_argument, NULL, 'p'}, + {"ignore-owner", no_argument, NULL, 'o'}, + {"ignore-time", no_argument, NULL, 't'}, + {"respect-xattrs", no_argument, NULL, 'X'}, + {"maximize", no_argument, NULL, 'm'}, + {"minimize", no_argument, NULL, 'M'}, + {"keep-oldest", no_argument, NULL, 'O'}, + {"exclude", required_argument, NULL, 'x'}, + {"include", required_argument, NULL, 'i'}, + {"minimum-size", required_argument, NULL, 's'}, + {"content", no_argument, NULL, 'c'}, + {"quiet", no_argument, NULL, 'q'}, + {NULL, 0, NULL, 0} + }; + static const ul_excl_t excl[] = { + {'q', 'v'}, + {0} + }; + int excl_st[ARRAY_SIZE(excl)] = UL_EXCL_STATUS_INIT; + int c; - while ((c = getopt_long(argc, argv, optstr, long_options, NULL)) != -1) { + while ((c = getopt_long(argc, argv, optstr, long_options, NULL)) != -1) { - err_exclusive_options(c, long_options, excl, excl_st); + err_exclusive_options(c, long_options, excl, excl_st); - switch (c) { - case 'p': - opts.respect_mode = FALSE; - break; - case 'o': - opts.respect_owner = FALSE; - break; - case 't': - opts.respect_time = FALSE; - break; - case 'X': - opts.respect_xattrs = TRUE; - break; - case 'm': - opts.maximise = TRUE; - break; - case 'M': - opts.minimise = TRUE; - break; - case 'O': - opts.keep_oldest = TRUE; - break; - case 'f': - opts.respect_name = TRUE; - break; - case 'v': - opts.verbosity++; - break; - case 'q': - quiet = TRUE; - break; - case 'c': - opts.respect_mode = FALSE; - opts.respect_name = FALSE; - opts.respect_owner = FALSE; - opts.respect_time = FALSE; - opts.respect_xattrs = FALSE; - break; - case 'n': - opts.dry_run = 1; - break; - case 'x': - register_regex(&opts.exclude, optarg); - break; - case 'i': - register_regex(&opts.include, optarg); - break; - case 's': - opts.min_size = strtosize_or_err(optarg, _("failed to parse size")); - break; + switch (c) { + case 'p': + opts.respect_mode = FALSE; + break; + case 'o': + opts.respect_owner = FALSE; + break; + case 't': + opts.respect_time = FALSE; + break; + case 'X': + opts.respect_xattrs = TRUE; + break; + case 'm': + opts.maximise = TRUE; + break; + case 'M': + opts.minimise = TRUE; + break; + case 'O': + opts.keep_oldest = TRUE; + break; + case 'f': + opts.respect_name = TRUE; + break; + case 'v': + opts.verbosity++; + break; + case 'q': + quiet = TRUE; + break; + case 'c': + opts.respect_mode = FALSE; + opts.respect_name = FALSE; + opts.respect_owner = FALSE; + opts.respect_time = FALSE; + opts.respect_xattrs = FALSE; + break; + case 'n': + opts.dry_run = 1; + break; + case 'x': + register_regex(&opts.exclude, optarg); + break; + case 'i': + register_regex(&opts.include, optarg); + break; + case 's': + opts.min_size = strtosize_or_err(optarg, _("failed to parse size")); + break; + case 'h': + usage(); + case 'V': + print_version(EXIT_SUCCESS); + default: + errtryhelp(EXIT_FAILURE);} + } - case 'h': - usage(); - case 'V': - print_version(EXIT_SUCCESS); - default: - errtryhelp(EXIT_FAILURE); - } - } - return 0; + return 0; } /** - * to_be_called_atexit - Cleanup handler, also prints statistics. - */ +* to_be_called_atexit - Cleanup handler, also prints statistics. +*/ static void to_be_called_atexit(void) { - if (stats.started) - print_stats(); + if (stats.started) + print_stats(); } /** - * sighandler - Signal handler, sets the global last_signal variable - * @i: The signal number - */ +* sighandler - Signal handler, sets the global last_signal variable +* @i: The signal number +*/ static void sighandler(int i) { - if (last_signal != SIGINT) - last_signal = i; - if (i == SIGINT) - putchar('\n'); + if (last_signal != SIGINT) + last_signal = i; + if (i == SIGINT) + putchar('\n'); } int main(int argc, char *argv[]) { - struct sigaction sa; + struct sigaction sa; - sa.sa_handler = sighandler; - sa.sa_flags = SA_RESTART; - sigfillset(&sa.sa_mask); + sa.sa_handler = sighandler; + sa.sa_flags = SA_RESTART; + sigfillset(&sa.sa_mask); - /* If we receive a SIGINT, end the processing */ - sigaction(SIGINT, &sa, NULL); - sigaction(SIGUSR1, &sa, NULL); + /* If we receive a SIGINT, end the processing */ + sigaction(SIGINT, &sa, NULL); + sigaction(SIGUSR1, &sa, NULL); - /* Pretty print numeric output */ - setlocale(LC_NUMERIC, ""); + /* Pretty print numeric output */ + setlocale(LC_NUMERIC, ""); - if (atexit(to_be_called_atexit) != 0) - err(EXIT_FAILURE, _("cannot register exit handler")); + if (atexit(to_be_called_atexit) != 0) + err(EXIT_FAILURE, _("cannot register exit handler")); - parse_options(argc, argv); + parse_options(argc, argv); - if (optind == argc) - errx(EXIT_FAILURE, _("no directory of dile specified")); + if (optind == argc) + errx(EXIT_FAILURE, _("no directory of dile specified")); - gettime_monotonic(&stats.start_time); - stats.started = TRUE; + gettime_monotonic(&stats.start_time); + stats.started = TRUE; - for (; optind < argc; optind++) - if (nftw(argv[optind], inserter, 20, FTW_PHYS) == -1) - warn(_("cannot process %s"), argv[optind]); + for (; optind < argc; optind++) { + if (nftw(argv[optind], inserter, 20, FTW_PHYS) == -1) + warn(_("cannot process %s"), argv[optind]); + } - twalk(files, visitor); - - return 0; + twalk(files, visitor); + return 0; }