conf.c revision 42629
1/* 2 * Copyright (c) 1997-1998 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.2 1998/12/27 06:24:46 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_fully_qualified_hosts(const char *val); 86static int gopt_hesiod_base(const char *val); 87static int gopt_karch(const char *val); 88static int gopt_ldap_base(const char *val); 89static int gopt_ldap_cache_maxmem(const char *val); 90static int gopt_ldap_cache_seconds(const char *val); 91static int gopt_ldap_hostports(const char *val); 92static int gopt_local_domain(const char *val); 93static int gopt_log_file(const char *val); 94static int gopt_log_options(const char *val); 95static 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 am_get_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 /* check if map type exist */ 538 if (!mapc_type_exists(val)) { 539 fprintf(stderr, "conf: no such map type \"%s\"\n", val); 540 return 1; 541 } 542 gopt.map_type = strdup((char *)val); 543 return 0; 544} 545 546 547static int 548gopt_mount_type(const char *val) 549{ 550 if (STREQ(val, "autofs")) { 551#ifdef HAVE_FS_AUTOFS 552 gopt.flags |= CFM_MOUNT_TYPE_AUTOFS; 553 return 0; 554#else /* not HAVE_FS_AUTOFS */ 555 fprintf(stderr, "conf: no autofs support available\n"); 556 return 1; 557#endif /* not HAVE_FS_AUTOFS */ 558 } else if (STREQ(val, "nfs")) { 559 gopt.flags &= ~CFM_MOUNT_TYPE_AUTOFS; 560 return 0; 561 } 562 563 fprintf(stderr, "conf: unknown value to mount_type \"%s\"\n", val); 564 return 1; /* unknown value */ 565} 566 567 568static int 569gopt_portmap_program(const char *val) 570{ 571 gopt.portmap_program = atoi(val); 572 /* 573 * allow alternate program numbers to be no more than 10 offset from 574 * official amd program number (300019). 575 */ 576 if (gopt.portmap_program < AMQ_PROGRAM || 577 gopt.portmap_program > AMQ_PROGRAM + 10) { 578 gopt.portmap_program = AMQ_PROGRAM; 579 set_amd_program_number(gopt.portmap_program); 580 fprintf(stderr, "conf: illegal amd program numver \"%s\"\n", val); 581 return 1; 582 } 583 584 set_amd_program_number(gopt.portmap_program); 585 return 0; /* all is OK */ 586} 587 588 589static int 590gopt_nfs_retransmit_counter(const char *val) 591{ 592 gopt.amfs_auto_retrans = atoi(val); 593 return 0; 594} 595 596 597static int 598gopt_nfs_retry_interval(const char *val) 599{ 600 gopt.amfs_auto_timeo = atoi(val); 601 return 0; 602} 603 604 605static int 606gopt_nis_domain(const char *val) 607{ 608#ifdef HAVE_MAP_NIS 609 gopt.nis_domain = strdup((char *)val); 610 return 0; 611#else /* not HAVE_MAP_NIS */ 612 fprintf(stderr, "conf: nis_domain option ignored. No NIS support available.\n"); 613 return 1; 614#endif /* not HAVE_MAP_NIS */ 615} 616 617 618static int 619gopt_normalize_hostnames(const char *val) 620{ 621 if (STREQ(val, "yes")) { 622 gopt.flags |= CFM_NORMALIZE_HOSTNAMES; 623 return 0; 624 } else if (STREQ(val, "no")) { 625 gopt.flags &= ~CFM_NORMALIZE_HOSTNAMES; 626 return 0; 627 } 628 629 fprintf(stderr, "conf: unknown value to normalize_hostnames \"%s\"\n", val); 630 return 1; /* unknown value */ 631} 632 633 634static int 635gopt_os(const char *val) 636{ 637 gopt.op_sys = strdup((char *)val); 638 return 0; 639} 640 641 642static int 643gopt_osver(const char *val) 644{ 645 gopt.op_sys_ver = strdup((char *)val); 646 return 0; 647} 648 649 650static int 651gopt_plock(const char *val) 652{ 653 if (STREQ(val, "yes")) { 654 gopt.flags |= CFM_PROCESS_LOCK; 655 return 0; 656 } else if (STREQ(val, "no")) { 657 gopt.flags &= ~CFM_PROCESS_LOCK; 658 return 0; 659 } 660 661 fprintf(stderr, "conf: unknown value to plock \"%s\"\n", val); 662 return 1; /* unknown value */ 663} 664 665 666static int 667gopt_print_pid(const char *val) 668{ 669 if (STREQ(val, "yes")) { 670 gopt.flags |= CFM_PRINT_PID; 671 return 0; 672 } else if (STREQ(val, "no")) { 673 gopt.flags &= ~CFM_PRINT_PID; 674 return 0; 675 } 676 677 fprintf(stderr, "conf: unknown value to print_pid \"%s\"\n", val); 678 return 1; /* unknown value */ 679} 680 681 682static int 683gopt_print_version(const char *val) 684{ 685 if (STREQ(val, "yes")) { 686 fputs(get_version_string(), stderr); 687 return 0; 688 } else if (STREQ(val, "no")) { 689 return 0; 690 } 691 692 fprintf(stderr, "conf: unknown value to print_version \"%s\"\n", val); 693 return 1; /* unknown value */ 694} 695 696 697static int 698gopt_restart_mounts(const char *val) 699{ 700 if (STREQ(val, "yes")) { 701 gopt.flags |= CFM_RESTART_EXISTING_MOUNTS; 702 return 0; 703 } else if (STREQ(val, "no")) { 704 gopt.flags &= ~CFM_RESTART_EXISTING_MOUNTS; 705 return 0; 706 } 707 708 fprintf(stderr, "conf: unknown value to restart_mounts \"%s\"\n", val); 709 return 1; /* unknown value */ 710} 711 712 713static int 714gopt_search_path(const char *val) 715{ 716 gopt.search_path = strdup((char *)val); 717 return 0; 718} 719 720 721static int 722gopt_selectors_on_default(const char *val) 723{ 724 if (STREQ(val, "yes")) { 725 gopt.flags |= CFM_ENABLE_DEFAULT_SELECTORS; 726 return 0; 727 } else if (STREQ(val, "no")) { 728 gopt.flags &= ~CFM_ENABLE_DEFAULT_SELECTORS; 729 return 0; 730 } 731 732 fprintf(stderr, "conf: unknown value to enable_default_selectors \"%s\"\n", val); 733 return 1; /* unknown value */ 734} 735 736 737static int 738gopt_show_statfs_entries(const char *val) 739{ 740 if (STREQ(val, "yes")) { 741 gopt.flags |= CFM_SHOW_STATFS_ENTRIES; 742 return 0; 743 } else if (STREQ(val, "no")) { 744 gopt.flags &= ~CFM_SHOW_STATFS_ENTRIES; 745 return 0; 746 } 747 748 fprintf(stderr, "conf: unknown value to show_statfs_entries \"%s\"\n", val); 749 return 1; /* unknown value */ 750} 751 752 753static int 754gopt_unmount_on_exit(const char *val) 755{ 756 if (STREQ(val, "yes")) { 757 gopt.flags |= CFM_UNMOUNT_ON_EXIT; 758 return 0; 759 } else if (STREQ(val, "no")) { 760 gopt.flags &= ~CFM_UNMOUNT_ON_EXIT; 761 return 0; 762 } 763 764 fprintf(stderr, "conf: unknown value to unmount_on_exit \"%s\"\n", val); 765 return 1; /* unknown value */ 766} 767 768 769/* 770 * Collect one entry for a regular map 771 */ 772static int 773process_regular_option(const char *section, const char *key, const char *val, cf_map_t *cfm) 774{ 775 /* ensure that val is valid */ 776 if (!section || section[0] == '\0' || 777 !key || key[0] == '\0' || 778 !val || val[0] == '\0' || 779 !cfm) { 780 fprintf(stderr, "conf: process_regular_option: null entries\n"); 781 return 1; 782 } 783 784 /* check if initializing a new map */ 785 if (!cfm->cfm_dir) 786 cfm->cfm_dir = strdup((char *)section); 787 788 /* check for each possible field */ 789 if (STREQ(key, "browsable_dirs")) 790 return ropt_browsable_dirs(val, cfm); 791 792 if (STREQ(key, "map_name")) 793 return ropt_map_name(val, cfm); 794 795 if (STREQ(key, "map_options")) 796 return ropt_map_options(val, cfm); 797 798 if (STREQ(key, "map_type")) 799 return ropt_map_type(val, cfm); 800 801 if (STREQ(key, "mount_type")) 802 return ropt_mount_type(val, cfm); 803 804 if (STREQ(key, "search_path")) 805 return ropt_search_path(val, cfm); 806 807 if (STREQ(key, "tag")) 808 return ropt_tag(val, cfm); 809 810 fprintf(stderr, "conf: unknown regular key \"%s\" for section \"%s\"\n", 811 key, section); 812 return 1; /* failed to match any command */ 813} 814 815 816static int 817ropt_browsable_dirs(const char *val, cf_map_t *cfm) 818{ 819 if (STREQ(val, "full")) { 820 cfm->cfm_flags |= CFM_BROWSABLE_DIRS_FULL; 821 return 0; 822 } else if (STREQ(val, "yes")) { 823 cfm->cfm_flags |= CFM_BROWSABLE_DIRS; 824 return 0; 825 } else if (STREQ(val, "no")) { 826 cfm->cfm_flags &= ~CFM_BROWSABLE_DIRS; 827 return 0; 828 } 829 830 fprintf(stderr, "conf: unknown value to browsable_dirs \"%s\"\n", val); 831 return 1; /* unknown value */ 832} 833 834 835static int 836ropt_map_name(const char *val, cf_map_t *cfm) 837{ 838 cfm->cfm_name = strdup((char *)val); 839 return 0; 840} 841 842 843static int 844ropt_map_options(const char *val, cf_map_t *cfm) 845{ 846 cfm->cfm_opts = strdup((char *)val); 847 return 0; 848} 849 850 851static int 852ropt_map_type(const char *val, cf_map_t *cfm) 853{ 854 /* check if map type exist */ 855 if (!mapc_type_exists(val)) { 856 fprintf(stderr, "conf: no such map type \"%s\"\n", val); 857 return 1; 858 } 859 cfm->cfm_type = strdup((char *)val); 860 return 0; 861} 862 863 864static int 865ropt_mount_type(const char *val, cf_map_t *cfm) 866{ 867 if (STREQ(val, "autofs")) { 868#ifdef HAVE_FS_AUTOFS 869 cfm->cfm_flags |= CFM_MOUNT_TYPE_AUTOFS; 870 return 0; 871#else /* not HAVE_FS_AUTOFS */ 872 fprintf(stderr, "conf: no autofs support available\n"); 873 return 1; 874#endif /* not HAVE_FS_AUTOFS */ 875 } else if (STREQ(val, "nfs")) { 876 cfm->cfm_flags &= ~CFM_MOUNT_TYPE_AUTOFS; 877 return 0; 878 } 879 880 fprintf(stderr, "conf: unknown value to mount_type \"%s\"\n", val); 881 return 1; /* unknown value */ 882} 883 884 885static int 886ropt_search_path(const char *val, cf_map_t *cfm) 887{ 888 cfm->cfm_search_path = strdup((char *)val); 889 return 0; 890} 891 892 893static int 894ropt_tag(const char *val, cf_map_t *cfm) 895{ 896 cfm->cfm_tag = strdup((char *)val); 897 return 0; 898} 899 900 901/* 902 * Process one collected map. 903 */ 904static int 905process_regular_map(cf_map_t *cfm) 906{ 907 908 if (!cfm->cfm_name) { 909 fprintf(stderr, "conf: map_name must be defined for map \"%s\"\n", cfm->cfm_dir); 910 return 1; 911 } 912 /* 913 * If map has no tag defined, process the map. 914 * If no conf_tag was set in amd -T, process all untagged entries. 915 * If a tag is defined, then process it only if it matches the map tag. 916 */ 917 if (!cfm->cfm_tag || 918 (conf_tag && STREQ(cfm->cfm_tag, conf_tag))) { 919#ifdef DEBUG_CONF 920 fprintf(stderr, "processing map %s (flags=0x%x)...\n", 921 cfm->cfm_dir, cfm->cfm_flags); 922#endif /* DEBUG_CONF */ 923 root_newmap(cfm->cfm_dir, 924 cfm->cfm_opts ? cfm->cfm_opts : "", 925 cfm->cfm_name, 926 cfm); 927 } else { 928 fprintf(stderr, "skipping map %s...\n", cfm->cfm_dir); 929 } 930 931 reset_cf_map(cfm); 932 return 0; 933} 934 935 936/* 937 * Process last map in conf file (if any) 938 */ 939int 940process_last_regular_map(void) 941{ 942 /* 943 * If the amd.conf file only has a [global] section (pretty useless 944 * IMHO), do not try to process a map that does not exist. 945 */ 946 if (!cur_map.cfm_dir) 947 return 0; 948 return process_regular_map(&cur_map); 949} 950