root/branches/omniti/config.c

Revision 2, 7.8 kB (checked in by jesus, 14 years ago)

Initial revision

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