1 /* @(#) $Id: ./src/syscheckd/seechanges.c, 2011/09/08 dcid Exp $
4 /* Copyright (C) 2009 Trend Micro Inc.
7 * This program is a free software; you can redistribute it
8 * and/or modify it under the terms of the GNU General Public
9 * License (version 2) as published by the FSF - Free Software
16 #include "os_crypto/md5/md5_op.h"
20 /* Generate diffs alerts. */
21 char *gen_diff_alert(char *filename, int alert_diff_time)
26 char buf[OS_MAXSTR +1];
27 char diff_alert[OS_MAXSTR +1];
29 buf[OS_MAXSTR] = '\0';
30 diff_alert[OS_MAXSTR] = '\0';
32 snprintf(buf, OS_MAXSTR, "%s/local/%s/diff.%d",
33 DIFF_DIR_PATH, filename, alert_diff_time);
38 merror("%s: ERROR: Unable to generate diff alert.", ARGV0);
42 n = fread(buf, 1, 4096 -1, fp);
45 merror("%s: ERROR: Unable to generate diff alert (fread).", ARGV0);
51 /* We need to clear the last new line. */
53 tmp_str = strrchr(buf, '\n');
58 /* Weird diff with only one large line. */
70 /* Getting up to 20 line changes. */
74 while(tmp_str && (*tmp_str != '\0'))
76 tmp_str = strchr(tmp_str, '\n');
90 snprintf(diff_alert, 4096 -1, "%s%s",
97 return(strdup(diff_alert));
101 int seechanges_dupfile(char *old, char *new)
106 unsigned char buf[2048 +1];
110 fpr = fopen(old,"r");
111 fpw = fopen(new,"w");
118 while((n = fread(buf, 1, 2048, fpr)) > 0)
121 fwrite(buf, n, 1, fpw);
131 int seechanges_createpath(char *filename)
138 os_strdup(filename, buffer);
140 tmpstr = strchr(buffer +1, '/');
143 merror("%s: ERROR: Invalid path name: '%s'", ARGV0, filename);
153 if(IsDir(newdir) != 0)
156 if(mkdir(newdir, 0770) == -1)
158 if(mkdir(newdir) == -1)
161 merror(MKDIR_ERROR, ARGV0, newdir);
173 tmpstr = strchr(tmpstr, '/');
187 /* Checks if the file has changed */
188 char *seechanges_addfile(char *filename)
191 char old_location[OS_MAXSTR +1];
192 char tmp_location[OS_MAXSTR +1];
193 char diff_cmd[OS_MAXSTR +1];
198 old_location[OS_MAXSTR] = '\0';
199 tmp_location[OS_MAXSTR] = '\0';
200 diff_cmd[OS_MAXSTR] = '\0';
201 md5sum_new[0] = '\0';
202 md5sum_old[0] = '\0';
205 snprintf(old_location, OS_MAXSTR, "%s/local/%s/%s", DIFF_DIR_PATH, filename +1,
209 /* If the file is not there, rename new location to last location. */
210 if(OS_MD5_File(old_location, md5sum_old) != 0)
212 seechanges_createpath(old_location);
213 if(seechanges_dupfile(filename, old_location) != 1)
215 merror(RENAME_ERROR, ARGV0, filename);
221 /* Get md5sum of the new file. */
222 if(OS_MD5_File(filename, md5sum_new) != 0)
224 //merror("%s: ERROR: Invalid internal state (missing '%s').",
230 /* If they match, keep the old file and remove the new. */
231 if(strcmp(md5sum_new, md5sum_old) == 0)
237 /* Saving the old file at timestamp and renaming new to last. */
238 date_of_change = File_DateofChange(old_location);
239 snprintf(tmp_location, OS_MAXSTR, "%s/local/%s/state.%d", DIFF_DIR_PATH, filename +1,
241 rename(old_location, tmp_location);
242 if(seechanges_dupfile(filename, old_location) != 1)
244 merror("%s: ERROR: Unable to create snapshot for %s",ARGV0, filename);
250 date_of_change = File_DateofChange(old_location);
251 snprintf(diff_cmd, 2048, "diff \"%s\" \"%s\" > \"%s/local/%s/diff.%d\" "
253 tmp_location, old_location,
254 DIFF_DIR_PATH, filename +1, date_of_change);
255 if(system(diff_cmd) != 256)
257 merror("%s: ERROR: Unable to run diff for %s",
263 /* Generate alert. */
264 return(gen_diff_alert(filename, date_of_change));