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