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