aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMicah Anderson <micah@riseup.net>2009-02-19 12:23:29 -0500
committerMicah Anderson <micah@riseup.net>2009-02-19 12:23:29 -0500
commit539fd1471907422d81626260ea4f1e23e4d398a4 (patch)
treeefe32e02a285fe1d241e16c6701a95a8201d79e7 /src
parent27a7859c42394a78c16b24f0d08ca28667bb1efa (diff)
downloadbackupninja-539fd1471907422d81626260ea4f1e23e4d398a4.tar.gz
backupninja-539fd1471907422d81626260ea4f1e23e4d398a4.tar.bz2
move the branches directories up to the root of the repository
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am34
-rw-r--r--src/Makefile.in343
-rwxr-xr-xsrc/backupninja.in583
-rwxr-xr-xsrc/ninjahelper.in268
-rwxr-xr-xsrc/ninjareport.in205
5 files changed, 1433 insertions, 0 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644
index 0000000..3d5bdb8
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,34 @@
+# tyhle vygenerujeme ...
+sbin_SCRIPTS = backupninja ninjahelper
+
+# a proto je taky musíme smazat ...
+CLEANFILES = $(sbin_SCRIPTS)
+
+EXTRA_DIST = backupninja.in ninjahelper.in ninjareport.in
+
+edit = sed \
+ -e "s,@CFGDIR\@,$(CFGDIR),g" \
+ -e "s,@BASH\@,$(BASH),g" \
+ -e "s,@AWK\@,$(AWK),g" \
+ -e "s,@SED\@,$(SED),g" \
+ -e 's,@datadir\@,$(pkgdatadir),g' \
+ -e "s,@libdir\@,$(pkglibdir),g" \
+ -e 's,@localstatedir\@,$(localstatedir),g' \
+ -e 's,@prefix\@,$(prefix),g'
+
+#install-exec-hook:
+
+backupninja: $(srcdir)/backupninja.in
+ rm -f backupninja
+ $(edit) $(srcdir)/backupninja.in > backupninja
+ chmod ugo+x backupninja
+
+ninjahelper: $(srcdir)/ninjahelper.in
+ rm -f ninjahelper
+ $(edit) $(srcdir)/ninjahelper.in > ninjahelper
+ chmod ugo+x ninjahelper
+
+ninjareport: $(srcdir)/ninjareport.in
+ rm -f ninjareport
+ $(edit) $(srcdir)/ninjareport.in > ninjareport
+ chmod ugo+x ninjareport
diff --git a/src/Makefile.in b/src/Makefile.in
new file mode 100644
index 0000000..f0ee2db
--- /dev/null
+++ b/src/Makefile.in
@@ -0,0 +1,343 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+subdir = src
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+am__installdirs = "$(DESTDIR)$(sbindir)"
+sbinSCRIPT_INSTALL = $(INSTALL_SCRIPT)
+SCRIPTS = $(sbin_SCRIPTS)
+SOURCES =
+DIST_SOURCES =
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BASH = @BASH@
+CFGDIR = @CFGDIR@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+HAVE_RPM = @HAVE_RPM@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MKTEMP = @MKTEMP@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_cv_have_rpm = @ac_cv_have_rpm@
+am__leading_dot = @am__leading_dot@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build_alias = @build_alias@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host_alias = @host_alias@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+
+# tyhle vygenerujeme ...
+sbin_SCRIPTS = backupninja ninjahelper
+
+# a proto je taky musíme smazat ...
+CLEANFILES = $(sbin_SCRIPTS)
+EXTRA_DIST = backupninja.in ninjahelper.in ninjareport.in
+edit = sed \
+ -e "s,@CFGDIR\@,$(CFGDIR),g" \
+ -e "s,@BASH\@,$(BASH),g" \
+ -e "s,@AWK\@,$(AWK),g" \
+ -e "s,@SED\@,$(SED),g" \
+ -e 's,@datadir\@,$(pkgdatadir),g' \
+ -e "s,@libdir\@,$(pkglibdir),g" \
+ -e 's,@localstatedir\@,$(localstatedir),g' \
+ -e 's,@prefix\@,$(prefix),g'
+
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+install-sbinSCRIPTS: $(sbin_SCRIPTS)
+ @$(NORMAL_INSTALL)
+ test -z "$(sbindir)" || $(MKDIR_P) "$(DESTDIR)$(sbindir)"
+ @list='$(sbin_SCRIPTS)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ if test -f $$d$$p; then \
+ f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \
+ echo " $(sbinSCRIPT_INSTALL) '$$d$$p' '$(DESTDIR)$(sbindir)/$$f'"; \
+ $(sbinSCRIPT_INSTALL) "$$d$$p" "$(DESTDIR)$(sbindir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-sbinSCRIPTS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(sbin_SCRIPTS)'; for p in $$list; do \
+ f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \
+ echo " rm -f '$(DESTDIR)$(sbindir)/$$f'"; \
+ rm -f "$(DESTDIR)$(sbindir)/$$f"; \
+ done
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(SCRIPTS)
+installdirs:
+ for dir in "$(DESTDIR)$(sbindir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-exec-am: install-sbinSCRIPTS
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-sbinSCRIPTS
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic distclean \
+ distclean-generic distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-sbinSCRIPTS install-strip installcheck installcheck-am \
+ installdirs maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-generic pdf pdf-am ps ps-am uninstall \
+ uninstall-am uninstall-sbinSCRIPTS
+
+
+#install-exec-hook:
+
+backupninja: $(srcdir)/backupninja.in
+ rm -f backupninja
+ $(edit) $(srcdir)/backupninja.in > backupninja
+ chmod ugo+x backupninja
+
+ninjahelper: $(srcdir)/ninjahelper.in
+ rm -f ninjahelper
+ $(edit) $(srcdir)/ninjahelper.in > ninjahelper
+ chmod ugo+x ninjahelper
+
+ninjareport: $(srcdir)/ninjareport.in
+ rm -f ninjareport
+ $(edit) $(srcdir)/ninjareport.in > ninjareport
+ chmod ugo+x ninjareport
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/backupninja.in b/src/backupninja.in
new file mode 100755
index 0000000..afb9556
--- /dev/null
+++ b/src/backupninja.in
@@ -0,0 +1,583 @@
+#!@BASH@
+# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*-
+#
+# |\_
+# B A C K U P N I N J A /()/
+# `\|
+#
+# Copyright (C) 2004-05 riseup.net -- property is theft.
+#
+# 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.
+#
+
+#####################################################
+## FUNCTIONS
+
+function setupcolors () {
+ BLUE="\033[34;01m"
+ GREEN="\033[32;01m"
+ YELLOW="\033[33;01m"
+ PURPLE="\033[35;01m"
+ RED="\033[31;01m"
+ OFF="\033[0m"
+ CYAN="\033[36;01m"
+ COLORS=($BLUE $GREEN $YELLOW $RED $PURPLE $CYAN)
+}
+
+function colorize () {
+ if [ "$usecolors" == "yes" ]; then
+ local typestr=`echo "$@" | @SED@ 's/\(^[^:]*\).*$/\1/'`
+ [ "$typestr" == "Debug" ] && type=0
+ [ "$typestr" == "Info" ] && type=1
+ [ "$typestr" == "Warning" ] && type=2
+ [ "$typestr" == "Error" ] && type=3
+ [ "$typestr" == "Fatal" ] && type=4
+ [ "$typestr" == "Halt" ] && type=5
+ color=${COLORS[$type]}
+ endcolor=$OFF
+ echo -e "$color$@$endcolor"
+ else
+ echo -e "$@"
+ fi
+}
+
+# We have the following message levels:
+# 0 - debug - blue
+# 1 - normal messages - green
+# 2 - warnings - yellow
+# 3 - errors - red
+# 4 - fatal - purple
+# 5 - halt - cyan
+# First variable passed is the error level, all others are printed
+
+# if 1, echo out all warnings, errors, or fatal
+# used to capture output from handlers
+echo_debug_msg=0
+
+usecolors=yes
+
+function printmsg() {
+ [ ${#@} -gt 1 ] || return
+
+ type=$1
+ shift
+ if [ $type == 100 ]; then
+ typestr=`echo "$@" | @SED@ 's/\(^[^:]*\).*$/\1/'`
+ [ "$typestr" == "Debug" ] && type=0
+ [ "$typestr" == "Info" ] && type=1
+ [ "$typestr" == "Warning" ] && type=2
+ [ "$typestr" == "Error" ] && type=3
+ [ "$typestr" == "Fatal" ] && type=4
+ [ "$typestr" == "Halt" ] && type=5
+ typestr=""
+ else
+ types=(Debug Info Warning Error Fatal Halt)
+ typestr="${types[$type]}: "
+ fi
+
+ print=$[4-type]
+
+ if [ $echo_debug_msg == 1 ]; then
+ echo -e "$typestr$@" >&2
+ elif [ $debug ]; then
+ colorize "$typestr$@" >&2
+ fi
+
+ if [ $print -lt $loglevel ]; then
+ logmsg "$typestr$@"
+ fi
+}
+
+function logmsg() {
+ if [ -w "$logfile" ]; then
+ echo -e `date "+%h %d %H:%M:%S"` "$@" >> $logfile
+ fi
+}
+
+function passthru() {
+ printmsg 100 "$@"
+}
+function debug() {
+ printmsg 0 "$@"
+}
+function info() {
+ printmsg 1 "$@"
+}
+function warning() {
+ printmsg 2 "$@"
+}
+function error() {
+ printmsg 3 "$@"
+}
+function fatal() {
+ printmsg 4 "$@"
+ exit 2
+}
+function halt() {
+ printmsg 5 "$@"
+ exit 2
+}
+
+msgcount=0
+function msg {
+ messages[$msgcount]=$1
+ let "msgcount += 1"
+}
+
+#
+# enforces very strict permissions on configuration file $file.
+#
+
+function check_perms() {
+ local file=$1
+ debug "check_perms $file"
+ local perms
+ local owners
+
+ perms=($(stat -L --format='%A' $file))
+ debug "perms: $perms"
+ local gperm=${perms:4:3}
+ debug "gperm: $gperm"
+ local wperm=${perms:7:3}
+ debug "wperm: $wperm"
+
+ owners=($(stat -L --format='%g %G %u %U' $file))
+ local gid=${owners[0]}
+ local group=${owners[1]}
+ local owner=${owners[2]}
+
+ if [ "$owner" != 0 ]; then
+ echo "Configuration files must be owned by root! Dying on file $file"
+ fatal "Configuration files must be owned by root! Dying on file $file"
+ fi
+
+ if [ "$wperm" != '---' ]; then
+ echo "Configuration files must not be world writable/readable! Dying on file $file"
+ fatal "Configuration files must not be world writable/readable! Dying on file $file"
+ fi
+
+ if [ "$gperm" != '---' ]; then
+ case "$admingroup" in
+ $gid|$group) :;;
+
+ *)
+ if [ "$gid" != 0 ]; then
+ echo "Configuration files must not be writable/readable by group $group! Use the admingroup option in backupninja.conf. Dying on file $file"
+ fatal "Configuration files must not be writable/readable by group $group! Use the admingroup option in backupninja.conf. Dying on file $file"
+ fi
+ ;;
+ esac
+ fi
+}
+
+# simple lowercase function
+function tolower() {
+ echo "$1" | tr '[:upper:]' '[:lower:]'
+}
+
+# simple to integer function
+function toint() {
+ echo "$1" | tr -d '[:alpha:]'
+}
+
+#
+# function isnow(): returns 1 if the time/day passed as $1 matches
+# the current time/day.
+#
+# format is <day> at <time>:
+# sunday at 16
+# 8th at 01
+# everyday at 22
+#
+
+# we grab the current time once, since processing
+# all the configs might take more than an hour.
+nowtime=`date +%H`
+nowday=`date +%d`
+nowdayofweek=`date +%A`
+nowdayofweek=`tolower "$nowdayofweek"`
+
+function isnow() {
+ local when="$1"
+ set -- $when
+ whendayofweek=$1; at=$2; whentime=$3;
+ whenday=`toint "$whendayofweek"`
+ whendayofweek=`tolower "$whendayofweek"`
+ whentime=`echo "$whentime" | @SED@ 's/:[0-9][0-9]$//' | @SED@ -r 's/^([0-9])$/0\1/'`
+
+ if [ "$whendayofweek" == "everyday" -o "$whendayofweek" == "daily" ]; then
+ whendayofweek=$nowdayofweek
+ fi
+
+ if [ "$whenday" == "" ]; then
+ if [ "$whendayofweek" != "$nowdayofweek" ]; then
+ whendayofweek=${whendayofweek%s}
+ if [ "$whendayofweek" != "$nowdayofweek" ]; then
+ return 0
+ fi
+ fi
+ elif [ "$whenday" != "$nowday" ]; then
+ return 0
+ fi
+
+ [ "$at" == "at" ] || return 0
+ [ "$whentime" == "$nowtime" ] || return 0
+
+ return 1
+}
+
+function usage() {
+ cat << EOF
+$0 usage:
+This script allows you to coordinate system backup by dropping a few
+simple configuration files into @CFGDIR@/backup.d/. Typically, this
+script is run hourly from cron.
+
+The following options are available:
+-h, --help This usage message
+-d, --debug Run in debug mode, where all log messages are
+ output to the current shell.
+-f, --conffile FILE Use FILE for the main configuration instead
+ of @CFGDIR@/backupninja.conf
+-t, --test Test run mode. This will test if the backup
+ could run, without actually preforming any
+ backups. For example, it will attempt to authenticate
+ or test that ssh keys are set correctly.
+-n, --now Perform actions now, instead of when they might
+ be scheduled. No output will be created unless also
+ run with -d.
+ --run FILE Execute the specified action file and then exit.
+ Also puts backupninja in debug mode.
+
+When in debug mode, output to the console will be colored:
+EOF
+ usecolors=yes
+ colorize "Debug: Debugging info (when run with -d)"
+ colorize "Info: Informational messages (verbosity level 4)"
+ colorize "Warning: Warnings (verbosity level 3 and up)"
+ colorize "Error: Errors (verbosity level 2 and up)"
+ colorize "Fatal: Errors which halt a given backup action (always shown)"
+ colorize "Halt: Errors which halt the whole backupninja run (always shown)"
+}
+
+##
+## this function handles the running of a backup action
+##
+## these globals are modified:
+## halts, fatals, errors, warnings, actions_run, errormsg
+##
+
+function process_action() {
+ local file="$1"
+ local suffix="$2"
+ local run="no"
+ setfile $file
+
+ # skip over this config if "when" option
+ # is not set to the current time.
+ getconf when "$defaultwhen"
+ if [ "$processnow" == 1 ]; then
+ info ">>>> starting action $file (because of --now)"
+ run="yes"
+ elif [ "$when" == "hourly" ]; then
+ info ">>>> starting action $file (because 'when = hourly')"
+ run="yes"
+ else
+ IFS=$'\t\n'
+ for w in $when; do
+ IFS=$' \t\n'
+ isnow "$w"
+ ret=$?
+ IFS=$'\t\n'
+ if [ $ret == 0 ]; then
+ debug "skipping $file because it is not $w"
+ else
+ info ">>>> starting action $file (because it is $w)"
+ run="yes"
+ fi
+ done
+ IFS=$' \t\n'
+ fi
+ debug $run
+ [ "$run" == "no" ] && return
+
+ let "actions_run += 1"
+
+ # call the handler:
+ local bufferfile=`maketemp backupninja.buffer`
+ echo "" > $bufferfile
+ echo_debug_msg=1
+ (
+ . $scriptdirectory/$suffix $file
+ ) 2>&1 | (
+ while read a; do
+ echo $a >> $bufferfile
+ [ $debug ] && colorize "$a"
+ done
+ )
+ retcode=$?
+ # ^^^^^^^^ we have a problem! we can't grab the return code "$?". grrr.
+ echo_debug_msg=0
+
+ _warnings=`cat $bufferfile | grep "^Warning: " | wc -l`
+ _errors=`cat $bufferfile | grep "^Error: " | wc -l`
+ _fatals=`cat $bufferfile | grep "^Fatal: " | wc -l`
+ _halts=`cat $bufferfile | grep "^Halt: " | wc -l`
+
+ ret=`grep "\(^Warning: \|^Error: \|^Fatal: \|Halt: \)" $bufferfile`
+ rm $bufferfile
+ if [ $_halts != 0 ]; then
+ msg "*halt* -- $file"
+ errormsg="$errormsg\n== halt request from $file==\n\n$ret\n"
+ passthru "Halt: <<<< finished action $file: FAILED"
+ elif [ $_fatals != 0 ]; then
+ msg "*failed* -- $file"
+ errormsg="$errormsg\n== fatal errors from $file ==\n\n$ret\n"
+ passthru "Fatal: <<<< finished action $file: FAILED"
+ elif [ $_errors != 0 ]; then
+ msg "*error* -- $file"
+ errormsg="$errormsg\n== errors from $file ==\n\n$ret\n"
+ error "<<<< finished action $file: ERROR"
+ elif [ $_warnings != 0 ]; then
+ msg "*warning* -- $file"
+ errormsg="$errormsg\n== warnings from $file ==\n\n$ret\n"
+ warning "<<<< finished action $file: WARNING"
+ else
+ msg "success -- $file"
+ info "<<<< finished action $file: SUCCESS"
+ fi
+
+ let "halts += _halts"
+ let "fatals += _fatals"
+ let "errors += _errors"
+ let "warnings += _warnings"
+}
+
+#####################################################
+## MAIN
+
+setupcolors
+conffile="@CFGDIR@/backupninja.conf"
+loglevel=3
+
+## process command line options
+
+while [ $# -ge 1 ]; do
+ case $1 in
+ -h|--help) usage;;
+ -d|--debug) debug=1;;
+ -t|--test) test=1;debug=1;;
+ -n|--now) processnow=1;;
+ -f|--conffile)
+ if [ -f $2 ]; then
+ conffile=$2
+ else
+ echo "-f|--conffile option must be followed by an existing filename"
+ fatal "-f|--conffile option must be followed by an existing filename"
+ usage
+ fi
+ # we shift here to avoid processing the file path
+ shift
+ ;;
+ --run)
+ debug=1
+ if [ -f $2 ]; then
+ singlerun=$2
+ processnow=1
+ else
+ echo "--run option must be followed by a backupninja action file"
+ fatal "--run option must be followed by a backupninja action file"
+ usage
+ fi
+ shift
+ ;;
+ *)
+ debug=1
+ echo "Unknown option $1"
+ fatal "Unknown option $1"
+ usage
+ exit
+ ;;
+ esac
+ shift
+done
+
+#if [ $debug ]; then
+# usercolors=yes
+#fi
+
+## Load and confirm basic configuration values
+
+# bootstrap
+if [ ! -r "$conffile" ]; then
+ echo "Configuration file $conffile not found."
+ fatal "Configuration file $conffile not found."
+fi
+
+# find $libdirectory
+libdirectory=`grep '^libdirectory' $conffile | @AWK@ '{print $3}'`
+if [ -z "$libdirectory" ]; then
+ if [ -d "@libdir@" ]; then
+ libdirectory="@libdir@"
+ else
+ echo "Could not find entry 'libdirectory' in $conffile."
+ fatal "Could not find entry 'libdirectory' in $conffile."
+ fi
+else
+ if [ ! -d "$libdirectory" ]; then
+ echo "Lib directory $libdirectory not found."
+ fatal "Lib directory $libdirectory not found."
+ fi
+fi
+
+# include shared functions
+. $libdirectory/tools
+. $libdirectory/vserver
+
+setfile $conffile
+
+# get global config options (second param is the default)
+getconf configdirectory @CFGDIR@/backup.d
+getconf scriptdirectory @datadir@
+getconf reportdirectory
+getconf reportemail
+getconf reporthost
+getconf reportspace
+getconf reportsuccess yes
+getconf reportuser
+getconf reportwarning yes
+getconf loglevel 3
+getconf when "Everyday at 01:00"
+defaultwhen=$when
+getconf logfile @localstatedir@/log/backupninja.log
+getconf usecolors "yes"
+getconf SLAPCAT /usr/sbin/slapcat
+getconf LDAPSEARCH /usr/bin/ldapsearch
+getconf RDIFFBACKUP /usr/bin/rdiff-backup
+getconf CSTREAM /usr/bin/cstream
+getconf MYSQLADMIN /usr/bin/mysqladmin
+getconf MYSQL /usr/bin/mysql
+getconf MYSQLHOTCOPY /usr/bin/mysqlhotcopy
+getconf MYSQLDUMP /usr/bin/mysqldump
+getconf PGSQLDUMP /usr/bin/pg_dump
+getconf PGSQLDUMPALL /usr/bin/pg_dumpall
+getconf PGSQLUSER postgres
+getconf GZIP /bin/gzip
+getconf RSYNC /usr/bin/rsync
+getconf admingroup root
+
+# initialize vservers support
+# (get config variables and check real vservers availability)
+init_vservers nodialog
+
+if [ ! -d "$configdirectory" ]; then
+ echo "Configuration directory '$configdirectory' not found."
+ fatal "Configuration directory '$configdirectory' not found."
+fi
+
+[ -f "$logfile" ] || touch $logfile
+
+if [ "$UID" != "0" ]; then
+ echo "`basename $0` can only be run as root"
+ exit 1
+fi
+
+## Process each configuration file
+
+# by default, don't make files which are world or group readable.
+umask 077
+
+# these globals are set by process_action()
+halts=0
+fatals=0
+errors=0
+warnings=0
+actions_run=0
+errormsg=""
+
+if [ "$singlerun" ]; then
+ files=$singlerun
+else
+ files=`find $configdirectory -follow -mindepth 1 -maxdepth 1 -type f ! -name '.*.swp' | sort -n`
+
+ if [ -z "$files" ]; then
+ fatal "No backup actions configured in '$configdirectory', run ninjahelper!"
+ fi
+fi
+
+for file in $files; do
+ [ -f "$file" ] || continue
+ [ "$halts" = "0" ] || continue
+
+ check_perms ${file%/*} # check containing dir
+ check_perms $file
+ suffix="${file##*.}"
+ base=`basename $file`
+ if [ "${base:0:1}" == "0" -o "$suffix" == "disabled" ]; then
+ info "Skipping $file"
+ continue
+ fi
+
+ if [ -e "$scriptdirectory/$suffix" ]; then
+ process_action $file $suffix
+ else
+ error "Can't process file '$file': no handler script for suffix '$suffix'"
+ msg "*missing handler* -- $file"
+ fi
+done
+
+## mail the messages to the report address
+
+if [ $actions_run == 0 ]; then doit=0
+elif [ "$reportemail" == "" ]; then doit=0
+elif [ $fatals != 0 ]; then doit=1
+elif [ $errors != 0 ]; then doit=1
+elif [ "$reportsuccess" == "yes" ]; then doit=1
+elif [ "$reportwarning" == "yes" -a $warnings != 0 ]; then doit=1
+else doit=0
+fi
+
+if [ $doit == 1 ]; then
+ debug "send report to $reportemail"
+ hostname=`hostname`
+ [ $warnings == 0 ] || subject="WARNING"
+ [ $errors == 0 ] || subject="ERROR"
+ [ $fatals == 0 ] || subject="FAILED"
+
+ {
+ for ((i=0; i < ${#messages[@]} ; i++)); do
+ echo ${messages[$i]}
+ done
+ echo -e "$errormsg"
+ if [ "$reportspace" == "yes" ]; then
+ previous=""
+ for i in $(ls "$configdirectory"); do
+ backuploc=$(grep ^directory "$configdirectory"/"$i" | @AWK@ '{print $3}')
+ if [ "$backuploc" != "$previous" -a -n "$backuploc" ]; then
+ df -h "$backuploc"
+ previous="$backuploc"
+ fi
+ done
+ fi
+ } | mail -s "backupninja: $hostname $subject" $reportemail
+fi
+
+if [ $actions_run != 0 ]; then
+ info "FINISHED: $actions_run actions run. $fatals fatal. $errors error. $warnings warning."
+ if [ "$halts" != "0" ]; then
+ info "Backup was halted prematurely. Some actions may not have run."
+ fi
+fi
+
+if [ -n "$reporthost" ]; then
+ debug "send $logfile to $reportuser@$reporthost:$reportdirectory"
+ rsync -qt $logfile $reportuser@$reporthost:$reportdirectory
+fi
diff --git a/src/ninjahelper.in b/src/ninjahelper.in
new file mode 100755
index 0000000..040727b
--- /dev/null
+++ b/src/ninjahelper.in
@@ -0,0 +1,268 @@
+#!@BASH@
+# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*-
+
+####################################################
+## Functions
+
+##
+## returns the next available file name given a file
+## in the form @CFGDIR@/backup.d/10.sys
+## sets variable $next_filename
+##
+get_next_filename() {
+ next_filename=$1
+ dir=`dirname $next_filename`
+ file=`basename $next_filename`
+ number=${file:0:2}
+ suffix=${file:3}
+ while [ -f $next_filename ]; do
+ let "number += 1"
+ next_filename="$dir/$number.$suffix"
+ done
+}
+
+##
+## installs packages (passed in as $@) if not present
+##
+require_packages() {
+ for pkg in "$@"; do
+ installed=`dpkg -s $pkg | grep 'ok installed'`
+ if [ -z "$installed" ]; then
+ booleanBox "install $pkg?" "This backup action requires package $pkg. Do you want to install it now?"
+ if [ $? = 0 ]; then
+ apt-get install $pkg
+ echo "hit return to continue...."
+ read
+ fi
+ fi
+ done
+}
+
+##
+## menu for the wizards
+##
+donew() {
+ # (re-)initialize vservers support
+ init_vservers
+ # menu
+ listBegin "new action menu" "select an action to create"
+ listItem return "return to main menu"
+ for data in $HELPERS; do
+ data=${data//_/ }
+ helper_function=${data%%:*}
+ helper_info=${data##*:}
+ listItem $helper_function "$helper_info"
+ done
+ listDisplay menu
+
+ [ $? = 1 ] && return
+ result="$REPLY"
+ [ "$result" = "return" -o "$result" = "" ] && return
+ run_wizard=${result}_wizard
+ $run_wizard
+ result=$?
+ # 0 is ok, 1 is cancel, anything else is bad.
+ if [ $result != 1 -a $result != 0 ]; then
+ echo "An error occurred ($result), bailing out. Hit return to continue."
+ read
+ fi
+}
+
+do_rm_action() {
+ booleanBox "remove action" "Are you sure you want to remove action file $1?"
+ if [ $? = 0 ]; then
+ rm $1;
+ fi
+}
+
+do_run() {
+ backupninja --run $1
+ echo "Hit return to continue..."
+ read
+}
+
+do_xedit() {
+ if [ -z "$EDITOR" -o ! -x "`which $EDITOR`" ]; then
+ if [ -h /etc/alternatives/editor -a -x "`readlink /etc/alternatives/editor`" ]; then
+ EDITOR="`readlink /etc/alternatives/editor`"
+ elif [ -x "`which nano`" ]; then
+ EDITOR="`which nano`"
+ elif [ -x "`which vim`" ]; then
+ EDITOR="`which vim`"
+ elif [ -x "`which vi`" ]; then
+ EDITOR="`which vi`"
+ else
+ echo "No suitable editor found."
+ echo "Please define $EDITOR or configure /etc/alternatives/editor."
+ exit
+ fi
+ fi
+ $EDITOR $1
+}
+
+do_run_test() {
+ backupninja --test --run $1
+ echo "Hit return to continue..."
+ read
+}
+
+do_disable() {
+ mv $1 $1.disabled
+}
+
+do_enable() {
+ mv $1 ${1%.*}
+}
+
+do_rename() {
+ dir=`dirname $1`
+ filename=`basename $1`
+ inputBox "rename action" "enter a new filename" $filename
+ mv $dir/$filename $dir/$REPLY
+}
+
+doaction() {
+ action=$1
+ base=`basename $action`
+ if [ "${base##*.}" == "disabled" ]; then
+ enable="enable";
+ else
+ enable="disable";
+ fi
+ while true; do
+ menuBox "action menu" "$action $first" \
+ main "return to main menu" \
+ view "view configuration" \
+ xedit "launch external editor" \
+ $enable "$enable action" \
+ name "change the filename" \
+ run "run this action now" \
+ test "do a test run" \
+ kill "remove this action"
+ [ $? = 1 ] && return;
+ result="$REPLY"
+ case "$result" in
+ "view") dialog --textbox $action 0 0;;
+ "xedit") do_xedit $action;;
+ "disable") do_disable $action; return;;
+ "enable") do_enable $action; return;;
+ "name") do_rename $action; return;;
+ "run") do_run $action;;
+ "test") do_run_test $action;;
+ "kill") do_rm_action $action; return;;
+ "main") return;;
+ esac
+ done
+}
+
+#####################################################
+## begin program
+
+if [ ! -x "`which dialog`" ]; then
+ echo "ninjahelper is a menu based wizard for backupninja."
+ echo "It requires 'dialog' in order to run. Do you want to install dialog now?"
+ while true; do
+ echo -n "(yes/no): "
+ read install
+ if [ "$install" == "yes" ]; then
+ apt-get install dialog
+ break
+ elif [ "$install" == "no" ]; then
+ exit
+ else
+ echo "You must answer 'yes' or 'no'"
+ fi
+ done
+fi
+
+# bootstrap
+conffile="@CFGDIR@/backupninja.conf"
+if [ ! -r "$conffile" ]; then
+ echo "Configuration file $conffile not found."
+ exit 1
+fi
+
+# find $libdirectory
+libdirectory=`grep '^libdirectory' $conffile | @AWK@ '{print $3}'`
+if [ -z "$libdirectory" ]; then
+ if [ -d "@libdir@" ]; then
+ libdirectory="@libdir@"
+ else
+ echo "Could not find entry 'libdirectory' in $conffile."
+ exit 1
+ fi
+else
+ if [ ! -d "$libdirectory" ]; then
+ echo "Lib directory $libdirectory not found."
+ exit 1
+ fi
+fi
+
+# include shared functions
+. $libdirectory/easydialog
+. $libdirectory/tools
+. $libdirectory/vserver
+
+# am I running as root?
+if [ "$UID" != "0" ]; then
+ msgBox "warning" "`basename $0` must be run by root!"
+ exit 1
+fi
+
+# get global config options (second param is the default)
+setfile $conffile
+getconf configdirectory @CFGDIR@/backup.d
+if [ ! -d $configdirectory ]; then
+ msgBox "warning" "The backupninja configuration directory $configdirectory does not exist. Ninjahelper cannot run without it!"
+ exit 1
+fi
+getconf scriptdirectory @datadir@
+
+# load all the helpers
+HELPERS=""
+for file in `find $scriptdirectory -follow -name '*.helper'`; do
+ . $file
+ if [ $? != 0 ]; then
+ echo "An error occurred while loading $file. Hit return to continue."
+ read
+ fi
+done
+
+setApplicationTitle "ninjahelper"
+setDimension 75 19
+
+#####################################################
+## main event loop
+
+while true; do
+
+menulist=
+action=
+let "i = 1"
+for file in `find ${configdirectory} -follow -mindepth 1 -maxdepth 1 -type f ! -name '.*.swp' | sort -n`; do
+ menulist="$menulist $i $file"
+ actions[$i]=$file
+ let "i += 1"
+done
+
+menuBox "main menu" "Select a backup action for more options, or create a new action:" $menulist \
+ new "create a new backup action" \
+ quit "leave ninjahelper"
+
+[ $? = 1 -o $? = 255 ] && exit 0;
+
+choice="$REPLY"
+if [ "$choice" == "new" ]; then
+ donew;
+elif [ "$choice" == "quit" ]; then
+ exit 0;
+else
+ action=${actions[$choice]};
+ if [ -f "$action" ]; then
+ doaction $action
+ else
+ msgBox "error" "error: cannot find the file '$action'"
+ fi
+fi
+
+done
diff --git a/src/ninjareport.in b/src/ninjareport.in
new file mode 100755
index 0000000..b68efb8
--- /dev/null
+++ b/src/ninjareport.in
@@ -0,0 +1,205 @@
+#!@BASH@
+# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*-
+#
+#
+# Ninjareport - generate a single simple report for a lot of hosts
+#
+# requires logtail
+#
+# Copyright (C) 2007 - riseup.net -- property is theft.
+
+# TODO:
+#
+# . check for logs that are never updating and warn
+# . change constantly updating logs (maildir) to be more friendly
+# . documentation
+# . maybe make config option that lists all hosts that should report-in, and if
+# one doesn't then warn
+# . restrict rsync somehow?
+# . abstract path for logtail
+# . on the report master, the reportdirectory should be set where the reports will be going, note this
+
+mail=1
+display=0
+
+process() {
+
+# look in the logfile for any lines like the following:
+# Jan 20 01:02:46 Info: FINISHED: 2 actions run. 0 fatal. 0 error. 0 warning.
+#
+# note: some backups never finish, such as the maildir one, need to handle these
+# perhaps by looking for FAILED messages?
+# note2: what about logs that aren't being updated? this is a failure case and
+# should be looked for
+# note3: there are also these entries:
+# Jan 20 14:00:01 Fatal: No backup actions configured in '/etc/backup.d', run ninjahelper!
+
+# The following has to be done without invoking a subshell (see BashFAQ #24)
+logupdates=`maketemp ninjadata`
+
+/usr/sbin/logtail -f $host > $logupdates
+grep FINISHED $logupdates |
+(
+ fatal=0
+ warning=0
+ error=0
+
+ while read line
+ do
+ line_array=($line)
+ fatal=$(($fatal + ${line_array[8]}))
+ error=$(($error + ${line_array[10]}))
+ warning=$(($warning + ${line_array[12]}))
+ done
+ if (( $fatal || $warning || $error )); then
+ echo "`basename $host .log`: $fatal fatals found, $error errors found, $warning warnings found" >> $statusfile
+ echo "" >> $reportappend
+ echo "`basename $host .log` log entries since last ninjareport" >> $reportappend
+ echo "---------" >> $reportappend
+ cat $logupdates >> $reportappend
+ rm $logupdates
+ fi
+)
+
+}
+
+generatereport() {
+
+reportfile=`maketemp ninjareport`
+
+# Generate a report, only if there are failures
+if [ -s $statusfile ]; then
+ echo " backupninja mission failures - `date`" >> $reportfile
+ echo " --------------------------------------------------------------" >> $reportfile
+ echo "" >> $reportfile
+ cat $statusfile | column -t >> $reportfile
+ echo "" >> $reportfile
+ echo " log entries from failed reports" >> $reportfile
+ echo " -----------------------------------" >> $reportfile
+ cat $reportappend >> $reportfile
+fi
+
+}
+
+usage() {
+ cat << EOF
+This script generates a backupninja status report for all configured
+systems. It requires that each status report is placed in a spot where
+ninjareport can read it, reports are mailed to the reportemail
+configured in @CFGDIR@/backupninja.conf.
+
+The following options are available:
+-h, --help This usage message
+-f, --conffile FILE Use FILE for the configuration instead
+ of @CFGDIR@/backupninja.conf
+-m, --mail <email> Mail the report to this address
+-o, --out Don't mail the report, just display it
+
+EOF
+}
+
+#####################################################
+## MAIN
+
+conffile="@CFGDIR@/backupninja.conf"
+
+## process command line options
+
+while [ $# -ge 1 ]; do
+ case $1 in
+ -h|--help)
+ usage
+ exit 0
+ ;;
+ -f|--conffile)
+ if [ -f $2 ]; then
+ conffile=$2
+ else
+ echo "-f|--conffile option must be followed by an existing filename"
+ fatal "-f|--conffile option must be followed by an existing filename"
+ usage
+ fi
+ # we shift here to avoid processing the file path
+ shift
+ ;;
+ -m|--mail)
+ reportemail=$2
+ shift
+ ;;
+ -o|--out)
+ mail=0
+ display=1
+ ;;
+ *)
+ echo "Unknown option $1"
+ usage
+ exit
+ ;;
+ esac
+ shift
+done
+
+## Load and confirm basic configuration values
+
+# bootstrap
+if [ ! -r "$conffile" ]; then
+ echo "Configuration file $conffile not found."
+ fatal "Configuration file $conffile not found."
+fi
+
+# find $libdirectory
+libdirectory=`grep '^libdirectory' $conffile | awk '{print $3}'`
+if [ -z "$libdirectory" ]; then
+ if [ -d "@libdir@" ]; then
+ libdirectory="@libdir@"
+ else
+ echo "Could not find entry 'libdirectory' in $conffile."
+ exit 1
+ fi
+else
+ if [ ! -d "$libdirectory" ]; then
+ echo "Lib directory $libdirectory not found."
+ exit 1
+ fi
+fi
+
+# include shared functions
+. $libdirectory/tools
+
+setfile $conffile
+
+getconf reportdirectory
+getconf reportemail
+
+## Process each configuration file
+
+hosts=`find $reportdirectory -follow -mindepth 1 -maxdepth 1 -type f ! -name '*.offset' | sort -n`
+
+if [ -z "$hosts" ]; then
+ echo "Fatal: No backupninja reports found in '$reportdirectory'!"
+ mail=0
+fi
+
+statusfile=`maketemp ninjastatus`
+reportappend=`maketemp ninjaappend`
+
+for host in $hosts; do
+ [ -f "$host" ] || continue
+ # Check somehow that the file is a valid report file
+ process $host
+done
+
+generatereport
+
+## mail the report to the report address or display it
+
+if [ -s $reportfile ]; then
+ if [ $mail == 1 ]; then
+ mail -s "backupninja mission failure report" $reportemail < $reportfile
+ fi
+fi
+
+if [ $display == 1 ]; then
+ cat $reportfile
+fi
+