+LUFS (Linux User File System) module to be Linux kernel filesystem
[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         g_log(G_LOG_DOMAIN,G_LOG_LEVEL_DEBUG,"captivefs_init");
57
58         arg_array=g_ptr_array_new();
59         if (!(cgs=lu_opt_getchar(cfg,"MOUNT","fs")))
60                 cgs="captivefs";
61         g_ptr_array_add(arg_array,(/* de-const */ char *)cgs);
62         for (cpopt=captive_popt;cpopt->argInfo || cpopt->longName;cpopt++) {
63 const gchar *dashdashname,*value;
64
65                 if (!cpopt->longName)
66                         continue;
67                 dashdashname=captive_printf_alloca("--%s",cpopt->longName);
68                 if (1
69                                 && !(value=lu_opt_getchar(cfg,"MOUNT",(/* de-const */ char *)dashdashname))
70                                 && !(value=lu_opt_getchar(cfg,"MOUNT",(/* de-const */ char *)cpopt->longName)))
71                         continue;
72                 g_ptr_array_add(arg_array,(/* de-const */ char *)captive_printf_alloca("%s=%s",dashdashname,value));
73                 }
74         g_ptr_array_add(arg_array,NULL);
75         g_assert(arg_array->len>=2);
76         g_assert(arg_array->pdata[arg_array->len-2]!=NULL);
77         g_assert(arg_array->pdata[arg_array->len-1]==NULL);
78
79         /* Initialize GObject subsystem of GLib. */
80         g_type_init();
81
82         captive_options_init(&options);
83         captive_options=&options;       /* for parsing by 'CAPTIVE_POPT_INCLUDE' */
84
85         context=poptGetContext(
86                         PACKAGE,        /* name */
87                         arg_array->len-1,       /* argc */
88                         (const char **)arg_array->pdata,        /* argv */
89                         captive_popt,   /* options */
90                         POPT_CONTEXT_POSIXMEHARDER);    /* flags; && !POPT_CONTEXT_KEEP_FIRST */
91         if (context==NULL) {
92                 g_warning("%s: argument recognization args_error","captivefs_init");
93                 goto fail_free_options;
94                 }
95         errint=poptReadDefaultConfig(context,
96                         TRUE);  /* useEnv */
97         if (errint!=0) {
98                 g_warning("%s: argument recognization args_error","captivefs_init");
99                 goto fail_free_options;
100                 }
101         errint=poptGetNextOpt(context);
102         if (errint!=-1) {
103                 g_warning("%s: some non-callbacked argument reached","captivefs_init");
104                 goto fail_free_options;
105                 }
106         cgs=poptPeekArg(context);
107         if (cgs) {
108                 g_warning("%s: some non-option argument reached","captivefs_init");
109                 goto fail_free_options;
110                 }
111
112         captive_options=NULL;   /* already parsed by 'CAPTIVE_POPT_INCLUDE' */
113
114         /* image_iochannel */
115         if ((cgs=lu_opt_getchar(cfg,"MOUNT","image"))) {
116                 g_assert(options.image_iochannel==NULL);
117                 if (!(options.image_iochannel=g_io_channel_new_file(
118                                 cgs,    /* filename */
119                                 (options.rwmode==CAPTIVE_OPTION_RWMODE_RW ? "r+" : "r"),        /* mode */
120                                 NULL))) {       /* error */
121                         g_warning(_("%s: image_iochannel open failed"),"captivefs_init");
122                         goto fail_free_options;
123                         }
124                 }
125
126         G_LOCK(libcaptive);
127         errvfsresult=captive_vfs_new(&captive_vfs_object,&options);
128         G_UNLOCK(libcaptive);
129
130         if (errvfsresult!=GNOME_VFS_OK)
131                 goto fail_unref_image_iochannel;
132
133         g_object_set_data(G_OBJECT(captive_vfs_object),"captivefs-vfs-image_iochannel",options.image_iochannel);
134         captive_options_free(&options);
135         g_ptr_array_free(arg_array,
136                         FALSE); /* free_seg */
137
138         return captive_vfs_object;
139
140 fail_unref_image_iochannel:
141         g_io_channel_unref(options.image_iochannel);
142 fail_free_options:
143         captive_options_free(&options);
144 /* fail_free_arg_array: */
145         g_ptr_array_free(arg_array,
146                         FALSE); /* free_seg */
147 /* fail: */
148         return NULL;
149 }
150
151
152 /* Cleanup
153  * Check the global context count and free it if necessary.
154  * Deallocate memory and free all resources.
155  */
156 void captivefs_free(CaptiveVfsObject *captive_vfs_object)
157 {
158 GIOChannel *image_iochannel;
159
160         g_return_if_fail(CAPTIVE_VFS_IS_OBJECT(captive_vfs_object));
161
162         g_log(G_LOG_DOMAIN,G_LOG_LEVEL_DEBUG,"captivefs_free");
163
164         image_iochannel=g_object_get_data(G_OBJECT(captive_vfs_object),"captivefs-vfs-image_iochannel");
165         g_assert(image_iochannel!=NULL);
166         g_object_set_data(G_OBJECT(captive_vfs_object),"captivefs-vfs-image_iochannel",NULL);   /* just a sanity */
167         /* Keep 'image_iochannel' reffed until 'g_object_unref(captive_vfs_object)'. */
168
169         G_LOCK(libcaptive);
170         g_object_unref(captive_vfs_object);
171         G_UNLOCK(libcaptive);
172
173         g_io_channel_unref(image_iochannel);
174 }
175
176
177 /* Mount the file system.
178  * Called when a mount operation is performed.
179  * Initialize specific connections, login, etc.
180  *
181  * Notes:
182  *     By default, LUFS may attempt multiple connections at once.  If your
183  * filesystem doesn't support this, you need to specificy -c 1 on the
184  * lufsmount command line or connections=1 in the mount options.
185  *     See ftpfs for an example of how to read configuration options
186  * from a configuration file if you want to, for example, be able to set
187  * default values.
188  */
189 int captivefs_mount(CaptiveVfsObject *captive_vfs_object)
190 {
191         g_return_val_if_fail(CAPTIVE_VFS_IS_OBJECT(captive_vfs_object),0);
192     
193         g_log(G_LOG_DOMAIN,G_LOG_LEVEL_DEBUG,"captivefs_mount");
194
195         return 1;       /* NEVER return 0 */
196 }
197
198
199 /* Unmount the  file system
200  * Called when the file system is unmounted.
201  */
202 void captivefs_umount(CaptiveVfsObject *captive_vfs_object)
203 {
204         g_return_if_fail(CAPTIVE_VFS_IS_OBJECT(captive_vfs_object));
205
206         g_log(G_LOG_DOMAIN,G_LOG_LEVEL_DEBUG,"captivefs_umount");
207 }