FTP wildcard depends code, initial commit.
Modulo some code cleanup, this gives NetBSD full wildcard support not only in pkgsrc, but esp. for binary packages installed from local disk and via FTP. For more information, see: http://www.feyrer.de/NetBSD/wildcards.html
This commit is contained in:
parent
e92c1387ea
commit
9d0c5bb4ee
|
@ -1,11 +1,11 @@
|
|||
/* $NetBSD: main.c,v 1.13 1999/11/10 18:51:47 abs Exp $ */
|
||||
/* $NetBSD: main.c,v 1.14 2000/01/19 23:28:28 hubertf Exp $ */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char *rcsid = "from FreeBSD Id: main.c,v 1.16 1997/10/08 07:45:43 charnier Exp";
|
||||
#else
|
||||
__RCSID("$NetBSD: main.c,v 1.13 1999/11/10 18:51:47 abs Exp $");
|
||||
__RCSID("$NetBSD: main.c,v 1.14 2000/01/19 23:28:28 hubertf Exp $");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -134,24 +134,54 @@ main(int argc, char **argv)
|
|||
warn("realpath failed for '%s'", *argv);
|
||||
} else
|
||||
lpp = alloc_lpkg(cp);
|
||||
} else if (ispkgpattern(*argv)
|
||||
&& (s = findbestmatchingname(dirname_of(*argv),
|
||||
} else if (ispkgpattern(*argv)) {
|
||||
if ((s = findbestmatchingname(dirname_of(*argv),
|
||||
basename_of(*argv))) != NULL) {
|
||||
char tmp[FILENAME_MAX];
|
||||
|
||||
snprintf(tmp, sizeof(tmp), "%s/%s", dirname_of(*argv), s);
|
||||
|
||||
if (Verbose)
|
||||
printf("Using %s for %s\n", tmp, *argv);
|
||||
|
||||
if (!(cp = realpath(tmp, pkgname))) {
|
||||
lpp = NULL;
|
||||
warn("realpath failed for '%s'", tmp);
|
||||
} else
|
||||
lpp = alloc_lpkg(cp);
|
||||
} else {
|
||||
lpp = NULL;
|
||||
warnx("can't find package pattern '%s'", *argv);
|
||||
}
|
||||
} else {
|
||||
/* Maybe just a pkg name w/o pattern was given */
|
||||
char tmp[FILENAME_MAX];
|
||||
|
||||
snprintf(tmp, sizeof(tmp), "%s-[0-9]*.tgz", *argv);
|
||||
s=findbestmatchingname(dirname_of(tmp),
|
||||
basename_of(tmp));
|
||||
if (s) {
|
||||
char tmp2[FILENAME_MAX];
|
||||
|
||||
snprintf(tmp2, sizeof(tmp2), "%s/%s", dirname_of(tmp), s);
|
||||
|
||||
if (Verbose)
|
||||
printf("Using %s for %s\n", s, *argv);
|
||||
printf("Using %s for %s\n", tmp2, *argv);
|
||||
|
||||
if (!(cp = realpath(s, pkgname))) {
|
||||
if (!(cp = realpath(tmp2, pkgname))) {
|
||||
lpp = NULL;
|
||||
warn("realpath failed for '%s'", s);
|
||||
warn("realpath failed for '%s'", tmp2);
|
||||
} else
|
||||
lpp = alloc_lpkg(cp);
|
||||
} else {
|
||||
/* No go there... */
|
||||
/* look for the file(pattern) in the expected places */
|
||||
if (!(cp = fileFindByPath(NULL, *argv))) {
|
||||
lpp = NULL;
|
||||
warnx("can't find package '%s'", *argv);
|
||||
} else
|
||||
lpp = alloc_lpkg(cp);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (lpp)
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
/* $NetBSD: perform.c,v 1.43 2000/01/09 17:21:53 hubertf Exp $ */
|
||||
/* $NetBSD: perform.c,v 1.44 2000/01/19 23:28:28 hubertf Exp $ */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static const char *rcsid = "from FreeBSD Id: perform.c,v 1.44 1997/10/13 15:03:46 jkh Exp";
|
||||
#else
|
||||
__RCSID("$NetBSD: perform.c,v 1.43 2000/01/09 17:21:53 hubertf Exp $");
|
||||
__RCSID("$NetBSD: perform.c,v 1.44 2000/01/19 23:28:28 hubertf Exp $");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -34,6 +34,7 @@ __RCSID("$NetBSD: perform.c,v 1.43 2000/01/09 17:21:53 hubertf Exp $");
|
|||
#include "add.h"
|
||||
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
static char LogDir[FILENAME_MAX];
|
||||
|
@ -124,19 +125,72 @@ pkg_do(char *pkg)
|
|||
* specification?
|
||||
*/
|
||||
if (IS_URL(pkg)) {
|
||||
char buf[FILENAME_MAX];
|
||||
char *tmppkg = pkg;
|
||||
|
||||
if (ispkgpattern(pkg)) {
|
||||
#if 0
|
||||
warnx("patterns not supported in URLs, "
|
||||
"please install manually!");
|
||||
"please install %s manually!", pkg);
|
||||
/* ... until we come up with a better solution :-/ - HF */
|
||||
|
||||
goto bomb;
|
||||
#else
|
||||
{
|
||||
/* Handle wildcard wildcard depends */
|
||||
|
||||
char *s;
|
||||
s=fileFindByPath(NULL, pkg);
|
||||
if (s == NULL) {
|
||||
warnx("no pkg found for '%s', sorry.", pkg);
|
||||
return 1;
|
||||
}
|
||||
strcpy(buf, s);
|
||||
tmppkg = buf;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!(Home = fileGetURL(NULL, pkg))) {
|
||||
warnx("unable to fetch `%s' by URL", pkg);
|
||||
if (!(Home = fileGetURL(NULL, tmppkg))) {
|
||||
warnx("unable to fetch `%s' by URL", tmppkg);
|
||||
if (ispkgpattern(pkg))
|
||||
return 1;
|
||||
|
||||
if (strstr(pkg, ".tgz") != NULL) {
|
||||
/* There already is a ".tgz" - give up
|
||||
* (We don't want to pretend to be exceedingly
|
||||
* clever - the user should give something sane!)
|
||||
*/
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* Second chance - maybe just a package name was given,
|
||||
* without even a wildcard as a version. Tack on
|
||||
* the same pattern as we do for local packages: "-[0-9]*",
|
||||
* plus a ".tgz" as we're talking binary pkgs here.
|
||||
* Then retry.
|
||||
*/
|
||||
{
|
||||
char *s;
|
||||
char buf2[FILENAME_MAX];
|
||||
|
||||
snprintf(buf2, sizeof(buf2), "%s-[0-9]*.tgz", tmppkg);
|
||||
s=fileFindByPath(NULL, buf2);
|
||||
if (s == NULL) {
|
||||
warnx("no pkg found for '%s' on 2nd try, sorry.", buf2);
|
||||
return 1;
|
||||
}
|
||||
strcpy(buf, s);
|
||||
tmppkg = buf;
|
||||
if (!(Home = fileGetURL(NULL, tmppkg))) {
|
||||
warnx("unable to fetch `%s' by URL", tmppkg);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
where_to = Home;
|
||||
strcpy(pkg_fullname, pkg);
|
||||
strcpy(pkg_fullname, tmppkg);
|
||||
cfile = fopen(CONTENTS_FNAME, "r");
|
||||
if (!cfile) {
|
||||
warnx("unable to open table of contents file `%s' - not a package?",
|
||||
|
@ -341,52 +395,82 @@ pkg_do(char *pkg)
|
|||
++code;
|
||||
}
|
||||
} else {
|
||||
warnx("add of dependency `%s' failed%s",
|
||||
p->name, Force ? " (proceeding anyway)" : "!");
|
||||
warnx("<%s> (1) add of dependency `%s' failed%s",
|
||||
pkg, p->name, Force ? " (proceeding anyway)" : "!");
|
||||
if (!Force)
|
||||
++code;
|
||||
} /* cp */
|
||||
} else {
|
||||
/* install depending pkg via FTP */
|
||||
/* pkg is url -> install depending pkg via FTP */
|
||||
|
||||
char *saved_Current; /* allocated/set by save_dirs(), */
|
||||
char *saved_Previous; /* freed by restore_dirs() */
|
||||
char *cp, *new_pkg, *new_name;
|
||||
|
||||
new_pkg = pkg;
|
||||
new_name = p->name;
|
||||
|
||||
if (ispkgpattern(p->name)) {
|
||||
#if 0
|
||||
warnx("can't install dependent pkg '%s' via FTP, "
|
||||
"please install manually!", p->name);
|
||||
/* ... until we come up with a better solution - HF */
|
||||
|
||||
goto bomb;
|
||||
} else {
|
||||
char *saved_Current; /* allocated/set by save_dirs(), */
|
||||
char *saved_Previous; /* freed by restore_dirs() */
|
||||
char *cp;
|
||||
#else
|
||||
{
|
||||
/* Might hack stuff for wildcard depends in here - HF */
|
||||
|
||||
char *s;
|
||||
s=fileFindByPath(pkg, p->name);
|
||||
printf("HF: pkg='%s'\n", pkg);
|
||||
printf("HF: s='%s'\n", s);
|
||||
|
||||
/* adjust new_pkg and new_name */
|
||||
new_pkg = NULL;
|
||||
new_name = s;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* makeplaypen() and leave_playpen() clobber Current and
|
||||
* Previous, save them! */
|
||||
save_dirs(&saved_Current, &saved_Previous);
|
||||
|
||||
if ((cp = fileGetURL(pkg, p->name)) != NULL) {
|
||||
if ((cp = fileGetURL(new_pkg, new_name)) != NULL) {
|
||||
if (Verbose)
|
||||
printf("Finished loading %s over FTP.\n", p->name);
|
||||
printf("Finished loading %s over FTP.\n", new_name);
|
||||
if (!fexists(CONTENTS_FNAME)) {
|
||||
warnx("autoloaded package %s has no %s file?",
|
||||
p->name, CONTENTS_FNAME);
|
||||
if (!Force)
|
||||
++code;
|
||||
} else if (vsystem("(pwd; cat %s) | pkg_add %s%s%s %s-S",
|
||||
} else {
|
||||
if (vsystem("(pwd; cat %s) | pkg_add %s%s%s %s-S",
|
||||
CONTENTS_FNAME,
|
||||
Force ? "-f " : "",
|
||||
Prefix ? "-p " : "",
|
||||
Prefix ? Prefix : "",
|
||||
Verbose ? "-v " : "")) {
|
||||
warnx("add of dependency `%s' failed%s",
|
||||
p->name, Force ? " (proceeding anyway)" : "!");
|
||||
warnx("<%s> (2) add of dependency `%s' failed%s",
|
||||
pkg, p->name, Force ? " (proceeding anyway)" : "!");
|
||||
if (!Force)
|
||||
++code;
|
||||
} else if (Verbose)
|
||||
printf("\t`%s' loaded successfully.\n", p->name);
|
||||
} else if (Verbose) {
|
||||
printf("\t`%s' loaded successfully as `%s'.\n", p->name, new_name);
|
||||
}
|
||||
}
|
||||
/* Nuke the temporary playpen */
|
||||
leave_playpen(cp);
|
||||
|
||||
restore_dirs(saved_Current, saved_Previous);
|
||||
}
|
||||
} else {
|
||||
if (Verbose)
|
||||
warnx("HF: fileGetURL('%s', '%s') failed", new_pkg, new_name);
|
||||
if (!Force)
|
||||
code++;
|
||||
}
|
||||
|
||||
restore_dirs(saved_Current, saved_Previous);
|
||||
}
|
||||
} else {
|
||||
/* fake install (???) */
|
||||
|
@ -628,5 +712,8 @@ pkg_perform(lpkg_head_t *pkgs)
|
|||
free_lpkg(lpp);
|
||||
}
|
||||
}
|
||||
|
||||
ftp_stop();
|
||||
|
||||
return err_cnt;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
.\" $NetBSD: pkg_add.1,v 1.18 2000/01/04 22:39:28 hubertf Exp $
|
||||
.\" $NetBSD: pkg_add.1,v 1.19 2000/01/19 23:28:28 hubertf Exp $
|
||||
.\"
|
||||
.\" FreeBSD install - a package for the installation and maintainance
|
||||
.\" of non-core utilities.
|
||||
|
@ -363,10 +363,10 @@ The value of the
|
|||
is used if a given package can't be found, it's usually set to
|
||||
.Pa /usr/pkgsrc/packages/All .
|
||||
The environment variable
|
||||
should be a series of entries seperated by colons. Each entry
|
||||
consists of a directory name. The current directory may be indicated
|
||||
should be a series of entries seperated by semicolons. Each entry
|
||||
consists of a directory name or URL. The current directory may be indicated
|
||||
implicitly by an empty directory name, or explicitly by a single
|
||||
period.
|
||||
period. FTP URLs may not end with a slash.
|
||||
.Ss PKG_DBDIR
|
||||
Where to register packages instead of
|
||||
.Pa /var/db/pkg .
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
.\" $NetBSD: pkg_create.1,v 1.21 1999/12/20 03:25:58 hubertf Exp $
|
||||
.\" $NetBSD: pkg_create.1,v 1.22 2000/01/19 23:28:30 hubertf Exp $
|
||||
.\"
|
||||
.\" FreeBSD install - a package for the installation and maintainance
|
||||
.\" of non-core utilities.
|
||||
|
@ -122,12 +122,12 @@ This is assumed to be a whitespace separated list of package names
|
|||
and is meant as a convenient shorthand for specifying multiple
|
||||
.Cm @pkgcfl
|
||||
directives in the packing list (see PACKING LIST DETAILS section below).
|
||||
.It Fl L Ar SrcDir
|
||||
This sets the package's @src directive; see below for a description
|
||||
of what this does.
|
||||
.It Fl D Ar displayfile
|
||||
Display the file after installing the package. Useful for things like
|
||||
legal notices on almost-free software, etc.
|
||||
.It Fl L Ar SrcDir
|
||||
This sets the package's @src directive; see below for a description
|
||||
of what this does.
|
||||
.It Fl O
|
||||
Go into a `packing list Only' mode.
|
||||
This is used to do `fake pkg_add' operations when a package is installed.
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
/* $NetBSD: perform.c,v 1.29 1999/12/01 14:51:52 hubertf Exp $ */
|
||||
/* $NetBSD: perform.c,v 1.30 2000/01/19 23:28:30 hubertf Exp $ */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static const char *rcsid = "from FreeBSD Id: perform.c,v 1.15 1997/10/13 15:03:52 jkh Exp";
|
||||
#else
|
||||
__RCSID("$NetBSD: perform.c,v 1.29 1999/12/01 14:51:52 hubertf Exp $");
|
||||
__RCSID("$NetBSD: perform.c,v 1.30 2000/01/19 23:28:30 hubertf Exp $");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -539,7 +539,7 @@ pkg_do(char *pkg)
|
|||
}
|
||||
|
||||
/* No match */
|
||||
warnx("no such package '%s' installed", pkg);
|
||||
warnx("package '%s' not installed", pkg);
|
||||
return 1;
|
||||
}
|
||||
if (!getcwd(home, FILENAME_MAX)) {
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
/* $NetBSD: perform.c,v 1.29 1999/11/29 19:48:46 hubertf Exp $ */
|
||||
/* $NetBSD: perform.c,v 1.30 2000/01/19 23:28:31 hubertf Exp $ */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static const char *rcsid = "from FreeBSD Id: perform.c,v 1.23 1997/10/13 15:03:53 jkh Exp";
|
||||
#else
|
||||
__RCSID("$NetBSD: perform.c,v 1.29 1999/11/29 19:48:46 hubertf Exp $");
|
||||
__RCSID("$NetBSD: perform.c,v 1.30 2000/01/19 23:28:31 hubertf Exp $");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -333,5 +333,6 @@ pkg_perform(lpkg_head_t *pkgs)
|
|||
free_lpkg(lpp);
|
||||
}
|
||||
}
|
||||
ftp_stop();
|
||||
return err_cnt;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
.\" $NetBSD: pkg_info.1,v 1.20 2000/01/17 00:48:52 hubertf Exp $
|
||||
.\" $NetBSD: pkg_info.1,v 1.21 2000/01/19 23:28:31 hubertf Exp $
|
||||
.\"
|
||||
.\" FreeBSD install - a package for the installation and maintainance
|
||||
.\" of non-core utilities.
|
||||
|
@ -142,8 +142,7 @@ Show the installation prefix for each package.
|
|||
Be ``quiet'' in emitting report headers and such, just dump the
|
||||
raw info (basically, assume a non-human reading).
|
||||
.It Fl R
|
||||
Show which packages required by each of the packages given on the
|
||||
command line.
|
||||
Show which packages are required by each package.
|
||||
.It Fl r
|
||||
Show the requirements script (if any) for each package.
|
||||
.It Fl S
|
||||
|
@ -164,7 +163,7 @@ can be overridden by specifying an alternative directory in the
|
|||
.Ev PKG_DBDIR
|
||||
environment variable.
|
||||
.It Ev PKG_PATH
|
||||
This can be used to specify a colon-separated list of paths to search for
|
||||
This can be used to specify a semicolon-separated list of paths and URLs to search for
|
||||
package files. The current directory is always searched first, even if
|
||||
.Ev PKG_PATH
|
||||
is set. If
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
# $NetBSD: Makefile,v 1.12 1999/03/22 05:02:41 hubertf Exp $
|
||||
# $NetBSD: Makefile,v 1.13 2000/01/19 23:28:32 hubertf Exp $
|
||||
# Original from FreeBSD, no rcs id.
|
||||
|
||||
LIB= install
|
||||
SRCS= exec.c file.c global.c lpkg.c pen.c pkgdb.c plist.c str.c
|
||||
SRCS= exec.c file.c ftpio.c global.c lpkg.c pen.c pkgdb.c \
|
||||
plist.c str.c
|
||||
|
||||
MKLINT= no
|
||||
MKMAN= no
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
/* $NetBSD: exec.c,v 1.6 1999/08/24 00:48:39 hubertf Exp $ */
|
||||
/* $NetBSD: exec.c,v 1.7 2000/01/19 23:28:32 hubertf Exp $ */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static const char *rcsid = "from FreeBSD Id: exec.c,v 1.6 1997/10/08 07:47:50 charnier Exp";
|
||||
#else
|
||||
__RCSID("$NetBSD: exec.c,v 1.6 1999/08/24 00:48:39 hubertf Exp $");
|
||||
__RCSID("$NetBSD: exec.c,v 1.7 2000/01/19 23:28:32 hubertf Exp $");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -56,8 +56,8 @@ vsystem(const char *fmt,...)
|
|||
warnx("vsystem args are too long");
|
||||
return 1;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
printf("Executing %s\n", cmd);
|
||||
#ifdef VSYSTEM_DEBUG
|
||||
printf("vsystem(\"%s\")\n", cmd);
|
||||
#endif
|
||||
ret = system(cmd);
|
||||
va_end(args);
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
/* $NetBSD: file.c,v 1.35 1999/12/01 14:51:53 hubertf Exp $ */
|
||||
/* $NetBSD: file.c,v 1.36 2000/01/19 23:28:32 hubertf Exp $ */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static const char *rcsid = "from FreeBSD Id: file.c,v 1.29 1997/10/08 07:47:54 charnier Exp";
|
||||
#else
|
||||
__RCSID("$NetBSD: file.c,v 1.35 1999/12/01 14:51:53 hubertf Exp $");
|
||||
__RCSID("$NetBSD: file.c,v 1.36 2000/01/19 23:28:32 hubertf Exp $");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -40,6 +40,7 @@ __RCSID("$NetBSD: file.c,v 1.35 1999/12/01 14:51:53 hubertf Exp $");
|
|||
#include <time.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* This is as ftpGetURL from FreeBSD's ftpio.c, except that it uses
|
||||
* NetBSD's ftp command to do all FTP, which will DTRT for proxies,
|
||||
|
@ -83,7 +84,10 @@ ftpGetURL(char *url, int *retcode)
|
|||
}
|
||||
}
|
||||
return ftp;
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Quick check to see if a file (or dir ...) exists
|
||||
|
@ -208,7 +212,7 @@ URLlength(char *fname)
|
|||
}
|
||||
for (up = urls; up->u_s; up++) {
|
||||
if (strncmp(fname, up->u_s, up->u_len) == 0) {
|
||||
return i + up->u_len;
|
||||
return i + up->u_len; /* ... + sizeof(up->u_s); - HF */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -253,7 +257,7 @@ fileURLFilename(char *fname, char *where, int max)
|
|||
int i;
|
||||
|
||||
if ((i = URLlength(fname)) < 0) { /* invalid URL? */
|
||||
errx(1, "fileURLhost called with a bad URL: `%s'", fname);
|
||||
errx(1, "fileURLFilename called with a bad URL: `%s'", fname);
|
||||
}
|
||||
fname += i;
|
||||
/* Do we have a place to stick our work? */
|
||||
|
@ -284,9 +288,7 @@ fileGetURL(char *base, char *spec)
|
|||
char *cp, *rp;
|
||||
char fname[FILENAME_MAX];
|
||||
char pen[FILENAME_MAX];
|
||||
FILE *ftp;
|
||||
pid_t tpid;
|
||||
int i, status;
|
||||
int rc;
|
||||
char *hint;
|
||||
|
||||
rp = NULL;
|
||||
|
@ -321,12 +323,13 @@ fileGetURL(char *base, char *spec)
|
|||
}
|
||||
} else
|
||||
strcpy(fname, spec);
|
||||
|
||||
/* Some sanity checks on the URL */
|
||||
cp = fileURLHost(fname, host, MAXHOSTNAMELEN);
|
||||
if (!*cp) {
|
||||
warnx("URL `%s' has bad host part!", fname);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cp = fileURLFilename(fname, file, FILENAME_MAX);
|
||||
if (!*cp) {
|
||||
warnx("URL `%s' has bad filename part!", fname);
|
||||
|
@ -335,6 +338,8 @@ fileGetURL(char *base, char *spec)
|
|||
|
||||
if (Verbose)
|
||||
printf("Trying to fetch %s.\n", fname);
|
||||
|
||||
#if 0
|
||||
ftp = ftpGetURL(fname, &status);
|
||||
if (ftp) {
|
||||
pen[0] = '\0';
|
||||
|
@ -363,6 +368,24 @@ fileGetURL(char *base, char *spec)
|
|||
fname,
|
||||
status ? "Error while performing FTP" :
|
||||
hstrerror(h_errno));
|
||||
#else
|
||||
pen[0] = '\0';
|
||||
rp = make_playpen(pen, sizeof(pen), 0);
|
||||
if (rp == NULL) {
|
||||
printf("Error: Unable to construct a new playpen for FTP!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rp = strdup(pen);
|
||||
/* printf("fileGetURL: fname='%s', pen='%s'\n", fname, pen); *//*HF*/
|
||||
rc = unpackURL(fname, pen);
|
||||
if (rc < 0) {
|
||||
leave_playpen(rp); /* Don't leave dir hang around! */
|
||||
|
||||
printf("Error on unpackURL('%s', '%s')\n", fname, pen);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
return rp;
|
||||
}
|
||||
|
||||
|
@ -378,6 +401,10 @@ fileFindByPath(char *base, char *fname)
|
|||
static char tmp[FILENAME_MAX];
|
||||
char *cp;
|
||||
|
||||
/* printf("HF: fileFindByPath(\"%s\", \"%s\")\n", base, fname); *//*HF*/
|
||||
|
||||
/* The following code won't return a match if base is an URL
|
||||
* Could save some cycles here - HF */
|
||||
if (ispkgpattern(fname)) {
|
||||
if ((cp = findbestmatchingname(".", fname)) != NULL) {
|
||||
strcpy(tmp, cp);
|
||||
|
@ -403,7 +430,28 @@ fileFindByPath(char *base, char *fname)
|
|||
strcat(cp, "All/");
|
||||
strcat(cp, fname);
|
||||
strcat(cp, ".tgz");
|
||||
|
||||
if (ispkgpattern(tmp)) {
|
||||
if (IS_URL(tmp)) {
|
||||
/* some package depends on a wildcard pkg */
|
||||
int rc;
|
||||
char url[FILENAME_MAX];
|
||||
|
||||
/* save url to expand, as tmp is the static var in which
|
||||
* we return the result of the expansion.
|
||||
*/
|
||||
strcpy(url, tmp);
|
||||
|
||||
/* printf("HF: expandURL('%s')'ing #1\n", url);*//*HF*/
|
||||
rc = expandURL(tmp, url);
|
||||
if (rc < 0) {
|
||||
warnx("fileFindByPath: expandURL('%s') failed\n", url);
|
||||
return NULL;
|
||||
}
|
||||
if (Verbose)
|
||||
printf("'%s' expanded to '%s'\n", url, tmp);
|
||||
return tmp; /* return expanded URL w/ corrent pkg */
|
||||
} else {
|
||||
cp = findbestmatchingname(dirname_of(tmp), basename_of(tmp));
|
||||
if (cp) {
|
||||
char *s;
|
||||
|
@ -412,19 +460,80 @@ fileFindByPath(char *base, char *fname)
|
|||
strcpy(s + 1, cp);
|
||||
return tmp;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (fexists(tmp)) {
|
||||
return tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (IS_URL(fname)) {
|
||||
/* Wildcard-URL directly specified on command line */
|
||||
int rc;
|
||||
|
||||
/* printf("HF: expandURL('%s')'ing #2\n", fname);*//*HF*/
|
||||
rc = expandURL(tmp, fname);
|
||||
if (rc < 0) {
|
||||
warnx("fileFindByPath: expandURL('%s') failed\n", fname);
|
||||
return NULL;
|
||||
}
|
||||
if (Verbose)
|
||||
printf("'%s' expanded to '%s'\n", fname, tmp);
|
||||
return tmp; /* return expanded URL w/ corrent pkg */
|
||||
}
|
||||
}
|
||||
|
||||
cp = getenv("PKG_PATH");
|
||||
while (cp) {
|
||||
char *cp2 = strsep(&cp, ":");
|
||||
char *cp2 = strsep(&cp, ";");
|
||||
|
||||
printf("trying PKG_PATH %s\n", cp2?cp2:cp);
|
||||
|
||||
if (strstr(fname, ".tgz")) {
|
||||
/* There's already a ".tgz" present, probably typed on the command line */
|
||||
(void) snprintf(tmp, sizeof(tmp), "%s/%s", cp2 ? cp2 : cp, fname);
|
||||
} else {
|
||||
/* Try this component, and tack on a ".tgz" */
|
||||
(void) snprintf(tmp, sizeof(tmp), "%s/%s.tgz", cp2 ? cp2 : cp, fname);
|
||||
}
|
||||
if (IS_URL(tmp)) {
|
||||
char url[FILENAME_MAX];
|
||||
int rc;
|
||||
|
||||
/* save url to expand, as tmp is the static var in which
|
||||
* we return the result of the expansion.
|
||||
*/
|
||||
strcpy(url, tmp);
|
||||
|
||||
/* printf("HF: expandURL('%s')'ing #3\n", url);*//*HF*/
|
||||
rc = expandURL(tmp, url);
|
||||
if (rc >= 0) {
|
||||
printf("fileFindByPath: success, expandURL('%s') returns '%s'\n", url, tmp);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/* Second chance - maybe just a package name was given, without
|
||||
* a version number. Remove the ".tgz" we tacked on above, and
|
||||
* re-add it with a "-[0-9]*" before. Then see if this matches
|
||||
* something. See also perform.c.
|
||||
*/
|
||||
{
|
||||
char *s;
|
||||
s=strstr(tmp, ".tgz");
|
||||
*s = '\0';
|
||||
snprintf(url, FILENAME_MAX, "%s-[0-9]*.tgz", tmp);
|
||||
rc = expandURL(tmp, url);
|
||||
if (rc >= 0) {
|
||||
printf("fileFindByPath: late success, expandURL('%s') returns '%s'\n",
|
||||
url, tmp);
|
||||
return tmp;
|
||||
}
|
||||
}
|
||||
|
||||
/* No luck with this parth of PKG_PATH - try next one */
|
||||
|
||||
} else {
|
||||
if (ispkgpattern(tmp)) {
|
||||
char *s;
|
||||
s = findbestmatchingname(dirname_of(tmp), basename_of(tmp));
|
||||
|
@ -437,6 +546,28 @@ fileFindByPath(char *base, char *fname)
|
|||
} else {
|
||||
if (fexists(tmp) && isfile(tmp)) {
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/* Second chance: seems just a pkg name was given,
|
||||
* no wildcard, no .tgz. Tack something on and retry.
|
||||
* (see above, and perform.c)
|
||||
*/
|
||||
{
|
||||
char *s;
|
||||
char buf2[FILENAME_MAX];
|
||||
|
||||
s = strstr(tmp, ".tgz");
|
||||
*s = '\0';
|
||||
snprintf(buf2, FILENAME_MAX, "%s-[0-9]*.tgz", tmp);
|
||||
s = findbestmatchingname(dirname_of(buf2), basename_of(buf2));
|
||||
if (s) {
|
||||
char *t;
|
||||
strcpy(tmp, buf2); /* now we can overwrite it */
|
||||
t = strrchr(tmp, '/');
|
||||
strcpy(t+1, s);
|
||||
return tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,748 @@
|
|||
/* $NetBSD: ftpio.c,v 1.7 2000/01/19 23:28:33 hubertf Exp $ */
|
||||
/* Id: foo2.c,v 1.12 1999/12/17 02:31:57 feyrer Exp feyrer */
|
||||
|
||||
/*
|
||||
* Work to implement wildcard dependency processing via FTP for the
|
||||
* NetBSD pkg_* package tools.
|
||||
*
|
||||
* Copyright (c) 1999 Hubert Feyrer <hubertf@netbsd.org>
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/signal.h>
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <regex.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <vis.h>
|
||||
|
||||
#include "../lib/lib.h"
|
||||
|
||||
/*
|
||||
* Names of environment variables used to pass things to
|
||||
* subprocesses, for connection caching.
|
||||
*/
|
||||
#define PKG_FTPIO_COMMAND "PKG_FTPIO_COMMAND"
|
||||
#define PKG_FTPIO_ANSWER "PKG_FTPIO_ANSWER"
|
||||
#define PKG_FTPIO_CNT "PKG_FTPIO_CNT"
|
||||
#define PKG_FTPIO_CURRENTHOST "PKG_FTPIO_CURRENTHOST"
|
||||
#define PKG_FTPIO_CURRENTDIR "PKG_FTPIO_CURRENTDIR"
|
||||
|
||||
#undef STANDALONE /* define for standalone debugging */
|
||||
|
||||
/* File descriptors */
|
||||
typedef struct {
|
||||
int command;
|
||||
int answer;
|
||||
} fds;
|
||||
|
||||
|
||||
#if EXPECT_DEBUG
|
||||
static int expect_debug = 1;
|
||||
#endif /* EXPECT_DEBUG */
|
||||
#ifdef STANDALONE
|
||||
int Verbose=1;
|
||||
#endif
|
||||
static int needclose=0;
|
||||
static int ftp_started=0;
|
||||
static fds ftpio;
|
||||
|
||||
|
||||
/*
|
||||
* expect "str" (a regular expression) on file descriptor "fd", storing
|
||||
* the FTP return code of the command in the integer "ftprc". The "str"
|
||||
* string is expected to match some FTP return codes after a '\n', e.g.
|
||||
* "\n(550|226).*\n"
|
||||
*/
|
||||
static int
|
||||
expect(int fd, const char *str, int *ftprc)
|
||||
{
|
||||
int rc;
|
||||
char buf[90];
|
||||
#if EXPECT_DEBUG
|
||||
char *vstr;
|
||||
#endif /* EXPECT_DEBUG */
|
||||
regex_t rstr;
|
||||
int done;
|
||||
struct timeval timeout;
|
||||
int retval;
|
||||
regmatch_t pmatch;
|
||||
int verbose_expect=0;
|
||||
|
||||
#if EXPECT_DEBUG
|
||||
vstr=malloc(2*sizeof(buf));
|
||||
if (vstr == NULL)
|
||||
err(1, "expect: malloc() failed");
|
||||
strvis(vstr, str, VIS_NL|VIS_SAFE|VIS_CSTYLE);
|
||||
#endif /* EXPECT_DEBUG */
|
||||
|
||||
if (regcomp(&rstr, str, REG_EXTENDED) != 0)
|
||||
err(1, "expect: regcomp() failed");
|
||||
|
||||
#if EXPECT_DEBUG
|
||||
if (expect_debug)
|
||||
printf("expecting \"%s\" on fd %d ...\n", vstr, fd);
|
||||
#endif /* EXPECT_DEBUG */
|
||||
|
||||
if(0) setbuf(stdout, NULL);
|
||||
|
||||
memset(buf, '#', sizeof(buf));
|
||||
|
||||
timeout.tv_sec=60;
|
||||
timeout.tv_usec=0;
|
||||
done=0;
|
||||
retval=0;
|
||||
while(!done) {
|
||||
fd_set fdset;
|
||||
|
||||
FD_ZERO(&fdset);
|
||||
FD_SET(fd, &fdset);
|
||||
rc = select(FD_SETSIZE, &fdset, NULL, NULL, &timeout);
|
||||
switch (rc) {
|
||||
case -1:
|
||||
warn("expect: select() failed (probably ftp died because of bad args)");
|
||||
done = 1;
|
||||
retval = -1;
|
||||
break;
|
||||
case 0:
|
||||
warnx("expect: select() timeout!");
|
||||
done = 1; /* hope that's ok */
|
||||
retval = -1;
|
||||
break;
|
||||
default:
|
||||
rc=read(fd,&buf[sizeof(buf)-1],1);
|
||||
|
||||
if (verbose_expect)
|
||||
putchar(buf[sizeof(buf)-1]);
|
||||
|
||||
#if EXPECT_DEBUG
|
||||
{
|
||||
char *v=malloc(2*sizeof(buf));
|
||||
strvis(v, buf, VIS_NL|VIS_SAFE|VIS_CSTYLE);
|
||||
if (expect_debug)
|
||||
printf("expect=<%s>, buf=<%*s>\n", vstr, strlen(v), v);
|
||||
free(v);
|
||||
}
|
||||
#endif /* EXPECT_DEBUG */
|
||||
|
||||
if (regexec(&rstr, buf, 1, &pmatch, 0) == 0) {
|
||||
#if EXPECT_DEBUG
|
||||
if (expect_debug)
|
||||
printf("Gotcha -> %s!\n", buf+pmatch.rm_so+1);
|
||||
fflush(stdout);
|
||||
#endif /* EXPECT_DEBUG */
|
||||
|
||||
if (ftprc && isdigit(buf[pmatch.rm_so+1]))
|
||||
*ftprc = atoi(buf+pmatch.rm_so+1);
|
||||
|
||||
done=1;
|
||||
retval=0;
|
||||
}
|
||||
|
||||
memmove(buf, buf+1, sizeof(buf)-1); /* yes, this is non-performant */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#if EXPECT_DEBUG
|
||||
printf("done.\n");
|
||||
|
||||
if (str)
|
||||
free(vstr);
|
||||
#endif /* EXPECT_DEBUG */
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* send a certain ftp-command "cmd" to our FTP coprocess, and wait for
|
||||
* "expectstr" to be returned. Return numeric FTP return code.
|
||||
*/
|
||||
static int
|
||||
ftp_cmd(const char *cmd, const char *expectstr)
|
||||
{
|
||||
int rc=0, verbose_ftp=0;
|
||||
|
||||
if (Verbose)
|
||||
verbose_ftp=1;
|
||||
|
||||
if (verbose_ftp)
|
||||
fprintf(stderr, "\n[1mftp> %s[0m", cmd);
|
||||
|
||||
fflush(stdout);
|
||||
rc=write(ftpio.command, cmd, strlen(cmd));
|
||||
if (rc == strlen(cmd)) {
|
||||
if (expectstr) {
|
||||
expect(ftpio.answer, expectstr, &rc);
|
||||
}
|
||||
} else {
|
||||
if (Verbose)
|
||||
warn("short write");
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Really fire up FTP coprocess
|
||||
*/
|
||||
static int
|
||||
setupCoproc(const char *base)
|
||||
{
|
||||
int command_pipe[2];
|
||||
int answer_pipe[2];
|
||||
int rc1, rc2;
|
||||
char buf[20];
|
||||
|
||||
rc1 = pipe(command_pipe);
|
||||
rc2 = pipe(answer_pipe);
|
||||
|
||||
if(rc1==-1 || rc2==-1) {
|
||||
warn("setupCoproc: pipe() failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc1=fork();
|
||||
switch (rc1) {
|
||||
case -1:
|
||||
/* Error */
|
||||
|
||||
warn("setupCoproc: fork() failed");
|
||||
return -1;
|
||||
break;
|
||||
|
||||
case 0:
|
||||
/* Child */
|
||||
|
||||
close(command_pipe[1]);
|
||||
dup2(command_pipe[0], 0);
|
||||
close(command_pipe[0]);
|
||||
|
||||
close(answer_pipe[0]);
|
||||
dup2(answer_pipe[1], 1);
|
||||
close(answer_pipe[1]);
|
||||
|
||||
setbuf(stdout, NULL);
|
||||
|
||||
if (Verbose)
|
||||
fprintf(stderr, "[1mftp -detv %s[0m\n", base);
|
||||
rc1 = execl("/usr/bin/ftp", "ftp", "-detv", base, NULL);
|
||||
warn("setupCoproc: execl() failed");
|
||||
exit(-1);
|
||||
break;
|
||||
default:
|
||||
/* Parent */
|
||||
close(command_pipe[0]);
|
||||
close(answer_pipe[1]);
|
||||
|
||||
snprintf(buf, sizeof(buf), "%d", command_pipe[1]);
|
||||
setenv(PKG_FTPIO_COMMAND, buf, 1);
|
||||
snprintf(buf, sizeof(buf), "%d", answer_pipe[0]);
|
||||
setenv(PKG_FTPIO_ANSWER, buf, 1);
|
||||
|
||||
ftpio.command = command_pipe[1];
|
||||
ftpio.answer = answer_pipe[0];
|
||||
|
||||
fcntl(ftpio.command, F_SETFL, O_NONBLOCK);
|
||||
fcntl(ftpio.answer , F_SETFL, O_NONBLOCK);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* SIGPIPE only happens when there's something wrong with the FTP
|
||||
* coprocess. In that case, set mark to not try to close shut down
|
||||
* the coprocess.
|
||||
*/
|
||||
static void
|
||||
sigpipe_handler(int n)
|
||||
{
|
||||
/* aparently our ftp companion died */
|
||||
if (Verbose)
|
||||
fprintf(stderr, "SIGPIPE!\n");
|
||||
needclose = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Close the FTP coprocess' current connection, but
|
||||
* keep the process itself alive.
|
||||
*/
|
||||
void
|
||||
ftp_stop(void)
|
||||
{
|
||||
char *tmp1, *tmp2;
|
||||
|
||||
if (!ftp_started)
|
||||
return;
|
||||
|
||||
tmp1=getenv(PKG_FTPIO_COMMAND);
|
||||
tmp2=getenv(PKG_FTPIO_ANSWER);
|
||||
|
||||
/* (Only) the last one closes the link */
|
||||
if (tmp1 != NULL && tmp2 != NULL) {
|
||||
if (needclose)
|
||||
ftp_cmd("close\n", "\n(221 Goodbye.|Not connected.)\n");
|
||||
|
||||
close(ftpio.command);
|
||||
close(ftpio.answer);
|
||||
}
|
||||
|
||||
unsetenv(PKG_FTPIO_COMMAND);
|
||||
unsetenv(PKG_FTPIO_ANSWER);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* (Start and re-)Connect the FTP coprocess to some host/dir.
|
||||
* If the requested host/dir is different than the one that the
|
||||
* coprocess is currently at, close first.
|
||||
*/
|
||||
static int
|
||||
ftp_start(char *base)
|
||||
{
|
||||
char *tmp1, *tmp2;
|
||||
int rc;
|
||||
char newHost[256];
|
||||
char newDir[1024];
|
||||
char *currentHost=getenv(PKG_FTPIO_CURRENTHOST);
|
||||
char *currentDir=getenv(PKG_FTPIO_CURRENTDIR);
|
||||
|
||||
fileURLHost(base, newHost, sizeof(newHost));
|
||||
strcpy(newDir, strchr(base+URLlength(base), '/') + 1);
|
||||
if (currentHost
|
||||
&& currentDir
|
||||
&& ( strcmp(newHost, currentHost) != 0
|
||||
|| strcmp(newDir, currentDir) != 0)) { /* could handle new dir case better here, w/o reconnect */
|
||||
if (Verbose) {
|
||||
printf("ftp_stgart: new host or dir, stopping previous connect...\n");
|
||||
printf("currentHost='%s', newHost='%s'\n", currentHost, newHost);
|
||||
printf("currentDir='%s', newDir='%s'\n", currentDir, newDir);
|
||||
}
|
||||
|
||||
ftp_stop();
|
||||
|
||||
if (Verbose)
|
||||
printf("ftp stopped\n");
|
||||
}
|
||||
setenv(PKG_FTPIO_CURRENTHOST, newHost, 1); /* need to update this in the environment */
|
||||
setenv(PKG_FTPIO_CURRENTDIR, newDir, 1); /* for subprocesses to have this available */
|
||||
|
||||
tmp1=getenv(PKG_FTPIO_COMMAND);
|
||||
tmp2=getenv(PKG_FTPIO_ANSWER);
|
||||
if(tmp1==NULL || tmp2==NULL || *tmp1=='\0' || *tmp2=='\0') {
|
||||
/* no FTP coprocess running yet */
|
||||
|
||||
if (Verbose)
|
||||
printf("Spawning FTP coprocess\n");
|
||||
|
||||
rc = setupCoproc(base);
|
||||
if (rc == -1) {
|
||||
warnx("setupCoproc() failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
needclose=1;
|
||||
signal(SIGPIPE, sigpipe_handler);
|
||||
|
||||
if ((expect(ftpio.answer, "\n(221|250|221|550).*\n", &rc) != 0)
|
||||
|| rc != 250) {
|
||||
warnx("expect1 failed, rc=%d", rc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = ftp_cmd("prompt off\n", "\n(Interactive mode off|221).*\n");
|
||||
if (rc == 221) {
|
||||
/* something is wrong */
|
||||
ftp_started=1; /* not really, but for ftp_stop() */
|
||||
ftp_stop();
|
||||
}
|
||||
|
||||
ftp_started=1;
|
||||
} else {
|
||||
/* get FDs of our coprocess */
|
||||
|
||||
ftpio.command = dup(atoi(tmp1));
|
||||
ftpio.answer = dup(atoi(tmp2));
|
||||
|
||||
if (Verbose)
|
||||
printf("Reusing FDs %s/%s for communication to FTP coprocess\n", tmp1, tmp2);
|
||||
|
||||
fcntl(ftpio.command, F_SETFL, O_NONBLOCK);
|
||||
fcntl(ftpio.answer , F_SETFL, O_NONBLOCK);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Expand the given wildcard URL "wildcardurl" if possible, and store the
|
||||
* expanded value into "expandedurl". return 0 if successful, -1 else.
|
||||
*/
|
||||
int
|
||||
expandURL(char *expandedurl, const char *wildcardurl)
|
||||
{
|
||||
char *pkg;
|
||||
int rc;
|
||||
char base[FILENAME_MAX];
|
||||
|
||||
pkg=strrchr(wildcardurl, '/');
|
||||
if (pkg == NULL){
|
||||
warnx("expandURL: no '/' in url %s?!", wildcardurl);
|
||||
return -1;
|
||||
}
|
||||
snprintf(base, FILENAME_MAX, "%*.*s/", pkg-wildcardurl, pkg-wildcardurl, wildcardurl);
|
||||
pkg++;
|
||||
|
||||
rc = ftp_start(base);
|
||||
if (rc == -1) {
|
||||
warnx("ftp_start() failed");
|
||||
return -1; /* error */
|
||||
}
|
||||
|
||||
/* for a given wildcard URL, find the best matching pkg */
|
||||
{
|
||||
char *s, buf[FILENAME_MAX];
|
||||
char tmpname[FILENAME_MAX];
|
||||
char best[FILENAME_MAX];
|
||||
|
||||
strcpy(tmpname, "/tmp/pkg.XXX");
|
||||
mktemp(tmpname);
|
||||
assert(tmpname != NULL);
|
||||
|
||||
s=strpbrk(pkg, "<>[]?*{"); /* Could leave out "[]?*" here;
|
||||
* ftp(1) is not that stupid */
|
||||
if (!s) {
|
||||
/* This should only happen when getting here with (only) a package
|
||||
* name specified to pkg_add, and PKG_PATH containing some URL.
|
||||
*/
|
||||
snprintf(buf,FILENAME_MAX, "ls %s %s\n", pkg, tmpname);
|
||||
} else {
|
||||
/* replace possible version(wildcard) given with "-*".
|
||||
* we can't use the pkg wildcards here as dewey compare
|
||||
* and alternates won't be handled by ftp(1); sort
|
||||
* out later, using pmatch() */
|
||||
snprintf(buf, FILENAME_MAX, "ls %*.*s*.tgz %s\n", s-pkg, s-pkg, pkg, tmpname);
|
||||
}
|
||||
|
||||
rc = ftp_cmd(buf, "\n(550|226).*\n"); /* catch errors */
|
||||
if (rc != 226) {
|
||||
if (Verbose)
|
||||
warnx("ls failed!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Sync - don't remove */
|
||||
rc = ftp_cmd("cd .\n", "\n(550|250).*\n");
|
||||
if (rc != 250) {
|
||||
warnx("chdir failed!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
best[0]='\0';
|
||||
if (access(tmpname, R_OK)==0) {
|
||||
int matches;
|
||||
FILE *f;
|
||||
char filename[FILENAME_MAX];
|
||||
|
||||
f=fopen(tmpname, "r");
|
||||
if (f == NULL) {
|
||||
warn("fopen");
|
||||
return -1;
|
||||
}
|
||||
matches=0;
|
||||
/* The following loop is basically the same as the readdir() loop
|
||||
* in findmatchingname() */
|
||||
while (fgets(filename, FILENAME_MAX, f)) {
|
||||
filename[strlen(filename)-1] = '\0';
|
||||
if (pmatch(pkg, filename)) {
|
||||
matches++;
|
||||
|
||||
/* compare findbestmatchingname() */
|
||||
findbestmatchingname_fn(filename, best);
|
||||
}
|
||||
}
|
||||
fclose(f);
|
||||
|
||||
if (matches == 0)
|
||||
warnx("nothing appropriate found\n");
|
||||
}
|
||||
|
||||
unlink(tmpname);
|
||||
|
||||
if (best[0] != '\0') {
|
||||
if (Verbose)
|
||||
printf("best match: '%s%s'\n", base, best);
|
||||
sprintf(expandedurl, "%s%s", base, best);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* extract the given (expanded) URL "url" to the given directory "dir"
|
||||
* return -1 on error, 0 else;
|
||||
*/
|
||||
int
|
||||
unpackURL(const char *url, const char *dir)
|
||||
{
|
||||
char *pkg;
|
||||
int rc;
|
||||
char base[FILENAME_MAX];
|
||||
char pkg_path[FILENAME_MAX];
|
||||
|
||||
{
|
||||
/* Verify if the url is really ok */
|
||||
int rc;
|
||||
char exp[FILENAME_MAX];
|
||||
|
||||
rc=expandURL(exp, url);
|
||||
if (rc == -1) {
|
||||
warnx("unpackURL: verification expandURL failed");
|
||||
return -1;
|
||||
}
|
||||
if (strcmp(exp, url) != 0) {
|
||||
warnx("unpackURL: verificatinon expandURL failed, '%s'!='%s'",
|
||||
exp, url);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
pkg=strrchr(url, '/');
|
||||
if (pkg == NULL){
|
||||
warnx("unpackURL: no '/' in url %s?!", url);
|
||||
return -1;
|
||||
}
|
||||
snprintf(base, FILENAME_MAX, "%*.*s/", pkg-url, pkg-url, url);
|
||||
snprintf(pkg_path, FILENAME_MAX, "%*.*s", pkg-url, pkg-url, url); /* no trailing '/' */
|
||||
pkg++;
|
||||
|
||||
/* Leave a hint for any depending pkgs that may need it */
|
||||
if (getenv("PKG_PATH") == NULL) {
|
||||
setenv("PKG_PATH", pkg_path, 1);
|
||||
printf("setenv PKG_PATH='%s'\n",pkg_path);
|
||||
}
|
||||
|
||||
rc = ftp_start(base);
|
||||
if (rc == -1) {
|
||||
warnx("ftp_start() failed");
|
||||
return -1; /* error */
|
||||
}
|
||||
|
||||
{
|
||||
char cmd[1024];
|
||||
|
||||
if (Verbose)
|
||||
printf("unpackURL '%s' to '%s'\n", url, dir);
|
||||
|
||||
/* yes, this is gross, but needed for borken ftp(1) */
|
||||
snprintf(cmd, sizeof(cmd), "get %s \"| ( cd %s ; gunzip 2>/dev/null | tar -%sx -f - )\"\n", pkg, dir, Verbose?"vv":"");
|
||||
rc = ftp_cmd(cmd, "\n(226|550).*\n");
|
||||
if (rc != 226) {
|
||||
warnx("Cannot fetch file (%d!=226)!", rc);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* Some misc stuff not needed yet, but maybe later
|
||||
*/
|
||||
int
|
||||
miscstuff(const char *url)
|
||||
{
|
||||
char *pkg;
|
||||
int rc;
|
||||
char base[FILENAME_MAX];
|
||||
|
||||
pkg=strrchr(url, '/');
|
||||
if (pkg == NULL){
|
||||
warnx("miscstuff: no '/' in url %s?!", url);
|
||||
return -1;
|
||||
}
|
||||
snprintf(base, FILENAME_MAX, "%*.*s/", pkg-url, pkg-url, url);
|
||||
pkg++;
|
||||
|
||||
rc = ftp_start(base);
|
||||
if (rc == -1) {
|
||||
warnx("ftp_start() failed");
|
||||
return -1; /* error */
|
||||
}
|
||||
|
||||
/* basic operation */
|
||||
if (0) {
|
||||
rc = ftp_cmd("cd ../All\n", "\n(550|250).*\n");
|
||||
if (rc != 250) {
|
||||
warnx("chdir failed!");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* get and extract a file to tmpdir */
|
||||
if (0) {
|
||||
char cmd[256];
|
||||
char tmpdir[256];
|
||||
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/dir%s",
|
||||
(getenv(PKG_FTPIO_CNT))?getenv(PKG_FTPIO_CNT):"");
|
||||
|
||||
mkdir(tmpdir, 0755);
|
||||
|
||||
/* yes, this is gross, but needed for borken ftp(1) */
|
||||
snprintf(cmd, sizeof(cmd), "get xpmroot-1.01.tgz \"| ( cd %s ; gunzip 2>/dev/null | tar -vvx -f - )\"\n", tmpdir);
|
||||
rc = ftp_cmd(cmd, "\n(226|550).*\n");
|
||||
if (rc != 226) {
|
||||
warnx("Cannot fetch file (%d != 226)!", rc);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* check if one more file(s) exist */
|
||||
if (0) {
|
||||
char buf[FILENAME_MAX];
|
||||
snprintf(buf,FILENAME_MAX, "ls %s /tmp/xxx\n", pkg);
|
||||
rc = ftp_cmd(buf, "\n(226|550).*\n"); /* catch errors */
|
||||
if (rc != 226) {
|
||||
if (Verbose)
|
||||
warnx("ls failed!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Sync - don't remove */
|
||||
rc = ftp_cmd("cd .\n", "\n(550|250).*\n");
|
||||
if (rc != 250) {
|
||||
warnx("chdir failed!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (access("/tmp/xxx", R_OK)==0) {
|
||||
system("cat /tmp/xxx");
|
||||
|
||||
{
|
||||
/* count lines - >0 -> fexists() == true */
|
||||
int len, count;
|
||||
FILE *f;
|
||||
|
||||
f=fopen("/tmp/xxx", "r");
|
||||
if (f == NULL) {
|
||||
warn("fopen");
|
||||
return -1;
|
||||
}
|
||||
count=0;
|
||||
while (fgetln(f, &len))
|
||||
count++;
|
||||
fclose(f);
|
||||
|
||||
printf("#lines = %d\n", count);
|
||||
}
|
||||
} else
|
||||
printf("NO MATCH\n");
|
||||
|
||||
unlink("/tmp/xxx");
|
||||
}
|
||||
|
||||
/* for a given wildcard URL, find the best matching pkg */
|
||||
/* spawn child - like pkg_add'ing another package */
|
||||
/* Here's where the connection caching kicks in */
|
||||
#if 0
|
||||
if (0) {
|
||||
char *s, buf[FILENAME_MAX];
|
||||
|
||||
if ((s=getenv(PKG_FTPIO_CNT)) && atoi(s)>0){
|
||||
snprintf(buf,FILENAME_MAX,"%d", atoi(s)-1);
|
||||
setenv(PKG_FTPIO_CNT, buf, 1);
|
||||
|
||||
snprintf(buf, FILENAME_MAX, "%s \"%s/%s\"", argv0, url, pkg);
|
||||
printf("%s>>> %s\n", s, buf);
|
||||
system(buf);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef STANDALONE
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
errx(1, "Usage: foo [-v] ftp://-pattern\n");
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int rc, ch;
|
||||
char *argv0 = argv[0];
|
||||
|
||||
while ((ch = getopt(argc, argv, "v")) != -1) {
|
||||
switch (ch) {
|
||||
case 'v':
|
||||
Verbose=1;
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc<1)
|
||||
usage();
|
||||
|
||||
while(argv[0] != NULL) {
|
||||
char newurl[FILENAME_MAX];
|
||||
|
||||
printf("Expand %s:\n", argv[0]);
|
||||
rc = expandURL(newurl, argv[0]);
|
||||
if (rc==-1)
|
||||
warnx("Cannot expand %s", argv[0]);
|
||||
else
|
||||
printf("Expanded URL: %s\n", newurl);
|
||||
|
||||
/* test out connection caching */
|
||||
if (1) {
|
||||
char *s, buf[FILENAME_MAX];
|
||||
|
||||
if ((s=getenv(PKG_FTPIO_CNT)) && atoi(s)>0){
|
||||
snprintf(buf,FILENAME_MAX,"%d", atoi(s)-1);
|
||||
setenv(PKG_FTPIO_CNT, buf, 1);
|
||||
|
||||
snprintf(buf, FILENAME_MAX, "%s -v '%s'", argv0, argv[0]);
|
||||
printf("%s>>> %s\n", s, buf);
|
||||
system(buf);
|
||||
}
|
||||
}
|
||||
|
||||
printf("\n\n\n");
|
||||
argv++;
|
||||
}
|
||||
|
||||
ftp_stop();
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* STANDALONE */
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: lib.h,v 1.28 1999/11/29 20:09:56 hubertf Exp $ */
|
||||
/* $NetBSD: lib.h,v 1.29 2000/01/19 23:28:33 hubertf Exp $ */
|
||||
|
||||
/* from FreeBSD Id: lib.h,v 1.25 1997/10/08 07:48:03 charnier Exp */
|
||||
|
||||
|
@ -180,7 +180,8 @@ void str_lowercase(char *);
|
|||
char *basename_of(char *);
|
||||
char *dirname_of(const char *);
|
||||
int pmatch(const char *, const char *);
|
||||
int findmatchingname(const char *, const char *, matchfn, char *); /* doesn't really belong here */
|
||||
int findmatchingname(const char *, const char *, matchfn, char *); /* doesn't really belong to "strings" */
|
||||
int findbestmatchingname_fn(const char *pkg, char *data); /* neither */
|
||||
char *findbestmatchingname(const char *, const char *); /* neither */
|
||||
int ispkgpattern(const char *);
|
||||
char *strnncpy(char *to, size_t tosize, char *from, size_t cc);
|
||||
|
@ -207,6 +208,11 @@ int delete_hierarchy(char *, Boolean, Boolean);
|
|||
int unpack(char *, char *);
|
||||
void format_cmd(char *, size_t, char *, char *, char *);
|
||||
|
||||
/* ftpio.c: FTP handling */
|
||||
int expandURL(char *expandedurl, const char *wildcardurl);
|
||||
int unpackURL(const char *url, const char *dir);
|
||||
void ftp_stop(void);
|
||||
|
||||
/* Packing list */
|
||||
plist_t *new_plist_entry(void);
|
||||
plist_t *last_plist(package_t *);
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
/* $NetBSD: str.c,v 1.18 1999/12/01 14:51:53 hubertf Exp $ */
|
||||
/* $NetBSD: str.c,v 1.19 2000/01/19 23:28:34 hubertf Exp $ */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static const char *rcsid = "Id: str.c,v 1.5 1997/10/08 07:48:21 charnier Exp";
|
||||
#else
|
||||
__RCSID("$NetBSD: str.c,v 1.18 1999/12/01 14:51:53 hubertf Exp $");
|
||||
__RCSID("$NetBSD: str.c,v 1.19 2000/01/19 23:28:34 hubertf Exp $");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -306,8 +306,9 @@ ispkgpattern(const char *pkg)
|
|||
|
||||
/*
|
||||
* Auxiliary function called by findbestmatchingname() if pkg > data
|
||||
* Also called for FTP matching
|
||||
*/
|
||||
static int
|
||||
int
|
||||
findbestmatchingname_fn(const char *pkg, char *data)
|
||||
{
|
||||
char *s1, *s2;
|
||||
|
|
Loading…
Reference in New Issue