Tue Oct 7 10:03:47 2008 UTC ()
Explicitly pull in "nbtool_config.h" if available.
Fixes tools/db build, as reported by Matthias Scheler.


(lukem)
diff -r1.21 -r1.22 src/usr.bin/db/db.c

cvs diff -r1.21 -r1.22 src/usr.bin/db/db.c (switch to unified diff)

--- src/usr.bin/db/db.c 2008/10/07 01:32:51 1.21
+++ src/usr.bin/db/db.c 2008/10/07 10:03:47 1.22
@@ -1,716 +1,720 @@ @@ -1,716 +1,720 @@
1/* $NetBSD: db.c,v 1.21 2008/10/07 01:32:51 lukem Exp $ */ 1/* $NetBSD: db.c,v 1.22 2008/10/07 10:03:47 lukem Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2002-2008 The NetBSD Foundation, Inc. 4 * Copyright (c) 2002-2008 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Luke Mewburn of Wasabi Systems. 8 * by Luke Mewburn of Wasabi Systems.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
 32#if HAVE_NBTOOL_CONFIG_H
 33#include "nbtool_config.h"
 34#endif
 35
32#include <sys/cdefs.h> 36#include <sys/cdefs.h>
33#ifndef lint 37#ifndef lint
34#ifdef __RCSID 38#ifdef __RCSID
35__RCSID("$NetBSD: db.c,v 1.21 2008/10/07 01:32:51 lukem Exp $"); 39__RCSID("$NetBSD: db.c,v 1.22 2008/10/07 10:03:47 lukem Exp $");
36#endif /* __RCSID */ 40#endif /* __RCSID */
37#endif /* not lint */ 41#endif /* not lint */
38 42
39#include <ctype.h> 43#include <ctype.h>
40#include <db.h> 44#include <db.h>
41#include <err.h> 45#include <err.h>
42#include <fcntl.h> 46#include <fcntl.h>
43#include <limits.h> 47#include <limits.h>
44#include <stdio.h> 48#include <stdio.h>
45#include <stdlib.h> 49#include <stdlib.h>
46#include <string.h> 50#include <string.h>
47#include <unistd.h> 51#include <unistd.h>
48#include <vis.h> 52#include <vis.h>
49 53
50 54
51typedef enum { 55typedef enum {
52 F_WRITE = 1<<0, 56 F_WRITE = 1<<0,
53 F_DELETE = 1<<1, 57 F_DELETE = 1<<1,
54 F_SHOW_KEY = 1<<2, 58 F_SHOW_KEY = 1<<2,
55 F_SHOW_VALUE = 1<<3, 59 F_SHOW_VALUE = 1<<3,
56 F_QUIET = 1<<10, 60 F_QUIET = 1<<10,
57 F_IGNORECASE = 1<<11, 61 F_IGNORECASE = 1<<11,
58 F_ENDIAN_BIG = 1<<12, 62 F_ENDIAN_BIG = 1<<12,
59 F_ENDIAN_LITTLE = 1<<13, 63 F_ENDIAN_LITTLE = 1<<13,
60 F_NO_NUL = 1<<14, 64 F_NO_NUL = 1<<14,
61 F_CREATENEW = 1<<20, 65 F_CREATENEW = 1<<20,
62 F_DUPLICATES = 1<<21, 66 F_DUPLICATES = 1<<21,
63 F_REPLACE = 1<<22, 67 F_REPLACE = 1<<22,
64 F_ENCODE_KEY = 1<<23, 68 F_ENCODE_KEY = 1<<23,
65 F_ENCODE_VAL = 1<<24, 69 F_ENCODE_VAL = 1<<24,
66 F_DECODE_KEY = 1<<25, 70 F_DECODE_KEY = 1<<25,
67 F_DECODE_VAL = 1<<26, 71 F_DECODE_VAL = 1<<26,
68} flags_t; 72} flags_t;
69 73
70int main(int, char *[]); 74int main(int, char *[]);
71void db_print(DBT *, DBT *); 75void db_print(DBT *, DBT *);
72int db_dump(void); 76int db_dump(void);
73int db_del(char *); 77int db_del(char *);
74int db_get(char *); 78int db_get(char *);
75int db_put(char *, char *); 79int db_put(char *, char *);
76int parseline(FILE *, const char *, char **, char **); 80int parseline(FILE *, const char *, char **, char **);
77int encode_data(size_t, char *, char **); 81int encode_data(size_t, char *, char **);
78int decode_data(char *, char **); 82int decode_data(char *, char **);
79void parse_encode_decode_arg(const char *, int); 83void parse_encode_decode_arg(const char *, int);
80int parse_encode_option(char **); 84int parse_encode_option(char **);
81void usage(void); 85void usage(void);
82 86
83flags_t flags = 0; 87flags_t flags = 0;
84DB *db; 88DB *db;
85const char *outputsep = "\t"; 89const char *outputsep = "\t";
86int visflags = 0; 90int visflags = 0;
87const char *extra_echars = NULL; 91const char *extra_echars = NULL;
88 92
89int 93int
90main(int argc, char *argv[]) 94main(int argc, char *argv[])
91{ 95{
92 struct { 96 struct {
93 char *file; 97 char *file;
94 char *type; 98 char *type;
95 DBTYPE dbtype; 99 DBTYPE dbtype;
96 void *info; 100 void *info;
97 int flags; 101 int flags;
98 mode_t mode; 102 mode_t mode;
99 unsigned int pagesize; 103 unsigned int pagesize;
100 } oi; 104 } oi;
101 BTREEINFO btreeinfo; 105 BTREEINFO btreeinfo;
102 HASHINFO hashinfo; 106 HASHINFO hashinfo;
103 FILE *infp; 107 FILE *infp;
104 const char *infile, *fieldsep; 108 const char *infile, *fieldsep;
105 char *p, *key, *val; 109 char *p, *key, *val;
106 int ch, rv; 110 int ch, rv;
107 long lval; 111 long lval;
108 112
109 setprogname(argv[0]); 113 setprogname(argv[0]);
110 114
111 infile = NULL; 115 infile = NULL;
112 fieldsep = " "; 116 fieldsep = " ";
113 infp = NULL; 117 infp = NULL;
114 memset(&oi, 0, sizeof(oi)); 118 memset(&oi, 0, sizeof(oi));
115 oi.mode = 0644; 119 oi.mode = 0644;
116 oi.pagesize = 4096; 120 oi.pagesize = 4096;
117 121
118 /* parse arguments */ 122 /* parse arguments */
119 while ( (ch = getopt(argc, argv, 123 while ( (ch = getopt(argc, argv,
120 "CDdE:F:f:iKm:NO:P:qRS:T:U:VwX:")) != -1) { 124 "CDdE:F:f:iKm:NO:P:qRS:T:U:VwX:")) != -1) {
121 switch (ch) { 125 switch (ch) {
122 126
123 case 'C': 127 case 'C':
124 flags |= F_CREATENEW; 128 flags |= F_CREATENEW;
125 break; 129 break;
126 130
127 case 'D': 131 case 'D':
128 flags |= F_DUPLICATES; 132 flags |= F_DUPLICATES;
129 break; 133 break;
130 134
131 case 'd': 135 case 'd':
132 flags |= F_DELETE; 136 flags |= F_DELETE;
133 break; 137 break;
134 138
135 case 'E': 139 case 'E':
136 if (! optarg[0] || optarg[1]) 140 if (! optarg[0] || optarg[1])
137 goto badendian; 141 goto badendian;
138 switch (toupper((int)optarg[0])) { 142 switch (toupper((int)optarg[0])) {
139 case 'B': 143 case 'B':
140 flags |= F_ENDIAN_BIG; 144 flags |= F_ENDIAN_BIG;
141 break; 145 break;
142 case 'L': 146 case 'L':
143 flags |= F_ENDIAN_LITTLE; 147 flags |= F_ENDIAN_LITTLE;
144 break; 148 break;
145 case 'H': 149 case 'H':
146 flags &= ~(F_ENDIAN_BIG | F_ENDIAN_LITTLE); 150 flags &= ~(F_ENDIAN_BIG | F_ENDIAN_LITTLE);
147 break; 151 break;
148 default: 152 default:
149 badendian: 153 badendian:
150 errx(1, "Bad endian `%s'", optarg); 154 errx(1, "Bad endian `%s'", optarg);
151 } 155 }
152 break; 156 break;
153 157
154 case 'F': 158 case 'F':
155 if (! optarg[0]) 159 if (! optarg[0])
156 errx(1, "Invalid field separator `%s'", 160 errx(1, "Invalid field separator `%s'",
157 optarg); 161 optarg);
158 fieldsep = optarg; 162 fieldsep = optarg;
159 break; 163 break;
160 164
161 case 'f': 165 case 'f':
162 infile = optarg; 166 infile = optarg;
163 break; 167 break;
164 168
165 case 'i': 169 case 'i':
166 flags |= F_IGNORECASE; 170 flags |= F_IGNORECASE;
167 break; 171 break;
168 172
169 case 'K': 173 case 'K':
170 flags |= F_SHOW_KEY; 174 flags |= F_SHOW_KEY;
171 break; 175 break;
172 176
173 case 'm': 177 case 'm':
174 lval = strtol(optarg, &p, 8); 178 lval = strtol(optarg, &p, 8);
175 if (p == optarg || *p != '\0') 179 if (p == optarg || *p != '\0')
176 errx(1, "Invalid octal number `%s'", optarg); 180 errx(1, "Invalid octal number `%s'", optarg);
177 if (lval < 0 || lval > 07777) 181 if (lval < 0 || lval > 07777)
178 errx(1, "Invalid mode `%s'", optarg); 182 errx(1, "Invalid mode `%s'", optarg);
179 oi.mode = (mode_t)lval; 183 oi.mode = (mode_t)lval;
180 break; 184 break;
181 185
182 case 'N': 186 case 'N':
183 flags |= F_NO_NUL; 187 flags |= F_NO_NUL;
184 break; 188 break;
185 189
186 case 'O': 190 case 'O':
187 outputsep = optarg; 191 outputsep = optarg;
188 break; 192 break;
189 193
190 case 'P': 194 case 'P':
191 lval = strtol(optarg, &p, 10); 195 lval = strtol(optarg, &p, 10);
192 if (p == optarg || *p != '\0') 196 if (p == optarg || *p != '\0')
193 errx(1, "Invalid pagesize `%s'", optarg); 197 errx(1, "Invalid pagesize `%s'", optarg);
194 if (lval < 0 || lval >= UINT_MAX) 198 if (lval < 0 || lval >= UINT_MAX)
195 errx(1, "Pagesize `%s' out of range", optarg); 199 errx(1, "Pagesize `%s' out of range", optarg);
196 oi.pagesize = (unsigned int)lval; 200 oi.pagesize = (unsigned int)lval;
197 break; 201 break;
198 202
199 case 'q': 203 case 'q':
200 flags |= F_QUIET; 204 flags |= F_QUIET;
201 break; 205 break;
202 206
203 case 'R': 207 case 'R':
204 flags |= F_REPLACE; 208 flags |= F_REPLACE;
205 break; 209 break;
206 210
207 case 'S': 211 case 'S':
208 parse_encode_decode_arg(optarg, 1 /* encode */); 212 parse_encode_decode_arg(optarg, 1 /* encode */);
209 if (! (flags & (F_ENCODE_KEY | F_ENCODE_VAL))) 213 if (! (flags & (F_ENCODE_KEY | F_ENCODE_VAL)))
210 errx(1, "Invalid encoding argument `%s'", 214 errx(1, "Invalid encoding argument `%s'",
211 optarg); 215 optarg);
212 break; 216 break;
213 217
214 case 'T': 218 case 'T':
215 visflags = parse_encode_option(&optarg); 219 visflags = parse_encode_option(&optarg);
216 if (! visflags) 220 if (! visflags)
217 errx(1, "Invalid encoding/decoding option `%s'", 221 errx(1, "Invalid encoding/decoding option `%s'",
218 optarg); 222 optarg);
219 break; 223 break;
220 224
221 case 'U': 225 case 'U':
222 parse_encode_decode_arg(optarg, 0 /* decode */); 226 parse_encode_decode_arg(optarg, 0 /* decode */);
223 if (! (flags & (F_DECODE_KEY | F_DECODE_VAL))) 227 if (! (flags & (F_DECODE_KEY | F_DECODE_VAL)))
224 errx(1, "Invalid decoding argument `%s'", 228 errx(1, "Invalid decoding argument `%s'",
225 optarg); 229 optarg);
226 break; 230 break;
227 231
228 case 'V': 232 case 'V':
229 flags |= F_SHOW_VALUE; 233 flags |= F_SHOW_VALUE;
230 break; 234 break;
231 235
232 case 'w': 236 case 'w':
233 flags |= F_WRITE; 237 flags |= F_WRITE;
234 break; 238 break;
235 239
236 case 'X': 240 case 'X':
237 extra_echars = optarg; 241 extra_echars = optarg;
238 break; 242 break;
239 243
240 default: 244 default:
241 usage(); 245 usage();
242 246
243 } 247 }
244 } 248 }
245 argc -= optind; 249 argc -= optind;
246 argv += optind; 250 argv += optind;
247 251
248 /* validate arguments */ 252 /* validate arguments */
249 if (argc < 2) 253 if (argc < 2)
250 usage(); 254 usage();
251 oi.type = argv[0]; 255 oi.type = argv[0];
252 oi.file = argv[1]; 256 oi.file = argv[1];
253 argc -= 2; 257 argc -= 2;
254 argv += 2; 258 argv += 2;
255 259
256 if (flags & F_WRITE) { 260 if (flags & F_WRITE) {
257 if (flags & (F_SHOW_KEY | F_SHOW_VALUE | F_DELETE)) 261 if (flags & (F_SHOW_KEY | F_SHOW_VALUE | F_DELETE))
258 usage(); 262 usage();
259 if ((!infile && argc < 2) || (argc % 2)) 263 if ((!infile && argc < 2) || (argc % 2))
260 usage(); 264 usage();
261 if (0 != (visflags & ~(VIS_HTTPSTYLE))) 265 if (0 != (visflags & ~(VIS_HTTPSTYLE)))
262 errx(1, "Unsupported decoding option provided to -T"); 266 errx(1, "Unsupported decoding option provided to -T");
263 oi.flags = O_RDWR | O_CREAT | O_EXLOCK; 267 oi.flags = O_RDWR | O_CREAT | O_EXLOCK;
264 if (flags & F_CREATENEW) 268 if (flags & F_CREATENEW)
265 oi.flags |= O_TRUNC; 269 oi.flags |= O_TRUNC;
266 } else if (flags & F_DELETE) { 270 } else if (flags & F_DELETE) {
267 if (flags & (F_SHOW_KEY | F_SHOW_VALUE | F_WRITE)) 271 if (flags & (F_SHOW_KEY | F_SHOW_VALUE | F_WRITE))
268 usage(); 272 usage();
269 if (!infile && argc < 1) 273 if (!infile && argc < 1)
270 usage(); 274 usage();
271 if (0 != (visflags & ~(VIS_HTTPSTYLE))) 275 if (0 != (visflags & ~(VIS_HTTPSTYLE)))
272 errx(1, "Unsupported decoding option provided to -T"); 276 errx(1, "Unsupported decoding option provided to -T");
273 oi.flags = O_RDWR | O_CREAT | O_EXLOCK; 277 oi.flags = O_RDWR | O_CREAT | O_EXLOCK;
274 } else { 278 } else {
275 if (! (flags & (F_SHOW_KEY | F_SHOW_VALUE))) 279 if (! (flags & (F_SHOW_KEY | F_SHOW_VALUE)))
276 flags |= (F_SHOW_KEY | F_SHOW_VALUE); 280 flags |= (F_SHOW_KEY | F_SHOW_VALUE);
277 oi.flags = O_RDONLY | O_SHLOCK; 281 oi.flags = O_RDONLY | O_SHLOCK;
278 } 282 }
279 283
280 /* validate oi.type */ 284 /* validate oi.type */
281 if (strcmp(oi.type, "btree") == 0) { 285 if (strcmp(oi.type, "btree") == 0) {
282 memset(&btreeinfo, 0, sizeof(btreeinfo)); 286 memset(&btreeinfo, 0, sizeof(btreeinfo));
283 if (flags & F_ENDIAN_BIG) 287 if (flags & F_ENDIAN_BIG)
284 btreeinfo.lorder = 4321; 288 btreeinfo.lorder = 4321;
285 else if (flags & F_ENDIAN_LITTLE) 289 else if (flags & F_ENDIAN_LITTLE)
286 btreeinfo.lorder = 1234; 290 btreeinfo.lorder = 1234;
287 if (flags & F_DUPLICATES) 291 if (flags & F_DUPLICATES)
288 btreeinfo.flags = R_DUP; 292 btreeinfo.flags = R_DUP;
289 btreeinfo.psize = oi.pagesize; 293 btreeinfo.psize = oi.pagesize;
290 btreeinfo.cachesize = 1024 * 1024; 294 btreeinfo.cachesize = 1024 * 1024;
291 oi.info = &btreeinfo; 295 oi.info = &btreeinfo;
292 oi.dbtype = DB_BTREE; 296 oi.dbtype = DB_BTREE;
293 } else if (strcmp(oi.type, "hash") == 0) { 297 } else if (strcmp(oi.type, "hash") == 0) {
294 memset(&hashinfo, 0, sizeof(hashinfo)); 298 memset(&hashinfo, 0, sizeof(hashinfo));
295 if (flags & F_ENDIAN_BIG) 299 if (flags & F_ENDIAN_BIG)
296 hashinfo.lorder = 4321; 300 hashinfo.lorder = 4321;
297 else if (flags & F_ENDIAN_LITTLE) 301 else if (flags & F_ENDIAN_LITTLE)
298 hashinfo.lorder = 1234; 302 hashinfo.lorder = 1234;
299 hashinfo.bsize = oi.pagesize; 303 hashinfo.bsize = oi.pagesize;
300 hashinfo.cachesize = 1024 * 1024; 304 hashinfo.cachesize = 1024 * 1024;
301 oi.info = &hashinfo; 305 oi.info = &hashinfo;
302 oi.dbtype = DB_HASH; 306 oi.dbtype = DB_HASH;
303 } else { 307 } else {
304 warnx("Unknown database type `%s'", oi.type); 308 warnx("Unknown database type `%s'", oi.type);
305 usage(); 309 usage();
306 } 310 }
307 311
308 if (infile) { 312 if (infile) {
309 if (strcmp(infile, "-") == 0) 313 if (strcmp(infile, "-") == 0)
310 infp = stdin; 314 infp = stdin;
311 else if ((infp = fopen(infile, "r")) == NULL) 315 else if ((infp = fopen(infile, "r")) == NULL)
312 err(1, "Opening input file `%s'", infile); 316 err(1, "Opening input file `%s'", infile);
313 } 317 }
314 318
315 /* open database */ 319 /* open database */
316 db = dbopen(oi.file, oi.flags, oi.mode, oi.dbtype, oi.info); 320 db = dbopen(oi.file, oi.flags, oi.mode, oi.dbtype, oi.info);
317 if (db == NULL) 321 if (db == NULL)
318 err(1, "Opening database `%s'", oi.file); 322 err(1, "Opening database `%s'", oi.file);
319 323
320 324
321 /* manipulate database */ 325 /* manipulate database */
322 rv = 0; 326 rv = 0;
323 if (flags & F_WRITE) { /* write entries */ 327 if (flags & F_WRITE) { /* write entries */
324 for (ch = 0; ch < argc; ch += 2) 328 for (ch = 0; ch < argc; ch += 2)
325 if ((rv = db_put(argv[ch], argv[ch+1]))) 329 if ((rv = db_put(argv[ch], argv[ch+1])))
326 goto cleanup; 330 goto cleanup;
327 if (infp) { 331 if (infp) {
328 while (parseline(infp, fieldsep, &key, &val)) { 332 while (parseline(infp, fieldsep, &key, &val)) {
329 if ((rv = db_put(key, val))) 333 if ((rv = db_put(key, val)))
330 goto cleanup; 334 goto cleanup;
331 } 335 }
332 if (ferror(infp)) { 336 if (ferror(infp)) {
333 warnx("Reading `%s'", infile); 337 warnx("Reading `%s'", infile);
334 goto cleanup; 338 goto cleanup;
335 } 339 }
336 } 340 }
337 } else if (!infp && argc == 0) { /* read all */ 341 } else if (!infp && argc == 0) { /* read all */
338 db_dump(); 342 db_dump();
339 } else { /* read/delete specific */ 343 } else { /* read/delete specific */
340 int (*dbop)(char *); 344 int (*dbop)(char *);
341 345
342 if (flags & F_DELETE) 346 if (flags & F_DELETE)
343 dbop = db_del; 347 dbop = db_del;
344 else 348 else
345 dbop = db_get; 349 dbop = db_get;
346 for (ch = 0; ch < argc; ch++) { 350 for (ch = 0; ch < argc; ch++) {
347 if ((rv = dbop(argv[ch]))) 351 if ((rv = dbop(argv[ch])))
348 goto cleanup; 352 goto cleanup;
349 } 353 }
350 if (infp) { 354 if (infp) {
351 while (parseline(infp, fieldsep, &key, NULL)) { 355 while (parseline(infp, fieldsep, &key, NULL)) {
352 if ((rv = dbop(key))) 356 if ((rv = dbop(key)))
353 goto cleanup; 357 goto cleanup;
354 } 358 }
355 if (ferror(infp)) { 359 if (ferror(infp)) {
356 warnx("Reading `%s'", infile); 360 warnx("Reading `%s'", infile);
357 goto cleanup; 361 goto cleanup;
358 } 362 }
359 } 363 }
360 } 364 }
361 365
362 /* close database */ 366 /* close database */
363 cleanup: 367 cleanup:
364 if (db->close(db) == -1) 368 if (db->close(db) == -1)
365 err(1, "Closing database `%s'", oi.file); 369 err(1, "Closing database `%s'", oi.file);
366 if (infp) 370 if (infp)
367 fclose(infp); 371 fclose(infp);
368 return (rv); 372 return (rv);
369} 373}
370 374
371void 375void
372db_print(DBT *key, DBT *val) 376db_print(DBT *key, DBT *val)
373{ 377{
374 int len; 378 int len;
375 char *data; 379 char *data;
376 380
377#define MINUSNUL(x) ((x) > 0 ? (x) - (flags & F_NO_NUL ? 0 : 1) : 0) 381#define MINUSNUL(x) ((x) > 0 ? (x) - (flags & F_NO_NUL ? 0 : 1) : 0)
378 382
379 if (flags & F_SHOW_KEY) { 383 if (flags & F_SHOW_KEY) {
380 if (flags & F_ENCODE_KEY) { 384 if (flags & F_ENCODE_KEY) {
381 len = encode_data(MINUSNUL(key->size), 385 len = encode_data(MINUSNUL(key->size),
382 (char *)key->data, &data); 386 (char *)key->data, &data);
383 } else { 387 } else {
384 len = (int)MINUSNUL(key->size); 388 len = (int)MINUSNUL(key->size);
385 data = (char *)key->data; 389 data = (char *)key->data;
386 } 390 }
387 printf("%.*s", len, data); 391 printf("%.*s", len, data);
388 } 392 }
389 if ((flags & F_SHOW_KEY) && (flags & F_SHOW_VALUE)) 393 if ((flags & F_SHOW_KEY) && (flags & F_SHOW_VALUE))
390 printf("%s", outputsep); 394 printf("%s", outputsep);
391 if (flags & F_SHOW_VALUE) { 395 if (flags & F_SHOW_VALUE) {
392 if (flags & F_ENCODE_VAL) { 396 if (flags & F_ENCODE_VAL) {
393 len = encode_data(MINUSNUL(val->size), 397 len = encode_data(MINUSNUL(val->size),
394 (char *)val->data, &data); 398 (char *)val->data, &data);
395 } else { 399 } else {
396 len = (int)MINUSNUL(val->size); 400 len = (int)MINUSNUL(val->size);
397 data = (char *)val->data; 401 data = (char *)val->data;
398 } 402 }
399 printf("%.*s", len, data); 403 printf("%.*s", len, data);
400 } 404 }
401 printf("\n"); 405 printf("\n");
402} 406}
403 407
404int 408int
405db_dump(void) 409db_dump(void)
406{ 410{
407 DBT key, val; 411 DBT key, val;
408 int rv; 412 int rv;
409 413
410 while ((rv = db->seq(db, &key, &val, R_NEXT)) == 0) 414 while ((rv = db->seq(db, &key, &val, R_NEXT)) == 0)
411 db_print(&key, &val); 415 db_print(&key, &val);
412 if (rv == -1) 416 if (rv == -1)
413 warn("Error dumping database"); 417 warn("Error dumping database");
414 return (rv == 1 ? 0 : 1); 418 return (rv == 1 ? 0 : 1);
415} 419}
416 420
417static void 421static void
418db_makekey(DBT *key, char *keystr, int downcase, int decode) 422db_makekey(DBT *key, char *keystr, int downcase, int decode)
419{ 423{
420 char *p, *ks; 424 char *p, *ks;
421 int klen; 425 int klen;
422 426
423 memset(key, 0, sizeof(*key)); 427 memset(key, 0, sizeof(*key));
424 if (decode) { 428 if (decode) {
425 if ((klen = decode_data(keystr, &ks)) == -1) 429 if ((klen = decode_data(keystr, &ks)) == -1)
426 errx(1, "Invalid escape sequence in `%s'", keystr); 430 errx(1, "Invalid escape sequence in `%s'", keystr);
427 } else { 431 } else {
428 klen = strlen(keystr); 432 klen = strlen(keystr);
429 ks = keystr; 433 ks = keystr;
430 } 434 }
431 key->data = ks; 435 key->data = ks;
432 key->size = klen + (flags & F_NO_NUL ? 0 : 1); 436 key->size = klen + (flags & F_NO_NUL ? 0 : 1);
433 if (downcase && (flags & F_IGNORECASE)) { 437 if (downcase && (flags & F_IGNORECASE)) {
434 for (p = ks; *p; p++) 438 for (p = ks; *p; p++)
435 if (isupper((int)*p)) 439 if (isupper((int)*p))
436 *p = tolower((int)*p); 440 *p = tolower((int)*p);
437 } 441 }
438} 442}
439 443
440int 444int
441db_del(char *keystr) 445db_del(char *keystr)
442{ 446{
443 DBT key; 447 DBT key;
444 int r; 448 int r;
445 449
446 db_makekey(&key, keystr, 1, (flags & F_DECODE_KEY ? 1 : 0)); 450 db_makekey(&key, keystr, 1, (flags & F_DECODE_KEY ? 1 : 0));
447 r = db->del(db, &key, 0); 451 r = db->del(db, &key, 0);
448 switch (r) { 452 switch (r) {
449 case -1: 453 case -1:
450 if (! (flags & F_QUIET)) 454 if (! (flags & F_QUIET))
451 warn("Error deleting key `%s'", keystr); 455 warn("Error deleting key `%s'", keystr);
452 r = 1; 456 r = 1;
453 break; 457 break;
454 case 0: 458 case 0:
455 if (! (flags & F_QUIET)) 459 if (! (flags & F_QUIET))
456 printf("Deleted key `%s'\n", keystr); 460 printf("Deleted key `%s'\n", keystr);
457 break; 461 break;
458 case 1: 462 case 1:
459 if (! (flags & F_QUIET)) 463 if (! (flags & F_QUIET))
460 warnx("Unknown key `%s'", keystr); 464 warnx("Unknown key `%s'", keystr);
461 break; 465 break;
462 default: 466 default:
463 abort(); 467 abort();
464 } 468 }
465 if (flags & F_DECODE_KEY) 469 if (flags & F_DECODE_KEY)
466 free(key.data); 470 free(key.data);
467 return (r); 471 return (r);
468} 472}
469 473
470int 474int
471db_get(char *keystr) 475db_get(char *keystr)
472{ 476{
473 DBT key, val; 477 DBT key, val;
474 char *wantkey; 478 char *wantkey;
475 int r, found; 479 int r, found;
476 u_int seqflags; 480 u_int seqflags;
477 481
478 db_makekey(&key, keystr, 1, (flags & F_DECODE_KEY ? 1 : 0)); 482 db_makekey(&key, keystr, 1, (flags & F_DECODE_KEY ? 1 : 0));
479 wantkey = strdup(key.data); 483 wantkey = strdup(key.data);
480 if (wantkey == NULL) 484 if (wantkey == NULL)
481 err(1, "Cannot allocate key buffer"); 485 err(1, "Cannot allocate key buffer");
482 486
483 found = 0; 487 found = 0;
484 seqflags = R_CURSOR; 488 seqflags = R_CURSOR;
485 while ((r = db->seq(db, &key, &val, seqflags)) == 0) { 489 while ((r = db->seq(db, &key, &val, seqflags)) == 0) {
486 if (strcmp((char *)key.data, wantkey) != 0) { 490 if (strcmp((char *)key.data, wantkey) != 0) {
487 r = 1; 491 r = 1;
488 break; 492 break;
489 } 493 }
490 seqflags = R_NEXT; 494 seqflags = R_NEXT;
491 found++; 495 found++;
492 db_print(&key, &val); 496 db_print(&key, &val);
493 if (! (flags & F_DUPLICATES)) 497 if (! (flags & F_DUPLICATES))
494 break; 498 break;
495 } 499 }
496 500
497 switch (r) { 501 switch (r) {
498 case -1: 502 case -1:
499 warn("Error reading key `%s'", keystr); 503 warn("Error reading key `%s'", keystr);
500 r = 1; 504 r = 1;
501 break; 505 break;
502 case 0: 506 case 0:
503 break; 507 break;
504 case 1: 508 case 1:
505 if (found) { 509 if (found) {
506 r = 0; 510 r = 0;
507 break; 511 break;
508 } 512 }
509 if (! (flags & F_QUIET)) { 513 if (! (flags & F_QUIET)) {
510 warnx("Unknown key `%s'", keystr); 514 warnx("Unknown key `%s'", keystr);
511 } 515 }
512 break; 516 break;
513 default: 517 default:
514 abort(); 518 abort();
515 } 519 }
516 if (flags & F_DECODE_KEY) 520 if (flags & F_DECODE_KEY)
517 free(key.data); 521 free(key.data);
518 free(wantkey); 522 free(wantkey);
519 return (r); 523 return (r);
520} 524}
521 525
522int 526int
523db_put(char *keystr, char *valstr) 527db_put(char *keystr, char *valstr)
524{ 528{
525 DBT key, val; 529 DBT key, val;
526 int r = 0; 530 int r = 0;
527 531
528 db_makekey(&key, keystr, 1, (flags & F_DECODE_KEY ? 1 : 0)); 532 db_makekey(&key, keystr, 1, (flags & F_DECODE_KEY ? 1 : 0));
529 db_makekey(&val, valstr, 0, (flags & F_DECODE_VAL ? 1 : 0)); 533 db_makekey(&val, valstr, 0, (flags & F_DECODE_VAL ? 1 : 0));
530 r = db->put(db, &key, &val, (flags & F_REPLACE) ? 0 : R_NOOVERWRITE); 534 r = db->put(db, &key, &val, (flags & F_REPLACE) ? 0 : R_NOOVERWRITE);
531 switch (r) { 535 switch (r) {
532 case -1: 536 case -1:
533 warn("Error writing key `%s'", keystr); 537 warn("Error writing key `%s'", keystr);
534 r = 1; 538 r = 1;
535 break; 539 break;
536 case 0: 540 case 0:
537 if (! (flags & F_QUIET)) 541 if (! (flags & F_QUIET))
538 printf("Added key `%s'\n", keystr); 542 printf("Added key `%s'\n", keystr);
539 break; 543 break;
540 case 1: 544 case 1:
541 if (! (flags & F_QUIET)) 545 if (! (flags & F_QUIET))
542 warnx("Key `%s' already exists", keystr); 546 warnx("Key `%s' already exists", keystr);
543 break; 547 break;
544 default: 548 default:
545 abort(); 549 abort();
546 } 550 }
547 if (flags & F_DECODE_KEY) 551 if (flags & F_DECODE_KEY)
548 free(key.data); 552 free(key.data);
549 if (flags & F_DECODE_VAL) 553 if (flags & F_DECODE_VAL)
550 free(val.data); 554 free(val.data);
551 return (r); 555 return (r);
552} 556}
553 557
554int 558int
555parseline(FILE *fp, const char *sep, char **kp, char **vp) 559parseline(FILE *fp, const char *sep, char **kp, char **vp)
556{ 560{
557 size_t len; 561 size_t len;
558 char *key, *val; 562 char *key, *val;
559 563
560 key = fgetln(fp, &len); 564 key = fgetln(fp, &len);
561 if (key == NULL) /* end of file, or error */ 565 if (key == NULL) /* end of file, or error */
562 return (0); 566 return (0);
563 567
564 if (key[len-1] == '\n') /* check for \n at EOL */ 568 if (key[len-1] == '\n') /* check for \n at EOL */
565 key[--len] = '\0'; 569 key[--len] = '\0';
566 else 570 else
567 return (0); 571 return (0);
568 572
569 *kp = key; 573 *kp = key;
570 if (vp == NULL) /* don't split if don't want value */ 574 if (vp == NULL) /* don't split if don't want value */
571 return (1); 575 return (1);
572 if ((val = strstr(key, sep)) == NULL) 576 if ((val = strstr(key, sep)) == NULL)
573 val = key + len; 577 val = key + len;
574 else { 578 else {
575 *val = '\0'; 579 *val = '\0';
576 val += strlen(sep); 580 val += strlen(sep);
577 } 581 }
578 *vp = val; 582 *vp = val;
579 return (1); 583 return (1);
580} 584}
581 585
582int 586int
583encode_data(size_t len, char *data, char **edata) 587encode_data(size_t len, char *data, char **edata)
584{ 588{
585 static char *buf = NULL; 589 static char *buf = NULL;
586 char *nbuf; 590 char *nbuf;
587 static size_t buflen = 0; 591 static size_t buflen = 0;
588 size_t elen; 592 size_t elen;
589 593
590 elen = 1 + (len * 4); 594 elen = 1 + (len * 4);
591 if (elen > buflen) { 595 if (elen > buflen) {
592 if ((nbuf = realloc(buf, elen)) == NULL) 596 if ((nbuf = realloc(buf, elen)) == NULL)
593 err(1, "Cannot allocate encoding buffer"); 597 err(1, "Cannot allocate encoding buffer");
594 buf = nbuf; 598 buf = nbuf;
595 buflen = elen; 599 buflen = elen;
596 } 600 }
597 *edata = buf; 601 *edata = buf;
598 if (extra_echars) { 602 if (extra_echars) {
599 return (strsvisx(buf, data, len, visflags, extra_echars)); 603 return (strsvisx(buf, data, len, visflags, extra_echars));
600 } else { 604 } else {
601 return (strvisx(buf, data, len, visflags)); 605 return (strvisx(buf, data, len, visflags));
602 } 606 }
603} 607}
604 608
605int 609int
606decode_data(char *data, char **ddata) 610decode_data(char *data, char **ddata)
607{ 611{
608 char *buf; 612 char *buf;
609 613
610 if ((buf = malloc(strlen(data) + 1)) == NULL) 614 if ((buf = malloc(strlen(data) + 1)) == NULL)
611 err(1, "Cannot allocate decoding buffer"); 615 err(1, "Cannot allocate decoding buffer");
612 *ddata = buf; 616 *ddata = buf;
613 return (strunvisx(buf, data, (visflags & VIS_HTTPSTYLE))); 617 return (strunvisx(buf, data, (visflags & VIS_HTTPSTYLE)));
614} 618}
615 619
616void 620void
617parse_encode_decode_arg(const char *arg, int encode) 621parse_encode_decode_arg(const char *arg, int encode)
618{ 622{
619 if (! arg[0] || arg[1]) 623 if (! arg[0] || arg[1])
620 return; 624 return;
621 if (arg[0] == 'k' || arg[0] == 'b') { 625 if (arg[0] == 'k' || arg[0] == 'b') {
622 if (encode) 626 if (encode)
623 flags |= F_ENCODE_KEY; 627 flags |= F_ENCODE_KEY;
624 else 628 else
625 flags |= F_DECODE_KEY; 629 flags |= F_DECODE_KEY;
626 } 630 }
627 if (arg[0] == 'v' || arg[0] == 'b') { 631 if (arg[0] == 'v' || arg[0] == 'b') {
628 if (encode) 632 if (encode)
629 flags |= F_ENCODE_VAL; 633 flags |= F_ENCODE_VAL;
630 else 634 else
631 flags |= F_DECODE_VAL; 635 flags |= F_DECODE_VAL;
632 } 636 }
633 return; 637 return;
634} 638}
635 639
636int 640int
637parse_encode_option(char **arg) 641parse_encode_option(char **arg)
638{ 642{
639 int r = 0; 643 int r = 0;
640 int encmask = ~(VIS_CSTYLE | VIS_HTTPSTYLE | VIS_OCTAL); 644 int encmask = ~(VIS_CSTYLE | VIS_HTTPSTYLE | VIS_OCTAL);
641 645
642 for(; **arg; (*arg)++) { 646 for(; **arg; (*arg)++) {
643 switch (**arg) { 647 switch (**arg) {
644 case 'b': 648 case 'b':
645 r |= VIS_NOSLASH; 649 r |= VIS_NOSLASH;
646 break; 650 break;
647 case 'c': 651 case 'c':
648 r &= encmask; 652 r &= encmask;
649 r |= VIS_CSTYLE; 653 r |= VIS_CSTYLE;
650 break; 654 break;
651 case 'h': 655 case 'h':
652 r &= encmask; 656 r &= encmask;
653 r |= VIS_HTTPSTYLE; 657 r |= VIS_HTTPSTYLE;
654 break; 658 break;
655 case 'o': 659 case 'o':
656 r &= encmask; 660 r &= encmask;
657 r |= VIS_OCTAL; 661 r |= VIS_OCTAL;
658 break; 662 break;
659 case 's': 663 case 's':
660 r |= VIS_SAFE; 664 r |= VIS_SAFE;
661 break; 665 break;
662 case 't': 666 case 't':
663 r |= VIS_TAB; 667 r |= VIS_TAB;
664 break; 668 break;
665 case 'w': 669 case 'w':
666 r |= VIS_WHITE; 670 r |= VIS_WHITE;
667 break; 671 break;
668 default: 672 default:
669 return (0); 673 return (0);
670 break; 674 break;
671 } 675 }
672 } 676 }
673 return (r); 677 return (r);
674} 678}
675 679
676void 680void
677usage(void) 681usage(void)
678{ 682{
679 const char *p = getprogname(); 683 const char *p = getprogname();
680 684
681 fprintf(stderr, 685 fprintf(stderr,
682"usage: %s [-KiNqV] [-E endian] [-f infile] [-O outsep] [-S visitem]\n" 686"usage: %s [-KiNqV] [-E endian] [-f infile] [-O outsep] [-S visitem]\n"
683" [-T visspec] [-X extravis] type dbfile [key [...]]\n" 687" [-T visspec] [-X extravis] type dbfile [key [...]]\n"
684" %s -d [-iNq] [-E endian] [-f infile] [-T visspec] [-U unvisitem]\n" 688" %s -d [-iNq] [-E endian] [-f infile] [-T visspec] [-U unvisitem]\n"
685" type dbfile [key [...]]\n" 689" type dbfile [key [...]]\n"
686" %s -w [-CDiNqR] [-E endian] [-F isep] [-f infile] [-m mode]\n" 690" %s -w [-CDiNqR] [-E endian] [-F isep] [-f infile] [-m mode]\n"
687" [-P pagesize] [-T visspec] [-U unvisitem]\n" 691" [-P pagesize] [-T visspec] [-U unvisitem]\n"
688" type dbfile [key value [...]]\n" 692" type dbfile [key value [...]]\n"
689 ,p ,p ,p ); 693 ,p ,p ,p );
690 fprintf(stderr, 694 fprintf(stderr,
691"Supported modes:\n" 695"Supported modes:\n"
692" read keys [default]\n" 696" read keys [default]\n"
693" -d delete keys\n" 697" -d delete keys\n"
694" -w write (add) keys/values\n" 698" -w write (add) keys/values\n"
695"Supported options:\n" 699"Supported options:\n"
696" -C create empty (truncated) database\n" 700" -C create empty (truncated) database\n"
697" -D allow duplicates\n" 701" -D allow duplicates\n"
698" -E endian database endian: `B'ig, `L'ittle, `H'ost [default: H]\n" 702" -E endian database endian: `B'ig, `L'ittle, `H'ost [default: H]\n"
699" -F isep input field separator string [default: a space]\n" 703" -F isep input field separator string [default: a space]\n"
700" -f infile file of keys (read|delete) or keys/vals (write)\n" 704" -f infile file of keys (read|delete) or keys/vals (write)\n"
701" -i ignore case of key by converting to lower case\n" 705" -i ignore case of key by converting to lower case\n"
702" -K print key\n" 706" -K print key\n"
703" -m mode mode of created database [default: 0644]\n" 707" -m mode mode of created database [default: 0644]\n"
704" -N don't NUL terminate key\n" 708" -N don't NUL terminate key\n"
705" -O outsep output field separator string [default: a tab]\n" 709" -O outsep output field separator string [default: a tab]\n"
706" -P pagesize database page size [default: 4096]\n" 710" -P pagesize database page size [default: 4096]\n"
707" -q quiet operation (missing keys aren't errors)\n" 711" -q quiet operation (missing keys aren't errors)\n"
708" -R replace existing keys\n" 712" -R replace existing keys\n"
709" -S visitem items to strvis(3) encode: 'k'ey, 'v'alue, 'b'oth\n" 713" -S visitem items to strvis(3) encode: 'k'ey, 'v'alue, 'b'oth\n"
710" -T visspec options to control -S and -U; like vis(1) options\n" 714" -T visspec options to control -S and -U; like vis(1) options\n"
711" -U unvisitem items to strunvis(3) decode: 'k'ey, 'v'alue, 'b'oth\n" 715" -U unvisitem items to strunvis(3) decode: 'k'ey, 'v'alue, 'b'oth\n"
712" -V print value\n" 716" -V print value\n"
713" -X extravis extra characters to encode with -S\n" 717" -X extravis extra characters to encode with -S\n"
714 ); 718 );
715 exit(1); 719 exit(1);
716} 720}