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*60089Seric static char sccsid[] = "@(#)map.c 6.14 (Berkeley) 05/17/93"; 1156822Seric #endif /* not lint */ 1256822Seric 1356822Seric #include "sendmail.h" 1456822Seric 15*60089Seric #ifdef NDBM 1656822Seric #include <ndbm.h> 1756822Seric #endif 18*60089Seric #ifdef NEWDB 1956822Seric #include <db.h> 2056822Seric #endif 21*60089Seric #ifdef NIS 2257208Seric #include <rpcsvc/ypclnt.h> 2357208Seric #endif 2456822Seric 2556822Seric /* 26*60089Seric ** MAP.C -- implementations for various map classes. 2756822Seric ** 28*60089Seric ** Each map class implements a series of functions: 29*60089Seric ** 30*60089Seric ** bool map_parse(MAP *map, char *args) 31*60089Seric ** Parse the arguments from the config file. Return TRUE 32*60089Seric ** if they were ok, FALSE otherwise. Fill in map with the 33*60089Seric ** values. 34*60089Seric ** 35*60089Seric ** char *map_lookup(MAP *map, char buf[], int bufsize, 36*60089Seric ** char **args, int *pstat) 37*60089Seric ** Look up the key given in buf in the given map. If found, 38*60089Seric ** do any rewriting the map wants (including "args" if desired) 39*60089Seric ** and return the value. Set *pstat to the appropriate status 40*60089Seric ** on error and return NULL. 41*60089Seric ** 42*60089Seric ** void map_store(MAP *map, char *key, char *value) 43*60089Seric ** Store the key:value pair in the map. 44*60089Seric ** 45*60089Seric ** void map_rebuild(MAP *map, FILE *fp, int automatic) 46*60089Seric ** Rebuild the map. If automatic is set, this is an 47*60089Seric ** auto-rebuild. 48*60089Seric ** 49*60089Seric ** bool map_open(MAP *map, int mode) 50*60089Seric ** Open the map for the indicated mode. Return TRUE if it 51*60089Seric ** was opened successfully, FALSE otherwise. 52*60089Seric ** 53*60089Seric ** void map_close(MAP *map) 54*60089Seric ** Close the map. 55*60089Seric */ 56*60089Seric 57*60089Seric #define DBMMODE 0644 58*60089Seric /* 59*60089Seric ** MAP_PARSEARGS -- parse config line arguments for database lookup 60*60089Seric ** 61*60089Seric ** This is a generic version of the map_parse method. 62*60089Seric ** 6356822Seric ** Parameters: 64*60089Seric ** map -- the map being initialized. 65*60089Seric ** ap -- a pointer to the args on the config line. 6656822Seric ** 6756822Seric ** Returns: 68*60089Seric ** TRUE -- if everything parsed OK. 6956822Seric ** FALSE -- otherwise. 7056822Seric ** 7156822Seric ** Side Effects: 72*60089Seric ** null terminates the filename; stores it in map 7356822Seric */ 7456822Seric 7556822Seric bool 76*60089Seric map_parseargs(map, ap) 7756822Seric MAP *map; 78*60089Seric char *ap; 7956822Seric { 80*60089Seric register char *p = ap; 8156822Seric 82*60089Seric for (;;) 83*60089Seric { 84*60089Seric while (isascii(*p) && isspace(*p)) 85*60089Seric p++; 86*60089Seric if (*p != '-') 87*60089Seric break; 88*60089Seric switch (*++p) 89*60089Seric { 90*60089Seric case 'N': 91*60089Seric map->map_flags |= MF_INCLNULL; 92*60089Seric break; 93*60089Seric 94*60089Seric case 'o': 95*60089Seric map->map_flags |= MF_OPTIONAL; 96*60089Seric break; 97*60089Seric 98*60089Seric case 'f': 99*60089Seric map->map_flags |= MF_NOFOLDCASE; 100*60089Seric break; 101*60089Seric 102*60089Seric case 'm': 103*60089Seric map->map_flags |= MF_MATCHONLY; 104*60089Seric break; 105*60089Seric 106*60089Seric case 'a': 107*60089Seric map->map_app = ++p; 108*60089Seric break; 109*60089Seric 110*60089Seric case 'd': 111*60089Seric map->map_domain = ++p; 112*60089Seric break; 113*60089Seric } 114*60089Seric while (*p != '\0' && !(isascii(*p) && isspace(*p))) 115*60089Seric p++; 116*60089Seric if (*p != '\0') 117*60089Seric *p++ = '\0'; 118*60089Seric } 119*60089Seric if (map->map_app != NULL) 120*60089Seric map->map_app = newstr(map->map_app); 121*60089Seric if (map->map_domain != NULL) 122*60089Seric map->map_domain = newstr(map->map_domain); 123*60089Seric 124*60089Seric if (*p != '\0') 125*60089Seric { 126*60089Seric map->map_file = p; 127*60089Seric while (*p != '\0' && !(isascii(*p) && isspace(*p))) 128*60089Seric p++; 129*60089Seric if (*p != '\0') 130*60089Seric *p++ = '\0'; 131*60089Seric map->map_file = newstr(map->map_file); 132*60089Seric } 133*60089Seric 134*60089Seric while (*p != '\0' && isascii(*p) && isspace(*p)) 135*60089Seric p++; 136*60089Seric if (*p != '\0') 137*60089Seric map->map_rebuild = newstr(p); 138*60089Seric 13956822Seric if (map->map_file == NULL) 14057208Seric { 141*60089Seric syserr("No file name for %s map %s", 142*60089Seric map->map_class->map_cname, map->map_mname); 14356822Seric return FALSE; 14457208Seric } 145*60089Seric return TRUE; 146*60089Seric } 147*60089Seric /* 148*60089Seric ** MAP_REWRITE -- rewrite a database key, interpolating %n indications. 149*60089Seric ** 150*60089Seric ** It also adds the map_app string. It can be used as a utility 151*60089Seric ** in the map_lookup method. 152*60089Seric ** 153*60089Seric ** Parameters: 154*60089Seric ** map -- the map that causes this. 155*60089Seric ** s -- the string to rewrite, NOT necessarily null terminated. 156*60089Seric ** slen -- the length of s. 157*60089Seric ** av -- arguments to interpolate into buf. 158*60089Seric ** 159*60089Seric ** Returns: 160*60089Seric ** Pointer to rewritten result. 161*60089Seric ** 162*60089Seric ** Side Effects: 163*60089Seric ** none. 164*60089Seric */ 165*60089Seric 166*60089Seric char * 167*60089Seric map_rewrite(map, s, slen, av) 168*60089Seric register MAP *map; 169*60089Seric register char *s; 170*60089Seric int slen; 171*60089Seric char **av; 172*60089Seric { 173*60089Seric register char *bp; 174*60089Seric register char c; 175*60089Seric char **avp; 176*60089Seric register char *ap; 177*60089Seric int i; 178*60089Seric int len; 179*60089Seric static int buflen = -1; 180*60089Seric static char *buf = NULL; 181*60089Seric 182*60089Seric if (tTd(23, 1)) 183*60089Seric { 184*60089Seric printf("map_rewrite(%.*s), av =\n", slen, s); 185*60089Seric for (avp = av; *avp != NULL; avp++) 186*60089Seric printf("\t%s\n", *avp); 187*60089Seric } 188*60089Seric 189*60089Seric /* count expected size of output (can safely overestimate) */ 190*60089Seric i = len = slen; 191*60089Seric if (av != NULL) 192*60089Seric { 193*60089Seric bp = s; 194*60089Seric for (i = slen; --i >= 0 && (c = *bp++) != 0; ) 195*60089Seric { 196*60089Seric if (c != '%') 197*60089Seric continue; 198*60089Seric if (--i < 0) 199*60089Seric break; 200*60089Seric c = *bp++; 201*60089Seric if (!(isascii(c) && isdigit(c))) 202*60089Seric continue; 203*60089Seric c -= 0; 204*60089Seric for (avp = av; --c >= 0 && *avp != NULL; avp++) 205*60089Seric continue; 206*60089Seric if (*avp == NULL) 207*60089Seric continue; 208*60089Seric len += strlen(*avp); 209*60089Seric } 210*60089Seric } 211*60089Seric if (map->map_app != NULL) 212*60089Seric len += strlen(map->map_app); 213*60089Seric if (buflen < ++len) 214*60089Seric { 215*60089Seric /* need to malloc additional space */ 216*60089Seric buflen = len; 217*60089Seric if (buf != NULL) 218*60089Seric free(buf); 219*60089Seric buf = xalloc(buflen); 220*60089Seric } 221*60089Seric 222*60089Seric bp = buf; 223*60089Seric if (av == NULL) 224*60089Seric { 225*60089Seric bcopy(s, bp, slen); 226*60089Seric bp += slen; 227*60089Seric } 228*60089Seric else 229*60089Seric { 230*60089Seric while (--slen >= 0 && (c = *s++) != '\0') 231*60089Seric { 232*60089Seric if (c != '%') 233*60089Seric { 234*60089Seric pushc: 235*60089Seric *bp++ = c; 236*60089Seric continue; 237*60089Seric } 238*60089Seric if (--slen < 0 || (c = *s++) == '\0') 239*60089Seric c = '%'; 240*60089Seric if (c == '%') 241*60089Seric goto pushc; 242*60089Seric if (!(isascii(c) && isdigit(c))) 243*60089Seric { 244*60089Seric *bp++ = '%'; 245*60089Seric goto pushc; 246*60089Seric } 247*60089Seric c -= '0'; 248*60089Seric for (avp = av; --c >= 0 && *avp != NULL; avp++) 249*60089Seric continue; 250*60089Seric if (*avp == NULL) 251*60089Seric continue; 252*60089Seric 253*60089Seric /* transliterate argument into output string */ 254*60089Seric for (ap = *avp; (c = *ap++) != '\0'; ) 255*60089Seric *bp++ = c; 256*60089Seric } 257*60089Seric } 258*60089Seric if (map->map_app != NULL) 259*60089Seric strcpy(bp, map->map_app); 260*60089Seric else 261*60089Seric *bp = '\0'; 262*60089Seric if (tTd(23, 1)) 263*60089Seric printf("map_rewrite => %s\n", buf); 264*60089Seric return buf; 265*60089Seric } 266*60089Seric /* 267*60089Seric ** NDBM modules 268*60089Seric */ 269*60089Seric 270*60089Seric #ifdef NDBM 271*60089Seric 272*60089Seric /* 273*60089Seric ** DBM_MAP_OPEN -- DBM-style map open 274*60089Seric */ 275*60089Seric 276*60089Seric bool 277*60089Seric ndbm_map_open(map, mode) 278*60089Seric MAP *map; 279*60089Seric int mode; 280*60089Seric { 281*60089Seric DBM *dbm; 282*60089Seric 283*60089Seric if (tTd(27, 2)) 284*60089Seric printf("ndbm_map_open(%s, %d)\n", map->map_file, mode); 285*60089Seric 286*60089Seric /* open the database */ 287*60089Seric dbm = dbm_open(map->map_file, mode, DBMMODE); 28856822Seric if (dbm == NULL) 28956822Seric { 29056836Seric if (!bitset(MF_OPTIONAL, map->map_flags)) 29156836Seric syserr("Cannot open DBM database %s", map->map_file); 29256822Seric return FALSE; 29356822Seric } 294*60089Seric map->map_db1 = (void *) dbm; 29556822Seric return TRUE; 29656822Seric } 297*60089Seric 298*60089Seric 299*60089Seric /* 30056822Seric ** DBM_MAP_LOOKUP -- look up a datum in a DBM-type map 30156822Seric */ 30256822Seric 30356822Seric char * 304*60089Seric ndbm_map_lookup(map, name, av, statp) 30556822Seric MAP *map; 306*60089Seric char *name; 30756822Seric char **av; 30859084Seric int *statp; 30956822Seric { 31056822Seric datum key, val; 311*60089Seric char keybuf[MAXNAME + 1]; 31256822Seric 313*60089Seric if (tTd(27, 20)) 314*60089Seric printf("ndbm_map_lookup(%s)\n", name); 315*60089Seric 316*60089Seric key.dptr = name; 317*60089Seric key.dsize = strlen(name); 31857033Seric if (!bitset(MF_NOFOLDCASE, map->map_flags)) 31957014Seric { 320*60089Seric if (key.dsize > sizeof keybuf - 1) 321*60089Seric key.dsize = sizeof keybuf - 1; 322*60089Seric bcopy(key.dptr, keybuf, key.dsize + 1); 323*60089Seric makelower(keybuf); 324*60089Seric key.dptr = keybuf; 32557014Seric } 32656822Seric if (bitset(MF_INCLNULL, map->map_flags)) 32756822Seric key.dsize++; 328*60089Seric (void) lockfile(dbm_dirfno((DBM *) map->map_db1), map->map_file, LOCK_SH); 329*60089Seric val = dbm_fetch((DBM *) map->map_db1, key); 330*60089Seric (void) lockfile(dbm_dirfno((DBM *) map->map_db1), map->map_file, LOCK_UN); 33156822Seric if (val.dptr == NULL) 33256822Seric return NULL; 333*60089Seric if (bitset(MF_MATCHONLY, map->map_flags)) 334*60089Seric av = NULL; 335*60089Seric return map_rewrite(map, val.dptr, val.dsize, av); 33656822Seric } 33756822Seric 33856822Seric 33956822Seric /* 340*60089Seric ** DBM_MAP_STORE -- store a datum in the database 34156822Seric */ 34256822Seric 343*60089Seric void 344*60089Seric ndbm_map_store(map, lhs, rhs) 345*60089Seric register MAP *map; 346*60089Seric char *lhs; 347*60089Seric char *rhs; 348*60089Seric { 349*60089Seric datum key; 350*60089Seric datum data; 351*60089Seric int stat; 352*60089Seric 353*60089Seric if (tTd(27, 12)) 354*60089Seric printf("ndbm_map_store(%s, %s)\n", lhs, rhs); 355*60089Seric 356*60089Seric key.dsize = strlen(lhs); 357*60089Seric key.dptr = lhs; 358*60089Seric 359*60089Seric data.dsize = strlen(rhs); 360*60089Seric data.dptr = rhs; 361*60089Seric 362*60089Seric if (bitset(MF_INCLNULL, map->map_flags)) 363*60089Seric { 364*60089Seric key.dsize++; 365*60089Seric data.dsize++; 366*60089Seric } 367*60089Seric 368*60089Seric stat = dbm_store((DBM *) map->map_db1, key, data, DBM_INSERT); 369*60089Seric if (stat > 0) 370*60089Seric { 371*60089Seric usrerr("050 Warning: duplicate alias name %s", lhs); 372*60089Seric stat = dbm_store((DBM *) map->map_db1, key, data, DBM_REPLACE); 373*60089Seric } 374*60089Seric if (stat != 0) 375*60089Seric syserr("readaliases: dbm put (%s)", lhs); 376*60089Seric } 377*60089Seric 378*60089Seric 379*60089Seric /* 380*60089Seric ** DBM_MAP_REBUILD -- rebuild DBM database 381*60089Seric */ 382*60089Seric 383*60089Seric void 384*60089Seric ndbm_map_rebuild(map, fp, automatic) 385*60089Seric register MAP *map; 386*60089Seric FILE *fp; 387*60089Seric int automatic; 388*60089Seric { 389*60089Seric register DBM *db; 390*60089Seric int i; 391*60089Seric char buf[MAXNAME]; 392*60089Seric 393*60089Seric if (tTd(27, 2)) 394*60089Seric printf("ndbm_map_rebuild(%s)\n", map->map_file); 395*60089Seric 396*60089Seric db = dbm_open(map->map_file, O_RDWR|O_CREAT|O_TRUNC, DBMMODE); 397*60089Seric if (db == NULL) 398*60089Seric { 399*60089Seric syserr("ndbm_map_rebuild: cannot create %s", buf); 400*60089Seric return; 401*60089Seric } 402*60089Seric map->map_db1 = (void *) db; 403*60089Seric map->map_flags |= MF_WRITABLE|MF_VALID; 404*60089Seric } 405*60089Seric 406*60089Seric /* 407*60089Seric ** NDBM_ACLOSE -- close the database 408*60089Seric */ 409*60089Seric 410*60089Seric void 411*60089Seric ndbm_map_close(map) 412*60089Seric register MAP *map; 413*60089Seric { 414*60089Seric if (bitset(MF_WRITABLE, map->map_flags)) 415*60089Seric { 416*60089Seric #ifdef YPCOMPAT 417*60089Seric char buf[200]; 418*60089Seric 419*60089Seric (void) sprintf(buf, "%010ld", curtime()); 420*60089Seric ndbm_map_store(map, "YP_LAST_MODIFIED", buf); 421*60089Seric 422*60089Seric (void) myhostname(buf, sizeof buf); 423*60089Seric ndbm_map_store(map, "YP_MASTER_NAME", buf); 424*60089Seric #endif 425*60089Seric 426*60089Seric /* write out the distinguished alias */ 427*60089Seric ndbm_map_store(map, "@", "@"); 428*60089Seric } 429*60089Seric dbm_close((DBM *) map->map_db1); 430*60089Seric } 431*60089Seric 432*60089Seric #endif 433*60089Seric /* 434*60089Seric ** HASH (NEWDB) Modules 435*60089Seric */ 436*60089Seric 437*60089Seric #ifdef NEWDB 438*60089Seric 439*60089Seric /* 440*60089Seric ** BTREE_MAP_PARSE -- BTREE-style map initialization 441*60089Seric */ 442*60089Seric 44356822Seric bool 444*60089Seric bt_map_open(map, mode) 44556822Seric MAP *map; 446*60089Seric int mode; 44756822Seric { 44856822Seric DB *db; 449*60089Seric char buf[MAXNAME]; 45056822Seric 451*60089Seric if (tTd(27, 2)) 452*60089Seric printf("bt_map_open(%s, %d)\n", map->map_file, mode); 453*60089Seric 454*60089Seric (void) sprintf(buf, "%s.db", map->map_file); 455*60089Seric db = dbopen(buf, mode, 0644, DB_BTREE, NULL); 45656822Seric if (db == NULL) 45756822Seric { 45856836Seric if (!bitset(MF_OPTIONAL, map->map_flags)) 45956836Seric syserr("Cannot open BTREE database %s", map->map_file); 46056822Seric return FALSE; 46156822Seric } 462*60089Seric map->map_db2 = (void *) db; 46356822Seric return TRUE; 46456822Seric } 46556822Seric 46656822Seric 46756822Seric /* 46856822Seric ** HASH_MAP_INIT -- HASH-style map initialization 46956822Seric */ 47056822Seric 47156822Seric bool 472*60089Seric hash_map_open(map, mode) 47356822Seric MAP *map; 474*60089Seric int mode; 47556822Seric { 47656822Seric DB *db; 477*60089Seric char buf[MAXNAME]; 47856822Seric 479*60089Seric if (tTd(27, 2)) 480*60089Seric printf("hash_map_open(%s, %d)\n", map->map_file, mode); 481*60089Seric 482*60089Seric (void) sprintf(buf, "%s.db", map->map_file); 483*60089Seric db = dbopen(buf, mode, 0644, DB_HASH, NULL); 48456822Seric if (db == NULL) 48556822Seric { 48656836Seric if (!bitset(MF_OPTIONAL, map->map_flags)) 48756836Seric syserr("Cannot open HASH database %s", map->map_file); 48856822Seric return FALSE; 48956822Seric } 490*60089Seric map->map_db2 = (void *) db; 49156822Seric return TRUE; 49256822Seric } 49356822Seric 49456822Seric 49556822Seric /* 49656822Seric ** DB_MAP_LOOKUP -- look up a datum in a BTREE- or HASH-type map 49756822Seric */ 49856822Seric 49956822Seric char * 500*60089Seric db_map_lookup(map, name, av, statp) 50156822Seric MAP *map; 502*60089Seric char *name; 50356822Seric char **av; 50459084Seric int *statp; 50556822Seric { 50656822Seric DBT key, val; 507*60089Seric char keybuf[MAXNAME + 1]; 50856822Seric 509*60089Seric if (tTd(27, 20)) 510*60089Seric printf("db_map_lookup(%s)\n", name); 511*60089Seric 512*60089Seric key.size = strlen(name); 513*60089Seric if (key.size > sizeof keybuf - 1) 514*60089Seric key.size = sizeof keybuf - 1; 515*60089Seric key.data = keybuf; 516*60089Seric bcopy(name, keybuf, key.size + 1); 51757033Seric if (!bitset(MF_NOFOLDCASE, map->map_flags)) 518*60089Seric makelower(keybuf); 51956822Seric if (bitset(MF_INCLNULL, map->map_flags)) 52056822Seric key.size++; 521*60089Seric if (((DB *) map->map_db2)->get((DB *) map->map_db2, &key, &val, 0) != 0) 52256822Seric return NULL; 523*60089Seric if (bitset(MF_MATCHONLY, map->map_flags)) 524*60089Seric av = NULL; 525*60089Seric return map_rewrite(map, val.data, val.size, av); 52656822Seric } 52756822Seric 528*60089Seric 529*60089Seric /* 530*60089Seric ** DB_MAP_STORE -- store a datum in the NEWDB database 53156822Seric */ 53256822Seric 533*60089Seric void 534*60089Seric db_map_store(map, lhs, rhs) 535*60089Seric register MAP *map; 536*60089Seric char *lhs; 537*60089Seric char *rhs; 53856822Seric { 539*60089Seric int stat; 540*60089Seric DBT key; 541*60089Seric DBT data; 542*60089Seric register DB *db = map->map_db2; 54356822Seric 544*60089Seric if (tTd(27, 20)) 545*60089Seric printf("db_map_store(%s, %s)\n", lhs, rhs); 546*60089Seric 547*60089Seric key.size = strlen(lhs); 548*60089Seric key.data = lhs; 549*60089Seric 550*60089Seric data.size = strlen(rhs); 551*60089Seric data.data = rhs; 552*60089Seric 553*60089Seric if (bitset(MF_INCLNULL, map->map_flags)) 55456822Seric { 555*60089Seric key.size++; 556*60089Seric data.size++; 557*60089Seric } 55856836Seric 559*60089Seric stat = db->put(db, &key, &data, R_NOOVERWRITE); 560*60089Seric if (stat > 0) 561*60089Seric { 562*60089Seric usrerr("050 Warning: duplicate alias name %s", lhs); 563*60089Seric stat = db->put(db, &key, &data, 0); 564*60089Seric } 565*60089Seric if (stat != 0) 566*60089Seric syserr("readaliases: db put (%s)", lhs); 567*60089Seric } 56856836Seric 56956847Seric 570*60089Seric /* 571*60089Seric ** HASH_MAP_REBUILD -- rebuild hash database 572*60089Seric */ 57357208Seric 574*60089Seric void 575*60089Seric db_map_rebuild(map, fp, automatic, e) 576*60089Seric register MAP *map; 577*60089Seric FILE *fp; 578*60089Seric int automatic; 579*60089Seric ENVELOPE *e; 580*60089Seric { 581*60089Seric register DB *db; 582*60089Seric char buf[MAXNAME]; 58357208Seric 584*60089Seric if (tTd(27, 2)) 585*60089Seric printf("hash_map_rebuild(%s)\n", map->map_file); 586*60089Seric 587*60089Seric (void) strcpy(buf, map->map_file); 588*60089Seric (void) strcat(buf, ".db"); 589*60089Seric db = dbopen(buf, O_RDWR|O_CREAT|O_TRUNC, DBMMODE, DB_HASH, NULL); 590*60089Seric if (db == NULL) 591*60089Seric { 592*60089Seric syserr("hash_map_rebuild: cannot create %s", buf); 593*60089Seric return; 59456822Seric } 595*60089Seric map->map_db2 = db; 596*60089Seric map->map_flags |= MF_WRITABLE|MF_VALID; 597*60089Seric } 59856822Seric 599*60089Seric 600*60089Seric /* 601*60089Seric ** DB_MAP_CLOSE -- add distinguished entries and close the database 602*60089Seric */ 603*60089Seric 604*60089Seric void 605*60089Seric db_map_close(map) 606*60089Seric MAP *map; 607*60089Seric { 608*60089Seric register DB *db = map->map_db2; 609*60089Seric 610*60089Seric if (tTd(27, 9)) 611*60089Seric printf("db_map_close(%s, %x)\n", map->map_file, map->map_flags); 612*60089Seric 613*60089Seric if (bitset(MF_WRITABLE, map->map_flags)) 61458804Seric { 615*60089Seric /* write out the distinguished alias */ 616*60089Seric db_map_store(map, "@", "@"); 61758804Seric } 61858963Seric 619*60089Seric if (db->close(db) != 0) 620*60089Seric syserr("readaliases: db close failure"); 62156822Seric } 62257208Seric 623*60089Seric #endif 624*60089Seric /* 625*60089Seric ** NIS Modules 626*60089Seric */ 627*60089Seric 628*60089Seric # ifdef NIS 629*60089Seric 63057208Seric /* 631*60089Seric ** NIS_MAP_OPEN -- open DBM map 63257208Seric */ 63357208Seric 63457208Seric bool 635*60089Seric nis_map_open(map, mode) 63657208Seric MAP *map; 637*60089Seric int mode; 63857208Seric { 63957216Seric int yperr; 64057216Seric char *master; 64157216Seric 642*60089Seric if (tTd(27, 2)) 643*60089Seric printf("nis_map_open(%s)\n", map->map_file); 644*60089Seric 64557208Seric if (map->map_domain == NULL) 64657208Seric yp_get_default_domain(&map->map_domain); 64757216Seric 64857216Seric /* check to see if this map actually exists */ 64957216Seric yperr = yp_master(map->map_domain, map->map_file, &master); 65057216Seric if (yperr == 0) 65157216Seric return TRUE; 65257216Seric if (!bitset(MF_OPTIONAL, map->map_flags)) 65357216Seric syserr("Cannot bind to domain %s: %s", map->map_domain, 65457216Seric yperr_string(yperr)); 65557216Seric return FALSE; 65657208Seric } 657*60089Seric 658*60089Seric bool 659*60089Seric nis_map_open(map, mode) 660*60089Seric MAP *map; 661*60089Seric int mode; 662*60089Seric { 663*60089Seric register char *p; 664*60089Seric int yperr; 665*60089Seric auto char *vp; 666*60089Seric auto int vsize; 667*60089Seric 668*60089Seric p = strchr(map->map_file, '@'); 669*60089Seric if (p != NULL) 670*60089Seric { 671*60089Seric *p++ = '\0'; 672*60089Seric if (*p != '\0') 673*60089Seric map->map_domain = p; 674*60089Seric } 675*60089Seric if (map->map_domain == NULL) 676*60089Seric yp_get_default_domain(&map->map_domain); 677*60089Seric 678*60089Seric if (*map->map_file == '\0') 679*60089Seric map->map_file = "mail.aliases"; 680*60089Seric 681*60089Seric yperr = yp_match(map->map_domain, map->map_file, "@", 1, 682*60089Seric &vp, &vsize); 683*60089Seric if (tTd(27, 10)) 684*60089Seric printf("nis_map_open: yp_match(%s, %s) => %s\n", 685*60089Seric map->map_domain, map->map_file, yperr_string(yperr)); 686*60089Seric if (yperr == 0 || yperr == YPERR_KEY || yperr == YPERR_BUSY) 687*60089Seric return TRUE; 688*60089Seric return FALSE; 689*60089Seric } 690*60089Seric 691*60089Seric 692*60089Seric /* 69357208Seric ** NIS_MAP_LOOKUP -- look up a datum in a NIS map 69457208Seric */ 69557208Seric 69657208Seric char * 697*60089Seric nis_map_lookup(map, name, av, statp) 69857208Seric MAP *map; 699*60089Seric char *name; 70057208Seric char **av; 70159084Seric int *statp; 70257208Seric { 70357208Seric char *vp; 70457642Seric auto int vsize; 70559274Seric int buflen; 706*60089Seric char keybuf[MAXNAME + 1]; 70757208Seric 708*60089Seric if (tTd(27, 20)) 709*60089Seric printf("nis_map_lookup(%s)\n", name); 710*60089Seric 711*60089Seric buflen = strlen(name); 712*60089Seric if (buflen > sizeof keybuf - 1) 713*60089Seric buflen = sizeof keybuf - 1; 714*60089Seric bcopy(name, keybuf, buflen + 1); 71557208Seric if (!bitset(MF_NOFOLDCASE, map->map_flags)) 716*60089Seric makelower(keybuf); 71759274Seric if (bitset(MF_INCLNULL, map->map_flags)) 71859274Seric buflen++; 719*60089Seric yperr = yp_match(map->map_domain, map->map_file, keybuf, buflen, 720*60089Seric &vp, &vsize); 721*60089Seric if (yperr != 0) 722*60089Seric { 723*60089Seric if (yperr != YPERR_KEY && yperr != YPERR_BUSY) 724*60089Seric map->map_flags &= ~MF_VALID; 72557208Seric return NULL; 726*60089Seric } 727*60089Seric if (bitset(MF_MATCHONLY, map->map_flags)) 728*60089Seric av = NULL; 729*60089Seric return map_rewrite(map, val.dptr, val.dsize, av); 73057208Seric } 73157208Seric 732*60089Seric 733*60089Seric /* 734*60089Seric ** NIS_ASTORE 735*60089Seric */ 736*60089Seric 737*60089Seric void 738*60089Seric nis_map_store(map, lhs, rhs) 739*60089Seric MAP *map; 740*60089Seric char *lhs; 741*60089Seric char *rhs; 742*60089Seric { 743*60089Seric /* nothing */ 744*60089Seric } 745*60089Seric 746*60089Seric /* 747*60089Seric ** NIS_AREBUILD 748*60089Seric */ 749*60089Seric 750*60089Seric void 751*60089Seric nis_map_rebuild(map, fp, automatic, e) 752*60089Seric MAP *map; 753*60089Seric FILE *fp; 754*60089Seric int automatic; 755*60089Seric ENVELOPE *e; 756*60089Seric { 757*60089Seric if (tTd(27, 2)) 758*60089Seric printf("nis_map_rebuild(%s)\n", map->map_file); 759*60089Seric } 760*60089Seric 761*60089Seric 762*60089Seric /* 763*60089Seric ** NIS_ACLOSE 764*60089Seric */ 765*60089Seric 766*60089Seric void 767*60089Seric nis_map_close(map) 768*60089Seric MAP *map; 769*60089Seric { 770*60089Seric /* nothing */ 771*60089Seric } 772*60089Seric 773*60089Seric #endif /* NIS */ 77457208Seric /* 775*60089Seric ** STAB (Symbol Table) Modules 776*60089Seric */ 777*60089Seric 778*60089Seric 779*60089Seric /* 780*60089Seric ** STAB_ALOOKUP -- look up alias in symbol table 781*60089Seric */ 782*60089Seric 783*60089Seric char * 784*60089Seric stab_map_lookup(map, name) 785*60089Seric register MAP *map; 786*60089Seric char *name; 787*60089Seric { 788*60089Seric register STAB *s; 789*60089Seric 790*60089Seric if (tTd(27, 20)) 791*60089Seric printf("stab_lookup(%s)\n", name); 792*60089Seric 793*60089Seric s = stab(name, ST_ALIAS, ST_FIND); 794*60089Seric if (s != NULL) 795*60089Seric return (s->s_alias); 796*60089Seric return (NULL); 797*60089Seric } 798*60089Seric 799*60089Seric 800*60089Seric /* 801*60089Seric ** STAB_ASTORE -- store in symtab (actually using during init, not rebuild) 802*60089Seric */ 803*60089Seric 804*60089Seric void 805*60089Seric stab_map_store(map, lhs, rhs) 806*60089Seric register MAP *map; 807*60089Seric char *lhs; 808*60089Seric char *rhs; 809*60089Seric { 810*60089Seric register STAB *s; 811*60089Seric 812*60089Seric s = stab(lhs, ST_ALIAS, ST_ENTER); 813*60089Seric s->s_alias = newstr(rhs); 814*60089Seric } 815*60089Seric 816*60089Seric 817*60089Seric /* 818*60089Seric ** STAB_AINIT -- initialize (reads data file) 819*60089Seric */ 820*60089Seric 821*60089Seric bool 822*60089Seric stab_map_open(map, mode) 823*60089Seric register MAP *map; 824*60089Seric int mode; 825*60089Seric { 826*60089Seric FILE *af; 827*60089Seric 828*60089Seric if (tTd(27, 2)) 829*60089Seric printf("stab_map_open(%s)\n", map->map_file); 830*60089Seric 831*60089Seric if (mode != O_RDONLY) 832*60089Seric return FALSE; 833*60089Seric 834*60089Seric af = fopen(map->map_file, "r"); 835*60089Seric if (af == NULL) 836*60089Seric return FALSE; 837*60089Seric return TRUE; 838*60089Seric } 839*60089Seric 840*60089Seric 841*60089Seric /* 842*60089Seric ** STAB_AREBUILD -- rebuild alias file 843*60089Seric */ 844*60089Seric 845*60089Seric void 846*60089Seric stab_map_rebuild(map, fp, automatic, e) 847*60089Seric MAP *map; 848*60089Seric FILE *fp; 849*60089Seric int automatic; 850*60089Seric ENVELOPE *e; 851*60089Seric { 852*60089Seric if (tTd(27, 2)) 853*60089Seric printf("stab_map_rebuild(%s)\n", map->map_file); 854*60089Seric 855*60089Seric map->map_flags |= MF_WRITABLE|MF_VALID; 856*60089Seric } 857*60089Seric 858*60089Seric 859*60089Seric /* 860*60089Seric ** STAB_ACLOSE -- close symbol table (???) 861*60089Seric */ 862*60089Seric 863*60089Seric void 864*60089Seric stab_map_close(map) 865*60089Seric MAP *map; 866*60089Seric { 867*60089Seric /* ignore it */ 868*60089Seric } 869*60089Seric /* 870*60089Seric ** Implicit Modules 87156822Seric ** 872*60089Seric ** Tries several types. For back compatibility of aliases. 87356822Seric */ 87456822Seric 875*60089Seric 876*60089Seric /* 877*60089Seric ** IMPL_ALOOKUP -- lookup in best open database 878*60089Seric */ 879*60089Seric 880*60089Seric char * 881*60089Seric impl_map_lookup(map, name, av, pstat) 882*60089Seric MAP *map; 883*60089Seric char *name; 88456822Seric char **av; 885*60089Seric int *pstat; 88656822Seric { 887*60089Seric if (tTd(27, 20)) 888*60089Seric printf("impl_map_lookup(%s)\n", name); 88956822Seric 890*60089Seric #ifdef NEWDB 891*60089Seric if (bitset(MF_IMPL_HASH, map->map_flags)) 892*60089Seric return db_map_lookup(map, name, av, pstat); 893*60089Seric #endif 894*60089Seric #ifdef NDBM 895*60089Seric if (bitset(MF_IMPL_NDBM, map->map_flags)) 896*60089Seric return ndbm_map_lookup(map, name, av, pstat); 897*60089Seric #endif 898*60089Seric return stab_map_lookup(map, name, av, pstat); 899*60089Seric } 900*60089Seric 901*60089Seric /* 902*60089Seric ** IMPL_ASTORE -- store in open databases 903*60089Seric */ 904*60089Seric 905*60089Seric void 906*60089Seric impl_map_store(map, lhs, rhs) 907*60089Seric MAP *map; 908*60089Seric char *lhs; 909*60089Seric char *rhs; 910*60089Seric { 911*60089Seric #ifdef NEWDB 912*60089Seric if (bitset(MF_IMPL_HASH, map->map_flags)) 913*60089Seric db_map_store(map, lhs, rhs); 914*60089Seric #endif 915*60089Seric #ifdef NDBM 916*60089Seric if (bitset(MF_IMPL_NDBM, map->map_flags)) 917*60089Seric ndbm_map_store(map, lhs, rhs); 918*60089Seric #endif 919*60089Seric stab_map_store(map, lhs, rhs); 920*60089Seric } 921*60089Seric 922*60089Seric /* 923*60089Seric ** IMPL_MAP_OPEN -- implicit database open 924*60089Seric */ 925*60089Seric 926*60089Seric bool 927*60089Seric impl_map_open(map, mode) 928*60089Seric MAP *map; 929*60089Seric int mode; 930*60089Seric { 931*60089Seric struct stat stb; 932*60089Seric 933*60089Seric if (tTd(27, 2)) 934*60089Seric printf("impl_map_open(%s)\n", map->map_file); 935*60089Seric 936*60089Seric if (stat(map->map_file, &stb) < 0) 93756822Seric { 938*60089Seric /* no alias file at all */ 939*60089Seric return FALSE; 94056822Seric } 94156822Seric 942*60089Seric #ifdef NEWDB 943*60089Seric if (hash_map_open(map, mode)) 94456822Seric { 945*60089Seric map->map_flags |= MF_IMPL_HASH; 946*60089Seric return TRUE; 947*60089Seric } 948*60089Seric #endif 949*60089Seric #ifdef NDBM 950*60089Seric if (ndbm_map_open(map, mode)) 951*60089Seric { 952*60089Seric map->map_flags |= MF_IMPL_NDBM; 953*60089Seric return TRUE; 954*60089Seric } 955*60089Seric #endif 95656822Seric 957*60089Seric if (Verbose) 958*60089Seric message("WARNING: cannot open alias database %s", map->map_file); 959*60089Seric 960*60089Seric if (stab_map_open(map, mode)) 961*60089Seric { 962*60089Seric return TRUE; 96356822Seric } 964*60089Seric 965*60089Seric return FALSE; 96656822Seric } 967*60089Seric 968*60089Seric /* 969*60089Seric ** IMPL_AREBUILD -- rebuild alias database 970*60089Seric */ 971*60089Seric 972*60089Seric void 973*60089Seric impl_map_rebuild(map, fp, automatic, e) 974*60089Seric MAP *map; 975*60089Seric FILE *fp; 976*60089Seric int automatic; 977*60089Seric ENVELOPE *e; 978*60089Seric { 979*60089Seric #ifdef NEWDB 980*60089Seric DB *ndb; 981*60089Seric char buf[MAXNAME]; 982*60089Seric #endif 983*60089Seric 984*60089Seric if (tTd(27, 2)) 985*60089Seric printf("impl_map_rebuild(%s)\n", map->map_file); 986*60089Seric 987*60089Seric #ifdef NEWDB 988*60089Seric (void) strcpy(buf, map->map_file); 989*60089Seric (void) strcat(buf, ".db"); 990*60089Seric ndb = dbopen(buf, O_RDWR|O_CREAT|O_TRUNC, DBMMODE, DB_HASH, NULL); 991*60089Seric if (ndb == NULL) 992*60089Seric { 993*60089Seric syserr("rebuildaliases: cannot create %s", buf); 994*60089Seric } 995*60089Seric else 996*60089Seric { 997*60089Seric map->map_db2 = ndb; 998*60089Seric map->map_flags |= MF_IMPL_HASH; 999*60089Seric #if defined(NDBM) && defined(YPCOMPAT) 1000*60089Seric if (access("/var/yp/Makefile", R_OK) != 0) 1001*60089Seric #endif 1002*60089Seric goto readem; 1003*60089Seric } 1004*60089Seric #endif 1005*60089Seric 1006*60089Seric #ifdef NDBM 1007*60089Seric map->map_db1 = (void *) dbm_open(map->map_file, O_RDWR|O_CREAT|O_TRUNC, DBMMODE); 1008*60089Seric if (map->map_db1 == NULL) 1009*60089Seric { 1010*60089Seric syserr("rebuildaliases: cannot create %s.{pag,dir}", 1011*60089Seric map->map_file); 1012*60089Seric } 1013*60089Seric else 1014*60089Seric { 1015*60089Seric map->map_flags |= MF_IMPL_NDBM; 1016*60089Seric } 1017*60089Seric #endif 1018*60089Seric 1019*60089Seric if (!bitset(MF_IMPL_HASH|MF_IMPL_NDBM, map->map_flags)) 1020*60089Seric return; 1021*60089Seric 1022*60089Seric readem: 1023*60089Seric map->map_flags |= MF_WRITABLE|MF_VALID; 1024*60089Seric } 1025*60089Seric 1026*60089Seric 1027*60089Seric /* 1028*60089Seric ** IMPL_ACLOSE -- close any open database(s) 1029*60089Seric */ 1030*60089Seric 1031*60089Seric void 1032*60089Seric impl_map_close(map, e) 1033*60089Seric MAP *map; 1034*60089Seric ENVELOPE *e; 1035*60089Seric { 1036*60089Seric #ifdef NEWDB 1037*60089Seric if (bitset(MF_IMPL_HASH, map->map_flags)) 1038*60089Seric db_map_close(map, e); 1039*60089Seric #endif 1040*60089Seric 1041*60089Seric #ifdef NDBM 1042*60089Seric if (bitset(MF_IMPL_NDBM, map->map_flags)) 1043*60089Seric ndbm_map_close(map, e); 1044*60089Seric #endif 1045*60089Seric } 1046*60089Seric /* 1047*60089Seric ** SETUPALIASES -- set up aliases classes 1048*60089Seric */ 1049*60089Seric 1050*60089Seric extern bool host_map_init __P((MAP *, char *)); 1051*60089Seric extern char *host_map_lookup __P((MAP *, char *, char **, int *)); 1052*60089Seric 1053*60089Seric extern bool dequote_init __P((MAP *, char *)); 1054*60089Seric extern char *dequote_map __P((MAP *, char *, char **, int *)); 1055*60089Seric 1056*60089Seric #if 0 1057*60089Seric extern bool udb_map_parse __P((MAP *, char *)); 1058*60089Seric extern char *udb_map_lookup __P((MAP *, char *, char **, int *)); 1059*60089Seric #endif 1060*60089Seric 1061*60089Seric static MAPCLASS MapClasses[] = 1062*60089Seric { 1063*60089Seric #ifdef NEWDB 1064*60089Seric { 1065*60089Seric "hash", ".db", map_parseargs, 1066*60089Seric db_map_lookup, db_map_store, 1067*60089Seric db_map_rebuild, hash_map_open, db_map_close, 1068*60089Seric }, 1069*60089Seric 1070*60089Seric { 1071*60089Seric "btree", ".db", map_parseargs, 1072*60089Seric db_map_lookup, db_map_store, 1073*60089Seric db_map_rebuild, bt_map_open, db_map_close, 1074*60089Seric }, 1075*60089Seric #endif 1076*60089Seric 1077*60089Seric #ifdef NDBM 1078*60089Seric { 1079*60089Seric "dbm", ".dir", map_parseargs, 1080*60089Seric ndbm_map_lookup, ndbm_map_store, 1081*60089Seric ndbm_map_rebuild, ndbm_map_open, ndbm_map_close, 1082*60089Seric }, 1083*60089Seric #endif 1084*60089Seric 1085*60089Seric #ifdef NIS 1086*60089Seric { 1087*60089Seric "nis", NULL, map_parseargs, 1088*60089Seric nis_map_lookup, NULL, 1089*60089Seric NULL, nis_map_open, nis_map_close, 1090*60089Seric }, 1091*60089Seric #endif 1092*60089Seric 1093*60089Seric { 1094*60089Seric "stab", NULL, map_parseargs, 1095*60089Seric stab_map_lookup, stab_map_store, 1096*60089Seric NULL, stab_map_open, stab_map_close, 1097*60089Seric }, 1098*60089Seric 1099*60089Seric { 1100*60089Seric "implicit", NULL, map_parseargs, 1101*60089Seric impl_map_lookup, impl_map_store, 1102*60089Seric impl_map_rebuild, impl_map_open, impl_map_close, 1103*60089Seric }, 1104*60089Seric 1105*60089Seric /* host DNS lookup */ 1106*60089Seric { 1107*60089Seric "host", NULL, host_map_init, 1108*60089Seric host_map_lookup, NULL, 1109*60089Seric NULL, NULL, NULL, 1110*60089Seric }, 1111*60089Seric 1112*60089Seric /* dequote map */ 1113*60089Seric { 1114*60089Seric "dequote", NULL, dequote_init, 1115*60089Seric dequote_map, NULL, 1116*60089Seric NULL, NULL, NULL, 1117*60089Seric }, 1118*60089Seric 1119*60089Seric #if 0 1120*60089Seric # ifdef USERDB 1121*60089Seric /* user database */ 1122*60089Seric { 1123*60089Seric "udb", ".db", udb_map_parse, 1124*60089Seric udb_map_lookup, NULL, 1125*60089Seric NULL, NULL, NULL, 1126*60089Seric }, 1127*60089Seric # endif 1128*60089Seric #endif 1129*60089Seric 1130*60089Seric { 1131*60089Seric NULL 1132*60089Seric } 1133*60089Seric }; 1134*60089Seric 1135*60089Seric setupmaps() 1136*60089Seric { 1137*60089Seric register MAPCLASS *mc; 1138*60089Seric register STAB *s; 1139*60089Seric 1140*60089Seric for (mc = MapClasses; mc->map_cname != NULL; mc++) 1141*60089Seric { 1142*60089Seric s = stab(mc->map_cname, ST_MAPCLASS, ST_ENTER); 1143*60089Seric s->s_mapclass = mc; 1144*60089Seric } 1145*60089Seric } 1146