2 Copyright (C) Andrew Tridgell 1996
3 Copyright (C) Paul Mackerras 1996
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.
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.
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.
22 extern int csum_length;
26 extern int always_checksum;
27 extern time_t starttime;
29 extern int remote_version;
31 extern char *backup_suffix;
33 extern int whole_file;
34 extern int block_size;
35 extern int update_only;
36 extern int make_backups;
37 extern int preserve_links;
38 extern int preserve_hard_links;
39 extern int preserve_perms;
40 extern int preserve_devices;
41 extern int preserve_uid;
42 extern int preserve_gid;
43 extern int preserve_times;
45 extern int ignore_times;
47 extern int delete_mode;
48 extern int cvs_exclude;
50 extern int relative_paths;
55 static void free_sums(struct sum_struct *s)
57 if (s->sums) free(s->sums);
64 send a sums struct down a fd
66 static void send_sums(struct sum_struct *s,int f_out)
70 /* tell the other guy how many we are going to be doing and how many
71 bytes there are in the last chunk */
72 write_int(f_out,s?s->count:0);
73 write_int(f_out,s?s->n:block_size);
74 write_int(f_out,s?s->remainder:0);
76 for (i=0;i<s->count;i++) {
77 write_int(f_out,s->sums[i].sum1);
78 write_buf(f_out,s->sums[i].sum2,csum_length);
85 generate a stream of signatures/checksums that describe a buffer
87 generate approximately one checksum every n bytes
89 static struct sum_struct *generate_sums(struct map_struct *buf,off_t len,int n)
95 int remainder = (len%block_len);
98 count = (len+(block_len-1))/block_len;
100 s = (struct sum_struct *)malloc(sizeof(*s));
101 if (!s) out_of_memory("generate_sums");
104 s->remainder = remainder;
114 fprintf(FERROR,"count=%d rem=%d n=%d flength=%d\n",
115 s->count,s->remainder,s->n,(int)s->flength);
117 s->sums = (struct sum_buf *)malloc(sizeof(s->sums[0])*s->count);
118 if (!s->sums) out_of_memory("generate_sums");
120 for (i=0;i<count;i++) {
122 char *map = map_ptr(buf,offset,n1);
124 s->sums[i].sum1 = get_checksum1(map,n1);
125 get_checksum2(map,n1,s->sums[i].sum2);
127 s->sums[i].offset = offset;
132 fprintf(FERROR,"chunk[%d] offset=%d len=%d sum1=%08x\n",
133 i,(int)s->sums[i].offset,s->sums[i].len,s->sums[i].sum1);
144 receive the checksums for a buffer
146 static struct sum_struct *receive_sums(int f)
148 struct sum_struct *s;
152 s = (struct sum_struct *)malloc(sizeof(*s));
153 if (!s) out_of_memory("receive_sums");
155 s->count = read_int(f);
157 s->remainder = read_int(f);
161 fprintf(FERROR,"count=%d n=%d rem=%d\n",
162 s->count,s->n,s->remainder);
167 s->sums = (struct sum_buf *)malloc(sizeof(s->sums[0])*s->count);
168 if (!s->sums) out_of_memory("receive_sums");
170 for (i=0;i<s->count;i++) {
171 s->sums[i].sum1 = read_int(f);
172 read_buf(f,s->sums[i].sum2,csum_length);
174 s->sums[i].offset = offset;
177 if (i == s->count-1 && s->remainder != 0) {
178 s->sums[i].len = s->remainder;
180 s->sums[i].len = s->n;
182 offset += s->sums[i].len;
185 fprintf(FERROR,"chunk[%d] len=%d offset=%d sum1=%08x\n",
186 i,s->sums[i].len,(int)s->sums[i].offset,s->sums[i].sum1);
195 static int set_perms(char *fname,struct file_struct *file,struct stat *st,
201 if (dry_run) return 0;
204 if (link_stat(fname,&st2) != 0) {
205 fprintf(FERROR,"stat %s : %s\n",fname,strerror(errno));
211 if (preserve_times && !S_ISLNK(st->st_mode) &&
212 st->st_mtime != file->modtime) {
214 if (set_modtime(fname,file->modtime) != 0) {
215 fprintf(FERROR,"failed to set times on %s : %s\n",
216 fname,strerror(errno));
222 if (preserve_perms && !S_ISLNK(st->st_mode) &&
223 st->st_mode != file->mode) {
225 if (chmod(fname,file->mode) != 0) {
226 fprintf(FERROR,"failed to set permissions on %s : %s\n",
227 fname,strerror(errno));
233 if ((am_root && preserve_uid && st->st_uid != file->uid) ||
234 (preserve_gid && st->st_gid != file->gid)) {
237 (am_root&&preserve_uid)?file->uid:-1,
238 preserve_gid?file->gid:-1) != 0) {
239 if (verbose>1 || preserve_uid)
240 fprintf(FERROR,"chown %s : %s\n",fname,strerror(errno));
245 if (verbose > 1 && report) {
247 fprintf(FINFO,"%s\n",fname);
249 fprintf(FINFO,"%s is uptodate\n",fname);
255 void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
259 struct map_struct *buf;
260 struct sum_struct *s;
261 char sum[MD4_SUM_LENGTH];
263 struct file_struct *file = &flist->files[i];
266 fprintf(FERROR,"recv_generator(%s,%d)\n",fname,i);
268 statret = link_stat(fname,&st);
270 if (S_ISDIR(file->mode)) {
272 if (statret == 0 && !S_ISDIR(st.st_mode)) {
273 if (unlink(fname) != 0) {
274 fprintf(FERROR,"unlink %s : %s\n",fname,strerror(errno));
279 if (statret != 0 && mkdir(fname,file->mode) != 0 && errno != EEXIST) {
280 if (!(relative_paths && errno==ENOENT &&
281 create_directory_path(fname)==0 &&
282 mkdir(fname,file->mode)==0)) {
283 fprintf(FERROR,"mkdir %s : %s (2)\n",
284 fname,strerror(errno));
287 if (set_perms(fname,file,NULL,0) && verbose)
288 fprintf(FINFO,"%s/\n",fname);
292 if (preserve_links && S_ISLNK(file->mode)) {
294 char lnk[MAXPATHLEN];
297 l = readlink(fname,lnk,MAXPATHLEN-1);
300 if (strcmp(lnk,file->link) == 0) {
301 set_perms(fname,file,&st,1);
306 if (!dry_run) unlink(fname);
307 if (!dry_run && symlink(file->link,fname) != 0) {
308 fprintf(FERROR,"link %s -> %s : %s\n",
309 fname,file->link,strerror(errno));
311 set_perms(fname,file,NULL,0);
313 fprintf(FINFO,"%s -> %s\n",
321 if (am_root && preserve_devices && IS_DEVICE(file->mode)) {
323 st.st_mode != file->mode ||
324 st.st_rdev != file->rdev) {
325 if (!dry_run) unlink(fname);
327 fprintf(FERROR,"mknod(%s,0%o,0x%x)\n",
328 fname,(int)file->mode,(int)file->rdev);
330 mknod(fname,file->mode,file->rdev) != 0) {
331 fprintf(FERROR,"mknod %s : %s\n",fname,strerror(errno));
333 set_perms(fname,file,NULL,0);
335 fprintf(FINFO,"%s\n",fname);
338 set_perms(fname,file,&st,1);
344 if (preserve_hard_links && check_hard_link(file)) {
346 fprintf(FINFO,"%s is a hard link\n",file->name);
350 if (!S_ISREG(file->mode)) {
351 fprintf(FERROR,"skipping non-regular file %s\n",fname);
356 if (errno == ENOENT) {
358 if (!dry_run) send_sums(NULL,f_out);
361 fprintf(FERROR,"recv_generator failed to open %s\n",fname);
366 if (!S_ISREG(st.st_mode)) {
367 /* its not a regular file on the receiving end, but it is on the
368 sending end. If its a directory then skip it (too dangerous to
369 do a recursive deletion??) otherwise try to unlink it */
370 if (S_ISDIR(st.st_mode)) {
371 fprintf(FERROR,"ERROR: %s is a directory\n",fname);
374 if (unlink(fname) != 0) {
375 fprintf(FERROR,"%s : not a regular file (generator)\n",fname);
379 /* now pretend the file didn't exist */
381 if (!dry_run) send_sums(NULL,f_out);
385 if (update_only && st.st_mtime >= file->modtime) {
387 fprintf(FERROR,"%s is newer\n",fname);
391 if (always_checksum && S_ISREG(st.st_mode)) {
392 file_checksum(fname,sum,st.st_size);
395 if (st.st_size == file->length &&
396 ((!ignore_times && st.st_mtime == file->modtime) ||
397 (always_checksum && S_ISREG(st.st_mode) &&
398 memcmp(sum,file->sum,csum_length) == 0))) {
399 set_perms(fname,file,&st,1);
410 send_sums(NULL,f_out);
415 fd = open(fname,O_RDONLY);
418 fprintf(FERROR,"failed to open %s : %s\n",fname,strerror(errno));
422 if (st.st_size > 0) {
423 buf = map_file(fd,st.st_size);
429 fprintf(FERROR,"gen mapped %s of size %d\n",fname,(int)st.st_size);
431 s = generate_sums(buf,st.st_size,block_size);
434 fprintf(FERROR,"sending sums for %d\n",i);
441 if (buf) unmap_file(buf);
448 static int receive_data(int f_in,struct map_struct *buf,int fd,char *fname)
450 int i,n,remainder,len,count;
454 static char file_sum1[MD4_SUM_LENGTH];
455 static char file_sum2[MD4_SUM_LENGTH];
458 count = read_int(f_in);
460 remainder = read_int(f_in);
464 for (i=recv_token(f_in,&data); i != 0; i=recv_token(f_in,&data)) {
467 fprintf(FERROR,"data recv %d at %d\n",i,(int)offset);
471 if (fd != -1 && write_sparse(fd,data,i) != i) {
472 fprintf(FERROR,"write failed on %s : %s\n",fname,strerror(errno));
480 if (i == count-1 && remainder != 0)
484 fprintf(FERROR,"chunk[%d] of size %d at %d offset=%d\n",
485 i,len,(int)offset2,(int)offset);
487 map = map_ptr(buf,offset2,len);
492 if (fd != -1 && write_sparse(fd,map,len) != len) {
493 fprintf(FERROR,"write failed on %s : %s\n",fname,strerror(errno));
500 if (fd != -1 && offset > 0 && sparse_end(fd) != 0) {
501 fprintf(FERROR,"write failed on %s : %s\n",fname,strerror(errno));
507 if (remote_version >= 14) {
508 read_buf(f_in,file_sum2,MD4_SUM_LENGTH);
510 fprintf(FERROR,"got file_sum\n");
511 if (fd != -1 && memcmp(file_sum1,file_sum2,MD4_SUM_LENGTH) != 0)
518 static void delete_one(struct file_struct *f)
520 if (!S_ISDIR(f->mode)) {
521 if (!dry_run && unlink(f->name) != 0) {
522 fprintf(FERROR,"unlink %s : %s\n",f->name,strerror(errno));
523 } else if (verbose) {
524 fprintf(FERROR,"deleting %s\n",f->name);
527 if (!dry_run && rmdir(f->name) != 0) {
528 if (errno != ENOTEMPTY)
529 fprintf(FERROR,"rmdir %s : %s\n",f->name,strerror(errno));
530 } else if (verbose) {
531 fprintf(FERROR,"deleting directory %s\n",f->name);
537 /* this deletes any files on the receiving side that are not present
538 on the sending side. For version 1.6.4 I have changed the behaviour
539 to match more closely what most people seem to expect of this option */
540 static void delete_files(struct file_list *flist)
542 struct file_list *local_file_list;
544 char *last_name=NULL;
549 for (j=0;j<flist->count;j++) {
550 if (!S_ISDIR(flist->files[j].mode)) continue;
551 if (strcmp(flist->files[j].name,".")==0) continue;
553 flist->files[j].name[strlen(last_name)] == '/' &&
554 strncmp(flist->files[j].name,last_name, strlen(last_name))==0)
556 last_name = flist->files[j].name;
557 if (!(local_file_list = send_file_list(-1,1,&last_name)))
560 fprintf(FINFO,"deleting in %s\n", last_name);
562 for (i=local_file_list->count-1;i>=0;i--) {
563 if (!local_file_list->files[i].name) continue;
564 if (-1 == flist_find(flist,&local_file_list->files[i])) {
565 delete_one(&local_file_list->files[i]);
571 static char *cleanup_fname = NULL;
573 void exit_cleanup(int code)
576 unlink(cleanup_fname);
577 signal(SIGUSR1, SIG_IGN);
580 kill(-getpgrp(), SIGUSR1);
582 kill(-getpgrp(getpid()), SIGUSR1);
594 int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
599 char fnametmp[MAXPATHLEN];
600 struct map_struct *buf;
602 struct file_struct *file;
607 fprintf(FERROR,"recv_files(%d) starting\n",flist->count);
610 if (recurse && delete_mode && !local_name && flist->count>0) {
618 if (phase==0 && remote_version >= 13) {
620 csum_length = SUM_LENGTH;
622 fprintf(FERROR,"recv_files phase=%d\n",phase);
630 file = &flist->files[i];
637 if (!am_server && verbose)
638 printf("%s\n",fname);
643 fprintf(FERROR,"recv_files(%s)\n",fname);
646 fd1 = open(fname,O_RDONLY);
648 if (fd1 != -1 && fstat(fd1,&st) != 0) {
649 fprintf(FERROR,"fstat %s : %s\n",fname,strerror(errno));
650 receive_data(f_in,NULL,-1,NULL);
655 if (fd1 != -1 && !S_ISREG(st.st_mode)) {
656 fprintf(FERROR,"%s : not a regular file (recv_files)\n",fname);
657 receive_data(f_in,NULL,-1,NULL);
662 if (fd1 != -1 && st.st_size > 0) {
663 buf = map_file(fd1,st.st_size);
665 fprintf(FERROR,"recv mapped %s of size %d\n",fname,(int)st.st_size);
671 if (strlen(fname) > (MAXPATHLEN-8)) {
672 fprintf(FERROR,"filename too long\n");
676 sprintf(fnametmp,"%s.XXXXXX",fname);
677 if (NULL == mktemp(fnametmp)) {
678 fprintf(FERROR,"mktemp %s failed\n",fnametmp);
679 receive_data(f_in,buf,-1,NULL);
680 if (buf) unmap_file(buf);
684 fd2 = open(fnametmp,O_WRONLY|O_CREAT,file->mode);
685 if (fd2 == -1 && relative_paths && errno == ENOENT &&
686 create_directory_path(fnametmp) == 0) {
687 fd2 = open(fnametmp,O_WRONLY|O_CREAT,file->mode);
690 fprintf(FERROR,"open %s : %s\n",fnametmp,strerror(errno));
691 receive_data(f_in,buf,-1,NULL);
692 if (buf) unmap_file(buf);
697 cleanup_fname = fnametmp;
699 if (!am_server && verbose)
700 printf("%s\n",fname);
703 recv_ok = receive_data(f_in,buf,fd2,fname);
706 if (buf) unmap_file(buf);
712 fprintf(FERROR,"renaming %s to %s\n",fnametmp,fname);
715 char fnamebak[MAXPATHLEN];
716 if (strlen(fname) + strlen(backup_suffix) > (MAXPATHLEN-1)) {
717 fprintf(FERROR,"backup filename too long\n");
720 sprintf(fnamebak,"%s%s",fname,backup_suffix);
721 if (rename(fname,fnamebak) != 0 && errno != ENOENT) {
722 fprintf(FERROR,"rename %s %s : %s\n",fname,fnamebak,strerror(errno));
727 /* move tmp file over real file */
728 if (rename(fnametmp,fname) != 0) {
729 fprintf(FERROR,"rename %s -> %s : %s\n",
730 fnametmp,fname,strerror(errno));
734 cleanup_fname = NULL;
736 set_perms(fname,file,NULL,0);
740 fprintf(FERROR,"redoing %s(%d)\n",fname,i);
741 if (csum_length == SUM_LENGTH)
742 fprintf(FERROR,"ERROR: file corruption in %s\n",fname);
747 if (preserve_hard_links)
748 do_hard_links(flist);
750 /* now we need to fix any directory permissions that were
751 modified during the transfer */
752 for (i = 0; i < flist->count; i++) {
753 struct file_struct *file = &flist->files[i];
754 if (!file->name || !S_ISDIR(file->mode)) continue;
755 recv_generator(file->name,flist,i,-1);
759 fprintf(FERROR,"recv_files finished\n");
766 off_t send_files(struct file_list *flist,int f_out,int f_in)
769 struct sum_struct *s;
770 struct map_struct *buf;
772 char fname[MAXPATHLEN];
775 struct file_struct *file;
779 fprintf(FERROR,"send_files starting\n");
781 setup_nonblocking(f_in,f_out);
787 if (phase==0 && remote_version >= 13) {
789 csum_length = SUM_LENGTH;
793 fprintf(FERROR,"send_files phase=%d\n",phase);
799 file = &flist->files[i];
803 strncpy(fname,file->dir,MAXPATHLEN-1);
804 fname[MAXPATHLEN-1] = 0;
807 strncat(fname,file->name,MAXPATHLEN-strlen(fname));
810 fprintf(FERROR,"send_files(%d,%s)\n",i,fname);
813 if (!am_server && verbose)
814 printf("%s\n",fname);
819 s = receive_sums(f_in);
821 fprintf(FERROR,"receive_sums failed\n");
825 fd = open(fname,O_RDONLY);
827 fprintf(FERROR,"send_files failed to open %s: %s\n",
828 fname,strerror(errno));
832 /* map the local file */
833 if (fstat(fd,&st) != 0) {
834 fprintf(FERROR,"fstat failed : %s\n",strerror(errno));
839 if (st.st_size > 0) {
840 buf = map_file(fd,st.st_size);
846 fprintf(FERROR,"send_files mapped %s of size %d\n",
847 fname,(int)st.st_size);
851 write_int(f_out,s->count);
852 write_int(f_out,s->n);
853 write_int(f_out,s->remainder);
856 fprintf(FERROR,"calling match_sums %s\n",fname);
858 if (!am_server && verbose)
859 printf("%s\n",fname);
861 match_sums(f_out,s,buf,st.st_size);
864 if (buf) unmap_file(buf);
870 fprintf(FERROR,"sender finished %s\n",fname);
876 fprintf(FERROR,"send files finished\n");
888 void generate_files(int f,struct file_list *flist,char *local_name,int f_recv)
894 fprintf(FERROR,"generator starting pid=%d count=%d\n",
895 (int)getpid(),flist->count);
897 for (i = 0; i < flist->count; i++) {
898 struct file_struct *file = &flist->files[i];
899 mode_t saved_mode = file->mode;
900 if (!file->name) continue;
902 /* we need to ensure that any directories we create have writeable
903 permissions initially so that we can create the files within
904 them. This is then fixed after the files are transferred */
905 if (!am_root && S_ISDIR(file->mode)) {
906 file->mode |= S_IWUSR; /* user write */
909 recv_generator(local_name?local_name:file->name,
912 file->mode = saved_mode;
916 csum_length = SUM_LENGTH;
920 fprintf(FERROR,"generate_files phase=%d\n",phase);
925 if (remote_version >= 13) {
926 /* in newer versions of the protocol the files can cycle through
927 the system more than once to catch initial checksum errors */
928 for (i=read_int(f_recv); i != -1; i=read_int(f_recv)) {
929 struct file_struct *file = &flist->files[i];
930 recv_generator(local_name?local_name:file->name,
936 fprintf(FERROR,"generate_files phase=%d\n",phase);
944 fprintf(FERROR,"generator wrote %d\n",write_total());