struct push_state {
XFILE *f;
off_t nread;
+ off_t total_size;
+ bool progress;
+ struct timeval start;
+ struct timeval last;
};
static size_t push_source(uint8_t *buf, size_t n, void *priv)
result = readfile(buf, n, state->f);
state->nread += result;
+
+ if (state->progress) {
+ struct timeval now = timeval_current();
+ double elapsed_start = timeval_elapsed2(&state->start, &now);
+ double elapsed_last = timeval_elapsed2(&state->last, &now);
+ const char *ps_unit = "";
+ double r = state->nread;
+ const char *r_unit = "";
+ double t = state->total_size;
+ const char *t_unit = "";
+ double pc = MIN((r / t) * 100, 99.9);
+ double ps = r / elapsed_start;
+
+ if (elapsed_last >= 0 && elapsed_last < 0.1) {
+ return result;
+ }
+
+#define per_unit(_val, _unit) { \
+ if (_val > (1024 * 1024 * 1024)) { \
+ _val /= (1024 * 1024 * 1024); \
+ _unit = "G"; \
+ } else if (_val > (1024 * 1024)) { \
+ _val /= (1024 * 1024); \
+ _unit = "M"; \
+ } else if (_val > (1024)) { \
+ _val /= (1024); \
+ _unit = "K"; \
+ } else { \
+ _unit = ""; \
+ } \
+} while (0)
+ per_unit(ps, ps_unit);
+ per_unit(r, r_unit);
+ per_unit(t, t_unit);
+#undef per_unit
+
+ if (t > 0) {
+ d_printf("(%-2.1f %%) (%0.3f %sBytes / %0.3f %sBytes) %0.3f %sBytes/s%-25s\r",
+ pc, r, r_unit, t, t_unit, ps, ps_unit, "");
+ } else {
+ d_printf("(%0.3f %sBytes) %0.3f %sBytes/s%-25s\r",
+ r, r_unit, ps, ps_unit, "");
+ }
+ fflush(stdout);
+ fflush(stderr);
+ state->last = now;
+ }
+
return result;
}
Get a file from rname to lname
****************************************************************************/
+struct writefile_sink_state {
+ int fd;
+ off_t written;
+ off_t total_size;
+ bool progress;
+ struct timeval start;
+ struct timeval last;
+};
+
static NTSTATUS writefile_sink(char *buf, size_t n, void *priv)
{
- int *pfd = (int *)priv;
- if (writefile(*pfd, buf, n) == -1) {
+ struct writefile_sink_state *state =
+ (struct writefile_sink_state *)priv;
+
+ if (writefile(state->fd, buf, n) == -1) {
return map_nt_error_from_unix(errno);
}
+
+ state->written += n;
+ if (state->progress) {
+ struct timeval now = timeval_current();
+ double elapsed_start = timeval_elapsed2(&state->start, &now);
+ double elapsed_last = timeval_elapsed2(&state->last, &now);
+ const char *ps_unit = "";
+ double w = state->written;
+ const char *w_unit = "";
+ double t = state->total_size;
+ const char *t_unit = "";
+ double pc = MIN((w / t) * 100, 99.9);
+ double ps = w / elapsed_start;
+
+ if (elapsed_last >= 0 && elapsed_last < 0.1) {
+ return NT_STATUS_OK;
+ }
+
+#define per_unit(_val, _unit) { \
+ if (_val > (1024 * 1024 * 1024)) { \
+ _val /= (1024 * 1024 * 1024); \
+ _unit = "G"; \
+ } else if (_val > (1024 * 1024)) { \
+ _val /= (1024 * 1024); \
+ _unit = "M"; \
+ } else if (_val > (1024)) { \
+ _val /= (1024); \
+ _unit = "K"; \
+ } else { \
+ _unit = ""; \
+ } \
+} while (0)
+ per_unit(ps, ps_unit);
+ per_unit(w, w_unit);
+ per_unit(t, t_unit);
+#undef per_unit
+
+ d_printf("(%-2.1f %%) (%0.3f %sBytes / %0.3f %sBytes) %0.3f %sBytes/s%-25s\r",
+ pc, w, w_unit, t, t_unit, ps, ps_unit, "");
+ fflush(stdout);
+ fflush(stderr);
+ state->last = now;
+ }
+
return NT_STATUS_OK;
}
char *targetname = NULL;
char *lname = NULL;
NTSTATUS status;
+ struct writefile_sink_state sink_state = { .fd = -1, };
lname = talloc_strdup(ctx, lname_in);
if (!lname) {
DEBUG(1,("getting file %s of size %.0f as %s ",
rname, (double)size, lname));
+ sink_state.fd = handle;
+ sink_state.total_size = size;
+ sink_state.progress = true;
+ sink_state.start = timeval_current();
+
status = cli_pull(targetcli, fnum, start, size, io_bufsize,
- writefile_sink, (void *)&handle, &nread);
+ writefile_sink, (void *)&sink_state, &nread);
if (!NT_STATUS_IS_OK(status)) {
d_fprintf(stderr, "parallel_read returned %s\n",
nt_errstr(status));
uint16_t fnum;
XFILE *f;
off_t start = 0;
+ off_t size = 0;
int rc = 0;
struct timespec tp_start;
struct cli_state *targetcli;
char *targetname = NULL;
- struct push_state state;
+ struct push_state state = { .f = NULL, };
NTSTATUS status;
status = cli_resolve_path(ctx, "", auth_info, cli, rname,
return 1;
}
}
+ if (f != NULL) {
+ struct stat st;
+ int fd;
+ int ret;
+
+ fd = x_fileno(f);
+ ret = fstat(fd, &st);
+ if (ret == 0) {
+ size = st.st_size;
+ }
+ }
}
if (!f) {
state.f = f;
state.nread = 0;
+ state.total_size = size;
+ state.progress = true;
+ state.start = timeval_current();
status = cli_push(targetcli, fnum, 0, 0, io_bufsize, push_source,
&state);