Commit eb86d661 authored by Andrew Tridgell's avatar Andrew Tridgell

added --progress option which shows the progress of transfers. This

gives bored users something to watch.
parent fe055c71
...@@ -102,6 +102,8 @@ void rprintf(int fd, const char *format, ...) ...@@ -102,6 +102,8 @@ void rprintf(int fd, const char *format, ...)
if (fwrite(buf, len, 1, f) != 1) exit_cleanup(1); if (fwrite(buf, len, 1, f) != 1) exit_cleanup(1);
if (buf[len-1] == '\r') fflush(f);
depth--; depth--;
} }
......
...@@ -118,6 +118,10 @@ static void matched(int f,struct sum_struct *s,struct map_struct *buf, ...@@ -118,6 +118,10 @@ static void matched(int f,struct sum_struct *s,struct map_struct *buf,
last_match = offset + s->sums[i].len; last_match = offset + s->sums[i].len;
else else
last_match = offset; last_match = offset;
show_progress(last_match, buf->size);
if (i == -1) end_progress();
} }
...@@ -252,6 +256,12 @@ void match_sums(int f,struct sum_struct *s,struct map_struct *buf,OFF_T len) ...@@ -252,6 +256,12 @@ void match_sums(int f,struct sum_struct *s,struct map_struct *buf,OFF_T len)
if (verbose > 2) if (verbose > 2)
rprintf(FINFO,"done hash search\n"); rprintf(FINFO,"done hash search\n");
} else { } else {
OFF_T j;
/* by doing this in pieces we avoid too many seeks */
for (j=0;j<(len-CHUNK_SIZE);j+=CHUNK_SIZE) {
int n1 = MIN(CHUNK_SIZE,(len-CHUNK_SIZE)-j);
matched(f,s,buf,j+n1,-2);
}
matched(f,s,buf,len,-1); matched(f,s,buf,len,-1);
} }
......
...@@ -56,6 +56,7 @@ int recurse = 0; ...@@ -56,6 +56,7 @@ int recurse = 0;
int am_daemon=0; int am_daemon=0;
int am_client=0; int am_client=0;
int do_stats=0; int do_stats=0;
int do_progress=0;
int keep_partial=0; int keep_partial=0;
int block_size=BLOCK_SIZE; int block_size=BLOCK_SIZE;
...@@ -126,6 +127,7 @@ void usage(int F) ...@@ -126,6 +127,7 @@ void usage(int F)
rprintf(F," --config=FILE specify alternate rsyncd.conf file\n"); rprintf(F," --config=FILE specify alternate rsyncd.conf file\n");
rprintf(F," --port=PORT specify alternate rsyncd port number\n"); rprintf(F," --port=PORT specify alternate rsyncd port number\n");
rprintf(F," --stats give some file transfer stats\n"); rprintf(F," --stats give some file transfer stats\n");
rprintf(F," --progress show progress during transfer\n");
rprintf(F," -h, --help show this help screen\n"); rprintf(F," -h, --help show this help screen\n");
rprintf(F,"\n"); rprintf(F,"\n");
...@@ -139,7 +141,7 @@ void usage(int F) ...@@ -139,7 +141,7 @@ void usage(int F)
enum {OPT_VERSION,OPT_SUFFIX,OPT_SENDER,OPT_SERVER,OPT_EXCLUDE, enum {OPT_VERSION,OPT_SUFFIX,OPT_SENDER,OPT_SERVER,OPT_EXCLUDE,
OPT_EXCLUDE_FROM,OPT_DELETE,OPT_NUMERIC_IDS,OPT_RSYNC_PATH, OPT_EXCLUDE_FROM,OPT_DELETE,OPT_NUMERIC_IDS,OPT_RSYNC_PATH,
OPT_FORCE,OPT_TIMEOUT,OPT_DAEMON,OPT_CONFIG,OPT_PORT, OPT_FORCE,OPT_TIMEOUT,OPT_DAEMON,OPT_CONFIG,OPT_PORT,
OPT_INCLUDE, OPT_INCLUDE_FROM, OPT_STATS, OPT_PARTIAL}; OPT_INCLUDE, OPT_INCLUDE_FROM, OPT_STATS, OPT_PARTIAL, OPT_PROGRESS};
static char *short_options = "oblLWHpguDCtcahvrRIxnSe:B:T:z"; static char *short_options = "oblLWHpguDCtcahvrRIxnSe:B:T:z";
...@@ -185,6 +187,7 @@ static struct option long_options[] = { ...@@ -185,6 +187,7 @@ static struct option long_options[] = {
{"compress", 0, 0, 'z'}, {"compress", 0, 0, 'z'},
{"daemon", 0, 0, OPT_DAEMON}, {"daemon", 0, 0, OPT_DAEMON},
{"stats", 0, 0, OPT_STATS}, {"stats", 0, 0, OPT_STATS},
{"progress", 0, 0, OPT_PROGRESS},
{"partial", 0, 0, OPT_PARTIAL}, {"partial", 0, 0, OPT_PARTIAL},
{"config", 1, 0, OPT_CONFIG}, {"config", 1, 0, OPT_CONFIG},
{"port", 1, 0, OPT_PORT}, {"port", 1, 0, OPT_PORT},
...@@ -385,6 +388,10 @@ void parse_arguments(int argc, char *argv[]) ...@@ -385,6 +388,10 @@ void parse_arguments(int argc, char *argv[])
do_stats = 1; do_stats = 1;
break; break;
case OPT_PROGRESS:
do_progress = 1;
break;
case OPT_PARTIAL: case OPT_PARTIAL:
keep_partial = 1; keep_partial = 1;
break; break;
...@@ -487,6 +494,9 @@ void server_options(char **args,int *argc) ...@@ -487,6 +494,9 @@ void server_options(char **args,int *argc)
if (keep_partial) if (keep_partial)
args[ac++] = "--partial"; args[ac++] = "--partial";
if (do_progress)
args[ac++] = "--progress";
if (force_delete) if (force_delete)
args[ac++] = "--force"; args[ac++] = "--force";
......
...@@ -577,78 +577,92 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out) ...@@ -577,78 +577,92 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
static int receive_data(int f_in,struct map_struct *buf,int fd,char *fname) static int receive_data(int f_in,struct map_struct *buf,int fd,char *fname,
OFF_T total_size)
{ {
int i,n,remainder,len,count; int i,n,remainder,len,count;
OFF_T offset = 0; OFF_T offset = 0;
OFF_T offset2; OFF_T offset2;
char *data; char *data;
static char file_sum1[MD4_SUM_LENGTH]; static char file_sum1[MD4_SUM_LENGTH];
static char file_sum2[MD4_SUM_LENGTH]; static char file_sum2[MD4_SUM_LENGTH];
char *map=NULL; char *map=NULL;
count = read_int(f_in); count = read_int(f_in);
n = read_int(f_in); n = read_int(f_in);
remainder = read_int(f_in); remainder = read_int(f_in);
sum_init();
for (i=recv_token(f_in,&data); i != 0; i=recv_token(f_in,&data)) {
sum_init(); show_progress(offset, total_size);
for (i=recv_token(f_in,&data); i != 0; i=recv_token(f_in,&data)) { if (i > 0) {
if (i > 0) { if (verbose > 3) {
if (verbose > 3) rprintf(FINFO,"data recv %d at %d\n",
rprintf(FINFO,"data recv %d at %d\n",i,(int)offset); i,(int)offset);
}
stats.literal_data += i; stats.literal_data += i;
cleanup_got_literal = 1; cleanup_got_literal = 1;
sum_update(data,i); sum_update(data,i);
if (fd != -1 && write_file(fd,data,i) != i) {
rprintf(FERROR,"write failed on %s : %s\n",fname,strerror(errno));
exit_cleanup(1);
}
offset += i;
} else {
i = -(i+1);
offset2 = i*n;
len = n;
if (i == count-1 && remainder != 0)
len = remainder;
stats.matched_data += len; if (fd != -1 && write_file(fd,data,i) != i) {
rprintf(FERROR,"write failed on %s : %s\n",fname,strerror(errno));
if (verbose > 3) exit_cleanup(1);
rprintf(FINFO,"chunk[%d] of size %d at %d offset=%d\n", }
i,len,(int)offset2,(int)offset); offset += i;
continue;
map = map_ptr(buf,offset2,len); }
see_token(map, len); i = -(i+1);
sum_update(map,len); offset2 = i*n;
len = n;
if (i == count-1 && remainder != 0)
len = remainder;
stats.matched_data += len;
if (verbose > 3)
rprintf(FINFO,"chunk[%d] of size %d at %d offset=%d\n",
i,len,(int)offset2,(int)offset);
map = map_ptr(buf,offset2,len);
see_token(map, len);
sum_update(map,len);
if (fd != -1 && write_file(fd,map,len) != len) {
rprintf(FERROR,"write failed on %s : %s\n",
fname,strerror(errno));
exit_cleanup(1);
}
offset += len;
}
if (fd != -1 && write_file(fd,map,len) != len) { end_progress();
rprintf(FERROR,"write failed on %s : %s\n",fname,strerror(errno));
exit_cleanup(1);
}
offset += len;
}
}
if (fd != -1 && offset > 0 && sparse_end(fd) != 0) { if (fd != -1 && offset > 0 && sparse_end(fd) != 0) {
rprintf(FERROR,"write failed on %s : %s\n",fname,strerror(errno)); rprintf(FERROR,"write failed on %s : %s\n",
exit_cleanup(1); fname,strerror(errno));
} exit_cleanup(1);
}
sum_end(file_sum1); sum_end(file_sum1);
if (remote_version >= 14) { if (remote_version >= 14) {
read_buf(f_in,file_sum2,MD4_SUM_LENGTH); read_buf(f_in,file_sum2,MD4_SUM_LENGTH);
if (verbose > 2) if (verbose > 2) {
rprintf(FINFO,"got file_sum\n"); rprintf(FINFO,"got file_sum\n");
if (fd != -1 && memcmp(file_sum1,file_sum2,MD4_SUM_LENGTH) != 0) }
return 0; if (fd != -1 &&
} memcmp(file_sum1,file_sum2,MD4_SUM_LENGTH) != 0) {
return 1; return 0;
}
}
return 1;
} }
...@@ -915,14 +929,14 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen) ...@@ -915,14 +929,14 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
if (fd1 != -1 && do_fstat(fd1,&st) != 0) { if (fd1 != -1 && do_fstat(fd1,&st) != 0) {
rprintf(FERROR,"fstat %s : %s\n",fname,strerror(errno)); rprintf(FERROR,"fstat %s : %s\n",fname,strerror(errno));
receive_data(f_in,NULL,-1,NULL); receive_data(f_in,NULL,-1,NULL,file->length);
close(fd1); close(fd1);
continue; continue;
} }
if (fd1 != -1 && !S_ISREG(st.st_mode)) { if (fd1 != -1 && !S_ISREG(st.st_mode)) {
rprintf(FERROR,"%s : not a regular file (recv_files)\n",fname); rprintf(FERROR,"%s : not a regular file (recv_files)\n",fname);
receive_data(f_in,NULL,-1,NULL); receive_data(f_in,NULL,-1,NULL,file->length);
close(fd1); close(fd1);
continue; continue;
} }
...@@ -943,7 +957,7 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen) ...@@ -943,7 +957,7 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
if (NULL == do_mktemp(fnametmp)) { if (NULL == do_mktemp(fnametmp)) {
rprintf(FERROR,"mktemp %s failed\n",fnametmp); rprintf(FERROR,"mktemp %s failed\n",fnametmp);
receive_data(f_in,buf,-1,NULL); receive_data(f_in,buf,-1,NULL,file->length);
if (buf) unmap_file(buf); if (buf) unmap_file(buf);
close(fd1); close(fd1);
continue; continue;
...@@ -964,7 +978,7 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen) ...@@ -964,7 +978,7 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
} }
if (fd2 == -1) { if (fd2 == -1) {
rprintf(FERROR,"open %s : %s\n",fnametmp,strerror(errno)); rprintf(FERROR,"open %s : %s\n",fnametmp,strerror(errno));
receive_data(f_in,buf,-1,NULL); receive_data(f_in,buf,-1,NULL,file->length);
if (buf) unmap_file(buf); if (buf) unmap_file(buf);
close(fd1); close(fd1);
continue; continue;
...@@ -978,7 +992,7 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen) ...@@ -978,7 +992,7 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
printf("%s\n",fname); printf("%s\n",fname);
/* recv file data */ /* recv file data */
recv_ok = receive_data(f_in,buf,fd2,fname); recv_ok = receive_data(f_in,buf,fd2,fname,file->length);
if (buf) unmap_file(buf); if (buf) unmap_file(buf);
if (fd1 != -1) { if (fd1 != -1) {
......
...@@ -234,6 +234,7 @@ verb( ...@@ -234,6 +234,7 @@ verb(
--config=FILE specify alternate rsyncd.conf file --config=FILE specify alternate rsyncd.conf file
--port=PORT specify alternate rsyncd port number --port=PORT specify alternate rsyncd port number
--stats give some file transfer stats --stats give some file transfer stats
--progress show progress during transfer
-h, --help show this help screen -h, --help show this help screen
) )
...@@ -510,6 +511,10 @@ on the file transfer, allowing you to tell how effective the rsync ...@@ -510,6 +511,10 @@ on the file transfer, allowing you to tell how effective the rsync
algorithm is for your data. This option only works in conjunction with algorithm is for your data. This option only works in conjunction with
the -v (verbose) option. the -v (verbose) option.
dit(bf(--progress)) This option tells rsync to print information
showing the progress of the transfer. This gives a bored user
something to watch.
enddit() enddit()
manpagesection(EXCLUDE PATTERNS) manpagesection(EXCLUDE PATTERNS)
......
...@@ -685,3 +685,28 @@ int u_strcmp(const char *cs1, const char *cs2) ...@@ -685,3 +685,28 @@ int u_strcmp(const char *cs1, const char *cs2)
return (int)*s1 - (int)*s2; return (int)*s1 - (int)*s2;
} }
static int last_pct = -1;
void end_progress(void)
{
extern int do_progress, am_server;
if (do_progress && !am_server) {
rprintf(FINFO,"\n");
}
last_pct = -1;
}
void show_progress(OFF_T ofs, OFF_T size)
{
extern int do_progress, am_server;
if (do_progress && !am_server) {
int pct = (int)((100.0*ofs)/size + 0.5);
if (pct != last_pct) {
rprintf(FINFO,"%.0f (%d%%)\r", (double)ofs, pct);
last_pct = pct;
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment