Clean (void) casts from usr.sbin
[dragonfly.git] / usr.sbin / yp_mkdb / yp_mkdb.c
1 /*
2  * Copyright (c) 1995, 1996
3  *      Bill Paul <wpaul@ctr.columbia.edu>.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. All advertising materials mentioning features or use of this software
14  *    must display the following acknowledgement:
15  *      This product includes software developed by Bill Paul.
16  * 4. Neither the name of the author nor the names of any co-contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  *
32  * $FreeBSD: src/usr.sbin/yp_mkdb/yp_mkdb.c,v 1.12.2.1 2002/02/15 00:46:59 des Exp $
33  * $DragonFly: src/usr.sbin/yp_mkdb/yp_mkdb.c,v 1.3 2004/12/18 22:48:14 swildner Exp $
34  */
35
36 #include <err.h>
37 #include <fcntl.h>
38 #include <limits.h>
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <string.h>
42 #include <time.h>
43 #include <unistd.h>
44 #include <rpc/rpc.h>
45 #include <rpcsvc/yp.h>
46 #include <sys/param.h>
47 #include <sys/types.h>
48 #include <sys/stat.h>
49 #include "yp_extern.h"
50 #include "ypxfr_extern.h"
51
52 char *yp_dir = "";      /* No particular default needed. */
53 int _rpcpmstart = 0;
54 int debug = 1;
55
56 static void usage()
57 {
58         fprintf(stderr, "%s\n%s\n%s\n%s\n",
59         "usage: yp_mkdb -c",
60         "       yp_mkdb -u dbname",
61         "       yp_mkdb [-c] [-b] [-s] [-f] [-i inputfile] [-o outputfile]",
62         "               [-d domainname ] [-m mastername] inputfile dbname");
63         exit(1);
64 }
65
66 #define PERM_SECURE (S_IRUSR|S_IWUSR)
67
68 static DB *open_db(path, flags)
69         char *path;
70         int flags;
71 {
72         extern HASHINFO openinfo;
73
74         return(dbopen(path, flags, PERM_SECURE, DB_HASH, &openinfo));
75 }
76
77 static void unwind(map)
78         char *map;
79 {
80         DB *dbp;
81         DBT key, data;
82
83         dbp = open_db(map, O_RDONLY);
84
85         if (dbp == NULL)
86                 err(1, "open_db(%s) failed", map);
87
88         key.data = NULL;
89         while (yp_next_record(dbp, &key, &data, 1, 1) == YP_TRUE)
90                 printf("%.*s %.*s\n", key.size,key.data,data.size,data.data);
91
92         dbp->close(dbp);
93         return;
94 }
95
96 int main (argc, argv)
97         int argc;
98         char *argv[];
99 {
100         int ch;
101         int un = 0;
102         int clear = 0;
103         int filter_plusminus = 0;
104         char *infile = NULL;
105         char *map = NULL;
106         char *domain = NULL;
107         char *infilename = NULL;
108         char *outfilename = NULL;
109         char *mastername = NULL;
110         int interdom = 0;
111         int secure = 0;
112         DB *dbp;
113         DBT key, data;
114         char buf[10240];
115         char *keybuf, *datbuf;
116         FILE *ifp;
117         char hname[MAXHOSTNAMELEN + 2];
118
119         while ((ch = getopt(argc, argv, "uhcbsfd:i:o:m:")) != -1) {
120                 switch (ch) {
121                 case 'f':
122                         filter_plusminus++;
123                         break;
124                 case 'u':
125                         un++;
126                         break;
127                 case 'c':
128                         clear++;
129                         break;
130                 case 'b':
131                         interdom++;
132                         break;
133                 case 's':
134                         secure++;
135                         break;
136                 case 'd':
137                         domain = optarg;
138                         break;
139                 case 'i':
140                         infilename = optarg;
141                         break;
142                 case 'o':
143                         outfilename = optarg;
144                         break;
145                 case 'm':
146                         mastername = optarg;
147                         break;
148                 case 'h':
149                 default:
150                         usage();
151                         break;
152                 }
153         }
154
155         argc -= optind;
156         argv += optind;
157
158         if (un) {
159                 map = argv[0];
160                 if (map == NULL)
161                         usage();
162                 unwind(map);
163                 exit(0);
164
165         }
166
167         infile = argv[0];
168         map = argv[1];
169
170         if (infile == NULL || map == NULL) {
171                 if (clear)
172                         goto doclear;
173                 usage();
174         }
175
176         if (mastername == NULL) {
177                 if (gethostname((char *)&hname, sizeof(hname)) == -1)
178                         err(1, "gethostname() failed");
179                 mastername = (char *)&hname;
180         }
181
182         /*
183          * Note that while we can read from stdin, we can't
184          * write to stdout; the db library doesn't let you
185          * write to a file stream like that.
186          */
187
188         if (!strcmp(infile, "-")) {
189                 ifp = stdin;
190         } else {
191                 if ((ifp = fopen(infile, "r")) == NULL)
192                         err(1, "failed to open %s", infile);
193         }
194
195         if ((dbp = open_db(map, O_RDWR|O_EXLOCK|O_EXCL|O_CREAT)) == NULL)
196                 err(1, "open_db(%s) failed", map);
197
198         if (interdom) {
199                 key.data = "YP_INTERDOMAIN";
200                 key.size = sizeof("YP_INTERDOMAIN") - 1;
201                 data.data = "";
202                 data.size = 0;
203                 yp_put_record(dbp, &key, &data, 0);
204         }
205
206         if (secure) {
207                 key.data = "YP_SECURE";
208                 key.size = sizeof("YP_SECURE") - 1;
209                 data.data = "";
210                 data.size = 0;
211                 yp_put_record(dbp, &key, &data, 0);
212         }
213
214         key.data = "YP_MASTER_NAME";
215         key.size = sizeof("YP_MASTER_NAME") - 1;
216         data.data = mastername;
217         data.size = strlen(mastername);
218         yp_put_record(dbp, &key, &data, 0);
219
220         key.data = "YP_LAST_MODIFIED";
221         key.size = sizeof("YP_LAST_MODIFIED") - 1;
222         snprintf(buf, sizeof(buf), "%lu", time(NULL));
223         data.data = (char *)&buf;
224         data.size = strlen(buf);
225         yp_put_record(dbp, &key, &data, 0);
226
227         if (infilename) {
228                 key.data = "YP_INPUT_FILE";
229                 key.size = sizeof("YP_INPUT_FILE") - 1;
230                 data.data = infilename;
231                 data.size = strlen(infilename);
232                 yp_put_record(dbp, &key, &data, 0);
233         }
234
235         if (outfilename) {
236                 key.data = "YP_OUTPUT_FILE";
237                 key.size = sizeof("YP_OUTPUT_FILE") - 1;
238                 data.data = outfilename;
239                 data.size = strlen(outfilename);
240                 yp_put_record(dbp, &key, &data, 0);
241         }
242
243         if (domain) {
244                 key.data = "YP_DOMAIN_NAME";
245                 key.size = sizeof("YP_DOMAIN_NAME") - 1;
246                 data.data = domain;
247                 data.size = strlen(domain);
248                 yp_put_record(dbp, &key, &data, 0);
249         }
250
251         while (fgets((char *)&buf, sizeof(buf), ifp)) {
252                 char *sep = NULL;
253                 int rval;
254
255                 /* NUL terminate */
256                 if ((sep = strchr(buf, '\n')))
257                         *sep = '\0';
258
259                 /* handle backslash line continuations */
260                 while (buf[strlen(buf) - 1] == '\\') {
261                         fgets((char *)&buf[strlen(buf) - 1],
262                                         sizeof(buf) - strlen(buf), ifp);
263                         if ((sep = strchr(buf, '\n')))
264                                 *sep = '\0';
265                 }
266
267                 /* find the separation between the key and data */
268                 if ((sep = strpbrk(buf, " \t")) == NULL) {
269                         warnx("bad input -- no white space: %s", buf);
270                         continue;
271                 }
272
273                 /* separate the strings */
274                 keybuf = (char *)&buf;
275                 datbuf = sep + 1;
276                 *sep = '\0';
277
278                 /* set datbuf to start at first non-whitespace character */
279                 while (*datbuf == ' ' || *datbuf == '\t')
280                         datbuf++;
281
282                 /* Check for silliness. */
283                 if (filter_plusminus) {
284                         if  (*keybuf == '+' || *keybuf == '-' ||
285                              *datbuf == '+' || *datbuf == '-') {
286                                 warnx("bad character at "
287                                     "start of line: %s", buf);
288                                 continue;
289                         }
290                 }
291
292                 if (strlen(keybuf) > YPMAXRECORD) {
293                         warnx("key too long: %s", keybuf);
294                         continue;
295                 }
296
297                 if (!strlen(keybuf)) {
298                         warnx("no key -- check source file for blank lines");
299                         continue;
300                 }
301
302                 if (strlen(datbuf) > YPMAXRECORD) {
303                         warnx("data too long: %s", datbuf);
304                         continue;
305                 }
306
307                 key.data = keybuf;
308                 key.size = strlen(keybuf);
309                 data.data = datbuf;
310                 data.size = strlen(datbuf);
311
312                 if ((rval = yp_put_record(dbp, &key, &data, 0)) != YP_TRUE) {
313                         switch (rval) {
314                         case YP_FALSE:
315                                 warnx("duplicate key '%s' - skipping", keybuf);
316                                 break;
317                         case YP_BADDB:
318                         default:
319                                 err(1,"failed to write new record - exiting");
320                                 break;
321                         }
322                 }
323
324         }
325
326         dbp->close(dbp);
327
328 doclear:
329
330         if (clear) {
331                 char in = 0;
332                 char *out = NULL;
333                 int stat;
334                 if ((stat = callrpc("localhost",YPPROG,YPVERS,YPPROC_CLEAR,
335                         xdr_void, (void *)&in,
336                         xdr_void, (void *)out)) != RPC_SUCCESS) {
337                         warnx("failed to send 'clear' to local ypserv: %s",
338                                 clnt_sperrno((enum clnt_stat) stat));
339                 }
340         }
341
342         exit(0);
343 }