|
|
Message-Id: <20190724213338.27138-1-ismael@iodev.co.uk>
Date: Wed, 24 Jul 2019 23:33:38 +0200
From: Ismael Luceno <ismael@...ev.co.uk>
To: musl@...ts.openwall.com
Cc: Ismael Luceno <ismael@...ev.co.uk>
Subject: [PATCH v2] glob: implement GLOB_TILDE
Signed-off-by: Ismael Luceno <ismael@...ev.co.uk>
---
include/glob.h | 1 +
src/regex/glob.c | 45 +++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 44 insertions(+), 2 deletions(-)
diff --git a/include/glob.h b/include/glob.h
index 76f6c1c68a23..fc8106b20c5b 100644
--- a/include/glob.h
+++ b/include/glob.h
@@ -30,6 +30,7 @@ void globfree(glob_t *);
#define GLOB_APPEND 0x20
#define GLOB_NOESCAPE 0x40
#define GLOB_PERIOD 0x80
+#define GLOB_TILDE 0x100
#define GLOB_NOSPACE 1
#define GLOB_ABORTED 2
diff --git a/src/regex/glob.c b/src/regex/glob.c
index aa1c6a4482ee..2428d5f02c2e 100644
--- a/src/regex/glob.c
+++ b/src/regex/glob.c
@@ -4,10 +4,13 @@
#include <sys/stat.h>
#include <dirent.h>
#include <limits.h>
-#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <stddef.h>
+#include <unistd.h>
+#include <pwd.h>
+#define _GNU_SOURCE
+#include <string.h>
struct match
{
@@ -182,6 +185,39 @@ static int sort(const void *a, const void *b)
return strcmp(*(const char **)a, *(const char **)b);
}
+static int expand_tilde(char **pat, char *buf, size_t *pos)
+{
+ char *p = *pat + 1;
+ size_t i = 0;
+
+ char *name_end = strchrnul(p, '/');
+ if (*name_end) *name_end++ = 0;
+ *pat = name_end;
+
+ char *home = (*p || issetugid()) ? NULL : getenv("HOME");
+ if (!home) {
+ struct passwd pw, *res;
+ switch (*p ? getpwnam_r(p, &pw, buf, PATH_MAX, &res)
+ : getpwuid_r(getuid(), &pw, buf, PATH_MAX, &res)) {
+ default:
+ return GLOB_ABORTED;
+ case ERANGE: case ENOMEM:
+ return GLOB_NOSPACE;
+ case 0:
+ if (!res) return GLOB_NOMATCH;
+ }
+ home = pw.pw_dir;
+ }
+ while (i < PATH_MAX - 2 && *home)
+ buf[i++] = *home++;
+ if (i > PATH_MAX - 2)
+ return GLOB_NOSPACE;
+ buf[i++] = '/';
+ buf[i] = 0;
+ *pos = i;
+ return 0;
+}
+
int glob(const char *restrict pat, int flags, int (*errfunc)(const char *path, int err), glob_t *restrict g)
{
struct match head = { .next = NULL }, *tail = &head;
@@ -202,7 +238,12 @@ int glob(const char *restrict pat, int flags, int (*errfunc)(const char *path, i
char *p = strdup(pat);
if (!p) return GLOB_NOSPACE;
buf[0] = 0;
- error = do_glob(buf, 0, 0, p, flags, errfunc, &tail);
+ size_t pos = 0;
+ char *s = p;
+ if ((flags & GLOB_TILDE) && *p == '~')
+ error = expand_tilde(&s, buf, &pos);
+ if (!error)
+ error = do_glob(buf, pos, 0, s, flags, errfunc, &tail);
free(p);
}
--
2.22.0
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.