Subject: [patch] a better CD command for wu-ftpd 2.4

From: �K�͹ڦ� �L���H�� <[email-masked]>
Date: Fri, 19 May 1995 10:36:31 +0800 (CST)

Hi :
	
	I sent this file days ago to this mailing-list, and now here
	is a newer patch for a little-bug-fix.
	This patch will allow ftpd to auto-search the directory name
	when a user try to CD.  You can try to ftp ftp.edu.tw then you
	will know what I mean.  But this patch is not the one at
	ftp.edu.tw and was written myself.
	This is not a smart patch, but at least it works for me.
	Your are welcome to make it better, and please send me a patch
	so that I can "upgrade" from your kindly patch...  :)
	Any opinion please reply to [email-masked]

====== This patch is diff with original wu-ftpd-2.4 ======
*** ftpd.c.orig	Thu May 18 17:57:34 1995
--- ftpd.c Thu May 18 18:01:23 1995
***************
*** 2208,2213 ****
--- 2208,2355 ----
      ack("DELE");
  }
  
+ #ifdef SMART_CD
+ 
+ /* 
+  *  Smart CD, written by [email-masked], May.18 1995
+  *
+  *  This is a replacement of original CD, it should act almost like
+  *  the ftpd at ftp.edu.tw (I hope) , you are freely to mondify it.
+  *  add "#define SMART_CD" into ~/src/config.h
+  *  Please notice following things :
+  *  Please use a better algorithm b'cos mine is stupid (I think)
+  *  and please notice the overhead, memory useage and performance.
+  *  And, please send a patch to me, thanks a lot !!   :-)
+  *
+  */
+ 
+ char *strstri(char *str, char *word)
+ {
+  char tmp_str[MAXPATHLEN + 1], tmp_word[MAXPATHLEN + 1], *cp;
+  int i;
+  
+  for (i=0; i < strlen(str); i++) {
+    tmp_str[i] = toupper(str[i]);
+  }
+  for (i=0; i < strlen(word); i++) {
+    tmp_word[i] = toupper(word[i]);
+  }
+  tmp_str[strlen(str)] = tmp_word[strlen(word)] = '\0';
+  if ((cp = strstr(tmp_str, tmp_word)) != NULL) {
+    return ((char *)(str + (cp - tmp_str)));
+  }
+  return ((char *) NULL);
+ }
+ 
+ cwd(char *path)
+ {
+     extern int match(char *s, char *p);
+     struct aclmember *entry = NULL;
+     char cdpath[MAXPATHLEN + 1], dirname[MAXPATHLEN + 1];
+     DIR *dirp = NULL;
+     char pass1_cdpath[MAXPATHLEN + 1], pass2_cdpath[MAXPATHLEN + 1], *tmp_cp;
+     int pass1_point, pass2_point, tmp_point;
+     struct stat st;
+     
+ #ifdef HAVE_DIRENT
+     struct dirent *dir;
+ #else
+     struct direct *dir;
+ #endif
+ 
+ 
+ #ifdef HAVE_GETCWD
+     extern char *getcwd();
+ #else
+     extern char *getwd(char *);
+ #endif
+ 
+     if (chdir(path) < 0) {
+ #ifdef HAVE_GETCWD
+ 	getcwd(dirname, MAXPATHLEN);
+ #else
+ 	getwd(dirname);
+ #endif
+ 	/*
+ 	 * Use two-pass algorithm
+ 	 * Pass one, case-sensitive
+ 	 * Pass two, case-insensitive
+ 	 */
+ 	  
+ 	if ((dirp = opendir(dirname)) != NULL) {
+ 	    pass1_point = pass2_point = 17084;
+ 	    while ((dir = readdir(dirp)) != NULL) {
+ 	        if (!stat(dir->d_name, &st) && !(st.st_mode & S_IFDIR)) continue;
+ 	        /* Pass one */
+ 	        if (((tmp_cp = strstr(dir->d_name, path)) != NULL)
+ 		    && ((tmp_point = (int) (tmp_cp - dir->d_name)) < pass1_point)) {
+ 	          pass1_point = tmp_point;
+ 	          strcpy(pass1_cdpath, dir->d_name);
+ 	        }
+ 	        /* Pass two */
+ 	        if (((tmp_cp = strstri(dir->d_name, path)) != NULL)
+ 		    && ((tmp_point = (int) (tmp_cp - dir->d_name)) < pass2_point)) {
+ 	          pass2_point = tmp_point;
+ 	          strcpy(pass2_cdpath, dir->d_name);
+ 	        }
+ 	    }
+ 	}
+ 	(void) closedir(dirp);
+ 
+ 	tmp_cp = (char *) NULL;
+ 	if (pass1_point != 17084)
+ 	  tmp_cp = pass1_cdpath;
+ 	else if (pass2_point != 17084)
+ 	  tmp_cp = pass2_cdpath;
+ 
+ 	if (tmp_cp && (chdir(tmp_cp) >= 0)) {
+ 	  show_message(250, C_WD);
+ 	  show_readme(250, C_WD);
+ 	  reply(250, "Searching Key: \"%s\". Change to an appropriate directory \"%s\".", path, tmp_cp);
+ /*	  ack("CWD");*/
+ 	  return;
+ 	}
+ 	
+         /* alias checking */
+         while (getaclentry("alias", &entry) && ARG0 && ARG1 != NULL) {
+             if (!strcasecmp(ARG0, path)) { 
+                 if (chdir(ARG1) < 0)
+                     perror_reply(550, path);
+                 else {
+                     show_message(250, C_WD);
+                     show_readme(250, C_WD);
+ 		    reply(250, "Change alias to the directory \"%s\".", path);
+ /*                    ack("CWD");*/
+                 }
+                 return;
+             }
+         }
+     /* check for "cdpath" directories. */
+         entry = (struct aclmember *) NULL;
+         while (getaclentry("cdpath", &entry) && ARG0 != NULL) {
+         strcpy(cdpath,ARG0);
+         strcat(cdpath,"/");
+         strcat(cdpath, path);
+             if (chdir(cdpath) >= 0) {
+                 show_message(250, C_WD);
+                 show_readme(250, C_WD);
+ 		reply(250, "Change cdpath to the directory \"%s\".", path);
+ /*                ack("CWD");*/
+                 return;
+             }
+         }
+ 	reply(250, "Unable to locate an appropriate directory for \"%s\" in \"%s\".", path, dirname);
+ /*        perror_reply(550,path);*/
+     } else {
+         show_message(250, C_WD);
+         show_readme(250, C_WD);
+ 	reply(250, "Change exactly to the directory \"%s\".", path);
+ /*        ack("CWD");*/
+     }
+ }
+ 
+ #else /* original CD */
+ 
  cwd(char *path)
  {
      struct aclmember *entry = NULL;
***************
*** 2247,2252 ****
--- 2389,2395 ----
          ack("CWD");
      }
  }
+ #endif /* endif SMART_CD */
  
  makedir(char *name)
  {
============== cut here =====================
-- 
                                           Mail: [email-masked]