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 storage_group_node_t::storage_group_node_t(char *name, node_t *parent_node) : node_t(name, NODE_TYPE_STORAGE_GROUP, parent_node)
32 restore_environment = NULL;
33 saved_log_path = NULL;
37 storage_group_node_t::~storage_group_node_t()
40 safe_delete(dbi_node);
41 safe_delete(file_node);
46 storage_group_node_t::startBackupFile(exchange_fd_context_t *context, struct save_pkt *sp)
50 WCHAR *tmp_logfiles, *tmp_logfile_ptr;
55 _DebugMessage(100, "startBackupNode_STORAGE_GROUP state = %d, name = %s\n", state, name);
62 if (context->job_level == 'F')
64 _DebugMessage(100, "Calling HrESEBackupSetup (BACKUP_TYPE_FULL)\n");
65 result = HrESEBackupSetup(hccx, ibi->hInstanceId, BACKUP_TYPE_FULL);
70 _DebugMessage(100, "Calling HrESEBackupSetup (BACKUP_TYPE_LOGS_ONLY)\n");
71 result = HrESEBackupSetup(hccx, ibi->hInstanceId, BACKUP_TYPE_LOGS_ONLY);
72 if (context->accurate)
79 _JobMessage(M_FATAL, "HrESEBackupSetup failed with error 0x%08x - %s\n", result, ESEErrorMessage(result));
85 if (context->path_bits[level + 1] == NULL)
87 _DebugMessage(100, "No specific database specified - backing them all up\n");
88 DATABASE_BACKUP_INFO *dbi = &ibi->rgDatabase[current_dbi];
89 char *tmp = new char[wcslen(dbi->wszDatabaseDisplayName) + 1];
90 wcstombs(tmp, dbi->wszDatabaseDisplayName, wcslen(dbi->wszDatabaseDisplayName) + 1);
91 store_node = new store_node_t(tmp, this);
92 store_node->dbi = dbi;
93 store_node->hccx = hccx;
94 context->current_node = store_node;
98 DATABASE_BACKUP_INFO *dbi = NULL;
100 for (current_dbi = 0; current_dbi < ibi->cDatabase; current_dbi++)
102 dbi = &ibi->rgDatabase[current_dbi];
103 char *tmp = new char[wcslen(dbi->wszDatabaseDisplayName) + 1];
104 wcstombs(tmp, dbi->wszDatabaseDisplayName, wcslen(dbi->wszDatabaseDisplayName) + 1);
105 if (stricmp(tmp, context->path_bits[level + 1]) == 0)
109 if (current_dbi == ibi->cDatabase)
111 _JobMessage(M_FATAL, "Invalid Database '%s'\n", context->path_bits[level + 1]);
114 store_node = new store_node_t(tmp, this);
115 _DebugMessage(100, "Database name = %s\n", store_node->name);
117 store_node->hccx = hccx;
118 store_node->dbi = dbi;
119 context->current_node = store_node;
123 _DebugMessage(100, "Calling HrESEBackupGetLogAndPatchFiles\n");
124 result = HrESEBackupGetLogAndPatchFiles(hccx, &tmp_logfiles);
127 _JobMessage(M_FATAL, "HrESEBackupGetLogAndPatchFiles failed with error 0x%08x - %s\n", result, ESEErrorMessage(result));
130 for (len = 0, tmp_logfile_ptr = tmp_logfiles; *tmp_logfile_ptr != 0; tmp_logfile_ptr += wcslen(tmp_logfile_ptr) + 1)
132 len += wcslen(tmp_logfile_ptr) + 1;
134 logfiles = new WCHAR[len + 1];
135 logfile_ptr = logfiles;
136 for (tmp_logfile_ptr = tmp_logfiles; *tmp_logfile_ptr != 0; tmp_logfile_ptr += wcslen(tmp_logfile_ptr) + 1)
138 // check file modification date
140 FILETIME modified_time;
144 include_file = false;
145 handle = INVALID_HANDLE_VALUE;
146 if (context->job_since == 0)
150 handle = CreateFileW(tmp_logfile_ptr, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
151 if (handle == INVALID_HANDLE_VALUE)
153 //_JobMessage(M_WARNING, "Could not open '%S' to check last modified date (0x%08x), including anyway\n", tmp_logfile_ptr, GetLastError());
159 if (GetFileTime(handle, NULL, NULL, &modified_time) == 0)
161 //_JobMessage(M_WARNING, "Could not check last modified date for '%S' (0x%08x), including anyway\n", tmp_logfile_ptr, GetLastError());
167 tmp_time = (((int64_t)modified_time.dwHighDateTime) << 32) | modified_time.dwLowDateTime;
168 tmp_time -= 116444736000000000LL;
169 tmp_time /= 10000000;
170 if (tmp_time > context->job_since)
177 memcpy(logfile_ptr, tmp_logfile_ptr, (wcslen(tmp_logfile_ptr) + 1) * 2);
178 logfile_ptr += wcslen(logfile_ptr) + 1;
179 //_DebugMessage(100, "Including file %S\n", logfile_ptr);
182 /* this is handled via checkFile now */
185 if (context->accurate) {
186 tmp = new char[strlen(full_path) + wcslen(tmp_logfile_ptr) + 1];
187 strcpy(tmp, full_path);
188 wcstombs(tmp + strlen(full_path), tmp_logfile_ptr, wcslen(tmp_logfile_ptr) + 1);
189 bfuncs->setBaculaValue(context->bpContext, bVarFileSeen, (void *)tmp);
195 if (handle != INVALID_HANDLE_VALUE)
200 logfile_ptr = logfiles;
204 tmp = new char[wcslen(logfile_ptr) + 1];
205 wcstombs(tmp, logfile_ptr, wcslen(logfile_ptr) + 1);
206 file_node = new file_node_t(tmp, this);
208 file_node->hccx = hccx;
209 file_node->filename = logfile_ptr;
210 context->current_node = file_node;
213 time_t now = time(NULL);
214 sp->fname = full_path;
215 sp->link = full_path;
216 _DebugMessage(100, "fname = %s\n", sp->fname);
217 sp->statp.st_mode = 0700 | S_IFDIR;
218 sp->statp.st_ctime = now;
219 sp->statp.st_mtime = now;
220 sp->statp.st_atime = now;
221 sp->statp.st_size = 0;
222 //sp->statp.st_blocks = 0;
223 sp->type = FT_DIREND;
230 storage_group_node_t::endBackupFile(exchange_fd_context_t *context)
233 bRC retval = bRC_Error;
235 _DebugMessage(100, "endBackupNode_STORAGE_GROUP state = %d\n", state);
240 // should never happen
243 // free node->storage_group_node
244 if (context->path_bits[level + 1] == NULL)
247 if (current_dbi == ibi->cDatabase)
255 // should never happen
258 safe_delete(file_node);
259 logfile_ptr += wcslen(logfile_ptr) + 1;
260 if (*logfile_ptr == 0)
265 if (context->truncate_logs) {
266 _DebugMessage(100, "Calling HrESEBackupTruncateLogs\n");
267 result = HrESEBackupTruncateLogs(hccx);
269 _JobMessage(M_FATAL, "HrESEBackupTruncateLogs failed with error 0x%08x - %s\n", result, ESEErrorMessage(result));
271 _JobMessage(M_INFO, "Truncated database logs for Storage Group %s\n", name);
274 _JobMessage(M_INFO, "Did NOT truncate database logs for Storage Group %s\n", name);
276 _DebugMessage(100, "Calling HrESEBackupInstanceEnd\n");
277 result = HrESEBackupInstanceEnd(hccx, ESE_BACKUP_INSTANCE_END_SUCCESS);
279 _JobMessage(M_FATAL, "HrESEBackupInstanceEnd failed with error 0x%08x - %s\n", result, ESEErrorMessage(result));
283 context->current_node = parent;
290 storage_group_node_t::createFile(exchange_fd_context_t *context, struct restore_pkt *rp)
295 _DebugMessage(0, "createFile_STORAGE_GROUP state = %d\n", state);
297 if (strcmp(context->path_bits[level], name) != 0) {
298 _DebugMessage(0, "Different storage group - switching back to parent\n", state);
299 saved_log_path = new WCHAR[wcslen(restore_environment->m_wszRestoreLogPath) + 1];
300 wcscpy(saved_log_path, restore_environment->m_wszRestoreLogPath);
301 _DebugMessage(100, "Calling HrESERestoreSaveEnvironment\n");
302 result = HrESERestoreSaveEnvironment(hccx);
304 _JobMessage(M_FATAL, "HrESERestoreSaveEnvironment failed with error 0x%08x - %s\n", result, ESEErrorMessage(result));
306 rp->create_status = CF_CREATED;
309 _DebugMessage(100, "Calling HrESERestoreClose\n");
310 result = HrESERestoreClose(hccx, RESTORE_CLOSE_NORMAL);
312 _JobMessage(M_FATAL, "HrESERestoreClose failed with error 0x%08x - %s\n", result, ESEErrorMessage(result));
314 rp->create_status = CF_CREATED;
317 context->current_node = parent;
320 if (saved_log_path != NULL) {
321 _DebugMessage(0, "Calling HrESERestoreReopen\n");
322 result = HrESERestoreReopen(context->computer_name, service_name, saved_log_path, &hccx);
324 _JobMessage(M_FATAL, "HrESERestoreReopen failed with error 0x%08x - %s\n", result, ESEErrorMessage(result));
326 saved_log_path = NULL;
327 rp->create_status = CF_CREATED;
330 _DebugMessage(0, "Calling HrESERestoreGetEnvironment\n");
331 result = HrESERestoreGetEnvironment(hccx, &restore_environment);
333 _JobMessage(M_FATAL, "HrESERestoreGetEnvironment failed with error 0x%08x - %s\n", result, ESEErrorMessage(result));
335 saved_log_path = NULL;
336 rp->create_status = CF_CREATED;
339 saved_log_path = NULL;
345 if (context->path_bits[level + 2] == NULL) {
346 _JobMessage(M_ERROR, "Unexpected log file '%s%s' - expecting database\n", full_path, context->path_bits[level + 1]);
350 service_name = new WCHAR[strlen(parent->name) + 1];
351 storage_group_name = new WCHAR[strlen(name) + 1];
352 mbstowcs(service_name, parent->name, strlen(parent->name) + 1);
353 mbstowcs(storage_group_name, name, strlen(name) + 1);
354 _DebugMessage(0, "Calling HrESERestoreOpen\n");
355 result = HrESERestoreOpen(context->computer_name, service_name, storage_group_name, NULL, &hccx);
357 _JobMessage(M_FATAL, "HrESERestoreOpen failed with error 0x%08x - %s\n", result, ESEErrorMessage(result));
361 _DebugMessage(0, "Calling HrESERestoreGetEnvironment\n");
362 result = HrESERestoreGetEnvironment(hccx, &restore_environment);
364 _JobMessage(M_FATAL, "HrESERestoreGetEnvironment failed with error 0x%08x - %s\n", result, ESEErrorMessage(result));
371 if (context->path_bits[level + 2] == NULL) {
375 store_node = new store_node_t(bstrdup(context->path_bits[level + 1]), this);
376 store_node->hccx = hccx;
377 context->current_node = store_node;
380 if (context->path_bits[level + 2] != NULL) {
381 _JobMessage(M_ERROR, "Unexpected file '%s'\n", full_path);
385 if (context->path_bits[level + 1] == NULL) {
390 file_node = new file_node_t(bstrdup(context->path_bits[level + 1]), this);
391 file_node->hccx = hccx;
393 for (i = strlen(file_node->name) - 1; i >= 0; i--) {
394 if (file_node->name[i] == '\\') {
399 len = wcslen(restore_environment->m_wszRestoreLogPath) + strlen(file_node->name + i) + 1 + 1;
400 file_node->filename = new WCHAR[len];
401 wcscpy(file_node->filename, restore_environment->m_wszRestoreLogPath);
402 wcscat(file_node->filename, L"\\");
403 mbstowcs(&file_node->filename[wcslen(file_node->filename)], file_node->name + i, strlen(file_node->name + i) + 1);
404 context->current_node = file_node;
407 if (rp->type != FT_DIREND) {
408 _JobMessage(M_ERROR, "Unexpected file '%s'\n", full_path);
412 // must be the storage group node
413 _DebugMessage(100, "Calling HrESERestoreSaveEnvironment\n");
414 result = HrESERestoreSaveEnvironment(hccx);
416 _JobMessage(M_FATAL, "HrESERestoreSaveEnvironment failed with error 0x%08x - %s\n", result, ESEErrorMessage(result));
421 _DebugMessage(100, "Calling HrESERestoreComplete\n");
422 result = HrESERestoreComplete(hccx, restore_environment->m_wszRestoreLogPath,
423 restore_environment->m_wszRestoreLogPath, storage_group_name, ESE_RESTORE_COMPLETE_ATTACH_DBS);
425 _JobMessage(M_FATAL, "HrESERestoreComplete failed with error 0x%08x - %s\n", result, ESEErrorMessage(result));
426 _DebugMessage(100, "Calling HrESERestoreClose\n");
427 result = HrESERestoreClose(hccx, RESTORE_CLOSE_NORMAL);
431 _JobMessage(M_INFO, "Storage Group '%s' restored successfully\n", name);
434 _DebugMessage(100, "Calling HrESERestoreClose\n");
435 result = HrESERestoreClose(hccx, RESTORE_CLOSE_NORMAL);
437 _JobMessage(M_FATAL, "HrESERestoreClose failed with error 0x%08x - %s\n", result, ESEErrorMessage(result));
442 rp->create_status = CF_CREATED;
445 rp->create_status = CF_CREATED;
452 storage_group_node_t::endRestoreFile(exchange_fd_context_t *context)
454 _DebugMessage(0, "endRestoreFile_STORAGE_GROUP state = %d\n", state);
463 context->current_node = parent;
466 context->current_node = parent;