GPLization banner introduced to *.[hc] files
[sip-router] / parser / parse_to.c
1 /*
2  * $Id$
3  *
4  * Copyright (C) 2001-2003 Fhg Fokus
5  *
6  * This file is part of ser, a free SIP server.
7  *
8  * ser is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version
12  *
13  * For a license to use the ser software under conditions
14  * other than those described here, or to purchase support for this
15  * software, please contact iptel.org by e-mail at the following addresses:
16  *    info@iptel.org
17  *
18  * ser is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License 
24  * along with this program; if not, write to the Free Software 
25  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26  */
27
28
29 #include "parse_to.h"
30 #include <stdlib.h>
31 #include <string.h>
32 #include "../dprint.h"
33 #include "msg_parser.h"
34 #include "../ut.h"
35 #include "../mem/mem.h"
36
37 enum {
38         TAG_PARAM = 400, GENERAL_PARAM
39 };
40
41
42 enum { 
43         START_TO, DISPLAY_QUOTED, E_DISPLAY_QUOTED, DISPLAY_TOKEN, 
44         S_URI_ENCLOSED, URI_ENCLOSED, E_URI_ENCLOSED, 
45         URI_OR_TOKEN, MAYBE_URI_END, END, F_CR, F_LF, F_CRLF
46 };
47
48
49 enum { 
50         S_PARA_NAME=20, PARA_NAME, S_EQUAL, S_PARA_VALUE, TAG1, TAG2, 
51         TAG3, PARA_VALUE_TOKEN , PARA_VALUE_QUOTED, E_PARA_VALUE, PARA_START
52 };
53
54
55
56 #define add_param( _param , _body ) \
57         do{\
58                 DBG("DEBUG: add_param: %.*s=%.*s\n",param->name.len,param->name.s,\
59                         param->value.len,param->value.s);\
60                 if (!(_body)->param_lst)  (_body)->param_lst=(_param);\
61                 else (_body)->last_param->next=(_param);\
62                 (_body)->last_param =(_param);\
63                 if ((_param)->type==TAG_PARAM)\
64                         memcpy(&((_body)->tag_value),&((_param)->value),sizeof(str));\
65         }while(0);
66
67
68
69
70
71 static /*inline*/ char* parse_to_param(char *buffer, char *end,
72                                         struct to_body *to_b,
73                                         int *returned_status)
74 {
75         struct to_param *param;
76         int status;
77         int saved_status;
78         char  *tmp;
79
80         param=0;
81         status=PARA_START;
82         saved_status=PARA_START;
83
84         for( tmp=buffer; tmp<end; tmp++)
85         {
86                 switch(*tmp)
87                 {
88                         case ' ':
89                         case '\t':
90                                 switch (status)
91                                 {
92                                         case TAG3:
93                                                 param->type=TAG_PARAM;
94                                         case PARA_NAME:
95                                         case TAG1:
96                                         case TAG2:
97                                                 param->name.len = tmp-param->name.s;
98                                                 *tmp=0;
99                                                 status = S_EQUAL;
100                                                 break;
101                                         case PARA_VALUE_TOKEN:
102                                                 param->value.len = tmp-param->value.s;
103                                                 *tmp=0;
104                                                 status = E_PARA_VALUE;
105                                                 add_param( param , to_b );
106                                                 break;
107                                         case F_CRLF:
108                                         case F_LF:
109                                         case F_CR:
110                                                 /*previous=crlf and now =' '*/
111                                                 status=saved_status;
112                                                 break;
113                                 }
114                                 break;
115                         case '\n':
116                                 switch (status)
117                                 {
118                                         case S_PARA_NAME:
119                                         case S_EQUAL:
120                                         case S_PARA_VALUE:
121                                         case E_PARA_VALUE:
122                                                 saved_status=status;
123                                                 status=F_LF;
124                                                 break;
125                                         case TAG3:
126                                                 param->type=TAG_PARAM;
127                                         case PARA_NAME:
128                                         case TAG1:
129                                         case TAG2:
130                                                 param->name.len = tmp-param->name.s;
131                                                 *tmp=0;
132                                                 saved_status = S_EQUAL;
133                                                 status = F_LF;
134                                                 break;
135                                         case PARA_VALUE_TOKEN:
136                                                 param->value.len = tmp-param->value.s;
137                                                 *tmp=0;
138                                                 saved_status = E_PARA_VALUE;
139                                                 status = F_LF;
140                                                 add_param( param , to_b );
141                                                 break;
142                                         case F_CR:
143                                                 status=F_CRLF;
144                                                 break;
145                                         case F_CRLF:
146                                         case F_LF:
147                                                 status=saved_status;
148                                                 goto endofheader;
149                                         default:
150                                                 LOG( L_ERR , "ERROR: parse_to_param : "
151                                                         "unexpected char [%c] in status %d: <<%.*s>> .\n",
152                                                         *tmp,status, tmp-buffer, buffer);
153                                 }
154                                 break;
155                         case '\r':
156                                 switch (status)
157                                 {
158                                         case S_PARA_NAME:
159                                         case S_EQUAL:
160                                         case S_PARA_VALUE:
161                                         case E_PARA_VALUE:
162                                                 saved_status=status;
163                                                 status=F_CR;
164                                                 break;
165                                         case TAG3:
166                                                 param->type=TAG_PARAM;
167                                         case PARA_NAME:
168                                         case TAG1:
169                                         case TAG2:
170                                                 param->name.len = tmp-param->name.s;
171                                                 *tmp=0;
172                                                 saved_status = S_EQUAL;
173                                                 status = F_CR;
174                                                 break;
175                                         case PARA_VALUE_TOKEN:
176                                                 param->value.len = tmp-param->value.s;
177                                                 *tmp=0;
178                                                 saved_status = E_PARA_VALUE;
179                                                 status = F_CR;
180                                                 add_param( param , to_b );
181                                                 break;
182                                         case F_CRLF:
183                                         case F_CR:
184                                         case F_LF:
185                                                 status=saved_status;
186                                                 goto endofheader;
187                                         default:
188                                                 LOG( L_ERR , "ERROR: parse_to_param : "
189                                                         "unexpected char [%c] in status %d: <<%.*s>> .\n",
190                                                         *tmp,status, tmp-buffer, buffer);
191                                                 goto error;
192                                 }
193                                 break;
194                         case '\\':
195                                 switch (status)
196                                 {
197                                         case PARA_VALUE_QUOTED:
198                                                 switch (*(tmp+1))
199                                                 {
200                                                         case '\r':
201                                                         case '\n':
202                                                                 break;
203                                                         default:
204                                                                 tmp++;
205                                                 }
206                                         default:
207                                                 LOG( L_ERR , "ERROR: parse_to_param : "
208                                                         "unexpected char [%c] in status %d: <<%.*s>> .\n",
209                                                         *tmp,status, tmp-buffer, buffer);
210                                                 goto error;
211                                 }
212                                 break;
213                         case '"':
214                                 switch (status)
215                                 {
216                                         case S_PARA_VALUE:
217                                                 param->value.s = tmp+1;
218                                                 status = PARA_VALUE_QUOTED;
219                                                 break;
220                                         case PARA_VALUE_QUOTED:
221                                                 param->value.len=tmp-param->value.s-1 ;
222                                                 *tmp = 0;
223                                                 add_param( param , to_b );
224                                                 status = E_PARA_VALUE;
225                                                 break;
226                                         case F_CRLF:
227                                         case F_LF:
228                                         case F_CR:
229                                                 /*previous=crlf and now !=' '*/
230                                                 goto endofheader;
231                                         default:
232                                                 LOG( L_ERR , "ERROR: parse_to_param :"
233                                                         "unexpected char [%c] in status %d: <<%.*s>> .\n",
234                                                         *tmp,status, tmp-buffer, buffer);
235                                                 goto error;
236                                 }
237                                 break;
238                         case ';' :
239                                 switch (status)
240                                 {
241                                         case PARA_VALUE_QUOTED:
242                                                 break;
243 #ifndef NO_PINGTEL_TAG_HACK
244                                         case TAG3:
245                                                 param->type = TAG_PARAM;
246                                                 param->name.len = 3;
247                                         case S_EQUAL:
248                                         case S_PARA_VALUE:
249                                                 if (param->type==TAG_PARAM)
250                                                         param->value.s = tmp;
251                                                 else {
252                                                         LOG( L_ERR , "ERROR: parse_to_param : unexpected "
253                                                                 "char [%c] in status %d: <<%.*s>> .\n",
254                                                                 *tmp,status, tmp-buffer, buffer);
255                                                         goto error;
256                                                 }
257 #endif
258                                         case PARA_VALUE_TOKEN:
259                                                 param->value.len=tmp-param->value.s;
260                                                 add_param(param,to_b);
261                                         case PARA_START:
262                                                 *tmp=0;
263                                         case E_PARA_VALUE:
264                                                 param = (struct to_param*)
265                                                         pkg_malloc(sizeof(struct to_param));
266                                                 if (!param){
267                                                         LOG( L_ERR , "ERROR: parse_to_param"
268                                                         " - out of memory\n" );
269                                                         goto error;
270                                                 }
271                                                 memset(param,0,sizeof(struct to_param));
272                                                 param->type=GENERAL_PARAM;
273                                                 status = S_PARA_NAME;
274                                                 break;
275                                         case F_CRLF:
276                                         case F_LF:
277                                         case F_CR:
278                                                 /*previous=crlf and now !=' '*/
279                                                 goto endofheader;
280                                         default:
281                                                 LOG( L_ERR , "ERROR: parse_to_param :"
282                                                         "unexpected char [%c] in status %d: <<%.*s>> .\n",
283                                                         *tmp,status, tmp-buffer, buffer);
284                                                 goto error;
285                                 }
286                                 break;
287                         case 'T':
288                         case 't' :
289                                 switch (status)
290                                 {
291                                         case PARA_VALUE_QUOTED:
292                                         case PARA_VALUE_TOKEN:
293                                         case PARA_NAME:
294                                                 break;
295                                         case S_PARA_NAME:
296                                                 param->name.s = tmp;
297                                                 status = TAG1;
298                                                 break;
299                                         case S_PARA_VALUE:
300                                                 param->value.s = tmp;
301                                                 status = PARA_VALUE_TOKEN;
302                                                 break;
303                                         case TAG1:
304                                         case TAG2:
305                                         case TAG3:
306                                                 status = PARA_NAME;
307                                                 break;
308                                         case F_CRLF:
309                                         case F_LF:
310                                         case F_CR:
311                                                 /*previous=crlf and now !=' '*/
312                                                 goto endofheader;
313                                         default:
314                                                 LOG( L_ERR , "ERROR: parse_to_param :"
315                                                         "unexpected char [%c] in status %d: <<%.*s>> .\n",
316                                                         *tmp,status, tmp-buffer, buffer);
317                                                 goto error;
318                                 }
319                                 break;
320                         case 'A':
321                         case 'a' :
322                                 switch (status)
323                                 {
324                                         case PARA_VALUE_QUOTED:
325                                         case PARA_VALUE_TOKEN:
326                                         case PARA_NAME:
327                                                 break;
328                                         case S_PARA_NAME:
329                                                 param->name.s = tmp;
330                                                 status = PARA_NAME;
331                                                 break;
332                                         case S_PARA_VALUE:
333                                                 param->value.s = tmp;
334                                                 status = PARA_VALUE_TOKEN;
335                                                 break;
336                                         case TAG1:
337                                                 status = TAG2;
338                                                 break;
339                                         case TAG2:
340                                         case TAG3:
341                                                 status = PARA_NAME;
342                                                 break;
343                                         case F_CRLF:
344                                         case F_LF:
345                                         case F_CR:
346                                                 /*previous=crlf and now !=' '*/
347                                                 goto endofheader;
348                                         default:
349                                                 LOG( L_ERR , "ERROR: parse_to_param : "
350                                                         "unexpected char [%c] in status %d: <<%.*s>> .\n",
351                                                         *tmp,status, tmp-buffer, buffer);
352                                                 goto error;
353                                 }
354                                 break;
355                         case 'G':
356                         case 'g' :
357                                 switch (status)
358                                 {
359                                         case PARA_VALUE_QUOTED:
360                                         case PARA_VALUE_TOKEN:
361                                         case PARA_NAME:
362                                                 break;
363                                         case S_PARA_NAME:
364                                                 param->name.s = tmp;
365                                                 status = PARA_NAME;
366                                                 break;
367                                         case S_PARA_VALUE:
368                                                 param->value.s = tmp;
369                                                 status = PARA_VALUE_TOKEN;
370                                                 break;
371                                         case TAG1:
372                                         case TAG3:
373                                                 status = PARA_NAME;
374                                                 break;
375                                         case TAG2:
376                                                 status = TAG3;
377                                                 break;
378                                         case F_CRLF:
379                                         case F_LF:
380                                         case F_CR:
381                                                 /*previous=crlf and now !=' '*/
382                                                 goto endofheader;
383                                         default:
384                                                 LOG( L_ERR , "ERROR: parse_to_param : "
385                                                         "unexpected char [%c] in status %d: <<%.*s>> .\n",
386                                                         *tmp,status, tmp-buffer, buffer);
387                                                 goto error;
388                                 }
389                                 break;
390                         case '=':
391                                 switch (status)
392                                 {
393                                         case PARA_VALUE_QUOTED:
394                                                 break;
395                                         case TAG3:
396                                                 param->type=TAG_PARAM;
397                                         case PARA_NAME:
398                                         case TAG1:
399                                         case TAG2:
400                                                 param->name.len = tmp-param->name.s;
401                                                 *tmp=0;
402                                                 status = S_PARA_VALUE;
403                                                 break;
404                                         case S_EQUAL:
405                                                 status = S_PARA_VALUE;
406                                                 break;
407                                         case F_CRLF:
408                                         case F_LF:
409                                         case F_CR:
410                                                 /*previous=crlf and now !=' '*/
411                                                 goto endofheader;
412                                         default:
413                                                 LOG( L_ERR , "ERROR: parse_to_param : "
414                                                         "unexpected char [%c] in status %d: <<%.*s>> .\n",
415                                                         *tmp,status, tmp-buffer, buffer);
416                                                 goto error;
417                                 }
418                                 break;
419                         default:
420                                 switch (status)
421                                 {
422                                         case PARA_VALUE_TOKEN:
423                                         case PARA_NAME:
424                                         case PARA_VALUE_QUOTED:
425                                                 break;
426                                         case S_PARA_NAME:
427                                                 param->name.s = tmp;
428                                                 status = PARA_NAME;
429                                                 break;
430                                         case S_PARA_VALUE:
431                                                 param->value.s = tmp;
432                                                 status = PARA_VALUE_TOKEN;
433                                                 break;
434                                         case F_CRLF:
435                                         case F_LF:
436                                         case F_CR:
437                                                 /*previous=crlf and now !=' '*/
438                                                 goto endofheader;
439                                         default:
440                                                 DBG("DEBUG: parse_to_param: "
441                                                 "spitting out [%c] in status %d\n",*tmp,status );
442                                                 goto error;
443                                 }
444                 }/*switch*/
445         }/*for*/
446
447
448 endofheader:
449 #ifndef NO_PINGTEL_TAG_HACK
450         if (param->type==TAG_PARAM 
451         && (saved_status==S_EQUAL||saved_status==S_PARA_VALUE) ) {
452                         saved_status = E_PARA_VALUE;
453                         param->value.s=(char*)param->value.len=0;
454                         add_param(param, to_b);
455         }
456 #endif
457         *returned_status=saved_status;
458         return tmp;
459
460 error:
461         LOG(L_ERR, "to_param parse error\n");
462         if (param) pkg_free(param);
463         to_b->error=PARSE_ERROR;
464         return tmp;
465 }
466
467
468
469
470 char* parse_to(char* buffer, char *end, struct to_body *to_b)
471 {
472         int status;
473         int saved_status;
474         char  *tmp,*foo;
475
476         status=START_TO;
477         to_b->error=PARSE_OK;
478         foo=0;  
479
480         for( tmp=buffer; tmp<end; tmp++)
481         {
482                 switch(*tmp)
483                 {
484                         case ' ':
485                         case '\t':
486                                 switch (status)
487                                 {
488                                         case F_CRLF:
489                                         case F_LF:
490                                         case F_CR:
491                                                 /*previous=crlf and now =' '*/
492                                                 status=saved_status;
493                                                 break;
494                                         case URI_ENCLOSED:
495                                                 to_b->uri.len = tmp - to_b->uri.s;
496                                                 //*tmp = 0;
497                                                 status = E_URI_ENCLOSED;
498                                                 break;
499                                         case URI_OR_TOKEN:
500                                                 foo = tmp;
501                                                 status = MAYBE_URI_END;
502                                                 break;
503                                 }
504                                 break;
505                         case '\n':
506                                 switch (status)
507                                 {
508                                         case URI_OR_TOKEN:
509                                                 foo = tmp;
510                                                 status = MAYBE_URI_END;
511                                         case MAYBE_URI_END:
512                                         case DISPLAY_TOKEN:
513                                         case E_DISPLAY_QUOTED:
514                                         case END:
515                                                 saved_status=status;
516                                                 status=F_LF;
517                                                 break;
518                                         case F_CR:
519                                                 status=F_CRLF;
520                                                 break;
521                                         case F_CRLF:
522                                         case F_LF:
523                                                 status=saved_status;
524                                                 goto endofheader;
525                                         default:
526                                                 LOG( L_ERR , "ERROR: parse_to : unexpected char [%c] "
527                                                         "in status %d: <<%.*s>> .\n",
528                                                         *tmp,status, tmp-buffer, buffer);
529                                 }
530                                 break;
531                         case '\r':
532                                 switch (status)
533                                 {
534                                         case URI_OR_TOKEN:
535                                                 foo = tmp;
536                                                 status = MAYBE_URI_END;
537                                         case MAYBE_URI_END:
538                                         case DISPLAY_TOKEN:
539                                         case E_DISPLAY_QUOTED:
540                                         case END:
541                                                 saved_status=status;
542                                                 status=F_CR;
543                                                 break;
544                                         case F_CRLF:
545                                         case F_CR:
546                                         case F_LF:
547                                                 status=saved_status;
548                                                 goto endofheader;
549                                         default:
550                                                 LOG( L_ERR , "ERROR: parse_to : unexpected char [%c] "
551                                                         "in status %d: <<%.*s>> .\n",
552                                                         *tmp,status, tmp-buffer, buffer);
553                                                 goto error;
554                                 }
555                                 break;
556                         case '\\':
557                                 switch (status)
558                                 {
559                                         case DISPLAY_QUOTED:
560                                                 switch (*(tmp+1))
561                                                 {
562                                                         case '\n':
563                                                         case '\r':
564                                                                 break;
565                                                         default:
566                                                                 tmp++;
567                                                 }
568                                         default:
569                                                 LOG( L_ERR , "ERROR: parse_to : unexpected char [%c] "
570                                                         "in status %d: <<%.*s>> .\n",
571                                                         *tmp,status, tmp-buffer, buffer);
572                                                 goto error;
573                                 }
574                                 break;
575                         case '<':
576                                 switch (status)
577                                 {
578                                         case START_TO:
579                                                 to_b->body.s=tmp;
580                                                 status = S_URI_ENCLOSED;
581                                                 break;
582                                         case DISPLAY_QUOTED:
583                                                 break;
584                                         case E_DISPLAY_QUOTED:
585                                         case URI_OR_TOKEN:
586                                         case DISPLAY_TOKEN: 
587                                         case MAYBE_URI_END:
588                                                 status = S_URI_ENCLOSED;
589                                                 break;
590                                         case F_CRLF:
591                                         case F_LF:
592                                         case F_CR:
593                                                 /*previous=crlf and now !=' '*/
594                                                 goto endofheader;
595                                         default:
596                                                 LOG( L_ERR , "ERROR: parse_to : unexpected char [%c] "
597                                                         "in status %d: <<%.*s>> .\n",
598                                                         *tmp,status, tmp-buffer, buffer);
599                                                 goto error;
600                                 }
601                                 break;
602                         case '>':
603                                 switch (status)
604                                 {
605                                         case DISPLAY_QUOTED:
606                                                 break;
607                                         case URI_ENCLOSED:
608                                                 //*tmp = 0;
609                                         case E_URI_ENCLOSED:
610                                                 to_b->uri.len = tmp - to_b->uri.s;
611                                                 status = END;
612                                                 foo = 0;
613                                                 break;
614                                         case F_CRLF:
615                                         case F_LF:
616                                         case F_CR:
617                                                 /*previous=crlf and now !=' '*/
618                                                 goto endofheader;
619                                         default:
620                                                 LOG( L_ERR , "ERROR: parse_to : unexpected char [%c] "
621                                                         "in status %d: <<%.*s>> .\n",
622                                                         *tmp,status, tmp-buffer, buffer);
623                                                 goto error;
624                                 }
625                                 break;
626                         case '"':
627                                 switch (status)
628                                 {
629                                         case START_TO:
630                                                 to_b->body.s = tmp;
631                                                 status = DISPLAY_QUOTED;
632                                                 break;
633                                         case DISPLAY_QUOTED:
634                                                 status = E_DISPLAY_QUOTED;
635                                                 break;
636                                         case F_CRLF:
637                                         case F_LF:
638                                         case F_CR:
639                                                 /*previous=crlf and now !=' '*/
640                                                 goto endofheader;
641                                         default:
642                                                 LOG( L_ERR , "ERROR: parse_to : unexpected char [%c] "
643                                                         "in status %d: <<%.*s>> .\n",
644                                                         *tmp,status, tmp-buffer, buffer);
645                                                 goto error;
646                                 }
647                                 break;
648                         case ';' :
649                                 switch (status)
650                                 {
651                                         case DISPLAY_QUOTED:
652                                         case URI_ENCLOSED:
653                                                 break;
654                                         case URI_OR_TOKEN:
655                                                 foo = tmp;
656                                         case MAYBE_URI_END:
657                                                 to_b->uri.len = foo - to_b->uri.s;
658                                         case END:
659                                                 to_b->body.len = tmp-to_b->body.s;
660                                                 tmp = parse_to_param(tmp,end,to_b,&saved_status);
661                                                 //if (foo) *foo=0;
662                                                 goto endofheader;
663                                         case F_CRLF:
664                                         case F_LF:
665                                         case F_CR:
666                                                 /*previous=crlf and now !=' '*/
667                                                 goto endofheader;
668                                         default:
669                                                 LOG( L_ERR , "ERROR: parse_to : unexpected char [%c] "
670                                                         "in status %d: <<%.*s>> .\n",
671                                                         *tmp,status, tmp-buffer, buffer);
672                                                 goto error;
673                                 }
674                                 break;
675                         default:
676                                 switch (status)
677                                 {
678                                         case START_TO:
679                                                 to_b->uri.s = to_b->body.s = tmp;
680                                                 status = URI_OR_TOKEN;;
681                                                 break;
682                                         case S_URI_ENCLOSED:
683                                                 to_b->uri.s=tmp;
684                                                 status=URI_ENCLOSED;
685                                                 break;
686                                         case MAYBE_URI_END:
687                                                 status = DISPLAY_TOKEN;
688                                         case DISPLAY_QUOTED:
689                                         case DISPLAY_TOKEN:
690                                         case URI_ENCLOSED:
691                                         case URI_OR_TOKEN:
692                                                 break;
693                                         case F_CRLF:
694                                         case F_LF:
695                                         case F_CR:
696                                                 /*previous=crlf and now !=' '*/
697                                                 goto endofheader;
698                                         default:
699                                                 DBG("DEBUG:parse_to: spitting out [%c] in status %d\n",
700                                                 *tmp,status );
701                                                 goto error;
702                                 }
703                 }/*char switch*/
704         }/*for*/
705
706 endofheader:
707         status=saved_status;
708         DBG("end of header reached, state=%d\n", status);
709         /* check if error*/
710         switch(status){
711                 case MAYBE_URI_END:
712                         //*foo=0;
713                         to_b->uri.len = foo - to_b->uri.s;
714                 case END:
715                         to_b->body.len = tmp - to_b->body.s;
716                 case E_PARA_VALUE:
717                         *(tmp-1)=0;
718                         break;
719                 default:
720                         LOG(L_ERR, "ERROR: parse_to: invalid To -  unexpected "
721                                         "end of header in state %d\n", status);
722                         goto error;
723         }
724         return tmp;
725
726 error:
727         LOG(L_ERR, "to parse error\n");
728         to_b->error=PARSE_ERROR;
729         return tmp;
730
731 }
732
733
734 void free_to(struct to_body* tb)
735 {
736         struct to_param *tp=tb->param_lst;
737         struct to_param *foo;
738         while (tp){
739                 foo = tp->next;
740                 pkg_free(tp);
741                 tp=foo;
742         }
743         pkg_free(tb);
744 }
745
746
747