]> git.ipfire.org Git - thirdparty/openembedded/openembedded-core-contrib.git/commitdiff
dpkg: implement offline mode for update-alternatives
authorAndreas Oberritter <obi@opendreambox.org>
Wed, 27 Aug 2014 15:37:20 +0000 (17:37 +0200)
committerAndreas Oberritter <obi@opendreambox.org>
Thu, 2 Jul 2020 10:15:54 +0000 (12:15 +0200)
Signed-off-by: Andreas Oberritter <obi@opendreambox.org>
meta/recipes-devtools/dpkg/dpkg.inc
meta/recipes-devtools/dpkg/dpkg/0003-Our-pre-postinsts-expect-D-to-be-set-when-running-in.patch [deleted file]
meta/recipes-devtools/dpkg/dpkg/0003-update-alternatives-Implement-offline-mode.patch [new file with mode: 0644]
meta/recipes-devtools/dpkg/dpkg_1.19.7.bb

index 1c3c585d793fb924df8c63f61a976ecc73d9c79b..4412c421fda1f6c4a10282821b4883152b85bf9e 100644 (file)
@@ -1,9 +1,10 @@
 SUMMARY = "Package maintenance system from Debian"
 LICENSE = "GPLv2.0+"
 SECTION = "base"
+PROVIDES = "${@bb.utils.contains('PACKAGECONFIG', 'update-alternatives', 'virtual/update-alternatives', '', d)}"
 
 DEPENDS = "zlib bzip2 perl ncurses"
-DEPENDS_class-native = "bzip2-replacement-native zlib-native virtual/update-alternatives-native gettext-native perl-native"
+DEPENDS_class-native = "bzip2-replacement-native zlib-native ${@bb.utils.contains('PACKAGECONFIG', 'update-alternatives', '', 'virtual/update-alternatives-native', d)} gettext-native perl-native"
 RDEPENDS_${PN} = "${VIRTUAL-RUNTIME_update-alternatives} perl"
 RDEPENDS_${PN}_class-native = ""
 
@@ -16,6 +17,12 @@ PERL_class-native = "${STAGING_BINDIR_NATIVE}/perl-native/perl"
 export PERL_LIBDIR = "${libdir}/perl/${@get_perl_version(d)}"
 PERL_LIBDIR_class-native = "${libdir}/perl-native/perl/${@get_perl_version(d)}"
 
+UA = "update-alternatives"
+UA_native = "${@['', 'update-alternatives'][d.getVar('PREFERRED_PROVIDER_virtual/update-alternatives-native', True) == 'dpkg-native']}"
+
+PACKAGECONFIG ??= "${UA}"
+PACKAGECONFIG[update-alternatives] = "--enable-update-alternatives,--disable-update-alternatives"
+
 EXTRA_OECONF = "\
                --disable-dselect \
                --enable-start-stop-daemon \
@@ -32,22 +39,15 @@ PACKAGECONFIG[liblzma] = "--with-liblzma,--without-liblzma, xz"
 
 do_install_append () {
        if [ "${PN}" = "dpkg-native" ]; then
-               # update-alternatives doesn't have an offline mode
-               rm ${D}${bindir}/update-alternatives
                sed -i -e 's|^#!.*${bindir}/perl-native.*/perl|#!/usr/bin/env nativeperl|' ${D}${bindir}/dpkg-*
        else
                sed -i -e 's|^#!.*${bindir}/perl-native.*/perl|#!/usr/bin/env perl|' ${D}${bindir}/dpkg-*
        fi
 }
 
-PROV = "virtual/update-alternatives"
-PROV_class-native = ""
-
-PROVIDES += "${PROV}"
-
 PACKAGES =+ "update-alternatives-dpkg"
 FILES_update-alternatives-dpkg = "${bindir}/update-alternatives ${localstatedir}/lib/dpkg/alternatives ${sysconfdir}/alternatives"
-RPROVIDES_update-alternatives-dpkg += "update-alternatives"
+RPROVIDES_update-alternatives-dpkg = "update-alternatives"
 
 PACKAGES += "${PN}-perl"
 FILES_${PN}-perl = "${libdir}/perl/${@get_perl_version(d)}"
diff --git a/meta/recipes-devtools/dpkg/dpkg/0003-Our-pre-postinsts-expect-D-to-be-set-when-running-in.patch b/meta/recipes-devtools/dpkg/dpkg/0003-Our-pre-postinsts-expect-D-to-be-set-when-running-in.patch
deleted file mode 100644 (file)
index 9ca7262..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-From dd11ed66640f79143e42d778b58fdd5a61fb5836 Mon Sep 17 00:00:00 2001
-From: Alexander Kanavin <alex.kanavin@gmail.com>
-Date: Wed, 26 Aug 2015 16:25:45 +0300
-Subject: [PATCH] Our pre/postinsts expect $D to be set when running in a
- sysroot and don't expect a chroot. This matches up our system expectations
- with what dpkg does.
-
-Upstream-Status: Inappropriate [OE Specific]
-
-RP 2011/12/07
-ALIMON 2016/05/26
-ALIMON 2017/02/21
-KKang 2019/02/20
----
- src/script.c | 53 +++-------------------------------------------------
- 1 file changed, 3 insertions(+), 50 deletions(-)
-
-diff --git a/src/script.c b/src/script.c
-index abe65b6f7..621ff9b27 100644
---- a/src/script.c
-+++ b/src/script.c
-@@ -96,58 +96,11 @@ setexecute(const char *path, struct stat *stab)
- static const char *
- maintscript_pre_exec(struct command *cmd)
- {
--      const char *admindir = dpkg_db_get_dir();
--      const char *changedir;
--      size_t instdirlen = strlen(instdir);
--
--      if (instdirlen > 0 && in_force(FORCE_SCRIPT_CHROOTLESS))
--              changedir = instdir;
--      else
--              changedir = "/";
--
--      if (instdirlen > 0 && !in_force(FORCE_SCRIPT_CHROOTLESS)) {
--              int rc;
--
--              if (strncmp(admindir, instdir, instdirlen) != 0)
--                      ohshit(_("admindir must be inside instdir for dpkg to work properly"));
--              if (setenv("DPKG_ADMINDIR", admindir + instdirlen, 1) < 0)
--                      ohshite(_("unable to setenv for subprocesses"));
--              if (setenv("DPKG_ROOT", "", 1) < 0)
--                      ohshite(_("unable to setenv for subprocesses"));
--
--              rc = chroot(instdir);
--              if (rc && in_force(FORCE_NON_ROOT) && errno == EPERM)
--                      ohshit(_("not enough privileges to change root "
--                               "directory with --force-not-root, consider "
--                               "using --force-script-chrootless?"));
--              else if (rc)
--                      ohshite(_("failed to chroot to '%.250s'"), instdir);
-+      if (*instdir) {
-+              setenv("D", instdir, 1);
-       }
--      /* Switch to a known good directory to give the maintainer script
--       * a saner environment, also needed after the chroot(). */
--      if (chdir(changedir))
--              ohshite(_("failed to chdir to '%.255s'"), changedir);
--      if (debug_has_flag(dbg_scripts)) {
--              struct varbuf args = VARBUF_INIT;
--              const char **argv = cmd->argv;
--
--              while (*++argv) {
--                      varbuf_add_char(&args, ' ');
--                      varbuf_add_str(&args, *argv);
--              }
--              varbuf_end_str(&args);
--              debug(dbg_scripts, "fork/exec %s (%s )", cmd->filename,
--                    args.buf);
--              varbuf_destroy(&args);
--      }
--      if (instdirlen == 0 || in_force(FORCE_SCRIPT_CHROOTLESS))
--              return cmd->filename;
--
--      if (strlen(cmd->filename) < instdirlen)
--              internerr("maintscript name '%s' length < instdir length %zd",
--                        cmd->filename, instdirlen);
--      return cmd->filename + instdirlen;
-+      return cmd->filename;
- }
- /**
--- 
-2.17.1
-
diff --git a/meta/recipes-devtools/dpkg/dpkg/0003-update-alternatives-Implement-offline-mode.patch b/meta/recipes-devtools/dpkg/dpkg/0003-update-alternatives-Implement-offline-mode.patch
new file mode 100644 (file)
index 0000000..f3aea1f
--- /dev/null
@@ -0,0 +1,263 @@
+From 6989ade07f96e2b232539680fc5822f3702e7bb2 Mon Sep 17 00:00:00 2001
+From: Andreas Oberritter <obi@opendreambox.org>
+Date: Thu, 8 Mar 2018 17:20:48 +0100
+Subject: [PATCH] update-alternatives: Implement offline mode
+
+Let update-alternatives manage symlinks inside a cross-arch root
+filesystem in a directory specified by DPKG_ROOT.
+
+Signed-off-by: Andreas Oberritter <obi@opendreambox.org>
+---
+ utils/Makefile.am           |   1 +
+ utils/update-alternatives.c | 108 +++++++++++++++++++++++++++++++++++++++-----
+ 2 files changed, 97 insertions(+), 12 deletions(-)
+
+diff --git a/utils/Makefile.am b/utils/Makefile.am
+index ed67e94c9..c16a21b1a 100644
+--- a/utils/Makefile.am
++++ b/utils/Makefile.am
+@@ -27,6 +27,7 @@ update_alternatives_SOURCES = \
+ update_alternatives_CPPFLAGS = \
+       -DALT_TMP_EXT=\".dpkg-tmp\" \
+       -DADMINDIR_ENVVAR=\"DPKG_ADMINDIR\" \
++      -DINSTDIR_ENVVAR=\"DPKG_ROOT\" \
+       $(AM_CPPFLAGS)
+ update_alternatives_LDADD = \
+diff --git a/utils/update-alternatives.c b/utils/update-alternatives.c
+index 9a9d10c62..5b398e3f0 100644
+--- a/utils/update-alternatives.c
++++ b/utils/update-alternatives.c
+@@ -51,6 +51,7 @@
+ #define PROGNAME "update-alternatives"
+ static const char *altdir = SYSCONFDIR "/alternatives";
++static const char *instdir;
+ static const char *admdir;
+ static const char *prog_path = "update-alternatives";
+@@ -294,7 +295,7 @@ xasprintf(const char *fmt, ...)
+ }
+ static char *
+-areadlink(const char *linkname)
++_areadlink(const char *linkname)
+ {
+       struct stat st;
+       char *buf;
+@@ -326,6 +327,19 @@ areadlink(const char *linkname)
+       return buf;
+ }
++static char *
++areadlink(const char *linkname)
++{
++      char *instdir_linkname;
++      char *ret;
++
++      instdir_linkname = xasprintf("%s%s", instdir, linkname);
++      ret = _areadlink(instdir_linkname);
++      free(instdir_linkname);
++
++      return ret;
++}
++
+ static char *
+ xreadlink(const char *linkname)
+ {
+@@ -339,7 +353,7 @@ xreadlink(const char *linkname)
+ }
+ static bool
+-pathname_is_missing(const char *pathname)
++_pathname_is_missing(const char *pathname)
+ {
+       struct stat st;
+@@ -353,6 +367,19 @@ pathname_is_missing(const char *pathname)
+       syserr(_("cannot stat file '%s'"), pathname);
+ }
++static bool
++pathname_is_missing(const char *pathname)
++{
++      char *instdir_pathname;
++      bool ret;
++
++      instdir_pathname = xasprintf("%s%s", instdir, pathname);
++      ret = _pathname_is_missing(instdir_pathname);
++      free(instdir_pathname);
++
++      return ret;
++}
++
+ static void
+ set_action(const char *new_action)
+ {
+@@ -362,10 +389,23 @@ set_action(const char *new_action)
+       action = new_action;
+ }
++static const char *
++instdir_init(void)
++{
++      const char *dpkg_instdir;
++
++      dpkg_instdir = getenv(INSTDIR_ENVVAR);
++      if (dpkg_instdir)
++              return dpkg_instdir;
++
++      return "";
++}
++
+ static const char *
+ admindir_init(void)
+ {
+       const char *basedir, *basedir_env;
++      size_t length;
+       /* Try to get the admindir from an environment variable, usually set
+        * by the system package manager. */
+@@ -375,6 +415,12 @@ admindir_init(void)
+       else
+               basedir = ADMINDIR;
++      /* If instdir is set and admindir is below instdir, treat admindir
++       * as relative. */
++      length = strlen(instdir);
++      if (strncmp(basedir, instdir, length) == 0)
++              basedir += length;
++
+       return xasprintf("%s/%s", basedir, "alternatives");
+ }
+@@ -447,25 +493,43 @@ rename_mv(const char *src, const char *dst)
+ static void
+ checked_symlink(const char *filename, const char *linkname)
+ {
+-      if (symlink(filename, linkname))
++      char *instdir_linkname;
++
++      instdir_linkname = xasprintf("%s%s", instdir, linkname);
++
++      if (symlink(filename, instdir_linkname))
+               syserr(_("error creating symbolic link '%.255s'"), linkname);
++
++      free(instdir_linkname);
+ }
+ static void
+ checked_mv(const char *src, const char *dst)
+ {
+-      if (!rename_mv(src, dst))
++      char *instdir_src;
++      char *instdir_dst;
++
++      instdir_src = xasprintf("%s%s", instdir, src);
++      instdir_dst = xasprintf("%s%s", instdir, dst);
++
++      if (!rename_mv(instdir_src, instdir_dst))
+               syserr(_("unable to install '%.250s' as '%.250s'"), src, dst);
++
++      free(instdir_src);
++      free(instdir_dst);
+ }
+ static void
+ checked_rm(const char *f)
+ {
+-      if (!unlink(f))
+-              return;
++      char *instdir_f;
++
++      instdir_f = xasprintf("%s%s", instdir, f);
+-      if (errno != ENOENT)
++      if (unlink(instdir_f) && errno != ENOENT)
+               syserr(_("unable to remove '%s'"), f);
++
++      free(instdir_f);
+ }
+ static void DPKG_ATTR_PRINTF(1)
+@@ -1046,10 +1110,15 @@ static int
+ altdb_get_namelist(struct dirent ***table)
+ {
+       int count;
++      char *instdir_admdir;
++
++      instdir_admdir = xasprintf("%s%s", instdir, admdir);
+-      count = scandir(admdir, table, altdb_filter_namelist, alphasort);
++      count = scandir(instdir_admdir, table, altdb_filter_namelist, alphasort);
+       if (count < 0)
+-              syserr(_("cannot scan directory '%.255s'"), admdir);
++              syserr(_("cannot scan directory '%.255s'"), instdir_admdir);
++
++      free(instdir_admdir);
+       return count;
+ }
+@@ -1255,7 +1324,7 @@ alternative_load(struct alternative *a, enum altdb_flags flags)
+               ctx.bad_format = altdb_parse_stop;
+       else
+               ctx.bad_format = altdb_parse_error;
+-      ctx.filename = xasprintf("%s/%s", admdir, a->master_name);
++      ctx.filename = xasprintf("%s%s/%s", instdir, admdir, a->master_name);
+       /* Open the alternative file. */
+       ctx.fh = fopen(ctx.filename, "r");
+@@ -1349,7 +1418,7 @@ alternative_save(struct alternative *a)
+       file = xasprintf("%s/%s", admdir, a->master_name);
+       filenew = xasprintf("%s" ALT_TMP_EXT, file);
+-      ctx.filename = filenew;
++      ctx.filename = xasprintf("%s%s", instdir, filenew);
+       ctx.fh = fopen(ctx.filename, "w");
+       if (ctx.fh == NULL)
+               syserr(_("unable to create file '%s'"), ctx.filename);
+@@ -1388,6 +1457,7 @@ alternative_save(struct alternative *a)
+               syserr(_("unable to sync file '%s'"), ctx.filename);
+       if (fclose(ctx.fh))
+               syserr(_("unable to close file '%s'"), ctx.filename);
++      free(ctx.filename);
+       /* Put in place atomically. */
+       checked_mv(filenew, file);
+@@ -1681,7 +1751,7 @@ enum alternative_path_status {
+ };
+ static enum alternative_path_status
+-alternative_path_classify(const char *linkname)
++_alternative_path_classify(const char *linkname)
+ {
+       struct stat st;
+@@ -1697,6 +1767,19 @@ alternative_path_classify(const char *linkname)
+       }
+ }
++static enum alternative_path_status
++alternative_path_classify(const char *linkname)
++{
++      enum alternative_path_status ret;
++      char *instdir_linkname;
++
++      instdir_linkname = xasprintf("%s%s", instdir, linkname);
++      ret = _alternative_path_classify(instdir_linkname);
++      free(instdir_linkname);
++
++      return ret;
++}
++
+ static bool
+ alternative_path_can_remove(const char *linkname)
+ {
+@@ -2563,6 +2646,7 @@ main(int argc, char **argv)
+       bindtextdomain(PACKAGE, LOCALEDIR);
+       textdomain(PACKAGE);
++      instdir = instdir_init();
+       admdir = admindir_init();
+       if (setvbuf(stdout, NULL, _IONBF, 0))
index e9dec337b3d154ccbedcff1ff5d37f5876517c8e..9d0476792998598ae9e4185419612b38635a5f26 100644 (file)
@@ -7,7 +7,7 @@ SRC_URI = "${DEBIAN_MIRROR}/main/d/${BPN}/${BPN}_${PV}.tar.xz \
            file://arch_pm.patch \
            file://add_armeb_triplet_entry.patch \
            file://0002-Adapt-to-linux-wrs-kernel-version-which-has-characte.patch \
-           file://0003-Our-pre-postinsts-expect-D-to-be-set-when-running-in.patch \
+           file://0003-update-alternatives-Implement-offline-mode.patch \
            file://0004-The-lutimes-function-doesn-t-work-properly-for-all-s.patch \
            file://0006-add-musleabi-to-known-target-tripets.patch \
            file://0007-dpkg-deb-build.c-Remove-usage-of-clamp-mtime-in-tar.patch \