diff --git a/usr.bin/ncftp/cmds.c b/usr.bin/ncftp/cmds.c index d576803ea19f..564c79910ea1 100644 --- a/usr.bin/ncftp/cmds.c +++ b/usr.bin/ncftp/cmds.c @@ -36,14 +36,12 @@ #include "copyright.h" /* cmds.c globals */ -#ifdef PASSIVEMODE -int passivemode; /* no reverse FTP connections */ -#endif int curtype; /* file transfer type */ char *typeabbrs = "abiet"; str32 curtypename; /* name of file transfer type */ int verbose; /* verbosity level of output */ int mprompt; /* interactively prompt on m* cmds */ +int passivemode; /* no reverse FTP connections */ int debug; /* debugging level */ int options; /* used during socket creation */ int macnum; /* number of defined macros */ @@ -52,7 +50,9 @@ int creating = 0; struct macel macros[MAXMACROS]; char *macbuf; /* holds ALL macros */ int doingInitMacro = 0; /* TRUE if executing "init" macro. */ +static char pad1a[8] = "Pad 1a"; jmp_buf jabort; +static char pad1b[8] = "Pad 1b"; char *mname; /* name of current m* command */ int activemcmd; /* flag: if != 0, then active multi command */ int warnNoLSFlagsWithWildcards = 0; @@ -2059,9 +2059,6 @@ int show_version(int argc, char **argv) #ifdef NET_ERRNO_H DStrs[nDStrs++] = "NET_ERRNO_H"; #endif -#ifdef PASSIVEMODE - DStrs[nDStrs++] = "PASSIVEMODE"; -#endif /* DONE with #ifdefs for now! */ @@ -2215,14 +2212,12 @@ int unimpl(int argc, char **argv) return (NOERR); } /* unimpl */ -#ifdef PASSIVEMODE int setpassive(int argc, char **argv) { passivemode = !passivemode; printf( "Passive mode %s.\n", (passivemode ? "ON" : "OFF") ); return NOERR; } -#endif /* eof cmds.c */ diff --git a/usr.bin/ncftp/cmds.h b/usr.bin/ncftp/cmds.h index 11dff6acc06d..0f8bce0b65fe 100644 --- a/usr.bin/ncftp/cmds.h +++ b/usr.bin/ncftp/cmds.h @@ -121,9 +121,7 @@ int unimpl(int argc, char **argv); long GetDateSizeFromLSLine(char *fName, unsigned long *mod_time); long GetDateAndSize(char *fName, unsigned long *mod_time); int SetTypeByNumber(int i); -#ifdef PASSIVEMODE int setpassive(int argc, char **argv); -#endif /* In util.c: */ diff --git a/usr.bin/ncftp/cmdtab.c b/usr.bin/ncftp/cmdtab.c index d4e161f3fcc5..86d4a5fce9b7 100644 --- a/usr.bin/ncftp/cmdtab.c +++ b/usr.bin/ncftp/cmdtab.c @@ -90,10 +90,7 @@ Examples:\n\ #define PAGEHELP "view a file on the remote host with your $PAGER" #define PAGEUSAGE REMOTEFILE -#ifdef PASSIVEMODE #define PASSIVEHELP "enter passive transfer mode" -#endif - #define PDIRUSAGE " [flags] [remote-files]" @@ -191,9 +188,7 @@ struct cmd cmdtab[] = { { "ntrans", 0, 1, unimpl, UNIMPLHELP, UNIMPLUSAGE }, { "open", 0, 0, cmdOpen, OPENHELP, OPENUSAGE }, { "p", 1, 1, get, PAGEHELP, PAGEUSAGE }, -#ifdef PASSIVEMODE { "passive", 0, 0, setpassive, PASSIVEHELP, EMPTYSTR }, -#endif { "page", 1, 0, get, PAGEHELP, PAGEUSAGE }, { "pdir", 1, 0, ls, "view a remote directory listing (long mode) with your $PAGER", diff --git a/usr.bin/ncftp/defaults.h b/usr.bin/ncftp/defaults.h index f3fbb0814cda..5ce57784a43b 100644 --- a/usr.bin/ncftp/defaults.h +++ b/usr.bin/ncftp/defaults.h @@ -44,10 +44,6 @@ #define dMPROMPT 0 #endif -#ifndef PASSIVEMODE -#define PASSIVEMODE 1 -#endif - /* If passive FTP can be used, this specifies whether it is turned on * by default. If not, we have passive mode available, but are using * Port ftp by default. diff --git a/usr.bin/ncftp/ftp.c b/usr.bin/ncftp/ftp.c index fe35d1a6272f..ecb2136280d2 100644 --- a/usr.bin/ncftp/ftp.c +++ b/usr.bin/ncftp/ftp.c @@ -64,10 +64,15 @@ int abrtflag = 0; struct sockaddr_in myctladdr; FILE *cin = NULL, *cout = NULL; char *reply_string = NULL; -jmp_buf sendabort, recvabort; +static char pad3a[8] = "Pad 3a"; /* For SunOS :-( */ +jmp_buf sendabort; +static char pad3b[8] = "Pad 3b"; +jmp_buf recvabort; +static char pad3c[8] = "Pad 3c"; int progress_meter = dPROGRESS; int cur_progress_meter; int sendport = -1; /* use PORT cmd for each data connection */ +int using_pasv; int code; /* return/reply code for ftp command */ string indataline; int cpend; /* flag: if != 0, then pending server reply */ @@ -99,9 +104,7 @@ extern struct userinfo uinfo; extern struct macel macros[]; extern struct lslist *lshead, *lstail; extern int is_ls; -#ifdef PASSIVEMODE extern int passivemode; -#endif #ifdef GATEWAY extern string gateway; @@ -244,6 +247,7 @@ int hookup(char *host, unsigned int port) #endif /* SO_OOBINLINE */ hErr = 0; + using_pasv = passivemode; /* Re-init for each new connection. */ goto done; bad: @@ -564,6 +568,8 @@ int getreply(int expecteof) } /* end for(;;) #2 */ *cp = '\0'; + dbprintf("rsp: %s", reply_string); + switch (verbose) { case V_QUIET: /* Don't print anything. */ @@ -1693,15 +1699,38 @@ int initconn(void) int on = 1, rval; string str; Sig_t oldintr; -#ifdef PASSIVEMODE + char *cp; int a1, a2, a3, a4, p1, p2; unsigned char n[6]; -#endif oldintr = Signal(SIGINT, SIG_IGN); -#ifdef PASSIVEMODE - if (passivemode) { + if (using_pasv) { + result = command("PASV"); + if (result != COMPLETE) { + printf("Passive mode refused.\n"); + using_pasv = 0; + goto TryPort; + } + + /* + * What we've got here is a string of comma separated one-byte + * unsigned integer values. The first four are the IP address, + * the fifth is the MSB of the port address, and the sixth is the + * LSB of the port address. Extract this data and prepare a + * 'data_addr' (struct sockaddr_in). + */ + for (cp = reply_string + 4; *cp != '\0'; cp++) + if (isdigit(*cp)) + break; + + if (sscanf(cp, "%d,%d,%d,%d,%d,%d", + &a1, &a2, &a3, &a4, &p1, &p2) != 6) { + printf("Cannot parse PASV response: %s\n", reply_string); + using_pasv = 0; + goto TryPort; + } + data = socket(AF_INET, SOCK_STREAM, 0); if (data < 0) { PERROR("initconn", "socket"); @@ -1712,25 +1741,7 @@ int initconn(void) setsockopt(data, SOL_SOCKET, SO_DEBUG, (char *)&on, sizeof(on)) < 0 ) { PERROR("initconn", "setscokopt (ignored)"); } - result = command("PASV"); - if (result != COMPLETE) { - printf("Passive mode refused.\n"); - rval = 1; - goto Return; - } - /* - * What we've got here is a string of comma separated one-byte - * unsigned integer values. The first four are the IP address, - * the fifth is the MSB of the port address, and the sixth is the - * LSB of the port address. Extract this data and prepare a - * 'data_addr' (struct sockaddr_in). - */ - if (sscanf(reply_string+27, "%d,%d,%d,%d,%d,%d", - &a1, &a2, &a3, &a4, &p1, &p2) != 6) { - printf("Cannot parse PASV response: %s\n", reply_string); - rval = 1; - goto Return; - } + n[0] = (unsigned char) a1; n[1] = (unsigned char) a2; n[2] = (unsigned char) a3; @@ -1743,6 +1754,14 @@ int initconn(void) bcopy( (void *)&n[4], (void *)&data_addr.sin_port, 2 ); if (Connect( data, &data_addr, sizeof(data_addr) ) < 0 ) { + if (errno == ECONNREFUSED) { + dbprintf("Could not connect to port specified by server;\n"); + dbprintf("Falling back to PORT mode.\n"); + close(data); + data = -1; + using_pasv = 0; + goto TryPort; + } PERROR("initconn", "connect"); rval = 1; goto Return; @@ -1750,7 +1769,9 @@ int initconn(void) rval = 0; goto Return; } -#endif + +TryPort: + rval = 0; noport: data_addr = myctladdr; @@ -1765,11 +1786,13 @@ int initconn(void) sendport = 1; rval = 1; goto Return; } + if (!sendport) if (setsockopt(data, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof (on)) < 0) { PERROR("initconn", "setsockopt (reuse address)"); goto bad; } + #ifdef SOCKS if (Rbind(data, (struct sockaddr *)&data_addr, sizeof (data_addr), hisctladdr.sin_addr.s_addr) < 0) { #else @@ -1859,10 +1882,8 @@ dataconn(char *mode) #ifdef SOCKS s = Raccept(data, (struct sockaddr *) &from, &fromlen); #else -#ifdef PASSIVEMODE - if (passivemode) + if (using_pasv) return( fdopen( data, mode )); -#endif s = Accept(data, &from, &fromlen); #endif if (s < 0) { diff --git a/usr.bin/ncftp/main.c b/usr.bin/ncftp/main.c index 9fdfc06ec0a5..1d1ed62de147 100644 --- a/usr.bin/ncftp/main.c +++ b/usr.bin/ncftp/main.c @@ -2,7 +2,7 @@ #define _main_c_ -#define FTP_VERSION "1.8.7 (December 11, 1994)" +#define FTP_VERSION "1.9.0 (December 22, 1994)" /* #define BETA 1 */ /* If defined, it prints a little warning message. */ @@ -46,7 +46,9 @@ int toatty; /* output is to a terminal */ int doing_script; /* is a file being