diff options
author | mdodd <mdodd@FreeBSD.org> | 2004-05-24 01:24:13 +0000 |
---|---|---|
committer | mdodd <mdodd@FreeBSD.org> | 2004-05-24 01:24:13 +0000 |
commit | c29bed19c8b31736bce40910d1ef1e2e85f6f07a (patch) | |
tree | 18dae3c6c57f45d1bee336c75c04f08312498ba5 /libexec | |
parent | c06663e28d152236fb3e27ce54f4e8a540acd85d (diff) | |
download | FreeBSD-src-c29bed19c8b31736bce40910d1ef1e2e85f6f07a.zip FreeBSD-src-c29bed19c8b31736bce40910d1ef1e2e85f6f07a.tar.gz |
Support basename and path based constrained matches.
eg:
[foo]
...
matches any executable 'foo'
[/usr/bin/foo/]
...
matches any executable under the directory /usr/bin/foo/
Exact matches continue to function as before.
PR: bin/66769
Submitted-by: Dan Nelson
Diffstat (limited to 'libexec')
-rw-r--r-- | libexec/rtld-elf/libmap.c | 30 |
1 files changed, 29 insertions, 1 deletions
diff --git a/libexec/rtld-elf/libmap.c b/libexec/rtld-elf/libmap.c index e710fd5..4705bc6 100644 --- a/libexec/rtld-elf/libmap.c +++ b/libexec/rtld-elf/libmap.c @@ -33,6 +33,7 @@ struct lm { TAILQ_HEAD(lmp_list, lmp) lmp_head = TAILQ_HEAD_INITIALIZER(lmp_head); struct lmp { char *p; + enum { T_EXACT=0, T_BASENAME, T_DIRECTORY } type; struct lm_list lml; TAILQ_ENTRY(lmp) lmp_link; }; @@ -42,6 +43,7 @@ static void lm_free (struct lm_list *); static char * lml_find (struct lm_list *, const char *); static struct lm_list * lmp_find (const char *); static struct lm_list * lmp_init (char *); +static const char * quickbasename (const char *); #define iseol(c) (((c) == '#') || ((c) == '\0') || \ ((c) == '\n') || ((c) == '\r')) @@ -216,6 +218,8 @@ lm_find (const char *p, const char *f) return (NULL); } +/* Given a libmap translation list and a library name, return the + replacement library, or NULL */ #ifdef COMPAT_32BIT char * lm_findn (const char *p, const char *f, const int n) @@ -250,6 +254,8 @@ lml_find (struct lm_list *lmh, const char *f) return NULL; } +/* Given an executable name, return a pointer to the translation list or + NULL if no matches */ static struct lm_list * lmp_find (const char *n) { @@ -258,7 +264,9 @@ lmp_find (const char *n) dbg("%s(\"%s\")", __func__, n); TAILQ_FOREACH(lmp, &lmp_head, lmp_link) - if (strcmp(n, lmp->p) == 0) + if ((lmp->type == T_EXACT && strcmp(n, lmp->p) == 0) || + (lmp->type == T_DIRECTORY && strncmp(n, lmp->p, strlen(lmp->p)) == 0) || + (lmp->type == T_BASENAME && strcmp(quickbasename(n), lmp->p) == 0)) return (&lmp->lml); return (NULL); } @@ -272,8 +280,28 @@ lmp_init (char *n) lmp = xmalloc(sizeof(struct lmp)); lmp->p = n; + if (n[strlen(n)-1] == '/') + lmp->type = T_DIRECTORY; + else if (strchr(n,'/') == NULL) + lmp->type = T_BASENAME; + else + lmp->type = T_EXACT; TAILQ_INIT(&lmp->lml); TAILQ_INSERT_HEAD(&lmp_head, lmp, lmp_link); return (&lmp->lml); } + +/* libc basename is overkill. Return a pointer to the character after the + last /, or the original string if there are no slashes. */ +static const char * +quickbasename (const char *path) +{ + const char *p = path; + for (; *path; path++) + { + if (*path == '/') + p = path+1; + } + return p; +} |