144926Smckusick /* 263601Sbostic * Copyright (c) 1990, 1993 Jan-Simon Pendry 344926Smckusick * Copyright (c) 1990 Imperial College of Science, Technology & Medicine 463601Sbostic * Copyright (c) 1990, 1993 563601Sbostic * The Regents of the University of California. 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*63612Sbostic * @(#)mk-amd-map.c 5.8 (Berkeley) 06/28/93 1349687Spendry * 1452458Spendry * $Id: mk-amd-map.c,v 5.2.2.1 1992/02/09 15:09:18 jsp beta $ 1544926Smckusick */ 1644926Smckusick 1744926Smckusick /* 1844926Smckusick * Convert a file map into an ndbm map 1944926Smckusick */ 2044926Smckusick 2144926Smckusick #ifndef lint 2244926Smckusick char copyright[] = "\ 2363601Sbostic @(#)Copyright (c) 1990, 1993 Jan-Simon Pendry\n\ 2444926Smckusick @(#)Copyright (c) 1990 Imperial College of Science, Technology & Medicine\n\ 2563601Sbostic @(#)Copyright (c) 1990, 1993\n\ 2663601Sbostic The Regents of the University of California. All rights reserved.\n"; 2744926Smckusick #endif /* not lint */ 2844926Smckusick 2944926Smckusick #ifndef lint 3052458Spendry static char rcsid[] = "$Id: mk-amd-map.c,v 5.2.2.1 1992/02/09 15:09:18 jsp beta $"; 31*63612Sbostic static char sccsid[] = "@(#)mk-amd-map.c 5.8 (Berkeley) 06/28/93"; 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 4463601Sbostic #ifdef DBM_SUFFIX 4563601Sbostic #define USING_DB 4663601Sbostic #endif 4744926Smckusick 4863601Sbostic #define create_database(name) dbm_open(name, O_RDWR|O_CREAT, 0644) 4963601Sbostic 5044926Smckusick static int store_data(db, k, v) 5144926Smckusick voidp db; 5244926Smckusick char *k, *v; 5344926Smckusick { 5444926Smckusick datum key, val; 5544926Smckusick 5644926Smckusick key.dptr = k; val.dptr = v; 5744926Smckusick key.dsize = strlen(k) + 1; 5844926Smckusick val.dsize = strlen(v) + 1; 5944926Smckusick return dbm_store((DBM *) db, key, val, DBM_INSERT); 6044926Smckusick } 6144926Smckusick 6244926Smckusick #endif /* OS_HAS_NDBM */ 6344926Smckusick 6444926Smckusick #ifdef HAS_DATABASE 6544926Smckusick #include <fcntl.h> 6644926Smckusick #include <ctype.h> 6744926Smckusick 6844926Smckusick static int read_line(buf, size, fp) 6944926Smckusick char *buf; 7044926Smckusick int size; 7144926Smckusick FILE *fp; 7244926Smckusick { 7344926Smckusick int done = 0; 7444926Smckusick 7544926Smckusick do { 7644926Smckusick while (fgets(buf, size, fp)) { 7744926Smckusick int len = strlen(buf); 7844926Smckusick done += len; 7944926Smckusick if (len > 1 && buf[len-2] == '\\' && 8044926Smckusick buf[len-1] == '\n') { 8144926Smckusick int ch; 8244926Smckusick buf += len - 2; 8344926Smckusick size -= len - 2; 8449687Spendry *buf = '\n'; buf[1] = '\0'; 8544926Smckusick /* 8644926Smckusick * Skip leading white space on next line 8744926Smckusick */ 8844926Smckusick while ((ch = getc(fp)) != EOF && 8944926Smckusick isascii(ch) && isspace(ch)) 9044926Smckusick ; 9144926Smckusick (void) ungetc(ch, fp); 9244926Smckusick } else { 9344926Smckusick return done; 9444926Smckusick } 9544926Smckusick } 9644926Smckusick } while (size > 0 && !feof(fp)); 9744926Smckusick 9844926Smckusick return done; 9944926Smckusick } 10044926Smckusick 10144926Smckusick /* 10244926Smckusick * Read through a map 10344926Smckusick */ 10444926Smckusick static int read_file(fp, map, db) 10544926Smckusick FILE *fp; 10644926Smckusick char *map; 10744926Smckusick voidp db; 10844926Smckusick { 10944926Smckusick char key_val[2048]; 11044926Smckusick int chuck = 0; 11144926Smckusick int line_no = 0; 11244926Smckusick int errs = 0; 11344926Smckusick 11444926Smckusick while (read_line(key_val, sizeof(key_val), fp)) { 11544926Smckusick char *kp; 11644926Smckusick char *cp; 11744926Smckusick char *hash; 11844926Smckusick int len = strlen(key_val); 11944926Smckusick line_no++; 12044926Smckusick 12144926Smckusick /* 12244926Smckusick * Make sure we got the whole line 12344926Smckusick */ 12444926Smckusick if (key_val[len-1] != '\n') { 12544926Smckusick fprintf(stderr, "line %d in \"%s\" is too long", line_no, map); 12644926Smckusick chuck = 1; 12744926Smckusick } else { 12844926Smckusick key_val[len-1] = '\0'; 12944926Smckusick } 13044926Smckusick 13144926Smckusick /* 13244926Smckusick * Strip comments 13344926Smckusick */ 13444926Smckusick hash = strchr(key_val, '#'); 13544926Smckusick if (hash) 13644926Smckusick *hash = '\0'; 13744926Smckusick 13844926Smckusick /* 13944926Smckusick * Find start of key 14044926Smckusick */ 14144926Smckusick for (kp = key_val; *kp && isascii(*kp) && isspace(*kp); kp++) 14244926Smckusick ; 14344926Smckusick 14444926Smckusick /* 14544926Smckusick * Ignore blank lines 14644926Smckusick */ 14744926Smckusick if (!*kp) 14844926Smckusick goto again; 14944926Smckusick 15044926Smckusick /* 15144926Smckusick * Find end of key 15244926Smckusick */ 15344926Smckusick for (cp = kp; *cp&&(!isascii(*cp)||!isspace(*cp)); cp++) 15444926Smckusick ; 15544926Smckusick 15644926Smckusick /* 15744926Smckusick * Check whether key matches, or whether 15844926Smckusick * the entry is a wildcard entry. 15944926Smckusick */ 16044926Smckusick if (*cp) 16144926Smckusick *cp++ = '\0'; 16244926Smckusick while (*cp && isascii(*cp) && isspace(*cp)) 16344926Smckusick cp++; 16444926Smckusick if (*kp == '+') { 16544926Smckusick fprintf(stderr, "Can't interpolate %s\n", kp); 16644926Smckusick errs++; 16744926Smckusick } else if (*cp) { 16847533Spendry if (db) { 16947533Spendry if (store_data(db, kp, cp) < 0) { 17047533Spendry fprintf(stderr, "Could store %s -> %s\n", kp, cp); 17147533Spendry errs++; 17247533Spendry } 17347533Spendry } else { 17447533Spendry printf("%s\t%s\n", kp, cp); 17544926Smckusick } 17644926Smckusick } else { 17744926Smckusick fprintf(stderr, "%s: line %d has no value field", map, line_no); 17844926Smckusick errs++; 17944926Smckusick } 18044926Smckusick 18144926Smckusick again: 18244926Smckusick /* 18344926Smckusick * If the last read didn't get a whole line then 18444926Smckusick * throw away the remainder before continuing... 18544926Smckusick */ 18644926Smckusick if (chuck) { 18744926Smckusick while (fgets(key_val, sizeof(key_val), fp) && 18844926Smckusick !strchr(key_val, '\n')) 18944926Smckusick ; 19044926Smckusick chuck = 0; 19144926Smckusick } 19244926Smckusick } 19344926Smckusick return errs; 19444926Smckusick } 19544926Smckusick 19647533Spendry static int remove_file(f) 19744926Smckusick char *f; 19844926Smckusick { 19944926Smckusick if (unlink(f) < 0 && errno != ENOENT) 20044926Smckusick return -1; 20144926Smckusick return 0; 20244926Smckusick } 20344926Smckusick 20444926Smckusick main(argc, argv) 20544926Smckusick int argc; 20644926Smckusick char *argv[]; 20744926Smckusick { 20844926Smckusick FILE *mapf; 20944926Smckusick char *map; 21044926Smckusick int rc = 0; 21144926Smckusick DBM *mapd; 21249687Spendry static char maptmp[] = "dbmXXXXXX"; 21363601Sbostic char maptpag[16]; 21463601Sbostic char *mappag; 21563601Sbostic #ifndef USING_DB 21663601Sbostic char maptdir[16]; 21763601Sbostic char *mapdir; 21863601Sbostic #endif 21944926Smckusick int len; 22044926Smckusick char *sl; 22147533Spendry int printit = 0; 22247533Spendry int usage = 0; 22347533Spendry int ch; 22447533Spendry extern int optind; 22544926Smckusick 22647533Spendry while ((ch = getopt(argc, argv, "p")) != EOF) 22747533Spendry switch (ch) { 22847533Spendry case 'p': 22947533Spendry printit = 1; 23047533Spendry break; 23147533Spendry default: 23247533Spendry usage++; 23347533Spendry break; 23447533Spendry } 23547533Spendry 23647533Spendry if (usage || optind != (argc - 1)) { 23747533Spendry fputs("Usage: mk-amd-map [-p] file-map\n", stderr); 23844926Smckusick exit(1); 23944926Smckusick } 24044926Smckusick 24147533Spendry map = argv[optind]; 24244926Smckusick sl = strrchr(map, '/'); 24344926Smckusick if (sl) { 24444926Smckusick *sl = '\0'; 24544926Smckusick if (chdir(map) < 0) { 24644926Smckusick fputs("Can't chdir to ", stderr); 24744926Smckusick perror(map); 24844926Smckusick exit(1); 24944926Smckusick } 25044926Smckusick map = sl + 1; 25144926Smckusick } 25247533Spendry 25347533Spendry if (!printit) { 25447533Spendry len = strlen(map); 25563601Sbostic #ifdef USING_DB 25647533Spendry mappag = (char *) malloc(len + 5); 25763601Sbostic if (!mappag) { 25863601Sbostic perror("mk-amd-map: malloc"); 25963601Sbostic exit(1); 26063601Sbostic } 26163601Sbostic mktemp(maptmp); 26263601Sbostic sprintf(maptpag, "%s%s", maptmp, DBM_SUFFIX); 26363601Sbostic if (remove_file(maptpag) < 0) { 26463601Sbostic fprintf(stderr, "Can't remove existing temporary file"); 26563601Sbostic perror(maptpag); 26663601Sbostic exit(1); 26763601Sbostic } 26863601Sbostic #else 26963601Sbostic mappag = (char *) malloc(len + 5); 27047533Spendry mapdir = (char *) malloc(len + 5); 27147533Spendry if (!mappag || !mapdir) { 27247533Spendry perror("mk-amd-map: malloc"); 27347533Spendry exit(1); 27447533Spendry } 27547533Spendry mktemp(maptmp); 27647533Spendry sprintf(maptpag, "%s.pag", maptmp); 27747533Spendry sprintf(maptdir, "%s.dir", maptmp); 27847533Spendry if (remove_file(maptpag) < 0 || remove_file(maptdir) < 0) { 27947533Spendry fprintf(stderr, "Can't remove existing temporary files; %s and", maptpag); 28047533Spendry perror(maptdir); 28147533Spendry exit(1); 28247533Spendry } 28363601Sbostic #endif 28444926Smckusick } 28547533Spendry 28644926Smckusick mapf = fopen(map, "r"); 28747533Spendry if (mapf && !printit) 28844926Smckusick mapd = create_database(maptmp); 28944926Smckusick else 29044926Smckusick mapd = 0; 29147533Spendry 29244926Smckusick #ifndef DEBUG 29344926Smckusick signal(SIGINT, SIG_IGN); 29447533Spendry #endif 29547533Spendry 29647533Spendry if (mapd || printit) { 29744926Smckusick int error = read_file(mapf, map, mapd); 298*63612Sbostic if (mapd) 299*63612Sbostic dbm_close(mapd); 30044926Smckusick (void) fclose(mapf); 30147533Spendry if (printit) { 30247533Spendry if (error) { 30347533Spendry fprintf(stderr, "Error creating ndbm map for %s\n", map); 30447533Spendry rc = 1; 30547533Spendry } 30647533Spendry } else { 30747533Spendry if (error) { 30847533Spendry fprintf(stderr, "Error reading source file %s\n", map); 30947533Spendry rc = 1; 31047533Spendry } else { 31163601Sbostic #ifdef USING_DB 31263601Sbostic sprintf(mappag, "%s%s", map, DBM_SUFFIX); 31363601Sbostic if (rename(maptpag, mappag) < 0) { 31463601Sbostic fprintf(stderr, "Couldn't rename %s to ", maptpag); 31563601Sbostic perror(mappag); 31663601Sbostic /* Throw away the temporary map */ 31763601Sbostic unlink(maptpag); 31863601Sbostic rc = 1; 31963601Sbostic } 32063601Sbostic #else 32147533Spendry sprintf(mappag, "%s.pag", map); 32247533Spendry sprintf(mapdir, "%s.dir", map); 32347533Spendry if (rename(maptpag, mappag) < 0) { 32447533Spendry fprintf(stderr, "Couldn't rename %s to ", maptpag); 32547533Spendry perror(mappag); 32647533Spendry /* Throw away the temporary map */ 32747533Spendry unlink(maptpag); 32847533Spendry unlink(maptdir); 32947533Spendry rc = 1; 33047533Spendry } else if (rename(maptdir, mapdir) < 0) { 33147533Spendry fprintf(stderr, "Couldn't rename %s to ", maptdir); 33247533Spendry perror(mapdir); 33347533Spendry /* Put the .pag file back */ 33447533Spendry rename(mappag, maptpag); 33547533Spendry /* Throw away remaining part of original map */ 33647533Spendry unlink(mapdir); 33747533Spendry fprintf(stderr, 33847533Spendry "WARNING: existing map \"%s.{dir,pag}\" destroyed\n", 33947533Spendry map); 34047533Spendry rc = 1; 34147533Spendry } 34263601Sbostic #endif 34347533Spendry } 34444926Smckusick } 34544926Smckusick } else { 34644926Smckusick fprintf(stderr, "Can't open \"%s.{dir,pag}\" for ", map); 34744926Smckusick perror("writing"); 34844926Smckusick rc = 1; 34944926Smckusick } 35044926Smckusick exit(rc); 35144926Smckusick } 35244926Smckusick #else 35344926Smckusick main() 35444926Smckusick { 35547533Spendry fputs("mk-amd-map: This system does not support hashed database files\n", stderr); 35647533Spendry exit(1); 35744926Smckusick } 35844926Smckusick #endif /* HAS_DATABASE */ 359