Beispiel #1
0
static struct dd_iohandle * open_file(struct resolve_context *resolve_ctx, 
				      struct tevent_context *ev,
				      const char * which, const char **ports,
				      struct smbcli_options *smb_options,
				      const char *socket_options,
				      struct smbcli_session_options *smb_session_options,
				      struct smb_iconv_convenience *iconv_convenience,
				      struct gensec_settings *gensec_settings)
{
	int			options = 0;
	const char *		path = NULL;
	struct dd_iohandle *	handle = NULL;

	if (check_arg_bool("direct")) {
		options |= DD_DIRECT_IO;
	}

	if (check_arg_bool("sync")) {
		options |= DD_SYNC_IO;
	}

	if (check_arg_bool("oplock")) {
		options |= DD_OPLOCK;
	}

	if (strcmp(which, "if") == 0) {
		path = check_arg_pathname("if");
		handle = dd_open_path(resolve_ctx, ev, path, ports,
				      check_arg_numeric("ibs"), options,
				      socket_options,
				      smb_options, smb_session_options,
				      iconv_convenience,
				      gensec_settings);
	} else if (strcmp(which, "of") == 0) {
		options |= DD_WRITE;
		path = check_arg_pathname("of");
		handle = dd_open_path(resolve_ctx, ev, path, ports,
				      check_arg_numeric("obs"), options,
				      socket_options,
				      smb_options, smb_session_options,
				      iconv_convenience,
				      gensec_settings);
	} else {
		SMB_ASSERT(0);
		return(NULL);
	}

	if (!handle) {
		fprintf(stderr, "%s: failed to open %s\n", PROGNAME, path);
	}

	return(handle);
}
Beispiel #2
0
static struct dd_iohandle * open_file(const char * which)
{
	int			options = 0;
	const char *		path = NULL;
	struct dd_iohandle *	handle = NULL;

	if (check_arg_bool("direct")) {
		options |= DD_DIRECT_IO;
	}

	if (check_arg_bool("sync")) {
		options |= DD_SYNC_IO;
	}

	if (check_arg_bool("oplock")) {
		options |= DD_OPLOCK;
	}

	if (strcmp(which, "if") == 0) {
		path = check_arg_pathname("if");
		handle = dd_open_path(path, check_arg_numeric("ibs"),
					options);
	} else if (strcmp(which, "of") == 0) {
		options |= DD_WRITE;
		path = check_arg_pathname("of");
		handle = dd_open_path(path, check_arg_numeric("obs"),
					options);
	} else {
		SMB_ASSERT(0);
		return(NULL);
	}

	if (!handle) {
		fprintf(stderr, "%s: failed to open %s\n", PROGNAME, path);
	}

	return(handle);
}
Beispiel #3
0
int main(int argc, const char ** argv)
{
	int i;
	const char ** dd_args;
	struct tevent_context *ev;

	poptContext pctx;
	struct poptOption poptions[] = {
		/* POPT_AUTOHELP */
		{ NULL, '\0', POPT_ARG_INCLUDE_TABLE, cifsddHelpOptions,
			0, "Help options:", NULL },
		POPT_COMMON_SAMBA
		POPT_COMMON_CONNECTION
		POPT_COMMON_CREDENTIALS
		POPT_COMMON_VERSION
		{ NULL }
	};

	/* Block sizes. */
	set_arg_val("bs", (uint64_t)4096);
	set_arg_val("ibs", (uint64_t)4096);
	set_arg_val("obs", (uint64_t)4096);
	/* Block counts. */
	set_arg_val("count", (uint64_t)-1);
	set_arg_val("seek", (uint64_t)0);
	set_arg_val("seek", (uint64_t)0);
	/* Files. */
	set_arg_val("if", NULL);
	set_arg_val("of", NULL);
	/* Options. */
	set_arg_val("direct", false);
	set_arg_val("sync", false);
	set_arg_val("oplock", false);

	pctx = poptGetContext(PROGNAME, argc, argv, poptions, 0);
	while ((i = poptGetNextOpt(pctx)) != -1) {
		;
	}

	for (dd_args = poptGetArgs(pctx); dd_args && *dd_args; ++dd_args) {

		if (!set_arg_argv(*dd_args)) {
			fprintf(stderr, "%s: invalid option: %s\n",
					PROGNAME, *dd_args);
			exit(SYNTAX_EXIT_CODE);
		}

		/* "bs" has the side-effect of setting "ibs" and "obs". */
		if (strncmp(*dd_args, "bs=", 3) == 0) {
			uint64_t bs = check_arg_numeric("bs");
			set_arg_val("ibs", bs);
			set_arg_val("obs", bs);
		}
	}

	ev = s4_event_context_init(talloc_autofree_context());

	gensec_init(cmdline_lp_ctx);
	dump_args();

	if (check_arg_numeric("ibs") == 0 || check_arg_numeric("ibs") == 0) {
		fprintf(stderr, "%s: block sizes must be greater that zero\n",
				PROGNAME);
		exit(SYNTAX_EXIT_CODE);
	}

	if (check_arg_pathname("if") == NULL) {
		fprintf(stderr, "%s: missing input filename\n", PROGNAME);
		exit(SYNTAX_EXIT_CODE);
	}

	if (check_arg_pathname("of") == NULL) {
		fprintf(stderr, "%s: missing output filename\n", PROGNAME);
		exit(SYNTAX_EXIT_CODE);
	}

	CatchSignal(SIGINT, dd_handle_signal);
	CatchSignal(SIGUSR1, dd_handle_signal);
	return(copy_files(ev, cmdline_lp_ctx));
}
Beispiel #4
0
static int copy_files(struct tevent_context *ev, struct loadparm_context *lp_ctx)
{
	uint8_t *	iobuf;	/* IO buffer. */
	uint64_t	iomax;	/* Size of the IO buffer. */
	uint64_t	data_size; /* Amount of data in the IO buffer. */

	uint64_t	ibs;
	uint64_t	obs;
	uint64_t	count;

	struct dd_iohandle *	ifile;
	struct dd_iohandle *	ofile;

	struct smbcli_options options;
	struct smbcli_session_options session_options;

	ibs = check_arg_numeric("ibs");
	obs = check_arg_numeric("obs");
	count = check_arg_numeric("count");

	lpcfg_smbcli_options(lp_ctx, &options);
	lpcfg_smbcli_session_options(lp_ctx, &session_options);

	/* Allocate IO buffer. We need more than the max IO size because we
	 * could accumulate a remainder if ibs and obs don't match.
	 */
	iomax = 2 * MAX(ibs, obs);
	if ((iobuf = malloc_array_p(uint8_t, iomax)) == NULL) {
		fprintf(stderr,
			"%s: failed to allocate IO buffer of %llu bytes\n",
			PROGNAME, (unsigned long long)iomax);
		return(EOM_EXIT_CODE);
	}

	options.max_xmit = MAX(ibs, obs);

	DEBUG(4, ("IO buffer size is %llu, max xmit is %d\n",
			(unsigned long long)iomax, options.max_xmit));

	if (!(ifile = open_file(lpcfg_resolve_context(lp_ctx), ev, "if",
				lpcfg_smb_ports(lp_ctx), &options,
				lpcfg_socket_options(lp_ctx),
				&session_options, 
				lpcfg_gensec_settings(lp_ctx, lp_ctx)))) {
		return(FILESYS_EXIT_CODE);
	}

	if (!(ofile = open_file(lpcfg_resolve_context(lp_ctx), ev, "of",
				lpcfg_smb_ports(lp_ctx), &options,
				lpcfg_socket_options(lp_ctx),
				&session_options,
				lpcfg_gensec_settings(lp_ctx, lp_ctx)))) {
		return(FILESYS_EXIT_CODE);
	}

	/* Seek the files to their respective starting points. */
	ifile->io_seek(ifile, check_arg_numeric("skip") * ibs);
	ofile->io_seek(ofile, check_arg_numeric("seek") * obs);

	DEBUG(4, ("max xmit was negotiated to be %d\n", options.max_xmit));

	for (data_size = 0;;) {

		/* Handle signals. We are somewhat compatible with GNU dd.
		 * SIGINT makes us stop, but still print transfer statistics.
		 * SIGUSR1 makes us print transfer statistics but we continue
		 * copying.
		 */
		if (dd_sigint) {
			break;
		}

		if (dd_sigusr1) {
			print_transfer_stats();
			dd_sigusr1 = 0;
		}

		if (ifile->io_flags & DD_END_OF_FILE) {
			DEBUG(4, ("flushing %llu bytes at EOF\n",
					(unsigned long long)data_size));
			while (data_size > 0) {
				if (!dd_flush_block(ofile, iobuf,
							&data_size, obs)) {
					return(IOERROR_EXIT_CODE);
				}
			}
			goto done;
		}

		/* Try and read enough blocks of ibs bytes to be able write
		 * out one of obs bytes.
		 */
		if (!dd_fill_block(ifile, iobuf, &data_size, obs, ibs)) {
			return(IOERROR_EXIT_CODE);
		}

		if (data_size == 0) {
			/* Done. */
			SMB_ASSERT(ifile->io_flags & DD_END_OF_FILE);
		}

		/* Stop reading when we hit the block count. */
		if (dd_stats.in.bytes >= (ibs * count)) {
			ifile->io_flags |= DD_END_OF_FILE;
		}

		/* If we wanted to be a legitimate dd, we would do character
		 * conversions and other shenanigans here.
		 */

		/* Flush what we read in units of obs bytes. We want to have
		 * at least obs bytes in the IO buffer but might not if the
		 * file is too small.
		 */
		if (data_size && 
		    !dd_flush_block(ofile, iobuf, &data_size, obs)) {
			return(IOERROR_EXIT_CODE);
		}
	}

done:
	print_transfer_stats();
	return(0);
}