ze-filter  (ze-filter-0.8.0-develop-180218)
ze-rfc2822.c
Go to the documentation of this file.
1 /*
2  *
3  * ze-filter - Mail Server Filter for sendmail
4  *
5  * Copyright (c) 2001-2018 - Jose-Marcio Martins da Cruz
6  *
7  * Auteur : Jose Marcio Martins da Cruz
8  * jose.marcio.mc@gmail.org
9  *
10  * Historique :
11  * Creation : Sun Apr 9 21:47:44 CEST 2006
12  *
13  * This program is free software, but with restricted license :
14  *
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19  *
20  * More details about ze-filter license can be found at ze-filter
21  * web site : http://foss.jose-marcio.org
22  */
23 
24 
25 #include <ze-sys.h>
26 #include <ze-libjc.h>
27 #include <ze-rfc2822.h>
28 
29 /* ****************************************************************************
30  * *
31  * *
32  **************************************************************************** */
33 #define LINESZ 0x4000
34 
35 #define str_clear_right_spaces(s) (s)
36 
37 #define APPEND_HEADER(head, hdr) \
38  do { \
39  if ((head) == NULL) { \
40  (head) = (hdr); \
41  } else { \
42  rfc2822_hdr_T *p = (head); \
43  while (p->next != NULL) \
44  p = p->next; \
45  p->next = (hdr); \
46  } \
47  } while (0) \
48 
49 #define LOG_HEADER(h) \
50  { \
51  ZE_MessageInfo(15, "hdr->key : %s", h->key); \
52  ZE_MessageInfo(15, "hdr->value : %s", h->value); \
53  ZE_MessageInfo(15, "------------"); \
54  }
55 
56 static rfc2822_hdr_T *line2header(char *line);
57 static char *append2line(char *line, char *str);
58 
59 /* ****************************************************************************
60  * *
61  * *
62  **************************************************************************** */
64 rfc2822_get_headers(buf, size, nptr)
65  char *buf;
66  size_t size;
67  char **nptr;
68 {
69  char *p = NULL;
70  char line[LINESZ];
71  rfc2822_hdr_T *hdr = NULL, *head = NULL;
72 
73  char *cline = NULL;
74 
75  ASSERT(buf != NULL);
76 
77  p = buf;
78 
79  while (*p != '\0')
80  {
81  char *ps;
82 
83  ps = p;
84  p = buf_get_next_line(line, p, LINESZ);
85 
86  (void) str_clear_right_spaces(line);
87 
88  /* end of headers */
89  if (strlen(line) == 0)
90  break;
91 
92  if (strspn(line, " \t") == 0)
93  {
94  /* New header */
95  if (cline != NULL)
96  {
97  ZE_MessageInfo(15, "LINE : %s", cline);
98 
99  hdr = line2header(cline);
100  APPEND_HEADER(head, hdr);
101  LOG_HEADER(hdr);
102  cline = NULL;
103  }
104 
105  if (strchr(line, ':') == NULL)
106  {
107  p = ps;
108  break;
109  }
110 
111  cline = append2line(cline, line);
112 
113  } else
114  {
115  /* continuation line */
116  if (cline == NULL)
117  {
118  /* error : continuation line without previous line */
119  }
120  cline = append2line(cline, line);
121  }
122  }
123 
124  if (cline != NULL)
125  {
126  ZE_MessageInfo(15, "LINE : %s", cline);
127  hdr = line2header(cline);
128  APPEND_HEADER(head, hdr);
129  LOG_HEADER(hdr);
130  }
131  ZE_MessageInfo(15, "***FIN***");
132 
133 fin:
134  if (nptr != NULL)
135  *nptr = p;
136 
137  return head;
138 }
139 
140 /* ****************************************************************************
141  * *
142  * *
143  **************************************************************************** */
146  rfc2822_hdr_T *head;
147  char *key;
148 {
149  while (head != NULL)
150  {
151  if (strcasecmp(head->key, key) == 0)
152  return head;
153  head = head->next;
154  }
155 
156  return NULL;
157 }
158 
159 /* ****************************************************************************
160  * *
161  * *
162  **************************************************************************** */
163 char *
165  rfc2822_hdr_T *header;
166 {
167  if (header == NULL)
168  return NULL;
169 
170  return header->value;
171 }
172 
173 /* ****************************************************************************
174  * *
175  * *
176  **************************************************************************** */
177 char *
179  rfc2822_hdr_T *header;
180 {
181  char *p = NULL;
182  size_t n;
183 
184  if (header == NULL || header->value == NULL)
185  return NULL;
186 
187  n = strcspn(header->value, "; \t");
188  if ((p = malloc(n + 1)) != NULL)
189  zeSafeStrnCpy(p, n + 1, header->value, n);
190  else
191  ZE_LogSysError("malloc error");
192 
193  return p;
194 }
195 
196 /* ****************************************************************************
197  * *
198  * *
199  **************************************************************************** */
200 char *
201 rfc2822_get_attr(head, attr)
202  rfc2822_hdr_T *head;
203  char *attr;
204 {
205  long pi, pf;
206  char *str;
207  char *value = NULL;
208 
209  if (head == NULL || head->value == NULL || attr == NULL)
210  return NULL;
211 
212  str = head->value;
213  if (zeStrRegex(str, attr, &pi, &pf, TRUE))
214  {
215  char *s = str + pf;
216  bool quoted = FALSE;
217  int n;
218 
219  if (*s == '"' || *s == '\'')
220  {
221  s++;
222  quoted = TRUE;
223  }
224  if (quoted)
225  n = strcspn(s, "\"\'");
226  else
227  n = strcspn(s, "<>@,;:\\/[]?=\"" " \t");
228 
229  value = malloc(n + 1);
230  zeSafeStrnCpy(value, n + 1, s, n);
231 
232  ZE_MessageInfo(15, " -> %s : %s", attr, value);
233  }
234 
235  return value;
236 }
237 
238 /* ****************************************************************************
239  * *
240  * *
241  **************************************************************************** */
242 static char *
243 get_attr_from_header(hdr, key)
244  rfc2822_hdr_T *hdr;
245  char *key;
246 {
247 
248  return NULL;
249 }
250 
251 /* ****************************************************************************
252  * *
253  * *
254  **************************************************************************** */
255 
256 static char *
257 append2line(line, str)
258  char *line;
259  char *str;
260 {
261  char *p = NULL;
262  size_t sz = 0;
263 
264  if (line == NULL)
265  {
266  if ((p = strdup(str)) == NULL)
267  ZE_LogSysError("strdup(%s) error", str);
268  return p;
269  }
270 
271  sz = strlen(line) + strlen(str) + 1;
272  p = realloc(line, sz);
273  if (p != NULL)
274  {
275  /* shall check value returned by strlcat ???
276  ** Does it matter ???
277  */
278  line = p;
279  (void) strlcat(line, str, sz);
280  }
281  return p;
282 }
283 
284 /* ****************************************************************************
285  * *
286  * *
287  **************************************************************************** */
288 static rfc2822_hdr_T *
289 line2header(line)
290  char *line;
291 {
292  rfc2822_hdr_T *p = NULL;
293  char *c = NULL;
294 
295  p = malloc(sizeof (rfc2822_hdr_T));
296  if (p == NULL)
297  goto fin;
298 
299  memset(p, 0, sizeof (rfc2822_hdr_T));
300  p->line = line;
301  if ((c = strchr(line, ':')) != NULL)
302  *c++ = '\0';
303  p->key = line;
304  if (c != NULL)
305  c += strspn(c, " \t");
306  p->value = c;
307 #if 0
308  if (p->value != NULL)
309  zeStr2Lower(p->value);
310 #endif
311 fin:
312  return p;
313 }
#define str_clear_right_spaces(s)
Definition: ze-rfc2822.c:35
#define LINESZ
Definition: ze-rfc2822.c:33
char * rfc2822_get_main_attr(rfc2822_hdr_T *header)
Definition: ze-rfc2822.c:178
#define ASSERT(a)
Definition: macros.h:27
char * key
Definition: ze-rfc2822.h:37
rfc2822_hdr_T * next
Definition: ze-rfc2822.h:39
char * value
Definition: ze-rfc2822.h:38
#define LOG_HEADER(h)
Definition: ze-rfc2822.c:49
#define FALSE
Definition: macros.h:160
bool zeStrRegex(char *, char *, long *, long *, bool)
Definition: zeStrings.c:544
#define strlcat
Definition: zeString.h:28
#define strchr
Definition: ze-sys.h:218
char * line
Definition: ze-rfc2822.h:36
#define ZE_MessageInfo(level,...)
Definition: zeSyslog.h:90
int zeSafeStrnCpy(char *, size_t, char *, size_t)
Definition: zeStrings.c:136
#define TRUE
Definition: macros.h:157
#define ZE_LogSysError(...)
Definition: zeSyslog.h:129
#define APPEND_HEADER(head, hdr)
Definition: ze-rfc2822.c:37
char * buf_get_next_line(char *, char *, size_t)
Definition: ze-buffer.c:230
char * zeStr2Lower(char *)
Definition: zeStrings.c:295
char * rfc2822_get_value(rfc2822_hdr_T *header)
Definition: ze-rfc2822.c:164
rfc2822_hdr_T * rfc2822_get_headers(char *buf, size_t size, char **nptr)
Definition: ze-rfc2822.c:64
char * rfc2822_get_attr(rfc2822_hdr_T *head, char *attr)
Definition: ze-rfc2822.c:201
rfc2822_hdr_T * rfc2822_lookup_header(rfc2822_hdr_T *head, char *key)
Definition: ze-rfc2822.c:145