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