144926Smckusick /* 2*47533Spendry * $Id: mk-amd-map.c,v 5.2.1.2 91/03/17 17:37:27 jsp Alpha $ 344926Smckusick * 444926Smckusick * Copyright (c) 1990 Jan-Simon Pendry 544926Smckusick * Copyright (c) 1990 Imperial College of Science, Technology & Medicine 644926Smckusick * Copyright (c) 1990 The Regents of the University of California. 744926Smckusick * All rights reserved. 844926Smckusick * 944926Smckusick * This code is derived from software contributed to Berkeley by 1044926Smckusick * Jan-Simon Pendry at Imperial College, London. 1144926Smckusick * 1244926Smckusick * %sccs.include.redist.c% 1344926Smckusick * 14*47533Spendry * @(#)mk-amd-map.c 5.3 (Berkeley) 03/17/91 1544926Smckusick */ 1644926Smckusick 1744926Smckusick /* 1844926Smckusick * Convert a file map into an ndbm map 1944926Smckusick */ 2044926Smckusick 2144926Smckusick #ifndef lint 2244926Smckusick char copyright[] = "\ 2344926Smckusick @(#)Copyright (c) 1990 Jan-Simon Pendry\n\ 2444926Smckusick @(#)Copyright (c) 1990 Imperial College of Science, Technology & Medicine\n\ 2544926Smckusick @(#)Copyright (c) 1990 The Regents of the University of California.\n\ 2644926Smckusick @(#)All rights reserved.\n"; 2744926Smckusick #endif /* not lint */ 2844926Smckusick 2944926Smckusick #ifndef lint 30*47533Spendry static char rcsid[] = "$Id: mk-amd-map.c,v 5.2.1.2 91/03/17 17:37:27 jsp Alpha $"; 31*47533Spendry static char sccsid[] = "@(#)mk-amd-map.c 5.3 (Berkeley) 03/17/91"; 3244926Smckusick #endif /* not lint */ 3344926Smckusick 3444926Smckusick #include "am.h" 3544926Smckusick 36*47533Spendry #ifndef SIGINT 37*47533Spendry #include <signal.h> 38*47533Spendry #endif 3944926Smckusick 4044926Smckusick #ifdef OS_HAS_NDBM 4144926Smckusick #define HAS_DATABASE 4244926Smckusick #include <ndbm.h> 4344926Smckusick 4444926Smckusick #define create_database(name) dbm_open(name, O_RDWR|O_CREAT, 0444) 4544926Smckusick 4644926Smckusick static int store_data(db, k, v) 4744926Smckusick voidp db; 4844926Smckusick char *k, *v; 4944926Smckusick { 5044926Smckusick datum key, val; 5144926Smckusick 5244926Smckusick key.dptr = k; val.dptr = v; 5344926Smckusick key.dsize = strlen(k) + 1; 5444926Smckusick val.dsize = strlen(v) + 1; 5544926Smckusick return dbm_store((DBM *) db, key, val, DBM_INSERT); 5644926Smckusick } 5744926Smckusick 5844926Smckusick #endif /* OS_HAS_NDBM */ 5944926Smckusick 6044926Smckusick #ifdef HAS_DATABASE 6144926Smckusick #include <fcntl.h> 6244926Smckusick #include <ctype.h> 6344926Smckusick 6444926Smckusick static int read_line(buf, size, fp) 6544926Smckusick char *buf; 6644926Smckusick int size; 6744926Smckusick FILE *fp; 6844926Smckusick { 6944926Smckusick int done = 0; 7044926Smckusick 7144926Smckusick do { 7244926Smckusick while (fgets(buf, size, fp)) { 7344926Smckusick int len = strlen(buf); 7444926Smckusick done += len; 7544926Smckusick if (len > 1 && buf[len-2] == '\\' && 7644926Smckusick buf[len-1] == '\n') { 7744926Smckusick int ch; 7844926Smckusick buf += len - 2; 7944926Smckusick size -= len - 2; 8044926Smckusick /* 8144926Smckusick * Skip leading white space on next line 8244926Smckusick */ 8344926Smckusick while ((ch = getc(fp)) != EOF && 8444926Smckusick isascii(ch) && isspace(ch)) 8544926Smckusick ; 8644926Smckusick (void) ungetc(ch, fp); 8744926Smckusick } else { 8844926Smckusick return done; 8944926Smckusick } 9044926Smckusick } 9144926Smckusick } while (size > 0 && !feof(fp)); 9244926Smckusick 9344926Smckusick return done; 9444926Smckusick } 9544926Smckusick 9644926Smckusick /* 9744926Smckusick * Read through a map 9844926Smckusick */ 9944926Smckusick static int read_file(fp, map, db) 10044926Smckusick FILE *fp; 10144926Smckusick char *map; 10244926Smckusick voidp db; 10344926Smckusick { 10444926Smckusick char key_val[2048]; 10544926Smckusick int chuck = 0; 10644926Smckusick int line_no = 0; 10744926Smckusick int errs = 0; 10844926Smckusick 10944926Smckusick while (read_line(key_val, sizeof(key_val), fp)) { 11044926Smckusick char *kp; 11144926Smckusick char *cp; 11244926Smckusick char *hash; 11344926Smckusick int len = strlen(key_val); 11444926Smckusick line_no++; 11544926Smckusick 11644926Smckusick /* 11744926Smckusick * Make sure we got the whole line 11844926Smckusick */ 11944926Smckusick if (key_val[len-1] != '\n') { 12044926Smckusick fprintf(stderr, "line %d in \"%s\" is too long", line_no, map); 12144926Smckusick chuck = 1; 12244926Smckusick } else { 12344926Smckusick key_val[len-1] = '\0'; 12444926Smckusick } 12544926Smckusick 12644926Smckusick /* 12744926Smckusick * Strip comments 12844926Smckusick */ 12944926Smckusick hash = strchr(key_val, '#'); 13044926Smckusick if (hash) 13144926Smckusick *hash = '\0'; 13244926Smckusick 13344926Smckusick /* 13444926Smckusick * Find start of key 13544926Smckusick */ 13644926Smckusick for (kp = key_val; *kp && isascii(*kp) && isspace(*kp); kp++) 13744926Smckusick ; 13844926Smckusick 13944926Smckusick /* 14044926Smckusick * Ignore blank lines 14144926Smckusick */ 14244926Smckusick if (!*kp) 14344926Smckusick goto again; 14444926Smckusick 14544926Smckusick /* 14644926Smckusick * Find end of key 14744926Smckusick */ 14844926Smckusick for (cp = kp; *cp&&(!isascii(*cp)||!isspace(*cp)); cp++) 14944926Smckusick ; 15044926Smckusick 15144926Smckusick /* 15244926Smckusick * Check whether key matches, or whether 15344926Smckusick * the entry is a wildcard entry. 15444926Smckusick */ 15544926Smckusick if (*cp) 15644926Smckusick *cp++ = '\0'; 15744926Smckusick while (*cp && isascii(*cp) && isspace(*cp)) 15844926Smckusick cp++; 15944926Smckusick if (*kp == '+') { 16044926Smckusick fprintf(stderr, "Can't interpolate %s\n", kp); 16144926Smckusick errs++; 16244926Smckusick } else if (*cp) { 163*47533Spendry if (db) { 164*47533Spendry if (store_data(db, kp, cp) < 0) { 165*47533Spendry fprintf(stderr, "Could store %s -> %s\n", kp, cp); 166*47533Spendry errs++; 167*47533Spendry } 168*47533Spendry } else { 169*47533Spendry printf("%s\t%s\n", kp, cp); 17044926Smckusick } 17144926Smckusick } else { 17244926Smckusick fprintf(stderr, "%s: line %d has no value field", map, line_no); 17344926Smckusick errs++; 17444926Smckusick } 17544926Smckusick 17644926Smckusick again: 17744926Smckusick /* 17844926Smckusick * If the last read didn't get a whole line then 17944926Smckusick * throw away the remainder before continuing... 18044926Smckusick */ 18144926Smckusick if (chuck) { 18244926Smckusick while (fgets(key_val, sizeof(key_val), fp) && 18344926Smckusick !strchr(key_val, '\n')) 18444926Smckusick ; 18544926Smckusick chuck = 0; 18644926Smckusick } 18744926Smckusick } 18844926Smckusick return errs; 18944926Smckusick } 19044926Smckusick 191*47533Spendry static int remove_file(f) 19244926Smckusick char *f; 19344926Smckusick { 19444926Smckusick if (unlink(f) < 0 && errno != ENOENT) 19544926Smckusick return -1; 19644926Smckusick return 0; 19744926Smckusick } 19844926Smckusick 19944926Smckusick main(argc, argv) 20044926Smckusick int argc; 20144926Smckusick char *argv[]; 20244926Smckusick { 20344926Smckusick FILE *mapf; 20444926Smckusick char *map; 20544926Smckusick int rc = 0; 20644926Smckusick DBM *mapd; 207*47533Spendry char *maptmp = "dbmXXXXXX"; 20844926Smckusick char maptpag[16], maptdir[16]; 20944926Smckusick char *mappag, *mapdir; 21044926Smckusick int len; 21144926Smckusick char *sl; 212*47533Spendry int printit = 0; 213*47533Spendry int usage = 0; 214*47533Spendry int ch; 215*47533Spendry extern int optind; 21644926Smckusick 217*47533Spendry while ((ch = getopt(argc, argv, "p")) != EOF) 218*47533Spendry switch (ch) { 219*47533Spendry case 'p': 220*47533Spendry printit = 1; 221*47533Spendry break; 222*47533Spendry default: 223*47533Spendry usage++; 224*47533Spendry break; 225*47533Spendry } 226*47533Spendry 227*47533Spendry if (usage || optind != (argc - 1)) { 228*47533Spendry fputs("Usage: mk-amd-map [-p] file-map\n", stderr); 22944926Smckusick exit(1); 23044926Smckusick } 23144926Smckusick 232*47533Spendry map = argv[optind]; 23344926Smckusick sl = strrchr(map, '/'); 23444926Smckusick if (sl) { 23544926Smckusick *sl = '\0'; 23644926Smckusick if (chdir(map) < 0) { 23744926Smckusick fputs("Can't chdir to ", stderr); 23844926Smckusick perror(map); 23944926Smckusick exit(1); 24044926Smckusick } 24144926Smckusick map = sl + 1; 24244926Smckusick } 243*47533Spendry 244*47533Spendry if (!printit) { 245*47533Spendry len = strlen(map); 246*47533Spendry mappag = (char *) malloc(len + 5); 247*47533Spendry mapdir = (char *) malloc(len + 5); 248*47533Spendry if (!mappag || !mapdir) { 249*47533Spendry perror("mk-amd-map: malloc"); 250*47533Spendry exit(1); 251*47533Spendry } 252*47533Spendry mktemp(maptmp); 253*47533Spendry sprintf(maptpag, "%s.pag", maptmp); 254*47533Spendry sprintf(maptdir, "%s.dir", maptmp); 255*47533Spendry if (remove_file(maptpag) < 0 || remove_file(maptdir) < 0) { 256*47533Spendry fprintf(stderr, "Can't remove existing temporary files; %s and", maptpag); 257*47533Spendry perror(maptdir); 258*47533Spendry exit(1); 259*47533Spendry } 26044926Smckusick } 261*47533Spendry 26244926Smckusick mapf = fopen(map, "r"); 263*47533Spendry if (mapf && !printit) 26444926Smckusick mapd = create_database(maptmp); 26544926Smckusick else 26644926Smckusick mapd = 0; 267*47533Spendry 26844926Smckusick #ifndef DEBUG 26944926Smckusick signal(SIGINT, SIG_IGN); 270*47533Spendry #endif 271*47533Spendry 272*47533Spendry if (mapd || printit) { 27344926Smckusick int error = read_file(mapf, map, mapd); 27444926Smckusick (void) fclose(mapf); 275*47533Spendry if (printit) { 276*47533Spendry if (error) { 277*47533Spendry fprintf(stderr, "Error creating ndbm map for %s\n", map); 278*47533Spendry rc = 1; 279*47533Spendry } 280*47533Spendry } else { 281*47533Spendry if (error) { 282*47533Spendry fprintf(stderr, "Error reading source file %s\n", map); 283*47533Spendry rc = 1; 284*47533Spendry } else { 285*47533Spendry sprintf(mappag, "%s.pag", map); 286*47533Spendry sprintf(mapdir, "%s.dir", map); 287*47533Spendry if (rename(maptpag, mappag) < 0) { 288*47533Spendry fprintf(stderr, "Couldn't rename %s to ", maptpag); 289*47533Spendry perror(mappag); 290*47533Spendry /* Throw away the temporary map */ 291*47533Spendry unlink(maptpag); 292*47533Spendry unlink(maptdir); 293*47533Spendry rc = 1; 294*47533Spendry } else if (rename(maptdir, mapdir) < 0) { 295*47533Spendry fprintf(stderr, "Couldn't rename %s to ", maptdir); 296*47533Spendry perror(mapdir); 297*47533Spendry /* Put the .pag file back */ 298*47533Spendry rename(mappag, maptpag); 299*47533Spendry /* Throw away remaining part of original map */ 300*47533Spendry unlink(mapdir); 301*47533Spendry fprintf(stderr, 302*47533Spendry "WARNING: existing map \"%s.{dir,pag}\" destroyed\n", 303*47533Spendry map); 304*47533Spendry rc = 1; 305*47533Spendry } 306*47533Spendry } 30744926Smckusick } 30844926Smckusick } else { 30944926Smckusick fprintf(stderr, "Can't open \"%s.{dir,pag}\" for ", map); 31044926Smckusick perror("writing"); 31144926Smckusick rc = 1; 31244926Smckusick } 31344926Smckusick exit(rc); 31444926Smckusick } 31544926Smckusick #else 31644926Smckusick main() 31744926Smckusick { 318*47533Spendry fputs("mk-amd-map: This system does not support hashed database files\n", stderr); 319*47533Spendry exit(1); 32044926Smckusick } 321*47533Spendry * %sccs.include.redist.c% 32244926Smckusick #endif /* HAS_DATABASE */ 323