Bootstrap of 'captive-install-acquire' for W32 modules acquiration process.
authorshort <>
Wed, 3 Sep 2003 14:39:41 +0000 (14:39 +0000)
committershort <>
Wed, 3 Sep 2003 14:39:41 +0000 (14:39 +0000)
17 files changed:
AUTHORS
autogen.pl
captive.spec.in
configure.in
src/install/Makefile.am
src/install/acquire/Makefile.am [new file with mode: 0644]
src/install/acquire/cabinet.c [new file with mode: 0644]
src/install/acquire/cabinet.h [new file with mode: 0644]
src/install/acquire/captivemodid.c [new file with mode: 0644]
src/install/acquire/captivemodid.h [new file with mode: 0644]
src/install/acquire/diskscan.c [new file with mode: 0644]
src/install/acquire/diskscan.h [new file with mode: 0644]
src/install/acquire/main.c [new file with mode: 0644]
src/install/acquire/main.h [new file with mode: 0644]
src/install/acquire/moduriload.c [new file with mode: 0644]
src/install/acquire/moduriload.h [new file with mode: 0644]
src/install/acquire/w32-mod-id.captivemodid.xml [new file with mode: 0644]

diff --git a/AUTHORS b/AUTHORS
index 25fffe0..8d2f0eb 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -14,3 +14,5 @@ against branchpoint "bp_captive".
 Integrated small parts of Wine are originally covered by LGPL-2.1.
 According to point 3 of LGPL-2.1 it was chosen to apply the terms of GPL-2.0
 instead to get fully compatible license with captive project.
+
+Integrated cabextract by Stuart Caie licensed according to GPL-2.0.
index 5b829e4..a9ba200 100755 (executable)
@@ -48,6 +48,7 @@ AutoGen->run(
                                ./src/client/sandbox-server/captive-sandbox-server
                                ./src/client/gnomevfs/captive.conf
                                ./src/install/fstab/captive-install-fstab
+                               ./src/install/acquire/captive-install-acquire
                                ./src/libcaptive/cc/marshallers.[ch]
                                ./src/libcaptive/ke/exports.c
                                ./src/libcaptive/reactos/*/*.[cS]
@@ -82,6 +83,11 @@ AutoGen->run(
                                        $gtk_doc_make=~s/^(dist-hook): dist-check-gtkdoc (dist-hook-local)$/$1: $2\n\nDISABLED_$&/m;
                                        AutoGen::_writefile "$fname-captive",$gtk_doc_make;
                                        }
+                               for my $dir ("./src/install/acquire/cabextract") {
+                                       if (!-f "$dir/cabextract.c" || -f "$dir/configure.in") {
+                                               do { system $_ and die "$_: $!"; } for ("cvs co -A $dir");
+                                               }
+                                       }
                                1;
                                },
                );
index 3f2c438..9ebc82c 100644 (file)
@@ -73,6 +73,9 @@ Group: System Environment/Base
 Requires: captive-lufs = %{PACKAGE_VERSION}
 BuildRequires: ntfsprogs-devel
 Requires: ntfsprogs
+Requires: ntfsprogs-gnomevfs
+BuildRequires: gnome-vfs2-devel
+Requires: gnome-vfs2
 
 %description install
 Package provides easy enough unattended installation of Microsoft Windows
@@ -152,6 +155,7 @@ rm -rf $RPM_BUILD_ROOT
 %files install
 %defattr(-,root,root)
 %{_sbindir}/captive-install-fstab
+%{_sbindir}/captive-install-acquire
 
 # %files devel
 # %defattr(-,root,root)
index 4eb1d3d..96adad4 100644 (file)
@@ -213,6 +213,9 @@ AC_SUBST(READLINE_LDFLAGS)
 PKG_CHECK_MODULES(GNOME_VFS_MODULE,gnome-vfs-module-2.0)
 AC_SUBST(GNOME_VFS_MODULE_CFLAGS)
 AC_SUBST(GNOME_VFS_MODULE_LIBS)
+PKG_CHECK_MODULES(GNOME_VFS,gnome-vfs-2.0)
+AC_SUBST(GNOME_VFS_CFLAGS)
+AC_SUBST(GNOME_VFS_LIBS)
 
 dnl Check for 2.5.9 for: http://bugzilla.gnome.org/show_bug.cgi?id=117702
 dnl Check the version - impossible to reliably check the missing feature.
@@ -326,7 +329,9 @@ Makefile
 ./src/client/lufs/Makefile
 ./src/client/sandbox-server/Makefile
 ./src/install/Makefile
+./src/install/libcaptive-install/Makefile
 ./src/install/fstab/Makefile
+./src/install/acquire/Makefile
 ./src/TraceFS/Makefile
 ./doc/Makefile
 ./doc/apiref/Makefile
index c04a8d9..bb4fb6a 100644 (file)
@@ -18,4 +18,4 @@
 
 include $(top_srcdir)/Makefile-head.am
 
-SUBDIRS=fstab
+SUBDIRS=libcaptive-install fstab acquire
diff --git a/src/install/acquire/Makefile.am b/src/install/acquire/Makefile.am
new file mode 100644 (file)
index 0000000..475e213
--- /dev/null
@@ -0,0 +1,45 @@
+# $Id$
+# automake source for drivers acquiring installation utility Makefile
+# 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 $(top_srcdir)/Makefile-head.am
+
+captive_install_acquire_SOURCES= \
+               cabextract/cabextract.c \
+               cabinet.c \
+               cabinet.h \
+               captivemodid.c \
+               captivemodid.h \
+               diskscan.c \
+               diskscan.h \
+               main.c \
+               main.h \
+               moduriload.c \
+               moduriload.h
+captive_install_acquire_CFLAGS=$(GNOME_VFS_CFLAGS) $(LIBXML_CFLAGS) $(OPENSSL_CFLAGS)
+captive_install_acquire_LDADD =$(GNOME_VFS_LIBS)   $(LIBXML_LIBS)   $(OPENSSL_LIBS)   $(LIBNTFS_LIBS) $(POPT_LIBS)
+
+captive_install_acquire_CFLAGS+=-DSYSCONFDIR="$(sysconfdir)"
+captive_install_acquire_LDADD+=../libcaptive-install/libcaptive-install.a
+
+EXTRA_DIST+= \
+               cabextract/.vimrc
+
+if HAVE_LIBNTFS
+captive_install_acquire_cond=captive-install-acquire
+endif
+sbin_PROGRAMS+=$(captive_install_acquire_cond)
diff --git a/src/install/acquire/cabinet.c b/src/install/acquire/cabinet.c
new file mode 100644 (file)
index 0000000..515d0c9
--- /dev/null
@@ -0,0 +1,249 @@
+/* $Id$
+ * cabextract interface 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 "cabinet.h"   /* self */
+#include <glib/gmessages.h>
+#include <libgnomevfs/gnome-vfs-file-size.h>
+#include <libgnomevfs/gnome-vfs-ops.h>
+#include "cabextract/cabextract.h"
+#include "captivemodid.h"
+#include "moduriload.h"
+#include <sys/mman.h>
+#include <unistd.h>
+
+#include <captive/macros.h>
+
+
+void acquire_cabinet_seek(struct acquire_cabinet *acquire_cabinet,GnomeVFSFileOffset offset)
+{
+       g_return_if_fail(acquire_cabinet!=NULL);
+
+       acquire_cabinet->offset=offset;
+}
+
+void acquire_cabinet_seek_skip(struct acquire_cabinet *acquire_cabinet,GnomeVFSFileOffset offset)
+{
+       g_return_if_fail(acquire_cabinet!=NULL);
+
+       acquire_cabinet->offset+=offset;
+}
+
+GnomeVFSFileOffset acquire_cabinet_tell(struct acquire_cabinet *acquire_cabinet)
+{
+       g_return_val_if_fail(acquire_cabinet!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
+
+       return acquire_cabinet->offset;
+}
+
+#define ACQUIRE_CABINET_BYTE_CACHED(acquire_cabinet,pos)     (!(acquire_cabinet)->base_cached \
+                                                           || (acquire_cabinet)->base_cached[(pos)/8] &  1<<((pos)&7))
+#define ACQUIRE_CABINET_SET_BYTE_CACHED(acquire_cabinet,pos) ((acquire_cabinet)->base_cached[(pos)/8] |= 1<<((pos)&7))
+
+GnomeVFSResult acquire_cabinet_read
+               (struct acquire_cabinet *acquire_cabinet,gpointer buffer,GnomeVFSFileSize bytes,GnomeVFSFileSize *bytes_read)
+{
+GnomeVFSFileOffset offset_start,offset_end,read_behind;
+GnomeVFSResult errvfsresult;
+GnomeVFSFileSize bytes_read_now;
+
+       g_return_val_if_fail(acquire_cabinet!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
+       g_return_val_if_fail(buffer!=NULL || bytes==0,GNOME_VFS_ERROR_BAD_PARAMETERS);
+
+       bytes=MAX(0,MIN(bytes,acquire_cabinet->size-acquire_cabinet->offset));
+       if (!bytes)
+               return GNOME_VFS_ERROR_EOF;
+
+       *bytes_read=0;
+       while (bytes) {
+               read_behind =acquire_cabinet->offset+bytes;
+
+               /* GnomeVFS block transfer: */
+               offset_start=acquire_cabinet->offset;
+               offset_end  =acquire_cabinet->offset;
+               while (offset_end<read_behind && !ACQUIRE_CABINET_BYTE_CACHED(acquire_cabinet,offset_end))
+                       offset_end++;
+               if (offset_end>offset_start) {
+                       if (GNOME_VFS_OK!=(errvfsresult=gnome_vfs_seek(acquire_cabinet->handle,GNOME_VFS_SEEK_START,offset_start)))
+                               return errvfsresult;
+                       errvfsresult=gnome_vfs_read(acquire_cabinet->handle,
+                                       acquire_cabinet->base+offset_start,offset_end-offset_start,&bytes_read_now);
+                       if (errvfsresult!=GNOME_VFS_OK)
+                               return errvfsresult;
+                       g_assert(bytes_read_now>0);
+                       while (bytes_read_now) {
+                               ACQUIRE_CABINET_SET_BYTE_CACHED(acquire_cabinet,offset_start);
+                               offset_start++;
+                               bytes_read_now--;
+                               }
+                       }
+
+               /* Memory block transfer: */
+               offset_start=acquire_cabinet->offset;
+               offset_end  =acquire_cabinet->offset;
+               while (offset_end<read_behind && ACQUIRE_CABINET_BYTE_CACHED(acquire_cabinet,offset_end))
+                       offset_end++;
+               memcpy(buffer,acquire_cabinet->base+offset_start,offset_end-offset_start);
+               if (bytes_read)
+                       *bytes_read+=offset_end-offset_start;
+               buffer+=offset_end-offset_start;
+               bytes-=offset_end-offset_start;
+               acquire_cabinet->offset=offset_end;
+               }
+
+       return GNOME_VFS_OK;
+}
+
+static void acquire_cabinet_set_uri(struct acquire_cabinet *acquire_cabinet,GnomeVFSURI *uri)
+{
+GnomeVFSURI *uri_cabextract;
+
+       g_return_if_fail(acquire_cabinet!=NULL);
+       g_return_if_fail(uri!=NULL);
+
+       /* FIXME: HACK: Use proper 'cabextract' scheme after it gets implemented.
+        * GnomeVFS will return NULL on gnome_vfs_uri_new() with scheme not available.
+        */
+       uri_cabextract=gnome_vfs_uri_new("file://");
+       g_assert(uri_cabextract->parent==NULL);
+       /* Do not: g_assert(!strcmp(uri_cabextract->method_string,"file"));
+        *         uri_cabextract->method_string=g_strdup("cabextract");
+        * as it will just strip such anchor. FIXME: Why?
+        */
+
+       uri_cabextract->parent=gnome_vfs_uri_dup(uri);
+
+       acquire_cabinet->uri=uri_cabextract;
+       acquire_cabinet->filename=gnome_vfs_uri_to_string(acquire_cabinet->uri,GNOME_VFS_URI_HIDE_PASSWORD);
+}
+
+struct acquire_cabinet *acquire_cabinet_new_from_memory(gconstpointer file_base,size_t file_length,GnomeVFSURI *uri)
+{
+struct acquire_cabinet *r;
+
+       g_return_val_if_fail(file_base!=NULL,NULL);
+       g_return_val_if_fail(uri!=NULL,NULL);
+       
+       captive_new(r);
+       r->base=(/* de-const */ gpointer)file_base;
+       r->base_cached=NULL;
+       r->offset=0;
+       r->handle=NULL;
+       r->size=file_length;
+       acquire_cabinet_set_uri(r,uri);
+
+       return r;
+}
+
+struct acquire_cabinet *acquire_cabinet_new_from_handle(GnomeVFSHandle *handle,GnomeVFSFileInfo *file_info,GnomeVFSURI *uri)
+{
+struct acquire_cabinet *r;
+
+       g_return_val_if_fail(handle!=NULL,NULL);
+       g_return_val_if_fail(file_info!=NULL,NULL);
+       g_return_val_if_fail(uri!=NULL,NULL);
+       
+       captive_new(r);
+       if (MAP_FAILED==(r->base=mmap(
+                       NULL,CAPTIVE_ROUND_UP64(file_info->size,getpagesize()),PROT_READ|PROT_WRITE,MAP_ANONYMOUS|MAP_PRIVATE,-1,0))) {
+               g_free(r);
+               g_return_val_if_reached(NULL);
+               }
+       captive_new0n(r->base_cached,CAPTIVE_ROUND_UP64(file_info->size,8)/8);
+       r->offset=0;
+       r->handle=handle;
+       r->size=file_info->size;
+       acquire_cabinet_set_uri(r,uri);
+
+       return r;
+}
+
+void acquire_cabinet_free(struct acquire_cabinet *acquire_cabinet)
+{
+       g_return_if_fail(acquire_cabinet!=NULL);
+
+       if (acquire_cabinet->base_cached) {
+               munmap(acquire_cabinet->base,CAPTIVE_ROUND_UP64(acquire_cabinet->size,getpagesize()));  /* errors ignored */
+               g_free(acquire_cabinet->base_cached);
+               }
+       g_free((/* de-const */ gchar *)acquire_cabinet->filename);
+       gnome_vfs_uri_unref(acquire_cabinet->uri);
+       g_free(acquire_cabinet);
+}
+
+static struct file *file_write_fi_assertion;
+static GByteArray *file_write_bytearray;
+
+int file_write(struct file *fi, UBYTE *buf, size_t length)
+{
+       g_return_val_if_fail(fi!=NULL,0);
+       g_return_val_if_fail(buf!=NULL || length==0,0);
+
+       g_return_val_if_fail(fi==file_write_fi_assertion,0);
+       g_return_val_if_fail(file_write_bytearray!=NULL,0);
+
+       g_byte_array_append(file_write_bytearray,buf,length);
+
+       return 1;       /* success */
+}
+
+void acquire_cabinet_load(struct acquire_cabinet *acquire_cabinet)
+{
+struct cabinet *basecab;
+struct file *filelist,*fi;
+
+       g_return_if_fail(acquire_cabinet!=NULL);
+
+       basecab=find_cabs_in_file(acquire_cabinet);
+       if (!basecab)
+               return;
+       if (basecab->next)
+               return;
+       if (basecab->prevcab || basecab->nextcab)
+               return;
+
+       filelist=process_files(basecab);
+
+       for (fi=filelist;fi;fi=fi->next) {
+gpointer file_buffer;
+GnomeVFSURI *uri_fi;
+
+               if (!captivemodid_module_length_is_valid(fi->length))
+                       continue;
+
+               file_write_fi_assertion=fi;
+               file_write_bytearray=g_byte_array_new();
+               extract_file(fi,
+                               0,      /* lower; ignored now */
+                               FALSE,  /* fix */
+                               NULL);  /* dir; ignored now */
+               if (fi->length!=file_write_bytearray->len) {
+                       g_byte_array_free(file_write_bytearray,
+                                       TRUE);  /* free_segment */
+                       continue;
+                       }
+               file_buffer=g_byte_array_free(file_write_bytearray,
+                               FALSE); /* free_segment */
+               uri_fi=gnome_vfs_uri_append_file_name(acquire_cabinet->uri,fi->filename);
+               mod_uri_load_file_from_memory(file_buffer,fi->length,uri_fi);
+               gnome_vfs_uri_unref(uri_fi);
+               g_free(file_buffer);
+    }
+}
diff --git a/src/install/acquire/cabinet.h b/src/install/acquire/cabinet.h
new file mode 100644 (file)
index 0000000..7d673e5
--- /dev/null
@@ -0,0 +1,64 @@
+/* $Id$
+ * Include file for drivers acquiring 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
+ */
+
+
+#ifndef _CAPTIVE_INSTALL_ACQUIRE_CABINET_H
+#define _CAPTIVE_INSTALL_ACQUIRE_CABINET_H 1
+
+
+#include <glib/gtypes.h>
+#include <libgnomevfs/gnome-vfs-file-size.h>
+#include <libgnomevfs/gnome-vfs-handle.h>
+
+
+G_BEGIN_DECLS
+
+/* It is not 'GObject'-based as we will move to GnomeVFS handler cabextract://
+ * anyway.
+ */
+
+struct acquire_cabinet {
+       gpointer base;
+       guint8 *base_cached;
+       GnomeVFSFileOffset offset;
+       GnomeVFSHandle *handle;
+       GnomeVFSFileSize size;
+       const gchar *filename;
+       GnomeVFSURI *uri;
+       void (*seek)(struct acquire_cabinet *acquire_cabinet,GnomeVFSFileOffset offset);
+       void (*seek_skip)(struct acquire_cabinet *acquire_cabinet,GnomeVFSFileOffset offset);
+       GnomeVFSFileOffset (*tell)(struct acquire_cabinet *acquire_cabinet);
+       GnomeVFSResult (*read)
+                       (struct acquire_cabinet *acquire_cabinet,gpointer buffer,GnomeVFSFileSize bytes,GnomeVFSFileSize *bytes_read);
+       };
+
+void acquire_cabinet_seek(struct acquire_cabinet *acquire_cabinet,GnomeVFSFileOffset offset);
+void acquire_cabinet_seek_skip(struct acquire_cabinet *acquire_cabinet,GnomeVFSFileOffset offset);
+GnomeVFSFileOffset acquire_cabinet_tell(struct acquire_cabinet *acquire_cabinet);
+GnomeVFSResult acquire_cabinet_read
+               (struct acquire_cabinet *acquire_cabinet,gpointer buffer,GnomeVFSFileSize bytes,GnomeVFSFileSize *bytes_read);
+
+struct acquire_cabinet *acquire_cabinet_new_from_memory(gconstpointer file_base,size_t file_length,GnomeVFSURI *uri);
+struct acquire_cabinet *acquire_cabinet_new_from_handle(GnomeVFSHandle *handle,GnomeVFSFileInfo *file_info,GnomeVFSURI *uri);
+void acquire_cabinet_free(struct acquire_cabinet *acquire_cabinet);
+void acquire_cabinet_load(struct acquire_cabinet *acquire_cabinet);
+
+G_END_DECLS
+
+
+#endif /* _CAPTIVE_INSTALL_ACQUIRE_CABINET_H */
diff --git a/src/install/acquire/captivemodid.c b/src/install/acquire/captivemodid.c
new file mode 100644 (file)
index 0000000..8421cef
--- /dev/null
@@ -0,0 +1,225 @@
+/* $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 <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);
+}
+
+static void captivemodid_load_module(struct captivemodid_module *module)
+{
+struct captivemodid_module *module_md5_conflict;
+
+       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();
+       g_hash_table_insert(module_valid_length_hash,GINT_TO_POINTER(module->length),module_valid_length_hash);
+}
+
+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;
+       return !!g_hash_table_lookup(module_valid_length_hash,GINT_TO_POINTER(file_size_gint));
+}
+
+struct captivemodid_module *captivemodid_module_md5_lookup(const gchar *file_md5)
+{
+       g_return_val_if_fail(file_md5!=NULL,NULL);
+
+       return g_hash_table_lookup(module_md5_hash,file_md5);
+}
+
+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,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(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;
+
+       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(module->md5)!=strspn(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(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 (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);
+}
+
+
+void captivemodid_load(const gchar *captivemodid_pathname)
+{
+xmlTextReader *xml_reader;
+
+       xml_reader=xmlNewTextReaderFilename(captivemodid_pathname);
+       g_assert(xml_reader!=NULL);
+       while (1==xmlTextReaderRead(xml_reader)) {
+               switch (xmlTextReaderNodeType(xml_reader)) {
+
+                       case XML_READER_TYPE_COMMENT:
+                               break;
+
+                       case XML_READER_TYPE_SIGNIFICANT_WHITESPACE:
+                               break;
+
+                       case XML_READER_TYPE_TEXT:      /* Even empty nodes have some '#text'. */
+                               break;
+
+                       case XML_READER_TYPE_END_ELEMENT:       /* We do not track tag ends. */
+                               break;
+
+                       case XML_READER_TYPE_ELEMENT: {
+const xmlChar *xml_name;
+
+                               xml_name=xmlTextReaderName(xml_reader);
+                               /**/ if (!xmlStrcmp(xml_name,"modid")) {        /* root tag */
+                                       }
+                               else if (!xmlStrcmp(xml_name,"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);
+}
diff --git a/src/install/acquire/captivemodid.h b/src/install/acquire/captivemodid.h
new file mode 100644 (file)
index 0000000..1fcdd4f
--- /dev/null
@@ -0,0 +1,47 @@
+/* $Id$
+ * Include file for 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
+ */
+
+
+#ifndef _CAPTIVE_INSTALL_ACQUIRE_CAPTIVEMODID_H
+#define _CAPTIVE_INSTALL_ACQUIRE_CAPTIVEMODID_H 1
+
+
+#include <glib/gtypes.h>
+#include <libgnomevfs/gnome-vfs-file-size.h>
+#include <libxml/tree.h>       /* for xmlChar */
+
+
+G_BEGIN_DECLS
+
+struct captivemodid_module {
+       const xmlChar *type;
+       gint length;
+       const xmlChar *md5;
+       const xmlChar *id;
+       gint priority;
+       };
+
+gchar *calc_md5(gconstpointer base,size_t length);
+gboolean captivemodid_module_length_is_valid(GnomeVFSFileSize file_size);
+struct captivemodid_module *captivemodid_module_md5_lookup(const gchar *file_md5);
+void captivemodid_load(const gchar *captivemodid_pathname);
+
+G_END_DECLS
+
+
+#endif /* _CAPTIVE_INSTALL_ACQUIRE_CAPTIVEMODID_H */
diff --git a/src/install/acquire/diskscan.c b/src/install/acquire/diskscan.c
new file mode 100644 (file)
index 0000000..4316db0
--- /dev/null
@@ -0,0 +1,145 @@
+/* $Id$
+ * W32 disk modules finder 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 <glib/gmessages.h>
+#include <mntent.h>
+#include <glib/ghash.h>
+#include <glib/glist.h>
+#include <libgnomevfs/gnome-vfs-uri.h>
+#include "../libcaptive-install/proc_partitions.h"
+#include "main.h"
+#include <string.h>
+
+
+/* Config: */
+#define FILENAME_ETC_MTAB "/etc/mtab"
+
+
+struct mod_uri_libntfs_proc_partitions_foreach_param {
+       GHashTable *proc_partitions_ntfs_hash;
+       GList *uri_list;        /* of (GnomeVFSURI *) */
+       };
+
+static void mod_uri_libntfs_proc_partitions_foreach(const gchar *device /* key */,const gchar *vol_name /* value */,
+               struct mod_uri_libntfs_proc_partitions_foreach_param *foreach_param /* user_data */)
+{
+GnomeVFSURI *uri_device,*uri_libntfs;
+
+       g_return_if_fail(device!=NULL);
+       g_return_if_fail(vol_name!=NULL);
+       g_return_if_fail(foreach_param!=NULL);
+
+       uri_device=gnome_vfs_uri_new("file:///");
+       uri_device=gnome_vfs_uri_append_path(uri_device,device);
+       g_assert(uri_device->parent==NULL);
+       uri_libntfs=gnome_vfs_uri_new("libntfs:///");
+       g_assert(uri_libntfs->parent==NULL);
+
+       uri_libntfs->parent=uri_device;
+
+       foreach_param->uri_list=g_list_prepend(foreach_param->uri_list,uri_libntfs);
+}
+
+static GList * /* of (GnomeVFSURI *) */ mod_uri_libntfs_proc_partitions(void)
+{
+/* map: (gchar *)device -> (gchar *)vol_name */
+GHashTable *proc_partitions_ntfs_hash;
+struct mod_uri_libntfs_proc_partitions_foreach_param foreach_param;
+
+       proc_partitions_ntfs_hash=proc_partitions_ntfs_hash_get(optarg_verbose);
+
+       foreach_param.proc_partitions_ntfs_hash=proc_partitions_ntfs_hash;
+       foreach_param.uri_list=NULL;
+       g_hash_table_foreach(proc_partitions_ntfs_hash,
+                       (GHFunc)mod_uri_libntfs_proc_partitions_foreach,        /* func */
+                       &foreach_param);        /* user_data */
+       g_hash_table_destroy(proc_partitions_ntfs_hash);
+
+       return foreach_param.uri_list;
+}
+
+
+static GList * /* of (GnomeVFSURI *) */ mod_uri_mtab(void)
+{
+struct mntent *mntent;
+FILE *mntentfiler;
+GList *uri_list;       /* of (GnomeVFSURI *) */
+GnomeVFSURI *uri;
+
+       if (!(mntentfiler=setmntent(FILENAME_ETC_MTAB,"r"))) {
+               g_warning(_("Cannot open \"%s\" for reading: %m"),FILENAME_ETC_MTAB);
+               return NULL;
+               }
+       uri_list=NULL;
+       while ((mntent=getmntent(mntentfiler))) {
+               if (!strcmp(mntent->mnt_type,"proc"))   /* optimize... */
+                       continue;
+               uri=gnome_vfs_uri_new("file:///");
+               uri=gnome_vfs_uri_append_path(uri,mntent->mnt_dir);
+               uri_list=g_list_prepend(uri_list,uri);
+               }
+       if (1!=endmntent(mntentfiler))
+               g_warning(_("Cannot close \"%s\" after reading: %m"),FILENAME_ETC_MTAB);
+
+       return uri_list;
+}
+
+static GList * /* of (GnomeVFSURI *) */ filter_non_local_uri(GList * /* of (GnomeVFSURI *) */ uri_list)
+{
+GList *uril;
+
+       /* Filter-out non-local URIs */
+       for (uril=uri_list;uril;) {
+GnomeVFSURI *uri=uril->data;
+
+               if (!gnome_vfs_uri_is_local(uri)) {
+                       if (optarg_verbose) {
+gchar *uri_string;
+
+                               uri_string=gnome_vfs_uri_to_string(uri,GNOME_VFS_URI_HIDE_PASSWORD);
+                               g_message(_("Ignoring URI in auto-search as it is not local: %s"),uri_string);
+                               g_free(uri_string);
+                               }
+                       gnome_vfs_uri_unref(uri);
+                       /* It is safe to be used during traversal this way: */
+                       uril=uril->next;
+                       uri_list=g_list_remove_link(uri_list,uril);
+                       /* Prevent auto-traversal to the next list item: */
+                       continue;
+                       }
+               uril=uril->next;
+               }
+       return uri_list;
+}
+
+GList * /* of (GnomeVFSURI *) */ mod_uri_list(void)
+{
+GList *uri_list;
+
+       uri_list=NULL;
+
+       uri_list=g_list_concat(uri_list,mod_uri_mtab());
+       uri_list=g_list_concat(uri_list,mod_uri_libntfs_proc_partitions());
+
+       uri_list=filter_non_local_uri(uri_list);
+
+       return uri_list;
+}
diff --git a/src/install/acquire/diskscan.h b/src/install/acquire/diskscan.h
new file mode 100644 (file)
index 0000000..067bed1
--- /dev/null
@@ -0,0 +1,35 @@
+/* $Id$
+ * Include file for W32 disk modules finder 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
+ */
+
+
+#ifndef _CAPTIVE_INSTALL_ACQUIRE_DISKSCAN_H
+#define _CAPTIVE_INSTALL_ACQUIRE_DISKSCAN_H 1
+
+
+#include <glib/gtypes.h>
+#include <glib/glist.h>
+
+
+G_BEGIN_DECLS
+
+GList * /* of (GnomeVFSURI *) */ mod_uri_list(void);
+
+G_END_DECLS
+
+
+#endif /* _CAPTIVE_INSTALL_ACQUIRE_DISKSCAN_H */
diff --git a/src/install/acquire/main.c b/src/install/acquire/main.c
new file mode 100644 (file)
index 0000000..d6de799
--- /dev/null
@@ -0,0 +1,145 @@
+/* $Id$
+ * Drivers acquiring 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 <glib/gmessages.h>
+#include <popt.h>
+#include <locale.h>
+#include <stdlib.h>
+#include <string.h>
+#include <mntent.h>
+#include <glib/ghash.h>
+#include <glib/gstrfuncs.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <unistd.h>
+#include <libgnomevfs/gnome-vfs-init.h>
+
+#include <captive/macros.h>
+
+
+#include "captivemodid.h"
+#include <glib/glist.h>
+#include "moduriload.h"
+#include "diskscan.h"
+
+
+int optarg_verbose;
+static int optarg_scan_disks;
+static GList *optarg_scan_path_list;   /* of (char *) */
+
+static void acquire_popt_callback
+               (poptContext con,enum poptCallbackReason reason,const struct poptOption *opt,const char *arg,const void *data);
+
+static const struct poptOption popt_table[]={
+               { argInfo:POPT_ARG_CALLBACK,arg:(void *)acquire_popt_callback },
+
+#define BUG_ACQUIRE_POPT(shortname,longname,argInfoP,argP,valP,descripP,argDescripP) \
+               { \
+                       longName: (longname), \
+                       shortName: (shortname), \
+                       argInfo: (argInfoP)|(!(valP) ? 0 : POPT_ARG_VAL), \
+                       arg: (void *)argP, \
+                       val: (valP), \
+                       descrip: (descripP), \
+                       argDescrip: (argDescripP), \
+               }
+
+               BUG_ACQUIRE_POPT('v',"verbose"   ,POPT_ARG_NONE  ,&optarg_verbose   ,0,N_("Display additional debug information"),NULL),
+               BUG_ACQUIRE_POPT(0  ,"scan-disks",POPT_ARG_NONE  ,&optarg_scan_disks,0,N_("Scan all local disks"),NULL),
+               BUG_ACQUIRE_POPT(0  ,"scan-path" ,POPT_ARG_STRING,NULL              ,0,N_("Scan specified disk path"),N_("path/URI")),
+
+#undef BUG_ACQUIRE_POPT
+               POPT_AUTOHELP
+               POPT_TABLEEND
+               };
+
+
+/* poptCallbackType captive_popt_callback */
+static void acquire_popt_callback
+               (poptContext con,enum poptCallbackReason reason,const struct poptOption *opt,const char *arg,const void *data)
+{
+       g_return_if_fail(reason==POPT_CALLBACK_REASON_OPTION);
+
+       if (opt->longName && !strcmp(opt->longName,"scan-path")) {
+               optarg_scan_path_list=g_list_append(optarg_scan_path_list,gnome_vfs_uri_new(arg));
+               }
+}
+
+
+int main(int argc,char **argv)
+{
+poptContext context;
+int errint;
+GList *scan_uri_list;
+
+#ifdef MAINTAINER_MODE
+       g_log_set_always_fatal(~(0
+                       |G_LOG_LEVEL_MESSAGE
+                       |G_LOG_LEVEL_INFO
+                       |G_LOG_LEVEL_DEBUG
+                       ));
+#endif
+
+       /* Initialize the i18n stuff */
+       setlocale(LC_ALL,"");
+       bindtextdomain(PACKAGE,LOCALEDIR);
+       textdomain(PACKAGE);
+
+       if (!gnome_vfs_init())
+               g_error(_("GnomeVFS failed to initialize"));
+
+       context=poptGetContext(
+                       PACKAGE,        /* name */
+                       argc,(/*en-const*/const char **)argv,   /* argc,argv */
+                       popt_table,     /* options */
+                       POPT_CONTEXT_POSIXMEHARDER);    /* flags; && !POPT_CONTEXT_KEEP_FIRST */
+       if (context==NULL) {
+               g_assert_not_reached(); /* argument recognization args_error */
+               return EXIT_FAILURE;
+               }
+       errint=poptReadDefaultConfig(context,
+                       TRUE);  /* useEnv */
+       if (errint!=0) {
+               g_assert_not_reached(); /* argument recognization args_error */
+               return EXIT_FAILURE;
+               }
+       errint=poptGetNextOpt(context);
+       if (errint!=-1) {
+               g_assert_not_reached(); /* some non-callbacked argument reached */
+               return EXIT_FAILURE;
+               }
+       if (poptPeekArg(context)) {
+               g_error(_("No arguments expected"));
+               return EXIT_FAILURE;
+               }
+
+       scan_uri_list=NULL;
+       scan_uri_list=g_list_concat(scan_uri_list,gnome_vfs_uri_list_copy(optarg_scan_path_list));
+       if (optarg_scan_disks)
+               scan_uri_list=g_list_concat(scan_uri_list,mod_uri_list());
+
+       captivemodid_load("./w32-mod-id.captivemodid.xml");
+       g_list_foreach(scan_uri_list,(GFunc)mod_uri_load,NULL);
+
+       gnome_vfs_shutdown();
+
+       return EXIT_SUCCESS;
+}
diff --git a/src/install/acquire/main.h b/src/install/acquire/main.h
new file mode 100644 (file)
index 0000000..1f8989a
--- /dev/null
@@ -0,0 +1,35 @@
+/* $Id$
+ * Include file for drivers acquiring 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
+ */
+
+
+#ifndef _CAPTIVE_INSTALL_ACQUIRE_MAIN_H
+#define _CAPTIVE_INSTALL_ACQUIRE_MAIN_H 1
+
+
+#include <glib/gtypes.h>
+#include <glib/ghash.h>
+
+
+G_BEGIN_DECLS
+
+extern gboolean optarg_verbose;
+
+G_END_DECLS
+
+
+#endif /* _CAPTIVE_INSTALL_ACQUIRE_MAIN_H */
diff --git a/src/install/acquire/moduriload.c b/src/install/acquire/moduriload.c
new file mode 100644 (file)
index 0000000..4d67e44
--- /dev/null
@@ -0,0 +1,241 @@
+/* $Id$
+ * W32 disk modules finder 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 "moduriload.h"        /* self */
+#include <glib/gmessages.h>
+#include <mntent.h>
+#include <glib/ghash.h>
+#include <glib/glist.h>
+#include <libgnomevfs/gnome-vfs-uri.h>
+#include "../libcaptive-install/proc_partitions.h"
+#include "main.h"
+#include <string.h>
+#include "captivemodid.h"
+#include "cabinet.h"
+#include <libgnomevfs/gnome-vfs-ops.h>
+#include <libgnomevfs/gnome-vfs-directory.h>
+
+
+/* Config: */
+#define MAX_FILE_LOAD_LENGTH 5000000   /* Otherwise use cabextract-over-http. */
+
+
+static void mod_uri_load_module_from_memory
+               (struct captivemodid_module *module,gconstpointer file_base,size_t file_length,GnomeVFSURI *uri)
+{
+gchar *uri_text;
+
+       g_return_if_fail(module!=NULL);
+       g_return_if_fail(file_base!=NULL);
+       g_return_if_fail(uri!=NULL);
+
+       uri_text=gnome_vfs_uri_to_string(uri,GNOME_VFS_URI_HIDE_PASSWORD);
+       g_message("type=%s,id:%s: %s",module->type,module->id,uri_text);
+       g_free(uri_text);
+}
+
+void mod_uri_load_file_from_memory(gconstpointer file_base,size_t file_length,GnomeVFSURI *uri)
+{
+gchar *file_md5;
+struct captivemodid_module *module;
+
+       g_return_if_fail(file_base!=NULL);
+       g_return_if_fail(uri!=NULL);
+
+       file_md5=calc_md5(file_base,file_length);
+       if (!(module=captivemodid_module_md5_lookup(file_md5)))
+               goto fail_free_file_md5;
+
+       if (strcmp("cabinet",module->type))
+               mod_uri_load_module_from_memory(module,file_base,file_length,uri);
+       else {
+               struct acquire_cabinet *acquire_cabinet;
+               /* acquire_cabinet_load() will call mod_uri_load_module_from_memory(): */
+               acquire_cabinet=acquire_cabinet_new_from_memory(file_base,file_length,uri);
+               acquire_cabinet_load(acquire_cabinet);
+               acquire_cabinet_free(acquire_cabinet);
+               }
+
+fail_free_file_md5:
+       g_free(file_md5);
+}
+
+static void mod_uri_load_file_handle_to_memory(GnomeVFSHandle *handle,GnomeVFSFileInfo *file_info,GnomeVFSURI *uri)
+{
+guint8 *file_buffer,file_tail_check;
+GnomeVFSFileSize bytes_read;
+GnomeVFSResult errvfsresult;
+
+       g_return_if_fail(handle!=NULL);
+       g_return_if_fail(file_info!=NULL);
+       g_return_if_fail(uri!=NULL);
+
+       /* gnome_vfs_read_entire_file() reads the file by chunks although
+        * it does not need to know the file size.
+        */
+       file_buffer=g_malloc(file_info->size);
+       
+       errvfsresult=gnome_vfs_read(handle,file_buffer,file_info->size,&bytes_read);
+       if (errvfsresult!=GNOME_VFS_OK || bytes_read!=file_info->size)
+               goto fail_free_file_buffer;
+       errvfsresult=gnome_vfs_read(handle,&file_tail_check,1,NULL);
+       if (errvfsresult!=GNOME_VFS_ERROR_EOF)
+               goto fail_free_file_buffer;
+       mod_uri_load_file_from_memory(file_buffer,file_info->size,uri);
+
+fail_free_file_buffer:
+       g_free(file_buffer);
+}
+
+static void mod_uri_load_file_handle_remote_cabinet(GnomeVFSHandle *handle,GnomeVFSFileInfo *file_info,GnomeVFSURI *uri)
+{
+struct acquire_cabinet *acquire_cabinet;
+
+       g_return_if_fail(handle!=NULL);
+       g_return_if_fail(file_info!=NULL);
+       g_return_if_fail(uri!=NULL);
+
+       acquire_cabinet=acquire_cabinet_new_from_handle(handle,file_info,uri);
+       /* acquire_cabinet_load() will call mod_uri_load_module_from_memory(): */
+       acquire_cabinet_load(acquire_cabinet);
+       acquire_cabinet_free(acquire_cabinet);
+}
+
+static void mod_uri_load_file(GnomeVFSURI *uri)
+{
+GnomeVFSResult errvfsresult;
+GnomeVFSFileInfo file_info_local;
+GnomeVFSHandle *handle;
+
+       g_return_if_fail(uri!=NULL);
+
+       if (GNOME_VFS_OK!=(errvfsresult=gnome_vfs_open_uri(&handle,uri,GNOME_VFS_OPEN_READ)))
+               goto fail;
+       if (GNOME_VFS_OK!=(errvfsresult=gnome_vfs_get_file_info_from_handle(handle,&file_info_local,GNOME_VFS_FILE_INFO_DEFAULT)))
+               goto fail_close_handle;
+       if (file_info_local.type!=GNOME_VFS_FILE_TYPE_REGULAR) {
+               errvfsresult=GNOME_VFS_ERROR_WRONG_FORMAT;
+               goto fail_close_handle;
+               }
+       if (!(file_info_local.valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE)) {
+               errvfsresult=GNOME_VFS_ERROR_WRONG_FORMAT;
+               goto fail_close_handle;
+               }
+       if (!captivemodid_module_length_is_valid(file_info_local.size)) {
+               errvfsresult=GNOME_VFS_ERROR_WRONG_FORMAT;
+               goto fail_close_handle;
+               }
+       if (file_info_local.size<=MAX_FILE_LOAD_LENGTH)
+               mod_uri_load_file_handle_to_memory(handle,&file_info_local,uri);
+       else
+               mod_uri_load_file_handle_remote_cabinet(handle,&file_info_local,uri);
+       errvfsresult=GNOME_VFS_OK;
+       /* PASSTHRU */
+fail_close_handle:
+       gnome_vfs_close(handle);
+fail:;
+}
+
+static gboolean mod_uri_load_directory_visit_func
+               (const gchar *rel_path,GnomeVFSFileInfo *info,gboolean recursing_will_loop,GnomeVFSURI *root_uri /* data */,
+               gboolean *recurse)
+{
+       g_return_val_if_fail(rel_path!=NULL,FALSE);
+       g_return_val_if_fail(info!=NULL,FALSE);
+       g_return_val_if_fail(root_uri!=NULL,FALSE);
+       g_return_val_if_fail(recurse!=NULL,FALSE);
+
+       *recurse=FALSE;
+
+       switch (info->type) {
+               case GNOME_VFS_FILE_TYPE_REGULAR: {
+GnomeVFSURI *file_uri;
+
+                       file_uri=gnome_vfs_uri_append_path(root_uri,rel_path);
+                       mod_uri_load_file(file_uri);
+                       gnome_vfs_uri_unref(file_uri);
+                       } break;
+               case GNOME_VFS_FILE_TYPE_DIRECTORY: {
+GnomeVFSURI *directory_uri;
+GnomeVFSDirectoryHandle *directory_handle;
+
+                       /* Never set '*recurse' if it would cause 'Access denied' error
+                        * as it would completely abort the upper gnome_vfs_directory_visit_uri().
+                        * Check the directory accessibility manually:
+                        */
+                       directory_uri=gnome_vfs_uri_append_path(root_uri,rel_path);
+                       if (GNOME_VFS_OK==gnome_vfs_directory_open_from_uri(&directory_handle,directory_uri,GNOME_VFS_FILE_INFO_DEFAULT)) {
+                               *recurse=TRUE;
+                               gnome_vfs_directory_close(directory_handle);    /* errors ignored */
+                               }
+                       gnome_vfs_uri_unref(directory_uri);
+                       } break;
+               default:;
+               }
+
+       return TRUE;    /* continue traversal */
+}
+
+static void mod_uri_load_directory(GnomeVFSURI *uri)
+{
+GnomeVFSResult errvfsresult;
+
+       g_return_if_fail(uri!=NULL);
+
+       errvfsresult=gnome_vfs_directory_visit_uri(uri,
+                       GNOME_VFS_FILE_INFO_DEFAULT,    /* info_options */
+                       GNOME_VFS_DIRECTORY_VISIT_SAMEFS,       /* visit_options; 'GNOME_VFS_DIRECTORY_VISIT_LOOPCHECK'? */
+                       (GnomeVFSDirectoryVisitFunc)mod_uri_load_directory_visit_func,
+                       uri);   /* data */
+       if (errvfsresult!=GNOME_VFS_OK) {
+gchar *uri_text;
+
+               uri_text=gnome_vfs_uri_to_string(uri,GNOME_VFS_URI_HIDE_PASSWORD);
+               g_warning(_("Error scanning sub-tree of \"%s\": %s"),uri_text,gnome_vfs_result_to_string(errvfsresult));
+               g_free(uri_text);
+               }
+}
+
+void mod_uri_load(GnomeVFSURI *uri)
+{
+GnomeVFSFileInfo file_info_local;
+GnomeVFSResult errvfsresult;
+
+       g_return_if_fail(uri!=NULL);
+
+       if (optarg_verbose) {
+gchar *uri_text;
+
+               uri_text=gnome_vfs_uri_to_string(uri,GNOME_VFS_URI_HIDE_PASSWORD);
+               g_message(_("Scanning...: %s"),uri_text);
+               g_free(uri_text);
+               }
+
+       file_info_local.type=GNOME_VFS_FILE_TYPE_UNKNOWN;
+       if (GNOME_VFS_OK!=(errvfsresult=gnome_vfs_get_file_info_uri(uri,&file_info_local,GNOME_VFS_FILE_INFO_DEFAULT)))
+               return /* errvfsresult */;
+       switch (file_info_local.type) {
+               case GNOME_VFS_FILE_TYPE_REGULAR:   return mod_uri_load_file(uri);
+               case GNOME_VFS_FILE_TYPE_DIRECTORY: return mod_uri_load_directory(uri);
+               default:                            return /* GNOME_VFS_ERROR_WRONG_FORMAT */;
+               }
+       /* NOTREACHED */
+}
diff --git a/src/install/acquire/moduriload.h b/src/install/acquire/moduriload.h
new file mode 100644 (file)
index 0000000..a0c03f3
--- /dev/null
@@ -0,0 +1,38 @@
+/* $Id$
+ * Include file for W32 disk modules finder 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
+ */
+
+
+#ifndef _CAPTIVE_INSTALL_ACQUIRE_MODURILOAD_H
+#define _CAPTIVE_INSTALL_ACQUIRE_MODURILOAD_H 1
+
+
+#include <glib/gtypes.h>
+#include <glib/ghash.h>
+#include <libgnomevfs/gnome-vfs-uri.h>
+#include "captivemodid.h"
+
+
+G_BEGIN_DECLS
+
+void mod_uri_load_file_from_memory(gconstpointer file_base,size_t file_length,GnomeVFSURI *uri);
+void mod_uri_load(GnomeVFSURI *uri);
+
+G_END_DECLS
+
+
+#endif /* _CAPTIVE_INSTALL_ACQUIRE_MODURILOAD_H */
diff --git a/src/install/acquire/w32-mod-id.captivemodid.xml b/src/install/acquire/w32-mod-id.captivemodid.xml
new file mode 100644 (file)
index 0000000..70531f5
--- /dev/null
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<modid>
+       <!-- xpsp1_en_x86_chk.exe -->
+       <module type="cabinet"      length="160852568" priority="100" md5="ed5c40cab78513084f9a11cdd3a25361"
+                       id="Windows XP Service Pack 1 Checked Build U.S. Cabinet" />
+       <!-- xpsp1a_en_x86_chk.exe -->
+       <module type="cabinet"      length="151583320" priority="100" md5="257c90b85f20f597caad8a4bd8c481ef"
+                       id="Windows XP Service Pack 1a Checked Build U.S. Cabinet" />
+               <!-- ntoskrnl.exe -->
+               <module type="ntoskrnl.exe" length="3427328"   priority="100" md5="f2935c744335d920c27d6fd47e814863"
+                               id="Windows XP Service Pack 1/1a Checked Build U.S. Kernel" />
+                       <!-- ntoskrnl.ex_ -->
+                       <module type="cabinet"      length="1242123"   priority="100" md5="3981722586e1d399e6b97143e7b1e3e7"
+                                       id="Windows XP Service Pack 1/1a Checked Build U.S. Kernel Cabinet" />
+               <!-- ntfs.sys -->
+               <module type="ntfs.sys"     length="823936"    priority="100" md5="a63ada389d34a9b52ca66872f1d762f2"
+                               id="Windows XP Service Pack 1/1a Checked Build U.S. NTFS Filesystem" />
+               <!-- fastfat.sys -->
+               <module type="fastfat.sys"  length="225408"    priority="100" md5="38ceddcb1de3895ca12893662fcad343"
+                               id="Windows XP Service Pack 1/1a Checked Build U.S. FastFAT/vfat Filesystem" />
+                       <!-- fastfat.sy_ -->
+                       <module type="cabinet"      length="92420"     priority="100" md5="b81ce7d78d3b7d50f694ac4231c7ca79"
+                                       id="Windows XP Service Pack 1/1a Checked Build U.S. FastFAT/vfat Filesystem Cabinet" />
+               <!-- cdfs.sys -->
+               <module type="cdfs.sys"     length="115840"    priority="100" md5="b4c6711edd5ce258f077f019fc4ecdaf"
+                               id="Windows XP Service Pack 1/1a Checked Build U.S. CD-ROM/iso-9660 Filesystem" />
+                       <!-- cdfs.sy_ -->
+                       <module type="cabinet"      length="44369"     priority="100" md5="956eae99b16722d86f6bf46b1dd6f299"
+                                       id="Windows XP Service Pack 1/1a Checked Build U.S. CD-ROM/iso-9660 Filesystem Cabinet" />
+
+       <module type="cabinet"      length="140440152" priority="50"  md5="ecf625f6563dfcaeeecc4b1481899d4b"
+                       id="Windows XP Service Pack 1 Free Build U.S." /><!--     xpsp1_en_x86.exe -->
+       <module type="cabinet"      length="131170400" priority="50"  md5="363af75cf99d554f8c4420448f2e0669"
+                       id="Windows XP Service Pack 1a Free Build U.S." /><!--    xpsp1a_en_x86.exe -->
+               <!-- ntoskrnl.exe -->
+               <module type="ntoskrnl.exe" length="2042240"   priority="50"  md5="b9080d97dbd631aadf9128f7316958d2"
+                               id="Windows XP Service Pack 1/1a Free Build U.S. Kernel" />
+                       <!-- ntoskrnl.ex_ -->
+                       <module type="cabinet"      length="990649"    priority="50"  md5="9545a215e18ee48b3cfe03c7a5ad6c63"
+                                       id="Windows XP Service Pack 1/1a Free Build U.S. Kernel Cabinet" />
+               <!-- ntfs.sys -->
+               <module type="ntfs.sys"     length="561920"    priority="50"  md5="e3ae9c79498210a5f39fe5a9ad62bc55"
+                               id="Windows XP Service Pack 1/1a Free Build U.S. NTFS Filesystem" />
+               <!-- fastfat.sys -->
+               <module type="fastfat.sys"  length="145152"    priority="50"  md5="e4a3a8f3e60b542a747b10e86faa5dad"
+                               id="Windows XP Service Pack 1/1a Free Build U.S. FastFAT/vfat Filesystem" />
+                       <!-- fastfat.sy_ -->
+                       <module type="cabinet"      length="76986"     priority="50"  md5="69732eff28f37b91b020c228987f9e5f"
+                                       id="Windows XP Service Pack 1/1a Free Build U.S. FastFAT/vfat Filesystem Cabinet" />
+               <!-- cdfs.sys -->
+               <module type="cdfs.sys"     length="59648"     priority="50"  md5="049a38451f2611caf2fd528e023a0b5a"
+                               id="Windows XP Service Pack 1/1a Free Build U.S. CD-ROM/iso-9660 Filesystem" />
+                       <!-- cdfs.sy_ -->
+                       <module type="cabinet"      length="32711"     priority="50"  md5="19139b835ca2eb12b2695a3c6cdfe598"
+                                       id="Windows XP Service Pack 1/1a Free Build U.S. CD-ROM/iso-9660 Filesystem Cabinet" />
+
+       <module type="ext2fsd.sys"  length="59514"     priority="50"  md5="8803c8f4c535d6a58606bcd0ff3f77e9"
+                       id="ext2 Filesystem v0.10a by http://sys.xiloo.com" />
+</modid>