1 // $Id$
2
3 #include "main.h"
4 #include "ssdeep.h"
5 #include "match.h"
6
7 #define MAX_STATUS_MSG 78
8
display_result(state * s,const TCHAR * fn,const char * sum)9 bool display_result(state *s, const TCHAR * fn, const char * sum) {
10 // Only spend the extra time to make a Filedata object if we need to
11 if (MODE(mode_match_pretty) or MODE(mode_match) or MODE(mode_directory)) {
12 Filedata * f;
13
14 try {
15 f = new Filedata(fn, sum);
16 }
17 catch (std::bad_alloc) {
18 fatal_error("%s: Unable to create Filedata object in engine.cpp:display_result()", __progname);
19 }
20
21 if (MODE(mode_match_pretty)) {
22 if (match_add(s, f))
23 print_error_unicode(s, fn, "Unable to add hash to set of known hashes");
24 }
25 else {
26 // This block is for MODE(mode_match) or MODE(mode_directory)
27 match_compare(s, f);
28
29 if (MODE(mode_directory)) {
30 if (match_add(s, f))
31 print_error_unicode(s,
32 fn,
33 "Unable to add hash to set of known hashes");
34 } else {
35 // We haven't add f to the set of knowns, so let's free it.
36 delete f;
37 }
38 }
39 }
40 else
41 {
42 // No special options selected. Display the hash for this file
43 if (s->first_file_processed)
44 {
45 print_status("%s", OUTPUT_FILE_HEADER);
46 s->first_file_processed = false;
47 }
48
49 printf ("%s,\"", sum);
50 display_filename(stdout, fn, TRUE);
51 print_status("\"");
52 }
53
54 return false;
55 }
56
57
hash_file(state * s,TCHAR * fn)58 int hash_file(state *s, TCHAR *fn) {
59 size_t fn_length;
60 char *sum;
61 TCHAR *my_filename, *msg;
62 FILE *handle;
63
64 #ifdef WIN32
65 TCHAR expanded_fn[SSDEEP_PATH_MAX];
66 if (not expanded_path(fn) && !(s->mode & mode_relative)) {
67 _sntprintf(expanded_fn,
68 SSDEEP_PATH_MAX,
69 _TEXT("\\\\?\\%s"),
70 fn);
71 } else {
72 _tcsncpy(expanded_fn, fn, SSDEEP_PATH_MAX);
73 }
74 handle = _tfopen(expanded_fn, _TEXT("rb"));
75 # else
76 handle = fopen(fn, "rb");
77 #endif
78
79 if (NULL == handle)
80 {
81 print_error_unicode(s,fn,"%s", strerror(errno));
82 return TRUE;
83 }
84
85 if ((sum = (char *)malloc(sizeof(char) * FUZZY_MAX_RESULT)) == NULL)
86 {
87 fclose(handle);
88 print_error_unicode(s,fn,"%s", strerror(errno));
89 return TRUE;
90 }
91
92 if ((msg = (TCHAR *)malloc(sizeof(TCHAR) * (MAX_STATUS_MSG + 2))) == NULL)
93 {
94 free(sum);
95 fclose(handle);
96 print_error_unicode(s,fn,"%s", strerror(errno));
97 return TRUE;
98 }
99
100 if (MODE(mode_verbose))
101 {
102 fn_length = _tcslen(fn);
103 if (fn_length > MAX_STATUS_MSG)
104 {
105 // We have to make a duplicate of the string to call basename on it
106 // We need the original name for the output later on
107 my_filename = _tcsdup(fn);
108 my_basename(my_filename);
109 }
110 else
111 my_filename = fn;
112
113 _sntprintf(msg,
114 MAX_STATUS_MSG-1,
115 _TEXT("Hashing: %s%s"),
116 my_filename,
117 _TEXT(BLANK_LINE));
118 _ftprintf(stderr,_TEXT("%s\r"), msg);
119
120 if (fn_length > MAX_STATUS_MSG)
121 free(my_filename);
122 }
123
124 fuzzy_hash_file(handle,sum);
125 prepare_filename(s,fn);
126 display_result(s,fn,sum);
127
128 if (find_file_size(handle) > SSDEEP_MIN_FILE_SIZE)
129 s->found_meaningful_file = true;
130 s->processed_file = true;
131
132 fclose(handle);
133 free(sum);
134 free(msg);
135 return FALSE;
136 }
137
138