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++] = '\\';
+