1/* 2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights 7 * Reserved. This file contains Original Code and/or Modifications of 8 * Original Code as defined in and that are subject to the Apple Public 9 * Source License Version 1.0 (the 'License'). You may not use this file 10 * except in compliance with the License. Please obtain a copy of the 11 * License at http://www.apple.com/publicsource and read it before using 12 * this file. 13 * 14 * The Original Code and all software distributed under the License are 15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the 19 * License for the specific language governing rights and limitations 20 * under the License." 21 * 22 * @APPLE_LICENSE_HEADER_END@ 23 */ 24/* $OpenBSD: makedbm.c,v 1.9 1997/08/18 03:11:34 millert Exp $ */ 25 26/* 27 * Copyright (c) 1994-97 Mats O Jansson <moj@stacken.kth.se> 28 * All rights reserved. 29 * 30 * Redistribution and use in source and binary forms, with or without 31 * modification, are permitted provided that the following conditions 32 * are met: 33 * 1. Redistributions of source code must retain the above copyright 34 * notice, this list of conditions and the following disclaimer. 35 * 2. Redistributions in binary form must reproduce the above copyright 36 * notice, this list of conditions and the following disclaimer in the 37 * documentation and/or other materials provided with the distribution. 38 * 3. All advertising materials mentioning features or use of this software 39 * must display the following acknowledgement: 40 * This product includes software developed by Mats O Jansson 41 * 4. The name of the author may not be used to endorse or promote products 42 * derived from this software without specific prior written permission. 43 * 44 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 45 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 46 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 47 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 48 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 49 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 50 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 51 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 52 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 53 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 54 * SUCH DAMAGE. 55 */ 56 57#include <sys/cdefs.h> 58#ifndef LINT 59__unused static char rcsid[] = "$OpenBSD: makedbm.c,v 1.9 1997/08/18 03:11:34 millert Exp $"; 60#endif 61 62#include <stdio.h> 63#include <stdlib.h> 64#include <time.h> 65#include <fcntl.h> 66#include <ctype.h> 67#include <sys/stat.h> 68#include <sys/param.h> 69#include <unistd.h> 70#include <string.h> 71#include <sys/errno.h> 72#include "ypdb.h" 73#include "ypdef.h" 74#include "db.h" 75 76extern char *__progname; /* from crt0.o */ 77extern int db_hash_list_database(char *); 78 79/* 80 * Read one line 81 */ 82 83static int read_line(fp, buf, size) 84 FILE *fp; 85 char *buf; 86 int size; 87{ 88 int done; 89 90 done = 0; 91 92 do { 93 while (fgets(buf, size, fp)) { 94 int len = strlen(buf); 95 done += len; 96 if (len > 1 && buf[len-2] == '\\' && 97 buf[len-1] == '\n') { 98 int ch; 99 buf += len - 2; 100 size -= len - 2; 101 *buf = '\n'; buf[1] = '\0'; 102 103 /* Skip leading white space on next line */ 104 while ((ch = getc(fp)) != EOF && 105 isascii(ch) && isspace(ch)) 106 ; 107 (void) ungetc(ch, fp); 108 } else { 109 return done; 110 } 111 } 112 } while (size > 0 && !feof(fp)); 113 114 return done; 115} 116 117void 118add_record(db, str1, str2, check) 119 DBM *db; 120 char *str1, *str2; 121 int check; 122{ 123 datum key,val; 124 int status; 125 126 key.dptr = str1; 127 key.dsize = strlen(str1); 128 129 if (check) { 130 val = ypdb_fetch(db,key); 131 132 if (val.dptr != NULL) 133 return; /* already there */ 134 135 } 136 137 val.dptr = str2; 138 val.dsize = strlen(str2); 139 status = ypdb_store(db, key, val, YPDB_INSERT); 140 141 if (status != 0) { 142 printf("%s: problem storing %s %s\n",__progname,str1,str2); 143 exit(1); 144 } 145} 146 147static char * 148file_date(filename) 149 char *filename; 150{ 151 struct stat finfo; 152 static char datestr[11]; 153 int status; 154 155 if (strcmp(filename,"-") == 0) { 156 sprintf(datestr, "%010ld", time(0)); 157 } else { 158 status = stat(filename, &finfo); 159 if (status < 0) { 160 fprintf(stderr, "%s: can't stat %s\n", __progname, filename); 161 exit(1); 162 } 163 sprintf(datestr, "%010ld", finfo.st_mtime); 164 } 165 166 return datestr; 167} 168 169void 170list_database(database,Uflag) 171 char *database; 172 int Uflag; 173{ 174 DBM *db; 175 datum key,val; 176 177 db = ypdb_open(database, O_RDONLY, 0444); 178 179 if (db == NULL) { 180 181 if (Uflag != 0) { 182 183 if (db_hash_list_database(database)) return; 184 185 } 186 187 188 fprintf(stderr, "%s: can't open database %s\n", __progname, database); 189 exit(1); 190 } 191 192 key = ypdb_firstkey(db); 193 194 while (key.dptr != NULL) { 195 val = ypdb_fetch(db,key); 196 printf("%*.*s %*.*s\n", 197 key.dsize, key.dsize, key.dptr, 198 val.dsize, val.dsize, val.dptr); 199 key = ypdb_nextkey(db); 200 } 201 202 ypdb_close(db); 203 204} 205 206void 207 208create_database(infile,database, 209 yp_input_file,yp_output_file, 210 yp_master_name,yp_domain_name, 211 bflag, lflag, sflag) 212 char *infile, *database; 213 char *yp_input_file, *yp_output_file; 214 char *yp_master_name, *yp_domain_name; 215 int bflag, lflag, sflag; 216{ 217 FILE *data_file; 218 char data_line[4096]; /* XXX: DB bsize = 4096 in ypdb.c */ 219 char myname[MAXHOSTNAMELEN]; 220 int line_no = 0; 221 int len; 222 char *p,*k,*v; 223 char *slash; 224 DBM *new_db; 225 static char mapname[] = "ypdbXXXXXXXXXX"; 226 char db_mapname[MAXPATHLEN],db_outfile[MAXPATHLEN], 227 db_tempname[MAXPATHLEN]; 228 char empty_str[] = ""; 229 230 if (strcmp(infile,"-") == 0) { 231 data_file = stdin; 232 } else { 233 data_file = fopen(infile, "r"); 234 if (errno != 0) { 235 (void)fprintf(stderr,"%s: ",__progname); 236 perror(infile); 237 exit(1); 238 } 239 } 240 241 if (strlen(database) + strlen(YPDB_SUFFIX) > MAXPATHLEN) { 242 fprintf(stderr,"%s: %s: file name too long\n", 243 __progname, database); 244 exit(1); 245 } 246 snprintf(db_outfile, sizeof(db_outfile), "%s%s", database, YPDB_SUFFIX); 247 248 slash = strrchr(database, '/'); 249 if (slash != NULL) 250 slash[1] = 0; /* truncate to dir */ 251 else 252 *database = 0; /* elminate */ 253 254 /* note: database is now directory where map goes ! */ 255 256 if (strlen(database) + strlen(mapname) 257 + strlen(YPDB_SUFFIX) > MAXPATHLEN) { 258 fprintf(stderr,"%s: %s: directory name too long\n", 259 __progname, database); 260 exit(1); 261 } 262 263 snprintf(db_tempname, sizeof(db_tempname), "%s%s", database, 264 mapname); 265 mktemp(db_tempname); 266 snprintf(db_mapname, sizeof(db_mapname), "%s%s", db_tempname, 267 YPDB_SUFFIX); 268 269 new_db = ypdb_open(db_tempname, O_RDWR|O_CREAT, 0444); 270 271 while (read_line(data_file,data_line,sizeof(data_line))) { 272 273 line_no++; 274 len = strlen(data_line); 275 276 /* Check if we have the whole line */ 277 278 if (data_line[len-1] != '\n') { 279 fprintf(stderr, "line %d in \"%s\" is too long", 280 line_no, infile); 281 } else { 282 data_line[len-1] = '\0'; 283 } 284 285 p = (char *) &data_line; 286 287 k = p; /* save start of key */ 288 while (!isspace(*p)) { /* find first "space" */ 289 if (lflag && isupper(*p)) /* if force lower case */ 290 *p = tolower(*p); /* fix it */ 291 p++; 292 }; 293 while (isspace(*p)) { /* replace space with <NUL> */ 294 *p = '\0'; 295 p++; 296 }; 297 298 v = p; /* save start of value */ 299 while(*p != '\0') { p++; }; /* find end of string */ 300 301 add_record(new_db, k, v, TRUE); /* save record */ 302 303 } 304 305 if (strcmp(infile,"-") != 0) { 306 (void) fclose(data_file); 307 } 308 309 add_record(new_db, YP_LAST_KEY, file_date(infile), FALSE); 310 311 if (yp_input_file) { 312 add_record(new_db, YP_INPUT_KEY, yp_input_file, FALSE); 313 } 314 315 if (yp_output_file) { 316 add_record(new_db, YP_OUTPUT_KEY, yp_output_file, FALSE); 317 } 318 319 if (yp_master_name) { 320 add_record(new_db, YP_MASTER_KEY, yp_master_name, FALSE); 321 } else { 322 gethostname(myname, sizeof(myname) - 1); 323 add_record(new_db, YP_MASTER_KEY, myname, FALSE); 324 } 325 326 if (yp_domain_name) { 327 add_record(new_db, YP_DOMAIN_KEY, yp_domain_name, FALSE); 328 } 329 330 if (bflag) { 331 add_record(new_db, YP_INTERDOMAIN_KEY, empty_str, FALSE); 332 } 333 334 if (sflag) { 335 add_record(new_db, YP_SECURE_KEY, empty_str, FALSE); 336 } 337 338 ypdb_close(new_db); 339 if (rename(db_mapname,db_outfile) < 0) { 340 perror("rename"); 341 fprintf(stderr,"rename %s -> %s failed!\n", db_mapname, 342 db_outfile); 343 exit(1); 344 } 345 346} 347 348int 349main (argc,argv) 350 int argc; 351 char *argv[]; 352{ 353 int aflag, uflag, bflag, lflag, sflag, Uflag; 354 char *yp_input_file, *yp_output_file; 355 char *yp_master_name,*yp_domain_name; 356 char *infile,*outfile; 357 int usage = 0; 358 int ch; 359 360 extern int optind; 361 362 yp_input_file = yp_output_file = NULL; 363 yp_master_name = yp_domain_name = NULL; 364 aflag = uflag = bflag = lflag = sflag = Uflag = 0; 365 infile = outfile = NULL; 366 367 while ((ch = getopt(argc, argv, "Ublsui:o:m:d:")) != -1) 368 switch (ch) { 369 case 'U': 370 uflag++; 371 Uflag++; 372 break; 373 case 'b': 374 bflag++; 375 aflag++; 376 break; 377 case 'l': 378 lflag++; 379 aflag++; 380 break; 381 case 's': 382 sflag++; 383 aflag++; 384 break; 385 case 'i': 386 yp_input_file = argv[optind]; 387 aflag++; 388 break; 389 case 'o': 390 yp_output_file = argv[optind]; 391 aflag++; 392 break; 393 case 'm': 394 yp_master_name = argv[optind]; 395 aflag++; 396 break; 397 case 'd': 398 yp_domain_name = argv[optind]; 399 aflag++; 400 break; 401 case 'u': 402 uflag++; 403 break; 404 default: 405 usage++; 406 break; 407 } 408 409 if ((uflag != 0) && (aflag != 0)) { 410 usage++; 411 } else { 412 413 if (uflag != 0) { 414 if (argc == (optind + 1)) { 415 infile = argv[optind]; 416 } else { 417 usage++; 418 } 419 } else { 420 if (argc == (optind + 2)) { 421 infile = argv[optind]; 422 outfile = argv[optind+1]; 423 } else { 424 usage++; 425 } 426 } 427 } 428 429 if (usage) { 430 fprintf(stderr,"%s%s%s", 431 "usage:\tmakedbm [-u|-U] file\n\tmakedbm [-bls]", 432 " [-i YP_INPUT_FILE] [-o YP_OUTPUT_FILE]\n\t\t", 433 "[-d YP_DOMAIN_NAME] [-m YP_MASTER_NAME] infile outfile\n"); 434 exit(1); 435 } 436 437 if (uflag != 0) { 438 list_database(infile,Uflag); 439 } else { 440 create_database(infile,outfile, 441 yp_input_file,yp_output_file, 442 yp_master_name,yp_domain_name, 443 bflag, lflag, sflag); 444 } 445 446 return(0); 447 448} 449