ls
for comparing two directories after running an rsync. [詳細]
関数 | |
static void | failed (char const *what, char const *where) |
static void | list_file (const char *fname) |
int | main (int argc, char *argv[]) |
変数 | |
int | dry_run = 0 |
int | read_only = 1 |
int | list_only = 0 |
int | preserve_perms = 0 |
ls
for comparing two directories after running an rsync.
The problem with using the system's own ls is that some features have little quirks that make directories look different when for our purposes they're the same -- for example, the BSD braindamage about setting the mode on symlinks based on your current umask.
All the filenames must be given on the command line -- tls does not even read directories, let alone recurse. The typical usage is "find|sort|xargs tls".
The format is not exactly the same as any particular Unix ls(1).
A key requirement for this program is that the output be "very reproducible." So we mask away information that can accidentally change.
tls.c で定義されています。
static void failed | ( | char const * | what, | |
char const * | where | |||
) | [static] |
参照先 errno.
参照元 list_file()・socketpair_tcp().
00053 { 00054 fprintf(stderr, PROGRAM ": %s %s: %s\n", 00055 what, where, strerror(errno)); 00056 exit(1); 00057 }
static void list_file | ( | const char * | fname | ) | [static] |
参照先 buf・do_lstat()・failed()・permstring()・sprintf().
参照元 main().
00062 { 00063 STRUCT_STAT buf; 00064 char permbuf[PERMSTRING_SIZE]; 00065 struct tm *mt; 00066 char datebuf[50]; 00067 char linkbuf[4096]; 00068 00069 if (do_lstat(fname, &buf) < 0) 00070 failed("stat", fname); 00071 00072 /* The size of anything but a regular file is probably not 00073 * worth thinking about. */ 00074 if (!S_ISREG(buf.st_mode)) 00075 buf.st_size = 0; 00076 00077 /* On some BSD platforms the mode bits of a symlink are 00078 * undefined. Also it tends not to be possible to reset a 00079 * symlink's mtime, so we have to ignore it too. */ 00080 if (S_ISLNK(buf.st_mode)) { 00081 int len; 00082 buf.st_mode &= ~0777; 00083 buf.st_mtime = (time_t)0; 00084 buf.st_uid = buf.st_gid = 0; 00085 strcpy(linkbuf, " -> "); 00086 /* const-cast required for silly UNICOS headers */ 00087 len = readlink((char *) fname, linkbuf+4, sizeof(linkbuf) - 4); 00088 if (len == -1) 00089 failed("readlink", fname); 00090 else 00091 /* it's not nul-terminated */ 00092 linkbuf[4+len] = 0; 00093 } else { 00094 linkbuf[0] = 0; 00095 } 00096 00097 permstring(permbuf, buf.st_mode); 00098 00099 if (buf.st_mtime) { 00100 mt = gmtime(&buf.st_mtime); 00101 00102 sprintf(datebuf, "%04d-%02d-%02d %02d:%02d:%02d", 00103 (int)mt->tm_year + 1900, 00104 (int)mt->tm_mon + 1, 00105 (int)mt->tm_mday, 00106 (int)mt->tm_hour, 00107 (int)mt->tm_min, 00108 (int)mt->tm_sec); 00109 } else { 00110 strcpy(datebuf, " "); 00111 } 00112 00113 /* TODO: Perhaps escape special characters in fname? */ 00114 00115 printf("%s ", permbuf); 00116 if (S_ISCHR(buf.st_mode) || S_ISBLK(buf.st_mode)) { 00117 printf("%5ld,%6ld", 00118 (long)major(buf.st_rdev), 00119 (long)minor(buf.st_rdev)); 00120 } else /* NB: use double for size since it might not fit in a long. */ 00121 printf("%12.0f", (double)buf.st_size); 00122 printf(" %6ld.%-6ld %6ld %s %s%s\n", 00123 (long)buf.st_uid, (long)buf.st_gid, (long)buf.st_nlink, 00124 datebuf, fname, linkbuf); 00125 }
int main | ( | int | argc, | |
char * | argv[] | |||
) |
参照先 list_file().
00130 { 00131 if (argc < 2) { 00132 fprintf(stderr, "usage: " PROGRAM " DIR ...\n" 00133 "Trivial file listing program for portably checking rsync\n"); 00134 return 1; 00135 } 00136 00137 for (argv++; *argv; argv++) { 00138 list_file(*argv); 00139 } 00140 00141 return 0; 00142 }
int preserve_perms = 0 |