]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/dird/ua_cmds.c
kes Rework prune_volumes() code to take account of InChanger flag,
[bacula/bacula] / bacula / src / dird / ua_cmds.c
index 917cf28a51360ccd1691996a93d99f4589e6bb2e..1b97b952faaac21b354c397aea91a9ac2d5d7e9e 100644 (file)
@@ -7,8 +7,8 @@
    many others, a complete list can be found in the file AUTHORS.
    This program is Free Software; you can redistribute it and/or
    modify it under the terms of version two of the GNU General Public
-   License as published by the Free Software Foundation plus additions
-   that are listed in the file LICENSE.
+   License as published by the Free Software Foundation and included
+   in the file LICENSE.
 
    This program is distributed in the hope that it will be useful, but
    WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -47,51 +47,53 @@ extern jobq_t job_queue;              /* job queue */
 
 
 /* Imported functions */
-extern int status_cmd(UAContext *ua, const char *cmd);
+extern int autodisplay_cmd(UAContext *ua, const char *cmd);
+extern int gui_cmd(UAContext *ua, const char *cmd);
+extern int label_cmd(UAContext *ua, const char *cmd);
 extern int list_cmd(UAContext *ua, const char *cmd);
 extern int llist_cmd(UAContext *ua, const char *cmd);
-extern int show_cmd(UAContext *ua, const char *cmd);
 extern int messagescmd(UAContext *ua, const char *cmd);
-extern int autodisplay_cmd(UAContext *ua, const char *cmd);
-extern int gui_cmd(UAContext *ua, const char *cmd);
-extern int sqlquerycmd(UAContext *ua, const char *cmd);
-extern int querycmd(UAContext *ua, const char *cmd);
-extern int retentioncmd(UAContext *ua, const char *cmd);
 extern int prunecmd(UAContext *ua, const char *cmd);
 extern int purgecmd(UAContext *ua, const char *cmd);
-extern int restore_cmd(UAContext *ua, const char *cmd);
-extern int label_cmd(UAContext *ua, const char *cmd);
+extern int querycmd(UAContext *ua, const char *cmd);
 extern int relabel_cmd(UAContext *ua, const char *cmd);
+extern int restore_cmd(UAContext *ua, const char *cmd);
+extern int retentioncmd(UAContext *ua, const char *cmd);
+extern int show_cmd(UAContext *ua, const char *cmd);
+extern int sqlquerycmd(UAContext *ua, const char *cmd);
+extern int status_cmd(UAContext *ua, const char *cmd);
 extern int update_cmd(UAContext *ua, const char *cmd);
 
 /* Forward referenced functions */
 static int add_cmd(UAContext *ua, const char *cmd);
-static int create_cmd(UAContext *ua, const char *cmd);
+static int automount_cmd(UAContext *ua, const char *cmd);
 static int cancel_cmd(UAContext *ua, const char *cmd);
-static int enable_cmd(UAContext *ua, const char *cmd);
+static int create_cmd(UAContext *ua, const char *cmd);
+static int delete_cmd(UAContext *ua, const char *cmd);
 static int disable_cmd(UAContext *ua, const char *cmd);
-static int setdebug_cmd(UAContext *ua, const char *cmd);
-static int trace_cmd(UAContext *ua, const char *cmd);
-static int var_cmd(UAContext *ua, const char *cmd);
+static int enable_cmd(UAContext *ua, const char *cmd);
 static int estimate_cmd(UAContext *ua, const char *cmd);
 static int help_cmd(UAContext *ua, const char *cmd);
-static int delete_cmd(UAContext *ua, const char *cmd);
-static int use_cmd(UAContext *ua, const char *cmd);
-static int unmount_cmd(UAContext *ua, const char *cmd);
-static int version_cmd(UAContext *ua, const char *cmd);
-static int automount_cmd(UAContext *ua, const char *cmd);
-static int time_cmd(UAContext *ua, const char *cmd);
-static int reload_cmd(UAContext *ua, const char *cmd);
-static int delete_volume(UAContext *ua);
-static int delete_pool(UAContext *ua);
-static void delete_job(UAContext *ua);
+static int memory_cmd(UAContext *ua, const char *cmd);
 static int mount_cmd(UAContext *ua, const char *cmd);
+static int python_cmd(UAContext *ua, const char *cmd);
 static int release_cmd(UAContext *ua, const char *cmd);
-static int wait_cmd(UAContext *ua, const char *cmd);
+static int reload_cmd(UAContext *ua, const char *cmd);
+static int setdebug_cmd(UAContext *ua, const char *cmd);
 static int setip_cmd(UAContext *ua, const char *cmd);
-static int python_cmd(UAContext *ua, const char *cmd);
+static int time_cmd(UAContext *ua, const char *cmd);
+static int trace_cmd(UAContext *ua, const char *cmd);
+static int unmount_cmd(UAContext *ua, const char *cmd);
+static int use_cmd(UAContext *ua, const char *cmd);
+static int var_cmd(UAContext *ua, const char *cmd);
+static int version_cmd(UAContext *ua, const char *cmd);
+static int wait_cmd(UAContext *ua, const char *cmd);
+
 static void do_job_delete(UAContext *ua, JobId_t JobId);
 static void delete_job_id_range(UAContext *ua, char *tok);
+static int delete_volume(UAContext *ua);
+static int delete_pool(UAContext *ua);
+static void delete_job(UAContext *ua);
 
 int qhelp_cmd(UAContext *ua, const char *cmd);
 int quit_cmd(UAContext *ua, const char *cmd);
@@ -114,6 +116,7 @@ static struct cmdstruct commands[] = {
  { NT_("list"),       list_cmd,      _("list [pools | jobs | jobtotals | media <pool=pool-name> | files <jobid=nn>]; from catalog")},
  { NT_("label"),      label_cmd,     _("label a tape")},
  { NT_("llist"),      llist_cmd,     _("full or long list like list command")},
+ { NT_("memory"),     memory_cmd,    _("print current memory usage")},
  { NT_("messages"),   messagescmd,   _("messages")},
  { NT_("mount"),      mount_cmd,     _("mount <storage-name>")},
  { NT_("prune"),      prunecmd,      _("prune expired records from catalog")},
@@ -150,7 +153,9 @@ int do_a_command(UAContext *ua, const char *cmd)
 {
    unsigned int i;
    int len, stat;
+   bool ok = false;
    bool found = false;
+   BSOCK *user = ua->UA_sock;
 
    stat = 1;
 
@@ -171,15 +176,17 @@ int do_a_command(UAContext *ua, const char *cmd)
              !acl_access_ok(ua, Command_ACL, ua->argk[0], len)) {
             break;
          }
-         stat = (*commands[i].func)(ua, cmd);   /* go execute command */
+         if (ua->api) user->signal(BNET_CMD_BEGIN);
+         ok = (*commands[i].func)(ua, cmd);   /* go execute command */
          found = true;
          break;
       }
    }
    if (!found) {
-      bnet_fsend(ua->UA_sock, _("%s: is an invalid command.\n"), ua->argk[0]);
+      user->fsend(_("%s: is an invalid command.\n"), ua->argk[0]);
    }
-   return stat;
+   if (ua->api) user->signal(ok?BNET_CMD_OK:BNET_CMD_FAILED);
+   return ok;
 }
 
 /*
@@ -216,7 +223,7 @@ static int add_cmd(UAContext *ua, const char *cmd)
    STORE *store;
    int Slot = 0, InChanger = 0;
 
-   bsendmsg(ua, _(
+   ua->send_msg(_(
 "You probably don't want to be using this command since it\n"
 "creates database records without labeling the Volumes.\n"
 "You probably want to use the \"label\" command.\n\n"));
@@ -236,7 +243,7 @@ static int add_cmd(UAContext *ua, const char *cmd)
       pr.MaxVols, pr.PoolType);
 
    while (pr.MaxVols > 0 && pr.NumVols >= pr.MaxVols) {
-      bsendmsg(ua, _("Pool already has maximum volumes=%d\n"), pr.MaxVols);
+      ua->warning_msg(_("Pool already has maximum volumes=%d\n"), pr.MaxVols);
       for (;;) {
          if (!get_pint(ua, _("Enter new maximum (zero for unlimited): "))) {
             return 1;
@@ -265,7 +272,7 @@ static int add_cmd(UAContext *ua, const char *cmd)
       }
       num = ua->pint32_val;
       if (num < 0 || num > max) {
-         bsendmsg(ua, _("The number must be between 0 and %d\n"), max);
+         ua->warning_msg(_("The number must be between 0 and %d\n"), max);
          continue;
       }
       break;
@@ -285,11 +292,11 @@ getVolName:
       goto getVolName;
    }
    if (strlen(ua->cmd) >= MAX_NAME_LENGTH-10) {
-      bsendmsg(ua, _("Volume name too long.\n"));
+      ua->warning_msg(_("Volume name too long.\n"));
       goto getVolName;
    }
    if (strlen(ua->cmd) == 0) {
-      bsendmsg(ua, _("Volume name must be at least one character long.\n"));
+      ua->warning_msg(_("Volume name must be at least one character long.\n"));
       goto getVolName;
    }
 
@@ -303,7 +310,7 @@ getVolName:
          }
          startnum = ua->pint32_val;
          if (startnum < 1) {
-            bsendmsg(ua, _("Start number must be greater than zero.\n"));
+            ua->warning_msg(_("Start number must be greater than zero.\n"));
             continue;
          }
          break;
@@ -333,7 +340,7 @@ getVolName:
       mr.Enabled = 1;
       Dmsg1(200, "Create Volume %s\n", mr.VolumeName);
       if (!db_create_media_record(ua->jcr, ua->db, &mr)) {
-         bsendmsg(ua, "%s", db_strerror(ua->db));
+         ua->error_msg("%s", db_strerror(ua->db));
          return 1;
       }
       if (i == startnum) {
@@ -343,10 +350,10 @@ getVolName:
    pr.NumVols += num;
    Dmsg0(200, "Update pool record.\n");
    if (db_update_pool_record(ua->jcr, ua->db, &pr) != 1) {
-      bsendmsg(ua, "%s", db_strerror(ua->db));
+      ua->warning_msg("%s", db_strerror(ua->db));
       return 1;
    }
-   bsendmsg(ua, _("%d Volumes created in pool %s\n"), num, pr.Name);
+   ua->send_msg(_("%d Volumes created in pool %s\n"), num, pr.Name);
 
    return 1;
 }
@@ -393,7 +400,7 @@ static int cancel_cmd(UAContext *ua, const char *cmd)
          }
          JobId = str_to_int64(ua->argv[i]);
          if (!(jcr=get_jcr_by_id(JobId))) {
-            bsendmsg(ua, _("JobId %s is not running. Use Job name to cancel inactive jobs.\n"),  ua->argv[i]);
+            ua->error_msg(_("JobId %s is not running. Use Job name to cancel inactive jobs.\n"),  ua->argv[i]);
             return 1;
          }
          break;
@@ -402,7 +409,7 @@ static int cancel_cmd(UAContext *ua, const char *cmd)
             break;
          }
          if (!(jcr=get_jcr_by_partial_name(ua->argv[i]))) {
-            bsendmsg(ua, _("Warning Job %s is not running. Continuing anyway ...\n"), ua->argv[i]);
+            ua->warning_msg(_("Warning Job %s is not running. Continuing anyway ...\n"), ua->argv[i]);
             jcr = new_jcr(sizeof(JCR), dird_free_jcr);
             bstrncpy(jcr->Job, ua->argv[i], sizeof(jcr->Job));
          }
@@ -412,7 +419,7 @@ static int cancel_cmd(UAContext *ua, const char *cmd)
             break;
          }
          if (!(jcr=get_jcr_by_full_name(ua->argv[i]))) {
-            bsendmsg(ua, _("Warning Job %s is not running. Continuing anyway ...\n"), ua->argv[i]);
+            ua->warning_msg(_("Warning Job %s is not running. Continuing anyway ...\n"), ua->argv[i]);
             jcr = new_jcr(sizeof(JCR), dird_free_jcr);
             bstrncpy(jcr->Job, ua->argv[i], sizeof(jcr->Job));
          }
@@ -422,7 +429,7 @@ static int cancel_cmd(UAContext *ua, const char *cmd)
    }
    if (jcr) {
       if (jcr->job && !acl_access_ok(ua, Job_ACL, jcr->job->name())) {
-         bsendmsg(ua, _("Unauthorized command from this console.\n"));
+         ua->error_msg(_("Unauthorized command from this console.\n"));
          return 1;
       }
    } else {
@@ -447,9 +454,9 @@ static int cancel_cmd(UAContext *ua, const char *cmd)
 
       if (njobs == 0) {            /* no authorized */
          if (tjobs == 0) {
-            bsendmsg(ua, _("No Jobs running.\n"));
+            ua->send_msg(_("No Jobs running.\n"));
          } else {
-            bsendmsg(ua, _("None of your jobs are running.\n"));
+            ua->send_msg(_("None of your jobs are running.\n"));
          }
          return 1;
       }
@@ -479,7 +486,7 @@ static int cancel_cmd(UAContext *ua, const char *cmd)
       sscanf(buf, "JobId=%d Job=%127s", &njobs, JobName);
       jcr = get_jcr_by_full_name(JobName);
       if (!jcr) {
-         bsendmsg(ua, _("Job \"%s\" not found.\n"), JobName);
+         ua->warning_msg(_("Job \"%s\" not found.\n"), JobName);
          return 1;
       }
    }
@@ -643,18 +650,18 @@ static int create_cmd(UAContext *ua, const char *cmd)
 
    switch (create_pool(ua->jcr, ua->db, pool, POOL_OP_CREATE)) {
    case 0:
-      bsendmsg(ua, _("Error: Pool %s already exists.\n"
+      ua->error_msg(_("Error: Pool %s already exists.\n"
                "Use update to change it.\n"), pool->name());
       break;
 
    case -1:
-      bsendmsg(ua, "%s", db_strerror(ua->db));
+      ua->error_msg("%s", db_strerror(ua->db));
       break;
 
    default:
      break;
    }
-   bsendmsg(ua, _("Pool %s created.\n"), pool->name());
+   ua->send_msg(_("Pool %s created.\n"), pool->name());
    return 1;
 }
 
@@ -671,9 +678,9 @@ static int python_cmd(UAContext *ua, const char *cmd)
       term_python_interpreter();
       init_python_interpreter(director->name(), 
          director->scripts_directory, "DirStartUp");
-      bsendmsg(ua, _("Python interpreter restarted.\n"));
+      ua->send_msg(_("Python interpreter restarted.\n"));
    } else {
-      bsendmsg(ua, _("Nothing done.\n"));
+      ua->warning_msg(_("Nothing done.\n"));
    }
    return 1;
 }
@@ -689,14 +696,14 @@ static int setip_cmd(UAContext *ua, const char *cmd)
    CLIENT *client;
    char buf[1024];
    if (!ua->cons || !acl_access_ok(ua, Client_ACL, ua->cons->name())) {
-      bsendmsg(ua, _("Unauthorized command from this console.\n"));
+      ua->error_msg(_("Unauthorized command from this console.\n"));
       return 1;
    }
    LockRes();
-   client = (CLIENT *)GetResWithName(R_CLIENT, ua->cons->name());
+   client = GetClientResWithName(ua->cons->name());
 
    if (!client) {
-      bsendmsg(ua, _("Client \"%s\" not found.\n"), ua->cons->name());
+      ua->error_msg(_("Client \"%s\" not found.\n"), ua->cons->name());
       goto get_out;
    }
    if (client->address) {
@@ -705,7 +712,7 @@ static int setip_cmd(UAContext *ua, const char *cmd)
    /* MA Bug 6 remove ifdef */
    sockaddr_to_ascii(&(ua->UA_sock->client_addr), buf, sizeof(buf));
    client->address = bstrdup(buf);
-   bsendmsg(ua, _("Client \"%s\" address set to %s\n"),
+   ua->send_msg(_("Client \"%s\" address set to %s\n"),
             client->name(), client->address);
 get_out:
    UnlockRes();
@@ -726,20 +733,20 @@ static void do_en_disable_cmd(UAContext *ua, bool setting)
       }
    } else {
       LockRes();
-      job = (JOB *)GetResWithName(R_JOB, ua->argv[i]);
+      job = GetJobResWithName(ua->argv[i]);
       UnlockRes();
    } 
    if (!job) {
-      bsendmsg(ua, _("Job \"%s\" not found.\n"), ua->argv[i]);
+      ua->error_msg(_("Job \"%s\" not found.\n"), ua->argv[i]);
       return;
    }
 
    if (!acl_access_ok(ua, Job_ACL, job->name())) {
-      bsendmsg(ua, _("Unauthorized command from this console.\n"));
+      ua->error_msg(_("Unauthorized command from this console.\n"));
       return;
    }
    job->enabled = setting;
-   bsendmsg(ua, _("Job \"%s\" %sabled\n"), job->name(), setting?"en":"dis");
+   ua->send_msg(_("Job \"%s\" %sabled\n"), job->name(), setting?"en":"dis");
    return;
 }
 
@@ -766,17 +773,17 @@ static void do_storage_setdebug(UAContext *ua, STORE *store, int level, int trac
    pm_strcpy(lstore.store_source, _("unknown source"));
    set_wstorage(jcr, &lstore);
    /* Try connecting for up to 15 seconds */
-   bsendmsg(ua, _("Connecting to Storage daemon %s at %s:%d\n"),
+   ua->send_msg(_("Connecting to Storage daemon %s at %s:%d\n"),
       store->name(), store->address, store->SDport);
    if (!connect_to_storage_daemon(jcr, 1, 15, 0)) {
-      bsendmsg(ua, _("Failed to connect to Storage daemon.\n"));
+      ua->error_msg(_("Failed to connect to Storage daemon.\n"));
       return;
    }
    Dmsg0(120, _("Connected to storage daemon\n"));
    sd = jcr->store_bsock;
    bnet_fsend(sd, "setdebug=%d trace=%d\n", level, trace_flag);
    if (bnet_recv(sd) >= 0) {
-      bsendmsg(ua, "%s", sd->msg);
+      ua->send_msg("%s", sd->msg);
    }
    bnet_sig(sd, BNET_TERMINATE);
    bnet_close(sd);
@@ -792,17 +799,17 @@ static void do_client_setdebug(UAContext *ua, CLIENT *client, int level, int tra
 
    ua->jcr->client = client;
    /* Try to connect for 15 seconds */
-   bsendmsg(ua, _("Connecting to Client %s at %s:%d\n"),
+   ua->send_msg(_("Connecting to Client %s at %s:%d\n"),
       client->name(), client->address, client->FDport);
    if (!connect_to_file_daemon(ua->jcr, 1, 15, 0)) {
-      bsendmsg(ua, _("Failed to connect to Client.\n"));
+      ua->error_msg(_("Failed to connect to Client.\n"));
       return;
    }
    Dmsg0(120, "Connected to file daemon\n");
    fd = ua->jcr->file_bsock;
    bnet_fsend(fd, "setdebug=%d trace=%d\n", level, trace_flag);
    if (bnet_recv(fd) >= 0) {
-      bsendmsg(ua, "%s", fd->msg);
+      ua->send_msg("%s", fd->msg);
    }
    bnet_sig(fd, BNET_TERMINATE);
    bnet_close(fd);
@@ -942,7 +949,7 @@ static int setdebug_cmd(UAContext *ua, const char *cmd)
           strcasecmp(ua->argk[i], "fd") == 0) {
          client = NULL;
          if (ua->argv[i]) {
-            client = (CLIENT *)GetResWithName(R_CLIENT, ua->argv[i]);
+            client = GetClientResWithName(ua->argv[i]);
             if (client) {
                do_client_setdebug(ua, client, level, trace_flag);
                return 1;
@@ -960,7 +967,7 @@ static int setdebug_cmd(UAContext *ua, const char *cmd)
           strcasecmp(ua->argk[i], NT_("sd")) == 0) {
          store = NULL;
          if (ua->argv[i]) {
-            store = (STORE *)GetResWithName(R_STORAGE, ua->argv[i]);
+            store = GetStoreResWithName(ua->argv[i]);
             if (store) {
                do_storage_setdebug(ua, store, level, trace_flag);
                return 1;
@@ -1045,7 +1052,7 @@ static int var_cmd(UAContext *ua, const char *cmd)
    }
    Dmsg1(100, "Var=%s:\n", var);
    variable_expansion(ua->jcr, var, &val);
-   bsendmsg(ua, "%s\n", val);
+   ua->send_msg("%s\n", val);
    free_pool_memory(val);
    return 1;
 }
@@ -1064,15 +1071,15 @@ static int estimate_cmd(UAContext *ua, const char *cmd)
       if (strcasecmp(ua->argk[i], NT_("client")) == 0 ||
           strcasecmp(ua->argk[i], NT_("fd")) == 0) {
          if (ua->argv[i]) {
-            client = (CLIENT *)GetResWithName(R_CLIENT, ua->argv[i]);
+            client = GetClientResWithName(ua->argv[i]);
             continue;
          }
       }
       if (strcasecmp(ua->argk[i], NT_("job")) == 0) {
          if (ua->argv[i]) {
-            job = (JOB *)GetResWithName(R_JOB, ua->argv[i]);
+            job = GetJobResWithName(ua->argv[i]);
             if (job && !acl_access_ok(ua, Job_ACL, job->name())) {
-               bsendmsg(ua, _("No authorization for Job \"%s\"\n"), job->name());
+               ua->error_msg(_("No authorization for Job \"%s\"\n"), job->name());
                return 1;
             }
             continue;
@@ -1080,9 +1087,9 @@ static int estimate_cmd(UAContext *ua, const char *cmd)
       }
       if (strcasecmp(ua->argk[i], NT_("fileset")) == 0) {
          if (ua->argv[i]) {
-            fileset = (FILESET *)GetResWithName(R_FILESET, ua->argv[i]);
+            fileset = GetFileSetResWithName(ua->argv[i]);
             if (fileset && !acl_access_ok(ua, FileSet_ACL, fileset->name())) {
-               bsendmsg(ua, _("No authorization for FileSet \"%s\"\n"), fileset->name());
+               ua->error_msg(_("No authorization for FileSet \"%s\"\n"), fileset->name());
                return 1;
             }
             continue;
@@ -1094,7 +1101,7 @@ static int estimate_cmd(UAContext *ua, const char *cmd)
       }
       if (strcasecmp(ua->argk[i], NT_("level")) == 0) {
          if (!get_level_from_name(ua->jcr, ua->argv[i])) {
-            bsendmsg(ua, _("Level %s not valid.\n"), ua->argv[i]);
+            ua->error_msg(_("Level %s not valid.\n"), ua->argv[i]);
          }
          continue;
       }
@@ -1105,13 +1112,13 @@ static int estimate_cmd(UAContext *ua, const char *cmd)
       }
    }
    if (!job) {
-      job = (JOB *)GetResWithName(R_JOB, ua->argk[1]);
+      job = GetJobResWithName(ua->argk[1]);
       if (!job) {
-         bsendmsg(ua, _("No job specified.\n"));
+         ua->error_msg(_("No job specified.\n"));
          return 1;
       }
       if (!acl_access_ok(ua, Job_ACL, job->name())) {
-         bsendmsg(ua, _("No authorization for Job \"%s\"\n"), job->name());
+         ua->error_msg(_("No authorization for Job \"%s\"\n"), job->name());
          return 1;
       }
    }
@@ -1143,20 +1150,20 @@ static int estimate_cmd(UAContext *ua, const char *cmd)
 
    get_level_since_time(ua->jcr, since, sizeof(since));
 
-   bsendmsg(ua, _("Connecting to Client %s at %s:%d\n"),
+   ua->send_msg(_("Connecting to Client %s at %s:%d\n"),
       job->client->name(), job->client->address, job->client->FDport);
    if (!connect_to_file_daemon(jcr, 1, 15, 0)) {
-      bsendmsg(ua, _("Failed to connect to Client.\n"));
+      ua->error_msg(_("Failed to connect to Client.\n"));
       return 1;
    }
 
    if (!send_include_list(jcr)) {
-      bsendmsg(ua, _("Error sending include list.\n"));
+      ua->error_msg(_("Error sending include list.\n"));
       goto bail_out;
    }
 
    if (!send_exclude_list(jcr)) {
-      bsendmsg(ua, _("Error sending exclude list.\n"));
+      ua->error_msg(_("Error sending exclude list.\n"));
       goto bail_out;
    }
 
@@ -1166,7 +1173,7 @@ static int estimate_cmd(UAContext *ua, const char *cmd)
 
    bnet_fsend(jcr->file_bsock, "estimate listing=%d\n", listing);
    while (bnet_recv(jcr->file_bsock) >= 0) {
-      bsendmsg(ua, "%s", jcr->file_bsock->msg);
+      ua->send_msg("%s", jcr->file_bsock->msg);
    }
 
 bail_out:
@@ -1189,7 +1196,7 @@ static int time_cmd(UAContext *ua, const char *cmd)
    struct tm tm;
    (void)localtime_r(&ttime, &tm);
    strftime(sdt, sizeof(sdt), "%d-%b-%Y %H:%M:%S", &tm);
-   bsendmsg(ua, "%s\n", sdt);
+   ua->send_msg("%s\n", sdt);
    return 1;
 }
 
@@ -1241,7 +1248,7 @@ static int delete_cmd(UAContext *ua, const char *cmd)
       break;
    }
 
-   bsendmsg(ua, _(
+   ua->warning_msg(_(
 "In general it is not a good idea to delete either a\n"
 "Pool or a Volume since they may contain data.\n\n"));
 
@@ -1256,7 +1263,7 @@ static int delete_cmd(UAContext *ua, const char *cmd)
       delete_job(ua);
       return 1;
    default:
-      bsendmsg(ua, _("Nothing done.\n"));
+      ua->warning_msg(_("Nothing done.\n"));
       break;
    }
    return 1;
@@ -1342,15 +1349,13 @@ static void delete_job_id_range(UAContext *ua, char *tok)
 /*
  * do_job_delete now performs the actual delete operation atomically
  */
-
 static void do_job_delete(UAContext *ua, JobId_t JobId)
 {
-   POOL_MEM query(PM_MESSAGE);
    char ed1[50];
 
-   purge_files_from_job(ua, JobId);
-   purge_job_from_catalog(ua, JobId);
-   bsendmsg(ua, _("Job %s and associated records deleted from the catalog.\n"), edit_int64(JobId, ed1));
+   edit_int64(JobId, ed1);
+   purge_jobs_from_catalog(ua, ed1);
+   ua->send_msg(_("Job %s and associated records deleted from the catalog.\n"), ed1);
 }
 
 /*
@@ -1363,7 +1368,7 @@ static int delete_volume(UAContext *ua)
    if (!select_media_dbr(ua, &mr)) {
       return 1;
    }
-   bsendmsg(ua, _("\nThis command will delete volume %s\n"
+   ua->warning_msg(_("\nThis command will delete volume %s\n"
       "and all Jobs saved on that volume from the Catalog\n"),
       mr.VolumeName);
 
@@ -1397,6 +1402,12 @@ static int delete_pool(UAContext *ua)
    return 1;
 }
 
+int memory_cmd(UAContext *ua, const char *cmd)
+{
+   list_dir_status_header(ua);
+   sm_dump(false, true);
+   return 1;
+}
 
 static void do_mount_cmd(UAContext *ua, const char *command)
 {
@@ -1427,7 +1438,7 @@ static void do_mount_cmd(UAContext *ua, const char *command)
       store.store->media_type, store.store->dev_name(), drive);
 
    if (!connect_to_storage_daemon(jcr, 10, SDConnectTimeout, 1)) {
-      bsendmsg(ua, _("Failed to connect to Storage daemon.\n"));
+      ua->error_msg(_("Failed to connect to Storage daemon.\n"));
       return;
    }
    sd = jcr->store_bsock;
@@ -1439,7 +1450,7 @@ static void do_mount_cmd(UAContext *ua, const char *command)
       bnet_fsend(sd, "%s %s drive=%d", command, dev_name, drive);
    }
    while (bnet_recv(sd) >= 0) {
-      bsendmsg(ua, "%s", sd->msg);
+      ua->send_msg("%s", sd->msg);
    }
    bnet_sig(sd, BNET_TERMINATE);
    bnet_close(sd);
@@ -1494,7 +1505,7 @@ static int use_cmd(UAContext *ua, const char *cmd)
       ua->catalog = catalog;
    }
    if (open_db(ua)) {
-      bsendmsg(ua, _("Using Catalog name=%s DB=%s\n"),
+      ua->send_msg(_("Using Catalog name=%s DB=%s\n"),
          ua->catalog->name(), ua->catalog->db_name);
    }
    return 1;
@@ -1554,7 +1565,7 @@ int wait_cmd(UAContext *ua, const char *cmd)
    uint32_t jobid = 0 ;
 
    if (!open_client_db(ua)) {
-      bsendmsg(ua, _("ERR: Can't open db\n")) ;
+      ua->error_msg(_("ERR: Can't open db\n")) ;
       return 1;
    }
 
@@ -1590,7 +1601,7 @@ int wait_cmd(UAContext *ua, const char *cmd)
    }
 
    if (jobid == 0) {
-      bsendmsg(ua, _("ERR: Job was not found\n"));
+      ua->error_msg(_("ERR: Job was not found\n"));
       return 1 ;
    }
 
@@ -1649,13 +1660,13 @@ int wait_cmd(UAContext *ua, const char *cmd)
       break;
    }
 
-   bsendmsg(ua, "JobId=%i\n", jobid) ;
-   bsendmsg(ua, "JobStatus=%s (%c)\n", 
+   ua->send_msg("JobId=%i\n", jobid) ;
+   ua->send_msg("JobStatus=%s (%c)\n", 
             job_status_to_str(jobstatus), 
             jobstatus) ;
 
-   if (ua->gui) {
-      bsendmsg(ua, "ExitStatus=%i\n", status) ;
+   if (ua->gui || ua->api) {
+      ua->send_msg("ExitStatus=%i\n", status) ;
    }
 
    return 1;
@@ -1666,11 +1677,11 @@ static int help_cmd(UAContext *ua, const char *cmd)
 {
    unsigned int i;
 
-   bsendmsg(ua, _("  Command    Description\n  =======    ===========\n"));
+   ua->send_msg(_("  Command    Description\n  =======    ===========\n"));
    for (i=0; i<comsize; i++) {
-      bsendmsg(ua, _("  %-10s %s\n"), _(commands[i].key), _(commands[i].help));
+      ua->send_msg(_("  %-10s %s\n"), _(commands[i].key), _(commands[i].help));
    }
-   bsendmsg(ua, _("\nWhen at a prompt, entering a period cancels the command.\n\n"));
+   ua->send_msg(_("\nWhen at a prompt, entering a period cancels the command.\n\n"));
    return 1;
 }
 
@@ -1679,16 +1690,37 @@ int qhelp_cmd(UAContext *ua, const char *cmd)
    unsigned int i;
 
    for (i=0; i<comsize; i++) {
-      bsendmsg(ua, "%s %s\n", commands[i].key, _(commands[i].help));
+      ua->send_msg("%s %s\n", commands[i].key, _(commands[i].help));
    }
    return 1;
 }
 
+#if 1 
 static int version_cmd(UAContext *ua, const char *cmd)
 {
-   bsendmsg(ua, _("%s Version: %s (%s)\n"), my_name, VERSION, BDATE);
+   ua->send_msg(_("%s Version: %s (%s) %s %s %s\n"), my_name, VERSION, BDATE,
+            HOST_OS, DISTNAME, DISTVER);
    return 1;
 }
+#else
+/*
+ *  Test code -- turned on only for debug testing 
+ */
+static int version_cmd(UAContext *ua, const char *cmd)
+{
+   dbid_list ids;
+   POOL_MEM query(PM_MESSAGE);
+   open_db(ua);
+   Mmsg(query, "select MediaId from Media,Pool where Pool.PoolId=Media.PoolId and Pool.Name='Full'");
+   db_get_query_dbids(ua->jcr, ua->db, query, ids);
+   ua->send_msg("num_ids=%d max_ids=%d tot_ids=%d\n", ids.num_ids, ids.max_ids, ids.tot_ids);
+   for (int i=0; i < ids.num_ids; i++) {
+      ua->send_msg("id=%d\n", ids.DBId[i]);
+   }
+   close_db(ua);
+   return 1;
+}
+#endif
 
 /* 
  * This call explicitly checks for a catalog=xxx and
@@ -1709,10 +1741,10 @@ bool open_client_db(UAContext *ua)
    i = find_arg_with_value(ua, NT_("catalog"));
    if (i >= 0) {
       if (!acl_access_ok(ua, Catalog_ACL, ua->argv[i])) {
-         bsendmsg(ua, _("No authorization for Catalog \"%s\"\n"), ua->argv[i]);
+         ua->error_msg(_("No authorization for Catalog \"%s\"\n"), ua->argv[i]);
          return false;
       }
-      catalog = (CAT *)GetResWithName(R_CATALOG, ua->argv[i]);
+      catalog = GetCatalogResWithName(ua->argv[i]);
       if (catalog) {
          if (ua->catalog && ua->catalog != catalog) {
             close_db(ua);
@@ -1726,17 +1758,17 @@ bool open_client_db(UAContext *ua)
    i = find_arg_with_value(ua, NT_("client"));
    if (i >= 0) {
       if (!acl_access_ok(ua, Client_ACL, ua->argv[i])) {
-         bsendmsg(ua, _("No authorization for Client \"%s\"\n"), ua->argv[i]);
+         ua->error_msg(_("No authorization for Client \"%s\"\n"), ua->argv[i]);
          return false;
       }
-      client = (CLIENT *)GetResWithName(R_CLIENT, ua->argv[i]);
+      client = GetClientResWithName(ua->argv[i]);
       if (client) {
          catalog = client->catalog;
          if (ua->catalog && ua->catalog != catalog) {
             close_db(ua);
          }
          if (!acl_access_ok(ua, Catalog_ACL, catalog->name())) {
-            bsendmsg(ua, _("No authorization for Catalog \"%s\"\n"), catalog->name());
+            ua->error_msg(_("No authorization for Catalog \"%s\"\n"), catalog->name());
             return false;
          }
          ua->catalog = catalog;
@@ -1748,17 +1780,17 @@ bool open_client_db(UAContext *ua)
    i = find_arg_with_value(ua, NT_("job"));
    if (i >= 0) {
       if (!acl_access_ok(ua, Job_ACL, ua->argv[i])) {
-         bsendmsg(ua, _("No authorization for Job \"%s\"\n"), ua->argv[i]);
+         ua->error_msg(_("No authorization for Job \"%s\"\n"), ua->argv[i]);
          return false;
       }
-      job = (JOB *)GetResWithName(R_JOB, ua->argv[i]);
+      job = GetJobResWithName(ua->argv[i]);
       if (job) {
          catalog = job->client->catalog;
          if (ua->catalog && ua->catalog != catalog) {
             close_db(ua);
          }
          if (!acl_access_ok(ua, Catalog_ACL, catalog->name())) {
-            bsendmsg(ua, _("No authorization for Catalog \"%s\"\n"), catalog->name());
+            ua->error_msg(_("No authorization for Catalog \"%s\"\n"), catalog->name());
             return false;
          }
          ua->catalog = catalog;
@@ -1781,29 +1813,31 @@ bool open_db(UAContext *ua)
    if (!ua->catalog) {
       ua->catalog = get_catalog_resource(ua);
       if (!ua->catalog) {
-         bsendmsg(ua, _("Could not find a Catalog resource\n"));
+         ua->error_msg( _("Could not find a Catalog resource\n"));
          return false;
       }
    }
 
    ua->jcr->catalog = ua->catalog;
 
-   Dmsg0(150, "Open database\n");
+   Dmsg0(100, "UA Open database\n");
    ua->db = db_init_database(ua->jcr, ua->catalog->db_name, ua->catalog->db_user,
                              ua->catalog->db_password, ua->catalog->db_address,
                              ua->catalog->db_port, ua->catalog->db_socket,
                              ua->catalog->mult_db_connections);
    if (!ua->db || !db_open_database(ua->jcr, ua->db)) {
-      bsendmsg(ua, _("Could not open catalog database \"%s\".\n"),
+      ua->error_msg(_("Could not open catalog database \"%s\".\n"),
                  ua->catalog->db_name);
       if (ua->db) {
-         bsendmsg(ua, "%s", db_strerror(ua->db));
+         ua->error_msg("%s", db_strerror(ua->db));
       }
       close_db(ua);
       return false;
    }
    ua->jcr->db = ua->db;
-   bsendmsg(ua, _("Using Catalog \"%s\"\n"), ua->catalog->name()); 
+   if (!ua->api) {
+      ua->send_msg(_("Using Catalog \"%s\"\n"), ua->catalog->name()); 
+   }
    Dmsg1(150, "DB %s opened\n", ua->catalog->db_name);
    return true;
 }