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

📄 sendsize.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: sendsize.c,v 1.171 2006/08/24 01:57:15 paddy_s Exp $ * * send estimated backup sizes using dump */#include "amanda.h"#include "pipespawn.h"#include "amfeatures.h"#include "amandates.h"#include "clock.h"#include "util.h"#include "getfsent.h"#include "version.h"#include "client_util.h"#include "conffile.h"#include "amandad.h"#ifdef SAMBA_CLIENT#include "findpass.h"#endif#define sendsize_debug(i, ...) do {	\	if ((i) <= debug_sebdsize) {	\	    dbprintf(__VA_ARGS__);	\	}				\} while (0)#ifdef HAVE_SETPGID#  define SETPGRP	setpgid(getpid(), getpid())#  define SETPGRP_FAILED() do {						\    dbprintf(_("setpgid(%ld,%ld) failed: %s\n"),				\	      (long)getpid(), (long)getpid(), strerror(errno));	\} while(0)#else /* () line 0 */#if defined(SETPGRP_VOID)#  define SETPGRP	setpgrp()#  define SETPGRP_FAILED() do {						\    dbprintf(_("setpgrp() failed: %s\n"), strerror(errno));		\} while(0)#else#  define SETPGRP	setpgrp(0, getpid())#  define SETPGRP_FAILED() do {						\    dbprintf(_("setpgrp(0,%ld) failed: %s\n"),				\	      (long)getpid(), strerror(errno));			\} while(0)#endif#endiftypedef struct level_estimates_s {    time_t dumpsince;    int estsize;    int needestimate;} level_estimate_t;typedef struct disk_estimates_s {    struct disk_estimates_s *next;    char *amname;    char *qamname;    char *amdevice;    char *qamdevice;    char *dirname;    char *qdirname;    char *program;    char *calcprog;    int program_is_backup_api;    int spindle;    pid_t child;    int done;    option_t *options;    level_estimate_t est[DUMP_LEVELS];} disk_estimates_t;disk_estimates_t *est_list;static am_feature_t *our_features = NULL;static char *our_feature_string = NULL;static g_option_t *g_options = NULL;/* local functions */int main(int argc, char **argv);void add_diskest(char *disk, char *amdevice, int level, int spindle, 		    int program_is_backup_api, char *prog, char *calcprog,		    option_t *options);void calc_estimates(disk_estimates_t *est);void free_estimates(disk_estimates_t *est);void dump_calc_estimates(disk_estimates_t *);void star_calc_estimates(disk_estimates_t *);void smbtar_calc_estimates(disk_estimates_t *);void gnutar_calc_estimates(disk_estimates_t *);void backup_api_calc_estimate(disk_estimates_t *);void generic_calc_estimates(disk_estimates_t *);intmain(    int		argc,    char **	argv){    int level, spindle;    char *prog, *calcprog, *dumpdate;    option_t *options = NULL;    int program_is_backup_api;    disk_estimates_t *est;    disk_estimates_t *est1;    disk_estimates_t *est_prev;    char *line = NULL;    char *s, *fp;    int ch;    char *err_extra = NULL;    int done;    int need_wait;    int dumpsrunning;    char *disk = NULL;    char *qdisk = NULL;    char *qlist = NULL;    char *amdevice = NULL;    char *qamdevice = NULL;    char *amandates_file;    int   amandates_read = 0;    (void)argc;	/* Quiet unused parameter warning */    (void)argv;	/* Quiet unused parameter warning */    /* initialize */    /*     * 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);    safe_cd();    set_pname("sendsize");    /* Don't die when child closes pipe */    signal(SIGPIPE, SIG_IGN);    erroutput_type = (ERR_INTERACTIVE|ERR_SYSLOG);    dbopen(DBG_SUBDIR_CLIENT);    startclock();    dbprintf(_("version %s\n"), version());    our_features = am_init_feature_set();    our_feature_string = am_feature_to_string(our_features);    config_init(CONFIG_INIT_CLIENT, NULL);    check_running_as(RUNNING_AS_CLIENT_LOGIN);    /* handle all service requests */    for(; (line = agets(stdin)) != NULL; free(line)) {	if (line[0] == '\0')	    continue;	if(strncmp_const(line, "OPTIONS ") == 0) {	    g_options = parse_g_options(line+8, 1);	    if(!g_options->hostname) {		g_options->hostname = alloc(MAX_HOSTNAME_LENGTH+1);		gethostname(g_options->hostname, MAX_HOSTNAME_LENGTH);		g_options->hostname[MAX_HOSTNAME_LENGTH] = '\0';	    }	    g_printf("OPTIONS ");	    if(am_has_feature(g_options->features, fe_rep_options_features)) {		g_printf("features=%s;", our_feature_string);	    }	    if(am_has_feature(g_options->features, fe_rep_options_maxdumps)) {		g_printf("maxdumps=%d;", g_options->maxdumps);	    }	    if(am_has_feature(g_options->features, fe_rep_options_hostname)) {		g_printf("hostname=%s;", g_options->hostname);	    }	    g_printf("\n");	    fflush(stdout);	    if (g_options->config) {		/* overlay this configuration on the existing (nameless) configuration */		config_init(CONFIG_INIT_CLIENT | CONFIG_INIT_EXPLICIT_NAME | CONFIG_INIT_OVERLAY,			    g_options->config);		dbrename(config_name, DBG_SUBDIR_CLIENT);	    }	    continue;	}	if (amandates_read == 0) {	    amandates_file = getconf_str(CNF_AMANDATES);	    if(!start_amandates(amandates_file, 0))	        error("error [opening %s: %s]", amandates_file,		      strerror(errno));	    amandates_read = 1;	}	s = line;	ch = *s++;	skip_whitespace(s, ch);			/* find the program name */	if(ch == '\0') {	    err_extra = stralloc(_("no program name"));	    goto err;				/* no program name */	}	prog = s - 1;	skip_non_whitespace(s, ch);	s[-1] = '\0';	program_is_backup_api=0;	if(strncmp_const(prog, "CALCSIZE") == 0) {	    skip_whitespace(s, ch);		/* find the program name */	    if(ch == '\0') {		err_extra = stralloc(_("no program name"));		goto err;	    }	    calcprog = s - 1;	    skip_non_whitespace(s, ch);	    s[-1] = '\0';	    if (strcmp(calcprog,"BACKUP") == 0) {		program_is_backup_api=1;		skip_whitespace(s, ch);		/* find dumper name */		if (ch == '\0') {		    goto err;			/* no program */		}		calcprog = s - 1;		skip_non_whitespace(s, ch);		s[-1] = '\0';	    }	}	else {	    calcprog = NULL;	    if (strcmp(prog,"BACKUP") == 0) {		program_is_backup_api=1;		skip_whitespace(s, ch);		/* find dumper name */		if (ch == '\0') {		    goto err;			/* no program */		}		prog = s - 1;		skip_non_whitespace(s, ch);		s[-1] = '\0';	    }	}	skip_whitespace(s, ch);			/* find the disk name */	if(ch == '\0') {	    err_extra = stralloc(_("no disk name"));	    goto err;				/* no disk name */	}	if (qdisk != NULL)	    amfree(qdisk);	if (disk != NULL)	    amfree(disk);	fp = s - 1;	skip_quoted_string(s, ch);	s[-1] = '\0';				/* terminate the disk name */	qdisk = stralloc(fp);	disk = unquote_string(qdisk);	skip_whitespace(s, ch);			/* find the device or level */	if (ch == '\0') {	    err_extra = stralloc(_("bad level"));	    goto err;	}	if(!isdigit((int)s[-1])) {	    fp = s - 1;	    skip_quoted_string(s, ch);	    s[-1] = '\0';	    qamdevice = stralloc(fp);	    amdevice = unquote_string(qamdevice);	    skip_whitespace(s, ch);		/* find level number */	}	else {	    amdevice = stralloc(disk);	    qamdevice = stralloc(qdisk);	}						/* find the level number */	if(ch == '\0' || sscanf(s - 1, "%d", &level) != 1) {	    err_extra = stralloc(_("bad level"));	    goto err;				/* bad level */	}	if (level < 0 || level >= DUMP_LEVELS) {	    err_extra = stralloc(_("bad level"));	    goto err;	}	skip_integer(s, ch);	skip_whitespace(s, ch);			/* find the dump date */	if(ch == '\0') {	    err_extra = stralloc(_("no dumpdate"));	    goto err;				/* no dumpdate */	}	dumpdate = s - 1;	skip_non_whitespace(s, ch);	s[-1] = '\0';	(void)dumpdate;				/* XXX: Set but not used */	spindle = 0;				/* default spindle */	skip_whitespace(s, ch);			/* find the spindle */	if(ch != '\0') {	    if(sscanf(s - 1, "%d", &spindle) != 1) {		err_extra = stralloc(_("bad spindle"));		goto err;			/* bad spindle */	    }	    skip_integer(s, ch);	    skip_whitespace(s, ch);		/* find the parameters */	    if(ch != '\0') {		if(strncmp_const(s-1, "OPTIONS |;") == 0) {		    options = parse_options(s + 8,					    disk,					    amdevice,					    g_options->features,					    0);		}		else {		    options = alloc(SIZEOF(option_t));		    init_options(options);		    while (ch != '\0') {			if(strncmp_const(s-1, "exclude-file=") == 0) {			    qlist = unquote_string(s+12);			    options->exclude_file =				append_sl(options->exclude_file, qlist);			    amfree(qlist);			} else if(strncmp_const(s-1, "exclude-list=") == 0) {			    qlist = unquote_string(s+12);			    options->exclude_list =				append_sl(options->exclude_list, qlist);			    amfree(qlist);			} else if(strncmp_const(s-1, "include-file=") == 0) {			    qlist = unquote_string(s+12);			    options->include_file =				append_sl(options->include_file, qlist);			    amfree(qlist);			} else if(strncmp_const(s-1, "include-list=") == 0) {			    qlist = unquote_string(s+12);			    options->include_list =				append_sl(options->include_list, qlist);			    amfree(qlist);			} else {			    err_extra = vstrallocf(_("Invalid parameter (%s)"), s-1);			    goto err;		/* should have gotten to end */			}			skip_quoted_string(s, ch);			skip_whitespace(s, ch);	/* find the inclusion list */			amfree(qlist);		    }		}	    }	    else {		options = alloc(SIZEOF(option_t));		init_options(options);	    }	}	else {	    options = alloc(SIZEOF(option_t));	    init_options(options);	}	/*@ignore@*/	add_diskest(disk, amdevice, level, spindle, program_is_backup_api, prog, calcprog, options);	/*@end@*/	amfree(disk);	amfree(qdisk);	amfree(amdevice);	amfree(qamdevice);    }    if (g_options == NULL) {	printf(_("ERROR [Missing OPTIONS line in sendsize input]\n"));	error(_("Missing OPTIONS line in sendsize input\n"));	/*NOTREACHED*/    }    amfree(line);    finish_amandates();    free_amandates();    dumpsrunning = 0;    need_wait = 0;    done = 0;    while(! done) {	done = 1;	/*	 * See if we need to wait for a child before we can do anything	 * else in this pass.	 */	if(need_wait) {	    pid_t child_pid;	    amwait_t child_status;	    need_wait = 0;	    dbprintf(_("waiting for any estimate child: %d running\n"),		      dumpsrunning);	    child_pid = wait(&child_status);	    if(child_pid == -1) {		error(_("wait failed: %s"), strerror(errno));		/*NOTREACHED*/	    }	    if (!WIFEXITED(child_status) || WEXITSTATUS(child_status) != 0) {		char *child_name = vstrallocf(_("child %ld"), (long)child_pid);		char *child_status_str = str_exit_status(child_name, child_status);		dbprintf("%s\n", child_status_str);		amfree(child_status_str);		amfree(child_name);	    }	    /*	     * Find the child and mark it done.	     */	    for(est = est_list; est != NULL; est = est->next) {		if(est->child == child_pid) {		    break;		}	    }	    if(est == NULL) {		dbprintf(_("unexpected child %ld\n"), (long)child_pid);	    } else {		est->done = 1;		est->child = 0;		dumpsrunning--;	    }	}	/*	 * If we are already running the maximum number of children	 * go back and wait until one of them finishes.	 */	if(dumpsrunning >= g_options->maxdumps) {	    done = 0;	    need_wait = 1;	    continue;				/* have to wait first */	}	/*	 * Find a new child to start.	 */	for(est = est_list; est != NULL; est = est->next) {	    if(est->done == 0) {		done = 0;			/* more to do */	    }	    if(est->child != 0 || est->done) {		continue;			/* child is running or done */	    }	    /*	     * Make sure there is no spindle conflict.	     */	    if(est->spindle != -1) {		for(est1 = est_list; est1 != NULL; est1 = est1->next) {		    if(est1->child == 0 || est == est1 || est1->done) {			/*			 * Ignore anything not yet started, ourself,			 * and anything completed.			 */			continue;		    }		    if(est1->spindle == est->spindle) {			break;			/* oops -- they match */		    }		}		if(est1 != NULL) {		    continue;			/* spindle conflict */		}	    }	    break;				/* start this estimate */	}	if(est == NULL) {	    if(dumpsrunning > 0) {		need_wait = 1;			/* nothing to do but wait */	    }	} else {	    done = 0;	    if((est->child = fork()) == 0) {		calc_estimates(est);		/* child does the estimate */		exit(0);	    } else if(est->child == -1) {		error(_("calc_estimates fork failed: %s"), strerror(errno));		/*NOTREACHED*/	    }	    dumpsrunning++;			/* parent */	}    }    est_prev = NULL;    for(est = est_list; est != NULL; est = est->next) {	free_estimates(est);	amfree(est_prev);	est_prev = est;    }    amfree(est_prev);    amfree(our_feature_string);    am_release_feature_set(our_features);    our_features = NULL;    free_g_options(g_options);    dbclose();    return 0; err:    g_printf(_("FORMAT ERROR IN REQUEST PACKET\n"));    if (err_extra) {	dbprintf(_("REQ packet is bogus: %s\n"), err_extra);	amfree(err_extra);    } else {	dbprintf(_("REQ packet is bogus\n"));    }    dbclose();    return 1;}voidadd_diskest(    char *	disk,    char *	amdevice,    int		level,    int		spindle,    int		program_is_backup_api,    char *	prog,    char *	calcprog,    option_t *	options){    disk_estimates_t *newp, *curp;    amandates_t *amdp;    int dumplev, estlev;    time_t dumpdate;    if (level < 0)	level = 0;    if (level >= DUMP_LEVELS)	level = DUMP_LEVELS - 1;    for(curp = est_list; curp != NULL; curp = curp->next) {	if(strcmp(curp->amname, disk) == 0) {	    /* already have disk info, just note the level request */	    curp->est[level].needestimate = 1;	    if(options) {		free_sl(options->exclude_file);		free_sl(options->exclude_list);		free_sl(options->include_file);		free_sl(options->include_list);		amfree(options->auth);		amfree(options->str);		amfree(options);	    }	    return;	}    }    newp = (disk_estimates_t *) alloc(SIZEOF(disk_estimates_t));    memset(newp, 0, SIZEOF(*newp));    newp->next = est_list;    est_list = newp;

⌨️ 快捷键说明

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