httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From r...@apache.org
Subject svn commit: r389342 - in /httpd/mod_smtpd/trunk/modules/queue: Makefile.am smtp/mod_smtpd_queue_smtp.c
Date Tue, 28 Mar 2006 01:11:31 GMT
Author: rian
Date: Mon Mar 27 17:11:29 2006
New Revision: 389342

URL: http://svn.apache.org/viewcvs?rev=389342&view=rev
Log:
Updated SMTP forwarding module to work with new mod_smtpd API.


Modified:
    httpd/mod_smtpd/trunk/modules/queue/Makefile.am
    httpd/mod_smtpd/trunk/modules/queue/smtp/mod_smtpd_queue_smtp.c

Modified: httpd/mod_smtpd/trunk/modules/queue/Makefile.am
URL: http://svn.apache.org/viewcvs/httpd/mod_smtpd/trunk/modules/queue/Makefile.am?rev=389342&r1=389341&r2=389342&view=diff
==============================================================================
--- httpd/mod_smtpd/trunk/modules/queue/Makefile.am (original)
+++ httpd/mod_smtpd/trunk/modules/queue/Makefile.am Mon Mar 27 17:11:29 2006
@@ -1,2 +1,2 @@
 # disabled for now
-#SUBDIRS = postfix smtp
+SUBDIRS = smtp

Modified: httpd/mod_smtpd/trunk/modules/queue/smtp/mod_smtpd_queue_smtp.c
URL: http://svn.apache.org/viewcvs/httpd/mod_smtpd/trunk/modules/queue/smtp/mod_smtpd_queue_smtp.c?rev=389342&r1=389341&r2=389342&view=diff
==============================================================================
--- httpd/mod_smtpd/trunk/modules/queue/smtp/mod_smtpd_queue_smtp.c (original)
+++ httpd/mod_smtpd/trunk/modules/queue/smtp/mod_smtpd_queue_smtp.c Mon Mar 27 17:11:29 2006
@@ -54,122 +54,13 @@
   return apr_pcalloc(p, sizeof(smtpd_queue_smtp_config));
 }
 
-/* pull the message body out of the spool file and write it to a socket,
- * one line at a time, doing the smtp dot encoding as we go. */
-static apr_status_t send_body(smtpd_conn_rec *scr,
-                              apr_socket_t *sock,
-                              apr_pool_t *pool)
-{
-    apr_status_t rv = APR_SUCCESS;
-    apr_bucket_brigade *bb, *tb;
-    char line[BUFFER_LEN];
-    apr_size_t nbytes;
-    apr_finfo_t finfo;
-
-    rv = apr_file_info_get(&finfo, APR_FINFO_SIZE, scr->transaction->tfp);
-    if (rv)
-        return rv;
-
-    bb = apr_brigade_create(pool, scr->c->bucket_alloc);
-    tb = apr_brigade_create(pool, scr->c->bucket_alloc);
-
-    APR_BRIGADE_INSERT_TAIL(
-        bb, apr_bucket_file_create(scr->transaction->tfp,
-                                   scr->transaction->body_offset,
-                                   finfo.size - scr->transaction->body_offset,
-                                   pool, scr->c->bucket_alloc)
-    );
-
-    /* loop over the lines in the file, writing them to the socket and
-     * dealing with single-period lines as we see them. */
-    for (;;) {
-        if (APR_BRIGADE_EMPTY(bb))
-            break;
-
-        memset(line, 0, sizeof(line));
-
-        rv = apr_brigade_split_line(tb, bb, APR_BLOCK_READ, sizeof(line));
-        if (rv)
-            break;
-
-        nbytes = sizeof(line);
-
-        apr_brigade_flatten(tb, line, &nbytes);
-
-        if (line[0] == '.' && line[1] == '\0') {
-            nbytes = 2;
-
-            rv = apr_socket_send(sock, "..", &nbytes);
-        } else {
-            nbytes = strlen(line);
-
-            rv = apr_socket_send(sock, line, &nbytes);
-        }
-
-        if (rv)
-            break;
-
-        apr_brigade_cleanup(tb);
-    }
-
-    apr_brigade_destroy(bb);
-    apr_brigade_destroy(tb);
-
-    /* now finish things off with a single period. */
-    if (! rv) {
-        nbytes = 3;
-
-        rv = apr_socket_send(sock, ".\r\n", &nbytes);
-    }
-
-    return rv;
-}
-
-/* read and parse a line of response from the server, returning the response
- * code in *respcode and the response text in *resptext.  the line is placed
- * in buffer, which is buflen bytes long. */
-static apr_status_t read_response(int *respcode,
-                                  char **resptext,
-                                  apr_bucket_brigade *bb,
-                                  apr_bucket_brigade *tb,
-                                  char *buffer,
-                                  apr_size_t buflen)
-{
-    apr_status_t rv = APR_SUCCESS;
-    apr_size_t nbytes;
-    char *text;
-
-    rv = apr_brigade_split_line(tb, bb, APR_BLOCK_READ, buflen);
-    if (rv)
-        return rv;
-
-    nbytes = buflen;
-
-    apr_brigade_flatten(tb, buffer, &nbytes);
-
-    apr_brigade_cleanup(tb);
-
-    *respcode = atoi(buffer);
-
-    text = strchr(buffer, ' ');
-
-    if (text)
-      *resptext = text + 1;
-    else
-      *resptext = NULL;
-
-    return rv;
-}
-
-/* Queue a message by sending it to a remote server for delivery.
- *
- * TODO: errors when sending mail on to the remote server should propogate
- *       back to the sender. */
-static smtpd_retcode queue_message(smtpd_conn_rec *scr, smtpd_return_data *in)
+/* Queue a message by sending it to a remote server for delivery. */
+static smtpd_retcode queue_message(smtpd_session_rec *scr)
 {
     apr_status_t apr_err = APR_SUCCESS;
     smtpd_retcode rv = SMTPD_DECLINED;
     apr_pool_t *subpool;
+    apr_bucket_brigade *body;
 
     smtpd_queue_smtp_config *cfg = ap_get_module_config(
         scr->s->module_config, &smtpd_queue_smtp_module
@@ -194,261 +85,78 @@
                      "Queuing message to smtp://%s:%d", cfg->host, cfg->port);
     }
 
-    apr_pool_create(&subpool, scr->p);
-
-    /* note: this is perhaps the stupidest SMTP client implementation
-     *       ever, i appologize for it profusely, but it's the minimum
-     *       we can get away with and still have this work. */
-
-    do {
-        apr_bucket_brigade *bb, *tb;
-        char line[BUFFER_LEN];
-        apr_sockaddr_t *saddr;
-        apr_socket_t *sock;
-        apr_size_t nbytes;
-        char *text;
-        int resp;
-        int i;
-
-        apr_err = apr_sockaddr_info_get(&saddr, cfg->host, APR_UNSPEC,
-                                        cfg->port, 0, subpool);
-        if (apr_err)
-            break;
-
-        /* open a connection to our target server. */
-        apr_err = apr_socket_create(&sock, saddr->family, SOCK_STREAM, 0,
-                                    subpool);
-        if (apr_err)
-            break;
-
-        apr_err = apr_socket_connect(sock, saddr);
-        if (apr_err)
-            break;
-
-        /* wrap a bucket brigade around our socket so we can easily read
-         * a line at a time from it. */
-        bb = apr_brigade_create(subpool, scr->c->bucket_alloc);
-
-        APR_BRIGADE_INSERT_TAIL(
-            bb, apr_bucket_socket_create(sock, scr->c->bucket_alloc)
-        );
-
-        tb = apr_brigade_create(subpool, scr->c->bucket_alloc);
-
-        apr_err = read_response(&resp, &text, bb, tb, line, sizeof(line));
-        if (apr_err)
-            break;
-
-        if (resp != 220) {
-            ap_log_error(APLOG_MARK, APLOG_ERR, 0, scr->s,
-                         "bad response from smtp server: "
-                         "got %d, expected 220", resp);
-
-            ap_log_error(APLOG_MARK, APLOG_ERR, 0, scr->s,
-                         "server said '%s'", text);
-            break;
-        }
-
-        nbytes = 16;
-
-        /* say hello to the server. */
-
-        {
-          struct iovec vec[3];
-
-          vec[0].iov_base = "HELO ";
-          vec[0].iov_len = 5;
-
-          vec[1].iov_base = scr->s->server_hostname;
-          vec[1].iov_len = strlen(scr->s->server_hostname);
-
-          vec[2].iov_base = "\r\n";
-          vec[2].iov_len = 2;
-
-          apr_err = apr_socket_sendv(sock, vec, 3, &nbytes);
-          if (apr_err)
-              break;
-        }
-
-        apr_err = read_response(&resp, &text, bb, tb, line, sizeof(line));
-        if (apr_err)
-            break;
-
-        if (resp != 250) {
-            ap_log_error(APLOG_MARK, APLOG_ERR, 0, scr->s,
-                         "bad response from smtp server: "
-                         "got %d, expected 250", resp);
-            ap_log_error(APLOG_MARK, APLOG_ERR, 0, scr->s,
-                         "server said '%s'", text);
-            break;
-        }
-
-        /* identify the sender. */
-
-        {
-            struct iovec vec[3];
-
-            vec[0].iov_base = "MAIL FROM:<";
-            vec[0].iov_len = 11;
-
-            vec[1].iov_base = scr->transaction->mail_from;
-            vec[1].iov_len = strlen(scr->transaction->mail_from);
-
-            vec[2].iov_base = ">\r\n";
-            vec[2].iov_len = 3;
-
-            apr_err = apr_socket_sendv(sock, vec, 3, &nbytes);
-            if (apr_err)
-                break;
-        }
-
-        apr_err = read_response(&resp, &text, bb, tb, line, sizeof(line));
-        if (apr_err)
-            break;
-
-        if (resp != 250) {
-            ap_log_error(APLOG_MARK, APLOG_ERR, 0, scr->s,
-                         "bad response from smtp server: "
-                         "got %d, expected 250", resp);
-
-            ap_log_error(APLOG_MARK, APLOG_ERR, 0, scr->s,
-                         "server said '%s'", text);
-            break;
-        }
-
-        /* tell the server who we're sending the message to. */
-
-        for (i = 0; i < scr->transaction->rcpt_to->nelts; ++i) {
-            struct iovec vec[3];
-
-            char *to = APR_ARRAY_IDX(scr->transaction->rcpt_to, i, char *);
-
-            vec[0].iov_base = "RCPT TO:<";
-            vec[0].iov_len = 9;
-
-            vec[1].iov_base = to;
-            vec[1].iov_len = strlen(to);
-
-            vec[2].iov_base = ">\r\n";
-            vec[2].iov_len = 3;
-
-            apr_err = apr_socket_sendv(sock, vec, 3, &nbytes);
-            if (apr_err)
-                break;
-
-            apr_err = read_response(&resp, &text, bb, tb, line, sizeof(line));
-            if (apr_err)
-                break;
-
-            if (resp != 250 && resp != 251) {
-                ap_log_error(APLOG_MARK, APLOG_ERR, 0, scr->s,
-                             "bad response from smtp server: "
-                             "got %d, expected 250 or 251", resp);
-
-                ap_log_error(APLOG_MARK, APLOG_ERR, 0, scr->s,
-                             "server said '%s'", text);
-
-                apr_err = APR_EINVAL;
+    body = apr_brigade_create(scr->per_command_pool, scr->c->bucket_alloc);
 
-                break;
-            }
-        }
-
-        /* if we ended up with an error from the loop bail. */
-        if (apr_err)
-            break;
-
-        /* now start the actual contents of the message. */
-
-        nbytes = 6;
-
-        apr_err = apr_socket_send(sock, "DATA\r\n", &nbytes);
-        if (apr_err)
-            break;
-
-        apr_err = read_response(&resp, &text, bb, tb, line, sizeof(line));
-        if (apr_err)
-            break;
-
-        if (resp != 354) {
-            ap_log_error(APLOG_MARK, APLOG_ERR, 0, scr->s,
-                         "bad response from smtp server: "
-                         "got %d, expected 354", resp);
-
-            ap_log_error(APLOG_MARK, APLOG_ERR, 0, scr->s,
-                         "server said '%s'", text);
-            break;
-        }
-
-        /* first we send the headers. */
-
-        {
-            const apr_array_header_t *arr;
-            const apr_table_entry_t *elts;
-
-            arr = apr_table_elts(scr->transaction->headers);
-            elts = (const apr_table_entry_t *) arr->elts;
+    /* first add on headers */
 
-            for (i = 0; i < arr->nelts; ++i) {
-                struct iovec vec[4];
-
-                vec[0].iov_base = elts[i].key;
-                vec[0].iov_len = strlen(elts[i].key);
-
-                vec[1].iov_base = ": ";
-                vec[1].iov_len = 2;
-
-                vec[2].iov_base = elts[i].val;
-                vec[2].iov_len = strlen(elts[i].val);
+    {
+        const apr_array_header_t *arr;
+        const apr_table_entry_t *elts;
+        apr_bucket *bucket;
+        int i;
 
-                vec[3].iov_base = "\r\n";
-                vec[3].iov_len = 2;
+        arr = apr_table_elts(scr->envelope->headers);
+        elts = (const apr_table_entry_t *) arr->elts;
 
-                apr_err = apr_socket_sendv(sock, vec, 4, &nbytes);
-                if (apr_err)
-                    break;
-            }
+        for (i = 0; i < arr->nelts; ++i) {
+            char *bucket_str = apr_pstrcat(scr->per_command_pool,
+                                           elts[i].key, ": ", elts[i].val,
+                                           "\r\n", NULL);
+            bucket = apr_bucket_pool_create(bucket_str,
+                                            strlen(bucket_str),
+                                            scr->per_command_pool,
+                                            scr->c->bucket_alloc);
 
-            if (apr_err)
-                break;
+            APR_BRIGADE_INSERT_TAIL(body, bucket);
         }
 
-        /* then finally the body. */
+        bucket = apr_bucket_immortal_create("\r\n", 2, scr->c->bucket_alloc);
 
-        apr_err = send_body(scr, sock, subpool);
-        if (apr_err)
-            break;
+        APR_BRIGADE_INSERT_TAIL(body, bucket);
+    }
 
-        apr_err = read_response(&resp, &text, bb, tb, line, sizeof(line));
-        if (apr_err)
-            break;
+    /* now add on body */
+    {
+        apr_finfo_t finfo;
+        apr_err = apr_file_info_get(&finfo, 
+                                    APR_FINFO_SIZE, scr->envelope->tfp);
+        
+        APR_BRIGADE_INSERT_TAIL(
+            body, apr_bucket_file_create(scr->envelope->tfp,
+                                         0,
+                                         finfo.size,
+                                         scr->per_command_pool,
+                                         scr->c->bucket_alloc));
+    }
 
-        if (resp != 250) {
-            ap_log_error(APLOG_MARK, APLOG_ERR, 0, scr->s,
-                         "bad response from smtp server: "
-                         "got %d, expected 250", resp);
+    smtpd_send_message(scr->s, scr->per_command_pool,
+                       cfg->host, cfg->port, scr->envelope->mail_from,
+                       apr_table_elts(scr->envelope->rcpt_to), body);
+
+    /* set queued flags */
+    {
+        const apr_array_header_t *arr;
+        const apr_table_entry_t *elts;
+        int i;
+        
+        arr = apr_table_elts(scr->envelope->rcpt_to);
+        elts = (const apr_table_entry_t *) arr->elts;
 
-            ap_log_error(APLOG_MARK, APLOG_ERR, 0, scr->s,
-                         "server said '%s'", text);
-            break;
+        for (i = 0; i < arr->nelts; ++i) {
+            apr_table_set(scr->envelope->rcpt_to, elts[i].key, "queued");
         }
-
-        /* if we made it this far the message has been sent, call it a day */
-        rv = SMTPD_OK;
-    } while (0);
+    }
 
     if (apr_err)
         ap_log_error(APLOG_MARK, APLOG_ERR, apr_err, scr->s,
                      "Error queuing to smtp server");
 
-    apr_pool_destroy(subpool);
-
-    return rv;
+    return SMTPD_OK;
 }
 
 static void smtpd_queue_smtp_register_hooks(apr_pool_t * p)
 {
-    APR_OPTIONAL_HOOK(smtpd, queue, queue_message, NULL, NULL, APR_HOOK_FIRST);
+    smtpd_hook_on_queue(queue_message, NULL, NULL, APR_HOOK_LAST);
 }
 
 static const char *enable_queue_smtp(cmd_parms *cmd,



Mime
View raw message