1*44926Smckusick /* 2*44926Smckusick * $Id: mk-amd-map.c,v 5.2 90/06/23 22:20:10 jsp Rel $ 3*44926Smckusick * 4*44926Smckusick * Copyright (c) 1990 Jan-Simon Pendry 5*44926Smckusick * Copyright (c) 1990 Imperial College of Science, Technology & Medicine 6*44926Smckusick * Copyright (c) 1990 The Regents of the University of California. 7*44926Smckusick * All rights reserved. 8*44926Smckusick * 9*44926Smckusick * This code is derived from software contributed to Berkeley by 10*44926Smckusick * Jan-Simon Pendry at Imperial College, London. 11*44926Smckusick * 12*44926Smckusick * %sccs.include.redist.c% 13*44926Smckusick * 14*44926Smckusick * @(#)mk-amd-map.c 5.1 (Berkeley) 07/19/90 15*44926Smckusick */ 16*44926Smckusick 17*44926Smckusick /* 18*44926Smckusick * Convert a file map into an ndbm map 19*44926Smckusick */ 20*44926Smckusick 21*44926Smckusick #ifndef lint 22*44926Smckusick char copyright[] = "\ 23*44926Smckusick @(#)Copyright (c) 1990 Jan-Simon Pendry\n\ 24*44926Smckusick @(#)Copyright (c) 1990 Imperial College of Science, Technology & Medicine\n\ 25*44926Smckusick @(#)Copyright (c) 1990 The Regents of the University of California.\n\ 26*44926Smckusick @(#)All rights reserved.\n"; 27*44926Smckusick #endif /* not lint */ 28*44926Smckusick 29*44926Smckusick #ifndef lint 30*44926Smckusick static char rcsid[] = "$Id: mk-amd-map.c,v 5.2 90/06/23 22:20:10 jsp Rel $"; 31*44926Smckusick static char sccsid[] = "@(#)mk-amd-map.c 5.1 (Berkeley) 07/19/90"; 32*44926Smckusick #endif /* not lint */ 33*44926Smckusick 34*44926Smckusick #include "am.h" 35*44926Smckusick 36*44926Smckusick #ifdef OS_HAS_GDBM 37*44926Smckusick #define HAS_DATABASE 38*44926Smckusick #include "gdbm.h" 39*44926Smckusick #endif /* OS_HAS_GDBM */ 40*44926Smckusick 41*44926Smckusick #ifndef HAS_DATABASE 42*44926Smckusick #ifdef OS_HAS_NDBM 43*44926Smckusick #define HAS_DATABASE 44*44926Smckusick #define USE_NDBM 45*44926Smckusick #include <ndbm.h> 46*44926Smckusick 47*44926Smckusick #define create_database(name) dbm_open(name, O_RDWR|O_CREAT, 0444) 48*44926Smckusick 49*44926Smckusick static int store_data(db, k, v) 50*44926Smckusick voidp db; 51*44926Smckusick char *k, *v; 52*44926Smckusick { 53*44926Smckusick datum key, val; 54*44926Smckusick 55*44926Smckusick key.dptr = k; val.dptr = v; 56*44926Smckusick key.dsize = strlen(k) + 1; 57*44926Smckusick val.dsize = strlen(v) + 1; 58*44926Smckusick return dbm_store((DBM *) db, key, val, DBM_INSERT); 59*44926Smckusick } 60*44926Smckusick 61*44926Smckusick #endif /* OS_HAS_NDBM */ 62*44926Smckusick #endif /* !OS_HAS_DATABASE */ 63*44926Smckusick 64*44926Smckusick #ifdef HAS_DATABASE 65*44926Smckusick #include <fcntl.h> 66*44926Smckusick #include <ctype.h> 67*44926Smckusick 68*44926Smckusick static int read_line(buf, size, fp) 69*44926Smckusick char *buf; 70*44926Smckusick int size; 71*44926Smckusick FILE *fp; 72*44926Smckusick { 73*44926Smckusick int done = 0; 74*44926Smckusick 75*44926Smckusick do { 76*44926Smckusick while (fgets(buf, size, fp)) { 77*44926Smckusick int len = strlen(buf); 78*44926Smckusick done += len; 79*44926Smckusick if (len > 1 && buf[len-2] == '\\' && 80*44926Smckusick buf[len-1] == '\n') { 81*44926Smckusick int ch; 82*44926Smckusick buf += len - 2; 83*44926Smckusick size -= len - 2; 84*44926Smckusick /* 85*44926Smckusick * Skip leading white space on next line 86*44926Smckusick */ 87*44926Smckusick while ((ch = getc(fp)) != EOF && 88*44926Smckusick isascii(ch) && isspace(ch)) 89*44926Smckusick ; 90*44926Smckusick (void) ungetc(ch, fp); 91*44926Smckusick } else { 92*44926Smckusick return done; 93*44926Smckusick } 94*44926Smckusick } 95*44926Smckusick } while (size > 0 && !feof(fp)); 96*44926Smckusick 97*44926Smckusick return done; 98*44926Smckusick } 99*44926Smckusick 100*44926Smckusick /* 101*44926Smckusick * Read through a map 102*44926Smckusick */ 103*44926Smckusick static int read_file(fp, map, db) 104*44926Smckusick FILE *fp; 105*44926Smckusick char *map; 106*44926Smckusick voidp db; 107*44926Smckusick { 108*44926Smckusick char key_val[2048]; 109*44926Smckusick int chuck = 0; 110*44926Smckusick int line_no = 0; 111*44926Smckusick int errs = 0; 112*44926Smckusick 113*44926Smckusick while (read_line(key_val, sizeof(key_val), fp)) { 114*44926Smckusick char *kp; 115*44926Smckusick char *cp; 116*44926Smckusick char *hash; 117*44926Smckusick int len = strlen(key_val); 118*44926Smckusick line_no++; 119*44926Smckusick 120*44926Smckusick /* 121*44926Smckusick * Make sure we got the whole line 122*44926Smckusick */ 123*44926Smckusick if (key_val[len-1] != '\n') { 124*44926Smckusick fprintf(stderr, "line %d in \"%s\" is too long", line_no, map); 125*44926Smckusick chuck = 1; 126*44926Smckusick } else { 127*44926Smckusick key_val[len-1] = '\0'; 128*44926Smckusick } 129*44926Smckusick 130*44926Smckusick /* 131*44926Smckusick * Strip comments 132*44926Smckusick */ 133*44926Smckusick hash = strchr(key_val, '#'); 134*44926Smckusick if (hash) 135*44926Smckusick *hash = '\0'; 136*44926Smckusick 137*44926Smckusick /* 138*44926Smckusick * Find start of key 139*44926Smckusick */ 140*44926Smckusick for (kp = key_val; *kp && isascii(*kp) && isspace(*kp); kp++) 141*44926Smckusick ; 142*44926Smckusick 143*44926Smckusick /* 144*44926Smckusick * Ignore blank lines 145*44926Smckusick */ 146*44926Smckusick if (!*kp) 147*44926Smckusick goto again; 148*44926Smckusick 149*44926Smckusick /* 150*44926Smckusick * Find end of key 151*44926Smckusick */ 152*44926Smckusick for (cp = kp; *cp&&(!isascii(*cp)||!isspace(*cp)); cp++) 153*44926Smckusick ; 154*44926Smckusick 155*44926Smckusick /* 156*44926Smckusick * Check whether key matches, or whether 157*44926Smckusick * the entry is a wildcard entry. 158*44926Smckusick */ 159*44926Smckusick if (*cp) 160*44926Smckusick *cp++ = '\0'; 161*44926Smckusick while (*cp && isascii(*cp) && isspace(*cp)) 162*44926Smckusick cp++; 163*44926Smckusick if (*kp == '+') { 164*44926Smckusick fprintf(stderr, "Can't interpolate %s\n", kp); 165*44926Smckusick errs++; 166*44926Smckusick } else if (*cp) { 167*44926Smckusick #ifdef DEBUG 168*44926Smckusick printf("%s\t%s\n", kp, cp); 169*44926Smckusick #endif /* DEBUG */ 170*44926Smckusick if (store_data(db, kp, cp) < 0) { 171*44926Smckusick fprintf(stderr, "Could store %s -> %s\n", kp, cp); 172*44926Smckusick errs++; 173*44926Smckusick } 174*44926Smckusick } else { 175*44926Smckusick fprintf(stderr, "%s: line %d has no value field", map, line_no); 176*44926Smckusick errs++; 177*44926Smckusick } 178*44926Smckusick 179*44926Smckusick again: 180*44926Smckusick /* 181*44926Smckusick * If the last read didn't get a whole line then 182*44926Smckusick * throw away the remainder before continuing... 183*44926Smckusick */ 184*44926Smckusick if (chuck) { 185*44926Smckusick while (fgets(key_val, sizeof(key_val), fp) && 186*44926Smckusick !strchr(key_val, '\n')) 187*44926Smckusick ; 188*44926Smckusick chuck = 0; 189*44926Smckusick } 190*44926Smckusick } 191*44926Smckusick return errs; 192*44926Smckusick } 193*44926Smckusick 194*44926Smckusick static int remove(f) 195*44926Smckusick char *f; 196*44926Smckusick { 197*44926Smckusick if (unlink(f) < 0 && errno != ENOENT) 198*44926Smckusick return -1; 199*44926Smckusick return 0; 200*44926Smckusick } 201*44926Smckusick 202*44926Smckusick main(argc, argv) 203*44926Smckusick int argc; 204*44926Smckusick char *argv[]; 205*44926Smckusick { 206*44926Smckusick FILE *mapf; 207*44926Smckusick char *map; 208*44926Smckusick int rc = 0; 209*44926Smckusick DBM *mapd; 210*44926Smckusick char *maptmp = "dbmXXXXXX"; 211*44926Smckusick char maptpag[16], maptdir[16]; 212*44926Smckusick char *mappag, *mapdir; 213*44926Smckusick int len; 214*44926Smckusick char *sl; 215*44926Smckusick 216*44926Smckusick if (argc != 2) { 217*44926Smckusick fputs("Usage: mk-amd-map file-map\n", stderr); 218*44926Smckusick exit(1); 219*44926Smckusick } 220*44926Smckusick 221*44926Smckusick map = argv[1]; 222*44926Smckusick sl = strrchr(map, '/'); 223*44926Smckusick if (sl) { 224*44926Smckusick *sl = '\0'; 225*44926Smckusick if (chdir(map) < 0) { 226*44926Smckusick fputs("Can't chdir to ", stderr); 227*44926Smckusick perror(map); 228*44926Smckusick exit(1); 229*44926Smckusick } 230*44926Smckusick map = sl + 1; 231*44926Smckusick } 232*44926Smckusick #ifdef USE_NDBM 233*44926Smckusick len = strlen(map); 234*44926Smckusick mappag = (char *) malloc(len + 5); 235*44926Smckusick mapdir = (char *) malloc(len + 5); 236*44926Smckusick if (!mappag || !mapdir) { 237*44926Smckusick perror("malloc"); 238*44926Smckusick exit(1); 239*44926Smckusick } 240*44926Smckusick mktemp(maptmp); 241*44926Smckusick sprintf(maptpag, "%s.pag", maptmp); 242*44926Smckusick sprintf(maptdir, "%s.dir", maptmp); 243*44926Smckusick if (remove(maptpag) < 0 || remove(maptdir) < 0) { 244*44926Smckusick fprintf(stderr, "Can't remove existing temporary files; %s and", maptpag); 245*44926Smckusick perror(maptdir); 246*44926Smckusick exit(1); 247*44926Smckusick } 248*44926Smckusick #endif /* USE_NDBM */ 249*44926Smckusick mapf = fopen(map, "r"); 250*44926Smckusick if (mapf) 251*44926Smckusick mapd = create_database(maptmp); 252*44926Smckusick else 253*44926Smckusick mapd = 0; 254*44926Smckusick #ifndef DEBUG 255*44926Smckusick signal(SIGINT, SIG_IGN); 256*44926Smckusick #endif /* DEBUG */ 257*44926Smckusick if (mapd) { 258*44926Smckusick int error = read_file(mapf, map, mapd); 259*44926Smckusick (void) fclose(mapf); 260*44926Smckusick if (error) { 261*44926Smckusick fprintf(stderr, "Error creating ndbm map for %s\n", map); 262*44926Smckusick rc = 1; 263*44926Smckusick } 264*44926Smckusick #ifdef USE_NDBM 265*44926Smckusick sprintf(mappag, "%s.pag", map); 266*44926Smckusick sprintf(mapdir, "%s.dir", map); 267*44926Smckusick if (rename(maptpag, mappag) < 0) { 268*44926Smckusick fprintf(stderr, "Couldn't rename %s to ", maptpag); 269*44926Smckusick perror(mappag); 270*44926Smckusick /* Throw away the temporary map */ 271*44926Smckusick unlink(maptpag); 272*44926Smckusick unlink(maptdir); 273*44926Smckusick rc = 1; 274*44926Smckusick } else if (rename(maptdir, mapdir) < 0) { 275*44926Smckusick fprintf(stderr, "Couldn't rename %s to ", maptdir); 276*44926Smckusick perror(mapdir); 277*44926Smckusick /* Put the .pag file back */ 278*44926Smckusick rename(mappag, maptpag); 279*44926Smckusick /* Throw away remaining part of original map */ 280*44926Smckusick unlink(mapdir); 281*44926Smckusick fprintf(stderr, "WARNING: existing map \"%s.{dir,pag}\" destroyed\n", map); 282*44926Smckusick rc = 1; 283*44926Smckusick } 284*44926Smckusick #endif /* USE_NDBM */ 285*44926Smckusick } else { 286*44926Smckusick #ifdef USE_NDBM 287*44926Smckusick fprintf(stderr, "Can't open \"%s.{dir,pag}\" for ", map); 288*44926Smckusick #endif /* USE_NDBM */ 289*44926Smckusick perror("writing"); 290*44926Smckusick rc = 1; 291*44926Smckusick } 292*44926Smckusick exit(rc); 293*44926Smckusick } 294*44926Smckusick #else 295*44926Smckusick main() 296*44926Smckusick { 297*44926Smckusick fputs("This system does not support hashed database files\n", stderr); 298*44926Smckusick exit(0); 299*44926Smckusick } 300*44926Smckusick #endif /* HAS_DATABASE */ 301