version 1.1, 2012/02/17 15:09:30
|
version 1.1.1.4, 2021/03/17 00:32:36
|
Line 2
|
Line 2
|
* Trivial ls for comparing two directories after running an rsync. |
* Trivial ls for comparing two directories after running an rsync. |
* |
* |
* Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org> |
* Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org> |
* Copyright (C) 2003-2009 Wayne Davison | * Copyright (C) 2003-2020 Wayne Davison |
* |
* |
* This program is free software; you can redistribute it and/or modify |
* This program is free software; you can redistribute it and/or modify |
* it under the terms of the GNU General Public License as published by |
* it under the terms of the GNU General Public License as published by |
Line 43
|
Line 43
|
/* These are to make syscall.o shut up. */ |
/* These are to make syscall.o shut up. */ |
int dry_run = 0; |
int dry_run = 0; |
int am_root = 0; |
int am_root = 0; |
|
int am_sender = 1; |
int read_only = 1; |
int read_only = 1; |
int list_only = 0; |
int list_only = 0; |
int link_times = 0; |
int link_times = 0; |
int link_owner = 0; |
int link_owner = 0; |
int preserve_perms = 0; | int nsec_times = 0; |
int preserve_executability = 0; | |
|
|
#ifdef SUPPORT_XATTRS |
#ifdef SUPPORT_XATTRS |
|
|
Line 107 static int stat_xattr(const char *fname, STRUCT_STAT *
|
Line 107 static int stat_xattr(const char *fname, STRUCT_STAT *
|
|
|
#endif |
#endif |
|
|
|
static int display_atimes = 0; |
|
#ifdef SUPPORT_CRTIMES |
|
static int display_crtimes = 0; |
|
#endif |
|
|
static void failed(char const *what, char const *where) |
static void failed(char const *what, char const *where) |
{ |
{ |
fprintf(stderr, PROGRAM ": %s %s: %s\n", |
fprintf(stderr, PROGRAM ": %s %s: %s\n", |
Line 114 static void failed(char const *what, char const *where
|
Line 119 static void failed(char const *what, char const *where
|
exit(1); |
exit(1); |
} |
} |
|
|
|
static void storetime(char *dest, size_t destsize, time_t t, int nsecs) |
|
{ |
|
if (t) { |
|
int len; |
|
struct tm *mt = gmtime(&t); |
|
|
|
len = snprintf(dest, destsize, |
|
" %04d-%02d-%02d %02d:%02d:%02d", |
|
(int)mt->tm_year + 1900, |
|
(int)mt->tm_mon + 1, |
|
(int)mt->tm_mday, |
|
(int)mt->tm_hour, |
|
(int)mt->tm_min, |
|
(int)mt->tm_sec); |
|
if (nsecs >= 0 && len >= 0) |
|
snprintf(dest + len, destsize - len, ".%09d", nsecs); |
|
} else { |
|
int has_nsecs = nsecs >= 0 ? 1 : 0; |
|
int len = MIN(20 + 10*has_nsecs, (int)destsize - 1); |
|
memset(dest, ' ', len); |
|
dest[len] = '\0'; |
|
} |
|
} |
|
|
static void list_file(const char *fname) |
static void list_file(const char *fname) |
{ |
{ |
STRUCT_STAT buf; |
STRUCT_STAT buf; |
|
#ifdef SUPPORT_CRTIMES |
|
time_t crtime = 0; |
|
#endif |
char permbuf[PERMSTRING_SIZE]; |
char permbuf[PERMSTRING_SIZE]; |
struct tm *mt; | char mtimebuf[50]; |
char datebuf[50]; | char atimebuf[50]; |
| char crtimebuf[50]; |
char linkbuf[4096]; |
char linkbuf[4096]; |
|
int nsecs; |
|
|
if (do_lstat(fname, &buf) < 0) |
if (do_lstat(fname, &buf) < 0) |
failed("stat", fname); |
failed("stat", fname); |
|
#ifdef SUPPORT_CRTIMES |
|
if (display_crtimes && (crtime = get_create_time(fname)) == 0) |
|
failed("get_create_time", fname); |
|
#endif |
#ifdef SUPPORT_XATTRS |
#ifdef SUPPORT_XATTRS |
if (am_root < 0) |
if (am_root < 0) |
stat_xattr(fname, &buf); |
stat_xattr(fname, &buf); |
Line 146 static void list_file(const char *fname)
|
Line 184 static void list_file(const char *fname)
|
buf.st_uid = buf.st_gid = 0; |
buf.st_uid = buf.st_gid = 0; |
strlcpy(linkbuf, " -> ", sizeof linkbuf); |
strlcpy(linkbuf, " -> ", sizeof linkbuf); |
/* const-cast required for silly UNICOS headers */ |
/* const-cast required for silly UNICOS headers */ |
len = readlink((char *) fname, linkbuf+4, sizeof(linkbuf) - 4); | len = do_readlink((char*)fname, linkbuf+4, sizeof linkbuf - 4); |
if (len == -1) |
if (len == -1) |
failed("readlink", fname); | failed("do_readlink", fname); |
else |
else |
/* it's not nul-terminated */ |
/* it's not nul-terminated */ |
linkbuf[4+len] = 0; |
linkbuf[4+len] = 0; |
} else { |
} else { |
linkbuf[0] = 0; | linkbuf[0] = '\0'; |
} |
} |
|
|
permstring(permbuf, buf.st_mode); |
permstring(permbuf, buf.st_mode); |
|
#ifdef ST_MTIME_NSEC |
|
if (nsec_times) |
|
nsecs = (int)buf.ST_MTIME_NSEC; |
|
else |
|
#endif |
|
nsecs = -1; |
|
storetime(mtimebuf, sizeof mtimebuf, buf.st_mtime, nsecs); |
|
if (display_atimes) |
|
storetime(atimebuf, sizeof atimebuf, S_ISDIR(buf.st_mode) ? 0 : buf.st_atime, -1); |
|
else |
|
atimebuf[0] = '\0'; |
|
#ifdef SUPPORT_CRTIMES |
|
if (display_crtimes) |
|
storetime(crtimebuf, sizeof crtimebuf, crtime, -1); |
|
else |
|
#endif |
|
crtimebuf[0] = '\0'; |
|
|
if (buf.st_mtime) { |
|
mt = gmtime(&buf.st_mtime); |
|
|
|
snprintf(datebuf, sizeof datebuf, |
|
"%04d-%02d-%02d %02d:%02d:%02d", |
|
(int)mt->tm_year + 1900, |
|
(int)mt->tm_mon + 1, |
|
(int)mt->tm_mday, |
|
(int)mt->tm_hour, |
|
(int)mt->tm_min, |
|
(int)mt->tm_sec); |
|
} else |
|
strlcpy(datebuf, " ", sizeof datebuf); |
|
|
|
/* TODO: Perhaps escape special characters in fname? */ |
/* TODO: Perhaps escape special characters in fname? */ |
|
|
printf("%s ", permbuf); |
printf("%s ", permbuf); |
|
|
if (S_ISCHR(buf.st_mode) || S_ISBLK(buf.st_mode)) { |
if (S_ISCHR(buf.st_mode) || S_ISBLK(buf.st_mode)) { |
printf("%5ld,%6ld", | printf("%5ld,%6ld", (long)major(buf.st_rdev), (long)minor(buf.st_rdev)); |
(long)major(buf.st_rdev), | } else |
(long)minor(buf.st_rdev)); | printf("%15s", do_big_num(buf.st_size, 1, NULL)); |
} else /* NB: use double for size since it might not fit in a long. */ | |
printf("%12.0f", (double)buf.st_size); | printf(" %6ld.%-6ld %6ld%s%s%s %s%s\n", |
printf(" %6ld.%-6ld %6ld %s %s%s\n", | |
(long)buf.st_uid, (long)buf.st_gid, (long)buf.st_nlink, |
(long)buf.st_uid, (long)buf.st_gid, (long)buf.st_nlink, |
datebuf, fname, linkbuf); | mtimebuf, atimebuf, crtimebuf, fname, linkbuf); |
} |
} |
|
|
static struct poptOption long_options[] = { |
static struct poptOption long_options[] = { |
/* longName, shortName, argInfo, argPtr, value, descrip, argDesc */ |
/* longName, shortName, argInfo, argPtr, value, descrip, argDesc */ |
|
{"atimes", 'U', POPT_ARG_NONE, &display_atimes, 0, 0, 0}, |
|
#ifdef SUPPORT_CRTIMES |
|
{"crtimes", 'N', POPT_ARG_NONE, &display_crtimes, 0, 0, 0}, |
|
#endif |
{"link-times", 'l', POPT_ARG_NONE, &link_times, 0, 0, 0 }, |
{"link-times", 'l', POPT_ARG_NONE, &link_times, 0, 0, 0 }, |
{"link-owner", 'L', POPT_ARG_NONE, &link_owner, 0, 0, 0 }, |
{"link-owner", 'L', POPT_ARG_NONE, &link_owner, 0, 0, 0 }, |
#ifdef SUPPORT_XATTRS |
#ifdef SUPPORT_XATTRS |
{"fake-super", 'f', POPT_ARG_VAL, &am_root, -1, 0, 0 }, |
{"fake-super", 'f', POPT_ARG_VAL, &am_root, -1, 0, 0 }, |
#endif |
#endif |
|
#ifdef ST_MTIME_NSEC |
|
{"nsec", 's', POPT_ARG_NONE, &nsec_times, 0, 0, 0 }, |
|
#endif |
{"help", 'h', POPT_ARG_NONE, 0, 'h', 0, 0 }, |
{"help", 'h', POPT_ARG_NONE, 0, 'h', 0, 0 }, |
{0,0,0,0,0,0,0} |
{0,0,0,0,0,0,0} |
}; |
}; |
|
|
static void tls_usage(int ret) | static void NORETURN tls_usage(int ret) |
{ |
{ |
FILE *F = ret ? stderr : stdout; |
FILE *F = ret ? stderr : stdout; |
fprintf(F,"usage: " PROGRAM " [OPTIONS] FILE ...\n"); |
fprintf(F,"usage: " PROGRAM " [OPTIONS] FILE ...\n"); |
fprintf(F,"Trivial file listing program for portably checking rsync\n"); |
fprintf(F,"Trivial file listing program for portably checking rsync\n"); |
fprintf(F,"\nOptions:\n"); |
fprintf(F,"\nOptions:\n"); |
|
fprintf(F," -U, --atimes display access (last-used) times\n"); |
|
#ifdef SUPPORT_CRTIMES |
|
fprintf(F," -N, --crtimes display create times (newness)\n"); |
|
#endif |
fprintf(F," -l, --link-times display the time on a symlink\n"); |
fprintf(F," -l, --link-times display the time on a symlink\n"); |
fprintf(F," -L, --link-owner display the owner+group on a symlink\n"); |
fprintf(F," -L, --link-owner display the owner+group on a symlink\n"); |
#ifdef SUPPORT_XATTRS |
#ifdef SUPPORT_XATTRS |
Line 219 main(int argc, char *argv[])
|
Line 270 main(int argc, char *argv[])
|
const char **extra_args; |
const char **extra_args; |
int opt; |
int opt; |
|
|
pc = poptGetContext(PROGRAM, argc, (const char **)argv, | pc = poptGetContext(PROGRAM, argc, (const char **)argv, long_options, 0); |
long_options, 0); | |
while ((opt = poptGetNextOpt(pc)) != -1) { |
while ((opt = poptGetNextOpt(pc)) != -1) { |
switch (opt) { |
switch (opt) { |
case 'h': |
case 'h': |
tls_usage(0); |
tls_usage(0); |
default: |
default: |
fprintf(stderr, | fprintf(stderr, "%s: %s\n", |
"%s: %s\n", | |
poptBadOption(pc, POPT_BADOPTION_NOALIAS), |
poptBadOption(pc, POPT_BADOPTION_NOALIAS), |
poptStrerror(opt)); |
poptStrerror(opt)); |
tls_usage(1); |
tls_usage(1); |