2 Bacula® - The Network Backup Solution
4 Copyright (C) 2008-2010 Free Software Foundation Europe e.V.
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.
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.
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
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.
29 * Written by James Harper, October 2008
32 #include "exchange-fd.h"
34 dbi_node_t::dbi_node_t(char *name, node_t *parent_node) : node_t(name, NODE_TYPE_DATABASE_INFO, parent_node)
36 restore_display_name = NULL;
37 restore_input_streams = NULL;
41 dbi_node_t::~dbi_node_t()
45 if (restore_input_streams != NULL)
46 delete restore_input_streams;
47 if (restore_display_name != NULL)
48 delete restore_display_name;
52 dbi_node_t::startBackupFile(exchange_fd_context_t *context, struct save_pkt *sp)
54 time_t now = time(NULL);
56 _DebugMessage(100, "startBackupNode_DBI state = %d\n", state);
58 if (context->job_level == 'F') {
59 sp->fname = 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;
71 bfuncs->setBaculaValue(context->bpContext, bVarFileSeen, (void *)full_path);
77 dbi_node_t::endBackupFile(exchange_fd_context_t *context)
79 _DebugMessage(100, "endBackupNode_DBI state = %d\n", state);
81 context->current_node = parent;
87 dbi_node_t::createFile(exchange_fd_context_t *context, struct restore_pkt *rp)
89 _DebugMessage(100, "createFile_DBI state = %d\n", state);
91 rp->create_status = CF_EXTRACT;
97 dbi_node_t::endRestoreFile(exchange_fd_context_t *context)
99 _DebugMessage(100, "endRestoreFile_DBI state = %d\n", state);
101 context->current_node = parent;
107 dbi_node_t::pluginIoOpen(exchange_fd_context_t *context, struct io_pkt *io)
116 buffer = new char[buffer_size];
118 if (context->job_type == JOB_TYPE_BACKUP)
120 ptr = (WCHAR *)buffer;
121 len = snwprintf(ptr, (buffer_size - buffer_pos) / 2, L"DatabaseBackupInfo\n");
124 buffer_pos += len * 2;
127 len = snwprintf(ptr, (buffer_size - buffer_pos) / 2, L"%d\n", EXCHANGE_PLUGIN_VERSION);
130 buffer_pos += len * 2;
133 len = snwprintf(ptr, (buffer_size - buffer_pos) / 2, L"%s\n", dbi->wszDatabaseDisplayName);
136 buffer_pos += len * 2;
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]);
147 buffer_pos += len * 2;
150 stream = dbi->wszDatabaseStreams;
153 len = snwprintf(ptr, (buffer_size - buffer_pos) / 2, L"%s\n", stream);
156 buffer_pos += len * 2;
158 stream += wcslen(stream) + 1;
161 buffer_size = buffer_pos;
176 dbi_node_t::pluginIoRead(exchange_fd_context_t *context, struct io_pkt *io)
181 io->status = MIN(io->count, (int)(buffer_size - buffer_pos));
184 memcpy(io->buf, buffer + buffer_pos, io->status);
185 buffer_pos += io->status;
191 dbi_node_t::pluginIoWrite(exchange_fd_context_t *context, struct io_pkt *io)
193 memcpy(&buffer[buffer_pos], io->buf, io->count);
194 buffer_pos += io->count;
195 io->status = io->count;
201 dbi_node_t::pluginIoClose(exchange_fd_context_t *context, struct io_pkt *io)
208 int stream_buf_count;
209 WCHAR *streams_start;
211 if (context->job_type == JOB_TYPE_RESTORE)
213 // need to think about making this buffer overflow proof...
214 _DebugMessage(100, "analyzing DatabaseBackupInfo\n");
215 ptr = (WCHAR *)buffer;
217 if (swscanf(ptr, L"%127[^\n]%c%n", tmp, &eol, &wchars_read) != 2)
220 _DebugMessage(150, "Header = %S\n", tmp);
221 // verify that header == "DatabaseBackupInfo"
223 if (swscanf(ptr, L"%127[^\n]%c%n", tmp, &eol, &wchars_read) != 2)
225 if (swscanf(tmp, L"%d%c", &version, &eol) != 1)
228 _DebugMessage(150, "Version = 0 (inferred)\n");
233 _DebugMessage(150, "Version = %d\n", version);
234 if (swscanf(ptr, L"%127[^\n]%c%n", tmp, &eol, &wchars_read) != 2)
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);
242 if (swscanf(ptr, L"%127[^\n]%c%n", tmp, &eol, &wchars_read) != 2)
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)
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]);
263 stream_buf_count = 1;
265 while (ptr < (WCHAR *)(buffer + buffer_pos) && swscanf(ptr, L"%127[^\n]%c%n", tmp, &eol, &wchars_read) == 2)
267 _DebugMessage(150, "File = %S\n", tmp);
269 stream_buf_count += wchars_read;
271 restore_input_streams = new WCHAR[stream_buf_count];
273 stream_buf_count = 0;
274 while (ptr < (WCHAR *)(buffer + buffer_pos) && swscanf(ptr, L"%127[^\n]%c%n", tmp, &eol, &wchars_read) == 2)
276 snwprintf(&restore_input_streams[stream_buf_count], 65535, L"%s", tmp);
278 stream_buf_count += wchars_read;
280 restore_input_streams[stream_buf_count] = 0;
282 _DebugMessage(100, "done analyzing DatabasePluginInfo\n");
288 _JobMessage(M_FATAL, "Format of %s is incorrect", full_path);