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