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

📄 amadmin.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. * * Author: James da Silva, Systems Design and Analysis Group *			   Computer Science Department *			   University of Maryland at College Park *//* * $Id: amadmin.c,v 1.124 2006/07/26 15:17:37 martinea Exp $ * * controlling process for the Amanda backup system */#include "amanda.h"#include "cmdline.h"#include "conffile.h"#include "diskfile.h"#include "tapefile.h"#include "infofile.h"#include "logfile.h"#include "version.h"#include "holding.h"#include "find.h"#include "util.h"#include "timestamp.h"disklist_t diskq;int main(int argc, char **argv);void usage(void);void force(int argc, char **argv);void force_one(disk_t *dp);void unforce(int argc, char **argv);void unforce_one(disk_t *dp);void force_bump(int argc, char **argv);void force_bump_one(disk_t *dp);void force_no_bump(int argc, char **argv);void force_no_bump_one(disk_t *dp);void unforce_bump(int argc, char **argv);void unforce_bump_one(disk_t *dp);void reuse(int argc, char **argv);void noreuse(int argc, char **argv);void info(int argc, char **argv);void info_one(disk_t *dp);void due(int argc, char **argv);void due_one(disk_t *dp);void find(int argc, char **argv);void holding(int argc, char **argv);void delete(int argc, char **argv);void delete_one(disk_t *dp);void balance(int argc, char **argv);void tape(int argc, char **argv);void bumpsize(int argc, char **argv);void diskloop(int argc, char **argv, char *cmdname, void (*func)(disk_t *dp));char *seqdatestr(int seq);static int next_level0(disk_t *dp, info_t *info);int bump_thresh(int level);void export_db(int argc, char **argv);void import_db(int argc, char **argv);void disklist(int argc, char **argv);void disklist_one(disk_t *dp);void show_version(int argc, char **argv);static void show_config(int argc, char **argv);static char *conf_tapelist = NULL;static char *displayunit;static long int unitdivisor;static const struct {    const char *name;    void (*fn)(int, char **);    const char *usage;} cmdtab[] = {    { "version", show_version,	T_("\t\t\t\t\t# Show version info.") },    { "config", show_config,	T_("\t\t\t\t\t# Show configuration.") },    { "force", force,	T_(" [<hostname> [<disks>]* ]+\t\t# Force level 0 at next run.") },    { "unforce", unforce,	T_(" [<hostname> [<disks>]* ]+\t# Clear force command.") },    { "force-bump", force_bump,	T_(" [<hostname> [<disks>]* ]+\t# Force bump at next run.") },    { "force-no-bump", force_no_bump,	T_(" [<hostname> [<disks>]* ]+\t# Force no-bump at next run.") },    { "unforce-bump", unforce_bump,	T_(" [<hostname> [<disks>]* ]+\t# Clear bump command.") },    { "disklist", disklist,	T_(" [<hostname> [<disks>]* ]*\t# Debug disklist entries.") },    { "reuse", reuse,	T_(" <tapelabel> ...\t\t # re-use this tape.") },    { "no-reuse", noreuse,	T_(" <tapelabel> ...\t # never re-use this tape.") },    { "find", find,	T_(" [<hostname> [<disks>]* ]*\t # Show which tapes these dumps are on.") },    { "holding", holding,	T_(" {list [ -l ] |delete} [ <hostname> [ <disk> [ <datestamp> [ .. ] ] ] ]+\t # Show or delete holding disk contents.") },    { "delete", delete,	T_(" [<hostname> [<disks>]* ]+ # Delete from database.") },    { "info", info,	T_(" [<hostname> [<disks>]* ]*\t # Show current info records.") },    { "due", due,	T_(" [<hostname> [<disks>]* ]*\t # Show due date.") },    { "balance", balance,	T_(" [-days <num>]\t\t # Show nightly dump size balance.") },    { "tape", tape,	T_(" [-days <num>]\t\t # Show which tape is due next.") },    { "bumpsize", bumpsize,	T_("\t\t\t # Show current bump thresholds.") },    { "export", export_db,	T_(" [<hostname> [<disks>]* ]* # Export curinfo database to stdout.") },    { "import", import_db,	T_("\t\t\t\t # Import curinfo database from stdin.") },};#define	NCMDS	(int)(sizeof(cmdtab) / sizeof(cmdtab[0]))intmain(    int		argc,    char **	argv){    int i;    char *conf_diskfile;    char *conf_infofile;    config_overwrites_t *cfg_ovr = NULL;    /*     * 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("amadmin");    /* Don't die when child closes pipe */    signal(SIGPIPE, SIG_IGN);    dbopen(DBG_SUBDIR_SERVER);    erroutput_type = ERR_INTERACTIVE;    cfg_ovr = extract_commandline_config_overwrites(&argc, &argv);    if(argc < 3) usage();    if(strcmp(argv[2],"version") == 0) {	show_version(argc, argv);	goto done;    }    config_init(CONFIG_INIT_EXPLICIT_NAME | CONFIG_INIT_FATAL, argv[1]);    apply_config_overwrites(cfg_ovr);    dbrename(config_name, DBG_SUBDIR_SERVER);    check_running_as(RUNNING_AS_DUMPUSER);    conf_diskfile = config_dir_relative(getconf_str(CNF_DISKFILE));    if (read_diskfile(conf_diskfile, &diskq) < 0) {	error(_("could not load disklist \"%s\""), conf_diskfile);	/*NOTREACHED*/    }    amfree(conf_diskfile);    conf_tapelist = config_dir_relative(getconf_str(CNF_TAPELIST));    if(read_tapelist(conf_tapelist)) {	error(_("could not load tapelist \"%s\""), conf_tapelist);	/*NOTREACHED*/    }    /* conf_tapelist is not freed yet -- it may be used to write the     * tapelist later. */    conf_infofile = config_dir_relative(getconf_str(CNF_INFOFILE));    if(open_infofile(conf_infofile)) {	error(_("could not open info db \"%s\""), conf_infofile);	/*NOTREACHED*/    }    amfree(conf_infofile);    displayunit = getconf_str(CNF_DISPLAYUNIT);    unitdivisor = getconf_unit_divisor();    for (i = 0; i < NCMDS; i++)	if (strcmp(argv[2], cmdtab[i].name) == 0) {	    (*cmdtab[i].fn)(argc, argv);	    break;	}    if (i == NCMDS) {	g_fprintf(stderr, _("%s: unknown command \"%s\"\n"), argv[0], argv[2]);	usage();    }    close_infofile();    clear_tapelist();    amfree(conf_tapelist);done:    free_disklist(&diskq);    dbclose();    return 0;}voidusage(void){    int i;    g_fprintf(stderr, _("\nUsage: %s%s <conf> <command> {<args>} [-o configoption]* ...\n"),	    get_pname(), versionsuffix());    g_fprintf(stderr, _("    Valid <command>s are:\n"));    for (i = 0; i < NCMDS; i++)	g_fprintf(stderr, "\t%s%s\n", cmdtab[i].name, _(cmdtab[i].usage));    exit(1);}/* ----------------------------------------------- */#define SECS_PER_DAY (24*60*60)time_t today;char *seqdatestr(    int		seq){    static char str[16];    static char *dow[7] = {			T_("Sun"),			T_("Mon"),			T_("Tue"),			T_("Wed"),			T_("Thu"),			T_("Fri"),			T_("Sat")		};    time_t t = today + seq*SECS_PER_DAY;    struct tm *tm;    tm = localtime(&t);    if (tm)	g_snprintf(str, SIZEOF(str),		 "%2d/%02d %3s", tm->tm_mon+1, tm->tm_mday, _(dow[tm->tm_wday]));    else	strcpy(str, _("BAD DATE"));    return str;}#undef days_diff#define days_diff(a, b)        (int)(((b) - (a) + SECS_PER_DAY) / SECS_PER_DAY)/* when is next level 0 due? 0 = tonight, 1 = tommorrow, etc*/static intnext_level0(    disk_t *	dp,    info_t *	info){    if(dp->strategy == DS_NOFULL)	return 1;	/* fake it */    if(info->inf[0].date < (time_t)0)	return 0;	/* new disk */    else	return dp->dumpcycle - days_diff(info->inf[0].date, today);}/* ----------------------------------------------- */voiddiskloop(    int		argc,    char **	argv,    char *	cmdname,    void	(*func)(disk_t *dp)){    disk_t *dp;    int count = 0;    char *errstr;    if(argc < 4) {	g_fprintf(stderr,_("%s: expecting \"%s [<hostname> [<disks>]* ]+\"\n"),		get_pname(), cmdname);	usage();    }    errstr = match_disklist(&diskq, argc-3, argv+3);    if (errstr) {	g_printf("%s", errstr);	amfree(errstr);    }    for(dp = diskq.head; dp != NULL; dp = dp->next) {	if(dp->todo) {	    count++;	    func(dp);	}    }    if(count==0) {	g_fprintf(stderr,_("%s: no disk matched\n"),get_pname());    }}/* ----------------------------------------------- */voidforce_one(    disk_t *	dp){    char *hostname = dp->host->hostname;    char *diskname = dp->name;    info_t info;    get_info(hostname, diskname, &info);    SET(info.command, FORCE_FULL);    if (ISSET(info.command, FORCE_BUMP)) {	CLR(info.command, FORCE_BUMP);	g_printf(_("%s: WARNING: %s:%s FORCE_BUMP command was cleared.\n"),	       get_pname(), hostname, diskname);    }    if(put_info(hostname, diskname, &info) == 0) {	if (dp->strategy == DS_INCRONLY) {	    g_printf(_("%s: %s:%s, full dump done offline, next dump will be at level 1.\n"),		     get_pname(), hostname, diskname);	} else {	    g_printf(_("%s: %s:%s is set to a forced level 0 at next run.\n"),		     get_pname(), hostname, diskname);	}    } else {	g_fprintf(stderr, _("%s: %s:%s could not be forced.\n"),		get_pname(), hostname, diskname);    }}voidforce(    int		argc,    char **	argv){    diskloop(argc, argv, "force", force_one);}/* ----------------------------------------------- */voidunforce_one(    disk_t *	dp){    char *hostname = dp->host->hostname;    char *diskname = dp->name;    info_t info;    get_info(hostname, diskname, &info);    if (ISSET(info.command, FORCE_FULL)) {	CLR(info.command, FORCE_FULL);	if(put_info(hostname, diskname, &info) == 0){	    g_printf(_("%s: force command for %s:%s cleared.\n"),		   get_pname(), hostname, diskname);	} else {	    g_fprintf(stderr,		    _("%s: force command for %s:%s could not be cleared.\n"),		    get_pname(), hostname, diskname);	}    }    else {	g_printf(_("%s: no force command outstanding for %s:%s, unchanged.\n"),	       get_pname(), hostname, diskname);    }}voidunforce(    int		argc,    char **	argv){    diskloop(argc, argv, "unforce", unforce_one);}/* ----------------------------------------------- */voidforce_bump_one(    disk_t *	dp){    char *hostname = dp->host->hostname;    char *diskname = dp->name;    info_t info;    get_info(hostname, diskname, &info);    SET(info.command, FORCE_BUMP);    if (ISSET(info.command, FORCE_NO_BUMP)) {	CLR(info.command, FORCE_NO_BUMP);	g_printf(_("%s: WARNING: %s:%s FORCE_NO_BUMP command was cleared.\n"),	       get_pname(), hostname, diskname);    }    if (ISSET(info.command, FORCE_FULL)) {	CLR(info.command, FORCE_FULL);	g_printf(_("%s: WARNING: %s:%s FORCE_FULL command was cleared.\n"),	       get_pname(), hostname, diskname);    }    if(put_info(hostname, diskname, &info) == 0) {	g_printf(_("%s: %s:%s is set to bump at next run.\n"),	       get_pname(), hostname, diskname);    } else {	g_fprintf(stderr, _("%s: %s:%s could not be forced to bump.\n"),		get_pname(), hostname, diskname);    }}voidforce_bump(    int		argc,    char **	argv){    diskloop(argc, argv, "force-bump", force_bump_one);}/* ----------------------------------------------- */voidforce_no_bump_one(    disk_t *	dp){    char *hostname = dp->host->hostname;    char *diskname = dp->name;    info_t info;    get_info(hostname, diskname, &info);    SET(info.command, FORCE_NO_BUMP);    if (ISSET(info.command, FORCE_BUMP)) {	CLR(info.command, FORCE_BUMP);	g_printf(_("%s: WARNING: %s:%s FORCE_BUMP command was cleared.\n"),	       get_pname(), hostname, diskname);    }    if(put_info(hostname, diskname, &info) == 0) {	g_printf(_("%s: %s:%s is set to not bump at next run.\n"),	       get_pname(), hostname, diskname);    } else {	g_fprintf(stderr, _("%s: %s:%s could not be force to not bump.\n"),		get_pname(), hostname, diskname);    }}voidforce_no_bump(    int		argc,    char **	argv){    diskloop(argc, argv, "force-no-bump", force_no_bump_one);}/* ----------------------------------------------- */voidunforce_bump_one(    disk_t *	dp){    char *hostname = dp->host->hostname;    char *diskname = dp->name;    info_t info;    get_info(hostname, diskname, &info);    if (ISSET(info.command, FORCE_BUMP|FORCE_NO_BUMP)) {	CLR(info.command, FORCE_BUMP|FORCE_NO_BUMP);	if(put_info(hostname, diskname, &info) == 0) {	    g_printf(_("%s: bump command for %s:%s cleared.\n"),		   get_pname(), hostname, diskname);	} else {	    g_fprintf(stderr, _("%s: %s:%s bump command could not be cleared.\n"),		    get_pname(), hostname, diskname);	}    }    else {	g_printf(_("%s: no bump command outstanding for %s:%s, unchanged.\n"),	       get_pname(), hostname, diskname);    }}voidunforce_bump(    int		argc,    char **	argv){    diskloop(argc, argv, "unforce-bump", unforce_bump_one);}/* ----------------------------------------------- */voidreuse(    int		argc,    char **	argv){    tape_t *tp;    int count;    if(argc < 4) {	g_fprintf(stderr,_("%s: expecting \"reuse <tapelabel> ...\"\n"),		get_pname());	usage();    }    for(count=3; count< argc; count++) {	tp = lookup_tapelabel(argv[count]);	if ( tp == NULL) {	    g_fprintf(stderr, _("reuse: tape label %s not found in tapelist.\n"),		argv[count]);	    continue;	}	if( tp->reuse == 0 ) {

⌨️ 快捷键说明

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