2 * W32 disk modules finder for acquiration installation utility
3 * Copyright (C) 2003 Jan Kratochvil <project-captive@jankratochvil.net>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; exactly version 2 of June 1991 is required
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include "moduriload.h" /* self */
23 #include <glib/gmessages.h>
25 #include <glib/ghash.h>
26 #include <glib/glist.h>
27 #include <libgnomevfs/gnome-vfs-uri.h>
28 #include "../libcaptive-install/proc_partitions.h"
31 #include "captivemodid.h"
33 #include <libgnomevfs/gnome-vfs-ops.h>
34 #include <libgnomevfs/gnome-vfs-directory.h>
38 #define MAX_FILE_LOAD_LENGTH 5000000 /* Otherwise use cabextract-over-http. */
41 static void mod_uri_load_module_from_memory
42 (struct captivemodid_module *module,gconstpointer file_base,size_t file_length,GnomeVFSURI *uri)
46 g_return_if_fail(module!=NULL);
47 g_return_if_fail(file_base!=NULL);
48 g_return_if_fail(uri!=NULL);
50 uri_text=gnome_vfs_uri_to_string(uri,GNOME_VFS_URI_HIDE_PASSWORD);
51 g_message("type=%s,id:%s: %s",module->type,module->id,uri_text);
55 void mod_uri_load_file_from_memory(gconstpointer file_base,size_t file_length,GnomeVFSURI *uri)
58 struct captivemodid_module *module;
60 g_return_if_fail(file_base!=NULL);
61 g_return_if_fail(uri!=NULL);
63 file_md5=calc_md5(file_base,file_length);
64 if (!(module=captivemodid_module_md5_lookup(file_md5)))
65 goto fail_free_file_md5;
67 if (strcmp("cabinet",module->type))
68 mod_uri_load_module_from_memory(module,file_base,file_length,uri);
70 struct acquire_cabinet *acquire_cabinet;
71 /* acquire_cabinet_load() will call mod_uri_load_module_from_memory(): */
72 acquire_cabinet=acquire_cabinet_new_from_memory(file_base,file_length,uri);
73 acquire_cabinet_load(acquire_cabinet);
74 acquire_cabinet_free(acquire_cabinet);
81 static void mod_uri_load_file_handle_to_memory(GnomeVFSHandle *handle,GnomeVFSFileInfo *file_info,GnomeVFSURI *uri)
83 guint8 *file_buffer,file_tail_check;
84 GnomeVFSFileSize bytes_read;
85 GnomeVFSResult errvfsresult;
87 g_return_if_fail(handle!=NULL);
88 g_return_if_fail(file_info!=NULL);
89 g_return_if_fail(uri!=NULL);
91 /* gnome_vfs_read_entire_file() reads the file by chunks although
92 * it does not need to know the file size.
94 file_buffer=g_malloc(file_info->size);
96 errvfsresult=gnome_vfs_read(handle,file_buffer,file_info->size,&bytes_read);
97 if (errvfsresult!=GNOME_VFS_OK || bytes_read!=file_info->size)
98 goto fail_free_file_buffer;
99 errvfsresult=gnome_vfs_read(handle,&file_tail_check,1,NULL);
100 if (errvfsresult!=GNOME_VFS_ERROR_EOF)
101 goto fail_free_file_buffer;
102 mod_uri_load_file_from_memory(file_buffer,file_info->size,uri);
104 fail_free_file_buffer:
108 static void mod_uri_load_file_handle_remote_cabinet(GnomeVFSHandle *handle,GnomeVFSFileInfo *file_info,GnomeVFSURI *uri)
110 struct acquire_cabinet *acquire_cabinet;
112 g_return_if_fail(handle!=NULL);
113 g_return_if_fail(file_info!=NULL);
114 g_return_if_fail(uri!=NULL);
116 acquire_cabinet=acquire_cabinet_new_from_handle(handle,file_info,uri);
117 /* acquire_cabinet_load() will call mod_uri_load_module_from_memory(): */
118 acquire_cabinet_load(acquire_cabinet);
119 acquire_cabinet_free(acquire_cabinet);
122 static void mod_uri_load_file(GnomeVFSURI *uri)
124 GnomeVFSResult errvfsresult;
125 GnomeVFSFileInfo file_info_local;
126 GnomeVFSHandle *handle;
128 g_return_if_fail(uri!=NULL);
130 if (GNOME_VFS_OK!=(errvfsresult=gnome_vfs_open_uri(&handle,uri,GNOME_VFS_OPEN_READ)))
132 if (GNOME_VFS_OK!=(errvfsresult=gnome_vfs_get_file_info_from_handle(handle,&file_info_local,GNOME_VFS_FILE_INFO_DEFAULT)))
133 goto fail_close_handle;
134 if (file_info_local.type!=GNOME_VFS_FILE_TYPE_REGULAR) {
135 errvfsresult=GNOME_VFS_ERROR_WRONG_FORMAT;
136 goto fail_close_handle;
138 if (!(file_info_local.valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE)) {
139 errvfsresult=GNOME_VFS_ERROR_WRONG_FORMAT;
140 goto fail_close_handle;
142 if (!captivemodid_module_length_is_valid(file_info_local.size)) {
143 errvfsresult=GNOME_VFS_ERROR_WRONG_FORMAT;
144 goto fail_close_handle;
146 if (file_info_local.size<=MAX_FILE_LOAD_LENGTH)
147 mod_uri_load_file_handle_to_memory(handle,&file_info_local,uri);
149 mod_uri_load_file_handle_remote_cabinet(handle,&file_info_local,uri);
150 errvfsresult=GNOME_VFS_OK;
153 gnome_vfs_close(handle);
157 static gboolean mod_uri_load_directory_visit_func
158 (const gchar *rel_path,GnomeVFSFileInfo *info,gboolean recursing_will_loop,GnomeVFSURI *root_uri /* data */,
161 g_return_val_if_fail(rel_path!=NULL,FALSE);
162 g_return_val_if_fail(info!=NULL,FALSE);
163 g_return_val_if_fail(root_uri!=NULL,FALSE);
164 g_return_val_if_fail(recurse!=NULL,FALSE);
168 switch (info->type) {
169 case GNOME_VFS_FILE_TYPE_REGULAR: {
170 GnomeVFSURI *file_uri;
172 file_uri=gnome_vfs_uri_append_path(root_uri,rel_path);
173 mod_uri_load_file(file_uri);
174 gnome_vfs_uri_unref(file_uri);
176 case GNOME_VFS_FILE_TYPE_DIRECTORY: {
177 GnomeVFSURI *directory_uri;
178 GnomeVFSDirectoryHandle *directory_handle;
180 /* Never set '*recurse' if it would cause 'Access denied' error
181 * as it would completely abort the upper gnome_vfs_directory_visit_uri().
182 * Check the directory accessibility manually:
184 directory_uri=gnome_vfs_uri_append_path(root_uri,rel_path);
185 if (GNOME_VFS_OK==gnome_vfs_directory_open_from_uri(&directory_handle,directory_uri,GNOME_VFS_FILE_INFO_DEFAULT)) {
187 gnome_vfs_directory_close(directory_handle); /* errors ignored */
189 gnome_vfs_uri_unref(directory_uri);
194 return TRUE; /* continue traversal */
197 static void mod_uri_load_directory(GnomeVFSURI *uri)
199 GnomeVFSResult errvfsresult;
201 g_return_if_fail(uri!=NULL);
203 errvfsresult=gnome_vfs_directory_visit_uri(uri,
204 GNOME_VFS_FILE_INFO_DEFAULT, /* info_options */
205 GNOME_VFS_DIRECTORY_VISIT_SAMEFS, /* visit_options; 'GNOME_VFS_DIRECTORY_VISIT_LOOPCHECK'? */
206 (GnomeVFSDirectoryVisitFunc)mod_uri_load_directory_visit_func,
208 if (errvfsresult!=GNOME_VFS_OK) {
211 uri_text=gnome_vfs_uri_to_string(uri,GNOME_VFS_URI_HIDE_PASSWORD);
212 g_warning(_("Error scanning sub-tree of \"%s\": %s"),uri_text,gnome_vfs_result_to_string(errvfsresult));
217 void mod_uri_load(GnomeVFSURI *uri)
219 GnomeVFSFileInfo file_info_local;
220 GnomeVFSResult errvfsresult;
222 g_return_if_fail(uri!=NULL);
224 if (optarg_verbose) {
227 uri_text=gnome_vfs_uri_to_string(uri,GNOME_VFS_URI_HIDE_PASSWORD);
228 g_message(_("Scanning...: %s"),uri_text);
232 file_info_local.type=GNOME_VFS_FILE_TYPE_UNKNOWN;
233 if (GNOME_VFS_OK!=(errvfsresult=gnome_vfs_get_file_info_uri(uri,&file_info_local,GNOME_VFS_FILE_INFO_DEFAULT)))
234 return /* errvfsresult */;
235 switch (file_info_local.type) {
236 case GNOME_VFS_FILE_TYPE_REGULAR: return mod_uri_load_file(uri);
237 case GNOME_VFS_FILE_TYPE_DIRECTORY: return mod_uri_load_directory(uri);
238 default: return /* GNOME_VFS_ERROR_WRONG_FORMAT */;