X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=bacula%2Fsrc%2Fdird%2Fua_restore.c;h=a625da14c9d40e076111b73fff87e5afe53958a7;hb=3f8a3a045ea058657030f588a10f786449d00e0d;hp=a0fde9b6aaa643a0d0acd07a95499c50be0e34e2;hpb=fce6a648a27ee86f6941a5085ec7909f6d43e725;p=bacula%2Fbacula diff --git a/bacula/src/dird/ua_restore.c b/bacula/src/dird/ua_restore.c index a0fde9b6aa..a625da14c9 100644 --- a/bacula/src/dird/ua_restore.c +++ b/bacula/src/dird/ua_restore.c @@ -13,7 +13,7 @@ * Version $Id$ */ /* - Copyright (C) 2002-2005 Kern Sibbald + Copyright (C) 2002-2006 Kern Sibbald This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -44,50 +44,13 @@ extern char *uar_sel_all_temp1, *uar_sel_fileset, *uar_mediatype; extern char *uar_jobid_fileindex, *uar_dif, *uar_sel_all_temp; extern char *uar_count_files, *uar_jobids_fileindex; extern char *uar_jobid_fileindex_from_dir; +extern char *uar_jobid_fileindex_from_table; -struct NAME_LIST { - char **name; /* list of names */ - int num_ids; /* ids stored */ - int max_ids; /* size of array */ - int num_del; /* number deleted */ - int tot_ids; /* total to process */ -}; - - -/* Main structure for obtaining JobIds or Files to be restored */ -struct RESTORE_CTX { - utime_t JobTDate; - uint32_t TotalFiles; - uint32_t JobId; - char ClientName[MAX_NAME_LENGTH]; - char last_jobid[20]; - POOLMEM *JobIds; /* User entered string of JobIds */ - STORE *store; - JOB *restore_job; - POOL *pool; - int restore_jobs; - uint32_t selected_files; - char *where; - RBSR *bsr; - POOLMEM *fname; /* filename only */ - POOLMEM *path; /* path only */ - POOLMEM *query; - int fnl; /* filename length */ - int pnl; /* path length */ - bool found; - bool all; /* mark all as default */ - NAME_LIST name_list; -}; - - -#define MAX_ID_LIST_LEN 1000000 - /* 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); -static int get_next_jobid_from_list(char **p, uint32_t *JobId); static int user_select_jobids_or_files(UAContext *ua, RESTORE_CTX *rx); static int fileset_handler(void *ctx, int num_fields, char **row); static void print_name_list(UAContext *ua, NAME_LIST *name_list); @@ -107,6 +70,7 @@ static void insert_one_file_or_dir(UAContext *ua, RESTORE_CTX *rx, char *date, b static int get_client_name(UAContext *ua, RESTORE_CTX *rx); static int get_date(UAContext *ua, char *date, int date_len); static int count_handler(void *ctx, int num_fields, char **row); +static bool insert_table_into_findex_list(UAContext *ua, RESTORE_CTX *rx, char *table); /* * Restore files @@ -117,7 +81,7 @@ int restore_cmd(UAContext *ua, const char *cmd) RESTORE_CTX rx; /* restore context */ JOB *job; int i; - POOLMEM *fname; + JCR *jcr = ua->jcr; memset(&rx, 0, sizeof(rx)); rx.path = get_pool_memory(PM_FNAME); @@ -178,7 +142,7 @@ int restore_cmd(UAContext *ua, const char *cmd) bsendmsg(ua, _("Unable to construct a valid BSR. Cannot continue.\n")); goto bail_out; } - if (!(selected_files = write_bsr_file(ua, rx.bsr))) { + if (!(selected_files = write_bsr_file(ua, rx))) { bsendmsg(ua, _("No files selected to be restored.\n")); goto bail_out; } @@ -213,26 +177,23 @@ int restore_cmd(UAContext *ua, const char *cmd) } /* Build run command */ - fname = get_pool_memory(PM_MESSAGE); - make_unique_restore_filename(ua, &fname); if (rx.where) { Mmsg(ua->cmd, "run job=\"%s\" client=\"%s\" storage=\"%s\" bootstrap=\"%s\"" " where=\"%s\" files=%d catalog=\"%s\"", job->hdr.name, rx.ClientName, rx.store?rx.store->hdr.name:"", - fname, rx.where, rx.selected_files, ua->catalog->hdr.name); + jcr->RestoreBootstrap, rx.where, rx.selected_files, ua->catalog->hdr.name); } else { Mmsg(ua->cmd, "run job=\"%s\" client=\"%s\" storage=\"%s\" bootstrap=\"%s\"" " files=%d catalog=\"%s\"", job->hdr.name, rx.ClientName, rx.store?rx.store->hdr.name:"", - fname, rx.selected_files, ua->catalog->hdr.name); + jcr->RestoreBootstrap, rx.selected_files, ua->catalog->hdr.name); } - free_pool_memory(fname); - if (find_arg(ua, N_("yes")) > 0) { + if (find_arg(ua, NT_("yes")) > 0) { pm_strcat(ua->cmd, " yes"); /* pass it on to the run command */ } - Dmsg1(400, "Submitting: %s\n", ua->cmd); + Dmsg1(100, "Submitting: %s\n", ua->cmd); parse_ua_args(ua); run_cmd(ua, ua->cmd); free_rx(&rx); @@ -267,14 +228,26 @@ static void free_rx(RESTORE_CTX *rx) free_name_list(&rx->name_list); } +static bool has_value(UAContext *ua, int i) +{ + if (!ua->argv[i]) { + bsendmsg(ua, _("Missing value for keyword: %s\n"), ua->argk[i]); + return false; + } + return true; +} + static int get_client_name(UAContext *ua, RESTORE_CTX *rx) { /* If no client name specified yet, get it now */ if (!rx->ClientName[0]) { CLIENT_DBR cr; /* try command line argument */ - int i = find_arg_with_value(ua, N_("client")); + int i = find_arg_with_value(ua, NT_("client")); if (i >= 0) { + if (!has_value(ua, i)) { + return 0; + } bstrncpy(rx->ClientName, ua->argv[i], sizeof(rx->ClientName)); return 1; } @@ -287,6 +260,7 @@ static int get_client_name(UAContext *ua, RESTORE_CTX *rx) return 1; } + /* * The first step in the restore process is for the user to * select a list of JobIds from which he will subsequently @@ -359,6 +333,9 @@ static int user_select_jobids_or_files(UAContext *ua, RESTORE_CTX *rx) /* Found keyword in kw[] list, process it */ switch (j) { case 0: /* jobid */ + if (!has_value(ua, i)) { + return 0; + } if (*rx->JobIds != 0) { pm_strcat(rx->JobIds, ","); } @@ -370,6 +347,9 @@ static int user_select_jobids_or_files(UAContext *ua, RESTORE_CTX *rx) have_date = true; break; case 2: /* before */ + if (!has_value(ua, i)) { + return 0; + } if (str_to_utime(ua->argv[i]) == 0) { bsendmsg(ua, _("Improper date format: %s\n"), ua->argv[i]); return 0; @@ -379,6 +359,9 @@ static int user_select_jobids_or_files(UAContext *ua, RESTORE_CTX *rx) break; case 3: /* file */ case 4: /* dir */ + if (!has_value(ua, i)) { + return 0; + } if (!have_date) { bstrutime(date, sizeof(date), time(NULL)); } @@ -403,6 +386,9 @@ static int user_select_jobids_or_files(UAContext *ua, RESTORE_CTX *rx) done = true; break; case 6: /* pool specified */ + if (!has_value(ua, i)) { + return 0; + } rx->pool = (POOL *)GetResWithName(R_POOL, ua->argv[i]); if (!rx->pool) { bsendmsg(ua, _("Error: Pool resource \"%s\" does not exist.\n"), ua->argv[i]); @@ -447,7 +433,7 @@ static int user_select_jobids_or_files(UAContext *ua, RESTORE_CTX *rx) } done = true; switch (do_prompt(ua, "", _("Select item: "), NULL, 0)) { - case -1: /* error */ + case -1: /* error or cancel */ return 0; case 0: /* list last 20 Jobs run */ gui_save = ua->jcr->gui; @@ -510,7 +496,7 @@ static int user_select_jobids_or_files(UAContext *ua, RESTORE_CTX *rx) return 0; } bsendmsg(ua, _("Enter file names with paths, or < to enter a filename\n" - "containg a list of file names with paths, and terminate\n" + "containing a list of file names with paths, and terminate\n" "them with a blank line.\n")); for ( ;; ) { if (!get_cmd(ua, _("Enter full filename: "))) { @@ -535,7 +521,7 @@ static int user_select_jobids_or_files(UAContext *ua, RESTORE_CTX *rx) return 0; } bsendmsg(ua, _("Enter file names with paths, or < to enter a filename\n" - "containg a list of file names with paths, and terminate\n" + "containing a list of file names with paths, and terminate\n" "them with a blank line.\n")); for ( ;; ) { if (!get_cmd(ua, _("Enter full filename: "))) { @@ -589,7 +575,7 @@ static int user_select_jobids_or_files(UAContext *ua, RESTORE_CTX *rx) return 0; } bsendmsg(ua, _("Enter full directory names or start the name\n" - "with a < to indicate it is a filename containg a list\n" + "with a < to indicate it is a filename containing a list\n" "of directories and terminate them with a blank line.\n")); for ( ;; ) { if (!get_cmd(ua, _("Enter directory name: "))) { @@ -627,7 +613,6 @@ static int user_select_jobids_or_files(UAContext *ua, RESTORE_CTX *rx) bsendmsg(ua, _("You have selected the following JobId: %s\n"), rx->JobIds); } - memset(&jr, 0, sizeof(JOB_DBR)); rx->TotalFiles = 0; for (p=rx->JobIds; ; ) { @@ -642,6 +627,7 @@ static int user_select_jobids_or_files(UAContext *ua, RESTORE_CTX *rx) if (jr.JobId == JobId) { continue; /* duplicate of last JobId */ } + memset(&jr, 0, sizeof(JOB_DBR)); jr.JobId = JobId; if (!db_get_job_record(ua->jcr, ua->db, &jr)) { char ed1[50]; @@ -712,6 +698,10 @@ static void insert_one_file_or_dir(UAContext *ua, RESTORE_CTX *rx, char *date, b } fclose(ffd); break; + case '?': + p++; + insert_table_into_findex_list(ua, rx, p); + break; default: if (dir) { insert_dir_into_findex_list(ua, rx, ua->cmd, date); @@ -732,7 +722,7 @@ static bool insert_file_into_findex_list(UAContext *ua, RESTORE_CTX *rx, char *f { char ed1[50]; - strip_trailing_junk(file); + strip_trailing_newline(file); split_path_and_filename(rx, file); if (*rx->JobIds == 0) { Mmsg(rx->query, uar_jobid_fileindex, date, rx->path, rx->fname, @@ -800,6 +790,36 @@ static bool insert_dir_into_findex_list(UAContext *ua, RESTORE_CTX *rx, char *di return true; } +/* + * Get the JobId and FileIndexes of all files in the specified table + */ +static bool insert_table_into_findex_list(UAContext *ua, RESTORE_CTX *rx, char *table) +{ + char ed1[50]; + + strip_trailing_junk(table); + Mmsg(rx->query, uar_jobid_fileindex_from_table, table); + + rx->found = false; + /* Find and insert jobid and File Index */ + if (!db_sql_query(ua->db, rx->query, jobid_fileindex_handler, (void *)rx)) { + bsendmsg(ua, _("Query failed: %s. ERR=%s\n"), + rx->query, db_strerror(ua->db)); + } + if (!rx->found) { + bsendmsg(ua, _("No table found: %s\n"), table); + return true; + } + /* + * Find the MediaTypes for this JobId and add to the name_list + */ + Mmsg(rx->query, uar_mediatype, edit_int64(rx->JobId, ed1)); + if (!db_sql_query(ua->db, rx->query, unique_name_list_handler, (void *)&rx->name_list)) { + bsendmsg(ua, "%s", db_strerror(ua->db)); + return false; + } + return true; +} static void split_path_and_filename(RESTORE_CTX *rx, char *name) { @@ -951,7 +971,7 @@ static bool build_directory_tree(UAContext *ua, RESTORE_CTX *rx) /* Check MediaType and select storage that corresponds */ get_storage_from_mediatype(ua, &rx->name_list, rx); - if (find_arg(ua, N_("done")) < 0) { + if (find_arg(ua, NT_("done")) < 0) { /* Let the user interact in selecting which files to restore */ OK = user_select_files_from_tree(&tree); } @@ -1130,8 +1150,15 @@ bail_out: } -/* Return next JobId from comma separated list */ -static int get_next_jobid_from_list(char **p, uint32_t *JobId) +/* + * Return next JobId from comma separated list + * + * Returns: + * 1 if next JobId returned + * 0 if no more JobIds are in list + * -1 there is an error + */ +int get_next_jobid_from_list(char **p, JobId_t *JobId) { char jobid[30]; char *q = *p;