Browse code

Date Header Field parsing funcions and macros

First release

Gergely Kovacs authored on 08/03/2007 15:19:47
Showing 3 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,41 @@
0
+/* 
1
+ * $Id$ 
2
+ *
3
+ * Date Header Field Name Parsing Macros
4
+ *
5
+ * Copyright (c) 2007 iptelorg GmbH
6
+ *
7
+ * This file is part of ser, a free SIP server.
8
+ *
9
+ * ser is free software; you can redistribute it and/or modify
10
+ * it under the terms of the GNU General Public License as published by
11
+ * the Free Software Foundation; either version 2 of the License, or
12
+ * (at your option) any later version
13
+ *
14
+ * For a license to use the ser software under conditions
15
+ * other than those described here, or to purchase support for this
16
+ * software, please contact iptel.org by e-mail at the following addresses:
17
+ *    info@iptel.org
18
+ *
19
+ * ser is distributed in the hope that it will be useful,
20
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
21
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22
+ * GNU General Public License for more details.
23
+ *
24
+ * You should have received a copy of the GNU General Public License 
25
+ * along with this program; if not, write to the Free Software 
26
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
27
+ */
28
+
29
+
30
+#ifndef CASE_DATE_H
31
+#define CASE_DATE_H
32
+
33
+
34
+#define date_CASE          \
35
+     hdr->type = HDR_DATE_T; \
36
+     p += 4;               \
37
+     goto dc_end
38
+
39
+
40
+#endif /* CASE_DATE_H */
0 41
new file mode 100644
... ...
@@ -0,0 +1,182 @@
0
+/*
1
+ * $Id$ 
2
+ *
3
+ * Copyright (c) 2007 iptelorg GmbH
4
+ *
5
+ * This file is part of ser, a free SIP server.
6
+ *
7
+ * ser is free software; you can redistribute it and/or modify
8
+ * it under the terms of the GNU General Public License as published by
9
+ * the Free Software Foundation; either version 2 of the License, or
10
+ * (at your option) any later version
11
+ *
12
+ * For a license to use the ser software under conditions
13
+ * other than those described here, or to purchase support for this
14
+ * software, please contact iptel.org by e-mail at the following addresses:
15
+ *    info@iptel.org
16
+ *
17
+ * ser is distributed in the hope that it will be useful,
18
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
+ * GNU General Public License for more details.
21
+ *
22
+ * You should have received a copy of the GNU General Public License
23
+ * along with this program; if not, write to the Free Software
24
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
25
+ */
26
+
27
+
28
+#include <string.h>
29
+#include "parse_date.h"
30
+#include "parse_def.h"
31
+#include "parser_f.h"  /* eat_space_end and so on */
32
+#include "../mem/mem.h"
33
+
34
+/*
35
+ * Parse Date header field
36
+ */
37
+
38
+#define READ(val) \
39
+(*(val + 0) + (*(val + 1) << 8) + (*(val + 2) << 16) + (*(val + 3) << 24))
40
+
41
+/*
42
+ * Converts a RFC 1123 formatted date string to stuct tm
43
+ */
44
+int rfc1123totm (char *stime, struct tm *ttm ) {
45
+	char *ptime = stime;
46
+	unsigned int uval;
47
+	int ires;
48
+
49
+	int char2int (char *p, int *t){
50
+		if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') return -1;
51
+		*t = (*p - '0')*10 + *(p + 1) - '0';
52
+
53
+		return 0;
54
+	}
55
+
56
+	uval = READ(ptime);
57
+	ptime+=4;
58
+	switch (uval) {
59
+		/* Sun, */
60
+		case 0x2c6e7553: ttm->tm_wday = 0; break;
61
+		/* Mon, */
62
+		case 0x2c6e6f4d: ttm->tm_wday = 1; break;
63
+		/* Tue, */
64
+		case 0x2c657554: ttm->tm_wday = 2; break;
65
+		/* Wed, */
66
+		case 0x2c646557: ttm->tm_wday = 3; break;
67
+		/* Thu, */
68
+		case 0x2c756854: ttm->tm_wday = 4; break;
69
+		/* Fri, */
70
+		case 0x2c697246: ttm->tm_wday = 5; break;
71
+		/* Sat, */
72
+		case 0x2c746153: ttm->tm_wday = 6; break;
73
+		default: return -2;
74
+	}
75
+
76
+	if (*(ptime++)!=' ') return -3;
77
+
78
+
79
+	if (char2int(ptime,&ttm->tm_mday) || ttm->tm_mday > 31) return -4;
80
+	ptime+=2;
81
+
82
+	if (*(ptime++) != ' ') return -5;
83
+
84
+	uval = READ(ptime);
85
+	ptime+=4;
86
+	switch (uval) {
87
+		/* Jan, */
88
+		case 0x206e614a: ttm->tm_mon = 0; break;
89
+		/* Feb, */
90
+		case 0x20626546: ttm->tm_mon = 1; break;
91
+		/* Mar, */
92
+		case 0x2072614d: ttm->tm_mon = 2; break;
93
+		/* Apr, */
94
+		case 0x20727041: ttm->tm_mon = 3; break;
95
+		/* May, */
96
+		case 0x2079614d: ttm->tm_mon = 4; break;
97
+		/* Jun, */
98
+		case 0x206e754a: ttm->tm_mon = 5; break;
99
+		/* Jul, */
100
+		case 0x206c754a: ttm->tm_mon = 6; break;
101
+		/* Aug, */
102
+		case 0x20677541: ttm->tm_mon = 7; break;
103
+		/* Sep, */
104
+		case 0x20706553: ttm->tm_mon = 8; break;
105
+		/* Oct, */
106
+		case 0x2074634f: ttm->tm_mon = 9; break;
107
+		/* Nov, */
108
+		case 0x20766f4e: ttm->tm_mon = 10; break;
109
+		/* Dec, */
110
+		case 0x20636544: ttm->tm_mon = 11; break;
111
+		default: return -6;
112
+	}
113
+
114
+	if (char2int(ptime,&ires)) return -7;
115
+	ptime+=2;
116
+	if (char2int(ptime,&ttm->tm_year)) return -8;
117
+	ptime+=2;
118
+	ttm->tm_year+=(ires-19)*100;
119
+
120
+	if (*(ptime++) != ' ') return -9;
121
+
122
+	if (char2int(ptime,&ttm->tm_hour) || ttm->tm_hour > 23) return -10;
123
+	ptime+=2;
124
+	if (*(ptime++) != ':') return -11;
125
+
126
+	if (char2int(ptime,&ttm->tm_min) || ttm->tm_min > 59) return -12;
127
+	ptime+=2;
128
+	if (*(ptime++) != ':') return -13;
129
+
130
+	if (char2int(ptime,&ttm->tm_sec) || ttm->tm_sec > 59) return -14;
131
+	ptime+=2;
132
+
133
+	/* " GMT" */
134
+	if (memcmp(ptime," GMT", strlen(" GMT"))) return -15;
135
+
136
+	return 0;
137
+}
138
+
139
+char* parse_date(char *buffer, char *end, struct date_body *db)
140
+{
141
+	char *p;
142
+	int i1;
143
+
144
+	db->error=PARSE_ERROR;
145
+	p = buffer;
146
+
147
+	/* check whether enough characters are available */
148
+	for (i1 = 0; i1 < RFC1123DATELENGTH || p[i1] == '\n' || p + i1 >= end;i1++);
149
+	if (i1 < RFC1123DATELENGTH)
150
+		goto error;
151
+
152
+	if (rfc1123totm(buffer,&db->date))
153
+		goto error;
154
+
155
+	p+=RFC1123DATELENGTH;
156
+
157
+	p=eat_lws_end(p, end);
158
+	/*check if the header ends here*/
159
+	if (p>=end) {
160
+		LOG(L_ERR, "ERROR: parse_date: strange EoHF\n");
161
+		goto error;
162
+	}
163
+	if (*p=='\r' && p+1<end && *(p+1)=='\n') {
164
+		db->error=PARSE_OK;
165
+		return p+2;
166
+	}
167
+	if (*p=='\n') {
168
+		db->error=PARSE_OK;
169
+		return p+1;
170
+	}
171
+	LOG(L_ERR, "ERROR: Date EoL expected\n");
172
+error:
173
+	LOG(L_ERR,"ERROR: parse_date: parse error\n");
174
+	return p;
175
+}
176
+
177
+
178
+void free_date(struct date_body *db)
179
+{
180
+	pkg_free(db);
181
+}
0 182
new file mode 100644
... ...
@@ -0,0 +1,58 @@
0
+/*
1
+ * $Id$ 
2
+ *
3
+ * Copyright (c) 2007 iptelorg GmbH
4
+ *
5
+ * This file is part of ser, a free SIP server.
6
+ *
7
+ * ser is free software; you can redistribute it and/or modify
8
+ * it under the terms of the GNU General Public License as published by
9
+ * the Free Software Foundation; either version 2 of the License, or
10
+ * (at your option) any later version
11
+ *
12
+ * For a license to use the ser software under conditions
13
+ * other than those described here, or to purchase support for this
14
+ * software, please contact iptel.org by e-mail at the following addresses:
15
+ *    info@iptel.org
16
+ *
17
+ * ser is distributed in the hope that it will be useful,
18
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
+ * GNU General Public License for more details.
21
+ *
22
+ * You should have received a copy of the GNU General Public License
23
+ * along with this program; if not, write to the Free Software
24
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
25
+ */
26
+
27
+
28
+#ifndef PARSE_DATE
29
+#define PARSE_DATE
30
+
31
+#include <time.h>
32
+
33
+#define RFC1123DATELENGTH	29
34
+
35
+struct date_body{
36
+	int error;  /* Error code */
37
+	struct tm date;
38
+};
39
+
40
+
41
+/* casting macro for accessing DATE body */
42
+#define get_date(p_msg) ((struct date_body*)(p_msg)->date->parsed)
43
+
44
+
45
+/*
46
+ * Parse Date header field
47
+ */
48
+char* parse_date(char *buf, char *end, struct date_body *db);
49
+
50
+
51
+/*
52
+ * Free all associated memory
53
+ */
54
+void free_date(struct date_body *db);
55
+
56
+
57
+#endif