--- a/components/proftpd/patches/17599705.patch Fri Jul 25 13:25:28 2014 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,315 +0,0 @@
-http://bugs.proftpd.org/show_bug.cgi?id=4011
-
-diff --git a/include/fsio.h b/include/fsio.h
-index 07c18c1..a4c395e 100644
---- a/include/fsio.h
-+++ b/include/fsio.h
-@@ -189,6 +189,9 @@ struct fh_rec {
- size_t fh_iosz;
- };
-
-+/* Maximum symlink count, for loop detection. */
-+#define PR_FSIO_MAX_LINK_COUNT 32
-+
- /* Macros for that code that needs to get into the internals of pr_fs_t.
- * (These will help keep the internals as opaque as possible).
- */
-@@ -319,7 +322,11 @@ char *pr_fs_encode_path(pool *, const char *);
- int pr_fs_use_encoding(int bool);
- int pr_fs_valid_path(const char *);
- void pr_fs_virtual_path(const char *, char *, size_t);
-+
- void pr_fs_clean_path(const char *, char *, size_t);
-+int pr_fs_clean_path2(const char *, char *, size_t, int);
-+#define PR_FSIO_CLEAN_PATH_FL_MAKE_ABS_PATH 0x001
-+
- int pr_fs_glob(const char *, int, int (*errfunc)(const char *, int), glob_t *);
- void pr_fs_globfree(glob_t *);
- void pr_resolve_fs_map(void);
-diff --git a/modules/mod_ls.c b/modules/mod_ls.c
-index 50e8035..58e81d7 100644
---- a/modules/mod_ls.c
-+++ b/modules/mod_ls.c
-@@ -2571,46 +2571,6 @@ MODRET ls_nlst(cmd_rec *cmd) {
- }
- }
-
-- /* Clean the path. */
-- if (*target != '/') {
-- size_t cwdlen = strlen(pr_fs_getcwd());
--
-- pr_fs_clean_path(pdircat(cmd->tmp_pool, pr_fs_getcwd(), target, NULL),
-- buf, sizeof(buf));
--
-- target = buf;
--
-- /* If the given target was not an absolute path, advance past the
-- * current working directory prefix in the cleaned up target path.
-- */
-- target += cwdlen;
--
-- /* If the length of the current working directory (cwdlen) is one,
-- * it means that the current working directory is the root ('/'),
-- * and so we don't want to advance past that into the file name
-- * portion of the path.
-- */
-- if (cwdlen > 1)
-- target += 1;
--
-- } else {
-- pr_fs_clean_path(target, buf, sizeof(buf));
-- target = buf;
-- }
--
-- /* Remove any trailing separators. */
-- targetlen = strlen(target);
-- while (targetlen >= 1 &&
-- target[targetlen-1] == '/') {
--
-- if (strcmp(target, "/") == 0) {
-- break;
-- }
--
-- target[targetlen-1] = '\0';
-- targetlen = strlen(target);
-- }
--
- /* If the target is a glob, get the listing of files/dirs to send. */
- if (use_globbing &&
- pr_str_is_fnmatch(target)) {
-@@ -2715,12 +2675,36 @@ MODRET ls_nlst(cmd_rec *cmd) {
- }
-
- } else {
--
- /* A single target. If it's a directory, list the contents; if it's a
- * file, just list the file.
- */
- struct stat st;
-
-+ if (!is_dotdir(target)) {
-+ /* Clean the path. */
-+ if (*target != '/') {
-+ pr_fs_clean_path2(target, buf, sizeof(buf), 0);
-+
-+ } else {
-+ pr_fs_clean_path(target, buf, sizeof(buf));
-+ }
-+
-+ target = buf;
-+
-+ } else {
-+ /* Remove any trailing separators. */
-+ targetlen = strlen(target);
-+ while (targetlen >= 1 &&
-+ target[targetlen-1] == '/') {
-+ if (strncmp(target, "/", 2) == 0) {
-+ break;
-+ }
-+
-+ target[targetlen-1] = '\0';
-+ targetlen = strlen(target);
-+ }
-+ }
-+
- if (!ls_perms_full(cmd->tmp_pool, cmd, target, &hidden)) {
- int xerrno = errno;
-
-diff --git a/src/fsio.c b/src/fsio.c
-index 782168d..4d191fe 100644
---- a/src/fsio.c
-+++ b/src/fsio.c
-@@ -1627,8 +1627,8 @@ int pr_fs_resolve_partial(const char *path, char *buf, size_t buflen, int op) {
-
- pr_fs_t *fs = NULL;
- int len = 0, fini = 1, link_cnt = 0;
-- ino_t last_inode = 0;
-- dev_t last_device = 0;
-+ ino_t prev_inode = 0;
-+ dev_t prev_device = 0;
- struct stat sbuf;
-
- if (!path) {
-@@ -1740,16 +1740,16 @@ int pr_fs_resolve_partial(const char *path, char *buf, size_t buflen, int op) {
- char linkpath[PR_TUNABLE_PATH_MAX + 1] = {'\0'};
-
- /* Detect an obvious recursive symlink */
-- if (sbuf.st_ino && (ino_t) sbuf.st_ino == last_inode &&
-- sbuf.st_dev && (dev_t) sbuf.st_dev == last_device) {
-+ if (sbuf.st_ino && (ino_t) sbuf.st_ino == prev_inode &&
-+ sbuf.st_dev && (dev_t) sbuf.st_dev == prev_device) {
- errno = ELOOP;
- return -1;
- }
-
-- last_inode = (ino_t) sbuf.st_ino;
-- last_device = (dev_t) sbuf.st_dev;
-+ prev_inode = (ino_t) sbuf.st_ino;
-+ prev_device = (dev_t) sbuf.st_dev;
-
-- if (++link_cnt > 32) {
-+ if (++link_cnt > PR_FSIO_MAX_LINK_COUNT) {
- errno = ELOOP;
- return -1;
- }
-@@ -1820,8 +1820,8 @@ int pr_fs_resolve_path(const char *path, char *buf, size_t buflen, int op) {
- pr_fs_t *fs = NULL;
-
- int len = 0, fini = 1, link_cnt = 0;
-- ino_t last_inode = 0;
-- dev_t last_device = 0;
-+ ino_t prev_inode = 0;
-+ dev_t prev_device = 0;
- struct stat sbuf;
-
- if (!path) {
-@@ -1906,16 +1906,16 @@ int pr_fs_resolve_path(const char *path, char *buf, size_t buflen, int op) {
- char linkpath[PR_TUNABLE_PATH_MAX + 1] = {'\0'};
-
- /* Detect an obvious recursive symlink */
-- if (sbuf.st_ino && (ino_t) sbuf.st_ino == last_inode &&
-- sbuf.st_dev && (dev_t) sbuf.st_dev == last_device) {
-+ if (sbuf.st_ino && (ino_t) sbuf.st_ino == prev_inode &&
-+ sbuf.st_dev && (dev_t) sbuf.st_dev == prev_device) {
- errno = ELOOP;
- return -1;
- }
-
-- last_inode = (ino_t) sbuf.st_ino;
-- last_device = (dev_t) sbuf.st_dev;
-+ prev_inode = (ino_t) sbuf.st_ino;
-+ prev_device = (dev_t) sbuf.st_dev;
-
-- if (++link_cnt > 32) {
-+ if (++link_cnt > PR_FSIO_MAX_LINK_COUNT) {
- errno = ELOOP;
- return -1;
- }
-@@ -1977,22 +1977,33 @@ int pr_fs_resolve_path(const char *path, char *buf, size_t buflen, int op) {
- return 0;
- }
-
--void pr_fs_clean_path(const char *path, char *buf, size_t buflen) {
-+int pr_fs_clean_path2(const char *path, char *buf, size_t buflen, int flags) {
- char workpath[PR_TUNABLE_PATH_MAX + 1] = {'\0'};
- char curpath[PR_TUNABLE_PATH_MAX + 1] = {'\0'};
- char namebuf[PR_TUNABLE_PATH_MAX + 1] = {'\0'};
-- char *where = NULL, *ptr = NULL, *last = NULL;
-- int fini = 1;
-+ int fini = 1, have_abs_path = FALSE;
-
-- if (!path)
-- return;
-+ if (path == NULL ||
-+ buf == NULL) {
-+ errno = EINVAL;
-+ return -1;
-+ }
-+
-+ if (buflen == 0) {
-+ return 0;
-+ }
-
- sstrncpy(curpath, path, sizeof(curpath));
-
-+ if (*curpath == '/') {
-+ have_abs_path = TRUE;
-+ }
-+
- /* main loop */
- while (fini--) {
-- where = curpath;
-+ char *where = NULL, *ptr = NULL, *last = NULL;
-
-+ where = curpath;
- while (*where != '\0') {
- pr_signals_handle();
-
-@@ -2013,8 +2024,12 @@ void pr_fs_clean_path(const char *path, char *buf, size_t buflen) {
- ptr = last = workpath;
-
- while (*ptr) {
-- if (*ptr == '/')
-+ pr_signals_handle();
-+
-+ if (*ptr == '/') {
- last = ptr;
-+ }
-+
- ptr++;
- }
-
-@@ -2028,34 +2043,46 @@ void pr_fs_clean_path(const char *path, char *buf, size_t buflen) {
- ptr = last = workpath;
-
- while (*ptr) {
-- if (*ptr == '/')
-+ pr_signals_handle();
-+
-+ if (*ptr == '/') {
- last = ptr;
-+ }
- ptr++;
- }
-+
- *last = '\0';
- continue;
- }
-- ptr = strchr(where, '/');
-
-- if (!ptr) {
-+ ptr = strchr(where, '/');
-+ if (ptr == NULL) {
- size_t wherelen = strlen(where);
-
- ptr = where;
-- if (wherelen >= 1)
-+ if (wherelen >= 1) {
- ptr += (wherelen - 1);
-+ }
-
-- } else
-+ } else {
- *ptr = '\0';
-+ }
-
- sstrncpy(namebuf, workpath, sizeof(namebuf));
-
- if (*namebuf) {
- for (last = namebuf; *last; last++);
-- if (*--last != '/')
-+ if (*--last != '/') {
- sstrcat(namebuf, "/", sizeof(namebuf)-1);
-+ }
-
-- } else
-- sstrcat(namebuf, "/", sizeof(namebuf)-1);
-+ } else {
-+ if (have_abs_path ||
-+ (flags & PR_FSIO_CLEAN_PATH_FL_MAKE_ABS_PATH)) {
-+ sstrcat(namebuf, "/", sizeof(namebuf)-1);
-+ have_abs_path = FALSE;
-+ }
-+ }
-
- sstrcat(namebuf, where, sizeof(namebuf)-1);
- namebuf[sizeof(namebuf)-1] = '\0';
-@@ -2066,10 +2093,16 @@ void pr_fs_clean_path(const char *path, char *buf, size_t buflen) {
- }
- }
-
-- if (!workpath[0])
-+ if (!workpath[0]) {
- sstrncpy(workpath, "/", sizeof(workpath));
-+ }
-
- sstrncpy(buf, workpath, buflen);
-+ return 0;
-+}
-+
-+void pr_fs_clean_path(const char *path, char *buf, size_t buflen) {
-+ pr_fs_clean_path2(path, buf, buflen, PR_FSIO_CLEAN_PATH_FL_MAKE_ABS_PATH);
- }
-
- int pr_fs_use_encoding(int bool) {
-