X-Git-Url: https://jxself.org/git/?p=skeinsum.git;a=blobdiff_plain;f=skein_cli.c;h=e95f4b60844f9e90db443def874a87c9e453d678;hp=bbe820c4082c4316bbf36f9084cc95c8fd5f4803;hb=a20d5ede618124ecba406fcca37cf92dbc202997;hpb=f92102e1a10a938eaad61481658409dd9b686d54 diff --git a/skein_cli.c b/skein_cli.c index bbe820c..e95f4b6 100644 --- a/skein_cli.c +++ b/skein_cli.c @@ -31,85 +31,73 @@ along with skeinsum. If not, see . #include #include "SHA3api_ref.h" +#define WARN(msg, ...) fprintf(stderr, "skein%dsum: " msg, hashbitlen, ##__VA_ARGS__) + +#define TRYHELP_GOODBYE() do { printf("Try 'skein%dsum --help' for more information.\n", hashbitlen); exit(1); } while(0) + +typedef long long unsigned LLU; + extern const int hashbitlen; -#define MaxNmberFiles 10 #define skeinVersion "1.3" + const size_t input_minbufsize = 32 * 1024; const size_t input_maxbufsize = 32 * 1024 * 1024; -char invalidOption = 0; - enum { QUIET_OPTION = 11, STATUS_OPTION, - TAG_OPTION, - HELP_OPTION, - VERSION_OPTION + TAG_OPTION }; static struct option const long_options[] = { - { "binary", no_argument, NULL, 'b' }, - { "check", no_argument, NULL, 'c' }, - { "quiet", no_argument, NULL, QUIET_OPTION }, - { "status", no_argument, NULL, STATUS_OPTION }, - { "text", no_argument, NULL, 't' }, - { "warn", no_argument, NULL, 'w' }, - { "tag", no_argument, NULL, TAG_OPTION }, - { "help", no_argument, NULL, HELP_OPTION }, - { "version", no_argument, NULL, VERSION_OPTION }, + { "binary", no_argument, NULL, 'b' }, + { "check", no_argument, NULL, 'c' }, + { "quiet", no_argument, NULL, QUIET_OPTION }, + { "status", no_argument, NULL, STATUS_OPTION }, + { "text", no_argument, NULL, 't' }, + { "warn", no_argument, NULL, 'w' }, + { "tag", no_argument, NULL, TAG_OPTION }, + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, 'V' }, { NULL, 0, NULL, 0 } }; -void printHexMsg(unsigned char *ptr, int size, char result[]) +void hash2hexstr(unsigned char hash[], char str[]) { - int i = 0; - int j = 0; - char High, Low; - for (i = 0 ; i < size ; i ++) - { - High = ptr[i]>>4; - Low = ptr[i]&0x0F; - - if (High >= 0xA && High <= 0xF) - High += 0x37; - else if(High >= 0x0 && High <= 0x9) - High += 0x30; - - if (Low >= 0xA && Low <= 0xF) - Low += 0x37; - else if(Low >= 0x0 && Low <= 0x9) - Low += 0x30; - - result[j++] = High; - result[j++] = Low; + int i; + for (i = 0; i < hashbitlen / 8; i++) { + sprintf(&str[i * 2], "%02X", hash[i]); } - result[i] = 0; + str[i * 2 + 1] = '\0'; } -int HashWithMode(char file_name[], char MsgDigest[], char mode) +int HashFile(const char file_name[], char MsgDigest[], char mode) { + int is_stdin = (strcmp(file_name, "-") == 0); + /* Try to get file info */ struct stat st; - if (stat(file_name, &st) < 0) { - printf("skein%dsum: %s: STAT FAILED: %s\n", hashbitlen, file_name, strerror(errno)); + st.st_size = 0; /* ..needed when reading from stdio */ + if (!is_stdin && stat(file_name, &st) < 0) { + WARN("%s: cannot stat: %s\n", file_name, strerror(errno)); return -1; } /* Get filesize */ size_t fsize = st.st_size; if (fsize != st.st_size) { - printf("skein%dsum: %s: SIZE WARNING: filesize %llu is too big for reading into memory!\n", - hashbitlen, file_name, (long long unsigned)st.st_size); + WARN("%s: SIZE WARNING: filesize %llu is too big for reading into memory!\n", + file_name, (long long unsigned)st.st_size); } /* Open file */ - FILE *fp_in = fopen(file_name, (mode == 't' ? "r" : "rb") ); + FILE *fp_in = is_stdin ? stdin : fopen(file_name, (mode == 't' ? "r" : "rb") ); if (!fp_in) { - printf("skein%dsum: %s: OPEN FAILED: %s\n", hashbitlen, file_name, strerror(errno)); + WARN("%s: cannot open: %s\n", file_name, strerror(errno)); return -1; } @@ -125,30 +113,37 @@ int HashWithMode(char file_name[], char MsgDigest[], char mode) } if (!readbuf) { - printf("skein%dsum: %s: MEM FAILED: %s\n", hashbitlen, file_name, strerror(errno)); - fclose(fp_in); + WARN("%s: MEM FAILED: error %s\n", file_name, strerror(errno)); + if (!is_stdin) + fclose(fp_in); return -1; } /* Read contents */ - size_t readpos = 0, readed, total_readed = 0; + size_t readpos = 0, total_readed = 0; while (1) { size_t maxread = bufsize - readpos; - readed = fread(readbuf, 1, maxread, fp_in); + size_t readed = fread(readbuf + readpos, 1, maxread, fp_in); if (readed > 0 && readed <= maxread) total_readed += readed; if (readed != maxread) break; if (getenv("SKEIN_DEBUG")) - printf("DEBUG: bufsize=%u (0x%x), readpos=%u (0x%x), maxread=%u (0x%x), total=%u (0x%x)\n", - bufsize, bufsize, readpos, readpos, maxread, maxread, total_readed, total_readed); + printf("DEBUG: bufsize=%llu (0x%llx), readpos=%llu (0x%llx), maxread=%llu (0x%llx), total=%llu (0x%llx)\n", + (LLU)bufsize, (LLU)bufsize, (LLU)readpos, (LLU)readpos, + (LLU)maxread, (LLU)maxread, (LLU)total_readed, (LLU)total_readed); char *newbuf = NULL; if (bufsize * 2 > bufsize) /* ..check overflow */ newbuf = realloc(readbuf, bufsize * 2); if (!newbuf) { - printf("skein%dsum: %s: MEM WARNING: %u bytes only readed from %llu\n", - hashbitlen, file_name, total_readed, (long long unsigned)st.st_size); + if (total_readed < st.st_size) { + WARN("%s: MEM WARNING: %llu bytes only readed from %llu\n", + file_name, (LLU)total_readed, (LLU)st.st_size); + } else { + WARN("%s: MEM WARNING: %llu bytes only readed.\n", + file_name, (LLU)total_readed); + } break; } readbuf = newbuf; @@ -156,52 +151,78 @@ int HashWithMode(char file_name[], char MsgDigest[], char mode) bufsize *= 2; } - if (total_readed < st.st_size && total_readed < bufsize) { - printf("skein%dsum: %s: READ WARNING: filesize=%llu, readed=%u, %s\n", - hashbitlen, file_name, (long long unsigned)st.st_size, total_readed, strerror(errno)); + if (!is_stdin) + fclose(fp_in); + + if (!is_stdin && total_readed < st.st_size && total_readed < bufsize) { + WARN("%s: READ WARNING: filesize=%llu, readed=%llu, error %d, %s\n", + file_name, (LLU)st.st_size, (LLU)total_readed, errno, strerror(errno)); } - fclose(fp_in); + if (getenv("SKEIN_DUMP")) { + printf("DEBUG: file=%s, bufsize=%llu (0x%llx), total_readed=%llu, buf:\n", + file_name, (LLU)bufsize, (LLU)bufsize, (LLU)total_readed); + fwrite(readbuf, 1, total_readed, stdout); + } unsigned char output[hashbitlen/4]; Hash(hashbitlen, (unsigned char*) readbuf, total_readed, output); free(readbuf); - printHexMsg(output,hashbitlen/4,MsgDigest); + hash2hexstr(output, MsgDigest); return 1; } -int HashTextMode(char file_name[], char MsgDigest[]) +int PrintFileHash(const char filename[], int tag, char mode) { - return HashWithMode(file_name, MsgDigest, 't'); + char MsgDigest[hashbitlen/2]; + if (HashFile(filename, MsgDigest, mode) < 0) + return -1; + if (tag == 1) { + printf("skein%d_v%s (%s) = %s\n", hashbitlen, skeinVersion, filename, MsgDigest); + } else { + printf("%s %s%s\n", MsgDigest, (mode == 'b' ? "*" : ""), filename); + } + return 1; } -int HashBinaryMode(char file_name[], char MsgDigest[]) +/* Return: -1 = Error, 0 = Mismatch, 1 = Match */ +int HashMatch(const char StoredDigest[], const char *filename, int quiet) { - return HashWithMode(file_name, MsgDigest, 'b'); -} + char mode = 't'; + if (filename[0] == '*') { + filename++; + mode = 'b'; + } + + char MsgDigest[hashbitlen/2]; + if (HashFile(filename, MsgDigest, mode) < 0) + return -1; -int HashStringMode(char Msg[],char MsgDigest[]) -{ - unsigned char output[hashbitlen/4]; - Hash(hashbitlen,(unsigned char*) Msg,sizeof(Msg),output); - printHexMsg(output,hashbitlen/4,MsgDigest); + if (strcmp(MsgDigest, StoredDigest)) { + printf("%s: FAILED\n", filename); + return 0; + } + + if (quiet > 0) + printf("%s: OK\n", filename); return 1; } -int isProper(char MsgDigest[]) +int isProper(const char MsgDigest[]) { - if ((strlen(MsgDigest) - hashbitlen/4) != 0) + int len = strlen(MsgDigest); + if (len != (hashbitlen / 4)) return 0; int index = 0; - char c = 0; - for(index = 0; index < strlen(MsgDigest);index++) + for (index = 0; index < len; index++) { - c = MsgDigest[index]; - if(!(( c >= '0' && c <= '9' ) || ( c >= 'A' && c <= 'F'))) - return 0; + char c = MsgDigest[index]; + if (c >= '0' && c <= '9') continue; + if (c >= 'A' && c <= 'F') continue; + return 0; } return 1; @@ -293,6 +314,58 @@ int decomposeHashLine(char hash[], char MsgDigest_tmp[], char file_tmp[]) } +/* Return: -1 = some errors/mismatches, 1 = all ok */ +int VerifyHashesFromFile(FILE *fp, int status, int warn, int quiet) +{ + char hash[PATH_MAX + hashbitlen/4 + 4]; + char MsgDigest_tmp[hashbitlen/2]; + int NoMatch = 0, NotProper = 0, Computed = 0; + int line = 0; + + while (fgets(hash, sizeof(hash)-1, fp)) + { + char file_tmp[PATH_MAX]; + line ++; + Computed++; + int hashVersion = decomposeHashLine(hash,MsgDigest_tmp,file_tmp); + if (hashVersion == -1) + { + WARN("%s is using newer version of skein%d algorithm\n" + "You should update your algorithm\n", + file_tmp, hashbitlen); + continue; + } + else if (hashVersion == 0) + { + WARN("%s is using an older version of skein%d algorithm\n" + "You should use the older algorithm\n", + file_tmp, hashbitlen); + continue; + } + else if (!isProper(MsgDigest_tmp)) + { + if(status != 1 && warn == 1) + WARN("%s: %d: improperly formatted skein%d checksum line\n",file_tmp,line,hashbitlen); + NotProper ++; + NoMatch ++; + } + else if (HashMatch(MsgDigest_tmp, file_tmp, quiet) <= 0) + { + NoMatch++; + } + } + if(NoMatch) + { + WARN("WARNING: %d of %d computed checksums did NOT match\n", + NoMatch, Computed); + } + if(NotProper) + { + WARN("WARNING: %d line is improperly formatted\n", NotProper); + } + return (NotProper || NoMatch) ? -1 : 1; +} + void print_version(void) { printf("skein%dsum 1.0\n", hashbitlen); @@ -307,37 +380,62 @@ void print_usage(void) { printf("Usage: skein%dsum [OPTION]... [FILE]...\n",hashbitlen); printf("Print or check skein (%d-bit) checksums.\n",hashbitlen); - printf("With no FILE, or when FILE is -, read standard input.\n"); - printf("\n"); - printf("-b, --binary read in binary mode\n"); - printf("-c, --check read skein sums from the FILEs and check them\n"); - printf("--tag create a BSD-style checksum\n"); - printf("-t, --text read in text mode (default)\n"); - printf("\n"); - printf("The following three options are useful only when verifying checksums:\n"); - printf("--quiet don't print OK for each successfully verified file\n"); - printf("--status don't output anything, status code shows success\n"); - printf("-w, --warn warn about improperly formatted checksum lines\n"); - printf("\n"); - printf("--strict with --check, exit non-zero for any invalid input\n"); - printf("--help display this help and exit\n"); - printf("--version output version information and exit\n"); - printf("\n"); - printf("The sums are computed as described in version 1.3 of the Skein\n"); - printf("specification. When checking, the input should be a former output of\n"); - printf("this program. The default mode is to print a line with checksum, a\n"); - printf("character indicating input mode ('*' for binary, space for text), and\n"); - printf("name for each FILE.\n"); + printf("With no FILE, or when FILE is -, read standard input.\n" + "\n" + "-b, --binary read in binary mode\n" + "-c, --check read skein sums from the FILEs and check them\n" + "--tag create a BSD-style checksum\n" + "-t, --text read in text mode (default)\n" + "-0 hash strings from command line\n" + "\n" + "The following three options are useful only when verifying checksums:\n" + "--quiet don't print OK for each successfully verified file\n" + "--status don't output anything, status code shows success\n" + "-w, --warn warn about improperly formatted checksum lines\n" + "\n" + "--strict with --check, exit non-zero for any invalid input\n" + "-h, --help display this help and exit\n" + "-V, --version output version information and exit\n" + "\n" + "The sums are computed as described in version 1.3 of the Skein\n" + "specification. When checking, the input should be a former output of\n" + "this program. The default mode is to print a line with checksum, a\n" + "character indicating input mode ('*' for binary, space for text), and\n" + "name for each FILE.\n"); exit(1); } +int is_goodfile(const char filename[]) +{ + if (!strcmp(filename, "-")) + return 1; + + struct stat s; + + if (stat(filename, &s) < 0) { + WARN("%s: no such file or directory\n", filename); + return 0; + } + + if (S_ISREG (s.st_mode)) return 1; + if (S_ISCHR (s.st_mode)) return 1; + if (S_ISBLK (s.st_mode)) return 1; + if (S_ISLNK (s.st_mode)) return 1; + if (S_ISFIFO(s.st_mode)) return 1; + + if (S_ISDIR (s.st_mode)) { + WARN("%s: is a directory\n", filename); + return 0; + } + + WARN("%s: WARNING: unknown filetype 0x%Xu\n", filename, s.st_mode); + return 1; /* try it as good */ +} int main(int argc, char** argv) { - char MsgDigest[hashbitlen/2]; - char *list_files[MaxNmberFiles]; - int number_files = 0; + int first_file = argc; int binary = -1, check = -1, quiet = -1, @@ -351,10 +449,10 @@ int main(int argc, char** argv) /***************************************************************************************** ************************************* GETTING DATA *********************************** *****************************************************************************************/ - while ((opt = getopt_long (argc, argv, "bctw", long_options, NULL)) != -1) + while ((opt = getopt_long (argc, argv, "hVbctw0", long_options, NULL)) != -1) { switch (opt) { - case 0 : hashString = 1; break; + case '0' : hashString = 1; break; case 'b' : binary = 1; break; case 't' : binary = 0; break; case 'c' : check = 1; break; @@ -363,380 +461,113 @@ int main(int argc, char** argv) case STATUS_OPTION : status = 1; break; case TAG_OPTION : tag = 1; break; - case HELP_OPTION : print_usage(); /* ..never returns */ - case VERSION_OPTION : print_version(); /* ..never returns */ + case 'h' : print_usage(); /* ..never returns */ + case 'V' : print_version(); /* ..never returns */ - default: - printf("Try `skein%dsum --help' for more information.\n",hashbitlen); - exit(1); + default: TRYHELP_GOODBYE(); } } - for (; optind < argc; ++optind) - { - struct stat s; - if (stat(argv[optind], &s) < 0) - { - printf("skein%dsum: %s: no such file or directory\n", hashbitlen, argv[optind]); - errorFound = 1; - } - else if (s.st_mode & (S_IFREG|S_IFBLK)) /* ..regular file or block device? */ - { - if (number_files < MaxNmberFiles) { - list_files[number_files++] = argv[optind]; - } else { - printf("skein%dsum: %s: ignore because filelist is too long\n", - hashbitlen, argv[optind]); - } - } - else if (s.st_mode & S_IFDIR) - { - printf("skein%dsum: %s: is a directory\n",hashbitlen,argv[optind]); - errorFound = 1; - } - else - { - printf("skein%dsum: %s: wrong filetype 0x%Xu\n", - hashbitlen, argv[optind], s.st_mode); - errorFound = 1; - } - } + first_file = optind; /***************************************************************************************** ************************************* PROCESSING DATA *********************************** *****************************************************************************************/ - if(argc > 1 && binary == 1) + + if (hashString > 0) { - if (check == 1 || quiet == 1 || warn == 1 || status == 1) - { - printf("skein%dsum: the --binary and --text options are meaningless when verifying checksums\n",hashbitlen); - printf("Try 'skein%dsum --help' for more information.\n",hashbitlen); - exit(0); + int n = first_file; + if (n >= argc) { + WARN("command line should contain strings for hashing\n"); + TRYHELP_GOODBYE(); } - if(number_files > 0) - { - int index_files = 0; - while(index_files < number_files) - { - if(hashString == 1) - { - printf("skein%dsum: %s: No such file or directory\n",hashbitlen,list_files[index_files]); - index_files++; - continue; - } - if(HashBinaryMode(list_files[index_files],MsgDigest)!=-1) - { - if(tag == 1) - { - printf("skein%d_v%s (%s) = %s\n",hashbitlen,skeinVersion,list_files[index_files],MsgDigest); - } - else - { - printf("%s ",MsgDigest); - printf("*%s\n",list_files[index_files]); - } - } - index_files++; - } - } - else if(errorFound != 1) - { // read stdin for strings - char stri[100]; - char longstring[1000]; - longstring[0] = 0; - while((fgets(stri,100,stdin))!=NULL) - { - strcat(longstring,stri); - } - HashStringMode(longstring,MsgDigest); - if(tag == 1) - { - printf("skein%d_v%s (-) = %s\n",hashbitlen,skeinVersion,MsgDigest); - } - else - { - printf("%s *-\n",MsgDigest); - } + for( ; n < argc; n++) { + unsigned char output[hashbitlen/4]; + char digest[hashbitlen/4 + 1]; + Hash(hashbitlen, argv[n], strlen(argv[n]), output); + hash2hexstr(output, digest); + printf("%s -%s\n", digest, argv[n]); } + return 0; } - else if (argc > 1 && binary == 0) // Text Mode + if (check < 0) /* READ FILES, GENERATE CHECKSUMS AND PRINT TO STDOUT.. */ { - if (check == 1 || quiet == 1 || warn == 1 || status == 1) + if (quiet == 1 || warn == 1 || status == 1) { - printf("skein%dsum: the --binary and --text options are meaningless when verifying checksums\n",hashbitlen); - printf("Try 'skein%dsum --help' for more information.\n",hashbitlen); - exit(0); + if(quiet == 1) + WARN("the --quiet option is meaningful only when verifying checksums\n"); + if(status ==1) + WARN("the --status option is meaningful only when verifying checksums\n"); + if(warn == 1) + WARN("the --warn option is meaningful only when verifying checksums\n"); + TRYHELP_GOODBYE(); } - if(number_files > 0) + + char mode = binary > 0 ? 'b' : 't'; + + int file_index; + for (file_index = first_file; file_index < argc; file_index++) { - int index_files = 0; - while(index_files < number_files) - { - if(HashTextMode(list_files[index_files],MsgDigest)!=-1) - { - if(tag == 1) - { - printf("skein%d_v%s (%s) = %s\n",hashbitlen,skeinVersion,list_files[index_files],MsgDigest); - } - else - { - printf("%s ",MsgDigest); - printf("%s\n",list_files[index_files]); - } - } - index_files++; - } - } - else if(errorFound != 1) - { // read stdin for strings - char stri[100]; - char longstring[1000]; - longstring[0] = 0; - while((fgets(stri,100,stdin))!=NULL) - { - strcat(longstring,stri); - } - HashStringMode(longstring,MsgDigest); - if(tag == 1) - { - printf("skein%d_v%s (-) = %s\n",hashbitlen,skeinVersion,MsgDigest); + const char *filename = argv[file_index]; + if (!is_goodfile(filename)) { + errorFound++; + continue; } - else - { - printf("%s -\n",MsgDigest); + + if (binary > 0 && hashString == 1) { + WARN("%s: No such file or directory\n", filename); + continue; } + + if (PrintFileHash(filename, tag, mode) < 0) + errorFound++; } + + if (first_file >= argc) /* no files in cmdline? hash stdin.. */ + if (PrintFileHash("-", tag, mode) < 0) + errorFound++; + + return (errorFound ? 1 : 0); } - else if (argc > 1 && binary == -1) + if (check == 1) /* READ LISTFILES, GENERATE HASHES, COMPARE WITH STORED, PRINT RESULT */ { - if(check == -1) - {// hashing stdin entries - if(quiet == 1 || status == 1 || warn == 1) - { - if(quiet == 1) - printf("skein%dsum: the --quiet option is meaningful only when verifying checksums\n",hashbitlen); - if(status ==1) - printf("skein%dsum: the --status option is meaningful only when verifying checksums\n",hashbitlen); - if(warn == 1) - printf("skein%dsum: the --warn option is meaningful only when verifying checksums\n",hashbitlen); - - printf("Try 'skein%dsum --help' for more information.\n",hashbitlen); - exit(1); - } - if(number_files > 0) - {// hashing files - int index_files = 0; - while(index_files < number_files) - { - if(HashTextMode(list_files[index_files],MsgDigest)!=-1) - { - if(tag == 1) - { - printf("skein%d_v%s (%s) = %s\n",hashbitlen,skeinVersion,list_files[index_files],MsgDigest); - } - else - { - printf("%s ",MsgDigest); - printf("%s\n",list_files[index_files]); - } - } - index_files++; - } - } - else if(errorFound != 1) - { // hasing strings read from stdin - char stri[100]; - char longstring[1000]; /* TODO!!! Fix buffer overflow!!! */ - longstring[0] = 0; - while((fgets(stri,100,stdin))!=NULL) - { - strcat(longstring,stri); - } - HashStringMode(longstring,MsgDigest); - if(tag == 1) - { - printf("skein%d_v%s (-) = %s\n",hashbitlen,skeinVersion,MsgDigest); - } - else - { - printf("%s -\n",MsgDigest); - } - } - } - else if(check == 1) + if (tag == 1 || binary >= 0) { - if(tag == 1) - { - printf("skein%dsum: the --tag option is meaningless when verifying checksums\n",hashbitlen); - printf("Try 'skein%dsum --help' for more information\n",hashbitlen); - exit(1); - } - int index_files = 0; - while(index_files < number_files) - { - FILE *fp; - char hash[500], file_name[100], file_tmp[100], MsgDigest_tmp[hashbitlen/2]; - int NoMatch = 0, NotProper = 0, Computed = 0; - strcpy(file_name,list_files[index_files]); - //show everything - int line = 0; - fp = fopen(file_name,"r"); - if(fp!=NULL) - { - while(fgets(hash,500,fp)!=NULL) - { - line ++; - Computed++; - unsigned int hashVersion = decomposeHashLine(hash,MsgDigest_tmp,file_tmp); - if(hashVersion == -1) - { - printf("skein%d: %s is using newer version of skein%d algorithm\n",hashbitlen,file_tmp,hashbitlen); - printf("You should update your algorithm\n"); - continue; - } - else if( hashVersion == 0) - { - printf("skein%d: %s is using an older version of skein%d algorithm\n",hashbitlen,file_tmp,hashbitlen); - printf("You should use the older algorithm\n"); - continue; - } - else - { - if(!isProper(MsgDigest_tmp)) - { - if(status != 1 && warn == 1) - { - printf("skein%dsum: %s: %d: improperly formatted skein%d checksum line\n",hashbitlen,file_tmp,line,hashbitlen); - } - NotProper ++; - NoMatch ++; - continue; - } - if(file_tmp[0] == '*') - { - int index_file_tmp = 0; - for( ; file_tmp[index_file_tmp+1]!=0 ; index_file_tmp++) - { - file_tmp[index_file_tmp] = file_tmp[index_file_tmp + 1]; - } - file_tmp[index_file_tmp] = 0; - HashBinaryMode(file_tmp,MsgDigest); - } - else - { - HashTextMode(file_tmp,MsgDigest); - } - - if(!strcmp(MsgDigest,MsgDigest_tmp)) - { - if(quiet != 1) - { - printf("%s: OK\n",file_tmp); - } - } - else - { - printf("%s: FAILED\n",file_tmp); - NoMatch ++; - } - } - } - if(NoMatch) - { - printf("skein%dsum: WARNING: %d of %d computed checksums did NOT match\n", - hashbitlen,NoMatch,Computed); - } - if(NotProper) - { - printf("skein%dsum: WARNING: %d line is improperly formatted\n",hashbitlen,NotProper); - } - } - else - { - printf("skein%dsum: %s: No such file or directory\n",hashbitlen,file_name); - } - index_files++; + if (tag == 1) + WARN("the --tag option is meaningless when verifying checksums\n"); + if (binary >= 0) + WARN("the --text and --binary options are meaningless when verifying checksums\n"); + TRYHELP_GOODBYE(); + } + int file_index; + for (file_index = first_file; file_index < argc; file_index++) + { + const char *filename = argv[file_index]; + if (!is_goodfile(filename)) { + errorFound++; + continue; } - if(number_files == 0) - { - char longstring[1000]; - char file_name[30]; - char MsgDigest_tmp[hashbitlen/2]; - int Computed = 0, NotProper = 0, NoMatch = 0 , line = 0; - while((fgets(longstring,1000,stdin))!=NULL) - { - Computed++; - line ++; - decomposeHashLine(longstring,MsgDigest_tmp,file_name); - if(!isProper(MsgDigest_tmp)) - { - if(status != 1 && warn == 1) - { - printf("skein%dsum: %s: %d: improperly formatted skein%d checksum line\n",hashbitlen,file_name,line,hashbitlen); - } - NotProper ++; - NoMatch ++; - continue; - } - if(file_name[0] == '*') - { - int index_file_tmp = 0; - for( ; file_name[index_file_tmp+1]!=0 ; index_file_tmp++) - { - file_name[index_file_tmp] = file_name[index_file_tmp + 1]; - } - file_name[index_file_tmp] = 0; - HashBinaryMode(file_name,MsgDigest); - } - else - { - HashTextMode(file_name,MsgDigest); - } - - if(!strcmp(MsgDigest,MsgDigest_tmp)) - { - if(quiet != 1) - { - printf("%s: OK\n",file_name); - } - } - else - { - printf("%s: FAILED\n",file_name); - NoMatch ++; - } - } - if(NoMatch) - { - printf("skein%dsum: WARNING: %d of %d computed checksums did NOT match\n", - hashbitlen,NoMatch,Computed); - } - if(NotProper) - { - printf("skein%dsum: WARNING: %d line is improperly formatted\n",hashbitlen,NotProper); - } - + FILE *fp = (strcmp(filename, "-") == 0) ? stdin : fopen(filename, "r"); + if (!fp) { + errorFound++; + WARN("%s: %s\n", filename, strerror(errno)); + continue; } - - + if (VerifyHashesFromFile(fp, status, warn, quiet) < 0) + errorFound++; + if (fp != stdin) + fclose(fp); } - } - if ((errorFound != 1) && (argc == 1 || (hashString == 1 && number_files == 0))) - { - char stri[100]; - char longstring[1000]; - longstring[0] = 0; - while((fgets(stri,100,stdin))!=NULL) - { - strcat(longstring,stri); - } - HashStringMode(longstring,MsgDigest); - printf("%s -\n",MsgDigest); + if (first_file >= argc) /* no files in cmdline? verify stdin.. */ + if (VerifyHashesFromFile(stdin, status, warn, quiet) < 0) + errorFound++; + + return (errorFound ? 1 : 0); } return 1;