Subject: Re: Wildcard/globbing in ftpaccess file

From: [email-masked] (William L. Sebok)
Date: Wed, 8 Oct 1997 10:32:00 -0400 (EDT)

Aaron Holtz <[email-masked]> said:

> This talk of 'noretrieve' in the ftpaccess file has me wondering:
> Would it be difficult to implement wildcards in the ftpaccess file?
> For example:
> 
> noretrieve /etc/*
> noretrieve /bin/*
> 
> 
> That way no file in that directory could be retrieved?

On April 22.1997 I posted to this list a patch which implements this.  It
implements regular expression type globbing
(i.e.
	notretrieve /incoming/.*
).  I have been running with this patch installed from then until now 
(wu-2.4.2-academ[BETA-15]).

Bill Sebok      Computer Software Manager, Univ. of Maryland, Astronomy
	Internet: [email-masked]	URL: http://www.astro.umd.edu/~wls/

---- Begin Quote ----
I consider this patch a hack.  I believe that the proper fix would implement a
"download" command with the same syntax and options as the present "upload"
command.  Still, this patch did the job and was quick to implement.

Bill Sebok      Computer Software Manager, Univ. of Maryland, Astronomy
	Internet: [email-masked]	URL: http://www.astro.umd.edu/~wls/

Patch against wu-ftpd-2.4.2-beta-13:

*** src/extensions.c.ORIG	Mon Mar  3 04:39:54 1997
--- src/extensions.c	Mon Apr 21 16:51:06 1997
***************
*** 1113,1118 ****
--- 1113,1120 ----
  }
  
  /* The following is from the Debian add-ons. */
+ /* hacked by W. Sebok ([email-masked]) to support regex expressions in
+  * noretrieve expressions */
  
  #define lbasename(x) (strrchr(x,'/')?1+strrchr(x,'/'):x)
  
***************
*** 1125,1130 ****
--- 1127,1133 ----
  #endif
  {
    char cwd[MAXPATHLEN+1], realwd[MAXPATHLEN+1], realname[MAXPATHLEN+1];
+   char *p, *q;
    int i;
    struct aclmember *entry = NULL;
  
***************
*** 1144,1161 ****
          if (ARG0 == (char *)NULL)
              continue;
  	for (i = 0; i< MAXARGS && 
! 	     (entry->arg[i] != (char *)NULL) && (*(entry->arg[i]) !='\0'); i++)
! 	  if (strcmp (((*(entry->arg[i]) == '/') ? realname : 
! 			lbasename (realname)), entry->arg[i]) == 0)
  	  {
! 	    reply (550, "%s is marked unretrievable", entry->arg[i]);
  	    return 1;
  	  }
        }
     return 0;
  }

--- 1147,1209 ----
          if (ARG0 == (char *)NULL)
              continue;
  	for (i = 0; i< MAXARGS && 
! 	     ((q = entry->arg[i]) != (char *)NULL) && (*q !='\0'); i++) {
! 	  p = (*q == '/') ? realname : lbasename (realname);
! 	  if (strcmp (p , q) == 0 || regexmatch(p, q))
  	  {
! 	    reply (550, "%s is marked unretrievable", p);
  	    return 1;
  	  }
+ 	}
        }
     return 0;
  }
  
+ int
+ regexmatch(name, rgexp)
+ char *name, *rgexp;
+ {
  
+ #ifdef M_UNIX
+ # ifdef REGEX
+   char *regp;
+ # endif
+ #endif
  
+ #ifdef REGEXEC
+   regex_t regexbuf;
+   regmatch_t regmatchbuf;
+ #else
+   char *sp;
+ #endif
  
+ #if defined(REGEXEC)
+ 	if (regcomp(&regexbuf, rgexp, REG_EXTENDED) != 0) {
+ 	    reply(553, "REGEX error");
+ #elif defined(REGEX)
+ 	if ((sp = regcmp(rgexp, (char *) 0)) == NULL) {
+ 	    reply(553, "REGEX error");
+ #else
+ 	if ((sp = re_comp(rgexp)) != 0) {
+ 	    perror_reply(553, sp);
+ #endif
+ 	    return(0);
+ 	}
  
+ #if defined(REGEXEC)
+ 	if (regexec(&regexbuf, name, 1, &regmatchbuf, 0) != 0) {
+ #elif defined(REGEX)
+ # ifdef M_UNIX
+ 	regp = regex(sp, name);
+ 	free(sp);
+ 	if (regp == NULL) {
+ # else
+ 	if ((regex(sp, name)) == NULL) {
+ # endif
+ #else
+ 	if ((re_exec(name)) != 1) {
+ #endif
+ 		return(0);
+ 	}
+ 	return(1);
+ }