Line data Source code
1 : /*
2 : tdbrestore -- construct a tdb from tdbdump output.
3 : Copyright (C) Volker Lendecke 2010
4 : Copyright (C) Simon McVittie 2005
5 :
6 : This program is free software; you can redistribute it and/or modify
7 : it under the terms of the GNU General Public License as published by
8 : the Free Software Foundation; either version 3 of the License, or
9 : (at your option) any later version.
10 :
11 : This program is distributed in the hope that it will be useful,
12 : but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : GNU General Public License for more details.
15 :
16 : You should have received a copy of the GNU General Public License
17 : along with this program. If not, see <http://www.gnu.org/licenses/>.
18 : */
19 :
20 : #include "replace.h"
21 : #include <assert.h>
22 : #include "system/locale.h"
23 : #include "system/time.h"
24 : #include "system/filesys.h"
25 : #include "system/wait.h"
26 : #include "tdb.h"
27 :
28 2857788 : static int read_linehead(FILE *f)
29 : {
30 : size_t i;
31 : int c;
32 : int num_bytes;
33 : char prefix[128];
34 :
35 : while (1) {
36 5080512 : c = getc(f);
37 2857788 : if (c == EOF) {
38 0 : return -1;
39 : }
40 2857788 : if (c == '(') {
41 635064 : break;
42 : }
43 : }
44 4833658 : for (i=0; i<sizeof(prefix); i++) {
45 4833658 : c = getc(f);
46 4833658 : if (c == EOF) {
47 0 : return -1;
48 : }
49 4833658 : prefix[i] = c;
50 4833658 : if (c == '"') {
51 635064 : break;
52 : }
53 : }
54 635064 : if (i == sizeof(prefix)) {
55 0 : return -1;
56 : }
57 635064 : prefix[i] = '\0';
58 :
59 635064 : if (sscanf(prefix, "%d) = ", &num_bytes) != 1) {
60 0 : return -1;
61 : }
62 635064 : return num_bytes;
63 : }
64 :
65 635064 : static int read_data(FILE *f, TDB_DATA *d, size_t size) {
66 : size_t i;
67 :
68 635064 : d->dptr = (unsigned char *)malloc(size);
69 635064 : if (d->dptr == NULL) {
70 0 : return -1;
71 : }
72 635064 : d->dsize = size;
73 :
74 207414489 : for (i=0; i<size; i++) {
75 206779425 : int c = getc(f);
76 206779425 : if (c == EOF) {
77 0 : fprintf(stderr, "Unexpected EOF in data\n");
78 0 : return 1;
79 206779425 : } else if (c == '"') {
80 0 : return 0;
81 206779425 : } else if (c == '\\') {
82 72782684 : char in[3] = {0};
83 : size_t n;
84 : bool ok;
85 :
86 72782684 : n = fread(in, 1, 2, stdin);
87 72782684 : if (n != 2) {
88 0 : return -1;
89 : }
90 72782684 : ok = hex_byte(in, &d->dptr[i]);
91 72782684 : if (!ok) {
92 0 : fprintf(stderr, "Invalid hex: .2%s\n", in);
93 0 : return -1;
94 : }
95 : } else {
96 133996741 : d->dptr[i] = c;
97 : }
98 : }
99 635064 : return 0;
100 : }
101 :
102 1270321 : static int swallow(FILE *f, const char *s, int *eof)
103 : {
104 : char line[128];
105 :
106 1270321 : if (fgets(line, sizeof(line), f) == NULL) {
107 193 : if (eof != NULL) {
108 193 : *eof = 1;
109 : }
110 193 : return -1;
111 : }
112 1270128 : if (strcmp(line, s) != 0) {
113 0 : return -1;
114 : }
115 1270128 : return 0;
116 : }
117 :
118 317725 : static int read_rec(FILE *f, TDB_CONTEXT *tdb, int *eof)
119 : {
120 : int length;
121 : TDB_DATA key, data;
122 317725 : int ret = -1;
123 :
124 317725 : key.dptr = NULL;
125 317725 : data.dptr = NULL;
126 :
127 317725 : if (swallow(f, "{\n", eof) == -1) {
128 193 : goto fail;
129 : }
130 317532 : length = read_linehead(f);
131 317532 : if (length == -1) {
132 0 : goto fail;
133 : }
134 317532 : if (read_data(f, &key, length) == -1) {
135 0 : goto fail;
136 : }
137 317532 : if (swallow(f, "\"\n", NULL) == -1) {
138 0 : goto fail;
139 : }
140 317532 : length = read_linehead(f);
141 317532 : if (length == -1) {
142 0 : goto fail;
143 : }
144 317532 : if (read_data(f, &data, length) == -1) {
145 0 : goto fail;
146 : }
147 317532 : if ((swallow(f, "\"\n", NULL) == -1)
148 317532 : || (swallow(f, "}\n", NULL) == -1)) {
149 : goto fail;
150 : }
151 317532 : if (tdb_store(tdb, key, data, TDB_INSERT) != 0) {
152 0 : fprintf(stderr, "TDB error: %s\n", tdb_errorstr(tdb));
153 0 : goto fail;
154 : }
155 :
156 317532 : ret = 0;
157 317725 : fail:
158 317725 : free(key.dptr);
159 317725 : free(data.dptr);
160 317725 : return ret;
161 : }
162 :
163 193 : static int restore_tdb(const char *fname)
164 : {
165 : TDB_CONTEXT *tdb;
166 :
167 193 : tdb = tdb_open(fname, 0, 0, O_RDWR|O_CREAT|O_EXCL, 0666);
168 193 : if (!tdb) {
169 0 : perror("tdb_open");
170 0 : fprintf(stderr, "Failed to open %s\n", fname);
171 0 : return 1;
172 : }
173 :
174 317532 : while (1) {
175 317725 : int eof = 0;
176 317725 : if (read_rec(stdin, tdb, &eof) == -1) {
177 193 : if (eof) {
178 193 : break;
179 : }
180 0 : return 1;
181 : }
182 : }
183 193 : if (tdb_close(tdb)) {
184 0 : fprintf(stderr, "Error closing tdb\n");
185 0 : return 1;
186 : }
187 193 : return 0;
188 : }
189 :
190 193 : int main(int argc, char *argv[])
191 : {
192 : char *fname;
193 :
194 193 : if (argc < 2) {
195 0 : printf("Usage: %s dbname < tdbdump_output\n", argv[0]);
196 0 : exit(1);
197 : }
198 :
199 193 : fname = argv[1];
200 :
201 193 : return restore_tdb(fname);
202 : }
|