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

📄 amindexd.c

📁 开源备份软件源码 AMANDA, the Advanced Maryland Automatic Network Disk Archiver, is a backup system that a
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * 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: amindexd.c,v 1.106 2006/07/25 18:27:57 martinea Exp $ * * This is the server daemon part of the index client/server system. * It is assumed that this is launched from inetd instead of being * started as a daemon because it is not often used *//*** Notes:** - this server will do very little until it knows what Amanda config it**   is to use.  Setting the config has the side effect of changing to the**   index directory.** - XXX - I'm pretty sure the config directory name should have '/'s stripped**   from it.  It is given to us by an unknown person via the network.*/#include "amanda.h"#include "conffile.h"#include "diskfile.h"#include "arglist.h"#include "clock.h"#include "version.h"#include "amindex.h"#include "disk_history.h"#include "list_dir.h"#include "logfile.h"#include "token.h"#include "find.h"#include "tapefile.h"#include "util.h"#include "amandad.h"#include "pipespawn.h"#include "sockaddr-util.h"#include <grp.h>#define amindexd_debug(i,x) do {	\	if ((i) <= debug_amindexd) {	\	    dbprintf(x);		\	}				\} while (0)typedef struct REMOVE_ITEM{    char *filename;    struct REMOVE_ITEM *next;} REMOVE_ITEM;/* state */static int from_amandad;static char local_hostname[MAX_HOSTNAME_LENGTH+1];	/* me! */static char *dump_hostname = NULL;		/* machine we are restoring */static char *disk_name;				/* disk we are restoring */char *qdisk_name = NULL;			/* disk we are restoring */static char *target_date = NULL;static disklist_t disk_list;			/* all disks in cur config */static find_result_t *output_find = NULL;static g_option_t *g_options = NULL;static int amindexd_debug = 0;static REMOVE_ITEM *uncompress_remove = NULL;					/* uncompressed files to remove */static am_feature_t *our_features = NULL;static am_feature_t *their_features = NULL;static REMOVE_ITEM *remove_files(REMOVE_ITEM *);static char *uncompress_file(char *, char **);static int process_ls_dump(char *, DUMP_ITEM *, int, char **);static size_t reply_buffer_size = 1;static char *reply_buffer = NULL;static char *amandad_auth = NULL;static FILE *cmdin;static FILE *cmdout;static void reply(int, char *, ...) G_GNUC_PRINTF(2, 3);static void lreply(int, char *, ...) G_GNUC_PRINTF(2, 3);static void fast_lreply(int, char *, ...) G_GNUC_PRINTF(2, 3);static am_host_t *is_dump_host_valid(char *);static int is_disk_valid(char *);static int check_and_load_config(char *);static int build_disk_table(void);static int disk_history_list(void);static int is_dir_valid_opaque(char *);static int opaque_ls(char *, int);static void opaque_ls_one (DIR_ITEM *dir_item, am_feature_e marshall_feature,			     int recursive);static int tapedev_is(void);static int are_dumps_compressed(void);static char *amindexd_nicedate (char *datestamp);static int cmp_date (const char *date1, const char *date2);static char *clean_backslash(char *line);static char *get_index_name(char *dump_hostname, char *hostname,			    char *diskname, char *timestamps, int level);static int get_index_dir(char *dump_hostname, char *hostname, char *diskname);int main(int, char **);static REMOVE_ITEM *remove_files(    REMOVE_ITEM *remove){    REMOVE_ITEM *prev;    while(remove) {	dbprintf(_("removing index file: %s\n"), remove->filename);	unlink(remove->filename);	amfree(remove->filename);	prev = remove;	remove = remove->next;	amfree(prev);    }    return remove;}static char *uncompress_file(    char *	filename_gz,    char **	emsg){    char *cmd = NULL;    char *filename = NULL;    struct stat stat_filename;    int result;    size_t len;    int pipe_from_gzip;    int pipe_to_sort;    int indexfd;    int nullfd;    int debugfd;    char line[STR_SIZE];    FILE *pipe_stream;    pid_t pid_gzip;    pid_t pid_sort;    amwait_t  wait_status;    filename = stralloc(filename_gz);    len = strlen(filename);    if(len > 3 && strcmp(&(filename[len-3]),".gz")==0) {	filename[len-3]='\0';    } else if(len > 2 && strcmp(&(filename[len-2]),".Z")==0) {	filename[len-2]='\0';    }    /* uncompress the file */    result=stat(filename,&stat_filename);    if(result==-1 && errno==ENOENT) {		/* file does not exist */	struct stat statbuf;	REMOVE_ITEM *remove_file;	/*	 * Check that compressed file exists manually.	 */	if (stat(filename_gz, &statbuf) < 0) {	    *emsg = newvstrallocf(*emsg,				_("Compressed file '%s' is inaccessable: %s"),				filename_gz, strerror(errno));	    dbprintf("%s\n",*emsg);	    amfree(filename);	    return NULL; 	}#ifdef UNCOMPRESS_OPT#  define PARAM_UNCOMPRESS_OPT UNCOMPRESS_OPT#else#  define PARAM_UNCOMPRESS_OPT skip_argument#endif	nullfd = open("/dev/null", O_RDONLY);	indexfd = open(filename,O_WRONLY|O_CREAT, 0600);	if (indexfd == -1) {	    *emsg = newvstrallocf(*emsg, _("Can't open '%s' for writting: %s"),				 filename, strerror(errno));	    dbprintf("%s\n",*emsg);	    amfree(filename);	    return NULL;	}	/* just use our stderr directly for the pipe's stderr; in 	 * main() we send stderr to the debug file, or /dev/null	 * if debugging is disabled */	debugfd = STDERR_FILENO;	/* start the uncompress process */	putenv(stralloc("LC_ALL=C"));	pid_gzip = pipespawn(UNCOMPRESS_PATH, STDOUT_PIPE,			     &nullfd, &pipe_from_gzip, &debugfd,			     UNCOMPRESS_PATH, PARAM_UNCOMPRESS_OPT,			     filename_gz, NULL);	aclose(nullfd);	pipe_stream = fdopen(pipe_from_gzip,"r");	if(pipe_stream == NULL) {	    *emsg = newvstrallocf(*emsg, _("Can't fdopen pipe from gzip: %s"),				 strerror(errno));	    dbprintf("%s\n",*emsg);	    amfree(filename);	    return NULL;	}	/* start the sort process */	putenv(stralloc("LC_ALL=C"));	pid_sort = pipespawn(SORT_PATH, STDIN_PIPE,			     &pipe_to_sort, &indexfd, &debugfd,			     SORT_PATH, NULL);	aclose(indexfd);	/* send all ouput from uncompress process to sort process */	/* clean the data with clean_backslash */	while (fgets(line, STR_SIZE, pipe_stream) != NULL) {	    if (line[0] != '\0') {		if (index(line,'/')) {		    clean_backslash(line);		    fullwrite(pipe_to_sort,line,strlen(line));		}	    }	}	fclose(pipe_stream);	aclose(pipe_to_sort);	if (waitpid(pid_gzip, &wait_status, 0) < 0) {	    if (!WIFEXITED(wait_status)) {		dbprintf(_("Uncompress exited with signal %d"),			  WTERMSIG(wait_status));	    } else if (WEXITSTATUS(wait_status) != 0) {		dbprintf(_("Uncompress exited with status %d"),			  WEXITSTATUS(wait_status));	    } else {		dbprintf(_("Uncompres returned negative value: %s"),			  strerror(errno));	    }	}	if (waitpid(pid_sort, &wait_status, 0) < 0) {	    if (!WIFEXITED(wait_status)) {		dbprintf(_("Sort exited with signal %d"),			  WTERMSIG(wait_status));	    } else if (WEXITSTATUS(wait_status) != 0) {		dbprintf(_("Sort exited with status %d"),			  WEXITSTATUS(wait_status));	    } else {		dbprintf(_("Sort returned negative value: %s"),			  strerror(errno));	    }	}	/* add at beginning */	remove_file = (REMOVE_ITEM *)alloc(SIZEOF(REMOVE_ITEM));	remove_file->filename = stralloc(filename);	remove_file->next = uncompress_remove;	uncompress_remove = remove_file;    } else if(!S_ISREG((stat_filename.st_mode))) {	    amfree(*emsg);	    *emsg = vstrallocf(_("\"%s\" is not a regular file"), filename);	    errno = -1;	    amfree(filename);	    amfree(cmd);	    return NULL;    }    amfree(cmd);    return filename;}/* find all matching entries in a dump listing *//* return -1 if error */static intprocess_ls_dump(    char *	dir,    DUMP_ITEM *	dump_item,    int		recursive,    char **	emsg){    char line[STR_SIZE];    char *old_line = NULL;    char *filename = NULL;    char *filename_gz;    char *dir_slash = NULL;    FILE *fp;    char *s;    int ch;    size_t len_dir_slash;    if (strcmp(dir, "/") == 0) {	dir_slash = stralloc(dir);    } else {	dir_slash = stralloc2(dir, "/");    }    filename_gz = get_index_name(dump_hostname, dump_item->hostname, disk_name,				 dump_item->date, dump_item->level);    if (filename_gz == NULL) {	*emsg = stralloc(_("index file not found"));	amfree(filename_gz);	return -1;    }    if((filename = uncompress_file(filename_gz, emsg)) == NULL) {	amfree(filename_gz);	amfree(dir_slash);	return -1;    }    amfree(filename_gz);    if((fp = fopen(filename,"r"))==0) {	amfree(*emsg);	*emsg = vstrallocf("%s", strerror(errno));	amfree(dir_slash);	return -1;    }    len_dir_slash=strlen(dir_slash);    while (fgets(line, STR_SIZE, fp) != NULL) {	if (line[0] != '\0') {	    if(line[strlen(line)-1] == '\n')		line[strlen(line)-1] = '\0';	    if(strncmp(dir_slash, line, len_dir_slash) == 0) {		if(!recursive) {		    s = line + len_dir_slash;		    ch = *s++;		    while(ch && ch != '/')			ch = *s++;/* find end of the file name */		    if(ch == '/') {			ch = *s++;		    }		    s[-1] = '\0';		}		if(old_line == NULL || strcmp(line, old_line) != 0) {		    add_dir_list_item(dump_item, line);		    amfree(old_line);		    old_line = stralloc(line);		}	    }	}    }    afclose(fp);    /*@i@*/ amfree(old_line);    amfree(filename);    amfree(dir_slash);    return 0;}/* send a 1 line reply to the client */printf_arglist_function1(static void reply, int, n, char *, fmt){    va_list args;    int len;    if(!reply_buffer)	reply_buffer = alloc(reply_buffer_size);    while(1) {	arglist_start(args, fmt);	len = g_vsnprintf(reply_buffer, reply_buffer_size, fmt, args);	arglist_end(args);	if (len > -1 && (size_t)len < reply_buffer_size-1)	    break;	reply_buffer_size *= 2;	amfree(reply_buffer);	reply_buffer = alloc(reply_buffer_size);    }    if (g_fprintf(cmdout,"%03d %s\r\n", n, reply_buffer) < 0)    {	dbprintf(_("! error %d (%s) in printf\n"), errno, strerror(errno));	uncompress_remove = remove_files(uncompress_remove);	exit(1);    }    if (fflush(cmdout) != 0)    {	dbprintf(_("! error %d (%s) in fflush\n"), errno, strerror(errno));	uncompress_remove = remove_files(uncompress_remove);	exit(1);    }    dbprintf(_("< %03d %s\n"), n, reply_buffer);}/* send one line of a multi-line response */printf_arglist_function1(static void lreply, int, n, char *, fmt){    va_list args;    int len;    if(!reply_buffer)	reply_buffer = alloc(reply_buffer_size);    while(1) {	arglist_start(args, fmt);	len = g_vsnprintf(reply_buffer, reply_buffer_size, fmt, args);	arglist_end(args);	if (len > -1 && (size_t)len < reply_buffer_size-1)	    break;	reply_buffer_size *= 2;	amfree(reply_buffer);	reply_buffer = alloc(reply_buffer_size);    }    if (g_fprintf(cmdout,"%03d-%s\r\n", n, reply_buffer) < 0)    {	dbprintf(_("! error %d (%s) in printf\n"),		  errno, strerror(errno));	uncompress_remove = remove_files(uncompress_remove);	exit(1);    }    if (fflush(cmdout) != 0)    {	dbprintf(_("! error %d (%s) in fflush\n"),		  errno, strerror(errno));

⌨️ 快捷键说明

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