diff options
author | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2016-02-28 01:52:11 +0100 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2016-02-28 01:56:11 +0100 |
commit | 6e8e837864d4e24c2fdb4d90e8eb262ded78c3a8 (patch) | |
tree | 47022b7fe9e8344ad1c1765e15122067072f0fba | |
parent | eeeb27ee14064dff84c833b4359d43d9869a9342 (diff) |
Fix mustbedir mechanism for symlinks
* libdiskfs/dir-lookup.c (diskfs_S_dir_lookup): When following a symlink,
if mustbedir is true, always append a slash to the symlink target, not only
when the target is absolute. Reset mustbedir to 0 before continuing the
lookup loop.
* libnetfs/dir-lookup.c (netfs_S_dir_lookup): When following a symlink,
if mustbedir is true, append a slash to the symlink target. Reset mustbedir
to 0 before continuing the lookup loop.
* libtreefs/dir-lookup.c (_treefs_s_dir_lookup): Likewise.
-rw-r--r-- | libdiskfs/dir-lookup.c | 17 | ||||
-rw-r--r-- | libnetfs/dir-lookup.c | 11 | ||||
-rw-r--r-- | libtreefs/dir-lookup.c | 11 |
3 files changed, 27 insertions, 12 deletions
diff --git a/libdiskfs/dir-lookup.c b/libdiskfs/dir-lookup.c index 8b986e49..c50970d2 100644 --- a/libdiskfs/dir-lookup.c +++ b/libdiskfs/dir-lookup.c @@ -421,24 +421,25 @@ diskfs_S_dir_lookup (struct protid *dircred, memcpy (pathbuf + np->dn_stat.st_size + 1, nextname, nextnamelen - 1); } - pathbuf[nextnamelen + np->dn_stat.st_size] = '\0'; + if (mustbedir) + { + pathbuf[nextnamelen + np->dn_stat.st_size] = '/'; + pathbuf[nextnamelen + np->dn_stat.st_size + 1] = '\0'; + } + else + pathbuf[nextnamelen + np->dn_stat.st_size] = '\0'; if (pathbuf[0] == '/') { /* Punt to the caller. */ *retry = FS_RETRY_MAGICAL; *returned_port = MACH_PORT_NULL; - memcpy (retryname, pathbuf, - nextnamelen + np->dn_stat.st_size + 1); - if (mustbedir) - { - retryname[nextnamelen + np->dn_stat.st_size] = '/'; - retryname[nextnamelen + np->dn_stat.st_size + 1] = '\0'; - } + strcpy (retryname, pathbuf); goto out; } path = pathbuf; + mustbedir = 0; } if (lastcomp) diff --git a/libnetfs/dir-lookup.c b/libnetfs/dir-lookup.c index 1fefd3ff..cbe29419 100644 --- a/libnetfs/dir-lookup.c +++ b/libnetfs/dir-lookup.c @@ -367,7 +367,7 @@ netfs_S_dir_lookup (struct protid *diruser, linklen = np->nn_stat.st_size; nextnamelen = nextname ? strlen (nextname) + 1 : 0; - newnamelen = nextnamelen + linklen + 1; + newnamelen = nextnamelen + linklen + 1 + 1; linkbuf = alloca (newnamelen); error = netfs_attempt_readlink (diruser->user, np, linkbuf); @@ -380,7 +380,13 @@ netfs_S_dir_lookup (struct protid *diruser, memcpy (linkbuf + linklen + 1, nextname, nextnamelen - 1); } - linkbuf[nextnamelen + linklen] = '\0'; + if (mustbedir) + { + linkbuf[nextnamelen + linklen] = '/'; + linkbuf[nextnamelen + linklen + 1] = '\0'; + } + else + linkbuf[nextnamelen + linklen] = '\0'; if (linkbuf[0] == '/') { @@ -392,6 +398,7 @@ netfs_S_dir_lookup (struct protid *diruser, } filename = linkbuf; + mustbedir = 0; if (lastcomp) { lastcomp = 0; diff --git a/libtreefs/dir-lookup.c b/libtreefs/dir-lookup.c index 8665059c..80b55388 100644 --- a/libtreefs/dir-lookup.c +++ b/libtreefs/dir-lookup.c @@ -229,7 +229,7 @@ _treefs_s_dir_lookup (struct treefs_handle *h, /* Symlink contents + extra path won't fit in our buffer, so reallocate it and try again. */ { - path_buf_len = sym_len + nextname_len + 1; + path_buf_len = sym_len + nextname_len + 1 + 1; path_buf = alloca (path_buf_len); err = treefs_node_get_symlink (node, path_buf, &sym_len); } @@ -241,7 +241,13 @@ _treefs_s_dir_lookup (struct treefs_handle *h, path_buf[sym_len] = '/'; bcopy (nextname, path_buf + sym_len + 1, nextname_len - 1); } - path_buf[nextname_len + sym_len] = '\0'; + if (mustbedir) + { + path_buf[nextnamelen + sym_len] = '/'; + path_buf[nextnamelen + sym_len + 1] = '\0'; + } + else + path_buf[nextname_len + sym_len] = '\0'; if (path_buf[0] == '/') { @@ -253,6 +259,7 @@ _treefs_s_dir_lookup (struct treefs_handle *h, } path = path_buf; + mustbedir = 0; if (lastcomp) { lastcomp = 0; |