--- /dev/null
+/* $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 */
+}