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