httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From wr...@apache.org
Subject svn commit: r793756 - in /httpd/mod_ftp/trunk: STATUS-FTP include/mod_ftp.h modules/ftp/ftp_commands.c modules/ftp/ftp_internal.h modules/ftp/ftp_protocol.c modules/ftp/mod_ftp.c
Date Mon, 13 Jul 2009 23:54:05 GMT
Author: wrowe
Date: Mon Jul 13 23:54:04 2009
New Revision: 793756

URL: http://svn.apache.org/viewvc?rev=793756&view=rev
Log:
Refactor HELP and FEAT to work around a roadblock.  This patch further;

  * introduces FTP_NO_HELP for commands registered for the FEAT list only

  * introduces FTP_NEW_FEAT for commands which must be reported via FEAT

  * adds REST STREAM, EPRT, EPSV to the FEAT results as required by spec

  * drops HELP mention of experimental LPRT/LPSV and antique MAIL commands


Modified:
    httpd/mod_ftp/trunk/STATUS-FTP
    httpd/mod_ftp/trunk/include/mod_ftp.h
    httpd/mod_ftp/trunk/modules/ftp/ftp_commands.c
    httpd/mod_ftp/trunk/modules/ftp/ftp_internal.h
    httpd/mod_ftp/trunk/modules/ftp/ftp_protocol.c
    httpd/mod_ftp/trunk/modules/ftp/mod_ftp.c

Modified: httpd/mod_ftp/trunk/STATUS-FTP
URL: http://svn.apache.org/viewvc/httpd/mod_ftp/trunk/STATUS-FTP?rev=793756&r1=793755&r2=793756&view=diff
==============================================================================
--- httpd/mod_ftp/trunk/STATUS-FTP (original)
+++ httpd/mod_ftp/trunk/STATUS-FTP Mon Jul 13 23:54:04 2009
@@ -39,18 +39,7 @@
 
 RELEASE SHOWSTOPPERS:
 
-  * (1.0 stopper) - API change, the register new function should take an
-    arguement suitable for display in the FEAT response, such that the
-    implementor of FOO could display OPT1,OPT2 to FEAT.  The immediate
-    case for this API change is registration of the EPRT/EPSV commands
-    (and essentially, anything that appears after RFC 959).
-
-  * (1.0 stopper) - API change, OPTS needs to be implemented and extensible,
-    such that various registered command handlers accept their corresponding
-    OPTS behavior.  RFC 2389 further requires that OPTS is implemented when
-    ever FEAT is implemented, so this implementation is nonconforming.
-    Consider a few other commands such as AUTH might need sub-delegation
-    facilities, as well.
+
 
 CURRENT RELEASE NOTES:
 

Modified: httpd/mod_ftp/trunk/include/mod_ftp.h
URL: http://svn.apache.org/viewvc/httpd/mod_ftp/trunk/include/mod_ftp.h?rev=793756&r1=793755&r2=793756&view=diff
==============================================================================
--- httpd/mod_ftp/trunk/include/mod_ftp.h (original)
+++ httpd/mod_ftp/trunk/include/mod_ftp.h Mon Jul 13 23:54:04 2009
@@ -211,11 +211,19 @@
  * FTP_TAKE1 - This command takes a single argument.
  * FTP_NEED_LOGIN - The user needs to be logged in to execute this command.
  * FTP_DATA_INTR - The current data transfer is interrupted by this command.
+ * FTP_NEW_FEAT - This command was introduced following RFC 2389, show in FEAT list
+ *                Register a NULL hook function for extended names with spaces
+ *                E.g. register "AUTH" with a hook function, and also register 
+ *                "AUTH TLS" as the specific FTP_NEW_FEAT with a NULL hook function.
+ * FTP_NO_HELP - Implicit if the command key contains a space, this flag omits 
+ *               a given FTP command from the HELP listing.
  */
 #define FTP_TAKE0            (1 << 0)
 #define FTP_TAKE1            (1 << 1)
 #define FTP_NEED_LOGIN       (1 << 2)
 #define FTP_DATA_INTR        (1 << 3)
+#define FTP_NEW_FEAT         (1 << 4)
+#define FTP_NO_HELP          (1 << 5)
 
 /* FTP command handler ordering */
 #define FTP_HOOK_FIRST  10

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=793756&r1=793755&r2=793756&view=diff
==============================================================================
--- httpd/mod_ftp/trunk/modules/ftp/ftp_commands.c (original)
+++ httpd/mod_ftp/trunk/modules/ftp/ftp_commands.c Mon Jul 13 23:54:04 2009
@@ -43,6 +43,27 @@
 
 static apr_hash_t *FTPMethodHash;
 static apr_pool_t *FTPMethodPool;
+static const char *FTPHelpText;
+static apr_size_t  FTPHelpTextLen;
+static const char *FTPFeatText;
+static apr_size_t  FTPFeatTextLen;
+
+/*
+ * The FTP command structure contains useful information about the FTP
+ * handler.  This information is filled out when a command is registered
+ * using ftp_hook_cmd(), which also puts the handler into the global hash.
+ */
+typedef struct ftp_cmd_entry
+{
+    const char *key;             /* The key, e.g. "DELE" */
+    ftp_hook_fn *pf;             /* Pointer to the handler */
+    const char *alias;           /* The aliased command e.g. "CDUP" */
+    int order;                   /* Handler ordering */
+    int flags;                   /* Flags for this command.  See FTP_CMD_ */
+    const char *help;            /* Help string for this command */
+    struct ftp_cmd_entry *next;  /* Pointer to the next handler */
+} ftp_cmd_entry;
+
 
 FTP_DECLARE(void) ftp_hook_cmd_any(const char *key, ftp_hook_fn *pf,
                                    const char *alias, int order,
@@ -56,6 +77,12 @@
     key = apr_pstrdup(FTPMethodPool, key);
     help = apr_pstrdup(FTPMethodPool, help);
 
+    /* Commands with a space are only for FTP_NEW_FEAT display, so
+     * we fix this display bit for convenience at registration time
+     */
+    if (strchr(key, ' '))
+        flags |= FTP_NO_HELP;
+
     cmd->key = key;
     cmd->pf = pf;
     cmd->alias = alias;
@@ -182,6 +209,50 @@
     return key;
 }
 
+void ftp_cmd_finalize(apr_pool_t *pool, apr_pool_t *ptemp)
+{
+    ftp_cmd_entry *cmd, *basecmd;
+    apr_hash_index_t *hi;
+    void *val;
+    int i;
+
+    FTPHelpText = apr_psprintf(ptemp, "%d-%s", FTP_REPLY_HELP_MESSAGE,
+                               "The following commands are recognized "
+                               "(* =>'s unimplemented).");
+
+    FTPFeatText = apr_psprintf(ptemp, "%d-%s", FTP_REPLY_SYSTEM_STATUS,
+                               "Extensions supported");
+
+    for (hi = apr_hash_first(ptemp, FTPMethodHash), i = 0; hi;
+         hi = apr_hash_next(hi), i++)
+    {
+        apr_hash_this(hi, NULL, NULL, &val);
+        cmd = (struct ftp_cmd_entry *) val;
+
+        if (cmd->alias)
+            basecmd = apr_hash_get(FTPMethodHash, cmd->alias, APR_HASH_KEY_STRING);
+        else
+            basecmd = cmd;
+
+        if (!(cmd->flags & FTP_NO_HELP))
+            FTPHelpText = apr_psprintf(ptemp, "%s%s   %c%-4s",
+                                       FTPHelpText, (i % 8) ? "" : CRLF,
+                                       (basecmd->pf) ? ' ' : '*', cmd->key);
+        else
+            --i;
+
+        if (cmd->flags & FTP_NEW_FEAT)
+            FTPFeatText = apr_pstrcat(ptemp, FTPFeatText, CRLF " ", 
+                                      cmd->key, NULL);
+    }
+
+    FTPHelpText = apr_pstrcat(pool, FTPHelpText, CRLF, NULL);
+    FTPHelpTextLen = strlen(FTPHelpText);
+
+    FTPFeatText = apr_pstrcat(pool, FTPFeatText, CRLF, NULL);
+    FTPFeatTextLen = strlen(FTPFeatText);
+}
+
 /* ftp_parse2: Parse a FTP request that is expected to have 2 arguments.
  *
  * Arguments: pool - Pool to allocate from
@@ -500,6 +571,21 @@
 
 static int ftp_cmd_feat(request_rec *r, const char *arg)
 {
+    ftp_connection *fc = ftp_get_module_config(r->connection->conn_config);
+    conn_rec *c = r->connection;
+    apr_bucket_brigade *bb;
+    apr_bucket *b;
+
+    bb = apr_brigade_create(r->pool, c->bucket_alloc);
+    b = apr_bucket_immortal_create(FTPFeatText, FTPFeatTextLen, c->bucket_alloc);
+    APR_BRIGADE_INSERT_TAIL(bb, b);
+    fc->traffic += FTPFeatTextLen;
+
+    b = apr_bucket_flush_create(c->bucket_alloc);
+    APR_BRIGADE_INSERT_TAIL(bb, b);
+    ap_pass_brigade(c->output_filters, bb);
+
+    fc->response_notes = "End";
     return FTP_REPLY_SYSTEM_STATUS;
 }
 
@@ -507,9 +593,10 @@
 {
     ftp_connection *fc = ftp_get_module_config(r->connection->conn_config);
     conn_rec *c = r->connection;
+    apr_bucket_brigade *bb;
+    apr_bucket *b;
     ftp_cmd_entry *cmd;
-    int i;
-    char *method, *buf = "";
+    char *method;
 
     if (*arg) {
         method = ftp_toupper(r->pool, arg);
@@ -525,65 +612,20 @@
             return FTP_REPLY_COMMAND_NOT_IMPLEMENTED;
         }
     }
-    else {
-        apr_status_t rv;
-        apr_bucket_brigade *bb;
-        apr_hash_index_t *hi;
-        ftp_cmd_entry *cmd;
-        apr_size_t nbytes;
-        apr_bucket *b;
-        void *val;
-        char supported;
-
-        buf = apr_psprintf(r->pool, "%d-%s" CRLF, FTP_REPLY_HELP_MESSAGE,
-                           "The following commands are recognized "
-                           "(* =>'s unimplemented).");
-
-        for (hi = apr_hash_first(r->pool, FTPMethodHash), i = 0; hi;
-             hi = apr_hash_next(hi), i++) {
-
-            apr_hash_this(hi, NULL, NULL, &val);
-            cmd = (struct ftp_cmd_entry *) val;
-
-            if (cmd->alias) {
-                ftp_cmd_entry *basecmd;
-                basecmd = apr_hash_get(FTPMethodHash, cmd->alias, APR_HASH_KEY_STRING);
-
-                if (basecmd && basecmd->pf)
-                    supported = ' ';
-                else
-                    supported = '*';
-            }
-            else if (cmd->pf)
-                supported = ' ';
-            else
-                supported = '*';
-
-            method = apr_psprintf(r->pool, "   %c%-4s",
-                                  supported, cmd->key);
 
-            buf = apr_pstrcat(r->pool, buf, method, NULL);
-
-            if (((i + 1) % 8) == 0)
-                buf = apr_pstrcat(r->pool, buf, CRLF, NULL);
-        }
-
-        buf = apr_pstrcat(r->pool, buf, CRLF, NULL);
-
-        bb = apr_brigade_create(r->pool, c->bucket_alloc);
-        nbytes = strlen(buf);
-        rv = apr_brigade_write(bb, ap_filter_flush, r->output_filters,
-                               buf, nbytes);
-        fc->traffic += nbytes;
+    /* given no argument, pre-prepared HELP message */
+    bb = apr_brigade_create(r->pool, c->bucket_alloc);
+    b = apr_bucket_immortal_create(FTPHelpText, FTPHelpTextLen, c->bucket_alloc);
+    APR_BRIGADE_INSERT_TAIL(bb, b);
+    fc->traffic += FTPHelpTextLen;
 
-        b = apr_bucket_flush_create(c->bucket_alloc);
-        APR_BRIGADE_INSERT_TAIL(bb, b);
-        ap_pass_brigade(c->output_filters, bb);
+    b = apr_bucket_flush_create(c->bucket_alloc);
+    APR_BRIGADE_INSERT_TAIL(bb, b);
+    ap_pass_brigade(c->output_filters, bb);
 
-        fc->response_notes = apr_psprintf(r->pool, FTP_MSG_HELP,
-                                          r->server->server_admin);
-        return FTP_REPLY_HELP_MESSAGE;
-    }
+    fc->response_notes = apr_psprintf(r->pool, FTP_MSG_HELP,
+                                      r->server->server_admin);
+    return FTP_REPLY_HELP_MESSAGE;
 }
 
 static int ftp_cmd_nlst(request_rec *r, const char *arg);
@@ -2344,11 +2386,12 @@
     }
     else {
         /*
-         * XXX: big bug - going back to the beginning.  We should compute
-         * size rather than stating the file... this could be done trivially
-         * with a request to a null 'data' port which simply counts up the
-         * bytes.  Will be implemented as a special-case of the ftp_core_data
+         * XXX: big bug - going back to the beginning.  We must compute size
+         * rather than stating the file... this could be done trivially with
+         * a request to a null 'data' port which simply counts up the bytes.
+         * Will be implemented as a special-case of the ftp_core_data
          * connection endpoint-filter.
+         * See RFC3659 - especially with respect to TYPE A/I
          */
         fc->response_notes = apr_psprintf(r->pool, "%" APR_OFF_T_FMT,
                                           rr->finfo.size);
@@ -2840,6 +2883,11 @@
                  FTP_TAKE1,
                  "<sp> mechanism-name");
 
+    /* Register the AUTH TLS mechanism for FEAT advertising */
+    ftp_hook_cmd("AUTH TLS", NULL, FTP_HOOK_LAST,
+                 FTP_NEW_FEAT,
+                 "<sp> mechanism-name");
+
     ftp_hook_cmd("CDUP", ftp_cmd_cdup, FTP_HOOK_LAST,
                  FTP_NEED_LOGIN | FTP_TAKE0,
                  "change to parent directory");
@@ -2853,15 +2901,15 @@
                  "<sp> file-name");
 
     ftp_hook_cmd("EPRT", ftp_cmd_eprt, FTP_HOOK_LAST,
-                 FTP_NEED_LOGIN | FTP_TAKE1,
+                 FTP_NEED_LOGIN | FTP_TAKE1 | FTP_NEW_FEAT,
                  "<sp> <d>af<d>addr<d>port<d>");
 
     ftp_hook_cmd("EPSV", ftp_cmd_epsv, FTP_HOOK_LAST,
-                 FTP_NEED_LOGIN | FTP_TAKE0 | FTP_TAKE1,
+                 FTP_NEED_LOGIN | FTP_TAKE0 | FTP_TAKE1 | FTP_NEW_FEAT,
                  "[ <sp> af|ALL ]");
 
     ftp_hook_cmd("FEAT", ftp_cmd_feat, FTP_HOOK_LAST,
-                 FTP_NEED_LOGIN | FTP_TAKE0,
+                 FTP_TAKE0,
                  "show server features");
 
     ftp_hook_cmd("HELP", ftp_cmd_help, FTP_HOOK_LAST,
@@ -2872,46 +2920,18 @@
                  FTP_NEED_LOGIN | FTP_TAKE0 | FTP_TAKE1,
                  "[ <sp> path-name ]");
 
-    ftp_hook_cmd("LPRT", NULL, FTP_HOOK_LAST,
-                 FTP_NEED_LOGIN | FTP_TAKE1,
-                 "<sp> af, hal, h1, h2, h3,..., pal, p1, p2...");
-
-    ftp_hook_cmd("LPSV", NULL, FTP_HOOK_LAST,
-                 FTP_NEED_LOGIN | FTP_TAKE0,
-                 "(set server in passive mode)");
-
-    ftp_hook_cmd("MAIL", NULL, FTP_HOOK_LAST,
-                 FTP_NEED_LOGIN | FTP_TAKE0,
-                 "(mail to user)");
-
     ftp_hook_cmd("MDTM", ftp_cmd_mdtm, FTP_HOOK_LAST,
-                 FTP_NEED_LOGIN | FTP_TAKE1,
+                 FTP_NEED_LOGIN | FTP_TAKE1 | FTP_NEW_FEAT,
                  "<sp> path-name");
 
     ftp_hook_cmd("MKD", ftp_cmd_mkd, FTP_HOOK_LAST,
                  FTP_NEED_LOGIN | FTP_TAKE1,
                  "<sp> path-name");
 
-    ftp_hook_cmd("MLFL", NULL, FTP_HOOK_LAST,
-                 FTP_NEED_LOGIN | FTP_TAKE0,
-                 "(mail file)");
-
     ftp_hook_cmd("MODE", NULL, FTP_HOOK_LAST,
                  FTP_NEED_LOGIN | FTP_TAKE0,
                  "(specify transfer mode)");
 
-    ftp_hook_cmd("MSAM", NULL, FTP_HOOK_LAST,
-                 FTP_NEED_LOGIN | FTP_TAKE0,
-                 "(mail send to terminal and mailbox)");
-
-    ftp_hook_cmd("MSND", NULL, FTP_HOOK_LAST,
-                 FTP_NEED_LOGIN | FTP_TAKE0,
-                 "(mail send to terminal)");
-
-    ftp_hook_cmd("MSOM", NULL, FTP_HOOK_LAST,
-                 FTP_NEED_LOGIN | FTP_TAKE0,
-                 "(mail send to terminal or mailbox");
-
     ftp_hook_cmd("NLST", ftp_cmd_nlst, FTP_HOOK_LAST,
                  FTP_NEED_LOGIN | FTP_TAKE0 | FTP_TAKE1,
                  "[ <sp> path-name ]");
@@ -2930,7 +2950,7 @@
 
     /* PBSZ does not require a user to be logged in */
     ftp_hook_cmd("PBSZ", ftp_cmd_pbsz, FTP_HOOK_LAST,
-                 FTP_TAKE1,
+                 FTP_TAKE1 | FTP_NEW_FEAT,
                  "<sp> decimal-integer");
 
     ftp_hook_cmd("PORT", ftp_cmd_port, FTP_HOOK_LAST,
@@ -2939,7 +2959,7 @@
 
     /* PROT does not require a user to be logged in */
     ftp_hook_cmd("PROT", ftp_cmd_prot, FTP_HOOK_LAST,
-                 FTP_TAKE1,
+                 FTP_TAKE1 | FTP_NEW_FEAT,
                  "<sp> prot-code");
 
     ftp_hook_cmd("PWD", ftp_cmd_pwd, FTP_HOOK_LAST,
@@ -2958,6 +2978,11 @@
                  FTP_NEED_LOGIN | FTP_TAKE1,
                  "<sp> offset (restart command)");
 
+    /* Register the REST STREAM mechanism for FEAT advertising */
+    ftp_hook_cmd("REST STREAM", ftp_cmd_rest, FTP_HOOK_LAST,
+                 FTP_NEW_FEAT,
+                 "<sp> offset (restart command)");
+
     ftp_hook_cmd("RETR", ftp_cmd_retr, FTP_HOOK_LAST,
                  FTP_NEED_LOGIN | FTP_TAKE1,
                  "<sp> file-name");
@@ -2979,7 +3004,7 @@
                  "site-cmd [ <sp> arguments ]");
 
     ftp_hook_cmd("SIZE", ftp_cmd_size, FTP_HOOK_LAST,
-                 FTP_NEED_LOGIN | FTP_TAKE1,
+                 FTP_NEED_LOGIN | FTP_TAKE1 | FTP_NEW_FEAT,
                  "<sp> path-name");
 
     ftp_hook_cmd("SMNT", NULL, FTP_HOOK_LAST,

Modified: httpd/mod_ftp/trunk/modules/ftp/ftp_internal.h
URL: http://svn.apache.org/viewvc/httpd/mod_ftp/trunk/modules/ftp/ftp_internal.h?rev=793756&r1=793755&r2=793756&view=diff
==============================================================================
--- httpd/mod_ftp/trunk/modules/ftp/ftp_internal.h (original)
+++ httpd/mod_ftp/trunk/modules/ftp/ftp_internal.h Mon Jul 13 23:54:04 2009
@@ -115,6 +115,8 @@
 #define FTP_MSG_HELP         "Direct comments to %s"
 #define FTP_MSG_NOTIMPL      "%s: Command not implemented"
 #define FTP_MSG_NOTALLOWED   "Permission denied: %s not allowed here"
+#define FTP_MSG_SESSIONLIMIT "Maximum number of concurrent sessions reached," \
+                             " closing connection."
 
 #define FTP_DEFAULT_DBFILE   "logs/ftplogins"
 /*
@@ -331,25 +333,8 @@
  */
 int ftp_cmd_abort_data(const char *key);
 
-typedef struct ftp_cmd_entry ftp_cmd_entry;
-
-/*
- * The FTP command structure contains useful information about the FTP
- * handler.  This information is filled out when a command is registered
- * using ftp_hook_cmd(), which also puts the handler into the global hash.
- */
-struct ftp_cmd_entry
-{
-    const char *key;                  /* The key, e.g. "DELE" */
-    ftp_hook_fn *pf;                  /* Pointer to the handler */
-    const char *alias;                /* The aliased command e.g. "CDUP" */
-    int order;                        /* Handler ordering */
-    int flags;                        /* Flags for this command.  See FTP_
-                                       * defines above
-                                       */
-    const char *help;                 /* Help string for this command */
-    struct ftp_cmd_entry *next;       /* Pointer to the next handler */
-};
+/* Finalizes ftp_cmd_help and ftp_cmd_feat messages */
+void ftp_cmd_finalize(apr_pool_t *p, apr_pool_t *ptemp);
 
 /* FTP low-numbered-port allocation daemon
  *

Modified: httpd/mod_ftp/trunk/modules/ftp/ftp_protocol.c
URL: http://svn.apache.org/viewvc/httpd/mod_ftp/trunk/modules/ftp/ftp_protocol.c?rev=793756&r1=793755&r2=793756&view=diff
==============================================================================
--- httpd/mod_ftp/trunk/modules/ftp/ftp_protocol.c (original)
+++ httpd/mod_ftp/trunk/modules/ftp/ftp_protocol.c Mon Jul 13 23:54:04 2009
@@ -729,17 +729,6 @@
     }
 
     switch (status) {
-    case FTP_REPLY_SYSTEM_STATUS:
-        ftp_reply(fc, c->output_filters, r->pool, FTP_REPLY_SYSTEM_STATUS, 1,
-                  "Extensions supported:\n"
-                  " AUTH TLS\n"
-                  " PBSZ\n"
-                  " PROT\n"
-                  " SIZE\n"
-                  " MDTM");
-        ftp_reply(fc, c->output_filters, r->pool, FTP_REPLY_SYSTEM_STATUS, 0,
-                  "END");
-        break;
     case FTP_REPLY_SYSTEM_TYPE:
         ftp_reply(fc, c->output_filters, r->pool, FTP_REPLY_SYSTEM_TYPE, 0,
                   apr_pstrcat(r->pool, "UNIX Type: L8 System: \"",

Modified: httpd/mod_ftp/trunk/modules/ftp/mod_ftp.c
URL: http://svn.apache.org/viewvc/httpd/mod_ftp/trunk/modules/ftp/mod_ftp.c?rev=793756&r1=793755&r2=793756&view=diff
==============================================================================
--- httpd/mod_ftp/trunk/modules/ftp/mod_ftp.c (original)
+++ httpd/mod_ftp/trunk/modules/ftp/mod_ftp.c Mon Jul 13 23:54:04 2009
@@ -86,6 +86,9 @@
 
     ap_add_version_component(p, FTP_SERVER_STRING);
 
+    /* Finalize ftp_cmd_help and ftp_cmd_feat messages */
+    ftp_cmd_finalize(p, ptemp);
+
     /*
      * Fixup global values, then base server and virtual host values
      */



Mime
View raw message