156822Seric /* 256822Seric * Copyright (c) 1992 Eric P. Allman. 356822Seric * Copyright (c) 1992 Regents of the University of California. 456822Seric * All rights reserved. 556822Seric * 656822Seric * %sccs.include.redist.c% 756822Seric */ 856822Seric 956822Seric #ifndef lint 10*60422Seric static char sccsid[] = "@(#)map.c 6.20 (Berkeley) 05/25/93"; 1156822Seric #endif /* not lint */ 1256822Seric 1356822Seric #include "sendmail.h" 1456822Seric 1560089Seric #ifdef NDBM 1656822Seric #include <ndbm.h> 1756822Seric #endif 1860089Seric #ifdef NEWDB 1956822Seric #include <db.h> 2056822Seric #endif 2160089Seric #ifdef NIS 2257208Seric #include <rpcsvc/ypclnt.h> 2357208Seric #endif 2456822Seric 2556822Seric /* 2660089Seric ** MAP.C -- implementations for various map classes. 2756822Seric ** 2860089Seric ** Each map class implements a series of functions: 2960089Seric ** 3060089Seric ** bool map_parse(MAP *map, char *args) 3160089Seric ** Parse the arguments from the config file. Return TRUE 3260089Seric ** if they were ok, FALSE otherwise. Fill in map with the 3360089Seric ** values. 3460089Seric ** 3560222Seric ** char *map_lookup(MAP *map, char *key, char **args, int *pstat) 3660222Seric ** Look up the key in the given map. If found, do any 3760222Seric ** rewriting the map wants (including "args" if desired) 3860089Seric ** and return the value. Set *pstat to the appropriate status 3960222Seric ** on error and return NULL. Args will be NULL if called 4060222Seric ** from the alias routines, although this should probably 4160222Seric ** not be relied upon. It is suggested you call map_rewrite 4260222Seric ** to return the results -- it takes care of null termination 4360222Seric ** and uses a dynamically expanded buffer as needed. 4460089Seric ** 4560089Seric ** void map_store(MAP *map, char *key, char *value) 4660089Seric ** Store the key:value pair in the map. 4760089Seric ** 4860089Seric ** bool map_open(MAP *map, int mode) 4960222Seric ** Open the map for the indicated mode. Mode should 5060222Seric ** be either O_RDONLY or O_RDWR. Return TRUE if it 5160222Seric ** was opened successfully, FALSE otherwise. If the open 5260222Seric ** failed an the MF_OPTIONAL flag is not set, it should 5360222Seric ** also print an error. If the MF_ALIAS bit is set 5460222Seric ** and this map class understands the @:@ convention, it 5560222Seric ** should call aliaswait() before returning. 5660089Seric ** 5760089Seric ** void map_close(MAP *map) 5860089Seric ** Close the map. 5960089Seric */ 6060089Seric 6160089Seric #define DBMMODE 0644 6260089Seric /* 6360089Seric ** MAP_PARSEARGS -- parse config line arguments for database lookup 6460089Seric ** 6560089Seric ** This is a generic version of the map_parse method. 6660089Seric ** 6756822Seric ** Parameters: 6860089Seric ** map -- the map being initialized. 6960089Seric ** ap -- a pointer to the args on the config line. 7056822Seric ** 7156822Seric ** Returns: 7260089Seric ** TRUE -- if everything parsed OK. 7356822Seric ** FALSE -- otherwise. 7456822Seric ** 7556822Seric ** Side Effects: 7660089Seric ** null terminates the filename; stores it in map 7756822Seric */ 7856822Seric 7956822Seric bool 8060089Seric map_parseargs(map, ap) 8156822Seric MAP *map; 8260089Seric char *ap; 8356822Seric { 8460089Seric register char *p = ap; 8556822Seric 8660089Seric for (;;) 8760089Seric { 8860089Seric while (isascii(*p) && isspace(*p)) 8960089Seric p++; 9060089Seric if (*p != '-') 9160089Seric break; 9260089Seric switch (*++p) 9360089Seric { 9460089Seric case 'N': 9560207Seric map->map_mflags |= MF_INCLNULL; 9660089Seric break; 9760089Seric 9860089Seric case 'o': 9960207Seric map->map_mflags |= MF_OPTIONAL; 10060089Seric break; 10160089Seric 10260089Seric case 'f': 10360207Seric map->map_mflags |= MF_NOFOLDCASE; 10460089Seric break; 10560089Seric 10660089Seric case 'm': 10760207Seric map->map_mflags |= MF_MATCHONLY; 10860089Seric break; 10960089Seric 11060089Seric case 'a': 11160089Seric map->map_app = ++p; 11260089Seric break; 11360089Seric } 11460089Seric while (*p != '\0' && !(isascii(*p) && isspace(*p))) 11560089Seric p++; 11660089Seric if (*p != '\0') 11760089Seric *p++ = '\0'; 11860089Seric } 11960089Seric if (map->map_app != NULL) 12060089Seric map->map_app = newstr(map->map_app); 12160089Seric 12260089Seric if (*p != '\0') 12360089Seric { 12460089Seric map->map_file = p; 12560089Seric while (*p != '\0' && !(isascii(*p) && isspace(*p))) 12660089Seric p++; 12760089Seric if (*p != '\0') 12860089Seric *p++ = '\0'; 12960089Seric map->map_file = newstr(map->map_file); 13060089Seric } 13160089Seric 13260089Seric while (*p != '\0' && isascii(*p) && isspace(*p)) 13360089Seric p++; 13460089Seric if (*p != '\0') 13560089Seric map->map_rebuild = newstr(p); 13660089Seric 13756822Seric if (map->map_file == NULL) 13857208Seric { 13960089Seric syserr("No file name for %s map %s", 14060089Seric map->map_class->map_cname, map->map_mname); 14156822Seric return FALSE; 14257208Seric } 14360089Seric return TRUE; 14460089Seric } 14560089Seric /* 14660089Seric ** MAP_REWRITE -- rewrite a database key, interpolating %n indications. 14760089Seric ** 14860089Seric ** It also adds the map_app string. It can be used as a utility 14960089Seric ** in the map_lookup method. 15060089Seric ** 15160089Seric ** Parameters: 15260089Seric ** map -- the map that causes this. 15360089Seric ** s -- the string to rewrite, NOT necessarily null terminated. 15460089Seric ** slen -- the length of s. 15560089Seric ** av -- arguments to interpolate into buf. 15660089Seric ** 15760089Seric ** Returns: 15860089Seric ** Pointer to rewritten result. 15960089Seric ** 16060089Seric ** Side Effects: 16160089Seric ** none. 16260089Seric */ 16360089Seric 16460089Seric char * 16560089Seric map_rewrite(map, s, slen, av) 16660089Seric register MAP *map; 16760089Seric register char *s; 16860089Seric int slen; 16960089Seric char **av; 17060089Seric { 17160089Seric register char *bp; 17260089Seric register char c; 17360089Seric char **avp; 17460089Seric register char *ap; 17560089Seric int i; 17660089Seric int len; 17760089Seric static int buflen = -1; 17860089Seric static char *buf = NULL; 17960089Seric 18060089Seric if (tTd(23, 1)) 18160089Seric { 18260256Seric printf("map_rewrite(%.*s), av =", slen, s); 18360256Seric if (av == NULL) 18460256Seric printf(" (nullv)"); 18560256Seric else 18660256Seric { 18760256Seric for (avp = av; *avp != NULL; avp++) 18860256Seric printf("\n\t%s", *avp); 18960256Seric } 19060256Seric printf("\n"); 19160089Seric } 19260089Seric 19360089Seric /* count expected size of output (can safely overestimate) */ 19460089Seric i = len = slen; 19560089Seric if (av != NULL) 19660089Seric { 19760089Seric bp = s; 19860089Seric for (i = slen; --i >= 0 && (c = *bp++) != 0; ) 19960089Seric { 20060089Seric if (c != '%') 20160089Seric continue; 20260089Seric if (--i < 0) 20360089Seric break; 20460089Seric c = *bp++; 20560089Seric if (!(isascii(c) && isdigit(c))) 20660089Seric continue; 20760089Seric c -= 0; 20860089Seric for (avp = av; --c >= 0 && *avp != NULL; avp++) 20960089Seric continue; 21060089Seric if (*avp == NULL) 21160089Seric continue; 21260089Seric len += strlen(*avp); 21360089Seric } 21460089Seric } 21560089Seric if (map->map_app != NULL) 21660089Seric len += strlen(map->map_app); 21760089Seric if (buflen < ++len) 21860089Seric { 21960089Seric /* need to malloc additional space */ 22060089Seric buflen = len; 22160089Seric if (buf != NULL) 22260089Seric free(buf); 22360089Seric buf = xalloc(buflen); 22460089Seric } 22560089Seric 22660089Seric bp = buf; 22760089Seric if (av == NULL) 22860089Seric { 22960089Seric bcopy(s, bp, slen); 23060089Seric bp += slen; 23160089Seric } 23260089Seric else 23360089Seric { 23460089Seric while (--slen >= 0 && (c = *s++) != '\0') 23560089Seric { 23660089Seric if (c != '%') 23760089Seric { 23860089Seric pushc: 23960089Seric *bp++ = c; 24060089Seric continue; 24160089Seric } 24260089Seric if (--slen < 0 || (c = *s++) == '\0') 24360089Seric c = '%'; 24460089Seric if (c == '%') 24560089Seric goto pushc; 24660089Seric if (!(isascii(c) && isdigit(c))) 24760089Seric { 24860089Seric *bp++ = '%'; 24960089Seric goto pushc; 25060089Seric } 25160089Seric c -= '0'; 25260089Seric for (avp = av; --c >= 0 && *avp != NULL; avp++) 25360089Seric continue; 25460089Seric if (*avp == NULL) 25560089Seric continue; 25660089Seric 25760089Seric /* transliterate argument into output string */ 25860089Seric for (ap = *avp; (c = *ap++) != '\0'; ) 25960089Seric *bp++ = c; 26060089Seric } 26160089Seric } 26260089Seric if (map->map_app != NULL) 26360089Seric strcpy(bp, map->map_app); 26460089Seric else 26560089Seric *bp = '\0'; 26660089Seric if (tTd(23, 1)) 26760089Seric printf("map_rewrite => %s\n", buf); 26860089Seric return buf; 26960089Seric } 27060089Seric /* 27160089Seric ** NDBM modules 27260089Seric */ 27360089Seric 27460089Seric #ifdef NDBM 27560089Seric 27660089Seric /* 27760089Seric ** DBM_MAP_OPEN -- DBM-style map open 27860089Seric */ 27960089Seric 28060089Seric bool 28160089Seric ndbm_map_open(map, mode) 28260089Seric MAP *map; 28360089Seric int mode; 28460089Seric { 28560089Seric DBM *dbm; 28660089Seric 28760089Seric if (tTd(27, 2)) 28860089Seric printf("ndbm_map_open(%s, %d)\n", map->map_file, mode); 28960089Seric 29060207Seric if (mode == O_RDWR) 29160207Seric mode |= O_CREAT|O_TRUNC; 29260207Seric 29360089Seric /* open the database */ 29460089Seric dbm = dbm_open(map->map_file, mode, DBMMODE); 29556822Seric if (dbm == NULL) 29656822Seric { 29760207Seric if (!bitset(MF_OPTIONAL, map->map_mflags)) 29856836Seric syserr("Cannot open DBM database %s", map->map_file); 29956822Seric return FALSE; 30056822Seric } 30160089Seric map->map_db1 = (void *) dbm; 30260207Seric if (mode == O_RDONLY && bitset(MF_ALIAS, map->map_mflags)) 30360207Seric aliaswait(map, ".dir"); 30456822Seric return TRUE; 30556822Seric } 30660089Seric 30760089Seric 30860089Seric /* 30956822Seric ** DBM_MAP_LOOKUP -- look up a datum in a DBM-type map 31056822Seric */ 31156822Seric 31256822Seric char * 31360089Seric ndbm_map_lookup(map, name, av, statp) 31456822Seric MAP *map; 31560089Seric char *name; 31656822Seric char **av; 31759084Seric int *statp; 31856822Seric { 31956822Seric datum key, val; 32060089Seric char keybuf[MAXNAME + 1]; 32156822Seric 32260089Seric if (tTd(27, 20)) 32360089Seric printf("ndbm_map_lookup(%s)\n", name); 32460089Seric 32560089Seric key.dptr = name; 32660089Seric key.dsize = strlen(name); 32760207Seric if (!bitset(MF_NOFOLDCASE, map->map_mflags)) 32857014Seric { 32960089Seric if (key.dsize > sizeof keybuf - 1) 33060089Seric key.dsize = sizeof keybuf - 1; 33160089Seric bcopy(key.dptr, keybuf, key.dsize + 1); 33260089Seric makelower(keybuf); 33360089Seric key.dptr = keybuf; 33457014Seric } 33560207Seric if (bitset(MF_INCLNULL, map->map_mflags)) 33656822Seric key.dsize++; 33760089Seric (void) lockfile(dbm_dirfno((DBM *) map->map_db1), map->map_file, LOCK_SH); 33860089Seric val = dbm_fetch((DBM *) map->map_db1, key); 33960089Seric (void) lockfile(dbm_dirfno((DBM *) map->map_db1), map->map_file, LOCK_UN); 34056822Seric if (val.dptr == NULL) 34156822Seric return NULL; 34260207Seric if (bitset(MF_MATCHONLY, map->map_mflags)) 34360089Seric av = NULL; 34460089Seric return map_rewrite(map, val.dptr, val.dsize, av); 34556822Seric } 34656822Seric 34756822Seric 34856822Seric /* 34960089Seric ** DBM_MAP_STORE -- store a datum in the database 35056822Seric */ 35156822Seric 35260089Seric void 35360089Seric ndbm_map_store(map, lhs, rhs) 35460089Seric register MAP *map; 35560089Seric char *lhs; 35660089Seric char *rhs; 35760089Seric { 35860089Seric datum key; 35960089Seric datum data; 36060089Seric int stat; 36160089Seric 36260089Seric if (tTd(27, 12)) 36360089Seric printf("ndbm_map_store(%s, %s)\n", lhs, rhs); 36460089Seric 36560089Seric key.dsize = strlen(lhs); 36660089Seric key.dptr = lhs; 36760089Seric 36860089Seric data.dsize = strlen(rhs); 36960089Seric data.dptr = rhs; 37060089Seric 37160207Seric if (bitset(MF_INCLNULL, map->map_mflags)) 37260089Seric { 37360089Seric key.dsize++; 37460089Seric data.dsize++; 37560089Seric } 37660089Seric 37760089Seric stat = dbm_store((DBM *) map->map_db1, key, data, DBM_INSERT); 37860089Seric if (stat > 0) 37960089Seric { 38060089Seric usrerr("050 Warning: duplicate alias name %s", lhs); 38160089Seric stat = dbm_store((DBM *) map->map_db1, key, data, DBM_REPLACE); 38260089Seric } 38360089Seric if (stat != 0) 38460089Seric syserr("readaliases: dbm put (%s)", lhs); 38560089Seric } 38660089Seric 38760089Seric 38860089Seric /* 38960207Seric ** NDBM_MAP_CLOSE -- close the database 39060089Seric */ 39160089Seric 39260089Seric void 39360089Seric ndbm_map_close(map) 39460089Seric register MAP *map; 39560089Seric { 39660207Seric if (bitset(MF_WRITABLE, map->map_mflags)) 39760089Seric { 39860089Seric #ifdef YPCOMPAT 39960089Seric char buf[200]; 40060089Seric 40160089Seric (void) sprintf(buf, "%010ld", curtime()); 40260089Seric ndbm_map_store(map, "YP_LAST_MODIFIED", buf); 40360089Seric 40460089Seric (void) myhostname(buf, sizeof buf); 40560089Seric ndbm_map_store(map, "YP_MASTER_NAME", buf); 40660089Seric #endif 40760089Seric 40860089Seric /* write out the distinguished alias */ 40960089Seric ndbm_map_store(map, "@", "@"); 41060089Seric } 41160089Seric dbm_close((DBM *) map->map_db1); 41260089Seric } 41360089Seric 41460089Seric #endif 41560089Seric /* 41660089Seric ** HASH (NEWDB) Modules 41760089Seric */ 41860089Seric 41960089Seric #ifdef NEWDB 42060089Seric 42160089Seric /* 42260089Seric ** BTREE_MAP_PARSE -- BTREE-style map initialization 42360089Seric */ 42460089Seric 42556822Seric bool 42660089Seric bt_map_open(map, mode) 42756822Seric MAP *map; 42860089Seric int mode; 42956822Seric { 43056822Seric DB *db; 43160228Seric int i; 43260089Seric char buf[MAXNAME]; 43356822Seric 43460089Seric if (tTd(27, 2)) 43560089Seric printf("bt_map_open(%s, %d)\n", map->map_file, mode); 43660089Seric 43760207Seric if (mode == O_RDWR) 43860207Seric mode |= O_CREAT|O_TRUNC; 43960207Seric 44060228Seric (void) strcpy(buf, map->map_file); 44160228Seric i = strlen(buf); 44260228Seric if (i < 3 || strcmp(&buf[i - 3], ".db") != 0) 44360228Seric (void) strcat(buf, ".db"); 44460222Seric db = dbopen(buf, mode, DBMMODE, DB_BTREE, NULL); 44556822Seric if (db == NULL) 44656822Seric { 44760207Seric if (!bitset(MF_OPTIONAL, map->map_mflags)) 44856836Seric syserr("Cannot open BTREE database %s", map->map_file); 44956822Seric return FALSE; 45056822Seric } 45160089Seric map->map_db2 = (void *) db; 45260207Seric if (mode == O_RDONLY && bitset(MF_ALIAS, map->map_mflags)) 45360207Seric aliaswait(map, ".db"); 45456822Seric return TRUE; 45556822Seric } 45656822Seric 45756822Seric 45856822Seric /* 45956822Seric ** HASH_MAP_INIT -- HASH-style map initialization 46056822Seric */ 46156822Seric 46256822Seric bool 46360089Seric hash_map_open(map, mode) 46456822Seric MAP *map; 46560089Seric int mode; 46656822Seric { 46756822Seric DB *db; 46860228Seric int i; 46960089Seric char buf[MAXNAME]; 47056822Seric 47160089Seric if (tTd(27, 2)) 47260089Seric printf("hash_map_open(%s, %d)\n", map->map_file, mode); 47360089Seric 47460207Seric if (mode == O_RDWR) 47560207Seric mode |= O_CREAT|O_TRUNC; 47660207Seric 47760228Seric (void) strcpy(buf, map->map_file); 47860228Seric i = strlen(buf); 47960228Seric if (i < 3 || strcmp(&buf[i - 3], ".db") != 0) 48060228Seric (void) strcat(buf, ".db"); 48160222Seric db = dbopen(buf, mode, DBMMODE, DB_HASH, NULL); 48256822Seric if (db == NULL) 48356822Seric { 48460207Seric if (!bitset(MF_OPTIONAL, map->map_mflags)) 48556836Seric syserr("Cannot open HASH database %s", map->map_file); 48656822Seric return FALSE; 48756822Seric } 48860089Seric map->map_db2 = (void *) db; 48960207Seric if (mode == O_RDONLY && bitset(MF_ALIAS, map->map_mflags)) 49060207Seric aliaswait(map, ".db"); 49156822Seric return TRUE; 49256822Seric } 49356822Seric 49456822Seric 49556822Seric /* 49656822Seric ** DB_MAP_LOOKUP -- look up a datum in a BTREE- or HASH-type map 49756822Seric */ 49856822Seric 49956822Seric char * 50060089Seric db_map_lookup(map, name, av, statp) 50156822Seric MAP *map; 50260089Seric char *name; 50356822Seric char **av; 50459084Seric int *statp; 50556822Seric { 50656822Seric DBT key, val; 507*60422Seric register DB *db = (DB *) map->map_db2; 508*60422Seric int st; 509*60422Seric int saveerrno; 51060089Seric char keybuf[MAXNAME + 1]; 51156822Seric 51260089Seric if (tTd(27, 20)) 51360089Seric printf("db_map_lookup(%s)\n", name); 51460089Seric 51560089Seric key.size = strlen(name); 51660089Seric if (key.size > sizeof keybuf - 1) 51760089Seric key.size = sizeof keybuf - 1; 51860089Seric key.data = keybuf; 51960089Seric bcopy(name, keybuf, key.size + 1); 52060207Seric if (!bitset(MF_NOFOLDCASE, map->map_mflags)) 52160089Seric makelower(keybuf); 52260207Seric if (bitset(MF_INCLNULL, map->map_mflags)) 52356822Seric key.size++; 524*60422Seric #ifndef OLD_NEWDB 525*60422Seric (void) lockfile(db->fd(db), map->map_file, LOCK_SH); 526*60422Seric #endif 527*60422Seric st = db->get(db, &key, &val, 0); 528*60422Seric saveerrno = errno; 529*60422Seric #ifndef OLD_NEWDB 530*60422Seric (void) lockfile(db->fd(db), map->map_file, LOCK_UN); 531*60422Seric #endif 532*60422Seric if (st != 0) 533*60422Seric { 534*60422Seric errno = saveerrno; 535*60422Seric if (st < 0) 536*60422Seric syserr("db_map_lookup: get (%s)", name); 53756822Seric return NULL; 538*60422Seric } 53960207Seric if (bitset(MF_MATCHONLY, map->map_mflags)) 54060089Seric av = NULL; 54160089Seric return map_rewrite(map, val.data, val.size, av); 54256822Seric } 54356822Seric 54460089Seric 54560089Seric /* 54660089Seric ** DB_MAP_STORE -- store a datum in the NEWDB database 54756822Seric */ 54856822Seric 54960089Seric void 55060089Seric db_map_store(map, lhs, rhs) 55160089Seric register MAP *map; 55260089Seric char *lhs; 55360089Seric char *rhs; 55456822Seric { 55560089Seric int stat; 55660089Seric DBT key; 55760089Seric DBT data; 55860089Seric register DB *db = map->map_db2; 55956822Seric 56060089Seric if (tTd(27, 20)) 56160089Seric printf("db_map_store(%s, %s)\n", lhs, rhs); 56260089Seric 56360089Seric key.size = strlen(lhs); 56460089Seric key.data = lhs; 56560089Seric 56660089Seric data.size = strlen(rhs); 56760089Seric data.data = rhs; 56860089Seric 56960207Seric if (bitset(MF_INCLNULL, map->map_mflags)) 57056822Seric { 57160089Seric key.size++; 57260089Seric data.size++; 57360089Seric } 57456836Seric 57560089Seric stat = db->put(db, &key, &data, R_NOOVERWRITE); 57660089Seric if (stat > 0) 57760089Seric { 57860089Seric usrerr("050 Warning: duplicate alias name %s", lhs); 57960089Seric stat = db->put(db, &key, &data, 0); 58060089Seric } 58160089Seric if (stat != 0) 58260089Seric syserr("readaliases: db put (%s)", lhs); 58360089Seric } 58456836Seric 58556847Seric 58660089Seric /* 58760089Seric ** DB_MAP_CLOSE -- add distinguished entries and close the database 58860089Seric */ 58960089Seric 59060089Seric void 59160089Seric db_map_close(map) 59260089Seric MAP *map; 59360089Seric { 59460089Seric register DB *db = map->map_db2; 59560089Seric 59660089Seric if (tTd(27, 9)) 59760207Seric printf("db_map_close(%s, %x)\n", map->map_file, map->map_mflags); 59860089Seric 59960207Seric if (bitset(MF_WRITABLE, map->map_mflags)) 60058804Seric { 60160089Seric /* write out the distinguished alias */ 60260089Seric db_map_store(map, "@", "@"); 60358804Seric } 60458963Seric 60560089Seric if (db->close(db) != 0) 60660089Seric syserr("readaliases: db close failure"); 60756822Seric } 60857208Seric 60960089Seric #endif 61060089Seric /* 61160089Seric ** NIS Modules 61260089Seric */ 61360089Seric 61460089Seric # ifdef NIS 61560089Seric 61657208Seric /* 61760089Seric ** NIS_MAP_OPEN -- open DBM map 61857208Seric */ 61957208Seric 62057208Seric bool 62160089Seric nis_map_open(map, mode) 62257208Seric MAP *map; 62360089Seric int mode; 62457208Seric { 62557216Seric int yperr; 62660215Seric register char *p; 62760215Seric auto char *vp; 62860215Seric auto int vsize; 62957216Seric char *master; 63057216Seric 63160089Seric if (tTd(27, 2)) 63260089Seric printf("nis_map_open(%s)\n", map->map_file); 63360089Seric 63460207Seric if (mode != O_RDONLY) 63560207Seric { 63660207Seric errno = ENODEV; 63760207Seric return FALSE; 63860207Seric } 63960207Seric 64060089Seric p = strchr(map->map_file, '@'); 64160089Seric if (p != NULL) 64260089Seric { 64360089Seric *p++ = '\0'; 64460089Seric if (*p != '\0') 64560089Seric map->map_domain = p; 64660089Seric } 64760215Seric 64860089Seric if (map->map_domain == NULL) 64960089Seric yp_get_default_domain(&map->map_domain); 65060089Seric 65160089Seric if (*map->map_file == '\0') 65260089Seric map->map_file = "mail.aliases"; 65360089Seric 65460215Seric /* check to see if this map actually exists */ 65560089Seric yperr = yp_match(map->map_domain, map->map_file, "@", 1, 65660089Seric &vp, &vsize); 65760089Seric if (tTd(27, 10)) 65860089Seric printf("nis_map_open: yp_match(%s, %s) => %s\n", 65960089Seric map->map_domain, map->map_file, yperr_string(yperr)); 66060089Seric if (yperr == 0 || yperr == YPERR_KEY || yperr == YPERR_BUSY) 66160089Seric return TRUE; 66260215Seric 66360215Seric if (!bitset(MF_OPTIONAL, map->map_mflags)) 66460215Seric syserr("Cannot bind to domain %s: %s", map->map_domain, 66560215Seric yperr_string(yperr)); 66660215Seric 66760089Seric return FALSE; 66860089Seric } 66960089Seric 67060089Seric 67160089Seric /* 67257208Seric ** NIS_MAP_LOOKUP -- look up a datum in a NIS map 67357208Seric */ 67457208Seric 67557208Seric char * 67660089Seric nis_map_lookup(map, name, av, statp) 67757208Seric MAP *map; 67860089Seric char *name; 67957208Seric char **av; 68059084Seric int *statp; 68157208Seric { 68257208Seric char *vp; 68357642Seric auto int vsize; 68459274Seric int buflen; 68560215Seric int yperr; 68660089Seric char keybuf[MAXNAME + 1]; 68757208Seric 68860089Seric if (tTd(27, 20)) 68960089Seric printf("nis_map_lookup(%s)\n", name); 69060089Seric 69160089Seric buflen = strlen(name); 69260089Seric if (buflen > sizeof keybuf - 1) 69360089Seric buflen = sizeof keybuf - 1; 69460089Seric bcopy(name, keybuf, buflen + 1); 69560207Seric if (!bitset(MF_NOFOLDCASE, map->map_mflags)) 69660089Seric makelower(keybuf); 69760207Seric if (bitset(MF_INCLNULL, map->map_mflags)) 69859274Seric buflen++; 69960089Seric yperr = yp_match(map->map_domain, map->map_file, keybuf, buflen, 70060089Seric &vp, &vsize); 70160089Seric if (yperr != 0) 70260089Seric { 70360089Seric if (yperr != YPERR_KEY && yperr != YPERR_BUSY) 70460215Seric map->map_mflags &= ~(MF_VALID|MF_OPEN); 70557208Seric return NULL; 70660089Seric } 70760207Seric if (bitset(MF_MATCHONLY, map->map_mflags)) 70860089Seric av = NULL; 70960215Seric return map_rewrite(map, vp, vsize, av); 71057208Seric } 71157208Seric 71260089Seric 71360089Seric /* 71460207Seric ** NIS_MAP_STORE 71560089Seric */ 71660089Seric 71760089Seric void 71860089Seric nis_map_store(map, lhs, rhs) 71960089Seric MAP *map; 72060089Seric char *lhs; 72160089Seric char *rhs; 72260089Seric { 72360089Seric /* nothing */ 72460089Seric } 72560089Seric 72660089Seric 72760089Seric /* 72860207Seric ** NIS_MAP_CLOSE 72960089Seric */ 73060089Seric 73160089Seric void 73260089Seric nis_map_close(map) 73360089Seric MAP *map; 73460089Seric { 73560089Seric /* nothing */ 73660089Seric } 73760089Seric 73860089Seric #endif /* NIS */ 73957208Seric /* 74060089Seric ** STAB (Symbol Table) Modules 74160089Seric */ 74260089Seric 74360089Seric 74460089Seric /* 74560207Seric ** STAB_MAP_LOOKUP -- look up alias in symbol table 74660089Seric */ 74760089Seric 74860089Seric char * 74960089Seric stab_map_lookup(map, name) 75060089Seric register MAP *map; 75160089Seric char *name; 75260089Seric { 75360089Seric register STAB *s; 75460089Seric 75560089Seric if (tTd(27, 20)) 75660089Seric printf("stab_lookup(%s)\n", name); 75760089Seric 75860089Seric s = stab(name, ST_ALIAS, ST_FIND); 75960089Seric if (s != NULL) 76060089Seric return (s->s_alias); 76160089Seric return (NULL); 76260089Seric } 76360089Seric 76460089Seric 76560089Seric /* 76660207Seric ** STAB_MAP_STORE -- store in symtab (actually using during init, not rebuild) 76760089Seric */ 76860089Seric 76960089Seric void 77060089Seric stab_map_store(map, lhs, rhs) 77160089Seric register MAP *map; 77260089Seric char *lhs; 77360089Seric char *rhs; 77460089Seric { 77560089Seric register STAB *s; 77660089Seric 77760089Seric s = stab(lhs, ST_ALIAS, ST_ENTER); 77860089Seric s->s_alias = newstr(rhs); 77960089Seric } 78060089Seric 78160089Seric 78260089Seric /* 78360207Seric ** STAB_MAP_OPEN -- initialize (reads data file) 78460207Seric ** 78560207Seric ** This is a wierd case -- it is only intended as a fallback for 78660207Seric ** aliases. For this reason, opens for write (only during a 78760207Seric ** "newaliases") always fails, and opens for read open the 78860207Seric ** actual underlying text file instead of the database. 78960089Seric */ 79060089Seric 79160089Seric bool 79260089Seric stab_map_open(map, mode) 79360089Seric register MAP *map; 79460089Seric int mode; 79560089Seric { 79660089Seric FILE *af; 79760089Seric 79860089Seric if (tTd(27, 2)) 79960089Seric printf("stab_map_open(%s)\n", map->map_file); 80060089Seric 80160089Seric if (mode != O_RDONLY) 80260207Seric { 80360207Seric errno = ENODEV; 80460089Seric return FALSE; 80560207Seric } 80660089Seric 80760089Seric return TRUE; 80860089Seric } 80960089Seric 81060089Seric 81160089Seric /* 81260207Seric ** STAB_MAP_CLOSE -- close symbol table (???) 81360089Seric */ 81460089Seric 81560089Seric void 81660089Seric stab_map_close(map) 81760089Seric MAP *map; 81860089Seric { 81960089Seric /* ignore it */ 82060089Seric } 82160089Seric /* 82260089Seric ** Implicit Modules 82356822Seric ** 82460089Seric ** Tries several types. For back compatibility of aliases. 82556822Seric */ 82656822Seric 82760089Seric 82860089Seric /* 82960207Seric ** IMPL_MAP_LOOKUP -- lookup in best open database 83060089Seric */ 83160089Seric 83260089Seric char * 83360089Seric impl_map_lookup(map, name, av, pstat) 83460089Seric MAP *map; 83560089Seric char *name; 83656822Seric char **av; 83760089Seric int *pstat; 83856822Seric { 83960089Seric if (tTd(27, 20)) 84060089Seric printf("impl_map_lookup(%s)\n", name); 84156822Seric 84260089Seric #ifdef NEWDB 84360207Seric if (bitset(MF_IMPL_HASH, map->map_mflags)) 84460089Seric return db_map_lookup(map, name, av, pstat); 84560089Seric #endif 84660089Seric #ifdef NDBM 84760207Seric if (bitset(MF_IMPL_NDBM, map->map_mflags)) 84860089Seric return ndbm_map_lookup(map, name, av, pstat); 84960089Seric #endif 85060089Seric return stab_map_lookup(map, name, av, pstat); 85160089Seric } 85260089Seric 85360089Seric /* 85460207Seric ** IMPL_MAP_STORE -- store in open databases 85560089Seric */ 85660089Seric 85760089Seric void 85860089Seric impl_map_store(map, lhs, rhs) 85960089Seric MAP *map; 86060089Seric char *lhs; 86160089Seric char *rhs; 86260089Seric { 86360089Seric #ifdef NEWDB 86460207Seric if (bitset(MF_IMPL_HASH, map->map_mflags)) 86560089Seric db_map_store(map, lhs, rhs); 86660089Seric #endif 86760089Seric #ifdef NDBM 86860207Seric if (bitset(MF_IMPL_NDBM, map->map_mflags)) 86960089Seric ndbm_map_store(map, lhs, rhs); 87060089Seric #endif 87160089Seric stab_map_store(map, lhs, rhs); 87260089Seric } 87360089Seric 87460089Seric /* 87560089Seric ** IMPL_MAP_OPEN -- implicit database open 87660089Seric */ 87760089Seric 87860089Seric bool 87960089Seric impl_map_open(map, mode) 88060089Seric MAP *map; 88160089Seric int mode; 88260089Seric { 88360089Seric struct stat stb; 88460089Seric 88560089Seric if (tTd(27, 2)) 88660089Seric printf("impl_map_open(%s)\n", map->map_file); 88760089Seric 88860089Seric if (stat(map->map_file, &stb) < 0) 88956822Seric { 89060089Seric /* no alias file at all */ 89160089Seric return FALSE; 89256822Seric } 89356822Seric 89460089Seric #ifdef NEWDB 89560207Seric map->map_mflags |= MF_IMPL_HASH; 89660089Seric if (hash_map_open(map, mode)) 89756822Seric { 89860207Seric #if defined(NDBM) && defined(YPCOMPAT) 89960207Seric if (mode == O_RDONLY || access("/var/yp/Makefile", R_OK) == 0) 90060207Seric #endif 90160207Seric return TRUE; 90260089Seric } 90360207Seric else 90460207Seric map->map_mflags &= ~MF_IMPL_HASH; 90560089Seric #endif 90660089Seric #ifdef NDBM 90760207Seric map->map_mflags |= MF_IMPL_NDBM; 90860089Seric if (ndbm_map_open(map, mode)) 90960089Seric { 91060089Seric return TRUE; 91160089Seric } 91260207Seric else 91360207Seric map->map_mflags &= ~MF_IMPL_NDBM; 91460089Seric #endif 91556822Seric 91660207Seric #if !defined(NEWDB) && !defined(NDBM) 91760089Seric if (Verbose) 91860089Seric message("WARNING: cannot open alias database %s", map->map_file); 91960207Seric #endif 92060089Seric 92160207Seric return stab_map_open(map, mode); 92256822Seric } 92360089Seric 92460207Seric 92560089Seric /* 92660207Seric ** IMPL_MAP_CLOSE -- close any open database(s) 92760089Seric */ 92860089Seric 92960089Seric void 93060207Seric impl_map_close(map) 93160089Seric MAP *map; 93260089Seric { 93360089Seric #ifdef NEWDB 93460207Seric if (bitset(MF_IMPL_HASH, map->map_mflags)) 93560089Seric { 93660207Seric db_map_close(map); 93760207Seric map->map_mflags &= ~MF_IMPL_HASH; 93860089Seric } 93960089Seric #endif 94060089Seric 94160089Seric #ifdef NDBM 94260207Seric if (bitset(MF_IMPL_NDBM, map->map_mflags)) 94360089Seric { 94460207Seric ndbm_map_close(map); 94560207Seric map->map_mflags &= ~MF_IMPL_NDBM; 94660089Seric } 94760089Seric #endif 94860089Seric } 94960207Seric /* 95060207Seric ** NULL stubs 95160089Seric */ 95260089Seric 95360207Seric bool 95460207Seric null_map_open(map, mode) 95560089Seric MAP *map; 95660207Seric int mode; 95760089Seric { 95860207Seric return TRUE; 95960089Seric } 96060089Seric 96160207Seric void 96260207Seric null_map_close(map) 96360207Seric MAP *map; 96460089Seric { 96560207Seric return; 96660207Seric } 96760089Seric 96860207Seric void 96960207Seric null_map_store(map, key, val) 97060207Seric MAP *map; 97160207Seric char *key; 97260207Seric char *val; 97360089Seric { 97460207Seric return; 97560089Seric } 976