From 577caa4da26f990464ce3aaea796303b63670a63 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Fri, 30 Jul 2004 00:54:44 +0000 Subject: (OPENOPTS, have_read_stdin, status_only, warn, bsd_split_3, split_3, hex_digits, digest_file, digest_check, main): Use bool when appropriate. (digest_check): Increase limit of number of input lines to UINTMAX_MAX from INT_MAX. Diagnose any overflows of this counter. Use ngettext instead of hard-to-i18nize hardcoded stuff for plurals. --- src/md5sum.c | 208 ++++++++++++++++++++++++++++++----------------------------- 1 file changed, 106 insertions(+), 102 deletions(-) (limited to 'src/md5sum.c') diff --git a/src/md5sum.c b/src/md5sum.c index da4a7caf5..dbb73a280 100644 --- a/src/md5sum.c +++ b/src/md5sum.c @@ -41,12 +41,12 @@ text representations. */ /* FIXME: This begs for an autoconf test. */ #if O_BINARY -# define OPENOPTS(BINARY) ((BINARY) != 0 ? TEXT1TO1 : TEXTCNVT) +# define OPENOPTS(BINARY) ((BINARY) ? TEXT1TO1 : TEXTCNVT) # define TEXT1TO1 "rb" # define TEXTCNVT "r" #else # if defined VMS -# define OPENOPTS(BINARY) ((BINARY) != 0 ? TEXT1TO1 : TEXTCNVT) +# define OPENOPTS(BINARY) ((BINARY) ? TEXT1TO1 : TEXTCNVT) # define TEXT1TO1 "rb", "ctx=stm" # define TEXTCNVT "r", "ctx=stm" # else @@ -78,8 +78,8 @@ + 2 /* blank and binary indicator */ \ + 1 /* minimum filename length */ ) -/* Nonzero if any of the files read were the standard input. */ -static int have_read_stdin; +/* True if any of the files read were the standard input. */ +static bool have_read_stdin; /* The minimum length of a valid checksum line for the selected algorithm. */ static size_t min_digest_line_length; @@ -89,11 +89,11 @@ static size_t digest_hex_bytes; /* With --check, don't generate any output. The exit code indicates success or failure. */ -static int status_only = 0; +static bool status_only = false; /* With --check, print a message to standard error warning about each improperly formatted checksum line. */ -static int warn = 0; +static bool warn = false; /* Declared and set via one of the wrapper .c files. */ /* int algorithm = ALG_UNSPECIFIED; */ @@ -164,9 +164,9 @@ text), and name for each FILE.\n"), /* Split the checksum string S (of length S_LEN) from a BSD 'md5' or 'sha1' command into two parts: a hexadecimal digest, and the file - name. S is modified. */ + name. S is modified. Return true if successful. */ -static int +static bool bsd_split_3 (char *s, size_t s_len, unsigned char **hex_digest, char **file_name) { size_t i; @@ -180,7 +180,7 @@ bsd_split_3 (char *s, size_t s_len, unsigned char **hex_digest, char **file_name i--; if (s[i] != ')') - return 1; + return false; s[i++] = '\0'; @@ -188,7 +188,7 @@ bsd_split_3 (char *s, size_t s_len, unsigned char **hex_digest, char **file_name i++; if (s[i] != '=') - return 1; + return false; i++; @@ -196,19 +196,19 @@ bsd_split_3 (char *s, size_t s_len, unsigned char **hex_digest, char **file_name i++; *hex_digest = (unsigned char *) &s[i]; - return 0; + return true; } /* Split the string S (of length S_LEN) into three parts: a hexadecimal digest, binary flag, and the file name. - S is modified. */ + S is modified. Return true if successful. */ -static int +static bool split_3 (char *s, size_t s_len, - unsigned char **hex_digest, int *binary, char **file_name) + unsigned char **hex_digest, bool *binary, char **file_name) { size_t i; - int escaped_filename = 0; + bool escaped_filename = false; size_t algo_name_len; i = 0; @@ -221,7 +221,7 @@ split_3 (char *s, size_t s_len, { if (strncmp (s + i + algo_name_len, " (", 2) == 0) { - *binary = 0; + *binary = false; return bsd_split_3 (s + i + algo_name_len + 2, s_len - (i + algo_name_len + 2), hex_digest, file_name); @@ -233,12 +233,12 @@ split_3 (char *s, size_t s_len, the first is a backslash) more characters to contain correct message digest information. */ if (s_len - i < min_digest_line_length + (s[i] == '\\')) - return 1; + return false; if (s[i] == '\\') { ++i; - escaped_filename = 1; + escaped_filename = true; } *hex_digest = (unsigned char *) &s[i]; @@ -247,12 +247,12 @@ split_3 (char *s, size_t s_len, immediately by a white space it's an error. */ i += digest_hex_bytes; if (!ISWHITE (s[i])) - return 1; + return false; s[i++] = '\0'; if (s[i] != ' ' && s[i] != '*') - return 1; + return false; *binary = (s[i++] == '*'); /* All characters between the type indicator and end of line are @@ -274,7 +274,7 @@ split_3 (char *s, size_t s_len, if (i == s_len - 1) { /* A valid line does not end with a backslash. */ - return 1; + return false; } ++i; switch (s[i++]) @@ -287,13 +287,13 @@ split_3 (char *s, size_t s_len, break; default: /* Only `\' or `n' may follow a backslash. */ - return 1; + return false; } break; case '\0': /* The file name may not contain a NUL. */ - return 1; + return false; break; default: @@ -303,36 +303,36 @@ split_3 (char *s, size_t s_len, } *dst = '\0'; } - return 0; + return true; } -static int +static bool hex_digits (unsigned char const *s) { while (*s) { if (!ISXDIGIT (*s)) - return 0; + return false; ++s; } - return 1; + return true; } /* An interface to the function, DIGEST_STREAM, (either md5_stream or sha_stream). Operate on FILENAME (it may be "-") and put the result in *BIN_RESULT. - Return non-zero upon failure, zero to indicate success. */ + Return true if successful. */ -static int -digest_file (const char *filename, int binary, unsigned char *bin_result, - int (*digest_stream)(FILE *, void *)) +static bool +digest_file (const char *filename, bool binary, unsigned char *bin_result, + int (*digest_stream) (FILE *, void *)) { FILE *fp; int err; if (STREQ (filename, "-")) { - have_read_stdin = 1; + have_read_stdin = true; fp = stdin; #if O_BINARY /* If we need binary reads from a pipe or redirected stdin, we need @@ -351,7 +351,7 @@ digest_file (const char *filename, int binary, unsigned char *bin_result, if (fp == NULL) { error (0, errno, "%s", filename); - return 1; + return false; } } @@ -361,33 +361,33 @@ digest_file (const char *filename, int binary, unsigned char *bin_result, error (0, errno, "%s", filename); if (fp != stdin) fclose (fp); - return 1; + return false; } if (fp != stdin && fclose (fp) == EOF) { error (0, errno, "%s", filename); - return 1; + return false; } - return 0; + return true; } -static int -digest_check (const char *checkfile_name, int (*digest_stream)(FILE *, void *)) +static bool +digest_check (const char *checkfile_name, int (*digest_stream) (FILE *, void *)) { FILE *checkfile_stream; - int n_properly_formated_lines = 0; - int n_mismatched_checksums = 0; - int n_open_or_read_failures = 0; + uintmax_t n_properly_formatted_lines = 0; + uintmax_t n_mismatched_checksums = 0; + uintmax_t n_open_or_read_failures = 0; unsigned char bin_buffer[MAX_DIGEST_BIN_BYTES]; - size_t line_number; + uintmax_t line_number; char *line; size_t line_chars_allocated; if (STREQ (checkfile_name, "-")) { - have_read_stdin = 1; + have_read_stdin = true; checkfile_name = _("standard input"); checkfile_stream = stdin; } @@ -397,7 +397,7 @@ digest_check (const char *checkfile_name, int (*digest_stream)(FILE *, void *)) if (checkfile_stream == NULL) { error (0, errno, "%s", checkfile_name); - return 1; + return false; } } @@ -408,12 +408,14 @@ digest_check (const char *checkfile_name, int (*digest_stream)(FILE *, void *)) do { char *filename; - int binary; + bool binary; unsigned char *hex_digest; - int err; - int line_length; + ssize_t line_length; ++line_number; + if (line_number == 0) + error (EXIT_FAILURE, 0, _("%s: too many checksum lines"), + checkfile_name); line_length = getline (&line, &line_chars_allocated, checkfile_stream); if (line_length <= 0) @@ -427,14 +429,15 @@ digest_check (const char *checkfile_name, int (*digest_stream)(FILE *, void *)) if (line[line_length - 1] == '\n') line[--line_length] = '\0'; - err = split_3 (line, line_length, &hex_digest, &binary, &filename); - if (err || !hex_digits (hex_digest)) + if (! (split_3 (line, line_length, &hex_digest, &binary, &filename) + && hex_digits (hex_digest))) { if (warn) { error (0, 0, - _("%s: %lu: improperly formatted %s checksum line"), - checkfile_name, (unsigned long) line_number, + _("%s: %" PRIuMAX + ": improperly formatted %s checksum line"), + checkfile_name, line_number, DIGEST_TYPE_STRING (algorithm)); } } @@ -444,13 +447,13 @@ digest_check (const char *checkfile_name, int (*digest_stream)(FILE *, void *)) '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; - int fail; + bool ok; - ++n_properly_formated_lines; + ++n_properly_formatted_lines; - fail = digest_file (filename, binary, bin_buffer, digest_stream); + ok = digest_file (filename, binary, bin_buffer, digest_stream); - if (fail) + if (!ok) { ++n_open_or_read_failures; if (!status_only) @@ -493,16 +496,16 @@ digest_check (const char *checkfile_name, int (*digest_stream)(FILE *, void *)) if (ferror (checkfile_stream)) { error (0, 0, _("%s: read error"), checkfile_name); - return 1; + return false; } if (checkfile_stream != stdin && fclose (checkfile_stream) == EOF) { error (0, errno, "%s", checkfile_name); - return 1; + return false; } - if (n_properly_formated_lines == 0) + if (n_properly_formatted_lines == 0) { /* Warn if no tests are found. */ error (0, 0, _("%s: no properly formatted %s checksum lines found"), @@ -512,51 +515,53 @@ digest_check (const char *checkfile_name, int (*digest_stream)(FILE *, void *)) { if (!status_only) { - int n_computed_checkums = (n_properly_formated_lines - - n_open_or_read_failures); - - if (n_open_or_read_failures > 0) - { - error (0, 0, - _("WARNING: %d of %d listed %s could not be read"), - n_open_or_read_failures, n_properly_formated_lines, - (n_properly_formated_lines == 1 - ? _("file") : _("files"))); - } - - if (n_mismatched_checksums > 0) + if (n_open_or_read_failures != 0) + error (0, 0, + ngettext ("WARNING: %" PRIuMAX " of %" PRIuMAX + " listed file could not be read", + "WARNING: %" PRIuMAX " of %" PRIuMAX + " listed files could not be read", + n_properly_formatted_lines), + n_open_or_read_failures, n_properly_formatted_lines); + + if (n_mismatched_checksums != 0) { + uintmax_t n_computed_checksums = + (n_properly_formatted_lines - n_open_or_read_failures); error (0, 0, - _("WARNING: %d of %d computed %s did NOT match"), - n_mismatched_checksums, n_computed_checkums, - (n_computed_checkums == 1 - ? _("checksum") : _("checksums"))); + ngettext ("WARNING: %" PRIuMAX " of %" PRIuMAX + " computed checksum did NOT match", + "WARNING: %" PRIuMAX " of %" PRIuMAX + " computed checksums did NOT match", + n_computed_checksums), + n_mismatched_checksums, n_computed_checksums); } } } - return ((n_properly_formated_lines > 0 && n_mismatched_checksums == 0 - && n_open_or_read_failures == 0) ? 0 : 1); + return (n_properly_formatted_lines != 0 + && n_mismatched_checksums == 0 + && n_open_or_read_failures == 0); } int main (int argc, char **argv) { unsigned char bin_buffer[MAX_DIGEST_BIN_BYTES]; - int do_check = 0; + bool do_check = false; int opt; char **string = NULL; size_t n_strings = 0; - int err = 0; - int file_type_specified = 0; + bool ok = true; + bool file_type_specified = false; #if O_BINARY /* Binary is default on MSDOS, so the actual file contents are used in computation. */ - int binary = 1; + bool binary = true; #else /* Text is default of the Plumb/Lankester format. */ - int binary = 0; + bool binary = false; #endif /* Setting values of global variables. */ @@ -584,23 +589,23 @@ main (int argc, char **argv) } break; case 'b': - file_type_specified = 1; - binary = 1; + file_type_specified = true; + binary = true; break; case 'c': - do_check = 1; + do_check = true; break; case 2: - status_only = 1; - warn = 0; + status_only = true; + warn = false; break; case 't': - file_type_specified = 1; - binary = 0; + file_type_specified = true; + binary = false; break; case 'w': - status_only = 0; - warn = 1; + status_only = false; + warn = true; break; case_GETOPT_HELP_CHAR; case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); @@ -611,7 +616,7 @@ main (int argc, char **argv) min_digest_line_length = MIN_DIGEST_LINE_LENGTH (algorithm); digest_hex_bytes = DIGEST_HEX_BYTES (algorithm); - if (file_type_specified && do_check) + if (file_type_specified & do_check) { error (0, 0, _("the --binary and --text options are meaningless when \ verifying checksums")); @@ -625,14 +630,14 @@ verifying checksums")); usage (EXIT_FAILURE); } - if (status_only && !do_check) + if (status_only & !do_check) { error (0, 0, _("the --status option is meaningful only when verifying checksums")); usage (EXIT_FAILURE); } - if (warn && !do_check) + if (warn & !do_check) { error (0, 0, _("the --warn option is meaningful only when verifying checksums")); @@ -674,8 +679,8 @@ verifying checksums")); usage (EXIT_FAILURE); } - err = digest_check ((optind == argc) ? "-" : argv[optind], - DIGEST_STREAM (algorithm)); + ok = digest_check (optind == argc ? "-" : argv[optind], + DIGEST_STREAM (algorithm)); } else { @@ -684,13 +689,12 @@ verifying checksums")); for (; optind < argc; ++optind) { - int fail; char *file = argv[optind]; - fail = digest_file (file, binary, bin_buffer, - DIGEST_STREAM (algorithm)); - err |= fail; - if (!fail) + if (! digest_file (file, binary, bin_buffer, + DIGEST_STREAM (algorithm))) + ok = false; + else { size_t i; @@ -735,5 +739,5 @@ verifying checksums")); if (have_read_stdin && fclose (stdin) == EOF) error (EXIT_FAILURE, errno, _("standard input")); - exit (err == 0 ? EXIT_SUCCESS : EXIT_FAILURE); + exit (ok ? EXIT_SUCCESS : EXIT_FAILURE); } -- cgit v1.2.3-54-g00ecf