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