⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 extract_list.c

📁 开源备份软件源码 AMANDA, the Advanced Maryland Automatic Network Disk Archiver, is a backup system that a
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * 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: extract_list.c,v 1.117 2006/08/24 01:57:15 paddy_s Exp $ * * implements the "extract" command in amrecover */#include "amanda.h"#include "version.h"#include "amrecover.h"#include "fileheader.h"#include "dgram.h"#include "stream.h"#include "tapelist.h"#ifdef SAMBA_CLIENT#include "findpass.h"#endif#include "util.h"#include "conffile.h"#include "protocol.h"#include "event.h"#include "security.h"typedef struct EXTRACT_LIST_ITEM {    char *path;    struct EXTRACT_LIST_ITEM *next;}EXTRACT_LIST_ITEM;typedef struct EXTRACT_LIST {    char *date;			/* date tape created */    int  level;			/* level of dump */    char *tape;			/* tape label */    off_t fileno;		/* fileno on tape */    EXTRACT_LIST_ITEM *files;	/* files to get off tape */    struct EXTRACT_LIST *next;}EXTRACT_LIST;#define SKIP_TAPE 2#define RETRY_TAPE 3static struct {    const char *name;    security_stream_t *fd;} amidxtaped_streams[] = {#define CTLFD  0    { "CTL", NULL },#define DATAFD  1    { "DATA", NULL },};#define NSTREAMS  (int)(sizeof(amidxtaped_streams) / sizeof(amidxtaped_streams[0]))static void amidxtaped_response(void *, pkt_t *, security_handle_t *);static void stop_amidxtaped(void);char *amidxtaped_client_get_security_conf(char *, void *);static char *dump_device_name = NULL;static char *errstr;static char *amidxtaped_line = NULL;extern char *localhost;/* global pid storage for interrupt handler */pid_t extract_restore_child_pid = -1;static EXTRACT_LIST *extract_list = NULL;static const security_driver_t *amidxtaped_secdrv;#ifdef SAMBA_CLIENTunsigned short samba_extract_method = SAMBA_TAR;#endif /* SAMBA_CLIENT */#define READ_TIMEOUT	240*60EXTRACT_LIST *first_tape_list(void);EXTRACT_LIST *next_tape_list(EXTRACT_LIST *list);static int is_empty_dir(char *fname);int is_extract_list_nonempty(void);int length_of_tape_list(EXTRACT_LIST *tape_list);void add_file(char *path, char *regex);void add_glob(char *glob);void add_regex(char *regex);void clear_extract_list(void);void clean_tape_list(EXTRACT_LIST *tape_list);void clean_extract_list(void);void check_file_overwrite(char *filename);void delete_file(char *path, char *regex);void delete_glob(char *glob);void delete_regex(char *regex);void delete_tape_list(EXTRACT_LIST *tape_list);void display_extract_list(char *file);void extract_files(void);void read_file_header(char *buffer,			dumpfile_t *file,			size_t buflen,			int tapedev);static int add_extract_item(DIR_ITEM *ditem);static int delete_extract_item(DIR_ITEM *ditem);static int extract_files_setup(char *label, off_t fsf);static int okay_to_continue(int allow_tape,			int allow_skip,			int allow_retry);static ssize_t read_buffer(int datafd,			char *buffer,			size_t buflen,			long timeout_s);static void clear_tape_list(EXTRACT_LIST *tape_list);static void extract_files_child(int in_fd, EXTRACT_LIST *elist);static void send_to_tape_server(security_stream_t *stream, char *cmd);int writer_intermediary(EXTRACT_LIST *elist);int get_amidxtaped_line(void);static void read_amidxtaped_data(void *, void *, ssize_t);/* * Function:  ssize_t read_buffer(datafd, buffer, buflen, timeout_s) * * Description: *	read data from input file desciptor waiting up to timeout_s *	seconds before returning data. * * Inputs: *	datafd    - File descriptor to read from. *	buffer    - Buffer to read into. *	buflen    - Maximum number of bytes to read into buffer. *	timeout_s - Seconds to wait before returning what was already read. * * Returns: *      >0	  - Number of data bytes in buffer. *       0	  - EOF *      -1        - errno == ETIMEDOUT if no data available in specified time. *                  errno == ENFILE if datafd is invalid. *                  otherwise errno is set by select or read.. */static ssize_tread_buffer(    int		datafd,    char *	buffer,    size_t	buflen,    long	timeout_s){    ssize_t size = 0;    SELECT_ARG_TYPE readset;    struct timeval timeout;    char *dataptr;    ssize_t spaceleft;    int nfound;    if(datafd < 0 || datafd >= (int)FD_SETSIZE) {	errno = EMFILE;					/* out of range */	return -1;    }    dataptr = buffer;    spaceleft = (ssize_t)buflen;    do {        FD_ZERO(&readset);        FD_SET(datafd, &readset);        timeout.tv_sec = timeout_s;        timeout.tv_usec = 0;        nfound = select(datafd+1, &readset, NULL, NULL, &timeout);        if(nfound < 0 ) {            /* Select returned an error. */	    g_fprintf(stderr,_("select error: %s\n"), strerror(errno));            size = -1;	    break;        }	if (nfound == 0) {            /* Select timed out. */            if (timeout_s != 0)  {                /* Not polling: a real read timeout */                g_fprintf(stderr,_("timeout waiting for restore\n"));                g_fprintf(stderr,_("increase READ_TIMEOUT in recover-src/extract_list.c if your tape is slow\n"));            }            errno = ETIMEDOUT;            size = -1;	    break;        }	if(!FD_ISSET(datafd, &readset))	    continue;        /* Select says data is available, so read it.  */        size = read(datafd, dataptr, (size_t)spaceleft);        if (size < 0) {	    if ((errno == EINTR) || (errno == EAGAIN)) {		continue;	    }	    if (errno != EPIPE) {	        g_fprintf(stderr, _("read_buffer: read error - %s"),		    strerror(errno));	        break;	    }	    size = 0;	}        spaceleft -= size;        dataptr += size;    } while ((size > 0) && (spaceleft > 0));    return ((((ssize_t)buflen-spaceleft) > 0) ? ((ssize_t)buflen-spaceleft) : size);}EXTRACT_LIST *first_tape_list(void){    return extract_list;}EXTRACT_LIST *next_tape_list(    /*@keep@*/EXTRACT_LIST *list){    if (list == NULL)	return NULL;    return list->next;}static voidclear_tape_list(    EXTRACT_LIST *	tape_list){    EXTRACT_LIST_ITEM *this, *next;        this = tape_list->files;    while (this != NULL)    {	next = this->next;        amfree(this->path);        amfree(this);	this = next;    }    tape_list->files = NULL;}/* remove a tape list from the extract list, clearing the tape list   beforehand if necessary */voiddelete_tape_list(    EXTRACT_LIST *tape_list){    EXTRACT_LIST *this, *prev;    if (tape_list == NULL)        return;    /* is it first on the list? */    if (tape_list == extract_list)    {	extract_list = tape_list->next;	clear_tape_list(tape_list);        amfree(tape_list->date);        amfree(tape_list->tape);	amfree(tape_list);	return;    }    /* so not first on list - find it and delete */    prev = extract_list;    this = extract_list->next;    while (this != NULL)    {	if (this == tape_list)	{	    prev->next = tape_list->next;	    clear_tape_list(tape_list);            amfree(tape_list->date);            amfree(tape_list->tape);	    amfree(tape_list);	    return;	}	prev = this;	this = this->next;    }    /*NOTREACHED*/}/* return the number of files on a tape's list */intlength_of_tape_list(    EXTRACT_LIST *tape_list){    EXTRACT_LIST_ITEM *fn;    int n;    n = 0;    for (fn = tape_list->files; fn != NULL; fn = fn->next)	n++;    return n;}voidclear_extract_list(void){    while (extract_list != NULL)	delete_tape_list(extract_list);}voidclean_tape_list(    EXTRACT_LIST *tape_list){    EXTRACT_LIST_ITEM *fn1, *pfn1, *ofn1;    EXTRACT_LIST_ITEM *fn2, *pfn2, *ofn2;    int remove_fn1;    int remove_fn2;    pfn1 = NULL;    fn1 = tape_list->files;    while (fn1 != NULL) {	remove_fn1 = 0;	pfn2 = fn1;	fn2 = fn1->next;	while (fn2 != NULL && remove_fn1 == 0) {	    remove_fn2 = 0;	    if(strcmp(fn1->path, fn2->path) == 0) {		remove_fn2 = 1;	    } else if (strncmp(fn1->path, fn2->path, strlen(fn1->path)) == 0 &&		       ((strlen(fn2->path) > strlen(fn1->path) &&			 fn2->path[strlen(fn1->path)] == '/') ||		       (fn1->path[strlen(fn1->path)-1] == '/'))) {		remove_fn2 = 1;	    } else if (strncmp(fn2->path, fn1->path, strlen(fn2->path)) == 0 &&		       ((strlen(fn1->path) > strlen(fn2->path) &&			 fn1->path[strlen(fn2->path)] == '/')  ||		       (fn2->path[strlen(fn2->path)-1] == '/'))) {		remove_fn1 = 1;		break;	    }	    if (remove_fn2) {		dbprintf(_("removing path %s, it is included in %s\n"),			  fn2->path, fn1->path);		ofn2 = fn2;		fn2 = fn2->next;		amfree(ofn2->path);		amfree(ofn2);		pfn2->next = fn2;	    } else if (remove_fn1 == 0) {		pfn2 = fn2;		fn2 = fn2->next;	    }	}	if(remove_fn1 != 0) {	    /* fn2->path is always valid */	    /*@i@*/ dbprintf(_("removing path %s, it is included in %s\n"),	    /*@i@*/	      fn1->path, fn2->path);	    ofn1 = fn1;	    fn1 = fn1->next;	    amfree(ofn1->path);	    if(pfn1 == NULL) {		amfree(tape_list->files);		tape_list->files = fn1;	    } else {		amfree(pfn1->next);		pfn1->next = fn1;	    }	} else {	    pfn1 = fn1;	    fn1 = fn1->next;	}    }}voidclean_extract_list(void){    EXTRACT_LIST *this;    for (this = extract_list; this != NULL; this = this->next)	clean_tape_list(this);}int add_to_unlink_list(char *path);int do_unlink_list(void);void free_unlink_list(void);typedef struct s_unlink_list {    char *path;    struct s_unlink_list *next;} t_unlink_list;t_unlink_list *unlink_list = NULL;intadd_to_unlink_list(    char *path){    t_unlink_list *ul;    if (!unlink_list) {	unlink_list = alloc(SIZEOF(*unlink_list));	unlink_list->path = stralloc(path);	unlink_list->next = NULL;    } else {	for (ul = unlink_list; ul != NULL; ul = ul->next) {	    if (strcmp(ul->path, path) == 0)		return 0;	}	ul = alloc(SIZEOF(*ul));	ul->path = stralloc(path);	ul->next = unlink_list;	unlink_list = ul;    }    return 1;}intdo_unlink_list(void){    t_unlink_list *ul;    int ret = 1;    for (ul = unlink_list; ul != NULL; ul = ul->next) {	if (unlink(ul->path) < 0) {	    g_fprintf(stderr,_("Can't unlink %s: %s\n"), ul->path, strerror(errno));	    ret = 0;	}    }    return ret;}voidfree_unlink_list(void){    t_unlink_list *ul, *ul1;    for (ul = unlink_list; ul != NULL; ul = ul1) {	amfree(ul->path);	ul1 = ul->next;	amfree(ul);    }    unlink_list = NULL;}voidcheck_file_overwrite(    char *dir){    EXTRACT_LIST      *this;    EXTRACT_LIST_ITEM *fn;    struct stat        stat_buf;    char              *filename;    char              *path, *s;    for (this = extract_list; this != NULL; this = this->next) {	for (fn = this->files; fn != NULL ; fn = fn->next) {	    /* Check path component of fn->path */	    path = stralloc2(dir, fn->path);	    if (path[strlen(path)-1] == '/') {		path[strlen(path)-1] = '\0';	    }	    s = path + strlen(dir) + 1;	    while((s = strchr(s, '/'))) {		*s = '\0';		if (lstat(path, &stat_buf) == 0) {		    if(!S_ISDIR(stat_buf.st_mode)) {			if (add_to_unlink_list(path)) {			    g_printf(_("WARNING: %s is not a directory, "				   "it will be deleted.\n"),				   path);			}		    }		}		else if (errno != ENOENT) {		    g_printf(_("Can't stat %s: %s\n"), path, strerror(errno));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -