More enhancements/bugfixes (when will it end?)

* differentiate between being connected, and being logged in
* cleanup some text messages
* support username & password ftp URLs (ftp://user:pass@host/) in non-proxy
  situations; assume proxy supports it for proxy situations.
* cd to / before performing any autofetch transfers
* use strncasecmp in URL parsing. fix from <Todd.Miller@courtesan.com>
This commit is contained in:
lukem 1997-04-14 09:09:15 +00:00
parent 1ef9434f47
commit a9a78ba448
8 changed files with 204 additions and 155 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: cmds.c,v 1.22 1997/04/05 03:27:32 lukem Exp $ */
/* $NetBSD: cmds.c,v 1.23 1997/04/14 09:09:15 lukem Exp $ */
/*
* Copyright (c) 1985, 1989, 1993, 1994
@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)cmds.c 8.6 (Berkeley) 10/9/94";
#else
static char rcsid[] = "$NetBSD: cmds.c,v 1.22 1997/04/05 03:27:32 lukem Exp $";
static char rcsid[] = "$NetBSD: cmds.c,v 1.23 1997/04/14 09:09:15 lukem Exp $";
#endif
#endif /* not lint */
@ -629,7 +629,8 @@ status(argc, argv)
int i;
if (connected)
printf("Connected to %s.\n", hostname);
printf("Connected %sto %s.\n",
connected == -1 ? "and logged in" : "", hostname);
else
puts("Not connected.");
if (!proxy) {
@ -1234,6 +1235,7 @@ user(argc, argv)
if (!aflag && argc == 4) {
(void)command("ACCT %s", argv[3]);
}
connected = -1;
}
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: complete.c,v 1.6 1997/03/16 14:24:16 lukem Exp $ */
/* $NetBSD: complete.c,v 1.7 1997/04/14 09:09:16 lukem Exp $ */
/*-
* Copyright (c) 1997 The NetBSD Foundation, Inc.
@ -38,7 +38,7 @@
#ifndef SMALL
#ifndef lint
static char rcsid[] = "$NetBSD: complete.c,v 1.6 1997/03/16 14:24:16 lukem Exp $";
static char rcsid[] = "$NetBSD: complete.c,v 1.7 1997/04/14 09:09:16 lukem Exp $";
#endif /* not lint */
/*
@ -364,8 +364,8 @@ complete(el, ch)
return (complete_local(word, dolist));
case 'r': /* remote complete */
case 'R':
if (!connected) {
puts("\nMust be connected to complete.");
if (connected != -1) {
puts("\nMust be logged in to complete.");
return (CC_REDISPLAY);
}
return (complete_remote(word, dolist));

View File

@ -1,4 +1,4 @@
/* $NetBSD: extern.h,v 1.14 1997/04/05 03:27:34 lukem Exp $ */
/* $NetBSD: extern.h,v 1.15 1997/04/14 09:09:17 lukem Exp $ */
/*-
* Copyright (c) 1994 The Regents of the University of California.
@ -81,7 +81,7 @@ int initconn __P((void));
void intr __P((void));
void list_vertical __P((StringList *));
void lcd __P((int, char **));
int login __P((const char *));
int login __P((const char *, char *, char *));
void lostpeer __P((void));
void lpwd __P((int, char **));
void ls __P((int, char **));

View File

@ -1,4 +1,4 @@
/* $NetBSD: fetch.c,v 1.5 1997/04/05 03:27:36 lukem Exp $ */
/* $NetBSD: fetch.c,v 1.6 1997/04/14 09:09:19 lukem Exp $ */
/*-
* Copyright (c) 1997 The NetBSD Foundation, Inc.
@ -37,7 +37,7 @@
*/
#ifndef lint
static char rcsid[] = "$NetBSD: fetch.c,v 1.5 1997/04/05 03:27:36 lukem Exp $";
static char rcsid[] = "$NetBSD: fetch.c,v 1.6 1997/04/14 09:09:19 lukem Exp $";
#endif /* not lint */
/*
@ -96,9 +96,9 @@ url_get(line, proxyenv)
s = -1;
proxy = NULL;
if (strncmp(line, HTTP_URL, sizeof(HTTP_URL) - 1) == 0)
if (strncasecmp(line, HTTP_URL, sizeof(HTTP_URL) - 1) == 0)
host = line + sizeof(HTTP_URL) - 1;
else if (strncmp(line, FTP_URL, sizeof(FTP_URL) - 1) == 0)
else if (strncasecmp(line, FTP_URL, sizeof(FTP_URL) - 1) == 0)
host = line + sizeof(FTP_URL) - 1;
else
errx(1, "url_get: invalid url '%s'", line);
@ -122,12 +122,12 @@ url_get(line, proxyenv)
proxy = strdup(proxyenv);
if (proxy == NULL)
errx(1, "Can't allocate memory for proxy url.");
if (strncmp(proxy, HTTP_URL, sizeof(HTTP_URL) - 1) == 0)
if (strncasecmp(proxy, HTTP_URL, sizeof(HTTP_URL) - 1) == 0)
host = proxy + sizeof(HTTP_URL) - 1;
else if (strncmp(proxy, FTP_URL, sizeof(FTP_URL) - 1) == 0)
else if (strncasecmp(proxy, FTP_URL, sizeof(FTP_URL) - 1) == 0)
host = proxy + sizeof(FTP_URL) - 1;
else {
warnx("Malformed proxy url: %s", proxy);
warnx("Malformed proxy URL: %s", proxy);
goto cleanup_url_get;
}
if (EMPTYSTRING(host))
@ -152,7 +152,7 @@ url_get(line, proxyenv)
if (isdigit(host[0])) {
if (inet_aton(host, &sin.sin_addr) == 0) {
warnx("invalid IP address: %s", host);
warnx("Invalid IP address: %s", host);
goto cleanup_url_get;
}
} else {
@ -173,7 +173,7 @@ url_get(line, proxyenv)
if (! EMPTYSTRING(portnum)) {
port = atoi(portnum);
if (port < 1 || (port & 0xffff) != port) {
warnx("invalid port: %s", portnum);
warnx("Invalid port: %s", portnum);
goto cleanup_url_get;
}
port = htons(port);
@ -326,7 +326,7 @@ url_get(line, proxyenv)
return (0);
improper:
warnx("improper response from %s", host);
warnx("Improper response from %s", host);
cleanup_url_get:
if (s != -1)
close(s);
@ -371,6 +371,7 @@ auto_fetch(argc, argv)
static char lasthost[MAXHOSTNAMELEN];
char *xargv[5];
char *cp, *line, *host, *dir, *file, *portnum;
char *user, *pass;
char *ftpproxy, *httpproxy;
int rval, xargc, argpos;
int dirhasglob, filehasglob;
@ -395,7 +396,7 @@ auto_fetch(argc, argv)
for (rval = 0; (rval == 0) && (argpos < argc); free(line), argpos++) {
if (strchr(argv[argpos], ':') == NULL)
break;
host = dir = file = portnum = NULL;
host = dir = file = portnum = user = pass = NULL;
/*
* We muck with the string, so we make a copy.
@ -407,7 +408,7 @@ auto_fetch(argc, argv)
/*
* Try HTTP URL-style arguments first.
*/
if (strncmp(line, HTTP_URL, sizeof(HTTP_URL) - 1) == 0) {
if (strncasecmp(line, HTTP_URL, sizeof(HTTP_URL) - 1) == 0) {
if (url_get(line, httpproxy) == -1)
rval = argpos + 1;
continue;
@ -419,21 +420,46 @@ auto_fetch(argc, argv)
* Finally, try host:file.
*/
host = line;
if (strncmp(line, FTP_URL, sizeof(FTP_URL) - 1) == 0) {
if (strncasecmp(line, FTP_URL, sizeof(FTP_URL) - 1) == 0) {
if (ftpproxy) {
if (url_get(line, ftpproxy) == -1)
rval = argpos + 1;
continue;
}
host += sizeof(FTP_URL) - 1;
cp = strchr(host, '/');
dir = strchr(host, '/');
/* Look for a port number after the host name. */
/* look for [user:pass@]host[:port] */
user = host;
pass = strpbrk(user, ":@/");
if (pass == NULL || *pass == '/')
goto parsed_url;
if (*pass == '@') {
warnx("Bad ftp URL: %s", argv[argpos]);
rval = argpos + 1;
continue;
}
*pass++ = '\0';
cp = strpbrk(pass, ":@/");
if (cp == NULL || *cp == '/') {
portnum = pass;
user = pass = NULL;
goto parsed_url;
}
if (*cp == ':') {
warnx("Bad ftp URL: %s", argv[argpos]);
rval = argpos + 1;
continue;
}
*cp++ = '\0';
host = cp;
portnum = strchr(host, ':');
if (portnum != NULL)
*portnum++ = '\0';
} else /* classic style `host:file' */
cp = strchr(host, ':');
parsed_url:
} else { /* classic style `host:file' */
dir = strchr(host, ':');
}
if (EMPTYSTRING(host)) {
rval = argpos + 1;
continue;
@ -443,15 +469,14 @@ auto_fetch(argc, argv)
* If cp is NULL, the file wasn't specified
* (URL looked something like ftp://host)
*/
if (cp != NULL)
*cp++ = '\0';
if (dir != NULL)
*dir++ = '\0';
/*
* Extract the file and (if present) directory name.
*/
dir = cp;
if (! EMPTYSTRING(dir)) {
cp = strrchr(cp, '/');
cp = strrchr(dir, '/');
if (cp != NULL) {
*cp++ = '\0';
file = cp;
@ -461,13 +486,15 @@ auto_fetch(argc, argv)
}
}
if (debug)
printf("host '%s', dir '%s', file '%s'\n",
host, dir, file);
printf("user %s:%s host %s port %s dir %s file %s\n",
user, pass, host, portnum, dir, file);
/*
* Set up the connection if we don't have one.
*/
if (strcmp(host, lasthost) != 0) {
int oautologin;
(void)strcpy(lasthost, host);
if (connected)
disconnect(0, NULL);
@ -475,14 +502,20 @@ auto_fetch(argc, argv)
xargv[1] = host;
xargv[2] = NULL;
xargc = 2;
if (portnum != NULL) {
if (! EMPTYSTRING(portnum)) {
xargv[2] = portnum;
xargv[3] = NULL;
xargc = 3;
}
oautologin = autologin;
if (user != NULL)
autologin = 0;
setpeer(xargc, xargv);
if (connected == 0) {
warnx("Can't connect to host `%s'", host);
autologin = oautologin;
if ((connected == 0)
|| ((connected == 1) && !login(host, user, pass)) ) {
warnx("Can't connect or login to host `%s'",
host);
rval = argpos + 1;
continue;
}
@ -490,16 +523,14 @@ auto_fetch(argc, argv)
/* Always use binary transfers. */
setbinary(0, NULL);
}
else /* already have connection, cd back to '/' */
{
xargv[0] = "cd";
xargv[1] = "/";
xargv[2] = NULL;
cd(2, xargv);
if (! dirchange) {
rval = argpos + 1;
continue;
}
/* cd back to '/' */
xargv[0] = "cd";
xargv[1] = "/";
xargv[2] = NULL;
cd(2, xargv);
if (! dirchange) {
rval = argpos + 1;
continue;
}
dirhasglob = filehasglob = 0;

View File

@ -1,4 +1,4 @@
.\" $NetBSD: ftp.1,v 1.19 1997/04/05 03:27:37 lukem Exp $
.\" $NetBSD: ftp.1,v 1.20 1997/04/14 09:09:20 lukem Exp $
.\"
.\" Copyright (c) 1985, 1989, 1990, 1993
.\" The Regents of the University of California. All rights reserved.
@ -56,7 +56,7 @@ file transfer program
.Op Fl V
.Op Ar host Op Ar port
.Nm ftp
ftp://\fIhost\fR[:\fIport\fR]/\fIfile\fR[/]
ftp://[\fIuser\fR:\fIpassword\fR@]\fIhost\fR[:\fIport\fR]/\fIfile\fR[/]
.Nm ftp
http://\fIhost\fR[:\fIport\fR]/\fIfile\fR
.Nm ftp
@ -1007,18 +1007,26 @@ To enable auto-fetch, simply pass the list of hostnames/files
on the command line.
.Pp
The following formats are valid syntax for an auto-fetch element:
.Bl -tag -width "http://host[:port]/file"
.Bl -tag -width "host:/file"
.It host:/file
.Dq Classic
ftp format
.It ftp://host[:port]/file
FTP URL, using the ftp protocol if
.It ftp://[user:password@]host[:port]/file
An ftp URL, retrieved using the ftp protocol if
.Ev ftp_proxy
isn't defined.
Otherwise, transfer using http via the proxy defined in
.Ev ftp_proxy .
If
.Ar user:password@
is given and
.Ev ftp_proxy
isn't defined, login as
.Ar user
with a password of
.Ar password .
.It http://host[:port]/file
HTTP URL, using the http protocol.
An HTTP URL, retrieved using the http protocol.
If
.Ev http_proxy
is defined, it is used as a URL to an HTTP proxy server.

View File

@ -1,4 +1,4 @@
/* $NetBSD: ftp.c,v 1.24 1997/03/16 14:24:19 lukem Exp $ */
/* $NetBSD: ftp.c,v 1.25 1997/04/14 09:09:22 lukem Exp $ */
/*
* Copyright (c) 1985, 1989, 1993, 1994
@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)ftp.c 8.6 (Berkeley) 10/27/94";
#else
static char rcsid[] = "$NetBSD: ftp.c,v 1.24 1997/03/16 14:24:19 lukem Exp $";
static char rcsid[] = "$NetBSD: ftp.c,v 1.25 1997/04/14 09:09:22 lukem Exp $";
#endif
#endif /* not lint */
@ -56,7 +56,6 @@ static char rcsid[] = "$NetBSD: ftp.c,v 1.24 1997/03/16 14:24:19 lukem Exp $";
#include <err.h>
#include <errno.h>
#include <netdb.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -191,102 +190,6 @@ bad:
return ((char *)0);
}
int
login(host)
const char *host;
{
char tmp[80];
char *user, *pass, *acct;
char anonpass[MAXLOGNAME + 1 + MAXHOSTNAMELEN]; /* "user@hostname" */
char hostname[MAXHOSTNAMELEN];
int n, aflag = 0;
user = pass = acct = NULL;
if (ruserpass(host, &user, &pass, &acct) < 0) {
code = -1;
return (0);
}
/*
* Set up arguments for an anonymous FTP session, if necessary.
*/
if ((user == NULL || pass == NULL) && anonftp) {
memset(anonpass, 0, sizeof(anonpass));
memset(hostname, 0, sizeof(hostname));
/*
* Set up anonymous login password.
*/
user = getlogin();
gethostname(hostname, MAXHOSTNAMELEN);
#ifndef DONT_CHEAT_ANONPASS
/*
* Every anonymous FTP server I've encountered
* will accept the string "username@", and will
* append the hostname itself. We do this by default
* since many servers are picky about not having
* a FQDN in the anonymous password. - thorpej@netbsd.org
*/
snprintf(anonpass, sizeof(anonpass) - 1, "%s@",
user);
#else
snprintf(anonpass, sizeof(anonpass) - 1, "%s@%s",
user, hp->h_name);
#endif
pass = anonpass;
user = "anonymous";
}
while (user == NULL) {
char *myname = getlogin();
if (myname == NULL) {
struct passwd *pp = getpwuid(getuid());
if (pp != NULL)
myname = pp->pw_name;
}
if (myname)
printf("Name (%s:%s): ", host, myname);
else
printf("Name (%s): ", host);
(void)fgets(tmp, sizeof(tmp) - 1, stdin);
tmp[strlen(tmp) - 1] = '\0';
if (*tmp == '\0')
user = myname;
else
user = tmp;
}
n = command("USER %s", user);
if (n == CONTINUE) {
if (pass == NULL)
pass = getpass("Password:");
n = command("PASS %s", pass);
}
if (n == CONTINUE) {
aflag++;
acct = getpass("Account:");
n = command("ACCT %s", acct);
}
if (n != COMPLETE) {
warnx("Login failed.");
return (0);
}
if (!aflag && acct != NULL)
(void)command("ACCT %s", acct);
if (proxy)
return (1);
for (n = 0; n < macnum; ++n) {
if (!strcmp("init", macros[n].mac_name)) {
(void)strcpy(line, "$init");
makeargv();
domacro(margc, margv);
break;
}
}
return (1);
}
void
cmdabort(notused)
int notused;

View File

@ -1,4 +1,4 @@
/* $NetBSD: ftp_var.h,v 1.15 1997/03/14 01:39:38 christos Exp $ */
/* $NetBSD: ftp_var.h,v 1.16 1997/04/14 09:09:23 lukem Exp $ */
/*
* Copyright (c) 1985, 1989, 1993, 1994
@ -67,7 +67,7 @@ int hash; /* print # for each buffer transferred */
int mark; /* number of bytes between hashes */
int sendport; /* use PORT cmd for each data connection */
int verbose; /* print messages coming back from server */
int connected; /* connected to server */
int connected; /* 1 = connected to server, -1 = logged in */
int fromatty; /* input is from a terminal */
int interactive; /* interactively prompt on m* cmds */
int confirmrest; /* confirm rest of current m* cmd */

View File

@ -1,4 +1,4 @@
/* $NetBSD: util.c,v 1.6 1997/04/05 03:27:39 lukem Exp $ */
/* $NetBSD: util.c,v 1.7 1997/04/14 09:09:24 lukem Exp $ */
/*
* Copyright (c) 1985, 1989, 1993, 1994
@ -34,7 +34,7 @@
*/
#ifndef lint
static char rcsid[] = "$NetBSD: util.c,v 1.6 1997/04/05 03:27:39 lukem Exp $";
static char rcsid[] = "$NetBSD: util.c,v 1.7 1997/04/14 09:09:24 lukem Exp $";
#endif /* not lint */
/*
@ -48,6 +48,7 @@ static char rcsid[] = "$NetBSD: util.c,v 1.6 1997/04/05 03:27:39 lukem Exp $";
#include <err.h>
#include <fcntl.h>
#include <glob.h>
#include <pwd.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
@ -107,7 +108,7 @@ setpeer(argc, argv)
(void)strcpy(structname, "file"), stru = STRU_F;
(void)strcpy(bytename, "8"), bytesize = 8;
if (autologin)
(void)login(argv[1]);
(void)login(argv[1], NULL, NULL);
overbose = verbose;
if (debug == 0)
@ -159,6 +160,110 @@ setpeer(argc, argv)
}
}
/*
* login to remote host, using given username & password if supplied
*/
int
login(host, user, pass)
const char *host;
char *user, *pass;
{
char tmp[80];
char *acct;
char anonpass[MAXLOGNAME + 1 + MAXHOSTNAMELEN]; /* "user@hostname" */
char hostname[MAXHOSTNAMELEN];
int n, aflag = 0;
acct = NULL;
if (user == NULL) {
if (ruserpass(host, &user, &pass, &acct) < 0) {
code = -1;
return (0);
}
}
/*
* Set up arguments for an anonymous FTP session, if necessary.
*/
if ((user == NULL || pass == NULL) && anonftp) {
memset(anonpass, 0, sizeof(anonpass));
memset(hostname, 0, sizeof(hostname));
/*
* Set up anonymous login password.
*/
user = getlogin();
gethostname(hostname, MAXHOSTNAMELEN);
#ifndef DONT_CHEAT_ANONPASS
/*
* Every anonymous FTP server I've encountered
* will accept the string "username@", and will
* append the hostname itself. We do this by default
* since many servers are picky about not having
* a FQDN in the anonymous password. - thorpej@netbsd.org
*/
snprintf(anonpass, sizeof(anonpass) - 1, "%s@",
user);
#else
snprintf(anonpass, sizeof(anonpass) - 1, "%s@%s",
user, hp->h_name);
#endif
pass = anonpass;
user = "anonymous";
}
while (user == NULL) {
char *myname = getlogin();
if (myname == NULL) {
struct passwd *pp = getpwuid(getuid());
if (pp != NULL)
myname = pp->pw_name;
}
if (myname)
printf("Name (%s:%s): ", host, myname);
else
printf("Name (%s): ", host);
(void)fgets(tmp, sizeof(tmp) - 1, stdin);
tmp[strlen(tmp) - 1] = '\0';
if (*tmp == '\0')
user = myname;
else
user = tmp;
}
n = command("USER %s", user);
if (n == CONTINUE) {
if (pass == NULL)
pass = getpass("Password:");
n = command("PASS %s", pass);
}
if (n == CONTINUE) {
aflag++;
if (acct == NULL)
acct = getpass("Account:");
n = command("ACCT %s", acct);
}
if ((n != COMPLETE) ||
(!aflag && acct != NULL && command("ACCT %s", acct) != COMPLETE)) {
warnx("Login failed.");
return (0);
}
if (proxy)
return (1);
connected = -1;
for (n = 0; n < macnum; ++n) {
if (!strcmp("init", macros[n].mac_name)) {
(void)strcpy(line, "$init");
makeargv();
domacro(margc, margv);
break;
}
}
return (1);
}
/*
* `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.