pkg: allow multiple add arguments again

While pkg(7) add only handles a single 'add' argument, pkg-add(8) fully
handles multiple arguments.

Stop rejecting it, just turn off local-bootstrap mode and proceed to
remote bootstrap if we need it.

While we're here, check if the first argument to pkg add is even a pkg
package. If it's not, also do remote bootstrap instead. Future work
could improve this altogether by picking out a pkg package out of many
and local bootstrap then pass the rest through to the newly installed
pkg.

Reviewed by:	bapt, manu (earlier version)
MFC after:	3 days
Differential Revision:	https://reviews.freebsd.org/D28766
This commit is contained in:
Kyle Evans 2021-02-17 21:41:53 -06:00
parent 34e7e4b6a0
commit 40b9f924b1

View file

@ -1056,6 +1056,40 @@ bootstrap_pkg_local(const char *pkgpath, bool force)
return (ret);
}
#define PKG_NAME "pkg"
#define PKG_DEVEL_NAME PKG_NAME "-devel"
#define PKG_PKG PKG_NAME "."
static bool
pkg_is_pkg_pkg(const char *pkg)
{
char *vstart;
size_t namelen;
/*
* Chop off the final "-" (version delimiter) and check the name that
* precedes it. If we didn't have a version delimiter, it must be the
* pkg.$archive short form but we'll check it anyways. pkg-devel short
* form will look like a pkg archive with 'devel' version, but that's
* OK. We otherwise assumed that non-pkg packages will always have a
* version component.
*/
vstart = strrchr(pkg, '-');
if (vstart == NULL) {
return (strlen(pkg) > sizeof(PKG_PKG) - 1 &&
strncmp(pkg, PKG_PKG, sizeof(PKG_PKG) - 1) == 0);
}
namelen = vstart - pkg;
if (namelen == sizeof(PKG_NAME) - 1 &&
strncmp(pkg, PKG_NAME, sizeof(PKG_NAME) - 1) == 0)
return (true);
if (namelen == sizeof(PKG_DEVEL_NAME) - 1 &&
strncmp(pkg, PKG_DEVEL_NAME, sizeof(PKG_DEVEL_NAME) - 1) == 0)
return (true);
return (false);
}
int
main(int argc, char *argv[])
{
@ -1159,13 +1193,25 @@ main(int argc, char *argv[])
fprintf(stderr, args_bootstrap_message);
exit(EXIT_FAILURE);
}
// For add, we accept exactly one further argument
else if (add_pkg && pkgarg != NULL) {
fprintf(stderr, args_add_message);
exit(EXIT_FAILURE);
/*
* Additional arguments also means it's not a
* local bootstrap request.
*/
add_pkg = false;
}
else if (add_pkg) {
pkgarg = argv[optind-1];
/*
* If it's not a request for pkg or pkg-devel,
* then we must assume they were trying to
* install some other local package and we
* should try to bootstrap from the repo.
*/
if (!pkg_is_pkg_pkg(argv[optind-1])) {
add_pkg = false;
} else {
pkgarg = argv[optind-1];
}
}
break;
default: