From: Radosław Korzeniewski Date: Fri, 2 Jul 2021 07:23:21 +0000 (+0200) Subject: metaplugin: Add RestoreObject support. X-Git-Tag: Release-11.3.2~442 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=74d14f7ff41067ae60b0b58a4ec62cc5aacc31b5;p=thirdparty%2Fbacula.git metaplugin: Add RestoreObject support. With this patch the backend can handle Restore Object save and receive. --- diff --git a/bacula/src/plugins/fd/pluginlib/metaplugin.cpp b/bacula/src/plugins/fd/pluginlib/metaplugin.cpp index bc4629540..0640e995c 100644 --- a/bacula/src/plugins/fd/pluginlib/metaplugin.cpp +++ b/bacula/src/plugins/fd/pluginlib/metaplugin.cpp @@ -376,17 +376,19 @@ bRC METAPLUGIN::parse_plugin_command(bpContext *ctx, const char *command, alist * bRC_OK - on success * bRC_Error - on error */ -bRC METAPLUGIN::parse_plugin_restoreobj(bpContext *ctx, restore_object_pkt *rop) +bRC METAPLUGIN::handle_plugin_restoreobj(bpContext *ctx, restore_object_pkt *rop) { if (!rop){ return bRC_OK; /* end of rop list */ } - if (!strcmp(rop->object_name, INI_RESTORE_OBJECT_NAME)) { - /* we have a single RO for every backend */ - backend.switch_command(rop->plugin_name); + /* we have a single RO for every backend */ + backend.switch_command(rop->plugin_name); - DMSG(ctx, DINFO, "INIcmd: %s\n", rop->plugin_name); + // if (strcmp(rop->object_name, INI_RESTORE_OBJECT_NAME) == 0) { + if (strcmp(rop->object_name, INI_RESTORE_OBJECT_NAME) == 0 && rop->object_type == FT_PLUGIN_CONFIG) { + + DMSG2(ctx, DINFO, "INIcmd: %s %d\n", rop->plugin_name, rop->object_type); ini.clear_items(); if (!ini.dump_string(rop->object, rop->object_len)) @@ -404,8 +406,7 @@ bRC METAPLUGIN::parse_plugin_restoreobj(bpContext *ctx, restore_object_pkt *rop) return bRC_Error; } - for (int i=0; ini.items[i].name; i++) - { + for (int i = 0; ini.items[i].name; i++) { if (ini.items[i].found){ if (ini.items[i].handler == ini_store_str){ DMSG2(ctx, DINFO, "INI: %s = %s\n", ini.items[i].name, ini.items[i].val.strval); @@ -422,8 +423,20 @@ bRC METAPLUGIN::parse_plugin_restoreobj(bpContext *ctx, restore_object_pkt *rop) } } } + + return bRC_OK; } + // handle any other RO restore + restore_object_class *ropclass = new restore_object_class; + ropclass->sent = false; + pm_strcpy(ropclass->plugin_name, rop->plugin_name); + pm_strcpy(ropclass->object_name, rop->object_name); + ropclass->length = rop->object_len; + pm_memcpy(ropclass->data, rop->object, rop->object_len); + restoreobject_list.append(ropclass); + DMSG2(ctx, DINFO, "ROclass saved for later: %s %d\n", ropclass->object_name.c_str(), ropclass->length); + return bRC_OK; } @@ -1242,7 +1255,7 @@ bRC METAPLUGIN::handlePluginEvent(bpContext *ctx, bEvent *event, void *value) /* Plugin command e.g. plugin = :parameters */ case bEventBackupCommand: DMSG(ctx, D2, "bEventBackupCommand value=%s\n", NPRT((char *)value)); - robjsent = false; + pluginconfigsent = false; return prepare_backend(ctx, BACKEND_JOB_INFO_BACKUP, (char*)value); /* Plugin command e.g. plugin = :parameters */ @@ -1285,7 +1298,7 @@ bRC METAPLUGIN::handlePluginEvent(bpContext *ctx, bEvent *event, void *value) break; } DMSG(ctx, D2, "bEventRestoreObject value=%p\n", value); - return parse_plugin_restoreobj(ctx, (restore_object_pkt *) value); + return handle_plugin_restoreobj(ctx, (restore_object_pkt *) value); case bEventCancelCommand: DMSG2(ctx, D3, "bEventCancelCommand self = %p pctx = %p\n", this, pctx); @@ -1690,7 +1703,8 @@ bRC METAPLUGIN::perform_read_metadata(bpContext *ctx) DMSG0(ctx, DDEBUG, "perform_read_metadata()\n"); // setup flags - nextfile = pluginobject = readacl = readxattr = false; + nextfile = readacl = readxattr = false; + objectsent = false; // loop on metadata from backend or EOD which means no more files to backup while (true) { @@ -1700,12 +1714,21 @@ bRC METAPLUGIN::perform_read_metadata(bpContext *ctx) if (scan_parameter_str(cmd, "FNAME:", fname)){ /* got FNAME: */ nextfile = true; + object = FileObject; return bRC_OK; } if (scan_parameter_str(cmd, "PLUGINOBJ:", fname)){ /* got Plugin Object header */ nextfile = true; - pluginobject = true; + object = PluginObject; + // pluginobject = true; + return bRC_OK; + } + if (scan_parameter_str(cmd, "RESTOREOBJ:", fname)){ + /* got Restore Object header */ + nextfile = true; + object = RestoreObject; + // restoreobject = true; return bRC_OK; } if (bstrcmp(cmd.c_str(), "ACL")){ @@ -1761,9 +1784,9 @@ bRC METAPLUGIN::perform_file_index_query(bpContext *ctx) /** * @brief * - * @param ctx - * @param sp - * @return bRC + * @param ctx bpContext - for Bacula debug and jobinfo messages + * @param sp save_pkt from startBackupFile() + * @return bRC bRC_OK when success, bRC_Error if not */ bRC METAPLUGIN::perform_read_pluginobject(bpContext *ctx, struct save_pkt *sp) { @@ -1835,8 +1858,9 @@ bRC METAPLUGIN::perform_read_pluginobject(bpContext *ctx, struct save_pkt *sp) if (backend.ctx->is_eod()){ /* no more plugin object params to backup */ DMSG0(ctx, DINFO, "No more Plugin Object params from backend.\n"); - pluginobject = false; - pluginobjectsent = true; + // pluginobject = false; + // pluginobjectsent = true; + objectsent = true; return bRC_OK; } } @@ -1845,6 +1869,75 @@ bRC METAPLUGIN::perform_read_pluginobject(bpContext *ctx, struct save_pkt *sp) return bRC_Error; } +/** + * @brief Receives a Restore Object data and populates save_pkt. + * + * @param ctx bpContext - for Bacula debug and jobinfo messages + * @param sp save_pkt from startBackupFile() + * @return bRC bRC_OK when success, bRC_Error if not + */ +bRC METAPLUGIN::perform_read_restoreobject(bpContext *ctx, struct save_pkt *sp) +{ + POOL_MEM cmd(PM_FNAME); + + sp->restore_obj.object = NULL; + + if (strlen(fname.c_str()) == 0){ + // input variable is not valid + return bRC_Error; + } + + DMSG0(ctx, DDEBUG, "perform_read_restoreobject()\n"); + // read object length required param + if (backend.ctx->read_command(ctx, cmd) > 0) { + DMSG(ctx, DDEBUG, "read_command(4): %s\n", cmd.c_str()); + POOL_MEM param(PM_NAME); + uint64_t length; + if (scan_parameter_str(cmd, "RESTOREOBJ_LEN:", param)) { + if (!size_to_uint64(param.c_str(), strlen(param.c_str()), &length)){ + // error in convert + DMSG1(ctx, DERROR, "Cannot convert Restore Object length to integer! p=%s\n", param.c_str()); + JMSG1(ctx, M_ERROR, "Cannot convert Restore Object length to integer! p=%s\n", param.c_str()); + return bRC_Error; + } + DMSG1(ctx, DDEBUG, "size: %llu\n", length); + sp->restore_obj.object_len = length; + robjbuf.check_size(length + 1); + } else { + // no required param + DMSG0(ctx, DERROR, "Cannot read Restore Object length!\n"); + JMSG0(ctx, M_ERROR, "Cannot read Restore Object length!\n"); + return bRC_Error; + } + } else { + if (backend.ctx->is_fatal()){ + /* raise up error from backend */ + return bRC_Error; + } + } + + int32_t recv_len = 0; + + if (backend.ctx->recv_data(ctx, robjbuf, &recv_len) != bRC_OK) { + DMSG0(ctx, DERROR, "Cannot read data from backend!\n"); + return bRC_Error; + } + + /* no more restore object data to backup */ + DMSG0(ctx, DINFO, "No more Restore Object data from backend.\n"); + objectsent = true; + + if (recv_len != sp->restore_obj.object_len) { + DMSG2(ctx, DERROR, "Backend reported RO length:%ld read:%ld\n", sp->restore_obj.object_len, recv_len); + JMSG2(ctx, M_ERROR, "Backend reported RO length:%ld read:%ld\n", sp->restore_obj.object_len, recv_len); + sp->restore_obj.object_len = recv_len; + } + + sp->restore_obj.object = robjbuf.c_str(); + + return bRC_OK; +} + /* * Handle Bacula Plugin I/O API for backend * @@ -1988,14 +2081,14 @@ bRC METAPLUGIN::startBackupFile(bpContext *ctx, struct save_pkt *sp) } /* The first file in Full backup, is the RestoreObject */ - if (!estimate && mode == BACKUP_FULL && robjsent == false) { + if (!estimate && mode == BACKUP_FULL && pluginconfigsent == false) { ConfigFile ini; ini.register_items(plugin_items_dump, sizeof(struct ini_items)); sp->restore_obj.object_name = (char *)INI_RESTORE_OBJECT_NAME; sp->restore_obj.object_len = ini.serialize(robjbuf.c_str()); sp->restore_obj.object = robjbuf.c_str(); sp->type = FT_PLUGIN_CONFIG; - DMSG0(ctx, DINFO, "Prepared RestoreObject sent.\n"); + DMSG2(ctx, DINFO, "Prepared RestoreObject/%s (%d) sent.\n", INI_RESTORE_OBJECT_NAME, FT_PLUGIN_CONFIG); return bRC_OK; } @@ -2017,8 +2110,36 @@ bRC METAPLUGIN::startBackupFile(bpContext *ctx, struct save_pkt *sp) DMSG(ctx, DINFO, "fname:%s\n", fname.c_str()); sp->fname = fname.c_str(); - if (!pluginobject){ - // here we handle metadata information + switch (object) + { + case RestoreObject: + // handle Restore Object parameters and data + if (perform_read_restoreobject(ctx, sp) != bRC_OK) { + // signal error + return bRC_Error; + } + sp->restore_obj.object_name = fname.c_str(); + sp->type = FT_RESTORE_FIRST; + size = sp->restore_obj.object_len; + sp->statp.st_mode = 0700 | S_IFREG; + { + time_t now = time(NULL); + sp->statp.st_ctime = now; + sp->statp.st_mtime = now; + sp->statp.st_atime = now; + } + break; + case PluginObject: + // handle Plugin Object parameters + if (perform_read_pluginobject(ctx, sp) != bRC_OK) { + // signal error + return bRC_Error; + } + sp->type = FT_PLUGIN_OBJECT; + size = sp->plugin_obj.object_size; + break; + default: + // here we handle standard file metadata information reqparams--; // ensure clear state for metadatas @@ -2131,14 +2252,7 @@ bRC METAPLUGIN::startBackupFile(bpContext *ctx, struct save_pkt *sp) return bRC_Error; } - } else { - // handle Plugin Object parameters - if (perform_read_pluginobject(ctx, sp) != bRC_OK) { - // signal error - return bRC_Error; - } - sp->type = FT_PLUGIN_OBJECT; - size = sp->plugin_obj.object_size; + break; } if (backend.ctx->is_error()) { @@ -2182,16 +2296,16 @@ bRC METAPLUGIN::endBackupFile(bpContext *ctx) if (!estimate){ /* The current file was the restore object, so just ask for the next file */ - if (mode == BACKUP_FULL && robjsent == false) { - robjsent = true; + if (mode == BACKUP_FULL && pluginconfigsent == false) { + pluginconfigsent = true; return bRC_More; } } // check for next file only when no previous error if (!openerror) { - if (estimate || pluginobjectsent) { - pluginobjectsent = false; + if (estimate || objectsent) { + objectsent = false; if (perform_read_metadata(ctx) != bRC_OK) { /* signal error */ return bRC_Error; @@ -2212,6 +2326,38 @@ bRC METAPLUGIN::endBackupFile(bpContext *ctx) */ bRC METAPLUGIN::startRestoreFile(bpContext *ctx, const char *cmd) { + if (restoreobject_list.size() > 0) { + restore_object_class *ropclass; + POOL_MEM backcmd(PM_FNAME); + + foreach_alist(ropclass, &restoreobject_list) { + if (!ropclass->sent && strcmp(cmd, ropclass->plugin_name.c_str()) == 0) { + + Mmsg(backcmd, "RESTOREOBJ:%s\n", ropclass->object_name.c_str()); + DMSG1(ctx, DINFO, "%s", backcmd.c_str()); + ropclass->sent = true; + + if (backend.ctx->write_command(ctx, backcmd.c_str()) < 0) + { + DMSG0(ctx, DERROR, "Error sending RESTOREOBJ command\n"); + return bRC_Error; + } + + Mmsg(backcmd, "RESTOREOBJ_LEN:%d\n", ropclass->length); + if (backend.ctx->write_command(ctx, backcmd.c_str()) < 0) { + DMSG0(ctx, DERROR, "Error sending RESTOREOBJ_LEN command\n"); + return bRC_Error; + } + + /* send data */ + if (backend.ctx->send_data(ctx, ropclass->data.c_str(), ropclass->length) != bRC_OK) { + DMSG0(ctx, DERROR, "Error sending RestoreObject data\n"); + return bRC_Error; + } + } + } + } + return bRC_OK; } diff --git a/bacula/src/plugins/fd/pluginlib/metaplugin.h b/bacula/src/plugins/fd/pluginlib/metaplugin.h index b74658d43..6aee4b1f8 100644 --- a/bacula/src/plugins/fd/pluginlib/metaplugin.h +++ b/bacula/src/plugins/fd/pluginlib/metaplugin.h @@ -28,10 +28,9 @@ #include "pluginlib.h" #include "ptcomm.h" -#include "smartmutex.h" #include "lib/ini.h" -#include "pluginlib/commctx.h" -#include "pluginlib/smartalist.h" +#include "commctx.h" +#include "smartalist.h" #define USE_CMD_PARSER @@ -83,6 +82,16 @@ extern const char *valid_params[]; // custom checkFile() callback extern checkFile_t checkFile; +// a simple ro buf class +struct restore_object_class +{ + POOL_MEM plugin_name; + POOL_MEM object_name; + POOL_MEM data; + int32_t length; + bool sent; +}; + /* * This is a main plugin API class. It manages a plugin context. * All the public methods correspond to a public Bacula API calls, even if @@ -137,14 +146,17 @@ public: where(NULL), regexwhere(NULL), replace(0), - robjsent(false), + pluginconfigsent(false), estimate(false), listing(None), nodata(false), nextfile(false), openerror(false), - pluginobject(false), - pluginobjectsent(false), + object(FileObject), + objectsent(false), + // pluginobject(false), + // pluginobjectsent(false), + // restoreobject(false), readacl(false), readxattr(false), skipextract(false), @@ -162,8 +174,9 @@ public: acldata(PM_MESSAGE), xattrdatalen(0), xattrdata(PM_MESSAGE), - metadatas_list(10, true), - prevjobname(NULL) + metadatas_list(10, owned_by_alist), + prevjobname(NULL), + restoreobject_list() {} #if __cplusplus > 201103L METAPLUGIN(METAPLUGIN&) = delete; @@ -172,6 +185,12 @@ public: ~METAPLUGIN() {} private: + enum OBJECT + { + FileObject, + PluginObject, + RestoreObject, + }; enum LISTING { None, @@ -190,14 +209,17 @@ private: char *where; // the Where variable for restore job if set by user char *regexwhere; // the RegexWhere variable for restore job if set by user char replace; // the replace variable for restore job - bool robjsent; // set when RestoreObject was sent during Full backup + bool pluginconfigsent; // set when RestoreObject/INI_RESTORE_OBJECT_NAME_FT_PLUGIN_CONFIG was sent during Full backup bool estimate; // used when mode is METAPLUGIN_BACKUP_* but we are doing estimate only LISTING listing; // used for a Listing procedure for estimate bool nodata; // set when backend signaled no data for backup or no data for restore bool nextfile; // set when IO_CLOSE got FNAME: command bool openerror; // show if "openfile" was unsuccessful - bool pluginobject; // set when IO_CLOSE got FNAME: command - bool pluginobjectsent; // set when startBackupFile handled plugin object and endBackupFile has to check for nextfile + OBJECT object; // + bool objectsent; // set when startBackupFile handled object and endBackupFile has to check for nextfile + // bool pluginobject; // set when got PLUGINOBJ: command + // bool pluginobjectsent; // set when startBackupFile handled plugin object and endBackupFile has to check for nextfile + // bool restoreobject; // set when got RESTOREOBJ: command bool readacl; // got ACL data from backend bool readxattr; // got XATTR data from backend bool skipextract; // got SKIP response from backend, so we should artificially skip it for backend @@ -218,12 +240,14 @@ private: POOL_MEM xattrdata; // the buffer for XATTR data received from backend cmd_parser parser; // Plugin command parser ConfigFile ini; // Restore ini file handler - alist metadatas_list; // - plugin_metadata metadatas; // + alist metadatas_list; // a list if managed metadatas + plugin_metadata metadatas; // the private metadata class const char *prevjobname; // this is a bVarPrevJobName parameter if requested + // a list of received RO from bacula which we will use to feed into backend later + smart_alist restoreobject_list; bRC parse_plugin_command(bpContext *ctx, const char *command, alist *params); - bRC parse_plugin_restoreobj(bpContext *ctx, restore_object_pkt *rop); + bRC handle_plugin_restoreobj(bpContext *ctx, restore_object_pkt *rop); bRC run_backend(bpContext *ctx); bRC send_parameters(bpContext *ctx, char *command); bRC send_jobinfo(bpContext *ctx, char type); @@ -243,6 +267,7 @@ private: bRC perform_read_metadata(bpContext *ctx); bRC perform_read_fstatdata(bpContext *ctx, struct save_pkt *sp); bRC perform_read_pluginobject(bpContext *ctx, struct save_pkt *sp); + bRC perform_read_restoreobject(bpContext *ctx, struct save_pkt *sp); bRC perform_read_acl(bpContext *ctx); bRC perform_write_acl(bpContext *ctx, const xacl_pkt * xacl); bRC perform_read_xattr(bpContext *ctx); diff --git a/bacula/src/plugins/fd/pluginlib/ptcomm.cpp b/bacula/src/plugins/fd/pluginlib/ptcomm.cpp index 2d83d183e..4699df979 100644 --- a/bacula/src/plugins/fd/pluginlib/ptcomm.cpp +++ b/bacula/src/plugins/fd/pluginlib/ptcomm.cpp @@ -583,7 +583,7 @@ int32_t PTCOMM::recvbackend_fixed(bpContext *ctx, char cmd, char *buf, int32_t b * -1 - when encountered any error * - the number of bytes sent, success */ -int32_t PTCOMM::sendbackend(bpContext *ctx, char cmd, POOLMEM *buf, int32_t len) +int32_t PTCOMM::sendbackend(bpContext *ctx, char cmd, const char *buf, int32_t len) { int status; PTHEADER *header; @@ -595,7 +595,7 @@ int32_t PTCOMM::sendbackend(bpContext *ctx, char cmd, POOLMEM *buf, int32_t len) return -1; } - if (len > 999999){ + if (len > PTCOMM_MAX_PACKET_SIZE){ /* message length too long, cannot send it */ DMSG(ctx, DERROR, "Message length %i too long, cannot send data.\n", len); JMSG(ctx, M_FATAL, "Message length %i too long, cannot send data.\n", len); @@ -806,7 +806,7 @@ bool PTCOMM::read_ack(bpContext *ctx) * -1 - when encountered any error * - the number of bytes sent, success */ -int32_t PTCOMM::write_command(bpContext *ctx, POOLMEM *buf) +int32_t PTCOMM::write_command(bpContext *ctx, const char *buf) { int32_t len; len = buf ? strlen(buf) : 0; @@ -825,7 +825,7 @@ int32_t PTCOMM::write_command(bpContext *ctx, POOLMEM *buf) * -1 - when encountered any error * - the number of bytes sent, success */ -int32_t PTCOMM::write_data(bpContext *ctx, POOLMEM *buf, int32_t len) +int32_t PTCOMM::write_data(bpContext *ctx, const char *buf, int32_t len) { int32_t status; @@ -903,3 +903,73 @@ bool PTCOMM::handshake(bpContext *ctx, const char *pluginname, const char * plug return false; } + +/** + * @brief Sends a single stream of data to backend read from a buf. + * + * @param ctx bpContext - for Bacula debug and jobinfo messages + * @param buf a buffer to read a data to send + * @param len a lengtho of the data to send + * @return bRC bRC_OK when successful, bRC_Error otherwise + */ +bRC PTCOMM::send_data(bpContext *ctx, const char *buf, int32_t len) +{ + /* send data */ + int32_t offset = 0; + + while (offset < len) + { + int32_t count = MIN(len - offset, PTCOMM_MAX_PACKET_SIZE); + int32_t status = write_data(ctx, buf + offset, count); + if (status < 0) { + /* got some error */ + return bRC_Error; + } + offset += status; + } + + /* signal end of data to restore and get ack */ + if (!send_ack(ctx)) { + return bRC_Error; + } + + return bRC_OK; +} + +/** + * @brief Receives a single stream of data from backend and saves it at buf. + * For a good performance it is expected that `buf` will be preallocated + * for the expected size of the stream. + * + * @param ctx bpContext - for Bacula debug and jobinfo messages + * @param buf a buffer to save received data + * @param recv_len a number of bytes saved at buf + * @return bRC bRC_OK when successful, bRC_Error otherwise + */ +bRC PTCOMM::recv_data(bpContext *ctx, POOL_MEM &buf, int32_t *recv_len) +{ + POOL_MEM cmd(PM_MESSAGE); + int32_t offset = 0; + + // loop on data from backend and EOD + while (!is_eod()) + { + int32_t status = read_data(ctx, cmd); + if (status > 0) { + buf.check_size(offset + status); // it should be preallocated + memcpy(buf.c_str() + offset, cmd.c_str(), status); + offset += status; + } else { + if (is_fatal()){ + /* raise up error from backend */ + return bRC_Error; + } + } + } + + if (recv_len != NULL) { + *recv_len = offset; + } + + return bRC_OK; +} diff --git a/bacula/src/plugins/fd/pluginlib/ptcomm.h b/bacula/src/plugins/fd/pluginlib/ptcomm.h index 0176c0347..3e3fcc412 100644 --- a/bacula/src/plugins/fd/pluginlib/ptcomm.h +++ b/bacula/src/plugins/fd/pluginlib/ptcomm.h @@ -34,6 +34,8 @@ #define PTCOMM_DEFAULT_TIMEOUT 3600 // timeout waiting for data is 1H as some backends could spent it doing real work // TODO: I think we should move it to plugin configurable variable instead of a const +#define PTCOMM_MAX_PACKET_SIZE 999999 + /* * The protocol packet header. * Every packet exchanged between Plugin and Backend will have a special header @@ -96,7 +98,7 @@ protected: int32_t recvbackend(bpContext *ctx, char *cmd, POOL_MEM &buf, bool any=false); int32_t recvbackend_fixed(bpContext *ctx, char cmd, char *buf, int32_t bufsize); - int32_t sendbackend(bpContext *ctx, char cmd, POOLMEM *buf, int32_t len); + int32_t sendbackend(bpContext *ctx, char cmd, const char *buf, int32_t len); public: PTCOMM(const char * command = NULL) : @@ -128,7 +130,10 @@ public: int32_t read_data(bpContext *ctx, POOL_MEM &buf); int32_t read_data_fixed(bpContext *ctx, char *buf, int32_t len); - int32_t write_command(bpContext *ctx, char *buf); + int32_t write_command(bpContext *ctx, const char *buf); + + bRC send_data(bpContext *ctx, const char *buf, int32_t len); + bRC recv_data(bpContext *ctx, POOL_MEM &buf, int32_t *recv_len=NULL); /** * @brief Sends a command to the backend. @@ -140,7 +145,7 @@ public: * - the number of bytes sent, success */ int32_t write_command(bpContext *ctx, POOL_MEM &buf) { return write_command(ctx, buf.addr()); } - int32_t write_data(bpContext *ctx, char *buf, int32_t len); + int32_t write_data(bpContext *ctx, const char *buf, int32_t len); bool read_ack(bpContext *ctx); bool send_ack(bpContext *ctx); diff --git a/bacula/src/plugins/fd/pluginlib/test_metaplugin_backend.c b/bacula/src/plugins/fd/pluginlib/test_metaplugin_backend.c index d6e1a3bf7..d9aaef2d8 100644 --- a/bacula/src/plugins/fd/pluginlib/test_metaplugin_backend.c +++ b/bacula/src/plugins/fd/pluginlib/test_metaplugin_backend.c @@ -211,14 +211,14 @@ void write_plugin(const char cmd, const char *str) * @param cmd the packet type to sent * @param str the text to write */ -void write_plugin_bin(const char *str, int len = 0) +void write_plugin_bin(const unsigned char *str, int len = 0) { - const char * out; + const unsigned char * out; if (str) { out = str; } else { - out = ""; + out = (const unsigned char*)""; } printf("D%06d\n", len); @@ -261,6 +261,342 @@ static void catch_function(int signo) jobcancelled = true; } +unsigned char restore_object_data[] = { + 0x61, 0x70, 0x69, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, + 0x76, 0x31, 0x0a, 0x6b, 0x69, 0x6e, 0x64, 0x3a, 0x20, 0x4e, 0x61, 0x6d, + 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x0a, 0x6d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x3a, 0x0a, 0x20, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3a, + 0x20, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x0a, + 0x2d, 0x2d, 0x2d, 0x0a, 0x61, 0x70, 0x69, 0x56, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x3a, 0x20, 0x76, 0x31, 0x0a, 0x6b, 0x69, 0x6e, 0x64, 0x3a, + 0x20, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x0a, 0x6d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x3a, 0x0a, 0x20, 0x20, 0x6e, 0x61, 0x6d, 0x65, + 0x3a, 0x20, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x74, 0x65, 0x73, 0x74, + 0x2d, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x0a, 0x20, 0x20, 0x6e, + 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x3a, 0x20, 0x70, 0x6c, + 0x75, 0x67, 0x69, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x0a, 0x20, 0x20, 0x6c, + 0x61, 0x62, 0x65, 0x6c, 0x73, 0x3a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x61, + 0x70, 0x70, 0x3a, 0x20, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x74, 0x65, + 0x73, 0x74, 0x0a, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x0a, 0x20, 0x20, 0x23, + 0x20, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x3a, 0x20, 0x62, + 0x61, 0x63, 0x75, 0x6c, 0x61, 0x0a, 0x20, 0x20, 0x23, 0x20, 0x70, 0x61, + 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x3a, 0x20, 0x70, 0x6c, 0x75, 0x67, + 0x69, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x0a, 0x20, 0x20, 0x23, 0x20, 0x73, + 0x65, 0x63, 0x72, 0x65, 0x74, 0x6b, 0x65, 0x79, 0x3a, 0x20, 0x35, 0x62, + 0x41, 0x6f, 0x56, 0x32, 0x43, 0x70, 0x7a, 0x42, 0x76, 0x68, 0x42, 0x51, + 0x5a, 0x61, 0x59, 0x55, 0x58, 0x31, 0x71, 0x59, 0x61, 0x77, 0x43, 0x30, + 0x30, 0x71, 0x68, 0x72, 0x78, 0x38, 0x63, 0x45, 0x57, 0x30, 0x66, 0x4b, + 0x31, 0x7a, 0x59, 0x6b, 0x54, 0x78, 0x56, 0x64, 0x62, 0x78, 0x66, 0x76, + 0x57, 0x4d, 0x79, 0x69, 0x30, 0x68, 0x35, 0x51, 0x62, 0x77, 0x65, 0x4a, + 0x6b, 0x71, 0x0a, 0x20, 0x20, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, + 0x65, 0x3a, 0x20, 0x59, 0x6d, 0x46, 0x6a, 0x64, 0x57, 0x78, 0x68, 0x43, + 0x67, 0x3d, 0x3d, 0x0a, 0x20, 0x20, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, + 0x72, 0x64, 0x3a, 0x20, 0x63, 0x47, 0x78, 0x31, 0x5a, 0x32, 0x6c, 0x75, + 0x64, 0x47, 0x56, 0x7a, 0x64, 0x41, 0x6f, 0x3d, 0x0a, 0x20, 0x20, 0x73, + 0x65, 0x63, 0x72, 0x65, 0x74, 0x6b, 0x65, 0x79, 0x3a, 0x20, 0x4e, 0x57, + 0x4a, 0x42, 0x62, 0x31, 0x59, 0x79, 0x51, 0x33, 0x42, 0x36, 0x51, 0x6e, + 0x5a, 0x6f, 0x51, 0x6c, 0x46, 0x61, 0x59, 0x56, 0x6c, 0x56, 0x57, 0x44, + 0x46, 0x78, 0x57, 0x57, 0x46, 0x33, 0x51, 0x7a, 0x41, 0x77, 0x63, 0x57, + 0x68, 0x79, 0x65, 0x44, 0x68, 0x6a, 0x52, 0x56, 0x63, 0x77, 0x5a, 0x6b, + 0x73, 0x78, 0x65, 0x6c, 0x6c, 0x72, 0x56, 0x48, 0x68, 0x57, 0x5a, 0x47, + 0x4a, 0x34, 0x5a, 0x6e, 0x5a, 0x58, 0x54, 0x58, 0x6c, 0x70, 0x4d, 0x47, + 0x67, 0x31, 0x55, 0x57, 0x4a, 0x33, 0x5a, 0x55, 0x70, 0x72, 0x63, 0x51, + 0x6f, 0x3d, 0x0a, 0x2d, 0x2d, 0x2d, 0x0a, 0x61, 0x70, 0x69, 0x56, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x76, 0x31, 0x0a, 0x6b, 0x69, + 0x6e, 0x64, 0x3a, 0x20, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4d, 0x61, + 0x70, 0x0a, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x0a, + 0x20, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3a, 0x20, 0x70, 0x6c, 0x75, 0x67, + 0x69, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2d, 0x63, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x6d, 0x61, 0x70, 0x0a, 0x20, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x3a, 0x20, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, + 0x74, 0x65, 0x73, 0x74, 0x0a, 0x20, 0x20, 0x6c, 0x61, 0x62, 0x65, 0x6c, + 0x73, 0x3a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x61, 0x70, 0x70, 0x3a, 0x20, + 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x0a, 0x64, + 0x61, 0x74, 0x61, 0x3a, 0x0a, 0x20, 0x20, 0x64, 0x61, 0x74, 0x61, 0x62, + 0x61, 0x73, 0x65, 0x3a, 0x20, 0x62, 0x61, 0x63, 0x75, 0x6c, 0x61, 0x0a, + 0x20, 0x20, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x68, + 0x6f, 0x73, 0x74, 0x3a, 0x20, 0x31, 0x32, 0x37, 0x2e, 0x30, 0x2e, 0x30, + 0x2e, 0x31, 0x0a, 0x20, 0x20, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, + 0x65, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x20, 0x27, 0x35, 0x34, 0x33, + 0x32, 0x27, 0x0a, 0x2d, 0x2d, 0x2d, 0x0a, 0x61, 0x70, 0x69, 0x56, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x76, 0x31, 0x0a, 0x6b, 0x69, + 0x6e, 0x64, 0x3a, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x0a, + 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x0a, 0x20, 0x20, + 0x6e, 0x61, 0x6d, 0x65, 0x3a, 0x20, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, + 0x74, 0x65, 0x73, 0x74, 0x2d, 0x73, 0x75, 0x62, 0x64, 0x6f, 0x6d, 0x61, + 0x69, 0x6e, 0x0a, 0x20, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x3a, 0x20, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x74, 0x65, + 0x73, 0x74, 0x0a, 0x20, 0x20, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x3a, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x61, 0x70, 0x70, 0x3a, 0x20, 0x70, 0x6c, + 0x75, 0x67, 0x69, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x0a, 0x73, 0x70, 0x65, + 0x63, 0x3a, 0x0a, 0x20, 0x20, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, + 0x72, 0x3a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3a, + 0x20, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x0a, + 0x20, 0x20, 0x23, 0x20, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, + 0x50, 0x3a, 0x20, 0x4e, 0x6f, 0x6e, 0x65, 0x0a, 0x20, 0x20, 0x70, 0x6f, + 0x72, 0x74, 0x73, 0x3a, 0x0a, 0x20, 0x20, 0x2d, 0x20, 0x6e, 0x61, 0x6d, + 0x65, 0x3a, 0x20, 0x66, 0x6f, 0x6f, 0x20, 0x23, 0x20, 0x41, 0x63, 0x74, + 0x75, 0x61, 0x6c, 0x6c, 0x79, 0x2c, 0x20, 0x6e, 0x6f, 0x20, 0x70, 0x6f, + 0x72, 0x74, 0x20, 0x69, 0x73, 0x20, 0x6e, 0x65, 0x65, 0x64, 0x65, 0x64, + 0x2e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x20, + 0x31, 0x32, 0x33, 0x34, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x61, 0x72, + 0x67, 0x65, 0x74, 0x50, 0x6f, 0x72, 0x74, 0x3a, 0x20, 0x31, 0x32, 0x33, + 0x34, 0x0a, 0x2d, 0x2d, 0x2d, 0x0a, 0x61, 0x70, 0x69, 0x56, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x76, 0x31, 0x0a, 0x6b, 0x69, 0x6e, + 0x64, 0x3a, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x0a, 0x6d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x0a, 0x20, 0x20, 0x6e, + 0x61, 0x6d, 0x65, 0x3a, 0x20, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x74, + 0x65, 0x73, 0x74, 0x2d, 0x6e, 0x67, 0x69, 0x6e, 0x78, 0x2d, 0x73, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x0a, 0x20, 0x20, 0x6e, 0x61, 0x6d, 0x65, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x3a, 0x20, 0x70, 0x6c, 0x75, 0x67, 0x69, + 0x6e, 0x74, 0x65, 0x73, 0x74, 0x0a, 0x20, 0x20, 0x6c, 0x61, 0x62, 0x65, + 0x6c, 0x73, 0x3a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x61, 0x70, 0x70, 0x3a, + 0x20, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2d, + 0x6e, 0x67, 0x69, 0x6e, 0x78, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x69, 0x65, 0x72, 0x3a, 0x20, + 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x0a, 0x73, 0x70, 0x65, 0x63, + 0x3a, 0x0a, 0x20, 0x20, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x3a, 0x0a, 0x20, + 0x20, 0x2d, 0x20, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x20, 0x38, 0x30, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3a, 0x20, 0x77, 0x65, + 0x62, 0x0a, 0x20, 0x20, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, + 0x50, 0x3a, 0x20, 0x4e, 0x6f, 0x6e, 0x65, 0x0a, 0x20, 0x20, 0x73, 0x65, + 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x3a, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x61, 0x70, 0x70, 0x3a, 0x20, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x74, + 0x65, 0x73, 0x74, 0x2d, 0x6e, 0x67, 0x69, 0x6e, 0x78, 0x2d, 0x77, 0x65, + 0x62, 0x0a, 0x2d, 0x2d, 0x2d, 0x0a, 0x61, 0x70, 0x69, 0x56, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x76, 0x31, 0x0a, 0x6b, 0x69, 0x6e, + 0x64, 0x3a, 0x20, 0x50, 0x65, 0x72, 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, + 0x74, 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x43, 0x6c, 0x61, 0x69, 0x6d, + 0x0a, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x0a, 0x20, + 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3a, 0x20, 0x70, 0x6c, 0x75, 0x67, 0x69, + 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2d, 0x70, 0x65, 0x72, 0x73, 0x69, 0x73, + 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x2d, + 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x0a, 0x20, 0x20, 0x6e, 0x61, 0x6d, 0x65, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x3a, 0x20, 0x70, 0x6c, 0x75, 0x67, 0x69, + 0x6e, 0x74, 0x65, 0x73, 0x74, 0x0a, 0x20, 0x20, 0x6c, 0x61, 0x62, 0x65, + 0x6c, 0x73, 0x3a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x61, 0x70, 0x70, 0x3a, + 0x20, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x0a, + 0x73, 0x70, 0x65, 0x63, 0x3a, 0x0a, 0x20, 0x20, 0x61, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x4d, 0x6f, 0x64, 0x65, 0x73, 0x3a, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x2d, 0x20, 0x52, 0x65, 0x61, 0x64, 0x57, 0x72, 0x69, 0x74, 0x65, + 0x4f, 0x6e, 0x63, 0x65, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x73, 0x3a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x3a, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x3a, 0x20, 0x31, + 0x47, 0x69, 0x0a, 0x2d, 0x2d, 0x2d, 0x0a, 0x61, 0x70, 0x69, 0x56, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x76, 0x31, 0x0a, 0x6b, 0x69, + 0x6e, 0x64, 0x3a, 0x20, 0x50, 0x6f, 0x64, 0x0a, 0x6d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x3a, 0x0a, 0x20, 0x20, 0x6e, 0x61, 0x6d, 0x65, + 0x3a, 0x20, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x74, 0x65, 0x73, 0x74, + 0x31, 0x0a, 0x20, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x3a, 0x20, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x74, 0x65, 0x73, + 0x74, 0x0a, 0x20, 0x20, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x3a, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x61, 0x70, 0x70, 0x3a, 0x20, 0x70, 0x6c, 0x75, + 0x67, 0x69, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x3a, + 0x20, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x23, 0x20, 0x74, 0x69, 0x65, 0x72, 0x3a, 0x20, + 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x0a, 0x73, 0x70, 0x65, + 0x63, 0x3a, 0x0a, 0x20, 0x20, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, + 0x65, 0x3a, 0x20, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x74, 0x65, 0x73, + 0x74, 0x2d, 0x31, 0x0a, 0x20, 0x20, 0x73, 0x75, 0x62, 0x64, 0x6f, 0x6d, + 0x61, 0x69, 0x6e, 0x3a, 0x20, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x74, + 0x65, 0x73, 0x74, 0x2d, 0x73, 0x75, 0x62, 0x64, 0x6f, 0x6d, 0x61, 0x69, + 0x6e, 0x0a, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, + 0x72, 0x73, 0x3a, 0x0a, 0x20, 0x20, 0x2d, 0x20, 0x69, 0x6d, 0x61, 0x67, + 0x65, 0x3a, 0x20, 0x62, 0x75, 0x73, 0x79, 0x62, 0x6f, 0x78, 0x3a, 0x31, + 0x2e, 0x32, 0x38, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6d, 0x6d, + 0x61, 0x6e, 0x64, 0x3a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2d, + 0x20, 0x73, 0x6c, 0x65, 0x65, 0x70, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x2d, 0x20, 0x22, 0x33, 0x36, 0x30, 0x30, 0x22, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3a, 0x20, 0x70, 0x6c, 0x75, 0x67, + 0x69, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x76, + 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x3a, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x6e, 0x61, 0x6d, + 0x65, 0x3a, 0x20, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x74, 0x65, 0x73, + 0x74, 0x2d, 0x70, 0x65, 0x72, 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x74, + 0x2d, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x50, 0x61, + 0x74, 0x68, 0x3a, 0x20, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x0a, 0x20, 0x20, + 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x73, 0x3a, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x2d, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3a, 0x20, 0x70, 0x6c, 0x75, + 0x67, 0x69, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2d, 0x70, 0x65, 0x72, 0x73, + 0x69, 0x73, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x73, 0x74, 0x6f, 0x72, 0x61, + 0x67, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x65, 0x72, + 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x74, 0x56, 0x6f, 0x6c, 0x75, 0x6d, + 0x65, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x3a, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x4e, 0x61, 0x6d, + 0x65, 0x3a, 0x20, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x74, 0x65, 0x73, + 0x74, 0x2d, 0x70, 0x65, 0x72, 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x74, + 0x2d, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x2d, 0x63, 0x6c, 0x61, 0x69, + 0x6d, 0x0a, 0x2d, 0x2d, 0x2d, 0x0a, 0x61, 0x70, 0x69, 0x56, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x76, 0x31, 0x0a, 0x6b, 0x69, 0x6e, + 0x64, 0x3a, 0x20, 0x50, 0x6f, 0x64, 0x0a, 0x6d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x3a, 0x0a, 0x20, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3a, + 0x20, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x32, + 0x0a, 0x20, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x3a, 0x20, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x74, 0x65, 0x73, 0x74, + 0x0a, 0x20, 0x20, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x3a, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x61, 0x70, 0x70, 0x3a, 0x20, 0x70, 0x6c, 0x75, 0x67, + 0x69, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x0a, 0x73, 0x70, 0x65, 0x63, 0x3a, + 0x0a, 0x20, 0x20, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x3a, + 0x20, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2d, + 0x32, 0x0a, 0x20, 0x20, 0x73, 0x75, 0x62, 0x64, 0x6f, 0x6d, 0x61, 0x69, + 0x6e, 0x3a, 0x20, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x74, 0x65, 0x73, + 0x74, 0x2d, 0x73, 0x75, 0x62, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x0a, + 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, + 0x3a, 0x0a, 0x20, 0x20, 0x2d, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x3a, + 0x20, 0x62, 0x75, 0x73, 0x79, 0x62, 0x6f, 0x78, 0x3a, 0x31, 0x2e, 0x32, + 0x38, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, + 0x64, 0x3a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x73, + 0x6c, 0x65, 0x65, 0x70, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2d, + 0x20, 0x22, 0x33, 0x36, 0x30, 0x30, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x6e, 0x61, 0x6d, 0x65, 0x3a, 0x20, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, + 0x74, 0x65, 0x73, 0x74, 0x0a, 0x2d, 0x2d, 0x2d, 0x0a, 0x61, 0x70, 0x69, + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x61, 0x70, 0x70, + 0x73, 0x2f, 0x76, 0x31, 0x0a, 0x6b, 0x69, 0x6e, 0x64, 0x3a, 0x20, 0x52, + 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x53, 0x65, 0x74, 0x0a, 0x6d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x0a, 0x20, 0x20, 0x6e, 0x61, + 0x6d, 0x65, 0x3a, 0x20, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x74, 0x65, + 0x73, 0x74, 0x2d, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x0a, + 0x20, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x3a, + 0x20, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x0a, + 0x20, 0x20, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x3a, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x61, 0x70, 0x70, 0x3a, 0x20, 0x70, 0x6c, 0x75, 0x67, 0x69, + 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2d, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, + 0x61, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x69, 0x65, 0x72, 0x3a, 0x20, + 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x0a, 0x73, 0x70, 0x65, + 0x63, 0x3a, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, + 0x73, 0x3a, 0x20, 0x31, 0x0a, 0x20, 0x20, 0x73, 0x65, 0x6c, 0x65, 0x63, + 0x74, 0x6f, 0x72, 0x3a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x61, 0x74, + 0x63, 0x68, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x3a, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x74, 0x69, 0x65, 0x72, 0x3a, 0x20, 0x66, 0x72, + 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x74, 0x65, 0x6d, + 0x70, 0x6c, 0x61, 0x74, 0x65, 0x3a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x3a, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x69, 0x65, 0x72, 0x3a, + 0x20, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x73, 0x70, 0x65, 0x63, 0x3a, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, + 0x3a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x6e, 0x61, + 0x6d, 0x65, 0x3a, 0x20, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x74, 0x65, + 0x73, 0x74, 0x2d, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x2d, + 0x74, 0x65, 0x73, 0x74, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x3a, 0x20, 0x67, 0x63, 0x72, 0x2e, + 0x69, 0x6f, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x5f, 0x73, 0x61, + 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2f, 0x67, 0x62, 0x2d, 0x66, 0x72, 0x6f, + 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x3a, 0x76, 0x33, 0x0a, 0x2d, 0x2d, 0x2d, + 0x0a, 0x61, 0x70, 0x69, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, + 0x20, 0x61, 0x70, 0x70, 0x73, 0x2f, 0x76, 0x31, 0x0a, 0x6b, 0x69, 0x6e, + 0x64, 0x3a, 0x20, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, + 0x74, 0x0a, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x0a, + 0x20, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3a, 0x20, 0x70, 0x6c, 0x75, 0x67, + 0x69, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2d, 0x6e, 0x67, 0x69, 0x6e, 0x78, + 0x2d, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x0a, + 0x20, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x3a, + 0x20, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x0a, + 0x20, 0x20, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x3a, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x61, 0x70, 0x70, 0x3a, 0x20, 0x70, 0x6c, 0x75, 0x67, 0x69, + 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2d, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, + 0x6d, 0x65, 0x6e, 0x74, 0x0a, 0x73, 0x70, 0x65, 0x63, 0x3a, 0x0a, 0x20, + 0x20, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, 0x3a, 0x20, 0x32, + 0x0a, 0x20, 0x20, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x3a, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x4c, 0x61, + 0x62, 0x65, 0x6c, 0x73, 0x3a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x61, 0x70, 0x70, 0x3a, 0x20, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x74, + 0x65, 0x73, 0x74, 0x2d, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, + 0x6e, 0x74, 0x0a, 0x20, 0x20, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, + 0x65, 0x3a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x3a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, + 0x61, 0x62, 0x65, 0x6c, 0x73, 0x3a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x61, 0x70, 0x70, 0x3a, 0x20, 0x70, 0x6c, 0x75, 0x67, + 0x69, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2d, 0x64, 0x65, 0x70, 0x6c, 0x6f, + 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x73, 0x70, + 0x65, 0x63, 0x3a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x3a, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3a, 0x20, + 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2d, 0x6e, + 0x67, 0x69, 0x6e, 0x78, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x3a, 0x20, 0x6e, 0x67, 0x69, 0x6e, + 0x78, 0x3a, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x3a, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x63, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x50, 0x6f, 0x72, 0x74, 0x3a, + 0x20, 0x38, 0x30, 0x38, 0x30, 0x0a, 0x2d, 0x2d, 0x2d, 0x0a, 0x61, 0x70, + 0x69, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x61, 0x70, + 0x70, 0x73, 0x2f, 0x76, 0x31, 0x0a, 0x6b, 0x69, 0x6e, 0x64, 0x3a, 0x20, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x66, 0x75, 0x6c, 0x53, 0x65, 0x74, 0x0a, + 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x0a, 0x20, 0x20, + 0x6e, 0x61, 0x6d, 0x65, 0x3a, 0x20, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, + 0x74, 0x65, 0x73, 0x74, 0x2d, 0x6e, 0x67, 0x69, 0x6e, 0x78, 0x2d, 0x77, + 0x65, 0x62, 0x0a, 0x20, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x3a, 0x20, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x74, 0x65, + 0x73, 0x74, 0x0a, 0x73, 0x70, 0x65, 0x63, 0x3a, 0x0a, 0x20, 0x20, 0x73, + 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x3a, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, + 0x3a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x70, 0x70, 0x3a, + 0x20, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2d, + 0x6e, 0x67, 0x69, 0x6e, 0x78, 0x2d, 0x77, 0x65, 0x62, 0x0a, 0x20, 0x20, + 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x3a, + 0x20, 0x22, 0x6e, 0x67, 0x69, 0x6e, 0x78, 0x22, 0x0a, 0x20, 0x20, 0x72, + 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, 0x3a, 0x20, 0x33, 0x0a, 0x20, + 0x20, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x3a, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x3a, 0x20, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, + 0x74, 0x65, 0x73, 0x74, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, + 0x61, 0x62, 0x65, 0x6c, 0x73, 0x3a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x61, 0x70, 0x70, 0x3a, 0x20, 0x70, 0x6c, 0x75, 0x67, + 0x69, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2d, 0x6e, 0x67, 0x69, 0x6e, 0x78, + 0x2d, 0x77, 0x65, 0x62, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x74, 0x69, 0x65, 0x72, 0x3a, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x65, + 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x73, 0x70, 0x65, 0x63, 0x3a, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x65, 0x72, 0x6d, 0x69, + 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x47, 0x72, 0x61, 0x63, 0x65, 0x50, + 0x65, 0x72, 0x69, 0x6f, 0x64, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, + 0x3a, 0x20, 0x31, 0x30, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x3a, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3a, + 0x20, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2d, + 0x6e, 0x67, 0x69, 0x6e, 0x78, 0x2d, 0x77, 0x65, 0x62, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x3a, + 0x20, 0x6b, 0x38, 0x73, 0x2e, 0x67, 0x63, 0x72, 0x2e, 0x69, 0x6f, 0x2f, + 0x6e, 0x67, 0x69, 0x6e, 0x78, 0x2d, 0x73, 0x6c, 0x69, 0x6d, 0x3a, 0x30, + 0x2e, 0x38, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, + 0x6f, 0x72, 0x74, 0x73, 0x3a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x2d, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, + 0x72, 0x50, 0x6f, 0x72, 0x74, 0x3a, 0x20, 0x38, 0x30, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6e, 0x61, 0x6d, 0x65, + 0x3a, 0x20, 0x77, 0x65, 0x62, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x4d, 0x6f, 0x75, 0x6e, + 0x74, 0x73, 0x3a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x2d, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3a, 0x20, 0x70, 0x6c, 0x75, 0x67, + 0x69, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2d, 0x77, 0x77, 0x77, 0x2d, 0x64, + 0x61, 0x74, 0x61, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x50, 0x61, 0x74, 0x68, 0x3a, + 0x20, 0x2f, 0x75, 0x73, 0x72, 0x2f, 0x73, 0x68, 0x61, 0x72, 0x65, 0x2f, + 0x6e, 0x67, 0x69, 0x6e, 0x78, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0a, 0x20, + 0x20, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x43, 0x6c, 0x61, 0x69, 0x6d, + 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x3a, 0x0a, 0x20, + 0x20, 0x2d, 0x20, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3a, + 0x20, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2d, + 0x77, 0x77, 0x77, 0x2d, 0x64, 0x61, 0x74, 0x61, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x3a, 0x20, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x74, 0x65, 0x73, 0x74, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x73, 0x70, 0x65, 0x63, 0x3a, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4d, + 0x6f, 0x64, 0x65, 0x73, 0x3a, 0x20, 0x5b, 0x20, 0x22, 0x52, 0x65, 0x61, + 0x64, 0x57, 0x72, 0x69, 0x74, 0x65, 0x4f, 0x6e, 0x63, 0x65, 0x22, 0x20, + 0x5d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x73, 0x3a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x3a, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, + 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x3a, 0x20, 0x31, 0x47, 0x69, 0x0a, +}; +unsigned int restore_object_data_len = 3984; + /** * @brief Perform test backup. */ @@ -388,6 +724,22 @@ void perform_backup() if (regress_backup_other_file) { + // restore object + snprintf(buf, BIGBUFLEN, "RESTOREOBJ:TestRObject%d\n", mypid); + write_plugin('C', buf); + snprintf(buf, BIGBUFLEN, "RESTOREOBJ_LEN:%u\n", restore_object_data_len); + write_plugin('C', buf); + write_plugin_bin(restore_object_data, restore_object_data_len); + signal_eod(); + + snprintf(buf, BIGBUFLEN, "RESTOREOBJ:OtherObject%d\n", mypid); + write_plugin('C', buf); + const char *r_data = "/* here comes a file data contents */"; + snprintf(buf, BIGBUFLEN, "RESTOREOBJ_LEN:%u\n", strlen(r_data) + 1); + write_plugin('C', buf); + write_plugin('D', r_data); + signal_eod(); + // next file snprintf(buf, BIGBUFLEN, "FNAME:%s/bucket/%d/vm222-other-file.iso\n", PLUGINPREFIX, mypid); write_plugin('C', buf); @@ -520,7 +872,7 @@ void perform_backup() write_plugin('I', "TEST17 - big file block"); write_plugin('C', "DATA\n"); { - char *bigfileblock_ptr = (char*)malloc(bigfileblock); + unsigned char *bigfileblock_ptr = (unsigned char*)malloc(bigfileblock); memset(bigfileblock_ptr, 0xA1, bigfileblock); for (int s = bigfilesize; s > 0; s -= bigfileblock) { write_plugin_bin(bigfileblock_ptr, bigfileblock); @@ -901,7 +1253,7 @@ void perform_queryparam(const char *query) write_plugin('C', buf); } else if (strcmp(query, "m_json") == 0) { - write_plugin_bin((const char*)m_json, m_json_len); + write_plugin_bin(m_json, m_json_len); write_plugin('D', "UmFkb3PFgmF3IEtvcnplbmlld3NraQo=\n"); } @@ -981,7 +1333,7 @@ void perform_restore() } /* check for METADATA stream */ - if (strncmp(buf, "METADATA_STREAM", 15) == 0){ + if (strncmp(buf, "METADATA_STREAM", 15) == 0) { // handle metadata read_plugin_data_stream(); /* signal OK */ @@ -998,6 +1350,20 @@ void perform_restore() continue; } + /* Restore Object stream */ + if (strncmp(buf, "RESTOREOBJ", 10) == 0) { + read_plugin(buf); // RESTOREOBJ_LEN + + // handle object data + read_plugin_data_stream(); + /* signal OK */ + LOG("#> RESTOREOBJ data saved."); + + write_plugin('I', "TEST6R - RO saved."); + write_plugin('C', "OK\n"); + continue; + } + /* check if DATA command, so read the data packets */ if (strcmp(buf, "DATA\n") == 0){ int len = read_plugin(buf);