]> git.ipfire.org Git - thirdparty/bacula.git/commitdiff
Scan metadata stream and insert into the catalog
authorEric Bollengier <eric@baculasystems.com>
Wed, 15 Sep 2021 07:37:56 +0000 (09:37 +0200)
committerEric Bollengier <eric@baculasystems.com>
Fri, 30 Jun 2023 18:35:17 +0000 (20:35 +0200)
12 files changed:
bacula/src/cats/cats.c
bacula/src/cats/cats.h
bacula/src/cats/drop_mysql_tables.in
bacula/src/cats/drop_postgresql_tables.in
bacula/src/cats/grant_postgresql_privileges.in
bacula/src/cats/make_mysql_tables.in
bacula/src/cats/make_postgresql_tables.in
bacula/src/dird/catreq.c
bacula/src/dird/ua_output.c
bacula/src/filed/backup.c
bacula/src/lib/Makefile.in
bacula/src/plugins/fd/test-plugin-fd.c

index 1189c31e22fd5a1faa7f519a8c69aac7d1d2bbc4..d95ca2fa6305c32c261138ef25ba5edbccb0bf26 100644 (file)
@@ -374,4 +374,262 @@ void parse_restore_object_string(char **r_obj_str, ROBJECT_DBR *robj_r)
       robj_r->object_len, robj_r->object);
 }
 
-#endif /* HAVE_SQLITE3 || HAVE_MYSQL || HAVE_POSTGRESQL */
+/****************************************************************
+ * Interface to the MetaXXX tables (MetaEmail, MetaAttachments
+ *
+ * The main idea is to get a JSON object fron the FD/SD that represents data to
+ * index in our catalog. We need to verify the input and convert/insert the
+ * data into the right table.
+ * 
+ ****************************************************************/
+
+/* The cJSON lib is a small JSON parser/writer */
+#include "lib/cJSON.h"
+
+/* We need one scanner per type and per version of data */
+struct json_sql {
+   const char *json_name;
+   const char *sql_name;
+   OutputType  type;
+};
+
+/* This class is the common interface for all JSON parser. It can be used in
+ * simple mapping. For more complex handling, we can subclass it
+ * 
+ * We will have a specific implementation for email, attachments, ...
+ * Each JSON input must be very carefully checked!!
+ */
+class META_JSON_SCANNER: public SMARTALLOC
+{
+public:
+   const char      *m_table;
+   struct json_sql *m_j2s;
+
+   META_JSON_SCANNER(const char *table, struct json_sql *j2s):
+      m_table(table), m_j2s(j2s) {};
+
+   virtual ~META_JSON_SCANNER(){};
+
+   /* Parse a JSON node and validate the input */
+   virtual bool parse(JCR *jcr, BDB *db,
+                      DBId_t jid, int64_t fidx,
+                      cJSON *root,
+                      POOLMEM **dest);
+};
+
+/* Email JSON data
+
+ {
+   "Version": 1,
+   "Type" : "EMAIL",
+   "EmailBodyPreview" : "-------- Forwarded Message --------\r\nSubject: Re: [Bacula-devel] When 5.1?\r\nDate: Sun, 5 Jun 2011 17:36:33 +0200\r\nFrom: Bastian Friedrich <bastian.friedrich@collax.com>\r\nTo: bacula-devel@lists.sourceforge.net\r\nCC: Kern Sibbald <kern@sibbald.com>",
+   "EmailCc" : "",
+   "EmailConversationId" : "AAQkADkzMjFhOGZjLTM4NWQtNDU1OC1iODA0LWRmNzRiOTRkZjEzMgAQAFu5M6Q-lKhMhvlmDMcwbug=",
+   "EmailFolderName" : "Inbox",
+   "EmailFrom" : "eric.bollengier@baculasystems.com",
+   "EmailId" : "AAMkADkzMjFhOGZjLTM4NWQtNDU1OC1iODA0LWRmNzRiOTRkZjEzMgBGAAAAAACLSt6kXFgwSaU_laiYbZmvBwBUvb47c4T-R5BYeUNUiTxqAADsn4zsAABUvb47c4T-R5BYeUNUiTxqAADsn8WxAAA=",
+   "EmailImportance" : "NORMAL",
+   "EmailInternetMessageId" : "<2fe3fc53-e83d-70e6-ebcf-38859c84ec26@baculasystems.com>",
+   "EmailIsDraft" : 0,
+   "EmailIsRead" : 0,
+   "EmailTime" : "Sep 10, 2021, 2:44:36 PM",
+   "EmailSubject" : "Fwd: [Bacula-devel] When 5.1?",
+   "EmailTags" : "category1, category2",
+   "EmailTo" : "jorgegea@jorgegea.onmicrosoft.com",
+   "EmailHasAttachment" : 0,
+   "Plugin" : "m365"
+}
+*/
+
+#define SAME_KW(keyword, type) {keyword, keyword, type}
+
+static struct json_sql email_json_v1[] = {
+   SAME_KW("EmailTenant", OT_STRING),
+   SAME_KW("EmailOwner", OT_STRING),
+   SAME_KW("EmailBodyPreview", OT_STRING),
+   SAME_KW("EmailCc", OT_STRING),
+   SAME_KW("EmailConversationId", OT_STRING),
+   SAME_KW("EmailFolderName", OT_STRING),
+   SAME_KW("EmailFrom", OT_STRING),
+   SAME_KW("EmailId", OT_STRING),
+   SAME_KW("EmailImportance", OT_STRING),
+   SAME_KW("EmailInternetMessageId", OT_STRING),
+   SAME_KW("EmailIsRead", OT_BOOL),
+   SAME_KW("EmailTime", OT_STRING),
+   SAME_KW("EmailSubject", OT_STRING),
+   SAME_KW("EmailTags", OT_STRING),
+   SAME_KW("EmailTo", OT_STRING),
+   SAME_KW("EmailHasAttachment", OT_INT),
+   SAME_KW("Plugin", OT_STRING),
+   {NULL, NULL, OT_END}
+};
+
+/*
+{
+   "AttachmentContentType" : "application/octet-stream",
+   "AttachmentEmailId" : "AAMkAGZmZjBlMjI0LTMxMmEtNDFkMi1hM2YxLWEzNjI5MjY4M2JkMQBGAAAAAAChUr1sDFmcSYm7PK3nvLVxBwB-S4yOymgVRpR5CA4-eilAAABABKybAAB-S4yOymgVRpR5CA4-eilAAABABUnfAAA=",
+   "AttachmentId" : "AAMkAGZmZjBlMjI0LTMxMmEtNDFkMi1hM2YxLWEzNjI5MjY4M2JkMQBGAAAAAAChUr1sDFmcSYm7PK3nvLVxBwB-S4yOymgVRpR5CA4-eilAAABABKybAAB-S4yOymgVRpR5CA4-eilAAABABUnfAAABEgAQAKT86cEi1S9PgA8I5xS0vKA=",
+   "AttachmentIsInline" : 0,
+   "AttachmentName" : "Ancillae.gen",
+   "Plugin" : "m365",
+   "Type" : "ATTACHMENT",
+   "Version" : 1
+}
+ */
+static struct json_sql email_attachment_json_v1[] = {
+   SAME_KW("AttachmentContentType", OT_STRING),
+   SAME_KW("AttachmentEmailId", OT_STRING),
+   //SAME_KW("AttachmentId", OT_STRING),
+   SAME_KW("AttachmentIsInline", OT_BOOL),
+   SAME_KW("AttachmentName", OT_STRING),
+   SAME_KW("Plugin", OT_STRING),
+   {NULL, NULL, OT_END}
+};
+
+bool META_JSON_SCANNER::parse(JCR *jcr, BDB *db,
+                              DBId_t jid, int64_t fidx,
+                              cJSON *root,
+                              POOLMEM **dest)
+{
+   POOL_MEM values, tmp, esc;
+   bool status = false;
+   bool first = true;
+   cJSON *val;
+   int len;
+   Mmsg(dest, "INSERT INTO %s (", m_table);
+   for (int i=0; m_j2s[i].json_name ; i++) {
+      if (!first) {
+         pm_strcat(dest, ",");
+      }
+      pm_strcat(dest, m_j2s[i].sql_name);
+
+      val = cJSON_GetObjectItemCaseSensitive(root, m_j2s[i].json_name);
+      switch(m_j2s[i].type) {
+      case OT_BOOL:
+         if (!cJSON_IsNumber(val)) {
+            Mmsg(dest, "JSON Error: Unable to find %s", m_j2s[i].json_name);
+            goto bail_out;
+         }
+         Mmsg(tmp, "%c%d",
+              first?' ':',',
+              val->valuedouble == 0 ? 0 : 1);
+         break;
+      case OT_STRING:
+         if (!cJSON_IsString(val) || (val->valuestring == NULL)) {
+            Mmsg(dest, "JSON Error: Unable to find %s", m_j2s[i].json_name);
+            goto bail_out;
+         }
+         len = strlen(val->valuestring);
+         esc.check_size(len*2+1);
+         db_escape_string(jcr, db, esc.c_str(), val->valuestring, len);
+
+         Mmsg(tmp, "%c'%s'",
+              first?' ':',',
+              esc.c_str());
+
+         break;
+      case OT_INT:
+         if (!cJSON_IsNumber(val)) {
+            Mmsg(dest, "JSON Error: Unable to find %s", m_j2s[i].json_name);
+            goto bail_out;
+         }
+         Mmsg(tmp, "%c%lld",
+              first?' ':',',
+              (int64_t)val->valuedouble);
+         break;
+      default:
+         Mmsg(dest, "Implenentation issue with type %d", m_j2s[i].type);
+         goto bail_out;
+      }
+      first = false;
+      pm_strcat(values, tmp.c_str());
+   }
+   /* Finish the query with job information */
+   pm_strcat(dest, ",JobId,FileIndex) VALUES (");
+   pm_strcat(dest, values.c_str());
+   Mmsg(tmp, ", %lld, %lld)", jid, fidx);
+   pm_strcat(dest, tmp.c_str());
+   status = true;
+
+bail_out:
+   return status;
+}
+
+static void *cats_malloc(size_t size)
+{
+   return malloc(size);
+}
+
+/****************************************************************
+ * The META_JSON class is here to initilize and find the META_XXX_JSON
+ * implementation to use to decode the JSON stream.
+ ****************************************************************/
+bool META_JSON::parse(JCR *jcr, BDB *db,
+                      DBId_t jid, int64_t fidx,
+                      const char *string,
+                      int len,
+                      POOLMEM **dest)
+{
+   bool status = false;
+   cJSON *type = NULL;
+   cJSON *version = NULL;
+   META_JSON_SCANNER *impl = NULL;
+
+   /* We use our own memory allocator to track orphan buffers */
+   cJSON_Hooks hook;
+   hook.malloc_fn = cats_malloc;
+   hook.free_fn = bfree;
+   cJSON_InitHooks(&hook);
+
+   cJSON *json = cJSON_ParseWithLength(string, len);
+   if (json == NULL) {
+      const char *error_ptr = cJSON_GetErrorPtr();
+      if (error_ptr != NULL) {
+         Mmsg(dest, "JSON Error before: %s\n", error_ptr);
+      }
+      goto bail_out;
+   }
+   type = cJSON_GetObjectItemCaseSensitive(json, "Type");
+   if (!cJSON_IsString(type) || (type->valuestring == NULL))
+   {
+      Mmsg(dest, "JSON Error: Unable to find Type");
+      goto bail_out;
+   }
+   version = cJSON_GetObjectItemCaseSensitive(json, "Version");
+   if (!cJSON_IsNumber(version) || (version->valueint == 0))
+   {
+      Mmsg(dest, "JSON Error: Unable to find Version");
+      goto bail_out;
+   }
+   if (strcmp(type->valuestring, "EMAIL") == 0) {
+      if (version->valueint >= 1) {
+         /* If the parser cannot handle a new format, adjust it */
+         impl = New(META_JSON_SCANNER("MetaEmail", email_json_v1));
+      }
+   } else if (strcmp(type->valuestring, "ATTACHMENT") == 0) {
+      if (version->valueint >= 1) {
+         impl = New(META_JSON_SCANNER("MetaAttachment", email_attachment_json_v1));
+      }
+   }
+   if (!impl) {
+      Mmsg(dest, "JSON Error: Incorrect Type");
+      goto bail_out;
+   }
+   if (!impl->parse(jcr, db, jid, fidx, json, dest)) {
+      goto bail_out;
+   }
+   status = true;
+
+bail_out:
+   if (impl) {
+      delete impl;
+   }
+   /* TODO: Need to see if we need to free all members */
+   if (json) {
+      cJSON_Delete(json);
+   }
+   return status;
+}
+
+
+#endif /* HAVE_SQLITE3 || HAVE_MYSQL || HAVE_POSTGRESQL */ 
index 9d9392f98c82e4e2df4026a6f260f2f9657c1d0a..a8381b010e01e7df66827b6b07f9f7ad05401c3d 100644 (file)
@@ -731,6 +731,19 @@ public:
    }
 };
 
+class META_JSON: public SMARTALLOC
+{
+public:
+   META_JSON(){};
+
+   virtual ~META_JSON(){};
+   bool parse(JCR *jcr, BDB *db,
+              DBId_t jid, int64_t fidx,
+              const char *value,
+              int len,
+              POOLMEM **dest);
+};
+
 
 /* Functions exported by sql.c for use within the cats directory. */
 void json_list_begin(void *vctx, const char *title);
index 1b1c60b5a9cb5fb772c4b17cf8631b3c96dc4d28..e2e4abcafa29b5cc403c66ff6f160d82923e7be8 100644 (file)
@@ -10,6 +10,8 @@ db_name=@db_name@
 
 if $bindir/mysql $* <<END-OF-DATA
 USE ${db_name};
+DROP TABLE IF EXISTS MetaEmail;
+DROP TABLE IF EXISTS MetaAttachment;
 DROP TABLE IF EXISTS TagJob;
 DROP TABLE IF EXISTS TagClient;
 DROP TABLE IF EXISTS TagMedia;
index 1f70d1b7f9fa43ab49c052c5cf620ac4cd76cc96..bd4f8a4d09d6a68534cddbcc101eeb4956d70666 100644 (file)
@@ -9,6 +9,8 @@ bindir=@POSTGRESQL_BINDIR@
 db_name=@db_name@
 
 $bindir/psql -f - -d ${db_name} $* <<END-OF-DATA 1>/dev/null 2>/dev/null
+drop table if exists MetaEmail;
+drop table if exists MetaAttachment;
 drop table if exists TagJob;
 drop table if exists TagClient;
 drop table if exists TagMedia;
index be7aaca4f6627b61b98654915a0497b11e165686..4d6187fcd320ab62b6e44347ee5b825a8568792b 100644 (file)
@@ -23,6 +23,8 @@ create user ${db_user} ${pass};
 alter database ${db_name} owner to ${db_user} ;
 
 -- for tables
+grant all on MetaEmail    to ${db_user};
+grant all on MetaAttachment to ${db_user};
 grant all on TagJob       to ${db_user};
 grant all on TagClient    to ${db_user};
 grant all on TagMedia     to ${db_user};
index dcecfff924e20fdf33455e564c273d528d659d6a..45c1d8e2eaeed965cc859a8d847fed763e35bad6 100644 (file)
@@ -31,6 +31,59 @@ USE ${db_name};
 --  sensitive in sorts, which is what we want, and TEXT
 --  is case insensitive.
 --
+-- --------------------------------------------------------------
+-- MetaData Index
+
+CREATE TABLE MetaEmail
+(
+    EmailTenant       TINYBLOB,
+    EmailOwner        TINYBLOB,
+    EmailId           TINYBLOB,
+    EmailTime         DATETIME,
+    EmailTags         BLOB,
+    EmailSubject      BLOB,
+    EmailFolderName   BLOB,
+    EmailFrom         TINYBLOB,
+    EmailTo           BLOB,
+    EmailCc           BLOB,
+    EmailInternetMessageId TINYBLOB,
+    EmailBodyPreview  BLOB,
+    EmailImportance   TINYBLOB,
+    EmailConversationId    TINYBLOB,
+    EmailIsRead       TINYINT,
+    EmailIsDraft      TINYINT,
+    EmailHasAttachement TINYINT,
+    Plugin       TINYBLOB,
+    FileIndex    int,
+    JobId        int
+);
+
+CREATE INDEX meta_emailowner ON MetaEmail (EmailTenant, EmailOwner);
+CREATE INDEX meta_emailtime on MetaEmail (EmailTime);
+CREATE INDEX meta_emailtags on MetaEmail (EmailTags);
+CREATE INDEX meta_emailfoldername on MetaEmail (EmailFolderName);
+CREATE INDEX meta_emailconversationid on MetaEmail (EmailConversationId);
+CREATE INDEX meta_emailsubjectbody ON MetaEmail (EmailSubject);
+CREATE INDEX meta_emailbodypreview ON MetaEmail (EmailBodyPreview);
+CREATE INDEX meta_emailto ON MetaEmail (EmailTo);
+CREATE INDEX meta_emailfrom ON MetaEmail (EmailFrom);
+CREATE INDEX meta_emailcc ON MetaEmail (EmailCc);
+CREATE INDEX meta_emailisread on MetaEmail (EmailIsRead);
+CREATE INDEX meta_emailhasattachement on MetaEmail (EmailHasAttachement);
+CREATE INDEX meta_emailfileindex_jobid on MetaEmail (Jobid, FileIndex);
+
+CREATE TABLE MetaAttachement
+{
+    AttachementName     BLOB,
+    AttachementEmailId  TINYBLOB,
+    AttachementContentType TINYBLOB,
+    AttachementIsInline SMALLINT,
+    Plugin       TINYBLOB,
+    FileIndex    INTEGER,
+    JobId        INTEGER
+};
+
+CREATE INDEX meta_attachementemailid ON MetaAttachement USING HASH (AttachementEmailId);
 
 CREATE TABLE TagJob
 (
index ade6969d116d184a92fafc12cafc7147e415282f..b37dcd54db489ba07f1a7c84280e5cb285a26610 100644 (file)
@@ -15,6 +15,78 @@ db_name=${db_name:-@db_name@}
 
 psql -f - -d ${db_name} $* <<END-OF-DATA
 
+-- --------------------------------------------------------------
+-- MetaData Index
+
+CREATE TABLE MetaEmail
+(
+    EmailTenant       text,
+    EmailOwner        text,
+    EmailId           text,
+    EmailTime timestamp without time zone,
+    EmailTags         text,
+    EmailSubject      text,
+    EmailFolderName   text,
+    EmailFrom         text,
+    EmailTo           text,
+    EmailCc           text,
+    EmailInternetMessageId text,  -- no index
+    EmailBodyPreview  text,
+    EmailImportance   text,
+    EmailConversationId    text,
+    EmailIsRead       smallint,
+    EmailIsDraft      smallint,
+    EmailHasAttachment smallint,
+    Plugin       text,
+    FileIndex    int,
+    JobId        int
+);
+
+-- Need to add postgresql-contrib to the dependency list
+
+do \$\$
+declare
+  selected_ext pg_extension%rowtype;
+begin  
+
+  select 1 from pg_extension
+    into selected_ext
+  where extname = 'pg_trgm';
+  
+  if not found then
+     CREATE EXTENSION pg_trgm;
+  end if;
+end \$\$;
+
+CREATE INDEX meta_emailowner on MetaEmail (EmailTenant, EmailOwner);
+CREATE INDEX meta_emailtime on MetaEmail (EmailTime);
+CREATE INDEX meta_emailsenttime on MetaEmail (EmailSentTime);
+CREATE INDEX meta_emailtags on MetaEmail (EmailTags);
+CREATE INDEX meta_emailfoldername on MetaEmail (EmailFolderName);
+-- CREATE INDEX meta_emailsender on MetaEmail (EmailSender);
+CREATE INDEX meta_emailconversationid on MetaEmail (EmailConversationId);
+CREATE INDEX meta_emailsubjectbody ON MetaEmail 
+       USING GIN (EmailSubject gin_trgm_ops, EmailBodyPreview gin_trgm_ops, EmailTo gin_trgm_ops, EmailCc gin_trgm_ops, EmailFrom gin_trgm_ops);
+CREATE INDEX meta_emailimportance on MetaEmail (EmailImportance);
+CREATE INDEX meta_emailisread on MetaEmail (EmailIsRead);
+CREATE INDEX meta_emailhasattachment on MetaEmail (EmailHasAttachment);
+CREATE INDEX meta_emailfileindex_jobid on MetaEmail (Jobid, FileIndex);
+
+CREATE TABLE MetaAttachment
+(
+    AttachmentName     text,
+    AttachmentEmailId  text,
+    AttachmentContentType text,
+    AttachmentIsInline smallint,
+    Plugin       text,
+    FileIndex    int,
+    JobId        int
+);
+
+CREATE INDEX meta_attachmentemailid ON MetaAttachment USING HASH (AttachmentEmailId);
+
+-- --------------------------------------------------------------
+
 CREATE TABLE TagJob
 (
    JobId integer not null,
index c6efe1c51c6eed440fe78568e16471d03f4f0332..f6a566d0cc419b51595403263a7c3ef0412ba682 100644 (file)
@@ -653,11 +653,29 @@ static void update_attribute(JCR *jcr, char *msg, int32_t msglen)
       }
 
    } else if (Stream == STREAM_PLUGIN_META_CATALOG) {
-      //TODO add storing values inside proper catalog table here instead of dummy print
+      Dmsg1(50, "Getting STREAM_PLUGIN_META_CATALOG %d\n", FileIndex);
       meta_pkt mp(p);
-      Dmsg1(100, "[metadata plugin] type: %d\n", mp.type);
-      Dmsg1(100, "[metadata plugin] buffer len: %d\n", mp.buf_len);
-      Dmsg2(100, "[metadata plugin] buf: %.*s\n", mp.buf_len, mp.buf);
+      META_JSON parser;
+      POOL_MEM val;
+      Dmsg3(50, "[metadata plugin] type=%d len=%d buf=[%.*s]\n", mp.type, mp.buf_len, mp.buf);
+      if (parser.parse(jcr,
+                       jcr->db,
+                       jcr->wjcr? jcr->wjcr->JobId : jcr->JobId,
+                       FileIndex,
+                       (char *)mp.buf, mp.buf_len,
+                       val.handle()))
+      {
+         db_lock(jcr->db);
+         if (!db_sql_query(jcr->db, val.c_str(), NULL, NULL)) {
+            // TODO: Make sure the SQL query is correct, else the transaction will fail
+            Jmsg(jcr, M_FATAL, 0, _("Unable to insert Plugin metadata for FileIndex %lld. ERR=%s\n"), (int64_t)FileIndex, jcr->db->errmsg);
+            Dmsg1(50, "Unable to parse Plugin metadata err=%s\n", val.c_str());
+         }
+         db_unlock(jcr->db);
+      } else {
+         Jmsg1(jcr, M_ERROR, 0, _("Unable to parse Plugin metadata for FileIndex %lld\n"), (int64_t)FileIndex);
+         Dmsg1(50, "Unable to parse Plugin metadata err=%s\n", val.c_str());
+      }
 
    } else if (Stream == STREAM_RESTORE_OBJECT) {
       ROBJECT_DBR ro;
@@ -848,7 +866,7 @@ bool despool_attributes_from_file(JCR *jcr, const char *file)
       berrno be;
       Qmsg1(jcr, M_FATAL, 0, _("fread attr spool error. ERR=%s\n"),
             be.bstrerror());
-      Dmsg1(050, "fread attr spool error. ERR=%s\n", be.bstrerror());
+      Dmsg1(50, "fread attr spool error. ERR=%s\n", be.bstrerror());
       goto bail_out;
    }
    ret = true;
index aeaff3c02ed51aeaab53b94ace265b6ccae33a2a..ecf323e354f41a17dc1cc37a54c91ad36ce7aa73 100644 (file)
@@ -336,7 +336,10 @@ bail_out:
  *  list objects [type=objecttype job_id=id clientname=n,status=S] - list plugin objects
  *  list pluginrestoreconf jobid=x,y,z [id=k]
  *  list filemedia jobid=x fileindex=z
+ *  list metadata type=email [search=<str> where=<from|to|cc|tags|subject|bodypreview|attachement> importance=<str> isread=<yes|no> isdraft=<yes|no> hasattachement=<yes|no> limit=<int> offset=<int> receivedtime=<time> senttime=<time> order=<asc|desc>]
  *
+ *  list metadata type=email where="(EmailFrom ILIKE '%test%' OR EmailTo ILIKE '%test%' OR EmailCc ILIKE '%test%') AND EmailReceivedtime > '2021-09-01 00:00:00'" limit=10
+ *  
  *  Note: keyword "long" is before the first command on the command 
  *    line results in doing a llist (long listing).
  */
index 1b21e688580ccf008077aa0b42b96faa20e9e625..8fcc986cf19c960216a9a85debb184541a321545 100644 (file)
@@ -264,6 +264,7 @@ bool metadata_save(JCR *jcr, const plugin_metadata *plug_meta)
       /* Send stream header */
       switch (mp->type) {
          case plugin_meta_blob:
+            Dmsg1(50, "Sending STREAM_PLUGIN_META_BLOB %d\n", jcr->JobFiles);
             stat = sd->fsend("%ld %d 0", jcr->JobFiles, STREAM_PLUGIN_META_BLOB);
             if (!stat) {
                if (!jcr->is_canceled() && !jcr->is_incomplete()) {
@@ -274,6 +275,7 @@ bool metadata_save(JCR *jcr, const plugin_metadata *plug_meta)
             }
             break;
          case plugin_meta_catalog_email:
+            Dmsg1(50, "Sending STREAM_PLUGIN_META_CATALOG %d\n", jcr->JobFiles);
             stat = sd->fsend("%ld %d 0", jcr->JobFiles, STREAM_PLUGIN_META_CATALOG);
             if (!stat) {
                if (!jcr->is_canceled() && !jcr->is_incomplete()) {
index 42458205619a605760f65c05fc612882241a1d47..c40f452afc96e51ff531cd2cbb4007dbd2027106 100644 (file)
@@ -62,7 +62,7 @@ LIBBAC_SRCS = attr.c base64.c base32.c berrno.c bsys.c binflate.c bget_msg.c \
       util.c var.c watchdog.c workq.c btimers.c \
       worker.c flist.c bcollector.c collect.c \
       address_conf.c breg.c htable.c lockmgr.c devlock.c output.c bwlimit.c \
-      bsock_meeting.c bcrc32.c events.c ilist.c $(EXTRA_SRCS)
+      bsock_meeting.c bcrc32.c events.c ilist.c cJSON.c cJSON_Utils.c $(EXTRA_SRCS)
 
 LIBBAC_OBJS_TMP = $(LIBBAC_SRCS:.c=.o)
 LIBBAC_OBJS = $(LIBBAC_OBJS_TMP:.cc=.o)
index e2ff725b0d1fc5ad6d72287ea89683bb732348b4..c1dd5cabc51e676302ce8e89519bab7d6e952aec 100644 (file)
@@ -720,20 +720,9 @@ static bRC startBackupFile(bpContext *ctx, struct save_pkt *sp)
          }";
 
          /*TODO change payload to catalog packet when it's defined*/
-         const char *m2 = "{\n   \"EmailBodyPreview\" : \"pretium sollicitudin vocent vulputate te semper partiendo mi cu consectetur antiopam commodo nominavi facilis iaculis montes veniam congue vitae eam ponderum idque doctus condimentum patrioque epicurei amet nominavi possit ancillae quo bibendum definition\",\n   \"EmailCc\" : \"\",\n   \"EmailConversationId\" : \"AAQkAGZmZjBlMjI0LTMxMmEtNDFkMi1hM2YxLWEzNjI5MjY4M2JkMQAQAE9i5o-JJZ5HvgNdGUT4uEA=\",\n   \"EmailFolderName\" : \"jorgegea/users/jonis@jorgegea.onmicrosoft.com/email/REGRESS_20210915123756\",\n   \"EmailFrom\" : \"eric@bacula\",\n   \"EmailHasAttachment\" : 0,\n   \"EmailId\" : \"AAMkAGZmZjBlMjI0LTMxMmEtNDFkMi1hM2YxLWEzNjI5MjY4M2JkMQBGAAAAAAChUr1sDFmcSYm7PK3nvLVxBwB-S4yOymgVRpR5CA4-eilAAABABKyCAAB-S4yOymgVRpR5CA4-eilAAABABPgVAAA=\",\n   \"EmailImportance\" : \"NORMAL\",\n   \"EmailInternetMessageId\" : \"<AM9P190MB144311378E81EB6E8400641689DB9@AM9P190MB1443.EURP190.PROD.OUTLOOK.COM>\",\n   \"EmailIsDraft\" : 0,\n   \"EmailIsRead\" : 1,\n   \"EmailTime\" : \"Sep 15, 2021, 12:39:19 PM\",\n   \"EmailOwner\" : \"xxxx\",\n \"EmailSize\" : 4096,\n \"EmailTenant\": \"xxxx\",\n  \"EmailSubject\" : \"Elaboraret Tellus - t\",\n   \"EmailTags\" : \"\",\n   \"EmailTo\" : \"jorge@bacula\",\n   \"Plugin\" : \"m365\",\n   \"Type\" : \"EMAIL\",\n   \"Version\" : 1\n }";
-
-         const char *m3 = "{\n \"AttachmentOwner\" : \"xxxx\", \"AttachmentTenant\" : \"xxxx\", \"AttachmentContentType\" : \"application/octet-stream\",\n   \"AttachmentEmailId\" : \"AAMkAGZmZjBlMjI0LTMxMmEtNDFkMi1hM2YxLWEzNjI5MjY4M2JkMQBGAAAAAAChUr1sDFmcSYm7PK3nvLVxBwB-S4yOymgVRpR5CA4-eilAAABABKybAAB-S4yOymgVRpR5CA4-eilAAABABUnfAAA=\",\n   \"AttachmentId\" : \"AAMkAGZmZjBlMjI0LTMxMmEtNDFkMi1hM2YxLWEzNjI5MjY4M2JkMQBGAAAAAAChUr1sDFmcSYm7PK3nvLVxBwB-S4yOymgVRpR5CA4-eilAAABABKybAAB-S4yOymgVRpR5CA4-eilAAABABUnfAAABEgAQAKT86cEi1S9PgA8I5xS0vKA=\",\n   \"AttachmentIsInline\" : 0,\n   \"AttachmentName\" : \"Ancillae.gen\",\n  \"AttachmentSize\" : 81920,\n   \"Plugin\" : \"m365\",\n   \"Type\" : \"ATTACHMENT\",\n   \"Version\" : 1\n}";
-
-         /* Send some huge packet to test the limits.
-          * Currently max packet size is 3MB (it's size of buf and all of the meta_pkt fields being sent),
-          * here we are sending 2,8MB just to be a bit below */
-         uint32_t m4_size = 2800000;
-         void *m4 = malloc(m4_size);
-
+         const char *m2 = "{\n   \"EmailBodyPreview\" : \"pretium sollicitudin vocent vulputate te semper partiendo mi cu consectetur antiopam commodo nominavi facilis iaculis montes veniam congue vitae eam ponderum idque doctus condimentum patrioque epicurei amet nominavi possit ancillae quo bibendum definition\",\n   \"EmailCc\" : \"\",\n   \"EmailConversationId\" : \"AAQkAGZmZjBlMjI0LTMxMmEtNDFkMi1hM2YxLWEzNjI5MjY4M2JkMQAQAE9i5o-JJZ5HvgNdGUT4uEA=\",\n   \"EmailFolderName\" : \"jorgegea/users/jonis@jorgegea.onmicrosoft.com/email/REGRESS_20210915123756\",\n   \"EmailFrom\" : \"eric@bacula\",\n   \"EmailHasAttachment\" : 0,\n   \"EmailId\" : \"AAMkAGZmZjBlMjI0LTMxMmEtNDFkMi1hM2YxLWEzNjI5MjY4M2JkMQBGAAAAAAChUr1sDFmcSYm7PK3nvLVxBwB-S4yOymgVRpR5CA4-eilAAABABKyCAAB-S4yOymgVRpR5CA4-eilAAABABPgVAAA=\",\n   \"EmailImportance\" : \"NORMAL\",\n   \"EmailInternetMessageId\" : \"<AM9P190MB144311378E81EB6E8400641689DB9@AM9P190MB1443.EURP190.PROD.OUTLOOK.COM>\",\n   \"EmailIsDraft\" : 0,\n   \"EmailIsRead\" : 1,\n   \"EmailReceivedTime\" : \"Sep 15, 2021, 12:39:19 PM\",\n   \"EmailSentTime\" : \"Sep 15, 2021, 12:39:19 PM\",\n   \"EmailSubject\" : \"Elaboraret Tellus - t\",\n   \"EmailTags\" : \"\",\n   \"EmailTo\" : \"jorge@bacula\",\n   \"Plugin\" : \"m365\",\n   \"Type\" : \"EMAIL\",\n   \"Version\" : 1\n }";
          p_ctx->meta_mgr->add_packet(plugin_meta_blob, strlen(m1)+1, (void *)m1);
          p_ctx->meta_mgr->add_packet(plugin_meta_catalog_email, strlen(m2)+1, (void *)m2);
-         p_ctx->meta_mgr->add_packet(plugin_meta_catalog_email, strlen(m3)+1, (void *)m3);
-         p_ctx->meta_mgr->add_packet(plugin_meta_blob, m4_size, m4);
 
          sp->plug_meta = p_ctx->meta_mgr;
          Dmsg0(0, "Insert metadata!!!!!!\n");