144926Smckusick /* 244926Smckusick * Copyright (c) 1990 Jan-Simon Pendry 344926Smckusick * Copyright (c) 1990 Imperial College of Science, Technology & Medicine 444926Smckusick * Copyright (c) 1990 The Regents of the University of California. 544926Smckusick * All rights reserved. 644926Smckusick * 744926Smckusick * This code is derived from software contributed to Berkeley by 844926Smckusick * Jan-Simon Pendry at Imperial College, London. 944926Smckusick * 1044926Smckusick * %sccs.include.redist.c% 1144926Smckusick * 12*49687Spendry * @(#)mk-amd-map.c 5.4 (Berkeley) 05/12/91 13*49687Spendry * 14*49687Spendry * $Id: mk-amd-map.c,v 5.2.1.4 91/05/07 22:18:47 jsp Alpha $ 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*49687Spendry static char rcsid[] = "$Id: mk-amd-map.c,v 5.2.1.4 91/05/07 22:18:47 jsp Alpha $"; 31*49687Spendry static char sccsid[] = "@(#)mk-amd-map.c 5.4 (Berkeley) 05/12/91"; 3244926Smckusick #endif /* not lint */ 3344926Smckusick 3444926Smckusick #include "am.h" 3544926Smckusick 3647533Spendry #ifndef SIGINT 3747533Spendry #include <signal.h> 3847533Spendry #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; 80*49687Spendry *buf = '\n'; buf[1] = '\0'; 8144926Smckusick /* 8244926Smckusick * Skip leading white space on next line 8344926Smckusick */ 8444926Smckusick while ((ch = getc(fp)) != EOF && 8544926Smckusick isascii(ch) && isspace(ch)) 8644926Smckusick ; 8744926Smckusick (void) ungetc(ch, fp); 8844926Smckusick } else { 8944926Smckusick return done; 9044926Smckusick } 9144926Smckusick } 9244926Smckusick } while (size > 0 && !feof(fp)); 9344926Smckusick 9444926Smckusick return done; 9544926Smckusick } 9644926Smckusick 9744926Smckusick /* 9844926Smckusick * Read through a map 9944926Smckusick */ 10044926Smckusick static int read_file(fp, map, db) 10144926Smckusick FILE *fp; 10244926Smckusick char *map; 10344926Smckusick voidp db; 10444926Smckusick { 10544926Smckusick char key_val[2048]; 10644926Smckusick int chuck = 0; 10744926Smckusick int line_no = 0; 10844926Smckusick int errs = 0; 10944926Smckusick 11044926Smckusick while (read_line(key_val, sizeof(key_val), fp)) { 11144926Smckusick char *kp; 11244926Smckusick char *cp; 11344926Smckusick char *hash; 11444926Smckusick int len = strlen(key_val); 11544926Smckusick line_no++; 11644926Smckusick 11744926Smckusick /* 11844926Smckusick * Make sure we got the whole line 11944926Smckusick */ 12044926Smckusick if (key_val[len-1] != '\n') { 12144926Smckusick fprintf(stderr, "line %d in \"%s\" is too long", line_no, map); 12244926Smckusick chuck = 1; 12344926Smckusick } else { 12444926Smckusick key_val[len-1] = '\0'; 12544926Smckusick } 12644926Smckusick 12744926Smckusick /* 12844926Smckusick * Strip comments 12944926Smckusick */ 13044926Smckusick hash = strchr(key_val, '#'); 13144926Smckusick if (hash) 13244926Smckusick *hash = '\0'; 13344926Smckusick 13444926Smckusick /* 13544926Smckusick * Find start of key 13644926Smckusick */ 13744926Smckusick for (kp = key_val; *kp && isascii(*kp) && isspace(*kp); kp++) 13844926Smckusick ; 13944926Smckusick 14044926Smckusick /* 14144926Smckusick * Ignore blank lines 14244926Smckusick */ 14344926Smckusick if (!*kp) 14444926Smckusick goto again; 14544926Smckusick 14644926Smckusick /* 14744926Smckusick * Find end of key 14844926Smckusick */ 14944926Smckusick for (cp = kp; *cp&&(!isascii(*cp)||!isspace(*cp)); cp++) 15044926Smckusick ; 15144926Smckusick 15244926Smckusick /* 15344926Smckusick * Check whether key matches, or whether 15444926Smckusick * the entry is a wildcard entry. 15544926Smckusick */ 15644926Smckusick if (*cp) 15744926Smckusick *cp++ = '\0'; 15844926Smckusick while (*cp && isascii(*cp) && isspace(*cp)) 15944926Smckusick cp++; 16044926Smckusick if (*kp == '+') { 16144926Smckusick fprintf(stderr, "Can't interpolate %s\n", kp); 16244926Smckusick errs++; 16344926Smckusick } else if (*cp) { 16447533Spendry if (db) { 16547533Spendry if (store_data(db, kp, cp) < 0) { 16647533Spendry fprintf(stderr, "Could store %s -> %s\n", kp, cp); 16747533Spendry errs++; 16847533Spendry } 16947533Spendry } else { 17047533Spendry printf("%s\t%s\n", kp, cp); 17144926Smckusick } 17244926Smckusick } else { 17344926Smckusick fprintf(stderr, "%s: line %d has no value field", map, line_no); 17444926Smckusick errs++; 17544926Smckusick } 17644926Smckusick 17744926Smckusick again: 17844926Smckusick /* 17944926Smckusick * If the last read didn't get a whole line then 18044926Smckusick * throw away the remainder before continuing... 18144926Smckusick */ 18244926Smckusick if (chuck) { 18344926Smckusick while (fgets(key_val, sizeof(key_val), fp) && 18444926Smckusick !strchr(key_val, '\n')) 18544926Smckusick ; 18644926Smckusick chuck = 0; 18744926Smckusick } 18844926Smckusick } 18944926Smckusick return errs; 19044926Smckusick } 19144926Smckusick 19247533Spendry static int remove_file(f) 19344926Smckusick char *f; 19444926Smckusick { 19544926Smckusick if (unlink(f) < 0 && errno != ENOENT) 19644926Smckusick return -1; 19744926Smckusick return 0; 19844926Smckusick } 19944926Smckusick 20044926Smckusick main(argc, argv) 20144926Smckusick int argc; 20244926Smckusick char *argv[]; 20344926Smckusick { 20444926Smckusick FILE *mapf; 20544926Smckusick char *map; 20644926Smckusick int rc = 0; 20744926Smckusick DBM *mapd; 208*49687Spendry static char maptmp[] = "dbmXXXXXX"; 20944926Smckusick char maptpag[16], maptdir[16]; 21044926Smckusick char *mappag, *mapdir; 21144926Smckusick int len; 21244926Smckusick char *sl; 21347533Spendry int printit = 0; 21447533Spendry int usage = 0; 21547533Spendry int ch; 21647533Spendry extern int optind; 21744926Smckusick 21847533Spendry while ((ch = getopt(argc, argv, "p")) != EOF) 21947533Spendry switch (ch) { 22047533Spendry case 'p': 22147533Spendry printit = 1; 22247533Spendry break; 22347533Spendry default: 22447533Spendry usage++; 22547533Spendry break; 22647533Spendry } 22747533Spendry 22847533Spendry if (usage || optind != (argc - 1)) { 22947533Spendry fputs("Usage: mk-amd-map [-p] file-map\n", stderr); 23044926Smckusick exit(1); 23144926Smckusick } 23244926Smckusick 23347533Spendry map = argv[optind]; 23444926Smckusick sl = strrchr(map, '/'); 23544926Smckusick if (sl) { 23644926Smckusick *sl = '\0'; 23744926Smckusick if (chdir(map) < 0) { 23844926Smckusick fputs("Can't chdir to ", stderr); 23944926Smckusick perror(map); 24044926Smckusick exit(1); 24144926Smckusick } 24244926Smckusick map = sl + 1; 24344926Smckusick } 24447533Spendry 24547533Spendry if (!printit) { 24647533Spendry len = strlen(map); 24747533Spendry mappag = (char *) malloc(len + 5); 24847533Spendry mapdir = (char *) malloc(len + 5); 24947533Spendry if (!mappag || !mapdir) { 25047533Spendry perror("mk-amd-map: malloc"); 25147533Spendry exit(1); 25247533Spendry } 25347533Spendry mktemp(maptmp); 25447533Spendry sprintf(maptpag, "%s.pag", maptmp); 25547533Spendry sprintf(maptdir, "%s.dir", maptmp); 25647533Spendry if (remove_file(maptpag) < 0 || remove_file(maptdir) < 0) { 25747533Spendry fprintf(stderr, "Can't remove existing temporary files; %s and", maptpag); 25847533Spendry perror(maptdir); 25947533Spendry exit(1); 26047533Spendry } 26144926Smckusick } 26247533Spendry 26344926Smckusick mapf = fopen(map, "r"); 26447533Spendry if (mapf && !printit) 26544926Smckusick mapd = create_database(maptmp); 26644926Smckusick else 26744926Smckusick mapd = 0; 26847533Spendry 26944926Smckusick #ifndef DEBUG 27044926Smckusick signal(SIGINT, SIG_IGN); 27147533Spendry #endif 27247533Spendry 27347533Spendry if (mapd || printit) { 27444926Smckusick int error = read_file(mapf, map, mapd); 27544926Smckusick (void) fclose(mapf); 27647533Spendry if (printit) { 27747533Spendry if (error) { 27847533Spendry fprintf(stderr, "Error creating ndbm map for %s\n", map); 27947533Spendry rc = 1; 28047533Spendry } 28147533Spendry } else { 28247533Spendry if (error) { 28347533Spendry fprintf(stderr, "Error reading source file %s\n", map); 28447533Spendry rc = 1; 28547533Spendry } else { 28647533Spendry sprintf(mappag, "%s.pag", map); 28747533Spendry sprintf(mapdir, "%s.dir", map); 28847533Spendry if (rename(maptpag, mappag) < 0) { 28947533Spendry fprintf(stderr, "Couldn't rename %s to ", maptpag); 29047533Spendry perror(mappag); 29147533Spendry /* Throw away the temporary map */ 29247533Spendry unlink(maptpag); 29347533Spendry unlink(maptdir); 29447533Spendry rc = 1; 29547533Spendry } else if (rename(maptdir, mapdir) < 0) { 29647533Spendry fprintf(stderr, "Couldn't rename %s to ", maptdir); 29747533Spendry perror(mapdir); 29847533Spendry /* Put the .pag file back */ 29947533Spendry rename(mappag, maptpag); 30047533Spendry /* Throw away remaining part of original map */ 30147533Spendry unlink(mapdir); 30247533Spendry fprintf(stderr, 30347533Spendry "WARNING: existing map \"%s.{dir,pag}\" destroyed\n", 30447533Spendry map); 30547533Spendry rc = 1; 30647533Spendry } 30747533Spendry } 30844926Smckusick } 30944926Smckusick } else { 31044926Smckusick fprintf(stderr, "Can't open \"%s.{dir,pag}\" for ", map); 31144926Smckusick perror("writing"); 31244926Smckusick rc = 1; 31344926Smckusick } 31444926Smckusick exit(rc); 31544926Smckusick } 31644926Smckusick #else 31744926Smckusick main() 31844926Smckusick { 31947533Spendry fputs("mk-amd-map: This system does not support hashed database files\n", stderr); 32047533Spendry exit(1); 32144926Smckusick } 32244926Smckusick #endif /* HAS_DATABASE */ 323