* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: set_commands.c,v 1.26.2.1 2006/12/22 15:10:27 martinea Exp $
+ * $Id: set_commands.c,v 1.26 2006/07/05 13:14:58 martinea Exp $
*
* implements the "set" commands in amrecover
*/
#include "amanda.h"
+#include "match.h"
#include "util.h"
#include "amrecover.h"
+#include "amxml.h"
-#ifdef SAMBA_CLIENT
extern unsigned short samba_extract_method;
-#endif /* SAMBA_CLIENT */
/* sets a date, mapping given date into standard form if needed */
int
}
else
{
- printf("No index records for cwd on new date\n");
- printf("Setting cwd to mount point\n");
+ g_printf(_("No index records for cwd on new date\n"));
+ g_printf(_("Setting cwd to mount point\n"));
disk_path = newstralloc(disk_path, "/"); /* fake it */
clear_dir_list();
}
const char *host)
{
char *cmd = NULL;
- struct hostent *hp;
+ struct hostent *hp = NULL;
char **hostp;
int found_host = 0;
+ char *uqhost = unquote_string(host);
if (is_extract_list_nonempty())
{
- printf("Must clear extract list before changing host\n");
+ g_printf(_("Must clear extract list before changing host\n"));
+ amfree(uqhost);
return;
}
- cmd = stralloc2("HOST ", host);
+ /*
+ * The idea here is to try as many permutations of the hostname
+ * as we can imagine. The server will reject anything it doesn't
+ * recognize.
+ */
+
+ cmd = stralloc2("HOST ", uqhost);
if (converse(cmd) == -1)
exit(1);
if (server_happy())
- {
found_host = 1;
- }
- else
- {
- /*
- * Try converting the given host to a fully qualified name
- * and then try each of the aliases.
- */
- if ((hp = gethostbyname(host)) != NULL) {
+
+ /*
+ * Try converting the given host to a fully qualified, canonical
+ * name.
+ */
+ if (!found_host) {
+ if ((hp = gethostbyname(uqhost)) != NULL) {
host = hp->h_name;
- printf("Trying host %s ...\n", host);
+ g_printf(_("Trying host %s ...\n"), host);
cmd = newstralloc2(cmd, "HOST ", host);
if (converse(cmd) == -1)
exit(1);
if(server_happy())
- {
found_host = 1;
- }
- else
+ }
+ }
+
+ /*
+ * Since we have them, try any CNAMEs that were traversed from uqhost
+ * to the canonical name (this assumes gethostbyname was called above)
+ */
+ if (!found_host) {
+ if (hp) {
+ for (hostp = hp->h_aliases; (host = *hostp) != NULL; hostp++)
{
- for (hostp = hp->h_aliases; (host = *hostp) != NULL; hostp++)
- {
- printf("Trying host %s ...\n", host);
- cmd = newstralloc2(cmd, "HOST ", host);
- if (converse(cmd) == -1)
- exit(1);
- if(server_happy())
- {
- found_host = 1;
- break;
- }
+ g_printf(_("Trying host %s ...\n"), host);
+ cmd = newstralloc2(cmd, "HOST ", host);
+ if (converse(cmd) == -1)
+ exit(1);
+ if(server_happy())
+ {
+ found_host = 1;
+ break;
}
}
}
}
- if(found_host)
- {
+
+ /* Try looking up the canonical name of the host */
+ if (!found_host) {
+ char *canonname;
+ int result;
+
+ result = resolve_hostname(uqhost, 0, NULL, &canonname);
+ if (result == 0 && canonname) {
+ host = canonname;
+ g_printf(_("Trying host %s ...\n"), host);
+ cmd = newstralloc2(cmd, "HOST ", host);
+ if (converse(cmd) == -1)
+ exit(1);
+ if(server_happy())
+ found_host = 1;
+ }
+ }
+
+ if(found_host) {
dump_hostname = newstralloc(dump_hostname, host);
amfree(disk_name);
amfree(mount_point);
clear_dir_list();
}
amfree(cmd);
+ amfree(uqhost);
}
void
{
char *cmd = NULL;
char *qdsk;
+ char *uqdsk;
+ char *uqmtpt = NULL;
if (is_extract_list_nonempty())
{
- printf("Must clear extract list before changing disk\n");
+ g_printf(_("Must clear extract list before changing disk\n"));
return;
}
/* if mount point specified, check it is valid */
- if ((mtpt != NULL) && (*mtpt != '/'))
- {
- printf("Mount point \"%s\" invalid - must start with /\n", mtpt);
- return;
+ if (mtpt != NULL) {
+ uqmtpt = unquote_string(mtpt);
+ if (*mtpt != '/') {
+ g_printf(_("Mount point \"%s\" invalid - must start with /\n"), uqmtpt);
+ amfree(uqmtpt);
+ return;
+ }
}
clear_dir_list();
- qdsk = quote_string(dsk);
+ uqdsk = unquote_string(dsk);
+ qdsk = quote_string(uqdsk);
cmd = stralloc2("DISK ", qdsk);
amfree(qdsk);
if (converse(cmd) == -1)
exit(1);
amfree(cmd);
- if (!server_happy())
+ if (!server_happy()) {
+ amfree(uqmtpt);
+ amfree(uqdsk);
return;
+ }
- disk_name = newstralloc(disk_name, dsk);
+ disk_name = newstralloc(disk_name, uqdsk);
if (mtpt == NULL)
{
/* mount point not specified */
- if (*dsk == '/')
+ if (*uqdsk == '/')
{
/* disk specified by mount point, hence use it */
- mount_point = newstralloc(mount_point, dsk);
+ mount_point = newstralloc(mount_point, uqdsk);
}
else
{
else
{
/* mount point specified */
- mount_point = newstralloc(mount_point, mtpt);
+ mount_point = newstralloc(mount_point, uqmtpt);
}
/* set the working directory to the mount point */
}
else
{
- printf("No index records for disk for specified date\n");
- printf("If date correct, notify system administrator\n");
+ g_printf(_("No index records for disk for specified date\n"));
+ g_printf(_("If date correct, notify system administrator\n"));
disk_path = newstralloc(disk_path, "/"); /* fake it */
clear_dir_list();
}
+ amfree(uqmtpt);
+ amfree(uqdsk);
+
+ if (am_has_feature(indexsrv_features, fe_amindexd_DLE)) {
+ char *dle_str;
+ char *errmsg = NULL;
+
+ cmd = stralloc("DLE");
+ if (exchange(cmd) == -1)
+ exit(1);
+ amfree(cmd);
+
+ if (!server_happy())
+ return;
+
+ dle_str = reply_line();
+ if (BSTRNCMP(dle_str+4, "NODLE") == 0) {
+ dump_dle = NULL;
+ } else {
+ dle_str = unquote_string(dle_str+4);
+ dump_dle = amxml_parse_node_CHAR(dle_str, &errmsg);
+ amfree(dle_str);
+ }
+ }
}
void
char * amdevice)
{
char *cmd = NULL;
- char *qamdevice;
+ char *qamdevice, *uqamdevice;
if(amdevice) {
- qamdevice = quote_string(amdevice);
+ uqamdevice = unquote_string(amdevice);
+ qamdevice = quote_string(uqamdevice);
cmd = stralloc2("LISTDISK ", qamdevice);
+ amfree(uqamdevice);
amfree(qamdevice);
if (converse(cmd) == -1)
exit(1);
}
}
+static GSList *prop_values = NULL;
+
+void
+set_property_name(
+ char *name,
+ int append)
+{
+ property_t *prop;
+ char *property_name, *pn;
+
+ pn = unquote_string(name);
+ property_name = amandaify_property_name(pn);
+ amfree(pn);
+
+ if (!append) {
+ g_hash_table_remove(proplist, property_name);
+ prop = NULL;
+ } else {
+ prop = g_hash_table_lookup(proplist, property_name);
+ }
+
+ if (!prop) {
+ prop = malloc(sizeof(property_t));
+ prop->append = 0;
+ prop->priority = 1;
+ prop->values = NULL;
+ g_hash_table_insert(proplist, stralloc(property_name), prop);
+ }
+
+ /* add prop_values to prop->values */
+ if (!prop->values) {
+ prop->values = prop_values;
+ prop_values = NULL;
+ } else {
+ GSList *pv;
+
+ for(pv = prop_values; pv != NULL; pv = pv->next) {
+ prop->values = g_slist_append(prop->values, pv->data);
+ }
+ g_slist_free(prop_values);
+ prop_values = NULL;
+ }
+ amfree(property_name);
+}
+
+void
+add_property_value(
+ char *value)
+{
+ if (value) {
+ prop_values = g_slist_prepend(prop_values, unquote_string(value));
+ }
+}
+
+/* A GHFunc (callback for g_hash_table_foreach) */
+static void list_one_property(
+ gpointer key_p,
+ gpointer value_p,
+ gpointer user_data_p G_GNUC_UNUSED)
+{
+ char *property_s = key_p;
+ char *qproperty;
+ property_t *property = value_p;
+ GSList *value;
+ char *qvalue;
+
+ qproperty = quote_string_always(property_s);
+ printf("property %s", qproperty);
+ amfree(qproperty);
+ for (value = property->values; value != NULL; value = value->next) {
+ qvalue = quote_string_always((char*)value->data);
+ printf(" %s", qvalue);
+ amfree(qvalue);
+ }
+ printf("\n");
+}
+
void
+list_property(void)
+{
+ if (proplist) {
+ g_hash_table_foreach(proplist, list_one_property, NULL);
+ } else {
+ printf("No property set\n");
+ }
+}
+
+void
+local_cd(
+ char *dir)
+{
+ char *uqdir = unquote_string(dir);
+ if (chdir(uqdir) == -1) {
+ perror(uqdir);
+ }
+ amfree(uqdir);
+}
+
+int
cd_glob(
- char * glob)
+ char * glob,
+ int verbose)
{
char *regex;
char *regex_path;
char *s;
+ char *uqglob;
+ int result;
char *path_on_disk = NULL;
if (disk_name == NULL) {
- printf("Must select disk before changing directory\n");
- return;
+ g_printf(_("Must select disk before changing directory\n"));
+ return 0;
}
- regex = glob_to_regex(glob);
- dbprintf(("cd_glob (%s) -> %s\n", glob, regex));
+ uqglob = unquote_string(glob);
+ regex = glob_to_regex(uqglob);
+ dbprintf(_("cd_glob (%s) -> %s\n"), uqglob, regex);
if ((s = validate_regexp(regex)) != NULL) {
- printf("\"%s\" is not a valid shell wildcard pattern: ", glob);
+ g_printf(_("\"%s\" is not a valid shell wildcard pattern: "), glob);
puts(s);
amfree(regex);
- return;
+ amfree(uqglob);
+ return 0;
}
/*
* glob_to_regex() anchors the beginning of the pattern with ^,
if (strcmp(disk_path, "/") == 0)
path_on_disk = stralloc2("/", regex_path);
else {
- char *clean_disk_path = clean_regex(disk_path);
+ char *clean_disk_path = clean_regex(disk_path, 0);
path_on_disk = vstralloc(clean_disk_path, "/", regex_path, NULL);
amfree(clean_disk_path);
}
- cd_dir(path_on_disk, glob);
+ result = cd_dir(path_on_disk, uqglob, verbose);
amfree(regex_path);
amfree(path_on_disk);
+ amfree(uqglob);
+
+ return result;
}
-void
+int
cd_regex(
- char * regex)
+ char * regex,
+ int verbose)
{
char *s;
+ char *uq_orig_regex;
+ char *uqregex;
+ int len_uqregex;
+ int result;
char *path_on_disk = NULL;
if (disk_name == NULL) {
- printf("Must select disk before changing directory\n");
- return;
+ g_printf(_("Must select disk before changing directory\n"));
+ return 0;
}
- if ((s = validate_regexp(regex)) != NULL) {
- printf("\"%s\" is not a valid regular expression: ", regex);
+ uq_orig_regex = unquote_string(regex);
+ uqregex = stralloc(uq_orig_regex);
+
+ /* Add a terminating '/' if it is not there, maybe before a '$' */
+ len_uqregex = strlen(uqregex);
+ if (uqregex[len_uqregex-1] == '$') {
+ if (uqregex[len_uqregex-2] != '/') {
+ uqregex[len_uqregex-1] = '\0';
+ strappend(uqregex, "/$");
+ }
+ } else if (uqregex[len_uqregex-1] != '/') {
+ //uqregex[len_uqregex-1] = '\0';
+ strappend(uqregex, "/");
+ }
+ if ((s = validate_regexp(uqregex)) != NULL) {
+ g_printf(_("\"%s\" is not a valid regular expression: "), uq_orig_regex);
+ amfree(uqregex);
+ amfree(uq_orig_regex);
puts(s);
- return;
+ return 0;
}
/* convert path (assumed in cwd) to one on disk */
if (strcmp(disk_path, "/") == 0)
- path_on_disk = stralloc2("/", regex);
+ path_on_disk = stralloc2("/", uqregex);
else {
- char *clean_disk_path = clean_regex(disk_path);
+ char *clean_disk_path = clean_regex(disk_path, 0);
path_on_disk = vstralloc(clean_disk_path, "/", regex, NULL);
amfree(clean_disk_path);
}
- cd_dir(path_on_disk, regex);
+ result = cd_dir(path_on_disk, uq_orig_regex, verbose);
amfree(path_on_disk);
+ amfree(uqregex);
+ amfree(uq_orig_regex);
+
+ return result;
}
-void
+int
cd_dir(
char * path_on_disk,
- char * default_dir)
+ char * default_dir,
+ int verbose)
{
- char *path_on_disk_slash = NULL;
char *dir = NULL;
-
+ char *s;
int nb_found;
+ int result;
size_t i;
DIR_ITEM *ditem;
- path_on_disk_slash = stralloc2(path_on_disk, "/");
+ if ((s = validate_regexp(path_on_disk)) != NULL) {
+ result = set_directory(default_dir, verbose);
+ return result;
+ }
nb_found = 0;
for (ditem=get_dir_list(); ditem!=NULL && nb_found <= 1;
ditem=get_next_dir_item(ditem))
{
- if (match(path_on_disk, ditem->path)
- || match(path_on_disk_slash, ditem->path))
+ if (match(path_on_disk, ditem->path))
{
i = strlen(ditem->path);
if((i > 0 && ditem->path[i-1] == '/')
if(dir[strlen(dir)-1] == '/')
dir[strlen(dir)-1] = '\0'; /* remove last / */
/* remove everything before the last / */
- dir1 = rindex(dir,'/');
+ dir1 = strrchr(dir,'/');
if (dir1) {
dir1++;
dir2 = stralloc(dir1);
}
}
}
- amfree(path_on_disk_slash);
if(nb_found==0) {
- set_directory(default_dir);
+ result = set_directory(default_dir, verbose);
}
else if(nb_found==1) {
- set_directory(dir);
+ result = set_directory(dir, verbose);
}
else {
- printf("Too many directory\n");
+ g_printf(_("Too many directories matching '%s'\n"), default_dir);
+ result = 0;
}
amfree(dir);
+ return result;
}
-void
+int
set_directory(
- char * dir)
+ char * dir,
+ int verbose)
{
char *cmd = NULL;
char *new_dir = NULL;
char *qnew_dir;
char *dp, *de;
char *ldir = NULL;
+ int result;
/* do nothing if "." */
if(strcmp(dir,".")==0) {
show_directory(); /* say where we are */
- return;
+ return 1;
/*NOTREACHED*/
}
if (disk_name == NULL) {
- printf("Must select disk before setting directory\n");
- return;
+ g_printf(_("Must select disk before setting directory\n"));
+ return 0;
/*NOTREACHED*/
}
{
if (strncmp(mount_point, ldir, strlen(mount_point)) != 0)
{
- printf("Invalid directory - Can't cd outside mount point \"%s\"\n",
+ g_printf(_("Invalid directory - Can't cd outside mount point \"%s\"\n"),
mount_point);
amfree(ldir);
- return;
+ return 0;
/*NOTREACHED*/
}
new_dir = stralloc(ldir+strlen(mount_point));
if (strcmp(dp, "..") == 0) {
if (strcmp(new_dir, "/") == 0) {
/* at top of disk */
- printf("Invalid directory - Can't cd outside mount point \"%s\"\n",
+ g_printf(_("Invalid directory - Can't cd outside mount point \"%s\"\n"),
mount_point);
/*@ignore@*/
amfree(new_dir);
/*@end@*/
amfree(ldir);
- return;
+ return 0;
/*NOTREACHED*/
}
de = strrchr(new_dir, '/'); /* always at least 1 */
{
disk_path = newstralloc(disk_path, new_dir);
suck_dir_list_from_server(); /* get list of directory contents */
- show_directory(); /* say where we moved to */
+ if (verbose)
+ show_directory(); /* say where we moved to */
+ result = 1;
}
else
{
- printf("Invalid directory - %s\n", dir);
+ g_printf(_("Invalid directory - %s\n"), dir);
+ result = 0;
}
/*@ignore@*/
amfree(new_dir);
amfree(ldir);
/*@end@*/
+
+ return result;
}
show_directory(void)
{
if (mount_point == NULL || disk_path == NULL)
- printf("Must select disk first\n");
+ g_printf(_("Must select disk first\n"));
else if (strcmp(mount_point, "/") == 0)
- printf("%s\n", disk_path);
+ g_printf("%s\n", disk_path);
else if (strcmp(disk_path, "/") == 0)
- printf("%s\n", mount_point);
+ g_printf("%s\n", mount_point);
else
- printf("%s%s\n", mount_point, disk_path);
+ g_printf("%s%s\n", mount_point, disk_path);
}
-/* set the tape server and device */
+/* set the tape server and device (deprecated version) */
void
set_tape(
char * tape)
{
- char *tapedev = strchr(tape, ':');
+ char *uqtape = unquote_string(tape);
+ char *tapedev = strchr(uqtape, ':');
+ char *host = NULL;
+
+ g_printf(_("NOTE: 'settape' is deprecated; use setdevice instead.\n"));
if (tapedev)
{
- if (tapedev != tape) {
+ /* This command is deprecated because this parsing is going to fall
+ * behind the list of available device names at some point, or to shadow
+ * an interesting hostname (wouldn't 'tape' be a good name for a
+ * tape server?) */
+ if (tapedev != uqtape) {
if((strchr(tapedev+1, ':') == NULL) &&
- (strncmp(tape, "null:", 5) == 0 ||
- strncmp(tape, "rait:", 5) == 0 ||
- strncmp(tape, "file:", 5) == 0 ||
- strncmp(tape, "tape:", 5) == 0)) {
- tapedev = tape;
+ (strncmp_const(uqtape, "null:") == 0 ||
+ strncmp_const(uqtape, "rait:") == 0 ||
+ strncmp_const(uqtape, "file:") == 0 ||
+ strncmp_const(uqtape, "s3:") == 0 ||
+ strncmp_const(uqtape, "tape:") == 0)) {
+ tapedev = uqtape;
}
else {
*tapedev = '\0';
- tape_server_name = newstralloc(tape_server_name, tape);
+ host = stralloc(uqtape);
++tapedev;
}
- } else { /* reset server_name if start with : */
- amfree(tape_server_name);
+ } else {
++tapedev;
}
} else
- tapedev = tape;
+ tapedev = uqtape;
if (tapedev[0])
{
if (strcmp(tapedev, "default") == 0)
- amfree(tape_device_name);
- else
- tape_device_name = newstralloc(tape_device_name, tapedev);
+ tapedev = NULL;
}
+ /* call out to the new version */
+ set_device(host, tapedev);
+
+ amfree(host);
+ amfree(uqtape);
+}
+
+/* set the tape server and device, for real */
+void
+set_device(
+ char * host,
+ char * device)
+{
+ if (host)
+ tape_server_name = newstralloc(tape_server_name, host);
+ else
+ amfree(tape_server_name);
+
+ if (device)
+ tape_device_name = newstralloc(tape_device_name, device);
+ else
+ amfree(tape_device_name);
+
+ /* print the current status */
if (tape_device_name)
- printf ("Using tape \"%s\"", tape_device_name);
+ g_printf (_("Using tape \"%s\""), tape_device_name);
else
- printf ("Using default tape");
+ g_printf (_("Using default tape"));
if (tape_server_name)
- printf (" from server %s.\n", tape_server_name);
+ g_printf (_(" from server %s.\n"), tape_server_name);
else
- printf (".\nTape server unspecified, assumed to be %s.\n",
+ g_printf (_(".\nTape server unspecified, assumed to be %s.\n"),
server_name);
}
set_mode(
int mode)
{
-#ifdef SAMBA_CLIENT
if (mode == SAMBA_SMBCLIENT) {
- printf ("SAMBA dumps will be extracted using smbclient\n");
+ g_printf (_("SAMBA dumps will be extracted using smbclient\n"));
samba_extract_method = SAMBA_SMBCLIENT;
} else {
if (mode == SAMBA_TAR) {
- printf ("SAMBA dumps will be extracted as TAR dumps\n");
+ g_printf (_("SAMBA dumps will be extracted as TAR dumps\n"));
samba_extract_method = SAMBA_TAR;
}
}
-#else
- (void)mode; /* Quiet unused parameter warning */
-#endif /* SAMBA_CLIENT */
}
void
show_mode(void)
{
#ifdef SAMBA_CLIENT
- printf ("SAMBA dumps are extracted ");
+ g_printf (_("SAMBA dumps are extracted "));
if (samba_extract_method == SAMBA_TAR) {
- printf (" as TAR dumps\n");
+ g_printf (_(" as TAR dumps\n"));
} else {
- printf ("using smbclient\n");
+ g_printf (_("using smbclient\n"));
}
#endif /* SAMBA_CLIENT */
}