diff options
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | NEWS | 7 | ||||
-rw-r--r-- | src/diskio.c | 40 |
3 files changed, 47 insertions, 6 deletions
@@ -1,3 +1,9 @@ +2009-01-17 Sergey Poznyakoff <gray@gnu.org.ua> + + * src/diskio.c (symlink_file): Silently remove existing symlink + target. + * NEWS: Update. + 2008-09-03 Sergey Poznyakoff <gray@gnu.org.ua> * configure.ac, NEWS: Version 1.0.90 @@ -1,4 +1,4 @@ -Wydawca NEWS -- history of user-visible changes. 2008-09-03 +Wydawca NEWS -- history of user-visible changes. 2009-01-17 Copyright (C) 2007, 2008 Sergey Poznyakoff See the end of file for copying conditions. @@ -9,6 +9,11 @@ Version 1.0.90, (SVN) * Log detailed statistics only if at least one counter is not zero. +* Handling of the `symlink' directive. + +If the symlink target exists, it is silently removed and the new link +is created. This behavior is compatible with that of ftp.gnu.org. + Version 1.0, 2008-08-23 diff --git a/src/diskio.c b/src/diskio.c index 43191bb..85389cb 100644 --- a/src/diskio.c +++ b/src/diskio.c @@ -585,11 +585,41 @@ symlink_file (struct file_triplet *trp, struct directory_pair *dpair, dst_dir, strerror (errno)); else { - rc = symlink (src, dst); - if (rc) - logmsg (LOG_ERR, - "symlinking %s to %s in directory %s failed: %s", - src, dst, dst_dir, strerror (errno)); + struct stat st; + + if (lstat (dst, &st) == 0) + { + if (!S_ISLNK (st.st_mode)) + { + logmsg (LOG_ERR, + "file %s exists and is not a symbolic link", + dst, strerror (errno)); + rc = 1; + } + else if (unlink (dst)) + { + logmsg (LOG_ERR, + "Cannot unlink %s: %s", + dst, strerror (errno)); + rc = 1; + } + } + else if (errno != ENOENT) + { + logmsg (LOG_ERR, + "cannot stat file %s: %s", + dst, strerror (errno)); + rc = 1; + } + + if (rc == 0) + { + rc = symlink (src, dst); + if (rc) + logmsg (LOG_ERR, + "symlinking %s to %s in directory %s failed: %s", + src, dst, dst_dir, strerror (errno)); + } } } } |