Hi Guillem,

On Wed, Mar 30, 2016 at 01:29:15AM +0200, Guillem Jover wrote:
> I don't quite like the name, as remote to me implies on some other
> machine. Perhaps foreign, host or extern(al), although some of these
> are a bit overloaded terms already.

Given that I didn't get any further feedback on the name from you, I
left it as is, but I still don't mind you changing it.

> Thanks for the patches! I think 2 and 3 need to be merged together,
> but see my comments on the name and if this deserves to be a force
> option or something else. And they need man page updates.

I am attaching updated patches that address all of these points except
for the renaming.

Helmut
>From 1d6cfda8e2a7ab5dfac3ea32b3ed6d957677fdda Mon Sep 17 00:00:00 2001
From: Helmut Grohne <hel...@subdivi.de>
Date: Mon, 9 Nov 2015 22:07:52 +0100
Subject: [PATCH 1/2] export a variable DPKG_ROOT

This variable holds the value of instdir. It is supposed to be used in
maintainer scripts. It should be prepended to all paths that are
operated on. Currently, dpkg chroots to the instdir before invoking
maintainer scripts, so when it does that DPKG_ROOT is set to the empty
string. Thus currently, DPKG_ROOT is always empty.
---
 man/dpkg.1   | 10 ++++++++++
 src/main.c   |  2 ++
 src/script.c |  2 ++
 3 files changed, 14 insertions(+)

diff --git a/man/dpkg.1 b/man/dpkg.1
index b47c848..86b5160 100644
--- a/man/dpkg.1
+++ b/man/dpkg.1
@@ -866,6 +866,16 @@ Defined by \fBdpkg\fP on the maintainer script environment to a value
 (\(oq\fB0\fP\(cq or \(oq\fB1\fP\(cq) noting whether debugging has been
 requested (with the \fB\-\-debug\fP option) for the maintainer scripts
 (since dpkg 1.18.4).
+.TP
+.B DPKG_ROOT
+Defined by \fBdpkg\fP on the maintainer script environment to indicate
+which installation to act on. The value is supposed to be prepended to
+any path maintainer scripts operate on. During normal operation, this
+variable is empy. When installing packages into a chroot, dpkg
+normally invokes maintainer scripts using chroot and leaves this
+variable empty. Only when installing into a chroot and the package
+being installed declares support for using this variabe, the chroot
+call is skipped and this variable is non-empty (since dpkg 1.18.5).
 .
 .SH FILES
 .TP
diff --git a/src/main.c b/src/main.c
index 0ff04f1..6440e79 100644
--- a/src/main.c
+++ b/src/main.c
@@ -879,6 +879,8 @@ int main(int argc, const char *const *argv) {
   /* Always set environment, to avoid possible security risks. */
   if (setenv("DPKG_ADMINDIR", admindir, 1) < 0)
     ohshite(_("unable to setenv for subprocesses"));
+  if (setenv("DPKG_ROOT", instdir, 1) < 0)
+    ohshite(_("unable to setenv for subprocesses"));
 
   if (!f_triggers)
     f_triggers = (cipaction->arg_int == act_triggers && *argv) ? -1 : 1;
diff --git a/src/script.c b/src/script.c
index d9514da..6bb121e 100644
--- a/src/script.c
+++ b/src/script.c
@@ -105,6 +105,8 @@ maintscript_pre_exec(struct command *cmd)
 			ohshit(_("admindir must be inside instdir for dpkg to work properly"));
 		if (setenv("DPKG_ADMINDIR", admindir + instdirl, 1) < 0)
 			ohshite(_("unable to setenv for subprocesses"));
+		if (setenv("DPKG_ROOT", "", 1) < 0)
+			ohshite(_("unable to setenv for subprocesses"));
 
 		if (chroot(instdir))
 			ohshite(_("failed to chroot to '%.250s'"), instdir);
-- 
2.8.0.rc3

>From 12ab016704b2b8e775f012c301587b49fe2e0701 Mon Sep 17 00:00:00 2001
From: Helmut Grohne <hel...@subdivi.de>
Date: Mon, 9 Nov 2015 22:16:10 +0100
Subject: [PATCH 2/2] add --force-remote-scripts

Currently, dpkg chroots to the instdir before invoking maintainer
scripts. The new force flag is supposed to inhibit the chroot call. The
user is supposed to know that the packages he is operating on do support
this new mode of operation. Thus the force flag is marked as dangerous.
---
 man/dpkg.1   | 4 ++++
 src/main.c   | 3 +++
 src/main.h   | 1 +
 src/script.c | 8 ++++----
 4 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/man/dpkg.1 b/man/dpkg.1
index 86b5160..1e8bc8e 100644
--- a/man/dpkg.1
+++ b/man/dpkg.1
@@ -611,6 +611,10 @@ Try to (de)install things even when not root.
 \fBbad\-verify\fP:
 Install a package even if it fails authenticity check.
 
+\fBremote\-scripts\fP:
+Run maintainer scrips without chroot despite the package not declaring
+support for this mode of operation (since dpkg 1.18.5).
+
 .TP
 \fB\-\-ignore\-depends\fP=\fIpackage\fP,...
 Ignore dependency-checking for specified packages (actually, checking is
diff --git a/src/main.c b/src/main.c
index 6440e79..025b48b 100644
--- a/src/main.c
+++ b/src/main.c
@@ -196,6 +196,7 @@ int fc_conff_ask = 0;
 int fc_unsafe_io = 0;
 int fc_badverify = 0;
 int fc_badversion = 0;
+int fc_remote_scripts = 0;
 
 int errabort = 50;
 static const char *admindir = ADMINDIR;
@@ -275,6 +276,8 @@ static const struct forceinfo {
     '!', N_("Remove packages which require installation") },
   { "remove-essential",    &fc_removeessential,
     '!', N_("Remove an essential package") },
+  { "remote-scripts",      &fc_remote_scripts,
+    '!', N_("Allow running maintainer scripts remotely") },
   { NULL }
 };
 
diff --git a/src/main.h b/src/main.h
index 021d611..972eb65 100644
--- a/src/main.h
+++ b/src/main.h
@@ -142,6 +142,7 @@ extern int fc_conff_ask;
 extern int fc_badverify;
 extern int fc_badversion;
 extern int fc_unsafe_io;
+extern int fc_remote_scripts;
 
 extern bool abort_processing;
 extern int errabort;
diff --git a/src/script.c b/src/script.c
index 6bb121e..1489d92 100644
--- a/src/script.c
+++ b/src/script.c
@@ -100,7 +100,7 @@ maintscript_pre_exec(struct command *cmd)
 	const char *admindir = dpkg_db_get_dir();
 	size_t instdirl = strlen(instdir);
 
-	if (*instdir) {
+	if (*instdir && !fc_remote_scripts) {
 		if (strncmp(admindir, instdir, instdirl) != 0)
 			ohshit(_("admindir must be inside instdir for dpkg to work properly"));
 		if (setenv("DPKG_ADMINDIR", admindir + instdirl, 1) < 0)
@@ -113,8 +113,8 @@ maintscript_pre_exec(struct command *cmd)
 	}
 	/* Switch to a known good directory to give the maintainer script
 	 * a saner environment, also needed after the chroot(). */
-	if (chdir("/"))
-		ohshite(_("failed to chdir to '%.255s'"), "/");
+	if (chdir(fc_remote_scripts ? instdir : "/"))
+		ohshite(_("failed to chdir to '%.255s'"), fc_remote_scripts ? instdir : "/");
 	if (debug_has_flag(dbg_scripts)) {
 		struct varbuf args = VARBUF_INIT;
 		const char **argv = cmd->argv;
@@ -128,7 +128,7 @@ maintscript_pre_exec(struct command *cmd)
 		      args.buf);
 		varbuf_destroy(&args);
 	}
-	if (!instdirl)
+	if (fc_remote_scripts || !instdirl)
 		return cmd->filename;
 
 	assert(strlen(cmd->filename) >= instdirl);
-- 
2.8.0.rc3

Reply via email to