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