guestfish: Add win: prefix to use Windows paths.
authorRichard Jones <rjones@redhat.com>
Mon, 26 Oct 2009 09:04:42 +0000 (09:04 +0000)
committerRichard Jones <rjones@redhat.com>
Mon, 26 Oct 2009 15:09:20 +0000 (15:09 +0000)
Add a win: prefix for path arguments in guestfish:

><fs> file win:c:\windows\system32\config\system.log
MS Windows registry file, NT/2000 or above

fish/fish.c
fish/fish.h
guestfish.pod
src/generator.ml

index 3300536..f699603 100644 (file)
@@ -1295,3 +1295,51 @@ 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".
+ */
+char *
+resolve_win_path (const char *path)
+{
+  char *ret;
+  size_t i;
+
+  if (strncasecmp (path, "win:", 4) != 0) {
+    ret = strdup (path);
+    if (ret == NULL)
+      perror ("strdup");
+    return ret;
+  }
+
+  path += 4;
+
+  /* Drop drive letter, if it's "C:". */
+  if (strncasecmp (path, "c:", 2) == 0)
+    path += 2;
+
+  if (!*path) {
+    ret = strdup ("/");
+    if (ret == NULL)
+      perror ("strdup");
+    return ret;
+  }
+
+  ret = strdup (path);
+  if (ret == NULL) {
+    perror ("strdup");
+    return NULL;
+  }
+
+  /* Blindly convert any backslashes into forward slashes.  Is this good? */
+  for (i = 0; i < strlen (ret); ++i)
+    if (ret[i] == '\\')
+      ret[i] = '/';
+
+  char *t = guestfs_case_sensitive_path (g, ret);
+  free (ret);
+  ret = t;
+
+  return ret;
+}
index 642c269..8c5dba1 100644 (file)
@@ -46,6 +46,7 @@ extern int launch (guestfs_h *);
 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);
 
 /* in cmds.c (auto-generated) */
 extern void list_commands (void);
index e4b2333..b635419 100644 (file)
@@ -350,6 +350,23 @@ it, eg:
 
  echo "~"
 
+=head1 WINDOWS PATHS
+
+If a path is prefixed with C<win:> then you can use Windows-style
+paths (with some limitations).  The following commands are equivalent:
+
+ file /WINDOWS/system32/config/system.LOG
+
+ file win:/windows/system32/config/system.log
+
+ file win:\windows\system32\config\system.log
+
+ file WIN:C:\Windows\SYSTEM32\conFIG\SYSTEM.LOG
+
+This syntax implicitly calls C<case-sensitive-path> (q.v.) so it also
+handles case insensitivity like Windows would.  This only works in
+argument positions that expect a path.
+
 =head1 EXIT ON ERROR BEHAVIOUR
 
 By default, guestfish will ignore any errors when in interactive mode
index 39f363d..f634cc8 100755 (executable)
@@ -6357,12 +6357,13 @@ and generate_fish_cmds () =
       );
       List.iter (
         function
-        | Pathname n
-        | Device n | Dev_or_Path n
+        | Device n
         | String n
         | OptString n
         | FileIn n
         | FileOut n -> pr "  const char *%s;\n" n
+        | Pathname n
+        | Dev_or_Path n -> pr "  char *%s;\n" n
         | StringList n | DeviceList n -> pr "  char **%s;\n" n
         | Bool n -> pr "  int %s;\n" n
         | Int n -> pr "  int %s;\n" n
@@ -6379,8 +6380,13 @@ and generate_fish_cmds () =
       iteri (
         fun i ->
           function
+          | Device name
+          | String name ->
+             pr "  %s = argv[%d];\n" name i
           | Pathname name
-          | Device name | Dev_or_Path name | String name -> pr "  %s = argv[%d];\n" name i
+          | Dev_or_Path name ->
+             pr "  %s = resolve_win_path (argv[%d]);\n" name i;
+             pr "  if (%s == NULL) return -1;\n" name
           | OptString name ->
               pr "  %s = strcmp (argv[%d], \"\") != 0 ? argv[%d] : NULL;\n"
                 name i i
@@ -6409,9 +6415,11 @@ and generate_fish_cmds () =
 
       List.iter (
         function
-        | Pathname name | Device name | Dev_or_Path name | String name
+        | Device name | String name
         | OptString name | FileIn name | FileOut name | Bool name
         | Int name -> ()
+        | Pathname name | Dev_or_Path name ->
+            pr "  free (%s);\n" name
         | StringList name | DeviceList name ->
             pr "  free_strings (%s);\n" name
       ) (snd style);