root/trunk/config.c

Revision 10, 10.5 kB (checked in by george, 13 years ago)

Replaced NR_OPEN code with calls to getrlimit/setrlimit.

  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
Line 
1 /* ======================================================================
2 * Copyright (c) 2000 Theo Schlossnagle
3 * All rights reserved.
4 * The following code was written by Theo Schlossnagle <jesus@omniti.com>
5 * This code was written to facilitate clustered logging via Spread.
6 * More information on Spread can be found at http://www.spread.org/
7 * Please refer to the LICENSE file before using this software.
8 * ======================================================================
9 */
10
11
12 #include <stdio.h>
13 #include <string.h>
14 #include <sys/types.h>
15 #include <sys/stat.h>
16 #include <fcntl.h>
17 #include <sys/file.h>
18 #include <sys/param.h>
19 #include <unistd.h>
20
21 #include "config.h"
22 #include "skiplist.h"
23 #include "timefuncs.h"
24
25 extern FILE *yyin;
26 extern int buffsize;
27 extern int nr_open;
28
29 int yyparse (void);
30 int line_num, semantic_errors;
31 static Skiplist logfiles;
32 static Skiplist spreaddaemons;
33 extern int verbose;
34 extern int skiplocking;
35 int logfile_compare(void *a, void *b) {
36   LogFile *ar = (LogFile *)a;
37   LogFile *br = (LogFile *)b;
38   return strcmp(ar->filename, br->filename);
39 }
40 int logfile_compare_key(void *a, void *b) {
41   LogFile *br = (LogFile *)b;
42   return strcmp(a, br->filename);
43
44 int spreadd_compare(void *a, void *b) {
45   SpreadConfiguration *ar = (SpreadConfiguration *)a;
46   SpreadConfiguration *br = (SpreadConfiguration *)b;
47   int temp;
48   if((temp = strcmp(ar->port, br->port))!=0)
49     return temp;
50   if((!ar->host) && (!br->host)) return 0;
51   if(!ar->host) return -1;
52   if(!br->host) return 1;
53   return strcmp(ar->host, br->host);
54 }
55 int spreadd_compare_key(void *a, void *b) {
56   SpreadConfiguration *br = (SpreadConfiguration *)b;
57   int temp;
58   if((temp = strcmp(a, br->port))!=0)
59     return temp;
60   if((!a) && (!br->host)) return 0;
61   if(!a) return -1;
62   if(!br->host) return 1;
63   return strcmp(a, br->host);
64
65 int facility_compare(void *a, void *b) {
66   LogFacility *ar = (LogFacility *)a;
67   LogFacility *br = (LogFacility *)b;
68   return strcmp(ar->groupname, br->groupname);
69 }
70 int facility_compare_key(void *a, void *b) {
71   LogFacility *br = (LogFacility *)b;
72   return strcmp(a, br->groupname);
73
74 int config_init(char *filename) {
75   int ret;
76   sl_init(&logfiles);
77   sl_set_compare(&logfiles, logfile_compare, logfile_compare_key);
78   sl_init(&spreaddaemons);
79   sl_set_compare(&spreaddaemons, spreadd_compare, spreadd_compare_key);
80   /*
81     sl_init(&logfacilities);
82     sl_set_compare(&logfacilities, facility_compare, facility_compare_key);
83   */
84   yyin = fopen(filename, "r");
85   if (!yyin) {
86     fprintf(stderr, "Couldn't open input file: %s\n", filename);
87     return -1;
88   }
89   ret = yyparse();
90   fclose(yyin);
91   return ret;
92
93 char *config_get_spreaddaemon(SpreadConfiguration *sc) {
94   static char buffer[1024];
95   if(sc->host) {
96     snprintf(buffer, 1024, "%s@%s", sc->port, sc->host);
97   }
98   else {
99     strncpy(buffer, sc->port, 1024);
100   }
101   return buffer;
102 }
103
104 void config_set_spread_port(SpreadConfiguration *sc, char *newport) {
105   if(sc->port) free(sc->port);
106   sc->port = newport;
107 }
108 void config_set_spread_host(SpreadConfiguration *sc, char *newhost) {
109   if(sc->host) free(sc->host);
110   sc->host = newhost;
111 }
112 void config_add_spreadconf(SpreadConfiguration *sc) {
113   sl_insert(&spreaddaemons, sc);
114 }
115 SpreadConfiguration *config_new_spread_conf(void) {
116   SpreadConfiguration *newsc;
117   newsc = (SpreadConfiguration *)malloc(sizeof(SpreadConfiguration));
118   newsc->host=NULL;
119   newsc->port=strdup("4803");
120   newsc->connected = 0;
121   newsc->logfacilities = (Skiplist *)malloc(sizeof(Skiplist));
122   sl_init(newsc->logfacilities);
123   sl_set_compare(newsc->logfacilities,
124                  facility_compare, facility_compare_key); 
125   return newsc;
126
127 LogFacility *config_new_logfacility(void) {
128   LogFacility *newlf;
129   newlf = malloc(sizeof(LogFacility));
130   newlf->groupname=NULL;
131   newlf->logfile=NULL;
132   newlf->nmatches=0;
133   newlf->rewritetimes=NO_REWRITE_TIMES;
134   newlf->rewritetimesformat=NULL;
135   return newlf;
136 }
137 void config_add_logfacility(SpreadConfiguration *sc, LogFacility *lf) {
138   sl_insert(sc->logfacilities, lf);
139 }
140 void config_set_logfacility_group(LogFacility *lf, char *ng) {
141   if(lf->groupname) free(lf->groupname);
142   lf->groupname = ng;
143 }
144 void config_set_logfacility_filename(LogFacility *lf, char *nf) {
145   LogFile *logf;
146   logf = sl_find(&logfiles, nf, NULL);
147   lf->logfile = logf;
148   if(!lf->logfile) {
149     logf = (LogFile *)malloc(sizeof(LogFile));
150     logf->filename = nf;
151     logf->fd = -1;
152     sl_insert(&logfiles, logf);
153     lf->logfile = logf;
154   }
155   else {
156     free(nf);
157   }
158 }
159 void config_set_logfacility_vhostdir(LogFacility *lf, char *vhd) {
160   int i;
161   lf->vhostdir = vhd;
162   lf->hash = (hash_element *) malloc (nr_open * sizeof(hash_element));
163   fprintf( stderr, "\nZeroing vhost hash for usage!\n");
164   for(i=0; i< nr_open; i++) {
165     lf->hash[i].fd = -1;
166     lf->hash[i].hostheader = NULL;
167   }
168
169 }
170 void config_set_logfaclity_rewritetimes_clf(LogFacility *lf) {
171   lf->rewritetimes = REWRITE_TIMES_IN_CLF;
172 }
173 void config_set_logfaclity_rewritetimes_user(LogFacility *lf, char *format) {
174   lf->rewritetimes = REWRITE_TIMES_FORMAT;
175   if(lf->rewritetimesformat) {
176     free(lf->rewritetimesformat);
177   }
178   lf->rewritetimesformat = format;
179 }
180 void config_add_logfacility_match(LogFacility *lf, char *nm) {
181 #ifdef RE_SYNTAX_EGREP
182   const char *ret;
183 #else 
184   int ret;
185 #endif 
186   if(lf->nmatches>=10) {
187     fprintf(stderr, "Already 10 regex's on group\n");
188     return;
189   }
190 #ifdef RE_SYNTAX_EGREP
191   re_set_syntax(RE_SYNTAX_EGREP);
192   if((ret = re_compile_pattern(nm, strlen(nm),
193                                &lf->match_expression[lf->nmatches]))!=0) {
194     fprintf(stderr, ret);
195 #else 
196 if((ret = regcomp(&lf->match_expression[lf->nmatches], nm, REG_EGREP))!=0) {
197       char errbuf[120];
198       regerror(ret, &lf->match_expression[lf->nmatches], errbuf, sizeof errbuf);
199       fprintf(stderr, errbuf);
200 #endif 
201   } else {
202     lf->nmatches++;
203   }
204 }
205
206 int config_foreach_spreadconf(int (*func)(SpreadConfiguration *, void *),
207                               void *closure) {
208   int i=0;
209   struct skiplistnode *iter;
210   SpreadConfiguration *sc;
211   iter = sl_getlist(&spreaddaemons);
212   if(!iter) return i;
213   sc = iter->data;
214   do {
215     if(func(sc, closure)==0) i++;
216   } while((sc = sl_next(&spreaddaemons, &iter))!=NULL);
217   return i; 
218 }
219
220 int config_foreach_logfacility(SpreadConfiguration *sc,
221                                int (*func)(LogFacility *, void *),
222                                void *closure) {
223   int i=0;
224   struct skiplistnode *iter;
225   LogFacility *lf;
226   iter = sl_getlist(sc->logfacilities);
227   if(!iter) return i;
228   lf = iter->data;
229   do {
230     if(func(lf, closure)==0) i++;
231   } while((lf = sl_next(sc->logfacilities, &iter))!=NULL);
232   return i; 
233 }
234
235 char *config_process_message(SpreadConfiguration *sc, char *group,
236                              char *message, int *len) {
237   LogFacility *lf;
238   char *cp;
239   lf = sl_find(sc->logfacilities, group, NULL);
240   if(lf->rewritetimes)
241     force_local_time(message, len, buffsize,
242                      lf->rewritetimes, lf->rewritetimesformat);
243   if(lf->vhostdir) {
244     cp=message;
245     while(*cp != ' ') {
246         cp++;
247         --*len;
248     }
249     --*len;
250     return cp+1;
251   }
252   return message;
253 }   
254
255 void config_hup(void) {
256   config_close();
257   config_start();
258
259
260 int config_close(void) {
261   struct skiplistnode *sciter, *lfiter;
262   SpreadConfiguration *sc;
263   LogFacility *lf;
264                                 int i;
265   sciter = sl_getlist(&spreaddaemons);
266   if(!sciter) return 0;
267   sc = (SpreadConfiguration *)sciter->data;
268   /* For each spread configuration: */
269   do {
270     lfiter = sl_getlist(sc->logfacilities);
271     if(!lfiter) return 0;
272     lf = (LogFacility *)lfiter->data;
273     /* For each log facility in that spread configuration: */
274     do {
275       if(lf->vhostdir) {
276         for (i=0;i< nr_open;i++) {
277           if(lf->hash[i].fd>0) {
278             if(!skiplocking) flock(lf->hash[i].fd, LOCK_UN);
279             close(lf->hash[i].fd);
280             lf->hash[i].fd = -1;
281           }
282         }
283       } else if(lf->logfile->fd>0) {
284         if(!skiplocking) flock(lf->logfile->fd, LOCK_UN);
285         close(lf->logfile->fd);
286         lf->logfile->fd = -1;
287       }
288     } while((lf = sl_next(sc->logfacilities, &lfiter))!=NULL);
289   } while((sc = sl_next(&spreaddaemons, &sciter))!=NULL);
290   return 0;
291
292
293 int config_start(void) {
294   struct skiplistnode *sciter, *lfiter;
295   SpreadConfiguration *sc;
296   LogFacility *lf;
297   sciter = sl_getlist(&spreaddaemons);
298   if(!sciter) return 0;
299   sc = (SpreadConfiguration *)sciter->data;
300   /* For each spread configuration: */
301   do {
302     lfiter = sl_getlist(sc->logfacilities);
303     if(!lfiter) return 0;
304     lf = (LogFacility *)lfiter->data;
305     /* For each log facility in that spread configuration: */
306     do {
307       if(lf->vhostdir) continue;
308       else if(lf->logfile->fd<0)
309         lf->logfile->fd = open(lf->logfile->filename,
310 #ifdef __USE_LARGEFILE64
311                                O_CREAT|O_APPEND|O_WRONLY|O_LARGEFILE,
312 #else 
313                                O_CREAT|O_APPEND|O_WRONLY,
314 #endif 
315                                00644);
316       if(!skiplocking) {
317         if(flock(lf->logfile->fd, LOCK_NB|LOCK_EX)==-1) {
318           fprintf(stderr, "Cannot lock %s, is another spreadlogd running?\n",
319                   lf->logfile->filename);
320           exit(1);
321         }
322       }
323       if(verbose) {
324         fprintf(stderr, "LogFacility: %s\n\tFile: %s\n\tFD: %d\n\t%d regexs\n",
325                 lf->groupname, lf->logfile->filename,
326                 lf->logfile->fd, lf->nmatches);
327       }
328     } while((lf = sl_next(sc->logfacilities, &lfiter))!=NULL);
329   } while((sc = sl_next(&spreaddaemons, &sciter))!=NULL);
330   return 0;
331
332
333 int config_get_fd(SpreadConfiguration *sc, char *group, char *message) {
334   LogFacility *lf;
335   int i, ret, slen, fd;
336   hash_element temp;
337   char *cp;
338   char fullpath[MAXPATHLEN];
339   lf = sl_find(sc->logfacilities, group, NULL);
340   if(!lf) return -1;
341   if(lf->vhostdir) {
342     cp = message;
343     while(*cp != ' '){
344       cp++;
345     }
346     *cp = '\0';
347     if((fd = gethash(message, lf->hash)) < 0) {
348       temp.hostheader = strdup(message);
349       *cp = ' ';
350       snprintf(fullpath, MAXPATHLEN, "%s/%s", lf->vhostdir,temp.hostheader);
351       temp.fd = open(fullpath,
352 #ifdef __USE_LARGEFILE64
353                      O_CREAT|O_APPEND|O_WRONLY|O_LARGEFILE,
354 #else 
355                      O_CREAT|O_APPEND|O_WRONLY,
356 #endif 
357                      00644);
358       if(!skiplocking) {
359         if(flock(temp.fd, LOCK_NB|LOCK_EX)==-1) {
360           fprintf(stderr, "Cannot lock %s, is another spreadlogd running?\n",
361                   fullpath);
362           exit(1);
363         }
364       }
365       inshash(temp,lf->hash);
366       return temp.fd;
367     }                                           
368     *cp = ' ';
369     return fd;
370   }     
371   if(!lf->nmatches) return lf->logfile->fd;
372   slen = strlen(message);
373   for(i=0; i<lf->nmatches; i++) {
374 #ifdef RE_SYNTAX_EGREP
375     if((ret = re_search(&lf->match_expression[i],
376                         message, slen, 0, slen, NULL)) >= 0)
377       return lf->logfile->fd;
378     else if(ret==-2 && verbose)
379       fprintf(stderr, "Internal error in re_search.\n");
380     else if(ret==-1 && verbose)
381       fprintf(stderr, "Failed match!\n");
382 #else  if(!regexec(&lf->match_expression[i], message, 0, NULL, 0))
383     return lf->logfile->fd;
384 #endif 
385   }
386   return -1;
387
388
Note: See TracBrowser for help on using the browser.