]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/win32/filed/plugins/dbi_node.c
Restore win32 dir from Branch-5.2 and update it
[bacula/bacula] / bacula / src / win32 / filed / plugins / dbi_node.c
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2008-2010 Free Software Foundation Europe e.V.
5
6    The main author of Bacula is Kern Sibbald, with contributions from
7    many others, a complete list can be found in the file AUTHORS.
8    This program is Free Software; you can redistribute it and/or
9    modify it under the terms of version three of the GNU Affero General Public
10    License as published by the Free Software Foundation, which is 
11    listed in the file LICENSE.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU Affero General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23    Bacula® is a registered trademark of Kern Sibbald.
24    The licensor of Bacula is the Free Software Foundation Europe
25    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26    Switzerland, email:ftf@fsfeurope.org.
27 */
28 /* 
29  *  Written by James Harper, October 2008
30  */
31
32 #include "exchange-fd.h"
33
34 dbi_node_t::dbi_node_t(char *name, node_t *parent_node) : node_t(name, NODE_TYPE_DATABASE_INFO, parent_node)
35 {
36    restore_display_name = NULL;
37    restore_input_streams = NULL;
38    buffer = NULL;
39 }
40
41 dbi_node_t::~dbi_node_t()
42 {
43    if (buffer != NULL)
44       delete buffer;
45    if (restore_input_streams != NULL)
46       delete restore_input_streams;
47    if (restore_display_name != NULL)
48       delete restore_display_name;
49 }
50
51 bRC
52 dbi_node_t::startBackupFile(exchange_fd_context_t *context, struct save_pkt *sp)
53 {
54    time_t now = time(NULL);
55
56    _DebugMessage(100, "startBackupNode_DBI state = %d\n", state);
57
58    if (context->job_level == 'F') {
59       sp->fname = full_path;
60       sp->link = full_path;
61       sp->statp.st_mode = 0700 | S_IFREG;
62       sp->statp.st_ctime = now;
63       sp->statp.st_mtime = now;
64       sp->statp.st_atime = now;
65       sp->statp.st_size = (uint64_t)-1;
66       sp->type = FT_REG;
67       return bRC_OK;
68    }
69    else
70    {
71       bfuncs->setBaculaValue(context->bpContext, bVarFileSeen, (void *)full_path);
72       return bRC_Seen;
73    }
74 }
75
76 bRC
77 dbi_node_t::endBackupFile(exchange_fd_context_t *context)
78 {
79    _DebugMessage(100, "endBackupNode_DBI state = %d\n", state);
80
81    context->current_node = parent;
82
83    return bRC_OK;
84 }
85
86 bRC
87 dbi_node_t::createFile(exchange_fd_context_t *context, struct restore_pkt *rp)
88 {
89    _DebugMessage(100, "createFile_DBI state = %d\n", state);
90
91    rp->create_status = CF_EXTRACT;
92
93    return bRC_OK;
94 }
95
96 bRC
97 dbi_node_t::endRestoreFile(exchange_fd_context_t *context)
98 {
99    _DebugMessage(100, "endRestoreFile_DBI state = %d\n", state);
100
101    context->current_node = parent;
102
103    return bRC_OK;
104 }
105
106 bRC
107 dbi_node_t::pluginIoOpen(exchange_fd_context_t *context, struct io_pkt *io)
108 {
109    uint32_t len;
110    WCHAR *ptr;
111    WCHAR *stream;
112    //char tmp[512];
113
114    buffer_pos = 0;
115    buffer_size = 65536;
116    buffer = new char[buffer_size];
117
118    if (context->job_type == JOB_TYPE_BACKUP)
119    {
120       ptr = (WCHAR *)buffer;
121       len = snwprintf(ptr, (buffer_size - buffer_pos) / 2, L"DatabaseBackupInfo\n");
122       if (len < 0)
123          goto fail;
124       buffer_pos += len * 2;
125       ptr += len;
126
127       len = snwprintf(ptr, (buffer_size - buffer_pos) / 2, L"%d\n", EXCHANGE_PLUGIN_VERSION);
128       if (len < 0)
129          goto fail;
130       buffer_pos += len * 2;
131       ptr += len;
132
133       len = snwprintf(ptr, (buffer_size - buffer_pos) / 2, L"%s\n", dbi->wszDatabaseDisplayName);
134       if (len < 0)
135          goto fail;
136       buffer_pos += len * 2;
137       ptr += len;
138
139       len = snwprintf(ptr, (buffer_size - buffer_pos) / 2, L"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x\n",
140          dbi->rguidDatabase.Data1, dbi->rguidDatabase.Data2, dbi->rguidDatabase.Data3,
141          dbi->rguidDatabase.Data4[0], dbi->rguidDatabase.Data4[1],
142          dbi->rguidDatabase.Data4[2], dbi->rguidDatabase.Data4[3],
143          dbi->rguidDatabase.Data4[4], dbi->rguidDatabase.Data4[5],
144          dbi->rguidDatabase.Data4[6], dbi->rguidDatabase.Data4[7]);
145       if (len < 0)
146          goto fail;
147       buffer_pos += len * 2;
148       ptr += len;
149       
150       stream = dbi->wszDatabaseStreams;
151       while (*stream)
152       {
153          len = snwprintf(ptr, (buffer_size - buffer_pos) / 2, L"%s\n", stream);
154          if (len < 0)
155             goto fail;
156          buffer_pos += len * 2;
157          ptr += len;
158          stream += wcslen(stream) + 1;
159       }
160
161       buffer_size = buffer_pos;
162       buffer_pos = 0;
163    }
164
165    io->status = 0;
166    io->io_errno = 0;
167    return bRC_OK;
168
169 fail:
170    io->status = 0;
171    io->io_errno = 1;
172    return bRC_Error;
173 }
174
175 bRC
176 dbi_node_t::pluginIoRead(exchange_fd_context_t *context, struct io_pkt *io)
177 {
178    io->status = 0;
179    io->io_errno = 0;
180
181    io->status = MIN(io->count, (int)(buffer_size - buffer_pos));
182    if (io->status == 0)
183       return bRC_OK;
184    memcpy(io->buf, buffer + buffer_pos, io->status);
185    buffer_pos += io->status;
186
187    return bRC_OK;
188 }
189
190 bRC 
191 dbi_node_t::pluginIoWrite(exchange_fd_context_t *context, struct io_pkt *io)
192 {
193    memcpy(&buffer[buffer_pos], io->buf, io->count);
194    buffer_pos += io->count;
195    io->status = io->count;
196    io->io_errno = 0;
197    return bRC_OK;
198 }
199
200 bRC
201 dbi_node_t::pluginIoClose(exchange_fd_context_t *context, struct io_pkt *io)
202 {
203    WCHAR tmp[128];
204    WCHAR *ptr;
205    WCHAR eol;
206    int wchars_read;
207    int version;
208    int stream_buf_count;
209    WCHAR *streams_start;
210
211    if (context->job_type == JOB_TYPE_RESTORE)
212    {
213       // need to think about making this buffer overflow proof...
214       _DebugMessage(100, "analyzing DatabaseBackupInfo\n");
215       ptr = (WCHAR *)buffer;
216
217       if (swscanf(ptr, L"%127[^\n]%c%n", tmp, &eol, &wchars_read) != 2)
218          goto restore_fail;
219       ptr += wchars_read;
220       _DebugMessage(150, "Header = %S\n", tmp);
221       // verify that header == "DatabaseBackupInfo"
222
223       if (swscanf(ptr, L"%127[^\n]%c%n", tmp, &eol, &wchars_read) != 2)
224          goto restore_fail;
225       if (swscanf(tmp, L"%d%c", &version, &eol) != 1)
226       {
227          version = 0;
228          _DebugMessage(150, "Version = 0 (inferred)\n");
229       }
230       else
231       {
232          ptr += wchars_read;
233          _DebugMessage(150, "Version = %d\n", version);
234          if (swscanf(ptr, L"%127[^\n]%c%n", tmp, &eol, &wchars_read) != 2)
235             goto restore_fail;
236       }
237       restore_display_name = new WCHAR[wchars_read];
238       swscanf(ptr, L"%127[^\n]", restore_display_name);
239       _DebugMessage(150, "Database Display Name = %S\n", restore_display_name);
240       ptr += wchars_read;
241
242       if (swscanf(ptr, L"%127[^\n]%c%n", tmp, &eol, &wchars_read) != 2)
243          goto restore_fail;
244       
245       if (swscanf(ptr, L"%8x-%4x-%4x-%2x%2x-%2x%2x%2x%2x%2x%2x",
246          &restore_guid.Data1, &restore_guid.Data2, &restore_guid.Data3,
247          &restore_guid.Data4[0], &restore_guid.Data4[1],
248          &restore_guid.Data4[2], &restore_guid.Data4[3],
249          &restore_guid.Data4[4], &restore_guid.Data4[5],
250          &restore_guid.Data4[6], &restore_guid.Data4[7]) != 11)
251       {
252          goto restore_fail;
253       }
254          _DebugMessage(150, "GUID = %08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x\n",
255          restore_guid.Data1, restore_guid.Data2, restore_guid.Data3,
256          restore_guid.Data4[0], restore_guid.Data4[1],
257          restore_guid.Data4[2], restore_guid.Data4[3],
258          restore_guid.Data4[4], restore_guid.Data4[5],
259          restore_guid.Data4[6], restore_guid.Data4[7]);
260
261       ptr += wchars_read;
262
263       stream_buf_count = 1;
264       streams_start = ptr;
265       while (ptr < (WCHAR *)(buffer + buffer_pos) && swscanf(ptr, L"%127[^\n]%c%n", tmp, &eol, &wchars_read) == 2)
266       {
267          _DebugMessage(150, "File = %S\n", tmp);
268          ptr += wchars_read;
269          stream_buf_count += wchars_read;
270       }
271       restore_input_streams = new WCHAR[stream_buf_count];
272       ptr = streams_start;
273       stream_buf_count = 0;
274       while (ptr < (WCHAR *)(buffer + buffer_pos) && swscanf(ptr, L"%127[^\n]%c%n", tmp, &eol, &wchars_read) == 2)
275       {
276          snwprintf(&restore_input_streams[stream_buf_count], 65535, L"%s", tmp);
277          ptr += wchars_read;
278          stream_buf_count += wchars_read;
279       }
280       restore_input_streams[stream_buf_count] = 0;
281
282       _DebugMessage(100, "done analyzing DatabasePluginInfo\n");
283    }
284    delete buffer;
285    buffer = NULL;
286    return bRC_OK;
287 restore_fail:
288    _JobMessage(M_FATAL, "Format of %s is incorrect", full_path);
289    delete buffer;
290    buffer = NULL;
291    return bRC_Error;
292 }