1 /* -*- c-file-style: "linux" -*-
3 Copyright (C) 1996-2000 by Andrew Tridgell
4 Copyright (C) Paul Mackerras 1996
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 extern int delete_mode
;
26 extern int protocol_version
;
27 extern int csum_length
;
28 extern struct stats stats
;
31 extern int relative_paths
;
32 extern int preserve_hard_links
;
33 extern int cvs_exclude
;
36 extern char *compare_dest
;
37 extern int make_backups
;
38 extern int do_progress
;
39 extern char *backup_dir
;
40 extern char *backup_suffix
;
41 extern int backup_suffix_len
;
43 static struct delete_list
{
47 static int dlist_len
, dlist_alloc_len
;
49 /* yuck! This function wouldn't have been necessary if I had the sorting
50 * algorithm right. Unfortunately fixing the sorting algorithm would introduce
51 * a backward incompatibility as file list indexes are sent over the link.
53 static int delete_already_done(struct file_list
*flist
,int j
)
58 if (link_stat(f_name(flist
->files
[j
]), &st
)) return 1;
60 for (i
= 0; i
< dlist_len
; i
++) {
61 if (st
.st_ino
== delete_list
[i
].inode
&&
62 (DEV64_T
)st
.st_dev
== delete_list
[i
].dev
)
69 static void add_delete_entry(struct file_struct
*file
)
71 if (dlist_len
== dlist_alloc_len
) {
72 dlist_alloc_len
+= 1024;
73 delete_list
= realloc_array(delete_list
, struct delete_list
,
75 if (!delete_list
) out_of_memory("add_delete_entry");
78 delete_list
[dlist_len
].dev
= file
->dev
;
79 delete_list
[dlist_len
].inode
= file
->inode
;
83 rprintf(FINFO
,"added %s to delete list\n", f_name(file
));
86 static void delete_one(char *fn
, int is_dir
)
89 if (robust_unlink(fn
) != 0) {
90 rprintf(FERROR
, "delete_one: unlink %s failed: %s\n",
91 full_fname(fn
), strerror(errno
));
93 rprintf(FINFO
, "deleting %s\n", fn
);
96 if (do_rmdir(fn
) != 0) {
97 if (errno
!= ENOTEMPTY
&& errno
!= EEXIST
) {
98 rprintf(FERROR
, "delete_one: rmdir %s failed: %s\n",
99 full_fname(fn
), strerror(errno
));
101 } else if (verbose
) {
102 rprintf(FINFO
, "deleting directory %s\n", fn
);
108 static int is_backup_file(char *fn
)
110 int k
= strlen(fn
) - backup_suffix_len
;
111 return k
> 0 && strcmp(fn
+k
, backup_suffix
) == 0;
115 /* this deletes any files on the receiving side that are not present
116 * on the sending side. For version 1.6.4 I have changed the behaviour
117 * to match more closely what most people seem to expect of this option */
118 void delete_files(struct file_list
*flist
)
120 struct file_list
*local_file_list
;
123 extern int module_id
;
124 extern int ignore_errors
;
125 extern int max_delete
;
126 static int deletion_count
;
131 if (io_error
&& !(lp_ignore_errors(module_id
) || ignore_errors
)) {
132 rprintf(FINFO
,"IO error encountered - skipping file deletion\n");
136 for (j
=0;j
<flist
->count
;j
++) {
137 if (!S_ISDIR(flist
->files
[j
]->mode
) ||
138 !(flist
->files
[j
]->flags
& FLAG_DELETE
)) continue;
140 if (protocol_version
< 19 &&
141 delete_already_done(flist
, j
)) continue;
143 name
= strdup(f_name(flist
->files
[j
]));
145 if (!(local_file_list
= send_file_list(-1,1,&name
))) {
151 rprintf(FINFO
,"deleting in %s\n", name
);
153 for (i
=local_file_list
->count
-1;i
>=0;i
--) {
154 if (max_delete
&& deletion_count
> max_delete
) break;
155 if (!local_file_list
->files
[i
]->basename
) continue;
156 if (protocol_version
< 19 &&
157 S_ISDIR(local_file_list
->files
[i
]->mode
))
158 add_delete_entry(local_file_list
->files
[i
]);
159 if (-1 == flist_find(flist
,local_file_list
->files
[i
])) {
160 char *f
= f_name(local_file_list
->files
[i
]);
161 if (make_backups
&& (backup_dir
|| !is_backup_file(f
))) {
162 (void) make_backup(f
);
164 rprintf(FINFO
, "deleting %s\n", f
);
166 int mode
= local_file_list
->files
[i
]->mode
;
167 delete_one(f
, S_ISDIR(mode
) != 0);
172 flist_free(local_file_list
);
179 * get_tmpname() - create a tmp filename for a given filename
181 * If a tmpdir is defined, use that as the directory to
182 * put it in. Otherwise, the tmp filename is in the same
183 * directory as the given name. Note that there may be no
184 * directory at all in the given name!
186 * The tmp filename is basically the given filename with a
187 * dot prepended, and .XXXXXX appended (for mkstemp() to
188 * put its unique gunk in). Take care to not exceed
189 * either the MAXPATHLEN or NAME_MAX, esp. the last, as
190 * the basename basically becomes 8 chars longer. In that
191 * case, the original name is shortened sufficiently to
194 * Of course, there's no real reason for the tmp name to
195 * look like the original, except to satisfy us humans.
196 * As long as it's unique, rsync will work.
199 static int get_tmpname(char *fnametmp
, char *fname
)
206 strlcpy(fnametmp
, tmpdir
, MAXPATHLEN
- 2);
207 length
= strlen(fnametmp
);
208 fnametmp
[length
++] = '/';
209 fnametmp
[length
] = '\0'; /* always NULL terminated */
212 if ((f
= strrchr(fname
, '/')) != NULL
) {
216 /* copy up to and including the slash */
217 strlcpy(fnametmp
, fname
, length
+ 1);
222 fnametmp
[length
++] = '.';
223 fnametmp
[length
] = '\0'; /* always NULL terminated */
225 maxname
= MIN(MAXPATHLEN
- 7 - length
, NAME_MAX
- 8);
228 rprintf(FERROR
, "temporary filename too long: %s\n", fname
);
233 strlcpy(fnametmp
+ length
, f
, maxname
);
234 strcat(fnametmp
+ length
, ".XXXXXX");
240 static int receive_data(int f_in
,struct map_struct
*buf
,int fd
,char *fname
,
244 struct sum_struct sum
;
249 static char file_sum1
[MD4_SUM_LENGTH
];
250 static char file_sum2
[MD4_SUM_LENGTH
];
253 read_sum_head(f_in
, &sum
);
257 for (i
=recv_token(f_in
,&data
); i
!= 0; i
=recv_token(f_in
,&data
)) {
259 show_progress(offset
, total_size
);
262 extern int cleanup_got_literal
;
265 rprintf(FINFO
,"data recv %d at %.0f\n",
269 stats
.literal_data
+= i
;
270 cleanup_got_literal
= 1;
274 if (fd
!= -1 && write_file(fd
,data
,i
) != i
) {
275 rprintf(FERROR
, "write failed on %s: %s\n",
276 full_fname(fname
), strerror(errno
));
277 exit_cleanup(RERR_FILEIO
);
284 offset2
= i
*(OFF_T
)sum
.blength
;
286 if (i
== (int) sum
.count
-1 && sum
.remainder
!= 0)
289 stats
.matched_data
+= len
;
292 rprintf(FINFO
,"chunk[%d] of size %d at %.0f offset=%.0f\n",
293 i
,len
,(double)offset2
,(double)offset
);
296 map
= map_ptr(buf
,offset2
,len
);
302 if (fd
!= -1 && write_file(fd
,map
,len
) != (int) len
) {
303 rprintf(FERROR
, "write failed on %s: %s\n",
304 full_fname(fname
), strerror(errno
));
305 exit_cleanup(RERR_FILEIO
);
311 end_progress(total_size
);
313 if (fd
!= -1 && offset
> 0 && sparse_end(fd
) != 0) {
314 rprintf(FERROR
, "write failed on %s: %s\n",
315 full_fname(fname
), strerror(errno
));
316 exit_cleanup(RERR_FILEIO
);
321 read_buf(f_in
,file_sum2
,MD4_SUM_LENGTH
);
323 rprintf(FINFO
,"got file_sum\n");
325 if (fd
!= -1 && memcmp(file_sum1
,file_sum2
,MD4_SUM_LENGTH
) != 0) {
333 * main routine for receiver process.
335 * Receiver process runs on the same host as the generator process. */
336 int recv_files(int f_in
,struct file_list
*flist
,char *local_name
,int f_gen
)
341 char template[MAXPATHLEN
];
342 char fnametmp
[MAXPATHLEN
];
344 char fnamecmpbuf
[MAXPATHLEN
];
345 struct map_struct
*buf
;
347 struct file_struct
*file
;
350 extern struct stats stats
;
351 extern int preserve_perms
;
352 extern int delete_after
;
353 extern int orig_umask
;
354 struct stats initial_stats
;
357 rprintf(FINFO
,"recv_files(%d) starting\n",flist
->count
);
367 csum_length
= SUM_LENGTH
;
369 rprintf(FINFO
,"recv_files phase=%d\n",phase
);
376 if (i
< 0 || i
>= flist
->count
) {
377 rprintf(FERROR
,"Invalid file index %d in recv_files (count=%d)\n",
379 exit_cleanup(RERR_PROTOCOL
);
382 file
= flist
->files
[i
];
383 fname
= f_name(file
);
385 stats
.num_transferred_files
++;
386 stats
.total_transferred_size
+= file
->length
;
392 if (!am_server
&& verbose
) { /* log transfer */
393 rprintf(FINFO
, "%s\n", fname
);
398 initial_stats
= stats
;
401 rprintf(FINFO
,"recv_files(%s)\n",fname
);
406 fd1
= do_open(fnamecmp
, O_RDONLY
, 0);
408 if ((fd1
== -1) && (compare_dest
!= NULL
)) {
409 /* try the file at compare_dest instead */
410 snprintf(fnamecmpbuf
,MAXPATHLEN
,"%s/%s",
412 fnamecmp
= fnamecmpbuf
;
413 fd1
= do_open(fnamecmp
, O_RDONLY
, 0);
416 if (fd1
!= -1 && do_fstat(fd1
,&st
) != 0) {
417 rprintf(FERROR
, "fstat %s failed: %s\n",
418 full_fname(fnamecmp
), strerror(errno
));
419 receive_data(f_in
,NULL
,-1,NULL
,file
->length
);
424 if (fd1
!= -1 && S_ISDIR(st
.st_mode
) && fnamecmp
== fname
) {
425 /* this special handling for directories
426 * wouldn't be necessary if robust_rename()
427 * and the underlying robust_unlink could cope
430 rprintf(FERROR
,"recv_files: %s is a directory\n",
431 full_fname(fnamecmp
));
432 receive_data(f_in
, NULL
, -1, NULL
, file
->length
);
437 if (fd1
!= -1 && !S_ISREG(st
.st_mode
)) {
443 if (fd1
!= -1 && !preserve_perms
) {
444 /* if the file exists already and we aren't preserving
445 * permissions then act as though the remote end sent
446 * us the file permissions we already have */
447 file
->mode
= st
.st_mode
;
450 if (fd1
!= -1 && st
.st_size
> 0) {
451 buf
= map_file(fd1
,st
.st_size
);
453 rprintf(FINFO
,"recv mapped %s of size %.0f\n",fnamecmp
,(double)st
.st_size
);
458 if (!get_tmpname(fnametmp
,fname
)) {
459 if (buf
) unmap_file(buf
);
460 if (fd1
!= -1) close(fd1
);
464 strlcpy(template, fnametmp
, sizeof(template));
466 /* we initially set the perms without the
467 * setuid/setgid bits to ensure that there is no race
468 * condition. They are then correctly updated after
469 * the lchown. Thanks to snabb@epipe.fi for pointing
470 * this out. We also set it initially without group
471 * access because of a similar race condition. */
472 fd2
= do_mkstemp(fnametmp
, file
->mode
& INITACCESSPERMS
);
474 /* in most cases parent directories will already exist
475 * because their information should have been previously
476 * transferred, but that may not be the case with -R */
477 if (fd2
== -1 && relative_paths
&& errno
== ENOENT
&&
478 create_directory_path(fnametmp
, orig_umask
) == 0) {
479 strlcpy(fnametmp
, template, sizeof(fnametmp
));
480 fd2
= do_mkstemp(fnametmp
, file
->mode
& INITACCESSPERMS
);
483 rprintf(FERROR
, "mkstemp %s failed: %s\n",
484 full_fname(fnametmp
), strerror(errno
));
485 receive_data(f_in
,buf
,-1,NULL
,file
->length
);
486 if (buf
) unmap_file(buf
);
487 if (fd1
!= -1) close(fd1
);
491 cleanup_set(fnametmp
, fname
, file
, buf
, fd1
, fd2
);
493 if (!am_server
&& verbose
) { /* log transfer */
494 rprintf(FINFO
, "%s\n", fname
);
498 recv_ok
= receive_data(f_in
,buf
,fd2
,fname
,file
->length
);
500 log_recv(file
, &initial_stats
);
502 if (buf
) unmap_file(buf
);
509 rprintf(FINFO
,"renaming %s to %s\n",fnametmp
,fname
);
511 finish_transfer(fname
, fnametmp
, file
);
516 if (csum_length
== SUM_LENGTH
) {
517 rprintf(FERROR
,"ERROR: file corruption in %s. File changed during transfer?\n",
521 rprintf(FINFO
,"redoing %s(%d)\n",fname
,i
);
528 if (recurse
&& delete_mode
&& !local_name
&& flist
->count
>0) {
533 if (preserve_hard_links
)
536 /* now we need to fix any directory permissions that were
537 * modified during the transfer */
538 for (i
= 0; i
< flist
->count
; i
++) {
539 file
= flist
->files
[i
];
540 if (!file
->basename
|| !S_ISDIR(file
->mode
)) continue;
541 recv_generator(local_name
?local_name
:f_name(file
),flist
,i
,-1);
545 rprintf(FINFO
,"recv_files finished\n");