"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 }