Imported Upstream version 2.7
[ossec-hids.git] / src / shared / file-queue.c
1 /* @(#) $Id: ./src/shared/file-queue.c, 2011/09/08 dcid Exp $
2  */
3
4 /* Copyright (C) 2009 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  * License details at the LICENSE file included with OSSEC or
13  * online at: http://www.ossec.net/en/licensing.html
14  */
15
16
17 /* File monitoring functions */
18
19 #include "shared.h"
20 #include "file-queue.h"
21
22
23 /* To translante between month (int) to month (char) */
24 char *(s_month[])={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug",
25                    "Sep","Oct","Nov","Dec"};
26
27
28
29 /** void file_sleep();
30  * file_sleep
31  */
32 void file_sleep()
33 {
34     #ifndef WIN32
35     struct timeval fp_timeout;
36
37     fp_timeout.tv_sec = FQ_TIMEOUT;
38     fp_timeout.tv_usec = 0;
39
40     /* Waiting for the select timeout */
41     select(0, NULL, NULL, NULL, &fp_timeout);
42
43     #else
44     /* Windows don't like select that way */
45     Sleep((FQ_TIMEOUT + 2) * 1000);
46     #endif
47
48     return;
49 }
50
51
52
53 /** void GetFile_Queue(file_queue *fileq)
54  * Get the file queue for that specific hour
55  */
56 void GetFile_Queue(file_queue *fileq)
57 {
58     /* Creating the logfile name */
59     fileq->file_name[0] = '\0';
60     fileq->file_name[MAX_FQUEUE] = '\0';
61
62     if(fileq->flags & CRALERT_FP_SET)
63     {
64         snprintf(fileq->file_name, MAX_FQUEUE,
65                  "<stdin>");
66     }
67     else
68     {
69         snprintf(fileq->file_name, MAX_FQUEUE,
70                                    "%s/%d/%s/ossec-alerts-%02d.log",
71                                    ALERTS,
72                                    fileq->year,
73                                    fileq->mon,
74                                    fileq->day);
75     }
76 }
77
78
79
80 /** int Handle_Queue(file_queue *fileq)
81  * Re Handle the file queue.
82  */
83 int Handle_Queue(file_queue *fileq, int flags)
84 {
85     /* Closing if it is open */
86     if(!(flags & CRALERT_FP_SET))
87     {
88         if(fileq->fp)
89         {
90             fclose(fileq->fp);
91             fileq->fp = NULL;
92         }
93
94
95         /* We must be able to open the file, fseek and get the
96          * time of change from it.
97          */
98         fileq->fp = fopen(fileq->file_name, "r");
99         if(!fileq->fp)
100         {
101             /* Queue not available */
102             return(0);
103         }
104     }
105
106
107     /* Seeking the end of file */
108     if(!(flags & CRALERT_READ_ALL))
109     {
110         if(fseek(fileq->fp, 0, SEEK_END) < 0)
111         {
112             merror(FSEEK_ERROR, __local_name, fileq->file_name);
113             fclose(fileq->fp);
114             fileq->fp = NULL;
115             return(-1);
116         }
117     }
118
119
120     /* File change time */
121     if(fstat(fileno(fileq->fp), &fileq->f_status) < 0)
122     {
123         merror(FILE_ERROR, __local_name, fileq->file_name);
124         fclose(fileq->fp);
125         fileq->fp = NULL;
126         return(-1);
127     }
128
129     fileq->last_change = fileq->f_status.st_mtime;
130
131     return(1);
132 }
133
134
135
136 /** int Init_FileQueue(file_queue *fileq, struct tm *p, int flags)
137  * Initiates the file monitoring.
138  */
139 int Init_FileQueue(file_queue *fileq, struct tm *p, int flags)
140 {
141     /* Initializing file_queue fields. */
142     if(!(flags & CRALERT_FP_SET))
143     {
144         fileq->fp = NULL;
145     }
146     fileq->last_change = 0;
147     fileq->flags = 0;
148
149     fileq->day = p->tm_mday;
150     fileq->year = p->tm_year+1900;
151
152     strncpy(fileq->mon, s_month[p->tm_mon], 4);
153     memset(fileq->file_name, '\0',MAX_FQUEUE + 1);
154
155
156     /* Setting the supplied flags */
157     fileq->flags = flags;
158
159
160     /* Getting latest file */
161     GetFile_Queue(fileq);
162
163
164     /* Always seek end when starting the queue */
165     if(Handle_Queue(fileq, fileq->flags) < 0)
166     {
167         return(-1);
168     }
169
170     return(0);
171 }
172
173
174
175 /** int Read_FileMon(file_queue *fileq, struct tm *p, int timeout)
176  * Reads from the monitored file.
177  */
178 alert_data *Read_FileMon(file_queue *fileq, struct tm *p, int timeout)
179 {
180     int i = 0;
181     alert_data *al_data;
182
183
184     /* If the file queue is not available, try to access it */
185     if(!fileq->fp)
186     {
187         if(Handle_Queue(fileq, 0) != 1)
188         {
189             file_sleep();
190             return(NULL);
191         }
192     }
193
194
195     /* Getting currently file */
196     if(p->tm_mday != fileq->day)
197     {
198         /* If the day changes, we need to get all remaining alerts. */
199         al_data = GetAlertData(fileq->flags, fileq->fp);
200         if(!al_data)
201         {
202             fileq->day = p->tm_mday;
203             fileq->year = p->tm_year+1900;
204             strncpy(fileq->mon, s_month[p->tm_mon], 4);
205
206             /* Getting latest file */
207             GetFile_Queue(fileq);
208
209             if(Handle_Queue(fileq, 0) != 1)
210             {
211                 file_sleep();
212                 return(NULL);
213             }
214         }
215         else
216         {
217             return(al_data);
218         }
219     }
220
221
222     /* Try up to timeout times to get an event */
223     while(i < timeout)
224     {
225         al_data = GetAlertData(fileq->flags, fileq->fp);
226         if(al_data)
227         {
228             return(al_data);
229         }
230
231         i++;
232         file_sleep();
233     }
234
235
236     /* Returning NULL if timeout expires. */
237     return(NULL);
238 }
239
240
241 /* EOF */