Imported Upstream version 5.3.21
[platform/upstream/libdb.git] / util / db_dump185.c
1 /*-
2  * See the file LICENSE for redistribution information.
3  *
4  * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
5  *
6  * $Id$
7  */
8
9 #ifndef lint
10 static const char copyright[] =
11     "Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.\n";
12 #endif
13
14 #include <sys/types.h>
15
16 #include <ctype.h>
17 #include <errno.h>
18 #include <fcntl.h>
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22
23 #ifdef HAVE_DB_185_H
24 #include <db_185.h>
25 #else
26 #include <db.h>
27 #endif
28
29 /* Hash Table Information */
30 typedef struct hashhdr185 {             /* Disk resident portion */
31         int             magic;          /* Magic NO for hash tables */
32         int             version;        /* Version ID */
33         u_int32_t       lorder;         /* Byte Order */
34         int             bsize;          /* Bucket/Page Size */
35         int             bshift;         /* Bucket shift */
36         int             dsize;          /* Directory Size */
37         int             ssize;          /* Segment Size */
38         int             sshift;         /* Segment shift */
39         int             ovfl_point;     /* Where overflow pages are being
40                                          * allocated */
41         int             last_freed;     /* Last overflow page freed */
42         int             max_bucket;     /* ID of Maximum bucket in use */
43         int             high_mask;      /* Mask to modulo into entire table */
44         int             low_mask;       /* Mask to modulo into lower half of
45                                          * table */
46         int             ffactor;        /* Fill factor */
47         int             nkeys;          /* Number of keys in hash table */
48 } HASHHDR185;
49 typedef struct htab185   {              /* Memory resident data structure */
50         HASHHDR185      hdr;            /* Header */
51 } HTAB185;
52
53 /* Hash Table Information */
54 typedef struct hashhdr186 {     /* Disk resident portion */
55         int32_t magic;          /* Magic NO for hash tables */
56         int32_t version;        /* Version ID */
57         int32_t lorder;         /* Byte Order */
58         int32_t bsize;          /* Bucket/Page Size */
59         int32_t bshift;         /* Bucket shift */
60         int32_t ovfl_point;     /* Where overflow pages are being allocated */
61         int32_t last_freed;     /* Last overflow page freed */
62         int32_t max_bucket;     /* ID of Maximum bucket in use */
63         int32_t high_mask;      /* Mask to modulo into entire table */
64         int32_t low_mask;       /* Mask to modulo into lower half of table */
65         int32_t ffactor;        /* Fill factor */
66         int32_t nkeys;          /* Number of keys in hash table */
67         int32_t hdrpages;       /* Size of table header */
68         int32_t h_charkey;      /* value of hash(CHARKEY) */
69 #define NCACHED 32              /* number of bit maps and spare points */
70         int32_t spares[NCACHED];/* spare pages for overflow */
71                                 /* address of overflow page bitmaps */
72         u_int16_t bitmaps[NCACHED];
73 } HASHHDR186;
74 typedef struct htab186   {              /* Memory resident data structure */
75         void *unused[2];
76         HASHHDR186      hdr;            /* Header */
77 } HTAB186;
78
79 typedef struct _epgno {
80         u_int32_t pgno;                 /* the page number */
81         u_int16_t index;                /* the index on the page */
82 } EPGNO;
83
84 typedef struct _epg {
85         void    *page;                  /* the (pinned) page */
86         u_int16_t index;                /* the index on the page */
87 } EPG;
88
89 typedef struct _cursor {
90         EPGNO    pg;                    /* B: Saved tree reference. */
91         DBT      key;                   /* B: Saved key, or key.data == NULL. */
92         u_int32_t rcursor;              /* R: recno cursor (1-based) */
93
94 #define CURS_ACQUIRE    0x01            /*  B: Cursor needs to be reacquired. */
95 #define CURS_AFTER      0x02            /*  B: Unreturned cursor after key. */
96 #define CURS_BEFORE     0x04            /*  B: Unreturned cursor before key. */
97 #define CURS_INIT       0x08            /* RB: Cursor initialized. */
98         u_int8_t flags;
99 } CURSOR;
100
101 /* The in-memory btree/recno data structure. */
102 typedef struct _btree {
103         void     *bt_mp;                /* memory pool cookie */
104
105         void     *bt_dbp;               /* pointer to enclosing DB */
106
107         EPG       bt_cur;               /* current (pinned) page */
108         void     *bt_pinned;            /* page pinned across calls */
109
110         CURSOR    bt_cursor;            /* cursor */
111
112         EPGNO     bt_stack[50];         /* stack of parent pages */
113         EPGNO    *bt_sp;                /* current stack pointer */
114
115         DBT       bt_rkey;              /* returned key */
116         DBT       bt_rdata;             /* returned data */
117
118         int       bt_fd;                /* tree file descriptor */
119
120         u_int32_t bt_free;              /* next free page */
121         u_int32_t bt_psize;             /* page size */
122         u_int16_t bt_ovflsize;          /* cut-off for key/data overflow */
123         int       bt_lorder;            /* byte order */
124                                         /* sorted order */
125         enum { NOT, BACK, FORWARD } bt_order;
126         EPGNO     bt_last;              /* last insert */
127
128                                         /* B: key comparison function */
129         int     (*bt_cmp) __P((DBT *, DBT *));
130                                         /* B: prefix comparison function */
131         size_t  (*bt_pfx) __P((DBT *, DBT *));
132                                         /* R: recno input function */
133         int     (*bt_irec) __P((struct _btree *, u_int32_t));
134
135         FILE     *bt_rfp;               /* R: record FILE pointer */
136         int       bt_rfd;               /* R: record file descriptor */
137
138         void     *bt_cmap;              /* R: current point in mapped space */
139         void     *bt_smap;              /* R: start of mapped space */
140         void     *bt_emap;              /* R: end of mapped space */
141         size_t    bt_msize;             /* R: size of mapped region. */
142
143         u_int32_t bt_nrecs;             /* R: number of records */
144         size_t    bt_reclen;            /* R: fixed record length */
145         u_char    bt_bval;              /* R: delimiting byte/pad character */
146
147 /*
148  * NB:
149  * B_NODUPS and R_RECNO are stored on disk, and may not be changed.
150  */
151 #define B_INMEM         0x00001         /* in-memory tree */
152 #define B_METADIRTY     0x00002         /* need to write metadata */
153 #define B_MODIFIED      0x00004         /* tree modified */
154 #define B_NEEDSWAP      0x00008         /* if byte order requires swapping */
155 #define B_RDONLY        0x00010         /* read-only tree */
156
157 #define B_NODUPS        0x00020         /* no duplicate keys permitted */
158 #define R_RECNO         0x00080         /* record oriented tree */
159
160 #define R_CLOSEFP       0x00040         /* opened a file pointer */
161 #define R_EOF           0x00100         /* end of input file reached. */
162 #define R_FIXLEN        0x00200         /* fixed length records */
163 #define R_MEMMAPPED     0x00400         /* memory mapped file. */
164 #define R_INMEM         0x00800         /* in-memory file */
165 #define R_MODIFIED      0x01000         /* modified file */
166 #define R_RDONLY        0x02000         /* read-only file */
167
168 #define B_DB_LOCK       0x04000         /* DB_LOCK specified. */
169 #define B_DB_SHMEM      0x08000         /* DB_SHMEM specified. */
170 #define B_DB_TXN        0x10000         /* DB_TXN specified. */
171         u_int32_t flags;
172 } BTREE;
173
174 void    db_btree __P((DB *, int));
175 void    db_hash __P((DB *, int));
176 void    dbt_dump __P((DBT *));
177 void    dbt_print __P((DBT *));
178 int     main __P((int, char *[]));
179 int     usage __P((void));
180
181 int
182 main(argc, argv)
183         int argc;
184         char *argv[];
185 {
186         extern char *optarg;
187         extern int optind;
188         DB *dbp;
189         DBT key, data;
190         int ch, pflag, rval;
191
192         pflag = 0;
193         while ((ch = getopt(argc, argv, "f:p")) != EOF)
194                 switch (ch) {
195                 case 'f':
196                         if (freopen(optarg, "w", stdout) == NULL) {
197                                 fprintf(stderr, "db_dump185: %s: %s\n",
198                                     optarg, strerror(errno));
199                                 return (EXIT_FAILURE);
200                         }
201                         break;
202                 case 'p':
203                         pflag = 1;
204                         break;
205                 case '?':
206                 default:
207                         return (usage());
208                 }
209         argc -= optind;
210         argv += optind;
211
212         if (argc != 1)
213                 return (usage());
214
215         if ((dbp = dbopen(argv[0], O_RDONLY, 0, DB_BTREE, NULL)) == NULL) {
216                 if ((dbp =
217                     dbopen(argv[0], O_RDONLY, 0, DB_HASH, NULL)) == NULL) {
218                         fprintf(stderr,
219                             "db_dump185: %s: %s\n", argv[0], strerror(errno));
220                         return (EXIT_FAILURE);
221                 }
222                 db_hash(dbp, pflag);
223         } else
224                 db_btree(dbp, pflag);
225
226         /*
227          * !!!
228          * DB 1.85 DBTs are a subset of DB 2.0 DBTs, so we just use the
229          * new dump/print routines.
230          */
231         if (pflag)
232                 while (!(rval = dbp->seq(dbp, &key, &data, R_NEXT))) {
233                         dbt_print(&key);
234                         dbt_print(&data);
235                 }
236         else
237                 while (!(rval = dbp->seq(dbp, &key, &data, R_NEXT))) {
238                         dbt_dump(&key);
239                         dbt_dump(&data);
240                 }
241
242         if (rval == -1) {
243                 fprintf(stderr, "db_dump185: seq: %s\n", strerror(errno));
244                 return (EXIT_FAILURE);
245         }
246         return (EXIT_SUCCESS);
247 }
248
249 /*
250  * db_hash --
251  *      Dump out hash header information.
252  */
253 void
254 db_hash(dbp, pflag)
255         DB *dbp;
256         int pflag;
257 {
258         HTAB185 *hash185p;
259         HTAB186 *hash186p;
260
261         printf("format=%s\n", pflag ? "print" : "bytevalue");
262         printf("type=hash\n");
263
264         /* DB 1.85 was version 2, DB 1.86 was version 3. */
265         hash185p = dbp->internal;
266         if (hash185p->hdr.version > 2) {
267                 hash186p = dbp->internal;
268                 printf("h_ffactor=%lu\n", (u_long)hash186p->hdr.ffactor);
269                 if (hash186p->hdr.lorder != 0)
270                         printf("db_lorder=%lu\n", (u_long)hash186p->hdr.lorder);
271                 printf("db_pagesize=%lu\n", (u_long)hash186p->hdr.bsize);
272         } else {
273                 printf("h_ffactor=%lu\n", (u_long)hash185p->hdr.ffactor);
274                 if (hash185p->hdr.lorder != 0)
275                         printf("db_lorder=%lu\n", (u_long)hash185p->hdr.lorder);
276                 printf("db_pagesize=%lu\n", (u_long)hash185p->hdr.bsize);
277         }
278         printf("HEADER=END\n");
279 }
280
281 /*
282  * db_btree --
283  *      Dump out btree header information.
284  */
285 void
286 db_btree(dbp, pflag)
287         DB *dbp;
288         int pflag;
289 {
290         BTREE *btp;
291
292         btp = dbp->internal;
293
294         printf("format=%s\n", pflag ? "print" : "bytevalue");
295         printf("type=btree\n");
296 #ifdef NOT_AVAILABLE_IN_185
297         printf("bt_minkey=%lu\n", (u_long)XXX);
298         printf("bt_maxkey=%lu\n", (u_long)XXX);
299 #endif
300         if (btp->bt_lorder != 0)
301                 printf("db_lorder=%lu\n", (u_long)btp->bt_lorder);
302         printf("db_pagesize=%lu\n", (u_long)btp->bt_psize);
303         if (!(btp->flags & B_NODUPS))
304                 printf("duplicates=1\n");
305         printf("HEADER=END\n");
306 }
307
308 static char hex[] = "0123456789abcdef";
309
310 /*
311  * dbt_dump --
312  *      Write out a key or data item using byte values.
313  */
314 void
315 dbt_dump(dbtp)
316         DBT *dbtp;
317 {
318         size_t len;
319         u_int8_t *p;
320
321         for (len = dbtp->size, p = dbtp->data; len--; ++p)
322                 (void)printf("%c%c",
323                     hex[(*p & 0xf0) >> 4], hex[*p & 0x0f]);
324         printf("\n");
325 }
326
327 /*
328  * dbt_print --
329  *      Write out a key or data item using printable characters.
330  */
331 void
332 dbt_print(dbtp)
333         DBT *dbtp;
334 {
335         size_t len;
336         u_int8_t *p;
337
338         for (len = dbtp->size, p = dbtp->data; len--; ++p)
339                 if (isprint((int)*p)) {
340                         if (*p == '\\')
341                                 (void)printf("\\");
342                         (void)printf("%c", *p);
343                 } else
344                         (void)printf("\\%c%c",
345                             hex[(*p & 0xf0) >> 4], hex[*p & 0x0f]);
346         printf("\n");
347 }
348
349 /*
350  * usage --
351  *      Display the usage message.
352  */
353 int
354 usage()
355 {
356         (void)fprintf(stderr, "usage: db_dump185 [-p] [-f file] db_file\n");
357         return (EXIT_FAILURE);
358 }