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*60215Seric static char sccsid[] = "@(#)map.c 6.16 (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': 8760207Seric map->map_mflags |= MF_INCLNULL; 8860089Seric break; 8960089Seric 9060089Seric case 'o': 9160207Seric map->map_mflags |= MF_OPTIONAL; 9260089Seric break; 9360089Seric 9460089Seric case 'f': 9560207Seric map->map_mflags |= MF_NOFOLDCASE; 9660089Seric break; 9760089Seric 9860089Seric case 'm': 9960207Seric map->map_mflags |= MF_MATCHONLY; 10060089Seric break; 10160089Seric 10260089Seric case 'a': 10360089Seric map->map_app = ++p; 10460089Seric break; 10560089Seric } 10660089Seric while (*p != '\0' && !(isascii(*p) && isspace(*p))) 10760089Seric p++; 10860089Seric if (*p != '\0') 10960089Seric *p++ = '\0'; 11060089Seric } 11160089Seric if (map->map_app != NULL) 11260089Seric map->map_app = newstr(map->map_app); 11360089Seric 11460089Seric if (*p != '\0') 11560089Seric { 11660089Seric map->map_file = p; 11760089Seric while (*p != '\0' && !(isascii(*p) && isspace(*p))) 11860089Seric p++; 11960089Seric if (*p != '\0') 12060089Seric *p++ = '\0'; 12160089Seric map->map_file = newstr(map->map_file); 12260089Seric } 12360089Seric 12460089Seric while (*p != '\0' && isascii(*p) && isspace(*p)) 12560089Seric p++; 12660089Seric if (*p != '\0') 12760089Seric map->map_rebuild = newstr(p); 12860089Seric 12956822Seric if (map->map_file == NULL) 13057208Seric { 13160089Seric syserr("No file name for %s map %s", 13260089Seric map->map_class->map_cname, map->map_mname); 13356822Seric return FALSE; 13457208Seric } 13560089Seric return TRUE; 13660089Seric } 13760089Seric /* 13860089Seric ** MAP_REWRITE -- rewrite a database key, interpolating %n indications. 13960089Seric ** 14060089Seric ** It also adds the map_app string. It can be used as a utility 14160089Seric ** in the map_lookup method. 14260089Seric ** 14360089Seric ** Parameters: 14460089Seric ** map -- the map that causes this. 14560089Seric ** s -- the string to rewrite, NOT necessarily null terminated. 14660089Seric ** slen -- the length of s. 14760089Seric ** av -- arguments to interpolate into buf. 14860089Seric ** 14960089Seric ** Returns: 15060089Seric ** Pointer to rewritten result. 15160089Seric ** 15260089Seric ** Side Effects: 15360089Seric ** none. 15460089Seric */ 15560089Seric 15660089Seric char * 15760089Seric map_rewrite(map, s, slen, av) 15860089Seric register MAP *map; 15960089Seric register char *s; 16060089Seric int slen; 16160089Seric char **av; 16260089Seric { 16360089Seric register char *bp; 16460089Seric register char c; 16560089Seric char **avp; 16660089Seric register char *ap; 16760089Seric int i; 16860089Seric int len; 16960089Seric static int buflen = -1; 17060089Seric static char *buf = NULL; 17160089Seric 17260089Seric if (tTd(23, 1)) 17360089Seric { 17460089Seric printf("map_rewrite(%.*s), av =\n", slen, s); 17560089Seric for (avp = av; *avp != NULL; avp++) 17660089Seric printf("\t%s\n", *avp); 17760089Seric } 17860089Seric 17960089Seric /* count expected size of output (can safely overestimate) */ 18060089Seric i = len = slen; 18160089Seric if (av != NULL) 18260089Seric { 18360089Seric bp = s; 18460089Seric for (i = slen; --i >= 0 && (c = *bp++) != 0; ) 18560089Seric { 18660089Seric if (c != '%') 18760089Seric continue; 18860089Seric if (--i < 0) 18960089Seric break; 19060089Seric c = *bp++; 19160089Seric if (!(isascii(c) && isdigit(c))) 19260089Seric continue; 19360089Seric c -= 0; 19460089Seric for (avp = av; --c >= 0 && *avp != NULL; avp++) 19560089Seric continue; 19660089Seric if (*avp == NULL) 19760089Seric continue; 19860089Seric len += strlen(*avp); 19960089Seric } 20060089Seric } 20160089Seric if (map->map_app != NULL) 20260089Seric len += strlen(map->map_app); 20360089Seric if (buflen < ++len) 20460089Seric { 20560089Seric /* need to malloc additional space */ 20660089Seric buflen = len; 20760089Seric if (buf != NULL) 20860089Seric free(buf); 20960089Seric buf = xalloc(buflen); 21060089Seric } 21160089Seric 21260089Seric bp = buf; 21360089Seric if (av == NULL) 21460089Seric { 21560089Seric bcopy(s, bp, slen); 21660089Seric bp += slen; 21760089Seric } 21860089Seric else 21960089Seric { 22060089Seric while (--slen >= 0 && (c = *s++) != '\0') 22160089Seric { 22260089Seric if (c != '%') 22360089Seric { 22460089Seric pushc: 22560089Seric *bp++ = c; 22660089Seric continue; 22760089Seric } 22860089Seric if (--slen < 0 || (c = *s++) == '\0') 22960089Seric c = '%'; 23060089Seric if (c == '%') 23160089Seric goto pushc; 23260089Seric if (!(isascii(c) && isdigit(c))) 23360089Seric { 23460089Seric *bp++ = '%'; 23560089Seric goto pushc; 23660089Seric } 23760089Seric c -= '0'; 23860089Seric for (avp = av; --c >= 0 && *avp != NULL; avp++) 23960089Seric continue; 24060089Seric if (*avp == NULL) 24160089Seric continue; 24260089Seric 24360089Seric /* transliterate argument into output string */ 24460089Seric for (ap = *avp; (c = *ap++) != '\0'; ) 24560089Seric *bp++ = c; 24660089Seric } 24760089Seric } 24860089Seric if (map->map_app != NULL) 24960089Seric strcpy(bp, map->map_app); 25060089Seric else 25160089Seric *bp = '\0'; 25260089Seric if (tTd(23, 1)) 25360089Seric printf("map_rewrite => %s\n", buf); 25460089Seric return buf; 25560089Seric } 25660089Seric /* 25760089Seric ** NDBM modules 25860089Seric */ 25960089Seric 26060089Seric #ifdef NDBM 26160089Seric 26260089Seric /* 26360089Seric ** DBM_MAP_OPEN -- DBM-style map open 26460089Seric */ 26560089Seric 26660089Seric bool 26760089Seric ndbm_map_open(map, mode) 26860089Seric MAP *map; 26960089Seric int mode; 27060089Seric { 27160089Seric DBM *dbm; 27260089Seric 27360089Seric if (tTd(27, 2)) 27460089Seric printf("ndbm_map_open(%s, %d)\n", map->map_file, mode); 27560089Seric 27660207Seric if (mode == O_RDWR) 27760207Seric mode |= O_CREAT|O_TRUNC; 27860207Seric 27960089Seric /* open the database */ 28060089Seric dbm = dbm_open(map->map_file, mode, DBMMODE); 28156822Seric if (dbm == NULL) 28256822Seric { 28360207Seric if (!bitset(MF_OPTIONAL, map->map_mflags)) 28456836Seric syserr("Cannot open DBM database %s", map->map_file); 28556822Seric return FALSE; 28656822Seric } 28760089Seric map->map_db1 = (void *) dbm; 28860207Seric if (mode == O_RDONLY && bitset(MF_ALIAS, map->map_mflags)) 28960207Seric aliaswait(map, ".dir"); 29056822Seric return TRUE; 29156822Seric } 29260089Seric 29360089Seric 29460089Seric /* 29556822Seric ** DBM_MAP_LOOKUP -- look up a datum in a DBM-type map 29656822Seric */ 29756822Seric 29856822Seric char * 29960089Seric ndbm_map_lookup(map, name, av, statp) 30056822Seric MAP *map; 30160089Seric char *name; 30256822Seric char **av; 30359084Seric int *statp; 30456822Seric { 30556822Seric datum key, val; 30660089Seric char keybuf[MAXNAME + 1]; 30756822Seric 30860089Seric if (tTd(27, 20)) 30960089Seric printf("ndbm_map_lookup(%s)\n", name); 31060089Seric 31160089Seric key.dptr = name; 31260089Seric key.dsize = strlen(name); 31360207Seric if (!bitset(MF_NOFOLDCASE, map->map_mflags)) 31457014Seric { 31560089Seric if (key.dsize > sizeof keybuf - 1) 31660089Seric key.dsize = sizeof keybuf - 1; 31760089Seric bcopy(key.dptr, keybuf, key.dsize + 1); 31860089Seric makelower(keybuf); 31960089Seric key.dptr = keybuf; 32057014Seric } 32160207Seric if (bitset(MF_INCLNULL, map->map_mflags)) 32256822Seric key.dsize++; 32360089Seric (void) lockfile(dbm_dirfno((DBM *) map->map_db1), map->map_file, LOCK_SH); 32460089Seric val = dbm_fetch((DBM *) map->map_db1, key); 32560089Seric (void) lockfile(dbm_dirfno((DBM *) map->map_db1), map->map_file, LOCK_UN); 32656822Seric if (val.dptr == NULL) 32756822Seric return NULL; 32860207Seric if (bitset(MF_MATCHONLY, map->map_mflags)) 32960089Seric av = NULL; 33060089Seric return map_rewrite(map, val.dptr, val.dsize, av); 33156822Seric } 33256822Seric 33356822Seric 33456822Seric /* 33560089Seric ** DBM_MAP_STORE -- store a datum in the database 33656822Seric */ 33756822Seric 33860089Seric void 33960089Seric ndbm_map_store(map, lhs, rhs) 34060089Seric register MAP *map; 34160089Seric char *lhs; 34260089Seric char *rhs; 34360089Seric { 34460089Seric datum key; 34560089Seric datum data; 34660089Seric int stat; 34760089Seric 34860089Seric if (tTd(27, 12)) 34960089Seric printf("ndbm_map_store(%s, %s)\n", lhs, rhs); 35060089Seric 35160089Seric key.dsize = strlen(lhs); 35260089Seric key.dptr = lhs; 35360089Seric 35460089Seric data.dsize = strlen(rhs); 35560089Seric data.dptr = rhs; 35660089Seric 35760207Seric if (bitset(MF_INCLNULL, map->map_mflags)) 35860089Seric { 35960089Seric key.dsize++; 36060089Seric data.dsize++; 36160089Seric } 36260089Seric 36360089Seric stat = dbm_store((DBM *) map->map_db1, key, data, DBM_INSERT); 36460089Seric if (stat > 0) 36560089Seric { 36660089Seric usrerr("050 Warning: duplicate alias name %s", lhs); 36760089Seric stat = dbm_store((DBM *) map->map_db1, key, data, DBM_REPLACE); 36860089Seric } 36960089Seric if (stat != 0) 37060089Seric syserr("readaliases: dbm put (%s)", lhs); 37160089Seric } 37260089Seric 37360089Seric 37460089Seric /* 37560207Seric ** NDBM_MAP_CLOSE -- close the database 37660089Seric */ 37760089Seric 37860089Seric void 37960089Seric ndbm_map_close(map) 38060089Seric register MAP *map; 38160089Seric { 38260207Seric if (bitset(MF_WRITABLE, map->map_mflags)) 38360089Seric { 38460089Seric #ifdef YPCOMPAT 38560089Seric char buf[200]; 38660089Seric 38760089Seric (void) sprintf(buf, "%010ld", curtime()); 38860089Seric ndbm_map_store(map, "YP_LAST_MODIFIED", buf); 38960089Seric 39060089Seric (void) myhostname(buf, sizeof buf); 39160089Seric ndbm_map_store(map, "YP_MASTER_NAME", buf); 39260089Seric #endif 39360089Seric 39460089Seric /* write out the distinguished alias */ 39560089Seric ndbm_map_store(map, "@", "@"); 39660089Seric } 39760089Seric dbm_close((DBM *) map->map_db1); 39860089Seric } 39960089Seric 40060089Seric #endif 40160089Seric /* 40260089Seric ** HASH (NEWDB) Modules 40360089Seric */ 40460089Seric 40560089Seric #ifdef NEWDB 40660089Seric 40760089Seric /* 40860089Seric ** BTREE_MAP_PARSE -- BTREE-style map initialization 40960089Seric */ 41060089Seric 41156822Seric bool 41260089Seric bt_map_open(map, mode) 41356822Seric MAP *map; 41460089Seric int mode; 41556822Seric { 41656822Seric DB *db; 41760089Seric char buf[MAXNAME]; 41856822Seric 41960089Seric if (tTd(27, 2)) 42060089Seric printf("bt_map_open(%s, %d)\n", map->map_file, mode); 42160089Seric 42260207Seric if (mode == O_RDWR) 42360207Seric mode |= O_CREAT|O_TRUNC; 42460207Seric 42560089Seric (void) sprintf(buf, "%s.db", map->map_file); 42660089Seric db = dbopen(buf, mode, 0644, DB_BTREE, NULL); 42756822Seric if (db == NULL) 42856822Seric { 42960207Seric if (!bitset(MF_OPTIONAL, map->map_mflags)) 43056836Seric syserr("Cannot open BTREE database %s", map->map_file); 43156822Seric return FALSE; 43256822Seric } 43360089Seric map->map_db2 = (void *) db; 43460207Seric if (mode == O_RDONLY && bitset(MF_ALIAS, map->map_mflags)) 43560207Seric aliaswait(map, ".db"); 43656822Seric return TRUE; 43756822Seric } 43856822Seric 43956822Seric 44056822Seric /* 44156822Seric ** HASH_MAP_INIT -- HASH-style map initialization 44256822Seric */ 44356822Seric 44456822Seric bool 44560089Seric hash_map_open(map, mode) 44656822Seric MAP *map; 44760089Seric int mode; 44856822Seric { 44956822Seric DB *db; 45060089Seric char buf[MAXNAME]; 45156822Seric 45260089Seric if (tTd(27, 2)) 45360089Seric printf("hash_map_open(%s, %d)\n", map->map_file, mode); 45460089Seric 45560207Seric if (mode == O_RDWR) 45660207Seric mode |= O_CREAT|O_TRUNC; 45760207Seric 45860089Seric (void) sprintf(buf, "%s.db", map->map_file); 45960089Seric db = dbopen(buf, mode, 0644, DB_HASH, NULL); 46056822Seric if (db == NULL) 46156822Seric { 46260207Seric if (!bitset(MF_OPTIONAL, map->map_mflags)) 46356836Seric syserr("Cannot open HASH database %s", map->map_file); 46456822Seric return FALSE; 46556822Seric } 46660089Seric map->map_db2 = (void *) db; 46760207Seric if (mode == O_RDONLY && bitset(MF_ALIAS, map->map_mflags)) 46860207Seric aliaswait(map, ".db"); 46956822Seric return TRUE; 47056822Seric } 47156822Seric 47256822Seric 47356822Seric /* 47456822Seric ** DB_MAP_LOOKUP -- look up a datum in a BTREE- or HASH-type map 47556822Seric */ 47656822Seric 47756822Seric char * 47860089Seric db_map_lookup(map, name, av, statp) 47956822Seric MAP *map; 48060089Seric char *name; 48156822Seric char **av; 48259084Seric int *statp; 48356822Seric { 48456822Seric DBT key, val; 48560089Seric char keybuf[MAXNAME + 1]; 48656822Seric 48760089Seric if (tTd(27, 20)) 48860089Seric printf("db_map_lookup(%s)\n", name); 48960089Seric 49060089Seric key.size = strlen(name); 49160089Seric if (key.size > sizeof keybuf - 1) 49260089Seric key.size = sizeof keybuf - 1; 49360089Seric key.data = keybuf; 49460089Seric bcopy(name, keybuf, key.size + 1); 49560207Seric if (!bitset(MF_NOFOLDCASE, map->map_mflags)) 49660089Seric makelower(keybuf); 49760207Seric if (bitset(MF_INCLNULL, map->map_mflags)) 49856822Seric key.size++; 49960089Seric if (((DB *) map->map_db2)->get((DB *) map->map_db2, &key, &val, 0) != 0) 50056822Seric return NULL; 50160207Seric if (bitset(MF_MATCHONLY, map->map_mflags)) 50260089Seric av = NULL; 50360089Seric return map_rewrite(map, val.data, val.size, av); 50456822Seric } 50556822Seric 50660089Seric 50760089Seric /* 50860089Seric ** DB_MAP_STORE -- store a datum in the NEWDB database 50956822Seric */ 51056822Seric 51160089Seric void 51260089Seric db_map_store(map, lhs, rhs) 51360089Seric register MAP *map; 51460089Seric char *lhs; 51560089Seric char *rhs; 51656822Seric { 51760089Seric int stat; 51860089Seric DBT key; 51960089Seric DBT data; 52060089Seric register DB *db = map->map_db2; 52156822Seric 52260089Seric if (tTd(27, 20)) 52360089Seric printf("db_map_store(%s, %s)\n", lhs, rhs); 52460089Seric 52560089Seric key.size = strlen(lhs); 52660089Seric key.data = lhs; 52760089Seric 52860089Seric data.size = strlen(rhs); 52960089Seric data.data = rhs; 53060089Seric 53160207Seric if (bitset(MF_INCLNULL, map->map_mflags)) 53256822Seric { 53360089Seric key.size++; 53460089Seric data.size++; 53560089Seric } 53656836Seric 53760089Seric stat = db->put(db, &key, &data, R_NOOVERWRITE); 53860089Seric if (stat > 0) 53960089Seric { 54060089Seric usrerr("050 Warning: duplicate alias name %s", lhs); 54160089Seric stat = db->put(db, &key, &data, 0); 54260089Seric } 54360089Seric if (stat != 0) 54460089Seric syserr("readaliases: db put (%s)", lhs); 54560089Seric } 54656836Seric 54756847Seric 54860089Seric /* 54960089Seric ** DB_MAP_CLOSE -- add distinguished entries and close the database 55060089Seric */ 55160089Seric 55260089Seric void 55360089Seric db_map_close(map) 55460089Seric MAP *map; 55560089Seric { 55660089Seric register DB *db = map->map_db2; 55760089Seric 55860089Seric if (tTd(27, 9)) 55960207Seric printf("db_map_close(%s, %x)\n", map->map_file, map->map_mflags); 56060089Seric 56160207Seric if (bitset(MF_WRITABLE, map->map_mflags)) 56258804Seric { 56360089Seric /* write out the distinguished alias */ 56460089Seric db_map_store(map, "@", "@"); 56558804Seric } 56658963Seric 56760089Seric if (db->close(db) != 0) 56860089Seric syserr("readaliases: db close failure"); 56956822Seric } 57057208Seric 57160089Seric #endif 57260089Seric /* 57360089Seric ** NIS Modules 57460089Seric */ 57560089Seric 57660089Seric # ifdef NIS 57760089Seric 57857208Seric /* 57960089Seric ** NIS_MAP_OPEN -- open DBM map 58057208Seric */ 58157208Seric 58257208Seric bool 58360089Seric nis_map_open(map, mode) 58457208Seric MAP *map; 58560089Seric int mode; 58657208Seric { 58757216Seric int yperr; 588*60215Seric register char *p; 589*60215Seric auto char *vp; 590*60215Seric auto int vsize; 59157216Seric char *master; 59257216Seric 59360089Seric if (tTd(27, 2)) 59460089Seric printf("nis_map_open(%s)\n", map->map_file); 59560089Seric 59660207Seric if (mode != O_RDONLY) 59760207Seric { 59860207Seric errno = ENODEV; 59960207Seric return FALSE; 60060207Seric } 60160207Seric 60260089Seric p = strchr(map->map_file, '@'); 60360089Seric if (p != NULL) 60460089Seric { 60560089Seric *p++ = '\0'; 60660089Seric if (*p != '\0') 60760089Seric map->map_domain = p; 60860089Seric } 609*60215Seric 61060089Seric if (map->map_domain == NULL) 61160089Seric yp_get_default_domain(&map->map_domain); 61260089Seric 61360089Seric if (*map->map_file == '\0') 61460089Seric map->map_file = "mail.aliases"; 61560089Seric 616*60215Seric /* check to see if this map actually exists */ 61760089Seric yperr = yp_match(map->map_domain, map->map_file, "@", 1, 61860089Seric &vp, &vsize); 61960089Seric if (tTd(27, 10)) 62060089Seric printf("nis_map_open: yp_match(%s, %s) => %s\n", 62160089Seric map->map_domain, map->map_file, yperr_string(yperr)); 62260089Seric if (yperr == 0 || yperr == YPERR_KEY || yperr == YPERR_BUSY) 62360089Seric return TRUE; 624*60215Seric 625*60215Seric if (!bitset(MF_OPTIONAL, map->map_mflags)) 626*60215Seric syserr("Cannot bind to domain %s: %s", map->map_domain, 627*60215Seric yperr_string(yperr)); 628*60215Seric 62960089Seric return FALSE; 63060089Seric } 63160089Seric 63260089Seric 63360089Seric /* 63457208Seric ** NIS_MAP_LOOKUP -- look up a datum in a NIS map 63557208Seric */ 63657208Seric 63757208Seric char * 63860089Seric nis_map_lookup(map, name, av, statp) 63957208Seric MAP *map; 64060089Seric char *name; 64157208Seric char **av; 64259084Seric int *statp; 64357208Seric { 64457208Seric char *vp; 64557642Seric auto int vsize; 64659274Seric int buflen; 647*60215Seric int yperr; 64860089Seric char keybuf[MAXNAME + 1]; 64957208Seric 65060089Seric if (tTd(27, 20)) 65160089Seric printf("nis_map_lookup(%s)\n", name); 65260089Seric 65360089Seric buflen = strlen(name); 65460089Seric if (buflen > sizeof keybuf - 1) 65560089Seric buflen = sizeof keybuf - 1; 65660089Seric bcopy(name, keybuf, buflen + 1); 65760207Seric if (!bitset(MF_NOFOLDCASE, map->map_mflags)) 65860089Seric makelower(keybuf); 65960207Seric if (bitset(MF_INCLNULL, map->map_mflags)) 66059274Seric buflen++; 66160089Seric yperr = yp_match(map->map_domain, map->map_file, keybuf, buflen, 66260089Seric &vp, &vsize); 66360089Seric if (yperr != 0) 66460089Seric { 66560089Seric if (yperr != YPERR_KEY && yperr != YPERR_BUSY) 666*60215Seric map->map_mflags &= ~(MF_VALID|MF_OPEN); 66757208Seric return NULL; 66860089Seric } 66960207Seric if (bitset(MF_MATCHONLY, map->map_mflags)) 67060089Seric av = NULL; 671*60215Seric return map_rewrite(map, vp, vsize, av); 67257208Seric } 67357208Seric 67460089Seric 67560089Seric /* 67660207Seric ** NIS_MAP_STORE 67760089Seric */ 67860089Seric 67960089Seric void 68060089Seric nis_map_store(map, lhs, rhs) 68160089Seric MAP *map; 68260089Seric char *lhs; 68360089Seric char *rhs; 68460089Seric { 68560089Seric /* nothing */ 68660089Seric } 68760089Seric 68860089Seric 68960089Seric /* 69060207Seric ** NIS_MAP_CLOSE 69160089Seric */ 69260089Seric 69360089Seric void 69460089Seric nis_map_close(map) 69560089Seric MAP *map; 69660089Seric { 69760089Seric /* nothing */ 69860089Seric } 69960089Seric 70060089Seric #endif /* NIS */ 70157208Seric /* 70260089Seric ** STAB (Symbol Table) Modules 70360089Seric */ 70460089Seric 70560089Seric 70660089Seric /* 70760207Seric ** STAB_MAP_LOOKUP -- look up alias in symbol table 70860089Seric */ 70960089Seric 71060089Seric char * 71160089Seric stab_map_lookup(map, name) 71260089Seric register MAP *map; 71360089Seric char *name; 71460089Seric { 71560089Seric register STAB *s; 71660089Seric 71760089Seric if (tTd(27, 20)) 71860089Seric printf("stab_lookup(%s)\n", name); 71960089Seric 72060089Seric s = stab(name, ST_ALIAS, ST_FIND); 72160089Seric if (s != NULL) 72260089Seric return (s->s_alias); 72360089Seric return (NULL); 72460089Seric } 72560089Seric 72660089Seric 72760089Seric /* 72860207Seric ** STAB_MAP_STORE -- store in symtab (actually using during init, not rebuild) 72960089Seric */ 73060089Seric 73160089Seric void 73260089Seric stab_map_store(map, lhs, rhs) 73360089Seric register MAP *map; 73460089Seric char *lhs; 73560089Seric char *rhs; 73660089Seric { 73760089Seric register STAB *s; 73860089Seric 73960089Seric s = stab(lhs, ST_ALIAS, ST_ENTER); 74060089Seric s->s_alias = newstr(rhs); 74160089Seric } 74260089Seric 74360089Seric 74460089Seric /* 74560207Seric ** STAB_MAP_OPEN -- initialize (reads data file) 74660207Seric ** 74760207Seric ** This is a wierd case -- it is only intended as a fallback for 74860207Seric ** aliases. For this reason, opens for write (only during a 74960207Seric ** "newaliases") always fails, and opens for read open the 75060207Seric ** actual underlying text file instead of the database. 75160089Seric */ 75260089Seric 75360089Seric bool 75460089Seric stab_map_open(map, mode) 75560089Seric register MAP *map; 75660089Seric int mode; 75760089Seric { 75860089Seric FILE *af; 75960089Seric 76060089Seric if (tTd(27, 2)) 76160089Seric printf("stab_map_open(%s)\n", map->map_file); 76260089Seric 76360089Seric if (mode != O_RDONLY) 76460207Seric { 76560207Seric errno = ENODEV; 76660089Seric return FALSE; 76760207Seric } 76860089Seric 76960089Seric return TRUE; 77060089Seric } 77160089Seric 77260089Seric 77360089Seric /* 77460207Seric ** STAB_MAP_CLOSE -- close symbol table (???) 77560089Seric */ 77660089Seric 77760089Seric void 77860089Seric stab_map_close(map) 77960089Seric MAP *map; 78060089Seric { 78160089Seric /* ignore it */ 78260089Seric } 78360089Seric /* 78460089Seric ** Implicit Modules 78556822Seric ** 78660089Seric ** Tries several types. For back compatibility of aliases. 78756822Seric */ 78856822Seric 78960089Seric 79060089Seric /* 79160207Seric ** IMPL_MAP_LOOKUP -- lookup in best open database 79260089Seric */ 79360089Seric 79460089Seric char * 79560089Seric impl_map_lookup(map, name, av, pstat) 79660089Seric MAP *map; 79760089Seric char *name; 79856822Seric char **av; 79960089Seric int *pstat; 80056822Seric { 80160089Seric if (tTd(27, 20)) 80260089Seric printf("impl_map_lookup(%s)\n", name); 80356822Seric 80460089Seric #ifdef NEWDB 80560207Seric if (bitset(MF_IMPL_HASH, map->map_mflags)) 80660089Seric return db_map_lookup(map, name, av, pstat); 80760089Seric #endif 80860089Seric #ifdef NDBM 80960207Seric if (bitset(MF_IMPL_NDBM, map->map_mflags)) 81060089Seric return ndbm_map_lookup(map, name, av, pstat); 81160089Seric #endif 81260089Seric return stab_map_lookup(map, name, av, pstat); 81360089Seric } 81460089Seric 81560089Seric /* 81660207Seric ** IMPL_MAP_STORE -- store in open databases 81760089Seric */ 81860089Seric 81960089Seric void 82060089Seric impl_map_store(map, lhs, rhs) 82160089Seric MAP *map; 82260089Seric char *lhs; 82360089Seric char *rhs; 82460089Seric { 82560089Seric #ifdef NEWDB 82660207Seric if (bitset(MF_IMPL_HASH, map->map_mflags)) 82760089Seric db_map_store(map, lhs, rhs); 82860089Seric #endif 82960089Seric #ifdef NDBM 83060207Seric if (bitset(MF_IMPL_NDBM, map->map_mflags)) 83160089Seric ndbm_map_store(map, lhs, rhs); 83260089Seric #endif 83360089Seric stab_map_store(map, lhs, rhs); 83460089Seric } 83560089Seric 83660089Seric /* 83760089Seric ** IMPL_MAP_OPEN -- implicit database open 83860089Seric */ 83960089Seric 84060089Seric bool 84160089Seric impl_map_open(map, mode) 84260089Seric MAP *map; 84360089Seric int mode; 84460089Seric { 84560089Seric struct stat stb; 84660089Seric 84760089Seric if (tTd(27, 2)) 84860089Seric printf("impl_map_open(%s)\n", map->map_file); 84960089Seric 85060089Seric if (stat(map->map_file, &stb) < 0) 85156822Seric { 85260089Seric /* no alias file at all */ 85360089Seric return FALSE; 85456822Seric } 85556822Seric 85660089Seric #ifdef NEWDB 85760207Seric map->map_mflags |= MF_IMPL_HASH; 85860089Seric if (hash_map_open(map, mode)) 85956822Seric { 86060207Seric #if defined(NDBM) && defined(YPCOMPAT) 86160207Seric if (mode == O_RDONLY || access("/var/yp/Makefile", R_OK) == 0) 86260207Seric #endif 86360207Seric return TRUE; 86460089Seric } 86560207Seric else 86660207Seric map->map_mflags &= ~MF_IMPL_HASH; 86760089Seric #endif 86860089Seric #ifdef NDBM 86960207Seric map->map_mflags |= MF_IMPL_NDBM; 87060089Seric if (ndbm_map_open(map, mode)) 87160089Seric { 87260089Seric return TRUE; 87360089Seric } 87460207Seric else 87560207Seric map->map_mflags &= ~MF_IMPL_NDBM; 87660089Seric #endif 87756822Seric 87860207Seric #if !defined(NEWDB) && !defined(NDBM) 87960089Seric if (Verbose) 88060089Seric message("WARNING: cannot open alias database %s", map->map_file); 88160207Seric #endif 88260089Seric 88360207Seric return stab_map_open(map, mode); 88456822Seric } 88560089Seric 88660207Seric 88760089Seric /* 88860207Seric ** IMPL_MAP_CLOSE -- close any open database(s) 88960089Seric */ 89060089Seric 89160089Seric void 89260207Seric impl_map_close(map) 89360089Seric MAP *map; 89460089Seric { 89560089Seric #ifdef NEWDB 89660207Seric if (bitset(MF_IMPL_HASH, map->map_mflags)) 89760089Seric { 89860207Seric db_map_close(map); 89960207Seric map->map_mflags &= ~MF_IMPL_HASH; 90060089Seric } 90160089Seric #endif 90260089Seric 90360089Seric #ifdef NDBM 90460207Seric if (bitset(MF_IMPL_NDBM, map->map_mflags)) 90560089Seric { 90660207Seric ndbm_map_close(map); 90760207Seric map->map_mflags &= ~MF_IMPL_NDBM; 90860089Seric } 90960089Seric #endif 91060089Seric } 91160207Seric /* 91260207Seric ** NULL stubs 91360089Seric */ 91460089Seric 91560207Seric bool 91660207Seric null_map_open(map, mode) 91760089Seric MAP *map; 91860207Seric int mode; 91960089Seric { 92060207Seric return TRUE; 92160089Seric } 92260089Seric 92360207Seric void 92460207Seric null_map_close(map) 92560207Seric MAP *map; 92660089Seric { 92760207Seric return; 92860207Seric } 92960089Seric 93060207Seric void 93160207Seric null_map_store(map, key, val) 93260207Seric MAP *map; 93360207Seric char *key; 93460207Seric char *val; 93560089Seric { 93660207Seric return; 93760089Seric } 938