X-Git-Url: http://git.annexia.org/?a=blobdiff_plain;f=src%2Fgenerator.ml;h=324945923ed6deb04d77c369bfd3018b7d54d87f;hb=00425c073e5c0743ef425cd12108a85ac36b15f4;hp=6f77e4ba77e564dd0bc83bd04f5eb6e348a02c74;hpb=dc0c80b3884c5fa2735b55b205e7406599bd77b0;p=libguestfs.git diff --git a/src/generator.ml b/src/generator.ml index 6f77e4b..3249459 100755 --- a/src/generator.ml +++ b/src/generator.ml @@ -2488,7 +2488,7 @@ C sometimes gives an error about this and sometimes not. In any case, it is always safe to call C before calling this function."); - ("find", (RStringList "names", [Pathname "directory"]), 107, [], + ("find", (RStringList "names", [Pathname "directory"]), 107, [ProtocolLimitWarning], [InitBasicFS, Always, TestOutputList ( [["find"; "/"]], ["lost+found"]); InitBasicFS, Always, TestOutputList ( @@ -2525,7 +2525,9 @@ then the returned list from C C would be If C is not a directory, then this command returns an error. -The returned list is sorted."); +The returned list is sorted. + +See also C."); ("e2fsck_f", (RErr, [Device "device"]), 108, [], [], (* lvresize tests this *) @@ -3610,6 +3612,109 @@ You can use this command to test the connection through to the daemon. See also C."); + ("find0", (RErr, [Pathname "directory"; FileOut "files"]), 196, [], + [], (* There is a regression test for this. *) + "find all files and directories, returning NUL-separated list", + "\ +This command lists out all files and directories, recursively, +starting at C, placing the resulting list in the +external file called C. + +This command works the same way as C with the +following exceptions: + +=over 4 + +=item * + +The resulting list is written to an external file. + +=item * + +Items (filenames) in the result are separated +by C<\\0> characters. See L option I<-print0>. + +=item * + +This command is not limited in the number of names that it +can return. + +=item * + +The result list is not sorted. + +=back"); + + ("case_sensitive_path", (RString "rpath", [Pathname "path"]), 197, [], + [InitISOFS, Always, TestOutput ( + [["case_sensitive_path"; "/DIRECTORY"]], "/directory"); + InitISOFS, Always, TestOutput ( + [["case_sensitive_path"; "/DIRECTORY/"]], "/directory"); + InitISOFS, Always, TestOutput ( + [["case_sensitive_path"; "/Known-1"]], "/known-1"); + InitISOFS, Always, TestLastFail ( + [["case_sensitive_path"; "/Known-1/"]]); + InitBasicFS, Always, TestOutput ( + [["mkdir"; "/a"]; + ["mkdir"; "/a/bbb"]; + ["touch"; "/a/bbb/c"]; + ["case_sensitive_path"; "/A/bbB/C"]], "/a/bbb/c"); + InitBasicFS, Always, TestOutput ( + [["mkdir"; "/a"]; + ["mkdir"; "/a/bbb"]; + ["touch"; "/a/bbb/c"]; + ["case_sensitive_path"; "/A////bbB/C"]], "/a/bbb/c"); + InitBasicFS, Always, TestLastFail ( + [["mkdir"; "/a"]; + ["mkdir"; "/a/bbb"]; + ["touch"; "/a/bbb/c"]; + ["case_sensitive_path"; "/A/bbb/../bbb/C"]])], + "return true path on case-insensitive filesystem", + "\ +This can be used to resolve case insensitive paths on +a filesystem which is case sensitive. The use case is +to resolve paths which you have read from Windows configuration +files or the Windows Registry, to the true path. + +The command handles a peculiarity of the Linux ntfs-3g +filesystem driver (and probably others), which is that although +the underlying filesystem is case-insensitive, the driver +exports the filesystem to Linux as case-sensitive. + +One consequence of this is that special directories such +as C may appear as C or C +(or other things) depending on the precise details of how +they were created. In Windows itself this would not be +a problem. + +Bug or feature? You decide: +L + +This function resolves the true case of each element in the +path and returns the case-sensitive path. + +Thus C (\"/Windows/System32\") +might return C<\"/WINDOWS/system32\"> (the exact return value +would depend on details of how the directories were originally +created under Windows). + +I: +This function does not handle drive names, backslashes etc. + +See also C."); + + ("vfs_type", (RString "fstype", [Device "device"]), 198, [], + [InitBasicFS, Always, TestOutput ( + [["vfs_type"; "/dev/sda1"]], "ext2")], + "get the Linux VFS type corresponding to a mounted device", + "\ +This command gets the block device type corresponding to +a mounted device called C. + +Usually the result is the name of the Linux VFS module that +is used to mount this device (probably determined automatically +if you used the C call)."); + ] let all_functions = non_daemon_functions @ daemon_functions @@ -3810,7 +3915,7 @@ type rstructs_used_t = RStructOnly | RStructListOnly | RStructAndList * == there are functions returning both RStruct (_, structname) * and RStructList (_, structname) *) -let rstructs_used = +let rstructs_used_by functions = (* ||| is a "logical OR" for rstructs_used_t *) let (|||) a b = match a, b with @@ -3839,21 +3944,11 @@ let rstructs_used = | RStruct (_, structname) -> update structname RStructOnly | RStructList (_, structname) -> update structname RStructListOnly | _ -> () - ) all_functions; + ) functions; (* return key->values as a list of (key,value) *) Hashtbl.fold (fun key value xs -> (key, value) :: xs) h [] -(* debug: -let () = - List.iter ( - function - | sn, RStructOnly -> printf "%s RStructOnly\n" sn - | sn, RStructListOnly -> printf "%s RStructListOnly\n" sn - | sn, RStructAndList -> printf "%s RStructAndList\n" sn - ) rstructs_used -*) - (* Used for testing language bindings. *) type callt = | CallString of string @@ -4956,11 +5051,11 @@ and generate_daemon_actions () = pr "#include \n"; pr "#include \n"; pr "#include \n"; - pr "#include \n"; pr "#include \n"; pr "#include \n"; pr "\n"; pr "#include \"daemon.h\"\n"; + pr "#include \"c-ctype.h\"\n"; pr "#include \"../src/guestfs_protocol.h\"\n"; pr "#include \"actions.h\"\n"; pr "\n"; @@ -5186,7 +5281,7 @@ and generate_daemon_actions () = pr " fprintf (stderr, \"%%s: failed: passed a NULL string\\n\", __func__);\n"; pr " return -1;\n"; pr " }\n"; - pr " if (!*str || isspace (*str)) {\n"; + pr " if (!*str || c_isspace (*str)) {\n"; pr " fprintf (stderr, \"%%s: failed: passed a empty string or one beginning with whitespace\\n\", __func__);\n"; pr " return -1;\n"; pr " }\n"; @@ -5288,7 +5383,7 @@ and generate_daemon_actions () = pr " pend++;\n"; pr " }\n"; pr "\n"; - pr " while (*p && isspace (*p)) /* Skip any leading whitespace. */\n"; + pr " while (*p && c_isspace (*p)) /* Skip any leading whitespace. */\n"; pr " p++;\n"; pr "\n"; pr " if (!*p) { /* Empty line? Skip it. */\n"; @@ -6073,9 +6168,9 @@ and generate_fish_cmds () = pr "#include \n"; pr "#include \n"; pr "#include \n"; - pr "#include \n"; pr "\n"; pr "#include \n"; + pr "#include \"c-ctype.h\"\n"; pr "#include \"fish.h\"\n"; pr "\n"; @@ -6186,17 +6281,17 @@ and generate_fish_cmds () = | name, FString -> pr " printf (\"%%s%s: %%s\\n\", indent, %s->%s);\n" name typ name | name, FUUID -> - pr " printf (\"%s: \");\n" name; + pr " printf (\"%%s%s: \", indent);\n" name; pr " for (i = 0; i < 32; ++i)\n"; - pr " printf (\"%%s%%c\", indent, %s->%s[i]);\n" typ name; + pr " printf (\"%%c\", %s->%s[i]);\n" typ name; pr " printf (\"\\n\");\n" | name, FBuffer -> pr " printf (\"%%s%s: \", indent);\n" name; pr " for (i = 0; i < %s->%s_len; ++i)\n" typ name; - pr " if (isprint (%s->%s[i]))\n" typ name; - pr " printf (\"%%s%%c\", indent, %s->%s[i]);\n" typ name; + pr " if (c_isprint (%s->%s[i]))\n" typ name; + pr " printf (\"%%c\", %s->%s[i]);\n" typ name; pr " else\n"; - pr " printf (\"%%s\\\\x%%02x\", indent, %s->%s[i]);\n" typ name; + pr " printf (\"\\\\x%%02x\", %s->%s[i]);\n" typ name; pr " printf (\"\\n\");\n" | name, (FUInt64|FBytes) -> pr " printf (\"%%s%s: %%\" PRIu64 \"\\n\", indent, %s->%s);\n" @@ -6229,19 +6324,19 @@ and generate_fish_cmds () = (* generate the function for typ *) emit_print_list_function typ | typ, _ -> () (* empty *) - ) rstructs_used; + ) (rstructs_used_by all_functions); (* Emit a print_TYPE function definition only if that function is used. *) List.iter ( function - | typ, RStructOnly -> + | typ, (RStructOnly | RStructAndList) -> pr "static void print_%s (struct guestfs_%s *%s)\n" typ typ typ; pr "{\n"; pr " print_%s_indent (%s, \"\");\n" typ typ; pr "}\n"; pr "\n"; | typ, _ -> () (* empty *) - ) rstructs_used; + ) (rstructs_used_by all_functions); (* run_ actions *) List.iter ( @@ -6264,12 +6359,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 @@ -6286,8 +6382,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 @@ -6316,9 +6417,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); @@ -6829,7 +6932,7 @@ copy_table (char * const * argv) (* generate the function for typ *) emit_ocaml_copy_list_function typ | typ, _ -> () (* empty *) - ) rstructs_used; + ) (rstructs_used_by all_functions); (* The wrappers. *) List.iter ( @@ -7775,7 +7878,7 @@ py_guestfs_close (PyObject *self, PyObject *args) (* generate the function for typ *) emit_put_list_function typ | typ, _ -> () (* empty *) - ) rstructs_used; + ) (rstructs_used_by all_functions); (* Python wrapper functions. *) List.iter (