]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/win32/filed/plugins/exch_dbi_node.c
Restore win32 dir from Branch-5.2 and update it
[bacula/bacula] / bacula / src / win32 / filed / plugins / exch_dbi_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  *  Used only in "old Exchange plugin" now deprecated.
23  */
24
25 #include "exchange-fd.h"
26
27 dbi_node_t::dbi_node_t(char *name, node_t *parent_node) : node_t(name, NODE_TYPE_DATABASE_INFO, parent_node)
28 {
29    restore_display_name = NULL;
30    restore_input_streams = NULL;
31    buffer = NULL;
32 }
33
34 dbi_node_t::~dbi_node_t()
35 {
36    safe_delete(buffer);
37    safe_delete(restore_input_streams);
38    safe_delete(restore_display_name);
39 }
40
41 bRC
42 dbi_node_t::startBackupFile(exchange_fd_context_t *context, struct save_pkt *sp)
43 {
44    time_t now = time(NULL);
45
46    _DebugMessage(100, "startBackupNode_DBI state = %d\n", state);
47
48    if (context->job_level == 'F') {
49       sp->fname = full_path;
50       sp->link = full_path;
51       sp->statp.st_mode = 0700 | S_IFREG;
52       sp->statp.st_ctime = now;
53       sp->statp.st_mtime = now;
54       sp->statp.st_atime = now;
55       sp->statp.st_size = (uint64_t)-1;
56       sp->type = FT_REG;
57       return bRC_OK;
58    }
59    else
60    {
61       bfuncs->setBaculaValue(context->bpContext, bVarFileSeen, (void *)full_path);
62       return bRC_Seen;
63    }
64 }
65
66 bRC
67 dbi_node_t::endBackupFile(exchange_fd_context_t *context)
68 {
69    _DebugMessage(100, "endBackupNode_DBI state = %d\n", state);
70
71    context->current_node = parent;
72
73    return bRC_OK;
74 }
75
76 bRC
77 dbi_node_t::createFile(exchange_fd_context_t *context, struct restore_pkt *rp)
78 {
79    _DebugMessage(0, "createFile_DBI state = %d\n", state);
80
81    rp->create_status = CF_EXTRACT;
82
83    return bRC_OK;
84 }
85
86 bRC
87 dbi_node_t::endRestoreFile(exchange_fd_context_t *context)
88 {
89    _DebugMessage(0, "endRestoreFile_DBI state = %d\n", state);
90
91    context->current_node = parent;
92
93    return bRC_OK;
94 }
95
96 bRC
97 dbi_node_t::pluginIoOpen(exchange_fd_context_t *context, struct io_pkt *io)
98 {
99    uint32_t len;
100    WCHAR *ptr;
101    WCHAR *stream;
102    //char tmp[512];
103
104    buffer_pos = 0;
105    buffer_size = 65536;
106    buffer = new char[buffer_size];
107
108    if (context->job_type == JOB_TYPE_BACKUP)
109    {
110       ptr = (WCHAR *)buffer;
111       len = snwprintf(ptr, (buffer_size - buffer_pos) / 2, L"DatabaseBackupInfo\n");
112       if (len < 0)
113          goto fail;
114       buffer_pos += len * 2;
115       ptr += len;
116
117       len = snwprintf(ptr, (buffer_size - buffer_pos) / 2, L"%d\n", EXCHANGE_PLUGIN_VERSION);
118       if (len < 0)
119          goto fail;
120       buffer_pos += len * 2;
121       ptr += len;
122
123       len = snwprintf(ptr, (buffer_size - buffer_pos) / 2, L"%s\n", dbi->wszDatabaseDisplayName);
124       if (len < 0)
125          goto fail;
126       buffer_pos += len * 2;
127       ptr += len;
128
129       len = snwprintf(ptr, (buffer_size - buffer_pos) / 2, L"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x\n",
130          dbi->rguidDatabase.Data1, dbi->rguidDatabase.Data2, dbi->rguidDatabase.Data3,
131          dbi->rguidDatabase.Data4[0], dbi->rguidDatabase.Data4[1],
132          dbi->rguidDatabase.Data4[2], dbi->rguidDatabase.Data4[3],
133          dbi->rguidDatabase.Data4[4], dbi->rguidDatabase.Data4[5],
134          dbi->rguidDatabase.Data4[6], dbi->rguidDatabase.Data4[7]);
135       if (len < 0)
136          goto fail;
137       buffer_pos += len * 2;
138       ptr += len;
139       
140       stream = dbi->wszDatabaseStreams;
141       while (*stream)
142       {
143          len = snwprintf(ptr, (buffer_size - buffer_pos) / 2, L"%s\n", stream);
144          if (len < 0)
145             goto fail;
146          buffer_pos += len * 2;
147          ptr += len;
148          stream += wcslen(stream) + 1;
149       }
150
151       buffer_size = buffer_pos;
152       buffer_pos = 0;
153    }
154
155    io->status = 0;
156    io->io_errno = 0;
157    return bRC_OK;
158
159 fail:
160    io->status = 0;
161    io->io_errno = 1;
162    return bRC_Error;
163 }
164
165 bRC
166 dbi_node_t::pluginIoRead(exchange_fd_context_t *context, struct io_pkt *io)
167 {
168    io->status = 0;
169    io->io_errno = 0;
170
171    io->status = MIN(io->count, (int)(buffer_size - buffer_pos));
172    if (io->status == 0)
173       return bRC_OK;
174    memcpy(io->buf, buffer + buffer_pos, io->status);
175    buffer_pos += io->status;
176
177    return bRC_OK;
178 }
179
180 bRC 
181 dbi_node_t::pluginIoWrite(exchange_fd_context_t *context, struct io_pkt *io)
182 {
183    memcpy(&buffer[buffer_pos], io->buf, io->count);
184    buffer_pos += io->count;
185    io->status = io->count;
186    io->io_errno = 0;
187    return bRC_OK;
188 }
189
190 bRC
191 dbi_node_t::pluginIoClose(exchange_fd_context_t *context, struct io_pkt *io)
192 {
193    WCHAR tmp[128];
194    WCHAR *ptr;
195    WCHAR eol;
196    int wchars_read;
197    int version;
198    int stream_buf_count;
199    WCHAR *streams_start;
200
201    if (context->job_type == JOB_TYPE_RESTORE)
202    {
203       // need to think about making this buffer overflow proof...
204       _DebugMessage(100, "analyzing DatabaseBackupInfo\n");
205       ptr = (WCHAR *)buffer;
206
207       if (swscanf(ptr, L"%127[^\n]%c%n", tmp, &eol, &wchars_read) != 2)
208          goto restore_fail;
209       ptr += wchars_read;
210       _DebugMessage(150, "Header = %S\n", tmp);
211       // verify that header == "DatabaseBackupInfo"
212
213       if (swscanf(ptr, L"%127[^\n]%c%n", tmp, &eol, &wchars_read) != 2)
214          goto restore_fail;
215       if (swscanf(tmp, L"%d%c", &version, &eol) != 1)
216       {
217          version = 0;
218          _DebugMessage(150, "Version = 0 (inferred)\n");
219       }
220       else
221       {
222          ptr += wchars_read;
223          _DebugMessage(150, "Version = %d\n", version);
224          if (swscanf(ptr, L"%127[^\n]%c%n", tmp, &eol, &wchars_read) != 2)
225             goto restore_fail;
226       }
227       restore_display_name = new WCHAR[wchars_read];
228       swscanf(ptr, L"%127[^\n]", restore_display_name);
229       _DebugMessage(150, "Database Display Name = %S\n", restore_display_name);
230       ptr += wchars_read;
231
232       if (swscanf(ptr, L"%127[^\n]%c%n", tmp, &eol, &wchars_read) != 2)
233          goto restore_fail;
234       
235       if (swscanf(ptr, L"%8x-%4x-%4x-%2x%2x-%2x%2x%2x%2x%2x%2x",
236          &restore_guid.Data1, &restore_guid.Data2, &restore_guid.Data3,
237          &restore_guid.Data4[0], &restore_guid.Data4[1],
238          &restore_guid.Data4[2], &restore_guid.Data4[3],
239          &restore_guid.Data4[4], &restore_guid.Data4[5],
240          &restore_guid.Data4[6], &restore_guid.Data4[7]) != 11)
241       {
242          goto restore_fail;
243       }
244          _DebugMessage(150, "GUID = %08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x\n",
245          restore_guid.Data1, restore_guid.Data2, restore_guid.Data3,
246          restore_guid.Data4[0], restore_guid.Data4[1],
247          restore_guid.Data4[2], restore_guid.Data4[3],
248          restore_guid.Data4[4], restore_guid.Data4[5],
249          restore_guid.Data4[6], restore_guid.Data4[7]);
250
251       ptr += wchars_read;
252
253       stream_buf_count = 1;
254       streams_start = ptr;
255       while (ptr < (WCHAR *)(buffer + buffer_pos) && swscanf(ptr, L"%127[^\n]%c%n", tmp, &eol, &wchars_read) == 2)
256       {
257          _DebugMessage(150, "File = %S\n", tmp);
258          ptr += wchars_read;
259          stream_buf_count += wchars_read;
260       }
261       restore_input_streams = new WCHAR[stream_buf_count];
262       ptr = streams_start;
263       stream_buf_count = 0;
264       while (ptr < (WCHAR *)(buffer + buffer_pos) && swscanf(ptr, L"%127[^\n]%c%n", tmp, &eol, &wchars_read) == 2)
265       {
266          snwprintf(&restore_input_streams[stream_buf_count], 65535, L"%s", tmp);
267          ptr += wchars_read;
268          stream_buf_count += wchars_read;
269       }
270       restore_input_streams[stream_buf_count] = 0;
271
272       _DebugMessage(100, "done analyzing DatabasePluginInfo\n");
273    }
274    safe_delete(buffer);
275    return bRC_OK;
276 restore_fail:
277    _JobMessage(M_FATAL, "Format of %s is incorrect", full_path);
278    safe_delete(buffer);
279    return bRC_Error;
280 }