httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From wr...@apache.org
Subject svn commit: r808795 - /httpd/mod_ftp/trunk/modules/ftp/ftp_commands.c
Date Fri, 28 Aug 2009 07:48:15 GMT
Author: wrowe
Date: Fri Aug 28 07:48:15 2009
New Revision: 808795

URL: http://svn.apache.org/viewvc?rev=808795&view=rev
Log:
Change ftp_cmd_list() to common_list(), and fold away ftp_cmd_nlst() into 
this common function by excluding appropriate code with the is_list arg.

No code change if I did this correctly.

Modified:
    httpd/mod_ftp/trunk/modules/ftp/ftp_commands.c

Modified: httpd/mod_ftp/trunk/modules/ftp/ftp_commands.c
URL: http://svn.apache.org/viewvc/httpd/mod_ftp/trunk/modules/ftp/ftp_commands.c?rev=808795&r1=808794&r2=808795&view=diff
==============================================================================
--- httpd/mod_ftp/trunk/modules/ftp/ftp_commands.c (original)
+++ httpd/mod_ftp/trunk/modules/ftp/ftp_commands.c Fri Aug 28 07:48:15 2009
@@ -650,9 +650,7 @@
     return FTP_REPLY_HELP_MESSAGE;
 }
 
-static int ftp_cmd_nlst(request_rec *r, const char *arg);
-
-static int ftp_cmd_list(request_rec *r, const char *arg)
+static int common_list(request_rec *r, const char *arg, int is_list)
 {
     ftp_connection *fc = ftp_get_module_config(r->connection->conn_config);
     conn_rec *c = r->connection;
@@ -687,13 +685,18 @@
     }
 
     /* Special FTPOption that maps NLST directly to LIST */
-    if ((fsc->options & FTP_OPT_LISTISNLST) && (!dashl)) {
-        return ftp_cmd_nlst(r, arg);
+    if (is_list && (fsc->options & FTP_OPT_LISTISNLST) && !dashl)
{
+        is_list = 0;
+    }
+    else
+    /* Special FTPOption that maps NLST directly to LIST */
+    if (!is_list && (fsc->options & FTP_OPT_NLSTISLIST) || dashl) {
+        is_list = 1;
     }
 
     arg = varg;
 
-    if (ap_strchr_c(arg, '*') != NULL) {
+    if (is_list && (ap_strchr_c(arg, '*') != NULL)) {
         /* Prevent DOS attacks, only allow one segment to have a wildcard */
         int found = 0;          /* The number of segments with a wildcard */
         const char *pos = arg;  /* Pointer for iterating over the string */
@@ -774,33 +777,41 @@
         return FTP_REPLY_CANNOT_OPEN_DATACONN;
     }
 
-    /*
-     * We have the directory tree, and its time to print it to the client.
-     * At this point we could have one of three things.
-     *
-     * 1. One entry, a directory.  Just print the contents
-     * 2. No directories.  Just print the contents.
-     * 3. Mixture.  Print files first, then directories.
-     */
+    if (is_list)
+    {
+        /*
+         * We have the directory tree, and its time to print it to the client.
+         * At this point we could have one of three things.
+         *
+         * 1. One entry, a directory.  Just print the contents
+         * 2. No directories.  Just print the contents.
+         * 3. Mixture.  Print files first, then directories.
+         */
 
-    /* Handle case 1 */
-    if (direntry->child && !direntry->next) {
-        direntry = direntry->child;
-    }
-    else {
-        /* Handle case 2 & 3 */
-        for (dirp = direntry; dirp; dirp = dirp->next) {
-            if (dirp->child)
-                decend = 1;
+        /* Handle case 1 */
+        if (direntry->child && !direntry->next) {
+            direntry = direntry->child;
+        }
+        else {
+            /* Handle case 2 & 3 */
+            for (dirp = direntry; dirp; dirp = dirp->next) {
+                if (dirp->child)
+                    decend = 1;
+            }
         }
     }
 
     bb = apr_brigade_create(r->pool, c->bucket_alloc);
 
-    /* Print the directory listing, skipping directories if needed */
-    for (dirp = direntry; dirp; dirp = dirp->next) {
-        if (dirp->modestring[0] == 'd' && decend) {
-            continue;
+    /* Print the directory listing, skipping directories as needed */
+    for (dirp = direntry; dirp; dirp = dirp->next)
+    {
+        if (dirp->modestring[0] == 'd')
+        {
+            if (is_list && decend) 
+                continue;
+            else if (!is_list && !(fsc->options & FTP_OPT_NLSTSHOWDIRS))
+                continue;
         }
 
         for (test = dirp->name; (sl = ap_strchr_c(test, '/')); test = sl + 1)
@@ -810,20 +821,25 @@
             continue;
         }
 
-        buf = apr_psprintf(r->pool,
-                           "%10s%5d %-8s %-8s%9" APR_OFF_T_FMT " %s %s"
-                           CRLF, dirp->modestring, dirp->nlink,
-                           dirp->username, dirp->groupname,
-                           dirp->size, dirp->datestring, dirp->name);
+        if (is_list)
+            buf = apr_psprintf(r->pool,
+                               "%10s%5d %-8s %-8s%9" APR_OFF_T_FMT " %s %s"
+                               CRLF, dirp->modestring, dirp->nlink,
+                               dirp->username, dirp->groupname,
+                               dirp->size, dirp->datestring, dirp->name);
+        else
+            buf = apr_psprintf(r->pool, "%s" CRLF, dirp->name);
+
         nbytes = strlen(buf);
         rv = apr_brigade_write(bb, ap_filter_flush, cdata->output_filters,
                                buf, nbytes);
         fc->traffic += nbytes;
     }
 
-    if (decend) {
+    if (is_list && decend) {
         for (dirp = direntry; dirp; dirp = dirp->next) {
-            if (dirp->modestring[0] == 'd' && dirp->child) {
+            if (dirp->modestring[0] == 'd' && dirp->child)
+            {
                 ftp_direntry *decend;
 
                 /* Iterate through the sub directory */
@@ -885,6 +901,16 @@
         return FTP_REPLY_DATA_CLOSE;
 }
 
+static int ftp_cmd_list(request_rec *r, const char *arg)
+{
+    return common_list(r, arg, 1);
+}
+
+static int ftp_cmd_nlst(request_rec *r, const char *arg)
+{
+    return common_list(r, arg, 0);
+}
+
 static int ftp_cmd_mdtm(request_rec *r, const char *arg)
 {
     ftp_connection *fc = ftp_get_module_config(r->connection->conn_config);
@@ -988,140 +1014,6 @@
     return FTP_REPLY_COMMAND_NOT_IMPL_PARAM;
 }
 
-static int ftp_cmd_nlst(request_rec *r, const char *arg)
-{
-    ftp_connection *fc = ftp_get_module_config(r->connection->conn_config);
-    conn_rec *c = r->connection;
-    ftp_server_config *fsc = ftp_get_module_config(r->server->module_config);
-    conn_rec *cdata;
-    request_rec *rr;
-    struct ftp_direntry *direntry, *dirp;
-    apr_bucket_brigade *bb;
-    apr_bucket *b;
-    char *word, *buf = NULL, *pattern;
-    apr_status_t rv;
-    apr_size_t nbytes;
-    char *varg = apr_pstrdup(r->pool, arg);
-    int dashl = 0;
-    const char *test, *sl;
-    int res;
-
-    while (*varg == '-') {
-        if (ftp_parse2(r->pool, varg, &word, &varg, FTP_KEEP_WHITESPACE)) {
-            varg = word;
-            break;
-        }
-        /* More Cowbell!  TODO: expand the accepted dash patterns */
-        if (ap_strchr(word, 'l')) {
-            dashl = 1;
-        }
-        /* -- 'end of dash-opts' by convention allows patterns like '-*' */
-        if (ap_strchr(word + 1, '-')) {
-            break;
-        }
-    }
-
-    /* Special FTPOption that maps NLST directly to LIST */
-    if (fsc->options & FTP_OPT_NLSTISLIST || (dashl)) {
-        return ftp_cmd_list(r, arg);
-    }
-
-    arg = varg;
-
-    if ((res = ftp_set_uri(r, arg))) {
-        return res;
-    }
-
-    /* Need to run intermediate subrequest to check for redirect */
-    rr = ap_sub_req_method_uri(r->method, r->uri, r, NULL);
-    if (rr->status == HTTP_MOVED_PERMANENTLY) {
-        ap_parse_uri(r, apr_pstrcat(r->pool, rr->uri, "/", NULL));
-
-        /* Rerun the subrequest with the new uri */
-        ap_destroy_sub_req(rr);
-        rr = ap_sub_req_method_uri(r->method, r->uri, r, NULL);
-    }
-
-    if (rr->status != HTTP_OK) {
-        fc->response_notes = apr_psprintf(r->pool, FTP_MSG_PERM_DENIED,
-                                 ftp_escape_control_text(r->parsed_uri.path,
-                                                         r->pool));
-        ap_destroy_sub_req(rr);
-        return FTP_REPLY_FILE_NOT_FOUND;
-    }
-    ap_destroy_sub_req(rr);
-
-    if (arg[0] == '\0') {
-        pattern = apr_pstrcat(r->pool, r->filename, "/*", NULL);
-    }
-    else {
-        pattern = r->filename;
-    }
-
-#ifdef FTP_DEBUG
-    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "Pattern: %s", pattern);
-#endif
-
-    /* Construct the sorted array of directory contents */
-    if ((direntry = ftp_direntry_get(r, pattern)) == NULL) {
-        fc->response_notes = apr_psprintf(r->pool, FTP_MSG_NOSUCHFILE,
-                                 ftp_escape_control_text(arg, r->pool));
-
-        return FTP_REPLY_FILE_NOT_FOUND;
-    }
-
-    fc->response_notes = FTP_MSG_OPENASCII;
-    ftp_send_response(r, FTP_REPLY_FILE_STATUS_OK);
-
-    if (!(cdata = ftp_open_dataconn(r, 1))) {
-        return FTP_REPLY_CANNOT_OPEN_DATACONN;
-    }
-
-    bb = apr_brigade_create(r->pool, c->bucket_alloc);
-
-    /* Print the directory listing, skipping directories if needed */
-    for (dirp = direntry; dirp; dirp = dirp->next) {
-        if (!(fsc->options & FTP_OPT_NLSTSHOWDIRS) 
-                && dirp->modestring[0] == 'd') {
-            continue;
-        }
-
-        for (test = dirp->name; (sl = ap_strchr_c(test, '/')); test = sl + 1)
-             /* noop */ ;
-
-        if (!strcmp(".", test)) {
-            continue;
-        }
-
-        buf = apr_psprintf(r->pool, "%s" CRLF, dirp->name);
-        nbytes = strlen(buf);
-        rv = apr_brigade_write(bb, ap_filter_flush, cdata->output_filters, 
-                               buf, nbytes);
-        fc->traffic += nbytes;
-    }
-
-    /* If the brigade is empty, just send an eos */
-    if (APR_BRIGADE_EMPTY(bb)) {
-        b = apr_bucket_eos_create(c->bucket_alloc);
-        APR_BRIGADE_INSERT_TAIL(bb, b);
-    }
-
-    /* Flush the brigade down the filter chain */
-    b = apr_bucket_flush_create(cdata->bucket_alloc);
-    APR_BRIGADE_INSERT_TAIL(bb, b);
-    ap_pass_brigade(cdata->output_filters, bb);
-
-    ap_lingering_close(cdata);
-    fc->datasock = NULL;
-
-    fc->transfers++;
-
-    if (cdata->aborted)
-        return FTP_REPLY_TRANSFER_ABORTED;
-    else
-        return FTP_REPLY_DATA_CLOSE;
-}
-
 static int ftp_cmd_noop(request_rec *r, const char *arg)
 {
     ftp_connection *fc = ftp_get_module_config(r->connection->conn_config);



Mime
View raw message