]> git.sur5r.net Git - bacula/bacula/commitdiff
kes Extend new GUI api code to tree commands.
authorKern Sibbald <kern@sibbald.com>
Mon, 5 Mar 2007 09:50:15 +0000 (09:50 +0000)
committerKern Sibbald <kern@sibbald.com>
Mon, 5 Mar 2007 09:50:15 +0000 (09:50 +0000)
kes  Ensure that tree and dot commands check console ACLs.
kes  Permit marking directory with trailing slash.
kes  Allow 20 console connections (instead of only 10).

git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@4311 91ce42f0-d328-0410-95d8-f526ca767f89

bacula/projects
bacula/src/dird/ua_cmds.c
bacula/src/dird/ua_dotcmds.c
bacula/src/dird/ua_input.c
bacula/src/dird/ua_server.c
bacula/src/dird/ua_tree.c
bacula/src/version.h
bacula/technotes-2.1

index 24c6573c0854110c3fb3830a880102dcb32f374c..bae68a506b5b444fdd78007ea0a2fe3bbfd0ca6b 100644 (file)
@@ -1129,6 +1129,57 @@ Item 40:  Include JobID in spool file name ****DONE****
           spoolfile name doesn't include that information. The date/time
           stamp is useful (and should be retained).
 
+============= New Freature Requests after vote of 26 Jan 2007 ========
+Item  n:  Enable to relocate files and directories when restoring
+  Date:   2007-03-01
+  Origin: Eric Bollengier <eric@eb.homelinux.org>
+  Status:
+
+  What:   The where= option is not powerful enough. It will be
+          a great feature if bacula can restore a file in the
+          same directory, but with a different name, or in 
+          an other directory without recreating the full path.
+
+  Why:    When i want to restore a production environment to a
+          development environment, i just want change the first
+          directory. ie restore /prod/data/file.dat to /rect/data/file.dat.
+          At this time, i have to move by hand files. You must have a big
+          dump space to restore and move data after.
+
+          When i use Linux or SAN snapshot, i mount them to /mnt/snap_xxx
+          so, when a restore a file, i have to move by hand
+          from /mnt/snap_xxx/file to /xxx/file. I can't replace a file
+          easily.
+
+          When a user ask me to restore a file in its personal folder,
+          (without replace the existing one), i can't restore from
+          my_file.txt to my_file.txt.old witch is very practical.
+
+          
+  Notes:  I think we can enhance the where= option very easily by
+          allowing regexp expression. (by replacing bregex by libpcre 
+          see http://en.wikipedia.org/wiki/PCRE and http://www.pcre.org/)
+
+          Since, many users think that regexp are not user friendly, i think
+          that bat, bconsole or brestore must provide a simple way to
+          configure where= option (i think to something like in
+          openoffice "search and replace").
+
+          Ie, if user uses where=/tmp/bacula-restore, we keep the old
+          fashion.
+
+          If user uses something like where=s!/prod!/test!, files will
+          be restored from /prod/xxx to /test/xxx.
+
+          If user uses something like where=s/$/.old/, files will
+          be restored from /prod/xxx.txt to /prod/xxx.txt.old.
+
+          If user uses something like where=s/txt$/old.txt/, files will
+          be restored from /prod/xxx.txt to /prod/xxx.old.txt
+
+          if user uses something like where=s/([a-z]+)$/old.$1/, files will
+          be restored from /prod/xxx.ext to /prod/xxx.old.ext
+
 ============= Empty Feature Request form ===========
 Item  n:  One line summary ...
   Date:   Date submitted 
index 917cf28a51360ccd1691996a93d99f4589e6bb2e..b09f3f7edd05787eed54946a9b8e5aa6e5cb693f 100644 (file)
@@ -150,7 +150,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 +173,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;
 }
 
 /*
index a236ff3c2e17253b36468a333df4590b428472e5..a53f609d1ba352752be1d8906a00eaed673aa096 100644 (file)
@@ -102,22 +102,29 @@ int do_a_dot_command(UAContext *ua, const char *cmd)
    int len;
    bool ok = false;
    bool found = false;
-   BSOCK *sock = ua->UA_sock;
+   BSOCK *user = ua->UA_sock;
 
-   Dmsg1(1400, "Dot command: %s\n", ua->UA_sock->msg);
+   Dmsg1(1400, "Dot command: %s\n", user->msg);
    if (ua->argc == 0) {
       return 1;
    }
 
    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 */
    }
    for (i=0; i<comsize; i++) {     /* search for command */
       if (strncasecmp(ua->argk[0],  _(commands[i].key), len) == 0) {
          bool gui = ua->gui;
+         /* Check if command permitted, but "quit" is always OK */
+         if (strcmp(ua->argk[0], NT_(".quit")) != 0 &&
+             !acl_access_ok(ua, Command_ACL, ua->argk[0], len)) {
+            break;
+         }
          ua->gui = true;
-         if (ua->api) sock->signal(BNET_CMD_BEGIN);
+         if (ua->api) user->signal(BNET_CMD_BEGIN);
          ok = (*commands[i].func)(ua, cmd);   /* go execute command */
          ua->gui = gui;
          found = true;
@@ -125,12 +132,11 @@ int do_a_dot_command(UAContext *ua, const char *cmd)
       }
    }
    if (!found) {
-      pm_strcat(sock->msg, _(": is an invalid command\n"));
-      sock->msglen = strlen(sock->msg);
-      sock->send();
-      if (ua->api) sock->signal(BNET_INVALID_CMD);
+      pm_strcat(user->msg, _(": is an invalid command.\n"));
+      user->msglen = strlen(user->msg);
+      user->send();
    }
-   if (ua->api) sock->signal(ok?BNET_CMD_OK:BNET_CMD_FAILED);
+   if (ua->api) user->signal(ok?BNET_CMD_OK:BNET_CMD_FAILED);
    return 1;
 }
 
index a51dbce63603aaaa2e72d829480ae65b96948c46..71ead60233648b3976770794165ce4dd395c67c2 100644 (file)
@@ -1,15 +1,7 @@
-/*
- *
- *   Bacula Director -- User Agent Input and scanning code
- *
- *     Kern Sibbald, October MMI
- *
- *   Version $Id$
- */
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2001-2006 Free Software Foundation Europe e.V.
+   Copyright (C) 2001-2007 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.
    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
    Switzerland, email:ftf@fsfeurope.org.
 */
+/*
+ *
+ *   Bacula Director -- User Agent Input and scanning code
+ *
+ *     Kern Sibbald, October MMI
+ *
+ *   Version $Id$
+ */
 
 #include "bacula.h"
 #include "dird.h"
@@ -52,10 +52,10 @@ int get_cmd(UAContext *ua, const char *prompt)
    if (!sock) {                       /* No UA */
       return 0;
    }
-   bnet_fsend(sock, "%s", prompt);
-   bnet_sig(sock, BNET_PROMPT);       /* request more input */
+   sock->fsend("%s", prompt);
+   sock->signal(BNET_PROMPT);       /* request more input */
    for ( ;; ) {
-      stat = bnet_recv(sock);
+      stat = sock->recv();
       if (stat == BNET_SIGNAL) {
          continue;                    /* ignore signals */
       }
index d64b93635dcaa107ad10f72a2776036eab5c48d1..14ff46d9e88338c6de42354280fcd1affeb96593 100644 (file)
@@ -1,15 +1,7 @@
-/*
- *
- *   Bacula Director -- User Agent Server
- *
- *     Kern Sibbald, September MM
- *
- *    Version $Id$
- */
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2000-2006 Free Software Foundation Europe e.V.
+   Copyright (C) 2000-2007 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.
    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
    Switzerland, email:ftf@fsfeurope.org.
 */
+/*
+ *
+ *   Bacula Director -- User Agent Server
+ *
+ *     Kern Sibbald, September MM
+ *
+ *    Version $Id$
+ */
 
 #include "bacula.h"
 #include "dird.h"
@@ -80,8 +80,8 @@ void *connect_thread(void *arg)
 {
    pthread_detach(pthread_self());
 
-   /* Permit 10 console connections */
-   bnet_thread_server((dlist*)arg, 10, &ua_workq, handle_UA_client_request);
+   /* Permit 20 console connections */
+   bnet_thread_server((dlist*)arg, 20, &ua_workq, handle_UA_client_request);
    return NULL;
 }
 
@@ -121,21 +121,22 @@ static void *handle_UA_client_request(void *arg)
    int stat;
    UAContext *ua;
    JCR *jcr;
+   BSOCK *user = (BSOCK *)arg;
 
    pthread_detach(pthread_self());
 
    jcr = new_control_jcr("*Console*", JT_CONSOLE);
 
    ua = new_ua_context(jcr);
-   ua->UA_sock = (BSOCK *)arg;
+   ua->UA_sock = user;
 
-   bnet_recv(ua->UA_sock);          /* Get first message */
+   user->recv();             /* Get first message */
    if (!authenticate_user_agent(ua)) {
       goto getout;
    }
 
    while (!ua->quit) {
-      stat = bnet_recv(ua->UA_sock);
+      stat = user->recv();
       if (stat >= 0) {
          pm_strcpy(ua->cmd, ua->UA_sock->msg);
          parse_ua_args(ua);
@@ -149,18 +150,18 @@ static void *handle_UA_client_request(void *arg)
                if (ua->auto_display_messages) {
                   pm_strcpy(ua->cmd, "messages");
                   qmessagescmd(ua, ua->cmd);
-                  ua->user_notified_msg_pending = FALSE;
+                  ua->user_notified_msg_pending = false;
                } else if (!ua->gui && !ua->user_notified_msg_pending && console_msg_pending) {
                   bsendmsg(ua, _("You have messages.\n"));
-                  ua->user_notified_msg_pending = TRUE;
+                  ua->user_notified_msg_pending = true;
                }
             }
-            bnet_sig(ua->UA_sock, BNET_EOD); /* send end of command */
+            if (!ua->api) user->signal(BNET_EOD);     /* send end of command */
          }
-      } else if (is_bnet_stop(ua->UA_sock)) {
+      } else if (is_bnet_stop(user)) {
          ua->quit = true;
       } else { /* signal */
-         bnet_sig(ua->UA_sock, BNET_POLL);
+         user->signal(BNET_POLL);
       }
    }
 
index 8741537643da6529018655ad78fbc58f4590ffb8..e9706c6e0f0408d68affa0c6fe84ecbf28ec2bc9 100644 (file)
@@ -1,17 +1,7 @@
-/*
- *
- *   Bacula Director -- User Agent Database File tree for Restore
- *      command. This file interacts with the user implementing the
- *      UA tree commands.
- *
- *     Kern Sibbald, July MMII
- *
- *   Version $Id$
- */
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2002-2006 Free Software Foundation Europe e.V.
+   Copyright (C) 2002-2007 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.
    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
    Switzerland, email:ftf@fsfeurope.org.
 */
+/*
+ *
+ *   Bacula Director -- User Agent Database File tree for Restore
+ *      command. This file interacts with the user implementing the
+ *      UA tree commands.
+ *
+ *     Kern Sibbald, July MMII
+ *
+ *   Version $Id$
+ */
 
 #include "bacula.h"
 #include "dird.h"
@@ -60,6 +60,7 @@ static int estimatecmd(UAContext *ua, TREE_CTX *tree);
 static int helpcmd(UAContext *ua, TREE_CTX *tree);
 static int cdcmd(UAContext *ua, TREE_CTX *tree);
 static int pwdcmd(UAContext *ua, TREE_CTX *tree);
+static int dot_pwdcmd(UAContext *ua, TREE_CTX *tree);
 static int unmarkcmd(UAContext *ua, TREE_CTX *tree);
 static int unmarkdircmd(UAContext *ua, TREE_CTX *tree);
 static int quitcmd(UAContext *ua, TREE_CTX *tree);
@@ -82,13 +83,13 @@ static struct cmdstruct commands[] = {
  { NT_("mark"),       markcmd,      _("mark dir/file to be restored recursively, wildcards allowed")},
  { NT_("markdir"),    markdircmd,   _("mark directory name to be restored (no files)")},
  { NT_("pwd"),        pwdcmd,       _("print current working directory")},
+ { NT_(".pwd"),       dot_pwdcmd,   _("print current working directory")},
  { NT_("unmark"),     unmarkcmd,    _("unmark dir/file to be restored recursively in dir")},
  { NT_("unmarkdir"),  unmarkdircmd, _("unmark directory name only no recursion")},
  { NT_("quit"),       quitcmd,      _("quit and do not do restore")},
  { NT_("?"),          helpcmd,      _("print help")},
              };
-#define comsize (sizeof(commands)/sizeof(struct cmdstruct))
-
+#define comsize ((int)(sizeof(commands)/sizeof(struct cmdstruct)))
 
 /*
  * Enter a prompt mode where the user can select/deselect
@@ -129,7 +130,7 @@ bool user_select_files_from_tree(TREE_CTX *tree)
       len = strlen(ua->argk[0]);
       found = 0;
       stat = false;
-      for (i=0; i<(int)comsize; i++)       /* search for command */
+      for (i=0; i<comsize; i++)       /* search for command */
          if (strncasecmp(ua->argk[0],  _(commands[i].key), len) == 0) {
             stat = (*commands[i].func)(ua, tree);   /* go execute command */
             found = 1;
@@ -298,6 +299,18 @@ static int set_extract(UAContext *ua, TREE_NODE *node, TREE_CTX *tree, bool extr
    return count;
 }
 
+static void strip_trailing_slash(char *arg)
+{
+   int len = strlen(arg);
+   if (len == 0) {
+      return;
+   }
+   len--;
+   if (arg[len] == '/') {       /* strip any trailing slash */
+      arg[len] = 0;
+   }
+}
+
 /*
  * Recursively mark the current directory to be restored as
  *  well as all directories and files below it.
@@ -313,6 +326,7 @@ static int markcmd(UAContext *ua, TREE_CTX *tree)
       return 1;
    }
    for (int i=1; i < ua->argc; i++) {
+      strip_trailing_slash(ua->argk[i]);
       foreach_child(node, tree->node) {
          if (fnmatch(ua->argk[i], node->fname, 0) == 0) {
             count += set_extract(ua, node, tree, true);
@@ -341,6 +355,7 @@ static int markdircmd(UAContext *ua, TREE_CTX *tree)
       return 1;
    }
    for (int i=1; i < ua->argc; i++) {
+      strip_trailing_slash(ua->argk[i]);
       foreach_child(node, tree->node) {
          if (fnmatch(ua->argk[i], node->fname, 0) == 0) {
             if (node->type == TN_DIR || node->type == TN_DIR_NLS) {
@@ -695,6 +710,13 @@ static int pwdcmd(UAContext *ua, TREE_CTX *tree)
    return 1;
 }
 
+static int dot_pwdcmd(UAContext *ua, TREE_CTX *tree)
+{
+   char cwd[2000];
+   tree_getpath(tree->node, cwd, sizeof(cwd));
+   bsendmsg(ua, _("%s"), cwd);
+   return 1;
+}
 
 static int unmarkcmd(UAContext *ua, TREE_CTX *tree)
 {
@@ -706,6 +728,7 @@ static int unmarkcmd(UAContext *ua, TREE_CTX *tree)
       return 1;
    }
    for (int i=1; i < ua->argc; i++) {
+      strip_trailing_slash(ua->argk[i]);
       foreach_child(node, tree->node) {
          if (fnmatch(ua->argk[i], node->fname, 0) == 0) {
             count += set_extract(ua, node, tree, false);
@@ -734,6 +757,7 @@ static int unmarkdircmd(UAContext *ua, TREE_CTX *tree)
    }
 
    for (int i=1; i < ua->argc; i++) {
+      strip_trailing_slash(ua->argk[i]);
       foreach_child(node, tree->node) {
          if (fnmatch(ua->argk[i], node->fname, 0) == 0) {
             if (node->type == TN_DIR || node->type == TN_DIR_NLS) {
index 746cab77e5cbb3b2ec4a3b33e6385f3e816f0bb8..4e70ba2d6557a8a5657e086bbcdd7de7afeb3883 100644 (file)
@@ -4,8 +4,8 @@
 
 #undef  VERSION
 #define VERSION "2.1.4"
-#define BDATE   "02 March 2007"
-#define LSMDATE "02Mar07"
+#define BDATE   "05 March 2007"
+#define LSMDATE "05Mar07"
 
 #define PROG_COPYRIGHT "Copyright (C) %d-2007 Free Software Foundation Europe e.V.\n"
 #define BYEAR "2007"       /* year for copyright messages in progs */
index 87a250d9e23b7daffdb4b6b965dd90164956a942..d3c23ebe18129edae2af2bbc82c74125208b0017 100644 (file)
@@ -1,6 +1,11 @@
               Technical notes on version 2.1
 
 General:
+05Mar07
+kes  Extend new GUI api code to tree commands.
+kes  Ensure that tree and dot commands check console ACLs.
+kes  Permit marking directory with trailing slash.
+kes  Allow 20 console connections (instead of only 10).
 04Mar07
 kes  Add smartctl call to bacula-sd.conf as an example of getting
      tape alert info.