#include #include #include #include #include extern const char * const __progname; static int nonfull; static int invert = 0; static void usage(void) __attribute__((__noreturn__)); static void usage(void) { fprintf(stderr,"Usage: %s [flags] [--] file [file [file...]]\n",__progname); fprintf(stderr," %s [flags] [--] - (to read filenames from stdin)\n",__progname); fprintf(stderr,"Flags:\n"); fprintf(stderr,"-i invert sense of printing test\n"); exit(1); } static char *readaline(FILE *f) { char *b; int a; int l; int c; static void savec(char c) { if (l >= a) b = realloc(b,a=l+16); b[l++] = c; } b = 0; a = 0; l = 0; while (1) { c = getc(f); if (c == EOF) { if (l > 0) savec('\0'); return(b); } if (c == '\r') continue; if (c == '\n') { savec('\0'); return(b); } savec(c); } } static void process_name(const char *fn) { FILE *f; char *l; int hsz; int sz; int full; struct stat stb; f = fopen(fn,"r"); if (f == 0) { fprintf(stderr,"%s: %s: can't open: %s\n",__progname,fn,strerror(errno)); return; } sz = -1; while ((l=readaline(f))) { if (l[0] == '\0') { free(l); if (sz < 0) { fclose(f); return; } hsz = ftell(f); fstat(fileno(f),&stb); fclose(f); if (stb.st_size == sz+hsz) { full = 1; } else if (stb.st_size > sz+hsz) { fprintf(stderr,"%s: %s: file larger than required\n",__progname,fn); full = 1; } else { nonfull ++; full = 0; } if (invert ? !full : full) printf("%s\n",fn); return; } if (!strncasecmp(l,"content-length:",15)) { if (sz >= 0) { fprintf(stderr,"%s: %s: multiple Content-Length:s\n",__progname,fn); } sz = atoi(l+15); } free(l); } fclose(f); } static void names_from_stdin(void) { char *l; while ((l=readaline(stdin))) { process_name(l); free(l); } } static void names_from_args(int ac, char **av) { for (;ac>0;ac--,av++) process_name(av[0]); } int main(int, char **); int main(int ac, char **av) { while (1) { if (ac < 2) usage(); if (!strcmp(av[1],"-i")) { invert = ! invert; ac --; av ++; continue; } if (!strcmp(av[1],"--")) { ac --; av ++; break; } break; } nonfull = 0; if ((ac == 2) && !strcmp(av[1],"-")) { names_from_stdin(); } else { names_from_args(ac-1,av+1); } exit(nonfull); }