parse_retry_after.c

Go to the documentation of this file.
00001 /* 
00002  * $Id$ 
00003  *
00004  * Copyright (C) 2007 iptelorg GmbH
00005  *
00006  * This file is part of ser, a free SIP server.
00007  *
00008  * ser is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2 of the License, or
00011  * (at your option) any later version
00012  *
00013  * ser is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  * GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License 
00019  * along with this program; if not, write to the Free Software 
00020  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021  * 
00022  * History:
00023  * --------
00024  *  2007-07-27  created by andrei
00025  */
00026 
00034 #include "../comp_defs.h"
00035 #include "parse_retry_after.h"
00036 #include "parser_f.h"  /* eat_space_end and so on */
00037 #include "parse_def.h"
00038 #include "../dprint.h"
00039 #include "../mem/mem.h"
00040 
00042 char* parse_retry_after(char *buf, char* end, unsigned* after, int* err)
00043 {
00044         char *t;
00045         int i;
00046         unsigned val;
00047         
00048         val=0;
00049         t=buf;
00050         
00051         t=eat_lws_end(t, end);
00052         if (t>=end) goto error;
00053         for (i=0; t<end; i++,t++){
00054                 if ((*t >= '0') && (*t <= '9')){
00055                         val=val*10+(*t-'0');
00056                 }else{
00057                         switch(*t){
00058                                 /* for now we don't care about retry-after params or comment*/
00059                                 case ' ':
00060                                 case '\t':
00061                                 case ';':
00062                                 case '\r':
00063                                 case '\n':
00064                                         goto found;
00065                                 default:
00066                                         /* invalid char */
00067                                         goto error;
00068                         }
00069                 }
00070         }
00071         goto error_nocrlf; /* end reached without encountering cr or lf */
00072 found:
00073         if (i>10 || i==0) /* too many  or too few digits */
00074                 goto error;
00075         *after=val;
00076         /* find the end of header */
00077         for (; t<end; t++){
00078                 if (*t=='\n'){
00079                         if (((t+1)<end) && (*(t+1)=='\r'))
00080                                 t++;
00081                         if (((t+1)<end) && (*(t+1)==' ' || *(t+1)=='\t')){
00082                                 t++;
00083                                 continue; /* line folding ... */
00084                         }
00085                         *err=0;
00086                         return t+1;
00087                 }
00088         }
00089 error_nocrlf:
00090         LOG(L_ERR, "ERROR: parse_retry_after: strange EoHF\n");
00091         goto error;
00092 error:
00093         LOG(L_ERR, "ERROR: parse_retry_after: bad Retry-After header \n");
00094         *err=1;
00095         return t;
00096 }