diff --git a/CHANGELOG b/CHANGELOG index 91903e9..6b16b0f 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,7 @@ ----------------------- - include krb5.h in lookup_ldap.h (some openssl doesn't implicitly include it). - correct initialization of local var in parse_server_string. +- add missing "multi" map support. 18/06/2007 autofs-5.0.2 ----------------------- diff --git a/daemon/lookup.c b/daemon/lookup.c index 06fcecc..70b9e02 100644 --- a/daemon/lookup.c +++ b/daemon/lookup.c @@ -456,8 +456,12 @@ int lookup_nss_read_map(struct autofs_point *ap, struct map_source *source, time } if (map->type) { - debug(ap->logopt, - "reading map %s %s", map->type, map->argv[0]); + if (!strncmp(map->type, "multi", 5)) + debug(ap->logopt, "reading multi map"); + else + debug(ap->logopt, + "reading map %s %s", + map->type, map->argv[0]); result = do_read_map(ap, map, age); map = map->next; continue; diff --git a/include/automount.h b/include/automount.h index 85e6e9c..106ed0a 100644 --- a/include/automount.h +++ b/include/automount.h @@ -192,6 +192,7 @@ char *cache_get_offset(const char *prefix, char *offset, int start, struct list_ /* Utility functions */ char **add_argv(int argc, char **argv, char *str); +char **append_argv(int argc1, char **argv1, int argc2, char **argv2); const char **copy_argv(int argc, const char **argv); int compare_argv(int argc1, const char **argv1, int argc2, const char **argv2); int free_argv(int argc, const char **argv); diff --git a/lib/args.c b/lib/args.c index 9e35388..fbfb004 100644 --- a/lib/args.c +++ b/lib/args.c @@ -62,6 +62,45 @@ char **add_argv(int argc, char **argv, char *str) return vector; } +char **append_argv(int argc1, char **argv1, int argc2, char **argv2) +{ + char **vector; + size_t vector_size; + int len, i, j; + + len = argc1 + argc2; + vector_size = (len + 1) * sizeof(char *); + vector = (char **) realloc(argv1, vector_size); + if (!vector) { + free_argv(argc1, (const char **) argv1); + free_argv(argc2, (const char **) argv2); + return NULL; + } + + for (i = argc1, j = 0; i <= len; i++, j++) { + if (argv2[j]) { + vector[i] = strdup(argv2[j]); + if (!vector[i]) { + error(LOGOPT_ANY, "failed to strdup arg"); + break; + } + } else + vector[i] = NULL; + } + + if (i < len) { + free_argv(len, (const char **) vector); + free_argv(argc2, (const char **) argv2); + return NULL; + } + + vector[len] = NULL; + + free_argv(argc2, (const char **) argv2); + + return vector; +} + const char **copy_argv(int argc, const char **argv) { char **vector; diff --git a/lib/master_parse.y b/lib/master_parse.y index 8d2be02..f9cba05 100644 --- a/lib/master_parse.y +++ b/lib/master_parse.y @@ -22,6 +22,7 @@ #include #include #include +#include #include #include "automount.h" @@ -44,6 +45,7 @@ extern void master_set_scan_buffer(const char *); static char *master_strdup(char *); static void local_init_vars(void); static void local_free_vars(void); +static int add_multi_mapstr(void); static int master_error(const char *s); static int master_notify(const char *s); @@ -53,6 +55,8 @@ static char *type; static char *format; static long timeout; static unsigned ghost; +static char **tmp_argv; +static int tmp_argc; static char **local_argv; static int local_argc; @@ -89,7 +93,7 @@ static int master_fprintf(FILE *, char *, ...); %token COMMENT %token MAP %token OPT_TIMEOUT OPT_NOGHOST OPT_GHOST OPT_VERBOSE OPT_DEBUG -%token COLON COMMA NL +%token COLON COMMA NL DDASH %type map %type options %type dn @@ -103,6 +107,7 @@ static int master_fprintf(FILE *, char *, ...); %token NILL %token SPACE %token EQUAL +%token MULTITYPE %token MAPTYPE %token DNSERVER %token DNATTR @@ -126,7 +131,7 @@ file: { ; line: - | PATH map + | PATH mapspec { path = master_strdup($1); if (!path) { @@ -134,14 +139,49 @@ line: YYABORT; } } - | PATH map options + | PATH MULTITYPE maplist { + char *tmp; + + tmp = strchr($2, ':'); + if (tmp) + *tmp = '\0'; + else { + int len = strlen($2); + while (len-- && isblank($2[len])) + $2[len] = '\0'; + if (len < 4) { + master_notify($2); + local_free_vars(); + YYABORT; + } + } + path = master_strdup($1); if (!path) { + master_error("memory allocation error"); local_free_vars(); YYABORT; } - } + + if ((tmp = strchr($2, ','))) + *tmp++ = '\0'; + + type = master_strdup($2); + if (!type) { + master_error("memory allocation error"); + local_free_vars(); + YYABORT; + } + if (tmp) { + format = master_strdup(tmp); + if (!format) { + master_error("memory allocation error"); + local_free_vars(); + YYABORT; + } + } + } | PATH COLON { master_notify($1); YYABORT; } | PATH OPTION { master_notify($2); YYABORT; } | PATH NILL { master_notify($2); YYABORT; } @@ -157,25 +197,89 @@ line: | COMMENT { YYABORT; } ; -map: PATH +mapspec: map + { + local_argc = tmp_argc; + local_argv = tmp_argv; + tmp_argc = 0; + tmp_argv = NULL; + } + | map options + { + local_argc = tmp_argc; + local_argv = tmp_argv; + tmp_argc = 0; + tmp_argv = NULL; + } + ; + +maplist: map + { + if (!add_multi_mapstr()) { + master_error("memory allocation error"); + local_free_vars(); + YYABORT; + } + } + | map options + { + if (!add_multi_mapstr()) { + master_error("memory allocation error"); + local_free_vars(); + YYABORT; + } + } + | maplist DDASH map { local_argc++; - local_argv = add_argv(local_argc, local_argv, $1); + local_argv = add_argv(local_argc, local_argv, "--"); if (!local_argv) { master_error("memory allocation error"); local_free_vars(); YYABORT; } + if (!add_multi_mapstr()) { + master_error("memory allocation error"); + local_free_vars(); + YYABORT; + } } - | MAPNAME + | maplist DDASH map options { local_argc++; - local_argv = add_argv(local_argc, local_argv, $1); + local_argv = add_argv(local_argc, local_argv, "--"); if (!local_argv) { master_error("memory allocation error"); local_free_vars(); YYABORT; } + if (!add_multi_mapstr()) { + master_error("memory allocation error"); + local_free_vars(); + YYABORT; + } + } + ; + +map: PATH + { + tmp_argc++; + tmp_argv = add_argv(tmp_argc, tmp_argv, $1); + if (!tmp_argv) { + master_error("memory allocation error"); + local_free_vars(); + YYABORT; + } + } + | MAPNAME + { + tmp_argc++; + tmp_argv = add_argv(tmp_argc, tmp_argv, $1); + if (!tmp_argv) { + master_error("memory allocation error"); + local_free_vars(); + YYABORT; + } } | MAPHOSTS { @@ -200,9 +304,9 @@ map: PATH local_free_vars(); YYABORT; } - local_argc++; - local_argv = add_argv(local_argc, local_argv, $1); - if (!local_argv) { + tmp_argc++; + tmp_argv = add_argv(tmp_argc, tmp_argv, $1); + if (!tmp_argv) { master_error("memory allocation error"); local_free_vars(); YYABORT; @@ -227,9 +331,9 @@ map: PATH YYABORT; } } - local_argc++; - local_argv = add_argv(local_argc, local_argv, $3); - if (!local_argv) { + tmp_argc++; + tmp_argv = add_argv(tmp_argc, tmp_argv, $3); + if (!tmp_argv) { master_error("memory allocation error"); local_free_vars(); YYABORT; @@ -254,9 +358,9 @@ map: PATH YYABORT; } } - local_argc++; - local_argv = add_argv(local_argc, local_argv, $3); - if (!local_argv) { + tmp_argc++; + tmp_argv = add_argv(tmp_argc, tmp_argv, $3); + if (!tmp_argv) { master_error("memory allocation error"); local_free_vars(); YYABORT; @@ -281,25 +385,25 @@ map: PATH YYABORT; } } - local_argc++; - local_argv = add_argv(local_argc, local_argv, $3); - if (!local_argv) { + tmp_argc++; + tmp_argv = add_argv(tmp_argc, tmp_argv, $3); + if (!tmp_argv) { master_error("memory allocation error"); local_free_vars(); YYABORT; } /* Add back the type for lookup_ldap.c to handle ldaps */ - if (*local_argv[0]) { - tmp = malloc(strlen(type) + strlen(local_argv[0]) + 2); + if (*tmp_argv[0]) { + tmp = malloc(strlen(type) + strlen(tmp_argv[0]) + 2); if (!tmp) { local_free_vars(); YYABORT; } strcpy(tmp, type); strcat(tmp, ":"); - strcat(tmp, local_argv[0]); - free(local_argv[0]); - local_argv[0] = tmp; + strcat(tmp, tmp_argv[0]); + free(tmp_argv[0]); + tmp_argv[0] = tmp; } } ; @@ -441,9 +545,9 @@ daemon_option: OPT_TIMEOUT NUMBER { timeout = $2; } mount_option: OPTION { - local_argc++; - local_argv = add_argv(local_argc, local_argv, $1); - if (!local_argv) { + tmp_argc++; + tmp_argv = add_argv(tmp_argc, tmp_argv, $1); + if (!tmp_argv) { master_error("memory allocation error"); local_free_vars(); YYABORT; @@ -494,6 +598,8 @@ static void local_init_vars(void) debug = 0; timeout = -1; ghost = defaults_get_browse_mode(); + tmp_argv = NULL; + tmp_argc = 0; local_argv = NULL; local_argc = 0; } @@ -509,8 +615,62 @@ static void local_free_vars(void) if (format) free(format); - if (local_argv) + if (local_argv) { free_argv(local_argc, (const char **) local_argv); + local_argv = NULL; + local_argc = 0; + } + + if (tmp_argv) { + free_argv(tmp_argc, (const char **) tmp_argv); + tmp_argv = NULL; + tmp_argc = 0; + } +} + +static int add_multi_mapstr(void) +{ + /* We need the individual map types for a multi map */ + if (!type) { + if (tmp_argc > 0 && *tmp_argv[0] == '/') + type = strdup("file"); + else + return 0; + } + + if (format) { + char *tmp = realloc(type, strlen(type) + strlen(format) + 2); + if (!tmp) + return 0; + type = tmp; + strcat(type, ","); + strcat(type, format); + free(format); + format = NULL; + } + + local_argc++; + local_argv = add_argv(local_argc, local_argv, type); + if (!local_argv) { + free(type); + type = NULL; + return 0; + } + + local_argv = append_argv(local_argc, local_argv, tmp_argc, tmp_argv); + if (!local_argv) { + free(type); + type = NULL; + return 0; + } + local_argc += tmp_argc; + + tmp_argc = 0; + tmp_argv = NULL; + free(type); + type = NULL; + + return 1; } void master_init_scan(void) diff --git a/lib/master_tok.l b/lib/master_tok.l index ee2a4eb..0548de1 100644 --- a/lib/master_tok.l +++ b/lib/master_tok.l @@ -27,6 +27,7 @@ static void master_echo(void); /* forward definition */ #include #include #include +#include #include "master_parse.tab.h" /* @@ -110,7 +111,9 @@ DNATTRSTR {AT_CN}|{AT_NMN}|{AT_AMN}|{AT_OU}|{AT_DC}|{AT_O}|{AT_C} DNNAMESTR ([[:alnum:]_.\-]+) INTMAP (-hosts|-null) -MTYPE ((file|program|yp|nis|nisplus|ldap|ldaps|hesiod|userdir)(,(sun|hesiod))?) +MULTI ((multi)(,(sun|hesiod))?[\:]?{OPTWS}) +MULTISEP ([\-]{2}[[:blank:]]+) +MTYPE ((file|program|yp|nis|nisplus|ldap|ldaps|hesiod|userdir)(,(sun|hesiod))?) OPTTOUT (-t{OPTWS}|-t{OPTWS}={OPTWS}|--timeout{OPTWS}|--timeout{OPTWS}={OPTWS}) @@ -184,11 +187,18 @@ OPTTOUT (-t{OPTWS}|-t{OPTWS}={OPTWS}|--timeout{OPTWS}|--timeout{OPTWS}={OPTWS}) { {OPTWS}\\\n{OPTWS} {} + {MULTI} { + strcpy(master_lval.strtype, master_text); + return(MULTITYPE); + } + {MTYPE}/":" { strcpy(master_lval.strtype, master_text); return(MAPTYPE); } + {MULTISEP} { return(DDASH); } + ":" { return(COLON); } "-hosts" { @@ -298,6 +308,11 @@ OPTTOUT (-t{OPTWS}|-t{OPTWS}={OPTWS}|--timeout{OPTWS}|--timeout{OPTWS}={OPTWS}) { {OPTWS}\\\n{OPTWS} {} + {MULTISEP} { + BEGIN(MAPSTR); + return(DDASH); + } + {OPTTOUT} { return(OPT_TIMEOUT); } {NUMBER} { diff --git a/modules/lookup_multi.c b/modules/lookup_multi.c index 00ab28e..38ca36c 100644 --- a/modules/lookup_multi.c +++ b/modules/lookup_multi.c @@ -45,7 +45,7 @@ int lookup_init(const char *my_mapfmt, int argc, const char *const *argv, void * struct lookup_context *ctxt; char buf[MAX_ERR_BUF]; char *map, *mapfmt; - int i, j, an; + int i, an; char *estr; ctxt = malloc(sizeof(struct lookup_context)); @@ -73,7 +73,7 @@ int lookup_init(const char *my_mapfmt, int argc, const char *const *argv, void * memcpy(ctxt->argl, argv, (argc + 1) * sizeof(const char *)); - for (i = j = an = 0; ctxt->argl[an]; an++) { + for (i = an = 0; ctxt->argl[an]; an++) { if (ctxt->m[i].argc == 0) { ctxt->m[i].argv = &ctxt->argl[an]; } @@ -100,9 +100,12 @@ int lookup_init(const char *my_mapfmt, int argc, const char *const *argv, void * if (!(ctxt->m[i].mod = open_lookup(map, MODPREFIX, mapfmt ? mapfmt : my_mapfmt, ctxt->m[i].argc - 1, - ctxt->m[i].argv + 1))) + ctxt->m[i].argv + 1))) { error(LOGOPT_ANY, MODPREFIX "error opening module"); + free(map); goto error_out; + } + free(map); } *context = ctxt;