yp_mkdb.c revision 22496
1223637Sbz/* 2126353Smlaier * Copyright (c) 1995, 1996 3126353Smlaier * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved. 4126353Smlaier * 5130617Smlaier * Redistribution and use in source and binary forms, with or without 6126353Smlaier * modification, are permitted provided that the following conditions 7126353Smlaier * are met: 8126353Smlaier * 1. Redistributions of source code must retain the above copyright 9126353Smlaier * notice, this list of conditions and the following disclaimer. 10126353Smlaier * 2. Redistributions in binary form must reproduce the above copyright 11126353Smlaier * notice, this list of conditions and the following disclaimer in the 12126353Smlaier * documentation and/or other materials provided with the distribution. 13126353Smlaier * 3. All advertising materials mentioning features or use of this software 14126353Smlaier * must display the following acknowledgement: 15126353Smlaier * This product includes software developed by Bill Paul. 16126353Smlaier * 4. Neither the name of the author nor the names of any co-contributors 17126353Smlaier * may be used to endorse or promote products derived from this software 18126353Smlaier * without specific prior written permission. 19126353Smlaier * 20126353Smlaier * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND 21126353Smlaier * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22126353Smlaier * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23126353Smlaier * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR CONTRIBUTORS BE LIABLE 24126353Smlaier * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25126353Smlaier * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26126353Smlaier * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27126353Smlaier * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28126353Smlaier * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29126353Smlaier * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30126353Smlaier * SUCH DAMAGE. 31126353Smlaier * 32126353Smlaier * $FreeBSD: head/usr.sbin/yp_mkdb/yp_mkdb.c 22496 1997-02-09 19:34:53Z wpaul $ 33126353Smlaier */ 34127082Sobrien 35127082Sobrien#include <stdio.h> 36127082Sobrien#include <string.h> 37126353Smlaier#include <fcntl.h> 38126353Smlaier#include <sys/param.h> 39126353Smlaier#include <sys/types.h> 40145840Smlaier#include <sys/stat.h> 41126353Smlaier#include <limits.h> 42223637Sbz#include <stdlib.h> 43223637Sbz#include <unistd.h> 44223637Sbz#include <errno.h> 45223637Sbz#include <time.h> 46126353Smlaier#include <err.h> 47126353Smlaier#include <rpc/rpc.h> 48126353Smlaier#include <rpcsvc/yp.h> 49126353Smlaier#include "yp_extern.h" 50126353Smlaier#include "ypxfr_extern.h" 51171172Smlaier 52126353Smlaier#ifndef lint 53126353Smlaierstatic const char rcsid[] = "$FreeBSD: head/usr.sbin/yp_mkdb/yp_mkdb.c 22496 1997-02-09 19:34:53Z wpaul $"; 54126353Smlaier#endif 55126353Smlaier 56126353Smlaierchar *yp_dir = ""; /* No particular default needed. */ 57126353Smlaierchar *progname = "yp_mkdb"; 58263029Sglebiusint _rpcpmstart = 0; 59126353Smlaierint debug = 1; 60126353Smlaier 61126353Smlaierstatic void usage() 62126353Smlaier{ 63126353Smlaier fprintf(stderr, "usage: %s -c\n", progname); 64126353Smlaier fprintf(stderr, "usage: %s -u dbname\n", progname); 65126353Smlaier fprintf(stderr, "usage: %s [-c] [-b] [-s] [-i inputfile] \ 66126353Smlaier[-o outputfile]\n", progname); 67126353Smlaier fprintf(stderr, " [-d domainname ] [-m mastername] \ 68126353Smlaierinputfile dbname\n"); 69126353Smlaier exit(1); 70126353Smlaier} 71145840Smlaier 72145840Smlaier#define PERM_SECURE (S_IRUSR|S_IWUSR) 73145840Smlaier 74126353Smlaierstatic DB *open_db(path, flags) 75130617Smlaier char *path; 76130617Smlaier int flags; 77171172Smlaier{ 78171172Smlaier extern HASHINFO openinfo; 79223637Sbz 80223637Sbz return(dbopen(path, flags, PERM_SECURE, DB_HASH, &openinfo)); 81223637Sbz} 82145840Smlaier 83145840Smlaierstatic void unwind(map) 84145840Smlaier char *map; 85145840Smlaier{ 86145840Smlaier DB *dbp; 87145840Smlaier DBT key, data; 88145840Smlaier 89126353Smlaier dbp = open_db(map, O_RDONLY); 90145840Smlaier 91126353Smlaier if (dbp == NULL) 92171172Smlaier err(1, "open_db(%s) failed", map); 93145840Smlaier 94130617Smlaier key.data = NULL; 95130617Smlaier while(yp_next_record(dbp, &key, &data, 1, 1) == YP_TRUE) 96130617Smlaier printf("%.*s %.*s\n", key.size,key.data,data.size,data.data); 97130617Smlaier 98130617Smlaier (void)(dbp->close)(dbp); 99145840Smlaier return; 100126353Smlaier} 101126353Smlaier 102171172Smlaiermain (argc, argv) 103171172Smlaier int argc; 104171172Smlaier char *argv[]; 105171172Smlaier{ 106126353Smlaier int ch; 107126353Smlaier int un = 0; 108171172Smlaier int clear = 0; 109171172Smlaier char *infile = NULL; 110171172Smlaier char *map = NULL; 111126353Smlaier char *domain = NULL; 112126353Smlaier char *infilename = NULL; 113126353Smlaier char *outfilename = NULL; 114126353Smlaier char *mastername = NULL; 115126353Smlaier int interdom = 0; 116171172Smlaier int secure = 0; 117130617Smlaier DB *dbp; 118130617Smlaier DBT key, data; 119126353Smlaier char buf[10240]; 120126353Smlaier char *keybuf, *datbuf; 121171172Smlaier FILE *ifp; 122171172Smlaier char hname[MAXHOSTNAMELEN + 2]; 123126353Smlaier 124126353Smlaier while ((ch = getopt(argc, argv, "uhcbsd:i:o:m:")) != EOF) { 125126353Smlaier switch(ch) { 126126353Smlaier case 'u': 127126353Smlaier un++; 128126353Smlaier break; 129130617Smlaier case 'c': 130130617Smlaier clear++; 131126353Smlaier break; 132171172Smlaier case 'b': 133171172Smlaier interdom++; 134171172Smlaier break; 135171172Smlaier case 's': 136171172Smlaier secure++; 137171172Smlaier break; 138171172Smlaier case 'd': 139171172Smlaier domain = optarg; 140171172Smlaier break; 141126353Smlaier case 'i': 142126353Smlaier infilename = optarg; 143126353Smlaier break; 144126353Smlaier case 'o': 145171172Smlaier outfilename = optarg; 146171172Smlaier break; 147171172Smlaier case 'm': 148171172Smlaier mastername = optarg; 149171172Smlaier break; 150126353Smlaier case 'h': 151126353Smlaier default: 152126353Smlaier usage(); 153126353Smlaier break; 154126353Smlaier } 155126353Smlaier } 156126353Smlaier 157126353Smlaier argc -= optind; 158126353Smlaier argv += optind; 159126353Smlaier 160126353Smlaier if (un) { 161126353Smlaier map = argv[0]; 162126353Smlaier if (map == NULL) 163145840Smlaier usage(); 164126353Smlaier unwind(map); 165126353Smlaier exit(0); 166126353Smlaier 167126353Smlaier } 168126353Smlaier 169126353Smlaier infile = argv[0]; 170126353Smlaier map = argv[1]; 171126353Smlaier 172126353Smlaier if (infile == NULL || map == NULL) { 173145840Smlaier if (clear) 174126353Smlaier goto doclear; 175126353Smlaier usage(); 176126353Smlaier } 177126353Smlaier 178126353Smlaier if (mastername == NULL) { 179126353Smlaier if (gethostname((char *)&hname, sizeof(hname)) == -1) 180126353Smlaier err(1, "gethostname() failed"); 181126353Smlaier mastername = (char *)&hname; 182126353Smlaier } 183145840Smlaier 184126353Smlaier /* 185126353Smlaier * Note that while we can read from stdin, we can't 186126353Smlaier * write to stdout; the db library doesn't let you 187126353Smlaier * write to a file stream like that. 188126353Smlaier */ 189126353Smlaier 190126353Smlaier if (!strcmp(infile, "-")) { 191126353Smlaier ifp = stdin; 192126353Smlaier } else { 193145840Smlaier if ((ifp = fopen(infile, "r")) == NULL) 194126353Smlaier err(1, "failed to open %s", infile); 195126353Smlaier } 196126353Smlaier 197126353Smlaier if ((dbp = open_db(map, O_RDWR|O_EXLOCK|O_EXCL|O_CREAT)) == NULL) 198126353Smlaier err(1, "open_db(%s) failed", map); 199126353Smlaier 200126353Smlaier if (interdom) { 201126353Smlaier key.data = "YP_INTERDOMAIN"; 202126353Smlaier key.size = sizeof("YP_INTERDOMAIN") - 1; 203126353Smlaier data.data = ""; 204126353Smlaier data.size = 0; 205126353Smlaier yp_put_record(dbp, &key, &data, 0); 206126353Smlaier } 207126353Smlaier 208126353Smlaier if (secure) { 209126353Smlaier key.data = "YP_SECURE"; 210130617Smlaier key.size = sizeof("YP_SECURE") - 1; 211223637Sbz data.data = ""; 212126353Smlaier data.size = 0; 213126353Smlaier yp_put_record(dbp, &key, &data, 0); 214126353Smlaier } 215223637Sbz 216130617Smlaier key.data = "YP_MASTER_NAME"; 217130617Smlaier key.size = sizeof("YP_MASTER_NAME") - 1; 218126353Smlaier data.data = mastername; 219126353Smlaier data.size = strlen(mastername); 220126353Smlaier yp_put_record(dbp, &key, &data, 0); 221126353Smlaier 222171172Smlaier key.data = "YP_LAST_MODIFIED"; 223126353Smlaier key.size = sizeof("YP_LAST_MODIFIED") - 1; 224126353Smlaier snprintf(buf, sizeof(buf), "%lu", time(NULL)); 225126353Smlaier data.data = (char *)&buf; 226126353Smlaier data.size = strlen(buf); 227126353Smlaier yp_put_record(dbp, &key, &data, 0); 228126353Smlaier 229171172Smlaier if (infilename) { 230223637Sbz key.data = "YP_INPUT_FILE"; 231171172Smlaier key.size = sizeof("YP_INPUT_FILE") - 1; 232126353Smlaier data.data = infilename; 233126353Smlaier data.size = strlen(infilename); 234126353Smlaier yp_put_record(dbp, &key, &data, 0); 235126353Smlaier } 236126353Smlaier 237126353Smlaier if (outfilename) { 238223057Sbz key.data = "YP_OUTPUT_FILE"; 239145840Smlaier key.size = sizeof("YP_OUTPUT_FILE") - 1; 240223637Sbz data.data = outfilename; 241223637Sbz data.size = strlen(outfilename); 242223637Sbz yp_put_record(dbp, &key, &data, 0); 243223637Sbz } 244223637Sbz 245126353Smlaier if (domain) { 246126353Smlaier key.data = "YP_DOMAIN_NAME"; 247126353Smlaier key.size = sizeof("YP_DOMAIN_NAME") - 1; 248126353Smlaier data.data = domain; 249126353Smlaier data.size = strlen(domain); 250126353Smlaier yp_put_record(dbp, &key, &data, 0); 251126353Smlaier } 252126353Smlaier 253126353Smlaier while(fgets((char *)&buf, sizeof(buf), ifp)) { 254127024Smlaier char *sep = NULL; 255126355Smlaier int rval; 256126355Smlaier 257126355Smlaier /* NUL terminate */ 258126353Smlaier if ((sep = strchr(buf, '\n'))) 259126353Smlaier *sep = '\0'; 260126353Smlaier 261126353Smlaier /* handle backslash line continuations */ 262126353Smlaier while(buf[strlen(buf) - 1] == '\\') { 263126353Smlaier fgets((char *)&buf[strlen(buf) - 1], 264126353Smlaier sizeof(buf) - strlen(buf), ifp); 265126353Smlaier if ((sep = strchr(buf, '\n'))) 266126353Smlaier *sep = '\0'; 267126353Smlaier } 268126353Smlaier 269126353Smlaier /* find the separation between the key and data */ 270126353Smlaier if ((sep = strpbrk(buf, " \t")) == NULL) { 271126353Smlaier warnx("bad input -- no white space: %s", buf); 272126353Smlaier continue; 273126353Smlaier } 274126353Smlaier 275126353Smlaier /* separate the strings */ 276126353Smlaier keybuf = (char *)&buf; 277126353Smlaier datbuf = sep + 1; 278126353Smlaier *sep = '\0'; 279126353Smlaier 280126353Smlaier /* set datbuf to start at first non-whitespace character */ 281126353Smlaier while (*datbuf == ' ' || *datbuf == '\t') 282126353Smlaier datbuf++; 283126353Smlaier 284126353Smlaier /* Check for silliness. */ 285126353Smlaier if (*keybuf == '+' || *keybuf == '-' || 286126353Smlaier *datbuf == '+' || *datbuf == '-') { 287126353Smlaier warnx("bad character at start of line: %s", buf); 288126353Smlaier continue; 289126353Smlaier } 290126353Smlaier 291126353Smlaier if (strlen(keybuf) > YPMAXRECORD) { 292126353Smlaier warnx("key too long: %s", keybuf); 293126353Smlaier continue; 294126353Smlaier } 295126353Smlaier 296126353Smlaier if (!strlen(keybuf)) { 297126353Smlaier warnx("no key -- check source file for blank lines"); 298126353Smlaier continue; 299126353Smlaier } 300126353Smlaier 301145840Smlaier if (strlen(datbuf) > YPMAXRECORD) { 302126353Smlaier warnx("data too long: %s", datbuf); 303145840Smlaier continue; 304126353Smlaier } 305145840Smlaier 306145840Smlaier key.data = keybuf; 307171172Smlaier key.size = strlen(keybuf); 308126353Smlaier data.data = datbuf; 309145840Smlaier data.size = strlen(datbuf); 310145840Smlaier 311126353Smlaier if ((rval = yp_put_record(dbp, &key, &data, 0)) != YP_TRUE) { 312145840Smlaier switch(rval) { 313126353Smlaier case YP_FALSE: 314145840Smlaier warnx("duplicate key '%s' - skipping", keybuf); 315145840Smlaier break; 316145840Smlaier case YP_BADDB: 317145840Smlaier default: 318145840Smlaier err(1,"failed to write new record - exiting"); 319145840Smlaier break; 320145840Smlaier } 321145840Smlaier } 322130617Smlaier 323130617Smlaier } 324145840Smlaier 325145840Smlaier (void)(dbp->close)(dbp); 326130617Smlaier 327130617Smlaierdoclear: 328130617Smlaier 329126353Smlaier if (clear) { 330126353Smlaier char in = 0; 331126353Smlaier char *out = NULL; 332126353Smlaier int stat; 333126353Smlaier if ((stat = callrpc("localhost",YPPROG,YPVERS,YPPROC_CLEAR, 334126353Smlaier xdr_void, (void *)&in, 335145840Smlaier xdr_void, (void *)out)) != RPC_SUCCESS) { 336126353Smlaier warnx("failed to send 'clear' to local ypserv: %s", 337130617Smlaier clnt_sperrno((enum clnt_stat) stat)); 338126353Smlaier } 339130617Smlaier } 340130617Smlaier 341145840Smlaier exit(0); 342145840Smlaier} 343145840Smlaier