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