* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: amcheck.c,v 1.50.2.19.2.7.2.20.2.10 2005/04/06 12:32:31 martinea Exp $
+ * $Id: amcheck.c,v 1.149 2006/08/24 01:57:16 paddy_s Exp $
*
* checks for common problems in server and clients
*/
#include "amanda.h"
+#include "util.h"
#include "conffile.h"
-#include "statfs.h"
+#include "columnar.h"
+#include "fsusage.h"
#include "diskfile.h"
#include "tapefile.h"
-#include "tapeio.h"
#include "changer.h"
+#include "packet.h"
+#include "security.h"
#include "protocol.h"
#include "clock.h"
#include "version.h"
#include "amindex.h"
-#include "token.h"
-#include "util.h"
+#include "taperscan.h"
+#include "server_util.h"
#include "pipespawn.h"
#include "amfeatures.h"
-
-/*
- * If we don't have the new-style wait access functions, use our own,
- * compatible with old-style BSD systems at least. Note that we don't
- * care about the case w_stopval == WSTOPPED since we don't ask to see
- * stopped processes, so should never get them from wait.
- */
-#ifndef WEXITSTATUS
-# define WEXITSTATUS(r) (((union wait *) &(r))->w_retcode)
-# define WTERMSIG(r) (((union wait *) &(r))->w_termsig)
-
-# undef WIFSIGNALED
-# define WIFSIGNALED(r) (((union wait *) &(r))->w_termsig != 0)
-#endif
+#include "device.h"
+#include "property.h"
+#include "timestamp.h"
+#include "amxml.h"
+#include "physmem.h"
#define BUFFER_SIZE 32768
-static int conf_ctimeout;
+static time_t conf_ctimeout;
static int overwrite;
-dgram_t *msg = NULL;
-static disklist_t *origqp;
+static disklist_t origq;
static uid_t uid_dumpuser;
/* local functions */
-void usage P((void));
-int start_client_checks P((int fd));
-int start_server_check P((int fd, int do_localchk, int do_tapechk));
-int main P((int argc, char **argv));
-int scan_init P((int rc, int ns, int bk));
-int taperscan_slot P((int rc, char *slotstr, char *device));
-char *taper_scan P((void));
-int test_server_pgm P((FILE *outf, char *dir, char *pgm,
- int suid, uid_t dumpuid));
-
-void usage()
+void usage(void);
+pid_t start_client_checks(int fd);
+pid_t start_server_check(int fd, int do_localchk, int do_tapechk);
+int main(int argc, char **argv);
+int check_tapefile(FILE *outf, char *tapefile);
+int test_server_pgm(FILE *outf, char *dir, char *pgm, int suid, uid_t dumpuid);
+
+void
+usage(void)
{
- error("Usage: amcheck%s [-M <username>] [-mawsclt] <conf> [host [disk]* ]*", versionsuffix());
+ error(_("Usage: amcheck%s [-am] [-w] [-sclt] [-M <address>] <conf> [host [disk]* ]* [-o configoption]*"), versionsuffix());
+ /*NOTREACHED*/
}
-static unsigned long malloc_hist_1, malloc_size_1;
-static unsigned long malloc_hist_2, malloc_size_2;
-
static am_feature_t *our_features = NULL;
static char *our_feature_string = NULL;
static char *displayunit;
static long int unitdivisor;
-int main(argc, argv)
-int argc;
-char **argv;
+int
+main(
+ int argc,
+ char ** argv)
{
char buffer[BUFFER_SIZE];
char *version_string;
char *mainfname = NULL;
char pid_str[NUM_STR_SIZE];
- int do_clientchk, clientchk_pid, client_probs;
- int do_localchk, do_tapechk, serverchk_pid, server_probs;
- int chk_flag;
- int opt, size, result_port, tempfd, mainfd;
+ int do_clientchk, client_probs;
+ int do_localchk, do_tapechk, server_probs;
+ pid_t clientchk_pid, serverchk_pid;
+ int opt, tempfd, mainfd;
+ size_t size;
amwait_t retstat;
pid_t pid;
extern int optind;
- int l, n, s;
- int fd;
char *mailto = NULL;
extern char *optarg;
int mailout;
int alwaysmail;
char *tempfname = NULL;
- char *conffile;
char *conf_diskfile;
char *dumpuser;
struct passwd *pw;
uid_t uid_me;
+ char *errstr;
+ config_overwrites_t *cfg_ovr;
+ char *mailer;
- for(fd = 3; fd < FD_SETSIZE; fd++) {
- /*
- * Make sure nobody spoofs us with a lot of extra open files
- * that would cause an open we do to get a very high file
- * descriptor, which in turn might be used as an index into
- * an array (e.g. an fd_set).
- */
- close(fd);
- }
-
+ /*
+ * 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("amcheck");
- dbopen();
+ /* drop root privileges */
+ if (!set_root_privs(0)) {
+ error(_("amcheck must be run setuid root"));
+ }
+
+ /* Don't die when child closes pipe */
+ signal(SIGPIPE, SIG_IGN);
+
+ dbopen(DBG_SUBDIR_SERVER);
- malloc_size_1 = malloc_inuse(&malloc_hist_1);
+ memset(buffer, 0, sizeof(buffer));
- ap_snprintf(pid_str, sizeof(pid_str), "%ld", (long)getpid());
+ g_snprintf(pid_str, SIZEOF(pid_str), "%ld", (long)getpid());
erroutput_type = ERR_INTERACTIVE;
our_features = am_init_feature_set();
our_feature_string = am_feature_to_string(our_features);
- /* set up dgram port first thing */
-
- msg = dgram_alloc();
-
- if(dgram_bind(msg, &result_port) == -1)
- error("could not bind result datagram port: %s", strerror(errno));
-
- if(geteuid() == 0) {
- /* set both real and effective uid's to real uid, likewise for gid */
- setgid(getgid());
- setuid(getuid());
- }
uid_me = getuid();
alwaysmail = mailout = overwrite = 0;
do_localchk = do_tapechk = do_clientchk = 0;
- chk_flag = 0;
server_probs = client_probs = 0;
tempfd = mainfd = -1;
/* process arguments */
- while((opt = getopt(argc, argv, "M:mawsclt")) != EOF) {
+ cfg_ovr = new_config_overwrites(argc/2);
+ while((opt = getopt(argc, argv, "M:mawsclto:")) != EOF) {
switch(opt) {
- case 'M': mailto=stralloc(optarg);
+ case 'M': if (mailto) {
+ g_printf(_("Multiple -M options\n"));
+ exit(1);
+ }
+ mailto=stralloc(optarg);
+ if(!validate_mailto(mailto)){
+ g_printf(_("Invalid characters in mail address\n"));
+ exit(1);
+ }
+ /*FALLTHROUGH*/
case 'm':
-#ifdef MAILER
mailout = 1;
-#else
- printf("You can't use -%c because configure didn't find a mailer.\n",
- opt);
- exit(1);
-#endif
break;
case 'a':
-#ifdef MAILER
mailout = 1;
alwaysmail = 1;
-#else
- printf("You can't use -%c because configure didn't find a mailer.\n",
- opt);
- exit(1);
-#endif
break;
- case 's': do_localchk = 1; do_tapechk = 1;
- chk_flag = 1;
+ case 's': do_localchk = do_tapechk = 1;
break;
case 'c': do_clientchk = 1;
- chk_flag = 1;
break;
case 'l': do_localchk = 1;
- chk_flag = 1;
break;
- case 'w': do_tapechk = 1; overwrite = 1;
- chk_flag = 1;
+ case 'w': overwrite = 1;
+ break;
+ case 'o': add_config_overwrite_opt(cfg_ovr, optarg);
break;
case 't': do_tapechk = 1;
- chk_flag = 1;
break;
case '?':
default:
}
}
argc -= optind, argv += optind;
- if(! chk_flag) {
+ if(argc < 1) usage();
+
+
+ if ((do_localchk | do_clientchk | do_tapechk) == 0) {
+ /* Check everything if individual checks were not asked for */
do_localchk = do_clientchk = do_tapechk = 1;
}
- if(argc < 1) usage();
+ if(overwrite)
+ do_tapechk = 1;
- config_name = stralloc(*argv);
+ config_init(CONFIG_INIT_EXPLICIT_NAME, argv[0]);
+ apply_config_overwrites(cfg_ovr);
+ dbrename(get_config_name(), DBG_SUBDIR_SERVER);
+
+ conf_diskfile = config_dir_relative(getconf_str(CNF_DISKFILE));
+ read_diskfile(conf_diskfile, &origq);
+ amfree(conf_diskfile);
- config_dir = vstralloc(CONFIG_DIR, "/", config_name, "/", NULL);
- conffile = stralloc2(config_dir, CONFFILE_NAME);
- if(read_conffile(conffile)) {
- error("errors processing config file \"%s\"", conffile);
+ if (config_errors(NULL) >= CFGERR_WARNINGS) {
+ config_print_errors();
+ if (config_errors(NULL) >= CFGERR_ERRORS) {
+ g_critical(_("errors processing config file"));
+ }
}
- amfree(conffile);
- conf_ctimeout = getconf_int(CNF_CTIMEOUT);
- conf_diskfile = getconf_str(CNF_DISKFILE);
- if (*conf_diskfile == '/') {
- conf_diskfile = stralloc(conf_diskfile);
- } else {
- conf_diskfile = stralloc2(config_dir, conf_diskfile);
+
+ mailer = getconf_str(CNF_MAILER);
+ if ((!mailer || *mailer == '\0') && mailout == 1) {
+ if (alwaysmail == 1) {
+ g_printf(_("You can't use -a because a mailer is not defined\n"));
+ } else {
+ g_printf(_("You can't use -m because a mailer is not defined\n"));
+ }
+ exit(1);
}
- if((origqp = read_diskfile(conf_diskfile)) == NULL) {
- error("could not load disklist %s", conf_diskfile);
+ if(mailout && !mailto &&
+ (getconf_seen(CNF_MAILTO)==0 || strlen(getconf_str(CNF_MAILTO)) == 0)) {
+ g_printf(_("\nWARNING:No mail address configured in amanda.conf.\n"));
+ g_printf(_("To receive dump results by email configure the "
+ "\"mailto\" parameter in amanda.conf\n"));
+ if(alwaysmail)
+ g_printf(_("When using -a option please specify -Maddress also\n\n"));
+ else
+ g_printf(_("Use -Maddress instead of -m\n\n"));
+ exit(1);
+ }
+ if(mailout && !mailto)
+ {
+ if(getconf_seen(CNF_MAILTO) &&
+ strlen(getconf_str(CNF_MAILTO)) > 0) {
+ if(!validate_mailto(getconf_str(CNF_MAILTO))){
+ g_printf(_("\nMail address in amanda.conf has invalid characters"));
+ g_printf(_("\nNo email will be sent\n"));
+ mailout = 0;
+ }
+ }
+ else {
+ g_printf(_("\nNo mail address configured in amanda.conf\n"));
+ if(alwaysmail)
+ g_printf(_("When using -a option please specify -Maddress also\n\n"));
+ else
+ g_printf(_("Use -Maddress instead of -m\n\n"));
+ exit(1);
+ }
+ }
+
+ conf_ctimeout = (time_t)getconf_int(CNF_CTIMEOUT);
+
+ errstr = match_disklist(&origq, argc-1, argv+1);
+ if (errstr) {
+ g_printf(_("%s"),errstr);
+ amfree(errstr);
}
- match_disklist(origqp, argc-1, argv+1);
- amfree(conf_diskfile);
/*
- * Make sure we are running as the dump user.
+ * Make sure we are running as the dump user. Don't use
+ * check_running_as(..) here, because we want to produce more
+ * verbose error messages.
*/
dumpuser = getconf_str(CNF_DUMPUSER);
if ((pw = getpwnam(dumpuser)) == NULL) {
- error("cannot look up dump user \"%s\"", dumpuser);
+ error(_("amanda.conf has dump user configured to \"%s\", but that user does not exist."), dumpuser);
+ /*NOTREACHED*/
}
uid_dumpuser = pw->pw_uid;
if ((pw = getpwuid(uid_me)) == NULL) {
- error("cannot look up my own uid (%ld)", (long)uid_me);
+ error(_("cannot get username for running user, uid %ld is not in your user database."),
+ (long)uid_me);
+ /*NOTREACHED*/
}
+#ifdef CHECK_USERID
if (uid_me != uid_dumpuser) {
- error("running as user \"%s\" instead of \"%s\"",
- pw->pw_name,
- dumpuser);
+ error(_("running as user \"%s\" instead of \"%s\".\n"
+ "Change user to \"%s\" or change dump user to \"%s\" in amanda.conf"),
+ pw->pw_name, dumpuser, dumpuser, pw->pw_name);
+ /*NOTREACHED*/
}
+#endif
displayunit = getconf_str(CNF_DISPLAYUNIT);
unitdivisor = getconf_unit_divisor();
if(do_clientchk && (do_localchk || do_tapechk)) {
/* we need the temp file */
tempfname = vstralloc(AMANDA_TMPDIR, "/amcheck.temp.", pid_str, NULL);
- if((tempfd = open(tempfname, O_RDWR|O_CREAT|O_TRUNC, 0600)) == -1)
- error("could not open %s: %s", tempfname, strerror(errno));
+ if((tempfd = open(tempfname, O_RDWR|O_CREAT|O_TRUNC, 0600)) == -1) {
+ error(_("could not open temporary amcheck output file %s: %s. Check permissions"), tempfname, strerror(errno));
+ /*NOTREACHED*/
+ }
unlink(tempfname); /* so it goes away on close */
amfree(tempfname);
}
if(mailout) {
/* the main fd is a file too */
mainfname = vstralloc(AMANDA_TMPDIR, "/amcheck.main.", pid_str, NULL);
- if((mainfd = open(mainfname, O_RDWR|O_CREAT|O_TRUNC, 0600)) == -1)
- error("could not open %s: %s", mainfname, strerror(errno));
+ if((mainfd = open(mainfname, O_RDWR|O_CREAT|O_TRUNC, 0600)) == -1) {
+ error(_("could not open amcheck server output file %s: %s. Check permissions"), mainfname, strerror(errno));
+ /*NOTREACHED*/
+ }
unlink(mainfname); /* so it goes away on close */
amfree(mainfname);
}
/* start server side checks */
- if(do_localchk || do_tapechk) {
+ if(do_localchk || do_tapechk)
serverchk_pid = start_server_check(mainfd, do_localchk, do_tapechk);
- } else {
+ else
serverchk_pid = 0;
- }
/* start client side checks */
server_probs = WIFSIGNALED(retstat) || WEXITSTATUS(retstat);
serverchk_pid = 0;
} else {
- char number[NUM_STR_SIZE];
char *wait_msg = NULL;
- ap_snprintf(number, sizeof(number), "%ld", (long)pid);
- wait_msg = vstralloc("parent: reaped bogus pid ", number, "\n",
- NULL);
- for(l = 0, n = strlen(wait_msg); l < n; l += s) {
- if((s = write(mainfd, wait_msg + l, n - l)) < 0) {
- error("write main file: %s", strerror(errno));
- }
+ wait_msg = vstrallocf(_("parent: reaped bogus pid %ld\n"), (long)pid);
+ if (full_write(mainfd, wait_msg, strlen(wait_msg)) < strlen(wait_msg)) {
+ error(_("write main file: %s"), strerror(errno));
+ /*NOTREACHED*/
}
amfree(wait_msg);
}
}
- amfree(msg);
/* copy temp output to main output and write tagline */
if(do_clientchk && (do_localchk || do_tapechk)) {
- if(lseek(tempfd, 0, 0) == -1)
- error("seek temp file: %s", strerror(errno));
+ if(lseek(tempfd, (off_t)0, 0) == (off_t)-1) {
+ error(_("seek temp file: %s"), strerror(errno));
+ /*NOTREACHED*/
+ }
- while((size=read(tempfd, buffer, sizeof(buffer))) > 0) {
- for(l = 0; l < size; l += s) {
- if((s = write(mainfd, buffer + l, size - l)) < 0) {
- error("write main file: %s", strerror(errno));
- }
+ while((size = full_read(tempfd, buffer, SIZEOF(buffer))) > 0) {
+ if (full_write(mainfd, buffer, size) < size) {
+ error(_("write main file: %s"), strerror(errno));
+ /*NOTREACHED*/
}
}
- if(size < 0)
- error("read temp file: %s", strerror(errno));
+ if(errno != 0) {
+ error(_("read temp file: %s"), strerror(errno));
+ /*NOTREACHED*/
+ }
aclose(tempfd);
}
- version_string = vstralloc("\n",
- "(brought to you by Amanda ", version(), ")\n",
- NULL);
- for(l = 0, n = strlen(version_string); l < n; l += s) {
- if((s = write(mainfd, version_string + l, n - l)) < 0) {
- error("write main file: %s", strerror(errno));
- }
+ version_string = vstrallocf(_("\n(brought to you by Amanda %s)\n"), version());
+ if (full_write(mainfd, version_string, strlen(version_string)) < strlen(version_string)) {
+ error(_("write main file: %s"), strerror(errno));
+ /*NOTREACHED*/
}
amfree(version_string);
- amfree(config_dir);
- amfree(config_name);
amfree(our_feature_string);
am_release_feature_set(our_features);
our_features = NULL;
- malloc_size_2 = malloc_inuse(&malloc_hist_2);
-
- if(malloc_size_1 != malloc_size_2) {
- malloc_list(fileno(stderr), malloc_hist_1, malloc_hist_2);
- }
-
/* send mail if requested, but only if there were problems */
-#ifdef MAILER
-
-#define MAILTO_LIMIT 10
if((server_probs || client_probs || alwaysmail) && mailout) {
int mailfd;
int errfd;
FILE *ferr;
char *subject;
- char **a;
+ char **a, **b;
+ GPtrArray *pipeargs;
amwait_t retstat;
- pid_t mailpid;
- pid_t wpid;
- int r;
- int w;
+ size_t r;
+ size_t w;
char *err = NULL;
char *extra_info = NULL;
char *line = NULL;
- int ret;
int rc;
- int sig;
- char number[NUM_STR_SIZE];
fflush(stdout);
- if(lseek(mainfd, (off_t)0, SEEK_SET) == -1) {
- error("lseek main file: %s", strerror(errno));
+ if(lseek(mainfd, (off_t)0, SEEK_SET) == (off_t)-1) {
+ error(_("lseek main file: %s"), strerror(errno));
+ /*NOTREACHED*/
}
if(alwaysmail && !(server_probs || client_probs)) {
- subject = stralloc2(getconf_str(CNF_ORG),
- " AMCHECK REPORT: NO PROBLEMS FOUND");
+ subject = vstrallocf(_("%s AMCHECK REPORT: NO PROBLEMS FOUND"),
+ getconf_str(CNF_ORG));
} else {
- subject = stralloc2(getconf_str(CNF_ORG),
- " AMANDA PROBLEM: FIX BEFORE RUN, IF POSSIBLE");
+ subject = vstrallocf(
+ _("%s AMANDA PROBLEM: FIX BEFORE RUN, IF POSSIBLE"),
+ getconf_str(CNF_ORG));
}
- /*
- * Variable arg lists are hard to deal with when we do not know
- * ourself how many args are involved. Split the address list
- * and hope there are not more than 9 entries.
- *
- * Remember that split() returns the original input string in
- * argv[0], so we have to skip over that.
- */
- a = (char **) alloc((MAILTO_LIMIT + 1) * sizeof(char *));
- memset(a, 0, (MAILTO_LIMIT + 1) * sizeof(char *));
if(mailto) {
- a[1] = mailto;
+ a = (char **) g_new0(char *, 2);
+ a[1] = stralloc(mailto);
a[2] = NULL;
} else {
- n = split(getconf_str(CNF_MAILTO), a, MAILTO_LIMIT, " ");
- a[n + 1] = NULL;
+ /* (note that validate_mailto doesn't allow any quotes, so this
+ * is really just splitting regular old strings) */
+ a = split_quoted_strings(getconf_str(CNF_MAILTO));
}
if((nullfd = open("/dev/null", O_RDWR)) < 0) {
error("nullfd: /dev/null: %s", strerror(errno));
+ /*NOTREACHED*/
}
- mailpid = pipespawn(MAILER, STDIN_PIPE | STDERR_PIPE,
- &mailfd, &nullfd, &errfd,
- MAILER,
- "-s", subject,
- a[1], a[2], a[3], a[4],
- a[5], a[6], a[7], a[8], a[9],
- NULL);
+
+ /* assemble the command line for the mailer */
+ pipeargs = g_ptr_array_sized_new(4);
+ g_ptr_array_add(pipeargs, mailer);
+ g_ptr_array_add(pipeargs, "-s");
+ g_ptr_array_add(pipeargs, subject);
+ for (b = a; *b; b++)
+ g_ptr_array_add(pipeargs, *b);
+ g_ptr_array_add(pipeargs, NULL);
+
+ pipespawnv(mailer, STDIN_PIPE | STDERR_PIPE, 0,
+ &mailfd, &nullfd, &errfd,
+ (char **)pipeargs->pdata);
+
+ g_ptr_array_free(pipeargs, FALSE);
amfree(subject);
+ amfree(mailto);
+ g_strfreev(a);
+
/*
* There is the potential for a deadlock here since we are writing
* to the process and then reading stderr, but in the normal case,
* cases, the pipe will break and we will exit out of the loop.
*/
signal(SIGPIPE, SIG_IGN);
- while((r = fullread(mainfd, buffer, sizeof(buffer))) > 0) {
- if((w = fullwrite(mailfd, buffer, r)) != r) {
- if(w < 0 && errno == EPIPE) {
- strappend(extra_info, "EPIPE writing to mail process\n");
+ while((r = full_read(mainfd, buffer, SIZEOF(buffer))) > 0) {
+ if((w = full_write(mailfd, buffer, r)) != r) {
+ if(errno == EPIPE) {
+ strappend(extra_info, _("EPIPE writing to mail process\n"));
break;
- } else if(w < 0) {
- error("mailfd write: %s", strerror(errno));
+ } else if(errno != 0) {
+ error(_("mailfd write: %s"), strerror(errno));
+ /*NOTREACHED*/
} else {
- error("mailfd write: wrote %d instead of %d", w, r);
+ error(_("mailfd write: wrote %zd instead of %zd"), w, r);
+ /*NOTREACHED*/
}
}
}
aclose(mailfd);
ferr = fdopen(errfd, "r");
+ if (!ferr) {
+ error(_("Can't fdopen: %s"), strerror(errno));
+ /*NOTREACHED*/
+ }
for(; (line = agets(ferr)) != NULL; free(line)) {
+ if (line[0] == '\0')
+ continue;
strappend(extra_info, line);
strappend(extra_info, "\n");
}
afclose(ferr);
errfd = -1;
rc = 0;
- while ((wpid = wait(&retstat)) != -1) {
- if (WIFSIGNALED(retstat)) {
- ret = 0;
- rc = sig = WTERMSIG(retstat);
- } else {
- sig = 0;
- rc = ret = WEXITSTATUS(retstat);
- }
- if (rc != 0) {
- if (ret == 0) {
- strappend(err, "got signal ");
- ret = sig;
- } else {
- strappend(err, "returned ");
- }
- ap_snprintf(number, sizeof(number), "%d", ret);
- strappend(err, number);
+ while (wait(&retstat) != -1) {
+ if (!WIFEXITED(retstat) || WEXITSTATUS(retstat) != 0) {
+ char *mailer_error = str_exit_status("mailer", retstat);
+ strappend(err, mailer_error);
+ amfree(mailer_error);
+
+ rc = 1;
}
}
if (rc != 0) {
fputs(extra_info, stderr);
amfree(extra_info);
}
- error("error running mailer %s: %s", MAILER, err);
+ error(_("error running mailer %s: %s"), mailer, err?err:"(unknown)");
+ /*NOTREACHED*/
}
}
-#endif
+
dbclose();
return (server_probs || client_probs);
}
/* --------------------------------------------------- */
-int nslots, backwards, found, got_match, tapedays;
-char *datestamp;
-char *first_match_label = NULL, *first_match = NULL, *found_device = NULL;
-char *label;
-char *searchlabel, *labelstr;
-tape_t *tp;
-FILE *errf;
-
-int scan_init(rc, ns, bk)
-int rc, ns, bk;
-{
- if(rc)
- error("could not get changer info: %s", changer_resultstr);
-
- nslots = ns;
- backwards = bk;
+static char *datestamp;
+static FILE *errf = NULL;
- return 0;
-}
-
-int taperscan_slot(rc, slotstr, device)
-int rc;
-char *slotstr;
-char *device;
-{
- char *errstr;
-
- if(rc == 2) {
- fprintf(errf, "%s: fatal slot %s: %s\n",
- get_pname(), slotstr, changer_resultstr);
- return 1;
- }
- else if(rc == 1) {
- fprintf(errf, "%s: slot %s: %s\n",
- get_pname(), slotstr, changer_resultstr);
- return 0;
- }
- else {
- if((errstr = tape_rdlabel(device, &datestamp, &label)) != NULL) {
- fprintf(errf, "%s: slot %s: %s\n", get_pname(), slotstr, errstr);
- } else {
- /* got an amanda tape */
- fprintf(errf, "%s: slot %s: date %-8s label %s",
- get_pname(), slotstr, datestamp, label);
- if(searchlabel != NULL
- && (strcmp(label, FAKE_LABEL) == 0
- || strcmp(label, searchlabel) == 0)) {
- /* it's the one we are looking for, stop here */
- fprintf(errf, " (exact label match)\n");
- found_device = newstralloc(found_device, device);
- found = 1;
- return 1;
- }
- else if(!match(labelstr, label))
- fprintf(errf, " (no match)\n");
- else {
- /* not an exact label match, but a labelstr match */
- /* check against tape list */
- tp = lookup_tapelabel(label);
- if(tp == NULL)
- fprintf(errf, " (Not in tapelist)\n");
- else if(!reusable_tape(tp))
- fprintf(errf, " (active tape)\n");
- else if(got_match == 0 && tp->datestamp == 0) {
- got_match = 1;
- first_match = newstralloc(first_match, slotstr);
- first_match_label = newstralloc(first_match_label, label);
- fprintf(errf, " (new tape)\n");
- found = 3;
- found_device = newstralloc(found_device, device);
- return 1;
- }
- else if(got_match)
- fprintf(errf, " (labelstr match)\n");
- else {
- got_match = 1;
- first_match = newstralloc(first_match, slotstr);
- first_match_label = newstralloc(first_match_label, label);
- fprintf(errf, " (first labelstr match)\n");
- if(!backwards || !searchlabel) {
- found = 2;
- found_device = newstralloc(found_device, device);
- return 1;
- }
- }
- }
- }
- }
- return 0;
-}
-
-char *taper_scan()
+int check_tapefile(
+ FILE *outf,
+ char *tapefile)
{
- char *outslot = NULL;
-
- if((tp = lookup_last_reusable_tape(0)) == NULL)
- searchlabel = NULL;
- else
- searchlabel = tp->label;
-
- found = 0;
- got_match = 0;
-
- changer_find(scan_init, taperscan_slot, searchlabel);
-
- if(found == 2 || found == 3)
- searchlabel = first_match_label;
- else if(!found && got_match) {
- searchlabel = first_match_label;
- amfree(found_device);
- if(changer_loadslot(first_match, &outslot, &found_device) == 0) {
- found = 1;
- }
- } else if(!found) {
- if(searchlabel) {
- changer_resultstr = newvstralloc(changer_resultstr,
- "label ", searchlabel,
- " or new tape not found in rack",
- NULL);
- } else {
- changer_resultstr = newstralloc(changer_resultstr,
- "new tape not found in rack");
+ struct stat statbuf;
+ char *quoted;
+ int tapebad = 0;
+
+ if (stat(tapefile, &statbuf) == 0) {
+ if (!S_ISREG(statbuf.st_mode)) {
+ quoted = quote_string(tapefile);
+ g_fprintf(outf, _("ERROR: tapelist %s: should be a regular file.\n"),
+ quoted);
+ tapebad = 1;
+ amfree(quoted);
+ } else if (access(tapefile, F_OK) != 0) {
+ quoted = quote_string(tapefile);
+ g_fprintf(outf, _("ERROR: can't access tapelist %s\n"), quoted);
+ tapebad = 1;
+ amfree(quoted);
+ } else if (access(tapefile, W_OK) != 0) {
+ quoted = quote_string(tapefile);
+ g_fprintf(outf, _("ERROR: tapelist %s: not writable\n"), quoted);
+ tapebad = 1;
+ amfree(quoted);
}
}
- amfree(outslot);
-
- return found ? found_device : NULL;
+ return tapebad;
}
-int test_server_pgm(outf, dir, pgm, suid, dumpuid)
-FILE *outf;
-char *dir;
-char *pgm;
-int suid;
-uid_t dumpuid;
+int
+test_server_pgm(
+ FILE * outf,
+ char * dir,
+ char * pgm,
+ int suid,
+ uid_t dumpuid)
{
struct stat statbuf;
int pgmbad = 0;
+ char *quoted;
pgm = vstralloc(dir, "/", pgm, versionsuffix(), NULL);
+ quoted = quote_string(pgm);
if(stat(pgm, &statbuf) == -1) {
- fprintf(outf, "ERROR: program %s: does not exist\n",
- pgm);
+ g_fprintf(outf, _("ERROR: program %s: does not exist\n"),
+ quoted);
pgmbad = 1;
} else if (!S_ISREG(statbuf.st_mode)) {
- fprintf(outf, "ERROR: program %s: not a file\n",
- pgm);
+ g_fprintf(outf, _("ERROR: program %s: not a file\n"),
+ quoted);
pgmbad = 1;
} else if (access(pgm, X_OK) == -1) {
- fprintf(outf, "ERROR: program %s: not executable\n",
- pgm);
+ g_fprintf(outf, _("ERROR: program %s: not executable\n"),
+ quoted);
pgmbad = 1;
+#ifndef SINGLE_USERID
} else if (suid \
&& dumpuid != 0
&& (statbuf.st_uid != 0 || (statbuf.st_mode & 04000) == 0)) {
- fprintf(outf, "WARNING: program %s: not setuid-root\n",
- pgm);
+ g_fprintf(outf, _("ERROR: program %s: not setuid-root\n"),
+ quoted);
+ pgmbad = 1;
+#else
+ /* Quiet unused parameter warnings */
+ (void)suid;
+ (void)dumpuid;
+#endif /* SINGLE_USERID */
}
+ amfree(quoted);
amfree(pgm);
return pgmbad;
}
-int start_server_check(fd, do_localchk, do_tapechk)
- int fd;
+/* check that the tape is a valid amanda tape
+ Returns TRUE if all tests passed; FALSE otherwise. */
+static gboolean test_tape_status(FILE * outf) {
+ int tape_status;
+ Device * device;
+ GValue property_value;
+ char * label = NULL;
+ char * tapename = NULL;
+ DeviceStatusFlags device_status;
+
+ bzero(&property_value, sizeof(property_value));
+
+ tapename = getconf_str(CNF_TAPEDEV);
+ g_return_val_if_fail(tapename != NULL, FALSE);
+
+ device_api_init();
+
+ if (!getconf_seen(CNF_TPCHANGER) && getconf_int(CNF_RUNTAPES) != 1) {
+ g_fprintf(outf,
+ _("WARNING: if a tape changer is not available, runtapes "
+ "must be set to 1\n"));
+ g_fprintf(outf, _("Change the value of the \"runtapes\" parameter in "
+ "amanda.conf or configure a tape changer\n"));
+ }
+
+ tape_status = taper_scan(NULL, &label, &datestamp, &tapename, NULL,
+ FILE_taperscan_output_callback, outf,
+ NULL, NULL);
+ if (tape_status < 0) {
+ tape_t *exptape = lookup_last_reusable_tape(0);
+ g_fprintf(outf, _(" (expecting "));
+ if(exptape != NULL) g_fprintf(outf, _("tape %s or "), exptape->label);
+ g_fprintf(outf, _("a new tape)\n"));
+ amfree(label);
+ return FALSE;
+ }
+
+ device = device_open(tapename);
+ g_assert(device != NULL);
+
+ if (device->status != DEVICE_STATUS_SUCCESS) {
+ g_fprintf(outf, "ERROR: Could not open tape device: %s.\n",
+ device_error(device));
+ amfree(label);
+ return FALSE;
+ }
+
+ if (!device_configure(device, TRUE)) {
+ g_fprintf(outf, "ERROR: Could not configure device: %s.\n",
+ device_error_or_status(device));
+ amfree(label);
+ return FALSE;
+ }
+
+ device_status = device_read_label(device);
+
+ if (tape_status == 3 &&
+ !(device_status & DEVICE_STATUS_VOLUME_UNLABELED)) {
+ if (device_status == DEVICE_STATUS_SUCCESS) {
+ g_fprintf(outf, "WARNING: Volume was unlabeled, but now "
+ "is labeled \"%s\".\n", device->volume_label);
+ }
+ } else if (device_status != DEVICE_STATUS_SUCCESS && tape_status != 3) {
+ g_fprintf(outf,
+ _("WARNING: Reading label the second time failed: %s.\n"),
+ device_error_or_status(device));
+ } else if (tape_status != 3 &&
+ (device->volume_label == NULL || label == NULL ||
+ strcmp(device->volume_label, label) != 0)) {
+ g_fprintf(outf, "WARNING: Label mismatch on re-read: "
+ "Got %s first, then %s.\n", label, device->volume_label);
+ }
+
+ /* If we can't get this property, it's not an error. Maybe the device
+ * doesn't support this property, or needs an actual volume to know
+ * for sure. */
+ if (device_property_get(device, PROPERTY_MEDIUM_ACCESS_TYPE, &property_value)) {
+ g_assert(G_VALUE_TYPE(&property_value) == MEDIA_ACCESS_MODE_TYPE);
+ if (g_value_get_enum(&property_value) ==
+ MEDIA_ACCESS_MODE_WRITE_ONLY) {
+ g_fprintf(outf, "WARNING: Media access mode is WRITE_ONLY; "
+ "dumps may not be recoverable.\n");
+ }
+ }
+
+ if (overwrite) {
+ char *timestamp = get_undef_timestamp();
+ if (!device_start(device, ACCESS_WRITE, label, timestamp)) {
+ if (tape_status == 3) {
+ g_fprintf(outf, "ERROR: Could not label brand new tape");
+ } else {
+ g_fprintf(outf,
+ "ERROR: tape %s label ok, but is not writable",
+ label);
+ }
+ g_fprintf(outf, ": %s.\n", device_error(device));
+ amfree(timestamp);
+ amfree(label);
+ g_object_unref(device);
+ return FALSE;
+ } else { /* Write succeeded. */
+ if (tape_status != 3) {
+ g_fprintf(outf, "Tape %s is writable; rewrote label.\n", label);
+ } else {
+ g_fprintf(outf, "Wrote label %s to brand new tape.\n", label);
+ }
+ }
+ amfree(timestamp);
+ } else { /* !overwrite */
+ g_fprintf(outf, "NOTE: skipping tape-writable test\n");
+ if (tape_status == 3) {
+ g_fprintf(outf,
+ "Found a brand new tape, will label it %s.\n",
+ label);
+ } else {
+ g_fprintf(outf, "Tape %s label ok\n", label);
+ }
+ }
+ g_object_unref(device);
+ amfree(label);
+ return TRUE;
+}
+
+pid_t
+start_server_check(
+ int fd,
+ int do_localchk,
+ int do_tapechk)
{
- char *errstr, *tapename;
- generic_fs_stats_t fs;
- tape_t *tp;
- FILE *outf;
+ struct fs_usage fsusage;
+ FILE *outf = NULL;
holdingdisk_t *hdp;
- int pid;
+ pid_t pid G_GNUC_UNUSED;
int confbad = 0, tapebad = 0, disklow = 0, logbad = 0;
int userbad = 0, infobad = 0, indexbad = 0, pgmbad = 0;
int testtape = do_tapechk;
+ tapetype_t *tp = NULL;
+ char *quoted;
+ int res;
+ intmax_t kb_avail;
+ off_t tape_size;
switch(pid = fork()) {
- case -1: error("could not fork server check: %s", strerror(errno));
- case 0: break;
+ case -1:
+ error(_("could not spawn a process for checking the server: %s"), strerror(errno));
+ g_assert_not_reached();
+
+ case 0:
+ break;
+
default:
return pid;
}
-
+
dup2(fd, 1);
dup2(fd, 2);
-
+
set_pname("amcheck-server");
-
- amfree(msg);
-
+
startclock();
- if((outf = fdopen(fd, "w")) == NULL)
- error("fdopen %d: %s", fd, strerror(errno));
+ if((outf = fdopen(fd, "w")) == NULL) {
+ error(_("fdopen %d: %s"), fd, strerror(errno));
+ /*NOTREACHED*/
+ }
errf = outf;
- fprintf(outf, "Amanda Tape Server Host Check\n");
- fprintf(outf, "-----------------------------\n");
+ g_fprintf(outf, _("Amanda Tape Server Host Check\n"));
+ g_fprintf(outf, "-----------------------------\n");
+
+ if (do_localchk || testtape) {
+ tp = lookup_tapetype(getconf_str(CNF_TAPETYPE));
+ }
/*
* Check various server side config file settings.
if(do_localchk) {
char *ColumnSpec;
char *errstr = NULL;
- tapetype_t *tp;
char *lbl_templ;
ColumnSpec = getconf_str(CNF_COLUMNSPEC);
- if(SetColumDataFromString(ColumnData, ColumnSpec, &errstr) < 0) {
- fprintf(outf, "ERROR: %s\n", errstr);
+ if(SetColumnDataFromString(ColumnData, ColumnSpec, &errstr) < 0) {
+ g_fprintf(outf, _("ERROR: %s\n"), errstr);
amfree(errstr);
confbad = 1;
}
- tp = lookup_tapetype(getconf_str(CNF_TAPETYPE));
- lbl_templ = tp->lbl_templ;
+ lbl_templ = tapetype_get_lbl_templ(tp);
if(strcmp(lbl_templ, "") != 0) {
- if(strchr(lbl_templ, '/') == NULL) {
- lbl_templ = stralloc2(config_dir, lbl_templ);
- } else {
- lbl_templ = stralloc(lbl_templ);
- }
+ lbl_templ = config_dir_relative(lbl_templ);
if(access(lbl_templ, R_OK) == -1) {
- fprintf(outf,
- "ERROR: cannot access lbl_templ file %s: %s\n",
+ g_fprintf(outf,
+ _("ERROR: cannot read label template (lbl-templ) file %s: %s. Check permissions\n"),
lbl_templ,
strerror(errno));
confbad = 1;
}
#if !defined(LPRCMD)
- fprintf(outf, "ERROR: lbl_templ set but no LPRCMD defined, you should reconfigure amanda\n and make sure it find a lpr or lp command.\n");
+ g_fprintf(outf, _("ERROR:lbl-templ set but no LPRCMD defined. You should reconfigure amanda\n and make sure it finds a lpr or lp command.\n"));
confbad = 1;
#endif
}
+
+ if (getconf_int(CNF_FLUSH_THRESHOLD_SCHEDULED) <
+ getconf_int(CNF_FLUSH_THRESHOLD_DUMPED)) {
+ g_fprintf(outf, _("WARNING: flush_threshold_dumped (%d) must be less than or equal to flush_threshold_scheduled (%d).\n"),
+ getconf_int(CNF_FLUSH_THRESHOLD_DUMPED),
+ getconf_int(CNF_FLUSH_THRESHOLD_SCHEDULED));
+ }
+
+ if (getconf_int(CNF_FLUSH_THRESHOLD_SCHEDULED) <
+ getconf_int(CNF_TAPERFLUSH)) {
+ g_fprintf(outf, _("WARNING: taperflush (%d) must be less than or equal to flush_threshold_scheduled (%d).\n"),
+ getconf_int(CNF_TAPERFLUSH),
+ getconf_int(CNF_FLUSH_THRESHOLD_SCHEDULED));
+ }
+
+ if (getconf_int(CNF_TAPERFLUSH) > 0 &&
+ !getconf_boolean(CNF_AUTOFLUSH)) {
+ g_fprintf(outf, _("WARNING: autoflush must be set to 'yes' if taperflush (%d) is greater that 0.\n"),
+ getconf_int(CNF_TAPERFLUSH));
+ }
+
+ /* Double-check that 'localhost' resolves properly */
+ if ((res = resolve_hostname("localhost", 0, NULL, NULL) != 0)) {
+ g_fprintf(outf, _("ERROR: Cannot resolve `localhost': %s\n"), gai_strerror(res));
+ confbad = 1;
+ }
}
/*
* Look up the programs used on the server side.
*/
if(do_localchk) {
- if(access(libexecdir, X_OK) == -1) {
- fprintf(outf, "ERROR: program dir %s: not accessible\n",
- libexecdir);
+ /*
+ * entreprise version will do planner/dumper suid check
+ */
+ if(access(amlibexecdir, X_OK) == -1) {
+ quoted = quote_string(amlibexecdir);
+ g_fprintf(outf, _("ERROR: Directory %s containing Amanda tools is not accessible\n."),
+ quoted);
+ g_fprintf(outf, _("Check permissions\n"));
pgmbad = 1;
+ amfree(quoted);
} else {
- pgmbad = pgmbad \
- || test_server_pgm(outf, libexecdir, "planner",
- 1, uid_dumpuser);
- pgmbad = pgmbad \
- || test_server_pgm(outf, libexecdir, "dumper",
- 1, uid_dumpuser);
- pgmbad = pgmbad \
- || test_server_pgm(outf, libexecdir, "driver",
- 0, uid_dumpuser);
- pgmbad = pgmbad \
- || test_server_pgm(outf, libexecdir, "taper",
- 0, uid_dumpuser);
- pgmbad = pgmbad \
- || test_server_pgm(outf, libexecdir, "amtrmidx",
- 0, uid_dumpuser);
- pgmbad = pgmbad \
- || test_server_pgm(outf, libexecdir, "amlogroll",
- 0, uid_dumpuser);
+ if(test_server_pgm(outf, amlibexecdir, "planner", 1, uid_dumpuser))
+ pgmbad = 1;
+ if(test_server_pgm(outf, amlibexecdir, "dumper", 1, uid_dumpuser))
+ pgmbad = 1;
+ if(test_server_pgm(outf, amlibexecdir, "driver", 0, uid_dumpuser))
+ pgmbad = 1;
+ if(test_server_pgm(outf, amlibexecdir, "taper", 0, uid_dumpuser))
+ pgmbad = 1;
+ if(test_server_pgm(outf, amlibexecdir, "amtrmidx", 0, uid_dumpuser))
+ pgmbad = 1;
+ if(test_server_pgm(outf, amlibexecdir, "amlogroll", 0, uid_dumpuser))
+ pgmbad = 1;
}
if(access(sbindir, X_OK) == -1) {
- fprintf(outf, "ERROR: program dir %s: not accessible\n",
+ quoted = quote_string(sbindir);
+ g_fprintf(outf, _("ERROR: Directory %s containing Amanda tools is not accessible\n"),
sbindir);
+ g_fprintf(outf, _("Check permissions\n"));
pgmbad = 1;
+ amfree(quoted);
} else {
- pgmbad = pgmbad \
- || test_server_pgm(outf, sbindir, "amgetconf",
- 0, uid_dumpuser);
- pgmbad = pgmbad \
- || test_server_pgm(outf, sbindir, "amcheck",
- 1, uid_dumpuser);
- pgmbad = pgmbad \
- || test_server_pgm(outf, sbindir, "amdump",
- 0, uid_dumpuser);
- pgmbad = pgmbad \
- || test_server_pgm(outf, sbindir, "amreport",
- 0, uid_dumpuser);
+ if(test_server_pgm(outf, sbindir, "amgetconf", 0, uid_dumpuser))
+ pgmbad = 1;
+ if(test_server_pgm(outf, sbindir, "amcheck", 1, uid_dumpuser))
+ pgmbad = 1;
+ if(test_server_pgm(outf, sbindir, "amdump", 0, uid_dumpuser))
+ pgmbad = 1;
+ if(test_server_pgm(outf, sbindir, "amreport", 0, uid_dumpuser))
+ pgmbad = 1;
}
if(access(COMPRESS_PATH, X_OK) == -1) {
- fprintf(outf, "WARNING: %s is not executable, server-compression and indexing will not work\n",
- COMPRESS_PATH);
+ quoted = quote_string(COMPRESS_PATH);
+ g_fprintf(outf, _("WARNING: %s is not executable, server-compression "
+ "and indexing will not work. \n"),quoted);
+ g_fprintf(outf, _("Check permissions\n"));
+ amfree(quoted);
}
}
*/
if(do_localchk || do_tapechk) {
- char *conf_tapelist;
char *tapefile;
+ char *newtapefile;
char *tape_dir;
char *lastslash;
char *holdfile;
+ char * tapename;
struct stat statbuf;
- conf_tapelist=getconf_str(CNF_TAPELIST);
- if (*conf_tapelist == '/') {
- tapefile = stralloc(conf_tapelist);
- } else {
- tapefile = stralloc2(config_dir, conf_tapelist);
- }
+ tapefile = config_dir_relative(getconf_str(CNF_TAPELIST));
/*
* XXX There Really Ought to be some error-checking here... dhw
*/
*/
}
if(access(tape_dir, W_OK) == -1) {
- fprintf(outf, "ERROR: tapelist dir %s: not writable.\n", tape_dir);
+ quoted = quote_string(tape_dir);
+ g_fprintf(outf, _("ERROR: tapelist dir %s: not writable.\nCheck permissions\n"),
+ quoted);
tapebad = 1;
+ amfree(quoted);
}
else if(stat(tapefile, &statbuf) == -1) {
- fprintf(outf, "ERROR: tapefile %s: %s, you must create an empty file.\n",
- tapefile, strerror(errno));
- tapebad = 1;
- }
- else if(access(tapefile, F_OK) != 0) {
- fprintf(outf, "ERROR: can't access tape list %s\n", tapefile);
- tapebad = 1;
- } else if(access(tapefile, F_OK) == 0 && access(tapefile, W_OK) != 0) {
- fprintf(outf, "ERROR: tape list %s: not writable\n", tapefile);
- tapebad = 1;
- } else if(read_tapelist(tapefile)) {
- fprintf(outf, "ERROR: tape list %s: parse error\n", tapefile);
- tapebad = 1;
+ if (errno != ENOENT) {
+ quoted = quote_string(tape_dir);
+ g_fprintf(outf, _("ERROR: tapelist %s (%s), "
+ "you must create an empty file.\n"),
+ quoted, strerror(errno));
+ tapebad = 1;
+ amfree(quoted);
+ } else {
+ g_fprintf(outf, _("NOTE: tapelist will be created on the next run.\n"));
+ }
+ } else {
+ tapebad |= check_tapefile(outf, tapefile);
+ if (tapebad == 0 && read_tapelist(tapefile)) {
+ quoted = quote_string(tapefile);
+ g_fprintf(outf, _("ERROR: tapelist %s: parse error\n"), quoted);
+ tapebad = 1;
+ amfree(quoted);
+ }
+ newtapefile = stralloc2(tapefile, ".new");
+ tapebad |= check_tapefile(outf, newtapefile);
+ amfree(newtapefile);
+ newtapefile = stralloc2(tapefile, ".amlabel");
+ tapebad |= check_tapefile(outf, newtapefile);
+ amfree(newtapefile);
+ newtapefile = stralloc2(tapefile, ".amlabel.new");
+ tapebad |= check_tapefile(outf, newtapefile);
+ amfree(newtapefile);
+ newtapefile = stralloc2(tapefile, ".yesterday");
+ tapebad |= check_tapefile(outf, newtapefile);
+ amfree(newtapefile);
+ newtapefile = stralloc2(tapefile, ".yesterday.new");
+ tapebad |= check_tapefile(outf, newtapefile);
+ amfree(newtapefile);
}
- holdfile = vstralloc(config_dir, "/", "hold", NULL);
+ holdfile = config_dir_relative("hold");
if(access(holdfile, F_OK) != -1) {
- fprintf(outf, "WARNING: hold file %s exists\n", holdfile);
+ quoted = quote_string(holdfile);
+ g_fprintf(outf, _("WARNING: hold file %s exists."), holdfile);
+ g_fprintf(outf, _("Amdump will sleep as long as this file exists.\n"));
+ g_fprintf(outf, _("You might want to delete the existing hold file\n"));
+ amfree(quoted);
}
amfree(tapefile);
amfree(tape_dir);
amfree(holdfile);
tapename = getconf_str(CNF_TAPEDEV);
- if (strncmp(tapename, "null:", 5) == 0) {
- fprintf(outf,
- "WARNING: tapedev is %s, dumps will be thrown away\n",
- tapename);
- testtape = 0;
- do_tapechk = 0;
+ if (tapename == NULL) {
+ if (getconf_str(CNF_TPCHANGER) == NULL) {
+ g_fprintf(outf, _("WARNING:Parameter \"tapedev\" or \"tpchanger\" not specified in amanda.conf.\n"));
+ testtape = 0;
+ do_tapechk = 0;
+ }
}
}
/* check available disk space */
if(do_localchk) {
- for(hdp = holdingdisks; hdp != NULL; hdp = hdp->next) {
- if(get_fs_stats(hdp->diskdir, &fs) == -1) {
- fprintf(outf, "ERROR: holding dir %s: %s, you must create a directory.\n",
- hdp->diskdir, strerror(errno));
+ for(hdp = getconf_holdingdisks(); hdp != NULL; hdp = holdingdisk_next(hdp)) {
+ quoted = quote_string(holdingdisk_get_diskdir(hdp));
+ if(get_fs_usage(holdingdisk_get_diskdir(hdp), NULL, &fsusage) == -1) {
+ g_fprintf(outf, _("ERROR: holding dir %s (%s), "
+ "you must create a directory.\n"),
+ quoted, strerror(errno));
disklow = 1;
+ amfree(quoted);
+ continue;
}
- else if(access(hdp->diskdir, W_OK) == -1) {
- fprintf(outf, "ERROR: holding disk %s: not writable: %s.\n",
- hdp->diskdir, strerror(errno));
+
+ /* do the division first to avoid potential integer overflow */
+ if (fsusage.fsu_bavail_top_bit_set)
+ kb_avail = 0;
+ else
+ kb_avail = fsusage.fsu_bavail / 1024 * fsusage.fsu_blocksize;
+
+ if(access(holdingdisk_get_diskdir(hdp), W_OK) == -1) {
+ g_fprintf(outf, _("ERROR: holding disk %s: not writable: %s.\n"),
+ quoted, strerror(errno));
+ g_fprintf(outf, _("Check permissions\n"));
disklow = 1;
}
- else if(fs.avail == -1) {
- fprintf(outf,
- "WARNING: holding disk %s: available space unknown (%ld KB requested)\n",
- hdp->diskdir, (long)hdp->disksize);
+ else if(access(holdingdisk_get_diskdir(hdp), X_OK) == -1) {
+ g_fprintf(outf, _("ERROR: holding disk %s: not searcheable: %s.\n"),
+ quoted, strerror(errno));
+ g_fprintf(outf, _("Check permissions of ancestors of %s\n"), quoted);
disklow = 1;
}
- else if(hdp->disksize > 0) {
- if(fs.avail < hdp->disksize) {
- fprintf(outf,
- "WARNING: holding disk %s: only %ld %sB free (%ld %sB requested)\n",
- hdp->diskdir, (long)fs.avail/unitdivisor, displayunit,
- (long)hdp->disksize/unitdivisor, displayunit);
+ else if(holdingdisk_get_disksize(hdp) > (off_t)0) {
+ if(kb_avail == 0) {
+ g_fprintf(outf,
+ _("WARNING: holding disk %s: "
+ "no space available (%lld %sB requested)\n"), quoted,
+ (long long)(holdingdisk_get_disksize(hdp)/(off_t)unitdivisor),
+ displayunit);
disklow = 1;
}
- else
- fprintf(outf,
- "Holding disk %s: %ld %sB disk space available, that's plenty\n",
- hdp->diskdir, fs.avail/unitdivisor, displayunit);
+ else if(kb_avail < holdingdisk_get_disksize(hdp)) {
+ g_fprintf(outf,
+ _("WARNING: holding disk %s: "
+ "only %lld %sB available (%lld %sB requested)\n"), quoted,
+ (long long)(kb_avail / (off_t)unitdivisor),
+ displayunit,
+ (long long)(holdingdisk_get_disksize(hdp)/(off_t)unitdivisor),
+ displayunit);
+ disklow = 1;
+ }
+ else {
+ g_fprintf(outf,
+ _("Holding disk %s: %lld %sB disk space available,"
+ " using %lld %sB as requested\n"),
+ quoted,
+ (long long)(kb_avail / (off_t)unitdivisor),
+ displayunit,
+ (long long)(holdingdisk_get_disksize(hdp)/(off_t)unitdivisor),
+ displayunit);
+ }
}
else {
- if(fs.avail < -hdp->disksize) {
- fprintf(outf,
- "WARNING: holding disk %s: only %ld %sB free, using nothing\n",
- hdp->diskdir, fs.avail/unitdivisor, displayunit);
+ if(kb_avail < -holdingdisk_get_disksize(hdp)) {
+ g_fprintf(outf,
+ _("WARNING: holding disk %s: "
+ "only %lld %sB free, using nothing\n"),
+ quoted, (long long)(kb_avail / (off_t)unitdivisor),
+ displayunit);
+ g_fprintf(outf, _("WARNING: Not enough free space specified in amanda.conf\n"));
disklow = 1;
}
- else
- fprintf(outf,
- "Holding disk %s: %ld %sB disk space available, using %ld %sB\n",
- hdp->diskdir, fs.avail/unitdivisor, displayunit,
- (fs.avail + hdp->disksize)/unitdivisor, displayunit);
+ else {
+ g_fprintf(outf,
+ _("Holding disk %s: %lld %sB disk space available, using %lld %sB\n"),
+ quoted,
+ (long long)(kb_avail/(off_t)unitdivisor),
+ displayunit,
+ (long long)((kb_avail + holdingdisk_get_disksize(hdp)) / (off_t)unitdivisor),
+ displayunit);
+ }
}
+ amfree(quoted);
}
}
struct stat stat_old;
struct stat statbuf;
- conf_logdir = getconf_str(CNF_LOGDIR);
- if (*conf_logdir == '/') {
- conf_logdir = stralloc(conf_logdir);
- } else {
- conf_logdir = stralloc2(config_dir, conf_logdir);
- }
+ conf_logdir = config_dir_relative(getconf_str(CNF_LOGDIR));
logfile = vstralloc(conf_logdir, "/log", NULL);
+ quoted = quote_string(conf_logdir);
if(stat(conf_logdir, &statbuf) == -1) {
- fprintf(outf, "ERROR: logdir %s: %s, you must create a directory.\n",
- conf_logdir, strerror(errno));
+ g_fprintf(outf, _("ERROR: logdir %s (%s), you must create directory.\n"),
+ quoted, strerror(errno));
disklow = 1;
}
else if(access(conf_logdir, W_OK) == -1) {
- fprintf(outf, "ERROR: log dir %s: not writable\n", conf_logdir);
+ g_fprintf(outf, _("ERROR: log dir %s: not writable\n"), quoted);
logbad = 1;
}
+ amfree(quoted);
if(access(logfile, F_OK) == 0) {
testtape = 0;
- logbad = 1;
- if(access(logfile, W_OK) != 0)
- fprintf(outf, "ERROR: log file %s: not writable\n",
- logfile);
+ logbad = 2;
+ if(access(logfile, W_OK) != 0) {
+ quoted = quote_string(logfile);
+ g_fprintf(outf, _("ERROR: log file %s: not writable\n"), quoted);
+ amfree(quoted);
+ }
}
olddir = vstralloc(conf_logdir, "/oldlog", NULL);
+ quoted = quote_string(olddir);
if (stat(olddir,&stat_old) == 0) { /* oldlog exist */
if(!(S_ISDIR(stat_old.st_mode))) {
- fprintf(outf, "ERROR: oldlog directory \"%s\" is not a directory\n", olddir);
+ g_fprintf(outf, _("ERROR: oldlog directory %s is not a directory\n"),
+ quoted);
+ g_fprintf(outf, _("Remove the entry and create a new directory\n"));
+ logbad = 1;
}
if(access(olddir, W_OK) == -1) {
- fprintf(outf, "ERROR: oldlog dir %s: not writable\n", olddir);
+ g_fprintf(outf, _("ERROR: oldlog dir %s: not writable\n"), quoted);
+ g_fprintf(outf, _("Check permissions\n"));
+ logbad = 1;
}
}
else if(lstat(olddir,&stat_old) == 0) {
- fprintf(outf, "ERROR: oldlog directory \"%s\" is not a directory\n", olddir);
+ g_fprintf(outf, _("ERROR: oldlog directory %s is not a directory\n"),
+ quoted);
+ g_fprintf(outf, _("Remove the entry and create a new directory\n"));
+ logbad = 1;
}
+ amfree(quoted);
if (testtape) {
logfile = newvstralloc(logfile, conf_logdir, "/amdump", NULL);
if (access(logfile, F_OK) == 0) {
testtape = 0;
- logbad = 1;
+ logbad = 2;
}
}
+ amfree(olddir);
amfree(logfile);
amfree(conf_logdir);
}
if (testtape) {
- /* check that the tape is a valid amanda tape */
-
- tapedays = getconf_int(CNF_TAPECYCLE);
- labelstr = getconf_str(CNF_LABELSTR);
- tapename = getconf_str(CNF_TAPEDEV);
-
- if (!getconf_seen(CNF_TPCHANGER) && getconf_int(CNF_RUNTAPES) != 1) {
- fprintf(outf,
- "WARNING: if a tape changer is not available, runtapes must be set to 1\n");
- }
-
- if(changer_init() && (tapename = taper_scan()) == NULL) {
- fprintf(outf, "ERROR: %s\n", changer_resultstr);
- tapebad = 1;
- } else if(tape_access(tapename,F_OK|R_OK|W_OK) == -1) {
- fprintf(outf, "ERROR: %s: %s\n", tapename, strerror(errno));
- tapebad = 1;
- } else if((errstr = tape_rdlabel(tapename, &datestamp, &label)) != NULL) {
- fprintf(outf, "ERROR: %s: %s\n", tapename, errstr);
- tapebad = 1;
- } else if(strcmp(label, FAKE_LABEL) != 0) {
- if(!match(labelstr, label)) {
- fprintf(outf, "ERROR: label %s doesn't match labelstr \"%s\"\n",
- label, labelstr);
- tapebad = 1;
- }
- else {
- tp = lookup_tapelabel(label);
- if(tp == NULL) {
- fprintf(outf, "ERROR: label %s match labelstr but it not listed in the tapelist file.\n", label);
- tapebad = 1;
- }
- else if(tp != NULL && !reusable_tape(tp)) {
- fprintf(outf, "ERROR: cannot overwrite active tape %s\n",
- label);
- tapebad = 1;
- }
- }
-
- }
-
- if(tapebad) {
- tape_t *exptape = lookup_last_reusable_tape(0);
- fprintf(outf, " (expecting ");
- if(exptape != NULL) fprintf(outf, "tape %s or ", exptape->label);
- fprintf(outf, "a new tape)\n");
- }
-
- if(!tapebad && overwrite) {
- if((errstr = tape_writable(tapename)) != NULL) {
- fprintf(outf,
- "ERROR: tape %s label ok, but is not writable\n",
- label);
- tapebad = 1;
- }
- else fprintf(outf, "Tape %s is writable\n", label);
- }
- else fprintf(outf, "NOTE: skipping tape-writable test\n");
-
- if(!tapebad)
- fprintf(outf, "Tape %s label ok\n", label);
+ tapebad = !test_tape_status(outf);
} else if (do_tapechk) {
- fprintf(outf, "WARNING: skipping tape test because amdump or amflush seem to be running\n");
- fprintf(outf, "WARNING: if they are not, you must run amcleanup\n");
+ g_fprintf(outf, _("WARNING: skipping tape test because amdump or amflush seem to be running\n"));
+ g_fprintf(outf, _("WARNING: if they are not, you must run amcleanup\n"));
+ } else if (logbad == 2) {
+ g_fprintf(outf, _("WARNING: amdump or amflush seem to be running\n"));
+ g_fprintf(outf, _("WARNING: if they are not, you must run amcleanup\n"));
} else {
- fprintf(outf, "NOTE: skipping tape checks\n");
+ g_fprintf(outf, _("NOTE: skipping tape checks\n"));
}
/*
conf_runspercycle = getconf_int(CNF_RUNSPERCYCLE);
if(conf_tapecycle <= conf_runspercycle) {
- fprintf(outf, "WARNING: tapecycle (%d) <= runspercycle (%d).\n",
+ g_fprintf(outf, _("WARNING: tapecycle (%d) <= runspercycle (%d).\n"),
conf_tapecycle, conf_runspercycle);
}
- conf_infofile = stralloc(getconf_str(CNF_INFOFILE));
- if (*conf_infofile != '/') {
- char *ci = stralloc2(config_dir, conf_infofile);
- amfree(conf_infofile);
- conf_infofile = ci;
- }
- conf_indexdir = stralloc(getconf_str(CNF_INDEXDIR));
- if (*conf_indexdir != '/') {
- char *ci = stralloc2(config_dir, conf_indexdir);
- amfree(conf_indexdir);
- conf_indexdir = ci;
- }
-#if TEXTDB
+ conf_infofile = config_dir_relative(getconf_str(CNF_INFOFILE));
+ conf_indexdir = config_dir_relative(getconf_str(CNF_INDEXDIR));
+
+ quoted = quote_string(conf_infofile);
if(stat(conf_infofile, &statbuf) == -1) {
- fprintf(outf, "NOTE: info dir %s: does not exist\n", conf_infofile);
- fprintf(outf, "NOTE: it will be created on the next run.\n");
+ if (errno == ENOENT) {
+ g_fprintf(outf, _("NOTE: conf info dir %s does not exist\n"),
+ quoted);
+ g_fprintf(outf, _("NOTE: it will be created on the next run.\n"));
+ } else {
+ g_fprintf(outf, _("ERROR: conf info dir %s (%s)\n"),
+ quoted, strerror(errno));
+ infobad = 1;
+ }
amfree(conf_infofile);
} else if (!S_ISDIR(statbuf.st_mode)) {
- fprintf(outf, "ERROR: info dir %s: not a directory\n", conf_infofile);
+ g_fprintf(outf, _("ERROR: info dir %s: not a directory\n"), quoted);
+ g_fprintf(outf, _("Remove the entry and create a new directory\n"));
amfree(conf_infofile);
infobad = 1;
} else if (access(conf_infofile, W_OK) == -1) {
- fprintf(outf, "ERROR: info dir %s: not writable\n", conf_infofile);
+ g_fprintf(outf, _("ERROR: info dir %s: not writable\n"), quoted);
+ g_fprintf(outf, _("Check permissions\n"));
amfree(conf_infofile);
infobad = 1;
} else {
+ char *errmsg = NULL;
+ if (check_infofile(conf_infofile, &origq, &errmsg) == -1) {
+ g_fprintf(outf, "ERROR: Can't copy infofile: %s\n", errmsg);
+ infobad = 1;
+ amfree(errmsg);
+ }
strappend(conf_infofile, "/");
}
-#endif
- while(!empty(*origqp)) {
- hostp = origqp->head->host;
+ amfree(quoted);
+
+ while(!empty(origq)) {
+ hostp = origq.head->host;
host = sanitise_filename(hostp->hostname);
-#if TEXTDB
if(conf_infofile) {
hostinfodir = newstralloc2(hostinfodir, conf_infofile, host);
+ quoted = quote_string(hostinfodir);
if(stat(hostinfodir, &statbuf) == -1) {
- fprintf(outf, "NOTE: info dir %s: does not exist\n",
- hostinfodir);
- fprintf(outf, "NOTE: it will be created on the next run.\n");
+ if (errno == ENOENT) {
+ g_fprintf(outf, _("NOTE: host info dir %s does not exist\n"),
+ quoted);
+ g_fprintf(outf,
+ _("NOTE: it will be created on the next run.\n"));
+ } else {
+ g_fprintf(outf, _("ERROR: host info dir %s (%s)\n"),
+ quoted, strerror(errno));
+ infobad = 1;
+ }
amfree(hostinfodir);
} else if (!S_ISDIR(statbuf.st_mode)) {
- fprintf(outf, "ERROR: info dir %s: not a directory\n",
- hostinfodir);
+ g_fprintf(outf, _("ERROR: info dir %s: not a directory\n"),
+ quoted);
+ g_fprintf(outf, _("Remove the entry and create a new directory\n"));
amfree(hostinfodir);
infobad = 1;
} else if (access(hostinfodir, W_OK) == -1) {
- fprintf(outf, "ERROR: info dir %s: not writable\n",
- hostinfodir);
+ g_fprintf(outf, _("ERROR: info dir %s: not writable\n"), quoted);
+ g_fprintf(outf, _("Check permissions\n"));
amfree(hostinfodir);
infobad = 1;
} else {
strappend(hostinfodir, "/");
}
+ amfree(quoted);
}
-#endif
for(dp = hostp->disks; dp != NULL; dp = dp->hostnext) {
disk = sanitise_filename(dp->name);
-#if TEXTDB
if(hostinfodir) {
+ char *quotedif;
+
diskdir = newstralloc2(diskdir, hostinfodir, disk);
infofile = vstralloc(diskdir, "/", "info", NULL);
+ quoted = quote_string(diskdir);
+ quotedif = quote_string(infofile);
if(stat(diskdir, &statbuf) == -1) {
- fprintf(outf, "NOTE: info dir %s: does not exist\n",
- diskdir);
- fprintf(outf, "NOTE: it will be created on the next run.\n");
+ if (errno == ENOENT) {
+ g_fprintf(outf, _("NOTE: info dir %s does not exist\n"),
+ quoted);
+ g_fprintf(outf,
+ _("NOTE: it will be created on the next run.\n"));
+ } else {
+ g_fprintf(outf, _("ERROR: info dir %s (%s)\n"),
+ quoted, strerror(errno));
+ infobad = 1;
+ }
} else if (!S_ISDIR(statbuf.st_mode)) {
- fprintf(outf, "ERROR: info dir %s: not a directory\n",
- diskdir);
+ g_fprintf(outf, _("ERROR: info dir %s: not a directory\n"),
+ quoted);
+ g_fprintf(outf, _("Remove the entry and create a new directory\n"));
infobad = 1;
} else if (access(diskdir, W_OK) == -1) {
- fprintf(outf, "ERROR: info dir %s: not writable\n",
- diskdir);
+ g_fprintf(outf, _("ERROR: info dir %s: not writable\n"),
+ quoted);
+ g_fprintf(outf,_("Check permissions\n"));
infobad = 1;
} else if(stat(infofile, &statbuf) == -1) {
- fprintf(outf, "WARNING: info file %s: does not exist\n",
- infofile);
- fprintf(outf, "NOTE: it will be created on the next run.\n");
+ if (errno == ENOENT) {
+ g_fprintf(outf, _("NOTE: info file %s does not exist\n"),
+ quotedif);
+ g_fprintf(outf, _("NOTE: it will be created on the next run.\n"));
+ } else {
+ g_fprintf(outf, _("ERROR: info dir %s (%s)\n"),
+ quoted, strerror(errno));
+ infobad = 1;
+ }
} else if (!S_ISREG(statbuf.st_mode)) {
- fprintf(outf, "ERROR: info file %s: not a file\n",
- infofile);
+ g_fprintf(outf, _("ERROR: info file %s: not a file\n"),
+ quotedif);
+ g_fprintf(outf, _("Remove the entry and create a new file\n"));
infobad = 1;
} else if (access(infofile, R_OK) == -1) {
- fprintf(outf, "ERROR: info file %s: not readable\n",
- infofile);
+ g_fprintf(outf, _("ERROR: info file %s: not readable\n"),
+ quotedif);
infobad = 1;
}
+ amfree(quotedif);
+ amfree(quoted);
amfree(infofile);
}
-#endif
if(dp->index) {
if(! indexdir_checked) {
+ quoted = quote_string(conf_indexdir);
if(stat(conf_indexdir, &statbuf) == -1) {
- fprintf(outf, "NOTE: index dir %s: does not exist\n",
- conf_indexdir);
- fprintf(outf, "NOTE: it will be created on the next run.\n");
+ if (errno == ENOENT) {
+ g_fprintf(outf, _("NOTE: index dir %s does not exist\n"),
+ quoted);
+ g_fprintf(outf, _("NOTE: it will be created on the next run.\n"));
+ } else {
+ g_fprintf(outf, _("ERROR: index dir %s (%s)\n"),
+ quoted, strerror(errno));
+ indexbad = 1;
+ }
amfree(conf_indexdir);
} else if (!S_ISDIR(statbuf.st_mode)) {
- fprintf(outf, "ERROR: index dir %s: not a directory\n",
- conf_indexdir);
+ g_fprintf(outf, _("ERROR: index dir %s: not a directory\n"),
+ quoted);
+ g_fprintf(outf, _("Remove the entry and create a new directory\n"));
amfree(conf_indexdir);
indexbad = 1;
} else if (access(conf_indexdir, W_OK) == -1) {
- fprintf(outf, "ERROR: index dir %s: not writable\n",
- conf_indexdir);
+ g_fprintf(outf, _("ERROR: index dir %s: not writable\n"),
+ quoted);
amfree(conf_indexdir);
indexbad = 1;
} else {
strappend(conf_indexdir, "/");
}
indexdir_checked = 1;
+ amfree(quoted);
}
if(conf_indexdir) {
if(! hostindexdir_checked) {
hostindexdir = stralloc2(conf_indexdir, host);
+ quoted = quote_string(hostindexdir);
if(stat(hostindexdir, &statbuf) == -1) {
- fprintf(outf, "NOTE: index dir %s: does not exist\n",
- hostindexdir);
- fprintf(outf, "NOTE: it will be created on the next run.\n");
+ if (errno == ENOENT) {
+ g_fprintf(outf, _("NOTE: index dir %s does not exist\n"),
+ quoted);
+ g_fprintf(outf, _("NOTE: it will be created on the next run.\n"));
+ } else {
+ g_fprintf(outf, _("ERROR: index dir %s (%s)\n"),
+ quoted, strerror(errno));
+ indexbad = 1;
+ }
amfree(hostindexdir);
} else if (!S_ISDIR(statbuf.st_mode)) {
- fprintf(outf, "ERROR: index dir %s: not a directory\n",
- hostindexdir);
+ g_fprintf(outf, _("ERROR: index dir %s: not a directory\n"),
+ quoted);
+ g_fprintf(outf, _("Remove the entry and create a new directory\n"));
amfree(hostindexdir);
indexbad = 1;
} else if (access(hostindexdir, W_OK) == -1) {
- fprintf(outf, "ERROR: index dir %s: not writable\n",
- hostindexdir);
+ g_fprintf(outf, _("ERROR: index dir %s: not writable\n"),
+ quoted);
amfree(hostindexdir);
indexbad = 1;
} else {
strappend(hostindexdir, "/");
}
hostindexdir_checked = 1;
+ amfree(quoted);
}
if(hostindexdir) {
diskdir = newstralloc2(diskdir, hostindexdir, disk);
+ quoted = quote_string(diskdir);
if(stat(diskdir, &statbuf) == -1) {
- fprintf(outf, "NOTE: index dir %s: does not exist\n",
- diskdir);
- fprintf(outf, "NOTE: it will be created on the next run.\n");
+ if (errno == ENOENT) {
+ g_fprintf(outf, _("NOTE: index dir %s does not exist\n"),
+ quoted);
+ g_fprintf(outf, _("NOTE: it will be created on the next run.\n"));
+ } else {
+ g_fprintf(outf, _("ERROR: index dir %s (%s)\n"),
+ quoted, strerror(errno));
+ indexbad = 1;
+ }
} else if (!S_ISDIR(statbuf.st_mode)) {
- fprintf(outf, "ERROR: index dir %s: not a directory\n",
- diskdir);
+ g_fprintf(outf, _("ERROR: index dir %s: not a directory\n"),
+ quoted);
+ g_fprintf(outf, _("Remove the entry and create a new directory\n"));
indexbad = 1;
} else if (access(diskdir, W_OK) == -1) {
- fprintf(outf, "ERROR: index dir %s: is not writable\n",
- diskdir);
+ g_fprintf(outf, _("ERROR: index dir %s: is not writable\n"),
+ quoted);
indexbad = 1;
}
+ amfree(quoted);
}
}
}
+
+ if ( dp->encrypt == ENCRYPT_SERV_CUST ) {
+ if ( dp->srv_encrypt[0] == '\0' ) {
+ g_fprintf(outf, _("ERROR: server encryption program not specified\n"));
+ g_fprintf(outf, _("Specify \"server_custom_encrypt\" in the dumptype\n"));
+ pgmbad = 1;
+ }
+ else if(access(dp->srv_encrypt, X_OK) == -1) {
+ g_fprintf(outf, _("ERROR: %s is not executable, server encryption will not work\n"),
+ dp->srv_encrypt );
+ g_fprintf(outf, _("Check file type\n"));
+ pgmbad = 1;
+ }
+ }
+ if ( dp->compress == COMP_SERVER_CUST ) {
+ if ( dp->srvcompprog[0] == '\0' ) {
+ g_fprintf(outf, _("ERROR: server custom compression program "
+ "not specified\n"));
+ g_fprintf(outf, _("Specify \"server_custom_compress\" in "
+ "the dumptype\n"));
+ pgmbad = 1;
+ }
+ else if(access(dp->srvcompprog, X_OK) == -1) {
+ quoted = quote_string(dp->srvcompprog);
+
+ g_fprintf(outf, _("ERROR: %s is not executable, server custom "
+ "compression will not work\n"),
+ quoted);
+ amfree(quoted);
+ g_fprintf(outf, _("Check file type\n"));
+ pgmbad = 1;
+ }
+ }
+
+ /* check tape_splitsize */
+ tape_size = tapetype_get_length(tp);
+ if (dp->tape_splitsize > tape_size) {
+ g_fprintf(outf,
+ _("ERROR: %s %s: tape_splitsize > tape size\n"),
+ hostp->hostname, dp->name);
+ pgmbad = 1;
+ }
+ if (dp->fallback_splitsize * 1024 > physmem_total()) {
+ g_fprintf(outf,
+ _("ERROR: %s %s: fallback_splitsize > total available memory\n"),
+ hostp->hostname, dp->name);
+ pgmbad = 1;
+ }
+ if (dp->fallback_splitsize > tape_size) {
+ g_fprintf(outf,
+ _("ERROR: %s %s: fallback_splitsize > tape size\n"),
+ hostp->hostname, dp->name);
+ pgmbad = 1;
+ }
amfree(disk);
- remove_disk(origqp, dp);
+ remove_disk(&origq, dp);
}
amfree(host);
amfree(hostindexdir);
}
amfree(datestamp);
- amfree(label);
- amfree(config_dir);
- amfree(config_name);
- fprintf(outf, "Server check took %s seconds\n", walltime_str(curclock()));
+ g_fprintf(outf, _("Server check took %s seconds\n"), walltime_str(curclock()));
fflush(outf);
- malloc_size_2 = malloc_inuse(&malloc_hist_2);
-
- if(malloc_size_1 != malloc_size_2) {
- malloc_list(fd, malloc_hist_1, malloc_hist_2);
- }
-
exit(userbad \
|| confbad \
|| tapebad \
|| infobad \
|| indexbad \
|| pgmbad);
- /* NOTREACHED */
+ /*NOTREACHED*/
return 0;
}
int remote_errors;
FILE *outf;
-int amanda_port;
-
-#ifdef KRB4_SECURITY
-int kamanda_port;
-#endif
-static void handle_response P((proto_t *p, pkt_t *pkt));
+static void handle_result(void *, pkt_t *, security_handle_t *);
+void start_host(am_host_t *hostp);
#define HOST_READY ((void *)0) /* must be 0 */
#define HOST_ACTIVE ((void *)1)
#define DISK_ACTIVE ((void *)1)
#define DISK_DONE ((void *)2)
-int start_host(hostp)
- am_host_t *hostp;
+void
+start_host(
+ am_host_t *hostp)
{
disk_t *dp;
char *req = NULL;
- int req_len = 0;
- int rc;
+ size_t req_len = 0;
int disk_count;
+ const security_driver_t *secdrv;
char number[NUM_STR_SIZE];
if(hostp->up != HOST_READY) {
- return 0;
+ return;
}
- if (strncmp (hostp->hostname,"localhost",9) == 0) {
- fprintf(outf,
- "WARNING: Usage of fully qualified hostname recommended for Client %s.\n",
+ if (strcmp(hostp->hostname,"localhost") == 0) {
+ g_fprintf(outf,
+ _("WARNING: Usage of fully qualified hostname recommended for Client %s.\n"),
hostp->hostname);
}
fe_req_options_hostname);
int has_maxdumps = am_has_feature(hostp->features,
fe_req_options_maxdumps);
+ int has_config = am_has_feature(hostp->features,
+ fe_req_options_config);
if(!am_has_feature(hostp->features, fe_selfcheck_req) &&
!am_has_feature(hostp->features, fe_selfcheck_req_device)) {
- fprintf(outf,
- "ERROR: Client %s does not support selfcheck REQ packet.\n",
+ g_fprintf(outf,
+ _("ERROR: Client %s does not support selfcheck REQ packet.\n"),
hostp->hostname);
+ g_fprintf(outf, _("Client might be of a very old version\n"));
}
if(!am_has_feature(hostp->features, fe_selfcheck_rep)) {
- fprintf(outf,
- "ERROR: Client %s does not support selfcheck REP packet.\n",
+ g_fprintf(outf,
+ _("ERROR: Client %s does not support selfcheck REP packet.\n"),
hostp->hostname);
+ g_fprintf(outf, _("Client might be of a very old version\n"));
}
if(!am_has_feature(hostp->features, fe_sendsize_req_options) &&
!am_has_feature(hostp->features, fe_sendsize_req_no_options) &&
!am_has_feature(hostp->features, fe_sendsize_req_device)) {
- fprintf(outf,
- "ERROR: Client %s does not support sendsize REQ packet.\n",
+ g_fprintf(outf,
+ _("ERROR: Client %s does not support sendsize REQ packet.\n"),
hostp->hostname);
+ g_fprintf(outf, _("Client might be of a very old version\n"));
}
if(!am_has_feature(hostp->features, fe_sendsize_rep)) {
- fprintf(outf,
- "ERROR: Client %s does not support sendsize REP packet.\n",
+ g_fprintf(outf,
+ _("ERROR: Client %s does not support sendsize REP packet.\n"),
hostp->hostname);
+ g_fprintf(outf, _("Client might be of a very old version\n"));
}
if(!am_has_feature(hostp->features, fe_sendbackup_req) &&
!am_has_feature(hostp->features, fe_sendbackup_req_device)) {
- fprintf(outf,
- "ERROR: Client %s does not support sendbackup REQ packet.\n",
+ g_fprintf(outf,
+ _("ERROR: Client %s does not support sendbackup REQ packet.\n"),
hostp->hostname);
+ g_fprintf(outf, _("Client might be of a very old version\n"));
}
if(!am_has_feature(hostp->features, fe_sendbackup_rep)) {
- fprintf(outf,
- "ERROR: Client %s does not support sendbackup REP packet.\n",
+ g_fprintf(outf,
+ _("ERROR: Client %s does not support sendbackup REP packet.\n"),
hostp->hostname);
+ g_fprintf(outf, _("Client might be of a very old version\n"));
}
- ap_snprintf(number, sizeof(number), "%d", hostp->maxdumps);
+ g_snprintf(number, SIZEOF(number), "%d", hostp->maxdumps);
req = vstralloc("SERVICE ", "selfcheck", "\n",
"OPTIONS ",
has_features ? "features=" : "",
has_hostname ? "hostname=" : "",
has_hostname ? hostp->hostname : "",
has_hostname ? ";" : "",
+ has_config ? "config=" : "",
+ has_config ? get_config_name() : "",
+ has_config ? ";" : "",
"\n",
NULL);
req_len = strlen(req);
- req_len += 128; /* room for SECURITY ... */
- req_len += 256; /* room for non-disk answers */
+ req_len += 128; /* room for SECURITY ... */
+ req_len += 256; /* room for non-disk answers */
for(dp = hostp->disks; dp != NULL; dp = dp->hostnext) {
char *l;
- int l_len;
+ size_t l_len;
char *o;
- char* calcsize;
-
- if(dp->todo == 0) continue;
+ char *calcsize;
+ char *qname, *b64disk;
+ char *qdevice, *b64device = NULL;
- if(dp->up != DISK_READY) {
+ if(dp->up != DISK_READY || dp->todo != 1) {
+ continue;
+ }
+ if (am_has_feature(hostp->features, fe_req_xml))
+ o = xml_optionstr(dp, hostp->features, outf, 0);
+ else
+ o = optionstr(dp, hostp->features, outf);
+ if (o == NULL) {
+ remote_errors++;
continue;
}
- o = optionstr(dp, hostp->features, outf);
+ qname = quote_string(dp->name);
+ b64disk = amxml_format_tag("disk", dp->name);
+ qdevice = quote_string(dp->device);
+ if (dp->device)
+ b64device = amxml_format_tag("diskdevice", dp->device);
+ if ((dp->name && qname[0] == '"') ||
+ (dp->device && qdevice[0] == '"')) {
+ if(!am_has_feature(hostp->features, fe_interface_quoted_text)) {
+ g_fprintf(outf,
+ _("WARNING: %s:%s:%s host does not support quoted text\n"),
+ hostp->hostname, qname, qdevice);
+ g_fprintf(outf, _("You must upgrade amanda on the client to "
+ "specify a quoted text/device in the disklist, "
+ "or don't use quoted text for the device.\n"));
+ }
+ }
if(dp->device) {
if(!am_has_feature(hostp->features, fe_selfcheck_req_device)) {
- fprintf(outf,
- "ERROR: %s:%s (%s): selfcheck does not support device.\n",
- hostp->hostname, dp->name, dp->device);
+ g_fprintf(outf,
+ _("ERROR: %s:%s (%s): selfcheck does not support device.\n"),
+ hostp->hostname, qname, dp->device);
+ g_fprintf(outf, _("You must upgrade amanda on the client to "
+ "specify a diskdevice in the disklist "
+ "or don't specify a diskdevice in the disklist.\n"));
}
if(!am_has_feature(hostp->features, fe_sendsize_req_device)) {
- fprintf(outf,
- "ERROR: %s:%s (%s): sendsize does not support device.\n",
- hostp->hostname, dp->name, dp->device);
+ g_fprintf(outf,
+ _("ERROR: %s:%s (%s): sendsize does not support device.\n"),
+ hostp->hostname, qname, dp->device);
+ g_fprintf(outf, _("You must upgrade amanda on the client to "
+ "specify a diskdevice in the disklist"
+ " or don't specify a diskdevice in the disklist.\n"));
}
if(!am_has_feature(hostp->features, fe_sendbackup_req_device)) {
- fprintf(outf,
- "ERROR: %s:%s (%s): sendbackup does not support device.\n",
- hostp->hostname, dp->name, dp->device);
+ g_fprintf(outf,
+ _("ERROR: %s:%s (%s): sendbackup does not support device.\n"),
+ hostp->hostname, qname, dp->device);
+ g_fprintf(outf, _("You must upgrade amanda on the client to "
+ "specify a diskdevice in the disklist"
+ " or don't specify a diskdevice in the disklist.\n"));
}
}
- if(strcmp(dp->program, "DUMP") == 0 &&
- !am_has_feature(hostp->features, fe_program_dump)) {
- fprintf(outf, "ERROR: %s:%s does not support DUMP.\n",
- hostp->hostname, dp->name);
- }
- if(strcmp(dp->program, "GNUTAR") == 0 &&
- !am_has_feature(hostp->features, fe_program_gnutar)) {
- fprintf(outf, "ERROR: %s:%s does not support GNUTAR.\n",
- hostp->hostname, dp->name);
- }
- if(dp->estimate == ES_CALCSIZE &&
- !am_has_feature(hostp->features, fe_calcsize_estimate)) {
- fprintf(outf, "ERROR: %s:%s does not support CALCSIZE for estimate, using CLIENT.\n",
- hostp->hostname, dp->name);
- dp->estimate = ES_CLIENT;
+ if (dp->program &&
+ (strcmp(dp->program,"DUMP") == 0 ||
+ strcmp(dp->program,"GNUTAR") == 0)) {
+ if(strcmp(dp->program, "DUMP") == 0 &&
+ !am_has_feature(hostp->features, fe_program_dump)) {
+ g_fprintf(outf, _("ERROR: %s:%s does not support DUMP.\n"),
+ hostp->hostname, qname);
+ g_fprintf(outf, _("You must upgrade amanda on the client to use DUMP "
+ "or you can use another program.\n"));
+ }
+ if(strcmp(dp->program, "GNUTAR") == 0 &&
+ !am_has_feature(hostp->features, fe_program_gnutar)) {
+ g_fprintf(outf, _("ERROR: %s:%s does not support GNUTAR.\n"),
+ hostp->hostname, qname);
+ g_fprintf(outf, _("You must upgrade amanda on the client to use GNUTAR "
+ "or you can use another program.\n"));
+ }
+ if(dp->estimate == ES_CALCSIZE &&
+ !am_has_feature(hostp->features, fe_calcsize_estimate)) {
+ g_fprintf(outf, _("ERROR: %s:%s does not support CALCSIZE for "
+ "estimate, using CLIENT.\n"),
+ hostp->hostname, qname);
+ g_fprintf(outf, _("You must upgrade amanda on the client to use "
+ "CALCSIZE for estimate or don't use CALCSIZE for estimate.\n"));
+ dp->estimate = ES_CLIENT;
+ }
+ if(dp->estimate == ES_CALCSIZE &&
+ am_has_feature(hostp->features, fe_selfcheck_calcsize))
+ calcsize = "CALCSIZE ";
+ else
+ calcsize = "";
+
+ if(dp->compress == COMP_CUST &&
+ !am_has_feature(hostp->features, fe_options_compress_cust)) {
+ g_fprintf(outf,
+ _("ERROR: Client %s does not support custom compression.\n"),
+ hostp->hostname);
+ g_fprintf(outf, _("You must upgrade amanda on the client to "
+ "use custom compression\n"));
+ g_fprintf(outf, _("Otherwise you can use the default client "
+ "compression program.\n"));
+ }
+ if(dp->encrypt == ENCRYPT_CUST ) {
+ if ( !am_has_feature(hostp->features, fe_options_encrypt_cust)) {
+ g_fprintf(outf,
+ _("ERROR: Client %s does not support data encryption.\n"),
+ hostp->hostname);
+ g_fprintf(outf, _("You must upgrade amanda on the client to use encryption program.\n"));
+ remote_errors++;
+ } else if ( dp->compress == COMP_SERVER_FAST ||
+ dp->compress == COMP_SERVER_BEST ||
+ dp->compress == COMP_SERVER_CUST ) {
+ g_fprintf(outf,
+ _("ERROR: %s: Client encryption with server compression "
+ "is not supported. See amanda.conf(5) for detail.\n"),
+ hostp->hostname);
+ remote_errors++;
+ }
+ }
+ if (am_has_feature(hostp->features, fe_req_xml)) {
+ l = vstralloc("<dle>\n"
+ " <program>",
+ dp->program,
+ "</program>\n", NULL);
+ if (strlen(calcsize) > 0)
+ vstrextend(&l, " <calcsize>YES</calcsize>\n", NULL);
+ vstrextend(&l, " ", b64disk, "\n", NULL);
+ if (dp->device)
+ vstrextend(&l, " ", b64device, "\n", NULL);
+ vstrextend(&l, o, "</dle>\n", NULL);
+ } else {
+ if (dp->device) {
+ l = vstralloc(calcsize,
+ dp->program, " ",
+ qname, " ",
+ qdevice,
+ " 0 OPTIONS |",
+ o,
+ "\n",
+ NULL);
+ } else {
+ l = vstralloc(calcsize,
+ dp->program, " ",
+ qname,
+ " 0 OPTIONS |",
+ o,
+ "\n",
+ NULL);
+ }
+ }
+ } else {
+ if (!am_has_feature(hostp->features, fe_program_application_api) ||
+ !am_has_feature(hostp->features, fe_req_xml)) {
+ g_fprintf(outf, _("ERROR: %s:%s does not support APPLICATION-API.\n"),
+ hostp->hostname, qname);
+ g_fprintf(outf, _("Dumptype configuration is not GNUTAR or DUMP."
+ " It is case sensitive\n"));
+ l = stralloc("");
+ } else {
+ l = vstralloc("<dle>\n"
+ " <program>APPLICATION</program>\n", NULL);
+ if (dp->application) {
+ char *xml_app = xml_application(dp->application,
+ hostp->features);
+ vstrextend(&l, xml_app, NULL);
+ amfree(xml_app);
+ }
+ if (dp->pp_scriptlist) {
+ if (!am_has_feature(hostp->features, fe_pp_script)) {
+ g_fprintf(outf,
+ _("ERROR: %s:%s does not support SCRIPT-API.\n"),
+ hostp->hostname, qname);
+ }
+ }
+ vstrextend(&l, " ", b64disk, "\n", NULL);
+ if (dp->device)
+ vstrextend(&l, " ", b64device, "\n", NULL);
+ vstrextend(&l, o, "</dle>\n", NULL);
+ }
}
-
- if(dp->estimate == ES_CALCSIZE &&
- am_has_feature(hostp->features, fe_selfcheck_calcsize))
- calcsize = "CALCSIZE ";
- else
- calcsize = "";
-
- l = vstralloc(calcsize,
- dp->program, " ",
- dp->name, " ",
- dp->device ? dp->device : "",
- " 0 OPTIONS |",
- o,
- "\n",
- NULL);
+ amfree(qname);
+ amfree(qdevice);
l_len = strlen(l);
amfree(o);
- /*
- * Allow 2X for error response in return packet.
- */
- if(req_len + l_len > MAX_DGRAM / 2) {
- amfree(l);
- break;
- }
+
strappend(req, l);
req_len += l_len;
amfree(l);
dp->up = DISK_ACTIVE;
disk_count++;
}
-
}
else { /* noop service */
req = vstralloc("SERVICE ", "noop", "\n",
"\n",
NULL);
for(dp = hostp->disks; dp != NULL; dp = dp->hostnext) {
- if(dp->todo == 0) continue;
-
- if(dp->up != DISK_READY) {
+ if(dp->up != DISK_READY || dp->todo != 1) {
continue;
}
disk_count++;
}
}
+
if(disk_count == 0) {
amfree(req);
hostp->up = HOST_DONE;
- return 0;
+ return;
}
-#ifdef KRB4_SECURITY
- if(hostp->disks->auth == AUTH_KRB4)
- rc = make_krb_request(hostp->hostname, kamanda_port, req,
- hostp, conf_ctimeout, handle_response);
- else
-#endif
- rc = make_request(hostp->hostname, amanda_port, req,
- hostp, conf_ctimeout, handle_response);
-
- req = NULL; /* do not own this any more */
-
- if(rc) {
- /* couldn't resolve hostname */
- fprintf(outf,
- "ERROR: %s: could not resolve hostname\n", hostp->hostname);
- remote_errors++;
- hostp->up = HOST_DONE;
+ secdrv = security_getdriver(hostp->disks->security_driver);
+ if (secdrv == NULL) {
+ fprintf(stderr, _("Could not find security driver \"%s\" for host \"%s\". auth for this dle is invalid\n"),
+ hostp->disks->security_driver, hostp->hostname);
} else {
- hostp->up = HOST_ACTIVE;
+ protocol_sendreq(hostp->hostname, secdrv, amhost_get_security_conf,
+ req, conf_ctimeout, handle_result, hostp);
}
- return 1;
+
+ amfree(req);
+
+ hostp->up = HOST_ACTIVE;
}
-int start_client_checks(fd)
-int fd;
+pid_t
+start_client_checks(
+ int fd)
{
am_host_t *hostp;
- disk_t *dp;
- int hostcount, pid;
- struct servent *amandad;
+ disk_t *dp, *dp1;
+ int hostcount;
+ pid_t pid;
int userbad = 0;
switch(pid = fork()) {
- case -1: error("could not fork client check: %s", strerror(errno));
- case 0: break;
+ case -1:
+ error(_("INTERNAL ERROR:could not fork client check: %s"), strerror(errno));
+ /*NOTREACHED*/
+
+ case 0:
+ break;
+
default:
return pid;
}
startclock();
- if((outf = fdopen(fd, "w")) == NULL)
- error("fdopen %d: %s", fd, strerror(errno));
+ if((outf = fdopen(fd, "w")) == NULL) {
+ error(_("fdopen %d: %s"), fd, strerror(errno));
+ /*NOTREACHED*/
+ }
errf = outf;
- fprintf(outf, "\nAmanda Backup Client Hosts Check\n");
- fprintf(outf, "--------------------------------\n");
+ g_fprintf(outf, _("\nAmanda Backup Client Hosts Check\n"));
+ g_fprintf(outf, "--------------------------------\n");
-#ifdef KRB4_SECURITY
- kerberos_service_init();
-#endif
-
- proto_init(msg->socket, time(0), 1024);
-
- /* get remote service port */
- if((amandad = getservbyname(AMANDA_SERVICE_NAME, "udp")) == NULL)
- amanda_port = AMANDA_SERVICE_DEFAULT;
- else
- amanda_port = ntohs(amandad->s_port);
-
-#ifdef KRB4_SECURITY
- if((amandad = getservbyname(KAMANDA_SERVICE_NAME, "udp")) == NULL)
- kamanda_port = KAMANDA_SERVICE_DEFAULT;
- else
- kamanda_port = ntohs(amandad->s_port);
-#endif
+ protocol_init();
hostcount = remote_errors = 0;
- for(dp = origqp->head; dp != NULL; dp = dp->next) {
+ for(dp = origq.head; dp != NULL; dp = dp->next) {
hostp = dp->host;
- if(hostp->up == HOST_READY) {
- if(start_host(hostp) == 1) {
- hostcount++;
- check_protocol();
+ if(hostp->up == HOST_READY && dp->todo == 1) {
+ for(dp1 = hostp->disks; dp1 != NULL; dp1 = dp1->hostnext) {
+ run_server_scripts(EXECUTE_ON_PRE_HOST_AMCHECK,
+ get_config_name(), dp1, -1);
+ }
+ for(dp1 = hostp->disks; dp1 != NULL; dp1 = dp1->hostnext) {
+ run_server_scripts(EXECUTE_ON_PRE_DLE_AMCHECK,
+ get_config_name(), dp1, -1);
}
+ start_host(hostp);
+ hostcount++;
+ protocol_check();
}
}
- run_protocol();
- amfree(msg);
+ protocol_run();
- fprintf(outf,
- "Client check: %d host%s checked in %s seconds, %d problem%s found\n",
- hostcount, (hostcount == 1) ? "" : "s",
- walltime_str(curclock()),
- remote_errors, (remote_errors == 1) ? "" : "s");
+ g_fprintf(outf, plural(_("Client check: %d host checked in %s seconds."),
+ _("Client check: %d hosts checked in %s seconds."),
+ hostcount),
+ hostcount, walltime_str(curclock()));
+ g_fprintf(outf, plural(_(" %d problem found.\n"),
+ _(" %d problems found.\n"), remote_errors),
+ remote_errors);
fflush(outf);
- amfree(config_dir);
- amfree(config_name);
-
- malloc_size_2 = malloc_inuse(&malloc_hist_2);
-
- if(malloc_size_1 != malloc_size_2) {
- malloc_list(fd, malloc_hist_1, malloc_hist_2);
- }
-
exit(userbad || remote_errors > 0);
- /* NOTREACHED */
+ /*NOTREACHED*/
return 0;
}
-static void handle_response(p, pkt)
-proto_t *p;
-pkt_t *pkt;
+static void
+handle_result(
+ void * datap,
+ pkt_t * pkt,
+ security_handle_t * sech)
{
am_host_t *hostp;
disk_t *dp;
int ch;
int tch;
- hostp = (am_host_t *) p->datap;
+ hostp = (am_host_t *)datap;
hostp->up = HOST_READY;
- if(p->state == S_FAILED && pkt == NULL) {
- if(p->prevstate == S_REPWAIT) {
- fprintf(outf,
- "WARNING: %s: selfcheck reply timed out.\n",
- hostp->hostname);
- }
- else {
- fprintf(outf,
- "WARNING: %s: selfcheck request timed out. Host down?\n",
- hostp->hostname);
- }
+ if (pkt == NULL) {
+ g_fprintf(outf,
+ _("WARNING: %s: selfcheck request failed: %s\n"), hostp->hostname,
+ security_geterror(sech));
remote_errors++;
hostp->up = HOST_DONE;
return;
}
-#ifdef KRB4_SECURITY
- if(hostp->disks->auth == AUTH_KRB4 &&
- !check_mutual_authenticator(host2key(hostp->hostname), pkt, p)) {
- fprintf(outf, "ERROR: %s [mutual-authentication failed]\n",
- hostp->hostname);
- remote_errors++;
- hostp->up = HOST_DONE;
- return;
- }
-#endif
-
#if 0
- fprintf(errf, "got %sresponse from %s:\n----\n%s----\n\n",
- (p->state == S_FAILED) ? "NAK " : "", hostp->hostname, pkt->body);
+ g_fprintf(errf, _("got response from %s:\n----\n%s----\n\n"),
+ hostp->hostname, pkt->body);
#endif
s = pkt->body;
ch = *s++;
while(ch) {
line = s - 1;
- skip_line(s, ch);
+ skip_quoted_line(s, ch);
if (s[-2] == '\n') {
s[-2] = '\0';
}
-#define sc "OPTIONS "
- if(strncmp(line, sc, sizeof(sc)-1) == 0) {
-#undef sc
+ if(strncmp_const(line, "OPTIONS ") == 0) {
-#define sc "features="
- t = strstr(line, sc);
- if(t != NULL && (isspace((int)t[-1]) || t[-1] == ';')) {
- t += sizeof(sc)-1;
-#undef sc
+ t = strstr(line, "features=");
+ if(t != NULL && (g_ascii_isspace((int)t[-1]) || t[-1] == ';')) {
+ char *u = strchr(t, ';');
+ if (u)
+ *u = '\0';
+ t += SIZEOF("features=")-1;
am_release_feature_set(hostp->features);
if((hostp->features = am_string_to_feature(t)) == NULL) {
- fprintf(outf, "ERROR: %s: bad features value: %s\n",
- hostp->hostname, line);
+ g_fprintf(outf, _("ERROR: %s: bad features value: '%s'\n"),
+ hostp->hostname, t);
+ g_fprintf(outf, _("The amfeature in the reply packet is invalid\n"));
+ remote_errors++;
+ hostp->up = HOST_DONE;
}
+ if (u)
+ *u = ';';
}
continue;
}
-#define sc "OK "
- if(strncmp(line, sc, sizeof(sc)-1) == 0) {
-#undef sc
+ if(strncmp_const(line, "OK ") == 0) {
continue;
}
-#define sc "ERROR "
- if(strncmp(line, sc, sizeof(sc)-1) == 0) {
- t = line + sizeof(sc)-1;
- tch = t[-1];
-#undef sc
-
+ t = line;
+ if(strncmp_const_skip(line, "ERROR ", t, tch) == 0) {
skip_whitespace(t, tch);
/*
* If the "error" is that the "noop" service is unknown, it
* just means the client is "old" (does not support the service).
* We can ignore this.
*/
- if(hostp->features == NULL
- && p->state == S_FAILED
- && (strcmp(t - 1, "unknown service: noop") == 0
- || strcmp(t - 1, "noop: invalid service") == 0)) {
- } else {
- fprintf(outf, "ERROR: %s%s: %s\n",
- (p->state == S_FAILED) ? "NAK " : "",
- hostp->hostname,
- t - 1);
+ if(!((hostp->features == NULL) && (pkt->type == P_NAK)
+ && ((strcmp(t - 1, "unknown service: noop") == 0)
+ || (strcmp(t - 1, "noop: invalid service") == 0)))) {
+ g_fprintf(outf, _("ERROR: %s%s: %s\n"),
+ (pkt->type == P_NAK) ? "NAK " : "",
+ hostp->hostname,
+ t - 1);
remote_errors++;
hostp->up = HOST_DONE;
}
continue;
}
- fprintf(outf, "ERROR: %s: unknown response: %s\n",
+ g_fprintf(outf, _("ERROR: %s: unknown response: %s\n"),
hostp->hostname, line);
remote_errors++;
hostp->up = HOST_DONE;
* The client does not support the features list, so give it an
* empty one.
*/
- dbprintf(("%s: no feature set from host %s\n",
- debug_prefix_time(NULL), hostp->hostname));
+ dbprintf(_("no feature set from host %s\n"), hostp->hostname);
hostp->features = am_set_default_feature_set();
}
for(dp = hostp->disks; dp != NULL; dp = dp->hostnext) {
}
}
start_host(hostp);
+ if(hostp->up == HOST_DONE) {
+ security_close_connection(sech, hostp->hostname);
+ for(dp = hostp->disks; dp != NULL; dp = dp->hostnext) {
+ run_server_scripts(EXECUTE_ON_POST_DLE_AMCHECK,
+ get_config_name(), dp, -1);
+ }
+ for(dp = hostp->disks; dp != NULL; dp = dp->hostnext) {
+ run_server_scripts(EXECUTE_ON_POST_HOST_AMCHECK,
+ get_config_name(), dp, -1);
+ }
+ }
+ /* try to clean up any defunct processes, since Amanda doesn't wait() for
+ them explicitly */
+ while(waitpid(-1, NULL, WNOHANG)> 0);
}