[libvirt] [PATCH 08/11] DEMO: Add file put / get commands to virsh as a stream demo

Daniel P. Berrange berrange at redhat.com
Mon Aug 24 20:51:11 UTC 2009


* src/virsh.c: Implement 'put' and 'get' commands
* .x-sc_avoid_write: Ignore src/virsh.c
---
 .x-sc_avoid_write |    1 +
 src/virsh.c       |  164 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 165 insertions(+), 0 deletions(-)

diff --git a/.x-sc_avoid_write b/.x-sc_avoid_write
index c5a7535..c37574d 100644
--- a/.x-sc_avoid_write
+++ b/.x-sc_avoid_write
@@ -2,5 +2,6 @@
 ^src/xend_internal\.c$
 ^src/util-lib\.c$
 ^src/libvirt\.c$
+^src/virsh\.c$
 ^qemud/qemud.c$
 ^gnulib/
diff --git a/src/virsh.c b/src/virsh.c
index 2d0cf81..6387a3c 100644
--- a/src/virsh.c
+++ b/src/virsh.c
@@ -6780,6 +6780,167 @@ cmdEdit (vshControl *ctl, const vshCmd *cmd)
 }
 
 /*
+ * "put" command
+ */
+static const vshCmdInfo info_put[] = {
+    {"help", gettext_noop("upload a file")},
+    {"desc", gettext_noop("Upload a file")},
+    {NULL, NULL}
+};
+
+static const vshCmdOptDef opts_put[] = {
+    {"file", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("file")},
+    {"name", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("name")},
+    {NULL, 0, 0, NULL}
+};
+
+
+static int
+cmdPutSource(virStreamPtr st ATTRIBUTE_UNUSED,
+             char *bytes, size_t nbytes, void *opaque)
+{
+    int *fd = opaque;
+
+    return read(*fd, bytes, nbytes);
+}
+
+/*
+ */
+static int
+cmdPut (vshControl *ctl, const vshCmd *cmd)
+{
+    char *file = NULL;
+    char *name = NULL;
+    int ret = FALSE;
+    int fd = -1;
+    virStreamPtr st = NULL;
+
+    if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
+        goto cleanup;
+
+    name = vshCommandOptString (cmd, "name", NULL);
+    if (name == NULL)
+        goto cleanup;
+    file = vshCommandOptString (cmd, "file", NULL);
+    if (file == NULL)
+        goto cleanup;
+
+    if ((fd = open(file, O_RDONLY)) < 0) {
+        vshError(ctl, FALSE, "cannot read %s", name);
+        goto cleanup;
+    }
+
+    st = virStreamNew(ctl->conn, 0);
+    if (virConnectPutFile(ctl->conn, name, st) < 0)
+        goto cleanup;
+
+    if (virStreamSendAll(st, cmdPutSource, &fd) < 0)
+        goto cleanup;
+
+    if (close(fd) < 0) {
+        virStreamAbort(st);
+        goto cleanup;
+    }
+    fd = -1;
+    if (virStreamFinish(st) < 0)
+        goto cleanup;
+
+    ret = TRUE;
+
+cleanup:
+    if (st)
+        virStreamFree(st);
+    free(name);
+    free(file);
+    if (fd != -1)
+        close(fd);
+    return ret;
+}
+
+
+
+/*
+ * "get" command
+ */
+static const vshCmdInfo info_get[] = {
+    {"help", gettext_noop("upload a file")},
+    {"desc", gettext_noop("Upload a file")},
+    {NULL, NULL}
+};
+
+static const vshCmdOptDef opts_get[] = {
+    {"file", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("file")},
+    {"name", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("name")},
+    {NULL, 0, 0, NULL}
+};
+
+
+static int
+cmdGetSink(virStreamPtr st ATTRIBUTE_UNUSED,
+           const char *bytes, size_t nbytes, void *opaque)
+{
+    int *fd = opaque;
+
+    return write(*fd, bytes, nbytes);
+}
+
+/*
+ */
+static int
+cmdGet (vshControl *ctl, const vshCmd *cmd)
+{
+    char *file = NULL;
+    char *name = NULL;
+    int ret = FALSE;
+    int fd = -1;
+    virStreamPtr st = NULL;
+
+    if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
+        goto cleanup;
+
+    name = vshCommandOptString (cmd, "name", NULL);
+    if (name == NULL)
+        goto cleanup;
+    file = vshCommandOptString (cmd, "file", NULL);
+    if (file == NULL)
+        goto cleanup;
+
+    if ((fd = open(file, O_WRONLY|O_TRUNC|O_CREAT,0700)) < 0) {
+        vshError(ctl, FALSE, "cannot create %s", name);
+        goto cleanup;
+    }
+
+    st = virStreamNew(ctl->conn, 0);
+    if (virConnectGetFile(ctl->conn, name, st) < 0)
+        goto cleanup;
+
+    if (virStreamRecvAll(st, cmdGetSink, &fd) < 0)
+        goto cleanup;
+
+    if (close(fd) < 0) {
+        virStreamAbort(st);
+        goto cleanup;
+    }
+    fd = -1;
+    if (virStreamFinish(st) < 0)
+        goto cleanup;
+
+    ret = TRUE;
+
+cleanup:
+    if (ret == FALSE)
+        unlink(file);
+    if (st)
+        virStreamFree(st);
+    free(name);
+    free(file);
+    if (fd != -1)
+        close(fd);
+    return ret;
+}
+
+
+/*
  * "net-edit" command
  */
 static const vshCmdInfo info_network_edit[] = {
@@ -6958,6 +7119,9 @@ static const vshCmdDef commands[] = {
     {"vcpupin", cmdVcpupin, opts_vcpupin, info_vcpupin},
     {"version", cmdVersion, NULL, info_version},
     {"vncdisplay", cmdVNCDisplay, opts_vncdisplay, info_vncdisplay},
+
+    {"put", cmdPut, opts_put, info_put},
+    {"get", cmdGet, opts_get, info_get},
     {NULL, NULL, NULL, NULL}
 };
 
-- 
1.6.2.5




More information about the libvir-list mailing list