Make all g_log()s conditional on --debug-messages.
[captive.git] / src / client / lufs / captivefs-vfs.c
1 /* $Id$
2  * lufs interface module vfs objects implementation for libcaptive
3  * Copyright (C) 2003 Jan Kratochvil <project-captive@jankratochvil.net>
4  * 
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
8  * 
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.
13  * 
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
17  */
18
19
20 #include "config.h"
21
22 #include <glib/gmessages.h>
23 #include "captivefs-misc.h"
24
25 #include <captive/client-vfs.h>
26 #include <captive/options.h>
27 #include <captive/macros.h>
28
29 #include <lufs/fs.h>
30
31
32 /* Initialization
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.  
43  */
44 CaptiveVfsObject *captivefs_init
45                 (struct list_head *cfg,struct dir_cache *cache,const struct credentials *cred,void **global_ctx)
46 {
47 CaptiveVfsObject *captive_vfs_object;
48 struct captive_options options;
49 GnomeVFSResult errvfsresult;
50 const struct poptOption *cpopt;
51 GPtrArray *arg_array;
52 const gchar *cgs;
53 poptContext context;
54 int errint;
55
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.
60          */
61
62         arg_array=g_ptr_array_new();
63         if (!(cgs=lu_opt_getchar(cfg,"MOUNT","fs")))
64                 cgs="captivefs";
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;
68
69                 if (!cpopt->longName)
70                         continue;
71                 dashdashname=captive_printf_alloca("--%s",cpopt->longName);
72                 if (1
73                                 && !(value=lu_opt_getchar(cfg,"MOUNT",(/* de-const */ char *)dashdashname))
74                                 && !(value=lu_opt_getchar(cfg,"MOUNT",(/* de-const */ char *)cpopt->longName)))
75                         continue;
76                 g_ptr_array_add(arg_array,(/* de-const */ char *)captive_printf_alloca("%s=%s",dashdashname,value));
77                 }
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);
82
83         /* Initialize GObject subsystem of GLib. */
84         g_type_init();
85
86         captive_options_init(&options);
87         captive_options=&options;       /* for parsing by 'CAPTIVE_POPT_INCLUDE' */
88
89         context=poptGetContext(
90                         PACKAGE,        /* name */
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 */
95         if (context==NULL) {
96                 g_warning("%s: argument recognization args_error","captivefs_init");
97                 goto fail_free_options;
98                 }
99         errint=poptReadDefaultConfig(context,
100                         TRUE);  /* useEnv */
101         if (errint!=0) {
102                 g_warning("%s: argument recognization args_error","captivefs_init");
103                 goto fail_free_options;
104                 }
105         errint=poptGetNextOpt(context);
106         if (errint!=-1) {
107                 g_warning("%s: some non-callbacked argument reached","captivefs_init");
108                 goto fail_free_options;
109                 }
110         cgs=poptPeekArg(context);
111         if (cgs) {
112                 g_warning("%s: some non-option argument reached","captivefs_init");
113                 goto fail_free_options;
114                 }
115
116         captive_options=NULL;   /* already parsed by 'CAPTIVE_POPT_INCLUDE' */
117
118         if (options.debug_messages)
119                 g_log(G_LOG_DOMAIN,G_LOG_LEVEL_DEBUG,"captivefs_init");
120
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(
125                                 cgs,    /* filename */
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;
130                         }
131                 }
132
133         G_LOCK(libcaptive);
134         errvfsresult=captive_vfs_new(&captive_vfs_object,&options);
135         G_UNLOCK(libcaptive);
136
137         if (errvfsresult!=GNOME_VFS_OK)
138                 goto fail_unref_image_iochannel;
139
140         if (options.debug_messages)
141                 g_object_set_data(G_OBJECT(captive_vfs_object),"captivefs-debug_messages",captive_vfs_object /* boolean true */);
142
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 */
147
148         return captive_vfs_object;
149
150 fail_unref_image_iochannel:
151         g_io_channel_unref(options.image_iochannel);
152 fail_free_options:
153         captive_options_free(&options);
154 /* fail_free_arg_array: */
155         g_ptr_array_free(arg_array,
156                         FALSE); /* free_seg */
157 /* fail: */
158         return NULL;
159 }
160
161
162 /* Cleanup
163  * Check the global context count and free it if necessary.
164  * Deallocate memory and free all resources.
165  */
166 void captivefs_free(CaptiveVfsObject *captive_vfs_object)
167 {
168 GIOChannel *image_iochannel;
169
170         g_return_if_fail(CAPTIVE_VFS_IS_OBJECT(captive_vfs_object));
171
172         if (VFS_DEBUG_MESSAGES(captive_vfs_object))
173                 g_log(G_LOG_DOMAIN,G_LOG_LEVEL_DEBUG,"captivefs_free");
174
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)'. */
179
180         G_LOCK(libcaptive);
181         g_object_unref(captive_vfs_object);
182         G_UNLOCK(libcaptive);
183
184         g_io_channel_unref(image_iochannel);
185 }
186
187
188 /* Mount the file system.
189  * Called when a mount operation is performed.
190  * Initialize specific connections, login, etc.
191  *
192  * Notes:
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
198  * default values.
199  */
200 int captivefs_mount(CaptiveVfsObject *captive_vfs_object)
201 {
202         g_return_val_if_fail(CAPTIVE_VFS_IS_OBJECT(captive_vfs_object),0);
203     
204         if (VFS_DEBUG_MESSAGES(captive_vfs_object))
205                 g_log(G_LOG_DOMAIN,G_LOG_LEVEL_DEBUG,"captivefs_mount");
206
207         return 1;       /* NEVER return 0 */
208 }
209
210
211 /* Unmount the  file system
212  * Called when the file system is unmounted.
213  */
214 void captivefs_umount(CaptiveVfsObject *captive_vfs_object)
215 {
216         g_return_if_fail(CAPTIVE_VFS_IS_OBJECT(captive_vfs_object));
217
218         if (VFS_DEBUG_MESSAGES(captive_vfs_object))
219                 g_log(G_LOG_DOMAIN,G_LOG_LEVEL_DEBUG,"captivefs_umount");
220 }