source: npl/mailserver/dspam/dspam-3.10.2/src/read_config.c @ c5c522c

gcc484ntopperl-5.22
Last change on this file since c5c522c was c5c522c, checked in by Edwin Eefting <edwin@datux.nl>, 8 years ago

initial commit, transferred from cleaned syn3 svn tree

  • Property mode set to 100644
File size: 9.6 KB
Line 
1/* $Id: read_config.c,v 1.197 2011/06/28 00:13:48 sbajic Exp $ */
2
3/*
4 DSPAM
5 COPYRIGHT (C) 2002-2012 DSPAM PROJECT
6
7 This program is free software: you can redistribute it and/or modify
8 it under the terms of the GNU Affero General Public License as
9 published by the Free Software Foundation, either version 3 of the
10 License, or (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU Affero General Public License for more details.
16
17 You should have received a copy of the GNU Affero General Public License
18 along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
20*/
21
22#ifdef HAVE_CONFIG_H
23#include <auto-config.h>
24#endif
25
26#include <stdio.h>
27#include <errno.h>
28#include <stdlib.h>
29#ifdef SPLIT_CONFIG
30#include <dirent.h>
31#endif
32#ifdef HAVE_STRINGS_H
33#include <strings.h>
34#endif
35#include <string.h>
36
37#include "config_shared.h"
38#include "read_config.h"
39#include "config.h"
40#include "error.h"
41#include "language.h"
42#include "libdspam.h"
43#include "pref.h"
44#include "util.h"
45
46#ifdef SPLIT_CONFIG
47long dirread(const char *path, config_t *attrib, long num_root);
48long fileread(const char *path, config_t *attrib, long num_root);
49#endif
50
51static char *next_normal_token(char **p)
52{
53  char *start = *p;
54  while (**p) {
55    if (**p == ' ' || **p == '\t') {
56      **p = 0;
57      *p += 1;
58      break;
59    }
60    *p += 1;
61  }
62  return start;
63}
64
65static char *next_quoted_token(char **p)
66{
67  char *start = *p;
68  while (**p) {
69    if (**p == '\"') {
70      **p = 0;
71      *p += 1;
72      break;
73    }
74    *p += 1;
75  }
76  return start;
77}
78
79static char *tokenize(char *text, char **next)
80{
81  /* Initialize */
82  if (text)
83    *next = text;
84
85  while (**next) {
86    /* Skip leading whitespace */
87    if (**next == ' ' || **next == '\t') {
88      *next += 1;
89      continue;
90    }
91
92    /* Strip off one token */
93    if (**next == '\"') {
94      *next += 1;
95      return next_quoted_token(next);
96    } else
97      return next_normal_token(next);
98  }
99
100  return NULL;
101}
102
103#ifdef SPLIT_CONFIG
104// Read the files in the directory and pass it to fileread
105// or if it is a file, pass it to fileread.
106long dirread(const char *path, config_t *attrib, long num_root) {
107  DIR *dir_p;
108  char *fulldir = NULL;
109  struct dirent *dir_entry_p;
110
111  if (path == NULL) return 0;
112
113  // Strip "\n"
114  char *ptr = strrchr(path, '\n');
115  if (ptr)
116    *ptr = '\0';
117
118  if ((dir_p = opendir(path)) == NULL) {
119    LOG(LOG_ERR, ERR_IO_FILE_OPEN, path, strerror(errno));
120    return 0;
121  }
122
123  if ((dir_p = opendir(path))) {
124    while((dir_entry_p = readdir(dir_p)))
125    {
126      // We don't need the . and ..
127      if (strcmp(dir_entry_p->d_name, ".") == 0 ||
128          strcmp(dir_entry_p->d_name, "..") == 0)
129        continue;
130
131      int n = strlen(dir_entry_p->d_name);
132
133      // only use files which end in .conf:
134      if (n < 5) continue;
135      if (strncmp(dir_entry_p->d_name + n - 5, ".conf", 5) != 0) continue;
136
137      int m = strlen(path);
138
139      fulldir = (char *)malloc(n+m+2);
140      if (fulldir == NULL) {
141        LOG(LOG_CRIT, ERR_MEM_ALLOC);
142        return 0;
143      }
144
145      strcpy(fulldir, (char *)path);
146      strcat(fulldir, "/");
147      strcat(fulldir, dir_entry_p->d_name);
148      num_root = fileread((const char *)fulldir, attrib, num_root);
149      free(fulldir);
150    }
151    closedir(dir_p);
152  } else {
153    // Could be a file.
154    return fileread((const char *)path, attrib, num_root);
155  }
156
157  return num_root;
158}
159
160// Read the file and check if there is an Include directive, if so then pass
161// it to dirread.
162long fileread(const char *path, config_t *attrib, long num_root) {
163  config_t ptr;
164#else
165config_t read_config(const char *path) {
166  config_t attrib, ptr;
167#endif
168  FILE *file;
169#ifdef SPLIT_CONFIG
170  long attrib_size = 128;
171#else
172  long attrib_size = 128, num_root = 0;
173#endif
174  char buffer[1024];
175  char *a, *c, *v, *bufptr = buffer;
176
177#ifndef SPLIT_CONFIG
178  attrib = calloc(1, attrib_size*sizeof(attribute_t));
179  if (attrib == NULL) {
180    LOG(LOG_CRIT, ERR_MEM_ALLOC);
181    return NULL;
182  }
183#endif
184
185  if (path == NULL)
186    file = fopen(CONFIG_DEFAULT, "r");
187  else
188    file = fopen(path, "r");
189
190  if (file == NULL) {
191#ifdef SPLIT_CONFIG
192    if (path == NULL) {
193      LOG(LOG_ERR, ERR_IO_FILE_OPEN, CONFIG_DEFAULT, strerror(errno));
194    } else {
195      LOG(LOG_ERR, ERR_IO_FILE_OPEN, path, strerror(errno));
196    }
197    return 0;
198#else
199    LOG(LOG_ERR, ERR_IO_FILE_OPEN, CONFIG_DEFAULT, strerror(errno));
200    free(attrib);
201    return NULL;
202#endif
203  }
204
205  while(fgets(buffer, sizeof(buffer), file)!=NULL) {
206
207    chomp(buffer);
208
209    /* Remove comments */
210    if ((c = strchr(buffer, '#')) || (c = strchr(buffer, ';')))
211      *c = 0;
212
213    /* Parse attribute name */
214    if (!(a = tokenize(buffer, &bufptr)))
215      continue; /* Ignore whitespace-only lines */
216
217    while ((v = tokenize(NULL, &bufptr)) != NULL) {
218#ifdef SPLIT_CONFIG
219      // Check for include directive
220      if (strcmp(a, "Include") == 0) {
221        // Give v (value) to dirraed
222        num_root = dirread(v, attrib, num_root);
223      } else {
224        if (_ds_find_attribute((*attrib), a)!=NULL) {
225          _ds_add_attribute((*attrib), a, v);
226        }
227        else {
228          num_root++;
229          if (num_root >= attrib_size) {
230            attrib_size *=2;
231            ptr = realloc((*attrib), attrib_size*sizeof(attribute_t));
232            if (ptr)
233              *attrib = ptr;
234            else {
235              LOG(LOG_CRIT, ERR_MEM_ALLOC);
236              fclose(file);
237              return 0;
238            }
239          }
240          _ds_add_attribute((*attrib), a, v);
241        }
242#else
243      if (_ds_find_attribute(attrib, a)!=NULL) {
244        _ds_add_attribute(attrib, a, v);
245      }
246      else {
247        num_root++;
248        if (num_root >= attrib_size) {
249          attrib_size *=2;
250          ptr = realloc(attrib, attrib_size*sizeof(attribute_t));
251          if (ptr)
252            attrib = ptr;
253          else {
254            LOG(LOG_CRIT, ERR_MEM_ALLOC);
255            fclose(file);
256            return NULL;
257          }
258        }
259        _ds_add_attribute(attrib, a, v);
260#endif
261      }
262    }
263  }
264
265  fclose(file);
266
267#ifdef SPLIT_CONFIG
268  return num_root;
269}
270
271config_t read_config(const char *path) {
272  config_t attrib;
273  long attrib_size = 128, num_root = 0;
274
275  attrib = calloc(1, attrib_size*sizeof(attribute_t));
276  if (attrib == NULL) {
277    LOG(LOG_CRIT, ERR_MEM_ALLOC);
278    return NULL;
279  }
280
281  if (fileread(path, &attrib, num_root) == 0)
282    return NULL;
283#else
284  ptr = realloc(attrib, ((num_root+1)*sizeof(attribute_t))+1);
285  if (ptr)
286    return ptr;
287  LOG(LOG_CRIT, ERR_MEM_ALLOC);
288#endif
289
290  return attrib;
291}
292
293int configure_algorithms(DSPAM_CTX *CTX) {
294  if (_ds_read_attribute(agent_config, "Algorithm"))
295    CTX->algorithms = 0;
296                                                                               
297  if (_ds_match_attribute(agent_config, "Algorithm", "graham"))
298    CTX->algorithms |= DSA_GRAHAM;
299                                                                               
300  if (_ds_match_attribute(agent_config, "Algorithm", "burton"))
301    CTX->algorithms |= DSA_BURTON;
302                                                                               
303  if (_ds_match_attribute(agent_config, "Algorithm", "robinson"))
304    CTX->algorithms |= DSA_ROBINSON;
305
306  if (_ds_match_attribute(agent_config, "Algorithm", "naive"))
307    CTX->algorithms |= DSA_NAIVE;
308                                                                               
309  if (_ds_match_attribute(agent_config, "PValue", "robinson"))
310    CTX->algorithms |= DSP_ROBINSON;
311  else if (_ds_match_attribute(agent_config, "PValue", "markov"))
312    CTX->algorithms |= DSP_MARKOV;
313  else
314    CTX->algorithms |= DSP_GRAHAM;
315
316  if (_ds_match_attribute(agent_config, "Tokenizer", "word"))
317    CTX->tokenizer = DSZ_WORD;
318  else if (_ds_match_attribute(agent_config, "Tokenizer", "chain") ||
319           _ds_match_attribute(agent_config, "Tokenizer", "chained"))
320    CTX->tokenizer = DSZ_CHAIN;
321  else if (_ds_match_attribute(agent_config, "Tokenizer", "sbph"))
322    CTX->tokenizer = DSZ_SBPH;
323  else if (_ds_match_attribute(agent_config, "Tokenizer", "osb"))
324    CTX->tokenizer = DSZ_OSB;
325 
326  if (_ds_match_attribute(agent_config, "Algorithm", "chi-square"))
327  {
328    if (CTX->algorithms != 0 && CTX->algorithms != DSP_ROBINSON) {
329      LOG(LOG_WARNING, "Warning: Chi-Square algorithm enabled with other algorithms. False positives may ensue.");
330    }
331    CTX->algorithms |= DSA_CHI_SQUARE;
332  }
333
334  return 0;
335}
336
337agent_pref_t pref_config(void)
338{
339  agent_pref_t PTX = malloc(sizeof(agent_attrib_t)*PREF_MAX);
340  agent_pref_t ptr;
341  attribute_t attrib;
342  char *p, *q;
343  char *ptrptr = NULL;
344  int i = 0;
345
346  if (PTX == NULL) {
347    LOG(LOG_CRIT, ERR_MEM_ALLOC);
348    return NULL;
349  }
350  PTX[0] = NULL;
351
352  /* Apply default preferences from dspam.conf */
353                                                                               
354  attrib = _ds_find_attribute(agent_config, "Preference");
355                                                                               
356  LOGDEBUG("Loading preferences from dspam.conf");
357                                                                               
358  while(attrib != NULL) {
359    char *pcopy = strdup(attrib->value);
360                                                                             
361    p = strtok_r(pcopy, "=", &ptrptr);
362    if (p == NULL) {
363      free(pcopy);
364      continue;
365    }
366    q = p + strlen(p)+1;
367
368    PTX[i] = _ds_pref_new(p, q);
369    PTX[i+1] = NULL;
370
371    i++;
372    attrib = attrib->next;
373    free(pcopy);
374  }
375
376  ptr = realloc(PTX, sizeof(agent_attrib_t)*(i+1));
377  if (ptr)
378    return ptr;
379 
380  LOG(LOG_CRIT, ERR_MEM_ALLOC);
381  return PTX;
382}
Note: See TracBrowser for help on using the repository browser.