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.26 2006/07/05 13:14:58 martinea Exp $
29 * implements the "set" commands in amrecover
33 #include "amrecover.h"
36 extern unsigned short samba_extract_method;
37 #endif /* SAMBA_CLIENT */
39 /* sets a date, mapping given date into standard form if needed */
48 cmd = stralloc2("DATE ", date);
49 if (converse(cmd) == -1)
52 /* if a host/disk/directory is set, then check if that directory
53 is still valid at the new date, and if not set directory to
55 if (disk_path != NULL) {
56 cmd = newstralloc2(cmd, "OISD ", disk_path);
57 if (exchange(cmd) == -1)
61 suck_dir_list_from_server();
65 printf("No index records for cwd on new date\n");
66 printf("Setting cwd to mount point\n");
67 disk_path = newstralloc(disk_path, "/"); /* fake it */
85 if (is_extract_list_nonempty())
87 printf("Must clear extract list before changing host\n");
91 cmd = stralloc2("HOST ", host);
92 if (converse(cmd) == -1)
101 * Try converting the given host to a fully qualified name
102 * and then try each of the aliases.
104 if ((hp = gethostbyname(host)) != NULL) {
106 printf("Trying host %s ...\n", host);
107 cmd = newstralloc2(cmd, "HOST ", host);
108 if (converse(cmd) == -1)
116 for (hostp = hp->h_aliases; (host = *hostp) != NULL; hostp++)
118 printf("Trying host %s ...\n", host);
119 cmd = newstralloc2(cmd, "HOST ", host);
120 if (converse(cmd) == -1)
133 dump_hostname = newstralloc(dump_hostname, host);
147 cmd = stralloc("LISTHOST");
148 if (converse(cmd) == -1)
160 if (is_extract_list_nonempty())
162 printf("Must clear extract list before changing disk\n");
166 /* if mount point specified, check it is valid */
167 if ((mtpt != NULL) && (*mtpt != '/'))
169 printf("Mount point \"%s\" invalid - must start with /\n", mtpt);
174 cmd = stralloc2("DISK ", dsk);
175 if (converse(cmd) == -1)
182 disk_name = newstralloc(disk_name, dsk);
185 /* mount point not specified */
188 /* disk specified by mount point, hence use it */
189 mount_point = newstralloc(mount_point, dsk);
193 /* device name given, use '/' because nothing better */
194 mount_point = newstralloc(mount_point, "/");
199 /* mount point specified */
200 mount_point = newstralloc(mount_point, mtpt);
203 /* set the working directory to the mount point */
204 /* there is the possibility that there are no index records for the
205 disk for the given date, hence setting the directory to the
206 mount point will fail. Preempt this by checking first so we can write
207 a more informative message. */
208 if (exchange("OISD /") == -1)
212 disk_path = newstralloc(disk_path, "/");
213 suck_dir_list_from_server(); /* get list of directory contents */
217 printf("No index records for disk for specified date\n");
218 printf("If date correct, notify system administrator\n");
219 disk_path = newstralloc(disk_path, "/"); /* fake it */
231 cmd = stralloc2("LISTDISK ", amdevice);
232 if (converse(cmd) == -1)
237 cmd = stralloc("LISTDISK");
238 if (converse(cmd) == -1)
252 char *path_on_disk = NULL;
254 if (disk_name == NULL) {
255 printf("Must select disk before changing directory\n");
259 regex = glob_to_regex(glob);
260 dbprintf(("cd_glob (%s) -> %s\n", glob, regex));
261 if ((s = validate_regexp(regex)) != NULL) {
262 printf("\"%s\" is not a valid shell wildcard pattern: ", glob);
268 * glob_to_regex() anchors the beginning of the pattern with ^,
269 * but we will be tacking it onto the end of the current directory
270 * in add_file, so strip that off. Also, it anchors the end with
271 * $, but we need to match a trailing /, add it if it is not there
273 regex_path = stralloc(regex + 1);
275 if(regex_path[strlen(regex_path) - 2] != '/' ) {
276 regex_path[strlen(regex_path) - 1] = '\0';
277 strappend(regex_path, "/$");
280 /* convert path (assumed in cwd) to one on disk */
281 if (strcmp(disk_path, "/") == 0)
282 path_on_disk = stralloc2("/", regex_path);
284 char *clean_disk_path = clean_regex(disk_path);
285 path_on_disk = vstralloc(clean_disk_path, "/", regex_path, NULL);
286 amfree(clean_disk_path);
289 cd_dir(path_on_disk, glob);
292 amfree(path_on_disk);
301 char *path_on_disk = NULL;
303 if (disk_name == NULL) {
304 printf("Must select disk before changing directory\n");
308 if ((s = validate_regexp(regex)) != NULL) {
309 printf("\"%s\" is not a valid regular expression: ", regex);
314 /* convert path (assumed in cwd) to one on disk */
315 if (strcmp(disk_path, "/") == 0)
316 path_on_disk = stralloc2("/", regex);
318 char *clean_disk_path = clean_regex(disk_path);
319 path_on_disk = vstralloc(clean_disk_path, "/", regex, NULL);
320 amfree(clean_disk_path);
323 cd_dir(path_on_disk, regex);
325 amfree(path_on_disk);
333 char *path_on_disk_slash = NULL;
341 path_on_disk_slash = stralloc2(path_on_disk, "/");
345 for (ditem=get_dir_list(); ditem!=NULL && nb_found <= 1;
346 ditem=get_next_dir_item(ditem))
348 if (match(path_on_disk, ditem->path)
349 || match(path_on_disk_slash, ditem->path))
351 i = strlen(ditem->path);
352 if((i > 0 && ditem->path[i-1] == '/')
353 || (i > 1 && ditem->path[i-2] == '/' && ditem->path[i-1] == '.'))
354 { /* It is a directory */
357 dir = newstralloc(dir,ditem->path);
358 if(dir[strlen(dir)-1] == '/')
359 dir[strlen(dir)-1] = '\0'; /* remove last / */
360 /* remove everything before the last / */
361 dir1 = rindex(dir,'/');
364 dir2 = stralloc(dir1);
371 amfree(path_on_disk_slash);
374 set_directory(default_dir);
376 else if(nb_found==1) {
380 printf("Too many directory\n");
390 char *new_dir = NULL;
394 /* do nothing if "." */
395 if(strcmp(dir,".")==0) {
396 show_directory(); /* say where we are */
401 if (disk_name == NULL) {
402 printf("Must select disk before setting directory\n");
407 ldir = stralloc(dir);
408 clean_pathname(ldir);
410 /* convert directory into absolute path relative to disk mount point */
413 /* absolute path specified, must start with mount point */
414 if (strcmp(mount_point, "/") == 0)
416 new_dir = stralloc(ldir);
420 if (strncmp(mount_point, ldir, strlen(mount_point)) != 0)
422 printf("Invalid directory - Can't cd outside mount point \"%s\"\n",
428 new_dir = stralloc(ldir+strlen(mount_point));
429 if (strlen(new_dir) == 0) {
430 new_dir = newstralloc(new_dir, "/");
431 /* i.e. ldir == mount_point */
437 new_dir = stralloc(disk_path);
439 /* strip any leading ..s */
440 while (strncmp(dp, "../", 3) == 0)
442 de = strrchr(new_dir, '/'); /* always at least 1 */
455 if (strcmp(dp, "..") == 0) {
456 if (strcmp(new_dir, "/") == 0) {
458 printf("Invalid directory - Can't cd outside mount point \"%s\"\n",
467 de = strrchr(new_dir, '/'); /* always at least 1 */
479 if (strcmp(new_dir, "/") != 0) {
480 strappend(new_dir, "/");
482 strappend(new_dir, ldir);
487 cmd = stralloc2("OISD ", new_dir);
488 if (exchange(cmd) == -1) {
496 disk_path = newstralloc(disk_path, new_dir);
497 suck_dir_list_from_server(); /* get list of directory contents */
498 show_directory(); /* say where we moved to */
502 printf("Invalid directory - %s\n", dir);
512 /* prints the current working directory */
516 if (mount_point == NULL || disk_path == NULL)
517 printf("Must select disk first\n");
518 else if (strcmp(mount_point, "/") == 0)
519 printf("%s\n", disk_path);
520 else if (strcmp(disk_path, "/") == 0)
521 printf("%s\n", mount_point);
523 printf("%s%s\n", mount_point, disk_path);
527 /* set the tape server and device */
532 char *tapedev = strchr(tape, ':');
536 if (tapedev != tape) {
537 if((strchr(tapedev+1, ':') == NULL) &&
538 (strncmp(tape, "null:", 5) == 0 ||
539 strncmp(tape, "rait:", 5) == 0 ||
540 strncmp(tape, "file:", 5) == 0 ||
541 strncmp(tape, "tape:", 5) == 0)) {
546 tape_server_name = newstralloc(tape_server_name, tape);
549 } else { /* reset server_name if start with : */
550 amfree(tape_server_name);
558 if (strcmp(tapedev, "default") == 0)
559 amfree(tape_device_name);
561 tape_device_name = newstralloc(tape_device_name, tapedev);
564 if (tape_device_name)
565 printf ("Using tape \"%s\"", tape_device_name);
567 printf ("Using default tape");
569 if (tape_server_name)
570 printf (" from server %s.\n", tape_server_name);
572 printf (".\nTape server unspecified, assumed to be %s.\n",
581 if (mode == SAMBA_SMBCLIENT) {
582 printf ("SAMBA dumps will be extracted using smbclient\n");
583 samba_extract_method = SAMBA_SMBCLIENT;
585 if (mode == SAMBA_TAR) {
586 printf ("SAMBA dumps will be extracted as TAR dumps\n");
587 samba_extract_method = SAMBA_TAR;
591 (void)mode; /* Quiet unused parameter warning */
592 #endif /* SAMBA_CLIENT */
599 printf ("SAMBA dumps are extracted ");
601 if (samba_extract_method == SAMBA_TAR) {
602 printf (" as TAR dumps\n");
604 printf ("using smbclient\n");
606 #endif /* SAMBA_CLIENT */