* Version $Id$
*/
/*
- Copyright (C) 2002-2005 Kern Sibbald
+ Bacula® - The Network Backup Solution
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- version 2 as amended with additional clauses defined in the
- file LICENSE in the main source directory.
+ Copyright (C) 2002-2006 Free Software Foundation Europe e.V.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- the file LICENSE for additional details.
+ 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.
- */
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+
+ Bacula® is a registered trademark of John Walker.
+ The licensor of Bacula is the Free Software Foundation Europe
+ (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
+ Switzerland, email:ftf@fsfeurope.org.
+*/
#include "bacula.h"
#include "dird.h"
static int lscmd(UAContext *ua, TREE_CTX *tree);
static int lsmarkcmd(UAContext *ua, TREE_CTX *tree);
static int dircmd(UAContext *ua, TREE_CTX *tree);
+static int dot_dircmd(UAContext *ua, TREE_CTX *tree);
static int estimatecmd(UAContext *ua, TREE_CTX *tree);
static int helpcmd(UAContext *ua, TREE_CTX *tree);
static int cdcmd(UAContext *ua, TREE_CTX *tree);
struct cmdstruct { const char *key; int (*func)(UAContext *ua, TREE_CTX *tree); const char *help; };
static struct cmdstruct commands[] = {
- { N_("cd"), cdcmd, _("change current directory")},
- { N_("count"), countcmd, _("count marked files in and below the cd")},
- { N_("dir"), dircmd, _("long list current directory, wildcards allowed")},
- { N_("done"), donecmd, _("leave file selection mode")},
- { N_("estimate"), estimatecmd, _("estimate restore size")},
- { N_("exit"), donecmd, _("same as done command")},
- { N_("find"), findcmd, _("find files, wildcards allowed")},
- { N_("help"), helpcmd, _("print help")},
- { N_("ls"), lscmd, _("list current directory, wildcards allowed")},
- { N_("lsmark"), lsmarkcmd, _("list the marked files in and below the cd")},
- { N_("mark"), markcmd, _("mark dir/file to be restored recursively in dirs")},
- { N_("markdir"), markdircmd, _("mark directory name to be restored (no files)")},
- { N_("pwd"), pwdcmd, _("print current working directory")},
- { N_("unmark"), unmarkcmd, _("unmark dir/file to be restored recursively in dir")},
- { N_("unmarkdir"), unmarkdircmd, _("unmark directory name only no recursion")},
- { N_("quit"), quitcmd, _("quit and do not do restore")},
- { N_("?"), helpcmd, _("print help")},
+ { NT_("cd"), cdcmd, _("change current directory")},
+ { NT_("count"), countcmd, _("count marked files in and below the cd")},
+ { NT_("dir"), dircmd, _("long list current directory, wildcards allowed")},
+ { NT_(".dir"), dot_dircmd, _("long list current directory, wildcards allowed")},
+ { NT_("done"), donecmd, _("leave file selection mode")},
+ { NT_("estimate"), estimatecmd, _("estimate restore size")},
+ { NT_("exit"), donecmd, _("same as done command")},
+ { NT_("find"), findcmd, _("find files, wildcards allowed")},
+ { NT_("help"), helpcmd, _("print help")},
+ { NT_("ls"), lscmd, _("list current directory, wildcards allowed")},
+ { NT_("lsmark"), lsmarkcmd, _("list the marked files in and below the cd")},
+ { 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_("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))
if (!get_cmd(ua, "$ ")) {
break;
}
- parse_ua_args(ua);
+ parse_args_only(ua->cmd, &ua->args, &ua->argc, ua->argk, ua->argv, MAX_CMD_ARGS);
if (ua->argc == 0) {
- break;
+ bsendmsg(tree->ua, _("Illegal command. Enter \"done\" to exit.\n"));
+ continue;
}
len = strlen(ua->argk[0]);
// Dmsg4(000, "Path=%s%s FI=%s JobId=%s\n", row[0], row[1],
// row[2], row[3]);
- if (*row[1] == 0) { /* no filename => directory */
- if (*row[0] != '/') { /* Must be Win32 directory */
+ if (*row[1] == 0) { /* no filename => directory */
+ if (!IsPathSeparator(*row[0])) { /* Must be Win32 directory */
type = TN_DIR_NLS;
} else {
type = TN_DIR;
if (ua->argc == 1) {
bsendmsg(ua, _("No file specification given.\n"));
- return 0;
+ return 1; /* make it non-fatal */
}
for (int i=1; i < ua->argc; i++) {
/*
* This is actually the long form used for "dir"
*/
-static void ls_output(char *buf, const char *fname, const char *tag, struct stat *statp)
+static void ls_output(char *buf, const char *fname, const char *tag,
+ struct stat *statp, bool dot_cmd)
+
{
char *p;
const char *f;
char ec1[30];
char en1[30], en2[30];
int n;
+ time_t time;
p = encode_mode(statp->st_mode, buf);
- n = sprintf(p, " %2d ", (uint32_t)statp->st_nlink);
- p += n;
- n = sprintf(p, "%-8.8s %-8.8s", getuser(statp->st_uid, en1, sizeof(en1)),
- getgroup(statp->st_gid, en2, sizeof(en2)));
- p += n;
- n = sprintf(p, "%10.10s ", edit_uint64(statp->st_size, ec1));
- p += n;
- p = encode_time(statp->st_ctime, p);
- *p++ = ' ';
- *p++ = *tag;
+ if (dot_cmd) {
+ *p++ = ',';
+ n = sprintf(p, "%d,", (uint32_t)statp->st_nlink);
+ p += n;
+ n = sprintf(p, "%s,%s,", getuser(statp->st_uid, en1, sizeof(en1)),
+ getgroup(statp->st_gid, en2, sizeof(en2)));
+ p += n;
+ n = sprintf(p, "%s,", edit_uint64(statp->st_size, ec1));
+ p += n;
+ p = encode_time(statp->st_mtime, p);
+ *p++ = ',';
+ *p++ = *tag;
+ *p++ = ',';
+ } else {
+ n = sprintf(p, " %2d ", (uint32_t)statp->st_nlink);
+ p += n;
+ n = sprintf(p, "%-8.8s %-8.8s", getuser(statp->st_uid, en1, sizeof(en1)),
+ getgroup(statp->st_gid, en2, sizeof(en2)));
+ p += n;
+ n = sprintf(p, "%10.10s ", edit_uint64(statp->st_size, ec1));
+ p += n;
+ if (statp->st_ctime > statp->st_mtime) {
+ time = statp->st_ctime;
+ } else {
+ time = statp->st_mtime;
+ }
+ /* Display most recent time */
+ p = encode_time(time, p);
+ *p++ = ' ';
+ *p++ = *tag;
+ }
for (f=fname; *f; ) {
*p++ = *f++;
}
*p = 0;
}
-
/*
* Like ls command, but give more detail on each file
*/
-static int dircmd(UAContext *ua, TREE_CTX *tree)
+static int do_dircmd(UAContext *ua, TREE_CTX *tree, bool dot_cmd)
{
TREE_NODE *node;
FILE_DBR fdbr;
/* Something went wrong getting attributes -- print name */
memset(&statp, 0, sizeof(statp));
}
- ls_output(buf, cwd, tag, &statp);
+ ls_output(buf, cwd, tag, &statp, dot_cmd);
bsendmsg(ua, "%s\n", buf);
}
}
return 1;
}
+int dot_dircmd(UAContext *ua, TREE_CTX *tree)
+{
+ return do_dircmd(ua, tree, true/*dot command*/);
+}
+
+static int dircmd(UAContext *ua, TREE_CTX *tree)
+{
+ return do_dircmd(ua, tree, false/*not dot command*/);
+}
+
static int estimatecmd(UAContext *ua, TREE_CTX *tree)
{
bsendmsg(ua, _(" Command Description\n ======= ===========\n"));
for (i=0; i<comsize; i++) {
- bsendmsg(ua, " %-10s %s\n", _(commands[i].key), _(commands[i].help));
+ /* List only non-dot commands */
+ if (commands[i].key[0] != '.') {
+ bsendmsg(ua, " %-10s %s\n", _(commands[i].key), _(commands[i].help));
+ }
}
bsendmsg(ua, "\n");
return 1;
TREE_NODE *node;
char cwd[2000];
+
if (ua->argc != 2) {
+ bsendmsg(ua, _("Too many arguments. Try using double quotes.\n"));
return 1;
}
- strip_leading_space(ua->argk[1]);
node = tree_cwd(ua->argk[1], tree->root, tree->node);
if (!node) {
/* Try once more if Win32 drive -- make absolute */
} else if (count == 1) {
bsendmsg(ua, _("1 file unmarked.\n"));
} else {
- bsendmsg(ua, _("%d files unmarked.\n"), count);
+ char ed1[50];
+ bsendmsg(ua, _("%s files unmarked.\n"), edit_uint64_with_commas(count, ed1));
}
return 1;
}