OSDN Git Service

d131c34e7430ad0b6effea6f2b16050950f0f12c
[mhash384/mhash384.git] / src / main.c
1 /* ---------------------------------------------------------------------------------------------- */
2 /* MHash-384 - Example application (plain C)                                                      */
3 /* Copyright(c) 2016-2017 LoRd_MuldeR <mulder2@gmx.de>                                            */
4 /*                                                                                                */
5 /* Permission is hereby granted, free of charge, to any person obtaining a copy of this software  */
6 /* and associated documentation files (the "Software"), to deal in the Software without           */
7 /* restriction, including without limitation the rights to use, copy, modify, merge, publish,     */
8 /* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the  */
9 /* Software is furnished to do so, subject to the following conditions:                           */
10 /*                                                                                                */
11 /* The above copyright notice and this permission notice shall be included in all copies or       */
12 /* substantial portions of the Software.                                                          */
13 /*                                                                                                */
14 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING  */
15 /* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND     */
16 /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   */
17 /* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, */
18 /* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.        */
19 /* ---------------------------------------------------------------------------------------------- */
20
21 /*Disable some warnings*/
22 #ifdef _MSC_VER
23 #define _CRT_SECURE_NO_WARNINGS 1
24 #endif
25
26 /*Includes*/
27 #include "mhash_384.h"
28 #include "compat.h"
29 #include "utilities.h"
30
31 /*Test includes*/
32 #ifndef NO_SELFTEST
33 #include "self_test.h"
34 #endif
35
36 /*CRT includes*/
37 #include <errno.h>
38 #include <time.h>
39
40 /*Constants*/
41 #define BUFF_SIZE 4096
42
43 /*Win32-only headers*/
44 #ifdef _WIN32
45 #include <io.h>
46 #include <fcntl.h>
47 #endif
48
49 /*The "main" function*/
50 int MAIN(int argc, CHAR *argv[])
51 {
52         param_t param;
53         FILE *source;
54         uint8_t buffer[BUFF_SIZE], result[MHASH_384_LEN];
55         uint_fast32_t count;
56         uint64_t size_total, size_processed;
57         uint_fast16_t update_iter;
58         clock_t ts_start, ts_finish;
59         mhash_384_t context;
60
61 #ifdef _WIN32
62         _setmode(_fileno(stdin), _O_BINARY);
63 #endif
64
65         /*install CTRL+C handler*/
66         signal(SIGINT, sigint_handler);
67
68         /*process command-line arguments*/
69         if (!parse_arguments(&param, argc, argv))
70         {
71                 return 1;
72         }
73
74         /*run self-test, if in test mode*/
75         if (param.test_mode)
76         {
77                 print_logo();
78 #ifdef NO_SELFTEST
79                 fprintf(stderr, "Not compiled with self-test code!\n");
80                 return 1;
81 #else
82                 return self_test();
83 #endif
84         }
85
86         /*open source file*/
87         if (!(source = param.filename ? FOPEN(param.filename, T("rb")) : stdin))
88         {
89                 print_logo();
90                 fprintf(stderr, "Failed to open input file:\n" FMT_S "\n\n%s\n\n", param.filename ? param.filename : T("<STDIN>"), strerror(errno));
91                 return 1;
92         }
93
94         /*determine file size*/
95         size_total = get_file_size(source);
96
97         /*setup state*/
98         ts_start = clock();
99         update_iter = 0;
100         size_processed = 0;
101
102         /*initialization*/
103         mhash_384_initialize(&context);
104
105         /*process file contents*/
106         while(!(ferror(source) || feof(source)))
107         {
108                 count = (uint_fast32_t) fread(buffer, sizeof(uint8_t), BUFF_SIZE, source);
109                 if (count > 0)
110                 {
111                         mhash_384_update(&context, buffer, count);
112                         size_processed += count;
113                 }
114                 if (g_interrupted || (count != BUFF_SIZE))
115                 {
116                         break; /*stop*/
117                 }
118                 if (param.show_progress && ((update_iter++ & 0x3FF) == 0))
119                 {
120                         print_progress(size_total, size_processed);
121                         fflush(stderr);
122                 }
123         }
124
125         /*check for interruption*/
126         if (g_interrupted)
127         {
128                 fprintf(stderr, "\nInterrupted!\n\n");
129                 return SIGINT;
130         }
131
132         /*final progress*/
133         if (param.show_progress)
134         {
135                 print_progress(size_total, size_processed);
136                 fprintf(stderr, " done\n\n");
137                 fflush(stderr);
138         }
139
140         /*check file error status*/
141         if (ferror(source))
142         {
143                 print_logo();
144                 fprintf(stderr, "File read error has occurred!\n");
145                 fclose(source);
146                 return 1;
147         }
148
149         /*finalize the hash*/
150         mhash_384_finalize(&context, result);
151         ts_finish = clock();
152
153         /*output stats*/
154         if (param.enable_bench)
155         {
156                 const double time_total = ((double)(ts_finish - ts_start)) / ((double)CLOCKS_PER_SEC);
157                 const double throughput = (size_processed) / time_total;
158                 fprintf(stderr, "Processed %" PRIu64 " bytes in %.1f seconds, %.1f bytes/sec.\n\n", size_processed, time_total, throughput);
159                 fflush(stderr);
160         }
161
162         /*output result as Hex string*/
163         print_digest(result, param.use_upper_case);
164         fflush(stdout);
165
166         /*clean up*/
167         if (source != stdin)
168         {
169                 fclose(source);
170         }
171
172         /*completed*/
173         return 0;
174 }