X-Git-Url: http://git.annexia.org/?p=libguestfs.git;a=blobdiff_plain;f=src%2Fgenerator.ml;h=eb61fd1c69facabdfe04aabc29b4ea800e091c8c;hp=8c864f0d7666898153d471ad14b0b2bb198ef7db;hb=039831c74c42553705abad99236ef6541e8dfcd5;hpb=96fdcf7f2ed0c0d32cf14b5fea95cfba94f2c977 diff --git a/src/generator.ml b/src/generator.ml index 8c864f0..eb61fd1 100755 --- a/src/generator.ml +++ b/src/generator.ml @@ -25,9 +25,8 @@ * daemon/.c to write the implementation. * * After editing this file, run it (./src/generator.ml) to regenerate all the - * output files. Note that if you are using a separate build directory you must - * run generator.ml from your top level build directory. You must also have run - * configure before generator.ml will run. + * output files. Note that if you are using a separate build directory you + * must run generator.ml from the _source_ directory. * * IMPORTANT: This script should NOT print any warnings. If it prints * warnings, you should treat them as errors. @@ -1371,7 +1370,9 @@ contains the filesystem."); This returns the list of currently mounted filesystems. It returns the list of devices (eg. C, C). -Some internal mounts are not shown."); +Some internal mounts are not shown. + +See also: C"); ("umount_all", (RErr, []), 47, [FishAlias "unmount-all"], [InitBasicFS, Always, TestOutputList ( @@ -1718,8 +1719,8 @@ This uses the L command."); ("upload", (RErr, [FileIn "filename"; String "remotefilename"]), 66, [], [InitBasicFS, Always, TestOutput ( (* Pick a file from cwd which isn't likely to change. *) - [["upload"; "../COPYING.LIB"; "/COPYING.LIB"]; - ["checksum"; "md5"; "/COPYING.LIB"]], "e3eda01d9815f8d24aae2dbd89b68b06")], + [["upload"; "../COPYING.LIB"; "/COPYING.LIB"]; + ["checksum"; "md5"; "/COPYING.LIB"]], "e3eda01d9815f8d24aae2dbd89b68b06")], "upload a file from the local machine", "\ Upload local file C to C on the @@ -1732,10 +1733,10 @@ See also C."); ("download", (RErr, [String "remotefilename"; FileOut "filename"]), 67, [], [InitBasicFS, Always, TestOutput ( (* Pick a file from cwd which isn't likely to change. *) - [["upload"; "../COPYING.LIB"; "/COPYING.LIB"]; - ["download"; "/COPYING.LIB"; "testdownload.tmp"]; - ["upload"; "testdownload.tmp"; "/upload"]; - ["checksum"; "md5"; "/upload"]], "e3eda01d9815f8d24aae2dbd89b68b06")], + [["upload"; "../COPYING.LIB"; "/COPYING.LIB"]; + ["download"; "/COPYING.LIB"; "testdownload.tmp"]; + ["upload"; "testdownload.tmp"; "/upload"]; + ["checksum"; "md5"; "/upload"]], "e3eda01d9815f8d24aae2dbd89b68b06")], "download a file to the local machine", "\ Download file C and save it as C @@ -2357,19 +2358,19 @@ are activated or deactivated."); ("lvresize", (RErr, [String "device"; Int "mbytes"]), 105, [], [InitNone, Always, TestOutput ( - [["sfdiskM"; "/dev/sda"; ","]; - ["pvcreate"; "/dev/sda1"]; - ["vgcreate"; "VG"; "/dev/sda1"]; - ["lvcreate"; "LV"; "VG"; "10"]; - ["mkfs"; "ext2"; "/dev/VG/LV"]; - ["mount"; "/dev/VG/LV"; "/"]; - ["write_file"; "/new"; "test content"; "0"]; - ["umount"; "/"]; - ["lvresize"; "/dev/VG/LV"; "20"]; - ["e2fsck_f"; "/dev/VG/LV"]; - ["resize2fs"; "/dev/VG/LV"]; - ["mount"; "/dev/VG/LV"; "/"]; - ["cat"; "/new"]], "test content")], + [["sfdiskM"; "/dev/sda"; ","]; + ["pvcreate"; "/dev/sda1"]; + ["vgcreate"; "VG"; "/dev/sda1"]; + ["lvcreate"; "LV"; "VG"; "10"]; + ["mkfs"; "ext2"; "/dev/VG/LV"]; + ["mount"; "/dev/VG/LV"; "/"]; + ["write_file"; "/new"; "test content"; "0"]; + ["umount"; "/"]; + ["lvresize"; "/dev/VG/LV"; "20"]; + ["e2fsck_f"; "/dev/VG/LV"]; + ["resize2fs"; "/dev/VG/LV"]; + ["mount"; "/dev/VG/LV"; "/"]; + ["cat"; "/new"]], "test content")], "resize an LVM logical volume", "\ This resizes (expands or shrinks) an existing LVM logical @@ -2441,7 +2442,7 @@ This command is only needed because of C ("sleep", (RErr, [Int "secs"]), 109, [], [InitNone, Always, TestRun ( - [["sleep"; "1"]])], + [["sleep"; "1"]])], "sleep for some seconds", "\ Sleep for C seconds."); @@ -2857,6 +2858,120 @@ were rarely if ever used anyway. See also C and the L manpage."); + ("zfile", (RString "description", [String "method"; String "path"]), 140, [], + [], + "determine file type inside a compressed file", + "\ +This command runs C after first decompressing C +using C. + +C must be one of C, C or C. + +See also: C"); + + ("getxattrs", (RStructList ("xattrs", "xattr"), [String "path"]), 141, [], + [], + "list extended attributes of a file or directory", + "\ +This call lists the extended attributes of the file or directory +C. + +At the system call level, this is a combination of the +L and L calls. + +See also: C, L."); + + ("lgetxattrs", (RStructList ("xattrs", "xattr"), [String "path"]), 142, [], + [], + "list extended attributes of a file or directory", + "\ +This is the same as C, but if C +is a symbolic link, then it returns the extended attributes +of the link itself."); + + ("setxattr", (RErr, [String "xattr"; + String "val"; Int "vallen"; (* will be BufferIn *) + String "path"]), 143, [], + [], + "set extended attribute of a file or directory", + "\ +This call sets the extended attribute named C +of the file C to the value C (of length C). +The value is arbitrary 8 bit data. + +See also: C, L."); + + ("lsetxattr", (RErr, [String "xattr"; + String "val"; Int "vallen"; (* will be BufferIn *) + String "path"]), 144, [], + [], + "set extended attribute of a file or directory", + "\ +This is the same as C, but if C +is a symbolic link, then it sets an extended attribute +of the link itself."); + + ("removexattr", (RErr, [String "xattr"; String "path"]), 145, [], + [], + "remove extended attribute of a file or directory", + "\ +This call removes the extended attribute named C +of the file C. + +See also: C, L."); + + ("lremovexattr", (RErr, [String "xattr"; String "path"]), 146, [], + [], + "remove extended attribute of a file or directory", + "\ +This is the same as C, but if C +is a symbolic link, then it removes an extended attribute +of the link itself."); + + ("mountpoints", (RHashtable "mps", []), 147, [], + [], + "show mountpoints", + "\ +This call is similar to C. That call returns +a list of devices. This one returns a hash table (map) of +device name to directory where the device is mounted."); + + ("mkmountpoint", (RErr, [String "path"]), 148, [], + [], + "create a mountpoint", + "\ +C and C are +specialized calls that can be used to create extra mountpoints +before mounting the first filesystem. + +These calls are I necessary in some very limited circumstances, +mainly the case where you want to mount a mix of unrelated and/or +read-only filesystems together. + +For example, live CDs often contain a \"Russian doll\" nest of +filesystems, an ISO outer layer, with a squashfs image inside, with +an ext2/3 image inside that. You can unpack this as follows +in guestfish: + + add-ro Fedora-11-i686-Live.iso + run + mkmountpoint /cd + mkmountpoint /squash + mkmountpoint /ext3 + mount /dev/sda /cd + mount-loop /cd/LiveOS/squashfs.img /squash + mount-loop /squash/LiveOS/ext3fs.img /ext3 + +The inner filesystem is now unpacked under the /ext3 mountpoint."); + + ("rmmountpoint", (RErr, [String "path"]), 149, [], + [], + "remove a mountpoint", + "\ +This calls removes a mountpoint that was previously created +with C. See C +for full details."); + ] let all_functions = non_daemon_functions @ daemon_functions @@ -2872,6 +2987,7 @@ let all_functions_sorted = type field = | FChar (* C 'char' (really, a 7 bit byte). *) | FString (* nul-terminated ASCII string. *) + | FBuffer (* opaque buffer of bytes, (char *, int) pair *) | FUInt32 | FInt32 | FUInt64 @@ -3010,6 +3126,12 @@ let structs = [ "release", FInt64; "extra", FString; ]; + + (* Extended attribute. *) + "xattr", [ + "attrname", FString; + "attrval", FBuffer; + ]; ] (* end of structs *) (* Ugh, Java has to be different .. @@ -3024,6 +3146,7 @@ let java_structs = [ "statvfs", "StatVFS"; "dirent", "Dirent"; "version", "Version"; + "xattr", "XAttr"; ] (* Used for testing language bindings. *) @@ -3437,6 +3560,10 @@ and generate_structs_pod () = | name, (FUInt64|FBytes) -> pr " uint64_t %s;\n" name | name, FInt64 -> pr " int64_t %s;\n" name | name, FString -> pr " char *%s;\n" name + | name, FBuffer -> + pr " /* The next two fields describe a byte array. */\n"; + pr " uint32_t %s_len;\n" name; + pr " char *%s;\n" name | name, FUUID -> pr " /* The next field is NOT nul-terminated, be careful when printing it: */\n"; pr " char %s[32];\n" name @@ -3480,6 +3607,7 @@ and generate_xdr () = List.iter (function | name, FChar -> pr " char %s;\n" name | name, FString -> pr " string %s<>;\n" name + | name, FBuffer -> pr " opaque %s<>;\n" name | name, FUUID -> pr " opaque %s[32];\n" name | name, (FInt32|FUInt32) -> pr " int %s;\n" name | name, (FInt64|FUInt64|FBytes) -> pr " hyper %s;\n" name @@ -3641,6 +3769,9 @@ and generate_structs_h () = function | name, FChar -> pr " char %s;\n" name | name, FString -> pr " char *%s;\n" name + | name, FBuffer -> + pr " uint32_t %s_len;\n" name; + pr " char *%s;\n" name | name, FUUID -> pr " char %s[32]; /* this is NOT nul-terminated, be careful when printing */\n" name | name, FUInt32 -> pr " uint32_t %s;\n" name | name, FInt32 -> pr " int32_t %s;\n" name @@ -3726,7 +3857,7 @@ check_state (guestfs_h *g, const char *caller) { if (!guestfs_is_ready (g)) { if (guestfs_is_config (g)) - error (g, \"%%s: call launch() before using this function\", + error (g, \"%%s: call launch before using this function\\n(in guestfish, don't forget to use the 'run' command)\", caller); else if (guestfs_is_launching (g)) error (g, \"%%s: call wait_ready() before using this function\", @@ -4258,7 +4389,7 @@ and generate_daemon_actions () = pr " fprintf (stderr, \"%%s: failed to parse float '%%s' from token %%s\\n\", __func__, tok, \"%s\");\n" name; pr " return -1;\n"; pr " }\n"; - | FInt32 | FUInt32 | FUInt64 | FChar -> + | FBuffer | FInt32 | FUInt32 | FUInt64 | FChar -> assert false (* can never be an LVM column *) ); pr " tok = next;\n"; @@ -5041,6 +5172,7 @@ and generate_fish_cmds () = pr "#include \n"; pr "#include \n"; pr "#include \n"; + pr "#include \n"; pr "\n"; pr "#include \n"; pr "#include \"fish.h\"\n"; @@ -5118,7 +5250,7 @@ and generate_fish_cmds () = List.iter ( fun (typ, cols) -> let needs_i = - List.exists (function (_, FUUID) -> true | _ -> false) cols in + List.exists (function (_, (FUUID|FBuffer)) -> true | _ -> false) cols in pr "static void print_%s (struct guestfs_%s *%s)\n" typ typ typ; pr "{\n"; @@ -5135,6 +5267,14 @@ and generate_fish_cmds () = pr " for (i = 0; i < 32; ++i)\n"; pr " printf (\"%%c\", %s->%s[i]);\n" typ name; pr " printf (\"\\n\");\n" + | name, FBuffer -> + pr " printf (\"%s: \");\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 (\"%%c\", %s->%s[i]);\n" typ name; + pr " else\n"; + pr " printf (\"\\\\x%%02x\", %s->%s[i]);\n" typ name; + pr " printf (\"\\n\");\n" | name, (FUInt64|FBytes) -> pr " printf (\"%s: %%\" PRIu64 \"\\n\", %s->%s);\n" name typ name | name, FInt64 -> @@ -5650,6 +5790,10 @@ copy_table (char * const * argv) (match col with | name, FString -> pr " v = caml_copy_string (%s->%s);\n" typ name + | name, FBuffer -> + pr " v = caml_alloc_string (%s->%s_len);\n" typ name; + pr " memcpy (String_val (v), %s->%s, %s->%s_len);\n" + typ name typ name | name, FUUID -> pr " v = caml_alloc_string (32);\n"; pr " memcpy (String_val (v), %s->%s, 32);\n" typ name @@ -5830,6 +5974,7 @@ and generate_ocaml_structure_decls () = List.iter ( function | name, FString -> pr " %s : string;\n" name + | name, FBuffer -> pr " %s : string;\n" name | name, FUUID -> pr " %s : string;\n" name | name, (FBytes|FInt64|FUInt64) -> pr " %s : int64;\n" name | name, (FInt32|FUInt32) -> pr " %s : int32;\n" name @@ -6126,6 +6271,9 @@ and generate_perl_struct_list_code typ cols name style n do_cleanups = | name, FUUID -> pr " (void) hv_store (hv, \"%s\", %d, newSVpv (%s->val[i].%s, 32), 0);\n" name (String.length name) n name + | name, FBuffer -> + pr " (void) hv_store (hv, \"%s\", %d, newSVpv (%s->val[i].%s, %s->val[i].%s_len), 0);\n" + name (String.length name) n name n name | name, (FBytes|FUInt64) -> pr " (void) hv_store (hv, \"%s\", %d, my_newSVull (%s->val[i].%s), 0);\n" name (String.length name) n name @@ -6165,6 +6313,9 @@ and generate_perl_struct_code typ cols name style n do_cleanups = | name, FString -> pr " PUSHs (sv_2mortal (newSVpv (%s->%s, 0)));\n" n name + | name, FBuffer -> + pr " PUSHs (sv_2mortal (newSVpv (%s->%s, %s->%s_len)));\n" + n name n name | name, FUUID -> pr " PUSHs (sv_2mortal (newSVpv (%s->%s, 32)));\n" n name @@ -6497,6 +6648,10 @@ py_guestfs_close (PyObject *self, PyObject *args) pr " PyDict_SetItemString (dict, \"%s\",\n" name; pr " PyString_FromString (%s->%s));\n" typ name + | name, FBuffer -> + pr " PyDict_SetItemString (dict, \"%s\",\n" name; + pr " PyString_FromStringAndSize (%s->%s, %s->%s_len));\n" + typ name typ name | name, FUUID -> pr " PyDict_SetItemString (dict, \"%s\",\n" name; pr " PyString_FromStringAndSize (%s->%s, 32));\n" @@ -7040,6 +7195,8 @@ and generate_ruby_struct_code typ cols = function | name, FString -> pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), rb_str_new2 (r->%s));\n" name name + | name, FBuffer -> + pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), rb_str_new (r->%s, r->%s_len));\n" name name name | name, FUUID -> pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), rb_str_new (r->%s, 32));\n" name name | name, (FBytes|FUInt64) -> @@ -7068,6 +7225,8 @@ and generate_ruby_struct_list_code typ cols = function | name, FString -> pr " rb_hash_aset (hv, rb_str_new2 (\"%s\"), rb_str_new2 (r->val[i].%s));\n" name name + | name, FBuffer -> + pr " rb_hash_aset (hv, rb_str_new2 (\"%s\"), rb_str_new (r->val[i].%s, r->val[i].%s_len));\n" name name name | name, FUUID -> pr " rb_hash_aset (hv, rb_str_new2 (\"%s\"), rb_str_new (r->val[i].%s, 32));\n" name name | name, (FBytes|FUInt64) -> @@ -7279,7 +7438,8 @@ public class %s { List.iter ( function | name, FString - | name, FUUID -> pr " public String %s;\n" name + | name, FUUID + | name, FBuffer -> pr " public String %s;\n" name | name, (FBytes|FUInt64|FInt64) -> pr " public long %s;\n" name | name, (FUInt32|FInt32) -> pr " public int %s;\n" name | name, FChar -> pr " public char %s;\n" name @@ -7543,6 +7703,15 @@ and generate_java_struct_return typ jtyp cols = pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"Ljava/lang/String;\");\n" name; pr " (*env)->SetObjectField (env, jr, fl, (*env)->NewStringUTF (env, s));\n"; pr " }\n"; + | name, FBuffer -> + pr " {\n"; + pr " int len = r->%s_len;\n" name; + pr " char s[len+1];\n"; + pr " memcpy (s, r->%s, len);\n" name; + pr " s[len] = 0;\n"; + pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"Ljava/lang/String;\");\n" name; + pr " (*env)->SetObjectField (env, jr, fl, (*env)->NewStringUTF (env, s));\n"; + pr " }\n"; | name, (FBytes|FUInt64|FInt64) -> pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"J\");\n" name; pr " (*env)->SetLongField (env, jr, fl, r->%s);\n" name; @@ -7577,6 +7746,15 @@ and generate_java_struct_list_return typ jtyp cols = pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"Ljava/lang/String;\");\n" name; pr " (*env)->SetObjectField (env, jfl, fl, (*env)->NewStringUTF (env, s));\n"; pr " }\n"; + | name, FBuffer -> + pr " {\n"; + pr " int len = r->val[i].%s_len;\n" name; + pr " char s[len+1];\n"; + pr " memcpy (s, r->val[i].%s, len);\n" name; + pr " s[len] = 0;\n"; + pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"Ljava/lang/String;\");\n" name; + pr " (*env)->SetObjectField (env, jfl, fl, (*env)->NewStringUTF (env, s));\n"; + pr " }\n"; | name, (FBytes|FUInt64|FInt64) -> pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"J\");\n" name; pr " (*env)->SetLongField (env, jfl, fl, r->val[i].%s);\n" name; @@ -8214,7 +8392,7 @@ let output_to filename = let () = check_functions (); - if not (Sys.file_exists "config.status") then ( + if not (Sys.file_exists "HACKING") then ( eprintf "\ You are probably running this from the wrong directory. Run it from the top source directory using the command