Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 5 May 2021 08:25:28 GMT
From:      Baptiste Daroussin <bapt@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: 0543e10e950d - stable/12 - pkg(7): rework the arguments handling
Message-ID:  <202105050825.1458PSCw028780@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch stable/12 has been updated by bapt:

URL: https://cgit.FreeBSD.org/src/commit/?id=0543e10e950dd5c8b17cdb7cf60b9f95aece094a

commit 0543e10e950dd5c8b17cdb7cf60b9f95aece094a
Author:     Baptiste Daroussin <bapt@FreeBSD.org>
AuthorDate: 2021-01-06 10:35:22 +0000
Commit:     Baptiste Daroussin <bapt@FreeBSD.org>
CommitDate: 2021-05-05 08:16:47 +0000

    pkg(7): rework the arguments handling
    
    Rework the arguments handling around using getopt_long:
    * add long option support
    * add -4 and -6 support to enforce ipv4 or ipv6
    
    While here fix a regression which occured between FreeBSD 12.1 and
    FreeBSD 12.2 where pkg bootstrap -y stopped working
    
    PR:             252270
    Submitted by:   evilham <contact@evilham.com>
    Differential Revision:  https://reviews.freebsd.org/D27860
    
    (cherry picked from commit ae994fdc5bd2ccc0ac0b8745fd1f1be67ad6e071)
---
 usr.sbin/pkg/pkg.7 |  25 ++++++++++--
 usr.sbin/pkg/pkg.c | 117 ++++++++++++++++++++++++++++++++++++-----------------
 2 files changed, 102 insertions(+), 40 deletions(-)

diff --git a/usr.sbin/pkg/pkg.7 b/usr.sbin/pkg/pkg.7
index f7116f5da828..c672306ac08d 100644
--- a/usr.sbin/pkg/pkg.7
+++ b/usr.sbin/pkg/pkg.7
@@ -24,7 +24,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd November 6, 2020
+.Dd December 31, 2020
 .Dt PKG 7
 .Os
 .Sh NAME
@@ -36,12 +36,15 @@
 .Nm
 add
 .Op Fl f
+.Op Fl y
 .Ao Pa pkg.txz Ac
 .Nm
 .Fl N
 .Nm
+.Op Fl 4 | Fl 6
 bootstrap
 .Op Fl f
+.Op Fl y
 .Sh DESCRIPTION
 .Nm
 is the package management tool.
@@ -65,7 +68,7 @@ is not installed yet, it will be fetched, have its signature verified,
 installed, and then have the original command forwarded to it.
 If already installed, the command requested will be forwarded to the real
 .Xr pkg 8 .
-.It Nm Li add Oo Fl f Oc Ao Pa pkg.txz Ac
+.It Nm Li add Oo Fl f Oc Oo Fl y Oc Ao Pa pkg.txz Ac
 Install
 .Xr pkg 8
 from a local package instead of fetching from remote.
@@ -76,21 +79,37 @@ If the
 flag is specified, then
 .Xr pkg 8
 will be installed regardless if it is already installed.
+If the
+.Fl y
+flag is specified, no confirmation will be asked when bootstrapping
+.Xr pkg 8 .
 .It Nm Fl N
 Do not bootstrap, just determine if
 .Xr pkg 8
 is actually installed or not.
 Returns 0 and the number of packages installed
 if it is, otherwise 1.
-.It Nm Li bootstrap Op Fl f
+.It Nm Oo Fl 4 | Fl 6 Oc Li bootstrap Oo Fl f Oc Oo Fl y Oc
 Attempt to bootstrap and do not forward anything to
 .Xr pkg 8
 after it is installed.
+With
+.Fl 4
+and
+.Fl 6 ,
+.Nm
+will force IPv4 or IPv6 respectively to fetch
+.Xr pkg 8
+and its signatures as needed.
 If the
 .Fl f
 flag is specified, then
 .Xr pkg 8
 will be fetched and installed regardless if it is already installed.
+If the
+.Fl y
+flag is specified, no confirmation will be asked when bootstrapping
+.Xr pkg 8 .
 .El
 .Sh CONFIGURATION
 Configuration varies in whether it is in a repository configuration file
diff --git a/usr.sbin/pkg/pkg.c b/usr.sbin/pkg/pkg.c
index 54eaf0882372..aa45a96683ec 100644
--- a/usr.sbin/pkg/pkg.c
+++ b/usr.sbin/pkg/pkg.c
@@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$");
 #include <errno.h>
 #include <fcntl.h>
 #include <fetch.h>
+#include <getopt.h>
 #include <paths.h>
 #include <stdbool.h>
 #include <stdlib.h>
@@ -173,7 +174,7 @@ install_pkg_static(const char *path, const char *pkgpath, bool force)
 }
 
 static int
-fetch_to_fd(const char *url, char *path)
+fetch_to_fd(const char *url, char *path, const char *fetchOpts)
 {
 	struct url *u;
 	struct dns_srvinfo *mirrors, *current;
@@ -225,7 +226,7 @@ fetch_to_fd(const char *url, char *path)
 			u->port = current->port;
 		}
 
-		remote = fetchXGet(u, &st, "");
+		remote = fetchXGet(u, &st, fetchOpts);
 		if (remote == NULL) {
 			--retry;
 			if (retry <= 0)
@@ -825,7 +826,7 @@ cleanup:
 }
 
 static int
-bootstrap_pkg(bool force)
+bootstrap_pkg(bool force, const char *fetchOpts)
 {
 	int fd_pkg, fd_sig;
 	int ret;
@@ -862,7 +863,7 @@ bootstrap_pkg(bool force)
 	snprintf(tmppkg, MAXPATHLEN, "%s/pkg.txz.XXXXXX",
 	    getenv("TMPDIR") ? getenv("TMPDIR") : _PATH_TMP);
 
-	if ((fd_pkg = fetch_to_fd(url, tmppkg)) == -1)
+	if ((fd_pkg = fetch_to_fd(url, tmppkg, fetchOpts)) == -1)
 		goto fetchfail;
 
 	if (signature_type != NULL &&
@@ -874,7 +875,7 @@ bootstrap_pkg(bool force)
 			snprintf(url, MAXPATHLEN, "%s/Latest/pkg.txz.sig",
 			    packagesite);
 
-			if ((fd_sig = fetch_to_fd(url, tmpsig)) == -1) {
+			if ((fd_sig = fetch_to_fd(url, tmpsig, fetchOpts)) == -1) {
 				fprintf(stderr, "Signature for pkg not "
 				    "available.\n");
 				goto fetchfail;
@@ -890,7 +891,7 @@ bootstrap_pkg(bool force)
 			snprintf(url, MAXPATHLEN, "%s/Latest/pkg.txz.pubkeysig",
 			    packagesite);
 
-			if ((fd_sig = fetch_to_fd(url, tmpsig)) == -1) {
+			if ((fd_sig = fetch_to_fd(url, tmpsig, fetchOpts)) == -1) {
 				fprintf(stderr, "Signature for pkg not "
 				    "available.\n");
 				goto fetchfail;
@@ -945,6 +946,14 @@ static const char non_interactive_message[] =
 "Please set ASSUME_ALWAYS_YES=yes environment variable to be able to bootstrap "
 "in non-interactive (stdin not being a tty)\n";
 
+static const char args_bootstrap_message[] =
+"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.txz}\n";
+
 static int
 pkg_query_yes_no(void)
 {
@@ -1034,28 +1043,75 @@ main(int argc, char *argv[])
 {
 	char pkgpath[MAXPATHLEN];
 	const char *pkgarg;
-	int i;
-	bool bootstrap_only, force, yes;
+	bool activation_test, add_pkg, bootstrap_only, force, yes;
+	signed char ch;
+	const char *fetchOpts;
+	char *command;
 
+	activation_test = false;
+	add_pkg = false;
 	bootstrap_only = false;
+	command = NULL;
+	fetchOpts = "";
 	force = false;
 	pkgarg = NULL;
 	yes = false;
 
+	struct option longopts[] = {
+		{ "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",
 	    getenv("LOCALBASE") ? getenv("LOCALBASE") : _LOCALBASE);
 
-	if (argc > 1 && strcmp(argv[1], "bootstrap") == 0) {
-		bootstrap_only = true;
-		if (argc > 3) {
-			fprintf(stderr, "Too many arguments\nUsage: pkg bootstrap [-f]\n");
-			exit(EXIT_FAILURE);
-		}
-		if (argc == 3 && strcmp(argv[2], "-f") == 0) {
+	while ((ch = getopt_long(argc, argv, "-:fyN46", longopts, NULL)) != -1) {
+		switch (ch) {
+		case 'f':
 			force = true;
-		} else if (argc == 3) {
-			fprintf(stderr, "Invalid argument specified\nUsage: pkg bootstrap [-f]\n");
-			exit(EXIT_FAILURE);
+			break;
+		case 'N':
+			activation_test = true;
+			break;
+		case 'y':
+			yes = true;
+			break;
+		case '4':
+			fetchOpts = "4";
+			break;
+		case '6':
+			fetchOpts = "6";
+			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;
+				}
+			}
+			// bootstrap doesn't accept other arguments
+			else if (bootstrap_only) {
+				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);
+			}
+			else if (add_pkg) {
+				pkgarg = argv[optind-1];
+			}
+			break;
+		default:
+			break;
 		}
 	}
 
@@ -1063,19 +1119,14 @@ main(int argc, char *argv[])
 		/* 
 		 * To allow 'pkg -N' to be used as a reliable test for whether
 		 * a system is configured to use pkg, don't bootstrap pkg
-		 * when that argument is given as argv[1].
+		 * when that that option is passed.
 		 */
-		if (argv[1] != NULL && strcmp(argv[1], "-N") == 0)
+		if (activation_test)
 			errx(EXIT_FAILURE, "pkg is not installed");
 
 		config_init();
 
-		if (argc > 1 && strcmp(argv[1], "add") == 0) {
-			if (argc > 2 && strcmp(argv[2], "-f") == 0) {
-				force = true;
-				pkgarg = argv[3];
-			} else
-				pkgarg = argv[2];
+		if (add_pkg) {
 			if (pkgarg == NULL) {
 				fprintf(stderr, "Path to pkg.txz required\n");
 				exit(EXIT_FAILURE);
@@ -1093,16 +1144,8 @@ main(int argc, char *argv[])
 		 * not tty. Check the environment to see if user has answer
 		 * tucked in there already.
 		 */
-		config_bool(ASSUME_ALWAYS_YES, &yes);
-		if (!yes) {
-			for (i = 1; i < argc; i++) {
-				if (strcmp(argv[i], "-y") == 0 ||
-				    strcmp(argv[i], "--yes") == 0) {
-					yes = true;
-					break;
-				}
-			}
-		}
+		if (!yes)
+			config_bool(ASSUME_ALWAYS_YES, &yes);
 		if (!yes) {
 			if (!isatty(fileno(stdin))) {
 				fprintf(stderr, non_interactive_message);
@@ -1113,7 +1156,7 @@ main(int argc, char *argv[])
 			if (pkg_query_yes_no() == 0)
 				exit(EXIT_FAILURE);
 		}
-		if (bootstrap_pkg(force) != 0)
+		if (bootstrap_pkg(force, fetchOpts) != 0)
 			exit(EXIT_FAILURE);
 		config_finish();
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202105050825.1458PSCw028780>