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 3419506 : static int read_linehead(FILE *f)
29 : {
30 2527731 : size_t i;
31 2527731 : int c;
32 2527731 : int num_bytes;
33 2527731 : char prefix[128];
34 :
35 2527731 : while (1) {
36 5385519 : c = getc(f);
37 5385519 : if (c == EOF) {
38 0 : return -1;
39 : }
40 5385519 : if (c == '(') {
41 635064 : break;
42 : }
43 : }
44 9115630 : for (i=0; i<sizeof(prefix); i++) {
45 9115630 : c = getc(f);
46 9115630 : if (c == EOF) {
47 0 : return -1;
48 : }
49 9115630 : prefix[i] = c;
50 9115630 : if (c == '"') {
51 635064 : break;
52 : }
53 : }
54 1196782 : if (i == sizeof(prefix)) {
55 0 : return -1;
56 : }
57 1196782 : prefix[i] = '\0';
58 :
59 1196782 : if (sscanf(prefix, "%d) = ", &num_bytes) != 1) {
60 0 : return -1;
61 : }
62 1196782 : return num_bytes;
63 : }
64 :
65 1196782 : static int read_data(FILE *f, TDB_DATA *d, size_t size) {
66 561718 : size_t i;
67 :
68 1196782 : d->dptr = (unsigned char *)malloc(size);
69 1196782 : if (d->dptr == NULL) {
70 0 : return -1;
71 : }
72 1196782 : d->dsize = size;
73 :
74 392323552 : for (i=0; i<size; i++) {
75 391126770 : int c = getc(f);
76 391126770 : if (c == EOF) {
77 0 : fprintf(stderr, "Unexpected EOF in data\n");
78 0 : return 1;
79 391126770 : } else if (c == '"') {
80 0 : return 0;
81 391126770 : } else if (c == '\\') {
82 138474403 : char in[3] = {0};
83 65691719 : size_t n;
84 65691719 : bool ok;
85 :
86 138474403 : n = fread(in, 1, 2, stdin);
87 138474403 : if (n != 2) {
88 0 : return -1;
89 : }
90 138474403 : ok = hex_byte(in, &d->dptr[i]);
91 138474403 : if (!ok) {
92 0 : fprintf(stderr, "Invalid hex: .2%s\n", in);
93 0 : return -1;
94 : }
95 : } else {
96 252652367 : d->dptr[i] = c;
97 : }
98 : }
99 635064 : return 0;
100 : }
101 :
102 2393917 : static int swallow(FILE *f, const char *s, int *eof)
103 : {
104 1123596 : char line[128];
105 :
106 2393917 : if (fgets(line, sizeof(line), f) == NULL) {
107 353 : if (eof != NULL) {
108 353 : *eof = 1;
109 : }
110 353 : return -1;
111 : }
112 2393564 : if (strcmp(line, s) != 0) {
113 0 : return -1;
114 : }
115 1270128 : return 0;
116 : }
117 :
118 598744 : static int read_rec(FILE *f, TDB_CONTEXT *tdb, int *eof)
119 : {
120 281019 : int length;
121 281019 : TDB_DATA key, data;
122 598744 : int ret = -1;
123 :
124 598744 : key.dptr = NULL;
125 598744 : data.dptr = NULL;
126 :
127 598744 : if (swallow(f, "{\n", eof) == -1) {
128 353 : goto fail;
129 : }
130 598391 : length = read_linehead(f);
131 598391 : if (length == -1) {
132 0 : goto fail;
133 : }
134 598391 : if (read_data(f, &key, length) == -1) {
135 0 : goto fail;
136 : }
137 598391 : if (swallow(f, "\"\n", NULL) == -1) {
138 0 : goto fail;
139 : }
140 598391 : length = read_linehead(f);
141 598391 : if (length == -1) {
142 0 : goto fail;
143 : }
144 598391 : if (read_data(f, &data, length) == -1) {
145 0 : goto fail;
146 : }
147 598391 : if ((swallow(f, "\"\n", NULL) == -1)
148 598391 : || (swallow(f, "}\n", NULL) == -1)) {
149 0 : goto fail;
150 : }
151 598391 : 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 598744 : fail:
158 598744 : free(key.dptr);
159 598744 : free(data.dptr);
160 598744 : return ret;
161 : }
162 :
163 353 : static int restore_tdb(const char *fname)
164 : {
165 160 : TDB_CONTEXT *tdb;
166 :
167 353 : tdb = tdb_open(fname, 0, 0, O_RDWR|O_CREAT|O_EXCL, 0666);
168 353 : if (!tdb) {
169 0 : perror("tdb_open");
170 0 : fprintf(stderr, "Failed to open %s\n", fname);
171 0 : return 1;
172 : }
173 :
174 598391 : while (1) {
175 598744 : int eof = 0;
176 598744 : if (read_rec(stdin, tdb, &eof) == -1) {
177 353 : if (eof) {
178 193 : break;
179 : }
180 0 : return 1;
181 : }
182 : }
183 353 : if (tdb_close(tdb)) {
184 0 : fprintf(stderr, "Error closing tdb\n");
185 0 : return 1;
186 : }
187 193 : return 0;
188 : }
189 :
190 353 : int main(int argc, char *argv[])
191 : {
192 160 : char *fname;
193 :
194 353 : if (argc < 2) {
195 0 : printf("Usage: %s dbname < tdbdump_output\n", argv[0]);
196 0 : exit(1);
197 : }
198 :
199 353 : fname = argv[1];
200 :
201 353 : return restore_tdb(fname);
202 : }
|