From f465ecb2f838388ae77b6271c5e38bf97017fbf8 Mon Sep 17 00:00:00 2001 From: lace <> Date: Mon, 26 Dec 2005 16:44:34 +0000 Subject: [PATCH] Completely rebuild the commandline processing. - It should now mostly match the original LUFS mount.captive(8) behavior. --- src/client/fuse/main.c | 195 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 131 insertions(+), 64 deletions(-) diff --git a/src/client/fuse/main.c b/src/client/fuse/main.c index b805c71..c018808 100644 --- a/src/client/fuse/main.c +++ b/src/client/fuse/main.c @@ -118,15 +118,30 @@ struct fuse *capfuse_fuse; int main(int argc,char **argv) { -poptContext context; -int errint; -int rest_argc,i; +poptContext context=NULL; /* Valid if: opt_o; '= NULL' to shut up GCC. */ +int rest_argc; const char **rest_argv,**csp; struct captive_options options; +int capfuse_argc; 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; +const char *image_filename=NULL; +gboolean opt_n=FALSE; +gboolean opt_v=FALSE; +const char *opt_o=NULL; +const char *mountpoint=NULL; +char **argv_sp; +int opt_o_argc; /* Valid if: opt_o */ +const char **opt_o_argv=NULL; /* Valid if: opt_o */ + +#if 0 +{ +char **sp; + for (sp=argv;*sp;sp++) + fprintf(stderr,"argv: \"%s\"\n",*sp); +} +#endif g_log_set_always_fatal(~(0 |G_LOG_LEVEL_MESSAGE @@ -136,6 +151,74 @@ const char *image_filename; captive_standalone_init(); + argv_sp=argv+1; + if (*argv_sp && (*argv_sp)[0]!='-') + image_filename=*argv_sp++; + if (*argv_sp && (*argv_sp)[0]!='-') + mountpoint=*argv_sp++; + if (*argv_sp && !strcmp(*argv_sp,"-n")) { + opt_n=TRUE; + argv_sp++; + } + if (*argv_sp && !strcmp(*argv_sp,"-v")) { + opt_v=TRUE; + argv_sp++; + } + if (argv_sp[0] && argv_sp[1] && !strcmp(argv_sp[0],"-o")) { + argv_sp++; + opt_o=*argv_sp++; + } + if (*argv_sp) { + /* Lethal path but still give chance for "--help" etc. */ + /* Do not: POPT_CONTEXT_POSIXMEHARDER + * as mount(8) puts there first un-pre-dashed "ro"/"rw" etc. */ + if ((context=poptGetContext( + PACKAGE, /* name */ + argc,(/*en-const*/const char **)argv, /* argc,argv */ + popt_table, /* options */ + 0))) /* flags; && !POPT_CONTEXT_KEEP_FIRST */ + while (0<=poptGetNextOpt(context)); + g_error(_("Excessive argument: %s"),*argv_sp); + } + + if (opt_o) { +char *opt_o_spaced=(char */* de-const; length is not changed */)captive_strdup_alloca(opt_o); +char *s,quote; + + quote=0; + for (s=opt_o_spaced;*s;s++) { + /* Be compatible with: poptParseArgvString() + * which also does not differentiate '"' and "'" */ + if (*s=='\\' && s[1]) { + s++; + continue; + } + if (quote) { + if (*s==quote) + quote=0; + continue; + } + switch (*s) { + case '"': + case '\'': + quote=*s; + continue; + case ',': + *s=' '; + continue; + } + } + if (poptParseArgvString(opt_o_spaced,&opt_o_argc,&opt_o_argv)) + g_error(_("Error splitting arguments of the space-reparsed '-o': %s"),opt_o_spaced); + /* Pre-dash "ro"/"rw" to let libcaptive to be aware of the mode. */ + for (csp=opt_o_argv;*csp;csp++) { + if (!strcmp(*csp,"ro")) + *csp="--ro"; + if (!strcmp(*csp,"rw")) + *csp="--rw"; + } + } + captive_options_init(&options); captive_options=&options; /* for parsing by 'CAPTIVE_POPT_INCLUDE' */ @@ -154,55 +237,32 @@ const char *image_filename; options.syslog_facility=DEFAULT_SYSLOG_FACILITY; - context=poptGetContext( - PACKAGE, /* name */ - argc,(/*en-const*/const char **)argv, /* argc,argv */ - popt_table, /* options */ - POPT_CONTEXT_POSIXMEHARDER); /* flags; && !POPT_CONTEXT_KEEP_FIRST */ - if (context==NULL) { - g_error(_("Error parsing command-line arguments")); - return EXIT_FAILURE; - } - errint=poptReadDefaultConfig(context, - TRUE); /* useEnv */ - if (errint!=0) - g_warning(_("Error reading default popt configuration")); - errint=poptGetNextOpt(context); - if (errint!=-1) { - g_error(_("Error parsing (dash-prefixed) command-line argument")); - return EXIT_FAILURE; + if (opt_o) { + /* Do not: POPT_CONTEXT_POSIXMEHARDER + * as mount(8) puts there first un-pre-dashed "ro"/"rw" etc. */ + if (!(context=poptGetContext( + PACKAGE, /* name */ + opt_o_argc,opt_o_argv, /* argc,argv */ + popt_table, /* options */ + POPT_CONTEXT_KEEP_FIRST))) /* flags */ + g_error(_("Error parsing command-line arguments from pre-parsed '-o': %s"),opt_o); + if (poptReadDefaultConfig(context, + TRUE)) /* useEnv */ + g_warning(_("Error reading default popt configuration")); + while (0<=poptGetNextOpt(context)); + rest_argv=poptGetArgs(context); } - rest_argv=poptGetArgs(context); - for (csp=rest_argv,rest_argc=0;csp && *csp;csp++) + else + rest_argv=NULL; + rest_argc=0; + for (csp=rest_argv;csp && *csp;csp++) rest_argc++; - /* 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++; - } - } + if (!image_filename || !mountpoint) + g_error(_("File/device disk image pathname and mountpoint command-line arguments required")); /* image_iochannel */ - if (rest_argc<1) { - g_error(_("File/device disk image pathname command-line argument required")); - 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( image_filename, /* filename */ (options.rwmode==CAPTIVE_OPTION_RWMODE_RW ? "r+" : "r"), /* mode */ @@ -251,29 +311,36 @@ struct captive_options_module *options_module; captive_options_free(&options); /* Simulate argv[0] there as it got cut by popt. */ - 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; - } + capfuse_argc=4+2*rest_argc; + captive_newn_alloca(capfuse_argv,capfuse_argc+1); + csp=capfuse_argv; + *csp++=argv[0]; + *csp++=mountpoint; + *csp++="-o"; + *csp++=captive_printf_alloca("fsname=%s" LIBFUSE_ADDONS ",%s", + image_filename,(options.rwmode==CAPTIVE_OPTION_RWMODE_RO ? "ro" : "rw")); + if (rest_argv) + while (*rest_argv) { + *csp++="-o"; + *csp++=*rest_argv++; + } + *csp=NULL; +#if 0 +{ +const char **csp; + for (csp=capfuse_argv;*csp;csp++) + fprintf(stderr,"capfuse_argv: \"%s\"\n",*csp); +} +#endif /* FIXFUSE: fuse_main()/fuse_main_real() would be enough for Captive fuse but * the public interface of fuse_main() is too broken. */ - capfuse_run(1+rest_argc,capfuse_argv); + capfuse_run(capfuse_argc,capfuse_argv); /* 'rest_argv' gets cleared by 'poptFreeContext(context);' below */ - poptFreeContext(context); + if (opt_o) + poptFreeContext(context); if (capfuse_captive_vfs_object) { g_object_unref(capfuse_captive_vfs_object); -- 1.8.3.1