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*60222Seric static char sccsid[] = "@(#)map.c 6.17 (Berkeley) 05/22/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 ** 35*60222Seric ** char *map_lookup(MAP *map, char *key, char **args, int *pstat) 36*60222Seric ** Look up the key in the given map. If found, do any 37*60222Seric ** rewriting the map wants (including "args" if desired) 3860089Seric ** and return the value. Set *pstat to the appropriate status 39*60222Seric ** on error and return NULL. Args will be NULL if called 40*60222Seric ** from the alias routines, although this should probably 41*60222Seric ** not be relied upon. It is suggested you call map_rewrite 42*60222Seric ** to return the results -- it takes care of null termination 43*60222Seric ** 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) 49*60222Seric ** Open the map for the indicated mode. Mode should 50*60222Seric ** be either O_RDONLY or O_RDWR. Return TRUE if it 51*60222Seric ** was opened successfully, FALSE otherwise. If the open 52*60222Seric ** failed an the MF_OPTIONAL flag is not set, it should 53*60222Seric ** also print an error. If the MF_ALIAS bit is set 54*60222Seric ** and this map class understands the @:@ convention, it 55*60222Seric ** 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 { 18260089Seric printf("map_rewrite(%.*s), av =\n", slen, s); 18360089Seric for (avp = av; *avp != NULL; avp++) 18460089Seric printf("\t%s\n", *avp); 18560089Seric } 18660089Seric 18760089Seric /* count expected size of output (can safely overestimate) */ 18860089Seric i = len = slen; 18960089Seric if (av != NULL) 19060089Seric { 19160089Seric bp = s; 19260089Seric for (i = slen; --i >= 0 && (c = *bp++) != 0; ) 19360089Seric { 19460089Seric if (c != '%') 19560089Seric continue; 19660089Seric if (--i < 0) 19760089Seric break; 19860089Seric c = *bp++; 19960089Seric if (!(isascii(c) && isdigit(c))) 20060089Seric continue; 20160089Seric c -= 0; 20260089Seric for (avp = av; --c >= 0 && *avp != NULL; avp++) 20360089Seric continue; 20460089Seric if (*avp == NULL) 20560089Seric continue; 20660089Seric len += strlen(*avp); 20760089Seric } 20860089Seric } 20960089Seric if (map->map_app != NULL) 21060089Seric len += strlen(map->map_app); 21160089Seric if (buflen < ++len) 21260089Seric { 21360089Seric /* need to malloc additional space */ 21460089Seric buflen = len; 21560089Seric if (buf != NULL) 21660089Seric free(buf); 21760089Seric buf = xalloc(buflen); 21860089Seric } 21960089Seric 22060089Seric bp = buf; 22160089Seric if (av == NULL) 22260089Seric { 22360089Seric bcopy(s, bp, slen); 22460089Seric bp += slen; 22560089Seric } 22660089Seric else 22760089Seric { 22860089Seric while (--slen >= 0 && (c = *s++) != '\0') 22960089Seric { 23060089Seric if (c != '%') 23160089Seric { 23260089Seric pushc: 23360089Seric *bp++ = c; 23460089Seric continue; 23560089Seric } 23660089Seric if (--slen < 0 || (c = *s++) == '\0') 23760089Seric c = '%'; 23860089Seric if (c == '%') 23960089Seric goto pushc; 24060089Seric if (!(isascii(c) && isdigit(c))) 24160089Seric { 24260089Seric *bp++ = '%'; 24360089Seric goto pushc; 24460089Seric } 24560089Seric c -= '0'; 24660089Seric for (avp = av; --c >= 0 && *avp != NULL; avp++) 24760089Seric continue; 24860089Seric if (*avp == NULL) 24960089Seric continue; 25060089Seric 25160089Seric /* transliterate argument into output string */ 25260089Seric for (ap = *avp; (c = *ap++) != '\0'; ) 25360089Seric *bp++ = c; 25460089Seric } 25560089Seric } 25660089Seric if (map->map_app != NULL) 25760089Seric strcpy(bp, map->map_app); 25860089Seric else 25960089Seric *bp = '\0'; 26060089Seric if (tTd(23, 1)) 26160089Seric printf("map_rewrite => %s\n", buf); 26260089Seric return buf; 26360089Seric } 26460089Seric /* 26560089Seric ** NDBM modules 26660089Seric */ 26760089Seric 26860089Seric #ifdef NDBM 26960089Seric 27060089Seric /* 27160089Seric ** DBM_MAP_OPEN -- DBM-style map open 27260089Seric */ 27360089Seric 27460089Seric bool 27560089Seric ndbm_map_open(map, mode) 27660089Seric MAP *map; 27760089Seric int mode; 27860089Seric { 27960089Seric DBM *dbm; 28060089Seric 28160089Seric if (tTd(27, 2)) 28260089Seric printf("ndbm_map_open(%s, %d)\n", map->map_file, mode); 28360089Seric 28460207Seric if (mode == O_RDWR) 28560207Seric mode |= O_CREAT|O_TRUNC; 28660207Seric 28760089Seric /* open the database */ 28860089Seric dbm = dbm_open(map->map_file, mode, DBMMODE); 28956822Seric if (dbm == NULL) 29056822Seric { 29160207Seric if (!bitset(MF_OPTIONAL, map->map_mflags)) 29256836Seric syserr("Cannot open DBM database %s", map->map_file); 29356822Seric return FALSE; 29456822Seric } 29560089Seric map->map_db1 = (void *) dbm; 29660207Seric if (mode == O_RDONLY && bitset(MF_ALIAS, map->map_mflags)) 29760207Seric aliaswait(map, ".dir"); 29856822Seric return TRUE; 29956822Seric } 30060089Seric 30160089Seric 30260089Seric /* 30356822Seric ** DBM_MAP_LOOKUP -- look up a datum in a DBM-type map 30456822Seric */ 30556822Seric 30656822Seric char * 30760089Seric ndbm_map_lookup(map, name, av, statp) 30856822Seric MAP *map; 30960089Seric char *name; 31056822Seric char **av; 31159084Seric int *statp; 31256822Seric { 31356822Seric datum key, val; 31460089Seric char keybuf[MAXNAME + 1]; 31556822Seric 31660089Seric if (tTd(27, 20)) 31760089Seric printf("ndbm_map_lookup(%s)\n", name); 31860089Seric 31960089Seric key.dptr = name; 32060089Seric key.dsize = strlen(name); 32160207Seric if (!bitset(MF_NOFOLDCASE, map->map_mflags)) 32257014Seric { 32360089Seric if (key.dsize > sizeof keybuf - 1) 32460089Seric key.dsize = sizeof keybuf - 1; 32560089Seric bcopy(key.dptr, keybuf, key.dsize + 1); 32660089Seric makelower(keybuf); 32760089Seric key.dptr = keybuf; 32857014Seric } 32960207Seric if (bitset(MF_INCLNULL, map->map_mflags)) 33056822Seric key.dsize++; 33160089Seric (void) lockfile(dbm_dirfno((DBM *) map->map_db1), map->map_file, LOCK_SH); 33260089Seric val = dbm_fetch((DBM *) map->map_db1, key); 33360089Seric (void) lockfile(dbm_dirfno((DBM *) map->map_db1), map->map_file, LOCK_UN); 33456822Seric if (val.dptr == NULL) 33556822Seric return NULL; 33660207Seric if (bitset(MF_MATCHONLY, map->map_mflags)) 33760089Seric av = NULL; 33860089Seric return map_rewrite(map, val.dptr, val.dsize, av); 33956822Seric } 34056822Seric 34156822Seric 34256822Seric /* 34360089Seric ** DBM_MAP_STORE -- store a datum in the database 34456822Seric */ 34556822Seric 34660089Seric void 34760089Seric ndbm_map_store(map, lhs, rhs) 34860089Seric register MAP *map; 34960089Seric char *lhs; 35060089Seric char *rhs; 35160089Seric { 35260089Seric datum key; 35360089Seric datum data; 35460089Seric int stat; 35560089Seric 35660089Seric if (tTd(27, 12)) 35760089Seric printf("ndbm_map_store(%s, %s)\n", lhs, rhs); 35860089Seric 35960089Seric key.dsize = strlen(lhs); 36060089Seric key.dptr = lhs; 36160089Seric 36260089Seric data.dsize = strlen(rhs); 36360089Seric data.dptr = rhs; 36460089Seric 36560207Seric if (bitset(MF_INCLNULL, map->map_mflags)) 36660089Seric { 36760089Seric key.dsize++; 36860089Seric data.dsize++; 36960089Seric } 37060089Seric 37160089Seric stat = dbm_store((DBM *) map->map_db1, key, data, DBM_INSERT); 37260089Seric if (stat > 0) 37360089Seric { 37460089Seric usrerr("050 Warning: duplicate alias name %s", lhs); 37560089Seric stat = dbm_store((DBM *) map->map_db1, key, data, DBM_REPLACE); 37660089Seric } 37760089Seric if (stat != 0) 37860089Seric syserr("readaliases: dbm put (%s)", lhs); 37960089Seric } 38060089Seric 38160089Seric 38260089Seric /* 38360207Seric ** NDBM_MAP_CLOSE -- close the database 38460089Seric */ 38560089Seric 38660089Seric void 38760089Seric ndbm_map_close(map) 38860089Seric register MAP *map; 38960089Seric { 39060207Seric if (bitset(MF_WRITABLE, map->map_mflags)) 39160089Seric { 39260089Seric #ifdef YPCOMPAT 39360089Seric char buf[200]; 39460089Seric 39560089Seric (void) sprintf(buf, "%010ld", curtime()); 39660089Seric ndbm_map_store(map, "YP_LAST_MODIFIED", buf); 39760089Seric 39860089Seric (void) myhostname(buf, sizeof buf); 39960089Seric ndbm_map_store(map, "YP_MASTER_NAME", buf); 40060089Seric #endif 40160089Seric 40260089Seric /* write out the distinguished alias */ 40360089Seric ndbm_map_store(map, "@", "@"); 40460089Seric } 40560089Seric dbm_close((DBM *) map->map_db1); 40660089Seric } 40760089Seric 40860089Seric #endif 40960089Seric /* 41060089Seric ** HASH (NEWDB) Modules 41160089Seric */ 41260089Seric 41360089Seric #ifdef NEWDB 41460089Seric 41560089Seric /* 41660089Seric ** BTREE_MAP_PARSE -- BTREE-style map initialization 41760089Seric */ 41860089Seric 41956822Seric bool 42060089Seric bt_map_open(map, mode) 42156822Seric MAP *map; 42260089Seric int mode; 42356822Seric { 42456822Seric DB *db; 42560089Seric char buf[MAXNAME]; 42656822Seric 42760089Seric if (tTd(27, 2)) 42860089Seric printf("bt_map_open(%s, %d)\n", map->map_file, mode); 42960089Seric 43060207Seric if (mode == O_RDWR) 43160207Seric mode |= O_CREAT|O_TRUNC; 43260207Seric 43360089Seric (void) sprintf(buf, "%s.db", map->map_file); 434*60222Seric db = dbopen(buf, mode, DBMMODE, DB_BTREE, NULL); 43556822Seric if (db == NULL) 43656822Seric { 43760207Seric if (!bitset(MF_OPTIONAL, map->map_mflags)) 43856836Seric syserr("Cannot open BTREE database %s", map->map_file); 43956822Seric return FALSE; 44056822Seric } 44160089Seric map->map_db2 = (void *) db; 44260207Seric if (mode == O_RDONLY && bitset(MF_ALIAS, map->map_mflags)) 44360207Seric aliaswait(map, ".db"); 44456822Seric return TRUE; 44556822Seric } 44656822Seric 44756822Seric 44856822Seric /* 44956822Seric ** HASH_MAP_INIT -- HASH-style map initialization 45056822Seric */ 45156822Seric 45256822Seric bool 45360089Seric hash_map_open(map, mode) 45456822Seric MAP *map; 45560089Seric int mode; 45656822Seric { 45756822Seric DB *db; 45860089Seric char buf[MAXNAME]; 45956822Seric 46060089Seric if (tTd(27, 2)) 46160089Seric printf("hash_map_open(%s, %d)\n", map->map_file, mode); 46260089Seric 46360207Seric if (mode == O_RDWR) 46460207Seric mode |= O_CREAT|O_TRUNC; 46560207Seric 46660089Seric (void) sprintf(buf, "%s.db", map->map_file); 467*60222Seric db = dbopen(buf, mode, DBMMODE, DB_HASH, NULL); 46856822Seric if (db == NULL) 46956822Seric { 47060207Seric if (!bitset(MF_OPTIONAL, map->map_mflags)) 47156836Seric syserr("Cannot open HASH database %s", map->map_file); 47256822Seric return FALSE; 47356822Seric } 47460089Seric map->map_db2 = (void *) db; 47560207Seric if (mode == O_RDONLY && bitset(MF_ALIAS, map->map_mflags)) 47660207Seric aliaswait(map, ".db"); 47756822Seric return TRUE; 47856822Seric } 47956822Seric 48056822Seric 48156822Seric /* 48256822Seric ** DB_MAP_LOOKUP -- look up a datum in a BTREE- or HASH-type map 48356822Seric */ 48456822Seric 48556822Seric char * 48660089Seric db_map_lookup(map, name, av, statp) 48756822Seric MAP *map; 48860089Seric char *name; 48956822Seric char **av; 49059084Seric int *statp; 49156822Seric { 49256822Seric DBT key, val; 49360089Seric char keybuf[MAXNAME + 1]; 49456822Seric 49560089Seric if (tTd(27, 20)) 49660089Seric printf("db_map_lookup(%s)\n", name); 49760089Seric 49860089Seric key.size = strlen(name); 49960089Seric if (key.size > sizeof keybuf - 1) 50060089Seric key.size = sizeof keybuf - 1; 50160089Seric key.data = keybuf; 50260089Seric bcopy(name, keybuf, key.size + 1); 50360207Seric if (!bitset(MF_NOFOLDCASE, map->map_mflags)) 50460089Seric makelower(keybuf); 50560207Seric if (bitset(MF_INCLNULL, map->map_mflags)) 50656822Seric key.size++; 50760089Seric if (((DB *) map->map_db2)->get((DB *) map->map_db2, &key, &val, 0) != 0) 50856822Seric return NULL; 50960207Seric if (bitset(MF_MATCHONLY, map->map_mflags)) 51060089Seric av = NULL; 51160089Seric return map_rewrite(map, val.data, val.size, av); 51256822Seric } 51356822Seric 51460089Seric 51560089Seric /* 51660089Seric ** DB_MAP_STORE -- store a datum in the NEWDB database 51756822Seric */ 51856822Seric 51960089Seric void 52060089Seric db_map_store(map, lhs, rhs) 52160089Seric register MAP *map; 52260089Seric char *lhs; 52360089Seric char *rhs; 52456822Seric { 52560089Seric int stat; 52660089Seric DBT key; 52760089Seric DBT data; 52860089Seric register DB *db = map->map_db2; 52956822Seric 53060089Seric if (tTd(27, 20)) 53160089Seric printf("db_map_store(%s, %s)\n", lhs, rhs); 53260089Seric 53360089Seric key.size = strlen(lhs); 53460089Seric key.data = lhs; 53560089Seric 53660089Seric data.size = strlen(rhs); 53760089Seric data.data = rhs; 53860089Seric 53960207Seric if (bitset(MF_INCLNULL, map->map_mflags)) 54056822Seric { 54160089Seric key.size++; 54260089Seric data.size++; 54360089Seric } 54456836Seric 54560089Seric stat = db->put(db, &key, &data, R_NOOVERWRITE); 54660089Seric if (stat > 0) 54760089Seric { 54860089Seric usrerr("050 Warning: duplicate alias name %s", lhs); 54960089Seric stat = db->put(db, &key, &data, 0); 55060089Seric } 55160089Seric if (stat != 0) 55260089Seric syserr("readaliases: db put (%s)", lhs); 55360089Seric } 55456836Seric 55556847Seric 55660089Seric /* 55760089Seric ** DB_MAP_CLOSE -- add distinguished entries and close the database 55860089Seric */ 55960089Seric 56060089Seric void 56160089Seric db_map_close(map) 56260089Seric MAP *map; 56360089Seric { 56460089Seric register DB *db = map->map_db2; 56560089Seric 56660089Seric if (tTd(27, 9)) 56760207Seric printf("db_map_close(%s, %x)\n", map->map_file, map->map_mflags); 56860089Seric 56960207Seric if (bitset(MF_WRITABLE, map->map_mflags)) 57058804Seric { 57160089Seric /* write out the distinguished alias */ 57260089Seric db_map_store(map, "@", "@"); 57358804Seric } 57458963Seric 57560089Seric if (db->close(db) != 0) 57660089Seric syserr("readaliases: db close failure"); 57756822Seric } 57857208Seric 57960089Seric #endif 58060089Seric /* 58160089Seric ** NIS Modules 58260089Seric */ 58360089Seric 58460089Seric # ifdef NIS 58560089Seric 58657208Seric /* 58760089Seric ** NIS_MAP_OPEN -- open DBM map 58857208Seric */ 58957208Seric 59057208Seric bool 59160089Seric nis_map_open(map, mode) 59257208Seric MAP *map; 59360089Seric int mode; 59457208Seric { 59557216Seric int yperr; 59660215Seric register char *p; 59760215Seric auto char *vp; 59860215Seric auto int vsize; 59957216Seric char *master; 60057216Seric 60160089Seric if (tTd(27, 2)) 60260089Seric printf("nis_map_open(%s)\n", map->map_file); 60360089Seric 60460207Seric if (mode != O_RDONLY) 60560207Seric { 60660207Seric errno = ENODEV; 60760207Seric return FALSE; 60860207Seric } 60960207Seric 61060089Seric p = strchr(map->map_file, '@'); 61160089Seric if (p != NULL) 61260089Seric { 61360089Seric *p++ = '\0'; 61460089Seric if (*p != '\0') 61560089Seric map->map_domain = p; 61660089Seric } 61760215Seric 61860089Seric if (map->map_domain == NULL) 61960089Seric yp_get_default_domain(&map->map_domain); 62060089Seric 62160089Seric if (*map->map_file == '\0') 62260089Seric map->map_file = "mail.aliases"; 62360089Seric 62460215Seric /* check to see if this map actually exists */ 62560089Seric yperr = yp_match(map->map_domain, map->map_file, "@", 1, 62660089Seric &vp, &vsize); 62760089Seric if (tTd(27, 10)) 62860089Seric printf("nis_map_open: yp_match(%s, %s) => %s\n", 62960089Seric map->map_domain, map->map_file, yperr_string(yperr)); 63060089Seric if (yperr == 0 || yperr == YPERR_KEY || yperr == YPERR_BUSY) 63160089Seric return TRUE; 63260215Seric 63360215Seric if (!bitset(MF_OPTIONAL, map->map_mflags)) 63460215Seric syserr("Cannot bind to domain %s: %s", map->map_domain, 63560215Seric yperr_string(yperr)); 63660215Seric 63760089Seric return FALSE; 63860089Seric } 63960089Seric 64060089Seric 64160089Seric /* 64257208Seric ** NIS_MAP_LOOKUP -- look up a datum in a NIS map 64357208Seric */ 64457208Seric 64557208Seric char * 64660089Seric nis_map_lookup(map, name, av, statp) 64757208Seric MAP *map; 64860089Seric char *name; 64957208Seric char **av; 65059084Seric int *statp; 65157208Seric { 65257208Seric char *vp; 65357642Seric auto int vsize; 65459274Seric int buflen; 65560215Seric int yperr; 65660089Seric char keybuf[MAXNAME + 1]; 65757208Seric 65860089Seric if (tTd(27, 20)) 65960089Seric printf("nis_map_lookup(%s)\n", name); 66060089Seric 66160089Seric buflen = strlen(name); 66260089Seric if (buflen > sizeof keybuf - 1) 66360089Seric buflen = sizeof keybuf - 1; 66460089Seric bcopy(name, keybuf, buflen + 1); 66560207Seric if (!bitset(MF_NOFOLDCASE, map->map_mflags)) 66660089Seric makelower(keybuf); 66760207Seric if (bitset(MF_INCLNULL, map->map_mflags)) 66859274Seric buflen++; 66960089Seric yperr = yp_match(map->map_domain, map->map_file, keybuf, buflen, 67060089Seric &vp, &vsize); 67160089Seric if (yperr != 0) 67260089Seric { 67360089Seric if (yperr != YPERR_KEY && yperr != YPERR_BUSY) 67460215Seric map->map_mflags &= ~(MF_VALID|MF_OPEN); 67557208Seric return NULL; 67660089Seric } 67760207Seric if (bitset(MF_MATCHONLY, map->map_mflags)) 67860089Seric av = NULL; 67960215Seric return map_rewrite(map, vp, vsize, av); 68057208Seric } 68157208Seric 68260089Seric 68360089Seric /* 68460207Seric ** NIS_MAP_STORE 68560089Seric */ 68660089Seric 68760089Seric void 68860089Seric nis_map_store(map, lhs, rhs) 68960089Seric MAP *map; 69060089Seric char *lhs; 69160089Seric char *rhs; 69260089Seric { 69360089Seric /* nothing */ 69460089Seric } 69560089Seric 69660089Seric 69760089Seric /* 69860207Seric ** NIS_MAP_CLOSE 69960089Seric */ 70060089Seric 70160089Seric void 70260089Seric nis_map_close(map) 70360089Seric MAP *map; 70460089Seric { 70560089Seric /* nothing */ 70660089Seric } 70760089Seric 70860089Seric #endif /* NIS */ 70957208Seric /* 71060089Seric ** STAB (Symbol Table) Modules 71160089Seric */ 71260089Seric 71360089Seric 71460089Seric /* 71560207Seric ** STAB_MAP_LOOKUP -- look up alias in symbol table 71660089Seric */ 71760089Seric 71860089Seric char * 71960089Seric stab_map_lookup(map, name) 72060089Seric register MAP *map; 72160089Seric char *name; 72260089Seric { 72360089Seric register STAB *s; 72460089Seric 72560089Seric if (tTd(27, 20)) 72660089Seric printf("stab_lookup(%s)\n", name); 72760089Seric 72860089Seric s = stab(name, ST_ALIAS, ST_FIND); 72960089Seric if (s != NULL) 73060089Seric return (s->s_alias); 73160089Seric return (NULL); 73260089Seric } 73360089Seric 73460089Seric 73560089Seric /* 73660207Seric ** STAB_MAP_STORE -- store in symtab (actually using during init, not rebuild) 73760089Seric */ 73860089Seric 73960089Seric void 74060089Seric stab_map_store(map, lhs, rhs) 74160089Seric register MAP *map; 74260089Seric char *lhs; 74360089Seric char *rhs; 74460089Seric { 74560089Seric register STAB *s; 74660089Seric 74760089Seric s = stab(lhs, ST_ALIAS, ST_ENTER); 74860089Seric s->s_alias = newstr(rhs); 74960089Seric } 75060089Seric 75160089Seric 75260089Seric /* 75360207Seric ** STAB_MAP_OPEN -- initialize (reads data file) 75460207Seric ** 75560207Seric ** This is a wierd case -- it is only intended as a fallback for 75660207Seric ** aliases. For this reason, opens for write (only during a 75760207Seric ** "newaliases") always fails, and opens for read open the 75860207Seric ** actual underlying text file instead of the database. 75960089Seric */ 76060089Seric 76160089Seric bool 76260089Seric stab_map_open(map, mode) 76360089Seric register MAP *map; 76460089Seric int mode; 76560089Seric { 76660089Seric FILE *af; 76760089Seric 76860089Seric if (tTd(27, 2)) 76960089Seric printf("stab_map_open(%s)\n", map->map_file); 77060089Seric 77160089Seric if (mode != O_RDONLY) 77260207Seric { 77360207Seric errno = ENODEV; 77460089Seric return FALSE; 77560207Seric } 77660089Seric 77760089Seric return TRUE; 77860089Seric } 77960089Seric 78060089Seric 78160089Seric /* 78260207Seric ** STAB_MAP_CLOSE -- close symbol table (???) 78360089Seric */ 78460089Seric 78560089Seric void 78660089Seric stab_map_close(map) 78760089Seric MAP *map; 78860089Seric { 78960089Seric /* ignore it */ 79060089Seric } 79160089Seric /* 79260089Seric ** Implicit Modules 79356822Seric ** 79460089Seric ** Tries several types. For back compatibility of aliases. 79556822Seric */ 79656822Seric 79760089Seric 79860089Seric /* 79960207Seric ** IMPL_MAP_LOOKUP -- lookup in best open database 80060089Seric */ 80160089Seric 80260089Seric char * 80360089Seric impl_map_lookup(map, name, av, pstat) 80460089Seric MAP *map; 80560089Seric char *name; 80656822Seric char **av; 80760089Seric int *pstat; 80856822Seric { 80960089Seric if (tTd(27, 20)) 81060089Seric printf("impl_map_lookup(%s)\n", name); 81156822Seric 81260089Seric #ifdef NEWDB 81360207Seric if (bitset(MF_IMPL_HASH, map->map_mflags)) 81460089Seric return db_map_lookup(map, name, av, pstat); 81560089Seric #endif 81660089Seric #ifdef NDBM 81760207Seric if (bitset(MF_IMPL_NDBM, map->map_mflags)) 81860089Seric return ndbm_map_lookup(map, name, av, pstat); 81960089Seric #endif 82060089Seric return stab_map_lookup(map, name, av, pstat); 82160089Seric } 82260089Seric 82360089Seric /* 82460207Seric ** IMPL_MAP_STORE -- store in open databases 82560089Seric */ 82660089Seric 82760089Seric void 82860089Seric impl_map_store(map, lhs, rhs) 82960089Seric MAP *map; 83060089Seric char *lhs; 83160089Seric char *rhs; 83260089Seric { 83360089Seric #ifdef NEWDB 83460207Seric if (bitset(MF_IMPL_HASH, map->map_mflags)) 83560089Seric db_map_store(map, lhs, rhs); 83660089Seric #endif 83760089Seric #ifdef NDBM 83860207Seric if (bitset(MF_IMPL_NDBM, map->map_mflags)) 83960089Seric ndbm_map_store(map, lhs, rhs); 84060089Seric #endif 84160089Seric stab_map_store(map, lhs, rhs); 84260089Seric } 84360089Seric 84460089Seric /* 84560089Seric ** IMPL_MAP_OPEN -- implicit database open 84660089Seric */ 84760089Seric 84860089Seric bool 84960089Seric impl_map_open(map, mode) 85060089Seric MAP *map; 85160089Seric int mode; 85260089Seric { 85360089Seric struct stat stb; 85460089Seric 85560089Seric if (tTd(27, 2)) 85660089Seric printf("impl_map_open(%s)\n", map->map_file); 85760089Seric 85860089Seric if (stat(map->map_file, &stb) < 0) 85956822Seric { 86060089Seric /* no alias file at all */ 86160089Seric return FALSE; 86256822Seric } 86356822Seric 86460089Seric #ifdef NEWDB 86560207Seric map->map_mflags |= MF_IMPL_HASH; 86660089Seric if (hash_map_open(map, mode)) 86756822Seric { 86860207Seric #if defined(NDBM) && defined(YPCOMPAT) 86960207Seric if (mode == O_RDONLY || access("/var/yp/Makefile", R_OK) == 0) 87060207Seric #endif 87160207Seric return TRUE; 87260089Seric } 87360207Seric else 87460207Seric map->map_mflags &= ~MF_IMPL_HASH; 87560089Seric #endif 87660089Seric #ifdef NDBM 87760207Seric map->map_mflags |= MF_IMPL_NDBM; 87860089Seric if (ndbm_map_open(map, mode)) 87960089Seric { 88060089Seric return TRUE; 88160089Seric } 88260207Seric else 88360207Seric map->map_mflags &= ~MF_IMPL_NDBM; 88460089Seric #endif 88556822Seric 88660207Seric #if !defined(NEWDB) && !defined(NDBM) 88760089Seric if (Verbose) 88860089Seric message("WARNING: cannot open alias database %s", map->map_file); 88960207Seric #endif 89060089Seric 89160207Seric return stab_map_open(map, mode); 89256822Seric } 89360089Seric 89460207Seric 89560089Seric /* 89660207Seric ** IMPL_MAP_CLOSE -- close any open database(s) 89760089Seric */ 89860089Seric 89960089Seric void 90060207Seric impl_map_close(map) 90160089Seric MAP *map; 90260089Seric { 90360089Seric #ifdef NEWDB 90460207Seric if (bitset(MF_IMPL_HASH, map->map_mflags)) 90560089Seric { 90660207Seric db_map_close(map); 90760207Seric map->map_mflags &= ~MF_IMPL_HASH; 90860089Seric } 90960089Seric #endif 91060089Seric 91160089Seric #ifdef NDBM 91260207Seric if (bitset(MF_IMPL_NDBM, map->map_mflags)) 91360089Seric { 91460207Seric ndbm_map_close(map); 91560207Seric map->map_mflags &= ~MF_IMPL_NDBM; 91660089Seric } 91760089Seric #endif 91860089Seric } 91960207Seric /* 92060207Seric ** NULL stubs 92160089Seric */ 92260089Seric 92360207Seric bool 92460207Seric null_map_open(map, mode) 92560089Seric MAP *map; 92660207Seric int mode; 92760089Seric { 92860207Seric return TRUE; 92960089Seric } 93060089Seric 93160207Seric void 93260207Seric null_map_close(map) 93360207Seric MAP *map; 93460089Seric { 93560207Seric return; 93660207Seric } 93760089Seric 93860207Seric void 93960207Seric null_map_store(map, key, val) 94060207Seric MAP *map; 94160207Seric char *key; 94260207Seric char *val; 94360089Seric { 94460207Seric return; 94560089Seric } 946