00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "pandabase.h"
00016 #include "hashVal.h"
00017 #include "filename.h"
00018 #include "panda_getopt.h"
00019 #include "preprocess_argv.h"
00020
00021 bool output_decimal = false;
00022 bool suppress_filename = false;
00023 pofstream binary_output;
00024
00025 void
00026 usage() {
00027 cerr <<
00028 "\n"
00029 "Usage:\n\n"
00030 "check_md5 [-q] [-d] [-b filename] [-i \"input string\"] [file1 file2 ...]\n"
00031 "check_md5 -h\n\n";
00032 }
00033
00034 void
00035 help() {
00036 usage();
00037 cerr <<
00038 "This program outputs the MD5 hash of one or more files (or of a string\n"
00039 "passed on the command line with -i).\n\n"
00040
00041 "An MD5 hash is a 128-bit value. The output is presented as a 32-digit\n"
00042 "hexadecimal string by default, but with -d, it is presented as four\n"
00043 "big-endian unsigned 32-bit decimal integers. Normally the filename\n"
00044 "of each file is printed along with the hash; -q suppresses this.\n\n"
00045
00046 "To write the 16 bytes (per input file) of the output directly to a\n"
00047 "binary file, use -b with the name of the file to receive the output.\n";
00048 }
00049
00050 void
00051 output_hash(const string &filename, const HashVal &hash) {
00052 if (!suppress_filename && !filename.empty()) {
00053 cout << filename << " ";
00054 }
00055 if (output_decimal) {
00056 hash.output_dec(cout);
00057 } else {
00058 hash.output_hex(cout);
00059 }
00060 cout << "\n";
00061
00062
00063
00064 hash.output_binary(binary_output);
00065 }
00066
00067
00068 int
00069 main(int argc, char **argv) {
00070 extern char *optarg;
00071 extern int optind;
00072 const char *optstr = "i:db:qh";
00073
00074 bool got_input_string = false;
00075 string input_string;
00076 Filename binary_output_filename;
00077
00078 preprocess_argv(argc, argv);
00079 int flag = getopt(argc, argv, optstr);
00080
00081 while (flag != EOF) {
00082 switch (flag) {
00083 case 'i':
00084 got_input_string = true;
00085 input_string = optarg;
00086 break;
00087
00088 case 'd':
00089 output_decimal = true;
00090 break;
00091
00092 case 'b':
00093 binary_output_filename = Filename::binary_filename(string(optarg));
00094 break;
00095
00096 case 'q':
00097 suppress_filename = true;
00098 break;
00099
00100 case 'h':
00101 help();
00102 exit(1);
00103
00104 default:
00105 exit(1);
00106 }
00107 flag = getopt(argc, argv, optstr);
00108 }
00109
00110 argc -= (optind-1);
00111 argv += (optind-1);
00112
00113 if (argc < 2 && !got_input_string) {
00114 usage();
00115 exit(1);
00116 }
00117
00118 if (!binary_output_filename.empty()) {
00119 if (!binary_output_filename.open_write(binary_output)) {
00120 cerr << "Unable to open " << binary_output_filename << ".\n";
00121 exit(1);
00122 }
00123 }
00124
00125 if (got_input_string) {
00126 HashVal hash;
00127 hash.hash_string(input_string);
00128 output_hash("", hash);
00129 }
00130
00131 bool okflag = true;
00132
00133 for (int i = 1; i < argc; i++) {
00134 Filename source_file = Filename::from_os_specific(argv[i]);
00135
00136 if (!source_file.exists()) {
00137 cerr << source_file << " not found!\n";
00138 okflag = false;
00139 } else {
00140 HashVal hash;
00141 if (!hash.hash_file(source_file)) {
00142 cerr << "Unable to read " << source_file << "\n";
00143 okflag = false;
00144 } else {
00145 output_hash(source_file.get_basename(), hash);
00146 }
00147 }
00148 }
00149
00150 if (!okflag) {
00151 exit(1);
00152 }
00153
00154 return 0;
00155 }