diff src/imap/ngx_imap_parse.c @ 419:47709bff4468

nginx-0.0.10-2004-09-09-19:40:48 import
author Igor Sysoev <igor@sysoev.ru>
date Thu, 09 Sep 2004 15:40:48 +0000
parents 0526206251f6
children 01456a419cf9
line wrap: on
line diff
--- a/src/imap/ngx_imap_parse.c
+++ b/src/imap/ngx_imap_parse.c
@@ -5,49 +5,75 @@
 #include <ngx_imap.h>
 
 
-ngx_int_t ngx_pop3_parse_command(ngx_imap_request_t *r)
+ngx_int_t ngx_pop3_parse_command(ngx_imap_session_t *s)
 {
-    u_char  ch, *p, *c;
+    u_char      ch, *p, *c;
+    ngx_str_t  *arg;
     enum {
         sw_start = 0,
+        sw_spaces_before_argument,
+        sw_argument,
+        sw_almost_done,
         sw_done
     } state;
 
-    while (p < r->buf->last && state < sw_done) {
+    state = s->state;
+    p = s->buffer->pos;
+
+    while (p < s->buffer->last && state < sw_done) {
         ch = *p++;
 
         switch (state) {
 
-        /* POP3 commands */
+        /* POP3 command */
+
         case sw_start:
-            if (ch == ' ') {
-                c = r->buf->start;
+            if (ch == ' ' || ch == CR || ch == LF) {
+                c = s->buffer->start;
+
+                if (p - 1 - c == 4) {
 
-                if (p - 1 - m == 4) {
+                    if (c[0] == 'U' && c[1] == 'S'
+                        && c[2] == 'E' && c[3] == 'R')
+                    {
+                        s->command = NGX_POP3_USER;
 
-                    if (*c == 'U' && *(c + 1) == 'S'
-                        && *(c + 2) == 'E' && *(c + 3) == 'R')
+                    } else if (c[0] == 'P' && c[1] == 'A'
+                               && c[2] == 'A' && c[3] == 'S')
                     {
-                        r->command = NGX_POP3_USER;
+                        s->command = NGX_POP3_PASS;
 
-                    } else if (*c == 'P' && *(c + 1) == 'A'
-                               && *(c + 2) == 'A' && *(c + 3) == 'S')
+                    } else if (c[0] == 'Q' && c[1] == 'U'
+                               && c[2] == 'I' && c[3] == 'T')
                     {
-                        r->method = NGX_POP3_PASS;
+                        s->command = NGX_POP3_QUIT;
 
-                    } else if (*c == 'Q' && *(c + 1) == 'U'
-                               && *(c + 2) == 'I' && *(c + 3) == 'T')
+#if 0
+                    } else if (c[0] == 'N' && c[1] == 'O'
+                               && c[2] == 'O' && c[3] == 'P')
                     {
-                        r->method = NGX_POP3_QUIT;
+                        s->command = NGX_POP3_NOOP;
+#endif
 
-                    } else if (*c == 'N' && *(c + 1) == 'O'
-                               && *(c + 2) == 'O' && *(c + 3) == 'P')
-                    {
-                        r->method = NGX_POP3_NOOP;
+                    } else {
+                        return NGX_IMAP_PARSE_INVALID_COMMAND;
                     }
+
+                } else {
+                    return NGX_IMAP_PARSE_INVALID_COMMAND;
                 }
 
-                state = sw_spaces_before_arg;
+                switch (ch) {
+                case ' ':
+                    state = sw_spaces_before_argument;
+                    break;
+                case CR:
+                    state = sw_almost_done;
+                    break;
+                case LF:
+                    state = sw_done;
+                    break;
+                }
                 break;
             }
 
@@ -56,7 +82,72 @@ ngx_int_t ngx_pop3_parse_command(ngx_ima
             }
 
             break;
-        }
+
+        /* the spaces before the argument */
+        case sw_spaces_before_argument:
+            switch (ch) {
+            case ' ':
+                break;
+            case CR:
+                state = sw_almost_done;
+                s->arg_end = p - 1;
+                break;
+            case LF:
+                state = sw_done;
+                s->arg_end = p - 1;
+                break;
+            default:
+                if (s->args.nelts > 2) {
+                    return NGX_IMAP_PARSE_INVALID_COMMAND;
+                }
+
+                state = sw_argument;
+                s->arg_start = p - 1;
+                break;
+            }
+            break;
+
+        /* the argument */
+        case sw_argument:
+            switch (ch) {
+            case ' ':
+            case CR:
+            case LF:
+                if (!(arg = ngx_array_push(&s->args))) {
+                    return NGX_ERROR;
+                }
+                arg->len = p - s->arg_start;
+                arg->data = s->arg_start;
+                s->arg_start = NULL;
+
+                switch (ch) {
+                case ' ':
+                    state = sw_spaces_before_argument;
+                    break;
+                case CR:
+                    state = sw_almost_done;
+                    break;
+                case LF:
+                    state = sw_done;
+                    break;
+                }
+                break;
+
+            default:
+                break;
+            }
+            break;
+
+        /* end of request line */
+        case sw_almost_done:
+            switch (ch) {
+            case LF:
+                state = sw_done;
+                break;
+            default:
+                return NGX_IMAP_PARSE_INVALID_COMMAND;
+            }
+            break;
 
         /* suppress warning */
         case sw_done:
@@ -64,5 +155,22 @@ ngx_int_t ngx_pop3_parse_command(ngx_ima
         }
     }
 
-    return NGX_OK;
+    s->buffer->pos = p;
+
+    if (state == sw_done) {
+        if (s->arg_start) {
+            if (!(arg = ngx_array_push(&s->args))) {
+                return NGX_ERROR;
+            }
+            arg->len = s->arg_end - s->arg_start;
+            arg->data = s->arg_start;
+            s->arg_start = NULL;
+        }
+
+        return NGX_OK;
+
+    } else {
+        s->state = state;
+        return NGX_AGAIN;
+    }
 }