]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/dird/ua_restore.c
Cache path in tree.c
[bacula/bacula] / bacula / src / dird / ua_restore.c
index e169cfdf3bfb34f61dc9b0e9e2590473d99f74cc..a7565991feb5f9256cf82be19fa8231525b1505e 100644 (file)
@@ -53,6 +53,7 @@ struct JOBIDS {
    utime_t JobTDate;
    uint32_t TotalFiles;
    char ClientName[MAX_NAME_LENGTH];
+   char last_jobid[10];
    char JobIds[200];                 /* User entered string of JobIds */
    STORE  *store;
 };
@@ -80,7 +81,6 @@ static void free_name_list(NAME_LIST *name_list);
 static void get_storage_from_mediatype(UAContext *ua, NAME_LIST *name_list, JOBIDS *ji);
 static int select_backups_before_date(UAContext *ua, JOBIDS *ji, char *date);
 
-
 /*
  *   Restore files
  *
@@ -176,9 +176,8 @@ int restorecmd(UAContext *ua, char *cmd)
       if (!db_sql_query(ua->db, query, unique_name_list_handler, (void *)&name_list)) {
          bsendmsg(ua, "%s", db_strerror(ua->db));
       }
-
    }
-   bsendmsg(ua, "%d item%s inserted into the tree and marked for extraction.\n", 
+   bsendmsg(ua, "%d Job%s inserted into the tree and marked for extraction.\n", 
       items, items==1?"":"s");
    free_pool_memory(query);
 
@@ -186,8 +185,10 @@ int restorecmd(UAContext *ua, char *cmd)
    get_storage_from_mediatype(ua, &name_list, &ji);
    free_name_list(&name_list);
 
-   /* Let the user select which files to restore */
-   user_select_files_from_tree(&tree);
+   if (find_arg(ua, _("all")) < 0) {
+      /* Let the user select which files to restore */
+      user_select_files_from_tree(&tree);
+   }
 
    /*
     * Walk down through the tree finding all files marked to be 
@@ -252,8 +253,8 @@ int restorecmd(UAContext *ua, char *cmd)
           job->hdr.name, ji.ClientName, ji.store?ji.store->hdr.name:"",
          working_directory);
    }
-   Dmsg1(400, "Submitting: %s\n", ua->cmd);
    
+   Dmsg1(400, "Submitting: %s\n", ua->cmd);
    parse_ua_args(ua);
    runcmd(ua, ua->cmd);
 
@@ -273,7 +274,8 @@ static int user_select_jobids(UAContext *ua, JOBIDS *ji)
    JobId_t JobId;
    JOB_DBR jr;
    POOLMEM *query;
-   int done = 0;
+   bool done = false;
+   int i;
    char *list[] = { 
       "List last 20 Jobs run",
       "List Jobs where a given File is saved",
@@ -284,23 +286,68 @@ static int user_select_jobids(UAContext *ua, JOBIDS *ji)
       "Cancel",
       NULL };
 
-   bsendmsg(ua, _("\nFirst you select one or more JobIds that contain files\n"
+   char *kw[] = {
+      "jobid",     /* 0 */
+      "current",   /* 1 */
+      "before",    /* 2 */
+      NULL
+   };
+
+   switch (find_arg_keyword(ua, kw)) {
+   case 0:                           /* jobid */
+      i = find_arg_with_value(ua, _("jobid"));
+      if (i < 0) {
+        return 0;
+      }
+      bstrncpy(ji->JobIds, ua->argv[i], sizeof(ji->JobIds));
+      done = true;
+      break;
+   case 1:                           /* current */
+      bstrutime(date, sizeof(date), time(NULL));
+      if (!select_backups_before_date(ua, ji, date)) {
+        return 0;
+      }
+      done = true;
+      break;
+   case 2:                           /* before */
+      i = find_arg_with_value(ua, _("before"));
+      if (i < 0) {
+        return 0;
+      }
+      if (str_to_utime(ua->argv[i]) == 0) {
+         bsendmsg(ua, _("Improper date format: %s\n"), ua->argv[i]);
+        return 0;
+      }
+      bstrncpy(date, ua->argv[i], sizeof(date));
+      if (!select_backups_before_date(ua, ji, date)) {
+        return 0;
+      }
+      done = true;
+      break;
+   default:
+      break;
+   }
+       
+   if (!done) {
+      bsendmsg(ua, _("\nFirst you select one or more JobIds that contain files\n"
                   "to be restored. You will be presented several methods\n"
                   "of specifying the JobIds. Then you will be allowed to\n"
                   "select which files from those JobIds are to be restored.\n\n"));
+   }
 
+   /* If choice not already made above, prompt */
    for ( ; !done; ) {
       start_prompt(ua, _("To select the JobIds, you have the following choices:\n"));
       for (int i=0; list[i]; i++) {
         add_prompt(ua, list[i]);
       }
-      done = 1;
+      done = true;
       switch (do_prompt(ua, "", _("Select item: "), NULL, 0)) {
       case -1:                       /* error */
         return 0;
       case 0:                        /* list last 20 Jobs run */
         db_list_sql_query(ua->jcr, ua->db, uar_list_jobs, prtit, ua, 1, HORZ_LIST);
-        done = 0;
+        done = false;
         break;
       case 1:                        /* list where a file is saved */
         char *fname;
@@ -316,7 +363,7 @@ static int user_select_jobids(UAContext *ua, JOBIDS *ji)
         free(fname);
         db_list_sql_query(ua->jcr, ua->db, query, prtit, ua, 1, HORZ_LIST);
         free_pool_memory(query);
-        done = 0;
+        done = false;
         break;
       case 2:                        /* enter a list of JobIds */
          if (!get_cmd(ua, _("Enter JobId(s), comma separated, to restore: "))) {
@@ -329,7 +376,7 @@ static int user_select_jobids(UAContext *ua, JOBIDS *ji)
            return 0;
         }
         db_list_sql_query(ua->jcr, ua->db, ua->cmd, prtit, ua, 1, HORZ_LIST);
-        done = 0;
+        done = false;
         break;
       case 4:                        /* Select the most recent backups */
         bstrutime(date, sizeof(date), time(NULL));
@@ -363,7 +410,8 @@ static int user_select_jobids(UAContext *ua, JOBIDS *ji)
       bsendmsg(ua, _("No Jobs selected.\n"));
       return 0;
    }
-   bsendmsg(ua, _("You have selected the following JobId: %s\n"), ji->JobIds);
+   bsendmsg(ua, _("You have selected the following JobId%s: %s\n"), 
+      strchr(ji->JobIds,',')?"s":"",ji->JobIds);
 
    memset(&jr, 0, sizeof(JOB_DBR));
 
@@ -377,6 +425,9 @@ static int user_select_jobids(UAContext *ua, JOBIDS *ji)
       if (stat == 0) {
         break;
       }
+      if (jr.JobId == JobId) {
+        continue;                    /* duplicate of last JobId */
+      }
       jr.JobId = JobId;
       if (!db_get_job_record(ua->jcr, ua->db, &jr)) {
          bsendmsg(ua, _("Unable to get Job record. ERR=%s\n"), db_strerror(ua->db));
@@ -473,6 +524,7 @@ static int select_backups_before_date(UAContext *ua, JOBIDS *ji, char *date)
 
    /* Get the JobIds from that list */
    ji->JobIds[0] = 0;
+   ji->last_jobid[0] = 0;
    if (!db_sql_query(ua->db, uar_sel_jobid_temp, jobid_handler, (void *)ji)) {
       bsendmsg(ua, "%s\n", db_strerror(ua->db));
    }
@@ -493,15 +545,14 @@ bail_out:
    return stat;
 }
 
-
+/* Return next JobId from comma separated list */
 static int next_jobid_from_list(char **p, uint32_t *JobId)
 {
    char jobid[30];
-   int i;
    char *q = *p;
 
    jobid[0] = 0;
-   for (i=0; i<(int)sizeof(jobid); i++) {
+   for (int i=0; i<(int)sizeof(jobid); i++) {
       if (*q == ',' || *q == 0) {
         q++;
         break;
@@ -524,13 +575,17 @@ static int jobid_handler(void *ctx, int num_fields, char **row)
 {
    JOBIDS *ji = (JOBIDS *)ctx;
 
+   if (strcmp(ji->last_jobid, row[0]) == 0) {          
+      return 0;                      /* duplicate id */
+   }
+   bstrncpy(ji->last_jobid, row[0], sizeof(ji->last_jobid));
+   /* Concatenate a JobId if it does not exceed array size */
    if (strlen(ji->JobIds)+strlen(row[0])+2 < sizeof(ji->JobIds)) {
       if (ji->JobIds[0] != 0) {
          strcat(ji->JobIds, ",");
       }
       strcat(ji->JobIds, row[0]);
    }
-
    return 0;
 }
 
@@ -597,9 +652,7 @@ static int unique_name_list_handler(void *ctx, int num_fields, char **row)
  */
 static void print_name_list(UAContext *ua, NAME_LIST *name_list)
 { 
-   int i;
-
-   for (i=0; i < name_list->num_ids; i++) {
+   for (int i=0; i < name_list->num_ids; i++) {
       bsendmsg(ua, "%s\n", name_list->name[i]);
    }
 }
@@ -610,9 +663,7 @@ static void print_name_list(UAContext *ua, NAME_LIST *name_list)
  */
 static void free_name_list(NAME_LIST *name_list)
 { 
-   int i;
-
-   for (i=0; i < name_list->num_ids; i++) {
+   for (int i=0; i < name_list->num_ids; i++) {
       free(name_list->name[i]);
    }
    if (name_list->name) {