Initial original import from: fuse-2.4.2-2.fc4
[captive.git] / src / client / cmdline / cmd_get.c
index ea213d7..87daf72 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 <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,8 +50,12 @@ GQuark r=0;
 }
 
 
+static gchar *optarg_transfer_buffer;
+
 const struct poptOption cmd_get_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
                };
 
@@ -60,13 +66,29 @@ 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);
 
-       sourcefile=cmd_argv[0];
+       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(cmd_argv[1]);
+               targetfile=captive_strdup_alloca(cmdline_path_from_cwd(cmd_argv[1]));
        else {
 char *s;
 
@@ -75,8 +97,8 @@ char *s;
                        targetfile=s+1;
                }
 
-       if (!(fdtgt=open(targetfile,
-                       O_CREAT|O_WRONLY        /* flags */
+       if (-1==(fdtgt=open(CMD_FILENAME_FROM_UTF8_ALLOCA(targetfile),
+                       O_CREAT|O_EXCL|O_WRONLY /* flags */
 #ifdef O_BINARY
                                        | O_BINARY
 #endif /* O_BINARY */
@@ -86,20 +108,24 @@ 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;
                }
 
        if (!errvfsresult_to_gerr(errp,captive_file_new_open(
                        &captive_file_object,   /* captive_file_object_return */
+                       cmdline_captive_vfs_object,     /* captive_vfs_object */
                        sourcefile,     /* pathname */
                        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 host-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;
@@ -108,8 +134,9 @@ 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));
                if (errvfsresult==GNOME_VFS_ERROR_EOF)
                        break;
@@ -120,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));
                }
 }