ff_pkt->fname = fname.c_str();
ff_pkt->link = link.c_str();
ff_pkt->type = sp.type;
- ff_pkt->object = sp.object;
- ff_pkt->object_len = sp.object_len;
if (sp.type == FT_RESTORE_FIRST) {
ff_pkt->LinkFI = sp.index; /* restore object index */
+ ff_pkt->object = sp.object;
+ ff_pkt->object_len = sp.object_len;
}
memcpy(&ff_pkt->statp, &sp.statp, sizeof(ff_pkt->statp));
Dmsg2(dbglvl, "startBackup returned type=%d, fname=%s\n", sp.type, sp.fname);
if (sp.object) {
Dmsg2(dbglvl, "index=%d object=%s\n", sp.index, sp.object);
}
+ /* Call Bacula core code to backup the plugin's file */
save_file(jcr, ff_pkt, true);
bRC rc = plug_func(plugin)->endBackupFile(jcr->plugin_ctx);
if (rc == bRC_More || rc == bRC_OK) {
#include "../win32/filed/vss.h"
#endif
+/*
+ * This packet is used for the restore objects
+ * It is passed to the plugin when restoring
+ * the object.
+ */
+struct restore_object_pkt {
+ int32_t pkt_size; /* size of this packet */
+ char *fname; /* Full path and filename */
+ int32_t object_type; /* FT_xx for this file */
+ char *object; /* restore object data to save */
+ int32_t object_len; /* restore object length */
+ int32_t object_index; /* restore object index */
+ uint32_t JobId; /* JobId object came from */
+ int32_t pkt_end; /* end packet sentinel */
+};
+
/*
* This packet is used for file save info transfer.
*/
bEventVssBackupAddComponents = 14,
bEventVssRestoreLoadComponentMetadata = 15,
bEventVssRestoreSetComponentsSelected = 16,
+ bEventRestoreObject = 17,
} bEventType;
typedef struct s_bEvent {
{
BSOCK *dir = jcr->dir_bsock;
POOLMEM *msg = get_memory(dir->msglen+1);
- uint32_t JobId;
- int32_t object_len, object_index, object_type, FileIndex;
+ int32_t FileIndex;
+ restore_object_pkt rop;
+ memset(&rop, 0, sizeof(rop));
+ rop.pkt_size = sizeof(rop);
+ rop.pkt_end = sizeof(rop);
Dmsg1(100, "Enter restoreobject_cmd: %s", dir->msg);
if (strcmp(dir->msg, endrestoreobjectcmd) == 0) {
+ generate_plugin_event(jcr, bEventRestoreObject, NULL);
free_memory(msg);
return dir->fsend(OKRestoreObject);
}
- if (sscanf(dir->msg, restoreobjcmd, &JobId, &object_len, &object_index,
- &object_type, &FileIndex) != 5) {
+ if (sscanf(dir->msg, restoreobjcmd, &rop.JobId, &rop.object_len,
+ &rop.object_index, &rop.object_type, &FileIndex) != 5) {
Dmsg0(5, "Bad restore object command\n");
pm_strcpy(jcr->errmsg, dir->msg);
Jmsg1(jcr, M_FATAL, 0, _("Bad RestoreObject command: %s\n"), jcr->errmsg);
goto bail_out;
}
// Dmsg2(000, "Recv Fname object: len=%d Fname=%s\n", dir->msglen, dir->msg);
+ rop.fname = bstrdup(dir->msg);
/* Read Path */
if (dir->recv() < 0) {
if (dir->recv() < 0) {
goto bail_out;
}
+ rop.object = dir->msg;
// Dmsg2(000, "Recv Object: len=%d Object=%s\n", dir->msglen, dir->msg);
+ /* pass to plugin */
+ generate_plugin_event(jcr, bEventRestoreObject, (void *)&rop);
+
+ if (rop.fname) {
+ free(rop.fname);
+ }
+ if (!rop.object) {
+ dir->msg = get_pool_memory(PM_MESSAGE);
+ }
+
free_memory(msg);
Dmsg1(100, "Send: %s", OKRestoreObject);
return 1;
extern "C" {
#endif
-static const int dbglvl = 150;
+static const int dbglvl = 000;
#define PLUGIN_LICENSE "Bacula GPLv2"
#define PLUGIN_AUTHOR "Kern Sibbald"
static bRC handlePluginEvent(bpContext *ctx, bEvent *event, void *value)
{
struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext;
+ restore_object_pkt *rop;
if (!p_ctx) {
return bRC_Error;
}
case bEventStartBackupJob:
bfuncs->AddExclude(ctx, "/home/kern/bacula/regress/README");
break;
+ case bEventRestoreObject:
+ printf("Plugin RestoreObject\n");
+ if (!value) {
+ bfuncs->DebugMessage(ctx, fi, li, dbglvl, "test-plugin-fd: End restore objects\n");
+ break;
+ }
+ rop = (restore_object_pkt *)value;
+ bfuncs->DebugMessage(ctx, fi, li, dbglvl, "test-plugin-fd: len=%d JobId=%d fname=%s\n",
+ rop->object_len, rop->JobId, rop->fname);
+ break;
/* Plugin command e.g. plugin = <plugin-name>:<name-space>:read command:write command */
case bEventRestoreCommand:
/* Fall-through wanted */