mkalias.c revision 1.2 1 /* $NetBSD: mkalias.c,v 1.2 1997/10/06 06:10:16 lukem Exp $ */
2
3 /*
4 * Copyright (c) 1997 Mats O Jansson <moj (at) stacken.kth.se>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by Mats O Jansson
18 * 4. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
22 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
25 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34 #include <sys/cdefs.h>
35 #ifndef LINT
36 __RCSID("$NetBSD: mkalias.c,v 1.2 1997/10/06 06:10:16 lukem Exp $");
37 #endif
38
39 #include <sys/types.h>
40 #include <sys/param.h>
41 #include <netinet/in.h>
42 #include <arpa/nameser.h>
43
44 #include <ctype.h>
45 #include <err.h>
46 #include <fcntl.h>
47 #include <netdb.h>
48 #include <resolv.h>
49 #include <stdio.h>
50 #include <string.h>
51 #include <unistd.h>
52
53 #include <rpc/rpc.h>
54
55 #include "ypdb.h"
56 #include "ypdef.h"
57
58 void capitalize __P((char *, int));
59 int check_host __P((char *, char *, int, int, int));
60 int main __P((int, char *[]));
61 void split_address __P((char *, int, char *, char *));
62 void usage __P((void));
63
64 extern char *__progname; /* from crt0.o */
65
66 void
67 split_address(address, len, user, host)
68 char *address;
69 int len;
70 char *user, *host;
71 {
72 char *c, *s, *r;
73 int i = 0;
74
75 if ((strchr(address, '@')) != NULL) {
76
77 s = user;
78
79 for(c = address; i < len; i++) {
80 if (*c == '@') {
81 *s = '\0';
82 s = host;
83 } else
84 *s++ = *c;
85 c++;
86 }
87 *s = '\0';
88 }
89
90 if ((r = strrchr(address, '!')) != NULL) {
91
92 s = host;
93
94 for(c = address; i < len; i++) {
95 if (c == r) {
96 *s = '\0';
97 s = user;
98 } else
99 *s++ = *c;
100 c++;
101 }
102 *s = '\0';
103 }
104 }
105
106 int
107 check_host(address, host, dflag, uflag, Eflag)
108 char *address, *host;
109 int dflag, uflag, Eflag;
110 {
111 char answer[PACKETSZ];
112 int status;
113
114 if ((dflag && strchr(address, '@')) ||
115 (uflag && strchr(address, '!')))
116 return(0);
117
118 if ((_res.options & RES_INIT) == 0)
119 res_init();
120
121 status = res_search(host, C_IN, T_AAAA, answer, sizeof(answer));
122
123 if (status == -1)
124 status = res_search(host, C_IN, T_A, answer, sizeof(answer));
125
126 if ((status == -1) && Eflag)
127 status = res_search(host, C_IN, T_MX, answer, sizeof(answer));
128
129 return(status == -1);
130 }
131
132 void
133 capitalize(name, len)
134 char *name;
135 int len;
136 {
137 char last = ' ';
138 char *c;
139 int i = 0;
140
141 for(c = name; i < len; i++) {
142 if (*c == '.') last = '.';
143 c++;
144 }
145
146 i = 0;
147 if (last == '.') {
148 for(c = name; i < len; i++) {
149 if (last == '.')
150 *c = toupper(*c);
151 last = *c++;
152 }
153 }
154 }
155
156 int
157 main(argc, argv)
158 int argc;
159 char *argv[];
160 {
161 int eflag = 0;
162 int dflag = 0;
163 int nflag = 0;
164 int sflag = 0;
165 int uflag = 0;
166 int vflag = 0;
167 int Eflag = 0;
168 int ch;
169 char *input = NULL;
170 char *output = NULL;
171 DBM *db;
172 datum key, val;
173 char *slash;
174 DBM *new_db = NULL;
175 static char mapname[] = "ypdbXXXXXXXXXX";
176 char db_mapname[MAXPATHLEN], db_outfile[MAXPATHLEN],
177 db_tempname[MAXPATHLEN];
178 int status;
179 char user[4096], host[4096]; /* XXX: DB bsize = 4096 in ypdb.c */
180 char datestr[11];
181 char myname[MAXHOSTNAMELEN];
182
183 while ((ch = getopt(argc, argv, "Edensuv")) != -1) {
184 switch(ch) {
185 case 'd':
186 dflag++; /* Don't check DNS hostname */
187 break;
188
189 case 'e':
190 eflag++; /* Check hostname */
191 break;
192
193 case 'E':
194 eflag++; /* Check hostname */
195 Eflag++; /* .. even check MX records */
196 break;
197
198 case 'n':
199 nflag++; /* Capitalize name parts */
200 break;
201
202 case 's':
203 sflag++; /* Don't know... */
204 break;
205
206 case 'u':
207 uflag++; /* Don't check UUCP hostname */
208 break;
209
210 case 'v':
211 vflag++; /* Verbose */
212 break;
213
214 default:
215 usage();
216 }
217 }
218
219 if (optind == argc)
220 usage();
221
222 input = argv[optind++];
223 if (optind < argc)
224 output = argv[optind++];
225 if (optind < argc)
226 usage();
227
228 db = ypdb_open(input, O_RDONLY, 0444);
229 if (db == NULL)
230 errx(1, "Unable to open input database `%s'", input);
231
232 if (output != NULL) {
233 if (strlen(output) + strlen(YPDB_SUFFIX) > MAXPATHLEN)
234 warnx("file name `%s' too long", output);
235 snprintf(db_outfile, sizeof(db_outfile),
236 "%s%s", output, YPDB_SUFFIX);
237
238 slash = strrchr(output, '/');
239 if (slash != NULL)
240 slash[1] = 0; /* truncate to dir */
241 else
242 *output = 0; /* elminate */
243
244 /* note: output is now directory where map goes ! */
245
246 if (strlen(output) + strlen(mapname)
247 + strlen(YPDB_SUFFIX) > MAXPATHLEN)
248 errx(1, "directory name `%s' too long", output);
249
250 snprintf(db_tempname, sizeof(db_tempname), "%s%s", output,
251 mapname);
252 mktemp(db_tempname);
253 snprintf(db_mapname, sizeof(db_mapname), "%s%s", db_tempname,
254 YPDB_SUFFIX);
255
256 new_db = ypdb_open(db_tempname, O_RDWR|O_CREAT, 0444);
257 if (new_db == NULL)
258 errx(1, "Unable to open output database `%s'",
259 db_outfile);
260 }
261
262 for (key = ypdb_firstkey(db);
263 key.dptr != NULL;
264 key = ypdb_nextkey(db)) {
265
266 val = ypdb_fetch(db, key);
267
268 if (val.dptr == NULL)
269 continue; /* No value */
270 if ((*key.dptr == '@') && (key.dsize == 1))
271 continue; /* Sendmail token */
272 if (strncmp(key.dptr, "YP_", 3)==0) /* YP token */
273 continue;
274 if (strchr(val.dptr, ',')) /* List... */
275 continue;
276 if (strchr(val.dptr, '|')) /* Pipe... */
277 continue;
278
279 if (!((strchr(val.dptr, '@')) ||
280 (strchr(val.dptr, '!'))))
281 continue; /* Skip local users */
282
283 split_address(val.dptr, val.dsize, user, host);
284
285 if (eflag && check_host(val.dptr, host, dflag, uflag, Eflag)) {
286 printf("Invalid host %s in %*.*s:%*.*s\n", host,
287 key.dsize, key.dsize, key.dptr,
288 val.dsize, val.dsize, val.dptr);
289 continue;
290 }
291
292 if (nflag)
293 capitalize(key.dptr, key.dsize);
294
295 if (new_db != NULL) {
296 status = ypdb_store(new_db, val, key, YPDB_INSERT);
297 if (status != 0) {
298 printf("%s: problem storing %*.*s %*.*s\n",
299 __progname,
300 val.dsize, val.dsize, val.dptr,
301 key.dsize, key.dsize, key.dptr);
302 }
303 }
304
305 if (vflag) {
306 printf("%*.*s --> %*.*s\n",
307 val.dsize, val.dsize, val.dptr,
308 key.dsize, key.dsize, key.dptr);
309 }
310
311 }
312
313 if (new_db != NULL) {
314 sprintf(datestr, "%010d", (int)time(NULL));
315 key.dptr = YP_LAST_KEY;
316 key.dsize = strlen(YP_LAST_KEY);
317 val.dptr = datestr;
318 val.dsize = strlen(datestr);
319 status = ypdb_store(new_db, key, val, YPDB_INSERT);
320 if (status != 0)
321 warnx("problem storing %*.*s %*.*s",
322 key.dsize, key.dsize, key.dptr,
323 val.dsize, val.dsize, val.dptr);
324 }
325
326 if (new_db != NULL) {
327 gethostname(myname, sizeof(myname) - 1);
328 key.dptr = YP_MASTER_KEY;
329 key.dsize = strlen(YP_MASTER_KEY);
330 val.dptr = myname;
331 val.dsize = strlen(myname);
332 status = ypdb_store(new_db, key, val, YPDB_INSERT);
333 if (status != 0)
334 warnx("problem storing %*.*s %*.*s",
335 key.dsize, key.dsize, key.dptr,
336 val.dsize, val.dsize, val.dptr);
337 }
338
339 ypdb_close(db);
340
341 if (new_db != NULL) {
342 ypdb_close(new_db);
343 if (rename(db_mapname, db_outfile) < 0)
344 err(1, "rename `%s' to `%s' failed", db_mapname,
345 db_outfile);
346 }
347
348 exit(0);
349 }
350
351 void
352 usage()
353 {
354 fprintf(stderr,
355 "usage: %s [-e|-E [-d] [-u]] [-n] [-v] input [output]\n",
356 __progname);
357 exit(1);
358 }
359