Mon Nov 20 21:11:37 2017 UTC ()
Issue PWD commands to the server only when we actually
need the results, not speculatively, just in case we might.

Allows operation with some broken servers that get confused
by PWD commands in some situations, and saves server round
trips in the (modern) common case of
	ftp ftp://path/name
where we never need to know the results from PWD.


(kre)
diff -r1.137 -r1.138 src/usr.bin/ftp/cmds.c
diff -r1.84 -r1.85 src/usr.bin/ftp/ftp_var.h
diff -r1.158 -r1.159 src/usr.bin/ftp/util.c

cvs diff -r1.137 -r1.138 src/usr.bin/ftp/cmds.c (expand / switch to unified diff)

--- src/usr.bin/ftp/cmds.c 2016/02/27 16:31:31 1.137
+++ src/usr.bin/ftp/cmds.c 2017/11/20 21:11:36 1.138
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: cmds.c,v 1.137 2016/02/27 16:31:31 christos Exp $ */ 1/* $NetBSD: cmds.c,v 1.138 2017/11/20 21:11:36 kre Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1996-2009 The NetBSD Foundation, Inc. 4 * Copyright (c) 1996-2009 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Luke Mewburn. 8 * by Luke Mewburn.
9 * 9 *
10 * This code is derived from software contributed to The NetBSD Foundation 10 * This code is derived from software contributed to The NetBSD Foundation
11 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 11 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
12 * NASA Ames Research Center. 12 * NASA Ames Research Center.
13 * 13 *
14 * Redistribution and use in source and binary forms, with or without 14 * Redistribution and use in source and binary forms, with or without
@@ -86,27 +86,27 @@ @@ -86,27 +86,27 @@
86 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 86 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
87 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 87 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
88 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 88 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
89 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 89 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
90 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 90 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
91 * SUCH DAMAGE. 91 * SUCH DAMAGE.
92 */ 92 */
93 93
94#include <sys/cdefs.h> 94#include <sys/cdefs.h>
95#ifndef lint 95#ifndef lint
96#if 0 96#if 0
97static char sccsid[] = "@(#)cmds.c 8.6 (Berkeley) 10/9/94"; 97static char sccsid[] = "@(#)cmds.c 8.6 (Berkeley) 10/9/94";
98#else 98#else
99__RCSID("$NetBSD: cmds.c,v 1.137 2016/02/27 16:31:31 christos Exp $"); 99__RCSID("$NetBSD: cmds.c,v 1.138 2017/11/20 21:11:36 kre Exp $");
100#endif 100#endif
101#endif /* not lint */ 101#endif /* not lint */
102 102
103/* 103/*
104 * FTP User Program -- Command Routines. 104 * FTP User Program -- Command Routines.
105 */ 105 */
106#include <sys/types.h> 106#include <sys/types.h>
107#include <sys/socket.h> 107#include <sys/socket.h>
108#include <sys/stat.h> 108#include <sys/stat.h>
109#include <sys/wait.h> 109#include <sys/wait.h>
110#include <arpa/ftp.h> 110#include <arpa/ftp.h>
111 111
112#include <ctype.h> 112#include <ctype.h>
@@ -1148,27 +1148,28 @@ cd(int argc, char *argv[]) @@ -1148,27 +1148,28 @@ cd(int argc, char *argv[])
1148 UPRINTF("usage: %s remote-directory\n", argv[0]); 1148 UPRINTF("usage: %s remote-directory\n", argv[0]);
1149 code = -1; 1149 code = -1;
1150 return; 1150 return;
1151 } 1151 }
1152 r = command("CWD %s", argv[1]); 1152 r = command("CWD %s", argv[1]);
1153 if (r == ERROR && code == 500) { 1153 if (r == ERROR && code == 500) {
1154 if (verbose) 1154 if (verbose)
1155 fputs("CWD command not recognized, trying XCWD.\n", 1155 fputs("CWD command not recognized, trying XCWD.\n",
1156 ttyout); 1156 ttyout);
1157 r = command("XCWD %s", argv[1]); 1157 r = command("XCWD %s", argv[1]);
1158 } 1158 }
1159 if (r == COMPLETE) { 1159 if (r == COMPLETE) {
1160 dirchange = 1; 1160 dirchange = 1;
1161 updateremotecwd(); 1161 remotecwd[0] = '\0';
 1162 remcwdvalid = 0;
1162 } 1163 }
1163} 1164}
1164 1165
1165/* 1166/*
1166 * Set current working directory on local machine. 1167 * Set current working directory on local machine.
1167 */ 1168 */
1168void 1169void
1169lcd(int argc, char *argv[]) 1170lcd(int argc, char *argv[])
1170{ 1171{
1171 char *locdir; 1172 char *locdir;
1172 1173
1173 code = -1; 1174 code = -1;
1174 if (argc == 1) { 1175 if (argc == 1) {
@@ -1534,29 +1535,29 @@ user(int argc, char *argv[]) @@ -1534,29 +1535,29 @@ user(int argc, char *argv[])
1534/* 1535/*
1535 * Print working directory on remote machine. 1536 * Print working directory on remote machine.
1536 */ 1537 */
1537/*VARARGS*/ 1538/*VARARGS*/
1538void 1539void
1539pwd(int argc, char *argv[]) 1540pwd(int argc, char *argv[])
1540{ 1541{
1541 1542
1542 code = -1; 1543 code = -1;
1543 if (argc != 1) { 1544 if (argc != 1) {
1544 UPRINTF("usage: %s\n", argv[0]); 1545 UPRINTF("usage: %s\n", argv[0]);
1545 return; 1546 return;
1546 } 1547 }
1547 if (! remotecwd[0]) 1548 if (!remcwdvalid || remotecwd[0] == '\0')
1548 updateremotecwd(); 1549 updateremotecwd();
1549 if (! remotecwd[0]) 1550 if (remotecwd[0] == '\0')
1550 fprintf(ttyout, "Unable to determine remote directory\n"); 1551 fprintf(ttyout, "Unable to determine remote directory\n");
1551 else { 1552 else {
1552 fprintf(ttyout, "Remote directory: %s\n", remotecwd); 1553 fprintf(ttyout, "Remote directory: %s\n", remotecwd);
1553 code = 0; 1554 code = 0;
1554 } 1555 }
1555} 1556}
1556 1557
1557/* 1558/*
1558 * Print working directory on local machine. 1559 * Print working directory on local machine.
1559 */ 1560 */
1560void 1561void
1561lpwd(int argc, char *argv[]) 1562lpwd(int argc, char *argv[])
1562{ 1563{
@@ -2349,27 +2350,28 @@ cdup(int argc, char *argv[]) @@ -2349,27 +2350,28 @@ cdup(int argc, char *argv[])
2349 UPRINTF("usage: %s\n", argv[0]); 2350 UPRINTF("usage: %s\n", argv[0]);
2350 code = -1; 2351 code = -1;
2351 return; 2352 return;
2352 } 2353 }
2353 r = command("CDUP"); 2354 r = command("CDUP");
2354 if (r == ERROR && code == 500) { 2355 if (r == ERROR && code == 500) {
2355 if (verbose) 2356 if (verbose)
2356 fputs("CDUP command not recognized, trying XCUP.\n", 2357 fputs("CDUP command not recognized, trying XCUP.\n",
2357 ttyout); 2358 ttyout);
2358 r = command("XCUP"); 2359 r = command("XCUP");
2359 } 2360 }
2360 if (r == COMPLETE) { 2361 if (r == COMPLETE) {
2361 dirchange = 1; 2362 dirchange = 1;
2362 updateremotecwd(); 2363 remotecwd[0] = '\0';
 2364 remcwdvalid = 0;
2363 } 2365 }
2364} 2366}
2365 2367
2366/* 2368/*
2367 * Restart transfer at specific point 2369 * Restart transfer at specific point
2368 */ 2370 */
2369void 2371void
2370restart(int argc, char *argv[]) 2372restart(int argc, char *argv[])
2371{ 2373{
2372 2374
2373 if (argc == 0 || argc > 2) { 2375 if (argc == 0 || argc > 2) {
2374 UPRINTF("usage: %s [restart-point]\n", argv[0]); 2376 UPRINTF("usage: %s [restart-point]\n", argv[0]);
2375 code = -1; 2377 code = -1;

cvs diff -r1.84 -r1.85 src/usr.bin/ftp/ftp_var.h (expand / switch to unified diff)

--- src/usr.bin/ftp/ftp_var.h 2015/12/16 23:00:39 1.84
+++ src/usr.bin/ftp/ftp_var.h 2017/11/20 21:11:36 1.85
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: ftp_var.h,v 1.84 2015/12/16 23:00:39 christos Exp $ */ 1/* $NetBSD: ftp_var.h,v 1.85 2017/11/20 21:11:36 kre Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1996-2009 The NetBSD Foundation, Inc. 4 * Copyright (c) 1996-2009 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Luke Mewburn. 8 * by Luke Mewburn.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -259,26 +259,27 @@ GLOBAL int features[FEAT_max]; /* remote @@ -259,26 +259,27 @@ GLOBAL int features[FEAT_max]; /* remote
259#ifndef NO_EDITCOMPLETE 259#ifndef NO_EDITCOMPLETE
260GLOBAL EditLine *el; /* editline(3) status structure */ 260GLOBAL EditLine *el; /* editline(3) status structure */
261GLOBAL History *hist; /* editline(3) history structure */ 261GLOBAL History *hist; /* editline(3) history structure */
262GLOBAL char *cursor_pos; /* cursor position we're looking for */ 262GLOBAL char *cursor_pos; /* cursor position we're looking for */
263GLOBAL size_t cursor_argc; /* location of cursor in margv */ 263GLOBAL size_t cursor_argc; /* location of cursor in margv */
264GLOBAL size_t cursor_argo; /* offset of cursor in margv[cursor_argc] */ 264GLOBAL size_t cursor_argo; /* offset of cursor in margv[cursor_argc] */
265#endif /* !NO_EDITCOMPLETE */ 265#endif /* !NO_EDITCOMPLETE */
266 266
267GLOBAL char *hostname; /* name of host connected to */ 267GLOBAL char *hostname; /* name of host connected to */
268GLOBAL int unix_server; /* server is unix, can use binary for ascii */ 268GLOBAL int unix_server; /* server is unix, can use binary for ascii */
269GLOBAL int unix_proxy; /* proxy is unix, can use binary for ascii */ 269GLOBAL int unix_proxy; /* proxy is unix, can use binary for ascii */
270GLOBAL char localcwd[MAXPATHLEN]; /* local dir */ 270GLOBAL char localcwd[MAXPATHLEN]; /* local dir */
271GLOBAL char remotecwd[MAXPATHLEN]; /* remote dir */ 271GLOBAL char remotecwd[MAXPATHLEN]; /* remote dir */
 272GLOBAL int remcwdvalid; /* remotecwd has been updated */
272GLOBAL char *username; /* name of user logged in as. (dynamic) */ 273GLOBAL char *username; /* name of user logged in as. (dynamic) */
273 274
274GLOBAL sa_family_t family; /* address family to use for connections */ 275GLOBAL sa_family_t family; /* address family to use for connections */
275GLOBAL const char *ftpport; /* port number to use for FTP connections */ 276GLOBAL const char *ftpport; /* port number to use for FTP connections */
276GLOBAL const char *httpport; /* port number to use for HTTP connections */ 277GLOBAL const char *httpport; /* port number to use for HTTP connections */
277#ifdef WITH_SSL 278#ifdef WITH_SSL
278GLOBAL const char *httpsport; /* port number to use for HTTPS connections */ 279GLOBAL const char *httpsport; /* port number to use for HTTPS connections */
279#endif 280#endif
280GLOBAL const char *gateport; /* port number to use for gateftp connections */ 281GLOBAL const char *gateport; /* port number to use for gateftp connections */
281GLOBAL struct addrinfo *bindai; /* local address to bind as */ 282GLOBAL struct addrinfo *bindai; /* local address to bind as */
282 283
283GLOBAL char *outfile; /* filename to output URLs to */ 284GLOBAL char *outfile; /* filename to output URLs to */
284GLOBAL int restartautofetch; /* restart auto-fetch */ 285GLOBAL int restartautofetch; /* restart auto-fetch */

cvs diff -r1.158 -r1.159 src/usr.bin/ftp/util.c (expand / switch to unified diff)

--- src/usr.bin/ftp/util.c 2013/02/19 23:29:15 1.158
+++ src/usr.bin/ftp/util.c 2017/11/20 21:11:36 1.159
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: util.c,v 1.158 2013/02/19 23:29:15 dsl Exp $ */ 1/* $NetBSD: util.c,v 1.159 2017/11/20 21:11:36 kre Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1997-2009 The NetBSD Foundation, Inc. 4 * Copyright (c) 1997-2009 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Luke Mewburn. 8 * by Luke Mewburn.
9 * 9 *
10 * This code is derived from software contributed to The NetBSD Foundation 10 * This code is derived from software contributed to The NetBSD Foundation
11 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 11 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
12 * NASA Ames Research Center. 12 * NASA Ames Research Center.
13 * 13 *
14 * Redistribution and use in source and binary forms, with or without 14 * Redistribution and use in source and binary forms, with or without
@@ -54,27 +54,27 @@ @@ -54,27 +54,27 @@
54 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 54 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
55 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 55 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
56 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 56 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
57 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 57 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
58 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 58 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
59 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 59 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
60 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 60 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
61 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 61 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
62 * SUCH DAMAGE. 62 * SUCH DAMAGE.
63 */ 63 */
64 64
65#include <sys/cdefs.h> 65#include <sys/cdefs.h>
66#ifndef lint 66#ifndef lint
67__RCSID("$NetBSD: util.c,v 1.158 2013/02/19 23:29:15 dsl Exp $"); 67__RCSID("$NetBSD: util.c,v 1.159 2017/11/20 21:11:36 kre Exp $");
68#endif /* not lint */ 68#endif /* not lint */
69 69
70/* 70/*
71 * FTP User Program -- Misc support routines 71 * FTP User Program -- Misc support routines
72 */ 72 */
73#include <sys/param.h> 73#include <sys/param.h>
74#include <sys/socket.h> 74#include <sys/socket.h>
75#include <sys/ioctl.h> 75#include <sys/ioctl.h>
76#include <sys/time.h> 76#include <sys/time.h>
77#include <netinet/in.h> 77#include <netinet/in.h>
78#include <arpa/ftp.h> 78#include <arpa/ftp.h>
79 79
80#include <ctype.h> 80#include <ctype.h>
@@ -468,27 +468,28 @@ ftp_login(const char *host, const char * @@ -468,27 +468,28 @@ ftp_login(const char *host, const char *
468 goto cleanup_ftp_login; 468 goto cleanup_ftp_login;
469 469
470 connected = -1; 470 connected = -1;
471 getremoteinfo(); 471 getremoteinfo();
472 for (n = 0; n < macnum; ++n) { 472 for (n = 0; n < macnum; ++n) {
473 if (!strcmp("init", macros[n].mac_name)) { 473 if (!strcmp("init", macros[n].mac_name)) {
474 (void)strlcpy(line, "$init", sizeof(line)); 474 (void)strlcpy(line, "$init", sizeof(line));
475 makeargv(); 475 makeargv();
476 domacro(margc, margv); 476 domacro(margc, margv);
477 break; 477 break;
478 } 478 }
479 } 479 }
480 updatelocalcwd(); 480 updatelocalcwd();
481 updateremotecwd(); 481 remotecwd[0] = '\0';
 482 remcwdvalid = 0;
482 483
483 cleanup_ftp_login: 484 cleanup_ftp_login:
484 FREEPTR(fuser); 485 FREEPTR(fuser);
485 if (pass != NULL) 486 if (pass != NULL)
486 memset(pass, 0, strlen(pass)); 487 memset(pass, 0, strlen(pass));
487 FREEPTR(pass); 488 FREEPTR(pass);
488 if (facct != NULL) 489 if (facct != NULL)
489 memset(facct, 0, strlen(facct)); 490 memset(facct, 0, strlen(facct));
490 FREEPTR(facct); 491 FREEPTR(facct);
491 return (rval); 492 return (rval);
492} 493}
493 494
494/* 495/*
@@ -825,26 +826,27 @@ updatelocalcwd(void) @@ -825,26 +826,27 @@ updatelocalcwd(void)
825 DPRINTF("updatelocalcwd: got `%s'\n", localcwd); 826 DPRINTF("updatelocalcwd: got `%s'\n", localcwd);
826} 827}
827 828
828/* 829/*
829 * Update global `remotecwd', which contains the state of the remote cwd 830 * Update global `remotecwd', which contains the state of the remote cwd
830 */ 831 */
831void 832void
832updateremotecwd(void) 833updateremotecwd(void)
833{ 834{
834 int overbose, ocode; 835 int overbose, ocode;
835 size_t i; 836 size_t i;
836 char *cp; 837 char *cp;
837 838
 839 remcwdvalid = 1; /* whether it works or not, we are done */
838 overbose = verbose; 840 overbose = verbose;
839 ocode = code; 841 ocode = code;
840 if (ftp_debug == 0) 842 if (ftp_debug == 0)
841 verbose = -1; 843 verbose = -1;
842 if (command("PWD") != COMPLETE) 844 if (command("PWD") != COMPLETE)
843 goto badremotecwd; 845 goto badremotecwd;
844 cp = strchr(reply_string, ' '); 846 cp = strchr(reply_string, ' ');
845 if (cp == NULL || cp[0] == '\0' || cp[1] != '"') 847 if (cp == NULL || cp[0] == '\0' || cp[1] != '"')
846 goto badremotecwd; 848 goto badremotecwd;
847 cp += 2; 849 cp += 2;
848 for (i = 0; *cp && i < sizeof(remotecwd) - 1; i++, cp++) { 850 for (i = 0; *cp && i < sizeof(remotecwd) - 1; i++, cp++) {
849 if (cp[0] == '"') { 851 if (cp[0] == '"') {
850 if (cp[1] == '"') 852 if (cp[1] == '"')
@@ -1164,26 +1166,28 @@ formatbuf(char *buf, size_t len, const c @@ -1164,26 +1166,28 @@ formatbuf(char *buf, size_t len, const c
1164 p = src; 1166 p = src;
1165 for (i = 0; *p; p++) { 1167 for (i = 0; *p; p++) {
1166 if (*p != '%') { 1168 if (*p != '%') {
1167 ADDBUF(*p); 1169 ADDBUF(*p);
1168 continue; 1170 continue;
1169 } 1171 }
1170 p++; 1172 p++;
1171 1173
1172 switch (op = *p) { 1174 switch (op = *p) {
1173 1175
1174 case '/': 1176 case '/':
1175 case '.': 1177 case '.':
1176 case 'c': 1178 case 'c':
 1179 if (connected && !remcwdvalid)
 1180 updateremotecwd();
1177 p2 = connected ? remotecwd : ""; 1181 p2 = connected ? remotecwd : "";
1178 updirs = pdirs = 0; 1182 updirs = pdirs = 0;
1179 1183
1180 /* option to determine fixed # of dirs from path */ 1184 /* option to determine fixed # of dirs from path */
1181 if (op == '.' || op == 'c') { 1185 if (op == '.' || op == 'c') {
1182 int skip; 1186 int skip;
1183 1187
1184 q = p2; 1188 q = p2;
1185 while (*p2) /* calc # of /'s */ 1189 while (*p2) /* calc # of /'s */
1186 if (*p2++ == '/') 1190 if (*p2++ == '/')
1187 updirs++; 1191 updirs++;
1188 if (p[1] == '0') { /* print <x> or ... */ 1192 if (p[1] == '0') { /* print <x> or ... */
1189 pdirs = 1; 1193 pdirs = 1;