|
|
306fa1 |
autofs-5.0.9 - amd lookup add expandamdent() function
|
|
|
306fa1 |
|
|
|
306fa1 |
From: Ian Kent <raven@themaw.net>
|
|
|
306fa1 |
|
|
|
306fa1 |
|
|
|
306fa1 |
---
|
|
|
306fa1 |
include/parse_subs.h | 2
|
|
|
306fa1 |
lib/parse_subs.c | 211 ++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
306fa1 |
2 files changed, 213 insertions(+)
|
|
|
306fa1 |
|
|
|
306fa1 |
diff --git a/include/parse_subs.h b/include/parse_subs.h
|
|
|
306fa1 |
index e57cf4a..675411d 100644
|
|
|
306fa1 |
--- a/include/parse_subs.h
|
|
|
306fa1 |
+++ b/include/parse_subs.h
|
|
|
306fa1 |
@@ -42,6 +42,8 @@ char *dequote(const char *, int, unsigned int);
|
|
|
306fa1 |
int span_space(const char *, unsigned int);
|
|
|
306fa1 |
char *sanitize_path(const char *, int, unsigned int, unsigned int);
|
|
|
306fa1 |
char *merge_options(const char *, const char *);
|
|
|
306fa1 |
+int expandamdent(const char *, char *, const struct substvar *);
|
|
|
306fa1 |
+int expand_selectors(struct autofs_point *, const char *, char **, struct substvar *);
|
|
|
306fa1 |
void free_map_type_info(struct map_type_info *);
|
|
|
306fa1 |
struct map_type_info *parse_map_type_info(const char *);
|
|
|
306fa1 |
|
|
|
306fa1 |
diff --git a/lib/parse_subs.c b/lib/parse_subs.c
|
|
|
306fa1 |
index 99075b1..279f40e 100644
|
|
|
306fa1 |
--- a/lib/parse_subs.c
|
|
|
306fa1 |
+++ b/lib/parse_subs.c
|
|
|
306fa1 |
@@ -20,6 +20,7 @@
|
|
|
306fa1 |
#include <ctype.h>
|
|
|
306fa1 |
#include <sys/types.h>
|
|
|
306fa1 |
#include <ifaddrs.h>
|
|
|
306fa1 |
+#include <libgen.h>
|
|
|
306fa1 |
#include <net/if.h>
|
|
|
306fa1 |
#include "automount.h"
|
|
|
306fa1 |
|
|
|
306fa1 |
@@ -39,6 +40,11 @@ static int volatile ifc_last_len = 0;
|
|
|
306fa1 |
/* Get numeric value of the n bits starting at position p */
|
|
|
306fa1 |
#define getbits(x, p, n) ((x >> (p + 1 - n)) & ~(~0 << n))
|
|
|
306fa1 |
|
|
|
306fa1 |
+#define EXPAND_LEADING_SLASH 0x0001
|
|
|
306fa1 |
+#define EXPAND_TRAILING_SLASH 0x0002
|
|
|
306fa1 |
+#define EXPAND_LEADING_DOT 0x0004
|
|
|
306fa1 |
+#define EXPAND_TRAILING_DOT 0x0008
|
|
|
306fa1 |
+
|
|
|
306fa1 |
struct types {
|
|
|
306fa1 |
char *type;
|
|
|
306fa1 |
unsigned int len;
|
|
|
306fa1 |
@@ -636,6 +642,211 @@ next:
|
|
|
306fa1 |
return strdup(result);
|
|
|
306fa1 |
}
|
|
|
306fa1 |
|
|
|
306fa1 |
+static char *expand_slash_or_dot(char *str, unsigned int type)
|
|
|
306fa1 |
+{
|
|
|
306fa1 |
+ char *val = NULL;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (!str)
|
|
|
306fa1 |
+ return NULL;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (!type)
|
|
|
306fa1 |
+ return str;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (type & EXPAND_LEADING_SLASH)
|
|
|
306fa1 |
+ val = basename(str);
|
|
|
306fa1 |
+ else if (type & EXPAND_TRAILING_SLASH)
|
|
|
306fa1 |
+ val = dirname(str);
|
|
|
306fa1 |
+ else if (type & (EXPAND_LEADING_DOT | EXPAND_TRAILING_DOT)) {
|
|
|
306fa1 |
+ char *dot = strchr(str, '.');
|
|
|
306fa1 |
+ if (dot)
|
|
|
306fa1 |
+ *dot++ = '\0';
|
|
|
306fa1 |
+ if (type & EXPAND_LEADING_DOT)
|
|
|
306fa1 |
+ val = dot;
|
|
|
306fa1 |
+ else
|
|
|
306fa1 |
+ val = str;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ return val;
|
|
|
306fa1 |
+}
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+/*
|
|
|
306fa1 |
+ * $-expand an amd-style map entry and return the length of the entry.
|
|
|
306fa1 |
+ * If "dst" is NULL, just count the length.
|
|
|
306fa1 |
+ */
|
|
|
306fa1 |
+/* TODO: how should quoting be handled? */
|
|
|
306fa1 |
+int expandamdent(const char *src, char *dst, const struct substvar *svc)
|
|
|
306fa1 |
+{
|
|
|
306fa1 |
+ unsigned int flags = conf_amd_get_flags(NULL);
|
|
|
306fa1 |
+ const struct substvar *sv;
|
|
|
306fa1 |
+ const char *o_src = src;
|
|
|
306fa1 |
+ int len, l;
|
|
|
306fa1 |
+ const char *p;
|
|
|
306fa1 |
+ char ch;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ len = 0;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ while ((ch = *src++)) {
|
|
|
306fa1 |
+ switch (ch) {
|
|
|
306fa1 |
+ case '$':
|
|
|
306fa1 |
+ if (*src == '{') {
|
|
|
306fa1 |
+ char *start, *end;
|
|
|
306fa1 |
+ unsigned int type = 0;
|
|
|
306fa1 |
+ p = strchr(++src, '}');
|
|
|
306fa1 |
+ if (!p) {
|
|
|
306fa1 |
+ /* Ignore rest of string */
|
|
|
306fa1 |
+ if (dst)
|
|
|
306fa1 |
+ *dst = '\0';
|
|
|
306fa1 |
+ return len;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ start = (char *) src;
|
|
|
306fa1 |
+ if (*src == '/' || *src == '.') {
|
|
|
306fa1 |
+ start++;
|
|
|
306fa1 |
+ type = EXPAND_LEADING_SLASH;
|
|
|
306fa1 |
+ if (*src == '.')
|
|
|
306fa1 |
+ type = EXPAND_LEADING_DOT;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ end = (char *) p;
|
|
|
306fa1 |
+ if (*(p - 1) == '/' || *(p - 1) == '.') {
|
|
|
306fa1 |
+ end--;
|
|
|
306fa1 |
+ type = EXPAND_TRAILING_SLASH;
|
|
|
306fa1 |
+ if (*(p - 1) == '.')
|
|
|
306fa1 |
+ type = EXPAND_TRAILING_DOT;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ sv = macro_findvar(svc, start, end - start);
|
|
|
306fa1 |
+ if (sv) {
|
|
|
306fa1 |
+ char *val;
|
|
|
306fa1 |
+ char *str = strdup(sv->val);
|
|
|
306fa1 |
+ val = expand_slash_or_dot(str, type);
|
|
|
306fa1 |
+ if (!val)
|
|
|
306fa1 |
+ val = sv->val;
|
|
|
306fa1 |
+ l = strlen(val);
|
|
|
306fa1 |
+ if (dst) {
|
|
|
306fa1 |
+ if (*dst)
|
|
|
306fa1 |
+ strcat(dst, val);
|
|
|
306fa1 |
+ else
|
|
|
306fa1 |
+ strcpy(dst, val);
|
|
|
306fa1 |
+ dst += l;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ len += l;
|
|
|
306fa1 |
+ if (str)
|
|
|
306fa1 |
+ free(str);
|
|
|
306fa1 |
+ } else {
|
|
|
306fa1 |
+ if (dst) {
|
|
|
306fa1 |
+ *dst++ = ch;
|
|
|
306fa1 |
+ *dst++ = '{';
|
|
|
306fa1 |
+ strncat(dst, src, p - src);
|
|
|
306fa1 |
+ dst += (p - src);
|
|
|
306fa1 |
+ *dst++ = '}';
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ len += 1 + 1 + (p - src) + 1;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ src = p + 1;
|
|
|
306fa1 |
+ } else {
|
|
|
306fa1 |
+ if (dst)
|
|
|
306fa1 |
+ *(dst++) = ch;
|
|
|
306fa1 |
+ len++;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ break;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ case '\\':
|
|
|
306fa1 |
+ if (!(flags & CONF_NORMALIZE_SLASHES)) {
|
|
|
306fa1 |
+ len++;
|
|
|
306fa1 |
+ if (dst)
|
|
|
306fa1 |
+ *dst++ = ch;
|
|
|
306fa1 |
+ break;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (*src) {
|
|
|
306fa1 |
+ len++;
|
|
|
306fa1 |
+ if (dst)
|
|
|
306fa1 |
+ *dst++ = *src;
|
|
|
306fa1 |
+ src++;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ break;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ case '/':
|
|
|
306fa1 |
+ len++;
|
|
|
306fa1 |
+ if (dst)
|
|
|
306fa1 |
+ *dst++ = ch;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (!(flags & CONF_NORMALIZE_SLASHES))
|
|
|
306fa1 |
+ break;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ /* Double slash at start is allowed */
|
|
|
306fa1 |
+ if (src == (o_src + 1) && *src == '/') {
|
|
|
306fa1 |
+ len++;
|
|
|
306fa1 |
+ if (dst)
|
|
|
306fa1 |
+ *dst++ = *src;
|
|
|
306fa1 |
+ src++;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ while (*src == '/')
|
|
|
306fa1 |
+ src++;
|
|
|
306fa1 |
+ break;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ case '"':
|
|
|
306fa1 |
+ len++;
|
|
|
306fa1 |
+ if (dst)
|
|
|
306fa1 |
+ *dst++ = ch;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ while (*src && *src != '"') {
|
|
|
306fa1 |
+ len++;
|
|
|
306fa1 |
+ if (dst)
|
|
|
306fa1 |
+ *dst++ = *src;
|
|
|
306fa1 |
+ src++;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ if (*src) {
|
|
|
306fa1 |
+ len++;
|
|
|
306fa1 |
+ if (dst)
|
|
|
306fa1 |
+ *dst++ = *src;
|
|
|
306fa1 |
+ src++;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ break;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ default:
|
|
|
306fa1 |
+ if (dst)
|
|
|
306fa1 |
+ *(dst++) = ch;
|
|
|
306fa1 |
+ len++;
|
|
|
306fa1 |
+ break;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ if (dst)
|
|
|
306fa1 |
+ *dst = '\0';
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ return len;
|
|
|
306fa1 |
+}
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+int expand_selectors(struct autofs_point *ap,
|
|
|
306fa1 |
+ const char *mapstr, char **pmapstr,
|
|
|
306fa1 |
+ struct substvar *sv)
|
|
|
306fa1 |
+{
|
|
|
306fa1 |
+ char buf[MAX_ERR_BUF];
|
|
|
306fa1 |
+ char *expand;
|
|
|
306fa1 |
+ size_t len;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (!mapstr)
|
|
|
306fa1 |
+ return 0;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ len = expandamdent(mapstr, NULL, sv);
|
|
|
306fa1 |
+ if (len == 0) {
|
|
|
306fa1 |
+ error(ap->logopt, "failed to expand map entry");
|
|
|
306fa1 |
+ return 0;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ expand = malloc(len + 1);
|
|
|
306fa1 |
+ if (!expand) {
|
|
|
306fa1 |
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
|
|
306fa1 |
+ error(ap->logopt, "malloc: %s", estr);
|
|
|
306fa1 |
+ return 0;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ memset(expand, 0, len + 1);
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ expandamdent(mapstr, expand, sv);
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ *pmapstr = expand;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ return len;
|
|
|
306fa1 |
+}
|
|
|
306fa1 |
+
|
|
|
306fa1 |
void free_map_type_info(struct map_type_info *info)
|
|
|
306fa1 |
{
|
|
|
306fa1 |
if (info->type)
|