... | ... |
@@ -161,6 +161,8 @@ int main(int argc, char **argv) { |
161 | 161 |
logg_time = optget(opts, "LogTime")->enabled; |
162 | 162 |
logg_size = optget(opts, "LogFileMaxSize")->numarg; |
163 | 163 |
logg_verbose = mprintf_verbose = optget(opts, "LogVerbose")->enabled; |
164 |
+ if (logg_size) |
|
165 |
+ logg_rotate = optget(opts, "LogRotate")->enabled; |
|
164 | 166 |
|
165 | 167 |
if((opt = optget(opts, "LogFile"))->enabled) { |
166 | 168 |
logg_file = opt->strarg; |
... | ... |
@@ -221,6 +221,8 @@ int main(int argc, char **argv) |
221 | 221 |
logok = optget(opts, "LogClean")->enabled; |
222 | 222 |
logg_size = optget(opts, "LogFileMaxSize")->numarg; |
223 | 223 |
logg_verbose = mprintf_verbose = optget(opts, "LogVerbose")->enabled; |
224 |
+ if (logg_size) |
|
225 |
+ logg_rotate = optget(opts, "LogRotate")->enabled; |
|
224 | 226 |
mprintf_send_timeout = optget(opts, "SendBufTimeout")->numarg; |
225 | 227 |
|
226 | 228 |
do { /* logger initialized */ |
... | ... |
@@ -251,6 +251,10 @@ Example |
251 | 251 |
# Default: no |
252 | 252 |
#LogVerbose yes |
253 | 253 |
|
254 |
+# Enable log rotation. |
|
255 |
+# Default: no |
|
256 |
+#LogRotate yes |
|
257 |
+ |
|
254 | 258 |
# This option allows to tune what is logged when a message is infected. |
255 | 259 |
# Possible values are Off (the default - nothing is logged), |
256 | 260 |
# Basic (minimal info logged), Full (verbose info logged) |
... | ... |
@@ -51,6 +51,10 @@ Example |
51 | 51 |
# Default: no |
52 | 52 |
#LogVerbose yes |
53 | 53 |
|
54 |
+# Enable log rotation. |
|
55 |
+# Default: no |
|
56 |
+#LogRotate yes |
|
57 |
+ |
|
54 | 58 |
# Log additional information about the infected file, such as its |
55 | 59 |
# size and hash, together with the virus name. |
56 | 60 |
#ExtendedDetectionInfo yes |
... | ... |
@@ -425,6 +425,8 @@ main (int argc, char **argv) |
425 | 425 |
logg_verbose = mprintf_verbose ? 1 : optget (opts, "LogVerbose")->enabled; |
426 | 426 |
logg_time = optget (opts, "LogTime")->enabled; |
427 | 427 |
logg_size = optget (opts, "LogFileMaxSize")->numarg; |
428 |
+ if (logg_size) |
|
429 |
+ logg_rotate = optget(opts, "LogRotate")->enabled; |
|
428 | 430 |
|
429 | 431 |
if ((opt = optget (opts, "UpdateLogFile"))->enabled) |
430 | 432 |
{ |
... | ... |
@@ -187,6 +187,8 @@ const struct clam_option __clam_options[] = { |
187 | 187 |
|
188 | 188 |
{ "LogVerbose", NULL, 0, TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_CLAMD | OPT_FRESHCLAM | OPT_MILTER, "Enable verbose logging.", "yes" }, |
189 | 189 |
|
190 |
+ { "LogRotate", "log-rotate", 0, TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_CLAMD | OPT_MILTER, "Rotate log file. Requires LogFileMaxSize option.", "yes" }, |
|
191 |
+ |
|
190 | 192 |
{ "ExtendedDetectionInfo", NULL, 0, TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_CLAMD, "Log additional information about the infected file, such as its\nsize and hash, together with the virus name.", "yes" }, |
191 | 193 |
|
192 | 194 |
{ "PidFile", "pid", 'p', TYPE_STRING, NULL, -1, NULL, 0, OPT_CLAMD | OPT_FRESHCLAM | OPT_MILTER, "Save the process ID to a file.", "/var/run/clam.pid" }, |
... | ... |
@@ -81,8 +81,8 @@ pthread_mutex_t mdprintf_mutex = PTHREAD_MUTEX_INITIALIZER; |
81 | 81 |
|
82 | 82 |
FILE *logg_fp = NULL; |
83 | 83 |
|
84 |
-short int logg_verbose = 0, logg_nowarn = 0, logg_lock = 1, logg_time = 0, logg_foreground = 1, logg_noflush = 0; |
|
85 |
-unsigned int logg_size = 0; |
|
84 |
+short int logg_verbose = 0, logg_nowarn = 0, logg_lock = 1, logg_time = 0, logg_foreground = 1, logg_noflush = 0, logg_rotate = 0; |
|
85 |
+off_t logg_size = 0; |
|
86 | 86 |
const char *logg_file = NULL; |
87 | 87 |
#if defined(USE_SYSLOG) && !defined(C_AIX) |
88 | 88 |
short logg_syslog; |
... | ... |
@@ -204,6 +204,79 @@ int mdprintf(int desc, const char *str, ...) |
204 | 204 |
return ret < 0 ? -1 : bytes; |
205 | 205 |
} |
206 | 206 |
|
207 |
+static int rename_logg(STATBUF *sb) |
|
208 |
+{ |
|
209 |
+ char *rotate_file; |
|
210 |
+ size_t rotate_file_len; |
|
211 |
+ time_t t; |
|
212 |
+ struct tm tmp; |
|
213 |
+ |
|
214 |
+ if (!logg_rotate) { |
|
215 |
+ logg_file = NULL; |
|
216 |
+ fprintf(logg_fp, "Log size = %u, max = %u\n", sb->st_size, logg_size); |
|
217 |
+ fprintf(logg_fp, "LOGGING DISABLED (Maximal log file size exceeded).\n"); |
|
218 |
+ fclose(logg_fp); |
|
219 |
+ logg_fp = NULL; |
|
220 |
+ |
|
221 |
+ return 0; |
|
222 |
+ } |
|
223 |
+ |
|
224 |
+ rotate_file_len = strlen(logg_file) + sizeof("-YYYY-MM-DD_HH:MM:SS"); |
|
225 |
+ rotate_file = calloc(1, rotate_file_len + 1); |
|
226 |
+ if (!rotate_file) { |
|
227 |
+ if (logg_fp) { |
|
228 |
+ fprintf(logg_fp, "Need to rotate log file due to size but ran out of memory.\n"); |
|
229 |
+ fclose(logg_fp); |
|
230 |
+ logg_fp = NULL; |
|
231 |
+ } |
|
232 |
+ |
|
233 |
+ return -1; |
|
234 |
+ } |
|
235 |
+ |
|
236 |
+ t = time(NULL); |
|
237 |
+ if (!localtime_r(&t, &tmp)) { |
|
238 |
+ if (logg_fp) { |
|
239 |
+ fprintf(logg_fp, "Need to rotate log file due to size but could not get local time.\n"); |
|
240 |
+ fclose(logg_fp); |
|
241 |
+ logg_fp = NULL; |
|
242 |
+ } |
|
243 |
+ |
|
244 |
+ free(rotate_file); |
|
245 |
+ return -1; |
|
246 |
+ } |
|
247 |
+ |
|
248 |
+ strcpy(rotate_file, logg_file); |
|
249 |
+ strftime(rotate_file+strlen(rotate_file), rotate_file_len-strlen(rotate_file), "-%Y-%m-%d_%H:%M:%S", &tmp); |
|
250 |
+ |
|
251 |
+ if (logg_fp) { |
|
252 |
+ fclose(logg_fp); |
|
253 |
+ logg_fp = NULL; |
|
254 |
+ } |
|
255 |
+ |
|
256 |
+ if (rename(logg_file, rotate_file)) { |
|
257 |
+ free(rotate_file); |
|
258 |
+ return -1; |
|
259 |
+ } |
|
260 |
+ |
|
261 |
+ free(rotate_file); |
|
262 |
+ return 0; |
|
263 |
+} |
|
264 |
+ |
|
265 |
+static int logg_open(void) |
|
266 |
+{ |
|
267 |
+ STATBUF sb; |
|
268 |
+ |
|
269 |
+ if(logg_file) |
|
270 |
+ if(logg_size) |
|
271 |
+ if(STAT(logg_file, &sb) != -1) |
|
272 |
+ if(sb.st_size > logg_size) |
|
273 |
+ if (rename_logg(&sb)) |
|
274 |
+ return -1; |
|
275 |
+ |
|
276 |
+ |
|
277 |
+ return 0; |
|
278 |
+} |
|
279 |
+ |
|
207 | 280 |
void logg_close(void) |
208 | 281 |
{ |
209 | 282 |
#if defined(USE_SYSLOG) && !defined(C_AIX) |
... | ... |
@@ -245,14 +318,13 @@ void logg_close(void) |
245 | 245 |
int logg(const char *str, ...) |
246 | 246 |
{ |
247 | 247 |
va_list args; |
248 |
-#ifdef F_WRLCK |
|
249 |
- struct flock fl; |
|
250 |
-#endif |
|
251 | 248 |
char buffer[1025], *abuffer = NULL, *buff; |
252 | 249 |
time_t currtime; |
253 |
- struct stat sb; |
|
254 |
- mode_t old_umask; |
|
255 | 250 |
size_t len; |
251 |
+ mode_t old_umask; |
|
252 |
+#ifdef F_WRLCK |
|
253 |
+ struct flock fl; |
|
254 |
+#endif |
|
256 | 255 |
|
257 | 256 |
if ((*str == '$' && logg_verbose < 2) || |
258 | 257 |
(*str == '*' && !logg_verbose)) |
... | ... |
@@ -279,55 +351,45 @@ int logg(const char *str, ...) |
279 | 279 |
#ifdef CL_THREAD_SAFE |
280 | 280 |
pthread_mutex_lock(&logg_mutex); |
281 | 281 |
#endif |
282 |
- if(logg_file) { |
|
283 |
- if(!logg_fp) { |
|
284 |
- old_umask = umask(0037); |
|
285 |
- if((logg_fp = fopen(logg_file, "at")) == NULL) { |
|
286 |
- umask(old_umask); |
|
282 |
+ |
|
283 |
+ logg_open(); |
|
284 |
+ |
|
285 |
+ if(!logg_fp && logg_file) { |
|
286 |
+ old_umask = umask(0037); |
|
287 |
+ if((logg_fp = fopen(logg_file, "at")) == NULL) { |
|
288 |
+ umask(old_umask); |
|
287 | 289 |
#ifdef CL_THREAD_SAFE |
288 |
- pthread_mutex_unlock(&logg_mutex); |
|
290 |
+ pthread_mutex_unlock(&logg_mutex); |
|
289 | 291 |
#endif |
290 |
- printf("ERROR: Can't open %s in append mode (check permissions!).\n", logg_file); |
|
291 |
- if(len > sizeof(buffer)) |
|
292 |
- free(abuffer); |
|
293 |
- return -1; |
|
294 |
- } else umask(old_umask); |
|
292 |
+ printf("ERROR: Can't open %s in append mode (check permissions!).\n", logg_file); |
|
293 |
+ if(len > sizeof(buffer)) |
|
294 |
+ free(abuffer); |
|
295 |
+ return -1; |
|
296 |
+ } else umask(old_umask); |
|
295 | 297 |
|
296 | 298 |
#ifdef F_WRLCK |
297 |
- if(logg_lock) { |
|
298 |
- memset(&fl, 0, sizeof(fl)); |
|
299 |
- fl.l_type = F_WRLCK; |
|
300 |
- if(fcntl(fileno(logg_fp), F_SETLK, &fl) == -1) { |
|
299 |
+ if(logg_lock) { |
|
300 |
+ memset(&fl, 0, sizeof(fl)); |
|
301 |
+ fl.l_type = F_WRLCK; |
|
302 |
+ if(fcntl(fileno(logg_fp), F_SETLK, &fl) == -1) { |
|
301 | 303 |
#ifdef EOPNOTSUPP |
302 |
- if(errno == EOPNOTSUPP) |
|
303 |
- printf("WARNING: File locking not supported (NFS?)\n"); |
|
304 |
- else |
|
304 |
+ if(errno == EOPNOTSUPP) |
|
305 |
+ printf("WARNING: File locking not supported (NFS?)\n"); |
|
306 |
+ else |
|
305 | 307 |
#endif |
306 |
- { |
|
308 |
+ { |
|
307 | 309 |
#ifdef CL_THREAD_SAFE |
308 |
- pthread_mutex_unlock(&logg_mutex); |
|
309 |
-#endif |
|
310 |
- printf("ERROR: %s is locked by another process\n", logg_file); |
|
311 |
- if(len > sizeof(buffer)) |
|
312 |
- free(abuffer); |
|
313 |
- return -1; |
|
314 |
- } |
|
315 |
- } |
|
316 |
- } |
|
310 |
+ pthread_mutex_unlock(&logg_mutex); |
|
317 | 311 |
#endif |
318 |
- } |
|
319 |
- |
|
320 |
- if(logg_size) { |
|
321 |
- if(stat(logg_file, &sb) != -1) { |
|
322 |
- if((unsigned int) sb.st_size > logg_size) { |
|
323 |
- logg_file = NULL; |
|
324 |
- fprintf(logg_fp, "Log size = %u, max = %u\n", (unsigned int) sb.st_size, logg_size); |
|
325 |
- fprintf(logg_fp, "LOGGING DISABLED (Maximal log file size exceeded).\n"); |
|
326 |
- fclose(logg_fp); |
|
327 |
- logg_fp = NULL; |
|
328 |
- } |
|
329 |
- } |
|
330 |
- } |
|
312 |
+ printf("ERROR: %s is locked by another process\n", logg_file); |
|
313 |
+ if(len > sizeof(buffer)) |
|
314 |
+ free(abuffer); |
|
315 |
+ return -1; |
|
316 |
+ } |
|
317 |
+ } |
|
318 |
+ } |
|
319 |
+#endif |
|
320 |
+ } |
|
331 | 321 |
|
332 | 322 |
if(logg_fp) { |
333 | 323 |
char flush = !logg_noflush; |
... | ... |
@@ -360,7 +422,6 @@ int logg(const char *str, ...) |
360 | 360 |
if (flush) |
361 | 361 |
fflush(logg_fp); |
362 | 362 |
} |
363 |
- } |
|
364 | 363 |
|
365 | 364 |
if(logg_foreground) { |
366 | 365 |
if(buff[0] != '#') |
... | ... |
@@ -40,8 +40,8 @@ int logg(const char *str, ...); |
40 | 40 |
#endif |
41 | 41 |
|
42 | 42 |
void logg_close(void); |
43 |
-extern short int logg_verbose, logg_nowarn, logg_lock, logg_time, logg_noflush; |
|
44 |
-extern unsigned int logg_size; |
|
43 |
+extern short int logg_verbose, logg_nowarn, logg_lock, logg_time, logg_noflush, logg_rotate; |
|
44 |
+extern off_t logg_size; |
|
45 | 45 |
extern const char *logg_file; |
46 | 46 |
|
47 | 47 |
#if defined(USE_SYSLOG) && !defined(C_AIX) |