/* guestmount - mount guests using libguestfs and FUSE
- * Copyright (C) 2009-2010 Red Hat Inc.
+ * Copyright (C) 2009-2011 Red Hat Inc.
*
* 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
#include <sys/time.h>
#include <sys/types.h>
#include <locale.h>
+#include <libintl.h>
#include <fuse.h>
#include <guestfs.h>
guestfs_h *g = NULL;
int read_only = 0;
+int live = 0;
int verbose = 0;
int inspector = 0;
int keys_from_stdin = 0;
free_attrs = 1;
}
+ /* Find the matching attribute (index in 'i'). */
+ ssize_t r;
size_t i;
- int r = -ENOATTR;
for (i = 0; i < xattrs->len; ++i) {
- if (STREQ (xattrs->val[i].attrname, name)) {
- size_t sz = xattrs->val[i].attrval_len;
- if (sz > size)
- sz = size;
- memcpy (value, xattrs->val[i].attrval, sz);
- r = 0;
+ if (STREQ (xattrs->val[i].attrname, name))
break;
- }
}
+ if (i == xattrs->len) { /* not found */
+ r = -ENOATTR;
+ goto out;
+ }
+
+ /* The getxattr man page is unclear, but if value == NULL then we
+ * return the space required (the caller then makes a second syscall
+ * after allocating the required amount of space). If value != NULL
+ * then it's not clear what we should do, but it appears we should
+ * copy as much as possible and return -ERANGE if there's not enough
+ * space in the buffer.
+ */
+ size_t sz = xattrs->val[i].attrval_len;
+ if (value == NULL) {
+ r = sz;
+ goto out;
+ }
+
+ if (sz <= size)
+ r = sz;
+ else {
+ r = -ERANGE;
+ sz = size;
+ }
+ memcpy (value, xattrs->val[i].attrval, sz);
+
+out:
if (free_attrs)
guestfs_free_xattr_list ((struct guestfs_xattr_list *) xattrs);
free_attrs = 1;
}
+ /* Calculate how much space is required to hold the result. */
+ size_t space = 0;
+ size_t len;
size_t i;
- ssize_t copied = 0;
for (i = 0; i < xattrs->len; ++i) {
- size_t len = strlen (xattrs->val[i].attrname) + 1;
+ len = strlen (xattrs->val[i].attrname) + 1;
+ space += len;
+ }
+
+ /* The listxattr man page is unclear, but if list == NULL then we
+ * return the space required (the caller then makes a second syscall
+ * after allocating the required amount of space). If list != NULL
+ * then it's not clear what we should do, but it appears we should
+ * copy as much as possible and return -ERANGE if there's not enough
+ * space in the buffer.
+ */
+ ssize_t r;
+ if (list == NULL) {
+ r = space;
+ goto out;
+ }
+
+ r = 0;
+ for (i = 0; i < xattrs->len; ++i) {
+ len = strlen (xattrs->val[i].attrname) + 1;
if (size >= len) {
memcpy (list, xattrs->val[i].attrname, len);
size -= len;
list += len;
- copied += len;
+ r += len;
} else {
- copied = -ERANGE;
+ r = -ERANGE;
break;
}
}
+ out:
if (free_attrs)
guestfs_free_xattr_list ((struct guestfs_xattr_list *) xattrs);
- return copied;
+ return r;
}
static int
" -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"
+ " --live Connect to a live virtual machine\n"
+ " -m|--mount dev[:mnt[:opts]] Mount dev on mnt (if omitted, /)\n"
" -n|--no-sync Don't autosync\n"
" -o|--option opt Pass extra option to FUSE\n"
" -r|--ro Mount read-only\n"
" --selinux Enable SELinux support\n"
" -v|--verbose Verbose messages\n"
" -V|--version Display version and exit\n"
+ " -w|--rw Mount read-write\n"
" -x|--trace Trace guestfs API calls\n"
),
program_name, program_name, program_name);
bindtextdomain (PACKAGE, LOCALEBASEDIR);
textdomain (PACKAGE);
+ parse_config ();
+
enum { HELP_OPTION = CHAR_MAX + 1 };
/* The command line arguments are broadly compatible with (a subset
{ "help", 0, 0, HELP_OPTION },
{ "inspector", 0, 0, 'i' },
{ "keys-from-stdin", 0, 0, 0 },
+ { "live", 0, 0, 0 },
{ "mount", 1, 0, 'm' },
{ "no-sync", 0, 0, 'n' },
{ "option", 1, 0, 'o' },
*/
ADD_FUSE_ARG ("-s");
- /* If developing, add ./appliance to the path. Note that libtools
- * interferes with this because uninstalled guestfish is a shell
- * script that runs the real program with an absolute path. Detect
- * that too.
- *
- * BUT if LIBGUESTFS_PATH environment variable is already set by
- * the user, then don't override it.
- */
- if (getenv ("LIBGUESTFS_PATH") == NULL &&
- argv[0] &&
- (argv[0][0] != '/' || strstr (argv[0], "/.libs/lt-") != NULL))
- guestfs_set_path (g, "appliance:" GUESTFS_DEFAULT_PATH);
-
for (;;) {
c = getopt_long (argc, argv, options, long_options, &option_index);
if (c == -1) break;
keys_from_stdin = 1;
} else if (STREQ (long_options[option_index].name, "echo-keys")) {
echo_keys = 1;
+ } else if (STREQ (long_options[option_index].name, "live")) {
+ live = 1;
} else {
fprintf (stderr, _("%s: unknown long option: %s (%d)\n"),
program_name, long_options[option_index].name, option_index);