1 | /*
|
---|
2 | Unix SMB/CIFS implementation.
|
---|
3 |
|
---|
4 | trivial database library
|
---|
5 |
|
---|
6 | Copyright (C) Andrew Tridgell 1999-2005
|
---|
7 | Copyright (C) Paul `Rusty' Russell 2000
|
---|
8 | Copyright (C) Jeremy Allison 2000-2003
|
---|
9 |
|
---|
10 | ** NOTE! The following LGPL license applies to the tdb
|
---|
11 | ** library. This does NOT imply that all of Samba is released
|
---|
12 | ** under the LGPL
|
---|
13 |
|
---|
14 | This library is free software; you can redistribute it and/or
|
---|
15 | modify it under the terms of the GNU Lesser General Public
|
---|
16 | License as published by the Free Software Foundation; either
|
---|
17 | version 3 of the License, or (at your option) any later version.
|
---|
18 |
|
---|
19 | This library is distributed in the hope that it will be useful,
|
---|
20 | but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
21 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
---|
22 | Lesser General Public License for more details.
|
---|
23 |
|
---|
24 | You should have received a copy of the GNU Lesser General Public
|
---|
25 | License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
---|
26 | */
|
---|
27 |
|
---|
28 | #include "tdb_private.h"
|
---|
29 |
|
---|
30 | static tdb_off_t tdb_dump_record(struct tdb_context *tdb, int hash,
|
---|
31 | tdb_off_t offset)
|
---|
32 | {
|
---|
33 | struct tdb_record rec;
|
---|
34 | tdb_off_t tailer_ofs, tailer;
|
---|
35 |
|
---|
36 | if (tdb->methods->tdb_read(tdb, offset, (char *)&rec,
|
---|
37 | sizeof(rec), DOCONV()) == -1) {
|
---|
38 | printf("ERROR: failed to read record at %u\n", offset);
|
---|
39 | return 0;
|
---|
40 | }
|
---|
41 |
|
---|
42 | printf(" rec: hash=%d offset=0x%08x next=0x%08x rec_len=%u "
|
---|
43 | "key_len=%u data_len=%u full_hash=0x%08x magic=0x%08x\n",
|
---|
44 | hash, offset, rec.next, rec.rec_len, rec.key_len, rec.data_len,
|
---|
45 | rec.full_hash, rec.magic);
|
---|
46 |
|
---|
47 | tailer_ofs = offset + sizeof(rec) + rec.rec_len - sizeof(tdb_off_t);
|
---|
48 |
|
---|
49 | if (tdb_ofs_read(tdb, tailer_ofs, &tailer) == -1) {
|
---|
50 | printf("ERROR: failed to read tailer at %u\n", tailer_ofs);
|
---|
51 | return rec.next;
|
---|
52 | }
|
---|
53 |
|
---|
54 | if (tailer != rec.rec_len + sizeof(rec)) {
|
---|
55 | printf("ERROR: tailer does not match record! tailer=%u totalsize=%u\n",
|
---|
56 | (unsigned int)tailer, (unsigned int)(rec.rec_len + sizeof(rec)));
|
---|
57 | }
|
---|
58 | return rec.next;
|
---|
59 | }
|
---|
60 |
|
---|
61 | static int tdb_dump_chain(struct tdb_context *tdb, int i)
|
---|
62 | {
|
---|
63 | tdb_off_t rec_ptr, top;
|
---|
64 |
|
---|
65 | top = TDB_HASH_TOP(i);
|
---|
66 |
|
---|
67 | if (tdb_lock(tdb, i, F_WRLCK) != 0)
|
---|
68 | return -1;
|
---|
69 |
|
---|
70 | if (tdb_ofs_read(tdb, top, &rec_ptr) == -1)
|
---|
71 | return tdb_unlock(tdb, i, F_WRLCK);
|
---|
72 |
|
---|
73 | if (rec_ptr)
|
---|
74 | printf("hash=%d\n", i);
|
---|
75 |
|
---|
76 | while (rec_ptr) {
|
---|
77 | rec_ptr = tdb_dump_record(tdb, i, rec_ptr);
|
---|
78 | }
|
---|
79 |
|
---|
80 | return tdb_unlock(tdb, i, F_WRLCK);
|
---|
81 | }
|
---|
82 |
|
---|
83 | _PUBLIC_ void tdb_dump_all(struct tdb_context *tdb)
|
---|
84 | {
|
---|
85 | int i;
|
---|
86 | for (i=0;i<tdb->hash_size;i++) {
|
---|
87 | tdb_dump_chain(tdb, i);
|
---|
88 | }
|
---|
89 | printf("freelist:\n");
|
---|
90 | tdb_dump_chain(tdb, -1);
|
---|
91 | }
|
---|
92 |
|
---|
93 | _PUBLIC_ int tdb_printfreelist(struct tdb_context *tdb)
|
---|
94 | {
|
---|
95 | int ret;
|
---|
96 | long total_free = 0;
|
---|
97 | tdb_off_t offset, rec_ptr;
|
---|
98 | struct tdb_record rec;
|
---|
99 |
|
---|
100 | if ((ret = tdb_lock(tdb, -1, F_WRLCK)) != 0)
|
---|
101 | return ret;
|
---|
102 |
|
---|
103 | offset = FREELIST_TOP;
|
---|
104 |
|
---|
105 | /* read in the freelist top */
|
---|
106 | if (tdb_ofs_read(tdb, offset, &rec_ptr) == -1) {
|
---|
107 | tdb_unlock(tdb, -1, F_WRLCK);
|
---|
108 | return 0;
|
---|
109 | }
|
---|
110 |
|
---|
111 | printf("freelist top=[0x%08x]\n", rec_ptr );
|
---|
112 | while (rec_ptr) {
|
---|
113 | if (tdb->methods->tdb_read(tdb, rec_ptr, (char *)&rec,
|
---|
114 | sizeof(rec), DOCONV()) == -1) {
|
---|
115 | tdb_unlock(tdb, -1, F_WRLCK);
|
---|
116 | return -1;
|
---|
117 | }
|
---|
118 |
|
---|
119 | if (rec.magic != TDB_FREE_MAGIC) {
|
---|
120 | printf("bad magic 0x%08x in free list\n", rec.magic);
|
---|
121 | tdb_unlock(tdb, -1, F_WRLCK);
|
---|
122 | return -1;
|
---|
123 | }
|
---|
124 |
|
---|
125 | printf("entry offset=[0x%08x], rec.rec_len = [0x%08x (%u)] (end = 0x%08x)\n",
|
---|
126 | rec_ptr, rec.rec_len, rec.rec_len, rec_ptr + rec.rec_len);
|
---|
127 | total_free += rec.rec_len;
|
---|
128 |
|
---|
129 | /* move to the next record */
|
---|
130 | rec_ptr = rec.next;
|
---|
131 | }
|
---|
132 | printf("total rec_len = [0x%08lx (%lu)]\n", total_free, total_free);
|
---|
133 |
|
---|
134 | return tdb_unlock(tdb, -1, F_WRLCK);
|
---|
135 | }
|
---|
136 |
|
---|