You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
119 lines
3.1 KiB
119 lines
3.1 KiB
autofs-5.0.9 - amd lookup add key matching helper function |
|
|
|
From: Ian Kent <raven@themaw.net> |
|
|
|
Add helper function and match_cached_key() that perform the progressive |
|
key+prefix matching procedure. |
|
--- |
|
include/parse_subs.h | 2 + |
|
lib/parse_subs.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++ |
|
2 files changed, 86 insertions(+) |
|
|
|
diff --git a/include/parse_subs.h b/include/parse_subs.h |
|
index 43da182..1e87716 100644 |
|
--- a/include/parse_subs.h |
|
+++ b/include/parse_subs.h |
|
@@ -113,6 +113,8 @@ struct map_type_info { |
|
unsigned int get_proximity(struct sockaddr *); |
|
unsigned int get_network_proximity(const char *); |
|
unsigned int in_network(char *); |
|
+struct mapent *match_cached_key(struct autofs_point *, const char *, |
|
+ struct map_source *, const char *); |
|
const char *skipspace(const char *); |
|
int check_colon(const char *); |
|
int chunklen(const char *, int); |
|
diff --git a/lib/parse_subs.c b/lib/parse_subs.c |
|
index 421d18c..1e4825d 100644 |
|
--- a/lib/parse_subs.c |
|
+++ b/lib/parse_subs.c |
|
@@ -498,6 +498,90 @@ unsigned int in_network(char *network) |
|
return 1; |
|
} |
|
|
|
+struct mapent *match_cached_key(struct autofs_point *ap, |
|
+ const char *err_prefix, |
|
+ struct map_source *source, |
|
+ const char *key) |
|
+{ |
|
+ char buf[MAX_ERR_BUF]; |
|
+ struct mapent_cache *mc; |
|
+ struct mapent *me; |
|
+ |
|
+ mc = source->mc; |
|
+ |
|
+ if (!(source->flags & MAP_FLAG_FORMAT_AMD)) { |
|
+ int ret; |
|
+ |
|
+ me = cache_lookup(mc, key); |
|
+ /* |
|
+ * Stale mapent => check for entry in alternate source or |
|
+ * wildcard. Note, plus included direct mount map entries |
|
+ * are included as an instance (same map entry cache), not |
|
+ * in a distinct source. |
|
+ */ |
|
+ if (me && (!me->mapent || |
|
+ (me->source != source && *me->key != '/'))) { |
|
+ while ((me = cache_lookup_key_next(me))) |
|
+ if (me->source == source) |
|
+ break; |
|
+ if (!me) |
|
+ me = cache_lookup_distinct(mc, "*"); |
|
+ } |
|
+ |
|
+ if (!me) |
|
+ goto done; |
|
+ |
|
+ /* |
|
+ * If this is a lookup add wildcard match for later validation |
|
+ * checks and negative cache lookups. |
|
+ */ |
|
+ if (!(ap->flags & MOUNT_FLAG_REMOUNT) && |
|
+ ap->type == LKP_INDIRECT && *me->key == '*') { |
|
+ ret = cache_update(mc, source, key, me->mapent, me->age); |
|
+ if (!(ret & (CHE_OK | CHE_UPDATED))) |
|
+ me = NULL; |
|
+ } |
|
+ } else { |
|
+ char *lkp_key = strdup(key); |
|
+ if (!lkp_key) { |
|
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); |
|
+ error(ap->logopt, "%s strdup: %s", err_prefix, estr); |
|
+ return NULL; |
|
+ } |
|
+ |
|
+ /* If it's found we're done */ |
|
+ me = cache_lookup_distinct(mc, lkp_key); |
|
+ if (me) |
|
+ goto free; |
|
+ |
|
+ /* |
|
+ * Otherwise strip successive directory components and try |
|
+ * a match against map entries ending with a wildcard and |
|
+ * finally try the wilcard entry itself. |
|
+ */ |
|
+ while (!me) { |
|
+ char *prefix; |
|
+ |
|
+ while ((prefix = strrchr(lkp_key, '/'))) { |
|
+ *prefix = '\0'; |
|
+ me = cache_partial_match_wild(mc, lkp_key); |
|
+ if (me) |
|
+ goto free; |
|
+ } |
|
+ |
|
+ me = cache_lookup_distinct(mc, "*"); |
|
+ if (me) |
|
+ goto free; |
|
+ |
|
+ break; |
|
+ } |
|
+free: |
|
+ free(lkp_key); |
|
+ } |
|
+done: |
|
+ return me; |
|
+} |
|
+ |
|
/* |
|
* Skip whitespace in a string; if we hit a #, consider the rest of the |
|
* entry a comment.
|
|
|