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*60207Seric static char sccsid[] = "@(#)map.c 6.15 (Berkeley) 05/21/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 ** 3560089Seric ** char *map_lookup(MAP *map, char buf[], int bufsize, 3660089Seric ** char **args, int *pstat) 3760089Seric ** Look up the key given in buf in the given map. If found, 3860089Seric ** do any rewriting the map wants (including "args" if desired) 3960089Seric ** and return the value. Set *pstat to the appropriate status 4060089Seric ** on error and return NULL. 4160089Seric ** 4260089Seric ** void map_store(MAP *map, char *key, char *value) 4360089Seric ** Store the key:value pair in the map. 4460089Seric ** 4560089Seric ** bool map_open(MAP *map, int mode) 4660089Seric ** Open the map for the indicated mode. Return TRUE if it 4760089Seric ** was opened successfully, FALSE otherwise. 4860089Seric ** 4960089Seric ** void map_close(MAP *map) 5060089Seric ** Close the map. 5160089Seric */ 5260089Seric 5360089Seric #define DBMMODE 0644 5460089Seric /* 5560089Seric ** MAP_PARSEARGS -- parse config line arguments for database lookup 5660089Seric ** 5760089Seric ** This is a generic version of the map_parse method. 5860089Seric ** 5956822Seric ** Parameters: 6060089Seric ** map -- the map being initialized. 6160089Seric ** ap -- a pointer to the args on the config line. 6256822Seric ** 6356822Seric ** Returns: 6460089Seric ** TRUE -- if everything parsed OK. 6556822Seric ** FALSE -- otherwise. 6656822Seric ** 6756822Seric ** Side Effects: 6860089Seric ** null terminates the filename; stores it in map 6956822Seric */ 7056822Seric 7156822Seric bool 7260089Seric map_parseargs(map, ap) 7356822Seric MAP *map; 7460089Seric char *ap; 7556822Seric { 7660089Seric register char *p = ap; 7756822Seric 7860089Seric for (;;) 7960089Seric { 8060089Seric while (isascii(*p) && isspace(*p)) 8160089Seric p++; 8260089Seric if (*p != '-') 8360089Seric break; 8460089Seric switch (*++p) 8560089Seric { 8660089Seric case 'N': 87*60207Seric map->map_mflags |= MF_INCLNULL; 8860089Seric break; 8960089Seric 9060089Seric case 'o': 91*60207Seric map->map_mflags |= MF_OPTIONAL; 9260089Seric break; 9360089Seric 9460089Seric case 'f': 95*60207Seric map->map_mflags |= MF_NOFOLDCASE; 9660089Seric break; 9760089Seric 9860089Seric case 'm': 99*60207Seric map->map_mflags |= MF_MATCHONLY; 10060089Seric break; 10160089Seric 10260089Seric case 'a': 10360089Seric map->map_app = ++p; 10460089Seric break; 10560089Seric 10660089Seric case 'd': 10760089Seric map->map_domain = ++p; 10860089Seric break; 10960089Seric } 11060089Seric while (*p != '\0' && !(isascii(*p) && isspace(*p))) 11160089Seric p++; 11260089Seric if (*p != '\0') 11360089Seric *p++ = '\0'; 11460089Seric } 11560089Seric if (map->map_app != NULL) 11660089Seric map->map_app = newstr(map->map_app); 11760089Seric if (map->map_domain != NULL) 11860089Seric map->map_domain = newstr(map->map_domain); 11960089Seric 12060089Seric if (*p != '\0') 12160089Seric { 12260089Seric map->map_file = p; 12360089Seric while (*p != '\0' && !(isascii(*p) && isspace(*p))) 12460089Seric p++; 12560089Seric if (*p != '\0') 12660089Seric *p++ = '\0'; 12760089Seric map->map_file = newstr(map->map_file); 12860089Seric } 12960089Seric 13060089Seric while (*p != '\0' && isascii(*p) && isspace(*p)) 13160089Seric p++; 13260089Seric if (*p != '\0') 13360089Seric map->map_rebuild = newstr(p); 13460089Seric 13556822Seric if (map->map_file == NULL) 13657208Seric { 13760089Seric syserr("No file name for %s map %s", 13860089Seric map->map_class->map_cname, map->map_mname); 13956822Seric return FALSE; 14057208Seric } 14160089Seric return TRUE; 14260089Seric } 14360089Seric /* 14460089Seric ** MAP_REWRITE -- rewrite a database key, interpolating %n indications. 14560089Seric ** 14660089Seric ** It also adds the map_app string. It can be used as a utility 14760089Seric ** in the map_lookup method. 14860089Seric ** 14960089Seric ** Parameters: 15060089Seric ** map -- the map that causes this. 15160089Seric ** s -- the string to rewrite, NOT necessarily null terminated. 15260089Seric ** slen -- the length of s. 15360089Seric ** av -- arguments to interpolate into buf. 15460089Seric ** 15560089Seric ** Returns: 15660089Seric ** Pointer to rewritten result. 15760089Seric ** 15860089Seric ** Side Effects: 15960089Seric ** none. 16060089Seric */ 16160089Seric 16260089Seric char * 16360089Seric map_rewrite(map, s, slen, av) 16460089Seric register MAP *map; 16560089Seric register char *s; 16660089Seric int slen; 16760089Seric char **av; 16860089Seric { 16960089Seric register char *bp; 17060089Seric register char c; 17160089Seric char **avp; 17260089Seric register char *ap; 17360089Seric int i; 17460089Seric int len; 17560089Seric static int buflen = -1; 17660089Seric static char *buf = NULL; 17760089Seric 17860089Seric if (tTd(23, 1)) 17960089Seric { 18060089Seric printf("map_rewrite(%.*s), av =\n", slen, s); 18160089Seric for (avp = av; *avp != NULL; avp++) 18260089Seric printf("\t%s\n", *avp); 18360089Seric } 18460089Seric 18560089Seric /* count expected size of output (can safely overestimate) */ 18660089Seric i = len = slen; 18760089Seric if (av != NULL) 18860089Seric { 18960089Seric bp = s; 19060089Seric for (i = slen; --i >= 0 && (c = *bp++) != 0; ) 19160089Seric { 19260089Seric if (c != '%') 19360089Seric continue; 19460089Seric if (--i < 0) 19560089Seric break; 19660089Seric c = *bp++; 19760089Seric if (!(isascii(c) && isdigit(c))) 19860089Seric continue; 19960089Seric c -= 0; 20060089Seric for (avp = av; --c >= 0 && *avp != NULL; avp++) 20160089Seric continue; 20260089Seric if (*avp == NULL) 20360089Seric continue; 20460089Seric len += strlen(*avp); 20560089Seric } 20660089Seric } 20760089Seric if (map->map_app != NULL) 20860089Seric len += strlen(map->map_app); 20960089Seric if (buflen < ++len) 21060089Seric { 21160089Seric /* need to malloc additional space */ 21260089Seric buflen = len; 21360089Seric if (buf != NULL) 21460089Seric free(buf); 21560089Seric buf = xalloc(buflen); 21660089Seric } 21760089Seric 21860089Seric bp = buf; 21960089Seric if (av == NULL) 22060089Seric { 22160089Seric bcopy(s, bp, slen); 22260089Seric bp += slen; 22360089Seric } 22460089Seric else 22560089Seric { 22660089Seric while (--slen >= 0 && (c = *s++) != '\0') 22760089Seric { 22860089Seric if (c != '%') 22960089Seric { 23060089Seric pushc: 23160089Seric *bp++ = c; 23260089Seric continue; 23360089Seric } 23460089Seric if (--slen < 0 || (c = *s++) == '\0') 23560089Seric c = '%'; 23660089Seric if (c == '%') 23760089Seric goto pushc; 23860089Seric if (!(isascii(c) && isdigit(c))) 23960089Seric { 24060089Seric *bp++ = '%'; 24160089Seric goto pushc; 24260089Seric } 24360089Seric c -= '0'; 24460089Seric for (avp = av; --c >= 0 && *avp != NULL; avp++) 24560089Seric continue; 24660089Seric if (*avp == NULL) 24760089Seric continue; 24860089Seric 24960089Seric /* transliterate argument into output string */ 25060089Seric for (ap = *avp; (c = *ap++) != '\0'; ) 25160089Seric *bp++ = c; 25260089Seric } 25360089Seric } 25460089Seric if (map->map_app != NULL) 25560089Seric strcpy(bp, map->map_app); 25660089Seric else 25760089Seric *bp = '\0'; 25860089Seric if (tTd(23, 1)) 25960089Seric printf("map_rewrite => %s\n", buf); 26060089Seric return buf; 26160089Seric } 26260089Seric /* 26360089Seric ** NDBM modules 26460089Seric */ 26560089Seric 26660089Seric #ifdef NDBM 26760089Seric 26860089Seric /* 26960089Seric ** DBM_MAP_OPEN -- DBM-style map open 27060089Seric */ 27160089Seric 27260089Seric bool 27360089Seric ndbm_map_open(map, mode) 27460089Seric MAP *map; 27560089Seric int mode; 27660089Seric { 27760089Seric DBM *dbm; 27860089Seric 27960089Seric if (tTd(27, 2)) 28060089Seric printf("ndbm_map_open(%s, %d)\n", map->map_file, mode); 28160089Seric 282*60207Seric if (mode == O_RDWR) 283*60207Seric mode |= O_CREAT|O_TRUNC; 284*60207Seric 28560089Seric /* open the database */ 28660089Seric dbm = dbm_open(map->map_file, mode, DBMMODE); 28756822Seric if (dbm == NULL) 28856822Seric { 289*60207Seric if (!bitset(MF_OPTIONAL, map->map_mflags)) 29056836Seric syserr("Cannot open DBM database %s", map->map_file); 29156822Seric return FALSE; 29256822Seric } 29360089Seric map->map_db1 = (void *) dbm; 294*60207Seric if (mode == O_RDONLY && bitset(MF_ALIAS, map->map_mflags)) 295*60207Seric aliaswait(map, ".dir"); 29656822Seric return TRUE; 29756822Seric } 29860089Seric 29960089Seric 30060089Seric /* 30156822Seric ** DBM_MAP_LOOKUP -- look up a datum in a DBM-type map 30256822Seric */ 30356822Seric 30456822Seric char * 30560089Seric ndbm_map_lookup(map, name, av, statp) 30656822Seric MAP *map; 30760089Seric char *name; 30856822Seric char **av; 30959084Seric int *statp; 31056822Seric { 31156822Seric datum key, val; 31260089Seric char keybuf[MAXNAME + 1]; 31356822Seric 31460089Seric if (tTd(27, 20)) 31560089Seric printf("ndbm_map_lookup(%s)\n", name); 31660089Seric 31760089Seric key.dptr = name; 31860089Seric key.dsize = strlen(name); 319*60207Seric if (!bitset(MF_NOFOLDCASE, map->map_mflags)) 32057014Seric { 32160089Seric if (key.dsize > sizeof keybuf - 1) 32260089Seric key.dsize = sizeof keybuf - 1; 32360089Seric bcopy(key.dptr, keybuf, key.dsize + 1); 32460089Seric makelower(keybuf); 32560089Seric key.dptr = keybuf; 32657014Seric } 327*60207Seric if (bitset(MF_INCLNULL, map->map_mflags)) 32856822Seric key.dsize++; 32960089Seric (void) lockfile(dbm_dirfno((DBM *) map->map_db1), map->map_file, LOCK_SH); 33060089Seric val = dbm_fetch((DBM *) map->map_db1, key); 33160089Seric (void) lockfile(dbm_dirfno((DBM *) map->map_db1), map->map_file, LOCK_UN); 33256822Seric if (val.dptr == NULL) 33356822Seric return NULL; 334*60207Seric if (bitset(MF_MATCHONLY, map->map_mflags)) 33560089Seric av = NULL; 33660089Seric return map_rewrite(map, val.dptr, val.dsize, av); 33756822Seric } 33856822Seric 33956822Seric 34056822Seric /* 34160089Seric ** DBM_MAP_STORE -- store a datum in the database 34256822Seric */ 34356822Seric 34460089Seric void 34560089Seric ndbm_map_store(map, lhs, rhs) 34660089Seric register MAP *map; 34760089Seric char *lhs; 34860089Seric char *rhs; 34960089Seric { 35060089Seric datum key; 35160089Seric datum data; 35260089Seric int stat; 35360089Seric 35460089Seric if (tTd(27, 12)) 35560089Seric printf("ndbm_map_store(%s, %s)\n", lhs, rhs); 35660089Seric 35760089Seric key.dsize = strlen(lhs); 35860089Seric key.dptr = lhs; 35960089Seric 36060089Seric data.dsize = strlen(rhs); 36160089Seric data.dptr = rhs; 36260089Seric 363*60207Seric if (bitset(MF_INCLNULL, map->map_mflags)) 36460089Seric { 36560089Seric key.dsize++; 36660089Seric data.dsize++; 36760089Seric } 36860089Seric 36960089Seric stat = dbm_store((DBM *) map->map_db1, key, data, DBM_INSERT); 37060089Seric if (stat > 0) 37160089Seric { 37260089Seric usrerr("050 Warning: duplicate alias name %s", lhs); 37360089Seric stat = dbm_store((DBM *) map->map_db1, key, data, DBM_REPLACE); 37460089Seric } 37560089Seric if (stat != 0) 37660089Seric syserr("readaliases: dbm put (%s)", lhs); 37760089Seric } 37860089Seric 37960089Seric 38060089Seric /* 381*60207Seric ** NDBM_MAP_CLOSE -- close the database 38260089Seric */ 38360089Seric 38460089Seric void 38560089Seric ndbm_map_close(map) 38660089Seric register MAP *map; 38760089Seric { 388*60207Seric if (bitset(MF_WRITABLE, map->map_mflags)) 38960089Seric { 39060089Seric #ifdef YPCOMPAT 39160089Seric char buf[200]; 39260089Seric 39360089Seric (void) sprintf(buf, "%010ld", curtime()); 39460089Seric ndbm_map_store(map, "YP_LAST_MODIFIED", buf); 39560089Seric 39660089Seric (void) myhostname(buf, sizeof buf); 39760089Seric ndbm_map_store(map, "YP_MASTER_NAME", buf); 39860089Seric #endif 39960089Seric 40060089Seric /* write out the distinguished alias */ 40160089Seric ndbm_map_store(map, "@", "@"); 40260089Seric } 40360089Seric dbm_close((DBM *) map->map_db1); 40460089Seric } 40560089Seric 40660089Seric #endif 40760089Seric /* 40860089Seric ** HASH (NEWDB) Modules 40960089Seric */ 41060089Seric 41160089Seric #ifdef NEWDB 41260089Seric 41360089Seric /* 41460089Seric ** BTREE_MAP_PARSE -- BTREE-style map initialization 41560089Seric */ 41660089Seric 41756822Seric bool 41860089Seric bt_map_open(map, mode) 41956822Seric MAP *map; 42060089Seric int mode; 42156822Seric { 42256822Seric DB *db; 42360089Seric char buf[MAXNAME]; 42456822Seric 42560089Seric if (tTd(27, 2)) 42660089Seric printf("bt_map_open(%s, %d)\n", map->map_file, mode); 42760089Seric 428*60207Seric if (mode == O_RDWR) 429*60207Seric mode |= O_CREAT|O_TRUNC; 430*60207Seric 43160089Seric (void) sprintf(buf, "%s.db", map->map_file); 43260089Seric db = dbopen(buf, mode, 0644, DB_BTREE, NULL); 43356822Seric if (db == NULL) 43456822Seric { 435*60207Seric if (!bitset(MF_OPTIONAL, map->map_mflags)) 43656836Seric syserr("Cannot open BTREE database %s", map->map_file); 43756822Seric return FALSE; 43856822Seric } 43960089Seric map->map_db2 = (void *) db; 440*60207Seric if (mode == O_RDONLY && bitset(MF_ALIAS, map->map_mflags)) 441*60207Seric aliaswait(map, ".db"); 44256822Seric return TRUE; 44356822Seric } 44456822Seric 44556822Seric 44656822Seric /* 44756822Seric ** HASH_MAP_INIT -- HASH-style map initialization 44856822Seric */ 44956822Seric 45056822Seric bool 45160089Seric hash_map_open(map, mode) 45256822Seric MAP *map; 45360089Seric int mode; 45456822Seric { 45556822Seric DB *db; 45660089Seric char buf[MAXNAME]; 45756822Seric 45860089Seric if (tTd(27, 2)) 45960089Seric printf("hash_map_open(%s, %d)\n", map->map_file, mode); 46060089Seric 461*60207Seric if (mode == O_RDWR) 462*60207Seric mode |= O_CREAT|O_TRUNC; 463*60207Seric 46460089Seric (void) sprintf(buf, "%s.db", map->map_file); 46560089Seric db = dbopen(buf, mode, 0644, DB_HASH, NULL); 46656822Seric if (db == NULL) 46756822Seric { 468*60207Seric if (!bitset(MF_OPTIONAL, map->map_mflags)) 46956836Seric syserr("Cannot open HASH database %s", map->map_file); 47056822Seric return FALSE; 47156822Seric } 47260089Seric map->map_db2 = (void *) db; 473*60207Seric if (mode == O_RDONLY && bitset(MF_ALIAS, map->map_mflags)) 474*60207Seric aliaswait(map, ".db"); 47556822Seric return TRUE; 47656822Seric } 47756822Seric 47856822Seric 47956822Seric /* 48056822Seric ** DB_MAP_LOOKUP -- look up a datum in a BTREE- or HASH-type map 48156822Seric */ 48256822Seric 48356822Seric char * 48460089Seric db_map_lookup(map, name, av, statp) 48556822Seric MAP *map; 48660089Seric char *name; 48756822Seric char **av; 48859084Seric int *statp; 48956822Seric { 49056822Seric DBT key, val; 49160089Seric char keybuf[MAXNAME + 1]; 49256822Seric 49360089Seric if (tTd(27, 20)) 49460089Seric printf("db_map_lookup(%s)\n", name); 49560089Seric 49660089Seric key.size = strlen(name); 49760089Seric if (key.size > sizeof keybuf - 1) 49860089Seric key.size = sizeof keybuf - 1; 49960089Seric key.data = keybuf; 50060089Seric bcopy(name, keybuf, key.size + 1); 501*60207Seric if (!bitset(MF_NOFOLDCASE, map->map_mflags)) 50260089Seric makelower(keybuf); 503*60207Seric if (bitset(MF_INCLNULL, map->map_mflags)) 50456822Seric key.size++; 50560089Seric if (((DB *) map->map_db2)->get((DB *) map->map_db2, &key, &val, 0) != 0) 50656822Seric return NULL; 507*60207Seric if (bitset(MF_MATCHONLY, map->map_mflags)) 50860089Seric av = NULL; 50960089Seric return map_rewrite(map, val.data, val.size, av); 51056822Seric } 51156822Seric 51260089Seric 51360089Seric /* 51460089Seric ** DB_MAP_STORE -- store a datum in the NEWDB database 51556822Seric */ 51656822Seric 51760089Seric void 51860089Seric db_map_store(map, lhs, rhs) 51960089Seric register MAP *map; 52060089Seric char *lhs; 52160089Seric char *rhs; 52256822Seric { 52360089Seric int stat; 52460089Seric DBT key; 52560089Seric DBT data; 52660089Seric register DB *db = map->map_db2; 52756822Seric 52860089Seric if (tTd(27, 20)) 52960089Seric printf("db_map_store(%s, %s)\n", lhs, rhs); 53060089Seric 53160089Seric key.size = strlen(lhs); 53260089Seric key.data = lhs; 53360089Seric 53460089Seric data.size = strlen(rhs); 53560089Seric data.data = rhs; 53660089Seric 537*60207Seric if (bitset(MF_INCLNULL, map->map_mflags)) 53856822Seric { 53960089Seric key.size++; 54060089Seric data.size++; 54160089Seric } 54256836Seric 54360089Seric stat = db->put(db, &key, &data, R_NOOVERWRITE); 54460089Seric if (stat > 0) 54560089Seric { 54660089Seric usrerr("050 Warning: duplicate alias name %s", lhs); 54760089Seric stat = db->put(db, &key, &data, 0); 54860089Seric } 54960089Seric if (stat != 0) 55060089Seric syserr("readaliases: db put (%s)", lhs); 55160089Seric } 55256836Seric 55356847Seric 55460089Seric /* 55560089Seric ** DB_MAP_CLOSE -- add distinguished entries and close the database 55660089Seric */ 55760089Seric 55860089Seric void 55960089Seric db_map_close(map) 56060089Seric MAP *map; 56160089Seric { 56260089Seric register DB *db = map->map_db2; 56360089Seric 56460089Seric if (tTd(27, 9)) 565*60207Seric printf("db_map_close(%s, %x)\n", map->map_file, map->map_mflags); 56660089Seric 567*60207Seric if (bitset(MF_WRITABLE, map->map_mflags)) 56858804Seric { 56960089Seric /* write out the distinguished alias */ 57060089Seric db_map_store(map, "@", "@"); 57158804Seric } 57258963Seric 57360089Seric if (db->close(db) != 0) 57460089Seric syserr("readaliases: db close failure"); 57556822Seric } 57657208Seric 57760089Seric #endif 57860089Seric /* 57960089Seric ** NIS Modules 58060089Seric */ 58160089Seric 58260089Seric # ifdef NIS 58360089Seric 58457208Seric /* 58560089Seric ** NIS_MAP_OPEN -- open DBM map 58657208Seric */ 58757208Seric 58857208Seric bool 58960089Seric nis_map_open(map, mode) 59057208Seric MAP *map; 59160089Seric int mode; 59257208Seric { 59357216Seric int yperr; 59457216Seric char *master; 59557216Seric 59660089Seric if (tTd(27, 2)) 59760089Seric printf("nis_map_open(%s)\n", map->map_file); 59860089Seric 599*60207Seric if (mode != O_RDONLY) 600*60207Seric { 601*60207Seric errno = ENODEV; 602*60207Seric return FALSE; 603*60207Seric } 604*60207Seric 60557208Seric if (map->map_domain == NULL) 60657208Seric yp_get_default_domain(&map->map_domain); 60757216Seric 60857216Seric /* check to see if this map actually exists */ 60957216Seric yperr = yp_master(map->map_domain, map->map_file, &master); 61057216Seric if (yperr == 0) 61157216Seric return TRUE; 612*60207Seric if (!bitset(MF_OPTIONAL, map->map_mflags)) 61357216Seric syserr("Cannot bind to domain %s: %s", map->map_domain, 61457216Seric yperr_string(yperr)); 61557216Seric return FALSE; 61657208Seric } 61760089Seric 61860089Seric bool 61960089Seric nis_map_open(map, mode) 62060089Seric MAP *map; 62160089Seric int mode; 62260089Seric { 62360089Seric register char *p; 62460089Seric int yperr; 62560089Seric auto char *vp; 62660089Seric auto int vsize; 62760089Seric 62860089Seric p = strchr(map->map_file, '@'); 62960089Seric if (p != NULL) 63060089Seric { 63160089Seric *p++ = '\0'; 63260089Seric if (*p != '\0') 63360089Seric map->map_domain = p; 63460089Seric } 63560089Seric if (map->map_domain == NULL) 63660089Seric yp_get_default_domain(&map->map_domain); 63760089Seric 63860089Seric if (*map->map_file == '\0') 63960089Seric map->map_file = "mail.aliases"; 64060089Seric 64160089Seric yperr = yp_match(map->map_domain, map->map_file, "@", 1, 64260089Seric &vp, &vsize); 64360089Seric if (tTd(27, 10)) 64460089Seric printf("nis_map_open: yp_match(%s, %s) => %s\n", 64560089Seric map->map_domain, map->map_file, yperr_string(yperr)); 64660089Seric if (yperr == 0 || yperr == YPERR_KEY || yperr == YPERR_BUSY) 64760089Seric return TRUE; 64860089Seric return FALSE; 64960089Seric } 65060089Seric 65160089Seric 65260089Seric /* 65357208Seric ** NIS_MAP_LOOKUP -- look up a datum in a NIS map 65457208Seric */ 65557208Seric 65657208Seric char * 65760089Seric nis_map_lookup(map, name, av, statp) 65857208Seric MAP *map; 65960089Seric char *name; 66057208Seric char **av; 66159084Seric int *statp; 66257208Seric { 66357208Seric char *vp; 66457642Seric auto int vsize; 66559274Seric int buflen; 66660089Seric char keybuf[MAXNAME + 1]; 66757208Seric 66860089Seric if (tTd(27, 20)) 66960089Seric printf("nis_map_lookup(%s)\n", name); 67060089Seric 67160089Seric buflen = strlen(name); 67260089Seric if (buflen > sizeof keybuf - 1) 67360089Seric buflen = sizeof keybuf - 1; 67460089Seric bcopy(name, keybuf, buflen + 1); 675*60207Seric if (!bitset(MF_NOFOLDCASE, map->map_mflags)) 67660089Seric makelower(keybuf); 677*60207Seric if (bitset(MF_INCLNULL, map->map_mflags)) 67859274Seric buflen++; 67960089Seric yperr = yp_match(map->map_domain, map->map_file, keybuf, buflen, 68060089Seric &vp, &vsize); 68160089Seric if (yperr != 0) 68260089Seric { 68360089Seric if (yperr != YPERR_KEY && yperr != YPERR_BUSY) 684*60207Seric map->map_mflags &= ~MF_VALID; 68557208Seric return NULL; 68660089Seric } 687*60207Seric if (bitset(MF_MATCHONLY, map->map_mflags)) 68860089Seric av = NULL; 68960089Seric return map_rewrite(map, val.dptr, val.dsize, av); 69057208Seric } 69157208Seric 69260089Seric 69360089Seric /* 694*60207Seric ** NIS_MAP_STORE 69560089Seric */ 69660089Seric 69760089Seric void 69860089Seric nis_map_store(map, lhs, rhs) 69960089Seric MAP *map; 70060089Seric char *lhs; 70160089Seric char *rhs; 70260089Seric { 70360089Seric /* nothing */ 70460089Seric } 70560089Seric 70660089Seric 70760089Seric /* 708*60207Seric ** NIS_MAP_CLOSE 70960089Seric */ 71060089Seric 71160089Seric void 71260089Seric nis_map_close(map) 71360089Seric MAP *map; 71460089Seric { 71560089Seric /* nothing */ 71660089Seric } 71760089Seric 71860089Seric #endif /* NIS */ 71957208Seric /* 72060089Seric ** STAB (Symbol Table) Modules 72160089Seric */ 72260089Seric 72360089Seric 72460089Seric /* 725*60207Seric ** STAB_MAP_LOOKUP -- look up alias in symbol table 72660089Seric */ 72760089Seric 72860089Seric char * 72960089Seric stab_map_lookup(map, name) 73060089Seric register MAP *map; 73160089Seric char *name; 73260089Seric { 73360089Seric register STAB *s; 73460089Seric 73560089Seric if (tTd(27, 20)) 73660089Seric printf("stab_lookup(%s)\n", name); 73760089Seric 73860089Seric s = stab(name, ST_ALIAS, ST_FIND); 73960089Seric if (s != NULL) 74060089Seric return (s->s_alias); 74160089Seric return (NULL); 74260089Seric } 74360089Seric 74460089Seric 74560089Seric /* 746*60207Seric ** STAB_MAP_STORE -- store in symtab (actually using during init, not rebuild) 74760089Seric */ 74860089Seric 74960089Seric void 75060089Seric stab_map_store(map, lhs, rhs) 75160089Seric register MAP *map; 75260089Seric char *lhs; 75360089Seric char *rhs; 75460089Seric { 75560089Seric register STAB *s; 75660089Seric 75760089Seric s = stab(lhs, ST_ALIAS, ST_ENTER); 75860089Seric s->s_alias = newstr(rhs); 75960089Seric } 76060089Seric 76160089Seric 76260089Seric /* 763*60207Seric ** STAB_MAP_OPEN -- initialize (reads data file) 764*60207Seric ** 765*60207Seric ** This is a wierd case -- it is only intended as a fallback for 766*60207Seric ** aliases. For this reason, opens for write (only during a 767*60207Seric ** "newaliases") always fails, and opens for read open the 768*60207Seric ** actual underlying text file instead of the database. 76960089Seric */ 77060089Seric 77160089Seric bool 77260089Seric stab_map_open(map, mode) 77360089Seric register MAP *map; 77460089Seric int mode; 77560089Seric { 77660089Seric FILE *af; 77760089Seric 77860089Seric if (tTd(27, 2)) 77960089Seric printf("stab_map_open(%s)\n", map->map_file); 78060089Seric 78160089Seric if (mode != O_RDONLY) 782*60207Seric { 783*60207Seric errno = ENODEV; 78460089Seric return FALSE; 785*60207Seric } 78660089Seric 78760089Seric return TRUE; 78860089Seric } 78960089Seric 79060089Seric 79160089Seric /* 792*60207Seric ** STAB_MAP_CLOSE -- close symbol table (???) 79360089Seric */ 79460089Seric 79560089Seric void 79660089Seric stab_map_close(map) 79760089Seric MAP *map; 79860089Seric { 79960089Seric /* ignore it */ 80060089Seric } 80160089Seric /* 80260089Seric ** Implicit Modules 80356822Seric ** 80460089Seric ** Tries several types. For back compatibility of aliases. 80556822Seric */ 80656822Seric 80760089Seric 80860089Seric /* 809*60207Seric ** IMPL_MAP_LOOKUP -- lookup in best open database 81060089Seric */ 81160089Seric 81260089Seric char * 81360089Seric impl_map_lookup(map, name, av, pstat) 81460089Seric MAP *map; 81560089Seric char *name; 81656822Seric char **av; 81760089Seric int *pstat; 81856822Seric { 81960089Seric if (tTd(27, 20)) 82060089Seric printf("impl_map_lookup(%s)\n", name); 82156822Seric 82260089Seric #ifdef NEWDB 823*60207Seric if (bitset(MF_IMPL_HASH, map->map_mflags)) 82460089Seric return db_map_lookup(map, name, av, pstat); 82560089Seric #endif 82660089Seric #ifdef NDBM 827*60207Seric if (bitset(MF_IMPL_NDBM, map->map_mflags)) 82860089Seric return ndbm_map_lookup(map, name, av, pstat); 82960089Seric #endif 83060089Seric return stab_map_lookup(map, name, av, pstat); 83160089Seric } 83260089Seric 83360089Seric /* 834*60207Seric ** IMPL_MAP_STORE -- store in open databases 83560089Seric */ 83660089Seric 83760089Seric void 83860089Seric impl_map_store(map, lhs, rhs) 83960089Seric MAP *map; 84060089Seric char *lhs; 84160089Seric char *rhs; 84260089Seric { 84360089Seric #ifdef NEWDB 844*60207Seric if (bitset(MF_IMPL_HASH, map->map_mflags)) 84560089Seric db_map_store(map, lhs, rhs); 84660089Seric #endif 84760089Seric #ifdef NDBM 848*60207Seric if (bitset(MF_IMPL_NDBM, map->map_mflags)) 84960089Seric ndbm_map_store(map, lhs, rhs); 85060089Seric #endif 85160089Seric stab_map_store(map, lhs, rhs); 85260089Seric } 85360089Seric 85460089Seric /* 85560089Seric ** IMPL_MAP_OPEN -- implicit database open 85660089Seric */ 85760089Seric 85860089Seric bool 85960089Seric impl_map_open(map, mode) 86060089Seric MAP *map; 86160089Seric int mode; 86260089Seric { 86360089Seric struct stat stb; 86460089Seric 86560089Seric if (tTd(27, 2)) 86660089Seric printf("impl_map_open(%s)\n", map->map_file); 86760089Seric 86860089Seric if (stat(map->map_file, &stb) < 0) 86956822Seric { 87060089Seric /* no alias file at all */ 87160089Seric return FALSE; 87256822Seric } 87356822Seric 87460089Seric #ifdef NEWDB 875*60207Seric map->map_mflags |= MF_IMPL_HASH; 87660089Seric if (hash_map_open(map, mode)) 87756822Seric { 878*60207Seric #if defined(NDBM) && defined(YPCOMPAT) 879*60207Seric if (mode == O_RDONLY || access("/var/yp/Makefile", R_OK) == 0) 880*60207Seric #endif 881*60207Seric return TRUE; 88260089Seric } 883*60207Seric else 884*60207Seric map->map_mflags &= ~MF_IMPL_HASH; 88560089Seric #endif 88660089Seric #ifdef NDBM 887*60207Seric map->map_mflags |= MF_IMPL_NDBM; 88860089Seric if (ndbm_map_open(map, mode)) 88960089Seric { 89060089Seric return TRUE; 89160089Seric } 892*60207Seric else 893*60207Seric map->map_mflags &= ~MF_IMPL_NDBM; 89460089Seric #endif 89556822Seric 896*60207Seric #if !defined(NEWDB) && !defined(NDBM) 89760089Seric if (Verbose) 89860089Seric message("WARNING: cannot open alias database %s", map->map_file); 899*60207Seric #endif 90060089Seric 901*60207Seric return stab_map_open(map, mode); 90256822Seric } 90360089Seric 904*60207Seric 90560089Seric /* 906*60207Seric ** IMPL_MAP_CLOSE -- close any open database(s) 90760089Seric */ 90860089Seric 90960089Seric void 910*60207Seric impl_map_close(map) 91160089Seric MAP *map; 91260089Seric { 91360089Seric #ifdef NEWDB 914*60207Seric if (bitset(MF_IMPL_HASH, map->map_mflags)) 91560089Seric { 916*60207Seric db_map_close(map); 917*60207Seric map->map_mflags &= ~MF_IMPL_HASH; 91860089Seric } 91960089Seric #endif 92060089Seric 92160089Seric #ifdef NDBM 922*60207Seric if (bitset(MF_IMPL_NDBM, map->map_mflags)) 92360089Seric { 924*60207Seric ndbm_map_close(map); 925*60207Seric map->map_mflags &= ~MF_IMPL_NDBM; 92660089Seric } 92760089Seric #endif 92860089Seric } 929*60207Seric /* 930*60207Seric ** NULL stubs 93160089Seric */ 93260089Seric 933*60207Seric bool 934*60207Seric null_map_open(map, mode) 93560089Seric MAP *map; 936*60207Seric int mode; 93760089Seric { 938*60207Seric return TRUE; 93960089Seric } 94060089Seric 941*60207Seric void 942*60207Seric null_map_close(map) 943*60207Seric MAP *map; 94460089Seric { 945*60207Seric return; 946*60207Seric } 94760089Seric 948*60207Seric void 949*60207Seric null_map_store(map, key, val) 950*60207Seric MAP *map; 951*60207Seric char *key; 952*60207Seric char *val; 95360089Seric { 954*60207Seric return; 95560089Seric } 956