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.
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
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
42 * File: am-utils/amd/conf.c
47 * Functions to handle the configuration file.
52 #endif /* HAVE_CONFIG_H */
60 /* Turn on to show some info about maps being configured */
61 /* #define DEBUG_CONF */
66 typedef int (*OptFuncPtr
)(const char *);
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
);
160 static cf_map_t
*head_map
, *cur_map
;
162 static struct _func_map glob_functable
[] = {
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
},
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
},
232 * Initialize a map from [global] defaults.
235 init_cf_map(cf_map_t
*cfm
)
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.
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
)
284 fprintf(stderr
, "set_conf_kv: section=%s, key=%s, val=%s\n",
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",
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",
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 */
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
);
323 /* initialize first head map from global defaults */
324 init_cf_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
);
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
;
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.
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')
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 */
374 gopt_arch(const char *val
)
376 gopt
.arch
= strdup((char *)val
);
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
);
394 gopt_auto_dir(const char *val
)
396 gopt
.auto_dir
= strdup((char *)val
);
402 gopt_autofs_use_lofs(const char *val
)
404 if (STREQ(val
, "yes")) {
405 gopt
.flags
|= CFM_AUTOFS_USE_LOFS
;
407 } else if (STREQ(val
, "no")) {
408 gopt
.flags
&= ~CFM_AUTOFS_USE_LOFS
;
412 fprintf(stderr
, "conf: unknown value to autofs_use_lofs \"%s\"\n", val
);
413 return 1; /* unknown value */
418 gopt_browsable_dirs(const char *val
)
420 if (STREQ(val
, "full")) {
421 gopt
.flags
|= CFM_BROWSABLE_DIRS_FULL
;
423 } else if (STREQ(val
, "yes")) {
424 gopt
.flags
|= CFM_BROWSABLE_DIRS
;
426 } else if (STREQ(val
, "no")) {
427 gopt
.flags
&= ~CFM_BROWSABLE_DIRS
;
431 fprintf(stderr
, "conf: unknown value to browsable_dirs \"%s\"\n", val
);
432 return 1; /* unknown value */
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
;
447 gopt_cluster(const char *val
)
449 gopt
.cluster
= strdup((char *)val
);
455 gopt_debug_mtab_file(const char *val
)
457 gopt
.debug_mtab_file
= strdup((char*)val
);
463 gopt_debug_options(const char *val
)
466 usage
+= debug_option((char *)val
);
468 #else /* not DEBUG */
469 fprintf(stderr
, "%s: not compiled with DEBUG option -- sorry.\n",
472 #endif /* not DEBUG */
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
;
487 gopt_domain_strip(const char *val
)
489 if (STREQ(val
, "yes")) {
490 gopt
.flags
|= CFM_DOMAIN_STRIP
;
492 } else if (STREQ(val
, "no")) {
493 gopt
.flags
&= ~CFM_DOMAIN_STRIP
;
497 fprintf(stderr
, "conf: unknown value to domain_strip \"%s\"\n", val
);
498 return 1; /* unknown value */
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 */
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");
519 #else /* defined(MNT2_GEN_OPT_DETACH) || defined(MNT2_GEN_OPT_FORCE) */
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.
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
;
543 #endif /* defined(MNT2_GEN_OPT_DETACH) || defined(MNT2_GEN_OPT_FORCE) */
544 } else if (STREQ(val
, "no")) {
545 gopt
.flags
&= ~CFM_FORCED_UNMOUNTS
;
549 fprintf(stderr
, "conf: unknown value to unmount_on_exit \"%s\"\n", val
);
550 return 1; /* unknown value */
555 gopt_full_os(const char *val
)
557 gopt
.op_sys_full
= strdup((char *)val
);
563 gopt_fully_qualified_hosts(const char *val
)
565 if (STREQ(val
, "yes")) {
566 gopt
.flags
|= CFM_FULLY_QUALIFIED_HOSTS
;
568 } else if (STREQ(val
, "no")) {
569 gopt
.flags
&= ~CFM_FULLY_QUALIFIED_HOSTS
;
573 fprintf(stderr
, "conf: unknown value to fully_qualified_hosts \"%s\"\n", val
);
574 return 1; /* unknown value */
579 gopt_hesiod_base(const char *val
)
581 #ifdef HAVE_MAP_HESIOD
582 gopt
.hesiod_base
= strdup((char *)val
);
584 #else /* not HAVE_MAP_HESIOD */
585 fprintf(stderr
, "conf: hesiod_base option ignored. No Hesiod support available.\n");
587 #endif /* not HAVE_MAP_HESIOD */
592 gopt_karch(const char *val
)
594 gopt
.karch
= strdup((char *)val
);
600 gopt_pid_file(const char *val
)
602 gopt
.pid_file
= strdup((char *)val
);
608 gopt_local_domain(const char *val
)
610 gopt
.sub_domain
= strdup((char *)val
);
616 gopt_localhost_address(const char *val
)
618 gopt
.localhost_address
= strdup((char *)val
);
624 gopt_ldap_base(const char *val
)
627 gopt
.ldap_base
= strdup((char *)val
);
629 #else /* not HAVE_MAP_LDAP */
630 fprintf(stderr
, "conf: ldap_base option ignored. No LDAP support available.\n");
632 #endif /* not HAVE_MAP_LDAP */
637 gopt_ldap_cache_seconds(const char *val
)
642 gopt
.ldap_cache_seconds
= strtol((char *)val
, &end
, 10);
644 fprintf(stderr
, "conf: bad LDAP cache (seconds) option: %s\n",val
);
648 #else /* not HAVE_MAP_LDAP */
649 fprintf(stderr
, "conf: ldap_cache_seconds option ignored. No LDAP support available.\n");
651 #endif /* not HAVE_MAP_LDAP */
656 gopt_ldap_cache_maxmem(const char *val
)
661 gopt
.ldap_cache_maxmem
= strtol((char *)val
, &end
, 10);
663 fprintf(stderr
, "conf: bad LDAP cache (maxmem) option: %s\n",val
);
667 #else /* not HAVE_MAP_LDAP */
668 fprintf(stderr
, "conf: ldap_cache_maxmem option ignored. No LDAP support available.\n");
670 #endif /* not HAVE_MAP_LDAP */
675 gopt_ldap_hostports(const char *val
)
678 gopt
.ldap_hostports
= strdup((char *)val
);
680 #else /* not HAVE_MAP_LDAP */
681 fprintf(stderr
, "conf: ldap_hostports option ignored. No LDAP support available.\n");
683 #endif /* not HAVE_MAP_LDAP */
689 gopt_ldap_proto_version(const char *val
)
694 gopt
.ldap_proto_version
= strtol((char *)val
, &end
, 10);
696 fprintf(stderr
, "conf: bad ldap_proto_version option: %s\n",val
);
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
);
704 switch (gopt
.ldap_proto_version
) {
705 /* XXX: what about LDAP_VERSION1? */
709 #endif /* LDAP_VERSION3 */
712 #endif /* LDAP_VERSION4 */
715 fprintf(stderr
, "conf: unsupported ldap_proto_version option value: %s\n",val
);
719 #else /* not HAVE_MAP_LDAP */
720 fprintf(stderr
, "conf: ldap_proto_version option ignored. No LDAP support available.\n");
722 #endif /* not HAVE_MAP_LDAP */
727 gopt_log_file(const char *val
)
729 gopt
.logfile
= strdup((char *)val
);
735 gopt_log_options(const char *val
)
737 usage
+= switch_option((char *)val
);
743 gopt_map_defaults(const char *val
)
745 gopt
.map_defaults
= strdup((char *)val
);
751 gopt_map_options(const char *val
)
753 gopt
.map_options
= strdup((char *)val
);
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
;
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
);
776 gopt
.map_type
= strdup((char *)val
);
782 gopt_mount_type(const char *val
)
784 if (STREQ(val
, "autofs")) {
785 #ifdef HAVE_FS_AUTOFS
786 gopt
.flags
|= CFM_MOUNT_TYPE_AUTOFS
;
789 #else /* not HAVE_FS_AUTOFS */
790 fprintf(stderr
, "conf: no autofs support available\n");
792 #endif /* not HAVE_FS_AUTOFS */
793 } else if (STREQ(val
, "nfs")) {
794 gopt
.flags
&= ~CFM_MOUNT_TYPE_AUTOFS
;
798 fprintf(stderr
, "conf: unknown value to mount_type \"%s\"\n", val
);
799 return 1; /* unknown value */
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
);
819 set_amd_program_number(gopt
.portmap_program
);
820 return 0; /* all is OK */
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 */
838 gopt_nfs_allow_any_interface(const char *val
)
840 if (STREQ(val
, "yes")) {
841 gopt
.flags
|= CFM_NFS_ANY_INTERFACE
;
843 } else if (STREQ(val
, "no")) {
844 gopt
.flags
&= ~CFM_NFS_ANY_INTERFACE
;
848 fprintf(stderr
, "conf: unknown value to nfs_allow_insecure_port \"%s\"\n", val
);
849 return 1; /* unknown value */
854 gopt_nfs_allow_insecure_port(const char *val
)
856 if (STREQ(val
, "yes")) {
857 gopt
.flags
|= CFM_NFS_INSECURE_PORT
;
859 } else if (STREQ(val
, "no")) {
860 gopt
.flags
&= ~CFM_NFS_INSECURE_PORT
;
864 fprintf(stderr
, "conf: unknown value to nfs_allow_insecure_port \"%s\"\n", val
);
865 return 1; /* unknown value */
870 gopt_nfs_proto(const char *val
)
872 if (STREQ(val
, "udp") || STREQ(val
, "tcp")) {
873 gopt
.nfs_proto
= strdup((char *)val
);
876 fprintf(stderr
, "conf: illegal nfs_proto \"%s\"\n", val
);
882 gopt_nfs_retransmit_counter(const char *val
)
886 for (i
=0; i
<AMU_TYPE_MAX
; ++i
)
887 gopt
.amfs_auto_retrans
[i
] = atoi(val
);
893 gopt_nfs_retransmit_counter_udp(const char *val
)
895 gopt
.amfs_auto_retrans
[AMU_TYPE_UDP
] = atoi(val
);
901 gopt_nfs_retransmit_counter_tcp(const char *val
)
903 gopt
.amfs_auto_retrans
[AMU_TYPE_TCP
] = atoi(val
);
909 gopt_nfs_retransmit_counter_toplvl(const char *val
)
911 gopt
.amfs_auto_retrans
[AMU_TYPE_TOPLVL
] = atoi(val
);
917 gopt_nfs_retry_interval(const char *val
)
921 for (i
=0; i
<AMU_TYPE_MAX
; ++i
)
922 gopt
.amfs_auto_timeo
[i
] = atoi(val
);
928 gopt_nfs_retry_interval_udp(const char *val
)
930 gopt
.amfs_auto_timeo
[AMU_TYPE_UDP
] = atoi(val
);
936 gopt_nfs_retry_interval_tcp(const char *val
)
938 gopt
.amfs_auto_timeo
[AMU_TYPE_TCP
] = atoi(val
);
944 gopt_nfs_retry_interval_toplvl(const char *val
)
946 gopt
.amfs_auto_timeo
[AMU_TYPE_TOPLVL
] = atoi(val
);
952 gopt_nfs_vers(const char *val
)
956 if (i
== 2 || i
== 3) {
960 fprintf(stderr
, "conf: illegal nfs_vers \"%s\"\n", val
);
966 gopt_nis_domain(const char *val
)
969 gopt
.nis_domain
= strdup((char *)val
);
971 #else /* not HAVE_MAP_NIS */
972 fprintf(stderr
, "conf: nis_domain option ignored. No NIS support available.\n");
974 #endif /* not HAVE_MAP_NIS */
979 gopt_normalize_hostnames(const char *val
)
981 if (STREQ(val
, "yes")) {
982 gopt
.flags
|= CFM_NORMALIZE_HOSTNAMES
;
984 } else if (STREQ(val
, "no")) {
985 gopt
.flags
&= ~CFM_NORMALIZE_HOSTNAMES
;
989 fprintf(stderr
, "conf: unknown value to normalize_hostnames \"%s\"\n", val
);
990 return 1; /* unknown value */
995 gopt_normalize_slashes(const char *val
)
997 if (STREQ(val
, "yes")) {
998 gopt
.flags
|= CFM_NORMALIZE_SLASHES
;
1000 } else if (STREQ(val
, "no")) {
1001 gopt
.flags
&= ~CFM_NORMALIZE_SLASHES
;
1005 fprintf(stderr
, "conf: unknown value to normalize_slashes \"%s\"\n", val
);
1006 return 1; /* unknown value */
1011 gopt_os(const char *val
)
1013 gopt
.op_sys
= strdup((char *)val
);
1019 gopt_osver(const char *val
)
1021 gopt
.op_sys_ver
= strdup((char *)val
);
1027 gopt_plock(const char *val
)
1029 if (STREQ(val
, "yes")) {
1030 gopt
.flags
|= CFM_PROCESS_LOCK
;
1032 } else if (STREQ(val
, "no")) {
1033 gopt
.flags
&= ~CFM_PROCESS_LOCK
;
1037 fprintf(stderr
, "conf: unknown value to plock \"%s\"\n", val
);
1038 return 1; /* unknown value */
1043 gopt_print_pid(const char *val
)
1045 if (STREQ(val
, "yes")) {
1046 gopt
.flags
|= CFM_PRINT_PID
;
1048 } else if (STREQ(val
, "no")) {
1049 gopt
.flags
&= ~CFM_PRINT_PID
;
1053 fprintf(stderr
, "conf: unknown value to print_pid \"%s\"\n", val
);
1054 return 1; /* unknown value */
1059 gopt_print_version(const char *val
)
1061 if (STREQ(val
, "yes")) {
1062 char *vers
= get_version_string();
1063 fputs(vers
, stderr
);
1066 } else if (STREQ(val
, "no")) {
1070 fprintf(stderr
, "conf: unknown value to print_version \"%s\"\n", val
);
1071 return 1; /* unknown value */
1076 gopt_restart_mounts(const char *val
)
1078 if (STREQ(val
, "yes")) {
1079 gopt
.flags
|= CFM_RESTART_EXISTING_MOUNTS
;
1081 } else if (STREQ(val
, "no")) {
1082 gopt
.flags
&= ~CFM_RESTART_EXISTING_MOUNTS
;
1086 fprintf(stderr
, "conf: unknown value to restart_mounts \"%s\"\n", val
);
1087 return 1; /* unknown value */
1092 gopt_search_path(const char *val
)
1094 gopt
.search_path
= strdup((char *)val
);
1100 gopt_selectors_in_defaults(const char *val
)
1102 if (STREQ(val
, "yes")) {
1103 gopt
.flags
|= CFM_SELECTORS_IN_DEFAULTS
;
1105 } else if (STREQ(val
, "no")) {
1106 gopt
.flags
&= ~CFM_SELECTORS_IN_DEFAULTS
;
1110 fprintf(stderr
, "conf: unknown value to enable_default_selectors \"%s\"\n", val
);
1111 return 1; /* unknown value */
1116 gopt_show_statfs_entries(const char *val
)
1118 if (STREQ(val
, "yes")) {
1119 gopt
.flags
|= CFM_SHOW_STATFS_ENTRIES
;
1121 } else if (STREQ(val
, "no")) {
1122 gopt
.flags
&= ~CFM_SHOW_STATFS_ENTRIES
;
1126 fprintf(stderr
, "conf: unknown value to show_statfs_entries \"%s\"\n", val
);
1127 return 1; /* unknown value */
1132 gopt_sun_map_syntax(const char *val
)
1134 if (STREQ(val
, "yes")) {
1135 gopt
.flags
|= CFM_SUN_MAP_SYNTAX
;
1137 } else if (STREQ(val
, "no")) {
1138 gopt
.flags
&= ~CFM_SUN_MAP_SYNTAX
;
1142 fprintf(stderr
, "conf: unknown value to sun_map_syntax \"%s\"\n", val
);
1143 return 1; /* unknown value */
1148 gopt_truncate_log(const char *val
)
1150 if (STREQ(val
, "yes")) {
1151 gopt
.flags
|= CFM_TRUNCATE_LOG
;
1153 } else if (STREQ(val
, "no")) {
1154 gopt
.flags
&= ~CFM_TRUNCATE_LOG
;
1158 fprintf(stderr
, "conf: unknown value to truncate_log \"%s\"\n", val
);
1159 return 1; /* unknown value */
1164 gopt_unmount_on_exit(const char *val
)
1166 if (STREQ(val
, "yes")) {
1167 gopt
.flags
|= CFM_UNMOUNT_ON_EXIT
;
1169 } else if (STREQ(val
, "no")) {
1170 gopt
.flags
&= ~CFM_UNMOUNT_ON_EXIT
;
1174 fprintf(stderr
, "conf: unknown value to unmount_on_exit \"%s\"\n", val
);
1175 return 1; /* unknown value */
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
;
1186 } else if (STREQ(val
, "no")) {
1187 gopt
.flags
&= ~CFM_USE_TCPWRAPPERS
;
1190 #else /* not defined(HAVE_TCPD_H) && defined(HAVE_LIBWRAP) */
1191 fprintf(stderr
, "conf: no tcpd/libwrap support available\n");
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 */
1201 gopt_vendor(const char *val
)
1203 gopt
.op_sys_vendor
= strdup((char *)val
);
1209 * Collect one entry for a regular map
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' ||
1219 fprintf(stderr
, "conf: process_regular_option: null entries\n");
1223 /* check if initializing a new map */
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",
1257 return 1; /* failed to match any command */
1262 ropt_browsable_dirs(const char *val
, cf_map_t
*cfm
)
1264 if (STREQ(val
, "full")) {
1265 cfm
->cfm_flags
|= CFM_BROWSABLE_DIRS_FULL
;
1267 } else if (STREQ(val
, "yes")) {
1268 cfm
->cfm_flags
|= CFM_BROWSABLE_DIRS
;
1270 } else if (STREQ(val
, "no")) {
1271 cfm
->cfm_flags
&= ~CFM_BROWSABLE_DIRS
;
1275 fprintf(stderr
, "conf: unknown value to browsable_dirs \"%s\"\n", val
);
1276 return 1; /* unknown value */
1281 ropt_map_name(const char *val
, cf_map_t
*cfm
)
1283 cfm
->cfm_name
= strdup((char *)val
);
1289 ropt_map_defaults(const char *val
, cf_map_t
*cfm
)
1291 cfm
->cfm_defaults
= strdup((char *)val
);
1297 ropt_map_options(const char *val
, cf_map_t
*cfm
)
1299 cfm
->cfm_opts
= strdup((char *)val
);
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
);
1312 cfm
->cfm_type
= strdup((char *)val
);
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
;
1325 #else /* not HAVE_FS_AUTOFS */
1326 fprintf(stderr
, "conf: no autofs support available\n");
1328 #endif /* not HAVE_FS_AUTOFS */
1329 } else if (STREQ(val
, "nfs")) {
1330 cfm
->cfm_flags
&= ~CFM_MOUNT_TYPE_AUTOFS
;
1334 fprintf(stderr
, "conf: unknown value to mount_type \"%s\"\n", val
);
1335 return 1; /* unknown value */
1340 ropt_search_path(const char *val
, cf_map_t
*cfm
)
1342 cfm
->cfm_search_path
= strdup((char *)val
);
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
;
1354 } else if (STREQ(val
, "no")) {
1355 cfm
->cfm_flags
&= ~CFM_SUN_MAP_SYNTAX
;
1359 fprintf(stderr
, "conf: unknown value to sun_map_syntax \"%s\"\n", val
);
1360 return 1; /* unknown value */
1365 ropt_tag(const char *val
, cf_map_t
*cfm
)
1367 cfm
->cfm_tag
= strdup((char *)val
);
1373 * Process one collected map.
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
);
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
))) {
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
: "",
1398 fprintf(stderr
, "skipping map %s...\n", cfm
->cfm_dir
);
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
1421 if (process_one_regular_map(tmp_map
) != 0)
1423 tmp_map
= tmp_map
->cfm_next
;
1430 * Find a cf_map_t for a given map name.
1431 * Return NULL if not found.
1434 find_cf_map(const char *name
)
1437 cf_map_t
*tmp_map
= head_map
;
1439 if (!tmp_map
|| !name
)
1443 if (STREQ(tmp_map
->cfm_dir
, name
)) {
1446 tmp_map
= tmp_map
->cfm_next
;