#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)
}
+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
};
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]);
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 */
#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(
&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));
}
}