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