]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/amd/amd/conf.c
This commit was generated by cvs2svn to compensate for changes in r133931,
[FreeBSD/FreeBSD.git] / contrib / amd / amd / conf.c
1 /*
2  * Copyright (c) 1997-2004 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  *      %W% (Berkeley) %G%
40  *
41  * $Id: conf.c,v 1.7.2.8 2004/01/21 04:04:58 ib42 Exp $
42  *
43  */
44
45 /*
46  * Functions to handle the configuration file.
47  */
48
49 #ifdef HAVE_CONFIG_H
50 # include <config.h>
51 #endif /* HAVE_CONFIG_H */
52 #include <am_defs.h>
53 #include <amd.h>
54
55
56 /*
57  * MACROS:
58  */
59 /* Turn on to show some info about maps being configured */
60 /* #define DEBUG_CONF */
61
62 /*
63  * TYPEDEFS:
64  */
65 typedef int (*OptFuncPtr)(const char *);
66
67 /*
68  * STRUCTURES:
69  */
70 struct _func_map {
71   char *name;
72   OptFuncPtr func;
73 };
74
75 /*
76  * FORWARD DECLARATIONS:
77  */
78 static int gopt_arch(const char *val);
79 static int gopt_auto_dir(const char *val);
80 static int gopt_browsable_dirs(const char *val);
81 static int gopt_cache_duration(const char *val);
82 static int gopt_cluster(const char *val);
83 static int gopt_debug_options(const char *val);
84 static int gopt_dismount_interval(const char *val);
85 static int gopt_full_os(const char *val);
86 static int gopt_fully_qualified_hosts(const char *val);
87 static int gopt_hesiod_base(const char *val);
88 static int gopt_karch(const char *val);
89 static int gopt_ldap_base(const char *val);
90 static int gopt_ldap_cache_maxmem(const char *val);
91 static int gopt_ldap_cache_seconds(const char *val);
92 static int gopt_ldap_hostports(const char *val);
93 static int gopt_local_domain(const char *val);
94 static int gopt_log_file(const char *val);
95 static int gopt_log_options(const char *val);
96 static int gopt_map_options(const char *val);
97 static int gopt_map_type(const char *val);
98 static int gopt_mount_type(const char *val);
99 static int gopt_pid_file(const char *val);
100 static int gopt_portmap_program(const char *val);
101 static int gopt_nfs_allow_insecure_port(const char *val);
102 static int gopt_nfs_proto(const char *val);
103 static int gopt_nfs_retransmit_counter(const char *val);
104 static int gopt_nfs_retry_interval(const char *val);
105 static int gopt_nfs_vers(const char *val);
106 static int gopt_nis_domain(const char *val);
107 static int gopt_normalize_hostnames(const char *val);
108 static int gopt_os(const char *val);
109 static int gopt_osver(const char *val);
110 static int gopt_plock(const char *val);
111 static int gopt_print_pid(const char *val);
112 static int gopt_print_version(const char *val);
113 static int gopt_restart_mounts(const char *val);
114 static int gopt_search_path(const char *val);
115 static int gopt_selectors_in_defaults(const char *val);
116 static int gopt_show_statfs_entries(const char *val);
117 static int gopt_unmount_on_exit(const char *val);
118 static int gopt_vendor(const char *val);
119 static int process_global_option(const char *key, const char *val);
120 static int process_regular_map(cf_map_t *cfm);
121 static int process_regular_option(const char *section, const char *key, const char *val, cf_map_t *cfm);
122 static int ropt_browsable_dirs(const char *val, cf_map_t *cfm);
123 static int ropt_map_name(const char *val, cf_map_t *cfm);
124 static int ropt_map_options(const char *val, cf_map_t *cfm);
125 static int ropt_map_type(const char *val, cf_map_t *cfm);
126 static int ropt_mount_type(const char *val, cf_map_t *cfm);
127 static int ropt_search_path(const char *val, cf_map_t *cfm);
128 static int ropt_tag(const char *val, cf_map_t *cfm);
129 static void reset_cf_map(cf_map_t *cfm);
130
131
132 /*
133  * STATIC VARIABLES:
134  */
135 static cf_map_t cur_map;
136 static struct _func_map glob_functable[] = {
137   {"arch",                      gopt_arch},
138   {"auto_dir",                  gopt_auto_dir},
139   {"browsable_dirs",            gopt_browsable_dirs},
140   {"cache_duration",            gopt_cache_duration},
141   {"cluster",                   gopt_cluster},
142   {"debug_options",             gopt_debug_options},
143   {"dismount_interval",         gopt_dismount_interval},
144   {"fully_qualified_hosts",     gopt_fully_qualified_hosts},
145   {"full_os",                   gopt_full_os},
146   {"hesiod_base",               gopt_hesiod_base},
147   {"karch",                     gopt_karch},
148   {"ldap_base",                 gopt_ldap_base},
149   {"ldap_cache_maxmem",         gopt_ldap_cache_maxmem},
150   {"ldap_cache_seconds",        gopt_ldap_cache_seconds},
151   {"ldap_hostports",            gopt_ldap_hostports},
152   {"local_domain",              gopt_local_domain},
153   {"log_file",                  gopt_log_file},
154   {"log_options",               gopt_log_options},
155   {"map_options",               gopt_map_options},
156   {"map_type",                  gopt_map_type},
157   {"mount_type",                gopt_mount_type},
158   {"pid_file",                  gopt_pid_file},
159   {"portmap_program",           gopt_portmap_program},
160   {"nfs_allow_insecure_port",   gopt_nfs_allow_insecure_port},
161   {"nfs_proto",                 gopt_nfs_proto},
162   {"nfs_retransmit_counter",    gopt_nfs_retransmit_counter},
163   {"nfs_retry_interval",        gopt_nfs_retry_interval},
164   {"nfs_vers",                  gopt_nfs_vers},
165   {"nis_domain",                gopt_nis_domain},
166   {"normalize_hostnames",       gopt_normalize_hostnames},
167   {"os",                        gopt_os},
168   {"osver",                     gopt_osver},
169   {"plock",                     gopt_plock},
170   {"print_pid",                 gopt_print_pid},
171   {"print_version",             gopt_print_version},
172   {"restart_mounts",            gopt_restart_mounts},
173   {"search_path",               gopt_search_path},
174   {"selectors_on_default",      gopt_selectors_in_defaults},
175   {"selectors_in_defaults",     gopt_selectors_in_defaults},
176   {"show_statfs_entries",       gopt_show_statfs_entries},
177   {"unmount_on_exit",           gopt_unmount_on_exit},
178   {"vendor",                    gopt_vendor},
179   {NULL, NULL}
180 };
181
182
183 /*
184  * Reset a map.
185  */
186 static void
187 reset_cf_map(cf_map_t *cfm)
188 {
189   if (!cfm)
190     return;
191
192   if (cfm->cfm_dir) {
193     XFREE(cfm->cfm_dir);
194     cfm->cfm_dir = NULL;
195   }
196
197   if (cfm->cfm_name) {
198     XFREE(cfm->cfm_name);
199     cfm->cfm_name = NULL;
200   }
201
202   if (cfm->cfm_tag) {
203     XFREE(cfm->cfm_tag);
204     cfm->cfm_tag = NULL;
205   }
206
207   /*
208    * reset/initialize a regular map's flags and other variables from the
209    * global ones, so that they are applied to all maps.  Of course, each map
210    * can then override the flags individually.
211    *
212    * NOTES:
213    * (1): Will only work for maps that appear after [global].
214    * (2): Also be careful not to free() a global option.
215    * (3): I'm doing direct char* pointer comparison, and not strcmp().  This
216    *      is correct!
217    */
218
219   /* initialize map_type from [global] */
220   if (cfm->cfm_type && cfm->cfm_type != gopt.map_type)
221     XFREE(cfm->cfm_type);
222   cfm->cfm_type = gopt.map_type;
223
224   /* initialize map_opts from [global] */
225   if (cfm->cfm_opts && cfm->cfm_opts != gopt.map_options)
226     XFREE(cfm->cfm_opts);
227   cfm->cfm_opts = gopt.map_options;
228
229   /* initialize search_path from [global] */
230   if (cfm->cfm_search_path && cfm->cfm_search_path != gopt.search_path)
231     XFREE(cfm->cfm_search_path);
232   cfm->cfm_search_path = gopt.search_path;
233
234   /*
235    * Initialize flags that are common both to [global] and a local map.
236    */
237   cfm->cfm_flags = gopt.flags & (CFM_BROWSABLE_DIRS |
238                                  CFM_BROWSABLE_DIRS_FULL |
239                                  CFM_MOUNT_TYPE_AUTOFS |
240                                  CFM_SELECTORS_IN_DEFAULTS);
241 }
242
243
244 /*
245  * Process configuration file options.
246  * Return 0 if OK, 1 otherwise.
247  */
248 int
249 set_conf_kv(const char *section, const char *key, const char *val)
250 {
251   int ret;
252
253 #ifdef DEBUG_CONF
254   fprintf(stderr,"set_conf_kv: section=%s, key=%s, val=%s\n",
255           section, key, val);
256 #endif /* DEBUG_CONF */
257
258   /*
259    * If global section, process them one at a time.
260    */
261   if (STREQ(section, "global")) {
262     /*
263      * Check if a regular map was configured before "global",
264      * and process it as needed.
265      */
266     if (cur_map.cfm_dir) {
267       fprintf(stderr,"processing regular map \"%s\" before global one.\n",
268               section);
269       ret = process_regular_map(&cur_map); /* will reset map */
270       if (ret != 0)
271         return ret;
272     }
273
274     /* process the global option first */
275     ret = process_global_option(key, val);
276
277     /* reset default options for regular maps from just updated globals */
278     if (ret == 0)
279       reset_cf_map(&cur_map);
280
281     /* return status from the processing of the global option */
282     return ret;
283   }
284
285   /*
286    * otherwise save options and process a single map all at once.
287    */
288
289   /* check if we found a new map, so process one already collected */
290   if (cur_map.cfm_dir && !STREQ(cur_map.cfm_dir, section)) {
291     ret = process_regular_map(&cur_map); /* will reset map */
292     if (ret != 0)
293       return ret;
294   }
295
296   /* now process a single entry of a regular map */
297   return process_regular_option(section, key, val, &cur_map);
298 }
299
300
301 /*
302  * Process global section of configuration file options.
303  * Return 0 upon success, 1 otherwise.
304  */
305 static int
306 process_global_option(const char *key, const char *val)
307 {
308   struct _func_map *gfp;
309
310   /* ensure that val is valid */
311   if (!val || val[0] == '\0')
312     return 1;
313
314   /*
315    * search for global function.
316    */
317   for (gfp = glob_functable; gfp->name; gfp++)
318     if (FSTREQ(gfp->name, key))
319       return (gfp->func)(val);
320
321   fprintf(stderr, "conf: unknown global key: \"%s\"\n", key);
322   return 1;                     /* failed to match any command */
323 }
324
325
326 static int
327 gopt_arch(const char *val)
328 {
329   gopt.arch = strdup((char *)val);
330   return 0;
331 }
332
333
334 static int
335 gopt_auto_dir(const char *val)
336 {
337   gopt.auto_dir = strdup((char *)val);
338   return 0;
339 }
340
341
342 static int
343 gopt_browsable_dirs(const char *val)
344 {
345   if (STREQ(val, "full")) {
346     gopt.flags |= CFM_BROWSABLE_DIRS_FULL;
347     return 0;
348   } else if (STREQ(val, "yes")) {
349     gopt.flags |= CFM_BROWSABLE_DIRS;
350     return 0;
351   } else if (STREQ(val, "no")) {
352     gopt.flags &= ~CFM_BROWSABLE_DIRS;
353     return 0;
354   }
355
356   fprintf(stderr, "conf: unknown value to browsable_dirs \"%s\"\n", val);
357   return 1;                     /* unknown value */
358 }
359
360
361 static int
362 gopt_cache_duration(const char *val)
363 {
364   gopt.am_timeo = atoi(val);
365   if (gopt.am_timeo <= 0)
366     gopt.am_timeo = AM_TTL;
367   return 0;
368 }
369
370
371 static int
372 gopt_cluster(const char *val)
373 {
374   gopt.cluster = strdup((char *)val);
375   return 0;
376 }
377
378
379 static int
380 gopt_debug_options(const char *val)
381 {
382 #ifdef DEBUG
383   usage += debug_option(strdup((char *)val));
384   return 0;
385 #else /* not DEBUG */
386   fprintf(stderr, "%s: not compiled with DEBUG option -- sorry.\n",
387           am_get_progname());
388   return 1;
389 #endif /* not DEBUG */
390 }
391
392
393 static int
394 gopt_dismount_interval(const char *val)
395 {
396   gopt.am_timeo_w = atoi(val);
397   if (gopt.am_timeo_w <= 0)
398     gopt.am_timeo_w = AM_TTL_W;
399   return 0;
400 }
401
402
403 static int
404 gopt_full_os(const char *val)
405 {
406   gopt.op_sys_full = strdup((char *)val);
407   return 0;
408 }
409
410
411 static int
412 gopt_fully_qualified_hosts(const char *val)
413 {
414   if (STREQ(val, "yes")) {
415     gopt.flags |= CFM_FULLY_QUALIFIED_HOSTS;
416     return 0;
417   } else if (STREQ(val, "no")) {
418     gopt.flags &= ~CFM_FULLY_QUALIFIED_HOSTS;
419     return 0;
420   }
421
422   fprintf(stderr, "conf: unknown value to fully_qualified_hosts \"%s\"\n", val);
423   return 1;                     /* unknown value */
424 }
425
426
427 static int
428 gopt_hesiod_base(const char *val)
429 {
430 #ifdef HAVE_MAP_HESIOD
431   gopt.hesiod_base = strdup((char *)val);
432   return 0;
433 #else /* not HAVE_MAP_HESIOD */
434   fprintf(stderr, "conf: hesiod_base option ignored.  No Hesiod support available.\n");
435   return 1;
436 #endif /* not HAVE_MAP_HESIOD */
437 }
438
439
440 static int
441 gopt_karch(const char *val)
442 {
443   gopt.karch = strdup((char *)val);
444   return 0;
445 }
446
447
448 static int
449 gopt_pid_file(const char *val)
450 {
451   gopt.pid_file = strdup((char *)val);
452   return 0;
453 }
454
455
456 static int
457 gopt_local_domain(const char *val)
458 {
459   gopt.sub_domain = strdup((char *)val);
460   return 0;
461 }
462
463
464 static int
465 gopt_ldap_base(const char *val)
466 {
467 #ifdef HAVE_MAP_LDAP
468   gopt.ldap_base = strdup((char *)val);
469   return 0;
470 #else /* not HAVE_MAP_LDAP */
471   fprintf(stderr, "conf: ldap_base option ignored.  No LDAP support available.\n");
472   return 1;
473 #endif /* not HAVE_MAP_LDAP */
474 }
475
476
477 static int
478 gopt_ldap_cache_seconds(const char *val)
479 {
480 #ifdef HAVE_MAP_LDAP
481   char *end;
482
483   gopt.ldap_cache_seconds = strtol((char *)val, &end, 10);
484   if (end == val) {
485     fprintf(stderr, "conf: bad LDAP cache (seconds) option: %s\n",val);
486     return 1;
487   }
488   return 0;
489 #else /* not HAVE_MAP_LDAP */
490   fprintf(stderr, "conf: ldap_cache_seconds option ignored.  No LDAP support available.\n");
491   return 1;
492 #endif /* not HAVE_MAP_LDAP */
493 }
494
495
496 static int
497 gopt_ldap_cache_maxmem(const char *val)
498 {
499 #ifdef HAVE_MAP_LDAP
500   char *end;
501
502   gopt.ldap_cache_maxmem = strtol((char *)val, &end, 10);
503   if (end == val) {
504     fprintf(stderr, "conf: bad LDAP cache (maxmem) option: %s\n",val);
505     return 1;
506   }
507   return 0;
508 #else /* not HAVE_MAP_LDAP */
509   fprintf(stderr, "conf: ldap_cache_maxmem option ignored.  No LDAP support available.\n");
510   return 1;
511 #endif /* not HAVE_MAP_LDAP */
512 }
513
514
515 static int
516 gopt_ldap_hostports(const char *val)
517 {
518 #ifdef HAVE_MAP_LDAP
519   gopt.ldap_hostports = strdup((char *)val);
520   return 0;
521 #else /* not HAVE_MAP_LDAP */
522   fprintf(stderr, "conf: ldap_hostports option ignored.  No LDAP support available.\n");
523   return 1;
524 #endif /* not HAVE_MAP_LDAP */
525
526 }
527
528
529 static int
530 gopt_log_file(const char *val)
531 {
532   gopt.logfile = strdup((char *)val);
533   return 0;
534 }
535
536
537 static int
538 gopt_log_options(const char *val)
539 {
540   usage += switch_option(strdup((char *)val));
541   return 0;
542 }
543
544
545 static int
546 gopt_map_options(const char *val)
547 {
548   gopt.map_options = strdup((char *)val);
549   return 0;
550 }
551
552
553 static int
554 gopt_map_type(const char *val)
555 {
556   /* check if map type exist */
557   if (!mapc_type_exists(val)) {
558     fprintf(stderr, "conf: no such map type \"%s\"\n", val);
559     return 1;
560   }
561   gopt.map_type = strdup((char *)val);
562   return 0;
563 }
564
565
566 static int
567 gopt_mount_type(const char *val)
568 {
569   if (STREQ(val, "autofs")) {
570     fprintf(stderr, "conf: no autofs support available, turning it off\n");
571     gopt.flags &= ~CFM_MOUNT_TYPE_AUTOFS;
572     return 0;
573   } else if (STREQ(val, "nfs")) {
574     gopt.flags &= ~CFM_MOUNT_TYPE_AUTOFS;
575     return 0;
576   }
577
578   fprintf(stderr, "conf: unknown value to mount_type \"%s\"\n", val);
579   return 1;                     /* unknown value */
580 }
581
582
583 static int
584 gopt_portmap_program(const char *val)
585 {
586   gopt.portmap_program = atoi(val);
587   /*
588    * allow alternate program numbers to be no more than 10 offset from
589    * official amd program number (300019).
590    */
591   if (gopt.portmap_program < AMQ_PROGRAM ||
592       gopt.portmap_program > AMQ_PROGRAM + 10) {
593     gopt.portmap_program = AMQ_PROGRAM;
594     set_amd_program_number(gopt.portmap_program);
595     fprintf(stderr, "conf: illegal amd program number \"%s\"\n", val);
596     return 1;
597   }
598
599   set_amd_program_number(gopt.portmap_program);
600   return 0;                     /* all is OK */
601 }
602
603
604 static int
605 gopt_nfs_allow_insecure_port(const char *val)
606 {
607   if (STREQ(val, "yes")) {
608     gopt.flags |= CFM_NFS_INSECURE_PORT;
609     return 0;
610   } else if (STREQ(val, "no")) {
611     gopt.flags &= ~CFM_NFS_INSECURE_PORT;
612     return 0;
613   }
614
615   fprintf(stderr, "conf: unknown value to nfs_allow_insecure_port \"%s\"\n", val);
616   return 1;                     /* unknown value */
617 }
618
619
620 static int
621 gopt_nfs_proto(const char *val)
622 {
623   if (STREQ(val, "udp") || STREQ(val, "tcp")) {
624     gopt.nfs_proto = strdup((char *)val);
625     return 0;
626   }
627   fprintf(stderr, "conf: illegal nfs_proto \"%s\"\n", val);
628   return 1;
629 }
630
631
632 static int
633 gopt_nfs_retransmit_counter(const char *val)
634 {
635   gopt.amfs_auto_retrans = atoi(val);
636   return 0;
637 }
638
639
640 static int
641 gopt_nfs_retry_interval(const char *val)
642 {
643   gopt.amfs_auto_timeo = atoi(val);
644   return 0;
645 }
646
647
648 static int
649 gopt_nfs_vers(const char *val)
650 {
651   int i = atoi(val);
652
653   if (i == 2 || i == 3) {
654     gopt.nfs_vers = i;
655     return 0;
656   }
657   fprintf(stderr, "conf: illegal nfs_vers \"%s\"\n", val);
658   return 1;
659 }
660
661
662 static int
663 gopt_nis_domain(const char *val)
664 {
665 #ifdef HAVE_MAP_NIS
666   gopt.nis_domain = strdup((char *)val);
667   return 0;
668 #else /* not HAVE_MAP_NIS */
669   fprintf(stderr, "conf: nis_domain option ignored.  No NIS support available.\n");
670   return 1;
671 #endif /* not HAVE_MAP_NIS */
672 }
673
674
675 static int
676 gopt_normalize_hostnames(const char *val)
677 {
678   if (STREQ(val, "yes")) {
679     gopt.flags |= CFM_NORMALIZE_HOSTNAMES;
680     return 0;
681   } else if (STREQ(val, "no")) {
682     gopt.flags &= ~CFM_NORMALIZE_HOSTNAMES;
683     return 0;
684   }
685
686   fprintf(stderr, "conf: unknown value to normalize_hostnames \"%s\"\n", val);
687   return 1;                     /* unknown value */
688 }
689
690
691 static int
692 gopt_os(const char *val)
693 {
694   gopt.op_sys = strdup((char *)val);
695   return 0;
696 }
697
698
699 static int
700 gopt_osver(const char *val)
701 {
702   gopt.op_sys_ver = strdup((char *)val);
703   return 0;
704 }
705
706
707 static int
708 gopt_plock(const char *val)
709 {
710   if (STREQ(val, "yes")) {
711     gopt.flags |= CFM_PROCESS_LOCK;
712     return 0;
713   } else if (STREQ(val, "no")) {
714     gopt.flags &= ~CFM_PROCESS_LOCK;
715     return 0;
716   }
717
718   fprintf(stderr, "conf: unknown value to plock \"%s\"\n", val);
719   return 1;                     /* unknown value */
720 }
721
722
723 static int
724 gopt_print_pid(const char *val)
725 {
726   if (STREQ(val, "yes")) {
727     gopt.flags |= CFM_PRINT_PID;
728     return 0;
729   } else if (STREQ(val, "no")) {
730     gopt.flags &= ~CFM_PRINT_PID;
731     return 0;
732   }
733
734   fprintf(stderr, "conf: unknown value to print_pid \"%s\"\n", val);
735   return 1;                     /* unknown value */
736 }
737
738
739 static int
740 gopt_print_version(const char *val)
741 {
742   if (STREQ(val, "yes")) {
743     fputs(get_version_string(), stderr);
744     return 0;
745   } else if (STREQ(val, "no")) {
746     return 0;
747   }
748
749   fprintf(stderr, "conf: unknown value to print_version \"%s\"\n", val);
750   return 1;                     /* unknown value */
751 }
752
753
754 static int
755 gopt_restart_mounts(const char *val)
756 {
757   if (STREQ(val, "yes")) {
758     gopt.flags |= CFM_RESTART_EXISTING_MOUNTS;
759     return 0;
760   } else if (STREQ(val, "no")) {
761     gopt.flags &= ~CFM_RESTART_EXISTING_MOUNTS;
762     return 0;
763   }
764
765   fprintf(stderr, "conf: unknown value to restart_mounts \"%s\"\n", val);
766   return 1;                     /* unknown value */
767 }
768
769
770 static int
771 gopt_search_path(const char *val)
772 {
773   gopt.search_path = strdup((char *)val);
774   return 0;
775 }
776
777
778 static int
779 gopt_selectors_in_defaults(const char *val)
780 {
781   if (STREQ(val, "yes")) {
782     gopt.flags |= CFM_SELECTORS_IN_DEFAULTS;
783     return 0;
784   } else if (STREQ(val, "no")) {
785     gopt.flags &= ~CFM_SELECTORS_IN_DEFAULTS;
786     return 0;
787   }
788
789   fprintf(stderr, "conf: unknown value to enable_default_selectors \"%s\"\n", val);
790   return 1;                     /* unknown value */
791 }
792
793
794 static int
795 gopt_show_statfs_entries(const char *val)
796 {
797   if (STREQ(val, "yes")) {
798     gopt.flags |= CFM_SHOW_STATFS_ENTRIES;
799     return 0;
800   } else if (STREQ(val, "no")) {
801     gopt.flags &= ~CFM_SHOW_STATFS_ENTRIES;
802     return 0;
803   }
804
805   fprintf(stderr, "conf: unknown value to show_statfs_entries \"%s\"\n", val);
806   return 1;                     /* unknown value */
807 }
808
809
810 static int
811 gopt_unmount_on_exit(const char *val)
812 {
813   if (STREQ(val, "yes")) {
814     gopt.flags |= CFM_UNMOUNT_ON_EXIT;
815     return 0;
816   } else if (STREQ(val, "no")) {
817     gopt.flags &= ~CFM_UNMOUNT_ON_EXIT;
818     return 0;
819   }
820
821   fprintf(stderr, "conf: unknown value to unmount_on_exit \"%s\"\n", val);
822   return 1;                     /* unknown value */
823 }
824
825
826 static int
827 gopt_vendor(const char *val)
828 {
829   gopt.op_sys_vendor = strdup((char *)val);
830   return 0;
831 }
832
833
834 /*
835  * Collect one entry for a regular map
836  */
837 static int
838 process_regular_option(const char *section, const char *key, const char *val, cf_map_t *cfm)
839 {
840   /* ensure that val is valid */
841   if (!section || section[0] == '\0' ||
842       !key || key[0] == '\0' ||
843       !val || val[0] == '\0' ||
844       !cfm) {
845     fprintf(stderr, "conf: process_regular_option: null entries\n");
846     return 1;
847   }
848
849   /* check if initializing a new map */
850   if (!cfm->cfm_dir)
851     cfm->cfm_dir = strdup((char *)section);
852
853   /* check for each possible field */
854   if (STREQ(key, "browsable_dirs"))
855     return ropt_browsable_dirs(val, cfm);
856
857   if (STREQ(key, "map_name"))
858     return ropt_map_name(val, cfm);
859
860   if (STREQ(key, "map_options"))
861     return ropt_map_options(val, cfm);
862
863   if (STREQ(key, "map_type"))
864     return ropt_map_type(val, cfm);
865
866   if (STREQ(key, "mount_type"))
867     return ropt_mount_type(val, cfm);
868
869   if (STREQ(key, "search_path"))
870     return ropt_search_path(val, cfm);
871
872   if (STREQ(key, "tag"))
873     return ropt_tag(val, cfm);
874
875   fprintf(stderr, "conf: unknown regular key \"%s\" for section \"%s\"\n",
876           key, section);
877   return 1;                     /* failed to match any command */
878 }
879
880
881 static int
882 ropt_browsable_dirs(const char *val, cf_map_t *cfm)
883 {
884   if (STREQ(val, "full")) {
885     cfm->cfm_flags |= CFM_BROWSABLE_DIRS_FULL;
886     return 0;
887   } else if (STREQ(val, "yes")) {
888     cfm->cfm_flags |= CFM_BROWSABLE_DIRS;
889     return 0;
890   } else if (STREQ(val, "no")) {
891     cfm->cfm_flags &= ~CFM_BROWSABLE_DIRS;
892     return 0;
893   }
894
895   fprintf(stderr, "conf: unknown value to browsable_dirs \"%s\"\n", val);
896   return 1;                     /* unknown value */
897 }
898
899
900 static int
901 ropt_map_name(const char *val, cf_map_t *cfm)
902 {
903   cfm->cfm_name = strdup((char *)val);
904   return 0;
905 }
906
907
908 static int
909 ropt_map_options(const char *val, cf_map_t *cfm)
910 {
911   cfm->cfm_opts = strdup((char *)val);
912   return 0;
913 }
914
915
916 static int
917 ropt_map_type(const char *val, cf_map_t *cfm)
918 {
919   /* check if map type exist */
920   if (!mapc_type_exists(val)) {
921     fprintf(stderr, "conf: no such map type \"%s\"\n", val);
922     return 1;
923   }
924   cfm->cfm_type = strdup((char *)val);
925   return 0;
926 }
927
928
929 static int
930 ropt_mount_type(const char *val, cf_map_t *cfm)
931 {
932   if (STREQ(val, "autofs")) {
933     fprintf(stderr, "conf: no autofs support available, turning it off\n");
934     cfm->cfm_flags &= ~CFM_MOUNT_TYPE_AUTOFS;
935     return 0;
936   } else if (STREQ(val, "nfs")) {
937     cfm->cfm_flags &= ~CFM_MOUNT_TYPE_AUTOFS;
938     return 0;
939   }
940
941   fprintf(stderr, "conf: unknown value to mount_type \"%s\"\n", val);
942   return 1;                     /* unknown value */
943 }
944
945
946 static int
947 ropt_search_path(const char *val, cf_map_t *cfm)
948 {
949   cfm->cfm_search_path = strdup((char *)val);
950   return 0;
951 }
952
953
954 static int
955 ropt_tag(const char *val, cf_map_t *cfm)
956 {
957   cfm->cfm_tag = strdup((char *)val);
958   return 0;
959 }
960
961
962 /*
963  * Process one collected map.
964  */
965 static int
966 process_regular_map(cf_map_t *cfm)
967 {
968
969   if (!cfm->cfm_name) {
970     fprintf(stderr, "conf: map_name must be defined for map \"%s\"\n", cfm->cfm_dir);
971     return 1;
972   }
973   /*
974    * If map has no tag defined, process the map.
975    * If no conf_tag was set in amd -T, process all untagged entries.
976    * If a tag is defined, then process it only if it matches the map tag.
977    */
978   if (!cfm->cfm_tag ||
979       (conf_tag && STREQ(cfm->cfm_tag, conf_tag))) {
980 #ifdef DEBUG_CONF
981     fprintf(stderr, "processing map %s (flags=0x%x)...\n",
982             cfm->cfm_dir, cfm->cfm_flags);
983 #endif /* DEBUG_CONF */
984     root_newmap(cfm->cfm_dir,
985                 cfm->cfm_opts ? cfm->cfm_opts : "",
986                 cfm->cfm_name,
987                 cfm);
988   } else {
989     fprintf(stderr, "skipping map %s...\n", cfm->cfm_dir);
990   }
991
992   reset_cf_map(cfm);
993   return 0;
994 }
995
996
997 /*
998  * Process last map in conf file (if any)
999  */
1000 int
1001 process_last_regular_map(void)
1002 {
1003   /*
1004    * If the amd.conf file only has a [global] section (pretty useless
1005    * IMHO), do not try to process a map that does not exist.
1006    */
1007   if (!cur_map.cfm_dir)
1008     return 0;
1009   return process_regular_map(&cur_map);
1010 }