--- Makefile | 1 + libutil/realpathm.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 104 insertions(+) create mode 100644 libutil/realpathm.c diff --git a/Makefile b/Makefile index c2d8266..c4ca41d 100644 --- a/Makefile +++ b/Makefile _AT_@ -59,6 +59,7 @@ LIBUTILSRC =\ libutil/parseoffset.c\ libutil/putword.c\ libutil/reallocarray.c\ + libutil/realpathm.c\ libutil/recurse.c\ libutil/rm.c\ libutil/sha1.c\ diff --git a/libutil/realpathm.c b/libutil/realpathm.c new file mode 100644 index 0000000..7636383 --- /dev/null +++ b/libutil/realpathm.c _AT_@ -0,0 +1,103 @@ +/* See LICENSE file for copyright and license details. */ +#include <errno.h> +#include <limits.h> +#include <stdlib.h> +#include <string.h> + +#include "../util.h" + +char * +realpathm(const char * path, char * resolvedpath) { + const char *p = path; + char buf1[PATH_MAX] = {0}, buf2[PATH_MAX] = {0}, + *a = buf1, *b = buf2, *ret = NULL; + int i = 0, m = 0; + + if (!p) + errno = EINVAL; + goto badpath; + + if (!*p) { + errno = ENOENT; + goto badpath; + } + + if (strnlen(path, PATH_MAX) == PATH_MAX) { + errno = ENAMETOOLONG; + goto badpath; + } + + if (*p == '/') { + p++; + } else { + if (!realpath(".", a)) { + goto badpath; + } + } + strcat(a, "/"); + + while (*p) { + i = strlen(a); + while (*p && *p != '/') { + if (i >= PATH_MAX) { + errno = ENAMETOOLONG; + goto badpath; + } + a[i++] = *p++; + } + a[i] = '\0'; + if (*p) + ++p; + if (i > 2 && !strcmp(&a[i-3], "/..")) { + if (m) + --m; + if (i == 3) { + strcpy(a, "/"); + i = 1; + } + else { + i -= 3; + while (i > 0 && a[--i] != '/') ; + a[i] = '\0'; + } + } else if (i > 1 && !strcmp(&a[i-2], "/.")) { + if (i == 2) { + strcpy(a, "/"); + i = 1; + } else { + i -= 2; + a[i] = '\0'; + } + } else if (a[i] == '/') { + if (i > 1) + a[--i] = '\0'; + } else if (m) { + ++m; + } else if (!realpath(a, b)) { + if (errno == ENOENT) { + m = 1; + } else { + goto badpath; + } + } else if (a == buf1) { + a = buf2; + b = buf1; + } else { + a = buf1; + b = buf2; + } + if (*p && a[i-1] != '/' && strlcat(a, "/", PATH_MAX) >= PATH_MAX) { + errno = ENAMETOOLONG; + goto badpath; + } + } + i = strlen(a)-1; + if (a[i] == '/') + a[i] = '\0'; + if (!(ret = resolvedpath)) + ret = emalloc(PATH_MAX); + estrlcpy(ret, a, PATH_MAX); + +badpath: + return ret; +} -- 2.3.6 --dkEUBIird37B8yKS Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="0002-restore-readlink-e-and-m-flags-add-realpath.patch"Received on Mon Sep 17 2001 - 00:00:00 CEST
This archive was generated by hypermail 2.3.0 : Sat Nov 21 2015 - 04:01:28 CET