Merge branch '1828_ftpfs_improved_symlink_handling'

* 1828_ftpfs_improved_symlink_handling:
  Ticket #1828: Improved symlink handling in ftpfs
This commit is contained in:
Slava Zanko 2009-12-25 15:54:43 +02:00
commit e8b41315ac
3 changed files with 114 additions and 87 deletions

View File

@ -146,6 +146,17 @@ extern struct sigaction startup_handler;
char *tilde_expand (const char *);
/* Pathname canonicalization */
typedef enum {
CANON_PATH_JOINSLASHES = 1L<<0, /* Multiple `/'s are collapsed to a single `/'. */
CANON_PATH_REMSLASHDOTS = 1L<<1, /* Leading `./'s, `/'s and trailing `/.'s are removed. */
CANON_PATH_REMDOUBLEDOTS = 1L<<3, /* Non-leading `../'s and trailing `..'s are handled by removing */
CANON_PATH_GUARDUNC = 1L<<4, /* Detect and preserve UNC paths: //server/... */
CANON_PATH_ALL = CANON_PATH_JOINSLASHES
| CANON_PATH_REMSLASHDOTS
| CANON_PATH_REMDOUBLEDOTS
| CANON_PATH_GUARDUNC
} CANON_PATH_FLAGS;
void custom_canonicalize_pathname (char *, CANON_PATH_FLAGS);
void canonicalize_pathname (char *);
/* Misc Unix functions */

View File

@ -457,14 +457,14 @@ close_error_pipe (int error, const char *text)
* Well formed UNC paths are modified only in the local part.
*/
void
canonicalize_pathname (char *path)
custom_canonicalize_pathname (char *path, CANON_PATH_FLAGS flags)
{
char *p, *s;
int len;
char *lpath = path; /* path without leading UNC part */
/* Detect and preserve UNC paths: //server/... */
if (path[0] == PATH_SEP && path[1] == PATH_SEP) {
if ( ( flags & CANON_PATH_GUARDUNC ) && path[0] == PATH_SEP && path[1] == PATH_SEP) {
p = path + 2;
while (p[0] && p[0] != '/')
p++;
@ -475,6 +475,7 @@ canonicalize_pathname (char *path)
if (!lpath[0] || !lpath[1])
return;
if ( flags & CANON_PATH_JOINSLASHES ) {
/* Collapse multiple slashes */
p = lpath;
while (*p) {
@ -485,7 +486,9 @@ canonicalize_pathname (char *path)
}
p++;
}
}
if ( flags & CANON_PATH_JOINSLASHES ) {
/* Collapse "/./" -> "/" */
p = lpath;
while (*p) {
@ -494,7 +497,9 @@ canonicalize_pathname (char *path)
else
p++;
}
}
if ( flags & CANON_PATH_REMSLASHDOTS ) {
/* Remove trailing slashes */
p = lpath + strlen (lpath) - 1;
while (p > lpath && *p == PATH_SEP)
@ -526,7 +531,9 @@ canonicalize_pathname (char *path)
}
}
}
}
if ( flags & CANON_PATH_REMDOUBLEDOTS ) {
/* Collapse "/.." with the previous part of path */
p = lpath;
while (p[0] && p[1] && p[2]) {
@ -579,6 +586,13 @@ canonicalize_pathname (char *path)
break;
}
}
}
void
canonicalize_pathname (char *path)
{
custom_canonicalize_pathname (path, CANON_PATH_ALL);
}
#ifdef HAVE_GET_PROCESS_STATS

View File

@ -263,7 +263,8 @@ vfs_s_find_entry_tree (struct vfs_class *me, struct vfs_s_inode *root,
char * const pathref = g_strdup (a_path);
char *path = pathref;
canonicalize_pathname (path);
/* canonicalize as well, but don't remove '../' from path */
custom_canonicalize_pathname (path, CANON_PATH_ALL & (~CANON_PATH_RMDBLDT));
while (root) {
while (*path == PATH_SEP) /* Strip leading '/' */
@ -336,7 +337,8 @@ vfs_s_find_entry_linear (struct vfs_class *me, struct vfs_s_inode *root,
if (root->super->root != root)
vfs_die ("We have to use _real_ root. Always. Sorry.");
canonicalize_pathname (path);
/* canonicalize as well, but don't remove '../' from path */
custom_canonicalize_pathname (path, CANON_PATH_ALL & (~CANON_PATH_RMDBLDT));
if (!(flags & FL_DIR)) {
char *dirname, *name, *save;