extern int verbose;
extern int recurse;
extern int delete_mode;
-extern int remote_version;
+extern int protocol_version;
extern int csum_length;
extern struct stats stats;
extern int dry_run;
extern char *tmpdir;
extern char *compare_dest;
extern int make_backups;
+extern int do_progress;
+extern char *backup_dir;
extern char *backup_suffix;
+extern int backup_suffix_len;
static struct delete_list {
DEV64_T dev;
for (i=0;i<dlist_len;i++) {
if (st.st_ino == delete_list[i].inode &&
- st.st_dev == delete_list[i].dev)
+ (DEV64_T)st.st_dev == delete_list[i].dev)
return 1;
}
{
if (dlist_len == dlist_alloc_len) {
dlist_alloc_len += 1024;
- delete_list = (struct delete_list *)Realloc(delete_list, sizeof(delete_list[0])*dlist_alloc_len);
+ delete_list = realloc_array(delete_list, struct delete_list,
+ dlist_alloc_len);
if (!delete_list) out_of_memory("add_delete_entry");
}
rprintf(FINFO,"added %s to delete list\n", f_name(file));
}
-static void delete_one(struct file_struct *f)
+static void delete_one(char *fn, int is_dir)
{
- if (!S_ISDIR(f->mode)) {
- if (robust_unlink(f_name(f)) != 0) {
- rprintf(FERROR,"delete_one: unlink %s: %s\n",f_name(f),strerror(errno));
+ if (!is_dir) {
+ if (robust_unlink(fn) != 0) {
+ rprintf(FERROR, "delete_one: unlink %s failed: %s\n",
+ full_fname(fn), strerror(errno));
} else if (verbose) {
- rprintf(FINFO,"deleting %s\n",f_name(f));
+ rprintf(FINFO, "deleting %s\n", fn);
}
} else {
- if (do_rmdir(f_name(f)) != 0) {
- if (errno != ENOTEMPTY && errno != EEXIST)
- rprintf(FERROR,"delete_one: rmdir %s: %s\n",
- f_name(f), strerror(errno));
+ if (do_rmdir(fn) != 0) {
+ if (errno != ENOTEMPTY && errno != EEXIST) {
+ rprintf(FERROR, "delete_one: rmdir %s failed: %s\n",
+ full_fname(fn), strerror(errno));
+ }
} else if (verbose) {
- rprintf(FINFO,"deleting directory %s\n",f_name(f));
+ rprintf(FINFO, "deleting directory %s\n", fn);
}
}
}
+static int is_backup_file(char *fn)
+{
+ int k = strlen(fn) - backup_suffix_len;
+ return k > 0 && strcmp(fn+k, backup_suffix) == 0;
+}
/* this deletes any files on the receiving side that are not present
if (!S_ISDIR(flist->files[j]->mode) ||
!(flist->files[j]->flags & FLAG_DELETE)) continue;
- if (remote_version < 19 &&
+ if (protocol_version < 19 &&
delete_already_done(flist, j)) continue;
name = strdup(f_name(flist->files[j]));
for (i=local_file_list->count-1;i>=0;i--) {
if (max_delete && deletion_count > max_delete) break;
if (!local_file_list->files[i]->basename) continue;
- if (remote_version < 19 &&
+ if (protocol_version < 19 &&
S_ISDIR(local_file_list->files[i]->mode))
add_delete_entry(local_file_list->files[i]);
if (-1 == flist_find(flist,local_file_list->files[i])) {
char *f = f_name(local_file_list->files[i]);
- int k = strlen(f) - strlen(backup_suffix);
-/* Hi Andrew, do we really need to play with backup_suffix here? */
- if (make_backups && ((k <= 0) ||
- (strcmp(f+k,backup_suffix) != 0))) {
+ if (make_backups && (backup_dir || !is_backup_file(f))) {
(void) make_backup(f);
+ if (verbose)
+ rprintf(FINFO, "deleting %s\n", f);
} else {
- deletion_count++;
- delete_one(local_file_list->files[i]);
+ int mode = local_file_list->files[i]->mode;
+ delete_one(f, S_ISDIR(mode) != 0);
}
+ deletion_count++;
}
}
flist_free(local_file_list);
length = strlen(fnametmp);
fnametmp[length++] = '/';
fnametmp[length] = '\0'; /* always NULL terminated */
- }
+ }
- if ((f = strrchr(fname, '/'))) { /* extra () for gcc */
+ if ((f = strrchr(fname, '/')) != NULL) {
++f;
if (!tmpdir) {
length = f - fname;
+ /* copy up to and including the slash */
strlcpy(fnametmp, fname, length + 1);
- } /* copy up to and including the slash */
+ }
} else {
f = fname;
}
maxname = MIN(MAXPATHLEN - 7 - length, NAME_MAX - 8);
- if (maxname < 1)
- {
+ if (maxname < 1) {
rprintf(FERROR, "temporary filename too long: %s\n", fname);
fnametmp[0] = '\0';
return 0;
sum_init();
for (i=recv_token(f_in,&data); i != 0; i=recv_token(f_in,&data)) {
-
- show_progress(offset, total_size);
+ if (do_progress)
+ show_progress(offset, total_size);
if (i > 0) {
extern int cleanup_got_literal;
sum_update(data,i);
if (fd != -1 && write_file(fd,data,i) != i) {
- rprintf(FERROR,"write failed on %s : %s\n",fname,strerror(errno));
+ rprintf(FERROR, "write failed on %s: %s\n",
+ full_fname(fname), strerror(errno));
exit_cleanup(RERR_FILEIO);
}
offset += i;
}
if (fd != -1 && write_file(fd,map,len) != (int) len) {
- rprintf(FERROR,"write failed on %s : %s\n",
- fname,strerror(errno));
+ rprintf(FERROR, "write failed on %s: %s\n",
+ full_fname(fname), strerror(errno));
exit_cleanup(RERR_FILEIO);
}
offset += len;
}
- end_progress(total_size);
+ if (do_progress)
+ end_progress(total_size);
if (fd != -1 && offset > 0 && sparse_end(fd) != 0) {
- rprintf(FERROR,"write failed on %s : %s\n",
- fname,strerror(errno));
+ rprintf(FERROR, "write failed on %s: %s\n",
+ full_fname(fname), strerror(errno));
exit_cleanup(RERR_FILEIO);
}
}
if (fd1 != -1 && do_fstat(fd1,&st) != 0) {
- rprintf(FERROR,"fstat %s : %s\n",fnamecmp,strerror(errno));
+ rprintf(FERROR, "fstat %s failed: %s\n",
+ full_fname(fnamecmp), strerror(errno));
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",fnamecmp);
- receive_data(f_in,NULL,-1,NULL,file->length);
+ if (fd1 != -1 && S_ISDIR(st.st_mode) && fnamecmp == fname) {
+ /* this special handling for directories
+ * wouldn't be necessary if robust_rename()
+ * and the underlying robust_unlink could cope
+ * with directories
+ */
+ rprintf(FERROR,"recv_files: %s is a directory\n",
+ full_fname(fnamecmp));
+ receive_data(f_in, NULL, -1, NULL, file->length);
close(fd1);
continue;
}
+ if (fd1 != -1 && !S_ISREG(st.st_mode)) {
+ close(fd1);
+ fd1 = -1;
+ buf = NULL;
+ }
+
if (fd1 != -1 && !preserve_perms) {
/* if the file exists already and we aren't preserving
permissions then act as though the remote end sent
fd2 = do_mkstemp(fnametmp, file->mode & INITACCESSPERMS);
}
if (fd2 == -1) {
- rprintf(FERROR,"mkstemp %s failed: %s\n",fnametmp,strerror(errno));
+ rprintf(FERROR, "mkstemp %s failed: %s\n",
+ full_fname(fnametmp), strerror(errno));
receive_data(f_in,buf,-1,NULL,file->length);
if (buf) unmap_file(buf);
if (fd1 != -1) close(fd1);
if (!recv_ok) {
if (csum_length == SUM_LENGTH) {
rprintf(FERROR,"ERROR: file corruption in %s. File changed during transfer?\n",
- fname);
+ full_fname(fname));
} else {
if (verbose > 1)
rprintf(FINFO,"redoing %s(%d)\n",fname,i);