X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/7842418b7b87c4c78ad8ad06fec44150c8aa0956..45c49b52a488882bbbd5366420389abbbeede7c9:/backup.c diff --git a/backup.c b/backup.c index 689bfad5..e34b7be9 100644 --- a/backup.c +++ b/backup.c @@ -55,21 +55,36 @@ char *get_backup_name(char *fname) /* simple backup creates a backup with a suffix in the same directory */ static int make_simple_backup(char *fname) { + int rename_errno; char *fnamebak = get_backup_name(fname); if (!fnamebak) return 0; - if (do_rename(fname, fnamebak) != 0) { - /* cygwin (at least version b19) reports EINVAL */ - if (errno != ENOENT && errno != EINVAL) { - rsyserr(FERROR, errno, - "rename %s to backup %s", fname, fnamebak); - return 0; + while (1) { + if (do_rename(fname, fnamebak) == 0) { + if (verbose > 1) { + rprintf(FINFO, "backed up %s to %s\n", + fname, fnamebak); + } + break; } - } else if (verbose > 1) { - rprintf(FINFO, "backed up %s to %s\n", fname, fnamebak); + /* cygwin (at least version b19) reports EINVAL */ + if (errno == ENOENT || errno == EINVAL) + break; + + rename_errno = errno; + if (errno == EISDIR && do_rmdir(fnamebak) == 0) + continue; + if (errno == ENOTDIR && do_unlink(fnamebak) == 0) + continue; + + rsyserr(FERROR, rename_errno, "rename %s to backup %s", + fname, fnamebak); + errno = rename_errno; + return 0; } + return 1; } @@ -133,7 +148,7 @@ static int make_bak_dir(char *fullpath) } return 0; -failure: + failure: while (p != end) { *p = '/'; p += strlen(p); @@ -172,18 +187,16 @@ static int keep_backup(char *fname) return 0; /* Check to see if this is a device file, or link */ - if (IS_DEVICE(file->mode)) { - if (am_root && preserve_devices) { - if (do_mknod(buf, file->mode, file->u.rdev) < 0 - && (errno != ENOENT || make_bak_dir(buf) < 0 - || do_mknod(buf, file->mode, file->u.rdev) < 0)) { - rsyserr(FERROR, errno, "mknod %s failed", - full_fname(buf)); - } else if (verbose > 2) { - rprintf(FINFO, - "make_backup: DEVICE %s successful.\n", - fname); - } + if (IS_DEVICE(file->mode) && am_root && preserve_devices) { + do_unlink(buf); + if (do_mknod(buf, file->mode, file->u.rdev) < 0 + && (errno != ENOENT || make_bak_dir(buf) < 0 + || do_mknod(buf, file->mode, file->u.rdev) < 0)) { + rsyserr(FERROR, errno, "mknod %s failed", + full_fname(buf)); + } else if (verbose > 2) { + rprintf(FINFO, "make_backup: DEVICE %s successful.\n", + fname); } kept = 1; do_unlink(fname); @@ -206,7 +219,7 @@ static int keep_backup(char *fname) kept = 1; } -#if SUPPORT_LINKS +#ifdef SUPPORT_LINKS if (!kept && preserve_links && S_ISLNK(file->mode)) { if (safe_symlinks && unsafe_symlink(file->u.link, buf)) { if (verbose) { @@ -214,15 +227,18 @@ static int keep_backup(char *fname) full_fname(buf), file->u.link); } kept = 1; + } else { + do_unlink(buf); + if (do_symlink(file->u.link, buf) < 0 + && (errno != ENOENT || make_bak_dir(buf) < 0 + || do_symlink(file->u.link, buf) < 0)) { + rsyserr(FERROR, errno, "link %s -> \"%s\"", + full_fname(buf), + file->u.link); + } + do_unlink(fname); + kept = 1; } - if (do_symlink(file->u.link, buf) < 0 - && (errno != ENOENT || make_bak_dir(buf) < 0 - || do_symlink(file->u.link, buf) < 0)) { - rsyserr(FERROR, errno, "link %s -> \"%s\"", - full_fname(buf), file->u.link); - } - do_unlink(fname); - kept = 1; } #endif @@ -246,8 +262,10 @@ static int keep_backup(char *fname) set_perms(buf, file, NULL, 0); free(file); - if (verbose > 1) - rprintf(FINFO, "backed up %s to %s\n", fname, buf); + if (verbose > 1) { + rprintf(FINFO, "backed up %s to %s\n", + fname, buf); + } return 1; }