summaryrefslogtreecommitdiffstats
path: root/utils/mountd/rmtab.c
diff options
context:
space:
mode:
authorhjl <hjl>2002-10-15 16:21:06 +0000
committerhjl <hjl>2002-10-15 16:21:06 +0000
commite85f72300043f96e3f352d9c8f93243d4d0a52dc (patch)
tree794e9143a49fdd937662a7f62410764f0957f0cd /utils/mountd/rmtab.c
parent0036a143c415eac6388d992a4e637e7004147296 (diff)
downloadnfs-utils-e85f72300043f96e3f352d9c8f93243d4d0a52dc.tar.gz
nfs-utils-e85f72300043f96e3f352d9c8f93243d4d0a52dc.tar.xz
nfs-utils-e85f72300043f96e3f352d9c8f93243d4d0a52dc.zip
2002-10-15 Juan Gomez <juang@us.ibm.com>
* utils/mountd/rmtab.c (slink_safe_rename): New. Support symlink. (mountlist_add): Call slink_safe_rename instead of rename.
Diffstat (limited to 'utils/mountd/rmtab.c')
-rw-r--r--utils/mountd/rmtab.c40
1 files changed, 38 insertions, 2 deletions
diff --git a/utils/mountd/rmtab.c b/utils/mountd/rmtab.c
index 170d859..0a4ed4c 100644
--- a/utils/mountd/rmtab.c
+++ b/utils/mountd/rmtab.c
@@ -8,7 +8,9 @@
#include "config.h"
+#include <sys/types.h>
#include <sys/stat.h>
+#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
@@ -18,6 +20,40 @@
#include "xio.h"
#include "mountd.h"
+#include <limits.h> /* PATH_MAX */
+
+/* If new path is a link do not destroy it but place the
+ * file where the link points.
+ */
+
+static int
+slink_safe_rename(const char * oldpath, const char * newpath)
+{
+ int r;
+ struct stat s;
+ char slink_path[PATH_MAX];
+ char real_newpath = newpath;
+
+ if((lstat(newpath, &s) == 0) && (S_ISLNK(s.st_mode))) {
+
+ /* New path is a symbolic link, do not destroy but follow */
+
+ if((r = readlink(newpath, slink_path, PATH_MAX))==-1) {
+
+ return -1;
+
+ }
+
+ slink_path[ (r < PATH_MAX) ? (r + 1) : (PATH_MAX - 1)] = '\0';
+
+ real_newpath = slink_path;
+
+ }
+
+ return rename(oldpath, real_newpath);
+
+}/* static int slink_safe_rename() */
+
void
mountlist_add(nfs_export *exp, const char *path)
{
@@ -82,7 +118,7 @@ mountlist_del(nfs_export *exp, const char *path)
if (!match || rep->r_count)
fputrmtabent(fp, rep, NULL);
}
- if (rename(_PATH_RMTABTMP, _PATH_RMTAB) < 0) {
+ if (slink_safe_rename(_PATH_RMTABTMP, _PATH_RMTAB) < 0) {
xlog(L_ERROR, "couldn't rename %s to %s",
_PATH_RMTABTMP, _PATH_RMTAB);
}
@@ -130,7 +166,7 @@ mountlist_del_all(struct sockaddr_in *sin)
}
fputrmtabent(fp, rep, NULL);
}
- if (rename(_PATH_RMTABTMP, _PATH_RMTAB) < 0) {
+ if (slink_safe_rename(_PATH_RMTABTMP, _PATH_RMTAB) < 0) {
xlog(L_ERROR, "couldn't rename %s to %s",
_PATH_RMTABTMP, _PATH_RMTAB);
}