--- zm-1.21.3.orig/src/zm_config.h
+++ zm-1.21.3/src/zm_config.h
@@ -0,0 +1,107 @@
+//
+// ZoneMinder Configuration, $Date: 2005/05/16 09:27:05 $, $Revision: 1.23 $
+// Copyright (C) 2003, 2004, 2005  Philip Coombes
+// 
+// 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.
+// 
+
+#include "config.h"
+#include "zm_config_defines.h"
+
+#define ZM_VERSION				"1.21.3"	// ZoneMinder version number, autogenerated do not change (from zmconfig)
+#define ZM_CONFIG				"/etc/zm/zm.conf"	// Path to the ZoneMinder config file, autogenerated do not change (from zmconfig)
+
+#define ZM_PATH_BIN				"/usr/bin"	// Path to the ZoneMinder executables, autogenerated do not change (from zmconfig)
+#define ZM_PATH_WEB				"/var/www/zm"	// Path to the ZoneMinder web files, autogenerated do not change (from zmconfig)
+#define ZM_PATH_CGI				"/usr/lib/cgi-bin"	// Path to the ZoneMinder cgi files, autogenerated do not change (from zmconfig)
+
+#define ZM_MAX_IMAGE_WIDTH		2048				// The largest image we imagine ever handling
+#define ZM_MAX_IMAGE_HEIGHT		1536				// The largest image we imagine ever handling
+#define ZM_MAX_IMAGE_COLOURS	3					// The largest image we imagine ever handling
+#define ZM_MAX_IMAGE_DIM		(ZM_MAX_IMAGE_WIDTH*ZM_MAX_IMAGE_HEIGHT)
+#define ZM_MAX_IMAGE_SIZE		(ZM_MAX_IMAGE_DIM*ZM_MAX_IMAGE_COLOURS)
+
+#define ZM_SCALE_SCALE			100					// The factor by which we bump up 'scale' to simulate FP
+#define ZM_RATE_SCALE			100					// The factor by which we bump up 'rate' to simulate FP
+
+#define ZM_MAX_FPS              30                  // The maximum frame rate we expect to handle
+#define ZM_SAMPLE_RATE          int(1000000/ZM_MAX_FPS) // A general nyquist sample frequency for delays etc
+
+extern char *ZM_DB_SERVER, *ZM_DB_NAME, *ZM_DB_USER, *ZM_DB_PASS;
+extern void zmLoadConfig();
+
+class ConfigItem
+{
+private:
+	char *name;
+	char *value;
+	char *type;
+
+	mutable enum { CFG_BOOLEAN, CFG_INTEGER, CFG_DECIMAL, CFG_STRING } cfg_type;
+	mutable union
+	{
+		bool boolean_value;
+		int integer_value;
+		double decimal_value;
+		char *string_value;
+	} cfg_value;
+	mutable bool accessed;
+
+public:
+	ConfigItem( const char *p_name, const char *p_value, const char *const p_type );
+	~ConfigItem();
+	void ConvertValue() const;
+	bool BooleanValue() const;
+	int IntegerValue() const;
+	double DecimalValue() const;
+	const char *StringValue() const;
+
+	inline operator bool() const
+	{
+		return( BooleanValue() );
+	}
+	inline operator int() const
+	{
+		return( IntegerValue() );
+	}
+	inline operator double() const
+	{
+		return( DecimalValue() );
+	}
+	inline operator const char *() const
+	{
+		return( StringValue() );
+	}
+};
+
+class Config
+{
+public:
+	ZM_CFG_DECLARE_LIST
+
+private:
+	int n_items;
+	ConfigItem **items;
+
+public:
+	Config();
+	~Config();
+
+	void Load();
+	void Assign();
+	const ConfigItem &Item( int id );
+};
+
+extern Config config;
--- zm-1.21.3.orig/scripts/zm
+++ zm-1.21.3/scripts/zm
@@ -0,0 +1,61 @@
+#!/bin/sh
+# description: Control ZoneMinder as a Service
+# chkconfig: 2345 99 99
+
+# Source function library.
+. /etc/rc.d/init.d/functions
+
+prog=ZoneMinder
+ZM_PATH_BIN="/usr/bin"
+command="$ZM_PATH_BIN/zmpkg.pl"
+
+start() {
+	echo -n "Starting $prog: "
+	$command start
+	RETVAL=$?
+	[ $RETVAL = 0 ] && echo_success
+	[ $RETVAL != 0 ] && echo_failure
+	echo
+	[ $RETVAL = 0 ] && touch /var/lock/subsys/zm
+	return $RETVAL
+}
+stop() {
+	echo -n $"Stopping $prog: "
+	$command stop
+	RETVAL=$?
+	[ $RETVAL = 0 ] && echo_success
+	[ $RETVAL != 0 ] && echo_failure
+	echo
+	[ $RETVAL = 0 ] && rm -f /var/lock/subsys/zm
+}
+status() {
+	result=`$command status`
+	if [ "$result" = "running" ]; then
+		echo "ZoneMinder is running"
+		RETVAL=0
+	else
+		echo "ZoneMinder is stopped"
+		RETVAL=1
+	fi
+}
+
+case "$1" in
+'start')
+	start
+	;;
+'stop')
+	stop
+	;;
+'restart')
+	stop
+	start
+	;;
+'status')
+	status
+	;;
+*)
+	echo "Usage: $0 { start | stop | restart | status }"
+	RETVAL=1
+	;;
+esac
+exit $RETVAL
--- zm-1.21.3.orig/scripts/zmx10.pl
+++ zm-1.21.3/scripts/zmx10.pl
@@ -0,0 +1,721 @@
+#!/usr/bin/perl -wT
+#
+# ==========================================================================
+#
+# ZoneMinder X10 Control Script, $Date: 2005/02/24 14:39:58 $, $Revision: 1.39 $
+# Copyright (C) 2003, 2004, 2005  Philip Coombes
+#
+# 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.
+#
+# ==========================================================================
+#
+# This script controls the monitoring of the X10 interface and the consequent
+# management of the ZM daemons based on the receipt of X10 signals.
+#
+use strict;
+use bytes;
+
+# ==========================================================================
+#
+# These are the elements you need to edit to suit your installation
+#
+# ==========================================================================
+
+use constant ZM_CONFIG => "/etc/zm/zm.conf";	# Path to the ZoneMinder config file, autogenerated do not change (from zmconfig)
+use constant ZM_PATH_BIN => "/usr/bin";	# Path to the ZoneMinder executables, autogenerated do not change (from zmconfig)
+
+# Load the config from the database into the symbol table
+BEGIN
+{
+	no strict 'refs';
+
+	open( CONFIG, "<".ZM_CONFIG ) or die( "Can't open config file: $!" );
+	foreach my $str ( <CONFIG> )
+	{
+		next if ( $str =~ /^\s*$/ );
+		next if ( $str =~ /^\s*#/ );
+		my ( $name, $value ) = $str =~ /^\s*([^=\\s]+)\s*=\s*(\S+)\s*$/;
+		$name =~ tr/a-z/A-Z/;
+		if (( $name eq 'ZM_DB_SERVER' ) ||
+			( $name eq 'ZM_DB_NAME' ) ||
+			( $name eq 'ZM_DB_USER' ) ||
+			( $name eq 'ZM_DB_PASS' ))
+		{
+			*{$name} = sub { $value };
+		}
+	}
+	close( CONFIG );
+
+	use DBI;
+	my $dbh = DBI->connect( "DBI:mysql:database=".&ZM_DB_NAME.";host=".&ZM_DB_SERVER, &ZM_DB_USER, &ZM_DB_PASS );
+	my $sql = "select * from Config";
+	my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
+	my $res = $sth->execute() or die( "Can't execute: ".$sth->errstr() );
+	while( my $config = $sth->fetchrow_hashref() )
+	{
+		*{$config->{Name}} = sub { $config->{Value} };
+	}
+	$sth->finish();
+	$dbh->disconnect();
+}
+
+use constant X10_SOCK_FILE => ZM_PATH_SOCKS.'/zmx10.sock';
+use constant X10_LOG_FILE => ZM_PATH_LOGS.'/zmx10.log';
+use constant VERBOSE => 0; # Whether to output more verbose debug
+
+# ==========================================================================
+#
+# Don't change anything below here
+#
+# ==========================================================================
+
+use POSIX;
+use Socket;
+use Getopt::Long;
+use Data::Dumper;
+
+$| = 1;
+
+$ENV{PATH}  = '/bin:/usr/bin';
+$ENV{SHELL} = '/bin/sh' if exists $ENV{SHELL};
+delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};
+
+sub Usage
+{
+    print( "
+Usage: zmx10.pl -c <command>,--command=<command> [-u <unit code>,--unit-code=<unit code>]
+Parameters are :-
+-c <command>, --command=<command>       - Command to issue, one of 'on','off','dim','bright','status','shutdown'
+-u <unit code>, --unit-code=<unit code> - Unit code to act on required for all commands except 'status' (optional) and 'shutdown'
+");
+	exit( -1 );
+}
+
+my $command;
+my $unit_code;
+
+if ( !GetOptions( 'command=s'=>\$command, 'unit-code=i'=>\$unit_code ) )
+{
+    Usage();
+}
+
+die( "No command given" ) unless( $command );
+die( "No unit code given" ) unless( $unit_code || ($command =~ /(?:start|status|shutdown)/) );
+
+if ( $command eq "start" )
+{
+	X10Server::runServer();
+	exit();
+}
+
+socket( CLIENT, PF_UNIX, SOCK_STREAM, 0 ) or die( "Can't open socket: $!" );
+
+my $saddr = sockaddr_un( X10_SOCK_FILE );
+
+if ( !connect( CLIENT, $saddr ) )
+{
+	# The server isn't there 
+	print( "Unable to connect, starting server\n" );
+	close( CLIENT );
+
+	if ( my $cpid = fork() )
+	{
+		# Parent process just sleep and fall through
+		sleep( 2 );
+		socket( CLIENT, PF_UNIX, SOCK_STREAM, 0 ) or die( "Can't open socket: $!" );
+		connect( CLIENT, $saddr ) or die( "Can't connect: $!" );
+	}
+	elsif ( defined($cpid) )
+	{
+		setpgrp();
+
+		X10Server::runServer();
+	}
+	else
+	{
+		die( "Can't fork: $!" );
+	}
+}
+# The server is there, connect to it
+#print( "Writing commands\n" );
+CLIENT->autoflush();
+my $message = "$command";
+$message .= ";$unit_code" if ( $unit_code );
+print( CLIENT $message );
+shutdown( CLIENT, 1 );
+while ( my $line = <CLIENT> )
+{
+	chomp( $line );
+	print( "$line\n" );
+}
+close( CLIENT );
+#print( "Finished writing, bye\n" );
+exit;
+
+#
+# ==========================================================================
+#
+# This is the X10 Server package
+#
+# ==========================================================================
+#
+package X10Server;
+
+use strict;
+use bytes;
+
+use POSIX;
+use DBI;
+use Socket;
+use X10::ActiveHome;
+use Data::Dumper;
+
+our $dbh;
+our $x10;
+
+our %monitor_hash;
+our %device_hash;
+our %pending_tasks;
+
+sub runServer
+{
+	my $log_file = main::X10_LOG_FILE;
+	open( LOG, ">>$log_file" ) or die( "Can't open log file: $!" );
+	open( STDOUT, ">&LOG" ) || die( "Can't dup stdout: $!" );
+	select( STDOUT ); $| = 1;
+	open( STDERR, ">&LOG" ) || die( "Can't dup stderr: $!" );
+	select( STDERR ); $| = 1;
+	select( LOG ); $| = 1;
+
+	print( "X10 server starting at ".strftime( '%y/%m/%d %H:%M:%S', localtime() )."\n" );
+
+	socket( SERVER, PF_UNIX, SOCK_STREAM, 0 ) or die( "Can't open socket: $!" );
+	unlink( main::X10_SOCK_FILE );
+	my $saddr = sockaddr_un( main::X10_SOCK_FILE );
+	bind( SERVER, $saddr ) or die( "Can't bind: $!" );
+	listen( SERVER, SOMAXCONN ) or die( "Can't listen: $!" );
+
+	$dbh = DBI->connect( "DBI:mysql:database=".main::ZM_DB_NAME.";host=".main::ZM_DB_SERVER, main::ZM_DB_USER, main::ZM_DB_PASS );
+
+	$x10 = new X10::ActiveHome( port=>main::ZM_X10_DEVICE, house_code=>main::ZM_X10_HOUSE_CODE, debug=>1 );
+
+	loadTasks();
+
+	$x10->register_listener( \&x10listen );
+
+	my $rin = '';
+	vec( $rin, fileno(SERVER),1) = 1;
+	vec( $rin, $x10->select_fds(),1) = 1;
+	my $timeout = 0.2;
+	#print( "F:".fileno(SERVER)."\n" );
+	my $reload = undef;
+	my $reload_count = 0;
+	my $reload_limit = (main::ZM_X10_DB_RELOAD_INTERVAL)/$timeout;
+	while( 1 )
+	{
+		my $nfound = select( my $rout = $rin, undef, undef, $timeout );
+		#print( "Off select, NF:$nfound, ER:$!\n" );
+		#print( vec( $rout, fileno(SERVER),1)."\n" );
+		#print( vec( $rout, $x10->select_fds(),1)."\n" );
+		if ( $nfound > 0 )
+		{
+			if ( vec( $rout, fileno(SERVER),1) )
+			{
+				my $paddr = accept( CLIENT, SERVER );
+				my $message = <CLIENT>;
+
+				my ( $command, $unit_code ) = split( ';', $message );
+
+				my $device;
+				if ( defined($unit_code) )
+				{
+					if ( $unit_code < 1 || $unit_code > 16 )
+					{
+						dprint( "Error, invalid unit code '$unit_code'\n" );
+						next;
+					}
+
+					$device = $device_hash{$unit_code};
+					if ( !$device )
+					{
+						$device = $device_hash{$unit_code} = { appliance=>$x10->Appliance( unit_code=>$unit_code ), status=>'unknown' };
+					}
+				}
+
+				my $result;
+				if ( $command eq 'on' )
+				{
+					$result = $device->{appliance}->on();
+				}
+				elsif ( $command eq 'off' )
+				{
+					$result = $device->{appliance}->off();
+				}
+				#elsif ( $command eq 'dim' )
+				#{
+					#$result = $device->{appliance}->dim();
+				#}
+				#elsif ( $command eq 'bright' )
+				#{
+					#$result = $device->{appliance}->bright();
+				#}
+				elsif ( $command eq 'status' )
+				{
+					if ( $device )
+					{
+						dprint( $unit_code." ".$device->{status}."\n" );
+					}
+					else
+					{
+						foreach my $unit_code ( sort( keys(%device_hash) ) )
+						{
+							my $device = $device_hash{$unit_code};
+							dprint( $unit_code." ".$device->{status}."\n" );
+						}
+					}
+				}
+				elsif ( $command eq 'shutdown' )
+				{
+					last;
+				}
+				else
+				{
+					dprint( "Error, invalid command '$command'\n" );
+				}
+				if ( defined($result) )
+				{
+					if ( 1 || $result )
+					{
+						$device->{status} = uc($command);
+						dprint( $device->{appliance}->address()." $command, ok\n" );
+						#x10listen( new X10::Event( sprintf("%s %s", $device->{appliance}->address, uc($command) ) ) );
+					}
+					else
+					{
+						dprint( $device->{appliance}->address()." $command, failed\n" );
+					}
+				}
+				close( CLIENT );
+			}
+			elsif ( vec( $rout, $x10->select_fds(),1) )
+			{
+				$x10->handle_input();
+			}
+			else
+			{
+				die( "Bogus descriptor" );
+			}
+		}
+		elsif ( $nfound < 0 )
+		{
+			die( "Can't select: $!" );
+		}
+		else
+		{
+			#print( "Select timed out\n" );
+			# Check for state changes
+			foreach my $monitor_id ( sort(keys(%monitor_hash) ) )
+			{
+				my $monitor = $monitor_hash{$monitor_id};
+				my $state;
+				if ( !shmread( $monitor->{ShmId}, $state, 8, 4 ) )
+				{
+					print( "Can't read from shared memory: $!\n" );
+					$reload = !undef;
+					next;
+				}
+				$state = unpack( "l", $state );
+				if ( defined( $monitor->{LastState} ) )
+				{
+					my $task_list;
+					if ( $state == 2 && $monitor->{LastState} == 0 ) # Gone into alarm state
+					{
+						print( "Applying ON_list for $monitor_id\n" ) if ( main::VERBOSE );
+						$task_list = $monitor->{"ON_list"};
+					}
+					elsif ( $state == 0 && $monitor->{LastState} > 0 ) # Come out of alarm state
+					{
+						print( "Applying OFF_list for $monitor_id\n" ) if ( main::VERBOSE );
+						$task_list = $monitor->{"OFF_list"};
+					}
+					if ( $task_list )
+					{
+						foreach my $task ( @$task_list )
+						{
+							processTask( $task );
+						}
+					}
+				}
+				$monitor->{LastState} = $state;
+			}
+
+			# Check for pending tasks
+			my $now = time();
+			foreach my $activation_time ( sort(keys(%pending_tasks) ) )
+			{
+				last if ( $activation_time > $now );
+				my $pending_list = $pending_tasks{$activation_time};
+				foreach my $task ( @$pending_list )
+				{
+					processTask( $task );
+				}
+				delete( $pending_tasks{$activation_time} );
+			}
+			if ( $reload || ++$reload_count >= $reload_limit )
+			{
+				loadTasks();
+				$reload = undef;
+				$reload_count = 0;
+			}
+		}
+	}
+	print( "X10 server exiting at ".strftime( '%y/%m/%d %H:%M:%S', localtime() )."\n" );
+	close( LOG );
+	close( SERVER );
+	exit();
+}
+
+sub addToDeviceList
+{
+	my $unit_code = shift;
+	my $event = shift;
+	my $monitor = shift;
+	my $function = shift;
+	my $limit = shift;
+
+	print( "Adding to device list, uc:$unit_code, ev:$event, mo:$monitor, fu:$function, li:$limit\n" ) if ( main::VERBOSE );
+	my $device = $device_hash{$unit_code};
+	if ( !$device )
+	{
+		$device = $device_hash{$unit_code} = { appliance=>$x10->Appliance( unit_code=>$unit_code ), status=>'unknown' };
+	}
+
+	my $task = { type=>"device", monitor=>$monitor, function=>$function };
+	if ( $limit )
+	{
+		$task->{limit} = $limit
+	}
+
+	my $task_list = $device->{$event."_list"};
+	if ( !$task_list )
+	{
+		$task_list = $device->{$event."_list"} = [];
+	}
+	push( @$task_list, $task );
+}
+
+sub addToMonitorList
+{
+	my $monitor = shift;
+	my $event = shift;
+	my $unit_code = shift;
+	my $function = shift;
+	my $limit = shift;
+
+	print( "Adding to monitor list, uc:$unit_code, ev:$event, mo:$monitor, fu:$function, li:$limit\n" ) if ( main::VERBOSE );
+	my $device = $device_hash{$unit_code};
+	if ( !$device )
+	{
+		$device = $device_hash{$unit_code} = { appliance=>$x10->Appliance( unit_code=>$unit_code ), status=>'unknown' };
+	}
+
+	my $task = { type=>"monitor", device=>$device, function=>$function };
+	if ( $limit )
+	{
+		$task->{limit} = $limit;
+	}
+
+	my $task_list = $monitor->{$event."_list"};
+	if ( !$task_list )
+	{
+		$task_list = $monitor->{$event."_list"} = [];
+	}
+	push( @$task_list, $task );
+}
+
+sub loadTasks
+{
+	%monitor_hash = ();
+
+	print( "Loading tasks\n" ) if ( main::VERBOSE );
+	# Clear out all old device task lists
+	foreach my $unit_code ( sort( keys(%device_hash) ) )
+	{
+		my $device = $device_hash{$unit_code};
+		$device->{ON_list} = [];
+		$device->{OFF_list} = [];
+	}
+
+	my $sql = "select M.*,T.* from Monitors as M inner join TriggersX10 as T on (M.Id = T.MonitorId) where find_in_set( M.Function, 'Modect,Record,Mocord' ) and M.RunMode = 'Triggered' and find_in_set( 'X10', M.Triggers )";
+	my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
+	my $res = $sth->execute() or die( "Can't execute: ".$sth->errstr() );
+	while( my $monitor = $sth->fetchrow_hashref() )
+	{
+		my $size = 512; # We only need the first 512 bytes really for the alarm state and forced alarm
+		$monitor->{ShmKey} = hex(main::ZM_SHM_KEY)|$monitor->{Id};
+		$monitor->{ShmId} = shmget( $monitor->{ShmKey}, $size, 0 );
+		if ( !defined($monitor->{ShmId}) )
+		{
+			print( "Can't get shared memory id '$monitor->{ShmKey}': $!\n" );
+			next;
+		}
+
+		$monitor_hash{$monitor->{Id}} = $monitor;
+
+		if ( $monitor->{Activation} )
+		{
+			print( "$monitor->{Name} has active string '$monitor->{Activation}'\n" ) if ( main::VERBOSE );
+			foreach my $code_string ( split( ',', $monitor->{Activation} ) )
+			{
+				#print( "Code string: $code_string\n" );
+				my ( $invert, $unit_code, $modifier, $limit ) = ( $code_string =~ /^([!~])?(\d+)(?:([+-])(\d+)?)?$/ );
+				$limit = 0 if ( !$limit );
+				if ( $unit_code )
+				{
+					if ( !$modifier || $modifier eq '+' )
+					{
+						addToDeviceList( $unit_code, "ON", $monitor, !$invert?"start_active":"stop_active", $limit );
+					}
+					if ( !$modifier || $modifier eq '-' )
+					{
+						addToDeviceList( $unit_code, "OFF", $monitor, !$invert?"stop_active":"start_active", $limit );
+					}
+				}
+			}
+		}
+		if ( $monitor->{AlarmInput} )
+		{
+			print( "$monitor->{Name} has alarm input string '$monitor->{AlarmInput}'\n" ) if ( main::VERBOSE );
+			foreach my $code_string ( split( ',', $monitor->{AlarmInput} ) )
+			{
+				#print( "Code string: $code_string\n" );
+				my ( $invert, $unit_code, $modifier, $limit ) = ( $code_string =~ /^([!~])?(\d+)(?:([+-])(\d+)?)?$/ );
+				$limit = 0 if ( !$limit );
+				if ( $unit_code )
+				{
+					if ( !$modifier || $modifier eq '+' )
+					{
+						addToDeviceList( $unit_code, "ON", $monitor, !$invert?"start_alarm":"stop_alarm", $limit );
+					}
+					if ( !$modifier || $modifier eq '-' )
+					{
+						addToDeviceList( $unit_code, "OFF", $monitor, !$invert?"stop_alarm":"start_alarm", $limit );
+					}
+				}
+			}
+		}
+		if ( $monitor->{AlarmOutput} )
+		{
+			print( "$monitor->{Name} has alarm output string '$monitor->{AlarmOutput}'\n" ) if ( main::VERBOSE );
+			foreach my $code_string ( split( ',', $monitor->{AlarmOutput} ) )
+			{
+				#print( "Code string: $code_string\n" );
+				my ( $invert, $unit_code, $modifier, $limit ) = ( $code_string =~ /^([!~])?(\d+)(?:([+-])(\d+)?)?$/ );
+				$limit = 0 if ( !$limit );
+				if ( $unit_code )
+				{
+					if ( !$modifier || $modifier eq '+' )
+					{
+						addToMonitorList( $monitor, "ON", $unit_code, !$invert?"on":"off", $limit );
+					}
+					if ( !$modifier || $modifier eq '-' )
+					{
+						addToMonitorList( $monitor, "OFF", $unit_code, !$invert?"off":"on", $limit );
+					}
+				}
+			}
+		}
+	}
+}
+
+sub addPendingTask
+{
+	my $task = shift;
+
+	# Check whether we are just extending a previous pending task
+	# and remove it if it's there
+	foreach my $activation_time ( sort(keys(%pending_tasks) ) )
+	{
+		my $pending_list = $pending_tasks{$activation_time};
+		my $new_pending_list = [];
+		foreach my $pending_task ( @$pending_list )
+		{
+			if ( $task->{type} ne $pending_task->{type} )
+			{
+				push( @$new_pending_list, $pending_task )
+			}
+			elsif ( $task->{type} eq "device" )
+			{
+				if (( $task->{monitor}->{Id} != $pending_task->{monitor}->{Id} )
+				|| ( $task->{function} ne $pending_task->{function} ))
+				{
+					push( @$new_pending_list, $pending_task )
+				}
+			}
+			elsif ( $task->{type} eq "monitor" )
+			{
+				if (( $task->{device}->{appliance}->unit_code() != $pending_task->{device}->{appliance}->unit_code() )
+				|| ( $task->{function} ne $pending_task->{function} ))
+				{
+					push( @$new_pending_list, $pending_task )
+				}
+			}
+		}
+		if ( @$new_pending_list )
+		{
+			$pending_tasks{$activation_time} = $new_pending_list;
+		}
+		else
+		{
+			delete( $pending_tasks{$activation_time} );
+		}
+	}
+
+	my $end_time = time() + $task->{limit};
+	my $pending_list = $pending_tasks{$end_time};
+	if ( !$pending_list )
+	{
+		$pending_list = $pending_tasks{$end_time} = [];
+	}
+	my $pending_task;
+	if ( $task->{type} eq "device" )
+	{
+		$pending_task = { type=>$task->{type}, monitor=>$task->{monitor}, function=>$task->{function} };
+		$pending_task->{function} =~ s/start/stop/;
+	}
+	elsif ( $task->{type} eq "monitor" )
+	{
+		$pending_task = { type=>$task->{type}, device=>$task->{device}, function=>$task->{function} };
+		$pending_task->{function} =~ s/on/off/;
+	}
+	push( @$pending_list, $pending_task );
+}
+
+sub processTask
+{
+	my $task = shift;
+
+	if ( $task->{type} eq "device" )
+	{
+		my ( $instruction, $class ) = ( $task->{function} =~ /^(.+)_(.+)$/ );
+
+		my @commands;
+		if ( $class eq "active" )
+		{
+			if ( $instruction eq "start" )
+			{
+				push( @commands, main::ZM_PATH_BIN."/zmdc.pl start zma -m ".$task->{monitor}->{Id} );
+				push( @commands, main::ZM_PATH_BIN."/zmdc.pl start zmf -m ".$task->{monitor}->{Id} );
+				if ( main::ZM_OPT_FRAME_SERVER )
+				{
+				}
+				if ( $task->{limit} )
+				{
+					addPendingTask( $task );
+				}
+			}
+			elsif( $instruction eq "stop" )
+			{
+				$command = main::ZM_PATH_BIN."/zmdc.pl stop zma -m ".$task->{monitor}->{Id};
+				push( @commands, main::ZM_PATH_BIN."/zmdc.pl stop zma -m ".$task->{monitor}->{Id} );
+				push( @commands, main::ZM_PATH_BIN."/zmdc.pl stop zmf -m ".$task->{monitor}->{Id} );
+			}
+		}
+		elsif( $class eq "alarm" )
+		{
+			if ( $instruction eq "start" )
+			{
+				#$command = main::ZM_PATH_BIN."/zmu --monitor ".$task->{monitor}->{Id}." --alarm";
+				my $force_data = pack( "llZ*", 1, 0, "X10" );
+				if ( !shmwrite( $task->{monitor}->{ShmId}, $force_data, 52, 12 ) )
+				{
+					print( "Can't write to shared memory: $!\n" );
+				}
+				if ( $task->{limit} )
+				{
+					addPendingTask( $task );
+				}
+			}
+			elsif( $instruction eq "stop" )
+			{
+				#$command = main::ZM_PATH_BIN."/zmu --monitor ".$task->{monitor}->{Id}." --cancel";
+				my $force_data = pack( "llZ*", 0, 0, "" );
+				if ( !shmwrite( $task->{monitor}->{ShmId}, $force_data, 52, 12 ) )
+				{
+					print( "Can't write to shared memory: $!\n" );
+				}
+			}
+		}
+		foreach my $command ( @commands )
+		{
+			print( "Executing command '$command'\n" );
+			qx( $command );
+		}
+	}
+	elsif( $task->{type} eq "monitor" )
+	{
+		if ( $task->{function} eq "on" )
+		{
+			$task->{device}->{appliance}->on();
+			if ( $task->{limit} )
+			{
+				addPendingTask( $task );
+			}
+		}
+		elsif ( $task->{function} eq "off" )
+		{
+			$task->{device}->{appliance}->off();
+		}
+	}
+}
+
+sub dprint
+{
+	if ( fileno(CLIENT) )
+	{
+		print CLIENT @_
+	}
+	print @_;
+}
+
+sub x10listen
+{
+	foreach my $event ( @_ )
+	{
+		#print( Data::Dumper( $_ )."\n" );
+		if ( $event->house_code() eq main::ZM_X10_HOUSE_CODE )
+		{
+			my $unit_code = $event->unit_code();
+			my $device = $device_hash{$unit_code};
+			if ( !$device )
+			{
+				$device = $device_hash{$unit_code} = { appliance=>$x10->Appliance( unit_code=>$unit_code ), status=>'unknown' };
+			}
+			next if ( $event->func() !~ /(?:ON|OFF)/ );
+			$device->{status} = $event->func();
+			my $task_list = $device->{$event->func()."_list"};
+			if ( $task_list )
+			{
+				foreach my $task ( @$task_list )
+				{
+					processTask( $task );
+				}
+			}
+		}
+		print( strftime( "%y/%m/%d %H:%M:%S", localtime() )." - ".$event->as_string()."\n" );
+	}
+}
+
+1;
--- zm-1.21.3.orig/scripts/zmaudit.pl
+++ zm-1.21.3/scripts/zmaudit.pl
@@ -0,0 +1,443 @@
+#!/usr/bin/perl -wT
+#
+# ==========================================================================
+#
+# ZoneMinder Audit Script, $Date: 2005/07/12 13:44:15 $, $Revision: 1.43 $
+# Copyright (C) 2003, 2004, 2005  Philip Coombes
+#
+# 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.
+#
+# ==========================================================================
+#
+# This script checks for consistency between the event filesystem and
+# the database. If events are found in one and not the other they are
+# deleted (optionally). Additionally any monitor event directories that
+# do not correspond to a database monitor are similarly disposed of.
+# However monitors in the database that don't have a directory are left
+# alone as this is valid if they are newly created and have no events
+# yet.
+#
+use strict;
+use bytes;
+
+# ==========================================================================
+#
+# These are the elements you need to edit to suit your installation
+#
+# ==========================================================================
+use constant ZM_CONFIG => "/etc/zm/zm.conf";	# Path to the ZoneMinder config file, autogenerated do not change (from zmconfig)
+use constant ZM_PATH_BIN => "/usr/bin";	# Path to the ZoneMinder executables, autogenerated do not change (from zmconfig)
+use constant ZM_PATH_WEB => "/var/www/zm";	# Path to the ZoneMinder web files, autogenerated do not change (from zmconfig)
+
+# Load the config from the database into the symbol table
+BEGIN
+{
+	no strict 'refs';
+
+	open( CONFIG, "<".ZM_CONFIG ) or die( "Can't open config file: $!" );
+	foreach my $str ( <CONFIG> )
+	{
+		next if ( $str =~ /^\s*$/ );
+		next if ( $str =~ /^\s*#/ );
+		my ( $name, $value ) = $str =~ /^\s*([^=\\s]+)\s*=\s*(\S+)\s*$/;
+		$name =~ tr/a-z/A-Z/;
+		if (( $name eq 'ZM_DB_SERVER' ) ||
+			( $name eq 'ZM_DB_NAME' ) ||
+			( $name eq 'ZM_DB_USER' ) ||
+			( $name eq 'ZM_DB_PASS' ))
+		{
+			*{$name} = sub { $value };
+		}
+	}
+	close( CONFIG );
+
+	use DBI;
+	my $dbh = DBI->connect( "DBI:mysql:database=".&ZM_DB_NAME.";host=".&ZM_DB_SERVER, &ZM_DB_USER, &ZM_DB_PASS );
+	my $sql = "select * from Config";
+	my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
+	my $res = $sth->execute() or die( "Can't execute: ".$sth->errstr() );
+	while( my $config = $sth->fetchrow_hashref() )
+	{
+		*{$config->{Name}} = sub { $config->{Value} };
+	}
+	$sth->finish();
+	$dbh->disconnect();
+}
+
+use constant IMAGE_PATH => ZM_PATH_WEB.'/'.ZM_DIR_IMAGES;
+use constant EVENT_PATH => ZM_PATH_WEB.'/'.ZM_DIR_EVENTS;
+use constant LOG_FILE => ZM_PATH_LOGS.'/zmaudit.log';
+use constant MIN_AGE => 300; # Minimum age when we will delete anything
+
+use constant DBG_LEVEL => 1; # 0 is errors, warnings and info only, > 0 for debug
+
+# ==========================================================================
+#
+# You shouldn't need to change anything from here downwards
+#
+# ==========================================================================
+
+use DBI;
+use POSIX;
+use Time::HiRes qw/gettimeofday/;
+use Getopt::Long;
+
+$| = 1;
+
+$ENV{PATH}  = '/bin:/usr/bin';
+$ENV{SHELL} = '/bin/sh' if exists $ENV{SHELL};
+delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};
+
+my $report = 0;
+my $yes = 0;
+my $delay = 0;
+
+sub usage
+{
+	print( "
+Usage: zmaudit.pl [-r,-report|-y,-yes] [-d <seconds>,-delay=<seconds>]
+Parameters are :-
+-r, --report                    - Just report don't actually do anything
+-y, --yes                       - Just do all actions without confirmation
+-d <seconds>, --delay=<seconds> - how long to delay between each pass, the default of 0 means run once only.
+");
+	exit( -1 );
+}
+
+my $dbg_id = "";
+
+sub dbgInit
+{
+	my $id = shift;
+	if ( $id )
+	{
+		$dbg_id = $id;
+		my $add_parms = shift;
+		if ( $add_parms )
+		{
+			foreach my $arg ( @ARGV )
+			{
+				if ( $arg =~ /^-(.*)$/ )
+				{
+					$dbg_id .= "_$1";
+				}
+				else
+				{
+					$dbg_id .= $arg;
+				}
+			}
+		}
+	}
+}
+
+sub dbgPrint
+{
+	my $code = shift;
+	my $string = shift;
+	my $line = shift;
+
+	$string =~ s/[\r\n]+$//g;
+
+	my ($seconds, $microseconds) = gettimeofday();
+	if ( $line )
+	{
+		my $file = __FILE__;
+		$file =~ s|^.*/||g;
+		printf( "%s.%06d %s[%d].%s-%s/%d [%s]\n", strftime( "%x %H:%M:%S", localtime( $seconds ) ), $microseconds, $dbg_id, $$, $file, $line, $code, $string );
+	}
+	else
+	{
+		printf( "%s.%06d %s[%d].%s [%s]\n", strftime( "%x %H:%M:%S", localtime( $seconds ) ), $microseconds, $dbg_id, $$, $code, $string );
+	}
+}
+
+sub Debug
+{
+	dbgPrint( "DBG", $_[0] ) if ( DBG_LEVEL >= 1 );
+}
+
+sub Info
+{
+	dbgPrint( "INF", $_[0] ) if ( DBG_LEVEL >= 0 );
+}
+
+sub Warning
+{
+	dbgPrint( "WAR", $_[0] ) if ( DBG_LEVEL >= -1 );
+}
+
+sub Error
+{
+	dbgPrint( "ERR", $_[0] ) if ( DBG_LEVEL >= -2 );
+}
+
+sub aud_print
+{
+	my $string = shift;
+	if ( $delay )
+	{
+		Info( $string );
+	}
+	else
+	{
+		print( $string );
+	}
+}
+
+sub confirm
+{
+	my $prompt = shift || "delete";
+	my $action = shift || "deleting";
+
+	my $yesno = $yes?1:0; 
+	if ( $report )
+	{
+		if ( !$delay )
+		{
+			print( "\n" );
+		}
+	}
+	elsif ( $yes )
+	{
+		if ( $delay )
+		{
+			Info( "$action\n" );
+		}
+		else
+		{
+			print( ", $action\n" );
+		}
+	}
+	else
+	{
+		print( ", $prompt y/n: " );
+		my $char = <>;
+		chomp( $char );
+		if ( $char eq 'q' )
+		{
+			exit( 0 );
+		}
+		if ( !$char )
+		{
+			$char = 'y';
+		}
+		if ( $char eq "a" )
+		{
+			$yes = 1;
+			return( 1 );
+		}
+		$yesno = ( $char =~ /[yY]/ );
+	}
+	return( $yesno );
+}
+
+dbgInit( "zmaudit", 1 );
+
+if ( !GetOptions( 'report'=>\$report, 'yes'=>\$yes, 'delay=i'=>\$delay ) )
+{
+	usage();
+}
+
+if ( $report && $yes )
+{
+	print( STDERR "Error, only one of --report and --yes may be specified\n" );
+	usage();
+}
+
+my $dbh = DBI->connect( "DBI:mysql:database=".ZM_DB_NAME.";host=".ZM_DB_SERVER, ZM_DB_USER, ZM_DB_PASS );
+
+chdir( EVENT_PATH );
+if ( $delay ) # Background mode
+{
+	open( LOG, ">>".LOG_FILE ) or die( "Can't open log file: $!" );
+	open( STDOUT, ">&LOG" ) || die( "Can't dup stdout: $!" );
+	select( STDOUT ); $| = 1;
+	open( STDERR, ">&LOG" ) || die( "Can't dup stderr: $!" );
+	select( STDERR ); $| = 1;
+	select( LOG ); $| = 1;
+}
+my $max_image_age = 15/(24*60); # 15 Minutes
+my $image_path = IMAGE_PATH;
+do
+{
+	my $db_monitors;
+	my $sql1 = "select Id from Monitors order by Id";
+	my $sth1 = $dbh->prepare_cached( $sql1 ) or die( "Can't prepare '$sql1': ".$dbh->errstr() );
+	my $sql2 = "select Id, (unix_timestamp() - unix_timestamp(StartTime)) as Age from Events where MonitorId = ? order by Id";
+	my $sth2 = $dbh->prepare_cached( $sql2 ) or die( "Can't prepare '$sql2': ".$dbh->errstr() );
+	my $res = $sth1->execute() or die( "Can't execute: ".$sth1->errstr() );
+	while( my $monitor = $sth1->fetchrow_hashref() )
+	{
+		Debug( "Found database monitor '$monitor->{Id}'" );
+		my $db_events = $db_monitors->{$monitor->{Id}} = {};
+		my $res = $sth2->execute( $monitor->{Id} ) or die( "Can't execute: ".$sth2->errstr() );
+		while ( my $event = $sth2->fetchrow_hashref() )
+		{
+			$db_events->{$event->{Id}} = $event->{Age};
+		}
+		Debug( "Got ".int(keys(%$db_events))." events\n" );
+		$sth2->finish();
+	}
+	$sth1->finish();
+
+	my $fs_now = time();
+	my $fs_monitors;
+	foreach my $monitor ( <[0-9]*> )
+	{
+		Debug( "Found filesystem monitor '$monitor'" );
+		my $fs_events = $fs_monitors->{$monitor} = {};
+		( my $monitor_dir ) = ( $monitor =~ /^(.*)$/ ); # De-taint
+
+		opendir( DIR, $monitor_dir ) or die( "Can't open directory '$monitor_dir': $!" );
+		my @temp_events = sort { $b <=> $a } grep { $_ =~ /^\d+$/ } readdir( DIR );
+		closedir( DIR );
+		chdir( $monitor_dir );
+		my $count = 0;
+		foreach my $event ( @temp_events )
+		{
+			if ( $count++ > 25 )
+			{
+				$fs_events->{$event} = -1;
+			}
+			else
+			{
+				$fs_events->{$event} = ($fs_now - ($^T - ((-M $event) * 24*60*60)));
+			}
+		}
+		chdir( EVENT_PATH );
+		Debug( "Got ".int(keys(%$fs_events))." events\n" );
+	}
+
+	while ( my ( $fs_monitor, $fs_events ) = each(%$fs_monitors) )
+	{
+		if ( my $db_events = $db_monitors->{$fs_monitor} )
+		{
+			if ( $fs_events )
+			{
+				while ( my ( $fs_event, $age ) = each(%$fs_events ) )
+				{
+					if ( !defined($db_events->{$fs_event}) && ($age < 0 || ($age > MIN_AGE)) )
+					{
+						aud_print( "Filesystem event '$fs_monitor/$fs_event' does not exist in database" );
+						if ( confirm() )
+						{
+							my $command = "/bin/rm -rf ".EVENT_PATH."/$fs_monitor/$fs_event";
+							qx( $command );
+						}
+					}
+				}
+			}
+		}
+		else
+		{
+			aud_print( "Filesystem monitor '$fs_monitor' does not exist in database" );
+			if ( confirm() )
+			{
+				my $command = "rm -rf ".EVENT_PATH."/$fs_monitor";
+				qx( $command );
+			}
+		}
+	}
+
+	my $sql3 = "delete from Monitors where Id = ?";
+	my $sth3 = $dbh->prepare_cached( $sql3 ) or die( "Can't prepare '$sql3': ".$dbh->errstr() );
+	my $sql4 = "delete from Events where Id = ?";
+	my $sth4 = $dbh->prepare_cached( $sql4 ) or die( "Can't prepare '$sql4': ".$dbh->errstr() );
+	my $sql5 = "delete from Frames where EventId = ?";
+	my $sth5 = $dbh->prepare_cached( $sql5 ) or die( "Can't prepare '$sql5': ".$dbh->errstr() );
+	my $sql6 = "delete from Stats where EventId = ?";
+	my $sth6 = $dbh->prepare_cached( $sql6 ) or die( "Can't prepare '$sql6': ".$dbh->errstr() );
+	while ( my ( $db_monitor, $db_events ) = each(%$db_monitors) )
+	{
+		if ( my $fs_events = $fs_monitors->{$db_monitor} )
+		{
+			if ( $db_events )
+			{
+				while ( my ( $db_event, $age ) = each(%$db_events ) )
+				{
+					if ( !defined($fs_events->{$db_event}) && ($age > MIN_AGE) )
+					{
+						aud_print( "Database event '$db_monitor/$db_event' does not exist in filesystem" );
+						if ( confirm() )
+						{
+							my $res = $sth4->execute( $db_event ) or die( "Can't execute: ".$sth4->errstr() );
+							$res = $sth5->execute( $db_event ) or die( "Can't execute: ".$sth5->errstr() );
+							$res = $sth6->execute( $db_event ) or die( "Can't execute: ".$sth6->errstr() );
+						}
+					}
+				}
+			}
+		}
+		else
+		{
+			#aud_print( "Database monitor '$db_monitor' does not exist in filesystem" );
+			#if ( confirm() )
+			#{
+				# We don't actually do this in case it's new
+				#my $res = $sth3->execute( $db_monitor ) or die( "Can't execute: ".$sth3->errstr() );
+			#}
+		}
+	}
+
+	my $sql7 = "select distinct EventId from Frames left join Events on Frames.EventId = Events.Id where isnull(Events.Id) group by EventId";
+	my $sth7 = $dbh->prepare_cached( $sql7 ) or die( "Can't prepare '$sql7': ".$dbh->errstr() );
+	$res = $sth7->execute() or die( "Can't execute: ".$sth7->errstr() );
+	while( my $frame = $sth7->fetchrow_hashref() )
+	{
+		aud_print( "Found orphaned frame records for event '$frame->{EventId}'" );
+		if ( confirm() )
+		{
+			$res = $sth5->execute( $frame->{EventId} ) or die( "Can't execute: ".$sth6->errstr() );
+		}
+	}
+
+	my $sql8 = "select distinct EventId from Stats left join Events on Stats.EventId = Events.Id where isnull(Events.Id) group by EventId";
+	my $sth8 = $dbh->prepare_cached( $sql8 ) or die( "Can't prepare '$sql8': ".$dbh->errstr() );
+	$res = $sth8->execute() or die( "Can't execute: ".$sth8->errstr() );
+	while( my $stat = $sth8->fetchrow_hashref() )
+	{
+		aud_print( "Found orphaned statistic records for event '$stat->{EventId}'" );
+		if ( confirm() )
+		{
+			$res = $sth6->execute( $stat->{EventId} ) or die( "Can't execute: ".$sth6->errstr() );
+		}
+	}
+
+	# New audit to close any events that were left open for longer than MIN_AGE seconds
+	my $sql9 = "select E.Id, max(F.TimeStamp) as EndTime, unix_timestamp(max(F.TimeStamp)) - unix_timestamp(E.StartTime) as Length, count(F.Id) as Frames, count(if(F.Score>0,1,NULL)) as AlarmFrames, sum(F.Score) as TotScore, max(F.Score) as MaxScore, M.EventPrefix as Prefix from Events as E left join Monitors as M on E.MonitorId = M.Id inner join Frames as F on E.Id = F.EventId where isnull(E.Frames) group by E.Id having EndTime < (now() - interval ".MIN_AGE." second)"; 
+	my $sth9 = $dbh->prepare_cached( $sql9 ) or die( "Can't prepare '$sql9': ".$dbh->errstr() );
+	my $sql10 = "update Events set Name = ?, EndTime = ?, Length = ?, Frames = ?, AlarmFrames = ?, TotScore = ?, AvgScore = ?, MaxScore = ? where Id = ?";
+	my $sth10 = $dbh->prepare_cached( $sql10 ) or die( "Can't prepare '$sql10': ".$dbh->errstr() );
+	$res = $sth9->execute() or die( "Can't execute: ".$sth9->errstr() );
+	while( my $event = $sth9->fetchrow_hashref() )
+	{
+		aud_print( "Found open event '$event->{Id}'" );
+		if ( confirm( 'close', 'closing' ) )
+		{
+			$res = $sth10->execute( sprintf( "%s-%d(r)", $event->{Prefix}, $event->{Id} ), $event->{EndTime}, $event->{Length}, $event->{Frames}, $event->{AlarmFrames}, $event->{TotScore}, $event->{AlarmFrames}?int($event->{TotScore}/$event->{AlarmFrames}):0, $event->{MaxScore}, $event->{Id} ) or die( "Can't execute: ".$sth10->errstr() );
+		}
+	}
+
+	# Now delete any old image files
+	if ( my @old_files = grep { -M > $max_image_age } <$image_path/*.{jpg,gif,wbmp}> )
+	{
+		aud_print( "Deleting ".int(@old_files)." old images\n" );
+		my $untainted_old_files = join( ";", @old_files );
+		( $untainted_old_files ) = ( $untainted_old_files =~ /^(.*)$/ );
+		unlink( split( ";", $untainted_old_files ) );
+	}
+
+	sleep( $delay ) if ( $delay );
+} while( $delay );
--- zm-1.21.3.orig/scripts/zmcontrol-pelco-d.pl
+++ zm-1.21.3/scripts/zmcontrol-pelco-d.pl
@@ -0,0 +1,699 @@
+#!/usr/bin/perl -wT
+#
+# ==========================================================================
+#
+# ZoneMinder Pelco-D Control Script, $Date: 2005/06/22 09:37:33 $, $Revision: 1.8 $
+# Copyright (C) 2003, 2004, 2005  Philip Coombes
+#
+# 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.
+#
+# ==========================================================================
+#
+# This script continuously monitors the recorded events for the given
+# monitor and applies any filters which would delete and/or upload 
+# matching events
+#
+use strict;
+
+# ==========================================================================
+#
+# These are the elements you need to edit to suit your installation
+#
+# ==========================================================================
+use constant ZM_CONFIG => "/etc/zm/zm.conf";	# Path to the ZoneMinder config file, autogenerated do not change (from zmconfig)
+use constant ZM_PATH_BIN => "/usr/bin";	# Path to the ZoneMinder executables, autogenerated do not change (from zmconfig)
+
+# Load the config from the database into the symbol table
+BEGIN
+{
+	no strict 'refs';
+
+	open( CONFIG, "<".ZM_CONFIG ) or die( "Can't open config file: $!" );
+	foreach my $str ( <CONFIG> )
+	{
+		next if ( $str =~ /^\s*$/ );
+		next if ( $str =~ /^\s*#/ );
+		my ( $name, $value ) = $str =~ /^\s*([^=\s]+)\s*=\s*([^=\s]+)\s*$/;
+		$name =~ tr/a-z/A-Z/;
+		if (( $name eq 'ZM_DB_SERVER' ) ||
+			( $name eq 'ZM_DB_NAME' ) ||
+			( $name eq 'ZM_DB_USER' ) ||
+			( $name eq 'ZM_DB_PASS' ))
+		{
+			*{$name} = sub { $value };
+		}
+	}
+	close( CONFIG );
+
+	use DBI;
+	my $dbh = DBI->connect( "DBI:mysql:database=".&ZM_DB_NAME.";host=".&ZM_DB_SERVER, &ZM_DB_USER, &ZM_DB_PASS );
+	my $sql = "select * from Config";
+	my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
+	my $res = $sth->execute() or die( "Can't execute '$sql': ".$sth->errstr() );
+	while( my $config = $sth->fetchrow_hashref() )
+	{
+		*{$config->{Name}} = sub { $config->{Value} };
+	}
+	$sth->finish();
+	$dbh->disconnect();
+}
+
+use Getopt::Long;
+use Device::SerialPort;
+use Time::HiRes qw( usleep );
+
+use constant LOG_FILE => ZM_PATH_LOGS.'/zmcontrol-pelco-d.log';
+
+$| = 1;
+
+$ENV{PATH}  = '/bin:/usr/bin';
+$ENV{SHELL} = '/bin/sh' if exists $ENV{SHELL};
+delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};
+
+sub Usage
+{
+	print( "
+Usage: zmcontrol-pelco-d.pl <various options>
+");
+	exit( -1 );
+}
+
+my $arg_string = join( " ", @ARGV );
+
+my $device = "/dev/ttyS0";
+my $address = 1;
+my $command;
+my $autostop;
+my ( $speed, $step );
+my ( $xcoord, $ycoord );
+my ( $panspeed, $tiltspeed );
+my ( $panstep, $tiltstep );
+my $preset;
+
+if ( !GetOptions(
+	'device=s'=>\$device,
+	'address=i'=>\$address,
+	'command=s'=>\$command,
+	'autostop=f'=>\$autostop,
+	'speed=i'=>\$speed,
+	'step=i'=>\$step,
+	'xcoord=i'=>\$xcoord,
+	'ycoord=i'=>\$ycoord,
+	'panspeed=i'=>\$panspeed,
+	'tiltspeed=i'=>\$tiltspeed,
+	'panstep=i'=>\$panstep,
+	'tiltstep=i'=>\$tiltstep,
+	'preset=i'=>\$preset
+	)
+)
+{
+	Usage();
+}
+
+if ( defined($autostop) )
+{
+	# Convert to microseconds.
+	$autostop = int(1000000*$autostop);
+}
+
+my $log_file = LOG_FILE;
+open( LOG, ">>$log_file" ) or die( "Can't open log file: $!" );
+open( STDOUT, ">&LOG" ) || die( "Can't dup stdout: $!" );
+select( STDOUT ); $| = 1;
+open( STDERR, ">&LOG" ) || die( "Can't dup stderr: $!" );
+select( STDERR ); $| = 1;
+select( LOG ); $| = 1;
+
+print( $arg_string."\n" );
+
+srand( time() );
+
+my $serial_port = new Device::SerialPort( $device );
+$serial_port->baudrate(2400);
+$serial_port->databits(8);
+$serial_port->parity('none');
+$serial_port->stopbits(1);
+$serial_port->handshake('none');
+ 
+$serial_port->read_const_time(50);
+$serial_port->read_char_time(10);
+
+sub printMsg
+{
+	my $msg = shift;
+	my $prefix = shift || "";
+	$prefix = $prefix.": " if ( $prefix );
+
+	my $line_length = 16;
+	my $msg_len = int(@$msg);
+
+	print( $prefix );
+	for ( my $i = 0; $i < $msg_len; $i++ )
+	{
+		if ( ($i > 0) && ($i%$line_length == 0) && ($i != ($msg_len-1)) )
+		{
+			printf( "\n%*s", length($prefix), "" );
+		}
+		printf( "%02x ", $msg->[$i] );
+	}
+	print( "[".$msg_len."]\n" );
+}
+
+sub sendCmd
+{
+	my $cmd = shift;
+	my $ack = shift || 0;
+
+	my $result = undef;
+
+	my $checksum = 0x00;
+	for ( my $i = 1; $i < int(@$cmd); $i++ )
+	{
+		$checksum += $cmd->[$i];
+		$checksum &= 0xff;
+	}
+	push( @$cmd, $checksum );
+
+	printMsg( $cmd, "Tx" );
+	my $id = $cmd->[0] & 0xf;
+
+	my $tx_msg = pack( "C*", @$cmd );
+
+	#print( "Tx: ".length( $tx_msg )." bytes\n" );
+	my $n_bytes = $serial_port->write( $tx_msg );
+	if ( !$n_bytes )
+	{
+		print( "Error, write failed: $!" );
+	}
+	if ( $n_bytes != length($tx_msg) )
+	{
+		print( "Error, incomplete write, only ".$n_bytes." of ".length($tx_msg)." written: $!" );
+	}
+
+	if ( $ack )
+	{
+		print( "Waiting for ack\n" );
+		my $max_wait = 3;
+		my $now = time();
+		while( 1 )
+		{
+			my ( $count, $rx_msg ) = $serial_port->read(4);
+
+			if ( $count )
+			{
+				#print( "Rx1: ".$count." bytes\n" );
+				my @resp = unpack( "C*", $rx_msg );
+				printMsg( \@resp, "Rx" );
+
+				if ( $resp[0] = 0x80 + ($id<<4) )
+				{
+					if ( ($resp[1] & 0xf0) == 0x40 )
+					{
+						my $socket = $resp[1] & 0x0f;
+						print( "Got ack for socket $socket\n" );
+						$result = !undef;
+					}
+					else
+					{
+						print( "Error, got bogus response\n" );
+					}
+					last;
+				}
+				else
+				{
+					print( "Error, got message for camera ".(($resp[0]-0x80)>>4)."\n" );
+				}
+			}
+			if ( (time() - $now) > $max_wait )
+			{
+				print( "Warning, response timeout\n" );
+				last;
+			}
+		}
+	}
+}
+
+my $sync = 0xff;
+
+sub cameraOff
+{
+	print( "Camera Off\n" );
+	my @msg = ( $sync, $address, 0x08, 0x00, 0x00, 0x00 );
+	sendCmd( \@msg );
+}
+
+sub cameraOn
+{
+	print( "Camera On\n" );
+	my @msg = ( $sync, $address, 0x88, 0x00, 0x00, 0x00 );
+	sendCmd( \@msg );
+}
+
+sub autoScan
+{
+	print( "Auto Scan\n" );
+	my @msg = ( $sync, $address, 0x90, 0x00, 0x00, 0x00 );
+	sendCmd( \@msg );
+}
+
+sub manScan
+{
+	print( "Manual Scan\n" );
+	my @msg = ( $sync, $address, 0x10, 0x00, 0x00, 0x00 );
+	sendCmd( \@msg );
+}
+
+sub stop
+{
+	print( "Stop\n" );
+	my @msg = ( $sync, $address, 0x00, 0x00, 0x00, 0x00 );
+	sendCmd( \@msg );
+}
+
+sub moveUp
+{
+	print( "Move Up\n" );
+	my $speed = shift || 0x3f;
+	my @msg = ( $sync, $address, 0x00, 0x08, 0x00, $speed );
+	sendCmd( \@msg );
+	if ( $autostop )
+	{
+		usleep( $autostop );
+		stop();
+	}
+}
+
+sub moveDown
+{
+	print( "Move Down\n" );
+	my $speed = shift || 0x3f;
+	my @msg = ( $sync, $address, 0x00, 0x10, 0x00, $speed );
+	sendCmd( \@msg );
+	if ( $autostop )
+	{
+		usleep( $autostop );
+		stop();
+	}
+}
+
+sub moveLeft
+{
+	print( "Move Left\n" );
+	my $speed = shift || 0x3f;
+	my @msg = ( $sync, $address, 0x00, 0x04, $speed, 0x00 );
+	sendCmd( \@msg );
+	if ( $autostop )
+	{
+		usleep( $autostop );
+		stop();
+	}
+}
+
+sub moveRight
+{
+	print( "Move Right\n" );
+	my $speed = shift || 0x3f;
+	my @msg = ( $sync, $address, 0x00, 0x02, $speed, 0x00 );
+	sendCmd( \@msg );
+	if ( $autostop )
+	{
+		usleep( $autostop );
+		stop();
+	}
+}
+
+sub moveUpLeft
+{
+	print( "Move Up/Left\n" );
+	my $panspeed = shift || 0x3f;
+	my $tiltspeed = shift || 0x3f;
+	my @msg = ( $sync, $address, 0x00, 0x0c, $panspeed, $tiltspeed );
+	sendCmd( \@msg );
+	if ( $autostop )
+	{
+		usleep( $autostop );
+		stop();
+	}
+}
+
+sub moveUpRight
+{
+	print( "Move Up/Right\n" );
+	my $panspeed = shift || 0x3f;
+	my $tiltspeed = shift || 0x3f;
+	my @msg = ( $sync, $address, 0x00, 0x0a, $panspeed, $tiltspeed );
+	sendCmd( \@msg );
+	if ( $autostop )
+	{
+		usleep( $autostop );
+		stop();
+	}
+}
+
+sub moveDownLeft
+{
+	print( "Move Down/Left\n" );
+	my $panspeed = shift || 0x3f;
+	my $tiltspeed = shift || 0x3f;
+	my @msg = ( $sync, $address, 0x00, 0x14, $panspeed, $tiltspeed );
+	sendCmd( \@msg );
+	if ( $autostop )
+	{
+		usleep( $autostop );
+		stop();
+	}
+}
+
+sub moveDownRight
+{
+	print( "Move Down/Right\n" );
+	my $panspeed = shift || 0x3f;
+	my $tiltspeed = shift || 0x3f;
+	my @msg = ( $sync, $address, 0x00, 0x12, $panspeed, $tiltspeed );
+	sendCmd( \@msg );
+	if ( $autostop )
+	{
+		usleep( $autostop );
+		stop();
+	}
+}
+
+sub flip180
+{
+	print( "Flip 180\n" );
+	my @msg = ( $sync, $address, 0x00, 0x07, 0x00, 0x21 );
+	sendCmd( \@msg );
+}
+
+sub zeroPan
+{
+	print( "Zero Pan\n" );
+	my @msg = ( $sync, $address, 0x00, 0x07, 0x00, 0x22 );
+	sendCmd( \@msg );
+}
+
+sub setZoomSpeed
+{
+	my $speed = shift;
+	my @msg = ( $sync, $address, 0x00, 0x25, 0x00, $speed );
+	sendCmd( \@msg );
+}
+
+sub zoomTele
+{
+	print( "Zoom Tele\n" );
+	my $speed = shift || 0x01;
+	setZoomSpeed( $speed );
+	usleep( 250000 );
+	my @msg = ( $sync, $address, 0x00, 0x20, 0x00, 0x00 );
+	sendCmd( \@msg );
+	if ( $autostop )
+	{
+		usleep( $autostop );
+		setZoomSpeed( 0 );
+	}
+}
+
+sub zoomWide
+{
+	print( "Zoom Wide\n" );
+	my $speed = shift || 0x01;
+	setZoomSpeed( $speed );
+	usleep( 250000 );
+	my @msg = ( $sync, $address, 0x00, 0x40, 0x00, 0x00 );
+	sendCmd( \@msg );
+	if ( $autostop )
+	{
+		usleep( $autostop );
+		setZoomSpeed( 0 );
+	}
+}
+
+sub setFocusSpeed
+{
+	my $speed = shift;
+	my @msg = ( $sync, $address, 0x00, 0x27, 0x00, $speed );
+	sendCmd( \@msg );
+}
+
+sub focusNear
+{
+	print( "Focus Near\n" );
+	my $speed = shift || 0x03;
+	setFocusSpeed( $speed );
+	usleep( 250000 );
+	my @msg = ( $sync, $address, 0x01, 0x00, 0x00, 0x00 );
+	sendCmd( \@msg );
+	if ( $autostop )
+	{
+		usleep( $autostop );
+		setFocusSpeed( 0 );
+	}
+}
+
+sub focusFar
+{
+	print( "Focus Far\n" );
+	my $speed = shift || 0x03;
+	setFocusSpeed( $speed );
+	usleep( 250000 );
+	my @msg = ( $sync, $address, 0x00, 0x80, 0x00, 0x00 );
+	sendCmd( \@msg );
+	if ( $autostop )
+	{
+		usleep( $autostop );
+		setFocusSpeed( 0 );
+	}
+}
+
+sub focusAuto
+{
+	print( "Focus Auto\n" );
+	my @msg = ( $sync, $address, 0x00, 0x2b, 0x00, 0x00 );
+	sendCmd( \@msg );
+}
+
+sub focusMan
+{
+	print( "Focus Man\n" );
+	my @msg = ( $sync, $address, 0x00, 0x2b, 0x00, 0x02 );
+	sendCmd( \@msg );
+}
+
+sub irisClose
+{
+	print( "Iris Close\n" );
+	my @msg = ( $sync, $address, 0x04, 0x00, 0x00, 0x00 );
+	sendCmd( \@msg );
+	if ( $autostop )
+	{
+		usleep( $autostop );
+		setIrisSpeed( 0 );
+	}
+}
+
+sub irisOpen
+{
+	print( "Iris Open\n" );
+	my @msg = ( $sync, $address, 0x02, 0x80, 0x00, 0x00 );
+	sendCmd( \@msg );
+	if ( $autostop )
+	{
+		usleep( $autostop );
+		setIrisSpeed( 0 );
+	}
+}
+
+sub irisAuto
+{
+	print( "Iris Auto\n" );
+	my @msg = ( $sync, $address, 0x00, 0x2d, 0x00, 0x00 );
+	sendCmd( \@msg );
+}
+
+sub irisMan
+{
+	print( "Iris Man\n" );
+	my @msg = ( $sync, $address, 0x00, 0x2d, 0x00, 0x02 );
+	sendCmd( \@msg );
+}
+
+sub writeScreen
+{
+	my $string = shift;
+	print( "Writing '$string' to screen\n" );
+	
+	my @chars = unpack( "C*", $string );
+	for ( my $i = 0; $i < length($string); $i++ )
+	{
+		printf( "0x%02x\n", $chars[$i] );
+		my @msg = ( $sync, $address, 0x00, 0x15, $i, $chars[$i] );
+		sendCmd( \@msg );
+	}
+}
+
+sub clearScreen
+{
+	print( "Clear Screen\n" );
+	my @msg = ( $sync, $address, 0x00, 0x17, 0x00, 0x00 );
+	sendCmd( \@msg );
+}
+
+sub clearPreset
+{
+	my $preset = shift || 1;
+	print( "Clear Preset $preset\n" );
+	my @msg = ( $sync, $address, 0x00, 0x05, 0x00, $preset );
+	sendCmd( \@msg );
+}
+
+sub presetSet
+{
+	my $preset = shift || 1;
+	print( "Set Preset $preset\n" );
+	my @msg = ( $sync, $address, 0x00, 0x03, 0x00, $preset );
+	sendCmd( \@msg );
+}
+
+sub presetGoto
+{
+	my $preset = shift || 1;
+	print( "Goto Preset $preset\n" );
+	my @msg = ( $sync, $address, 0x00, 0x07, 0x00, $preset );
+	sendCmd( \@msg );
+}
+
+sub presetHome
+{
+	print( "Home Preset\n" );
+	my @msg = ( $sync, $address, 0x00, 0x07, 0x00, 0x22 );
+	sendCmd( \@msg );
+}
+
+if ( $command eq "wake" )
+{
+	cameraOn();
+}
+elsif ( $command eq "sleep" )
+{
+	cameraOff();
+}
+elsif ( $command eq "move_con_up" )
+{
+	moveUp( $tiltspeed );
+}
+elsif ( $command eq "move_con_down" )
+{
+	moveDown( $tiltspeed );
+}
+elsif ( $command eq "move_con_left" )
+{
+	moveLeft( $panspeed );
+}
+elsif ( $command eq "move_con_right" )
+{
+	moveRight( $panspeed );
+}
+elsif ( $command eq "move_con_upleft" )
+{
+	moveUpLeft( $panspeed, $tiltspeed );
+}
+elsif ( $command eq "move_con_upright" )
+{
+	moveUpRight( $panspeed, $tiltspeed );
+}
+elsif ( $command eq "move_con_downleft" )
+{
+	moveDownLeft( $panspeed, $tiltspeed );
+}
+elsif ( $command eq "move_con_downright" )
+{
+	moveDownRight( $panspeed, $tiltspeed );
+}
+elsif ( $command eq "move_stop" )
+{
+	stop();
+}
+elsif ( $command eq "zoom_con_tele" )
+{
+	zoomTele( $speed );
+}
+elsif ( $command eq "zoom_con_wide" )
+{
+	zoomWide( $speed );
+}
+elsif ( $command eq "zoom_stop" )
+{
+	setZoomSpeed( 0 );
+}
+elsif ( $command eq "focus_con_near" )
+{
+	focusNear();
+}
+elsif ( $command eq "focus_con_far" )
+{
+	focusFar();
+}
+elsif ( $command eq "focus_stop" )
+{
+	stop();
+	#setFocusSpeed( 0 );
+}
+elsif ( $command eq "focus_auto" )
+{
+	focusAuto();
+}
+elsif ( $command eq "focus_man" )
+{
+	focusMan();
+}
+elsif ( $command eq "iris_con_close" )
+{
+	irisClose();
+}
+elsif ( $command eq "iris_con_open" )
+{
+	irisOpen();
+}
+elsif ( $command eq "iris_stop" )
+{
+	stop();
+}
+elsif ( $command eq "iris_auto" )
+{
+	irisAuto();
+}
+elsif ( $command eq "iris_man" )
+{
+	irisMan();
+}
+elsif ( $command eq "preset_home" )
+{
+	presetHome();
+}
+elsif ( $command eq "preset_set" )
+{
+	presetSet( $preset );
+}
+elsif ( $command eq "preset_goto" )
+{
+	presetGoto( $preset );
+}
+else
+{
+	print( "Error, can't handle command $command\n" );
+}
+
+$serial_port->close();
--- zm-1.21.3.orig/scripts/zmcontrol-pelco-p.pl
+++ zm-1.21.3/scripts/zmcontrol-pelco-p.pl
@@ -0,0 +1,640 @@
+#!/usr/bin/perl -wT
+#
+# ==========================================================================
+#
+# ZoneMinder Pelco-P Control Script, $Date: 2005/06/22 09:33:25 $, $Revision: 1.2 $
+# Copyright (C) 2003, 2004, 2005  Philip Coombes
+#
+# 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.
+#
+# ==========================================================================
+#
+# This script continuously monitors the recorded events for the given
+# monitor and applies any filters which would delete and/or upload 
+# matching events
+#
+use strict;
+
+# ==========================================================================
+#
+# These are the elements you need to edit to suit your installation
+#
+# ==========================================================================
+use constant ZM_CONFIG => "/etc/zm/zm.conf";	# Path to the ZoneMinder config file, autogenerated do not change (from zmconfig)
+use constant ZM_PATH_BIN => "/usr/bin";	# Path to the ZoneMinder executables, autogenerated do not change (from zmconfig)
+
+# Load the config from the database into the symbol table
+BEGIN
+{
+	no strict 'refs';
+
+	open( CONFIG, "<".ZM_CONFIG ) or die( "Can't open config file: $!" );
+	foreach my $str ( <CONFIG> )
+	{
+		next if ( $str =~ /^\s*$/ );
+		next if ( $str =~ /^\s*#/ );
+		my ( $name, $value ) = $str =~ /^\s*([^=\s]+)\s*=\s*([^=\s]+)\s*$/;
+		$name =~ tr/a-z/A-Z/;
+		if (( $name eq 'ZM_DB_SERVER' ) ||
+			( $name eq 'ZM_DB_NAME' ) ||
+			( $name eq 'ZM_DB_USER' ) ||
+			( $name eq 'ZM_DB_PASS' ))
+		{
+			*{$name} = sub { $value };
+		}
+	}
+	close( CONFIG );
+
+	use DBI;
+	my $dbh = DBI->connect( "DBI:mysql:database=".&ZM_DB_NAME.";host=".&ZM_DB_SERVER, &ZM_DB_USER, &ZM_DB_PASS );
+	my $sql = "select * from Config";
+	my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
+	my $res = $sth->execute() or die( "Can't execute '$sql': ".$sth->errstr() );
+	while( my $config = $sth->fetchrow_hashref() )
+	{
+		*{$config->{Name}} = sub { $config->{Value} };
+	}
+	$sth->finish();
+	$dbh->disconnect();
+}
+
+#use Data::Dumper;
+use Getopt::Long;
+use Device::SerialPort;
+use Time::HiRes qw( usleep );
+
+use constant LOG_FILE => ZM_PATH_LOGS.'/zmcontrol-pelco-p.log';
+
+$| = 1;
+
+$ENV{PATH}  = '/bin:/usr/bin';
+$ENV{SHELL} = '/bin/sh' if exists $ENV{SHELL};
+delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};
+
+sub Usage
+{
+	print( "
+Usage: zmcontrol-pelco-d.pl <various options>
+");
+	exit( -1 );
+}
+
+my $arg_string = join( " ", @ARGV );
+
+my $device = "/dev/ttyS0";
+my $address = 1;
+my $command;
+my $autostop;
+my ( $speed, $step );
+my ( $xcoord, $ycoord );
+my ( $panspeed, $tiltspeed );
+my ( $panstep, $tiltstep );
+my $preset;
+
+if ( !GetOptions(
+	'device=s'=>\$device,
+	'address=i'=>\$address,
+	'command=s'=>\$command,
+	'autostop=f'=>\$autostop,
+	'speed=i'=>\$speed,
+	'step=i'=>\$step,
+	'xcoord=i'=>\$xcoord,
+	'ycoord=i'=>\$ycoord,
+	'panspeed=i'=>\$panspeed,
+	'tiltspeed=i'=>\$tiltspeed,
+	'panstep=i'=>\$panstep,
+	'tiltstep=i'=>\$tiltstep,
+	'preset=i'=>\$preset
+	)
+)
+{
+	Usage();
+}
+
+if ( defined($autostop) )
+{
+	# Convert to microseconds.
+	$autostop = int(1000000*$autostop);
+}
+
+my $log_file = LOG_FILE;
+open( LOG, ">>$log_file" ) or die( "Can't open log file: $!" );
+open( STDOUT, ">&LOG" ) || die( "Can't dup stdout: $!" );
+select( STDOUT ); $| = 1;
+open( STDERR, ">&LOG" ) || die( "Can't dup stderr: $!" );
+select( STDERR ); $| = 1;
+select( LOG ); $| = 1;
+
+print( $arg_string."\n" );
+
+srand( time() );
+
+my $serial_port = new Device::SerialPort( $device );
+$serial_port->baudrate(2400);
+$serial_port->databits(8);
+$serial_port->parity('none');
+$serial_port->stopbits(1);
+$serial_port->handshake('none');
+ 
+$serial_port->read_const_time(50);
+$serial_port->read_char_time(10);
+
+sub printMsg
+{
+	my $msg = shift;
+	my $prefix = shift || "";
+	$prefix = $prefix.": " if ( $prefix );
+
+	my $line_length = 16;
+	my $msg_len = int(@$msg);
+
+	print( $prefix );
+	for ( my $i = 0; $i < $msg_len; $i++ )
+	{
+		if ( ($i > 0) && ($i%$line_length == 0) && ($i != ($msg_len-1)) )
+		{
+			printf( "\n%*s", length($prefix), "" );
+		}
+		printf( "%02x ", $msg->[$i] );
+	}
+	print( "[".$msg_len."]\n" );
+}
+
+sub sendCmd
+{
+	my $cmd = shift;
+	my $ack = shift || 0;
+
+	my $result = undef;
+
+	#print( Dumper( @$cmd ) );
+	my $checksum = 0x00;
+	for ( my $i = 0; $i < int(@$cmd)-1; $i++ )
+	{
+		$checksum ^= $cmd->[$i];
+		$checksum &= 0xff;
+		#printf( "%02x - %02x\n", $cmd->[$i], $checksum );
+	}
+	push( @$cmd, $checksum );
+
+	printMsg( $cmd, "Tx" );
+	my $id = $cmd->[0] & 0xf;
+
+	my $tx_msg = pack( "C*", @$cmd );
+
+	#print( "Tx: ".length( $tx_msg )." bytes\n" );
+	my $n_bytes = $serial_port->write( $tx_msg );
+	if ( !$n_bytes )
+	{
+		print( "Error, write failed: $!" );
+	}
+	if ( $n_bytes != length($tx_msg) )
+	{
+		print( "Error, incomplete write, only ".$n_bytes." of ".length($tx_msg)." written: $!" );
+	}
+
+	if ( $ack )
+	{
+		print( "Waiting for ack\n" );
+		my $max_wait = 3;
+		my $now = time();
+		while( 1 )
+		{
+			my ( $count, $rx_msg ) = $serial_port->read(4);
+
+			if ( $count )
+			{
+				#print( "Rx1: ".$count." bytes\n" );
+				my @resp = unpack( "C*", $rx_msg );
+				printMsg( \@resp, "Rx" );
+
+				if ( $resp[0] = 0x80 + ($id<<4) )
+				{
+					if ( ($resp[1] & 0xf0) == 0x40 )
+					{
+						my $socket = $resp[1] & 0x0f;
+						print( "Got ack for socket $socket\n" );
+						$result = !undef;
+					}
+					else
+					{
+						print( "Error, got bogus response\n" );
+					}
+					last;
+				}
+				else
+				{
+					print( "Error, got message for camera ".(($resp[0]-0x80)>>4)."\n" );
+				}
+			}
+			if ( (time() - $now) > $max_wait )
+			{
+				print( "Warning, response timeout\n" );
+				last;
+			}
+		}
+	}
+}
+
+my $stx = 0xa0;
+my $etx = 0xaf;
+
+sub cameraOff
+{
+	print( "Camera Off\n" );
+	my @msg = ( $stx, $address, 0x10, 0x00, 0x00, 0x00, $etx );
+	sendCmd( \@msg );
+}
+
+sub cameraOn
+{
+	print( "Camera On\n" );
+	my @msg = ( $stx, $address, 0x40, 0x00, 0x00, 0x00, $etx );
+	sendCmd( \@msg );
+}
+
+sub autoScan
+{
+	print( "Auto Scan\n" );
+	my @msg = ( $stx, $address, 0x90, 0x00, 0x00, 0x00, $etx );
+	sendCmd( \@msg );
+}
+
+sub manScan
+{
+	print( "Manual Scan\n" );
+	my @msg = ( $stx, $address, 0x10, 0x00, 0x00, 0x00, $etx );
+	sendCmd( \@msg );
+}
+
+sub stop
+{
+	print( "Stop\n" );
+	my @msg = ( $stx, $address, 0x00, 0x00, 0x00, 0x00, $etx );
+	sendCmd( \@msg );
+}
+
+sub moveUp
+{
+	print( "Move Up\n" );
+	my $speed = shift || 0x3f;
+	my @msg = ( $stx, $address, 0x00, 0x08, 0x00, $speed, $etx );
+	sendCmd( \@msg );
+	if ( $autostop )
+	{
+		usleep( $autostop );
+		stop();
+	}
+}
+
+sub moveDown
+{
+	print( "Move Down\n" );
+	my $speed = shift || 0x3f;
+	my @msg = ( $stx, $address, 0x00, 0x10, 0x00, $speed, $etx );
+	sendCmd( \@msg );
+	if ( $autostop )
+	{
+		usleep( $autostop );
+		stop();
+	}
+}
+
+sub moveLeft
+{
+	print( "Move Left\n" );
+	my $speed = shift || 0x3f;
+	my @msg = ( $stx, $address, 0x00, 0x04, $speed, 0x00, $etx );
+	sendCmd( \@msg );
+	if ( $autostop )
+	{
+		usleep( $autostop );
+		stop();
+	}
+}
+
+sub moveRight
+{
+	print( "Move Right\n" );
+	my $speed = shift || 0x3f;
+	my @msg = ( $stx, $address, 0x00, 0x02, $speed, 0x00 , $etx);
+	sendCmd( \@msg );
+	if ( $autostop )
+	{
+		usleep( $autostop );
+		stop();
+	}
+}
+
+sub moveUpLeft
+{
+	print( "Move Up/Left\n" );
+	my $panspeed = shift || 0x3f;
+	my $tiltspeed = shift || 0x3f;
+	my @msg = ( $stx, $address, 0x00, 0x0c, $panspeed, $tiltspeed, $etx );
+	sendCmd( \@msg );
+	if ( $autostop )
+	{
+		usleep( $autostop );
+		stop();
+	}
+}
+
+sub moveUpRight
+{
+	print( "Move Up/Right\n" );
+	my $panspeed = shift || 0x3f;
+	my $tiltspeed = shift || 0x3f;
+	my @msg = ( $stx, $address, 0x00, 0x0a, $panspeed, $tiltspeed, $etx );
+	sendCmd( \@msg );
+	if ( $autostop )
+	{
+		usleep( $autostop );
+		stop();
+	}
+}
+
+sub moveDownLeft
+{
+	print( "Move Down/Left\n" );
+	my $panspeed = shift || 0x3f;
+	my $tiltspeed = shift || 0x3f;
+	my @msg = ( $stx, $address, 0x00, 0x14, $panspeed, $tiltspeed, $etx );
+	sendCmd( \@msg );
+	if ( $autostop )
+	{
+		usleep( $autostop );
+		stop();
+	}
+}
+
+sub moveDownRight
+{
+	print( "Move Down/Right\n" );
+	my $panspeed = shift || 0x3f;
+	my $tiltspeed = shift || 0x3f;
+	my @msg = ( $stx, $address, 0x00, 0x12, $panspeed, $tiltspeed, $etx );
+	sendCmd( \@msg );
+	if ( $autostop )
+	{
+		usleep( $autostop );
+		stop();
+	}
+}
+
+sub flip180
+{
+	print( "Flip 180\n" );
+	my @msg = ( $stx, $address, 0x00, 0x07, 0x00, 0x21, $etx );
+	sendCmd( \@msg );
+}
+
+sub zeroPan
+{
+	print( "Zero Pan\n" );
+	my @msg = ( $stx, $address, 0x00, 0x07, 0x00, 0x22, $etx );
+	sendCmd( \@msg );
+}
+
+sub setZoomSpeed
+{
+	my $speed = shift;
+	my @msg = ( $stx, $address, 0x00, 0x25, 0x00, $speed, $etx );
+	sendCmd( \@msg );
+}
+
+sub zoomTele
+{
+	print( "Zoom Tele\n" );
+	my $speed = shift || 0x01;
+	setZoomSpeed( $speed );
+	my @msg = ( $stx, $address, 0x00, 0x20, 0x00, 0x00, $etx );
+	sendCmd( \@msg );
+	if ( $autostop )
+	{
+		usleep( $autostop );
+		setZoomSpeed( 0 );
+	}
+}
+
+sub zoomWide
+{
+	print( "Zoom Wide\n" );
+	my $speed = shift || 0x01;
+	setZoomSpeed( $speed );
+	my @msg = ( $stx, $address, 0x00, 0x40, 0x00, 0x00, $etx );
+	sendCmd( \@msg );
+	if ( $autostop )
+	{
+		usleep( $autostop );
+		setZoomSpeed( 0 );
+	}
+}
+
+sub setFocusSpeed
+{
+	my $speed = shift;
+	my @msg = ( $stx, $address, 0x00, 0x27, 0x00, $speed, $etx );
+	sendCmd( \@msg );
+}
+
+sub focusNear
+{
+	print( "Focus Near\n" );
+	my $speed = shift || 0x03;
+	setFocusSpeed( $speed );
+	my @msg = ( $stx, $address, 0x02, 0x00, 0x00, 0x00, $etx );
+	sendCmd( \@msg );
+	if ( $autostop )
+	{
+		usleep( $autostop );
+		setFocusSpeed( 0 );
+	}
+}
+
+sub focusFar
+{
+	print( "Focus Far\n" );
+	my $speed = shift || 0x03;
+	setFocusSpeed( $speed );
+	my @msg = ( $stx, $address, 0x01, 0x80, 0x00, 0x00, $etx );
+	sendCmd( \@msg );
+	if ( $autostop )
+	{
+		usleep( $autostop );
+		setFocusSpeed( 0 );
+	}
+}
+
+sub focusAuto
+{
+	print( "Focus Auto\n" );
+	my @msg = ( $stx, $address, 0x00, 0x2b, 0x00, 0x01, $etx );
+	sendCmd( \@msg );
+}
+
+sub focusMan
+{
+	print( "Focus Man\n" );
+	my @msg = ( $stx, $address, 0x00, 0x2b, 0x00, 0x02, $etx );
+	sendCmd( \@msg );
+}
+
+sub writeScreen
+{
+	my $string = shift;
+	print( "Writing '$string' to screen\n" );
+	
+	my @chars = unpack( "C*", $string );
+	for ( my $i = 0; $i < length($string); $i++ )
+	{
+		printf( "0x%02x\n", $chars[$i] );
+		my @msg = ( $stx, $address, 0x00, 0x15, $i, $chars[$i], $etx );
+		sendCmd( \@msg );
+	}
+}
+
+sub clearScreen
+{
+	print( "Clear Screen\n" );
+	my @msg = ( $stx, $address, 0x00, 0x17, 0x00, 0x00, $etx );
+	sendCmd( \@msg );
+}
+
+sub clearPreset
+{
+	my $preset = shift || 1;
+	print( "Clear Preset $preset\n" );
+	my @msg = ( $stx, $address, 0x00, 0x05, 0x00, $preset, $etx );
+	sendCmd( \@msg );
+}
+
+sub presetSet
+{
+	my $preset = shift || 1;
+	print( "Set Preset $preset\n" );
+	my @msg = ( $stx, $address, 0x00, 0x03, 0x00, $preset, $etx );
+	sendCmd( \@msg );
+}
+
+sub presetGoto
+{
+	my $preset = shift || 1;
+	print( "Goto Preset $preset\n" );
+	my @msg = ( $stx, $address, 0x00, 0x07, 0x00, $preset, $etx );
+	sendCmd( \@msg );
+}
+
+sub presetHome
+{
+	print( "Home Preset\n" );
+	my @msg = ( $stx, $address, 0x00, 0x07, 0x00, 0x22, $etx );
+	sendCmd( \@msg );
+}
+
+if ( $command eq "wake" )
+{
+	cameraOn();
+}
+elsif ( $command eq "sleep" )
+{
+	cameraOff();
+}
+elsif ( $command eq "move_con_up" )
+{
+	moveUp( $tiltspeed );
+}
+elsif ( $command eq "move_con_down" )
+{
+	moveDown( $tiltspeed );
+}
+elsif ( $command eq "move_con_left" )
+{
+	moveLeft( $panspeed );
+}
+elsif ( $command eq "move_con_right" )
+{
+	moveRight( $panspeed );
+}
+elsif ( $command eq "move_con_upleft" )
+{
+	moveUpLeft( $panspeed, $tiltspeed );
+}
+elsif ( $command eq "move_con_upright" )
+{
+	moveUpRight( $panspeed, $tiltspeed );
+}
+elsif ( $command eq "move_con_downleft" )
+{
+	moveDownLeft( $panspeed, $tiltspeed );
+}
+elsif ( $command eq "move_con_downright" )
+{
+	moveDownRight( $panspeed, $tiltspeed );
+}
+elsif ( $command eq "move_stop" )
+{
+	stop();
+}
+elsif ( $command eq "zoom_con_tele" )
+{
+	zoomTele( $speed );
+}
+elsif ( $command eq "zoom_con_wide" )
+{
+	zoomWide( $speed );
+}
+elsif ( $command eq "zoom_stop" )
+{
+	setZoomSpeed( 0 );
+}
+elsif ( $command eq "focus_con_near" )
+{
+	focusNear();
+}
+elsif ( $command eq "focus_con_far" )
+{
+	focusFar();
+}
+elsif ( $command eq "focus_stop" )
+{
+	setFocusSpeed( 0 );
+}
+elsif ( $command eq "focus_auto" )
+{
+	focusAuto();
+}
+elsif ( $command eq "focus_man" )
+{
+	focusMan();
+}
+elsif ( $command eq "preset_home" )
+{
+	presetHome();
+}
+elsif ( $command eq "preset_set" )
+{
+	presetSet( $preset );
+}
+elsif ( $command eq "preset_goto" )
+{
+	presetGoto( $preset );
+}
+else
+{
+	print( "Error, can't handle command $command\n" );
+}
+
+$serial_port->close();
--- zm-1.21.3.orig/scripts/zmtrack.pl
+++ zm-1.21.3/scripts/zmtrack.pl
@@ -0,0 +1,268 @@
+#!/usr/bin/perl -wT
+#
+# ==========================================================================
+#
+# ZoneMinder Experimental PTZ Tracking Script, $Date: 2005/03/04 12:15:02 $, $Revision: 1.4 $
+# Copyright (C) 2003, 2004, 2005  Philip Coombes
+#
+# 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.
+#
+# ==========================================================================
+#
+# This script is used to trigger and cancel alarms from external sources
+# using an arbitrary text based format
+#
+use strict;
+use bytes;
+
+# ==========================================================================
+#
+# User config
+#
+# ==========================================================================
+
+use constant ZM_CONFIG => "/etc/zm/zm.conf";	# Path to the ZoneMinder config file, autogenerated do not change (from zmconfig)
+use constant ZM_VERSION => "1.21.3";	# ZoneMinder version number, autogenerated do not change (from zmconfig)
+use constant ZM_PATH_BIN => "/usr/bin";	# Path to the ZoneMinder executables, autogenerated do not change (from zmconfig)
+
+# Load the config from the database into the symbol table
+BEGIN
+{
+	no strict 'refs';
+
+	open( CONFIG, "<".ZM_CONFIG ) or die( "Can't open config file: $!" );
+	foreach my $str ( <CONFIG> )
+	{
+		next if ( $str =~ /^\s*$/ );
+		next if ( $str =~ /^\s*#/ );
+		my ( $name, $value ) = $str =~ /^\s*([^=\s]+)\s*=\s*([^=\s]+)\s*$/;
+		$name =~ tr/a-z/A-Z/;
+		if (( $name eq 'ZM_DB_SERVER' ) ||
+			( $name eq 'ZM_DB_NAME' ) ||
+			( $name eq 'ZM_DB_USER' ) ||
+			( $name eq 'ZM_DB_PASS' ))
+		{
+			*{$name} = sub { $value };
+		}
+	}
+	close( CONFIG );
+
+	use DBI;
+	my $dbh = DBI->connect( "DBI:mysql:database=".&ZM_DB_NAME.";host=".&ZM_DB_SERVER, &ZM_DB_USER, &ZM_DB_PASS );
+	my $sql = "select * from Config";
+	my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
+	my $res = $sth->execute() or die( "Can't execute '$sql': ".$sth->errstr() );
+	while( my $config = $sth->fetchrow_hashref() )
+	{
+		*{$config->{Name}} = sub { $config->{Value} };
+	}
+	$sth->finish();
+	$dbh->disconnect();
+}
+
+use constant LOG_FILE => ZM_PATH_LOGS.'/zmtrack-%s.log';
+use constant SLEEP_TIME => 10000; # In microseconds
+use constant VERBOSE => 1; # Whether to output more verbose debug
+
+# ==========================================================================
+#
+# Don't change anything from here on down
+#
+# ==========================================================================
+
+use DBI;
+use POSIX;
+use Data::Dumper;
+use Getopt::Long;
+use Time::HiRes qw( usleep );
+
+$| = 1;
+
+$ENV{PATH}  = '/bin:/usr/bin';
+$ENV{SHELL} = '/bin/sh' if exists $ENV{SHELL};
+delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};
+
+my $mid = 0;
+
+sub Usage
+{
+	print( "
+		Usage: zmtrack.pl -m <monitor>,--monitor=<monitor>]
+		Parameters are :-
+		-m<monitor>, --monitor=<monitor>   - Id of the monitor to track
+		");
+	exit( -1 );
+}   
+
+if ( !GetOptions( 'monitor=s'=>\$mid ) )
+{
+	Usage();
+}
+
+my ( $detaint_mid ) = $mid =~ /^(\d+)$/;
+$mid = $detaint_mid;
+
+my $log_file = sprintf( LOG_FILE, $mid );
+open( LOG, ">>$log_file" ) or die( "Can't open log file: $!" );
+open( STDOUT, ">&LOG" ) || die( "Can't dup stdout: $!" );
+select( STDOUT ); $| = 1;
+open( STDERR, ">&LOG" ) || die( "Can't dup stderr: $!" );
+select( STDERR ); $| = 1;
+select( LOG ); $| = 1;
+
+print( "Tracker daemon $mid (experimental) starting at ".strftime( '%y/%m/%d %H:%M:%S', localtime() )."\n" );
+
+my $dbh = DBI->connect( "DBI:mysql:database=".ZM_DB_NAME.";host=".ZM_DB_SERVER, ZM_DB_USER, ZM_DB_PASS );
+
+my $sql = "select C.*,M.* from Monitors as M left join Controls as C on M.ControlId = C.Id where M.Id = ?";
+my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
+
+my $res = $sth->execute( $mid ) or die( "Can't execute '$sql': ".$sth->errstr() );
+my $monitor = $sth->fetchrow_hashref();
+
+if ( !$monitor )
+{
+	print( "Can't find monitor '$mid'\n" );
+	exit( -1 );
+}
+if ( !$monitor->{Controllable} )
+{
+	print( "Monitor '$mid' is not controllable\n" );
+	exit( -1 );
+}
+if ( !$monitor->{TrackMotion} )
+{
+	print( "Monitor '$mid' is not configured to track motion\n" );
+	exit( -1 );
+}
+
+if ( !$monitor->{CanMoveMap} )
+{
+	print( "Monitor '$mid' cannot move in map mode" );
+	if ( $monitor->{CanMoveRel} )
+	{
+		print( ", falling back to pseudo map mode\n" );
+	}
+	else
+	{
+		print( "\n" );
+		exit( -1 );
+	}
+}
+
+print( "Found monitor for id '$monitor'\n" ) if ( VERBOSE );
+my $size = 512; # We only need the first 512 bytes really for the alarm state and forced alarm
+$monitor->{ShmKey} = hex(ZM_SHM_KEY)|$monitor->{Id};
+$monitor->{ShmId} = shmget( $monitor->{ShmKey}, $size, 0 );
+if ( !defined($monitor->{ShmId}) )
+{
+	printf( "Can't get shared memory id '%x': $!\n", $monitor->{ShmKey}, $! );
+	exit( -1 );
+}
+
+sub Suspend
+{
+	my $monitor = shift;
+	my $suspend_cmd = "/usr/local/bin/zmu -m ".$monitor->{Id}." -u -U admin -P pc00zm";
+	qx( $suspend_cmd );
+}
+
+sub Resume
+{
+	my $monitor = shift;
+	sleep( $monitor->{TrackDelay} );
+	my $resume_cmd = "/usr/local/bin/zmu -m ".$monitor->{Id}." -r -U admin -P pc00zm";
+	qx( $resume_cmd );
+}
+
+sub Track
+{
+	my $monitor = shift;
+	my ( $x, $y ) = @_;
+	my ( $detaint_x ) = $x =~ /^(\d+)$/; $x = $detaint_x;
+	my ( $detaint_y ) = $y =~ /^(\d+)$/; $y = $detaint_y;
+	my $move_cmd = $monitor->{Command};
+	$move_cmd .= " --device=".$monitor->{ControlDevice} if ( $monitor->{ControlDevice} );
+	$move_cmd .= " --address=".$monitor->{ControlAddress} if ( $monitor->{ControlAddress} );
+	$move_cmd .= " --command=".($monitor->{CanMoveMap}?"move_map":"move_pseudo_map")." --xcoord=$x --ycoord=$y --width=".$monitor->{Width}." --height=".$monitor->{Height};
+	qx( $move_cmd );
+}
+
+sub Return
+{
+	my $monitor = shift;
+	my $move_cmd = $monitor->{Command};
+	$move_cmd .= " --device=".$monitor->{ControlDevice} if ( $monitor->{ControlDevice} );
+	$move_cmd .= " --address=".$monitor->{ControlAddress} if ( $monitor->{ControlAddress} );
+	$move_cmd .= " --command=".($monitor->{ReturnLocation}?"preset1":"preset_home");
+	qx( $move_cmd );
+}
+
+my $last_alarm = 0;
+if ( ($monitor->{ReturnLocation} >= 0) )
+{
+	Suspend( $monitor );
+	Return( $monitor );
+	Resume( $monitor );
+}
+
+my $alarmed = undef;
+while( 1 )
+{
+	my $state;
+	if ( !shmread( $monitor->{ShmId}, $state, 8, 4 ) )
+	{ 
+		print( "Can't read from shared memory: $!\n" );
+		exit( -1 );
+	}
+	$state = unpack( "l", $state );
+
+	if ( $state == 2 ) # Alarmed
+	{
+		my $alarm_pos;
+		if ( !shmread( $monitor->{ShmId}, $alarm_pos, 48, 8 ) )
+		{
+			print( "Can't read from shared memory '$monitor->{ShmKey}/$monitor->{ShmId}': $!\n" );
+			next;
+		}
+		my ( $alarm_x, $alarm_y ) = unpack( "ll", $alarm_pos );
+		if ( $alarm_x > 0 && $alarm_y > 0 )
+		{
+			print( "Got alarm at $alarm_x, $alarm_y\n" ) if ( VERBOSE );
+			Suspend( $monitor );
+			Track( $monitor, $alarm_x, $alarm_y );
+			Resume( $monitor );
+			$last_alarm = time();
+			$alarmed = !undef;
+		}
+	}
+	else
+	{
+		if ( VERBOSE && $alarmed )
+		{
+			print( "Left alarm state\n" );
+			$alarmed = undef;
+		}
+		if ( ($monitor->{ReturnLocation} >= 0) && ($last_alarm > 0) && ((time()-$last_alarm) > $monitor->{ReturnDelay}) )
+		{
+			print( "Returning to location ".$monitor->{ReturnLocation}."\n" ) if ( VERBOSE );
+			Suspend( $monitor );
+			Return( $monitor );
+			Resume( $monitor );
+			$last_alarm = 0;
+		}
+	}
+	usleep( SLEEP_TIME );
+}
--- zm-1.21.3.orig/scripts/zmcontrol-kx-hcm10.pl
+++ zm-1.21.3/scripts/zmcontrol-kx-hcm10.pl
@@ -0,0 +1,346 @@
+#!/usr/bin/perl -wT
+#
+# ==========================================================================
+#
+# ZoneMinder Panasonic KX-HCM10 Control Script, $Date: 2005/07/14 08:53:15 $, $Revision: 1.6 $
+# Copyright (C) 2003, 2004, 2005  Philip Coombes
+#
+# 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.
+#
+# ==========================================================================
+#
+# This script continuously monitors the recorded events for the given
+# monitor and applies any filters which would delete and/or upload 
+# matching events
+#
+use strict;
+
+# ==========================================================================
+#
+# These are the elements you need to edit to suit your installation
+#
+# ==========================================================================
+use constant ZM_CONFIG => "/etc/zm/zm.conf";	# Path to the ZoneMinder config file, autogenerated do not change (from zmconfig)
+use constant ZM_VERSION => "1.21.3";	# ZoneMinder version number, autogenerated do not change (from zmconfig)
+use constant ZM_PATH_BIN => "/usr/bin";	# Path to the ZoneMinder executables, autogenerated do not change (from zmconfig)
+
+# Load the config from the database into the symbol table
+BEGIN
+{
+	no strict 'refs';
+
+	open( CONFIG, "<".ZM_CONFIG ) or die( "Can't open config file: $!" );
+	foreach my $str ( <CONFIG> )
+	{
+		next if ( $str =~ /^\s*$/ );
+		next if ( $str =~ /^\s*#/ );
+		my ( $name, $value ) = $str =~ /^\s*([^=\s]+)\s*=\s*([^=\s]+)\s*$/;
+		$name =~ tr/a-z/A-Z/;
+		if (( $name eq 'ZM_DB_SERVER' ) ||
+			( $name eq 'ZM_DB_NAME' ) ||
+			( $name eq 'ZM_DB_USER' ) ||
+			( $name eq 'ZM_DB_PASS' ))
+		{
+			*{$name} = sub { $value };
+		}
+	}
+	close( CONFIG );
+
+	use DBI;
+	my $dbh = DBI->connect( "DBI:mysql:database=".&ZM_DB_NAME.";host=".&ZM_DB_SERVER, &ZM_DB_USER, &ZM_DB_PASS );
+	my $sql = "select * from Config";
+	my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
+	my $res = $sth->execute() or die( "Can't execute '$sql': ".$sth->errstr() );
+	while( my $config = $sth->fetchrow_hashref() )
+	{
+		*{$config->{Name}} = sub { $config->{Value} };
+	}
+	$sth->finish();
+	$dbh->disconnect();
+}
+
+use Getopt::Long;
+use Device::SerialPort;
+
+use constant LOG_FILE => ZM_PATH_LOGS.'/zmcontrol-kx-hcm10.log';
+
+$| = 1;
+
+$ENV{PATH}  = '/bin:/usr/bin';
+$ENV{SHELL} = '/bin/sh' if exists $ENV{SHELL};
+delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};
+
+sub Usage
+{
+	print( "
+Usage: zmcontrol-kx-hcm10.pl <various options>
+");
+	exit( -1 );
+}
+
+my $arg_string = join( " ", @ARGV );
+
+my $address;
+my $command;
+my ( $speed, $step );
+my ( $xcoord, $ycoord );
+my ( $width, $height );
+my ( $panspeed, $tiltspeed );
+my ( $panstep, $tiltstep );
+my $preset;
+
+if ( !GetOptions(
+	'address=s'=>\$address,
+	'command=s'=>\$command,
+	'speed=i'=>\$speed,
+	'step=i'=>\$step,
+	'xcoord=i'=>\$xcoord,
+	'ycoord=i'=>\$ycoord,
+	'width=i'=>\$width,
+	'height=i'=>\$height,
+	'panspeed=i'=>\$panspeed,
+	'tiltspeed=i'=>\$tiltspeed,
+	'panstep=i'=>\$panstep,
+	'tiltstep=i'=>\$tiltstep,
+	'preset=i'=>\$preset
+	)
+)
+{
+	Usage();
+}
+
+if ( !$address )
+{
+	Usage();
+}
+
+my $log_file = LOG_FILE;
+open( LOG, ">>$log_file" ) or die( "Can't open log file: $!" );
+open( STDOUT, ">&LOG" ) || die( "Can't dup stdout: $!" );
+select( STDOUT ); $| = 1;
+open( STDERR, ">&LOG" ) || die( "Can't dup stderr: $!" );
+select( STDERR ); $| = 1;
+select( LOG ); $| = 1;
+
+print( $arg_string."\n" );
+
+srand( time() );
+
+sub printMsg
+{
+	my $msg = shift;
+	my $msg_len = length($msg);
+
+	print( $msg );
+	print( "[".$msg_len."]\n" );
+}
+
+sub sendCmd
+{
+	my $cmd = shift;
+
+	my $result = undef;
+
+	printMsg( $cmd, "Tx" );
+
+	use LWP::UserAgent;
+	my $ua = LWP::UserAgent->new;
+	$ua->agent( "ZoneMinder Control Agent/".ZM_VERSION );
+
+	#print( "http://$address/$cmd\n" );
+	my $req = HTTP::Request->new( GET=>"http://$address$cmd" );
+	my $res = $ua->request($req);
+
+	if ( $res->is_success )
+	{
+		$result = !undef;
+	}
+	else
+	{
+		print( "Error check failed: '".$res->status_line()."'\n" );
+	}
+
+	return( $result );
+}
+
+sub cameraReset
+{
+	print( "Camera Reset\n" );
+	my $cmd = "nphRestart?PAGE=Restart&Restart=OK";
+	sendCmd( $cmd );
+}
+
+sub moveUp
+{
+	print( "Move Up\n" );
+	my $cmd = "nphControlCamera?Direction=TiltUp";
+	sendCmd( $cmd );
+}
+
+sub moveDown
+{
+	print( "Move Down\n" );
+	my $cmd = "nphControlCamera?Direction=TiltDown";
+	sendCmd( $cmd );
+}
+
+sub moveLeft
+{
+	print( "Move Left\n" );
+	my $cmd = "nphControlCamera?Direction=PanLeft";
+	sendCmd( $cmd );
+}
+
+sub moveRight
+{
+	print( "Move Right\n" );
+	my $cmd = "nphControlCamera?Direction=PanRight";
+	sendCmd( $cmd );
+}
+
+sub moveMap
+{
+	my ( $xcoord, $ycoord, $width, $height ) = @_;
+	print( "Move Map to $xcoord,$ycoord\n" );
+	my $cmd = "nphControlCamera?Direction=Direct&NewPosition.x=$xcoord&NewPosition.y=$ycoord&Width=$width&Height=$height";
+	sendCmd( $cmd );
+}
+
+sub zoomTele
+{
+	print( "Zoom Tele\n" );
+	my $cmd = "nphControlCamera?Direction=ZoomTele";
+	sendCmd( $cmd );
+}
+
+sub zoomWide
+{
+	print( "Zoom Wide\n" );
+	my $cmd = "nphControlCamera?Direction=ZoomWide";
+	sendCmd( $cmd );
+}
+
+sub focusNear
+{
+	print( "Focus Near\n" );
+	my $cmd = "nphControlCamera?Direction=FocusNear";
+	sendCmd( $cmd );
+}
+
+sub focusFar
+{
+	print( "Focus Far\n" );
+	my $cmd = "nphControlCamera?Direction=FocusFar";
+	sendCmd( $cmd );
+}
+
+sub focusAuto
+{
+	print( "Focus Auto\n" );
+	my $cmd = "nphControlCamera?Direction=FocusAuto";
+	sendCmd( $cmd );
+}
+
+sub presetClear
+{
+	my $preset = shift || 1;
+	print( "Clear Preset $preset\n" );
+	my $cmd = "nphPresetNameCheck?Data=$preset";
+	sendCmd( $cmd );
+}
+
+sub presetSet
+{
+	my $preset = shift || 1;
+	print( "Set Preset $preset\n" );
+	my $cmd = "nphPresetNameCheck?PresetName=$preset&Data=$preset";
+	sendCmd( $cmd );
+}
+
+sub presetGoto
+{
+	my $preset = shift || 1;
+	print( "Goto Preset $preset\n" );
+	my $cmd = "nphControlCamera?Direction=Preset&PresetOperation=Move&Data=$preset";
+	sendCmd( $cmd );
+}
+
+sub presetHome
+{
+	print( "Home Preset\n" );
+	my $cmd = "nphControlCamera?Direction=HomePosition";
+	sendCmd( $cmd );
+}
+
+if ( $command eq "move_con_up" )
+{
+	moveUp();
+}
+elsif ( $command eq "move_con_down" )
+{
+	moveDown();
+}
+elsif ( $command eq "move_con_left" )
+{
+	moveLeft();
+}
+elsif ( $command eq "move_con_right" )
+{
+	moveRight();
+}
+elsif ( $command eq "move_map" )
+{
+	moveMap( $xcoord, $ycoord, $width, $height );
+}
+elsif ( $command eq "zoom_con_tele" )
+{
+	zoomTele();
+}
+elsif ( $command eq "zoom_con_wide" )
+{
+	zoomWide();
+}
+elsif ( $command eq "focus_con_near" )
+{
+	focusNear();
+}
+elsif ( $command eq "focus_con_far" )
+{
+	focusFar();
+}
+elsif ( $command eq "focus_auto" )
+{
+	focusAuto();
+}
+elsif ( $command eq "focus_man" )
+{
+	#focusMan();
+}
+elsif ( $command eq "preset_home" )
+{
+	presetHome();
+}
+elsif ( $command eq "preset_set" )
+{
+	presetSet( $preset );
+}
+elsif ( $command eq "preset_goto" )
+{
+	presetGoto( $preset );
+}
+else
+{
+	print( "Error, can't handle command $command\n" );
+}
--- zm-1.21.3.orig/scripts/zmcontrol-visca.pl
+++ zm-1.21.3/scripts/zmcontrol-visca.pl
@@ -0,0 +1,659 @@
+#!/usr/bin/perl -wT
+#
+# ==========================================================================
+#
+# ZoneMinder VISCA Control Script, $Date: 2005/07/14 08:53:15 $, $Revision: 1.6 $
+# Copyright (C) 2003, 2004, 2005  Philip Coombes
+#
+# 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.
+#
+# ==========================================================================
+#
+# This script continuously monitors the recorded events for the given
+# monitor and applies any filters which would delete and/or upload 
+# matching events
+#
+use strict;
+
+# ==========================================================================
+#
+# These are the elements you need to edit to suit your installation
+#
+# ==========================================================================
+use constant ZM_CONFIG => "/etc/zm/zm.conf";	# Path to the ZoneMinder config file, autogenerated do not change (from zmconfig)
+use constant ZM_PATH_BIN => "/usr/bin";	# Path to the ZoneMinder executables, autogenerated do not change (from zmconfig)
+
+# Load the config from the database into the symbol table
+BEGIN
+{
+	no strict 'refs';
+
+	open( CONFIG, "<".ZM_CONFIG ) or die( "Can't open config file: $!" );
+	foreach my $str ( <CONFIG> )
+	{
+		next if ( $str =~ /^\s*$/ );
+		next if ( $str =~ /^\s*#/ );
+		my ( $name, $value ) = $str =~ /^\s*([^=\s]+)\s*=\s*([^=\s]+)\s*$/;
+		$name =~ tr/a-z/A-Z/;
+		if (( $name eq 'ZM_DB_SERVER' ) ||
+			( $name eq 'ZM_DB_NAME' ) ||
+			( $name eq 'ZM_DB_USER' ) ||
+			( $name eq 'ZM_DB_PASS' ))
+		{
+			*{$name} = sub { $value };
+		}
+	}
+	close( CONFIG );
+
+	use DBI;
+	my $dbh = DBI->connect( "DBI:mysql:database=".&ZM_DB_NAME.";host=".&ZM_DB_SERVER, &ZM_DB_USER, &ZM_DB_PASS );
+	my $sql = "select * from Config";
+	my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
+	my $res = $sth->execute() or die( "Can't execute '$sql': ".$sth->errstr() );
+	while( my $config = $sth->fetchrow_hashref() )
+	{
+		*{$config->{Name}} = sub { $config->{Value} };
+	}
+	$sth->finish();
+	$dbh->disconnect();
+}
+
+use Getopt::Long;
+use Device::SerialPort;
+
+use constant LOG_FILE => ZM_PATH_LOGS.'/zmcontrol-visca.log';
+
+$| = 1;
+
+$ENV{PATH}  = '/bin:/usr/bin';
+$ENV{SHELL} = '/bin/sh' if exists $ENV{SHELL};
+delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};
+
+sub Usage
+{
+	print( "
+Usage: zmcontrol-visca.pl <various options>
+");
+	exit( -1 );
+}
+
+my $arg_string = join( " ", @ARGV );
+
+my $device = "/dev/ttyS0";
+my $address = 1;
+my $command;
+my ( $speed, $step );
+my ( $xcoord, $ycoord );
+my ( $panspeed, $tiltspeed );
+my ( $panstep, $tiltstep );
+my $preset;
+
+if ( !GetOptions(
+	'device=s'=>\$device,
+	'address=i'=>\$address,
+	'command=s'=>\$command,
+	'speed=i'=>\$speed,
+	'step=i'=>\$step,
+	'xcoord=i'=>\$xcoord,
+	'ycoord=i'=>\$ycoord,
+	'panspeed=i'=>\$panspeed,
+	'tiltspeed=i'=>\$tiltspeed,
+	'panstep=i'=>\$panstep,
+	'tiltstep=i'=>\$tiltstep,
+	'preset=i'=>\$preset
+	)
+)
+{
+	Usage();
+}
+
+my $log_file = LOG_FILE;
+open( LOG, ">>$log_file" ) or die( "Can't open log file: $!" );
+open( STDOUT, ">&LOG" ) || die( "Can't dup stdout: $!" );
+select( STDOUT ); $| = 1;
+open( STDERR, ">&LOG" ) || die( "Can't dup stderr: $!" );
+select( STDERR ); $| = 1;
+select( LOG ); $| = 1;
+
+print( $arg_string."\n" );
+
+srand( time() );
+
+my $serial_port = new Device::SerialPort( $device );
+$serial_port->baudrate(9600);
+$serial_port->databits(8);
+$serial_port->parity('none');
+$serial_port->stopbits(1);
+$serial_port->handshake('rts');
+$serial_port->stty_echo(0);
+ 
+#$serial_port->read_const_time(250);
+$serial_port->read_char_time(2);
+
+sub printMsg
+{
+	my $msg = shift;
+	my $prefix = shift || "";
+	$prefix = $prefix.": " if ( $prefix );
+
+	my $line_length = 16;
+	my $msg_len = int(@$msg);
+
+	print( $prefix );
+	for ( my $i = 0; $i < $msg_len; $i++ )
+	{
+		if ( ($i > 0) && ($i%$line_length == 0) && ($i != ($msg_len-1)) )
+		{
+			printf( "\n%*s", length($prefix), "" );
+		}
+		printf( "%02x ", $msg->[$i] );
+	}
+	print( "[".$msg_len."]\n" );
+}
+
+sub sendCmd
+{
+	my $cmd = shift;
+	my $ack = shift || 0;
+	my $cmp = shift || 0;
+
+	my $result = undef;
+
+	printMsg( $cmd, "Tx" );
+	my $id = $cmd->[0] & 0xf;
+
+	my $tx_msg = pack( "C*", @$cmd );
+
+	#print( "Tx: ".length( $tx_msg )." bytes\n" );
+	my $n_bytes = $serial_port->write( $tx_msg );
+	if ( !$n_bytes )
+	{
+		print( "Error, write failed: $!" );
+	}
+	if ( $n_bytes != length($tx_msg) )
+	{
+		print( "Error, incomplete write, only ".$n_bytes." of ".length($tx_msg)." written: $!" );
+	}
+
+	if ( $ack )
+	{
+		print( "Waiting for ack\n" );
+		my $max_wait = 3;
+		my $now = time();
+		while( 1 )
+		{
+			my ( $count, $rx_msg ) = $serial_port->read(4);
+
+			if ( $count )
+			{
+				#print( "Rx1: ".$count." bytes\n" );
+				my @resp = unpack( "C*", $rx_msg );
+				printMsg( \@resp, "Rx" );
+
+				if ( $resp[0] = 0x80 + ($id<<4) )
+				{
+					if ( ($resp[1] & 0xf0) == 0x40 )
+					{
+						my $socket = $resp[1] & 0x0f;
+						print( "Got ack for socket $socket\n" );
+						$result = !undef;
+					}
+					else
+					{
+						printf( "Error, got bogus response\n" );
+					}
+					last;
+				}
+				else
+				{
+					print( "Error, got message for camera ".(($resp[0]-0x80)>>4)."\n" );
+				}
+			}
+			if ( (time() - $now) > $max_wait )
+			{
+				last;
+			}
+		}
+	}
+
+	if ( $cmp )
+	{
+		print( "Waiting for command complete\n" );
+		my $max_wait = 10;
+		my $now = time();
+		while( 1 )
+		{
+			#print( "Waiting\n" );
+			my ( $count, $rx_msg ) = $serial_port->read(16);
+
+			if ( $count )
+			{
+				#print( "Rx1: ".$count." bytes\n" );
+				my @resp = unpack( "C*", $rx_msg );
+				printMsg( \@resp, "Rx" );
+
+				if ( $resp[0] = 0x80 + ($id<<4) )
+				{
+					if ( ($resp[1] & 0xf0) == 0x50 )
+					{
+						printf( "Got command complete\n" );
+						$result = !undef;
+					}
+					else
+					{
+						printf( "Error, got bogus response\n" );
+					}
+					last;
+				}
+				else
+				{
+					print( "Error, got message for camera ".(($resp[0]-0x80)>>4)."\n" );
+				}
+			}
+			if ( (time() - $now) > $max_wait )
+			{
+				last;
+			}
+		}
+	}
+	return( $result );
+}
+
+my $sync = 0xff;
+
+sub cameraOff
+{
+	print( "Camera Off\n" );
+	my @msg = ( 0x80|$address, 0x01, 0x04, 0x00, 0x03, $sync );
+	sendCmd( \@msg );
+}
+
+sub cameraOn
+{
+	print( "Camera On\n" );
+	my @msg = ( 0x80|$address, 0x01, 0x04, 0x00, 0x02, $sync );
+	sendCmd( \@msg );
+}
+
+sub stop
+{
+	print( "Stop\n" );
+	my @msg = ( 0x80|$address, 0x01, 0x06, 0x01, 0x00, 0x00, 0x03, 0x03, $sync );
+	sendCmd( \@msg );
+}
+
+sub moveUp
+{
+	print( "Move Up\n" );
+	my $speed = shift || 0x40;
+	my @msg = ( 0x80|$address, 0x01, 0x06, 0x01, 0x00, $speed, 0x03, 0x01, $sync );
+	sendCmd( \@msg );
+}
+
+sub moveDown
+{
+	print( "Move Down\n" );
+	my $speed = shift || 0x40;
+	my @msg = ( 0x80|$address, 0x01, 0x06, 0x01, 0x00, $speed, 0x03, 0x02, $sync );
+	sendCmd( \@msg );
+}
+
+sub moveLeft
+{
+	print( "Move Left\n" );
+	my $speed = shift || 0x40;
+	my @msg = ( 0x80|$address, 0x01, 0x06, 0x01, $speed, 0x00, 0x01, 0x03, $sync );
+	sendCmd( \@msg );
+}
+
+sub moveRight
+{
+	print( "Move Right\n" );
+	my $speed = shift || 0x40;
+	my @msg = ( 0x80|$address, 0x01, 0x06, 0x01, $speed, 0x00, 0x02, 0x03, $sync );
+	sendCmd( \@msg );
+}
+
+sub moveUpLeft
+{
+	print( "Move Up/Left\n" );
+	my $panspeed = shift || 0x40;
+	my $tiltspeed = shift || 0x40;
+	my @msg = ( 0x80|$address, 0x01, 0x06, 0x01, $panspeed, $tiltspeed, 0x01, 0x01, $sync );
+	sendCmd( \@msg );
+}
+
+sub moveUpRight
+{
+	print( "Move Up/Right\n" );
+	my $panspeed = shift || 0x40;
+	my $tiltspeed = shift || 0x40;
+	my @msg = ( 0x80|$address, 0x01, 0x06, 0x01, $panspeed, $tiltspeed, 0x02, 0x01, $sync );
+	sendCmd( \@msg );
+}
+
+sub moveDownLeft
+{
+	print( "Move Down/Left\n" );
+	my $panspeed = shift || 0x40;
+	my $tiltspeed = shift || 0x40;
+	my @msg = ( 0x80|$address, 0x01, 0x06, 0x01, $panspeed, $tiltspeed, 0x01, 0x02, $sync );
+	sendCmd( \@msg );
+}
+
+sub moveDownRight
+{
+	print( "Move Down/Right\n" );
+	my $panspeed = shift || 0x40;
+	my $tiltspeed = shift || 0x40;
+	my @msg = ( 0x80|$address, 0x01, 0x06, 0x01, $panspeed, $tiltspeed, 0x02, 0x02, $sync );
+	sendCmd( \@msg );
+}
+
+sub stepUp
+{
+	print( "Step Up\n" );
+	my $step = shift;
+	my $speed = shift || 0x40;
+	my @msg = ( 0x80|$address, 0x01, 0x06, 0x03, 0x00, $speed, 0x00, 0x00, 0x00, 0x00, ($step&0xf000)>>12, ($step&0x0f00)>>8, ($step&0x00f0)>>4, ($step&0x000f)>>0, $sync );
+
+	sendCmd( \@msg );
+}
+
+sub stepDown
+{
+	print( "Step Down\n" );
+	my $step = shift;
+	$step = -$step;
+	my $speed = shift || 0x40;
+	my @msg = ( 0x80|$address, 0x01, 0x06, 0x03, 0x00, $speed, 0x00, 0x00, 0x00, 0x00, ($step&0xf000)>>12, ($step&0x0f00)>>8, ($step&0x00f0)>>4, ($step&0x000f)>>0, $sync );
+	sendCmd( \@msg );
+}
+
+sub stepLeft
+{
+	print( "Step Left\n" );
+	my $step = shift;
+	$step = -$step;
+	my $speed = shift || 0x40;
+	my @msg = ( 0x80|$address, 0x01, 0x06, 0x03, $speed, 0x00, ($step&0xf000)>>12, ($step&0x0f00)>>8, ($step&0x00f0)>>4, ($step&0x000f)>>0, 0x00, 0x00, 0x00, 0x00, $sync );
+	sendCmd( \@msg );
+}
+
+sub stepRight
+{
+	print( "Step Right\n" );
+	my $step = shift;
+	my $speed = shift || 0x40;
+	my @msg = ( 0x80|$address, 0x01, 0x06, 0x03, $speed, 0x00, ($step&0xf000)>>12, ($step&0x0f00)>>8, ($step&0x00f0)>>4, ($step&0x000f)>>0, 0x00, 0x00, 0x00, 0x00, $sync );
+	sendCmd( \@msg );
+}
+
+sub stepUpLeft
+{
+	print( "Step Up/Left\n" );
+	my $panstep = shift;
+	$panstep = -$panstep;
+	my $tiltstep = shift;
+	my $panspeed = shift || 0x40;
+	my $tiltspeed = shift || 0x40;
+	my @msg = ( 0x80|$address, 0x01, 0x06, 0x03, $panspeed, $tiltspeed, ($panstep&0xf000)>>12, ($panstep&0x0f00)>>8, ($panstep&0x00f0)>>4, ($panstep&0x000f)>>0, ($tiltstep&0xf000)>>12, ($tiltstep&0x0f00)>>8, ($tiltstep&0x00f0)>>4, ($tiltstep&0x000f)>>0, $sync );
+	sendCmd( \@msg );
+}
+
+sub stepUpRight
+{
+	print( "Step Up/Right\n" );
+	my $panstep = shift;
+	my $tiltstep = shift;
+	my $panspeed = shift || 0x40;
+	my $tiltspeed = shift || 0x40;
+	my @msg = ( 0x80|$address, 0x01, 0x06, 0x03, $panspeed, $tiltspeed, ($panstep&0xf000)>>12, ($panstep&0x0f00)>>8, ($panstep&0x00f0)>>4, ($panstep&0x000f)>>0, ($tiltstep&0xf000)>>12, ($tiltstep&0x0f00)>>8, ($tiltstep&0x00f0)>>4, ($tiltstep&0x000f)>>0, $sync );
+	sendCmd( \@msg );
+}
+
+sub stepDownLeft
+{
+	print( "Step Down/Left\n" );
+	my $panstep = shift;
+	$panstep = -$panstep;
+	my $tiltstep = shift;
+	$tiltstep = -$tiltstep;
+	my $panspeed = shift || 0x40;
+	my $tiltspeed = shift || 0x40;
+	my @msg = ( 0x80|$address, 0x01, 0x06, 0x03, $panspeed, $tiltspeed, ($panstep&0xf000)>>12, ($panstep&0x0f00)>>8, ($panstep&0x00f0)>>4, ($panstep&0x000f)>>0, ($tiltstep&0xf000)>>12, ($tiltstep&0x0f00)>>8, ($tiltstep&0x00f0)>>4, ($tiltstep&0x000f)>>0, $sync );
+	sendCmd( \@msg );
+}
+
+sub stepDownRight
+{
+	print( "Step Down/Right\n" );
+	my $panstep = shift;
+	my $tiltstep = shift;
+	$tiltstep = -$tiltstep;
+	my $panspeed = shift || 0x40;
+	my $tiltspeed = shift || 0x40;
+	my @msg = ( 0x80|$address, 0x01, 0x06, 0x03, $panspeed, $tiltspeed, ($panstep&0xf000)>>12, ($panstep&0x0f00)>>8, ($panstep&0x00f0)>>4, ($panstep&0x000f)>>0, ($tiltstep&0xf000)>>12, ($tiltstep&0x0f00)>>8, ($tiltstep&0x00f0)>>4, ($tiltstep&0x000f)>>0, $sync );
+	sendCmd( \@msg );
+}
+
+sub zoomTele
+{
+	print( "Zoom Tele\n" );
+	my $speed = shift || 0x06;
+	my @msg = ( 0x80|$address, 0x01, 0x04, 0x07, 0x20|$speed, $sync );
+	sendCmd( \@msg );
+}
+
+sub zoomWide
+{
+	print( "Zoom Wide\n" );
+	my $speed = shift || 0x06;
+	my @msg = ( 0x80|$address, 0x01, 0x04, 0x07, 0x30|$speed, $sync );
+	sendCmd( \@msg );
+}
+
+sub zoomStop
+{
+	print( "Zoom Stop\n" );
+	my $speed = shift || 0x06;
+	my @msg = ( 0x80|$address, 0x01, 0x04, 0x07, 0x00, $sync );
+	sendCmd( \@msg );
+}
+
+sub focusNear
+{
+	print( "Focus Near\n" );
+	my @msg = ( 0x80|$address, 0x01, 0x04, 0x08, 0x03, $sync );
+	sendCmd( \@msg );
+}
+
+sub focusFar
+{
+	print( "Focus Far\n" );
+	my @msg = ( 0x80|$address, 0x01, 0x04, 0x08, 0x02, $sync );
+	sendCmd( \@msg );
+}
+
+sub focusStop
+{
+	print( "Focus Far\n" );
+	my @msg = ( 0x80|$address, 0x01, 0x04, 0x08, 0x00, $sync );
+	sendCmd( \@msg );
+}
+
+sub focusAuto
+{
+	print( "Focus Auto\n" );
+	my @msg = ( 0x80|$address, 0x01, 0x04, 0x38, 0x02, $sync );
+	sendCmd( \@msg );
+}
+
+sub focusMan
+{
+	print( "Focus Man\n" );
+	my @msg = ( 0x80|$address, 0x01, 0x04, 0x38, 0x03, $sync );
+	sendCmd( \@msg );
+}
+
+sub presetClear
+{
+	my $preset = shift || 1;
+	print( "Clear Preset $preset\n" );
+	my @msg = ( 0x80|$address, 0x01, 0x04, 0x3f, 0x00, $preset, $sync );
+	sendCmd( \@msg );
+}
+
+sub presetSet
+{
+	my $preset = shift || 1;
+	print( "Set Preset $preset\n" );
+	my @msg = ( 0x80|$address, 0x01, 0x04, 0x3f, 0x01, $preset, $sync );
+	sendCmd( \@msg );
+}
+
+sub presetGoto
+{
+	my $preset = shift || 1;
+	print( "Goto Preset $preset\n" );
+	my @msg = ( 0x80|$address, 0x01, 0x04, 0x3f, 0x02, $preset, $sync );
+	sendCmd( \@msg );
+}
+
+sub presetHome
+{
+	print( "Home Preset\n" );
+	my @msg = ( 0x80|$address, 0x01, 0x06, 0x04, $sync );
+	sendCmd( \@msg );
+}
+
+if ( $command eq "move_con_up" )
+{
+	moveUp( $tiltspeed );
+}
+elsif ( $command eq "move_con_down" )
+{
+	moveDown( $tiltspeed );
+}
+elsif ( $command eq "move_con_left" )
+{
+	moveLeft( $panspeed );
+}
+elsif ( $command eq "move_con_right" )
+{
+	moveRight( $panspeed );
+}
+elsif ( $command eq "move_con_upleft" )
+{
+	moveUpLeft( $panspeed, $tiltspeed );
+}
+elsif ( $command eq "move_con_upright" )
+{
+	moveUpRight( $panspeed, $tiltspeed );
+}
+elsif ( $command eq "move_con_downleft" )
+{
+	moveDownLeft( $panspeed, $tiltspeed );
+}
+elsif ( $command eq "move_con_downright" )
+{
+	moveDownLeft( $panspeed, $tiltspeed );
+}
+elsif ( $command eq "move_stop" )
+{
+	stop();
+}
+elsif ( $command eq "move_rel_up" )
+{
+	stepUp( $tiltstep, $tiltspeed );
+}
+elsif ( $command eq "move_rel_down" )
+{
+	stepDown( $tiltstep, $tiltspeed );
+}
+elsif ( $command eq "move_rel_left" )
+{
+	stepLeft( $panstep, $panspeed );
+}
+elsif ( $command eq "move_rel_right" )
+{
+	stepRight( $panstep, $panspeed );
+}
+elsif ( $command eq "move_rel_upleft" )
+{
+	stepUpLeft( $panstep, $tiltstep, $panspeed, $tiltspeed );
+}
+elsif ( $command eq "move_rel_upright" )
+{
+	stepUpRight( $panstep, $tiltstep, $panspeed, $tiltspeed );
+}
+elsif ( $command eq "move_rel_downleft" )
+{
+	stepDownLeft( $panstep, $tiltstep, $panspeed, $tiltspeed );
+}
+elsif ( $command eq "move_rel_downright" )
+{
+	stepDownRight( $panstep, $tiltstep, $panspeed, $tiltspeed );
+}
+elsif ( $command eq "zoom_con_tele" )
+{
+	zoomTele( $speed );
+}
+elsif ( $command eq "zoom_con_wide" )
+{
+	zoomWide( $speed );
+}
+elsif ( $command eq "zoom_stop" )
+{
+	zoomStop();
+}
+elsif ( $command eq "focus_con_near" )
+{
+	focusNear();
+}
+elsif ( $command eq "focus_con_far" )
+{
+	focusFar();
+}
+elsif ( $command eq "focus_stop" )
+{
+	focusStop();
+}
+elsif ( $command eq "focus_auto" )
+{
+	focusAuto();
+}
+elsif ( $command eq "focus_man" )
+{
+	focusMan();
+}
+elsif ( $command eq "preset_home" )
+{
+	presetHome();
+}
+elsif ( $command eq "preset_set" )
+{
+	presetSet( $preset );
+}
+elsif ( $command eq "preset_goto" )
+{
+	presetGoto( $preset );
+}
+else
+{
+	print( "Error, can't handle command $command\n" );
+}
+
+$serial_port->close();
--- zm-1.21.3.orig/scripts/zmpkg.pl
+++ zm-1.21.3/scripts/zmpkg.pl
@@ -0,0 +1,310 @@
+#!/usr/bin/perl -wT
+#
+# ==========================================================================
+#
+# ZoneMinder Package Control Script, $Date: 2005/02/24 14:39:58 $, $Revision: 1.33 $
+# Copyright (C) 2003, 2004, 2005  Philip Coombes
+#
+# 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.
+#
+# ==========================================================================
+#
+# This script is used to start and stop the ZoneMinder package primarily to
+# allow command line control for automatic restart on reboot (see zm script)
+#
+use strict;
+use bytes;
+
+# ==========================================================================
+#
+# These are the elements you need to edit to suit your installation
+#
+# ==========================================================================
+use constant ZM_CONFIG => "/etc/zm/zm.conf";	# Path to the ZoneMinder config file, autogenerated do not change (from zmconfig)
+use constant ZM_PATH_BIN => "/usr/bin";	# Path to the ZoneMinder executables, autogenerated do not change (from zmconfig)
+use constant ZM_PATH_WEB => "/var/www/zm";	# Path to the ZoneMinder web files, autogenerated do not change (from zmconfig)
+use constant ZM_PATH_CGI => "/usr/lib/cgi-bin";	# Path to the ZoneMinder cgi files, autogenerated do not change (from zmconfig)
+use constant ZM_WEB_USER => "www-data";	# User name of your httpd daemon user, autogenerated do not change (from zmconfig)
+use constant ZM_WEB_GROUP => "www-data";	# User group of your httpd daemon user, autogenerated do not change (from zmconfig)
+
+# Load the config from the database into the symbol table
+BEGIN
+{
+	no strict 'refs';
+
+	open( CONFIG, "<".ZM_CONFIG ) or die( "Can't open config file: $!" );
+	foreach my $str ( <CONFIG> )
+	{
+		next if ( $str =~ /^\s*$/ );
+		next if ( $str =~ /^\s*#/ );
+		my ( $name, $value ) = $str =~ /^\s*([^=\\s]+)\s*=\s*(\S+)\s*$/;
+		$name =~ tr/a-z/A-Z/;
+		if (( $name eq 'ZM_DB_SERVER' ) ||
+			( $name eq 'ZM_DB_NAME' ) ||
+			( $name eq 'ZM_DB_USER' ) ||
+			( $name eq 'ZM_DB_PASS' ))
+		{
+			*{$name} = sub { $value };
+		}
+	}
+	close( CONFIG );
+
+	use DBI;
+	my $dbh = DBI->connect( "DBI:mysql:database=".&ZM_DB_NAME.";host=".&ZM_DB_SERVER, &ZM_DB_USER, &ZM_DB_PASS );
+	my $sql = "select * from Config";
+	my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
+	my $res = $sth->execute() or die( "Can't execute: ".$sth->errstr() );
+	while( my $config = $sth->fetchrow_hashref() )
+	{
+		*{$config->{Name}} = sub { $config->{Value} };
+	}
+	$sth->finish();
+	$dbh->disconnect();
+}
+
+use constant LOG_FILE => ZM_PATH_LOGS.'/zmpkg.log';
+use constant VERBOSE => 0; # Whether to output more verbose debug
+
+# ==========================================================================
+#
+# Don't change anything below here
+#
+# ==========================================================================
+use DBI;
+
+# Detaint our environment
+$ENV{PATH}  = '/bin:/usr/bin';
+$ENV{SHELL} = '/bin/sh' if exists $ENV{SHELL};
+delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};
+
+my $command = $ARGV[0];
+
+my $state;
+
+my $dbh = DBI->connect( "DBI:mysql:database=".ZM_DB_NAME.";host=".ZM_DB_SERVER, ZM_DB_USER, ZM_DB_PASS );
+
+if ( !$command || $command !~ /^(?:start|stop|restart|status)$/ )
+{
+	if ( $command )
+	{
+		# Check to see if it's a valid run state
+		my $sql = "select * from States where Name = '$command'";
+		my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
+		my $res = $sth->execute() or die( "Can't execute: ".$sth->errstr() );
+		if ( $state = $sth->fetchrow_hashref() )
+		{
+			$state->{Name} = $command;
+			$state->{Definitions} = [];
+			foreach( split( ',', $state->{Definition} ) )
+			{
+				my ( $id, $function ) = split( ':', $_ );
+				push( @{$state->{Definitions}}, { Id=>$id, Function=>$function } );
+			}
+			$command = 'state';
+		}
+		else
+		{
+			$command = undef;
+		}
+	}
+	if ( !$command )
+	{
+		print( "Usage: zmpkg.pl <start|stop|restart|status|'state'>\n" );
+		exit( -1 );
+	}
+}
+
+sub remove_shm
+{
+	print( STDERR "Removing shared memory\n" );
+	# Find ZoneMinder shared memory
+	my $command = "ipcs -m | grep '^".substr( sprintf( "0x%x", hex(ZM_SHM_KEY) ), 0, -2 )."'";
+	print( "Checking for shared memory with '$command'\n" ) if ( VERBOSE );
+	open( CMD, "$command |" ) or die( "Can't execute '$command': $!" );
+	while( <CMD> )
+	{
+		chomp;
+		my ( $key, $id ) = split( /\s+/ );
+		if ( $id =~ /^(\d+)/ )
+		{
+			$id = $1;
+			my $command = "ipcrm shm $id";
+			print( "Removing shared memory with '$command'\n" ) if ( VERBOSE );
+			qx( $command );
+		}
+	}
+	close( CMD );
+}
+
+sub execute
+{
+	my $command = shift;
+	my ( $name ) = getpwuid( $> );
+	if ( $name ne ZM_WEB_USER )
+	{
+		$command = "su ".ZM_WEB_USER." --shell=/bin/sh --command='$command'";
+	}
+	print( STDERR "Executing: $command\n" );
+	return( qx( $command ) );
+}
+
+# Move to the right place
+chdir( ZM_PATH_WEB ) or die( "Can't chdir to '".ZM_PATH_WEB."': $!" );
+
+my $log_file = LOG_FILE;
+open( LOG, ">>$log_file" ) or die( "Can't open log file: $!" );
+#open( STDOUT, ">&LOG" ) || die( "Can't dup stdout: $!" );
+#select( STDOUT ); $| = 1;
+open( STDERR, ">&LOG" ) || die( "Can't dup stderr: $!" );
+select( STDERR ); $| = 1;
+select( LOG ); $| = 1;
+
+print( STDERR "Command: $command\n" );
+
+my $web_uid = (getpwnam( ZM_WEB_USER ))[2];
+my $web_gid = (getgrnam( ZM_WEB_GROUP ))[2];
+if ( $> != $web_uid )
+{
+	chown( $web_uid, $web_gid, $log_file ) or die( "Can't change permissions on log file: $!" )
+}
+
+my $retval = 0;
+
+if ( $command eq "state" )
+{
+	print( STDERR "Updating DB: $state->{Name}\n" );
+	my $sql = "select * from Monitors order by Id asc";
+	my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
+	my $res = $sth->execute() or die( "Can't execute: ".$sth->errstr() );
+	while( my $monitor = $sth->fetchrow_hashref() )
+	{
+		foreach my $definition ( @{$state->{Definitions}} )
+		{
+			if ( $monitor->{Id} =~ /^$definition->{Id}$/ )
+			{
+				$monitor->{NewFunction} = $definition->{Function};
+			}
+		}
+		#next if ( !$monitor->{NewFunction} );
+		$monitor->{NewFunction} = 'None' if ( !$monitor->{NewFunction} );
+		if ( $monitor->{Function} ne $monitor->{NewFunction} )
+		{
+			my $sql = "update Monitors set Function = ? where Id = ?";
+			my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
+			my $res = $sth->execute( $monitor->{NewFunction}, $monitor->{Id} ) or die( "Can't execute: ".$sth->errstr() );
+		}
+	}
+	$sth->finish();
+
+	$command = "restart";
+}
+
+if ( $command =~ /^(?:stop|restart)$/ )
+{
+	my $status = execute( ZM_PATH_BIN."/zmdc.pl check" );
+	chomp( $status );
+
+	if ( $status eq "running" )
+	{
+		execute( ZM_PATH_BIN."/zmdc.pl shutdown" );
+		remove_shm();
+	}
+	else
+	{
+		$retval = 1;
+	}
+}
+
+if ( $command =~ /^(?:start|restart)$/ )
+{
+	my $status = execute( ZM_PATH_BIN."/zmdc.pl check" );
+	chomp( $status );
+
+	if ( $status eq "stopped" )
+	{
+		remove_shm();
+		execute( ZM_PATH_BIN."/zmfix" );
+		execute( ZM_PATH_BIN."/zmdc.pl status" );
+
+		my $sql = "select * from Monitors";
+		my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
+		my $res = $sth->execute() or die( "Can't execute: ".$sth->errstr() );
+		while( my $monitor = $sth->fetchrow_hashref() )
+		{
+			if ( $monitor->{Function} ne 'None' )
+			{
+				if ( $monitor->{Type} eq 'Local' )
+				{
+					execute( ZM_PATH_BIN."/zmdc.pl start zmc -d $monitor->{Device}" );
+				}
+				else
+				{
+					execute( ZM_PATH_BIN."/zmdc.pl start zmc -m $monitor->{Id}" );
+				}
+				if ( $monitor->{Function} ne 'Monitor' )
+				{
+					if ( ZM_OPT_FRAME_SERVER )
+					{
+						execute( ZM_PATH_BIN."/zmdc.pl start zmf -m $monitor->{Id}" );
+					}
+					execute( ZM_PATH_BIN."/zmdc.pl start zma -m $monitor->{Id}" );
+				}
+				if ( ZM_OPT_CONTROL )
+				{
+					if ( $monitor->{Function} eq 'Modect' || $monitor->{Function} eq 'Mocord' )
+					{
+						if ( $monitor->{Controllable} && $monitor->{TrackMotion} )
+						{
+							execute( ZM_PATH_BIN."/zmdc.pl start zmtrack.pl -m $monitor->{Id}" );
+						}
+					}
+				}
+			}
+		}
+		$sth->finish();
+
+		# This is now started unconditionally
+		execute( ZM_PATH_BIN."/zmdc.pl start zmfilter.pl" );
+		execute( ZM_PATH_BIN."/zmdc.pl start zmaudit.pl -d 900 -y" );
+
+		if ( ZM_OPT_TRIGGERS )
+		{
+			execute( ZM_PATH_BIN."/zmdc.pl start zmtrigger.pl" );
+		}
+		if ( ZM_OPT_X10 )
+		{
+			execute( ZM_PATH_BIN."/zmdc.pl start zmx10.pl -c start" );
+		}
+		execute( ZM_PATH_BIN."/zmdc.pl start zmwatch.pl" );
+		if ( ZM_CHECK_FOR_UPDATES )
+		{
+			execute( ZM_PATH_BIN."/zmdc.pl start zmupdate.pl -c" );
+		}
+	}
+	else
+	{
+		$retval = 1;
+	}
+}
+
+if ( $command eq "status" )
+{
+	my $status = execute( ZM_PATH_BIN."/zmdc.pl check" );
+	chomp( $status );
+
+	print( STDOUT $status."\n" );
+}
+
+exit( $retval );
--- zm-1.21.3.orig/scripts/zmupdate.pl
+++ zm-1.21.3/scripts/zmupdate.pl
@@ -0,0 +1,415 @@
+#!/usr/bin/perl -w
+#
+# ==========================================================================
+#
+# ZoneMinder Update Script, $Date: 2005/06/23 08:39:54 $, $Revision: 1.26 $
+# Copyright (C) 2003, 2004, 2005  Philip Coombes
+#
+# 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.
+#
+# ==========================================================================
+#
+# This script just checks what the most recent release of ZoneMinder is
+# at the the moment. It will eventually be responsible for applying and
+# configuring upgrades etc, including on the fly upgrades.
+#
+use strict;
+use bytes;
+
+# ==========================================================================
+#
+# These are the elements you need to edit to suit your installation
+#
+# ==========================================================================
+
+use constant ZM_CONFIG => "/etc/zm/zm.conf";	# Path to the ZoneMinder config file, autogenerated do not change (from zmconfig)
+use constant ZM_VERSION => "1.21.3";	# ZoneMinder version number, autogenerated do not change (from zmconfig)
+use constant ZM_PATH_BUILD => "/usr/share/doc/zm";	# ZoneMinder build directory , autogenerated do not change (from zmconfig)
+use constant ZM_PATH_BIN => "/usr/bin";	# Path to the ZoneMinder executables, autogenerated do not change (from zmconfig)
+use constant ZM_PATH_WEB => "/var/www/zm";	# Path to the ZoneMinder web files, autogenerated do not change (from zmconfig)
+
+# Load the config from the database into the symbol table
+BEGIN
+{
+	no strict 'refs';
+
+	if ( open( CONFIG, "<".ZM_CONFIG ) )
+	{
+		foreach my $str ( <CONFIG> )
+		{
+			next if ( $str =~ /^\s*$/ );
+			next if ( $str =~ /^\s*#/ );
+			my ( $name, $value ) = $str =~ /^\s*([^=\\s]+)\s*=\s*(\S+)\s*$/;
+			$name =~ tr/a-z/A-Z/;
+			if (( $name eq 'ZM_DB_SERVER' ) ||
+				( $name eq 'ZM_DB_NAME' ) ||
+				( $name eq 'ZM_DB_USER' ) ||
+				( $name eq 'ZM_DB_PASS' ))
+			{
+				*{$name} = sub { $value };
+			}
+		}
+		close( CONFIG );
+	}
+	else
+	{
+		warn( "Can't open config file: $!" );
+	}
+
+	use DBI;
+	my $dbh = DBI->connect( "DBI:mysql:database=".&ZM_DB_NAME.";host=".&ZM_DB_SERVER, &ZM_DB_USER, &ZM_DB_PASS );
+	my $sql = "select * from Config";
+	my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
+	my $res = $sth->execute() or die( "Can't execute: ".$sth->errstr() );
+	while( my $config = $sth->fetchrow_hashref() )
+	{
+		*{$config->{Name}} = sub { $config->{Value} };
+	}
+	$sth->finish();
+	$dbh->disconnect();
+}
+
+use constant UPDATE_LOG_FILE => ZM_PATH_LOGS.'/zmupdate.log';
+use constant CHECK_INTERVAL => (1*24*60*60); # Interval between version checks
+use constant EVENT_PATH => ZM_PATH_WEB.'/'.ZM_DIR_EVENTS;
+use constant VERBOSE => 0; # Whether to output more verbose debug
+
+# ==========================================================================
+#
+# Don't change anything below here
+#
+# ==========================================================================
+
+use POSIX;
+use DBI;
+use Getopt::Long;
+use Data::Dumper;
+
+$| = 1;
+
+$ENV{PATH}  = '/bin:/usr/bin';
+$ENV{SHELL} = '/bin/sh' if exists $ENV{SHELL};
+delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};
+
+my $check = 0;
+my $rename = 0;
+my $zone_fix = 0;
+my $version = '';
+my $db_user = ZM_DB_USER;
+my $db_pass = ZM_DB_PASS;
+sub Usage
+{
+    print( "
+Usage: zmupdate.pl <-c,--check|-r,--rename|-z,--zone-fix|-v<version>,--version=<version> [-u<dbuser> -p<dbpass>]>
+Parameters are :-
+-c, --check                      - Check for updated versions of ZoneMinder
+-r, --rename                     - Rename images from old 'capture-nnn.jpg' format to new 'nnn-capture.jpg' style from v1.17.2
+-z, --zone-fix                   - Update zone percentage sizes from %ge of image to %ge of zone from 1.18.2 onwards
+-v<version>, --version=<version> - Upgrade to the current version from <version>
+-u<dbuser>, --user=<dbuser>      - Alternate DB user with privileges to alter DB
+-p<dbpass>, --pass=<dbpass>      - Password of alternate DB user with privileges to alter DB
+");
+    exit( -1 );
+}
+
+if ( !GetOptions( 'check'=>\$check, 'rename'=>\$rename, 'zone-fix'=>\$zone_fix, 'version=s'=>\$version, 'user:s'=>\$db_user, 'pass:s'=>\$db_pass ) )
+{
+	Usage();
+}
+
+if ( ! ($check || $rename || $zone_fix || $version) )
+{
+	print( STDERR "Please give a valid option\n" );
+	Usage();
+}
+
+if ( ($check + $rename + $zone_fix + ($version?1:0)) > 1 )
+{
+	print( STDERR "Please give only one option\n" );
+	Usage();
+}
+
+if ( $check )
+{
+	open( LOG, '>>'.UPDATE_LOG_FILE ) or die( "Can't open log file: $!" );
+	open( STDOUT, ">&LOG" ) || die( "Can't dup stdout: $!" );
+	select( STDOUT ); $| = 1;
+	open( STDERR, ">&LOG" ) || die( "Can't dup stderr: $!" );
+	select( STDERR ); $| = 1;
+	select( LOG ); $| = 1;
+}
+
+print( "Update agent starting at ".strftime( '%y/%m/%d %H:%M:%S', localtime() )."\n" );
+
+if ( $check && ZM_CHECK_FOR_UPDATES )
+{
+	my $dbh = DBI->connect( "DBI:mysql:database=".ZM_DB_NAME.";host=".ZM_DB_SERVER, ZM_DB_USER, ZM_DB_PASS );
+
+	my $curr_version = ZM_DYN_CURR_VERSION;
+	my $last_version = ZM_DYN_LAST_VERSION;
+	my $last_check = ZM_DYN_LAST_CHECK;
+
+	if ( !$curr_version )
+	{
+		$curr_version = ZM_VERSION;
+
+		my $sql = "update Config set Value = ? where Name = 'ZM_DYN_CURR_VERSION'";
+		my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
+		my $res = $sth->execute( $curr_version ) or die( "Can't execute: ".$sth->errstr() );
+	}
+
+	$dbh->disconnect();
+	while( 1 )
+	{
+		my $now = time();
+		if ( !$last_version || !$last_check || (($now-$last_check) > CHECK_INTERVAL) )
+		{
+			print( "Checking for updates at ".strftime( '%y/%m/%d %H:%M:%S', localtime() )."\n" );
+
+			use LWP::UserAgent;
+			my $ua = LWP::UserAgent->new;
+			$ua->agent( "ZoneMinder Update Agent/".ZM_VERSION );
+
+			my $req = HTTP::Request->new( GET=>'http://www.zoneminder.com/version' );
+			my $res = $ua->request($req);
+
+			if ( $res->is_success )
+			{
+				$last_version = $res->content;
+				chomp($last_version);
+				$last_check = $now;
+
+				print( "Got version: '".$last_version."'\n" );
+
+				my $dbh = DBI->connect( "DBI:mysql:database=".ZM_DB_NAME.";host=".ZM_DB_SERVER, ZM_DB_USER, ZM_DB_PASS );
+
+				my $lv_sql = "update Config set Value = ? where Name = 'ZM_DYN_LAST_VERSION'";
+				my $lv_sth = $dbh->prepare_cached( $lv_sql ) or die( "Can't prepare '$lv_sql': ".$dbh->errstr() );
+				my $lv_res = $lv_sth->execute( $last_version ) or die( "Can't execute: ".$lv_sth->errstr() );
+
+				my $lc_sql = "update Config set Value = ? where Name = 'ZM_DYN_LAST_CHECK'";
+				my $lc_sth = $dbh->prepare_cached( $lc_sql ) or die( "Can't prepare '$lc_sql': ".$dbh->errstr() );
+				my $lc_res = $lc_sth->execute( $last_check ) or die( "Can't execute: ".$lc_sth->errstr() );
+
+				$dbh->disconnect();
+			}
+			else
+			{
+				print( "Error check failed: '".$res->status_line()."'\n" );
+			}
+
+		}
+		sleep( 3600 );
+	}
+}
+if ( $rename )
+{
+	require File::Find;
+
+	chdir( EVENT_PATH );
+
+	sub renameImage
+	{
+		my $file = $_;
+
+		# Ignore directories
+		if ( -d $file )
+		{
+			print( "Checking directory '$file'\n" );
+			return;
+		}
+		if ( $file !~ /(capture|analyse)-(\d+)(\.jpg)/ )
+		{
+			return;
+		}
+		my $new_file = "$2-$1$3";
+
+		print( "Renaming '$file' to '$new_file'\n" );
+		rename( $file, $new_file ) or warn( "Can't rename '$file' to '$new_file'" );
+	}
+
+	File::Find::find( \&renameImage, '.' );
+}
+if ( $zone_fix )
+{
+	require DBI;
+
+	my $dbh = DBI->connect( "DBI:mysql:database=".ZM_DB_NAME.";host=".ZM_DB_SERVER, ZM_DB_USER, ZM_DB_PASS );
+
+	my $sql = "select Z.*, M.Width as MonitorWidth, M.Height as MonitorHeight from Zones as Z inner join Monitors as M on Z.MonitorId = M.Id where Z.Units = 'Percent'";
+	my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
+	my $res = $sth->execute() or die( "Can't execute: ".$sth->errstr() );
+	my @zones;
+	while( my $zone = $sth->fetchrow_hashref() )
+	{
+		push( @zones, $zone );
+	}
+	$sth->finish();
+
+	foreach my $zone ( @zones )
+	{
+		my $zone_width = (($zone->{HiX}*$zone->{MonitorWidth})-($zone->{LoX}*$zone->{MonitorWidth}))/100;
+		my $zone_height = (($zone->{HiY}*$zone->{MonitorHeight})-($zone->{LoY}*$zone->{MonitorHeight}))/100;
+		my $zone_area = $zone_width * $zone_height;
+		my $monitor_area = $zone->{MonitorWidth} * $zone->{MonitorHeight};
+		my $sql = "update Zones set MinAlarmPixels = ?, MaxAlarmPixels = ?, MinFilterPixels = ?, MaxFilterPixels = ?, MinBlobPixels = ?, MaxBlobPixels = ? where Id = ?";
+		my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
+		my $res = $sth->execute(
+			($zone->{MinAlarmPixels}*$monitor_area)/$zone_area,
+			($zone->{MaxAlarmPixels}*$monitor_area)/$zone_area,
+			($zone->{MinFilterPixels}*$monitor_area)/$zone_area,
+			($zone->{MaxFilterPixels}*$monitor_area)/$zone_area,
+			($zone->{MinBlobPixels}*$monitor_area)/$zone_area,
+			($zone->{MaxBlobPixels}*$monitor_area)/$zone_area,
+			$zone->{Id}
+		) or die( "Can't execute: ".$sth->errstr() );
+	}
+}
+if ( $version )
+{
+	sub patchDB
+	{
+		my $dbh = shift;
+		my $version = shift;
+
+		my $command = "mysql -h".ZM_DB_SERVER;
+		if ( $db_user )
+		{
+			$command .= " -u".$db_user;
+			if ( $db_pass )
+			{
+				$command .= " -p".$db_pass;
+			}
+		}
+		$command .= " ".ZM_DB_NAME." < ".ZM_PATH_BUILD."/db/zmalter-".$version.".sql";
+
+		print( "Executing '$command'\n" ) if ( VERBOSE );
+		my $output = qx($command);
+		my $status = $? >> 8;
+		if ( $status || VERBOSE )
+		{
+				chomp( $output );
+				print( "Output: $output\n" );
+		}
+		if ( $status )
+		{
+			die( "Command '$command' exited with status: $status\n" );
+		}
+		else
+		{
+			print( "Database successfully upgraded to version '$version'\n" );
+			my $sql = "update Config set Value = ? where Name = 'ZM_DYN_DB_VERSION'";
+			my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
+			my $res = $sth->execute( $version ) or die( "Can't execute: ".$sth->errstr() );
+		}
+	}
+
+	if ( ZM_DYN_DB_VERSION && ZM_DYN_DB_VERSION ne $version )
+	{
+		# Nothing yet
+	}
+
+	my $dbh = DBI->connect( "DBI:mysql:database=".ZM_DB_NAME.";host=".ZM_DB_SERVER, ZM_DB_USER, ZM_DB_PASS );
+
+	my $cascade = undef;
+	if ( $cascade || $version eq "1.19.0" )
+	{
+		# Patch the database
+		patchDB( $dbh, "1.19.0" );
+		$cascade = !undef;
+	}
+	if ( $cascade || $version eq "1.19.1" )
+	{
+		# Patch the database
+		patchDB( $dbh, "1.19.1");
+		$cascade = !undef;
+	}
+	if ( $cascade || $version eq "1.19.2" )
+	{
+		# Patch the database
+		patchDB( $dbh, "1.19.2" );
+		$cascade = !undef;
+	}
+	if ( $cascade || $version eq "1.19.3" )
+	{
+		# Patch the database
+		patchDB( $dbh, "1.19.3" );
+		$cascade = !undef;
+	}
+	if ( $cascade || $version eq "1.19.4" )
+	{
+		require DBI;
+
+		# Rename the event directories and create a new symlink for the names
+		chdir( EVENT_PATH );
+
+		my $sql = "select * from Monitors order by Id";
+		my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
+		my $res = $sth->execute() or die( "Can't execute: ".$sth->errstr() );
+		while( my $monitor = $sth->fetchrow_hashref() )
+		{
+			if ( -d $monitor->{Name} )
+			{
+				rename( $monitor->{Name}, $monitor->{Id} ) or warn( "Can't rename existing monitor directory '$monitor->{Name}' to '$monitor->{Id}': $!" );
+				symlink( $monitor->{Id}, $monitor->{Name} ) or warn( "Can't symlink monitor directory '$monitor->{Id}' to '$monitor->{Name}': $!" );
+			}
+		}
+		$sth->finish();
+		
+		# Patch the database
+		patchDB( $dbh, "1.19.4" );
+
+		$cascade = !undef;
+	}
+	if ( $cascade || $version eq "1.19.5" )
+	{
+		print( "This version now only uses one database user.\nPlease ensure you have run zmconfig.pl and re-entered your database username and password prior to upgrading, or the upgrade will fail.\nPress enter to continue or ctrl-C to stop :" );
+		# Patch the database
+		my $dummy = <STDIN>;
+		patchDB( $dbh, "1.19.5" );
+		$cascade = !undef;
+	}
+	if ( $cascade || $version eq "1.20.0" )
+	{
+		# Patch the database
+		patchDB( $dbh, "1.20.0" );
+		$cascade = !undef;
+	}
+	if ( $cascade || $version eq "1.20.1" )
+	{
+		# Patch the database
+		patchDB( $dbh, "1.20.1" );
+		$cascade = !undef;
+	}
+	if ( $cascade || $version eq "1.21.0" )
+	{
+		# Patch the database
+		patchDB( $dbh, "1.21.0" );
+		$cascade = !undef;
+	}
+	if ( $cascade || $version eq "1.21.1" )
+	{
+		# Patch the database
+		patchDB( $dbh, "1.21.1" );
+		$cascade = !undef;
+	}
+	if ( !$cascade )
+	{
+		die( "Can't find upgrade from version '$version'" );
+	}
+	$dbh->disconnect();
+}
+print( "Update agent exiting at ".strftime( '%y/%m/%d %H:%M:%S', localtime() )."\n" );
+exit();
--- zm-1.21.3.orig/scripts/zmcontrol-axis-v2.pl
+++ zm-1.21.3/scripts/zmcontrol-axis-v2.pl
@@ -0,0 +1,547 @@
+#!/usr/bin/perl -wT
+#
+# ==========================================================================
+#
+# ZoneMinder Axis HTTP API v2 Control Script, $Date: 2005/07/14 08:53:14 $, $Revision: 1.3 $
+# Copyright (C) 2003, 2004, 2005  Philip Coombes
+#
+# 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.
+#
+# ==========================================================================
+#
+# This script continuously monitors the recorded events for the given
+# monitor and applies any filters which would delete and/or upload 
+# matching events
+#
+use strict;
+
+# ==========================================================================
+#
+# These are the elements you need to edit to suit your installation
+#
+# ==========================================================================
+use constant ZM_CONFIG => "/etc/zm/zm.conf";	# Path to the ZoneMinder config file, autogenerated do not change (from zmconfig)
+use constant ZM_VERSION => "1.21.3";	# ZoneMinder version number, autogenerated do not change (from zmconfig)
+use constant ZM_PATH_BIN => "/usr/bin";	# Path to the ZoneMinder executables, autogenerated do not change (from zmconfig)
+
+# Load the config from the database into the symbol table
+BEGIN
+{
+	no strict 'refs';
+
+	open( CONFIG, "<".ZM_CONFIG ) or die( "Can't open config file: $!" );
+	foreach my $str ( <CONFIG> )
+	{
+		next if ( $str =~ /^\s*$/ );
+		next if ( $str =~ /^\s*#/ );
+		my ( $name, $value ) = $str =~ /^\s*([^=\s]+)\s*=\s*([^=\s]+)\s*$/;
+		$name =~ tr/a-z/A-Z/;
+		if (( $name eq 'ZM_DB_SERVER' ) ||
+			( $name eq 'ZM_DB_NAME' ) ||
+			( $name eq 'ZM_DB_USER' ) ||
+			( $name eq 'ZM_DB_PASS' ))
+		{
+			*{$name} = sub { $value };
+		}
+	}
+	close( CONFIG );
+
+	use DBI;
+	my $dbh = DBI->connect( "DBI:mysql:database=".&ZM_DB_NAME.";host=".&ZM_DB_SERVER, &ZM_DB_USER, &ZM_DB_PASS );
+	my $sql = "select * from Config";
+	my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
+	my $res = $sth->execute() or die( "Can't execute '$sql': ".$sth->errstr() );
+	while( my $config = $sth->fetchrow_hashref() )
+	{
+		*{$config->{Name}} = sub { $config->{Value} };
+	}
+	$sth->finish();
+	$dbh->disconnect();
+}
+
+use Getopt::Long;
+use Device::SerialPort;
+
+use constant LOG_FILE => ZM_PATH_LOGS.'/zmcontrol-axis-v2.log';
+
+$| = 1;
+
+$ENV{PATH}  = '/bin:/usr/bin';
+$ENV{SHELL} = '/bin/sh' if exists $ENV{SHELL};
+delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};
+
+sub Usage
+{
+	print( "
+Usage: zmcontrol-axis-v2.pl <various options>
+");
+	exit( -1 );
+}
+
+my $arg_string = join( " ", @ARGV );
+
+my $address;
+my $command;
+my ( $speed, $step );
+my ( $xcoord, $ycoord );
+my ( $width, $height );
+my ( $panspeed, $tiltspeed );
+my ( $panstep, $tiltstep );
+my $preset;
+
+if ( !GetOptions(
+	'address=s'=>\$address,
+	'command=s'=>\$command,
+	'speed=i'=>\$speed,
+	'step=i'=>\$step,
+	'xcoord=i'=>\$xcoord,
+	'ycoord=i'=>\$ycoord,
+	'width=i'=>\$width,
+	'height=i'=>\$height,
+	'panspeed=i'=>\$panspeed,
+	'tiltspeed=i'=>\$tiltspeed,
+	'panstep=i'=>\$panstep,
+	'tiltstep=i'=>\$tiltstep,
+	'preset=i'=>\$preset
+	)
+)
+{
+	Usage();
+}
+
+if ( !$address )
+{
+	Usage();
+}
+
+my $log_file = LOG_FILE;
+open( LOG, ">>$log_file" ) or die( "Can't open log file: $!" );
+open( STDOUT, ">&LOG" ) || die( "Can't dup stdout: $!" );
+select( STDOUT ); $| = 1;
+open( STDERR, ">&LOG" ) || die( "Can't dup stderr: $!" );
+select( STDERR ); $| = 1;
+select( LOG ); $| = 1;
+
+print( $arg_string."\n" );
+
+srand( time() );
+
+sub printMsg
+{
+	my $msg = shift;
+	my $msg_len = length($msg);
+
+	print( $msg );
+	print( "[".$msg_len."]\n" );
+}
+
+sub sendCmd
+{
+	my $cmd = shift;
+
+	my $result = undef;
+
+	printMsg( $cmd, "Tx" );
+
+	use LWP::UserAgent;
+	my $ua = LWP::UserAgent->new;
+	$ua->agent( "ZoneMinder Control Agent/".ZM_VERSION );
+
+	#print( "http://$address/$cmd\n" );
+	my $req = HTTP::Request->new( GET=>"http://$address$cmd" );
+	my $res = $ua->request($req);
+
+	if ( $res->is_success )
+	{
+		$result = !undef;
+	}
+	else
+	{
+		print( "Error check failed: '".$res->status_line()."'\n" );
+	}
+
+	return( $result );
+}
+
+sub cameraReset
+{
+	print( "Camera Reset\n" );
+	my $cmd = "nphRestart?PAGE=Restart&Restart=OK";
+	sendCmd( $cmd );
+}
+
+sub moveUp
+{
+	print( "Move Up\n" );
+	my $cmd = "/axis-cgi/com/ptz.cgi?move=up";
+	sendCmd( $cmd );
+}
+
+sub moveDown
+{
+	print( "Move Down\n" );
+	my $cmd = "/axis-cgi/com/ptz.cgi?move=down";
+	sendCmd( $cmd );
+}
+
+sub moveLeft
+{
+	print( "Move Left\n" );
+	my $cmd = "/axis-cgi/com/ptz.cgi?move=left";
+	sendCmd( $cmd );
+}
+
+sub moveRight
+{
+	print( "Move Right\n" );
+	my $cmd = "/axis-cgi/com/ptz.cgi?move=right";
+	sendCmd( $cmd );
+}
+
+sub moveUpRight
+{
+	print( "Move Up/Right\n" );
+	my $cmd = "/axis-cgi/com/ptz.cgi?move=upright";
+	sendCmd( $cmd );
+}
+
+sub moveUpLeft
+{
+	print( "Move Up/Left\n" );
+	my $cmd = "/axis-cgi/com/ptz.cgi?move=upleft";
+	sendCmd( $cmd );
+}
+
+sub moveDownRight
+{
+	print( "Move Down/Right\n" );
+	my $cmd = "/axis-cgi/com/ptz.cgi?move=downright";
+	sendCmd( $cmd );
+}
+
+sub moveDownLeft
+{
+	print( "Move Down/Left\n" );
+	my $cmd = "/axis-cgi/com/ptz.cgi?move=downleft";
+	sendCmd( $cmd );
+}
+
+sub moveMap
+{
+	my ( $xcoord, $ycoord, $width, $height ) = @_;
+	print( "Move Map to $xcoord,$ycoord\n" );
+	my $cmd = "/axis-cgi/com/ptz.cgi?center=$xcoord,$ycoord&imagewidth=$width&imageheight=$height";
+	sendCmd( $cmd );
+}
+
+sub stepUp
+{
+	my $step = shift;
+	print( "Step Up $step\n" );
+	my $cmd = "/axis-cgi/com/ptz.cgi?rtilt=$step";
+	sendCmd( $cmd );
+}
+
+sub stepDown
+{
+	my $step = shift;
+	print( "Step Down $step\n" );
+	my $cmd = "/axis-cgi/com/ptz.cgi?rtilt=-$step";
+	sendCmd( $cmd );
+}
+
+sub stepLeft
+{
+	my $step = shift;
+	print( "Step Left $step\n" );
+	my $cmd = "/axis-cgi/com/ptz.cgi?rpan=-$step";
+	sendCmd( $cmd );
+}
+
+sub stepRight
+{
+	my $step = shift;
+	print( "Step Right $step\n" );
+	my $cmd = "/axis-cgi/com/ptz.cgi?rpan=$step";
+	sendCmd( $cmd );
+}
+
+sub stepUpRight
+{
+	my $panstep = shift;
+	my $tiltstep = shift;
+	print( "Step Up/Right $tiltstep/$panstep\n" );
+	my $cmd = "/axis-cgi/com/ptz.cgi?rpan=$panstep&rtilt=$tiltstep";
+	sendCmd( $cmd );
+}
+
+sub stepUpLeft
+{
+	my $panstep = shift;
+	my $tiltstep = shift;
+	print( "Step Up/Left $tiltstep/$panstep\n" );
+	my $cmd = "/axis-cgi/com/ptz.cgi?rpan=-$panstep&rtilt=$tiltstep";
+	sendCmd( $cmd );
+}
+
+sub stepDownRight
+{
+	my $panstep = shift;
+	my $tiltstep = shift;
+	print( "Step Down/Right $tiltstep/$panstep\n" );
+	my $cmd = "/axis-cgi/com/ptz.cgi?rpan=$panstep&rtilt=-$tiltstep";
+	sendCmd( $cmd );
+}
+
+sub stepDownLeft
+{
+	my $panstep = shift;
+	my $tiltstep = shift;
+	print( "Step Down/Left $tiltstep/$panstep\n" );
+	my $cmd = "/axis-cgi/com/ptz.cgi?rpan=-$panstep&rtilt=-$tiltstep";
+	sendCmd( $cmd );
+}
+
+sub zoomTele
+{
+	my $step = shift;
+	print( "Zoom Tele\n" );
+	my $cmd = "/axis-cgi/com/ptz.cgi?rzoom=$step";
+	sendCmd( $cmd );
+}
+
+sub zoomWide
+{
+	my $step = shift;
+	print( "Zoom Wide\n" );
+	my $cmd = "/axis-cgi/com/ptz.cgi?rzoom=-$step";
+	sendCmd( $cmd );
+}
+
+sub focusNear
+{
+	my $step = shift;
+	print( "Focus Near\n" );
+	my $cmd = "/axis-cgi/com/ptz.cgi?rfocus=-$step";
+	sendCmd( $cmd );
+}
+
+sub focusFar
+{
+	my $step = shift;
+	print( "Focus Far\n" );
+	my $cmd = "/axis-cgi/com/ptz.cgi?rfocus=$step";
+	sendCmd( $cmd );
+}
+
+sub focusAuto
+{
+	print( "Focus Auto\n" );
+	my $cmd = "/axis-cgi/com/ptz.cgi?autofocus=on";
+	sendCmd( $cmd );
+}
+
+sub focusMan
+{
+	print( "Focus Manual\n" );
+	my $cmd = "/axis-cgi/com/ptz.cgi?autofocus=off";
+	sendCmd( $cmd );
+}
+
+sub irisOpen
+{
+	my $step = shift;
+	print( "Iris Open\n" );
+	my $cmd = "/axis-cgi/com/ptz.cgi?riris=$step";
+	sendCmd( $cmd );
+}
+
+sub irisClose
+{
+	my $step = shift;
+	print( "Iris Close\n" );
+	my $cmd = "/axis-cgi/com/ptz.cgi?riris=-$step";
+	sendCmd( $cmd );
+}
+
+sub irisAuto
+{
+	print( "Iris Auto\n" );
+	my $cmd = "/axis-cgi/com/ptz.cgi?autoiris=on";
+	sendCmd( $cmd );
+}
+
+sub irisMan
+{
+	print( "Iris Manual\n" );
+	my $cmd = "/axis-cgi/com/ptz.cgi?autoiris=off";
+	sendCmd( $cmd );
+}
+
+sub presetClear
+{
+	my $preset = shift || 1;
+	print( "Clear Preset $preset\n" );
+	my $cmd = "nphPresetNameCheck?Data=$preset";
+	sendCmd( $cmd );
+}
+
+sub presetSet
+{
+	my $preset = shift || 1;
+	print( "Set Preset $preset\n" );
+	my $cmd = "/axis-cgi/com/ptz.cgi?setserverpresetno=$preset";
+	sendCmd( $cmd );
+}
+
+sub presetGoto
+{
+	my $preset = shift || 1;
+	print( "Goto Preset $preset\n" );
+	my $cmd = "/axis-cgi/com/ptz.cgi?gotoserverpresetno=$preset";
+	sendCmd( $cmd );
+}
+
+sub presetHome
+{
+	print( "Home Preset\n" );
+	my $cmd = "/axis-cgi/com/ptz.cgi?move=home";
+	sendCmd( $cmd );
+}
+
+if ( $command eq "move_con_up" )
+{
+	moveUp();
+}
+elsif ( $command eq "move_con_down" )
+{
+	moveDown();
+}
+elsif ( $command eq "move_con_left" )
+{
+	moveLeft();
+}
+elsif ( $command eq "move_con_right" )
+{
+	moveRight();
+}
+elsif ( $command eq "move_con_upleft" )
+{
+	moveUpLeft();
+}
+elsif ( $command eq "move_con_upright" )
+{
+	moveUpRight();
+}
+elsif ( $command eq "move_con_downleft" )
+{
+	moveDownLeft();
+}
+elsif ( $command eq "move_con_downright" )
+{
+	moveDownLeft();
+}
+elsif ( $command eq "move_map" )
+{
+	moveMap( $xcoord, $ycoord, $width, $height );
+}
+elsif ( $command eq "move_rel_up" )
+{
+	stepUp( $tiltstep );
+}
+elsif ( $command eq "move_rel_down" )
+{
+	stepDown( $tiltstep );
+}
+elsif ( $command eq "move_rel_left" )
+{
+	stepLeft( $panstep );
+}
+elsif ( $command eq "move_rel_right" )
+{
+	stepRight( $panstep );
+}
+elsif ( $command eq "move_rel_upleft" )
+{
+	stepUpLeft( $panstep, $tiltstep );
+}
+elsif ( $command eq "move_rel_upright" )
+{
+	stepUpRight( $panstep, $tiltstep );
+}
+elsif ( $command eq "move_rel_downleft" )
+{
+	stepDownLeft( $panstep, $tiltstep );
+}
+elsif ( $command eq "move_rel_downright" )
+{
+	stepDownRight( $panstep, $tiltstep );
+}
+elsif ( $command eq "zoom_rel_tele" )
+{
+	zoomTele( $step );
+}
+elsif ( $command eq "zoom_rel_wide" )
+{
+	zoomWide( $step );
+}
+elsif ( $command eq "focus_rel_near" )
+{
+	focusNear( $step );
+}
+elsif ( $command eq "focus_rel_far" )
+{
+	focusFar( $step );
+}
+elsif ( $command eq "focus_auto" )
+{
+	focusAuto();
+}
+elsif ( $command eq "focus_man" )
+{
+	focusMan();
+}
+elsif ( $command eq "iris_rel_open" )
+{
+	irisOpen( $step );
+}
+elsif ( $command eq "iris_rel_close" )
+{
+	irisClose( $step );
+}
+elsif ( $command eq "iris_auto" )
+{
+	irisAuto();
+}
+elsif ( $command eq "iris_man" )
+{
+	irisMan();
+}
+elsif ( $command eq "preset_home" )
+{
+	presetHome();
+}
+elsif ( $command eq "preset_set" )
+{
+	presetSet( $preset );
+}
+elsif ( $command eq "preset_goto" )
+{
+	presetGoto( $preset );
+}
+else
+{
+	print( "Error, can't handle command $command\n" );
+}
--- zm-1.21.3.orig/scripts/zmvideo.pl
+++ zm-1.21.3/scripts/zmvideo.pl
@@ -0,0 +1,284 @@
+#!/usr/bin/perl -wT
+#
+# ==========================================================================
+#
+# ZoneMinder Video Creation Script, $Date: 2005/02/24 14:39:58 $, $Revision: 1.19 $
+# Copyright (C) 2003, 2004, 2005  Philip Coombes
+#
+# 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.
+#
+# ==========================================================================
+#
+# This script is used to create MPEG videos of events for the web pages
+# or as email attachments.
+#
+use strict;
+use bytes;
+
+# ==========================================================================
+#
+# These are the elements you need to edit to suit your installation
+#
+# ==========================================================================
+use constant ZM_CONFIG => "/etc/zm/zm.conf";	# Path to the ZoneMinder config file, autogenerated do not change (from zmconfig)
+use constant ZM_PATH_BIN => "/usr/bin";	# Path to the ZoneMinder executables, autogenerated do not change (from zmconfig)
+use constant ZM_PATH_WEB => "/var/www/zm";	# Path to the ZoneMinder web files, autogenerated do not change (from zmconfig)
+use constant ZM_PATH_CGI => "/usr/lib/cgi-bin";	# Path to the ZoneMinder cgi files, autogenerated do not change (from zmconfig)
+
+# Load the config from the database into the symbol table
+BEGIN
+{
+	no strict 'refs';
+
+	open( CONFIG, "<".ZM_CONFIG ) or die( "Can't open config file: $!" );
+	foreach my $str ( <CONFIG> )
+	{
+		next if ( $str =~ /^\s*$/ );
+		next if ( $str =~ /^\s*#/ );
+		my ( $name, $value ) = $str =~ /^\s*([^=\\s]+)\s*=\s*(\S+)\s*$/;
+		$name =~ tr/a-z/A-Z/;
+		if (( $name eq 'ZM_DB_SERVER' ) ||
+			( $name eq 'ZM_DB_NAME' ) ||
+			( $name eq 'ZM_DB_USER' ) ||
+			( $name eq 'ZM_DB_PASS' ))
+		{
+			*{$name} = sub { $value };
+		}
+	}
+	close( CONFIG );
+
+	use DBI;
+	my $dbh = DBI->connect( "DBI:mysql:database=".&ZM_DB_NAME.";host=".&ZM_DB_SERVER, &ZM_DB_USER, &ZM_DB_PASS );
+	my $sql = "select * from Config";
+	my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
+	my $res = $sth->execute() or die( "Can't execute: ".$sth->errstr() );
+	while( my $config = $sth->fetchrow_hashref() )
+	{
+		*{$config->{Name}} = sub { $config->{Value} };
+	}
+	$sth->finish();
+	$dbh->disconnect();
+}
+
+use constant LOG_FILE => ZM_PATH_LOGS.'/zmvideo.log';
+use constant VERBOSE => 0; # Whether to output more verbose debug
+
+# ==========================================================================
+#
+# You shouldn't need to change anything from here downwards
+#
+# ==========================================================================
+
+use DBI;
+use Data::Dumper;
+use Getopt::Long;
+
+$| = 1;
+
+$ENV{PATH}  = '/bin:/usr/bin';
+$ENV{SHELL} = '/bin/sh' if exists $ENV{SHELL};
+delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};
+
+my $event_id;
+my $rate = 1.0;
+my $scale = 1.0;
+my $overwrite = 0;
+
+sub Usage
+{
+	print( "
+Usage: zmvideo.pl -e <event_id>,--event=<event_id> [-r <rate>,--rate=<rate>] [-s <scale>,--scale=<scale>] [-o,--overwrite]
+Parameters are :-
+-e<event_id>, --event=<event_id>  - What event to create the video for
+-r<rate>, --rate=<rate>           - Relative rate to use, 1 = realtime, 2 = double speed , 0.5 = half speed etc
+-s<scale>, --scale=<scale>        - Scale to use, 1 = normal, 2 = double size, 0.5 = half size etc
+-o, --overwrite                   - Whether to overwrite an existing file, off by default.
+");
+	exit( -1 );
+}
+
+if ( !GetOptions( 'event=i'=>\$event_id, 'rate=f'=>\$rate, 'scale=f'=>\$scale, 'overwrite'=>\$overwrite ) )
+{
+	Usage();
+}
+
+if ( !$event_id || $event_id < 0 )
+{
+	print( STDERR "Please give a valid event id\n" );
+	Usage();
+}
+
+if ( ZM_OPT_MPEG eq "no" )
+{
+	print( STDERR "Mpeg encoding is not currently enabled\n" );
+	exit(-1);
+}
+
+if ( ZM_OPT_MPEG eq "mpeg_encode" && $rate != 1.0 )
+{
+	print( STDERR "Variable rate not supported with mpeg_encode\n" );
+	exit(-1);
+}
+
+if ( $rate < 0.25 || $rate > 100 )
+{
+	print( STDERR "Rate is out of range, 0.25 >= rate <= 100\n" );
+	Usage();
+}
+
+if ( !$scale || $scale < 0.25 || $scale > 4 )
+{
+	print( STDERR "Scale is out of range, 0.25 >= scale <= 4\n" );
+	Usage();
+}
+
+my ( $detaint_rate ) = $rate =~ /^(-?\d+(?:\.\d+)?)$/;
+my ( $detaint_scale ) = $scale =~ /^(-?\d+(?:\.\d+)?)$/;
+
+$rate = $detaint_rate;
+$scale = $detaint_scale;
+
+my $log_file = LOG_FILE;
+open( LOG, ">>$log_file" ) or die( "Can't open log file: $!" );
+#open( STDOUT, ">&LOG" ) || die( "Can't dup stdout: $!" );
+#select( STDOUT ); $| = 1;
+open( STDERR, ">&LOG" ) || die( "Can't dup stderr: $!" );
+select( STDERR ); $| = 1;
+select( LOG ); $| = 1;
+
+my $dbh = DBI->connect( "DBI:mysql:database=".ZM_DB_NAME.";host=".ZM_DB_SERVER, ZM_DB_USER, ZM_DB_PASS );
+
+my @filters;
+my $sql = "select max(F.Delta)-min(F.Delta) as FullLength, E.*, M.Name as MonitorName, M.Width as MonitorWidth, M.Height as MonitorHeight, M.Palette from Frames as F inner join Events as E on F.EventId = E.Id inner join Monitors as M on E.MonitorId = M.Id where EventId = '$event_id' group by F.EventId";
+my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
+my $res = $sth->execute() or die( "Can't execute: ".$sth->errstr() );
+my $event = $sth->fetchrow_hashref();
+$sth->finish();
+chdir( ZM_PATH_WEB.'/'.ZM_DIR_EVENTS.'/'.$event->{MonitorId}.'/'.$event->{Id} );
+( my $video_name = $event->{Name} ) =~ s/\s/_/g; 
+my $video_file = "$video_name.mpg";
+
+if ( $overwrite || !-s $video_file )
+{
+	print( LOG "Creating video file $video_file for event $event->{Id}\n" );
+
+	if ( ZM_OPT_MPEG eq "mpeg_encode" )
+	{
+		my $param_file = "$video_name.mpe";
+		open( PARAMS, ">$param_file" ) or die( "Can't open '$param_file': $!" );
+
+		print( PARAMS "PATTERN		IBBPBBPBBPBBPBB\n" );
+		print( PARAMS "FORCE_ENCODE_LAST_FRAME\n" );
+		print( PARAMS "OUTPUT		$video_file\n" );
+
+		print( PARAMS "BASE_FILE_FORMAT	JPEG\n" );
+		print( PARAMS "GOP_SIZE	30\n" );
+		print( PARAMS "SLICES_PER_FRAME	1\n" );
+
+		print( PARAMS "PIXEL		HALF\n" );
+		print( PARAMS "RANGE		10\n" );
+		print( PARAMS "PSEARCH_ALG	LOGARITHMIC\n" );
+		print( PARAMS "BSEARCH_ALG	CROSS2\n" );
+		print( PARAMS "IQSCALE		8\n" );
+		print( PARAMS "PQSCALE		10\n" );
+		print( PARAMS "BQSCALE		25\n" );
+
+		print( PARAMS "REFERENCE_FRAME	ORIGINAL\n" );
+		print( PARAMS "FRAME_RATE 24\n" );
+
+		my $scale_conversion = "";
+		if ( $scale != 1 )
+		{
+			if ( $scale > 1 )
+			{
+				$scale_conversion = ZM_PATH_NETPBM."/pnmscale $scale";
+			}
+			else
+			{
+				$scale_conversion = ZM_PATH_NETPBM."/pnmscale ".(1/$scale);
+			}
+			if ( $event->{Palette} == 1 && !ZM_COLOUR_JPEG_FILES )
+			{
+				print( PARAMS "INPUT_CONVERT	".ZM_PATH_NETPBM."/jpegtopnm * | ".$scale_conversion." | ".ZM_PATH_NETPBM."/pgmtoppm white | ".ZM_PATH_NETPBM."/ppmtojpeg\n" );
+			}
+			else
+			{
+				print( PARAMS "INPUT_CONVERT	".ZM_PATH_NETPBM."/jpegtopnm * | ".$scale_conversion." | ".ZM_PATH_NETPBM."/ppmtojpeg\n" );
+			}
+		}
+		else
+		{
+			if ( $event->{Palette} == 1 && !ZM_COLOUR_JPEG_FILES )
+			{
+				print( PARAMS "INPUT_CONVERT	".ZM_PATH_NETPBM."/jpegtopnm * | ".ZM_PATH_NETPBM."/pgmtoppm white | ".ZM_PATH_NETPBM."/ppmtojpeg\n" );
+			}
+			else
+			{
+				print( PARAMS "INPUT_CONVERT	*\n" );
+			}
+		}
+		print( PARAMS "INPUT_DIR	.\n" );
+
+		print( PARAMS "INPUT\n" );
+		for ( my $i = 1; $i <= $event->{Frames}; $i++ )
+		{
+			printf( PARAMS "%0".ZM_EVENT_IMAGE_DIGITS."d-capture.jpg\n", $i );
+		}
+		print( PARAMS "END_INPUT\n" );
+		close( PARAMS );
+
+		my $command = ZM_PATH_MPEG_ENCODE." $param_file >mpeg.log";
+		print( LOG $command."\n" );
+		my $output = qx($command);
+		print( LOG $output."\n" );
+	}
+	elsif ( ZM_OPT_MPEG eq "ffmpeg" )
+	{
+		my $frame_rate = sprintf( "%.2f", $event->{Frames}/$event->{FullLength} );
+		if ( $rate != 1.0 )
+		{
+			$frame_rate *= $rate;
+		}
+		my $width = $event->{MonitorWidth};
+		my $height = $event->{MonitorHeight};
+		if ( $scale != 1.0 )
+		{
+			$width = int($width*$scale);
+			$height = int($height*$scale);
+		}
+		my $command = ZM_PATH_FFMPEG." -y ".ZM_FFMPEG_OPTIONS." -r $frame_rate -s ${width}x${height} -i %0".ZM_EVENT_IMAGE_DIGITS."d-capture.jpg $video_file > mpeg.log";
+		print( LOG $command."\n" );
+		my $output = qx($command);
+		print( LOG $output."\n" );
+	}
+	else
+	{
+		die( "Bogus mpeg option ".ZM_OPT_MPEG."\n" );
+	}
+	
+	my $status = $? >> 8;
+	if ( $status )
+	{
+		die( "Error: $status" );
+	}
+	print( LOG "Finished $video_file\n" );
+}
+else
+{
+	print( LOG "Video file $video_file already exists for event $event->{Id}\n" );
+}
+#print( STDOUT $event->{MonitorId}.'/'.$event->{Id}.'/'.$video_file."\n" );
+print( STDOUT $video_file."\n" );
+exit( 0 );
--- zm-1.21.3.orig/scripts/zmwatch.pl
+++ zm-1.21.3/scripts/zmwatch.pl
@@ -0,0 +1,180 @@
+#!/usr/bin/perl -wT
+#
+# ==========================================================================
+#
+# ZoneMinder WatchDog Script, $Date: 2005/02/24 14:39:58 $, $Revision: 1.28 $
+# Copyright (C) 2003, 2004, 2005  Philip Coombes
+#
+# 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.
+#
+# ==========================================================================
+#
+# This does some basic setup for ZoneMinder to run and then periodically
+# checks the fps output of the active daemons to check they haven't 
+# locked up. If they have then they are killed and restarted
+#
+use strict;
+use bytes;
+
+# ==========================================================================
+#
+# These are the elements you need to edit to suit your installation
+#
+# ==========================================================================
+
+use constant ZM_CONFIG => "/etc/zm/zm.conf";	# Path to the ZoneMinder config file, autogenerated do not change (from zmconfig)
+use constant ZM_PATH_BIN => "/usr/bin";	# Path to the ZoneMinder executables, autogenerated do not change (from zmconfig)
+
+# Load the config from the database into the symbol table
+BEGIN
+{
+	no strict 'refs';
+
+	open( CONFIG, "<".ZM_CONFIG ) or die( "Can't open config file: $!" );
+	foreach my $str ( <CONFIG> )
+	{
+		next if ( $str =~ /^\s*$/ );
+		next if ( $str =~ /^\s*#/ );
+		my ( $name, $value ) = $str =~ /^\s*([^=\\s]+)\s*=\s*(\S+)\s*$/;
+		$name =~ tr/a-z/A-Z/;
+		if (( $name eq 'ZM_DB_SERVER' ) ||
+			( $name eq 'ZM_DB_NAME' ) ||
+			( $name eq 'ZM_DB_USER' ) ||
+			( $name eq 'ZM_DB_PASS' ))
+		{
+			*{$name} = sub { $value };
+		}
+	}
+	close( CONFIG );
+
+	use DBI;
+	my $dbh = DBI->connect( "DBI:mysql:database=".&ZM_DB_NAME.";host=".&ZM_DB_SERVER, &ZM_DB_USER, &ZM_DB_PASS );
+	my $sql = "select * from Config";
+	my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
+	my $res = $sth->execute() or die( "Can't execute: ".$sth->errstr() );
+	while( my $config = $sth->fetchrow_hashref() )
+	{
+		*{$config->{Name}} = sub { $config->{Value} };
+	}
+	$sth->finish();
+	$dbh->disconnect();
+}
+
+use constant WATCH_LOG_FILE => ZM_PATH_LOGS.'/zmwatch.log';
+use constant START_DELAY => 30; # To give everything else time to start
+use constant VERBOSE => 0; # Whether to output more verbose debug
+
+# ==========================================================================
+#
+# Don't change anything below here
+#
+# ==========================================================================
+
+use POSIX;
+use DBI;
+use Data::Dumper;
+
+$| = 1;
+
+$ENV{PATH}  = '/bin:/usr/bin';
+$ENV{SHELL} = '/bin/sh' if exists $ENV{SHELL};
+delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};
+
+sub Usage
+{
+    print( "
+Usage: zmwatch.pl
+");
+	exit( -1 );
+}
+
+open( LOG, '>>'.WATCH_LOG_FILE ) or die( "Can't open log file: $!" );
+open( STDOUT, ">&LOG" ) || die( "Can't dup stdout: $!" );
+select( STDOUT ); $| = 1;
+open( STDERR, ">&LOG" ) || die( "Can't dup stderr: $!" );
+select( STDERR ); $| = 1;
+select( LOG ); $| = 1;
+print( "Watchdog starting at ".strftime( '%y/%m/%d %H:%M:%S', localtime() )."\n" );
+print( "Watchdog pausing for ".START_DELAY." seconds\n" );
+sleep( START_DELAY );
+
+my $dbh = DBI->connect( "DBI:mysql:database=".ZM_DB_NAME.";host=".ZM_DB_SERVER, ZM_DB_USER, ZM_DB_PASS );
+
+my $sql = "select * from Monitors";
+my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
+
+while( 1 )
+{
+	my $now = time();
+	my $res = $sth->execute() or die( "Can't execute: ".$sth->errstr() );
+	my $shm_size = 24; # We only need the first 24 bytes really for the last event time
+	while( my $monitor = $sth->fetchrow_hashref() )
+	{
+		if ( $monitor->{Function} ne 'None' )
+		{
+			# Check we have got an image recently
+			$monitor->{ShmKey} = hex(ZM_SHM_KEY)|$monitor->{Id};
+			$monitor->{ShmId} = shmget( $monitor->{ShmKey}, $shm_size, 0 );
+			if ( !defined($monitor->{ShmId}) )
+			{
+				print( "Can't get shared memory id '$monitor->{ShmKey}': $!\n" );
+				next;
+			}
+			my $image_time;
+			if ( !shmread( $monitor->{ShmId}, $image_time, 20, 4 ) )
+			{
+				print( "Can't read from shared memory '$monitor->{ShmKey}/$monitor->{ShmId}': $!\n" );
+				next;
+			}
+			$image_time = unpack( "l", $image_time );
+
+			#my $command = ZM_PATH_BIN."/zmu -m ".$monitor->{Id}." -t";
+			#print( "Getting last image time for monitor $monitor->{Id} ('$command')\n" ) if ( VERBOSE );
+			#my $image_time = qx( $command );
+			#chomp($image_time);
+
+			if ( !$image_time )
+			{
+				# We can't get the last capture time so can't be sure it's died.
+				next;
+			}
+
+			my $max_image_delay = (($monitor->{MaxFPS}>0)&&($monitor->{MaxFPS}<1))?(3/$monitor->{MaxFPS}):ZM_WATCH_MAX_DELAY;
+			my $image_delay = $now-$image_time;
+			print( "Monitor $monitor->{Id} last captured $image_delay seconds ago, max is $max_image_delay\n" ) if ( VERBOSE );
+			if ( $image_delay <= $max_image_delay )
+			{
+				# Yes, so continue
+				next;
+			}
+
+			my $command;
+			# If we are here then something bad has happened
+			if ( $monitor->{Type} eq 'Local' )
+			{
+				$command = ZM_PATH_BIN."/zmdc.pl restart zmc -d $monitor->{Device}";
+			}
+			else
+			{
+				$command = ZM_PATH_BIN."/zmdc.pl restart zmc -m $monitor->{Id}";
+			}
+			print( "Restarting capture daemon ('$command'), time since last capture $image_delay seconds ($now-$image_time)\n" );
+			print( qx( $command ) );
+		}
+	}
+	sleep( ZM_WATCH_CHECK_INTERVAL );
+}
+print( "Watchdog exiting at ".strftime( '%y/%m/%d %H:%M:%S', localtime() )."\n" );
+exit();
--- zm-1.21.3.orig/scripts/zmdc.pl
+++ zm-1.21.3/scripts/zmdc.pl
@@ -0,0 +1,637 @@
+#!/usr/bin/perl -wT
+#
+# ==========================================================================
+#
+# ZoneMinder Daemon Control Script, $Date: 2005/02/24 14:39:58 $, $Revision: 1.42 $
+# Copyright (C) 2003, 2004, 2005  Philip Coombes
+#
+# 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.
+#
+# ==========================================================================
+#
+# This script is the gateway for controlling the various ZoneMinder
+# daemons. All starting, stopping and restarting goes through here.
+# On the first invocation it starts up a server which subsequently
+# records what's running and what's not. Other invocations just 
+# connect to the server and pass instructions to it.
+#
+use strict;
+use bytes;
+
+# ==========================================================================
+#
+# User config
+#
+# ==========================================================================
+
+use constant ZM_CONFIG => "/etc/zm/zm.conf";	# Path to the ZoneMinder config file, autogenerated do not change (from zmconfig)
+use constant ZM_PATH_BIN => "/usr/bin";	# Path to the ZoneMinder executables, autogenerated do not change (from zmconfig)
+use constant ZM_PATH_WEB => "/var/www/zm";	# Path to the ZoneMinder web files, autogenerated do not change (from zmconfig)
+
+# Load the config from the database into the symbol table
+BEGIN
+{
+	no strict 'refs';
+
+	open( CONFIG, "<".ZM_CONFIG ) or die( "Can't open config file: $!" );
+	foreach my $str ( <CONFIG> )
+	{
+		next if ( $str =~ /^\s*$/ );
+		next if ( $str =~ /^\s*#/ );
+		my ( $name, $value ) = $str =~ /^\s*([^=\\s]+)\s*=\s*(\S+)\s*$/;
+		$name =~ tr/a-z/A-Z/;
+		if (( $name eq 'ZM_DB_SERVER' ) ||
+			( $name eq 'ZM_DB_NAME' ) ||
+			( $name eq 'ZM_DB_USER' ) ||
+			( $name eq 'ZM_DB_PASS' ))
+		{
+			*{$name} = sub { $value };
+		}
+	}
+	close( CONFIG );
+
+	use DBI;
+	my $dbh = DBI->connect( "DBI:mysql:database=".&ZM_DB_NAME.";host=".&ZM_DB_SERVER, &ZM_DB_USER, &ZM_DB_PASS );
+	my $sql = "select * from Config";
+	my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
+	my $res = $sth->execute() or die( "Can't execute: ".$sth->errstr() );
+	while( my $config = $sth->fetchrow_hashref() )
+	{
+		*{$config->{Name}} = sub { $config->{Value} };
+	}
+	$sth->finish();
+	$dbh->disconnect();
+}
+
+use constant DC_SOCK_FILE => ZM_PATH_SOCKS.'/zmdc.sock';
+use constant DC_LOG_FILE => ZM_PATH_LOGS.'/zmdc.log';
+use constant MAX_CONNECT_DELAY => 10;
+use constant VERBOSE => 0; # Whether to output more verbose debug
+
+# ==========================================================================
+#
+# Don't change anything from here on down
+#
+# ==========================================================================
+
+use POSIX;
+use Socket;
+use IO::Handle;
+use Data::Dumper;
+
+$| = 1;
+
+$ENV{PATH}  = '/bin:/usr/bin';
+$ENV{SHELL} = '/bin/sh' if exists $ENV{SHELL};
+delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};
+
+my @daemons = ( 'zmc', 'zma', 'zmf', 'zmfilter.pl', 'zmaudit.pl', 'zmtrigger.pl', 'zmx10.pl', 'zmwatch.pl', 'zmupdate.pl', 'zmtrack.pl' );
+
+my $command = shift @ARGV;
+die( "No command given" ) unless( $command );
+my $needs_daemon = $command !~ /(?:shutdown|status|check)/;
+my $daemon = shift( @ARGV );
+die( "No daemon given" ) unless( !$needs_daemon || $daemon );
+my @args;
+
+my $daemon_patt = '('.join( '|', @daemons ).')';
+if ( $needs_daemon )
+{
+	if ( $daemon =~ /^${daemon_patt}$/ )
+	{
+		$daemon = $1;
+	}
+	else
+	{
+		die( "Invalid daemon '$daemon' specified" );
+	}
+}
+
+foreach my $arg ( @ARGV )
+{
+	# Detaint arguments, if they look ok
+	#if ( $arg =~ /^(-{0,2}[\w]+)/ )
+	if ( $arg =~ /^(-{0,2}[\w\/?&=.-]+)$/ )
+	{
+		push( @args, $1 );
+	}
+	else
+	{
+		die( "Bogus argument '$arg' found" );
+	}
+}
+
+socket( CLIENT, PF_UNIX, SOCK_STREAM, 0 ) or die( "Can't open socket: $!" );
+
+my $saddr = sockaddr_un( DC_SOCK_FILE );
+
+if ( !connect( CLIENT, $saddr ) )
+{
+	if ( $command eq "check" )
+	{
+		print( "stopped\n" );
+		exit();
+	}
+	# The server isn't there 
+	print( "Unable to connect, starting server\n" );
+	close( CLIENT );
+
+	if ( my $cpid = fork() )
+	{
+		# Parent process just sleep and fall through
+		socket( CLIENT, PF_UNIX, SOCK_STREAM, 0 ) or die( "Can't open socket: $!" );
+		my $attempts = 0;
+		while (!connect( CLIENT, $saddr ))
+		{
+			$attempts++;
+			die( "Can't connect: $!" ) if ($attempts > MAX_CONNECT_DELAY);
+			sleep(1);
+		}
+	}
+	elsif ( defined($cpid) )
+	{
+		setpgrp();
+
+		open( LOG, ">>".DC_LOG_FILE ) or die( "Can't open log file: $!" );
+		open(STDOUT, ">&LOG") || die( "Can't dup stdout: $!" );
+		select( STDOUT ); $| = 1;
+		open(STDERR, ">&LOG") || die( "Can't dup stderr: $!" );
+		select( STDERR ); $| = 1;
+		select( LOG ); $| = 1;
+
+		dprint( "Server starting at ".strftime( '%y/%m/%d %H:%M:%S', localtime() )."\n" );
+
+		kill_all( 1 );
+
+		socket( SERVER, PF_UNIX, SOCK_STREAM, 0 ) or die( "Can't open socket: $!" );
+		unlink( DC_SOCK_FILE );
+		bind( SERVER, $saddr ) or die( "Can't bind: $!" );
+		listen( SERVER, SOMAXCONN ) or die( "Can't listen: $!" );
+
+		$SIG{CHLD} = \&reaper;
+		$SIG{INT} = \&shutdown_all;
+		$SIG{TERM} = \&shutdown_all;
+		$SIG{ABRT} = \&shutdown_all;
+		$SIG{HUP} = \&status;
+
+		my %cmd_hash;
+		my %pid_hash;
+
+		sub cprint
+		{
+			if ( fileno(CLIENT) )
+			{
+				print CLIENT @_
+			}
+		}
+		sub dprint
+		{
+			if ( fileno(CLIENT) )
+			{
+				print CLIENT @_
+			}
+			print @_;
+		}
+		sub start
+		{
+			my $daemon = shift;
+			my @args = @_;
+
+			my $command = $daemon;
+			$command .= ' '.join( ' ', ( @args ) ) if ( @args );
+			my $process = $cmd_hash{$command};
+
+			if ( !$process )
+			{
+				# It's not running, or at least it's not been started by us
+				$process = { daemon=>$daemon, args=>\@args, command=>$command, keepalive=>!undef };
+				# So check whether someone else has started it
+				#$ps_command = "ps -wh --user $> | grep '$command' | grep -v grep";
+				#$ps_array = preg_split( "/\s+/", exec( $ps_command ) );
+				#$pid = $ps_array[3];
+				#if ( $pid )
+			}
+			elsif ( $process->{pid} && $pid_hash{$process->{pid}} )
+			{
+				dprint( "'$process->{command}' already running at ".strftime( '%y/%m/%d %H:%M:%S', localtime( $process->{started}) ).", pid = $process->{pid}\n" );
+				return();
+			}
+
+			if ( my $cpid = fork() )
+			{
+				my $sigset = POSIX::SigSet->new;
+				my $blockset = POSIX::SigSet->new( SIGCHLD );
+				sigprocmask( SIG_BLOCK, $blockset, $sigset ) or die( "Can't block SIGCHLD: $!" );
+				$process->{pid} = $cpid;
+				$process->{started} = time();
+				delete( $process->{pending} );
+
+				dprint( "'$command' starting at ".strftime( '%y/%m/%d %H:%M:%S', localtime( $process->{started}) ).", pid = $process->{pid}\n" );
+
+				$cmd_hash{$process->{command}} = $pid_hash{$cpid} = $process;
+				sigprocmask( SIG_SETMASK, $sigset ) or die( "Can't restore SIGCHLD: $!" );
+			}
+			elsif ( defined($cpid ) )
+			{
+				# Child process
+				$SIG{CHLD} = 'DEFAULT';
+				$SIG{INT} = 'DEFAULT';
+				$SIG{TERM} = 'DEFAULT';
+				$SIG{ABRT} = 'DEFAULT';
+				$SIG{HUP} = 'DEFAULT';
+				dprint( "'".join( ' ', ( $daemon, @args ) )."' started at ".strftime( '%y/%m/%d %H:%M:%S', localtime() )."\n" );
+	
+				if ( $daemon =~ /^${daemon_patt}$/ )
+				{
+					$daemon = ZM_PATH_BIN.'/'.$1;
+				}
+				else
+				{
+					die( "Invalid daemon '$daemon' specified" );
+				}
+
+				my @good_args;
+				foreach my $arg ( @args )
+				{
+					# Detaint arguments, if they look ok
+					#if ( $arg =~ /^(-{0,2}[\w]+)/ )
+					if ( $arg =~ /^(-{0,2}[\w\/?&=.-]+)$/ )
+					{
+						push( @good_args, $1 );
+					}
+					else
+					{
+						die( "Bogus argument '$arg' found" );
+					}
+				}
+
+				exec( $daemon, @good_args ) or die( "Can't exec: $!" );
+			}
+			else
+			{
+				die( "Can't fork: $!" );
+			}
+		}
+		sub _stop
+		{
+			my $final = shift;
+			my $daemon = shift;
+			my @args = @_;
+
+			my $command = $daemon;
+			$command .= ' '.join( ' ', ( @args ) ) if ( @args );
+			my $process = $cmd_hash{$command};
+			if ( !$process )
+			{
+				dprint( "Can't find process with command of '$command'\n" );
+				return();
+			}
+			elsif ( $process->{pending} )
+			{
+				delete( $cmd_hash{$command} );
+				dprint( "Command '$command' removed from pending list at ".strftime( '%y/%m/%d %H:%M:%S', localtime() )."\n" );
+				return();
+			}
+
+			my $cpid = $process->{pid};
+			if ( !$pid_hash{$cpid} )
+			{
+				dprint( "No process with command of '$command' is running\n" );
+				return();
+			}
+
+			print( "'$daemon ".join( ' ', @args )."' stopping at ".strftime( '%y/%m/%d %H:%M:%S', localtime() )."\n" );
+			$process->{keepalive} = !$final;
+			kill( 'TERM', $cpid );
+			delete( $cmd_hash{$command} );
+
+			# Now check it has actually gone away, if not kill -9 it
+			my $count = 0;
+			while( $cpid && kill( 0, $cpid ) )
+			{
+				if ( $count++ > 5 )
+				{
+					kill( 'KILL', $cpid );
+				}
+				sleep( 1 );
+			}
+		}
+		sub stop
+		{
+			_stop( 1, @_ );
+		}
+		sub restart
+		{
+			my $daemon = shift;
+			my @args = @_;
+
+			my $command = $daemon;
+			$command .= ' '.join( ' ', ( @args ) ) if ( @args );
+			my $process = $cmd_hash{$command};
+			if ( $process )
+			{
+				my $cpid = $process->{pid};
+				if ( $pid_hash{$cpid} )
+				{
+					_stop( 0, $daemon, @args );
+					return;
+				}
+			}
+			start( $daemon, @args );
+		}
+		sub reaper
+		{
+			while ( (my $cpid = waitpid( -1, WNOHANG )) > 0 )
+			{
+				my $status = $?;
+
+				my $process = $pid_hash{$cpid};
+				delete( $pid_hash{$cpid} );
+
+				if ( !$process )
+				{
+					dprint( "Can't find child with pid of '$cpid'\n" );
+					next;
+				}
+
+				$process->{stopped} = time();
+				$process->{runtime} = ($process->{stopped}-$process->{started});
+				delete( $process->{pid} );
+
+				my $exit_status = $status>>8;
+				my $exit_signal = $status&0xfe;
+				my $core_dumped = $status&0x01;
+
+				if ( $exit_status == 0 )
+				{
+					print( "'$process->{daemon} ".join( ' ', @{$process->{args}} )."' died at ".strftime( '%y/%m/%d %H:%M:%S', localtime( $process->{stopped} ) ) );
+				}
+				else
+				{
+					print( "'$process->{daemon} ".join( ' ', @{$process->{args}} )."' crashed at ".strftime( '%y/%m/%d %H:%M:%S', localtime( $process->{stopped} ) ) );
+				}
+				print( ", exit status $exit_status" ) if ( $exit_status );
+				print( ", signal $exit_signal" ) if ( $exit_signal );
+				#print( ", core dumped" ) if ( $core_dumped );
+				print( "\n" );
+
+				if ( $process->{keepalive} )
+				{
+					if ( !$process->{delay} || ($process->{runtime} > (10*$process->{delay})) )
+					{
+						start( $process->{daemon}, @{$process->{args}} );
+						$process->{delay} = 5;
+					}
+					else
+					{
+						$cmd_hash{$process->{command}} = $process;
+						$process->{pending} = $process->{stopped}+$process->{delay};
+						$process->{delay} *= 2;
+						# Limit the start delay to 15 minutes max
+						if ( $process->{delay} > ZM_MAX_RESTART_DELAY )
+						{
+							$process->{delay} = ZM_MAX_RESTART_DELAY;
+						}
+					}
+				}
+			}
+			$SIG{CHLD} = \&reaper;
+		}
+		sub kill_all
+		{
+			my $delay = shift;
+			sleep( $delay );
+			foreach my $daemon ( @daemons )
+			{
+				qx( killall --quiet --signal TERM $daemon );
+			}
+			sleep( $delay );
+			foreach my $daemon ( @daemons )
+			{
+				qx( killall --quiet --signal KILL $daemon );
+			}
+		}
+		sub shutdown_all()
+		{
+			foreach my $process ( values( %pid_hash ) )
+			{
+				stop( $process->{daemon}, @{$process->{args}} );
+			}
+			kill_all( 5 );
+			dprint( "Server shutdown at ".strftime( '%y/%m/%d %H:%M:%S', localtime() )."\n" );
+			unlink( DC_SOCK_FILE );
+			close( CLIENT );
+			close( SERVER );
+			exit();
+		}
+		sub check
+		{
+			my $daemon = shift;
+			my @args = @_;
+
+			my $command = $daemon;
+			$command .= ' '.join( ' ', ( @args ) ) if ( @args );
+			my $process = $cmd_hash{$command};
+			if ( !$process )
+			{
+				cprint( "unknown\n" );
+			}
+			elsif ( $process->{pending} )
+			{
+				cprint( "pending\n" );
+			}
+			else
+			{
+				my $cpid = $process->{pid};
+				if ( !$pid_hash{$cpid} )
+				{
+					cprint( "stopped\n" );
+				}
+				else
+				{
+					cprint( "running\n" );
+				}
+			}
+		}
+		sub status
+		{
+			my $daemon = shift;
+			my @args = @_;
+
+			if ( defined($daemon) )
+			{
+				my $command = $daemon;
+				$command .= ' '.join( ' ', ( @args ) ) if ( @args );
+				my $process = $cmd_hash{$command};
+				if ( !$process )
+				{
+					dprint( "'$command' not running\n" );
+					return();
+				}
+
+				if ( $process->{pending} )
+				{
+					dprint( "'$process->{command}' pending at ".strftime( '%y/%m/%d %H:%M:%S', localtime( $process->{pending}) )."\n" );
+				}
+				else
+				{
+					my $cpid = $process->{pid};
+					if ( !$pid_hash{$cpid} )
+					{
+						dprint( "'$command' not running\n" );
+						return();
+					}
+				}
+				dprint( "'$process->{command}' running at ".strftime( '%y/%m/%d %H:%M:%S', localtime( $process->{started}) ).", pid = $process->{pid}" );
+			}
+			else
+			{
+				foreach my $process ( values(%pid_hash) )
+				{
+					dprint( "'$process->{command}' running at ".strftime( '%y/%m/%d %H:%M:%S', localtime( $process->{started}) ).", pid = $process->{pid}" );
+					dprint( ", valid" ) if ( kill( 0, $process->{pid} ) );
+					dprint( "\n" );
+				}
+				foreach my $process ( values( %cmd_hash ) )
+				{
+					if ( $process->{pending} )
+					{
+						dprint( "'$process->{command}' pending at ".strftime( '%y/%m/%d %H:%M:%S', localtime( $process->{pending}) )."\n" );
+					}
+				}
+			}
+		}
+
+		my $rin = '';
+		vec( $rin, fileno(SERVER),1) = 1;
+		my $win = $rin;
+		my $ein = $win;
+		my $timeout = 1;
+		#my ( $nfound, $timeleft) = select( $rin, $win, $ein, $timeout );
+		#print( "F:".fileno(SERVER)."\n" );
+		while( 1 )
+		{
+			my $nfound = select( my $rout = $rin, undef, my $eout = $ein, $timeout );
+			#print( "Off select, NF:$nfound, ER:$!\n" );
+			#print( vec( $rout, fileno(SERVER),1)."\n" );
+			#print( vec( $eout, fileno(SERVER),1)."\n" );
+			#print( "C:".fileno(CLIENT)."S:".fileno(SERVER)."\n" );
+			if ( $nfound > 0 )
+			{
+				if ( vec( $rout, fileno(SERVER),1) )
+				{
+					my $paddr = accept( CLIENT, SERVER );
+					my $message = <CLIENT>;
+
+					next if ( !$message );
+
+					my ( $command, $daemon, @args ) = split( ';', $message );
+
+					if ( $command eq 'start' )
+					{
+						start( $daemon, @args );
+					}
+					elsif ( $command eq 'stop' )
+					{
+						stop( $daemon, @args );
+					}
+					elsif ( $command eq 'restart' )
+					{
+						restart( $daemon, @args );
+					}
+					elsif ( $command eq 'shutdown' )
+					{
+						shutdown_all();
+					}
+					elsif ( $command eq 'check' )
+					{
+						check( $daemon, @args );
+					}
+					elsif ( $command eq 'status' )
+					{
+						if ( $daemon )
+						{
+							status( $daemon, @args );
+						}
+						else
+						{
+							status();
+						}
+					}
+					else
+					{
+						dprint( "Invalid command '$command'\n" );
+					}
+					close( CLIENT );
+				}
+				else
+				{
+					die( "Bogus descriptor" );
+				}
+			}
+			elsif ( $nfound < 0 )
+			{
+				if ( $! == EINTR )
+				{
+					# Dead child, will be reaped
+					#print( "Probable dead child\n" );
+				}
+				else
+				{
+					die( "Can't select: $!" );
+				}
+			}
+			else
+			{
+				#print( "Select timed out\n" );
+				foreach my $process ( values( %cmd_hash ) )
+				{
+					if ( $process->{pending} && $process->{pending} <= time() )
+					{
+						dprint( "Starting pending process, $process->{command}\n" );
+						start( $process->{daemon}, @{$process->{args}} );
+					}
+				}
+			}
+		}
+		dprint( "Server exiting at ".strftime( '%y/%m/%d %H:%M:%S', localtime() )."\n" );
+		close( LOG );
+		exit();
+	}
+	else
+	{
+		die( "Can't fork: $!" );
+	}
+}
+if ( $command eq "check" && !$daemon )
+{
+	print( "running\n" );
+	exit();
+}
+# The server is there, connect to it
+#print( "Writing commands\n" );
+CLIENT->autoflush();
+my $message = "$command";
+$message .= ";$daemon" if ( $daemon );
+$message .= ";".join( ';', @args ) if ( @args );
+print( CLIENT $message );
+shutdown( CLIENT, 1 );
+while ( my $line = <CLIENT> )
+{
+	chomp( $line );
+	print( "$line\n" );
+}
+close( CLIENT );
+#print( "Finished writing, bye\n" );
--- zm-1.21.3.orig/scripts/zmtrigger.pl
+++ zm-1.21.3/scripts/zmtrigger.pl
@@ -0,0 +1,377 @@
+#!/usr/bin/perl -wT
+#
+# ==========================================================================
+#
+# ZoneMinder External Trigger Script, $Date: 2005/05/19 16:22:19 $, $Revision: 1.11 $
+# Copyright (C) 2003, 2004, 2005  Philip Coombes
+#
+# 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.
+#
+# ==========================================================================
+#
+# This script is used to trigger and cancel alarms from external sources
+# using an arbitrary text based format
+#
+use strict;
+use bytes;
+
+# ==========================================================================
+#
+# User config
+#
+# ==========================================================================
+
+use constant ZM_CONFIG => "/etc/zm/zm.conf";	# Path to the ZoneMinder config file, autogenerated do not change (from zmconfig)
+use constant ZM_VERSION => "1.21.3";	# ZoneMinder version number, autogenerated do not change (from zmconfig)
+use constant ZM_PATH_BIN => "/usr/bin";	# Path to the ZoneMinder executables, autogenerated do not change (from zmconfig)
+use constant ZM_PATH_WEB => "/var/www/zm";	# Path to the ZoneMinder web files, autogenerated do not change (from zmconfig)
+
+# Load the config from the database into the symbol table
+BEGIN
+{
+	no strict 'refs';
+
+	open( CONFIG, "<".ZM_CONFIG ) or die( "Can't open config file: $!" );
+	foreach my $str ( <CONFIG> )
+	{
+		next if ( $str =~ /^\s*$/ );
+		next if ( $str =~ /^\s*#/ );
+		my ( $name, $value ) = $str =~ /^\s*([^=\\s]+)\s*=\s*(\S+)\s*$/;
+		$name =~ tr/a-z/A-Z/;
+		if (( $name eq 'ZM_DB_SERVER' ) ||
+			( $name eq 'ZM_DB_NAME' ) ||
+			( $name eq 'ZM_DB_USER' ) ||
+			( $name eq 'ZM_DB_PASS' ))
+		{
+			*{$name} = sub { $value };
+		}
+	}
+	close( CONFIG );
+
+	use DBI;
+	my $dbh = DBI->connect( "DBI:mysql:database=".&ZM_DB_NAME.";host=".&ZM_DB_SERVER, &ZM_DB_USER, &ZM_DB_PASS );
+	my $sql = "select * from Config";
+	my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
+	my $res = $sth->execute() or die( "Can't execute '$sql': ".$sth->errstr() );
+	while( my $config = $sth->fetchrow_hashref() )
+	{
+		*{$config->{Name}} = sub { $config->{Value} };
+	}
+	$sth->finish();
+	$dbh->disconnect();
+}
+
+use constant LOG_FILE => ZM_PATH_LOGS.'/zmtrigger.log';
+use constant MAX_CONNECT_DELAY => 10;
+use constant VERBOSE => 0; # Whether to output more verbose debug
+
+# Now define the trigger sources, can be inet socket, unix socket or file based
+# Ignore parser field for now.
+
+my @sources = (
+	{ name=>"S1", type=>"inet", port=>"6802", parser=>"", },
+	{ name=>"S2", type=>"unix", path=>"/tmp/test.sock", parser=>"", },
+	{ name=>"S3", type=>"file", path=>"/dev/ttyS0", parser=>"", },
+);
+
+# Need to make sure each parser function is defined
+sub parseTrigger1
+{
+}
+
+# ==========================================================================
+#
+# Don't change anything from here on down
+#
+# ==========================================================================
+
+use DBI;
+use POSIX;
+use Fcntl;
+use Socket;
+use IO::Handle;
+use Data::Dumper;
+
+$| = 1;
+
+$ENV{PATH}  = '/bin:/usr/bin';
+$ENV{SHELL} = '/bin/sh' if exists $ENV{SHELL};
+delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};
+
+open( LOG, ">>".LOG_FILE ) or die( "Can't open log file: $!" );
+open(STDOUT, ">&LOG") || die( "Can't dup stdout: $!" );
+select( STDOUT ); $| = 1;
+open(STDERR, ">&LOG") || die( "Can't dup stderr: $!" );
+select( STDERR ); $| = 1;
+select( LOG ); $| = 1;
+
+print( "Trigger daemon starting at ".strftime( '%y/%m/%d %H:%M:%S', localtime() )."\n" );
+
+my $dbh = DBI->connect( "DBI:mysql:database=".ZM_DB_NAME.";host=".ZM_DB_SERVER, ZM_DB_USER, ZM_DB_PASS );
+
+my $sql = "select * from Monitors where Id = ? or Name = ?";
+my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
+
+$SIG{HUP} = \&status;
+
+my $base_rin = '';
+foreach my $source ( @sources )
+{
+	print( "Opening source '$source->{name}'\n" );
+	if ( $source->{type} eq "inet" )
+	{
+		local *sfh;
+		my $saddr = sockaddr_in( $source->{port}, INADDR_ANY );
+		socket( *sfh, PF_INET, SOCK_STREAM, getprotobyname('tcp') ) or die( "Can't open socket: $!" );
+		setsockopt( *sfh, SOL_SOCKET, SO_REUSEADDR, 1 );
+		bind( *sfh, $saddr ) or die( "Can't bind: $!" );
+		listen( *sfh, SOMAXCONN ) or die( "Can't listen: $!" );
+		$source->{handle} = *sfh;
+		vec( $base_rin, fileno($source->{handle}),1) = 1;
+	}
+	elsif ( $source->{type} eq "unix" )
+	{
+		local *sfh;
+		unlink( $source->{path} );
+		my $saddr = sockaddr_un( $source->{path} );
+		socket( *sfh, PF_UNIX, SOCK_STREAM, 0 ) or die( "Can't open socket: $!" );
+		bind( *sfh, $saddr ) or die( "Can't bind: $!" );
+		listen( *sfh, SOMAXCONN ) or die( "Can't listen: $!" );
+		$source->{handle} = *sfh;
+		vec( $base_rin, fileno($source->{handle}),1) = 1;
+	}
+	elsif ( $source->{type} eq "file" )
+	{
+		local *sfh;
+		#sysopen( *sfh, $source->{path}, O_NONBLOCK|O_RDONLY ) or die( "Can't sysopen: $!" );
+		#open( *sfh, "<".$source->{path} ) or die( "Can't open: $!" );
+		open( *sfh, "+<".$source->{path} ) or die( "Can't open: $!" );
+		$source->{handle} = *sfh;
+		vec( $base_rin, fileno($source->{handle}),1) = 1;
+	}
+	else
+	{
+		die( "Bogus source type '$source->{type}' found for '$source->{name}'" );
+	}
+}
+
+my $sigset = POSIX::SigSet->new;
+my $blockset = POSIX::SigSet->new( SIGCHLD );
+sigprocmask( SIG_BLOCK, $blockset, $sigset ) or die( "Can't block SIGCHLD: $!" );
+
+my %connections;
+
+$! = undef;
+my $rin = '';
+my $win = $rin;
+my $ein = $win;
+my $timeout = 1;
+my %actions;
+while( 1 )
+{
+	$rin = $base_rin;
+	foreach my $fileno ( keys(%connections) )
+	{
+		vec( $rin, $fileno,1) = 1;
+	}
+	my $nfound = select( my $rout = $rin, undef, my $eout = $ein, $timeout );
+	if ( $nfound > 0 )
+	{
+		print( "Got input from $nfound sources\n" ) if ( VERBOSE );
+		foreach my $source ( @sources )
+		{
+			if ( vec( $rout, fileno($source->{handle}),1) )
+			{
+				print( "Got input from source $source->{name} (".fileno($source->{handle}).")\n" ) if ( VERBOSE );
+				if ( $source->{type} eq "inet" || $source->{type} eq "unix" )
+				{
+					local *cfh;
+					my $paddr = accept( *cfh, $source->{handle} );
+					$connections{fileno(*cfh)} = { source=>$source, handle=>*cfh };
+					print( "Added new connection (".fileno(*cfh)."), ".int(keys(%connections))." connections\n" ) if ( VERBOSE );
+				}
+				else
+				{
+					my $buffer;
+					my $nbytes = sysread( $source->{handle}, $buffer, POSIX::BUFSIZ );
+					if ( !$nbytes )
+					{
+						die( "Got unexpected close on source $source->{name}" );
+					}
+					else
+					{
+						print( "Got '$buffer' ($nbytes bytes)\n" ) if ( VERBOSE );
+						handleMessage( $buffer );
+					}
+				}
+			}
+		}
+		foreach my $connection ( values(%connections) )
+		{
+			print( "Got input from connection on ".$connection->{source}->{name}." (".fileno($connection->{handle}).")\n" ) if ( VERBOSE );
+			if ( vec( $rout, fileno($connection->{handle}),1) )
+			{
+				my $buffer;
+				my $nbytes = sysread( $connection->{handle}, $buffer, POSIX::BUFSIZ );
+				if ( !$nbytes )
+				{
+					delete( $connections{fileno($connection->{handle})} );
+					print( "Removed connection (".fileno($connection->{handle})."), ".int(keys(%connections))." connections\n" ) if ( VERBOSE );
+					close( $connection->{handle} );
+				}
+				else
+				{
+					print( "Got '$buffer' ($nbytes bytes)\n" ) if ( VERBOSE );
+					handleMessage( $buffer );
+				}
+			}
+		}
+	}
+	elsif ( $nfound < 0 )
+	{
+		if ( $! == EINTR )
+		{
+			# Dead child, will be reaped
+			#print( "Probable dead child\n" );
+		}
+		else
+		{
+			die( "Can't select: $!" );
+		}
+	}
+	else
+	{
+		print( "Checking for timed actions at ".time()."\n" ) if ( VERBOSE && int(keys(%actions)) );
+		my $now = time();
+		foreach my $action_time ( sort( grep { $_ < $now } keys( %actions ) ) )
+		{
+			print( "Found actions expiring at $action_time\n" );
+			foreach my $action ( @{$actions{$action_time}} )
+			{
+				print( "Found action '$action'\n" );
+				handleMessage( $action );
+			}
+			delete( $actions{$action_time} );
+		}
+	}
+}
+print( "Trigger daemon exiting\n" );
+
+sub handleMessage
+{
+	my $buffer = shift;
+	#chomp( $buffer );
+
+	print( "Processing buffer '$buffer'\n" ) if ( VERBOSE );
+	foreach my $message ( split( /\r?\n/, $buffer ) )
+	{
+		next if ( !$message );
+		print( "Processing message '$message'\n" ) if ( VERBOSE );
+		my ( $id, $action, $score, $cause, $text, $showtext ) = split( /\|/, $message );
+		$score = 0 if ( !defined($score) );
+		$cause = 0 if ( !defined($cause) );
+		$text = 0 if ( !defined($text) );
+
+		my $res = $sth->execute( $id, $id ) or die( "Can't execute '$sql': ".$sth->errstr() );
+		my $monitor = $sth->fetchrow_hashref();
+
+		if ( !$monitor )
+		{
+			print( "Can't find monitor '$id' for message '$message'\n" );
+			next;
+		}
+		print( "Found monitor for id '$id'\n" ) if ( VERBOSE );
+		my $size = 512; # We only need the first 512 bytes really for the shared data and trigger section
+		$monitor->{ShmKey} = hex(ZM_SHM_KEY)|$monitor->{Id};
+		$monitor->{ShmId} = shmget( $monitor->{ShmKey}, $size, 0 );
+		if ( !defined($monitor->{ShmId}) )
+		{
+			printf( "Can't get shared memory id '%x': $!\n", $monitor->{ShmKey}, $! );
+			next;
+		}
+
+		my $shm_data_size;
+		if ( !shmread( $monitor->{ShmId}, $shm_data_size, 0, 4 ) )
+		{
+			print( "Can't read from shared memory: $!\n" );
+			exit( -1 );
+		}
+		$shm_data_size = unpack( "l", $shm_data_size );
+		my $trigger_data_offset = $shm_data_size+4; # Allow for 'size' member of trigger data
+
+		print( "Handling action '$action'\n" ) if ( VERBOSE );
+		if ( $action =~ /^(on|off)(?:\+(\d+))?$/ )
+		{
+			my $trigger = $1;
+			my $delay = $2;
+			my $trigger_data;
+			if ( defined($showtext) )
+			{
+				$trigger_data = pack( "llZ32Z256Z32", $trigger eq "on"?1:2, $trigger eq "on"?$score:0, $cause, $text, $showtext );
+			}
+			else
+			{
+				$trigger_data = pack( "llZ32Z256", $trigger eq "on"?1:2, $trigger eq "on"?$score:0, $cause, $text );
+			}
+			if ( !shmwrite( $monitor->{ShmId}, $trigger_data, $trigger_data_offset, length($trigger_data) ) )
+			{
+				print( "Can't write to shared memory: $!\n" );
+			}
+			print( "Triggered event $trigger '$cause'\n" );
+			if ( $delay )
+			{
+				my $action_time = time()+$delay;
+				my $action_text = $id."|cancel|0|".$cause."|".$text;
+				my $action_array = $actions{$action_time};
+				if ( !$action_array )
+				{
+					$action_array = $actions{$action_time} = [];
+				}
+				push( @$action_array, $action_text );
+				print( "Added timed event '$action_text', expires at $action_time (+$delay secs)\n" ) if ( VERBOSE );
+			}
+		}
+		elsif( $action eq "cancel" )
+		{
+			my $trigger_data;
+			if ( defined($showtext) )
+			{
+				$trigger_data = pack( "llZ32Z256Z32", 0, 0, "", "", $showtext );
+			}
+			else
+			{
+				$trigger_data = pack( "llZ32Z256", 0, 0, "", "" );
+			}
+			if ( !shmwrite( $monitor->{ShmId}, $trigger_data, $trigger_data_offset, length($trigger_data) ) )
+			{
+				print( "Can't write to shared memory: $!\n" );
+			}
+			print( "Cancelled event '$cause'\n" );
+		}
+		elsif( $action eq "show" )
+		{
+			my $trigger_data = pack( "Z32", $showtext );
+			if ( !shmwrite( $monitor->{ShmId}, $trigger_data, $trigger_data_offset, length($trigger_data) ) )
+			{
+				print( "Can't write to shared memory: $!\n" );
+			}
+			print( "Updated show text to '$showtext'\n" );
+		}
+		else
+		{
+			print( "Unrecognised action '$action' in message '$message'\n" );
+		}
+	}
+}
--- zm-1.21.3.orig/scripts/zmfilter.pl
+++ zm-1.21.3/scripts/zmfilter.pl
@@ -0,0 +1,1090 @@
+#!/usr/bin/perl -wT
+#
+# ==========================================================================
+#
+# ZoneMinder Event Filter Script, $Date: 2005/06/23 08:34:19 $, $Revision: 1.70 $
+# Copyright (C) 2003, 2004, 2005  Philip Coombes
+#
+# 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.
+#
+# ==========================================================================
+#
+# This script continuously monitors the recorded events for the given
+# monitor and applies any filters which would delete and/or upload 
+# matching events
+#
+use strict;
+use bytes;
+
+# ==========================================================================
+#
+# These are the elements you need to edit to suit your installation
+#
+# ==========================================================================
+use constant ZM_CONFIG => "/etc/zm/zm.conf";	# Path to the ZoneMinder config file, autogenerated do not change (from zmconfig)
+use constant ZM_PATH_BIN => "/usr/bin";	# Path to the ZoneMinder executables, autogenerated do not change (from zmconfig)
+use constant ZM_PATH_WEB => "/var/www/zm";	# Path to the ZoneMinder web files, autogenerated do not change (from zmconfig)
+use constant ZM_PATH_CGI => "/usr/lib/cgi-bin";	# Path to the ZoneMinder cgi files, autogenerated do not change (from zmconfig)
+
+# Load the config from the database into the symbol table
+BEGIN
+{
+	no strict 'refs';
+
+	open( CONFIG, "<".ZM_CONFIG ) or die( "Can't open config file: $!" );
+	foreach my $str ( <CONFIG> )
+	{
+		next if ( $str =~ /^\s*$/ );
+		next if ( $str =~ /^\s*#/ );
+		my ( $name, $value ) = $str =~ /^\s*([^=\\s]+)\s*=\s*(\S+)\s*$/;
+		$name =~ tr/a-z/A-Z/;
+		if (( $name eq 'ZM_DB_SERVER' ) ||
+			( $name eq 'ZM_DB_NAME' ) ||
+			( $name eq 'ZM_DB_USER' ) ||
+			( $name eq 'ZM_DB_PASS' ))
+		{
+			*{$name} = sub { $value };
+		}
+	}
+	close( CONFIG );
+
+	use DBI;
+	my $dbh = DBI->connect( "DBI:mysql:database=".&ZM_DB_NAME.";host=".&ZM_DB_SERVER, &ZM_DB_USER, &ZM_DB_PASS );
+	my $sql = "select * from Config";
+	my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
+	my $res = $sth->execute() or die( "Can't execute '$sql': ".$sth->errstr() );
+	while( my $config = $sth->fetchrow_hashref() )
+	{
+		*{$config->{Name}} = sub { $config->{Value} };
+	}
+	$sth->finish();
+	$dbh->disconnect();
+}
+
+use constant EVENT_PATH => ZM_PATH_WEB.'/'.ZM_DIR_EVENTS;
+use constant LOG_FILE => ZM_PATH_LOGS.'/zmfilter.log';
+use constant START_DELAY => 5; # How long to wait before starting
+use constant CHECK_DELAY => 60; # How long between each event check
+
+use constant DBG_LEVEL => 0; # 0 is errors, warnings and info only, > 0 for debug
+
+if ( ZM_OPT_UPLOAD )
+{
+	# Comment these out if you don't have them and don't want to upload
+	# or don't want to use that format
+	if ( ZM_UPLOAD_ARCH_FORMAT eq "zip" )
+	{
+		require Archive::Zip;
+		import Archive::Zip qw( :ERROR_CODES :CONSTANTS );
+	}
+	else
+	{
+		require Archive::Tar;
+	}
+	require Net::FTP;
+}
+
+my $email_subject;
+my $email_body;
+if ( ZM_OPT_EMAIL )
+{
+	if ( ZM_NEW_MAIL_MODULES )
+	{
+		require MIME::Lite;
+		require Net::SMTP;
+	}
+	else
+	{
+		require MIME::Entity;
+	}
+	( $email_subject, $email_body ) = ZM_EMAIL_TEXT =~ /subject\s*=\s*"([^\n]*)".*body\s*=\s*"(.*)"/ms;
+}
+
+my $message_subject;
+my $message_body;
+if ( ZM_OPT_MESSAGE )
+{
+	if ( ZM_NEW_MAIL_MODULES )
+	{
+		require MIME::Lite;
+		require Net::SMTP;
+	}
+	else
+	{
+		require MIME::Entity;
+	}
+
+	( $message_subject, $message_body ) = ZM_MESSAGE_TEXT =~ /subject\s*=\s*"([^\n]*)".*body\s*=\s*"(.*)"/ms;
+}
+
+# ==========================================================================
+#
+# You shouldn't need to change anything from here downwards
+#
+# ==========================================================================
+
+use DBI;
+use POSIX;
+use Time::HiRes qw/gettimeofday/;
+use Date::Manip;
+use Data::Dumper;
+use Getopt::Long;
+
+$| = 1;
+
+$ENV{PATH}  = '/bin:/usr/bin';
+$ENV{SHELL} = '/bin/sh' if exists $ENV{SHELL};
+delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};
+
+my $delay = CHECK_DELAY;
+my $event_id = 0;
+
+sub Usage
+{
+	print( "
+Usage: zmfilter.pl [-d <seconds>,--delay=<seconds>]
+Parameters are :-
+-d<seconds>, --delay=<seconds>          - How long to delay between each check, default 60
+");
+	exit( -1 );
+}
+
+my $dbg_id = "";
+
+sub dbgInit
+{
+	my $id = shift;
+	if ( $id )
+	{
+		$dbg_id = $id;
+		my $add_parms = shift;
+		if ( $add_parms )
+		{
+			foreach my $arg ( @ARGV )
+			{
+				if ( $arg =~ /^-(.*)$/ )
+				{
+					$dbg_id .= "_$1";
+				}
+				else
+				{
+					$dbg_id .= $arg;
+				}
+			}
+		}
+	}
+}
+
+sub dbgPrint
+{
+	my $code = shift;
+	my $string = shift;
+	my $line = shift;
+
+	$string =~ s/[\r\n]+$//g;
+
+	my ($seconds, $microseconds) = gettimeofday();
+	if ( $line )
+	{
+		my $file = __FILE__;
+		$file =~ s|^.*/||g;
+		printf( "%s.%06d %s[%d].%s-%s/%d [%s]\n", strftime( "%x %H:%M:%S", localtime( $seconds ) ), $microseconds, $dbg_id, $$, $file, $line, $code, $string );
+	}
+	else
+	{
+		printf( "%s.%06d %s[%d].%s [%s]\n", strftime( "%x %H:%M:%S", localtime( $seconds ) ), $microseconds, $dbg_id, $$, $code, $string );
+	}
+}
+
+sub Debug
+{
+	dbgPrint( "DBG", $_[0] ) if ( DBG_LEVEL >= 1 );
+}
+
+sub Info
+{
+	dbgPrint( "INF", $_[0] ) if ( DBG_LEVEL >= 0 );
+}
+
+sub Warning
+{
+	dbgPrint( "WAR", $_[0] ) if ( DBG_LEVEL >= -1 );
+}
+
+sub Error
+{
+	dbgPrint( "ERR", $_[0] ) if ( DBG_LEVEL >= -2 );
+}
+
+#
+# More or less replicates the equivalent PHP function
+#
+sub strtotime
+{
+	my $dt_str = shift;
+	return( UnixDate( $dt_str, '%s' ) );
+}
+
+#
+# More or less replicates the equivalent PHP function
+#
+sub str_repeat
+{
+	my $string = shift;
+	my $count = shift;
+	return( ${string}x${count} );
+}
+
+# Formats a date into MySQL format
+sub DateTimeToSQL
+{
+	my $dt_str = shift;
+	my $dt_val = strtotime( $dt_str );
+	if ( !$dt_val )
+	{
+		Error( "Unable to parse date string '$dt_str'\n" );
+		return( undef );
+	}
+	return( strftime( "%Y-%m-%d %H:%M:%S", localtime( $dt_val ) ) );
+}
+
+dbgInit( "zmfilter", 1 );
+
+if ( !GetOptions( 'delay=i'=>\$delay ) )
+{
+	Usage();
+}
+
+my $log_file = LOG_FILE;
+open( LOG, ">>$log_file" ) or die( "Can't open log file: $!" );
+open( STDOUT, ">&LOG" ) || die( "Can't dup stdout: $!" );
+select( STDOUT ); $| = 1;
+open( STDERR, ">&LOG" ) || die( "Can't dup stderr: $!" );
+select( STDERR ); $| = 1;
+select( LOG ); $| = 1;
+
+chdir( EVENT_PATH );
+
+my $dbh = DBI->connect( "DBI:mysql:database=".ZM_DB_NAME.";host=".ZM_DB_SERVER, ZM_DB_USER, ZM_DB_PASS );
+
+Info( "Scanning for events\n" );
+
+sleep( START_DELAY );
+
+my $filters = getFilters();
+my $last_action = 0;
+
+while( 1 )
+{
+	if ( (time() - $last_action) > ZM_FILTER_RELOAD_DELAY )
+	{
+		Debug( "Reloading filters\n" );
+		$last_action = time();
+		$filters = getFilters();
+	}
+
+	foreach my $filter ( @$filters )
+	{
+		checkFilter( $filter );
+	}
+
+	Debug( "Sleeping for $delay seconds\n" );
+	sleep( $delay );
+}
+
+sub getDiskPercent
+{
+	my $command = "df .";
+	my $df = qx( $command );
+	my $space = -1;
+	if ( $df =~ /\s(\d+)%/ms )
+	{
+		$space = $1;
+	}
+	return( $space );
+}
+
+sub getDiskBlocks
+{
+	my $command = "df .";
+	my $df = qx( $command );
+	my $space = -1;
+	if ( $df =~ /\s(\d+)\s+\d+\s+\d+%/ms )
+	{
+		$space = $1;
+	}
+	return( $space );
+}
+
+sub getFilters
+{
+	my @filters;
+	my $sql = "select * from Filters where (AutoArchive = 1 or AutoDelete = 1 or AutoUpload = 1 or AutoEmail = 1 or AutoMessage = 1 or AutoExecute != '') order by Name";
+	my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
+	my $res = $sth->execute() or die( "Can't execute '$sql': ".$sth->errstr() );
+	FILTER: while( my $filter_data = $sth->fetchrow_hashref() )
+	{
+		Debug( "Found filter '$filter_data->{Name}'\n" );
+		my %filter_terms;
+		foreach my $filter_parm ( split( '&', $filter_data->{Query} ) )
+		{
+			my( $key, $value ) = split( '=', $filter_parm, 2 );
+			if ( $key )
+			{
+				$filter_terms{$key} = $value;
+			}
+		}
+		#Debug( Dumper( %filter_terms ) );
+		my $sql = "select E.Id,E.MonitorId,M.Name as MonitorName,E.Name,E.StartTime,unix_timestamp(E.StartTime) as Time,E.Length,E.Frames,E.AlarmFrames,E.TotScore,E.AvgScore,E.MaxScore,E.Archived,E.Uploaded,E.Emailed,E.Messaged,E.LearnState from Events as E inner join Monitors as M on M.Id = E.MonitorId where not isnull(E.EndTime)";
+		my $filter_sql = '';
+		for ( my $i = 1; $i <= $filter_terms{trms}; $i++ )
+		{
+			my $conjunction_name = "cnj$i";
+			my $obracket_name = "obr$i";
+			my $cbracket_name = "cbr$i";
+			my $attr_name = "attr$i";
+			my $op_name = "op$i";
+			my $value_name = "val$i";
+			if ( $filter_terms{$conjunction_name} )
+			{
+				$filter_sql .= " ".$filter_terms{$conjunction_name}." ";
+			}
+			if ( $filter_terms{$obracket_name} )
+			{
+				$filter_sql .= str_repeat( "(", $filter_terms{$obracket_name} );
+			}
+			my $value = $filter_terms{$value_name};
+			my @value_list;
+			if ( $filter_terms{$attr_name} )
+			{
+				if ( $filter_terms{$attr_name} =~ '/^Monitor/' )
+				{
+					my ( $temp_attr_name ) = $filter_terms{$attr_name} =~ /^Monitor(.+)$/;
+					$filter_sql .= "M.".$temp_attr_name;
+				}
+				elsif ( $filter_terms{$attr_name} eq 'DateTime' )
+				{
+					$filter_sql .= "E.StartTime";
+				}
+				elsif ( $filter_terms{$attr_name} eq 'Date' )
+				{
+					$filter_sql .= "to_days( E.StartTime )";
+				}
+				elsif ( $filter_terms{$attr_name} eq 'Time' )
+				{
+					$filter_sql .= "extract( hour_second from E.StartTime )";
+				}
+				elsif ( $filter_terms{$attr_name} eq 'Weekday' )
+				{
+					$filter_sql .= "weekday( E.StartTime )";
+				}
+				elsif ( $filter_terms{$attr_name} eq 'Archived' )
+				{
+					$filter_sql .= "E.Archived = ".$filter_terms{$value_name};
+				}
+				elsif ( $filter_terms{$attr_name} eq 'DiskPercent' )
+				{
+					$filter_sql .= "zmDiskPercent";
+					$filter_data->{HasDiskPercent} = !undef;
+				}
+				elsif ( $filter_terms{$attr_name} eq 'DiskBlocks' )
+				{
+					$filter_sql .= "zmDiskBlocks";
+					$filter_data->{HasDiskBlocks} = !undef;
+				}
+				else
+				{
+					$filter_sql .= "E.".$filter_terms{$attr_name};
+				}
+
+				( my $stripped_value = $value ) =~ s/^["\']+?(.+)["\']+?$/$1/;
+				foreach my $temp_value ( split( '/["\'\s]*?,["\'\s]*?/', $stripped_value ) )
+				{
+					if ( $filter_terms{$attr_name} =~ '/^Monitor/' )
+					{
+						$value = "'$temp_value'";
+					}
+					elsif ( $filter_terms{$attr_name} eq 'DateTime' )
+					{
+						$value = DateTimeToSQL( $temp_value );
+						if ( !$value )
+						{
+							Error( "Error parsing date/time '$temp_value', skipping filter '$filter_data->{Name}'\n" );
+							next FILTER;
+						}
+						$value = "'$value'";
+					}
+					elsif ( $filter_terms{$attr_name} eq 'Date' )
+					{
+						$value = DateTimeToSQL( $temp_value );
+						if ( !$value )
+						{
+							Error( "Error parsing date/time '$temp_value', skipping filter '$filter_data->{Name}'\n" );
+							next FILTER;
+						}
+						$value = "to_days( '$value' )";
+					}
+					elsif ( $filter_terms{$attr_name} eq 'Time' )
+					{
+						$value = DateTimeToSQL( $temp_value );
+						if ( !$value )
+						{
+							Error( "Error parsing date/time '$temp_value', skipping filter '$filter_data->{Name}'\n" );
+							next FILTER;
+						}
+						$value = "extract( hour_second from '$value' )";
+					}
+					elsif ( $filter_terms{$attr_name} eq 'Weekday' )
+					{
+						$value = DateTimeToSQL( $temp_value );
+						if ( !$value )
+						{
+							Error( "Error parsing date/time '$temp_value', skipping filter '$filter_data->{Name}'\n" );
+							next FILTER;
+						}
+						$value = "weekday( '$value' )";
+					}
+					else
+					{
+						$value = $temp_value;
+					}
+					push( @value_list, $value );
+				}
+			}
+			if ( $filter_terms{$op_name} )
+			{
+				if ( $filter_terms{$op_name} eq '=~' )
+				{
+					$filter_sql .= " regexp $value";
+				}
+				elsif ( $filter_terms{$op_name} eq '!~' )
+				{
+					$filter_sql .= " not regexp $value";
+				}
+				elsif ( $filter_terms{$op_name} eq '=[]' )
+				{
+					$filter_sql .= " in (".join( ",", @value_list ).")";
+				}
+				elsif ( $filter_terms{$op_name} eq '!~' )
+				{
+					$filter_sql .= " not in (".join( ",", @value_list ).")";
+				}
+				else
+				{
+					$filter_sql .= " ".$filter_terms{$op_name}." $value";
+				}
+			}
+			if ( $filter_terms{$cbracket_name} )
+			{
+				$filter_sql .= str_repeat( ")", $filter_terms{$cbracket_name} );
+			}
+		}
+		if ( $filter_sql )
+		{
+			$sql .= " and ( $filter_sql )";
+		}
+		my @auto_terms;
+		if ( $filter_data->{AutoArchive} )
+		{
+			push( @auto_terms, "E.Archived = 0" )
+		}
+		if ( $filter_data->{AutoUpload} )
+		{
+			push( @auto_terms, "E.Uploaded = 0" )
+		}
+		if ( $filter_data->{AutoEmail} )
+		{
+			push( @auto_terms, "E.Emailed = 0" )
+		}
+		if ( $filter_data->{AutoMessage} )
+		{
+			push( @auto_terms, "E.Messaged = 0" )
+		}
+		if ( $filter_data->{AutoExecute} )
+		{
+			push( @auto_terms, "E.Executed = 0" )
+		}
+		if ( @auto_terms )
+		{
+			$sql .= " and ( ".join( " or ", @auto_terms )." )";
+		}
+		if ( !$filter_terms{sort_field} )
+		{
+			$filter_terms{sort_field} = 'StartTime';
+			$filter_terms{sort_asc} = 0;
+		}
+		my $sort_column = '';
+		if ( $filter_terms{sort_field} eq 'Id' )
+		{
+            $sort_column = "E.Id"; 
+		}
+		elsif ( $filter_terms{sort_field} eq 'MonitorName' )
+		{
+            $sort_column = "M.Name";
+		}
+		elsif ( $filter_terms{sort_field} eq 'Name' )
+		{
+            $sort_column = "E.Name";
+		}
+		elsif ( $filter_terms{sort_field} eq 'StartTime' )
+		{
+            $sort_column = "E.StartTime";
+		}
+		elsif ( $filter_terms{sort_field} eq 'Secs' )
+		{
+            $sort_column = "E.Length";
+		}
+		elsif ( $filter_terms{sort_field} eq 'Frames' )
+		{
+            $sort_column = "E.Frames";
+		}
+		elsif ( $filter_terms{sort_field} eq 'AlarmFrames' )
+		{
+            $sort_column = "E.AlarmFrames";
+		}
+		elsif ( $filter_terms{sort_field} eq 'TotScore' )
+		{
+            $sort_column = "E.TotScore";
+		}
+		elsif ( $filter_terms{sort_field} eq 'AvgScore' )
+		{
+            $sort_column = "E.AvgScore";
+		}
+		elsif ( $filter_terms{sort_field} eq 'MaxScore' )
+		{
+            $sort_column = "E.MaxScore";
+		}
+		else
+		{
+            $sort_column = "E.StartTime";
+    	}
+		my $sort_order = $filter_terms{sort_asc}?"asc":"desc";
+		$sql .= " order by ".$sort_column." ".$sort_order;
+		if ( $filter_terms{limit} )
+		{
+			$sql .= " limit 0, ".$filter_terms{limit};
+		}
+		Debug( "SQL:$sql\n" );
+		$filter_data->{Sql} = $sql;
+		if ( $filter_data->{AutoExecute} )
+		{
+			my $script = $filter_data->{AutoExecute};
+			if ( !-e $script )
+			{
+				Error( "Auto execute script '$script' not found, skipping filter '$filter_data->{Name}'\n" );
+				next FILTER;
+
+			}
+			elsif ( !-x $script )
+			{
+				Error( "Auto execute script '$script' not executable, skipping filter '$filter_data->{Name}'\n" );
+				next FILTER;
+			}
+		}
+		push( @filters, $filter_data );
+	}
+	$sth->finish();
+
+	return( \@filters );
+}
+
+sub checkFilter
+{
+	my $filter = shift;
+
+	Debug( "Checking filter '$filter->{Name}'".
+		($filter->{AutoArchive}?", archive":"").
+		($filter->{AutoDelete}?", delete":"").
+		($filter->{AutoUpload}?", upload":"").
+		($filter->{AutoEmail}?", email":"").
+		($filter->{AutoMessage}?", message":"").
+		($filter->{AutoExecute}?", execute":"").
+		"\n"
+	);
+	my $sql = $filter->{Sql};
+	
+	if ( $filter->{HasDiskPercent} )
+	{
+		my $disk_percent = getDiskPercent();
+		$sql =~ s/zmDiskPercent/$disk_percent/g;
+	}
+	if ( $filter->{HasDiskBlocks} )
+	{
+		my $disk_blocks = getDiskBlocks();
+		$sql =~ s/zmDiskBlocks/$disk_blocks/g;
+	}
+
+	my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
+	my $res = $sth->execute() or die( "Can't execute '$sql': ".$sth->errstr() );
+
+	while( my $event = $sth->fetchrow_hashref() )
+	{
+		Debug( "Checking event $event->{Id}\n" );
+		if ( $filter->{AutoExecute} )
+		{
+			if ( !$event->{Execute} )
+			{
+				executeCommand( $filter, $event );
+			}
+		}
+		if ( ZM_OPT_EMAIL && $filter->{AutoEmail} )
+		{
+			if ( !$event->{Emailed} )
+			{
+				sendEmail( $filter, $event );
+			}
+		}
+		if ( ZM_OPT_MESSAGE && $filter->{AutoMessage} )
+		{
+			if ( !$event->{Messaged} )
+			{
+				sendMessage( $filter, $event );
+			}
+		}
+		if ( ZM_OPT_UPLOAD && $filter->{AutoUpload} )
+		{
+			if ( !$event->{Uploaded} )
+			{
+				uploadArchFile( $filter, $event );
+			}
+		}
+		if ( $filter->{AutoArchive} )
+		{
+			Info( "Archiving event $event->{Id}\n" );
+			# Do it individually to avoid locking up the table for new events
+			my $sql = "update Events set Archived = 1 where Id = ?";
+			my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
+			my $res = $sth->execute( $event->{Id} ) or die( "Can't execute '$sql': ".$sth->errstr() );
+		}
+		if ( $filter->{AutoDelete} )
+		{
+			Info( "Deleting event $event->{Id}\n" );
+			# Do it individually to avoid locking up the table for new events
+			my $sql = "delete from Events where Id = ?";
+			my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
+			my $res = $sth->execute( $event->{Id} ) or die( "Can't execute '$sql': ".$sth->errstr() );
+
+			if ( !ZM_OPT_FAST_DELETE )
+			{
+				my $sql = "delete from Frames where EventId = ?";
+				my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
+				my $res = $sth->execute( $event->{Id} ) or die( "Can't execute '$sql': ".$sth->errstr() );
+
+				$sql = "delete from Stats where EventId = ?";
+				$sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
+				$res = $sth->execute( $event->{Id} ) or die( "Can't execute '$sql': ".$sth->errstr() );
+
+				my $command = "rm -rf ".ZM_DIR_EVENTS."/*/".sprintf( "%d", $event->{Id} );
+				my $output = qx($command);
+				my $status = $? >> 8;
+				if ( $status || DBG_LEVEL > 0 )
+				{
+					chomp( $output );
+					Debug( "Output: $output\n" );
+				}
+			}
+		}
+	}
+	$sth->finish();
+}
+
+sub executeCommand
+{
+	my $filter = shift;
+	my $event = shift;
+
+	my $event_path = "$event->{MonitorId}/$event->{Id}";
+
+	my $command = $filter->{AutoExecute};
+	$command .= " $event_path";
+
+	Info( "Executing '$command'\n" );
+	my $output = qx($command);
+	my $status = $? >> 8;
+	if ( $status || DBG_LEVEL > 0 )
+	{
+		chomp( $output );
+		Debug( "Output: $output\n" );
+	}
+	if ( $status )
+	{
+		Error( "Command '$command' exited with status: $status\n" );
+	}
+	else
+	{
+		my $sql = "update Events set Executed = 1 where Id = ?";
+		my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
+		my $res = $sth->execute( $event->{Id} ) or die( "Can't execute '$sql': ".$sth->errstr() );
+	}
+}
+
+sub uploadArchFile
+{
+	my $filter = shift;
+	my $event = shift;
+
+	my $arch_file = ZM_UPLOAD_FTP_LOC_DIR.'/'.$event->{MonitorName}.'-'.$event->{Id};
+	my $arch_image_path = "$event->{MonitorId}/$event->{Id}/".((ZM_UPLOAD_ARCH_ANALYSE)?'{*analyse,*capture}':'*capture').".jpg";
+	my $arch_error;
+
+	if ( ZM_UPLOAD_ARCH_FORMAT eq "zip" )
+	{
+		$arch_file .= '.zip';
+		my $zip = Archive::Zip->new();
+		Info( "Creating upload file '$arch_file'\n" );
+
+		my $status = &AZ_OK;
+		foreach my $image_file ( <*$arch_image_path> )
+		{
+			Info( "Adding $image_file\n" );
+			my $member = $zip->addFile( $image_file );
+			last unless ( $member );
+			$member->desiredCompressionMethod( (ZM_UPLOAD_ARCH_COMPRESS)?&COMPRESSION_DEFLATED:&COMPRESSION_STORED );
+		}
+		$status = $zip->writeToFileNamed( $arch_file );
+
+		if ( $arch_error = ($status != &AZ_OK) )
+		{
+			Error( "Zip error: $status\n " );
+		}
+	}
+	elsif ( ZM_UPLOAD_ARCH_FORMAT eq "tar" )
+	{
+		if ( ZM_UPLOAD_ARCH_COMPRESS )
+		{
+			$arch_file .= '.tar.gz';
+		}
+		else
+		{
+			$arch_file .= '.tar';
+		}
+		Info( "Creating upload file '$arch_file'\n" );
+
+		if ( $arch_error = !Archive::Tar->create_archive( $arch_file, ZM_UPLOAD_ARCH_COMPRESS, <*$arch_image_path> ) )
+		{
+			Error( "Tar error: ".Archive::Tar->error()."\n " );
+		}
+	}
+
+
+	if ( !$arch_error )
+	{
+		Info( "Uploading to ".ZM_UPLOAD_FTP_HOST."\n" );
+		my $ftp = Net::FTP->new( ZM_UPLOAD_FTP_HOST, Timeout=>ZM_UPLOAD_FTP_TIMEOUT, Passive=>ZM_UPLOAD_FTP_PASSIVE, Debug=>ZM_UPLOAD_FTP_DEBUG );
+		if ( !$ftp )
+		{
+			warn( "Can't create ftp connection: $@" );
+			return();
+		}
+
+		$ftp->login( ZM_UPLOAD_FTP_USER, ZM_UPLOAD_FTP_PASS ) or warn( "FTP - Can't login" );
+		$ftp->binary() or warn( "FTP - Can't go binary" );
+		$ftp->cwd( ZM_UPLOAD_FTP_REM_DIR ) or warn( "FTP - Can't cwd" );
+		$ftp->put( $arch_file ) or warn( "FTP - Can't upload '$arch_file'" );
+		$ftp->quit() or warn( "FTP - Can't quit" );
+		unlink( $arch_file );
+		my $sql = "update Events set Uploaded = 1 where Id = ?";
+		my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
+		my $res = $sth->execute( $event->{Id} ) or die( "Can't execute '$sql': ".$sth->errstr() );
+	}
+}
+
+sub sendEmail
+{
+	my $filter = shift;
+	my $event = shift;
+
+	if ( !ZM_FROM_EMAIL )
+	{
+		warn( "No 'from' email address defined, not sending email" );
+		return;
+	}
+	if ( !ZM_EMAIL_ADDRESS )
+	{
+		warn( "No email address defined, not sending email" );
+		return;
+	}
+
+	Info( "Creating notification email\n" );
+
+	my $subject = substituteTags( $email_subject, $filter, $event );
+	my @attachments;
+	my $body = substituteTags( $email_body, $filter, $event, \@attachments );
+
+	Info( "Sending notification email '$subject'\n" );
+
+	eval
+	{
+		if ( ZM_NEW_MAIL_MODULES )
+		{
+			### Create the multipart container
+			my $mail = MIME::Lite->new (
+				From => ZM_FROM_EMAIL,
+				To => ZM_EMAIL_ADDRESS,
+				Subject => $subject,
+				Type => "multipart/mixed"
+			);
+			### Add the text message part
+			$mail->attach (
+				Type => "TEXT",
+				Data => $body
+			);
+			### Add the attachments
+			foreach my $attachment ( @attachments )
+			{
+				Info( "Attaching '$attachment->{path}\n" );
+				$mail->attach(
+					Path => $attachment->{path},
+					Type => $attachment->{type},
+					Disposition => "attachment"
+				);
+			}
+			### Send the Message
+			MIME::Lite->send( "smtp", ZM_EMAIL_HOST, Timeout=>60 );
+			$mail->send();
+        } 
+		else
+		{
+			my $mail = MIME::Entity->build(
+				From => ZM_FROM_EMAIL,
+				To => ZM_EMAIL_ADDRESS,
+				Subject => $subject,
+				Type => (($body=~/<html>/)?'text/html':'text/plain'),
+				Data => $body
+			);
+
+			foreach my $attachment ( @attachments )
+			{
+				Info( "Attaching '$attachment->{path}\n" );
+				$mail->attach(
+					Path => $attachment->{path},
+					Type => $attachment->{type},
+					Encoding => "base64"
+				);
+			}
+			$mail->smtpsend( Host => ZM_EMAIL_HOST, MailFrom => ZM_FROM_EMAIL );
+		}
+	};
+	if ( $@ )
+	{
+		warn( "Can't send email: $@" );
+		return();
+	}
+	else
+	{
+		Info( "Notification email sent\n" );
+	}
+	my $sql = "update Events set Emailed = 1 where Id = ?";
+	my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
+	my $res = $sth->execute( $event->{Id} ) or die( "Can't execute '$sql': ".$sth->errstr() );
+}
+
+sub sendMessage
+{
+	my $filter = shift;
+	my $event = shift;
+
+	if ( !ZM_FROM_EMAIL )
+	{
+		warn( "No 'from' email address defined, not sending message" );
+		return;
+	}
+	if ( !ZM_MESSAGE_ADDRESS )
+	{
+		warn( "No message address defined, not sending message" );
+		return;
+	}
+
+	Info( "Creating notification message\n" );
+
+	my $subject = substituteTags( $message_subject, $filter, $event );
+	my @attachments;
+	my $body = substituteTags( $message_body, $filter, $event, \@attachments );
+
+	Info( "Sending notification message '$subject'\n" );
+
+	eval
+	{
+		if ( ZM_NEW_MAIL_MODULES )
+		{
+			### Create the multipart container
+			my $mail = MIME::Lite->new (
+				From => ZM_FROM_EMAIL,
+				To => ZM_EMAIL_ADDRESS,
+				Subject => $subject,
+				Type => "multipart/mixed"
+			);
+			### Add the text message part
+			$mail->attach (
+				Type => "TEXT",
+				Data => $body
+			);
+			### Add the attachments
+			foreach my $attachment ( @attachments )
+			{
+				Info( "Attaching '$attachment->{path}\n" );
+				$mail->attach(
+					Path => $attachment->{path},
+					Type => $attachment->{type},
+					Disposition => "attachment"
+				);
+			}
+			### Send the Message
+			MIME::Lite->send( "smtp", ZM_EMAIL_HOST, Timeout=>60 );
+			$mail->send();
+        } 
+		else
+		{
+			my $mail = MIME::Entity->build(
+				From => ZM_FROM_EMAIL,
+				To => ZM_MESSAGE_ADDRESS,
+				Subject => $subject,
+				Type => (($body=~/<html>/)?'text/html':'text/plain'),
+				Data => $body
+			);
+
+			foreach my $attachment ( @attachments )
+			{
+				Info( "Attaching '$attachment->{path}\n" );
+				$mail->attach(
+					Path => $attachment->{path},
+					Type => $attachment->{type},
+					Encoding => "base64"
+				);
+			}
+			$mail->smtpsend( Host => ZM_EMAIL_HOST, MailFrom => ZM_FROM_EMAIL );
+		}
+	};
+	if ( $@ )
+	{
+		warn( "Can't send email: $@" );
+		return();
+	}
+	else
+	{
+		Info( "Notification message sent\n" );
+	}
+	my $sql = "update Events set Messaged = 1 where Id = ?";
+	my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
+	my $res = $sth->execute( $event->{Id} ) or die( "Can't execute '$sql': ".$sth->errstr() );
+}
+
+sub substituteTags
+{
+	my $text = shift;
+	my $filter = shift;
+	my $event = shift;
+	my $attachments_ref = shift;
+
+	# First we'd better check what we need to get
+	# We have a filter and an event, do we need any more
+	# monitor information?
+	my $need_monitor = $text =~ /%(?:MET|MEH|MED|MEW|MEN|MEA)%/;
+
+	my $monitor = {};
+	if ( $need_monitor )
+	{
+		my $db_now = strftime( "%Y-%m-%d %H:%M:%S", localtime() );
+		my $sql = "select M.Id, count(E.Id) as EventCount, count(if(E.Archived,1,NULL)) as ArchEventCount, count(if(E.StartTime>'$db_now' - INTERVAL 1 HOUR && E.Archived = 0,1,NULL)) as HourEventCount, count(if(E.StartTime>'$db_now' - INTERVAL 1 DAY && E.Archived = 0,1,NULL)) as DayEventCount, count(if(E.StartTime>'$db_now' - INTERVAL 7 DAY && E.Archived = 0,1,NULL)) as WeekEventCount, count(if(E.StartTime>'$db_now' - INTERVAL 1 MONTH && E.Archived = 0,1,NULL)) as MonthEventCount from Monitors as M left join Events as E on E.MonitorId = M.Id where MonitorId = ? group by E.MonitorId order by Id";
+		my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
+		my $res = $sth->execute( $event->{MonitorId} ) or die( "Can't execute '$sql': ".$sth->errstr() );
+		$monitor = $sth->fetchrow_hashref();
+		$sth->finish();
+		return() if ( !$monitor );
+	}
+
+	# Do we need the image information too?
+	my $need_images = $text =~ /%(?:EPI1|EPIM|EI1|EIM)%/;
+	my $first_alarm_frame;
+	my $max_alarm_frame;
+	my $max_alarm_score = 0;
+	if ( $need_images )
+	{
+		my $sql = "select * from Frames where EventId = ? and Type = 'Alarm' order by FrameId";
+		my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
+		my $res = $sth->execute( $event->{Id} ) or die( "Can't execute '$sql': ".$sth->errstr() );
+		while( my $frame = $sth->fetchrow_hashref() )
+		{
+			if ( !$first_alarm_frame )
+			{
+				$first_alarm_frame = $frame;
+			}
+			if ( $frame->{Score} > $max_alarm_score )
+			{
+				$max_alarm_frame = $frame;
+				$max_alarm_score = $frame->{Score};
+			}
+		}
+		$sth->finish();
+	}
+
+	my $url = ZM_URL;
+	$text =~ s/%ZP%/$url/g;
+	$text =~ s/%MN%/$event->{MonitorName}/g;
+	$text =~ s/%MET%/$monitor->{EventCount}/g;
+	$text =~ s/%MEH%/$monitor->{HourEventCount}/g;
+	$text =~ s/%MED%/$monitor->{DayEventCount}/g;
+	$text =~ s/%MEW%/$monitor->{WeekEventCount}/g;
+	$text =~ s/%MEM%/$monitor->{MonthEventCount}/g;
+	$text =~ s/%MEA%/$monitor->{ArchEventCount}/g;
+	$text =~ s/%MP%/$url?view=watch&mid=$event->{MonitorId}/g;
+	$text =~ s/%MPS%/$url?view=watchfeed&mid=$event->{MonitorId}&mode=stream/g;
+	$text =~ s/%MPI%/$url?view=watchfeed&mid=$event->{MonitorId}&mode=still/g;
+	$text =~ s/%EP%/$url?view=event&mid=$event->{MonitorId}&eid=$event->{Id}/g;
+	$text =~ s/%EPS%/$url?view=event&mode=stream&mid=$event->{MonitorId}&eid=$event->{Id}/g;
+	$text =~ s/%EPI%/$url?view=event&mode=still&mid=$event->{MonitorId}&eid=$event->{Id}/g;
+	$text =~ s/%EI%/$event->{Id}/g;
+	$text =~ s/%EN%/$event->{Name}/g;
+	$text =~ s/%ET%/$event->{StartTime}/g;
+	$text =~ s/%ED%/$event->{Length}/g;
+	$text =~ s/%EF%/$event->{Frames}/g;
+	$text =~ s/%EFA%/$event->{AlarmFrames}/g;
+	$text =~ s/%EST%/$event->{TotScore}/g;
+	$text =~ s/%ESA%/$event->{AvgScore}/g;
+	$text =~ s/%ESM%/$event->{MaxScore}/g;
+	if ( $first_alarm_frame )
+	{
+		$text =~ s/%EPI1%/$url?view=frame&mid=$event->{MonitorId}&eid=$event->{Id}&fid=$first_alarm_frame->{FrameId}/g;
+		$text =~ s/%EPIM%/$url?view=frame&mid=$event->{MonitorId}&eid=$event->{Id}&fid=$max_alarm_frame->{FrameId}/g;
+		if ( $attachments_ref && $text =~ s/%EI1%//g )
+		{
+			push( @$attachments_ref, { type=>"image/jpeg", path=>sprintf( "%d/%d/%0".ZM_EVENT_IMAGE_DIGITS."d-capture.jpg", $event->{MonitorId}, $event->{Id}, $first_alarm_frame->{FrameId} ) } );
+		}
+		if ( $attachments_ref && $text =~ s/%EIM%//g )
+		{
+			# Don't attach the same image twice
+			if ( !@$attachments_ref || ($first_alarm_frame->{FrameId} != $max_alarm_frame->{FrameId} ) )
+			{
+				push( @$attachments_ref, { type=>"image/jpeg", path=>sprintf( "%d/%d/%0".ZM_EVENT_IMAGE_DIGITS."d-capture.jpg", $event->{MonitorId}, $event->{Id}, $max_alarm_frame->{FrameId} ) } );
+			}
+		}
+	}
+	if ( $attachments_ref && ZM_OPT_MPEG ne "no" && $text =~ s/%EV%//g )
+	{
+		my $command = ZM_PATH_BIN."/zmvideo.pl -e $event->{Id}";
+		my $output = qx($command);
+		my $status = $? >> 8;
+		if ( $status == 0 )
+		{
+			chomp $output;
+			push( @$attachments_ref, { type=>"video/mpeg", path=>sprintf( "%d/%d/%s", $event->{MonitorId}, $event->{Id}, $output ) } );
+		}
+	}
+	$text =~ s/%FN%/$filter->{Name}/g;
+	( my $filter_name = $filter->{Name} ) =~ s/ /+/g;
+	$text =~ s/%FP%/$url?view=filter&mid=$event->{MonitorId}&filter_name=$filter_name/g;
+	
+	return( $text );
+}
--- zm-1.21.3.orig/zm.conf
+++ zm-1.21.3/zm.conf
@@ -0,0 +1,5 @@
+# ZoneMinder config
+ZM_DB_SERVER=localhost
+ZM_DB_NAME=zm
+ZM_DB_USER=zm
+ZM_DB_PASS=zmpass
--- zm-1.21.3.orig/config.sub
+++ zm-1.21.3/config.sub
@@ -0,0 +1,1569 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+timestamp='2005-04-22'
+
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine.  It does not imply ALL GNU software can.
+#
+# This file 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.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Please send patches to <config-patches@gnu.org>.  Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support.  The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+#	CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+#	CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+       $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit 0 ;;
+    --version | -v )
+       echo "$version" ; exit 0 ;;
+    --help | --h* | -h )
+       echo "$usage"; exit 0 ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help"
+       exit 1 ;;
+
+    *local*)
+       # First pass through any local machine types.
+       echo $1
+       exit 0;;
+
+    * )
+       break ;;
+  esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+    exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+    exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+  nto-qnx* | linux-gnu* | linux-dietlibc | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | \
+  kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*)
+    os=-$maybe_os
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+    ;;
+  *)
+    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+    if [ $basic_machine != $1 ]
+    then os=`echo $1 | sed 's/.*-/-/'`
+    else os=; fi
+    ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work.  We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+	-sun*os*)
+		# Prevent following clause from handling this invalid input.
+		;;
+	-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+	-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+	-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+	-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+	-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+	-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+	-apple | -axis | -knuth | -cray)
+		os=
+		basic_machine=$1
+		;;
+	-sim | -cisco | -oki | -wec | -winbond)
+		os=
+		basic_machine=$1
+		;;
+	-scout)
+		;;
+	-wrs)
+		os=-vxworks
+		basic_machine=$1
+		;;
+	-chorusos*)
+		os=-chorusos
+		basic_machine=$1
+		;;
+ 	-chorusrdb)
+ 		os=-chorusrdb
+		basic_machine=$1
+ 		;;
+	-hiux*)
+		os=-hiuxwe2
+		;;
+	-sco5)
+		os=-sco3.2v5
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco4)
+		os=-sco3.2v4
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2.[4-9]*)
+		os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2v[4-9]*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco*)
+		os=-sco3.2v2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-udk*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-isc)
+		os=-isc2.2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-clix*)
+		basic_machine=clipper-intergraph
+		;;
+	-isc*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-lynx*)
+		os=-lynxos
+		;;
+	-ptx*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+		;;
+	-windowsnt*)
+		os=`echo $os | sed -e 's/windowsnt/winnt/'`
+		;;
+	-psos*)
+		os=-psos
+		;;
+	-mint | -mint[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+	# Recognize the basic CPU types without company name.
+	# Some are omitted here because they have special meanings below.
+	1750a | 580 \
+	| a29k \
+	| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+	| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+	| am33_2.0 \
+	| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
+	| bfin \
+	| c4x | clipper \
+	| d10v | d30v | dlx | dsp16xx \
+	| fr30 | frv \
+	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+	| i370 | i860 | i960 | ia64 \
+	| ip2k | iq2000 \
+	| m32r | m32rle | m68000 | m68k | m88k | maxq | mcore \
+	| mips | mipsbe | mipseb | mipsel | mipsle \
+	| mips16 \
+	| mips64 | mips64el \
+	| mips64vr | mips64vrel \
+	| mips64orion | mips64orionel \
+	| mips64vr4100 | mips64vr4100el \
+	| mips64vr4300 | mips64vr4300el \
+	| mips64vr5000 | mips64vr5000el \
+	| mipsisa32 | mipsisa32el \
+	| mipsisa32r2 | mipsisa32r2el \
+	| mipsisa64 | mipsisa64el \
+	| mipsisa64r2 | mipsisa64r2el \
+	| mipsisa64sb1 | mipsisa64sb1el \
+	| mipsisa64sr71k | mipsisa64sr71kel \
+	| mipstx39 | mipstx39el \
+	| mn10200 | mn10300 \
+	| msp430 \
+	| ns16k | ns32k \
+	| openrisc | or32 \
+	| pdp10 | pdp11 | pj | pjl \
+	| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+	| pyramid \
+	| sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
+	| sh64 | sh64le \
+	| sparc | sparc64 | sparc64b | sparc86x | sparclet | sparclite \
+	| sparcv8 | sparcv9 | sparcv9b \
+	| strongarm \
+	| tahoe | thumb | tic4x | tic80 | tron \
+	| v850 | v850e \
+	| we32k \
+	| x86 | xscale | xscalee[bl] | xstormy16 | xtensa \
+	| z8k)
+		basic_machine=$basic_machine-unknown
+		;;
+	m6811 | m68hc11 | m6812 | m68hc12)
+		# Motorola 68HC11/12.
+		basic_machine=$basic_machine-unknown
+		os=-none
+		;;
+	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+		;;
+
+	# We use `pc' rather than `unknown'
+	# because (1) that's what they normally are, and
+	# (2) the word "unknown" tends to confuse beginning users.
+	i*86 | x86_64)
+	  basic_machine=$basic_machine-pc
+	  ;;
+	# Object if more than one company name word.
+	*-*-*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+	# Recognize the basic CPU types with company name.
+	580-* \
+	| a29k-* \
+	| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+	| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
+	| avr-* \
+	| bfin-* | bs2000-* \
+	| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
+	| clipper-* | craynv-* | cydra-* \
+	| d10v-* | d30v-* | dlx-* \
+	| elxsi-* \
+	| f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
+	| h8300-* | h8500-* \
+	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+	| i*86-* | i860-* | i960-* | ia64-* \
+	| ip2k-* | iq2000-* \
+	| m32r-* | m32rle-* \
+	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+	| m88110-* | m88k-* | maxq-* | mcore-* \
+	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+	| mips16-* \
+	| mips64-* | mips64el-* \
+	| mips64vr-* | mips64vrel-* \
+	| mips64orion-* | mips64orionel-* \
+	| mips64vr4100-* | mips64vr4100el-* \
+	| mips64vr4300-* | mips64vr4300el-* \
+	| mips64vr5000-* | mips64vr5000el-* \
+	| mipsisa32-* | mipsisa32el-* \
+	| mipsisa32r2-* | mipsisa32r2el-* \
+	| mipsisa64-* | mipsisa64el-* \
+	| mipsisa64r2-* | mipsisa64r2el-* \
+	| mipsisa64sb1-* | mipsisa64sb1el-* \
+	| mipsisa64sr71k-* | mipsisa64sr71kel-* \
+	| mipstx39-* | mipstx39el-* \
+	| mmix-* \
+	| msp430-* \
+	| none-* | np1-* | ns16k-* | ns32k-* \
+	| orion-* \
+	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
+	| pyramid-* \
+	| romp-* | rs6000-* \
+	| sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \
+	| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+	| sparc-* | sparc64-* | sparc64b-* | sparc86x-* | sparclet-* \
+	| sparclite-* \
+	| sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
+	| tahoe-* | thumb-* \
+	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+	| tron-* \
+	| v850-* | v850e-* | vax-* \
+	| we32k-* \
+	| x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \
+	| xstormy16-* | xtensa-* \
+	| ymp-* \
+	| z8k-*)
+		;;
+	# Recognize the various machine names and aliases which stand
+	# for a CPU type and a company and sometimes even an OS.
+	386bsd)
+		basic_machine=i386-unknown
+		os=-bsd
+		;;
+	3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+		basic_machine=m68000-att
+		;;
+	3b*)
+		basic_machine=we32k-att
+		;;
+	a29khif)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+    	abacus)
+		basic_machine=abacus-unknown
+		;;
+	adobe68k)
+		basic_machine=m68010-adobe
+		os=-scout
+		;;
+	alliant | fx80)
+		basic_machine=fx80-alliant
+		;;
+	altos | altos3068)
+		basic_machine=m68k-altos
+		;;
+	am29k)
+		basic_machine=a29k-none
+		os=-bsd
+		;;
+	amd64)
+		basic_machine=x86_64-pc
+		;;
+	amd64-*)
+		basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	amdahl)
+		basic_machine=580-amdahl
+		os=-sysv
+		;;
+	amiga | amiga-*)
+		basic_machine=m68k-unknown
+		;;
+	amigaos | amigados)
+		basic_machine=m68k-unknown
+		os=-amigaos
+		;;
+	amigaunix | amix)
+		basic_machine=m68k-unknown
+		os=-sysv4
+		;;
+	apollo68)
+		basic_machine=m68k-apollo
+		os=-sysv
+		;;
+	apollo68bsd)
+		basic_machine=m68k-apollo
+		os=-bsd
+		;;
+	aux)
+		basic_machine=m68k-apple
+		os=-aux
+		;;
+	balance)
+		basic_machine=ns32k-sequent
+		os=-dynix
+		;;
+	c90)
+		basic_machine=c90-cray
+		os=-unicos
+		;;
+	convex-c1)
+		basic_machine=c1-convex
+		os=-bsd
+		;;
+	convex-c2)
+		basic_machine=c2-convex
+		os=-bsd
+		;;
+	convex-c32)
+		basic_machine=c32-convex
+		os=-bsd
+		;;
+	convex-c34)
+		basic_machine=c34-convex
+		os=-bsd
+		;;
+	convex-c38)
+		basic_machine=c38-convex
+		os=-bsd
+		;;
+	cray | j90)
+		basic_machine=j90-cray
+		os=-unicos
+		;;
+	craynv)
+		basic_machine=craynv-cray
+		os=-unicosmp
+		;;
+	cr16c)
+		basic_machine=cr16c-unknown
+		os=-elf
+		;;
+	crds | unos)
+		basic_machine=m68k-crds
+		;;
+	crisv32 | crisv32-* | etraxfs*)
+		basic_machine=crisv32-axis
+		;;
+	cris | cris-* | etrax*)
+		basic_machine=cris-axis
+		;;
+	crx)
+		basic_machine=crx-unknown
+		os=-elf
+		;;
+	da30 | da30-*)
+		basic_machine=m68k-da30
+		;;
+	decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+		basic_machine=mips-dec
+		;;
+	decsystem10* | dec10*)
+		basic_machine=pdp10-dec
+		os=-tops10
+		;;
+	decsystem20* | dec20*)
+		basic_machine=pdp10-dec
+		os=-tops20
+		;;
+	delta | 3300 | motorola-3300 | motorola-delta \
+	      | 3300-motorola | delta-motorola)
+		basic_machine=m68k-motorola
+		;;
+	delta88)
+		basic_machine=m88k-motorola
+		os=-sysv3
+		;;
+	djgpp)
+		basic_machine=i586-pc
+		os=-msdosdjgpp
+		;;
+	dpx20 | dpx20-*)
+		basic_machine=rs6000-bull
+		os=-bosx
+		;;
+	dpx2* | dpx2*-bull)
+		basic_machine=m68k-bull
+		os=-sysv3
+		;;
+	ebmon29k)
+		basic_machine=a29k-amd
+		os=-ebmon
+		;;
+	elxsi)
+		basic_machine=elxsi-elxsi
+		os=-bsd
+		;;
+	encore | umax | mmax)
+		basic_machine=ns32k-encore
+		;;
+	es1800 | OSE68k | ose68k | ose | OSE)
+		basic_machine=m68k-ericsson
+		os=-ose
+		;;
+	fx2800)
+		basic_machine=i860-alliant
+		;;
+	genix)
+		basic_machine=ns32k-ns
+		;;
+	gmicro)
+		basic_machine=tron-gmicro
+		os=-sysv
+		;;
+	go32)
+		basic_machine=i386-pc
+		os=-go32
+		;;
+	h3050r* | hiux*)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	h8300hms)
+		basic_machine=h8300-hitachi
+		os=-hms
+		;;
+	h8300xray)
+		basic_machine=h8300-hitachi
+		os=-xray
+		;;
+	h8500hms)
+		basic_machine=h8500-hitachi
+		os=-hms
+		;;
+	harris)
+		basic_machine=m88k-harris
+		os=-sysv3
+		;;
+	hp300-*)
+		basic_machine=m68k-hp
+		;;
+	hp300bsd)
+		basic_machine=m68k-hp
+		os=-bsd
+		;;
+	hp300hpux)
+		basic_machine=m68k-hp
+		os=-hpux
+		;;
+	hp3k9[0-9][0-9] | hp9[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k2[0-9][0-9] | hp9k31[0-9])
+		basic_machine=m68000-hp
+		;;
+	hp9k3[2-9][0-9])
+		basic_machine=m68k-hp
+		;;
+	hp9k6[0-9][0-9] | hp6[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k7[0-79][0-9] | hp7[0-79][0-9])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k78[0-9] | hp78[0-9])
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][13679] | hp8[0-9][13679])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][0-9] | hp8[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hppa-next)
+		os=-nextstep3
+		;;
+	hppaosf)
+		basic_machine=hppa1.1-hp
+		os=-osf
+		;;
+	hppro)
+		basic_machine=hppa1.1-hp
+		os=-proelf
+		;;
+	i370-ibm* | ibm*)
+		basic_machine=i370-ibm
+		;;
+# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
+	i*86v32)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv32
+		;;
+	i*86v4*)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv4
+		;;
+	i*86v)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv
+		;;
+	i*86sol2)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-solaris2
+		;;
+	i386mach)
+		basic_machine=i386-mach
+		os=-mach
+		;;
+	i386-vsta | vsta)
+		basic_machine=i386-unknown
+		os=-vsta
+		;;
+	iris | iris4d)
+		basic_machine=mips-sgi
+		case $os in
+		    -irix*)
+			;;
+		    *)
+			os=-irix4
+			;;
+		esac
+		;;
+	isi68 | isi)
+		basic_machine=m68k-isi
+		os=-sysv
+		;;
+	m88k-omron*)
+		basic_machine=m88k-omron
+		;;
+	magnum | m3230)
+		basic_machine=mips-mips
+		os=-sysv
+		;;
+	merlin)
+		basic_machine=ns32k-utek
+		os=-sysv
+		;;
+	mingw32)
+		basic_machine=i386-pc
+		os=-mingw32
+		;;
+	miniframe)
+		basic_machine=m68000-convergent
+		;;
+	*mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+	mips3*-*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+		;;
+	mips3*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+		;;
+	monitor)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	morphos)
+		basic_machine=powerpc-unknown
+		os=-morphos
+		;;
+	msdos)
+		basic_machine=i386-pc
+		os=-msdos
+		;;
+	mvs)
+		basic_machine=i370-ibm
+		os=-mvs
+		;;
+	ncr3000)
+		basic_machine=i486-ncr
+		os=-sysv4
+		;;
+	netbsd386)
+		basic_machine=i386-unknown
+		os=-netbsd
+		;;
+	netwinder)
+		basic_machine=armv4l-rebel
+		os=-linux
+		;;
+	news | news700 | news800 | news900)
+		basic_machine=m68k-sony
+		os=-newsos
+		;;
+	news1000)
+		basic_machine=m68030-sony
+		os=-newsos
+		;;
+	news-3600 | risc-news)
+		basic_machine=mips-sony
+		os=-newsos
+		;;
+	necv70)
+		basic_machine=v70-nec
+		os=-sysv
+		;;
+	next | m*-next )
+		basic_machine=m68k-next
+		case $os in
+		    -nextstep* )
+			;;
+		    -ns2*)
+		      os=-nextstep2
+			;;
+		    *)
+		      os=-nextstep3
+			;;
+		esac
+		;;
+	nh3000)
+		basic_machine=m68k-harris
+		os=-cxux
+		;;
+	nh[45]000)
+		basic_machine=m88k-harris
+		os=-cxux
+		;;
+	nindy960)
+		basic_machine=i960-intel
+		os=-nindy
+		;;
+	mon960)
+		basic_machine=i960-intel
+		os=-mon960
+		;;
+	nonstopux)
+		basic_machine=mips-compaq
+		os=-nonstopux
+		;;
+	np1)
+		basic_machine=np1-gould
+		;;
+	nsr-tandem)
+		basic_machine=nsr-tandem
+		;;
+	op50n-* | op60c-*)
+		basic_machine=hppa1.1-oki
+		os=-proelf
+		;;
+	or32 | or32-*)
+		basic_machine=or32-unknown
+		os=-coff
+		;;
+	os400)
+		basic_machine=powerpc-ibm
+		os=-os400
+		;;
+	OSE68000 | ose68000)
+		basic_machine=m68000-ericsson
+		os=-ose
+		;;
+	os68k)
+		basic_machine=m68k-none
+		os=-os68k
+		;;
+	pa-hitachi)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	paragon)
+		basic_machine=i860-intel
+		os=-osf
+		;;
+	pbd)
+		basic_machine=sparc-tti
+		;;
+	pbb)
+		basic_machine=m68k-tti
+		;;
+	pc532 | pc532-*)
+		basic_machine=ns32k-pc532
+		;;
+	pentium | p5 | k5 | k6 | nexgen | viac3)
+		basic_machine=i586-pc
+		;;
+	pentiumpro | p6 | 6x86 | athlon | athlon_*)
+		basic_machine=i686-pc
+		;;
+	pentiumii | pentium2 | pentiumiii | pentium3)
+		basic_machine=i686-pc
+		;;
+	pentium4)
+		basic_machine=i786-pc
+		;;
+	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+		basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumpro-* | p6-* | 6x86-* | athlon-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentium4-*)
+		basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pn)
+		basic_machine=pn-gould
+		;;
+	power)	basic_machine=power-ibm
+		;;
+	ppc)	basic_machine=powerpc-unknown
+		;;
+	ppc-*)	basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppcle | powerpclittle | ppc-le | powerpc-little)
+		basic_machine=powerpcle-unknown
+		;;
+	ppcle-* | powerpclittle-*)
+		basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64)	basic_machine=powerpc64-unknown
+		;;
+	ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+		basic_machine=powerpc64le-unknown
+		;;
+	ppc64le-* | powerpc64little-*)
+		basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ps2)
+		basic_machine=i386-ibm
+		;;
+	pw32)
+		basic_machine=i586-unknown
+		os=-pw32
+		;;
+	rom68k)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	rm[46]00)
+		basic_machine=mips-siemens
+		;;
+	rtpc | rtpc-*)
+		basic_machine=romp-ibm
+		;;
+	s390 | s390-*)
+		basic_machine=s390-ibm
+		;;
+	s390x | s390x-*)
+		basic_machine=s390x-ibm
+		;;
+	sa29200)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	sb1)
+		basic_machine=mipsisa64sb1-unknown
+		;;
+	sb1el)
+		basic_machine=mipsisa64sb1el-unknown
+		;;
+	sei)
+		basic_machine=mips-sei
+		os=-seiux
+		;;
+	sequent)
+		basic_machine=i386-sequent
+		;;
+	sh)
+		basic_machine=sh-hitachi
+		os=-hms
+		;;
+	sh64)
+		basic_machine=sh64-unknown
+		;;
+	sparclite-wrs | simso-wrs)
+		basic_machine=sparclite-wrs
+		os=-vxworks
+		;;
+	sps7)
+		basic_machine=m68k-bull
+		os=-sysv2
+		;;
+	spur)
+		basic_machine=spur-unknown
+		;;
+	st2000)
+		basic_machine=m68k-tandem
+		;;
+	stratus)
+		basic_machine=i860-stratus
+		os=-sysv4
+		;;
+	sun2)
+		basic_machine=m68000-sun
+		;;
+	sun2os3)
+		basic_machine=m68000-sun
+		os=-sunos3
+		;;
+	sun2os4)
+		basic_machine=m68000-sun
+		os=-sunos4
+		;;
+	sun3os3)
+		basic_machine=m68k-sun
+		os=-sunos3
+		;;
+	sun3os4)
+		basic_machine=m68k-sun
+		os=-sunos4
+		;;
+	sun4os3)
+		basic_machine=sparc-sun
+		os=-sunos3
+		;;
+	sun4os4)
+		basic_machine=sparc-sun
+		os=-sunos4
+		;;
+	sun4sol2)
+		basic_machine=sparc-sun
+		os=-solaris2
+		;;
+	sun3 | sun3-*)
+		basic_machine=m68k-sun
+		;;
+	sun4)
+		basic_machine=sparc-sun
+		;;
+	sun386 | sun386i | roadrunner)
+		basic_machine=i386-sun
+		;;
+	sv1)
+		basic_machine=sv1-cray
+		os=-unicos
+		;;
+	symmetry)
+		basic_machine=i386-sequent
+		os=-dynix
+		;;
+	t3e)
+		basic_machine=alphaev5-cray
+		os=-unicos
+		;;
+	t90)
+		basic_machine=t90-cray
+		os=-unicos
+		;;
+	tic54x | c54x*)
+		basic_machine=tic54x-unknown
+		os=-coff
+		;;
+	tic55x | c55x*)
+		basic_machine=tic55x-unknown
+		os=-coff
+		;;
+	tic6x | c6x*)
+		basic_machine=tic6x-unknown
+		os=-coff
+		;;
+	tx39)
+		basic_machine=mipstx39-unknown
+		;;
+	tx39el)
+		basic_machine=mipstx39el-unknown
+		;;
+	toad1)
+		basic_machine=pdp10-xkl
+		os=-tops20
+		;;
+	tower | tower-32)
+		basic_machine=m68k-ncr
+		;;
+	tpf)
+		basic_machine=s390x-ibm
+		os=-tpf
+		;;
+	udi29k)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	ultra3)
+		basic_machine=a29k-nyu
+		os=-sym1
+		;;
+	v810 | necv810)
+		basic_machine=v810-nec
+		os=-none
+		;;
+	vaxv)
+		basic_machine=vax-dec
+		os=-sysv
+		;;
+	vms)
+		basic_machine=vax-dec
+		os=-vms
+		;;
+	vpp*|vx|vx-*)
+		basic_machine=f301-fujitsu
+		;;
+	vxworks960)
+		basic_machine=i960-wrs
+		os=-vxworks
+		;;
+	vxworks68)
+		basic_machine=m68k-wrs
+		os=-vxworks
+		;;
+	vxworks29k)
+		basic_machine=a29k-wrs
+		os=-vxworks
+		;;
+	w65*)
+		basic_machine=w65-wdc
+		os=-none
+		;;
+	w89k-*)
+		basic_machine=hppa1.1-winbond
+		os=-proelf
+		;;
+	xbox)
+		basic_machine=i686-pc
+		os=-mingw32
+		;;
+	xps | xps100)
+		basic_machine=xps100-honeywell
+		;;
+	ymp)
+		basic_machine=ymp-cray
+		os=-unicos
+		;;
+	z8k-*-coff)
+		basic_machine=z8k-unknown
+		os=-sim
+		;;
+	none)
+		basic_machine=none-none
+		os=-none
+		;;
+
+# Here we handle the default manufacturer of certain CPU types.  It is in
+# some cases the only manufacturer, in others, it is the most popular.
+	w89k)
+		basic_machine=hppa1.1-winbond
+		;;
+	op50n)
+		basic_machine=hppa1.1-oki
+		;;
+	op60c)
+		basic_machine=hppa1.1-oki
+		;;
+	romp)
+		basic_machine=romp-ibm
+		;;
+	mmix)
+		basic_machine=mmix-knuth
+		;;
+	rs6000)
+		basic_machine=rs6000-ibm
+		;;
+	vax)
+		basic_machine=vax-dec
+		;;
+	pdp10)
+		# there are many clones, so DEC is not a safe bet
+		basic_machine=pdp10-unknown
+		;;
+	pdp11)
+		basic_machine=pdp11-dec
+		;;
+	we32k)
+		basic_machine=we32k-att
+		;;
+	sh3 | sh4 | sh[34]eb | sh[1234]le | sh[23]ele)
+		basic_machine=sh-unknown
+		;;
+	sh64)
+		basic_machine=sh64-unknown
+		;;
+	sparc | sparcv8 | sparcv9 | sparcv9b)
+		basic_machine=sparc-sun
+		;;
+	cydra)
+		basic_machine=cydra-cydrome
+		;;
+	orion)
+		basic_machine=orion-highlevel
+		;;
+	orion105)
+		basic_machine=clipper-highlevel
+		;;
+	mac | mpw | mac-mpw)
+		basic_machine=m68k-apple
+		;;
+	pmac | pmac-mpw)
+		basic_machine=powerpc-apple
+		;;
+	*-unknown)
+		# Make sure to match an already-canonicalized machine name.
+		;;
+	*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+	*-digital*)
+		basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+		;;
+	*-commodore*)
+		basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+		;;
+	*)
+		;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+        # First match some system type aliases
+        # that might get confused with valid system types.
+	# -solaris* is a basic system type, with this one exception.
+	-solaris1 | -solaris1.*)
+		os=`echo $os | sed -e 's|solaris1|sunos4|'`
+		;;
+	-solaris)
+		os=-solaris2
+		;;
+	-svr4*)
+		os=-sysv4
+		;;
+	-unixware*)
+		os=-sysv4.2uw
+		;;
+	-gnu/linux*)
+		os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+		;;
+	# First accept the basic system types.
+	# The portable systems comes first.
+	# Each alternative MUST END IN A *, to match a version number.
+	# -sysv* is not here because it comes later, after sysvr4.
+	-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+	      | -aos* \
+	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+	      | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* | -openbsd* \
+	      | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+	      | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+	      | -chorusos* | -chorusrdb* \
+	      | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+	      | -mingw32* | -linux-gnu* | -linux-uclibc* | -uxpv* | -beos* | -mpeix* | -udk* \
+	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+	      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly*)
+	# Remember, each alternative MUST END IN *, to match a version number.
+		;;
+	-qnx*)
+		case $basic_machine in
+		    x86-* | i*86-*)
+			;;
+		    *)
+			os=-nto$os
+			;;
+		esac
+		;;
+	-nto-qnx*)
+		;;
+	-nto*)
+		os=`echo $os | sed -e 's|nto|nto-qnx|'`
+		;;
+	-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+	      | -windows* | -osx | -abug | -netware* | -os9* | -beos* \
+	      | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+		;;
+	-mac*)
+		os=`echo $os | sed -e 's|mac|macos|'`
+		;;
+	-linux-dietlibc)
+		os=-linux-dietlibc
+		;;
+	-linux*)
+		os=`echo $os | sed -e 's|linux|linux-gnu|'`
+		;;
+	-sunos5*)
+		os=`echo $os | sed -e 's|sunos5|solaris2|'`
+		;;
+	-sunos6*)
+		os=`echo $os | sed -e 's|sunos6|solaris3|'`
+		;;
+	-opened*)
+		os=-openedition
+		;;
+        -os400*)
+		os=-os400
+		;;
+	-wince*)
+		os=-wince
+		;;
+	-osfrose*)
+		os=-osfrose
+		;;
+	-osf*)
+		os=-osf
+		;;
+	-utek*)
+		os=-bsd
+		;;
+	-dynix*)
+		os=-bsd
+		;;
+	-acis*)
+		os=-aos
+		;;
+	-atheos*)
+		os=-atheos
+		;;
+	-syllable*)
+		os=-syllable
+		;;
+	-386bsd)
+		os=-bsd
+		;;
+	-ctix* | -uts*)
+		os=-sysv
+		;;
+	-nova*)
+		os=-rtmk-nova
+		;;
+	-ns2 )
+		os=-nextstep2
+		;;
+	-nsk*)
+		os=-nsk
+		;;
+	# Preserve the version number of sinix5.
+	-sinix5.*)
+		os=`echo $os | sed -e 's|sinix|sysv|'`
+		;;
+	-sinix*)
+		os=-sysv4
+		;;
+        -tpf*)
+		os=-tpf
+		;;
+	-triton*)
+		os=-sysv3
+		;;
+	-oss*)
+		os=-sysv3
+		;;
+	-svr4)
+		os=-sysv4
+		;;
+	-svr3)
+		os=-sysv3
+		;;
+	-sysvr4)
+		os=-sysv4
+		;;
+	# This must come after -sysvr4.
+	-sysv*)
+		;;
+	-ose*)
+		os=-ose
+		;;
+	-es1800*)
+		os=-ose
+		;;
+	-xenix)
+		os=-xenix
+		;;
+	-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+		os=-mint
+		;;
+	-aros*)
+		os=-aros
+		;;
+	-kaos*)
+		os=-kaos
+		;;
+	-zvmoe)
+		os=-zvmoe
+		;;
+	-none)
+		;;
+	*)
+		# Get rid of the `-' at the beginning of $os.
+		os=`echo $os | sed 's/[^-]*-//'`
+		echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+		exit 1
+		;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system.  Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+	*-acorn)
+		os=-riscix1.2
+		;;
+	arm*-rebel)
+		os=-linux
+		;;
+	arm*-semi)
+		os=-aout
+		;;
+    c4x-* | tic4x-*)
+        os=-coff
+        ;;
+	# This must come before the *-dec entry.
+	pdp10-*)
+		os=-tops20
+		;;
+	pdp11-*)
+		os=-none
+		;;
+	*-dec | vax-*)
+		os=-ultrix4.2
+		;;
+	m68*-apollo)
+		os=-domain
+		;;
+	i386-sun)
+		os=-sunos4.0.2
+		;;
+	m68000-sun)
+		os=-sunos3
+		# This also exists in the configure program, but was not the
+		# default.
+		# os=-sunos4
+		;;
+	m68*-cisco)
+		os=-aout
+		;;
+	mips*-cisco)
+		os=-elf
+		;;
+	mips*-*)
+		os=-elf
+		;;
+	or32-*)
+		os=-coff
+		;;
+	*-tti)	# must be before sparc entry or we get the wrong os.
+		os=-sysv3
+		;;
+	sparc-* | *-sun)
+		os=-sunos4.1.1
+		;;
+	*-be)
+		os=-beos
+		;;
+	*-ibm)
+		os=-aix
+		;;
+    	*-knuth)
+		os=-mmixware
+		;;
+	*-wec)
+		os=-proelf
+		;;
+	*-winbond)
+		os=-proelf
+		;;
+	*-oki)
+		os=-proelf
+		;;
+	*-hp)
+		os=-hpux
+		;;
+	*-hitachi)
+		os=-hiux
+		;;
+	i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+		os=-sysv
+		;;
+	*-cbm)
+		os=-amigaos
+		;;
+	*-dg)
+		os=-dgux
+		;;
+	*-dolphin)
+		os=-sysv3
+		;;
+	m68k-ccur)
+		os=-rtu
+		;;
+	m88k-omron*)
+		os=-luna
+		;;
+	*-next )
+		os=-nextstep
+		;;
+	*-sequent)
+		os=-ptx
+		;;
+	*-crds)
+		os=-unos
+		;;
+	*-ns)
+		os=-genix
+		;;
+	i370-*)
+		os=-mvs
+		;;
+	*-next)
+		os=-nextstep3
+		;;
+	*-gould)
+		os=-sysv
+		;;
+	*-highlevel)
+		os=-bsd
+		;;
+	*-encore)
+		os=-bsd
+		;;
+	*-sgi)
+		os=-irix
+		;;
+	*-siemens)
+		os=-sysv4
+		;;
+	*-masscomp)
+		os=-rtu
+		;;
+	f30[01]-fujitsu | f700-fujitsu)
+		os=-uxpv
+		;;
+	*-rom68k)
+		os=-coff
+		;;
+	*-*bug)
+		os=-coff
+		;;
+	*-apple)
+		os=-macos
+		;;
+	*-atari*)
+		os=-mint
+		;;
+	*)
+		os=-none
+		;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer.  We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+	*-unknown)
+		case $os in
+			-riscix*)
+				vendor=acorn
+				;;
+			-sunos*)
+				vendor=sun
+				;;
+			-aix*)
+				vendor=ibm
+				;;
+			-beos*)
+				vendor=be
+				;;
+			-hpux*)
+				vendor=hp
+				;;
+			-mpeix*)
+				vendor=hp
+				;;
+			-hiux*)
+				vendor=hitachi
+				;;
+			-unos*)
+				vendor=crds
+				;;
+			-dgux*)
+				vendor=dg
+				;;
+			-luna*)
+				vendor=omron
+				;;
+			-genix*)
+				vendor=ns
+				;;
+			-mvs* | -opened*)
+				vendor=ibm
+				;;
+			-os400*)
+				vendor=ibm
+				;;
+			-ptx*)
+				vendor=sequent
+				;;
+			-tpf*)
+				vendor=ibm
+				;;
+			-vxsim* | -vxworks* | -windiss*)
+				vendor=wrs
+				;;
+			-aux*)
+				vendor=apple
+				;;
+			-hms*)
+				vendor=hitachi
+				;;
+			-mpw* | -macos*)
+				vendor=apple
+				;;
+			-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+				vendor=atari
+				;;
+			-vos*)
+				vendor=stratus
+				;;
+		esac
+		basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+		;;
+esac
+
+echo $basic_machine$os
+exit 0
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
--- zm-1.21.3.orig/web/zm_config.php
+++ zm-1.21.3/web/zm_config.php
@@ -0,0 +1,190 @@
+<?php
+//
+// ZoneMinder web configuration file, $Date: 2005/05/22 17:44:15 $, $Revision: 1.66 $
+// Copyright (C) 2003, 2004, 2005  Philip Coombes
+//
+// 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.
+//
+
+// This section contains options substituted by the zmconfig.pl utility, do not edit these directly
+//
+define( "ZM_VERSION", "1.21.3" );	// ZoneMinder version number, autogenerated do not change (from zmconfig)
+define( "ZM_CONFIG", "/etc/zm/zm.conf" );	// Path to the ZoneMinder config file, autogenerated do not change (from zmconfig)
+define( "ZM_PATH_BIN", "/usr/bin" );	// Path to the ZoneMinder executables, autogenerated do not change (from zmconfig)
+define( "ZM_PATH_WEB", "/var/www/zm" );	// Path to the ZoneMinder web files, autogenerated do not change (from zmconfig)
+define( "ZM_PATH_CGI", "/usr/lib/cgi-bin" );	// Path to the ZoneMinder cgi files, autogenerated do not change (from zmconfig)
+
+$cfg = fopen( ZM_CONFIG, "r") or die("Could not open config file.");
+while ( !feof($cfg) )
+{
+	$str = fgets( $cfg, 256 );
+	if ( preg_match( '/^\s*$/', $str )) { continue; }
+	elseif ( preg_match( '/^\s*#/', $str )) { continue; }
+	elseif ( preg_match( '/^\s*([^=\s]+)\s*=\s*([^=\s]+)\s*$/', $str, $matches ))
+	{
+		if (( $matches[1] == "ZM_DB_SERVER") ||
+			( $matches[1] == "ZM_DB_NAME") ||
+			( $matches[1] == "ZM_DB_USER") ||
+			( $matches[1] == "ZM_DB_PASS"))
+		{
+			define( $matches[1], $matches[2] );
+		}
+	}
+}
+fclose( $cfg );
+
+// This section is options normally derived from other options or configuration
+//
+define( "ZMU_PATH", ZM_PATH_BIN."/zmu" );				// Local path to the ZoneMinder Utility
+
+// Alarm states
+//
+define( "STATE_IDLE", 0 );
+define( "STATE_PREALARM", 1 );
+define( "STATE_ALARM", 2 );
+define( "STATE_ALERT", 3 );
+define( "STATE_TAPE", 4 );
+
+// These are miscellaneous options you won't normally need to change
+//
+define( "MAX_EVENTS", 10 );								// The maximum number of events to show in the monitor event listing
+define( "RATE_SCALE", 100 );							// The additional scaling factor used to help get fractional rates in integer format
+define( "SCALE_SCALE", 100 );							// The additional scaling factor used to help get fractional scales in integer format
+define( "LEARN_MODE", false );							// Currently unimplemented, do not change
+define( 'DEVICE_WIDTH', 150 );							// Default device width for phones and handhelds
+define( 'DEVICE_HEIGHT', 150 );							// Default device height for phones and handhelds
+define( 'DEVICE_LINES', 10 );							// Default device lines for phones and handhelds
+
+require_once( 'zm_db.php' );
+loadConfig();
+
+switch ( $bandwidth )
+{
+	case "high" :
+	{
+		define( "ZM_WEB_REFRESH_MAIN", ZM_WEB_H_REFRESH_MAIN );		// How often (in seconds) the main console window refreshes
+		define( "ZM_WEB_REFRESH_CYCLE", ZM_WEB_H_REFRESH_CYCLE );	// How often the cycle watch windows swaps to the next monitor
+		define( "ZM_WEB_REFRESH_IMAGE", ZM_WEB_H_REFRESH_IMAGE );	// How often the watched image is refreshed (if not streaming)
+		define( "ZM_WEB_REFRESH_STATUS", ZM_WEB_H_REFRESH_STATUS );	// How often the little status frame refreshes itself in the watch window
+		define( "ZM_WEB_REFRESH_EVENTS", ZM_WEB_H_REFRESH_EVENTS );	// How often the event listing is refreshed in the watch window, only for recent events
+		define( "ZM_WEB_DEFAULT_SCALE", ZM_WEB_H_DEFAULT_SCALE );	// What the default scaling factor applied to 'live' or 'event' views is (%)
+		define( "ZM_WEB_DEFAULT_RATE", ZM_WEB_H_DEFAULT_RATE );		// What the default replay rate factor applied to 'event' views is (%)
+		define( "ZM_WEB_VIDEO_BITRATE", ZM_WEB_H_VIDEO_BITRATE );	// What the bitrate of any streamed video should be
+		define( "ZM_WEB_VIDEO_MAXFPS", ZM_WEB_H_VIDEO_MAXFPS );		// What the maximum frame rate of any streamed video should be
+		define( "ZM_WEB_IMAGE_SCALING", ZM_WEB_H_IMAGE_SCALING );	// Image scaling for thumbnails, bandwidth versus cpu in rescaling
+		break;
+	}
+	case "medium" : 
+	{
+		define( "ZM_WEB_REFRESH_MAIN", ZM_WEB_M_REFRESH_MAIN );		// How often (in seconds) the main console window refreshes
+		define( "ZM_WEB_REFRESH_CYCLE", ZM_WEB_M_REFRESH_CYCLE );	// How often the cycle watch windows swaps to the next monitor
+		define( "ZM_WEB_REFRESH_IMAGE", ZM_WEB_M_REFRESH_IMAGE );	// How often the watched image is refreshed (if not streaming)
+		define( "ZM_WEB_REFRESH_STATUS", ZM_WEB_M_REFRESH_STATUS );	// How often the little status frame refreshes itself in the watch window
+		define( "ZM_WEB_REFRESH_EVENTS", ZM_WEB_M_REFRESH_EVENTS );	// How often the event listing is refreshed in the watch window, only for recent events
+		define( "ZM_WEB_DEFAULT_SCALE", ZM_WEB_M_DEFAULT_SCALE );	// What the default scaling factor applied to 'live' or 'event' views is (%)
+		define( "ZM_WEB_DEFAULT_RATE", ZM_WEB_M_DEFAULT_RATE );		// What the default replay rate factor applied to 'event' views is (%)
+		define( "ZM_WEB_VIDEO_BITRATE", ZM_WEB_M_VIDEO_BITRATE );	// What the bitrate of any streamed video should be
+		define( "ZM_WEB_VIDEO_MAXFPS", ZM_WEB_M_VIDEO_MAXFPS );		// What the maximum frame rate of any streamed video should be
+		define( "ZM_WEB_IMAGE_SCALING", ZM_WEB_M_IMAGE_SCALING );	// Image scaling for thumbnails, bandwidth versus cpu in rescaling
+		break;
+	}
+	case "low" :
+	{
+		define( "ZM_WEB_REFRESH_MAIN", ZM_WEB_L_REFRESH_MAIN );		// How often (in seconds) the main console window refreshes
+		define( "ZM_WEB_REFRESH_CYCLE", ZM_WEB_L_REFRESH_CYCLE );	// How often the cycle watch windows swaps to the next monitor
+		define( "ZM_WEB_REFRESH_IMAGE", ZM_WEB_L_REFRESH_IMAGE );	// How often the watched image is refreshed (if not streaming)
+		define( "ZM_WEB_REFRESH_STATUS", ZM_WEB_L_REFRESH_STATUS );	// How often the little status frame refreshes itself in the watch window
+		define( "ZM_WEB_REFRESH_EVENTS", ZM_WEB_L_REFRESH_EVENTS );	// How often the event listing is refreshed in the watch window, only for recent events
+		define( "ZM_WEB_DEFAULT_SCALE", ZM_WEB_L_DEFAULT_SCALE );	// What the default scaling factor applied to 'live' or 'event' views is (%)
+		define( "ZM_WEB_DEFAULT_RATE", ZM_WEB_L_DEFAULT_RATE );		// What the default replay rate factor applied to 'event' views is (%)
+		define( "ZM_WEB_VIDEO_BITRATE", ZM_WEB_L_VIDEO_BITRATE );	// What the bitrate of any streamed video should be
+		define( "ZM_WEB_VIDEO_MAXFPS", ZM_WEB_L_VIDEO_MAXFPS );		// What the maximum frame rate of any streamed video should be
+		define( "ZM_WEB_IMAGE_SCALING", ZM_WEB_L_IMAGE_SCALING );	// Image scaling for thumbnails, bandwidth versus cpu in rescaling
+		break;
+	}
+	case "mobile" : // Very incomplete at present
+	{
+		define( "ZM_WEB_REFRESH_MAIN", ZM_WEB_P_REFRESH_MAIN );		// How often (in seconds) the main console window refreshes
+		define( "ZM_WEB_REFRESH_IMAGE", ZM_WEB_P_REFRESH_IMAGE );	// How often the watched image is refreshed (if not streaming)
+		break;
+	}
+}
+
+function loadConfig()
+{
+	global $config;
+	global $config_cats;
+
+	$config = array();
+	$config_cat = array();
+
+	$sql = "select * from Config order by Id asc";
+	$result = mysql_query( $sql );
+	if ( !$result )
+		echo mysql_error();
+	$monitors = array();
+	while( $row = mysql_fetch_assoc( $result ) )
+	{
+		define( $row['Name'], $row['Value'] );
+		$config[$row['Name']] = $row;
+		if ( !($config_cat = &$config_cats[$row['Category']]) )
+		{
+			$config_cats[$row['Category']] = array();
+			$config_cat = &$config_cats[$row['Category']];
+		}
+		$config_cat[$row['Name']] = $row;
+	}
+	//print_r( $config );
+	//print_r( $config_cats );
+}
+
+// Javascript window sizes
+$jws = array( 
+	'bandwidth' => array( 'w'=>200, 'h'=>90 ),
+	'console' => array( 'w'=>720, 'h'=>312 ),
+	'control' => array( 'w'=>380, 'h'=>480 ),
+	'controlcaps' => array( 'w'=>700, 'h'=>320 ),
+	'controlcap' => array( 'w'=>360, 'h'=>440 ),
+	'cycle' => array( 'w'=>16, 'h'=>32 ),
+	'device' => array( 'w'=>196, 'h'=>164 ),
+	'event' => array( 'w'=>96, 'h'=>168 ),
+	'eventdetail' => array( 'w'=>400, 'h'=>220 ),
+	'events' => array( 'w'=>720, 'h'=>480 ),
+	'export' => array( 'w'=>400, 'h'=>340 ),
+	'filter' => array( 'w'=>560, 'h'=>250 ),
+	'filtersave' => array( 'w'=>560, 'h'=>220 ),
+	'frames' => array( 'w'=>500, 'h'=>300 ),
+	'function' => array( 'w'=>248, 'h'=>92 ),
+	'groups' => array( 'w'=>400, 'h'=>220 ),
+	'image' => array( 'w'=>48, 'h'=>80 ),
+	'login' => array( 'w'=>720, 'h'=>480 ),
+	'logout' => array( 'w'=>200, 'h'=>100 ),
+	'monitor' => array( 'w'=>360, 'h'=>324 ),
+	'montage' => array( 'w'=>10, 'h'=>20 ),
+	'optionhelp' => array( 'w'=>320, 'h'=>240 ),
+	'options' => array( 'w'=>760, 'h'=>480 ),
+	'preset' => array( 'w'=>240, 'h'=>90 ),
+	'restarting' => array( 'w'=>250, 'h'=>150 ),
+	'settings' => array( 'w'=>200, 'h'=>225 ),
+	'state' => array( 'w'=>300, 'h'=>120 ),
+	'stats' => array( 'w'=>680, 'h'=>200 ),
+	'user' => array( 'w'=>280, 'h'=>340 ),
+	'version' => array( 'w'=>320, 'h'=>140 ),
+	'video' => array( 'w'=>100, 'h'=>80 ),
+	'watch' => array( 'w'=>96, 'h'=>384 ),
+	'zone' => array( 'w'=>360, 'h'=>500 ),
+	'zones' => array( 'w'=>72, 'h'=>232 ),
+);
+?>
--- zm-1.21.3.orig/zmconfig.pl.in
+++ zm-1.21.3/zmconfig.pl.in
@@ -41,6 +41,7 @@
 -(no)d, --(no)database                 - Whether the database has already been created, on by default 
 -(no)i, --(no)interactive              - Whether to include interactive configuration, on by default 
 -(no)r, --(no)reprocess                - Whether to reprocess files, on by default
+-c,     --configsql                    - Whether to generate db/zmconfig.sql, off by default
 ");
 	exit( -1 );
 }
@@ -50,8 +51,9 @@
 my $database = !undef;
 my $interactive = !undef;
 my $reprocess = !undef;
+my $configsql = undef;
 
-if ( !GetOptions( 'file=s'=>\$config_file, 'database!'=>\$database, 'interactive!'=>\$interactive, 'reprocess!'=>\$reprocess ) )
+if ( !GetOptions( 'file=s'=>\$config_file, 'database!'=>\$database, 'interactive!'=>\$interactive, 'reprocess!'=>\$reprocess, 'configsql!'=>\$configsql ) )
 {
 	Usage();
 }
@@ -1541,7 +1543,13 @@
 }
 
 saveOptionsToFile();
-saveOptionsToDB();
+if ( $configsql )
+{
+	saveOptionsToDBdump();
+}
+else {
+	saveOptionsToDB();
+}
 
 sub saveOptionsToFile
 {
@@ -1560,6 +1568,52 @@
 	close( CONFIG );
 }
 
+
+sub saveOptionsToDBdump
+{
+	print( "Saving config to DBdump\n" );
+	print( "Saving config to '$config_file.sql'\n" );
+	open( CONFIG, ">db/zmconfig.sql" ) or die( "Can't open options file: $!" );
+        print( CONFIG "delete from Config ; \n");
+
+	foreach my $option ( @options )
+	{
+		next if ( $option->{category} eq 'core' );
+		next if ( $option->{type} == $types{include} );
+		#print( $option->{name}."\n" ) if ( !$option->{category} );
+		$option->{db_type} = $option->{type}->{db_type};
+		$option->{db_hint} = $option->{type}->{hint};
+		$option->{db_pattern} = $option->{type}->{pattern};
+		$option->{db_format} = $option->{type}->{format};
+		if ( $option->{db_type} eq "boolean" )
+		{
+			$option->{db_value} = ($option->{value} eq "yes")?"1":"0";
+		}
+		else
+		{
+			$option->{db_value} = $option->{value};
+		}
+		if ( my $requires = $option->{requires} )
+		{
+			$option->{db_requires} = join( ";", map { my $value = $_->{value}; $value = ($value eq "yes")?1:0 if ( $options_hash{$_->{name}}->{db_type} eq "boolean" ); ( "$_->{name}=$value" ) } @$requires );
+		}
+		else
+		{
+		}
+		my $sql = "replace into Config set Id = ][$option->{id}][ , Name = ][$option->{name}][, Value = ][$option->{db_value}][, Type = ][$option->{db_type}][, DefaultValue = ][$option->{default}][, Hint = ][$option->{db_hint}][, Pattern = ][$option->{db_pattern}][, Format = ][$option->{db_format}][, Prompt = ][$option->{description}][, Help = ][$option->{help}][, Category = ][$option->{category}][, Readonly =  ][$option->{readonly}?1:0][, Requires = ][$option->{db_requires}][ ; \n" ;
+		$sql =~ s/\\/\\\\/g ;
+		$sql =~ s/[^\\](["'])/\\$1/g ;
+		$sql =~ s/\$2\"/\$2\\\'/g ;
+		$sql =~ s/\]\[/\'/g ;
+		print( CONFIG  $sql );
+	}
+
+	print( CONFIG "\n" );
+	chmod( 0600, $config_file ) or die( "Can't chmod '$config_file': $!" );
+	close( CONFIG );
+
+}
+
 sub saveOptionsToDB
 {
 	print( "Saving config to DB\n" );
--- zm-1.21.3.orig/debian/compat
+++ zm-1.21.3/debian/compat
@@ -0,0 +1 @@
+4
--- zm-1.21.3.orig/debian/init.d
+++ zm-1.21.3/debian/init.d
@@ -0,0 +1,61 @@
+#!/bin/sh
+# description: Control ZoneMinder as a Service
+# chkconfig: 2345 99 99
+
+# Source function library.
+#. /etc/rc.d/init.d/functions
+
+prog=ZoneMinder
+ZM_PATH_BIN="/usr/bin"
+command="$ZM_PATH_BIN/zmpkg.pl"
+
+start() {
+	echo -n "Starting $prog: "
+	$command start
+	RETVAL=$?
+	[ $RETVAL = 0 ] && echo success
+	[ $RETVAL != 0 ] && echo failure
+	echo
+	[ $RETVAL = 0 ] && touch /var/lock/zm
+	return $RETVAL
+}
+stop() {
+	echo -n $"Stopping $prog: "
+	$command stop
+	RETVAL=$?
+	[ $RETVAL = 0 ] && echo success
+	[ $RETVAL != 0 ] && echo failure
+	echo
+	[ $RETVAL = 0 ] && rm -f /var/lock/zm
+}
+status() {
+	result=`$command status`
+	if [ "$result" = "running" ]; then
+		echo "ZoneMinder is running"
+		RETVAL=0
+	else
+		echo "ZoneMinder is stopped"
+		RETVAL=1
+	fi
+}
+
+case "$1" in
+'start')
+	start
+	;;
+'stop')
+	stop
+	;;
+'restart' | 'force-reload')
+	stop
+	start
+	;;
+'status')
+	status
+	;;
+*)
+	echo "Usage: $0 { start | stop | restart | status | force-reload }"
+	RETVAL=1
+	;;
+esac
+exit $RETVAL
--- zm-1.21.3.orig/debian/zm.postrm
+++ zm-1.21.3/debian/zm.postrm
@@ -0,0 +1,34 @@
+#! /bin/sh
+
+export PATH=$PATH:/sbin:/usr/sbin:/bin:/usr/bin
+
+case "$1" in
+  purge|remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear)
+    echo 
+  ;;
+  *)
+    echo "postrm called with unknown argument '$1'" 1>&2
+    exit 1
+  ;;
+esac
+
+
+if [ "$1" = "purge" ]; then
+  # we remove the mysql user only after all his owned files are purged
+  rm -rf /var/lib/zm/
+  rm -rf /var/log/zm/
+  rm -rf /var/www/zm/
+
+  echo 'delete from user where User="zm";' | mysql --defaults-file=/etc/mysql/debian.cnf mysql 
+  echo 'delete from db where User="zm";' | mysql --defaults-file=/etc/mysql/debian.cnf mysql
+  mysqladmin --defaults-file=/etc/mysql/debian.cnf -f drop zm
+fi
+
+# Automatically added by dh_installinit
+if [ "$1" = "purge" ] ; then
+        update-rc.d zm remove >/dev/null || exit 0
+fi
+# End automatically added section
+
+exit 0
+
--- zm-1.21.3.orig/debian/changelog
+++ zm-1.21.3/debian/changelog
@@ -0,0 +1,69 @@
+zm (1.21.3-4) unstable; urgency=low
+
+  * patched zmconfig.pl to generate db/zmconfig.sql (eliminates needing mysql at build time)
+
+ -- Francois Gurin <matrix@spic.net>  Wed, 31 Aug 2005 22:12:30 -0400
+
+zm (1.21.3-3) unstable; urgency=low
+
+  * debug bump 
+
+ -- Francois Gurin <matrix@spic.net>  Wed, 10 Aug 2005 01:02:33 -0400
+
+zm (1.21.3-2) unstable; urgency=low
+
+  * add the db directory to include the zmalter*.sql files
+  * hardcoded ZM_PATH_BUILD to /usr/share/doc/zm so zmupdate.pl can find the db/ files
+
+ -- Francois Gurin <matrix@spic.net>  Tue,  9 Aug 2005 02:11:40 -0400
+
+zm (1.21.3-1) unstable; urgency=low
+
+  * New upstream release
+
+ -- Francois Gurin <matrix@spic.net>  Tue,  9 Aug 2005 00:58:39 -0400
+
+zm (1.21.0-5) unstable; urgency=low
+
+  * test compile against libjpeg-mmx-dev 
+
+ -- root <root@cecilia>  Mon,  9 May 2005 21:33:04 -0400
+
+zm (1.21.0-4) unstable; urgency=low
+
+  * really fixed postinst.  will only load database on initial install
+
+ -- Francois Gurin <matrix@spic.net>  Sat,  7 May 2005 03:35:50 -0400
+
+zm (1.21.0-3) unstable; urgency=low
+
+  * fixed preinst and postrm to not mess with the database unless it's a new install or purge respectively 
+  * added some of the build-deps
+  * added force-reload alias to restart in /etc/init.d/zm to make lintian happier
+
+ -- Francois Gurin <matrix@spic.net>  Fri,  6 May 2005 23:40:11 -0400
+
+zm (1.21.0-2) unstable; urgency=low
+
+  * package fixes
+
+ -- Francois Gurin <matrix@spic.net>  Fri,  6 May 2005 08:42:21 -0400
+
+zm (1.21.0-1) unstable; urgency=low
+
+  * New upstream release
+
+ -- root <matrix@spic.net>  Thu,  5 May 2005 17:32:14 -0400
+
+zm (1.20.1-2) unstable; urgency=low
+
+  * package fixes 
+
+ -- root <matrix@spic.net>  Wed,  9 Mar 2005 10:47:40 -0500
+
+zm (1.20.1-1) unstable; urgency=low
+
+  * Initial Release.
+
+ -- matrix <matrix@spic.net>  Mon,  7 Mar 2005 02:07:57 -0500
+
--- zm-1.21.3.orig/debian/dirs
+++ zm-1.21.3/debian/dirs
@@ -0,0 +1,3 @@
+var/log/zm
+var/lib/zm
+
--- zm-1.21.3.orig/debian/copyright
+++ zm-1.21.3/debian/copyright
@@ -0,0 +1,19 @@
+This package was debianized by Francois Gurin <matrix@spic.net> on
+Mon,  7 Mar 2005 02:07:57 -0500.
+
+It was downloaded from http://www.zoneminder.com/
+
+Copyright:
+Copyright (C) 2004  Philip Coombes
+
+Upstream Author: Philip Coombes <philip.coombes@zoneminder.com>
+
+License:
+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.
+
+On Debian GNU/Linux systems, the complete text of the GNU General
+Public License can be found in `/usr/share/common-licenses/GPL'.
+
--- zm-1.21.3.orig/debian/zm.postinst
+++ zm-1.21.3/debian/zm.postinst
@@ -0,0 +1,45 @@
+#! /bin/sh
+
+export PATH=$PATH:/sbin:/usr/sbin:/bin:/usr/bin
+
+
+case "$1" in
+  configure)
+    if [ "$2" == "" ] ; then 
+      echo 'grant select,insert,update,delete,alter,drop,create,index on zm.* to 'zm'@localhost identified by "zmpass";' | mysql --defaults-file=/etc/mysql/debian.cnf mysql
+      mysqladmin --defaults-file=/etc/mysql/debian.cnf -f create zm > /dev/null 2>&1
+      mysqladmin --defaults-file=/etc/mysql/debian.cnf -f reload > /dev/null 2>&1
+      cat /usr/share/doc/zm/db/zmschema.sql | mysql --defaults-file=/etc/mysql/debian.cnf zm > /dev/null 2>&1
+      cat /usr/share/doc/zm/db/zmconfig.sql | mysql --defaults-file=/etc/mysql/debian.cnf zm > /dev/null 2>&1
+      chown www-data.www-data /var/log/zm/ > /dev/null 2>&1
+      chown www-data.www-data /var/lib/zm/ > /dev/null 2>&1
+      chown www-data.www-data /var/www/zm/events/ > /dev/null 2>&1
+      chown www-data.www-data /var/www/zm/temp/ > /dev/null 2>&1
+      chown www-data.www-data /var/www/zm/sounds/ > /dev/null 2>&1
+      chown www-data.www-data /var/www/zm/images/ > /dev/null 2>&1
+      chown www-data.www-data /var/www/zm/temp/ > /dev/null 2>&1
+      chmod 4755 /usr/bin/zmfix > /dev/null 2>&1
+    fi
+  ;;
+
+  abort-upgrade|abort-remove|abort-configure)
+  ;;
+
+  *)
+    echo "postinst called with unknown argument '$1'" 1>&2
+    exit 1
+  ;;
+esac
+
+# Automatically added by dh_installinit
+if [ -x "/etc/init.d/zm" ]; then
+	update-rc.d zm defaults >/dev/null
+	if [ -x "`which invoke-rc.d 2>/dev/null`" ]; then
+		invoke-rc.d zm start || exit 0
+	else
+		/etc/init.d/zm start || exit 0
+	fi
+fi
+# End automatically added section
+
+exit 0
--- zm-1.21.3.orig/debian/rules
+++ zm-1.21.3/debian/rules
@@ -0,0 +1,108 @@
+#!/usr/bin/make -f
+# -*- makefile -*-
+# Sample debian/rules that uses debhelper.
+# This file was originally written by Joey Hess and Craig Small.
+# As a special exception, when this file is copied by dh-make into a
+# dh-make output file, you may use that output file without restriction.
+# This special exception was added by Craig Small in version 0.37 of dh-make.
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+
+# These are used for cross-compiling and for saving the configure script
+# from having to guess our platform (since we know it already)
+DEB_HOST_GNU_TYPE   ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
+DEB_BUILD_GNU_TYPE  ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
+
+
+CFLAGS = -Wall -g
+
+ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
+	CFLAGS += -O0
+else
+	CFLAGS += -O2
+endif
+
+config.status: configure
+	dh_testdir
+	# Add here commands to configure the package.
+	CFLAGS="$(CFLAGS)" ./configure --host=$(DEB_HOST_GNU_TYPE) --build=$(DEB_BUILD_GNU_TYPE) --sysconfdir=/etc/zm --prefix=/usr --mandir=\$${prefix}/share/man --infodir=\$${prefix}/share/info --with-mysql=/usr --with-ffmpeg=/usr --with-lame=/usr  --with-webdir=/var/www/zm --with-cgidir=/usr/lib/cgi-bin --with-webuser=www-data --with-webgroup=www-data
+
+	# NEEDFIX this shouldn't be done here and not like this
+	perl zmconfig.pl -noi -nod -c
+
+build: build-stamp
+
+build-stamp:  config.status
+	dh_testdir
+
+	# Add here commands to compile the package.
+	$(MAKE)
+	#docbook-to-man debian/zm.sgml > zm.1
+
+	touch build-stamp
+
+clean:
+	dh_testdir
+	dh_testroot
+	rm -f build-stamp 
+
+	# Add here commands to clean up after the build process.
+	-$(MAKE) distclean
+ifneq "$(wildcard /usr/share/misc/config.sub)" ""
+	cp -f /usr/share/misc/config.sub config.sub
+endif
+ifneq "$(wildcard /usr/share/misc/config.guess)" ""
+	cp -f /usr/share/misc/config.guess config.guess
+endif
+
+
+	dh_clean 
+
+install: build
+	dh_testdir
+	dh_testroot
+	dh_clean -k 
+	dh_installdirs
+
+	# Add here commands to install the package into debian/zm.
+	$(MAKE) install DESTDIR=$(CURDIR)/debian/zm
+
+# Build architecture-independent files here.
+binary-indep: build install
+# We have nothing to do by default.
+
+# Build architecture-dependent files here.
+binary-arch: build install
+	dh_testdir
+	dh_testroot
+	dh_installchangelogs ChangeLog
+	dh_installdocs
+	dh_installexamples
+#	dh_install
+#	dh_installmenu
+#	dh_installdebconf	
+#	dh_installlogrotate
+#	dh_installemacsen
+#	dh_installpam
+#	dh_installmime
+	dh_installinit
+#	dh_installcron
+#	dh_installinfo
+	dh_installman
+	dh_link
+	dh_strip
+	dh_compress -Xdb/ 
+	dh_fixperms
+#	dh_perl
+#	dh_python
+#	dh_makeshlibs
+	dh_installdeb
+	dh_shlibdeps
+	dh_gencontrol
+	dh_md5sums
+	dh_builddeb
+
+binary: binary-indep binary-arch
+.PHONY: build clean binary-indep binary-arch binary install 
--- zm-1.21.3.orig/debian/docs
+++ zm-1.21.3/debian/docs
@@ -0,0 +1,10 @@
+NEWS
+README
+README.html
+README.pdf
+README.rtf
+TODO
+zmconfig_eml.txt
+zmconfig_msg.txt
+zmconfig.txt
+db/
--- zm-1.21.3.orig/debian/control
+++ zm-1.21.3/debian/control
@@ -0,0 +1,18 @@
+Source: zm
+Section: unknown
+Priority: optional
+Maintainer: Francois Gurin <matrix@spic.net>
+Build-Depends: debhelper (>= 4.0.0), libavcodec2-dev, liblame-dev, libmysqlclient14-dev, libdbd-mysql-perl, libjpeg-mmx-dev | libjpeg62-dev
+Standards-Version: 3.6.1
+
+Package: zm
+Architecture: any
+Depends: ffmpeg, php4-mysql, php4, libdate-manip-perl, libmime-perl, libdbd-mysql-perl, mysql-server, mysql-client, ${shlibs:Depends}, ${misc:Depends}
+Description: Video security camera monitoring and analysis tool
+ ZoneMinder is intended for use in single or multi-camera video
+ security applications, including theft prevention and child or
+ family member or home monitoring and other care scenarios. It
+ supports capture, analysis, recording, and monitoring of video
+ data coming from one or more video or network cameras attached
+ to a Linux system. ZoneMinder also support web and semi-automatic
+ control of Pan/Tilt/Zoom cameras using a variety of protocols.
--- zm-1.21.3.orig/debian/README.Debian
+++ zm-1.21.3/debian/README.Debian
@@ -0,0 +1,50 @@
+zm for Debian
+-------------
+
+*****
+** THIS ZONEMINDER COMPILED AGAINST LIBJPEG-MMX 
+** libjpeg-mmx is not by supported upstream yet
+*****
+
+*****
+** If you see errors in your syslog like:
+**   zms[30117]: WAR [Attempt to fetch integer value for ZM_DYN_LAST_VERSION, actual type is string]
+**   zms[30117]: WAR [Attempt to fetch integer value for ZM_DYN_CURR_VERSION, actual type is string]
+**   zms[30117]: WAR [Attempt to fetch integer value for ZM_DYN_DB_VERSION, actual type is string]
+**   zms[30117]: ERR [Can't find config item 134]
+** then you should manually run zmupdate.pl to update to the latest schema
+** this will be automated RealSoonNow
+*****
+
+this is a rough debian package for zoneminder, and definitely does not do all 
+you'd expect from a typical debian package.
+
+everything should be in typical debian directories, and you should be able to
+just install and be done with it.  the db user & password is preset to zm/zmpass
+but at least everything should just work.
+
+to meet the dependencies I've compiled against you'll probably need to add the
+the following line to your /etc/apt/sources.list 
+	deb ftp://ftp.nerim.net/debian-marillat/ testing main
+
+once i figure out what all the actual build dependencies are, this will be 
+considerably more useful as a source package.
+
+There are a lot of ugly things done in postinst and postrm out of laziness
+
+you'll notice a zmdata.sql in here, this is a mysqldump of the zm database
+created by zmconfig.pl with defualts that work for me
+
+if you use the source package to create your own binary, be sure to overwrite
+the debian/zmdata.sql with an appropriate config or you'll be wondering what's
+going on
+
+after installation the package will create a user and database in mysql, as
+well as chown all the appropriate directories to www-data.
+
+when you purge (not remove, this behavior changed in 1.21.0-3) the package,
+it will delete the zm user and db from mysql.  It should be safe to upgrade
+and remove the package and keep your zoneminder data.
+
+ -- Francois Gurin <matrix@spic.net>, Tue,  9 Aug 2005 03:09:46 -0500
+
--- zm-1.21.3.orig/configure.in
+++ zm-1.21.3/configure.in
@@ -2,7 +2,8 @@
 AM_INIT_AUTOMAKE(zm,1.21.3)
 AM_CONFIG_HEADER(config.h)
 
-PATH_BUILD=`pwd`
+#PATH_BUILD=`pwd`
+PATH_BUILD=/usr/share/doc/zm
 AC_SUBST(PATH_BUILD)
 
 AC_ARG_WITH(mysql,
--- zm-1.21.3.orig/config.guess
+++ zm-1.21.3/config.guess
@@ -0,0 +1,1465 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+timestamp='2005-04-22'
+
+# This file 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.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Per Bothner <per@bothner.com>.
+# Please send patches to <config-patches@gnu.org>.  Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub.  If it succeeds, it prints the system name on stdout, and
+# exits with 0.  Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit build system type.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit 0 ;;
+    --version | -v )
+       echo "$version" ; exit 0 ;;
+    --help | --h* | -h )
+       echo "$usage"; exit 0 ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help" >&2
+       exit 1 ;;
+    * )
+       break ;;
+  esac
+done
+
+if test $# != 0; then
+  echo "$me: too many arguments$help" >&2
+  exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,)    echo "int x;" > $dummy.c ;
+	for c in cc gcc c89 c99 ; do
+	  if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+	     CC_FOR_BUILD="$c"; break ;
+	  fi ;
+	done ;
+	if test x"$CC_FOR_BUILD" = x ; then
+	  CC_FOR_BUILD=no_compiler_found ;
+	fi
+	;;
+ ,,*)   CC_FOR_BUILD=$CC ;;
+ ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
+esac ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+	PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+    *:NetBSD:*:*)
+	# NetBSD (nbsd) targets should (where applicable) match one or
+	# more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+	# *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
+	# switched to ELF, *-*-netbsd* would select the old
+	# object file format.  This provides both forward
+	# compatibility and a consistent mechanism for selecting the
+	# object file format.
+	#
+	# Note: NetBSD doesn't particularly care about the vendor
+	# portion of the name.  We always set it to "unknown".
+	sysctl="sysctl -n hw.machine_arch"
+	UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+	    /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+	case "${UNAME_MACHINE_ARCH}" in
+	    armeb) machine=armeb-unknown ;;
+	    arm*) machine=arm-unknown ;;
+	    sh3el) machine=shl-unknown ;;
+	    sh3eb) machine=sh-unknown ;;
+	    *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+	esac
+	# The Operating System including object format, if it has switched
+	# to ELF recently, or will in the future.
+	case "${UNAME_MACHINE_ARCH}" in
+	    arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+		eval $set_cc_for_build
+		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+			| grep __ELF__ >/dev/null
+		then
+		    # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+		    # Return netbsd for either.  FIX?
+		    os=netbsd
+		else
+		    os=netbsdelf
+		fi
+		;;
+	    *)
+	        os=netbsd
+		;;
+	esac
+	# The OS release
+	# Debian GNU/NetBSD machines have a different userland, and
+	# thus, need a distinct triplet. However, they do not need
+	# kernel version information, so it can be replaced with a
+	# suitable tag, in the style of linux-gnu.
+	case "${UNAME_VERSION}" in
+	    Debian*)
+		release='-gnu'
+		;;
+	    *)
+		release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+		;;
+	esac
+	# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+	# contains redundant information, the shorter form:
+	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+	echo "${machine}-${os}${release}"
+	exit 0 ;;
+    amd64:OpenBSD:*:*)
+	echo x86_64-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    amiga:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    cats:OpenBSD:*:*)
+	echo arm-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    hp300:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    luna88k:OpenBSD:*:*)
+    	echo m88k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mac68k:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    macppc:OpenBSD:*:*)
+	echo powerpc-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mvme68k:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mvme88k:OpenBSD:*:*)
+	echo m88k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mvmeppc:OpenBSD:*:*)
+	echo powerpc-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    sgi:OpenBSD:*:*)
+	echo mips64-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    sun3:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    *:OpenBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    *:ekkoBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+	exit 0 ;;
+    macppc:MirBSD:*:*)
+	echo powerppc-unknown-mirbsd${UNAME_RELEASE}
+	exit 0 ;;
+    *:MirBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+	exit 0 ;;
+    alpha:OSF1:*:*)
+	case $UNAME_RELEASE in
+	*4.0)
+		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+		;;
+	*5.*)
+	        UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+		;;
+	esac
+	# According to Compaq, /usr/sbin/psrinfo has been available on
+	# OSF/1 and Tru64 systems produced since 1995.  I hope that
+	# covers most systems running today.  This code pipes the CPU
+	# types through head -n 1, so we only detect the type of CPU 0.
+	ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+	case "$ALPHA_CPU_TYPE" in
+	    "EV4 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV4.5 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "LCA4 (21066/21068)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV5 (21164)")
+		UNAME_MACHINE="alphaev5" ;;
+	    "EV5.6 (21164A)")
+		UNAME_MACHINE="alphaev56" ;;
+	    "EV5.6 (21164PC)")
+		UNAME_MACHINE="alphapca56" ;;
+	    "EV5.7 (21164PC)")
+		UNAME_MACHINE="alphapca57" ;;
+	    "EV6 (21264)")
+		UNAME_MACHINE="alphaev6" ;;
+	    "EV6.7 (21264A)")
+		UNAME_MACHINE="alphaev67" ;;
+	    "EV6.8CB (21264C)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8AL (21264B)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8CX (21264D)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.9A (21264/EV69A)")
+		UNAME_MACHINE="alphaev69" ;;
+	    "EV7 (21364)")
+		UNAME_MACHINE="alphaev7" ;;
+	    "EV7.9 (21364A)")
+		UNAME_MACHINE="alphaev79" ;;
+	esac
+	# A Pn.n version is a patched version.
+	# A Vn.n version is a released version.
+	# A Tn.n version is a released field test version.
+	# A Xn.n version is an unreleased experimental baselevel.
+	# 1.2 uses "1.2" for uname -r.
+	echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+	exit 0 ;;
+    Alpha\ *:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# Should we change UNAME_MACHINE based on the output of uname instead
+	# of the specific Alpha model?
+	echo alpha-pc-interix
+	exit 0 ;;
+    21064:Windows_NT:50:3)
+	echo alpha-dec-winnt3.5
+	exit 0 ;;
+    Amiga*:UNIX_System_V:4.0:*)
+	echo m68k-unknown-sysv4
+	exit 0;;
+    *:[Aa]miga[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-amigaos
+	exit 0 ;;
+    *:[Mm]orph[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-morphos
+	exit 0 ;;
+    *:OS/390:*:*)
+	echo i370-ibm-openedition
+	exit 0 ;;
+    *:z/VM:*:*)
+	echo s390-ibm-zvmoe
+	exit 0 ;;
+    *:OS400:*:*)
+        echo powerpc-ibm-os400
+	exit 0 ;;
+    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+	echo arm-acorn-riscix${UNAME_RELEASE}
+	exit 0;;
+    SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+	echo hppa1.1-hitachi-hiuxmpp
+	exit 0;;
+    Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+	# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+	if test "`(/bin/universe) 2>/dev/null`" = att ; then
+		echo pyramid-pyramid-sysv3
+	else
+		echo pyramid-pyramid-bsd
+	fi
+	exit 0 ;;
+    NILE*:*:*:dcosx)
+	echo pyramid-pyramid-svr4
+	exit 0 ;;
+    DRS?6000:unix:4.0:6*)
+	echo sparc-icl-nx6
+	exit 0 ;;
+    DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
+	case `/usr/bin/uname -p` in
+	    sparc) echo sparc-icl-nx7 && exit 0 ;;
+	esac ;;
+    sun4H:SunOS:5.*:*)
+	echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+	echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    i86pc:SunOS:5.*:*)
+	echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    sun4*:SunOS:6*:*)
+	# According to config.sub, this is the proper way to canonicalize
+	# SunOS6.  Hard to guess exactly what SunOS6 will be like, but
+	# it's likely to be more like Solaris than SunOS4.
+	echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    sun4*:SunOS:*:*)
+	case "`/usr/bin/arch -k`" in
+	    Series*|S4*)
+		UNAME_RELEASE=`uname -v`
+		;;
+	esac
+	# Japanese Language versions have a version number like `4.1.3-JL'.
+	echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+	exit 0 ;;
+    sun3*:SunOS:*:*)
+	echo m68k-sun-sunos${UNAME_RELEASE}
+	exit 0 ;;
+    sun*:*:4.2BSD:*)
+	UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+	test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+	case "`/bin/arch`" in
+	    sun3)
+		echo m68k-sun-sunos${UNAME_RELEASE}
+		;;
+	    sun4)
+		echo sparc-sun-sunos${UNAME_RELEASE}
+		;;
+	esac
+	exit 0 ;;
+    aushp:SunOS:*:*)
+	echo sparc-auspex-sunos${UNAME_RELEASE}
+	exit 0 ;;
+    # The situation for MiNT is a little confusing.  The machine name
+    # can be virtually everything (everything which is not
+    # "atarist" or "atariste" at least should have a processor
+    # > m68000).  The system name ranges from "MiNT" over "FreeMiNT"
+    # to the lowercase version "mint" (or "freemint").  Finally
+    # the system name "TOS" denotes a system which is actually not
+    # MiNT.  But MiNT is downward compatible to TOS, so this should
+    # be no problem.
+    atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+	exit 0 ;;
+    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+	echo m68k-atari-mint${UNAME_RELEASE}
+        exit 0 ;;
+    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+	exit 0 ;;
+    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+        echo m68k-milan-mint${UNAME_RELEASE}
+        exit 0 ;;
+    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+        echo m68k-hades-mint${UNAME_RELEASE}
+        exit 0 ;;
+    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+        echo m68k-unknown-mint${UNAME_RELEASE}
+        exit 0 ;;
+    m68k:machten:*:*)
+	echo m68k-apple-machten${UNAME_RELEASE}
+	exit 0 ;;
+    powerpc:machten:*:*)
+	echo powerpc-apple-machten${UNAME_RELEASE}
+	exit 0 ;;
+    RISC*:Mach:*:*)
+	echo mips-dec-mach_bsd4.3
+	exit 0 ;;
+    RISC*:ULTRIX:*:*)
+	echo mips-dec-ultrix${UNAME_RELEASE}
+	exit 0 ;;
+    VAX*:ULTRIX*:*:*)
+	echo vax-dec-ultrix${UNAME_RELEASE}
+	exit 0 ;;
+    2020:CLIX:*:* | 2430:CLIX:*:*)
+	echo clipper-intergraph-clix${UNAME_RELEASE}
+	exit 0 ;;
+    mips:*:*:UMIPS | mips:*:*:RISCos)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h>  /* for printf() prototype */
+	int main (int argc, char *argv[]) {
+#else
+	int main (argc, argv) int argc; char *argv[]; {
+#endif
+	#if defined (host_mips) && defined (MIPSEB)
+	#if defined (SYSTYPE_SYSV)
+	  printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_SVR4)
+	  printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+	  printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+	#endif
+	#endif
+	  exit (-1);
+	}
+EOF
+	$CC_FOR_BUILD -o $dummy $dummy.c \
+	  && $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
+	  && exit 0
+	echo mips-mips-riscos${UNAME_RELEASE}
+	exit 0 ;;
+    Motorola:PowerMAX_OS:*:*)
+	echo powerpc-motorola-powermax
+	exit 0 ;;
+    Motorola:*:4.3:PL8-*)
+	echo powerpc-harris-powermax
+	exit 0 ;;
+    Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+	echo powerpc-harris-powermax
+	exit 0 ;;
+    Night_Hawk:Power_UNIX:*:*)
+	echo powerpc-harris-powerunix
+	exit 0 ;;
+    m88k:CX/UX:7*:*)
+	echo m88k-harris-cxux7
+	exit 0 ;;
+    m88k:*:4*:R4*)
+	echo m88k-motorola-sysv4
+	exit 0 ;;
+    m88k:*:3*:R3*)
+	echo m88k-motorola-sysv3
+	exit 0 ;;
+    AViiON:dgux:*:*)
+        # DG/UX returns AViiON for all architectures
+        UNAME_PROCESSOR=`/usr/bin/uname -p`
+	if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+	then
+	    if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+	       [ ${TARGET_BINARY_INTERFACE}x = x ]
+	    then
+		echo m88k-dg-dgux${UNAME_RELEASE}
+	    else
+		echo m88k-dg-dguxbcs${UNAME_RELEASE}
+	    fi
+	else
+	    echo i586-dg-dgux${UNAME_RELEASE}
+	fi
+ 	exit 0 ;;
+    M88*:DolphinOS:*:*)	# DolphinOS (SVR3)
+	echo m88k-dolphin-sysv3
+	exit 0 ;;
+    M88*:*:R3*:*)
+	# Delta 88k system running SVR3
+	echo m88k-motorola-sysv3
+	exit 0 ;;
+    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+	echo m88k-tektronix-sysv3
+	exit 0 ;;
+    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+	echo m68k-tektronix-bsd
+	exit 0 ;;
+    *:IRIX*:*:*)
+	echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+	exit 0 ;;
+    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+	echo romp-ibm-aix      # uname -m gives an 8 hex-code CPU id
+	exit 0 ;;              # Note that: echo "'`uname -s`'" gives 'AIX '
+    i*86:AIX:*:*)
+	echo i386-ibm-aix
+	exit 0 ;;
+    ia64:AIX:*:*)
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+	exit 0 ;;
+    *:AIX:2:3)
+	if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+		eval $set_cc_for_build
+		sed 's/^		//' << EOF >$dummy.c
+		#include <sys/systemcfg.h>
+
+		main()
+			{
+			if (!__power_pc())
+				exit(1);
+			puts("powerpc-ibm-aix3.2.5");
+			exit(0);
+			}
+EOF
+		$CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0
+		echo rs6000-ibm-aix3.2.5
+	elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+		echo rs6000-ibm-aix3.2.4
+	else
+		echo rs6000-ibm-aix3.2
+	fi
+	exit 0 ;;
+    *:AIX:*:[45])
+	IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+	if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+		IBM_ARCH=rs6000
+	else
+		IBM_ARCH=powerpc
+	fi
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+	exit 0 ;;
+    *:AIX:*:*)
+	echo rs6000-ibm-aix
+	exit 0 ;;
+    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+	echo romp-ibm-bsd4.4
+	exit 0 ;;
+    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
+	echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
+	exit 0 ;;                           # report: romp-ibm BSD 4.3
+    *:BOSX:*:*)
+	echo rs6000-bull-bosx
+	exit 0 ;;
+    DPX/2?00:B.O.S.:*:*)
+	echo m68k-bull-sysv3
+	exit 0 ;;
+    9000/[34]??:4.3bsd:1.*:*)
+	echo m68k-hp-bsd
+	exit 0 ;;
+    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+	echo m68k-hp-bsd4.4
+	exit 0 ;;
+    9000/[34678]??:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	case "${UNAME_MACHINE}" in
+	    9000/31? )            HP_ARCH=m68000 ;;
+	    9000/[34]?? )         HP_ARCH=m68k ;;
+	    9000/[678][0-9][0-9])
+		if [ -x /usr/bin/getconf ]; then
+		    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+                    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+                    case "${sc_cpu_version}" in
+                      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+                      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+                      532)                      # CPU_PA_RISC2_0
+                        case "${sc_kernel_bits}" in
+                          32) HP_ARCH="hppa2.0n" ;;
+                          64) HP_ARCH="hppa2.0w" ;;
+			  '') HP_ARCH="hppa2.0" ;;   # HP-UX 10.20
+                        esac ;;
+                    esac
+		fi
+		if [ "${HP_ARCH}" = "" ]; then
+		    eval $set_cc_for_build
+		    sed 's/^              //' << EOF >$dummy.c
+
+              #define _HPUX_SOURCE
+              #include <stdlib.h>
+              #include <unistd.h>
+
+              int main ()
+              {
+              #if defined(_SC_KERNEL_BITS)
+                  long bits = sysconf(_SC_KERNEL_BITS);
+              #endif
+                  long cpu  = sysconf (_SC_CPU_VERSION);
+
+                  switch (cpu)
+              	{
+              	case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+              	case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+              	case CPU_PA_RISC2_0:
+              #if defined(_SC_KERNEL_BITS)
+              	    switch (bits)
+              		{
+              		case 64: puts ("hppa2.0w"); break;
+              		case 32: puts ("hppa2.0n"); break;
+              		default: puts ("hppa2.0"); break;
+              		} break;
+              #else  /* !defined(_SC_KERNEL_BITS) */
+              	    puts ("hppa2.0"); break;
+              #endif
+              	default: puts ("hppa1.0"); break;
+              	}
+                  exit (0);
+              }
+EOF
+		    (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+		    test -z "$HP_ARCH" && HP_ARCH=hppa
+		fi ;;
+	esac
+	if [ ${HP_ARCH} = "hppa2.0w" ]
+	then
+	    # avoid double evaluation of $set_cc_for_build
+	    test -n "$CC_FOR_BUILD" || eval $set_cc_for_build
+	    if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E -) | grep __LP64__ >/dev/null
+	    then
+		HP_ARCH="hppa2.0w"
+	    else
+		HP_ARCH="hppa64"
+	    fi
+	fi
+	echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+	exit 0 ;;
+    ia64:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	echo ia64-hp-hpux${HPUX_REV}
+	exit 0 ;;
+    3050*:HI-UX:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <unistd.h>
+	int
+	main ()
+	{
+	  long cpu = sysconf (_SC_CPU_VERSION);
+	  /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+	     true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct
+	     results, however.  */
+	  if (CPU_IS_PA_RISC (cpu))
+	    {
+	      switch (cpu)
+		{
+		  case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+		  default: puts ("hppa-hitachi-hiuxwe2"); break;
+		}
+	    }
+	  else if (CPU_IS_HP_MC68K (cpu))
+	    puts ("m68k-hitachi-hiuxwe2");
+	  else puts ("unknown-hitachi-hiuxwe2");
+	  exit (0);
+	}
+EOF
+	$CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0
+	echo unknown-hitachi-hiuxwe2
+	exit 0 ;;
+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+	echo hppa1.1-hp-bsd
+	exit 0 ;;
+    9000/8??:4.3bsd:*:*)
+	echo hppa1.0-hp-bsd
+	exit 0 ;;
+    *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+	echo hppa1.0-hp-mpeix
+	exit 0 ;;
+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+	echo hppa1.1-hp-osf
+	exit 0 ;;
+    hp8??:OSF1:*:*)
+	echo hppa1.0-hp-osf
+	exit 0 ;;
+    i*86:OSF1:*:*)
+	if [ -x /usr/sbin/sysversion ] ; then
+	    echo ${UNAME_MACHINE}-unknown-osf1mk
+	else
+	    echo ${UNAME_MACHINE}-unknown-osf1
+	fi
+	exit 0 ;;
+    parisc*:Lites*:*:*)
+	echo hppa1.1-hp-lites
+	exit 0 ;;
+    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+	echo c1-convex-bsd
+        exit 0 ;;
+    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+        exit 0 ;;
+    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+	echo c34-convex-bsd
+        exit 0 ;;
+    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+	echo c38-convex-bsd
+        exit 0 ;;
+    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+	echo c4-convex-bsd
+        exit 0 ;;
+    CRAY*Y-MP:*:*:*)
+	echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY*[A-Z]90:*:*:*)
+	echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+	| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+	      -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+	      -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY*TS:*:*:*)
+	echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY*T3E:*:*:*)
+	echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY*SV1:*:*:*)
+	echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    *:UNICOS/mp:*:*)
+	echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+	FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+        echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+        exit 0 ;;
+    5000:UNIX_System_V:4.*:*)
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+        echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+	exit 0 ;;
+    i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+	echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+	exit 0 ;;
+    sparc*:BSD/OS:*:*)
+	echo sparc-unknown-bsdi${UNAME_RELEASE}
+	exit 0 ;;
+    *:BSD/OS:*:*)
+	echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+	exit 0 ;;
+    *:FreeBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+	exit 0 ;;
+    i*:CYGWIN*:*)
+	echo ${UNAME_MACHINE}-pc-cygwin
+	exit 0 ;;
+    i*:MINGW*:*)
+	echo ${UNAME_MACHINE}-pc-mingw32
+	exit 0 ;;
+    i*:PW*:*)
+	echo ${UNAME_MACHINE}-pc-pw32
+	exit 0 ;;
+    x86:Interix*:[34]*)
+	echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//'
+	exit 0 ;;
+    [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+	echo i${UNAME_MACHINE}-pc-mks
+	exit 0 ;;
+    i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+	# UNAME_MACHINE based on the output of uname instead of i386?
+	echo i586-pc-interix
+	exit 0 ;;
+    i*:UWIN*:*)
+	echo ${UNAME_MACHINE}-pc-uwin
+	exit 0 ;;
+    amd64:CYGWIN*:*:*)
+	echo x86_64-unknown-cygwin
+	exit 0 ;;
+    p*:CYGWIN*:*)
+	echo powerpcle-unknown-cygwin
+	exit 0 ;;
+    prep*:SunOS:5.*:*)
+	echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    *:GNU:*:*)
+	# the GNU system
+	echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+	exit 0 ;;
+    *:GNU/*:*:*)
+	# other systems with GNU libc and userland
+	echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
+	exit 0 ;;
+    i*86:Minix:*:*)
+	echo ${UNAME_MACHINE}-pc-minix
+	exit 0 ;;
+    arm*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    cris:Linux:*:*)
+	echo cris-axis-linux-gnu
+	exit 0 ;;
+    crisv32:Linux:*:*)
+	echo crisv32-axis-linux-gnu
+	exit 0 ;;
+    frv:Linux:*:*)
+    	echo frv-unknown-linux-gnu
+	exit 0 ;;
+    ia64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    m32r*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    m68*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    mips:Linux:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#undef CPU
+	#undef mips
+	#undef mipsel
+	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+	CPU=mipsel
+	#else
+	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+	CPU=mips
+	#else
+	CPU=
+	#endif
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
+	test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0
+	;;
+    mips64:Linux:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#undef CPU
+	#undef mips64
+	#undef mips64el
+	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+	CPU=mips64el
+	#else
+	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+	CPU=mips64
+	#else
+	CPU=
+	#endif
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
+	test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0
+	;;
+    ppc:Linux:*:*)
+	echo powerpc-unknown-linux-gnu
+	exit 0 ;;
+    ppc64:Linux:*:*)
+	echo powerpc64-unknown-linux-gnu
+	exit 0 ;;
+    alpha:Linux:*:*)
+	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+	  EV5)   UNAME_MACHINE=alphaev5 ;;
+	  EV56)  UNAME_MACHINE=alphaev56 ;;
+	  PCA56) UNAME_MACHINE=alphapca56 ;;
+	  PCA57) UNAME_MACHINE=alphapca56 ;;
+	  EV6)   UNAME_MACHINE=alphaev6 ;;
+	  EV67)  UNAME_MACHINE=alphaev67 ;;
+	  EV68*) UNAME_MACHINE=alphaev68 ;;
+        esac
+	objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
+	if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+	echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+	exit 0 ;;
+    parisc:Linux:*:* | hppa:Linux:*:*)
+	# Look for CPU level
+	case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+	  PA7*) echo hppa1.1-unknown-linux-gnu ;;
+	  PA8*) echo hppa2.0-unknown-linux-gnu ;;
+	  *)    echo hppa-unknown-linux-gnu ;;
+	esac
+	exit 0 ;;
+    parisc64:Linux:*:* | hppa64:Linux:*:*)
+	echo hppa64-unknown-linux-gnu
+	exit 0 ;;
+    s390:Linux:*:* | s390x:Linux:*:*)
+	echo ${UNAME_MACHINE}-ibm-linux
+	exit 0 ;;
+    sh64*:Linux:*:*)
+    	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    sh*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    sparc:Linux:*:* | sparc64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    x86_64:Linux:*:*)
+	echo x86_64-unknown-linux-gnu
+	exit 0 ;;
+    i*86:Linux:*:*)
+	# The BFD linker knows what the default object file format is, so
+	# first see if it will tell us. cd to the root directory to prevent
+	# problems with other programs or directories called `ld' in the path.
+	# Set LC_ALL=C to ensure ld outputs messages in English.
+	ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
+			 | sed -ne '/supported targets:/!d
+				    s/[ 	][ 	]*/ /g
+				    s/.*supported targets: *//
+				    s/ .*//
+				    p'`
+        case "$ld_supported_targets" in
+	  elf32-i386)
+		TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
+		;;
+	  a.out-i386-linux)
+		echo "${UNAME_MACHINE}-pc-linux-gnuaout"
+		exit 0 ;;
+	  coff-i386)
+		echo "${UNAME_MACHINE}-pc-linux-gnucoff"
+		exit 0 ;;
+	  "")
+		# Either a pre-BFD a.out linker (linux-gnuoldld) or
+		# one that does not give us useful --help.
+		echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
+		exit 0 ;;
+	esac
+	# Determine whether the default compiler is a.out or elf
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <features.h>
+	#ifdef __ELF__
+	# ifdef __GLIBC__
+	#  if __GLIBC__ >= 2
+	LIBC=gnu
+	#  else
+	LIBC=gnulibc1
+	#  endif
+	# else
+	LIBC=gnulibc1
+	# endif
+	#else
+	#ifdef __INTEL_COMPILER
+	LIBC=gnu
+	#else
+	LIBC=gnuaout
+	#endif
+	#endif
+	#ifdef __dietlibc__
+	LIBC=dietlibc
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
+	test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0
+	test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0
+	;;
+    i*86:DYNIX/ptx:4*:*)
+	# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+	# earlier versions are messed up and put the nodename in both
+	# sysname and nodename.
+	echo i386-sequent-sysv4
+	exit 0 ;;
+    i*86:UNIX_SV:4.2MP:2.*)
+        # Unixware is an offshoot of SVR4, but it has its own version
+        # number series starting with 2...
+        # I am not positive that other SVR4 systems won't match this,
+	# I just have to hope.  -- rms.
+        # Use sysv4.2uw... so that sysv4* matches it.
+	echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+	exit 0 ;;
+    i*86:OS/2:*:*)
+	# If we were able to find `uname', then EMX Unix compatibility
+	# is probably installed.
+	echo ${UNAME_MACHINE}-pc-os2-emx
+	exit 0 ;;
+    i*86:XTS-300:*:STOP)
+	echo ${UNAME_MACHINE}-unknown-stop
+	exit 0 ;;
+    i*86:atheos:*:*)
+	echo ${UNAME_MACHINE}-unknown-atheos
+	exit 0 ;;
+	i*86:syllable:*:*)
+	echo ${UNAME_MACHINE}-pc-syllable
+	exit 0 ;;
+    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
+	echo i386-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    i*86:*DOS:*:*)
+	echo ${UNAME_MACHINE}-pc-msdosdjgpp
+	exit 0 ;;
+    i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+	UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+	if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+		echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+	else
+		echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+	fi
+	exit 0 ;;
+    i*86:*:5:[78]*)
+	case `/bin/uname -X | grep "^Machine"` in
+	    *486*)	     UNAME_MACHINE=i486 ;;
+	    *Pentium)	     UNAME_MACHINE=i586 ;;
+	    *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+	esac
+	echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+	exit 0 ;;
+    i*86:*:3.2:*)
+	if test -f /usr/options/cb.name; then
+		UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+		echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+	elif /bin/uname -X 2>/dev/null >/dev/null ; then
+		UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+		(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+		(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+			&& UNAME_MACHINE=i586
+		(/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+	else
+		echo ${UNAME_MACHINE}-pc-sysv32
+	fi
+	exit 0 ;;
+    pc:*:*:*)
+	# Left here for compatibility:
+        # uname -m prints for DJGPP always 'pc', but it prints nothing about
+        # the processor, so we play safe by assuming i386.
+	echo i386-pc-msdosdjgpp
+        exit 0 ;;
+    Intel:Mach:3*:*)
+	echo i386-pc-mach3
+	exit 0 ;;
+    paragon:*:*:*)
+	echo i860-intel-osf1
+	exit 0 ;;
+    i860:*:4.*:*) # i860-SVR4
+	if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+	  echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+	else # Add other i860-SVR4 vendors below as they are discovered.
+	  echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
+	fi
+	exit 0 ;;
+    mini*:CTIX:SYS*5:*)
+	# "miniframe"
+	echo m68010-convergent-sysv
+	exit 0 ;;
+    mc68k:UNIX:SYSTEM5:3.51m)
+	echo m68k-convergent-sysv
+	exit 0 ;;
+    M680?0:D-NIX:5.3:*)
+	echo m68k-diab-dnix
+	exit 0 ;;
+    M68*:*:R3V[5678]*:*)
+	test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
+    3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
+	OS_REL=''
+	test -r /etc/.relid \
+	&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+	  && echo i486-ncr-sysv4.3${OS_REL} && exit 0
+	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+	  && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
+    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+          && echo i486-ncr-sysv4 && exit 0 ;;
+    m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+	echo m68k-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    mc68030:UNIX_System_V:4.*:*)
+	echo m68k-atari-sysv4
+	exit 0 ;;
+    TSUNAMI:LynxOS:2.*:*)
+	echo sparc-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    rs6000:LynxOS:2.*:*)
+	echo rs6000-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
+	echo powerpc-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    SM[BE]S:UNIX_SV:*:*)
+	echo mips-dde-sysv${UNAME_RELEASE}
+	exit 0 ;;
+    RM*:ReliantUNIX-*:*:*)
+	echo mips-sni-sysv4
+	exit 0 ;;
+    RM*:SINIX-*:*:*)
+	echo mips-sni-sysv4
+	exit 0 ;;
+    *:SINIX-*:*:*)
+	if uname -p 2>/dev/null >/dev/null ; then
+		UNAME_MACHINE=`(uname -p) 2>/dev/null`
+		echo ${UNAME_MACHINE}-sni-sysv4
+	else
+		echo ns32k-sni-sysv
+	fi
+	exit 0 ;;
+    PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+                      # says <Richard.M.Bartel@ccMail.Census.GOV>
+        echo i586-unisys-sysv4
+        exit 0 ;;
+    *:UNIX_System_V:4*:FTX*)
+	# From Gerald Hewes <hewes@openmarket.com>.
+	# How about differentiating between stratus architectures? -djm
+	echo hppa1.1-stratus-sysv4
+	exit 0 ;;
+    *:*:*:FTX*)
+	# From seanf@swdc.stratus.com.
+	echo i860-stratus-sysv4
+	exit 0 ;;
+    i*86:VOS:*:*)
+	# From Paul.Green@stratus.com.
+	echo ${UNAME_MACHINE}-stratus-vos
+	exit 0 ;;
+    *:VOS:*:*)
+	# From Paul.Green@stratus.com.
+	echo hppa1.1-stratus-vos
+	exit 0 ;;
+    mc68*:A/UX:*:*)
+	echo m68k-apple-aux${UNAME_RELEASE}
+	exit 0 ;;
+    news*:NEWS-OS:6*:*)
+	echo mips-sony-newsos6
+	exit 0 ;;
+    R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+	if [ -d /usr/nec ]; then
+	        echo mips-nec-sysv${UNAME_RELEASE}
+	else
+	        echo mips-unknown-sysv${UNAME_RELEASE}
+	fi
+        exit 0 ;;
+    BeBox:BeOS:*:*)	# BeOS running on hardware made by Be, PPC only.
+	echo powerpc-be-beos
+	exit 0 ;;
+    BeMac:BeOS:*:*)	# BeOS running on Mac or Mac clone, PPC only.
+	echo powerpc-apple-beos
+	exit 0 ;;
+    BePC:BeOS:*:*)	# BeOS running on Intel PC compatible.
+	echo i586-pc-beos
+	exit 0 ;;
+    SX-4:SUPER-UX:*:*)
+	echo sx4-nec-superux${UNAME_RELEASE}
+	exit 0 ;;
+    SX-5:SUPER-UX:*:*)
+	echo sx5-nec-superux${UNAME_RELEASE}
+	exit 0 ;;
+    SX-6:SUPER-UX:*:*)
+	echo sx6-nec-superux${UNAME_RELEASE}
+	exit 0 ;;
+    Power*:Rhapsody:*:*)
+	echo powerpc-apple-rhapsody${UNAME_RELEASE}
+	exit 0 ;;
+    *:Rhapsody:*:*)
+	echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+	exit 0 ;;
+    *:Darwin:*:*)
+	UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+	case $UNAME_PROCESSOR in
+	    *86) UNAME_PROCESSOR=i686 ;;
+	    unknown) UNAME_PROCESSOR=powerpc ;;
+	esac
+	echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+	exit 0 ;;
+    *:procnto*:*:* | *:QNX:[0123456789]*:*)
+	UNAME_PROCESSOR=`uname -p`
+	if test "$UNAME_PROCESSOR" = "x86"; then
+		UNAME_PROCESSOR=i386
+		UNAME_MACHINE=pc
+	fi
+	echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+	exit 0 ;;
+    *:QNX:*:4*)
+	echo i386-pc-qnx
+	exit 0 ;;
+    NSE-?:NONSTOP_KERNEL:*:*)
+	echo nse-tandem-nsk${UNAME_RELEASE}
+	exit 0 ;;
+    NSR-?:NONSTOP_KERNEL:*:*)
+	echo nsr-tandem-nsk${UNAME_RELEASE}
+	exit 0 ;;
+    *:NonStop-UX:*:*)
+	echo mips-compaq-nonstopux
+	exit 0 ;;
+    BS2000:POSIX*:*:*)
+	echo bs2000-siemens-sysv
+	exit 0 ;;
+    DS/*:UNIX_System_V:*:*)
+	echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+	exit 0 ;;
+    *:Plan9:*:*)
+	# "uname -m" is not consistent, so use $cputype instead. 386
+	# is converted to i386 for consistency with other x86
+	# operating systems.
+	if test "$cputype" = "386"; then
+	    UNAME_MACHINE=i386
+	else
+	    UNAME_MACHINE="$cputype"
+	fi
+	echo ${UNAME_MACHINE}-unknown-plan9
+	exit 0 ;;
+    *:TOPS-10:*:*)
+	echo pdp10-unknown-tops10
+	exit 0 ;;
+    *:TENEX:*:*)
+	echo pdp10-unknown-tenex
+	exit 0 ;;
+    KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+	echo pdp10-dec-tops20
+	exit 0 ;;
+    XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+	echo pdp10-xkl-tops20
+	exit 0 ;;
+    *:TOPS-20:*:*)
+	echo pdp10-unknown-tops20
+	exit 0 ;;
+    *:ITS:*:*)
+	echo pdp10-unknown-its
+	exit 0 ;;
+    SEI:*:*:SEIUX)
+        echo mips-sei-seiux${UNAME_RELEASE}
+	exit 0 ;;
+    *:DragonFly:*:*)
+	echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+	exit 0 ;;
+    *:*VMS:*:*)
+    	UNAME_MACHINE=`(uname -p) 2>/dev/null`
+	case "${UNAME_MACHINE}" in
+	    A*) echo alpha-dec-vms && exit 0 ;;
+	    I*) echo ia64-dec-vms && exit 0 ;;
+	    V*) echo vax-dec-vms && exit 0 ;;
+	esac ;;
+    *:XENIX:*:SysV)
+	echo i386-pc-xenix
+	exit 0 ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+eval $set_cc_for_build
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+     I don't know....  */
+  printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+  printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+          "4"
+#else
+	  ""
+#endif
+         ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+  printf ("arm-acorn-riscix"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+  printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+  int version;
+  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+  if (version < 4)
+    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+  else
+    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+    struct utsname un;
+
+    uname(&un);
+
+    if (strncmp(un.version, "V2", 2) == 0) {
+	printf ("i386-sequent-ptx2\n"); exit (0);
+    }
+    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+	printf ("i386-sequent-ptx1\n"); exit (0);
+    }
+    printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+#  include <sys/param.h>
+#  if defined (BSD)
+#   if BSD == 43
+      printf ("vax-dec-bsd4.3\n"); exit (0);
+#   else
+#    if BSD == 199006
+      printf ("vax-dec-bsd4.3reno\n"); exit (0);
+#    else
+      printf ("vax-dec-bsd\n"); exit (0);
+#    endif
+#   endif
+#  else
+    printf ("vax-dec-bsd\n"); exit (0);
+#  endif
+# else
+    printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+  printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+  exit (1);
+}
+EOF
+
+$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && $dummy && exit 0
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+    case `getsysinfo -f cpu_type` in
+    c1*)
+	echo c1-convex-bsd
+	exit 0 ;;
+    c2*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+	exit 0 ;;
+    c34*)
+	echo c34-convex-bsd
+	exit 0 ;;
+    c38*)
+	echo c38-convex-bsd
+	exit 0 ;;
+    c4*)
+	echo c4-convex-bsd
+	exit 0 ;;
+    esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+  http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess
+and
+  http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches@gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo               = `(hostinfo) 2>/dev/null`
+/bin/universe          = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch              = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM  = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
--- zm-1.21.3.orig/db/zmschema.sql.z
+++ zm-1.21.3/db/zmschema.sql.z
@@ -385,9 +385,9 @@
 --
 -- Add in some sample control protocol definitions
 --
-insert into Controls values (1,'PELCO-D','Local','/usr/local/bin/zmcontrol-pelco-d.pl',1,1,0,1,1,0,0,1,NULL,NULL,NULL,NULL,1,0,3,1,1,0,0,1,NULL,NULL,NULL,NULL,0,NULL,NULL,1,1,0,1,0,NULL,NULL,NULL,NULL,0,NULL,NULL,0,0,0,0,0,NULL,NULL,NULL,NULL,0,NULL,NULL,1,1,0,1,0,NULL,NULL,NULL,NULL,0,NULL,NULL,1,20,1,1,1,1,0,0,0,1,1,NULL,NULL,NULL,NULL,1,0,63,1,254,1,NULL,NULL,NULL,NULL,1,0,63,1,254,0,0);
-insert into Controls values (2,'PELCO-P','Local','/usr/local/bin/zmcontrol-pelco-p.pl',1,1,0,1,1,0,0,1,NULL,NULL,NULL,NULL,1,0,3,1,1,0,0,1,NULL,NULL,NULL,NULL,0,NULL,NULL,1,1,0,1,0,NULL,NULL,NULL,NULL,0,NULL,NULL,0,0,0,0,0,NULL,NULL,NULL,NULL,0,NULL,NULL,1,1,0,1,0,NULL,NULL,NULL,NULL,0,NULL,NULL,1,20,1,1,1,1,0,0,0,1,1,NULL,NULL,NULL,NULL,1,0,63,1,254,1,NULL,NULL,NULL,NULL,1,0,63,1,254,0,0);
-insert into Controls values (3,'Sony VISCA','Local','/usr/local/bin/zmcontrol-visca.pl',1,1,0,1,0,0,0,1,0,16384,10,4000,1,1,6,1,1,1,0,1,0,1536,NULL,NULL,0,NULL,NULL,0,0,0,0,0,NULL,NULL,NULL,NULL,0,NULL,NULL,0,0,0,0,0,NULL,NULL,NULL,NULL,0,NULL,NULL,0,0,0,0,0,NULL,NULL,NULL,NULL,0,NULL,NULL,1,3,1,1,1,1,0,1,1,0,1,-15578,15578,100,10000,1,1,50,1,254,1,-7789,7789,100,5000,1,1,50,1,254,0,0);
-INSERT INTO Controls VALUES (4,'Axis API v2','Remote','/usr/local/bin/zmcontrol-axis-v2.pl',0,0,0,1,0,0,1,0,0,9999,10,2500,0,NULL,NULL,1,1,0,1,0,0,9999,10,2500,0,NULL,NULL,1,1,0,1,0,0,9999,10,2500,0,NULL,NULL,0,0,0,0,0,NULL,NULL,NULL,NULL,0,NULL,NULL,0,0,0,0,0,NULL,NULL,NULL,NULL,0,NULL,NULL,1,12,1,1,1,1,1,0,1,0,1,-360,360,1,90,0,NULL,NULL,0,NULL,1,-360,360,1,90,0,NULL,NULL,0,NULL,0,0);
-insert into Controls values (5,'KX-HCM10','Remote','/usr/local/bin/zmcontrol-kx-hcm10.pl',0,0,0,0,0,0,0,0,NULL,NULL,NULL,NULL,0,NULL,NULL,0,0,0,0,0,NULL,NULL,NULL,NULL,0,NULL,NULL,0,0,0,0,0,NULL,NULL,NULL,NULL,0,NULL,NULL,0,0,0,0,0,NULL,NULL,NULL,NULL,0,NULL,NULL,0,0,0,0,0,NULL,NULL,NULL,NULL,0,NULL,NULL,1,8,1,1,1,0,1,0,0,1,1,NULL,NULL,NULL,NULL,0,NULL,NULL,0,NULL,1,NULL,NULL,NULL,NULL,0,NULL,NULL,0,NULL,0,0);
+insert into Controls values (1,'PELCO-D','Local','/usr/bin/zmcontrol-pelco-d.pl',1,1,0,1,1,0,0,1,NULL,NULL,NULL,NULL,1,0,3,1,1,0,0,1,NULL,NULL,NULL,NULL,0,NULL,NULL,1,1,0,1,0,NULL,NULL,NULL,NULL,0,NULL,NULL,0,0,0,0,0,NULL,NULL,NULL,NULL,0,NULL,NULL,1,1,0,1,0,NULL,NULL,NULL,NULL,0,NULL,NULL,1,20,1,1,1,1,0,0,0,1,1,NULL,NULL,NULL,NULL,1,0,63,1,254,1,NULL,NULL,NULL,NULL,1,0,63,1,254,0,0);
+insert into Controls values (2,'PELCO-P','Local','/usr/bin/zmcontrol-pelco-p.pl',1,1,0,1,1,0,0,1,NULL,NULL,NULL,NULL,1,0,3,1,1,0,0,1,NULL,NULL,NULL,NULL,0,NULL,NULL,1,1,0,1,0,NULL,NULL,NULL,NULL,0,NULL,NULL,0,0,0,0,0,NULL,NULL,NULL,NULL,0,NULL,NULL,1,1,0,1,0,NULL,NULL,NULL,NULL,0,NULL,NULL,1,20,1,1,1,1,0,0,0,1,1,NULL,NULL,NULL,NULL,1,0,63,1,254,1,NULL,NULL,NULL,NULL,1,0,63,1,254,0,0);
+insert into Controls values (3,'Sony VISCA','Local','/usr/bin/zmcontrol-visca.pl',1,1,0,1,0,0,0,1,0,16384,10,4000,1,1,6,1,1,1,0,1,0,1536,NULL,NULL,0,NULL,NULL,0,0,0,0,0,NULL,NULL,NULL,NULL,0,NULL,NULL,0,0,0,0,0,NULL,NULL,NULL,NULL,0,NULL,NULL,0,0,0,0,0,NULL,NULL,NULL,NULL,0,NULL,NULL,1,3,1,1,1,1,0,1,1,0,1,-15578,15578,100,10000,1,1,50,1,254,1,-7789,7789,100,5000,1,1,50,1,254,0,0);
+INSERT INTO Controls VALUES (4,'Axis API v2','Remote','/usr/bin/zmcontrol-axis-v2.pl',0,0,0,1,0,0,1,0,0,9999,10,2500,0,NULL,NULL,1,1,0,1,0,0,9999,10,2500,0,NULL,NULL,1,1,0,1,0,0,9999,10,2500,0,NULL,NULL,0,0,0,0,0,NULL,NULL,NULL,NULL,0,NULL,NULL,0,0,0,0,0,NULL,NULL,NULL,NULL,0,NULL,NULL,1,12,1,1,1,1,1,0,1,0,1,-360,360,1,90,0,NULL,NULL,0,NULL,1,-360,360,1,90,0,NULL,NULL,0,NULL,0,0);
+insert into Controls values (5,'KX-HCM10','Remote','/usr/bin/zmcontrol-kx-hcm10.pl',0,0,0,0,0,0,0,0,NULL,NULL,NULL,NULL,0,NULL,NULL,0,0,0,0,0,NULL,NULL,NULL,NULL,0,NULL,NULL,0,0,0,0,0,NULL,NULL,NULL,NULL,0,NULL,NULL,0,0,0,0,0,NULL,NULL,NULL,NULL,0,NULL,NULL,0,0,0,0,0,NULL,NULL,NULL,NULL,0,NULL,NULL,1,8,1,1,1,0,1,0,0,1,1,NULL,NULL,NULL,NULL,0,NULL,NULL,0,NULL,1,NULL,NULL,NULL,NULL,0,NULL,NULL,0,NULL,0,0);
 
--- zm-1.21.3.orig/db/zmschema.sql
+++ zm-1.21.3/db/zmschema.sql
@@ -0,0 +1,393 @@
+--
+-- Current Database: zm
+--
+
+CREATE DATABASE /*!32312 IF NOT EXISTS*/ zm;
+
+USE zm;
+
+--
+-- Table structure for table `Config`
+--
+
+CREATE TABLE Config (
+  Id smallint(5) unsigned NOT NULL default '0',
+  Name varchar(32) NOT NULL default '',
+  Value text NOT NULL,
+  Type tinytext NOT NULL,
+  DefaultValue tinytext,
+  Hint tinytext,
+  Pattern tinytext,
+  Format tinytext,
+  Prompt tinytext,
+  Help text,
+  Category varchar(32) NOT NULL default '',
+  Readonly tinyint(3) unsigned NOT NULL default '0',
+  Requires text,
+  PRIMARY KEY  (Name),
+  UNIQUE KEY UC_Name (Name)
+) TYPE=MyISAM;
+
+--
+-- Table structure for table `Events`
+--
+
+CREATE TABLE Events (
+  Id int(10) unsigned NOT NULL auto_increment,
+  MonitorId int(10) unsigned NOT NULL default '0',
+  Name varchar(64) NOT NULL,
+  Cause varchar(32) NOT NULL default '',
+  StartTime datetime default NULL,
+  EndTime datetime default NULL,
+  Length decimal(10,2) NOT NULL default '0.00',
+  Frames int(10) unsigned default NULL,
+  AlarmFrames int(10) unsigned default NULL,
+  TotScore int(10) unsigned NOT NULL default '0',
+  AvgScore smallint(5) unsigned default '0',
+  MaxScore smallint(5) unsigned default '0',
+  Archived tinyint(3) unsigned NOT NULL default '0',
+  Uploaded tinyint(3) unsigned NOT NULL default '0',
+  Emailed tinyint(3) unsigned NOT NULL default '0',
+  Messaged tinyint(3) unsigned NOT NULL default '0',
+  Executed tinyint(3) unsigned NOT NULL default '0',
+  LearnState char(1) default '',
+  Notes tinytext,
+  PRIMARY KEY  (Id),
+  UNIQUE KEY UC_Id (Id),
+  KEY Id (Id,MonitorId),
+  KEY MonitorId (MonitorId),
+  KEY StartTime (StartTime),
+  KEY Frames (Frames),
+  KEY Archived (Archived)
+) TYPE=MyISAM;
+
+--
+-- Table structure for table `Filters`
+--
+
+CREATE TABLE Filters (
+  Name varchar(64) NOT NULL,
+  Query text NOT NULL,
+  AutoArchive tinyint(3) unsigned NOT NULL default '0',
+  AutoDelete tinyint(3) unsigned NOT NULL default '0',
+  AutoUpload tinyint(3) unsigned NOT NULL default '0',
+  AutoEmail tinyint(3) unsigned NOT NULL default '0',
+  AutoMessage tinyint(3) unsigned NOT NULL default '0',
+  AutoExecute tinytext,
+  PRIMARY KEY  (Name)
+) TYPE=MyISAM;
+
+--
+-- Table structure for table `Frames`
+--
+
+CREATE TABLE Frames (
+  Id int(10) unsigned NOT NULL auto_increment,
+  EventId int(10) unsigned NOT NULL default '0',
+  FrameId int(10) unsigned NOT NULL default '0',
+  Type enum('Normal','Bulk','Alarm') NOT NULL default 'Normal',
+  TimeStamp timestamp(14) NOT NULL,
+  Delta decimal(8,2) NOT NULL default '0.00',
+  Score smallint(5) unsigned NOT NULL default '0',
+  PRIMARY KEY  (Id),
+  UNIQUE KEY UC_Id (Id),
+  KEY EventId (EventId)
+) TYPE=MyISAM;
+
+--
+-- Table structure for table `Groups`
+--
+
+CREATE TABLE Groups (
+  Id int(10) unsigned NOT NULL auto_increment,
+  Name varchar(64) NOT NULL,
+  MonitorIds tinytext NOT NULL,
+  PRIMARY KEY  (Id)
+) TYPE=MyISAM;
+
+--
+-- Table structure for table `Monitors`
+--
+
+CREATE TABLE Monitors (
+  Id int(10) unsigned NOT NULL auto_increment,
+  Name varchar(64) NOT NULL,
+  Type enum('Local','Remote') NOT NULL default 'Local',
+  Function enum('None','Monitor','Modect','Record','Mocord','Nodect') NOT NULL default 'Monitor',
+  RunMode enum('Continuous','Triggered') NOT NULL default 'Continuous',
+  Triggers set('X10') NOT NULL default '',
+  Device tinyint(3) unsigned NOT NULL default '0',
+  Channel tinyint(3) unsigned NOT NULL default '0',
+  Format tinyint(3) unsigned NOT NULL default '0',
+  Host varchar(64) default NULL,
+  Port varchar(8) default '80',
+  Path varchar(255) default NULL,
+  Width smallint(5) unsigned NOT NULL default '0',
+  Height smallint(5) unsigned NOT NULL default '0',
+  Palette tinyint(3) unsigned NOT NULL default '1',
+  Orientation enum('0','90','180','270','hori','vert') NOT NULL default '0',
+  Brightness mediumint(7) NOT NULL default '-1',
+  Contrast mediumint(7) NOT NULL default '-1',
+  Hue mediumint(7) NOT NULL default '-1',
+  Colour mediumint(7) NOT NULL default '-1',
+  EventPrefix varchar(32) NOT NULL default 'Event-',
+  LabelFormat varchar(32) NOT NULL default '%%s - %y/%m/%d %H:%M:%S',
+  LabelX smallint(5) unsigned default NULL,
+  LabelY smallint(5) unsigned default NULL,
+  ImageBufferCount smallint(5) unsigned NOT NULL default '100',
+  WarmupCount smallint(5) unsigned NOT NULL default '25',
+  PreEventCount smallint(5) unsigned NOT NULL default '10',
+  PostEventCount smallint(5) unsigned NOT NULL default '10',
+  AlarmFrameCount smallint(5) unsigned NOT NULL default '1',
+  SectionLength int(10) unsigned NOT NULL default '600',
+  FrameSkip smallint(5) unsigned NOT NULL default '0',
+  MaxFPS decimal(5,2) NOT NULL default '0.00',
+  FPSReportInterval smallint(5) unsigned NOT NULL default '250',
+  RefBlendPerc tinyint(3) unsigned NOT NULL default '10',
+  Controllable tinyint(3) unsigned NOT NULL default '0',
+  ControlId int(10) unsigned NOT NULL default '0',
+  ControlDevice varchar(255) default NULL,
+  ControlAddress varchar(255) default NULL,
+  AutoStopTimeout decimal(5,2) default NULL,
+  TrackMotion tinyint(3) unsigned NOT NULL default '0',
+  TrackDelay smallint(5) unsigned NOT NULL default '0',
+  ReturnLocation tinyint(3) NOT NULL default '-1',
+  ReturnDelay smallint(5) unsigned NOT NULL default '0',
+  PRIMARY KEY  (Id)
+) TYPE=MyISAM;
+
+--
+-- Table structure for table `States`
+--
+
+CREATE TABLE States (
+  Name varchar(64) NOT NULL,
+  Definition tinytext NOT NULL,
+  PRIMARY KEY  (Name)
+) TYPE=MyISAM;
+
+--
+-- Table structure for table `Stats`
+--
+
+CREATE TABLE Stats (
+  MonitorId int(10) unsigned NOT NULL default '0',
+  ZoneId int(10) unsigned NOT NULL default '0',
+  EventId int(10) unsigned NOT NULL default '0',
+  FrameId int(10) unsigned NOT NULL default '0',
+  AlarmPixels int(10) unsigned NOT NULL default '0',
+  FilterPixels int(10) unsigned NOT NULL default '0',
+  BlobPixels int(10) unsigned NOT NULL default '0',
+  Blobs smallint(5) unsigned NOT NULL default '0',
+  MinBlobSize int(10) unsigned NOT NULL default '0',
+  MaxBlobSize int(10) unsigned NOT NULL default '0',
+  MinX smallint(5) unsigned NOT NULL default '0',
+  MaxX smallint(5) unsigned NOT NULL default '0',
+  MinY smallint(5) unsigned NOT NULL default '0',
+  MaxY smallint(5) unsigned NOT NULL default '0',
+  Score smallint(5) unsigned NOT NULL default '0',
+  KEY EventId (EventId),
+  KEY MonitorId (MonitorId),
+  KEY ZoneId (ZoneId)
+) TYPE=MyISAM;
+
+--
+-- Table structure for table `TriggersX10`
+--
+
+CREATE TABLE TriggersX10 (
+  MonitorId int(10) unsigned NOT NULL default '0',
+  Activation varchar(32) default NULL,
+  AlarmInput varchar(32) default NULL,
+  AlarmOutput varchar(32) default NULL,
+  PRIMARY KEY  (MonitorId)
+) TYPE=MyISAM;
+
+--
+-- Table structure for table `Users`
+--
+
+CREATE TABLE Users (
+  Id int(10) unsigned NOT NULL auto_increment,
+  Username varchar(32) BINARY NOT NULL default '',
+  Password varchar(64) NOT NULL default '',
+  Language varchar(8) NOT NULL default '',
+  Enabled tinyint(3) unsigned NOT NULL default '1',
+  Stream enum('None','View') NOT NULL default 'None',
+  Events enum('None','View','Edit') NOT NULL default 'None',
+  Monitors enum('None','View','Edit') NOT NULL default 'None',
+  System enum('None','View','Edit') NOT NULL default 'None',
+  MonitorIds tinytext,
+  PRIMARY KEY  (Id),
+  UNIQUE KEY UC_Username (Username),
+  UNIQUE KEY UC_Id (Id)
+) TYPE=MyISAM;
+
+--
+-- Table structure for table `Zones`
+--
+
+CREATE TABLE Zones (
+  Id int(10) unsigned NOT NULL auto_increment,
+  MonitorId int(10) unsigned NOT NULL default '0',
+  Name varchar(64) NOT NULL default '',
+  Type enum('Active','Inclusive','Exclusive','Preclusive','Inactive') NOT NULL default 'Active',
+  Units enum('Pixels','Percent') NOT NULL default 'Pixels',
+  LoX smallint(5) unsigned NOT NULL default '0',
+  LoY smallint(5) unsigned NOT NULL default '0',
+  HiX smallint(5) unsigned NOT NULL default '0',
+  HiY smallint(5) unsigned NOT NULL default '0',
+  AlarmRGB int(10) unsigned default NULL,
+  CheckMethod enum('AlarmedPixels','FilteredPixels','Blobs') NOT NULL default 'Blobs',
+  MinPixelThreshold smallint(5) unsigned default NULL,
+  MaxPixelThreshold smallint(5) unsigned default NULL,
+  MinAlarmPixels int(10) unsigned default NULL,
+  MaxAlarmPixels int(10) unsigned default NULL,
+  FilterX tinyint(3) unsigned default NULL,
+  FilterY tinyint(3) unsigned default NULL,
+  MinFilterPixels int(10) unsigned default NULL,
+  MaxFilterPixels int(10) unsigned default NULL,
+  MinBlobPixels int(10) unsigned default NULL,
+  MaxBlobPixels int(10) unsigned default NULL,
+  MinBlobs smallint(5) unsigned default NULL,
+  MaxBlobs smallint(5) unsigned default NULL,
+  PRIMARY KEY  (Id),
+  UNIQUE KEY UC_Id (Id)
+) TYPE=MyISAM;
+
+--
+-- Table structure for table `Controls`
+--
+
+CREATE TABLE Controls (
+  Id int(10) unsigned NOT NULL auto_increment,
+  Name varchar(64) NOT NULL default '',
+  Type enum('Local','Remote') NOT NULL default 'Local',
+  Command varchar(255) default NULL,
+
+  CanWake tinyint(3) unsigned NOT NULL default '0',
+  CanSleep tinyint(3) unsigned NOT NULL default '0',
+  CanReset tinyint(3) unsigned NOT NULL default '0',
+
+  CanZoom tinyint(3) unsigned NOT NULL default '0',
+  CanAutoZoom tinyint(3) unsigned NOT NULL default '0',
+  CanZoomAbs tinyint(3) unsigned NOT NULL default '0',
+  CanZoomRel tinyint(3) unsigned NOT NULL default '0',
+  CanZoomCon tinyint(3) unsigned NOT NULL default '0',
+  MinZoomRange int(10) unsigned default NULL,
+  MaxZoomRange int(10) unsigned default NULL,
+  MinZoomStep int(10) unsigned default NULL,
+  MaxZoomStep int(10) unsigned default NULL,
+  HasZoomSpeed tinyint(3) unsigned NOT NULL default '0',
+  MinZoomSpeed int(10) unsigned default NULL,
+  MaxZoomSpeed int(10) unsigned default NULL,
+
+  CanFocus tinyint(3) unsigned NOT NULL default '0',
+  CanAutoFocus tinyint(3) unsigned NOT NULL default '0',
+  CanFocusAbs tinyint(3) unsigned NOT NULL default '0',
+  CanFocusRel tinyint(3) unsigned NOT NULL default '0',
+  CanFocusCon tinyint(3) unsigned NOT NULL default '0',
+  MinFocusRange int(10) unsigned default NULL,
+  MaxFocusRange int(10) unsigned default NULL,
+  MinFocusStep int(10) unsigned default NULL,
+  MaxFocusStep int(10) unsigned default NULL,
+  HasFocusSpeed tinyint(3) unsigned NOT NULL default '0',
+  MinFocusSpeed int(10) unsigned default NULL,
+  MaxFocusSpeed int(10) unsigned default NULL,
+
+  CanIris tinyint(3) unsigned NOT NULL default '0',
+  CanAutoIris tinyint(3) unsigned NOT NULL default '0',
+  CanIrisAbs tinyint(3) unsigned NOT NULL default '0',
+  CanIrisRel tinyint(3) unsigned NOT NULL default '0',
+  CanIrisCon tinyint(3) unsigned NOT NULL default '0',
+  MinIrisRange int(10) unsigned default NULL,
+  MaxIrisRange int(10) unsigned default NULL,
+  MinIrisStep int(10) unsigned default NULL,
+  MaxIrisStep int(10) unsigned default NULL,
+  HasIrisSpeed tinyint(3) unsigned NOT NULL default '0',
+  MinIrisSpeed int(10) unsigned default NULL,
+  MaxIrisSpeed int(10) unsigned default NULL,
+
+  CanGain tinyint(3) unsigned NOT NULL default '0',
+  CanAutoGain tinyint(3) unsigned NOT NULL default '0',
+  CanGainAbs tinyint(3) unsigned NOT NULL default '0',
+  CanGainRel tinyint(3) unsigned NOT NULL default '0',
+  CanGainCon tinyint(3) unsigned NOT NULL default '0',
+  MinGainRange int(10) unsigned default NULL,
+  MaxGainRange int(10) unsigned default NULL,
+  MinGainStep int(10) unsigned default NULL,
+  MaxGainStep int(10) unsigned default NULL,
+  HasGainSpeed tinyint(3) unsigned NOT NULL default '0',
+  MinGainSpeed int(10) unsigned default NULL,
+  MaxGainSpeed int(10) unsigned default NULL,
+
+  CanWhite tinyint(3) unsigned NOT NULL default '0',
+  CanAutoWhite tinyint(3) unsigned NOT NULL default '0',
+  CanWhiteAbs tinyint(3) unsigned NOT NULL default '0',
+  CanWhiteRel tinyint(3) unsigned NOT NULL default '0',
+  CanWhiteCon tinyint(3) unsigned NOT NULL default '0',
+  MinWhiteRange int(10) unsigned default NULL,
+  MaxWhiteRange int(10) unsigned default NULL,
+  MinWhiteStep int(10) unsigned default NULL,
+  MaxWhiteStep int(10) unsigned default NULL,
+  HasWhiteSpeed tinyint(3) unsigned NOT NULL default '0',
+  MinWhiteSpeed int(10) unsigned default NULL,
+  MaxWhiteSpeed int(10) unsigned default NULL,
+
+  HasPresets tinyint(3) unsigned NOT NULL default '0',
+  NumPresets tinyint(3) unsigned NOT NULL default '0',
+  HasHomePreset tinyint(3) unsigned NOT NULL default '0',
+  CanSetPresets tinyint(3) unsigned NOT NULL default '0',
+
+  CanMove tinyint(3) unsigned NOT NULL default '0',
+  CanMoveDiag tinyint(3) unsigned NOT NULL default '0',
+  CanMoveMap tinyint(3) unsigned NOT NULL default '0',
+  CanMoveAbs tinyint(3) unsigned NOT NULL default '0',
+  CanMoveRel tinyint(3) unsigned NOT NULL default '0',
+  CanMoveCon tinyint(3) unsigned NOT NULL default '0',
+  CanPan tinyint(3) unsigned NOT NULL default '0',
+  MinPanRange int(10) default NULL,
+  MaxPanRange int(10) default NULL,
+  MinPanStep int(10) default NULL,
+  MaxPanStep int(10) default NULL,
+  HasPanSpeed tinyint(3) unsigned NOT NULL default '0',
+  MinPanSpeed int(10) default NULL,
+  MaxPanSpeed int(10) default NULL,
+  HasTurboPan tinyint(3) unsigned NOT NULL default '0',
+  TurboPanSpeed int(10) default NULL,
+  CanTilt tinyint(3) unsigned NOT NULL default '0',
+  MinTiltRange int(10) default NULL,
+  MaxTiltRange int(10) default NULL,
+  MinTiltStep int(10) default NULL,
+  MaxTiltStep int(10) default NULL,
+  HasTiltSpeed tinyint(3) unsigned NOT NULL default '0',
+  MinTiltSpeed int(10) default NULL,
+  MaxTiltSpeed int(10) default NULL,
+  HasTurboTilt tinyint(3) unsigned NOT NULL default '0',
+  TurboTiltSpeed int(10) default NULL,
+
+  CanAutoScan tinyint(3) unsigned NOT NULL default '0',
+  NumScanPaths tinyint(3) unsigned NOT NULL default '0',
+
+  PRIMARY KEY  (Id),
+  UNIQUE KEY UC_Id (Id)
+) TYPE=MyISAM;
+
+
+--
+-- Create a default admin user.
+--
+insert into Users values ('','admin',password('admin'),'',1,'View','Edit','Edit','Edit',NULL);
+--
+-- Add in a sample filter to purge the oldest 5 events when the disk is 99% full, delete is disabled though
+--
+insert into Filters values ('PurgeWhenFull','trms=2&obr1=&cbr1=&attr1=Archived&op1=&val1=0&cnj2=and&obr2=&cbr2=&attr2=DiskPercent&op2=>=&val2=99&sort_field=Id&sort_asc=1&limit=5',0,0,0,0,0,'');
+--
+-- Add in some sample control protocol definitions
+--
+insert into Controls values (1,'PELCO-D','Local','/usr/bin/zmcontrol-pelco-d.pl',1,1,0,1,1,0,0,1,NULL,NULL,NULL,NULL,1,0,3,1,1,0,0,1,NULL,NULL,NULL,NULL,0,NULL,NULL,1,1,0,1,0,NULL,NULL,NULL,NULL,0,NULL,NULL,0,0,0,0,0,NULL,NULL,NULL,NULL,0,NULL,NULL,1,1,0,1,0,NULL,NULL,NULL,NULL,0,NULL,NULL,1,20,1,1,1,1,0,0,0,1,1,NULL,NULL,NULL,NULL,1,0,63,1,254,1,NULL,NULL,NULL,NULL,1,0,63,1,254,0,0);
+insert into Controls values (2,'PELCO-P','Local','/usr/bin/zmcontrol-pelco-p.pl',1,1,0,1,1,0,0,1,NULL,NULL,NULL,NULL,1,0,3,1,1,0,0,1,NULL,NULL,NULL,NULL,0,NULL,NULL,1,1,0,1,0,NULL,NULL,NULL,NULL,0,NULL,NULL,0,0,0,0,0,NULL,NULL,NULL,NULL,0,NULL,NULL,1,1,0,1,0,NULL,NULL,NULL,NULL,0,NULL,NULL,1,20,1,1,1,1,0,0,0,1,1,NULL,NULL,NULL,NULL,1,0,63,1,254,1,NULL,NULL,NULL,NULL,1,0,63,1,254,0,0);
+insert into Controls values (3,'Sony VISCA','Local','/usr/bin/zmcontrol-visca.pl',1,1,0,1,0,0,0,1,0,16384,10,4000,1,1,6,1,1,1,0,1,0,1536,NULL,NULL,0,NULL,NULL,0,0,0,0,0,NULL,NULL,NULL,NULL,0,NULL,NULL,0,0,0,0,0,NULL,NULL,NULL,NULL,0,NULL,NULL,0,0,0,0,0,NULL,NULL,NULL,NULL,0,NULL,NULL,1,3,1,1,1,1,0,1,1,0,1,-15578,15578,100,10000,1,1,50,1,254,1,-7789,7789,100,5000,1,1,50,1,254,0,0);
+INSERT INTO Controls VALUES (4,'Axis API v2','Remote','/usr/bin/zmcontrol-axis-v2.pl',0,0,0,1,0,0,1,0,0,9999,10,2500,0,NULL,NULL,1,1,0,1,0,0,9999,10,2500,0,NULL,NULL,1,1,0,1,0,0,9999,10,2500,0,NULL,NULL,0,0,0,0,0,NULL,NULL,NULL,NULL,0,NULL,NULL,0,0,0,0,0,NULL,NULL,NULL,NULL,0,NULL,NULL,1,12,1,1,1,1,1,0,1,0,1,-360,360,1,90,0,NULL,NULL,0,NULL,1,-360,360,1,90,0,NULL,NULL,0,NULL,0,0);
+insert into Controls values (5,'KX-HCM10','Remote','/usr/bin/zmcontrol-kx-hcm10.pl',0,0,0,0,0,0,0,0,NULL,NULL,NULL,NULL,0,NULL,NULL,0,0,0,0,0,NULL,NULL,NULL,NULL,0,NULL,NULL,0,0,0,0,0,NULL,NULL,NULL,NULL,0,NULL,NULL,0,0,0,0,0,NULL,NULL,NULL,NULL,0,NULL,NULL,0,0,0,0,0,NULL,NULL,NULL,NULL,0,NULL,NULL,1,8,1,1,1,0,1,0,0,1,1,NULL,NULL,NULL,NULL,0,NULL,NULL,0,NULL,1,NULL,NULL,NULL,NULL,0,NULL,NULL,0,NULL,0,0);
+
--- zm-1.21.3.orig/db/zmconfig.sql
+++ zm-1.21.3/db/zmconfig.sql
@@ -0,0 +1,265 @@
+delete from Config ; 
+replace into Config set Id = '0' , Name = 'ZM_LANG_DEFAULT', Value = 'en_US', Type = 'string', DefaultValue = 'en_gb', Hint = 'directory', Pattern = '(?-xism:^([a-zA-Z0-9-_.]+)$)', Format = ' $1 ', Prompt = 'Default language used by web interface', Help = 'ZoneMinder allows the web interface to use languages other than English if the appropriate language file has been created and is present. This option allows you to change the default language that is used from the shipped language, British English, to another language', Category = 'system', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '1' , Name = 'ZM_OPT_USE_AUTH', Value = '1', Type = 'boolean', DefaultValue = 'no', Hint = 'yes|no', Pattern = '(?i-xsm:^([yn]))', Format = ' ($1 =~ /^y/) ?\'ye\' :\'n\' ', Prompt = 'Authenticate user logins to ZoneMinder', Help = 'ZoneMinder can run in two modes. The simplest is an entirely unauthenticated mode where anyone can access ZoneMinder and perform all tasks. This is most suitable for installation where the web server access is limited in other ways. The other mode enables user accounts with varying sets of permissions. Users must login to access ZoneMinder and are limited by their defined permissions.', Category = 'system', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '2' , Name = 'ZM_AUTH_METHOD', Value = 'hashed', Type = 'string', DefaultValue = 'hashed', Hint = 'hashed|plain', Pattern = '(?i-xsm:^([hp]))', Format = ' $1 =~ /^h/ ?\'hashe\' :\'plai\' ', Prompt = 'Method used to send authentication information', Help = 'When ZoneMinder is running in authenticated mode it must pass user details between the web pages and the back end processes. There are two methods for doing this. This first is to use a time limited hashed string which contains no direct username or password details, the second method is to pass the username and passwords around in plaintext. This method is not recommend except where you do not have the md5 libraries available on your system or you have a completely isolated system with no external access.', Category = 'system', Readonly =  '?1:0', Requires = 'ZM_OPT_USE_AUTH=1' ; 
+replace into Config set Id = '3' , Name = 'ZM_AUTH_SECRET', Value = 'blah', Type = 'string', DefaultValue = '', Hint = 'string', Pattern = '(?-xism:^(.+)$)', Format = ' $1 ', Prompt = 'Secret used when encoding authentication information', Help = 'When ZoneMinder is running in hashed authenticated mode it is necessary to generate hashed strings containing encrypted sensitive information such as usernames and password. Although these string are reasonably secure the addition of a random secret increases security substantially.', Category = 'system', Readonly =  '?1:0', Requires = 'ZM_AUTH_METHOD=hashed' ; 
+replace into Config set Id = '4' , Name = 'ZM_DIR_EVENTS', Value = 'events', Type = 'string', DefaultValue = 'events', Hint = 'directory', Pattern = '(?-xism:^([a-zA-Z0-9-_.]+)$)', Format = ' $1 ', Prompt = 'Directory where events are stored', Help = 'This is the path to the events directory where all the event images and other miscellaneous files are stored. It is normally given as a subdirectory of the web directory you have specified earlier however if disk space is tight it can reside on another partition in which case you should create a link from that area to the path you give here.', Category = 'paths', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '5' , Name = 'ZM_DIR_IMAGES', Value = 'images', Type = 'string', DefaultValue = 'images', Hint = 'directory', Pattern = '(?-xism:^([a-zA-Z0-9-_.]+)$)', Format = ' $1 ', Prompt = 'Directory where the images that the ZoneMinder client generates are stored', Help = 'ZoneMinder generates a myriad of images, mosty of which are associated with events. For those that are\'t this is where they go.', Category = 'paths', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '6' , Name = 'ZM_DIR_SOUNDS', Value = 'sounds', Type = 'string', DefaultValue = 'sounds', Hint = 'directory', Pattern = '(?-xism:^([a-zA-Z0-9-_.]+)$)', Format = ' $1 ', Prompt = 'Directory to the sounds that the ZoneMinder client can use', Help = 'ZoneMinder can optionally play a sound file when an alarm is detected. This indicates where (relative to the web root) to look for this file.', Category = 'paths', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '7' , Name = 'ZM_PATH_ZMS', Value = '/cgi-bin/zms', Type = 'string', DefaultValue = '/cgi-bin/zms', Hint = 'relative/path/to/somewhere', Pattern = '(?-xism:^((?:[^/].*)?)/?$)', Format = ' $1 ', Prompt = 'Web path to zms streaming server', Help = 'The ZoneMinder streaming server is required to send streamed images to your browser. It will be installed into the cgi-bin path given at configuration time. This option determines what the web path to the server is rather than the local path on your machine. Ordinarily the streaming server runs in parser-header mode however if you experience problems with streaming you can change this to non-parsed-header (nph) mode by changing\'zm\' to\'nph-zm\'.', Category = 'paths', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '8' , Name = 'ZM_CAN_STREAM', Value = 'auto', Type = 'string', DefaultValue = 'auto', Hint = 'auto|yes|no', Pattern = '(?i-xsm:^([ayn]))', Format = ' ($1 =~ /^y/) ?\'ye\' : ($1 =~ /^n/ ?\'n\' :\'aut\' ) ', Prompt = 'Override the automatic detection of browser streaming capability', Help = 'If you know that your browser can handle image streams of the type\'multipart/x-mixed-replac\' but ZoneMinder does not detect this correctly you can set this option to ensure that the stream is delivered with or without the use of the Cambozola plugin. Selecting\'ye\' will tell ZoneMinder that your browser can handle the streams natively,\'n\' means that it ca\'t and so the plugin will be used while\'aut\' lets ZoneMinder decide.', Category = 'tools', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '9' , Name = 'ZM_RAND_STREAM', Value = '0', Type = 'boolean', DefaultValue = 'no', Hint = 'yes|no', Pattern = '(?i-xsm:^([yn]))', Format = ' ($1 =~ /^y/) ?\'ye\' :\'n\' ', Prompt = 'Add a random string to prevent caching of streams', Help = 'Some browsers can cache the streams used by ZoneMinder. In order to prevent his a harmless random string can be appended to the url to make each invocation of the stream appear unique.', Category = 'tools', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '10' , Name = 'ZM_OPT_CAMBOZOLA', Value = '0', Type = 'boolean', DefaultValue = 'no', Hint = 'yes|no', Pattern = '(?i-xsm:^([yn]))', Format = ' ($1 =~ /^y/) ?\'ye\' :\'n\' ', Prompt = 'Is the (optional) cambozola java streaming client installed (recommended)', Help = 'Cambozola is a handy low fat cheese flavoured Java applet that ZoneMinder uses to view image streams on browsers such as Internet Explorer that do\'t natively support this format. It is highly recommended to install this from http://www.charliemouse.com/code/cambozola/  however if it is not installed still images at a lower refresh rate can still be viewed.', Category = 'tools', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '11' , Name = 'ZM_PATH_CAMBOZOLA', Value = 'cambozola.jar', Type = 'string', DefaultValue = 'cambozola.jar', Hint = 'relative/path/to/somewhere', Pattern = '(?-xism:^((?:[^/].*)?)/?$)', Format = ' $1 ', Prompt = 'Web path to (optional) cambozola java streaming client (recommended)', Help = 'Cambozola is a handy low fat cheese flavoured Java applet that ZoneMinder uses to view image streams on browsers such as Internet Explorer that do\'t natively support this format. It is highly recommended to install this from http://www.charliemouse.com/code/cambozola/  however if it is not installed still images at a lower refresh rate can still be viewed. Leave this as\'cambozola.ja\' if cambozola is installed in the same directory as the ZoneMinder web client files.', Category = 'tools', Readonly =  '?1:0', Requires = 'ZM_OPT_CAMBOZOLA=1' ; 
+replace into Config set Id = '12' , Name = 'ZM_TIMESTAMP_ON_CAPTURE', Value = '1', Type = 'boolean', DefaultValue = 'yes', Hint = 'yes|no', Pattern = '(?i-xsm:^([yn]))', Format = ' ($1 =~ /^y/) ?\'ye\' :\'n\' ', Prompt = 'Timestamp images as soon as they are captured', Help = 'ZoneMinder can add a timestamp to images in two ways. The default method, when this option is set, is that each image is timestamped immediately when captured and so the image held in memory is marked right away. The second method does not timestamp the images until they are either saved as part of an event or accessed over the web. The timestamp used in both methods will contain the same time as this is preserved along with the image. The first method ensures that an image is timestamped regardless of any other circumstances but will result in all images being timestamped even those never saved or viewed. The second method necessitates that saved images are copied before being saved otherwise two timestamps perhaps at different scales may be applied. This has the (perhaps) desirable side effect that the timestamp is always applied at the same resolution so an image that has scaling applied will still have a legible and correctly scaled timestamp.', Category = 'config', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '13' , Name = 'ZM_LOCAL_BGR_INVERT', Value = '1', Type = 'boolean', DefaultValue = 'yes', Hint = 'yes|no', Pattern = '(?i-xsm:^([yn]))', Format = ' ($1 =~ /^y/) ?\'ye\' :\'n\' ', Prompt = 'Invert BGR colours to RGB', Help = 'Some cameras or video cards capture images in BGR (Blue-Green-Red) order even when the palette says RGB. If you see strange colours casts on your images then it may be worth trying this option to see if that corrects the issue. Note this option will apply only to local cameras and not those over a network.', Category = 'config', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '14' , Name = 'ZM_Y_IMAGE_DELTAS', Value = '1', Type = 'boolean', DefaultValue = 'yes', Hint = 'yes|no', Pattern = '(?i-xsm:^([yn]))', Format = ' ($1 =~ /^y/) ?\'ye\' :\'n\' ', Prompt = 'Whether we calculate images differences using Y channel', Help = 'When ZoneMinder tries to establish the differences between two colour images it generates a greyscale\'delt\' image between the two sets of images. In order to do this it determines the differences found between the different RGB colour components and calculates a greyscale value representing this. If this option is set then a calculation will be made to convert each pixel of the image into a brightness value (Y from YUV) and then find the difference between the two. If this option is not set then the resulting difference is determined as the average of the differences of each colour which is a simple calculation. Using the Y value is likely to be more accurate and is up to 15% faster. Only switch this option off if Y based deltas do not work as well for you as RGB ones.', Category = 'config', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '15' , Name = 'ZM_FAST_IMAGE_BLENDS', Value = '1', Type = 'boolean', DefaultValue = 'yes', Hint = 'yes|no', Pattern = '(?i-xsm:^([yn]))', Format = ' ($1 =~ /^y/) ?\'ye\' :\'n\' ', Prompt = 'Whether we use a fast algorithm to blend the reference image', Help = 'In most modes of operation ZoneMinder needs to blend the captured image with the stored reference image to update it for the next image. The reference blend percentage specified for the monitor controls how much the new image affects the reference image. There are two methods that are available for this. If this option is set then a basic calculation is applied which though fast and fairly accurate can (due to rounding) mean that the actual range of pixel values in the reference image may be reduced from that in the captured image, e.g. a pixel may only be able to achieve a maximum of say 250 while the captured image is consistently at 255. If you also have a small minimum pixel difference threshold this can cause multiple bogus alarms. The alternative is to switch this option off which stores an additional set of temporary values which eliminate any significant rounding errors. This is more accurate though up to 6 times slower and should not really be necessary unless you find problems with the default method.', Category = 'config', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '16' , Name = 'ZM_COLOUR_JPEG_FILES', Value = '1', Type = 'boolean', DefaultValue = 'yes', Hint = 'yes|no', Pattern = '(?i-xsm:^([yn]))', Format = ' ($1 =~ /^y/) ?\'ye\' :\'n\' ', Prompt = 'Colourise greyscale JPEG files', Help = 'Cameras that capture in greyscale can write their captured images to jpeg files with a corresponding greyscale colour space. This saves a small amount of disk space over colour ones. However some tools such as ffmpeg and mpeg_encode either fail to work with this colour space or have to convert it beforehand. Setting this option to yes uses up a little more space but makes creation of MPEG files much faster.', Category = 'config', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '17' , Name = 'ZM_JPEG_FILE_QUALITY', Value = '100', Type = 'integer', DefaultValue = '70', Hint = 'integer', Pattern = '(?-xism:^(\\d+)$)', Format = ' $1 ', Prompt = 'Set the JPEG quality setting for the saved event files (1-100)', Help = 'When ZoneMinder detects an event it will save the images associated with that event to files. These files are in the JPEG format and can be viewed or streamed later. This option specifies what image quality should be used to save these files. A higher number means better quality but less compression so will take up more disk space and take longer to view over a slow connection. By contrast a low number means smaller, quicker to view, files but at the price of lower quality images.', Category = 'config', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '18' , Name = 'ZM_JPEG_IMAGE_QUALITY', Value = '100', Type = 'integer', DefaultValue = '70', Hint = 'integer', Pattern = '(?-xism:^(\\d+)$)', Format = ' $1 ', Prompt = 'Set the JPEG quality setting for the streamed\'liv\' images (1-100)', Help = 'When viewing a\'liv\' stream for a monitor ZoneMinder will grab an image from the buffer and encode it into JPEG format before sending it. This option specifies what image quality should be used to encode these images. A higher number means better quality but less compression so will take longer to view over a slow connection. By contrast a low number means quicker to view files but at the price of lower quality images. This option does not apply when viewing still images as these are just read from disk and so will be encoded at the quality specified by the previous option.', Category = 'config', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '19' , Name = 'ZM_BLEND_ALARMED_IMAGES', Value = '1', Type = 'boolean', DefaultValue = 'yes', Hint = 'yes|no', Pattern = '(?i-xsm:^([yn]))', Format = ' ($1 =~ /^y/) ?\'ye\' :\'n\' ', Prompt = 'Whether alarmed images are blended to update the reference image', Help = 'To detect alarms ZoneMinder compares an image with a reference image which is formed from a composite of the previous images. This option determines whether images that cause events are included in this process. Doing so may increase the precision of the alarmed region but can cause problems if wholescale lighting changes cause alarms as this would not get fed back into the image and an alarm may persist indefinately. A better way to achive the same effect in most cases is to lower substantially the reference blend persentage in specific monitors.', Category = 'config', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '20' , Name = 'ZM_NO_MAX_FPS_ON_ALARM', Value = '1', Type = 'boolean', DefaultValue = 'yes', Hint = 'yes|no', Pattern = '(?i-xsm:^([yn]))', Format = ' ($1 =~ /^y/) ?\'ye\' :\'n\' ', Prompt = 'Should any Maximum FPS be ignored if an alarm occurs', Help = 'When configuring monitors you can optionally specify a maximum setting for the capture rate rate in frames per second. This can used to limit your video or network bandwidth or reduce CPU load. This setting tells ZoneMinder to ignore these constraints if an alarm is detected an attempt to capture as fast as possible.', Category = 'config', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '21' , Name = 'ZM_OPT_ADAPTIVE_SKIP', Value = '1', Type = 'boolean', DefaultValue = 'yes', Hint = 'yes|no', Pattern = '(?i-xsm:^([yn]))', Format = ' ($1 =~ /^y/) ?\'ye\' :\'n\' ', Prompt = 'Should frame analysis try and be efficient in skipping frames', Help = 'In previous versions of ZoneMinder the analysis daemon would attempt to keep up with the capture daemon by processing the last captured frame on each pass. This would sometimes have the undesirable side-effect of missing a chunk of the initial activity that caused the alarm because the pre-alarm frames would all have to be written to disk and the database before processing the next frame, leading to some delay between the first and second event frames. Setting this option enables a newer adaptive algorithm where the analysis daemon attempts to process as many captured frames as possible, only skipping frames when in danger of the capture daemon overwriting yet to be processed frames. This skip is variable depending on the size of the ring buffer and the amount of space left in it. Enabling this option will give you much better coverage of the beginning of alarms whilst biasing out any skipped frames towards the middle or end of the event. However you should be aware that this will have the effect of making the analysis daemon run somewhat behind the capture daemon during events and for particularly fast rates of capture it is possible for the adaptive algorithm to be overwhelmed and not have time to react to a rapid build up of pending frames and thus for a buffer overrun condition to occur.', Category = 'config', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '22' , Name = 'ZM_OPT_REMOTE_CAMERAS', Value = '1', Type = 'boolean', DefaultValue = 'no', Hint = 'yes|no', Pattern = '(?i-xsm:^([yn]))', Format = ' ($1 =~ /^y/) ?\'ye\' :\'n\' ', Prompt = 'Are you going to use remote/networked cameras', Help = 'ZoneMinder can work with both local cameras, ie. those attached physically to your computer and remote or network cameras. If you will be using networked cameras select this option.', Category = 'network', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '23' , Name = 'ZM_NETCAM_REGEXPS', Value = '0', Type = 'boolean', DefaultValue = 'no', Hint = 'yes|no', Pattern = '(?i-xsm:^([yn]))', Format = ' ($1 =~ /^y/) ?\'ye\' :\'n\' ', Prompt = 'Whether to use regular expression matching with network cameras', Help = 'Traditionally ZoneMinder has used complex regular regular expressions to handle the multitude of formats that network cameras produce. In versions from 1.21.1 the default is to use a simpler and faster built in pattern matching methodology. This works well with most networks cameras but if you have problems you can try the older, but more flexible, regular expression based method by selecting this option. Note, to use this method you must have libpcre installed on your system.', Category = 'network', Readonly =  '?1:0', Requires = 'ZM_OPT_REMOTE_CAMERAS=1' ; 
+replace into Config set Id = '24' , Name = 'ZM_HTTP_VERSION', Value = '1.1', Type = 'string', DefaultValue = '1.1', Hint = '1.1|1.0', Pattern = '(?-xism:^(1\\.[01])$)', Format = ' $1?$1\"" ', Prompt = 'The version of HTTP that ZoneMinder will use to connect', Help = 'ZoneMinder can communicate using either of the HTTP/1.1 or HTTP/1.0 standard. A server will normally fall back to the version it supports iwht no problem so this should usually by left at the default. However it can be changed to HTTP/1.0 if necessary to resolve particular issues.', Category = 'network', Readonly =  '?1:0', Requires = 'ZM_OPT_REMOTE_CAMERAS=1' ; 
+replace into Config set Id = '25' , Name = 'ZM_HTTP_UA', Value = 'ZoneMinder', Type = 'string', DefaultValue = 'ZoneMinder', Hint = 'string', Pattern = '(?-xism:^(.+)$)', Format = ' $1 ', Prompt = 'The user agent that ZoneMinder uses to identify itself', Help = 'When ZoneMinder communicates with remote cameras it will identify itself using this string and i\'s version number. This is normally sufficient, however if a particular cameras expects only to communicate with certain browsers then this can be changed to a different string identifying ZoneMinder as Internet Explorer or Netscape etc.', Category = 'network', Readonly =  '?1:0', Requires = 'ZM_OPT_REMOTE_CAMERAS=1' ; 
+replace into Config set Id = '26' , Name = 'ZM_HTTP_TIMEOUT', Value = '2500', Type = 'integer', DefaultValue = '2500', Hint = 'integer', Pattern = '(?-xism:^(\\d+)$)', Format = ' $1 ', Prompt = 'How long ZoneMinder waits before giving up on images (milliseconds)', Help = 'When retrieving remote images ZoneMinder will wait for this length of time before deciding that an image is not going to arrive and taking steps to retry. This timeout is in milliseconds (1000 per second) and will apply to each part of an image if it is not sent in one whole chunk.', Category = 'network', Readonly =  '?1:0', Requires = 'ZM_OPT_REMOTE_CAMERAS=1' ; 
+replace into Config set Id = '27' , Name = 'ZM_OPT_MPEG', Value = 'ffmpeg', Type = 'string', DefaultValue = 'no', Hint = 'no|mpeg_encode|ffmpeg', Pattern = '(?i-xsm:^([nmf]))', Format = ' $1 =~ /^n/ ?\'n\' : ( $1 =~ /^m/ ?\'mpeg_encod\' :\'ffmpe\') ', Prompt = 'Is there an (optional) mpeg video encoder installed', Help = 'ZoneMinder can optionally encode a series of video images into an MPEG encoded file. This option allows you to specifiy whether you have an mpeg encoder installed and if so which one. The two that ZoneMinder supports are mpeg_encode and ffmpeg, of which the latter is by far the fastest. However creating MPEG files can be fairly CPU and disk intensive and is not required as events can still be reviewed as video stream without it.', Category = 'tools', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '28' , Name = 'ZM_PATH_MPEG_ENCODE', Value = '/usr/bin/mpeg_encode', Type = 'string', DefaultValue = '/usr/local/bin/mpeg_encode', Hint = '/absolute/path/to/somewhere', Pattern = '(?-xism:^((?:/[^/]*)+?)/?$)', Format = ' $1 ', Prompt = 'Path to (optional) Berkeley mpeg encoder', Help = 'This path should point to where the Berkeley mpeg_encode program has been installed.', Category = 'tools', Readonly =  '?1:0', Requires = 'ZM_OPT_MPEG=mpeg_encode' ; 
+replace into Config set Id = '29' , Name = 'ZM_PATH_FFMPEG', Value = '/usr/bin/ffmpeg', Type = 'string', DefaultValue = '/usr/local/bin/ffmpeg', Hint = '/absolute/path/to/somewhere', Pattern = '(?-xism:^((?:/[^/]*)+?)/?$)', Format = ' $1 ', Prompt = 'Path to (optional) ffmpeg mpeg encoder', Help = 'This path should point to where the ffmpeg has been installed.', Category = 'tools', Readonly =  '?1:0', Requires = 'ZM_OPT_MPEG=ffmpeg' ; 
+replace into Config set Id = '30' , Name = 'ZM_FFMPEG_OPTIONS', Value = '-hq -intra', Type = 'string', DefaultValue = '-hq -intra', Hint = 'string', Pattern = '(?-xism:^(.+)$)', Format = ' $1 ', Prompt = 'Additional options to ffmpeg', Help = 'Ffmpeg can take many options on the command line to control the quality of video produced. This option allows you to specify your own set. Check the ffmpeg documentation for the meaning of these and other options.', Category = 'tools', Readonly =  '?1:0', Requires = 'ZM_OPT_MPEG=ffmpeg' ; 
+replace into Config set Id = '31' , Name = 'ZM_OPT_NETPBM', Value = '1', Type = 'boolean', DefaultValue = 'no', Hint = 'yes|no', Pattern = '(?i-xsm:^([yn]))', Format = ' ($1 =~ /^y/) ?\'ye\' :\'n\' ', Prompt = 'Are the (optional) Netpbm utilities installed', Help = 'For low bandwidth situations ZoneMinder will resize images into thumbnails on the fly before sending them to the browser to reduce the network traffic at the expense of CPU on the server. It uses the Netpbm package to do this and this option should be set to where the binaries from that package are installed. If you do not have it installed it means that the images will always be sent full size and rescaled on your browser which may or not be an issue for you.', Category = 'tools', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '32' , Name = 'ZM_PATH_NETPBM', Value = '/usr/bin', Type = 'string', DefaultValue = '/usr/bin', Hint = '/absolute/path/to/somewhere', Pattern = '(?-xism:^((?:/[^/]*)+?)/?$)', Format = ' $1 ', Prompt = 'Path to (optional) Netpbm utilities', Help = 'For low bandwidth situations ZoneMinder will resize images into thumbnails on the fly before sending them to the browser to reduce the network traffic at the expense of CPU on the server. It uses the Netpbm package to do this and this option should be set to where the binaries from that package are installed. If you do not have it installed it means that the images will always be sent full size and rescaled on your browser which may or not be an issue for you.', Category = 'tools', Readonly =  '?1:0', Requires = 'ZM_OPT_NETPBM=1' ; 
+replace into Config set Id = '33' , Name = 'ZM_OPT_TRIGGERS', Value = '0', Type = 'boolean', DefaultValue = 'no', Hint = 'yes|no', Pattern = '(?i-xsm:^([yn]))', Format = ' ($1 =~ /^y/) ?\'ye\' :\'n\' ', Prompt = 'Whether we want to interface external event triggers via socket or device files', Help = 'ZoneMinder can interact with external systems which prompt or cancel alarms. This is done via the zmtrigger.pl script. This option indicates whether you want to use these external triggers, most people will say no here.', Category = 'tools', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '34' , Name = 'ZM_PATH_SOCKS', Value = '/var/lib/zm', Type = 'string', DefaultValue = '/tmp', Hint = '/absolute/path/to/somewhere', Pattern = '(?-xism:^((?:/[^/]*)+?)/?$)', Format = ' $1 ', Prompt = 'Path to the various Unix domain socket files that ZoneMinder uses', Help = 'ZoneMinder generally uses Unix domain sockets where possible. This reduces the need for port assignments and prevents external applications from possibly compromising the daemons. However each Unix socket requires a .sock file to be created. This option where those socket files go.', Category = 'paths', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '35' , Name = 'ZM_PATH_LOGS', Value = '/var/log/zm', Type = 'string', DefaultValue = '/tmp', Hint = '/absolute/path/to/somewhere', Pattern = '(?-xism:^((?:/[^/]*)+?)/?$)', Format = ' $1 ', Prompt = 'Path to the various logs that the ZoneMinder daemons generate', Help = 'There are various daemons that are used by ZoneMinder to perform various tasks. Most generate helpful log files and this is where they go. They can be deleted if not required for debugging.', Category = 'paths', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '36' , Name = 'ZM_VIDEO_STREAM_METHOD', Value = 'mpeg', Type = 'string', DefaultValue = 'jpeg', Hint = 'mpeg|jpeg', Pattern = '(?i-xsm:^([mj]))', Format = ' $1 =~ /^m/ ?\'mpe\' :\'jpe\' ', Prompt = 'Which method should be used to send video streams to your browser, choose\'mpe\' or\'jpe\'', Help = 'ZoneMinder can be configured to use either mpeg encoded video or a series or still jpeg images when sending video streams. This option defines which is used. If you choose mpeg you should ensure that you have the appropriate plugins available on your browser whereas choosing jpeg will work natively on Mozilla and related browsers and with a Java applet on Internet Explorer', Category = 'video', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '37' , Name = 'ZM_VIDEO_TIMED_FRAMES', Value = '1', Type = 'boolean', DefaultValue = 'yes', Hint = 'yes|no', Pattern = '(?i-xsm:^([yn]))', Format = ' ($1 =~ /^y/) ?\'ye\' :\'n\' ', Prompt = 'Whether video frames are sent tagged with a timestamp for more realistic streaming', Help = 'When using streamed MPEG based video, either for live monitor streams or events, ZoneMinder can send the streams in two ways. If this option is selected then the timestamp for each frame, taken from i\'s capture time, is included in the stream. This means that where the frame rate varies, for instance around an alarm, the stream will still maintain i\'s\'rea\' timing. If this option is not selected then an approximate frame rate is calculated and that is used to schedule frames instead. This option should be selected unless you encounter problems with your preferred streaming method.', Category = 'video', Readonly =  '?1:0', Requires = 'ZM_VIDEO_STREAM_METHOD=mpeg' ; 
+replace into Config set Id = '38' , Name = 'ZM_VIDEO_LIVE_FORMAT', Value = 'asf', Type = 'string', DefaultValue = 'asf', Hint = 'string', Pattern = '(?-xism:^(.+)$)', Format = ' $1 ', Prompt = 'What format\'liv\' video streams are played in', Help = 'When using MPEG mode ZoneMinder can output live video. However what formats are handled by the browser varies greatly between machines. This option allows you to specify a video format using a file extension format, so you would just enter the extension of the file type you would like and the rest is determined from that. The default of\'as\' works well under Windows with Windows Media Player but \'m currently not sure what, if anything, works on a Linux platform. If you find out please let me know! If this option is left blank then live streams will revert to being in motion jpeg format', Category = 'video', Readonly =  '?1:0', Requires = 'ZM_VIDEO_STREAM_METHOD=mpeg' ; 
+replace into Config set Id = '39' , Name = 'ZM_VIDEO_REPLAY_FORMAT', Value = 'asf', Type = 'string', DefaultValue = 'asf', Hint = 'string', Pattern = '(?-xism:^(.+)$)', Format = ' $1 ', Prompt = 'What format\'repla\' video streams are played in', Help = 'When using MPEG mode ZoneMinder can replay events in encoded video format. However what formats are handled by the browser varies greatly between machines. This option allows you to specify a video format using a file extension format, so you would just enter the extension of the file type you would like and the rest is determined from that. The default of\'as\' works well under Windows with Windows Media Player and\'mp\', or\'av\' etc should work under Linux. If you knwo any more then please let me know! If this option is left blank then live streams will revert to being in motion jpeg format', Category = 'video', Readonly =  '?1:0', Requires = 'ZM_VIDEO_STREAM_METHOD=mpeg' ; 
+replace into Config set Id = '40' , Name = 'ZM_WEB_TITLE_PREFIX', Value = 'ZM', Type = 'string', DefaultValue = 'ZM', Hint = 'string', Pattern = '(?-xism:^(.+)$)', Format = ' $1 ', Prompt = 'The title prefix displayed on each window', Help = 'If you have more than one installation of ZoneMinder it can be helpful to display different titles for each one. Changing this option allows you to customise the window titles to include further information to aid identification.', Category = 'web', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '41' , Name = 'ZM_WEB_RESIZE_CONSOLE', Value = '1', Type = 'boolean', DefaultValue = 'yes', Hint = 'yes|no', Pattern = '(?i-xsm:^([yn]))', Format = ' ($1 =~ /^y/) ?\'ye\' :\'n\' ', Prompt = 'Should the console window resize itself to fit', Help = 'Traditionally the main ZoneMinder web console window has resized itself to shrink to a size small enough to list only the monitors that are actually present. This is intended to make the window more unobtrusize but may not be to everyones tastes, especially if opened in a tab in browsers which support this kind if layout. Switch this option off to have the console window size left to the users preference', Category = 'web', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '42' , Name = 'ZM_WEB_POPUP_ON_ALARM', Value = '1', Type = 'boolean', DefaultValue = 'yes', Hint = 'yes|no', Pattern = '(?i-xsm:^([yn]))', Format = ' ($1 =~ /^y/) ?\'ye\' :\'n\' ', Prompt = 'Should the monitor window jump to the top if an alarm occurs', Help = 'When viewing a live monitor stream you can specify whether you want the window to pop to the front if an alarm occurs when the window is minimised or behind another window. This is most useful if your monitors are over doors for example when they can pop up if someone comes to the doorway.', Category = 'web', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '43' , Name = 'ZM_OPT_X10', Value = '0', Type = 'boolean', DefaultValue = 'no', Hint = 'yes|no', Pattern = '(?i-xsm:^([yn]))', Format = ' ($1 =~ /^y/) ?\'ye\' :\'n\' ', Prompt = 'Whether we want to interface with X10 devices', Help = 'If you have an X10 Home Automation setup in your home you can use ZoneMinder to initiate or react to X10 signals if your computer has the appropriate interface controller. This option indicates whether X10 options will be available in the browser client.', Category = 'x10', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '44' , Name = 'ZM_X10_DEVICE', Value = '/dev/ttyS0', Type = 'string', DefaultValue = '/dev/ttyS0', Hint = '/absolute/path/to/somewhere', Pattern = '(?-xism:^((?:/[^/]*)+?)/?$)', Format = ' $1 ', Prompt = 'What device is your X10 controller connected on', Help = 'If you have an X10 controller device (e.g. XM10U) connected to your computer this option details which port it is conected on, the default of /dev/ttyS0 maps to serial or com port 1.', Category = 'x10', Readonly =  '?1:0', Requires = 'ZM_OPT_X10=1' ; 
+replace into Config set Id = '45' , Name = 'ZM_X10_HOUSE_CODE', Value = 'A', Type = 'string', DefaultValue = 'A', Hint = 'A-P', Pattern = '(?i-xsm:^([A-P]))', Format = ' uc($1) ', Prompt = 'What X10 house code should be used', Help = 'X10 devices are grouped together by identifying them as all belonging to one House Code. This option details what that is. It should be a single letter between A and P.', Category = 'x10', Readonly =  '?1:0', Requires = 'ZM_OPT_X10=1' ; 
+replace into Config set Id = '46' , Name = 'ZM_X10_DB_RELOAD_INTERVAL', Value = '60', Type = 'integer', DefaultValue = '60', Hint = 'integer', Pattern = '(?-xism:^(\\d+)$)', Format = ' $1 ', Prompt = 'How often (in seconds) the X10 daemon reloads the monitors from the database', Help = 'The zmx10 daemon periodically checks the database to find out what X10 events trigger, or result from, alarms. This option determines how frequently this check occurs, unless you change this area frequently this can be a fairly large value.', Category = 'x10', Readonly =  '?1:0', Requires = 'ZM_OPT_X10=1' ; 
+replace into Config set Id = '47' , Name = 'ZM_WEB_SOUND_ON_ALARM', Value = '0', Type = 'boolean', DefaultValue = 'no', Hint = 'yes|no', Pattern = '(?i-xsm:^([yn]))', Format = ' ($1 =~ /^y/) ?\'ye\' :\'n\' ', Prompt = 'Should the monitor window play a sound if an alarm occurs', Help = 'When viewing a live monitor stream you can specify whether you want the window to play a sound to alert you if an alarm occurs.', Category = 'web', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '48' , Name = 'ZM_WEB_ALARM_SOUND', Value = '', Type = 'string', DefaultValue = '', Hint = 'filename', Pattern = '(?-xism:^([a-zA-Z0-9-_.]+)$)', Format = ' $1 ', Prompt = 'The sound to play on alarm, put this in the sounds directory', Help = 'You can specify a sound file to play if an alarm occurs whilst you are watching a live monitor stream. So long as your browser understands the format it does not need to be any particular type. This file should be placed in the sounds directory defined earlier.', Category = 'web', Readonly =  '?1:0', Requires = 'ZM_WEB_SOUND_ON_ALARM=1' ; 
+replace into Config set Id = '49' , Name = 'ZM_WEB_COMPACT_MONTAGE', Value = '0', Type = 'boolean', DefaultValue = 'no', Hint = 'yes|no', Pattern = '(?i-xsm:^([yn]))', Format = ' ($1 =~ /^y/) ?\'ye\' :\'n\' ', Prompt = 'Whether to compact the montage view by removing extra detail', Help = 'The montage view shows the output of all of your active monitors in one window. This include a small menu and status information for each one. This can increase the web traffic and make the window larger than may be desired. Setting this option on removes all this extraneous information and just displays the images.', Category = 'web', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '50' , Name = 'ZM_WEB_MONTAGE_MAX_COLS', Value = '2', Type = 'integer', DefaultValue = '2', Hint = 'integer', Pattern = '(?-xism:^(\\d+)$)', Format = ' $1 ', Prompt = 'The maximum number of monitor columns in the montage view', Help = 'The\'montag\' view shows images from all your monitors at once. This parameter defines how many monitors to place across your screen before moving to the next row. If you have a very wide screen and/or small images from your cameras this can be a bigger value however if not, of if you prefer the images stacked vertically it should be small.', Category = 'web', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '51' , Name = 'ZM_WEB_MONTAGE_WIDTH', Value = '0', Type = 'integer', DefaultValue = '0', Hint = 'integer', Pattern = '(?-xism:^(\\d+)$)', Format = ' $1 ', Prompt = 'What width should each monitor in the montage view be', Help = 'In the montage view it is possible to view all of your monitors at once. If they are all different sizes this can be fairly untidy. Setting this option allows you to constrain the width of each of the monitor views to a fixed value to make the window tidier overall. Leaving it at the default of zero lets each monitor be displayed at i\'s normal native size.', Category = 'web', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '52' , Name = 'ZM_WEB_MONTAGE_HEIGHT', Value = '0', Type = 'integer', DefaultValue = '0', Hint = 'integer', Pattern = '(?-xism:^(\\d+)$)', Format = ' $1 ', Prompt = 'What height should each monitor in the montage view be', Help = 'In the montage view it is possible to view all of your monitors at once. If they are all different sizes this can be fairly untidy. Setting this option allows you to constrain the height of each of the monitor views to a fixed value to make the window tidier overall. Leaving it at the default of zero lets each monitor be displayed at i\'s normal native size.', Category = 'web', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '53' , Name = 'ZM_OPT_FAST_DELETE', Value = '1', Type = 'boolean', DefaultValue = 'yes', Hint = 'yes|no', Pattern = '(?i-xsm:^([yn]))', Format = ' ($1 =~ /^y/) ?\'ye\' :\'n\' ', Prompt = 'When deleting events should the client only delete the database records for speed', Help = 'Normally an event created as the result of an alarm consists of entries in one or more database tables plus the various files associated with it. When deleting events in the browser it can take a long time to remove all of this if your are trying to do a lot of events at once. It is recommended that you set this option which means that the browser client only deletes the key entries in the events table, which means the events will no longer appear in listing, and leaves the zmaudit daemon to clear up the rest later.', Category = 'system', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '54' , Name = 'ZM_STRICT_VIDEO_CONFIG', Value = '1', Type = 'boolean', DefaultValue = 'yes', Hint = 'yes|no', Pattern = '(?i-xsm:^([yn]))', Format = ' ($1 =~ /^y/) ?\'ye\' :\'n\' ', Prompt = 'Whether to allow errors in setting video config to be fatal', Help = 'With some video devices errors can be reported in setting the various video attributes when in fact the operation was successful. Switching this option off will still allow these errors to be reported but will not cause them to kill the video capture daemon. Note however that doing this will cause all errors to be ignored including those which are genuine and which may cause the video capture to not function correctly. Use this option with caution.', Category = 'config', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '55' , Name = 'ZM_CAPTURES_PER_FRAME', Value = '1', Type = 'integer', DefaultValue = '1', Hint = 'integer', Pattern = '(?-xism:^(\\d+)$)', Format = ' $1 ', Prompt = 'How many images are captured per returned frame, for shared local cameras', Help = 'If you are using cameras attached to a video capture card which forces multiple inputs to share one capture chip, it can sometimes produce images with interlaced frames reversed resulting in poor image quality and a distinctive comb edge appearance. Increasing this setting allows you to force additional image captures before one is selected as the captured frame. This allows the capture hardware to\'settle dow\' and produce better quality images at the price of lesser capture rates. This option has no effect on (a) network cameras, or (b) where multiple inputs do not share a capture chip', Category = 'config', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '56' , Name = 'ZM_SHM_KEY', Value = '0x7a6d2000', Type = 'hexadecimal', DefaultValue = '0x7a6d2000', Hint = 'hexadecimal', Pattern = '(?-xism:^(?:0x)?([0-9a-f]{1,8})$)', Format = '\'0\'.$1 ', Prompt = 'Shared memory key to use, only change if it clashes with another application', Help = 'ZoneMinder uses shared memory to speed up communication between modules. To identify the right area to use shared memory keys are used. This option controls what the base key is, each monitor will have i\'s Id o\'ed with this to get the actual key used.', Category = 'system', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '57' , Name = 'ZM_FILTER_RELOAD_DELAY', Value = '300', Type = 'integer', DefaultValue = '300', Hint = 'integer', Pattern = '(?-xism:^(\\d+)$)', Format = ' $1 ', Prompt = 'How often (in seconds) filters are reloaded in zmfilter.pl', Help = 'ZoneMinder allows you to save filters to the database which allow events that match certain criteria to be deleted or uploaded to a remote machine. The zmfilter daemon loads these and does the deleting or uploading. This option determine how often the filters are reloaded to get the latest versions of the filters. If you do\'t change filters very often this can be quite large.', Category = 'system', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '58' , Name = 'ZM_OPT_UPLOAD', Value = '0', Type = 'boolean', DefaultValue = 'no', Hint = 'yes|no', Pattern = '(?i-xsm:^([yn]))', Format = ' ($1 =~ /^y/) ?\'ye\' :\'n\' ', Prompt = 'Should ZoneMinder try and upload events that match corresponding filters', Help = 'In ZoneMinder you can create event filters that specify whether events that match certain criteria should be uploaded to a remote server for archiving. This option specifies whether this functionality should be available', Category = 'ftp', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '59' , Name = 'ZM_UPLOAD_ARCH_FORMAT', Value = 'tar', Type = 'string', DefaultValue = 'tar', Hint = 'tar|zip', Pattern = '(?i-xsm:^([tz]))', Format = ' $1 =~ /^t/ ?\'ta\' :\'zi\' ', Prompt = 'What format the uploaded events should be created in. This can be\'ta\' or\'zi\'', Help = 'Uploaded events may be stored in either .tar or .zip format, this option specifies which. Note that to use this you will need to have the Archive::Tar and/or Archive::Zip perl modules installed.', Category = 'ftp', Readonly =  '?1:0', Requires = 'ZM_OPT_UPLOAD=1' ; 
+replace into Config set Id = '60' , Name = 'ZM_UPLOAD_ARCH_COMPRESS', Value = '0', Type = 'boolean', DefaultValue = 'no', Hint = 'yes|no', Pattern = '(?i-xsm:^([yn]))', Format = ' ($1 =~ /^y/) ?\'ye\' :\'n\' ', Prompt = 'Should archive files be compressed', Help = 'When the archive files are created they can be compressed. However in general since the images are compressed already this saves only a minimal amount of space versus utilising more CPU in their creation. Only enable if you have CPU to waste and are limited in disk space on your remote server or bandwidth', Category = 'ftp', Readonly =  '?1:0', Requires = 'ZM_OPT_UPLOAD=1' ; 
+replace into Config set Id = '61' , Name = 'ZM_UPLOAD_ARCH_ANALYSE', Value = '0', Type = 'boolean', DefaultValue = 'no', Hint = 'yes|no', Pattern = '(?i-xsm:^([yn]))', Format = ' ($1 =~ /^y/) ?\'ye\' :\'n\' ', Prompt = 'Whether to include the analysis files in the archive, bigger but slower', Help = 'When the archive files are created they can contain either just the captured frames or both the captured frames and for frames that caused an alarm the analysed image with the changed area highlighted. This option controls which to do. Only included analysed frames if you have a high bandwidth connection to the remote server or if you need help in figuring out what caused an alarm in the first place', Category = 'ftp', Readonly =  '?1:0', Requires = 'ZM_OPT_UPLOAD=1' ; 
+replace into Config set Id = '62' , Name = 'ZM_UPLOAD_FTP_HOST', Value = '', Type = 'string', DefaultValue = '', Hint = 'host.your.domain', Pattern = '(?-xism:^([a-zA-Z0-9_.-]+)$)', Format = ' $1 ', Prompt = 'The remote server to upload to', Help = 'This is the remote machine that you wish to upload archived events to.', Category = 'ftp', Readonly =  '?1:0', Requires = 'ZM_OPT_UPLOAD=1' ; 
+replace into Config set Id = '63' , Name = 'ZM_UPLOAD_FTP_USER', Value = '', Type = 'string', DefaultValue = '', Hint = 'alphanumeric', Pattern = '(?-xism:^([a-zA-Z0-9-_]+)$)', Format = ' $1 ', Prompt = 'Your ftp username', Help = '', Category = 'ftp', Readonly =  '?1:0', Requires = 'ZM_OPT_UPLOAD=1' ; 
+replace into Config set Id = '64' , Name = 'ZM_UPLOAD_FTP_PASS', Value = '', Type = 'string', DefaultValue = '', Hint = 'string', Pattern = '(?-xism:^(.+)$)', Format = ' $1 ', Prompt = 'Your ftp password', Help = '', Category = 'ftp', Readonly =  '?1:0', Requires = 'ZM_OPT_UPLOAD=1' ; 
+replace into Config set Id = '65' , Name = 'ZM_UPLOAD_FTP_LOC_DIR', Value = '/tmp', Type = 'string', DefaultValue = '/tmp', Hint = '/absolute/path/to/somewhere', Pattern = '(?-xism:^((?:/[^/]*)+?)/?$)', Format = ' $1 ', Prompt = 'The local directory in which to create upload files', Help = '', Category = 'ftp', Readonly =  '?1:0', Requires = 'ZM_OPT_UPLOAD=1' ; 
+replace into Config set Id = '66' , Name = 'ZM_UPLOAD_FTP_REM_DIR', Value = '', Type = 'string', DefaultValue = '', Hint = 'relative/path/to/somewhere', Pattern = '(?-xism:^((?:[^/].*)?)/?$)', Format = ' $1 ', Prompt = 'The remote directory to upload to', Help = '', Category = 'ftp', Readonly =  '?1:0', Requires = 'ZM_OPT_UPLOAD=1' ; 
+replace into Config set Id = '67' , Name = 'ZM_UPLOAD_FTP_TIMEOUT', Value = '120', Type = 'integer', DefaultValue = '120', Hint = 'integer', Pattern = '(?-xism:^(\\d+)$)', Format = ' $1 ', Prompt = 'How long (in seconds) we allow the transfer to take for each file', Help = '', Category = 'ftp', Readonly =  '?1:0', Requires = 'ZM_OPT_UPLOAD=1' ; 
+replace into Config set Id = '68' , Name = 'ZM_UPLOAD_FTP_PASSIVE', Value = '1', Type = 'boolean', DefaultValue = 'yes', Hint = 'yes|no', Pattern = '(?i-xsm:^([yn]))', Format = ' ($1 =~ /^y/) ?\'ye\' :\'n\' ', Prompt = 'Whether to use passive ftp', Help = 'If your computer is behind a firewall or proxy you may need to set FTP to passive mode. In fact for simple transfers it makes little sense to do otherwise anyway but you can set this to\'N\' if you wish.', Category = 'ftp', Readonly =  '?1:0', Requires = 'ZM_OPT_UPLOAD=1' ; 
+replace into Config set Id = '69' , Name = 'ZM_UPLOAD_FTP_DEBUG', Value = '1', Type = 'boolean', DefaultValue = 'yes', Hint = 'yes|no', Pattern = '(?i-xsm:^([yn]))', Format = ' ($1 =~ /^y/) ?\'ye\' :\'n\' ', Prompt = 'Whether to switch ftp debugging on', Help = 'If you are having (or expecting) troubles with uploading archived events then setting this to\'ye\' permits additional information to be included in the zmfilter log file.', Category = 'ftp', Readonly =  '?1:0', Requires = 'ZM_OPT_UPLOAD=1' ; 
+replace into Config set Id = '70' , Name = 'ZM_OPT_EMAIL', Value = '0', Type = 'boolean', DefaultValue = 'no', Hint = 'yes|no', Pattern = '(?i-xsm:^([yn]))', Format = ' ($1 =~ /^y/) ?\'ye\' :\'n\' ', Prompt = 'Should ZoneMinder email you details of events that match corresponding filters', Help = 'In ZoneMinder you can create event filters that specify whether events that match certain criteria should have their details emailed to you at a designated email address. This will allow you to be notified of events as soon as they occur and also to quickly view the events directly. This option specifies whether this functionality should be available. The email created with this option can be any size and is intended to be sent to a regular email reader rather than a mobile device.', Category = 'mail', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '71' , Name = 'ZM_EMAIL_ADDRESS', Value = '', Type = 'string', DefaultValue = '', Hint = 'your.name@your.domain', Pattern = '(?-xism:^([a-zA-Z0-9_.-]+)\\@([a-zA-Z0-9_.-]+)$)', Format = ' $1\\@$\" ', Prompt = 'The email address to send matching event details to', Help = 'This option is used to define the email address that any events that match the appropriate filters will be sent to.', Category = 'mail', Readonly =  '?1:0', Requires = 'ZM_OPT_EMAIL=1' ; 
+replace into Config set Id = '72' , Name = 'ZM_EMAIL_TEXT', Value = '#
+# This is the configuration file for notification emails
+#
+# The tags you can use in here are as follows
+# %ZP% - The path to your ZoneMinder console
+# %MN% - The name of the monitor
+# %MET% - The total number of events for the monitor
+# %MEH% - The number of events for the monitor in the last hour
+# %MED% - The number of events for the monitor in the last day
+# %MEW% - The number of events for the monitor in the last week
+# %MEM% - The number of events for the monitor in the last month
+# %MEA% - The number of archived events for the monitor
+# %MP% - The path to the monitor window
+# %MPS% - The path to the monitor stream
+# %MPI% - The path to the monitor recent image
+# %EP% - The path to the event
+# %EPS% - The path to the event stream
+# %EPI% - The path to the event images
+# %EPI1% - The path to the first alarmed event image
+# %EPIM% - The path to the (first) event image with the highest score
+# %EI1% - Attach first alarmed event image
+# %EIM% - Attach (first) event image with the highest score
+# %EV% - Attach event mpeg video
+# %EI% - The id of the event
+# %EN% - The name of the event
+# %ET% - The time of the event
+# %ED% - The duration of the event
+# %EF% - The number of frames in the event
+# %EFA% - The number of alarm frames in the event
+# %EST% - The total score of the event
+# %ESA% - The average score of the event
+# %ESM% - The maximum score of the event
+# %FN% - The name of the current filter that matched
+# %FP% - The path to the current filter that matched
+
+# Change these to suit your own preferences
+subject =\"ZoneMinder: Alarm - %MN%-%EI% (%ESM% - %ESA% %EFA%\"
+body =\"
+Hello,
+
+An alarm has been detected on your installation of the ZoneMinder.
+
+The details are as follows :-
+
+  Monitor  : %MN%
+  Event Id : %EI%
+  Duration : %ED%
+  Frames   : %EF% (%EFA%)
+  Scores   : t%EST% m%ESM% a%ESA%
+
+This alarm was matched by the %FN% filter and can be viewed at %EPS%
+
+	# %ZP% - The path to your ZoneMinder console
+	# %MN% - The name of the monitor
+	# %MET% - The total number of events for the monitor
+	# %MEH% - The number of events for the monitor in the last hour
+	# %MED% - The number of events for the monitor in the last day
+	# %MEW% - The number of events for the monitor in the last week
+	# %MEM% - The number of events for the monitor in the last month
+	# %MEA% - The number of archived events for the monitor
+	# %MP% - The path to the monitor window
+	# %MPS% - The path to the monitor stream
+	# %MPI% - The path to the monitor recent image
+	# %EP% - The path to the event
+	# %EPS% - The path to the event stream
+	# %EPI% - The path to the event images
+	# %EPI1% - The path to the first alarmed event image
+	# %EPIM% - The path to the (first) event image with the highest score
+	# %EI1% - Attach first alarmed event image
+	# %EIM% - Attach (first) event image with the highest score
+	# %EV% - Attach event mpeg video
+	# %EI% - The id of the event
+	# %EN% - The name of the event
+	# %ET% - The time of the event
+	# %ED% - The duration of the event
+	# %EF% - The number of frames in the event
+	# %EFA% - The number of alarm frames in the event
+	# %EST% - The total score of the event
+	# %ESA% - The average score of the event
+	# %ESM% - The maximum score of the event
+	# %FN% - The name of the current filter that matched
+	# %FP% - The path to the current filter that matched
+
+ZoneMinder\"
+', Type = 'text', DefaultValue = '', Hint = 'free text', Pattern = '(?-xism:^(.+)$)', Format = ' $1 ', Prompt = 'The text of the email used to send matching event details', Help = 'This option is used to define the content of the email that is sent for any events that match the appropriate filters.', Category = 'mail', Readonly =  '1?1:0', Requires = 'ZM_OPT_EMAIL=1' ; 
+replace into Config set Id = '73' , Name = 'ZM_OPT_MESSAGE', Value = '0', Type = 'boolean', DefaultValue = 'no', Hint = 'yes|no', Pattern = '(?i-xsm:^([yn]))', Format = ' ($1 =~ /^y/) ?\'ye\' :\'n\' ', Prompt = 'Should ZoneMinder message you with details of events that match corresponding filters', Help = 'In ZoneMinder you can create event filters that specify whether events that match certain criteria should have their details sent to you at a designated short message email address. This will allow you to be notified of events as soon as they occur. This option specifies whether this functionality should be available. The email created by this option will be brief and is intended to be sent to an SMS gateway or a minimal mail reader such as a mobile device or phone rather than a regular email reader.', Category = 'mail', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '74' , Name = 'ZM_MESSAGE_ADDRESS', Value = '', Type = 'string', DefaultValue = '', Hint = 'your.name@your.domain', Pattern = '(?-xism:^([a-zA-Z0-9_.-]+)\\@([a-zA-Z0-9_.-]+)$)', Format = ' $1\\@$\" ', Prompt = 'The email address to send matching event details to', Help = 'This option is used to define the short message email address that any events that match the appropriate filters will be sent to.', Category = 'mail', Readonly =  '?1:0', Requires = 'ZM_OPT_MESSAGE=1' ; 
+replace into Config set Id = '75' , Name = 'ZM_MESSAGE_TEXT', Value = '# 
+# This is the configuration file for notification messages
+# 
+# The tags you can use in here are as follows
+# The path tags however may be over long for a message
+# destined for an SMS and will in any case probably not
+# direct you to a WAP compatible page (yet).
+# %ZP% - The path to your ZoneMinder console
+# %MN% - The name of the monitor
+# %MET% - The total number of events for the monitor
+# %MEH% - The number of events for the monitor in the last hour
+# %MED% - The number of events for the monitor in the last day
+# %MEW% - The number of events for the monitor in the last week
+# %MEM% - The number of events for the monitor in the last month
+# %MEA% - The number of archived events for the monitor
+# %MP% - The path to the monitor window
+# %MPS% - The path to the monitor stream
+# %MPI% - The path to the monitor recent image
+# %EP% - The path to the event
+# %EPS% - The path to the event stream
+# %EPI% - The path to the event images
+# %EPI1% - The path to the first alarmed event image
+# %EPIM% - The path to the (first) event image with the highest score
+# %EI1% - Attach first alarmed event image
+# %EIM% - Attach (first) event image with the highest score
+# %EV% - Attach event mpeg video
+# %EI% - The id of the event
+# %EN% - The name of the event
+# %ET% - The time of the event
+# %ED% - The duration of the event
+# %EF% - The number of frames in the event
+# %EFA% - The number of alarm frames in the event
+# %EST% - The total score of the event
+# %ESA% - The average score of the event
+# %ESM% - The maximum score of the event
+# %FN% - The name of the current filter that matched
+# %FP% - The path to the current filter that matched
+
+# Change these to suit your own preferences
+subject =\"ZoneMinder: Alarm - %MN%-%EI\"
+body =\"ZM alarm detected - %ED% secs, %EF%/%EFA% frames, t%EST%/m%ESM%/a%ESA% score\"
+', Type = 'text', DefaultValue = '', Hint = 'free text', Pattern = '(?-xism:^(.+)$)', Format = ' $1 ', Prompt = 'The text of the message used to send matching event details', Help = 'This option is used to define the content of the message that is sent for any events that match the appropriate filters.', Category = 'mail', Readonly =  '1?1:0', Requires = 'ZM_OPT_MESSAGE=1' ; 
+replace into Config set Id = '76' , Name = 'ZM_NEW_MAIL_MODULES', Value = '0', Type = 'boolean', DefaultValue = 'no', Hint = 'yes|no', Pattern = '(?i-xsm:^([yn]))', Format = ' ($1 =~ /^y/) ?\'ye\' :\'n\' ', Prompt = 'Whether to use a newer perl method to send emails', Help = 'Traditionally ZoneMinder has used the MIME::Entity perl module to construct and send notification emails and messages. Some people have reported problems with this module not being present at all or flexible enough for their needs. If you are one of those people this option allows you to select a new mailing method using MIME::Lite and Net::SMTP instead. This method was contributed by Ross Melin and should work for everyone but has not been extensively tested so currently is not selected by default.', Category = 'mail', Readonly =  '?1:0', Requires = 'ZM_OPT_EMAIL=1;ZM_OPT_MESSAGE=1' ; 
+replace into Config set Id = '77' , Name = 'ZM_EMAIL_HOST', Value = 'localhost', Type = 'string', DefaultValue = 'localhost', Hint = 'host.your.domain', Pattern = '(?-xism:^([a-zA-Z0-9_.-]+)$)', Format = ' $1 ', Prompt = 'The host address of your SMTP mail server', Help = 'If you have chosen SMTP as the method by which to send notification emails or messages then this option allows you to choose which SMTP server to use to send them. The default of localhost may work if you have the sendmail, exim or a similar daemon running however you may wish to enter your IS\'s SMTP mail server here.', Category = 'mail', Readonly =  '?1:0', Requires = 'ZM_OPT_EMAIL=1;ZM_OPT_MESSAGE=1' ; 
+replace into Config set Id = '78' , Name = 'ZM_FROM_EMAIL', Value = '', Type = 'string', DefaultValue = '', Hint = 'your.name@your.domain', Pattern = '(?-xism:^([a-zA-Z0-9_.-]+)\\@([a-zA-Z0-9_.-]+)$)', Format = ' $1\\@$\" ', Prompt = 'The email address you wish your event notifications to originate from', Help = 'The emails or messages that will be sent to you informing you of events can appear to come from a designated email address to help you with mail filtering etc. An address of something like ZoneMinder@your.domain is recommended.', Category = 'mail', Readonly =  '?1:0', Requires = 'ZM_OPT_EMAIL=1;ZM_OPT_MESSAGE=1' ; 
+replace into Config set Id = '79' , Name = 'ZM_URL', Value = '', Type = 'string', DefaultValue = '', Hint = 'http://host.your.domain/', Pattern = '(?-xism:^(?:http://)?(.+)$)', Format = '\'http:/\'.$1 ', Prompt = 'The URL of your ZoneMinder installation', Help = 'The emails or messages that will be sent to you informing you of events can include a link to the events themselves for easy viewing. If you intend to use this feature then set this option to the url of your installation as it would appear from where you read your email, e.g. http://host.your.domain/zm.php.', Category = 'mail', Readonly =  '?1:0', Requires = 'ZM_OPT_EMAIL=1;ZM_OPT_MESSAGE=1' ; 
+replace into Config set Id = '80' , Name = 'ZM_MAX_RESTART_DELAY', Value = '600', Type = 'integer', DefaultValue = '600', Hint = 'integer', Pattern = '(?-xism:^(\\d+)$)', Format = ' $1 ', Prompt = 'The maximum delay (in seconds) for daemon restart attempts.', Help = 'The zmdc (zm daemopn control) process controls when processeses are started or stopped and will attempt to restart any that fail. If a daemon fails frequently then a delay is introduced between each restart attempt. If the daemon stills fails then this delay is increased to prevent extra load being placed on the system by continual restarts. This option controls what this maximum delay is.', Category = 'system', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '81' , Name = 'ZM_WATCH_CHECK_INTERVAL', Value = '10', Type = 'integer', DefaultValue = '10', Hint = 'integer', Pattern = '(?-xism:^(\\d+)$)', Format = ' $1 ', Prompt = 'How often to check the capture daemons have not locked up', Help = 'The zmwatch daemon checks the image capture performance of the capture daemons to ensure that they have not locked up (rarely a sync error may occur which blocks indefinately). This option determines how often the daemons are checked.', Category = 'system', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '82' , Name = 'ZM_WATCH_MAX_DELAY', Value = '5', Type = 'decimal', DefaultValue = '5', Hint = 'decimal', Pattern = '(?-xism:^(\\d+(?:\\.\\d+)?)$)', Format = ' $1 ', Prompt = 'The maximum delay since the last captured image we will allow before restarting the capture daemons', Help = 'The zmwatch daemon checks the image capture performance of the capture daemons to ensure that they have not locked up (rarely a sync error may occur which blocks indefinately). This option determines the maximum delay we will allow since the last captured frame. The daemon will be restarted if it has not captured any images after this period though the actual restart may take slightly longer in conjunction with the check interval value above.', Category = 'system', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '83' , Name = 'ZM_FORCED_ALARM_SCORE', Value = '255', Type = 'integer', DefaultValue = '255', Hint = 'integer', Pattern = '(?-xism:^(\\d+)$)', Format = ' $1 ', Prompt = 'Score to give forced alarms', Help = 'The\'zm\' utility can be used to force an alarm on a monitor rather than rely on the motion detection algorithms. This option determines what score to give these alarms to distinguish them from regular ones. It must be 255 or less.', Category = 'config', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '84' , Name = 'ZM_BULK_FRAME_INTERVAL', Value = '100', Type = 'integer', DefaultValue = '100', Hint = 'integer', Pattern = '(?-xism:^(\\d+)$)', Format = ' $1 ', Prompt = 'How often a bulk frame should be written to the database', Help = 'Traditionally ZoneMinder writes an entry into the Frames database table for each frame that is captured and saved. This works well in motion detection scenarios but when in a DVR situation \'Recor\' or\'Mocor\' mode) this results in a huge number of frame writes and a lot of database and disk bandwidth for very little additional information. Setting this to a non-zero value will enabled ZoneMinder to group these non-alarm frames into one\'bul\' frame entry which saves a lot of bandwidth and space. The only disadvantage of this is that timing information for individual frames is lost but in constant frame rate situations this is usually not significant. This setting is ignored in Modect mode and individual frames are still written if an alarm occurs in Mocord mode also.', Category = 'config', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '85' , Name = 'ZM_EVENT_IMAGE_DIGITS', Value = '3', Type = 'integer', DefaultValue = '3', Hint = 'integer', Pattern = '(?-xism:^(\\d+)$)', Format = ' $1 ', Prompt = 'How many significant digits are used in event image numbering', Help = 'As event images are captured they are stored to the filesystem with a numerical index. By default this index has three digits so the numbers start 001, 002 etc. This works works for most scenarios as events with more than 999 frames are rarely captured. However if you have extremely long events and use external applications then you may wish to increase this to ensure correct sorting of images in listings etc. Warning, increasing this value on a live system may render existing events unviewable as the event will have been saved with the previous scheme. Decreasing this value should have no ill effects.', Category = 'config', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '86' , Name = 'ZM_RECORD_EVENT_STATS', Value = '1', Type = 'boolean', DefaultValue = 'yes', Hint = 'yes|no', Pattern = '(?i-xsm:^([yn]))', Format = ' ($1 =~ /^y/) ?\'ye\' :\'n\' ', Prompt = 'Whether to record event statistical information, switch off if too slow', Help = 'This version of ZoneMinder records detailed information about events in the Stats table. This can help in profiling what the optimum settings are for Zones though this is tricky at present. However in future releases this will be done more easily and intuitively, especially with a large sample of events. The default option of\'ye\' allows this information to be collected now in readiness for this but if you are concerned about performance you can switch this off in which case no Stats information will be saved.', Category = 'system', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '87' , Name = 'ZM_RECORD_DIAG_IMAGES', Value = '0', Type = 'boolean', DefaultValue = 'no', Hint = 'yes|no', Pattern = '(?i-xsm:^([yn]))', Format = ' ($1 =~ /^y/) ?\'ye\' :\'n\' ', Prompt = 'Whether to record intermediate alarm diagnostic images, can be very slow', Help = 'In addition to recording event statistics you can also record the intermediate diagnostic images that display the results of the various checks and processing that occur when trying to determine if an alarm event has taken place. There are several of these images generated for each frame and zone for each alarm or alert frame so this can have a massive impact on performance. Only switch this setting on for debug or analysis purposes and remember to switch it off again once no longer required.', Category = 'system', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '88' , Name = 'ZM_CREATE_ANALYSIS_IMAGES', Value = '1', Type = 'boolean', DefaultValue = 'yes', Hint = 'yes|no', Pattern = '(?i-xsm:^([yn]))', Format = ' ($1 =~ /^y/) ?\'ye\' :\'n\' ', Prompt = 'Whether to create analysed alarm images with motion outlined', Help = 'By default during an alarm ZoneMinder records both the raw captured image and one that has been analysed and had areas where motion was detected outlined. This can be very useful during zone configuration or in analysing why events occured. However it also incurs some overhead and in a stable system may no longer be necessary. This parameter allows you to switch the generation of these images off.', Category = 'system', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '89' , Name = 'ZM_OPT_FRAME_SERVER', Value = '1', Type = 'boolean', DefaultValue = 'no', Hint = 'yes|no', Pattern = '(?i-xsm:^([yn]))', Format = ' ($1 =~ /^y/) ?\'ye\' :\'n\' ', Prompt = 'Should analysis farm out the writing of images to disk', Help = 'In some circumstances it is possible for a slow disk to take so long writing images to disk that it causes the analysis daemon to fall behind especially during high frame rate events. Setting this option to yes enables a frame server daemon (zmf) which will be sent the images from the analysis daemon and will do the actual writing of images itself freeing up the analysis daemon to get on with other things. Should this transmission fail or other permanent or transient error occur, this function will fall back to the analysis daemon.', Category = 'system', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '90' , Name = 'ZM_FRAME_SOCKET_SIZE', Value = '0', Type = 'integer', DefaultValue = '0', Hint = 'integer', Pattern = '(?-xism:^(\\d+)$)', Format = ' $1 ', Prompt = 'Specify the size of the frame server socket buffer if non-standard', Help = 'For large captured images it is possible for the writes from the analysis daemon to the frame server to fail as the amount to be written exceeds the default buffer size. While the images are then written by the analysis daemon so no data is lost, it defeats the object of the frame server daemon in the first place. You can use this option to indicate that a larger buffer size should be used. Note that you may have to change the existing maximum socket buffer size on your system via sysctl (or in /proc/sys/net/core/wmem_max) to allow this new size to be set. Alternatively you can change the default buffer size on your system in the same way in which case that will be used with no change necessary in this option', Category = 'system', Readonly =  '?1:0', Requires = 'ZM_OPT_FRAME_SERVER=1' ; 
+replace into Config set Id = '91' , Name = 'ZM_OPT_CONTROL', Value = '0', Type = 'boolean', DefaultValue = 'no', Hint = 'yes|no', Pattern = '(?i-xsm:^([yn]))', Format = ' ($1 =~ /^y/) ?\'ye\' :\'n\' ', Prompt = 'Whether to support controllable (e.g. pan/tilt/zoom) cameras', Help = 'ZoneMinder includes limited support for controllable cameras. A number of sample protocols are included and others can easily be added. If you wish to control your cameras via ZoneMinder then select this option otherwise if you only have static cameras or use other control methods then leave this option off.', Category = 'system', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '92' , Name = 'ZM_CHECK_FOR_UPDATES', Value = '0', Type = 'boolean', DefaultValue = 'yes', Hint = 'yes|no', Pattern = '(?i-xsm:^([yn]))', Format = ' ($1 =~ /^y/) ?\'ye\' :\'n\' ', Prompt = 'Whether to check with zoneminder.com for updated versions', Help = 'From ZoneMinder version 1.17.0 onwards new versions are expected to be more frequent. To save checking manually for each new version ZoneMinder can check with the zoneminder.com website to determine the most recent release. These checks are infrequent, about once per week, and no personal or system information is transmitted other than your current version number. If you do not wish these checks to take place or your ZoneMinder system has no internet access you can switch these check off with this configuration variable', Category = 'system', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '93' , Name = 'ZM_WEB_REFRESH_METHOD', Value = 'javascript', Type = 'string', DefaultValue = 'javascript', Hint = 'javascript|http', Pattern = '(?i-xsm:^([jh]))', Format = ' $1 =~ /^j/ ?\'javascrip\' :\'htt\' ', Prompt = 'What method windows should use to refresh themselves, choose either javascript or http', Help = 'Many windows in Javascript need to refresh themselves to keep their information current. This option determines what method they should use to do this. Choosing\'javascrip\' means that each window will have a short JavaScript statement in with a timer to prompt the refresh. This is the most compatible method. Choosing\'htt\' means the refresh instruction is put in the HTTP header. This is a cleaner method but refreshes are interrupted or cancelled when a link in the window is clicked meaning that the window will no longer refresh and this would have to be done manually.', Category = 'web', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '94' , Name = 'ZM_WEB_DOUBLE_BUFFER', Value = '1', Type = 'boolean', DefaultValue = 'yes', Hint = 'yes|no', Pattern = '(?i-xsm:^([yn]))', Format = ' ($1 =~ /^y/) ?\'ye\' :\'n\' ', Prompt = 'Whether still images should be double buffered to avoid flickering', Help = 'From version 1.18.0 ZoneMinder can use a double buffering method to preload still image prior to displaying them on screen. This reduces flickering and makes viewing still images a more pleasant experience. However some devices may not support the JavaScript/frames combination needed to make this possible in which case this option should be switched off. As this option uses JavaScript it will only have an effect if the ZM_WEB_REFRESH_METHOD option is set to JavaScript also.', Category = 'web', Readonly =  '?1:0', Requires = 'ZM_WEB_REFRESH_METHOD=javascript' ; 
+replace into Config set Id = '95' , Name = 'ZM_WEB_EVENTS_PER_PAGE', Value = '25', Type = 'integer', DefaultValue = '25', Hint = 'integer', Pattern = '(?-xism:^(\\d+)$)', Format = ' $1 ', Prompt = 'How many events to list per page in paged mode', Help = 'In the event list view you can either list all events or just a page at a time. This option controls how many events are listed per page in paged mode and how often to repeat the column headers in non-paged mode.', Category = 'web', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '96' , Name = 'ZM_WEB_FRAMES_PER_LINE', Value = '4', Type = 'integer', DefaultValue = '4', Hint = 'integer', Pattern = '(?-xism:^(\\d+)$)', Format = ' $1 ', Prompt = 'How many frames to list per line in the frame view', Help = 'In the event frame view you can view the individual frames that comprise an event. This option allows you to specify how many frames go on each line. The product of this option and the frame lines option are the number of frames per page', Category = 'web', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '97' , Name = 'ZM_WEB_FRAME_LINES', Value = '4', Type = 'integer', DefaultValue = '4', Hint = 'integer', Pattern = '(?-xism:^(\\d+)$)', Format = ' $1 ', Prompt = 'How many lines of frames to list in the frame view', Help = 'In the event frame view you can view the individual frames that comprise an event. This option allows you to specify how many lines of frames are shown per page. The product of this option and the frames per line option are the number of frames per page.', Category = 'web', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '98' , Name = 'ZM_WEB_LIST_THUMBS', Value = '1', Type = 'boolean', DefaultValue = 'no', Hint = 'yes|no', Pattern = '(?i-xsm:^([yn]))', Format = ' ($1 =~ /^y/) ?\'ye\' :\'n\' ', Prompt = 'Whether to display mini-thumbnails of event images in event lists', Help = 'Ordinarily the event lists just display text details of the events to save space and time. By switching this option on you can also display small thumbnails to help you identify events of interest. The size of these thumbnails is controlled by the following two options.', Category = 'web', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '99' , Name = 'ZM_WEB_LIST_THUMB_WIDTH', Value = '48', Type = 'integer', DefaultValue = '48', Hint = 'integer', Pattern = '(?-xism:^(\\d+)$)', Format = ' $1 ', Prompt = 'The width of the thumbnails that appear in the event lists', Help = 'This options controls the width of the thumbnail images that appear in the event lists. It should be fairly small to fit in with the rest of the table. If you prefer you can specify a height instead in the next option but you should only use one of the width or height and the other option should be set to zero. If both width and height are specified then width will be used and height ignored.', Category = 'web', Readonly =  '?1:0', Requires = 'ZM_WEB_LIST_THUMBS=1' ; 
+replace into Config set Id = '100' , Name = 'ZM_WEB_LIST_THUMB_HEIGHT', Value = '0', Type = 'integer', DefaultValue = '0', Hint = 'integer', Pattern = '(?-xism:^(\\d+)$)', Format = ' $1 ', Prompt = 'The height of the thumbnails that appear in the event lists', Help = 'This options controls the height of the thumbnail images that appear in the event lists. It should be fairly small to fit in with the rest of the table. If you prefer you can specify a width instead in the previous option but you should only use one of the width or height and the other option should be set to zero. If both width and height are specified then width will be used and height ignored.', Category = 'web', Readonly =  '?1:0', Requires = 'ZM_WEB_LIST_THUMBS=1' ; 
+replace into Config set Id = '101' , Name = 'ZM_WEB_H_REFRESH_MAIN', Value = '300', Type = 'integer', DefaultValue = '300', Hint = 'integer', Pattern = '(?-xism:^(\\d+)$)', Format = ' $1 ', Prompt = 'How often (in seconds) the main console window should refresh itself', Help = 'The main console window lists a general status and the event totals for all monitors. This is not a trivial task and should not be repeated too frequently or it may affect the performance of the rest of the system.', Category = 'highband', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '102' , Name = 'ZM_WEB_H_REFRESH_CYCLE', Value = '10', Type = 'integer', DefaultValue = '10', Hint = 'integer', Pattern = '(?-xism:^(\\d+)$)', Format = ' $1 ', Prompt = 'How often (in seconds) the cycle watch window swaps to the next monitor', Help = 'The cycle watch window is a method of continuously cycling between images from all of your monitors. This option determines how often to refresh with a new image.', Category = 'highband', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '103' , Name = 'ZM_WEB_H_REFRESH_IMAGE', Value = '5', Type = 'integer', DefaultValue = '5', Hint = 'integer', Pattern = '(?-xism:^(\\d+)$)', Format = ' $1 ', Prompt = 'How often (in seconds) the watched image is refreshed (if not streaming)', Help = 'The live images from a monitor can be viewed in either streamed or stills mode. This option determines how often a stills image is refreshed, it has no effect if streaming is selected.', Category = 'highband', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '104' , Name = 'ZM_WEB_H_REFRESH_STATUS', Value = '3', Type = 'integer', DefaultValue = '3', Hint = 'integer', Pattern = '(?-xism:^(\\d+)$)', Format = ' $1 ', Prompt = 'How often (in seconds) the status frame refreshes itself in the watch window', Help = 'The monitor window is actually made from several frames. The one in the middle merely contains a monitor status which needs to refresh fairly frequently to give a true indication. This option determines that frequency.', Category = 'highband', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '105' , Name = 'ZM_WEB_H_REFRESH_EVENTS', Value = '30', Type = 'integer', DefaultValue = '30', Hint = 'integer', Pattern = '(?-xism:^(\\d+)$)', Format = ' $1 ', Prompt = 'How often (in seconds) the event listing is refreshed in the watch window', Help = 'The monitor window is actually made from several frames. The lower framme contains a listing of the last few events for easy access. This option determines how often this is refreshed.', Category = 'highband', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '106' , Name = 'ZM_WEB_H_DEFAULT_SCALE', Value = '100', Type = 'integer', DefaultValue = '100', Hint = 'integer', Pattern = '(?-xism:^(\\d+)$)', Format = ' $1 ', Prompt = 'What the default scaling factor applied to\'liv\' or\'even\' views is (%)', Help = 'Normally ZoneMinder will display\'liv\' or\'even\' streams in their native size. However if you have monitors with large dimensions or a slow link you may prefer to reduce this size, alternatively for small monitors you can enlarge it. This options lets you specify what the default scaling factor will be. It is expressed as a percentage so 100 is normal size, 200 is double size etc.', Category = 'highband', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '107' , Name = 'ZM_WEB_H_DEFAULT_RATE', Value = '100', Type = 'integer', DefaultValue = '100', Hint = 'integer', Pattern = '(?-xism:^(\\d+)$)', Format = ' $1 ', Prompt = 'What the default replay rate factor applied to\'even\' views is (%)', Help = 'Normally ZoneMinder will display\'even\' streams at their native rate, i.e. as close to real-time as possible. However if you have long events it is often convenient to replay them at a faster rate for review. This option lets you specify what the default replay rate will be. It is expressed as a percentage so 100 is normal rate, 200 is double speed etc.', Category = 'highband', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '108' , Name = 'ZM_WEB_H_VIDEO_BITRATE', Value = '150000', Type = 'integer', DefaultValue = '150000', Hint = 'integer', Pattern = '(?-xism:^(\\d+)$)', Format = ' $1 ', Prompt = 'What the bitrate of the video encoded stream should be set to', Help = 'When encoding real video via the ffmpeg library a bit rate can be specified which roughly corresponds to the available bandwidth used for the stream. This setting effectively corresponds to a\'qualit\' setting for the video. A low value will result in a blocky image whereas a high value will produce a clearer view. Note that this setting does not control the frame rate of the video however the quality of the video produced is affected both by this setting and the frame rate that the video is produced at. A higher frame rate at a particular bit rate result in individual frames being at a lower quality.', Category = 'highband', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '109' , Name = 'ZM_WEB_H_VIDEO_MAXFPS', Value = '15', Type = 'integer', DefaultValue = '15', Hint = 'integer', Pattern = '(?-xism:^(\\d+)$)', Format = ' $1 ', Prompt = 'What the maximum frame rate for streamed video should be', Help = 'When using streamed video the main control is the bitrate which determines how much data can be transmitted. However a lower bitrate at high frame rates results in a lower quality image. This option allows you to limit the maximum frame rate to ensure that video quality is maintained. An additional advantage is that encoding video at high frame rates is a processor intensive task when for the most part a very high frame rate offers little perceptible improvement over one that has a more manageable resource requirement. Note, this option is implemented as a cap beyond which binary reduction takes place. So if you have a device capturing at 15fps and set this option to 10fps then the video is not produced at 10fps, but rather at 7.5fps (15 divided by 2) as the final frame rate must be the original divided by a power of 2.', Category = 'highband', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '110' , Name = 'ZM_WEB_H_IMAGE_SCALING', Value = '1', Type = 'integer', DefaultValue = '1', Hint = 'integer', Pattern = '(?-xism:^(\\d+)$)', Format = ' $1 ', Prompt = 'How to scale thumbnails in events, bandwidth versus cpu in rescaling', Help = 'A value of 1 sends the whole image to the browser which resizes it in the window, larger values scale down by that amount on the server before sending a reduced size image to the browser. For high bandwidth settings the default of 1 is usually the fastest and also does not result in extraneous thumbnail files being generated.', Category = 'highband', Readonly =  '?1:0', Requires = 'ZM_PATH_NETPBM=/' ; 
+replace into Config set Id = '111' , Name = 'ZM_WEB_M_REFRESH_MAIN', Value = '300', Type = 'integer', DefaultValue = '300', Hint = 'integer', Pattern = '(?-xism:^(\\d+)$)', Format = ' $1 ', Prompt = 'How often (in seconds) the main console window should refresh itself', Help = 'The main console window lists a general status and the event totals for all monitors. This is not a trivial task and should not be repeated too frequently or it may affect the performance of the rest of the system.', Category = 'medband', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '112' , Name = 'ZM_WEB_M_REFRESH_CYCLE', Value = '20', Type = 'integer', DefaultValue = '20', Hint = 'integer', Pattern = '(?-xism:^(\\d+)$)', Format = ' $1 ', Prompt = 'How often (in seconds) the cycle watch window swaps to the next monitor', Help = 'The cycle watch window is a method of continuously cycling between images from all of your monitors. This option determines how often to refresh with a new image.', Category = 'medband', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '113' , Name = 'ZM_WEB_M_REFRESH_IMAGE', Value = '10', Type = 'integer', DefaultValue = '10', Hint = 'integer', Pattern = '(?-xism:^(\\d+)$)', Format = ' $1 ', Prompt = 'How often (in seconds) the watched image is refreshed (if not streaming)', Help = 'The live images from a monitor can be viewed in either streamed or stills mode. This option determines how often a stills image is refreshed, it has no effect if streaming is selected.', Category = 'medband', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '114' , Name = 'ZM_WEB_M_REFRESH_STATUS', Value = '5', Type = 'integer', DefaultValue = '5', Hint = 'integer', Pattern = '(?-xism:^(\\d+)$)', Format = ' $1 ', Prompt = 'How often (in seconds) the status frame refreshes itself in the watch window', Help = 'The monitor window is actually made from several frames. The one in the middle merely contains a monitor status which needs to refresh fairly frequently to give a true indication. This option determines that frequency.', Category = 'medband', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '115' , Name = 'ZM_WEB_M_REFRESH_EVENTS', Value = '60', Type = 'integer', DefaultValue = '60', Hint = 'integer', Pattern = '(?-xism:^(\\d+)$)', Format = ' $1 ', Prompt = 'How often (in seconds) the event listing is refreshed in the watch window', Help = 'The monitor window is actually made from several frames. The lower framme contains a listing of the last few events for easy access. This option determines how often this is refreshed.', Category = 'medband', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '116' , Name = 'ZM_WEB_M_DEFAULT_SCALE', Value = '100', Type = 'integer', DefaultValue = '100', Hint = 'integer', Pattern = '(?-xism:^(\\d+)$)', Format = ' $1 ', Prompt = 'What the default scaling factor applied to\'liv\' or\'even\' views is (%)', Help = 'Normally ZoneMinder will display\'liv\' or\'even\' streams in their native size. However if you have monitors with large dimensions or a slow link you may prefer to reduce this size, alternatively for small monitors you can enlarge it. This options lets you specify what the default scaling factor will be. It is expressed as a percentage so 100 is normal size, 200 is double size etc.', Category = 'medband', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '117' , Name = 'ZM_WEB_M_DEFAULT_RATE', Value = '100', Type = 'integer', DefaultValue = '100', Hint = 'integer', Pattern = '(?-xism:^(\\d+)$)', Format = ' $1 ', Prompt = 'What the default replay rate factor applied to\'even\' views is (%)', Help = 'Normally ZoneMinder will display\'even\' streams at their native rate, i.e. as close to real-time as possible. However if you have long events it is often convenient to replay them at a faster rate for review. This option lets you specify what the default replay rate will be. It is expressed as a percentage so 100 is normal rate, 200 is double speed etc.', Category = 'medband', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '118' , Name = 'ZM_WEB_M_VIDEO_BITRATE', Value = '75000', Type = 'integer', DefaultValue = '75000', Hint = 'integer', Pattern = '(?-xism:^(\\d+)$)', Format = ' $1 ', Prompt = 'What the bitrate of the video encoded stream should be set to', Help = 'When encoding real video via the ffmpeg library a bit rate can be specified which roughly corresponds to the available bandwidth used for the stream. This setting effectively corresponds to a\'qualit\' setting for the video. A low value will result in a blocky image whereas a high value will produce a clearer view. Note that this setting does not control the frame rate of the video however the quality of the video produced is affected both by this setting and the frame rate that the video is produced at. A higher frame rate at a particular bit rate result in individual frames being at a lower quality.', Category = 'medband', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '119' , Name = 'ZM_WEB_M_VIDEO_MAXFPS', Value = '10', Type = 'integer', DefaultValue = '10', Hint = 'integer', Pattern = '(?-xism:^(\\d+)$)', Format = ' $1 ', Prompt = 'What the maximum frame rate for streamed video should be', Help = 'When using streamed video the main control is the bitrate which determines how much data can be transmitted. However a lower bitrate at high frame rates results in a lower quality image. This option allows you to limit the maximum frame rate to ensure that video quality is maintained. An additional advantage is that encoding video at high frame rates is a processor intensive task when for the most part a very high frame rate offers little perceptible improvement over one that has a more manageable resource requirement. Note, this option is implemented as a cap beyond which binary reduction takes place. So if you have a device capturing at 15fps and set this option to 10fps then the video is not produced at 10fps, but rather at 7.5fps (15 divided by 2) as the final frame rate must be the original divided by a power of 2.', Category = 'medband', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '120' , Name = 'ZM_WEB_M_IMAGE_SCALING', Value = '4', Type = 'integer', DefaultValue = '4', Hint = 'integer', Pattern = '(?-xism:^(\\d+)$)', Format = ' $1 ', Prompt = 'How to scale thumbnails in events, bandwidth versus cpu in rescaling', Help = 'A value of 1 sends the whole image to the browser which resizes it in the window, larger values scale down by that amount on the server before sending a reduced size image to the browser. For medium bandwidth settings the default of 4 is usually the fastest though 1 may also work.', Category = 'medband', Readonly =  '?1:0', Requires = 'ZM_PATH_NETPBM=/' ; 
+replace into Config set Id = '121' , Name = 'ZM_WEB_L_REFRESH_MAIN', Value = '300', Type = 'integer', DefaultValue = '300', Hint = 'integer', Pattern = '(?-xism:^(\\d+)$)', Format = ' $1 ', Prompt = 'How often (in seconds) the main console window should refresh itself', Help = 'The main console window lists a general status and the event totals for all monitors. This is not a trivial task and should not be repeated too frequently or it may affect the performance of the rest of the system.', Category = 'lowband', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '122' , Name = 'ZM_WEB_L_REFRESH_CYCLE', Value = '30', Type = 'integer', DefaultValue = '30', Hint = 'integer', Pattern = '(?-xism:^(\\d+)$)', Format = ' $1 ', Prompt = 'How often (in seconds) the cycle watch window swaps to the next monitor', Help = 'The cycle watch window is a method of continuously cycling between images from all of your monitors. This option determines how often to refresh with a new image.', Category = 'lowband', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '123' , Name = 'ZM_WEB_L_REFRESH_IMAGE', Value = '15', Type = 'integer', DefaultValue = '15', Hint = 'integer', Pattern = '(?-xism:^(\\d+)$)', Format = ' $1 ', Prompt = 'How often (in seconds) the watched image is refreshed (if not streaming)', Help = 'The live images from a monitor can be viewed in either streamed or stills mode. This option determines how often a stills image is refreshed, it has no effect if streaming is selected.', Category = 'lowband', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '124' , Name = 'ZM_WEB_L_REFRESH_STATUS', Value = '10', Type = 'integer', DefaultValue = '10', Hint = 'integer', Pattern = '(?-xism:^(\\d+)$)', Format = ' $1 ', Prompt = 'How often (in seconds) the status frame refreshes itself in the watch window', Help = 'The monitor window is actually made from several frames. The one in the middle merely contains a monitor status which needs to refresh fairly frequently to give a true indication. This option determines that frequency.', Category = 'lowband', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '125' , Name = 'ZM_WEB_L_REFRESH_EVENTS', Value = '180', Type = 'integer', DefaultValue = '180', Hint = 'integer', Pattern = '(?-xism:^(\\d+)$)', Format = ' $1 ', Prompt = 'How often (in seconds) the event listing is refreshed in the watch window', Help = 'The monitor window is actually made from several frames. The lower framme contains a listing of the last few events for easy access. This option determines how often this is refreshed.', Category = 'lowband', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '126' , Name = 'ZM_WEB_L_DEFAULT_SCALE', Value = '100', Type = 'integer', DefaultValue = '100', Hint = 'integer', Pattern = '(?-xism:^(\\d+)$)', Format = ' $1 ', Prompt = 'What the default scaling factor applied to\'liv\' or\'even\' views is (%)', Help = 'Normally ZoneMinder will display\'liv\' or\'even\' streams in their native size. However if you have monitors with large dimensions or a slow link you may prefer to reduce this size, alternatively for small monitors you can enlarge it. This options lets you specify what the default scaling factor will be. It is expressed as a percentage so 100 is normal size, 200 is double size etc.', Category = 'lowband', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '127' , Name = 'ZM_WEB_L_DEFAULT_RATE', Value = '100', Type = 'integer', DefaultValue = '100', Hint = 'integer', Pattern = '(?-xism:^(\\d+)$)', Format = ' $1 ', Prompt = 'What the default replay rate factor applied to\'even\' views is (%)', Help = 'Normally ZoneMinder will display\'even\' streams at their native rate, i.e. as close to real-time as possible. However if you have long events it is often convenient to replay them at a faster rate for review. This option lets you specify what the default replay rate will be. It is expressed as a percentage so 100 is normal rate, 200 is double speed etc.', Category = 'lowband', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '128' , Name = 'ZM_WEB_L_VIDEO_BITRATE', Value = '25000', Type = 'integer', DefaultValue = '25000', Hint = 'integer', Pattern = '(?-xism:^(\\d+)$)', Format = ' $1 ', Prompt = 'What the bitrate of the video encoded stream should be set to', Help = 'When encoding real video via the ffmpeg library a bit rate can be specified which roughly corresponds to the available bandwidth used for the stream. This setting effectively corresponds to a\'qualit\' setting for the video. A low value will result in a blocky image whereas a high value will produce a clearer view. Note that this setting does not control the frame rate of the video however the quality of the video produced is affected both by this setting and the frame rate that the video is produced at. A higher frame rate at a particular bit rate result in individual frames being at a lower quality.', Category = 'lowband', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '129' , Name = 'ZM_WEB_L_VIDEO_MAXFPS', Value = '5', Type = 'integer', DefaultValue = '5', Hint = 'integer', Pattern = '(?-xism:^(\\d+)$)', Format = ' $1 ', Prompt = 'What the maximum frame rate for streamed video should be', Help = 'When using streamed video the main control is the bitrate which determines how much data can be transmitted. However a lower bitrate at high frame rates results in a lower quality image. This option allows you to limit the maximum frame rate to ensure that video quality is maintained. An additional advantage is that encoding video at high frame rates is a processor intensive task when for the most part a very high frame rate offers little perceptible improvement over one that has a more manageable resource requirement. Note, this option is implemented as a cap beyond which binary reduction takes place. So if you have a device capturing at 15fps and set this option to 10fps then the video is not produced at 10fps, but rather at 7.5fps (15 divided by 2) as the final frame rate must be the original divided by a power of 2.', Category = 'lowband', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '130' , Name = 'ZM_WEB_L_IMAGE_SCALING', Value = '4', Type = 'integer', DefaultValue = '4', Hint = 'integer', Pattern = '(?-xism:^(\\d+)$)', Format = ' $1 ', Prompt = 'How to scale thumbnails in events, bandwidth versus cpu in rescaling', Help = 'A value of 1 sends the whole image to the browser which resizes it in the window, larger values scale down by that amount on the server before sending a reduced size image to the browser. For low bandwidth settings the default of 4 is usually the best.', Category = 'lowband', Readonly =  '?1:0', Requires = 'ZM_PATH_NETPBM=/' ; 
+replace into Config set Id = '131' , Name = 'ZM_WEB_P_REFRESH_MAIN', Value = '300', Type = 'integer', DefaultValue = '300', Hint = 'integer', Pattern = '(?-xism:^(\\d+)$)', Format = ' $1 ', Prompt = 'How often (in seconds) the main console window should refresh itself', Help = 'The main console window lists a general status and the event totals for all monitors. This is not a trivial task and should not be repeated too frequently or it may affect the performance of the rest of the system.', Category = 'phoneband', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '132' , Name = 'ZM_WEB_P_REFRESH_IMAGE', Value = '30', Type = 'integer', DefaultValue = '30', Hint = 'integer', Pattern = '(?-xism:^(\\d+)$)', Format = ' $1 ', Prompt = 'How often (in seconds) the watched image is refreshed', Help = 'The live images from a monitor are viewed as a sequence of still images. This option determines how the image is refreshed. Though the images are small setting this at too frequent a value may rapidly consume a lot of bandwidth resource.', Category = 'phoneband', Readonly =  '?1:0', Requires = '' ; 
+replace into Config set Id = '133' , Name = 'ZM_DYN_LAST_VERSION', Value = '', Type = 'string', DefaultValue = '', Hint = 'string', Pattern = '(?-xism:^(.+)$)', Format = ' $1 ', Prompt = 'What the last version of ZoneMinder recorded from zoneminder.com is', Help = '', Category = 'dynamic', Readonly =  '1?1:0', Requires = '' ; 
+replace into Config set Id = '134' , Name = 'ZM_DYN_CURR_VERSION', Value = '1.21.3', Type = 'string', DefaultValue = '1.21.3', Hint = 'string', Pattern = '(?-xism:^(.+)$)', Format = ' $1 ', Prompt = 'What the effective current version of ZoneMinder is, might be different from actual if versions ignored', Help = '', Category = 'dynamic', Readonly =  '1?1:0', Requires = '' ; 
+replace into Config set Id = '135' , Name = 'ZM_DYN_DB_VERSION', Value = '', Type = 'string', DefaultValue = '', Hint = 'string', Pattern = '(?-xism:^(.+)$)', Format = ' $1 ', Prompt = 'What the version of the database is, from zmupdate', Help = '', Category = 'dynamic', Readonly =  '1?1:0', Requires = '' ; 
+replace into Config set Id = '136' , Name = 'ZM_DYN_LAST_CHECK', Value = '', Type = 'integer', DefaultValue = '', Hint = 'integer', Pattern = '(?-xism:^(\\d+)$)', Format = ' $1 ', Prompt = 'When the last check for version from zoneminder.com was', Help = '', Category = 'dynamic', Readonly =  '1?1:0', Requires = '' ; 
+replace into Config set Id = '137' , Name = 'ZM_DYN_NEXT_REMINDER', Value = '', Type = 'string', DefaultValue = '', Hint = 'string', Pattern = '(?-xism:^(.+)$)', Format = ' $1 ', Prompt = 'When the earliest time to remind about versions will be', Help = '', Category = 'dynamic', Readonly =  '1?1:0', Requires = '' ; 
+
--- zm-1.21.3.orig/zmconfig.txt
+++ zm-1.21.3/zmconfig.txt
@@ -0,0 +1,548 @@
+Name: ZM_DB_SERVER
+Value: localhost
+Description: Machine on which the database server is running
+
+Name: ZM_DB_NAME
+Value: zm
+Description: Database containing the tables
+
+Name: ZM_DB_USER
+Value: zm
+Description: DB user name, needs at least select, insert, update and delete privileges
+
+Name: ZM_DB_PASS
+Value: zmpass
+Description: DB user password
+
+Name: ZM_LANG_DEFAULT
+Value: en_US
+Description: Default language used by web interface
+
+Name: ZM_OPT_USE_AUTH
+Value: yes
+Description: Authenticate user logins to ZoneMinder
+
+Name: ZM_AUTH_METHOD
+Value: hashed
+Description: Method used to send authentication information
+
+Name: ZM_AUTH_SECRET
+Value: blah
+Description: Secret used when encoding authentication information
+
+Name: ZM_DIR_EVENTS
+Value: events
+Description: Directory where events are stored
+
+Name: ZM_DIR_IMAGES
+Value: images
+Description: Directory where the images that the ZoneMinder client generates are stored
+
+Name: ZM_DIR_SOUNDS
+Value: sounds
+Description: Directory to the sounds that the ZoneMinder client can use
+
+Name: ZM_PATH_ZMS
+Value: /cgi-bin/zms
+Description: Web path to zms streaming server
+
+Name: ZM_CAN_STREAM
+Value: auto
+Description: Override the automatic detection of browser streaming capability
+
+Name: ZM_RAND_STREAM
+Value: no
+Description: Add a random string to prevent caching of streams
+
+Name: ZM_OPT_CAMBOZOLA
+Value: no
+Description: Is the (optional) cambozola java streaming client installed (recommended)
+
+Name: ZM_PATH_CAMBOZOLA
+Value: cambozola.jar
+Description: Web path to (optional) cambozola java streaming client (recommended)
+
+Name: ZM_TIMESTAMP_ON_CAPTURE
+Value: yes
+Description: Timestamp images as soon as they are captured
+
+Name: ZM_LOCAL_BGR_INVERT
+Value: yes
+Description: Invert BGR colours to RGB
+
+Name: ZM_Y_IMAGE_DELTAS
+Value: yes
+Description: Whether we calculate images differences using Y channel
+
+Name: ZM_FAST_IMAGE_BLENDS
+Value: yes
+Description: Whether we use a fast algorithm to blend the reference image
+
+Name: ZM_COLOUR_JPEG_FILES
+Value: yes
+Description: Colourise greyscale JPEG files
+
+Name: ZM_JPEG_FILE_QUALITY
+Value: 100
+Description: Set the JPEG quality setting for the saved event files (1-100)
+
+Name: ZM_JPEG_IMAGE_QUALITY
+Value: 100
+Description: Set the JPEG quality setting for the streamed 'live' images (1-100)
+
+Name: ZM_BLEND_ALARMED_IMAGES
+Value: yes
+Description: Whether alarmed images are blended to update the reference image
+
+Name: ZM_NO_MAX_FPS_ON_ALARM
+Value: yes
+Description: Should any Maximum FPS be ignored if an alarm occurs
+
+Name: ZM_OPT_ADAPTIVE_SKIP
+Value: yes
+Description: Should frame analysis try and be efficient in skipping frames
+
+Name: ZM_OPT_REMOTE_CAMERAS
+Value: yes
+Description: Are you going to use remote/networked cameras
+
+Name: ZM_NETCAM_REGEXPS
+Value: no
+Description: Whether to use regular expression matching with network cameras
+
+Name: ZM_HTTP_VERSION
+Value: 1.1
+Description: The version of HTTP that ZoneMinder will use to connect
+
+Name: ZM_HTTP_UA
+Value: ZoneMinder
+Description: The user agent that ZoneMinder uses to identify itself
+
+Name: ZM_HTTP_TIMEOUT
+Value: 2500
+Description: How long ZoneMinder waits before giving up on images (milliseconds)
+
+Name: ZM_OPT_MPEG
+Value: ffmpeg
+Description: Is there an (optional) mpeg video encoder installed
+
+Name: ZM_PATH_MPEG_ENCODE
+Value: /usr/bin/mpeg_encode
+Description: Path to (optional) Berkeley mpeg encoder
+
+Name: ZM_PATH_FFMPEG
+Value: /usr/bin/ffmpeg
+Description: Path to (optional) ffmpeg mpeg encoder
+
+Name: ZM_FFMPEG_OPTIONS
+Value: -hq -intra
+Description: Additional options to ffmpeg
+
+Name: ZM_OPT_NETPBM
+Value: yes
+Description: Are the (optional) Netpbm utilities installed
+
+Name: ZM_PATH_NETPBM
+Value: /usr/bin
+Description: Path to (optional) Netpbm utilities
+
+Name: ZM_OPT_TRIGGERS
+Value: no
+Description: Whether we want to interface external event triggers via socket or device files
+
+Name: ZM_PATH_SOCKS
+Value: /var/lib/zm
+Description: Path to the various Unix domain socket files that ZoneMinder uses
+
+Name: ZM_PATH_LOGS
+Value: /var/log/zm
+Description: Path to the various logs that the ZoneMinder daemons generate
+
+Name: ZM_VIDEO_STREAM_METHOD
+Value: mpeg
+Description: Which method should be used to send video streams to your browser, choose 'mpeg' or 'jpeg'
+
+Name: ZM_VIDEO_TIMED_FRAMES
+Value: yes
+Description: Whether video frames are sent tagged with a timestamp for more realistic streaming
+
+Name: ZM_VIDEO_LIVE_FORMAT
+Value: asf
+Description: What format 'live' video streams are played in
+
+Name: ZM_VIDEO_REPLAY_FORMAT
+Value: asf
+Description: What format 'replay' video streams are played in
+
+Name: ZM_WEB_TITLE_PREFIX
+Value: ZM
+Description: The title prefix displayed on each window
+
+Name: ZM_WEB_RESIZE_CONSOLE
+Value: yes
+Description: Should the console window resize itself to fit
+
+Name: ZM_WEB_POPUP_ON_ALARM
+Value: yes
+Description: Should the monitor window jump to the top if an alarm occurs
+
+Name: ZM_OPT_X10
+Value: no
+Description: Whether we want to interface with X10 devices
+
+Name: ZM_X10_DEVICE
+Value: /dev/ttyS0
+Description: What device is your X10 controller connected on
+
+Name: ZM_X10_HOUSE_CODE
+Value: A
+Description: What X10 house code should be used
+
+Name: ZM_X10_DB_RELOAD_INTERVAL
+Value: 60
+Description: How often (in seconds) the X10 daemon reloads the monitors from the database
+
+Name: ZM_WEB_SOUND_ON_ALARM
+Value: no
+Description: Should the monitor window play a sound if an alarm occurs
+
+Name: ZM_WEB_ALARM_SOUND
+Value: 
+Description: The sound to play on alarm, put this in the sounds directory
+
+Name: ZM_WEB_COMPACT_MONTAGE
+Value: no
+Description: Whether to compact the montage view by removing extra detail
+
+Name: ZM_WEB_MONTAGE_MAX_COLS
+Value: 2
+Description: The maximum number of monitor columns in the montage view
+
+Name: ZM_WEB_MONTAGE_WIDTH
+Value: 0
+Description: What width should each monitor in the montage view be
+
+Name: ZM_WEB_MONTAGE_HEIGHT
+Value: 0
+Description: What height should each monitor in the montage view be
+
+Name: ZM_OPT_FAST_DELETE
+Value: yes
+Description: When deleting events should the client only delete the database records for speed
+
+Name: ZM_STRICT_VIDEO_CONFIG
+Value: yes
+Description: Whether to allow errors in setting video config to be fatal
+
+Name: ZM_CAPTURES_PER_FRAME
+Value: 1
+Description: How many images are captured per returned frame, for shared local cameras
+
+Name: ZM_SHM_KEY
+Value: 0x7a6d2000
+Description: Shared memory key to use, only change if it clashes with another application
+
+Name: ZM_FILTER_RELOAD_DELAY
+Value: 300
+Description: How often (in seconds) filters are reloaded in zmfilter.pl
+
+Name: ZM_OPT_UPLOAD
+Value: no
+Description: Should ZoneMinder try and upload events that match corresponding filters
+
+Name: ZM_UPLOAD_ARCH_FORMAT
+Value: tar
+Description: What format the uploaded events should be created in. This can be 'tar' or 'zip'
+
+Name: ZM_UPLOAD_ARCH_COMPRESS
+Value: no
+Description: Should archive files be compressed
+
+Name: ZM_UPLOAD_ARCH_ANALYSE
+Value: no
+Description: Whether to include the analysis files in the archive, bigger but slower
+
+Name: ZM_UPLOAD_FTP_HOST
+Value: 
+Description: The remote server to upload to
+
+Name: ZM_UPLOAD_FTP_USER
+Value: 
+Description: Your ftp username
+
+Name: ZM_UPLOAD_FTP_PASS
+Value: 
+Description: Your ftp password
+
+Name: ZM_UPLOAD_FTP_LOC_DIR
+Value: /tmp
+Description: The local directory in which to create upload files
+
+Name: ZM_UPLOAD_FTP_REM_DIR
+Value: 
+Description: The remote directory to upload to
+
+Name: ZM_UPLOAD_FTP_TIMEOUT
+Value: 120
+Description: How long (in seconds) we allow the transfer to take for each file
+
+Name: ZM_UPLOAD_FTP_PASSIVE
+Value: yes
+Description: Whether to use passive ftp
+
+Name: ZM_UPLOAD_FTP_DEBUG
+Value: yes
+Description: Whether to switch ftp debugging on
+
+Name: ZM_OPT_EMAIL
+Value: no
+Description: Should ZoneMinder email you details of events that match corresponding filters
+
+Name: ZM_EMAIL_ADDRESS
+Value: 
+Description: The email address to send matching event details to
+
+Name: ZM_EMAIL_FORMAT
+Value: zmconfig_eml.txt
+Description: The format of the email used to send matching event details
+
+Name: ZM_OPT_MESSAGE
+Value: no
+Description: Should ZoneMinder message you with details of events that match corresponding filters
+
+Name: ZM_MESSAGE_ADDRESS
+Value: 
+Description: The email address to send matching event details to
+
+Name: ZM_MESSAGE_FORMAT
+Value: zmconfig_msg.txt
+Description: The format of the message used to send matching event details
+
+Name: ZM_NEW_MAIL_MODULES
+Value: no
+Description: Whether to use a newer perl method to send emails
+
+Name: ZM_EMAIL_HOST
+Value: localhost
+Description: The host address of your SMTP mail server
+
+Name: ZM_FROM_EMAIL
+Value: 
+Description: The email address you wish your event notifications to originate from
+
+Name: ZM_URL
+Value: 
+Description: The URL of your ZoneMinder installation
+
+Name: ZM_MAX_RESTART_DELAY
+Value: 600
+Description: The maximum delay (in seconds) for daemon restart attempts.
+
+Name: ZM_WATCH_CHECK_INTERVAL
+Value: 10
+Description: How often to check the capture daemons have not locked up
+
+Name: ZM_WATCH_MAX_DELAY
+Value: 5
+Description: The maximum delay since the last captured image we will allow before restarting the capture daemons
+
+Name: ZM_FORCED_ALARM_SCORE
+Value: 255
+Description: Score to give forced alarms
+
+Name: ZM_BULK_FRAME_INTERVAL
+Value: 100
+Description: How often a bulk frame should be written to the database
+
+Name: ZM_EVENT_IMAGE_DIGITS
+Value: 3
+Description: How many significant digits are used in event image numbering
+
+Name: ZM_RECORD_EVENT_STATS
+Value: yes
+Description: Whether to record event statistical information, switch off if too slow
+
+Name: ZM_RECORD_DIAG_IMAGES
+Value: no
+Description: Whether to record intermediate alarm diagnostic images, can be very slow
+
+Name: ZM_CREATE_ANALYSIS_IMAGES
+Value: yes
+Description: Whether to create analysed alarm images with motion outlined
+
+Name: ZM_OPT_FRAME_SERVER
+Value: yes
+Description: Should analysis farm out the writing of images to disk
+
+Name: ZM_FRAME_SOCKET_SIZE
+Value: 0
+Description: Specify the size of the frame server socket buffer if non-standard
+
+Name: ZM_OPT_CONTROL
+Value: no
+Description: Whether to support controllable (e.g. pan/tilt/zoom) cameras
+
+Name: ZM_CHECK_FOR_UPDATES
+Value: no
+Description: Whether to check with zoneminder.com for updated versions
+
+Name: ZM_WEB_REFRESH_METHOD
+Value: javascript
+Description: What method windows should use to refresh themselves, choose either javascript or http
+
+Name: ZM_WEB_DOUBLE_BUFFER
+Value: yes
+Description: Whether still images should be double buffered to avoid flickering
+
+Name: ZM_WEB_EVENTS_PER_PAGE
+Value: 25
+Description: How many events to list per page in paged mode
+
+Name: ZM_WEB_FRAMES_PER_LINE
+Value: 4
+Description: How many frames to list per line in the frame view
+
+Name: ZM_WEB_FRAME_LINES
+Value: 4
+Description: How many lines of frames to list in the frame view
+
+Name: ZM_WEB_LIST_THUMBS
+Value: yes
+Description: Whether to display mini-thumbnails of event images in event lists
+
+Name: ZM_WEB_LIST_THUMB_WIDTH
+Value: 48
+Description: The width of the thumbnails that appear in the event lists
+
+Name: ZM_WEB_LIST_THUMB_HEIGHT
+Value: 0
+Description: The height of the thumbnails that appear in the event lists
+
+Name: ZM_WEB_H_REFRESH_MAIN
+Value: 300
+Description: How often (in seconds) the main console window should refresh itself
+
+Name: ZM_WEB_H_REFRESH_CYCLE
+Value: 10
+Description: How often (in seconds) the cycle watch window swaps to the next monitor
+
+Name: ZM_WEB_H_REFRESH_IMAGE
+Value: 5
+Description: How often (in seconds) the watched image is refreshed (if not streaming)
+
+Name: ZM_WEB_H_REFRESH_STATUS
+Value: 3
+Description: How often (in seconds) the status frame refreshes itself in the watch window
+
+Name: ZM_WEB_H_REFRESH_EVENTS
+Value: 30
+Description: How often (in seconds) the event listing is refreshed in the watch window
+
+Name: ZM_WEB_H_DEFAULT_SCALE
+Value: 100
+Description: What the default scaling factor applied to 'live' or 'event' views is (%)
+
+Name: ZM_WEB_H_DEFAULT_RATE
+Value: 100
+Description: What the default replay rate factor applied to 'event' views is (%)
+
+Name: ZM_WEB_H_VIDEO_BITRATE
+Value: 150000
+Description: What the bitrate of the video encoded stream should be set to
+
+Name: ZM_WEB_H_VIDEO_MAXFPS
+Value: 15
+Description: What the maximum frame rate for streamed video should be
+
+Name: ZM_WEB_H_IMAGE_SCALING
+Value: 1
+Description: How to scale thumbnails in events, bandwidth versus cpu in rescaling
+
+Name: ZM_WEB_M_REFRESH_MAIN
+Value: 300
+Description: How often (in seconds) the main console window should refresh itself
+
+Name: ZM_WEB_M_REFRESH_CYCLE
+Value: 20
+Description: How often (in seconds) the cycle watch window swaps to the next monitor
+
+Name: ZM_WEB_M_REFRESH_IMAGE
+Value: 10
+Description: How often (in seconds) the watched image is refreshed (if not streaming)
+
+Name: ZM_WEB_M_REFRESH_STATUS
+Value: 5
+Description: How often (in seconds) the status frame refreshes itself in the watch window
+
+Name: ZM_WEB_M_REFRESH_EVENTS
+Value: 60
+Description: How often (in seconds) the event listing is refreshed in the watch window
+
+Name: ZM_WEB_M_DEFAULT_SCALE
+Value: 100
+Description: What the default scaling factor applied to 'live' or 'event' views is (%)
+
+Name: ZM_WEB_M_DEFAULT_RATE
+Value: 100
+Description: What the default replay rate factor applied to 'event' views is (%)
+
+Name: ZM_WEB_M_VIDEO_BITRATE
+Value: 75000
+Description: What the bitrate of the video encoded stream should be set to
+
+Name: ZM_WEB_M_VIDEO_MAXFPS
+Value: 10
+Description: What the maximum frame rate for streamed video should be
+
+Name: ZM_WEB_M_IMAGE_SCALING
+Value: 4
+Description: How to scale thumbnails in events, bandwidth versus cpu in rescaling
+
+Name: ZM_WEB_L_REFRESH_MAIN
+Value: 300
+Description: How often (in seconds) the main console window should refresh itself
+
+Name: ZM_WEB_L_REFRESH_CYCLE
+Value: 30
+Description: How often (in seconds) the cycle watch window swaps to the next monitor
+
+Name: ZM_WEB_L_REFRESH_IMAGE
+Value: 15
+Description: How often (in seconds) the watched image is refreshed (if not streaming)
+
+Name: ZM_WEB_L_REFRESH_STATUS
+Value: 10
+Description: How often (in seconds) the status frame refreshes itself in the watch window
+
+Name: ZM_WEB_L_REFRESH_EVENTS
+Value: 180
+Description: How often (in seconds) the event listing is refreshed in the watch window
+
+Name: ZM_WEB_L_DEFAULT_SCALE
+Value: 100
+Description: What the default scaling factor applied to 'live' or 'event' views is (%)
+
+Name: ZM_WEB_L_DEFAULT_RATE
+Value: 100
+Description: What the default replay rate factor applied to 'event' views is (%)
+
+Name: ZM_WEB_L_VIDEO_BITRATE
+Value: 25000
+Description: What the bitrate of the video encoded stream should be set to
+
+Name: ZM_WEB_L_VIDEO_MAXFPS
+Value: 5
+Description: What the maximum frame rate for streamed video should be
+
+Name: ZM_WEB_L_IMAGE_SCALING
+Value: 4
+Description: How to scale thumbnails in events, bandwidth versus cpu in rescaling
+
+Name: ZM_WEB_P_REFRESH_MAIN
+Value: 300
+Description: How often (in seconds) the main console window should refresh itself
+
+Name: ZM_WEB_P_REFRESH_IMAGE
+Value: 30
+Description: How often (in seconds) the watched image is refreshed
+
--- zm-1.21.3.orig/configure
+++ zm-1.21.3/configure
@@ -974,7 +974,7 @@
     else
       echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
     fi
-    cd $ac_popdir
+    cd "$ac_popdir"
   done
 fi
 
@@ -1761,7 +1761,8 @@
           ac_config_headers="$ac_config_headers config.h"
 
 
-PATH_BUILD=`pwd`
+#PATH_BUILD=`pwd`
+PATH_BUILD=/usr/share/doc/zm
 
 
 
@@ -2487,8 +2488,7 @@
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2546,8 +2546,7 @@
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2663,8 +2662,7 @@
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2718,8 +2716,7 @@
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2764,8 +2761,7 @@
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2809,8 +2805,7 @@
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3168,8 +3163,7 @@
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_cxx_werror_flag"
-			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_cxx_werror_flag"			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3227,8 +3221,7 @@
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_cxx_werror_flag"
-			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_cxx_werror_flag"			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3299,8 +3292,7 @@
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_cxx_werror_flag"
-			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_cxx_werror_flag"			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3344,8 +3336,7 @@
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_cxx_werror_flag"
-			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_cxx_werror_flag"			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3880,8 +3871,7 @@
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -4062,8 +4052,7 @@
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_cxx_werror_flag"
-			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_cxx_werror_flag"			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -4361,8 +4350,7 @@
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_cxx_werror_flag"
-			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_cxx_werror_flag"			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -4511,8 +4499,7 @@
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_cxx_werror_flag"
-			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_cxx_werror_flag"			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -4660,8 +4647,7 @@
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_cxx_werror_flag"
-			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_cxx_werror_flag"			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -4733,8 +4719,7 @@
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_cxx_werror_flag"
-			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_cxx_werror_flag"			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -4806,8 +4791,7 @@
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_cxx_werror_flag"
-			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_cxx_werror_flag"			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -4885,8 +4869,7 @@
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_cxx_werror_flag"
-			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_cxx_werror_flag"			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -4963,8 +4946,7 @@
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_cxx_werror_flag"
-			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_cxx_werror_flag"			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -5041,8 +5023,7 @@
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_cxx_werror_flag"
-			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_cxx_werror_flag"			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -5119,8 +5100,7 @@
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_cxx_werror_flag"
-			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_cxx_werror_flag"			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -5197,8 +5177,7 @@
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_cxx_werror_flag"
-			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_cxx_werror_flag"			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -5274,8 +5253,7 @@
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_cxx_werror_flag"
-			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_cxx_werror_flag"			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -5351,8 +5329,7 @@
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_cxx_werror_flag"
-			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_cxx_werror_flag"			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -5428,8 +5405,7 @@
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_cxx_werror_flag"
-			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_cxx_werror_flag"			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -5505,8 +5481,7 @@
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_cxx_werror_flag"
-			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_cxx_werror_flag"			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -6428,11 +6403,6 @@
   *) ac_INSTALL=$ac_top_builddir$INSTALL ;;
   esac
 
-  if test x"$ac_file" != x-; then
-    { echo "$as_me:$LINENO: creating $ac_file" >&5
-echo "$as_me: creating $ac_file" >&6;}
-    rm -f "$ac_file"
-  fi
   # Let's still pretend it is `configure' which instantiates (i.e., don't
   # use $as_me), people would be surprised to read:
   #    /* config.h.  Generated by config.status.  */
@@ -6471,6 +6441,12 @@
 	 fi;;
       esac
     done` || { (exit 1); exit 1; }
+
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF
   sed "$ac_vpsub
