conf.c revision 119679
190075Sobrien/* 290075Sobrien * Copyright (c) 1997-2003 Erez Zadok 390075Sobrien * Copyright (c) 1990 Jan-Simon Pendry 490075Sobrien * Copyright (c) 1990 Imperial College of Science, Technology & Medicine 590075Sobrien * Copyright (c) 1990 The Regents of the University of California. 690075Sobrien * All rights reserved. 790075Sobrien * 890075Sobrien * This code is derived from software contributed to Berkeley by 990075Sobrien * Jan-Simon Pendry at Imperial College, London. 1090075Sobrien * 1190075Sobrien * Redistribution and use in source and binary forms, with or without 1290075Sobrien * modification, are permitted provided that the following conditions 1390075Sobrien * are met: 1490075Sobrien * 1. Redistributions of source code must retain the above copyright 1590075Sobrien * notice, this list of conditions and the following disclaimer. 1690075Sobrien * 2. Redistributions in binary form must reproduce the above copyright 1790075Sobrien * notice, this list of conditions and the following disclaimer in the 18169689Skan * documentation and/or other materials provided with the distribution. 19169689Skan * 3. All advertising materials mentioning features or use of this software 2090075Sobrien * must display the following acknowledgment: 2190075Sobrien * This product includes software developed by the University of 2290075Sobrien * California, Berkeley and its contributors. 23117395Skan * 4. Neither the name of the University nor the names of its contributors 24169689Skan * may be used to endorse or promote products derived from this software 25169689Skan * without specific prior written permission. 26169689Skan * 27169689Skan * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2890075Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2990075Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 3090075Sobrien * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 3190075Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3290075Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3390075Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3490075Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3590075Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3690075Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3790075Sobrien * SUCH DAMAGE. 3890075Sobrien * 3990075Sobrien * %W% (Berkeley) %G% 4090075Sobrien * 4190075Sobrien * $Id: conf.c,v 1.7.2.6 2002/12/27 22:44:34 ezk Exp $ 4290075Sobrien * 4390075Sobrien */ 4490075Sobrien 4590075Sobrien/* 4690075Sobrien * Functions to handle the configuration file. 4790075Sobrien */ 4890075Sobrien 4990075Sobrien#ifdef HAVE_CONFIG_H 50117395Skan# include <config.h> 5190075Sobrien#endif /* HAVE_CONFIG_H */ 5290075Sobrien#include <am_defs.h> 5390075Sobrien#include <amd.h> 5490075Sobrien 5590075Sobrien 5690075Sobrien/* 5790075Sobrien * MACROS: 5890075Sobrien */ 5990075Sobrien/* Turn on to show some info about maps being configured */ 6090075Sobrien/* #define DEBUG_CONF */ 6190075Sobrien 6290075Sobrien/* 63169689Skan * TYPEDEFS: 64169689Skan */ 6590075Sobrientypedef int (*OptFuncPtr)(const char *); 6690075Sobrien 6790075Sobrien/* 6890075Sobrien * STRUCTURES: 6990075Sobrien */ 7090075Sobrienstruct _func_map { 7190075Sobrien char *name; 72169689Skan OptFuncPtr func; 73169689Skan}; 7490075Sobrien 7590075Sobrien/* 7690075Sobrien * FORWARD DECLARATIONS: 7790075Sobrien */ 7890075Sobrienstatic int gopt_arch(const char *val); 7990075Sobrienstatic int gopt_auto_dir(const char *val); 8090075Sobrienstatic int gopt_browsable_dirs(const char *val); 8190075Sobrienstatic int gopt_cache_duration(const char *val); 8290075Sobrienstatic int gopt_cluster(const char *val); 8390075Sobrienstatic int gopt_debug_options(const char *val); 84169689Skanstatic int gopt_dismount_interval(const char *val); 85169689Skanstatic int gopt_full_os(const char *val); 86169689Skanstatic int gopt_fully_qualified_hosts(const char *val); 87169689Skanstatic int gopt_hesiod_base(const char *val); 88169689Skanstatic int gopt_karch(const char *val); 8990075Sobrienstatic int gopt_ldap_base(const char *val); 9090075Sobrienstatic int gopt_ldap_cache_maxmem(const char *val); 9190075Sobrienstatic int gopt_ldap_cache_seconds(const char *val); 9290075Sobrienstatic int gopt_ldap_hostports(const char *val); 93117395Skanstatic int gopt_local_domain(const char *val); 94117395Skanstatic int gopt_log_file(const char *val); 95117395Skanstatic int gopt_log_options(const char *val); 96117395Skanstatic int gopt_map_options(const char *val); 97117395Skanstatic int gopt_map_type(const char *val); 9890075Sobrienstatic int gopt_mount_type(const char *val); 9990075Sobrienstatic int gopt_pid_file(const char *val); 10090075Sobrienstatic int gopt_portmap_program(const char *val); 10190075Sobrienstatic int gopt_nfs_proto(const char *val); 10290075Sobrienstatic int gopt_nfs_retransmit_counter(const char *val); 10390075Sobrienstatic int gopt_nfs_retry_interval(const char *val); 10490075Sobrienstatic int gopt_nfs_vers(const char *val); 10590075Sobrienstatic int gopt_nis_domain(const char *val); 10690075Sobrienstatic int gopt_normalize_hostnames(const char *val); 10790075Sobrienstatic int gopt_os(const char *val); 10890075Sobrienstatic int gopt_osver(const char *val); 109122180Skanstatic int gopt_plock(const char *val); 11090075Sobrienstatic int gopt_print_pid(const char *val); 11190075Sobrienstatic int gopt_print_version(const char *val); 11296263Sobrienstatic int gopt_restart_mounts(const char *val); 113122180Skanstatic int gopt_search_path(const char *val); 114117395Skanstatic int gopt_selectors_in_defaults(const char *val); 115122180Skanstatic int gopt_show_statfs_entries(const char *val); 116117395Skanstatic int gopt_unmount_on_exit(const char *val); 117122180Skanstatic int gopt_vendor(const char *val); 118117395Skanstatic int process_global_option(const char *key, const char *val); 11996263Sobrienstatic int process_regular_map(cf_map_t *cfm); 12096263Sobrienstatic int process_regular_option(const char *section, const char *key, const char *val, cf_map_t *cfm); 12190075Sobrienstatic int ropt_browsable_dirs(const char *val, cf_map_t *cfm); 122122180Skanstatic int ropt_map_name(const char *val, cf_map_t *cfm); 123122180Skanstatic int ropt_map_options(const char *val, cf_map_t *cfm); 124122180Skanstatic int ropt_map_type(const char *val, cf_map_t *cfm); 125122180Skanstatic int ropt_mount_type(const char *val, cf_map_t *cfm); 126122180Skanstatic int ropt_search_path(const char *val, cf_map_t *cfm); 127122180Skanstatic int ropt_tag(const char *val, cf_map_t *cfm); 128122180Skanstatic void reset_cf_map(cf_map_t *cfm); 12990075Sobrien 13090075Sobrien 13190075Sobrien/* 13290075Sobrien * STATIC VARIABLES: 133 */ 134static cf_map_t cur_map; 135static struct _func_map glob_functable[] = { 136 {"arch", gopt_arch}, 137 {"auto_dir", gopt_auto_dir}, 138 {"browsable_dirs", gopt_browsable_dirs}, 139 {"cache_duration", gopt_cache_duration}, 140 {"cluster", gopt_cluster}, 141 {"debug_options", gopt_debug_options}, 142 {"dismount_interval", gopt_dismount_interval}, 143 {"fully_qualified_hosts", gopt_fully_qualified_hosts}, 144 {"full_os", gopt_full_os}, 145 {"hesiod_base", gopt_hesiod_base}, 146 {"karch", gopt_karch}, 147 {"ldap_base", gopt_ldap_base}, 148 {"ldap_cache_maxmem", gopt_ldap_cache_maxmem}, 149 {"ldap_cache_seconds", gopt_ldap_cache_seconds}, 150 {"ldap_hostports", gopt_ldap_hostports}, 151 {"local_domain", gopt_local_domain}, 152 {"log_file", gopt_log_file}, 153 {"log_options", gopt_log_options}, 154 {"map_options", gopt_map_options}, 155 {"map_type", gopt_map_type}, 156 {"mount_type", gopt_mount_type}, 157 {"pid_file", gopt_pid_file}, 158 {"portmap_program", gopt_portmap_program}, 159 {"nfs_proto", gopt_nfs_proto}, 160 {"nfs_retransmit_counter", gopt_nfs_retransmit_counter}, 161 {"nfs_retry_interval", gopt_nfs_retry_interval}, 162 {"nfs_vers", gopt_nfs_vers}, 163 {"nis_domain", gopt_nis_domain}, 164 {"normalize_hostnames", gopt_normalize_hostnames}, 165 {"os", gopt_os}, 166 {"osver", gopt_osver}, 167 {"plock", gopt_plock}, 168 {"print_pid", gopt_print_pid}, 169 {"print_version", gopt_print_version}, 170 {"restart_mounts", gopt_restart_mounts}, 171 {"search_path", gopt_search_path}, 172 {"selectors_on_default", gopt_selectors_in_defaults}, 173 {"selectors_in_defaults", gopt_selectors_in_defaults}, 174 {"show_statfs_entries", gopt_show_statfs_entries}, 175 {"unmount_on_exit", gopt_unmount_on_exit}, 176 {"vendor", gopt_vendor}, 177 {NULL, NULL} 178}; 179 180 181/* 182 * Reset a map. 183 */ 184static void 185reset_cf_map(cf_map_t *cfm) 186{ 187 if (!cfm) 188 return; 189 190 if (cfm->cfm_dir) { 191 XFREE(cfm->cfm_dir); 192 cfm->cfm_dir = NULL; 193 } 194 195 if (cfm->cfm_name) { 196 XFREE(cfm->cfm_name); 197 cfm->cfm_name = NULL; 198 } 199 200 if (cfm->cfm_tag) { 201 XFREE(cfm->cfm_tag); 202 cfm->cfm_tag = NULL; 203 } 204 205 /* 206 * reset/initialize a regular map's flags and other variables from the 207 * global ones, so that they are applied to all maps. Of course, each map 208 * can then override the flags individually. 209 * 210 * NOTES: 211 * (1): Will only work for maps that appear after [global]. 212 * (2): Also be careful not to free() a global option. 213 * (3): I'm doing direct char* pointer comparison, and not strcmp(). This 214 * is correct! 215 */ 216 217 /* initialize map_type from [global] */ 218 if (cfm->cfm_type && cfm->cfm_type != gopt.map_type) 219 XFREE(cfm->cfm_type); 220 cfm->cfm_type = gopt.map_type; 221 222 /* initialize map_opts from [global] */ 223 if (cfm->cfm_opts && cfm->cfm_opts != gopt.map_options) 224 XFREE(cfm->cfm_opts); 225 cfm->cfm_opts = gopt.map_options; 226 227 /* initialize search_path from [global] */ 228 if (cfm->cfm_search_path && cfm->cfm_search_path != gopt.search_path) 229 XFREE(cfm->cfm_search_path); 230 cfm->cfm_search_path = gopt.search_path; 231 232 /* 233 * Initialize flags that are common both to [global] and a local map. 234 */ 235 cfm->cfm_flags = gopt.flags & (CFM_BROWSABLE_DIRS | 236 CFM_BROWSABLE_DIRS_FULL | 237 CFM_MOUNT_TYPE_AUTOFS | 238 CFM_SELECTORS_IN_DEFAULTS); 239} 240 241 242/* 243 * Process configuration file options. 244 * Return 0 if OK, 1 otherwise. 245 */ 246int 247set_conf_kv(const char *section, const char *key, const char *val) 248{ 249 int ret; 250 251#ifdef DEBUG_CONF 252 fprintf(stderr,"set_conf_kv: section=%s, key=%s, val=%s\n", 253 section, key, val); 254#endif /* DEBUG_CONF */ 255 256 /* 257 * If global section, process them one at a time. 258 */ 259 if (STREQ(section, "global")) { 260 /* 261 * Check if a regular map was configured before "global", 262 * and process it as needed. 263 */ 264 if (cur_map.cfm_dir) { 265 fprintf(stderr,"processing regular map \"%s\" before global one.\n", 266 section); 267 ret = process_regular_map(&cur_map); /* will reset map */ 268 if (ret != 0) 269 return ret; 270 } 271 272 /* process the global option first */ 273 ret = process_global_option(key, val); 274 275 /* reset default options for regular maps from just updated globals */ 276 if (ret == 0) 277 reset_cf_map(&cur_map); 278 279 /* return status from the processing of the global option */ 280 return ret; 281 } 282 283 /* 284 * otherwise save options and process a single map all at once. 285 */ 286 287 /* check if we found a new map, so process one already collected */ 288 if (cur_map.cfm_dir && !STREQ(cur_map.cfm_dir, section)) { 289 ret = process_regular_map(&cur_map); /* will reset map */ 290 if (ret != 0) 291 return ret; 292 } 293 294 /* now process a single entry of a regular map */ 295 return process_regular_option(section, key, val, &cur_map); 296} 297 298 299/* 300 * Process global section of configuration file options. 301 * Return 0 upon success, 1 otherwise. 302 */ 303static int 304process_global_option(const char *key, const char *val) 305{ 306 struct _func_map *gfp; 307 308 /* ensure that val is valid */ 309 if (!val || val[0] == '\0') 310 return 1; 311 312 /* 313 * search for global function. 314 */ 315 for (gfp = glob_functable; gfp->name; gfp++) 316 if (FSTREQ(gfp->name, key)) 317 return (gfp->func)(val); 318 319 fprintf(stderr, "conf: unknown global key: \"%s\"\n", key); 320 return 1; /* failed to match any command */ 321} 322 323 324static int 325gopt_arch(const char *val) 326{ 327 gopt.arch = strdup((char *)val); 328 return 0; 329} 330 331 332static int 333gopt_auto_dir(const char *val) 334{ 335 gopt.auto_dir = strdup((char *)val); 336 return 0; 337} 338 339 340static int 341gopt_browsable_dirs(const char *val) 342{ 343 if (STREQ(val, "full")) { 344 gopt.flags |= CFM_BROWSABLE_DIRS_FULL; 345 return 0; 346 } else if (STREQ(val, "yes")) { 347 gopt.flags |= CFM_BROWSABLE_DIRS; 348 return 0; 349 } else if (STREQ(val, "no")) { 350 gopt.flags &= ~CFM_BROWSABLE_DIRS; 351 return 0; 352 } 353 354 fprintf(stderr, "conf: unknown value to browsable_dirs \"%s\"\n", val); 355 return 1; /* unknown value */ 356} 357 358 359static int 360gopt_cache_duration(const char *val) 361{ 362 gopt.am_timeo = atoi(val); 363 if (gopt.am_timeo <= 0) 364 gopt.am_timeo = AM_TTL; 365 return 0; 366} 367 368 369static int 370gopt_cluster(const char *val) 371{ 372 gopt.cluster = strdup((char *)val); 373 return 0; 374} 375 376 377static int 378gopt_debug_options(const char *val) 379{ 380#ifdef DEBUG 381 usage += debug_option(strdup((char *)val)); 382 return 0; 383#else /* not DEBUG */ 384 fprintf(stderr, "%s: not compiled with DEBUG option -- sorry.\n", 385 am_get_progname()); 386 return 1; 387#endif /* not DEBUG */ 388} 389 390 391static int 392gopt_dismount_interval(const char *val) 393{ 394 gopt.am_timeo_w = atoi(val); 395 if (gopt.am_timeo_w <= 0) 396 gopt.am_timeo_w = AM_TTL_W; 397 return 0; 398} 399 400 401static int 402gopt_full_os(const char *val) 403{ 404 gopt.op_sys_full = strdup((char *)val); 405 return 0; 406} 407 408 409static int 410gopt_fully_qualified_hosts(const char *val) 411{ 412 if (STREQ(val, "yes")) { 413 gopt.flags |= CFM_FULLY_QUALIFIED_HOSTS; 414 return 0; 415 } else if (STREQ(val, "no")) { 416 gopt.flags &= ~CFM_FULLY_QUALIFIED_HOSTS; 417 return 0; 418 } 419 420 fprintf(stderr, "conf: unknown value to fully_qualified_hosts \"%s\"\n", val); 421 return 1; /* unknown value */ 422} 423 424 425static int 426gopt_hesiod_base(const char *val) 427{ 428#ifdef HAVE_MAP_HESIOD 429 gopt.hesiod_base = strdup((char *)val); 430 return 0; 431#else /* not HAVE_MAP_HESIOD */ 432 fprintf(stderr, "conf: hesiod_base option ignored. No Hesiod support available.\n"); 433 return 1; 434#endif /* not HAVE_MAP_HESIOD */ 435} 436 437 438static int 439gopt_karch(const char *val) 440{ 441 gopt.karch = strdup((char *)val); 442 return 0; 443} 444 445 446static int 447gopt_pid_file(const char *val) 448{ 449 gopt.pid_file = strdup((char *)val); 450 return 0; 451} 452 453 454static int 455gopt_local_domain(const char *val) 456{ 457 gopt.sub_domain = strdup((char *)val); 458 return 0; 459} 460 461 462static int 463gopt_ldap_base(const char *val) 464{ 465#ifdef HAVE_MAP_LDAP 466 gopt.ldap_base = strdup((char *)val); 467 return 0; 468#else /* not HAVE_MAP_LDAP */ 469 fprintf(stderr, "conf: ldap_base option ignored. No LDAP support available.\n"); 470 return 1; 471#endif /* not HAVE_MAP_LDAP */ 472} 473 474 475static int 476gopt_ldap_cache_seconds(const char *val) 477{ 478#ifdef HAVE_MAP_LDAP 479 char *end; 480 481 gopt.ldap_cache_seconds = strtol((char *)val, &end, 10); 482 if (end == val) { 483 fprintf(stderr, "conf: bad LDAP cache (seconds) option: %s\n",val); 484 return 1; 485 } 486 return 0; 487#else /* not HAVE_MAP_LDAP */ 488 fprintf(stderr, "conf: ldap_cache_seconds option ignored. No LDAP support available.\n"); 489 return 1; 490#endif /* not HAVE_MAP_LDAP */ 491} 492 493 494static int 495gopt_ldap_cache_maxmem(const char *val) 496{ 497#ifdef HAVE_MAP_LDAP 498 char *end; 499 500 gopt.ldap_cache_maxmem = strtol((char *)val, &end, 10); 501 if (end == val) { 502 fprintf(stderr, "conf: bad LDAP cache (maxmem) option: %s\n",val); 503 return 1; 504 } 505 return 0; 506#else /* not HAVE_MAP_LDAP */ 507 fprintf(stderr, "conf: ldap_cache_maxmem option ignored. No LDAP support available.\n"); 508 return 1; 509#endif /* not HAVE_MAP_LDAP */ 510} 511 512 513static int 514gopt_ldap_hostports(const char *val) 515{ 516#ifdef HAVE_MAP_LDAP 517 gopt.ldap_hostports = strdup((char *)val); 518 return 0; 519#else /* not HAVE_MAP_LDAP */ 520 fprintf(stderr, "conf: ldap_hostports option ignored. No LDAP support available.\n"); 521 return 1; 522#endif /* not HAVE_MAP_LDAP */ 523 524} 525 526 527static int 528gopt_log_file(const char *val) 529{ 530 gopt.logfile = strdup((char *)val); 531 return 0; 532} 533 534 535static int 536gopt_log_options(const char *val) 537{ 538 usage += switch_option(strdup((char *)val)); 539 return 0; 540} 541 542 543static int 544gopt_map_options(const char *val) 545{ 546 gopt.map_options = strdup((char *)val); 547 return 0; 548} 549 550 551static int 552gopt_map_type(const char *val) 553{ 554 /* check if map type exist */ 555 if (!mapc_type_exists(val)) { 556 fprintf(stderr, "conf: no such map type \"%s\"\n", val); 557 return 1; 558 } 559 gopt.map_type = strdup((char *)val); 560 return 0; 561} 562 563 564static int 565gopt_mount_type(const char *val) 566{ 567 if (STREQ(val, "autofs")) { 568 fprintf(stderr, "conf: no autofs support available, turning it off\n"); 569 gopt.flags &= ~CFM_MOUNT_TYPE_AUTOFS; 570 return 0; 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 number \"%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_proto(const char *val) 604{ 605 if (STREQ(val, "udp") || STREQ(val, "tcp")) { 606 gopt.nfs_proto = strdup((char *)val); 607 return 0; 608 } 609 fprintf(stderr, "conf: illegal nfs_proto \"%s\"\n", val); 610 return 1; 611} 612 613 614static int 615gopt_nfs_retransmit_counter(const char *val) 616{ 617 gopt.amfs_auto_retrans = atoi(val); 618 return 0; 619} 620 621 622static int 623gopt_nfs_retry_interval(const char *val) 624{ 625 gopt.amfs_auto_timeo = atoi(val); 626 return 0; 627} 628 629 630static int 631gopt_nfs_vers(const char *val) 632{ 633 int i = atoi(val); 634 635 if (i == 2 || i == 3) { 636 gopt.nfs_vers = i; 637 return 0; 638 } 639 fprintf(stderr, "conf: illegal nfs_vers \"%s\"\n", val); 640 return 1; 641} 642 643 644static int 645gopt_nis_domain(const char *val) 646{ 647#ifdef HAVE_MAP_NIS 648 gopt.nis_domain = strdup((char *)val); 649 return 0; 650#else /* not HAVE_MAP_NIS */ 651 fprintf(stderr, "conf: nis_domain option ignored. No NIS support available.\n"); 652 return 1; 653#endif /* not HAVE_MAP_NIS */ 654} 655 656 657static int 658gopt_normalize_hostnames(const char *val) 659{ 660 if (STREQ(val, "yes")) { 661 gopt.flags |= CFM_NORMALIZE_HOSTNAMES; 662 return 0; 663 } else if (STREQ(val, "no")) { 664 gopt.flags &= ~CFM_NORMALIZE_HOSTNAMES; 665 return 0; 666 } 667 668 fprintf(stderr, "conf: unknown value to normalize_hostnames \"%s\"\n", val); 669 return 1; /* unknown value */ 670} 671 672 673static int 674gopt_os(const char *val) 675{ 676 gopt.op_sys = strdup((char *)val); 677 return 0; 678} 679 680 681static int 682gopt_osver(const char *val) 683{ 684 gopt.op_sys_ver = strdup((char *)val); 685 return 0; 686} 687 688 689static int 690gopt_plock(const char *val) 691{ 692 if (STREQ(val, "yes")) { 693 gopt.flags |= CFM_PROCESS_LOCK; 694 return 0; 695 } else if (STREQ(val, "no")) { 696 gopt.flags &= ~CFM_PROCESS_LOCK; 697 return 0; 698 } 699 700 fprintf(stderr, "conf: unknown value to plock \"%s\"\n", val); 701 return 1; /* unknown value */ 702} 703 704 705static int 706gopt_print_pid(const char *val) 707{ 708 if (STREQ(val, "yes")) { 709 gopt.flags |= CFM_PRINT_PID; 710 return 0; 711 } else if (STREQ(val, "no")) { 712 gopt.flags &= ~CFM_PRINT_PID; 713 return 0; 714 } 715 716 fprintf(stderr, "conf: unknown value to print_pid \"%s\"\n", val); 717 return 1; /* unknown value */ 718} 719 720 721static int 722gopt_print_version(const char *val) 723{ 724 if (STREQ(val, "yes")) { 725 fputs(get_version_string(), stderr); 726 return 0; 727 } else if (STREQ(val, "no")) { 728 return 0; 729 } 730 731 fprintf(stderr, "conf: unknown value to print_version \"%s\"\n", val); 732 return 1; /* unknown value */ 733} 734 735 736static int 737gopt_restart_mounts(const char *val) 738{ 739 if (STREQ(val, "yes")) { 740 gopt.flags |= CFM_RESTART_EXISTING_MOUNTS; 741 return 0; 742 } else if (STREQ(val, "no")) { 743 gopt.flags &= ~CFM_RESTART_EXISTING_MOUNTS; 744 return 0; 745 } 746 747 fprintf(stderr, "conf: unknown value to restart_mounts \"%s\"\n", val); 748 return 1; /* unknown value */ 749} 750 751 752static int 753gopt_search_path(const char *val) 754{ 755 gopt.search_path = strdup((char *)val); 756 return 0; 757} 758 759 760static int 761gopt_selectors_in_defaults(const char *val) 762{ 763 if (STREQ(val, "yes")) { 764 gopt.flags |= CFM_SELECTORS_IN_DEFAULTS; 765 return 0; 766 } else if (STREQ(val, "no")) { 767 gopt.flags &= ~CFM_SELECTORS_IN_DEFAULTS; 768 return 0; 769 } 770 771 fprintf(stderr, "conf: unknown value to enable_default_selectors \"%s\"\n", val); 772 return 1; /* unknown value */ 773} 774 775 776static int 777gopt_show_statfs_entries(const char *val) 778{ 779 if (STREQ(val, "yes")) { 780 gopt.flags |= CFM_SHOW_STATFS_ENTRIES; 781 return 0; 782 } else if (STREQ(val, "no")) { 783 gopt.flags &= ~CFM_SHOW_STATFS_ENTRIES; 784 return 0; 785 } 786 787 fprintf(stderr, "conf: unknown value to show_statfs_entries \"%s\"\n", val); 788 return 1; /* unknown value */ 789} 790 791 792static int 793gopt_unmount_on_exit(const char *val) 794{ 795 if (STREQ(val, "yes")) { 796 gopt.flags |= CFM_UNMOUNT_ON_EXIT; 797 return 0; 798 } else if (STREQ(val, "no")) { 799 gopt.flags &= ~CFM_UNMOUNT_ON_EXIT; 800 return 0; 801 } 802 803 fprintf(stderr, "conf: unknown value to unmount_on_exit \"%s\"\n", val); 804 return 1; /* unknown value */ 805} 806 807 808static int 809gopt_vendor(const char *val) 810{ 811 gopt.op_sys_vendor = strdup((char *)val); 812 return 0; 813} 814 815 816/* 817 * Collect one entry for a regular map 818 */ 819static int 820process_regular_option(const char *section, const char *key, const char *val, cf_map_t *cfm) 821{ 822 /* ensure that val is valid */ 823 if (!section || section[0] == '\0' || 824 !key || key[0] == '\0' || 825 !val || val[0] == '\0' || 826 !cfm) { 827 fprintf(stderr, "conf: process_regular_option: null entries\n"); 828 return 1; 829 } 830 831 /* check if initializing a new map */ 832 if (!cfm->cfm_dir) 833 cfm->cfm_dir = strdup((char *)section); 834 835 /* check for each possible field */ 836 if (STREQ(key, "browsable_dirs")) 837 return ropt_browsable_dirs(val, cfm); 838 839 if (STREQ(key, "map_name")) 840 return ropt_map_name(val, cfm); 841 842 if (STREQ(key, "map_options")) 843 return ropt_map_options(val, cfm); 844 845 if (STREQ(key, "map_type")) 846 return ropt_map_type(val, cfm); 847 848 if (STREQ(key, "mount_type")) 849 return ropt_mount_type(val, cfm); 850 851 if (STREQ(key, "search_path")) 852 return ropt_search_path(val, cfm); 853 854 if (STREQ(key, "tag")) 855 return ropt_tag(val, cfm); 856 857 fprintf(stderr, "conf: unknown regular key \"%s\" for section \"%s\"\n", 858 key, section); 859 return 1; /* failed to match any command */ 860} 861 862 863static int 864ropt_browsable_dirs(const char *val, cf_map_t *cfm) 865{ 866 if (STREQ(val, "full")) { 867 cfm->cfm_flags |= CFM_BROWSABLE_DIRS_FULL; 868 return 0; 869 } else if (STREQ(val, "yes")) { 870 cfm->cfm_flags |= CFM_BROWSABLE_DIRS; 871 return 0; 872 } else if (STREQ(val, "no")) { 873 cfm->cfm_flags &= ~CFM_BROWSABLE_DIRS; 874 return 0; 875 } 876 877 fprintf(stderr, "conf: unknown value to browsable_dirs \"%s\"\n", val); 878 return 1; /* unknown value */ 879} 880 881 882static int 883ropt_map_name(const char *val, cf_map_t *cfm) 884{ 885 cfm->cfm_name = strdup((char *)val); 886 return 0; 887} 888 889 890static int 891ropt_map_options(const char *val, cf_map_t *cfm) 892{ 893 cfm->cfm_opts = strdup((char *)val); 894 return 0; 895} 896 897 898static int 899ropt_map_type(const char *val, cf_map_t *cfm) 900{ 901 /* check if map type exist */ 902 if (!mapc_type_exists(val)) { 903 fprintf(stderr, "conf: no such map type \"%s\"\n", val); 904 return 1; 905 } 906 cfm->cfm_type = strdup((char *)val); 907 return 0; 908} 909 910 911static int 912ropt_mount_type(const char *val, cf_map_t *cfm) 913{ 914 if (STREQ(val, "autofs")) { 915 fprintf(stderr, "conf: no autofs support available, turning it off\n"); 916 cfm->cfm_flags &= ~CFM_MOUNT_TYPE_AUTOFS; 917 return 0; 918 } else if (STREQ(val, "nfs")) { 919 cfm->cfm_flags &= ~CFM_MOUNT_TYPE_AUTOFS; 920 return 0; 921 } 922 923 fprintf(stderr, "conf: unknown value to mount_type \"%s\"\n", val); 924 return 1; /* unknown value */ 925} 926 927 928static int 929ropt_search_path(const char *val, cf_map_t *cfm) 930{ 931 cfm->cfm_search_path = strdup((char *)val); 932 return 0; 933} 934 935 936static int 937ropt_tag(const char *val, cf_map_t *cfm) 938{ 939 cfm->cfm_tag = strdup((char *)val); 940 return 0; 941} 942 943 944/* 945 * Process one collected map. 946 */ 947static int 948process_regular_map(cf_map_t *cfm) 949{ 950 951 if (!cfm->cfm_name) { 952 fprintf(stderr, "conf: map_name must be defined for map \"%s\"\n", cfm->cfm_dir); 953 return 1; 954 } 955 /* 956 * If map has no tag defined, process the map. 957 * If no conf_tag was set in amd -T, process all untagged entries. 958 * If a tag is defined, then process it only if it matches the map tag. 959 */ 960 if (!cfm->cfm_tag || 961 (conf_tag && STREQ(cfm->cfm_tag, conf_tag))) { 962#ifdef DEBUG_CONF 963 fprintf(stderr, "processing map %s (flags=0x%x)...\n", 964 cfm->cfm_dir, cfm->cfm_flags); 965#endif /* DEBUG_CONF */ 966 root_newmap(cfm->cfm_dir, 967 cfm->cfm_opts ? cfm->cfm_opts : "", 968 cfm->cfm_name, 969 cfm); 970 } else { 971 fprintf(stderr, "skipping map %s...\n", cfm->cfm_dir); 972 } 973 974 reset_cf_map(cfm); 975 return 0; 976} 977 978 979/* 980 * Process last map in conf file (if any) 981 */ 982int 983process_last_regular_map(void) 984{ 985 /* 986 * If the amd.conf file only has a [global] section (pretty useless 987 * IMHO), do not try to process a map that does not exist. 988 */ 989 if (!cur_map.cfm_dir) 990 return 0; 991 return process_regular_map(&cur_map); 992} 993