From 50fe60865662b13acaa1efcc49f1837fdffd785a Mon Sep 17 00:00:00 2001 From: ian Date: Sat, 20 Dec 2003 17:46:03 +0000 Subject: [PATCH] initial checkin, found stuff --- cprogs/summer.c | 187 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 187 insertions(+) create mode 100644 cprogs/summer.c diff --git a/cprogs/summer.c b/cprogs/summer.c new file mode 100644 index 0000000..2e169a1 --- /dev/null +++ b/cprogs/summer.c @@ -0,0 +1,187 @@ +/* + * usage: + * cat startpoints.list | summer >data.list + * summer startpoints... >data.list + * prints md5sum of data-list to stderr + */ + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "md5.h" + +#define MAXFN 2048 +#define MAXDEPTH 1024 + +static void fn_escaped(FILE *f, const char *fn) { + int c; + while ((c= *fn++)) { + if (c>=33 && c<=126) putc(c,f); + else fprintf(f,"\\x%02x",(int)(unsigned char)c); + } +} + +static void undoable(const char *path, const char *fmt, ...) { + va_list(al); + va_start(al,fmt); + fputs("summer: ", stderr); + vfprintf(stderr, fmt, al); + fn_escaped(stderr, path); + putc('\n',stderr); + exit(4); +} + +static void unreadable(const char *path, const char *doing) { + undoable(path, "unreadable: %s: %s: ", strerror(errno), doing); +} + +static void csum_file(const char *path) { + FILE *f; + struct MD5Context mc; + char db[65536]; + unsigned char digest[16]; + size_t r; + int i; + + f= fopen(path,"rb"); if (!f) unreadable(path, "open"); + MD5Init(&mc); + for (;;) { + r= fread(db,1,sizeof(db),f); + if (ferror(f)) unreadable(path, "read"); + if (!r) { assert(feof(f)); break; } + MD5Update(&mc,db,r); + } + MD5Final(digest,&mc); + if (fclose(f)) unreadable(path, "close"); + + for (i=0; ist_rdev, + ((unsigned long)stab->st_rdev & 0x0ff000000U) >> 24, + ((unsigned long)stab->st_rdev & 0x000ff0000U) >> 16, + ((unsigned long)stab->st_rdev & 0x00000ff00U) >> 8, + ((unsigned long)stab->st_rdev & 0x0000000ffU) >> 0); +} + +static void csum_str(const char *s) { + printf("%-32s", s); +} + +struct FTW; + +static int item(const char *path, const struct stat *stab, + int flag, struct FTW *ftws) { + switch (flag) { + case FTW_D: + case FTW_F: + case FTW_SL: + if (S_ISREG(stab->st_mode)) csum_file(path); + else if (S_ISDIR(stab->st_mode)) csum_str("dir"); + else if (S_ISCHR(stab->st_mode)) csum_dev('c',stab); + else if (S_ISBLK(stab->st_mode)) csum_dev('b',stab); + else if (S_ISFIFO(stab->st_mode)) csum_str("pipe"); + else if (S_ISLNK(stab->st_mode)) csum_str("link"); + else if (S_ISSOCK(stab->st_mode)) csum_str("sock"); + else undoable(path, "badobj: 0x%lx: ", (unsigned long)stab->st_mode); + break; + + case FTW_NS: + case FTW_DNR: + undoable(path,"inaccessible: %s: ", strerror(errno)); + + default: + undoable(path,"ftw flag 0x%x: %s: ", flag); + } + + printf(" %10lu %4d %4o %10ld %10ld %10lu %10lu %10lu ", + (unsigned long)stab->st_size, + (int)stab->st_nlink, + (unsigned)stab->st_mode & 07777U, + (unsigned long)stab->st_uid, + (unsigned long)stab->st_gid, + (unsigned long)stab->st_atime, + (unsigned long)stab->st_mtime, + (unsigned long)stab->st_ctime); + fn_escaped(stdout, path); + + if (S_ISLNK(stab->st_mode)) { + char linktarg[MAXFN+1]; + int r; + + r= readlink(path, linktarg, sizeof(linktarg)-1); + if (r==sizeof(linktarg)) undoable(path,"readlink too big"); + if (r<0) undoable(path,"readlink: %s: ", strerror(errno)); + + linktarg[r]= 0; + + printf(" -> "); + fn_escaped(stdout, linktarg); + } + putchar('\n'); + + if (ferror(stdout)) { perror("summer: stdout"); exit(12); } + return 0; +} + +static void process(const char *startpoint) { + int r; + fprintf(stderr,"summer: processing: %s\n",startpoint); + r= nftw(startpoint, item, MAXDEPTH, FTW_MOUNT|FTW_PHYS); + if (r) { fprintf(stderr, "summer: nftw failed: %s: %s\n", + strerror(errno), startpoint); exit(4); } +} + +static void from_stdin(void) { + char buf[MAXFN+2]; + char *s; + int l; + + fprintf(stderr, "summer: processing stdin lines as startpoints\n"); + for (;;) { + s= fgets(buf,sizeof(buf),stdin); + if (ferror(stdin)) { perror("summer: stdin"); exit(12); } + if (!s) { if (feof(stdin)) return; else abort(); } + l= strlen(buf); + assert(l>0); + if (buf[l-1]!='\n') { fprintf(stderr,"summer: line too long\n"); exit(8); } + buf[l-1]= 0; + process(buf); + } +} + +int main(int argc, const char *const *argv) { + const char *arg; + + if (!argv[1]) { + from_stdin(); + } else if (argv[1][0]=='h') { + fprintf(stderr, + "summer: usage: summer startpoint... >data.list\n" + " cat startpoints.list | summer >data.list\n"); + return 8; + } else { + fprintf(stderr, "summer: processing command line args as startpoints\n"); + while ((arg=*++argv)) { + process(arg); + } + } + if (ferror(stdout) || fclose(stdout)) { + perror("summer: stdout (at end)"); exit(12); + } + fputs("summer: done.\n", stderr); + return 0; +} -- 2.30.2