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*60228Seric static char sccsid[] = "@(#)map.c 6.18 (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 ** 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 { 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; 425*60228Seric int i; 42660089Seric char buf[MAXNAME]; 42756822Seric 42860089Seric if (tTd(27, 2)) 42960089Seric printf("bt_map_open(%s, %d)\n", map->map_file, mode); 43060089Seric 43160207Seric if (mode == O_RDWR) 43260207Seric mode |= O_CREAT|O_TRUNC; 43360207Seric 434*60228Seric (void) strcpy(buf, map->map_file); 435*60228Seric i = strlen(buf); 436*60228Seric if (i < 3 || strcmp(&buf[i - 3], ".db") != 0) 437*60228Seric (void) strcat(buf, ".db"); 43860222Seric db = dbopen(buf, mode, DBMMODE, DB_BTREE, NULL); 43956822Seric if (db == NULL) 44056822Seric { 44160207Seric if (!bitset(MF_OPTIONAL, map->map_mflags)) 44256836Seric syserr("Cannot open BTREE database %s", map->map_file); 44356822Seric return FALSE; 44456822Seric } 44560089Seric map->map_db2 = (void *) db; 44660207Seric if (mode == O_RDONLY && bitset(MF_ALIAS, map->map_mflags)) 44760207Seric aliaswait(map, ".db"); 44856822Seric return TRUE; 44956822Seric } 45056822Seric 45156822Seric 45256822Seric /* 45356822Seric ** HASH_MAP_INIT -- HASH-style map initialization 45456822Seric */ 45556822Seric 45656822Seric bool 45760089Seric hash_map_open(map, mode) 45856822Seric MAP *map; 45960089Seric int mode; 46056822Seric { 46156822Seric DB *db; 462*60228Seric int i; 46360089Seric char buf[MAXNAME]; 46456822Seric 46560089Seric if (tTd(27, 2)) 46660089Seric printf("hash_map_open(%s, %d)\n", map->map_file, mode); 46760089Seric 46860207Seric if (mode == O_RDWR) 46960207Seric mode |= O_CREAT|O_TRUNC; 47060207Seric 471*60228Seric (void) strcpy(buf, map->map_file); 472*60228Seric i = strlen(buf); 473*60228Seric if (i < 3 || strcmp(&buf[i - 3], ".db") != 0) 474*60228Seric (void) strcat(buf, ".db"); 47560222Seric db = dbopen(buf, mode, DBMMODE, DB_HASH, NULL); 47656822Seric if (db == NULL) 47756822Seric { 47860207Seric if (!bitset(MF_OPTIONAL, map->map_mflags)) 47956836Seric syserr("Cannot open HASH database %s", map->map_file); 48056822Seric return FALSE; 48156822Seric } 48260089Seric map->map_db2 = (void *) db; 48360207Seric if (mode == O_RDONLY && bitset(MF_ALIAS, map->map_mflags)) 48460207Seric aliaswait(map, ".db"); 48556822Seric return TRUE; 48656822Seric } 48756822Seric 48856822Seric 48956822Seric /* 49056822Seric ** DB_MAP_LOOKUP -- look up a datum in a BTREE- or HASH-type map 49156822Seric */ 49256822Seric 49356822Seric char * 49460089Seric db_map_lookup(map, name, av, statp) 49556822Seric MAP *map; 49660089Seric char *name; 49756822Seric char **av; 49859084Seric int *statp; 49956822Seric { 50056822Seric DBT key, val; 50160089Seric char keybuf[MAXNAME + 1]; 50256822Seric 50360089Seric if (tTd(27, 20)) 50460089Seric printf("db_map_lookup(%s)\n", name); 50560089Seric 50660089Seric key.size = strlen(name); 50760089Seric if (key.size > sizeof keybuf - 1) 50860089Seric key.size = sizeof keybuf - 1; 50960089Seric key.data = keybuf; 51060089Seric bcopy(name, keybuf, key.size + 1); 51160207Seric if (!bitset(MF_NOFOLDCASE, map->map_mflags)) 51260089Seric makelower(keybuf); 51360207Seric if (bitset(MF_INCLNULL, map->map_mflags)) 51456822Seric key.size++; 51560089Seric if (((DB *) map->map_db2)->get((DB *) map->map_db2, &key, &val, 0) != 0) 51656822Seric return NULL; 51760207Seric if (bitset(MF_MATCHONLY, map->map_mflags)) 51860089Seric av = NULL; 51960089Seric return map_rewrite(map, val.data, val.size, av); 52056822Seric } 52156822Seric 52260089Seric 52360089Seric /* 52460089Seric ** DB_MAP_STORE -- store a datum in the NEWDB database 52556822Seric */ 52656822Seric 52760089Seric void 52860089Seric db_map_store(map, lhs, rhs) 52960089Seric register MAP *map; 53060089Seric char *lhs; 53160089Seric char *rhs; 53256822Seric { 53360089Seric int stat; 53460089Seric DBT key; 53560089Seric DBT data; 53660089Seric register DB *db = map->map_db2; 53756822Seric 53860089Seric if (tTd(27, 20)) 53960089Seric printf("db_map_store(%s, %s)\n", lhs, rhs); 54060089Seric 54160089Seric key.size = strlen(lhs); 54260089Seric key.data = lhs; 54360089Seric 54460089Seric data.size = strlen(rhs); 54560089Seric data.data = rhs; 54660089Seric 54760207Seric if (bitset(MF_INCLNULL, map->map_mflags)) 54856822Seric { 54960089Seric key.size++; 55060089Seric data.size++; 55160089Seric } 55256836Seric 55360089Seric stat = db->put(db, &key, &data, R_NOOVERWRITE); 55460089Seric if (stat > 0) 55560089Seric { 55660089Seric usrerr("050 Warning: duplicate alias name %s", lhs); 55760089Seric stat = db->put(db, &key, &data, 0); 55860089Seric } 55960089Seric if (stat != 0) 56060089Seric syserr("readaliases: db put (%s)", lhs); 56160089Seric } 56256836Seric 56356847Seric 56460089Seric /* 56560089Seric ** DB_MAP_CLOSE -- add distinguished entries and close the database 56660089Seric */ 56760089Seric 56860089Seric void 56960089Seric db_map_close(map) 57060089Seric MAP *map; 57160089Seric { 57260089Seric register DB *db = map->map_db2; 57360089Seric 57460089Seric if (tTd(27, 9)) 57560207Seric printf("db_map_close(%s, %x)\n", map->map_file, map->map_mflags); 57660089Seric 57760207Seric if (bitset(MF_WRITABLE, map->map_mflags)) 57858804Seric { 57960089Seric /* write out the distinguished alias */ 58060089Seric db_map_store(map, "@", "@"); 58158804Seric } 58258963Seric 58360089Seric if (db->close(db) != 0) 58460089Seric syserr("readaliases: db close failure"); 58556822Seric } 58657208Seric 58760089Seric #endif 58860089Seric /* 58960089Seric ** NIS Modules 59060089Seric */ 59160089Seric 59260089Seric # ifdef NIS 59360089Seric 59457208Seric /* 59560089Seric ** NIS_MAP_OPEN -- open DBM map 59657208Seric */ 59757208Seric 59857208Seric bool 59960089Seric nis_map_open(map, mode) 60057208Seric MAP *map; 60160089Seric int mode; 60257208Seric { 60357216Seric int yperr; 60460215Seric register char *p; 60560215Seric auto char *vp; 60660215Seric auto int vsize; 60757216Seric char *master; 60857216Seric 60960089Seric if (tTd(27, 2)) 61060089Seric printf("nis_map_open(%s)\n", map->map_file); 61160089Seric 61260207Seric if (mode != O_RDONLY) 61360207Seric { 61460207Seric errno = ENODEV; 61560207Seric return FALSE; 61660207Seric } 61760207Seric 61860089Seric p = strchr(map->map_file, '@'); 61960089Seric if (p != NULL) 62060089Seric { 62160089Seric *p++ = '\0'; 62260089Seric if (*p != '\0') 62360089Seric map->map_domain = p; 62460089Seric } 62560215Seric 62660089Seric if (map->map_domain == NULL) 62760089Seric yp_get_default_domain(&map->map_domain); 62860089Seric 62960089Seric if (*map->map_file == '\0') 63060089Seric map->map_file = "mail.aliases"; 63160089Seric 63260215Seric /* check to see if this map actually exists */ 63360089Seric yperr = yp_match(map->map_domain, map->map_file, "@", 1, 63460089Seric &vp, &vsize); 63560089Seric if (tTd(27, 10)) 63660089Seric printf("nis_map_open: yp_match(%s, %s) => %s\n", 63760089Seric map->map_domain, map->map_file, yperr_string(yperr)); 63860089Seric if (yperr == 0 || yperr == YPERR_KEY || yperr == YPERR_BUSY) 63960089Seric return TRUE; 64060215Seric 64160215Seric if (!bitset(MF_OPTIONAL, map->map_mflags)) 64260215Seric syserr("Cannot bind to domain %s: %s", map->map_domain, 64360215Seric yperr_string(yperr)); 64460215Seric 64560089Seric return FALSE; 64660089Seric } 64760089Seric 64860089Seric 64960089Seric /* 65057208Seric ** NIS_MAP_LOOKUP -- look up a datum in a NIS map 65157208Seric */ 65257208Seric 65357208Seric char * 65460089Seric nis_map_lookup(map, name, av, statp) 65557208Seric MAP *map; 65660089Seric char *name; 65757208Seric char **av; 65859084Seric int *statp; 65957208Seric { 66057208Seric char *vp; 66157642Seric auto int vsize; 66259274Seric int buflen; 66360215Seric int yperr; 66460089Seric char keybuf[MAXNAME + 1]; 66557208Seric 66660089Seric if (tTd(27, 20)) 66760089Seric printf("nis_map_lookup(%s)\n", name); 66860089Seric 66960089Seric buflen = strlen(name); 67060089Seric if (buflen > sizeof keybuf - 1) 67160089Seric buflen = sizeof keybuf - 1; 67260089Seric bcopy(name, keybuf, buflen + 1); 67360207Seric if (!bitset(MF_NOFOLDCASE, map->map_mflags)) 67460089Seric makelower(keybuf); 67560207Seric if (bitset(MF_INCLNULL, map->map_mflags)) 67659274Seric buflen++; 67760089Seric yperr = yp_match(map->map_domain, map->map_file, keybuf, buflen, 67860089Seric &vp, &vsize); 67960089Seric if (yperr != 0) 68060089Seric { 68160089Seric if (yperr != YPERR_KEY && yperr != YPERR_BUSY) 68260215Seric map->map_mflags &= ~(MF_VALID|MF_OPEN); 68357208Seric return NULL; 68460089Seric } 68560207Seric if (bitset(MF_MATCHONLY, map->map_mflags)) 68660089Seric av = NULL; 68760215Seric return map_rewrite(map, vp, vsize, av); 68857208Seric } 68957208Seric 69060089Seric 69160089Seric /* 69260207Seric ** NIS_MAP_STORE 69360089Seric */ 69460089Seric 69560089Seric void 69660089Seric nis_map_store(map, lhs, rhs) 69760089Seric MAP *map; 69860089Seric char *lhs; 69960089Seric char *rhs; 70060089Seric { 70160089Seric /* nothing */ 70260089Seric } 70360089Seric 70460089Seric 70560089Seric /* 70660207Seric ** NIS_MAP_CLOSE 70760089Seric */ 70860089Seric 70960089Seric void 71060089Seric nis_map_close(map) 71160089Seric MAP *map; 71260089Seric { 71360089Seric /* nothing */ 71460089Seric } 71560089Seric 71660089Seric #endif /* NIS */ 71757208Seric /* 71860089Seric ** STAB (Symbol Table) Modules 71960089Seric */ 72060089Seric 72160089Seric 72260089Seric /* 72360207Seric ** STAB_MAP_LOOKUP -- look up alias in symbol table 72460089Seric */ 72560089Seric 72660089Seric char * 72760089Seric stab_map_lookup(map, name) 72860089Seric register MAP *map; 72960089Seric char *name; 73060089Seric { 73160089Seric register STAB *s; 73260089Seric 73360089Seric if (tTd(27, 20)) 73460089Seric printf("stab_lookup(%s)\n", name); 73560089Seric 73660089Seric s = stab(name, ST_ALIAS, ST_FIND); 73760089Seric if (s != NULL) 73860089Seric return (s->s_alias); 73960089Seric return (NULL); 74060089Seric } 74160089Seric 74260089Seric 74360089Seric /* 74460207Seric ** STAB_MAP_STORE -- store in symtab (actually using during init, not rebuild) 74560089Seric */ 74660089Seric 74760089Seric void 74860089Seric stab_map_store(map, lhs, rhs) 74960089Seric register MAP *map; 75060089Seric char *lhs; 75160089Seric char *rhs; 75260089Seric { 75360089Seric register STAB *s; 75460089Seric 75560089Seric s = stab(lhs, ST_ALIAS, ST_ENTER); 75660089Seric s->s_alias = newstr(rhs); 75760089Seric } 75860089Seric 75960089Seric 76060089Seric /* 76160207Seric ** STAB_MAP_OPEN -- initialize (reads data file) 76260207Seric ** 76360207Seric ** This is a wierd case -- it is only intended as a fallback for 76460207Seric ** aliases. For this reason, opens for write (only during a 76560207Seric ** "newaliases") always fails, and opens for read open the 76660207Seric ** actual underlying text file instead of the database. 76760089Seric */ 76860089Seric 76960089Seric bool 77060089Seric stab_map_open(map, mode) 77160089Seric register MAP *map; 77260089Seric int mode; 77360089Seric { 77460089Seric FILE *af; 77560089Seric 77660089Seric if (tTd(27, 2)) 77760089Seric printf("stab_map_open(%s)\n", map->map_file); 77860089Seric 77960089Seric if (mode != O_RDONLY) 78060207Seric { 78160207Seric errno = ENODEV; 78260089Seric return FALSE; 78360207Seric } 78460089Seric 78560089Seric return TRUE; 78660089Seric } 78760089Seric 78860089Seric 78960089Seric /* 79060207Seric ** STAB_MAP_CLOSE -- close symbol table (???) 79160089Seric */ 79260089Seric 79360089Seric void 79460089Seric stab_map_close(map) 79560089Seric MAP *map; 79660089Seric { 79760089Seric /* ignore it */ 79860089Seric } 79960089Seric /* 80060089Seric ** Implicit Modules 80156822Seric ** 80260089Seric ** Tries several types. For back compatibility of aliases. 80356822Seric */ 80456822Seric 80560089Seric 80660089Seric /* 80760207Seric ** IMPL_MAP_LOOKUP -- lookup in best open database 80860089Seric */ 80960089Seric 81060089Seric char * 81160089Seric impl_map_lookup(map, name, av, pstat) 81260089Seric MAP *map; 81360089Seric char *name; 81456822Seric char **av; 81560089Seric int *pstat; 81656822Seric { 81760089Seric if (tTd(27, 20)) 81860089Seric printf("impl_map_lookup(%s)\n", name); 81956822Seric 82060089Seric #ifdef NEWDB 82160207Seric if (bitset(MF_IMPL_HASH, map->map_mflags)) 82260089Seric return db_map_lookup(map, name, av, pstat); 82360089Seric #endif 82460089Seric #ifdef NDBM 82560207Seric if (bitset(MF_IMPL_NDBM, map->map_mflags)) 82660089Seric return ndbm_map_lookup(map, name, av, pstat); 82760089Seric #endif 82860089Seric return stab_map_lookup(map, name, av, pstat); 82960089Seric } 83060089Seric 83160089Seric /* 83260207Seric ** IMPL_MAP_STORE -- store in open databases 83360089Seric */ 83460089Seric 83560089Seric void 83660089Seric impl_map_store(map, lhs, rhs) 83760089Seric MAP *map; 83860089Seric char *lhs; 83960089Seric char *rhs; 84060089Seric { 84160089Seric #ifdef NEWDB 84260207Seric if (bitset(MF_IMPL_HASH, map->map_mflags)) 84360089Seric db_map_store(map, lhs, rhs); 84460089Seric #endif 84560089Seric #ifdef NDBM 84660207Seric if (bitset(MF_IMPL_NDBM, map->map_mflags)) 84760089Seric ndbm_map_store(map, lhs, rhs); 84860089Seric #endif 84960089Seric stab_map_store(map, lhs, rhs); 85060089Seric } 85160089Seric 85260089Seric /* 85360089Seric ** IMPL_MAP_OPEN -- implicit database open 85460089Seric */ 85560089Seric 85660089Seric bool 85760089Seric impl_map_open(map, mode) 85860089Seric MAP *map; 85960089Seric int mode; 86060089Seric { 86160089Seric struct stat stb; 86260089Seric 86360089Seric if (tTd(27, 2)) 86460089Seric printf("impl_map_open(%s)\n", map->map_file); 86560089Seric 86660089Seric if (stat(map->map_file, &stb) < 0) 86756822Seric { 86860089Seric /* no alias file at all */ 86960089Seric return FALSE; 87056822Seric } 87156822Seric 87260089Seric #ifdef NEWDB 87360207Seric map->map_mflags |= MF_IMPL_HASH; 87460089Seric if (hash_map_open(map, mode)) 87556822Seric { 87660207Seric #if defined(NDBM) && defined(YPCOMPAT) 87760207Seric if (mode == O_RDONLY || access("/var/yp/Makefile", R_OK) == 0) 87860207Seric #endif 87960207Seric return TRUE; 88060089Seric } 88160207Seric else 88260207Seric map->map_mflags &= ~MF_IMPL_HASH; 88360089Seric #endif 88460089Seric #ifdef NDBM 88560207Seric map->map_mflags |= MF_IMPL_NDBM; 88660089Seric if (ndbm_map_open(map, mode)) 88760089Seric { 88860089Seric return TRUE; 88960089Seric } 89060207Seric else 89160207Seric map->map_mflags &= ~MF_IMPL_NDBM; 89260089Seric #endif 89356822Seric 89460207Seric #if !defined(NEWDB) && !defined(NDBM) 89560089Seric if (Verbose) 89660089Seric message("WARNING: cannot open alias database %s", map->map_file); 89760207Seric #endif 89860089Seric 89960207Seric return stab_map_open(map, mode); 90056822Seric } 90160089Seric 90260207Seric 90360089Seric /* 90460207Seric ** IMPL_MAP_CLOSE -- close any open database(s) 90560089Seric */ 90660089Seric 90760089Seric void 90860207Seric impl_map_close(map) 90960089Seric MAP *map; 91060089Seric { 91160089Seric #ifdef NEWDB 91260207Seric if (bitset(MF_IMPL_HASH, map->map_mflags)) 91360089Seric { 91460207Seric db_map_close(map); 91560207Seric map->map_mflags &= ~MF_IMPL_HASH; 91660089Seric } 91760089Seric #endif 91860089Seric 91960089Seric #ifdef NDBM 92060207Seric if (bitset(MF_IMPL_NDBM, map->map_mflags)) 92160089Seric { 92260207Seric ndbm_map_close(map); 92360207Seric map->map_mflags &= ~MF_IMPL_NDBM; 92460089Seric } 92560089Seric #endif 92660089Seric } 92760207Seric /* 92860207Seric ** NULL stubs 92960089Seric */ 93060089Seric 93160207Seric bool 93260207Seric null_map_open(map, mode) 93360089Seric MAP *map; 93460207Seric int mode; 93560089Seric { 93660207Seric return TRUE; 93760089Seric } 93860089Seric 93960207Seric void 94060207Seric null_map_close(map) 94160207Seric MAP *map; 94260089Seric { 94360207Seric return; 94460207Seric } 94560089Seric 94660207Seric void 94760207Seric null_map_store(map, key, val) 94860207Seric MAP *map; 94960207Seric char *key; 95060207Seric char *val; 95160089Seric { 95260207Seric return; 95360089Seric } 954