1 /* 2 * Copyright (c) 1992 Eric P. Allman. 3 * Copyright (c) 1992 Regents of the University of California. 4 * All rights reserved. 5 * 6 * %sccs.include.redist.c% 7 */ 8 9 #ifndef lint 10 static char sccsid[] = "@(#)map.c 6.22 (Berkeley) 05/28/93"; 11 #endif /* not lint */ 12 13 #include "sendmail.h" 14 15 #ifdef NDBM 16 #include <ndbm.h> 17 #endif 18 #ifdef NEWDB 19 #include <db.h> 20 #endif 21 #ifdef NIS 22 #include <rpcsvc/ypclnt.h> 23 #endif 24 25 /* 26 ** MAP.C -- implementations for various map classes. 27 ** 28 ** Each map class implements a series of functions: 29 ** 30 ** bool map_parse(MAP *map, char *args) 31 ** Parse the arguments from the config file. Return TRUE 32 ** if they were ok, FALSE otherwise. Fill in map with the 33 ** values. 34 ** 35 ** char *map_lookup(MAP *map, char *key, char **args, int *pstat) 36 ** Look up the key in the given map. If found, do any 37 ** rewriting the map wants (including "args" if desired) 38 ** and return the value. Set *pstat to the appropriate status 39 ** on error and return NULL. Args will be NULL if called 40 ** from the alias routines, although this should probably 41 ** not be relied upon. It is suggested you call map_rewrite 42 ** to return the results -- it takes care of null termination 43 ** and uses a dynamically expanded buffer as needed. 44 ** 45 ** void map_store(MAP *map, char *key, char *value) 46 ** Store the key:value pair in the map. 47 ** 48 ** bool map_open(MAP *map, int mode) 49 ** Open the map for the indicated mode. Mode should 50 ** be either O_RDONLY or O_RDWR. Return TRUE if it 51 ** was opened successfully, FALSE otherwise. If the open 52 ** failed an the MF_OPTIONAL flag is not set, it should 53 ** also print an error. If the MF_ALIAS bit is set 54 ** and this map class understands the @:@ convention, it 55 ** should call aliaswait() before returning. 56 ** 57 ** void map_close(MAP *map) 58 ** Close the map. 59 */ 60 61 #define DBMMODE 0644 62 /* 63 ** MAP_PARSEARGS -- parse config line arguments for database lookup 64 ** 65 ** This is a generic version of the map_parse method. 66 ** 67 ** Parameters: 68 ** map -- the map being initialized. 69 ** ap -- a pointer to the args on the config line. 70 ** 71 ** Returns: 72 ** TRUE -- if everything parsed OK. 73 ** FALSE -- otherwise. 74 ** 75 ** Side Effects: 76 ** null terminates the filename; stores it in map 77 */ 78 79 bool 80 map_parseargs(map, ap) 81 MAP *map; 82 char *ap; 83 { 84 register char *p = ap; 85 86 for (;;) 87 { 88 while (isascii(*p) && isspace(*p)) 89 p++; 90 if (*p != '-') 91 break; 92 switch (*++p) 93 { 94 case 'N': 95 map->map_mflags |= MF_INCLNULL; 96 break; 97 98 case 'o': 99 map->map_mflags |= MF_OPTIONAL; 100 break; 101 102 case 'f': 103 map->map_mflags |= MF_NOFOLDCASE; 104 break; 105 106 case 'm': 107 map->map_mflags |= MF_MATCHONLY; 108 break; 109 110 case 'a': 111 map->map_app = ++p; 112 break; 113 } 114 while (*p != '\0' && !(isascii(*p) && isspace(*p))) 115 p++; 116 if (*p != '\0') 117 *p++ = '\0'; 118 } 119 if (map->map_app != NULL) 120 map->map_app = newstr(map->map_app); 121 122 if (*p != '\0') 123 { 124 map->map_file = p; 125 while (*p != '\0' && !(isascii(*p) && isspace(*p))) 126 p++; 127 if (*p != '\0') 128 *p++ = '\0'; 129 map->map_file = newstr(map->map_file); 130 } 131 132 while (*p != '\0' && isascii(*p) && isspace(*p)) 133 p++; 134 if (*p != '\0') 135 map->map_rebuild = newstr(p); 136 137 if (map->map_file == NULL) 138 { 139 syserr("No file name for %s map %s", 140 map->map_class->map_cname, map->map_mname); 141 return FALSE; 142 } 143 return TRUE; 144 } 145 /* 146 ** MAP_REWRITE -- rewrite a database key, interpolating %n indications. 147 ** 148 ** It also adds the map_app string. It can be used as a utility 149 ** in the map_lookup method. 150 ** 151 ** Parameters: 152 ** map -- the map that causes this. 153 ** s -- the string to rewrite, NOT necessarily null terminated. 154 ** slen -- the length of s. 155 ** av -- arguments to interpolate into buf. 156 ** 157 ** Returns: 158 ** Pointer to rewritten result. 159 ** 160 ** Side Effects: 161 ** none. 162 */ 163 164 struct rwbuf 165 { 166 int rwb_len; /* size of buffer */ 167 char *rwb_buf; /* ptr to buffer */ 168 }; 169 170 struct rwbuf RwBufs[2]; /* buffers for rewriting output */ 171 172 char * 173 map_rewrite(map, s, slen, av) 174 register MAP *map; 175 register char *s; 176 int slen; 177 char **av; 178 { 179 register char *bp; 180 register char c; 181 char **avp; 182 register char *ap; 183 register struct rwbuf *rwb; 184 int i; 185 int len; 186 187 if (tTd(39, 1)) 188 { 189 printf("map_rewrite(%.*s), av =", slen, s); 190 if (av == NULL) 191 printf(" (nullv)"); 192 else 193 { 194 for (avp = av; *avp != NULL; avp++) 195 printf("\n\t%s", *avp); 196 } 197 printf("\n"); 198 } 199 200 rwb = RwBufs; 201 if (av == NULL) 202 rwb++; 203 204 /* count expected size of output (can safely overestimate) */ 205 i = len = slen; 206 if (av != NULL) 207 { 208 bp = s; 209 for (i = slen; --i >= 0 && (c = *bp++) != 0; ) 210 { 211 if (c != '%') 212 continue; 213 if (--i < 0) 214 break; 215 c = *bp++; 216 if (!(isascii(c) && isdigit(c))) 217 continue; 218 c -= 0; 219 for (avp = av; --c >= 0 && *avp != NULL; avp++) 220 continue; 221 if (*avp == NULL) 222 continue; 223 len += strlen(*avp); 224 } 225 } 226 if (map->map_app != NULL) 227 len += strlen(map->map_app); 228 if (rwb->rwb_len < ++len) 229 { 230 /* need to malloc additional space */ 231 rwb->rwb_len = len; 232 if (rwb->rwb_buf != NULL) 233 free(rwb->rwb_buf); 234 rwb->rwb_buf = xalloc(rwb->rwb_len); 235 } 236 237 bp = rwb->rwb_buf; 238 if (av == NULL) 239 { 240 bcopy(s, bp, slen); 241 bp += slen; 242 } 243 else 244 { 245 while (--slen >= 0 && (c = *s++) != '\0') 246 { 247 if (c != '%') 248 { 249 pushc: 250 *bp++ = c; 251 continue; 252 } 253 if (--slen < 0 || (c = *s++) == '\0') 254 c = '%'; 255 if (c == '%') 256 goto pushc; 257 if (!(isascii(c) && isdigit(c))) 258 { 259 *bp++ = '%'; 260 goto pushc; 261 } 262 c -= '0'; 263 for (avp = av; --c >= 0 && *avp != NULL; avp++) 264 continue; 265 if (*avp == NULL) 266 continue; 267 268 /* transliterate argument into output string */ 269 for (ap = *avp; (c = *ap++) != '\0'; ) 270 *bp++ = c; 271 } 272 } 273 if (map->map_app != NULL) 274 strcpy(bp, map->map_app); 275 else 276 *bp = '\0'; 277 if (tTd(39, 1)) 278 printf("map_rewrite => %s\n", rwb->rwb_buf); 279 return rwb->rwb_buf; 280 } 281 /* 282 ** INITMAPS -- initialize for aliasing 283 ** 284 ** Parameters: 285 ** rebuild -- if TRUE, this rebuilds the cached versions. 286 ** e -- current envelope. 287 ** 288 ** Returns: 289 ** none. 290 ** 291 ** Side Effects: 292 ** initializes aliases: 293 ** if NDBM: opens the database. 294 ** if ~NDBM: reads the aliases into the symbol table. 295 */ 296 297 initmaps(rebuild, e) 298 bool rebuild; 299 register ENVELOPE *e; 300 { 301 extern void map_init(); 302 303 CurEnv = e; 304 stabapply(map_init, rebuild); 305 } 306 307 void 308 map_init(s, rebuild) 309 register STAB *s; 310 int rebuild; 311 { 312 register MAP *map; 313 314 /* has to be a map */ 315 if (s->s_type != ST_MAP) 316 return; 317 318 map = &s->s_map; 319 if (!bitset(MF_VALID, map->map_mflags)) 320 return; 321 322 if (tTd(38, 2)) 323 printf("map_init(%s:%s)\n", 324 map->map_class->map_cname, map->map_file); 325 326 /* if already open, close it (for nested open) */ 327 if (bitset(MF_OPEN, map->map_mflags)) 328 { 329 map->map_class->map_close(map); 330 map->map_mflags &= ~(MF_OPEN|MF_WRITABLE); 331 } 332 333 if (rebuild) 334 { 335 if (bitset(MCF_REBUILDABLE, map->map_class->map_cflags)) 336 rebuildaliases(map, FALSE); 337 } 338 else 339 { 340 if (map->map_class->map_open(map, O_RDONLY)) 341 { 342 if (tTd(38, 4)) 343 printf("%s:%s: valid\n", 344 map->map_class->map_cname, 345 map->map_file); 346 map->map_mflags |= MF_OPEN; 347 } 348 else if (tTd(38, 4)) 349 printf("%s:%s: invalid: %s\n", 350 map->map_class->map_cname, 351 map->map_file, 352 errstring(errno)); 353 } 354 } 355 /* 356 ** NDBM modules 357 */ 358 359 #ifdef NDBM 360 361 /* 362 ** DBM_MAP_OPEN -- DBM-style map open 363 */ 364 365 bool 366 ndbm_map_open(map, mode) 367 MAP *map; 368 int mode; 369 { 370 DBM *dbm; 371 372 if (tTd(38, 2)) 373 printf("ndbm_map_open(%s, %d)\n", map->map_file, mode); 374 375 if (mode == O_RDWR) 376 mode |= O_CREAT|O_TRUNC; 377 378 /* open the database */ 379 dbm = dbm_open(map->map_file, mode, DBMMODE); 380 if (dbm == NULL) 381 { 382 if (!bitset(MF_OPTIONAL, map->map_mflags)) 383 syserr("Cannot open DBM database %s", map->map_file); 384 return FALSE; 385 } 386 map->map_db1 = (void *) dbm; 387 if (mode == O_RDONLY && bitset(MF_ALIAS, map->map_mflags)) 388 aliaswait(map, ".dir"); 389 return TRUE; 390 } 391 392 393 /* 394 ** DBM_MAP_LOOKUP -- look up a datum in a DBM-type map 395 */ 396 397 char * 398 ndbm_map_lookup(map, name, av, statp) 399 MAP *map; 400 char *name; 401 char **av; 402 int *statp; 403 { 404 datum key, val; 405 char keybuf[MAXNAME + 1]; 406 407 if (tTd(38, 20)) 408 printf("ndbm_map_lookup(%s)\n", name); 409 410 key.dptr = name; 411 key.dsize = strlen(name); 412 if (!bitset(MF_NOFOLDCASE, map->map_mflags)) 413 { 414 if (key.dsize > sizeof keybuf - 1) 415 key.dsize = sizeof keybuf - 1; 416 bcopy(key.dptr, keybuf, key.dsize + 1); 417 makelower(keybuf); 418 key.dptr = keybuf; 419 } 420 if (bitset(MF_INCLNULL, map->map_mflags)) 421 key.dsize++; 422 (void) lockfile(dbm_dirfno((DBM *) map->map_db1), map->map_file, LOCK_SH); 423 val = dbm_fetch((DBM *) map->map_db1, key); 424 (void) lockfile(dbm_dirfno((DBM *) map->map_db1), map->map_file, LOCK_UN); 425 if (val.dptr == NULL) 426 return NULL; 427 if (bitset(MF_MATCHONLY, map->map_mflags)) 428 av = NULL; 429 return map_rewrite(map, val.dptr, val.dsize, av); 430 } 431 432 433 /* 434 ** DBM_MAP_STORE -- store a datum in the database 435 */ 436 437 void 438 ndbm_map_store(map, lhs, rhs) 439 register MAP *map; 440 char *lhs; 441 char *rhs; 442 { 443 datum key; 444 datum data; 445 int stat; 446 447 if (tTd(38, 12)) 448 printf("ndbm_map_store(%s, %s)\n", lhs, rhs); 449 450 key.dsize = strlen(lhs); 451 key.dptr = lhs; 452 453 data.dsize = strlen(rhs); 454 data.dptr = rhs; 455 456 if (bitset(MF_INCLNULL, map->map_mflags)) 457 { 458 key.dsize++; 459 data.dsize++; 460 } 461 462 stat = dbm_store((DBM *) map->map_db1, key, data, DBM_INSERT); 463 if (stat > 0) 464 { 465 usrerr("050 Warning: duplicate alias name %s", lhs); 466 stat = dbm_store((DBM *) map->map_db1, key, data, DBM_REPLACE); 467 } 468 if (stat != 0) 469 syserr("readaliases: dbm put (%s)", lhs); 470 } 471 472 473 /* 474 ** NDBM_MAP_CLOSE -- close the database 475 */ 476 477 void 478 ndbm_map_close(map) 479 register MAP *map; 480 { 481 if (bitset(MF_WRITABLE, map->map_mflags)) 482 { 483 #ifdef YPCOMPAT 484 char buf[200]; 485 486 (void) sprintf(buf, "%010ld", curtime()); 487 ndbm_map_store(map, "YP_LAST_MODIFIED", buf); 488 489 (void) myhostname(buf, sizeof buf); 490 ndbm_map_store(map, "YP_MASTER_NAME", buf); 491 #endif 492 493 /* write out the distinguished alias */ 494 ndbm_map_store(map, "@", "@"); 495 } 496 dbm_close((DBM *) map->map_db1); 497 } 498 499 #endif 500 /* 501 ** HASH (NEWDB) Modules 502 */ 503 504 #ifdef NEWDB 505 506 /* 507 ** BTREE_MAP_PARSE -- BTREE-style map initialization 508 */ 509 510 bool 511 bt_map_open(map, mode) 512 MAP *map; 513 int mode; 514 { 515 DB *db; 516 int i; 517 char buf[MAXNAME]; 518 519 if (tTd(38, 2)) 520 printf("bt_map_open(%s, %d)\n", map->map_file, mode); 521 522 if (mode == O_RDWR) 523 mode |= O_CREAT|O_TRUNC; 524 525 (void) strcpy(buf, map->map_file); 526 i = strlen(buf); 527 if (i < 3 || strcmp(&buf[i - 3], ".db") != 0) 528 (void) strcat(buf, ".db"); 529 db = dbopen(buf, mode, DBMMODE, DB_BTREE, NULL); 530 if (db == NULL) 531 { 532 if (!bitset(MF_OPTIONAL, map->map_mflags)) 533 syserr("Cannot open BTREE database %s", map->map_file); 534 return FALSE; 535 } 536 map->map_db2 = (void *) db; 537 if (mode == O_RDONLY && bitset(MF_ALIAS, map->map_mflags)) 538 aliaswait(map, ".db"); 539 return TRUE; 540 } 541 542 543 /* 544 ** HASH_MAP_INIT -- HASH-style map initialization 545 */ 546 547 bool 548 hash_map_open(map, mode) 549 MAP *map; 550 int mode; 551 { 552 DB *db; 553 int i; 554 char buf[MAXNAME]; 555 556 if (tTd(38, 2)) 557 printf("hash_map_open(%s, %d)\n", map->map_file, mode); 558 559 if (mode == O_RDWR) 560 mode |= O_CREAT|O_TRUNC; 561 562 (void) strcpy(buf, map->map_file); 563 i = strlen(buf); 564 if (i < 3 || strcmp(&buf[i - 3], ".db") != 0) 565 (void) strcat(buf, ".db"); 566 db = dbopen(buf, mode, DBMMODE, DB_HASH, NULL); 567 if (db == NULL) 568 { 569 if (!bitset(MF_OPTIONAL, map->map_mflags)) 570 syserr("Cannot open HASH database %s", map->map_file); 571 return FALSE; 572 } 573 map->map_db2 = (void *) db; 574 if (mode == O_RDONLY && bitset(MF_ALIAS, map->map_mflags)) 575 aliaswait(map, ".db"); 576 return TRUE; 577 } 578 579 580 /* 581 ** DB_MAP_LOOKUP -- look up a datum in a BTREE- or HASH-type map 582 */ 583 584 char * 585 db_map_lookup(map, name, av, statp) 586 MAP *map; 587 char *name; 588 char **av; 589 int *statp; 590 { 591 DBT key, val; 592 register DB *db = (DB *) map->map_db2; 593 int st; 594 int saveerrno; 595 char keybuf[MAXNAME + 1]; 596 597 if (tTd(38, 20)) 598 printf("db_map_lookup(%s)\n", name); 599 600 key.size = strlen(name); 601 if (key.size > sizeof keybuf - 1) 602 key.size = sizeof keybuf - 1; 603 key.data = keybuf; 604 bcopy(name, keybuf, key.size + 1); 605 if (!bitset(MF_NOFOLDCASE, map->map_mflags)) 606 makelower(keybuf); 607 if (bitset(MF_INCLNULL, map->map_mflags)) 608 key.size++; 609 #ifndef OLD_NEWDB 610 (void) lockfile(db->fd(db), map->map_file, LOCK_SH); 611 #endif 612 st = db->get(db, &key, &val, 0); 613 saveerrno = errno; 614 #ifndef OLD_NEWDB 615 (void) lockfile(db->fd(db), map->map_file, LOCK_UN); 616 #endif 617 if (st != 0) 618 { 619 errno = saveerrno; 620 if (st < 0) 621 syserr("db_map_lookup: get (%s)", name); 622 return NULL; 623 } 624 if (bitset(MF_MATCHONLY, map->map_mflags)) 625 av = NULL; 626 return map_rewrite(map, val.data, val.size, av); 627 } 628 629 630 /* 631 ** DB_MAP_STORE -- store a datum in the NEWDB database 632 */ 633 634 void 635 db_map_store(map, lhs, rhs) 636 register MAP *map; 637 char *lhs; 638 char *rhs; 639 { 640 int stat; 641 DBT key; 642 DBT data; 643 register DB *db = map->map_db2; 644 645 if (tTd(38, 20)) 646 printf("db_map_store(%s, %s)\n", lhs, rhs); 647 648 key.size = strlen(lhs); 649 key.data = lhs; 650 651 data.size = strlen(rhs); 652 data.data = rhs; 653 654 if (bitset(MF_INCLNULL, map->map_mflags)) 655 { 656 key.size++; 657 data.size++; 658 } 659 660 stat = db->put(db, &key, &data, R_NOOVERWRITE); 661 if (stat > 0) 662 { 663 usrerr("050 Warning: duplicate alias name %s", lhs); 664 stat = db->put(db, &key, &data, 0); 665 } 666 if (stat != 0) 667 syserr("readaliases: db put (%s)", lhs); 668 } 669 670 671 /* 672 ** DB_MAP_CLOSE -- add distinguished entries and close the database 673 */ 674 675 void 676 db_map_close(map) 677 MAP *map; 678 { 679 register DB *db = map->map_db2; 680 681 if (tTd(38, 9)) 682 printf("db_map_close(%s, %x)\n", map->map_file, map->map_mflags); 683 684 if (bitset(MF_WRITABLE, map->map_mflags)) 685 { 686 /* write out the distinguished alias */ 687 db_map_store(map, "@", "@"); 688 } 689 690 if (db->close(db) != 0) 691 syserr("readaliases: db close failure"); 692 } 693 694 #endif 695 /* 696 ** NIS Modules 697 */ 698 699 # ifdef NIS 700 701 /* 702 ** NIS_MAP_OPEN -- open DBM map 703 */ 704 705 bool 706 nis_map_open(map, mode) 707 MAP *map; 708 int mode; 709 { 710 int yperr; 711 register char *p; 712 auto char *vp; 713 auto int vsize; 714 char *master; 715 716 if (tTd(38, 2)) 717 printf("nis_map_open(%s)\n", map->map_file); 718 719 if (mode != O_RDONLY) 720 { 721 errno = ENODEV; 722 return FALSE; 723 } 724 725 p = strchr(map->map_file, '@'); 726 if (p != NULL) 727 { 728 *p++ = '\0'; 729 if (*p != '\0') 730 map->map_domain = p; 731 } 732 733 if (map->map_domain == NULL) 734 yp_get_default_domain(&map->map_domain); 735 736 if (*map->map_file == '\0') 737 map->map_file = "mail.aliases"; 738 739 /* check to see if this map actually exists */ 740 yperr = yp_match(map->map_domain, map->map_file, "@", 1, 741 &vp, &vsize); 742 if (tTd(38, 10)) 743 printf("nis_map_open: yp_match(%s, %s) => %s\n", 744 map->map_domain, map->map_file, yperr_string(yperr)); 745 if (yperr == 0 || yperr == YPERR_KEY || yperr == YPERR_BUSY) 746 return TRUE; 747 748 if (!bitset(MF_OPTIONAL, map->map_mflags)) 749 syserr("Cannot bind to domain %s: %s", map->map_domain, 750 yperr_string(yperr)); 751 752 return FALSE; 753 } 754 755 756 /* 757 ** NIS_MAP_LOOKUP -- look up a datum in a NIS map 758 */ 759 760 char * 761 nis_map_lookup(map, name, av, statp) 762 MAP *map; 763 char *name; 764 char **av; 765 int *statp; 766 { 767 char *vp; 768 auto int vsize; 769 int buflen; 770 int yperr; 771 char keybuf[MAXNAME + 1]; 772 773 if (tTd(38, 20)) 774 printf("nis_map_lookup(%s)\n", name); 775 776 buflen = strlen(name); 777 if (buflen > sizeof keybuf - 1) 778 buflen = sizeof keybuf - 1; 779 bcopy(name, keybuf, buflen + 1); 780 if (!bitset(MF_NOFOLDCASE, map->map_mflags)) 781 makelower(keybuf); 782 if (bitset(MF_INCLNULL, map->map_mflags)) 783 buflen++; 784 yperr = yp_match(map->map_domain, map->map_file, keybuf, buflen, 785 &vp, &vsize); 786 if (yperr != 0) 787 { 788 if (yperr != YPERR_KEY && yperr != YPERR_BUSY) 789 map->map_mflags &= ~(MF_VALID|MF_OPEN); 790 return NULL; 791 } 792 if (bitset(MF_MATCHONLY, map->map_mflags)) 793 av = NULL; 794 return map_rewrite(map, vp, vsize, av); 795 } 796 797 798 /* 799 ** NIS_MAP_STORE 800 */ 801 802 void 803 nis_map_store(map, lhs, rhs) 804 MAP *map; 805 char *lhs; 806 char *rhs; 807 { 808 /* nothing */ 809 } 810 811 812 /* 813 ** NIS_MAP_CLOSE 814 */ 815 816 void 817 nis_map_close(map) 818 MAP *map; 819 { 820 /* nothing */ 821 } 822 823 #endif /* NIS */ 824 /* 825 ** STAB (Symbol Table) Modules 826 */ 827 828 829 /* 830 ** STAB_MAP_LOOKUP -- look up alias in symbol table 831 */ 832 833 char * 834 stab_map_lookup(map, name) 835 register MAP *map; 836 char *name; 837 { 838 register STAB *s; 839 840 if (tTd(38, 20)) 841 printf("stab_lookup(%s)\n", name); 842 843 s = stab(name, ST_ALIAS, ST_FIND); 844 if (s != NULL) 845 return (s->s_alias); 846 return (NULL); 847 } 848 849 850 /* 851 ** STAB_MAP_STORE -- store in symtab (actually using during init, not rebuild) 852 */ 853 854 void 855 stab_map_store(map, lhs, rhs) 856 register MAP *map; 857 char *lhs; 858 char *rhs; 859 { 860 register STAB *s; 861 862 s = stab(lhs, ST_ALIAS, ST_ENTER); 863 s->s_alias = newstr(rhs); 864 } 865 866 867 /* 868 ** STAB_MAP_OPEN -- initialize (reads data file) 869 ** 870 ** This is a wierd case -- it is only intended as a fallback for 871 ** aliases. For this reason, opens for write (only during a 872 ** "newaliases") always fails, and opens for read open the 873 ** actual underlying text file instead of the database. 874 */ 875 876 bool 877 stab_map_open(map, mode) 878 register MAP *map; 879 int mode; 880 { 881 FILE *af; 882 883 if (tTd(38, 2)) 884 printf("stab_map_open(%s)\n", map->map_file); 885 886 if (mode != O_RDONLY) 887 { 888 errno = ENODEV; 889 return FALSE; 890 } 891 892 return TRUE; 893 } 894 895 896 /* 897 ** STAB_MAP_CLOSE -- close symbol table (???) 898 */ 899 900 void 901 stab_map_close(map) 902 MAP *map; 903 { 904 /* ignore it */ 905 } 906 /* 907 ** Implicit Modules 908 ** 909 ** Tries several types. For back compatibility of aliases. 910 */ 911 912 913 /* 914 ** IMPL_MAP_LOOKUP -- lookup in best open database 915 */ 916 917 char * 918 impl_map_lookup(map, name, av, pstat) 919 MAP *map; 920 char *name; 921 char **av; 922 int *pstat; 923 { 924 if (tTd(38, 20)) 925 printf("impl_map_lookup(%s)\n", name); 926 927 #ifdef NEWDB 928 if (bitset(MF_IMPL_HASH, map->map_mflags)) 929 return db_map_lookup(map, name, av, pstat); 930 #endif 931 #ifdef NDBM 932 if (bitset(MF_IMPL_NDBM, map->map_mflags)) 933 return ndbm_map_lookup(map, name, av, pstat); 934 #endif 935 return stab_map_lookup(map, name, av, pstat); 936 } 937 938 /* 939 ** IMPL_MAP_STORE -- store in open databases 940 */ 941 942 void 943 impl_map_store(map, lhs, rhs) 944 MAP *map; 945 char *lhs; 946 char *rhs; 947 { 948 #ifdef NEWDB 949 if (bitset(MF_IMPL_HASH, map->map_mflags)) 950 db_map_store(map, lhs, rhs); 951 #endif 952 #ifdef NDBM 953 if (bitset(MF_IMPL_NDBM, map->map_mflags)) 954 ndbm_map_store(map, lhs, rhs); 955 #endif 956 stab_map_store(map, lhs, rhs); 957 } 958 959 /* 960 ** IMPL_MAP_OPEN -- implicit database open 961 */ 962 963 bool 964 impl_map_open(map, mode) 965 MAP *map; 966 int mode; 967 { 968 struct stat stb; 969 970 if (tTd(38, 2)) 971 printf("impl_map_open(%s)\n", map->map_file); 972 973 if (stat(map->map_file, &stb) < 0) 974 { 975 /* no alias file at all */ 976 return FALSE; 977 } 978 979 #ifdef NEWDB 980 map->map_mflags |= MF_IMPL_HASH; 981 if (hash_map_open(map, mode)) 982 { 983 #if defined(NDBM) && defined(YPCOMPAT) 984 if (mode == O_RDONLY || access("/var/yp/Makefile", R_OK) == 0) 985 #endif 986 return TRUE; 987 } 988 else 989 map->map_mflags &= ~MF_IMPL_HASH; 990 #endif 991 #ifdef NDBM 992 map->map_mflags |= MF_IMPL_NDBM; 993 if (ndbm_map_open(map, mode)) 994 { 995 return TRUE; 996 } 997 else 998 map->map_mflags &= ~MF_IMPL_NDBM; 999 #endif 1000 1001 #if !defined(NEWDB) && !defined(NDBM) 1002 if (Verbose) 1003 message("WARNING: cannot open alias database %s", map->map_file); 1004 #endif 1005 1006 return stab_map_open(map, mode); 1007 } 1008 1009 1010 /* 1011 ** IMPL_MAP_CLOSE -- close any open database(s) 1012 */ 1013 1014 void 1015 impl_map_close(map) 1016 MAP *map; 1017 { 1018 #ifdef NEWDB 1019 if (bitset(MF_IMPL_HASH, map->map_mflags)) 1020 { 1021 db_map_close(map); 1022 map->map_mflags &= ~MF_IMPL_HASH; 1023 } 1024 #endif 1025 1026 #ifdef NDBM 1027 if (bitset(MF_IMPL_NDBM, map->map_mflags)) 1028 { 1029 ndbm_map_close(map); 1030 map->map_mflags &= ~MF_IMPL_NDBM; 1031 } 1032 #endif 1033 } 1034 /* 1035 ** NULL stubs 1036 */ 1037 1038 bool 1039 null_map_open(map, mode) 1040 MAP *map; 1041 int mode; 1042 { 1043 return TRUE; 1044 } 1045 1046 void 1047 null_map_close(map) 1048 MAP *map; 1049 { 1050 return; 1051 } 1052 1053 void 1054 null_map_store(map, key, val) 1055 MAP *map; 1056 char *key; 1057 char *val; 1058 { 1059 return; 1060 } 1061