From 5d35464c3acf3473bdfc2b75a20ba6d1c2f05be3 Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Mon, 5 Mar 2007 09:50:15 +0000 Subject: [PATCH] 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). git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@4311 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/projects | 51 +++++++++++++++++++++++++++++++++++ bacula/src/dird/ua_cmds.c | 10 ++++--- bacula/src/dird/ua_dotcmds.c | 22 +++++++++------ bacula/src/dird/ua_input.c | 24 ++++++++--------- bacula/src/dird/ua_server.c | 39 ++++++++++++++------------- bacula/src/dird/ua_tree.c | 52 ++++++++++++++++++++++++++---------- bacula/src/version.h | 4 +-- bacula/technotes-2.1 | 5 ++++ 8 files changed, 149 insertions(+), 58 deletions(-) diff --git a/bacula/projects b/bacula/projects index 24c6573c08..bae68a506b 100644 --- a/bacula/projects +++ b/bacula/projects @@ -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 + 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 diff --git a/bacula/src/dird/ua_cmds.c b/bacula/src/dird/ua_cmds.c index 917cf28a51..b09f3f7edd 100644 --- a/bacula/src/dird/ua_cmds.c +++ b/bacula/src/dird/ua_cmds.c @@ -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; } /* diff --git a/bacula/src/dird/ua_dotcmds.c b/bacula/src/dird/ua_dotcmds.c index a236ff3c2e..a53f609d1b 100644 --- a/bacula/src/dird/ua_dotcmds.c +++ b/bacula/src/dird/ua_dotcmds.c @@ -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; iargk[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; } diff --git a/bacula/src/dird/ua_input.c b/bacula/src/dird/ua_input.c index a51dbce636..71ead60233 100644 --- a/bacula/src/dird/ua_input.c +++ b/bacula/src/dird/ua_input.c @@ -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. @@ -33,6 +25,14 @@ (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 */ } diff --git a/bacula/src/dird/ua_server.c b/bacula/src/dird/ua_server.c index d64b93635d..14ff46d9e8 100644 --- a/bacula/src/dird/ua_server.c +++ b/bacula/src/dird/ua_server.c @@ -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. @@ -33,6 +25,14 @@ (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); } } diff --git a/bacula/src/dird/ua_tree.c b/bacula/src/dird/ua_tree.c index 8741537643..e9706c6e0f 100644 --- a/bacula/src/dird/ua_tree.c +++ b/bacula/src/dird/ua_tree.c @@ -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. @@ -35,6 +25,16 @@ (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; iargk[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) { diff --git a/bacula/src/version.h b/bacula/src/version.h index 746cab77e5..4e70ba2d65 100644 --- a/bacula/src/version.h +++ b/bacula/src/version.h @@ -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 */ diff --git a/bacula/technotes-2.1 b/bacula/technotes-2.1 index 87a250d9e2..d3c23ebe18 100644 --- a/bacula/technotes-2.1 +++ b/bacula/technotes-2.1 @@ -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. -- 2.39.5