Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F177516886
D58165.1794605821.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
7 KB
Referenced Files
None
Subscribers
None
D58165.1794605821.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
@@ -22,7 +22,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd April 29, 2025
+.Dd July 10, 2026
.Dt PKG 7
.Os
.Sh NAME
@@ -31,17 +31,21 @@
.Sh SYNOPSIS
.Nm
.Op Fl d
+.Op Fl r Ar rootdir
.Ar command ...
.Nm
.Op Fl d
+.Op Fl r Ar rootdir
.Cm add
.Op Fl fy
.Op Fl r Ar reponame
.Ar pkg.pkg
.Nm
+.Op Fl r Ar rootdir
.Fl N
.Nm
.Op Fl 46d
+.Op Fl r Ar rootdir
.Cm bootstrap
.Op Fl fy
.Op Fl r Ar reponame
@@ -61,14 +65,14 @@
.Xr pkg 8
from a remote repository.
.Bl -tag
-.It Nm Ar command ...
+.It Nm Oo Fl r Ar rootdir Oc Ar command ...
If
.Xr pkg 8
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 Cm add Oo Fl fy Oc Oo Fl r Ar reponame Oc Ar pkg.pkg
+.It Nm Oo Fl r Ar rootdir Oc Cm add Oo Fl fy Oc Oo Fl r Ar reponame Oc Ar pkg.pkg
Install
.Xr pkg 8
from a local package instead of fetching from remote.
@@ -88,13 +92,13 @@
.Ar reponame
has been specified, then the signature configuration for that repository will be
used.
-.It Nm Fl N
+.It Nm Oo Fl r Ar rootdir Oc 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 Oo Fl 46 Oc Cm bootstrap Oo Fl fy Oc \
+.It Nm Oo Fl 46d Oc Oo Fl r Ar rootdir Oc Cm bootstrap Oo Fl fy Oc \
Oo Fl r Ar reponame Oc
Attempt to bootstrap and do not forward anything to
.Xr pkg 8
@@ -131,6 +135,9 @@
When specified twice,
.Xr fetch 3
debug output is enabled.
+.It Fl r Ar rootdir , Fl -rootdir Ar rootdir
+Operate on the system rooted at
+.Ar rootdir .
.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
--- a/usr.sbin/pkg/pkg.c
+++ b/usr.sbin/pkg/pkg.c
@@ -92,6 +92,8 @@
};
static const char *bootstrap_name = "pkg.pkg";
+static const char *rootdir = NULL;
+static int rootd = -1;
STAILQ_HEAD(fingerprint_list, fingerprint);
@@ -168,7 +170,8 @@
{
struct archive *a;
struct archive_entry *ae;
- char *end;
+ const char *name, *end;
+ char *rname;
int ret, r;
ret = -1;
@@ -192,11 +195,22 @@
ae = NULL;
while ((r = archive_read_next_header(a, &ae)) == ARCHIVE_OK) {
- end = strrchr(archive_entry_pathname(ae), '/');
+ name = archive_entry_pathname(ae);
+ end = strrchr(name, '/');
if (end == NULL)
continue;
if (strcmp(end, "/pkg-static") == 0) {
+ if (rootdir) {
+ if (asprintf(&rname, "%s%s", rootdir, name) < 0)
+ err(1, NULL);
+ archive_entry_copy_pathname(ae, rname);
+ free(rname);
+ }
+ if (debug) {
+ fprintf(stderr, "extracting %s...\n",
+ archive_entry_pathname(ae));
+ }
r = archive_read_extract(a, ae,
ARCHIVE_EXTRACT_OWNER | ARCHIVE_EXTRACT_PERM |
ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_ACL |
@@ -221,28 +235,56 @@
static int
install_pkg_static(const char *path, const char *pkgpath, bool force)
{
+ const char *argv[16];
+ int argc = 0;
int pstat;
pid_t pid;
- switch ((pid = fork())) {
- case -1:
+ /* assemble the command line */
+ argv[argc++] = "pkg-static";
+ if (rootdir) {
+ argv[argc++] = "-r";
+ argv[argc++] = rootdir;
+ }
+ argv[argc++] = "add";
+ if (rootdir) {
+ /*
+ * Installing into an empty directory will normally fail
+ * because none of the shared libraries required by pkg
+ * are present, but pkg-static will still work and can be
+ * used to install a packaged base, so tell pkg-static to
+ * ignore missing dependencies.
+ */
+ argv[argc++] = "-M";
+ }
+ if (force)
+ argv[argc++] = "-f";
+ argv[argc++] = pkgpath;
+ argv[argc] = NULL;
+ assert((size_t)argc < sizeof(argv) / sizeof(*argv));
+
+ if (debug) {
+ fprintf(stderr, "%s", path);
+ for (int i = 1; i < argc; i++)
+ fprintf(stderr, " %s", argv[i]);
+ fprintf(stderr, "\n");
+ }
+
+ /* fork and exec */
+ if ((pid = fork()) < 0)
return (-1);
- case 0:
- if (force)
- execl(path, "pkg-static", "add", "-f", pkgpath,
- (char *)NULL);
- else
- execl(path, "pkg-static", "add", pkgpath,
- (char *)NULL);
+ if (pid == 0) {
+ /* child */
+ execv(path, __DECONST(char **, argv));
_exit(1);
- default:
- break;
}
+ /* wait for pkg-static to complete */
while (waitpid(pid, &pstat, 0) == -1)
if (errno != EINTR)
return (-1);
+ /* check the result */
if (WEXITSTATUS(pstat))
return (WEXITSTATUS(pstat));
else if (WIFSIGNALED(pstat))
@@ -946,7 +988,7 @@
static const char args_bootstrap_message[] =
"Too many arguments\n"
-"Usage: pkg [-4|-6] bootstrap [-f] [-y]\n";
+"Usage: pkg [-46d] [-r rootdir] bootstrap [-f] [-y]\n";
static int
pkg_query_yes_no(void)
@@ -978,7 +1020,7 @@
fd_sig = -1;
ret = -1;
- fd_pkg = open(pkgpath, O_RDONLY);
+ fd_pkg = open(pkgpath, O_RDONLY | O_CLOEXEC);
if (fd_pkg == -1)
err(EXIT_FAILURE, "Unable to open %s", pkgpath);
@@ -992,7 +1034,8 @@
snprintf(path, sizeof(path), "%s.sig", pkgpath);
- if ((fd_sig = open(path, O_RDONLY)) == -1) {
+ fd_sig = open(path, O_RDONLY | O_CLOEXEC);
+ if (fd_sig == -1) {
fprintf(stderr, "Signature for pkg not "
"available.\n");
goto cleanup;
@@ -1005,7 +1048,8 @@
snprintf(path, sizeof(path), "%s.pubkeysig", pkgpath);
- if ((fd_sig = open(path, O_RDONLY)) == -1) {
+ fd_sig = open(path, O_RDONLY | O_CLOEXEC);
+ if (fd_sig == -1) {
fprintf(stderr, "Signature for pkg not "
"available.\n");
goto cleanup;
@@ -1075,9 +1119,9 @@
{
char pkgpath[MAXPATHLEN];
char **original_argv;
- const char *pkgarg, *repo_name;
+ const char *localbase, *pkgarg, *repo_name;
bool activation_test, add_pkg, bootstrap_only, force, yes;
- signed char ch;
+ int ch;
const char *fetchOpts;
struct repositories *repositories;
@@ -1095,12 +1139,16 @@
{ "debug", no_argument, NULL, 'd' },
{ "only-ipv4", no_argument, NULL, '4' },
{ "only-ipv6", no_argument, NULL, '6' },
+ { "rootdir", required_argument, NULL, 'r' },
{ NULL, 0, NULL, 0 },
};
- snprintf(pkgpath, MAXPATHLEN, "%s/sbin/pkg", getlocalbase());
+ localbase = getlocalbase();
+ while (localbase[0] == '/' && localbase[1] == '/')
+ localbase++;
+ snprintf(pkgpath, MAXPATHLEN, "%s/sbin/pkg", localbase);
- while ((ch = getopt_long(argc, argv, "+:dN46", longopts, NULL)) != -1) {
+ while ((ch = getopt_long(argc, argv, "+:dNr:46", longopts, NULL)) != -1) {
switch (ch) {
case 'd':
debug++;
@@ -1108,6 +1156,9 @@
case 'N':
activation_test = true;
break;
+ case 'r':
+ rootdir = optarg;
+ break;
case '4':
fetchOpts = "4";
break;
@@ -1207,7 +1258,14 @@
}
}
- if ((bootstrap_only && force) || access(pkgpath, X_OK) == -1) {
+ if (rootdir) {
+ rootd = open(rootdir, O_DIRECTORY | O_SEARCH | O_CLOEXEC);
+ if (rootd < 0)
+ err(1, "%s", rootdir);
+ }
+
+ if ((bootstrap_only && force) ||
+ faccessat(rootd, pkgpath + 1, X_OK, 0) == -1) {
struct repository *repo;
int ret = 0;
/*
@@ -1259,7 +1317,8 @@
if (bootstrap_only)
exit(EXIT_SUCCESS);
} else if (bootstrap_only) {
- printf("pkg already bootstrapped at %s\n", pkgpath);
+ printf("pkg already bootstrapped at %s%s\n",
+ rootdir ? rootdir : "", pkgpath);
exit(EXIT_SUCCESS);
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Nov 13, 9:37 PM (18 h, 9 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
41709285
Default Alt Text
D58165.1794605821.diff (7 KB)
Attached To
Mode
D58165: pkg: Add -j and -r options
Attached
Detach File
Event Timeline