It would be very helpful to have a "recursive" option in md5sum (or any
other *sum utility, for that matter).  That way, an entire directory tree
could be summed into a file in order to do integrity checking (with
the "check" flag) at later dates.  For example:

% md5sum -r /home/foo > /home/bar/check.md5

md5sums everything in the /home/foo path so that:

% md5sum -c /home/bar/check.md5

can validate the entire /home/foo tree.  I have attached a rough, but
working, patch to md5sum.c to facilitate this option.  I hope you find
this suggestion helpful!

-Brian

106a107
>   { "recursive", no_argument, 0, 'r'},
132a134
>   -r, --recursive         check directories recursively\n\
477a480,574
> 
> void print_sum(char *file, int recurse, int binary, 
>              unsigned char bin_buffer[], 
>              int (*digest_stream)(FILE *, void *),
>              int *err) {
>   int fail;
>   struct stat filestat;
>   
>   if (lstat(file, &filestat) == -1) {
>     fprintf(stderr, "Error checking file: \"%s\"\n", file);
>     return;
>   } else {
>     if (recurse && S_ISDIR(filestat.st_mode)) {
>       DIR *dp;
>       struct dirent *dentry;
>       char *ptr;
>       int value = 0;
> 
>       if ((dp = opendir(file)) != NULL) {
>       while ((dentry = readdir(dp)) != NULL) {
>         if ((strcmp(dentry->d_name, ".") == 0) ||
>             (strcmp(dentry->d_name, "..") == 0))
>           continue;
> 
>         ptr = malloc(strlen(file) + 1 + 
>                      strlen(dentry->d_name) + 1);
> 
>         if (ptr == NULL) {
>           fprintf(stderr, "Out of memory\n");
>           exit(1);
>         }
> 
>         sprintf(ptr, "%s/%s", file, dentry->d_name);
>               
>         print_sum(ptr, recurse, binary, bin_buffer, 
>                   DIGEST_STREAM(algorithm), err);
> 
>         free(ptr);
>       }
> 
>       closedir(dp);
> 
>       return;
>       } else {
>       fprintf(stderr, "Errer opening directory %s", file);
>       return;
>       }
>     } else {
> 
>       fail = digest_file (file, binary, bin_buffer,
>                         DIGEST_STREAM (algorithm));
>       *err |= fail;
>       if (!fail)
>       {
>         size_t i;
>         
>         /* Output a leading backslash if the file name contains
>            a newline or backslash.  */
>         if (strchr (file, '\n') || strchr (file, '\\'))
>           putchar ('\\');
> 
>         for (i = 0; i < (digest_hex_bytes / 2); ++i)
>           printf ("%02x", bin_buffer[i]);
>         
>         putchar (' ');
>         if (binary)
>           putchar ('*');
>         else
>           putchar (' ');
> 
>         /* Translate each NEWLINE byte to the string, "\\n",
>            and each backslash to "\\\\".  */
>         for (i = 0; i < strlen (file); ++i)
>           {
>             switch (file[i])
>               {
>               case '\n':
>                 fputs ("\\n", stdout);
>                 break;
>                 
>               case '\\':
>                 fputs ("\\\\", stdout);
>                 break;
>                 
>               default:
>                 putchar (file[i]);
>                 break;
>               }
>           }
>         putchar ('\n');
>       }
>     }
>   }
> }
> 
487a585
>   int recursive = 0;
506c604
<   while ((opt = getopt_long (argc, argv, "bctw", long_options, NULL)) != -1)
---
>   while ((opt = getopt_long (argc, argv, "brctw", long_options, NULL)) != -1)
524a623,625
>       case 'r':
>       recursive = 1;
>       break;
622,663c723,724
<         fail = digest_file (file, binary, bin_buffer,
<                             DIGEST_STREAM (algorithm));
<         err |= fail;
<         if (!fail)
<           {
<             size_t i;
< 
<             /* Output a leading backslash if the file name contains
<                a newline or backslash.  */
<             if (strchr (file, '\n') || strchr (file, '\\'))
<               putchar ('\\');
< 
<             for (i = 0; i < (digest_hex_bytes / 2); ++i)
<               printf ("%02x", bin_buffer[i]);
< 
<             putchar (' ');
<             if (binary)
<               putchar ('*');
<             else
<               putchar (' ');
< 
<             /* Translate each NEWLINE byte to the string, "\\n",
<                and each backslash to "\\\\".  */
<             for (i = 0; i < strlen (file); ++i)
<               {
<                 switch (file[i])
<                   {
<                   case '\n':
<                     fputs ("\\n", stdout);
<                     break;
< 
<                   case '\\':
<                     fputs ("\\\\", stdout);
<                     break;
< 
<                   default:
<                     putchar (file[i]);
<                     break;
<                   }
<               }
<             putchar ('\n');
<           }
---
>         print_sum(file, recursive, binary, bin_buffer, 
>                   DIGEST_STREAM(algorithm), &err);

Reply via email to