3 /* Copyright (C) 2009 Trend Micro Inc.
6 * This program is a free software; you can redistribute it
7 * and/or modify it under the terms of the GNU General Public
8 * License (version 2) as published by the FSF - Free Software
15 #include "os_crypto/md5/md5_op.h"
19 /* Generate diffs alerts. */
20 char *gen_diff_alert(char *filename, int alert_diff_time)
25 char buf[OS_MAXSTR +1];
26 char diff_alert[OS_MAXSTR +1];
28 buf[OS_MAXSTR] = '\0';
29 diff_alert[OS_MAXSTR] = '\0';
31 snprintf(buf, OS_MAXSTR, "%s/local/%s/diff.%d",
32 DIFF_DIR_PATH, filename, alert_diff_time);
37 merror("%s: ERROR: Unable to generate diff alert.", ARGV0);
41 n = fread(buf, 1, 4096 -1, fp);
44 merror("%s: ERROR: Unable to generate diff alert (fread).", ARGV0);
50 /* We need to clear the last new line. */
52 tmp_str = strrchr(buf, '\n');
57 /* Weird diff with only one large line. */
69 /* Getting up to 20 line changes. */
73 while(tmp_str && (*tmp_str != '\0'))
75 tmp_str = strchr(tmp_str, '\n');
89 snprintf(diff_alert, 4096 -1, "%s%s",
96 return(strdup(diff_alert));
100 int seechanges_dupfile(char *old, char *new)
105 unsigned char buf[2048 +1];
109 fpr = fopen(old,"r");
110 fpw = fopen(new,"w");
117 while((n = fread(buf, 1, 2048, fpr)) > 0)
120 fwrite(buf, n, 1, fpw);
130 int seechanges_createpath(char *filename)
137 os_strdup(filename, buffer);
139 tmpstr = strchr(buffer +1, '/');
142 merror("%s: ERROR: Invalid path name: '%s'", ARGV0, filename);
152 if(IsDir(newdir) != 0)
155 if(mkdir(newdir, 0770) == -1)
157 if(mkdir(newdir) == -1)
160 merror(MKDIR_ERROR, ARGV0, newdir);
172 tmpstr = strchr(tmpstr, '/');
186 /* Checks if the file has changed */
187 char *seechanges_addfile(char *filename)
190 char old_location[OS_MAXSTR +1];
191 char tmp_location[OS_MAXSTR +1];
192 char diff_cmd[OS_MAXSTR +1];
197 old_location[OS_MAXSTR] = '\0';
198 tmp_location[OS_MAXSTR] = '\0';
199 diff_cmd[OS_MAXSTR] = '\0';
200 md5sum_new[0] = '\0';
201 md5sum_old[0] = '\0';
204 snprintf(old_location, OS_MAXSTR, "%s/local/%s/%s", DIFF_DIR_PATH, filename +1,
208 /* If the file is not there, rename new location to last location. */
209 if(OS_MD5_File(old_location, md5sum_old) != 0)
211 seechanges_createpath(old_location);
212 if(seechanges_dupfile(filename, old_location) != 1)
214 merror(RENAME_ERROR, ARGV0, filename);
220 /* Get md5sum of the new file. */
221 if(OS_MD5_File(filename, md5sum_new) != 0)
223 //merror("%s: ERROR: Invalid internal state (missing '%s').",
229 /* If they match, keep the old file and remove the new. */
230 if(strcmp(md5sum_new, md5sum_old) == 0)
236 /* Saving the old file at timestamp and renaming new to last. */
237 date_of_change = File_DateofChange(old_location);
238 snprintf(tmp_location, OS_MAXSTR, "%s/local/%s/state.%d", DIFF_DIR_PATH, filename +1,
240 rename(old_location, tmp_location);
241 if(seechanges_dupfile(filename, old_location) != 1)
243 merror("%s: ERROR: Unable to create snapshot for %s",ARGV0, filename);
249 date_of_change = File_DateofChange(old_location);
250 snprintf(diff_cmd, 2048, "diff \"%s\" \"%s\" > \"%s/local/%s/diff.%d\" "
252 tmp_location, old_location,
253 DIFF_DIR_PATH, filename +1, date_of_change);
254 if(system(diff_cmd) != 256)
256 merror("%s: ERROR: Unable to run diff for %s",
262 /* Generate alert. */
263 return(gen_diff_alert(filename, date_of_change));