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.
8 * This code is derived from software contributed to Berkeley by
9 * Jan-Simon Pendry at Imperial College, London.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
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.
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
36 * File: am-utils/amd/conf.c
41 * Functions to handle the configuration file.
46 #endif /* HAVE_CONFIG_H */
54 /* Turn on to show some info about maps being configured */
55 /* #define DEBUG_CONF */
60 typedef int (*OptFuncPtr)(const char *);
71 * FORWARD DECLARATIONS:
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);
156 static cf_map_t *head_map, *cur_map;
158 static struct _func_map glob_functable[] = {
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},
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},
230 * Initialize a map from [global] defaults.
233 init_cf_map(cf_map_t *cfm)
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.
244 * (1): Will only work for maps that appear after [global].
245 * (2): I'm assigning pointers directly from the global map.
248 /* initialize map_type from [global] */
249 cfm->cfm_type = gopt.map_type;
251 /* initialize map_defaults from [global] */
252 cfm->cfm_defaults = gopt.map_defaults;
254 /* initialize map_opts from [global] */
255 cfm->cfm_opts = gopt.map_options;
257 /* initialize search_path from [global] */
258 cfm->cfm_search_path = gopt.search_path;
261 * Initialize flags that are common both to [global] and a local map
262 * (that is, they could be inherited from the global section).
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 );
273 * Process configuration file options (called from YACC parser).
274 * Return 0 if OK, 1 otherwise.
277 set_conf_kv(const char *section, const char *key, const char *val)
282 fprintf(stderr, "set_conf_kv: section=%s, key=%s, val=%s\n",
284 #endif /* DEBUG_CONF */
287 * If global section, process kv pairs one at a time.
289 if (STREQ(section, "global")) {
291 * Check if a regular map was configured before "global",
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",
299 printed_this_error = 1;
303 /* process the global option first */
304 ret = process_global_option(key, val);
306 /* return status from the processing of the global option */
311 * Otherwise we found a non-global option: store it after some testing.
314 /* initialize (static) global list head and current map pointer */
315 if (!head_map && !cur_map) {
316 cur_map = CALLOC(cf_map_t);
321 /* initialize first head map from global defaults */
322 init_cf_map(cur_map);
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);
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;
341 /* now process a single entry of a regular map */
342 return process_regular_option(section, key, val, cur_map);
347 * Process global section of configuration file options.
348 * Return 0 upon success, 1 otherwise.
351 process_global_option(const char *key, const char *val)
353 struct _func_map *gfp;
355 /* ensure that val is valid */
356 if (!val || val[0] == '\0')
360 * search for global function.
362 for (gfp = glob_functable; gfp->name; gfp++)
363 if (FSTREQ(gfp->name, key))
364 return (gfp->func)(val);
366 fprintf(stderr, "conf: unknown global key: \"%s\"\n", key);
367 return 1; /* failed to match any command */
372 gopt_arch(const char *val)
374 gopt.arch = xstrdup(val);
380 gopt_auto_attrcache(const char *val)
382 gopt.auto_attrcache = atoi(val);
383 if (gopt.auto_attrcache < 0) {
384 fprintf(stderr, "conf: bad attrcache value: \"%s\"\n", val);
392 gopt_auto_dir(const char *val)
394 gopt.auto_dir = xstrdup(val);
399 gopt_auto_nfs_version(const char *val)
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;
406 fprintf(stderr, "conf: bad auto nfs version : \"%s\"\n", val);
413 gopt_autofs_use_lofs(const char *val)
415 if (STREQ(val, "yes")) {
416 gopt.flags |= CFM_AUTOFS_USE_LOFS;
418 } else if (STREQ(val, "no")) {
419 gopt.flags &= ~CFM_AUTOFS_USE_LOFS;
423 fprintf(stderr, "conf: unknown value to autofs_use_lofs \"%s\"\n", val);
424 return 1; /* unknown value */
429 gopt_browsable_dirs(const char *val)
431 if (STREQ(val, "full")) {
432 gopt.flags |= CFM_BROWSABLE_DIRS_FULL;
434 } else if (STREQ(val, "yes")) {
435 gopt.flags |= CFM_BROWSABLE_DIRS;
437 } else if (STREQ(val, "no")) {
438 gopt.flags &= ~CFM_BROWSABLE_DIRS;
442 fprintf(stderr, "conf: unknown value to browsable_dirs \"%s\"\n", val);
443 return 1; /* unknown value */
448 gopt_cache_duration(const char *val)
450 gopt.am_timeo = atoi(val);
451 if (gopt.am_timeo <= 0)
452 gopt.am_timeo = AM_TTL;
458 gopt_cluster(const char *val)
460 gopt.cluster = xstrdup(val);
466 gopt_debug_mtab_file(const char *val)
468 gopt.debug_mtab_file = xstrdup(val);
474 gopt_debug_options(const char *val)
477 usage += debug_option((char *)val);
479 #else /* not DEBUG */
480 fprintf(stderr, "%s: not compiled with DEBUG option -- sorry.\n",
483 #endif /* not DEBUG */
488 gopt_dismount_interval(const char *val)
490 gopt.am_timeo_w = atoi(val);
491 if (gopt.am_timeo_w <= 0)
492 gopt.am_timeo_w = AM_TTL_W;
498 gopt_domain_strip(const char *val)
500 if (STREQ(val, "yes")) {
501 gopt.flags |= CFM_DOMAIN_STRIP;
503 } else if (STREQ(val, "no")) {
504 gopt.flags &= ~CFM_DOMAIN_STRIP;
508 fprintf(stderr, "conf: unknown value to domain_strip \"%s\"\n", val);
509 return 1; /* unknown value */
514 gopt_exec_map_timeout(const char *val)
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 */
524 gopt_forced_unmounts(const char *val)
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");
530 #else /* defined(MNT2_GEN_OPT_DETACH) || defined(MNT2_GEN_OPT_FORCE) */
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.
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 */
551 # endif /* __linux__ */
552 gopt.flags |= CFM_FORCED_UNMOUNTS;
554 #endif /* defined(MNT2_GEN_OPT_DETACH) || defined(MNT2_GEN_OPT_FORCE) */
555 } else if (STREQ(val, "no")) {
556 gopt.flags &= ~CFM_FORCED_UNMOUNTS;
560 fprintf(stderr, "conf: unknown value to unmount_on_exit \"%s\"\n", val);
561 return 1; /* unknown value */
566 gopt_full_os(const char *val)
568 gopt.op_sys_full = xstrdup(val);
574 gopt_fully_qualified_hosts(const char *val)
576 if (STREQ(val, "yes")) {
577 gopt.flags |= CFM_FULLY_QUALIFIED_HOSTS;
579 } else if (STREQ(val, "no")) {
580 gopt.flags &= ~CFM_FULLY_QUALIFIED_HOSTS;
584 fprintf(stderr, "conf: unknown value to fully_qualified_hosts \"%s\"\n", val);
585 return 1; /* unknown value */
590 gopt_hesiod_base(const char *val)
592 #ifdef HAVE_MAP_HESIOD
593 gopt.hesiod_base = xstrdup(val);
595 #else /* not HAVE_MAP_HESIOD */
596 fprintf(stderr, "conf: hesiod_base option ignored. No Hesiod support available.\n");
598 #endif /* not HAVE_MAP_HESIOD */
603 gopt_karch(const char *val)
605 gopt.karch = xstrdup(val);
611 gopt_pid_file(const char *val)
613 gopt.pid_file = xstrdup(val);
619 gopt_local_domain(const char *val)
621 gopt.sub_domain = xstrdup(val);
627 gopt_localhost_address(const char *val)
629 gopt.localhost_address = xstrdup(val);
635 gopt_ldap_base(const char *val)
638 gopt.ldap_base = xstrdup(val);
640 #else /* not HAVE_MAP_LDAP */
641 fprintf(stderr, "conf: ldap_base option ignored. No LDAP support available.\n");
643 #endif /* not HAVE_MAP_LDAP */
648 gopt_ldap_cache_seconds(const char *val)
653 gopt.ldap_cache_seconds = strtol((char *)val, &end, 10);
655 fprintf(stderr, "conf: bad LDAP cache (seconds) option: %s\n",val);
659 #else /* not HAVE_MAP_LDAP */
660 fprintf(stderr, "conf: ldap_cache_seconds option ignored. No LDAP support available.\n");
662 #endif /* not HAVE_MAP_LDAP */
667 gopt_ldap_cache_maxmem(const char *val)
672 gopt.ldap_cache_maxmem = strtol((char *)val, &end, 10);
674 fprintf(stderr, "conf: bad LDAP cache (maxmem) option: %s\n",val);
678 #else /* not HAVE_MAP_LDAP */
679 fprintf(stderr, "conf: ldap_cache_maxmem option ignored. No LDAP support available.\n");
681 #endif /* not HAVE_MAP_LDAP */
686 gopt_ldap_hostports(const char *val)
689 gopt.ldap_hostports = xstrdup(val);
691 #else /* not HAVE_MAP_LDAP */
692 fprintf(stderr, "conf: ldap_hostports option ignored. No LDAP support available.\n");
694 #endif /* not HAVE_MAP_LDAP */
700 gopt_ldap_proto_version(const char *val)
705 gopt.ldap_proto_version = strtol((char *)val, &end, 10);
707 fprintf(stderr, "conf: bad ldap_proto_version option: %s\n",val);
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);
715 switch (gopt.ldap_proto_version) {
716 /* XXX: what about LDAP_VERSION1? */
720 #endif /* LDAP_VERSION3 */
723 #endif /* LDAP_VERSION4 */
726 fprintf(stderr, "conf: unsupported ldap_proto_version option value: %s\n",val);
730 #else /* not HAVE_MAP_LDAP */
731 fprintf(stderr, "conf: ldap_proto_version option ignored. No LDAP support available.\n");
733 #endif /* not HAVE_MAP_LDAP */
738 gopt_log_file(const char *val)
740 gopt.logfile = xstrdup(val);
746 gopt_log_options(const char *val)
748 usage += switch_option((char *)val);
754 gopt_map_defaults(const char *val)
756 gopt.map_defaults = xstrdup(val);
762 gopt_map_options(const char *val)
764 gopt.map_options = xstrdup(val);
770 gopt_map_reload_interval(const char *val)
772 gopt.map_reload_interval = atoi(val);
773 if (gopt.map_reload_interval <= 0)
774 gopt.map_reload_interval = ONE_HOUR;
780 gopt_map_type(const char *val)
782 /* check if map type exist */
783 if (!mapc_type_exists(val)) {
784 fprintf(stderr, "conf: no such map type \"%s\"\n", val);
787 gopt.map_type = xstrdup(val);
793 gopt_mount_type(const char *val)
795 if (STREQ(val, "autofs")) {
796 #ifdef HAVE_FS_AUTOFS
797 gopt.flags |= CFM_MOUNT_TYPE_AUTOFS;
800 #else /* not HAVE_FS_AUTOFS */
801 fprintf(stderr, "conf: no autofs support available\n");
803 #endif /* not HAVE_FS_AUTOFS */
804 } else if (STREQ(val, "nfs")) {
805 gopt.flags &= ~CFM_MOUNT_TYPE_AUTOFS;
809 fprintf(stderr, "conf: unknown value to mount_type \"%s\"\n", val);
810 return 1; /* unknown value */
815 gopt_portmap_program(const char *val)
817 gopt.portmap_program = atol(val);
819 * allow alternate program numbers to be no more than 10 offset from
820 * official amd program number (300019).
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);
830 set_amd_program_number(gopt.portmap_program);
831 return 0; /* all is OK */
836 gopt_preferred_amq_port(const char *val)
838 gopt.preferred_amq_port = atoi(val);
841 * No need to check value: preferred_amq_port is an unsigned short and 0
842 * is a valid number, meaning "any port".
844 return 0; /* all is OK */
849 gopt_nfs_allow_any_interface(const char *val)
851 if (STREQ(val, "yes")) {
852 gopt.flags |= CFM_NFS_ANY_INTERFACE;
854 } else if (STREQ(val, "no")) {
855 gopt.flags &= ~CFM_NFS_ANY_INTERFACE;
859 fprintf(stderr, "conf: unknown value to nfs_allow_insecure_port \"%s\"\n", val);
860 return 1; /* unknown value */
865 gopt_nfs_allow_insecure_port(const char *val)
867 if (STREQ(val, "yes")) {
868 gopt.flags |= CFM_NFS_INSECURE_PORT;
870 } else if (STREQ(val, "no")) {
871 gopt.flags &= ~CFM_NFS_INSECURE_PORT;
875 fprintf(stderr, "conf: unknown value to nfs_allow_insecure_port \"%s\"\n", val);
876 return 1; /* unknown value */
881 gopt_nfs_proto(const char *val)
883 if (STREQ(val, "udp") || STREQ(val, "tcp")) {
884 gopt.nfs_proto = xstrdup(val);
887 fprintf(stderr, "conf: illegal nfs_proto \"%s\"\n", val);
893 gopt_nfs_retransmit_counter(const char *val)
897 for (i=0; i<AMU_TYPE_MAX; ++i)
898 gopt.amfs_auto_retrans[i] = atoi(val);
904 gopt_nfs_retransmit_counter_udp(const char *val)
906 gopt.amfs_auto_retrans[AMU_TYPE_UDP] = atoi(val);
912 gopt_nfs_retransmit_counter_tcp(const char *val)
914 gopt.amfs_auto_retrans[AMU_TYPE_TCP] = atoi(val);
920 gopt_nfs_retransmit_counter_toplvl(const char *val)
922 gopt.amfs_auto_retrans[AMU_TYPE_TOPLVL] = atoi(val);
928 gopt_nfs_retry_interval(const char *val)
932 for (i=0; i<AMU_TYPE_MAX; ++i)
933 gopt.amfs_auto_timeo[i] = atoi(val);
939 gopt_nfs_retry_interval_udp(const char *val)
941 gopt.amfs_auto_timeo[AMU_TYPE_UDP] = atoi(val);
947 gopt_nfs_retry_interval_tcp(const char *val)
949 gopt.amfs_auto_timeo[AMU_TYPE_TCP] = atoi(val);
955 gopt_nfs_retry_interval_toplvl(const char *val)
957 gopt.amfs_auto_timeo[AMU_TYPE_TOPLVL] = atoi(val);
963 gopt_nfs_vers(const char *val)
967 if (i == 2 || i == 3 || i == 4) {
971 fprintf(stderr, "conf: illegal nfs_vers \"%s\"\n", val);
977 gopt_nfs_vers_ping(const char *val)
981 if (i == 2 || i == 3 || i == 4) {
982 gopt.nfs_vers_ping = i;
985 fprintf(stderr, "conf: illegal nfs_vers_ping \"%s\"\n", val);
990 gopt_nis_domain(const char *val)
993 gopt.nis_domain = xstrdup(val);
995 #else /* not HAVE_MAP_NIS */
996 fprintf(stderr, "conf: nis_domain option ignored. No NIS support available.\n");
998 #endif /* not HAVE_MAP_NIS */
1003 gopt_normalize_hostnames(const char *val)
1005 if (STREQ(val, "yes")) {
1006 gopt.flags |= CFM_NORMALIZE_HOSTNAMES;
1008 } else if (STREQ(val, "no")) {
1009 gopt.flags &= ~CFM_NORMALIZE_HOSTNAMES;
1013 fprintf(stderr, "conf: unknown value to normalize_hostnames \"%s\"\n", val);
1014 return 1; /* unknown value */
1019 gopt_normalize_slashes(const char *val)
1021 if (STREQ(val, "yes")) {
1022 gopt.flags |= CFM_NORMALIZE_SLASHES;
1024 } else if (STREQ(val, "no")) {
1025 gopt.flags &= ~CFM_NORMALIZE_SLASHES;
1029 fprintf(stderr, "conf: unknown value to normalize_slashes \"%s\"\n", val);
1030 return 1; /* unknown value */
1035 gopt_os(const char *val)
1037 gopt.op_sys = xstrdup(val);
1043 gopt_osver(const char *val)
1045 gopt.op_sys_ver = xstrdup(val);
1051 gopt_plock(const char *val)
1053 if (STREQ(val, "yes")) {
1054 gopt.flags |= CFM_PROCESS_LOCK;
1056 } else if (STREQ(val, "no")) {
1057 gopt.flags &= ~CFM_PROCESS_LOCK;
1061 fprintf(stderr, "conf: unknown value to plock \"%s\"\n", val);
1062 return 1; /* unknown value */
1067 gopt_print_pid(const char *val)
1069 if (STREQ(val, "yes")) {
1070 gopt.flags |= CFM_PRINT_PID;
1072 } else if (STREQ(val, "no")) {
1073 gopt.flags &= ~CFM_PRINT_PID;
1077 fprintf(stderr, "conf: unknown value to print_pid \"%s\"\n", val);
1078 return 1; /* unknown value */
1083 gopt_print_version(const char *val)
1085 if (STREQ(val, "yes")) {
1086 char *vers = get_version_string();
1087 fputs(vers, stderr);
1090 } else if (STREQ(val, "no")) {
1094 fprintf(stderr, "conf: unknown value to print_version \"%s\"\n", val);
1095 return 1; /* unknown value */
1100 gopt_restart_mounts(const char *val)
1102 if (STREQ(val, "yes")) {
1103 gopt.flags |= CFM_RESTART_EXISTING_MOUNTS;
1105 } else if (STREQ(val, "no")) {
1106 gopt.flags &= ~CFM_RESTART_EXISTING_MOUNTS;
1110 fprintf(stderr, "conf: unknown value to restart_mounts \"%s\"\n", val);
1111 return 1; /* unknown value */
1116 gopt_search_path(const char *val)
1118 gopt.search_path = xstrdup(val);
1124 gopt_selectors_in_defaults(const char *val)
1126 if (STREQ(val, "yes")) {
1127 gopt.flags |= CFM_SELECTORS_IN_DEFAULTS;
1129 } else if (STREQ(val, "no")) {
1130 gopt.flags &= ~CFM_SELECTORS_IN_DEFAULTS;
1134 fprintf(stderr, "conf: unknown value to enable_default_selectors \"%s\"\n", val);
1135 return 1; /* unknown value */
1140 gopt_show_statfs_entries(const char *val)
1142 if (STREQ(val, "yes")) {
1143 gopt.flags |= CFM_SHOW_STATFS_ENTRIES;
1145 } else if (STREQ(val, "no")) {
1146 gopt.flags &= ~CFM_SHOW_STATFS_ENTRIES;
1150 fprintf(stderr, "conf: unknown value to show_statfs_entries \"%s\"\n", val);
1151 return 1; /* unknown value */
1156 gopt_sun_map_syntax(const char *val)
1158 if (STREQ(val, "yes")) {
1159 gopt.flags |= CFM_SUN_MAP_SYNTAX;
1161 } else if (STREQ(val, "no")) {
1162 gopt.flags &= ~CFM_SUN_MAP_SYNTAX;
1166 fprintf(stderr, "conf: unknown value to sun_map_syntax \"%s\"\n", val);
1167 return 1; /* unknown value */
1172 gopt_truncate_log(const char *val)
1174 if (STREQ(val, "yes")) {
1175 gopt.flags |= CFM_TRUNCATE_LOG;
1177 } else if (STREQ(val, "no")) {
1178 gopt.flags &= ~CFM_TRUNCATE_LOG;
1182 fprintf(stderr, "conf: unknown value to truncate_log \"%s\"\n", val);
1183 return 1; /* unknown value */
1188 gopt_unmount_on_exit(const char *val)
1190 if (STREQ(val, "yes")) {
1191 gopt.flags |= CFM_UNMOUNT_ON_EXIT;
1193 } else if (STREQ(val, "no")) {
1194 gopt.flags &= ~CFM_UNMOUNT_ON_EXIT;
1198 fprintf(stderr, "conf: unknown value to unmount_on_exit \"%s\"\n", val);
1199 return 1; /* unknown value */
1204 gopt_use_tcpwrappers(const char *val)
1206 #if defined(HAVE_TCPD_H) && defined(HAVE_LIBWRAP)
1207 if (STREQ(val, "yes")) {
1208 gopt.flags |= CFM_USE_TCPWRAPPERS;
1210 } else if (STREQ(val, "no")) {
1211 gopt.flags &= ~CFM_USE_TCPWRAPPERS;
1214 #else /* not defined(HAVE_TCPD_H) && defined(HAVE_LIBWRAP) */
1215 fprintf(stderr, "conf: no tcpd/libwrap support available\n");
1217 #endif /* not defined(HAVE_TCPD_H) && defined(HAVE_LIBWRAP) */
1219 fprintf(stderr, "conf: unknown value to use_tcpwrappers \"%s\"\n", val);
1220 return 1; /* unknown value */
1225 gopt_vendor(const char *val)
1227 gopt.op_sys_vendor = xstrdup(val);
1233 * Collect one entry for a regular map
1236 process_regular_option(const char *section, const char *key, const char *val, cf_map_t *cfm)
1238 /* ensure that val is valid */
1239 if (!section || section[0] == '\0' ||
1240 !key || key[0] == '\0' ||
1241 !val || val[0] == '\0' ||
1243 fprintf(stderr, "conf: process_regular_option: null entries\n");
1247 /* check if initializing a new map */
1249 cfm->cfm_dir = xstrdup(section);
1251 /* check for each possible field */
1252 if (STREQ(key, "browsable_dirs"))
1253 return ropt_browsable_dirs(val, cfm);
1255 if (STREQ(key, "map_name"))
1256 return ropt_map_name(val, cfm);
1258 if (STREQ(key, "map_defaults"))
1259 return ropt_map_defaults(val, cfm);
1261 if (STREQ(key, "map_options"))
1262 return ropt_map_options(val, cfm);
1264 if (STREQ(key, "map_type"))
1265 return ropt_map_type(val, cfm);
1267 if (STREQ(key, "mount_type"))
1268 return ropt_mount_type(val, cfm);
1270 if (STREQ(key, "search_path"))
1271 return ropt_search_path(val, cfm);
1273 if (STREQ(key, "sun_map_syntax"))
1274 return ropt_sun_map_syntax(val, cfm);
1276 if (STREQ(key, "tag"))
1277 return ropt_tag(val, cfm);
1279 fprintf(stderr, "conf: unknown regular key \"%s\" for section \"%s\"\n",
1281 return 1; /* failed to match any command */
1286 ropt_browsable_dirs(const char *val, cf_map_t *cfm)
1288 if (STREQ(val, "full")) {
1289 cfm->cfm_flags |= CFM_BROWSABLE_DIRS_FULL;
1291 } else if (STREQ(val, "yes")) {
1292 cfm->cfm_flags |= CFM_BROWSABLE_DIRS;
1294 } else if (STREQ(val, "no")) {
1295 cfm->cfm_flags &= ~CFM_BROWSABLE_DIRS;
1299 fprintf(stderr, "conf: unknown value to browsable_dirs \"%s\"\n", val);
1300 return 1; /* unknown value */
1305 ropt_map_name(const char *val, cf_map_t *cfm)
1307 cfm->cfm_name = xstrdup(val);
1313 ropt_map_defaults(const char *val, cf_map_t *cfm)
1315 cfm->cfm_defaults = xstrdup(val);
1321 ropt_map_options(const char *val, cf_map_t *cfm)
1323 cfm->cfm_opts = xstrdup(val);
1329 ropt_map_type(const char *val, cf_map_t *cfm)
1331 /* check if map type exist */
1332 if (!mapc_type_exists(val)) {
1333 fprintf(stderr, "conf: no such map type \"%s\"\n", val);
1336 cfm->cfm_type = xstrdup(val);
1342 ropt_mount_type(const char *val, cf_map_t *cfm)
1344 if (STREQ(val, "autofs")) {
1345 #ifdef HAVE_FS_AUTOFS
1346 cfm->cfm_flags |= CFM_MOUNT_TYPE_AUTOFS;
1349 #else /* not HAVE_FS_AUTOFS */
1350 fprintf(stderr, "conf: no autofs support available\n");
1352 #endif /* not HAVE_FS_AUTOFS */
1353 } else if (STREQ(val, "nfs")) {
1354 cfm->cfm_flags &= ~CFM_MOUNT_TYPE_AUTOFS;
1358 fprintf(stderr, "conf: unknown value to mount_type \"%s\"\n", val);
1359 return 1; /* unknown value */
1364 ropt_search_path(const char *val, cf_map_t *cfm)
1366 cfm->cfm_search_path = xstrdup(val);
1372 ropt_sun_map_syntax(const char *val, cf_map_t *cfm)
1374 if (STREQ(val, "yes")) {
1375 cfm->cfm_flags |= CFM_SUN_MAP_SYNTAX;
1378 } else if (STREQ(val, "no")) {
1379 cfm->cfm_flags &= ~CFM_SUN_MAP_SYNTAX;
1383 fprintf(stderr, "conf: unknown value to sun_map_syntax \"%s\"\n", val);
1384 return 1; /* unknown value */
1389 ropt_tag(const char *val, cf_map_t *cfm)
1391 cfm->cfm_tag = xstrdup(val);
1397 * Process one collected map.
1400 process_one_regular_map(const cf_map_t *cfm)
1402 if (!cfm->cfm_name) {
1403 fprintf(stderr, "conf: map_name must be defined for map \"%s\"\n", cfm->cfm_dir);
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.
1411 if (!cfm->cfm_tag ||
1412 (conf_tag && STREQ(cfm->cfm_tag, conf_tag))) {
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 : "",
1422 fprintf(stderr, "skipping map %s...\n", cfm->cfm_dir);
1430 * Process all regular maps in conf file (if any)
1433 process_all_regular_maps(void)
1435 cf_map_t *tmp_map = head_map;
1438 * If the amd.conf file only has a [global] section (pretty useless
1439 * IMHO), there's nothing to process
1445 if (process_one_regular_map(tmp_map) != 0)
1447 tmp_map = tmp_map->cfm_next;
1454 * Find a cf_map_t for a given map name.
1455 * Return NULL if not found.
1458 find_cf_map(const char *name)
1461 cf_map_t *tmp_map = head_map;
1463 if (!tmp_map || !name)
1467 if (STREQ(tmp_map->cfm_dir, name)) {
1470 tmp_map = tmp_map->cfm_next;