/*
Bacula® - The Network Backup Solution
- Copyright (C) 2002-2010 Free Software Foundation Europe e.V.
+ Copyright (C) 2002-2011 Free Software Foundation Europe e.V.
The main author of Bacula is Kern Sibbald, with contributions from
many others, a complete list can be found in the file AUTHORS.
extern void print_bsr(UAContext *ua, RBSR *bsr);
-
/* Forward referenced functions */
static int last_full_handler(void *ctx, int num_fields, char **row);
static int jobid_handler(void *ctx, int num_fields, char **row);
rx.where = ua->argv[i];
}
+ i = find_arg_with_value(ua, "replace");
+ if (i >= 0) {
+ rx.replace = ua->argv[i];
+ }
+
+
i = find_arg_with_value(ua, "strip_prefix");
if (i >= 0) {
strip_prefix = ua->argv[i];
if (rx.restore_jobs == 1) {
job = rx.restore_job;
} else {
- job = select_restore_job_resource(ua);
+ job = get_restore_job(ua);
}
if (!job) {
goto bail_out;
}
pm_strcat(ua->cmd, buf);
+ if (rx.replace) {
+ Mmsg(buf, " replace=%s", rx.replace);
+ pm_strcat(ua->cmd, buf);
+ }
+
if (rx.comment) {
Mmsg(buf, " comment=\"%s\"", rx.comment);
pm_strcat(ua->cmd, buf);
parse_ua_args(ua);
run_cmd(ua, ua->cmd);
free_rx(&rx);
+ garbage_collect_memory(); /* release unused memory */
return 1;
bail_out:
}
free_rx(&rx);
+ garbage_collect_memory(); /* release unused memory */
return 0;
}
i = find_arg_with_value(ua, NT_("backupclient"));
}
if (i >= 0) {
- if (!has_value(ua, i)) {
+ if (!is_name_valid(ua->argv[i], &ua->errmsg)) {
+ ua->error_msg("%s argument: %s", ua->argk[i], ua->errmsg);
return 0;
}
bstrncpy(rx->ClientName, ua->argv[i], sizeof(rx->ClientName));
/* try command line argument */
int i = find_arg_with_value(ua, NT_("restoreclient"));
if (i >= 0) {
- if (!has_value(ua, i)) {
+ if (!is_name_valid(ua->argv[i], &ua->errmsg)) {
+ ua->error_msg("%s argument: %s", ua->argk[i], ua->errmsg);
return 0;
}
bstrncpy(rx.RestoreClientName, ua->argv[i], sizeof(rx.RestoreClientName));
"restoreclient", /* 19 */
"copies", /* 20 */
"comment", /* 21 */
+ "restorejob", /* 22 */
+ "replace", /* 23 */
NULL
};
len = strlen(ua->cmd);
fname = (char *)malloc(len * 2 + 1);
db_escape_string(ua->jcr, ua->db, fname, ua->cmd, len);
- Mmsg(rx->query, uar_file[db_type], rx->ClientName, fname);
+ Mmsg(rx->query, uar_file[db_get_type_index(ua->db)], rx->ClientName, fname);
free(fname);
gui_save = ua->jcr->gui;
ua->jcr->gui = true;
ua->error_msg(_("No JobId specified cannot continue.\n"));
return false;
} else {
- Mmsg(rx->query, uar_jobid_fileindex_from_dir[db_type], rx->JobIds, dir, rx->ClientName);
+ Mmsg(rx->query, uar_jobid_fileindex_from_dir[db_get_type_index(ua->db)], rx->JobIds, dir, rx->ClientName);
}
rx->found = false;
/* Find and insert jobid and File Index */
}
/* Walk on the delta_list of a TREE_NODE item and insert all parts
- * TODO: Optimize for bootstrap creation
+ * TODO: Optimize for bootstrap creation, remove recursion
+ * 6 -> 5 -> 4 -> 3 -> 2 -> 1 -> 0
+ * should insert as
+ * 0, 1, 2, 3, 4, 5, 6
*/
static void add_delta_list_findex(RESTORE_CTX *rx, struct delta_list *lst)
{
- while (lst != NULL) {
- add_findex(rx->bsr, lst->JobId, lst->FileIndex);
- lst = lst->next;
+ if (lst == NULL) {
+ return;
+ }
+ if (lst->next) {
+ add_delta_list_findex(rx, lst->next);
}
+ add_findex(rx->bsr, lst->JobId, lst->FileIndex);
}
static bool build_directory_tree(UAContext *ua, RESTORE_CTX *rx)
#define new_get_file_list
#ifdef new_get_file_list
- if (!db_get_file_list_with_delta(ua->jcr, ua->db,
- rx->JobIds, false /* do not use md5 */,
- insert_tree_handler, (void *)&tree))
+ if (!db_get_file_list(ua->jcr, ua->db,
+ rx->JobIds, false /* do not use md5 */,
+ true /* get delta */,
+ insert_tree_handler, (void *)&tree))
{
ua->error_msg("%s", db_strerror(ua->db));
}
}
}
#endif
+ /*
+ * At this point, the tree is built, so we can garbage collect
+ * any memory released by the SQL engine that RedHat has
+ * not returned to the OS :-(
+ */
+ garbage_collect_memory();
+
/*
* Look at the first JobId on the list (presumably the oldest) and
* if it is marked purged, don't do the manual selection because
/* Create temp tables */
db_sql_query(ua->db, uar_del_temp, NULL, NULL);
db_sql_query(ua->db, uar_del_temp1, NULL, NULL);
- if (!db_sql_query(ua->db, uar_create_temp[db_type], NULL, NULL)) {
+ if (!db_sql_query(ua->db, uar_create_temp[db_get_type_index(ua->db)], NULL, NULL)) {
ua->error_msg("%s\n", db_strerror(ua->db));
}
- if (!db_sql_query(ua->db, uar_create_temp1[db_type], NULL, NULL)) {
+ if (!db_sql_query(ua->db, uar_create_temp1[db_get_type_index(ua->db)], NULL, NULL)) {
ua->error_msg("%s\n", db_strerror(ua->db));
}
/*
*/
memset(&fsr, 0, sizeof(fsr));
i = find_arg_with_value(ua, "FileSet");
- if (i >= 0) {
+
+ if (i >= 0 && is_name_valid(ua->argv[i], &ua->errmsg)) {
bstrncpy(fsr.FileSet, ua->argv[i], sizeof(fsr.FileSet));
if (!db_get_fileset_record(ua->jcr, ua->db, &fsr)) {
ua->error_msg(_("Error getting FileSet \"%s\": ERR=%s\n"), fsr.FileSet,
db_strerror(ua->db));
i = -1;
}
+ } else if (i >= 0) { /* name is invalid */
+ ua->error_msg(_("FileSet argument: %s\n"), ua->errmsg);
}
+
if (i < 0) { /* fileset not found */
edit_int64(cr.ClientId, ed1);
Mmsg(rx->query, uar_sel_fileset, ed1, ed1);
if (acl_access_ok(ua, Storage_ACL, store->name())) {
rx.store = store;
Dmsg1(200, "Set store=%s\n", rx.store->name());
- ua->warning_msg(_("Storage \"%s\" not found, using Storage \"%s\" from MediaType \"%s\".\n"),
- Storage, store->name(), MediaType);
+ if (Storage == NULL) {
+ ua->warning_msg(_("Using Storage \"%s\" from MediaType \"%s\".\n"),
+ store->name(), MediaType);
+ } else {
+ ua->warning_msg(_("Storage \"%s\" not found, using Storage \"%s\" from MediaType \"%s\".\n"),
+ Storage, store->name(), MediaType);
+ }
}
UnlockRes();
return;