📄 amrecover.c
字号:
/* * Amanda, The Advanced Maryland Automatic Network Disk Archiver * Copyright (c) 1991-1998, 2000 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: amrecover.c,v 1.7 2006/07/25 18:27:57 martinea Exp $ * * an interactive program for recovering backed-up files */#include "amanda.h"#include "version.h"#include "stream.h"#include "amfeatures.h"#include "amrecover.h"#include "getfsent.h"#include "dgram.h"#include "util.h"#include "conffile.h"extern int process_line(char *line);int guess_disk(char *cwd, size_t cwd_len, char **dn_guess, char **mpt_guess);int get_line(void);int grab_reply(int show);void sigint_handler(int signum);int main(int argc, char **argv);#define USAGE _("Usage: amoldrecover [[-C] <config>] [-s <index-server>] [-t <tape-server>] [-d <tape-device>]\n")char *config = NULL;char *server_name = NULL;int server_socket;char *server_line = NULL;char *dump_datestamp = NULL; /* date we are restoring */char *dump_hostname; /* which machine we are restoring */char *disk_name = NULL; /* disk we are restoring */char *mount_point = NULL; /* where disk was mounted */char *disk_path = NULL; /* path relative to mount point */char dump_date[STR_SIZE]; /* date on which we are restoring */int quit_prog; /* set when time to exit parser */char *tape_server_name = NULL;int tape_server_socket;char *tape_device_name = NULL;am_feature_t *our_features = NULL;am_feature_t *indexsrv_features = NULL;am_feature_t *tapesrv_features = NULL;/* gets a "line" from server and put in server_line *//* server_line is terminated with \0, \r\n is striped *//* returns -1 if error */intget_line(void){ char *line = NULL; char *part = NULL; size_t len; while(1) { if((part = areads(server_socket)) == NULL) { int save_errno = errno; if(server_line) { fputs(server_line, stderr); /* show the last line read */ fputc('\n', stderr); } if(save_errno != 0) { g_fprintf(stderr, _("%s: Error reading line from server: %s\n"), get_pname(), strerror(save_errno)); } else { g_fprintf(stderr, _("%s: Unexpected end of file, check amindexd*debug on server %s\n"), get_pname(), server_name); } errno = save_errno; break; /* exit while loop */ } if(line) { strappend(line, part); amfree(part); } else { line = part; part = NULL; } if((len = strlen(line)) > 0 && line[len-1] == '\r') { line[len-1] = '\0'; server_line = newstralloc(server_line, line); amfree(line); return 0; } /* * Hmmm. We got a "line" from areads(), which means it saw * a '\n' (or EOF, etc), but there was not a '\r' before it. * Put a '\n' back in the buffer and loop for more. */ strappend(line, "\n"); } amfree(line); amfree(server_line); return -1;}/* get reply from server and print to screen *//* handle multi-line reply *//* return -1 if error *//* return code returned by server always occupies first 3 bytes of global variable server_line */intgrab_reply( int show){ do { if (get_line() == -1) { return -1; } if(show) puts(server_line); } while (server_line[3] == '-'); if(show) fflush(stdout); return 0;}/* get 1 line of reply *//* returns -1 if error, 0 if last (or only) line, 1 if more to follow */intget_reply_line(void){ if (get_line() == -1) return -1; return server_line[3] == '-';}/* returns pointer to returned line */char *reply_line(void){ return server_line;}/* returns 0 if server returned an error code (ie code starting with 5) and non-zero otherwise */intserver_happy(void){ return server_line[0] != '5';}intsend_command( char * cmd){ /* * NOTE: this routine is called from sigint_handler, so we must be * **very** careful about what we do since there is no way to know * our state at the time the interrupt happened. For instance, * do not use any stdio or malloc routines here. */ struct iovec msg[2]; ssize_t bytes; memset(msg, 0, sizeof(msg)); msg[0].iov_base = cmd; msg[0].iov_len = strlen(msg[0].iov_base); msg[1].iov_base = "\r\n"; msg[1].iov_len = strlen(msg[1].iov_base); bytes = (ssize_t)(msg[0].iov_len + msg[1].iov_len); if (writev(server_socket, msg, 2) < bytes) { return -1; } return (0);}/* send a command to the server, get reply and print to screen */intconverse( char * cmd){ if (send_command(cmd) == -1) return -1; if (grab_reply(1) == -1) return -1; return 0;}/* same as converse() but reply not echoed to stdout */intexchange( char * cmd){ if (send_command(cmd) == -1) return -1; if (grab_reply(0) == -1) return -1; return 0;}/* basic interrupt handler for when user presses ^C *//* Bale out, letting server know before doing so */voidsigint_handler( int signum){ /* * NOTE: we must be **very** careful about what we do here since there * is no way to know our state at the time the interrupt happened. * For instance, do not use any stdio routines here or in any called * routines. Also, use _exit() instead of exit() to make sure stdio * buffer flushing is not attempted. */ (void)signum; /* Quiet unused parameter warning */ if (extract_restore_child_pid != -1) (void)kill(extract_restore_child_pid, SIGKILL); extract_restore_child_pid = -1; (void)send_command("QUIT"); _exit(1);}voidclean_pathname( char * s){ size_t length; length = strlen(s); /* remove "/" at end of path */ if(length>1 && s[length-1]=='/') s[length-1]='\0'; /* change "/." to "/" */ if(strcmp(s,"/.")==0) s[1]='\0'; /* remove "/." at end of path */ if(strcmp(&(s[length-2]),"/.")==0) s[length-2]='\0';}/* try and guess the disk the user is currently on. Return -1 if error, 0 if disk not local, 1 if disk local, 2 if disk local but can't guess name *//* do this by looking for the longest mount point which matches the current directory */intguess_disk ( char * cwd, size_t cwd_len, char ** dn_guess, char ** mpt_guess){ size_t longest_match = 0; size_t current_length; size_t cwd_length; int local_disk = 0; generic_fsent_t fsent; char *fsname = NULL; char *disk_try = NULL; *dn_guess = NULL; *mpt_guess = NULL; if (getcwd(cwd, cwd_len) == NULL) { return -1; /*NOTREACHED*/ } cwd_length = strlen(cwd); dbprintf(_("guess_disk: %zu: \"%s\"\n"), cwd_length, cwd); if (open_fstab() == 0) { return -1; /*NOTREACHED*/ } while (get_fstab_nextentry(&fsent)) { current_length = fsent.mntdir ? strlen(fsent.mntdir) : (size_t)0; dbprintf(_("guess_disk: %zu: %zu: \"%s\": \"%s\"\n"), longest_match, current_length, fsent.mntdir ? fsent.mntdir : _("(mntdir null)"), fsent.fsname ? fsent.fsname : _("(fsname null)")); if ((current_length > longest_match) && (current_length <= cwd_length) && (strncmp(fsent.mntdir, cwd, current_length) == 0)) { longest_match = current_length; *mpt_guess = newstralloc(*mpt_guess, fsent.mntdir); if(strncmp(fsent.fsname,DEV_PREFIX,(strlen(DEV_PREFIX)))) { fsname = newstralloc(fsname, fsent.fsname); } else { fsname = newstralloc(fsname,fsent.fsname+strlen(DEV_PREFIX)); } local_disk = is_local_fstype(&fsent); dbprintf(_("guess_disk: local_disk = %d, fsname = \"%s\"\n"), local_disk, fsname); } } close_fstab(); if (longest_match == 0) { amfree(*mpt_guess); amfree(fsname); return -1; /* ? at least / should match */ } if (!local_disk) { amfree(*mpt_guess); amfree(fsname); return 0; } /* have mount point now */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -