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>