features:

* support $no_proxy, which is a comma or space separated list of
  host[:port] elements for which proxying is to be disabled.
  (asked for by cgd in [bin/5027])
* if $FTPANONPASS is defined, use that as the anon ftp password
  (instead of "`whoami`@")
* allow http URL's without a filename as long as an output file
  is specified.

other stuff:
* implement parse_url(), which breaks up a URL into its bits, and use.
* simplify url_get() and auto_fetch() to use parse_url() and to not
  modify the supplied URL or a copy of it.
* implement xmalloc() and xstrdup(); error-checked malloc()/strdup()
* add more consistency to messages, quoting strings in output as `%s'
This commit is contained in:
lukem 1998-08-03 01:49:25 +00:00
parent ac2b25e392
commit 4a8ec5494d
9 changed files with 378 additions and 267 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: cmds.c,v 1.40 1998/07/26 12:58:16 lukem Exp $ */
/* $NetBSD: cmds.c,v 1.41 1998/08/03 01:49:25 lukem Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -75,7 +75,7 @@
#if 0
static char sccsid[] = "@(#)cmds.c 8.6 (Berkeley) 10/9/94";
#else
__RCSID("$NetBSD: cmds.c,v 1.40 1998/07/26 12:58:16 lukem Exp $");
__RCSID("$NetBSD: cmds.c,v 1.41 1998/08/03 01:49:25 lukem Exp $");
#endif
#endif /* not lint */
@ -2272,8 +2272,7 @@ page(argc, argv)
p = getenv("PAGER");
if (p == NULL)
p = PAGER;
if ((pager = malloc(strlen(p) + 2)) == NULL)
errx(1, "Can't allocate memory for $PAGER");
pager = xmalloc(strlen(p) + 2);
(void)sprintf(pager, "|%s", p);
ohash = hash;

View File

@ -1,4 +1,4 @@
/* $NetBSD: complete.c,v 1.14 1998/06/04 08:28:35 lukem Exp $ */
/* $NetBSD: complete.c,v 1.15 1998/08/03 01:49:25 lukem Exp $ */
/*-
* Copyright (c) 1997 The NetBSD Foundation, Inc.
@ -40,7 +40,7 @@
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: complete.c,v 1.14 1998/06/04 08:28:35 lukem Exp $");
__RCSID("$NetBSD: complete.c,v 1.15 1998/08/03 01:49:25 lukem Exp $");
#endif /* not lint */
/*
@ -216,9 +216,7 @@ complete_local(word, list)
if (strncmp(file, dp->d_name, len) == 0) {
char *tcp;
tcp = strdup(dp->d_name);
if (tcp == NULL)
errx(1, "Can't allocate memory for local dir");
tcp = xstrdup(dp->d_name);
sl_add(words, tcp);
}
}
@ -297,9 +295,7 @@ complete_remote(word, list)
tcp++;
else
tcp = cp;
tcp = strdup(tcp);
if (tcp == NULL)
errx(1, "Can't allocate memory for remote dir");
tcp = xstrdup(tcp);
sl_add(dirlist, tcp);
}
if (emesg != NULL) {

View File

@ -1,4 +1,4 @@
/* $NetBSD: extern.h,v 1.23 1998/07/26 21:47:47 mycroft Exp $ */
/* $NetBSD: extern.h,v 1.24 1998/08/03 01:49:25 lukem Exp $ */
/*-
* Copyright (c) 1994 The Regents of the University of California.
@ -170,6 +170,8 @@ void usage __P((void));
void user __P((int, char **));
int xconnect __P((int, const struct sockaddr *, int));
int xlisten __P((int, int));
void *xmalloc __P((size_t));
char *xstrdup __P((const char *));
extern struct cmd cmdtab[];
extern FILE *cout;

View File

@ -1,4 +1,4 @@
/* $NetBSD: fetch.c,v 1.26 1998/07/26 12:59:40 lukem Exp $ */
/* $NetBSD: fetch.c,v 1.27 1998/08/03 01:49:25 lukem Exp $ */
/*-
* Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
@ -38,7 +38,7 @@
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: fetch.c,v 1.26 1998/07/26 12:59:40 lukem Exp $");
__RCSID("$NetBSD: fetch.c,v 1.27 1998/08/03 01:49:25 lukem Exp $");
#endif /* not lint */
/*
@ -68,6 +68,15 @@ __RCSID("$NetBSD: fetch.c,v 1.26 1998/07/26 12:59:40 lukem Exp $");
#include "ftp_var.h"
typedef enum {
UNKNOWN_URL_T=-1,
HTTP_URL_T,
FTP_URL_T,
FILE_URL_T
} url_t;
static int parse_url __P((const char *, const char *, url_t *, char **,
char **, char **, in_port_t *, char **));
static int url_get __P((const char *, const char *, const char *));
void aborthttp __P((int));
@ -78,9 +87,112 @@ void aborthttp __P((int));
#define HTTP_URL "http://" /* http URL prefix */
#define FTP_PROXY "ftp_proxy" /* env var with ftp proxy location */
#define HTTP_PROXY "http_proxy" /* env var with http proxy location */
#define NO_PROXY "no_proxy" /* env var with list of non-proxied
* hosts, comma or space separated */
#define EMPTYSTRING(x) ((x) == NULL || (*(x) == '\0'))
#define FREEPTR(x) if ((x) != NULL) { free(x); (x) = NULL; }
/*
* Parse URL of form:
* <type>://[<user>[:<password>@]]<host>[:<port>]/<url-path>
* Returns -1 if a parse error occurred, otherwise 0.
* Sets type to url_t, each of the given char ** pointers to a
* malloc(3)ed strings of the relevant section, and port to
* 0 if not given, or the number given.
*/
static int
parse_url(url, desc, type, user, pass, host, port, path)
const char *url;
const char *desc;
url_t *type;
char **user;
char **pass;
char **host;
in_port_t *port;
char **path;
{
char *cp, *ep, *thost;
if (url == NULL || desc == NULL || type == NULL || user == NULL
|| pass == NULL || host == NULL || port == NULL || path == NULL)
errx(1, "parse_url: invoked with NULL argument!");
*type = UNKNOWN_URL_T;
*user = *pass = *host = *path = NULL;
*port = 0;
if (strncasecmp(url, HTTP_URL, sizeof(HTTP_URL) - 1) == 0) {
url += sizeof(HTTP_URL) - 1;
*type = HTTP_URL_T;
} else if (strncasecmp(url, FTP_URL, sizeof(FTP_URL) - 1) == 0) {
url += sizeof(FTP_URL) - 1;
*type = FTP_URL_T;
} else if (strncasecmp(url, FILE_URL, sizeof(FILE_URL) - 1) == 0) {
url += sizeof(FILE_URL) - 1;
*type = FILE_URL_T;
} else {
warnx("Invalid %s `%s'", desc, url);
cleanup_parse_url:
FREEPTR(*user);
FREEPTR(*pass);
FREEPTR(*host);
FREEPTR(*path);
return (-1);
}
if (*url == '\0')
return (0);
/* find [user[:pass]@]host[:port] */
ep = strchr(url, '/');
if (ep == NULL)
thost = xstrdup(url);
else {
size_t len = ep - url;
thost = (char *)xmalloc(len + 1);
strncpy(thost, url, len);
thost[len] = '\0';
*path = xstrdup(ep);
}
cp = strchr(thost, '@');
if (cp != NULL) {
*user = thost;
*cp = '\0';
*host = xstrdup(cp + 1);
cp = strchr(*user, ':');
if (cp != NULL) {
*cp = '\0';
*pass = xstrdup(cp + 1);
}
} else
*host = thost;
/* look for [:port] */
cp = strrchr(*host, ':');
if (cp != NULL) {
long nport;
*cp = '\0';
nport = strtol(cp + 1, &ep, 10);
if (nport < 1 || nport > MAX_IN_PORT_T || *ep != '\0') {
warnx("Invalid port `%s' in %s `%s'", cp, desc, line);
goto cleanup_parse_url;
}
*port = htons((in_port_t)nport);
}
if (debug)
fprintf(ttyout,
"parse_url: user `%s', pass `%s', host %s:%d, path `%s'\n",
*user ? *user : "", *pass ? *pass : "", *host ? *host : "",
ntohs(*port), *path ? *path : "");
return (0);
}
jmp_buf httpabort;
@ -90,85 +202,65 @@ jmp_buf httpabort;
* Returns -1 on failure, 0 on success
*/
static int
url_get(origline, proxyenv, outfile)
const char *origline;
url_get(url, proxyenv, outfile)
const char *url;
const char *proxyenv;
const char *outfile;
{
struct sockaddr_in sin;
int isredirected;
in_port_t port;
int isredirected, isproxy;
volatile int s;
size_t len;
char *cp, *ep, *portnum, *path;
char *cp, *ep;
const char *savefile;
char *line, *proxy, *host, *buf;
char *buf;
volatile sig_t oldintr, oldintp;
off_t hashbytes;
struct hostent *hp = NULL;
int (*closefunc) __P((FILE *));
FILE *fin, *fout;
int retval;
enum { HTTP_URL_T=0, FTP_URL_T, FILE_URL_T } urltype;
time_t mtime;
url_t urltype;
char *user, *pass, *host;
in_port_t port;
char *path;
closefunc = NULL;
fin = fout = NULL;
s = -1;
proxy = buf = NULL;
isredirected = 0;
buf = NULL;
isredirected = isproxy = 0;
retval = -1;
#ifdef __GNUC__ /* to shut up gcc warnings */
#ifdef __GNUC__ /* shut up gcc warnings */
(void)&closefunc;
(void)&fin;
(void)&fout;
(void)&buf;
(void)&proxy;
(void)&savefile;
(void)&retval;
#endif
line = strdup(origline);
if (line == NULL)
errx(1, "Can't allocate memory to parse URL");
if (strncasecmp(line, HTTP_URL, sizeof(HTTP_URL) - 1) == 0) {
host = line + sizeof(HTTP_URL) - 1;
urltype = HTTP_URL_T;
} else if (strncasecmp(line, FTP_URL, sizeof(FTP_URL) - 1) == 0) {
host = line + sizeof(FTP_URL) - 1;
urltype = FTP_URL_T;
} else if (strncasecmp(line, FILE_URL, sizeof(FILE_URL) - 1) == 0) {
host = line + sizeof(FILE_URL) - 1;
urltype = FILE_URL_T;
} else
errx(1, "url_get: Invalid URL '%s'", line);
if (parse_url(url, "URL", &urltype, &user, &pass, &host, &port, &path)
== -1)
goto cleanup_url_get;
if (port == 0)
port = httpport;
path = strchr(host, '/'); /* find path */
if (EMPTYSTRING(path)) {
switch (urltype) {
case FILE_URL_T:
break;
case FTP_URL_T:
goto noftpautologin;
case HTTP_URL_T:
warnx("Invalid URL (no `/' after host): %s", origline);
goto cleanup_url_get;
default:
errx(1, "Unknown URL type %d\n", urltype);
}
}
*path++ = '\0';
if (urltype == FILE_URL_T &&
*host != '\0' && strcmp(host, "localhost") != 0) {
warnx("No support for non local file URL: %s", origline);
if (urltype == FILE_URL_T && ! EMPTYSTRING(host)
&& strcasecmp(host, "localhost") != 0) {
warnx("No support for non local file URL `%s'", url);
goto cleanup_url_get;
}
if (EMPTYSTRING(path)) {
if (urltype == FTP_URL_T)
goto noftpautologin;
warnx("Invalid URL (no file after host): %s", origline);
goto cleanup_url_get;
if (urltype != HTTP_URL_T || outfile == NULL) {
warnx("Invalid URL (no file after host) `%s'", url);
goto cleanup_url_get;
}
}
if (outfile)
@ -183,7 +275,7 @@ url_get(origline, proxyenv, outfile)
if (EMPTYSTRING(savefile)) {
if (urltype == FTP_URL_T)
goto noftpautologin;
warnx("Invalid URL (no file after directory): %s", origline);
warnx("Invalid URL (no file after directory) `%s'", url);
goto cleanup_url_get;
}
@ -193,10 +285,9 @@ url_get(origline, proxyenv, outfile)
struct stat sb;
direction = "copied";
*--path = '/'; /* put / back in */
fin = fopen(path, "r");
if (fin == NULL) {
warn("Cannot open file %s", path);
warn("Cannot open file `%s'", path);
goto cleanup_url_get;
}
if (fstat(fileno(fin), &sb) == 0) {
@ -207,46 +298,88 @@ url_get(origline, proxyenv, outfile)
} else { /* ftp:// or http:// URLs */
direction = "retrieved";
if (proxyenv != NULL) { /* use proxy */
proxy = strdup(proxyenv);
if (proxy == NULL)
errx(1, "Can't allocate memory for proxy URL.");
if (strncasecmp(proxy, HTTP_URL,
sizeof(HTTP_URL) - 1) == 0)
host = proxy + sizeof(HTTP_URL) - 1;
else if (strncasecmp(proxy, FTP_URL,
sizeof(FTP_URL) - 1) == 0)
host = proxy + sizeof(FTP_URL) - 1;
else {
warnx("Malformed proxy URL: %s", proxyenv);
goto cleanup_url_get;
}
if (EMPTYSTRING(host)) {
warnx("Malformed proxy URL: %s", proxyenv);
goto cleanup_url_get;
}
*--path = '/'; /* add / back to real path */
path = strchr(host, '/');
/* remove trailing / on host */
if (! EMPTYSTRING(path))
*path++ = '\0';
path = line;
}
url_t purltype;
char *puser, *ppass, *phost;
in_port_t pport;
char *ppath;
char *no_proxy;
portnum = strchr(host, ':'); /* find portnum */
if (portnum != NULL)
*portnum++ = '\0';
isproxy = 1;
if (debug)
fprintf(ttyout,
"host %s, port %s, path %s, save as %s.\n",
host, portnum, path, savefile);
/* check URL against list of no_proxied sites */
no_proxy = getenv(NO_PROXY);
if (no_proxy != NULL) {
char *np, *np_copy;
long np_port;
size_t hlen, plen;
np_copy = xstrdup(no_proxy);
hlen = strlen(host);
while ((cp = strsep(&np_copy, " ,")) != NULL) {
if (*cp == '\0')
continue;
if ((np = strchr(cp, ':')) != NULL) {
*np = '\0';
np_port =
strtol(np + 1, &ep, 10);
if (*ep != '\0')
continue;
if (port !=
htons((in_port_t)np_port))
continue;
}
plen = strlen(cp);
if (strncasecmp(host + hlen - plen,
cp, plen) == 0) {
isproxy = 0;
break;
}
}
FREEPTR(np_copy);
}
if (isproxy) {
if (parse_url(proxyenv, "proxy URL", &purltype,
&puser, &ppass, &phost, &pport, &ppath)
== -1)
goto cleanup_url_get;
if ((purltype != HTTP_URL_T
&& purltype != FTP_URL_T) ||
EMPTYSTRING(phost) ||
(! EMPTYSTRING(ppath)
&& strcmp(ppath, "/") != 0)) {
warnx("Malformed proxy URL `%s'",
proxyenv);
FREEPTR(puser);
FREEPTR(ppass);
FREEPTR(phost);
FREEPTR(ppath);
goto cleanup_url_get;
}
FREEPTR(user);
user = puser;
FREEPTR(pass);
pass = ppass;
FREEPTR(host);
host = phost;
if (pport == 0)
port = httpport;
else
port = pport;
FREEPTR(path);
FREEPTR(ppath);
path = xstrdup(url);
}
} /* proxyenv != NULL */
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
if (isdigit((unsigned char)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 {
@ -256,23 +389,13 @@ url_get(origline, proxyenv, outfile)
goto cleanup_url_get;
}
if (hp->h_addrtype != AF_INET) {
warnx("%s: not an Internet address?", host);
warnx("`%s': not an Internet address?", host);
goto cleanup_url_get;
}
memcpy(&sin.sin_addr, hp->h_addr, hp->h_length);
}
if (! EMPTYSTRING(portnum)) {
char *ep;
long nport;
nport = strtol(portnum, &ep, 10);
if (nport < 1 || nport > MAX_IN_PORT_T || *ep != '\0') {
warnx("Invalid port: %s", portnum);
goto cleanup_url_get;
}
port = htons((in_port_t)nport);
} else
if (port == 0)
port = httpport;
sin.sin_port = port;
@ -292,7 +415,7 @@ url_get(origline, proxyenv, outfile)
ia = inet_ntoa(sin.sin_addr);
errno = oerrno;
warn("connect to address %s", ia);
warn("Connect to address `%s'", ia);
hp->h_addr_list++;
memcpy(&sin.sin_addr, hp->h_addr_list[0],
(size_t)hp->h_length);
@ -306,24 +429,24 @@ url_get(origline, proxyenv, outfile)
}
continue;
}
warn("Can't connect to %s", host);
warn("Can't connect to `%s'", host);
goto cleanup_url_get;
}
fin = fdopen(s, "r+");
/*
* Construct and send the request. Proxy requests don't want
* leading /.
* Construct and send the request.
* Proxy requests don't want leading /.
*/
if (!proxy) {
fprintf(ttyout, "Requesting %s\n", origline);
fprintf(fin, "GET /%s HTTP/1.1\r\n", path);
if (isproxy) {
fprintf(ttyout, "Requesting %s\n (via %s)\n",
url, proxyenv);
fprintf(fin, "GET %s HTTP/1.0\r\n\r\n", path);
} else {
fprintf(ttyout, "Requesting %s\n", url);
fprintf(fin, "GET %s HTTP/1.1\r\n", path);
fprintf(fin, "Host: %s\r\n", host);
fprintf(fin, "Connection: close\r\n\r\n");
} else {
fprintf(ttyout, "Requesting %s\n (via %s)\n",
origline, proxyenv);
fprintf(fin, "GET %s HTTP/1.0\r\n\r\n", path);
}
if (fflush(fin) == EOF) {
warn("Writing HTTP request");
@ -338,7 +461,7 @@ url_get(origline, proxyenv, outfile)
while (len > 0 && (buf[len-1] == '\r' || buf[len-1] == '\n'))
buf[--len] = '\0';
if (debug)
fprintf(ttyout, "received '%s'\n", buf);
fprintf(ttyout, "received `%s'\n", buf);
cp = strchr(buf, ' ');
if (cp == NULL)
@ -348,12 +471,12 @@ url_get(origline, proxyenv, outfile)
if (strncmp(cp, "301", 3) == 0 || strncmp(cp, "302", 3) == 0) {
isredirected++;
} else if (strncmp(cp, "200", 3)) {
warnx("Error retrieving file: %s", cp);
warnx("Error retrieving file `%s'", cp);
goto cleanup_url_get;
}
/* Read the rest of the header. */
free(buf);
FREEPTR(buf);
while (1) {
if ((buf = fparseln(fin, &len, NULL, "\0\0\0", 0))
== NULL) {
@ -366,7 +489,7 @@ url_get(origline, proxyenv, outfile)
if (len == 0)
break;
if (debug)
fprintf(ttyout, "received '%s'\n", buf);
fprintf(ttyout, "received `%s'\n", buf);
/* Look for some headers */
cp = buf;
@ -423,23 +546,11 @@ url_get(origline, proxyenv, outfile)
if (verbose)
fprintf(ttyout,
"Redirected to %s\n", cp);
resetsockbufsize();
if (fin != NULL)
fclose(fin);
else if (s != -1)
close(s);
if (closefunc != NULL && fout != NULL)
(*closefunc)(fout);
if (proxy)
free(proxy);
free(line);
retval = url_get(cp, proxyenv, outfile);
if (buf)
free(buf);
return retval;
goto cleanup_url_get;
}
}
free(buf);
FREEPTR(buf);
}
oldintr = oldintp = NULL;
@ -451,14 +562,14 @@ url_get(origline, proxyenv, outfile)
oldintp = signal(SIGPIPE, SIG_IGN);
fout = popen(savefile + 1, "w");
if (fout == NULL) {
warn("Can't run %s", savefile + 1);
warn("Can't run `%s'", savefile + 1);
goto cleanup_url_get;
}
closefunc = pclose;
} else {
fout = fopen(savefile, "w");
if (fout == NULL) {
warn("Can't open %s", savefile);
warn("Can't open `%s'", savefile);
goto cleanup_url_get;
}
closefunc = fclose;
@ -479,12 +590,11 @@ url_get(origline, proxyenv, outfile)
progressmeter(-1);
/* Finally, suck down the file. */
if ((buf = malloc(BUFSIZ)) == NULL)
errx(1, "Can't allocate memory for transfer buffer\n");
buf = xmalloc(BUFSIZ);
while ((len = fread(buf, sizeof(char), BUFSIZ, fin)) > 0) {
bytes += len;
if (fwrite(buf, sizeof(char), len, fout) != len) {
warn("Writing %s", savefile);
warn("Writing `%s'", savefile);
goto cleanup_url_get;
}
if (hash && !progress) {
@ -534,7 +644,7 @@ noftpautologin:
goto cleanup_url_get;
improper:
warnx("Improper response from %s", host);
warnx("Improper response from `%s'", host);
cleanup_url_get:
resetsockbufsize();
@ -544,11 +654,11 @@ cleanup_url_get:
close(s);
if (closefunc != NULL && fout != NULL)
(*closefunc)(fout);
if (buf)
free(buf);
if (proxy)
free(proxy);
free(line);
FREEPTR(user);
FREEPTR(pass);
FREEPTR(host);
FREEPTR(path);
FREEPTR(buf);
return (retval);
}
@ -588,9 +698,12 @@ auto_fetch(argc, argv, outfile)
char *outfile;
{
static char lasthost[MAXHOSTNAMELEN];
char portnum[6]; /* large enough for "65535\0" */
char *xargv[5];
char *cp, *line, *host, *dir, *file, *portnum;
const char *line;
char *cp, *host, *path, *dir, *file;
char *user, *pass;
in_port_t port;
char *ftpproxy, *httpproxy;
int rval, xargc;
volatile int argpos;
@ -613,39 +726,34 @@ auto_fetch(argc, argv, outfile)
ftpproxy = getenv(FTP_PROXY);
httpproxy = getenv(HTTP_PROXY);
host = path = dir = file = user = pass = NULL;
/*
* Loop through as long as there's files to fetch.
*/
for (rval = 0; (rval == 0) && (argpos < argc); free(line), argpos++) {
for (rval = 0; (rval == 0) && (argpos < argc); argpos++) {
if (strchr(argv[argpos], ':') == NULL)
break;
host = dir = file = portnum = user = pass = NULL;
/*
* We muck with the string, so we make a copy.
*/
line = strdup(argv[argpos]);
if (line == NULL)
errx(1, "Can't allocate memory for auto-fetch.");
host = path = dir = file = user = pass = NULL;
line = argv[argpos];
#ifndef SMALL
/*
* Check for about:*
*/
if (strncasecmp(line, ABOUT_URL, sizeof(ABOUT_URL) - 1) == 0) {
cp = line + sizeof(ABOUT_URL) -1;
if (strcasecmp(cp, "ftp") == 0) {
line += sizeof(ABOUT_URL) -1;
if (strcasecmp(line, "ftp") == 0) {
fprintf(ttyout, "%s\n%s\n",
"This version of ftp has been enhanced by Luke Mewburn <lukem@netbsd.org>.",
"Execute 'man ftp' for more details");
} else if (strcasecmp(cp, "netbsd") == 0) {
} else if (strcasecmp(line, "netbsd") == 0) {
fprintf(ttyout, "%s\n%s\n",
"NetBSD is a freely available and redistributable UNIX-like operating system.",
"For more information, see http://www.netbsd.org/index.html");
} else {
fprintf(ttyout,
"'%s' is an interesting topic.\n", cp);
"`%s' is an interesting topic.\n", line);
}
continue;
}
@ -666,58 +774,41 @@ auto_fetch(argc, argv, outfile)
* set, use url_get() instead of standard ftp.
* Finally, try host:file.
*/
host = line;
if (strncasecmp(line, FTP_URL, sizeof(FTP_URL) - 1) == 0) {
int urltype;
if (ftpproxy) {
if (url_get(line, ftpproxy, outfile) == -1)
rval = argpos + 1;
continue;
}
host += sizeof(FTP_URL) - 1;
dir = strchr(host, '/');
/* look for [user:pass@]host[:port] */
pass = strpbrk(host, ":@/");
if (pass == NULL || *pass == '/') {
pass = NULL;
goto parsed_url;
}
if (pass == host || *pass == '@') {
bad_url:
warnx("Invalid URL: %s", argv[argpos]);
if ((parse_url(line, "URL", &urltype, &user, &pass,
&host, &port, &path) == -1) ||
(user != NULL && *user == '\0') ||
(pass != NULL && *pass == '\0') ||
EMPTYSTRING(host)) {
warnx("Invalid URL `%s'", argv[argpos]);
rval = argpos + 1;
continue;
break;
}
*pass++ = '\0';
cp = strpbrk(pass, ":@/");
if (cp == NULL || *cp == '/') {
portnum = pass;
pass = NULL;
goto parsed_url;
}
if (EMPTYSTRING(cp) || *cp == ':')
goto bad_url;
*cp++ = '\0';
user = host;
if (EMPTYSTRING(user))
goto bad_url;
host = cp;
portnum = strchr(host, ':');
if (portnum != NULL)
*portnum++ = '\0';
} else { /* classic style `host:file' */
dir = strchr(host, ':');
host = xstrdup(line);
cp = strchr(host, ':');
if (cp != NULL) {
*cp = '\0';
path = xstrdup(cp + 1);
}
}
parsed_url:
if (EMPTYSTRING(host)) {
rval = argpos + 1;
continue;
break;
}
/*
* If dir is NULL, the file wasn't specified
* (URL looked something like ftp://host)
*/
dir = path;
if (dir != NULL)
*dir++ = '\0';
@ -736,13 +827,15 @@ parsed_url:
}
if (debug)
fprintf(ttyout,
"user %s:%s host %s port %s dir %s file %s\n",
user, pass, host, portnum, dir, file);
"auto_fetch: user `%s', pass `%s', host %s:%d, path, `%s', dir `%s', file `%s'\n",
user ? user : "", pass ? pass : "",
host ? host : "", ntohs(port), path ? path : "",
dir ? dir : "", file ? file : "");
/*
* Set up the connection if we don't have one.
*/
if (strcmp(host, lasthost) != 0) {
if (strcasecmp(host, lasthost) != 0) {
int oautologin;
(void)strcpy(lasthost, host);
@ -752,7 +845,9 @@ parsed_url:
xargv[1] = host;
xargv[2] = NULL;
xargc = 2;
if (! EMPTYSTRING(portnum)) {
if (port) {
snprintf(portnum, sizeof(portnum),
"%d", (int)port);
xargv[2] = portnum;
xargv[3] = NULL;
xargc = 3;
@ -768,20 +863,20 @@ parsed_url:
warnx("Can't connect or login to host `%s'",
host);
rval = argpos + 1;
continue;
break;
}
/* Always use binary transfers. */
setbinary(0, NULL);
}
/* cd back to '/' */
/* cd back to `/' */
xargv[0] = "cd";
xargv[1] = "/";
xargv[2] = NULL;
cd(2, xargv);
if (! dirchange) {
rval = argpos + 1;
continue;
break;
}
dirhasglob = filehasglob = 0;
@ -794,7 +889,7 @@ parsed_url:
filehasglob = 1;
}
/* Change directories, if necessary. */
/* Change directories, if necessary. */
if (! EMPTYSTRING(dir) && !dirhasglob) {
xargv[0] = "cd";
xargv[1] = dir;
@ -802,13 +897,13 @@ parsed_url:
cd(2, xargv);
if (! dirchange) {
rval = argpos + 1;
continue;
break;
}
}
if (EMPTYSTRING(file)) {
rval = -1;
continue;
break;
}
if (!verbose)
@ -820,7 +915,7 @@ parsed_url:
file = rempath;
}
/* Fetch the file(s). */
/* Fetch the file(s). */
xargc = 2;
xargv[0] = "get";
xargv[1] = file;
@ -850,5 +945,9 @@ parsed_url:
}
if (connected && rval != -1)
disconnect(0, NULL);
FREEPTR(host);
FREEPTR(path);
FREEPTR(user);
FREEPTR(pass);
return (rval);
}

View File

@ -1,7 +1,9 @@
.\" $NetBSD: ftp.1,v 1.27 1998/07/26 12:58:18 lukem Exp $
.\" $NetBSD: ftp.1,v 1.28 1998/08/03 01:49:25 lukem Exp $
.\"
.\" Copyright (c) 1985, 1989, 1990, 1993
.\" The Regents of the University of California. All rights reserved.
.\" Portions Copyright (c) 1997, 1998
.\" The NetBSD Foundation, Inc.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
@ -33,7 +35,7 @@
.\"
.\" @(#)ftp.1 8.3 (Berkeley) 10/9/94
.\"
.Dd July 26, 1998
.Dd August 2, 1998
.Dt FTP 1
.Os BSD 4.2
.Sh NAME
@ -1376,6 +1378,10 @@ By default, this is bound to the TAB key.
.Nm
uses the following environment variables.
.Bl -tag -width "FTPSERVERPORT"
.It Ev FTPANONPASS
Password to send in an anonymous ftp transfer.
Defaults to
.Dq `whoami`@`hostname` .
.It Ev FTPMODE
Overrides the default operation mode.
Support values are:
@ -1416,6 +1422,11 @@ URL of FTP proxy to use when making FTP URL requests
(if not defined, use the standard ftp protocol).
.It Ev http_proxy
URL of HTTP proxy to use when making HTTP URL requests.
.It Ev no_proxy
A space or comma separated list of hosts (or domains) for which
proxying is not to be used.
Each entry may have an optional trailing ":port", which restricts
the matching to connections to that port.
.El
.Sh SEE ALSO
.Xr getservbyname 3 ,

View File

@ -1,4 +1,4 @@
/* $NetBSD: ftp.c,v 1.36 1998/07/10 04:39:04 thorpej Exp $ */
/* $NetBSD: ftp.c,v 1.37 1998/08/03 01:49:25 lukem Exp $ */
/*
* Copyright (c) 1985, 1989, 1993, 1994
@ -38,7 +38,7 @@
#if 0
static char sccsid[] = "@(#)ftp.c 8.6 (Berkeley) 10/27/94";
#else
__RCSID("$NetBSD: ftp.c,v 1.36 1998/07/10 04:39:04 thorpej Exp $");
__RCSID("$NetBSD: ftp.c,v 1.37 1998/08/03 01:49:25 lukem Exp $");
#endif
#endif /* not lint */
@ -895,13 +895,8 @@ recvrequest(cmd, local, remote, lmode, printnames, ignorespecial)
if (st.st_blksize > bufsize) {
if (buf)
(void)free(buf);
buf = malloc((unsigned)st.st_blksize);
if (buf == NULL) {
warn("malloc");
bufsize = 0;
goto abort;
}
bufsize = st.st_blksize;
buf = xmalloc(bufsize);
}
if (!S_ISREG(st.st_mode)) {
progress = 0;

View File

@ -1,4 +1,4 @@
/* $NetBSD: main.c,v 1.31 1998/06/04 08:28:36 lukem Exp $ */
/* $NetBSD: main.c,v 1.32 1998/08/03 01:49:26 lukem Exp $ */
/*
* Copyright (c) 1985, 1989, 1993, 1994
@ -43,7 +43,7 @@ __COPYRIGHT("@(#) Copyright (c) 1985, 1989, 1993, 1994\n\
#if 0
static char sccsid[] = "@(#)main.c 8.6 (Berkeley) 10/9/94";
#else
__RCSID("$NetBSD: main.c,v 1.31 1998/06/04 08:28:36 lukem Exp $");
__RCSID("$NetBSD: main.c,v 1.32 1998/08/03 01:49:26 lukem Exp $");
#endif
#endif /* not lint */
@ -142,12 +142,10 @@ main(argc, argv)
warnx("unknown $FTPMODE '%s'; using defaults", cp);
}
cp = strrchr(argv[0], '/');
cp = (cp == NULL) ? argv[0] : cp + 1;
if (strcmp(cp, "pftp") == 0) {
if (strcmp(__progname, "pftp") == 0) {
passivemode = 1;
activefallback = 0;
} else if (strcmp(cp, "gate-ftp") == 0)
} else if (strcmp(__progname, "gate-ftp") == 0)
gatemode = 1;
gateserver = getenv("FTPSERVER");

View File

@ -1,4 +1,4 @@
/* $NetBSD: ruserpass.c,v 1.19 1998/07/26 21:47:47 mycroft Exp $ */
/* $NetBSD: ruserpass.c,v 1.20 1998/08/03 01:49:26 lukem Exp $ */
/*
* Copyright (c) 1985, 1993, 1994
@ -38,7 +38,7 @@
#if 0
static char sccsid[] = "@(#)ruserpass.c 8.4 (Berkeley) 4/27/95";
#else
__RCSID("$NetBSD: ruserpass.c,v 1.19 1998/07/26 21:47:47 mycroft Exp $");
__RCSID("$NetBSD: ruserpass.c,v 1.20 1998/08/03 01:49:26 lukem Exp $");
#endif
#endif /* not lint */
@ -149,11 +149,9 @@ next:
case LOGIN:
if (token()) {
if (*aname == NULL) {
*aname = strdup(tokval);
if (*aname == NULL)
err(1, "can't strdup *aname");
} else {
if (*aname == NULL)
*aname = xstrdup(tokval);
else {
if (strcmp(*aname, tokval))
goto next;
}
@ -167,11 +165,8 @@ next:
warnx("Remove password or make file unreadable by others.");
goto bad;
}
if (token() && *apass == NULL) {
*apass = strdup(tokval);
if (*apass == NULL)
err(1, "can't strdup *apass");
}
if (token() && *apass == NULL)
*apass = xstrdup(tokval);
break;
case ACCOUNT:
if (fstat(fileno(cfile), &stb) >= 0
@ -180,11 +175,8 @@ next:
warnx("Remove account or make file unreadable by others.");
goto bad;
}
if (token() && *aacct == NULL) {
*aacct = strdup(tokval);
if (*aacct == NULL)
err(1, "can't strdup *aacct");
}
if (token() && *aacct == NULL)
*aacct = xstrdup(tokval);
break;
case MACDEF:
if (proxy) {

View File

@ -1,4 +1,4 @@
/* $NetBSD: util.c,v 1.30 1998/07/29 02:46:26 lukem Exp $ */
/* $NetBSD: util.c,v 1.31 1998/08/03 01:49:26 lukem Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -72,7 +72,7 @@
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: util.c,v 1.30 1998/07/29 02:46:26 lukem Exp $");
__RCSID("$NetBSD: util.c,v 1.31 1998/08/03 01:49:26 lukem Exp $");
#endif /* not lint */
/*
@ -242,8 +242,7 @@ ftp_login(host, user, pass)
{
char tmp[80];
const char *acct;
char anonpass[MAXLOGNAME + 1 + MAXHOSTNAMELEN + 1]; /* user@hostname */
char hostname[MAXHOSTNAMELEN + 1];
char anonpass[MAXLOGNAME + 2]; /* "user@" */
struct passwd *pw;
int n, aflag = 0;
@ -260,34 +259,28 @@ ftp_login(host, user, pass)
*/
if ((user == NULL || pass == NULL) && anonftp) {
memset(anonpass, 0, sizeof(anonpass));
memset(hostname, 0, sizeof(hostname));
/*
* Set up anonymous login password.
*/
if ((user = getlogin()) == NULL) {
if ((pw = getpwuid(getuid())) == NULL)
user = "anonymous";
else
user = pw->pw_name;
if ((pass = getenv("FTPANONPASS")) == NULL) {
if ((pass = getlogin()) == NULL) {
if ((pw = getpwuid(getuid())) == NULL)
pass = "anonymous";
else
pass = pw->pw_name;
}
/*
* 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@", pass);
pass = anonpass;
}
gethostname(hostname, MAXHOSTNAMELEN);
hostname[sizeof(hostname) - 1] = '\0';
#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"; /* as per RFC 1635 */
}
@ -508,7 +501,7 @@ globulize(cpp)
/* XXX: caller should check if *cpp changed, and
* free(*cpp) if that is the case
*/
*cpp = strdup(gl.gl_pathv[0]);
*cpp = xstrdup(gl.gl_pathv[0]);
globfree(&gl);
return (1);
}
@ -1056,3 +1049,29 @@ xlisten(sock, backlog)
setupsockbufsize(sock);
return (listen(sock, backlog));
}
void *
xmalloc(size)
size_t size;
{
void *p;
p = malloc(size);
if (p == NULL)
err(1, "Unable to allocate %ld bytes of memory", (long)size);
return (p);
}
char *
xstrdup(str)
const char *str;
{
char *s;
if (str == NULL)
errx(1, "xstrdup() called with NULL argument");
s = strdup(str);
if (s == NULL)
err(1, "Unable to allocate memory for string copy");
return (s);
}