]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/win32/filed/plugins/service_node.c
Restore win32 dir from Branch-5.2 and update it
[bacula/bacula] / bacula / src / win32 / filed / plugins / service_node.c
diff --git a/bacula/src/win32/filed/plugins/service_node.c b/bacula/src/win32/filed/plugins/service_node.c
new file mode 100644 (file)
index 0000000..0953200
--- /dev/null
@@ -0,0 +1,229 @@
+/*
+   Bacula® - The Network Backup Solution
+
+   Copyright (C) 2008-2010 Free Software Foundation Europe e.V.
+
+   The main author of Bacula is Kern Sibbald, with contributions from
+   many others, a complete list can be found in the file AUTHORS.
+   This program is Free Software; you can redistribute it and/or
+   modify it under the terms of version three of the GNU Affero General Public
+   License as published by the Free Software Foundation, which is 
+   listed in the file LICENSE.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU Affero General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
+
+   Bacula® is a registered trademark of Kern Sibbald.
+   The licensor of Bacula is the Free Software Foundation Europe
+   (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
+   Switzerland, email:ftf@fsfeurope.org.
+*/
+/* 
+ *  Written by James Harper, October 2008
+ */
+
+#include "exchange-fd.h"
+
+service_node_t::service_node_t(char *name, node_t *parent_node) : node_t(name, NODE_TYPE_SERVICE, parent_node)
+{
+   current_ibi = 0;
+   hccx = NULL;
+   ibi = NULL;
+   ibi_count = 0;
+   first_storage_group_node = NULL;
+}
+
+service_node_t::~service_node_t()
+{
+}
+
+bRC
+service_node_t::startBackupFile(exchange_fd_context_t *context, struct save_pkt *sp)
+{
+   HRESULT result;
+   char aname[256];
+
+   _DebugMessage(100, "startBackupNode_SERVICE state = %d\n", state);
+   switch(state)
+   {
+   case 0:
+      if (strcmp(PLUGIN_PATH_PREFIX_SERVICE, name) != 0)
+      {
+         _JobMessage(M_FATAL, "Invalid restore path specified, must start with /" PLUGIN_PATH_PREFIX_BASE "/" PLUGIN_PATH_PREFIX_SERVICE "/\n");
+         return bRC_Error;
+      }
+      // convert name to a wide string
+
+      _DebugMessage(100, "Calling HrESEBackupPrepare\n");
+      wcstombs(aname, context->computer_name, 256);
+      _JobMessage(M_INFO, "Preparing Exchange Backup for %s\n", aname);
+      result = HrESEBackupPrepare(context->computer_name, PLUGIN_PATH_PREFIX_SERVICE_W, &ibi_count, &ibi, &hccx);
+      if (result != 0)
+      {
+         _JobMessage(M_FATAL, "HrESEBackupPrepare failed with error 0x%08x - %s\n", result, ESEErrorMessage(result));
+         return bRC_Error;
+      }
+      state = 1;
+      // fall through
+   case 1:
+      if (context->path_bits[level + 1] == NULL)
+      {
+         _DebugMessage(100, "No specific storage group specified - backing them all up\n");
+         char *tmp = new char[wcslen(ibi[current_ibi].wszInstanceName) + 1];
+         wcstombs(tmp, ibi[current_ibi].wszInstanceName, wcslen(ibi[current_ibi].wszInstanceName) + 1);
+         first_storage_group_node = new storage_group_node_t(tmp, this);
+         delete tmp;
+         _DebugMessage(100, "storage group name = %s\n", first_storage_group_node->name);
+         first_storage_group_node->ibi = &ibi[current_ibi];
+         first_storage_group_node->hccx = hccx;
+         context->current_node = first_storage_group_node;
+      }
+      else
+      {
+         char *tmp = NULL;
+         for (current_ibi = 0; current_ibi < ibi_count; current_ibi++)
+         {
+            tmp = new char[wcslen(ibi[current_ibi].wszInstanceName) + 1];
+            wcstombs(tmp, ibi[current_ibi].wszInstanceName, wcslen(ibi[current_ibi].wszInstanceName) + 1);
+            if (stricmp(tmp, context->path_bits[level + 1]) == 0)
+               break;
+         }
+         first_storage_group_node = new storage_group_node_t(tmp, this);
+         delete tmp;
+         if (current_ibi == ibi_count)
+         {
+            _JobMessage(M_FATAL, "Invalid Storage Group '%s'\n", context->path_bits[level + 1]);
+            return bRC_Error;
+         }
+         _DebugMessage(100, "storage group name = %s\n", first_storage_group_node->name);
+         first_storage_group_node->ibi = &ibi[current_ibi];
+         first_storage_group_node->hccx = hccx;
+         context->current_node = first_storage_group_node;
+      }
+      break;
+   case 2:
+      time_t now = time(NULL);
+      sp->fname = full_path;
+      sp->link = full_path;
+      sp->statp.st_mode = 0700 | S_IFDIR;
+      sp->statp.st_ctime = now;
+      sp->statp.st_mtime = now;
+      sp->statp.st_atime = now;
+      sp->statp.st_size = 0;
+      sp->statp.st_nlink = 1;
+      //sp->statp.st_blocks = 0;
+      sp->type = FT_DIREND;
+      break;
+   }
+   _DebugMessage(100, "ending startBackupNode_SERVICE state = %d\n", state);
+   return bRC_OK;
+}
+
+bRC
+service_node_t::endBackupFile(exchange_fd_context_t *context)
+{
+   HRESULT result;
+   bRC retval = bRC_OK;
+
+   _DebugMessage(100, "endBackupNode_SERVICE state = %d\n", state);
+   switch(state)
+   {
+   case 0:
+      // should never happen
+      break;
+   case 1:
+      // free node->storage_group_node
+      if (context->path_bits[level + 1] == NULL)
+      {
+         current_ibi++;
+         if (current_ibi == ibi_count)
+            state = 2;
+      }
+      else
+         state = 2;
+      retval = bRC_More;
+      break;
+   case 2:
+      _DebugMessage(100, "calling HrESEBackupEnd\n");
+      result = HrESEBackupEnd(hccx);
+      if (result != 0)
+      {
+         _JobMessage(M_FATAL, "HrESEBackupEnd failed with error 0x%08x - %s\n", result, ESEErrorMessage(result));
+         return bRC_Error;
+      }
+
+      context->current_node = parent;
+      retval = bRC_OK;
+      break;
+   }
+   return retval;
+}
+
+bRC
+service_node_t::createFile(exchange_fd_context_t *context, struct restore_pkt *rp)
+{
+   storage_group_node_t *curr_sg, *prev_sg;
+
+   _DebugMessage(100, "createFile_SERVICE state = %d\n", state);
+   if (strcmp(name, "Microsoft Information Store") != 0)
+   {
+      _JobMessage(M_FATAL, "Invalid restore path specified, must start with '/" PLUGIN_PATH_PREFIX_BASE "/" PLUGIN_PATH_PREFIX_SERVICE "/'\n", state);
+      return bRC_Error;
+   }
+   for(;;)
+   {
+      switch (state)
+      {
+      case 0:
+         if (context->path_bits[level + 1] == NULL)
+         {
+            state = 1;
+            break;
+         }
+         for (prev_sg = NULL, curr_sg = first_storage_group_node; curr_sg != NULL; prev_sg = curr_sg, curr_sg = curr_sg->next)
+         {
+            if (strcmp(curr_sg->name, context->path_bits[level + 1]) == 0)
+            {
+               break;
+            }
+         }
+         if (curr_sg == NULL)
+         {
+            curr_sg = new storage_group_node_t(bstrdup(context->path_bits[level + 1]), this);
+            if (prev_sg == NULL)
+               first_storage_group_node = curr_sg;
+            else
+               prev_sg->next = curr_sg;
+         }
+         context->current_node = curr_sg;
+         return bRC_OK;
+      case 1:
+         rp->create_status = CF_CREATED;
+         return bRC_OK;
+      }
+   }
+   return bRC_Error;
+}
+
+bRC
+service_node_t::endRestoreFile(exchange_fd_context_t *context)
+{
+   _DebugMessage(100, "endRestoreFile_SERVICE state = %d\n", state);
+   switch(state)
+   {
+   case 0:
+      return bRC_Error;
+   case 1:
+      context->current_node = parent;
+      return bRC_OK;
+   }
+
+   return bRC_Error;
+}