set QDONTSEND together with QBADADDR
[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
a0f5c935 10static char sccsid[] = "@(#)makemap.c 6.1 (Berkeley) %G%";
d15694cb
EA
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;
1b15d3af 57 bool foldcase = FALSE;
d15694cb
EA
58 int exitstat;
59 int opt;
60 char *typename;
61 char *mapname;
62 int lineno;
63 int st;
64 int mode;
65 enum type type;
66 union
67 {
68#ifdef DBM_MAP
69 DBM *dbm;
70#endif
71#if defined(HASH_MAP) || defined(BTREE_MAP)
72 DB *db;
73#endif
74 void *dbx;
75 } dbp;
76 union dbent key, val;
77 char ibuf[BUFSIZE];
78 extern char *optarg;
79 extern int optind;
80
81 progname = argv[0];
82
1b15d3af 83 while ((opt = getopt(argc, argv, "Nforv")) != EOF)
d15694cb
EA
84 {
85 switch (opt)
86 {
87 case 'N':
88 inclnull = TRUE;
89 break;
90
1b15d3af
EA
91 case 'f':
92 foldcase = TRUE;
93 break;
94
d15694cb
EA
95 case 'o':
96 notrunc = TRUE;
97 break;
98
99 case 'r':
100 allowreplace = TRUE;
101 break;
102
103 case 'v':
104 verbose = TRUE;
105 break;
106
107 default:
108 type = T_ERR;
109 break;
110 }
111 }
112
113 argc -= optind;
114 argv += optind;
115 if (argc != 2)
116 type = T_ERR;
117 else
118 {
119 typename = argv[0];
120 mapname = argv[1];
121
122 if (strcmp(typename, "dbm") == 0)
123 type = T_DBM;
124 else if (strcmp(typename, "btree") == 0)
125 type = T_BTREE;
126 else if (strcmp(typename, "hash") == 0)
127 type = T_HASH;
128 else
129 type = T_UNKNOWN;
130 }
131
132 switch (type)
133 {
134 case T_ERR:
135 fprintf(stderr, "Usage: %s [-N] [-o] [-v] type mapname\n", progname);
136 exit(EX_USAGE);
137
138 case T_UNKNOWN:
139 fprintf(stderr, "%s: Unknown database type %s\n",
140 progname, typename);
141 exit(EX_USAGE);
142
143#ifndef DBM_MAP
144 case T_DBM:
145#endif
146#ifndef BTREE_MAP
147 case T_BTREE:
148#endif
149#ifndef HASH_MAP
150 case T_HASH:
151#endif
152 fprintf(stderr, "%s: Type %s not supported in this version\n",
153 progname, typename);
154 exit(EX_UNAVAILABLE);
155 }
156
157 /*
158 ** Create the database.
159 */
160
161 mode = O_RDWR;
162 if (!notrunc)
163 mode |= O_CREAT|O_TRUNC;
164 switch (type)
165 {
166#ifdef DBM_MAP
167 case T_DBM:
168 dbp.dbm = dbm_open(mapname, mode, 0644);
169 break;
170#endif
171
172#ifdef HASH_MAP
173 case T_HASH:
174 dbp.db = dbopen(mapname, mode, 0644, DB_HASH, NULL);
175 break;
176#endif
177
178#ifdef BTREE_MAP
179 case T_BTREE:
180 dbp.db = dbopen(mapname, mode, 0644, DB_BTREE, NULL);
181 break;
182#endif
183
184 default:
185 fprintf(stderr, "%s: internal error: type %d\n", progname, type);
186 exit(EX_SOFTWARE);
187 }
188
189 if (dbp.dbx == NULL)
190 {
191 fprintf(stderr, "%s: cannot create type %s map %s\n",
192 progname, typename, mapname);
193 exit(EX_CANTCREAT);
194 }
195
196 /*
197 ** Copy the data
198 */
199
200 lineno = 0;
201 exitstat = EX_OK;
202 while (fgets(ibuf, sizeof ibuf, stdin) != NULL)
203 {
204 register char *p;
205
206 lineno++;
207
208 /*
209 ** Parse the line.
210 */
211
212 p = strchr(ibuf, '\n');
213 if (*p != '\0')
214 *p = '\0';
215 if (ibuf[0] == '\0' || ibuf[0] == '#')
216 continue;
217 if (isspace(ibuf[0]))
218 {
219 fprintf(stderr, "%s: %s: line %d: syntax error (leading space)\n",
220 progname, mapname, lineno);
221 continue;
222 }
223 key.xx.data = ibuf;
224 for (p = ibuf; *p != '\0' && !isspace(*p); p++)
1b15d3af
EA
225 {
226 if (foldcase && isupper(*p))
227 *p = tolower(*p);
228 }
d15694cb
EA
229 key.xx.size = p - key.xx.data;
230 if (inclnull)
231 key.xx.size++;
232 if (*p != '\0')
233 *p++ = '\0';
234 while (isspace(*p))
235 p++;
236 if (*p == '\0')
237 {
238 fprintf(stderr, "%s: %s: line %d: no RHS for LHS %s\n",
239 progname, mapname, lineno, key.xx.data);
240 continue;
241 }
242 val.xx.data = p;
243 val.xx.size = strlen(p);
244 if (inclnull)
245 val.xx.size++;
246
247 /*
248 ** Do the database insert.
249 */
250
251 if (verbose)
252 {
253 printf("key=`%s', val=`%s'\n", key.xx.data, val.xx.data);
254 }
255
256 switch (type)
257 {
258#ifdef DBM_MAP
259 case T_DBM:
260 st = dbm_store(dbp.dbm, key.dbm, val.dbm,
261 allowreplace ? DBM_REPLACE : DBM_INSERT);
262 break;
263#endif
264
265#if defined(BTREE_MAP) || defined(HASH_MAP)
266 case T_BTREE:
267 case T_HASH:
268 st = (*dbp.db->put)(dbp.db, &key.db, &val.db,
269 allowreplace ? 0 : R_NOOVERWRITE);
270 break;
271#endif
272 }
273
274 if (st < 0)
275 {
276 fprintf(stderr, "%s: %s: line %d: key %s: put error\n",
277 progname, mapname, lineno, key.xx.data);
278 perror(mapname);
279 exitstat = EX_IOERR;
280 }
281 else if (st > 0)
282 {
283 fprintf(stderr, "%s: %s: line %d: key %s: duplicate key\n",
284 progname, mapname, lineno, key.xx.data);
285 }
286 }
287
288 /*
289 ** Now close the database.
290 */
291
292 switch (type)
293 {
294#ifdef DBM_MAP
295 case T_DBM:
296 dbm_close(dbp.dbm);
297 break;
298#endif
299
300#if defined(HASH_MAP) || defined(BTREE_MAP)
301 case T_HASH:
302 case T_BTREE:
303 if ((*dbp.db->close)(dbp.db) < 0)
304 {
305 fprintf(stderr, "%s: %s: error on close\n",
306 progname, mapname);
307 perror(mapname);
308 exitstat = EX_IOERR;
309 }
310#endif
311 }
312
313 exit (exitstat);
314}