00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <basis/function.h>
00020 #include <basis/istring.h>
00021 #include <basis/utility.h>
00022 #include <data_struct/static_memory_gremlin.h>
00023
00024 #include <stdio.h>
00025 #include <string.h>
00026 #include <stdlib.h>
00027
00028 const int buffer_size = 4096;
00029
00030 HOOPLE_STARTUP_CODE;
00031
00032
00033
00034
00035 void print_instructions_and_exit(char *program_name)
00036 {
00037 printf("\n\
00038 Usage:\n\t%s [-t] filename [filename]\n\n\
00039 This program generates a checksum for each file that is entered on the\n\
00040 command line. The checksum is (hopefully) an architecture independent\n\
00041 number that is a very compressed representation of the file gestalt.\n\
00042 If one compares two copies of a file, then the checksums should be identical.\n\
00043 This is a useful test of whether a file copy or a program download is\n\
00044 successful in making an identical version of the file. In particular, if the\n\
00045 file is made slightly bigger or smaller, or if an item in the file is changed,\n\
00046 then the checksums of the two versions should be different numbers.\n\n\
00047 The -b flag is used if the files are to be compared as binary files, and this\n\
00048 is also the default. The -t flag is used if the files are to be compared as\n\
00049 text files.\n",
00050 program_name);
00051 exit(1);
00052 }
00053
00054 #define HIGHEST_CHECK 32714
00055
00056
00057
00058
00059 int do_checksum(char *file_name, int open_as_a_text_file)
00060 {
00061 char file_open_mode[10];
00062 if (open_as_a_text_file) strcpy(file_open_mode, "rt");
00063 else strcpy(file_open_mode, "rb");
00064 FILE *opened_file = fopen(file_name, file_open_mode);
00065 #ifdef DEBUG_CHECKER
00066 LOG(istring("opened ") + file_name);
00067 #endif
00068 if (!opened_file) return common::NOT_FOUND;
00069 int characters_read = 0;
00070 int current_checksum_value = 0;
00071 char buffer_chunk[buffer_size];
00072 while (!feof(opened_file)) {
00073 characters_read = int(fread(buffer_chunk, sizeof(char), buffer_size,
00074 opened_file));
00075
00076 #ifdef DEBUG_CHECKER
00077 LOG(isprintf("char read = %d", characters_read));
00078 #endif
00079 if (characters_read <= 0) {
00080 if (characters_read < 0) current_checksum_value = -1;
00081 else if (current_checksum_value == 0) current_checksum_value = -1;
00082 break;
00083 }
00084 current_checksum_value = (current_checksum_value
00085 + utility::bizarre_checksum((byte *)buffer_chunk, characters_read))
00086 % HIGHEST_CHECK;
00087 #ifdef DEBUG_CHECKER
00088 LOG(isprintf("current checksum=%d", current_checksum_value));
00089 #endif
00090 }
00091 fclose(opened_file);
00092 return int(current_checksum_value);
00093 }
00094
00095
00096
00097
00098 int do_fletcher_checksum(char *file_name, int open_as_a_text_file)
00099 {
00100 char file_open_mode[10];
00101 if (open_as_a_text_file) strcpy(file_open_mode, "rt");
00102 else strcpy(file_open_mode, "rb");
00103 FILE *opened_file = fopen(file_name, file_open_mode);
00104 #ifdef DEBUG_CHECKER
00105 LOG(istring("opened ") + file_name);
00106 #endif
00107 if (!opened_file) return common::NOT_FOUND;
00108 int characters_read = 0;
00109 int current_checksum_value = 0;
00110 char buffer_chunk[buffer_size];
00111 while (!feof(opened_file)) {
00112 characters_read = int(fread(buffer_chunk, sizeof(char), buffer_size,
00113 opened_file));
00114
00115 #ifdef DEBUG_CHECKER
00116 LOG(isprintf("char read = %d", characters_read));
00117 #endif
00118 if (characters_read <= 0) {
00119 if (characters_read < 0) current_checksum_value = -1;
00120 else if (current_checksum_value == 0) current_checksum_value = -1;
00121 break;
00122 }
00123 current_checksum_value = utility::rolling_fletcher_checksum
00124 ((uint16)current_checksum_value, (byte *)buffer_chunk,
00125 characters_read);
00126 #ifdef DEBUG_CHECKER
00127 LOG(isprintf("current checksum=%d", current_checksum_value));
00128 #endif
00129 }
00130 fclose(opened_file);
00131 return current_checksum_value;
00132 }
00133
00134 int main(int argc, char *argv[])
00135 {
00136 char name[200];
00137
00138
00139 int open_file_as_text = false;
00140
00141 if (argc <= 1) print_instructions_and_exit(argv[0]);
00142 else {
00143 int current_parameter = 0;
00144 if (argv[1][0] == '-') {
00145 if (argv[1][1] == 't') {
00146 current_parameter++;
00147 open_file_as_text = true;
00148 } else if (argv[1][1] == 'b') {
00149 current_parameter++;
00150 open_file_as_text = false;
00151 } else print_instructions_and_exit(argv[0]);
00152 }
00153 bool printed_header = false;
00154 while (++current_parameter < argc) {
00155 if (!printed_header) {
00156 printed_header = true;
00157 printf("bizarro fletcher filename\n");
00158 printf("======= ======== ========\n");
00159 }
00160 strcpy(name, argv[current_parameter]);
00161 int checksum_of_file = do_checksum(name, open_file_as_text);
00162 int fletcher_chksum = do_fletcher_checksum(name, open_file_as_text);
00163 if (checksum_of_file >= 0) {
00164 printf(isprintf(" %05d 0x%04x %s\n", checksum_of_file,
00165 fletcher_chksum, name).s());
00166 } else {
00167 printf(isprintf("%s is inaccessible.\n", name).s());
00168 }
00169 }
00170 }
00171 return 0;
00172 }
00173
00174 #ifdef __BUILD_STATIC_APPLICATION__
00175
00176 #include <basis/array.cpp>
00177 #include <basis/byte_array.cpp>
00178 #include <basis/callstack_tracker.cpp>
00179 #include <basis/chaos.cpp>
00180 #include <basis/convert_utf.cpp>
00181 #include <basis/definitions.cpp>
00182 #include <basis/earth_time.cpp>
00183 #include <basis/guards.cpp>
00184 #include <basis/istring.cpp>
00185 #include <basis/log_base.cpp>
00186 #include <basis/memory_checker.cpp>
00187 #include <basis/mutex.cpp>
00188 #include <basis/object_base.cpp>
00189 #include <basis/outcome.cpp>
00190 #include <basis/packable.cpp>
00191 #include <basis/portable.cpp>
00192 #include <basis/sequence.cpp>
00193 #include <basis/set.cpp>
00194 #include <basis/utility.cpp>
00195 #include <basis/version_record.cpp>
00196 #include <data_struct/amorph.cpp>
00197 #include <data_struct/bit_vector.cpp>
00198 #include <data_struct/byte_hasher.cpp>
00199 #include <data_struct/configurator.cpp>
00200 #include <data_struct/hash_table.cpp>
00201 #include <data_struct/pointer_hash.cpp>
00202 #include <data_struct/stack.cpp>
00203 #include <data_struct/static_memory_gremlin.cpp>
00204 #include <data_struct/string_hash.cpp>
00205 #include <data_struct/string_hasher.cpp>
00206 #include <data_struct/string_table.cpp>
00207 #include <data_struct/symbol_table.cpp>
00208 #include <data_struct/table_configurator.cpp>
00209 #include <loggers/console_logger.cpp>
00210 #include <loggers/file_logger.cpp>
00211 #include <loggers/locked_logger.cpp>
00212 #include <loggers/null_logger.cpp>
00213 #include <loggers/program_wide_logger.cpp>
00214 #include <opsystem/byte_filer.cpp>
00215 #include <opsystem/command_line.cpp>
00216 #include <opsystem/critical_events.cpp>
00217 #include <opsystem/directory.cpp>
00218 #include <opsystem/filename.cpp>
00219 #include <opsystem/ini_config.cpp>
00220 #include <opsystem/ini_parser.cpp>
00221 #include <opsystem/path_configuration.cpp>
00222 #include <opsystem/rendezvous.cpp>
00223 #include <textual/byte_format.cpp>
00224 #include <textual/parser_bits.cpp>
00225 #include <textual/string_manipulation.cpp>
00226 #include <textual/tokenizer.cpp>
00227 #endif // __BUILD_STATIC_APPLICATION__
00228