Merge pull request #5 from ksherlock/ftp-update

ftp passive mode
This commit is contained in:
Devin Reade 2012-09-08 15:44:32 -07:00
commit 44ab20dfb9
6 changed files with 115 additions and 24 deletions

View File

@ -46,6 +46,26 @@ extern char reply_string[];
char *mname;
jmp_buf jabort;
/*
* Toggle a variable
*/
int togglevar(int argc, char ** argv, int *var, const char *mesg)
{
if (argc < 2) {
*var = !*var;
} else if (argc == 2 && strcasecmp(argv[1], "on") == 0) {
*var = 1;
} else if (argc == 2 && strcasecmp(argv[1], "off") == 0) {
*var = 0;
} else {
printf("usage: %s [ on | off ]\n", argv[0]);
return (-1);
}
if (mesg)
printf("%s %s.\n", mesg, onoff(*var));
return (*var);
}
/*
* `Another' gets another argument, and stores the new argc and argv.
* It reverts to the top level (via main.c's intr()) on EOF/error.
@ -830,9 +850,7 @@ int i;
/*VARARGS*/
void setbell (int argc, char **argv)
{
bell = !bell;
printf("Bell mode %s.\n", onoff(bell));
code = bell;
code = togglevar(argc, argv, &bell, "Bell mode");
}
/*
@ -841,9 +859,7 @@ void setbell (int argc, char **argv)
/*VARARGS*/
void settrace (int argc, char **argv)
{
trace = !trace;
printf("Packet tracing %s.\n", onoff(trace));
code = trace;
code = togglevar(argc, argv, &trace, "Packet tracing");
}
/*
@ -866,9 +882,7 @@ void sethash (int argc, char **argv)
/*VARARGS*/
void setverbose (int argc, char **argv)
{
verbose = !verbose;
printf("Verbose mode %s.\n", onoff(verbose));
code = verbose;
code = togglevar(argc, argv, &verbose, "Verbose mode");
}
/*
@ -877,9 +891,7 @@ void setverbose (int argc, char **argv)
/*VARARGS*/
void setport (int argc, char **argv)
{
sendport = !sendport;
printf("Use of PORT cmds %s.\n", onoff(sendport));
code = sendport;
code = togglevar(argc, argv, &sendport, "Use of PORT cmds");
}
/*
@ -889,9 +901,7 @@ void setport (int argc, char **argv)
/*VARARGS*/
void setprompt (int argc, char **argv)
{
interactive = !interactive;
printf("Interactive mode %s.\n", onoff(interactive));
code = interactive;
code = togglevar(argc, argv, &interactive, "Interactive mode");
}
/*
@ -901,9 +911,7 @@ void setprompt (int argc, char **argv)
/*VARARGS*/
void setglob (int argc, char **argv)
{
doglob = !doglob;
printf("Globbing %s.\n", onoff(doglob));
code = doglob;
code = togglevar(argc, argv, &doglob, "Globbing");
}
/*
@ -979,6 +987,18 @@ static char buf[MAXPATHLEN];
code = 0;
}
void lpwd(int argc, char **argv)
{
static char buf[MAXPATHLEN];
if (getcwd(buf, sizeof(buf)) != NULL)
printf("Local directory %s\n", buf);
else
fprintf(stderr, "getcwd: %s\n", strerror(errno));
code = 0;
}
/*
* Delete a single file.
*/
@ -1844,18 +1864,20 @@ LOOP:
return(new);
}
void setpassive(int argc, char **argv)
{
code = togglevar(argc, argv, &passivemode,
verbose ? "Passive mode" : (char *)NULL);
}
void setsunique (int argc, char **argv)
{
sunique = !sunique;
printf("Store unique %s.\n", onoff(sunique));
code = sunique;
code = togglevar(argc, argv, &sunique, "Store unique");
}
void setrunique (int argc, char **argv)
{
runique = !runique;
printf("Receive unique %s.\n", onoff(runique));
code = runique;
code = togglevar(argc, argv, &runique, "Receive unique");
}
/* change directory to perent directory */

View File

@ -10,6 +10,7 @@ void setbell (int argc, char **argv);
void settrace (int argc, char **argv);
void sethash (int argc, char **argv);
void setverbose (int argc, char **argv);
void setpassive (int argc, char **argv);
void setport (int argc, char **argv);
void setprompt (int argc, char **argv);
void setglob (int argc, char **argv);
@ -45,6 +46,7 @@ void mget (int argc, char **argv);
void status (int argc, char **argv);
void cd (int argc, char **argv);
void lcd (int argc, char **argv);
void lpwd (int argc, char **argv);
void delete (int argc, char **argv);
void mdelete (int argc, char **argv);
void renamefile (int argc, char **argv);

View File

@ -34,6 +34,7 @@ char hashhelp[] = "toggle printing `#' for each buffer transferred";
char helphelp[] = "print local help information";
char idlehelp[] = "get (set) idle timer on remote side";
char lcdhelp[] = "change local working directory";
char lpwdhelp[] = "print local working directory";
char lshelp[] = "list contents of remote directory";
char macdefhelp[] = "define a macro";
char mdeletehelp[] = "delete multiple files";
@ -48,6 +49,7 @@ char newerhelp[] = "get file if remote file is newer than local file ";
char nlisthelp[] = "nlist contents of remote directory";
char nmaphelp[] = "set templates for default file name mapping";
char ntranshelp[] = "set translation table for default file name mapping";
char passivehelp[] = "enter passive transfer mode";
char porthelp[] = "toggle use of PORT cmd for each data connection";
char prompthelp[] = "force interactive prompting on multiple commands";
char proxyhelp[] = "issue command on alternate connection";
@ -105,6 +107,7 @@ struct cmd cmdtab[] = {
{ "idle", idlehelp, 0, 1, 1, idle },
{ "image", binaryhelp, 0, 1, 1, setbinary },
{ "lcd", lcdhelp, 0, 0, 0, lcd },
{ "lpwd", lpwdhelp, 0, 0, 0, lpwd },
{ "ls", lshelp, 1, 1, 1, ls },
{ "macdef", macdefhelp, 0, 0, 0, macdef },
{ "mdelete", mdeletehelp, 1, 1, 1, mdelete },
@ -120,6 +123,7 @@ struct cmd cmdtab[] = {
{ "nlist", nlisthelp, 1, 1, 1, ls },
{ "ntrans", ntranshelp, 0, 0, 1, setntrans },
{ "open", connecthelp, 0, 0, 1, setpeer },
{ "passive", passivehelp, 0, 0, 0, setpassive },
{ "prompt", prompthelp, 0, 0, 0, setprompt },
{ "proxy", proxyhelp, 0, 0, 1, doproxy },
{ "sendport", porthelp, 0, 0, 0, setport },

View File

@ -974,6 +974,64 @@ int initconn (void)
unsigned char *p, *a;
int result, len, tmpno = 0;
int on = 1;
int a1,a2,a3,a4,p1,p2;
if (passivemode) {
data = socket(AF_INET, SOCK_STREAM, 0);
if (data < 0) {
perror("ftp: socket");
return(1);
}
if (options & SO_DEBUG &&
setsockopt(data, SOL_SOCKET, SO_DEBUG, (char *)&on,
sizeof (on)) < 0)
perror("ftp: setsockopt (ignored)");
if (command("PASV") != COMPLETE) {
printf("Passive mode refused.\n");
return(1);
}
/*
* What we've got at this point is a string of comma separated
* one-byte unsigned integer values, separated by commas.
* The first four are the an IP address. The fifth is the MSB
* of the port number, the sixth is the LSB. From that we'll
* prepare a sockaddr_in.
*/
if (sscanf(pasv,"%d,%d,%d,%d,%d,%d",&a1,&a2,&a3,&a4,&p1,&p2)
!= 6) {
printf("Passive mode address scan failure. Shouldn't happen!\n");
return(1);
};
data_addr.sin_family = AF_INET;
#ifdef __GNO__
// s_addr is a 32-bit value which overflows the
// int shift.
data_addr.sin_addr.S_un.S_un_b.s_b1 = a1;
data_addr.sin_addr.S_un.S_un_b.s_b2 = a2;
data_addr.sin_addr.S_un.S_un_b.s_b3 = a3;
data_addr.sin_addr.S_un.S_un_b.s_b4 = a4;
#else
data_addr.sin_addr.s_addr = htonl((a1 << 24) | (a2 << 16) |
(a3 << 8) | a4);
#endif
data_addr.sin_port = htons((p1 << 8) | p2);
if (connect(data, (struct __SOCKADDR *) &data_addr, sizeof(data_addr)) < 0) {
perror("ftp: connect");
return(1);
}
#if defined(IP_TOS) && defined(IPTOS_THROUGHPUT)
on = IPTOS_THROUGHPUT;
if (setsockopt(data, IPPROTO_IP, IP_TOS, (char *)&on,
sizeof(int)) < 0)
perror("ftp: setsockopt TOS (ignored)");
#endif
return(0);
}
noport:
data_addr = myctladdr;
@ -1042,6 +1100,9 @@ FILE *dataconn (char *lmode)
struct sockaddr_in from;
int s, fromlen = sizeof (from), tos;
if (passivemode)
return (fdopen(data, lmode));
s = accept(data, (struct __SOCKADDR *) &from, &fromlen);
if (s < 0) {
perror("ftp: accept");

View File

@ -61,6 +61,7 @@ extern int mapflag; /* use mapin mapout templates on file names */
extern int code; /* return/reply code for ftp command */
extern int crflag; /* if 1, strip car. rets. on ascii gets */
extern char pasv[64]; /* passive port for proxy data connection */
extern int passivemode; /* passive mode enabled */
extern char *altarg; /* argv[1] with no shell-like preprocessing */
extern char ntin[17]; /* input translation table */
extern char ntout[17]; /* output translation table */

View File

@ -53,6 +53,7 @@ static char homedir[MAXPATHLEN];
doglob = 1;
interactive = 1;
autologin = 1;
passivemode = 1;
argc--, argv++;
while (argc > 0 && **argv == '-') {
for (cp = *argv + 1; *cp; cp++)