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