231a232,335
> 
> int groklist(file_t **filelistp)
> {
> 
>   file_t *newfile;
> 
>   int filecount = 0;
>   struct stat info;
>   struct stat linfo;
>   static int progress = 0;
>   static char indicator[] = "-\\|/";
> 
> 
>   int looped_once = 0;
>   while ( 1 ) {
> 
>     int filename_buffer_size = 1024;
>     char *filename = (char*) malloc(filename_buffer_size);
>     filename = fgets( filename, filename_buffer_size-1, stdin);
>     if (filename == NULL) {
>       break;
>     } else {
>       // Strip newline
>       size_t newbuflen = strlen(filename);
>       if (filename[newbuflen - 1] == '\n') filename[newbuflen - 1] = '\0';
>     }
> 
>     looped_once = 1;
> 
>     if (!ISFLAG(flags, F_HIDEPROGRESS)) {
>       fprintf(stderr, "\rBuilding file list %c ", indicator[progress]);
>       progress = (progress + 1) % 4;
>     }
> 
>     newfile = (file_t*) malloc(sizeof(file_t));
> 
>     if (!newfile) {
>       errormsg("out of memory!\n");
>       exit(1);
>     } else newfile->next = *filelistp;
> 
>     newfile->device = 0;
>     newfile->inode = 0;
>     newfile->crcsignature = NULL;
>     newfile->crcpartial = NULL;
>     newfile->duplicates = NULL;
>     newfile->hasdupes = 0;
> 
> 
>     newfile->d_name = (char*)malloc(strlen(filename) + 2);	// FIXME - WHY "2"?
>     strcpy(newfile->d_name, filename);
>     free(filename);
> 
>     if (!newfile->d_name) {
>       errormsg("out of memory!\n");
>       free(newfile);
>       exit(1);
>     }
> 
>     if (filesize(newfile->d_name) == 0 && ISFLAG(flags, F_EXCLUDEEMPTY)) {
>       free(newfile->d_name);
>       free(newfile);
>       continue;
>     }
>     if (stat(newfile->d_name, &info) == -1) {
>       free(newfile->d_name);
>       free(newfile);
>       continue;
>     }
>     if (lstat(newfile->d_name, &linfo) == -1) {
>       free(newfile->d_name);
>       free(newfile);
>       continue;
>     }
> 
>     if (S_ISDIR(info.st_mode)) {
>       // FIXME: We could recurse into the directories from the list, if desired
>       /*
>       if (ISFLAG(flags, F_RECURSE) && (ISFLAG(flags, F_FOLLOWLINKS) || !S_ISLNK(linfo.st_mode)))
>         filecount += grokdir(newfile->d_name, filelistp);
>       */
>       free(newfile->d_name);
>       free(newfile);
>     } else {
>       if (S_ISREG(linfo.st_mode) || (S_ISLNK(linfo.st_mode) && ISFLAG(flags, F_FOLLOWLINKS))) {
>         *filelistp = newfile;
>         filecount++;
>       } else {
>         free(newfile->d_name);
>         free(newfile);
>       }
>     }
>   }
> 
> 
>   if (!looped_once) {
>     errormsg("no directories specified\n");
>     exit(1);
>   }
> 
>   return filecount;
> }
> 
> 
1067,1074c1171,1176
<     errormsg("no directories specified\n");
<     exit(1);
<   }
< 
<   if (ISFLAG(flags, F_RECURSE) && ISFLAG(flags, F_RECURSEAFTER)) {
<     errormsg("options --recurse and --recurse: are not compatible\n");
<     exit(1);
<   }
---
>     // Accept piped list of files (mutually exclusive with directory name arguments)
>     filecount += groklist(&files);
>     if (!filecount) {
>       errormsg("no directories or absolute filenames specified\n");
>       exit(1);
>     }
1076,1079c1178
<   if (ISFLAG(flags, F_SUMMARIZEMATCHES) && ISFLAG(flags, F_DELETEFILES)) {
<     errormsg("options --summarize and --delete are not compatible\n");
<     exit(1);
<   }
---
>   } else {
1081,1085c1180,1183
<   if (ISFLAG(flags, F_RECURSEAFTER)) {
<     firstrecurse = nonoptafter("--recurse:", argc, oldargv, argv, optind);
<     
<     if (firstrecurse == argc)
<       firstrecurse = nonoptafter("-R", argc, oldargv, argv, optind);
---
>     if (ISFLAG(flags, F_RECURSE) && ISFLAG(flags, F_RECURSEAFTER)) {
>       errormsg("options --recurse and --recurse: are not compatible\n");
>       exit(1);
>     }
1087,1088c1185,1186
<     if (firstrecurse == argc) {
<       errormsg("-R option must be isolated from other options\n");
---
>     if (ISFLAG(flags, F_SUMMARIZEMATCHES) && ISFLAG(flags, F_DELETEFILES)) {
>       errormsg("options --summarize and --delete are not compatible\n");
1092,1094c1190,1191
<     /* F_RECURSE is not set for directories before --recurse: */
<     for (x = optind; x < firstrecurse; x++)
<       filecount += grokdir(argv[x], &files);
---
>     if (ISFLAG(flags, F_RECURSEAFTER)) {
>       firstrecurse = nonoptafter("--recurse:", argc, oldargv, argv, optind);
1096,1097c1193,1194
<     /* Set F_RECURSE for directories after --recurse: */
<     SETFLAG(flags, F_RECURSE);
---
>       if (firstrecurse == argc)
>         firstrecurse = nonoptafter("-R", argc, oldargv, argv, optind);
1099,1103c1196,1213
<     for (x = firstrecurse; x < argc; x++)
<       filecount += grokdir(argv[x], &files);
<   } else {
<     for (x = optind; x < argc; x++)
<       filecount += grokdir(argv[x], &files);
---
>       if (firstrecurse == argc) {
>         errormsg("-R option must be isolated from other options\n");
>         exit(1);
>       }
> 
>       /* F_RECURSE is not set for directories before --recurse: */
>       for (x = optind; x < firstrecurse; x++)
>         filecount += grokdir(argv[x], &files);
> 
>       /* Set F_RECURSE for directories after --recurse: */
>       SETFLAG(flags, F_RECURSE);
> 
>       for (x = firstrecurse; x < argc; x++)
>         filecount += grokdir(argv[x], &files);
>     } else {
>       for (x = optind; x < argc; x++)
>         filecount += grokdir(argv[x], &files);
>     }
