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*63613Sbostic * @(#)mk-amd-map.c 8.1 (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*63613Sbostic static char sccsid[] = "@(#)mk-amd-map.c 8.1 (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
store_data(db,k,v)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
read_line(buf,size,fp)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 */
read_file(fp,map,db)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
remove_file(f)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
main(argc,argv)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);
29863612Sbostic if (mapd)
29963612Sbostic 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
main()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