conf.c revision 131702
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 */ 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_allow_insecure_port(const char *val); 102static int gopt_nfs_proto(const char *val); 103static int gopt_nfs_retransmit_counter(const char *val); 104static int gopt_nfs_retry_interval(const char *val); 105static int gopt_nfs_vers(const char *val); 106static int gopt_nis_domain(const char *val); 107static int gopt_normalize_hostnames(const char *val); 108static int gopt_os(const char *val); 109static int gopt_osver(const char *val); 110static int gopt_plock(const char *val); 111static int gopt_print_pid(const char *val); 112static int gopt_print_version(const char *val); 113static int gopt_restart_mounts(const char *val); 114static int gopt_search_path(const char *val); 115static int gopt_selectors_in_defaults(const char *val); 116static int gopt_show_statfs_entries(const char *val); 117static int gopt_unmount_on_exit(const char *val); 118static int gopt_vendor(const char *val); 119static int process_global_option(const char *key, const char *val); 120static int process_regular_map(cf_map_t *cfm); 121static int process_regular_option(const char *section, const char *key, const char *val, cf_map_t *cfm); 122static int ropt_browsable_dirs(const char *val, cf_map_t *cfm); 123static int ropt_map_name(const char *val, cf_map_t *cfm); 124static int ropt_map_options(const char *val, cf_map_t *cfm); 125static int ropt_map_type(const char *val, cf_map_t *cfm); 126static int ropt_mount_type(const char *val, cf_map_t *cfm); 127static int ropt_search_path(const char *val, cf_map_t *cfm); 128static int ropt_tag(const char *val, cf_map_t *cfm); 129static void reset_cf_map(cf_map_t *cfm); 130 131 132/* 133 * STATIC VARIABLES: 134 */ 135static cf_map_t cur_map; 136static 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 */ 186static void 187reset_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 */ 248int 249set_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 */ 305static int 306process_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 326static int 327gopt_arch(const char *val) 328{ 329 gopt.arch = strdup((char *)val); 330 return 0; 331} 332 333 334static int 335gopt_auto_dir(const char *val) 336{ 337 gopt.auto_dir = strdup((char *)val); 338 return 0; 339} 340 341 342static int 343gopt_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 361static int 362gopt_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 371static int 372gopt_cluster(const char *val) 373{ 374 gopt.cluster = strdup((char *)val); 375 return 0; 376} 377 378 379static int 380gopt_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 393static int 394gopt_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 403static int 404gopt_full_os(const char *val) 405{ 406 gopt.op_sys_full = strdup((char *)val); 407 return 0; 408} 409 410 411static int 412gopt_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 427static int 428gopt_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 440static int 441gopt_karch(const char *val) 442{ 443 gopt.karch = strdup((char *)val); 444 return 0; 445} 446 447 448static int 449gopt_pid_file(const char *val) 450{ 451 gopt.pid_file = strdup((char *)val); 452 return 0; 453} 454 455 456static int 457gopt_local_domain(const char *val) 458{ 459 gopt.sub_domain = strdup((char *)val); 460 return 0; 461} 462 463 464static int 465gopt_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 477static int 478gopt_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 496static int 497gopt_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 515static int 516gopt_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 529static int 530gopt_log_file(const char *val) 531{ 532 gopt.logfile = strdup((char *)val); 533 return 0; 534} 535 536 537static int 538gopt_log_options(const char *val) 539{ 540 usage += switch_option(strdup((char *)val)); 541 return 0; 542} 543 544 545static int 546gopt_map_options(const char *val) 547{ 548 gopt.map_options = strdup((char *)val); 549 return 0; 550} 551 552 553static int 554gopt_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 566static int 567gopt_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 583static int 584gopt_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 604static int 605gopt_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 620static int 621gopt_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 632static int 633gopt_nfs_retransmit_counter(const char *val) 634{ 635 gopt.amfs_auto_retrans = atoi(val); 636 return 0; 637} 638 639 640static int 641gopt_nfs_retry_interval(const char *val) 642{ 643 gopt.amfs_auto_timeo = atoi(val); 644 return 0; 645} 646 647 648static int 649gopt_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 662static int 663gopt_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 675static int 676gopt_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 691static int 692gopt_os(const char *val) 693{ 694 gopt.op_sys = strdup((char *)val); 695 return 0; 696} 697 698 699static int 700gopt_osver(const char *val) 701{ 702 gopt.op_sys_ver = strdup((char *)val); 703 return 0; 704} 705 706 707static int 708gopt_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 723static int 724gopt_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 739static int 740gopt_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 754static int 755gopt_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 770static int 771gopt_search_path(const char *val) 772{ 773 gopt.search_path = strdup((char *)val); 774 return 0; 775} 776 777 778static int 779gopt_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 794static int 795gopt_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 810static int 811gopt_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 826static int 827gopt_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 */ 837static int 838process_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 881static int 882ropt_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 900static int 901ropt_map_name(const char *val, cf_map_t *cfm) 902{ 903 cfm->cfm_name = strdup((char *)val); 904 return 0; 905} 906 907 908static int 909ropt_map_options(const char *val, cf_map_t *cfm) 910{ 911 cfm->cfm_opts = strdup((char *)val); 912 return 0; 913} 914 915 916static int 917ropt_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 929static int 930ropt_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 946static int 947ropt_search_path(const char *val, cf_map_t *cfm) 948{ 949 cfm->cfm_search_path = strdup((char *)val); 950 return 0; 951} 952 953 954static int 955ropt_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 */ 965static int 966process_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 */ 1000int 1001process_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} 1011