]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/win32/filed/plugins/store_node.c
Integrate James Harper's Exchange Win32 plugin patch.
[bacula/bacula] / bacula / src / win32 / filed / plugins / store_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 store_node_t::store_node_t(char *name, node_t *parent_node) : node_t(name, NODE_TYPE_STORE, parent_node)
35 {
36         dbi = NULL;
37         hccx = NULL;
38         dbi_node = NULL;
39         file_node = NULL;
40 }
41
42 store_node_t::~store_node_t()
43 {
44         if (dbi_node != NULL)
45                 delete dbi_node;
46
47         if (file_node != NULL)
48                 delete file_node;
49 }
50
51 bRC
52 store_node_t::startBackupFile(exchange_fd_context_t *context, struct save_pkt *sp)
53 {
54         char *tmp;
55
56         _DebugMessage(100, "startBackupNode_STORE state = %d\n", state);
57
58         switch(state)
59         {
60         case 0:
61                 stream_ptr = dbi->wszDatabaseStreams;
62                 state = 1;
63                 // fall through
64         case 1:
65                 dbi_node = new dbi_node_t("DatabaseBackupInfo", this);
66                 dbi_node->dbi = dbi;
67                 context->current_node = dbi_node;
68                 break;
69         case 2:
70                 tmp = new char[wcslen(stream_ptr) + 1];
71                 wcstombs(tmp, stream_ptr, wcslen(stream_ptr) + 1);
72                 file_node = new file_node_t(tmp, this);
73                 file_node->hccx = hccx;
74                 file_node->filename = stream_ptr;
75                 context->current_node = file_node;
76                 break;
77         case 3:
78                 time_t now = time(NULL);
79                 sp->fname = full_path;
80                 sp->link = full_path;
81                 sp->statp.st_mode = 0700 | S_IFDIR;
82                 sp->statp.st_ctime = now;
83                 sp->statp.st_mtime = now;
84                 sp->statp.st_atime = now;
85                 sp->statp.st_size = 0;
86                 sp->type = FT_DIREND;
87                 break;
88         }
89
90         return bRC_OK;
91 }
92
93 bRC
94 store_node_t::endBackupFile(exchange_fd_context_t *context)
95 {
96         _DebugMessage(100, "endBackupNode_STORE state = %d\n", state);
97         bRC retval = bRC_OK;
98
99         switch(state)
100         {
101         case 0:
102                 // should never happen
103                 break;
104         case 1:
105                 state = 2;
106                 retval = bRC_More;
107                 break;
108         case 2:
109                 delete file_node;
110                 stream_ptr += wcslen(stream_ptr) + 1;
111                 if (*stream_ptr == 0)
112                         state = 3;
113                 retval = bRC_More;
114                 break;
115         case 3:
116                 //delete dbi_node;
117                 context->current_node = parent;
118                 break;
119         }
120         return retval;
121 }
122
123 bRC
124 store_node_t::createFile(exchange_fd_context_t *context, struct restore_pkt *rp)
125 {
126         _DebugMessage(0, "createFile_STORE state = %d\n", state);
127
128         if (strcmp(context->path_bits[level - 1], parent->name) != 0)
129         {
130                 _DebugMessage(0, "Different storage group - switching back to parent\n", state);
131                 context->current_node = parent;
132                 return bRC_OK;
133         }
134         for (;;)
135         {
136                 switch (state)
137                 {
138                 case 0:
139                         if (strcmp("DatabaseBackupInfo", context->path_bits[level + 1]) != 0)
140                         {
141                                 _JobMessage(M_ERROR, "DatabaseBackupInfo file must exist and must be first in directory\n");
142                                 state = 999;
143                                 break;
144                         }
145                         dbi_node = new dbi_node_t(bstrdup(context->path_bits[level + 1]), this);
146                         context->current_node = dbi_node;
147                         return bRC_OK;
148                 case 1:
149                         if (strcmp(context->path_bits[level - 1], parent->name) != 0)
150                         {
151                                 _JobMessage(M_ERROR, "Unexpected Storage Group Change\n");
152                                 state = 999;
153                                 break;
154                         }
155
156                         if (*stream_ptr != 0)
157                         {
158                                 // verify that stream_ptr == context->path_bits[level + 1];
159                                 _DebugMessage(150, "stream_ptr = %S\n", stream_ptr);
160                                 _DebugMessage(150, "out_stream_ptr = %S\n", out_stream_ptr);
161                                 file_node = new file_node_t(bstrdup(context->path_bits[level + 1]), this);
162                                 file_node->hccx = hccx;
163                                 file_node->filename = out_stream_ptr;
164                                 context->current_node = file_node;
165                                 return bRC_OK;
166                         }
167                         else
168                         {
169                                 _JobMessage(M_ERROR, "Extra file found '%s'\n", full_path);
170                                 state = 999;
171                                 break;
172                         }
173                 case 2:
174                         if (rp->type != FT_DIREND)
175                         {
176                                 _JobMessage(M_ERROR, "Unexpected file '%s'\n", full_path);
177                                 state = 999;
178                                 break;
179                         }
180                         rp->create_status = CF_CREATED;
181                         return bRC_OK;
182                 case 999:
183                         if (strcmp(context->path_bits[level], name) != 0)
184                         {
185                                 _DebugMessage(0, "End of Store when in error state - switching back to parent\n", state);
186                                 context->current_node = parent;
187                                 return bRC_OK;
188                         }
189                         rp->create_status = CF_CREATED;
190                         return bRC_OK;
191                 }
192         }
193 }
194
195 bRC
196 store_node_t::endRestoreFile(exchange_fd_context_t *context)
197 {
198         HRESULT result;
199
200         _DebugMessage(0, "endRestoreFile_STORE state = %d\n", state);
201         for (;;)
202         {
203                 switch (state)
204                 {
205                 case 0:
206                         state = 1;
207                         _DebugMessage(0, "Calling HrESERestoreAddDatabase\n");
208                         result = HrESERestoreAddDatabase(hccx, dbi_node->restore_display_name, dbi_node->restore_guid, dbi_node->restore_input_streams, &dbi_node->restore_output_streams);
209                         if (result != 0)
210                         {
211                                 _JobMessage(M_ERROR, "HrESERestoreAddDatabase failed with error 0x%08x - %s\n", result, ESEErrorMessage(result));
212                                 state = 999;
213                                 break;
214                         }
215                         stream_ptr = dbi_node->restore_input_streams;
216                         out_stream_ptr = dbi_node->restore_output_streams;
217                         return bRC_OK;
218                 case 1:
219                         if (*stream_ptr != 0)
220                         {
221                                 delete file_node;
222                                 file_node = NULL;
223                                 stream_ptr += wcslen(stream_ptr) + 1;
224                                 out_stream_ptr += wcslen(out_stream_ptr) + 1;
225                                 if (*stream_ptr == 0)
226                                         state = 2;
227                                 return bRC_OK;
228                         }
229                         else
230                         {
231                                 state = 999;
232                                 break;
233                         }
234                 case 2:
235                         context->current_node = parent;
236                         return bRC_OK;
237                 case 999:
238                         return bRC_OK;
239                 }
240         }
241 }