Merge branch 'storageareas' of github.com:ZoneMinder/ZoneMinder into storageareas
This commit is contained in:
commit
add4992dea
|
@ -67,3 +67,92 @@ src/zmu
|
|||
web/includes/config.php
|
||||
zm.conf
|
||||
zmconfgen.pl
|
||||
scripts/ZoneMinder/cmake_install.cmake
|
||||
scripts/ZoneMinder/output/
|
||||
scripts/cmake_install.cmake
|
||||
scripts/zmtelemetry.pl
|
||||
scripts/zoneminder-zmaudit.pl.8
|
||||
scripts/zoneminder-zmaudit.pl.8.gz
|
||||
scripts/zoneminder-zmcamtool.pl.8
|
||||
scripts/zoneminder-zmcamtool.pl.8.gz
|
||||
scripts/zoneminder-zmcontrol.pl.8
|
||||
scripts/zoneminder-zmcontrol.pl.8.gz
|
||||
scripts/zoneminder-zmdc.pl.8
|
||||
scripts/zoneminder-zmdc.pl.8.gz
|
||||
scripts/zoneminder-zmfilter.pl.8
|
||||
scripts/zoneminder-zmfilter.pl.8.gz
|
||||
scripts/zoneminder-zmpkg.pl.8
|
||||
scripts/zoneminder-zmpkg.pl.8.gz
|
||||
scripts/zoneminder-zmsystemctl.pl.8
|
||||
scripts/zoneminder-zmsystemctl.pl.8.gz
|
||||
scripts/zoneminder-zmtelemetry.pl.8
|
||||
scripts/zoneminder-zmtelemetry.pl.8.gz
|
||||
scripts/zoneminder-zmtrack.pl.8
|
||||
scripts/zoneminder-zmtrack.pl.8.gz
|
||||
scripts/zoneminder-zmtrigger.pl.8
|
||||
scripts/zoneminder-zmtrigger.pl.8.gz
|
||||
scripts/zoneminder-zmupdate.pl.8
|
||||
scripts/zoneminder-zmupdate.pl.8.gz
|
||||
scripts/zoneminder-zmvideo.pl.8
|
||||
scripts/zoneminder-zmvideo.pl.8.gz
|
||||
scripts/zoneminder-zmwatch.pl.8
|
||||
scripts/zoneminder-zmwatch.pl.8.gz
|
||||
scripts/zoneminder-zmx10.pl.8
|
||||
scripts/zoneminder-zmx10.pl.8.gz
|
||||
src/CMakeFiles/
|
||||
src/cmake_install.cmake
|
||||
src/libzm.a
|
||||
src/nph-zms
|
||||
src/zoneminder-zma.8
|
||||
src/zoneminder-zma.8.gz
|
||||
src/zoneminder-zmc.8
|
||||
src/zoneminder-zmc.8.gz
|
||||
src/zoneminder-zmf.8
|
||||
src/zoneminder-zmf.8.gz
|
||||
src/zoneminder-zmstreamer.8
|
||||
src/zoneminder-zmstreamer.8.gz
|
||||
src/zoneminder-zmu.8
|
||||
src/zoneminder-zmu.8.gz
|
||||
web/CMakeFiles/
|
||||
web/api/CMakeFiles/
|
||||
web/api/app/Config/bootstrap.php
|
||||
web/api/app/Config/core.php
|
||||
web/api/cmake_install.cmake
|
||||
web/cgi-bin/
|
||||
web/cmake_install.cmake
|
||||
web/events/
|
||||
web/images/
|
||||
web/tools/mootools/CMakeFiles/
|
||||
web/tools/mootools/cmake_install.cmake
|
||||
web/tools/mootools/mootools-core.js
|
||||
web/tools/mootools/mootools-more.js
|
||||
web/undef.log
|
||||
zmlinkcontent.sh
|
||||
CMakeCache.txt
|
||||
CMakeFiles/
|
||||
cmake/cmake_uninstall.cmake
|
||||
cmake_install.cmake
|
||||
db/CMakeFiles/
|
||||
db/cmake_install.cmake
|
||||
install_manifest.txt
|
||||
misc/CMakeFiles/
|
||||
misc/cmake_install.cmake
|
||||
misc/zoneminder-tmpfiles.conf
|
||||
misc/zoneminder.service
|
||||
onvif/CMakeFiles/
|
||||
onvif/cmake_install.cmake
|
||||
onvif/modules/CMakeFiles/
|
||||
onvif/modules/MakefilePerl
|
||||
onvif/modules/cmake_install.cmake
|
||||
onvif/modules/output/
|
||||
onvif/modules/pm_to_blib
|
||||
onvif/proxy/CMakeFiles/
|
||||
onvif/proxy/MakefilePerl
|
||||
onvif/proxy/cmake_install.cmake
|
||||
onvif/proxy/output/
|
||||
onvif/proxy/pm_to_blib
|
||||
onvif/scripts/CMakeFiles/
|
||||
onvif/scripts/cmake_install.cmake
|
||||
scripts/CMakeFiles/
|
||||
scripts/ZoneMinder/CMakeFiles/
|
||||
scripts/ZoneMinder/MakefilePerl
|
||||
|
|
|
@ -373,7 +373,7 @@ UPDATE States SET IsActive = '1' WHERE Name = 'default';
|
|||
-- If duplicate states existed while upgrading, that is
|
||||
-- very likely an error that ZM allowed earlier, so
|
||||
-- we are picking up the first one and deleting the others
|
||||
ALTER IGNORE TABLE States ADD UNIQUE (Name);
|
||||
ALTER TABLE States ADD UNIQUE (Name);
|
||||
|
||||
SET @s = (SELECT IF(
|
||||
(SELECT COUNT(*)
|
||||
|
|
|
@ -1,9 +1,43 @@
|
|||
zoneminder (1.28.1+1-vivid-SNAPSHOT2015081701) vivid; urgency=medium
|
||||
zoneminder (1.29.0+dfsg-1) unstable; urgency=low
|
||||
|
||||
* include api, switch to cmake build
|
||||
* New upstream release [February 2016] (Closes: #788317, #770851).
|
||||
|
||||
-- Isaac Connor <iconnor@connortechnology.com> Mon, 17 Aug 2015 10:29:23 -0400
|
||||
[ Dmitry Smirnov <onlyjob@debian.org> ]
|
||||
* copyright/Files-Excluded += "onvif/*" due to licensing uncertainty.
|
||||
* Fixed FTBFS when built with dpkg-buildpackage -A (Closes: #806126).
|
||||
* FFmpeg 2.9 support. Thanks, Andreas Cadhalpun. (Closes: #803850).
|
||||
* Use "ffmpeg" instead of "avconv":
|
||||
+ "libav_path.patch" replaced with "default_ffmpeg_path.patch".
|
||||
* zoneminder/Depends:
|
||||
- perl-modules (package-relation-with-perl-modules)
|
||||
- libav-tools
|
||||
* zoneminder/Recommends:
|
||||
+ ffmpeg | libav-tools
|
||||
* Updated Vcs URLs.
|
||||
* Build/install new man pages.
|
||||
* Removed obsolete lintian-overrides.
|
||||
* README: grant "index" right to DB user.
|
||||
* systemd: start after MySQL but do not require the latter.
|
||||
* Added new patch with spelling corrections.
|
||||
* Removed obsolete patches:
|
||||
- 783.patch
|
||||
- 980-fix-image-size.patch
|
||||
- cmake-fix-confpath.patch
|
||||
- cmake.patch
|
||||
- cmake-gnutls.patch
|
||||
- fix-html-export.patch
|
||||
- format-hardening.patch
|
||||
- libv4l1-videodev.h.patch
|
||||
- pod_man_fixes.patch
|
||||
- pod_name_fixes.patch
|
||||
- pod_zmupdate-to-pod2usage.patch
|
||||
- respect-privacy.patch
|
||||
- zmtrigger-plus.patch
|
||||
|
||||
[ Vagrant Cascadian <vagrant@debian.org> ]
|
||||
* Remove myself from Uploaders.
|
||||
|
||||
-- Dmitry Smirnov <onlyjob@debian.org> Tue, 09 Feb 2016 15:40:32 +1100
|
||||
|
||||
zoneminder (1.28.1-8) unstable; urgency=medium
|
||||
|
|
@ -5,8 +5,8 @@ Maintainer: Dmitry Smirnov <onlyjob@debian.org>
|
|||
Uploaders: Vagrant Cascadian <vagrant@debian.org>
|
||||
Build-Depends: debhelper (>= 9), dh-systemd, python-sphinx | python3-sphinx, apache2-dev, dh-linktree
|
||||
,cmake
|
||||
,libavcodec-ffmpeg-dev, libavformat-ffmpeg-dev, libswscale-ffmpeg-dev, libavutil-ffmpeg-dev, libavdevice-ffmpeg-dev
|
||||
,libx264-dev, libmp4v2-dev,
|
||||
,libx264-dev, libmp4v2-dev
|
||||
,libavcodec-dev, libavformat-dev, libswscale-dev, libavutil-dev, libavdevice-dev
|
||||
,libbz2-dev
|
||||
,libgcrypt-dev
|
||||
,libcurl4-gnutls-dev
|
||||
|
@ -61,9 +61,10 @@ Depends: ${shlibs:Depends}, ${misc:Depends}, ${perl:Depends}
|
|||
,rsyslog | system-log-daemon
|
||||
,zip
|
||||
Recommends: ${misc:Recommends}
|
||||
,libapache2-mod-php5 | libapache2-mod-php7 | php5-fpm
|
||||
,libapache2-mod-php5 | libapache2-mod-php | php5-fpm | php-fpm
|
||||
,mysql-server | virtual-mysql-server
|
||||
,zoneminder-doc (>= ${source:Version})
|
||||
,ffmpeg
|
||||
Suggests: fcgiwrap, logrotate
|
||||
Description: video camera security and surveillance solution
|
||||
ZoneMinder is intended for use in single or multi-camera video security
|
|
@ -81,6 +81,11 @@ our @EXPORT = ( @EXPORT_OK );
|
|||
|
||||
our $VERSION = $ZoneMinder::Base::VERSION;
|
||||
|
||||
BEGIN {
|
||||
ZoneMinder::Config::zmConfigLoad();
|
||||
ZoneMinder::Database::zmDbConnect();
|
||||
}
|
||||
|
||||
1;
|
||||
__END__
|
||||
|
||||
|
|
|
@ -30,6 +30,8 @@ use warnings;
|
|||
|
||||
require Exporter;
|
||||
require ZoneMinder::Base;
|
||||
require ZoneMinder::Database;
|
||||
use ZoneMinder::ConfigData qw(:all);
|
||||
|
||||
our @ISA = qw(Exporter ZoneMinder::Base);
|
||||
|
||||
|
@ -44,7 +46,12 @@ use vars qw( %Config );
|
|||
our @EXPORT_CONFIG = qw( %Config ); # Get populated by BEGIN
|
||||
|
||||
our %EXPORT_TAGS = (
|
||||
'constants' => [ qw(
|
||||
functions => [ qw(
|
||||
zmConfigLoad
|
||||
loadConfigFromDB
|
||||
saveConfigToDB
|
||||
) ],
|
||||
constants => [ qw(
|
||||
ZM_PID
|
||||
) ]
|
||||
);
|
||||
|
@ -63,55 +70,166 @@ use constant ZM_CONFIG => "@ZM_CONFIG@"; # Path to the ZoneMinder config file
|
|||
use Carp;
|
||||
|
||||
# Load the config from the database into the symbol table
|
||||
BEGIN
|
||||
{
|
||||
my $config_file = ZM_CONFIG;
|
||||
open( my $CONFIG, "<", $config_file )
|
||||
or croak( "Can't open config file '$config_file': $!" );
|
||||
foreach my $str ( <$CONFIG> )
|
||||
{
|
||||
next if ( $str =~ /^\s*$/ );
|
||||
next if ( $str =~ /^\s*#/ );
|
||||
my ( $name, $value ) = $str =~ /^\s*([^=\s]+)\s*=\s*(.*?)\s*$/;
|
||||
if ( ! $name ) {
|
||||
print( STDERR "Warning, bad line in $config_file: $str\n" );
|
||||
next;
|
||||
} # end if
|
||||
$name =~ tr/a-z/A-Z/;
|
||||
$Config{$name} = $value;
|
||||
}
|
||||
close( $CONFIG );
|
||||
sub zmConfigLoad {
|
||||
%Config = ();
|
||||
|
||||
use DBI;
|
||||
my $dbh = DBI->connect( "DBI:mysql:database=".$Config{ZM_DB_NAME}
|
||||
.";host=".$Config{ZM_DB_HOST}
|
||||
, $Config{ZM_DB_USER}
|
||||
, $Config{ZM_DB_PASS}
|
||||
) or croak( "Can't connect to db" );
|
||||
my $sql = 'select * from Config';
|
||||
my $sth = $dbh->prepare_cached( $sql ) or croak( "Can't prepare '$sql': ".$dbh->errstr() );
|
||||
my $res = $sth->execute() or croak( "Can't execute: ".$sth->errstr() );
|
||||
while( my $config = $sth->fetchrow_hashref() ) {
|
||||
$Config{$config->{Name}} = $config->{Value};
|
||||
my $config_file = ZM_CONFIG;
|
||||
open( my $CONFIG, "<", $config_file )
|
||||
or croak( "Can't open config file '$config_file': $!" );
|
||||
foreach my $str ( <$CONFIG> ) {
|
||||
next if ( $str =~ /^\s*$/ );
|
||||
next if ( $str =~ /^\s*#/ );
|
||||
my ( $name, $value ) = $str =~ /^\s*([^=\s]+)\s*=\s*(.*?)\s*$/;
|
||||
if ( ! $name ) {
|
||||
print( STDERR "Warning, bad line in $config_file: $str\n" );
|
||||
next;
|
||||
} # end if
|
||||
$name =~ tr/a-z/A-Z/;
|
||||
$Config{$name} = $value;
|
||||
}
|
||||
close( $CONFIG );
|
||||
|
||||
my $dbh = ZoneMinder::Database::zmDbConnect() or croak( "Can't connect to db" );
|
||||
my $sql = 'select * from Config';
|
||||
my $sth = $dbh->prepare_cached( $sql ) or croak( "Can't prepare '$sql': ".$dbh->errstr() );
|
||||
my $res = $sth->execute() or croak( "Can't execute: ".$sth->errstr() );
|
||||
while( my $config = $sth->fetchrow_hashref() ) {
|
||||
$Config{$config->{Name}} = $config->{Value};
|
||||
}
|
||||
$sth->finish();
|
||||
|
||||
if ( ! exists $Config{ZM_SERVER_ID} ) {
|
||||
$Config{ZM_SERVER_ID} = undef;
|
||||
$sth = $dbh->prepare_cached( 'SELECT * FROM Servers WHERE Name=?' );
|
||||
if ( $Config{ZM_SERVER_NAME} ) {
|
||||
$res = $sth->execute( $Config{ZM_SERVER_NAME} );
|
||||
my $result = $sth->fetchrow_hashref();
|
||||
$Config{ZM_SERVER_ID} = $$result{Id};
|
||||
} elsif ( $Config{ZM_SERVER_HOST} ) {
|
||||
$res = $sth->execute( $Config{ZM_SERVER_HOST} );
|
||||
my $result = $sth->fetchrow_hashref();
|
||||
$Config{ZM_SERVER_ID} = $$result{Id};
|
||||
}
|
||||
$sth->finish();
|
||||
#$dbh->disconnect();
|
||||
|
||||
if ( ! exists $Config{ZM_SERVER_ID} ) {
|
||||
$Config{ZM_SERVER_ID} = undef;
|
||||
$sth = $dbh->prepare_cached( 'SELECT * FROM Servers WHERE Name=?' );
|
||||
if ( $Config{ZM_SERVER_NAME} ) {
|
||||
$res = $sth->execute( $Config{ZM_SERVER_NAME} );
|
||||
my $result = $sth->fetchrow_hashref();
|
||||
$Config{ZM_SERVER_ID} = $$result{Id};
|
||||
} elsif ( $Config{ZM_SERVER_HOST} ) {
|
||||
$res = $sth->execute( $Config{ZM_SERVER_HOST} );
|
||||
my $result = $sth->fetchrow_hashref();
|
||||
$Config{ZM_SERVER_ID} = $$result{Id};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub loadConfigFromDB {
|
||||
print( "Loading config from DB\n" );
|
||||
my $dbh = ZoneMinder::Database::zmDbConnect();
|
||||
if ( !$dbh ) {
|
||||
print( "Error: unable to load options from database: $DBI::errstr\n" );
|
||||
return( 0 );
|
||||
}
|
||||
my $sql = "select * from Config";
|
||||
my $sth = $dbh->prepare_cached( $sql )
|
||||
or croak( "Can't prepare '$sql': ".$dbh->errstr() );
|
||||
my $res = $sth->execute()
|
||||
or croak( "Can't execute: ".$sth->errstr() );
|
||||
my $option_count = 0;
|
||||
while( my $config = $sth->fetchrow_hashref() ) {
|
||||
my ( $name, $value ) = ( $config->{Name}, $config->{Value} );
|
||||
#print( "Name = '$name'\n" );
|
||||
my $option = $options_hash{$name};
|
||||
if ( !$option ) {
|
||||
warn( "No option '$name' found, removing" );
|
||||
next;
|
||||
}
|
||||
#next if ( $option->{category} eq 'hidden' );
|
||||
if ( defined($value) ) {
|
||||
if ( $option->{type} == $types{boolean} ) {
|
||||
$option->{value} = $value?"yes":"no";
|
||||
} else {
|
||||
$option->{value} = $value;
|
||||
}
|
||||
}
|
||||
$option_count++;;
|
||||
}
|
||||
$sth->finish();
|
||||
return( $option_count );
|
||||
}
|
||||
|
||||
sub saveConfigToDB {
|
||||
print( "Saving config to DB\n" );
|
||||
my $dbh = ZoneMinder::Database::zmDbConnect();
|
||||
if ( !$dbh )
|
||||
{
|
||||
print( "Error: unable to save options to database: $DBI::errstr\n" );
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
my $ac = $dbh->{AutoCommit};
|
||||
$dbh->{AutoCommit} = 0;
|
||||
|
||||
$dbh->do('LOCK TABLE Config WRITE')
|
||||
or croak( "Can't lock Config table: " . $dbh->errstr() );
|
||||
|
||||
my $sql = "delete from Config";
|
||||
my $res = $dbh->do( $sql )
|
||||
or croak( "Can't do '$sql': ".$dbh->errstr() );
|
||||
|
||||
$sql = "replace into Config set Id = ?, Name = ?, Value = ?, Type = ?, DefaultValue = ?, Hint = ?, Pattern = ?, Format = ?, Prompt = ?, Help = ?, Category = ?, Readonly = ?, Requires = ?";
|
||||
my $sth = $dbh->prepare_cached( $sql )
|
||||
or croak( "Can't prepare '$sql': ".$dbh->errstr() );
|
||||
foreach my $option ( @options )
|
||||
{
|
||||
#next if ( $option->{category} eq 'hidden' );
|
||||
#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 $res = $sth->execute(
|
||||
$option->{id},
|
||||
$option->{name},
|
||||
$option->{db_value},
|
||||
$option->{db_type},
|
||||
$option->{default},
|
||||
$option->{db_hint},
|
||||
$option->{db_pattern},
|
||||
$option->{db_format},
|
||||
$option->{description},
|
||||
$option->{help},
|
||||
$option->{category},
|
||||
$option->{readonly} ? 1 : 0,
|
||||
$option->{db_requires}
|
||||
) or croak( "Can't execute: ".$sth->errstr() );
|
||||
}
|
||||
$sth->finish();
|
||||
|
||||
$dbh->do('UNLOCK TABLES');
|
||||
$dbh->{AutoCommit} = $ac;
|
||||
}
|
||||
|
||||
1;
|
||||
__END__
|
||||
1;
|
||||
__END__
|
||||
|
||||
|
@ -121,7 +239,7 @@ ZoneMinder::Config - ZoneMinder configuration module.
|
|||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use ZoneMinder::Config qw(:all);
|
||||
use ZoneMinder::Config qw(:all);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
|
@ -136,7 +254,25 @@ namespace of the calling program or module.
|
|||
Once the configuration has been imported then configuration variables are
|
||||
defined as constants and can be accessed directory by name, e.g.
|
||||
|
||||
$lang = $Config{ZM_LANG_DEFAULT};
|
||||
$lang = $Config{ZM_LANG_DEFAULT};
|
||||
|
||||
=head1 METHODS
|
||||
|
||||
=over 4
|
||||
|
||||
=item loadConfigFromDB ();
|
||||
|
||||
Loads existing configuration from the database (if any) and merges it with
|
||||
the definitions held in this module. This results in the merging of any new
|
||||
configuration and the removal of any deprecated configuration while
|
||||
preserving the existing values of every else.
|
||||
|
||||
=item saveConfigToDB ();
|
||||
|
||||
Saves configuration held in memory to the database. The act of loading and
|
||||
saving configuration is a convenient way to ensure that the configuration
|
||||
held in the database corresponds with the most recent definitions and that
|
||||
all components are using the same set of configuration.
|
||||
|
||||
=head2 EXPORT
|
||||
|
||||
|
@ -159,7 +295,7 @@ Copyright (C) 2001-2008 Philip Coombes
|
|||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the same terms as Perl itself, either Perl version 5.8.3 or,
|
||||
at your option, any later version of Perl 5 you may have available.
|
||||
at your option, any later version of Perl 5 you may have available.
|
||||
|
||||
|
||||
=cut
|
||||
=cut
|
||||
|
|
|
@ -1,276 +0,0 @@
|
|||
# ==========================================================================
|
||||
#
|
||||
# ZoneMinder Config Admin Module, $Date$, $Revision$
|
||||
# Copyright (C) 2001-2008 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 module contains the debug definitions and functions used by the rest
|
||||
# of the ZoneMinder scripts
|
||||
#
|
||||
package ZoneMinder::ConfigAdmin;
|
||||
|
||||
use 5.006;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
require Exporter;
|
||||
require ZoneMinder::Base;
|
||||
|
||||
our @ISA = qw(Exporter ZoneMinder::Base);
|
||||
|
||||
# Items to export into callers namespace by default. Note: do not export
|
||||
# names by default without a very good reason. Use EXPORT_OK instead.
|
||||
# Do not simply export all your public functions/methods/constants.
|
||||
|
||||
# This allows declaration use ZoneMinder ':all';
|
||||
# If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
|
||||
# will save memory.
|
||||
our %EXPORT_TAGS = (
|
||||
'functions' => [ qw(
|
||||
loadConfigFromDB
|
||||
saveConfigToDB
|
||||
) ]
|
||||
);
|
||||
push( @{$EXPORT_TAGS{all}}, @{$EXPORT_TAGS{$_}} ) foreach keys %EXPORT_TAGS;
|
||||
|
||||
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'functions'} } );
|
||||
|
||||
our @EXPORT = qw();
|
||||
|
||||
our $VERSION = $ZoneMinder::Base::VERSION;
|
||||
|
||||
# ==========================================================================
|
||||
#
|
||||
# Configuration Administration
|
||||
#
|
||||
# ==========================================================================
|
||||
|
||||
use ZoneMinder::Config qw(:all);
|
||||
use ZoneMinder::ConfigData qw(:all);
|
||||
|
||||
use Carp;
|
||||
|
||||
sub loadConfigFromDB
|
||||
{
|
||||
print( "Loading config from DB\n" );
|
||||
my $dbh = DBI->connect( "DBI:mysql:database=".$Config{ZM_DB_NAME}
|
||||
.";host=".$Config{ZM_DB_HOST}
|
||||
,$Config{ZM_DB_USER}
|
||||
,$Config{ZM_DB_PASS}
|
||||
);
|
||||
|
||||
if ( !$dbh )
|
||||
{
|
||||
print( "Error: unable to load options from database: $DBI::errstr\n" );
|
||||
return( 0 );
|
||||
}
|
||||
my $sql = "select * from Config";
|
||||
my $sth = $dbh->prepare_cached( $sql )
|
||||
or croak( "Can't prepare '$sql': ".$dbh->errstr() );
|
||||
my $res = $sth->execute()
|
||||
or croak( "Can't execute: ".$sth->errstr() );
|
||||
my $option_count = 0;
|
||||
while( my $config = $sth->fetchrow_hashref() )
|
||||
{
|
||||
my ( $name, $value ) = ( $config->{Name}, $config->{Value} );
|
||||
#print( "Name = '$name'\n" );
|
||||
my $option = $options_hash{$name};
|
||||
if ( !$option )
|
||||
{
|
||||
warn( "No option '$name' found, removing" );
|
||||
next;
|
||||
}
|
||||
#next if ( $option->{category} eq 'hidden' );
|
||||
if ( defined($value) )
|
||||
{
|
||||
if ( $option->{type} == $types{boolean} )
|
||||
{
|
||||
$option->{value} = $value?"yes":"no";
|
||||
}
|
||||
else
|
||||
{
|
||||
$option->{value} = $value;
|
||||
}
|
||||
}
|
||||
$option_count++;;
|
||||
}
|
||||
$sth->finish();
|
||||
$dbh->disconnect();
|
||||
return( $option_count );
|
||||
}
|
||||
|
||||
sub saveConfigToDB
|
||||
{
|
||||
print( "Saving config to DB\n" );
|
||||
my $dbh = DBI->connect( "DBI:mysql:database=".$Config{ZM_DB_NAME}
|
||||
.";host=".$Config{ZM_DB_HOST}
|
||||
,$Config{ZM_DB_USER}
|
||||
,$Config{ZM_DB_PASS}
|
||||
);
|
||||
|
||||
if ( !$dbh )
|
||||
{
|
||||
print( "Error: unable to save options to database: $DBI::errstr\n" );
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
my $ac = $dbh->{AutoCommit};
|
||||
$dbh->{AutoCommit} = 0;
|
||||
|
||||
$dbh->do('LOCK TABLE Config WRITE')
|
||||
or croak( "Can't lock Config table: " . $dbh->errstr() );
|
||||
|
||||
my $sql = "delete from Config";
|
||||
my $res = $dbh->do( $sql )
|
||||
or croak( "Can't do '$sql': ".$dbh->errstr() );
|
||||
|
||||
$sql = "replace into Config set Id = ?, Name = ?, Value = ?, Type = ?, DefaultValue = ?, Hint = ?, Pattern = ?, Format = ?, Prompt = ?, Help = ?, Category = ?, Readonly = ?, Requires = ?";
|
||||
my $sth = $dbh->prepare_cached( $sql )
|
||||
or croak( "Can't prepare '$sql': ".$dbh->errstr() );
|
||||
foreach my $option ( @options )
|
||||
{
|
||||
#next if ( $option->{category} eq 'hidden' );
|
||||
#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 $res = $sth->execute(
|
||||
$option->{id},
|
||||
$option->{name},
|
||||
$option->{db_value},
|
||||
$option->{db_type},
|
||||
$option->{default},
|
||||
$option->{db_hint},
|
||||
$option->{db_pattern},
|
||||
$option->{db_format},
|
||||
$option->{description},
|
||||
$option->{help},
|
||||
$option->{category},
|
||||
$option->{readonly} ? 1 : 0,
|
||||
$option->{db_requires}
|
||||
) or croak( "Can't execute: ".$sth->errstr() );
|
||||
}
|
||||
$sth->finish();
|
||||
|
||||
$dbh->do('UNLOCK TABLES');
|
||||
$dbh->{AutoCommit} = $ac;
|
||||
|
||||
$dbh->disconnect();
|
||||
}
|
||||
|
||||
1;
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
ZoneMinder::ConfigAdmin - ZoneMinder Configuration Administration module
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use ZoneMinder::ConfigAdmin;
|
||||
use ZoneMinder::ConfigAdmin qw(:all);
|
||||
|
||||
loadConfigFromDB();
|
||||
saveConfigToDB();
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
The ZoneMinder:ConfigAdmin module contains the master definition of the
|
||||
ZoneMinder configuration options as well as helper methods. This module is
|
||||
intended for specialist confguration management and would not normally be
|
||||
used by end users.
|
||||
|
||||
The configuration held in this module, which was previously in zmconfig.pl,
|
||||
includes the name, default value, description, help text, type and category
|
||||
for each option, as well as a number of additional fields in a small number
|
||||
of cases.
|
||||
|
||||
=head1 METHODS
|
||||
|
||||
=over 4
|
||||
|
||||
=item loadConfigFromDB ();
|
||||
|
||||
Loads existing configuration from the database (if any) and merges it with
|
||||
the definitions held in this module. This results in the merging of any new
|
||||
configuration and the removal of any deprecated configuration while
|
||||
preserving the existing values of every else.
|
||||
|
||||
=item saveConfigToDB ();
|
||||
|
||||
Saves configuration held in memory to the database. The act of loading and
|
||||
saving configuration is a convenient way to ensure that the configuration
|
||||
held in the database corresponds with the most recent definitions and that
|
||||
all components are using the same set of configuration.
|
||||
|
||||
=back
|
||||
|
||||
=head2 EXPORT
|
||||
|
||||
None by default.
|
||||
The :data tag will export the various configuration data structures
|
||||
The :functions tag will export the helper functions.
|
||||
The :all tag will export all above symbols.
|
||||
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
http://www.zoneminder.com
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Philip Coombes, E<lt>philip.coombes@zoneminder.comE<gt>
|
||||
|
||||
=head1 COPYRIGHT AND LICENSE
|
||||
|
||||
Copyright (C) 2001-2008 Philip Coombes
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the same terms as Perl itself, either Perl version 5.8.3 or,
|
||||
at your option, any later version of Perl 5 you may have available.
|
||||
|
||||
|
||||
=cut
|
|
@ -1709,6 +1709,17 @@ our @options =
|
|||
type => $types{boolean},
|
||||
category => "config",
|
||||
},
|
||||
{
|
||||
name => 'ZM_LD_PRELOAD',
|
||||
default => '',
|
||||
description => "Path to library to preload before launching daemons",
|
||||
help => qqq("Some older cameras require the use of the v4l1 compat
|
||||
library. This setting allows the setting of the path
|
||||
to the library, so that it can be loaded by zmdc.pl
|
||||
before launching zmc."),
|
||||
type => $types{abs_path},
|
||||
category => 'config',
|
||||
},
|
||||
{
|
||||
name => "ZM_SIGNAL_CHECK_POINTS",
|
||||
default => "10",
|
||||
|
|
|
@ -27,9 +27,11 @@ package ZoneMinder::Database;
|
|||
use 5.006;
|
||||
use strict;
|
||||
use warnings;
|
||||
use DBI;
|
||||
|
||||
require Exporter;
|
||||
require ZoneMinder::Base;
|
||||
require ZoneMinder::Config;
|
||||
|
||||
our @ISA = qw(Exporter ZoneMinder::Base);
|
||||
|
||||
|
@ -64,7 +66,6 @@ our $VERSION = $ZoneMinder::Base::VERSION;
|
|||
# ==========================================================================
|
||||
|
||||
use ZoneMinder::Logger qw(:all);
|
||||
use ZoneMinder::Config qw(:all);
|
||||
|
||||
use Carp;
|
||||
|
||||
|
@ -79,23 +80,23 @@ sub zmDbConnect
|
|||
}
|
||||
if ( !defined( $dbh ) )
|
||||
{
|
||||
my ( $host, $port ) = ( $Config{ZM_DB_HOST} =~ /^([^:]+)(?::(.+))?$/ );
|
||||
my ( $host, $port ) = ( $ZoneMinder::Config::Config{ZM_DB_HOST} =~ /^([^:]+)(?::(.+))?$/ );
|
||||
|
||||
if ( defined($port) )
|
||||
{
|
||||
$dbh = DBI->connect( "DBI:mysql:database=".$Config{ZM_DB_NAME}
|
||||
$dbh = DBI->connect( "DBI:mysql:database=".$ZoneMinder::Config::Config{ZM_DB_NAME}
|
||||
.";host=".$host
|
||||
.";port=".$port
|
||||
, $Config{ZM_DB_USER}
|
||||
, $Config{ZM_DB_PASS}
|
||||
, $ZoneMinder::Config::Config{ZM_DB_USER}
|
||||
, $ZoneMinder::Config::Config{ZM_DB_PASS}
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
$dbh = DBI->connect( "DBI:mysql:database=".$Config{ZM_DB_NAME}
|
||||
.";host=".$Config{ZM_DB_HOST}
|
||||
, $Config{ZM_DB_USER}
|
||||
, $Config{ZM_DB_PASS}
|
||||
$dbh = DBI->connect( "DBI:mysql:database=".$ZoneMinder::Config::Config{ZM_DB_NAME}
|
||||
.";host=".$ZoneMinder::Config::Config{ZM_DB_HOST}
|
||||
, $ZoneMinder::Config::Config{ZM_DB_USER}
|
||||
, $ZoneMinder::Config::Config{ZM_DB_PASS}
|
||||
);
|
||||
}
|
||||
$dbh->trace( 0 );
|
||||
|
|
|
@ -30,6 +30,9 @@ use warnings;
|
|||
|
||||
require Exporter;
|
||||
require ZoneMinder::Base;
|
||||
require ZoneMinder::Database;
|
||||
require ZoneMinder::Config;
|
||||
|
||||
|
||||
our @ISA = qw(Exporter ZoneMinder::Base);
|
||||
|
||||
|
@ -86,8 +89,6 @@ our $VERSION = $ZoneMinder::Base::VERSION;
|
|||
#
|
||||
# ==========================================================================
|
||||
|
||||
use ZoneMinder::Config qw(:all);
|
||||
|
||||
use DBI;
|
||||
use Carp;
|
||||
use POSIX;
|
||||
|
@ -151,7 +152,7 @@ sub new
|
|||
$this->{hasTerm} = -t STDERR;
|
||||
|
||||
( $this->{fileName} = $0 ) =~ s|^.*/||;
|
||||
$this->{logPath} = $Config{ZM_PATH_LOGS};
|
||||
$this->{logPath} = $ZoneMinder::Config::Config{ZM_PATH_LOGS};
|
||||
$this->{logFile} = $this->{logPath}."/".$this->{id}.".log";
|
||||
|
||||
$this->{trace} = 0;
|
||||
|
@ -164,7 +165,7 @@ sub BEGIN
|
|||
{
|
||||
# Fake the config variables that are used in case they are not defined yet
|
||||
# Only really necessary to support upgrade from previous version
|
||||
if ( !eval('defined($Config{ZM_LOG_DEBUG})') )
|
||||
if ( !eval('defined($ZoneMinder::Config::Config{ZM_LOG_DEBUG})') )
|
||||
{
|
||||
no strict 'subs';
|
||||
no strict 'refs';
|
||||
|
@ -222,7 +223,7 @@ sub initialise( @ )
|
|||
}
|
||||
else
|
||||
{
|
||||
$tempDatabaseLevel = $Config{ZM_LOG_LEVEL_DATABASE};
|
||||
$tempDatabaseLevel = $ZoneMinder::Config::Config{ZM_LOG_LEVEL_DATABASE};
|
||||
}
|
||||
if ( defined($options{fileLevel}) )
|
||||
{
|
||||
|
@ -230,7 +231,7 @@ sub initialise( @ )
|
|||
}
|
||||
else
|
||||
{
|
||||
$tempFileLevel = $Config{ZM_LOG_LEVEL_FILE};
|
||||
$tempFileLevel = $ZoneMinder::Config::Config{ZM_LOG_LEVEL_FILE};
|
||||
}
|
||||
if ( defined($options{syslogLevel}) )
|
||||
{
|
||||
|
@ -238,7 +239,7 @@ sub initialise( @ )
|
|||
}
|
||||
else
|
||||
{
|
||||
$tempSyslogLevel = $Config{ZM_LOG_LEVEL_SYSLOG};
|
||||
$tempSyslogLevel = $ZoneMinder::Config::Config{ZM_LOG_LEVEL_SYSLOG};
|
||||
}
|
||||
|
||||
if ( defined($ENV{'LOG_PRINT'}) )
|
||||
|
@ -254,9 +255,9 @@ sub initialise( @ )
|
|||
$tempFileLevel = $level if ( defined($level = $this->getTargettedEnv('LOG_LEVEL_FILE')) );
|
||||
$tempSyslogLevel = $level if ( defined($level = $this->getTargettedEnv('LOG_LEVEL_SYSLOG')) );
|
||||
|
||||
if ( $Config{ZM_LOG_DEBUG} )
|
||||
if ( $ZoneMinder::Config::Config{ZM_LOG_DEBUG} )
|
||||
{
|
||||
foreach my $target ( split( /\|/, $Config{ZM_LOG_DEBUG_TARGET} ) )
|
||||
foreach my $target ( split( /\|/, $ZoneMinder::Config::Config{ZM_LOG_DEBUG_TARGET} ) )
|
||||
{
|
||||
if ( $target eq $this->{id}
|
||||
|| $target eq "_".$this->{id}
|
||||
|
@ -265,12 +266,12 @@ sub initialise( @ )
|
|||
|| $target eq ""
|
||||
)
|
||||
{
|
||||
if ( $Config{ZM_LOG_DEBUG_LEVEL} > NOLOG )
|
||||
if ( $ZoneMinder::Config::Config{ZM_LOG_DEBUG_LEVEL} > NOLOG )
|
||||
{
|
||||
$tempLevel = $this->limit( $Config{ZM_LOG_DEBUG_LEVEL} );
|
||||
if ( $Config{ZM_LOG_DEBUG_FILE} ne "" )
|
||||
$tempLevel = $this->limit( $ZoneMinder::Config::Config{ZM_LOG_DEBUG_LEVEL} );
|
||||
if ( $ZoneMinder::Config::Config{ZM_LOG_DEBUG_FILE} ne "" )
|
||||
{
|
||||
$tempLogFile = $Config{ZM_LOG_DEBUG_FILE};
|
||||
$tempLogFile = $ZoneMinder::Config::Config{ZM_LOG_DEBUG_FILE};
|
||||
$tempFileLevel = $tempLevel;
|
||||
}
|
||||
}
|
||||
|
@ -460,32 +461,14 @@ sub databaseLevel
|
|||
{
|
||||
if ( !$this->{dbh} )
|
||||
{
|
||||
my ( $host, $port ) = ( $Config{ZM_DB_HOST} =~ /^([^:]+)(?::(.+))?$/ );
|
||||
|
||||
if ( defined($port) )
|
||||
{
|
||||
$this->{dbh} = DBI->connect( "DBI:mysql:database=".$Config{ZM_DB_NAME}
|
||||
.";host=".$host
|
||||
.";port=".$port
|
||||
, $Config{ZM_DB_USER}
|
||||
, $Config{ZM_DB_PASS}
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->{dbh} = DBI->connect( "DBI:mysql:database=".$Config{ZM_DB_NAME}
|
||||
.";host=".$Config{ZM_DB_HOST}
|
||||
, $Config{ZM_DB_USER}
|
||||
, $Config{ZM_DB_PASS}
|
||||
);
|
||||
}
|
||||
$this->{dbh} = ZoneMinder::Database::zmDbConnect();
|
||||
if ( !$this->{dbh} )
|
||||
{
|
||||
$databaseLevel = NOLOG;
|
||||
Error( "Unable to write log entries to DB, can't connect to database '"
|
||||
.$Config{ZM_DB_NAME}
|
||||
.$ZoneMinder::Config::Config{ZM_DB_NAME}
|
||||
."' on host '"
|
||||
.$Config{ZM_DB_HOST}
|
||||
.$ZoneMinder::Config::Config{ZM_DB_HOST}
|
||||
."'"
|
||||
);
|
||||
}
|
||||
|
@ -505,7 +488,8 @@ sub databaseLevel
|
|||
{
|
||||
if ( $this->{dbh} )
|
||||
{
|
||||
$this->{dbh}->disconnect();
|
||||
# $this->dbh is now the global dbh, so don't close it.
|
||||
#$this->{dbh}->disconnect();
|
||||
undef($this->{dbh});
|
||||
}
|
||||
}
|
||||
|
@ -582,8 +566,8 @@ sub openFile
|
|||
{
|
||||
$LOGFILE->autoflush() if ( $this->{autoFlush} );
|
||||
|
||||
my $webUid = (getpwnam( $Config{ZM_WEB_USER} ))[2];
|
||||
my $webGid = (getgrnam( $Config{ZM_WEB_GROUP} ))[2];
|
||||
my $webUid = (getpwnam( $ZoneMinder::Config::Config{ZM_WEB_USER} ))[2];
|
||||
my $webGid = (getgrnam( $ZoneMinder::Config::Config{ZM_WEB_GROUP} ))[2];
|
||||
if ( $> == 0 )
|
||||
{
|
||||
chown( $webUid, $webGid, $this->{logFile} )
|
||||
|
|
|
@ -75,6 +75,10 @@ $| = 1;
|
|||
|
||||
$ENV{PATH} = '/bin:/usr/bin:/usr/local/bin';
|
||||
$ENV{SHELL} = '/bin/sh' if exists $ENV{SHELL};
|
||||
if ( $Config{ZM_LD_PRELOAD} ) {
|
||||
Debug("Adding ENV{LD_PRELOAD} = $Config{ZM_LD_PRELOAD}");
|
||||
$ENV{LD_PRELOAD} = $Config{ZM_LD_PRELOAD};
|
||||
}
|
||||
delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};
|
||||
|
||||
my @daemons = (
|
||||
|
|
|
@ -67,12 +67,8 @@ use constant CHECK_INTERVAL => (1*24*60*60); # Interval between version checks
|
|||
# ==========================================================================
|
||||
|
||||
@EXTRA_PERL_LIB@
|
||||
use ZoneMinder::Base qw(:all);
|
||||
use ZoneMinder;
|
||||
use ZoneMinder::Config qw(:all);
|
||||
use ZoneMinder::Logger qw(:all);
|
||||
use ZoneMinder::General qw(:all);
|
||||
use ZoneMinder::Database qw(:all);
|
||||
use ZoneMinder::ConfigAdmin qw( :functions );
|
||||
use POSIX;
|
||||
use DBI;
|
||||
use Getopt::Long;
|
||||
|
@ -155,6 +151,7 @@ if ( $check && $Config{ZM_CHECK_FOR_UPDATES} )
|
|||
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( "$currVersion" ) or die( "Can't execute: ".$sth->errstr() );
|
||||
$sth->finish();
|
||||
}
|
||||
|
||||
while( 1 )
|
||||
|
@ -184,10 +181,12 @@ if ( $check && $Config{ZM_CHECK_FOR_UPDATES} )
|
|||
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( $lastVersion ) or die( "Can't execute: ".$lv_sth->errstr() );
|
||||
$lv_sth->finish();
|
||||
|
||||
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( $lastCheck ) or die( "Can't execute: ".$lc_sth->errstr() );
|
||||
$lc_sth->finish();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -239,14 +238,14 @@ if ( $zoneFix )
|
|||
}
|
||||
$sth->finish();
|
||||
|
||||
$sql = "update Zones set MinAlarmPixels = ?, MaxAlarmPixels = ?, MinFilterPixels = ?, MaxFilterPixels = ?, MinBlobPixels = ?, MaxBlobPixels = ? where Id = ?";
|
||||
$sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
|
||||
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,
|
||||
|
@ -257,6 +256,7 @@ if ( $zoneFix )
|
|||
$zone->{Id}
|
||||
) or die( "Can't execute: ".$sth->errstr() );
|
||||
}
|
||||
$sth->finish();
|
||||
}
|
||||
if ( $migrateEvents )
|
||||
{
|
||||
|
@ -318,11 +318,13 @@ if ( $migrateEvents )
|
|||
symlink( $newTimePath, $idLink ) or die( "Can't symlink $newTimePath -> $idLink: $!" );
|
||||
rename( $oldEventPath, $newEventPath ) or die( "Can't move $oldEventPath -> $newEventPath: $!" );
|
||||
}
|
||||
$sth->finish();
|
||||
|
||||
print( "Updating configuration.\n" );
|
||||
$sql = "update Config set Value = ? where Name = 'ZM_USE_DEEP_STORAGE'";
|
||||
$sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
|
||||
$res = $sth->execute( 1 ) or die( "Can't execute: ".$sth->errstr() );
|
||||
$sth->finish();
|
||||
|
||||
print( "All events converted.\n\n" );
|
||||
}
|
||||
|
@ -334,8 +336,8 @@ if ( $migrateEvents )
|
|||
if ( $freshen )
|
||||
{
|
||||
print( "\nFreshening configuration in database\n" );
|
||||
loadConfigFromDB();
|
||||
saveConfigToDB();
|
||||
ZoneMinder::Config::loadConfigFromDB();
|
||||
ZoneMinder::Config::saveConfigToDB();
|
||||
}
|
||||
|
||||
# Don't do innoDB upgrade if not interactive
|
||||
|
@ -359,12 +361,12 @@ if ( $interactive ) {
|
|||
if ( $response =~ /^[yY]$/ ) {
|
||||
$dbh->do(q|SET sql_mode='traditional'|); # Elevate warnings to errors
|
||||
print "\nConverting MyISAM tables to InnoDB. Please wait.\n";
|
||||
my $sql = "ALTER TABLE $_ ENGINE = InnoDB";
|
||||
my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
|
||||
foreach (@MyISAM_Tables) {
|
||||
my $sql = "ALTER TABLE $_ ENGINE = InnoDB";
|
||||
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() );
|
||||
$sth->finish();
|
||||
}
|
||||
$sth->finish();
|
||||
$dbh->do(q|SET sql_mode=''|); # Set mode back to default
|
||||
}
|
||||
}
|
||||
|
@ -494,8 +496,8 @@ if ( $version )
|
|||
print( "\nUpgrading database to version ".ZM_VERSION."\n" );
|
||||
|
||||
# Update config first of all
|
||||
loadConfigFromDB();
|
||||
saveConfigToDB();
|
||||
ZoneMinder::Config::loadConfigFromDB();
|
||||
ZoneMinder::Config::saveConfigToDB();
|
||||
|
||||
my $cascade = undef;
|
||||
if ( $cascade || $version eq "1.19.0" )
|
||||
|
@ -1064,6 +1066,7 @@ if ( $version )
|
|||
my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
|
||||
my $res = $sth->execute( "$installed_version", "ZM_DYN_DB_VERSION" ) or die( "Can't execute: ".$sth->errstr() );
|
||||
$res = $sth->execute( "$installed_version", "ZM_DYN_CURR_VERSION" ) or die( "Can't execute: ".$sth->errstr() );
|
||||
$sth->finish();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
162
src/zm_comms.cpp
162
src/zm_comms.cpp
|
@ -35,6 +35,8 @@
|
|||
#include <sys/ioctl.h>
|
||||
#include <sys/param.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <arpa/inet.h> // for debug output
|
||||
#include <stdio.h> // for snprintf
|
||||
|
||||
#ifdef SOLARIS
|
||||
#include <sys/filio.h> // define FIONREAD
|
||||
|
@ -516,6 +518,166 @@ bool Socket::setNoDelay( bool nodelay )
|
|||
return( true );
|
||||
}
|
||||
|
||||
bool InetSocket::connect( const char *host, const char *serv )
|
||||
{
|
||||
struct addrinfo hints;
|
||||
struct addrinfo *result, *rp;
|
||||
int s;
|
||||
char buf[255];
|
||||
|
||||
mAddressFamily = AF_UNSPEC;
|
||||
memset(&hints, 0, sizeof(struct addrinfo));
|
||||
hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
|
||||
hints.ai_socktype = getType();
|
||||
hints.ai_flags = 0;
|
||||
hints.ai_protocol = 0; /* Any protocol */
|
||||
|
||||
s = getaddrinfo(host, serv, &hints, &result);
|
||||
if (s != 0) {
|
||||
Error( "connect(): getaddrinfo: %s", gai_strerror(s) );
|
||||
return( false );
|
||||
}
|
||||
|
||||
/* getaddrinfo() returns a list of address structures.
|
||||
* Try each address until we successfully connect(2).
|
||||
* If socket(2) (or connect(2)) fails, we (close the socket
|
||||
* and) try the next address. */
|
||||
|
||||
for (rp = result; rp != NULL; rp = rp->ai_next) {
|
||||
if (mSd != -1) {
|
||||
if (::connect(mSd, rp->ai_addr, rp->ai_addrlen) != -1)
|
||||
break; /* Success */
|
||||
continue;
|
||||
}
|
||||
memset(&buf, 0, sizeof(buf));
|
||||
if (rp->ai_family == AF_INET) {
|
||||
inet_ntop(AF_INET, &((struct sockaddr_in *)rp->ai_addr)->sin_addr, buf, sizeof(buf)-1);
|
||||
}
|
||||
else if (rp->ai_family == AF_INET6) {
|
||||
inet_ntop(AF_INET6, &((struct sockaddr_in6 *)rp->ai_addr)->sin6_addr, buf, sizeof(buf)-1);
|
||||
}
|
||||
else {
|
||||
strncpy(buf, "n/a", sizeof(buf)-1);
|
||||
}
|
||||
Debug( 1, "connect(): Trying '%s', family '%d', proto '%d'", buf, rp->ai_family, rp->ai_protocol);
|
||||
mSd = ::socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
|
||||
if (mSd == -1)
|
||||
continue;
|
||||
|
||||
int val = 1;
|
||||
|
||||
(void)::setsockopt( mSd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val) );
|
||||
(void)::setsockopt( mSd, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val) );
|
||||
mAddressFamily = rp->ai_family; /* save AF_ for ctrl and data connections */
|
||||
|
||||
if (::connect(mSd, rp->ai_addr, rp->ai_addrlen) != -1)
|
||||
break; /* Success */
|
||||
|
||||
::close(mSd);
|
||||
}
|
||||
|
||||
if (rp == NULL) { /* No address succeeded */
|
||||
Error( "connect(), Could not connect" );
|
||||
mAddressFamily = AF_UNSPEC;
|
||||
return( false );
|
||||
}
|
||||
|
||||
freeaddrinfo(result); /* No longer needed */
|
||||
|
||||
mState = CONNECTED;
|
||||
|
||||
return( true );
|
||||
}
|
||||
|
||||
bool InetSocket::connect( const char *host, int port )
|
||||
{
|
||||
char serv[8];
|
||||
snprintf(serv, sizeof(serv), "%d", port);
|
||||
|
||||
return connect( host, serv );
|
||||
}
|
||||
|
||||
bool InetSocket::bind( const char * host, const char * serv )
|
||||
{
|
||||
struct addrinfo hints;
|
||||
struct addrinfo *result, *rp;
|
||||
int s;
|
||||
char buf[255];
|
||||
|
||||
memset(&hints, 0, sizeof(struct addrinfo));
|
||||
hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
|
||||
hints.ai_socktype = getType();
|
||||
hints.ai_flags = AI_PASSIVE; /* For wildcard IP address */
|
||||
hints.ai_protocol = 0; /* Any protocol */
|
||||
hints.ai_canonname = NULL;
|
||||
hints.ai_addr = NULL;
|
||||
hints.ai_next = NULL;
|
||||
|
||||
s = getaddrinfo(host, serv, &hints, &result);
|
||||
if (s != 0) {
|
||||
Error( "bind(): getaddrinfo: %s", gai_strerror(s) );
|
||||
return( false );
|
||||
}
|
||||
|
||||
/* getaddrinfo() returns a list of address structures.
|
||||
* Try each address until we successfully bind(2).
|
||||
* If socket(2) (or bind(2)) fails, we (close the socket
|
||||
* and) try the next address. */
|
||||
for (rp = result; rp != NULL; rp = rp->ai_next) {
|
||||
memset(&buf, 0, sizeof(buf));
|
||||
if (rp->ai_family == AF_INET) {
|
||||
inet_ntop(AF_INET, &((struct sockaddr_in *)rp->ai_addr)->sin_addr, buf, sizeof(buf)-1);
|
||||
}
|
||||
else if (rp->ai_family == AF_INET6) {
|
||||
inet_ntop(AF_INET6, &((struct sockaddr_in6 *)rp->ai_addr)->sin6_addr, buf, sizeof(buf)-1);
|
||||
}
|
||||
else {
|
||||
strncpy(buf, "n/a", sizeof(buf)-1);
|
||||
}
|
||||
Debug( 1, "bind(): Trying '%s', family '%d', proto '%d'", buf, rp->ai_family, rp->ai_protocol);
|
||||
mSd = ::socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
|
||||
if (mSd == -1)
|
||||
continue;
|
||||
|
||||
mState = DISCONNECTED;
|
||||
if (::bind(mSd, rp->ai_addr, rp->ai_addrlen) == 0)
|
||||
break; /* Success */
|
||||
|
||||
::close(mSd);
|
||||
mSd = -1;
|
||||
}
|
||||
|
||||
if (rp == NULL) { /* No address succeeded */
|
||||
Error( "bind(), Could not bind" );
|
||||
return( false );
|
||||
}
|
||||
|
||||
freeaddrinfo(result); /* No longer needed */
|
||||
|
||||
return( true );
|
||||
}
|
||||
|
||||
bool InetSocket::bind( const char * serv )
|
||||
{
|
||||
return bind( NULL, serv);
|
||||
}
|
||||
|
||||
bool InetSocket::bind( const char * host, int port )
|
||||
{
|
||||
char serv[8];
|
||||
snprintf(serv, sizeof(serv), "%d", port);
|
||||
|
||||
return bind( host, serv );
|
||||
}
|
||||
|
||||
bool InetSocket::bind( int port )
|
||||
{
|
||||
char serv[8];
|
||||
snprintf(serv, sizeof(serv), "%d", port);
|
||||
|
||||
return bind( NULL, serv );
|
||||
}
|
||||
|
||||
bool TcpInetServer::listen()
|
||||
{
|
||||
return( Socket::listen() );
|
||||
|
|
160
src/zm_comms.h
160
src/zm_comms.h
|
@ -399,103 +399,27 @@ public:
|
|||
|
||||
class InetSocket : virtual public Socket
|
||||
{
|
||||
protected:
|
||||
int mAddressFamily;
|
||||
|
||||
public:
|
||||
int getDomain() const
|
||||
{
|
||||
return( AF_INET );
|
||||
}
|
||||
virtual socklen_t getAddrSize() const
|
||||
{
|
||||
return( SockAddrInet::addrSize() );
|
||||
}
|
||||
int getDomain() const
|
||||
{
|
||||
return( mAddressFamily );
|
||||
}
|
||||
virtual socklen_t getAddrSize() const
|
||||
{
|
||||
return( SockAddrInet::addrSize() );
|
||||
}
|
||||
|
||||
protected:
|
||||
bool resolveLocal( const char *host, const char *serv, const char *proto )
|
||||
{
|
||||
SockAddrInet *addr = new SockAddrInet;
|
||||
mLocalAddr = addr;
|
||||
return( addr->resolve( host, serv, proto ) );
|
||||
}
|
||||
bool resolveLocal( const char *host, int port, const char *proto )
|
||||
{
|
||||
SockAddrInet *addr = new SockAddrInet;
|
||||
mLocalAddr = addr;
|
||||
return( addr->resolve( host, port, proto ) );
|
||||
}
|
||||
bool resolveLocal( const char *serv, const char *proto )
|
||||
{
|
||||
SockAddrInet *addr = new SockAddrInet;
|
||||
mLocalAddr = addr;
|
||||
return( addr->resolve( serv, proto ) );
|
||||
}
|
||||
bool resolveLocal( int port, const char *proto )
|
||||
{
|
||||
SockAddrInet *addr = new SockAddrInet;
|
||||
mLocalAddr = addr;
|
||||
return( addr->resolve( port, proto ) );
|
||||
}
|
||||
bool connect( const char *host, const char *serv );
|
||||
bool connect( const char *host, int port );
|
||||
|
||||
bool resolveRemote( const char *host, const char *serv, const char *proto )
|
||||
{
|
||||
SockAddrInet *addr = new SockAddrInet;
|
||||
mRemoteAddr = addr;
|
||||
return( addr->resolve( host, serv, proto ) );
|
||||
}
|
||||
bool resolveRemote( const char *host, int port, const char *proto )
|
||||
{
|
||||
SockAddrInet *addr = new SockAddrInet;
|
||||
mRemoteAddr = addr;
|
||||
return( addr->resolve( host, port, proto ) );
|
||||
}
|
||||
|
||||
protected:
|
||||
bool bind( const SockAddrInet &addr )
|
||||
{
|
||||
mLocalAddr = new SockAddrInet( addr );
|
||||
return( Socket::bind() );
|
||||
}
|
||||
bool bind( const char *host, const char *serv )
|
||||
{
|
||||
if ( !resolveLocal( host, serv, getProtocol() ) )
|
||||
return( false );
|
||||
return( Socket::bind() );
|
||||
}
|
||||
bool bind( const char *host, int port )
|
||||
{
|
||||
if ( !resolveLocal( host, port, getProtocol() ) )
|
||||
return( false );
|
||||
return( Socket::bind() );
|
||||
}
|
||||
bool bind( const char *serv )
|
||||
{
|
||||
if ( !resolveLocal( serv, getProtocol() ) )
|
||||
return( false );
|
||||
return( Socket::bind() );
|
||||
}
|
||||
bool bind( int port )
|
||||
{
|
||||
if ( !resolveLocal( port, getProtocol() ) )
|
||||
return( false );
|
||||
return( Socket::bind() );
|
||||
}
|
||||
|
||||
bool connect( const SockAddrInet &addr )
|
||||
{
|
||||
mRemoteAddr = new SockAddrInet( addr );
|
||||
return( Socket::connect() );
|
||||
}
|
||||
bool connect( const char *host, const char *serv )
|
||||
{
|
||||
if ( !resolveRemote( host, serv, getProtocol() ) )
|
||||
return( false );
|
||||
return( Socket::connect() );
|
||||
}
|
||||
bool connect( const char *host, int port )
|
||||
{
|
||||
if ( !resolveRemote( host, port, getProtocol() ) )
|
||||
return( false );
|
||||
return( Socket::connect() );
|
||||
}
|
||||
bool bind( const char *host, const char *serv );
|
||||
bool bind( const char *host, int port );
|
||||
bool bind( const char *serv );
|
||||
bool bind( int port );
|
||||
};
|
||||
|
||||
class UnixSocket : virtual public Socket
|
||||
|
@ -591,10 +515,6 @@ public:
|
|||
class UdpInetSocket : virtual public UdpSocket, virtual public InetSocket
|
||||
{
|
||||
public:
|
||||
bool bind( const SockAddrInet &addr )
|
||||
{
|
||||
return( InetSocket::bind( addr ) );
|
||||
}
|
||||
bool bind( const char *host, const char *serv )
|
||||
{
|
||||
return( InetSocket::bind( host, serv ) );
|
||||
|
@ -612,10 +532,6 @@ public:
|
|||
return( InetSocket::bind( port ) );
|
||||
}
|
||||
|
||||
bool connect( const SockAddrInet &addr )
|
||||
{
|
||||
return( InetSocket::connect( addr ) );
|
||||
}
|
||||
bool connect( const char *host, const char *serv )
|
||||
{
|
||||
return( InetSocket::connect( host, serv ) );
|
||||
|
@ -642,33 +558,7 @@ public:
|
|||
|
||||
class UdpInetClient : public UdpInetSocket
|
||||
{
|
||||
protected:
|
||||
bool bind( const SockAddrInet &addr )
|
||||
{
|
||||
return( UdpInetSocket::bind( addr ) );
|
||||
}
|
||||
bool bind( const char *host, const char *serv )
|
||||
{
|
||||
return( UdpInetSocket::bind( host, serv ) );
|
||||
}
|
||||
bool bind( const char *host, int port )
|
||||
{
|
||||
return( UdpInetSocket::bind( host, port ) );
|
||||
}
|
||||
bool bind( const char *serv )
|
||||
{
|
||||
return( UdpInetSocket::bind( serv ) );
|
||||
}
|
||||
bool bind( int port )
|
||||
{
|
||||
return( UdpInetSocket::bind( port ) );
|
||||
}
|
||||
|
||||
public:
|
||||
bool connect( const SockAddrInet &addr )
|
||||
{
|
||||
return( UdpInetSocket::connect( addr ) );
|
||||
}
|
||||
bool connect( const char *host, const char *serv )
|
||||
{
|
||||
return( UdpInetSocket::connect( host, serv ) );
|
||||
|
@ -697,10 +587,6 @@ public:
|
|||
class UdpInetServer : public UdpInetSocket
|
||||
{
|
||||
public:
|
||||
bool bind( const SockAddrInet &addr )
|
||||
{
|
||||
return( UdpInetSocket::bind( addr ) );
|
||||
}
|
||||
bool bind( const char *host, const char *serv )
|
||||
{
|
||||
return( UdpInetSocket::bind( host, serv ) );
|
||||
|
@ -812,18 +698,6 @@ public:
|
|||
class TcpInetServer : public TcpInetSocket
|
||||
{
|
||||
public:
|
||||
bool bind( const char *host, const char *serv )
|
||||
{
|
||||
return( TcpInetSocket::bind( host, serv ) );
|
||||
}
|
||||
bool bind( const char *host, int port )
|
||||
{
|
||||
return( TcpInetSocket::bind( host, port ) );
|
||||
}
|
||||
bool bind( const char *serv )
|
||||
{
|
||||
return( TcpInetSocket::bind( serv ) );
|
||||
}
|
||||
bool bind( int port )
|
||||
{
|
||||
return( TcpInetSocket::bind( port ) );
|
||||
|
|
|
@ -168,18 +168,18 @@ int SWScale::Convert(const uint8_t* in_buffer, const size_t in_buffer_size, uint
|
|||
|
||||
/* Check the buffer sizes */
|
||||
#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0)
|
||||
size_t insize = av_image_get_buffer_size(in_pf, width, height,1);
|
||||
size_t insize = av_image_get_buffer_size(in_pf, width, height,1);
|
||||
#else
|
||||
size_t insize = avpicture_get_size(in_pf, width, height);
|
||||
size_t insize = avpicture_get_size(in_pf, width, height);
|
||||
#endif
|
||||
if(insize != in_buffer_size) {
|
||||
Error("The input buffer size does not match the expected size for the input format. Required: %d Available: %d", insize, in_buffer_size);
|
||||
return -4;
|
||||
}
|
||||
#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0)
|
||||
size_t outsize = av_image_get_buffer_size(out_pf, width, height,1);
|
||||
size_t outsize = av_image_get_buffer_size(out_pf, width, height,1);
|
||||
#else
|
||||
size_t outsize = avpicture_get_size(out_pf, width, height);
|
||||
size_t outsize = avpicture_get_size(out_pf, width, height);
|
||||
#endif
|
||||
|
||||
if(outsize < out_buffer_size) {
|
||||
|
@ -196,37 +196,30 @@ int SWScale::Convert(const uint8_t* in_buffer, const size_t in_buffer_size, uint
|
|||
|
||||
/* Fill in the buffers */
|
||||
#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0)
|
||||
if(av_image_fill_arrays(input_avframe->data, input_avframe->linesize,
|
||||
(uint8_t*)in_buffer, in_pf, width, height, 1) <= 0)
|
||||
{
|
||||
if(av_image_fill_arrays(input_avframe->data, input_avframe->linesize,
|
||||
(uint8_t*)in_buffer, in_pf, width, height, 1) <= 0)
|
||||
{
|
||||
#else
|
||||
if(avpicture_fill( (AVPicture*)input_avframe, (uint8_t*)in_buffer,
|
||||
in_pf, width, height ) <= 0)
|
||||
{
|
||||
in_pf, width, height ) <= 0)
|
||||
{
|
||||
#endif
|
||||
Error("Failed filling input frame with input buffer");
|
||||
return -7;
|
||||
}
|
||||
#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0)
|
||||
if(av_image_fill_arrays(output_avframe->data, output_avframe->linesize,
|
||||
out_buffer, out_pf, width, height, 1) <= 0)
|
||||
{
|
||||
#else
|
||||
if(avpicture_fill( (AVPicture*)output_avframe, out_buffer,
|
||||
out_pf, width, height ) <= 0)
|
||||
{
|
||||
#endif
|
||||
Error("Failed filling output frame with output buffer");
|
||||
return -8;
|
||||
Error("Failed filling input frame with input buffer");
|
||||
return -7;
|
||||
}
|
||||
|
||||
/* Do the conversion */
|
||||
if(!sws_scale(swscale_ctx, input_avframe->data, input_avframe->linesize, 0, height, output_avframe->data, output_avframe->linesize ) ) {
|
||||
Error("swscale conversion failed");
|
||||
return -10;
|
||||
}
|
||||
if(!avpicture_fill( (AVPicture*)output_avframe, out_buffer, out_pf, width, height ) ) {
|
||||
Error("Failed filling output frame with output buffer");
|
||||
return -8;
|
||||
}
|
||||
|
||||
return 0;
|
||||
/* Do the conversion */
|
||||
if(!sws_scale(swscale_ctx, input_avframe->data, input_avframe->linesize, 0, height, output_avframe->data, output_avframe->linesize ) ) {
|
||||
Error("swscale conversion failed");
|
||||
return -10;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SWScale::Convert(const Image* img, uint8_t* out_buffer, const size_t out_buffer_size, enum _AVPIXELFORMAT in_pf, enum _AVPIXELFORMAT out_pf, unsigned int width, unsigned int height) {
|
||||
|
|
|
@ -51,8 +51,6 @@ extern "C" {
|
|||
|
||||
#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0)
|
||||
#include <libavutil/imgutils.h>
|
||||
#else
|
||||
#include <libavutil/avutil.h>
|
||||
#endif
|
||||
#elif HAVE_FFMPEG_AVUTIL_H
|
||||
#include <ffmpeg/avutil.h>
|
||||
|
|
|
@ -182,43 +182,43 @@ int FfmpegCamera::Capture( Image &image )
|
|||
if ( packet.stream_index == mVideoStreamId )
|
||||
{
|
||||
#if LIBAVCODEC_VERSION_CHECK(52, 23, 0, 23, 0)
|
||||
if ( avcodec_decode_video2( mCodecContext, mRawFrame, &frameComplete, &packet ) < 0 )
|
||||
if ( avcodec_decode_video2( mCodecContext, mRawFrame, &frameComplete, &packet ) < 0 )
|
||||
#else
|
||||
if ( avcodec_decode_video( mCodecContext, mRawFrame, &frameComplete, packet.data, packet.size ) < 0 )
|
||||
if ( avcodec_decode_video( mCodecContext, mRawFrame, &frameComplete, packet.data, packet.size ) < 0 )
|
||||
#endif
|
||||
Fatal( "Unable to decode frame at frame %d", frameCount );
|
||||
Fatal( "Unable to decode frame at frame %d", frameCount );
|
||||
|
||||
Debug( 4, "Decoded video packet at frame %d", frameCount );
|
||||
Debug( 4, "Decoded video packet at frame %d", frameCount );
|
||||
|
||||
if ( frameComplete ) {
|
||||
Debug( 4, "Got frame %d", frameCount );
|
||||
if ( frameComplete ) {
|
||||
Debug( 4, "Got frame %d", frameCount );
|
||||
|
||||
#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0)
|
||||
av_image_fill_arrays(mFrame->data, mFrame->linesize,
|
||||
directbuffer, imagePixFormat, width, height, 1);
|
||||
av_image_fill_arrays(mFrame->data, mFrame->linesize,
|
||||
directbuffer, imagePixFormat, width, height, 1);
|
||||
#else
|
||||
avpicture_fill( (AVPicture *)mFrame, directbuffer,
|
||||
imagePixFormat, width, height);
|
||||
avpicture_fill( (AVPicture *)mFrame, directbuffer,
|
||||
imagePixFormat, width, height);
|
||||
#endif
|
||||
|
||||
#if HAVE_LIBSWSCALE
|
||||
if(mConvertContext == NULL) {
|
||||
mConvertContext = sws_getContext( mCodecContext->width, mCodecContext->height, mCodecContext->pix_fmt, width, height, imagePixFormat, SWS_BICUBIC, NULL, NULL, NULL );
|
||||
if(mConvertContext == NULL) {
|
||||
mConvertContext = sws_getContext( mCodecContext->width, mCodecContext->height, mCodecContext->pix_fmt, width, height, imagePixFormat, SWS_BICUBIC, NULL, NULL, NULL );
|
||||
|
||||
if(mConvertContext == NULL)
|
||||
Fatal( "Unable to create conversion context for %s", mPath.c_str() );
|
||||
}
|
||||
if(mConvertContext == NULL)
|
||||
Fatal( "Unable to create conversion context for %s", mPath.c_str() );
|
||||
}
|
||||
|
||||
if ( sws_scale( mConvertContext, mRawFrame->data, mRawFrame->linesize, 0, mCodecContext->height, mFrame->data, mFrame->linesize ) < 0 )
|
||||
Fatal( "Unable to convert raw format %u to target format %u at frame %d", mCodecContext->pix_fmt, imagePixFormat, frameCount );
|
||||
if ( sws_scale( mConvertContext, mRawFrame->data, mRawFrame->linesize, 0, mCodecContext->height, mFrame->data, mFrame->linesize ) < 0 )
|
||||
Fatal( "Unable to convert raw format %u to target format %u at frame %d", mCodecContext->pix_fmt, imagePixFormat, frameCount );
|
||||
#else // HAVE_LIBSWSCALE
|
||||
Fatal( "You must compile ffmpeg with the --enable-swscale option to use ffmpeg cameras" );
|
||||
Fatal( "You must compile ffmpeg with the --enable-swscale option to use ffmpeg cameras" );
|
||||
#endif // HAVE_LIBSWSCALE
|
||||
|
||||
frameCount++;
|
||||
} // end if frameComplete
|
||||
frameCount++;
|
||||
} // end if frameComplete
|
||||
} else {
|
||||
Debug( 4, "Different stream_index %d", packet.stream_index );
|
||||
Debug( 4, "Different stream_index %d", packet.stream_index );
|
||||
} // end if packet.stream_index == mVideoStreamId
|
||||
#if LIBAVCODEC_VERSION_CHECK(57, 8, 0, 12, 100)
|
||||
av_packet_unref( &packet);
|
||||
|
@ -399,20 +399,20 @@ int FfmpegCamera::OpenFfmpeg() {
|
|||
if(mRawFrame == NULL || mFrame == NULL)
|
||||
Fatal( "Unable to allocate frame for %s", mPath.c_str() );
|
||||
|
||||
Debug ( 1, "Allocated frames" );
|
||||
|
||||
Debug ( 1, "Allocated frames" );
|
||||
|
||||
#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0)
|
||||
int pSize = av_image_get_buffer_size( imagePixFormat, width, height,1 );
|
||||
int pSize = av_image_get_buffer_size( imagePixFormat, width, height,1 );
|
||||
#else
|
||||
int pSize = avpicture_get_size( imagePixFormat, width, height );
|
||||
int pSize = avpicture_get_size( imagePixFormat, width, height );
|
||||
#endif
|
||||
|
||||
if( (unsigned int)pSize != imagesize) {
|
||||
Fatal("Image size mismatch. Required: %d Available: %d",pSize,imagesize);
|
||||
}
|
||||
|
||||
Debug ( 1, "Validated imagesize %d", pSize );
|
||||
if( (unsigned int)pSize != imagesize) {
|
||||
Fatal("Image size mismatch. Required: %d Available: %d",pSize,imagesize);
|
||||
}
|
||||
|
||||
Debug ( 1, "Validated imagesize" );
|
||||
|
||||
#if HAVE_LIBSWSCALE
|
||||
Debug ( 1, "Calling sws_isSupportedInput" );
|
||||
if(!sws_isSupportedInput(mCodecContext->pix_fmt)) {
|
||||
|
|
File diff suppressed because it is too large
Load Diff
138
src/zm_mpeg.cpp
138
src/zm_mpeg.cpp
|
@ -328,82 +328,82 @@ void VideoStream::OpenStream( )
|
|||
#else
|
||||
opicture = avcodec_alloc_frame( );
|
||||
#endif
|
||||
if ( !opicture )
|
||||
{
|
||||
Panic( "Could not allocate opicture" );
|
||||
}
|
||||
|
||||
if ( !opicture )
|
||||
{
|
||||
Panic( "Could not allocate opicture" );
|
||||
}
|
||||
|
||||
#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0)
|
||||
int size = av_image_get_buffer_size( c->pix_fmt, c->width,
|
||||
c->height, 1 );
|
||||
int size = av_image_get_buffer_size( c->pix_fmt, c->width,
|
||||
c->height, 1 );
|
||||
#else
|
||||
int size = avpicture_get_size( c->pix_fmt, c->width, c->height );
|
||||
int size = avpicture_get_size( c->pix_fmt, c->width, c->height );
|
||||
#endif
|
||||
|
||||
uint8_t *opicture_buf = (uint8_t *)av_malloc( size );
|
||||
if ( !opicture_buf )
|
||||
{
|
||||
uint8_t *opicture_buf = (uint8_t *)av_malloc( size );
|
||||
if ( !opicture_buf )
|
||||
{
|
||||
#if LIBAVCODEC_VERSION_CHECK(55, 28, 1, 45, 101)
|
||||
av_frame_free( &opicture );
|
||||
#else
|
||||
av_freep( &opicture );
|
||||
#endif
|
||||
Panic( "Could not allocate opicture_buf" );
|
||||
}
|
||||
Panic( "Could not allocate opicture_buf" );
|
||||
}
|
||||
#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0)
|
||||
av_image_fill_arrays(opicture->data, opicture->linesize,
|
||||
opicture_buf, c->pix_fmt, c->width, c->height, 1);
|
||||
av_image_fill_arrays(opicture->data, opicture->linesize,
|
||||
opicture_buf, c->pix_fmt, c->width, c->height, 1);
|
||||
#else
|
||||
avpicture_fill( (AVPicture *)opicture, opicture_buf, c->pix_fmt,
|
||||
c->width, c->height );
|
||||
avpicture_fill( (AVPicture *)opicture, opicture_buf, c->pix_fmt,
|
||||
c->width, c->height );
|
||||
#endif
|
||||
|
||||
/* if the output format is not identical to the input format, then a temporary
|
||||
picture is needed too. It is then converted to the required
|
||||
output format */
|
||||
tmp_opicture = NULL;
|
||||
if ( c->pix_fmt != pf )
|
||||
{
|
||||
/* if the output format is not identical to the input format, then a temporary
|
||||
picture is needed too. It is then converted to the required
|
||||
output format */
|
||||
tmp_opicture = NULL;
|
||||
if ( c->pix_fmt != pf )
|
||||
{
|
||||
#if LIBAVCODEC_VERSION_CHECK(55, 28, 1, 45, 101)
|
||||
tmp_opicture = av_frame_alloc( );
|
||||
#else
|
||||
tmp_opicture = avcodec_alloc_frame( );
|
||||
#endif
|
||||
if ( !tmp_opicture )
|
||||
{
|
||||
Panic( "Could not allocate tmp_opicture" );
|
||||
}
|
||||
if ( !tmp_opicture )
|
||||
{
|
||||
Panic( "Could not allocate tmp_opicture" );
|
||||
}
|
||||
#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0)
|
||||
int size = av_image_get_buffer_size( pf, c->width,
|
||||
c->height,1 );
|
||||
int size = av_image_get_buffer_size( pf, c->width,
|
||||
c->height,1 );
|
||||
#else
|
||||
int size = avpicture_get_size( pf, c->width, c->height );
|
||||
int size = avpicture_get_size( pf, c->width, c->height );
|
||||
#endif
|
||||
uint8_t *tmp_opicture_buf = (uint8_t *)av_malloc( size );
|
||||
if ( !tmp_opicture_buf )
|
||||
{
|
||||
uint8_t *tmp_opicture_buf = (uint8_t *)av_malloc( size );
|
||||
if ( !tmp_opicture_buf )
|
||||
{
|
||||
#if LIBAVCODEC_VERSION_CHECK(55, 28, 1, 45, 101)
|
||||
av_frame_free( &tmp_opicture );
|
||||
av_frame_free( &tmp_opicture );
|
||||
#else
|
||||
av_freep( &tmp_opicture );
|
||||
av_freep( &tmp_opicture );
|
||||
#endif
|
||||
Panic( "Could not allocate tmp_opicture_buf" );
|
||||
}
|
||||
Panic( "Could not allocate tmp_opicture_buf" );
|
||||
}
|
||||
#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0)
|
||||
av_image_fill_arrays(tmp_opicture->data,
|
||||
tmp_opicture->linesize, tmp_opicture_buf, pf,
|
||||
c->width, c->height, 1);
|
||||
av_image_fill_arrays(tmp_opicture->data,
|
||||
tmp_opicture->linesize, tmp_opicture_buf, pf,
|
||||
c->width, c->height, 1);
|
||||
#else
|
||||
avpicture_fill( (AVPicture *)tmp_opicture,
|
||||
tmp_opicture_buf, pf, c->width, c->height );
|
||||
avpicture_fill( (AVPicture *)tmp_opicture,
|
||||
tmp_opicture_buf, pf, c->width, c->height );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* open the output file, if needed */
|
||||
if ( !(of->flags & AVFMT_NOFILE) )
|
||||
{
|
||||
int ret;
|
||||
/* open the output file, if needed */
|
||||
if ( !(of->flags & AVFMT_NOFILE) )
|
||||
{
|
||||
int ret;
|
||||
#if LIBAVFORMAT_VERSION_CHECK(53, 15, 0, 21, 0)
|
||||
ret = avio_open2( &ofc->pb, filename, AVIO_FLAG_WRITE, NULL, NULL );
|
||||
#elif LIBAVFORMAT_VERSION_CHECK(52, 102, 0, 102, 0)
|
||||
|
@ -700,31 +700,31 @@ double VideoStream::ActuallyEncodeFrame( const uint8_t *buffer, int buffer_size,
|
|||
pkt->data = got_packet ? video_outbuf : NULL;
|
||||
pkt->size = got_packet ? out_size : 0;
|
||||
#endif
|
||||
if ( got_packet )
|
||||
{
|
||||
// if ( c->coded_frame->key_frame )
|
||||
// {
|
||||
if ( got_packet )
|
||||
{
|
||||
// if ( c->coded_frame->key_frame )
|
||||
// {
|
||||
//#if LIBAVCODEC_VERSION_CHECK(52, 30, 2, 30, 2)
|
||||
// pkt->flags |= AV_PKT_FLAG_KEY;
|
||||
// pkt->flags |= AV_PKT_FLAG_KEY;
|
||||
//#else
|
||||
// pkt->flags |= PKT_FLAG_KEY;
|
||||
// pkt->flags |= PKT_FLAG_KEY;
|
||||
//#endif
|
||||
// }
|
||||
// }
|
||||
|
||||
if ( pkt->pts != (int64_t)AV_NOPTS_VALUE )
|
||||
{
|
||||
pkt->pts = av_rescale_q( pkt->pts, c->time_base, ost->time_base );
|
||||
}
|
||||
if ( pkt->dts != (int64_t)AV_NOPTS_VALUE )
|
||||
{
|
||||
pkt->dts = av_rescale_q( pkt->dts, c->time_base, ost->time_base );
|
||||
}
|
||||
pkt->duration = av_rescale_q( pkt->duration, c->time_base, ost->time_base );
|
||||
pkt->stream_index = ost->index;
|
||||
}
|
||||
}
|
||||
|
||||
return ( opicture_ptr->pts);
|
||||
if ( pkt->pts != (int64_t)AV_NOPTS_VALUE )
|
||||
{
|
||||
pkt->pts = av_rescale_q( pkt->pts, c->time_base, ost->time_base );
|
||||
}
|
||||
if ( pkt->dts != (int64_t)AV_NOPTS_VALUE )
|
||||
{
|
||||
pkt->dts = av_rescale_q( pkt->dts, c->time_base, ost->time_base );
|
||||
}
|
||||
pkt->duration = av_rescale_q( pkt->duration, c->time_base, ost->time_base );
|
||||
pkt->stream_index = ost->index;
|
||||
}
|
||||
}
|
||||
|
||||
return ( opicture_ptr->pts);
|
||||
}
|
||||
|
||||
int VideoStream::SendPacket(AVPacket *packet) {
|
||||
|
|
|
@ -238,19 +238,19 @@ int RemoteCameraRtsp::PrimeCapture()
|
|||
mFrame = avcodec_alloc_frame();
|
||||
#endif
|
||||
|
||||
if(mRawFrame == NULL || mFrame == NULL)
|
||||
Fatal( "Unable to allocate frame(s)");
|
||||
|
||||
if(mRawFrame == NULL || mFrame == NULL)
|
||||
Fatal( "Unable to allocate frame(s)");
|
||||
|
||||
#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0)
|
||||
int pSize = av_image_get_buffer_size( imagePixFormat, width, height, 1 );
|
||||
int pSize = av_image_get_buffer_size( imagePixFormat, width, height, 1 );
|
||||
#else
|
||||
int pSize = avpicture_get_size( imagePixFormat, width, height );
|
||||
int pSize = avpicture_get_size( imagePixFormat, width, height );
|
||||
#endif
|
||||
|
||||
if( (unsigned int)pSize != imagesize) {
|
||||
Fatal("Image size mismatch. Required: %d Available: %d",pSize,imagesize);
|
||||
}
|
||||
/*
|
||||
/*
|
||||
#if HAVE_LIBSWSCALE
|
||||
if(!sws_isSupportedInput(mCodecContext->pix_fmt)) {
|
||||
Fatal("swscale does not support the codec format: %c%c%c%c",(mCodecContext->pix_fmt)&0xff,((mCodecContext->pix_fmt>>8)&0xff),((mCodecContext->pix_fmt>>16)&0xff),((mCodecContext->pix_fmt>>24)&0xff));
|
||||
|
@ -488,11 +488,11 @@ int RemoteCameraRtsp::CaptureAndRecord( Image &image, bool recording, char* even
|
|||
Debug( 3, "Got frame %d", frameCount );
|
||||
|
||||
#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0)
|
||||
av_image_fill_arrays(mFrame->data, mFrame->linesize,
|
||||
directbuffer, imagePixFormat, width, height, 1);
|
||||
av_image_fill_arrays(mFrame->data, mFrame->linesize,
|
||||
directbuffer, imagePixFormat, width, height, 1);
|
||||
#else
|
||||
avpicture_fill( (AVPicture *)mFrame, directbuffer,
|
||||
imagePixFormat, width, height);
|
||||
avpicture_fill( (AVPicture *)mFrame, directbuffer,
|
||||
imagePixFormat, width, height);
|
||||
#endif
|
||||
|
||||
//Video recording
|
||||
|
|
|
@ -279,20 +279,17 @@ int RtpCtrlThread::run()
|
|||
UdpInetSocket rtpCtrlServer;
|
||||
if ( mRtpSource.getLocalHost() != "" )
|
||||
{
|
||||
localAddr.resolve( mRtpSource.getLocalHost().c_str(), mRtpSource.getLocalCtrlPort(), "udp" );
|
||||
if ( !rtpCtrlServer.bind( localAddr ) )
|
||||
if ( !rtpCtrlServer.bind( mRtpSource.getLocalHost().c_str(), mRtpSource.getLocalCtrlPort() ) )
|
||||
Fatal( "Failed to bind RTCP server" );
|
||||
sendReports = false;
|
||||
Debug( 3, "Bound to %s:%d", mRtpSource.getLocalHost().c_str(), mRtpSource.getLocalCtrlPort() );
|
||||
}
|
||||
else
|
||||
{
|
||||
localAddr.resolve( mRtpSource.getLocalCtrlPort(), "udp" );
|
||||
if ( !rtpCtrlServer.bind( localAddr ) )
|
||||
if ( !rtpCtrlServer.bind( mRtspThread.getAddressFamily() == AF_INET6 ? "::" : "0.0.0.0", mRtpSource.getLocalCtrlPort() ) )
|
||||
Fatal( "Failed to bind RTCP server" );
|
||||
Debug( 3, "Bound to %s:%d", mRtpSource.getLocalHost().c_str(), mRtpSource.getLocalCtrlPort() );
|
||||
remoteAddr.resolve( mRtpSource.getRemoteHost().c_str(), mRtpSource.getRemoteCtrlPort(), "udp" );
|
||||
if ( !rtpCtrlServer.connect( remoteAddr ) )
|
||||
if ( !rtpCtrlServer.connect( mRtpSource.getRemoteHost().c_str(), mRtpSource.getRemoteCtrlPort() ) )
|
||||
Fatal( "Failed to connect RTCP server" );
|
||||
Debug( 3, "Connected to %s:%d", mRtpSource.getRemoteHost().c_str(), mRtpSource.getRemoteCtrlPort() );
|
||||
sendReports = true;
|
||||
|
|
|
@ -67,13 +67,17 @@ int RtpDataThread::run()
|
|||
|
||||
SockAddrInet localAddr;
|
||||
UdpInetServer rtpDataSocket;
|
||||
if ( mRtpSource.getLocalHost() != "" )
|
||||
localAddr.resolve( mRtpSource.getLocalHost().c_str(), mRtpSource.getLocalDataPort(), "udp" );
|
||||
if ( mRtpSource.getLocalHost() != "" ) {
|
||||
if ( !rtpDataSocket.bind( mRtpSource.getLocalHost().c_str(), mRtpSource.getLocalDataPort() ) )
|
||||
Fatal( "Failed to bind RTP server" );
|
||||
Debug( 3, "Bound to %s:%d", mRtpSource.getLocalHost().c_str(), mRtpSource.getLocalDataPort() );
|
||||
}
|
||||
else
|
||||
localAddr.resolve( mRtpSource.getLocalDataPort(), "udp" );
|
||||
if ( !rtpDataSocket.bind( localAddr ) )
|
||||
Fatal( "Failed to bind RTP server" );
|
||||
Debug( 3, "Bound to %s:%d", mRtpSource.getLocalHost().c_str(), mRtpSource.getLocalDataPort() );
|
||||
{
|
||||
if ( !rtpDataSocket.bind( mRtspThread.getAddressFamily() == AF_INET6 ? "::" : "0.0.0.0", mRtpSource.getLocalDataPort() ) )
|
||||
Fatal( "Failed to bind RTP server" );
|
||||
Debug( 3, "Bound to %s:%d", mRtpSource.getLocalHost().c_str(), mRtpSource.getLocalDataPort() );
|
||||
}
|
||||
|
||||
Select select( 3 );
|
||||
select.addReader( &rtpDataSocket );
|
||||
|
|
|
@ -234,7 +234,7 @@ int RtspThread::run()
|
|||
|
||||
response.reserve( ZM_NETWORK_BUFSIZ );
|
||||
|
||||
if ( !mRtspSocket.connect( mHost.c_str(), strtol( mPort.c_str(), NULL, 10 ) ) )
|
||||
if ( !mRtspSocket.connect( mHost.c_str(), mPort.c_str() ) )
|
||||
Fatal( "Unable to connect RTSP socket" );
|
||||
//Select select( 0.25 );
|
||||
//select.addReader( &mRtspSocket );
|
||||
|
@ -248,7 +248,7 @@ int RtspThread::run()
|
|||
bool authTried = false;
|
||||
if ( mMethod == RTP_RTSP_HTTP )
|
||||
{
|
||||
if ( !mRtspSocket2.connect( mHost.c_str(), strtol( mPort.c_str(), NULL, 10 ) ) )
|
||||
if ( !mRtspSocket2.connect( mHost.c_str(), mPort.c_str() ) )
|
||||
Fatal( "Unable to connect auxiliary RTSP/HTTP socket" );
|
||||
//Select select( 0.25 );
|
||||
//select.addReader( &mRtspSocket2 );
|
||||
|
@ -289,13 +289,13 @@ int RtspThread::run()
|
|||
{
|
||||
if ( isalnum(response[0]) )
|
||||
{
|
||||
Error( "Response parse failure in '%s'", response.c_str() );
|
||||
Error( "Response parse failure in '%s'", response.c_str() );
|
||||
}
|
||||
else
|
||||
{
|
||||
Error( "Response parse failure, %zd bytes follow", response.size() );
|
||||
if ( response.size() )
|
||||
Hexdump( Logger::ERROR, response.data(), min(response.size(),16) );
|
||||
Error( "Response parse failure, %zd bytes follow", response.size() );
|
||||
if ( response.size() )
|
||||
Hexdump( Logger::ERROR, response.data(), min(response.size(),16) );
|
||||
}
|
||||
return( -1 );
|
||||
}
|
||||
|
@ -306,7 +306,7 @@ int RtspThread::run()
|
|||
mAuthenticator->checkAuthResponse(response);
|
||||
Debug(2, "Processed 401 response");
|
||||
mRtspSocket.close();
|
||||
if ( !mRtspSocket.connect( mHost.c_str(), strtol( mPort.c_str(), NULL, 10 ) ) )
|
||||
if ( !mRtspSocket.connect( mHost.c_str(), mPort.c_str() ) )
|
||||
Fatal( "Unable to reconnect RTSP socket" );
|
||||
Debug(2, "connection should be reopened now");
|
||||
}
|
||||
|
|
|
@ -138,6 +138,10 @@ public:
|
|||
{
|
||||
return( mStop );
|
||||
}
|
||||
int getAddressFamily ()
|
||||
{
|
||||
return mRtspSocket.getDomain();
|
||||
}
|
||||
};
|
||||
|
||||
#endif // ZM_RTSP_H
|
||||
|
|
|
@ -112,7 +112,7 @@ SessionDescriptor::ConnInfo::ConnInfo( const std::string &connInfo ) :
|
|||
if ( mNetworkType != "IN" )
|
||||
throw Exception( "Invalid SDP network type '"+mNetworkType+"' in connection info '"+connInfo+"'" );
|
||||
mAddressType = tokens[1];
|
||||
if ( mAddressType != "IP4" )
|
||||
if ( mAddressType != "IP4" && mAddressType != "IP6" )
|
||||
throw Exception( "Invalid SDP address type '"+mAddressType+"' in connection info '"+connInfo+"'" );
|
||||
StringVector addressTokens = split( tokens[2], "/" );
|
||||
if ( addressTokens.size() < 1 )
|
||||
|
|
|
@ -321,9 +321,48 @@ void StreamBase::openComms()
|
|||
snprintf( loc_sock_path, sizeof(loc_sock_path), "%s/zms-%06ds.sock", config.path_socks, connkey );
|
||||
unlink( loc_sock_path );
|
||||
|
||||
unsigned int length = snprintf( sock_path_lock, sizeof(sock_path_lock), "%s/zms-%06d.lock", config.path_socks, connkey);
|
||||
if ( length >= sizeof(sock_path_lock) ) {
|
||||
Warning("Socket lock path was truncated.");
|
||||
length = sizeof(sock_path_lock)-1;
|
||||
}
|
||||
|
||||
lock_fd = open(sock_path_lock, O_CREAT|O_WRONLY, S_IRUSR | S_IWUSR);
|
||||
if ( lock_fd <= 0 )
|
||||
{
|
||||
Error("Unable to open sock lock file %s: %s", sock_path_lock, strerror(errno) );
|
||||
lock_fd = 0;
|
||||
}
|
||||
else if ( flock(lock_fd, LOCK_EX) != 0 )
|
||||
{
|
||||
Error("Unable to lock sock lock file %s: %s", sock_path_lock, strerror(errno) );
|
||||
close(lock_fd);
|
||||
lock_fd = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug( 1, "We have obtained a lock on %s fd: %d", sock_path_lock, lock_fd);
|
||||
}
|
||||
|
||||
sd = socket( AF_UNIX, SOCK_DGRAM, 0 );
|
||||
if ( sd < 0 )
|
||||
{
|
||||
Fatal( "Can't create socket: %s", strerror(errno) );
|
||||
}
|
||||
|
||||
length = snprintf( loc_sock_path, sizeof(loc_sock_path), "%s/zms-%06ds.sock", config.path_socks, connkey );
|
||||
if ( length >= sizeof(loc_sock_path) ) {
|
||||
Warning("Socket path was truncated.");
|
||||
length = sizeof(loc_sock_path)-1;
|
||||
}
|
||||
unlink( loc_sock_path );
|
||||
if ( sizeof(loc_addr.sun_path) < length ) {
|
||||
Error("Not enough space %d in loc_addr.sun_path for socket file %s", sizeof(loc_addr.sun_path), loc_sock_path );
|
||||
}
|
||||
|
||||
strncpy( loc_addr.sun_path, loc_sock_path, sizeof(loc_addr.sun_path) );
|
||||
loc_addr.sun_family = AF_UNIX;
|
||||
if ( bind( sd, (struct sockaddr *)&loc_addr, strlen(loc_addr.sun_path)+sizeof(loc_addr.sun_family)) < 0 )
|
||||
if ( bind( sd, (struct sockaddr *)&loc_addr, strlen(loc_addr.sun_path)+sizeof(loc_addr.sun_family))+1 < 0 )
|
||||
{
|
||||
Fatal( "Can't bind: %s", strerror(errno) );
|
||||
}
|
||||
|
@ -331,7 +370,7 @@ void StreamBase::openComms()
|
|||
snprintf( rem_sock_path, sizeof(rem_sock_path), "%s/zms-%06dw.sock", config.path_socks, connkey );
|
||||
strncpy( rem_addr.sun_path, rem_sock_path, sizeof(rem_addr.sun_path) );
|
||||
rem_addr.sun_family = AF_UNIX;
|
||||
}
|
||||
} // end if connKey > 0
|
||||
}
|
||||
|
||||
void StreamBase::closeComms()
|
||||
|
|
|
@ -49,7 +49,7 @@ git submodule update --init --recursive
|
|||
if [ $DISTRO == "trusty" ]; then
|
||||
ln -sf distros/ubuntu1204 debian
|
||||
else
|
||||
ln -sf distros/ubuntu1504 debian
|
||||
ln -sf distros/ubuntu1604 debian
|
||||
fi;
|
||||
|
||||
# Auto-install all ZoneMinder's depedencies using the Debian control file
|
||||
|
|
|
@ -253,11 +253,20 @@ public function beforeFilter() {
|
|||
|
||||
}
|
||||
|
||||
// format expected:
|
||||
// you can changed AlarmFrames to any other named params
|
||||
// consoleEvents/1 hour/AlarmFrames >=: 1/AlarmFrames <=: 20.json
|
||||
|
||||
public function consoleEvents($interval = null) {
|
||||
$this->Event->recursive = -1;
|
||||
$results = array();
|
||||
|
||||
$query = $this->Event->query("select MonitorId, COUNT(*) AS Count from Events WHERE StartTime >= (DATE_SUB(NOW(), interval $interval)) GROUP BY MonitorId;");
|
||||
$moreconditions ="";
|
||||
foreach ($this->request->params['named'] as $name => $param) {
|
||||
$moreconditions = $moreconditions . " AND ".$name.$param;
|
||||
}
|
||||
|
||||
$query = $this->Event->query("select MonitorId, COUNT(*) AS Count from Events WHERE (StartTime >= (DATE_SUB(NOW(), interval $interval)) $moreconditions) GROUP BY MonitorId;");
|
||||
|
||||
foreach ($query as $result) {
|
||||
$results[$result['Events']['MonitorId']] = $result[0]['Count'];
|
||||
|
|
|
@ -138,7 +138,8 @@ public function beforeFilter() {
|
|||
'_serialize' => array('message')
|
||||
));
|
||||
// - restart this monitor after change
|
||||
$this->daemonControl($this->Monitor->id, 'restart', $this->request->data);
|
||||
// We don't pass the request data as the monitor object because it may be a subset of the full monitor array
|
||||
$this->daemonControl( $this->Monitor->id, 'restart' );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -183,6 +184,78 @@ public function beforeFilter() {
|
|||
));
|
||||
}
|
||||
|
||||
// arm/disarm alarms
|
||||
// expected format: http(s):/portal-api-url/monitors/alarm/id:M/command:C.json
|
||||
// where M=monitorId
|
||||
// where C=on|off
|
||||
public function alarm()
|
||||
{
|
||||
$id = $this->request->params['named']['id'];
|
||||
$cmd = strtolower($this->request->params['named']['command']);
|
||||
if (!$this->Monitor->exists($id)) {
|
||||
throw new NotFoundException(__('Invalid monitor'));
|
||||
}
|
||||
if ( $cmd != 'on' && $cmd != 'off')
|
||||
{
|
||||
throw new BadRequestException(__('Invalid command'));
|
||||
}
|
||||
|
||||
if ($this->Session->Read('systemPermission') != 'Edit')
|
||||
{
|
||||
throw new UnauthorizedException(__('Insufficient privileges'));
|
||||
return;
|
||||
}
|
||||
|
||||
$zm_path_bin = Configure::read('ZM_PATH_BIN');
|
||||
$q = ($cmd == 'on') ? '-a':'-c';
|
||||
|
||||
// form auth key based on auth credentials
|
||||
$this->loadModel('Config');
|
||||
$options = array('conditions' => array('Config.' . $this->Config->primaryKey => 'ZM_OPT_USE_AUTH'));
|
||||
$config = $this->Config->find('first', $options);
|
||||
$zmOptAuth = $config['Config']['Value'];
|
||||
|
||||
|
||||
$options = array('conditions' => array('Config.' . $this->Config->primaryKey => 'ZM_AUTH_RELAY'));
|
||||
$config = $this->Config->find('first', $options);
|
||||
$zmAuthRelay = $config['Config']['Value'];
|
||||
|
||||
$auth="";
|
||||
if ($zmOptAuth)
|
||||
{
|
||||
if ($zmAuthRelay == 'hashed')
|
||||
{
|
||||
$options = array('conditions' => array('Config.' . $this->Config->primaryKey => 'ZM_AUTH_HASH_SECRET'));
|
||||
$config = $this->Config->find('first', $options);
|
||||
$zmAuthHashSecret = $config['Config']['Value'];
|
||||
|
||||
$time = localtime();
|
||||
$ak = $zmAuthHashSecret.$this->Session->Read('username').$this->Session->Read('passwordHash').$time[2].$time[3].$time[4].$time[5];
|
||||
$ak = md5($ak);
|
||||
$auth = " -A ".$ak;
|
||||
}
|
||||
elseif ($zmAuthRelay == 'plain')
|
||||
{
|
||||
$auth = " -U " .$this->Session->Read('username')." -P ".$this->Session->Read('password');
|
||||
|
||||
}
|
||||
elseif ($zmAuthRelay == 'none')
|
||||
{
|
||||
$auth = " -U " .$this->Session->Read('username');
|
||||
}
|
||||
}
|
||||
|
||||
$shellcmd = escapeshellcmd("$zm_path_bin/zmu -v -m$id $q $auth");
|
||||
$status = exec ($shellcmd);
|
||||
|
||||
$this->set(array(
|
||||
'status' => $status,
|
||||
'_serialize' => array('status'),
|
||||
));
|
||||
|
||||
|
||||
}
|
||||
|
||||
// Check if a daemon is running for the monitor id
|
||||
public function daemonStatus() {
|
||||
$id = $this->request->params['named']['id'];
|
||||
|
|
|
@ -19,7 +19,7 @@ class ServersController extends AppController {
|
|||
|
||||
public function beforeFilter() {
|
||||
parent::beforeFilter();
|
||||
$canView = $this->Session->Read('systemPermission');
|
||||
$canView = $this->Session->Read('streamPermission');
|
||||
if ($canView =='None') {
|
||||
throw new UnauthorizedException(__('Insufficient Privileges'));
|
||||
return;
|
||||
|
|
|
@ -86,20 +86,15 @@ class Frame {
|
|||
if ( $limit ) {
|
||||
$sql .= ' LIMIT ' . $limit;
|
||||
}
|
||||
Error("sql:$sql ". implode(",", $values));
|
||||
$results = dbFetchAll( $sql, NULL, $values );
|
||||
if ( $results ) {
|
||||
Error("results" . sizeof($results) );
|
||||
return array_map( function($id){ return new Frame($id); }, $results );
|
||||
}
|
||||
Error("No results");
|
||||
|
||||
}
|
||||
|
||||
public static function find_one( $parameters = array() ) {
|
||||
$results = Frame::find( $parameters, 1 );
|
||||
if ( ! sizeof( $results ) ) {
|
||||
Debug("No Frame found");
|
||||
return;
|
||||
}
|
||||
return $results[0];
|
||||
|
|
|
@ -3,114 +3,115 @@ require_once( 'database.php' );
|
|||
require_once( 'Server.php' );
|
||||
|
||||
class Monitor {
|
||||
public function __construct( $IdOrRow ) {
|
||||
$row = NULL;
|
||||
if ( $IdOrRow ) {
|
||||
if ( is_integer( $IdOrRow ) or is_numeric( $IdOrRow ) ) {
|
||||
$row = dbFetchOne( 'SELECT * FROM Monitors WHERE Id=?', NULL, array( $IdOrRow ) );
|
||||
if ( ! $row ) {
|
||||
Error("Unable to load Server record for Id=" . $IdOrRow );
|
||||
}
|
||||
} elseif ( is_array( $IdOrRow ) ) {
|
||||
$row = $IdOrRow;
|
||||
} else {
|
||||
Error("Unknown argument passed to Monitor Constructor ($IdOrRow)");
|
||||
return;
|
||||
}
|
||||
} # end if isset($IdOrRow)
|
||||
|
||||
if ( $row ) {
|
||||
foreach ($row as $k => $v) {
|
||||
$this->{$k} = $v;
|
||||
}
|
||||
if ( $this->{'Controllable'} ) {
|
||||
$s = dbFetchOne( 'SELECT * FROM Controls WHERE Id=?', NULL, array( $this->{'ControlId'} ) );
|
||||
foreach ($s as $k => $v) {
|
||||
if ( $k == 'Id' ) {
|
||||
continue;
|
||||
} else if ( $k == 'Protocol' ) {
|
||||
$this->{'ControlProtocol'} = $v;
|
||||
} else if ( $k == 'Name' ) {
|
||||
$this->{'ControlName'} = $v;
|
||||
} else if ( $k == 'Type' ) {
|
||||
$this->{'ControlType'} = $v;
|
||||
} else {
|
||||
$this->{$k} = $v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
Error("No row for Monitor " . $IdOrRow );
|
||||
}
|
||||
} // end function __construct
|
||||
public function Server() {
|
||||
return new Server( $this->{'ServerId'} );
|
||||
}
|
||||
public function __call( $fn, array $args){
|
||||
if(isset($this->{$fn})){
|
||||
return $this->{$fn};
|
||||
#array_unshift($args, $this);
|
||||
#call_user_func_array( $this->{$fn}, $args);
|
||||
public function __construct( $IdOrRow ) {
|
||||
$row = NULL;
|
||||
if ( $IdOrRow ) {
|
||||
if ( is_integer( $IdOrRow ) or is_numeric( $IdOrRow ) ) {
|
||||
$row = dbFetchOne( 'SELECT * FROM Monitors WHERE Id=?', NULL, array( $IdOrRow ) );
|
||||
if ( ! $row ) {
|
||||
Error("Unable to load Server record for Id=" . $IdOrRow );
|
||||
}
|
||||
} elseif ( is_array( $IdOrRow ) ) {
|
||||
$row = $IdOrRow;
|
||||
} else {
|
||||
Error("Unknown argument passed to Monitor Constructor ($IdOrRow)");
|
||||
return;
|
||||
}
|
||||
} # end if isset($IdOrRow)
|
||||
|
||||
if ( $row ) {
|
||||
foreach ($row as $k => $v) {
|
||||
$this->{$k} = $v;
|
||||
}
|
||||
if ( $this->{'Controllable'} ) {
|
||||
$s = dbFetchOne( 'SELECT * FROM Controls WHERE Id=?', NULL, array( $this->{'ControlId'} ) );
|
||||
foreach ($s as $k => $v) {
|
||||
if ( $k == 'Id' ) {
|
||||
continue;
|
||||
# The reason for these is that the name overlaps Monitor fields.
|
||||
} else if ( $k == 'Protocol' ) {
|
||||
$this->{'ControlProtocol'} = $v;
|
||||
} else if ( $k == 'Name' ) {
|
||||
$this->{'ControlName'} = $v;
|
||||
} else if ( $k == 'Type' ) {
|
||||
$this->{'ControlType'} = $v;
|
||||
} else {
|
||||
$this->{$k} = $v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
Error("No row for Monitor " . $IdOrRow );
|
||||
}
|
||||
} // end function __construct
|
||||
public function Server() {
|
||||
return new Server( $this->{'ServerId'} );
|
||||
}
|
||||
public function __call( $fn, array $args){
|
||||
if ( isset( $this->{$fn} ) ) {
|
||||
return $this->{$fn};
|
||||
#array_unshift($args, $this);
|
||||
#call_user_func_array( $this->{$fn}, $args);
|
||||
}
|
||||
}
|
||||
public function getStreamSrc( $args, $querySep='&' ) {
|
||||
if ( isset($this->{'ServerId'}) and $this->{'ServerId'} ) {
|
||||
$Server = new Server( $this->{'ServerId'} );
|
||||
$streamSrc = ZM_BASE_PROTOCOL.'://'.$Server->Hostname().ZM_PATH_ZMS;
|
||||
} else {
|
||||
$streamSrc = ZM_BASE_URL.ZM_PATH_ZMS;
|
||||
}
|
||||
public function getStreamSrc( $args, $querySep='&' ) {
|
||||
if ( isset($this->{'ServerId'}) and $this->{'ServerId'} ) {
|
||||
$Server = new Server( $this->{'ServerId'} );
|
||||
$streamSrc = ZM_BASE_PROTOCOL.'://'.$Server->Hostname().ZM_PATH_ZMS;
|
||||
} else {
|
||||
$streamSrc = ZM_BASE_URL.ZM_PATH_ZMS;
|
||||
}
|
||||
|
||||
$args[] = "monitor=".$this->{'Id'};
|
||||
$args[] = "monitor=".$this->{'Id'};
|
||||
|
||||
if ( ZM_OPT_USE_AUTH ) {
|
||||
if ( ZM_AUTH_RELAY == "hashed" ) {
|
||||
$args[] = "auth=".generateAuthHash( ZM_AUTH_HASH_IPS );
|
||||
} elseif ( ZM_AUTH_RELAY == "plain" ) {
|
||||
$args[] = "user=".$_SESSION['username'];
|
||||
$args[] = "pass=".$_SESSION['password'];
|
||||
} elseif ( ZM_AUTH_RELAY == "none" ) {
|
||||
$args[] = "user=".$_SESSION['username'];
|
||||
}
|
||||
}
|
||||
if ( !in_array( "mode=single", $args ) && !empty($GLOBALS['connkey']) ) {
|
||||
$args[] = "connkey=".$GLOBALS['connkey'];
|
||||
}
|
||||
if ( ZM_RAND_STREAM ) {
|
||||
$args[] = "rand=".time();
|
||||
}
|
||||
if ( ZM_OPT_USE_AUTH ) {
|
||||
if ( ZM_AUTH_RELAY == "hashed" ) {
|
||||
$args[] = "auth=".generateAuthHash( ZM_AUTH_HASH_IPS );
|
||||
} elseif ( ZM_AUTH_RELAY == "plain" ) {
|
||||
$args[] = "user=".$_SESSION['username'];
|
||||
$args[] = "pass=".$_SESSION['password'];
|
||||
} elseif ( ZM_AUTH_RELAY == "none" ) {
|
||||
$args[] = "user=".$_SESSION['username'];
|
||||
}
|
||||
}
|
||||
if ( !in_array( "mode=single", $args ) && !empty($GLOBALS['connkey']) ) {
|
||||
$args[] = "connkey=".$GLOBALS['connkey'];
|
||||
}
|
||||
if ( ZM_RAND_STREAM ) {
|
||||
$args[] = "rand=".time();
|
||||
}
|
||||
|
||||
if ( count($args) ) {
|
||||
$streamSrc .= "?".join( $querySep, $args );
|
||||
}
|
||||
if ( count($args) ) {
|
||||
$streamSrc .= "?".join( $querySep, $args );
|
||||
}
|
||||
|
||||
return( $streamSrc );
|
||||
} // end function getStreamSrc
|
||||
public function Width() {
|
||||
if ( $this->Orientation() == '90' or $this->Orientation() == '270' ) {
|
||||
return $this->{'Height'};
|
||||
}
|
||||
return $this->{'Width'};
|
||||
}
|
||||
public function Height() {
|
||||
if ( $this->Orientation() == '90' or $this->Orientation() == '270' ) {
|
||||
return $this->{'Width'};
|
||||
}
|
||||
return $this->{'Height'};
|
||||
}
|
||||
public function set( $data ) {
|
||||
foreach ($data as $k => $v) {
|
||||
if ( is_array( $v ) ) {
|
||||
# perhaps should turn into a comma-separated string
|
||||
$this->{$k} = implode(',',$v);
|
||||
} else if ( is_string( $v ) ) {
|
||||
$this->{$k} = trim( $v );
|
||||
} else {
|
||||
Error( "Unknown type of var " . gettype( $v ) );
|
||||
$this->{$k} = $v;
|
||||
}
|
||||
}
|
||||
}
|
||||
return( $streamSrc );
|
||||
} // end function getStreamSrc
|
||||
public function Width() {
|
||||
if ( $this->Orientation() == '90' or $this->Orientation() == '270' ) {
|
||||
return $this->{'Height'};
|
||||
}
|
||||
return $this->{'Width'};
|
||||
}
|
||||
public function Height() {
|
||||
if ( $this->Orientation() == '90' or $this->Orientation() == '270' ) {
|
||||
return $this->{'Width'};
|
||||
}
|
||||
return $this->{'Height'};
|
||||
}
|
||||
public function set( $data ) {
|
||||
foreach ($data as $k => $v) {
|
||||
if ( is_array( $v ) ) {
|
||||
# perhaps should turn into a comma-separated string
|
||||
$this->{$k} = implode(',',$v);
|
||||
} else if ( is_string( $v ) ) {
|
||||
$this->{$k} = trim( $v );
|
||||
} else {
|
||||
Error( "Unknown type of var " . gettype( $v ) );
|
||||
$this->{$k} = $v;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
|
|
@ -1,28 +1,28 @@
|
|||
<?php
|
||||
require_once( 'database.php' );
|
||||
class Server {
|
||||
|
||||
public function __construct( $IdOrRow = NULL ) {
|
||||
$row = NULL;
|
||||
if ( $IdOrRow ) {
|
||||
if ( is_integer( $IdOrRow ) or is_numeric( $IdOrRow ) ) {
|
||||
$row = dbFetchOne( 'SELECT * FROM Servers WHERE Id=?', NULL, array( $IdOrRow ) );
|
||||
if ( ! $row ) {
|
||||
Error("Unable to load Server record for Id=" . $IdOrRow );
|
||||
}
|
||||
} elseif ( is_array( $IdOrRow ) ) {
|
||||
$row = $IdOrRow;
|
||||
}
|
||||
} # end if isset($IdOrRow)
|
||||
if ( $row ) {
|
||||
foreach ($row as $k => $v) {
|
||||
$this->{$k} = $v;
|
||||
}
|
||||
} else {
|
||||
$this->{'Name'} = '';
|
||||
$this->{'Hostname'} = '';
|
||||
}
|
||||
class Server {
|
||||
public function __construct( $IdOrRow = NULL ) {
|
||||
$row = NULL;
|
||||
if ( $IdOrRow ) {
|
||||
if ( is_integer( $IdOrRow ) or is_numeric( $IdOrRow ) ) {
|
||||
$row = dbFetchOne( 'SELECT * FROM Servers WHERE Id=?', NULL, array( $IdOrRow ) );
|
||||
if ( ! $row ) {
|
||||
Error("Unable to load Server record for Id=" . $IdOrRow );
|
||||
}
|
||||
} elseif ( is_array( $IdOrRow ) ) {
|
||||
$row = $IdOrRow;
|
||||
}
|
||||
} # end if isset($IdOrRow)
|
||||
if ( $row ) {
|
||||
foreach ($row as $k => $v) {
|
||||
$this->{$k} = $v;
|
||||
}
|
||||
} else {
|
||||
$this->{'Name'} = '';
|
||||
$this->{'Hostname'} = '';
|
||||
}
|
||||
}
|
||||
public static function find_all() {
|
||||
$servers = array();
|
||||
$result = dbQuery( 'SELECT * FROM Servers ORDER BY Name');
|
||||
|
@ -47,11 +47,38 @@ class Server {
|
|||
return $this->{'Name'};
|
||||
}
|
||||
public function __call( $fn, array $args= NULL){
|
||||
if(isset($this->{$fn})){
|
||||
return $this->{$fn};
|
||||
#array_unshift($args, $this);
|
||||
#call_user_func_array( $this->{$fn}, $args);
|
||||
}
|
||||
if(isset($this->{$fn})){
|
||||
return $this->{$fn};
|
||||
#array_unshift($args, $this);
|
||||
#call_user_func_array( $this->{$fn}, $args);
|
||||
}
|
||||
}
|
||||
public static function find( $parameters = array(), $limit = NULL ) {
|
||||
$sql = 'SELECT * FROM Servers';
|
||||
$values = array();
|
||||
if ( sizeof($parameters) ) {
|
||||
$sql .= ' WHERE ' . implode( ' AND ', array_map(
|
||||
function($v){ return $v.'=?'; },
|
||||
array_keys( $parameters )
|
||||
) );
|
||||
$values = array_values( $parameters );
|
||||
}
|
||||
if ( $limit ) {
|
||||
$sql .= ' LIMIT ' . $limit;
|
||||
}
|
||||
$results = dbFetchAll( $sql, NULL, $values );
|
||||
if ( $results ) {
|
||||
return array_map( function($id){ return new Server($id); }, $results );
|
||||
}
|
||||
}
|
||||
|
||||
public static function find_one( $parameters = array() ) {
|
||||
$results = Server::find( $parameters, 1 );
|
||||
if ( ! sizeof( $results ) ) {
|
||||
return;
|
||||
}
|
||||
return $results[0];
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
||||
|
|
|
@ -755,7 +755,11 @@ function getFormChanges( $values, $newValues, $types=false, $columns=false )
|
|||
{
|
||||
if ( !isset($values[$key]) || ($values[$key] != $value) )
|
||||
{
|
||||
$changes[$key] = "$key = ".dbEscape(trim($value));
|
||||
if ( ! isset($value) || $value == '' ) {
|
||||
$changes[$key] = "$key = NULL";
|
||||
} else {
|
||||
$changes[$key] = "$key = ".dbEscape(trim($value));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -138,6 +138,10 @@ else
|
|||
|
||||
require_once( 'includes/lang.php' );
|
||||
require_once( 'includes/functions.php' );
|
||||
$running = daemonCheck();
|
||||
$states = dbFetchAll( "select * from States" );
|
||||
$status = $running?translate('Running'):translate('Stopped');
|
||||
$run_state = dbFetchOne('select Name from States where IsActive = 1', 'Name' );
|
||||
|
||||
# Add Cross domain access headers
|
||||
CORSHeaders();
|
||||
|
|
|
@ -26,6 +26,7 @@ body {
|
|||
font-size: 18px;
|
||||
color: #333333;
|
||||
font-weight: normal;
|
||||
padding-top: 70px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
|
@ -433,16 +434,12 @@ th.table-th-sort-rev span.table-th-sort-span {
|
|||
}
|
||||
|
||||
.nav.nav-pills.nav-stacked.col-md-2 {
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
.nav.nav-pills.nav-stacked.col-md-2 > li > a {
|
||||
border-top-right-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
|
||||
#options {
|
||||
border-left: 1px solid #337ab7;
|
||||
}
|
||||
|
||||
#options .form-group {
|
||||
|
@ -450,3 +447,46 @@ th.table-th-sort-rev span.table-th-sort-span {
|
|||
border-bottom: 1px solid #e7e7e7;
|
||||
|
||||
}
|
||||
|
||||
.navbar{
|
||||
margin-bottom: 0 !important;
|
||||
border-radius: 0;
|
||||
color: #03A9F4 !important;
|
||||
}
|
||||
|
||||
.navbar-brand {
|
||||
font-weight: bold;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
position: fixed;
|
||||
top: 51px;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 1000;
|
||||
display: block;
|
||||
padding: 20px;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
background-color: #f5f5f5;
|
||||
border-right: 1px solid #eeeeee;
|
||||
}
|
||||
|
||||
.sidebar ul {
|
||||
margin-right: -21px;
|
||||
margin-bottom: 20px;
|
||||
margin-left: -20px;
|
||||
}
|
||||
|
||||
.nav-pills > li > a {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
#options .help-block {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
#options {
|
||||
font-size:90%;
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ body {
|
|||
color: #333333;
|
||||
font-weight: 300;
|
||||
text-align: center;
|
||||
padding-top:81px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
|
@ -491,5 +492,36 @@ input[type=submit]:disabled {
|
|||
background-color: #f2f2f2;
|
||||
}
|
||||
|
||||
.navbar{
|
||||
margin-bottom: 0 !important;
|
||||
border-radius: 0;
|
||||
color: #03A9F4 !important;
|
||||
}
|
||||
|
||||
.navbar-brand {
|
||||
font-weight: bold;
|
||||
font-size: 20px;
|
||||
}
|
||||
.sidebar {
|
||||
position: fixed;
|
||||
top: 81px;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 1000;
|
||||
display: block;
|
||||
padding: 20px;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
background-color: #f5f5f5;
|
||||
border-right: 1px solid #eeeeee;
|
||||
}
|
||||
|
||||
.sidebar ul {
|
||||
margin-right: -21px;
|
||||
margin-bottom: 20px;
|
||||
margin-left: -20px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -254,7 +254,11 @@ function controlPanTilt( $monitor, $cmds )
|
|||
<div class="arrowBtn upBtn<?php echo $hasTilt?'':' invisible' ?>" onclick="controlCmd('<?php echo $cmds['MoveUp'] ?>',event,0,-1)"></div>
|
||||
<div class="arrowBtn upRightBtn<?php echo $hasDiag?'':' invisible' ?>" onclick="controlCmd('<?php echo $cmds['MoveUpRight'] ?>',event,1,-1)"></div>
|
||||
<div class="arrowBtn leftBtn<?php echo $hasPan?'':' invisible' ?>" onclick="controlCmd('<?php echo $cmds['MoveLeft'] ?>',event,1,0)"></div>
|
||||
<?php if ( isset($cmds['Center']) ) { ?>
|
||||
<div class="arrowBtn centerBtn" onclick="controlCmd('<?php echo $cmds['Center'] ?>')"></div>
|
||||
<?php } else { ?>
|
||||
<div class="arrowBtn NocenterBtn"></div>
|
||||
<?php } ?>
|
||||
<div class="arrowBtn rightBtn<?php echo $hasPan?'':' invisible' ?>" onclick="controlCmd('<?php echo $cmds['MoveRight'] ?>',event,1,0)"></div>
|
||||
<div class="arrowBtn downLeftBtn<?php echo $hasDiag?'':' invisible' ?>" onclick="controlCmd('<?php echo $cmds['MoveDownLeft'] ?>',event,-1,1)"></div>
|
||||
<div class="arrowBtn downBtn<?php echo $hasTilt?'':' invisible' ?>" onclick="controlCmd('<?php echo $cmds['MoveDown'] ?>',event,0,1)"></div>
|
||||
|
|
|
@ -18,9 +18,14 @@
|
|||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
//
|
||||
|
||||
|
||||
// Don't load in additional JS to these views
|
||||
$bad_views = array('monitor', 'log');
|
||||
|
||||
function xhtmlHeaders( $file, $title )
|
||||
{
|
||||
global $css;
|
||||
global $css;
|
||||
global $skin;
|
||||
$skinCssFile = getSkinFile( 'css/'.$css.'/skin.css' );
|
||||
$skinCssPhpFile = getSkinFile( 'css/'.$css.'/skin.css.php' );
|
||||
|
||||
|
@ -36,9 +41,12 @@ function xhtmlHeaders( $file, $title )
|
|||
|
||||
extract( $GLOBALS, EXTR_OVERWRITE );
|
||||
?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maxiumum-scale=1.0, user-scalable=no">
|
||||
<title><?php echo ZM_WEB_TITLE_PREFIX ?> - <?php echo validHtmlStr($title) ?></title>
|
||||
<link rel="icon" type="image/ico" href="graphics/favicon.ico"/>
|
||||
<link rel="shortcut icon" href="graphics/favicon.ico"/>
|
||||
|
@ -69,12 +77,23 @@ function xhtmlHeaders( $file, $title )
|
|||
<script type="text/javascript" src="tools/mootools/mootools-core.js"></script>
|
||||
<script type="text/javascript" src="tools/mootools/mootools-more.js"></script>
|
||||
<script type="text/javascript" src="js/mootools.ext.js"></script>
|
||||
<?php if ( !in_array($basename, $bad_views) ) { ?>
|
||||
<script type="text/javascript" src="js/logger.js"></script>
|
||||
<script type="text/javascript" src="js/overlay.js"></script>
|
||||
<script type="text/javascript" src="/skins/<?php echo $skin; ?>/js/jquery-1.11.3.js"></script>
|
||||
<script type="text/javascript" src="/skins/<?php echo $skin; ?>/js/bootstrap.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
<!--
|
||||
<?php include("skins/$skin/views/js/state.js.php")?>
|
||||
//-->
|
||||
//]]>
|
||||
</script>
|
||||
<script type="text/javascript" src="/skins/<?php echo $skin; ?>/views/js/state.js"></script>
|
||||
<?php } ?>
|
||||
<?php if ( $title == 'Login' && (defined('ZM_OPT_USE_GOOG_RECAPTCHA') && ZM_OPT_USE_GOOG_RECAPTCHA) ) { ?>
|
||||
<script src='https://www.google.com/recaptcha/api.js'></script>
|
||||
<?php
|
||||
}
|
||||
<?php }
|
||||
if ( $skinJsPhpFile )
|
||||
{
|
||||
?>
|
||||
|
@ -119,4 +138,123 @@ function xhtmlHeaders( $file, $title )
|
|||
</head>
|
||||
<?php
|
||||
}
|
||||
|
||||
function getNavBarHTML() {
|
||||
|
||||
$group = NULL;
|
||||
if ( ! empty($_COOKIE['zmGroup']) ) {
|
||||
if ( $group = dbFetchOne( 'select * from Groups where Id = ?', NULL, array($_COOKIE['zmGroup'])) )
|
||||
$groupIds = array_flip(explode( ',', $group['MonitorIds'] ));
|
||||
}
|
||||
|
||||
$maxWidth = 0;
|
||||
$maxHeight = 0;
|
||||
# Used to determine if the Cycle button should be made available
|
||||
$cycleCount = 0;
|
||||
$monitors = dbFetchAll( "select * from Monitors order by Sequence asc" );
|
||||
global $displayMonitors;
|
||||
$displayMonitors = array();
|
||||
for ( $i = 0; $i < count($monitors); $i++ ) {
|
||||
if ( !visibleMonitor( $monitors[$i]['Id'] ) ) {
|
||||
continue;
|
||||
}
|
||||
if ( $group && !empty($groupIds) && !array_key_exists( $monitors[$i]['Id'], $groupIds ) ) {
|
||||
continue;
|
||||
}
|
||||
if ( $monitors[$i]['Function'] != 'None' ) {
|
||||
$cycleCount++;
|
||||
$scaleWidth = reScale( $monitors[$i]['Width'], $monitors[$i]['DefaultScale'], ZM_WEB_DEFAULT_SCALE );
|
||||
$scaleHeight = reScale( $monitors[$i]['Height'], $monitors[$i]['DefaultScale'], ZM_WEB_DEFAULT_SCALE );
|
||||
if ( $maxWidth < $scaleWidth ) $maxWidth = $scaleWidth;
|
||||
if ( $maxHeight < $scaleHeight ) $maxHeight = $scaleHeight;
|
||||
}
|
||||
$displayMonitors[] = $monitors[$i];
|
||||
}
|
||||
|
||||
$cycleWidth = $maxWidth;
|
||||
$cycleHeight = $maxHeight;
|
||||
|
||||
|
||||
$versionClass = (ZM_DYN_DB_VERSION&&(ZM_DYN_DB_VERSION!=ZM_VERSION))?'errorText':'';
|
||||
|
||||
ob_start();
|
||||
global $CLANG;
|
||||
global $VLANG;
|
||||
global $CLANG;
|
||||
global $VLANG;
|
||||
global $status;
|
||||
global $running;
|
||||
global $user;
|
||||
global $bwArray;
|
||||
?>
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="container-fluid">
|
||||
<div class="navbar-header">
|
||||
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#main-header-nav" aria-expanded="false">
|
||||
<span class="sr-only">Toggle navigation</span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<a class="navbar-brand" href="http://www.zoneminder.com" target="ZoneMinder">ZoneMinder</a>
|
||||
</div>
|
||||
|
||||
<div class="collapse navbar-collapse" id="main-header-nav">
|
||||
<ul class="nav navbar-nav">
|
||||
<li><a href="?view=console"><?php echo translate('Console') ?></a></li>
|
||||
<?php if ( canView( 'System' ) ) { ?>
|
||||
<li><a href="?view=options"><?php echo translate('Options') ?></a></li>
|
||||
<li><?php if ( logToDatabase() > Logger::NOLOG ) { ?> <?php echo makePopupLink( '?view=log', 'zmLog', 'log', '<span class="'.logState().'">'.translate('Log').'</span>' ) ?><?php } ?></li>
|
||||
<?php } ?>
|
||||
<?php if ( ZM_OPT_X10 && canView( 'Devices' ) ) { ?>
|
||||
<li><a href="/?view=devices">Devices</a></li>
|
||||
<?php } ?>
|
||||
<li><?php echo makePopupLink( '?view=groups', 'zmGroups', 'groups', sprintf( $CLANG['MonitorCount'], count($displayMonitors), zmVlang( $VLANG['Monitor'], count($displayMonitors) ) ).($group?' ('.$group['Name'].')':''), canView( 'Groups' ) ); ?></li>
|
||||
<li><?php echo makePopupLink( '?view=filter&filter[terms][0][attr]=DateTime&filter[terms][0][op]=%3c&filter[terms][0][val]=now', 'zmFilter', 'filter', translate('Filters'), canView( 'Events' ) ) ?></li>
|
||||
|
||||
<?php if ( canView( 'Stream' ) && $cycleCount > 1 ) {
|
||||
$cycleGroup = isset($_COOKIE['zmGroup'])?$_COOKIE['zmGroup']:0;
|
||||
?>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Montage <span class="caret"></span></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><?php echo makePopupLink( '?view=cycle&group='.$cycleGroup, 'zmCycle'.$cycleGroup, array( 'cycle', $cycleWidth, $cycleHeight ), translate('Cycle'), $running ) ?></li>
|
||||
<li><?php echo makePopupLink( '?view=montage&group='.$cycleGroup, 'zmMontage'.$cycleGroup, 'montage', translate('Montage'), $running ) ?></li>
|
||||
<li><?php echo makePopupLink( '?view=montagereview&group='.$cycleGroup, 'zmMontage'.$cycleGroup, 'montagereview', translate('Montage Review'), $running ) ?></li>
|
||||
</ul>
|
||||
</li>
|
||||
<?php } ?>
|
||||
</ul>
|
||||
|
||||
<div class="navbar-right">
|
||||
<?php if ( ZM_OPT_USE_AUTH ) { ?>
|
||||
<p class="navbar-text"><?php echo translate('LoggedInAs') ?> <?php echo makePopupLink( '?view=logout', 'zmLogout', 'logout', $user['Username'], (ZM_AUTH_TYPE == "builtin") ) ?> </p>
|
||||
<?php } ?>
|
||||
|
||||
<?php if ( canEdit( 'System' ) ) { ?>
|
||||
<button type="button" class="btn btn-default navbar-btn" data-toggle="modal" data-target="#modalState"><?php echo $status ?></button>
|
||||
|
||||
<?php } else if ( canView( 'System' ) ) { ?>
|
||||
<p class="navbar-text"> <?php echo $status ?> </p>
|
||||
<?php } ?>
|
||||
</div>
|
||||
</div><!-- End .navbar-collapse -->
|
||||
</div> <!-- End .container-fluid -->
|
||||
<div class="container-fluid">
|
||||
<div class="pull-left">
|
||||
<?php echo makePopupLink( '?view=bandwidth', 'zmBandwidth', 'bandwidth', $bwArray[$_COOKIE['zmBandwidth']], ($user && $user['MaxBandwidth'] != 'low' ) ) ?> <?php echo translate('BandwidthHead') ?>
|
||||
</div>
|
||||
<div class="pull-right">
|
||||
<?php echo makePopupLink( '?view=version', 'zmVersion', 'version', '<span class="'.$versionClass.'">v'.ZM_VERSION.'</span>', canEdit( 'System' ) ) ?>
|
||||
</div>
|
||||
<ul class="list-inline">
|
||||
<li><?php echo translate('Load') ?>: <?php echo getLoad() ?></li>
|
||||
<li><?php echo translate('Disk') ?>: <?php echo getDiskPercent() ?>%</li>
|
||||
</ul>
|
||||
</div> <!-- End .footer -->
|
||||
|
||||
</div> <!-- End .navbar .navbar-default -->
|
||||
<?php
|
||||
return( ob_get_clean() );
|
||||
}
|
||||
?>
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,10 +1,119 @@
|
|||
<?php
|
||||
require_once('includes/Server.php');
|
||||
//
|
||||
// ZoneMinder web console file, $Date$, $Revision$
|
||||
// Copyright (C) 2001-2008 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.
|
||||
//
|
||||
|
||||
$servers = Server::find_all();
|
||||
require_once('includes/Storage.php');
|
||||
$storage_areas = Storage::find_all();
|
||||
$show_storage_areas = count($storage_areas) > 1 and canEdit( 'System' ) ? 1 : 0;
|
||||
|
||||
$eventCounts = array(
|
||||
array(
|
||||
"title" => translate('Events'),
|
||||
"filter" => array(
|
||||
"terms" => array(
|
||||
)
|
||||
),
|
||||
"total" => 0,
|
||||
),
|
||||
array(
|
||||
"title" => translate('Hour'),
|
||||
"filter" => array(
|
||||
"terms" => array(
|
||||
array( "attr" => "DateTime", "op" => ">=", "val" => "-1 hour" ),
|
||||
)
|
||||
),
|
||||
"total" => 0,
|
||||
),
|
||||
array(
|
||||
"title" => translate('Day'),
|
||||
"filter" => array(
|
||||
"terms" => array(
|
||||
array( "attr" => "DateTime", "op" => ">=", "val" => "-1 day" ),
|
||||
)
|
||||
),
|
||||
"total" => 0,
|
||||
),
|
||||
array(
|
||||
"title" => translate('Week'),
|
||||
"filter" => array(
|
||||
"terms" => array(
|
||||
array( "attr" => "DateTime", "op" => ">=", "val" => "-7 day" ),
|
||||
)
|
||||
),
|
||||
"total" => 0,
|
||||
),
|
||||
array(
|
||||
"title" => translate('Month'),
|
||||
"filter" => array(
|
||||
"terms" => array(
|
||||
array( "attr" => "DateTime", "op" => ">=", "val" => "-1 month" ),
|
||||
)
|
||||
),
|
||||
"total" => 0,
|
||||
),
|
||||
array(
|
||||
"title" => translate('Archived'),
|
||||
"filter" => array(
|
||||
"terms" => array(
|
||||
array( "attr" => "Archived", "op" => "=", "val" => "1" ),
|
||||
)
|
||||
),
|
||||
"total" => 0,
|
||||
),
|
||||
);
|
||||
|
||||
$displayMonitors = NULL;
|
||||
|
||||
# Also populates displayMonitors
|
||||
$navbar = getNavBarHTML();
|
||||
$zoneCount = 0;
|
||||
|
||||
for( $i = 0; $i < count($displayMonitors); $i += 1 ) {
|
||||
$monitor = $displayMonitors[$i];
|
||||
$monitor['zmc'] = zmcStatus( $monitor );
|
||||
$monitor['zma'] = zmaStatus( $monitor );
|
||||
$monitor['ZoneCount'] = dbFetchOne( 'select count(Id) as ZoneCount from Zones where MonitorId = ?', 'ZoneCount', array($monitor['Id']) );
|
||||
$counts = array();
|
||||
for ( $j = 0; $j < count($eventCounts); $j += 1 ) {
|
||||
$filter = addFilterTerm( $eventCounts[$j]['filter'], count($eventCounts[$j]['filter']['terms']), array( "cnj" => "and", "attr" => "MonitorId", "op" => "=", "val" => $monitor['Id'] ) );
|
||||
parseFilter( $filter );
|
||||
$counts[] = "count(if(1".$filter['sql'].",1,NULL)) as EventCount$j";
|
||||
$monitor['eventCounts'][$j]['filter'] = $filter;
|
||||
}
|
||||
$sql = "select ".join($counts,", ")." from Events as E where MonitorId = ?";
|
||||
$counts = dbFetchOne( $sql, NULL, array($monitor['Id']) );
|
||||
if ( $counts )
|
||||
$displayMonitors[$i] = $monitor = array_merge( $monitor, $counts );
|
||||
for ( $j = 0; $j < count($eventCounts); $j += 1 ) {
|
||||
$eventCounts[$j]['total'] += $monitor['EventCount'.$j];
|
||||
}
|
||||
$zoneCount += $monitor['ZoneCount'];
|
||||
}
|
||||
|
||||
noCacheHeaders();
|
||||
|
||||
$seqUpFile = getSkinFile( 'graphics/seq-u.gif' );
|
||||
$seqDownFile = getSkinFile( 'graphics/seq-d.gif' );
|
||||
$eventsView = ZM_WEB_EVENTS_VIEW;
|
||||
$eventsWindow = 'zm'.ucfirst(ZM_WEB_EVENTS_VIEW);
|
||||
|
||||
xhtmlHeaders( __FILE__, translate('Console') );
|
||||
?>
|
||||
<body>
|
||||
|
@ -12,10 +121,10 @@ xhtmlHeaders( __FILE__, translate('Console') );
|
|||
<input type="hidden" name="view" value="<?php echo $view ?>"/>
|
||||
<input type="hidden" name="action" value=""/>
|
||||
|
||||
<?php include("skins/$skin/views/header.php") ?>
|
||||
<?php echo $navbar ?>
|
||||
|
||||
<div class="container-fluid">
|
||||
<table id="consoleTable" cellspacing="0">
|
||||
<table class="table table-striped table-hover table-condensed">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="colName"><?php echo translate('Name') ?></th>
|
||||
|
@ -54,9 +163,10 @@ if ( canEdit('Monitors') )
|
|||
if ( $show_storage_areas ) { $columns += 1; }
|
||||
echo $columns;
|
||||
?>">
|
||||
<input type="button" name="addBtn" value="<?php echo translate('AddNewMonitor') ?>" onclick="addMonitor( this )"/>
|
||||
<input type="button" value="<?php echo translate('Refresh') ?>" onclick="location.reload(true);"/>
|
||||
<input type="button" class="btn btn-primary" name="addBtn" value="<?php echo translate('AddNewMonitor') ?>" onclick="addMonitor( this )"/>
|
||||
<!-- <?php echo makePopupButton( '?view=monitor', 'zmMonitor0', 'monitor', translate('AddNewMonitor'), (canEdit( 'Monitors' ) && !$user['MonitorIds']) ) ?> -->
|
||||
|
||||
<?php echo makePopupButton( '?view=filter&filter[terms][0][attr]=DateTime&filter[terms][0][op]=%3c&filter[terms][0][val]=now', 'zmFilter', 'filter', translate('Filters'), canView( 'Events' ) ) ?>
|
||||
</td>
|
||||
<?php
|
||||
for ( $i = 0; $i < count($eventCounts); $i++ )
|
||||
|
@ -68,13 +178,14 @@ for ( $i = 0; $i < count($eventCounts); $i++ )
|
|||
}
|
||||
?>
|
||||
<td class="colZones"><?php echo $zoneCount ?></td>
|
||||
<td class="colRightButtons" colspan="<?php echo canEdit('Monitors')?2:1 ?>"><input class="btn btn-default" type="button" name="editBtn" value="<?php echo translate('Edit') ?>" onclick="editMonitor( this )" disabled="disabled"/><input class="btn btn-default" type="button" name="deleteBtn" value="<?php echo translate('Delete') ?>" onclick="deleteMonitor( this )" disabled="disabled"/></td>
|
||||
<td><input class="btn btn-primary" type="button" name="editBtn" value="<?php echo translate('Edit') ?>" onclick="editMonitor( this )" disabled="disabled"/></td>
|
||||
<td><input class="btn btn-danger" type="button" name="deleteBtn" value="<?php echo translate('Delete') ?>" onclick="deleteMonitor( this )" disabled="disabled"/></td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
<tbody>
|
||||
<?php
|
||||
foreach( $displayMonitors as $monitor )
|
||||
{
|
||||
for( $monitor_i = 0; $monitor_i < count($displayMonitors); $monitor_i += 1 ) {
|
||||
$monitor = $displayMonitors[$monitor_i];
|
||||
?>
|
||||
<tr title="<?php echo $monitor['Id'] ?>">
|
||||
<?php
|
||||
|
@ -144,35 +255,34 @@ echo $Storage->Name();
|
|||
if ( canEdit('Monitors') )
|
||||
{
|
||||
?>
|
||||
<td class="colOrder"><?php echo makeLink( '?view='.$view.'&action=sequence&mid='.$monitor['Id'].'&smid='.$seqIdUpList[$monitor['Id']], '<img src="'.$seqUpFile.'" alt="Up"/>', $monitor['Sequence']>$minSequence ) ?><?php echo makeLink( '?view='.$view.'&action=sequence&mid='.$monitor['Id'].'&smid='.$seqIdDownList[$monitor['Id']], '<img src="'.$seqDownFile.'" alt="Down"/>', $monitor['Sequence']<$maxSequence ) ?></td>
|
||||
<td class="colOrder">
|
||||
<?php
|
||||
if ( $monitor_i ) {
|
||||
echo makeLink( '?view='.$view.'&action=sequence&mid='.$monitor['Id'].'&smid='.$displayMonitors[$monitor_i-1]['Id'], '<img src="'.$seqUpFile.'" alt="Up"/>' );
|
||||
} else {
|
||||
echo '<img src="'.$seqUpFile.'" alt="Up"/>';
|
||||
}
|
||||
if ( $monitor_i<count($displayMonitors)-1 ) {
|
||||
echo makeLink( '?view='.$view.'&action=sequence&mid='.$monitor['Id'].'&smid='.$displayMonitors[$monitor_i+1]['Id'], '<img src="'.$seqDownFile.'" alt="Down"/>' );
|
||||
} else {
|
||||
echo '<img src="'.$seqDownFile.'" alt="Down"/>';
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
<td class="colMark"><input type="checkbox" name="markMids[]" value="<?php echo $monitor['Id'] ?>" onclick="setButtonStates( this )"<?php if ( !canEdit( 'Monitors' ) ) { ?> disabled="disabled"<?php } ?>/></td>
|
||||
</tr>
|
||||
<?php
|
||||
}
|
||||
} # end for eacho monitor
|
||||
?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div id="footer">
|
||||
|
||||
|
||||
<div class="pull-left">
|
||||
<?php echo makePopupLink( '?view=bandwidth', 'zmBandwidth', 'bandwidth', $bwArray[$_COOKIE['zmBandwidth']], ($user && $user['MaxBandwidth'] != 'low' ) ) ?> <?php echo translate('BandwidthHead') ?>
|
||||
</div>
|
||||
|
||||
<div class="pull-right">
|
||||
<?php echo makePopupLink( '?view=version', 'zmVersion', 'version', '<span class="'.$versionClass.'">v'.ZM_VERSION.'</span>', canEdit( 'System' ) ) ?>
|
||||
</div>
|
||||
<ul class="list-inline">
|
||||
<li><?php echo translate('Load') ?>: <?php echo getLoad() ?></li>
|
||||
<li><?php echo translate('Disk') ?>: <?php echo getDiskPercent() ?>%</li>
|
||||
</ul>
|
||||
</div> <!-- End .footer -->
|
||||
|
||||
</form>
|
||||
<?php include("skins/$skin/views/state.php") ?>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,228 +0,0 @@
|
|||
<?php
|
||||
//
|
||||
// ZoneMinder web console file, $Date$, $Revision$
|
||||
// Copyright (C) 2001-2008 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.
|
||||
//
|
||||
|
||||
require_once('includes/Server.php');
|
||||
$servers = Server::find_all();
|
||||
|
||||
$eventCounts = array(
|
||||
array(
|
||||
"title" => translate('Events'),
|
||||
"filter" => array(
|
||||
"terms" => array(
|
||||
)
|
||||
),
|
||||
),
|
||||
array(
|
||||
"title" => translate('Hour'),
|
||||
"filter" => array(
|
||||
"terms" => array(
|
||||
array( "attr" => "DateTime", "op" => ">=", "val" => "-1 hour" ),
|
||||
)
|
||||
),
|
||||
),
|
||||
array(
|
||||
"title" => translate('Day'),
|
||||
"filter" => array(
|
||||
"terms" => array(
|
||||
array( "attr" => "DateTime", "op" => ">=", "val" => "-1 day" ),
|
||||
)
|
||||
),
|
||||
),
|
||||
array(
|
||||
"title" => translate('Week'),
|
||||
"filter" => array(
|
||||
"terms" => array(
|
||||
array( "attr" => "DateTime", "op" => ">=", "val" => "-7 day" ),
|
||||
)
|
||||
),
|
||||
),
|
||||
array(
|
||||
"title" => translate('Month'),
|
||||
"filter" => array(
|
||||
"terms" => array(
|
||||
array( "attr" => "DateTime", "op" => ">=", "val" => "-1 month" ),
|
||||
)
|
||||
),
|
||||
),
|
||||
array(
|
||||
"title" => translate('Archived'),
|
||||
"filter" => array(
|
||||
"terms" => array(
|
||||
array( "attr" => "Archived", "op" => "=", "val" => "1" ),
|
||||
)
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
$running = daemonCheck();
|
||||
$status = $running?translate('Running'):translate('Stopped');
|
||||
$run_state = dbFetchOne('select Name from States where IsActive = 1', 'Name' );
|
||||
|
||||
$group = NULL;
|
||||
if ( ! empty($_COOKIE['zmGroup']) ) {
|
||||
if ( $group = dbFetchOne( 'select * from Groups where Id = ?', NULL, array($_COOKIE['zmGroup'])) )
|
||||
$groupIds = array_flip(explode( ',', $group['MonitorIds'] ));
|
||||
}
|
||||
|
||||
noCacheHeaders();
|
||||
|
||||
$maxWidth = 0;
|
||||
$maxHeight = 0;
|
||||
$cycleCount = 0;
|
||||
$minSequence = 0;
|
||||
$maxSequence = 1;
|
||||
$seqIdList = array();
|
||||
$monitors = dbFetchAll( "select * from Monitors order by Sequence asc" );
|
||||
$displayMonitors = array();
|
||||
for ( $i = 0; $i < count($monitors); $i++ )
|
||||
{
|
||||
if ( !visibleMonitor( $monitors[$i]['Id'] ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ( $group && !empty($groupIds) && !array_key_exists( $monitors[$i]['Id'], $groupIds ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
$monitors[$i]['Show'] = true;
|
||||
if ( empty($minSequence) || ($monitors[$i]['Sequence'] < $minSequence) )
|
||||
{
|
||||
$minSequence = $monitors[$i]['Sequence'];
|
||||
}
|
||||
if ( $monitors[$i]['Sequence'] > $maxSequence )
|
||||
{
|
||||
$maxSequence = $monitors[$i]['Sequence'];
|
||||
}
|
||||
$monitors[$i]['zmc'] = zmcStatus( $monitors[$i] );
|
||||
$monitors[$i]['zma'] = zmaStatus( $monitors[$i] );
|
||||
$monitors[$i]['ZoneCount'] = dbFetchOne( 'select count(Id) as ZoneCount from Zones where MonitorId = ?', 'ZoneCount', array($monitors[$i]['Id']) );
|
||||
$counts = array();
|
||||
for ( $j = 0; $j < count($eventCounts); $j++ )
|
||||
{
|
||||
$filter = addFilterTerm( $eventCounts[$j]['filter'], count($eventCounts[$j]['filter']['terms']), array( "cnj" => "and", "attr" => "MonitorId", "op" => "=", "val" => $monitors[$i]['Id'] ) );
|
||||
parseFilter( $filter );
|
||||
$counts[] = "count(if(1".$filter['sql'].",1,NULL)) as EventCount$j";
|
||||
$monitors[$i]['eventCounts'][$j]['filter'] = $filter;
|
||||
}
|
||||
$sql = "select ".join($counts,", ")." from Events as E where MonitorId = ?";
|
||||
$counts = dbFetchOne( $sql, NULL, array($monitors[$i]['Id']) );
|
||||
if ( $monitors[$i]['Function'] != 'None' )
|
||||
{
|
||||
$cycleCount++;
|
||||
$scaleWidth = reScale( $monitors[$i]['Width'], $monitors[$i]['DefaultScale'], ZM_WEB_DEFAULT_SCALE );
|
||||
$scaleHeight = reScale( $monitors[$i]['Height'], $monitors[$i]['DefaultScale'], ZM_WEB_DEFAULT_SCALE );
|
||||
if ( $maxWidth < $scaleWidth ) $maxWidth = $scaleWidth;
|
||||
if ( $maxHeight < $scaleHeight ) $maxHeight = $scaleHeight;
|
||||
}
|
||||
if ( $counts ) $monitors[$i] = array_merge( $monitors[$i], $counts );
|
||||
$seqIdList[] = $monitors[$i]['Id'];
|
||||
$displayMonitors[] = $monitors[$i];
|
||||
}
|
||||
$lastId = 0;
|
||||
$seqIdUpList = array();
|
||||
foreach ( $seqIdList as $seqId )
|
||||
{
|
||||
if ( !empty($lastId) )
|
||||
$seqIdUpList[$seqId] = $lastId;
|
||||
else
|
||||
$seqIdUpList[$seqId] = $seqId;
|
||||
$lastId = $seqId;
|
||||
}
|
||||
$lastId = 0;
|
||||
$seqIdDownList = array();
|
||||
foreach ( array_reverse($seqIdList) as $seqId )
|
||||
{
|
||||
if ( !empty($lastId) )
|
||||
$seqIdDownList[$seqId] = $lastId;
|
||||
else
|
||||
$seqIdDownList[$seqId] = $seqId;
|
||||
$lastId = $seqId;
|
||||
}
|
||||
|
||||
$cycleWidth = $maxWidth;
|
||||
$cycleHeight = $maxHeight;
|
||||
|
||||
$eventsView = ZM_WEB_EVENTS_VIEW;
|
||||
$eventsWindow = 'zm'.ucfirst(ZM_WEB_EVENTS_VIEW);
|
||||
|
||||
$eventCount = 0;
|
||||
for ( $i = 0; $i < count($eventCounts); $i++ )
|
||||
{
|
||||
$eventCounts[$i]['total'] = 0;
|
||||
}
|
||||
$zoneCount = 0;
|
||||
foreach( $displayMonitors as $monitor )
|
||||
{
|
||||
for ( $i = 0; $i < count($eventCounts); $i++ )
|
||||
{
|
||||
$eventCounts[$i]['total'] += $monitor['EventCount'.$i];
|
||||
}
|
||||
$zoneCount += $monitor['ZoneCount'];
|
||||
}
|
||||
|
||||
$seqUpFile = getSkinFile( 'graphics/seq-u.gif' );
|
||||
$seqDownFile = getSkinFile( 'graphics/seq-d.gif' );
|
||||
|
||||
$versionClass = (ZM_DYN_DB_VERSION&&(ZM_DYN_DB_VERSION!=ZM_VERSION))?'errorText':'';
|
||||
|
||||
|
||||
?>
|
||||
<div class="navbar navbar-default">
|
||||
<div class="container">
|
||||
<div class="navbar-header">
|
||||
<a class="navbar-brand" href="http://www.zoneminder.com" target="ZoneMinder">ZoneMinder</a>
|
||||
</div>
|
||||
|
||||
<ul class="nav navbar-nav">
|
||||
<li><a href="?view=console"><?php echo translate('Console') ?></a></li>
|
||||
<?php if ( canView( 'System' ) ) { ?>
|
||||
<li><a href="?view=options"><?php echo translate('Options') ?></a></li>
|
||||
<li><?php if ( logToDatabase() > Logger::NOLOG ) { ?> <?php echo makePopupLink( '?view=log', 'zmLog', 'log', '<span class="'.logState().'">'.translate('Log').'</span>' ) ?><?php } ?></li>
|
||||
<?php } ?>
|
||||
<?php if ( ZM_OPT_X10 && canView( 'Devices' ) ) { ?>
|
||||
<li><a href="/?view=devices">Devices</a></li>
|
||||
<?php } ?>
|
||||
<li><?php echo makePopupLink( '?view=groups', 'zmGroups', 'groups', sprintf( $CLANG['MonitorCount'], count($displayMonitors), zmVlang( $VLANG['Monitor'], count($displayMonitors) ) ).($group?' ('.$group['Name'].')':''), canView( 'Groups' ) ); ?></li>
|
||||
<li><?php echo makePopupLink( '?view=filter&filter[terms][0][attr]=DateTime&filter[terms][0][op]=%3c&filter[terms][0][val]=now', 'zmFilter', 'filter', translate('Filters'), canView( 'Events' ) ) ?></li>
|
||||
|
||||
<?php if ( canView( 'Stream' ) && $cycleCount > 1 ) {
|
||||
$cycleGroup = isset($_COOKIE['zmGroup'])?$_COOKIE['zmGroup']:0;
|
||||
?>
|
||||
<li><?php echo makePopupLink( '?view=cycle&group='.$cycleGroup, 'zmCycle'.$cycleGroup, array( 'cycle', $cycleWidth, $cycleHeight ), translate('Cycle'), $running ) ?></li>
|
||||
<li><?php echo makePopupLink( '?view=montage&group='.$cycleGroup, 'zmMontage'.$cycleGroup, 'montage', translate('Montage'), $running ) ?></li>
|
||||
<li><?php echo makePopupLink( '?view=montagereview&group='.$cycleGroup, 'zmMontage'.$cycleGroup, 'montagereview', translate('Montage Review'), $running ) ?></li>
|
||||
<?php } ?>
|
||||
</ul>
|
||||
|
||||
<div class="navbar-right">
|
||||
<?php if ( ZM_OPT_USE_AUTH ) { ?>
|
||||
<p class="navbar-text"><?php echo translate('LoggedInAs') ?> <?php echo makePopupLink( '?view=logout', 'zmLogout', 'logout', $user['Username'], (ZM_AUTH_TYPE == "builtin") ) ?> </p>
|
||||
<?php } ?>
|
||||
|
||||
<?php if ( canEdit( 'System' ) ) { ?>
|
||||
<a class="btn btn-default navbar-btn" href="/?view=state" onclick="createPopup( '?view=state', 'zmState', 'state' ); return( false );"> <?php echo $status ?> </a>
|
||||
|
||||
<?php } else if ( canView( 'System' ) ) { ?>
|
||||
<p class="navbar-text"> <?php echo $status ?> </p>
|
||||
<?php } ?>
|
||||
</div>
|
||||
|
||||
</div> <!-- End .container-fluid -->
|
||||
</div> <!-- End .navbar .navbar-default -->
|
|
@ -16,7 +16,7 @@ function setButtonStates( element )
|
|||
}
|
||||
}
|
||||
}
|
||||
$(element).getParent( 'tr' ).toggleClass( 'highlight' );
|
||||
$(element).closest("tr").toggleClass("danger");
|
||||
form.editBtn.disabled = (checked!=1);
|
||||
form.addBtn.value = (checked==1) ? jsTranslatedCloneText:jsTranslatedAddText;
|
||||
|
||||
|
|
|
@ -1,55 +1,69 @@
|
|||
function checkState( element )
|
||||
{
|
||||
$(document).ready(function() {
|
||||
// Enable or disable the Delete button depending on the selected run state
|
||||
$("#runState").change(function() {
|
||||
runstate = $(this).val();
|
||||
|
||||
var form = element.form;
|
||||
if ( (runstate == 'stop') || (runstate == 'restart') || (runstate == 'start') || (runstate == 'default') ) {
|
||||
$("#btnDelete").prop( "disabled", true );
|
||||
} else {
|
||||
$("#btnDelete").prop( "disabled", false );
|
||||
}
|
||||
});
|
||||
|
||||
var minIndex = running?2:1;
|
||||
if ( form.runState.selectedIndex < minIndex )
|
||||
{
|
||||
form.saveBtn.disabled = true;
|
||||
form.deleteBtn.disabled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
form.saveBtn.disabled = false;
|
||||
form.deleteBtn.disabled = false;
|
||||
}
|
||||
// Enable or disable the Save button when entering a new state
|
||||
$("#newState").keyup(function() {
|
||||
length = $(this).val().length;
|
||||
console.log(length);
|
||||
if (length < 1) {
|
||||
$("#btnSave").prop( "disabled", true );
|
||||
} else {
|
||||
$("#btnSave").prop( "disabled", false );
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
if ( form.newState.value != '' )
|
||||
form.saveBtn.disabled = false;
|
||||
// Delete a state
|
||||
$("#btnDelete").click(function() {
|
||||
StateStuff( 'delete', $("#runState").val( ));
|
||||
});
|
||||
|
||||
// PP if we are in 'default' state, disable delete
|
||||
// you can still save
|
||||
if (element.value.toLowerCase() == 'default' )
|
||||
{
|
||||
form.saveBtn.disabled = false;
|
||||
form.deleteBtn.disabled = true;
|
||||
}
|
||||
|
||||
}
|
||||
// Save a new state
|
||||
$("#btnSave").click(function() {
|
||||
StateStuff( 'save', undefined, $("#newState").val() );
|
||||
|
||||
});
|
||||
|
||||
function saveState( element )
|
||||
{
|
||||
var form = element.form;
|
||||
// Change state
|
||||
$("#btnApply").click(function() {
|
||||
StateStuff( 'state', $("#runState").val() );
|
||||
});
|
||||
|
||||
form.view.value = currentView;
|
||||
form.action.value = 'save';
|
||||
form.submit();
|
||||
}
|
||||
function StateStuff( action, runState, newState ){
|
||||
var formData = {
|
||||
'view' : 'console',
|
||||
'action' : action,
|
||||
'apply' : 1,
|
||||
'runState' : runState,
|
||||
'newState' : newState
|
||||
};
|
||||
console.log(formData);
|
||||
|
||||
function deleteState( element )
|
||||
{
|
||||
var form = element.form;
|
||||
form.view.value = currentView;
|
||||
form.action.value = 'delete';
|
||||
form.submit();
|
||||
}
|
||||
$("#pleasewait").toggleClass("hidden");
|
||||
|
||||
if ( applying )
|
||||
{
|
||||
function submitForm()
|
||||
{
|
||||
$('contentForm').submit();
|
||||
}
|
||||
window.addEvent( 'domready', function() { submitForm.delay( 1000 ); } );
|
||||
}
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: '/index.php',
|
||||
data: formData,
|
||||
dataType: 'html',
|
||||
enocde: true
|
||||
}).done(function(data) {
|
||||
location.reload();
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
});
|
||||
|
|
|
@ -78,11 +78,11 @@ Error("setting css $current_css to " . $_GET['css-choice']);
|
|||
|
||||
?>
|
||||
<body>
|
||||
|
||||
<?php include("skins/$skin/views/header.php") ?>
|
||||
|
||||
<?php echo getNavBarHTML(); ?>
|
||||
<div class="container-fluid">
|
||||
<ul class="nav nav-pills nav-stacked col-md-2">
|
||||
<div class="row">
|
||||
<div class="col-sm-2 sidebar">
|
||||
<ul class="nav nav-pills nav-stacked">
|
||||
<?php
|
||||
foreach ( $tabs as $name=>$value )
|
||||
{
|
||||
|
@ -92,8 +92,10 @@ foreach ( $tabs as $name=>$value )
|
|||
}
|
||||
?>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div id="options" class="col-md-10">
|
||||
<div class="col-sm-10 col-sm-offset-2">
|
||||
<div id="options">
|
||||
<?php
|
||||
if($tab == 'skins') {
|
||||
?>
|
||||
|
@ -393,6 +395,9 @@ elseif ( $tab == "users" )
|
|||
?>
|
||||
|
||||
</div><!-- end #options -->
|
||||
</div>
|
||||
</div> <!-- end row -->
|
||||
</div>
|
||||
<?php include("skins/$skin/views/state.php") ?>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -18,90 +18,55 @@
|
|||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
//
|
||||
|
||||
if ( !canEdit( 'System' ) )
|
||||
{
|
||||
$view = "error";
|
||||
return;
|
||||
if ( !canEdit( 'System' ) ) {
|
||||
$view = "error";
|
||||
return;
|
||||
}
|
||||
$running = daemonCheck();
|
||||
|
||||
$states = dbFetchAll( "select * from States" );
|
||||
$focusWindow = true;
|
||||
|
||||
xhtmlHeaders(__FILE__, translate('RunState') );
|
||||
?>
|
||||
<body>
|
||||
<div id="page">
|
||||
<div id="header">
|
||||
<h2><?php echo translate('RunState') ?></h2>
|
||||
</div>
|
||||
<div id="content">
|
||||
<form name="contentForm" id="contentForm" method="get" action="<?php echo $_SERVER['PHP_SELF'] ?>">
|
||||
<?php
|
||||
if ( empty($_REQUEST['apply']) )
|
||||
{
|
||||
?>
|
||||
<input type="hidden" name="view" value="<?php echo $view ?>"/>
|
||||
<input type="hidden" name="action" value=""/>
|
||||
<input type="hidden" name="apply" value="1"/>
|
||||
<p>
|
||||
<select name="runState" onchange="checkState( this );">
|
||||
<?php
|
||||
if ( $running )
|
||||
{
|
||||
?>
|
||||
<option value="stop" selected="selected"><?php echo translate('Stop') ?></option>
|
||||
<option value="restart"><?php echo translate('Restart') ?></option>
|
||||
<?php
|
||||
}
|
||||
else
|
||||
{
|
||||
?>
|
||||
<option value="start" selected="selected"><?php echo translate('Start') ?></option>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
<?php
|
||||
foreach ( $states as $state )
|
||||
{
|
||||
?>
|
||||
<option value="<?php echo $state['Name'] ?>"><?php echo $state['Name'] ?></option>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
</p>
|
||||
<table id="contentTable" class="minor" cellspacing="0">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row"><?php echo translate('NewState') ?></th>
|
||||
<!-- PP - added oninput so that changes are detected immediately -->
|
||||
<!-- PP - retained onchange for older browsers -->
|
||||
<td><input type="text" name="newState" value="" size="16" oninput="checkState( this );" onchange="checkState(this);"/></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div id="contentButtons">
|
||||
<input type="submit" value="<?php echo translate('Apply') ?>"/>
|
||||
<input type="button" name="saveBtn" value="<?php echo translate('Save') ?>" disabled="disabled" onclick="saveState( this );"/>
|
||||
<input type="button" name="deleteBtn" value="<?php echo translate('Delete') ?>" disabled="disabled" onclick="deleteState( this );"/>
|
||||
<input type="button" value="<?php echo translate('Cancel') ?>" onclick="closeWindow()"/>
|
||||
<div id="modalState" class="modal fade">
|
||||
<form class="form-horizontal" name="contentForm" id="contentForm" method="get" action="<?php echo $_SERVER['PHP_SELF'] ?>">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
<h2 class="modal-title"><?php echo translate('RunState') ?></h2>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="modal-body">
|
||||
<input type="hidden" name="view" value="<?php echo $view ?>"/>
|
||||
<input type="hidden" name="action" value="state"/>
|
||||
<input type="hidden" name="apply" value="1"/>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="runState" class="col-sm-3 control-label">Change State</label>
|
||||
<div class="col-sm-9">
|
||||
<select id="runState" name="runState" class="form-control">
|
||||
<?php if ( $running ) { ?>
|
||||
<option value="stop" selected="selected"><?php echo translate('Stop') ?></option>
|
||||
<option value="restart"><?php echo translate('Restart') ?></option>
|
||||
<?php } else { ?>
|
||||
<option value="start" selected="selected"><?php echo translate('Start') ?></option>
|
||||
<?php }
|
||||
?>
|
||||
<input type="hidden" name="view" value="none"/>
|
||||
<input type="hidden" name="action" value="state"/>
|
||||
<input type="hidden" name="runState" value="<?php echo validHtmlStr($_REQUEST['runState']) ?>"/>
|
||||
<p><?php echo translate('ApplyingStateChange') ?></p>
|
||||
<p><?php echo translate('PleaseWait') ?></p>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
<?php foreach ( $states as $state ) { ?>
|
||||
<option value="<?php echo $state['Name'] ?>"><?php echo $state['Name'] ?></option>
|
||||
<?php } ?>
|
||||
</select>
|
||||
</div><!--col-sm-9-->
|
||||
</div><!--form-group-->
|
||||
<div class="form-group">
|
||||
<label for="newState" class="col-sm-3 control-label"><?php echo translate('NewState') ?></label>
|
||||
<div class="col-sm-9">
|
||||
<input class="form-control" type="text" id="newState"/>
|
||||
</div>
|
||||
</div>
|
||||
</div> <!-- modal-body -->
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-primary" type="button" id="btnApply"><?php echo translate('Apply') ?></button>
|
||||
<button class="btn btn-primary" type="button" id="btnSave" disabled><?php echo translate('Save') ?></button>
|
||||
<button class="btn btn-danger" type="button" id="btnDelete" disabled><?php echo translate('Delete') ?></button>
|
||||
<p class="pull-left hidden" id="pleasewait"><?php echo translate('PleaseWait') ?></p>
|
||||
</div><!-- footer -->
|
||||
</div> <!-- content -->
|
||||
</div> <!-- dialog -->
|
||||
</form>
|
||||
</div> <!-- state -->
|
||||
|
|
Loading…
Reference in New Issue