Expand PMF_FN_* macros.
[netbsd-mini2440.git] / external / bsd / am-utils / dist / amd / conf.c
blobc8fc6a182adc4c9f7ba5d92adab8b1f95b2552a5
1 /* $NetBSD$ */
3 /*
4 * Copyright (c) 1997-2009 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.
10 * This code is derived from software contributed to Berkeley by
11 * Jan-Simon Pendry at Imperial College, London.
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. All advertising materials mentioning features or use of this software
22 * must display the following acknowledgment:
23 * This product includes software developed by the University of
24 * California, Berkeley and its contributors.
25 * 4. Neither the name of the University nor the names of its contributors
26 * may be used to endorse or promote products derived from this software
27 * without specific prior written permission.
29 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
30 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
33 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
34 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
35 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
37 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
38 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
39 * SUCH DAMAGE.
42 * File: am-utils/amd/conf.c
47 * Functions to handle the configuration file.
50 #ifdef HAVE_CONFIG_H
51 # include <config.h>
52 #endif /* HAVE_CONFIG_H */
53 #include <am_defs.h>
54 #include <amd.h>
58 * MACROS:
60 /* Turn on to show some info about maps being configured */
61 /* #define DEBUG_CONF */
64 * TYPEDEFS:
66 typedef int (*OptFuncPtr)(const char *);
69 * STRUCTURES:
71 struct _func_map {
72 char *name;
73 OptFuncPtr func;
77 * FORWARD DECLARATIONS:
79 static int gopt_arch(const char *val);
80 static int gopt_auto_attrcache(const char *val);
81 static int gopt_auto_dir(const char *val);
82 static int gopt_autofs_use_lofs(const char *val);
83 static int gopt_browsable_dirs(const char *val);
84 static int gopt_cache_duration(const char *val);
85 static int gopt_cluster(const char *val);
86 static int gopt_debug_mtab_file(const char *val);
87 static int gopt_debug_options(const char *val);
88 static int gopt_dismount_interval(const char *val);
89 static int gopt_domain_strip(const char *val);
90 static int gopt_exec_map_timeout(const char *val);
91 static int gopt_forced_unmounts(const char *val);
92 static int gopt_full_os(const char *val);
93 static int gopt_fully_qualified_hosts(const char *val);
94 static int gopt_hesiod_base(const char *val);
95 static int gopt_karch(const char *val);
96 static int gopt_ldap_base(const char *val);
97 static int gopt_ldap_cache_maxmem(const char *val);
98 static int gopt_ldap_cache_seconds(const char *val);
99 static int gopt_ldap_hostports(const char *val);
100 static int gopt_ldap_proto_version(const char *val);
101 static int gopt_local_domain(const char *val);
102 static int gopt_localhost_address(const char *val);
103 static int gopt_log_file(const char *val);
104 static int gopt_log_options(const char *val);
105 static int gopt_map_defaults(const char *val);
106 static int gopt_map_options(const char *val);
107 static int gopt_map_reload_interval(const char *val);
108 static int gopt_map_type(const char *val);
109 static int gopt_mount_type(const char *val);
110 static int gopt_pid_file(const char *val);
111 static int gopt_portmap_program(const char *val);
112 static int gopt_preferred_amq_port(const char *val);
113 static int gopt_nfs_allow_any_interface(const char *val);
114 static int gopt_nfs_allow_insecure_port(const char *val);
115 static int gopt_nfs_proto(const char *val);
116 static int gopt_nfs_retransmit_counter(const char *val);
117 static int gopt_nfs_retransmit_counter_udp(const char *val);
118 static int gopt_nfs_retransmit_counter_tcp(const char *val);
119 static int gopt_nfs_retransmit_counter_toplvl(const char *val);
120 static int gopt_nfs_retry_interval(const char *val);
121 static int gopt_nfs_retry_interval_udp(const char *val);
122 static int gopt_nfs_retry_interval_tcp(const char *val);
123 static int gopt_nfs_retry_interval_toplvl(const char *val);
124 static int gopt_nfs_vers(const char *val);
125 static int gopt_nis_domain(const char *val);
126 static int gopt_normalize_hostnames(const char *val);
127 static int gopt_normalize_slashes(const char *val);
128 static int gopt_os(const char *val);
129 static int gopt_osver(const char *val);
130 static int gopt_plock(const char *val);
131 static int gopt_print_pid(const char *val);
132 static int gopt_print_version(const char *val);
133 static int gopt_restart_mounts(const char *val);
134 static int gopt_search_path(const char *val);
135 static int gopt_selectors_in_defaults(const char *val);
136 static int gopt_show_statfs_entries(const char *val);
137 static int gopt_sun_map_syntax(const char *val);
138 static int gopt_truncate_log(const char *val);
139 static int gopt_unmount_on_exit(const char *val);
140 static int gopt_use_tcpwrappers(const char *val);
141 static int gopt_vendor(const char *val);
142 static int process_global_option(const char *key, const char *val);
143 static int process_one_regular_map(const cf_map_t *cfm);
144 static int process_regular_option(const char *section, const char *key, const char *val, cf_map_t *cfm);
145 static int ropt_browsable_dirs(const char *val, cf_map_t *cfm);
146 static int ropt_map_name(const char *val, cf_map_t *cfm);
147 static int ropt_map_defaults(const char *val, cf_map_t *cfm);
148 static int ropt_map_options(const char *val, cf_map_t *cfm);
149 static int ropt_map_type(const char *val, cf_map_t *cfm);
150 static int ropt_mount_type(const char *val, cf_map_t *cfm);
151 static int ropt_search_path(const char *val, cf_map_t *cfm);
152 static int ropt_sun_map_syntax(const char *val, cf_map_t *cfm);
153 static int ropt_tag(const char *val, cf_map_t *cfm);
154 static void init_cf_map(cf_map_t *cfm);
158 * STATIC VARIABLES:
160 static cf_map_t *head_map, *cur_map;
162 static struct _func_map glob_functable[] = {
163 {"arch", gopt_arch},
164 {"auto_attrcache", gopt_auto_attrcache},
165 {"auto_dir", gopt_auto_dir},
166 {"autofs_use_lofs", gopt_autofs_use_lofs},
167 {"browsable_dirs", gopt_browsable_dirs},
168 {"cache_duration", gopt_cache_duration},
169 {"cluster", gopt_cluster},
170 {"debug_mtab_file", gopt_debug_mtab_file},
171 {"debug_options", gopt_debug_options},
172 {"dismount_interval", gopt_dismount_interval},
173 {"domain_strip", gopt_domain_strip},
174 {"exec_map_timeout", gopt_exec_map_timeout},
175 {"forced_unmounts", gopt_forced_unmounts},
176 {"fully_qualified_hosts", gopt_fully_qualified_hosts},
177 {"full_os", gopt_full_os},
178 {"hesiod_base", gopt_hesiod_base},
179 {"karch", gopt_karch},
180 {"ldap_base", gopt_ldap_base},
181 {"ldap_cache_maxmem", gopt_ldap_cache_maxmem},
182 {"ldap_cache_seconds", gopt_ldap_cache_seconds},
183 {"ldap_hostports", gopt_ldap_hostports},
184 {"ldap_proto_version", gopt_ldap_proto_version},
185 {"local_domain", gopt_local_domain},
186 {"localhost_address", gopt_localhost_address},
187 {"log_file", gopt_log_file},
188 {"log_options", gopt_log_options},
189 {"map_defaults", gopt_map_defaults},
190 {"map_options", gopt_map_options},
191 {"map_reload_interval", gopt_map_reload_interval},
192 {"map_type", gopt_map_type},
193 {"mount_type", gopt_mount_type},
194 {"pid_file", gopt_pid_file},
195 {"portmap_program", gopt_portmap_program},
196 {"preferred_amq_port", gopt_preferred_amq_port},
197 {"nfs_allow_any_interface", gopt_nfs_allow_any_interface},
198 {"nfs_allow_insecure_port", gopt_nfs_allow_insecure_port},
199 {"nfs_proto", gopt_nfs_proto},
200 {"nfs_retransmit_counter", gopt_nfs_retransmit_counter},
201 {"nfs_retransmit_counter_udp", gopt_nfs_retransmit_counter_udp},
202 {"nfs_retransmit_counter_tcp", gopt_nfs_retransmit_counter_tcp},
203 {"nfs_retransmit_counter_toplvl", gopt_nfs_retransmit_counter_toplvl},
204 {"nfs_retry_interval", gopt_nfs_retry_interval},
205 {"nfs_retry_interval_udp", gopt_nfs_retry_interval_udp},
206 {"nfs_retry_interval_tcp", gopt_nfs_retry_interval_tcp},
207 {"nfs_retry_interval_toplvl", gopt_nfs_retry_interval_toplvl},
208 {"nfs_vers", gopt_nfs_vers},
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}
232 * Initialize a map from [global] defaults.
234 static void
235 init_cf_map(cf_map_t *cfm)
237 if (!cfm)
238 return;
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.
245 * NOTES:
246 * (1): Will only work for maps that appear after [global].
247 * (2): I'm assigning pointers directly from the global map.
250 /* initialize map_type from [global] */
251 cfm->cfm_type = gopt.map_type;
253 /* initialize map_defaults from [global] */
254 cfm->cfm_defaults = gopt.map_defaults;
256 /* initialize map_opts from [global] */
257 cfm->cfm_opts = gopt.map_options;
259 /* initialize search_path from [global] */
260 cfm->cfm_search_path = gopt.search_path;
263 * Initialize flags that are common both to [global] and a local map
264 * (that is, they could be inherited from the global section).
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 );
275 * Process configuration file options (called from YACC parser).
276 * Return 0 if OK, 1 otherwise.
279 set_conf_kv(const char *section, const char *key, const char *val)
281 int ret;
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 */
289 * If global section, process kv pairs one at a time.
291 if (STREQ(section, "global")) {
293 * Check if a regular map was configured before "global",
294 * and warn about it.
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;
305 /* process the global option first */
306 ret = process_global_option(key, val);
308 /* return status from the processing of the global option */
309 return ret;
313 * Otherwise we found a non-global option: store it after some testing.
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);
323 /* initialize first head map from global defaults */
324 init_cf_map(cur_map);
325 head_map = cur_map;
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);
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;
343 /* now process a single entry of a regular map */
344 return process_regular_option(section, key, val, cur_map);
349 * Process global section of configuration file options.
350 * Return 0 upon success, 1 otherwise.
352 static int
353 process_global_option(const char *key, const char *val)
355 struct _func_map *gfp;
357 /* ensure that val is valid */
358 if (!val || val[0] == '\0')
359 return 1;
362 * search for global function.
364 for (gfp = glob_functable; gfp->name; gfp++)
365 if (FSTREQ(gfp->name, key))
366 return (gfp->func)(val);
368 fprintf(stderr, "conf: unknown global key: \"%s\"\n", key);
369 return 1; /* failed to match any command */
373 static int
374 gopt_arch(const char *val)
376 gopt.arch = strdup((char *)val);
377 return 0;
381 static int
382 gopt_auto_attrcache(const char *val)
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;
389 return 0;
393 static int
394 gopt_auto_dir(const char *val)
396 gopt.auto_dir = strdup((char *)val);
397 return 0;
401 static int
402 gopt_autofs_use_lofs(const char *val)
404 if (STREQ(val, "yes")) {
405 gopt.flags |= CFM_AUTOFS_USE_LOFS;
406 return 0;
407 } else if (STREQ(val, "no")) {
408 gopt.flags &= ~CFM_AUTOFS_USE_LOFS;
409 return 0;
412 fprintf(stderr, "conf: unknown value to autofs_use_lofs \"%s\"\n", val);
413 return 1; /* unknown value */
417 static int
418 gopt_browsable_dirs(const char *val)
420 if (STREQ(val, "full")) {
421 gopt.flags |= CFM_BROWSABLE_DIRS_FULL;
422 return 0;
423 } else if (STREQ(val, "yes")) {
424 gopt.flags |= CFM_BROWSABLE_DIRS;
425 return 0;
426 } else if (STREQ(val, "no")) {
427 gopt.flags &= ~CFM_BROWSABLE_DIRS;
428 return 0;
431 fprintf(stderr, "conf: unknown value to browsable_dirs \"%s\"\n", val);
432 return 1; /* unknown value */
436 static int
437 gopt_cache_duration(const char *val)
439 gopt.am_timeo = atoi(val);
440 if (gopt.am_timeo <= 0)
441 gopt.am_timeo = AM_TTL;
442 return 0;
446 static int
447 gopt_cluster(const char *val)
449 gopt.cluster = strdup((char *)val);
450 return 0;
454 static int
455 gopt_debug_mtab_file(const char *val)
457 gopt.debug_mtab_file = strdup((char*)val);
458 return 0;
462 static int
463 gopt_debug_options(const char *val)
465 #ifdef DEBUG
466 usage += debug_option((char *)val);
467 return 0;
468 #else /* not DEBUG */
469 fprintf(stderr, "%s: not compiled with DEBUG option -- sorry.\n",
470 am_get_progname());
471 return 1;
472 #endif /* not DEBUG */
476 static int
477 gopt_dismount_interval(const char *val)
479 gopt.am_timeo_w = atoi(val);
480 if (gopt.am_timeo_w <= 0)
481 gopt.am_timeo_w = AM_TTL_W;
482 return 0;
486 static int
487 gopt_domain_strip(const char *val)
489 if (STREQ(val, "yes")) {
490 gopt.flags |= CFM_DOMAIN_STRIP;
491 return 0;
492 } else if (STREQ(val, "no")) {
493 gopt.flags &= ~CFM_DOMAIN_STRIP;
494 return 0;
497 fprintf(stderr, "conf: unknown value to domain_strip \"%s\"\n", val);
498 return 1; /* unknown value */
502 static int
503 gopt_exec_map_timeout(const char *val)
505 gopt.exec_map_timeout = atoi(val);
506 if (gopt.exec_map_timeout <= 0)
507 gopt.exec_map_timeout = AMFS_EXEC_MAP_TIMEOUT; /* default exec map timeout */
508 return 0;
512 static int
513 gopt_forced_unmounts(const char *val)
515 if (STREQ(val, "yes")) {
516 #if !defined(MNT2_GEN_OPT_DETACH) && !defined(MNT2_GEN_OPT_FORCE)
517 fprintf(stderr, "conf: forced_unmounts unsupported on this system.\n");
518 return 1;
519 #else /* defined(MNT2_GEN_OPT_DETACH) || defined(MNT2_GEN_OPT_FORCE) */
520 # ifdef __linux__
522 * HACK ALERT: Linux has had MNT_FORCE since 2.2, but it hasn't gotten
523 * stable until 2.4. And it had MNT_DETACH since 2.4, but it hasn't
524 * gotten stable since 2.6. So alert users if they're trying to use a
525 * feature that may not work well on their older kernel.
528 struct utsname un;
529 if (uname(&un) >= 0) {
530 # ifdef MNT2_GEN_OPT_FORCE
531 if (strcmp(un.release, "2.4.0") < 0)
532 fprintf(stderr, "warning: forced-unmounts (MNT_FORCE) may not work well before 2.4.0\n");
533 # endif /* MNT2_GEN_OPT_FORCE */
534 # ifdef MNT2_GEN_OPT_DETACH
535 if (strcmp(un.release, "2.6.0") < 0)
536 fprintf(stderr, "warning: lazy-unmounts (MNT_DETACH) may not work well before 2.6.0\n");
537 # endif /* MNT2_GEN_OPT_DETACH */
540 # endif /* __linux__ */
541 gopt.flags |= CFM_FORCED_UNMOUNTS;
542 return 0;
543 #endif /* defined(MNT2_GEN_OPT_DETACH) || defined(MNT2_GEN_OPT_FORCE) */
544 } else if (STREQ(val, "no")) {
545 gopt.flags &= ~CFM_FORCED_UNMOUNTS;
546 return 0;
549 fprintf(stderr, "conf: unknown value to unmount_on_exit \"%s\"\n", val);
550 return 1; /* unknown value */
554 static int
555 gopt_full_os(const char *val)
557 gopt.op_sys_full = strdup((char *)val);
558 return 0;
562 static int
563 gopt_fully_qualified_hosts(const char *val)
565 if (STREQ(val, "yes")) {
566 gopt.flags |= CFM_FULLY_QUALIFIED_HOSTS;
567 return 0;
568 } else if (STREQ(val, "no")) {
569 gopt.flags &= ~CFM_FULLY_QUALIFIED_HOSTS;
570 return 0;
573 fprintf(stderr, "conf: unknown value to fully_qualified_hosts \"%s\"\n", val);
574 return 1; /* unknown value */
578 static int
579 gopt_hesiod_base(const char *val)
581 #ifdef HAVE_MAP_HESIOD
582 gopt.hesiod_base = strdup((char *)val);
583 return 0;
584 #else /* not HAVE_MAP_HESIOD */
585 fprintf(stderr, "conf: hesiod_base option ignored. No Hesiod support available.\n");
586 return 1;
587 #endif /* not HAVE_MAP_HESIOD */
591 static int
592 gopt_karch(const char *val)
594 gopt.karch = strdup((char *)val);
595 return 0;
599 static int
600 gopt_pid_file(const char *val)
602 gopt.pid_file = strdup((char *)val);
603 return 0;
607 static int
608 gopt_local_domain(const char *val)
610 gopt.sub_domain = strdup((char *)val);
611 return 0;
615 static int
616 gopt_localhost_address(const char *val)
618 gopt.localhost_address = strdup((char *)val);
619 return 0;
623 static int
624 gopt_ldap_base(const char *val)
626 #ifdef HAVE_MAP_LDAP
627 gopt.ldap_base = strdup((char *)val);
628 return 0;
629 #else /* not HAVE_MAP_LDAP */
630 fprintf(stderr, "conf: ldap_base option ignored. No LDAP support available.\n");
631 return 1;
632 #endif /* not HAVE_MAP_LDAP */
636 static int
637 gopt_ldap_cache_seconds(const char *val)
639 #ifdef HAVE_MAP_LDAP
640 char *end;
642 gopt.ldap_cache_seconds = strtol((char *)val, &end, 10);
643 if (end == val) {
644 fprintf(stderr, "conf: bad LDAP cache (seconds) option: %s\n",val);
645 return 1;
647 return 0;
648 #else /* not HAVE_MAP_LDAP */
649 fprintf(stderr, "conf: ldap_cache_seconds option ignored. No LDAP support available.\n");
650 return 1;
651 #endif /* not HAVE_MAP_LDAP */
655 static int
656 gopt_ldap_cache_maxmem(const char *val)
658 #ifdef HAVE_MAP_LDAP
659 char *end;
661 gopt.ldap_cache_maxmem = strtol((char *)val, &end, 10);
662 if (end == val) {
663 fprintf(stderr, "conf: bad LDAP cache (maxmem) option: %s\n",val);
664 return 1;
666 return 0;
667 #else /* not HAVE_MAP_LDAP */
668 fprintf(stderr, "conf: ldap_cache_maxmem option ignored. No LDAP support available.\n");
669 return 1;
670 #endif /* not HAVE_MAP_LDAP */
674 static int
675 gopt_ldap_hostports(const char *val)
677 #ifdef HAVE_MAP_LDAP
678 gopt.ldap_hostports = strdup((char *)val);
679 return 0;
680 #else /* not HAVE_MAP_LDAP */
681 fprintf(stderr, "conf: ldap_hostports option ignored. No LDAP support available.\n");
682 return 1;
683 #endif /* not HAVE_MAP_LDAP */
688 static int
689 gopt_ldap_proto_version(const char *val)
691 #ifdef HAVE_MAP_LDAP
692 char *end;
694 gopt.ldap_proto_version = strtol((char *)val, &end, 10);
695 if (end == val) {
696 fprintf(stderr, "conf: bad ldap_proto_version option: %s\n",val);
697 return 1;
700 if (gopt.ldap_proto_version < 0 || gopt.ldap_proto_version > LDAP_VERSION_MAX) {
701 fprintf(stderr, "conf: bad ldap_proto_version option value: %s\n",val);
702 return 1;
704 switch (gopt.ldap_proto_version) {
705 /* XXX: what about LDAP_VERSION1? */
706 case LDAP_VERSION2:
707 #ifdef LDAP_VERSION3
708 case LDAP_VERSION3:
709 #endif /* LDAP_VERSION3 */
710 #ifdef LDAP_VERSION4
711 case LDAP_VERSION4:
712 #endif /* LDAP_VERSION4 */
713 break;
714 default:
715 fprintf(stderr, "conf: unsupported ldap_proto_version option value: %s\n",val);
716 return 1;
718 return 0;
719 #else /* not HAVE_MAP_LDAP */
720 fprintf(stderr, "conf: ldap_proto_version option ignored. No LDAP support available.\n");
721 return 1;
722 #endif /* not HAVE_MAP_LDAP */
726 static int
727 gopt_log_file(const char *val)
729 gopt.logfile = strdup((char *)val);
730 return 0;
734 static int
735 gopt_log_options(const char *val)
737 usage += switch_option((char *)val);
738 return 0;
742 static int
743 gopt_map_defaults(const char *val)
745 gopt.map_defaults = strdup((char *)val);
746 return 0;
750 static int
751 gopt_map_options(const char *val)
753 gopt.map_options = strdup((char *)val);
754 return 0;
758 static int
759 gopt_map_reload_interval(const char *val)
761 gopt.map_reload_interval = atoi(val);
762 if (gopt.map_reload_interval <= 0)
763 gopt.map_reload_interval = ONE_HOUR;
764 return 0;
768 static int
769 gopt_map_type(const char *val)
771 /* check if map type exist */
772 if (!mapc_type_exists(val)) {
773 fprintf(stderr, "conf: no such map type \"%s\"\n", val);
774 return 1;
776 gopt.map_type = strdup((char *)val);
777 return 0;
781 static int
782 gopt_mount_type(const char *val)
784 if (STREQ(val, "autofs")) {
785 #ifdef HAVE_FS_AUTOFS
786 gopt.flags |= CFM_MOUNT_TYPE_AUTOFS;
787 amd_use_autofs++;
788 return 0;
789 #else /* not HAVE_FS_AUTOFS */
790 fprintf(stderr, "conf: no autofs support available\n");
791 return 1;
792 #endif /* not HAVE_FS_AUTOFS */
793 } else if (STREQ(val, "nfs")) {
794 gopt.flags &= ~CFM_MOUNT_TYPE_AUTOFS;
795 return 0;
798 fprintf(stderr, "conf: unknown value to mount_type \"%s\"\n", val);
799 return 1; /* unknown value */
803 static int
804 gopt_portmap_program(const char *val)
806 gopt.portmap_program = atol(val);
808 * allow alternate program numbers to be no more than 10 offset from
809 * official amd program number (300019).
811 if (gopt.portmap_program < AMQ_PROGRAM ||
812 gopt.portmap_program > AMQ_PROGRAM + 10) {
813 gopt.portmap_program = AMQ_PROGRAM;
814 set_amd_program_number(gopt.portmap_program);
815 fprintf(stderr, "conf: illegal amd program number \"%s\"\n", val);
816 return 1;
819 set_amd_program_number(gopt.portmap_program);
820 return 0; /* all is OK */
824 static int
825 gopt_preferred_amq_port(const char *val)
827 gopt.preferred_amq_port = atoi(val);
830 * No need to check value: preferred_amq_port is an unsigned short and 0
831 * is a valid number, meaning "any port".
833 return 0; /* all is OK */
837 static int
838 gopt_nfs_allow_any_interface(const char *val)
840 if (STREQ(val, "yes")) {
841 gopt.flags |= CFM_NFS_ANY_INTERFACE;
842 return 0;
843 } else if (STREQ(val, "no")) {
844 gopt.flags &= ~CFM_NFS_ANY_INTERFACE;
845 return 0;
848 fprintf(stderr, "conf: unknown value to nfs_allow_insecure_port \"%s\"\n", val);
849 return 1; /* unknown value */
853 static int
854 gopt_nfs_allow_insecure_port(const char *val)
856 if (STREQ(val, "yes")) {
857 gopt.flags |= CFM_NFS_INSECURE_PORT;
858 return 0;
859 } else if (STREQ(val, "no")) {
860 gopt.flags &= ~CFM_NFS_INSECURE_PORT;
861 return 0;
864 fprintf(stderr, "conf: unknown value to nfs_allow_insecure_port \"%s\"\n", val);
865 return 1; /* unknown value */
869 static int
870 gopt_nfs_proto(const char *val)
872 if (STREQ(val, "udp") || STREQ(val, "tcp")) {
873 gopt.nfs_proto = strdup((char *)val);
874 return 0;
876 fprintf(stderr, "conf: illegal nfs_proto \"%s\"\n", val);
877 return 1;
881 static int
882 gopt_nfs_retransmit_counter(const char *val)
884 int i;
886 for (i=0; i<AMU_TYPE_MAX; ++i)
887 gopt.amfs_auto_retrans[i] = atoi(val);
888 return 0;
892 static int
893 gopt_nfs_retransmit_counter_udp(const char *val)
895 gopt.amfs_auto_retrans[AMU_TYPE_UDP] = atoi(val);
896 return 0;
900 static int
901 gopt_nfs_retransmit_counter_tcp(const char *val)
903 gopt.amfs_auto_retrans[AMU_TYPE_TCP] = atoi(val);
904 return 0;
908 static int
909 gopt_nfs_retransmit_counter_toplvl(const char *val)
911 gopt.amfs_auto_retrans[AMU_TYPE_TOPLVL] = atoi(val);
912 return 0;
916 static int
917 gopt_nfs_retry_interval(const char *val)
919 int i;
921 for (i=0; i<AMU_TYPE_MAX; ++i)
922 gopt.amfs_auto_timeo[i] = atoi(val);
923 return 0;
927 static int
928 gopt_nfs_retry_interval_udp(const char *val)
930 gopt.amfs_auto_timeo[AMU_TYPE_UDP] = atoi(val);
931 return 0;
935 static int
936 gopt_nfs_retry_interval_tcp(const char *val)
938 gopt.amfs_auto_timeo[AMU_TYPE_TCP] = atoi(val);
939 return 0;
943 static int
944 gopt_nfs_retry_interval_toplvl(const char *val)
946 gopt.amfs_auto_timeo[AMU_TYPE_TOPLVL] = atoi(val);
947 return 0;
951 static int
952 gopt_nfs_vers(const char *val)
954 int i = atoi(val);
956 if (i == 2 || i == 3) {
957 gopt.nfs_vers = i;
958 return 0;
960 fprintf(stderr, "conf: illegal nfs_vers \"%s\"\n", val);
961 return 1;
965 static int
966 gopt_nis_domain(const char *val)
968 #ifdef HAVE_MAP_NIS
969 gopt.nis_domain = strdup((char *)val);
970 return 0;
971 #else /* not HAVE_MAP_NIS */
972 fprintf(stderr, "conf: nis_domain option ignored. No NIS support available.\n");
973 return 1;
974 #endif /* not HAVE_MAP_NIS */
978 static int
979 gopt_normalize_hostnames(const char *val)
981 if (STREQ(val, "yes")) {
982 gopt.flags |= CFM_NORMALIZE_HOSTNAMES;
983 return 0;
984 } else if (STREQ(val, "no")) {
985 gopt.flags &= ~CFM_NORMALIZE_HOSTNAMES;
986 return 0;
989 fprintf(stderr, "conf: unknown value to normalize_hostnames \"%s\"\n", val);
990 return 1; /* unknown value */
994 static int
995 gopt_normalize_slashes(const char *val)
997 if (STREQ(val, "yes")) {
998 gopt.flags |= CFM_NORMALIZE_SLASHES;
999 return 0;
1000 } else if (STREQ(val, "no")) {
1001 gopt.flags &= ~CFM_NORMALIZE_SLASHES;
1002 return 0;
1005 fprintf(stderr, "conf: unknown value to normalize_slashes \"%s\"\n", val);
1006 return 1; /* unknown value */
1010 static int
1011 gopt_os(const char *val)
1013 gopt.op_sys = strdup((char *)val);
1014 return 0;
1018 static int
1019 gopt_osver(const char *val)
1021 gopt.op_sys_ver = strdup((char *)val);
1022 return 0;
1026 static int
1027 gopt_plock(const char *val)
1029 if (STREQ(val, "yes")) {
1030 gopt.flags |= CFM_PROCESS_LOCK;
1031 return 0;
1032 } else if (STREQ(val, "no")) {
1033 gopt.flags &= ~CFM_PROCESS_LOCK;
1034 return 0;
1037 fprintf(stderr, "conf: unknown value to plock \"%s\"\n", val);
1038 return 1; /* unknown value */
1042 static int
1043 gopt_print_pid(const char *val)
1045 if (STREQ(val, "yes")) {
1046 gopt.flags |= CFM_PRINT_PID;
1047 return 0;
1048 } else if (STREQ(val, "no")) {
1049 gopt.flags &= ~CFM_PRINT_PID;
1050 return 0;
1053 fprintf(stderr, "conf: unknown value to print_pid \"%s\"\n", val);
1054 return 1; /* unknown value */
1058 static int
1059 gopt_print_version(const char *val)
1061 if (STREQ(val, "yes")) {
1062 char *vers = get_version_string();
1063 fputs(vers, stderr);
1064 XFREE(vers);
1065 return 0;
1066 } else if (STREQ(val, "no")) {
1067 return 0;
1070 fprintf(stderr, "conf: unknown value to print_version \"%s\"\n", val);
1071 return 1; /* unknown value */
1075 static int
1076 gopt_restart_mounts(const char *val)
1078 if (STREQ(val, "yes")) {
1079 gopt.flags |= CFM_RESTART_EXISTING_MOUNTS;
1080 return 0;
1081 } else if (STREQ(val, "no")) {
1082 gopt.flags &= ~CFM_RESTART_EXISTING_MOUNTS;
1083 return 0;
1086 fprintf(stderr, "conf: unknown value to restart_mounts \"%s\"\n", val);
1087 return 1; /* unknown value */
1091 static int
1092 gopt_search_path(const char *val)
1094 gopt.search_path = strdup((char *)val);
1095 return 0;
1099 static int
1100 gopt_selectors_in_defaults(const char *val)
1102 if (STREQ(val, "yes")) {
1103 gopt.flags |= CFM_SELECTORS_IN_DEFAULTS;
1104 return 0;
1105 } else if (STREQ(val, "no")) {
1106 gopt.flags &= ~CFM_SELECTORS_IN_DEFAULTS;
1107 return 0;
1110 fprintf(stderr, "conf: unknown value to enable_default_selectors \"%s\"\n", val);
1111 return 1; /* unknown value */
1115 static int
1116 gopt_show_statfs_entries(const char *val)
1118 if (STREQ(val, "yes")) {
1119 gopt.flags |= CFM_SHOW_STATFS_ENTRIES;
1120 return 0;
1121 } else if (STREQ(val, "no")) {
1122 gopt.flags &= ~CFM_SHOW_STATFS_ENTRIES;
1123 return 0;
1126 fprintf(stderr, "conf: unknown value to show_statfs_entries \"%s\"\n", val);
1127 return 1; /* unknown value */
1131 static int
1132 gopt_sun_map_syntax(const char *val)
1134 if (STREQ(val, "yes")) {
1135 gopt.flags |= CFM_SUN_MAP_SYNTAX;
1136 return 0;
1137 } else if (STREQ(val, "no")) {
1138 gopt.flags &= ~CFM_SUN_MAP_SYNTAX;
1139 return 0;
1142 fprintf(stderr, "conf: unknown value to sun_map_syntax \"%s\"\n", val);
1143 return 1; /* unknown value */
1147 static int
1148 gopt_truncate_log(const char *val)
1150 if (STREQ(val, "yes")) {
1151 gopt.flags |= CFM_TRUNCATE_LOG;
1152 return 0;
1153 } else if (STREQ(val, "no")) {
1154 gopt.flags &= ~CFM_TRUNCATE_LOG;
1155 return 0;
1158 fprintf(stderr, "conf: unknown value to truncate_log \"%s\"\n", val);
1159 return 1; /* unknown value */
1163 static int
1164 gopt_unmount_on_exit(const char *val)
1166 if (STREQ(val, "yes")) {
1167 gopt.flags |= CFM_UNMOUNT_ON_EXIT;
1168 return 0;
1169 } else if (STREQ(val, "no")) {
1170 gopt.flags &= ~CFM_UNMOUNT_ON_EXIT;
1171 return 0;
1174 fprintf(stderr, "conf: unknown value to unmount_on_exit \"%s\"\n", val);
1175 return 1; /* unknown value */
1179 static int
1180 gopt_use_tcpwrappers(const char *val)
1182 #if defined(HAVE_TCPD_H) && defined(HAVE_LIBWRAP)
1183 if (STREQ(val, "yes")) {
1184 gopt.flags |= CFM_USE_TCPWRAPPERS;
1185 return 0;
1186 } else if (STREQ(val, "no")) {
1187 gopt.flags &= ~CFM_USE_TCPWRAPPERS;
1188 return 0;
1190 #else /* not defined(HAVE_TCPD_H) && defined(HAVE_LIBWRAP) */
1191 fprintf(stderr, "conf: no tcpd/libwrap support available\n");
1192 return 1;
1193 #endif /* not defined(HAVE_TCPD_H) && defined(HAVE_LIBWRAP) */
1195 fprintf(stderr, "conf: unknown value to use_tcpwrappers \"%s\"\n", val);
1196 return 1; /* unknown value */
1200 static int
1201 gopt_vendor(const char *val)
1203 gopt.op_sys_vendor = strdup((char *)val);
1204 return 0;
1209 * Collect one entry for a regular map
1211 static int
1212 process_regular_option(const char *section, const char *key, const char *val, cf_map_t *cfm)
1214 /* ensure that val is valid */
1215 if (!section || section[0] == '\0' ||
1216 !key || key[0] == '\0' ||
1217 !val || val[0] == '\0' ||
1218 !cfm) {
1219 fprintf(stderr, "conf: process_regular_option: null entries\n");
1220 return 1;
1223 /* check if initializing a new map */
1224 if (!cfm->cfm_dir)
1225 cfm->cfm_dir = strdup((char *)section);
1227 /* check for each possible field */
1228 if (STREQ(key, "browsable_dirs"))
1229 return ropt_browsable_dirs(val, cfm);
1231 if (STREQ(key, "map_name"))
1232 return ropt_map_name(val, cfm);
1234 if (STREQ(key, "map_defaults"))
1235 return ropt_map_defaults(val, cfm);
1237 if (STREQ(key, "map_options"))
1238 return ropt_map_options(val, cfm);
1240 if (STREQ(key, "map_type"))
1241 return ropt_map_type(val, cfm);
1243 if (STREQ(key, "mount_type"))
1244 return ropt_mount_type(val, cfm);
1246 if (STREQ(key, "search_path"))
1247 return ropt_search_path(val, cfm);
1249 if (STREQ(key, "sun_map_syntax"))
1250 return ropt_sun_map_syntax(val, cfm);
1252 if (STREQ(key, "tag"))
1253 return ropt_tag(val, cfm);
1255 fprintf(stderr, "conf: unknown regular key \"%s\" for section \"%s\"\n",
1256 key, section);
1257 return 1; /* failed to match any command */
1261 static int
1262 ropt_browsable_dirs(const char *val, cf_map_t *cfm)
1264 if (STREQ(val, "full")) {
1265 cfm->cfm_flags |= CFM_BROWSABLE_DIRS_FULL;
1266 return 0;
1267 } else if (STREQ(val, "yes")) {
1268 cfm->cfm_flags |= CFM_BROWSABLE_DIRS;
1269 return 0;
1270 } else if (STREQ(val, "no")) {
1271 cfm->cfm_flags &= ~CFM_BROWSABLE_DIRS;
1272 return 0;
1275 fprintf(stderr, "conf: unknown value to browsable_dirs \"%s\"\n", val);
1276 return 1; /* unknown value */
1280 static int
1281 ropt_map_name(const char *val, cf_map_t *cfm)
1283 cfm->cfm_name = strdup((char *)val);
1284 return 0;
1288 static int
1289 ropt_map_defaults(const char *val, cf_map_t *cfm)
1291 cfm->cfm_defaults = strdup((char *)val);
1292 return 0;
1296 static int
1297 ropt_map_options(const char *val, cf_map_t *cfm)
1299 cfm->cfm_opts = strdup((char *)val);
1300 return 0;
1304 static int
1305 ropt_map_type(const char *val, cf_map_t *cfm)
1307 /* check if map type exist */
1308 if (!mapc_type_exists(val)) {
1309 fprintf(stderr, "conf: no such map type \"%s\"\n", val);
1310 return 1;
1312 cfm->cfm_type = strdup((char *)val);
1313 return 0;
1317 static int
1318 ropt_mount_type(const char *val, cf_map_t *cfm)
1320 if (STREQ(val, "autofs")) {
1321 #ifdef HAVE_FS_AUTOFS
1322 cfm->cfm_flags |= CFM_MOUNT_TYPE_AUTOFS;
1323 amd_use_autofs++;
1324 return 0;
1325 #else /* not HAVE_FS_AUTOFS */
1326 fprintf(stderr, "conf: no autofs support available\n");
1327 return 1;
1328 #endif /* not HAVE_FS_AUTOFS */
1329 } else if (STREQ(val, "nfs")) {
1330 cfm->cfm_flags &= ~CFM_MOUNT_TYPE_AUTOFS;
1331 return 0;
1334 fprintf(stderr, "conf: unknown value to mount_type \"%s\"\n", val);
1335 return 1; /* unknown value */
1339 static int
1340 ropt_search_path(const char *val, cf_map_t *cfm)
1342 cfm->cfm_search_path = strdup((char *)val);
1343 return 0;
1347 static int
1348 ropt_sun_map_syntax(const char *val, cf_map_t *cfm)
1350 if (STREQ(val, "yes")) {
1351 cfm->cfm_flags |= CFM_SUN_MAP_SYNTAX;
1352 return 0;
1354 } else if (STREQ(val, "no")) {
1355 cfm->cfm_flags &= ~CFM_SUN_MAP_SYNTAX;
1356 return 0;
1359 fprintf(stderr, "conf: unknown value to sun_map_syntax \"%s\"\n", val);
1360 return 1; /* unknown value */
1364 static int
1365 ropt_tag(const char *val, cf_map_t *cfm)
1367 cfm->cfm_tag = strdup((char *)val);
1368 return 0;
1373 * Process one collected map.
1375 static int
1376 process_one_regular_map(const cf_map_t *cfm)
1378 if (!cfm->cfm_name) {
1379 fprintf(stderr, "conf: map_name must be defined for map \"%s\"\n", cfm->cfm_dir);
1380 return 1;
1383 * If map has no tag defined, process the map.
1384 * If no conf_tag was set in amd -T, process all untagged entries.
1385 * If a tag is defined, then process it only if it matches the map tag.
1387 if (!cfm->cfm_tag ||
1388 (conf_tag && STREQ(cfm->cfm_tag, conf_tag))) {
1389 #ifdef DEBUG_CONF
1390 fprintf(stderr, "processing map %s (flags=0x%x)...\n",
1391 cfm->cfm_dir, cfm->cfm_flags);
1392 #endif /* DEBUG_CONF */
1393 root_newmap(cfm->cfm_dir,
1394 cfm->cfm_opts ? cfm->cfm_opts : "",
1395 cfm->cfm_name,
1396 cfm);
1397 } else {
1398 fprintf(stderr, "skipping map %s...\n", cfm->cfm_dir);
1401 return 0;
1406 * Process all regular maps in conf file (if any)
1409 process_all_regular_maps(void)
1411 cf_map_t *tmp_map = head_map;
1414 * If the amd.conf file only has a [global] section (pretty useless
1415 * IMHO), there's nothing to process
1417 if (!tmp_map)
1418 return 0;
1420 while (tmp_map) {
1421 if (process_one_regular_map(tmp_map) != 0)
1422 return 1;
1423 tmp_map = tmp_map->cfm_next;
1425 return 0;
1430 * Find a cf_map_t for a given map name.
1431 * Return NULL if not found.
1433 cf_map_t *
1434 find_cf_map(const char *name)
1437 cf_map_t *tmp_map = head_map;
1439 if (!tmp_map || !name)
1440 return NULL;
1442 while (tmp_map) {
1443 if (STREQ(tmp_map->cfm_dir, name)) {
1444 return tmp_map;
1446 tmp_map = tmp_map->cfm_next;
1448 return NULL;