2 * Amanda, The Advanced Maryland Automatic Network Disk Archiver
3 * Copyright (c) 1991-1998 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: display_commands.c,v 1.12.4.1.6.3 2002/10/27 21:13:25 martinea Exp $
29 * implements the directory-display related commands in amrecover
33 #include "amrecover.h"
35 static DIR_ITEM *dir_list = NULL;
37 DIR_ITEM *get_dir_list P((void))
42 DIR_ITEM *get_next_dir_item(this)
49 void clear_dir_list P((void))
58 dir_list = dir_list->next;
60 } while (dir_list != NULL);
63 /* add item to list if path not already on list */
64 static int add_dir_list_item(date, level, tape, fileno, path)
73 dbprintf(("add_dir_list_item: Adding \"%s\" \"%d\" \"%s\" \"%d\" \"%s\"\n",
74 date, level, tape, fileno, path));
78 dir_list = (DIR_ITEM *)alloc(sizeof(DIR_ITEM));
79 dir_list->next = NULL;
80 strncpy(dir_list->date, date, sizeof(dir_list->date)-1);
81 dir_list->date[sizeof(dir_list->date)-1] = '\0';
82 dir_list->level = level;
83 strncpy(dir_list->tape, tape, sizeof(dir_list->tape)-1);
84 dir_list->tape[sizeof(dir_list->tape)-1] = '\0';
85 dir_list->fileno = fileno;
86 strncpy(dir_list->path, path, sizeof(dir_list->path)-1);
87 dir_list->path[sizeof(dir_list->path)-1] = '\0';
93 while (last->next != NULL)
98 last->next = (DIR_ITEM *)alloc(sizeof(DIR_ITEM));
99 last->next->next = NULL;
100 strncpy(last->next->date, date, sizeof(last->next->date)-1);
101 last->next->date[sizeof(last->next->date)-1] = '\0';
102 last->next->level = level;
103 strncpy(last->next->tape, tape, sizeof(last->next->tape)-1);
104 last->next->tape[sizeof(last->next->tape)-1] = '\0';
105 last->next->fileno = fileno;
106 strncpy(last->next->path, path, sizeof(last->next->path)-1);
107 last->next->path[sizeof(last->next->path)-1] = '\0';
113 void list_disk_history P((void))
115 if (converse("DHST") == -1)
120 void suck_dir_list_from_server P((void))
126 char *date, *date_undo, date_undo_ch = '\0';
128 char *tape, *tape_undo, tape_undo_ch = '\0';
129 char *dir, *dir_undo, dir_undo_ch = '\0';
130 char *disk_path_slash = NULL;
131 char *disk_path_slash_dot = NULL;
135 if (disk_path == NULL) {
136 printf("Directory must be set before getting listing\n");
138 } else if(strcmp(disk_path, "/") == 0) {
139 disk_path_slash = stralloc(disk_path);
141 disk_path_slash = stralloc2(disk_path, "/");
146 cmd = stralloc2("OLSD ", disk_path);
147 if (send_command(cmd) == -1) {
149 amfree(disk_path_slash);
154 if ((i = get_reply_line()) == -1) {
155 amfree(disk_path_slash);
158 if (i == 0) /* assume something wrong! */
160 amfree(disk_path_slash);
165 disk_path_slash_dot = stralloc2(disk_path_slash, ".");
168 date_undo = tape_undo = dir_undo = NULL;
169 /* skip the last line -- duplicate of the preamble */
170 while ((i = get_reply_line()) != 0)
173 amfree(disk_path_slash_dot);
174 amfree(disk_path_slash);
179 if(tape_undo) *tape_undo = tape_undo_ch;
180 if(dir_undo) *dir_undo = dir_undo_ch;
181 date_undo = tape_undo = dir_undo = NULL;
182 cmd = stralloc(l); /* save for the error report */
184 continue; /* throw the rest of the lines away */
193 if (strncmp(l, sc, sizeof(sc)-1) != 0) {
194 err = "bad reply: not 201-";
197 s = l + sizeof(sc)-1;
200 skip_whitespace(s, ch);
202 err = "bad reply: missing date field";
206 skip_non_whitespace(s, ch);
208 date_undo_ch = *date_undo;
211 skip_whitespace(s, ch);
212 if(ch == '\0' || sscanf(s - 1, "%d", &level) != 1) {
213 err = "bad reply: cannot parse level field";
218 skip_whitespace(s, ch);
220 err = "bad reply: missing tape field";
224 skip_non_whitespace(s, ch);
226 tape_undo_ch = *tape_undo;
229 if(am_has_feature(their_features, fe_amindexd_fileno_in_OLSD)) {
230 skip_whitespace(s, ch);
231 if(ch == '\0' || sscanf(s - 1, "%d", &fileno) != 1) {
232 err = "bad reply: cannot parse fileno field";
241 skip_whitespace(s, ch);
243 err = "bad reply: missing directory field";
248 /* add a '.' if it a the entry for the current directory */
249 if(strcmp(disk_path,dir)==0 || strcmp(disk_path_slash,dir)==0) {
250 dir = disk_path_slash_dot;
252 add_dir_list_item(date, level, tape, fileno, dir);
254 amfree(disk_path_slash_dot);
255 amfree(disk_path_slash);
256 if(!server_happy()) {
269 void list_directory P((void))
277 if (disk_path == NULL) {
278 printf("Must select a disk before listing files\n");
282 if ((pager = getenv("PAGER")) == NULL)
287 * Set up the pager command so if the pager is terminated, we do
288 * not get a SIGPIPE back.
290 pager_command = stralloc2(pager, " ; /bin/cat > /dev/null");
291 if ((fp = popen(pager_command, "w")) == NULL)
293 printf("Warning - can't pipe through %s\n", pager);
296 amfree(pager_command);
297 i = strlen(disk_path);
299 i++; /* so disk_path != "/" */
300 for (item = get_dir_list(); item != NULL; item=get_next_dir_item(item))
301 fprintf(fp, "%s %s\n", item->date, item->path+i);