| %{ |
| /* ----------------------------------------------------------------------- * |
| * |
| * master_parser.y - master map buffer parser. |
| * |
| * Copyright 2006 Ian Kent <raven@themaw.net> |
| * |
| * This program is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License as published by |
| * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139, |
| * USA; either version 2 of the License, or (at your option) any later |
| * version. |
| * |
| * This program is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| * GNU General Public License for more details. |
| * |
| * ----------------------------------------------------------------------- */ |
| |
| #include <stdio.h> |
| #include <string.h> |
| #include <stdlib.h> |
| #include <stdarg.h> |
| #include <ctype.h> |
| #include <sys/ioctl.h> |
| |
| #include "automount.h" |
| #include "master.h" |
| |
| #define MAX_ERR_LEN 512 |
| |
| extern struct master *master_list; |
| |
| char **add_argv(int, char **, char *); |
| const char **copy_argv(int, const char **); |
| int free_argv(int, const char **); |
| |
| extern FILE *master_in; |
| extern char *master_text; |
| extern int master_lex(void); |
| extern int master_lineno; |
| 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 void trim_maptype(char *); |
| static int add_multi_mapstr(void); |
| |
| static int master_error(const char *s); |
| static int master_notify(const char *s); |
| static int master_msg(const char *s); |
| |
| static char *path; |
| static char *type; |
| static char *format; |
| static long timeout; |
| static long negative_timeout; |
| static unsigned symlnk; |
| static unsigned slave; |
| static unsigned private; |
| static unsigned nobind; |
| static unsigned ghost; |
| extern unsigned global_selection_options; |
| static unsigned random_selection; |
| static unsigned use_weight; |
| static unsigned long mode; |
| static char **tmp_argv; |
| static int tmp_argc; |
| static char **local_argv; |
| static int local_argc; |
| |
| static char errstr[MAX_ERR_LEN]; |
| |
| static unsigned int verbose; |
| static unsigned int debug; |
| |
| static int lineno; |
| |
| #define YYDEBUG 0 |
| |
| #ifndef YYENABLE_NLS |
| #define YYENABLE_NLS 0 |
| #endif |
| #ifndef YYLTYPE_IS_TRIVIAL |
| #define YYLTYPE_IS_TRIVIAL 0 |
| #endif |
| |
| #if YYDEBUG |
| static int master_fprintf(FILE *, char *, ...); |
| #undef YYFPRINTF |
| #define YYFPRINTF master_fprintf |
| #endif |
| |
| %} |
| |
| %union { |
| char strtype[2048]; |
| int inttype; |
| long longtype; |
| } |
| |
| %token COMMENT |
| %token MAP |
| %token OPT_TIMEOUT OPT_NTIMEOUT OPT_NOBIND OPT_NOGHOST OPT_GHOST OPT_VERBOSE |
| %token OPT_DEBUG OPT_RANDOM OPT_USE_WEIGHT OPT_SYMLINK OPT_MODE |
| %token OPT_SLAVE OPT_PRIVATE |
| %token COLON COMMA NL DDASH |
| %type <strtype> map |
| %type <strtype> options |
| %type <strtype> dn |
| %type <strtype> dnattrs |
| %type <strtype> dnattr |
| %type <strtype> option |
| %type <strtype> daemon_option |
| %type <strtype> mount_option |
| %token <strtype> PATH |
| %token <strtype> QUOTE |
| %token <strtype> NILL |
| %token <strtype> SPACE |
| %token <strtype> EQUAL |
| %token <strtype> MULTITYPE |
| %token <strtype> MAPTYPE |
| %token <strtype> DNSERVER |
| %token <strtype> DNATTR |
| %token <strtype> DNNAME |
| %token <strtype> MAPHOSTS |
| %token <strtype> MAPNULL |
| %token <strtype> MAPXFN |
| %token <strtype> MAPNAME |
| %token <longtype> NUMBER |
| %token <longtype> OCTALNUMBER |
| %token <strtype> OPTION |
| |
| %start file |
| |
| %% |
| |
| file: { |
| master_lineno = 0; |
| #if YYDEBUG != 0 |
| master_debug = YYDEBUG; |
| #endif |
| } line |
| ; |
| |
| line: |
| | PATH mapspec |
| { |
| path = master_strdup($1); |
| if (!path) { |
| local_free_vars(); |
| YYABORT; |
| } |
| } |
| | PATH MULTITYPE maplist |
| { |
| char *tmp = NULL; |
| |
| trim_maptype($2); |
| |
| if (path) |
| free(path); |
| path = master_strdup($1); |
| if (!path) { |
| master_error("memory allocation error"); |
| local_free_vars(); |
| YYABORT; |
| } |
| |
| if ((tmp = strchr($2, ','))) |
| *tmp++ = '\0'; |
| |
| if (type) |
| free(type); |
| type = master_strdup($2); |
| if (!type) { |
| master_error("memory allocation error"); |
| local_free_vars(); |
| YYABORT; |
| } |
| if (tmp) { |
| if (format) |
| free(format); |
| 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; } |
| | PATH OPT_RANDOM { master_notify($1); YYABORT; } |
| | PATH OPT_USE_WEIGHT { master_notify($1); YYABORT; } |
| | PATH OPT_DEBUG { master_notify($1); YYABORT; } |
| | PATH OPT_TIMEOUT { master_notify($1); YYABORT; } |
| | PATH OPT_SYMLINK { master_notify($1); YYABORT; } |
| | PATH OPT_SLAVE { master_notify($1); YYABORT; } |
| | PATH OPT_PRIVATE { master_notify($1); YYABORT; } |
| | PATH OPT_NOBIND { master_notify($1); YYABORT; } |
| | PATH OPT_GHOST { master_notify($1); YYABORT; } |
| | PATH OPT_NOGHOST { master_notify($1); YYABORT; } |
| | PATH OPT_VERBOSE { master_notify($1); YYABORT; } |
| | PATH OPT_MODE { master_notify($1); YYABORT; } |
| | PATH { master_notify($1); YYABORT; } |
| | QUOTE { master_notify($1); YYABORT; } |
| | OPTION { master_notify($1); YYABORT; } |
| | NILL { master_notify($1); YYABORT; } |
| | COMMENT { YYABORT; } |
| ; |
| |
| mapspec: map |
| { |
| if (local_argv) |
| free_argv(local_argc, (const char **) local_argv); |
| local_argc = tmp_argc; |
| local_argv = tmp_argv; |
| tmp_argc = 0; |
| tmp_argv = NULL; |
| } |
| | map options |
| { |
| if (local_argv) |
| free_argv(local_argc, (const char **) local_argv); |
| 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, "--"); |
| 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; |
| } |
| } |
| | maplist DDASH map options |
| { |
| local_argc++; |
| 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 |
| { |
| if (type) |
| free(type); |
| type = master_strdup($1 + 1); |
| if (!type) { |
| local_free_vars(); |
| YYABORT; |
| } |
| } |
| | MAPXFN |
| { |
| master_notify($1); |
| master_msg("X/Open Federated Naming service not supported"); |
| YYABORT; |
| } |
| | MAPNULL |
| { |
| if (type) |
| free(type); |
| type = master_strdup($1 + 1); |
| if (!type) { |
| local_free_vars(); |
| YYABORT; |
| } |
| } |
| | dnattrs |
| { |
| if (type) |
| free(type); |
| type = master_strdup("ldap"); |
| if (!type) { |
| local_free_vars(); |
| YYABORT; |
| } |
| tmp_argc++; |
| tmp_argv = add_argv(tmp_argc, tmp_argv, $1); |
| if (!tmp_argv) { |
| master_error("memory allocation error"); |
| local_free_vars(); |
| YYABORT; |
| } |
| } |
| | MAPTYPE PATH |
| { |
| char *tmp = NULL; |
| |
| trim_maptype($1); |
| |
| if ((tmp = strchr($1, ','))) |
| *tmp++ = '\0'; |
| |
| if (type) |
| free(type); |
| if (strcmp($1, "exec")) |
| type = master_strdup($1); |
| else |
| type = master_strdup("program"); |
| if (!type) { |
| master_error("memory allocation error"); |
| local_free_vars(); |
| YYABORT; |
| } |
| if (tmp) { |
| if (format) |
| free(format); |
| format = master_strdup(tmp); |
| if (!format) { |
| master_error("memory allocation error"); |
| local_free_vars(); |
| YYABORT; |
| } |
| } |
| tmp_argc++; |
| tmp_argv = add_argv(tmp_argc, tmp_argv, $2); |
| if (!tmp_argv) { |
| master_error("memory allocation error"); |
| local_free_vars(); |
| YYABORT; |
| } |
| } |
| | MAPTYPE MAPNAME |
| { |
| char *tmp = NULL; |
| |
| trim_maptype($1); |
| |
| if ((tmp = strchr($1, ','))) |
| *tmp++ = '\0'; |
| |
| if (type) |
| free(type); |
| if (strcmp($1, "exec")) |
| type = master_strdup($1); |
| else |
| type = master_strdup("program"); |
| if (!type) { |
| master_error("memory allocation error"); |
| local_free_vars(); |
| YYABORT; |
| } |
| if (tmp) { |
| if (format) |
| free(format); |
| format = master_strdup(tmp); |
| if (!format) { |
| master_error("memory allocation error"); |
| local_free_vars(); |
| YYABORT; |
| } |
| } |
| tmp_argc++; |
| tmp_argv = add_argv(tmp_argc, tmp_argv, $2); |
| if (!tmp_argv) { |
| master_error("memory allocation error"); |
| local_free_vars(); |
| YYABORT; |
| } |
| } |
| | MAPTYPE dn |
| { |
| char *tmp = NULL; |
| |
| trim_maptype($1); |
| |
| if ((tmp = strchr($1, ','))) |
| *tmp++ = '\0'; |
| |
| if (type) |
| free(type); |
| if (strcmp($1, "exec")) |
| type = master_strdup($1); |
| else |
| type = master_strdup("program"); |
| if (!type) { |
| master_error("memory allocation error"); |
| local_free_vars(); |
| YYABORT; |
| } |
| if (tmp) { |
| if (format) |
| free(format); |
| format = master_strdup(tmp); |
| if (!format) { |
| master_error("memory allocation error"); |
| local_free_vars(); |
| YYABORT; |
| } |
| } |
| tmp_argc++; |
| tmp_argv = add_argv(tmp_argc, tmp_argv, $2); |
| if (!tmp_argv) { |
| master_error("memory allocation error"); |
| local_free_vars(); |
| YYABORT; |
| } |
| /* Add back the type for lookup_ldap.c to handle ldaps */ |
| if (*tmp_argv[0]) { |
| tmp = malloc(strlen(type) + strlen(tmp_argv[0]) + 2); |
| if (!tmp) { |
| master_error("memory allocation error"); |
| local_free_vars(); |
| YYABORT; |
| } |
| strcpy(tmp, type); |
| strcat(tmp, ":"); |
| strcat(tmp, tmp_argv[0]); |
| free(tmp_argv[0]); |
| tmp_argv[0] = tmp; |
| } |
| } |
| ; |
| |
| dn: DNSERVER dnattrs |
| { |
| strcpy($$, $1); |
| strcat($$, $2); |
| } |
| | dnattrs |
| { |
| strcpy($$, $1); |
| } |
| | |
| { |
| master_notify("syntax error in dn"); |
| YYABORT; |
| } |
| ; |
| |
| dnattrs: DNATTR EQUAL DNNAME |
| { |
| if (strcasecmp($1, "cn") && |
| strcasecmp($1, "ou") && |
| strcasecmp($1, "automountMapName") && |
| strcasecmp($1, "nisMapName")) { |
| strcpy(errstr, $1); |
| strcat(errstr, "="); |
| strcat(errstr, $3); |
| master_notify(errstr); |
| YYABORT; |
| } |
| strcpy($$, $1); |
| strcat($$, "="); |
| strcat($$, $3); |
| } |
| | DNATTR EQUAL DNNAME COMMA dnattr |
| { |
| if (strcasecmp($1, "cn") && |
| strcasecmp($1, "ou") && |
| strcasecmp($1, "automountMapName") && |
| strcasecmp($1, "nisMapName")) { |
| strcpy(errstr, $1); |
| strcat(errstr, "="); |
| strcat(errstr, $3); |
| master_notify(errstr); |
| YYABORT; |
| } |
| strcpy($$, $1); |
| strcat($$, "="); |
| strcat($$, $3); |
| strcat($$, ","); |
| strcat($$, $5); |
| } |
| | DNNAME |
| { |
| /* Matches map in old style syntax ldap:server:map */ |
| strcpy($$, $1); |
| } |
| | DNATTR |
| { |
| master_notify($1); |
| YYABORT; |
| } |
| ; |
| |
| dnattr: DNATTR EQUAL DNNAME |
| { |
| if (!strcasecmp($1, "automountMapName") || |
| !strcasecmp($1, "nisMapName")) { |
| strcpy(errstr, $1); |
| strcat(errstr, "="); |
| strcat(errstr, $3); |
| master_notify(errstr); |
| YYABORT; |
| } |
| strcpy($$, $1); |
| strcat($$, "="); |
| strcat($$, $3); |
| } |
| | DNATTR EQUAL DNNAME COMMA dnattr |
| { |
| if (!strcasecmp($1, "automountMapName") || |
| !strcasecmp($1, "nisMapName")) { |
| strcpy(errstr, $1); |
| strcat(errstr, "="); |
| strcat(errstr, $3); |
| master_notify(errstr); |
| YYABORT; |
| } |
| strcpy($$, $1); |
| strcat($$, "="); |
| strcat($$, $3); |
| strcat($$, ","); |
| strcat($$, $5); |
| } |
| | DNATTR |
| { |
| master_notify($1); |
| YYABORT; |
| } |
| | DNNAME |
| { |
| master_notify($1); |
| YYABORT; |
| } |
| ; |
| |
| options: option {} |
| | options COMMA option {} |
| | options option {} |
| | options COMMA COMMA option |
| { |
| master_notify($1); |
| YYABORT; |
| } |
| | options EQUAL |
| { |
| master_notify($1); |
| YYABORT; |
| } |
| ; |
| |
| option: daemon_option |
| | mount_option {} |
| | error |
| { |
| master_notify("bogus option"); |
| YYABORT; |
| } |
| ; |
| |
| daemon_option: OPT_TIMEOUT NUMBER { timeout = $2; } |
| | OPT_NTIMEOUT NUMBER { negative_timeout = $2; } |
| | OPT_SYMLINK { symlnk = 1; } |
| | OPT_SLAVE { slave = 1; } |
| | OPT_PRIVATE { private = 1; } |
| | OPT_NOBIND { nobind = 1; } |
| | OPT_NOGHOST { ghost = 0; } |
| | OPT_GHOST { ghost = 1; } |
| | OPT_VERBOSE { verbose = 1; } |
| | OPT_DEBUG { debug = 1; } |
| | OPT_RANDOM { random_selection = 1; } |
| | OPT_USE_WEIGHT { use_weight = 1; } |
| | OPT_MODE OCTALNUMBER { mode = $2; } |
| ; |
| |
| mount_option: OPTION |
| { |
| tmp_argc++; |
| tmp_argv = add_argv(tmp_argc, tmp_argv, $1); |
| if (!tmp_argv) { |
| master_error("memory allocation error"); |
| local_free_vars(); |
| YYABORT; |
| } |
| } |
| ; |
| %% |
| |
| #if YYDEBUG |
| static int master_fprintf(FILE *f, char *msg, ...) |
| { |
| va_list ap; |
| va_start(ap, msg); |
| vsyslog(LOG_DEBUG, msg, ap); |
| va_end(ap); |
| return 1; |
| } |
| #endif |
| |
| static char *master_strdup(char *str) |
| { |
| char *tmp; |
| |
| tmp = strdup(str); |
| if (!tmp) |
| master_error("memory allocation error"); |
| return tmp; |
| } |
| |
| static int master_error(const char *s) |
| { |
| logmsg("%s while parsing map.", s); |
| return 0; |
| } |
| |
| static int master_notify(const char *s) |
| { |
| logmsg("syntax error in map near [ %s ]", s); |
| return(0); |
| } |
| |
| static int master_msg(const char *s) |
| { |
| logmsg("%s", s); |
| return 0; |
| } |
| |
| static void local_init_vars(void) |
| { |
| path = NULL; |
| type = NULL; |
| format = NULL; |
| verbose = 0; |
| debug = 0; |
| timeout = -1; |
| negative_timeout = 0; |
| symlnk = 0; |
| slave = 0; |
| private = 0; |
| nobind = 0; |
| ghost = defaults_get_browse_mode(); |
| random_selection = global_selection_options & MOUNT_FLAG_RANDOM_SELECT; |
| use_weight = 0; |
| mode = 0; |
| tmp_argv = NULL; |
| tmp_argc = 0; |
| local_argv = NULL; |
| local_argc = 0; |
| } |
| |
| static void local_free_vars(void) |
| { |
| if (path) |
| free(path); |
| |
| if (type) |
| free(type); |
| |
| if (format) |
| free(format); |
| |
| 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 void trim_maptype(char *type) |
| { |
| char *tmp; |
| |
| tmp = strchr(type, ':'); |
| if (tmp) |
| *tmp = '\0'; |
| else { |
| int len = strlen(type); |
| while (len-- && isblank(type[len])) |
| type[len] = '\0'; |
| } |
| return; |
| } |
| |
| static int add_multi_mapstr(void) |
| { |
| if (type) { |
| /* If type given and format is non-null add it back */ |
| if (format) { |
| int len = strlen(type) + strlen(format) + 2; |
| char *tmp = realloc(type, len); |
| 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; |
| } |
| |
| free(type); |
| type = NULL; |
| } |
| |
| 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; |
| |
| return 1; |
| } |
| |
| void master_init_scan(void) |
| { |
| lineno = 0; |
| } |
| |
| int master_parse_entry(const char *buffer, unsigned int default_timeout, unsigned int logging, time_t age) |
| { |
| struct master *master = master_list; |
| struct mapent_cache *nc; |
| struct master_mapent *entry, *new; |
| struct map_source *source; |
| unsigned int logopt = logging; |
| unsigned int m_logopt = master->logopt; |
| size_t mp_len; |
| int ret; |
| |
| local_init_vars(); |
| |
| lineno++; |
| |
| master_set_scan_buffer(buffer); |
| |
| ret = master_parse(); |
| if (ret != 0) { |
| local_free_vars(); |
| return 0; |
| } |
| |
| mp_len = strlen(path); |
| while (mp_len && path[--mp_len] == '/') |
| path[mp_len] = 0; |
| |
| nc = master->nc; |
| |
| /* Add null map entries to the null map cache */ |
| if (type && !strcmp(type, "null")) { |
| cache_update(nc, NULL, path, NULL, lineno); |
| local_free_vars(); |
| return 1; |
| } |
| |
| /* Ignore all subsequent matching nulled entries */ |
| if (cache_lookup_distinct(nc, path)) { |
| local_free_vars(); |
| return 1; |
| } |
| |
| if (debug || verbose) { |
| logopt = (debug ? LOGOPT_DEBUG : 0); |
| logopt |= (verbose ? LOGOPT_VERBOSE : 0); |
| } |
| |
| new = NULL; |
| entry = master_find_mapent(master, path); |
| if (!entry) { |
| new = master_new_mapent(master, path, age); |
| if (!new) { |
| local_free_vars(); |
| return 0; |
| } |
| entry = new; |
| } else { |
| if (entry->age && entry->age == age) { |
| if (strcmp(path, "/-")) { |
| info(m_logopt, |
| "ignoring duplicate indirect mount %s", |
| path); |
| local_free_vars(); |
| return 0; |
| } |
| } |
| } |
| |
| if (!format) { |
| if (conf_amd_mount_section_exists(path)) |
| format = strdup("amd"); |
| } |
| |
| if (format && !strcmp(format, "amd")) { |
| unsigned int loglevel = conf_amd_get_log_options(); |
| unsigned int flags = conf_amd_get_flags(path); |
| |
| if (loglevel <= LOG_DEBUG && loglevel > LOG_INFO) |
| logopt = LOGOPT_DEBUG; |
| else if (loglevel <= LOG_INFO && loglevel > LOG_ERR) |
| logopt = LOGOPT_VERBOSE; |
| |
| /* It isn't possible to provide the fullybrowsable amd |
| * browsing functionality within the autofs framework. |
| * This flag will not be set if browsable_dirs = full |
| * in the configuration or fullybrowsable is present as |
| * an option. |
| */ |
| if (flags & CONF_BROWSABLE_DIRS) |
| ghost = 1; |
| } |
| |
| |
| if (!entry->ap) { |
| ret = master_add_autofs_point(entry, logopt, nobind, ghost, 0); |
| if (!ret) { |
| error(m_logopt, "failed to add autofs_point"); |
| if (new) |
| master_free_mapent(new); |
| local_free_vars(); |
| return 0; |
| } |
| } |
| if (random_selection) |
| entry->ap->flags |= MOUNT_FLAG_RANDOM_SELECT; |
| if (use_weight) |
| entry->ap->flags |= MOUNT_FLAG_USE_WEIGHT_ONLY; |
| if (symlnk) |
| entry->ap->flags |= MOUNT_FLAG_SYMLINK; |
| if (slave) |
| entry->ap->flags |= MOUNT_FLAG_SLAVE; |
| if (private) |
| entry->ap->flags |= MOUNT_FLAG_PRIVATE; |
| if (negative_timeout) |
| entry->ap->negative_timeout = negative_timeout; |
| if (mode && mode < LONG_MAX) |
| entry->ap->mode = mode; |
| |
| if (timeout < 0) { |
| /* |
| * If no timeout is given get the timout from the |
| * autofs point, or the first map, or the config |
| * for amd maps. |
| */ |
| if (format && !strcmp(format, "amd")) |
| timeout = conf_amd_get_dismount_interval(path); |
| else |
| timeout = get_exp_timeout(entry->ap, entry->maps); |
| } |
| |
| if (format && !strcmp(format, "amd")) { |
| char *opts = conf_amd_get_map_options(path); |
| if (opts) { |
| /* autofs uses the equivalent of cache:=inc,sync |
| * (except for file maps which use cache:=all,sync) |
| * but if the map is large then it may be necessary |
| * to read the whole map at startup even if browsing |
| * is is not enabled, so look for cache:=all in the |
| * map_options configuration entry. |
| */ |
| if (strstr(opts, "cache:=all")) |
| entry->ap->flags |= MOUNT_FLAG_AMD_CACHE_ALL; |
| free(opts); |
| } |
| } |
| |
| /* |
| source = master_find_map_source(entry, type, format, |
| local_argc, (const char **) local_argv); |
| if (!source) |
| source = master_add_map_source(entry, type, format, age, |
| local_argc, (const char **) local_argv); |
| else |
| source->age = age; |
| */ |
| source = master_add_map_source(entry, type, format, age, |
| local_argc, (const char **) local_argv); |
| if (!source) { |
| error(m_logopt, "failed to add source"); |
| if (new) |
| master_free_mapent(new); |
| local_free_vars(); |
| return 0; |
| } |
| set_exp_timeout(entry->ap, source, timeout); |
| source->master_line = lineno; |
| |
| entry->age = age; |
| entry->current = NULL; |
| |
| if (new) |
| master_add_mapent(master, entry); |
| |
| local_free_vars(); |
| |
| return 1; |
| } |
| |