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