]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/plugins/fd/bpipe-fd.c
Plugin updates
[bacula/bacula] / bacula / src / plugins / fd / bpipe-fd.c
index f29eb72b2af712485b88328bbfe988d3412f76af..c6c841cc763cf05556ca60237672e1ebd16bc2ae 100644 (file)
    Switzerland, email:ftf@fsfeurope.org.
 */
 /*
- * Sample Plugin program
+ * A simple pipe plugin for Bacula
  *
  *  Kern Sibbald, October 2007
  *
  */
-#include <stdio.h>
 #include "fd-plugins.h"
 
 #undef malloc
 #undef free
+#undef strdup
 
 #ifdef __cplusplus
 extern "C" {
@@ -87,14 +87,20 @@ static pFuncs pluginFuncs = {
 };
 
 struct plugin_ctx {
-   int record;
+   boffset_t offset;
+   FILE *fd;
+   bool backup;
+   char *cmd;
+   char *fname;
+   char *reader;
+   char *writer;
 };
 
 bRC loadPlugin(bInfo *lbinfo, bFuncs *lbfuncs, pInfo **pinfo, pFuncs **pfuncs)
 {
    bfuncs = lbfuncs;                  /* set Bacula funct pointers */
    binfo  = lbinfo;
-   printf("bpipe-fd: Loaded: size=%d version=%d\n", bfuncs->size, bfuncs->version);
+// printf("bpipe-fd: Loaded: size=%d version=%d\n", bfuncs->size, bfuncs->version);
 
    *pinfo  = &pluginInfo;             /* return pointer to our info */
    *pfuncs = &pluginFuncs;            /* return pointer to our functions */
@@ -104,15 +110,14 @@ bRC loadPlugin(bInfo *lbinfo, bFuncs *lbfuncs, pInfo **pinfo, pFuncs **pfuncs)
 
 bRC unloadPlugin() 
 {
-   printf("bpipe-fd: Unloaded\n");
+// printf("bpipe-fd: Unloaded\n");
    return bRC_OK;
 }
 
 static bRC newPlugin(bpContext *ctx)
 {
    struct plugin_ctx *p_ctx = (struct plugin_ctx *)malloc(sizeof(struct plugin_ctx));
-
-   p_ctx->record = -1;
+   memset(p_ctx, 0, sizeof(struct plugin_ctx));
    ctx->pContext = (void *)p_ctx;        /* set our context pointer */
    return bRC_OK;
 }
@@ -120,6 +125,9 @@ static bRC newPlugin(bpContext *ctx)
 static bRC freePlugin(bpContext *ctx)
 {
    struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext;
+   if (p_ctx->cmd) {
+      free(p_ctx->cmd);
+   }
    free(p_ctx);
    return bRC_OK;
 }
@@ -136,31 +144,64 @@ static bRC setPluginValue(bpContext *ctx, pVariable var, void *value)
 
 static bRC handlePluginEvent(bpContext *ctx, bEvent *event, void *value)
 {
+   struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext;
    char *name;
 
    switch (event->eventType) {
    case bEventJobStart:
-      printf("bpipe-fd: JobStart=%s\n", (char *)value);
+//    printf("bpipe-fd: JobStart=%s\n", (char *)value);
       break;
    case bEventJobEnd:
-      printf("bpipe-fd: JobEnd\n");
+//    printf("bpipe-fd: JobEnd\n");
       break;
    case bEventBackupStart:
-      printf("bpipe-fd: BackupStart\n");
+//    printf("bpipe-fd: BackupStart\n");
       break;
    case bEventBackupEnd:
-      printf("bpipe-fd: BackupEnd\n");
+//    printf("bpipe-fd: BackupEnd\n");
       break;
    case bEventLevel:
-      printf("bpipe-fd: JobLevel=%c %d\n", (int)value, (int)value);
+//    printf("bpipe-fd: JobLevel=%c %d\n", (int)value, (int)value);
       break;
    case bEventSince:
-      printf("bpipe-fd: since=%d\n", (int)value);
+//    printf("bpipe-fd: since=%d\n", (int)value);
+      break;
+
+   case bEventRestoreStart: 
+//    printf("bpipe-fd: RestoreStart\n");
+      break;
+   case bEventRestoreEnd:
+//    printf("bpipe-fd: RestoreEnd\n");
       break;
 
    /* Plugin command e.g. plugin = <plugin-name>:<name-space>:command */
    case bEventPluginCommand:
-      printf("bpipe-fd: command=%s\n", (char *)value);
+      char *p;
+//    printf("bpipe-fd: pluginEvent cmd=%s\n", (char *)value);
+      p_ctx->cmd = strdup((char *)value);
+      p = strchr(p_ctx->cmd, ':');
+      if (!p) {
+         printf("Plugin terminator not found: %s\n", (char *)value);
+         return bRC_Error;
+      }
+      *p++ = 0;           /* terminate plugin */
+      p_ctx->fname = p;
+      p = strchr(p, ':');
+      if (!p) {
+         printf("File terminator not found: %s\n", (char *)value);
+         return bRC_Error;
+      }
+      *p++ = 0;           /* terminate file */
+      p_ctx->reader = p;
+      p = strchr(p, ':');
+      if (!p) {
+         printf("Reader terminator not found: %s\n", (char *)value);
+         return bRC_Error;
+      }
+      *p++ = 0;           /* terminate reader string */
+      p_ctx->writer = p;
+      printf("bpipe-fd: plugin=%s fname=%s reader=%s writer=%s\n", 
+         p_ctx->cmd, p_ctx->fname, p_ctx->reader, p_ctx->writer);
       break;
 
    default:
@@ -175,17 +216,18 @@ static bRC handlePluginEvent(bpContext *ctx, bEvent *event, void *value)
 
 static bRC startPluginBackup(bpContext *ctx, struct save_pkt *sp)
 {
-   static char *fname = (char *)"/BPIPE/test.txt";
+   struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext;
    time_t now = time(NULL);
-   sp->fname = fname;
-   sp->statp.st_mode = 0700;
+   sp->fname = p_ctx->fname;
+   sp->statp.st_mode = 0700 | S_IFREG;
    sp->statp.st_ctime = now;
    sp->statp.st_mtime = now;
    sp->statp.st_atime = now;
-   sp->statp.st_size = 100;
+   sp->statp.st_size = -1;
    sp->statp.st_blksize = 4096;
    sp->statp.st_blocks = 1;
-   printf("bpipe-fd: startPluginBackup\n");
+   p_ctx->backup = true;
+// printf("bpipe-fd: startPluginBackup\n");
    return bRC_OK;
 }
 
@@ -195,30 +237,46 @@ static bRC startPluginBackup(bpContext *ctx, struct save_pkt *sp)
 static bRC pluginIO(bpContext *ctx, struct io_pkt *io)
 {
    struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext;
+   char msg[200];
     
    io->status = 0;
    io->io_errno = 0;
    switch(io->func) {
    case IO_OPEN:
-      p_ctx->record = 0;
-      printf("bpipe-fd: IO_OPEN\n");
+      p_ctx->fd = popen(p_ctx->reader, "r");
+      if (!p_ctx->fd) {
+         io->io_errno = errno;
+         snprintf(msg, sizeof(msg), "bpipe-fd: reader=%s failed: ERR=%d\n", p_ctx->reader, errno);
+         bfuncs->JobMessage(ctx, __FILE__, __LINE__, 1, 0, msg);
+         printf("%s", msg);
+         return bRC_Error;
+      }
+      printf("bpipe-fd: IO_OPEN reader=%s fd=%p\n", p_ctx->reader, p_ctx->fd);
+      sleep(1);                 /* let pipe connect */
       break;
+
    case IO_READ:
-      printf("bpipe-fd: IO_READ buf=%p len=%d\n", io->buf, io->count);
-      if (p_ctx->record == 0) {
-         strcpy(io->buf, "This is a test string.\n");
-         io->status = strlen(io->buf);
-         p_ctx->record = 1;
-         return bRC_OK;
+      io->status = fread(io->buf, 1, io->count, p_ctx->fd);
+      printf("bpipe-fd: IO_READ buf=%p len=%d\n", io->buf, io->status);
+      if (io->status == 0 && ferror(p_ctx->fd)) {
+         printf("Error reading pipe\n");
+         return bRC_Error;
       }
-      io->status = 0;
+      printf("status=%d\n", io->status);
       break;
+
    case IO_WRITE:
       printf("bpipe-fd: IO_WRITE buf=%p len=%d\n", io->buf, io->count);
       break;
+
    case IO_CLOSE:
+      io->status = pclose(p_ctx->fd);
       printf("bpipe-fd: IO_CLOSE\n");
       break;
+
+   case IO_SEEK:
+      io->offset = p_ctx->offset;
+      break;
    }
    return bRC_OK;
 }