"Fossies" - the Fresh Open Source Software Archive

Member "littleutils-1.2.5/littleutils/filehash.c" (29 Oct 2021, 15256 Bytes) of package /linux/privat/littleutils-1.2.5.tar.lz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "filehash.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 1.2.4_vs_1.2.5.

    1 /* filehash:  Print various hash digests and filesizes for specified files.
    2 
    3    Copyright (C) 2004-2021 by Brian Lindholm.
    4    This file is part of the littleutils utility set.
    5 
    6    The filehash utility is free software; you can redistribute it and/or modify
    7    it under the terms of the GNU General Public License as published by the
    8    Free Software Foundation; either version 3, or (at your option) any later
    9    version.
   10 
   11    The filehash utility is distributed in the hope that it will be useful, but
   12    WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
   13    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   14    more details.
   15 
   16    You should have received a copy of the GNU General Public License along with
   17    the littleutils.  If not, see <https://www.gnu.org/licenses/>. */
   18 
   19 
   20 #include <config.h>
   21 
   22 #if HAVE_INTTYPES_H
   23 # include <inttypes.h>
   24 #endif
   25 #include <limits.h>
   26 #ifdef HAVE_STDIO_H
   27 # include <stdio.h>
   28 #endif
   29 #ifdef HAVE_STDLIB_H
   30 # include <stdlib.h>
   31 #endif
   32 #ifdef HAVE_STRING_H
   33 # include <string.h>
   34 #endif
   35 #ifdef HAVE_SYS_STAT_H
   36 # include <sys/stat.h>
   37 #endif
   38 #ifdef HAVE_SYS_TYPES_H
   39 # include <sys/types.h>
   40 #endif
   41 
   42 #ifdef HAVE_UNISTD_H
   43 # include <unistd.h>
   44 # define OPTEND -1
   45 #else
   46 # define OPTEND EOF
   47 #endif
   48 #ifdef HAVE_GETOPT_H
   49 # include <getopt.h>
   50 #endif
   51 
   52 #ifdef MSDOS
   53 # include "io.h"
   54 #endif
   55 
   56 #include "md5.h"
   57 #include "sha1.h"
   58 #include "sha256.h"
   59 #include "sha512.h"
   60 #include "b2sum.h"
   61 
   62 #ifdef HAVE_FSEEKO
   63 # define fseek(a,b,c) fseeko((a),(off_t)(b),(c))
   64 #endif
   65 
   66 #ifdef __MINGW32__
   67 extern int getopt (int argc, char * const *argv, const char *optstring);
   68 extern char *optarg;
   69 extern int optind;
   70 #endif
   71 
   72 #ifdef DJGPP
   73 unsigned short _djstat_flags = 63;
   74 #endif
   75 
   76 #ifndef PATH_MAX
   77 # define PATH_MAX 256
   78 #endif
   79 
   80 char *sizefmt = (sizeof (off_t) <= sizeof (long) ? "%lu" : "%llu");
   81 
   82 
   83 static void
   84 help (FILE *where)
   85 {
   86   fprintf (where,
   87     "filehash " PACKAGE_VERSION "\n"
   88     "usage: filehash [-1(MD5)] [-2(SHA1)] [-3(SHA224) ][-4(SHA256)]\n"
   89     "         [-5(SHA384)] [-6(SHA512)] [-7(BLAKE2B_256)] [-8(BLAKE2B_256)]\n"
   90     "         [-b(ase64url)] [-c(lassic)] [-f file_list] [-h(elp)]\n"
   91     "         [-n byte_count] [-o offset] [-p(ipe) ] [-q(uiet)] [-s(ize)]\n"
   92     "         [-v(erbose)] file...\n");
   93 }
   94 
   95 
   96 static void
   97 encode_hash (unsigned char *string, unsigned char *hash, int bytes, int use_base64)
   98 {
   99   int i, j;
  100   static const unsigned char base64_table[65] =
  101     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
  102   static const unsigned char hex_table[65] = "0123456789abcdef";
  103 
  104   j = 0;
  105   if (use_base64) {
  106     for (i = 0; i < (bytes / 3); ++i) {
  107       string[j++] = base64_table[hash[i*3] >> 2];
  108       string[j++] = base64_table[((hash[i*3] & 0x03) << 4) | (hash[i*3+1] >> 4)];
  109       string[j++] = base64_table[((hash[i*3+1] & 0x0F) << 2) | (hash[i*3+2] >> 6)];
  110       string[j++] = base64_table[hash[i*3+2] & 0x3F];
  111     }
  112     if ((bytes % 3) == 2) {
  113       string[j++] = base64_table[hash[bytes-2] >> 2];
  114       string[j++] = base64_table[((hash[bytes-2] & 0x03) << 4) | (hash[bytes-1] >> 4)];
  115       string[j++] = base64_table[(hash[bytes-1] & 0x0F) << 2];
  116     }
  117     else if ((bytes % 3) == 1) {
  118       string[j++] = base64_table[hash[bytes-1] >> 2];
  119       string[j++] = base64_table[(hash[bytes-1] & 0x03) << 4];
  120     }
  121     string[j++] = '\000';
  122   }
  123   else {
  124     for (i = 0; i < bytes; ++i) {
  125       string[j++] = hex_table[hash[i] >> 4];
  126       string[j++] = hex_table[hash[i] & 0x0F];
  127     }
  128     string[j++] = '\000';
  129   }
  130 }
  131 
  132 
  133 static void
  134 print_filehash (char *filename, off_t offset, off_t read_bytes, int print_size,
  135   int run_md5, int run_sha1, int run_sha224, int run_sha256, int run_sha384,
  136   int run_sha512, int run_blake2b_256, int run_blake2b_512, int classic,
  137   int use_base64, int verbose)
  138 {
  139   FILE *file;
  140   int i, not_first, rc;
  141   struct stat file_stats;
  142   unsigned char md5result[16], sha1result[20], sha224result[28],
  143                 sha256result[32], sha384result[48], sha512result[64],
  144                 blake2b_256result[32], blake2b_512result[64], string[129];
  145 
  146   if (stat (filename, &file_stats))
  147     fprintf (stderr, "filehash error: can't stat %s\n", filename);
  148   else if (((file_stats.st_mode & S_IFDIR) != S_IFDIR) &&
  149            ((file_stats.st_mode & S_IFREG) == S_IFREG))
  150     {
  151       if ((file = fopen (filename, "rb")) == NULL)
  152         fprintf (stderr, "filehash error: can't open %s\n", filename);
  153       else
  154         {
  155           not_first = 0;
  156           if (run_md5) {
  157             if (not_first || (offset > 0))
  158               (void) fseek (file, (off_t) offset, 0);
  159             rc = md5_stream (file, md5result, read_bytes);
  160             if (rc)
  161               fprintf (stderr, "filehash error: md5_stream failed on %s\n", filename);
  162             not_first = 1;
  163           }
  164           if (run_sha1) {
  165             if (not_first || (offset > 0))
  166               (void) fseek (file, (off_t) offset, 0);
  167             rc = sha1_stream (file, sha1result, read_bytes);
  168             if (rc)
  169               fprintf (stderr, "filehash error: sha1_stream failed on %s\n", filename);
  170             not_first = 1;
  171           }
  172           if (run_sha224) {
  173             if (not_first || (offset > 0))
  174               (void) fseek (file, (off_t) offset, 0);
  175             rc = sha224_stream (file, sha224result, read_bytes);
  176             if (rc)
  177               fprintf (stderr, "filehash error: sha224_stream failed on %s\n", filename);
  178             not_first = 1;
  179           }
  180           if (run_sha256) {
  181             if (not_first || (offset > 0))
  182               (void) fseek (file, (off_t) offset, 0);
  183             rc = sha256_stream (file, sha256result, read_bytes);
  184             if (rc)
  185               fprintf (stderr, "filehash error: sha256_stream failed on %s\n", filename);
  186             not_first = 1;
  187           }
  188           if (run_sha384) {
  189             if (not_first || (offset > 0))
  190               (void) fseek (file, (off_t) offset, 0);
  191             rc = sha384_stream (file, sha384result, read_bytes);
  192             if (rc)
  193               fprintf (stderr, "filehash error: sha384_stream failed on %s\n", filename);
  194             not_first = 1;
  195           }
  196           if (run_sha512) {
  197             if (not_first || (offset > 0))
  198               (void) fseek (file, (off_t) offset, 0);
  199             rc = sha512_stream (file, sha512result, read_bytes);
  200             if (rc)
  201               fprintf (stderr, "filehash error: sha512_stream failed on %s\n", filename);
  202             not_first = 1;
  203           }
  204           if (run_blake2b_256) {
  205             if (not_first || (offset > 0))
  206               (void) fseek (file, (off_t) offset, 0);
  207             rc = blake2b_stream (file, blake2b_256result, 32, read_bytes);
  208             if (rc)
  209               fprintf (stderr, "filehash error: sha384_stream failed on %s\n", filename);
  210             not_first = 1;
  211           }
  212           if (run_blake2b_512) {
  213             if (not_first || (offset > 0))
  214               (void) fseek (file, (off_t) offset, 0);
  215             rc = blake2b_stream (file, blake2b_512result, 64, read_bytes);
  216             if (rc)
  217               fprintf (stderr, "filehash error: sha512_stream failed on %s\n", filename);
  218             not_first = 1;
  219           }
  220           (void) fclose (file);
  221           not_first = 0;
  222           if ((verbose == 1) && (classic == 0)) {
  223             fprintf (stdout, "%s", filename);
  224             not_first = 1;
  225           }
  226           if (print_size) {
  227             if (classic) {
  228               fprintf (stdout, sizefmt, file_stats.st_size);
  229               fprintf (stdout, "  %s\n", filename);
  230             }
  231             else {
  232               if (not_first)
  233                 fprintf (stdout, "\t");
  234               not_first = 1;
  235               fprintf (stdout, sizefmt, file_stats.st_size);
  236             }
  237           }
  238           if (run_md5) {
  239             encode_hash(string, md5result, 16, use_base64);
  240             if (classic)
  241               fprintf (stdout, "%s  %s\n", string, filename);
  242             else {
  243               if (not_first)
  244                 fprintf (stdout, "\t");
  245               not_first = 1;
  246               fprintf (stdout, "%s", string);
  247             }
  248           }
  249           if (run_sha1) {
  250             encode_hash(string, sha1result, 20, use_base64);
  251             if (classic)
  252               fprintf (stdout, "%s  %s\n", string, filename);
  253             else {
  254               if (not_first)
  255                 fprintf (stdout, "\t");
  256               not_first = 1;
  257               fprintf (stdout, "%s", string);
  258             }
  259           }
  260           if (run_sha224) {
  261             encode_hash(string, sha224result, 28, use_base64);
  262             if (classic)
  263               fprintf (stdout, "%s  %s\n", string, filename);
  264             else {
  265               if (not_first)
  266                 fprintf (stdout, "\t");
  267               not_first = 1;
  268               fprintf (stdout, "%s", string);
  269             }
  270           }
  271           if (run_sha256) {
  272             encode_hash(string, sha256result, 32, use_base64);
  273             if (classic)
  274               fprintf (stdout, "%s  %s\n", string, filename);
  275             else {
  276               if (not_first)
  277                 fprintf (stdout, "\t");
  278               not_first = 1;
  279               fprintf (stdout, "%s", string);
  280             }
  281           }
  282           if (run_sha384) {
  283             encode_hash(string, sha384result, 48, use_base64);
  284             if (classic)
  285               fprintf (stdout, "%s  %s\n", string, filename);
  286             else {
  287               if (not_first)
  288                 fprintf (stdout, "\t");
  289               not_first = 1;
  290               fprintf (stdout, "%s", string);
  291             }
  292           }
  293           if (run_sha512) {
  294             encode_hash(string, sha512result, 64, use_base64);
  295             if (classic)
  296               fprintf (stdout, "%s  %s\n", string, filename);
  297             else {
  298               if (not_first)
  299                 fprintf (stdout, "\t");
  300               not_first = 1;
  301               fprintf (stdout, "%s", string);
  302             }
  303           }
  304           if (run_blake2b_256) {
  305             encode_hash(string, blake2b_256result, 32, use_base64);
  306             if (classic)
  307               fprintf (stdout, "%s  %s\n", string, filename);
  308             else {
  309               if (not_first)
  310                 fprintf (stdout, "\t");
  311               not_first = 1;
  312               fprintf (stdout, "%s", string);
  313             }
  314           }
  315           if (run_blake2b_512) {
  316             encode_hash(string, blake2b_512result, 64, use_base64);
  317             if (classic)
  318               fprintf (stdout, "%s  %s\n", string, filename);
  319             else {
  320               if (not_first)
  321                 fprintf (stdout, "\t");
  322               not_first = 1;
  323               fprintf (stdout, "%s", string);
  324             }
  325           }
  326           if (classic == 0)
  327             fprintf (stdout, "\n");
  328         }
  329     }
  330 }
  331 
  332 
  333 int
  334 main (int argc, char **argv)
  335 {
  336   FILE *infile;
  337   char filename[PATH_MAX], *listname, *newline, *rc;
  338   int argn, classic, offset, opt, print_size, run_md5, run_sha1, run_sha224,
  339       run_sha256, run_sha384, run_sha512, run_blake2b_256, run_blake2b_512,
  340       use_base64, use_file, use_pipe, verbose;
  341   off_t read_bytes, tmp_bytes;
  342 
  343   /* parse options */
  344 
  345   classic = 0;
  346   listname = "";
  347   offset = 0;
  348   print_size = 0;
  349   read_bytes = -1;
  350   run_md5 = 0;
  351   run_sha1 = 0;
  352   run_sha224 = 0;
  353   run_sha256 = 0;
  354   run_sha384 = 0;
  355   run_sha512 = 0;
  356   run_blake2b_256 = 0;
  357   run_blake2b_512 = 0;
  358   use_base64 = 0;
  359   use_file = 0;
  360   use_pipe = 0;
  361   verbose = 0;
  362   while ((opt = getopt (argc, argv, "12345678bcf:hpn:o:qsv")) != OPTEND)
  363     switch (opt)
  364       {
  365       case '1':
  366         run_md5 = 1;
  367         break;
  368       case '2':
  369         run_sha1 = 1;
  370         break;
  371       case '3':
  372         run_sha224 = 1;
  373         break;
  374       case '4':
  375         run_sha256 = 1;
  376         break;
  377       case '5':
  378         run_sha384 = 1;
  379         break;
  380       case '6':
  381         run_sha512 = 1;
  382         break;
  383       case '7':
  384         run_blake2b_256 = 1;
  385         break;
  386       case '8':
  387         run_blake2b_512 = 1;
  388         break;
  389       case 'b':
  390         use_base64 = 1;
  391         break;
  392       case 'c':
  393         classic = 1;
  394         break;
  395       case 'f':
  396         use_file = 1;
  397         listname = optarg;
  398         break;
  399       case 'h':
  400         help (stdout);
  401         return (0);
  402       case 'n':
  403         tmp_bytes = (sizeof (off_t) <= sizeof (long) ? atol(optarg) : atoll(optarg));
  404         if (tmp_bytes > 0)
  405           read_bytes = tmp_bytes;
  406         else
  407           read_bytes = 0;
  408         break;
  409       case 'o':
  410         tmp_bytes = (sizeof (off_t) <= sizeof (long) ? atol(optarg) : atoll(optarg));
  411         if (tmp_bytes > 0)
  412           offset = tmp_bytes;
  413         else
  414           offset = 0;
  415         break;
  416       case 'p':
  417         use_pipe = 1;
  418         break;
  419       case 'q':
  420         verbose = -1;
  421         break;
  422       case 's':
  423         print_size = 1;
  424         break;
  425       case 'v':
  426         verbose = 1;
  427         break;
  428       case '?':
  429         help (stderr);
  430         return (1);
  431       }
  432 
  433   /* finalize options */
  434 
  435   if ((optind == argc) && (use_file == 0) && (use_pipe == 0))
  436     {
  437       help (stdout);
  438       return (0);
  439     }
  440   if (verbose == 0)
  441     {
  442       if (((argc - optind) != 1) || use_file || use_pipe)
  443         verbose = 1;
  444       else
  445         verbose = -1;
  446     }
  447   if ((run_md5 + run_sha1 + run_sha224 + run_sha256 + run_sha384 + run_sha512 +
  448     run_blake2b_256 + run_blake2b_512) == 0)
  449       run_sha256 = 1;
  450 
  451   /* process files in listed in file specified by -f option */
  452 
  453   if (use_file)
  454     {
  455       infile = fopen (listname, "r");
  456       if (infile == NULL)
  457         fprintf (stderr, "filehash error: can't open %s!\n", listname);
  458       else
  459         {
  460           while (!feof (infile))
  461             {
  462               rc = fgets (filename, PATH_MAX - 1, infile);
  463               if (rc != NULL)
  464                 {
  465                   newline = strchr (filename, '\n');
  466                   if (newline != NULL)
  467                     *newline = '\0';
  468                   if (strlen (filename) != 0)
  469                     print_filehash (filename, offset, read_bytes, print_size,
  470                       run_md5, run_sha1, run_sha224, run_sha256, run_sha384,
  471                       run_sha512, run_blake2b_256, run_blake2b_512, classic,
  472                       use_base64, verbose);
  473                 }
  474             }
  475           (void) fclose (infile);
  476         }
  477     }
  478 
  479   /* process files listed on stdin (i.e., the -p option) */
  480 
  481   if (use_pipe)
  482     while (!feof (stdin))
  483       {
  484         rc = fgets (filename, PATH_MAX - 1, stdin);
  485         if (rc != NULL)
  486           {
  487             newline = strchr (filename, '\n');
  488             if (newline != NULL)
  489               *newline = '\0';
  490             if (strlen (filename) != 0)
  491               print_filehash (filename, offset, read_bytes, print_size, run_md5,
  492                 run_sha1, run_sha224, run_sha256, run_sha384, run_sha512,
  493                 run_blake2b_256, run_blake2b_512, classic, use_base64, verbose);
  494           }
  495       }
  496 
  497   /* process files given in the argument list */
  498 
  499   for (argn = optind; argn < argc; argn++)
  500     print_filehash (argv[argn], offset, read_bytes, print_size, run_md5,
  501       run_sha1, run_sha224, run_sha256, run_sha384, run_sha512,
  502       run_blake2b_256, run_blake2b_512, classic, use_base64, verbose);
  503 
  504   /* indicate successful finish */
  505 
  506   return (0);
  507 }