Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 12 Aug 2000 20:03:42 +0100
From:      Dermot McNally <dermot@traveldev.com>
To:        current@freebsd.org
Subject:   Re: Proposed enhancement to FTP autocompletion
Message-ID:  <39959F8E.8D3FB78@traveldev.com>
References:  <3992A35B.4D213DFB@traveldev.com>

next in thread | previous in thread | raw e-mail | index | archive | help
Folks,

Since I got some encouragement in private mail, I've produced the
enclosed patches to ftp. The changes are direct copies from the NetBSD
ftp client and from "lukemftp"
(ftp://ftp.netbsd.org/pub/NetBSD/misc/lukemftp/). They do the following:

Spaces in completed file/directory names (local and remote) are now
escaped (NetBSD)

Slashes are now appended to completed local directories (lukemftp)


There's a bunch of other stuff in lukemftp that may be worth using, but
it doesn't append slashes for remote directories either - I'll be having
a closer look at this, it's certainly doable, but possibly not very
elegantly.

Comments, criticism?

Dermot



Index: complete.c
===================================================================
RCS file: /usr/local/ncvs/src/usr.bin/ftp/complete.c,v
retrieving revision 1.5
diff -c -r1.5 complete.c
*** complete.c	1999/08/28 01:01:30	1.5
--- complete.c	2000/08/12 18:33:11
***************
*** 56,61 ****
--- 56,62 ----
  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>
+ #include <sys/stat.h>
  
  #include "ftp_var.h"
  
***************
*** 83,89 ****
  	StringList *words;
  {
  	char insertstr[MAXPATHLEN];
! 	char *lastmatch;
  	int i, j;
  	size_t matchlen, wordlen;
  
--- 84,90 ----
  	StringList *words;
  {
  	char insertstr[MAXPATHLEN];
! 	char *lastmatch, *p;
  	int i, j;
  	size_t matchlen, wordlen;
  
***************
*** 92,99 ****
  		return (CC_ERROR);	/* no choices available */
  
  	if (words->sl_cur == 1) {	/* only once choice available */
! 		(void)strcpy(insertstr, words->sl_str[0]);
! 		if (el_insertstr(el, insertstr + wordlen) == -1)
  			return (CC_ERROR);
  		else
  			return (CC_REFRESH);
--- 93,103 ----
  		return (CC_ERROR);	/* no choices available */
  
  	if (words->sl_cur == 1) {	/* only once choice available */
! 		p = words->sl_str[0] + wordlen;
! 		if (*p == '\0')		/* at end of word? */
! 			return (CC_REFRESH);
! 		ftpvis(insertstr, sizeof(insertstr), p, strlen(p));
! 		if (el_insertstr(el, insertstr) == -1)
  			return (CC_ERROR);
  		else
  			return (CC_REFRESH);
***************
*** 111,119 ****
  				matchlen = j;
  		}
  		if (matchlen > wordlen) {
! 			(void)strncpy(insertstr, lastmatch, matchlen);
! 			insertstr[matchlen] = '\0';
! 			if (el_insertstr(el, insertstr + wordlen) == -1)
  				return (CC_ERROR);
  			else	
  					/*
--- 115,123 ----
  				matchlen = j;
  		}
  		if (matchlen > wordlen) {
! 			ftpvis(insertstr, sizeof(insertstr),
! 			    lastmatch + wordlen, matchlen - wordlen);
! 			if (el_insertstr(el, insertstr) == -1)
  				return (CC_ERROR);
  			else	
  					/*
***************
*** 209,214 ****
--- 213,235 ----
  	closedir(dd);
  
  	rv = complete_ambiguous(file, list, words);
+ 	if (rv == CC_REFRESH) {
+ 		struct stat sb;
+ 		char path[MAXPATHLEN];
+ 
+ 		(void)strlcpy(path, dir,		sizeof(path));
+ 		(void)strlcat(path, "/",		sizeof(path));
+ 		(void)strlcat(path, words->sl_str[0],	sizeof(path));
+ 
+ 		if (stat(path, &sb) >= 0) {
+ 			char suffix[2] = " ";
+ 
+ 			if (S_ISDIR(sb.st_mode))
+ 				suffix[0] = '/';
+ 			if (el_insertstr(el, suffix) == -1)
+ 				rv = CC_ERROR; 
+ 		} 
+ 	}
  	sl_free(words, 1);
  	return (rv);
  }
Index: util.c
===================================================================
RCS file: /usr/local/ncvs/src/usr.bin/ftp/util.c,v
retrieving revision 1.13
diff -c -r1.13 util.c
*** util.c	2000/05/22 17:18:38	1.13
--- util.c	2000/08/12 18:29:56
***************
*** 851,856 ****
--- 851,886 ----
  #endif /* !SMALL */
  
  /*
+  * Copy characters from src into dst, \ quoting characters that
require it
+  */
+ void
+ ftpvis(char *dst, size_t dstlen, const char *src, size_t srclen)
+ {
+ 	int	di, si;
+ 
+ 	for (di = si = 0;
+ 	    src[si] != '\0' && di < dstlen && si < srclen;
+ 	    di++, si++) {
+ 		switch (src[si]) {
+ 		case '\\':
+ 		case ' ':
+ 		case '\t':
+ 		case '\r':
+ 		case '\n':
+ 		case '"':
+ 			dst[di++] = '\\';
+ 			if (di >= dstlen)
+ 				break;
+ 			/* FALLTHROUGH */
+ 		default:
+ 			dst[di] = src[si];
+ 		}
+ 	}
+ 	dst[di] = '\0';
+ }
+ 
+ 
+ /*
   * Determine if given string is an IPv6 address or not.
   * Return 1 for yes, 0 for no
   */


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?39959F8E.8D3FB78>