ze-filter  (ze-filter-0.8.0-develop-180218)
ze-cf.c
Go to the documentation of this file.
1 
2 /*
3  *
4  * ze-filter - Mail Server Filter for sendmail
5  *
6  * Copyright (c) 2001-2018 - Jose-Marcio Martins da Cruz
7  *
8  * Auteur : Jose Marcio Martins da Cruz
9  * jose.marcio.mc@gmail.org
10  *
11  * Historique :
12  * Creation : janvier 2002
13  *
14  * This program is free software, but with restricted license :
15  *
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
20  *
21  * More details about ze-filter license can be found at ze-filter
22  * web site : http://foss.jose-marcio.org
23  */
24 #include <ze-sys.h>
25 #include <libze.h>
26 
27 #include "ze-cf.h"
28 
29 #include "ze-filter.h"
30 
31 /* ****************************************************************************
32  * *
33  * *
34  **************************************************************************** */
35 
36 #define TOKEN_TAG "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_0123456789@"
37 
39 
40 unsigned int statistics_interval = 300;
41 
42 #define STRING(a) #a
43 
44 #define CF_NONE 0
45 
46 #define ZE_STR 1
47 #define ZE_ENUM 2
48 #define ZE_INT 3
49 #define ZE_DOUBLE 4
50 
51 #define DIM_CF 256
52 
53 time_t last_reconf_date = (time_t) 0;
54 
55 struct jcfrec_T {
56  int id;
57  char name[64];
58  int kind;
59  int slen;
60  long iv;
61  double dv;
62  char *sv;
63  char **opt;
64  char strval[64];
65 } jcfrec_T;
66 
67 static struct jcfrec_T cf[DIM_CF];
68 
69 int cf_init();
70 
71 void cf_clear_values();
72 
73 void cf_load_default();
74 
75 int cf_add_id_enum(int id, char *name, char **opt, char *val);
76 int cf_add_id_str(int id, char *name, int len, char *val);
77 int cf_add_id_int(int id, char *name, char *val);
78 int cf_add_id_double(int id, char *name, char *val);
79 
80 int cf_set_str_val(int id, char *val);
81 int cf_set_int_val(int id, int val);
82 int cf_set_double_val(int id, double val);
83 
84 int cf_set_val(int id, char *name);
85 
86 static void cf_define();
87 
88 static int get_enum_index(char *, char **);
89 
90 char *unix_sock = NULL;
91 
92 static pthread_mutex_t cf_mutex = PTHREAD_MUTEX_INITIALIZER;
93 
94 #define CF_DATA_LOCK() \
95  if (pthread_mutex_lock(&cf_mutex) != 0) { \
96  ZE_LogSysError("pthread_mutex_lock(cf_mutex)"); \
97  }
98 
99 #define CF_DATA_UNLOCK() \
100  if (pthread_mutex_unlock(&cf_mutex) != 0) { \
101  ZE_LogSysError("pthread_mutex_unlock(cf_mutex)"); \
102  }
103 
104 bool configure_after(char *app);
105 
106 /* ****************************************************************************
107  * *
108  * *
109  **************************************************************************** */
110 static int
111 cf_compare(va, vb)
112  const void *va;
113  const void *vb;
114 {
115  struct jcfrec_T *a = (struct jcfrec_T *) va;
116  struct jcfrec_T *b = (struct jcfrec_T *) vb;
117 
118  if (a->id == 0 || b->id == 0)
119  return 0;
120  if (a->id == 0)
121  return 1;
122  if (b->id == 0)
123  return -1;
124  return (a->id - b->id);
125 }
126 
127 static void
128 cf_sort()
129 {
130  qsort(cf, DIM_CF, sizeof (struct jcfrec_T), cf_compare);
131 }
132 
133 /* ****************************************************************************
134  * *
135  * *
136  **************************************************************************** */
137 typedef struct {
138  int id; /* parameter ID */
139  int type; /* type : STR, INT, ENUM or DOUBLE */
140 
141  char **enum_ptr; /* enumeration values */
142  int str_length; /* string length */
143 
144  char *cftag; /* configuration file tag */
145  char *cfnull; /* default value */
146  char *cfsection; /* configuration section */
147  char *desc; /* variable description */
148  char *syntax;
149  char *cfdefault; /* default value */
150 } cfvar_t;
151 
152 #include "cfc-defs.h"
153 
154 /* ****************************************************************************
155  * *
156  * *
157  **************************************************************************** */
158 
159 static void fill_conf_data();
160 
161 /* ****************************************************************************
162  * *
163  * *
164  **************************************************************************** */
165 static void
166 fill_conf_data()
167 {
168  cfvar_t *p = cfvar;
169 
170  while (p->id >= 0) {
171  switch (p->type) {
172  case ZE_INT:
173  cf_add_id_int(p->id, p->cftag, p->cfnull);
174  break;
175  case ZE_STR:
176  cf_add_id_str(p->id, p->cftag, p->str_length, p->cfnull);
177  break;
178  case ZE_DOUBLE:
179  cf_add_id_double(p->id, p->cftag, p->cfnull);
180  break;
181  case ZE_ENUM:
182  cf_add_id_enum(p->id, p->cftag, p->enum_ptr, p->cfnull);
183  break;
184  default:
185  break;
186  }
187  p++;
188  }
189 }
190 
191 /* ****************************************************************************
192  * *
193  * *
194  **************************************************************************** */
195 int
197 {
198  memset(cf, 0, sizeof (cf));
199 
200  if (1)
201  fill_conf_data();
202  else
203  cf_define();
204 
205  return 0;
206 }
207 
208 /* ****************************************************************************
209  * *
210  * *
211  **************************************************************************** */
212 
213 void
214 cf_dump(fd, full)
215  int fd;
216  bool full;
217 {
218  int i, j;
219  char *p;
220 
221 #if 0
222  if (fd < 0)
223  fd = STDOUT_FILENO;
224 #endif
225 
226  for (i = 0; i < DIM_CF; i++) {
227  if (cf[i].id != 0) {
228  switch (cf[i].kind) {
229  case ZE_INT:
230  if (full) {
231  char *p = cf[i].strval;
232 
233  if (strspn(p, "0123456789 ") == strlen(p))
234  p = NULL;
235 
236  FD_PRINTF(fd, " %4d %-26s %-4s %7ld %6d (%s)\n",
237  cf[i].id, cf[i].name, "INT", cf[i].iv, cf[i].slen,
238  STRNULL(p, ""));
239  } else {
240  char *p = cf[i].strval;
241 
242  if (strspn(p, "0123456789 ") == strlen(p))
243  p = NULL;
244 
245  if (p != NULL)
246  FD_PRINTF(fd, " %4d %-26s %7ld (%s)\n", cf[i].id, cf[i].name,
247  cf[i].iv, p);
248  else
249  FD_PRINTF(fd, " %4d %-26s %7ld\n", cf[i].id, cf[i].name,
250  cf[i].iv);
251  }
252  break;
253  case ZE_DOUBLE:
254  if (full) {
255  char *p = cf[i].strval;
256 
257  if (strspn(p, "0123456789. ") == strlen(p))
258  p = NULL;
259 
260  FD_PRINTF(fd, " %4d %-26s %-6s %7.3f %6d (%s)\n",
261  cf[i].id, cf[i].name, "DOUBLE", cf[i].dv, cf[i].slen,
262  STRNULL(p, ""));
263  } else {
264  char *p = cf[i].strval;
265 
266  if (strspn(p, "0123456789. ") == strlen(p))
267  p = NULL;
268 
269  if (p != NULL)
270  FD_PRINTF(fd, " %4d %-26s %7.3f (%s)\n", cf[i].id, cf[i].name,
271  cf[i].dv, p);
272  else
273  FD_PRINTF(fd, " %4d %-26s %7.3f\n", cf[i].id, cf[i].name,
274  cf[i].dv);
275  }
276  break;
277  case ZE_ENUM:
278  p = cf[i].sv;
279  if (p == NULL || strlen(p) == 0) {
280  for (j = 0; cf[i].opt[j] != NULL; j++) {
281  if (j == cf[i].iv) {
282  p = cf[i].opt[j];
283  break;
284  }
285  }
286  }
287  if (full) {
288  FD_PRINTF(fd, " %4d %-26s %-4s %7ld %6d %s\n",
289  cf[i].id,
290  cf[i].name, "ENUM", cf[i].iv, cf[i].slen,
291  p != NULL ? p : "(null)");
292  } else {
293  FD_PRINTF(fd, " %4d %-26s %7ld %s\n",
294  cf[i].id, cf[i].name, cf[i].iv, p != NULL ? p : "(null)");
295  }
296  break;
297  case ZE_STR:
298  if (cf[i].sv != NULL) {
299  int n = 0;
300 
301  p = cf[i].sv;
302  while (*p) {
303  int nc = strcspn(p, "\n");
304 
305  if (nc > 0) {
306  char out[256];
307 
308  strncpy(out, p, nc);
309  out[nc] = '\0';
310  if (full) {
311  FD_PRINTF(fd, " %4d %-26s %-4s %7ld %6d %s\n",
312  cf[i].id, cf[i].name, "STR", cf[i].iv, cf[i].slen,
313  out);
314  } else {
315  FD_PRINTF(fd, " %4d %-26s %s\n", cf[i].id, cf[i].name,
316  out);
317  }
318  p += nc;
319  n++;
320  }
321  p += strspn(p, "\n");
322  }
323  if (n == 0) {
324  if (full) {
325  FD_PRINTF(fd, " %4d %-26s %-4s %7ld %6d %s\n",
326  cf[i].id, cf[i].name, "STR", cf[i].iv, cf[i].slen,
327  "");
328  } else {
329  FD_PRINTF(fd, " %4d %-26s %s\n", cf[i].id, cf[i].name,
330  "(null)");
331  }
332  }
333  }
334  break;
335  default:
336  FD_PRINTF(fd, " %4d %-26s %-4s %7ld %6d %s\n",
337  cf[i].id,
338  cf[i].name,
339  "????", cf[i].iv, cf[i].slen,
340  cf[i].sv != NULL ? cf[i].sv : "(null)");
341  break;
342  }
343  }
344  }
345 }
346 
347 
348 /* ****************************************************************************
349  * *
350  * *
351  **************************************************************************** */
352 void
353 mk_cf_file(fd, inuse, verbose)
354  int fd;
355  bool inuse;
356  bool verbose;
357 {
358  cfvar_t *p = cfvar;
359  time_t now = time(NULL);
360  char tstr[256];
361  char *section = "";
362  char *string = NULL;
363 
364 #if HAVE_CTIME_R
365 #ifdef _POSIX_PTHREAD_SEMANTICS
366  ctime_r(&now, tstr);
367 #else
368  ctime_r(&now, tstr, sizeof (tstr));
369 #endif
370 #elif HAVE_CTIME
371  ctime(&now, sizeof (tstr));
372 #else
373  strlcpy(tstr, "-", sizeof (tstr));
374 #endif
375  {
376  int n = strlen(tstr) - 1;;
377 
378  if (tstr[n] == '\n')
379  tstr[n] = '\0';
380  }
381 
382  FD_PRINTF(fd, "#\n");
383  FD_PRINTF(fd, "# ze-filter - (c) Ecole des Mines de Paris 2008, 2009\n");
384  FD_PRINTF(fd, "# Creation date : %s\n", tstr);
385  switch (inuse) {
386  case MK_CF_DEFAULT:
387  string = "default";
388  break;
389  case MK_CF_RUNNING:
390  string = "running";
391  break;
392  case MK_CF_NULL:
393  string = "null filter";
394  break;
395  default:
396  string = "default";
397  break;
398  }
399  FD_PRINTF(fd, "# Configuration file template : %s values\n", string);
400  FD_PRINTF(fd, "#\n");
401 
402  while (p->id >= 0) {
403  if (verbose && strcasecmp(section, p->cfsection) != 0) {
404  char s[128];
405 
406  section = p->cfsection;
407  zeStrSet(s, '#', 72);
408  FD_PRINTF(fd, "%s\n", s);
409  FD_PRINTF(fd, "# SECTION : %s\n", section);
410  FD_PRINTF(fd, "%s\n\n", s);
411  }
412 
413  if (p->cftag == NULL)
414  continue;
415 
416  if (verbose) {
417  FD_PRINTF(fd, "# %s\n", p->cftag);
418  FD_PRINTF(fd, "# %s\n", STRNULL(p->desc, ""));
419  if (p->syntax != NULL && strlen(p->syntax) > 0)
420  FD_PRINTF(fd, "# Syntax : %s\n", STRNULL(p->syntax, ""));
421 
422  if (p->type == ZE_ENUM) {
423  char **v;
424 
425  FD_PRINTF(fd, "# VALUES : ");
426  for (v = p->enum_ptr; *v != NULL; v++)
427  FD_PRINTF(fd, " %s ", *v);
428  FD_PRINTF(fd, "\n");
429  }
430  }
431  {
432  char *svalue = NULL;
433 
434  if (p->id != CF_VERSION) {
435  switch (inuse) {
436  case MK_CF_NULL:
437  svalue = STRNULL(p->cfnull, "");
438  break;
439  case MK_CF_RUNNING:
440  svalue = STRNULL(cf_get_str(p->id), "");
441  break;
442  case MK_CF_DEFAULT:
443  svalue = STRNULL(p->cfdefault, "");
444  break;
445  default:
446  svalue = STRNULL(p->cfdefault, "");
447  break;
448  }
449  } else
450  svalue = VERSION;
451 
452 #if 1
453  FD_PRINTF(fd, "%-32s %s\n", p->cftag, STRNULL(svalue, ""));
454 #else
455  {
456  char *ts = NULL;
457  int i;
458  int argc;
459  char *argv[32];
460 
461  ts = strdup(svalue);
462  if (ts == NULL)
463  continue;
464  argc = zeStr2Tokens(ts, 32, argv, "\n");
465  for (i = 0; i < argc; i++)
466  FD_PRINTF(fd, "%-32s %s\n", p->cftag, argv[i]);
467  FREE(ts);
468  }
469 #endif
470  }
471  if (verbose)
472  FD_PRINTF(fd, "\n");
473  p++;
474  }
475 }
476 
477 
478 /* ****************************************************************************
479  * *
480  * *
481  **************************************************************************** */
482 void
484 {
485  int i;
486 
487  for (i = 0; i < DIM_CF; i++) {
488  switch (cf[i].kind) {
489  case ZE_STR:
490  if (cf[i].sv)
491  *cf[i].sv = '\0';
492  cf[i].iv = 0;
493  break;
494  case ZE_INT:
495  cf[i].iv = 0;
496  break;
497  case ZE_ENUM:
498  cf[i].iv = 0;
499  if (cf[i].sv)
500  *cf[i].sv = '\0';
501  break;
502  default:
503  cf[i].iv = 0;
504  break;
505  }
506  }
507 }
508 
509 /* ****************************************************************************
510  * *
511  * *
512  **************************************************************************** */
513 int
515  int id;
516  char *name;
517  char **opt;
518  char *val;
519 {
520  int i = 0;
521  int len = 128;
522 
523  while (i < DIM_CF && cf[i].id != CF_NONE) {
524  if (cf[i].id == id)
525  return -1;
526  i++;
527  }
528  if (i >= DIM_CF)
529  return -2;
530 
531  if ((cf[i].sv = malloc(len + 1)) == NULL) {
532  ZE_LogSysError("malloc error");
533  return -3;
534  }
535 
536  strlcpy(cf[i].name, name, sizeof (cf[i].name));
537  memset(cf[i].sv, 0, len + 1);
538  cf[i].iv = 0;
539  cf[i].id = id;
540  cf[i].kind = ZE_ENUM;
541  cf[i].slen = len;
542  cf[i].opt = opt;
543 
544  cf_set_val(id, val);
545 
546  return id;
547 }
548 
549 /* ****************************************************************************
550  * *
551  * *
552  **************************************************************************** */
553 int
554 cf_add_id_str(id, name, len, val)
555  int id;
556  char *name;
557  int len;
558  char *val;
559 {
560  int i = 0;
561 
562  while (i < DIM_CF && cf[i].id != CF_NONE) {
563  if (cf[i].id == id)
564  return -1;
565  i++;
566  }
567  if (i >= DIM_CF)
568  return -2;
569 
570  if ((cf[i].sv = malloc(len + 1)) == NULL) {
571  ZE_LogSysError("malloc error");
572  return -3;
573  }
574 
575  strlcpy(cf[i].name, name, sizeof (cf[i].name));
576  memset(cf[i].sv, 0, len + 1);
577  cf[i].iv = 0;
578  cf[i].id = id;
579  cf[i].kind = ZE_STR;
580  cf[i].slen = len;
581 
582  cf_set_val(id, val);
583 
584  return id;
585 }
586 
587 /* ****************************************************************************
588  * *
589  * *
590  **************************************************************************** */
591 int
592 cf_add_id_int(id, name, val)
593  int id;
594  char *name;
595  char *val;
596 {
597  int i = 0;
598 
599  while (i < DIM_CF && cf[i].id != CF_NONE) {
600  if (cf[i].id == id)
601  return -1;
602  i++;
603  }
604  if (i >= DIM_CF)
605  return -2;
606 
607  strlcpy(cf[i].name, name, sizeof (cf[i].name));
608  cf[i].sv = NULL;
609  cf[i].iv = 0;
610  cf[i].id = id;
611  cf[i].kind = ZE_INT;
612  cf[i].slen = 0;
613 
614  cf_set_val(id, val);
615 
616  return id;
617 }
618 
619 /* ****************************************************************************
620  * *
621  * *
622  **************************************************************************** */
623 int
624 cf_add_id_double(id, name, val)
625  int id;
626  char *name;
627  char *val;
628 {
629  int i = 0;
630 
631  while (i < DIM_CF && cf[i].id != CF_NONE) {
632  if (cf[i].id == id)
633  return -1;
634  i++;
635  }
636  if (i >= DIM_CF)
637  return -2;
638 
639  strlcpy(cf[i].name, name, sizeof (cf[i].name));
640  cf[i].sv = NULL;
641  cf[i].iv = 0;
642  cf[i].id = id;
643  cf[i].kind = ZE_DOUBLE;
644  cf[i].slen = 0;
645 
646  cf_set_val(id, val);
647 
648  return id;
649 }
650 
651 
652 /* ****************************************************************************
653  * *
654  * *
655  **************************************************************************** */
656 int
658  char *tag;
659 {
660  int i = 0;
661 
662  for (i = 0; i < DIM_CF; i++) {
663  if (strcasecmp(tag, cf[i].name) == 0)
664  return cf[i].id;
665  }
666  return CF_NONE;
667 }
668 
669 /* ****************************************************************************
670  * *
671  * *
672  **************************************************************************** */
673 int
675  int id;
676 {
677  int i = 0;
678 
679  for (i = 0; i < DIM_CF; i++) {
680  if (id == cf[i].id)
681  return cf[i].kind;
682  }
683  return -1;
684 }
685 
686 /* ****************************************************************************
687  * *
688  * *
689  **************************************************************************** */
690 int
691 cf_set_val(id, value)
692  int id;
693  char *value;
694 {
695  int i = 0;
696  long val;
697 
698  if (value == NULL || strlen(value) == 0)
699  return CF_NONE;
700 
701  for (i = 0; i < DIM_CF; i++) {
702  if (id == cf[i].id)
703  break;
704  }
705  if (i == DIM_CF)
706  return CF_NONE;
707 
708  strlcpy(cf[i].strval, value, sizeof (cf[i].strval));
709  switch (cf[i].kind) {
710  case ZE_STR:
711  strlcpy(cf[i].sv, value, cf[i].slen);
712  break;
713  case ZE_INT:
714  val = zeStr2long(value, NULL, 0);
715  cf[i].iv = val;
716  break;
717  case ZE_DOUBLE:
718  val = zeStr2double(value, NULL, 0.0);
719  cf[i].dv = val;
720  break;
721  case ZE_ENUM:
722  val = get_enum_index(value, cf[i].opt);
723  if (val < 0)
724  return CF_NONE;
725  cf[i].iv = val;
726  if (strcasecmp(cf[i].opt[val], "OTHER") == 0)
727  strlcpy(cf[i].sv, value, cf[i].slen);
728  else
729  strlcpy(cf[i].sv, cf[i].opt[val], cf[i].slen);
730  break;
731  default:
732  return CF_NONE;
733  }
734  return id;
735 }
736 
737 /* ****************************************************************************
738  * *
739  * *
740  **************************************************************************** */
741 int
742 cf_set_str_val(id, value)
743  int id;
744  char *value;
745 {
746  int i = 0;
747 
748  if (value == NULL || strlen(value) == 0)
749  return CF_NONE;
750 
751  for (i = 0; i < DIM_CF; i++) {
752  if (id == cf[i].id)
753  break;
754  }
755  if (i == DIM_CF)
756  return CF_NONE;
757 
758  if (cf[i].kind == ZE_STR) {
759  strlcpy(cf[i].sv, value, cf[i].slen);
760  }
761  return id;
762 }
763 
764 /* ****************************************************************************
765  * *
766  * *
767  **************************************************************************** */
768 int
770  int id;
771  char *value;
772 {
773  int i = 0;
774 
775  if (value == NULL || strlen(value) == 0)
776  return CF_NONE;
777 
778  for (i = 0; i < DIM_CF; i++) {
779  if (id == cf[i].id)
780  break;
781  }
782  if (i == DIM_CF)
783  return CF_NONE;
784 
785  if (cf[i].kind == ZE_STR) {
786  if (strlen(cf[i].sv) > 0) {
787  if ((strlen(cf[i].sv) + strlen(value) + strlen("\n")) < cf[i].slen) {
788  strlcat(cf[i].sv, "\n", cf[i].slen);
789  strlcat(cf[i].sv, value, cf[i].slen);
790  } else
791  ZE_LogMsgWarning(0, "Error appending string");
792  } else
793  strlcpy(cf[i].sv, value, cf[i].slen);
794  }
795  return id;
796 }
797 
798 /* ****************************************************************************
799  * *
800  * *
801  **************************************************************************** */
802 int
804  int id;
805 {
806  int i = 0;
807  int res = -1;
808 
809  if (id <= 0)
810  return -1;
811 
812  CF_DATA_LOCK();
813  for (i = 0; i < DIM_CF; i++) {
814  if (id == cf[i].id) {
815  res = cf[i].iv;
816  break;
817  }
818  }
819  CF_DATA_UNLOCK();
820  return res;
821 }
822 
823 /* ****************************************************************************
824  * *
825  * *
826  **************************************************************************** */
827 double
829  int id;
830 {
831  int i = 0;
832  double res = 0.0;
833 
834  if (id <= 0)
835  return -1;
836 
837  CF_DATA_LOCK();
838  for (i = 0; i < DIM_CF; i++) {
839  if (id == cf[i].id) {
840  res = cf[i].dv;
841  break;
842  }
843  }
844  CF_DATA_UNLOCK();
845  return res;
846 }
847 
848 
849 /* ****************************************************************************
850  * *
851  * *
852  **************************************************************************** */
853 char *
855  int id;
856 {
857  int i = 0, j;
858  char *res = NULL;
859 
860  if (id <= 0)
861  return NULL;
862 
863  CF_DATA_LOCK();
864  for (i = 0; i < DIM_CF; i++) {
865  if (id == cf[i].id) {
866  switch (cf[i].kind) {
867  case ZE_STR:
868  res = cf[i].sv;
869  break;
870  case ZE_INT:
871  res = cf[i].strval;
872  break;
873  case ZE_ENUM:
874  if (cf[i].opt != NULL) {
875  for (j = 0; cf[i].opt[j] != NULL; j++) {
876  if (j == cf[i].iv) {
877  if (strcasecmp(cf[i].opt[j], "OTHER") != 0)
878  res = cf[i].opt[j];
879  else
880  res = cf[i].sv;
881  break;
882  }
883  }
884  }
885  break;
886  default:
887  break;
888  }
889  break;
890  }
891  }
892  CF_DATA_UNLOCK();
893  return res;
894 }
895 
896 /* ****************************************************************************
897  * *
898  * *
899  **************************************************************************** */
900 int
901 cf_get_enum_val(id, value, len)
902  int id;
903  char *value;
904  int len;
905 {
906  int i = 0;
907  int res = -1;
908 
909  if (id <= 0)
910  return -1;
911 
912  CF_DATA_LOCK();
913  for (i = 0; i < DIM_CF; i++) {
914  if (id == cf[i].id) {
915  if (value) {
916  if (cf[i].opt[cf[i].iv] == NULL) {
917  strlcpy(value, "", len);
918  break;
919  }
920  if (strcasecmp("OTHER", cf[i].opt[cf[i].iv]) == 0)
921  strlcpy(value, cf[i].sv, len);
922  else
923  strlcpy(value, cf[i].opt[cf[i].iv], len);
924  }
925  res = cf[i].iv;
926  break;
927  }
928  }
929  CF_DATA_UNLOCK();
930  return res;
931 }
932 
933 /* ****************************************************************************
934  * *
935  * *
936  **************************************************************************** */
937 static int
938 get_enum_index(val, opt)
939  char *val;
940  char **opt;
941 {
942  int i;
943 
944  if (opt == NULL)
945  return -1;
946  for (i = 0; opt[i] != NULL; i++) {
947  if (strcasecmp(opt[i], val) == 0 || strcasecmp(opt[i], "OTHER") == 0)
948  return i;
949  }
950  return -1;
951 }
952 
953 
954 /* ****************************************************************************
955  * *
956  * *
957  **************************************************************************** */
958 
959 #define KEY_CHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_.0123456789@"
960 
961 int
963  char *fname;
964 {
965  FILE *fin;
966  char line[512];
967  int lineno = 0;
968 
969  free_fext();
970 
971  if ((fname == NULL) || (strlen(fname) == 0)) {
972  ZE_LogMsgError(0, "Invalid fname : %s", STRNULL(fname, "(null)"));
973  return -1;
974  }
975 
976  if ((fin = fopen(fname, "r")) == NULL) {
977  ZE_LogSysError("Error opening file : %s", STRNULL(fname, "(NULL)"));
978  ZE_LogMsgError(0, "Exiting...");
979  exit(EX_SOFTWARE);
980  }
981 
982  while (fgets(line, sizeof (line), fin) == line) {
983  char *p, key[512], value[512];
984  int da;
985  int id;
986 
987  lineno++;
988 
989  if ((p = strpbrk(line, "\n\r")) != NULL)
990  *p = '\0';
991 
992  if (strlen(line) == 0)
993  continue;
994 
995  p = line;
996  p += strspn(p, " \t");
997  if (*p == '#' || strlen(p) == 0)
998  continue;
999 
1000  da = strspn(p, KEY_CHARS);
1001 
1002  strncpy(key, p, da);
1003  key[da] = '\0';
1004 
1005  {
1006  char *x;
1007 
1008  ZE_MessageInfo(15, "KEY = %s", key);
1009  while ((x = strchr(key, (int) '.')) != NULL)
1010  *x = '_';
1011  }
1012 
1013  p += da;
1014  p += strspn(p, "= \t");
1015  strlcpy(value, p, sizeof (value));
1016  if (strlen(value) > 0) {
1017  p = value + strlen(value) - 1;
1018  while (p > value && (*p == ' ' || *p == '\t'))
1019  *p-- = '\0';
1020  } else
1021  continue;
1022 
1023  if ((id = cf_get_id(key)) > 0) {
1024  int res;
1025 
1026  ZE_LogMsgDebug(20, "KEY : %-32s (%3d) --%s--\n", key, id, value);
1027  switch (id) {
1028  default:
1029  res = cf_set_val(id, value);
1030  break;
1031  }
1032  if (res <= 0) {
1033  ZE_MessageWarning(7, "# line %4d : Error setting parameter value : %s",
1034  lineno, value);
1035  }
1036  } else
1037  ZE_MessageWarning(7, "# line %4d : UNKNOWN KEY : %s", lineno, key);
1038 
1039  }
1040  fclose(fin);
1041 
1042  return lineno;
1043 }
1044 
1045 /* ****************************************************************************
1046  * *
1047  * *
1048  **************************************************************************** */
1049 #define LOAD_TABLE_HEADER \
1050  memset(fbuf, 0, sizeof(fbuf)); \
1051  if (fname != NULL) \
1052  strlcpy(fbuf, fname, sizeof(fbuf)); \
1053  argc = zeStr2Tokens(fbuf, 32, argv, " ,"); \
1054  for (i = 0; i < argc; i++) { \
1055  char *tag; \
1056  \
1057  tag = strchr(argv[i], ':'); \
1058  if (tag != NULL) \
1059  *tag++ = '\0';
1060 
1061 #define LOAD_TABLE_FOOTER \
1062  }
1063 
1064 #define LLEVEL 11
1065 void
1067 {
1068  char *fname;
1069  char *cfdir = NULL;
1070 
1071  cfdir = cf_get_str(CF_CONFDIR);
1072  if (cfdir == NULL || strlen(cfdir) == 0)
1073  cfdir = ZE_CONFDIR;
1074 
1075  ZE_MessageInfo(10, "Reloading configuration tables...");
1076 
1077  fname = cf_get_str(CF_REGEX_FILE);
1078  ZE_MessageInfo(LLEVEL, "Reloading : %s ...", fname);
1079  if (!load_regex_table(cfdir, fname))
1080  ZE_LogMsgError(0, "Unable to reload regex table");
1081 
1083  ZE_MessageInfo(LLEVEL, "Reloading : %s ...", fname);
1084  if (!load_oradata_table(cfdir, fname))
1085  ZE_LogMsgError(0, "Unable to reload oracle data table");
1086 
1088  ZE_MessageInfo(LLEVEL, "Reloading : %s ...", fname);
1089  if (!load_oracle_defs(cfdir, fname))
1090  ZE_LogMsgError(0, "Unable to reload oracle definitions table");
1091 
1092  fname = cf_get_str(CF_XFILES_FILE);
1093  ZE_MessageInfo(LLEVEL, "Reloading : %s ...", fname);
1094  if (!load_xfiles_table(cfdir, fname))
1095  ZE_LogMsgError(0, "Unable to reload xfiles data table");
1096 
1097  fname = cf_get_str(CF_DNS_IPRBWL);
1098  ZE_MessageInfo(LLEVEL, "Reloading : %s ...", fname);
1099  if (!load_iprbwl_table(cfdir, fname))
1100  ZE_LogMsgError(0, "Unable to reload IP RBWL data table");
1101 
1102  fname = cf_get_str(CF_DNS_URLBL);
1103  ZE_MessageInfo(LLEVEL, "Reloading : %s ...", fname);
1104  if (!load_urlbl_table(cfdir, fname))
1105  ZE_LogMsgError(0, "Unable to reload URL BL data table");
1106 }
1107 
1108 /* ****************************************************************************
1109  * *
1110  * *
1111  **************************************************************************** */
1112 bool
1114  char *app;
1115 {
1116  char *p;
1117 
1118  app = STRNULL(app, "ze-filter");
1119  /*
1120  * Log level
1121  */
1124 
1125  if (cf_opt.arg_l != NULL) {
1126  int l = 0;
1127 
1128  if ((l = atoi(cf_opt.arg_l)) > 0)
1129  ze_logLevel = l;
1130  }
1131  {
1132  char *envloglevel = NULL;
1133  int level;
1134 
1135  if ((envloglevel = getenv("ZEFILTER_LOG_LEVEL")) != NULL) {
1136  level = atoi(envloglevel);
1137  if (level > 0)
1138  ze_logLevel = level;
1139  }
1140  }
1141 
1142  /*
1143  * Log facility
1144  */
1145  {
1146  int opt = CF_LOG_FACILITY;
1147 
1148  if (STRCASEEQUAL(app, "ze-greyd"))
1149  opt = CF_GREYD_LOG_FACILITY;
1150 
1151  if ((p = cf_get_str(opt)) != NULL) {
1152  int n;
1153 
1154  n = zeLog_FacilityValue(p);
1155  if (n != -1 && n != ze_logFacility) {
1156  zeLog_SetFacility(p);
1157  closelog();
1158  openlog(app, LOG_PID | LOG_NOWAIT | LOG_NDELAY, ze_logFacility);
1159  ZE_MessageInfo(11, "NEW FACILITY : %d - %s",
1161  }
1162  }
1163  }
1164 
1166 
1168 
1170 
1174 
1179 
1183 
1186 
1188 
1190 
1192  OPT_YES);
1193 
1194  return TRUE;
1195 }
1196 
1197 
1198 /* ****************************************************************************
1199  * *
1200  * *
1201  **************************************************************************** */
1202 int
1203 configure(app, fname, only_cf)
1204  char *app;
1205  char *fname;
1206  bool only_cf;
1207 {
1208  static bool init_ok = FALSE;
1209 
1210  ZE_MessageInfo(9, "Loading ze-filter configuration");
1211 
1212  if (!init_ok) {
1213  if (cf_init() != 0) {
1214  ZE_MessageError(5, "configure : Can't initialise");
1215  exit(1);
1216  }
1217  init_ok = TRUE;
1218  }
1219 
1220  ZE_MessageInfo(10, "Loading default values");
1221  cf_defaults();
1222 
1223  ZE_MessageInfo(9, "Reading configuration file : %s",
1224  STRNULL(fname, "(NULL)"));
1225  cf_read_file(fname);
1226 
1227  configure_after(app);
1228 
1229  if (only_cf)
1230  goto fin;
1231 
1232  reload_cf_tables();
1233 
1234 #if FALSE && defined(CF_SOCKET)
1235  {
1236  char *g_sock;
1237 
1238  xxxxx g_sock = cf_get_str(CF_SOCKET);
1239 
1240  if (g_sock != NULL && strlen(g_sock) > 0)
1241  strlcpy(sm_sock, g_sock, sizeof (sm_sock));
1242 
1243  if (cf_opt.arg_i != NULL)
1244  strlcpy(sm_sock, cf_opt.arg_i, sizeof (sm_sock));
1245 
1246  if (cf_opt.arg_u != NULL)
1247  strlcpy(sm_sock, cf_opt.arg_u, sizeof (sm_sock));
1248 
1249  if (cf_opt.arg_p != NULL)
1250  strlcpy(sm_sock, cf_opt.arg_p, sizeof (sm_sock));
1251 
1252  {
1253  char *envsock = NULL;
1254 
1255  if ((envsock = getenv("ZEFILTER_SOCKET")) != NULL)
1256  strlcpy(sm_sock, envsock, sizeof (sm_sock));
1257  }
1258  ZE_MessageInfo(12, "SM_SOCK = %s", sm_sock);
1259  }
1260 #endif /* CF_SOCKET */
1261 
1262 fin:
1263  last_reconf_date = time(NULL);
1264 
1265  return 0;
1266 }
char * cftag
Definition: ze-cf.c:144
#define KEY_CHARS
Definition: ze-cf.c:959
#define CF_GREY_MAX_DELAY_NULLSENDER
Definition: cfh-defs.h:197
bool load_oradata_table(char *, char *)
Definition: ze-oracle.c:211
int cf_get_enum_val(int id, char *value, int len)
Definition: ze-cf.c:901
char * arg_p
Definition: ze-config.h:44
char * unix_sock
Definition: ze-cf.c:90
#define CF_GREY_TO_COMPONENT
Definition: cfh-defs.h:206
#define CF_GREY_WHITELIST_LIFETIME
Definition: cfh-defs.h:199
int cf_add_id_enum(int id, char *name, char **opt, char *val)
Definition: ze-cf.c:514
#define MK_CF_NULL
Definition: ze-cf.h:40
void grey_set_compat_domain_check(bool enable)
Definition: ze-grey.c:473
#define CF_XFILES_FILE
Definition: cfh-defs.h:93
#define CF_GREY_BLACKLIST_LIFETIME
Definition: cfh-defs.h:200
#define VERSION
Definition: version.h:25
int cf_set_val(int id, char *name)
Definition: ze-cf.c:691
void cf_defaults()
Definition: cfc-defs.h:313
bool grey_set_cleanup_interval(time_t tclean)
Definition: ze-grey.c:459
char * syntax
Definition: ze-cf.c:148
#define CF_GREYD_LOG_FACILITY
Definition: cfh-defs.h:212
int cf_init()
Definition: ze-cf.c:196
char sm_sock[]
time_t last_reconf_date
Definition: ze-cf.c:53
char * arg_l
Definition: ze-config.h:48
bool grey_set_tuples(char *ip, char *from, char *to)
Definition: ze-grey.c:355
#define FREE(x)
Definition: macros.h:37
int zeLog_FacilityValue(char *)
Definition: zeSyslog.c:442
#define CF_DNS_URLBL
Definition: cfh-defs.h:115
#define CF_LOG_FACILITY
Definition: cfh-defs.h:55
int cf_add_id_int(int id, char *name, char *val)
Definition: ze-cf.c:592
int ze_logLevel
Definition: zeSyslog.c:34
#define STRNULL(x, r)
Definition: macros.h:81
int type
Definition: ze-cf.c:139
bool grey_set_delays(time_t tp_min_norm, time_t tp_max_norm, time_t tp_min_null, time_t tp_max_null)
Definition: ze-grey.c:399
#define CF_LOG_LEVEL
Definition: cfh-defs.h:56
int ze_logFacility
Definition: zeSyslog.c:35
#define CF_GREY_IP_COMPONENT
Definition: cfh-defs.h:204
int cf_set_int_val(int id, int val)
char * desc
Definition: ze-cf.c:147
#define CF_GREY_MIN_DELAY_NORMAL
Definition: cfh-defs.h:194
char * cfnull
Definition: ze-cf.c:145
int cf_set_str_val(int id, char *val)
Definition: ze-cf.c:742
#define FALSE
Definition: macros.h:160
char * zeLog_FacilityName(int)
Definition: zeSyslog.c:431
int id
Definition: ze-cf.c:56
#define strlcpy
Definition: zeString.h:32
void mk_cf_file(int fd, bool inuse, bool verbose)
Definition: ze-cf.c:353
#define ZE_LogMsgError(level,...)
Definition: zeSyslog.h:113
#define CF_DATA_LOCK()
Definition: ze-cf.c:94
#define LLEVEL
Definition: ze-cf.c:1064
#define OPT_YES
Definition: ze-cf.h:45
#define CF_VERSION
Definition: cfh-defs.h:29
bool load_xfiles_table(char *, char *)
Definition: ze-fileexp.c:575
#define ZE_CONF_FILE
Definition: defs.h:40
Definition: ze-cf.c:137
void cf_clear_values()
Definition: ze-cf.c:483
#define MK_CF_DEFAULT
Definition: ze-cf.h:41
#define ZE_DOUBLE
Definition: ze-cf.c:49
#define FD_PRINTF(fdp,...)
Definition: macros.h:45
int cf_get_int(int id)
Definition: ze-cf.c:803
int zeStr2Tokens(char *, int, char **, char *)
Definition: zeStrings.c:610
#define CF_DATA_UNLOCK()
Definition: ze-cf.c:99
bool load_regex_table(char *, char *)
Definition: ze-mailregex.c:258
#define CF_DB_CACHE_SIZE
Definition: cfh-defs.h:79
#define strlcat
Definition: zeString.h:28
char name[64]
Definition: ze-cf.c:57
#define strchr
Definition: ze-sys.h:218
#define CF_DNS_IPRBWL
Definition: cfh-defs.h:141
#define CF_CONFDIR
Definition: cfh-defs.h:51
void zeLog_SetFacility(char *)
Definition: zeSyslog.c:475
char ** opt
Definition: ze-cf.c:63
long zeStr2long(char *s, int *error, long dval)
Definition: zeStrConvert.c:35
char * arg_u
Definition: ze-config.h:46
#define CF_GREY_DEWHITE_FLAGS
Definition: cfh-defs.h:209
#define CF_ORACLE_SCORES_FILE
Definition: cfh-defs.h:124
size_t zeDb_SetDefaultCacheSize(size_t size)
Definition: zeDb.c:54
#define ZE_LogMsgDebug(level,...)
Definition: zeSyslog.h:109
bool grey_set_lifetime(time_t tv, time_t tw, time_t tb)
Definition: ze-grey.c:422
int cf_add_id_str(int id, char *name, int len, char *val)
Definition: ze-cf.c:554
char strval[64]
Definition: ze-cf.c:64
double zeStr2double(char *s, int *error, double dval)
Definition: zeStrConvert.c:202
char * zeStrSet(char *, int, int)
Definition: zeStrings.c:330
#define DIM_CF
Definition: ze-cf.c:51
int cf_append_str_val(int id, char *value)
Definition: ze-cf.c:769
bool configure_after(char *app)
Definition: ze-cf.c:1113
bool load_oracle_defs(char *cfdir, char *fname)
char * cfdefault
Definition: ze-cf.c:149
#define ZE_MessageInfo(level,...)
Definition: zeSyslog.h:90
#define OPT_NO
Definition: ze-cf.h:44
#define CF_GREY_FROM_COMPONENT
Definition: cfh-defs.h:205
double dv
Definition: ze-cf.c:61
int slen
Definition: ze-cf.c:59
#define TRUE
Definition: macros.h:157
#define ZE_MessageWarning(level,...)
Definition: zeSyslog.h:92
OPT_REC_T cf_opt
Definition: ze-config.c:40
#define CF_STATS_INTERVAL
Definition: cfh-defs.h:64
#define CF_NONE
Definition: ze-cf.c:44
#define ZE_LogSysError(...)
Definition: zeSyslog.h:129
#define CF_GREY_MAX_DELAY_NORMAL
Definition: cfh-defs.h:196
#define ZE_MessageError(level,...)
Definition: zeSyslog.h:93
char * cf_get_str(int id)
Definition: ze-cf.c:854
#define CF_GREY_MAX_PENDING_NORMAL
Definition: cfh-defs.h:201
Definition: ze-cf.c:55
#define CF_GREY_MIN_DELAY_NULLSENDER
Definition: cfh-defs.h:195
char * conf_file
Definition: ze-cf.c:38
#define CF_GREY_COMPAT_DOMAIN_CHECK
Definition: cfh-defs.h:203
int cf_add_id_double(int id, char *name, char *val)
Definition: ze-cf.c:624
char * arg_i
Definition: ze-config.h:45
#define CF_GREY_VALIDLIST_LIFETIME
Definition: cfh-defs.h:198
#define ZE_LogMsgWarning(level,...)
Definition: zeSyslog.h:112
#define CF_REGEX_FILE
Definition: cfh-defs.h:117
void grey_set_dewhite_flags(char *, bool)
Definition: ze-grey.c:1772
char ** enum_ptr
Definition: ze-cf.c:141
int configure(char *app, char *fname, bool only_cf)
Definition: ze-cf.c:1203
bool grey_set_max_pending(int normal, int bounce)
Definition: ze-grey.c:442
char * cfsection
Definition: ze-cf.c:146
#define ZE_ENUM
Definition: ze-cf.c:47
int kind
Definition: ze-cf.c:58
#define CF_LOG_SEVERITY
Definition: cfh-defs.h:57
int str_length
Definition: ze-cf.c:142
long iv
Definition: ze-cf.c:60
#define MK_CF_RUNNING
Definition: ze-cf.h:42
#define STRCASEEQUAL(a, b)
Definition: macros.h:72
struct jcfrec_T jcfrec_T
void cf_load_default()
int cf_set_double_val(int id, double val)
#define ZE_INT
Definition: ze-cf.c:48
bool load_iprbwl_table(char *cfdir, char *fname)
#define ZE_CONFDIR
Definition: defs.h:36
bool ze_logSeverity
Definition: zeSyslog.c:36
char * sv
Definition: ze-cf.c:62
int cf_get_kind(int id)
Definition: ze-cf.c:674
#define CF_SOCKET
Definition: cfh-defs.h:46
void reload_cf_tables()
Definition: ze-cf.c:1066
double cf_get_double(int id)
Definition: ze-cf.c:828
#define CF_GREY_MAX_PENDING_NULLSENDER
Definition: cfh-defs.h:202
int id
Definition: ze-cf.c:138
#define CF_ORACLE_DATA_FILE
Definition: cfh-defs.h:125
unsigned int statistics_interval
Definition: ze-cf.c:40
bool load_urlbl_table(char *cfdir, char *fname)
Definition: ze-dns-urlbl.c:347
int cf_get_id(char *tag)
Definition: ze-cf.c:657
int cf_read_file(char *fname)
Definition: ze-cf.c:962
void cf_dump(int fd, bool full)
Definition: ze-cf.c:214
#define ZE_STR
Definition: ze-cf.c:46
#define CF_GREY_CLEANUP_INTERVAL
Definition: cfh-defs.h:208
void init_file_extension_regex()
Definition: ze-fileexp.c:249
int free_fext()
Definition: ze-fileexp.c:89