#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)
}
+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
};
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;
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 */
,
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;
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;
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));
}
}