ze-filter  (ze-filter-0.8.0-develop-180218)
ze-divers.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 #include "zelibs.h"
27 
28 /* ****************************************************************************
29  * *
30  * *
31  ******************************************************************************/
32 int
34  uint32_t val;
35 {
36  int r = 0;
37  int i;
38 
39  for (i = 0; i < 8 * sizeof (val); i++)
40  if (GET_BIT(val, i))
41  r++;
42  return r;
43 }
44 
45 
46 /* ****************************************************************************
47  * *
48  * *
49  ******************************************************************************/
50 #if 0
51 time_t
52 timestr2secs(s)
53  char *s;
54 {
55  int l;
56  time_t n;
57  char strn[16];
58 
59  if ((s == NULL) || (strlen(s) == 0))
60  return 3600;
61 
62  if ((l = strspn(s, "0123456789")) == 0)
63  return 3600;
64 
65  if (l >= (sizeof (strn)))
66  return 3600;
67 
68  memset(strn, 0, sizeof (strn));
69  strncpy(strn, s, l);
70 
71 #if HAVE_STRTOL
72  errno = 0;
73  n = strtol(strn, (char **) NULL, 10);
74  if (errno == ERANGE || errno == EINVAL || n <= 0)
75  n = 3600;
76 #else
77  n = atoi(strn);
78  if (n <= 0 | n > 32)
79  n = 3600;
80 #endif
81  s += l;
82 
83  if (strlen(s) == 0)
84  return n;
85 
86  switch (*s) {
87  case 's':
88  case 'S':
89  return n;
90  break;
91  case 'm':
92  case 'M':
93  return 60 * n;
94  break;
95  case 'h':
96  case 'H':
97  return 3600 * n;
98  break;
99  case 'd':
100  case 'D':
101  return 86400 * n;
102  break;
103  }
104  return 3600;
105 }
106 #endif
107 
108 /* ****************************************************************************
109  * *
110  * *
111  ******************************************************************************/
112 char *
114  char *s;
115 {
116  char *p;
117  size_t sz = 0;
118 
119  if (s == NULL)
120  return NULL;
121 
122  sz = strlen(s) + 1;
123  p = malloc(sz);
124  if (p != NULL)
125  strlcpy(p, s, sz);
126  else
127  ZE_LogSysError("malloc(s)");
128 
129  return p;
130 }
131 
132 /* ****************************************************************************
133  * *
134  * *
135  ******************************************************************************/
136 void *
138  size_t sz;
139 {
140  void *p;
141  size_t xtra = (8 - sz % 8) % 8;
142 
143  p = malloc(sz + xtra);
144  if (p == NULL) {
145  ZE_LogSysError("malloc(%lu)", (unsigned long) (sz + xtra));
146  }
147 
148  return p;
149 }
150 
151 /* ****************************************************************************
152  * *
153  * *
154  ******************************************************************************/
155 char *
156 strtolower(char *s)
157 {
158  char *p;
159 
160  if (s == NULL)
161  return NULL;
162  for (p = s; *p != '\0'; p++)
163  *p = tolower(*p);
164  return s;
165 }
166 
167 /* ****************************************************************************
168  * *
169  * *
170  ******************************************************************************/
171 char *
172 strtoupper(char *s)
173 {
174  char *p;
175 
176  if (s == NULL)
177  return NULL;
178  for (p = s; *p != '\0'; p++)
179  *p = toupper(*p);
180  return s;
181 }
182 
183 /* ****************************************************************************
184  * *
185  * *
186  ******************************************************************************/
187 char *
188 strset(dst, c, len)
189  char *dst;
190  int c;
191  int len;
192 {
193  if (dst != NULL) {
194  memset(dst, (int) c, len);
195  dst[len] = '\0';
196  }
197  return dst;
198 }
199 
200 /* ****************************************************************************
201  * *
202  * *
203  ******************************************************************************/
204 void
205 strchknull(s, len)
206  char *s;
207  int len;
208 {
209  char *p = s;
210 
211  if (s == NULL)
212  return;
213 
214  while (len-- > 0) {
215  if (*p == '\0')
216  *p = ' ';
217  p++;
218  }
219 }
220 
221 /* ****************************************************************************
222  * *
223  * *
224  ******************************************************************************/
225 size_t
226 strclean(s, sz)
227  char *s;
228  size_t sz;
229 {
230  size_t nsz = 0;
231 
232  if (s != NULL) {
233  char *p, *q;
234  size_t i;
235 
236  p = q = s;
237  for (i = 0; i < sz; i++, p++) {
238  switch (*p) {
239  case '\0':
240  break;
241  default:
242  *q++ = *p;
243  nsz++;
244  break;
245  }
246  }
247  *q = 0;
248  }
249  return nsz;
250 }
251 
252 /* ****************************************************************************
253  * *
254  * *
255  ******************************************************************************/
256 char *
257 strnoblanks(s, size)
258  char *s;
259  size_t size;
260 {
261  char *p, *q;
262 
263  if (s == NULL)
264  return NULL;
265 
266  p = q = s;
267  while ((*p != '\0') && (size-- > 0)) {
268  if ((*p != ' ') && (*p != '\t'))
269  *q++ = *p;
270  p++;
271  }
272  *q = 0;
273 
274  return s;
275 }
276 
277 /* ****************************************************************************
278  * *
279  * *
280  ******************************************************************************/
281 char *
283  char *s;
284 {
285  char *p;
286  size_t n;
287 
288  if (s == NULL)
289  return NULL;
290 
291  for (n = strlen(s); n > 0; n--) {
292  p = s + n - 1;
293  if (strchr(" \t\r\n", *p) == NULL)
294  break;
295  *p = '\0';
296  }
297 
298  return s;
299 }
300 
301 /* ****************************************************************************
302  * *
303  * *
304  ******************************************************************************/
305 #if defined(REGCOMP_FLAGS)
306 #undef REGCOMP_FLAGS
307 #endif
308 
309 #define REGCOMP_FLAGS (REG_ICASE | REG_EXTENDED)
310 
311 bool
312 strexpr(s, expr, pi, pf, icase)
313  char *s;
314  char *expr;
315  long *pi;
316  long *pf;
317  bool icase;
318 {
319  regex_t re;
320  bool found = FALSE;
321  int rerror;
322  int flags;
323 
324  if ((s == NULL) || (expr == NULL))
325  return FALSE;
326 
327  flags = REG_EXTENDED | (icase ? REG_ICASE : 0);
328  if ((rerror = regcomp(&re, expr, flags)) == 0) {
329  regmatch_t pm;
330 
331  if (regexec(&re, s, 1, &pm, 0) == 0) {
332  if (pi != NULL)
333  *pi = pm.rm_so;
334  if (pf != NULL)
335  *pf = pm.rm_eo;
336  found = TRUE;
337  }
338  regfree(&re);
339  } else {
340  char s[256];
341 
342  if (regerror(rerror, &re, s, sizeof (s)) > 0)
343  ZE_LogMsgError(0, "regcomp(%s) error : %s", expr, s);
344  }
345 
346  return found;
347 }
348 
349 /* ****************************************************************************
350  * *
351  * *
352  ******************************************************************************/
353 void
354 center_string(dst, org, len)
355  char *dst;
356  char *org;
357  int len;
358 {
359  int i;
360  char *p;
361 
362  memset(dst, 0, len);
363  i = (len - strlen(org)) / 2;
364  for (p = dst; i > 0; i--)
365  *p++ = ' ';
366  strcat(dst, org);
367 }
368 
369 /* ****************************************************************************
370  * *
371  * *
372  ******************************************************************************/
373 int
375  char *a;
376  char *b;
377  char *c;
378 {
379  int r = 0;
380 
381  if (a)
382  r++;
383  if (b)
384  r++;
385  if (c)
386  r++;
387  return r;
388 }
389 
390 /* ****************************************************************************
391  * *
392  * *
393  ******************************************************************************/
394 int
395 str2tokens(s, sz, argv, sep)
396  char *s;
397  int sz;
398  char **argv;
399  char *sep;
400 {
401  int i;
402  char *p, *ptr;
403 
404  if (s == NULL || argv == NULL || sz == 0)
405  return 0;
406 
407  sep = STRNULL(sep, ":,");
408 
409  for (i = 0; i < sz; i++)
410  argv[i] = NULL;
411  for (p = strtok_r(s, sep, &ptr), i = 0;
412  p != NULL && i < sz - 1; p = strtok_r(NULL, sep, &ptr), i++) {
413  argv[i] = p;
414  }
415  argv[i] = NULL;
416 
417  return i;
418 }
419 
420 /* ****************************************************************************
421  * *
422  * *
423  ******************************************************************************/
424 char *
425 j_basename(out, in, size)
426  char *out;
427  char *in;
428  size_t size;
429 {
430  char *p, *t;
431 
432  if (in == NULL || out == NULL)
433  return NULL;
434 
435  if ((t = strdup(in)) == NULL)
436  return NULL;
437 
438  if ((p = strrchr(t, '/')) != NULL && *(p + 1) == '\0')
439  *p = '\0';
440 
441  if ((p = strrchr(t, '/')) != NULL) {
442  p++;
443  } else
444  p = t;
445 
446  strlcpy(out, p, size);
447  FREE(t);
448  return out;
449 }
450 
451 
452 /* ****************************************************************************
453  * *
454  * *
455  ******************************************************************************/
456 static int
457 ssp_flock(fd, cmd, type)
458  int fd;
459  int cmd;
460  short type;
461 {
462  flock_t lock;
463 
464  memset(&lock, 0, sizeof (lock));
465  lock.l_type = type;
466  lock.l_whence = SEEK_SET;
467  lock.l_start = 0;
468  lock.l_len = 0;
469 
470  return fcntl(fd, cmd, &lock);
471 }
472 
473 bool
475  int fd;
476 {
477  if (ssp_flock(fd, F_SETLKW, F_WRLCK) < 0) {
478  ZE_LogSysError("lock error");
479  /*
480  * exit (EX_SOFTWARE);
481  */
482  return FALSE;
483  }
484  return TRUE;
485 }
486 
487 bool
489  int fd;
490 {
491  if (ssp_flock(fd, F_SETLK, F_UNLCK) < 0) {
492  ZE_LogSysError("lock error");
493  /*
494  * exit (EX_SOFTWARE);
495  */
496  return FALSE;
497  }
498  return TRUE;
499 }
500 
501 /* ****************************************************************************
502  * *
503  * *
504  ******************************************************************************/
505 size_t
507  char *fname;
508 {
509  struct stat fstat;
510 
511  if (fname == NULL)
512  return 0;
513 
514  if (stat(fname, &fstat) == 0)
515  return fstat.st_size;
516 
517 #if 0
518  ZE_LogSysError("stat(%s) error", fname);
519 #endif
520 
521  return 0;
522 }
523 
524 /* ****************************************************************************
525  * *
526  * *
527  ******************************************************************************/
528 size_t
530  int fd;
531 {
532  struct stat st;
533 
534  if (fd < 0)
535  return 0;
536 
537  if (fstat(fd, &st) == 0)
538  return st.st_size;
539 
540  ZE_LogSysError("fstat error");
541 
542  return 0;
543 }
544 
545 /* ****************************************************************************
546  * *
547  * *
548  ******************************************************************************/
549 int
550 readln(fd, buf, size)
551  int fd;
552  char *buf;
553  size_t size;
554 {
555  char *p = buf;
556 
557  if (fd < 0)
558  return -1;
559 
560  *p = '\0';
561  while (size > 0) {
562  int n;
563 
564  n = read(fd, p, 1);
565  if (n == 0)
566  break;
567  if (n < 0) {
568  if (errno == EINTR)
569  continue;
570  ZE_LogSysError("read error");
571  break;
572  }
573 
574  if (*p == '\r')
575  continue;
576  if (*p == '\n')
577  break;
578  p++;
579  size--;
580  }
581  *p = '\0';
582  return strlen(buf);
583 }
584 
585 /* ****************************************************************************
586  * *
587  * *
588  ******************************************************************************/
589 bool
590 remove_dir(dirname)
591  char *dirname;
592 {
593  DIR *dir;
594  struct dirent *p;
595  struct stat st;
596  char fname[PATH_MAX];
597  bool r = TRUE;
598 
599  if ((dir = opendir(dirname)) != NULL) {
600  while (r && (p = readdir(dir)) != NULL) {
601  if ((strcmp(p->d_name, ".") == 0) || (strcmp(p->d_name, "..") == 0))
602  continue;
603  snprintf(fname, sizeof (fname), "%s/%s", dirname, p->d_name);
604  ZE_LogMsgInfo(9, "ENTRY : %s", fname);
605  if (stat(fname, &st) == 0) {
606  if (S_ISDIR(st.st_mode))
607  r = remove_dir(fname);
608  else
609  unlink(fname);
610  } else {
611  ZE_LogSysError("lstat(%s) ", fname);
612  r = FALSE;
613  }
614  }
615  closedir(dir);
616  } else {
617  ZE_LogSysError("opendir(%s) :", dirname);
618  r = FALSE;
619  }
620 
621  if (r && rmdir(dirname) != 0) {
622  ZE_LogSysError("rmdir(%s) :", dirname);
623  r = FALSE;
624  }
625 
626  return r;
627 }
628 
629 /* ****************************************************************************
630  * *
631  * *
632  ******************************************************************************/
633 bool
635  char *dir;
636 {
637  int r = 0;
638  struct stat buf;
639 
640  if ((r = stat(dir, &buf)) != 0) {
641  ZE_LogSysError("stat(%s) error", dir);
642  return FALSE;
643  }
644 
645  if (S_ISFIFO(buf.st_mode))
646  ZE_MessageInfo(0, "%s : FIFO", dir);
647 
648  if (S_ISCHR(buf.st_mode))
649  ZE_MessageInfo(0, "%s : CHR", dir);
650 
651  if (S_ISDIR(buf.st_mode))
652  ZE_MessageInfo(0, "%s : DIR", dir);
653 
654  if (S_ISBLK(buf.st_mode))
655  ZE_MessageInfo(0, "%s : BLK", dir);
656 
657 #if 0
658  if (S_ISSOCK(buf.st_mode))
659  ZE_MessageInfo(0, "%s : SOCK", dir);
660 #endif
661 
662  if (S_ISREG(buf.st_mode))
663  ZE_MessageInfo(0, "%s : REG", dir);
664 
665  ZE_MessageInfo(0, " mode : %4o", buf.st_mode);
666  ZE_MessageInfo(0, " uid : %4d", buf.st_uid);
667  ZE_MessageInfo(0, " gid : %4d", buf.st_gid);
668 
669  return TRUE;
670 }
671 
672 /* ****************************************************************************
673  * *
674  * *
675  ******************************************************************************/
676 
677 char *
679  char *path;
680 {
681  while (path != NULL && strlen(path) > 0) {
682  char *p;
683 
684  p = strchr(path, '/');
685  if (p == NULL)
686  return path;
687  path = ++p;
688  }
689 
690  return path;
691 }
692 
void * jmalloc(size_t sz)
Definition: ze-divers.c:137
int str2tokens(char *s, int sz, char **argv, char *sep)
Definition: ze-divers.c:395
size_t get_fd_size(int fd)
Definition: ze-divers.c:529
char * str_clear_trailing_blanks(char *s)
Definition: ze-divers.c:282
#define strrchr
Definition: ze-sys.h:219
#define FREE(x)
Definition: macros.h:37
bool remove_dir(char *dirname)
Definition: ze-divers.c:590
#define STRNULL(x, r)
Definition: macros.h:81
#define ZE_LogMsgInfo(level,...)
Definition: zeSyslog.h:110
#define FALSE
Definition: macros.h:160
#define strlcpy
Definition: zeString.h:32
#define ZE_LogMsgError(level,...)
Definition: zeSyslog.h:113
void center_string(char *dst, char *org, int len)
Definition: ze-divers.c:354
#define GET_BIT(p, i)
Definition: macros.h:168
size_t strclean(char *s, size_t sz)
Definition: ze-divers.c:226
char * jstrdup(char *s)
Definition: ze-divers.c:113
char * j_basename(char *out, char *in, size_t size)
Definition: ze-divers.c:425
char * strtolower(char *s)
Definition: ze-divers.c:156
#define strchr
Definition: ze-sys.h:218
char * path2filename(char *path)
Definition: ze-divers.c:678
bool strexpr(char *s, char *expr, long *pi, long *pf, bool icase)
Definition: ze-divers.c:312
#define ZE_MessageInfo(level,...)
Definition: zeSyslog.h:90
#define TRUE
Definition: macros.h:157
int count_uint32bits(uint32_t val)
Definition: ze-divers.c:33
bool file_unlock(int fd)
Definition: ze-divers.c:488
bool getdirinfo(char *dir)
Definition: ze-divers.c:634
#define ZE_LogSysError(...)
Definition: zeSyslog.h:129
size_t get_file_size(char *fname)
Definition: ze-divers.c:506
char * strnoblanks(char *s, size_t size)
Definition: ze-divers.c:257
int nb_valid_pointer(char *a, char *b, char *c)
Definition: ze-divers.c:374
char * strset(char *dst, int c, int len)
Definition: ze-divers.c:188
void strchknull(char *s, int len)
Definition: ze-divers.c:205
char * strtoupper(char *s)
Definition: ze-divers.c:172
long uint32_t
Definition: ze-sys.h:489
bool file_lock(int fd)
Definition: ze-divers.c:474
int readln(int fd, char *buf, size_t size)
Definition: ze-divers.c:550