The ability to pass parameters to program maps, in some way, is needed. Standard autofs specifies that program maps have one argument so passing parameters as arguments shouldn't be done. This patch sets the existing macro table definitions (for both global and local table) as environment variables before calling the map. The values are not checked after return so, at this stage, program maps can't change macro definitions. --- include/macros.h | 1 + lib/macros.c | 28 ++++++++++++++++++++++++++++ modules/lookup_program.c | 20 ++++++++++++++++++++ 3 files changed, 49 insertions(+) diff --git a/include/macros.h b/include/macros.h index a73a4a7..5077b5d 100644 --- a/include/macros.h +++ b/include/macros.h @@ -40,5 +40,6 @@ void macro_free_global_table(void); void macro_free_table(struct substvar *table); const struct substvar * macro_findvar(const struct substvar *table, const char *str, int len); +void macro_setenv(const struct substvar *table); #endif diff --git a/lib/macros.c b/lib/macros.c index 32b70bf..33c2ada 100644 --- a/lib/macros.c +++ b/lib/macros.c @@ -421,3 +421,31 @@ macro_findvar(const struct substvar *table, const char *str, int len) return NULL; } +/* Set environment from macro variable table */ +void macro_setenv(const struct substvar *table) +{ + const struct substvar *sv = system_table; + const struct substvar *lv = table; + + /* + * First set environment from global table, matching local + * variables will overwrite these. + */ + while (sv) { + if (sv->def) + setenv(sv->def, sv->val, 1); + sv = sv->next; + } + + error(LOGOPT_ANY, "table %p", table); + dump_table(table); + + /* Next set environment from the local table */ + while (lv) { + if (lv->def) + setenv(lv->def, lv->val, 1); + lv = lv->next; + } + + return; +} diff --git a/modules/lookup_program.c b/modules/lookup_program.c index 2457108..7e22b38 100644 --- a/modules/lookup_program.c +++ b/modules/lookup_program.c @@ -36,9 +36,17 @@ struct lookup_context { const char *mapname; + char *mapfmt; struct parse_mod *parse; }; +struct parse_context { + char *optstr; /* Mount options */ + char *macros; /* Map wide macro defines */ + struct substvar *subst; /* $-substitutions */ + int slashify_colons; /* Change colons to slashes? */ +}; + int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **context) @@ -79,6 +87,8 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co if (!mapfmt) mapfmt = MAPFMT_DEFAULT; + ctxt->mapfmt = strdup(mapfmt); + ctxt->parse = open_parse(mapfmt, MODPREFIX, argc - 1, argv + 1); if (!ctxt->parse) { logmsg(MODPREFIX "failed to open parse context"); @@ -255,6 +265,14 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * warn(ap->logopt, MODPREFIX "failed to set PWD to %s for map %s", ap->path, ctxt->mapname); + /* + * MAPFMT_DEFAULT must be "sun" for ->parse_init() to have setup + * the macro table. + */ + if (ctxt->mapfmt && strcmp(ctxt->mapfmt, "MAPFMT_DEFAULT")) { + struct parse_context *pctxt = (struct parse_context *) ctxt->parse->context; + macro_setenv(pctxt->subst); + } execl(ctxt->mapname, ctxt->mapname, name, NULL); _exit(255); /* execl() failed */ } @@ -448,6 +466,8 @@ int lookup_done(void *context) { struct lookup_context *ctxt = (struct lookup_context *) context; int rv = close_parse(ctxt->parse); + if (ctxt->mapfmt) + free(ctxt->mapfmt); free(ctxt); return rv; } -- To unsubscribe from this list: send the line "unsubscribe autofs" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html