Date: Wed, 28 Mar 2007 14:52:27 -0700 From: Nate Lawson <nate@root.org> To: current@FreeBSD.org Cc: =?ISO-8859-1?Q?Dag-Erling_Sm=F8rgrav?= <des@des.no> Subject: libfetch ftp patch for less latency Message-ID: <460AE39B.4070706@root.org>
next in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format. --------------070508040504000902030504 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit To speed up pkg_add and other ftp command channel performance over slow links, change this: >>> PWD <<< 257 "/" >>> CWD pub <<< 250 Directory successfully changed. >>> CWD FreeBSD <<< 250 Directory successfully changed. >>> CWD ports <<< 250 Directory successfully changed. >>> CWD amd64 <<< 250 Directory successfully changed. >>> CWD packages-6-stable <<< 250 Directory successfully changed. >>> CWD Latest <<< 250 Directory successfully changed. >>> MODE S Into this: >>> PWD <<< 257 "/" >>> CWD pub/FreeBSD/ports/amd64/packages-6-stable/Latest <<< 250 Directory successfully changed. All ftp servers I've ever seen support a full path when changing down dirs. This might be a DOS ftp server thing however. In any case, if there is an error to the all-in-one CWD, the code reverts back to legacy behavior of multiple CWDs. -- Nate --------------070508040504000902030504 Content-Type: text/x-patch; name="ftp.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="ftp.diff" =================================================================== RCS file: /home/ncvs/src/lib/libfetch/ftp.c,v --- ftp.c 22 Jul 2006 06:01:58 -0000 1.91.2.1 +++ ftp.c 28 Mar 2007 20:42:58 -0000 @@ -267,6 +267,7 @@ char pwd[PATH_MAX]; int e, i, len; + /* If no slashes in name, no need to change dirs. */ if ((end = strrchr(file, '/')) == NULL) return (0); if ((e = _ftp_cmd(conn, "PWD")) != FTP_WORKING_DIRECTORY || @@ -276,7 +277,8 @@ } for (;;) { len = strlen(pwd); - /* look for a common prefix */ + + /* Look for a common prefix between PWD and dir to fetch. */ for (i = 0; i <= len && i <= end - file; ++i) if (pwd[i] != file[i]) break; @@ -284,6 +286,7 @@ DEBUG(fprintf(stderr, "have: [%.*s|%s]\n", i, pwd, pwd + i)); DEBUG(fprintf(stderr, "want: [%.*s|%s]\n", i, file, file + i)); #endif + /* Keep going up a dir until we have a matching prefix. */ if (pwd[i] == '\0' && (file[i - 1] == '/' || file[i] == '/')) break; if ((e = _ftp_cmd(conn, "CDUP")) != FTP_FILE_ACTION_OK || @@ -293,6 +296,21 @@ return (-1); } } + + /* Skip leading slashes, even "////". */ + for (beg = file + i; beg < end && *beg == '/'; ++beg, ++i) + /* nothing */ ; + + /* If there is no trailing dir, we're already there. */ + if (beg >= end) + return (0); + + /* Change to the directory all in one chunk (e.g., foo/bar/baz). */ + e = _ftp_cmd(conn, "CWD %.*s", (int)(end - beg), beg); + if (e == FTP_FILE_ACTION_OK) + return (0); + + /* That didn't work so go back to legacy behavior (multiple CWDs). */ for (beg = file + i; beg < end; beg = file + i + 1) { while (*beg == '/') ++beg, ++i; --------------070508040504000902030504--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?460AE39B.4070706>