]> git.ipfire.org Git - thirdparty/bacula.git/commitdiff
metaplugin: Add accurate get feature for backends.
authorRadosław Korzeniewski <radoslaw@korzeniewski.net>
Mon, 30 Aug 2021 08:02:00 +0000 (10:02 +0200)
committerEric Bollengier <eric@baculasystems.com>
Thu, 24 Mar 2022 08:03:03 +0000 (09:03 +0100)
bacula/src/plugins/fd/pluginlib/metaplugin.cpp
bacula/src/plugins/fd/pluginlib/metaplugin.h
bacula/src/plugins/fd/pluginlib/metaplugin_attributes.cpp
bacula/src/plugins/fd/pluginlib/metaplugin_attributes.h
bacula/src/plugins/fd/pluginlib/metaplugin_test.cpp
bacula/src/plugins/fd/pluginlib/pluginlib.h
bacula/src/plugins/fd/pluginlib/ptcomm.cpp
bacula/src/plugins/fd/pluginlib/ptcomm.h

index 28f265178c741f818f8b68def721e55ee9bd0999..e81a91d82a86266a8e0cd2ca1267f129c73882cd 100644 (file)
@@ -232,19 +232,26 @@ int METAPLUGIN::get_ini_count()
    return count;
 }
 
-/*
+/**
+ * @brief
  *
+ * @param ctx
+ * @param param
+ * @param handler
+ * @param key
+ * @param val
+ * @return bRC
  */
-bRC METAPLUGIN::render_param(bpContext* ctx, POOLMEM *param, INI_ITEM_HANDLER *handler, char *key, item_value val)
+bRC METAPLUGIN::render_param(bpContext* ctx, POOL_MEM &param, INI_ITEM_HANDLER *handler, char *key, item_value val)
 {
    if (handler == ini_store_str){
-      Mmsg(&param, "%s=%s\n", key, val.strval);
+      Mmsg(param, "%s=%s\n", key, val.strval);
    } else
    if (handler == ini_store_int64){
-      Mmsg(&param, "%s=%lld\n", key, val.int64val);
+      Mmsg(param, "%s=%lld\n", key, val.int64val);
    } else
    if (handler == ini_store_bool){
-      Mmsg(&param, "%s=%d\n", key, val.boolval ? 1 : 0);
+      Mmsg(param, "%s=%d\n", key, val.boolval ? 1 : 0);
    } else {
       DMSG1(ctx, DERROR, "Unsupported parameter handler for: %s\n", key);
       JMSG1(ctx, M_FATAL, "Unsupported parameter handler for: %s\n", key);
@@ -254,22 +261,20 @@ bRC METAPLUGIN::render_param(bpContext* ctx, POOLMEM *param, INI_ITEM_HANDLER *h
    return bRC_OK;
 }
 
-/*
- * Parsing a plugin command.
+/**
+ * @brief Parsing a plugin command.
  *
- * in:
- *    bpContext - Bacula Plugin context structure
- *    command - plugin command string to parse
- * out:
- *    bRC_OK - on success
- *    bRC_Error - on error
+ * @param ctx bpContext - Bacula Plugin context structure
+ * @param command plugin command string to parse
+ * @param params output parsed params list
+ * @return bRC bRC_OK - on success, bRC_Error - on error
  */
-bRC METAPLUGIN::parse_plugin_command(bpContext *ctx, const char *command, alist *params)
+bRC METAPLUGIN::parse_plugin_command(bpContext *ctx, const char *command, smart_alist<POOL_MEM> &params)
 {
    bool found;
    int count;
    int parargc, argc;
-   POOLMEM *param;
+   POOL_MEM *param;
 
    DMSG(ctx, DINFO, "Parse command: %s\n", command);
    if (parser.parse_cmd(command) != bRC_OK)
@@ -287,7 +292,7 @@ bRC METAPLUGIN::parse_plugin_command(bpContext *ctx, const char *command, alist
    parargc = argc + count;
    /* first parameters from plugin command saved during backup */
    for (int i = 1; i < parser.argc; i++) {
-      param = get_pool_memory(PM_FNAME);
+      param = new POOL_MEM(PM_FNAME);     // TODO: change to POOL_MEM
       found = false;
 
       int k;
@@ -295,22 +300,22 @@ bRC METAPLUGIN::parse_plugin_command(bpContext *ctx, const char *command, alist
       if ((k = check_ini_param(parser.argk[i])) != -1){
          found = true;
          DMSG1(ctx, DINFO, "parse_plugin_command: %s found in restore parameters\n", parser.argk[i]);
-         if (render_param(ctx, param, ini.items[k].handler, parser.argk[i], ini.items[k].val) != bRC_OK){
-            free_and_null_pool_memory(param);
+         if (render_param(ctx, *param, ini.items[k].handler, parser.argk[i], ini.items[k].val) != bRC_OK){
+            delete(param);
             return bRC_Error;
          }
-         params->append(param);
+         params.append(param);
          parargc--;
       }
 
       /* check if param overloaded above */
       if (!found){
          if (parser.argv[i]){
-            Mmsg(&param, "%s=%s\n", parser.argk[i], parser.argv[i]);
-            params->append(param);
+            Mmsg(*param, "%s=%s\n", parser.argk[i], parser.argv[i]);
+            params.append(param);
          } else {
-            Mmsg(&param, "%s=1\n", parser.argk[i]);
-            params->append(param);
+            Mmsg(*param, "%s=1\n", parser.argk[i]);
+            params.append(param);
          }
       }
       /* param is always ended with '\n' */
@@ -346,14 +351,14 @@ bRC METAPLUGIN::parse_plugin_command(bpContext *ctx, const char *command, alist
    /* check what was missing in plugin command but get from ini file */
    if (argc < parargc){
       for (int k = 0; ini.items[k].name; k++){
-         if (ini.items[k].found && !check_plugin_param(ini.items[k].name, params)){
-            param = get_pool_memory(PM_FNAME);
+         if (ini.items[k].found && !check_plugin_param(ini.items[k].name, &params)){
+            param = new POOL_MEM(PM_FNAME);
             DMSG1(ctx, DINFO, "parse_plugin_command: %s from restore parameters\n", ini.items[k].name);
-            if (render_param(ctx, param, ini.items[k].handler, (char*)ini.items[k].name, ini.items[k].val) != bRC_OK){
-               free_and_null_pool_memory(param);
+            if (render_param(ctx, *param, ini.items[k].handler, (char*)ini.items[k].name, ini.items[k].val) != bRC_OK){
+               delete(param);
                return bRC_Error;
             }
-            params->append(param);
+            params.append(param);
             /* param is always ended with '\n' */
             DMSG(ctx, DINFO, "Param: %s", param);
          }
@@ -762,8 +767,9 @@ bRC METAPLUGIN::send_parameters(bpContext *ctx, char *command)
    int32_t rc;
    bRC status = bRC_OK;
    POOL_MEM cmd(PM_FNAME);
-   alist params(16, not_owned_by_alist);
-   POOLMEM *param;
+   // alist params(16, not_owned_by_alist);
+   smart_alist<POOL_MEM> params;
+   POOL_MEM *param;
    bool found;
 
 #ifdef DEVELOPER
@@ -789,19 +795,18 @@ bRC METAPLUGIN::send_parameters(bpContext *ctx, char *command)
 #endif
 
    /* parse and prepare final backend plugin params */
-   status = parse_plugin_command(ctx, command, &params);
+   status = parse_plugin_command(ctx, command, params);
    if (status != bRC_OK){
       /* error */
-      goto bailout;
+      return status;
    }
 
    /* send backend info that parameters are coming */
    pm_strcpy(cmd, "Params\n");
-   rc = backend.ctx->write_command(ctx, cmd.c_str());
+   rc = backend.ctx->write_command(ctx, cmd);
    if (rc < 0){
       /* error */
-      status = bRC_Error;
-      goto bailout;
+      return bRC_Error;
    }
    /* send all prepared parameters */
    foreach_alist(param, &params){
@@ -810,7 +815,7 @@ bRC METAPLUGIN::send_parameters(bpContext *ctx, char *command)
       for (int a = 0; valid_params[a] != NULL; a++ )
       {
          DMSG3(ctx, DVDEBUG, "=> '%s' vs '%s' [%d]\n", param, valid_params[a], strlen(valid_params[a]));
-         if (strncasecmp(param, valid_params[a], strlen(valid_params[a])) == 0){
+         if (strncasecmp(param->c_str(), valid_params[a], strlen(valid_params[a])) == 0){
             found = true;
             break;
          }
@@ -821,7 +826,7 @@ bRC METAPLUGIN::send_parameters(bpContext *ctx, char *command)
          // now handle regression tests commands
          for (int a = 0; regress_valid_params[a] != NULL; a++ ){
             DMSG3(ctx, DVDEBUG, "regress=> '%s' vs '%s' [%d]\n", param, regress_valid_params[a], strlen(regress_valid_params[a]));
-            if (strncasecmp(param, regress_valid_params[a], strlen(regress_valid_params[a])) == 0){
+            if (strncasecmp(param->c_str(), regress_valid_params[a], strlen(regress_valid_params[a])) == 0){
                found = true;
                break;
             }
@@ -830,34 +835,40 @@ bRC METAPLUGIN::send_parameters(bpContext *ctx, char *command)
 #endif
 
       // signal error if required
-      if (!found){
-         pm_strcpy(cmd, param);
+      if (!found) {
+         pm_strcpy(cmd, param->c_str());
          strip_trailing_junk(cmd.c_str());
          DMSG1(ctx, DERROR, "Unknown parameter %s in Plugin command.\n", cmd.c_str());
          JMSG1(ctx, M_ERROR, "Unknown parameter %s in Plugin command.\n", cmd.c_str());
       }
 
-      rc = backend.ctx->write_command(ctx, param);
-      if (rc < 0){
+      rc = backend.ctx->write_command(ctx, *param);
+      if (rc < 0) {
          /* error */
-         status = bRC_Error;
-         goto bailout;
+         return bRC_Error;
       }
    }
-   /* signal end of parameters block */
+
+   // now send accurate parameter if requested and available
+   if (ACCURATEPLUGINPARAMETER && accurate_mode) {
+      pm_strcpy(cmd, "Accurate=1\n");
+      rc = backend.ctx->write_command(ctx, cmd);
+      if (rc < 0) {
+         /* error */
+         return bRC_Error;
+      }
+   }
+
+   // signal end of parameters block
    backend.ctx->signal_eod(ctx);
    /* ack Params command */
    if (!backend.ctx->read_ack(ctx)){
       DMSG0(ctx, DERROR, "Wrong backend response to Params command.\n");
       JMSG0(ctx, backend.ctx->jmsg_err_level(), "Wrong backend response to Params command.\n");
-      status = bRC_Error;
+      return bRC_Error;
    }
 
-bailout:
-   foreach_alist(param, &params){
-      free_and_null_pool_memory(param);
-   }
-   return status;
+   return bRC_OK;
 }
 
 /*
@@ -1733,6 +1744,11 @@ bRC METAPLUGIN::perform_read_metacommands(bpContext *ctx)
             perform_accurate_check(ctx);
             continue;
          }
+         if (scan_parameter_str(cmd, "CHECKGET:", fname)){
+            /* got accurate get query */
+            perform_accurate_check_get(ctx);
+            continue;
+         }
          if (bstrcmp(cmd.c_str(), "ACL")){
             /* got ACL header */
             perform_read_acl(ctx);
@@ -1873,6 +1889,77 @@ bRC METAPLUGIN::perform_accurate_check(bpContext *ctx)
    return bRC_Error;
 }
 
+/**
+ * @brief Perform accurate query check and resturn accurate data to backend.
+ *
+ * @param ctx bpContext - for Bacula debug and jobinfo messages
+ * @return bRC bRC_OK when success, bRC_Error if not
+ */
+bRC METAPLUGIN::perform_accurate_check_get(bpContext *ctx)
+{
+   POOL_MEM cmd(PM_FNAME);
+
+   if (strlen(fname.c_str()) == 0){
+      // input variable is not valid
+      return bRC_Error;
+   }
+
+   DMSG0(ctx, DDEBUG, "perform_accurate_check_get()\n");
+
+   if (!accurate_mode) {
+      // the job is not accurate, so no accurate data will be available at all
+      pm_strcpy(cmd, "NOACCJOB\n");
+      if (!backend.ctx->signal_error(ctx, cmd)) {
+         DMSG0(ctx, DERROR, "Cannot send 'No Accurate Job' info to backend\n");
+         JMSG0(ctx, backend.ctx->jmsg_err_level(), "Cannot send 'No Accurate Job' info to backend\n");
+         return bRC_Error;
+      }
+      return bRC_OK;
+   }
+
+#if __cplusplus >= 201103L
+   accurate_attribs_pkt attribs {0};
+#else
+   accurate_attribs_pkt attribs;
+   memset(attribs, 0, sizeof(attribs));
+#endif
+
+   attribs.fname = fname.c_str();
+   bRC rc = getAccurateAttribs(&attribs);
+
+   struct restore_pkt rp;
+
+   switch (rc)
+   {
+   case bRC_Seen:
+      memcpy(&rp.statp, &attribs.statp, sizeof(rp.statp));
+      rp.type = FT_MASK;   // This is a special metaplugin protocol hack
+                           // because the current Bacula accurate code does
+                           // not handle FileType on catalog attributes, yet.
+      // STAT:...
+      metaplugin::attributes::make_stat_command(ctx, cmd, &rp);
+      backend.ctx->write_command(ctx, cmd);
+
+      // TSTAMP:...
+      if (metaplugin::attributes::make_tstamp_command(ctx, cmd, &rp) == metaplugin::attributes::Status_OK) {
+         backend.ctx->write_command(ctx, cmd);
+         DMSG(ctx, DINFO, "createFile:%s", cmd.c_str());
+      }
+
+      break;
+   default:
+      pm_strcpy(cmd, "UNAVAIL\n");
+      if (!backend.ctx->write_command(ctx, cmd)) {
+         DMSG0(ctx, DERROR, "Cannot send 'UNAVAIL' response to backend\n");
+         JMSG0(ctx, backend.ctx->jmsg_err_level(), "Cannot send 'UNAVAIL' response to backend\n");
+         return bRC_Error;
+      }
+      break;
+   }
+
+   return bRC_OK;
+}
+
 /**
  * @brief
  *
@@ -2461,24 +2548,24 @@ bRC METAPLUGIN::createFile(bpContext *ctx, struct restore_pkt *rp)
       DMSG0(ctx, DDEBUG, "createFile:Forwarding restore to Core\n");
       rp->create_status = CF_CORE;
    } else {
-      /* FNAME:$fname$ */
+      // FNAME:$fname$
       Mmsg(cmd, "FNAME:%s\n", rp->ofname);
       backend.ctx->write_command(ctx, cmd);
       DMSG(ctx, DINFO, "createFile:%s", cmd.c_str());
 
-      /* STAT:... */
+      // STAT:...
       metaplugin::attributes::make_stat_command(ctx, cmd, rp);
       backend.ctx->write_command(ctx, cmd);
       last_type = rp->type;
       DMSG(ctx, DINFO, "createFile:%s", cmd.c_str());
 
-      /* TSTAMP:... */
+      // TSTAMP:...
       if (metaplugin::attributes::make_tstamp_command(ctx, cmd, rp) == metaplugin::attributes::Status_OK) {
          backend.ctx->write_command(ctx, cmd);
          DMSG(ctx, DINFO, "createFile:%s", cmd.c_str());
       }
 
-      /* LSTAT:$link$ */
+      // LSTAT:$link$
       if (rp->type == FT_LNK && rp->olname != NULL){
          Mmsg(cmd, "LSTAT:%s\n", rp->olname);
          backend.ctx->write_command(ctx, cmd);
@@ -2487,7 +2574,7 @@ bRC METAPLUGIN::createFile(bpContext *ctx, struct restore_pkt *rp)
 
       backend.ctx->signal_eod(ctx);
 
-      /* check if backend accepted the file */
+      // check if backend accepted the file
       if (backend.ctx->read_command(ctx, cmd) > 0){
          DMSG(ctx, DINFO, "createFile:resp: %s\n", cmd.c_str());
          if (strcmp(cmd.c_str(), "OK") == 0){
index 923511f040bc7c0477cbd9a33de4c263588431f9..67c12f4724bec8590688bf56c37e497eebb1562f 100644 (file)
@@ -20,8 +20,8 @@
  * @file metaplugin.h
  * @author Radosław Korzeniewski (radoslaw@korzeniewski.net)
  * @brief This is a Bacula metaplugin interface.
- * @version 2.2.0
- * @date 2021-03-08
+ * @version 3.0.0
+ * @date 2021-08-20
  *
  * @copyright Copyright (c) 2021 All rights reserved. IP transferred to Bacula Systems according to agreement.
  */
@@ -59,14 +59,15 @@ extern const char *PLUGIN_VERSION;
 extern const char *PLUGIN_DESCRIPTION;
 
 // Plugin linking time variables
-extern const char *PLUGINPREFIX;          /// is used for prefixing every Job and Debug messages generted by a plugin
-extern const char *PLUGINNAME;            /// should match the backend $pluginname$ used for Handshake procedure
-extern const bool CUSTOMNAMESPACE;        /// defines if metaplugin should send `Namespace=...` backend plugin parameter using PLUGINNAMESPACE variable
-extern const bool CUSTOMPREVJOBNAME;      /// defines if metaplugin should send `PrevJobName=...` backend plugin parameter from bacula variable
-extern const char *PLUGINNAMESPACE;       /// custom backend plugin namespace used as file name prefix
-extern const char *PLUGINAPI;             /// the plugin api string which should match backend expectations
-extern const char *BACKEND_CMD;           /// a backend execution command path
-extern const int32_t CUSTOMCANCELSLEEP;   /// custom wait time for backend between USR1 and terminate procedures
+extern const char *PLUGINPREFIX;             /// is used for prefixing every Job and Debug messages generted by a plugin
+extern const char *PLUGINNAME;               /// should match the backend $pluginname$ used for Handshake procedure
+extern const bool CUSTOMNAMESPACE;           /// defines if metaplugin should send `Namespace=...` backend plugin parameter using PLUGINNAMESPACE variable
+extern const bool CUSTOMPREVJOBNAME;         /// defines if metaplugin should send `PrevJobName=...` backend plugin parameter from bacula variable
+extern const char *PLUGINNAMESPACE;          /// custom backend plugin namespace used as file name prefix
+extern const char *PLUGINAPI;                /// the plugin api string which should match backend expectations
+extern const char *BACKEND_CMD;              /// a backend execution command path
+extern const int32_t CUSTOMCANCELSLEEP;      /// custom wait time for backend between USR1 and terminate procedures
+extern const bool ACCURATEPLUGINPARAMETER;   /// accurate parameter for plugin parameter
 
 /// defines if metaplugin should handle local filesystem restore with Bacula Core functions
 /// `false` means metaplugin will redirect local restore to backend
@@ -250,7 +251,7 @@ private:
    // a list of received RO from bacula which we will use to feed into backend later
    smart_alist<restore_object_class> restoreobject_list;
 
-   bRC parse_plugin_command(bpContext *ctx, const char *command, alist *params);
+   bRC parse_plugin_command(bpContext *ctx, const char *command, smart_alist<POOL_MEM> &params);
    bRC handle_plugin_restoreobj(bpContext *ctx, restore_object_pkt *rop);
    bRC run_backend(bpContext *ctx);
    bRC send_parameters(bpContext *ctx, char *command);
@@ -279,6 +280,7 @@ private:
    bRC perform_read_metadata_info(bpContext *ctx, metadata_type type, struct save_pkt *sp);
    bRC perform_file_index_query(bpContext *ctx);
    bRC perform_accurate_check(bpContext *ctx);
+   bRC perform_accurate_check_get(bpContext *ctx);
    // bRC perform_write_metadata_info(bpContext *ctx, struct meta_pkt *mp);
    metadata_type scan_metadata_type(bpContext *ctx, const POOL_MEM &cmd);
    const char *prepare_metadata_type(metadata_type type);
@@ -291,7 +293,7 @@ private:
    bRC terminate_all_backends(bpContext *ctx);
    bRC cancel_all_backends(bpContext *ctx);
    bRC signal_finish_all_backends(bpContext *ctx);
-   bRC render_param(bpContext *ctx, POOLMEM *param, INI_ITEM_HANDLER *handler, char *key, item_value val);
+   bRC render_param(bpContext *ctx, POOL_MEM &param, INI_ITEM_HANDLER *handler, char *key, item_value val);
 };
 
 #endif   // PLUGINLIB_METAPLUGIN_H
index c33e60eefb275d2cd1caaf3ab2ff46f4e4be3bba..d1e4b208fcf8fb10dace757886e51bbe44499795 100644 (file)
@@ -126,7 +126,7 @@ namespace attributes
       return Not_Command;
    }
 
-   Status make_stat_command(bpContext *ctx, POOL_MEM &cmd, struct restore_pkt *rp)
+   Status make_stat_command(bpContext *ctx, POOL_MEM &cmd, const restore_pkt *rp)
    {
       /* STAT:... */
       char type;
@@ -145,6 +145,9 @@ namespace attributes
       case FT_LNKSAVED:
          type = 'L';
          break;
+      case FT_MASK:     // This is a special metaplugin protocol hack
+         type = 'X';    // as the accurate code does not know this exact value
+         break;
       case FT_REG:
       default:
          type = 'F';
@@ -158,16 +161,13 @@ namespace attributes
       return Status_OK;
    }
 
-   Status make_tstamp_command(bpContext *ctx, POOL_MEM &cmd, struct restore_pkt *rp)
+   Status make_tstamp_command(bpContext *ctx, POOL_MEM &cmd, const restore_pkt *rp)
    {
       /* TSTAMP:... */
-      pm_strcpy(cmd, NULL);
-      if (rp->statp.st_atime || rp->statp.st_mtime || rp->statp.st_ctime) {
-         Mmsg(cmd, "TSTAMP:%ld %ld %ld\n", rp->statp.st_atime, rp->statp.st_mtime, rp->statp.st_ctime);
-         DMSG(ctx, DDEBUG, "make_tstamp_command:%s", cmd.c_str());
-         return Status_OK;
-      }
-      return Not_Command;
+      Mmsg(cmd, "TSTAMP:%ld %ld %ld\n", rp->statp.st_atime, rp->statp.st_mtime, rp->statp.st_ctime);
+      DMSG(ctx, DDEBUG, "make_tstamp_command:%s", cmd.c_str());
+
+      return Status_OK;
    }
 }  // attributes
 }  // metaplugin
index 2d843b22678936ff66ddedb99f6a2dda4ecb1d73..38bb3910ee3a6fb4c5ce8b41a4d9440fa84bc70d 100644 (file)
@@ -45,9 +45,9 @@ namespace attributes
    } Status;
 
    Status read_scan_stat_command(bpContext *ctx, POOL_MEM &cmd, struct save_pkt *sp);
-   Status make_stat_command(bpContext *ctx, POOL_MEM &cmd, struct restore_pkt *rp);
+   Status make_stat_command(bpContext *ctx, POOL_MEM &cmd, const restore_pkt *rp);
    Status read_scan_tstamp_command(bpContext *ctx, POOL_MEM &cmd, struct save_pkt *sp);
-   Status make_tstamp_command(bpContext *ctx, POOL_MEM &cmd, struct restore_pkt *rp);
+   Status make_tstamp_command(bpContext *ctx, POOL_MEM &cmd, const restore_pkt *rp);
 }  // attributes
 }  // metaplugin
 
index ff0391b5c177c18573be653b3b64d882da3c4435..71b578805283feadaba190ba2804d95b97b860e9 100644 (file)
@@ -43,7 +43,7 @@ const char *PLUGINPREFIX         = "metaplugin:";
 const char *PLUGINNAME           = "metaplugin";
 const char *PLUGINNAMESPACE      = "@metaplugin";
 const bool CUSTOMNAMESPACE       = true;
-const char *PLUGINAPI            = "3";
+const char *PLUGINAPI            = "4";
 const char *BACKEND_CMD          = "/bin/true";
 
 static bRC mycheckFile(bpContext *ctx, char *fname);
index 9916313db15348d5c03a5b0af6b11cfe0b41b532..f1d0c9a6627b27d176209d5a0fbacd69e4841eaa 100644 (file)
@@ -90,8 +90,9 @@ extern const char *PLUGINNAME;
 #define D4  800                  /* debug for detailed information only */
 #define DVDEBUG D4
 
-#define getBaculaVar(bvar,val)  bfuncs->getBaculaValue(ctx, bvar, val);
-#define checkChanges(sp)   bfuncs->checkChanges(ctx, sp);
+#define getBaculaVar(bvar,val)   bfuncs->getBaculaValue(ctx, bvar, val);
+#define checkChanges(sp)         bfuncs->checkChanges(ctx, sp);
+#define getAccurateAttribs(att)  bfuncs->getAccurateAttribs(ctx, att);
 
 /* used for sanity check in plugin functions */
 #define ASSERT_CTX \
index 88dd921ed1c9bf5d2a36b9159ae3ba69884fd4f0..ee132985652c1037116dd592910d803496a69e84 100644 (file)
@@ -790,6 +790,7 @@ bool PTCOMM::read_ack(bpContext *ctx)
  *
  * @param ctx for Bacula debug and jobinfo messages
  * @param buf a message buffer contains command to send
+ * @param _single_senddata when true then low-level driver will use POOLMEM reserved space for transfer
  * @return true success
  * @return false when encountered any error
  */
index 0ac2e7ab80df4fd0119bef0c82d3dc8bd5aa8e79..9f8552c75646534db94709f6460de25012fbe7da 100644 (file)
@@ -20,8 +20,8 @@
  * @file ptcomm.h
  * @author Radosław Korzeniewski (radoslaw@korzeniewski.net)
  * @brief This is a process communication lowlevel library for Bacula plugin.
- * @version 2.0.0
- * @date 2021-02-10
+ * @version 3.0.0
+ * @date 2021-08-20
  *
  * @copyright Copyright (c) 2021 All rights reserved. IP transferred to Bacula Systems according to agreement.
  */
@@ -146,7 +146,7 @@ public:
     *    -1 - when encountered any error
     *    <n> - the number of bytes sent, success
     */
-   int32_t write_command(bpContext *ctx, POOL_MEM &buf) { return write_command(ctx, buf.addr(), true); }
+   int32_t write_command(bpContext *ctx, POOL_MEM &buf) { return write_command(ctx, buf.c_str(), true); }
    int32_t write_data(bpContext *ctx, const char *buf, int32_t len, bool _single_senddata = false);
 
    bool read_ack(bpContext *ctx);
@@ -162,11 +162,12 @@ public:
     * @return true success
     * @return false when encountered any error
     */
-   inline bool signal_error(bpContext *ctx, const POOLMEM *buf)
+   inline bool signal_error(bpContext *ctx, const char * buf, bool _single_senddata = false)
    {
       int32_t len = buf ? strlen(buf) : 0;
-      return sendbackend(ctx, 'E', buf, len);
+      return sendbackend(ctx, 'E', buf, len, _single_senddata);
    }
+   inline bool signal_error(bpContext *ctx, const POOL_MEM &buf) { return signal_error(ctx, buf.c_str(), true); }
 
    POOLMEM *get_error(bpContext *ctx);