4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
31 * Portions of this source code were derived from Berkeley
32 * under license from the Regents of the University of
38 #include <sys/types.h>
40 #include <sys/param.h>
47 #include <sys/systeminfo.h>
62 extern void sysvconfig();
64 extern int yp_getalias();
66 #define MAXLINE 4096 /* max length of input line */
67 #define DEFAULT_SEP " "
68 static char *get_date();
70 static void addpair();
74 int inode_dev_valid
= 0;
79 * Interpose close(2) to enable us to keep one of the output
80 * files open until process exit.
82 #pragma weak _close = close
87 static int (*fptr
)() = 0;
90 fptr
= (int (*)())dlsym(RTLD_NEXT
, "close");
92 fprintf(stderr
, "makedbm: dlopen(close): %s\n",
99 if (inode_dev_valid
!= 0 && fstat64(filedes
, &sb
) == 0) {
100 if (sb
.st_ino
== inode
&& sb
.st_dev
== dev
) {
101 /* Keep open; pretend successful */
106 return ((*fptr
)(filedes
));
115 datum key
, content
, tmp
;
117 char pagbuf
[MAXPATHLEN
];
118 char tmppagbuf
[MAXPATHLEN
];
119 char dirbuf
[MAXPATHLEN
];
120 char tmpdirbuf
[MAXPATHLEN
];
122 char *infile
, *outfile
;
123 char outalias
[MAXPATHLEN
];
124 char outaliasmap
[MAXNAMLEN
];
125 char outaliasdomain
[MAXNAMLEN
];
126 char *last_slash
, *next_to_last_slash
;
127 char *infilename
, *outfilename
, *mastername
, *domainname
,
128 *interdomain_bind
, *security
, *lower_case_keys
;
129 char key_sep
[] = DEFAULT_SEP
;
130 char local_host
[MAX_MASTER_NAME
];
133 struct stat64 statbuf
;
134 int num_del_to_match
= 0;
135 /* flag to indicate if matching char can be escaped */
138 /* Ignore existing umask, always force 077 (owner rw only) */
141 infile
= outfile
= NULL
; /* where to get files */
142 /* name to imbed in database */
143 infilename
= outfilename
= mastername
= domainname
= interdomain_bind
=
144 security
= lower_case_keys
= NULL
;
148 if (argv
[0][0] == '-' && argv
[0][1]) {
149 switch (argv
[0][1]) {
151 infilename
= argv
[1];
156 outfilename
= argv
[1];
161 mastername
= argv
[1];
166 interdomain_bind
= argv
[0];
169 domainname
= argv
[1];
174 lower_case_keys
= argv
[0];
180 if (strlen(argv
[1]) != 1) {
185 key_sep
[0] = argv
[1][0];
190 num_del_to_match
= atoi(argv
[1]);
205 } else if (infile
== NULL
)
207 else if (outfile
== NULL
)
214 if (infile
== NULL
|| outfile
== NULL
)
218 * do alias mapping if necessary
220 last_slash
= strrchr(outfile
, '/');
223 next_to_last_slash
= strrchr(outfile
, '/');
224 if (next_to_last_slash
) *next_to_last_slash
= '\0';
225 } else next_to_last_slash
= NULL
;
228 if (last_slash
) printf("last_slash=%s\n", last_slash
+1);
229 if (next_to_last_slash
) printf("next_to_last_slash=%s\n",
230 next_to_last_slash
+1);
233 /* reads in alias file for system v filename translation */
238 if (last_slash
&& next_to_last_slash
) {
239 if (yp_getalias(last_slash
+1, outaliasmap
, MAXALIASLEN
) < 0) {
240 if ((int)strlen(last_slash
+1) <= MAXALIASLEN
)
241 strcpy(outaliasmap
, last_slash
+1);
244 "makedbm: warning: no alias for %s\n",
248 printf("%s\n", last_slash
+1);
249 printf("%s\n", outaliasmap
);
251 if (yp_getalias(next_to_last_slash
+1, outaliasdomain
,
253 if ((int)strlen(last_slash
+1) <= NAME_MAX
)
254 strcpy(outaliasdomain
, next_to_last_slash
+1);
257 "makedbm: warning: no alias for %s\n",
258 next_to_last_slash
+1);
261 printf("%s\n", next_to_last_slash
+1);
262 printf("%s\n", outaliasdomain
);
264 sprintf(outalias
, "%s/%s/%s", outfile
, outaliasdomain
,
267 printf("outlias=%s\n", outalias
);
270 } else if (last_slash
) {
271 if (yp_getalias(last_slash
+1, outaliasmap
, MAXALIASLEN
) < 0) {
272 if ((int)strlen(last_slash
+1) <= MAXALIASLEN
)
273 strcpy(outaliasmap
, last_slash
+1);
276 "makedbm: warning: no alias for %s\n",
279 if (yp_getalias(outfile
, outaliasdomain
, NAME_MAX
) < 0) {
280 if ((int)strlen(outfile
) <= NAME_MAX
)
281 strcpy(outaliasdomain
, outfile
);
284 "makedbm: warning: no alias for %s\n",
287 sprintf(outalias
, "%s/%s", outaliasdomain
, outaliasmap
);
289 if (yp_getalias(outfile
, outalias
, MAXALIASLEN
) < 0) {
290 if ((int)strlen(last_slash
+1) <= MAXALIASLEN
)
291 strcpy(outalias
, outfile
);
294 "makedbm: warning: no alias for %s\n",
299 fprintf(stderr
, "outalias=%s\n", outalias
);
300 fprintf(stderr
, "outfile=%s\n", outfile
);
303 strcpy(tmppagbuf
, outalias
);
304 strcat(tmppagbuf
, ".tmp");
305 strcpy(tmpdirbuf
, tmppagbuf
);
306 strcat(tmpdirbuf
, dbm_dir
);
307 strcat(tmppagbuf
, dbm_pag
);
309 /* Loop until we can lock the tmpdirbuf file */
312 if (strcmp(infile
, "-") != 0)
313 infp
= fopen(infile
, "r");
314 else if (fstat64(fileno(stdin
), &statbuf
) == -1) {
315 fprintf(stderr
, "makedbm: can't open stdin\n");
321 fprintf(stderr
, "makedbm: can't open %s\n", infile
);
325 if ((outfp
= fopen(tmpdirbuf
, "w")) == (FILE *)NULL
) {
326 fprintf(stderr
, "makedbm: can't create %s\n",
331 if (lockf(fileno(outfp
), F_TLOCK
, 0) == 0) {
332 /* Got exclusive access; save inode and dev */
333 if (fstat64(fileno(outfp
), &statbuf
) != 0) {
334 fprintf(stderr
, "makedbm: can't fstat ");
338 inode
= statbuf
.st_ino
;
339 dev
= statbuf
.st_dev
;
344 if (errno
!= EAGAIN
) {
345 fprintf(stderr
, "makedbm: can't lock ");
351 * Someone else is holding the lock.
352 * Close both output and input file
353 * (the latter to ensure consistency
354 * if the input file is updated while
355 * we're suspended), wait a little,
360 (void) fclose(outfp
);
364 if (fopen(tmppagbuf
, "w") == (FILE *)NULL
) {
365 fprintf(stderr
, "makedbm: can't create %s\n", tmppagbuf
);
368 strcpy(dirbuf
, outalias
);
369 strcat(dirbuf
, ".tmp");
370 if ((fdb
= dbm_open(dirbuf
, O_RDWR
| O_CREAT
, 0644)) == NULL
) {
371 fprintf(stderr
, "makedbm: can't open %s\n", dirbuf
);
374 strcpy(dirbuf
, outalias
);
375 strcpy(pagbuf
, outalias
);
376 strcat(dirbuf
, dbm_dir
);
377 strcat(pagbuf
, dbm_pag
);
378 while (fgets(buf
, sizeof (buf
), infp
) != NULL
) {
380 cnt
= strlen(buf
) - 1; /* erase trailing newline */
381 while (p
[cnt
-1] == '\\') {
383 if (fgets(p
, sizeof (buf
)-(p
-buf
), infp
) == NULL
)
387 if (strcmp(key_sep
, DEFAULT_SEP
) == 0) {
388 p
= any(buf
, " \t\n", num_del_to_match
, count_esp
);
390 p
= any(buf
, key_sep
, num_del_to_match
, count_esp
);
395 if (p
== NULL
|| *p
== NULL
) {
397 "makedbm: source files is garbage!\n");
400 if (*p
!= ' ' && *p
!= '\t' && *p
!= key_sep
[0])
405 content
.dsize
= strlen(p
) - 1; /* erase trailing newline */
406 if (lower_case_keys
) {
407 for (i
= (strncmp(key
.dptr
, "YP_MULTI_", 9) ? 0 : 9);
408 i
< key
.dsize
; i
++) {
411 if (isascii(ic
) && isupper(ic
))
412 *(key
.dptr
+i
) = tolower(ic
);
415 tmp
= dbm_fetch(fdb
, key
);
416 if (tmp
.dptr
== NULL
) {
417 if (dbm_store(fdb
, key
, content
, 1) != 0) {
418 printf("problem storing %.*s %.*s\n",
420 content
.dsize
, content
.dptr
);
426 printf("duplicate: %.*s %.*s\n",
428 content
.dsize
, content
.dptr
);
433 addpair(fdb
, yp_last_modified
, get_date(infile
));
435 addpair(fdb
, yp_input_file
, infilename
);
437 addpair(fdb
, yp_output_file
, outfilename
);
439 addpair(fdb
, yp_domain_name
, domainname
);
441 addpair(fdb
, yp_secure
, "");
442 if (interdomain_bind
)
443 addpair(fdb
, yp_interdomain
, "");
445 sysinfo(SI_HOSTNAME
, local_host
, sizeof (local_host
) - 1);
446 mastername
= local_host
;
448 addpair(fdb
, yp_master_name
, mastername
);
449 (void) dbm_close(fdb
);
451 fprintf(stderr
, ".tmp ndbm map closed. ndbm successful !\n");
453 if (rename(tmppagbuf
, pagbuf
) < 0) {
454 perror("makedbm: rename");
455 unlink(tmppagbuf
); /* Remove the tmp files */
459 if (rename(tmpdirbuf
, dirbuf
) < 0) {
460 perror("makedbm: rename");
461 unlink(tmppagbuf
); /* Remove the tmp files */
466 * sprintf(buf, "mv %s %s", tmppagbuf, pagbuf);
467 * if (system(buf) < 0)
468 * perror("makedbm: rename");
469 * sprintf(buf, "mv %s %s", tmpdirbuf, dirbuf);
470 * if (system(buf) < 0)
471 * perror("makedbm: rename");
478 * scans cp, looking for a match with any character
479 * in match. Returns pointer to place in cp that matched
480 * (or NULL if no match)
482 * It will find the num_del_to_match+1
483 * matching character in the line.
485 * The backslash escapes a delimiter if count_esp==1
486 * We don't count it as a character match if
487 * an escape character precedes a matching character.
491 any(cp
, match
, num_del_to_match
, count_esp
)
494 int num_del_to_match
;
497 register char *mp
, c
, prev_char
;
503 for (mp
= match
; *mp
; mp
++) {
507 } else if (prev_char
!= '\\') {
510 if (num_del_matched
> num_del_to_match
)
524 struct stat filestat
;
525 static char ans
[MAX_ASCII_ORDER_NUMBER_LENGTH
];
526 /* ASCII numeric string */
528 if (strcmp(name
, "-") == 0)
529 sprintf(ans
, "%010ld", (long)time(0));
531 if (stat(name
, &filestat
) < 0) {
532 fprintf(stderr
, "makedbm: can't stat %s\n", name
);
535 sprintf(ans
, "%010ld", (long)filestat
.st_mtime
);
544 "usage: makedbm -u file\n makedbm [-b] [-l] [-s] [-i YP_INPUT_FILE] "
545 "[-o YP_OUTPUT_FILE] [-d YP_DOMAIN_NAME] [-m YP_MASTER_NAME] "
546 "[-S DELIMITER] [-D NUM_DELIMITER_TO_SKIP] [-E] "
552 addpair(fdb
, str1
, str2
)
560 key
.dsize
= strlen(str1
);
562 content
.dsize
= strlen(str2
);
563 if (dbm_store(fdb
, key
, content
, 1) != 0) {
564 printf("makedbm: problem storing %.*s %.*s\n",
565 key
.dsize
, key
.dptr
, content
.dsize
, content
.dptr
);
580 if ((fdb
= dbm_open(file
, O_RDONLY
, 0644)) == NULL
) {
581 fprintf(stderr
, "makedbm: couldn't open %s dbm file\n", file
);
585 for (key
= dbm_firstkey(fdb
); key
.dptr
!= NULL
;
586 key
= dbm_nextkey(fdb
)) {
587 content
= dbm_fetch(fdb
, key
);
588 printf("%.*s %.*s\n", key
.dsize
, key
.dptr
,
589 content
.dsize
, content
.dptr
);