Mercurial > hg > nginx-quic
annotate src/imap/ngx_imap_parse.c @ 816:e372368dadd7 release-0.4.11
nginx-0.4.11-RELEASE
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Wed, 25 Oct 2006 16:29:25 +0000 |
parents | e3aa8f305d21 |
children |
rev | line source |
---|---|
441
da8c5707af39
nginx-0.1.0-2004-09-28-12:34:51 import; set copyright and remove unused files
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1 |
da8c5707af39
nginx-0.1.0-2004-09-28-12:34:51 import; set copyright and remove unused files
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
2 /* |
444
42d11f017717
nginx-0.1.0-2004-09-29-20:00:49 import; remove years from copyright
Igor Sysoev <igor@sysoev.ru>
parents:
441
diff
changeset
|
3 * Copyright (C) Igor Sysoev |
441
da8c5707af39
nginx-0.1.0-2004-09-28-12:34:51 import; set copyright and remove unused files
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
4 */ |
da8c5707af39
nginx-0.1.0-2004-09-28-12:34:51 import; set copyright and remove unused files
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
5 |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
6 |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
7 #include <ngx_config.h> |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
8 #include <ngx_core.h> |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
9 #include <ngx_event.h> |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
10 #include <ngx_imap.h> |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
11 |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
12 |
527 | 13 ngx_int_t ngx_imap_parse_command(ngx_imap_session_t *s) |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
14 { |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
15 u_char ch, *p, *c; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
16 ngx_str_t *arg; |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
17 enum { |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
18 sw_start = 0, |
527 | 19 sw_spaces_before_command, |
20 sw_command, | |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
21 sw_spaces_before_argument, |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
22 sw_argument, |
543 | 23 sw_backslash, |
527 | 24 sw_literal, |
543 | 25 sw_no_sync_literal_argument, |
527 | 26 sw_start_literal_argument, |
27 sw_literal_argument, | |
28 sw_end_literal_argument, | |
29 sw_almost_done | |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
30 } state; |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
31 |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
32 state = s->state; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
33 |
527 | 34 for (p = s->buffer->pos; p < s->buffer->last; p++) { |
35 ch = *p; | |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
36 |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
37 switch (state) { |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
38 |
527 | 39 /* IMAP tag */ |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
40 case sw_start: |
527 | 41 switch (ch) { |
42 case ' ': | |
43 s->tag.len = p - s->buffer->start + 1; | |
44 s->tag.data = s->buffer->start; | |
45 state = sw_spaces_before_command; | |
46 break; | |
47 case CR: | |
48 s->state = sw_start; | |
49 return NGX_IMAP_PARSE_INVALID_COMMAND; | |
50 case LF: | |
51 s->state = sw_start; | |
52 return NGX_IMAP_PARSE_INVALID_COMMAND; | |
53 } | |
54 break; | |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
55 |
527 | 56 case sw_spaces_before_command: |
57 switch (ch) { | |
58 case ' ': | |
59 break; | |
60 case CR: | |
61 s->state = sw_start; | |
62 return NGX_IMAP_PARSE_INVALID_COMMAND; | |
63 case LF: | |
64 s->state = sw_start; | |
65 return NGX_IMAP_PARSE_INVALID_COMMAND; | |
66 default: | |
67 s->cmd_start = p; | |
68 state = sw_command; | |
69 break; | |
70 } | |
71 break; | |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
72 |
527 | 73 case sw_command: |
74 if (ch == ' ' || ch == CR || ch == LF) { | |
75 | |
76 c = s->cmd_start; | |
77 | |
78 switch (p - c) { | |
79 | |
80 case 4: | |
81 if ((c[0] == 'N' || c[0] == 'n') | |
82 && (c[1] == 'O'|| c[1] == 'o') | |
83 && (c[2] == 'O'|| c[2] == 'o') | |
84 && (c[3] == 'P'|| c[3] == 'p')) | |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
85 { |
527 | 86 s->command = NGX_IMAP_NOOP; |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
87 |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
88 } else { |
527 | 89 goto invalid; |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
90 } |
527 | 91 break; |
92 | |
93 case 5: | |
94 if ((c[0] == 'L'|| c[0] == 'l') | |
95 && (c[1] == 'O'|| c[1] == 'o') | |
96 && (c[2] == 'G'|| c[2] == 'g') | |
97 && (c[3] == 'I'|| c[3] == 'i') | |
98 && (c[4] == 'N'|| c[4] == 'n')) | |
99 { | |
100 s->command = NGX_IMAP_LOGIN; | |
101 | |
102 } else { | |
103 goto invalid; | |
104 } | |
105 break; | |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
106 |
527 | 107 case 6: |
108 if ((c[0] == 'L'|| c[0] == 'l') | |
109 && (c[1] == 'O'|| c[1] == 'o') | |
110 && (c[2] == 'G'|| c[2] == 'g') | |
111 && (c[3] == 'O'|| c[3] == 'o') | |
112 && (c[4] == 'U'|| c[4] == 'u') | |
113 && (c[5] == 'T'|| c[5] == 't')) | |
114 { | |
115 s->command = NGX_IMAP_LOGOUT; | |
116 | |
117 } else { | |
118 goto invalid; | |
119 } | |
120 break; | |
121 | |
583 | 122 #if (NGX_IMAP_SSL) |
123 case 8: | |
124 if ((c[0] == 'S'|| c[0] == 's') | |
125 && (c[1] == 'T'|| c[1] == 't') | |
126 && (c[2] == 'A'|| c[2] == 'a') | |
127 && (c[3] == 'R'|| c[3] == 'r') | |
128 && (c[4] == 'T'|| c[4] == 't') | |
129 && (c[5] == 'T'|| c[5] == 't') | |
130 && (c[6] == 'L'|| c[6] == 'l') | |
131 && (c[7] == 'S'|| c[7] == 's')) | |
132 { | |
133 s->command = NGX_IMAP_STARTTLS; | |
134 | |
135 } else { | |
136 goto invalid; | |
137 } | |
138 break; | |
139 #endif | |
140 | |
527 | 141 case 10: |
142 if ((c[0] == 'C'|| c[0] == 'c') | |
143 && (c[1] == 'A'|| c[1] == 'a') | |
144 && (c[2] == 'P'|| c[2] == 'p') | |
145 && (c[3] == 'A'|| c[3] == 'a') | |
146 && (c[4] == 'B'|| c[4] == 'b') | |
147 && (c[5] == 'I'|| c[5] == 'i') | |
148 && (c[6] == 'L'|| c[6] == 'l') | |
149 && (c[7] == 'I'|| c[7] == 'i') | |
150 && (c[8] == 'T'|| c[8] == 't') | |
151 && (c[9] == 'Y'|| c[9] == 'y')) | |
152 { | |
153 s->command = NGX_IMAP_CAPABILITY; | |
154 | |
155 } else { | |
156 goto invalid; | |
157 } | |
158 break; | |
159 | |
160 default: | |
161 goto invalid; | |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
162 } |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
163 |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
164 switch (ch) { |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
165 case ' ': |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
166 state = sw_spaces_before_argument; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
167 break; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
168 case CR: |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
169 state = sw_almost_done; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
170 break; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
171 case LF: |
527 | 172 goto done; |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
173 } |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
174 break; |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
175 } |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
176 |
527 | 177 if ((ch < 'A' || ch > 'Z') && (ch < 'a' || ch > 'z')) { |
178 goto invalid; | |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
179 } |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
180 |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
181 break; |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
182 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
183 case sw_spaces_before_argument: |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
184 switch (ch) { |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
185 case ' ': |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
186 break; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
187 case CR: |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
188 state = sw_almost_done; |
527 | 189 s->arg_end = p; |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
190 break; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
191 case LF: |
527 | 192 s->arg_end = p; |
193 goto done; | |
194 case '"': | |
195 if (s->args.nelts <= 2) { | |
196 s->quoted = 1; | |
197 s->arg_start = p + 1; | |
198 state = sw_argument; | |
199 break; | |
200 } | |
201 goto invalid; | |
202 case '{': | |
203 if (s->args.nelts <= 2) { | |
204 state = sw_literal; | |
205 break; | |
206 } | |
207 goto invalid; | |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
208 default: |
527 | 209 if (s->args.nelts <= 2) { |
210 s->arg_start = p; | |
211 state = sw_argument; | |
212 break; | |
213 } | |
214 goto invalid; | |
215 } | |
216 break; | |
217 | |
218 case sw_argument: | |
219 switch (ch) { | |
220 case '"': | |
221 if (!s->quoted) { | |
222 break; | |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
223 } |
527 | 224 s->quoted = 0; |
225 /* fall through */ | |
226 case ' ': | |
227 case CR: | |
228 case LF: | |
229 arg = ngx_array_push(&s->args); | |
230 if (arg == NULL) { | |
231 return NGX_ERROR; | |
232 } | |
233 arg->len = p - s->arg_start; | |
234 arg->data = s->arg_start; | |
235 s->arg_start = NULL; | |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
236 |
527 | 237 switch (ch) { |
238 case '"': | |
239 case ' ': | |
240 state = sw_spaces_before_argument; | |
241 break; | |
242 case CR: | |
243 state = sw_almost_done; | |
244 break; | |
245 case LF: | |
246 goto done; | |
247 } | |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
248 break; |
543 | 249 case '\\': |
250 if (s->quoted) { | |
251 s->backslash = 1; | |
252 state = sw_backslash; | |
253 } | |
254 break; | |
255 } | |
256 break; | |
257 | |
258 case sw_backslash: | |
259 switch (ch) { | |
260 case CR: | |
261 case LF: | |
262 goto invalid; | |
263 default: | |
264 state = sw_argument; | |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
265 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
266 break; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
267 |
527 | 268 case sw_literal: |
269 if (ch >= '0' && ch <= '9') { | |
270 s->literal_len = s->literal_len * 10 + (ch - '0'); | |
271 break; | |
272 } | |
273 if (ch == '}') { | |
274 state = sw_start_literal_argument; | |
275 break; | |
276 } | |
543 | 277 if (ch == '+') { |
278 state = sw_no_sync_literal_argument; | |
279 break; | |
280 } | |
281 goto invalid; | |
282 | |
283 case sw_no_sync_literal_argument: | |
284 if (ch == '}') { | |
285 s->no_sync_literal = 1; | |
286 state = sw_start_literal_argument; | |
287 break; | |
288 } | |
527 | 289 goto invalid; |
290 | |
291 case sw_start_literal_argument: | |
292 switch (ch) { | |
293 case CR: | |
294 break; | |
295 case LF: | |
296 s->buffer->pos = p + 1; | |
297 s->arg_start = p + 1; | |
543 | 298 if (s->no_sync_literal == 0) { |
299 s->state = sw_literal_argument; | |
300 return NGX_IMAP_NEXT; | |
301 } | |
302 state = sw_literal_argument; | |
303 s->no_sync_literal = 0; | |
304 break; | |
305 default: | |
306 goto invalid; | |
527 | 307 } |
543 | 308 break; |
527 | 309 |
310 case sw_literal_argument: | |
529 | 311 if (s->literal_len && --s->literal_len) { |
527 | 312 break; |
313 } | |
314 | |
315 arg = ngx_array_push(&s->args); | |
316 if (arg == NULL) { | |
317 return NGX_ERROR; | |
318 } | |
319 arg->len = p + 1 - s->arg_start; | |
320 arg->data = s->arg_start; | |
321 s->arg_start = NULL; | |
322 state = sw_end_literal_argument; | |
323 | |
324 break; | |
325 | |
326 case sw_end_literal_argument: | |
327 switch (ch) { | |
328 case '{': | |
329 if (s->args.nelts <= 2) { | |
330 state = sw_literal; | |
331 break; | |
332 } | |
333 goto invalid; | |
334 case CR: | |
335 state = sw_almost_done; | |
336 break; | |
337 case LF: | |
338 goto done; | |
339 default: | |
529 | 340 state = sw_spaces_before_argument; |
341 break; | |
527 | 342 } |
343 break; | |
344 | |
345 case sw_almost_done: | |
346 switch (ch) { | |
347 case LF: | |
348 goto done; | |
349 default: | |
350 goto invalid; | |
351 } | |
352 } | |
353 } | |
354 | |
355 s->buffer->pos = p; | |
356 s->state = state; | |
357 | |
358 return NGX_AGAIN; | |
359 | |
360 done: | |
361 | |
362 s->buffer->pos = p + 1; | |
363 | |
364 if (s->arg_start) { | |
365 arg = ngx_array_push(&s->args); | |
366 if (arg == NULL) { | |
367 return NGX_ERROR; | |
368 } | |
369 arg->len = s->arg_end - s->arg_start; | |
370 arg->data = s->arg_start; | |
543 | 371 |
527 | 372 s->arg_start = NULL; |
373 s->cmd_start = NULL; | |
374 s->quoted = 0; | |
543 | 375 s->no_sync_literal = 0; |
527 | 376 s->literal_len = 0; |
377 } | |
378 | |
379 s->state = sw_start; | |
380 | |
381 return NGX_OK; | |
382 | |
383 invalid: | |
384 | |
385 s->state = sw_start; | |
386 s->quoted = 0; | |
543 | 387 s->no_sync_literal = 0; |
527 | 388 s->literal_len = 0; |
389 | |
390 return NGX_IMAP_PARSE_INVALID_COMMAND; | |
391 } | |
392 | |
393 | |
394 ngx_int_t ngx_pop3_parse_command(ngx_imap_session_t *s) | |
395 { | |
396 u_char ch, *p, *c, c0, c1, c2, c3; | |
397 ngx_str_t *arg; | |
398 enum { | |
399 sw_start = 0, | |
400 sw_spaces_before_argument, | |
401 sw_argument, | |
402 sw_almost_done | |
403 } state; | |
404 | |
405 state = s->state; | |
406 | |
407 for (p = s->buffer->pos; p < s->buffer->last; p++) { | |
408 ch = *p; | |
409 | |
410 switch (state) { | |
411 | |
412 /* POP3 command */ | |
413 case sw_start: | |
414 if (ch == ' ' || ch == CR || ch == LF) { | |
415 c = s->buffer->start; | |
416 | |
417 if (p - c == 4) { | |
418 | |
419 c0 = ngx_toupper(c[0]); | |
420 c1 = ngx_toupper(c[1]); | |
421 c2 = ngx_toupper(c[2]); | |
422 c3 = ngx_toupper(c[3]); | |
423 | |
424 if (c0 == 'U' && c1 == 'S' && c2 == 'E' && c3 == 'R') | |
425 { | |
426 s->command = NGX_POP3_USER; | |
427 | |
428 } else if (c0 == 'P' && c1 == 'A' && c2 == 'S' && c3 == 'S') | |
429 { | |
430 s->command = NGX_POP3_PASS; | |
431 | |
800 | 432 } else if (c0 == 'A' && c1 == 'P' && c2 == 'O' && c3 == 'P') |
433 { | |
434 s->command = NGX_POP3_APOP; | |
435 | |
527 | 436 } else if (c0 == 'Q' && c1 == 'U' && c2 == 'I' && c3 == 'T') |
437 { | |
438 s->command = NGX_POP3_QUIT; | |
439 | |
440 } else if (c0 == 'C' && c1 == 'A' && c2 == 'P' && c3 == 'A') | |
441 { | |
442 s->command = NGX_POP3_CAPA; | |
443 | |
809 | 444 } else if (c0 == 'A' && c1 == 'U' && c2 == 'T' && c3 == 'H') |
445 { | |
446 s->command = NGX_POP3_AUTH; | |
447 | |
527 | 448 } else if (c0 == 'N' && c1 == 'O' && c2 == 'O' && c3 == 'P') |
449 { | |
450 s->command = NGX_POP3_NOOP; | |
583 | 451 #if (NGX_IMAP_SSL) |
452 } else if (c0 == 'S' && c1 == 'T' && c2 == 'L' && c3 == 'S') | |
453 { | |
454 s->command = NGX_POP3_STLS; | |
455 #endif | |
527 | 456 } else { |
457 goto invalid; | |
458 } | |
459 | |
460 } else { | |
461 goto invalid; | |
462 } | |
463 | |
464 switch (ch) { | |
465 case ' ': | |
466 state = sw_spaces_before_argument; | |
467 break; | |
468 case CR: | |
469 state = sw_almost_done; | |
470 break; | |
471 case LF: | |
472 goto done; | |
473 } | |
474 break; | |
475 } | |
476 | |
477 if ((ch < 'A' || ch > 'Z') && (ch < 'a' || ch > 'z')) { | |
478 goto invalid; | |
479 } | |
480 | |
481 break; | |
482 | |
483 case sw_spaces_before_argument: | |
484 switch (ch) { | |
485 case ' ': | |
486 break; | |
487 case CR: | |
488 state = sw_almost_done; | |
489 s->arg_end = p; | |
490 break; | |
491 case LF: | |
492 s->arg_end = p; | |
493 goto done; | |
494 default: | |
495 if (s->args.nelts <= 2) { | |
496 state = sw_argument; | |
497 s->arg_start = p; | |
498 break; | |
499 } | |
500 goto invalid; | |
501 } | |
502 break; | |
503 | |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
504 case sw_argument: |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
505 switch (ch) { |
543 | 506 |
800 | 507 case ' ': |
508 | |
509 /* | |
510 * the space should be considered as part of the at username | |
511 * or password, but not of argument in other commands | |
512 */ | |
513 | |
514 if (s->command == NGX_POP3_USER | |
515 || s->command == NGX_POP3_PASS) | |
516 { | |
517 break; | |
518 } | |
519 | |
520 /* fall through */ | |
543 | 521 |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
522 case CR: |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
523 case LF: |
501 | 524 arg = ngx_array_push(&s->args); |
525 if (arg == NULL) { | |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
526 return NGX_ERROR; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
527 } |
527 | 528 arg->len = p - s->arg_start; |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
529 arg->data = s->arg_start; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
530 s->arg_start = NULL; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
531 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
532 switch (ch) { |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
533 case ' ': |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
534 state = sw_spaces_before_argument; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
535 break; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
536 case CR: |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
537 state = sw_almost_done; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
538 break; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
539 case LF: |
527 | 540 goto done; |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
541 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
542 break; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
543 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
544 default: |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
545 break; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
546 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
547 break; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
548 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
549 case sw_almost_done: |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
550 switch (ch) { |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
551 case LF: |
527 | 552 goto done; |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
553 default: |
527 | 554 goto invalid; |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
555 } |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
556 } |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
557 } |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
558 |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
559 s->buffer->pos = p; |
527 | 560 s->state = state; |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
561 |
527 | 562 return NGX_AGAIN; |
563 | |
564 done: | |
565 | |
566 s->buffer->pos = p + 1; | |
567 | |
568 if (s->arg_start) { | |
569 arg = ngx_array_push(&s->args); | |
570 if (arg == NULL) { | |
571 return NGX_ERROR; | |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
572 } |
527 | 573 arg->len = s->arg_end - s->arg_start; |
574 arg->data = s->arg_start; | |
575 s->arg_start = NULL; | |
576 } | |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
577 |
809 | 578 s->state = (s->command != NGX_POP3_AUTH) ? sw_start : sw_argument; |
527 | 579 return NGX_OK; |
580 | |
581 invalid: | |
582 | |
583 s->state = sw_start; | |
810 | 584 s->arg_start = NULL; |
527 | 585 |
586 return NGX_IMAP_PARSE_INVALID_COMMAND; | |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
587 } |