📄 amrestore.c
字号:
/* * Amanda, The Advanced Maryland Automatic Network Disk Archiver * Copyright (c) 1991-1998 University of Maryland at College Park * All Rights Reserved. * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of U.M. not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. U.M. makes no representations about the * suitability of this software for any purpose. It is provided "as is" * without express or implied warranty. * * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M. * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Authors: the Amanda Development Team. Its members are listed in a * file named AUTHORS, in the root directory of this distribution. *//* * $Id: amrestore.c 6512 2007-05-24 17:00:24Z ian $ * * retrieves files from an amanda tape *//* * Pulls all files from the tape that match the hostname, diskname and * datestamp regular expressions. * * If the header is output, only up to DISK_BLOCK_BYTES worth of it is * sent, regardless of the tape blocksize. This makes the disk image * look like a holding disk image, and also makes it easier to remove * the header (e.g. in amrecover) since it has a fixed size. */#include "amanda.h"#include "util.h"#include "fileheader.h"#include "restore.h"#include "conffile.h"#include "device.h"#include "cmdline.h"#define CREAT_MODE 0640/* * Print usage message and terminate. */static voidusage(void){ error(_("Usage: amrestore [-b blocksize] [-r|-c] [-p] [-h] [-f fileno] " "[-l label] tape-device|holdingfile [hostname [diskname [datestamp " "[hostname [diskname [datestamp ... ]]]]]]")); /*NOTREACHED*/}/* Checks if the given tape device is actually a holding disk file. We accomplish this by stat()ing the file; if it is a regular file, we assume (somewhat dangerously) that it's a holding disk file. If it doesn't exist or is not a regular file, we assume it's a device name. Returns TRUE if we suspect the device is a holding disk, FALSE otherwise. */static gboolean check_device_type(char * device_name) { struct stat stat_buf; int result; result = stat(device_name, &stat_buf); return !((result != 0 || !S_ISREG(stat_buf.st_mode)));}static void handle_holding_disk_restore(char * filename, rst_flags_t * flags, GSList * dumpspecs) { dumpfile_t this_header; tapelist_t this_disk; bzero(&this_disk, sizeof(this_disk)); this_disk.label = filename; if (!restore_holding_disk(stderr, flags, NULL, &this_disk, NULL, dumpspecs, &this_header, NULL)) { g_fprintf(stderr, "%s did not match requested host.\n", filename); return; }}static void handle_tape_restore(char * device_name, rst_flags_t * flags, GSList * dumpspecs, char * check_label) { Device * device; ReadLabelStatusFlags read_label_status; dumpfile_t first_restored_file; device_api_init(); fh_init(&first_restored_file); device = device_open(device_name); if (device == NULL) { error("Could not open device.\n"); } device_set_startup_properties_from_config(device); read_label_status = device_read_label(device); if (read_label_status != READ_LABEL_STATUS_SUCCESS) { char * errstr = g_english_strjoinv_and_free (g_flags_nick_to_strv(read_label_status, READ_LABEL_STATUS_FLAGS_TYPE), "or"); error("Error reading volume label: %s.\n", errstr); } g_assert(device->volume_label != NULL); if (!device_start(device, ACCESS_READ, NULL, NULL)) { error("Could not open device %s for reading.\n", device_name); } if (check_label != NULL && strcmp(check_label, device->volume_label) != 0) { error("Wrong label: Expected %s, found %s.\n", check_label, device->volume_label); } search_a_tape(device, stderr, flags, NULL, NULL, dumpspecs, NULL, &first_restored_file, 0, NULL);}/* * Parses command line, then loops through all files on tape, restoring * files that match the command line criteria. */intmain( int argc, char ** argv){ extern int optind; int opt; int holding_disk_mode; char *tapename = NULL; char *e; char *label = NULL; rst_flags_t *rst_flags; long tmplong; GSList *dumpspecs; config_overwrites_t *cfg_ovr; /* * Configure program for internationalization: * 1) Only set the message locale for now. * 2) Set textdomain for all amanda related programs to "amanda" * We don't want to be forced to support dozens of message catalogs. */ setlocale(LC_MESSAGES, "C"); textdomain("amanda"); safe_fd(-1, 0); set_pname("amrestore"); dbopen(DBG_SUBDIR_SERVER); /* Don't die when child closes pipe */ signal(SIGPIPE, SIG_IGN); erroutput_type = ERR_INTERACTIVE; error_exit_status = 2; rst_flags = new_rst_flags(); rst_flags->inline_assemble = 0; cfg_ovr = new_config_overwrites(argc/2); /* handle options */ while( (opt = getopt(argc, argv, "b:cCd:rphf:l:o:")) != -1) { switch(opt) { case 'b': tmplong = strtol(optarg, &e, 10); rst_flags->blocksize = (ssize_t)tmplong; if(*e == 'k' || *e == 'K') { rst_flags->blocksize *= 1024; } else if(*e == 'm' || *e == 'M') { rst_flags->blocksize *= 1024 * 1024; } else if(*e != '\0') { error(_("invalid blocksize value \"%s\""), optarg); /*NOTREACHED*/ } if(rst_flags->blocksize < DISK_BLOCK_BYTES) { error(_("minimum block size is %dk"), DISK_BLOCK_BYTES / 1024); /*NOTREACHED*/ } break; case 'c': rst_flags->compress = 1; break; case 'o': add_config_overwrite_opt(cfg_ovr, optarg); break; case 'C': rst_flags->compress = 1; rst_flags->comp_type = COMPRESS_BEST_OPT; break; case 'r': rst_flags->raw = 1; break; case 'p': rst_flags->pipe_to_fd = fileno(stdout); break; case 'h': rst_flags->headers = 1; break; case 'f': rst_flags->fsf = (off_t)OFF_T_STRTOL(optarg, &e, 10); /*@ignore@*/ if(*e != '\0') { error(_("invalid fileno value \"%s\""), optarg); g_assert_not_reached(); } /*@end@*/ break; case 'l': label = stralloc(optarg); break; default: usage(); } } /* initialize a generic configuration without reading anything */ config_init(CONFIG_INIT_CLIENT, NULL); apply_config_overwrites(cfg_ovr); if(rst_flags->compress && rst_flags->raw) { g_fprintf(stderr, _("Cannot specify both -r (raw) and -c (compressed) output.\n")); usage(); } if(optind >= argc) { g_fprintf(stderr, _("%s: Must specify tape-device or holdingfile\n"), get_pname()); usage(); } tapename = argv[optind++]; dumpspecs = cmdline_parse_dumpspecs(argc - optind, argv + optind, CMDLINE_PARSE_DATESTAMP | CMDLINE_EMPTY_TO_WILDCARD); holding_disk_mode = check_device_type(tapename); if (holding_disk_mode) { if (label) { g_fprintf(stderr,_("%s: ignoring -l flag when restoring from a file.\n"), get_pname()); } if (rst_flags->fsf > 0) { g_fprintf(stderr, "%s: ignoring -f flag when restoring from a file.\n", get_pname()); } handle_holding_disk_restore(tapename, rst_flags, dumpspecs); } else { handle_tape_restore(tapename, rst_flags, dumpspecs, label); } dumpspec_list_free(dumpspecs); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -