]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.sbin/yp_mkdb/yp_mkdb.c
Add two missing eventhandler.h headers
[FreeBSD/FreeBSD.git] / usr.sbin / yp_mkdb / yp_mkdb.c
1 /*-
2  * SPDX-License-Identifier: BSD-4-Clause
3  *
4  * Copyright (c) 1995, 1996
5  *      Bill Paul <wpaul@ctr.columbia.edu>.  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 Bill Paul.
18  * 4. Neither the name of the author nor the names of any co-contributors
19  *    may be used to endorse or promote products derived from this software
20  *    without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  */
34
35 #include <sys/cdefs.h>
36 __FBSDID("$FreeBSD$");
37
38 #include <err.h>
39 #include <fcntl.h>
40 #include <limits.h>
41 #include <stdint.h>
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <string.h>
45 #include <time.h>
46 #include <unistd.h>
47 #include <rpc/rpc.h>
48 #include <rpcsvc/yp.h>
49 #include <sys/param.h>
50 #include <sys/types.h>
51 #include <sys/stat.h>
52 #include "yp_extern.h"
53 #include "ypxfr_extern.h"
54
55 char *yp_dir = "";      /* No particular default needed. */
56 int debug = 1;
57
58 static void
59 usage(void)
60 {
61         fprintf(stderr, "%s\n%s\n%s\n%s\n",
62         "usage: yp_mkdb -c",
63         "       yp_mkdb -u dbname",
64         "       yp_mkdb [-c] [-b] [-s] [-f] [-i inputfile] [-o outputfile]",
65         "               [-d domainname ] [-m mastername] inputfile dbname");
66         exit(1);
67 }
68
69 #define PERM_SECURE (S_IRUSR|S_IWUSR)
70 static DB *
71 open_db(char *path, int flags)
72 {
73         extern HASHINFO openinfo;
74
75         return(dbopen(path, flags, PERM_SECURE, DB_HASH, &openinfo));
76 }
77
78 static void
79 unwind(char *map)
80 {
81         DB *dbp;
82         DBT key, data;
83
84         dbp = open_db(map, O_RDONLY);
85
86         if (dbp == NULL)
87                 err(1, "open_db(%s) failed", map);
88
89         key.data = NULL;
90         while (yp_next_record(dbp, &key, &data, 1, 1) == YP_TRUE)
91                 printf("%.*s %.*s\n", (int)key.size, key.data, (int)data.size,
92                     data.data);
93
94         (void)(dbp->close)(dbp);
95         return;
96 }
97
98 int
99 main(int argc, char *argv[])
100 {
101         int ch;
102         int un = 0;
103         int clear = 0;
104         int filter_plusminus = 0;
105         char *infile = NULL;
106         char *map = NULL;
107         char *domain = NULL;
108         char *infilename = NULL;
109         char *outfilename = NULL;
110         char *mastername = NULL;
111         int interdom = 0;
112         int secure = 0;
113         DB *dbp;
114         DBT key, data;
115         char buf[10240];
116         char *keybuf, *datbuf;
117         FILE *ifp;
118         char hname[MAXHOSTNAMELEN + 2];
119
120         while ((ch = getopt(argc, argv, "uhcbsfd:i:o:m:")) != -1) {
121                 switch (ch) {
122                 case 'f':
123                         filter_plusminus++;
124                         break;
125                 case 'u':
126                         un++;
127                         break;
128                 case 'c':
129                         clear++;
130                         break;
131                 case 'b':
132                         interdom++;
133                         break;
134                 case 's':
135                         secure++;
136                         break;
137                 case 'd':
138                         domain = optarg;
139                         break;
140                 case 'i':
141                         infilename = optarg;
142                         break;
143                 case 'o':
144                         outfilename = optarg;
145                         break;
146                 case 'm':
147                         mastername = optarg;
148                         break;
149                 case 'h':
150                 default:
151                         usage();
152                         break;
153                 }
154         }
155
156         argc -= optind;
157         argv += optind;
158
159         if (un) {
160                 map = argv[0];
161                 if (map == NULL)
162                         usage();
163                 unwind(map);
164                 exit(0);
165
166         }
167
168         infile = argv[0];
169         map = argv[1];
170
171         if (infile == NULL || map == NULL) {
172                 if (clear)
173                         goto doclear;
174                 usage();
175         }
176
177         if (mastername == NULL) {
178                 if (gethostname((char *)&hname, sizeof(hname)) == -1)
179                         err(1, "gethostname() failed");
180                 mastername = (char *)&hname;
181         }
182
183         /*
184          * Note that while we can read from stdin, we can't
185          * write to stdout; the db library doesn't let you
186          * write to a file stream like that.
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), "%jd", (intmax_t)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         (void)(dbp->close)(dbp);
327
328 doclear:
329         if (clear) {
330                 char in = 0;
331                 char *out = NULL;
332                 int stat;
333                 if ((stat = callrpc("localhost", YPPROG,YPVERS, YPPROC_CLEAR,
334                         (xdrproc_t)xdr_void, &in,
335                         (xdrproc_t)xdr_void, out)) != RPC_SUCCESS) {
336                         warnx("failed to send 'clear' to local ypserv: %s",
337                                 clnt_sperrno((enum clnt_stat) stat));
338                 }
339         }
340
341         exit(0);
342 }