date and time created 92/11/16 09:14:26 by eric
[unix-history] / usr / src / usr.sbin / sendmail / makemap / makemap.c
CommitLineData
d15694cb
EA
1/*
2 * Copyright (c) 1992 Eric P. Allman.
3 * Copyright (c) 1992 Regents of the University of California.
4 * All rights reserved.
5 *
6 * %sccs.include.redist.c%
7 */
8
9#ifndef lint
10static char sccsid[] = "@(#)makemap.c 5.1 (Berkeley) %G%";
11#endif /* not lint */
12
13#include <stdio.h>
14#include <sysexits.h>
15#include <sys/file.h>
16#include <ctype.h>
17#include <string.h>
18#include "useful.h"
19#include "conf.h"
20
21#ifdef DBM_MAP
22#include <ndbm.h>
23#endif
24
25#if defined(HASH_MAP) || defined(BTREE_MAP)
26#include <db.h>
27#endif
28
29enum type { T_DBM, T_BTREE, T_HASH, T_ERR, T_UNKNOWN };
30
31union dbent
32{
33#ifdef DBM_MAP
34 datum dbm;
35#endif
36#if defined(HASH_MAP) || defined(BTREE_MAP)
37 DBT db;
38#endif
39 struct
40 {
41 char *data;
42 int size;
43 } xx;
44};
45
46#define BUFSIZE 1024
47
48main(argc, argv)
49 int argc;
50 char **argv;
51{
52 char *progname;
53 bool inclnull = FALSE;
54 bool notrunc = FALSE;
55 bool allowreplace = FALSE;
56 bool verbose = FALSE;
57 int exitstat;
58 int opt;
59 char *typename;
60 char *mapname;
61 int lineno;
62 int st;
63 int mode;
64 enum type type;
65 union
66 {
67#ifdef DBM_MAP
68 DBM *dbm;
69#endif
70#if defined(HASH_MAP) || defined(BTREE_MAP)
71 DB *db;
72#endif
73 void *dbx;
74 } dbp;
75 union dbent key, val;
76 char ibuf[BUFSIZE];
77 extern char *optarg;
78 extern int optind;
79
80 progname = argv[0];
81
82 while ((opt = getopt(argc, argv, "Norv")) != EOF)
83 {
84 switch (opt)
85 {
86 case 'N':
87 inclnull = TRUE;
88 break;
89
90 case 'o':
91 notrunc = TRUE;
92 break;
93
94 case 'r':
95 allowreplace = TRUE;
96 break;
97
98 case 'v':
99 verbose = TRUE;
100 break;
101
102 default:
103 type = T_ERR;
104 break;
105 }
106 }
107
108 argc -= optind;
109 argv += optind;
110 if (argc != 2)
111 type = T_ERR;
112 else
113 {
114 typename = argv[0];
115 mapname = argv[1];
116
117 if (strcmp(typename, "dbm") == 0)
118 type = T_DBM;
119 else if (strcmp(typename, "btree") == 0)
120 type = T_BTREE;
121 else if (strcmp(typename, "hash") == 0)
122 type = T_HASH;
123 else
124 type = T_UNKNOWN;
125 }
126
127 switch (type)
128 {
129 case T_ERR:
130 fprintf(stderr, "Usage: %s [-N] [-o] [-v] type mapname\n", progname);
131 exit(EX_USAGE);
132
133 case T_UNKNOWN:
134 fprintf(stderr, "%s: Unknown database type %s\n",
135 progname, typename);
136 exit(EX_USAGE);
137
138#ifndef DBM_MAP
139 case T_DBM:
140#endif
141#ifndef BTREE_MAP
142 case T_BTREE:
143#endif
144#ifndef HASH_MAP
145 case T_HASH:
146#endif
147 fprintf(stderr, "%s: Type %s not supported in this version\n",
148 progname, typename);
149 exit(EX_UNAVAILABLE);
150 }
151
152 /*
153 ** Create the database.
154 */
155
156 mode = O_RDWR;
157 if (!notrunc)
158 mode |= O_CREAT|O_TRUNC;
159 switch (type)
160 {
161#ifdef DBM_MAP
162 case T_DBM:
163 dbp.dbm = dbm_open(mapname, mode, 0644);
164 break;
165#endif
166
167#ifdef HASH_MAP
168 case T_HASH:
169 dbp.db = dbopen(mapname, mode, 0644, DB_HASH, NULL);
170 break;
171#endif
172
173#ifdef BTREE_MAP
174 case T_BTREE:
175 dbp.db = dbopen(mapname, mode, 0644, DB_BTREE, NULL);
176 break;
177#endif
178
179 default:
180 fprintf(stderr, "%s: internal error: type %d\n", progname, type);
181 exit(EX_SOFTWARE);
182 }
183
184 if (dbp.dbx == NULL)
185 {
186 fprintf(stderr, "%s: cannot create type %s map %s\n",
187 progname, typename, mapname);
188 exit(EX_CANTCREAT);
189 }
190
191 /*
192 ** Copy the data
193 */
194
195 lineno = 0;
196 exitstat = EX_OK;
197 while (fgets(ibuf, sizeof ibuf, stdin) != NULL)
198 {
199 register char *p;
200
201 lineno++;
202
203 /*
204 ** Parse the line.
205 */
206
207 p = strchr(ibuf, '\n');
208 if (*p != '\0')
209 *p = '\0';
210 if (ibuf[0] == '\0' || ibuf[0] == '#')
211 continue;
212 if (isspace(ibuf[0]))
213 {
214 fprintf(stderr, "%s: %s: line %d: syntax error (leading space)\n",
215 progname, mapname, lineno);
216 continue;
217 }
218 key.xx.data = ibuf;
219 for (p = ibuf; *p != '\0' && !isspace(*p); p++)
220 continue;
221 key.xx.size = p - key.xx.data;
222 if (inclnull)
223 key.xx.size++;
224 if (*p != '\0')
225 *p++ = '\0';
226 while (isspace(*p))
227 p++;
228 if (*p == '\0')
229 {
230 fprintf(stderr, "%s: %s: line %d: no RHS for LHS %s\n",
231 progname, mapname, lineno, key.xx.data);
232 continue;
233 }
234 val.xx.data = p;
235 val.xx.size = strlen(p);
236 if (inclnull)
237 val.xx.size++;
238
239 /*
240 ** Do the database insert.
241 */
242
243 if (verbose)
244 {
245 printf("key=`%s', val=`%s'\n", key.xx.data, val.xx.data);
246 }
247
248 switch (type)
249 {
250#ifdef DBM_MAP
251 case T_DBM:
252 st = dbm_store(dbp.dbm, key.dbm, val.dbm,
253 allowreplace ? DBM_REPLACE : DBM_INSERT);
254 break;
255#endif
256
257#if defined(BTREE_MAP) || defined(HASH_MAP)
258 case T_BTREE:
259 case T_HASH:
260 st = (*dbp.db->put)(dbp.db, &key.db, &val.db,
261 allowreplace ? 0 : R_NOOVERWRITE);
262 break;
263#endif
264 }
265
266 if (st < 0)
267 {
268 fprintf(stderr, "%s: %s: line %d: key %s: put error\n",
269 progname, mapname, lineno, key.xx.data);
270 perror(mapname);
271 exitstat = EX_IOERR;
272 }
273 else if (st > 0)
274 {
275 fprintf(stderr, "%s: %s: line %d: key %s: duplicate key\n",
276 progname, mapname, lineno, key.xx.data);
277 }
278 }
279
280 /*
281 ** Now close the database.
282 */
283
284 switch (type)
285 {
286#ifdef DBM_MAP
287 case T_DBM:
288 dbm_close(dbp.dbm);
289 break;
290#endif
291
292#if defined(HASH_MAP) || defined(BTREE_MAP)
293 case T_HASH:
294 case T_BTREE:
295 if ((*dbp.db->close)(dbp.db) < 0)
296 {
297 fprintf(stderr, "%s: %s: error on close\n",
298 progname, mapname);
299 perror(mapname);
300 exitstat = EX_IOERR;
301 }
302#endif
303 }
304
305 exit (exitstat);
306}