conf.c revision 38494
11553Srgrimes/* 21553Srgrimes * Copyright (c) 1997-1998 Erez Zadok 31553Srgrimes * Copyright (c) 1990 Jan-Simon Pendry 41553Srgrimes * Copyright (c) 1990 Imperial College of Science, Technology & Medicine 51553Srgrimes * Copyright (c) 1990 The Regents of the University of California. 61553Srgrimes * All rights reserved. 71553Srgrimes * 81553Srgrimes * This code is derived from software contributed to Berkeley by 91553Srgrimes * Jan-Simon Pendry at Imperial College, London. 101553Srgrimes * 111553Srgrimes * Redistribution and use in source and binary forms, with or without 121553Srgrimes * modification, are permitted provided that the following conditions 131553Srgrimes * are met: 141553Srgrimes * 1. Redistributions of source code must retain the above copyright 151553Srgrimes * notice, this list of conditions and the following disclaimer. 161553Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 171553Srgrimes * notice, this list of conditions and the following disclaimer in the 181553Srgrimes * documentation and/or other materials provided with the distribution. 191553Srgrimes * 3. All advertising materials mentioning features or use of this software 201553Srgrimes * must display the following acknowledgement: 211553Srgrimes * This product includes software developed by the University of 221553Srgrimes * California, Berkeley and its contributors. 231553Srgrimes * 4. Neither the name of the University nor the names of its contributors 241553Srgrimes * may be used to endorse or promote products derived from this software 251553Srgrimes * without specific prior written permission. 261553Srgrimes * 271553Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 281553Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 291553Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 301553Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 311553Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 321553Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 331553Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 341553Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 351553Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 361553Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 371553Srgrimes * SUCH DAMAGE. 381553Srgrimes * 391553Srgrimes * %W% (Berkeley) %G% 401553Srgrimes * 411553Srgrimes * $Id: conf.c,v 5.2.2.1 1992/02/09 15:08:23 jsp beta $ 421553Srgrimes * 431553Srgrimes */ 441553Srgrimes 451553Srgrimes/* 461553Srgrimes * Functions to handle the configuration file. 471553Srgrimes */ 481553Srgrimes 491553Srgrimes#ifdef HAVE_CONFIG_H 501553Srgrimes# include <config.h> 511553Srgrimes#endif /* HAVE_CONFIG_H */ 521553Srgrimes#include <am_defs.h> 531553Srgrimes#include <amd.h> 541553Srgrimes 551553Srgrimes 561553Srgrimes/* 571553Srgrimes * MACROS: 581553Srgrimes */ 591553Srgrimes/* Turn on to show some info about maps being configured */ 6024428Simp/* #define DEBUG_CONF */ 611553Srgrimes 621553Srgrimes/* 631553Srgrimes * TYPEDEFS: 641553Srgrimes */ 651553Srgrimestypedef int (*OptFuncPtr)(const char *); 661553Srgrimes 671553Srgrimes/* 681553Srgrimes * STRUCTURES: 691553Srgrimes */ 708857Srgrimesstruct _func_map { 711553Srgrimes char *name; 721553Srgrimes OptFuncPtr func; 731553Srgrimes}; 741553Srgrimes 751553Srgrimes/* 761553Srgrimes * FORWARD DECLARATIONS: 771553Srgrimes */ 781553Srgrimesstatic int gopt_arch(const char *val); 791553Srgrimesstatic int gopt_auto_dir(const char *val); 801553Srgrimesstatic int gopt_browsable_dirs(const char *val); 811553Srgrimesstatic int gopt_cache_duration(const char *val); 821553Srgrimesstatic int gopt_cluster(const char *val); 831553Srgrimesstatic int gopt_debug_options(const char *val); 841553Srgrimesstatic int gopt_dismount_interval(const char *val); 851553Srgrimesstatic int gopt_fully_qualified_hosts(const char *val); 861553Srgrimesstatic int gopt_hesiod_base(const char *val); 871553Srgrimesstatic int gopt_karch(const char *val); 881553Srgrimesstatic int gopt_ldap_base(const char *val); 891553Srgrimesstatic int gopt_ldap_cache_maxmem(const char *val); 901553Srgrimesstatic int gopt_ldap_cache_seconds(const char *val); 911553Srgrimesstatic int gopt_ldap_hostports(const char *val); 921553Srgrimesstatic int gopt_local_domain(const char *val); 931553Srgrimesstatic int gopt_log_file(const char *val); 941553Srgrimesstatic int gopt_log_options(const char *val); 951553Srgrimesstatic int gopt_map_options(const char *val); 96static int gopt_map_type(const char *val); 97static int gopt_mount_type(const char *val); 98static int gopt_pid_file(const char *val); 99static int gopt_portmap_program(const char *val); 100static int gopt_nfs_retransmit_counter(const char *val); 101static int gopt_nfs_retry_interval(const char *val); 102static int gopt_nis_domain(const char *val); 103static int gopt_normalize_hostnames(const char *val); 104static int gopt_os(const char *val); 105static int gopt_osver(const char *val); 106static int gopt_plock(const char *val); 107static int gopt_print_pid(const char *val); 108static int gopt_print_version(const char *val); 109static int gopt_restart_mounts(const char *val); 110static int gopt_search_path(const char *val); 111static int gopt_selectors_on_default(const char *val); 112static int gopt_show_statfs_entries(const char *val); 113static int gopt_unmount_on_exit(const char *val); 114static int process_global_option(const char *key, const char *val); 115static int process_regular_map(cf_map_t *cfm); 116static int process_regular_option(const char *section, const char *key, const char *val, cf_map_t *cfm); 117static int ropt_browsable_dirs(const char *val, cf_map_t *cfm); 118static int ropt_map_name(const char *val, cf_map_t *cfm); 119static int ropt_map_options(const char *val, cf_map_t *cfm); 120static int ropt_map_type(const char *val, cf_map_t *cfm); 121static int ropt_mount_type(const char *val, cf_map_t *cfm); 122static int ropt_search_path(const char *val, cf_map_t *cfm); 123static int ropt_tag(const char *val, cf_map_t *cfm); 124static void reset_cf_map(cf_map_t *cfm); 125 126 127/* 128 * STATIC VARIABLES: 129 */ 130static cf_map_t cur_map; 131static struct _func_map glob_functable[] = { 132 {"arch", gopt_arch}, 133 {"auto_dir", gopt_auto_dir}, 134 {"browsable_dirs", gopt_browsable_dirs}, 135 {"cache_duration", gopt_cache_duration}, 136 {"cluster", gopt_cluster}, 137 {"debug_options", gopt_debug_options}, 138 {"dismount_interval", gopt_dismount_interval}, 139 {"fully_qualified_hosts", gopt_fully_qualified_hosts}, 140 {"hesiod_base", gopt_hesiod_base}, 141 {"karch", gopt_karch}, 142 {"ldap_base", gopt_ldap_base}, 143 {"ldap_cache_maxmem", gopt_ldap_cache_maxmem}, 144 {"ldap_cache_seconds", gopt_ldap_cache_seconds}, 145 {"ldap_hostports", gopt_ldap_hostports}, 146 {"local_domain", gopt_local_domain}, 147 {"log_file", gopt_log_file}, 148 {"log_options", gopt_log_options}, 149 {"map_options", gopt_map_options}, 150 {"map_type", gopt_map_type}, 151 {"mount_type", gopt_mount_type}, 152 {"pid_file", gopt_pid_file}, 153 {"portmap_program", gopt_portmap_program}, 154 {"nfs_retransmit_counter", gopt_nfs_retransmit_counter}, 155 {"nfs_retry_interval", gopt_nfs_retry_interval}, 156 {"nis_domain", gopt_nis_domain}, 157 {"normalize_hostnames", gopt_normalize_hostnames}, 158 {"os", gopt_os}, 159 {"osver", gopt_osver}, 160 {"plock", gopt_plock}, 161 {"print_pid", gopt_print_pid}, 162 {"print_version", gopt_print_version}, 163 {"restart_mounts", gopt_restart_mounts}, 164 {"search_path", gopt_search_path}, 165 {"selectors_on_default", gopt_selectors_on_default}, 166 {"show_statfs_entries", gopt_show_statfs_entries}, 167 {"unmount_on_exit", gopt_unmount_on_exit}, 168 {NULL, NULL} 169}; 170 171 172/* 173 * Reset a map. 174 */ 175static void 176reset_cf_map(cf_map_t *cfm) 177{ 178 if (!cfm) 179 return; 180 181 if (cfm->cfm_dir) { 182 XFREE(cfm->cfm_dir); 183 cfm->cfm_dir = NULL; 184 } 185 186 if (cfm->cfm_name) { 187 XFREE(cfm->cfm_name); 188 cfm->cfm_name = NULL; 189 } 190 191 if (cfm->cfm_tag) { 192 XFREE(cfm->cfm_tag); 193 cfm->cfm_tag = NULL; 194 } 195 196 /* 197 * reset/initialize a regular map's flags and other variables from the 198 * global ones, so that they are applied to all maps. Of course, each map 199 * can then override the flags individually. 200 * 201 * NOTES: 202 * (1): Will only work for maps that appear after [global]. 203 * (2): Also be careful not to free() a global option. 204 * (3): I'm doing direct char* pointer comparison, and not strcmp(). This 205 * is correct! 206 */ 207 208 /* initialize map_type from [global] */ 209 if (cfm->cfm_type && cfm->cfm_type != gopt.map_type) 210 XFREE(cfm->cfm_type); 211 cfm->cfm_type = gopt.map_type; 212 213 /* initialize map_opts from [global] */ 214 if (cfm->cfm_opts && cfm->cfm_opts != gopt.map_options) 215 XFREE(cfm->cfm_opts); 216 cfm->cfm_opts = gopt.map_options; 217 218 /* initialize search_path from [global] */ 219 if (cfm->cfm_search_path && cfm->cfm_search_path != gopt.search_path) 220 XFREE(cfm->cfm_search_path); 221 cfm->cfm_search_path = gopt.search_path; 222 223 /* 224 * Initialize flags that are common both to [global] and a local map. 225 */ 226 cfm->cfm_flags = gopt.flags & (CFM_BROWSABLE_DIRS | 227 CFM_BROWSABLE_DIRS_FULL | 228 CFM_MOUNT_TYPE_AUTOFS | 229 CFM_ENABLE_DEFAULT_SELECTORS); 230} 231 232 233/* 234 * Process configuration file options. 235 * Return 0 if OK, 1 otherwise. 236 */ 237int 238set_conf_kv(const char *section, const char *key, const char *val) 239{ 240 int ret; 241 242#ifdef DEBUG_CONF 243 fprintf(stderr,"set_conf_kv: section=%s, key=%s, val=%s\n", 244 section, key, val); 245#endif /* DEBUG_CONF */ 246 247 /* 248 * If global section, process them one at a time. 249 */ 250 if (STREQ(section, "global")) { 251 /* 252 * Check if a regular map was configured before "global", 253 * and process it as needed. 254 */ 255 if (cur_map.cfm_dir) { 256 fprintf(stderr,"processing regular map \"%s\" before global one.\n", 257 section); 258 ret = process_regular_map(&cur_map); /* will reset map */ 259 if (ret != 0) 260 return ret; 261 } 262 263 /* process the global option first */ 264 ret = process_global_option(key, val); 265 266 /* reset default options for regular maps from just updated globals */ 267 if (ret == 0) 268 reset_cf_map(&cur_map); 269 270 /* return status from the processing of the global option */ 271 return ret; 272 } 273 274 /* 275 * otherwise save options and process a single map all at once. 276 */ 277 278 /* check if we found a new map, so process one already collected */ 279 if (cur_map.cfm_dir && !STREQ(cur_map.cfm_dir, section)) { 280 ret = process_regular_map(&cur_map); /* will reset map */ 281 if (ret != 0) 282 return ret; 283 } 284 285 /* now process a single entry of a regular map */ 286 return process_regular_option(section, key, val, &cur_map); 287} 288 289 290/* 291 * Process global section of configuration file options. 292 * Return 0 upon success, 1 otherwise. 293 */ 294static int 295process_global_option(const char *key, const char *val) 296{ 297 struct _func_map *gfp; 298 299 /* ensure that val is valid */ 300 if (!val || val[0] == '\0') 301 return 1; 302 303 /* 304 * search for global function. 305 */ 306 for (gfp = glob_functable; gfp->name; gfp++) 307 if (FSTREQ(gfp->name, key)) 308 return (gfp->func)(val); 309 310 fprintf(stderr, "conf: unknown global key: \"%s\"\n", key); 311 return 1; /* failed to match any command */ 312} 313 314 315static int 316gopt_arch(const char *val) 317{ 318 gopt.arch = strdup((char *)val); 319 return 0; 320} 321 322 323static int 324gopt_auto_dir(const char *val) 325{ 326 gopt.auto_dir = strdup((char *)val); 327 return 0; 328} 329 330 331static int 332gopt_browsable_dirs(const char *val) 333{ 334 if (STREQ(val, "full")) { 335 gopt.flags |= CFM_BROWSABLE_DIRS_FULL; 336 return 0; 337 } else if (STREQ(val, "yes")) { 338 gopt.flags |= CFM_BROWSABLE_DIRS; 339 return 0; 340 } else if (STREQ(val, "no")) { 341 gopt.flags &= ~CFM_BROWSABLE_DIRS; 342 return 0; 343 } 344 345 fprintf(stderr, "conf: unknown value to browsable_dirs \"%s\"\n", val); 346 return 1; /* unknown value */ 347} 348 349 350static int 351gopt_cache_duration(const char *val) 352{ 353 gopt.am_timeo = atoi(val); 354 if (gopt.am_timeo <= 0) 355 gopt.am_timeo = AM_TTL; 356 return 0; 357} 358 359 360static int 361gopt_cluster(const char *val) 362{ 363 gopt.cluster = strdup((char *)val); 364 return 0; 365} 366 367 368static int 369gopt_debug_options(const char *val) 370{ 371#ifdef DEBUG 372 usage += debug_option(strdup((char *)val)); 373 return 0; 374#else /* not DEBUG */ 375 fprintf(stderr, "%s: not compiled with DEBUG option -- sorry.\n", 376 progname); 377 return 1; 378#endif /* not DEBUG */ 379} 380 381 382static int 383gopt_dismount_interval(const char *val) 384{ 385 gopt.am_timeo_w = atoi(val); 386 if (gopt.am_timeo_w <= 0) 387 gopt.am_timeo_w = AM_TTL_W; 388 return 0; 389} 390 391 392static int 393gopt_fully_qualified_hosts(const char *val) 394{ 395 if (STREQ(val, "yes")) { 396 gopt.flags |= CFM_FULLY_QUALIFIED_HOSTS; 397 return 0; 398 } else if (STREQ(val, "no")) { 399 gopt.flags &= ~CFM_FULLY_QUALIFIED_HOSTS; 400 return 0; 401 } 402 403 fprintf(stderr, "conf: unknown value to fully_qualified_hosts \"%s\"\n", val); 404 return 1; /* unknown value */ 405} 406 407 408static int 409gopt_hesiod_base(const char *val) 410{ 411#ifdef HAVE_MAP_HESIOD 412 gopt.hesiod_base = strdup((char *)val); 413 return 0; 414#else /* not HAVE_MAP_HESIOD */ 415 fprintf(stderr, "conf: hesiod_base option ignored. No Hesiod support available.\n"); 416 return 1; 417#endif /* not HAVE_MAP_HESIOD */ 418} 419 420 421static int 422gopt_karch(const char *val) 423{ 424 gopt.karch = strdup((char *)val); 425 return 0; 426} 427 428 429static int 430gopt_pid_file(const char *val) 431{ 432 gopt.pid_file = strdup((char *)val); 433 return 0; 434} 435 436 437static int 438gopt_local_domain(const char *val) 439{ 440 gopt.sub_domain = strdup((char *)val); 441 return 0; 442} 443 444 445static int 446gopt_ldap_base(const char *val) 447{ 448#ifdef HAVE_MAP_LDAP 449 gopt.ldap_base = strdup((char *)val); 450 return 0; 451#else /* not HAVE_MAP_LDAP */ 452 fprintf(stderr, "conf: ldap_base option ignored. No LDAP support available.\n"); 453 return 1; 454#endif /* not HAVE_MAP_LDAP */ 455} 456 457 458static int 459gopt_ldap_cache_seconds(const char *val) 460{ 461#ifdef HAVE_MAP_LDAP 462 char *end; 463 464 gopt.ldap_cache_seconds = strtol((char *)val, &end, 10); 465 if (end == val) { 466 fprintf(stderr, "conf: bad LDAP cache (seconds) option: %s\n",val); 467 return 1; 468 } 469 return 0; 470#else /* not HAVE_MAP_LDAP */ 471 fprintf(stderr, "conf: ldap_cache option ignored. No LDAP support available.\n"); 472 return 1; 473#endif /* not HAVE_MAP_LDAP */ 474} 475 476 477static int 478gopt_ldap_cache_maxmem(const char *val) 479{ 480#ifdef HAVE_MAP_LDAP 481 char *end; 482 483 gopt.ldap_cache_maxmem = strtol((char *)val, &end, 10); 484 if (end == val) { 485 fprintf(stderr, "conf: bad LDAP cache (maxmem) option: %s\n",val); 486 return 1; 487 } 488 return 0; 489#else /* not HAVE_MAP_LDAP */ 490 fprintf(stderr, "conf: ldap_cache option ignored. No LDAP support available.\n"); 491 return 1; 492#endif /* not HAVE_MAP_LDAP */ 493} 494 495 496static int 497gopt_ldap_hostports(const char *val) 498{ 499#ifdef HAVE_MAP_LDAP 500 gopt.ldap_hostports = strdup((char *)val); 501 return 0; 502#else /* not HAVE_MAP_LDAP */ 503 fprintf(stderr, "conf: ldap_hostports option ignored. No LDAP support available.\n"); 504 return 1; 505#endif /* not HAVE_MAP_LDAP */ 506 507} 508 509 510static int 511gopt_log_file(const char *val) 512{ 513 gopt.logfile = strdup((char *)val); 514 return 0; 515} 516 517 518static int 519gopt_log_options(const char *val) 520{ 521 usage += switch_option(strdup((char *)val)); 522 return 0; 523} 524 525 526static int 527gopt_map_options(const char *val) 528{ 529 gopt.map_options = strdup((char *)val); 530 return 0; 531} 532 533 534static int 535gopt_map_type(const char *val) 536{ 537 gopt.map_type = strdup((char *)val); 538 return 0; 539} 540 541 542static int 543gopt_mount_type(const char *val) 544{ 545 if (STREQ(val, "autofs")) { 546#ifdef HAVE_FS_AUTOFS 547 gopt.flags |= CFM_MOUNT_TYPE_AUTOFS; 548 return 0; 549#else /* not HAVE_FS_AUTOFS */ 550 fprintf(stderr, "conf: no autofs support available\n"); 551 return 1; 552#endif /* not HAVE_FS_AUTOFS */ 553 } else if (STREQ(val, "nfs")) { 554 gopt.flags &= ~CFM_MOUNT_TYPE_AUTOFS; 555 return 0; 556 } 557 558 fprintf(stderr, "conf: unknown value to mount_type \"%s\"\n", val); 559 return 1; /* unknown value */ 560} 561 562 563static int 564gopt_portmap_program(const char *val) 565{ 566 gopt.portmap_program = atoi(val); 567 /* 568 * allow alternate program numbers to be no more than 10 offset from 569 * official amd program number (300019). 570 */ 571 if (gopt.portmap_program < AMQ_PROGRAM || 572 gopt.portmap_program > AMQ_PROGRAM + 10) { 573 gopt.portmap_program = AMQ_PROGRAM; 574 set_amd_program_number(gopt.portmap_program); 575 fprintf(stderr, "conf: illegal amd program numver \"%s\"\n", val); 576 return 1; 577 } 578 579 set_amd_program_number(gopt.portmap_program); 580 return 0; /* all is OK */ 581} 582 583 584static int 585gopt_nfs_retransmit_counter(const char *val) 586{ 587 gopt.amfs_auto_retrans = atoi(val); 588 return 0; 589} 590 591 592static int 593gopt_nfs_retry_interval(const char *val) 594{ 595 gopt.amfs_auto_timeo = atoi(val); 596 return 0; 597} 598 599 600static int 601gopt_nis_domain(const char *val) 602{ 603#ifdef HAVE_MAP_NIS 604 gopt.nis_domain = strdup((char *)val); 605 return 0; 606#else /* not HAVE_MAP_NIS */ 607 fprintf(stderr, "conf: nis_domain option ignored. No NIS support available.\n"); 608 return 1; 609#endif /* not HAVE_MAP_NIS */ 610} 611 612 613static int 614gopt_normalize_hostnames(const char *val) 615{ 616 if (STREQ(val, "yes")) { 617 gopt.flags |= CFM_NORMALIZE_HOSTNAMES; 618 return 0; 619 } else if (STREQ(val, "no")) { 620 gopt.flags &= ~CFM_NORMALIZE_HOSTNAMES; 621 return 0; 622 } 623 624 fprintf(stderr, "conf: unknown value to normalize_hostnames \"%s\"\n", val); 625 return 1; /* unknown value */ 626} 627 628 629static int 630gopt_os(const char *val) 631{ 632 gopt.op_sys = strdup((char *)val); 633 return 0; 634} 635 636 637static int 638gopt_osver(const char *val) 639{ 640 gopt.op_sys_ver = strdup((char *)val); 641 return 0; 642} 643 644 645static int 646gopt_plock(const char *val) 647{ 648 if (STREQ(val, "yes")) { 649 gopt.flags |= CFM_PROCESS_LOCK; 650 return 0; 651 } else if (STREQ(val, "no")) { 652 gopt.flags &= ~CFM_PROCESS_LOCK; 653 return 0; 654 } 655 656 fprintf(stderr, "conf: unknown value to plock \"%s\"\n", val); 657 return 1; /* unknown value */ 658} 659 660 661static int 662gopt_print_pid(const char *val) 663{ 664 if (STREQ(val, "yes")) { 665 gopt.flags |= CFM_PRINT_PID; 666 return 0; 667 } else if (STREQ(val, "no")) { 668 gopt.flags &= ~CFM_PRINT_PID; 669 return 0; 670 } 671 672 fprintf(stderr, "conf: unknown value to print_pid \"%s\"\n", val); 673 return 1; /* unknown value */ 674} 675 676 677static int 678gopt_print_version(const char *val) 679{ 680 if (STREQ(val, "yes")) { 681 fputs(get_version_string(), stderr); 682 return 0; 683 } else if (STREQ(val, "no")) { 684 return 0; 685 } 686 687 fprintf(stderr, "conf: unknown value to print_version \"%s\"\n", val); 688 return 1; /* unknown value */ 689} 690 691 692static int 693gopt_restart_mounts(const char *val) 694{ 695 if (STREQ(val, "yes")) { 696 gopt.flags |= CFM_RESTART_EXISTING_MOUNTS; 697 return 0; 698 } else if (STREQ(val, "no")) { 699 gopt.flags &= ~CFM_RESTART_EXISTING_MOUNTS; 700 return 0; 701 } 702 703 fprintf(stderr, "conf: unknown value to restart_mounts \"%s\"\n", val); 704 return 1; /* unknown value */ 705} 706 707 708static int 709gopt_search_path(const char *val) 710{ 711 gopt.search_path = strdup((char *)val); 712 return 0; 713} 714 715 716static int 717gopt_selectors_on_default(const char *val) 718{ 719 if (STREQ(val, "yes")) { 720 gopt.flags |= CFM_ENABLE_DEFAULT_SELECTORS; 721 return 0; 722 } else if (STREQ(val, "no")) { 723 gopt.flags &= ~CFM_ENABLE_DEFAULT_SELECTORS; 724 return 0; 725 } 726 727 fprintf(stderr, "conf: unknown value to enable_default_selectors \"%s\"\n", val); 728 return 1; /* unknown value */ 729} 730 731 732static int 733gopt_show_statfs_entries(const char *val) 734{ 735 if (STREQ(val, "yes")) { 736 gopt.flags |= CFM_SHOW_STATFS_ENTRIES; 737 return 0; 738 } else if (STREQ(val, "no")) { 739 gopt.flags &= ~CFM_SHOW_STATFS_ENTRIES; 740 return 0; 741 } 742 743 fprintf(stderr, "conf: unknown value to show_statfs_entries \"%s\"\n", val); 744 return 1; /* unknown value */ 745} 746 747 748static int 749gopt_unmount_on_exit(const char *val) 750{ 751 if (STREQ(val, "yes")) { 752 gopt.flags |= CFM_UNMOUNT_ON_EXIT; 753 return 0; 754 } else if (STREQ(val, "no")) { 755 gopt.flags &= ~CFM_UNMOUNT_ON_EXIT; 756 return 0; 757 } 758 759 fprintf(stderr, "conf: unknown value to unmount_on_exit \"%s\"\n", val); 760 return 1; /* unknown value */ 761} 762 763 764/* 765 * Collect one entry for a regular map 766 */ 767static int 768process_regular_option(const char *section, const char *key, const char *val, cf_map_t *cfm) 769{ 770 /* ensure that val is valid */ 771 if (!section || section[0] == '\0' || 772 !key || key[0] == '\0' || 773 !val || val[0] == '\0' || 774 !cfm) { 775 fprintf(stderr, "conf: process_regular_option: null entries\n"); 776 return 1; 777 } 778 779 /* check if initializing a new map */ 780 if (!cfm->cfm_dir) 781 cfm->cfm_dir = strdup((char *)section); 782 783 /* check for each possible field */ 784 if (STREQ(key, "browsable_dirs")) 785 return ropt_browsable_dirs(val, cfm); 786 787 if (STREQ(key, "map_name")) 788 return ropt_map_name(val, cfm); 789 790 if (STREQ(key, "map_options")) 791 return ropt_map_options(val, cfm); 792 793 if (STREQ(key, "map_type")) 794 return ropt_map_type(val, cfm); 795 796 if (STREQ(key, "mount_type")) 797 return ropt_mount_type(val, cfm); 798 799 if (STREQ(key, "search_path")) 800 return ropt_search_path(val, cfm); 801 802 if (STREQ(key, "tag")) 803 return ropt_tag(val, cfm); 804 805 fprintf(stderr, "conf: unknown regular key \"%s\" for section \"%s\"\n", 806 key, section); 807 return 1; /* failed to match any command */ 808} 809 810 811static int 812ropt_browsable_dirs(const char *val, cf_map_t *cfm) 813{ 814 if (STREQ(val, "full")) { 815 cfm->cfm_flags |= CFM_BROWSABLE_DIRS_FULL; 816 return 0; 817 } else if (STREQ(val, "yes")) { 818 cfm->cfm_flags |= CFM_BROWSABLE_DIRS; 819 return 0; 820 } else if (STREQ(val, "no")) { 821 cfm->cfm_flags &= ~CFM_BROWSABLE_DIRS; 822 return 0; 823 } 824 825 fprintf(stderr, "conf: unknown value to browsable_dirs \"%s\"\n", val); 826 return 1; /* unknown value */ 827} 828 829 830static int 831ropt_map_name(const char *val, cf_map_t *cfm) 832{ 833 cfm->cfm_name = strdup((char *)val); 834 return 0; 835} 836 837 838static int 839ropt_map_options(const char *val, cf_map_t *cfm) 840{ 841 cfm->cfm_opts = strdup((char *)val); 842 return 0; 843} 844 845 846static int 847ropt_map_type(const char *val, cf_map_t *cfm) 848{ 849 cfm->cfm_type = strdup((char *)val); 850 return 0; 851} 852 853 854static int 855ropt_mount_type(const char *val, cf_map_t *cfm) 856{ 857 if (STREQ(val, "autofs")) { 858#ifdef HAVE_FS_AUTOFS 859 cfm->cfm_flags |= CFM_MOUNT_TYPE_AUTOFS; 860 return 0; 861#else /* not HAVE_FS_AUTOFS */ 862 fprintf(stderr, "conf: no autofs support available\n"); 863 return 1; 864#endif /* not HAVE_FS_AUTOFS */ 865 } else if (STREQ(val, "nfs")) { 866 cfm->cfm_flags &= ~CFM_MOUNT_TYPE_AUTOFS; 867 return 0; 868 } 869 870 fprintf(stderr, "conf: unknown value to mount_type \"%s\"\n", val); 871 return 1; /* unknown value */ 872} 873 874 875static int 876ropt_search_path(const char *val, cf_map_t *cfm) 877{ 878 cfm->cfm_search_path = strdup((char *)val); 879 return 0; 880} 881 882 883static int 884ropt_tag(const char *val, cf_map_t *cfm) 885{ 886 cfm->cfm_tag = strdup((char *)val); 887 return 0; 888} 889 890 891/* 892 * Process one collected map. 893 */ 894static int 895process_regular_map(cf_map_t *cfm) 896{ 897 898 if (!cfm->cfm_name) { 899 fprintf(stderr, "conf: map_name must be defined for map \"%s\"\n", cfm->cfm_dir); 900 return 1; 901 } 902 /* 903 * If map has no tag defined, process the map. 904 * If no conf_tag was set in amd -T, process all untagged entries. 905 * If a tag is defined, then process it only if it matches the map tag. 906 */ 907 if (!cfm->cfm_tag || 908 (conf_tag && STREQ(cfm->cfm_tag, conf_tag))) { 909#ifdef DEBUG_CONF 910 fprintf(stderr, "processing map %s (flags=0x%x)...\n", 911 cfm->cfm_dir, cfm->cfm_flags); 912#endif /* DEBUG_CONF */ 913 root_newmap(cfm->cfm_dir, 914 cfm->cfm_opts ? cfm->cfm_opts : "", 915 cfm->cfm_name, 916 cfm); 917 } else { 918 fprintf(stderr, "skipping map %s...\n", cfm->cfm_dir); 919 } 920 921 reset_cf_map(cfm); 922 return 0; 923} 924 925 926/* 927 * Process last map in conf file (if any) 928 */ 929int 930process_last_regular_map(void) 931{ 932 /* 933 * If the amd.conf file only has a [global] section (pretty useless 934 * IMHO), do not try to process a map that does not exist. 935 */ 936 if (!cur_map.cfm_dir) 937 return 0; 938 return process_regular_map(&cur_map); 939} 940