diff -urp rpm-4.2.orig/lib/fsm.c rpm-4.2/lib/fsm.c --- rpm-4.2.orig/lib/fsm.c 2003-03-03 19:38:32 +0000 +++ rpm-4.2/lib/fsm.c 2011-07-25 01:31:24 +0000 @@ -1990,26 +1990,54 @@ if (!(fsm->mapFlags & CPIO_ALL_HARDLINKS /*@notreached@*/ break; case FSM_UNLINK: - rc = Unlink(fsm->path); + { + struct stat stb; + int saved_errno; + int saved_rc = lstat(fsm->path, &stb); + if (!saved_rc && !S_ISLNK(stb.st_mode)) + saved_rc = chmod(fsm->path, 0); + saved_errno = errno; + if (saved_rc && saved_errno == ENOENT) + saved_rc = 0; + rc = Unlink(fsm->path); + if (!rc && saved_rc) { + rc = saved_rc; + errno = saved_errno; + } + } if (_fsm_debug && (stage & FSM_SYSCALL)) rpmMessage(RPMMESS_DEBUG, " %8s (%s) %s\n", cur, fsm->path, (rc < 0 ? strerror(errno) : "")); if (rc < 0) rc = CPIOERR_UNLINK_FAILED; break; case FSM_RENAME: - rc = Rename(fsm->opath, fsm->path); + { + struct stat stb; + int saved_errno; + int saved_rc = lstat(fsm->path, &stb); + if (!saved_rc && !S_ISLNK(stb.st_mode)) + saved_rc = chmod(fsm->path, 0); + saved_errno = errno; + if (saved_rc && saved_errno == ENOENT) + saved_rc = 0; + rc = Rename(fsm->opath, fsm->path); #if defined(ETXTBSY) - if (rc && errno == ETXTBSY) { - char * path = alloca(strlen(fsm->path) + sizeof("-RPMDELETE")); - (void) stpcpy( stpcpy(path, fsm->path), "-RPMDELETE"); - /* - * XXX HP-UX (and other os'es) don't permit rename to busy - * XXX files. - */ - rc = Rename(fsm->path, path); - if (!rc) rc = Rename(fsm->opath, fsm->path); - } + if (rc && errno == ETXTBSY) { + char * path = alloca(strlen(fsm->path) + sizeof("-RPMDELETE")); + (void) stpcpy( stpcpy(path, fsm->path), "-RPMDELETE"); + /* + * XXX HP-UX (and other os'es) don't permit rename to busy + * XXX files. + */ + rc = Rename(fsm->path, path); + if (!rc) rc = Rename(fsm->opath, fsm->path); + } #endif + if (!rc && saved_rc) { + rc = saved_rc; + errno = saved_errno; + } + } if (_fsm_debug && (stage & FSM_SYSCALL)) rpmMessage(RPMMESS_DEBUG, " %8s (%s, %s) %s\n", cur, fsm->opath, fsm->path, (rc < 0 ? strerror(errno) : ""));