]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/dird/ua_output.c
Merge branch 'master' of ssh://bacula.git.sourceforge.net/gitroot/bacula/bacula
[bacula/bacula] / bacula / src / dird / ua_output.c
index 66dc23d51bc69e768d21681ff7fae7ba9a67a988..55c308966a248eb8b62d1ced01e628b5b7e7eb65 100644 (file)
@@ -1,7 +1,7 @@
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2000-2007 Free Software Foundation Europe e.V.
+   Copyright (C) 2000-2009 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.
@@ -20,7 +20,7 @@
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Bacula® is a registered trademark of John Walker.
+   Bacula® is a registered trademark of Kern Sibbald.
    The licensor of Bacula is the Free Software Foundation Europe
    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
    Switzerland, email:ftf@fsfeurope.org.
 /* Imported subroutines */
 
 /* Imported variables */
-extern int r_first;
-extern int r_last;
-extern RES_TABLE resources[];
-extern RES **res_head;
 
 /* Imported functions */
 
@@ -100,7 +96,29 @@ int gui_cmd(UAContext *ua, const char *cmd)
    return 1;
 }
 
-
+/* 
+ * Enter with Resources locked 
+ */
+static void show_disabled_jobs(UAContext *ua)
+{
+   JOB *job;
+   bool first = true;
+   foreach_res(job, R_JOB) {   
+      if (!acl_access_ok(ua, Job_ACL, job->name())) {
+         continue;
+      }
+      if (!job->enabled) {
+         if (first) {
+            first = false;
+            ua->send_msg(_("Disabled Jobs:\n"));
+         }
+         ua->send_msg("   %s\n", job->name());
+     }
+  }
+  if (first) {
+     ua->send_msg(_("No disabled Jobs.\n"));
+  }
+}
 
 struct showstruct {const char *res_name; int type;};
 static struct showstruct reses[] = {
@@ -127,6 +145,7 @@ static struct showstruct reses[] = {
  *  show all
  *  show <resource-keyword-name>  e.g. show directors
  *  show <resource-keyword-name>=<name> e.g. show director=HeadMan
+ *  show disabled    shows disabled jobs
  *
  */
 int show_cmd(UAContext *ua, const char *cmd)
@@ -141,6 +160,10 @@ int show_cmd(UAContext *ua, const char *cmd)
 
    LockRes();
    for (i=1; i<ua->argc; i++) {
+      if (strcasecmp(ua->argk[i], _("disabled")) == 0) {
+         show_disabled_jobs(ua);
+         goto bail_out;
+      }
       type = 0;
       res_name = ua->argk[i];
       if (!ua->argv[i]) {             /* was a name given? */
@@ -216,6 +239,8 @@ bail_out:
  *  list jobname=name   - same as above 
  *  list jobmedia jobid=<nn>
  *  list jobmedia job=name
+ *  list joblog jobid=<nn>
+ *  list joblog job=name
  *  list files jobid=<nn> - list files saved for job nn
  *  list files job=name
  *  list pools          - list pool records
@@ -225,6 +250,7 @@ bail_out:
  *  list clients        - list clients
  *  list nextvol job=xx  - list the next vol to be used by job
  *  list nextvolume job=xx - same as above.
+ *  list copies jobid=x,y,z
  *
  */
 
@@ -321,7 +347,7 @@ static int do_list_cmd(UAContext *ua, const char *cmd, e_list_type llist)
 
       /* List JOBMEDIA */
       } else if (strcasecmp(ua->argk[i], NT_("jobmedia")) == 0) {
-         int done = FALSE;
+         bool done = false;
          for (j=i+1; j<ua->argc; j++) {
             if (strcasecmp(ua->argk[j], NT_("ujobid")) == 0 && ua->argv[j]) {
                bstrncpy(jr.Job, ua->argv[j], MAX_NAME_LENGTH);
@@ -334,13 +360,36 @@ static int do_list_cmd(UAContext *ua, const char *cmd, e_list_type llist)
                continue;
             }
             db_list_jobmedia_records(ua->jcr, ua->db, jobid, prtit, ua, llist);
-            done = TRUE;
+            done = true;
          }
          if (!done) {
             /* List for all jobs (jobid=0) */
             db_list_jobmedia_records(ua->jcr, ua->db, 0, prtit, ua, llist);
          }
 
+      /* List JOBLOG */
+      } else if (strcasecmp(ua->argk[i], NT_("joblog")) == 0) {
+         bool done = false;
+         for (j=i+1; j<ua->argc; j++) {
+            if (strcasecmp(ua->argk[j], NT_("ujobid")) == 0 && ua->argv[j]) {
+               bstrncpy(jr.Job, ua->argv[j], MAX_NAME_LENGTH);
+               jr.JobId = 0;
+               db_get_job_record(ua->jcr, ua->db, &jr);
+               jobid = jr.JobId;
+            } else if (strcasecmp(ua->argk[j], NT_("jobid")) == 0 && ua->argv[j]) {
+               jobid = str_to_int64(ua->argv[j]);
+            } else {
+               continue;
+            }
+            db_list_joblog_records(ua->jcr, ua->db, jobid, prtit, ua, llist);
+            done = true;
+         }
+         if (!done) {
+            /* List for all jobs (jobid=0) */
+            db_list_joblog_records(ua->jcr, ua->db, 0, prtit, ua, llist);
+         }
+
+
       /* List POOLS */
       } else if (strcasecmp(ua->argk[i], NT_("pool")) == 0 ||
                  strcasecmp(ua->argk[i], NT_("pools")) == 0) {
@@ -433,6 +482,19 @@ static int do_list_cmd(UAContext *ua, const char *cmd, e_list_type llist)
             }
          }
          list_nextvol(ua, n);
+      } else if (strcasecmp(ua->argk[i], NT_("copies")) == 0) {
+         char *jobids = NULL;
+         uint32_t limit=0;
+         for (j=i+1; j<ua->argc; j++) {
+            if (strcasecmp(ua->argk[j], NT_("jobid")) == 0 && ua->argv[j]) {
+               if (is_a_number_list(ua->argv[j])) {
+                  jobids = ua->argv[j];
+               }
+            } else if (strcasecmp(ua->argk[j], NT_("limit")) == 0 && ua->argv[j]) {
+               limit = atoi(ua->argv[j]);
+            } 
+         }
+         db_list_copies_records(ua->jcr,ua->db,limit,jobids,prtit,ua,llist);
       } else if (strcasecmp(ua->argk[i], NT_("limit")) == 0
                  || strcasecmp(ua->argk[i], NT_("days")) == 0) {
          /* Ignore it */
@@ -446,10 +508,10 @@ static int do_list_cmd(UAContext *ua, const char *cmd, e_list_type llist)
 static bool list_nextvol(UAContext *ua, int ndays)
 {
    JOB *job;
-   JCR *jcr = ua->jcr;
+   JCR *jcr;          
    USTORE store;
    RUN *run;
-   time_t runtime;
+   utime_t runtime;
    bool found = false;
    MEDIA_DBR mr;
    POOL_DBR pr;
@@ -463,28 +525,32 @@ static bool list_nextvol(UAContext *ua, int ndays)
    } else {
       job = (JOB *)GetResWithName(R_JOB, ua->argv[i]);
       if (!job) {
-         Jmsg(jcr, M_ERROR, 0, _("%s is not a job name.\n"), ua->argv[i]);
+         Jmsg(ua->jcr, M_ERROR, 0, _("%s is not a job name.\n"), ua->argv[i]);
          if ((job = select_job_resource(ua)) == NULL) {
             return false;
          }
       }
    }
+
+   jcr = new_jcr(sizeof(JCR), dird_free_jcr);
    for (run=NULL; (run = find_next_run(run, job, runtime, ndays)); ) {
       if (!complete_jcr_for_job(jcr, job, run->pool)) {
-         return false;
+         found = false;
+         goto get_out;
       }
       if (!jcr->jr.PoolId) {
-         ua->error_msg(_("Could not Pool Job %s\n"), job->name());
+         ua->error_msg(_("Could not find Pool for Job %s\n"), job->name());
          continue;
       }
       memset(&pr, 0, sizeof(pr));
       pr.PoolId = jcr->jr.PoolId;
-      if (!db_get_pool_record(ua->jcr, ua->db, &pr)) {
+      if (!db_get_pool_record(jcr, jcr->db, &pr)) {
          bstrncpy(pr.Name, "*UnknownPool*", sizeof(pr.Name));
       }
       mr.PoolId = jcr->jr.PoolId;
       get_job_storage(&store, job, run);
       mr.StorageId = store.store->StorageId;
+      /* no need to set ScratchPoolId, since we use fnv_no_create_vol */
       if (!find_next_volume_for_append(jcr, &mr, 1, fnv_no_create_vol, fnv_prune)) {
          ua->error_msg(_("Could not find next Volume for Job %s (Pool=%s, Level=%s).\n"),
             job->name(), pr.Name, level_to_str(run->level));
@@ -494,11 +560,12 @@ static bool list_nextvol(UAContext *ua, int ndays)
             job->name(), pr.Name, level_to_str(run->level), mr.VolumeName);
          found = true;
       }
-      if (jcr->db && jcr->db != ua->db) {
-         db_close_database(jcr, jcr->db);
-         jcr->db = NULL;
-      }
    }
+
+get_out:
+   db_close_database(jcr, jcr->db);
+   jcr->db = NULL;
+   free_jcr(jcr);
    if (!found) {
       ua->error_msg(_("Could not find next Volume for Job %s.\n"),
          job->hdr.name);
@@ -512,7 +579,7 @@ static bool list_nextvol(UAContext *ua, int ndays)
  * For a given job, we examine all his run records
  *  to see if it is scheduled today or tomorrow.
  */
-RUN *find_next_run(RUN *run, JOB *job, time_t &runtime, int ndays)
+RUN *find_next_run(RUN *run, JOB *job, utime_t &runtime, int ndays)
 {
    time_t now, future, endtime;
    SCHED *sched;
@@ -586,7 +653,7 @@ RUN *find_next_run(RUN *run, JOB *job, time_t &runtime, int ndays)
                   runtm.tm_min = run->minute;
                   runtm.tm_sec = 0;
                   runtime = mktime(&runtm);
-                  Dmsg2(200, "now=%d runtime=%d\n", now, runtime);
+                  Dmsg2(200, "now=%d runtime=%lld\n", now, runtime);
                   if ((runtime > now) && (runtime < endtime)) {
                      Dmsg2(200, "Found it level=%d %c\n", run->level, run->level);
                      return run;         /* found it, return run resource */
@@ -620,7 +687,8 @@ bool complete_jcr_for_job(JCR *jcr, JOB *job, POOL *pool)
    }
 
    Dmsg0(100, "complete_jcr open db\n");
-   jcr->db = jcr->db=db_init_database(jcr, jcr->catalog->db_name, jcr->catalog->db_user,
+   jcr->db = jcr->db=db_init(jcr, jcr->catalog->db_driver, jcr->catalog->db_name, 
+                      jcr->catalog->db_user,
                       jcr->catalog->db_password, jcr->catalog->db_address,
                       jcr->catalog->db_port, jcr->catalog->db_socket,
                       jcr->catalog->mult_db_connections);