The following commit has been merged in the master branch: commit 1c1c2f7dc4b191f665f7cf7d8f70e7b66f942212 Author: Guillem Jover <guil...@debian.org> Date: Tue Nov 15 21:59:17 2011 +0100
libdpkg: Add new dpkg_arch database interface The arch database will store all known architectures in the file «/var/lib/dpkg/arch», this includes the native architecture dpkg was built for, and all registered foreign architectures. diff --git a/lib/dpkg/arch.c b/lib/dpkg/arch.c index 9a9c56c..856158f 100644 --- a/lib/dpkg/arch.c +++ b/lib/dpkg/arch.c @@ -24,15 +24,23 @@ #include <compat.h> #include <assert.h> +#include <limits.h> #include <ctype.h> #include <string.h> +#include <stdbool.h> +#include <stdlib.h> +#include <stdio.h> #include <dpkg/i18n.h> #include <dpkg/ehandle.h> +#include <dpkg/dpkg.h> #include <dpkg/dpkg-db.h> +#include <dpkg/dir.h> #include <dpkg/varbuf.h> #include <dpkg/arch.h> +#define DPKG_DB_ARCH_FILE "arch" + /** * Verify if the architecture name is valid. * @@ -98,6 +106,7 @@ static struct dpkg_arch arch_item_native = { }; static struct dpkg_arch *arch_head = &arch_item_native; static struct dpkg_arch *arch_builtin_tail = &arch_item_any; +static bool arch_list_dirty; static struct dpkg_arch * dpkg_arch_new(const char *name, enum dpkg_arch_type type) @@ -202,6 +211,7 @@ void dpkg_arch_reset_list(void) { arch_builtin_tail->next = NULL; + arch_list_dirty = false; } void @@ -213,3 +223,100 @@ varbuf_add_archqual(struct varbuf *vb, const struct dpkg_arch *arch) varbuf_add_char(vb, ':'); varbuf_add_str(vb, arch->name); } + +/** + * Add a new foreign dpkg_arch architecture. + */ +struct dpkg_arch * +dpkg_arch_add(const char *name) +{ + struct dpkg_arch *arch; + + arch = dpkg_arch_find(name); + if (arch->type == arch_unknown) { + arch->type = arch_foreign; + arch_list_dirty = true; + } + + return arch; +} + +/** + * Remove a foreign dpkg_arch architecture. + */ +void +dpkg_arch_remove(struct dpkg_arch *arch_remove) +{ + struct dpkg_arch *arch; + + for (arch = arch_builtin_tail; arch->next; arch = arch->next) { + if (arch->next->type != arch_foreign) + continue; + + if (arch->next == arch_remove) { + arch->next = arch->next->next; + arch_list_dirty = true; + } + } +} + +/** + * Load the architecture database. + */ +void +dpkg_arch_load_list(void) +{ + FILE *fp; + char *archfile; + char archname[_POSIX2_LINE_MAX]; + + archfile = dpkg_db_get_path(DPKG_DB_ARCH_FILE); + fp = fopen(archfile, "r"); + free(archfile); + if (fp == NULL) { + arch_list_dirty = true; + return; + } + + while (fgets_checked(archname, sizeof(archname), fp, archfile) >= 0) + dpkg_arch_add(archname); + + fclose(fp); +} + +/** + * Save the architecture database. + */ +void +dpkg_arch_save_list(void) +{ + struct atomic_file *file; + struct dpkg_arch *arch; + char *archfile; + + if (!arch_list_dirty) + return; + + archfile = dpkg_db_get_path(DPKG_DB_ARCH_FILE); + file = atomic_file_new(archfile, 0); + atomic_file_open(file); + + for (arch = arch_head; arch; arch = arch->next) { + if (arch->type != arch_foreign && arch->type != arch_native) + continue; + + if (fprintf(file->fp, "%s\n", arch->name) < 0) + ohshite(_("error writing to architecture list")); + } + + atomic_file_sync(file); + atomic_file_close(file); + atomic_file_commit(file); + atomic_file_free(file); + + dir_sync_path(dpkg_db_get_dir()); + + arch_list_dirty = false; + + free(archfile); +} diff --git a/lib/dpkg/arch.h b/lib/dpkg/arch.h index fbb9268..23f532e 100644 --- a/lib/dpkg/arch.h +++ b/lib/dpkg/arch.h @@ -51,6 +51,11 @@ struct dpkg_arch *dpkg_arch_get(enum dpkg_arch_type type); struct dpkg_arch *dpkg_arch_get_list(void); void dpkg_arch_reset_list(void); +struct dpkg_arch *dpkg_arch_add(const char *name); +void dpkg_arch_remove(struct dpkg_arch *arch); +void dpkg_arch_load_list(void); +void dpkg_arch_save_list(void); + void varbuf_add_archqual(struct varbuf *vb, const struct dpkg_arch *arch); DPKG_END_DECLS diff --git a/lib/dpkg/libdpkg.map b/lib/dpkg/libdpkg.map index 41d3ad5..9f80069 100644 --- a/lib/dpkg/libdpkg.map +++ b/lib/dpkg/libdpkg.map @@ -191,6 +191,10 @@ LIBDPKG_PRIVATE { dpkg_arch_get; dpkg_arch_get_list; dpkg_arch_reset_list; + dpkg_arch_add; + dpkg_arch_remove; + dpkg_arch_load_list; + dpkg_arch_save_list; # Package struct handling pkg_blank; -- 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