conf.c revision 51292
1161764Sobrien/*
279968Sobrien * Copyright (c) 1997-1999 Erez Zadok
379968Sobrien * Copyright (c) 1990 Jan-Simon Pendry
4161764Sobrien * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
579968Sobrien * Copyright (c) 1990 The Regents of the University of California.
679968Sobrien * All rights reserved.
779968Sobrien *
879968Sobrien * This code is derived from software contributed to Berkeley by
979968Sobrien * Jan-Simon Pendry at Imperial College, London.
1079968Sobrien *
1179968Sobrien * Redistribution and use in source and binary forms, with or without
1279968Sobrien * modification, are permitted provided that the following conditions
1379968Sobrien * are met:
1479968Sobrien * 1. Redistributions of source code must retain the above copyright
1579968Sobrien *    notice, this list of conditions and the following disclaimer.
1679968Sobrien * 2. Redistributions in binary form must reproduce the above copyright
1779968Sobrien *    notice, this list of conditions and the following disclaimer in the
1879968Sobrien *    documentation and/or other materials provided with the distribution.
1979968Sobrien * 3. All advertising materials mentioning features or use of this software
2079968Sobrien *    must display the following acknowledgment:
2179968Sobrien *      This product includes software developed by the University of
2279968Sobrien *      California, Berkeley and its contributors.
2379968Sobrien * 4. Neither the name of the University nor the names of its contributors
2479968Sobrien *    may be used to endorse or promote products derived from this software
2579968Sobrien *    without specific prior written permission.
2679968Sobrien *
2779968Sobrien * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2879968Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2979968Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
3079968Sobrien * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
3179968Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3279968Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
3379968Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3479968Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3579968Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3679968Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3779968Sobrien * SUCH DAMAGE.
3879968Sobrien *
3979968Sobrien *      %W% (Berkeley) %G%
4079968Sobrien *
4179968Sobrien * $Id: conf.c,v 1.4 1999/02/04 07:24:15 ezk Exp $
4279968Sobrien *
4379968Sobrien */
4479968Sobrien
4579968Sobrien/*
4679968Sobrien * Functions to handle the configuration file.
4779968Sobrien */
4879968Sobrien
4979968Sobrien#ifdef HAVE_CONFIG_H
5079968Sobrien# include <config.h>
51133936Sobrien#endif /* HAVE_CONFIG_H */
5279968Sobrien#include <am_defs.h>
5379968Sobrien#include <amd.h>
5479968Sobrien
5579968Sobrien
5679968Sobrien/*
5779968Sobrien * MACROS:
5879968Sobrien */
5979968Sobrien/* Turn on to show some info about maps being configured */
6079968Sobrien/* #define DEBUG_CONF */
6179968Sobrien
6279968Sobrien/*
6379968Sobrien * TYPEDEFS:
6479968Sobrien */
6579968Sobrientypedef int (*OptFuncPtr)(const char *);
6679968Sobrien
6779968Sobrien/*
6879968Sobrien * STRUCTURES:
6979968Sobrien */
7079968Sobrienstruct _func_map {
7179968Sobrien  char *name;
7279968Sobrien  OptFuncPtr func;
7379968Sobrien};
7479968Sobrien
7579968Sobrien/*
76108746Sobrien * FORWARD DECLARATIONS:
7779968Sobrien */
78108746Sobrienstatic int gopt_arch(const char *val);
79108746Sobrienstatic int gopt_auto_dir(const char *val);
80108746Sobrienstatic int gopt_browsable_dirs(const char *val);
81108746Sobrienstatic int gopt_cache_duration(const char *val);
82161764Sobrienstatic int gopt_cluster(const char *val);
83108746Sobrienstatic int gopt_debug_options(const char *val);
84108746Sobrienstatic int gopt_dismount_interval(const char *val);
85108746Sobrienstatic int gopt_fully_qualified_hosts(const char *val);
86108746Sobrienstatic int gopt_hesiod_base(const char *val);
87108746Sobrienstatic int gopt_karch(const char *val);
88108746Sobrienstatic int gopt_ldap_base(const char *val);
89108746Sobrienstatic int gopt_ldap_cache_maxmem(const char *val);
90108746Sobrienstatic int gopt_ldap_cache_seconds(const char *val);
91108746Sobrienstatic int gopt_ldap_hostports(const char *val);
92108746Sobrienstatic int gopt_local_domain(const char *val);
93108746Sobrienstatic int gopt_log_file(const char *val);
94108746Sobrienstatic int gopt_log_options(const char *val);
95108746Sobrienstatic int gopt_map_options(const char *val);
96108746Sobrienstatic int gopt_map_type(const char *val);
97108746Sobrienstatic int gopt_mount_type(const char *val);
98108746Sobrienstatic int gopt_pid_file(const char *val);
99108746Sobrienstatic int gopt_portmap_program(const char *val);
100108746Sobrienstatic int gopt_nfs_retransmit_counter(const char *val);
101108746Sobrienstatic int gopt_nfs_retry_interval(const char *val);
102108746Sobrienstatic int gopt_nis_domain(const char *val);
103108746Sobrienstatic int gopt_normalize_hostnames(const char *val);
104108746Sobrienstatic int gopt_os(const char *val);
105108746Sobrienstatic int gopt_osver(const char *val);
106108746Sobrienstatic int gopt_plock(const char *val);
107108746Sobrienstatic int gopt_print_pid(const char *val);
108108746Sobrienstatic int gopt_print_version(const char *val);
109108746Sobrienstatic int gopt_restart_mounts(const char *val);
11079968Sobrienstatic int gopt_search_path(const char *val);
11179968Sobrienstatic int gopt_selectors_on_default(const char *val);
11279968Sobrienstatic int gopt_show_statfs_entries(const char *val);
11379968Sobrienstatic int gopt_unmount_on_exit(const char *val);
11479968Sobrienstatic int process_global_option(const char *key, const char *val);
11579968Sobrienstatic int process_regular_map(cf_map_t *cfm);
11679968Sobrienstatic int process_regular_option(const char *section, const char *key, const char *val, cf_map_t *cfm);
11779968Sobrienstatic int ropt_browsable_dirs(const char *val, cf_map_t *cfm);
11879968Sobrienstatic int ropt_map_name(const char *val, cf_map_t *cfm);
11979968Sobrienstatic int ropt_map_options(const char *val, cf_map_t *cfm);
12079968Sobrienstatic int ropt_map_type(const char *val, cf_map_t *cfm);
121161764Sobrienstatic int ropt_mount_type(const char *val, cf_map_t *cfm);
122161764Sobrienstatic int ropt_search_path(const char *val, cf_map_t *cfm);
123161764Sobrienstatic int ropt_tag(const char *val, cf_map_t *cfm);
124161764Sobrienstatic void reset_cf_map(cf_map_t *cfm);
125161764Sobrien
126161764Sobrien
127161764Sobrien/*
128161764Sobrien * STATIC VARIABLES:
12979968Sobrien */
13079968Sobrienstatic cf_map_t cur_map;
13179968Sobrienstatic struct _func_map glob_functable[] = {
132108746Sobrien  {"arch",			gopt_arch},
133133936Sobrien  {"auto_dir",			gopt_auto_dir},
134108746Sobrien  {"browsable_dirs",		gopt_browsable_dirs},
135108746Sobrien  {"cache_duration",		gopt_cache_duration},
13679968Sobrien  {"cluster",			gopt_cluster},
13779968Sobrien  {"debug_options",		gopt_debug_options},
13879968Sobrien  {"dismount_interval",		gopt_dismount_interval},
13979968Sobrien  {"fully_qualified_hosts",	gopt_fully_qualified_hosts},
14079968Sobrien  {"hesiod_base",		gopt_hesiod_base},
14179968Sobrien  {"karch",			gopt_karch},
14279968Sobrien  {"ldap_base",			gopt_ldap_base},
143133936Sobrien  {"ldap_cache_maxmem",		gopt_ldap_cache_maxmem},
14479968Sobrien  {"ldap_cache_seconds",	gopt_ldap_cache_seconds},
14579968Sobrien  {"ldap_hostports",		gopt_ldap_hostports},
14679968Sobrien  {"local_domain",		gopt_local_domain},
14779968Sobrien  {"log_file",			gopt_log_file},
14879968Sobrien  {"log_options",		gopt_log_options},
14979968Sobrien  {"map_options",		gopt_map_options},
15079968Sobrien  {"map_type",			gopt_map_type},
15179968Sobrien  {"mount_type",		gopt_mount_type},
15279968Sobrien  {"pid_file",			gopt_pid_file},
15379968Sobrien  {"portmap_program",		gopt_portmap_program},
15479968Sobrien  {"nfs_retransmit_counter",	gopt_nfs_retransmit_counter},
15579968Sobrien  {"nfs_retry_interval",	gopt_nfs_retry_interval},
15679968Sobrien  {"nis_domain",		gopt_nis_domain},
15779968Sobrien  {"normalize_hostnames",	gopt_normalize_hostnames},
15879968Sobrien  {"os",			gopt_os},
15979968Sobrien  {"osver",			gopt_osver},
16079968Sobrien  {"plock",			gopt_plock},
16179968Sobrien  {"print_pid",			gopt_print_pid},
16279968Sobrien  {"print_version",		gopt_print_version},
16379968Sobrien  {"restart_mounts",		gopt_restart_mounts},
16479968Sobrien  {"search_path",		gopt_search_path},
16579968Sobrien  {"selectors_on_default",	gopt_selectors_on_default},
16679968Sobrien  {"show_statfs_entries",	gopt_show_statfs_entries},
16779968Sobrien  {"unmount_on_exit",		gopt_unmount_on_exit},
16879968Sobrien  {NULL, NULL}
169108746Sobrien};
17079968Sobrien
171108746Sobrien
172108746Sobrien/*
17379968Sobrien * Reset a map.
17479968Sobrien */
17579968Sobrienstatic void
17679968Sobrienreset_cf_map(cf_map_t *cfm)
17779968Sobrien{
17879968Sobrien  if (!cfm)
17979968Sobrien    return;
18079968Sobrien
18179968Sobrien  if (cfm->cfm_dir) {
18279968Sobrien    XFREE(cfm->cfm_dir);
183133936Sobrien    cfm->cfm_dir = NULL;
18479968Sobrien  }
18579968Sobrien
18679968Sobrien  if (cfm->cfm_name) {
18779968Sobrien    XFREE(cfm->cfm_name);
18879968Sobrien    cfm->cfm_name = NULL;
18979968Sobrien  }
19079968Sobrien
19179968Sobrien  if (cfm->cfm_tag) {
19279968Sobrien    XFREE(cfm->cfm_tag);
19379968Sobrien    cfm->cfm_tag = NULL;
19479968Sobrien  }
19579968Sobrien
19679968Sobrien  /*
19779968Sobrien   * reset/initialize a regular map's flags and other variables from the
19879968Sobrien   * global ones, so that they are applied to all maps.  Of course, each map
19979968Sobrien   * can then override the flags individually.
20079968Sobrien   *
20179968Sobrien   * NOTES:
20279968Sobrien   * (1): Will only work for maps that appear after [global].
20379968Sobrien   * (2): Also be careful not to free() a global option.
20479968Sobrien   * (3): I'm doing direct char* pointer comparison, and not strcmp().  This
20579968Sobrien   *      is correct!
20679968Sobrien   */
20779968Sobrien
20879968Sobrien  /* initialize map_type from [global] */
20979968Sobrien  if (cfm->cfm_type && cfm->cfm_type != gopt.map_type)
21079968Sobrien    XFREE(cfm->cfm_type);
21179968Sobrien  cfm->cfm_type = gopt.map_type;
21279968Sobrien
21379968Sobrien  /* initialize map_opts from [global] */
21479968Sobrien  if (cfm->cfm_opts && cfm->cfm_opts != gopt.map_options)
21579968Sobrien    XFREE(cfm->cfm_opts);
21679968Sobrien  cfm->cfm_opts = gopt.map_options;
21779968Sobrien
21879968Sobrien  /* initialize search_path from [global] */
21979968Sobrien  if (cfm->cfm_search_path && cfm->cfm_search_path != gopt.search_path)
22079968Sobrien    XFREE(cfm->cfm_search_path);
22179968Sobrien  cfm->cfm_search_path = gopt.search_path;
22279968Sobrien
22379968Sobrien  /*
22479968Sobrien   * Initialize flags that are common both to [global] and a local map.
22579968Sobrien   */
22679968Sobrien  cfm->cfm_flags = gopt.flags & (CFM_BROWSABLE_DIRS |
22779968Sobrien				 CFM_BROWSABLE_DIRS_FULL |
22879968Sobrien				 CFM_MOUNT_TYPE_AUTOFS |
22979968Sobrien				 CFM_ENABLE_DEFAULT_SELECTORS);
23079968Sobrien}
23179968Sobrien
23279968Sobrien
23379968Sobrien/*
23479968Sobrien * Process configuration file options.
23579968Sobrien * Return 0 if OK, 1 otherwise.
23679968Sobrien */
23779968Sobrienint
23879968Sobrienset_conf_kv(const char *section, const char *key, const char *val)
23979968Sobrien{
24079968Sobrien  int ret;
24179968Sobrien
24279968Sobrien#ifdef DEBUG_CONF
24379968Sobrien  fprintf(stderr,"set_conf_kv: section=%s, key=%s, val=%s\n",
24479968Sobrien	  section, key, val);
24579968Sobrien#endif /* DEBUG_CONF */
24679968Sobrien
24779968Sobrien  /*
24879968Sobrien   * If global section, process them one at a time.
24979968Sobrien   */
25079968Sobrien  if (STREQ(section, "global")) {
25179968Sobrien    /*
25279968Sobrien     * Check if a regular map was configured before "global",
25379968Sobrien     * and process it as needed.
25479968Sobrien     */
25579968Sobrien    if (cur_map.cfm_dir) {
25679968Sobrien      fprintf(stderr,"processing regular map \"%s\" before global one.\n",
25779968Sobrien	      section);
25879968Sobrien      ret = process_regular_map(&cur_map); /* will reset map */
25979968Sobrien      if (ret != 0)
26079968Sobrien	return ret;
26179968Sobrien    }
26279968Sobrien
26379968Sobrien    /* process the global option first */
26479968Sobrien    ret = process_global_option(key, val);
26579968Sobrien
26679968Sobrien    /* reset default options for regular maps from just updated globals */
26779968Sobrien    if (ret == 0)
26879968Sobrien      reset_cf_map(&cur_map);
26979968Sobrien
27079968Sobrien    /* return status from the processing of the global option */
27179968Sobrien    return ret;
27279968Sobrien  }
27379968Sobrien
27479968Sobrien  /*
27579968Sobrien   * otherwise save options and process a single map all at once.
27679968Sobrien   */
27779968Sobrien
27879968Sobrien  /* check if we found a new map, so process one already collected */
27979968Sobrien  if (cur_map.cfm_dir && !STREQ(cur_map.cfm_dir, section)) {
28079968Sobrien    ret = process_regular_map(&cur_map); /* will reset map */
28179968Sobrien    if (ret != 0)
28279968Sobrien      return ret;
28379968Sobrien  }
28479968Sobrien
28579968Sobrien  /* now process a single entry of a regular map */
28679968Sobrien  return process_regular_option(section, key, val, &cur_map);
28779968Sobrien}
28879968Sobrien
28979968Sobrien
29079968Sobrien/*
29179968Sobrien * Process global section of configuration file options.
29279968Sobrien * Return 0 upon success, 1 otherwise.
29379968Sobrien */
29479968Sobrienstatic int
29579968Sobrienprocess_global_option(const char *key, const char *val)
29679968Sobrien{
29779968Sobrien  struct _func_map *gfp;
29879968Sobrien
29979968Sobrien  /* ensure that val is valid */
300108746Sobrien  if (!val || val[0] == '\0')
301108746Sobrien    return 1;
302108746Sobrien
303108746Sobrien  /*
304108746Sobrien   * search for global function.
305108746Sobrien   */
306108746Sobrien  for (gfp = glob_functable; gfp->name; gfp++)
307108746Sobrien    if (FSTREQ(gfp->name, key))
30879968Sobrien      return (gfp->func)(val);
30979968Sobrien
31079968Sobrien  fprintf(stderr, "conf: unknown global key: \"%s\"\n", key);
31179968Sobrien  return 1;			/* failed to match any command */
31279968Sobrien}
313108746Sobrien
314108746Sobrien
315108746Sobrienstatic int
316108746Sobriengopt_arch(const char *val)
317108746Sobrien{
318108746Sobrien  gopt.arch = strdup((char *)val);
319108746Sobrien  return 0;
32079968Sobrien}
32179968Sobrien
32279968Sobrien
32379968Sobrienstatic int
32479968Sobriengopt_auto_dir(const char *val)
325108746Sobrien{
326108746Sobrien  gopt.auto_dir = strdup((char *)val);
327108746Sobrien  return 0;
328108746Sobrien}
329108746Sobrien
330108746Sobrien
33179968Sobrienstatic int
33279968Sobriengopt_browsable_dirs(const char *val)
33379968Sobrien{
33479968Sobrien  if (STREQ(val, "full")) {
33579968Sobrien    gopt.flags |= CFM_BROWSABLE_DIRS_FULL;
336108746Sobrien    return 0;
337108746Sobrien  } else if (STREQ(val, "yes")) {
338108746Sobrien    gopt.flags |= CFM_BROWSABLE_DIRS;
339108746Sobrien    return 0;
340108746Sobrien  } else if (STREQ(val, "no")) {
341108746Sobrien    gopt.flags &= ~CFM_BROWSABLE_DIRS;
34279968Sobrien    return 0;
34379968Sobrien  }
34479968Sobrien
34579968Sobrien  fprintf(stderr, "conf: unknown value to browsable_dirs \"%s\"\n", val);
34679968Sobrien  return 1;			/* unknown value */
34779968Sobrien}
34879968Sobrien
34979968Sobrien
35079968Sobrienstatic int
35179968Sobriengopt_cache_duration(const char *val)
35279968Sobrien{
35379968Sobrien  gopt.am_timeo = atoi(val);
35479968Sobrien  if (gopt.am_timeo <= 0)
35579968Sobrien    gopt.am_timeo = AM_TTL;
35679968Sobrien  return 0;
35779968Sobrien}
35879968Sobrien
35979968Sobrien
36079968Sobrienstatic int
36179968Sobriengopt_cluster(const char *val)
36279968Sobrien{
36379968Sobrien  gopt.cluster = strdup((char *)val);
36479968Sobrien  return 0;
36579968Sobrien}
36679968Sobrien
36779968Sobrien
36879968Sobrienstatic int
36979968Sobriengopt_debug_options(const char *val)
37079968Sobrien{
37179968Sobrien#ifdef DEBUG
37279968Sobrien  usage += debug_option(strdup((char *)val));
37379968Sobrien  return 0;
37479968Sobrien#else /* not DEBUG */
37579968Sobrien  fprintf(stderr, "%s: not compiled with DEBUG option -- sorry.\n",
37679968Sobrien	  am_get_progname());
37779968Sobrien  return 1;
37879968Sobrien#endif /* not DEBUG */
37979968Sobrien}
38079968Sobrien
38179968Sobrien
38279968Sobrienstatic int
38379968Sobriengopt_dismount_interval(const char *val)
38479968Sobrien{
38579968Sobrien  gopt.am_timeo_w = atoi(val);
38679968Sobrien  if (gopt.am_timeo_w <= 0)
38779968Sobrien    gopt.am_timeo_w = AM_TTL_W;
38879968Sobrien  return 0;
38979968Sobrien}
39079968Sobrien
39179968Sobrien
39279968Sobrienstatic int
39379968Sobriengopt_fully_qualified_hosts(const char *val)
39479968Sobrien{
39579968Sobrien  if (STREQ(val, "yes")) {
39679968Sobrien    gopt.flags |= CFM_FULLY_QUALIFIED_HOSTS;
39779968Sobrien    return 0;
39879968Sobrien  } else if (STREQ(val, "no")) {
39979968Sobrien    gopt.flags &= ~CFM_FULLY_QUALIFIED_HOSTS;
40079968Sobrien    return 0;
40179968Sobrien  }
40279968Sobrien
40379968Sobrien  fprintf(stderr, "conf: unknown value to fully_qualified_hosts \"%s\"\n", val);
40479968Sobrien  return 1;			/* unknown value */
40579968Sobrien}
40679968Sobrien
40779968Sobrien
40879968Sobrienstatic int
40979968Sobriengopt_hesiod_base(const char *val)
41079968Sobrien{
41179968Sobrien#ifdef HAVE_MAP_HESIOD
41279968Sobrien  gopt.hesiod_base = strdup((char *)val);
41379968Sobrien  return 0;
41479968Sobrien#else /* not HAVE_MAP_HESIOD */
41579968Sobrien  fprintf(stderr, "conf: hesiod_base option ignored.  No Hesiod support available.\n");
41679968Sobrien  return 1;
41779968Sobrien#endif /* not HAVE_MAP_HESIOD */
41879968Sobrien}
41979968Sobrien
42079968Sobrien
42179968Sobrienstatic int
42279968Sobriengopt_karch(const char *val)
42379968Sobrien{
42479968Sobrien  gopt.karch = strdup((char *)val);
42579968Sobrien  return 0;
42679968Sobrien}
42779968Sobrien
42879968Sobrien
42979968Sobrienstatic int
43079968Sobriengopt_pid_file(const char *val)
43179968Sobrien{
43279968Sobrien  gopt.pid_file = strdup((char *)val);
43379968Sobrien  return 0;
43479968Sobrien}
43579968Sobrien
43679968Sobrien
43779968Sobrienstatic int
43879968Sobriengopt_local_domain(const char *val)
43979968Sobrien{
44079968Sobrien  gopt.sub_domain = strdup((char *)val);
44179968Sobrien  return 0;
44279968Sobrien}
44379968Sobrien
44479968Sobrien
44579968Sobrienstatic int
44679968Sobriengopt_ldap_base(const char *val)
44779968Sobrien{
44879968Sobrien#ifdef HAVE_MAP_LDAP
44979968Sobrien  gopt.ldap_base = strdup((char *)val);
45079968Sobrien  return 0;
45179968Sobrien#else /* not HAVE_MAP_LDAP */
45279968Sobrien  fprintf(stderr, "conf: ldap_base option ignored.  No LDAP support available.\n");
45379968Sobrien  return 1;
45479968Sobrien#endif /* not HAVE_MAP_LDAP */
45579968Sobrien}
45679968Sobrien
45779968Sobrien
45879968Sobrienstatic int
45979968Sobriengopt_ldap_cache_seconds(const char *val)
46079968Sobrien{
46179968Sobrien#ifdef HAVE_MAP_LDAP
46279968Sobrien  char *end;
463133936Sobrien
46479968Sobrien  gopt.ldap_cache_seconds = strtol((char *)val, &end, 10);
46579968Sobrien  if (end == val) {
46679968Sobrien    fprintf(stderr, "conf: bad LDAP cache (seconds) option: %s\n",val);
46779968Sobrien    return 1;
46879968Sobrien  }
46979968Sobrien  return 0;
47079968Sobrien#else /* not HAVE_MAP_LDAP */
47179968Sobrien  fprintf(stderr, "conf: ldap_cache option ignored.  No LDAP support available.\n");
47279968Sobrien  return 1;
47379968Sobrien#endif /* not HAVE_MAP_LDAP */
47479968Sobrien}
47579968Sobrien
47679968Sobrien
47779968Sobrienstatic int
47879968Sobriengopt_ldap_cache_maxmem(const char *val)
47979968Sobrien{
48079968Sobrien#ifdef HAVE_MAP_LDAP
48179968Sobrien  char *end;
48279968Sobrien
48379968Sobrien  gopt.ldap_cache_maxmem = strtol((char *)val, &end, 10);
48479968Sobrien  if (end == val) {
48579968Sobrien    fprintf(stderr, "conf: bad LDAP cache (maxmem) option: %s\n",val);
48679968Sobrien    return 1;
48779968Sobrien  }
48879968Sobrien  return 0;
48979968Sobrien#else /* not HAVE_MAP_LDAP */
49079968Sobrien  fprintf(stderr, "conf: ldap_cache option ignored.  No LDAP support available.\n");
49179968Sobrien  return 1;
49279968Sobrien#endif /* not HAVE_MAP_LDAP */
49379968Sobrien}
49479968Sobrien
49579968Sobrien
49679968Sobrienstatic int
49779968Sobriengopt_ldap_hostports(const char *val)
49879968Sobrien{
49979968Sobrien#ifdef HAVE_MAP_LDAP
50079968Sobrien  gopt.ldap_hostports = strdup((char *)val);
50179968Sobrien  return 0;
50279968Sobrien#else /* not HAVE_MAP_LDAP */
50379968Sobrien  fprintf(stderr, "conf: ldap_hostports option ignored.  No LDAP support available.\n");
50479968Sobrien  return 1;
50579968Sobrien#endif /* not HAVE_MAP_LDAP */
50679968Sobrien
50779968Sobrien}
50879968Sobrien
50979968Sobrien
51079968Sobrienstatic int
51179968Sobriengopt_log_file(const char *val)
51279968Sobrien{
51379968Sobrien  gopt.logfile = strdup((char *)val);
514161764Sobrien  return 0;
515161764Sobrien}
51679968Sobrien
51779968Sobrien
51879968Sobrienstatic int
51979968Sobriengopt_log_options(const char *val)
52079968Sobrien{
52179968Sobrien  usage += switch_option(strdup((char *)val));
52279968Sobrien  return 0;
52379968Sobrien}
524161764Sobrien
525161764Sobrien
52679968Sobrienstatic int
52779968Sobriengopt_map_options(const char *val)
52879968Sobrien{
52979968Sobrien  gopt.map_options = strdup((char *)val);
53079968Sobrien  return 0;
53179968Sobrien}
53279968Sobrien
53379968Sobrien
53479968Sobrienstatic int
53579968Sobriengopt_map_type(const char *val)
53679968Sobrien{
53779968Sobrien  /* check if map type exist */
53879968Sobrien  if (!mapc_type_exists(val)) {
53979968Sobrien    fprintf(stderr, "conf: no such map type \"%s\"\n", val);
54079968Sobrien    return 1;
54179968Sobrien  }
54279968Sobrien  gopt.map_type = strdup((char *)val);
54379968Sobrien  return 0;
54479968Sobrien}
54579968Sobrien
54679968Sobrien
54779968Sobrienstatic int
54879968Sobriengopt_mount_type(const char *val)
54979968Sobrien{
55079968Sobrien  if (STREQ(val, "autofs")) {
55179968Sobrien#ifdef HAVE_FS_AUTOFS
55279968Sobrien    gopt.flags |= CFM_MOUNT_TYPE_AUTOFS;
55379968Sobrien    amd_use_autofs++;
55479968Sobrien    return 0;
555133936Sobrien#else /* not HAVE_FS_AUTOFS */
55679968Sobrien    fprintf(stderr, "conf: no autofs support available\n");
55779968Sobrien    return 1;
55879968Sobrien#endif /* not HAVE_FS_AUTOFS */
55979968Sobrien  } else if (STREQ(val, "nfs")) {
56079968Sobrien    gopt.flags &= ~CFM_MOUNT_TYPE_AUTOFS;
56179968Sobrien    return 0;
56279968Sobrien  }
56379968Sobrien
56479968Sobrien  fprintf(stderr, "conf: unknown value to mount_type \"%s\"\n", val);
56579968Sobrien  return 1;			/* unknown value */
56679968Sobrien}
56779968Sobrien
56879968Sobrien
56979968Sobrienstatic int
57079968Sobriengopt_portmap_program(const char *val)
57179968Sobrien{
57279968Sobrien  gopt.portmap_program = atoi(val);
57379968Sobrien  /*
57479968Sobrien   * allow alternate program numbers to be no more than 10 offset from
57579968Sobrien   * official amd program number (300019).
57679968Sobrien   */
577108746Sobrien  if (gopt.portmap_program < AMQ_PROGRAM ||
578108746Sobrien      gopt.portmap_program > AMQ_PROGRAM + 10) {
579108746Sobrien    gopt.portmap_program = AMQ_PROGRAM;
580108746Sobrien    set_amd_program_number(gopt.portmap_program);
58179968Sobrien    fprintf(stderr, "conf: illegal amd program numver \"%s\"\n", val);
58279968Sobrien    return 1;
58379968Sobrien  }
58479968Sobrien
58579968Sobrien  set_amd_program_number(gopt.portmap_program);
58679968Sobrien  return 0;			/* all is OK */
587108746Sobrien}
58879968Sobrien
589108746Sobrien
590108746Sobrienstatic int
591108746Sobriengopt_nfs_retransmit_counter(const char *val)
59279968Sobrien{
593108746Sobrien  gopt.amfs_auto_retrans = atoi(val);
59479968Sobrien  return 0;
59579968Sobrien}
596108746Sobrien
597108746Sobrien
598108746Sobrienstatic int
59979968Sobriengopt_nfs_retry_interval(const char *val)
60079968Sobrien{
60179968Sobrien  gopt.amfs_auto_timeo = atoi(val);
60279968Sobrien  return 0;
60379968Sobrien}
60479968Sobrien
60579968Sobrien
60679968Sobrienstatic int
60779968Sobriengopt_nis_domain(const char *val)
60879968Sobrien{
60979968Sobrien#ifdef HAVE_MAP_NIS
61079968Sobrien  gopt.nis_domain = strdup((char *)val);
61179968Sobrien  return 0;
61279968Sobrien#else /* not HAVE_MAP_NIS */
61379968Sobrien  fprintf(stderr, "conf: nis_domain option ignored.  No NIS support available.\n");
614108746Sobrien  return 1;
61579968Sobrien#endif /* not HAVE_MAP_NIS */
61679968Sobrien}
61779968Sobrien
61879968Sobrien
619108746Sobrienstatic int
620108746Sobriengopt_normalize_hostnames(const char *val)
621108746Sobrien{
622108746Sobrien  if (STREQ(val, "yes")) {
623108746Sobrien    gopt.flags |= CFM_NORMALIZE_HOSTNAMES;
624108746Sobrien    return 0;
62579968Sobrien  } else if (STREQ(val, "no")) {
62679968Sobrien    gopt.flags &= ~CFM_NORMALIZE_HOSTNAMES;
62779968Sobrien    return 0;
62879968Sobrien  }
62979968Sobrien
63079968Sobrien  fprintf(stderr, "conf: unknown value to normalize_hostnames \"%s\"\n", val);
63179968Sobrien  return 1;			/* unknown value */
63279968Sobrien}
63379968Sobrien
63479968Sobrien
63579968Sobrienstatic int
63679968Sobriengopt_os(const char *val)
63779968Sobrien{
63879968Sobrien  gopt.op_sys = strdup((char *)val);
63979968Sobrien  return 0;
64079968Sobrien}
64179968Sobrien
64279968Sobrien
64379968Sobrienstatic int
64479968Sobriengopt_osver(const char *val)
64579968Sobrien{
646108746Sobrien  gopt.op_sys_ver = strdup((char *)val);
64779968Sobrien  return 0;
64879968Sobrien}
64979968Sobrien
65079968Sobrien
651108746Sobrienstatic int
652108746Sobriengopt_plock(const char *val)
653108746Sobrien{
654108746Sobrien  if (STREQ(val, "yes")) {
655108746Sobrien    gopt.flags |= CFM_PROCESS_LOCK;
656108746Sobrien    return 0;
65779968Sobrien  } else if (STREQ(val, "no")) {
65879968Sobrien    gopt.flags &= ~CFM_PROCESS_LOCK;
65979968Sobrien    return 0;
66079968Sobrien  }
66179968Sobrien
66279968Sobrien  fprintf(stderr, "conf: unknown value to plock \"%s\"\n", val);
66379968Sobrien  return 1;			/* unknown value */
66479968Sobrien}
66579968Sobrien
66679968Sobrien
66779968Sobrienstatic int
66879968Sobriengopt_print_pid(const char *val)
66979968Sobrien{
67079968Sobrien  if (STREQ(val, "yes")) {
67179968Sobrien    gopt.flags |= CFM_PRINT_PID;
67279968Sobrien    return 0;
67379968Sobrien  } else if (STREQ(val, "no")) {
67479968Sobrien    gopt.flags &= ~CFM_PRINT_PID;
67579968Sobrien    return 0;
67679968Sobrien  }
67779968Sobrien
67879968Sobrien  fprintf(stderr, "conf: unknown value to print_pid \"%s\"\n", val);
67979968Sobrien  return 1;			/* unknown value */
68079968Sobrien}
68179968Sobrien
682108746Sobrien
68379968Sobrienstatic int
68479968Sobriengopt_print_version(const char *val)
68579968Sobrien{
68679968Sobrien  if (STREQ(val, "yes")) {
68779968Sobrien    fputs(get_version_string(), stderr);
68879968Sobrien    return 0;
68979968Sobrien  } else if (STREQ(val, "no")) {
69079968Sobrien    return 0;
69179968Sobrien  }
69279968Sobrien
69379968Sobrien  fprintf(stderr, "conf: unknown value to print_version \"%s\"\n", val);
69479968Sobrien  return 1;			/* unknown value */
69579968Sobrien}
69679968Sobrien
69779968Sobrien
69879968Sobrienstatic int
69979968Sobriengopt_restart_mounts(const char *val)
70079968Sobrien{
70179968Sobrien  if (STREQ(val, "yes")) {
70279968Sobrien    gopt.flags |= CFM_RESTART_EXISTING_MOUNTS;
70379968Sobrien    return 0;
70479968Sobrien  } else if (STREQ(val, "no")) {
70579968Sobrien    gopt.flags &= ~CFM_RESTART_EXISTING_MOUNTS;
70679968Sobrien    return 0;
70779968Sobrien  }
70879968Sobrien
70979968Sobrien  fprintf(stderr, "conf: unknown value to restart_mounts \"%s\"\n", val);
71079968Sobrien  return 1;			/* unknown value */
71179968Sobrien}
71279968Sobrien
71379968Sobrien
71479968Sobrienstatic int
71579968Sobriengopt_search_path(const char *val)
71679968Sobrien{
71779968Sobrien  gopt.search_path = strdup((char *)val);
71879968Sobrien  return 0;
71979968Sobrien}
72079968Sobrien
72179968Sobrien
72279968Sobrienstatic int
72379968Sobriengopt_selectors_on_default(const char *val)
72479968Sobrien{
72579968Sobrien  if (STREQ(val, "yes")) {
72679968Sobrien    gopt.flags |= CFM_ENABLE_DEFAULT_SELECTORS;
72779968Sobrien    return 0;
72879968Sobrien  } else if (STREQ(val, "no")) {
72979968Sobrien    gopt.flags &= ~CFM_ENABLE_DEFAULT_SELECTORS;
73079968Sobrien    return 0;
73179968Sobrien  }
73279968Sobrien
73379968Sobrien  fprintf(stderr, "conf: unknown value to enable_default_selectors \"%s\"\n", val);
73479968Sobrien  return 1;			/* unknown value */
73579968Sobrien}
73679968Sobrien
73779968Sobrien
73879968Sobrienstatic int
73979968Sobriengopt_show_statfs_entries(const char *val)
74079968Sobrien{
74179968Sobrien  if (STREQ(val, "yes")) {
74279968Sobrien    gopt.flags |= CFM_SHOW_STATFS_ENTRIES;
74379968Sobrien    return 0;
74479968Sobrien  } else if (STREQ(val, "no")) {
74579968Sobrien    gopt.flags &= ~CFM_SHOW_STATFS_ENTRIES;
74679968Sobrien    return 0;
74779968Sobrien  }
74879968Sobrien
74979968Sobrien  fprintf(stderr, "conf: unknown value to show_statfs_entries \"%s\"\n", val);
75079968Sobrien  return 1;			/* unknown value */
75179968Sobrien}
75279968Sobrien
75379968Sobrien
75479968Sobrienstatic int
75579968Sobriengopt_unmount_on_exit(const char *val)
75679968Sobrien{
75779968Sobrien  if (STREQ(val, "yes")) {
75879968Sobrien    gopt.flags |= CFM_UNMOUNT_ON_EXIT;
75979968Sobrien    return 0;
76079968Sobrien  } else if (STREQ(val, "no")) {
76179968Sobrien    gopt.flags &= ~CFM_UNMOUNT_ON_EXIT;
76279968Sobrien    return 0;
76379968Sobrien  }
76479968Sobrien
76579968Sobrien  fprintf(stderr, "conf: unknown value to unmount_on_exit \"%s\"\n", val);
76679968Sobrien  return 1;			/* unknown value */
76779968Sobrien}
76879968Sobrien
76979968Sobrien
77079968Sobrien/*
77179968Sobrien * Collect one entry for a regular map
77279968Sobrien */
77379968Sobrienstatic int
77479968Sobrienprocess_regular_option(const char *section, const char *key, const char *val, cf_map_t *cfm)
77579968Sobrien{
77679968Sobrien  /* ensure that val is valid */
77779968Sobrien  if (!section || section[0] == '\0' ||
77879968Sobrien      !key || key[0] == '\0' ||
77979968Sobrien      !val || val[0] == '\0' ||
78079968Sobrien      !cfm) {
78179968Sobrien    fprintf(stderr, "conf: process_regular_option: null entries\n");
78279968Sobrien    return 1;
78379968Sobrien  }
78479968Sobrien
78579968Sobrien  /* check if initializing a new map */
78679968Sobrien  if (!cfm->cfm_dir)
78779968Sobrien    cfm->cfm_dir = strdup((char *)section);
78879968Sobrien
78979968Sobrien  /* check for each possible field */
79079968Sobrien  if (STREQ(key, "browsable_dirs"))
79179968Sobrien    return ropt_browsable_dirs(val, cfm);
79279968Sobrien
79379968Sobrien  if (STREQ(key, "map_name"))
79479968Sobrien    return ropt_map_name(val, cfm);
79579968Sobrien
79679968Sobrien  if (STREQ(key, "map_options"))
79779968Sobrien    return ropt_map_options(val, cfm);
79879968Sobrien
79979968Sobrien  if (STREQ(key, "map_type"))
80079968Sobrien    return ropt_map_type(val, cfm);
80179968Sobrien
80279968Sobrien  if (STREQ(key, "mount_type"))
80379968Sobrien    return ropt_mount_type(val, cfm);
80479968Sobrien
80579968Sobrien  if (STREQ(key, "search_path"))
80679968Sobrien    return ropt_search_path(val, cfm);
80779968Sobrien
80879968Sobrien  if (STREQ(key, "tag"))
80979968Sobrien    return ropt_tag(val, cfm);
81079968Sobrien
81179968Sobrien  fprintf(stderr, "conf: unknown regular key \"%s\" for section \"%s\"\n",
81279968Sobrien	  key, section);
81379968Sobrien  return 1;			/* failed to match any command */
81479968Sobrien}
81579968Sobrien
81679968Sobrien
81779968Sobrienstatic int
81879968Sobrienropt_browsable_dirs(const char *val, cf_map_t *cfm)
81979968Sobrien{
82079968Sobrien  if (STREQ(val, "full")) {
82179968Sobrien    cfm->cfm_flags |= CFM_BROWSABLE_DIRS_FULL;
82279968Sobrien    return 0;
82379968Sobrien  } else if (STREQ(val, "yes")) {
82479968Sobrien    cfm->cfm_flags |= CFM_BROWSABLE_DIRS;
82579968Sobrien    return 0;
82679968Sobrien  } else if (STREQ(val, "no")) {
82779968Sobrien    cfm->cfm_flags &= ~CFM_BROWSABLE_DIRS;
82879968Sobrien    return 0;
82979968Sobrien  }
83079968Sobrien
83179968Sobrien  fprintf(stderr, "conf: unknown value to browsable_dirs \"%s\"\n", val);
83279968Sobrien  return 1;			/* unknown value */
83379968Sobrien}
83479968Sobrien
83579968Sobrien
83679968Sobrienstatic int
83779968Sobrienropt_map_name(const char *val, cf_map_t *cfm)
83879968Sobrien{
83979968Sobrien  cfm->cfm_name = strdup((char *)val);
84079968Sobrien  return 0;
84179968Sobrien}
84279968Sobrien
84379968Sobrien
84479968Sobrienstatic int
84579968Sobrienropt_map_options(const char *val, cf_map_t *cfm)
84679968Sobrien{
84779968Sobrien  cfm->cfm_opts = strdup((char *)val);
84879968Sobrien  return 0;
84979968Sobrien}
85079968Sobrien
85179968Sobrien
85279968Sobrienstatic int
85379968Sobrienropt_map_type(const char *val, cf_map_t *cfm)
85479968Sobrien{
85579968Sobrien  /* check if map type exist */
85679968Sobrien  if (!mapc_type_exists(val)) {
85779968Sobrien    fprintf(stderr, "conf: no such map type \"%s\"\n", val);
85879968Sobrien    return 1;
85979968Sobrien  }
86079968Sobrien  cfm->cfm_type = strdup((char *)val);
86179968Sobrien  return 0;
86279968Sobrien}
86379968Sobrien
86479968Sobrien
86579968Sobrienstatic int
86679968Sobrienropt_mount_type(const char *val, cf_map_t *cfm)
86779968Sobrien{
86879968Sobrien  if (STREQ(val, "autofs")) {
86979968Sobrien#ifdef HAVE_FS_AUTOFS
87079968Sobrien    cfm->cfm_flags |= CFM_MOUNT_TYPE_AUTOFS;
87179968Sobrien    amd_use_autofs++;
87279968Sobrien    return 0;
87379968Sobrien#else /* not HAVE_FS_AUTOFS */
87479968Sobrien    fprintf(stderr, "conf: no autofs support available\n");
87579968Sobrien    return 1;
87679968Sobrien#endif /* not HAVE_FS_AUTOFS */
87779968Sobrien  } else if (STREQ(val, "nfs")) {
87879968Sobrien    cfm->cfm_flags &= ~CFM_MOUNT_TYPE_AUTOFS;
87979968Sobrien    return 0;
88079968Sobrien  }
88179968Sobrien
88279968Sobrien  fprintf(stderr, "conf: unknown value to mount_type \"%s\"\n", val);
88379968Sobrien  return 1;			/* unknown value */
88479968Sobrien}
88579968Sobrien
88679968Sobrien
887108746Sobrienstatic int
88879968Sobrienropt_search_path(const char *val, cf_map_t *cfm)
88979968Sobrien{
890133936Sobrien  cfm->cfm_search_path = strdup((char *)val);
891133936Sobrien  return 0;
89279968Sobrien}
89379968Sobrien
89479968Sobrien
89579968Sobrienstatic int
89679968Sobrienropt_tag(const char *val, cf_map_t *cfm)
89779968Sobrien{
89879968Sobrien  cfm->cfm_tag = strdup((char *)val);
89979968Sobrien  return 0;
90079968Sobrien}
901133936Sobrien
902133936Sobrien
90379968Sobrien/*
904133936Sobrien * Process one collected map.
90579968Sobrien */
90679968Sobrienstatic int
90779968Sobrienprocess_regular_map(cf_map_t *cfm)
90879968Sobrien{
90979968Sobrien
91079968Sobrien  if (!cfm->cfm_name) {
91179968Sobrien    fprintf(stderr, "conf: map_name must be defined for map \"%s\"\n", cfm->cfm_dir);
91279968Sobrien    return 1;
91379968Sobrien  }
91479968Sobrien  /*
91579968Sobrien   * If map has no tag defined, process the map.
91679968Sobrien   * If no conf_tag was set in amd -T, process all untagged entries.
91779968Sobrien   * If a tag is defined, then process it only if it matches the map tag.
91879968Sobrien   */
91979968Sobrien  if (!cfm->cfm_tag ||
92079968Sobrien      (conf_tag && STREQ(cfm->cfm_tag, conf_tag))) {
92179968Sobrien#ifdef DEBUG_CONF
92279968Sobrien    fprintf(stderr, "processing map %s (flags=0x%x)...\n",
92379968Sobrien	    cfm->cfm_dir, cfm->cfm_flags);
92479968Sobrien#endif /* DEBUG_CONF */
925108746Sobrien    root_newmap(cfm->cfm_dir,
926108746Sobrien		cfm->cfm_opts ? cfm->cfm_opts : "",
927108746Sobrien		cfm->cfm_name,
92879968Sobrien		cfm);
92979968Sobrien  } else {
93079968Sobrien    fprintf(stderr, "skipping map %s...\n", cfm->cfm_dir);
93179968Sobrien  }
93279968Sobrien
93379968Sobrien  reset_cf_map(cfm);
93479968Sobrien  return 0;
93579968Sobrien}
93679968Sobrien
93779968Sobrien
93879968Sobrien/*
93979968Sobrien * Process last map in conf file (if any)
940108746Sobrien */
94179968Sobrienint
942108746Sobrienprocess_last_regular_map(void)
94379968Sobrien{
94479968Sobrien  /*
94579968Sobrien   * If the amd.conf file only has a [global] section (pretty useless
94679968Sobrien   * IMHO), do not try to process a map that does not exist.
94779968Sobrien   */
94879968Sobrien  if (!cur_map.cfm_dir)
94979968Sobrien    return 0;
95079968Sobrien  return process_regular_map(&cur_map);
95179968Sobrien}
95279968Sobrien