You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by ji...@apache.org on 2007/05/03 14:51:44 UTC

svn commit: r534830 - in /httpd/mod_ftp/trunk: CHANGES include/mod_ftp.h modules/ftp/ftp_commands.c modules/ftp/ftp_util.c

Author: jim
Date: Thu May  3 05:51:43 2007
New Revision: 534830

URL: http://svn.apache.org/viewvc?view=rev&rev=534830
Log:
Remove the usage of, and dependence on, ftp_glob() by
using apr_fnmatch()... Still need to remove the remaining
vestages of ftp_glob (files, etc)

Modified:
    httpd/mod_ftp/trunk/CHANGES
    httpd/mod_ftp/trunk/include/mod_ftp.h
    httpd/mod_ftp/trunk/modules/ftp/ftp_commands.c
    httpd/mod_ftp/trunk/modules/ftp/ftp_util.c

Modified: httpd/mod_ftp/trunk/CHANGES
URL: http://svn.apache.org/viewvc/httpd/mod_ftp/trunk/CHANGES?view=diff&rev=534830&r1=534829&r2=534830
==============================================================================
--- httpd/mod_ftp/trunk/CHANGES (original)
+++ httpd/mod_ftp/trunk/CHANGES Thu May  3 05:51:43 2007
@@ -1,29 +1,31 @@
 Changes post submission, prior to first release;
 
-  * Moved FTPUMask and FTPDirMask from the vhost server scope out to
-    per-directory scope (valid in .htaccess with Options FileInfo.)
-    Enabled these directives even if fchmod is absent.  [William Rowe]
-
-  * Reorganized PASV command handling and the FTPPasvBindAddr directive
-    to handle IPv6 addresses, especially for the cases of dual-bound
-    adapters, IPv6 tunneled IPv4 connections, and IPv6 servers hiding
-    behind IPv4 load balancing solutions.  [William Rowe]
-
-  * Adjust 220 and 215 responses to only quote the same Server: string
-    which the HTTP Server: string would display.  This removes the build
-    datestamp from 215 responses, and adds Type: L8 to the 215 response. 
-    [William Rowe]
-
-  * Update to Apache HTTP 2.2.  [William Rowe]
-
-  * Incorporated documentation submitted by Covalent, in Apache HTTP-style,
-    with edits and additional examples.  [Sander Temme]
-
-  * Remove the configuration system, starting over.  Makefile.apxs is the 
-    trivial mechanism, but also added config.m4 to configure in-tree.
-    [William Rowe, Colm MacCarthaig]
-
-  * Implement the FTPDirUmask directive to allow the administrator
-    to customize the perms of newly MKD'ed directories, independent
-    of the FTPUmask (which wasn't honored in the first place for dirs.)
-    [Kanagasabai Sriskanthaverl <sris covalent.net>]
+  *) Remove dependence on ftp_glob(). [Jim Jagielski]
+
+  *) Moved FTPUMask and FTPDirMask from the vhost server scope out to
+     per-directory scope (valid in .htaccess with Options FileInfo.)
+     Enabled these directives even if fchmod is absent.  [William Rowe]
+
+  *) Reorganized PASV command handling and the FTPPasvBindAddr directive
+     to handle IPv6 addresses, especially for the cases of dual-bound
+     adapters, IPv6 tunneled IPv4 connections, and IPv6 servers hiding
+     behind IPv4 load balancing solutions.  [William Rowe]
+
+  *) Adjust 220 and 215 responses to only quote the same Server: string
+     which the HTTP Server: string would display.  This removes the build
+     datestamp from 215 responses, and adds Type: L8 to the 215 response. 
+     [William Rowe]
+
+  *) Update to Apache HTTP 2.2.  [William Rowe]
+
+  *) Incorporated documentation submitted by Covalent, in Apache HTTP-style,
+     with edits and additional examples.  [Sander Temme]
+
+  *) Remove the configuration system, starting over.  Makefile.apxs is the 
+     trivial mechanism, but also added config.m4 to configure in-tree.
+     [William Rowe, Colm MacCarthaig]
+
+  *) Implement the FTPDirUmask directive to allow the administrator
+     to customize the perms of newly MKD'ed directories, independent
+     of the FTPUmask (which wasn't honored in the first place for dirs.)
+     [Kanagasabai Sriskanthaverl <sris covalent.net>]

Modified: httpd/mod_ftp/trunk/include/mod_ftp.h
URL: http://svn.apache.org/viewvc/httpd/mod_ftp/trunk/include/mod_ftp.h?view=diff&rev=534830&r1=534829&r2=534830
==============================================================================
--- httpd/mod_ftp/trunk/include/mod_ftp.h (original)
+++ httpd/mod_ftp/trunk/include/mod_ftp.h Thu May  3 05:51:43 2007
@@ -397,11 +397,7 @@
  *
  * ftp_util.c
  */
-#ifdef FTP_HAS_GLOB
-struct ftp_direntry *ftp_direntry_get_glob(request_rec *r, const char *pat);
-#else
-struct ftp_direntry *ftp_direntry_get(request_rec *r);
-#endif /* FTP_HAS_GLOB */
+struct ftp_direntry *ftp_direntry_get(request_rec *r, const char *pattern);
 
 void ftp_set_authorization(request_rec *r);
 int ftp_set_uri(request_rec *r, const char *arg);

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?view=diff&rev=534830&r1=534829&r2=534830
==============================================================================
--- httpd/mod_ftp/trunk/modules/ftp/ftp_commands.c (original)
+++ httpd/mod_ftp/trunk/modules/ftp/ftp_commands.c Thu May  3 05:51:43 2007
@@ -678,19 +678,16 @@
     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 */
-#ifndef FTP_HAS_GLOB
-    if((direntry = ftp_direntry_get(r)) == NULL) {
-        fc->response_notes = apr_psprintf(r->pool, FTP_MSG_NOSUCHFILE, arg);
-        return FTP_REPLY_FILE_NOT_FOUND;
-    }
-#else
-    if((direntry = ftp_direntry_get_glob(r, pattern)) == NULL) {
+    if((direntry = ftp_direntry_get(r, pattern)) == NULL) {
         fc->response_notes = apr_psprintf(r->pool, FTP_MSG_NOSUCHFILE, arg);
         return FTP_REPLY_FILE_NOT_FOUND;
     }
-#endif /* FTP_HAS_GLOB */
 
     fc->response_notes = FTP_MSG_OPENASCII;
     ftp_send_response(r, FTP_REPLY_FILE_STATUS_OK);
@@ -954,18 +951,15 @@
         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 */
-#ifndef FTP_HAS_GLOB
-    if((direntry = ftp_direntry_get(r)) == NULL) {
-        fc->response_notes = apr_psprintf(r->pool, FTP_MSG_NOSUCHFILE, arg);
-        return FTP_REPLY_FILE_NOT_FOUND;
-    }
-#else
-    if((direntry = ftp_direntry_get_glob(r, pattern)) == NULL) {
+    if((direntry = ftp_direntry_get(r, pattern)) == NULL) {
         fc->response_notes = apr_psprintf(r->pool, FTP_MSG_NOSUCHFILE, arg);
         return FTP_REPLY_FILE_NOT_FOUND;
     }
-#endif /* FTP_HAS_GLOB */
 
     fc->response_notes = FTP_MSG_OPENASCII;
     ftp_send_response(r, FTP_REPLY_FILE_STATUS_OK);

Modified: httpd/mod_ftp/trunk/modules/ftp/ftp_util.c
URL: http://svn.apache.org/viewvc/httpd/mod_ftp/trunk/modules/ftp/ftp_util.c?view=diff&rev=534830&r1=534829&r2=534830
==============================================================================
--- httpd/mod_ftp/trunk/modules/ftp/ftp_util.c (original)
+++ httpd/mod_ftp/trunk/modules/ftp/ftp_util.c Thu May  3 05:51:43 2007
@@ -23,10 +23,7 @@
 
 #include "ftp_config.h"
 #include "mod_ftp.h"
-#ifdef FTP_HAS_GLOB
-#include "ftp_glob.h" /* Custom globber */
-#endif /* FTP_HAS_GLOB */
-
+#include "apr_fnmatch.h"
 #include "ap_mpm.h" /* For MPM query interface */
 
 #include <sys/stat.h> /* For file perms */
@@ -87,16 +84,19 @@
 }
 
 
-/* ftp_make_direntry: Fill out a directory entry structure from the
+/* ftp_direntry_make: Fill out a directory entry structure from the
  *                    directory being requested and a filename.
  *
- * Arguments: r    - The request record for the directory index
- *            name - The filename to be checked.
+ * Arguments: r       - The request record for the directory index
+ *            name    - The filename to be checked.
+ *            pattern - Pattern to get a directory listing for. If NULL
+ *                      we do not GLOB.
  *
  * Returns: ftp_direntry structure on success, NULL otherwise.
  */
 static struct ftp_direntry *ftp_direntry_make(request_rec *r,
-                                              const char *name)
+                                              const char *name,
+                                              const char *pattern)
 {
     ftp_server_config *fsc = ftp_get_module_config(r->server->module_config);
     struct ftp_direntry *dirent;
@@ -111,6 +111,19 @@
         return NULL;
     }
 
+#ifdef FTP_DEBUG
+    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "Name    - fdm: %s", name);
+    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "Pattern - fdm: %s", pattern);
+#endif
+
+    if (pattern && *pattern && 
+        (apr_fnmatch(pattern, name, APR_FNM_PATHNAME | APR_FNM_PERIOD) != APR_SUCCESS)) {
+#ifdef FTP_DEBUG
+        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "no match");
+#endif
+        return NULL;
+    }
+
     rr = ap_sub_req_lookup_file(name, r, NULL);
 
     /* Another hack.  With BSD glob it is possible to return a file
@@ -187,10 +200,7 @@
     return dirent;
 }
 
-#ifndef FTP_HAS_GLOB
-
-/* ftp_dsortf: Used for sorting directory entries when globbing is
- *             not enabled.  Called by qsort()
+/* ftp_dsortf: Used for sorting directory entries. Called by qsort()
  *
  * Arguments: d1 - The first directory entry
  *            d2 - The second directory entry
@@ -206,51 +216,68 @@
     return strcmp((*d1)->name, (*d2)->name);
 }
 
-/* ftp_direntry_get: Identical to ftp_direntry_get_glob, but we do not
- *                   support globbing.
- *
- * Arguments r - The request rec for the directory listing
+/* ftp_direntry_get: Return an array of ftp_direntry structures based
+ *                   on the uri stored in the request rec.  An extra
+ *                   argument may be passed for pattern matching.
+ *         
+ * Arguments: r       - The request record for the directory index
+ *            pattern - Pattern to get a directory listing for.
  *
  * Returns: The sorted array of directory entries on success, NULL otherwise
  */
-struct ftp_direntry *ftp_direntry_get(request_rec *r)
+struct ftp_direntry *ftp_direntry_get(request_rec *r, const char *pattern)
 {
     struct ftp_direntry *p, *head, *current, **a;
     apr_dir_t *dir;
     apr_finfo_t finfo;
     apr_status_t rv;
     int num, i;
+    char *fname;
+    const char *path, *search;
+    
+    /* The actual search pattern, used to determine if we should recurse
+     * into a directory or not.  If the search pattern is just *, we should
+     * not decend.  For search patterns like 'm*', we should.
+     */
+#ifdef FTP_DEBUG
+    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "Pattern - start: %s", pattern);
+#endif
 
-#ifdef WIN32
-    /* FIXME: A nasty hack. If the last char is a '*' then
-     * we silently delete it and press on. This allows for
-     * things like 'NLST *' to work */
-    num = strlen(r->filename) - 1;
-    if ((num >= 0) && (r->filename[num] == '*')) {
-        r->filename[num] = '\0';
-        num = strlen(r->filename) - 1;
-        if ((num >= 0) && (r->filename[num] == '/')) {
-            r->filename[num] = '\0';
-        }
+    path = pattern;
+    search = ap_strrchr_c(pattern, '/');
+    
+    if (search == NULL) {
+        search = ap_strrchr_c(pattern, '\\');
+    }
+    if (search != NULL) {
+        search++;
+        path = apr_pstrndup(r->pool, pattern, search-pattern);
     }
 
+#ifdef FTP_DEBUG
+    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "Path    - end: %s", path);
+    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "Pattern - end: %s", pattern);
+#endif
+
+#ifdef WIN32
+
     /* Win32 will always return sucess on apr_dir_open, which means
      * we have to stat the file to see if the request was made for
      * a directory or file.
      */
-    rv = apr_stat(&finfo, r->filename, APR_FINFO_MIN, r->pool);
+    rv = apr_stat(&finfo, path, APR_FINFO_MIN, r->pool);
     if (finfo.filetype != APR_DIR) {
         /* Must be for a single file */
-        return ftp_direntry_make(r, r->filename);    
+        return ftp_direntry_make(r, path, pattern);    
     }
 #endif /* WIN32 */
 
-    rv = apr_dir_open(&dir, r->filename, r->pool);
+    rv = apr_dir_open(&dir, path, r->pool);
 
     if (rv != APR_SUCCESS) {
         if (APR_STATUS_IS_ENOTDIR(rv)) {
             /* Must be for a single file */
-            return ftp_direntry_make(r, r->filename);
+            return ftp_direntry_make(r, path, pattern);
         }
         else {
             return NULL;
@@ -262,8 +289,8 @@
     while ((rv = apr_dir_read(&finfo, APR_FINFO_DIRENT, dir)) 
            == APR_SUCCESS) {
 
-        p = ftp_direntry_make(r, ap_make_full_path(r->pool, r->filename,
-                                                   finfo.name));
+        fname = ap_make_full_path(r->pool, path, finfo.name);
+        p = ftp_direntry_make(r, fname, pattern);
         if (!p) {
             continue;
         }
@@ -278,7 +305,20 @@
             current->next = p;
             current = p;
         }
-        p->child = NULL;
+        /* We are only going to support single recursive listings
+         * this means that requests such as 'ls m*' will print out
+         * all files that match, and recurse a single level into
+         * directories.
+         */
+        
+        if (search && (search[0] != '*') && (p->modestring[0] == 'd')) {
+            const char *newpattern = apr_pstrcat(r->pool, fname,
+                                                 "/*", NULL);
+            p->child = ftp_direntry_get(r, newpattern);
+        }
+        else {
+            p->child = NULL;
+        }
         num++;
     }
     
@@ -295,6 +335,7 @@
             a[i++] = p;
             p = p->next;
         }
+        num = i;
         qsort((void *) a, num, sizeof (struct ftp_direntry *),
               (int(*)(const void *, const void *))ftp_dsortf);
 
@@ -311,83 +352,6 @@
     return head;
 }
 
-#else /* FTP_HAS_GLOB */
-
-/* ftp_direntry_get_glob: Return an array of ftp_direntry structures based
- *                        on the uri stored in the request rec.  An extra
- *                        argument may be passed for pattern matching. Note 
- *                        that this uses glob, which is only available on 
- *                        Unix type systems.
- *
- * Arguments: r       - The request rec for the directory listing
- *            pattern - Pattern to get a directory listing for
- *
- * Returns: The sorted array of directory entries on success, NULL otherwise
- */
-
-struct ftp_direntry *ftp_direntry_get_glob(request_rec *r,  
-                                           const char *pattern)
-{
-    struct ftp_direntry *p, *head, *current;
-    int i;
-    ftp_glob_t gb;
-    /* The actual search pattern, used to determine if we should recurse
-     * into a directory or not.  If the search pattern is just *, we should
-     * not decend.  For search patterns like 'm*', we should.
-     */
-    const char *search = strrchr((char *) pattern, '/') + 1;
-
-    if(ftp_glob(pattern, FTP_GLOB_PERIOD, NULL, &gb)) {
-        return NULL;
-    }
-
-    /* BSD glob does not consider finding no matches an error. */
-    if (gb.gl_pathc == 0 && gb.gl_matchc == 0) {
-        return NULL;
-    }
-
-    head = NULL;
-    current = NULL;
-    for(i=0; gb.gl_pathv[i] != NULL; i++) {
-
-        /* Run the subreq and fill out most information */
-        p = ftp_direntry_make(r, gb.gl_pathv[i]);
-        if (!p) {
-            continue;
-        }
-
-        /* Add this entry to the linked list */
-        if (head == NULL) {
-            head = p;
-            p->next = NULL;
-            current = p;
-        }
-        else {
-            current->next = p;
-            current = p;
-        }
-
-        /* We are only going to support single recursive listings
-         * this means that reqeusts such as 'ls m*' will print out
-         * all files that match, and recurse a single level into
-         * directories.
-         */
-        
-        if ((search[0] != '*') && (p->modestring[0] == 'd')) {
-            const char *newpattern = apr_pstrcat(r->pool, gb.gl_pathv[i],
-                                                 "/*", NULL);
-            p->child = ftp_direntry_get_glob(r, newpattern);
-        }
-        else {
-            p->child = NULL;
-        }
-    }
-
-    ftp_globfree(&gb);
-    return head;
-}
-
-#endif /* FTP_HAS_GLOB */
 
 /* ftp_set_authorization: set the r->headers_in Authorization header
  *