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