summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--TODO23
-rw-r--r--daemon/Makefile.am1
-rw-r--r--daemon/base64.c150
-rw-r--r--images/Makefile.am4
-rw-r--r--po/POTFILES.in1
-rw-r--r--src/MAX_PROC_NR2
-rwxr-xr-xsrc/generator.ml16
8 files changed, 174 insertions, 24 deletions
diff --git a/.gitignore b/.gitignore
index fa231500..382cbcf1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -103,6 +103,7 @@ images/100kallspaces
images/100kallzeroes
images/100krandom
images/10klines
+images/hello.b64
images/initrd
images/initrd-x86_64.img
images/initrd-x86_64.img.gz
diff --git a/TODO b/TODO
index e99f7ed6..56b429a9 100644
--- a/TODO
+++ b/TODO
@@ -271,26 +271,3 @@ List filesystems by UUID or label.
Mount filesystems by UUID or label. (I'm not really sure if we can do
this at the moment but we ought to be able to do it, and perhaps make
it easier by having a direct command).
-
-UUencoded uploads
------------------
-
-(Or base64). Something like:
-
-base64-in -<<EOF
-TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz
-IHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2Yg
-dGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGlu
-dWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRo
-ZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=
-EOF
-
-Arbitrary scripts
------------------
-
-debug-upload -<<EOF script
-#!/bin/sh -
-...
-EOF
-
-debug sh ...
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
index 7bfb2808..3fa2b319 100644
--- a/daemon/Makefile.am
+++ b/daemon/Makefile.am
@@ -64,6 +64,7 @@ guestfsd_SOURCES = \
actions.h \
available.c \
augeas.c \
+ base64.c \
blkid.c \
blockdev.c \
checksum.c \
diff --git a/daemon/base64.c b/daemon/base64.c
new file mode 100644
index 00000000..89bf4379
--- /dev/null
+++ b/daemon/base64.c
@@ -0,0 +1,150 @@
+/* libguestfs - the guestfsd daemon
+ * Copyright (C) 2010 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+
+#include "../src/guestfs_protocol.h"
+#include "daemon.h"
+#include "actions.h"
+
+static int
+write_cb (void *fd_ptr, const void *buf, size_t len)
+{
+ int fd = *(int *)fd_ptr;
+ return xwrite (fd, buf, len);
+}
+
+/* Has one FileIn parameter. */
+int
+do_base64_in (const char *file)
+{
+ int err, r;
+ FILE *fp;
+ char *cmd;
+
+ if (asprintf_nowarn (&cmd, "base64 -d > %R", file) == -1) {
+ err = errno;
+ cancel_receive ();
+ errno = err;
+ reply_with_perror ("asprintf");
+ return -1;
+ }
+
+ if (verbose)
+ fprintf (stderr, "%s\n", cmd);
+
+ fp = popen (cmd, "w");
+ if (fp == NULL) {
+ err = errno;
+ cancel_receive ();
+ errno = err;
+ reply_with_perror ("%s", cmd);
+ free (cmd);
+ return -1;
+ }
+ free (cmd);
+
+ /* The semantics of fwrite are too undefined, so write to the
+ * file descriptor directly instead.
+ */
+ int fd = fileno (fp);
+
+ r = receive_file (write_cb, &fd);
+ if (r == -1) { /* write error */
+ cancel_receive ();
+ reply_with_error ("write error on file: %s", file);
+ pclose (fp);
+ return -1;
+ }
+ if (r == -2) { /* cancellation from library */
+ pclose (fp);
+ /* Do NOT send any error. */
+ return -1;
+ }
+
+ if (pclose (fp) != 0) {
+ if (r == -1) /* if r == 0, file transfer ended already */
+ cancel_receive ();
+ reply_with_error ("base64 subcommand failed on file: %s", file);
+ return -1;
+ }
+
+ return 0;
+}
+
+/* Has one FileOut parameter. */
+int
+do_base64_out (const char *file)
+{
+ int r;
+ FILE *fp;
+ char *cmd;
+ char buf[GUESTFS_MAX_CHUNK_SIZE];
+
+ if (asprintf_nowarn (&cmd, "base64 %R", file) == -1) {
+ reply_with_perror ("asprintf");
+ return -1;
+ }
+
+ if (verbose)
+ fprintf (stderr, "%s\n", cmd);
+
+ fp = popen (cmd, "r");
+ if (fp == NULL) {
+ reply_with_perror ("%s", cmd);
+ free (cmd);
+ return -1;
+ }
+ free (cmd);
+
+ /* Now we must send the reply message, before the file contents. After
+ * this there is no opportunity in the protocol to send any error
+ * message back. Instead we can only cancel the transfer.
+ */
+ reply (NULL, NULL);
+
+ while ((r = fread (buf, 1, sizeof buf, fp)) > 0) {
+ if (send_file_write (buf, r) < 0) {
+ pclose (fp);
+ return -1;
+ }
+ }
+
+ if (ferror (fp)) {
+ perror (file);
+ send_file_end (1); /* Cancel. */
+ pclose (fp);
+ return -1;
+ }
+
+ if (pclose (fp) != 0) {
+ perror (file);
+ send_file_end (1); /* Cancel. */
+ return -1;
+ }
+
+ if (send_file_end (0)) /* Normal end of file. */
+ return -1;
+
+ return 0;
+}
diff --git a/images/Makefile.am b/images/Makefile.am
index ff8d46fb..7f35b757 100644
--- a/images/Makefile.am
+++ b/images/Makefile.am
@@ -73,6 +73,7 @@ images_files_build = \
$(builddir)/100kallspaces \
$(builddir)/100krandom \
$(builddir)/10klines \
+ $(builddir)/hello.b64 \
$(builddir)/initrd \
$(builddir)/initrd-x86_64.img \
$(builddir)/initrd-x86_64.img.gz \
@@ -118,6 +119,9 @@ $(builddir)/10klines:
done > $@-t
mv $@-t $@
+$(builddir)/hello.b64:
+ echo "hello" | base64 > $@
+
$(builddir)/initrd: empty known-1 known-2 known-3 known-4 known-5
rm -f $@ $@-t
for f in $^; do echo $$f; done | cpio -o -H newc | gzip --best > $@-t
diff --git a/po/POTFILES.in b/po/POTFILES.in
index a5a27fae..aebe4504 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -1,6 +1,7 @@
appliance/libguestfs-supermin-helper.c
daemon/augeas.c
daemon/available.c
+daemon/base64.c
daemon/blkid.c
daemon/blockdev.c
daemon/checksum.c
diff --git a/src/MAX_PROC_NR b/src/MAX_PROC_NR
index f06fa6c9..77f83230 100644
--- a/src/MAX_PROC_NR
+++ b/src/MAX_PROC_NR
@@ -1 +1 @@
-241
+243
diff --git a/src/generator.ml b/src/generator.ml
index 77fa0530..b274411b 100755
--- a/src/generator.ml
+++ b/src/generator.ml
@@ -4520,6 +4520,22 @@ There is no comprehensive help for this command. You have
to look at the file C<daemon/debug.c> in the libguestfs source
to find out what it is for.");
+ ("base64_in", (RErr, [FileIn "base64file"; Pathname "filename"]), 242, [],
+ [InitBasicFS, Always, TestOutput (
+ [["base64_in"; "../images/hello.b64"; "/hello"];
+ ["cat"; "/hello"]], "hello\n")],
+ "upload base64-encoded data to file",
+ "\
+This command uploads base64-encoded data from C<base64file>
+to C<filename>.");
+
+ ("base64_out", (RErr, [Pathname "filename"; FileOut "base64file"]), 243, [],
+ [],
+ "download file and encode as base64",
+ "\
+This command downloads the contents of C<filename>, writing
+it out to local file C<base64file> encoded as base64.");
+
]
let all_functions = non_daemon_functions @ daemon_functions