X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/4875d6b64dd0ed8d451746cc0cc609cff36192bd..bec617b934dc2ef90b7acd1c7ef4b5db74821e91:/backup.c diff --git a/backup.c b/backup.c index 1db011ce..7d288858 100644 --- a/backup.c +++ b/backup.c @@ -55,23 +55,37 @@ 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", - safe_fname(fname), safe_fname(fnamebak)); - return 0; + while (1) { + if (do_rename(fname, fnamebak) == 0) { + if (verbose > 1) { + rprintf(FINFO, "backed up %s to %s\n", + safe_fname(fname), + safe_fname(fnamebak)); + } + break; } - } else if (verbose > 1) { - rprintf(FINFO, "backed up %s to %s\n", + /* 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", safe_fname(fname), safe_fname(fnamebak)); + errno = rename_errno; + return 0; } + return 1; } @@ -174,18 +188,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", - safe_fname(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", + safe_fname(fname)); } kept = 1; do_unlink(fname); @@ -208,7 +220,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) { @@ -216,15 +228,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), + safe_fname(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), safe_fname(file->u.link)); - } - do_unlink(fname); - kept = 1; } #endif