📄 selfcheck.c
字号:
/* * 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: selfcheck.c,v 1.95 2006/08/29 11:21:00 martinea Exp $ * * do self-check and send back any error messages */#include "amanda.h"#include "fsusage.h"#include "version.h"#include "getfsent.h"#include "amandates.h"#include "clock.h"#include "util.h"#include "pipespawn.h"#include "amfeatures.h"#include "client_util.h"#include "conffile.h"#include "amandad.h"#ifdef SAMBA_CLIENT#include "findpass.h"#endifint need_samba=0;int need_rundump=0;int need_dump=0;int need_restore=0;int need_vdump=0;int need_vrestore=0;int need_xfsdump=0;int need_xfsrestore=0;int need_vxdump=0;int need_vxrestore=0;int need_runtar=0;int need_gnutar=0;int need_compress_path=0;int need_calcsize=0;int program_is_backup_api=0;static char *amandad_auth = NULL;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);static void check_options(char *program, char *calcprog, char *disk, char *amdevice, option_t *options);static void check_disk(char *program, char *calcprog, char *disk, char *amdevice, int level, option_t *options);static void check_overall(void);static void check_access(char *filename, int mode);static int check_file_exist(char *filename);static void check_file(char *filename, int mode);static void check_dir(char *dirname, int mode);static void check_suid(char *filename);static void check_space(char *dir, off_t kbytes);intmain( int argc, char ** argv){ int level; char *line = NULL; char *program = NULL; char *calcprog = NULL; char *disk = NULL; char *qdisk = NULL; char *amdevice = NULL; char *qamdevice = NULL; char *optstr = NULL; char *err_extra = NULL; char *s, *fp; option_t *options; int ch; /* 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("selfcheck"); /* 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()); if(argc > 2 && strcmp(argv[1], "amandad") == 0) { amandad_auth = stralloc(argv[2]); } config_init(CONFIG_INIT_CLIENT, NULL); check_running_as(RUNNING_AS_CLIENT_LOGIN); our_features = am_init_feature_set(); our_feature_string = am_feature_to_string(our_features); /* handle all service requests */ /*@ignore@*/ for(; (line = agets(stdin)) != NULL; free(line)) { /*@end@*/ 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_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; } s = line; ch = *s++; skip_whitespace(s, ch); /* find program name */ if (ch == '\0') { goto err; /* no program */ } program = s - 1; skip_non_whitespace(s, ch); s[-1] = '\0'; /* terminate the program name */ program_is_backup_api = 0; if(strcmp(program,"BACKUP")==0) { program_is_backup_api = 1; skip_whitespace(s, ch); /* find dumper name */ if (ch == '\0') { goto err; /* no program */ } program = s - 1; skip_non_whitespace(s, ch); s[-1] = '\0'; /* terminate the program name */ } if(strncmp_const(program, "CALCSIZE") == 0) { skip_whitespace(s, ch); /* find program name */ if (ch == '\0') { goto err; /* no program */ } calcprog = s - 1; skip_non_whitespace(s, ch); s[-1] = '\0'; } else { calcprog = NULL; } skip_whitespace(s, ch); /* find disk name */ if (ch == '\0') { goto err; /* no disk */ } qdisk = s - 1; skip_quoted_string(s, ch); s[-1] = '\0'; /* terminate the disk name */ disk = unquote_string(qdisk); skip_whitespace(s, ch); /* find the device or level */ if (ch == '\0') { goto err; /* no device or level */ } if(!isdigit((int)s[-1])) { fp = s - 1; skip_quoted_string(s, ch); s[-1] = '\0'; /* terminate the device */ qamdevice = stralloc(fp); amdevice = unquote_string(qamdevice); skip_whitespace(s, ch); /* find level number */ } else { amdevice = stralloc(disk); } /* find level number */ if (ch == '\0' || sscanf(s - 1, "%d", &level) != 1) { goto err; /* bad level */ } skip_integer(s, ch); skip_whitespace(s, ch); if (ch && strncmp_const_skip(s - 1, "OPTIONS ", s, ch) == 0) { skip_whitespace(s, ch); /* find the option string */ if(ch == '\0') { goto err; /* bad options string */ } optstr = s - 1; skip_quoted_string(s, ch); s[-1] = '\0'; /* terminate the options */ options = parse_options(optstr, disk, amdevice, g_options->features, 1); /*@ignore@*/ check_options(program, calcprog, disk, amdevice, options); check_disk(program, calcprog, disk, amdevice, level, options); /*@end@*/ 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); } else if (ch == '\0') { /* check all since no option */ need_samba=1; need_rundump=1; need_dump=1; need_restore=1; need_vdump=1; need_vrestore=1; need_xfsdump=1; need_xfsrestore=1; need_vxdump=1; need_vxrestore=1; need_runtar=1; need_gnutar=1; need_compress_path=1; need_calcsize=1; /*@ignore@*/ check_disk(program, calcprog, disk, amdevice, level, NULL); /*@end@*/ } else { goto err; /* bad syntax */ } amfree(disk); amfree(qamdevice); amfree(amdevice); } if (g_options == NULL) { printf(_("ERROR [Missing OPTIONS line in selfcheck input]\n")); error(_("Missing OPTIONS line in selfcheck input\n")); /*NOTREACHED*/ } check_overall(); amfree(line); amfree(our_feature_string); am_release_feature_set(our_features); our_features = NULL; free_g_options(g_options); dbclose(); return 0; err: g_printf(_("ERROR [BOGUS REQUEST PACKET]\n")); dbprintf(_("REQ packet is bogus%s%s\n"), err_extra ? ": " : "", err_extra ? err_extra : ""); dbclose(); return 1;}static voidcheck_options( char * program, char * calcprog, char * disk, char * amdevice, option_t * options){ char *myprogram = program; if(strcmp(myprogram,"CALCSIZE") == 0) { int nb_exclude = 0; int nb_include = 0; char *file_exclude = NULL; char *file_include = NULL; if(options->exclude_file) nb_exclude += options->exclude_file->nb_element; if(options->exclude_list) nb_exclude += options->exclude_list->nb_element; if(options->include_file) nb_include += options->include_file->nb_element; if(options->include_list) nb_include += options->include_list->nb_element; if(nb_exclude > 0) file_exclude = build_exclude(disk, amdevice, options, 1); if(nb_include > 0) file_include = build_include(disk, amdevice, options, 1); amfree(file_exclude); amfree(file_include); need_calcsize=1; if (calcprog == NULL) { g_printf(_("ERROR [no program name for calcsize]\n")); } else { myprogram = calcprog; } } if(strcmp(myprogram,"GNUTAR") == 0) { need_gnutar=1; if(amdevice[0] == '/' && amdevice[1] == '/') { if(options->exclude_file && options->exclude_file->nb_element > 1) { g_printf(_("ERROR [samba support only one exclude file]\n")); } if(options->exclude_list && options->exclude_list->nb_element > 0 && options->exclude_optional==0) { g_printf(_("ERROR [samba does not support exclude list]\n")); } if(options->include_file && options->include_file->nb_element > 0) { g_printf(_("ERROR [samba does not support include file]\n")); } if(options->include_list && options->include_list->nb_element > 0 && options->include_optional==0) { g_printf(_("ERROR [samba does not support include list]\n")); } need_samba=1; } else { int nb_exclude = 0; int nb_include = 0; char *file_exclude = NULL; char *file_include = NULL; if(options->exclude_file) nb_exclude += options->exclude_file->nb_element; if(options->exclude_list) nb_exclude += options->exclude_list->nb_element; if(options->include_file) nb_include += options->include_file->nb_element; if(options->include_list) nb_include += options->include_list->nb_element; if(nb_exclude > 0) file_exclude = build_exclude(disk, amdevice, options, 1); if(nb_include > 0) file_include = build_include(disk, amdevice, options, 1); amfree(file_exclude); amfree(file_include); need_runtar=1; } } if(strcmp(myprogram,"DUMP") == 0) { if(options->exclude_file && options->exclude_file->nb_element > 0) { g_printf(_("ERROR [DUMP does not support exclude file]\n")); } if(options->exclude_list && options->exclude_list->nb_element > 0) { g_printf(_("ERROR [DUMP does not support exclude list]\n")); } if(options->include_file && options->include_file->nb_element > 0) { g_printf(_("ERROR [DUMP does not support include file]\n")); } if(options->include_list && options->include_list->nb_element > 0) { g_printf(_("ERROR [DUMP does not support include list]\n")); }#ifdef USE_RUNDUMP need_rundump=1;#endif#ifndef AIX_BACKUP#ifdef VDUMP#ifdef DUMP if (strcmp(amname_to_fstype(amdevice), "advfs") == 0)#else if (1)#endif { need_vdump=1; need_rundump=1; if (options->createindex) need_vrestore=1; } else#endif /* VDUMP */#ifdef XFSDUMP#ifdef DUMP if (strcmp(amname_to_fstype(amdevice), "xfs") == 0)#else if (1)#endif { need_xfsdump=1; need_rundump=1; if (options->createindex) need_xfsrestore=1; } else#endif /* XFSDUMP */#ifdef VXDUMP#ifdef DUMP if (strcmp(amname_to_fstype(amdevice), "vxfs") == 0)#else if (1)#endif { need_vxdump=1; if (options->createindex) need_vxrestore=1; } else#endif /* VXDUMP */ { need_dump=1; if (options->createindex) need_restore=1; }#else /* AIX backup program */ need_dump=1; if (options->createindex) need_restore=1;#endif } if ((options->compress == COMP_BEST) || (options->compress == COMP_FAST) || (options->compress == COMP_CUST)) { need_compress_path=1; } if(options->auth && amandad_auth) { if(strcasecmp(options->auth, amandad_auth) != 0) { g_fprintf(stdout,_("ERROR [client configured for auth=%s while server requested '%s']\n"), amandad_auth, options->auth); if(strcmp(options->auth, "ssh") == 0) { g_fprintf(stderr, _("ERROR [The auth in ~/.ssh/authorized_keys " "should be \"--auth=ssh\", or use another auth " " for the DLE]\n")); } else { g_fprintf(stderr, _("ERROR [The auth in the inetd/xinetd configuration " " must be the same as the DLE]\n")); } } }}static voidcheck_disk( char * program, char * calcprog, char * disk, char * amdevice, int level, option_t *options){ char *device = stralloc("nodevice"); char *err = NULL; char *user_and_password = NULL; char *domain = NULL; char *share = NULL, *subdir = NULL; size_t lpass = 0; int amode; int access_result; char *access_type; char *extra_info = NULL; char *myprogram = program; char *qdisk = quote_string(disk); char *qamdevice = quote_string(amdevice); char *qdevice = NULL; FILE *toolin; (void)level; /* Quiet unused parameter warning */ dbprintf(_("checking disk %s\n"), qdisk); if(strcmp(myprogram,"CALCSIZE") == 0) { if(amdevice[0] == '/' && amdevice[1] == '/') { err = vstrallocf(_("Can't use CALCSIZE for samba estimate, use CLIENT: %s"), amdevice); goto common_exit; } if (calcprog == NULL) { err = _("no program for calcsize"); goto common_exit; } myprogram = calcprog; } if (strcmp(myprogram, "GNUTAR")==0) { if(amdevice[0] == '/' && amdevice[1] == '/') {#ifdef SAMBA_CLIENT int nullfd, checkerr; int passwdfd; char *pwtext; size_t pwtext_len; pid_t checkpid; amwait_t retstat; pid_t wpid; int rc; char *line; char *sep; FILE *ferr; char *pw_fd_env; int errdos; parsesharename(amdevice, &share, &subdir); if (!share) { err = vstrallocf(_("cannot parse for share/subdir disk entry %s"), amdevice); goto common_exit; } if ((subdir) && (SAMBA_VERSION < 2)) { err = vstrallocf(_("subdirectory specified for share '%s' but, samba is not v2 or better"), amdevice); goto common_exit; } if ((user_and_password = findpass(share, &domain)) == NULL) { err = vstrallocf(_("cannot find password for %s"), amdevice); goto common_exit; } lpass = strlen(user_and_password); if ((pwtext = strchr(user_and_password, '%')) == NULL) { err = vstrallocf(_("password field not \'user%%pass\' for %s"), amdevice); goto common_exit; } *pwtext++ = '\0'; pwtext_len = (size_t)strlen(pwtext); amfree(device); if ((device = makesharename(share, 0)) == NULL) { err = vstrallocf(_("cannot make share name of %s"), share); goto common_exit; } if ((nullfd = open("/dev/null", O_RDWR)) == -1) { err = vstrallocf(_("Cannot access /dev/null : %s"), strerror(errno)); goto common_exit; } if (pwtext_len > 0) { pw_fd_env = "PASSWD_FD"; } else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -