[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Bacula-devel] Pre-alpha version of Bacula plugins working


Hi,

On Friday 22 February 2008, Bastian Friedrich wrote:
> I'm sure you already have that on your radar; nonetheless, I'd like to
> mention that (if I understood things right...) currently plugins -- and the
> reader/writer executables in the bpipe plugin -- do not have access to the
> target directory specification during restore ("where"; the same holds true
> for the "replace" setting).

thanks for your additional work on the plugin interface on that topic.

I have supplemented your basic work in the bpipe plugin to allow two codes, %w 
and %r, to reference the "where" and "replace" flags. See attached patch.

If a writer wants this information in an environment variable (as suggested in 
my earlier mail), a writer "ENVVAR=%w /path/to/writer" will work fine.

Of course, feel free to apply, modify, or throw away :)

Thx,
   Bastian

-- 
Collax GmbH . Burkheimer Straße 3 . 79111 Freiburg . Germany
p: +49 (0) 761-45684-24
f: +49 (0) 761-45684-10        www.collax.com

Geschäftsführer: William K. Hite / Boris Nalbach
AG München HRB 158898 . Ust.-IdNr: DE 814464942
\ Imagination is more important than knowledge - Einstein
Index: src/plugins/fd/bpipe-fd.c
===================================================================
--- src/plugins/fd/bpipe-fd.c	(revision 6579)
+++ src/plugins/fd/bpipe-fd.c	(working copy)
@@ -111,6 +111,8 @@
    char *writer;                      /* writer program for backup */
 };
 
+struct restore_pkt *createRP;
+
 /*
  * loadPlugin() and unloadPlugin() are entry points that are
  *  exported, so Bacula can directly call these two entry points
@@ -151,6 +153,7 @@
    struct plugin_ctx *p_ctx = (struct plugin_ctx *)malloc(sizeof(struct plugin_ctx));
    memset(p_ctx, 0, sizeof(struct plugin_ctx));
    ctx->pContext = (void *)p_ctx;        /* set our context pointer */
+   createRP = NULL;
    return bRC_OK;
 }
 
@@ -288,6 +291,96 @@
 }
 
 /*
+ * Apply codes in writer command:
+ * %w -> "where"
+ * %r -> "replace"
+ *
+ * Replace:
+ * 'always' => 'a', chr(97)
+ * 'ifnewer' => 'w', chr(119)
+ * 'ifolder' => 'o', chr(111)
+ * 'never' => 'n', chr(110)
+ *
+ * This function will allocate the required amount of memory with malloc.
+ * Need to be free()d manually.
+ * Inspired by edit_job_codes in lib/util.c
+ */
+
+char *apply_rp_codes(char *imsg, struct restore_pkt *rp)
+{
+   char *p, *q;
+   const char *str;
+   char add[10];
+   int w_count = 0, r_count = 0;
+   char *omsg;
+
+   if (!rp) {
+      if (imsg) {
+         return strdup(imsg);
+      } else {
+         return NULL;
+      }
+   }
+
+   if ((p = imsg)) {
+      while ((q = strstr(p, "%w"))) {
+         w_count++;
+         p=q+1;
+      }
+
+      p = imsg;
+      while ((q = strstr(p, "%r"))) {
+         r_count++;
+         p=q+1;
+      }
+   }
+
+   /* Required mem: 
+    * len(imsg) 
+    * + number of "where" codes * (len(where)-2) 
+    * - number of "replace" codes
+    */
+   omsg = (char*)malloc(strlen(imsg) + (w_count * (strlen(rp->where)-2)) - r_count + 1);
+   if (!omsg) {
+      fprintf(stderr, "Out of memory.");
+      exit(1);
+   }
+
+   *omsg = 0;
+   //printf("apply_rp_codes: %s\n", imsg);
+   for (p=imsg; *p; p++) {
+      if (*p == '%') {
+         switch (*++p) {
+         case '%':
+            str = "%";
+            break;
+         case 'w':
+	     str = rp->where;
+             break;
+         case 'r':
+	    snprintf(add, 2, "%c", rp->replace);
+	    str = add;
+            break;
+         default:
+            add[0] = '%';
+            add[1] = *p;
+            add[2] = 0;
+            str = add;
+            break;
+         }
+      } else {
+         add[0] = *p;
+         add[1] = 0;
+         str = add;
+      }
+      //printf("add_str %s\n", str);
+      strcat(omsg, str);
+      //printf("omsg=%s\n", omsg);
+   }
+   return omsg;
+}
+
+/*
  * Bacula is calling us to do the actual I/O
  */
 static bRC pluginIO(bpContext *ctx, struct io_pkt *io)
@@ -300,14 +393,22 @@
    case IO_OPEN:
 //    printf("bpipe-fd: IO_OPEN\n");
       if (io->flags & (O_CREAT | O_WRONLY)) {
-         p_ctx->fd = popen(p_ctx->writer, "w");
-         printf("bpipe-fd: IO_OPEN writer=%s\n", p_ctx->writer);
+	 char *writer_codes = apply_rp_codes(p_ctx->writer, createRP);
+
+         p_ctx->fd = popen(writer_codes, "w");
+         printf("bpipe-fd: IO_OPEN writer=%s\n", writer_codes);
          if (!p_ctx->fd) {
             io->io_errno = errno;
             bfuncs->JobMessage(ctx, __FILE__, __LINE__, M_FATAL, 0, 
-               "Open pipe writer=%s failed: ERR=%s\n", p_ctx->writer, strerror(errno));
+               "Open pipe writer=%s failed: ERR=%s\n", writer_codes, strerror(errno));
+            if (writer_codes) {
+               free(writer_codes);
+            }
             return bRC_Error;
          }
+         if (writer_codes) {
+            free(writer_codes);
+         }
       } else {
          p_ctx->fd = popen(p_ctx->reader, "r");
 //       printf("bpipe-fd: IO_OPEN reader=%s\n", p_ctx->reader);
@@ -382,6 +483,7 @@
 static bRC createFile(bpContext *ctx, struct restore_pkt *rp)
 {
 // printf("bpipe-fd: createFile\n");
+   createRP = rp;
    return bRC_OK;
 }
 
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Bacula-devel mailing list
Bacula-devel@xxxxxxxxxxxxxxxxxxxxx
https://lists.sourceforge.net/lists/listinfo/bacula-devel


This mailing list archive is a service of Copilotco.