Browse code

*** empty log message ***

Bogdan-Andrei Iancu authored on 11/02/2002 14:30:00
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,490 @@
1
+
2
+
3
+#include <stdlib.h>
4
+#include "dprint.h"
5
+#include "msg_parser.h"
6
+#include "ut.h"
7
+#include "mem/mem.h"
8
+
9
+
10
+enum{ START_TO, IN_NAME_ADDR, E_NAME_ADDR , IN_ADDR_SPEC, E_ADDR_SPEC
11
+	, IN_ADDR_SPEC_ONLY, S_PARA_NAME, PARA_NAME, S_EQUAL, S_PARA_VALUE
12
+	, TAG1, TAG2, TAG3, PARA_VALUE_TOKEN , PARA_VALUE_QUOTED, E_PARA_VALUE
13
+	, F_CR, F_LF, F_CRLF
14
+	};
15
+
16
+
17
+#define add_param( _param , _body ) \
18
+	do{\
19
+		if (!(_body)->param_lst)  (_body)->param_lst=(_param);\
20
+		else (_body)->last_param->next=(_param);\
21
+		(_body)->last_param =(_param);\
22
+		if ((_param)->type==TAG_PARAM)\
23
+			memcpy(&((_body)->tag_value),&((_param)->value),sizeof(str));\
24
+	}while(0);
25
+
26
+
27
+
28
+
29
+char* parse_to(char* buffer, char *end, struct to_body *to_b)
30
+{
31
+	struct to_param *param=0;
32
+	int status = START_TO;
33
+	int saved_status;
34
+	char  *tmp;
35
+
36
+	for( tmp=buffer; tmp<end; tmp++)
37
+	{
38
+		switch(*tmp)
39
+		{
40
+			case ' ':
41
+			case '\t':
42
+				switch (status)
43
+				{
44
+					case IN_ADDR_SPEC_ONLY:
45
+						to_b->body.len=tmp-to_b->body.s;
46
+						*tmp=0;
47
+						status = E_ADDR_SPEC;
48
+						break;
49
+					case E_ADDR_SPEC:
50
+						*tmp =0;
51
+						break;
52
+					case TAG3:
53
+						param->type=TAG_PARAM;
54
+					case PARA_NAME:
55
+					case TAG1:
56
+					case TAG2:
57
+						param->name.len = tmp-param->name.s;
58
+						*tmp=0;
59
+						status = S_EQUAL;
60
+						break;
61
+					case PARA_VALUE_TOKEN:
62
+						param->value.len = tmp-param->value.s;
63
+						*tmp=0;
64
+						status = E_PARA_VALUE;
65
+						add_param( param , to_b );
66
+						break;
67
+					case F_CRLF:
68
+					case F_LF:
69
+					case F_CR:
70
+						/*previous=crlf and now =' '*/
71
+						status=saved_status;
72
+						break;
73
+				}
74
+				break;
75
+			case '\n':
76
+				switch (status)
77
+				{
78
+					case IN_ADDR_SPEC_ONLY:
79
+						to_b->body.len=tmp-to_b->body.s;
80
+						*tmp=0;
81
+						status = E_ADDR_SPEC;
82
+						break;
83
+					case E_ADDR_SPEC:
84
+						*tmp =0;
85
+					case START_TO:
86
+					case E_NAME_ADDR:
87
+					case S_PARA_NAME:
88
+					case S_EQUAL:
89
+					case S_PARA_VALUE:
90
+					case E_PARA_VALUE:
91
+						saved_status=status;
92
+						status=F_LF;
93
+						break;
94
+					case TAG3:
95
+						param->type=TAG_PARAM;
96
+					case PARA_NAME:
97
+					case TAG1:
98
+					case TAG2:
99
+						param->name.len = tmp-param->name.s;
100
+						*tmp=0;
101
+						status = S_EQUAL;
102
+						break;
103
+					case PARA_VALUE_TOKEN:
104
+						param->value.len = tmp-param->value.s;
105
+						*tmp=0;
106
+						status = E_PARA_VALUE;
107
+						add_param( param , to_b );
108
+						break;
109
+					case F_CR:
110
+						status=F_CRLF;
111
+						break;
112
+					case F_CRLF:
113
+					case F_LF:
114
+						status=saved_status;
115
+						goto endofheader;
116
+					default:
117
+						LOG( L_ERR , "ERROR: parse_to : unexpected char [%c] "
118
+						"in status %d .\n",*tmp,status);
119
+				}
120
+				break;
121
+			case '\r':
122
+				switch (status)
123
+				{
124
+					case IN_ADDR_SPEC_ONLY:
125
+						to_b->body.len=tmp-to_b->body.s;
126
+						*tmp=0;
127
+						status = E_ADDR_SPEC;
128
+						break;
129
+					case E_ADDR_SPEC:
130
+						*tmp =0;
131
+					case START_TO:
132
+					case E_NAME_ADDR:
133
+					case S_PARA_NAME:
134
+					case S_EQUAL:
135
+					case S_PARA_VALUE:
136
+					case E_PARA_VALUE:
137
+						saved_status=status;
138
+						status=F_CR;
139
+						break;
140
+					case TAG3:
141
+						param->type=TAG_PARAM;
142
+					case PARA_NAME:
143
+					case TAG1:
144
+					case TAG2:
145
+						param->name.len = tmp-param->name.s;
146
+						*tmp=0;
147
+						status = S_EQUAL;
148
+						break;
149
+					case PARA_VALUE_TOKEN:
150
+						param->value.len = tmp-param->value.s;
151
+						*tmp=0;
152
+						status = E_PARA_VALUE;
153
+						add_param( param , to_b );
154
+						break;
155
+					case F_CRLF:
156
+					case F_CR:
157
+					case F_LF:
158
+						status=saved_status;
159
+						goto endofheader;
160
+					default:
161
+						LOG( L_ERR , "ERROR: parse_to : unexpected char [%c] "
162
+						"in status %d .\n",*tmp,status);
163
+						goto error;
164
+				}
165
+				break;
166
+			case '\\':
167
+				switch (status)
168
+				{
169
+					case IN_NAME_ADDR:
170
+					case PARA_VALUE_QUOTED:
171
+						switch (*(tmp+1))
172
+						{
173
+							case F_CR:
174
+							case F_LF:
175
+								break;
176
+							default:
177
+								tmp++;
178
+						}
179
+					default:
180
+						LOG( L_ERR , "ERROR: parse_to : unexpected char [%c] "
181
+						"in status %d .\n",*tmp,status);
182
+						goto error;
183
+				}
184
+				break;
185
+			case '<':
186
+				switch (status)
187
+				{
188
+					case START_TO:
189
+					case E_NAME_ADDR:
190
+						if (!to_b->body.s) to_b->body.s=tmp;
191
+						status = IN_ADDR_SPEC;
192
+						break;
193
+					case IN_NAME_ADDR:
194
+						break;
195
+					case F_CRLF:
196
+					case F_LF:
197
+					case F_CR:
198
+						/*previous=crlf and now !=' '*/
199
+						goto endofheader;
200
+					default:
201
+						LOG( L_ERR , "ERROR: parse_to : unexpected char [%c] "
202
+						"in status %d .\n",*tmp,status);
203
+						goto error;
204
+				}
205
+				break;
206
+			case '>':
207
+				switch (status)
208
+				{
209
+					case IN_ADDR_SPEC:
210
+						to_b->body.len=tmp-to_b->body.s;
211
+						status = E_ADDR_SPEC;
212
+						break;
213
+					case IN_NAME_ADDR:
214
+						break;
215
+					case F_CRLF:
216
+					case F_LF:
217
+					case F_CR:
218
+						/*previous=crlf and now !=' '*/
219
+						goto endofheader;
220
+					default:
221
+						LOG( L_ERR , "ERROR: parse_to : unexpected char [%c] "
222
+						"in status %d .\n",*tmp,status);
223
+						goto error;
224
+				}
225
+				break;
226
+			case '"':
227
+				switch (status)
228
+				{
229
+					case START_TO:
230
+						to_b->body.s=tmp;
231
+						status = IN_NAME_ADDR;
232
+						break;
233
+					case IN_NAME_ADDR:
234
+						status = E_NAME_ADDR;
235
+						break;
236
+					case S_PARA_VALUE:
237
+						param->value.s = tmp+1;
238
+						status = PARA_VALUE_QUOTED;
239
+						break;
240
+					case PARA_VALUE_QUOTED:
241
+						param->value.len=tmp-param->value.s-1 ;
242
+						*tmp = 0;
243
+						add_param( param , to_b );
244
+						status = E_PARA_VALUE;
245
+						break;
246
+					case F_CRLF:
247
+					case F_LF:
248
+					case F_CR:
249
+						/*previous=crlf and now !=' '*/
250
+						goto endofheader;
251
+					default:
252
+						LOG( L_ERR , "ERROR: parse_to : unexpected char [%c] "
253
+						"in status %d .\n",*tmp,status);
254
+						goto error;
255
+				}
256
+				break;
257
+			case ';' :
258
+				switch (status)
259
+				{
260
+					case IN_NAME_ADDR:
261
+					case PARA_VALUE_QUOTED:
262
+						break;
263
+					case IN_ADDR_SPEC_ONLY:
264
+						to_b->body.len=tmp-to_b->body.s;
265
+						*tmp=0;
266
+					case E_ADDR_SPEC:
267
+					case E_PARA_VALUE:
268
+						param = (struct to_param*)pkg_malloc(sizeof(struct to_param));
269
+						if (!param){
270
+							LOG( L_ERR , "ERROR: parse_to - out of memory\n" );
271
+							goto error;
272
+						}
273
+						memset(param,0,sizeof(struct to_param));
274
+						param->type=GENERAL_PARAM;
275
+						status = S_PARA_NAME;
276
+						break;
277
+					case F_CRLF:
278
+					case F_LF:
279
+					case F_CR:
280
+						/*previous=crlf and now !=' '*/
281
+						goto endofheader;
282
+					default:
283
+						LOG( L_ERR , "ERROR: parse_to : unexpected char [%c] "
284
+						"in status %d .\n",*tmp,status);
285
+						goto error;
286
+				}
287
+				break;
288
+			case 'T':
289
+			case 't' :
290
+				switch (status)
291
+				{
292
+					case START_TO:
293
+						to_b->body.s=tmp;
294
+						status = IN_ADDR_SPEC_ONLY;
295
+						break;
296
+					case IN_NAME_ADDR:
297
+					case PARA_VALUE_QUOTED:
298
+					case PARA_VALUE_TOKEN:
299
+					case IN_ADDR_SPEC:
300
+					case IN_ADDR_SPEC_ONLY:
301
+					case PARA_NAME:
302
+						break;
303
+					case S_PARA_NAME:
304
+						param->name.s = tmp;
305
+						status = TAG1;
306
+						break;
307
+					case S_PARA_VALUE:
308
+						param->value.s = tmp;
309
+						status = PARA_VALUE_TOKEN;
310
+						break;
311
+					case TAG1:
312
+					case TAG2:
313
+					case TAG3:
314
+						status = PARA_NAME;
315
+						break;
316
+					case F_CRLF:
317
+					case F_LF:
318
+					case F_CR:
319
+						/*previous=crlf and now !=' '*/
320
+						goto endofheader;
321
+					default:
322
+						LOG( L_ERR , "ERROR: parse_to : unexpected char [%c] "
323
+						"in status %d .\n",*tmp,status);
324
+						goto error;
325
+				}
326
+				break;
327
+			case 'A':
328
+			case 'a' :
329
+				switch (status)
330
+				{
331
+					case START_TO:
332
+						to_b->body.s=tmp;
333
+						status = IN_ADDR_SPEC_ONLY;
334
+						break;
335
+					case IN_NAME_ADDR:
336
+					case PARA_VALUE_QUOTED:
337
+					case PARA_VALUE_TOKEN:
338
+					case IN_ADDR_SPEC:
339
+					case IN_ADDR_SPEC_ONLY:
340
+					case PARA_NAME:
341
+						break;
342
+					case S_PARA_NAME:
343
+						param->name.s = tmp;
344
+						status = PARA_NAME;
345
+						break;
346
+					case S_PARA_VALUE:
347
+						param->value.s = tmp;
348
+						status = PARA_VALUE_TOKEN;
349
+						break;
350
+					case TAG1:
351
+						status = TAG2;
352
+						break;
353
+					case TAG2:
354
+					case TAG3:
355
+						status = PARA_NAME;
356
+						break;
357
+					case F_CRLF:
358
+					case F_LF:
359
+					case F_CR:
360
+						/*previous=crlf and now !=' '*/
361
+						goto endofheader;
362
+					default:
363
+						LOG( L_ERR , "ERROR: parse_to : unexpected char [%c] "
364
+						"in status %d .\n",*tmp,status);
365
+						goto error;
366
+				}
367
+				break;
368
+			case 'G':
369
+			case 'g' :
370
+				switch (status)
371
+				{
372
+					case START_TO:
373
+						to_b->body.s=tmp;
374
+						status = IN_ADDR_SPEC_ONLY;
375
+						break;
376
+					case IN_NAME_ADDR:
377
+					case PARA_VALUE_QUOTED:
378
+					case PARA_VALUE_TOKEN:
379
+					case IN_ADDR_SPEC:
380
+					case IN_ADDR_SPEC_ONLY:
381
+					case PARA_NAME:
382
+						break;
383
+					case S_PARA_NAME:
384
+						param->name.s = tmp;
385
+						status = PARA_NAME;
386
+						break;
387
+					case S_PARA_VALUE:
388
+						param->value.s = tmp;
389
+						status = PARA_VALUE_TOKEN;
390
+						break;
391
+					case TAG1:
392
+					case TAG3:
393
+						status = PARA_NAME;
394
+						break;
395
+					case TAG2:
396
+						status = TAG3;
397
+						break;
398
+					case F_CRLF:
399
+					case F_LF:
400
+					case F_CR:
401
+						/*previous=crlf and now !=' '*/
402
+						goto endofheader;
403
+					default:
404
+						LOG( L_ERR , "ERROR: parse_to : unexpected char [%c] "
405
+						"in status %d .\n",*tmp,status);
406
+						goto error;
407
+				}
408
+				break;
409
+			case '=':
410
+				switch (status)
411
+				{
412
+					case IN_NAME_ADDR:
413
+					case PARA_VALUE_QUOTED:
414
+						break;
415
+					case TAG3:
416
+						param->type=TAG_PARAM;
417
+					case PARA_NAME:
418
+					case TAG1:
419
+					case TAG2:
420
+						param->name.len = tmp-param->name.s;
421
+						*tmp=0;
422
+						status = S_PARA_VALUE;
423
+						break;
424
+					case S_EQUAL:
425
+						status = S_PARA_VALUE;
426
+						break;
427
+					default:
428
+						LOG( L_ERR , "ERROR: parse_to : unexpected char [%c] "
429
+						"in status %d .\n",*tmp,status);
430
+						goto error;
431
+				}
432
+				break;
433
+			default:
434
+				switch (status)
435
+				{
436
+					case START_TO:
437
+						to_b->body.s=tmp;
438
+						status = IN_ADDR_SPEC_ONLY;
439
+						break;
440
+					case PARA_VALUE_TOKEN:
441
+					case PARA_NAME:
442
+					case IN_ADDR_SPEC:
443
+					case IN_ADDR_SPEC_ONLY:
444
+					case IN_NAME_ADDR:
445
+					case PARA_VALUE_QUOTED:
446
+						break;
447
+					case S_PARA_NAME:
448
+						param->name.s = tmp;
449
+						status = PARA_NAME;
450
+						break;
451
+					case S_PARA_VALUE:
452
+						param->value.s = tmp;
453
+						status = PARA_VALUE_TOKEN;
454
+						break;
455
+					case F_CRLF:
456
+					case F_LF:
457
+					case F_CR:
458
+						/*previous=crlf and now !=' '*/
459
+						goto endofheader;
460
+					default:
461
+						DBG("DEBUG: parse_to: spitting out [%c] in status %d\n",
462
+						*tmp,status );
463
+						goto error;
464
+				}
465
+		}/*char switch*/
466
+	}/*for*/
467
+
468
+endofheader:
469
+	status=saved_status;
470
+	DBG("end of header reached, state=%d\n", status);
471
+	/* check if error*/
472
+	switch(status){
473
+		case E_ADDR_SPEC:
474
+		case E_PARA_VALUE:
475
+			break;
476
+		default:
477
+			LOG(L_ERR, "ERROR: parse_to: invalid To - end of header in"
478
+					" state %d\n", status);
479
+			goto error;
480
+	}
481
+	return tmp;
482
+
483
+error:
484
+	LOG(L_ERR, "to parse error\n");
485
+	if (param) pkg_free(param);
486
+	to_b->error=PARSE_ERROR;
487
+	return tmp;
488
+
489
+}
490
+