2 * Amanda, The Advanced Maryland Automatic Network Disk Archiver
3 * Copyright (c) 1991-1998, 2000 University of Maryland at College Park
4 * Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved.
7 * Permission to use, copy, modify, distribute, and sell this software and its
8 * documentation for any purpose is hereby granted without fee, provided that
9 * the above copyright notice appear in all copies and that both that
10 * copyright notice and this permission notice appear in supporting
11 * documentation, and that the name of U.M. not be used in advertising or
12 * publicity pertaining to distribution of the software without specific,
13 * written prior permission. U.M. makes no representations about the
14 * suitability of this software for any purpose. It is provided "as is"
15 * without express or implied warranty.
17 * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
19 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
20 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
21 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
22 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
24 * Authors: the Amanda Development Team. Its members are listed in a
25 * file named AUTHORS, in the root directory of this distribution.
28 * $Id: set_commands.c,v 1.3 2006/07/05 13:14:58 martinea Exp $
30 * implements the "set" commands in amrecover
36 #include "amrecover.h"
39 extern unsigned short samba_extract_method;
40 #endif /* SAMBA_CLIENT */
42 /* sets a date, mapping given date into standard form if needed */
51 cmd = stralloc2("DATE ", date);
52 if (converse(cmd) == -1)
55 /* if a host/disk/directory is set, then check if that directory
56 is still valid at the new date, and if not set directory to
58 if (disk_path != NULL) {
59 cmd = newstralloc2(cmd, "OISD ", disk_path);
60 if (exchange(cmd) == -1)
64 suck_dir_list_from_server();
68 g_printf(_("No index records for cwd on new date\n"));
69 g_printf(_("Setting cwd to mount point\n"));
70 disk_path = newstralloc(disk_path, "/"); /* fake it */
87 char *uqhost = unquote_string(host);
89 if (is_extract_list_nonempty())
91 g_printf(_("Must clear extract list before changing host\n"));
95 cmd = stralloc2("HOST ", uqhost);
96 if (converse(cmd) == -1)
105 * Try converting the given host to a fully qualified name
106 * and then try each of the aliases.
108 if ((hp = gethostbyname(uqhost)) != NULL) {
110 g_printf(_("Trying host %s ...\n"), host);
111 cmd = newstralloc2(cmd, "HOST ", host);
112 if (converse(cmd) == -1)
120 for (hostp = hp->h_aliases; (host = *hostp) != NULL; hostp++)
122 g_printf(_("Trying host %s ...\n"), host);
123 cmd = newstralloc2(cmd, "HOST ", host);
124 if (converse(cmd) == -1)
137 dump_hostname = newstralloc(dump_hostname, host);
153 cmd = stralloc("LISTHOST");
154 if (converse(cmd) == -1)
168 if (is_extract_list_nonempty())
170 g_printf(_("Must clear extract list before changing disk\n"));
174 /* if mount point specified, check it is valid */
176 uqmtpt = unquote_string(mtpt);
178 g_printf(_("Mount point \"%s\" invalid - must start with /\n"), uqmtpt);
185 uqdsk = unquote_string(dsk);
186 cmd = stralloc2("DISK ", uqdsk);
187 if (converse(cmd) == -1)
194 disk_name = newstralloc(disk_name, uqdsk);
197 /* mount point not specified */
200 /* disk specified by mount point, hence use it */
201 mount_point = newstralloc(mount_point, uqdsk);
205 /* device name given, use '/' because nothing better */
206 mount_point = newstralloc(mount_point, "/");
211 /* mount point specified */
212 mount_point = newstralloc(mount_point, uqmtpt);
215 /* set the working directory to the mount point */
216 /* there is the possibility that there are no index records for the
217 disk for the given date, hence setting the directory to the
218 mount point will fail. Preempt this by checking first so we can write
219 a more informative message. */
220 if (exchange("OISD /") == -1)
224 disk_path = newstralloc(disk_path, "/");
225 suck_dir_list_from_server(); /* get list of directory contents */
229 g_printf(_("No index records for disk for specified date\n"));
230 g_printf(_("If date correct, notify system administrator\n"));
231 disk_path = newstralloc(disk_path, "/"); /* fake it */
246 uqamdevice = unquote_string(amdevice);
247 cmd = stralloc2("LISTDISK ", uqamdevice);
249 if (converse(cmd) == -1)
254 cmd = stralloc("LISTDISK");
255 if (converse(cmd) == -1)
265 char *uqdir = unquote_string(dir);
266 if (chdir(uqdir) == -1) {
281 char *path_on_disk = NULL;
283 if (disk_name == NULL) {
284 g_printf(_("Must select disk before changing directory\n"));
288 uqglob = unquote_string(glob);
289 regex = glob_to_regex(uqglob);
290 dbprintf(_("cd_glob (%s) -> %s\n"), uqglob, regex);
291 if ((s = validate_regexp(regex)) != NULL) {
292 g_printf(_("\"%s\" is not a valid shell wildcard pattern: "), glob);
298 * glob_to_regex() anchors the beginning of the pattern with ^,
299 * but we will be tacking it onto the end of the current directory
300 * in add_file, so strip that off. Also, it anchors the end with
301 * $, but we need to match a trailing /, add it if it is not there
303 regex_path = stralloc(regex + 1);
305 if(regex_path[strlen(regex_path) - 2] != '/' ) {
306 regex_path[strlen(regex_path) - 1] = '\0';
307 strappend(regex_path, "/$");
310 /* convert path (assumed in cwd) to one on disk */
311 if (strcmp(disk_path, "/") == 0)
312 path_on_disk = stralloc2("/", regex_path);
314 char *clean_disk_path = clean_regex(disk_path, 0);
315 path_on_disk = vstralloc(clean_disk_path, "/", regex_path, NULL);
316 amfree(clean_disk_path);
319 cd_dir(path_on_disk, uqglob);
322 amfree(path_on_disk);
333 char *path_on_disk = NULL;
335 if (disk_name == NULL) {
336 g_printf(_("Must select disk before changing directory\n"));
340 uqregex = unquote_string(regex);
341 if ((s = validate_regexp(uqregex)) != NULL) {
342 g_printf(_("\"%s\" is not a valid regular expression: "), uqregex);
348 /* convert path (assumed in cwd) to one on disk */
349 if (strcmp(disk_path, "/") == 0)
350 path_on_disk = stralloc2("/", regex);
352 char *clean_disk_path = clean_regex(disk_path, 0);
353 path_on_disk = vstralloc(clean_disk_path, "/", regex, NULL);
354 amfree(clean_disk_path);
357 cd_dir(path_on_disk, uqregex);
359 amfree(path_on_disk);
368 char *path_on_disk_slash = NULL;
376 path_on_disk_slash = stralloc2(path_on_disk, "/");
380 for (ditem=get_dir_list(); ditem!=NULL && nb_found <= 1;
381 ditem=get_next_dir_item(ditem))
383 if (match(path_on_disk, ditem->path)
384 || match(path_on_disk_slash, ditem->path))
386 i = strlen(ditem->path);
387 if((i > 0 && ditem->path[i-1] == '/')
388 || (i > 1 && ditem->path[i-2] == '/' && ditem->path[i-1] == '.'))
389 { /* It is a directory */
392 dir = newstralloc(dir,ditem->path);
393 if(dir[strlen(dir)-1] == '/')
394 dir[strlen(dir)-1] = '\0'; /* remove last / */
395 /* remove everything before the last / */
396 dir1 = strrchr(dir,'/');
399 dir2 = stralloc(dir1);
406 amfree(path_on_disk_slash);
409 set_directory(default_dir);
411 else if(nb_found==1) {
415 g_printf(_("Too many directory\n"));
425 char *new_dir = NULL;
429 /* do nothing if "." */
430 if(strcmp(dir,".")==0) {
431 show_directory(); /* say where we are */
436 if (disk_name == NULL) {
437 g_printf(_("Must select disk before setting directory\n"));
442 ldir = stralloc(dir);
443 clean_pathname(ldir);
445 /* convert directory into absolute path relative to disk mount point */
448 /* absolute path specified, must start with mount point */
449 if (strcmp(mount_point, "/") == 0)
451 new_dir = stralloc(ldir);
455 if (strncmp(mount_point, ldir, strlen(mount_point)) != 0)
457 g_printf(_("Invalid directory - Can't cd outside mount point \"%s\"\n"),
463 new_dir = stralloc(ldir+strlen(mount_point));
464 if (strlen(new_dir) == 0) {
465 new_dir = newstralloc(new_dir, "/");
466 /* i.e. ldir == mount_point */
472 new_dir = stralloc(disk_path);
474 /* strip any leading ..s */
475 while (strncmp(dp, "../", 3) == 0)
477 de = strrchr(new_dir, '/'); /* always at least 1 */
490 if (strcmp(dp, "..") == 0) {
491 if (strcmp(new_dir, "/") == 0) {
493 g_printf(_("Invalid directory - Can't cd outside mount point \"%s\"\n"),
502 de = strrchr(new_dir, '/'); /* always at least 1 */
514 if (strcmp(new_dir, "/") != 0) {
515 strappend(new_dir, "/");
517 strappend(new_dir, ldir);
522 cmd = stralloc2("OISD ", new_dir);
523 if (exchange(cmd) == -1) {
531 disk_path = newstralloc(disk_path, new_dir);
532 suck_dir_list_from_server(); /* get list of directory contents */
533 show_directory(); /* say where we moved to */
537 g_printf(_("Invalid directory - %s\n"), dir);
547 /* prints the current working directory */
551 if (mount_point == NULL || disk_path == NULL)
552 g_printf(_("Must select disk first\n"));
553 else if (strcmp(mount_point, "/") == 0)
554 g_printf("%s\n", disk_path);
555 else if (strcmp(disk_path, "/") == 0)
556 g_printf("%s\n", mount_point);
558 g_printf("%s%s\n", mount_point, disk_path);
562 /* set the tape server and device */
567 char *uqtape = unquote_string(tape);
568 char *tapedev = strchr(uqtape, ':');
572 if (tapedev != uqtape) {
573 if((strchr(tapedev+1, ':') == NULL) &&
574 (strncmp(uqtape, "null:", 5) == 0 ||
575 strncmp(uqtape, "rait:", 5) == 0 ||
576 strncmp(uqtape, "file:", 5) == 0 ||
577 strncmp(uqtape, "tape:", 5) == 0)) {
582 tape_server_name = newstralloc(tape_server_name, uqtape);
585 } else { /* reset server_name if start with : */
586 amfree(tape_server_name);
594 if (strcmp(tapedev, "default") == 0)
595 amfree(tape_device_name);
597 tape_device_name = newstralloc(tape_device_name, tapedev);
600 if (tape_device_name)
601 g_printf (_("Using tape \"%s\""), tape_device_name);
603 g_printf (_("Using default tape"));
605 if (tape_server_name)
606 g_printf (_(" from server %s.\n"), tape_server_name);
608 g_printf (_(".\nTape server unspecified, assumed to be %s.\n"),
617 if (mode == SAMBA_SMBCLIENT) {
618 g_printf (_("SAMBA dumps will be extracted using smbclient\n"));
619 samba_extract_method = SAMBA_SMBCLIENT;
621 if (mode == SAMBA_TAR) {
622 g_printf (_("SAMBA dumps will be extracted as TAR dumps\n"));
623 samba_extract_method = SAMBA_TAR;
627 (void)mode; /* Quiet unused parameter warning */
628 #endif /* SAMBA_CLIENT */
635 g_printf (_("SAMBA dumps are extracted "));
637 if (samba_extract_method == SAMBA_TAR) {
638 g_printf (_(" as TAR dumps\n"));
640 g_printf (_("using smbclient\n"));
642 #endif /* SAMBA_CLIENT */