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