added --progress option which shows the progress of transfers. This
authorAndrew Tridgell <tridge@samba.org>
Thu, 2 Jul 1998 00:47:13 +0000 (00:47 +0000)
committerAndrew Tridgell <tridge@samba.org>
Thu, 2 Jul 1998 00:47:13 +0000 (00:47 +0000)
gives bored users something to watch.

log.c
match.c
options.c
rsync.c
rsync.yo
util.c

diff --git a/log.c b/log.c
index 71eb234..2454088 100644 (file)
--- a/log.c
+++ b/log.c
@@ -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--;
 }
 
diff --git a/match.c b/match.c
index 272025a..f54c229 100644 (file)
--- a/match.c
+++ b/match.c
@@ -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);
        }
 
index 10c2773..0a0e680 100644 (file)
--- a/options.c
+++ b/options.c
@@ -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";
 
diff --git a/rsync.c b/rsync.c
index 48ed69f..5af7193 100644 (file)
--- a/rsync.c
+++ b/rsync.c
@@ -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) {
index b13a8b8..9847ac9 100644 (file)
--- a/rsync.yo
+++ b/rsync.yo
@@ -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)
diff --git a/util.c b/util.c
index 639a4a4..34c8f8b 100644 (file)
--- a/util.c
+++ b/util.c
@@ -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;
+               }
+       }
+}