X-Git-Url: http://git.annexia.org/?a=blobdiff_plain;f=fuse%2Fguestmount.c;h=8fe91220021284ca75bf061a9fca9b7982614536;hb=4beb2844091310012b5e28971707397d1d51d833;hp=068f7ded6116e9f16eae9fc4d2da353a6a720115;hpb=c66d6f215e8303d4eaf8ccfdb6a58cff04ccc485;p=libguestfs.git diff --git a/fuse/guestmount.c b/fuse/guestmount.c index 068f7de..8fe9122 100644 --- a/fuse/guestmount.c +++ b/fuse/guestmount.c @@ -61,43 +61,15 @@ guestfs_h *g = NULL; int read_only = 0; int verbose = 0; int inspector = 0; +int keys_from_stdin = 0; +int echo_keys = 0; const char *libvirt_uri; int dir_cache_timeout = 60; -/* This is ugly: guestfs errors are strings, FUSE wants -errno. We - * have to do the conversion as best we can. - */ -#define MAX_ERRNO 256 - static int error (void) { - int i; - const char *err = guestfs_last_error (g); - - if (!err) - return -EINVAL; - - if (verbose) - fprintf (stderr, "%s\n", err); - - /* Add a few of our own ... */ - - /* This indicates guestfsd died. Translate into a hard EIO error. - * Arguably we could relaunch the guest if we hit this error. - */ - if (strstr (err, "call launch before using this function")) - return -EIO; - - /* See if it matches an errno string in the host. */ - for (i = 0; i < MAX_ERRNO; ++i) { - const char *e = strerror (i); - if (e && strstr (err, e) != NULL) - return -i; - } - - /* Too bad, return a generic error. */ - return -EINVAL; + return -guestfs_last_errno (g); } static struct guestfs_xattr_list * @@ -563,53 +535,16 @@ fg_utimens (const char *path, const struct timespec ts[2]) return 0; } -/* This call is quite hard to emulate through the guestfs(3) API. In - * one sense it's a little like access (see above) because it tests - * whether opening a file would succeed given the flags. But it also - * has side effects such as truncating the file if O_TRUNC is given. - * Therefore we need to emulate it ... painfully. +/* All this function needs to do is to check that the requested open + * flags are valid. See the notes in . */ static int fg_open (const char *path, struct fuse_file_info *fi) { - int r, exists; - - if (fi->flags & O_WRONLY) { - if (read_only) - return -EROFS; - } - - exists = guestfs_exists (g, path); - if (exists == -1) - return error (); - - if (fi->flags & O_CREAT) { - if (read_only) - return -EROFS; - - dir_cache_invalidate (path); - - /* Exclusive? File must not exist already. */ - if (fi->flags & O_EXCL) { - if (exists) - return -EEXIST; - } - - /* Create? Touch it and optionally truncate it. */ - r = guestfs_touch (g, path); - if (r == -1) - return error (); + int flags = fi->flags & 3; - if (fi->flags & O_TRUNC) { - r = guestfs_truncate (g, path); - if (r == -1) - return error (); - } - } else { - /* Not create, just check it exists. */ - if (!exists) - return -ENOENT; - } + if (read_only && flags != O_RDONLY) + return -EROFS; return 0; } @@ -880,10 +815,12 @@ usage (int status) " -c|--connect uri Specify libvirt URI for -d option\n" " --dir-cache-timeout Set readdir cache timeout (default 5 sec)\n" " -d|--domain guest Add disks from libvirt guest\n" + " --echo-keys Don't turn off echo for passphrases\n" " --format[=raw|..] Force disk format for -a option\n" " --fuse-help Display extra FUSE options\n" " -i|--inspector Automatically mount filesystems\n" " --help Display help message and exit\n" + " --keys-from-stdin Read passphrases from stdin\n" " -m|--mount dev[:mnt] Mount dev on mnt (if omitted, /)\n" " -n|--no-sync Don't autosync\n" " -o|--option opt Pass extra option to FUSE\n" @@ -910,20 +847,23 @@ main (int argc, char *argv[]) /* The command line arguments are broadly compatible with (a subset * of) guestfish. Thus we have to deal mainly with -a, -m and --ro. */ - static const char *options = "a:c:d:im:no:rv?Vx"; + static const char *options = "a:c:d:im:no:rv?Vwx"; static const struct option long_options[] = { { "add", 1, 0, 'a' }, { "connect", 1, 0, 'c' }, { "dir-cache-timeout", 1, 0, 0 }, { "domain", 1, 0, 'd' }, + { "echo-keys", 0, 0, 0 }, { "format", 2, 0, 0 }, { "fuse-help", 0, 0, 0 }, { "help", 0, 0, HELP_OPTION }, { "inspector", 0, 0, 'i' }, + { "keys-from-stdin", 0, 0, 0 }, { "mount", 1, 0, 'm' }, { "no-sync", 0, 0, 'n' }, { "option", 1, 0, 'o' }, { "ro", 0, 0, 'r' }, + { "rw", 0, 0, 'w' }, { "selinux", 0, 0, 0 }, { "trace", 0, 0, 'x' }, { "verbose", 0, 0, 'v' }, @@ -1015,8 +955,11 @@ main (int argc, char *argv[]) format = NULL; else format = optarg; - } - else { + } else if (STREQ (long_options[option_index].name, "keys-from-stdin")) { + keys_from_stdin = 1; + } else if (STREQ (long_options[option_index].name, "echo-keys")) { + echo_keys = 1; + } else { fprintf (stderr, _("%s: unknown long option: %s (%d)\n"), program_name, long_options[option_index].name, option_index); exit (EXIT_FAILURE); @@ -1064,6 +1007,10 @@ main (int argc, char *argv[]) OPTION_V; break; + case 'w': + OPTION_w; + break; + case 'x': OPTION_x; ADD_FUSE_ARG ("-f");