3 * cat startpoints.list | summer >data.list
4 * summer startpoints... >data.list
5 * prints md5sum of data-list to stderr
11 #include <sys/types.h>
26 static void fn_escaped(FILE *f, const char *fn) {
29 if (c>=33 && c<=126) putc(c,f);
30 else fprintf(f,"\\x%02x",(int)(unsigned char)c);
34 static void undoable(const char *path, const char *fmt, ...) {
37 fputs("summer: ", stderr);
38 vfprintf(stderr, fmt, al);
39 fn_escaped(stderr, path);
44 static void unreadable(const char *path, const char *doing) {
45 undoable(path, "unreadable: %s: %s: ", strerror(errno), doing);
48 static void csum_file(const char *path) {
52 unsigned char digest[16];
56 f= fopen(path,"rb"); if (!f) unreadable(path, "open");
59 r= fread(db,1,sizeof(db),f);
60 if (ferror(f)) unreadable(path, "read");
61 if (!r) { assert(feof(f)); break; }
65 if (fclose(f)) unreadable(path, "close");
67 for (i=0; i<sizeof(digest); i++)
68 printf("%02x", digest[i]);
71 static void csum_dev(int cb, const struct stat *stab) {
72 printf("%c 0x%08lx %3lu %3lu %3lu %3lu ", cb,
73 (unsigned long)stab->st_rdev,
74 ((unsigned long)stab->st_rdev & 0x0ff000000U) >> 24,
75 ((unsigned long)stab->st_rdev & 0x000ff0000U) >> 16,
76 ((unsigned long)stab->st_rdev & 0x00000ff00U) >> 8,
77 ((unsigned long)stab->st_rdev & 0x0000000ffU) >> 0);
80 static void csum_str(const char *s) {
86 static int item(const char *path, const struct stat *stab,
87 int flag, struct FTW *ftws) {
92 if (S_ISREG(stab->st_mode)) csum_file(path);
93 else if (S_ISDIR(stab->st_mode)) csum_str("dir");
94 else if (S_ISCHR(stab->st_mode)) csum_dev('c',stab);
95 else if (S_ISBLK(stab->st_mode)) csum_dev('b',stab);
96 else if (S_ISFIFO(stab->st_mode)) csum_str("pipe");
97 else if (S_ISLNK(stab->st_mode)) csum_str("link");
98 else if (S_ISSOCK(stab->st_mode)) csum_str("sock");
99 else undoable(path, "badobj: 0x%lx: ", (unsigned long)stab->st_mode);
104 undoable(path,"inaccessible: %s: ", strerror(errno));
107 undoable(path,"ftw flag 0x%x: %s: ", flag);
110 printf(" %10lu %4d %4o %10ld %10ld %10lu %10lu %10lu ",
111 (unsigned long)stab->st_size,
113 (unsigned)stab->st_mode & 07777U,
114 (unsigned long)stab->st_uid,
115 (unsigned long)stab->st_gid,
116 (unsigned long)stab->st_atime,
117 (unsigned long)stab->st_mtime,
118 (unsigned long)stab->st_ctime);
119 fn_escaped(stdout, path);
121 if (S_ISLNK(stab->st_mode)) {
122 char linktarg[MAXFN+1];
125 r= readlink(path, linktarg, sizeof(linktarg)-1);
126 if (r==sizeof(linktarg)) undoable(path,"readlink too big");
127 if (r<0) undoable(path,"readlink: %s: ", strerror(errno));
132 fn_escaped(stdout, linktarg);
136 if (ferror(stdout)) { perror("summer: stdout"); exit(12); }
140 static void process(const char *startpoint) {
142 fprintf(stderr,"summer: processing: %s\n",startpoint);
143 r= nftw(startpoint, item, MAXDEPTH, FTW_MOUNT|FTW_PHYS);
144 if (r) { fprintf(stderr, "summer: nftw failed: %s: %s\n",
145 strerror(errno), startpoint); exit(4); }
148 static void from_stdin(void) {
153 fprintf(stderr, "summer: processing stdin lines as startpoints\n");
155 s= fgets(buf,sizeof(buf),stdin);
156 if (ferror(stdin)) { perror("summer: stdin"); exit(12); }
157 if (!s) { if (feof(stdin)) return; else abort(); }
160 if (buf[l-1]!='\n') { fprintf(stderr,"summer: line too long\n"); exit(8); }
166 int main(int argc, const char *const *argv) {
171 } else if (argv[1][0]=='h') {
173 "summer: usage: summer startpoint... >data.list\n"
174 " cat startpoints.list | summer >data.list\n");
177 fprintf(stderr, "summer: processing command line args as startpoints\n");
178 while ((arg=*++argv)) {
182 if (ferror(stdout) || fclose(stdout)) {
183 perror("summer: stdout (at end)"); exit(12);
185 fputs("summer: done.\n", stderr);