11/* Compute and validate checksums of files.
22 *
3- * Copyright (C) 2017 Mark Pizzolato.
3+ * Copyright (C) 2017-2023 Mark Pizzolato.
44 * All Rights Reserved.
55 *
66 * This program is free software; you can redistribute it and/or modify
4646
4747#define VERSION "2.0RC2"
4848
49- #define FLG_CHECK 1
50- #define FLG_QUIET 2
51- #define FLG_STATUS 4
52- #define FLG_WARN 8
53- #define FLG_STRICT 16
54- #define FLG_BINARY 32
55- #define FLG_TEXT 64
56- #define FLG_BSDTAG 128
57- #define FLG_IGNORE 256
58- #define FLG_ZERO 512
59- #define FLG_RECURSE 1024
60- #define FLG_CMDARG 2048
49+ #define FLG_CHECK 0X0001
50+ #define FLG_QUIET 0X0002
51+ #define FLG_STATUS 0X0004
52+ #define FLG_WARN 0X0008
53+ #define FLG_STRICT 0X0010
54+ #define FLG_BINARY 0X0020
55+ #define FLG_TEXT 0X0040
56+ #define FLG_BSDTAG 0X0080
57+ #define FLG_IGNORE 0X0100
58+ #define FLG_ZERO 0X0200
59+ #define FLG_RECURSE 0X0400
60+ #define FLG_CMDARG 0X0800
6161
6262#define MIN (a ,b ) ((a<b) ? (a) : (b))
6363
@@ -400,6 +400,9 @@ if (Algorithms)
400400 fprintf (stdout ,
401401"\n"
402402" The following three options are useful only when verifying checksums:\n"
403+ " --ignore-missing\n"
404+ " don't fail or report status for missing files\n"
405+ "\n"
403406" --quiet\n"
404407" don't print OK for each successfully verified file\n"
405408"\n"
@@ -437,7 +440,7 @@ if (Algorithms)
437440" Report %s bugs to mark@infocomm.com\n"
438441"\n"
439442"COPYRIGHT\n"
440- " Copyright (c) 2017 Mark Pizzolato. All Rights Reserved.\n"
443+ " Copyright (c) 2017-2023 Mark Pizzolato. All Rights Reserved.\n"
441444" There is NO WARRANTY, to the extent permitted by law.\n"
442445"\n"
443446"\n" ,
@@ -739,7 +742,7 @@ ProcessFile(BCRYPT_ALG_HANDLE hAlg, const char *file, int flags)
739742 {
740743 int status ;
741744 FILE * f ;
742- char * open_mode = (flags & FLG_TEXT ) ? "rt" : "rb" ;
745+ char * open_mode = (flags & FLG_TEXT ) ? "rt" : "rb" ;
743746 char * hash = NULL ;
744747 wchar_t AlgorithmNameW [32 ];
745748 char AlgorithmName [sizeof (AlgorithmNameW )];
@@ -802,16 +805,17 @@ ProcessFile(BCRYPT_ALG_HANDLE hAlg, const char *file, int flags)
802805 }
803806 if (statb .st_mode & _S_IFDIR )
804807 {
805- fprintf (stderr , "%s: %s: Is a directory\n" , GetProgramBaseName (), FileName );
808+ if ((flags & FLG_RECURSE ) == 0 )
809+ fprintf (stderr , "%s: %s: Is a directory\n" , GetProgramBaseName (), FileName );
806810 continue ;
807811 }
808- status = ProcessFile (hAlg , FileName , flags & ~(FLG_RECURSE | FLG_CMDARG ));
812+ status = ProcessFile (hAlg , FileName , flags & ~(FLG_RECURSE | FLG_CMDARG ));
809813 if (status )
810814 return_status = status ;
811815 } while (FindNextFileA (hFind , & File ));
812816 FindClose (hFind );
813817 }
814- if (flags & FLG_RECURSE )
818+ if (flags & FLG_RECURSE )
815819 {
816820 char WildPath [MAX_PATH + 1 ];
817821 char DirPath [MAX_PATH + 1 ];
@@ -860,8 +864,11 @@ ProcessFile(BCRYPT_ALG_HANDLE hAlg, const char *file, int flags)
860864 }
861865 else
862866 {
863- fprintf (stderr , "%s: %s: Is a directory\n" , GetProgramBaseName (), file );
864- return EXIT_FAILURE ;
867+ if (flags & FLG_RECURSE )
868+ {
869+ fprintf (stderr , "%s: %s: Is a directory\n" , GetProgramBaseName (), file );
870+ return EXIT_FAILURE ;
871+ }
865872 }
866873 }
867874 }
@@ -884,8 +891,8 @@ ProcessFile(BCRYPT_ALG_HANDLE hAlg, const char *file, int flags)
884891 flags &= ~FLG_BINARY ;
885892 else
886893 flags |= FLG_BINARY ;
887- fprintf (stderr , "%s mode _setmode for stdin\n" , (flags & FLG_BINARY ) ? "Binary" : "Text" );
888- _setmode (fileno (stdin ), (flags & FLG_BINARY ) ? _O_BINARY : _O_TEXT );
894+ fprintf (stderr , "%s mode _setmode for stdin\n" , (flags & FLG_BINARY ) ? "Binary" : "Text" );
895+ _setmode (fileno (stdin ), (flags & FLG_BINARY ) ? _O_BINARY : _O_TEXT );
889896 f = stdin ;
890897 }
891898 else
@@ -895,7 +902,7 @@ ProcessFile(BCRYPT_ALG_HANDLE hAlg, const char *file, int flags)
895902 fprintf (stderr , "Error Opening '%s': %s\n" , file , strerror (errno ));
896903 return EXIT_FAILURE ;
897904 }
898- if (flags & FLG_CHECK )
905+ if (flags & FLG_CHECK )
899906 {
900907 char * line_buf = NULL ;
901908 size_t line_buf_size = 0 ;
@@ -907,6 +914,19 @@ ProcessFile(BCRYPT_ALG_HANDLE hAlg, const char *file, int flags)
907914 int open_or_io_errors = 0 ;
908915 BCRYPT_ALG_HANDLE hCheckAlg = INVALID_HANDLE_VALUE ;
909916
917+ #define LINE_CLEANUP \
918+ do \
919+ { \
920+ if (check != stdin) \
921+ fclose(check); \
922+ if (hCheckAlg != INVALID_HANDLE_VALUE) \
923+ { \
924+ CloseHashAlgorithmProvider(hCheckAlg); \
925+ hCheckAlg = INVALID_HANDLE_VALUE; \
926+ } \
927+ free(file_hash); \
928+ } while (0)
929+
910930 while (0 < (line_size = GetLine (& line_buf , & line_buf_size , f )))
911931 {
912932 char * file_hash ;
@@ -938,7 +958,7 @@ ProcessFile(BCRYPT_ALG_HANDLE hAlg, const char *file, int flags)
938958 {
939959 if (NULL == (check = fopen (file , open_mode )))
940960 {
941- if ((flags & FLG_IGNORE ) && (errno == ENOENT ))
961+ if ((flags & FLG_IGNORE ) && (errno == ENOENT ))
942962 continue ; /* Next line */
943963 ++ open_or_io_errors ;
944964 fprintf (stderr , "%s: Error Opening '%s': %s\n" , GetProgramBaseName (), file , strerror (errno ));
@@ -957,18 +977,6 @@ ProcessFile(BCRYPT_ALG_HANDLE hAlg, const char *file, int flags)
957977 }
958978 }
959979 line_stat = GetFileHash ((algo && (hCheckAlg != INVALID_HANDLE_VALUE )) ? hCheckAlg : hAlg , check , & file_hash );
960- #define LINE_CLEANUP \
961- do \
962- { \
963- if (check != stdin) \
964- fclose(check); \
965- if (hCheckAlg != INVALID_HANDLE_VALUE) \
966- { \
967- CloseHashAlgorithmProvider(hCheckAlg); \
968- hCheckAlg = INVALID_HANDLE_VALUE; \
969- } \
970- free(file_hash); \
971- } while (0)
972980 if (line_stat != EXIT_SUCCESS )
973981 {
974982 LINE_CLEANUP ;
@@ -992,7 +1000,7 @@ ProcessFile(BCRYPT_ALG_HANDLE hAlg, const char *file, int flags)
9921000 /* binary mode failure */
9931001 status = EXIT_FAILURE ;
9941002 ++ mis_matches ;
995- if (!(flags & FLG_QUIET ))
1003+ if (!(flags & FLG_QUIET ))
9961004 fprintf (stdout , "%s: FAILED\n" , file );
9971005 LINE_CLEANUP ;
9981006 continue ; /* Next line */
@@ -1003,18 +1011,18 @@ ProcessFile(BCRYPT_ALG_HANDLE hAlg, const char *file, int flags)
10031011 /* binary mode failure */
10041012 status = EXIT_FAILURE ;
10051013 ++ mis_matches ;
1006- if (!(flags & FLG_QUIET ))
1014+ if (!(flags & FLG_QUIET ))
10071015 fprintf (stdout , "%s: FAILED\n" , file );
10081016 LINE_CLEANUP ;
10091017 continue ; /* Next line */
10101018 }
10111019 }
10121020 LINE_CLEANUP ;
10131021 ++ matches ;
1014- if (!(flags & FLG_QUIET ))
1022+ if (!(flags & FLG_QUIET ))
10151023 fprintf (stdout , "%s: OK\n" , file );
10161024 }
1017- if (!(flags & FLG_STATUS ))
1025+ if (!(flags & FLG_STATUS ))
10181026 {
10191027 if (bad_lines )
10201028 fprintf (stderr , "%s: WARNING: %d line%s improperly formatted\n" , GetProgramBaseName (), bad_lines , (bad_lines == 1 ) ? " is" : "s are" );
@@ -1029,7 +1037,7 @@ ProcessFile(BCRYPT_ALG_HANDLE hAlg, const char *file, int flags)
10291037 }
10301038 else
10311039 {
1032- if ((flags & (FLG_BINARY | FLG_TEXT )) == 0 )
1040+ if ((flags & (FLG_BINARY | FLG_TEXT )) == 0 )
10331041 { /* No mode specified, auto detect text/binary files */
10341042 fclose (f );
10351043 f = fopen (file , "rb" );
@@ -1043,7 +1051,7 @@ ProcessFile(BCRYPT_ALG_HANDLE hAlg, const char *file, int flags)
10431051 status = GetFileHash (hAlg , f , & hash );
10441052 if (hash )
10451053 {
1046- if (flags & FLG_BSDTAG )
1054+ if (flags & FLG_BSDTAG )
10471055 {
10481056 fprintf (stdout , "%s (" , AlgorithmName );
10491057 if (f == stdin )
@@ -1070,7 +1078,7 @@ ProcessFile(BCRYPT_ALG_HANDLE hAlg, const char *file, int flags)
10701078 fprintf (stdout , "%c" , (file [i ] == '\\' ) ? '/' : file [i ]);
10711079 }
10721080 }
1073- if (flags & FLG_ZERO )
1081+ if (flags & FLG_ZERO )
10741082 fputc ('\0' , stdout );
10751083 else
10761084 fprintf (stdout , "\n" );
0 commit comments