Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00031 #include <string.h>
00032 #include "parse_date.h"
00033 #include "parse_def.h"
00034 #include "parser_f.h"
00035 #include "../mem/mem.h"
00036
00037
00038
00039
00040
00041 #define READ(val) \
00042 (*(val + 0) + (*(val + 1) << 8) + (*(val + 2) << 16) + (*(val + 3) << 24))
00043
00044 inline static int char2int (char *p, int *t)
00045 {
00046 if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9')
00047 return -1;
00048 *t = (*p - '0')*10 + *(p + 1) - '0';
00049
00050 return 0;
00051 }
00052
00056 static int rfc1123totm (char *stime, struct tm *ttm ) {
00057 char *ptime = stime;
00058 unsigned int uval;
00059 int ires;
00060
00061 uval = READ(ptime);
00062 ptime+=4;
00063 switch (uval) {
00064
00065 case 0x2c6e7553: ttm->tm_wday = 0; break;
00066
00067 case 0x2c6e6f4d: ttm->tm_wday = 1; break;
00068
00069 case 0x2c657554: ttm->tm_wday = 2; break;
00070
00071 case 0x2c646557: ttm->tm_wday = 3; break;
00072
00073 case 0x2c756854: ttm->tm_wday = 4; break;
00074
00075 case 0x2c697246: ttm->tm_wday = 5; break;
00076
00077 case 0x2c746153: ttm->tm_wday = 6; break;
00078 default: return -2;
00079 }
00080
00081 if (*(ptime++)!=' ') return -3;
00082
00083
00084 if (char2int(ptime,&ttm->tm_mday) || ttm->tm_mday > 31) return -4;
00085 ptime+=2;
00086
00087 if (*(ptime++) != ' ') return -5;
00088
00089 uval = READ(ptime);
00090 ptime+=4;
00091 switch (uval) {
00092
00093 case 0x206e614a: ttm->tm_mon = 0; break;
00094
00095 case 0x20626546: ttm->tm_mon = 1; break;
00096
00097 case 0x2072614d: ttm->tm_mon = 2; break;
00098
00099 case 0x20727041: ttm->tm_mon = 3; break;
00100
00101 case 0x2079614d: ttm->tm_mon = 4; break;
00102
00103 case 0x206e754a: ttm->tm_mon = 5; break;
00104
00105 case 0x206c754a: ttm->tm_mon = 6; break;
00106
00107 case 0x20677541: ttm->tm_mon = 7; break;
00108
00109 case 0x20706553: ttm->tm_mon = 8; break;
00110
00111 case 0x2074634f: ttm->tm_mon = 9; break;
00112
00113 case 0x20766f4e: ttm->tm_mon = 10; break;
00114
00115 case 0x20636544: ttm->tm_mon = 11; break;
00116 default: return -6;
00117 }
00118
00119 if (char2int(ptime,&ires)) return -7;
00120 ptime+=2;
00121 if (char2int(ptime,&ttm->tm_year)) return -8;
00122 ptime+=2;
00123 ttm->tm_year+=(ires-19)*100;
00124
00125 if (*(ptime++) != ' ') return -9;
00126
00127 if (char2int(ptime,&ttm->tm_hour) || ttm->tm_hour > 23) return -10;
00128 ptime+=2;
00129 if (*(ptime++) != ':') return -11;
00130
00131 if (char2int(ptime,&ttm->tm_min) || ttm->tm_min > 59) return -12;
00132 ptime+=2;
00133 if (*(ptime++) != ':') return -13;
00134
00135 if (char2int(ptime,&ttm->tm_sec) || ttm->tm_sec > 59) return -14;
00136 ptime+=2;
00137
00138
00139 uval = READ(ptime);
00140 if ((uval | 0x20202020) != 0x746d6720) return -15;
00141
00142 return 0;
00143 }
00144
00145 void parse_date(char *buffer, char *end, struct date_body *db)
00146 {
00147 db->error=PARSE_ERROR;
00148
00149
00150 if (end - buffer < RFC1123DATELENGTH)
00151 goto error;
00152
00153 if (rfc1123totm(buffer,&db->date))
00154 goto error;
00155
00156 db->error=PARSE_OK;
00157 return ;
00158 error:
00159 LOG(L_ERR,"ERROR: parse_date: parse error\n");
00160 return ;
00161 }
00162
00163 int parse_date_header(struct sip_msg *msg)
00164 {
00165 struct date_body* date_b;
00166
00167
00168 if ( !msg->date && (parse_headers(msg,HDR_DATE_F,0)==-1 || !msg->date) ) {
00169 LOG(L_ERR,"ERROR:parse_date_header: bad msg or missing DATE header\n");
00170 goto error;
00171 }
00172
00173
00174 if (msg->date->parsed)
00175 return 0;
00176
00177 date_b=pkg_malloc(sizeof(*date_b));
00178 if (date_b==0){
00179 LOG(L_ERR, "ERROR:parse_date_header: out of memory\n");
00180 goto error;
00181 }
00182 memset(date_b, 0, sizeof(*date_b));
00183
00184 parse_date(msg->date->body.s,
00185 msg->date->body.s + msg->date->body.len+1,
00186 date_b);
00187 if (date_b->error==PARSE_ERROR){
00188 free_date(date_b);
00189 goto error;
00190 }
00191 msg->date->parsed=(void*)date_b;
00192
00193 return 0;
00194 error:
00195 return -1;
00196 }
00197
00198 void free_date(struct date_body *db)
00199 {
00200 pkg_free(db);
00201 }