POOLMEM *path; /* Path only */
POOLMEM *esc_name; /* Escaped file name */
POOLMEM *esc_path; /* Escaped path name */
+ POOLMEM *esc_obj; /* Escaped restore object */
int fnl; /* file name length */
int pnl; /* path name length */
};
POOLMEM *path; /* Path only */
POOLMEM *esc_name; /* Escaped file name */
POOLMEM *esc_path; /* Escaped path name */
+ POOLMEM *esc_obj; /* Escaped restore object */
int fnl; /* file name length */
int pnl; /* path name length */
};
POOLMEM *path; /* Path only */
POOLMEM *esc_name; /* Escaped file name */
POOLMEM *esc_path; /* Escaped path name */
+ POOLMEM *esc_obj; /* Escaped restore object */
int fnl; /* file name length */
int pnl; /* path name length */
};
POOLMEM *path; /* Path only */
POOLMEM *esc_name; /* Escaped file name */
POOLMEM *esc_path; /* Escaped path name */
+ unsigned char *esc_obj; /* Escaped restore object */
int fnl; /* file name length */
int pnl; /* path name length */
};
POOLMEM *path; /* Path only */
POOLMEM *esc_name; /* Escaped file name */
POOLMEM *esc_path; /* Escaped path name */
+ POOLMEM *esc_obj; /* Escaped restore object */
int fnl; /* file name length */
int pnl; /* path name length */
};
CREATE TABLE RestoreObject (
RestoreObjectId SERIAL NOT NULL,
ObjectName TEXT NOT NULL,
- RestoreObject TEXT NOT NULL,
+ RestoreObject BYTEA NOT NULL,
PluginName TEXT NOT NULL,
ObjectLength INTEGER DEFAULT 0,
ObjectFullLength INTEGER DEFAULT 0,
mdb->path = get_pool_memory(PM_FNAME);
mdb->esc_name = get_pool_memory(PM_FNAME);
mdb->esc_path = get_pool_memory(PM_FNAME);
+ mdb->esc_obj = get_pool_memory(PM_FNAME);
mdb->allow_transactions = mult_db_connections;
db_list->append(mdb); /* put db in list */
Dmsg3(100, "initdb ref=%d connected=%d db=%p\n", mdb->ref_count,
free_pool_memory(mdb->path);
free_pool_memory(mdb->esc_name);
free_pool_memory(mdb->esc_path);
+ free_pool_memory(mdb->esc_obj);
if (mdb->db_name) {
free(mdb->db_name);
}
return 1;
}
+/*
+ * Escape binary object so that MySQL is happy
+ * Memory is stored in B_DB struct, no need to free it
+ */
+char *
+db_escape_object(JCR *jcr, B_DB *db, char *old, int len)
+{
+ mdb->esc_obj = check_pool_memory_size(mdb->esc_obj, len*2+1);
+ mysql_real_escape_string(mdb->db, mdb->esc_obj, old, len);
+ return mdb->esc_obj;
+}
+
+/*
+ * Unescape binary object so that MySQL is happy
+ */
+void
+db_unescape_object(JCR *jcr, B_DB *db,
+ char *from, int32_t expected_len,
+ POOLMEM **dest, int32_t *dest_len)
+{
+ if (!from) {
+ *dest[0] = 0;
+ *dest_len = 0;
+ return;
+ }
+ *dest = check_pool_memory_size(*dest, expected_len+1);
+ *dest_len = expected_len;
+ memcpy(*dest, from, expected_len);
+ (*dest)[expected_len]=0;
+}
/*
* Escape strings so that MySQL is happy
mdb->fname = get_pool_memory(PM_FNAME);
mdb->path = get_pool_memory(PM_FNAME);
mdb->esc_name = get_pool_memory(PM_FNAME);
- mdb->esc_path = get_pool_memory(PM_FNAME);
+ mdb->esc_path = get_pool_memory(PM_FNAME);
mdb->allow_transactions = mult_db_connections;
db_list->append(mdb); /* put db in list */
V(mutex);
if (mdb->db_socket) {
free(mdb->db_socket);
}
+ if (mdb->esc_obj) {
+ PQfreemem(mdb->esc_obj);
+ }
free(mdb);
if (db_list->size() == 0) {
delete db_list;
return 1;
}
+/*
+ * Escape binary so that PostgreSQL is happy
+ *
+ */
+char *
+db_escape_object(JCR *jcr, B_DB *mdb, char *old, int len)
+{
+ size_t new_len;
+ if (mdb->esc_obj) {
+ PQfreemem(mdb->esc_obj);
+ }
+
+ mdb->esc_obj = PQescapeByteaConn(mdb->db, (unsigned const char *)old,
+ len, &new_len);
+
+ if (!mdb->esc_obj) {
+ Jmsg(jcr, M_FATAL, 0, _("PQescapeByteaConn returned NULL.\n"));
+ }
+
+ return (char *)mdb->esc_obj;
+}
+
+/*
+ * Unescape binary object so that PostgreSQL is happy
+ *
+ */
+void
+db_unescape_object(JCR *jcr, B_DB *mdb,
+ char *from, int32_t expected_len,
+ POOLMEM **dest, int32_t *dest_len)
+{
+ size_t new_len;
+ unsigned char *obj;
+
+ if (!from) {
+ *dest[0] = 0;
+ *dest_len = 0;
+ return;
+ }
+
+ obj = PQunescapeBytea((unsigned const char *)from, &new_len);
+
+ if (!obj) {
+ Jmsg(jcr, M_FATAL, 0, _("PQunescapeByteaConn returned NULL.\n"));
+ }
+
+ *dest_len = new_len;
+ *dest = check_pool_memory_size(*dest, new_len+1);
+ memcpy(*dest, obj, new_len);
+ (*dest)[new_len]=0;
+
+ PQfreemem(obj);
+
+ Dmsg1(000, "obj size: %d\n", *dest_len);
+}
/*
* Escape strings so that PostgreSQL is happy
bail_out:
PQclear(result);
-
+
return id;
}
void db_close_database(JCR *jcr, B_DB *db);
bool db_open_batch_connexion(JCR *jcr, B_DB *mdb);
void db_escape_string(JCR *jcr, B_DB *db, char *snew, char *old, int len);
+char *db_escape_object(JCR *jcr, B_DB *db, char *old, int len);
+void db_unescape_object(JCR *jcr, B_DB *db,
+ char *from, int32_t expected_len,
+ POOLMEM **dest, int32_t *len);
char *db_strerror(B_DB *mdb);
int db_next_index(JCR *jcr, B_DB *mdb, char *table, char *index);
bool db_sql_query(B_DB *mdb, const char *cmd, DB_RESULT_HANDLER *result_handler, void *ctx);
{
bool stat;
int plug_name_len;
- POOLMEM *esc_obj = get_pool_memory(PM_MESSAGE);
POOLMEM *esc_plug_name = get_pool_memory(PM_MESSAGE);
db_lock(mdb);
mdb->esc_name = check_pool_memory_size(mdb->esc_name, mdb->fnl*2+1);
db_escape_string(jcr, mdb, mdb->esc_name, ro->object_name, mdb->fnl);
- esc_obj = check_pool_memory_size(esc_obj, ro->object_len*2+1);
- db_escape_string(jcr, mdb, esc_obj, ro->object, ro->object_len);
+ db_escape_object(jcr, mdb, ro->object, ro->object_len);
plug_name_len = strlen(ro->plugin_name);
esc_plug_name = check_pool_memory_size(esc_plug_name, plug_name_len*2+1);
"ObjectLength,ObjectFullLength,ObjectIndex,ObjectType,"
"ObjectCompression,FileIndex,JobId) "
"VALUES ('%s','%s','%s',%d,%d,%d,%d,%d,%d,%u)",
- mdb->esc_name, esc_plug_name, esc_obj,
+ mdb->esc_name, esc_plug_name, mdb->esc_obj,
ro->object_len, ro->object_full_len, ro->object_index,
FT_RESTORE_FIRST, ro->object_compression, ro->FileIndex, ro->JobId);
stat = true;
}
db_unlock(mdb);
- free_pool_memory(esc_obj);
free_pool_memory(esc_plug_name);
return stat;
}
mdb->path = get_pool_memory(PM_FNAME);
mdb->esc_name = get_pool_memory(PM_FNAME);
mdb->esc_path = get_pool_memory(PM_FNAME);
+ mdb->esc_obj = get_pool_memory(PM_FNAME);
mdb->allow_transactions = mult_db_connections;
db_list->append(mdb);
V(mutex);
free_pool_memory(mdb->path);
free_pool_memory(mdb->esc_name);
free_pool_memory(mdb->esc_path);
+ free_pool_memory(mdb->esc_obj);
if (mdb->db_name) {
free(mdb->db_name);
}
return 1;
}
+/*
+ * Escape binary object so that SQLite is happy
+ * Memory is stored in B_DB struct, no need to free it
+ *
+ * TODO: this should be implemented (escape \0)
+ */
+char *
+db_escape_object(JCR *jcr, B_DB *db, char *old, int len)
+{
+ char *n, *o;
+
+ n = mdb->esc_obj = check_pool_memory_size(mdb->esc_obj, len*2+1);
+ o = old;
+ while (len--) {
+ switch (*o) {
+ case '\'':
+ *n++ = '\'';
+ *n++ = '\'';
+ o++;
+ break;
+ case 0:
+ *n++ = '\\';
+ *n++ = 0;
+ o++;
+ break;
+ default:
+ *n++ = *o++;
+ break;
+ }
+ }
+ *n = 0;
+ return mdb->esc_obj;
+}
+
+/*
+ * Unescape binary object so that SQLIte is happy
+ * Memory is stored in B_DB struct, no need to free it
+ *
+ * TODO: need to be implemented (escape \0)
+ */
+void
+db_unescape_object(JCR *jcr, B_DB *db,
+ char *from, int32_t expected_len,
+ POOLMEM **dest, int32_t *dest_len)
+{
+ if (!from) {
+ *dest[0] = 0;
+ *dest_len = 0;
+ return;
+ }
+ *dest = check_pool_memory_size(*dest, expected_len+1);
+ *dest_len = expected_len;
+ memcpy(*dest, from, expected_len);
+ (*dest)[expected_len]=0;
+}
/*
* Escape strings so that SQLite is happy
{
JCR *jcr = (JCR *)ctx;
BSOCK *fd;
- POOLMEM *msg_save;
fd = jcr->file_bsock;
if (jcr->is_job_canceled()) {
Dmsg1(000, "Send obj hdr=%s", fd->msg);
- msg_save = fd->msg;
- fd->msg = row[7] ? row[7] : (char *)"";
- fd->msglen = strlen(fd->msg);
+ fd->msglen = pm_strcpy(fd->msg, row[7]);
fd->send(); /* send Object name */
+
Dmsg1(000, "Send obj: %s\n", fd->msg);
- fd->msg = row[8] ? row[8] : (char *)""; /* object */
- fd->msglen = str_to_uint64(row[1]); /* object length */
+// fd->msglen = str_to_uint64(row[1]); /* object length */
+// Dmsg1(000, "obj size: %lld\n", (uint64_t)fd->msglen);
+
+ /* object */
+ db_unescape_object(jcr, jcr->db,
+ row[8], /* Object */
+ str_to_uint64(row[1]), /* Object length */
+ &fd->msg, &fd->msglen);
fd->send(); /* send object */
-// Dmsg1(000, "Send obj: %s\n", fd->msg);
- fd->msg = msg_save;
+
+ if (debug_level) {
+ for (int i=0; i < fd->msglen; i++)
+ if (!fd->msg[i])
+ fd->msg[i] = ' ';
+ Dmsg1(000, "Send obj: %s\n", fd->msg);
+ }
return 0;
}
if (!jcr->JobIds || !jcr->JobIds[0]) {
return true;
}
- Mmsg(query, "SELECT JobId,ObjectLength,ObjectFullLength,ObjectIndex,ObjectType,"
- "ObjectCompression,FileIndex,ObjectName,RestoreObject FROM RestoreObject "
- "WHERE JobId IN (%s) ORDER BY ObjectIndex ASC", jcr->JobIds);
+ Mmsg(query, "SELECT JobId,ObjectLength,ObjectFullLength,ObjectIndex,"
+ "ObjectType,ObjectCompression,FileIndex,ObjectName,"
+ "RestoreObject "
+ "FROM RestoreObject "
+ "WHERE JobId IN (%s) "
+ "ORDER BY ObjectIndex ASC", jcr->JobIds);
/* restore_object_handler is called for each file found */
db_sql_query(jcr->db, query.c_str(), restore_object_handler, (void *)jcr);
if (jcr->VSS) {
if (g_pVSSClient->InitializeForRestore(jcr, vss_restore_init_callback,
(WCHAR *)jcr->job_metadata)) {
+
/* inform user about writer states */
int i;
for (i=0; i < (int)g_pVSSClient->GetWriterCount(); i++) {
}
}
} else {
+/*
+ int fd = open("C:\\eric.xml", O_CREAT | O_WRONLY | O_TRUNC, 0777);
+ write(fd, (WCHAR *)jcr->job_metadata, wcslen((WCHAR *)jcr->job_metadata) * sizeof(WCHAR));
+ close(fd);
+*/
berrno be;
Jmsg(jcr, M_WARNING, 0, _("VSS was not initialized properly. VSS support is disabled. ERR=%s\n"), be.bstrerror());
}