home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 35 Internet / 35-Internet.zip / rsync221.zip / sender.c < prev    next >
C/C++ Source or Header  |  1999-03-04  |  5KB  |  231 lines

  1. /* 
  2.    Copyright (C) Andrew Tridgell 1996
  3.    Copyright (C) Paul Mackerras 1996
  4.    
  5.    This program is free software; you can redistribute it and/or modify
  6.    it under the terms of the GNU General Public License as published by
  7.    the Free Software Foundation; either version 2 of the License, or
  8.    (at your option) any later version.
  9.    
  10.    This program is distributed in the hope that it will be useful,
  11.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.    GNU General Public License for more details.
  14.    
  15.    You should have received a copy of the GNU General Public License
  16.    along with this program; if not, write to the Free Software
  17.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18. */
  19.  
  20. #include "rsync.h"
  21.  
  22. extern int verbose;
  23. extern int remote_version;
  24. extern int csum_length;
  25. extern struct stats stats;
  26. extern int io_error;
  27. extern int dry_run;
  28. extern int am_server;
  29.  
  30.  
  31. /*
  32.   receive the checksums for a buffer
  33.   */
  34. static struct sum_struct *receive_sums(int f)
  35. {
  36.     struct sum_struct *s;
  37.     int i;
  38.     OFF_T offset = 0;
  39.  
  40.     s = (struct sum_struct *)malloc(sizeof(*s));
  41.     if (!s) out_of_memory("receive_sums");
  42.  
  43.     s->count = read_int(f);
  44.     s->n = read_int(f);
  45.     s->remainder = read_int(f);  
  46.     s->sums = NULL;
  47.  
  48.     if (verbose > 3)
  49.         rprintf(FINFO,"count=%d n=%d rem=%d\n",
  50.             s->count,s->n,s->remainder);
  51.  
  52.     if (s->count == 0) 
  53.         return(s);
  54.  
  55.     s->sums = (struct sum_buf *)malloc(sizeof(s->sums[0])*s->count);
  56.     if (!s->sums) out_of_memory("receive_sums");
  57.  
  58.     for (i=0;i<s->count;i++) {
  59.         s->sums[i].sum1 = read_int(f);
  60.         read_buf(f,s->sums[i].sum2,csum_length);
  61.  
  62.         s->sums[i].offset = offset;
  63.         s->sums[i].i = i;
  64.  
  65.         if (i == s->count-1 && s->remainder != 0) {
  66.             s->sums[i].len = s->remainder;
  67.         } else {
  68.             s->sums[i].len = s->n;
  69.         }
  70.         offset += s->sums[i].len;
  71.  
  72.         if (verbose > 3)
  73.             rprintf(FINFO,"chunk[%d] len=%d offset=%d sum1=%08x\n",
  74.                 i,s->sums[i].len,(int)s->sums[i].offset,s->sums[i].sum1);
  75.     }
  76.  
  77.     s->flength = offset;
  78.  
  79.     return s;
  80. }
  81.  
  82.  
  83.  
  84. void send_files(struct file_list *flist,int f_out,int f_in)
  85.     int fd;
  86.     struct sum_struct *s;
  87.     struct map_struct *buf;
  88.     STRUCT_STAT st;
  89.     char fname[MAXPATHLEN];  
  90.     int i;
  91.     struct file_struct *file;
  92.     int phase = 0;
  93.     extern struct stats stats;        
  94.     struct stats initial_stats;
  95.  
  96.     if (verbose > 2)
  97.         rprintf(FINFO,"send_files starting\n");
  98.  
  99.     setup_readbuffer(f_in);
  100.  
  101.     while (1) {
  102.         int offset=0;
  103.  
  104.         i = read_int(f_in);
  105.         if (i == -1) {
  106.             if (phase==0 && remote_version >= 13) {
  107.                 phase++;
  108.                 csum_length = SUM_LENGTH;
  109.                 write_int(f_out,-1);
  110.                 if (verbose > 2)
  111.                     rprintf(FINFO,"send_files phase=%d\n",phase);
  112.                 continue;
  113.             }
  114.             break;
  115.         }
  116.  
  117.         if (i < 0 || i >= flist->count) {
  118.             rprintf(FERROR,"Invalid file index %d (count=%d)\n", 
  119.                 i, flist->count);
  120.             exit_cleanup(RERR_PROTOCOL);
  121.         }
  122.  
  123.         file = flist->files[i];
  124.  
  125.         stats.num_transferred_files++;
  126.         stats.total_transferred_size += file->length;
  127.  
  128.         fname[0] = 0;
  129.         if (file->basedir) {
  130.             strlcpy(fname,file->basedir,MAXPATHLEN);
  131.             if (strlen(fname) == MAXPATHLEN-1) {
  132.                 io_error = 1;
  133.                 rprintf(FERROR, "send_files failed on long-named directory %s\n",
  134.                     fname);
  135.                 return;
  136.             }
  137.             strlcat(fname,"/",MAXPATHLEN);
  138.             offset = strlen(file->basedir)+1;
  139.         }
  140.         strlcat(fname,f_name(file),MAXPATHLEN);
  141.       
  142.         if (verbose > 2) 
  143.             rprintf(FINFO,"send_files(%d,%s)\n",i,fname);
  144.       
  145.         if (dry_run) {    
  146.             if (!am_server) {
  147.                 log_transfer(file, fname+offset);
  148.             }
  149.             write_int(f_out,i);
  150.             continue;
  151.         }
  152.  
  153.         initial_stats = stats;
  154.  
  155.         s = receive_sums(f_in);
  156.         if (!s) {
  157.             io_error = 1;
  158.             rprintf(FERROR,"receive_sums failed\n");
  159.             return;
  160.         }
  161.       
  162.         fd = open(fname,O_RDONLY);
  163.         if (fd == -1) {
  164.             io_error = 1;
  165.             rprintf(FERROR,"send_files failed to open %s: %s\n",
  166.                 fname,strerror(errno));
  167.             free_sums(s);
  168.             continue;
  169.         }
  170.       
  171.         /* map the local file */
  172.         if (do_fstat(fd,&st) != 0) {
  173.             io_error = 1;
  174.             rprintf(FERROR,"fstat failed : %s\n",strerror(errno));
  175.             free_sums(s);
  176.             close(fd);
  177.             return;
  178.         }
  179.       
  180.         if (st.st_size > 0) {
  181.             buf = map_file(fd,st.st_size);
  182.         } else {
  183.             buf = NULL;
  184.         }
  185.       
  186.         if (verbose > 2)
  187.             rprintf(FINFO,"send_files mapped %s of size %d\n",
  188.                 fname,(int)st.st_size);
  189.  
  190.         write_int(f_out,i);
  191.       
  192.         write_int(f_out,s->count);
  193.         write_int(f_out,s->n);
  194.         write_int(f_out,s->remainder);
  195.       
  196.         if (verbose > 2)
  197.             rprintf(FINFO,"calling match_sums %s\n",fname);
  198.       
  199.         if (!am_server) {
  200.             log_transfer(file, fname+offset);
  201.         }
  202.  
  203.         set_compression(fname);
  204.       
  205.         match_sums(f_out,s,buf,st.st_size);
  206.  
  207.         log_send(file, &initial_stats);
  208.             
  209.         if (buf) unmap_file(buf);
  210.         close(fd);
  211.       
  212.         free_sums(s);
  213.       
  214.         if (verbose > 2)
  215.             rprintf(FINFO,"sender finished %s\n",fname);
  216.     }
  217.  
  218.     if (verbose > 2)
  219.         rprintf(FINFO,"send files finished\n");
  220.  
  221.     match_report();
  222.  
  223.     write_int(f_out,-1);
  224. }
  225.  
  226.  
  227.  
  228.  
  229.  
  230.