Initial original import from: fuse-2.4.2-2.fc4
[captive.git] / src / client / cmdline / cmd_put.c
index d6564f0..910eb15 100644 (file)
 #include <glib/gmessages.h>
 #include <glib/gerror.h>
 #include <popt.h>
-#include "captive/client-file.h"
+#include <captive/client-file.h>
 #include <fcntl.h>
 #include <errno.h>
 #include <unistd.h>
+#include <captive/macros.h>
+#include <stdlib.h>
 
 #include "cmd_put.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_put_error_quark(void)
@@ -47,8 +50,12 @@ GQuark r=0;
 }
 
 
+static gchar *optarg_transfer_buffer;
+
 const struct poptOption cmd_put_table[]={
-               POPT_AUTOHELP
+               CMDLINE_POPT("buffer-size",'b',POPT_ARG_STRING,&optarg_transfer_buffer,
+                               N_("Transfer buffer size"),N_("size")),
+               CMDLINE_POPT_AUTOHELP
                POPT_TABLEEND
                };
 
@@ -59,11 +66,27 @@ CaptiveFileObject *captive_file_object;
 const gchar *sourcefile,*targetfile;
 guint perm=0644;
 int fdsrc;
-guint8 transfer_buffer[TRANSFER_BUFFER_SIZE];
+guint8 *transfer_buffer;
+long transfer_buffer_size=DEFAULT_TRANSFER_BUFFER_SIZE;
 int got;
 
        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_PUT_ERROR,CMDLINE_CMD_PUT_ERROR_PARSING_TRANSFER_BUFFER_SIZE,
+                                       _("Error parsing transfer buffer size: %s"),CMD_LOCALE_FROM_UTF8_ALLOCA(string));
+                       return;
+                       }
+               }
+
        sourcefile=cmd_argv[0];
        if (cmd_argv[1])
                targetfile=cmdline_path_from_cwd(cmd_argv[1]);
@@ -75,7 +98,7 @@ gchar *sourcefile_basename;
                g_free(sourcefile_basename);
                }
 
-       if (-1==(fdsrc=open(sourcefile,O_RDONLY
+       if (-1==(fdsrc=open(CMD_FILENAME_FROM_UTF8_ALLOCA(sourcefile),O_RDONLY
 #ifdef O_BINARY
                        | O_BINARY
 #endif /* O_BINARY */
@@ -84,23 +107,27 @@ gchar *sourcefile_basename;
 #endif /* O_LARGEFILE */
                        ))) {
                g_set_error(errp,CMDLINE_CMD_PUT_ERROR,CMDLINE_CMD_PUT_ERROR_OPENING_SOURCE_FILE,
-                               _("Error opening source host-os file '%s': %s"),sourcefile,g_strerror(errno));
+                               _("Error opening source host-os file '%s': %s"),CMD_LOCALE_FROM_UTF8_ALLOCA(sourcefile),g_strerror(errno));
                return;
                }
 
        if (!errvfsresult_to_gerr(errp,captive_file_new_create(
                        &captive_file_object,   /* captive_file_object_return */
+                       cmdline_captive_vfs_object,     /* captive_vfs_object */
                        targetfile,     /* pathname */
                        GNOME_VFS_OPEN_WRITE,   /* mode */
                        FALSE,  /* exclusive */
                        perm))) {       /* perm */
                err_cleanup(errp);
                g_set_error(errp,CMDLINE_CMD_PUT_ERROR,CMDLINE_CMD_PUT_ERROR_CANNOT_CREATE_TARGET_GUESTOS_FILE,
-                               _("Cannot create target guest-os file: %s"),targetfile);
+                               _("Cannot create target guest-os file: %s"),CMD_LOCALE_FROM_UTF8_ALLOCA(targetfile));
                goto err_close_fdsrc;
                }
 
-       while (0<(got=read(fdsrc,transfer_buffer,sizeof(transfer_buffer)))) {
+       transfer_buffer=g_malloc(transfer_buffer_size);
+       g_assert(transfer_buffer!=NULL);        /* Should not happen. */
+
+       while (0<(got=read(fdsrc,transfer_buffer,transfer_buffer_size))) {
 GnomeVFSFileSize bytes_written;
 
                if (!errvfsresult_to_gerr(errp,captive_file_write(
@@ -110,29 +137,31 @@ GnomeVFSFileSize bytes_written;
                                &bytes_written))) {     /* bytes_written_return */
                        err_cleanup(errp);
                        g_set_error(errp,CMDLINE_CMD_PUT_ERROR,CMDLINE_CMD_PUT_ERROR_WRITING_TARGET_GUESTOS_FILE,
-                                       _("Error writing target guest-os file: %s"),targetfile);
-                       goto err_unref_captive_file_object;
+                                       _("Error writing target guest-os file: %s"),CMD_LOCALE_FROM_UTF8_ALLOCA(targetfile));
+                       goto err_free_transfer_buffer;
                        }
                if (bytes_written!=(GnomeVFSFileSize)got) {
                        g_set_error(errp,CMDLINE_CMD_PUT_ERROR,CMDLINE_CMD_PUT_ERROR_WRITING_TARGET_GUESTOS_FILE,
                                        _("Error writing target guest-os file '%s': requested %d, written %Lu"),
-                                       targetfile,got,(unsigned long long)bytes_written);
-                       goto err_unref_captive_file_object;
+                                       CMD_LOCALE_FROM_UTF8_ALLOCA(targetfile),got,(unsigned long long)bytes_written);
+                       goto err_free_transfer_buffer;
                        }
                }
        if (got==-1) {
                g_set_error(errp,CMDLINE_CMD_PUT_ERROR,CMDLINE_CMD_PUT_ERROR_READING_SOURCE_FILE,
-                               _("Error reading source host-os file '%s': %s"),sourcefile,g_strerror(errno));
-               goto err_unref_captive_file_object;
+                               _("Error reading source host-os file '%s': %s"),CMD_LOCALE_FROM_UTF8_ALLOCA(sourcefile),g_strerror(errno));
+               goto err_free_transfer_buffer;
                }
        g_assert(got==0);
 
-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_fdsrc:
        if (close(fdsrc)) {
                err_cleanup(errp);      /* may be clean */
                g_set_error(errp,CMDLINE_CMD_PUT_ERROR,CMDLINE_CMD_PUT_ERROR_CLOSING_SOURCE_FILE,
-                               _("Error closing source host-os file '%s': %s"),sourcefile,g_strerror(errno));
+                               _("Error closing source host-os file '%s': %s"),CMD_LOCALE_FROM_UTF8_ALLOCA(sourcefile),g_strerror(errno));
                }
 }