diff options
author | Richard W.M. Jones <rjones@redhat.com> | 2011-04-05 19:43:30 +0100 |
---|---|---|
committer | Richard W.M. Jones <rjones@redhat.com> | 2011-04-05 20:01:59 +0100 |
commit | b8be128caa27fa5e1636e9e4caff3e23a6dc761f (patch) | |
tree | 4d7650463345581ae038f8b3484b52a6d897623e /fish | |
parent | ade2f824509c5399e60ddab7db2b618aaf8db0aa (diff) | |
download | libguestfs-b8be128caa27fa5e1636e9e4caff3e23a6dc761f.tar.gz libguestfs-b8be128caa27fa5e1636e9e4caff3e23a6dc761f.tar.xz libguestfs-b8be128caa27fa5e1636e9e4caff3e23a6dc761f.zip |
fish: Enhance guestfish win:... parsing to understand drive letters.
Diffstat (limited to 'fish')
-rw-r--r-- | fish/fish.c | 80 | ||||
-rw-r--r-- | fish/fish.h | 2 |
2 files changed, 75 insertions, 7 deletions
diff --git a/fish/fish.c b/fish/fish.c index c4fdf799..1419c895 100644 --- a/fish/fish.c +++ b/fish/fish.c @@ -1375,16 +1375,18 @@ xwrite (int fd, const void *v_buf, size_t len) return 0; } -/* Resolve the special "win:..." form for Windows-specific paths. - * This always returns a newly allocated string which is freed by the - * caller function in "cmds.c". +/* Resolve the special "win:..." form for Windows-specific paths. The + * generated code calls this for all device or path arguments. The + * function must return a newly allocated string (caller frees) or + * display an error and return NULL. */ char * -resolve_win_path (const char *path) +win_prefix (const char *path) { char *ret; size_t i; + /* If there is not a "win:..." prefix on the path, return strdup'd string. */ if (STRCASENEQLEN (path, "win:", 4)) { ret = strdup (path); if (ret == NULL) @@ -1394,10 +1396,76 @@ resolve_win_path (const char *path) path += 4; - /* Drop drive letter, if it's "C:". */ - if (STRCASEEQLEN (path, "c:", 2)) + /* Is there a drive letter? */ + if (c_isalpha (path[0]) && path[1] == ':') { + char drive_letter; + char **roots, **drives, **mountpoints, *device; + size_t i; + + drive_letter = c_tolower (path[0]); path += 2; + /* Resolve the drive letter using the drive mappings table. */ + roots = guestfs_inspect_get_roots (g); + if (roots == NULL) + return NULL; + if (roots[0] == NULL) { + fprintf (stderr, _("%s: to use Windows drive letters, you must inspect the guest (\"-i\" option or run \"inspect-os\" command)\n"), + program_name); + free_strings (roots); + return NULL; + } + drives = guestfs_inspect_get_drive_mappings (g, roots[0]); + if (drives == NULL || drives[0] == NULL) { + fprintf (stderr, _("%s: to use Windows drive letters, this must be a Windows guest\n"), + program_name); + free_strings (roots); + free_strings (drives); + return NULL; + } + + device = NULL; + for (i = 0; drives[i] != NULL; i += 2) { + if (c_tolower (drives[i][0]) == drive_letter && drives[i][1] == '\0') { + device = drives[i+1]; + break; + } + } + + if (device == NULL) { + fprintf (stderr, _("%s: drive '%c:' not found. To list available drives do:\n inspect-get-drive-mappings %s\n"), + program_name, drive_letter, roots[0]); + free_strings (roots); + free_strings (drives); + return NULL; + } + + /* This drive letter must be mounted on / (we won't do it). */ + mountpoints = guestfs_mountpoints (g); + if (mountpoints == NULL) { + free_strings (roots); + free_strings (drives); + return NULL; + } + + for (i = 0; mountpoints[i] != NULL; i += 2) { + if (STREQ (mountpoints[i+1], "/")) { + if (STRNEQ (mountpoints[i], device)) { + fprintf (stderr, _("%s: to access '%c:', mount %s on / first. One way to do this is:\n umount-all\n mount %s /\n"), + program_name, drive_letter, device, device); + free_strings (roots); + free_strings (drives); + free_strings (mountpoints); + return NULL; + } + } + } + + free_strings (roots); + free_strings (drives); + free_strings (mountpoints); + } + if (!*path) { ret = strdup ("/"); if (ret == NULL) diff --git a/fish/fish.h b/fish/fish.h index 114e8a87..a885b891 100644 --- a/fish/fish.h +++ b/fish/fish.h @@ -73,7 +73,7 @@ extern void print_table (char *const *argv); extern int is_true (const char *str); extern char **parse_string_list (const char *str); extern int xwrite (int fd, const void *buf, size_t len); -extern char *resolve_win_path (const char *path); +extern char *win_prefix (const char *path); extern char *file_in (const char *arg); extern void free_file_in (char *s); extern char *file_out (const char *arg); |