2 * lufs interface module vfs objects implementation for libcaptive
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 <glib/gmessages.h>
23 #include "captivefs-misc.h"
25 #include <captive/client-vfs.h>
26 #include <captive/options.h>
27 #include <captive/macros.h>
33 * Here we allocate a structure to hold all the file system local info
34 * (localfs_local). This structure will then be passed as a parameter to
35 * the other functions.
36 * global_ctx holds info about another structure that can be shared between all
37 * instances of the filesystem. If the pointer is NULL, then this is the
38 * first instance and the structure should be allocated.
39 * ! You must implement locking/usage-count/deallocation logic when using
40 * a global context. (locking is omited here)
41 * ! Most filesystems don't need a global context so you can safely ignore the
42 * global_ctx parameter.
44 CaptiveVfsObject *captivefs_init
45 (struct list_head *cfg,struct dir_cache *cache,const struct credentials *cred,void **global_ctx)
47 CaptiveVfsObject *captive_vfs_object;
48 struct captive_options options;
49 GnomeVFSResult errvfsresult;
50 const struct poptOption *cpopt;
56 /* Do not: g_log(G_LOG_DOMAIN,G_LOG_LEVEL_DEBUG,"captivefs_init");
57 * as we do not yet have 'VFS_DEBUG_MESSAGES(captive_vfs_object)' set.
58 * Generally we make all g_log() conditional here as we do not want to mess
59 * with overriden GLog handlers of libcaptive itself.
62 arg_array=g_ptr_array_new();
63 if (!(cgs=lu_opt_getchar(cfg,"MOUNT","fs")))
65 g_ptr_array_add(arg_array,(/* de-const */ char *)cgs);
66 for (cpopt=captive_popt;cpopt->argInfo || cpopt->longName;cpopt++) {
67 const gchar *dashdashname,*value;
71 dashdashname=captive_printf_alloca("--%s",cpopt->longName);
73 && !(value=lu_opt_getchar(cfg,"MOUNT",(/* de-const */ char *)dashdashname))
74 && !(value=lu_opt_getchar(cfg,"MOUNT",(/* de-const */ char *)cpopt->longName)))
76 g_ptr_array_add(arg_array,(/* de-const */ char *)captive_printf_alloca("%s=%s",dashdashname,value));
78 g_ptr_array_add(arg_array,NULL);
79 g_assert(arg_array->len>=2);
80 g_assert(arg_array->pdata[arg_array->len-2]!=NULL);
81 g_assert(arg_array->pdata[arg_array->len-1]==NULL);
83 /* Initialize GObject subsystem of GLib. */
86 captive_options_init(&options);
87 captive_options=&options; /* for parsing by 'CAPTIVE_POPT_INCLUDE' */
89 context=poptGetContext(
91 arg_array->len-1, /* argc */
92 (const char **)arg_array->pdata, /* argv */
93 captive_popt, /* options */
94 POPT_CONTEXT_POSIXMEHARDER); /* flags; && !POPT_CONTEXT_KEEP_FIRST */
96 g_warning("%s: argument recognization args_error","captivefs_init");
97 goto fail_free_options;
99 errint=poptReadDefaultConfig(context,
102 g_warning("%s: argument recognization args_error","captivefs_init");
103 goto fail_free_options;
105 errint=poptGetNextOpt(context);
107 g_warning("%s: some non-callbacked argument reached","captivefs_init");
108 goto fail_free_options;
110 cgs=poptPeekArg(context);
112 g_warning("%s: some non-option argument reached","captivefs_init");
113 goto fail_free_options;
116 captive_options=NULL; /* already parsed by 'CAPTIVE_POPT_INCLUDE' */
118 if (options.debug_messages)
119 g_log(G_LOG_DOMAIN,G_LOG_LEVEL_DEBUG,"captivefs_init");
121 /* image_iochannel */
122 if ((cgs=lu_opt_getchar(cfg,"MOUNT","image"))) {
123 g_assert(options.image_iochannel==NULL);
124 if (!(options.image_iochannel=g_io_channel_new_file(
126 (options.rwmode==CAPTIVE_OPTION_RWMODE_RW ? "r+" : "r"), /* mode */
127 NULL))) { /* error */
128 g_warning(_("%s: image_iochannel open failed"),"captivefs_init");
129 goto fail_free_options;
134 errvfsresult=captive_vfs_new(&captive_vfs_object,&options);
135 G_UNLOCK(libcaptive);
137 if (errvfsresult!=GNOME_VFS_OK)
138 goto fail_unref_image_iochannel;
140 if (options.debug_messages)
141 g_object_set_data(G_OBJECT(captive_vfs_object),"captivefs-debug_messages",captive_vfs_object /* boolean true */);
143 g_object_set_data(G_OBJECT(captive_vfs_object),"captivefs-vfs-image_iochannel",options.image_iochannel);
144 captive_options_free(&options);
145 g_ptr_array_free(arg_array,
146 FALSE); /* free_seg */
148 return captive_vfs_object;
150 fail_unref_image_iochannel:
151 g_io_channel_unref(options.image_iochannel);
153 captive_options_free(&options);
154 /* fail_free_arg_array: */
155 g_ptr_array_free(arg_array,
156 FALSE); /* free_seg */
163 * Check the global context count and free it if necessary.
164 * Deallocate memory and free all resources.
166 void captivefs_free(CaptiveVfsObject *captive_vfs_object)
168 GIOChannel *image_iochannel;
170 g_return_if_fail(CAPTIVE_VFS_IS_OBJECT(captive_vfs_object));
172 if (VFS_DEBUG_MESSAGES(captive_vfs_object))
173 g_log(G_LOG_DOMAIN,G_LOG_LEVEL_DEBUG,"captivefs_free");
175 image_iochannel=g_object_get_data(G_OBJECT(captive_vfs_object),"captivefs-vfs-image_iochannel");
176 g_assert(image_iochannel!=NULL);
177 g_object_set_data(G_OBJECT(captive_vfs_object),"captivefs-vfs-image_iochannel",NULL); /* just a sanity */
178 /* Keep 'image_iochannel' reffed until 'g_object_unref(captive_vfs_object)'. */
181 g_object_unref(captive_vfs_object);
182 G_UNLOCK(libcaptive);
184 g_io_channel_unref(image_iochannel);
188 /* Mount the file system.
189 * Called when a mount operation is performed.
190 * Initialize specific connections, login, etc.
193 * By default, LUFS may attempt multiple connections at once. If your
194 * filesystem doesn't support this, you need to specificy -c 1 on the
195 * lufsmount command line or connections=1 in the mount options.
196 * See ftpfs for an example of how to read configuration options
197 * from a configuration file if you want to, for example, be able to set
200 int captivefs_mount(CaptiveVfsObject *captive_vfs_object)
202 g_return_val_if_fail(CAPTIVE_VFS_IS_OBJECT(captive_vfs_object),0);
204 if (VFS_DEBUG_MESSAGES(captive_vfs_object))
205 g_log(G_LOG_DOMAIN,G_LOG_LEVEL_DEBUG,"captivefs_mount");
207 return 1; /* NEVER return 0 */
211 /* Unmount the file system
212 * Called when the file system is unmounted.
214 void captivefs_umount(CaptiveVfsObject *captive_vfs_object)
216 g_return_if_fail(CAPTIVE_VFS_IS_OBJECT(captive_vfs_object));
218 if (VFS_DEBUG_MESSAGES(captive_vfs_object))
219 g_log(G_LOG_DOMAIN,G_LOG_LEVEL_DEBUG,"captivefs_umount");