1 /*
2 BAREOS® - Backup Archiving REcovery Open Sourced
3
4 Copyright (C) 2007-2012 Free Software Foundation Europe e.V.
5 Copyright (C) 2016-2016 Bareos GmbH & Co. KG
6
7 This program is Free Software; you can redistribute it and/or
8 modify it under the terms of version three of the GNU Affero General Public
9 License as published by the Free Software Foundation, which is
10 listed in the file LICENSE.
11
12 This program is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Affero General Public License for more details.
16
17 You should have received a copy of the GNU Affero General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 02110-1301, USA.
21 */
22 /*
23 * Kern Sibbald, October 2007
24 */
25 /**
26 * @file
27 * A simple test plugin for the Bareos File Daemon derived from
28 * the bpipe plugin, but used for testing new features.
29 */
30 #include "include/bareos.h"
31 #include "filed/fd_plugins.h"
32 #include "fd_common.h"
33 #include "lib/ini.h"
34 #include <wchar.h>
35
36 namespace filedaemon {
37
38 static const int debuglevel = 000;
39
40 #define PLUGIN_LICENSE "Bareos AGPLv3"
41 #define PLUGIN_AUTHOR "Kern Sibbald"
42 #define PLUGIN_DATE "May 2011"
43 #define PLUGIN_VERSION "3"
44 #define PLUGIN_DESCRIPTION "Bareos Test File Daemon Plugin"
45
46 /* Forward referenced functions */
47 static bRC newPlugin(bpContext *ctx);
48 static bRC freePlugin(bpContext *ctx);
49 static bRC getPluginValue(bpContext *ctx, pVariable var, void *value);
50 static bRC setPluginValue(bpContext *ctx, pVariable var, void *value);
51 static bRC handlePluginEvent(bpContext *ctx, bEvent *event, void *value);
52 static bRC startBackupFile(bpContext *ctx, struct save_pkt *sp);
53 static bRC endBackupFile(bpContext *ctx);
54 static bRC pluginIO(bpContext *ctx, struct io_pkt *io);
55 static bRC startRestoreFile(bpContext *ctx, const char *cmd);
56 static bRC endRestoreFile(bpContext *ctx);
57 static bRC createFile(bpContext *ctx, struct restore_pkt *rp);
58 static bRC setFileAttributes(bpContext *ctx, struct restore_pkt *rp);
59 static bRC checkFile(bpContext *ctx, char *fname);
60 static bRC getAcl(bpContext *ctx, acl_pkt *ap);
61 static bRC setAcl(bpContext *ctx, acl_pkt *ap);
62 static bRC getXattr(bpContext *ctx, xattr_pkt *xp);
63 static bRC setXattr(bpContext *ctx, xattr_pkt *xp);
64
65 /* Pointers to Bareos functions */
66 static bFuncs *bfuncs = NULL;
67 static bInfo *binfo = NULL;
68
69 /* Plugin Information block */
70 static genpInfo pluginInfo = {
71 sizeof(pluginInfo),
72 FD_PLUGIN_INTERFACE_VERSION,
73 FD_PLUGIN_MAGIC,
74 PLUGIN_LICENSE,
75 PLUGIN_AUTHOR,
76 PLUGIN_DATE,
77 PLUGIN_VERSION,
78 PLUGIN_DESCRIPTION
79 };
80
81 /* Plugin entry points for Bareos */
82 static pFuncs pluginFuncs = {
83 sizeof(pluginFuncs),
84 FD_PLUGIN_INTERFACE_VERSION,
85
86 /* Entry points into plugin */
87 newPlugin, /* new plugin instance */
88 freePlugin, /* free plugin instance */
89 getPluginValue,
90 setPluginValue,
91 handlePluginEvent,
92 startBackupFile,
93 endBackupFile,
94 startRestoreFile,
95 endRestoreFile,
96 pluginIO,
97 createFile,
98 setFileAttributes,
99 checkFile,
100 getAcl,
101 setAcl,
102 getXattr,
103 setXattr
104 };
105
106 static struct ini_items test_items[] = {
107 // name type comment required
108 { "string1", INI_CFG_TYPE_STR, "Special String", 1 },
109 { "string2", INI_CFG_TYPE_STR, "2nd String", 0 },
110 { "ok", INI_CFG_TYPE_BOOL, "boolean", 0 },
111 // We can also use the ITEMS_DEFAULT
112 // { "ok", INI_CFG_TYPE_BOOL, "boolean", 0, ITEMS_DEFAULT },
113 { NULL, 0, NULL, 0 }
114 };
115
116 /**
117 * Plugin private context
118 */
119 struct plugin_ctx {
120 boffset_t offset;
121 FILE *fd; /* pipe file descriptor */
122 char *cmd; /* plugin command line */
123 char *fname; /* filename to "backup/restore" */
124 char *reader; /* reader program for backup */
125 char *writer; /* writer program for backup */
126
127 char where[512];
128 int replace;
129
130 int nb_obj; /* Number of objects created */
131 POOLMEM *buf; /* store ConfigFile */
132 };
133
134 #ifdef __cplusplus
135 extern "C" {
136 #endif
137
138 /**
139 * loadPlugin() and unloadPlugin() are entry points that are
140 * exported, so Bareos can directly call these two entry points
141 * they are common to all Bareos plugins.
142 */
143 /**
144 * External entry point called by Bareos to "load" the plugin
145 */
loadPlugin(bInfo * lbinfo,bFuncs * lbfuncs,genpInfo ** pinfo,pFuncs ** pfuncs)146 bRC loadPlugin(bInfo *lbinfo,
147 bFuncs *lbfuncs,
148 genpInfo **pinfo,
149 pFuncs **pfuncs)
150 {
151 bfuncs = lbfuncs; /* set Bareos funct pointers */
152 binfo = lbinfo;
153 *pinfo = &pluginInfo; /* return pointer to our info */
154 *pfuncs = &pluginFuncs; /* return pointer to our functions */
155
156 return bRC_OK;
157 }
158
159 /**
160 * External entry point to unload the plugin
161 */
unloadPlugin()162 bRC unloadPlugin()
163 {
164 return bRC_OK;
165 }
166
167 #ifdef __cplusplus
168 }
169 #endif
170
171 /**
172 * The following entry points are accessed through the function
173 * pointers we supplied to Bareos. Each plugin type (dir, fd, sd)
174 * has its own set of entry points that the plugin must define.
175 */
176 /**
177 * Create a new instance of the plugin i.e. allocate our private storage
178 */
newPlugin(bpContext * ctx)179 static bRC newPlugin(bpContext *ctx)
180 {
181 struct plugin_ctx *p_ctx = (struct plugin_ctx *)malloc(sizeof(struct plugin_ctx));
182 if (!p_ctx) {
183 return bRC_Error;
184 }
185 p_ctx = (plugin_ctx*)memset(p_ctx, 0, sizeof(struct plugin_ctx));
186 ctx->pContext = (void *)p_ctx; /* set our context pointer */
187
188 bfuncs->registerBareosEvents(ctx,
189 5,
190 bEventJobStart,
191 bEventEndFileSet,
192 bEventRestoreObject,
193 bEventEstimateCommand,
194 bEventBackupCommand);
195
196 return bRC_OK;
197 }
198
199 /**
200 * Free a plugin instance, i.e. release our private storage
201 */
freePlugin(bpContext * ctx)202 static bRC freePlugin(bpContext *ctx)
203 {
204 struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext;
205 if (!p_ctx) {
206 return bRC_Error;
207 }
208 if (p_ctx->buf) {
209 FreePoolMemory(p_ctx->buf);
210 }
211 if (p_ctx->cmd) {
212 free(p_ctx->cmd); /* free any allocated command string */
213 }
214 free(p_ctx); /* free our private context */
215 ctx->pContext = NULL;
216 return bRC_OK;
217 }
218
219 /**
220 * Return some plugin value (none defined)
221 */
getPluginValue(bpContext * ctx,pVariable var,void * value)222 static bRC getPluginValue(bpContext *ctx, pVariable var, void *value)
223 {
224 return bRC_OK;
225 }
226
227 /**
228 * Set a plugin value (none defined)
229 */
setPluginValue(bpContext * ctx,pVariable var,void * value)230 static bRC setPluginValue(bpContext *ctx, pVariable var, void *value)
231 {
232 return bRC_OK;
233 }
234
235 /**
236 * Handle an event that was generated in Bareos
237 */
handlePluginEvent(bpContext * ctx,bEvent * event,void * value)238 static bRC handlePluginEvent(bpContext *ctx, bEvent *event, void *value)
239 {
240 struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext;
241 restore_object_pkt *rop;
242 if (!p_ctx) {
243 return bRC_Error;
244 }
245
246 // char *name;
247
248 switch (event->eventType) {
249 case bEventJobStart:
250 Dmsg(ctx, debuglevel, "test-plugin-fd: JobStart=%s\n", (char *)value);
251 break;
252 case bEventEndFileSet:
253 /*
254 * End of Dir FileSet commands, now we can add excludes
255 */
256 bfuncs->NewOptions(ctx);
257 bfuncs->AddWild(ctx, "*.c", ' ');
258 bfuncs->AddWild(ctx, "*.cpp", ' ');
259 bfuncs->AddOptions(ctx, "ei"); /* exclude, ignore case */
260 bfuncs->AddExclude(ctx, "/home/user/bareos/regress/README");
261 break;
262 case bEventRestoreObject: {
263 FILE *fp;
264 POOLMEM *q;
265 char *working;
266 static int _nb = 0;
267
268 printf("Plugin RestoreObject\n");
269 if (!value) {
270 Dmsg(ctx, debuglevel, "test-plugin-fd: End restore objects\n");
271 break;
272 }
273 rop = (restore_object_pkt *)value;
274 Dmsg(ctx, debuglevel, "Get RestoreObject len=%d JobId=%d oname=%s type=%d data=%.127s\n",
275 rop->object_len, rop->JobId, rop->object_name, rop->object_type, rop->object);
276 q = GetPoolMemory(PM_FNAME);
277
278 bfuncs->getBareosValue(ctx, bVarWorkingDir, &working);
279 Mmsg(q, "%s/restore.%d", working, _nb++);
280 if ((fp = fopen(q, "w")) != NULL) {
281 fwrite(rop->object, rop->object_len, 1, fp);
282 fclose(fp);
283 }
284
285 FreePoolMemory(q);
286
287 if (!strcmp(rop->object_name, INI_RESTORE_OBJECT_NAME)) {
288 ConfigFile ini;
289 if (!ini.DumpString(rop->object, rop->object_len)) {
290 break;
291 }
292 ini.RegisterItems(test_items, sizeof(struct ini_items));
293 if (ini.parse(ini.out_fname)) {
294 Jmsg(ctx, M_INFO, "string1 = %s\n", ini.items[0].val.strval);
295 } else {
296 Jmsg(ctx, M_ERROR, "Can't parse config\n");
297 }
298 }
299
300 break;
301 }
302 case bEventEstimateCommand:
303 /* Fall-through wanted */
304 case bEventBackupCommand: {
305 /*
306 * Plugin command e.g. plugin = <plugin-name>:<name-space>:read command:write command
307 */
308 char *p;
309
310 Dmsg(ctx, debuglevel, "test-plugin-fd: pluginEvent cmd=%s\n", (char *)value);
311 p_ctx->cmd = bstrdup((char *)value);
312 p = strchr(p_ctx->cmd, ':');
313 if (!p) {
314 Jmsg(ctx, M_FATAL, "Plugin terminator not found: %s\n", (char *)value);
315 Dmsg(ctx, debuglevel, "Plugin terminator not found: %s\n", (char *)value);
316 return bRC_Error;
317 }
318 *p++ = 0; /* Terminate plugin */
319 p_ctx->fname = p;
320 p = strchr(p, ':');
321 if (!p) {
322 Jmsg(ctx, M_FATAL, "File terminator not found: %s\n", (char *)value);
323 Dmsg(ctx, debuglevel, "File terminator not found: %s\n", (char *)value);
324 return bRC_Error;
325 }
326 *p++ = 0; /* Terminate file */
327 p_ctx->reader = p;
328 p = strchr(p, ':');
329 if (!p) {
330 Jmsg(ctx, M_FATAL, "Reader terminator not found: %s\n", (char *)value);
331 Dmsg(ctx, debuglevel, "Reader terminator not found: %s\n", (char *)value);
332 return bRC_Error;
333 }
334 *p++ = 0; /* Terminate reader string */
335 p_ctx->writer = p;
336 Dmsg(ctx, debuglevel, "test-plugin-fd: plugin=%s fname=%s reader=%s writer=%s\n",
337 p_ctx->cmd, p_ctx->fname, p_ctx->reader, p_ctx->writer);
338 break;
339 }
340 default:
341 Dmsg(ctx, debuglevel, "test-plugin-fd: unknown event=%d\n", event->eventType);
342 break;
343 }
344
345 return bRC_OK;
346 }
347
348 /**
349 * Start the backup of a specific file
350 */
startBackupFile(bpContext * ctx,struct save_pkt * sp)351 static bRC startBackupFile(bpContext *ctx, struct save_pkt *sp)
352 {
353 struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext;
354 if (!p_ctx) {
355 return bRC_Error;
356 }
357
358 if (p_ctx->nb_obj == 0) {
359 sp->fname = (char *)"takeme.h";
360 Dmsg(ctx, debuglevel, "AcceptFile=%s = %d\n",
361 sp->fname, bfuncs->AcceptFile(ctx, sp));
362
363 sp->fname = (char *)"/path/to/excludeme.o";
364 Dmsg(ctx, debuglevel, "AcceptFile=%s = %d\n",
365 sp->fname, bfuncs->AcceptFile(ctx, sp));
366
367 sp->fname = (char *)"/path/to/excludeme.c";
368 Dmsg(ctx, debuglevel, "AcceptFile=%s = %d\n",
369 sp->fname, bfuncs->AcceptFile(ctx, sp));
370 }
371
372 if (p_ctx->nb_obj == 0) {
373 sp->object_name = (char *)"james.xml";
374 sp->object = (char *)"This is test data for the restore object. "
375 "garbage=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
376 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
377 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
378 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
379 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
380 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
381 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
382 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
383 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
384 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
385 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
386 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
387 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
388 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
389 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
390 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
391 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
392 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
393 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
394 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
395 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
396 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
397 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
398 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
399 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
400 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
401 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
402 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
403 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
404 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
405 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
406 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
407 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
408 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
409 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
410 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
411 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
412 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
413 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
414 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
415 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
416 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
417 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
418 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
419 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
420 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
421 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
422 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
423 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
424 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
425 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
426 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
427 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
428 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
429 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
430 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
431 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
432 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
433 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
434 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
435 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
436 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
437 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
438 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
439 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
440 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
441 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
442 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
443 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
444 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
445 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
446 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
447 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
448 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
449 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
450 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
451 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
452 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
453 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
454 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
455 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
456 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
457 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
458 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
459 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
460 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
461 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
462 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
463 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
464 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
465 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
466 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
467 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
468 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
469 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
470 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
471 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
472 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
473 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
474 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
475 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
476 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
477 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
478 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
479 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
480 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
481 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
482 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
483 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
484 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
485 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
486 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
487 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
488 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
489 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
490 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
491 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
492 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
493 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
494 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
495 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
496 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
497 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
498 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
499 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
500 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
501 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
502 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
503 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
504 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
505 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
506 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
507 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
508 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
509 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
510 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
511 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
512 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
513 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
514 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
515 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
516 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
517 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
518 "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
519 "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
520 "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
521 "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
522 "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
523 "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
524 "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
525 "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
526 "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
527 "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
528 "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
529 "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
530 "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
531 "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
532 "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
533 "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
534 "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
535 "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
536 "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
537 "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
538 "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
539 "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
540 "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
541 "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
542 "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
543 "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
544 "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
545 "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
546 "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
547 "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
548 "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
549 "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
550 "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
551 "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
552 "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
553 "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
554 "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
555 "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
556 "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
557 "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
558 "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
559 "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
560 "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
561 "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
562 "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
563 "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
564 "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
565 "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
566 "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
567 "\0secret";
568 sp->object_len = strlen(sp->object)+1+6+1; /* str + 0 + secret + 0 */
569 sp->type = FT_RESTORE_FIRST;
570
571 static int _nb=0;
572 POOLMEM *q = GetPoolMemory(PM_FNAME);
573 char *working;
574 FILE *fp;
575
576 bfuncs->getBareosValue(ctx, bVarWorkingDir, &working);
577 Mmsg(q, "%s/torestore.%d", working, _nb++);
578 if ((fp = fopen(q, "w")) != NULL) {
579 fwrite(sp->object, sp->object_len, 1, fp);
580 fclose(fp);
581 }
582 FreePoolMemory(q);
583
584 } else if (p_ctx->nb_obj == 1) {
585 ConfigFile ini;
586
587 p_ctx->buf = GetPoolMemory(PM_BSOCK);
588 Dmsg(ctx, debuglevel, "p_ctx->buf = 0x%x\n", p_ctx->buf);
589 ini.RegisterItems(test_items, sizeof(struct ini_items));
590
591 sp->object_name = (char*)INI_RESTORE_OBJECT_NAME;
592 sp->object_len = ini.Serialize(p_ctx->buf);
593 sp->object = p_ctx->buf;
594 sp->type = FT_PLUGIN_CONFIG;
595
596 Dmsg(ctx, debuglevel, "RestoreOptions=<%s>\n", p_ctx->buf);
597 }
598
599 time_t now = time(NULL);
600 sp->index = ++p_ctx->nb_obj;
601 sp->statp.st_mode = 0700 | S_IFREG;
602 sp->statp.st_ctime = now;
603 sp->statp.st_mtime = now;
604 sp->statp.st_atime = now;
605 sp->statp.st_size = sp->object_len;
606 sp->statp.st_blksize = 4096;
607 sp->statp.st_blocks = 1;
608 Dmsg(ctx, debuglevel, "Creating RestoreObject len=%d oname=%s data=%.127s\n",
609 sp->object_len, sp->object_name, sp->object);
610 Dmsg(ctx, debuglevel,"test-plugin-fd: startBackupFile\n");
611 return bRC_OK;
612 }
613
getAcl(bpContext * ctx,acl_pkt * ap)614 static bRC getAcl(bpContext *ctx, acl_pkt *ap)
615 {
616 return bRC_OK;
617 }
618
setAcl(bpContext * ctx,acl_pkt * ap)619 static bRC setAcl(bpContext *ctx, acl_pkt *ap)
620 {
621 return bRC_OK;
622 }
623
getXattr(bpContext * ctx,xattr_pkt * xp)624 static bRC getXattr(bpContext *ctx, xattr_pkt *xp)
625 {
626 return bRC_OK;
627 }
628
setXattr(bpContext * ctx,xattr_pkt * xp)629 static bRC setXattr(bpContext *ctx, xattr_pkt *xp)
630 {
631 return bRC_OK;
632 }
633
634 /**
635 * Done with backup of this file
636 */
endBackupFile(bpContext * ctx)637 static bRC endBackupFile(bpContext *ctx)
638 {
639 /*
640 * We would return bRC_More if we wanted startBackupFile to be
641 * called again to backup another file
642 */
643 return bRC_OK;
644 }
645
646
647 /**
648 * Bareos is calling us to do the actual I/O
649 */
pluginIO(bpContext * ctx,struct io_pkt * io)650 static bRC pluginIO(bpContext *ctx, struct io_pkt *io)
651 {
652 struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext;
653 if (!p_ctx) {
654 return bRC_Error;
655 }
656
657 io->status = 0;
658 io->io_errno = 0;
659 return bRC_OK;
660 }
661
662 /**
663 * Bareos is notifying us that a plugin name string was found, and
664 * passing us the plugin command, so we can prepare for a restore.
665 */
startRestoreFile(bpContext * ctx,const char * cmd)666 static bRC startRestoreFile(bpContext *ctx, const char *cmd)
667 {
668 printf("test-plugin-fd: startRestoreFile cmd=%s\n", cmd);
669 return bRC_OK;
670 }
671
672 /**
673 * Bareos is notifying us that the plugin data has terminated, so
674 * the restore for this particular file is done.
675 */
endRestoreFile(bpContext * ctx)676 static bRC endRestoreFile(bpContext *ctx)
677 {
678 printf("test-plugin-fd: endRestoreFile\n");
679 return bRC_OK;
680 }
681
682 /**
683 * This is called during restore to create the file (if necessary)
684 * We must return in rp->create_status:
685 *
686 * CF_ERROR -- error
687 * CF_SKIP -- skip processing this file
688 * CF_EXTRACT -- extract the file (i.e.call i/o routines)
689 * CF_CREATED -- created, but no content to extract (typically directories)
690 *
691 */
createFile(bpContext * ctx,struct restore_pkt * rp)692 static bRC createFile(bpContext *ctx, struct restore_pkt *rp)
693 {
694 printf("test-plugin-fd: createFile\n");
695 if (strlen(rp->where) > 512) {
696 printf("Restore target dir too long. Restricting to first 512 bytes.\n");
697 }
698 bstrncpy(((struct plugin_ctx *)ctx->pContext)->where, rp->where, 513);
699 ((struct plugin_ctx *)ctx->pContext)->replace = rp->replace;
700 rp->create_status = CF_EXTRACT;
701 return bRC_OK;
702 }
703
setFileAttributes(bpContext * ctx,struct restore_pkt * rp)704 static bRC setFileAttributes(bpContext *ctx, struct restore_pkt *rp)
705 {
706 printf("test-plugin-fd: setFileAttributes\n");
707 return bRC_OK;
708 }
709
710 /* When using Incremental dump, all previous dumps are necessary */
checkFile(bpContext * ctx,char * fname)711 static bRC checkFile(bpContext *ctx, char *fname)
712 {
713 return bRC_OK;
714 }
715 } /* namespace filedaemon */
716