]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/dird/dir_plugins.c
ebl Add writable variable to director plugin interface
[bacula/bacula] / bacula / src / dird / dir_plugins.c
index 1821c593ff98a04adc30c57870db8ddfa4881861..45ca43af715867ca6b47baaef343829c8f8a7d68 100644 (file)
@@ -20,7 +20,7 @@
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Bacula® is a registered trademark of John Walker.
+   Bacula® is a registered trademark of Kern Sibbald.
    The licensor of Bacula is the Free Software Foundation Europe
    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
    Switzerland, email:ftf@fsfeurope.org.
@@ -74,12 +74,12 @@ void generate_plugin_event(JCR *jcr, bEventType eventType, void *value)
    Plugin *plugin;
    int i = 0;
 
-   if (!plugin_list) {
+   if (!plugin_list || !jcr || !jcr->plugin_ctx_list) {
       return;
    }
 
    bpContext *plugin_ctx_list = (bpContext *)jcr->plugin_ctx_list;
-   event.eventType = eventType;
+   jcr->eventType = event.eventType = eventType;
 
    Dmsg2(dbglvl, "plugin_ctx_list=%p JobId=%d\n", jcr->plugin_ctx_list, jcr->JobId);
 
@@ -94,6 +94,21 @@ void generate_plugin_event(JCR *jcr, bEventType eventType, void *value)
    return;
 }
 
+static void dump_dir_plugin(Plugin *plugin, FILE *fp)
+{
+   if (!plugin) {
+      return ;
+   }
+   pInfo *info = (pInfo *) plugin->pinfo;
+   fprintf(fp, "\tversion=%d\n", info->version);
+   fprintf(fp, "\tdate=%s\n", NPRTB(info->plugin_date));
+   fprintf(fp, "\tmagic=%s\n", NPRTB(info->plugin_magic));
+   fprintf(fp, "\tauthor=%s\n", NPRTB(info->plugin_author));
+   fprintf(fp, "\tlicence=%s\n", NPRTB(info->plugin_license));
+   fprintf(fp, "\tversion=%s\n", NPRTB(info->plugin_version));
+   fprintf(fp, "\tdescription=%s\n", NPRTB(info->plugin_description));
+}
+
 void load_dir_plugins(const char *plugin_dir)
 {
    if (!plugin_dir) {
@@ -102,6 +117,7 @@ void load_dir_plugins(const char *plugin_dir)
 
    plugin_list = New(alist(10, not_owned_by_alist));
    load_plugins((void *)&binfo, (void *)&bfuncs, plugin_dir, plugin_type);
+   dbg_plugin_add_hook(dump_dir_plugin);
 }
 
 /*
@@ -122,9 +138,9 @@ void new_plugins(JCR *jcr)
       return;
    }
 
-   jcr->plugin_ctx_list = (void *)malloc(sizeof(bpContext) * num);
+   jcr->plugin_ctx_list = (bpContext *)malloc(sizeof(bpContext) * num);
 
-   bpContext *plugin_ctx_list = (bpContext *)jcr->plugin_ctx_list;
+   bpContext *plugin_ctx_list = jcr->plugin_ctx_list;
    Dmsg2(dbglvl, "Instantiate plugin_ctx_list=%p JobId=%d\n", jcr->plugin_ctx_list, jcr->JobId);
    foreach_alist(plugin, plugin_list) {
       /* Start a new instance of each plugin */
@@ -142,7 +158,7 @@ void free_plugins(JCR *jcr)
    Plugin *plugin;
    int i = 0;
 
-   if (!plugin_list) {
+   if (!plugin_list || !jcr->plugin_ctx_list) {
       return;
    }
 
@@ -156,7 +172,6 @@ void free_plugins(JCR *jcr)
    jcr->plugin_ctx_list = NULL;
 }
 
-
 /* ==============================================================
  *
  * Callbacks from the plugin
@@ -165,9 +180,14 @@ void free_plugins(JCR *jcr)
  */
 static bRC baculaGetValue(bpContext *ctx, brVariable var, void *value)
 {
+   bRC ret=bRC_OK;
+
+   if (!ctx) {
+      return bRC_Error;
+   }
    JCR *jcr = (JCR *)(ctx->bContext);
 // Dmsg1(dbglvl, "bacula: baculaGetValue var=%d\n", var);
-   if (!value) {
+   if (!jcr || !value) {
       return bRC_Error;
    }
 // Dmsg1(dbglvl, "Bacula: jcr=%p\n", jcr); 
@@ -176,16 +196,194 @@ static bRC baculaGetValue(bpContext *ctx, brVariable var, void *value)
       *((int *)value) = jcr->JobId;
       Dmsg1(dbglvl, "Bacula: return bVarJobId=%d\n", jcr->JobId);
       break;
+   case bVarJobName:
+      *((char **)value) = jcr->Job;
+      Dmsg1(dbglvl, "Bacula: return bVarJobName=%s\n", jcr->Job);
+      break;
+   case bVarJob:
+      *((char **)value) = jcr->job->hdr.name;
+      Dmsg1(dbglvl, "Bacula: return bVarJob=%s\n", jcr->job->hdr.name);
+      break;
+   case bVarLevel:
+      *((int *)value) = jcr->get_JobLevel();
+      Dmsg1(dbglvl, "Bacula: return bVarLevel=%c\n", jcr->get_JobLevel());
+      break;
+   case bVarType:
+      *((int *)value) = jcr->get_JobType();
+      Dmsg1(dbglvl, "Bacula: return bVarType=%c\n", jcr->get_JobType());
+      break;
+   case bVarClient:
+      *((char **)value) = jcr->client->hdr.name;
+      Dmsg1(dbglvl, "Bacula: return bVarClient=%s\n", jcr->client->hdr.name);
+      break;
+   case bVarNumVols:
+      POOL_DBR pr;
+      memset(&pr, 0, sizeof(pr));
+      bstrncpy(pr.Name, jcr->pool->hdr.name, sizeof(pr.Name));
+      if (!db_get_pool_record(jcr, jcr->db, &pr)) {
+         ret=bRC_Error;
+      }
+      *((int *)value) = pr.NumVols;
+      Dmsg1(dbglvl, "Bacula: return bVarNumVols=%d\n", pr.NumVols);
+      break;
+   case bVarPool:
+      *((char **)value) = jcr->pool->hdr.name;
+      Dmsg1(dbglvl, "Bacula: return bVarPool=%s\n", jcr->pool->hdr.name);
+      break;
+   case bVarStorage:
+      if (jcr->wstore) {
+         *((char **)value) = jcr->wstore->hdr.name;
+      } else if (jcr->rstore) {
+         *((char **)value) = jcr->rstore->hdr.name;
+      } else {
+         *((char **)value) = NULL;
+         ret=bRC_Error;
+      }
+      Dmsg1(dbglvl, "Bacula: return bVarStorage=%s\n", NPRT(*((char **)value)));
+      break;
+   case bVarWriteStorage:
+      if (jcr->wstore) {
+         *((char **)value) = jcr->wstore->hdr.name;
+      } else {
+         *((char **)value) = NULL;
+         ret=bRC_Error;
+      }
+      Dmsg1(dbglvl, "Bacula: return bVarWriteStorage=%s\n", NPRT(*((char **)value)));
+      break;
+   case bVarReadStorage:
+      if (jcr->rstore) {
+         *((char **)value) = jcr->rstore->hdr.name;
+      } else {
+         *((char **)value) = NULL;
+         ret=bRC_Error;
+      }
+      Dmsg1(dbglvl, "Bacula: return bVarReadStorage=%s\n", NPRT(*((char **)value)));
+      break;
+   case bVarCatalog:
+      *((char **)value) = jcr->catalog->hdr.name;
+      Dmsg1(dbglvl, "Bacula: return bVarCatalog=%s\n", jcr->catalog->hdr.name);
+      break;
+   case bVarMediaType:
+      if (jcr->wstore) {
+         *((char **)value) = jcr->wstore->media_type;
+      } else if (jcr->rstore) {
+         *((char **)value) = jcr->rstore->media_type;
+      } else {
+         *((char **)value) = NULL;
+         ret=bRC_Error;
+      }
+      Dmsg1(dbglvl, "Bacula: return bVarMediaType=%s\n", NPRT(*((char **)value)));
+      break;
+   case bVarJobStatus:
+      *((int *)value) = jcr->JobStatus;
+      Dmsg1(dbglvl, "Bacula: return bVarJobStatus=%c\n", jcr->JobStatus);
+      break;
+   case bVarPriority:
+      *((int *)value) = jcr->JobPriority;
+      Dmsg1(dbglvl, "Bacula: return bVarPriority=%d\n", jcr->JobPriority);
+      break;
+   case bVarVolumeName:
+      *((char **)value) = jcr->VolumeName;
+      Dmsg1(dbglvl, "Bacula: return bVarVolumeName=%s\n", jcr->VolumeName);
+      break;
+   case bVarCatalogRes:
+      ret = bRC_Error;
+      break;
+   case bVarJobErrors:
+      *((int *)value) = jcr->JobErrors;
+      Dmsg1(dbglvl, "Bacula: return bVarErrors=%d\n", jcr->JobErrors);
+      break;
+   case bVarJobFiles:
+      *((int *)value) = jcr->JobFiles;
+      Dmsg1(dbglvl, "Bacula: return bVarFiles=%d\n", jcr->JobFiles);
+      break;
+   case bVarSDJobFiles:
+      *((int *)value) = jcr->SDJobFiles;
+      Dmsg1(dbglvl, "Bacula: return bVarSDFiles=%d\n", jcr->SDJobFiles);
+      break;
+   case bVarSDErrors:
+      *((int *)value) = jcr->SDErrors;
+      Dmsg1(dbglvl, "Bacula: return bVarSDErrors=%d\n", jcr->SDErrors);
+      break;
+   case bVarFDJobStatus:
+      *((int *)value) = jcr->FDJobStatus;
+      Dmsg1(dbglvl, "Bacula: return bVarFDJobStatus=%c\n", jcr->FDJobStatus);
+      break;      
+   case bVarSDJobStatus:
+      *((int *)value) = jcr->SDJobStatus;
+      Dmsg1(dbglvl, "Bacula: return bVarSDJobStatus=%c\n", jcr->SDJobStatus);
+      break;      
    default:
+      ret = bRC_Error;
       break;
    }
-   return bRC_OK;
+   return ret;
 }
 
+extern struct s_jl joblevels[];
+
 static bRC baculaSetValue(bpContext *ctx, bwVariable var, void *value)
 {
+   bRC ret=bRC_OK;
+
+   if (!ctx || !var || !value) {
+      return bRC_Error;
+   }
+   
+   JCR *jcr = (JCR *)ctx->bContext;
+   int intval = *(int*)value;
+   char *strval = (char *)value;
+   bool ok;
+
+   switch (var) {
+   case bwVarJobReport:
+      Jmsg(jcr, M_INFO, 0, "%s", (char *)value);
+      break;
+   
+   case bwVarVolumeName:
+      /* Make sure VolumeName is valid and we are in VolumeName event */
+      if (jcr->eventType == bEventNewVolume &&
+          is_volume_name_legal(NULL, strval))
+      {
+         pm_strcpy(jcr->VolumeName, strval);
+         Dmsg1(100, "Set Vol=%s\n", strval);
+      } else {
+         jcr->VolumeName[0] = 0;
+         ret = bRC_Error;
+      }
+      break;
+
+   case bwVarPriority:
+      Dmsg1(000, "Set priority=%d\n", intval);
+      if (intval >= 1 && intval <= 100) {
+         jcr->JobPriority = intval;
+      } else {
+         ret = bRC_Error;
+      }
+      break;
+
+   case bwVarJobLevel:
+      ok=true;
+      if (jcr->eventType == bEventJobInit) {
+         for (int i=0; ok && joblevels[i].level_name; i++) {
+            if (strcasecmp(strval, joblevels[i].level_name) == 0) {
+               if (joblevels[i].job_type == jcr->get_JobType()) {
+                  jcr->set_JobLevel(joblevels[i].level);
+                  jcr->jr.JobLevel = jcr->get_JobLevel();
+                  ok = false;
+               }
+            }
+         }
+      } else {
+         ret = bRC_Error;
+      }
+      break;
+   default:
+      ret = bRC_Error;
+      break;
+   }
    Dmsg1(dbglvl, "bacula: baculaSetValue var=%d\n", var);
-   return bRC_OK;
+   return ret;
 }
 
 static bRC baculaRegisterEvents(bpContext *ctx, ...)
@@ -240,6 +438,7 @@ int main(int argc, char *argv[])
 
    generate_plugin_event(jcr1, bEventJobStart, (void *)"Start Job 1");
    generate_plugin_event(jcr1, bEventJobEnd);
+   generate_plugin_event(jcr2, bEventJobInit, (void *)"Start Job 1");
    generate_plugin_event(jcr2, bEventJobStart, (void *)"Start Job 1");
    free_plugins(jcr1);
    generate_plugin_event(jcr2, bEventJobEnd);