2 * Amanda, The Advanced Maryland Automatic Network Disk Archiver
3 * Copyright (c) 1991-1998, 2000 University of Maryland at College Park
6 * Permission to use, copy, modify, distribute, and sell this software and its
7 * documentation for any purpose is hereby granted without fee, provided that
8 * the above copyright notice appear in all copies and that both that
9 * copyright notice and this permission notice appear in supporting
10 * documentation, and that the name of U.M. not be used in advertising or
11 * publicity pertaining to distribution of the software without specific,
12 * written prior permission. U.M. makes no representations about the
13 * suitability of this software for any purpose. It is provided "as is"
14 * without express or implied warranty.
16 * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
18 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
20 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
21 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23 * Authors: the Amanda Development Team. Its members are listed in a
24 * file named AUTHORS, in the root directory of this distribution.
27 * $Id: set_commands.c,v 1.3 2006/07/05 13:14:58 martinea Exp $
29 * implements the "set" commands in amrecover
35 #include "amrecover.h"
38 extern unsigned short samba_extract_method;
39 #endif /* SAMBA_CLIENT */
41 /* sets a date, mapping given date into standard form if needed */
50 cmd = stralloc2("DATE ", date);
51 if (converse(cmd) == -1)
54 /* if a host/disk/directory is set, then check if that directory
55 is still valid at the new date, and if not set directory to
57 if (disk_path != NULL) {
58 cmd = newstralloc2(cmd, "OISD ", disk_path);
59 if (exchange(cmd) == -1)
63 suck_dir_list_from_server();
67 g_printf(_("No index records for cwd on new date\n"));
68 g_printf(_("Setting cwd to mount point\n"));
69 disk_path = newstralloc(disk_path, "/"); /* fake it */
86 char *uqhost = unquote_string(host);
88 if (is_extract_list_nonempty())
90 g_printf(_("Must clear extract list before changing host\n"));
94 cmd = stralloc2("HOST ", uqhost);
95 if (converse(cmd) == -1)
104 * Try converting the given host to a fully qualified name
105 * and then try each of the aliases.
107 if ((hp = gethostbyname(uqhost)) != NULL) {
109 g_printf(_("Trying host %s ...\n"), host);
110 cmd = newstralloc2(cmd, "HOST ", host);
111 if (converse(cmd) == -1)
119 for (hostp = hp->h_aliases; (host = *hostp) != NULL; hostp++)
121 g_printf(_("Trying host %s ...\n"), host);
122 cmd = newstralloc2(cmd, "HOST ", host);
123 if (converse(cmd) == -1)
136 dump_hostname = newstralloc(dump_hostname, host);
152 cmd = stralloc("LISTHOST");
153 if (converse(cmd) == -1)
167 if (is_extract_list_nonempty())
169 g_printf(_("Must clear extract list before changing disk\n"));
173 /* if mount point specified, check it is valid */
175 uqmtpt = unquote_string(mtpt);
177 g_printf(_("Mount point \"%s\" invalid - must start with /\n"), uqmtpt);
184 uqdsk = unquote_string(dsk);
185 cmd = stralloc2("DISK ", uqdsk);
186 if (converse(cmd) == -1)
193 disk_name = newstralloc(disk_name, uqdsk);
196 /* mount point not specified */
199 /* disk specified by mount point, hence use it */
200 mount_point = newstralloc(mount_point, uqdsk);
204 /* device name given, use '/' because nothing better */
205 mount_point = newstralloc(mount_point, "/");
210 /* mount point specified */
211 mount_point = newstralloc(mount_point, uqmtpt);
214 /* set the working directory to the mount point */
215 /* there is the possibility that there are no index records for the
216 disk for the given date, hence setting the directory to the
217 mount point will fail. Preempt this by checking first so we can write
218 a more informative message. */
219 if (exchange("OISD /") == -1)
223 disk_path = newstralloc(disk_path, "/");
224 suck_dir_list_from_server(); /* get list of directory contents */
228 g_printf(_("No index records for disk for specified date\n"));
229 g_printf(_("If date correct, notify system administrator\n"));
230 disk_path = newstralloc(disk_path, "/"); /* fake it */
245 uqamdevice = unquote_string(amdevice);
246 cmd = stralloc2("LISTDISK ", uqamdevice);
248 if (converse(cmd) == -1)
253 cmd = stralloc("LISTDISK");
254 if (converse(cmd) == -1)
264 char *uqdir = unquote_string(dir);
265 if (chdir(uqdir) == -1) {
280 char *path_on_disk = NULL;
282 if (disk_name == NULL) {
283 g_printf(_("Must select disk before changing directory\n"));
287 uqglob = unquote_string(glob);
288 regex = glob_to_regex(uqglob);
289 dbprintf(_("cd_glob (%s) -> %s\n"), uqglob, regex);
290 if ((s = validate_regexp(regex)) != NULL) {
291 g_printf(_("\"%s\" is not a valid shell wildcard pattern: "), glob);
297 * glob_to_regex() anchors the beginning of the pattern with ^,
298 * but we will be tacking it onto the end of the current directory
299 * in add_file, so strip that off. Also, it anchors the end with
300 * $, but we need to match a trailing /, add it if it is not there
302 regex_path = stralloc(regex + 1);
304 if(regex_path[strlen(regex_path) - 2] != '/' ) {
305 regex_path[strlen(regex_path) - 1] = '\0';
306 strappend(regex_path, "/$");
309 /* convert path (assumed in cwd) to one on disk */
310 if (strcmp(disk_path, "/") == 0)
311 path_on_disk = stralloc2("/", regex_path);
313 char *clean_disk_path = clean_regex(disk_path, 0);
314 path_on_disk = vstralloc(clean_disk_path, "/", regex_path, NULL);
315 amfree(clean_disk_path);
318 cd_dir(path_on_disk, uqglob);
321 amfree(path_on_disk);
332 char *path_on_disk = NULL;
334 if (disk_name == NULL) {
335 g_printf(_("Must select disk before changing directory\n"));
339 uqregex = unquote_string(regex);
340 if ((s = validate_regexp(uqregex)) != NULL) {
341 g_printf(_("\"%s\" is not a valid regular expression: "), uqregex);
347 /* convert path (assumed in cwd) to one on disk */
348 if (strcmp(disk_path, "/") == 0)
349 path_on_disk = stralloc2("/", regex);
351 char *clean_disk_path = clean_regex(disk_path, 0);
352 path_on_disk = vstralloc(clean_disk_path, "/", regex, NULL);
353 amfree(clean_disk_path);
356 cd_dir(path_on_disk, uqregex);
358 amfree(path_on_disk);
367 char *path_on_disk_slash = NULL;
375 path_on_disk_slash = stralloc2(path_on_disk, "/");
379 for (ditem=get_dir_list(); ditem!=NULL && nb_found <= 1;
380 ditem=get_next_dir_item(ditem))
382 if (match(path_on_disk, ditem->path)
383 || match(path_on_disk_slash, ditem->path))
385 i = strlen(ditem->path);
386 if((i > 0 && ditem->path[i-1] == '/')
387 || (i > 1 && ditem->path[i-2] == '/' && ditem->path[i-1] == '.'))
388 { /* It is a directory */
391 dir = newstralloc(dir,ditem->path);
392 if(dir[strlen(dir)-1] == '/')
393 dir[strlen(dir)-1] = '\0'; /* remove last / */
394 /* remove everything before the last / */
395 dir1 = strrchr(dir,'/');
398 dir2 = stralloc(dir1);
405 amfree(path_on_disk_slash);
408 set_directory(default_dir);
410 else if(nb_found==1) {
414 g_printf(_("Too many directory\n"));
424 char *new_dir = NULL;
428 /* do nothing if "." */
429 if(strcmp(dir,".")==0) {
430 show_directory(); /* say where we are */
435 if (disk_name == NULL) {
436 g_printf(_("Must select disk before setting directory\n"));
441 ldir = stralloc(dir);
442 clean_pathname(ldir);
444 /* convert directory into absolute path relative to disk mount point */
447 /* absolute path specified, must start with mount point */
448 if (strcmp(mount_point, "/") == 0)
450 new_dir = stralloc(ldir);
454 if (strncmp(mount_point, ldir, strlen(mount_point)) != 0)
456 g_printf(_("Invalid directory - Can't cd outside mount point \"%s\"\n"),
462 new_dir = stralloc(ldir+strlen(mount_point));
463 if (strlen(new_dir) == 0) {
464 new_dir = newstralloc(new_dir, "/");
465 /* i.e. ldir == mount_point */
471 new_dir = stralloc(disk_path);
473 /* strip any leading ..s */
474 while (strncmp(dp, "../", 3) == 0)
476 de = strrchr(new_dir, '/'); /* always at least 1 */
489 if (strcmp(dp, "..") == 0) {
490 if (strcmp(new_dir, "/") == 0) {
492 g_printf(_("Invalid directory - Can't cd outside mount point \"%s\"\n"),
501 de = strrchr(new_dir, '/'); /* always at least 1 */
513 if (strcmp(new_dir, "/") != 0) {
514 strappend(new_dir, "/");
516 strappend(new_dir, ldir);
521 cmd = stralloc2("OISD ", new_dir);
522 if (exchange(cmd) == -1) {
530 disk_path = newstralloc(disk_path, new_dir);
531 suck_dir_list_from_server(); /* get list of directory contents */
532 show_directory(); /* say where we moved to */
536 g_printf(_("Invalid directory - %s\n"), dir);
546 /* prints the current working directory */
550 if (mount_point == NULL || disk_path == NULL)
551 g_printf(_("Must select disk first\n"));
552 else if (strcmp(mount_point, "/") == 0)
553 g_printf("%s\n", disk_path);
554 else if (strcmp(disk_path, "/") == 0)
555 g_printf("%s\n", mount_point);
557 g_printf("%s%s\n", mount_point, disk_path);
561 /* set the tape server and device */
566 char *uqtape = unquote_string(tape);
567 char *tapedev = strchr(uqtape, ':');
571 if (tapedev != uqtape) {
572 if((strchr(tapedev+1, ':') == NULL) &&
573 (strncmp(uqtape, "null:", 5) == 0 ||
574 strncmp(uqtape, "rait:", 5) == 0 ||
575 strncmp(uqtape, "file:", 5) == 0 ||
576 strncmp(uqtape, "tape:", 5) == 0)) {
581 tape_server_name = newstralloc(tape_server_name, uqtape);
584 } else { /* reset server_name if start with : */
585 amfree(tape_server_name);
593 if (strcmp(tapedev, "default") == 0)
594 amfree(tape_device_name);
596 tape_device_name = newstralloc(tape_device_name, tapedev);
599 if (tape_device_name)
600 g_printf (_("Using tape \"%s\""), tape_device_name);
602 g_printf (_("Using default tape"));
604 if (tape_server_name)
605 g_printf (_(" from server %s.\n"), tape_server_name);
607 g_printf (_(".\nTape server unspecified, assumed to be %s.\n"),
616 if (mode == SAMBA_SMBCLIENT) {
617 g_printf (_("SAMBA dumps will be extracted using smbclient\n"));
618 samba_extract_method = SAMBA_SMBCLIENT;
620 if (mode == SAMBA_TAR) {
621 g_printf (_("SAMBA dumps will be extracted as TAR dumps\n"));
622 samba_extract_method = SAMBA_TAR;
626 (void)mode; /* Quiet unused parameter warning */
627 #endif /* SAMBA_CLIENT */
634 g_printf (_("SAMBA dumps are extracted "));
636 if (samba_extract_method == SAMBA_TAR) {
637 g_printf (_(" as TAR dumps\n"));
639 g_printf (_("using smbclient\n"));
641 #endif /* SAMBA_CLIENT */