root/trunk/config.c

Revision 6, 8.2 kB (checked in by jesus, 14 years ago)

Updated regex support to use Solaris native regex's under Solaris and the
GNU regex under Linux. Fixed rejoin after disconnect bug.
Robustified makefile for Solaris.

  • 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 #include <stdio.h>
12 #include <string.h>
13 #include <sys/types.h>
14 #include <sys/stat.h>
15 #include <fcntl.h>
16 #include <sys/file.h>
17 #include <unistd.h>
18
19 #include "config.h"
20 #include "skiplist.h"
21
22 extern FILE *yyin;
23 int yyparse (void);
24
25 int line_num, semantic_errors;
26 static Skiplist logfiles;
27 static Skiplist spreaddaemons;
28
29 extern int verbose;
30 extern int skiplocking;
31
32 int logfile_compare(void *a, void *b) {
33   LogFile *ar = (LogFile *)a;
34   LogFile *br = (LogFile *)b;
35   return strcmp(ar->filename, br->filename);
36 }
37 int logfile_compare_key(void *a, void *b) {
38   LogFile *br = (LogFile *)b;
39   return strcmp(a, br->filename);
40 }
41
42 int spreadd_compare(void *a, void *b) {
43   SpreadConfiguration *ar = (SpreadConfiguration *)a;
44   SpreadConfiguration *br = (SpreadConfiguration *)b;
45   int temp;
46   if((temp = strcmp(ar->port, br->port))!=0)
47     return temp;
48   if((!ar->host) && (!br->host)) return 0;
49   if(!ar->host) return -1;
50   if(!br->host) return 1;
51   return strcmp(ar->host, br->host);
52 }
53 int spreadd_compare_key(void *a, void *b) {
54   SpreadConfiguration *br = (SpreadConfiguration *)b;
55   int temp;
56   if((temp = strcmp(a, br->port))!=0)
57     return temp;
58   if((!a) && (!br->host)) return 0;
59   if(!a) return -1;
60   if(!br->host) return 1;
61   return strcmp(a, br->host);
62 }
63
64 int facility_compare(void *a, void *b) {
65   LogFacility *ar = (LogFacility *)a;
66   LogFacility *br = (LogFacility *)b;
67   return strcmp(ar->groupname, br->groupname);
68 }
69 int facility_compare_key(void *a, void *b) {
70   LogFacility *br = (LogFacility *)b;
71   return strcmp(a, br->groupname);
72 }
73
74 int config_init(char *filename) {
75   int ret;
76
77   sl_init(&logfiles);
78   sl_set_compare(&logfiles, logfile_compare, logfile_compare_key);
79   sl_init(&spreaddaemons);
80   sl_set_compare(&spreaddaemons, spreadd_compare, spreadd_compare_key);
81  
82   /*
83     sl_init(&logfacilities);
84     sl_set_compare(&logfacilities, facility_compare, facility_compare_key);
85   */
86  
87   yyin = fopen(filename, "r");
88   if (!yyin) {
89     fprintf(stderr, "Couldn't open input file: %s\n", filename);
90     return -1;
91   }
92   ret = yyparse();
93   fclose(yyin);
94   return ret;
95 }
96
97 char *config_get_spreaddaemon(SpreadConfiguration *sc) {
98   static char buffer[1024];
99   if(sc->host) {
100     snprintf(buffer, 1024, "%s@%s", sc->port, sc->host);
101   } else {
102     strncpy(buffer, sc->port, 1024);
103   }
104   return buffer;
105 }
106 void config_set_spread_port(SpreadConfiguration *sc, char *newport) {
107   if(sc->port) free(sc->port);
108   sc->port = newport;
109 }
110 void config_set_spread_host(SpreadConfiguration *sc, char *newhost) {
111   if(sc->host) free(sc->host);
112   sc->host = newhost;
113 }
114 void config_add_spreadconf(SpreadConfiguration *sc) {
115   sl_insert(&spreaddaemons, sc);
116 }
117 SpreadConfiguration *config_new_spread_conf(void) {
118   SpreadConfiguration *newsc;
119   newsc = (SpreadConfiguration *)malloc(sizeof(SpreadConfiguration));
120   newsc->host=NULL;
121   newsc->port=strdup("4803");
122   newsc->connected = 0;
123   newsc->logfacilities = (Skiplist *)malloc(sizeof(Skiplist));
124   sl_init(newsc->logfacilities);
125   sl_set_compare(newsc->logfacilities,
126                  facility_compare, facility_compare_key); 
127   return newsc;
128 }
129
130 LogFacility *config_new_logfacility(void) {
131   LogFacility *newlf;
132   newlf = malloc(sizeof(LogFacility));
133   newlf->groupname=NULL;
134   newlf->logfile=NULL;
135   newlf->nmatches=0;
136   return newlf;
137 }
138 void config_add_logfacility(SpreadConfiguration *sc, LogFacility *lf) {
139   sl_insert(sc->logfacilities, lf);
140 }
141 void config_set_logfacility_group(LogFacility *lf, char *ng) {
142   if(lf->groupname) free(lf->groupname);
143   lf->groupname = ng;
144 }
145 void config_set_logfacility_filename(LogFacility *lf, char *nf) {
146   LogFile *logf;
147   logf = sl_find(&logfiles, nf, NULL);
148   lf->logfile = logf;
149   if(!lf->logfile) {
150     logf = (LogFile *)malloc(sizeof(LogFile));
151     logf->filename = nf;
152     logf->fd = -1;
153     sl_insert(&logfiles, logf);
154     lf->logfile = logf;
155   } else {
156     free(nf);
157   }
158 }
159 void config_add_logfacility_match(LogFacility *lf, char *nm) {
160 #ifdef RE_SYNTAX_EGREP
161   const char *ret;
162 #else
163   int ret;
164 #endif
165   if(lf->nmatches>=10) {
166     fprintf(stderr, "Already 10 regex's on group\n");
167     return;
168   }
169 #ifdef RE_SYNTAX_EGREP
170   re_set_syntax(RE_SYNTAX_EGREP);
171   if((ret = re_compile_pattern(nm, strlen(nm),
172                               &lf->match_expression[lf->nmatches]))!=0) {
173     fprintf(stderr, ret);
174 #else
175  if((ret = regcomp(&lf->match_expression[lf->nmatches], nm, REG_EGREP))!=0) {
176    char errbuf[120];
177    regerror(ret, &lf->match_expression[lf->nmatches], errbuf, sizeof errbuf);
178    fprintf(stderr, errbuf);
179 #endif
180   } else {
181     lf->nmatches++;
182   }
183 }
184 int config_foreach_spreadconf(int (*func)(SpreadConfiguration *, void *),
185                               void *closure) {
186   int i=0;
187   struct skiplistnode *iter;
188   SpreadConfiguration *sc;
189
190   iter = sl_getlist(&spreaddaemons);
191   if(!iter) return i;
192
193   sc = iter->data;
194   do {
195     if(func(sc, closure)==0) i++;
196   } while((sc = sl_next(&spreaddaemons, &iter))!=NULL);
197   return i; 
198 }
199 int config_foreach_logfacility(SpreadConfiguration *sc,
200                                int (*func)(LogFacility *, void *),
201                                void *closure) {
202   int i=0;
203   struct skiplistnode *iter;
204   LogFacility *lf;
205
206   iter = sl_getlist(sc->logfacilities);
207   if(!iter) return i;
208
209   lf = iter->data;
210   do {
211     if(func(lf, closure)==0) i++;
212   } while((lf = sl_next(sc->logfacilities, &iter))!=NULL);
213   return i; 
214 }
215 void config_hup(void) {
216   config_close();
217   config_start();
218 }
219
220 int config_close(void) {
221   struct skiplistnode *sciter, *lfiter;
222   SpreadConfiguration *sc;
223   LogFacility *lf;
224
225   sciter = sl_getlist(&spreaddaemons);
226   if(!sciter) return 0;
227  
228   sc = (SpreadConfiguration *)sciter->data;
229   /* For each spread configuration: */
230   do {
231     lfiter = sl_getlist(sc->logfacilities);
232     if(!lfiter) return 0;
233    
234     lf = (LogFacility *)lfiter->data;
235     /* For each log facility in that spread configuration: */
236     do {
237       if(lf->logfile->fd>0) {
238         if(!skiplocking) flock(lf->logfile->fd, LOCK_UN);
239         close(lf->logfile->fd);
240         lf->logfile->fd = -1;
241       }
242     } while((lf = sl_next(sc->logfacilities, &lfiter))!=NULL);
243   } while((sc = sl_next(&spreaddaemons, &sciter))!=NULL);
244   return 0;
245 }
246
247 int config_start(void) {
248   struct skiplistnode *sciter, *lfiter;
249   SpreadConfiguration *sc;
250   LogFacility *lf;
251
252   sciter = sl_getlist(&spreaddaemons);
253   if(!sciter) return 0;
254  
255   sc = (SpreadConfiguration *)sciter->data;
256   /* For each spread configuration: */
257   do {
258     lfiter = sl_getlist(sc->logfacilities);
259     if(!lfiter) return 0;
260
261     lf = (LogFacility *)lfiter->data;
262     /* For each log facility in that spread configuration: */
263     do {
264       if(lf->logfile->fd<0)
265         lf->logfile->fd = open(lf->logfile->filename,
266 #ifdef __USE_LARGEFILE64
267                                O_CREAT|O_APPEND|O_WRONLY|O_LARGEFILE,
268 #else
269                                O_CREAT|O_APPEND|O_WRONLY,
270 #endif
271                                00644);
272       if(!skiplocking) {
273         if(flock(lf->logfile->fd, LOCK_NB|LOCK_EX)==-1) {
274           fprintf(stderr, "Cannot lock %s, is another spreadlogd running?\n",
275                   lf->logfile->filename);
276           exit(1);
277         }
278       }
279       if(verbose) {
280         fprintf(stderr, "LogFacility: %s\n\tFile: %s\n\tFD: %d\n\t%d regexs\n",
281                 lf->groupname, lf->logfile->filename,
282                 lf->logfile->fd, lf->nmatches);
283       }
284     } while((lf = sl_next(sc->logfacilities, &lfiter))!=NULL);
285   } while((sc = sl_next(&spreaddaemons, &sciter))!=NULL);
286   return 0;
287 }
288
289 int config_get_fd(SpreadConfiguration *sc, char *group, char *message) {
290   LogFacility *lf;
291   int i, ret, slen;
292   lf = sl_find(sc->logfacilities, group, NULL);
293   if(!lf) return -1;
294   if(!lf->nmatches) return lf->logfile->fd;
295   slen = strlen(message);
296   for(i=0; i<lf->nmatches; i++) {
297 #ifdef RE_SYNTAX_EGREP
298     if((ret = re_search(&lf->match_expression[i],
299                         message, slen, 0, slen, NULL)) >= 0)
300       return lf->logfile->fd;
301     else if(ret==-2 && verbose)
302       fprintf(stderr, "Internal error in re_search.\n");
303     else if(ret==-1 && verbose)
304       fprintf(stderr, "Failed match!\n");
305 #else
306     if(!regexec(&lf->match_expression[i], message, 0, NULL, 0))
307       return lf->logfile->fd;
308 #endif
309   }
310   return -1;
311 }
312
Note: See TracBrowser for help on using the browser.