]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/dird/ua_dotcmds.c
ebl Modify disk-changer to check if slot contains something before
[bacula/bacula] / bacula / src / dird / ua_dotcmds.c
index c8479129e4371ee42a618f6c7f9a5681f20a01b3..ced146c49a8a609127fc46f67291c5a477af26a9 100644 (file)
@@ -1,14 +1,14 @@
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2002-2007 Free Software Foundation Europe e.V.
+   Copyright (C) 2002-2008 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.
    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
@@ -98,7 +98,7 @@ static struct cmdstruct commands[] = {
 /*
  * Execute a command from the UA
  */
-int do_a_dot_command(UAContext *ua, const char *cmd)
+bool do_a_dot_command(UAContext *ua) 
 {
    int i;
    int len;
@@ -108,14 +108,14 @@ int do_a_dot_command(UAContext *ua, const char *cmd)
 
    Dmsg1(1400, "Dot command: %s\n", user->msg);
    if (ua->argc == 0) {
-      return 1;
+      return false;
    }
 
    len = strlen(ua->argk[0]);
    if (len == 1) {
       if (ua->api) user->signal(BNET_CMD_BEGIN);
       if (ua->api) user->signal(BNET_CMD_OK);
-      return 1;                       /* no op */
+      return true;                    /* no op */
    }
    for (i=0; i<comsize; i++) {     /* search for command */
       if (strncasecmp(ua->argk[0],  _(commands[i].key), len) == 0) {
@@ -125,9 +125,10 @@ int do_a_dot_command(UAContext *ua, const char *cmd)
              !acl_access_ok(ua, Command_ACL, ua->argk[0], len)) {
             break;
          }
+         Dmsg1(100, "Cmd: %s\n", ua->cmd);
          ua->gui = true;
          if (ua->api) user->signal(BNET_CMD_BEGIN);
-         ok = (*commands[i].func)(ua, cmd);   /* go execute command */
+         ok = (*commands[i].func)(ua, ua->cmd);   /* go execute command */
          ua->gui = gui;
          found = true;
          break;
@@ -135,11 +136,11 @@ int do_a_dot_command(UAContext *ua, const char *cmd)
    }
    if (!found) {
       pm_strcat(user->msg, _(": is an invalid command.\n"));
-      user->msglen = strlen(user->msg);
-      user->send();
+      ua->error_msg("%s", user->msg);
+      ok = false;
    }
    if (ua->api) user->signal(ok?BNET_CMD_OK:BNET_CMD_FAILED);
-   return 1;
+   return ok;
 }
 
 static bool dot_quit_cmd(UAContext *ua, const char *cmd)
@@ -162,20 +163,162 @@ static bool getmsgscmd(UAContext *ua, const char *cmd)
    return 1;
 }
 
+#ifdef DEVELOPER
+static void do_storage_die(UAContext *ua, STORE *store)
+{
+   BSOCK *sd;
+   JCR *jcr = ua->jcr;
+   USTORE lstore;
+   
+   lstore.store = store;
+   pm_strcpy(lstore.store_source, _("unknown source"));
+   set_wstorage(jcr, &lstore);
+   /* Try connecting for up to 15 seconds */
+   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)) {
+      ua->error_msg(_("Failed to connect to Storage daemon.\n"));
+      return;
+   }
+   Dmsg0(120, _("Connected to storage daemon\n"));
+   sd = jcr->store_bsock;
+   sd->fsend(".die");
+   if (sd->recv() >= 0) {
+      ua->send_msg("%s", sd->msg);
+   }
+   sd->signal(BNET_TERMINATE);
+   sd->close();
+   jcr->store_bsock = NULL;
+   return;
+}
+
+static void do_client_die(UAContext *ua, CLIENT *client)
+{
+   BSOCK *fd;
+
+   /* Connect to File daemon */
+
+   ua->jcr->client = client;
+   /* Try to connect for 15 seconds */
+   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)) {
+      ua->error_msg(_("Failed to connect to Client.\n"));
+      return;
+   }
+   Dmsg0(120, "Connected to file daemon\n");
+   fd = ua->jcr->file_bsock;
+   fd->fsend(".die");
+   if (fd->recv() >= 0) {
+      ua->send_msg("%s", fd->msg);
+   }
+   fd->signal(BNET_TERMINATE);
+   fd->close();
+   ua->jcr->file_bsock = NULL;
+   return;
+}
+
 /*
  * Create segmentation fault
  */
 static bool diecmd(UAContext *ua, const char *cmd)
 {
+   STORE *store;
+   CLIENT *client;
+   int i;
    JCR *jcr = NULL;
    int a;
 
-   ua->send_msg(_("The Director will segment fault.\n"));
-   a = jcr->JobId; /* ref NULL pointer */
-   jcr->JobId = 1000; /* another ref NULL pointer */
+   Dmsg1(120, "diecmd:%s:\n", cmd);
+
+   /* General debug? */
+   for (i=1; i<ua->argc; i++) {
+      if (strcasecmp(ua->argk[i], "dir") == 0 ||
+          strcasecmp(ua->argk[i], "director") == 0) {
+         ua->send_msg(_("The Director will segment fault.\n"));
+         a = jcr->JobId; /* ref NULL pointer */
+         jcr->JobId = 1000; /* another ref NULL pointer */
+         return 1;
+      }
+      if (strcasecmp(ua->argk[i], "client") == 0 ||
+          strcasecmp(ua->argk[i], "fd") == 0) {
+         client = NULL;
+         if (ua->argv[i]) {
+            client = (CLIENT *)GetResWithName(R_CLIENT, ua->argv[i]);
+            if (client) {
+               do_client_die(ua, client);
+               return 1;
+            }
+         }
+         client = select_client_resource(ua);
+         if (client) {
+            do_client_die(ua, client);
+            return 1;
+         }
+      }
+
+      if (strcasecmp(ua->argk[i], NT_("store")) == 0 ||
+          strcasecmp(ua->argk[i], NT_("storage")) == 0 ||
+          strcasecmp(ua->argk[i], NT_("sd")) == 0) {
+         store = NULL;
+         if (ua->argv[i]) {
+            store = (STORE *)GetResWithName(R_STORAGE, ua->argv[i]);
+            if (store) {
+               do_storage_die(ua, store);
+               return 1;
+            }
+         }
+         store = get_storage_resource(ua, false/*no default*/);
+         if (store) {
+            do_storage_die(ua, store);
+            return 1;
+         }
+      }
+   }
+   /*
+    * We didn't find an appropriate keyword above, so
+    * prompt the user.
+    */
+   start_prompt(ua, _("Available daemons are: \n"));
+   add_prompt(ua, _("Director"));
+   add_prompt(ua, _("Storage"));
+   add_prompt(ua, _("Client"));
+   switch(do_prompt(ua, "", _("Select daemon type to make die"), NULL, 0)) {
+   case 0:                         /* Director */
+      ua->send_msg(_("The Director will segment fault.\n"));
+      a = jcr->JobId; /* ref NULL pointer */
+      jcr->JobId = 1000; /* another ref NULL pointer */
+      break;
+   case 1:
+      store = get_storage_resource(ua, false/*no default*/);
+      if (store) {
+         do_storage_die(ua, store);
+      }
+      break;
+   case 2:
+      client = select_client_resource(ua);
+      if (client) {
+         do_client_die(ua, client);
+      }
+      break;
+   default:
+      break;
+   }
    return true;
 }
 
+#else
+
+/*
+ * Dummy routine for non-development version
+ */
+static bool diecmd(UAContext *ua, const char *cmd)
+{
+   return true;
+}
+
+#endif
+
 static bool jobscmd(UAContext *ua, const char *cmd)
 {
    JOB *job;
@@ -325,13 +468,17 @@ static int sql_handler(void *ctx, int num_field, char **row)
 
    for (int i=0; num_field--; i++) {
       if (i == 0) {
-         pm_strcpy(rows, row[0]);
+         pm_strcpy(rows, NPRT(row[0]));
       } else {
-         pm_strcat(rows, row[i]);
+         pm_strcat(rows, NPRT(row[i]));
       }
       pm_strcat(rows, "\t");
    }
-   ua->send_msg(rows.c_str());
+   if (!rows.c_str() || !*rows.c_str()) {
+      ua->send_msg("\t");
+   } else {
+      ua->send_msg("%s", rows.c_str());
+   }
    return 0;
 }