The following commit has been merged in the master branch:
commit 61b3201ddbd1fc5b8683309138d5482c95716f88
Author: Guillem Jover <guil...@debian.org>
Date:   Tue Nov 15 21:59:17 2011 +0100

    dpkg: Switch from foreign arch option to add and remove commands
    
    The --foreign-architecture option is not a good interface, the problem
    with it comes from the fact that the architectures supported by the
    database are not configuration, they are state. This shows up in several
    ways.
    
    When a front-end needs to load the list of architectures, it needs to
    get someone to parse dpkg.cfg files, this is currently done by dpkg
    itself, and the list can be retrieved with --print-foreign-architectures,
    the problem appears when wanting a front-end to load them through libdpkg.
    Making the latter have to execute «dpkg --print-foreign-architectures»
    would be suboptimal, and making libdpkg have to load dpkg.cfg would be
    distasteful. Another issue is that if the list of foreign architectures
    is on the configuration files it makes it slightly more tricky to
    cross-grade dpkg, and it makes it fairly easy to accidentally remove
    architectures required by the database.
    
    Replace the option with two new commands --add-architecture and
    --remove-architecture which will perform sanity checks and store and
    load the architecture list (including the native arch) in an internal
    db file under /var/lib/dpkg/.

diff --git a/lib/dpkg/dbmodify.c b/lib/dpkg/dbmodify.c
index 6981511..8922e46 100644
--- a/lib/dpkg/dbmodify.c
+++ b/lib/dpkg/dbmodify.c
@@ -276,6 +276,8 @@ modstatdb_open(enum modstatdb_rw readwritereq)
     internerr("unknown modstatdb_rw '%d'", readwritereq);
   }
 
+  dpkg_arch_load_list();
+
   if (cstatus != msdbrw_needsuperuserlockonly) {
     cleanupdates();
     if (cflags >= msdbrw_available_readonly)
diff --git a/man/dpkg.1 b/man/dpkg.1
index a01ae42..390a478 100644
--- a/man/dpkg.1
+++ b/man/dpkg.1
@@ -231,6 +231,19 @@ deinstall any packages not in list given to 
\-\-set\-selections.
 Searches for packages selected for installation, but which for some
 reason still haven't been installed.
 .TP
+.B \-\-add\-architecture \fIarchitecture\fP
+Add \fIarchitecture\fP to the list of architectures for which packages can
+be installed without using \fB\-\-force\-architecture\fP. The architecture
+\fBdpkg\fP is built for (i.e. the output of \fB\-\-print\-architecture\fP)
+is always part of that list.
+.TP
+.B \-\-remove\-architecture \fIarchitecture\fP
+Remove \fIarchitecture\fP from the list of architectures for which packages
+can be installed without using \fB\-\-force\-architecture\fP. If the
+architecture is currently in use in the database then the operation will
+be refused, except if \fB\-\-force\-architecture\fP is specified. The
+architecture \fBdpkg\fP is built for (i.e. the output of
+\fB\-\-print\-architecture\fP) can never be removed from that list.
 .TP
 .B \-\-print\-architecture
 Print architecture of packages \fBdpkg\fP installs (for example, "i386").
@@ -572,12 +585,6 @@ each other. Both are processed in the given order, with 
the last rule that
 matches a file name making the decision.
 .RE
 .TP
-.B \-\-foreign\-architecture \fIarchitecture\fP
-Add \fIarchitecture\fP to the list of architectures for which packages can
-be installed without using \fB\-\-force\-architecture\fP, in addition to
-the architecture \fBdpkg\fP is built for (i.e.: the output of
-\fB\-\-print\-architecture\fP).
-.TP
 \fB\-\-status\-fd \fR\fIn\fR
 Send machine-readable package status and progress information to file
 descriptor \fIn\fP. This option can be specified multiple times. The
diff --git a/src/enquiry.c b/src/enquiry.c
index 0eebf11..5b661b5 100644
--- a/src/enquiry.c
+++ b/src/enquiry.c
@@ -484,6 +484,8 @@ print_foreign_arches(const char *const *argv)
   if (*argv)
     badusage(_("--%s takes no arguments"), cipaction->olong);
 
+  dpkg_arch_load_list();
+
   for (arch = dpkg_arch_get_list(); arch; arch = arch->next) {
     if (arch->type != arch_foreign)
       continue;
diff --git a/src/main.c b/src/main.c
index 27924cf..4ed6ee1 100644
--- a/src/main.c
+++ b/src/main.c
@@ -104,6 +104,8 @@ usage(const struct cmdinfo *ci, const char *value)
 "  -l|--list [<pattern> ...]        List packages concisely.\n"
 "  -S|--search <pattern> ...        Find package(s) owning file(s).\n"
 "  -C|--audit                       Check for broken package(s).\n"
+"  --add-architecture <arch>        Add <arch> to the list of architectures.\n"
+"  --remove-architecture <arch>     Remove <arch> from the list of 
architectures.\n"
 "  --print-architecture             Print dpkg architecture.\n"
 "  --print-foreign-architectures    Print allowed foreign architectures.\n"
 "  --compare-versions <a> <op> <b>  Compare version numbers - see below.\n"
@@ -133,8 +135,6 @@ usage(const struct cmdinfo *ci, const char *value)
 "  --instdir=<directory>      Change installation dir without changing admin 
dir.\n"
 "  --path-exclude=<pattern>   Do not install paths which match a shell 
pattern.\n"
 "  --path-include=<pattern>   Re-include a pattern after a previous 
exclusion.\n"
-"  --foreign-architecture=<arch>\n"
-"                             Add <arch> to the list of foreign 
architectures.\n"
 "  -O|--selected-only         Skip packages not selected for 
install/upgrade.\n"
 "  -E|--skip-same-version     Skip packages whose same version is installed.\n"
 "  -G|--refuse-downgrade      Skip packages with earlier version than 
installed.\n"
@@ -473,22 +473,74 @@ run_status_loggers(struct invoke_hook *hook_head)
   }
 }
 
-static void
-set_foreign_arch(const struct cmdinfo *cip, const char *value)
+static int
+arch_add(const char *const *argv)
 {
   struct dpkg_arch *arch;
+  const char *archname = *argv++;
+
+  if (archname == NULL)
+    badusage(_("--%s takes one argument"), cipaction->olong);
+
+  dpkg_arch_load_list();
+
+  arch = dpkg_arch_add(archname);
+  switch (arch->type) {
+  case arch_native:
+  case arch_foreign:
+    break;
+  case arch_illegal:
+    ohshit(_("architecture '%s' is illegal: %s"), archname,
+           dpkg_arch_name_is_illegal(archname));
+  default:
+    ohshit(_("architecture '%s' is reserved and cannot be added"), archname);
+  }
+
+  dpkg_arch_save_list();
+
+  return 0;
+}
+
+static int
+arch_remove(const char *const *argv)
+{
+  const char *archname = *argv++;
+  struct dpkg_arch *arch;
+  struct pkgiterator *iter;
+  struct pkginfo *pkg;
+
+  if (archname == NULL)
+    badusage(_("--%s takes one argument"), cipaction->olong);
+
+  modstatdb_open(msdbrw_readonly);
+
+  arch = dpkg_arch_find(archname);
+  if (arch->type != arch_foreign) {
+    warning(_("cannot remove non-foreign architecture '%s'"), arch->name);
+    return 0;
+  }
+
+  /* Check if it's safe to remove the architecture from the db. */
+  iter = pkg_db_iter_new();
+  while ((pkg = pkg_db_iter_next_pkg(iter))) {
+    if (pkg->installed.arch == arch) {
+      if (fc_architecture)
+        warning(_("removing architecture '%s' currently in use by database"),
+                arch->name);
+      else
+        ohshit(_("cannot remove architecture '%s' currently in use by the 
database"),
+               arch->name);
+      break;
+    }
+  }
+  pkg_db_iter_free(iter);
+
+  dpkg_arch_remove(arch);
+  dpkg_arch_save_list();
+
+  modstatdb_shutdown();
 
-  arch = dpkg_arch_find(value);
-  if (arch->type == arch_foreign)
-    return;
-  else if (arch->type == arch_unknown)
-    arch->type = arch_foreign;
-  else if (arch->type == arch_illegal)
-    warning(_("ignoring option --%s=%s: %s"), cip->olong, value,
-            dpkg_arch_name_is_illegal(value));
-  else
-    warning(_("ignoring option --%s=%s: %s"), cip->olong, value,
-            _("this architecture cannot be foreign"));
+  return 0;
 }
 
 static void setforce(const struct cmdinfo *cip, const char *value) {
@@ -574,6 +626,8 @@ static const struct cmdinfo cmdinfos[]= {
   ACTION( "assert-working-epoch",            0,  act_assertepoch,          
assertepoch     ),
   ACTION( "assert-long-filenames",           0,  act_assertlongfilenames,  
assertlongfilenames ),
   ACTION( "assert-multi-conrep",             0,  act_assertmulticonrep,    
assertmulticonrep ),
+  ACTION( "add-architecture",                0,  act_arch_add,             
arch_add        ),
+  ACTION( "remove-architecture",             0,  act_arch_remove,          
arch_remove     ),
   ACTION( "print-architecture",              0,  act_printarch,            
printarch   ),
   ACTION( "print-installation-architecture", 0,  act_printinstarch,        
printinstarch  ),
   ACTION( "print-foreign-architectures",     0,  act_printforeignarches,   
print_foreign_arches ),
@@ -587,7 +641,6 @@ static const struct cmdinfo cmdinfos[]= {
   { "post-invoke",       0,   1, NULL,          NULL,      set_invoke_hook, 0, 
&post_invoke_hooks_tail },
   { "path-exclude",      0,   1, NULL,          NULL,      setfilter,     0 },
   { "path-include",      0,   1, NULL,          NULL,      setfilter,     1 },
-  { "foreign-architecture", 0, 1, NULL,         NULL,      set_foreign_arch, 0 
},
   { "status-logger",     0,   1, NULL,          NULL,      set_invoke_hook, 0, 
&status_loggers_tail },
   { "status-fd",         0,   1, NULL,          NULL,      setpipe, 0 },
   { "log",               0,   1, NULL,          &log_file, NULL,    0 },
diff --git a/src/main.h b/src/main.h
index c6807be..583dedd 100644
--- a/src/main.h
+++ b/src/main.h
@@ -78,6 +78,8 @@ enum action {
 
        act_cmpversions,
 
+       act_arch_add,
+       act_arch_remove,
        act_printarch,
        act_printinstarch,
        act_printforeignarches,

-- 
dpkg's main repository


-- 
To UNSUBSCRIBE, email to debian-dpkg-cvs-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org

Reply via email to