Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F115822410
D49977.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D49977.diff
View Options
diff --git a/usr.sbin/pkg/pkg.7 b/usr.sbin/pkg/pkg.7
--- a/usr.sbin/pkg/pkg.7
+++ b/usr.sbin/pkg/pkg.7
@@ -33,8 +33,9 @@
.Op Fl d
.Ar command ...
.Nm
+.Op Fl d
.Cm add
-.Op Fl dfy
+.Op Fl fy
.Op Fl r Ar reponame
.Ar pkg.txz
.Nm
diff --git a/usr.sbin/pkg/pkg.c b/usr.sbin/pkg/pkg.c
--- a/usr.sbin/pkg/pkg.c
+++ b/usr.sbin/pkg/pkg.c
@@ -942,10 +942,6 @@
"Too many arguments\n"
"Usage: pkg [-4|-6] bootstrap [-f] [-y]\n";
-static const char args_add_message[] =
-"Too many arguments\n"
-"Usage: pkg add [-f] [-y] {pkg.pkg}\n";
-
static int
pkg_query_yes_no(void)
{
@@ -1072,137 +1068,138 @@
main(int argc, char *argv[])
{
char pkgpath[MAXPATHLEN];
+ char **original_argv;
const char *pkgarg, *repo_name;
bool activation_test, add_pkg, bootstrap_only, force, yes;
signed char ch;
const char *fetchOpts;
- char *command;
struct repositories *repositories;
activation_test = false;
add_pkg = false;
bootstrap_only = false;
- command = NULL;
fetchOpts = "";
force = false;
+ original_argv = argv;
pkgarg = NULL;
repo_name = NULL;
yes = false;
struct option longopts[] = {
{ "debug", no_argument, NULL, 'd' },
- { "force", no_argument, NULL, 'f' },
{ "only-ipv4", no_argument, NULL, '4' },
{ "only-ipv6", no_argument, NULL, '6' },
- { "yes", no_argument, NULL, 'y' },
{ NULL, 0, NULL, 0 },
};
snprintf(pkgpath, MAXPATHLEN, "%s/sbin/pkg", getlocalbase());
- while ((ch = getopt_long(argc, argv, "-:dfr::yN46", longopts, NULL)) != -1) {
+ while ((ch = getopt_long(argc, argv, "+:dN46", longopts, NULL)) != -1) {
switch (ch) {
case 'd':
debug++;
break;
- case 'f':
- force = true;
- break;
case 'N':
activation_test = true;
break;
- case 'y':
- yes = true;
- break;
case '4':
fetchOpts = "4";
break;
case '6':
fetchOpts = "6";
break;
- case 'r':
- /*
- * The repository can only be specified for an explicit
- * bootstrap request at this time, so that we don't
- * confuse the user if they're trying to use a verb that
- * has some other conflicting meaning but we need to
- * bootstrap.
- *
- * For that reason, we specify that -r has an optional
- * argument above and process the next index ourselves.
- * This is mostly significant because getopt(3) will
- * otherwise eat the next argument, which could be
- * something we need to try and make sense of.
- *
- * At worst this gets us false positives that we ignore
- * in other contexts, and we have to do a little fudging
- * in order to support separating -r from the reponame
- * with a space since it's not actually optional in
- * the bootstrap/add sense.
- */
- if (add_pkg || bootstrap_only) {
- if (optarg != NULL) {
- repo_name = optarg;
- } else if (optind < argc) {
- repo_name = argv[optind];
- }
+ default:
+ break;
+ }
+ }
+ if (debug > 1)
+ fetchDebug = 1;
- if (repo_name == NULL || *repo_name == '\0') {
- fprintf(stderr,
- "Must specify a repository with -r!\n");
- exit(EXIT_FAILURE);
- }
+ argc -= optind;
+ argv += optind;
+
+ if (argc >= 1) {
+ if (strcmp(argv[0], "bootstrap") == 0) {
+ bootstrap_only = true;
+ } else if (strcmp(argv[0], "add") == 0) {
+ add_pkg = true;
+ }
- if (optarg == NULL) {
- /* Advance past repo name. */
- optreset = 1;
- optind++;
+ optreset = 1;
+ optind = 1;
+ if (bootstrap_only || add_pkg) {
+ struct option sub_longopts[] = {
+ { "force", no_argument, NULL, 'f' },
+ { "yes", no_argument, NULL, 'y' },
+ { NULL, 0, NULL, 0 },
+ };
+ while ((ch = getopt_long(argc, argv, "+:fr:y",
+ sub_longopts, NULL)) != -1) {
+ switch (ch) {
+ case 'f':
+ force = true;
+ break;
+ case 'r':
+ repo_name = optarg;
+ break;
+ case 'y':
+ yes = true;
+ break;
+ case ':':
+ fprintf(stderr, "Option -%c requires an argument\n", optopt);
+ exit(EXIT_FAILURE);
+ break;
+ default:
+ break;
}
}
- break;
- case 1:
- // Non-option arguments, first one is the command
- if (command == NULL) {
- command = argv[optind-1];
- if (strcmp(command, "add") == 0) {
- add_pkg = true;
- }
- else if (strcmp(command, "bootstrap") == 0) {
- bootstrap_only = true;
+ } else {
+ /*
+ * Parse -y and --yes regardless of the pkg subcommand
+ * specified. This is necessary to make, for example,
+ * `pkg install -y foobar` work as expected when pkg is
+ * not yet bootstrapped.
+ */
+ struct option sub_longopts[] = {
+ { "yes", no_argument, NULL, 'y' },
+ { NULL, 0, NULL, 0 },
+ };
+ while ((ch = getopt_long(argc, argv, "+y",
+ sub_longopts, NULL)) != -1) {
+ switch (ch) {
+ case 'y':
+ yes = true;
+ break;
+ default:
+ break;
}
}
- // bootstrap doesn't accept other arguments
- else if (bootstrap_only) {
- fprintf(stderr, args_bootstrap_message);
+
+ }
+ argc -= optind;
+ argv += optind;
+
+ if (bootstrap_only && argc > 0) {
+ fprintf(stderr, args_bootstrap_message);
+ exit(EXIT_FAILURE);
+ }
+
+ if (add_pkg) {
+ if (argc < 1) {
+ fprintf(stderr, "Path to pkg.pkg required\n");
exit(EXIT_FAILURE);
- }
- else if (add_pkg && pkgarg != NULL) {
+ } else if (argc == 1 && pkg_is_pkg_pkg(argv[0])) {
+ pkgarg = argv[0];
+ } else {
/*
- * Additional arguments also means it's not a
- * local bootstrap request.
+ * If the target package is not pkg.pkg
+ * or there is more than one target package,
+ * this is not a local bootstrap request.
*/
add_pkg = false;
}
- else if (add_pkg) {
- /*
- * 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:
- break;
}
}
- if (debug > 1)
- fetchDebug = 1;
if ((bootstrap_only && force) || access(pkgpath, X_OK) == -1) {
struct repository *repo;
@@ -1218,10 +1215,7 @@
config_init(repo_name);
if (add_pkg) {
- if (pkgarg == NULL) {
- fprintf(stderr, "Path to pkg.pkg required\n");
- exit(EXIT_FAILURE);
- }
+ assert(pkgarg != NULL);
if (access(pkgarg, R_OK) == -1) {
fprintf(stderr, "No such file: %s\n", pkgarg);
exit(EXIT_FAILURE);
@@ -1263,7 +1257,7 @@
exit(EXIT_SUCCESS);
}
- execv(pkgpath, argv);
+ execv(pkgpath, original_argv);
/* NOT REACHED */
return (EXIT_FAILURE);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Apr 30, 4:01 AM (12 h, 59 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
17851281
Default Alt Text
D49977.diff (6 KB)
Attached To
Mode
D49977: pkg: clarify argument parsing
Attached
Detach File
Event Timeline
Log In to Comment