Move 'captivemodid' library to libcaptive.
[captive.git] / src / install / acquire / captivemodid.c
diff --git a/src/install/acquire/captivemodid.c b/src/install/acquire/captivemodid.c
deleted file mode 100644 (file)
index bc9c24d..0000000
+++ /dev/null
@@ -1,332 +0,0 @@
-/* $Id$
- * W32 disk modules identifier for acquiration installation utility
- * Copyright (C) 2003 Jan Kratochvil <project-captive@jankratochvil.net>
- * 
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; exactly version 2 of June 1991 is required
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-
-#include "config.h"
-
-#include "captivemodid.h"      /* self */
-#include <glib/gmessages.h>
-#include <libxml/xmlreader.h>
-#include <glib/ghash.h>
-#include <limits.h>
-#include <stdlib.h>
-#include <libgnomevfs/gnome-vfs-file-size.h>
-#include <openssl/md5.h>
-#include <openssl/bn.h>
-#include <openssl/crypto.h>
-#include <glib/gstrfuncs.h>
-#include <ctype.h>
-#include "../../libcaptive/include/captive/libxml.h"
-
-#include <captive/macros.h>
-
-
-gchar *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;
-}
-
-
-/* map: GINT_TO_POINTER(captivemodid_module.length) -> !=NULL */
-static GHashTable *module_valid_length_hash;
-
-static void module_valid_length_hash_init(void)
-{
-       if (module_valid_length_hash)
-               return;
-       module_valid_length_hash=g_hash_table_new(g_direct_hash,g_direct_equal);
-}
-
-/* map: (const xmlChar *)md5 -> (struct captivemodid_module *) */
-static GHashTable *module_md5_hash;
-
-static void module_md5_hash_init(void)
-{
-       if (module_md5_hash)
-               return;
-       module_md5_hash=g_hash_table_new(g_str_hash,g_str_equal);
-}
-
-/* map: (const xmlChar *)type -> (gpointer)GINT_TO_POINTER(priority) */
-/* We remove entry for module with already the best priority found,
- * therefore captivemodid_module_type_best_priority_lookup() will return
- * 'G_MININT' afterwards.
- */
-static GHashTable *module_type_best_priority_hash;
-
-static void module_type_best_priority_hash_init(void)
-{
-       if (module_type_best_priority_hash)
-               return;
-       module_type_best_priority_hash=g_hash_table_new(g_str_hash,g_str_equal);
-}
-
-static void captivemodid_load_module(struct captivemodid_module *module)
-{
-struct 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))) {
-               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);
-
-       module_valid_length_hash_init();
-       if (!g_hash_table_lookup_extended(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));
-       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);
-               }
-
-       if (strcmp((const char *)module->type,"cabinet")) {
-               if (module->priority>captivemodid_module_type_best_priority_lookup(module->type)) {
-                       module_type_best_priority_hash_init();
-                       g_hash_table_insert(module_type_best_priority_hash,
-                                       (/* de-const */ xmlChar *)module->type,GINT_TO_POINTER(module->priority));
-                       }
-               }
-}
-
-gboolean captivemodid_module_length_is_valid(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),
-                       NULL,   /* orig_key */
-                       NULL);  /* value */
-}
-
-gint captivemodid_cabinet_length_to_used(gint cabinet_length)
-{
-gpointer valid_length_value_gpointer;
-
-       if (!g_hash_table_lookup_extended(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 captivemodid_module *captivemodid_module_md5_lookup(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);
-}
-
-gint captivemodid_module_type_best_priority_lookup(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,
-                       module_type,    /* lookup_key */
-                       NULL,   /* orig_key */
-                       &r_gpointer);   /* value */
-       if (!errbool)
-               return G_MININT;
-
-       return GPOINTER_TO_INT(r_gpointer);
-}
-
-/* Returns: TRUE if all modules were found. */
-gboolean captivemodid_module_type_best_priority_found(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);
-       g_assert(errbool==TRUE);
-
-       return !g_hash_table_size(module_type_best_priority_hash);
-}
-
-static xmlChar *captivemodid_load_module_xml_get_attr
-               (const gchar *captivemodid_pathname,xmlTextReader *xml_reader,const gchar *attr_name)
-{
-xmlChar *r;
-
-       if (!(r=xmlTextReaderGetAttribute(xml_reader,BAD_CAST attr_name))) {
-               /* FIXME: File line identification? */
-               g_warning(_("%s: Undefined attributes: %s"),captivemodid_pathname,attr_name);
-               return NULL;
-               }
-       return r;
-}
-
-static long captivemodid_load_module_xml_get_attr_l
-               (const gchar *captivemodid_pathname,xmlTextReader *xml_reader,const gchar *attr_name,long num_min,long num_max)
-{
-xmlChar *string;
-long r;
-char *ends;
-
-       g_return_val_if_fail(num_min-1<num_min,-1);
-       g_return_val_if_fail(num_min<=num_max,num_min-1);
-       g_return_val_if_fail(LONG_MIN<num_min,LONG_MIN);
-       g_return_val_if_fail(num_max<LONG_MAX,num_min-1);
-
-       if (!(string=captivemodid_load_module_xml_get_attr(captivemodid_pathname,xml_reader,attr_name)))
-               return num_min-1;
-       r=strtol((const char *)string,&ends,0);
-       xmlFree(string);
-       if (r<num_min || r>num_max) {
-               g_warning(_("%s: Numer of out range %ld..%ld: %ld"),captivemodid_pathname,num_min,num_max,r);
-               return num_min-1;
-               }
-       return r;
-}
-
-static void captivemodid_load_module_xml(const gchar *captivemodid_pathname,xmlTextReader *xml_reader)
-{
-struct captivemodid_module *module;
-xmlChar *cabinet_used_string;
-
-       captive_new0(module);
-       if (!(module->type=captivemodid_load_module_xml_get_attr(captivemodid_pathname,xml_reader,"type")))
-               goto fail_free_module;
-       if (!(module->md5 =captivemodid_load_module_xml_get_attr(captivemodid_pathname,xml_reader,"md5")))
-               goto fail_free_module;
-       if (strlen((const char *)module->md5)!=strspn((const char *)module->md5,"0123456789abcdef")) {
-               g_warning(_("%s: Attribute 'md5' can be only lower-cased hexstring: %s"),captivemodid_pathname,module->md5);
-               goto fail_free_module;
-               }
-       if (strlen((const char *)module->md5)!=32) {
-               g_warning(_("%s: Attribute 'md5' length must be 32: %s"),captivemodid_pathname,module->md5);
-               goto fail_free_module;
-               }
-       if (!(module->id  =captivemodid_load_module_xml_get_attr(captivemodid_pathname,xml_reader,"id")))
-               goto fail_free_module;
-       if (0>=(module->length=captivemodid_load_module_xml_get_attr_l(
-                       captivemodid_pathname,xml_reader,"length",1,G_MAXINT-1)))
-               goto fail_free_module;
-       if (!(cabinet_used_string=xmlTextReaderGetAttribute(xml_reader,BAD_CAST "cabinet_used")))
-               module->cabinet_used=0;
-       else {
-               xmlFree(cabinet_used_string);
-               if (0>=(module->cabinet_used=captivemodid_load_module_xml_get_attr_l(
-                               captivemodid_pathname,xml_reader,"cabinet_used",1,G_MAXINT-1)))
-                       goto fail_free_module;
-               }
-       if (G_MININT>=(module->priority=captivemodid_load_module_xml_get_attr_l(captivemodid_pathname,xml_reader,"priority",
-                       G_MININT+1,G_MAXINT-1)))
-               goto fail_free_module;
-       captivemodid_load_module(module);
-       return;
-
-fail_free_module:
-       xmlFree((xmlChar *)module->type);
-       xmlFree((xmlChar *)module->md5);
-       xmlFree((xmlChar *)module->id);
-       g_free(module);
-}
-
-static void captivemodid_load_foreach
-               (const xmlChar *type /* key */,gpointer priority_gpointer /* value */,gpointer user_data /* unused */)
-{
-       g_return_if_fail(type!=NULL);
-
-       g_return_if_fail(captivemodid_module_best_priority_notify!=NULL);
-
-       (*captivemodid_module_best_priority_notify)((const gchar *)type);
-}
-
-void (*captivemodid_module_best_priority_notify)(const gchar *module_type);
-
-gboolean captivemodid_load(const gchar *captivemodid_pathname)
-{
-xmlTextReader *xml_reader;
-
-       if (!(xml_reader=xmlNewTextReaderFilename(captivemodid_pathname)))
-               return FALSE;
-       while (1==xmlTextReaderRead(xml_reader)) {
-               switch (xmlTextReaderNodeType(xml_reader)) {
-
-                       case CAPTIVE_XML_TEXT_READER_NODE_TYPE_COMMENT:
-                               break;
-
-                       case CAPTIVE_XML_TEXT_READER_NODE_TYPE_SIGNIFICANT_WHITESPACE:
-                               break;
-
-                       case CAPTIVE_XML_TEXT_READER_NODE_TYPE_TEXT:    /* Even empty nodes have some '#text'. */
-                               break;
-
-                       case CAPTIVE_XML_TEXT_READER_NODE_TYPE_END:     /* We do not track tag ends. */
-                               break;
-
-                       case CAPTIVE_XML_TEXT_READER_NODE_TYPE_START: {
-const xmlChar *xml_name;
-
-                               xml_name=xmlTextReaderName(xml_reader);
-                               /**/ if (!xmlStrcmp(xml_name,BAD_CAST "modid")) {       /* root tag */
-                                       }
-                               else if (!xmlStrcmp(xml_name,BAD_CAST "module"))
-                                       captivemodid_load_module_xml(captivemodid_pathname,xml_reader);
-                               else g_warning(_("%s: Unknown ELEMENT node: %s"),captivemodid_pathname,xml_name);
-                               xmlFree((xmlChar *)xml_name);
-                               } break;
-
-                       default: g_assert_not_reached();
-                       }
-               }
-       xmlFreeTextReader(xml_reader);
-
-       if (captivemodid_module_best_priority_notify) {
-               g_hash_table_foreach(module_type_best_priority_hash,
-                                               (GHFunc)captivemodid_load_foreach,NULL);
-               }
-       return TRUE;
-}