librpc: Shorten dcerpc_binding_handle_call a bit
[Samba/gebeck_regimport.git] / lib / ntdb / tools / ntdbrestore.c
blob1df9322e6412533dba3391c151e6052a49dbf493
1 /*
2 ntdbrestore -- construct a ntdb from (n)tdbdump output.
3 Copyright (C) Rusty Russell 2012
4 Copyright (C) Volker Lendecke 2010
5 Copyright (C) Simon McVittie 2005
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "config.h"
22 #include "ntdb.h"
23 #include <assert.h>
24 #ifdef HAVE_LIBREPLACE
25 #include <replace.h>
26 #include <system/filesys.h>
27 #else
28 #include <sys/types.h>
29 #include <sys/stat.h>
30 #include <fcntl.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #endif
35 static int read_linehead(FILE *f)
37 int i, c;
38 int num_bytes;
39 char prefix[128];
41 while (1) {
42 c = getc(f);
43 if (c == EOF) {
44 return -1;
46 if (c == '(') {
47 break;
50 for (i=0; i<sizeof(prefix); i++) {
51 c = getc(f);
52 if (c == EOF) {
53 return -1;
55 prefix[i] = c;
56 if (c == '"') {
57 break;
60 if (i == sizeof(prefix)) {
61 return -1;
63 prefix[i] = '\0';
65 if (sscanf(prefix, "%d) = ", &num_bytes) != 1) {
66 return -1;
68 return num_bytes;
71 static int read_hex(void) {
72 int c;
73 c = getchar();
74 if (c == EOF) {
75 fprintf(stderr, "Unexpected EOF in data\n");
76 return -1;
77 } else if (c == '"') {
78 fprintf(stderr, "Unexpected \\\" sequence\n");
79 return -1;
80 } else if ('0' <= c && c <= '9') {
81 return c - '0';
82 } else if ('A' <= c && c <= 'F') {
83 return c - 'A' + 10;
84 } else if ('a' <= c && c <= 'f') {
85 return c - 'a' + 10;
86 } else {
87 fprintf(stderr, "Invalid hex: %c\n", c);
88 return -1;
92 static int read_data(FILE *f, NTDB_DATA *d, size_t size) {
93 int c, low, high;
94 int i;
96 d->dptr = (unsigned char *)malloc(size);
97 if (d->dptr == NULL) {
98 return -1;
100 d->dsize = size;
102 for (i=0; i<size; i++) {
103 c = getc(f);
104 if (c == EOF) {
105 fprintf(stderr, "Unexpected EOF in data\n");
106 return 1;
107 } else if (c == '"') {
108 return 0;
109 } else if (c == '\\') {
110 high = read_hex();
111 if (high < 0) {
112 return -1;
114 high = high << 4;
115 assert(high == (high & 0xf0));
116 low = read_hex();
117 if (low < 0) {
118 return -1;
120 assert(low == (low & 0x0f));
121 d->dptr[i] = (low|high);
122 } else {
123 d->dptr[i] = c;
126 return 0;
129 static int swallow(FILE *f, const char *s, int *eof)
131 char line[128];
133 if (fgets(line, sizeof(line), f) == NULL) {
134 if (eof != NULL) {
135 *eof = 1;
137 return -1;
139 if (strcmp(line, s) != 0) {
140 return -1;
142 return 0;
145 static bool read_rec(FILE *f, struct ntdb_context *ntdb, int *eof)
147 int length;
148 NTDB_DATA key, data;
149 bool ret = false;
150 enum NTDB_ERROR e;
152 key.dptr = NULL;
153 data.dptr = NULL;
155 if (swallow(f, "{\n", eof) == -1) {
156 goto fail;
158 length = read_linehead(f);
159 if (length == -1) {
160 goto fail;
162 if (read_data(f, &key, length) == -1) {
163 goto fail;
165 if (swallow(f, "\"\n", NULL) == -1) {
166 goto fail;
168 length = read_linehead(f);
169 if (length == -1) {
170 goto fail;
172 if (read_data(f, &data, length) == -1) {
173 goto fail;
175 if ((swallow(f, "\"\n", NULL) == -1)
176 || (swallow(f, "}\n", NULL) == -1)) {
177 goto fail;
179 e = ntdb_store(ntdb, key, data, NTDB_INSERT);
180 if (e != NTDB_SUCCESS) {
181 fprintf(stderr, "NTDB error: %s\n", ntdb_errorstr(e));
182 goto fail;
185 ret = true;
186 fail:
187 free(key.dptr);
188 free(data.dptr);
189 return ret;
192 static int restore_ntdb(const char *fname, unsigned int hsize)
194 struct ntdb_context *ntdb;
195 union ntdb_attribute hashsize;
197 hashsize.base.attr = NTDB_ATTRIBUTE_HASHSIZE;
198 hashsize.base.next = NULL;
199 hashsize.hashsize.size = hsize;
201 ntdb = ntdb_open(fname, 0, O_RDWR|O_CREAT|O_EXCL, 0666,
202 hsize ? &hashsize : NULL);
203 if (!ntdb) {
204 perror("ntdb_open");
205 fprintf(stderr, "Failed to open %s\n", fname);
206 return 1;
209 while (1) {
210 int eof = 0;
211 if (!read_rec(stdin, ntdb, &eof)) {
212 if (eof) {
213 break;
215 return 1;
218 if (ntdb_close(ntdb)) {
219 fprintf(stderr, "Error closing ntdb\n");
220 return 1;
222 fprintf(stderr, "EOF\n");
223 return 0;
226 int main(int argc, char *argv[])
228 unsigned int hsize = 0;
229 const char *execname = argv[0];
231 if (argv[1] && strcmp(argv[1], "-h") == 0) {
232 if (argv[2]) {
233 hsize = atoi(argv[2]);
235 if (hsize == 0) {
236 fprintf(stderr, "-h requires a integer value"
237 " (eg. 128 or 131072)\n");
238 exit(1);
240 argv += 2;
241 argc -= 2;
243 if (argc != 2) {
244 printf("Usage: %s [-h <hashsize>] dbname < tdbdump_output\n",
245 execname);
246 exit(1);
250 return restore_ntdb(argv[1], hsize);