version 1.1.1.3, 2016/11/01 09:54:32
|
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-2015 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 49 int list_only = 0;
|
Line 49 int list_only = 0;
|
int link_times = 0; |
int link_times = 0; |
int link_owner = 0; |
int link_owner = 0; |
int nsec_times = 0; |
int nsec_times = 0; |
int preserve_perms = 0; |
|
int preserve_executability = 0; |
|
|
|
#ifdef SUPPORT_XATTRS |
#ifdef SUPPORT_XATTRS |
|
|
Line 109 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 116 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 148 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 = do_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("do_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); |
|
|
if (buf.st_mtime) { |
|
int len; |
|
mt = gmtime(&buf.st_mtime); |
|
|
|
len = 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); |
|
#ifdef ST_MTIME_NSEC |
#ifdef ST_MTIME_NSEC |
if (nsec_times) { | if (nsec_times) |
snprintf(datebuf + len, sizeof datebuf - len, | nsecs = (int)buf.ST_MTIME_NSEC; |
".%09d", (int)buf.ST_MTIME_NSEC); | else |
} | |
#endif |
#endif |
} else { | nsecs = -1; |
int len = MIN(19 + 9*nsec_times, (int)sizeof datebuf - 1); | storetime(mtimebuf, sizeof mtimebuf, buf.st_mtime, nsecs); |
memset(datebuf, ' ', len); | if (display_atimes) |
datebuf[len] = '\0'; | 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'; |
|
|
/* 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), | |
(long)minor(buf.st_rdev)); | |
} else |
} else |
printf("%15s", do_big_num(buf.st_size, 1, NULL)); |
printf("%15s", do_big_num(buf.st_size, 1, NULL)); |
printf(" %6ld.%-6ld %6ld %s %s%s\n", | |
| printf(" %6ld.%-6ld %6ld%s%s%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 |
Line 212 static struct poptOption long_options[] = {
|
Line 244 static struct poptOption long_options[] = {
|
{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 234 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); |