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, ...)
if (fwrite(buf, len, 1, f) != 1) exit_cleanup(1);
if (buf[len-1] == '\r') fflush(f);
depth--;
}
......
......@@ -118,6 +118,10 @@ static void matched(int f,struct sum_struct *s,struct map_struct *buf,
last_match = offset + s->sums[i].len;
else
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)
if (verbose > 2)
rprintf(FINFO,"done hash search\n");
} 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);
}
......
......@@ -56,6 +56,7 @@ int recurse = 0;
int am_daemon=0;
int am_client=0;
int do_stats=0;
int do_progress=0;
int keep_partial=0;
int block_size=BLOCK_SIZE;
......@@ -126,6 +127,7 @@ void usage(int F)
rprintf(F," --config=FILE specify alternate rsyncd.conf file\n");
rprintf(F," --port=PORT specify alternate rsyncd port number\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,"\n");
......@@ -139,7 +141,7 @@ void usage(int F)
enum {OPT_VERSION,OPT_SUFFIX,OPT_SENDER,OPT_SERVER,OPT_EXCLUDE,
OPT_EXCLUDE_FROM,OPT_DELETE,OPT_NUMERIC_IDS,OPT_RSYNC_PATH,
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";
......@@ -185,6 +187,7 @@ static struct option long_options[] = {
{"compress", 0, 0, 'z'},
{"daemon", 0, 0, OPT_DAEMON},
{"stats", 0, 0, OPT_STATS},
{"progress", 0, 0, OPT_PROGRESS},
{"partial", 0, 0, OPT_PARTIAL},
{"config", 1, 0, OPT_CONFIG},
{"port", 1, 0, OPT_PORT},
......@@ -385,6 +388,10 @@ void parse_arguments(int argc, char *argv[])
do_stats = 1;
break;
case OPT_PROGRESS:
do_progress = 1;
break;
case OPT_PARTIAL:
keep_partial = 1;
break;
......@@ -487,6 +494,9 @@ void server_options(char **args,int *argc)
if (keep_partial)
args[ac++] = "--partial";
if (do_progress)
args[ac++] = "--progress";
if (force_delete)
args[ac++] = "--force";
......
......@@ -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;
OFF_T offset = 0;
OFF_T offset2;
char *data;
static char file_sum1[MD4_SUM_LENGTH];
static char file_sum2[MD4_SUM_LENGTH];
char *map=NULL;
count = read_int(f_in);
n = read_int(f_in);
remainder = read_int(f_in);
int i,n,remainder,len,count;
OFF_T offset = 0;
OFF_T offset2;
char *data;
static char file_sum1[MD4_SUM_LENGTH];
static char file_sum2[MD4_SUM_LENGTH];
char *map=NULL;
count = read_int(f_in);
n = 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 (verbose > 3)
rprintf(FINFO,"data recv %d at %d\n",i,(int)offset);
if (i > 0) {
if (verbose > 3) {
rprintf(FINFO,"data recv %d at %d\n",
i,(int)offset);
}
stats.literal_data += i;
cleanup_got_literal = 1;
stats.literal_data += i;
cleanup_got_literal = 1;
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;
sum_update(data,i);
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);
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;
continue;
}
see_token(map, len);
sum_update(map,len);
i = -(i+1);
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) {
rprintf(FERROR,"write failed on %s : %s\n",fname,strerror(errno));
exit_cleanup(1);
}
offset += len;
}
}
end_progress();
if (fd != -1 && offset > 0 && sparse_end(fd) != 0) {
rprintf(FERROR,"write failed on %s : %s\n",fname,strerror(errno));
exit_cleanup(1);
}
if (fd != -1 && offset > 0 && sparse_end(fd) != 0) {
rprintf(FERROR,"write failed on %s : %s\n",
fname,strerror(errno));
exit_cleanup(1);
}
sum_end(file_sum1);
sum_end(file_sum1);
if (remote_version >= 14) {
read_buf(f_in,file_sum2,MD4_SUM_LENGTH);
if (verbose > 2)
rprintf(FINFO,"got file_sum\n");
if (fd != -1 && memcmp(file_sum1,file_sum2,MD4_SUM_LENGTH) != 0)
return 0;
}
return 1;
if (remote_version >= 14) {
read_buf(f_in,file_sum2,MD4_SUM_LENGTH);
if (verbose > 2) {
rprintf(FINFO,"got file_sum\n");
}
if (fd != -1 &&
memcmp(file_sum1,file_sum2,MD4_SUM_LENGTH) != 0) {
return 0;
}
}
return 1;
}
......@@ -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) {
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);
continue;
}
if (fd1 != -1 && !S_ISREG(st.st_mode)) {
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);
continue;
}
......@@ -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)) {
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);
close(fd1);
continue;
......@@ -964,7 +978,7 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
}
if (fd2 == -1) {
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);
close(fd1);
continue;
......@@ -978,7 +992,7 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
printf("%s\n",fname);
/* 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 (fd1 != -1) {
......
......@@ -234,6 +234,7 @@ verb(
--config=FILE specify alternate rsyncd.conf file
--port=PORT specify alternate rsyncd port number
--stats give some file transfer stats
--progress show progress during transfer
-h, --help show this help screen
)
......@@ -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
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()
manpagesection(EXCLUDE PATTERNS)
......
......@@ -685,3 +685,28 @@ int u_strcmp(const char *cs1, const char *cs2)
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