2 Bacula(R) - The Network Backup Solution
4 Copyright (C) 2000-2018 Kern Sibbald
6 The original author of Bacula is Kern Sibbald, with contributions
7 from many others, a complete list can be found in the file AUTHORS.
9 You may use this file and others of this release according to the
10 license defined in the LICENSE file, which includes the Affero General
11 Public License, v3.0 ("AGPLv3") and some additional permissions and
12 terms pursuant to its AGPLv3 Section 7.
14 This notice must be preserved when any source code is
15 conveyed and/or propagated.
17 Bacula(R) is a registered trademark of Kern Sibbald.
20 * Written by James Harper, July 2010
22 * Used only in "old Exchange plugin" now deprecated.
25 #include "exchange-fd.h"
27 dbi_node_t::dbi_node_t(char *name, node_t *parent_node) : node_t(name, NODE_TYPE_DATABASE_INFO, parent_node)
29 restore_display_name = NULL;
30 restore_input_streams = NULL;
34 dbi_node_t::~dbi_node_t()
37 safe_delete(restore_input_streams);
38 safe_delete(restore_display_name);
42 dbi_node_t::startBackupFile(exchange_fd_context_t *context, struct save_pkt *sp)
44 time_t now = time(NULL);
46 _DebugMessage(100, "startBackupNode_DBI state = %d\n", state);
48 if (context->job_level == 'F') {
49 sp->fname = full_path;
51 sp->statp.st_mode = 0700 | S_IFREG;
52 sp->statp.st_ctime = now;
53 sp->statp.st_mtime = now;
54 sp->statp.st_atime = now;
55 sp->statp.st_size = (uint64_t)-1;
61 bfuncs->setBaculaValue(context->bpContext, bVarFileSeen, (void *)full_path);
67 dbi_node_t::endBackupFile(exchange_fd_context_t *context)
69 _DebugMessage(100, "endBackupNode_DBI state = %d\n", state);
71 context->current_node = parent;
77 dbi_node_t::createFile(exchange_fd_context_t *context, struct restore_pkt *rp)
79 _DebugMessage(0, "createFile_DBI state = %d\n", state);
81 rp->create_status = CF_EXTRACT;
87 dbi_node_t::endRestoreFile(exchange_fd_context_t *context)
89 _DebugMessage(0, "endRestoreFile_DBI state = %d\n", state);
91 context->current_node = parent;
97 dbi_node_t::pluginIoOpen(exchange_fd_context_t *context, struct io_pkt *io)
106 buffer = new char[buffer_size];
108 if (context->job_type == JOB_TYPE_BACKUP)
110 ptr = (WCHAR *)buffer;
111 len = snwprintf(ptr, (buffer_size - buffer_pos) / 2, L"DatabaseBackupInfo\n");
114 buffer_pos += len * 2;
117 len = snwprintf(ptr, (buffer_size - buffer_pos) / 2, L"%d\n", EXCHANGE_PLUGIN_VERSION);
120 buffer_pos += len * 2;
123 len = snwprintf(ptr, (buffer_size - buffer_pos) / 2, L"%s\n", dbi->wszDatabaseDisplayName);
126 buffer_pos += len * 2;
129 len = snwprintf(ptr, (buffer_size - buffer_pos) / 2, L"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x\n",
130 dbi->rguidDatabase.Data1, dbi->rguidDatabase.Data2, dbi->rguidDatabase.Data3,
131 dbi->rguidDatabase.Data4[0], dbi->rguidDatabase.Data4[1],
132 dbi->rguidDatabase.Data4[2], dbi->rguidDatabase.Data4[3],
133 dbi->rguidDatabase.Data4[4], dbi->rguidDatabase.Data4[5],
134 dbi->rguidDatabase.Data4[6], dbi->rguidDatabase.Data4[7]);
137 buffer_pos += len * 2;
140 stream = dbi->wszDatabaseStreams;
143 len = snwprintf(ptr, (buffer_size - buffer_pos) / 2, L"%s\n", stream);
146 buffer_pos += len * 2;
148 stream += wcslen(stream) + 1;
151 buffer_size = buffer_pos;
166 dbi_node_t::pluginIoRead(exchange_fd_context_t *context, struct io_pkt *io)
171 io->status = MIN(io->count, (int)(buffer_size - buffer_pos));
174 memcpy(io->buf, buffer + buffer_pos, io->status);
175 buffer_pos += io->status;
181 dbi_node_t::pluginIoWrite(exchange_fd_context_t *context, struct io_pkt *io)
183 memcpy(&buffer[buffer_pos], io->buf, io->count);
184 buffer_pos += io->count;
185 io->status = io->count;
191 dbi_node_t::pluginIoClose(exchange_fd_context_t *context, struct io_pkt *io)
198 int stream_buf_count;
199 WCHAR *streams_start;
201 if (context->job_type == JOB_TYPE_RESTORE)
203 // need to think about making this buffer overflow proof...
204 _DebugMessage(100, "analyzing DatabaseBackupInfo\n");
205 ptr = (WCHAR *)buffer;
207 if (swscanf(ptr, L"%127[^\n]%c%n", tmp, &eol, &wchars_read) != 2)
210 _DebugMessage(150, "Header = %S\n", tmp);
211 // verify that header == "DatabaseBackupInfo"
213 if (swscanf(ptr, L"%127[^\n]%c%n", tmp, &eol, &wchars_read) != 2)
215 if (swscanf(tmp, L"%d%c", &version, &eol) != 1)
218 _DebugMessage(150, "Version = 0 (inferred)\n");
223 _DebugMessage(150, "Version = %d\n", version);
224 if (swscanf(ptr, L"%127[^\n]%c%n", tmp, &eol, &wchars_read) != 2)
227 restore_display_name = new WCHAR[wchars_read];
228 swscanf(ptr, L"%127[^\n]", restore_display_name);
229 _DebugMessage(150, "Database Display Name = %S\n", restore_display_name);
232 if (swscanf(ptr, L"%127[^\n]%c%n", tmp, &eol, &wchars_read) != 2)
235 if (swscanf(ptr, L"%8x-%4x-%4x-%2x%2x-%2x%2x%2x%2x%2x%2x",
236 &restore_guid.Data1, &restore_guid.Data2, &restore_guid.Data3,
237 &restore_guid.Data4[0], &restore_guid.Data4[1],
238 &restore_guid.Data4[2], &restore_guid.Data4[3],
239 &restore_guid.Data4[4], &restore_guid.Data4[5],
240 &restore_guid.Data4[6], &restore_guid.Data4[7]) != 11)
244 _DebugMessage(150, "GUID = %08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x\n",
245 restore_guid.Data1, restore_guid.Data2, restore_guid.Data3,
246 restore_guid.Data4[0], restore_guid.Data4[1],
247 restore_guid.Data4[2], restore_guid.Data4[3],
248 restore_guid.Data4[4], restore_guid.Data4[5],
249 restore_guid.Data4[6], restore_guid.Data4[7]);
253 stream_buf_count = 1;
255 while (ptr < (WCHAR *)(buffer + buffer_pos) && swscanf(ptr, L"%127[^\n]%c%n", tmp, &eol, &wchars_read) == 2)
257 _DebugMessage(150, "File = %S\n", tmp);
259 stream_buf_count += wchars_read;
261 restore_input_streams = new WCHAR[stream_buf_count];
263 stream_buf_count = 0;
264 while (ptr < (WCHAR *)(buffer + buffer_pos) && swscanf(ptr, L"%127[^\n]%c%n", tmp, &eol, &wchars_read) == 2)
266 snwprintf(&restore_input_streams[stream_buf_count], 65535, L"%s", tmp);
268 stream_buf_count += wchars_read;
270 restore_input_streams[stream_buf_count] = 0;
272 _DebugMessage(100, "done analyzing DatabasePluginInfo\n");
277 _JobMessage(M_FATAL, "Format of %s is incorrect", full_path);