]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/win32/filed/plugins/service_node.c
Integrate James Harper's Exchange Win32 plugin patch.
[bacula/bacula] / bacula / src / win32 / filed / plugins / service_node.c
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2008-2008 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 two of the GNU 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 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 service_node_t::service_node_t(char *name, node_t *parent_node) : node_t(name, NODE_TYPE_SERVICE, parent_node)
35 {
36         current_ibi = 0;
37         hccx = NULL;
38         ibi = NULL;
39         ibi_count = 0;
40         first_storage_group_node = NULL;
41 }
42
43 service_node_t::~service_node_t()
44 {
45 }
46
47 bRC
48 service_node_t::startBackupFile(exchange_fd_context_t *context, struct save_pkt *sp)
49 {
50         HRESULT result;
51
52         _DebugMessage(100, "startBackupNode_SERVICE state = %d\n", state);
53         switch(state)
54         {
55         case 0:
56                 if (strcmp(PLUGIN_PATH_PREFIX_SERVICE, name) != 0)
57                 {
58                         _JobMessage(M_ERROR, "Invalid restore path specified, must start with /" PLUGIN_PATH_PREFIX_BASE "/" PLUGIN_PATH_PREFIX_SERVICE "/\n");
59                         return bRC_Error;
60                 }
61                 // convert name to a wide string
62
63                 _DebugMessage(100, "Calling HrESEBackupPrepare\n");
64                 result = HrESEBackupPrepare(context->computer_name, PLUGIN_PATH_PREFIX_SERVICE_W, &ibi_count, &ibi, &hccx);
65                 if (result != 0)
66                 {
67                         _JobMessage(M_ERROR, "HrESEBackupPrepare failed with error 0x%08x - %s\n", result, ESEErrorMessage(result));
68                         return bRC_Error;
69                 }
70                 state = 1;
71                 // fall through
72         case 1:
73                 if (context->path_bits[level + 1] == NULL)
74                 {
75                         _DebugMessage(100, "No specific storage group specified - backing them all up\n");
76                         char *tmp = new char[wcslen(ibi[current_ibi].wszInstanceName) + 1];
77                         wcstombs(tmp, ibi[current_ibi].wszInstanceName, wcslen(ibi[current_ibi].wszInstanceName) + 1);
78                         first_storage_group_node = new storage_group_node_t(tmp, this);
79                         delete tmp;
80                         _DebugMessage(100, "storage group name = %s\n", first_storage_group_node->name);
81                         first_storage_group_node->ibi = &ibi[current_ibi];
82                         first_storage_group_node->hccx = hccx;
83                         context->current_node = first_storage_group_node;
84                 }
85                 else
86                 {
87                         char *tmp = NULL;
88                         for (current_ibi = 0; current_ibi < ibi_count; current_ibi++)
89                         {
90                                 tmp = new char[wcslen(ibi[current_ibi].wszInstanceName) + 1];
91                                 wcstombs(tmp, ibi[current_ibi].wszInstanceName, wcslen(ibi[current_ibi].wszInstanceName) + 1);
92                                 if (stricmp(tmp, context->path_bits[level + 1]) == 0)
93                                         break;
94                         }
95                         first_storage_group_node = new storage_group_node_t(tmp, this);
96                         delete tmp;
97                         if (current_ibi == ibi_count)
98                         {
99                                 _JobMessage(M_ERROR, "Invalid Storage Group '%s'\n", context->path_bits[level + 1]);
100                                 return bRC_Error;
101                         }
102                         _DebugMessage(100, "storage group name = %s\n", first_storage_group_node->name);
103                         first_storage_group_node->ibi = &ibi[current_ibi];
104                         first_storage_group_node->hccx = hccx;
105                         context->current_node = first_storage_group_node;
106                 }
107                 break;
108         case 2:
109                 time_t now = time(NULL);
110                 sp->fname = full_path;
111                 sp->link = full_path;
112                 sp->statp.st_mode = 0700 | S_IFDIR;
113                 sp->statp.st_ctime = now;
114                 sp->statp.st_mtime = now;
115                 sp->statp.st_atime = now;
116                 sp->statp.st_size = 0;
117                 sp->statp.st_nlink = 1;
118                 //sp->statp.st_blocks = 0;
119                 sp->type = FT_DIREND;
120                 break;
121         }
122         _DebugMessage(100, "ending startBackupNode_SERVICE state = %d\n", state);
123         return bRC_OK;
124 }
125
126 bRC
127 service_node_t::endBackupFile(exchange_fd_context_t *context)
128 {
129         HRESULT result;
130         bRC retval = bRC_OK;
131
132         _DebugMessage(100, "endBackupNode_SERVICE state = %d\n", state);
133         switch(state)
134         {
135         case 0:
136                 // should never happen
137                 break;
138         case 1:
139                 // free node->storage_group_node
140                 if (context->path_bits[level + 1] == NULL)
141                 {
142                         current_ibi++;
143                         if (current_ibi == ibi_count)
144                                 state = 2;
145                 }
146                 else
147                         state = 2;
148                 retval = bRC_More;
149                 break;
150         case 2:
151                 _DebugMessage(100, "calling HrESEBackupEnd\n");
152                 result = HrESEBackupEnd(hccx);
153                 if (result != 0)
154                 {
155                         _JobMessage(M_ERROR, "HrESEBackupEnd failed with error 0x%08x - %s\n", result, ESEErrorMessage(result));
156                         return bRC_Error;
157                 }
158
159                 context->current_node = parent;
160                 retval = bRC_OK;
161                 break;
162         }
163         return retval;
164 }
165
166 bRC
167 service_node_t::createFile(exchange_fd_context_t *context, struct restore_pkt *rp)
168 {
169         storage_group_node_t *curr_sg, *prev_sg;
170
171         _DebugMessage(0, "createFile_SERVICE state = %d\n", state);
172         if (strcmp(name, "Microsoft Information Store") != 0)
173         {
174                 _JobMessage(M_ERROR, "Invalid restore path specified, must start with '/" PLUGIN_PATH_PREFIX_BASE "/" PLUGIN_PATH_PREFIX_SERVICE "/'\n", state);
175                 return bRC_Error;
176         }
177         for(;;)
178         {
179                 switch (state)
180                 {
181                 case 0:
182                         if (context->path_bits[level + 1] == NULL)
183                         {
184                                 state = 1;
185                                 break;
186                         }
187                         for (prev_sg = NULL, curr_sg = first_storage_group_node; curr_sg != NULL; prev_sg = curr_sg, curr_sg = curr_sg->next)
188                         {
189                                 if (strcmp(curr_sg->name, context->path_bits[level + 1]) == 0)
190                                 {
191                                         break;
192                                 }
193                         }
194                         if (curr_sg == NULL)
195                         {
196                                 curr_sg = new storage_group_node_t(bstrdup(context->path_bits[level + 1]), this);
197                                 if (prev_sg == NULL)
198                                         first_storage_group_node = curr_sg;
199                                 else
200                                         prev_sg->next = curr_sg;
201                         }
202                         context->current_node = curr_sg;
203                         return bRC_OK;
204                 case 1:
205                         rp->create_status = CF_CREATED;
206                         return bRC_OK;
207                 }
208         }
209         return bRC_Error;
210 }
211
212 bRC
213 service_node_t::endRestoreFile(exchange_fd_context_t *context)
214 {
215         _DebugMessage(0, "endRestoreFile_SERVICE state = %d\n", state);
216         switch(state)
217         {
218         case 0:
219                 return bRC_Error;
220         case 1:
221                 context->current_node = parent;
222                 return bRC_OK;
223         }
224
225         return bRC_Error;
226 }