File: engine.cpp

package info (click to toggle)
ssdeep 2.12-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 1,652 kB
  • ctags: 436
  • sloc: sh: 10,876; cpp: 1,601; ansic: 1,034; makefile: 50
file content (137 lines) | stat: -rw-r--r-- 3,166 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
// $Id: engine.cpp 211 2014-05-14 18:20:23Z jessekornblum $ 

#include "main.h"
#include "ssdeep.h"
#include "match.h"

#define MAX_STATUS_MSG   78

bool display_result(state *s, const TCHAR * fn, const char * sum) {
  // Only spend the extra time to make a Filedata object if we need to
  if (MODE(mode_match_pretty) or MODE(mode_match) or MODE(mode_directory)) {
    Filedata * f;
    
    try {
      f = new Filedata(fn, sum);
    } 
    catch (std::bad_alloc) {
      fatal_error("%s: Unable to create Filedata object in engine.cpp:display_result()", __progname);
    }

    if (MODE(mode_match_pretty)) {
      if (match_add(s, f))
	print_error_unicode(s, fn, "Unable to add hash to set of known hashes");
    }
    else {
      // This block is for MODE(mode_match) or MODE(mode_directory)
      match_compare(s, f);
      
      if (MODE(mode_directory)) {
	if (match_add(s, f))
	  print_error_unicode(s,
			      fn,
			      "Unable to add hash to set of known hashes");
      } else {
	// We haven't add f to the set of knowns, so let's free it.
	delete f;
      }
    }
  }
  else
  {
    // No special options selected. Display the hash for this file
    if (s->first_file_processed)
    {
      print_status("%s", OUTPUT_FILE_HEADER);
      s->first_file_processed = false;
    }

    printf ("%s,\"", sum);
    display_filename(stdout, fn, TRUE);
    print_status("\"");
  }

  return false;
}


int hash_file(state *s, TCHAR *fn) {
  size_t fn_length;
  char *sum;
  TCHAR *my_filename, *msg;
  FILE *handle;

#ifdef WIN32  
  TCHAR expanded_fn[SSDEEP_PATH_MAX];
  if (not expanded_path(fn)) {
    _sntprintf(expanded_fn, 
	       SSDEEP_PATH_MAX,
	       _TEXT("\\\\?\\%s"), 
	       fn);
  } else {
    _tcsncpy(expanded_fn, fn, SSDEEP_PATH_MAX);
  }
  handle = _tfopen(expanded_fn, _TEXT("rb"));
# else
  handle = fopen(fn, "rb");
#endif

  if (NULL == handle)
  {
    print_error_unicode(s,fn,"%s", strerror(errno));
    return TRUE;
  }
 
  if ((sum = (char *)malloc(sizeof(char) * FUZZY_MAX_RESULT)) == NULL)
  {
    fclose(handle);
    print_error_unicode(s,fn,"%s", strerror(errno));
    return TRUE;
  }

  if ((msg = (TCHAR *)malloc(sizeof(TCHAR) * (MAX_STATUS_MSG + 2))) == NULL)
  {
    free(sum);
    fclose(handle);
    print_error_unicode(s,fn,"%s", strerror(errno));
    return TRUE;
  }

  if (MODE(mode_verbose))
  {
    fn_length = _tcslen(fn);
    if (fn_length > MAX_STATUS_MSG)
    {
      // We have to make a duplicate of the string to call basename on it
      // We need the original name for the output later on
      my_filename = _tcsdup(fn);
      my_basename(my_filename);
    }
    else
      my_filename = fn;

    _sntprintf(msg,
	       MAX_STATUS_MSG-1,
	       _TEXT("Hashing: %s%s"), 
	       my_filename, 
	       _TEXT(BLANK_LINE));
    _ftprintf(stderr,_TEXT("%s\r"), msg);

    if (fn_length > MAX_STATUS_MSG)
      free(my_filename);
  }

  fuzzy_hash_file(handle,sum);
  prepare_filename(s,fn);
  display_result(s,fn,sum);

  if (find_file_size(handle) > SSDEEP_MIN_FILE_SIZE)
    s->found_meaningful_file = true;
  s->processed_file = true;

  fclose(handle);
  free(sum);
  free(msg);
  return FALSE;
}