From 24ccbb29ac475187f51a27dcd318db2b4824a0c1 Mon Sep 17 00:00:00 2001 From: Richard Jones Date: Mon, 20 Apr 2009 10:19:45 +0100 Subject: [PATCH] Generated code for 'checksum' command. --- daemon/actions.h | 1 + daemon/stubs.c | 32 +++ fish/cmds.c | 26 +++ fish/completion.c | 1 + guestfish-actions.pod | 45 ++++ guestfs-actions.pod | 50 ++++ ocaml/guestfs.ml | 1 + ocaml/guestfs.mli | 3 + ocaml/guestfs_c_actions.c | 25 ++ perl/Guestfs.xs | 16 ++ perl/lib/Sys/Guestfs.pm | 43 ++++ python/guestfs-py.c | 27 +++ python/guestfs.py | 38 +++ ruby/ext/guestfs/_guestfs.c | 29 +++ src/guestfs-actions.c | 88 +++++++ src/guestfs-actions.h | 1 + src/guestfs_protocol.c | 22 ++ src/guestfs_protocol.h | 18 +- src/guestfs_protocol.x | 10 + tests.c | 559 +++++++++++++++++++++++++++++++++++++++++++- 20 files changed, 1033 insertions(+), 2 deletions(-) diff --git a/daemon/actions.h b/daemon/actions.h index 01ef882..cffd8ef 100644 --- a/daemon/actions.h +++ b/daemon/actions.h @@ -88,3 +88,4 @@ extern int do_blockdev_flushbufs (const char *device); extern int do_blockdev_rereadpt (const char *device); extern int do_upload (const char *remotefilename); extern int do_download (const char *remotefilename); +extern char *do_checksum (const char *csumtype, const char *path); diff --git a/daemon/stubs.c b/daemon/stubs.c index df067cc..3039404 100644 --- a/daemon/stubs.c +++ b/daemon/stubs.c @@ -1632,6 +1632,35 @@ done: xdr_free ((xdrproc_t) xdr_guestfs_download_args, (char *) &args); } +static void checksum_stub (XDR *xdr_in) +{ + char *r; + struct guestfs_checksum_args args; + const char *csumtype; + const char *path; + + memset (&args, 0, sizeof args); + + if (!xdr_guestfs_checksum_args (xdr_in, &args)) { + reply_with_error ("%s: daemon failed to decode procedure arguments", "checksum"); + return; + } + csumtype = args.csumtype; + path = args.path; + + r = do_checksum (csumtype, path); + if (r == NULL) + /* do_checksum has already called reply_with_error */ + goto done; + + struct guestfs_checksum_ret ret; + ret.checksum = r; + reply ((xdrproc_t) &xdr_guestfs_checksum_ret, (char *) &ret); + free (r); +done: + xdr_free ((xdrproc_t) xdr_guestfs_checksum_args, (char *) &args); +} + void dispatch_incoming_message (XDR *xdr_in) { switch (proc_nr) { @@ -1836,6 +1865,9 @@ void dispatch_incoming_message (XDR *xdr_in) case GUESTFS_PROC_DOWNLOAD: download_stub (xdr_in); break; + case GUESTFS_PROC_CHECKSUM: + checksum_stub (xdr_in); + break; default: reply_with_error ("dispatch_incoming_message: unknown procedure number %d", proc_nr); } diff --git a/fish/cmds.c b/fish/cmds.c index 9cd23c5..dd574f2 100644 --- a/fish/cmds.c +++ b/fish/cmds.c @@ -57,6 +57,7 @@ void list_commands (void) printf ("%-20s %s\n", "blockdev-setro", "set block device to read-only"); printf ("%-20s %s\n", "blockdev-setrw", "set block device to read-write"); printf ("%-20s %s\n", "cat", "list the contents of a file"); + printf ("%-20s %s\n", "checksum", "compute MD5, SHAx or CRC checksum of file"); printf ("%-20s %s\n", "chmod", "change file mode"); printf ("%-20s %s\n", "chown", "change file owner and group"); printf ("%-20s %s\n", "command", "run a command from the guest filesystem"); @@ -368,6 +369,9 @@ void display_command (const char *cmd) if (strcasecmp (cmd, "download") == 0) pod2text ("download - download a file to the local machine", " download \n\nDownload file C and save it as C\non the local machine.\n\nC can also be a named pipe.\n\nSee also C, C."); else + if (strcasecmp (cmd, "checksum") == 0) + pod2text ("checksum - compute MD5, SHAx or CRC checksum of file", " checksum \n\nThis call computes the MD5, SHAx or CRC checksum of the\nfile named C.\n\nThe type of checksum to compute is given by the C\nparameter which must have one of the following values:\n\n=over 4\n\n=item C\n\nCompute the cyclic redundancy check (CRC) specified by POSIX\nfor the C command.\n\n=item C\n\nCompute the MD5 hash (using the C program).\n\n=item C\n\nCompute the SHA1 hash (using the C program).\n\n=item C\n\nCompute the SHA224 hash (using the C program).\n\n=item C\n\nCompute the SHA256 hash (using the C program).\n\n=item C\n\nCompute the SHA384 hash (using the C program).\n\n=item C\n\nCompute the SHA512 hash (using the C program).\n\n=back\n\nThe checksum is returned as a printable string."); + else display_builtin_command (cmd); } @@ -1778,6 +1782,25 @@ static int run_download (const char *cmd, int argc, char *argv[]) return r; } +static int run_checksum (const char *cmd, int argc, char *argv[]) +{ + char *r; + const char *csumtype; + const char *path; + if (argc != 2) { + fprintf (stderr, "%s should have 2 parameter(s)\n", cmd); + fprintf (stderr, "type 'help %s' for help on %s\n", cmd, cmd); + return -1; + } + csumtype = argv[0]; + path = argv[1]; + r = guestfs_checksum (g, csumtype, path); + if (r == NULL) return -1; + printf ("%s\n", r); + free (r); + return 0; +} + int run_action (const char *cmd, int argc, char *argv[]) { if (strcasecmp (cmd, "launch") == 0 || strcasecmp (cmd, "run") == 0) @@ -2029,6 +2052,9 @@ int run_action (const char *cmd, int argc, char *argv[]) if (strcasecmp (cmd, "download") == 0) return run_download (cmd, argc, argv); else + if (strcasecmp (cmd, "checksum") == 0) + return run_checksum (cmd, argc, argv); + else { fprintf (stderr, "%s: unknown command\n", cmd); return -1; diff --git a/fish/completion.c b/fish/completion.c index a0ba5ae..49f912b 100644 --- a/fish/completion.c +++ b/fish/completion.c @@ -63,6 +63,7 @@ static const char *commands[] = { "blockdev-setrw", "cat", "cdrom", + "checksum", "chmod", "chown", "command", diff --git a/guestfish-actions.pod b/guestfish-actions.pod index 5013a28..78cb4b7 100644 --- a/guestfish-actions.pod +++ b/guestfish-actions.pod @@ -296,6 +296,51 @@ Because of the message protocol, there is a transfer limit of somewhere between 2MB and 4MB. To transfer large files you should use FTP. +=head2 checksum + + checksum csumtype path + +This call computes the MD5, SHAx or CRC checksum of the +file named C. + +The type of checksum to compute is given by the C +parameter which must have one of the following values: + +=over 4 + +=item C + +Compute the cyclic redundancy check (CRC) specified by POSIX +for the C command. + +=item C + +Compute the MD5 hash (using the C program). + +=item C + +Compute the SHA1 hash (using the C program). + +=item C + +Compute the SHA224 hash (using the C program). + +=item C + +Compute the SHA256 hash (using the C program). + +=item C + +Compute the SHA384 hash (using the C program). + +=item C + +Compute the SHA512 hash (using the C program). + +=back + +The checksum is returned as a printable string. + =head2 chmod chmod mode path diff --git a/guestfs-actions.pod b/guestfs-actions.pod index d57dae3..b901919 100644 --- a/guestfs-actions.pod +++ b/guestfs-actions.pod @@ -388,6 +388,56 @@ Because of the message protocol, there is a transfer limit of somewhere between 2MB and 4MB. To transfer large files you should use FTP. +=head2 guestfs_checksum + + char *guestfs_checksum (guestfs_h *handle, + const char *csumtype, + const char *path); + +This call computes the MD5, SHAx or CRC checksum of the +file named C. + +The type of checksum to compute is given by the C +parameter which must have one of the following values: + +=over 4 + +=item C + +Compute the cyclic redundancy check (CRC) specified by POSIX +for the C command. + +=item C + +Compute the MD5 hash (using the C program). + +=item C + +Compute the SHA1 hash (using the C program). + +=item C + +Compute the SHA224 hash (using the C program). + +=item C + +Compute the SHA256 hash (using the C program). + +=item C + +Compute the SHA384 hash (using the C program). + +=item C + +Compute the SHA512 hash (using the C program). + +=back + +The checksum is returned as a printable string. + +This function returns a string, or NULL on error. +I. + =head2 guestfs_chmod int guestfs_chmod (guestfs_h *handle, diff --git a/ocaml/guestfs.ml b/ocaml/guestfs.ml index 09b12b1..337555c 100644 --- a/ocaml/guestfs.ml +++ b/ocaml/guestfs.ml @@ -201,3 +201,4 @@ external blockdev_flushbufs : t -> string -> unit = "ocaml_guestfs_blockdev_flus external blockdev_rereadpt : t -> string -> unit = "ocaml_guestfs_blockdev_rereadpt" external upload : t -> string -> string -> unit = "ocaml_guestfs_upload" external download : t -> string -> string -> unit = "ocaml_guestfs_download" +external checksum : t -> string -> string -> string = "ocaml_guestfs_checksum" diff --git a/ocaml/guestfs.mli b/ocaml/guestfs.mli index dfc1784..4fd05da 100644 --- a/ocaml/guestfs.mli +++ b/ocaml/guestfs.mli @@ -382,3 +382,6 @@ val upload : t -> string -> string -> unit val download : t -> string -> string -> unit (** download a file to the local machine *) +val checksum : t -> string -> string -> string +(** compute MD5, SHAx or CRC checksum of file *) + diff --git a/ocaml/guestfs_c_actions.c b/ocaml/guestfs_c_actions.c index 138f0fd..882d505 100644 --- a/ocaml/guestfs_c_actions.c +++ b/ocaml/guestfs_c_actions.c @@ -2367,3 +2367,28 @@ ocaml_guestfs_download (value gv, value remotefilenamev, value filenamev) CAMLreturn (rv); } +CAMLprim value +ocaml_guestfs_checksum (value gv, value csumtypev, value pathv) +{ + CAMLparam3 (gv, csumtypev, pathv); + CAMLlocal1 (rv); + + guestfs_h *g = Guestfs_val (gv); + if (g == NULL) + caml_failwith ("checksum: used handle after closing it"); + + const char *csumtype = String_val (csumtypev); + const char *path = String_val (pathv); + char *r; + + caml_enter_blocking_section (); + r = guestfs_checksum (g, csumtype, path); + caml_leave_blocking_section (); + if (r == NULL) + ocaml_guestfs_raise_error (g, "checksum"); + + rv = caml_copy_string (r); + free (r); + CAMLreturn (rv); +} + diff --git a/perl/Guestfs.xs b/perl/Guestfs.xs index 235c3a7..7d9b3df 100644 --- a/perl/Guestfs.xs +++ b/perl/Guestfs.xs @@ -1341,3 +1341,19 @@ PREINIT: if (r == -1) croak ("download: %s", guestfs_last_error (g)); +SV * +checksum (g, csumtype, path) + guestfs_h *g; + char *csumtype; + char *path; +PREINIT: + char *checksum; + CODE: + checksum = guestfs_checksum (g, csumtype, path); + if (checksum == NULL) + croak ("checksum: %s", guestfs_last_error (g)); + RETVAL = newSVpv (checksum, 0); + free (checksum); + OUTPUT: + RETVAL + diff --git a/perl/lib/Sys/Guestfs.pm b/perl/lib/Sys/Guestfs.pm index bd8da0f..ad20088 100644 --- a/perl/lib/Sys/Guestfs.pm +++ b/perl/lib/Sys/Guestfs.pm @@ -337,6 +337,49 @@ Because of the message protocol, there is a transfer limit of somewhere between 2MB and 4MB. To transfer large files you should use FTP. +=item $checksum = $h->checksum ($csumtype, $path); + +This call computes the MD5, SHAx or CRC checksum of the +file named C. + +The type of checksum to compute is given by the C +parameter which must have one of the following values: + +=over 4 + +=item C + +Compute the cyclic redundancy check (CRC) specified by POSIX +for the C command. + +=item C + +Compute the MD5 hash (using the C program). + +=item C + +Compute the SHA1 hash (using the C program). + +=item C + +Compute the SHA224 hash (using the C program). + +=item C + +Compute the SHA256 hash (using the C program). + +=item C + +Compute the SHA384 hash (using the C program). + +=item C + +Compute the SHA512 hash (using the C program). + +=back + +The checksum is returned as a printable string. + =item $h->chmod ($mode, $path); Change the mode (permissions) of C to C. Only diff --git a/python/guestfs-py.c b/python/guestfs-py.c index 9969c53..4d31d9f 100644 --- a/python/guestfs-py.c +++ b/python/guestfs-py.c @@ -2536,6 +2536,32 @@ py_guestfs_download (PyObject *self, PyObject *args) return py_r; } +static PyObject * +py_guestfs_checksum (PyObject *self, PyObject *args) +{ + PyObject *py_g; + guestfs_h *g; + PyObject *py_r; + char *r; + const char *csumtype; + const char *path; + + if (!PyArg_ParseTuple (args, (char *) "Oss:guestfs_checksum", + &py_g, &csumtype, &path)) + return NULL; + g = get_handle (py_g); + + r = guestfs_checksum (g, csumtype, path); + if (r == NULL) { + PyErr_SetString (PyExc_RuntimeError, guestfs_last_error (g)); + return NULL; + } + + py_r = PyString_FromString (r); + free (r); + return py_r; +} + static PyMethodDef methods[] = { { (char *) "create", py_guestfs_create, METH_VARARGS, NULL }, { (char *) "close", py_guestfs_close, METH_VARARGS, NULL }, @@ -2625,6 +2651,7 @@ static PyMethodDef methods[] = { { (char *) "blockdev_rereadpt", py_guestfs_blockdev_rereadpt, METH_VARARGS, NULL }, { (char *) "upload", py_guestfs_upload, METH_VARARGS, NULL }, { (char *) "download", py_guestfs_download, METH_VARARGS, NULL }, + { (char *) "checksum", py_guestfs_checksum, METH_VARARGS, NULL }, { NULL, NULL, 0, NULL } }; diff --git a/python/guestfs.py b/python/guestfs.py index 416404b..4d71b23 100644 --- a/python/guestfs.py +++ b/python/guestfs.py @@ -959,3 +959,41 @@ class GuestFS: """ return libguestfsmod.download (self._o, remotefilename, filename) + def checksum (self, csumtype, path): + u"""This call computes the MD5, SHAx or CRC checksum of the + file named "path". + + The type of checksum to compute is given by the + "csumtype" parameter which must have one of the + following values: + + "crc" + Compute the cyclic redundancy check (CRC) specified + by POSIX for the "cksum" command. + + "md5" + Compute the MD5 hash (using the "md5sum" program). + + "sha1" + Compute the SHA1 hash (using the "sha1sum" program). + + "sha224" + Compute the SHA224 hash (using the "sha224sum" + program). + + "sha256" + Compute the SHA256 hash (using the "sha256sum" + program). + + "sha384" + Compute the SHA384 hash (using the "sha384sum" + program). + + "sha512" + Compute the SHA512 hash (using the "sha512sum" + program). + + The checksum is returned as a printable string. + """ + return libguestfsmod.checksum (self._o, csumtype, path) + diff --git a/ruby/ext/guestfs/_guestfs.c b/ruby/ext/guestfs/_guestfs.c index 0104017..3861d9b 100644 --- a/ruby/ext/guestfs/_guestfs.c +++ b/ruby/ext/guestfs/_guestfs.c @@ -2066,6 +2066,33 @@ static VALUE ruby_guestfs_download (VALUE gv, VALUE remotefilenamev, VALUE filen return Qnil; } +static VALUE ruby_guestfs_checksum (VALUE gv, VALUE csumtypev, VALUE pathv) +{ + guestfs_h *g; + Data_Get_Struct (gv, guestfs_h, g); + if (!g) + rb_raise (rb_eArgError, "%s: used handle after closing it", "checksum"); + + const char *csumtype = StringValueCStr (csumtypev); + if (!csumtype) + rb_raise (rb_eTypeError, "expected string for parameter %s of %s", + "csumtype", "checksum"); + const char *path = StringValueCStr (pathv); + if (!path) + rb_raise (rb_eTypeError, "expected string for parameter %s of %s", + "path", "checksum"); + + char *r; + + r = guestfs_checksum (g, csumtype, path); + if (r == NULL) + rb_raise (e_Error, "%s", guestfs_last_error (g)); + + VALUE rv = rb_str_new2 (r); + free (r); + return rv; +} + /* Initialize the module. */ void Init__guestfs () { @@ -2248,4 +2275,6 @@ void Init__guestfs () ruby_guestfs_upload, 2); rb_define_method (c_guestfs, "download", ruby_guestfs_download, 2); + rb_define_method (c_guestfs, "checksum", + ruby_guestfs_checksum, 2); } diff --git a/src/guestfs-actions.c b/src/guestfs-actions.c index 1a63236..70d5cce 100644 --- a/src/guestfs-actions.c +++ b/src/guestfs-actions.c @@ -5756,3 +5756,91 @@ int guestfs_download (guestfs_h *g, return 0; } +struct checksum_ctx { + /* This flag is set by the callbacks, so we know we've done + * the callbacks as expected, and in the right sequence. + * 0 = not called, 1 = send called, + * 1001 = reply called. + */ + int cb_sequence; + struct guestfs_message_header hdr; + struct guestfs_message_error err; + struct guestfs_checksum_ret ret; +}; + +static void checksum_reply_cb (guestfs_h *g, void *data, XDR *xdr) +{ + guestfs_main_loop *ml = guestfs_get_main_loop (g); + struct checksum_ctx *ctx = (struct checksum_ctx *) data; + + ml->main_loop_quit (ml, g); + + if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) { + error (g, "%s: failed to parse reply header", "guestfs_checksum"); + return; + } + if (ctx->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &ctx->err)) { + error (g, "%s: failed to parse reply error", "guestfs_checksum"); + return; + } + goto done; + } + if (!xdr_guestfs_checksum_ret (xdr, &ctx->ret)) { + error (g, "%s: failed to parse reply", "guestfs_checksum"); + return; + } + done: + ctx->cb_sequence = 1001; +} + +char *guestfs_checksum (guestfs_h *g, + const char *csumtype, + const char *path) +{ + struct guestfs_checksum_args args; + struct checksum_ctx ctx; + guestfs_main_loop *ml = guestfs_get_main_loop (g); + int serial; + + if (check_state (g, "guestfs_checksum") == -1) return NULL; + guestfs_set_busy (g); + + memset (&ctx, 0, sizeof ctx); + + args.csumtype = (char *) csumtype; + args.path = (char *) path; + serial = guestfs__send_sync (g, GUESTFS_PROC_CHECKSUM, + (xdrproc_t) xdr_guestfs_checksum_args, (char *) &args); + if (serial == -1) { + guestfs_set_ready (g); + return NULL; + } + + read_reply: + guestfs__switch_to_receiving (g); + ctx.cb_sequence = 0; + guestfs_set_reply_callback (g, checksum_reply_cb, &ctx); + (void) ml->main_loop_run (ml, g); + guestfs_set_reply_callback (g, NULL, NULL); + if (ctx.cb_sequence != 1001) { + error (g, "%s reply failed, see earlier error messages", "guestfs_checksum"); + guestfs_set_ready (g); + return NULL; + } + + if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_CHECKSUM, serial) == -1) { + guestfs_set_ready (g); + return NULL; + } + + if (ctx.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", ctx.err.error_message); + guestfs_set_ready (g); + return NULL; + } + + guestfs_set_ready (g); + return ctx.ret.checksum; /* caller will free */ +} + diff --git a/src/guestfs-actions.h b/src/guestfs-actions.h index e3c3cf8..c694ddd 100644 --- a/src/guestfs-actions.h +++ b/src/guestfs-actions.h @@ -105,3 +105,4 @@ extern int guestfs_blockdev_flushbufs (guestfs_h *handle, const char *device); extern int guestfs_blockdev_rereadpt (guestfs_h *handle, const char *device); extern int guestfs_upload (guestfs_h *handle, const char *filename, const char *remotefilename); extern int guestfs_download (guestfs_h *handle, const char *remotefilename, const char *filename); +extern char *guestfs_checksum (guestfs_h *handle, const char *csumtype, const char *path); diff --git a/src/guestfs_protocol.c b/src/guestfs_protocol.c index 24b14a0..fc2eae9 100644 --- a/src/guestfs_protocol.c +++ b/src/guestfs_protocol.c @@ -1207,6 +1207,28 @@ xdr_guestfs_download_args (XDR *xdrs, guestfs_download_args *objp) } bool_t +xdr_guestfs_checksum_args (XDR *xdrs, guestfs_checksum_args *objp) +{ + register int32_t *buf; + + if (!xdr_string (xdrs, &objp->csumtype, ~0)) + return FALSE; + if (!xdr_string (xdrs, &objp->path, ~0)) + return FALSE; + return TRUE; +} + +bool_t +xdr_guestfs_checksum_ret (XDR *xdrs, guestfs_checksum_ret *objp) +{ + register int32_t *buf; + + if (!xdr_string (xdrs, &objp->checksum, ~0)) + return FALSE; + return TRUE; +} + +bool_t xdr_guestfs_procedure (XDR *xdrs, guestfs_procedure *objp) { register int32_t *buf; diff --git a/src/guestfs_protocol.h b/src/guestfs_protocol.h index 4c3f1cd..05bd40b 100644 --- a/src/guestfs_protocol.h +++ b/src/guestfs_protocol.h @@ -626,6 +626,17 @@ struct guestfs_download_args { }; typedef struct guestfs_download_args guestfs_download_args; +struct guestfs_checksum_args { + char *csumtype; + char *path; +}; +typedef struct guestfs_checksum_args guestfs_checksum_args; + +struct guestfs_checksum_ret { + char *checksum; +}; +typedef struct guestfs_checksum_ret guestfs_checksum_ret; + enum guestfs_procedure { GUESTFS_PROC_MOUNT = 1, GUESTFS_PROC_SYNC = 2, @@ -694,7 +705,8 @@ enum guestfs_procedure { GUESTFS_PROC_BLOCKDEV_REREADPT = 65, GUESTFS_PROC_UPLOAD = 66, GUESTFS_PROC_DOWNLOAD = 67, - GUESTFS_PROC_NR_PROCS = 67 + 1, + GUESTFS_PROC_CHECKSUM = 68, + GUESTFS_PROC_NR_PROCS = 68 + 1, }; typedef enum guestfs_procedure guestfs_procedure; #define GUESTFS_MESSAGE_MAX 4194304 @@ -839,6 +851,8 @@ extern bool_t xdr_guestfs_blockdev_flushbufs_args (XDR *, guestfs_blockdev_flus extern bool_t xdr_guestfs_blockdev_rereadpt_args (XDR *, guestfs_blockdev_rereadpt_args*); extern bool_t xdr_guestfs_upload_args (XDR *, guestfs_upload_args*); extern bool_t xdr_guestfs_download_args (XDR *, guestfs_download_args*); +extern bool_t xdr_guestfs_checksum_args (XDR *, guestfs_checksum_args*); +extern bool_t xdr_guestfs_checksum_ret (XDR *, guestfs_checksum_ret*); extern bool_t xdr_guestfs_procedure (XDR *, guestfs_procedure*); extern bool_t xdr_guestfs_message_direction (XDR *, guestfs_message_direction*); extern bool_t xdr_guestfs_message_status (XDR *, guestfs_message_status*); @@ -942,6 +956,8 @@ extern bool_t xdr_guestfs_blockdev_flushbufs_args (); extern bool_t xdr_guestfs_blockdev_rereadpt_args (); extern bool_t xdr_guestfs_upload_args (); extern bool_t xdr_guestfs_download_args (); +extern bool_t xdr_guestfs_checksum_args (); +extern bool_t xdr_guestfs_checksum_ret (); extern bool_t xdr_guestfs_procedure (); extern bool_t xdr_guestfs_message_direction (); extern bool_t xdr_guestfs_message_status (); diff --git a/src/guestfs_protocol.x b/src/guestfs_protocol.x index ff4713f..ca2d0ce 100644 --- a/src/guestfs_protocol.x +++ b/src/guestfs_protocol.x @@ -483,6 +483,15 @@ struct guestfs_download_args { string remotefilename<>; }; +struct guestfs_checksum_args { + string csumtype<>; + string path<>; +}; + +struct guestfs_checksum_ret { + string checksum<>; +}; + enum guestfs_procedure { GUESTFS_PROC_MOUNT = 1, GUESTFS_PROC_SYNC = 2, @@ -551,6 +560,7 @@ enum guestfs_procedure { GUESTFS_PROC_BLOCKDEV_REREADPT = 65, GUESTFS_PROC_UPLOAD = 66, GUESTFS_PROC_DOWNLOAD = 67, + GUESTFS_PROC_CHECKSUM = 68, GUESTFS_PROC_NR_PROCS }; diff --git a/tests.c b/tests.c index bd541be..9744575 100644 --- a/tests.c +++ b/tests.c @@ -105,6 +105,515 @@ static void no_test_warnings (void) fprintf (stderr, "warning: \"guestfs_download\" has no tests\n"); } +static int test_checksum_0 (void) +{ + /* InitBasicFS for checksum (0): create ext2 on /dev/sda1 */ + { + int r; + suppress_error = 0; + r = guestfs_umount_all (g); + if (r == -1) + return -1; + } + { + int r; + suppress_error = 0; + r = guestfs_lvm_remove_all (g); + if (r == -1) + return -1; + } + { + char *lines[] = { + ",", + NULL + }; + int r; + suppress_error = 0; + r = guestfs_sfdisk (g, "/dev/sda", 0, 0, 0, lines); + if (r == -1) + return -1; + } + { + int r; + suppress_error = 0; + r = guestfs_mkfs (g, "ext2", "/dev/sda1"); + if (r == -1) + return -1; + } + { + int r; + suppress_error = 0; + r = guestfs_mount (g, "/dev/sda1", "/"); + if (r == -1) + return -1; + } + /* TestOutput for checksum (0) */ + { + int r; + suppress_error = 0; + r = guestfs_write_file (g, "/new", "test\n", 0); + if (r == -1) + return -1; + } + { + char *r; + suppress_error = 0; + r = guestfs_checksum (g, "crc", "/new"); + if (r == NULL) + return -1; + if (strcmp (r, "935282863") != 0) { + fprintf (stderr, "test_checksum_0: expected \"935282863\" but got \"%s\"\n", r); + return -1; + } + free (r); + } + return 0; +} + +static int test_checksum_1 (void) +{ + /* InitBasicFS for checksum (1): create ext2 on /dev/sda1 */ + { + int r; + suppress_error = 0; + r = guestfs_umount_all (g); + if (r == -1) + return -1; + } + { + int r; + suppress_error = 0; + r = guestfs_lvm_remove_all (g); + if (r == -1) + return -1; + } + { + char *lines[] = { + ",", + NULL + }; + int r; + suppress_error = 0; + r = guestfs_sfdisk (g, "/dev/sda", 0, 0, 0, lines); + if (r == -1) + return -1; + } + { + int r; + suppress_error = 0; + r = guestfs_mkfs (g, "ext2", "/dev/sda1"); + if (r == -1) + return -1; + } + { + int r; + suppress_error = 0; + r = guestfs_mount (g, "/dev/sda1", "/"); + if (r == -1) + return -1; + } + /* TestLastFail for checksum (1) */ + { + char *r; + suppress_error = 1; + r = guestfs_checksum (g, "crc", "/new"); + if (r != NULL) + return -1; + free (r); + } + return 0; +} + +static int test_checksum_2 (void) +{ + /* InitBasicFS for checksum (2): create ext2 on /dev/sda1 */ + { + int r; + suppress_error = 0; + r = guestfs_umount_all (g); + if (r == -1) + return -1; + } + { + int r; + suppress_error = 0; + r = guestfs_lvm_remove_all (g); + if (r == -1) + return -1; + } + { + char *lines[] = { + ",", + NULL + }; + int r; + suppress_error = 0; + r = guestfs_sfdisk (g, "/dev/sda", 0, 0, 0, lines); + if (r == -1) + return -1; + } + { + int r; + suppress_error = 0; + r = guestfs_mkfs (g, "ext2", "/dev/sda1"); + if (r == -1) + return -1; + } + { + int r; + suppress_error = 0; + r = guestfs_mount (g, "/dev/sda1", "/"); + if (r == -1) + return -1; + } + /* TestOutput for checksum (2) */ + { + int r; + suppress_error = 0; + r = guestfs_write_file (g, "/new", "test\n", 0); + if (r == -1) + return -1; + } + { + char *r; + suppress_error = 0; + r = guestfs_checksum (g, "md5", "/new"); + if (r == NULL) + return -1; + if (strcmp (r, "d8e8fca2dc0f896fd7cb4cb0031ba249") != 0) { + fprintf (stderr, "test_checksum_2: expected \"d8e8fca2dc0f896fd7cb4cb0031ba249\" but got \"%s\"\n", r); + return -1; + } + free (r); + } + return 0; +} + +static int test_checksum_3 (void) +{ + /* InitBasicFS for checksum (3): create ext2 on /dev/sda1 */ + { + int r; + suppress_error = 0; + r = guestfs_umount_all (g); + if (r == -1) + return -1; + } + { + int r; + suppress_error = 0; + r = guestfs_lvm_remove_all (g); + if (r == -1) + return -1; + } + { + char *lines[] = { + ",", + NULL + }; + int r; + suppress_error = 0; + r = guestfs_sfdisk (g, "/dev/sda", 0, 0, 0, lines); + if (r == -1) + return -1; + } + { + int r; + suppress_error = 0; + r = guestfs_mkfs (g, "ext2", "/dev/sda1"); + if (r == -1) + return -1; + } + { + int r; + suppress_error = 0; + r = guestfs_mount (g, "/dev/sda1", "/"); + if (r == -1) + return -1; + } + /* TestOutput for checksum (3) */ + { + int r; + suppress_error = 0; + r = guestfs_write_file (g, "/new", "test\n", 0); + if (r == -1) + return -1; + } + { + char *r; + suppress_error = 0; + r = guestfs_checksum (g, "sha1", "/new"); + if (r == NULL) + return -1; + if (strcmp (r, "4e1243bd22c66e76c2ba9eddc1f91394e57f9f83") != 0) { + fprintf (stderr, "test_checksum_3: expected \"4e1243bd22c66e76c2ba9eddc1f91394e57f9f83\" but got \"%s\"\n", r); + return -1; + } + free (r); + } + return 0; +} + +static int test_checksum_4 (void) +{ + /* InitBasicFS for checksum (4): create ext2 on /dev/sda1 */ + { + int r; + suppress_error = 0; + r = guestfs_umount_all (g); + if (r == -1) + return -1; + } + { + int r; + suppress_error = 0; + r = guestfs_lvm_remove_all (g); + if (r == -1) + return -1; + } + { + char *lines[] = { + ",", + NULL + }; + int r; + suppress_error = 0; + r = guestfs_sfdisk (g, "/dev/sda", 0, 0, 0, lines); + if (r == -1) + return -1; + } + { + int r; + suppress_error = 0; + r = guestfs_mkfs (g, "ext2", "/dev/sda1"); + if (r == -1) + return -1; + } + { + int r; + suppress_error = 0; + r = guestfs_mount (g, "/dev/sda1", "/"); + if (r == -1) + return -1; + } + /* TestOutput for checksum (4) */ + { + int r; + suppress_error = 0; + r = guestfs_write_file (g, "/new", "test\n", 0); + if (r == -1) + return -1; + } + { + char *r; + suppress_error = 0; + r = guestfs_checksum (g, "sha224", "/new"); + if (r == NULL) + return -1; + if (strcmp (r, "52f1bf093f4b7588726035c176c0cdb4376cfea53819f1395ac9e6ec") != 0) { + fprintf (stderr, "test_checksum_4: expected \"52f1bf093f4b7588726035c176c0cdb4376cfea53819f1395ac9e6ec\" but got \"%s\"\n", r); + return -1; + } + free (r); + } + return 0; +} + +static int test_checksum_5 (void) +{ + /* InitBasicFS for checksum (5): create ext2 on /dev/sda1 */ + { + int r; + suppress_error = 0; + r = guestfs_umount_all (g); + if (r == -1) + return -1; + } + { + int r; + suppress_error = 0; + r = guestfs_lvm_remove_all (g); + if (r == -1) + return -1; + } + { + char *lines[] = { + ",", + NULL + }; + int r; + suppress_error = 0; + r = guestfs_sfdisk (g, "/dev/sda", 0, 0, 0, lines); + if (r == -1) + return -1; + } + { + int r; + suppress_error = 0; + r = guestfs_mkfs (g, "ext2", "/dev/sda1"); + if (r == -1) + return -1; + } + { + int r; + suppress_error = 0; + r = guestfs_mount (g, "/dev/sda1", "/"); + if (r == -1) + return -1; + } + /* TestOutput for checksum (5) */ + { + int r; + suppress_error = 0; + r = guestfs_write_file (g, "/new", "test\n", 0); + if (r == -1) + return -1; + } + { + char *r; + suppress_error = 0; + r = guestfs_checksum (g, "sha256", "/new"); + if (r == NULL) + return -1; + if (strcmp (r, "f2ca1bb6c7e907d06dafe4687e579fce76b37e4e93b7605022da52e6ccc26fd2") != 0) { + fprintf (stderr, "test_checksum_5: expected \"f2ca1bb6c7e907d06dafe4687e579fce76b37e4e93b7605022da52e6ccc26fd2\" but got \"%s\"\n", r); + return -1; + } + free (r); + } + return 0; +} + +static int test_checksum_6 (void) +{ + /* InitBasicFS for checksum (6): create ext2 on /dev/sda1 */ + { + int r; + suppress_error = 0; + r = guestfs_umount_all (g); + if (r == -1) + return -1; + } + { + int r; + suppress_error = 0; + r = guestfs_lvm_remove_all (g); + if (r == -1) + return -1; + } + { + char *lines[] = { + ",", + NULL + }; + int r; + suppress_error = 0; + r = guestfs_sfdisk (g, "/dev/sda", 0, 0, 0, lines); + if (r == -1) + return -1; + } + { + int r; + suppress_error = 0; + r = guestfs_mkfs (g, "ext2", "/dev/sda1"); + if (r == -1) + return -1; + } + { + int r; + suppress_error = 0; + r = guestfs_mount (g, "/dev/sda1", "/"); + if (r == -1) + return -1; + } + /* TestOutput for checksum (6) */ + { + int r; + suppress_error = 0; + r = guestfs_write_file (g, "/new", "test\n", 0); + if (r == -1) + return -1; + } + { + char *r; + suppress_error = 0; + r = guestfs_checksum (g, "sha384", "/new"); + if (r == NULL) + return -1; + if (strcmp (r, "109bb6b5b6d5547c1ce03c7a8bd7d8f80c1cb0957f50c4f7fda04692079917e4f9cad52b878f3d8234e1a170b154b72d") != 0) { + fprintf (stderr, "test_checksum_6: expected \"109bb6b5b6d5547c1ce03c7a8bd7d8f80c1cb0957f50c4f7fda04692079917e4f9cad52b878f3d8234e1a170b154b72d\" but got \"%s\"\n", r); + return -1; + } + free (r); + } + return 0; +} + +static int test_checksum_7 (void) +{ + /* InitBasicFS for checksum (7): create ext2 on /dev/sda1 */ + { + int r; + suppress_error = 0; + r = guestfs_umount_all (g); + if (r == -1) + return -1; + } + { + int r; + suppress_error = 0; + r = guestfs_lvm_remove_all (g); + if (r == -1) + return -1; + } + { + char *lines[] = { + ",", + NULL + }; + int r; + suppress_error = 0; + r = guestfs_sfdisk (g, "/dev/sda", 0, 0, 0, lines); + if (r == -1) + return -1; + } + { + int r; + suppress_error = 0; + r = guestfs_mkfs (g, "ext2", "/dev/sda1"); + if (r == -1) + return -1; + } + { + int r; + suppress_error = 0; + r = guestfs_mount (g, "/dev/sda1", "/"); + if (r == -1) + return -1; + } + /* TestOutput for checksum (7) */ + { + int r; + suppress_error = 0; + r = guestfs_write_file (g, "/new", "test\n", 0); + if (r == -1) + return -1; + } + { + char *r; + suppress_error = 0; + r = guestfs_checksum (g, "sha512", "/new"); + if (r == NULL) + return -1; + if (strcmp (r, "0e3e75234abc68f4378a86b3f4b32a198ba301845b0cd6e50106e874345700cc6663a86c1ea125dc5e92be17c98f9a0f85ca9d5f595db2012f7cc3571945c123") != 0) { + fprintf (stderr, "test_checksum_7: expected \"0e3e75234abc68f4378a86b3f4b32a198ba301845b0cd6e50106e874345700cc6663a86c1ea125dc5e92be17c98f9a0f85ca9d5f595db2012f7cc3571945c123\" but got \"%s\"\n", r); + return -1; + } + free (r); + } + return 0; +} + static int test_blockdev_rereadpt_0 (void) { /* InitEmpty for blockdev_rereadpt (0) */ @@ -4508,9 +5017,57 @@ int main (int argc, char *argv[]) exit (1); } - nr_tests = 63; + nr_tests = 71; test_num++; + printf ("%3d/%3d test_checksum_0\n", test_num, nr_tests); + if (test_checksum_0 () == -1) { + printf ("test_checksum_0 FAILED\n"); + failed++; + } + test_num++; + printf ("%3d/%3d test_checksum_1\n", test_num, nr_tests); + if (test_checksum_1 () == -1) { + printf ("test_checksum_1 FAILED\n"); + failed++; + } + test_num++; + printf ("%3d/%3d test_checksum_2\n", test_num, nr_tests); + if (test_checksum_2 () == -1) { + printf ("test_checksum_2 FAILED\n"); + failed++; + } + test_num++; + printf ("%3d/%3d test_checksum_3\n", test_num, nr_tests); + if (test_checksum_3 () == -1) { + printf ("test_checksum_3 FAILED\n"); + failed++; + } + test_num++; + printf ("%3d/%3d test_checksum_4\n", test_num, nr_tests); + if (test_checksum_4 () == -1) { + printf ("test_checksum_4 FAILED\n"); + failed++; + } + test_num++; + printf ("%3d/%3d test_checksum_5\n", test_num, nr_tests); + if (test_checksum_5 () == -1) { + printf ("test_checksum_5 FAILED\n"); + failed++; + } + test_num++; + printf ("%3d/%3d test_checksum_6\n", test_num, nr_tests); + if (test_checksum_6 () == -1) { + printf ("test_checksum_6 FAILED\n"); + failed++; + } + test_num++; + printf ("%3d/%3d test_checksum_7\n", test_num, nr_tests); + if (test_checksum_7 () == -1) { + printf ("test_checksum_7 FAILED\n"); + failed++; + } + test_num++; printf ("%3d/%3d test_blockdev_rereadpt_0\n", test_num, nr_tests); if (test_blockdev_rereadpt_0 () == -1) { printf ("test_blockdev_rereadpt_0 FAILED\n"); -- 1.8.3.1