Initial original import from: fuse-2.4.2-2.fc4
[captive.git] / src / client / cmdline / cmd_get.c
index 3d815a9..87daf72 100644 (file)
 #include <errno.h>
 #include <unistd.h>
 #include <captive/macros.h>
+#include <stdlib.h>
 
 #include "cmd_get.h"   /* self */
 #include "cmd_cd.h"    /* for cmdline_path_from_cwd() */
 #include "main.h"
+#include "utf8.h"
 
 
 /* Config: */
-#define TRANSFER_BUFFER_SIZE (0x10000)
+#define DEFAULT_TRANSFER_BUFFER_SIZE (0x10000)
 
 
 GQuark cmdline_cmd_get_error_quark(void)
@@ -48,7 +50,11 @@ GQuark r=0;
 }
 
 
+static gchar *optarg_transfer_buffer;
+
 const struct poptOption cmd_get_table[]={
+               CMDLINE_POPT("buffer-size",'b',POPT_ARG_STRING,&optarg_transfer_buffer,
+                               N_("Transfer buffer size"),N_("size")),
                CMDLINE_POPT_AUTOHELP
                POPT_TABLEEND
                };
@@ -60,10 +66,26 @@ CaptiveFileObject *captive_file_object;
 const gchar *sourcefile,*targetfile;
 guint perm=0644;
 int fdtgt;
-guint8 transfer_buffer[TRANSFER_BUFFER_SIZE];
+guint8 *transfer_buffer;
+long transfer_buffer_size=DEFAULT_TRANSFER_BUFFER_SIZE;
 
        g_return_if_fail(!errp || !*errp);
 
+       if (optarg_transfer_buffer) {
+const gchar *string=captive_strdup_alloca(optarg_transfer_buffer);
+char *endptr;
+
+               free(optarg_transfer_buffer);
+               optarg_transfer_buffer=NULL;
+
+               transfer_buffer_size=strtol(string,&endptr,0);
+               if (transfer_buffer_size<=0 || transfer_buffer_size>=LONG_MAX || (endptr && *endptr)) {
+                       g_set_error(errp,CMDLINE_CMD_GET_ERROR,CMDLINE_CMD_GET_ERROR_PARSING_TRANSFER_BUFFER_SIZE,
+                                       _("Error parsing transfer buffer size: %s"),CMD_LOCALE_FROM_UTF8_ALLOCA(string));
+                       return;
+                       }
+               }
+
        sourcefile=cmdline_path_from_cwd(cmd_argv[0]);
        if (cmd_argv[1])
                targetfile=captive_strdup_alloca(cmdline_path_from_cwd(cmd_argv[1]));
@@ -75,7 +97,7 @@ char *s;
                        targetfile=s+1;
                }
 
-       if (-1==(fdtgt=open(targetfile,
+       if (-1==(fdtgt=open(CMD_FILENAME_FROM_UTF8_ALLOCA(targetfile),
                        O_CREAT|O_EXCL|O_WRONLY /* flags */
 #ifdef O_BINARY
                                        | O_BINARY
@@ -86,7 +108,7 @@ char *s;
                                        ,
                        perm))) {       /* mode */
                g_set_error(errp,CMDLINE_CMD_GET_ERROR,CMDLINE_CMD_GET_ERROR_CANNOT_CREATE_TARGET_HOSTOS_FILE,
-                               _("Cannot create target host-os file: %s"),targetfile);
+                               _("Cannot create target host-os file '%s': %s"),CMD_LOCALE_FROM_UTF8_ALLOCA(targetfile),g_strerror(errno));
                return;
                }
 
@@ -97,10 +119,13 @@ char *s;
                        GNOME_VFS_OPEN_READ))) {        /* mode */
                err_cleanup(errp);
                g_set_error(errp,CMDLINE_CMD_GET_ERROR,CMDLINE_CMD_GET_ERROR_OPENING_SOURCE_FILE,
-                               _("Error opening source guest-os file '%s': %s"),sourcefile,g_strerror(errno));
+                               _("Error opening source guest-os file: %s"),CMD_LOCALE_FROM_UTF8_ALLOCA(sourcefile));
                goto err_close_fdtgt;
                }
 
+       transfer_buffer=g_malloc(transfer_buffer_size);
+       g_assert(transfer_buffer!=NULL);        /* Should not happen. */
+
        for (;;) {
 GnomeVFSFileSize bytes_read;
 GnomeVFSResult errvfsresult;
@@ -109,7 +134,7 @@ ssize_t gotssize;
                errvfsresult=captive_file_read(
                                captive_file_object,    /* captive_file_object */
                                transfer_buffer,        /* buffer */
-                               sizeof(transfer_buffer),        /* num_bytes */
+                               transfer_buffer_size,   /* num_bytes */
                                &bytes_read);   /* bytes_read_return */
                g_assert(errvfsresult==GNOME_VFS_OK || errvfsresult==GNOME_VFS_ERROR_EOF);
                g_assert((errvfsresult==GNOME_VFS_ERROR_EOF)==(bytes_read==0));
@@ -122,23 +147,25 @@ gboolean errbool;
                        g_assert(errbool==FALSE);
                        err_cleanup(errp);
                        g_set_error(errp,CMDLINE_CMD_GET_ERROR,CMDLINE_CMD_GET_ERROR_READING_SOURCE_FILE,
-                                       _("Error reading source guest-os file '%s': %s"),sourcefile,g_strerror(errno));
-                       goto err_unref_captive_file_object;
+                                       _("Error reading source guest-os file '%s': %s"),CMD_LOCALE_FROM_UTF8_ALLOCA(sourcefile),g_strerror(errno));
+                       goto err_free_transfer_buffer;
                        }
 
                if (bytes_read!=(GnomeVFSFileSize)(gotssize=write(fdtgt,transfer_buffer,bytes_read))) {
                        g_set_error(errp,CMDLINE_CMD_GET_ERROR,CMDLINE_CMD_GET_ERROR_WRITING_TARGET_HOSTOS_FILE,
-                                       _("Error writing target host-os file: %s"),targetfile);
-                       goto err_unref_captive_file_object;
+                                       _("Error writing target host-os file: %s"),CMD_LOCALE_FROM_UTF8_ALLOCA(targetfile));
+                       goto err_free_transfer_buffer;
                        }
                }
 
-err_unref_captive_file_object:
+err_free_transfer_buffer:
+       g_free(transfer_buffer);
+/* err_unref_captive_file_object: */
        g_object_unref(captive_file_object);
 err_close_fdtgt:
        if (close(fdtgt)) {
                err_cleanup(errp);      /* may be clean */
                g_set_error(errp,CMDLINE_CMD_GET_ERROR,CMDLINE_CMD_GET_ERROR_CLOSING_TARGET_HOSTOS_FILE,
-                               _("Error closing target host-os file '%s': %s"),targetfile,g_strerror(errno));
+                               _("Error closing target host-os file '%s': %s"),CMD_LOCALE_FROM_UTF8_ALLOCA(targetfile),g_strerror(errno));
                }
 }