From: Daniel Dehennin <daniel.dehennin@ac-dijon.fr>
Date: Tue, 16 Oct 2018 14:30:39 +0200
Subject: Add check-bareos-plugin

---
 check_bareos/Makefile.in           |  93 +++++++++
 check_bareos/README                |  15 ++
 check_bareos/authenticate.c        | 176 +++++++++++++++++
 check_bareos/check_bareos.c        | 373 +++++++++++++++++++++++++++++++++++++
 check_bareos/check_bareos.h        | 115 ++++++++++++
 check_bareos/check_bareos_pools.sh | 159 ++++++++++++++++
 configure                          |   6 +-
 7 files changed, 936 insertions(+), 1 deletion(-)
 create mode 100644 check_bareos/Makefile.in
 create mode 100644 check_bareos/README
 create mode 100644 check_bareos/authenticate.c
 create mode 100644 check_bareos/check_bareos.c
 create mode 100644 check_bareos/check_bareos.h
 create mode 100644 check_bareos/check_bareos_pools.sh

diff --git a/check_bareos/Makefile.in b/check_bareos/Makefile.in
new file mode 100644
index 0000000..3637c32
--- /dev/null
+++ b/check_bareos/Makefile.in
@@ -0,0 +1,93 @@
+#
+#  Version $Id: Makefile.in,v 1.4 2004/09/25 10:19:59 nboichat Exp $
+#
+@MCOMMON@
+
+srcdir = ../src
+
+# one up
+basedir = ../src/include
+# top dir
+topdir = ..
+# this dir relative to top dir
+thisdir = ../check_bareos
+
+DEBUG=@DEBUG@
+
+first_rule: all
+dummy:
+
+#
+CHECKSRCS = check_bareos.c authenticate.c
+CHECKOBJS = check_bareos.o authenticate.o
+
+CHECK_CPPFLAGS=
+CHECK_LDFLAGS=
+
+.SUFFIXES:	.c .o
+.PHONY:
+.DONTCARE:
+
+# inference rules
+.c.o:
+	@echo "Compiling $<"
+	$(NO_ECHO) $(CXX) $(DEFS) $(DEBUG) -c $(CPPFLAGS) $(CHECK_CPPFLAGS) \
+ -I$(srcdir) -I$(basedir) $(DINCLUDE) $(CXXFLAGS) $<
+#-------------------------------------------------------------------------
+all: Makefile check_bareos
+	@echo "==== Make of check_bareos is good ===="
+	@echo " "
+
+check_bareos: Makefile $(CHECKOBJS) $(srcdir)/lib/libbareos$(DEFAULT_ARCHIVE_TYPE)
+	$(LIBTOOL_LINK) $(CXX) $(LDFLAGS) $(CHECK_LDFLAGS) -L$(srcdir)/lib -o $@ \
+	  $(CHECKOBJS) $(DLIB) -lbareos -lm $(LIBS) $(OPENSSL_LIBS)
+
+
+Makefile: $(srcdir)/Makefile.in $(topdir)/config.status
+	cd $(topdir) \
+	  && CONFIG_FILES=$(thisdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+libtool-clean:
+	$(RMF) -r .libs _libs
+
+clean:
+	@$(RMF) check_bareos core core.* a.out *.o *.bak *~ *.intpro *.extpro 1 2 3
+
+realclean: clean
+	@$(RMF) tags
+
+distclean: realclean
+	if test $(srcdir) = .; then $(MAKE) realclean; fi
+	(cd $(srcdir); $(RMF) Makefile)
+
+devclean: realclean
+	if test $(srcdir) = .; then $(MAKE) realclean; fi
+	(cd $(srcdir); $(RMF) Makefile)
+
+install: all
+	$(INSTALL_PROGRAM) check_bareos $(DESTDIR)$(sbindir)/check_bareos
+
+uninstall:
+	(cd $(DESTDIR)$(sbindir); $(RMF) check_bareos)
+
+
+
+# Semi-automatic generation of dependencies:
+# Use gcc -MM because X11 `makedepend' doesn't work on all systems
+# and it also includes system headers.
+# `semi'-automatic since dependencies are generated at distribution time.
+
+depend:
+	@$(MV) Makefile Makefile.bak
+	@$(SED) "/^# DO NOT DELETE:/,$$ d" Makefile.bak > Makefile
+	@$(ECHO) "# DO NOT DELETE: nice dependency list follows" >> Makefile
+	@$(CXX) -S -M $(CPPFLAGS) $(CHECK_CPPFLAGS) -I$(srcdir) -I$(basedir) *.c >> Makefile
+	@if test -f Makefile ; then \
+	    $(RMF) Makefile.bak; \
+	else \
+	   $(MV) Makefile.bak Makefile; \
+	   echo -e "Something went wrong\n\a"; \
+	fi
+
+# -----------------------------------------------------------------------
+# DO NOT DELETE: nice dependency list follows
diff --git a/check_bareos/README b/check_bareos/README
new file mode 100644
index 0000000..984d402
--- /dev/null
+++ b/check_bareos/README
@@ -0,0 +1,15 @@
+# It's more or less untested, though.
+#  Submitted by Arno Lehmann <al@its-lehmann.de>
+#
+
+run ./configure with your usual options at the toplevel. Afterwards, use
+'make' to create your binaries.
+
+If you encounter problems, you'll have to setup the Bacula source manually.
+
+Note that check_bareos does not support TLS and is an unsupported add-on to
+Bacula. Even if it's not part of the core Bacula programs, questions can be
+asked at the bareos-users mailing list.
+
+Bacula is a Trademark of Kern Sibbald. Bacula and the accompanying programs
+are open source. See the LICENSE file for more information.
diff --git a/check_bareos/authenticate.c b/check_bareos/authenticate.c
new file mode 100644
index 0000000..79c5544
--- /dev/null
+++ b/check_bareos/authenticate.c
@@ -0,0 +1,176 @@
+/*
+ *
+ *   Bacula authentication. Provides authentication with
+ *     File and Storage daemons.
+ *
+ *     Nicolas Boichat, August MMIV
+ *
+ *    This routine runs as a thread and must be thread reentrant.
+ *
+ *  Basic tasks done here:
+ *
+ */
+/*
+   Bacula® - The Network Backup Solution
+
+   Copyright (C) 2004-2010 Free Software Foundation Europe e.V.
+
+   The main author of Bacula is Kern Sibbald, with contributions from
+   many others, a complete list can be found in the file AUTHORS.
+   This program is Free Software; you can redistribute it and/or
+   modify it under the terms of version three of the GNU Affero General Public
+   License as published by the Free Software Foundation plus additions
+   that are listed in the file LICENSE.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU Affero General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
+
+   Bacula® is a registered trademark of John Walker.
+   The licensor of Bacula is the Free Software Foundation Europe
+   (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
+   Switzerland, email:ftf@fsfeurope.org.
+*/
+
+#include "bareos.h"
+#include "check_bareos.h"
+
+void senditf(const char *fmt, ...);
+void sendit(const char *buf);
+
+/* Commands sent to Director */
+static char DIRhello[]    = "Hello %s calling\n";
+
+/* Response from Director */
+static char DIROKhello[]   = "1000 OK:";
+
+/* Commands sent to Storage daemon and File daemon and received
+ *  from the User Agent */
+static char SDFDhello[]    = "Hello Director %s calling\n";
+
+/* Response from SD */
+static char SDOKhello[]   = "3000 OK Hello\n";
+/* Response from FD */
+static char FDOKhello[] = "2000 OK Hello";
+
+/* Forward referenced functions */
+
+/*
+ * Authenticate Director
+ */
+int authenticate_director(BSOCK *dir, char *dirname, char *password)
+{
+   int tls_local_need = BNET_TLS_NONE;
+   int tls_remote_need = BNET_TLS_NONE;
+   bool compatible = true;
+   char bashed_name[MAX_NAME_LENGTH];
+
+   bstrncpy(bashed_name, dirname, sizeof(bashed_name));
+   bash_spaces(bashed_name);
+
+   /* Timeout Hello after 5 mins */
+   btimer_t *tid = start_bsock_timer(dir, 60 * 5);
+   bnet_fsend(dir, DIRhello, bashed_name);
+
+   if (!cram_md5_respond(dir, password, &tls_remote_need, &compatible) ||
+       !cram_md5_challenge(dir, password, tls_local_need, compatible)) {
+      stop_bsock_timer(tid);
+      return 0;
+   }
+
+   Dmsg1(6, ">dird: %s", dir->msg);
+   if (bnet_recv(dir) <= 0) {
+      stop_bsock_timer(tid);
+      return 0;
+   }
+   Dmsg1(10, "<dird: %s", dir->msg);
+   stop_bsock_timer(tid);
+   if (!bstrncmp(dir->msg, DIROKhello, sizeof(DIROKhello)-1)) {
+      return 0;
+   }
+   return 1;
+}
+
+/*
+ * Authenticate Storage daemon connection
+ */
+int authenticate_storage_daemon(BSOCK *sd, char *sdname, char* password)
+{
+   char dirname[MAX_NAME_LENGTH];
+   int tls_local_need = BNET_TLS_NONE;
+   int tls_remote_need = BNET_TLS_NONE;
+   bool compatible = true;
+
+   /*
+    * Send my name to the Storage daemon then do authentication
+    */
+   bstrncpy(dirname, sdname, sizeof(dirname));
+   bash_spaces(dirname);
+   /* Timeout Hello after 5 mins */
+   btimer_t *tid = start_bsock_timer(sd, 60 * 5);
+   if (!bnet_fsend(sd, SDFDhello, dirname)) {
+      stop_bsock_timer(tid);
+      return 0;
+   }
+   if (!cram_md5_respond(sd, password, &tls_remote_need, &compatible) ||
+       !cram_md5_challenge(sd, password, tls_local_need, compatible)) {
+      stop_bsock_timer(tid);
+      return 0;
+   }
+   Dmsg1(116, ">stored: %s", sd->msg);
+   if (bnet_recv(sd) <= 0) {
+      stop_bsock_timer(tid);
+      return 0;
+   }
+   Dmsg1(110, "<stored: %s", sd->msg);
+   stop_bsock_timer(tid);
+   if (!bstrncmp(sd->msg, SDOKhello, sizeof(SDOKhello))) {
+      return 0;
+   }
+   return 1;
+}
+
+/*
+ * Authenticate File daemon connection
+ */
+int authenticate_file_daemon(BSOCK *fd, char *fdname, char *password)
+{
+   char dirname[MAX_NAME_LENGTH];
+   int tls_local_need = BNET_TLS_NONE;
+   int tls_remote_need = BNET_TLS_NONE;
+   bool compatible = true;
+
+   /*
+    * Send my name to the File daemon then do authentication
+    */
+   bstrncpy(dirname, fdname, sizeof(dirname));
+   bash_spaces(dirname);
+   /* Timeout Hello after 5 mins */
+   btimer_t *tid = start_bsock_timer(fd, 60 * 5);
+   if (!bnet_fsend(fd, SDFDhello, dirname)) {
+      stop_bsock_timer(tid);
+      return 0;
+   }
+   if (!cram_md5_respond(fd, password, &tls_remote_need, &compatible) ||
+       !cram_md5_challenge(fd, password, tls_local_need, compatible)) {
+      stop_bsock_timer(tid);
+      return 0;
+   }
+   Dmsg1(116, ">filed: %s", fd->msg);
+   if (bnet_recv(fd) <= 0) {
+      stop_bsock_timer(tid);
+      return 0;
+   }
+   Dmsg1(110, "<stored: %s", fd->msg);
+   stop_bsock_timer(tid);
+   if (!bstrncmp(fd->msg, FDOKhello, strlen(FDOKhello))) {
+      return 0;
+   }
+   return 1;
+}
diff --git a/check_bareos/check_bareos.c b/check_bareos/check_bareos.c
new file mode 100644
index 0000000..9d8ea8d
--- /dev/null
+++ b/check_bareos/check_bareos.c
@@ -0,0 +1,373 @@
+/*
+ *
+ *   Nagios Plugin check_bareos
+ *
+ *     Christian Masopust, (c)2005
+ *
+ *     Version $Id: check_bareos.c,v 1.0 2005/02/25
+ */
+
+/*
+   Copyright (C) 2005 Christian Masopust
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+   MA 02111-1307, USA.
+
+ */
+
+#include "bareos.h"
+#include "check_bareos.h"
+
+#define STATE_OK 0
+#define STATE_WARNING 1
+#define STATE_CRITICAL 2
+#define STATE_UNKNOWN 3
+
+
+/* Imported functions */
+int authenticate_director(BSOCK *s, char *dirname, char *password);
+int authenticate_file_daemon(BSOCK *s, char *fdname, char *password);
+int authenticate_storage_daemon(BSOCK *s, char* sdname, char *password);
+
+/* Forward referenced functions */
+void writecmd(monitoritem* item, const char* command);
+int docmd(monitoritem* item, const char* command, char *answer);
+
+/* Static variables */
+static monitoritem mitem;
+
+/* Data received from DIR/FD/SD */
+static char OKqstatus[]   = "%c000 OK .status\n";
+
+
+
+static void usage()
+{
+   fprintf(stderr, _(
+"Copyright (C) 2005 Christian Masopust\n"
+"Written by Christian Masopust (2005)\n"
+"\nVersion: " VERSION " (" BDATE ") %s %s %s\n\n"
+"Usage: check_bareos [-d debug_level] -H host -D daemon -M name -P port\n"
+"       -H <host>     hostname where daemon runs\n"
+"       -D <daemon>   which daemon to check: dir|sd|fd\n"
+"       -M <name>     name of monitor (as in bareos-*.conf)\n"
+"       -K <md5-hash> password for access to daemon\n"
+"       -P <port>     port where daemon listens\n"
+"       -dnn          set debug level to nn\n"
+"       -?            print this message.\n"
+"\n"), HOST_OS, DISTNAME, DISTVER);
+}
+
+
+/*********************************************************************
+ *
+ *	   Main Bacula Tray Monitor -- User Interface Program
+ *
+ */
+int main(int argc, char *argv[])
+{
+   int ch;
+   DIRRES s_dird;
+   CLIENTRES s_filed;
+   STORERES s_stored;
+
+   char host[250];
+   char daemon[20];
+   char monitorname[100];
+   char pw[200];
+   int port = 0;
+
+   char answer[1024];
+   int retcode = STATE_UNKNOWN;
+
+   unsigned int i, j;
+   MD5_CTX md5c;
+   unsigned char signature[16];
+
+
+   struct sigaction sigignore;
+   sigignore.sa_flags = 0;
+   sigignore.sa_handler = SIG_IGN;
+   sigfillset(&sigignore.sa_mask);
+   sigaction(SIGPIPE, &sigignore, NULL);
+
+   strcpy (pw, "");
+
+   init_stack_dump();
+   my_name_is(argc, argv, "check_bareos");
+   textdomain("bareos");
+   init_msg(NULL, NULL);
+
+   while ((ch = getopt(argc, argv, "H:D:M:P:K:d:h?")) != -1) {
+
+      switch (ch) {
+
+		  case 'H':
+		  	strcpy (host, optarg);
+		  	break;
+
+		  case 'D':
+		  	strcpy (daemon, optarg);
+		  	break;
+
+		  case 'M':
+		  	strcpy (monitorname, optarg);
+		  	break;
+
+		  case 'P':
+		  	port = atoi(optarg);
+		  	break;
+
+		  case 'K':
+		  	strcpy (pw, optarg);
+		  	break;
+
+		  case 'd':
+		 	debug_level = atoi(optarg);
+		 	if (debug_level <= 0) {
+		 	   debug_level = 1;
+		 	}
+		 	break;
+
+      	  case 'h':
+      	  case '?':
+      	  default:
+			 usage();
+			 exit(1);
+      }
+   }
+   argc -= optind;
+   //argv += optind;
+
+   if (argc) {
+      usage();
+      exit(STATE_UNKNOWN);
+   }
+
+   lmgr_init_thread();
+
+   char sig[100];
+   MD5_Init(&md5c);
+   MD5_Update(&md5c, (unsigned char *) pw, strlen(pw));
+   MD5_Final(signature, &md5c);
+   for (i = j = 0; i < sizeof(signature); i++) {
+      sprintf(&sig[j], "%02x", signature[i]);
+      j += 2;
+   }
+
+
+   /* director ?  */
+   if (bstrcmp(daemon, "dir")) {
+
+	   if (port != 0)
+	   	 s_dird.DIRport = port;
+	   else
+	   	 s_dird.DIRport = 9101;
+
+	   s_dird.address  = host;
+	   s_dird.password = sig;
+	   s_dird.hdr.name = monitorname;
+
+	   mitem.type = R_DIRECTOR;
+	   mitem.resource = &s_dird;
+	   mitem.D_sock = NULL;
+
+   } else if (bstrcmp(daemon, "sd")) {
+
+	   if (port != 0)
+	   	 s_stored.SDport = port;
+	   else
+	   	 s_stored.SDport = 9103;
+
+	   s_stored.address = host;
+	   s_stored.password = sig;
+	   s_stored.hdr.name = monitorname;
+
+	   mitem.type = R_STORAGE;
+	   mitem.resource = &s_stored;
+	   mitem.D_sock = NULL;
+
+   } else if (bstrcmp(daemon, "fd")) {
+
+	   if (port != 0)
+	   	 s_filed.FDport = port;
+	   else
+	   	 s_filed.FDport = 9102;
+
+	   s_filed.address = host;
+	   s_filed.password = sig;
+	   s_filed.hdr.name = monitorname;
+
+	   mitem.type = R_CLIENT;
+	   mitem.resource = &s_filed;
+	   mitem.D_sock = NULL;
+
+   } else {
+
+	   usage();
+	   exit(1);
+   }
+
+
+   if (mitem.type == R_DIRECTOR)
+	   retcode = docmd(&mitem, ".status dir current\n", answer);
+   else
+	   retcode = docmd(&mitem, ".status current\n", answer);
+
+
+   if (mitem.D_sock) {
+        mitem.D_sock->signal(BNET_TERMINATE); /* send EOF */
+        mitem.D_sock->close();
+        mitem.D_sock = NULL;
+   }
+
+   printf ("%s\n", answer);
+   return retcode;
+}
+
+
+static int authenticate_daemon(monitoritem* item) {
+
+   DIRRES *d;
+   CLIENTRES *f;
+   STORERES *s;
+
+   switch (item->type) {
+   case R_DIRECTOR:
+      d = (DIRRES *)item->resource;
+      return authenticate_director(item->D_sock, d->hdr.name, d->password);
+      break;
+   case R_CLIENT:
+      f = (CLIENTRES *)item->resource;
+      return authenticate_file_daemon(item->D_sock, f->hdr.name, f->password);
+      break;
+   case R_STORAGE:
+      s = (STORERES *)item->resource;
+      return authenticate_storage_daemon(item->D_sock, s->hdr.name, s->password);
+      break;
+   default:
+      printf("Error, currentitem is not a Client or a Storage..\n");
+      return FALSE;
+   }
+}
+
+
+
+int docmd(monitoritem* item, const char* command, char *answer) {
+
+   int stat;
+   char num;
+   const char *dname;
+
+   dname = "";
+
+   if (!item->D_sock) {
+
+      DIRRES* dird;
+      CLIENTRES* filed;
+      STORERES* stored;
+      item->D_sock = New(BSOCK_TCP);
+//      item->D_sock->init();
+
+      switch (item->type) {
+      case R_DIRECTOR:
+		 dird = (DIRRES*)item->resource;
+         item->D_sock->connect(NULL, 0, 0, 0, "Director daemon" , dird->address, NULL, dird->DIRport, 0);
+		 dname = "Director";
+		 break;
+      case R_CLIENT:
+		 filed = (CLIENTRES*)item->resource;
+         item->D_sock->connect(NULL, 0, 0, 0, "File daemon" , filed->address, NULL, filed->FDport, 0);
+		 dname = "FileDaemon";
+		 break;
+      case R_STORAGE:
+		 stored = (STORERES*)item->resource;
+         item->D_sock->connect(NULL, 0, 0, 0, "Storage daemon" , stored->address, NULL, stored->SDport, 0);
+		 dname = "StorageDaemon";
+		 break;
+      default:
+		 printf("Error, currentitem is not a Client, a Storage or a Director..\n");
+		 return STATE_UNKNOWN;
+      }
+
+      if (item->D_sock == NULL) {
+      		 sprintf (answer, "BACULA CRITICAL - Cannot connect to %s!", dname);
+		 return STATE_CRITICAL;
+      }
+
+      if (!authenticate_daemon(item)) {
+	 	sprintf (answer, "BACULA CRITICAL - Cannot authenticate to %s: %s", dname, item->D_sock->msg);
+	 	item->D_sock = NULL;
+	 	return STATE_CRITICAL;
+      }
+
+   }
+
+   if (command[0] != 0)
+      writecmd(item, command);
+
+   while(1) {
+      if ((stat = bnet_recv(item->D_sock)) >= 0) {
+
+	/* welcome message of director */
+	if ((item->type == R_DIRECTOR) && bstrncmp(item->D_sock->msg, "Using ", 6))
+		continue;
+
+	if (sscanf(item->D_sock->msg, OKqstatus, &num) != 1) {
+		/* Error, couldn't find OK */
+		sprintf (answer, "BACULA CRITICAL - %s Status: %s", dname, item->D_sock->msg);
+		return STATE_CRITICAL;
+	} else {
+		sprintf (answer, "BACULA OK - %s Status OK", dname);
+		return STATE_OK;
+	}
+      }
+      else if (stat == BNET_SIGNAL) {
+	 	if (item->D_sock->msglen == BNET_EOD) {
+	    	strcpy(answer, "BACULA WARNING - << EOD >>");
+	    	return STATE_WARNING;
+	 }
+	 else if (item->D_sock->msglen == BNET_SUB_PROMPT) {
+	    strcpy(answer, "BACULA WARNING - BNET_SUB_PROMPT signal received.");
+	    return STATE_WARNING;
+	 }
+	 else if (item->D_sock->msglen == BNET_HEARTBEAT) {
+	    bnet_sig(item->D_sock, BNET_HB_RESPONSE);
+	 }
+	 else {
+		sprintf(answer, "BACULA WARNING - Unexpected signal received : %s ", bnet_sig_to_ascii(item->D_sock));
+	 }
+      }
+      else { /* BNET_HARDEOF || BNET_ERROR */
+		 strcpy(answer, "BACULA CRITICAL - ERROR: BNET_HARDEOF or BNET_ERROR");
+		 item->D_sock = NULL;
+		 return STATE_CRITICAL;
+      }
+
+      if (is_bnet_stop(item->D_sock)) {
+		 item->D_sock = NULL;
+		 return STATE_WARNING;
+      }
+   }
+}
+
+void writecmd(monitoritem* item, const char* command) {
+   if (item->D_sock) {
+      item->D_sock->msglen = strlen(command);
+      pm_strcpy(item->D_sock->msg, command);
+      bnet_send(item->D_sock);
+   }
+}
+
diff --git a/check_bareos/check_bareos.h b/check_bareos/check_bareos.h
new file mode 100644
index 0000000..73971ee
--- /dev/null
+++ b/check_bareos/check_bareos.h
@@ -0,0 +1,115 @@
+/*
+   Copyright (C) 2004 Kern Sibbald and John Walker
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2 of
+   the License, or (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public
+   License along with this program; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+   MA 02111-1307, USA.
+
+ */
+/*
+ * Includes specific to the tray monitor
+ *
+ *     Nicolas Boichat, August MMIV
+ */
+
+/*
+ * Resource codes -- they must be sequential for indexing
+ */
+enum rescode {
+   R_MONITOR = 1001,
+   R_DIRECTOR,
+   R_CLIENT,
+   R_STORAGE,
+   R_FIRST = R_MONITOR,
+   R_LAST  = R_STORAGE                /* keep this updated */
+};
+
+/*
+ * Some resource attributes
+ */
+enum {
+   R_NAME = 1020,
+   R_ADDRESS,
+   R_PASSWORD,
+   R_TYPE,
+   R_BACKUP
+};
+
+/* Director */
+struct DIRRES {
+   RES hdr;
+
+   int DIRport;                       /* UA server port */
+   char *address;                     /* UA server address */
+   char *password;                    /* UA server password */
+   int enable_ssl;                    /* Use SSL */
+};
+
+/*
+ *   Tray Monitor Resource
+ *
+ */
+//struct MONITORRES {
+//   RES hdr;
+//
+//   int require_ssl;                   /* Require SSL for all connections */
+//   MSGSRES *messages;                 /* Daemon message handler */
+//   char *password;                    /* UA server password */
+//   utime_t RefreshInterval;           /* Status refresh interval */
+//   utime_t FDConnectTimeout;          /* timeout for connect in seconds */
+//   utime_t SDConnectTimeout;          /* timeout in seconds */
+//};
+
+/*
+ *   Client Resource
+ *
+ */
+struct CLIENTRES {
+   RES hdr;
+
+   int FDport;                        /* Where File daemon listens */
+   char *address;
+   char *password;
+   int enable_ssl;                    /* Use SSL */
+};
+
+/*
+ *   Store Resource
+ *
+ */
+struct STORERES {
+   RES hdr;
+
+   int SDport;                        /* port where Directors connect */
+   char *address;
+   char *password;
+   int enable_ssl;                    /* Use SSL */
+};
+
+/* Define the Union of all the above
+ * resource structure definitions.
+ */
+//union URES {
+//   //MONITOR res_monitor;
+//   DIRRES res_dir;
+//   CLIENT res_client;
+//   STORE res_store;
+//   RES hdr;
+//};
+
+struct monitoritem {
+   rescode type; /* R_DIRECTOR, R_CLIENT or R_STORAGE */
+   void* resource; /* DIRRES*, CLIENT* or STORE* */
+   BSOCK *D_sock;
+};
diff --git a/check_bareos/check_bareos_pools.sh b/check_bareos/check_bareos_pools.sh
new file mode 100644
index 0000000..e81cbe1
--- /dev/null
+++ b/check_bareos/check_bareos_pools.sh
@@ -0,0 +1,159 @@
+#! /bin/sh
+# Author : Ludovic Strappazon. l.strappazon@gmail.com
+# Copyright 2004, Free Software Foundation Europe e.V.
+# Any comment, advice or enhancement are welcome  :-)
+
+PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin
+MYSQL="/usr/bin/mysql -u bacula --password=mypassword"
+TMP=/tmp
+BACULA=/usr/local/bacula
+
+PROGNAME=`basename $0`
+PROGPATH=`echo $0 | sed -e 's,[\\/][^\\/][^\\/]*$,,'`
+STATUS=""
+
+. $PROGPATH/utils.sh
+
+print_usage() {
+        echo "Usage: $PROGNAME -P <pool> -M <media-type> -w <warning threshold> -c <critical threshold> [-S]"
+}
+
+print_help() {
+        echo ""
+        print_usage
+        echo ""
+        echo "This plugin checks the space available in the pool against the space required for the next scheduled backups"
+        echo "Example : $PROGNAME -P default -M LTO -w 20 -c 10 will check the default pool, return OK if (available space) > 1,20*(required space), WARNING if 1,20*(required space) > (available space) > 1,10*(required space), and CRITICAL else."
+        echo ""
+        echo "With the -S option, it will check the pool named Scratch and return WARNING instead of CRITICAL if the Scratch pool can save the situation."
+        echo "Example : $PROGNAME -P default -M LTO -w 20 -c 10 -S will check the default pool, return OK if (available space) > 1,20*(required space), WARNING if 1,20*(required space) > (available space) > 1,10*(required space) or if (available space in default and Scratch) > 1,10*(required space) > (available space in default), and CRITICAL else."
+        echo ""
+        echo "The evaluation of the space required is done by adding the biggest backups of the same level than the scheduled jobs"
+        echo "The available space is evaluated by the number of out of retention tapes and the average VolBytes of these Full tapes"
+        echo ""
+        echo "The Information Status are : \"Required, Available, Volume Errors\" and \"Will use Scratch pool\" if necessary."
+        echo ""
+        echo "I think this plugin should be used in passive mode, and ran by a RunAfterJob"
+        exit 3
+}
+
+NB_ARGS=$#
+SCRATCH=0
+while getopts :P:M:w:c:hS OPTION
+do
+  case $OPTION in
+    P) POOL="$OPTARG"
+       ;;
+    M) MEDIA_TYPE="$OPTARG"
+       ;;
+    S) SCRATCH=1
+       ;;
+    w) WARNING="$OPTARG"
+       ;;
+    c) CRITICAL="$OPTARG"
+       ;;
+    h) print_help
+       exit 3
+       ;;
+    *) print_usage
+       exit 3
+       ;;
+  esac
+done
+shift $(($OPTIND - 1))
+
+if [ "$NB_ARGS" -ne 8 -a "$NB_ARGS" -ne 9 ]; then
+        print_revision $PROGNAME 25/05/2005
+        print_usage
+        exit 3
+fi
+
+LAST_CHECK=`ps -ef | grep check_ba[Cc]ula_pools.sh | awk {'print $5'} | uniq | wc -l`
+if [ "$LAST_CHECK" -gt 1 ]; then
+        echo "The last check was not complete, you should increase the check_period."
+        exit 3
+fi
+
+  NB_VOLUMES_OUT_OF_RETENTION=`$MYSQL << EOF
+USE bacula
+SELECT COUNT(MediaId) from Media, Pool where Media.PoolId=Pool.PoolId and Pool.Name="$POOL" AND LastWritten <> "0000-00-00 00:00:00" AND UNIX_TIMESTAMP()-UNIX_TIMESTAMP(LastWritten)>Media.VolRetention AND Inchanger = "1";
+EOF
+`
+  NB_VOLUMES_OUT_OF_RETENTION=`echo $NB_VOLUMES_OUT_OF_RETENTION | cut -f 2 -d ' '`
+
+NB_VOLUMES_ERROR=`$MYSQL << EOF
+USE bacula
+SELECT COUNT(MediaId) from Media, Pool where Media.PoolId=Pool.PoolId and Pool.Name="$POOL" AND VolStatus="Error" AND Inchanger = "1";
+EOF
+`
+NB_VOLUMES_ERROR=`echo $NB_VOLUMES_ERROR | cut -f 2 -d ' '`
+
+AVERAGE_CAPA_VOLUME=`$MYSQL << EOF
+USE bacula
+SELECT SUM(VolBytes)/COUNT(MediaId) FROM Media where VolStatus="Full" AND MediaType="$MEDIA_TYPE";
+EOF
+`
+AVERAGE_CAPA_VOLUME=`echo $AVERAGE_CAPA_VOLUME | cut -f 2 -d ' ' | cut -f 1 -d '.'`
+
+CAPA_VOLUMES_APPEND=`$MYSQL << EOF
+USE bacula
+SELECT SUM("$AVERAGE_CAPA_VOLUME"-VolBytes) from Media, Pool where Media.PoolId=Pool.PoolId and Pool.Name="$POOL" AND (VolStatus = "Append" OR VolStatus = "Recycle" OR VolStatus = "Purge") AND Inchanger = "1" AND MediaType="$MEDIA_TYPE";
+EOF
+`
+CAPA_VOLUMES_APPEND=`echo $CAPA_VOLUMES_APPEND | cut -f 2 -d ' '`
+
+if [ $SCRATCH -eq 1 ]
+then
+CAPA_VOLUMES_SCRATCH=`$MYSQL << EOF
+USE bacula
+SELECT SUM("$AVERAGE_CAPA_VOLUME"-VolBytes) from Media, Pool where Media.PoolId=Pool.PoolId and Pool.Name="Scratch" AND VolStatus = "Append" AND Inchanger = "1" AND MediaType="$MEDIA_TYPE";
+EOF
+`
+CAPA_VOLUMES_SCRATCH=`echo $CAPA_VOLUMES_SCRATCH | cut -f 2 -d ' '`
+else
+CAPA_VOLUMES_SCRATCH=0
+fi
+
+echo "st
+1
+q" | $BACULA/etc/bconsole | sed -n /Scheduled/,/Running/p | grep Backup | tr -s [:blank:] | tr '[:blank:]' '@' > ${TMP}/Scheduled.txt
+
+CAPA_REQUIRED=0
+for LINE in `cat ${TMP}/Scheduled.txt`
+do
+  SCHEDULED_JOB=`echo $LINE | awk -F@ '{print $6}'`
+  LEVEL=`echo $LINE | awk -F@ '{print $1}' | cut -c 1`
+
+MAX_VOLUME_JOB_FOR_LEVEL=`$MYSQL << EOF
+USE bacula
+SELECT MAX(JobBytes) from Job, Pool where Level="$LEVEL" AND Job.Name="$SCHEDULED_JOB" AND Job.PoolId=Pool.PoolId AND Pool.Name="$POOL";
+EOF
+`
+MAX_VOLUME_JOB_FOR_LEVEL=`echo $MAX_VOLUME_JOB_FOR_LEVEL | cut -f 2 -d ' ' `
+
+CAPA_REQUIRED=$[CAPA_REQUIRED+MAX_VOLUME_JOB_FOR_LEVEL]
+done
+
+rm ${TMP}/Scheduled.txt
+
+CAPA_WARNING=`echo $[(WARNING+100)*CAPA_REQUIRED]/100 | bc | cut -f 1 -d '.'`
+CAPA_CRITICAL=`echo $[(CRITICAL+100)*CAPA_REQUIRED]/100 | bc | cut -f 1 -d '.'`
+CAPA_DISP=$[NB_VOLUMES_OUT_OF_RETENTION*AVERAGE_CAPA_VOLUME+CAPA_VOLUMES_APPEND]
+CAPA_DISP_INCLUDING_SCRATCH=$[CAPA_DISP+CAPA_VOLUMES_SCRATCH]
+
+MESSAGE="Required : $[CAPA_REQUIRED/1000000000] Go, available : $[CAPA_DISP/1000000000] Go, Volumes Error : $NB_VOLUMES_ERROR"
+
+if [ "$CAPA_DISP" -gt $CAPA_WARNING ]; then
+   echo $MESSAGE
+   exit 0
+elif [ "$CAPA_DISP" -gt $CAPA_CRITICAL ];then
+   echo $MESSAGE
+   exit 1
+elif [ "$CAPA_DISP_INCLUDING_SCRATCH" -gt $CAPA_CRITICAL ];then
+   MESSAGE="${MESSAGE}. Will use Scratch Pool !"
+   echo $MESSAGE
+   exit 1
+else
+   exit 2
+fi
+exit 3
diff --git a/configure b/configure
index ad1ed22..119dd86 100755
--- a/configure
+++ b/configure
@@ -33681,7 +33681,11 @@ $as_echo "no" >&6; }
 fi
 
 
-
+# Add nagios check_bareos_plugin
+if test -d check_bareos; then
+    PFILES="${PFILES} \
+            check_bareos/Makefile"
+fi
 
 
 LIBS="$PTHREAD_LIB $LIBS"
