+/*
+ * This reads data sent from the Director from the
+ * RestoreObject table that allows us to get objects
+ * that were backed up (VSS .xml data) and are needed
+ * before starting the restore.
+ */
+static int restore_object_cmd(JCR *jcr)
+{
+ BSOCK *dir = jcr->dir_bsock;
+ int32_t FileIndex;
+ restore_object_pkt rop;
+
+ memset(&rop, 0, sizeof(rop));
+ rop.pkt_size = sizeof(rop);
+ rop.pkt_end = sizeof(rop);
+ Dmsg1(100, "Enter restoreobject_cmd: %s", dir->msg);
+ if (strcmp(dir->msg, endrestoreobjectcmd) == 0) {
+ generate_plugin_event(jcr, bEventRestoreObject, NULL);
+ return dir->fsend(OKRestoreObject);
+ }
+
+ if (sscanf(dir->msg, restoreobjcmd, &rop.JobId, &rop.object_len,
+ &rop.object_full_len, &rop.object_index,
+ &rop.object_type, &rop.object_compression, &FileIndex) != 7) {
+ Dmsg0(5, "Bad restore object command\n");
+ pm_strcpy(jcr->errmsg, dir->msg);
+ Jmsg1(jcr, M_FATAL, 0, _("Bad RestoreObject command: %s\n"), jcr->errmsg);
+ goto bail_out;
+ }
+
+ Dmsg6(100, "Recv object: JobId=%u objlen=%d full_len=%d objinx=%d objtype=%d FI=%d\n",
+ rop.JobId, rop.object_len, rop.object_full_len,
+ rop.object_index, rop.object_type, FileIndex);
+ /* Read Object name */
+ if (dir->recv() < 0) {
+ goto bail_out;
+ }
+ Dmsg2(100, "Recv Oname object: len=%d Oname=%s\n", dir->msglen, dir->msg);
+ rop.object_name = bstrdup(dir->msg);
+
+ /* Read Object */
+ if (dir->recv() < 0) {
+ goto bail_out;
+ }
+ /* Transfer object from message buffer, and get new message buffer */
+ rop.object = dir->msg;
+ dir->msg = get_pool_memory(PM_MESSAGE);
+
+ /* If object is compressed, uncompress it */
+ if (rop.object_compression == 1) { /* zlib level 9 */
+ int stat;
+ int out_len = rop.object_full_len + 100;
+ POOLMEM *obj = get_memory(out_len);
+ Dmsg2(100, "Inflating from %d to %d\n", rop.object_len, rop.object_full_len);
+ stat = Zinflate(rop.object, rop.object_len, obj, out_len);
+ Dmsg1(100, "Zinflate stat=%d\n", stat);
+ if (out_len != rop.object_full_len) {
+ Jmsg3(jcr, M_ERROR, 0, ("Decompression failed. Len wanted=%d got=%d. Object=%s\n"),
+ rop.object_full_len, out_len, rop.object_name);
+ }
+ free_pool_memory(rop.object); /* release compressed object */
+ rop.object = obj; /* new uncompressed object */
+ rop.object_len = out_len;
+ }
+ Dmsg2(100, "Recv Object: len=%d Object=%s\n", rop.object_len, rop.object);
+ /* Special Job meta data */
+ if (strcmp(rop.object_name, "job_metadata.xml") == 0) {
+ Dmsg0(100, "got job metadata\n");
+ free_and_null_pool_memory(jcr->job_metadata);
+ jcr->job_metadata = rop.object;
+ rop.object = NULL;
+ } else {
+ /* pass to plugin */
+ generate_plugin_event(jcr, bEventRestoreObject, (void *)&rop);
+ }
+
+ if (rop.object_name) {
+ free(rop.object_name);
+ }
+ if (rop.object) {
+ free_pool_memory(rop.object);
+ }
+
+ Dmsg1(100, "Send: %s", OKRestoreObject);
+ return 1;
+
+bail_out:
+ dir->fsend(_("2909 Bad RestoreObject command.\n"));
+ return 0;
+
+}
+