Force 'captivemodid' checking during any W32 module loading.
[captive.git] / src / client / fuse / main.c
index 9092e80..b805c71 100644 (file)
 #include <locale.h>
 #include <stdlib.h>
 #include <string.h>
+#include <syslog.h>
 
 #include <captive/client-vfs.h>
 #include <captive/macros.h>
+#include <captive/client.h>
+#include <captive/captivemodid.h>
 
 #include "main.h"      /* self */
 #include "op_statfs.h"
 #include "op_utime.h"
 
 
+/* Config: */
+/* FIXME: Dupe with libcaptive/client/options.c */
+#define DEFAULT_SYSLOG_FACILITY LOG_DAEMON
+/* Each element must be preceded by a comma (',')! */
+#define LIBFUSE_ADDONS ",default_permissions,kernel_cache"
+
+
 CaptiveVfsObject *capfuse_captive_vfs_object;
 
 static const struct poptOption popt_table[]={
@@ -110,10 +120,13 @@ int main(int argc,char **argv)
 {
 poptContext context;
 int errint;
-int rest_argc;
+int rest_argc,i;
 const char **rest_argv,**csp;
 struct captive_options options;
 const char **capfuse_argv;
+const char *program_name=argv[0];
+const char *sandbox_server_argv0=G_STRINGIFY(LIBEXECDIR) "/captive-sandbox-server";
+const char *image_filename;
 
        g_log_set_always_fatal(~(0
                        |G_LOG_LEVEL_MESSAGE
@@ -121,21 +134,26 @@ const char **capfuse_argv;
                        |G_LOG_LEVEL_DEBUG
                        ));
 
-       /* Prevent output block buffering if redirecting stdout to file. */
-       setvbuf(stdout,(char *)NULL,_IONBF,0);
-       setvbuf(stderr,(char *)NULL,_IONBF,0);
-
-       /* Initialize the i18n stuff */
-       setlocale(LC_ALL,"");
-       bindtextdomain(PACKAGE,LOCALEDIR);
-       textdomain(PACKAGE);
-
-       /* Initialize GObject subsystem of GLib. */
-       g_type_init();
+       captive_standalone_init();
 
        captive_options_init(&options);
        captive_options=&options;       /* for parsing by 'CAPTIVE_POPT_INCLUDE' */
 
+       g_assert(!options.sandbox_server_argv);
+       g_assert(!options.sandbox_server_ior);
+       /* captive_options_free(&options) will: g_free(options.sandbox_server_argv); */
+       /* Allocation is so terrible to be compatible with: captive_options_copy() */
+       options.sandbox_server_argv=g_malloc(2*sizeof(*options.sandbox_server_argv)+strlen(sandbox_server_argv0)+1);
+       options.sandbox_server_argv[0]=(char *)(options.sandbox_server_argv+2);
+       options.sandbox_server_argv[1]=NULL;
+       strcpy(options.sandbox_server_argv[0],sandbox_server_argv0);
+       options.sandbox=TRUE;
+
+       g_assert(!options.bug_pathname);
+       options.bug_pathname=g_strdup(G_STRINGIFY(VARLIBCAPTIVEDIR) "/bug-%FT%T.captivebug.xml.gz");
+
+       options.syslog_facility=DEFAULT_SYSLOG_FACILITY;
+
        context=poptGetContext(
                        PACKAGE,        /* name */
                        argc,(/*en-const*/const char **)argv,   /* argc,argv */
@@ -158,7 +176,23 @@ const char **capfuse_argv;
        for (csp=rest_argv,rest_argc=0;csp && *csp;csp++)
                rest_argc++;
 
-       captive_options=NULL;   /* already parsed by 'CAPTIVE_POPT_INCLUDE' */
+       /* Override the (default) Captive options with mount(8) supplied "-o" argument. */
+       /* rest_argv[0] is the device now. */
+       /* rest_argv[1] is the mountpoint now. */
+       if (rest_argc>=4 && !strcmp(rest_argv[2],"-o")) {
+const char *cs=rest_argv[3];
+
+               while (cs&&*cs) {
+                       if ((!strncmp(cs,"ro",2) || !strncmp(cs,"rw",2)) && (cs[2]==',' || !cs[2])) {
+                               if (!strncmp(cs,"ro",2))
+                                       options.rwmode=CAPTIVE_OPTION_RWMODE_RO;
+                               if (!strncmp(cs,"rw",2))
+                                       options.rwmode=CAPTIVE_OPTION_RWMODE_RW;
+                               }
+                       if ((cs=strchr(cs,',')))
+                               cs++;
+                       }
+               }
 
        /* image_iochannel */
        if (rest_argc<1) {
@@ -166,36 +200,73 @@ const char **capfuse_argv;
                return EXIT_FAILURE;
                }
        g_assert(options.image_iochannel==NULL);
+       image_filename=rest_argv[0];
+       rest_argc--;
+       rest_argv++;
        if (!(options.image_iochannel=g_io_channel_new_file(
-                       rest_argv[0],   /* filename */
+                       image_filename, /* filename */
                        (options.rwmode==CAPTIVE_OPTION_RWMODE_RW ? "r+" : "r"),        /* mode */
                        NULL))) {       /* error */
-               g_error(_("image_iochannel open failed"));
+               g_error(_("image_iochannel failed open of: %s"),image_filename);
                return EXIT_FAILURE;
                }
+       
+       if (!options.captivemodid)
+               options.captivemodid=captive_captivemodid_load_default(FALSE);
 
        if (options.filesystem.type==CAPTIVE_OPTIONS_MODULE_TYPE_EMPTY) {
-               g_error(_("'--filesystem' option required ('ntfs.sys' pathname suggested)"));
-               return EXIT_FAILURE;
+const char *self_prefix="mount.captive-";
+size_t self_prefix_len=strlen(self_prefix);
+const char *fsname;
+
+               if ((fsname=strrchr(program_name,'/')))
+                       fsname++;
+               else
+                       fsname=program_name;
+               if (strncmp(fsname,self_prefix,self_prefix_len))
+                       g_error(_("Cannot detected default filesystem name from my basename: %s"),fsname);
+               fsname+=self_prefix_len;
+               if (!captive_options_module_load(&options.filesystem,
+                               captive_printf_alloca("%s/%s.sys",G_STRINGIFY(VARLIBCAPTIVEDIR),fsname)))
+                       g_error(_("'--filesystem' option requires valid pathname ('ntfs.sys' suggested)"));
+               g_assert(options.filesystem.type!=CAPTIVE_OPTIONS_MODULE_TYPE_EMPTY);
                }
        if (!options.load_module) {
-               g_warning(_("'--load-module' option required ('ntoskrnl.exe' pathname suggested)"));
-               return EXIT_FAILURE;
+struct captive_options_module *options_module;
+
+               captive_new(options_module);
+               if (!captive_options_module_load(options_module,G_STRINGIFY(VARLIBCAPTIVEDIR) "/ntoskrnl.exe"))
+                       g_error(_("'--load-module' option requires valid pathname ('ntoskrnl.exe' suggested)"));
+
+               options.load_module=g_list_append(options.load_module,options_module);
                }
 
+       /* It is still required for: captive_options_module_load() */
+       captive_options=NULL;   /* already parsed by 'CAPTIVE_POPT_INCLUDE' */
+
        if (GNOME_VFS_OK!=captive_vfs_new(&capfuse_captive_vfs_object,&options)) {
                g_error(_("captive_vfs_new() failed"));
                return EXIT_FAILURE;
                }
        captive_options_free(&options);
-       rest_argc--;
-       rest_argv++;
 
        /* Simulate argv[0] there as it got cut by popt. */
-       captive_newn_alloca(capfuse_argv,1+rest_argc+1);
+       captive_newn_alloca(capfuse_argv,1+rest_argc+1+2);
        capfuse_argv[0]=argv[0];
        memcpy(capfuse_argv+1,rest_argv,sizeof(*rest_argv)*(rest_argc+1));
 
+       for (i=1;capfuse_argv[i];i++) {
+               if (strcmp(capfuse_argv[i],"-o"))
+                       continue;
+               capfuse_argv[i+1]=captive_printf_alloca("fsname=%s" LIBFUSE_ADDONS  ",%s",image_filename,capfuse_argv[i+1]);
+               break;
+               }
+       if (!capfuse_argv[i]) {
+               capfuse_argv[i  ]="-o";
+               capfuse_argv[i+1]=captive_printf_alloca("fsname=%s" LIBFUSE_ADDONS,image_filename);
+               capfuse_argv[i+2]=NULL;
+               }
+
        /* FIXFUSE: fuse_main()/fuse_main_real() would be enough for Captive fuse but
         * the public interface of fuse_main() is too broken.
         */