Force 'captivemodid' checking during any W32 module loading.
authorlace <>
Mon, 26 Dec 2005 14:21:19 +0000 (14:21 +0000)
committerlace <>
Mon, 26 Dec 2005 14:21:19 +0000 (14:21 +0000)
15 files changed:
src/client/cmdline/Makefile.am
src/client/fuse/Makefile.am
src/client/fuse/main.c
src/client/sandbox-server/Makefile.am
src/install/acquire/Makefile.am
src/install/acquire/cabinet.c
src/install/acquire/main.c
src/install/acquire/main.h
src/install/acquire/moduriload.c
src/install/acquire/ui-line.c
src/libcaptive/captivemodid/captivemodid.c
src/libcaptive/client/options-module.c
src/libcaptive/client/options.c
src/libcaptive/include/captive/captivemodid.h
src/libcaptive/include/captive/options.h

index b456c70..72b5053 100644 (file)
@@ -63,8 +63,8 @@ captive_cmdline_SOURCES= \
                main.h \
                utf8.c \
                utf8.h
-captive_cmdline_CFLAGS=                   $(GNOME_VFS_CFLAGS)
-captive_cmdline_LDADD =$(captive_library) $(GNOME_VFS_LIBS)   $(READLINE_LIBS) $(INTLLIBS)
+captive_cmdline_CFLAGS=                   $(GNOME_VFS_CFLAGS) $(LIBXML_CFLAGS) 
+captive_cmdline_LDADD =$(captive_library) $(GNOME_VFS_LIBS)   $(LIBXML_LIBS)   $(READLINE_LIBS) $(INTLLIBS)
 captive_cmdline_LDFLAGS=$(READLINE_LDFLAGS)
 bin_PROGRAMS+=captive-cmdline
 
index 9d673c3..30de43f 100644 (file)
@@ -64,13 +64,14 @@ mount_captive_SOURCES= \
                gnomevfsfileinfo.h \
                main.c \
                main.h
-mount_captive_CFLAGS=                   $(GNOME_VFS_CFLAGS) $(FUSE_CFLAGS)
-mount_captive_LDADD =$(captive_library) $(GNOME_VFS_LIBS)   $(FUSE_LIBS)   $(INTLLIBS)
+mount_captive_CFLAGS=                   $(GNOME_VFS_CFLAGS) $(LIBXML_CFLAGS) $(FUSE_CFLAGS)
+mount_captive_LDADD =$(captive_library) $(GNOME_VFS_LIBS)   $(LIBXML_LIBS)   $(FUSE_LIBS)   $(INTLLIBS)
 mount_captive_LDFLAGS=$(READLINE_LDFLAGS)
 
 mount_captive_CFLAGS+=-DLIBEXECDIR="$(libexecdir)"
 mount_captive_CFLAGS+=-DVARLIBCAPTIVEDIR="$(localstatedir)/lib/$(PACKAGE)"
 
+
 if ENABLE_FUSE
 if ENABLE_SBIN_MOUNT
 mount_captive_cond=mount.captive
index 0935914..b805c71 100644 (file)
@@ -29,6 +29,7 @@
 #include <captive/client-vfs.h>
 #include <captive/macros.h>
 #include <captive/client.h>
+#include <captive/captivemodid.h>
 
 #include "main.h"      /* self */
 #include "op_statfs.h"
@@ -175,8 +176,6 @@ const char *image_filename;
        for (csp=rest_argv,rest_argc=0;csp && *csp;csp++)
                rest_argc++;
 
-       captive_options=NULL;   /* already parsed by 'CAPTIVE_POPT_INCLUDE' */
-
        /* Override the (default) Captive options with mount(8) supplied "-o" argument. */
        /* rest_argv[0] is the device now. */
        /* rest_argv[1] is the mountpoint now. */
@@ -211,6 +210,9 @@ const char *cs=rest_argv[3];
                g_error(_("image_iochannel failed open of: %s"),image_filename);
                return EXIT_FAILURE;
                }
+       
+       if (!options.captivemodid)
+               options.captivemodid=captive_captivemodid_load_default(FALSE);
 
        if (options.filesystem.type==CAPTIVE_OPTIONS_MODULE_TYPE_EMPTY) {
 const char *self_prefix="mount.captive-";
@@ -239,6 +241,9 @@ struct captive_options_module *options_module;
                options.load_module=g_list_append(options.load_module,options_module);
                }
 
+       /* It is still required for: captive_options_module_load() */
+       captive_options=NULL;   /* already parsed by 'CAPTIVE_POPT_INCLUDE' */
+
        if (GNOME_VFS_OK!=captive_vfs_new(&capfuse_captive_vfs_object,&options)) {
                g_error(_("captive_vfs_new() failed"));
                return EXIT_FAILURE;
index f38f296..ac952a9 100644 (file)
@@ -20,8 +20,8 @@ include $(top_srcdir)/Makefile-head.am
 
 captive_sandbox_server_SOURCES= \
                main.c
-captive_sandbox_server_CFLAGS=$(ORBIT_CFLAGS) $(LINC_CFLAGS)
-captive_sandbox_server_LDADD =$(ORBIT_LIBS)   $(LINC_LIBS)   $(captive_library) $(INTLLIBS)
+captive_sandbox_server_CFLAGS=$(ORBIT_CFLAGS) $(LINC_CFLAGS) $(GNOME_VFS_CFLAGS) $(LIBXML_CFLAGS) 
+captive_sandbox_server_LDADD =$(ORBIT_LIBS)   $(LINC_LIBS)   $(GNOME_VFS_LIBS)   $(LIBXML_LIBS)   $(captive_library) $(INTLLIBS)
 libexec_PROGRAMS=captive-sandbox-server
 libexecPROGRAMS_INSTALL=${INSTALL} -o root -g root -m 4755
 EXTRA_DIST+=.gdbinit
index 4e0f4bc..d306a28 100644 (file)
@@ -99,7 +99,6 @@ captive_install_acquire_LDFLAGS=$(READLINE_LDFLAGS)
 captive_install_acquire_CFLAGS+=$(GNOMEUI_CFLAGS)
 captive_install_acquire_LDADD +=$(GNOMEUI_LIBS)
 
-captive_install_acquire_CFLAGS+=-DSYSCONFDIR="$(sysconfdir)"
 captive_install_acquire_CFLAGS+=-DVARLIBCAPTIVEDIR="$(localstatedir)/lib/$(PACKAGE)"
 captive_install_acquire_LDADD+=../libcaptive-install/libcaptive-install.a
 
index fd6263b..3ad56c7 100644 (file)
@@ -400,7 +400,7 @@ gpointer file_buffer;
 GnomeVFSURI *uri_fi;
 int errint;
 
-               if (!captive_captivemodid_module_length_is_valid(fi->length))
+               if (!captive_captivemodid_module_length_is_valid(captivemodid,fi->length))
                        continue;
 
                uri_fi=gnome_vfs_uri_append_file_name(acquire_cabinet->uri,fi->filename);
index a8a2eba..260e821 100644 (file)
 
 #include <captive/macros.h>
 #include <captive/client.h>
+#include <captive/captivemodid.h>
 
 
+CaptiveCaptivemodidObject *captivemodid;
+
 int optarg_verbose;
 int optarg_dry;
 static int optarg_microsoft_com;
 static int optarg_scan_disks;
 static int optarg_scan_disks_quick;
 static int optarg_text;
-static char *optarg_modid_path=G_STRINGIFY(SYSCONFDIR) "/w32-mod-id.captivemodid.xml";
 static GList *optarg_scan_path_list;   /* of (char *) */
 
 static void acquire_popt_callback
@@ -75,8 +77,6 @@ static const struct poptOption popt_table[]={
                                N_("Disable Gnome UI; --text must be first argument"),NULL),
                BUG_ACQUIRE_POPT('v',"verbose"         ,POPT_ARG_NONE  ,&optarg_verbose,0,N_("Display additional debug information"),NULL),
                BUG_ACQUIRE_POPT('n',"dry"             ,POPT_ARG_NONE  ,&optarg_dry    ,0,N_("No modifications, no files written"),NULL),
-               BUG_ACQUIRE_POPT(0  ,"modid-path"      ,POPT_ARG_STRING|POPT_ARGFLAG_SHOW_DEFAULT,&optarg_modid_path,0,
-                               N_("Path to .captivemodid.xml database"),N_("path")),
                BUG_ACQUIRE_POPT(0  ,"scan-disks"      ,POPT_ARG_NONE  ,&optarg_scan_disks,0,N_("Scan all files on local disks"),NULL),
                BUG_ACQUIRE_POPT(0  ,"scan-disks-quick",POPT_ARG_NONE  ,&optarg_scan_disks_quick,0,
                                N_("Scan MS-Windows directories on local disks"),NULL),
@@ -280,8 +280,7 @@ guint handler_id;
                        && !ui_line_init())
                g_error(_("No UI interface could be initialized"));
 
-       if (!captive_captivemodid_load(optarg_modid_path) && !captive_captivemodid_load("./w32-mod-id.captivemodid.xml"))
-               g_error(_("Unable to load modid database: %s"),optarg_modid_path);
+       captivemodid=captive_captivemodid_load_default(TRUE);
 
        mod_uri_load_base_reporting(gnome_vfs_uri_new("file://" G_STRINGIFY(VARLIBCAPTIVEDIR)));
 
index 7c11693..ea221b7 100644 (file)
 
 #include <glib/gtypes.h>
 #include <glib/ghash.h>
+#include <captive/captivemodid.h>
 
 
 G_BEGIN_DECLS
 
+extern CaptiveCaptivemodidObject *captivemodid;
 extern gboolean optarg_verbose;
 extern gboolean optarg_dry;
 extern void (*ui_interactive)(void);
index 4500716..dbc86fe 100644 (file)
@@ -109,10 +109,10 @@ int dest_fd;
 
        all_modules_found=FALSE;
 
-       best_priority=captive_captivemodid_module_type_best_priority_lookup(module->type);
+       best_priority=captive_captivemodid_module_type_best_priority_lookup(captivemodid,module->type);
        if (best_priority==G_MININT     /* no longer seeking for such module */
                        || module_available->module->priority==best_priority) {
-               if (captive_captivemodid_module_type_best_priority_found(module->type)) {
+               if (captive_captivemodid_module_type_best_priority_found(captivemodid,module->type)) {
                        /* Postpone (*acquire_module_all_modules_found_notify)()
                         * after (*acquire_module_available_notify)().
                         */
@@ -139,7 +139,7 @@ struct captive_captivemodid_module *module;
                return;
 
        file_md5=captive_calc_md5(file_base,file_length);
-       if (!(module=captive_captivemodid_module_md5_lookup(file_md5)))
+       if (!(module=captive_captivemodid_module_md5_lookup(captivemodid,file_md5)))
                goto fail_free_file_md5;
 
        if (strcmp("cabinet",(const char *)module->type))
@@ -239,14 +239,14 @@ GnomeVFSHandle *handle;
                errvfsresult=GNOME_VFS_ERROR_WRONG_FORMAT;
                goto fail_file_info_local_clear;
                }
-       if (!captive_captivemodid_module_length_is_valid(file_info_local.size)) {
+       if (!captive_captivemodid_module_length_is_valid(captivemodid,file_info_local.size)) {
                errvfsresult=GNOME_VFS_ERROR_WRONG_FORMAT;
                goto fail_file_info_local_clear;
                }
        if (file_info_local.size<=MAX_FILE_LOAD_LENGTH)
                mod_uri_load_file_handle_to_memory(handle,&file_info_local,uri);
        else {
-gint cabinet_used=captive_captivemodid_cabinet_length_to_used(file_info_local.size);
+gint cabinet_used=captive_captivemodid_cabinet_length_to_used(captivemodid,file_info_local.size);
 
                mod_uri_load_file_handle_remote_cabinet(&handle,&file_info_local,uri,cabinet_used);
                }
index 999a1ec..1177fb1 100644 (file)
@@ -44,7 +44,8 @@ gint priority_best;
        g_return_if_fail(module_available!=NULL);
        g_return_if_fail(module_available->module!=NULL);
 
-       if (G_MININT==(priority_best=captive_captivemodid_module_type_best_priority_lookup(module_available->module->type)))
+       if (G_MININT==(priority_best=captive_captivemodid_module_type_best_priority_lookup(
+                       captivemodid,module_available->module->type)))
                printf(_("Found best available \"%s\": %s\n"),module_available->module->type,module_available->module->id);
        else
                printf(_("Found although not best \"%s\" (pri=%d; best=%d): %s\n"),
index 8aceea4..3344896 100644 (file)
 #include <ctype.h>
 
 
-gchar *captive_calc_md5(gconstpointer base,size_t length)
+struct _CaptiveCaptivemodidObject {
+       GObject parent_instance;
+
+       /* map: GINT_TO_POINTER(captive_captivemodid_module.length) -> !=NULL */
+       /* No allocations needed. */
+       GHashTable *module_valid_length_hash;
+
+       /* map: (const xmlChar *)md5 -> (struct captive_captivemodid_module *) */
+       /* 'key' is not allocated it is shared with: 'val'->md5 */
+       /* 'val' is allocated, to be automatically freed by: captive_captivemodid_module_free() */
+       GHashTable *module_md5_hash;
+
+       /* map: (const xmlChar *)type -> (gpointer)GINT_TO_POINTER(priority) */
+       /* We remove entry for module with already the best priority found,
+        * therefore captive_captivemodid_module_type_best_priority_lookup() will return
+        * 'G_MININT' afterwards.
+        * 'key' is not allocated - it is shared with: module_md5_hash */
+       /* No allocations needed. */
+       GHashTable *module_type_best_priority_hash;
+
+       /* g_strdup()ped */
+       gchar *pathname_loaded;
+       };
+struct _CaptiveCaptivemodidObjectClass {
+       GObjectClass parent_class;
+       };
+
+
+static gpointer captive_captivemodid_object_parent_class=NULL;
+
+
+static void captive_captivemodid_object_finalize(CaptiveCaptivemodidObject *captive_captivemodid_object)
 {
-unsigned char md5_bin[1+128/8];        /* 128 bits==16 bytes; '1+' for leading stub to prevent shorter output of BN_bn2hex() */
-BIGNUM *bignum;
-char *hex;
-gchar *r,*gs;
+       g_return_if_fail(captive_captivemodid_object!=NULL);
 
-       /* already done above */
-       /* Calculate MD5 sum and convert it to hex string: */
-       MD5(base,length,md5_bin+1);
-       md5_bin[0]=0xFF;  /* stub to prevent shorter output of BN_bn2hex() */
-       bignum=BN_bin2bn(md5_bin,1+128/8,NULL);
-       hex=BN_bn2hex(bignum);
-       g_assert(strlen(hex)==2*(1+128/8));
-       r=g_strdup(hex+2);
-       OPENSSL_free(hex);
-       BN_free(bignum);
+       g_hash_table_destroy(captive_captivemodid_object->module_valid_length_hash);
+       g_hash_table_destroy(captive_captivemodid_object->module_md5_hash);
+       g_hash_table_destroy(captive_captivemodid_object->module_type_best_priority_hash);
+       g_free(captive_captivemodid_object->pathname_loaded);
 
-       g_assert(strlen(r)==32);
-       for (gs=r;*gs;gs++) {
-               g_assert(isxdigit(*gs));
-               *gs=tolower(*gs);
-               g_assert(isxdigit(*gs));
-               }
-       return r;
+       G_OBJECT_CLASS(captive_captivemodid_object_parent_class)->finalize((GObject *)captive_captivemodid_object);
 }
 
 
-/* map: GINT_TO_POINTER(captive_captivemodid_module.length) -> !=NULL */
-static GHashTable *module_valid_length_hash;
-
-static void module_valid_length_hash_init(void)
+static void captive_captivemodid_object_class_init(CaptiveCaptivemodidObjectClass *class)
 {
-       if (module_valid_length_hash)
-               return;
-       module_valid_length_hash=g_hash_table_new(g_direct_hash,g_direct_equal);
+GObjectClass *gobject_class=G_OBJECT_CLASS(class);
+
+       captive_captivemodid_object_parent_class=g_type_class_ref(g_type_parent(G_TYPE_FROM_CLASS(class)));
+       gobject_class->finalize=(void (*)(GObject *object))captive_captivemodid_object_finalize;
 }
 
-/* map: (const xmlChar *)md5 -> (struct captive_captivemodid_module *) */
-static GHashTable *module_md5_hash;
 
-static void module_md5_hash_init(void)
+static void captive_captivemodid_module_free(struct captive_captivemodid_module *module)
 {
-       if (module_md5_hash)
-               return;
-       module_md5_hash=g_hash_table_new(g_str_hash,g_str_equal);
+       xmlFree((xmlChar *)module->type);
+       xmlFree((xmlChar *)module->md5);
+       xmlFree((xmlChar *)module->id);
+       g_free(module);
 }
 
-/* map: (const xmlChar *)type -> (gpointer)GINT_TO_POINTER(priority) */
-/* We remove entry for module with already the best priority found,
- * therefore captive_captivemodid_module_type_best_priority_lookup() will return
- * 'G_MININT' afterwards.
- */
-static GHashTable *module_type_best_priority_hash;
+static void captive_captivemodid_object_init(CaptiveCaptivemodidObject *captive_captivemodid_object)
+{
+       captive_captivemodid_object->module_valid_length_hash=g_hash_table_new(g_direct_hash,g_direct_equal);
+       captive_captivemodid_object->module_md5_hash=g_hash_table_new_full(g_str_hash,g_str_equal,
+                       NULL,   /* key_destroy_func */
+                       (GDestroyNotify)captive_captivemodid_module_free);      /* value_destroy_func */
+       captive_captivemodid_object->module_type_best_priority_hash=g_hash_table_new(g_str_hash,g_str_equal);
+}
 
-static void module_type_best_priority_hash_init(void)
+
+GType captive_captivemodid_object_get_type(void)
 {
-       if (module_type_best_priority_hash)
-               return;
-       module_type_best_priority_hash=g_hash_table_new(g_str_hash,g_str_equal);
+static GType captive_captivemodid_object_type=0;
+
+       if (!captive_captivemodid_object_type) {
+static const GTypeInfo captive_captivemodid_object_info={
+                               sizeof(CaptiveCaptivemodidObjectClass),
+                               NULL,   /* base_init */
+                               NULL,   /* base_finalize */
+                               (GClassInitFunc)captive_captivemodid_object_class_init,
+                               NULL,   /* class_finalize */
+                               NULL,   /* class_data */
+                               sizeof(CaptiveCaptivemodidObject),
+                               5,      /* n_preallocs */
+                               (GInstanceInitFunc)captive_captivemodid_object_init,
+                               };
+
+               captive_captivemodid_object_type=g_type_register_static(G_TYPE_OBJECT,
+                               "CaptiveCaptivemodidObject",&captive_captivemodid_object_info,0);
+               }
+
+       return captive_captivemodid_object_type;
 }
 
-static void captive_captivemodid_load_module(struct captive_captivemodid_module *module)
+
+static void captive_captivemodid_load_module
+               (CaptiveCaptivemodidObject *captivemodid,struct captive_captivemodid_module *module)
 {
 struct captive_captivemodid_module *module_md5_conflict;
 gpointer valid_length_value_gpointer;
 
-       module_md5_hash_init();
-       if ((module_md5_conflict=g_hash_table_lookup(module_md5_hash,module->md5))) {
+       if ((module_md5_conflict=g_hash_table_lookup(captivemodid->module_md5_hash,module->md5))) {
                g_warning(_("Ignoring module \"%s\" as it has MD5 conflict with: %s"),
                                module->id,module_md5_conflict->id);
                return;
                }
-       g_hash_table_insert(module_md5_hash,(/* de-const */ xmlChar *)module->md5,module);
+       g_hash_table_insert(captivemodid->module_md5_hash,(/* de-const */ xmlChar *)module->md5,module);
 
-       module_valid_length_hash_init();
-       if (!g_hash_table_lookup_extended(module_valid_length_hash,GINT_TO_POINTER(module->length),
+       if (!g_hash_table_lookup_extended(captivemodid->module_valid_length_hash,GINT_TO_POINTER(module->length),
                        NULL,   /* orig_key */
                        &valid_length_value_gpointer))  /* value */
-               g_hash_table_insert(module_valid_length_hash,GINT_TO_POINTER(module->length),GINT_TO_POINTER(module->cabinet_used));
+               g_hash_table_insert(captivemodid->module_valid_length_hash,
+                               GINT_TO_POINTER(module->length),GINT_TO_POINTER(module->cabinet_used));
        else {
                /* Conflicting 'cabinet_used' values for single 'cabinet size'? */
                if (valid_length_value_gpointer && GPOINTER_TO_INT(valid_length_value_gpointer)!=module->cabinet_used)
-                       g_hash_table_insert(module_valid_length_hash,GINT_TO_POINTER(module->length),NULL);
+                       g_hash_table_insert(captivemodid->module_valid_length_hash,GINT_TO_POINTER(module->length),NULL);
                }
 
        if (strcmp((const char *)module->type,"cabinet")) {
-               if (module->priority>captive_captivemodid_module_type_best_priority_lookup(module->type)) {
-                       module_type_best_priority_hash_init();
-                       g_hash_table_insert(module_type_best_priority_hash,
+               if (module->priority>captive_captivemodid_module_type_best_priority_lookup(captivemodid,module->type)) {
+                       g_hash_table_insert(captivemodid->module_type_best_priority_hash,
                                        (/* de-const */ xmlChar *)module->type,GINT_TO_POINTER(module->priority));
                        }
                }
 }
 
-gboolean captive_captivemodid_module_length_is_valid(GnomeVFSFileSize file_size)
+gboolean captive_captivemodid_module_length_is_valid(CaptiveCaptivemodidObject *captivemodid,GnomeVFSFileSize file_size)
 {
 gint file_size_gint;
 
        if ((GnomeVFSFileSize)(file_size_gint=file_size)!=file_size)    /* Size too big to be valid. */
                return FALSE;
-       module_valid_length_hash_init();
-       return g_hash_table_lookup_extended(module_valid_length_hash,GINT_TO_POINTER(file_size_gint),
+       return g_hash_table_lookup_extended(captivemodid->module_valid_length_hash,GINT_TO_POINTER(file_size_gint),
                        NULL,   /* orig_key */
                        NULL);  /* value */
 }
 
-gint captive_captivemodid_cabinet_length_to_used(gint cabinet_length)
+gint captive_captivemodid_cabinet_length_to_used(CaptiveCaptivemodidObject *captivemodid,gint cabinet_length)
 {
 gpointer valid_length_value_gpointer;
 
-       if (!g_hash_table_lookup_extended(module_valid_length_hash,GINT_TO_POINTER(cabinet_length),
+       if (!g_hash_table_lookup_extended(captivemodid->module_valid_length_hash,GINT_TO_POINTER(cabinet_length),
                        NULL,   /* orig_key */
                        &valid_length_value_gpointer))  /* value */
                return 0;
        return GPOINTER_TO_INT(valid_length_value_gpointer);
 }
 
-struct captive_captivemodid_module *captive_captivemodid_module_md5_lookup(const gchar *file_md5)
+struct captive_captivemodid_module *captive_captivemodid_module_md5_lookup
+               (CaptiveCaptivemodidObject *captivemodid,const gchar *file_md5)
 {
        g_return_val_if_fail(file_md5!=NULL,NULL);
 
-       module_md5_hash_init();
-       return g_hash_table_lookup(module_md5_hash,file_md5);
+       return g_hash_table_lookup(captivemodid->module_md5_hash,file_md5);
 }
 
-gint captive_captivemodid_module_type_best_priority_lookup(const xmlChar *module_type)
+gint captive_captivemodid_module_type_best_priority_lookup(CaptiveCaptivemodidObject *captivemodid,const xmlChar *module_type)
 {
 gpointer r_gpointer;
 gboolean errbool;
 
        g_return_val_if_fail(module_type!=NULL,G_MININT);
 
-       module_type_best_priority_hash_init();
-       errbool=g_hash_table_lookup_extended(module_type_best_priority_hash,
+       errbool=g_hash_table_lookup_extended(captivemodid->module_type_best_priority_hash,
                        module_type,    /* lookup_key */
                        NULL,   /* orig_key */
                        &r_gpointer);   /* value */
@@ -180,17 +211,17 @@ gboolean errbool;
 }
 
 /* Returns: TRUE if all modules were found. */
-gboolean captive_captivemodid_module_type_best_priority_found(const xmlChar *module_type)
+gboolean captive_captivemodid_module_type_best_priority_found
+               (CaptiveCaptivemodidObject *captivemodid,const xmlChar *module_type)
 {
 gboolean errbool;
 
        g_return_val_if_fail(module_type!=NULL,FALSE);
 
-       module_type_best_priority_hash_init();
-       errbool=g_hash_table_remove(module_type_best_priority_hash,module_type);
+       errbool=g_hash_table_remove(captivemodid->module_type_best_priority_hash,module_type);
        g_assert(errbool==TRUE);
 
-       return !g_hash_table_size(module_type_best_priority_hash);
+       return !g_hash_table_size(captivemodid->module_type_best_priority_hash);
 }
 
 static xmlChar *captive_captivemodid_load_module_xml_get_attr
@@ -229,7 +260,8 @@ char *ends;
        return r;
 }
 
-static void captive_captivemodid_load_module_xml(const gchar *captive_captivemodid_pathname,xmlTextReader *xml_reader)
+static void captive_captivemodid_load_module_xml
+               (CaptiveCaptivemodidObject *captivemodid,const gchar *captive_captivemodid_pathname,xmlTextReader *xml_reader)
 {
 struct captive_captivemodid_module *module;
 xmlChar *cabinet_used_string;
@@ -263,14 +295,11 @@ xmlChar *cabinet_used_string;
        if (G_MININT>=(module->priority=captive_captivemodid_load_module_xml_get_attr_l(captive_captivemodid_pathname,xml_reader,"priority",
                        G_MININT+1,G_MAXINT-1)))
                goto fail_free_module;
-       captive_captivemodid_load_module(module);
+       captive_captivemodid_load_module(captivemodid,module);
        return;
 
 fail_free_module:
-       xmlFree((xmlChar *)module->type);
-       xmlFree((xmlChar *)module->md5);
-       xmlFree((xmlChar *)module->id);
-       g_free(module);
+       captive_captivemodid_module_free(module);
 }
 
 static void captive_captivemodid_load_foreach
@@ -285,12 +314,19 @@ static void captive_captivemodid_load_foreach
 
 void (*captive_captivemodid_module_best_priority_notify)(const gchar *module_type);
 
-gboolean captive_captivemodid_load(const gchar *captive_captivemodid_pathname)
+CaptiveCaptivemodidObject *captive_captivemodid_load(const gchar *captive_captivemodid_pathname)
 {
+CaptiveCaptivemodidObject *captivemodid;
 xmlTextReader *xml_reader;
 
        if (!(xml_reader=xmlNewTextReaderFilename(captive_captivemodid_pathname)))
                return FALSE;
+
+       captivemodid=g_object_new(
+               CAPTIVE_CAPTIVEMODID_TYPE_OBJECT,       /* object_type */
+               NULL);  /* first_property_name; FIXME: support properties */
+       captivemodid->pathname_loaded=g_strdup(captive_captivemodid_pathname);
+
        while (1==xmlTextReaderRead(xml_reader)) {
                switch (xmlTextReaderNodeType(xml_reader)) {
 
@@ -313,7 +349,7 @@ const xmlChar *xml_name;
                                /**/ if (!xmlStrcmp(xml_name,BAD_CAST "modid")) {       /* root tag */
                                        }
                                else if (!xmlStrcmp(xml_name,BAD_CAST "module"))
-                                       captive_captivemodid_load_module_xml(captive_captivemodid_pathname,xml_reader);
+                                       captive_captivemodid_load_module_xml(captivemodid,captive_captivemodid_pathname,xml_reader);
                                else g_warning(_("%s: Unknown ELEMENT node: %s"),captive_captivemodid_pathname,xml_name);
                                xmlFree((xmlChar *)xml_name);
                                } break;
@@ -324,8 +360,59 @@ const xmlChar *xml_name;
        xmlFreeTextReader(xml_reader);
 
        if (captive_captivemodid_module_best_priority_notify) {
-               g_hash_table_foreach(module_type_best_priority_hash,
-                                               (GHFunc)captive_captivemodid_load_foreach,NULL);
+               g_hash_table_foreach(captivemodid->module_type_best_priority_hash,
+                                               (GHFunc)captive_captivemodid_load_foreach,
+                                               captivemodid);  /* user_data */
                }
-       return TRUE;
+
+       return captivemodid;
+}
+
+CaptiveCaptivemodidObject *captive_captivemodid_load_default(gboolean fatal)
+{
+CaptiveCaptivemodidObject *captivemodid=NULL;
+const gchar *pathname_default=G_STRINGIFY(SYSCONFDIR) "/w32-mod-id.captivemodid.xml";
+const gchar *msg;
+
+       if ((captivemodid=captive_captivemodid_load(pathname_default)))
+               return captivemodid;
+       if ((captivemodid=captive_captivemodid_load("./w32-mod-id.captivemodid.xml")))
+               return captivemodid;
+       msg=_("Unable to load modid database: %s");
+       if (fatal)
+               g_error(msg,pathname_default);
+       g_warning(msg,pathname_default);
+       return NULL;
+}
+
+const gchar *captive_captivemodid_get_pathname_loaded(CaptiveCaptivemodidObject *captivemodid)
+{
+       return captivemodid->pathname_loaded;
+}
+
+gchar *captive_calc_md5(gconstpointer base,size_t length)
+{
+unsigned char md5_bin[1+128/8];        /* 128 bits==16 bytes; '1+' for leading stub to prevent shorter output of BN_bn2hex() */
+BIGNUM *bignum;
+char *hex;
+gchar *r,*gs;
+
+       /* already done above */
+       /* Calculate MD5 sum and convert it to hex string: */
+       MD5(base,length,md5_bin+1);
+       md5_bin[0]=0xFF;  /* stub to prevent shorter output of BN_bn2hex() */
+       bignum=BN_bin2bn(md5_bin,1+128/8,NULL);
+       hex=BN_bn2hex(bignum);
+       g_assert(strlen(hex)==2*(1+128/8));
+       r=g_strdup(hex+2);
+       OPENSSL_free(hex);
+       BN_free(bignum);
+
+       g_assert(strlen(r)==32);
+       for (gs=r;*gs;gs++) {
+               g_assert(isxdigit(*gs));
+               *gs=tolower(*gs);
+               g_assert(isxdigit(*gs));
+               }
+       return r;
 }
index 8b83174..ba07eaa 100644 (file)
 #include <ctype.h>
 
 
+static void module_check_captivemodid(struct captive_options_module *options_module,const gchar *pathname_utf8)
+{
+       if (!captive_options->captivemodid) {
+               if (!captive_options->load_untested)
+                       g_error(_(
+                                       "You do not have loaded any .captivemodid.xml database using: --modid-path\n"
+                                       "Unable to check MS-Windows module file validity. You should load the database first.\n"
+                                       "You may also force loading of the module although it may not be tested: --load-untested"));
+               g_warning(_("Loading possibly INCOMPATIBLE module as no database is present. Forced by: --load-untested: %s"),
+                               pathname_utf8);
+               return;
+               }
+       if (captive_captivemodid_module_md5_lookup(captive_options->captivemodid,options_module->u.pe32.md5))
+               return;
+       if (!captive_options->load_untested)
+               g_error(_(
+                               "Attempted to load UNTESTED and possibly INCOMPATIBLE module: %s\n"
+                               "You should get more recent identifications database: %s\n"
+                               "Otherwise you may also force the loading by the option: --load-untested"),
+                               pathname_utf8,captive_captivemodid_get_pathname_loaded(captive_options->captivemodid));
+       g_warning(_(
+                       "Loading UNTESTED and possibly INCOMPATIBLE module: %s\n"
+                       "Although forced by --load-untested you really should get more recent modid database: %s\n"),
+                       pathname_utf8,captive_captivemodid_get_pathname_loaded(captive_options->captivemodid));
+}
+
 gboolean captive_options_module_load(struct captive_options_module *options_module,const gchar *pathname_utf8)
 {
 const guint8 magic_mscf[]={'M','S','C','F',0,0,0,0};
@@ -78,6 +104,7 @@ char *hex,*s;
                        *s=tolower(*s);
                        g_assert(isxdigit(*s));
                        }
+               module_check_captivemodid(options_module,pathname_utf8);
                }
        else if (options_module->u.pe32.length>=sizeof(magic_mscf)
                        && !memcmp(options_module->u.pe32.base,magic_mscf,sizeof(magic_mscf))) {
index ff2d6ed..703a84c 100644 (file)
@@ -43,6 +43,8 @@ void captive_options_init(struct captive_options *options)
        options->load_module=NULL;
        options->sandbox=FALSE;
        options->syslog_facility=-1;
+       options->captivemodid=NULL;
+       options->load_untested=FALSE;
 }
 
 
@@ -91,6 +93,9 @@ char **sp;
 
        if (src->bug_pathname)
                dest->bug_pathname=g_strdup(src->bug_pathname);
+
+       if (dest->captivemodid)
+               g_object_ref(dest->captivemodid);
 }
 
 
@@ -110,6 +115,9 @@ void captive_options_free(struct captive_options *options)
        g_free(options->sandbox_server_argv);
        g_free(options->sandbox_server_ior);
        g_free(options->bug_pathname);
+
+       if (options->captivemodid)
+               g_object_unref(options->captivemodid);
 }
 
 
@@ -137,6 +145,19 @@ gboolean errbool;
        captive_options->load_module=g_list_append(captive_options->load_module,options_module);
 }
 
+static void arg_modid_path(void)
+{
+       if (captive_options->captivemodid)
+               g_object_unref(captive_options->captivemodid);
+       if (!(captive_options->captivemodid=captive_captivemodid_load(captive_popt_optarg)))
+               g_error(_("Unable to load modid database: %s"),captive_popt_optarg);
+}
+
+static void arg_load_untested(void)
+{
+       captive_options->load_untested=TRUE;
+}
+
 static void arg_ro(void)
 {
        captive_options->rwmode=CAPTIVE_OPTION_RWMODE_RO;
@@ -334,6 +355,8 @@ const struct poptOption captive_popt[]={
 
                CAPTIVE_POPT_STRING("filesystem"        ,N_("Pathname to .sys or .so filesystem module file"),N_("pathname")),
                CAPTIVE_POPT_STRING("load-module"       ,N_("Pathname to any W32 module to load w/o initialization"),N_("pathname")),
+               CAPTIVE_POPT_STRING("modid-path"        ,N_("Path to .captivemodid.xml database"),N_("path")),
+               CAPTIVE_POPT_NONE(  "load-untested"     ,N_("Force loading of W32 module not present in --modid-path database")),
                CAPTIVE_POPT_NONE(  "ro"                ,N_("Read/write mode: Any write access will be forbidden")),
                CAPTIVE_POPT_NONE(  "blind"             ,N_("Read/write mode: All writes are just simulated in memory (default)")),
                CAPTIVE_POPT_NONE(  "rw"                ,N_("Read/write mode: Write directly to the image file/device")),
@@ -366,6 +389,8 @@ static const struct poptOption captive_popt_standalone[]={
 static void (*const popt_func_table[])(void)={
                arg_filesystem,
                arg_load_module,
+               arg_modid_path,
+               arg_load_untested,
                arg_ro,
                arg_blind,
                arg_rw,
index 5a3847a..592c689 100644 (file)
@@ -22,6 +22,7 @@
 
 
 #include <glib/gtypes.h>
+#include <glib-object.h>
 #include <libgnomevfs/gnome-vfs-file-size.h>
 #include <libxml/tree.h>       /* for xmlChar */
 #include <glib/ghash.h>
 
 G_BEGIN_DECLS
 
+#define CAPTIVE_CAPTIVEMODID_TYPE_OBJECT            (captive_captivemodid_object_get_type())
+#define CAPTIVE_CAPTIVEMODID_OBJECT(object)         (G_TYPE_CHECK_INSTANCE_CAST((object),CAPTIVE_CAPTIVEMODID_TYPE_OBJECT,CaptiveCaptivemodidObject))
+#define CAPTIVE_CAPTIVEMODID_OBJECT_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass),CAPTIVE_CAPTIVEMODID_TYPE_OBJECT,CaptiveCaptivemodidObjectClass))
+#define CAPTIVE_CAPTIVEMODID_IS_OBJECT(object)      (G_TYPE_CHECK_INSTANCE_TYPE((object),CAPTIVE_CAPTIVEMODID_TYPE_OBJECT))
+#define CAPTIVE_CAPTIVEMODID_IS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),CAPTIVE_CAPTIVEMODID_TYPE_OBJECT))
+#define CAPTIVE_CAPTIVEMODID_OBJECT_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj),CAPTIVE_CAPTIVEMODID_TYPE_OBJECT,CaptiveCaptivemodidObjectClass))
+typedef struct _CaptiveCaptivemodidObject      CaptiveCaptivemodidObject;
+typedef struct _CaptiveCaptivemodidObjectClass CaptiveCaptivemodidObjectClass;
+
+
+GType captive_captivemodid_object_get_type(void);
+
+
 struct captive_captivemodid_module {
        const xmlChar *type;
        gint length;
@@ -40,13 +54,19 @@ struct captive_captivemodid_module {
 
 extern void (*captive_captivemodid_module_best_priority_notify)(const gchar *module_type);
 
+CaptiveCaptivemodidObject *captive_captivemodid_load(const gchar *captive_captivemodid_pathname);
+CaptiveCaptivemodidObject *captive_captivemodid_load_default(gboolean fatal);
+const gchar *captive_captivemodid_get_pathname_loaded(CaptiveCaptivemodidObject *captivemodid);
+gboolean captive_captivemodid_module_length_is_valid(CaptiveCaptivemodidObject *captivemodid,GnomeVFSFileSize file_size);
+struct captive_captivemodid_module *captive_captivemodid_module_md5_lookup
+               (CaptiveCaptivemodidObject *captivemodid,const gchar *file_md5);
+gint captive_captivemodid_module_type_best_priority_lookup
+               (CaptiveCaptivemodidObject *captivemodid,const xmlChar *module_type);
+gboolean captive_captivemodid_module_type_best_priority_found
+               (CaptiveCaptivemodidObject *captivemodid,const xmlChar *module_type);
+gint captive_captivemodid_cabinet_length_to_used(CaptiveCaptivemodidObject *captivemodid,gint cabinet_length);
+
 gchar *captive_calc_md5(gconstpointer base,size_t length);
-gboolean captive_captivemodid_module_length_is_valid(GnomeVFSFileSize file_size);
-struct captive_captivemodid_module *captive_captivemodid_module_md5_lookup(const gchar *file_md5);
-gint captive_captivemodid_module_type_best_priority_lookup(const xmlChar *module_type);
-gboolean captive_captivemodid_module_type_best_priority_found(const xmlChar *module_type);
-gboolean captive_captivemodid_load(const gchar *captive_captivemodid_pathname);
-gint captive_captivemodid_cabinet_length_to_used(gint cabinet_length);
 
 G_END_DECLS
 
index 02b4124..d6d97b0 100644 (file)
@@ -26,6 +26,7 @@
 #include <popt.h>
 #include <glib/glist.h>
 #include "captive/options-module.h"
+#include "captive/captivemodid.h"
 
 
 G_BEGIN_DECLS
@@ -61,6 +62,8 @@ struct captive_options {
        gchar *sandbox_server_ior;
        gchar *bug_pathname;
        int syslog_facility;    /* LOG_*; -1 if not used */
+       CaptiveCaptivemodidObject *captivemodid;
+       gboolean load_untested;
        };
 
 /**