?? md5sum.c
字號:
/* A valid line does not end with a backslash. */ return FALSE; } ++i; switch (s[i++]) { case 'n': *dst++ = '\n'; break; case '\\': *dst++ = '\\'; break; default: /* Only `\' or `n' may follow a backslash. */ return FALSE; } break; case '\0': /* The file name may not contain a NUL. */ return FALSE; break; default: *dst++ = s[i++]; break; } } *dst = '\0'; } return TRUE;}static inline int hex_digits(unsigned char const *s){ while (*s) { if (!ISXDIGIT(*s)) return TRUE; ++s; } return FALSE;}/* An interface to md5_stream. Operate on FILENAME (it may be "-") and put the result in *MD5_RESULT. Return non-zero upon failure, zero to indicate success. */static int md5_file(const char *filename, unsigned char *md5_result){ FILE *fp; if (filename[0] == '-' && filename[1] == '\0') { have_read_stdin = 1; fp = stdin; } else { fp = wfopen(filename, "r"); if (fp == NULL) return FALSE; } if (md5_stream(fp, md5_result)) { perror_msg("%s", filename); if (fp != stdin) fclose(fp); return FALSE; } if (fp != stdin && fclose(fp) == EOF) { perror_msg("%s", filename); return FALSE; } return TRUE;}static int md5_check(const char *checkfile_name){ FILE *checkfile_stream; int n_properly_formated_lines = 0; int n_mismatched_checksums = 0; int n_open_or_read_failures = 0; unsigned char md5buffer[16]; size_t line_number; char line[BUFSIZ]; if (checkfile_name[0] == '-' && checkfile_name[1] == '\0') { have_read_stdin = 1; checkfile_stream = stdin; } else { checkfile_stream = wfopen(checkfile_name, "r"); if (checkfile_stream == NULL) return FALSE; } line_number = 0; do { char *filename; unsigned char *md5num; int line_length; ++line_number; fgets(line, BUFSIZ-1, checkfile_stream); line_length = strlen(line); if (line_length <= 0 || line==NULL) break; /* Ignore comment lines, which begin with a '#' character. */ if (line[0] == '#') continue; /* Remove any trailing newline. */ if (line[line_length - 1] == '\n') line[--line_length] = '\0'; if (split_3(line, line_length, &md5num, &filename) || !hex_digits(md5num)) { if (warn) { error_msg("%s: %lu: improperly formatted MD5 checksum line", checkfile_name, (unsigned long) line_number); } } else { static const char bin2hex[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; ++n_properly_formated_lines; if (md5_file(filename, md5buffer)) { ++n_open_or_read_failures; if (!status_only) { printf("%s: FAILED open or read\n", filename); fflush(stdout); } } else { size_t cnt; /* Compare generated binary number with text representation in check file. Ignore case of hex digits. */ for (cnt = 0; cnt < 16; ++cnt) { if (tolower(md5num[2 * cnt]) != bin2hex[md5buffer[cnt] >> 4] || (tolower(md5num[2 * cnt + 1]) != (bin2hex[md5buffer[cnt] & 0xf]))) break; } if (cnt != 16) ++n_mismatched_checksums; if (!status_only) { printf("%s: %s\n", filename, (cnt != 16 ? "FAILED" : "OK")); fflush(stdout); } } } } while (!feof(checkfile_stream) && !ferror(checkfile_stream)); if (ferror(checkfile_stream)) { error_msg("%s: read error", checkfile_name); return FALSE; } if (checkfile_stream != stdin && fclose(checkfile_stream) == EOF) { perror_msg("md5sum: %s", checkfile_name); return FALSE; } if (n_properly_formated_lines == 0) { /* Warn if no tests are found. */ error_msg("%s: no properly formatted MD5 checksum lines found", checkfile_name); return FALSE; } else { if (!status_only) { int n_computed_checkums = (n_properly_formated_lines - n_open_or_read_failures); if (n_open_or_read_failures > 0) { error_msg("WARNING: %d of %d listed files could not be read", n_open_or_read_failures, n_properly_formated_lines); return FALSE; } if (n_mismatched_checksums > 0) { error_msg("WARNING: %d of %d computed checksums did NOT match", n_mismatched_checksums, n_computed_checkums); return FALSE; } } } return ((n_properly_formated_lines > 0 && n_mismatched_checksums == 0 && n_open_or_read_failures == 0) ? 0 : 1);}int md5sum_main(int argc, char **argv){ unsigned char md5buffer[16]; int do_check = 0; int opt; char **string = NULL; size_t n_strings = 0; size_t err = 0; char file_type_specified = 0; char binary = 0; while ((opt = getopt(argc, argv, "g:bcstw")) != -1) { switch (opt) { case 'g': { /* read a string */ if (string == NULL) string = (char **) xmalloc ((argc - 1) * sizeof (char *)); string[n_strings++] = optarg; break; } case 'b': /* read files in binary mode */ file_type_specified = 1; binary = 1; break; case 'c': /* check MD5 sums against given list */ do_check = 1; break; case 's': /* don't output anything, status code shows success */ status_only = 1; warn = 0; break; case 't': /* read files in text mode (default) */ file_type_specified = 1; binary = 0; break; case 'w': /* warn about improperly formated MD5 checksum lines */ status_only = 0; warn = 1; break; default: show_usage(); } } if (file_type_specified && do_check) { error_msg_and_die("the -b and -t options are meaningless when verifying checksums"); } if (n_strings > 0 && do_check) { error_msg_and_die("the -g and -c options are mutually exclusive"); } if (status_only && !do_check) { error_msg_and_die("the -s option is meaningful only when verifying checksums"); } if (warn && !do_check) { error_msg_and_die("the -w option is meaningful only when verifying checksums"); } if (n_strings > 0) { size_t i; if (optind < argc) { error_msg_and_die("no files may be specified when using -g"); } for (i = 0; i < n_strings; ++i) { size_t cnt; md5_buffer (string[i], strlen (string[i]), md5buffer); for (cnt = 0; cnt < 16; ++cnt) printf ("%02x", md5buffer[cnt]); printf (" \"%s\"\n", string[i]); } } else if (do_check) { if (optind + 1 < argc) { error_msg("only one argument may be specified when using -c"); } err = md5_check ((optind == argc) ? "-" : argv[optind]); } else { if (optind == argc) argv[argc++] = "-"; for (; optind < argc; ++optind) { int fail; char *file = argv[optind]; fail = md5_file (file, md5buffer); err |= fail; if (!fail && file[0]=='-' && file[1] == '\0') { size_t i; for (i = 0; i < 16; ++i) printf ("%02x", md5buffer[i]); putchar ('\n'); } else if (!fail) { size_t i; /* Output a leading backslash if the file name contains a newline or backslash. */ if (strchr (file, '\n') || strchr (file, '\\')) putchar ('\\'); for (i = 0; i < 16; ++i) printf ("%02x", md5buffer[i]); putchar (' '); if (binary) putchar ('*'); else putchar (' '); /* Translate each NEWLINE byte to the string, "\\n", and each backslash to "\\\\". */ for (i = 0; i < strlen (file); ++i) { switch (file[i]) { case '\n': fputs ("\\n", stdout); break; case '\\': fputs ("\\\\", stdout); break; default: putchar (file[i]); break; } } putchar ('\n'); } } } if (fclose (stdout) == EOF) { error_msg_and_die("write error"); } if (have_read_stdin && fclose (stdin) == EOF) { error_msg_and_die("standard input"); } if (err == 0) return EXIT_SUCCESS; else return EXIT_FAILURE;}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -