diff --git a/backupninja b/backupninja
index c8764ab651d3ea3402d1a4192ee47d5070ab28fc..3b3b16d0b363bb17ad7ea93a875d08a03feecc73 100755
--- a/backupninja
+++ b/backupninja
@@ -16,45 +16,35 @@
 # GNU General Public License for more details.
 #
 
-#####################################################
-## DEFAULTS
-
-DEBUG=${DEBUG:=0}
-CONFFILE="/etc/backupninja.conf"
-USECOLOURS=1
-
 #####################################################
 ## FUNCTIONS
 
 function setupcolors() {
-	if [  "$USECOLOURS" == 1 ]
-	then
-		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"
-	fi
+	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"
 }
 
-function run() {
-	RUNERROR=0
-	debug 0 "$@"
-	returnstring=`$@ 2>&1`
-	RUNERROR=$?
-	RUNERRORS=$[RUNERRORS+RUNERROR]
-	if [ "$RUNERROR" != 0 ]; then
-		debug 3 "Exitcode $RUNERROR returned when running: $@"
-		debug 3 "$returnstring"
-	else
-		debug 0 "$returnstring"
-	fi
-	return $RUNERROR
-}
-
-# We have the following debug levels:
+#function run() {
+#	RUNERROR=0
+#	debug 0 "$@"
+#	returnstring=`$@ 2>&1`
+#	RUNERROR=$?
+#	RUNERRORS=$[RUNERRORS+RUNERROR]
+#	if [ "$RUNERROR" != 0 ]; then
+#		debug 3 "Exitcode $RUNERROR returned when running: $@"
+#		debug 3 "$returnstring"
+#	else
+#		debug 0 "$returnstring"
+#	fi
+#	return $RUNERROR
+#}
+
+# We have the following message levels:
 # 0 - debug - blue
 # 1 - normal messages - green
 # 2 - warnings - yellow
@@ -66,33 +56,52 @@ function run() {
 # used to capture output from handlers
 echo_debug_msg=0
 
-function debug() {
+usecolor=yes
 
+function printmsg() {
 	[ ${#@} -gt 1 ] || return
 	 
-	TYPES=(Debug Info Warning Error Fatal)
-	COLOURS=($BLUE $GREEN $YELLOW $RED $PURPLE)
+	types=(Debug Info Warning Error Fatal)
 	type=$1
-	colour=${COLOURS[$type]}
-	shift
 	print=$[4-type]
-	if [ "$print" -lt "$loglevel" -o "$DEBUG" == 1 ]; then
-		if [ -z "$logfile" ]; then
-			echo -e "${colour}${TYPES[$type]}: $@${OFF}" >&2
-		else
-			if [ "$DEBUG" == 1 -o "$type" == 4 ]; then
-				echo -e "${colour}${TYPES[$type]}: $@${OFF}" >&2
-			fi
-			echo -e "${colour}${TYPES[$type]}: $@${OFF}" >> $logfile
-		fi
+	typestr=${types[$type]}
+	if [ "$usecolor" == "yes" ]; then
+		colors=($BLUE $GREEN $YELLOW $RED $PURPLE)
+		color=${colors[$type]}
+		endcolor=$OFF
 	fi
+	
+	shift
+	
 	if [ "$echo_debug_msg" != "0" -a "$type" -gt "1" ]; then
-		echo -e "${TYPES[$type]}: $@"
+		echo -e "$typestr: $@"
+	fi
+	
+	if [ "$debug" == 1 ]; then
+		echo -e "${color}$typestr: $@${endcolor}" >&2
+	fi
+	
+	if [ "$print" -lt "$loglevel" ]; then
+		if [ -w "$logfile" ]; then
+			echo -e "${color}$typestr: $@${endcolor}" >> $logfile
+		fi
 	fi
 }
 
+function debug() {
+	printmsg 0 "$@"
+}
+function info() {
+	printmsg 1 "$@"
+}
+function warning() {
+	printmsg 2 "$@"
+}
+function error() {
+	printmsg 3 "$@" 
+}
 function fatal() {
-	debug 4 "$@"
+	printmsg 4 "$@"
 	exit 2
 }
 
@@ -205,60 +214,120 @@ function isnow() {
 	return 1
 }
 
-#####################################################
-## MAIN
+function usage() {
+	cat << EOF
+$0 usage:
+This script allows you to coordinate system backup by dropping a few
+simple configuration files into /etc/backup.d/. Typically, this
+script is run hourly from cron.
 
-## process command line options
+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 /etc/backupninja.conf
+-t, --test           Run in test mode, no actions are actually taken.
+-n, --now            Perform actions now, instead of when they
+                     might be scheduled.
+When using colored output, there are:
+EOF
+	debug=1
+	debug   "Debugging info (when run with -d)"
+	info    "Informational messages (verbosity level 4)"
+	warning "Warnings (verbosity level 3 and up)"
+	error   "Errors (verbosity level 2 and up)"
+	fatal   "Fatal, halting errors (always shown)"
+}
 
-if [ "$1" == "--help" ]; then
-	HELP=1;DEBUG=1;loglevel=4
-else
-	while getopts h,f:,d,t option
-	do
-		case "$option" in
-			h) HELP=1;DEBUG=1;loglevel=4;;
-			d) DEBUG=1;loglevel=4;;
-			f) CONFFILE="$OPTARG";;
-			t) test=1;DEBUG=1;;
-		esac
-	done
-fi
+function process_action() {
+	local file="$1"
+	local suffix="$2"
+
+	setfile $file
+
+	# skip over this config if "when" option
+	# is not set to the current time.
+	getconf when "$defaultwhen"
+	if [ "$processnow" == 1 ]; then
+		info "running $file because of --now"
+	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"
+				return
+			else
+				info "running $file because it is $w"
+			fi
+		done
+		IFS=$' \t\n'
+	fi
 	
-setupcolors
+	echo_debug_msg=1
+	# call the handler:
+	ret=`( . $scriptdir/$suffix $file )`
+	retcode="$?"
+	warnings=`echo $ret | grep -e "^Warning: " | wc -l`
+	errors=`echo $ret | grep -e "^Error: \|^Fatal: " | wc -l`
+	if [ $errors != 0 ]; then
+		msg "*failed* -- $file"
+		errormsg="$errormsg\n== errors from $file ==\n\n$ret\n"
+	elif [ $warnings != 0 ]; then
+		msg "*warning* -- $file"
+		errormsg="$errormsg\n== warnings from $file ==\n\n$ret\n"
+	elif [ $retcode == 0 ]; then
+		msg "success -- $file"
+	else
+		msg "unknown -- $file"
+	fi
+	echo_debug_msg=0
+}
 
-## Print help
+#####################################################
+## MAIN
 
-if [ "$HELP" == 1 ]; then
-cat << EOF
-$0 usage:
-This script allows you to coordinate system backup by dropping a few
-simple configuration files into /etc/backup.d/. In general, this script
-is run from a cron job late at night. 
+setupcolors
+conffile="/etc/backupninja.conf"
 
-The following options are available:
--h         This help message
--d         Run in debug mode, where all log messages are output to the current shell.
--f <file>  Use <file> for the main configuration instead of /etc/backupninja.conf
--t         Run in test mode, no actions are actually taken.
+## process command line options
 
-When using colored output, there are:
-EOF
-debug 0 "Debugging info (when run with -d)"
-debug 1 "Informational messages (verbosity level 4)"
-debug 2 "Warnings (verbosity level 3 and up)"
-debug 3 "Errors (verbosity level 2 and up)"
-debug 4 "Fatal, halting errors (always shown)"
-exit 0
-fi
+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
+				fatal "-f|--conffile option must be followed by an existing filename"
+				usage
+			fi
+			# we shift here to avoid processing the file path 
+			shift
+			;;
+		*)
+			fatal "Unknown option $1"
+			usage
+			;;
+	esac
+	shift
+done																										
 
 ## Load and confirm basic configuration values
 
 # bootstrap
-[ -r "$CONFFILE" ] || fatal "Configuration file $CONFFILE not found."
-scriptdir=`grep scriptdirectory $CONFFILE | awk '{print $3}'`
-[ -n "$scriptdir" ] || fatal "Cound not find entry 'scriptdirectory' in $CONFFILE."
+[ -r "$conffile" ] || fatal "Configuration file $conffile not found."
+scriptdir=`grep scriptdirectory $conffile | awk '{print $3}'`
+[ -n "$scriptdir" ] || fatal "Cound not find entry 'scriptdirectory' in $conffile"
 [ -d "$scriptdir" ] || fatal "Script directory $scriptdir not found."
-setfile $CONFFILE
+setfile $conffile
 
 # get global config options (second param is the default)
 getconf configdirectory /etc/backup.d
@@ -269,6 +338,7 @@ getconf loglevel 3
 getconf when "Everyday at 01:00"
 defaultwhen=$when
 getconf logfile /var/log/backupninja.log
+getconf usecolors "yes"
 getconf SLAPCAT /usr/sbin/slapcat
 getconf RDIFFBACKUP /usr/bin/rdiff-backup
 getconf MYSQL /usr/bin/mysql
@@ -277,11 +347,15 @@ getconf MYSQLDUMP /usr/bin/mysqldump
 getconf GZIP /bin/gzip
 
 [ -d "$configdirectory" ] || fatal "Configuration directory '$configdirectory' not found."
-[ `id -u` == "0" ] || fatal "Can only be run as root"
+
+if [ "$UID" != "0" ]; then
+	echo "$0 can only be run as root"
+	exit 1
+fi
 
 ## Process each configuration file
 
-debug 1 "====== starting at "`date`" ======"
+info "====== starting at "`date`" ======"
 
 # by default, don't make files which are world or group readable.
 umask 077
@@ -295,54 +369,14 @@ for file in $configdirectory/*; do
 	suffix="${file##*.}"
 	base=`basename $file`
 	if [ "${base:0:1}" == "0" ]; then
-		debug 1 "Skipping $file"
+		info "Skipping $file"
 		continue
-	else
-		debug 1 "Processing $file"
 	fi
 
 	if [ -e "$scriptdir/$suffix" ]; then
-		setfile $file
-
-		# skip over this config if "when" option
-		# is not set to the current time.
-		getconf when "$defaultwhen"
-		IFS=$'\t\n'
-		for w in $when; do
-			IFS=$' \t\n'
-			isnow "$w"
-			ret=$?
-			IFS=$'\t\n'
-			if [ $ret == 0 ]; then
-				debug 0 "skipping $file because it is not $w"
-				continue
-			else
-				debug 0 "running $file because it is $w"
-				continue
-			fi		
-		done
-		IFS=$' \t\n'
-
-		echo_debug_msg=1
-		# call the handler:
-		ret=`( . $scriptdir/$suffix $file )`
-		retcode="$?"
-		warnings=`echo $ret | grep -e "^Warning: " | wc -l`
-		errors=`echo $ret | grep -e "^Error: \|^Fatal: " | wc -l`
-		if [ $errors != 0 ]; then
-			msg "*failed* -- $file"
-			errormsg="$error\n== errors from $file ==\n\n$ret\n"
-		elif [ $warnings != 0 ]; then
-			msg "*warning* -- $file"
-			errormsg="$error\n== warnings from $file ==\n\n$ret\n"
-		elif [ $retcode == 0 ]; then
-			msg "success -- $file"
-		else
-			msg "unknown -- $file"
-		fi
-		echo_debug_msg=0
+		process_action $file $suffix
 	else
-		debug 3 "Can't process file '$file': no handler script for suffix '$suffix'"
+		error "Can't process file '$file': no handler script for suffix '$suffix'"
 		msg "*missing handler* -- $file"
 	fi
 done
@@ -366,6 +400,6 @@ if [ $doit == 1 ]; then
 	} | mail $reportemail -s "backupninja: $hostname"
 fi
 
-debug 1 "====== finished at "`date`" ======"
+info "====== finished at "`date`" ======"
 
 ############################################################
diff --git a/changelog b/changelog
index 0111e7c8396b3ed0a461c9f1369aebbdc72851ce..2036ee2a0cd2f5fc66a54ea02b72d0089cf5d847 100644
--- a/changelog
+++ b/changelog
@@ -1,3 +1,9 @@
+version 0.4.1 -- Jan 3 2005
+	added $usecolors and now more conservative about when colors are echoed.
+	fixed major bug, 'when' actually works now.
+	replaced debug function with debug, info, warning, error, fatal.
+	added --now option to force all actions to be performed now.
+	
 version 0.4 -- Dec 26 2004
 	added "when" option, so that all configs can specify when
       they are to be run.
diff --git a/etc/backupninja.conf b/etc/backupninja.conf
index 45af4ed4f6651fe507b81b659f99f9c3d0446a88..1c33830b57617ca56903b2d2136487d1d281582f 100644
--- a/etc/backupninja.conf
+++ b/etc/backupninja.conf
@@ -37,3 +37,6 @@ configdirectory = /etc/backup.d
 
 # where backupninja helper scripts are found
 scriptdirectory = /usr/share/backupninja
+
+# whether to use colors in the log file
+usecolors = yes
diff --git a/handlers/ldap b/handlers/ldap
index 06e4e288e14de25823067458548ab7f32835cc70..9ead9d17db491fffa1860d54d197e596fa7bfd5d 100644
--- a/handlers/ldap
+++ b/handlers/ldap
@@ -47,20 +47,20 @@ if [ "$ldif" == "yes" ]; then
 			fatal "Couldn't create ldif dump file: $dumpdir/$dbsuffix.ldif"
 		fi
 		execstr="$SLAPCAT -f $conf -b $dbsuffix -l $dumpdir/$dbsuffix.ldif"
-		debug 0 "$execstr"
+		debug "$execstr"
 		if [ ! $test ]; then
 			output=`$execstr`
 			code=$?
 			if [ "$code" == "0" ]; then
-				debug 0 $output
-				debug 1 "Successfully finished ldif export of $dbsuffix"
+				debug $output
+				info "Successfully finished ldif export of $dbsuffix"
 			else
-				debug 2 $output
-				debug 2 "Failed ldif export of $dbsuffix"
+				warning $output
+				warning "Failed ldif export of $dbsuffix"
 			fi
 			if [ "$compress" == "yes" ]; then
 				output=`$GZIP -f "$dumpdir/$dbsuffix.ldif" 2>&1`
-				debug 0 $output
+				debug $output
 			fi
 		fi
 	done	
diff --git a/handlers/mysql b/handlers/mysql
index 4439bcc533173f84b9ca962ada281781d11f756e..165ebc68829c35ec63a59154183c7d0e0b5b19e1 100644
--- a/handlers/mysql
+++ b/handlers/mysql
@@ -33,7 +33,7 @@ if [ "$dbusername" != "" ]; then
 	if [ -f $mycnf ]; then
 		# rename temporarily
 		tmpcnf="$home/my.cnf.disable"
-		debug 0 "mv $mycnf $tmpcnf"
+		debug "mv $mycnf $tmpcnf"
 		mv $mycnf $tmpcnf
 	fi
 	oldmask=`umask`
@@ -60,31 +60,31 @@ fi
 if [ "$hotcopy" == "yes" ]; then 
 	if [ "$databases" == "all" ]; then
 		execstr="$MYSQLHOTCOPY --quiet --allowold --regexp /.\*/./.\*/ $hotdir"
-		debug 0 "su $user -c '$execstr'"
+		debug "su $user -c '$execstr'"
 		if [ ! $test ]; then
 			output=`su $user -c "$execstr" 2>&1`
 			code=$?
 			if [ "$code" == "0" ]; then
-				debug 0 $output
-				debug 1 "Successfully finished hotcopy of all mysql databases"
+				debug $output
+				info "Successfully finished hotcopy of all mysql databases"
 			else
-				debug 2 $output
-				debug 2 "Failed to hotcopy all mysql databases"
+				warning $output
+				warning "Failed to hotcopy all mysql databases"
 			fi
 		fi
 	else	
 		for db in $databases; do
 			execstr="$MYSQLHOTCOPY --allowold $db $hotdir"
-			debug 0 "su $user -c '$execstr'"
+			debug "su $user -c '$execstr'"
 			if [ ! $test ]; then
 				output=`su $user -c "$execstr" 2>&1`
 				code=$?
 				if [ "$code" == "0" ]; then
-					debug 0 $output
-					debug 1 "Successfully finished hotcopy of mysql database $db"
+					debug $output
+					info "Successfully finished hotcopy of mysql database $db"
 				else
-					debug 2 $output
-					debug 2 "Failed to hotcopy mysql database $db"
+					warning $output
+					warning "Failed to hotcopy mysql database $db"
 				fi
 			fi
 		done
@@ -100,32 +100,32 @@ if [ "$sqldump" == "yes" ]; then
 
 	for db in $databases; do
 		execstr="$MYSQLDUMP --lock-tables --complete-insert --add-drop-table --quick --quote-names $db > $dumpdir/${db}.sql"
-		debug 0 "su $user -c '$execstr'"
+		debug "su $user -c '$execstr'"
 		if [ ! $test ]; then
 			output=`su $user -c "$execstr" 2>&1`
 			code=$?
 			if [ "$code" == "0" ]; then
-				debug 0 $output
-				debug 1 "Successfully finished dump of mysql database $db"
+				debug $output
+				info "Successfully finished dump of mysql database $db"
 			else
-				debug 2 $output
-				debug 2 "Failed to dump mysql databases $db"
+				warning $output
+				warning "Failed to dump mysql databases $db"
 			fi
 		fi
 	done
 	
 	if [ "$compress" == "yes" ]; then
 		output=`$GZIP -f $dumpdir/*.sql 2>&1`
-		debug 0 $output
+		debug $output
 	fi
 fi
 
 if [ "$dbusername" != "" ]; then
 	## clean up tmp config file
-	debug 0 "rm $mycnf"
+	debug "rm $mycnf"
 	rm $mycnf
 	if [ -f "$tmpcnf" ]; then
-		debug 0 "mv $tmpcnf $mycnf"
+		debug "mv $tmpcnf $mycnf"
 		mv $tmpcnf $mycnf
 	fi
 fi
diff --git a/handlers/rdiff b/handlers/rdiff
index 1f2058f47c4adf6d862a03b9e12140d13868dc33..90ca2a3ebf39f72e7d626c11d72ab28a3d48193c 100644
--- a/handlers/rdiff
+++ b/handlers/rdiff
@@ -6,7 +6,7 @@
 setsection source
 getconf type; sourcetype=$type
 getconf label
-getconf user; sourceuser=$user
+getconf user root; sourceuser=$user
 getconf keep
 getconf include
 getconf exclude
@@ -25,7 +25,7 @@ getconf host; desthost=$host
 [ "$desttype" == "remote" ] || fatal "Only remote destinations are supported"
 
 # see if we can login
-debug 0 "su $sourceuser -c \"ssh -o PasswordAuthentication=no $desthost -l $destuser 'echo -n 1'\""
+debug "su $sourceuser -c \"ssh -o PasswordAuthentication=no $desthost -l $destuser 'echo -n 1'\""
 if [ ! $test ]; then
 	result=`su $sourceuser -c "ssh -o PasswordAuthentication=no $desthost -l $destuser 'echo -n 1'" 2>&1`
 	if [ "$result" != "1" ]; then
@@ -34,7 +34,7 @@ if [ ! $test ]; then
 fi
 
 # see that rdiff-backup has the same version as here
-debug 0 "su $sourceuser -c \"ssh $desthost -l $destuser '$RDIFFBACKUP -V'\""
+debug "su $sourceuser -c \"ssh $desthost -l $destuser '$RDIFFBACKUP -V'\""
 if [ ! $test ]; then
 	remoteversion=`su $sourceuser -c "ssh $desthost -l $destuser '$RDIFFBACKUP -V'" 2>&1`
 	localversion=`$RDIFFBACKUP -V`
@@ -62,16 +62,16 @@ if [ "$keep" -gt "0" ]; then
 	fi
 	removestr="${removestr}${destdir}/${label}";
 	
-	debug 0 "su $sourceuser -c '$removestr'"
+	debug "su $sourceuser -c '$removestr'"
 	if [ ! $test ]; then
 		output=`su $sourceuser -c "$removestr" 2>&1`
 		code=$?
 		if [ "$code" == "0" ]; then
-			debug 0 $output
-			debug 1 "Removing backups older than $keep days succeeded."
+			debug $output
+			info "Removing backups older than $keep days succeeded."
 		else
-			debug 2 $output
-			debug 2 "Failed removing backups older than $keep."
+			warning $output
+			warning "Failed removing backups older than $keep."
 		fi
 	fi
 fi
@@ -100,16 +100,16 @@ execstr="${execstr}--exclude '/*' "
 # include client-part and server-part
 execstr="${execstr}$execstr_clientpart $execstr_serverpart"
 
-debug 0 "su $sourceuser -c '$execstr'"
+debug "su $sourceuser -c '$execstr'"
 if [ ! $test ]; then
 	output=`su $sourceuser -c "$execstr" 2>&1`
 	code=$?
 	if [ "$code" == "0" ]; then
-		debug 0 $output
-		debug 1 "Successfully finished backing up source '$label'"
+		debug $output
+		info "Successfully finished backing up source '$label'"
 	else
-		debug 2 $output
-		debug 2 "Failed backup up source '$label'"
+		warning $output
+		warning "Failed backup up source '$label'"
 	fi
 fi	
 
diff --git a/handlers/sys b/handlers/sys
index 35a3919b7ac8d7bfb4a1226e5d27a576361a0a92..140db766f128a460fc5fd6b66cd2f20170d356ff 100755
--- a/handlers/sys
+++ b/handlers/sys
@@ -28,21 +28,21 @@ getconf hardwarefile /var/backups/hardware.txt
 
 if [ "$packages" == "yes" ]; then
 	if [ ! -x "`which dpkg`" ]; then
-		debug 2 "can't find dpkg, skipping installed packages report."
+		warning "can't find dpkg, skipping installed packages report."
 		packages="no"
 	fi
 fi
 
 if [ "$partitions" == "yes" ]; then
 	if [ ! -x "`which sfdisk`" ]; then
-		debug 2 "can't find sfdisk, skipping partition report."
+		warning "can't find sfdisk, skipping partition report."
 		partitions="no"
 	fi
 fi
 
 if [ "$hardware" == "yes" ]; then
 	if [ ! -x "`which discover`" ]; then
-		debug 2 "can't find discover, skipping hardware report."
+		warning "can't find discover, skipping hardware report."
 		hardware="no"
 	fi
 fi