From 47ed703a8554a934e19a81da91a6fa9892e9aaf3 Mon Sep 17 00:00:00 2001 From: Nikias Bassen Date: Sun, 14 Jun 2009 02:53:04 +0200 Subject: [PATCH] Better option handling, added usage info, --uuid=, and uid= parameter. --- src/ifuse.c | 130 ++++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 files changed, 111 insertions(+), 19 deletions(-) diff --git a/src/ifuse.c b/src/ifuse.c index 0aac298..93181cb 100644 --- a/src/ifuse.c +++ b/src/ifuse.c @@ -43,6 +43,29 @@ iphone_lckd_client_t control = NULL; int debug = 0; +static struct { + char *mount_point; + char *device_file; + char *device_uuid; + int uid_given; +} opts; + +enum { + KEY_HELP = 1, + KEY_ROOT, + KEY_UUID, + KEY_UID +}; + +static struct fuse_opt ifuse_opts[] = { + FUSE_OPT_KEY("--help", KEY_HELP), + FUSE_OPT_KEY("-h", KEY_HELP), + FUSE_OPT_KEY("--uuid=", KEY_UUID), + FUSE_OPT_KEY("--root", KEY_ROOT), + FUSE_OPT_KEY("uid=", KEY_UID), + FUSE_OPT_END +}; + static int ifuse_getattr(const char *path, struct stat *stbuf) { int res = 0; @@ -368,51 +391,120 @@ static struct fuse_operations ifuse_oper = { .destroy = ifuse_cleanup }; +static void usage() +{ + puts( +"\n" +"Usage: mount.fuse.ifuse OPTIONS\n" +"\n" +" device file (currently not used, so just pass 'none')\n" +" mount point where the file system should be mounted\n" +"\n" +" OPTIONS --uuid=UUID | --root | -o fuse_option[,...]\n" +"\n" +" --uuid=UUID 40-digit device UUID of the device to connect to\n" +" --root mount the root file system instead of the default jail\n" +" (a jailbroken device is required for this to work)\n" +" -o uid=N set file owner to user id N\n" +"\n" +" Example:\n" +" mount.fuse.ifuse none /media/iPhone -ouid=1000\n" +"\n"); + exit(0); +} + static int ifuse_opt_proc(void *data, const char *arg, int key, struct fuse_args *outargs) { char *tmp; static int option_num = 0; - (void) data; + int res = 1; switch (key) { + case KEY_UUID: + opts.device_uuid = strdup(arg+7); + res = 0; + break; + case KEY_UID: + // we need to check this because if specified, we need to + // chown the mount point accordingly. Don't return 0 as + // fuse_main should also get this option. + opts.uid_given = strtol(arg+4, NULL, 10); + break; + case KEY_ROOT: + ifuse_oper.init = ifuse_init_jailbroken; + res = 0; + break; + case KEY_HELP: + usage(); + res = 0; + break; case FUSE_OPT_KEY_OPT: - if (strcmp(arg, "allow_other") == 0 || strcmp(arg, "-d") == 0 || strcmp(arg, "-s") == 0) - return 1; - else if (strcmp(arg, "--root") == 0) { - ifuse_oper.init = ifuse_init_jailbroken; - return 0; - } else - return 0; + // ignore other options and pass them to fuse_main break; case FUSE_OPT_KEY_NONOPT: + if (option_num == 0) { + opts.device_file = strdup(arg); + res = 0; // do not pass as fuse option + } else if (option_num == 1) { + opts.mount_point = strdup(arg); + } option_num++; - - // Throw the first nameless option away (the mountpoint) - if (option_num == 1) - return 0; - else - return 1; + break; } - return 1; + return res; } int main(int argc, char *argv[]) { char **ammended_argv; - int i, j; struct fuse_args args = FUSE_ARGS_INIT(argc, argv); + struct stat mst; + + memset(&opts, 0, sizeof(opts)); - if (fuse_opt_parse(&args, NULL, NULL, ifuse_opt_proc) == -1) { + if (fuse_opt_parse(&args, NULL, ifuse_opts, ifuse_opt_proc) == -1) { return -1; } fuse_opt_add_arg(&args, "-oallow_other"); - if (argc < 2) { + if (!opts.device_file) { fprintf(stderr, "A path to the USB device must be specified\n"); return -1; } - iphone_get_device(&phone); + if (!opts.mount_point) { + fprintf(stderr, "Error: No mount point specified\n"); + return -1; + } + + if (opts.device_uuid && strlen(opts.device_uuid) != 40) { + fprintf(stderr, "Invalid device UUID specified, length needs to be 40 characters\n"); + return -1; + } + + if (stat(opts.mount_point, &mst) < 0) { + if (errno == ENOENT) { + fprintf(stderr, "Error: the mount point specified does not exist\n"); + return -1; + } + + fprintf(stderr, "There was an error accessing the mount point: %s\n", strerror(errno)); + return -1; + } + + if (opts.uid_given > 0) { + printf("opts.uid_given=%d\n", opts.uid_given); + // change the owner, keep the group + if (chown(opts.mount_point, opts.uid_given, mst.st_gid) < 0) { + fprintf(stderr, "WARNING: chown: %s\n", strerror(errno)); + } + } + + if (opts.device_uuid) { + iphone_get_device_by_uuid(&phone, opts.device_uuid); + } else { + iphone_get_device(&phone); + } if (!phone) { fprintf(stderr, "No iPhone found, is it connected?\n"); fprintf(stderr, "If it is make sure that your user has permissions to access the raw usb device.\n"); -- 1.6.0.4