Imported Upstream version 2.5.1
[ossec-hids.git] / src / monitord / generate_reports.c
1 /* @(#) $Id$ */
2
3 /* Copyright (C) 2010 Trend Micro Inc.
4  * All right reserved.
5  *
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 
9  * Foundation
10  */
11
12
13 #include "shared.h"
14 #include "monitord.h"
15 int OS_SendCustomEmail(char **to, char *subject, char *smtpserver, char *from, FILE *fp, struct tm *p);
16 char *(monthss[])={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug",
17                   "Sep","Oct","Nov","Dec"};
18
19
20 void generate_reports(int cday, int cmon, int cyear,struct tm *p)
21 {
22     int s = 0;
23
24     if(!mond.smtpserver)
25     {
26         return;
27     }
28
29     if(mond.reports)
30     {
31         int twait = 0;
32         int childcount = 0;
33         while(mond.reports[s])
34         {
35             pid_t pid;
36             if(mond.reports[s]->emailto == NULL)
37             {
38                 s++;
39                 continue;
40             }
41
42             /* We create a new process to run the report and send the email.
43              * To avoid crashing monitord if something goes wrong.
44              */
45             pid = fork();
46             if(pid < 0)
47             {
48                 merror("%s: ERROR: Fork failed. cause: %d - %s", ARGV0, errno, strerror(errno));
49                 s++;
50                 continue;
51             }
52             else if(pid == 0)
53             {
54                 char fname[256];
55                 char aname[256];
56                 fname[255] = '\0';
57                 aname[255] = '\0';
58                 snprintf(fname, 255, "/logs/.report-%d.log", getpid());
59
60                 merror("%s: INFO: Starting daily reporting for '%s'", ARGV0, mond.reports[s]->title);
61                 mond.reports[s]->r_filter.fp = fopen(fname, "w+");
62                 if(!mond.reports[s]->r_filter.fp)
63                 {
64                     merror("%s: ERROR: Unable to open temporary reports file.", ARGV0);
65                     s++;
66                     continue;
67                 }
68
69
70                 /* Opening the log file. */
71                 snprintf(aname, 255, "%s/%d/%s/ossec-%s-%02d.log",
72                          ALERTS, cyear, monthss[cmon], "alerts", cday);
73                 os_strdup(aname, mond.reports[s]->r_filter.filename);
74
75
76                 /* Starting report */
77                 os_ReportdStart(&mond.reports[s]->r_filter);
78                 fflush(mond.reports[s]->r_filter.fp);
79
80                 if(ftell(mond.reports[s]->r_filter.fp) < 10)
81                 {
82                     merror("%s: INFO: Report '%s' empty.", ARGV0, mond.reports[s]->title);
83                 }
84                 else if(OS_SendCustomEmail(mond.reports[s]->emailto, mond.reports[s]->title, 
85                         mond.smtpserver, mond.emailfrom, mond.reports[s]->r_filter.fp, p) != 0)
86                 {
87                     merror("%s: WARN: Unable to send report email.", ARGV0);
88                 }
89                 fclose(mond.reports[s]->r_filter.fp);
90                 unlink(fname);
91                 free(mond.reports[s]->r_filter.filename);
92                 mond.reports[s]->r_filter.filename = NULL;
93
94                 exit(0);
95             }
96             else
97             {
98                 /* Sleep between each report. Time is not important in here. */
99                 sleep(20);
100                 childcount++;
101             }
102
103             s++;
104         }
105
106
107         while (childcount)
108         {
109             int wp;
110             wp = waitpid((pid_t) -1, NULL, WNOHANG);
111             if (wp < 0)
112             {
113                 merror(WAITPID_ERROR, ARGV0);
114             }
115             else if(wp == 0)
116             {
117                 /* If there is still any report left, sleep 5 and try again.*/
118                 sleep(5);
119                 twait++;
120
121                 if(twait > 2)
122                 {
123                     merror("%s: WARN: Report taking too long to complete. Waiting for it to finish...", ARGV0);
124                     sleep(10);
125                     if(twait > 10)
126                     {
127                         merror("%s: WARN: Report took too long. Moving on...", ARGV0);
128                         break;
129                     }
130                 }
131             }
132             else
133             {
134                 childcount--;
135             }
136         }
137     }
138     return;
139 }
140
141 /* EOF */