Merge branch 'storageareas' of github.com:ZoneMinder/ZoneMinder into storageareas

This commit is contained in:
Isaac Connor 2016-05-09 21:08:13 -04:00
commit add4992dea
84 changed files with 2884 additions and 2621 deletions

89
.gitignore vendored
View File

@ -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

View File

@ -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(*)

View File

@ -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

View File

@ -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

View File

@ -81,6 +81,11 @@ our @EXPORT = ( @EXPORT_OK );
our $VERSION = $ZoneMinder::Base::VERSION;
BEGIN {
ZoneMinder::Config::zmConfigLoad();
ZoneMinder::Database::zmDbConnect();
}
1;
__END__

View File

@ -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

View File

@ -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

View File

@ -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",

View File

@ -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 );

View File

@ -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} )

View File

@ -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 = (

View File

@ -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
{

View File

@ -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() );

View File

@ -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 ) );

View File

@ -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) {

View File

@ -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>

View File

@ -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

View File

@ -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) {

View File

@ -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

View File

@ -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;

View File

@ -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 );

View File

@ -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");
}

View File

@ -138,6 +138,10 @@ public:
{
return( mStop );
}
int getAddressFamily ()
{
return mRtspSocket.getDomain();
}
};
#endif // ZM_RTSP_H

View File

@ -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 )

View File

@ -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()

View File

@ -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

View 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'];

View File

@ -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'];

View File

@ -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;

View File

@ -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];

View File

@ -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='&amp;' ) {
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='&amp;' ) {
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;
}
}
}
}
?>

View File

@ -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];
}
}
?>

View File

@ -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;
}

View File

@ -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();

View File

@ -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%;
}

View File

@ -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;
}

View File

@ -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>

View File

@ -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&amp;filter[terms][0][attr]=DateTime&amp;filter[terms][0][op]=%3c&amp;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&amp;group='.$cycleGroup, 'zmCycle'.$cycleGroup, array( 'cycle', $cycleWidth, $cycleHeight ), translate('Cycle'), $running ) ?></li>
<li><?php echo makePopupLink( '?view=montage&amp;group='.$cycleGroup, 'zmMontage'.$cycleGroup, 'montage', translate('Montage'), $running ) ?></li>
<li><?php echo makePopupLink( '?view=montagereview&amp;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() );
}
?>

7
web/skins/classic/js/bootstrap.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -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&amp;filter[terms][0][attr]=DateTime&amp;filter[terms][0][op]=%3c&amp;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.'&amp;action=sequence&amp;mid='.$monitor['Id'].'&amp;smid='.$seqIdUpList[$monitor['Id']], '<img src="'.$seqUpFile.'" alt="Up"/>', $monitor['Sequence']>$minSequence ) ?><?php echo makeLink( '?view='.$view.'&amp;action=sequence&amp;mid='.$monitor['Id'].'&amp;smid='.$seqIdDownList[$monitor['Id']], '<img src="'.$seqDownFile.'" alt="Down"/>', $monitor['Sequence']<$maxSequence ) ?></td>
<td class="colOrder">
<?php
if ( $monitor_i ) {
echo makeLink( '?view='.$view.'&amp;action=sequence&amp;mid='.$monitor['Id'].'&amp;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.'&amp;action=sequence&amp;mid='.$monitor['Id'].'&amp;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>

View File

@ -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&amp;filter[terms][0][attr]=DateTime&amp;filter[terms][0][op]=%3c&amp;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&amp;group='.$cycleGroup, 'zmCycle'.$cycleGroup, array( 'cycle', $cycleWidth, $cycleHeight ), translate('Cycle'), $running ) ?></li>
<li><?php echo makePopupLink( '?view=montage&amp;group='.$cycleGroup, 'zmMontage'.$cycleGroup, 'montage', translate('Montage'), $running ) ?></li>
<li><?php echo makePopupLink( '?view=montagereview&amp;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 -->

View File

@ -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;

View File

@ -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();
});
}
});

View File

@ -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>

View File

@ -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">&times;</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 -->