xref: /netbsd-src/external/bsd/am-utils/dist/amd/conf.c (revision 8bae5d409deb915cf7c8f0539fae22ff2cb8a313)
1 /*	$NetBSD: conf.c,v 1.1.1.3 2015/01/17 16:34:15 christos Exp $	*/
2 
3 /*
4  * Copyright (c) 1997-2014 Erez Zadok
5  * Copyright (c) 1990 Jan-Simon Pendry
6  * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
7  * Copyright (c) 1990 The Regents of the University of California.
8  * All rights reserved.
9  *
10  * This code is derived from software contributed to Berkeley by
11  * Jan-Simon Pendry at Imperial College, London.
12  *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions
15  * are met:
16  * 1. Redistributions of source code must retain the above copyright
17  *    notice, this list of conditions and the following disclaimer.
18  * 2. Redistributions in binary form must reproduce the above copyright
19  *    notice, this list of conditions and the following disclaimer in the
20  *    documentation and/or other materials provided with the distribution.
21  * 3. Neither the name of the University nor the names of its contributors
22  *    may be used to endorse or promote products derived from this software
23  *    without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35  * SUCH DAMAGE.
36  *
37  *
38  * File: am-utils/amd/conf.c
39  *
40  */
41 
42 /*
43  * Functions to handle the configuration file.
44  */
45 
46 #ifdef HAVE_CONFIG_H
47 # include <config.h>
48 #endif /* HAVE_CONFIG_H */
49 #include <am_defs.h>
50 #include <amd.h>
51 
52 
53 /*
54  * MACROS:
55  */
56 /* Turn on to show some info about maps being configured */
57 /* #define DEBUG_CONF */
58 
59 /*
60  * TYPEDEFS:
61  */
62 typedef int (*OptFuncPtr)(const char *);
63 
64 /*
65  * STRUCTURES:
66  */
67 struct _func_map {
68   char *name;
69   OptFuncPtr func;
70 };
71 
72 /*
73  * FORWARD DECLARATIONS:
74  */
75 static int gopt_arch(const char *val);
76 static int gopt_auto_attrcache(const char *val);
77 static int gopt_auto_dir(const char *val);
78 static int gopt_auto_nfs_version(const char *val);
79 static int gopt_autofs_use_lofs(const char *val);
80 static int gopt_browsable_dirs(const char *val);
81 static int gopt_cache_duration(const char *val);
82 static int gopt_cluster(const char *val);
83 static int gopt_debug_mtab_file(const char *val);
84 static int gopt_debug_options(const char *val);
85 static int gopt_dismount_interval(const char *val);
86 static int gopt_domain_strip(const char *val);
87 static int gopt_exec_map_timeout(const char *val);
88 static int gopt_forced_unmounts(const char *val);
89 static int gopt_full_os(const char *val);
90 static int gopt_fully_qualified_hosts(const char *val);
91 static int gopt_hesiod_base(const char *val);
92 static int gopt_karch(const char *val);
93 static int gopt_ldap_base(const char *val);
94 static int gopt_ldap_cache_maxmem(const char *val);
95 static int gopt_ldap_cache_seconds(const char *val);
96 static int gopt_ldap_hostports(const char *val);
97 static int gopt_ldap_proto_version(const char *val);
98 static int gopt_local_domain(const char *val);
99 static int gopt_localhost_address(const char *val);
100 static int gopt_log_file(const char *val);
101 static int gopt_log_options(const char *val);
102 static int gopt_map_defaults(const char *val);
103 static int gopt_map_options(const char *val);
104 static int gopt_map_reload_interval(const char *val);
105 static int gopt_map_type(const char *val);
106 static int gopt_mount_type(const char *val);
107 static int gopt_pid_file(const char *val);
108 static int gopt_portmap_program(const char *val);
109 static int gopt_preferred_amq_port(const char *val);
110 static int gopt_nfs_allow_any_interface(const char *val);
111 static int gopt_nfs_allow_insecure_port(const char *val);
112 static int gopt_nfs_proto(const char *val);
113 static int gopt_nfs_retransmit_counter(const char *val);
114 static int gopt_nfs_retransmit_counter_udp(const char *val);
115 static int gopt_nfs_retransmit_counter_tcp(const char *val);
116 static int gopt_nfs_retransmit_counter_toplvl(const char *val);
117 static int gopt_nfs_retry_interval(const char *val);
118 static int gopt_nfs_retry_interval_udp(const char *val);
119 static int gopt_nfs_retry_interval_tcp(const char *val);
120 static int gopt_nfs_retry_interval_toplvl(const char *val);
121 static int gopt_nfs_vers(const char *val);
122 static int gopt_nfs_vers_ping(const char *val);
123 static int gopt_nis_domain(const char *val);
124 static int gopt_normalize_hostnames(const char *val);
125 static int gopt_normalize_slashes(const char *val);
126 static int gopt_os(const char *val);
127 static int gopt_osver(const char *val);
128 static int gopt_plock(const char *val);
129 static int gopt_print_pid(const char *val);
130 static int gopt_print_version(const char *val);
131 static int gopt_restart_mounts(const char *val);
132 static int gopt_search_path(const char *val);
133 static int gopt_selectors_in_defaults(const char *val);
134 static int gopt_show_statfs_entries(const char *val);
135 static int gopt_sun_map_syntax(const char *val);
136 static int gopt_truncate_log(const char *val);
137 static int gopt_unmount_on_exit(const char *val);
138 static int gopt_use_tcpwrappers(const char *val);
139 static int gopt_vendor(const char *val);
140 static int process_global_option(const char *key, const char *val);
141 static int process_one_regular_map(const cf_map_t *cfm);
142 static int process_regular_option(const char *section, const char *key, const char *val, cf_map_t *cfm);
143 static int ropt_browsable_dirs(const char *val, cf_map_t *cfm);
144 static int ropt_map_name(const char *val, cf_map_t *cfm);
145 static int ropt_map_defaults(const char *val, cf_map_t *cfm);
146 static int ropt_map_options(const char *val, cf_map_t *cfm);
147 static int ropt_map_type(const char *val, cf_map_t *cfm);
148 static int ropt_mount_type(const char *val, cf_map_t *cfm);
149 static int ropt_search_path(const char *val, cf_map_t *cfm);
150 static int ropt_sun_map_syntax(const char *val, cf_map_t *cfm);
151 static int ropt_tag(const char *val, cf_map_t *cfm);
152 static void init_cf_map(cf_map_t *cfm);
153 
154 
155 /*
156  * STATIC VARIABLES:
157  */
158 static cf_map_t *head_map, *cur_map;
159 
160 static struct _func_map glob_functable[] = {
161   {"arch",			gopt_arch},
162   {"auto_attrcache",		gopt_auto_attrcache},
163   {"auto_dir",			gopt_auto_dir},
164   {"auto_nfs_version",		gopt_auto_nfs_version},
165   {"autofs_use_lofs",		gopt_autofs_use_lofs},
166   {"browsable_dirs",		gopt_browsable_dirs},
167   {"cache_duration",		gopt_cache_duration},
168   {"cluster",			gopt_cluster},
169   {"debug_mtab_file",           gopt_debug_mtab_file},
170   {"debug_options",		gopt_debug_options},
171   {"dismount_interval",		gopt_dismount_interval},
172   {"domain_strip",		gopt_domain_strip},
173   {"exec_map_timeout",		gopt_exec_map_timeout},
174   {"forced_unmounts",		gopt_forced_unmounts},
175   {"fully_qualified_hosts",	gopt_fully_qualified_hosts},
176   {"full_os",			gopt_full_os},
177   {"hesiod_base",		gopt_hesiod_base},
178   {"karch",			gopt_karch},
179   {"ldap_base",			gopt_ldap_base},
180   {"ldap_cache_maxmem",		gopt_ldap_cache_maxmem},
181   {"ldap_cache_seconds",	gopt_ldap_cache_seconds},
182   {"ldap_hostports",		gopt_ldap_hostports},
183   {"ldap_proto_version",	gopt_ldap_proto_version},
184   {"local_domain",		gopt_local_domain},
185   {"localhost_address",		gopt_localhost_address},
186   {"log_file",			gopt_log_file},
187   {"log_options",		gopt_log_options},
188   {"map_defaults",		gopt_map_defaults},
189   {"map_options",		gopt_map_options},
190   {"map_reload_interval",	gopt_map_reload_interval},
191   {"map_type",			gopt_map_type},
192   {"mount_type",		gopt_mount_type},
193   {"pid_file",			gopt_pid_file},
194   {"portmap_program",		gopt_portmap_program},
195   {"preferred_amq_port",	gopt_preferred_amq_port},
196   {"nfs_allow_any_interface",	gopt_nfs_allow_any_interface},
197   {"nfs_allow_insecure_port",	gopt_nfs_allow_insecure_port},
198   {"nfs_proto",			gopt_nfs_proto},
199   {"nfs_retransmit_counter",	gopt_nfs_retransmit_counter},
200   {"nfs_retransmit_counter_udp",	gopt_nfs_retransmit_counter_udp},
201   {"nfs_retransmit_counter_tcp",	gopt_nfs_retransmit_counter_tcp},
202   {"nfs_retransmit_counter_toplvl",	gopt_nfs_retransmit_counter_toplvl},
203   {"nfs_retry_interval",	gopt_nfs_retry_interval},
204   {"nfs_retry_interval_udp",	gopt_nfs_retry_interval_udp},
205   {"nfs_retry_interval_tcp",	gopt_nfs_retry_interval_tcp},
206   {"nfs_retry_interval_toplvl",	gopt_nfs_retry_interval_toplvl},
207   {"nfs_vers",			gopt_nfs_vers},
208   {"nfs_vers_ping",		gopt_nfs_vers_ping},
209   {"nis_domain",		gopt_nis_domain},
210   {"normalize_hostnames",	gopt_normalize_hostnames},
211   {"normalize_slashes",		gopt_normalize_slashes},
212   {"os",			gopt_os},
213   {"osver",			gopt_osver},
214   {"plock",			gopt_plock},
215   {"print_pid",			gopt_print_pid},
216   {"print_version",		gopt_print_version},
217   {"restart_mounts",		gopt_restart_mounts},
218   {"search_path",		gopt_search_path},
219   {"selectors_on_default",	gopt_selectors_in_defaults},
220   {"selectors_in_defaults",	gopt_selectors_in_defaults},
221   {"show_statfs_entries",	gopt_show_statfs_entries},
222   {"sun_map_syntax",		gopt_sun_map_syntax},
223   {"truncate_log",		gopt_truncate_log},
224   {"unmount_on_exit",		gopt_unmount_on_exit},
225   {"use_tcpwrappers",		gopt_use_tcpwrappers},
226   {"vendor",			gopt_vendor},
227   {NULL, NULL}
228 };
229 
230 
231 /*
232  * Initialize a map from [global] defaults.
233  */
234 static void
init_cf_map(cf_map_t * cfm)235 init_cf_map(cf_map_t *cfm)
236 {
237   if (!cfm)
238     return;
239 
240   /*
241    * Initialize a regular map's flags and other variables from the
242    * global ones, so that they are applied to all maps.  Of course, each map
243    * can then override the flags individually.
244    *
245    * NOTES:
246    * (1): Will only work for maps that appear after [global].
247    * (2): I'm assigning pointers directly from the global map.
248    */
249 
250   /* initialize map_type from [global] */
251   cfm->cfm_type = gopt.map_type;
252 
253   /* initialize map_defaults from [global] */
254   cfm->cfm_defaults = gopt.map_defaults;
255 
256   /* initialize map_opts from [global] */
257   cfm->cfm_opts = gopt.map_options;
258 
259   /* initialize search_path from [global] */
260   cfm->cfm_search_path = gopt.search_path;
261 
262   /*
263    * Initialize flags that are common both to [global] and a local map
264    * (that is, they could be inherited from the global section).
265    */
266   cfm->cfm_flags = gopt.flags & (CFM_BROWSABLE_DIRS |
267 				 CFM_BROWSABLE_DIRS_FULL |
268 				 CFM_MOUNT_TYPE_AUTOFS |
269 				 CFM_SELECTORS_IN_DEFAULTS |
270 				 CFM_SUN_MAP_SYNTAX );
271 }
272 
273 
274 /*
275  * Process configuration file options (called from YACC parser).
276  * Return 0 if OK, 1 otherwise.
277  */
278 int
set_conf_kv(const char * section,const char * key,const char * val)279 set_conf_kv(const char *section, const char *key, const char *val)
280 {
281   int ret;
282 
283 #ifdef DEBUG_CONF
284   fprintf(stderr, "set_conf_kv: section=%s, key=%s, val=%s\n",
285 	  section, key, val);
286 #endif /* DEBUG_CONF */
287 
288   /*
289    * If global section, process kv pairs one at a time.
290    */
291   if (STREQ(section, "global")) {
292     /*
293      * Check if a regular map was configured before "global",
294      * and warn about it.
295      */
296     if (cur_map && cur_map->cfm_dir) {
297       static short printed_this_error;
298       if (!printed_this_error) {
299 	fprintf(stderr, "found regular map \"%s\" before global one.\n",
300 		cur_map->cfm_dir);
301 	printed_this_error = 1;
302       }
303     }
304 
305     /* process the global option first */
306     ret = process_global_option(key, val);
307 
308     /* return status from the processing of the global option */
309     return ret;
310   }
311 
312   /*
313    * Otherwise we found a non-global option: store it after some testing.
314    */
315 
316   /* initialize (static) global list head and current map pointer */
317   if (!head_map && !cur_map) {
318     cur_map = CALLOC(cf_map_t);
319     if (!cur_map) {
320       perror("calloc");
321       exit(1);
322     }
323     /* initialize first head map from global defaults */
324     init_cf_map(cur_map);
325     head_map = cur_map;
326   }
327 
328   /* check if we found a new map, then allocate and initialize it */
329   if (cur_map->cfm_dir && !STREQ(cur_map->cfm_dir, section)) {
330     /* allocate new map struct */
331     cf_map_t *tmp_map = CALLOC(cf_map_t);
332     if (!tmp_map) {
333       perror("calloc");
334       exit(1);
335     }
336     /* initialize it from global defaults */
337     init_cf_map(tmp_map);
338     /* append it to end of linked list */
339     cur_map->cfm_next = tmp_map;
340     cur_map = tmp_map;
341   }
342 
343   /* now process a single entry of a regular map */
344   return process_regular_option(section, key, val, cur_map);
345 }
346 
347 
348 /*
349  * Process global section of configuration file options.
350  * Return 0 upon success, 1 otherwise.
351  */
352 static int
process_global_option(const char * key,const char * val)353 process_global_option(const char *key, const char *val)
354 {
355   struct _func_map *gfp;
356 
357   /* ensure that val is valid */
358   if (!val || val[0] == '\0')
359     return 1;
360 
361   /*
362    * search for global function.
363    */
364   for (gfp = glob_functable; gfp->name; gfp++)
365     if (FSTREQ(gfp->name, key))
366       return (gfp->func)(val);
367 
368   fprintf(stderr, "conf: unknown global key: \"%s\"\n", key);
369   return 1;			/* failed to match any command */
370 }
371 
372 
373 static int
gopt_arch(const char * val)374 gopt_arch(const char *val)
375 {
376   gopt.arch = xstrdup(val);
377   return 0;
378 }
379 
380 
381 static int
gopt_auto_attrcache(const char * val)382 gopt_auto_attrcache(const char *val)
383 {
384   gopt.auto_attrcache = atoi(val);
385   if (gopt.auto_attrcache < 0) {
386     fprintf(stderr, "conf: bad attrcache value: \"%s\"\n", val);
387     return 1;
388   }
389   return 0;
390 }
391 
392 
393 static int
gopt_auto_dir(const char * val)394 gopt_auto_dir(const char *val)
395 {
396   gopt.auto_dir = xstrdup(val);
397   return 0;
398 }
399 
400 static int
gopt_auto_nfs_version(const char * val)401 gopt_auto_nfs_version(const char *val)
402 {
403   if (strcmp(val, "2") == 0)
404     nfs_dispatcher = nfs_program_2;
405   else if (strcmp(val, "3") == 0)
406     nfs_dispatcher = nfs_program_3;
407   else {
408     fprintf(stderr, "conf: bad auto nfs version : \"%s\"\n", val);
409     return 1;
410   }
411   return 0;
412 }
413 
414 static int
gopt_autofs_use_lofs(const char * val)415 gopt_autofs_use_lofs(const char *val)
416 {
417   if (STREQ(val, "yes")) {
418     gopt.flags |= CFM_AUTOFS_USE_LOFS;
419     return 0;
420   } else if (STREQ(val, "no")) {
421     gopt.flags &= ~CFM_AUTOFS_USE_LOFS;
422     return 0;
423   }
424 
425   fprintf(stderr, "conf: unknown value to autofs_use_lofs \"%s\"\n", val);
426   return 1;			/* unknown value */
427 }
428 
429 
430 static int
gopt_browsable_dirs(const char * val)431 gopt_browsable_dirs(const char *val)
432 {
433   if (STREQ(val, "full")) {
434     gopt.flags |= CFM_BROWSABLE_DIRS_FULL;
435     return 0;
436   } else if (STREQ(val, "yes")) {
437     gopt.flags |= CFM_BROWSABLE_DIRS;
438     return 0;
439   } else if (STREQ(val, "no")) {
440     gopt.flags &= ~CFM_BROWSABLE_DIRS;
441     return 0;
442   }
443 
444   fprintf(stderr, "conf: unknown value to browsable_dirs \"%s\"\n", val);
445   return 1;			/* unknown value */
446 }
447 
448 
449 static int
gopt_cache_duration(const char * val)450 gopt_cache_duration(const char *val)
451 {
452   gopt.am_timeo = atoi(val);
453   if (gopt.am_timeo <= 0)
454     gopt.am_timeo = AM_TTL;
455   return 0;
456 }
457 
458 
459 static int
gopt_cluster(const char * val)460 gopt_cluster(const char *val)
461 {
462   gopt.cluster = xstrdup(val);
463   return 0;
464 }
465 
466 
467 static int
gopt_debug_mtab_file(const char * val)468 gopt_debug_mtab_file(const char *val)
469 {
470   gopt.debug_mtab_file = xstrdup(val);
471   return 0;
472 }
473 
474 
475 static int
gopt_debug_options(const char * val)476 gopt_debug_options(const char *val)
477 {
478 #ifdef DEBUG
479   usage += debug_option((char *)val);
480   return 0;
481 #else /* not DEBUG */
482   fprintf(stderr, "%s: not compiled with DEBUG option -- sorry.\n",
483 	  am_get_progname());
484   return 1;
485 #endif /* not DEBUG */
486 }
487 
488 
489 static int
gopt_dismount_interval(const char * val)490 gopt_dismount_interval(const char *val)
491 {
492   gopt.am_timeo_w = atoi(val);
493   if (gopt.am_timeo_w <= 0)
494     gopt.am_timeo_w = AM_TTL_W;
495   return 0;
496 }
497 
498 
499 static int
gopt_domain_strip(const char * val)500 gopt_domain_strip(const char *val)
501 {
502   if (STREQ(val, "yes")) {
503     gopt.flags |= CFM_DOMAIN_STRIP;
504     return 0;
505   } else if (STREQ(val, "no")) {
506     gopt.flags &= ~CFM_DOMAIN_STRIP;
507     return 0;
508   }
509 
510   fprintf(stderr, "conf: unknown value to domain_strip \"%s\"\n", val);
511   return 1;                     /* unknown value */
512 }
513 
514 
515 static int
gopt_exec_map_timeout(const char * val)516 gopt_exec_map_timeout(const char *val)
517 {
518   gopt.exec_map_timeout = atoi(val);
519   if (gopt.exec_map_timeout <= 0)
520     gopt.exec_map_timeout = AMFS_EXEC_MAP_TIMEOUT; /* default exec map timeout */
521   return 0;
522 }
523 
524 
525 static int
gopt_forced_unmounts(const char * val)526 gopt_forced_unmounts(const char *val)
527 {
528   if (STREQ(val, "yes")) {
529 #if !defined(MNT2_GEN_OPT_DETACH) && !defined(MNT2_GEN_OPT_FORCE)
530     fprintf(stderr, "conf: forced_unmounts unsupported on this system.\n");
531     return 1;
532 #else /* defined(MNT2_GEN_OPT_DETACH) || defined(MNT2_GEN_OPT_FORCE) */
533 # ifdef __linux__
534     /*
535      * HACK ALERT: Linux has had MNT_FORCE since 2.2, but it hasn't gotten
536      * stable until 2.4.  And it had MNT_DETACH since 2.4, but it hasn't
537      * gotten stable since 2.6.  So alert users if they're trying to use a
538      * feature that may not work well on their older kernel.
539      */
540     {
541       struct utsname un;
542       if (uname(&un) >= 0) {
543 #  ifdef MNT2_GEN_OPT_FORCE
544 	if (strcmp(un.release, "2.4.0") < 0)
545 	  fprintf(stderr, "warning: forced-unmounts (MNT_FORCE) may not work well before 2.4.0\n");
546 #  endif /* MNT2_GEN_OPT_FORCE */
547 #  ifdef MNT2_GEN_OPT_DETACH
548 	if (strcmp(un.release, "2.6.0") < 0)
549 	  fprintf(stderr, "warning: lazy-unmounts (MNT_DETACH) may not work well before 2.6.0\n");
550 #  endif /* MNT2_GEN_OPT_DETACH */
551       }
552     }
553 # endif /* __linux__ */
554     gopt.flags |= CFM_FORCED_UNMOUNTS;
555     return 0;
556 #endif /* defined(MNT2_GEN_OPT_DETACH) || defined(MNT2_GEN_OPT_FORCE) */
557   } else if (STREQ(val, "no")) {
558     gopt.flags &= ~CFM_FORCED_UNMOUNTS;
559     return 0;
560   }
561 
562   fprintf(stderr, "conf: unknown value to unmount_on_exit \"%s\"\n", val);
563   return 1;			/* unknown value */
564 }
565 
566 
567 static int
gopt_full_os(const char * val)568 gopt_full_os(const char *val)
569 {
570   gopt.op_sys_full = xstrdup(val);
571   return 0;
572 }
573 
574 
575 static int
gopt_fully_qualified_hosts(const char * val)576 gopt_fully_qualified_hosts(const char *val)
577 {
578   if (STREQ(val, "yes")) {
579     gopt.flags |= CFM_FULLY_QUALIFIED_HOSTS;
580     return 0;
581   } else if (STREQ(val, "no")) {
582     gopt.flags &= ~CFM_FULLY_QUALIFIED_HOSTS;
583     return 0;
584   }
585 
586   fprintf(stderr, "conf: unknown value to fully_qualified_hosts \"%s\"\n", val);
587   return 1;			/* unknown value */
588 }
589 
590 
591 static int
gopt_hesiod_base(const char * val)592 gopt_hesiod_base(const char *val)
593 {
594 #ifdef HAVE_MAP_HESIOD
595   gopt.hesiod_base = xstrdup(val);
596   return 0;
597 #else /* not HAVE_MAP_HESIOD */
598   fprintf(stderr, "conf: hesiod_base option ignored.  No Hesiod support available.\n");
599   return 1;
600 #endif /* not HAVE_MAP_HESIOD */
601 }
602 
603 
604 static int
gopt_karch(const char * val)605 gopt_karch(const char *val)
606 {
607   gopt.karch = xstrdup(val);
608   return 0;
609 }
610 
611 
612 static int
gopt_pid_file(const char * val)613 gopt_pid_file(const char *val)
614 {
615   gopt.pid_file = xstrdup(val);
616   return 0;
617 }
618 
619 
620 static int
gopt_local_domain(const char * val)621 gopt_local_domain(const char *val)
622 {
623   gopt.sub_domain = xstrdup(val);
624   return 0;
625 }
626 
627 
628 static int
gopt_localhost_address(const char * val)629 gopt_localhost_address(const char *val)
630 {
631   gopt.localhost_address = xstrdup(val);
632   return 0;
633 }
634 
635 
636 static int
gopt_ldap_base(const char * val)637 gopt_ldap_base(const char *val)
638 {
639 #ifdef HAVE_MAP_LDAP
640   gopt.ldap_base = xstrdup(val);
641   return 0;
642 #else /* not HAVE_MAP_LDAP */
643   fprintf(stderr, "conf: ldap_base option ignored.  No LDAP support available.\n");
644   return 1;
645 #endif /* not HAVE_MAP_LDAP */
646 }
647 
648 
649 static int
gopt_ldap_cache_seconds(const char * val)650 gopt_ldap_cache_seconds(const char *val)
651 {
652 #ifdef HAVE_MAP_LDAP
653   char *end;
654 
655   gopt.ldap_cache_seconds = strtol((char *)val, &end, 10);
656   if (end == val) {
657     fprintf(stderr, "conf: bad LDAP cache (seconds) option: %s\n",val);
658     return 1;
659   }
660   return 0;
661 #else /* not HAVE_MAP_LDAP */
662   fprintf(stderr, "conf: ldap_cache_seconds option ignored.  No LDAP support available.\n");
663   return 1;
664 #endif /* not HAVE_MAP_LDAP */
665 }
666 
667 
668 static int
gopt_ldap_cache_maxmem(const char * val)669 gopt_ldap_cache_maxmem(const char *val)
670 {
671 #ifdef HAVE_MAP_LDAP
672   char *end;
673 
674   gopt.ldap_cache_maxmem = strtol((char *)val, &end, 10);
675   if (end == val) {
676     fprintf(stderr, "conf: bad LDAP cache (maxmem) option: %s\n",val);
677     return 1;
678   }
679   return 0;
680 #else /* not HAVE_MAP_LDAP */
681   fprintf(stderr, "conf: ldap_cache_maxmem option ignored.  No LDAP support available.\n");
682   return 1;
683 #endif /* not HAVE_MAP_LDAP */
684 }
685 
686 
687 static int
gopt_ldap_hostports(const char * val)688 gopt_ldap_hostports(const char *val)
689 {
690 #ifdef HAVE_MAP_LDAP
691   gopt.ldap_hostports = xstrdup(val);
692   return 0;
693 #else /* not HAVE_MAP_LDAP */
694   fprintf(stderr, "conf: ldap_hostports option ignored.  No LDAP support available.\n");
695   return 1;
696 #endif /* not HAVE_MAP_LDAP */
697 
698 }
699 
700 
701 static int
gopt_ldap_proto_version(const char * val)702 gopt_ldap_proto_version(const char *val)
703 {
704 #ifdef HAVE_MAP_LDAP
705   char *end;
706 
707   gopt.ldap_proto_version = strtol((char *)val, &end, 10);
708   if (end == val) {
709     fprintf(stderr, "conf: bad ldap_proto_version option: %s\n",val);
710     return 1;
711   }
712 
713   if (gopt.ldap_proto_version < 0 || gopt.ldap_proto_version > LDAP_VERSION_MAX) {
714     fprintf(stderr, "conf: bad ldap_proto_version option value: %s\n",val);
715     return 1;
716   }
717   switch (gopt.ldap_proto_version) {
718     /* XXX: what about LDAP_VERSION1? */
719   case LDAP_VERSION2:
720 #ifdef LDAP_VERSION3
721   case LDAP_VERSION3:
722 #endif /* LDAP_VERSION3 */
723 #ifdef LDAP_VERSION4
724   case LDAP_VERSION4:
725 #endif /* LDAP_VERSION4 */
726     break;
727   default:
728     fprintf(stderr, "conf: unsupported ldap_proto_version option value: %s\n",val);
729     return 1;
730   }
731   return 0;
732 #else /* not HAVE_MAP_LDAP */
733   fprintf(stderr, "conf: ldap_proto_version option ignored.  No LDAP support available.\n");
734   return 1;
735 #endif /* not HAVE_MAP_LDAP */
736 }
737 
738 
739 static int
gopt_log_file(const char * val)740 gopt_log_file(const char *val)
741 {
742   gopt.logfile = xstrdup(val);
743   return 0;
744 }
745 
746 
747 static int
gopt_log_options(const char * val)748 gopt_log_options(const char *val)
749 {
750   usage += switch_option((char *)val);
751   return 0;
752 }
753 
754 
755 static int
gopt_map_defaults(const char * val)756 gopt_map_defaults(const char *val)
757 {
758   gopt.map_defaults = xstrdup(val);
759   return 0;
760 }
761 
762 
763 static int
gopt_map_options(const char * val)764 gopt_map_options(const char *val)
765 {
766   gopt.map_options = xstrdup(val);
767   return 0;
768 }
769 
770 
771 static int
gopt_map_reload_interval(const char * val)772 gopt_map_reload_interval(const char *val)
773 {
774   gopt.map_reload_interval = atoi(val);
775   if (gopt.map_reload_interval <= 0)
776     gopt.map_reload_interval = ONE_HOUR;
777   return 0;
778 }
779 
780 
781 static int
gopt_map_type(const char * val)782 gopt_map_type(const char *val)
783 {
784   /* check if map type exist */
785   if (!mapc_type_exists(val)) {
786     fprintf(stderr, "conf: no such map type \"%s\"\n", val);
787     return 1;
788   }
789   gopt.map_type = xstrdup(val);
790   return 0;
791 }
792 
793 
794 static int
gopt_mount_type(const char * val)795 gopt_mount_type(const char *val)
796 {
797   if (STREQ(val, "autofs")) {
798 #ifdef HAVE_FS_AUTOFS
799     gopt.flags |= CFM_MOUNT_TYPE_AUTOFS;
800     amd_use_autofs++;
801     return 0;
802 #else /* not HAVE_FS_AUTOFS */
803     fprintf(stderr, "conf: no autofs support available\n");
804     return 1;
805 #endif /* not HAVE_FS_AUTOFS */
806   } else if (STREQ(val, "nfs")) {
807     gopt.flags &= ~CFM_MOUNT_TYPE_AUTOFS;
808     return 0;
809   }
810 
811   fprintf(stderr, "conf: unknown value to mount_type \"%s\"\n", val);
812   return 1;			/* unknown value */
813 }
814 
815 
816 static int
gopt_portmap_program(const char * val)817 gopt_portmap_program(const char *val)
818 {
819   gopt.portmap_program = atol(val);
820   /*
821    * allow alternate program numbers to be no more than 10 offset from
822    * official amd program number (300019).
823    */
824   if (gopt.portmap_program < AMQ_PROGRAM ||
825       gopt.portmap_program > AMQ_PROGRAM + 10) {
826     gopt.portmap_program = AMQ_PROGRAM;
827     set_amd_program_number(gopt.portmap_program);
828     fprintf(stderr, "conf: illegal amd program number \"%s\"\n", val);
829     return 1;
830   }
831 
832   set_amd_program_number(gopt.portmap_program);
833   return 0;			/* all is OK */
834 }
835 
836 
837 static int
gopt_preferred_amq_port(const char * val)838 gopt_preferred_amq_port(const char *val)
839 {
840   gopt.preferred_amq_port = atoi(val);
841 
842   /*
843    * No need to check value: preferred_amq_port is an unsigned short and 0
844    * is a valid number, meaning "any port".
845    */
846   return 0;			/* all is OK */
847 }
848 
849 
850 static int
gopt_nfs_allow_any_interface(const char * val)851 gopt_nfs_allow_any_interface(const char *val)
852 {
853   if (STREQ(val, "yes")) {
854     gopt.flags |= CFM_NFS_ANY_INTERFACE;
855     return 0;
856   } else if (STREQ(val, "no")) {
857     gopt.flags &= ~CFM_NFS_ANY_INTERFACE;
858     return 0;
859   }
860 
861   fprintf(stderr, "conf: unknown value to nfs_allow_insecure_port \"%s\"\n", val);
862   return 1;			/* unknown value */
863 }
864 
865 
866 static int
gopt_nfs_allow_insecure_port(const char * val)867 gopt_nfs_allow_insecure_port(const char *val)
868 {
869   if (STREQ(val, "yes")) {
870     gopt.flags |= CFM_NFS_INSECURE_PORT;
871     return 0;
872   } else if (STREQ(val, "no")) {
873     gopt.flags &= ~CFM_NFS_INSECURE_PORT;
874     return 0;
875   }
876 
877   fprintf(stderr, "conf: unknown value to nfs_allow_insecure_port \"%s\"\n", val);
878   return 1;			/* unknown value */
879 }
880 
881 
882 static int
gopt_nfs_proto(const char * val)883 gopt_nfs_proto(const char *val)
884 {
885   if (STREQ(val, "udp") || STREQ(val, "tcp")) {
886     gopt.nfs_proto = xstrdup(val);
887     return 0;
888   }
889   fprintf(stderr, "conf: illegal nfs_proto \"%s\"\n", val);
890   return 1;
891 }
892 
893 
894 static int
gopt_nfs_retransmit_counter(const char * val)895 gopt_nfs_retransmit_counter(const char *val)
896 {
897   int i;
898 
899   for (i=0; i<AMU_TYPE_MAX; ++i)
900     gopt.amfs_auto_retrans[i] = atoi(val);
901   return 0;
902 }
903 
904 
905 static int
gopt_nfs_retransmit_counter_udp(const char * val)906 gopt_nfs_retransmit_counter_udp(const char *val)
907 {
908   gopt.amfs_auto_retrans[AMU_TYPE_UDP] = atoi(val);
909   return 0;
910 }
911 
912 
913 static int
gopt_nfs_retransmit_counter_tcp(const char * val)914 gopt_nfs_retransmit_counter_tcp(const char *val)
915 {
916   gopt.amfs_auto_retrans[AMU_TYPE_TCP] = atoi(val);
917   return 0;
918 }
919 
920 
921 static int
gopt_nfs_retransmit_counter_toplvl(const char * val)922 gopt_nfs_retransmit_counter_toplvl(const char *val)
923 {
924   gopt.amfs_auto_retrans[AMU_TYPE_TOPLVL] = atoi(val);
925   return 0;
926 }
927 
928 
929 static int
gopt_nfs_retry_interval(const char * val)930 gopt_nfs_retry_interval(const char *val)
931 {
932   int i;
933 
934   for (i=0; i<AMU_TYPE_MAX; ++i)
935     gopt.amfs_auto_timeo[i] = atoi(val);
936   return 0;
937 }
938 
939 
940 static int
gopt_nfs_retry_interval_udp(const char * val)941 gopt_nfs_retry_interval_udp(const char *val)
942 {
943   gopt.amfs_auto_timeo[AMU_TYPE_UDP] = atoi(val);
944   return 0;
945 }
946 
947 
948 static int
gopt_nfs_retry_interval_tcp(const char * val)949 gopt_nfs_retry_interval_tcp(const char *val)
950 {
951   gopt.amfs_auto_timeo[AMU_TYPE_TCP] = atoi(val);
952   return 0;
953 }
954 
955 
956 static int
gopt_nfs_retry_interval_toplvl(const char * val)957 gopt_nfs_retry_interval_toplvl(const char *val)
958 {
959   gopt.amfs_auto_timeo[AMU_TYPE_TOPLVL] = atoi(val);
960   return 0;
961 }
962 
963 
964 static int
gopt_nfs_vers(const char * val)965 gopt_nfs_vers(const char *val)
966 {
967   int i = atoi(val);
968 
969   if (i == 2 || i == 3 || i == 4) {
970     gopt.nfs_vers = i;
971     return 0;
972   }
973   fprintf(stderr, "conf: illegal nfs_vers \"%s\"\n", val);
974   return 1;
975 }
976 
977 
978 static int
gopt_nfs_vers_ping(const char * val)979 gopt_nfs_vers_ping(const char *val)
980 {
981   int i = atoi(val);
982 
983   if (i == 2 || i == 3 || i == 4) {
984     gopt.nfs_vers_ping = i;
985     return 0;
986   }
987   fprintf(stderr, "conf: illegal nfs_vers_ping \"%s\"\n", val);
988   return 1;
989 }
990 
991 static int
gopt_nis_domain(const char * val)992 gopt_nis_domain(const char *val)
993 {
994 #ifdef HAVE_MAP_NIS
995   gopt.nis_domain = xstrdup(val);
996   return 0;
997 #else /* not HAVE_MAP_NIS */
998   fprintf(stderr, "conf: nis_domain option ignored.  No NIS support available.\n");
999   return 1;
1000 #endif /* not HAVE_MAP_NIS */
1001 }
1002 
1003 
1004 static int
gopt_normalize_hostnames(const char * val)1005 gopt_normalize_hostnames(const char *val)
1006 {
1007   if (STREQ(val, "yes")) {
1008     gopt.flags |= CFM_NORMALIZE_HOSTNAMES;
1009     return 0;
1010   } else if (STREQ(val, "no")) {
1011     gopt.flags &= ~CFM_NORMALIZE_HOSTNAMES;
1012     return 0;
1013   }
1014 
1015   fprintf(stderr, "conf: unknown value to normalize_hostnames \"%s\"\n", val);
1016   return 1;			/* unknown value */
1017 }
1018 
1019 
1020 static int
gopt_normalize_slashes(const char * val)1021 gopt_normalize_slashes(const char *val)
1022 {
1023   if (STREQ(val, "yes")) {
1024     gopt.flags |= CFM_NORMALIZE_SLASHES;
1025     return 0;
1026   } else if (STREQ(val, "no")) {
1027     gopt.flags &= ~CFM_NORMALIZE_SLASHES;
1028     return 0;
1029   }
1030 
1031   fprintf(stderr, "conf: unknown value to normalize_slashes \"%s\"\n", val);
1032   return 1;			/* unknown value */
1033 }
1034 
1035 
1036 static int
gopt_os(const char * val)1037 gopt_os(const char *val)
1038 {
1039   gopt.op_sys = xstrdup(val);
1040   return 0;
1041 }
1042 
1043 
1044 static int
gopt_osver(const char * val)1045 gopt_osver(const char *val)
1046 {
1047   gopt.op_sys_ver = xstrdup(val);
1048   return 0;
1049 }
1050 
1051 
1052 static int
gopt_plock(const char * val)1053 gopt_plock(const char *val)
1054 {
1055   if (STREQ(val, "yes")) {
1056     gopt.flags |= CFM_PROCESS_LOCK;
1057     return 0;
1058   } else if (STREQ(val, "no")) {
1059     gopt.flags &= ~CFM_PROCESS_LOCK;
1060     return 0;
1061   }
1062 
1063   fprintf(stderr, "conf: unknown value to plock \"%s\"\n", val);
1064   return 1;			/* unknown value */
1065 }
1066 
1067 
1068 static int
gopt_print_pid(const char * val)1069 gopt_print_pid(const char *val)
1070 {
1071   if (STREQ(val, "yes")) {
1072     gopt.flags |= CFM_PRINT_PID;
1073     return 0;
1074   } else if (STREQ(val, "no")) {
1075     gopt.flags &= ~CFM_PRINT_PID;
1076     return 0;
1077   }
1078 
1079   fprintf(stderr, "conf: unknown value to print_pid \"%s\"\n", val);
1080   return 1;			/* unknown value */
1081 }
1082 
1083 
1084 static int
gopt_print_version(const char * val)1085 gopt_print_version(const char *val)
1086 {
1087   if (STREQ(val, "yes")) {
1088     char *vers = get_version_string();
1089     fputs(vers, stderr);
1090     XFREE(vers);
1091     return 0;
1092   } else if (STREQ(val, "no")) {
1093     return 0;
1094   }
1095 
1096   fprintf(stderr, "conf: unknown value to print_version \"%s\"\n", val);
1097   return 1;			/* unknown value */
1098 }
1099 
1100 
1101 static int
gopt_restart_mounts(const char * val)1102 gopt_restart_mounts(const char *val)
1103 {
1104   if (STREQ(val, "yes")) {
1105     gopt.flags |= CFM_RESTART_EXISTING_MOUNTS;
1106     return 0;
1107   } else if (STREQ(val, "no")) {
1108     gopt.flags &= ~CFM_RESTART_EXISTING_MOUNTS;
1109     return 0;
1110   }
1111 
1112   fprintf(stderr, "conf: unknown value to restart_mounts \"%s\"\n", val);
1113   return 1;			/* unknown value */
1114 }
1115 
1116 
1117 static int
gopt_search_path(const char * val)1118 gopt_search_path(const char *val)
1119 {
1120   gopt.search_path = xstrdup(val);
1121   return 0;
1122 }
1123 
1124 
1125 static int
gopt_selectors_in_defaults(const char * val)1126 gopt_selectors_in_defaults(const char *val)
1127 {
1128   if (STREQ(val, "yes")) {
1129     gopt.flags |= CFM_SELECTORS_IN_DEFAULTS;
1130     return 0;
1131   } else if (STREQ(val, "no")) {
1132     gopt.flags &= ~CFM_SELECTORS_IN_DEFAULTS;
1133     return 0;
1134   }
1135 
1136   fprintf(stderr, "conf: unknown value to enable_default_selectors \"%s\"\n", val);
1137   return 1;			/* unknown value */
1138 }
1139 
1140 
1141 static int
gopt_show_statfs_entries(const char * val)1142 gopt_show_statfs_entries(const char *val)
1143 {
1144   if (STREQ(val, "yes")) {
1145     gopt.flags |= CFM_SHOW_STATFS_ENTRIES;
1146     return 0;
1147   } else if (STREQ(val, "no")) {
1148     gopt.flags &= ~CFM_SHOW_STATFS_ENTRIES;
1149     return 0;
1150   }
1151 
1152   fprintf(stderr, "conf: unknown value to show_statfs_entries \"%s\"\n", val);
1153   return 1;			/* unknown value */
1154 }
1155 
1156 
1157 static int
gopt_sun_map_syntax(const char * val)1158 gopt_sun_map_syntax(const char *val)
1159 {
1160   if (STREQ(val, "yes")) {
1161     gopt.flags |= CFM_SUN_MAP_SYNTAX;
1162     return 0;
1163   } else if (STREQ(val, "no")) {
1164     gopt.flags &= ~CFM_SUN_MAP_SYNTAX;
1165     return 0;
1166   }
1167 
1168   fprintf(stderr, "conf: unknown value to sun_map_syntax \"%s\"\n", val);
1169   return 1;			/* unknown value */
1170 }
1171 
1172 
1173 static int
gopt_truncate_log(const char * val)1174 gopt_truncate_log(const char *val)
1175 {
1176   if (STREQ(val, "yes")) {
1177     gopt.flags |= CFM_TRUNCATE_LOG;
1178     return 0;
1179   } else if (STREQ(val, "no")) {
1180     gopt.flags &= ~CFM_TRUNCATE_LOG;
1181     return 0;
1182   }
1183 
1184   fprintf(stderr, "conf: unknown value to truncate_log \"%s\"\n", val);
1185   return 1;			/* unknown value */
1186 }
1187 
1188 
1189 static int
gopt_unmount_on_exit(const char * val)1190 gopt_unmount_on_exit(const char *val)
1191 {
1192   if (STREQ(val, "yes")) {
1193     gopt.flags |= CFM_UNMOUNT_ON_EXIT;
1194     return 0;
1195   } else if (STREQ(val, "no")) {
1196     gopt.flags &= ~CFM_UNMOUNT_ON_EXIT;
1197     return 0;
1198   }
1199 
1200   fprintf(stderr, "conf: unknown value to unmount_on_exit \"%s\"\n", val);
1201   return 1;			/* unknown value */
1202 }
1203 
1204 
1205 static int
gopt_use_tcpwrappers(const char * val)1206 gopt_use_tcpwrappers(const char *val)
1207 {
1208 #if defined(HAVE_TCPD_H) && defined(HAVE_LIBWRAP)
1209   if (STREQ(val, "yes")) {
1210     gopt.flags |= CFM_USE_TCPWRAPPERS;
1211     return 0;
1212   } else if (STREQ(val, "no")) {
1213     gopt.flags &= ~CFM_USE_TCPWRAPPERS;
1214     return 0;
1215   }
1216 #else /* not defined(HAVE_TCPD_H) && defined(HAVE_LIBWRAP) */
1217     fprintf(stderr, "conf: no tcpd/libwrap support available\n");
1218     return 1;
1219 #endif /* not defined(HAVE_TCPD_H) && defined(HAVE_LIBWRAP) */
1220 
1221   fprintf(stderr, "conf: unknown value to use_tcpwrappers \"%s\"\n", val);
1222   return 1;			/* unknown value */
1223 }
1224 
1225 
1226 static int
gopt_vendor(const char * val)1227 gopt_vendor(const char *val)
1228 {
1229   gopt.op_sys_vendor = xstrdup(val);
1230   return 0;
1231 }
1232 
1233 
1234 /*
1235  * Collect one entry for a regular map
1236  */
1237 static int
process_regular_option(const char * section,const char * key,const char * val,cf_map_t * cfm)1238 process_regular_option(const char *section, const char *key, const char *val, cf_map_t *cfm)
1239 {
1240   /* ensure that val is valid */
1241   if (!section || section[0] == '\0' ||
1242       !key || key[0] == '\0' ||
1243       !val || val[0] == '\0' ||
1244       !cfm) {
1245     fprintf(stderr, "conf: process_regular_option: null entries\n");
1246     return 1;
1247   }
1248 
1249   /* check if initializing a new map */
1250   if (!cfm->cfm_dir)
1251     cfm->cfm_dir = xstrdup(section);
1252 
1253   /* check for each possible field */
1254   if (STREQ(key, "browsable_dirs"))
1255     return ropt_browsable_dirs(val, cfm);
1256 
1257   if (STREQ(key, "map_name"))
1258     return ropt_map_name(val, cfm);
1259 
1260   if (STREQ(key, "map_defaults"))
1261     return ropt_map_defaults(val, cfm);
1262 
1263   if (STREQ(key, "map_options"))
1264     return ropt_map_options(val, cfm);
1265 
1266   if (STREQ(key, "map_type"))
1267     return ropt_map_type(val, cfm);
1268 
1269   if (STREQ(key, "mount_type"))
1270     return ropt_mount_type(val, cfm);
1271 
1272   if (STREQ(key, "search_path"))
1273     return ropt_search_path(val, cfm);
1274 
1275   if (STREQ(key, "sun_map_syntax"))
1276     return ropt_sun_map_syntax(val, cfm);
1277 
1278   if (STREQ(key, "tag"))
1279     return ropt_tag(val, cfm);
1280 
1281   fprintf(stderr, "conf: unknown regular key \"%s\" for section \"%s\"\n",
1282 	  key, section);
1283   return 1;			/* failed to match any command */
1284 }
1285 
1286 
1287 static int
ropt_browsable_dirs(const char * val,cf_map_t * cfm)1288 ropt_browsable_dirs(const char *val, cf_map_t *cfm)
1289 {
1290   if (STREQ(val, "full")) {
1291     cfm->cfm_flags |= CFM_BROWSABLE_DIRS_FULL;
1292     return 0;
1293   } else if (STREQ(val, "yes")) {
1294     cfm->cfm_flags |= CFM_BROWSABLE_DIRS;
1295     return 0;
1296   } else if (STREQ(val, "no")) {
1297     cfm->cfm_flags &= ~CFM_BROWSABLE_DIRS;
1298     return 0;
1299   }
1300 
1301   fprintf(stderr, "conf: unknown value to browsable_dirs \"%s\"\n", val);
1302   return 1;			/* unknown value */
1303 }
1304 
1305 
1306 static int
ropt_map_name(const char * val,cf_map_t * cfm)1307 ropt_map_name(const char *val, cf_map_t *cfm)
1308 {
1309   cfm->cfm_name = xstrdup(val);
1310   return 0;
1311 }
1312 
1313 
1314 static int
ropt_map_defaults(const char * val,cf_map_t * cfm)1315 ropt_map_defaults(const char *val, cf_map_t *cfm)
1316 {
1317   cfm->cfm_defaults = xstrdup(val);
1318   return 0;
1319 }
1320 
1321 
1322 static int
ropt_map_options(const char * val,cf_map_t * cfm)1323 ropt_map_options(const char *val, cf_map_t *cfm)
1324 {
1325   cfm->cfm_opts = xstrdup(val);
1326   return 0;
1327 }
1328 
1329 
1330 static int
ropt_map_type(const char * val,cf_map_t * cfm)1331 ropt_map_type(const char *val, cf_map_t *cfm)
1332 {
1333   /* check if map type exist */
1334   if (!mapc_type_exists(val)) {
1335     fprintf(stderr, "conf: no such map type \"%s\"\n", val);
1336     return 1;
1337   }
1338   cfm->cfm_type = xstrdup(val);
1339   return 0;
1340 }
1341 
1342 
1343 static int
ropt_mount_type(const char * val,cf_map_t * cfm)1344 ropt_mount_type(const char *val, cf_map_t *cfm)
1345 {
1346   if (STREQ(val, "autofs")) {
1347 #ifdef HAVE_FS_AUTOFS
1348     cfm->cfm_flags |= CFM_MOUNT_TYPE_AUTOFS;
1349     amd_use_autofs++;
1350     return 0;
1351 #else /* not HAVE_FS_AUTOFS */
1352     fprintf(stderr, "conf: no autofs support available\n");
1353     return 1;
1354 #endif /* not HAVE_FS_AUTOFS */
1355   } else if (STREQ(val, "nfs")) {
1356     cfm->cfm_flags &= ~CFM_MOUNT_TYPE_AUTOFS;
1357     return 0;
1358   }
1359 
1360   fprintf(stderr, "conf: unknown value to mount_type \"%s\"\n", val);
1361   return 1;			/* unknown value */
1362 }
1363 
1364 
1365 static int
ropt_search_path(const char * val,cf_map_t * cfm)1366 ropt_search_path(const char *val, cf_map_t *cfm)
1367 {
1368   cfm->cfm_search_path = xstrdup(val);
1369   return 0;
1370 }
1371 
1372 
1373 static int
ropt_sun_map_syntax(const char * val,cf_map_t * cfm)1374 ropt_sun_map_syntax(const char *val, cf_map_t *cfm)
1375 {
1376   if (STREQ(val, "yes")) {
1377     cfm->cfm_flags |= CFM_SUN_MAP_SYNTAX;
1378     return 0;
1379 
1380   } else if (STREQ(val, "no")) {
1381     cfm->cfm_flags &= ~CFM_SUN_MAP_SYNTAX;
1382     return 0;
1383   }
1384 
1385   fprintf(stderr, "conf: unknown value to sun_map_syntax \"%s\"\n", val);
1386   return 1;			/* unknown value */
1387 }
1388 
1389 
1390 static int
ropt_tag(const char * val,cf_map_t * cfm)1391 ropt_tag(const char *val, cf_map_t *cfm)
1392 {
1393   cfm->cfm_tag = xstrdup(val);
1394   return 0;
1395 }
1396 
1397 
1398 /*
1399  * Process one collected map.
1400  */
1401 static int
process_one_regular_map(const cf_map_t * cfm)1402 process_one_regular_map(const cf_map_t *cfm)
1403 {
1404   if (!cfm->cfm_name) {
1405     fprintf(stderr, "conf: map_name must be defined for map \"%s\"\n", cfm->cfm_dir);
1406     return 1;
1407   }
1408   /*
1409    * If map has no tag defined, process the map.
1410    * If no conf_tag was set in amd -T, process all untagged entries.
1411    * If a tag is defined, then process it only if it matches the map tag.
1412    */
1413   if (!cfm->cfm_tag ||
1414       (conf_tag && STREQ(cfm->cfm_tag, conf_tag))) {
1415 #ifdef DEBUG_CONF
1416     fprintf(stderr, "processing map %s (flags=0x%x)...\n",
1417 	    cfm->cfm_dir, cfm->cfm_flags);
1418 #endif /* DEBUG_CONF */
1419     root_newmap(cfm->cfm_dir,
1420 		cfm->cfm_opts ? cfm->cfm_opts : "",
1421 		cfm->cfm_name,
1422 		cfm);
1423   } else {
1424     fprintf(stderr, "skipping map %s...\n", cfm->cfm_dir);
1425   }
1426 
1427   return 0;
1428 }
1429 
1430 
1431 /*
1432  * Process all regular maps in conf file (if any)
1433  */
1434 int
process_all_regular_maps(void)1435 process_all_regular_maps(void)
1436 {
1437   cf_map_t *tmp_map = head_map;
1438 
1439   /*
1440    * If the amd.conf file only has a [global] section (pretty useless
1441    * IMHO), there's nothing to process
1442    */
1443   if (!tmp_map)
1444     return 0;
1445 
1446   while (tmp_map) {
1447     if (process_one_regular_map(tmp_map) != 0)
1448       return 1;
1449     tmp_map = tmp_map->cfm_next;
1450   }
1451   return 0;
1452 }
1453 
1454 
1455 /*
1456  * Find a cf_map_t for a given map name.
1457  * Return NULL if not found.
1458  */
1459 cf_map_t *
find_cf_map(const char * name)1460 find_cf_map(const char *name)
1461 {
1462 
1463   cf_map_t *tmp_map = head_map;
1464 
1465   if (!tmp_map || !name)
1466     return NULL;
1467 
1468   while (tmp_map) {
1469     if (STREQ(tmp_map->cfm_dir, name)) {
1470       return tmp_map;
1471     }
1472     tmp_map = tmp_map->cfm_next;
1473   }
1474   return NULL;
1475 }
1476