X-Git-Url: http://git.annexia.org/?a=blobdiff_plain;f=fish%2Foptions.c;h=48c8e1c2fa4286e8ec74a120cc727a0257a0df0e;hb=ae45cee728039d7724fc73e5ffb2550c8054d268;hp=55bcf687144c661aa49b7cb66ade81d4ff3f611d;hpb=c66d6f215e8303d4eaf8ccfdb6a58cff04ccc485;p=libguestfs.git diff --git a/fish/options.c b/fish/options.c index 55bcf68..48c8e1c 100644 --- a/fish/options.c +++ b/fish/options.c @@ -1,5 +1,5 @@ /* libguestfs - guestfish and guestmount shared option parsing - * Copyright (C) 2010 Red Hat Inc. + * Copyright (C) 2010-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 @@ -21,6 +21,8 @@ #include #include +#include "c-ctype.h" + #include "guestfs.h" #include "options.h" @@ -41,6 +43,11 @@ add_drives (struct drv *drv, char next_drive) if (drv) { next_drive = add_drives (drv->next, next_drive); + if (asprintf (&drv->device, "/dev/sd%c", next_drive) == -1) { + perror ("asprintf"); + exit (EXIT_FAILURE); + } + switch (drv->type) { case drv_a: ad_optargs.bitmask = 0; @@ -56,6 +63,7 @@ add_drives (struct drv *drv, char next_drive) if (r == -1) exit (EXIT_FAILURE); + drv->nr_drives = 1; next_drive++; break; @@ -64,6 +72,7 @@ add_drives (struct drv *drv, char next_drive) if (r == -1) exit (EXIT_FAILURE); + drv->nr_drives = r; next_drive += r; break; @@ -78,11 +87,7 @@ add_drives (struct drv *drv, char next_drive) if (r == -1) exit (EXIT_FAILURE); - if (asprintf (&drv->N.device, "/dev/sd%c", next_drive) == -1) { - perror ("asprintf"); - exit (EXIT_FAILURE); - } - + drv->nr_drives = 1; next_drive++; break; @@ -94,6 +99,9 @@ add_drives (struct drv *drv, char next_drive) return next_drive; } +static void display_mountpoints_on_failure (const char *mp_device); +static void canonical_device_name (char *dev); + /* List is built in reverse order, so mount them in reverse order. */ void mount_mps (struct mp *mp) @@ -103,42 +111,81 @@ mount_mps (struct mp *mp) if (mp) { mount_mps (mp->next); + const char *options; + if (mp->options) + options = mp->options; + else if (read_only) + options = "ro"; + else + options = ""; + /* Don't use guestfs_mount here because that will default to mount * options -o sync,noatime. For more information, see guestfs(3) * section "LIBGUESTFS GOTCHAS". */ - const char *options = read_only ? "ro" : ""; r = guestfs_mount_options (g, options, mp->device, mp->mountpoint); if (r == -1) { - /* Display possible mountpoints before exiting. */ - char **fses = guestfs_list_filesystems (g); - if (fses == NULL || fses[0] == NULL) - goto out; - fprintf (stderr, - _("%s: '%s' could not be mounted. Did you mean one of these?\n"), - program_name, mp->device); - size_t i; - for (i = 0; fses[i] != NULL; i += 2) - fprintf (stderr, "\t%s (%s)\n", fses[i], fses[i+1]); - - out: + display_mountpoints_on_failure (mp->device); exit (EXIT_FAILURE); } } } +/* If the -m option fails on any command, display a useful error + * message listing the mountpoints. + */ +static void +display_mountpoints_on_failure (const char *mp_device) +{ + char **fses; + size_t i; + + fses = guestfs_list_filesystems (g); + if (fses == NULL) + return; + if (fses[0] == NULL) { + free (fses); + return; + } + + fprintf (stderr, + _("%s: '%s' could not be mounted. Did you mean one of these?\n"), + program_name, mp_device); + + for (i = 0; fses[i] != NULL; i += 2) { + canonical_device_name (fses[i]); + fprintf (stderr, "\t%s (%s)\n", fses[i], fses[i+1]); + free (fses[i]); + free (fses[i+1]); + } + + free (fses); +} + +static void +canonical_device_name (char *dev) +{ + if (STRPREFIX (dev, "/dev/") && + (dev[5] == 'h' || dev[5] == 'v') && + dev[6] == 'd' && + c_isalpha (dev[7]) && + (c_isdigit (dev[8]) || dev[8] == '\0')) + dev[5] = 's'; +} + void free_drives (struct drv *drv) { if (!drv) return; free_drives (drv->next); + free (drv->device); + switch (drv->type) { case drv_a: /* a.filename and a.format are optargs, don't free them */ break; case drv_d: /* d.filename is optarg, don't free it */ break; case drv_N: free (drv->N.filename); - free (drv->N.device); drv->N.data_free (drv->N.data); break; default: ; /* keep GCC happy */