| |
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);
|
| |
}
|
| |
|