home *** CD-ROM | disk | FTP | other *** search
/ Big Green CD 8 / BGCD_8_Dev.iso / OPENSTEP / UNIX / Utilities / rsync-1.6.3-MIH / src / rsync.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-04-11  |  19.8 KB  |  900 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 csum_length;
  23.  
  24. extern int verbose;
  25. extern int am_server;
  26. extern int always_checksum;
  27. extern time_t starttime;
  28.  
  29. extern int remote_version;
  30.  
  31. extern char *backup_suffix;
  32.  
  33. extern int block_size;
  34. extern int update_only;
  35. extern int make_backups;
  36. extern int preserve_links;
  37. extern int preserve_hard_links;
  38. extern int preserve_perms;
  39. extern int preserve_devices;
  40. extern int preserve_uid;
  41. extern int preserve_gid;
  42. extern int preserve_times;
  43. extern int dry_run;
  44. extern int ignore_times;
  45. extern int recurse;
  46. extern int delete_mode;
  47. extern int cvs_exclude;
  48. extern int am_root;
  49.  
  50. /*
  51.   free a sums struct
  52.   */
  53. static void free_sums(struct sum_struct *s)
  54. {
  55.   if (s->sums) free(s->sums);
  56.   free(s);
  57. }
  58.  
  59.  
  60.  
  61. /*
  62.   send a sums struct down a fd
  63.   */
  64. static void send_sums(struct sum_struct *s,int f_out)
  65. {
  66.   int i;
  67.  
  68.   /* tell the other guy how many we are going to be doing and how many
  69.      bytes there are in the last chunk */
  70.   write_int(f_out,s?s->count:0);
  71.   write_int(f_out,s?s->n:block_size);
  72.   write_int(f_out,s?s->remainder:0);
  73.   if (s)
  74.     for (i=0;i<s->count;i++) {
  75.       write_int(f_out,s->sums[i].sum1);
  76.       write_buf(f_out,s->sums[i].sum2,csum_length);
  77.     }
  78.   write_flush(f_out);
  79. }
  80.  
  81.  
  82. /*
  83.   generate a stream of signatures/checksums that describe a buffer
  84.  
  85.   generate approximately one checksum every n bytes
  86.   */
  87. static struct sum_struct *generate_sums(struct map_struct *buf,off_t len,int n)
  88. {
  89.   int i;
  90.   struct sum_struct *s;
  91.   int count;
  92.   int block_len = n;
  93.   int remainder = (len%block_len);
  94.   off_t offset = 0;
  95.  
  96.   count = (len+(block_len-1))/block_len;
  97.  
  98.   s = (struct sum_struct *)malloc(sizeof(*s));
  99.   if (!s) out_of_memory("generate_sums");
  100.  
  101.   s->count = count;
  102.   s->remainder = remainder;
  103.   s->n = n;
  104.   s->flength = len;
  105.  
  106.   if (count==0) {
  107.     s->sums = NULL;
  108.     return s;
  109.   }
  110.  
  111.   if (verbose > 3)
  112.     fprintf(FERROR,"count=%d rem=%d n=%d flength=%d\n",
  113.         s->count,s->remainder,s->n,(int)s->flength);
  114.  
  115.   s->sums = (struct sum_buf *)malloc(sizeof(s->sums[0])*s->count);
  116.   if (!s->sums) out_of_memory("generate_sums");
  117.   
  118.   for (i=0;i<count;i++) {
  119.     int n1 = MIN(len,n);
  120.     char *map = map_ptr(buf,offset,n1);
  121.  
  122.     s->sums[i].sum1 = get_checksum1(map,n1);
  123.     get_checksum2(map,n1,s->sums[i].sum2);
  124.  
  125.     s->sums[i].offset = offset;
  126.     s->sums[i].len = n1;
  127.     s->sums[i].i = i;
  128.  
  129.     if (verbose > 3)
  130.       fprintf(FERROR,"chunk[%d] offset=%d len=%d sum1=%08x\n",
  131.           i,(int)s->sums[i].offset,s->sums[i].len,s->sums[i].sum1);
  132.  
  133.     len -= n1;
  134.     offset += n1;
  135.   }
  136.  
  137.   return s;
  138. }
  139.  
  140.  
  141. /*
  142.   receive the checksums for a buffer
  143.   */
  144. static struct sum_struct *receive_sums(int f)
  145. {
  146.   struct sum_struct *s;
  147.   int i;
  148.   off_t offset = 0;
  149.   int block_len;
  150.  
  151.   s = (struct sum_struct *)malloc(sizeof(*s));
  152.   if (!s) out_of_memory("receive_sums");
  153.  
  154.   s->count = read_int(f);
  155.   s->n = read_int(f);
  156.   s->remainder = read_int(f);  
  157.   s->sums = NULL;
  158.  
  159.   if (verbose > 3)
  160.     fprintf(FERROR,"count=%d n=%d rem=%d\n",
  161.         s->count,s->n,s->remainder);
  162.  
  163.   block_len = s->n;
  164.  
  165.   if (s->count == 0) 
  166.     return(s);
  167.  
  168.   s->sums = (struct sum_buf *)malloc(sizeof(s->sums[0])*s->count);
  169.   if (!s->sums) out_of_memory("receive_sums");
  170.  
  171.   for (i=0;i<s->count;i++) {
  172.     s->sums[i].sum1 = read_int(f);
  173.     read_buf(f,s->sums[i].sum2,csum_length);
  174.  
  175.     s->sums[i].offset = offset;
  176.     s->sums[i].i = i;
  177.  
  178.     if (i == s->count-1 && s->remainder != 0) {
  179.       s->sums[i].len = s->remainder;
  180.     } else {
  181.       s->sums[i].len = s->n;
  182.     }
  183.     offset += s->sums[i].len;
  184.  
  185.     if (verbose > 3)
  186.       fprintf(FERROR,"chunk[%d] len=%d offset=%d sum1=%08x\n",
  187.           i,s->sums[i].len,(int)s->sums[i].offset,s->sums[i].sum1);
  188.   }
  189.  
  190.   s->flength = offset;
  191.  
  192.   return s;
  193. }
  194.  
  195.  
  196. static int set_perms(char *fname,struct file_struct *file,struct stat *st,
  197.              int report)
  198. {
  199.   int updated = 0;
  200.   struct stat st2;
  201.  
  202.   if (dry_run) return 0;
  203.  
  204.   if (!st) {
  205.     if (lstat(fname,&st2) != 0) {
  206.       fprintf(FERROR,"stat %s : %s\n",fname,strerror(errno));
  207.       return 0;
  208.     }
  209.     st = &st2;
  210.   }
  211.  
  212.   if (preserve_times && !S_ISLNK(st->st_mode) &&
  213.       st->st_mtime != file->modtime) {
  214.     updated = 1;
  215.     if (set_modtime(fname,file->modtime) != 0) {
  216.       fprintf(FERROR,"failed to set times on %s : %s\n",
  217.           fname,strerror(errno));
  218.       return 0;
  219.     }
  220.   }
  221.  
  222. #ifdef HAVE_CHMOD
  223.   if (preserve_perms && !S_ISLNK(st->st_mode) &&
  224.       st->st_mode != file->mode) {
  225.     updated = 1;
  226.     if (chmod(fname,file->mode) != 0) {
  227.       fprintf(FERROR,"failed to set permissions on %s : %s\n",
  228.           fname,strerror(errno));
  229.       return 0;
  230.     }
  231.   }
  232. #endif
  233.  
  234.   if ((am_root && preserve_uid && st->st_uid != file->uid) || 
  235.       (preserve_gid && st->st_gid != file->gid)) {
  236.     updated = 1;
  237.     if (lchown(fname,
  238.            (am_root&&preserve_uid)?file->uid:-1,
  239.            preserve_gid?file->gid:-1) != 0) {
  240.       if (verbose>1 || preserve_uid)
  241.     fprintf(FERROR,"chown %s : %s\n",fname,strerror(errno));
  242.       return updated;
  243.     }
  244.   }
  245.     
  246.   if (verbose > 1 && report) {
  247.     if (updated)
  248.       fprintf(FINFO,"%s\n",fname);
  249.     else
  250.       fprintf(FINFO,"%s is uptodate\n",fname);
  251.   }
  252.   return updated;
  253. }
  254.  
  255.  
  256. void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
  257. {  
  258.   int fd;
  259.   struct stat st;
  260.   struct map_struct *buf;
  261.   struct sum_struct *s;
  262.   char sum[MD4_SUM_LENGTH];
  263.   int statret;
  264.   struct file_struct *file = &flist->files[i];
  265.  
  266.   if (verbose > 2)
  267.     fprintf(FERROR,"recv_generator(%s,%d)\n",fname,i);
  268.  
  269.   statret = lstat(fname,&st);
  270.  
  271.   if (S_ISDIR(file->mode)) {
  272.     if (dry_run) return;
  273.     if (statret == 0 && !S_ISDIR(st.st_mode)) {
  274.       if (unlink(fname) != 0) {
  275.     fprintf(FERROR,"unlink %s : %s\n",fname,strerror(errno));
  276.     return;
  277.       }
  278.       statret = -1;
  279.     }
  280.     if (statret != 0 && mkdir(fname,file->mode) != 0 && errno != EEXIST)
  281.       fprintf(FERROR,"mkdir %s : %s\n",fname,strerror(errno));
  282.     if (set_perms(fname,file,NULL,0) && verbose) 
  283.       fprintf(FINFO,"%s/\n",fname);
  284.     return;
  285.   }
  286.  
  287. #if SUPPORT_LINKS
  288.   if (preserve_links && S_ISLNK(file->mode)) {
  289.     char lnk[MAXPATHLEN];
  290.     int l;
  291.     if (statret == 0) {
  292.       l = readlink(fname,lnk,MAXPATHLEN-1);
  293.       if (l > 0) {
  294.     lnk[l] = 0;
  295.     if (strcmp(lnk,file->link) == 0) {
  296.       set_perms(fname,file,&st,1);
  297.       return;
  298.     }
  299.       }
  300.     }
  301.     if (!dry_run) unlink(fname);
  302.     if (!dry_run && symlink(file->link,fname) != 0) {
  303.       fprintf(FERROR,"link %s -> %s : %s\n",
  304.           fname,file->link,strerror(errno));
  305.     } else {
  306.       set_perms(fname,file,NULL,0);
  307.       if (verbose) 
  308.     fprintf(FINFO,"%s -> %s\n",
  309.         fname,file->link);
  310.     }
  311.     return;
  312.   }
  313. #endif
  314.  
  315. #ifdef HAVE_MKNOD
  316.   if (am_root && preserve_devices && IS_DEVICE(file->mode)) {
  317.     if (statret != 0 || 
  318.     st.st_mode != file->mode ||
  319.     st.st_rdev != file->rdev) {    
  320.       if (!dry_run) unlink(fname);
  321.       if (verbose > 2)
  322.     fprintf(FERROR,"mknod(%s,0%o,0x%x)\n",
  323.         fname,(int)file->mode,(int)file->rdev);
  324.       if (!dry_run && 
  325.       mknod(fname,file->mode,file->rdev) != 0) {
  326.     fprintf(FERROR,"mknod %s : %s\n",fname,strerror(errno));
  327.       } else {
  328.     set_perms(fname,file,NULL,0);
  329.     if (verbose)
  330.       fprintf(FINFO,"%s\n",fname);
  331.       }
  332.     } else {
  333.       set_perms(fname,file,&st,1);
  334.     }
  335.     return;
  336.   }
  337. #endif
  338.  
  339.   if (preserve_hard_links && check_hard_link(file)) {
  340.     if (verbose > 1)
  341.       fprintf(FINFO,"%s is a hard link\n",file->name);
  342.     return;
  343.   }
  344.  
  345.   if (!S_ISREG(file->mode)) {
  346.     fprintf(FERROR,"skipping non-regular file %s\n",fname);
  347.     return;
  348.   }
  349.  
  350.   if (statret == -1) {
  351.     if (errno == ENOENT) {
  352.       write_int(f_out,i);
  353.       if (!dry_run) send_sums(NULL,f_out);
  354.     } else {
  355.       if (verbose > 1)
  356.     fprintf(FERROR,"recv_generator failed to open %s\n",fname);
  357.     }
  358.     return;
  359.   }
  360.  
  361.   if (!S_ISREG(st.st_mode)) {
  362.     /* its not a regular file on the receiving end, but it is on the
  363.        sending end. If its a directory then skip it (too dangerous to
  364.        do a recursive deletion??) otherwise try to unlink it */
  365.     if (S_ISDIR(st.st_mode)) {
  366.       fprintf(FERROR,"ERROR: %s is a directory\n",fname);
  367.       return;
  368.     }
  369.     if (unlink(fname) != 0) {
  370.       fprintf(FERROR,"%s : not a regular file (generator)\n",fname);
  371.       return;
  372.     }
  373.  
  374.     /* now pretend the file didn't exist */
  375.     write_int(f_out,i);
  376.     if (!dry_run) send_sums(NULL,f_out);    
  377.     return;
  378.   }
  379.  
  380.   if (update_only && st.st_mtime >= file->modtime) {
  381.     if (verbose > 1)
  382.       fprintf(FERROR,"%s is newer\n",fname);
  383.     return;
  384.   }
  385.  
  386.   if (always_checksum && S_ISREG(st.st_mode)) {
  387.     file_checksum(fname,sum,st.st_size);
  388.   }
  389.  
  390.   if (st.st_size == file->length &&
  391.       ((!ignore_times && st.st_mtime == file->modtime) ||
  392.        (always_checksum && S_ISREG(st.st_mode) &&       
  393.     memcmp(sum,file->sum,csum_length) == 0))) {
  394.     set_perms(fname,file,&st,1);
  395.     return;
  396.   }
  397.  
  398.   if (dry_run) {
  399.     write_int(f_out,i);
  400.     return;
  401.   }
  402.  
  403.   /* open the file */  
  404.   fd = open(fname,O_RDONLY);
  405.  
  406.   if (fd == -1) {
  407.     fprintf(FERROR,"failed to open %s : %s\n",fname,strerror(errno));
  408.     return;
  409.   }
  410.  
  411.   if (st.st_size > 0) {
  412.     buf = map_file(fd,st.st_size);
  413.   } else {
  414.     buf = NULL;
  415.   }
  416.  
  417.   if (verbose > 3)
  418.     fprintf(FERROR,"gen mapped %s of size %d\n",fname,(int)st.st_size);
  419.  
  420.   s = generate_sums(buf,st.st_size,block_size);
  421.  
  422.   if (verbose > 2)
  423.     fprintf(FERROR,"sending sums for %d\n",i);
  424.  
  425.   write_int(f_out,i);
  426.   send_sums(s,f_out);
  427.   write_flush(f_out);
  428.  
  429.   close(fd);
  430.   if (buf) unmap_file(buf);
  431.  
  432.   free_sums(s);
  433. }
  434.  
  435.  
  436.  
  437. static int receive_data(int f_in,struct map_struct *buf,int fd,char *fname)
  438. {
  439.   int i,n,remainder,len,count;
  440.   off_t offset = 0;
  441.   off_t offset2;
  442.   char *data;
  443.   static char file_sum1[MD4_SUM_LENGTH];
  444.   static char file_sum2[MD4_SUM_LENGTH];
  445.   char *map=NULL;
  446.  
  447.   count = read_int(f_in);
  448.   n = read_int(f_in);
  449.   remainder = read_int(f_in);
  450.  
  451.   sum_init();
  452.  
  453.   for (i=recv_token(f_in,&data); i != 0; i=recv_token(f_in,&data)) {
  454.     if (i > 0) {
  455.       if (verbose > 3)
  456.     fprintf(FERROR,"data recv %d at %d\n",i,(int)offset);
  457.  
  458.       sum_update(data,i);
  459.  
  460.       if (fd != -1 && write_sparse(fd,data,i) != i) {
  461.     fprintf(FERROR,"write failed on %s : %s\n",fname,strerror(errno));
  462.     exit_cleanup(1);
  463.       }
  464.       offset += i;
  465.     } else {
  466.       i = -(i+1);
  467.       offset2 = i*n;
  468.       len = n;
  469.       if (i == count-1 && remainder != 0)
  470.     len = remainder;
  471.  
  472.       if (verbose > 3)
  473.     fprintf(FERROR,"chunk[%d] of size %d at %d offset=%d\n",
  474.         i,len,(int)offset2,(int)offset);
  475.  
  476.       map = map_ptr(buf,offset2,len);
  477.  
  478.       see_token(map, len);
  479.       sum_update(map,len);
  480.  
  481.       if (fd != -1 && write_sparse(fd,map,len) != len) {
  482.     fprintf(FERROR,"write failed on %s : %s\n",fname,strerror(errno));
  483.     exit_cleanup(1);
  484.       }
  485.       offset += len;
  486.     }
  487.   }
  488.  
  489.   if (fd != -1 && offset > 0 && sparse_end(fd) != 0) {
  490.     fprintf(FERROR,"write failed on %s : %s\n",fname,strerror(errno));
  491.     exit_cleanup(1);
  492.   }
  493.  
  494.   sum_end(file_sum1);
  495.  
  496.   if (remote_version >= 14) {
  497.     read_buf(f_in,file_sum2,MD4_SUM_LENGTH);
  498.     if (verbose > 2)
  499.       fprintf(FERROR,"got file_sum\n");
  500.     if (fd != -1 && memcmp(file_sum1,file_sum2,MD4_SUM_LENGTH) != 0)
  501.       return 0;
  502.   }
  503.   return 1;
  504. }
  505.  
  506.  
  507. static void delete_one(struct file_struct *f)
  508. {
  509.   if (!S_ISDIR(f->mode)) {
  510.     if (!dry_run && unlink(f->name) != 0) {
  511.       fprintf(FERROR,"unlink %s : %s\n",f->name,strerror(errno));
  512.     } else if (verbose) {
  513.       fprintf(FERROR,"deleting %s\n",f->name);
  514.     }
  515.   } else {    
  516.     if (!dry_run && rmdir(f->name) != 0) {
  517.       if (errno != ENOTEMPTY)
  518.     fprintf(FERROR,"rmdir %s : %s\n",f->name,strerror(errno));
  519.     } else if (verbose) {
  520.       fprintf(FERROR,"deleting directory %s\n",f->name);      
  521.     }
  522.   }
  523. }
  524.  
  525.  
  526. static void delete_files(struct file_list *flist)
  527. {
  528.   struct file_list *local_file_list;
  529.   char *dot=".";
  530.   int i;
  531.  
  532.   if (cvs_exclude)
  533.     add_cvs_excludes();
  534.  
  535.   if (!(local_file_list = send_file_list(-1,1,&dot)))
  536.     return;
  537.  
  538.   for (i=local_file_list->count-1;i>=0;i--) {
  539.     if (!local_file_list->files[i].name) continue;
  540.     if (-1 == flist_find(flist,&local_file_list->files[i])) {
  541.       delete_one(&local_file_list->files[i]);
  542.     }    
  543.   }
  544. }
  545.  
  546. static char *cleanup_fname = NULL;
  547.  
  548. void exit_cleanup(int code)
  549. {
  550.   if (cleanup_fname)
  551.     unlink(cleanup_fname);
  552.   exit(code);
  553. }
  554.  
  555. void sig_int(void)
  556. {
  557.   exit_cleanup(1);
  558. }
  559.  
  560.  
  561. int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
  562. {  
  563.   int fd1,fd2;
  564.   struct stat st;
  565.   char *fname;
  566.   char fnametmp[MAXPATHLEN];
  567.   struct map_struct *buf;
  568.   int i;
  569.   struct file_struct *file;
  570.   int phase=0;
  571.   int recv_ok;
  572.  
  573.   if (verbose > 2) {
  574.     fprintf(FERROR,"recv_files(%d) starting\n",flist->count);
  575.   }
  576.  
  577.   if (recurse && delete_mode && !local_name && flist->count>0) {
  578.     delete_files(flist);
  579.   }
  580.  
  581.   while (1) 
  582.     {      
  583.       i = read_int(f_in);
  584.       if (i == -1) {
  585.     if (phase==0 && remote_version >= 13) {
  586.       phase++;
  587.       csum_length = SUM_LENGTH;
  588.       if (verbose > 2)
  589.         fprintf(FERROR,"recv_files phase=%d\n",phase);
  590.       write_int(f_gen,-1);
  591.       write_flush(f_gen);
  592.       continue;
  593.     }
  594.     break;
  595.       }
  596.  
  597.       file = &flist->files[i];
  598.       fname = file->name;
  599.  
  600.       if (local_name)
  601.     fname = local_name;
  602.  
  603.       if (dry_run) {
  604.     if (!am_server && verbose)
  605.       printf("%s\n",fname);
  606.     continue;
  607.       }
  608.  
  609.       if (verbose > 2)
  610.     fprintf(FERROR,"recv_files(%s)\n",fname);
  611.  
  612.       /* open the file */  
  613.       fd1 = open(fname,O_RDONLY);
  614.  
  615.       if (fd1 != -1 && fstat(fd1,&st) != 0) {
  616.     fprintf(FERROR,"fstat %s : %s\n",fname,strerror(errno));
  617.     receive_data(f_in,NULL,-1,NULL);
  618.     close(fd1);
  619.     continue;
  620.       }
  621.  
  622.       if (fd1 != -1 && !S_ISREG(st.st_mode)) {
  623.     fprintf(FERROR,"%s : not a regular file (recv_files)\n",fname);
  624.     receive_data(f_in,NULL,-1,NULL);
  625.     close(fd1);
  626.     continue;
  627.       }
  628.  
  629.       if (fd1 != -1 && st.st_size > 0) {
  630.     buf = map_file(fd1,st.st_size);
  631.     if (verbose > 2)
  632.       fprintf(FERROR,"recv mapped %s of size %d\n",fname,(int)st.st_size);
  633.       } else {
  634.     buf = NULL;
  635.       }
  636.  
  637.       /* open tmp file */
  638.       sprintf(fnametmp,"%s.XXXXXX",fname);
  639.       if (NULL == mktemp(fnametmp)) {
  640.     fprintf(FERROR,"mktemp %s failed\n",fnametmp);
  641.     receive_data(f_in,buf,-1,NULL);
  642.     if (buf) unmap_file(buf);
  643.     close(fd1);
  644.     continue;
  645.       }
  646.       fd2 = open(fnametmp,O_WRONLY|O_CREAT,file->mode);
  647.       if (fd2 == -1) {
  648.     fprintf(FERROR,"open %s : %s\n",fnametmp,strerror(errno));
  649.     receive_data(f_in,buf,-1,NULL);
  650.     if (buf) unmap_file(buf);
  651.     close(fd1);
  652.     continue;
  653.       }
  654.       
  655.       cleanup_fname = fnametmp;
  656.  
  657.       if (!am_server && verbose)
  658.     printf("%s\n",fname);
  659.  
  660.       /* recv file data */
  661.       recv_ok = receive_data(f_in,buf,fd2,fname);
  662.  
  663.       if (fd1 != -1) {
  664.     if (buf) unmap_file(buf);
  665.     close(fd1);
  666.       }
  667.       close(fd2);
  668.  
  669.       if (verbose > 2)
  670.     fprintf(FERROR,"renaming %s to %s\n",fnametmp,fname);
  671.  
  672.       if (make_backups) {
  673.     char fnamebak[MAXPATHLEN];
  674.     sprintf(fnamebak,"%s%s",fname,backup_suffix);
  675.     if (rename(fname,fnamebak) != 0 && errno != ENOENT) {
  676.       fprintf(FERROR,"rename %s %s : %s\n",fname,fnamebak,strerror(errno));
  677.       continue;
  678.     }
  679.       }
  680.  
  681.       /* move tmp file over real file */
  682.       if (rename(fnametmp,fname) != 0) {
  683.     fprintf(FERROR,"rename %s -> %s : %s\n",
  684.         fnametmp,fname,strerror(errno));
  685.     unlink(fnametmp);
  686.       }
  687.  
  688.       cleanup_fname = NULL;
  689.  
  690.       set_perms(fname,file,NULL,0);
  691.  
  692.       if (!recv_ok) {
  693.     if (verbose > 1)
  694.       fprintf(FERROR,"redoing %s(%d)\n",fname,i);
  695.         if (csum_length == SUM_LENGTH)
  696.       fprintf(FERROR,"ERROR: file corruption in %s\n",fname);
  697.     write_int(f_gen,i);
  698.       }
  699.     }
  700.  
  701.   /* now we need to fix any directory permissions that were 
  702.      modified during the transfer */
  703.   if (!am_root) {
  704.     for (i = 0; i < flist->count; i++) {
  705.       struct file_struct *file = &flist->files[i];
  706.       if (!file->name || !S_ISDIR(file->mode)) continue;
  707.       recv_generator(file->name,flist,i,-1);
  708.     }
  709.   }
  710.   
  711.  
  712.   if (verbose > 2)
  713.     fprintf(FERROR,"recv_files finished\n");
  714.   
  715.   return 0;
  716. }
  717.  
  718.  
  719.  
  720. off_t send_files(struct file_list *flist,int f_out,int f_in)
  721.   int fd;
  722.   struct sum_struct *s;
  723.   struct map_struct *buf;
  724.   struct stat st;
  725.   char fname[MAXPATHLEN];  
  726.   off_t total=0;
  727.   int i;
  728.   struct file_struct *file;
  729.   int phase = 0;
  730.  
  731.   if (verbose > 2)
  732.     fprintf(FERROR,"send_files starting\n");
  733.  
  734.   setup_nonblocking(f_in,f_out);
  735.  
  736.   while (1) 
  737.     {
  738.       i = read_int(f_in);
  739.       if (i == -1) {
  740.     if (phase==0 && remote_version >= 13) {
  741.       phase++;
  742.       csum_length = SUM_LENGTH;
  743.       write_int(f_out,-1);
  744.       write_flush(f_out);
  745.       if (verbose > 2)
  746.         fprintf(FERROR,"send_files phase=%d\n",phase);
  747.       continue;
  748.     }
  749.     break;
  750.       }
  751.  
  752.       file = &flist->files[i];
  753.  
  754.       fname[0] = 0;
  755.       if (file->dir) {
  756.     strcpy(fname,file->dir);
  757.     strcat(fname,"/");
  758.       }
  759.       strcat(fname,file->name);
  760.  
  761.       if (verbose > 2) 
  762.     fprintf(FERROR,"send_files(%d,%s)\n",i,fname);
  763.  
  764.       if (dry_run) {    
  765.     if (!am_server && verbose)
  766.       printf("%s\n",fname);
  767.     write_int(f_out,i);
  768.     continue;
  769.       }
  770.  
  771.       s = receive_sums(f_in);
  772.       if (!s) {
  773.     fprintf(FERROR,"receive_sums failed\n");
  774.     return -1;
  775.       }
  776.  
  777.       fd = open(fname,O_RDONLY);
  778.       if (fd == -1) {
  779.     fprintf(FERROR,"send_files failed to open %s: %s\n",
  780.         fname,strerror(errno));
  781.     continue;
  782.       }
  783.   
  784.       /* map the local file */
  785.       if (fstat(fd,&st) != 0) {
  786.     fprintf(FERROR,"fstat failed : %s\n",strerror(errno));
  787.     return -1;
  788.       }
  789.       
  790.       if (st.st_size > 0) {
  791.     buf = map_file(fd,st.st_size);
  792.       } else {
  793.     buf = NULL;
  794.       }
  795.  
  796.       if (verbose > 2)
  797.     fprintf(FERROR,"send_files mapped %s of size %d\n",
  798.         fname,(int)st.st_size);
  799.  
  800.       write_int(f_out,i);
  801.  
  802.       write_int(f_out,s->count);
  803.       write_int(f_out,s->n);
  804.       write_int(f_out,s->remainder);
  805.  
  806.       if (verbose > 2)
  807.     fprintf(FERROR,"calling match_sums %s\n",fname);
  808.  
  809.       if (!am_server && verbose)
  810.     printf("%s\n",fname);
  811.       
  812.       match_sums(f_out,s,buf,st.st_size);
  813.       write_flush(f_out);
  814.       
  815.       if (buf) unmap_file(buf);
  816.       close(fd);
  817.  
  818.       free_sums(s);
  819.  
  820.       if (verbose > 2)
  821.     fprintf(FERROR,"sender finished %s\n",fname);
  822.  
  823.       total += st.st_size;
  824.     }
  825.  
  826.   if (verbose > 2)
  827.     fprintf(FERROR,"send files finished\n");
  828.  
  829.   match_report();
  830.  
  831.   write_int(f_out,-1);
  832.   write_flush(f_out);
  833.  
  834.   return total;
  835. }
  836.  
  837.  
  838.  
  839. void generate_files(int f,struct file_list *flist,char *local_name,int f_recv)
  840. {
  841.   int i;
  842.   int phase=0;
  843.  
  844.   if (verbose > 2)
  845.     fprintf(FERROR,"generator starting pid=%d count=%d\n",
  846.         (int)getpid(),flist->count);
  847.  
  848.   for (i = 0; i < flist->count; i++) {
  849.     struct file_struct *file = &flist->files[i];
  850.     mode_t saved_mode = file->mode;
  851.     if (!file->name) continue;
  852.  
  853.     /* we need to ensure that any directories we create have writeable
  854.        permissions initially so that we can create the files within
  855.        them. This is then fixed after the files are transferred */
  856.     if (!am_root && S_ISDIR(file->mode)) {
  857.       file->mode |= S_IWUSR; /* user write */
  858.     }
  859.  
  860.     recv_generator(local_name?local_name:file->name,
  861.            flist,i,f);
  862.  
  863.     file->mode = saved_mode;
  864.   }
  865.  
  866.   phase++;
  867.   csum_length = SUM_LENGTH;
  868.   ignore_times=1;
  869.  
  870.   if (verbose > 2)
  871.     fprintf(FERROR,"generate_files phase=%d\n",phase);
  872.  
  873.   write_int(f,-1);
  874.   write_flush(f);
  875.  
  876.   if (remote_version >= 13) {
  877.     /* in newer versions of the protocol the files can cycle through
  878.        the system more than once to catch initial checksum errors */
  879.     for (i=read_int(f_recv); i != -1; i=read_int(f_recv)) {
  880.       struct file_struct *file = &flist->files[i];
  881.       recv_generator(local_name?local_name:file->name,
  882.              flist,i,f);    
  883.     }
  884.  
  885.     phase++;
  886.     if (verbose > 2)
  887.       fprintf(FERROR,"generate_files phase=%d\n",phase);
  888.  
  889.     write_int(f,-1);
  890.     write_flush(f);
  891.   }
  892.  
  893.  
  894.   if (verbose > 2)
  895.     fprintf(FERROR,"generator wrote %d\n",write_total());
  896. }
  897.  
  898.  
  899.