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.22 2006/07/05 19:42:17 martinea Exp $
29 * implements the directory-display related commands in amrecover
33 #include "amrecover.h"
36 gboolean translate_mode = TRUE;
38 DIR_ITEM *get_dir_list(void);
39 DIR_ITEM *get_next_dir_item(DIR_ITEM *this);
41 void clear_dir_list(void);
42 void free_dir_item(DIR_ITEM *item);
43 static int add_dir_list_item(char *date,
48 void list_disk_history(void);
49 void suck_dir_list_from_server(void);
50 void list_directory(void);
52 static DIR_ITEM *dir_list = NULL;
73 free_dir_item(dir_list); /* Frees all items from dir_list to end of list */
83 while (item != NULL) {
94 /* add item to list if path not already on list */
105 dbprintf(_("add_dir_list_item: Adding \"%s\" \"%d\" \"%s\" \"%lld\" \"%s\"\n"),
106 date, level, tape, (long long)fileno, path);
108 next = (DIR_ITEM *)alloc(sizeof(DIR_ITEM));
109 memset(next, 0, sizeof(DIR_ITEM));
111 next->date = stralloc(date);
113 next->tape = stralloc(tape);
114 next->fileno = fileno;
115 next->path = stralloc(path);
116 next->tpath = translate_octal(g_strdup(path));
118 next->next = dir_list;
126 list_disk_history(void)
128 if (converse("DHST") == -1)
134 suck_dir_list_from_server(void)
142 off_t fileno = (off_t)-1;
143 char *tape, *tape_undo, tape_undo_ch = '\0';
145 char *disk_path_slash = NULL;
146 char *disk_path_slash_dot = NULL;
151 if (disk_path == NULL) {
152 g_printf(_("Directory must be set before getting listing\n"));
154 } else if(strcmp(disk_path, "/") == 0) {
155 disk_path_slash = stralloc(disk_path);
157 disk_path_slash = stralloc2(disk_path, "/");
162 qdisk_path = quote_string(disk_path);
163 cmd = stralloc2("OLSD ", qdisk_path);
165 if (send_command(cmd) == -1) {
167 amfree(disk_path_slash);
172 if ((i = get_reply_line()) == -1) {
173 amfree(disk_path_slash);
176 if (i == 0) /* assume something wrong! */
178 amfree(disk_path_slash);
183 disk_path_slash_dot = stralloc2(disk_path_slash, ".");
187 /* skip the last line -- duplicate of the preamble */
188 while ((i = get_reply_line()) != 0)
191 amfree(disk_path_slash_dot);
192 amfree(disk_path_slash);
197 if(tape_undo) *tape_undo = tape_undo_ch;
199 cmd = stralloc(l); /* save for the error report */
201 continue; /* throw the rest of the lines away */
210 if (strncmp_const_skip(l, "201-", s, ch) != 0) {
211 err = _("bad reply: not 201-");
215 skip_whitespace(s, ch);
217 err = _("bad reply: missing date field");
221 skip_non_whitespace(s, ch);
224 skip_whitespace(s, ch);
225 if(ch == '\0' || sscanf(s - 1, "%d", &level) != 1) {
226 err = _("bad reply: cannot parse level field");
231 skip_whitespace(s, ch);
233 err = _("bad reply: missing tape field");
237 skip_quoted_string(s, ch);
239 tape_undo_ch = *tape_undo;
241 tape = unquote_string(tape);
243 if(am_has_feature(indexsrv_features, fe_amindexd_fileno_in_OLSD)) {
244 long long fileno_ = (long long)0;
245 skip_whitespace(s, ch);
246 if(ch == '\0' || sscanf(s - 1, "%lld", &fileno_) != 1) {
247 err = _("bad reply: cannot parse fileno field");
250 fileno = (off_t)fileno_;
257 skip_whitespace(s, ch);
259 err = _("bad reply: missing directory field");
263 dir = unquote_string(qdir);
265 /* add a '.' if it a the entry for the current directory */
266 if((strcmp(disk_path,dir)==0) || (strcmp(disk_path_slash,dir)==0)) {
268 dir = stralloc(disk_path_slash_dot);
270 add_dir_list_item(date, level, tape, fileno, dir);
274 amfree(disk_path_slash_dot);
275 amfree(disk_path_slash);
276 if(!server_happy()) {
300 if (disk_path == NULL) {
301 g_printf(_("Must select a disk before listing files; use the setdisk command.\n"));
305 if ((pager = getenv("PAGER")) == NULL)
310 * Set up the pager command so if the pager is terminated, we do
311 * not get a SIGPIPE back.
313 pager_command = stralloc2(pager, " ; /bin/cat > /dev/null");
314 if ((fp = popen(pager_command, "w")) == NULL)
316 g_printf(_("Warning - can't pipe through %s\n"), pager);
319 amfree(pager_command);
320 i = strlen(disk_tpath);
322 i++; /* so disk_tpath != "/" */
323 for (item = get_dir_list(); item != NULL; item=get_next_dir_item(item)) {
324 quoted = quote_string(item->tpath + i);
325 g_fprintf(fp, "%s %s\n", item->date, quoted);