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
*