--- /dev/null
+/* $Id$
+ * client FUSE interface for libcaptive
+ * Copyright (C) 2005 Jan Kratochvil <project-captive@jankratochvil.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; exactly version 2 of June 1991 is required
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include "config.h"
+
+#include <fuse.h>
+#include <popt.h>
+#include <locale.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <captive/client-vfs.h>
+#include <captive/macros.h>
+
+#include "main.h" /* self */
+#include "op_statfs.h"
+#include "op_fsync.h"
+#include "op_fsyncdir.h"
+
+
+CaptiveVfsObject *capfuse_captive_vfs_object;
+
+static const struct poptOption popt_table[]={
+ CAPTIVE_POPT_INCLUDE,
+ POPT_AUTOHELP
+ POPT_TABLEEND
+ };
+
+static const struct fuse_operations capfuse_operations={
+ statfs: op_statfs,
+ fsync: op_fsync,
+ fsyncdir: op_fsyncdir,
+#if 0
+ getattr: op_getattr,
+ mknod: op_mknod,
+ mkdir: op_mkdir,
+ unlink: op_unlink,
+ rmdir: op_rmdir,
+ rename: op_rename,
+ chmod: op_chmod,
+ truncate: op_truncate,
+ utime: op_utime,
+ open: op_open,
+ read: op_read,
+ write: op_write,
+ flush: op_flush,
+ release: op_release,
+ opendir: op_opendir,
+ readdir: op_readdir,
+ releasedir: op_releasedir,
+#endif
+ };
+
+/* argv[0] expected as the program name. */
+/* Only options and mountpoint expected here. */
+static void capfuse_run(int argc,const char **argv)
+{
+char *capfuse_mountpoint;
+int capfuse_multithreaded,capfuse_fd;
+struct fuse *capfuse_fuse;
+
+ if (!(capfuse_fuse=fuse_setup(
+ argc, /* argc */
+ (/*de-const; broken fuset_setup()*/char **)argv, /* argv */
+ &capfuse_operations, /* op */
+ sizeof(capfuse_operations), /* op_size */
+ &capfuse_mountpoint, /* mountpoint */
+ &capfuse_multithreaded, /* multithreaded */
+ &capfuse_fd))) /* fd */
+ g_error(_("FUSE fuse_setup() failed"));
+ if (fuse_loop(capfuse_fuse))
+ g_error(_("FUSE fuse_loop() error: %m"));
+ fuse_teardown(capfuse_fuse,capfuse_fd,capfuse_mountpoint);
+}
+
+int main(int argc,char **argv)
+{
+poptContext context;
+int errint;
+int rest_argc;
+const char **rest_argv,**csp;
+struct captive_options options;
+const char **capfuse_argv;
+
+ g_log_set_always_fatal(~(0
+ |G_LOG_LEVEL_MESSAGE
+ |G_LOG_LEVEL_INFO
+ |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_options_init(&options);
+ captive_options=&options; /* for parsing by 'CAPTIVE_POPT_INCLUDE' */
+
+ 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;
+ }
+ rest_argv=poptGetArgs(context);
+ for (csp=rest_argv,rest_argc=0;csp && *csp;csp++)
+ rest_argc++;
+
+ captive_options=NULL; /* already parsed by 'CAPTIVE_POPT_INCLUDE' */
+
+ /* 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);
+ if (!(options.image_iochannel=g_io_channel_new_file(
+ rest_argv[0], /* filename */
+ (options.rwmode==CAPTIVE_OPTION_RWMODE_RW ? "r+" : "r"), /* mode */
+ NULL))) { /* error */
+ g_error(_("image_iochannel open failed"));
+ return EXIT_FAILURE;
+ }
+
+ if (options.filesystem.type==CAPTIVE_OPTIONS_MODULE_TYPE_EMPTY) {
+ g_error(_("'--filesystem' option required ('ntfs.sys' pathname suggested)"));
+ return EXIT_FAILURE;
+ }
+ if (!options.load_module) {
+ g_warning(_("'--load-module' option required ('ntoskrnl.exe' pathname suggested)"));
+ return EXIT_FAILURE;
+ }
+
+ 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);
+ capfuse_argv[0]=argv[0];
+ memcpy(capfuse_argv+1,rest_argv,sizeof(*rest_argv)*(rest_argc+1));
+
+ /* 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);
+
+ /* 'rest_argv' gets cleared by 'poptFreeContext(context);' below */
+ poptFreeContext(context);
+
+ if (capfuse_captive_vfs_object) {
+ g_object_unref(capfuse_captive_vfs_object);
+ capfuse_captive_vfs_object=NULL;
+ }
+
+ return EXIT_SUCCESS;
+}