Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F162716223
D58165.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
8 KB
Referenced Files
None
Subscribers
None
D58165.diff
View Options
diff --git a/usr.sbin/pkg/Makefile b/usr.sbin/pkg/Makefile
--- a/usr.sbin/pkg/Makefile
+++ b/usr.sbin/pkg/Makefile
@@ -27,7 +27,7 @@
CFLAGS+=-I${SRCTOP}/contrib/libucl/include
.PATH: ${SRCTOP}/contrib/libucl/include
-LIBADD= archive der fetch pkgecc ucl crypto ssl util md
+LIBADD= archive der fetch jail pkgecc ucl crypto ssl util md
CFLAGS+=-I${SRCTOP}/contrib/libder/libder
CFLAGS+=-I${SRCTOP}/crypto/libecc/include
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 13, 2026
.Dt PKG 7
.Os
.Sh NAME
@@ -31,17 +31,25 @@
.Sh SYNOPSIS
.Nm
.Op Fl d
+.Op Fl j Ar jail
+.Op Fl r Ar rootdir
.Ar command ...
.Nm
.Op Fl d
+.Op Fl j Ar jail
+.Op Fl r Ar rootdir
.Cm add
.Op Fl fy
.Op Fl r Ar reponame
.Ar pkg.pkg
.Nm
+.Op Fl j Ar jail
+.Op Fl r Ar rootdir
.Fl N
.Nm
.Op Fl 46d
+.Op Fl j Ar jail
+.Op Fl r Ar rootdir
.Cm bootstrap
.Op Fl fy
.Op Fl r Ar reponame
@@ -61,14 +69,14 @@
.Xr pkg 8
from a remote repository.
.Bl -tag
-.It Nm Ar command ...
+.It Nm Oo Fl j Ar jail Oc 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 j Ar jail Oc 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 +96,13 @@
.Ar reponame
has been specified, then the signature configuration for that repository will be
used.
-.It Nm Fl N
+.It Nm Oo Fl j Ar jail Oc 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 j Ar jail 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 +139,16 @@
When specified twice,
.Xr fetch 3
debug output is enabled.
+.It Fl j Ar jail , Fl -jail Ar jail
+Attach to the jail designated by the name or numerical identifier
+.Ar jail .
+Note that
+.Nm
+will attach to the jail immediately upon encountering this option, so
+any paths should be relative to the root of the jail.
+.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
@@ -28,8 +28,7 @@
*/
#include <sys/param.h>
-#include <sys/queue.h>
-#include <sys/types.h>
+#include <sys/jail.h>
#include <sys/wait.h>
#include <archive.h>
@@ -41,6 +40,7 @@
#include <fcntl.h>
#include <fetch.h>
#include <getopt.h>
+#include <jail.h>
#include <libutil.h>
#include <paths.h>
#include <stdbool.h>
@@ -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, jid;
const char *fetchOpts;
struct repositories *repositories;
@@ -1093,21 +1137,35 @@
struct option longopts[] = {
{ "debug", no_argument, NULL, 'd' },
+ { "jail", required_argument, NULL, 'j' },
{ "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, "+:djNr:46", longopts, NULL)) != -1) {
switch (ch) {
case 'd':
debug++;
break;
+ case 'j':
+ if ((jid = jail_getid(optarg)) == -1)
+ err(1, "%s", jail_errmsg);
+ if (jail_attach(jid) != 0)
+ err(1, "jail_attach(%s)", optarg);
+ break;
case 'N':
activation_test = true;
break;
+ case 'r':
+ rootdir = optarg;
+ break;
case '4':
fetchOpts = "4";
break;
@@ -1207,7 +1265,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 +1324,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, Jul 17, 2:37 AM (18 h, 4 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
35115117
Default Alt Text
D58165.diff (8 KB)
Attached To
Mode
D58165: pkg: Add support for -r and -j
Attached
Detach File
Event Timeline
Log In to Comment