diff --git libpkg/repo/binary/fetch.c libpkg/repo/binary/fetch.c index b7f2569..5e22f21 100644 --- libpkg/repo/binary/fetch.c +++ libpkg/repo/binary/fetch.c @@ -94,36 +94,32 @@ static int pkg_repo_binary_create_symlink(struct pkg *pkg, const char *fname, const char *dir) { - struct stat st; const char *ext, *dest_fname; - char link_dest[MAXPATHLEN]; - + char link_dest_tmp[MAXPATHLEN], link_dest[MAXPATHLEN]; /* Create symlink from full pkgname */ ext = strrchr(fname, '.'); pkg_snprintf(link_dest, sizeof(link_dest), "%S/%n-%v%S", dir, pkg, pkg, ext ? ext : ""); - if (stat(link_dest, &st) != -1) { - /* We already have this path, check for symlink */ - if (S_ISLNK(st.st_mode)) { - /* We can safely remove symlink */ - if (unlink(link_dest) == -1) { - pkg_emit_errno("unlink", link_dest); - return (EPKG_FATAL); - } - } - /* Do not touch anything but symlinks */ - return (EPKG_END); - } + snprintf(link_dest_tmp, sizeof(link_dest_tmp), "%s.new", link_dest); + + /* Ignore errors here */ + (void)unlink(link_dest_tmp); /* Trim the path to just the filename. */ if ((dest_fname = strrchr(fname, '/')) != NULL) ++dest_fname; - if (symlink(dest_fname, link_dest) == -1) { + if (symlink(dest_fname, link_dest_tmp) == -1) { pkg_emit_errno("symlink", link_dest); return (EPKG_FATAL); } + if (rename(link_dest_tmp, link_dest) == -1) { + pkg_emit_errno("rename", link_dest); + unlink(link_dest_tmp); + return (EPKG_FATAL); + } + return (EPKG_OK); }