From mboxrd@z Thu Jan 1 00:00:00 1970 X-Msuck: nntp://news.gmane.org/gmane.linux.lib.musl.general/14448 Path: news.gmane.org!.POSTED.blaine.gmane.org!not-for-mail From: Ismael Luceno Newsgroups: gmane.linux.lib.musl.general Subject: [PATCH v2] glob: implement GLOB_TILDE Date: Wed, 24 Jul 2019 23:33:38 +0200 Message-ID: <20190724213338.27138-1-ismael@iodev.co.uk> Reply-To: musl@lists.openwall.com Mime-Version: 1.0 Content-Transfer-Encoding: 8bit Injection-Info: blaine.gmane.org; posting-host="blaine.gmane.org:195.159.176.226"; logging-data="130371"; mail-complaints-to="usenet@blaine.gmane.org" Cc: Ismael Luceno To: musl@lists.openwall.com Original-X-From: musl-return-14464-gllmg-musl=m.gmane.org@lists.openwall.com Wed Jul 24 23:33:54 2019 Return-path: Envelope-to: gllmg-musl@m.gmane.org Original-Received: from mother.openwall.net ([195.42.179.200]) by blaine.gmane.org with smtp (Exim 4.89) (envelope-from ) id 1hqOtW-000Xoc-1P for gllmg-musl@m.gmane.org; Wed, 24 Jul 2019 23:33:54 +0200 Original-Received: (qmail 12172 invoked by uid 550); 24 Jul 2019 21:33:52 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Original-Received: (qmail 12140 invoked from network); 24 Jul 2019 21:33:51 -0000 X-Mailer: git-send-email 2.22.0 Xref: news.gmane.org gmane.linux.lib.musl.general:14448 Archived-At: Signed-off-by: Ismael Luceno --- 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 #include #include -#include #include #include #include +#include +#include +#define _GNU_SOURCE +#include 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