The following commit has been merged in the master branch:
commit 61b3201ddbd1fc5b8683309138d5482c95716f88
Author: Guillem Jover <[email protected]>
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 [email protected]
with a subject of "unsubscribe". Trouble? Contact [email protected]