ze-filter  (ze-filter-0.8.0-develop-180218)
zeRdFile.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 
25 #include <ze-sys.h>
26 
27 #include "libze.h"
28 
29 
30 int zm_RdTextFile(char *, int, int, char *,
31  int (*)(void *, void *));
32 
33 static void strClearBlanks(char *);
34 
35 #define BSIZE 1024
36 
37 /* ****************************************************************************
38  * *
39  * *
40  ******************************************************************************/
41 
42 int
43 zm_RdTextFile(fname, rdtype, rdreverse, tag, func)
44  char *fname;
45  int rdtype;
46  int rdreverse;
47  char *tag;
48  int (*func) (void *, void *);
49 {
50  char s[BSIZE];
51  FILE *fin = stdin;
52  bool rdstate = TRUE, chktag = FALSE;
53  char *beg_tag, *end_tag;
54  int nb = 0;
55 
56  ASSERT(func != NULL);
57 
58  beg_tag = end_tag = NULL;
59 
60  if (fname != NULL && strlen(fname) > 0) {
61  static int nberr = 0;
62  static time_t tlast = (time_t) 0;
63 
64  if ((fin = fopen(fname, "r")) == NULL) {
65  ZE_LogSysError("fopen(%s)", STRNULL(fname, "NULL"));
66 
67  if (tlast > 3600) {
68  tlast = time(NULL);
69  nberr = 0;
70  }
71 
72  if (++nberr > 16) {
73  if (errno != EINTR)
74  exit(EX_SOFTWARE);
75  }
76 
77  return 0;
78  } else {
79  nberr = 0;
80  tlast = (time_t) 0;
81  }
82  }
83 
84  if (tag != NULL && strlen(tag) > 0) {
85  size_t sz = strlen(tag) + 8;
86 
87  rdstate = FALSE;
88  chktag = TRUE;
89 
90  beg_tag = malloc(sz);
91  end_tag = malloc(sz);
92  if (beg_tag == NULL || end_tag == NULL)
93  goto fin;
94 
95  snprintf(beg_tag, sz, "<%s>", tag);
96  snprintf(end_tag, sz, "</%s>", tag);
97  }
98 
99  memset(s, 0, sizeof (s));
100  while (fgets(s, BSIZE, fin) == s) {
101  char *pk = NULL, *pv = NULL;
102  char *q;
103 
104  s[BSIZE - 1] = '\0';
105  if ((pk = strchr(s, '\n')) != NULL)
106  *pk = '\0';
107 
108  if (chktag) {
109  if (!rdstate) {
110  if (strncasecmp(beg_tag, s, strlen(beg_tag)) == 0)
111  rdstate = TRUE;
112  continue;
113  } else {
114  if (strncasecmp(end_tag, s, strlen(end_tag)) == 0) {
115  rdstate = FALSE;
116  continue;
117  }
118  }
119  }
120 
121  pk = s;
122  pk += strspn(pk, " \t");
123  if ((strlen(pk) == 0) || (*pk == '#'))
124  continue;
125  q = pk + strlen(pk) - 1;
126  while ((q != pk) && (*q == ' ' || *q == '\t'))
127  *q-- = '\0';
128 
129  if (rdtype == RD_TWO_COLUMN) {
130  pv = pk + strcspn(pk, " \t");
131  if (*pv != '\0') {
132  q = pv;
133  pv += strspn(pv, " \t");
134  *q = '\0';
135  }
136  if (rdreverse == RD_REVERSE) {
137  q = pv;
138  pv = pk;
139  pk = q;
140  }
141  }
142  strClearBlanks(pk);
143  strClearBlanks(pv);
144 
145  if (strlen(pk) > 0) {
146  int res;
147 
148  if ((res = func(pk, pv)) != 0) {
149  /*
150  * what do we do if ther's an error ???
151  */
152  /*
153  * separate negative and positive errors ???
154  */
155  if (res < 0) {
156  /*
157  * fatal errors ...
158  */
159  } else {
160  /*
161  * non fatal errors ...
162  */
163  }
164  } else
165  nb++;
166  }
167  memset(s, 0, sizeof (s));
168  }
169 
170 fin:
171  FREE(beg_tag);
172  FREE(end_tag);
173 
174  if (fin != stdin)
175  fclose(fin);
176 
177  return nb;
178 }
179 
180 /* ****************************************************************************
181  * *
182  * *
183  ******************************************************************************/
184 int
185 zm_RdFile(fname, tag, func, arg)
186  char *fname;
187  char *tag;
188  RDFILE_F func;
189  void *arg;
190 {
191  char s[BSIZE];
192  FILE *fin = stdin;
193  bool rdstate = TRUE, chktag = FALSE;
194  char *beg_tag, *end_tag;
195  int nb = 0;
196 
197  ASSERT(func != NULL);
198 
199  beg_tag = end_tag = NULL;
200 
201  if (fname != NULL && strlen(fname) > 0) {
202  static int nberr = 0;
203  static time_t tlast = (time_t) 0;
204 
205  if ((fin = fopen(fname, "r")) == NULL) {
206  ZE_LogSysError("fopen(%s)", STRNULL(fname, "NULL"));
207 
208  if (tlast > 3600) {
209  tlast = time(NULL);
210  nberr = 0;
211  }
212 
213  if (++nberr > 16) {
214  if (errno != EINTR)
215  exit(EX_SOFTWARE);
216  }
217 
218  return 0;
219  } else {
220  nberr = 0;
221  tlast = (time_t) 0;
222  }
223  }
224 
225  if (tag != NULL && strlen(tag) > 0) {
226  size_t sz = strlen(tag) + 8;
227 
228  rdstate = FALSE;
229  chktag = TRUE;
230 
231  beg_tag = malloc(sz);
232  end_tag = malloc(sz);
233  if (beg_tag == NULL || end_tag == NULL)
234  goto fin;
235 
236  snprintf(beg_tag, sz, "^<%s>", tag);
237  snprintf(end_tag, sz, "^</%s>", tag);
238  }
239 
240  memset(s, 0, sizeof (s));
241  while (fgets(s, BSIZE, fin) == s) {
242  char *q = NULL;
243  int res;
244 
245  s[BSIZE - 1] = '\0';
246  if ((q = strchr(s, '\n')) != NULL)
247  *q = '\0';
248 
249  if (strlen(s) == 0)
250  continue;
251 
252  if (zeStrRegex(s, "^[ \t]*$", NULL, NULL, FALSE))
253  continue;
254  if (zeStrRegex(s, "^[ \t]*#", NULL, NULL, FALSE))
255  continue;
256 
257  if (chktag) {
258  if (!rdstate) {
259  if (zeStrRegex(s, beg_tag, NULL, NULL, TRUE))
260  rdstate = TRUE;
261  continue;
262  } else {
263  if (zeStrRegex(s, end_tag, NULL, NULL, TRUE)) {
264  rdstate = FALSE;
265  continue;
266  }
267  }
268  }
269 
270  if ((res = func(s, arg)) != 0) {
271  /*
272  * what do we do if ther's an error ???
273  */
274  /*
275  * separate negative and positive errors ???
276  */
277  if (res < 0) {
278  /*
279  * fatal errors ...
280  */
281  } else {
282  /*
283  * non fatal errors ...
284  */
285  }
286  } else
287  nb++;
288 
289  memset(s, 0, sizeof (s));
290  }
291 
292 fin:
293  FREE(beg_tag);
294  FREE(end_tag);
295 
296  if (fin != stdin)
297  fclose(fin);
298 
299  return nb;
300 }
301 
302 /* ****************************************************************************
303  * *
304  * *
305  ******************************************************************************/
306 static void
307 strClearBlanks(s)
308  char *s;
309 {
310  char *p;
311 
312  if (s == NULL || strlen(s) == 0)
313  return;
314 
315  p = s + strlen(s) - 1;
316  while ((p != s) && ((*p == ' ') || (*p == '\t')))
317  *p-- = '\0';
318 }
#define BSIZE
Definition: zeRdFile.c:35
#define ASSERT(a)
Definition: macros.h:27
#define FREE(x)
Definition: macros.h:37
int zm_RdFile(char *fname, char *tag, RDFILE_F func, void *arg)
Definition: zeRdFile.c:185
#define STRNULL(x, r)
Definition: macros.h:81
#define FALSE
Definition: macros.h:160
bool zeStrRegex(char *, char *, long *, long *, bool)
Definition: zeStrings.c:544
#define strchr
Definition: ze-sys.h:218
int(* RDFILE_F)(void *, void *)
Definition: ze-rdfile.h:35
int nb
Definition: ze-connopen.c:61
#define RD_REVERSE
Definition: ze-rdfile.h:30
#define TRUE
Definition: macros.h:157
#define ZE_LogSysError(...)
Definition: zeSyslog.h:129
int zm_RdTextFile(char *, int, int, char *, int(*)(void *, void *))
#define RD_TWO_COLUMN
Definition: ze-rdfile.h:27