Merge branch 'storageareas' of github.com:connortechnology/ZoneMinder into storageareas
This commit is contained in:
commit
09dae432ce
|
@ -4,6 +4,11 @@ What's New
|
||||||
1. See the ZoneMinder release notes for a list of new features:
|
1. See the ZoneMinder release notes for a list of new features:
|
||||||
https://github.com/ZoneMinder/zoneminder/releases
|
https://github.com/ZoneMinder/zoneminder/releases
|
||||||
|
|
||||||
|
2. The contents of the ZoneMinder Apache config file have changed. In
|
||||||
|
addition, this ZoneMinder package now requires you to manually symlink the
|
||||||
|
ZoneMinder Apache config file. See new install step 6 and upgrade step 3
|
||||||
|
below for details.
|
||||||
|
|
||||||
New installs
|
New installs
|
||||||
============
|
============
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,11 @@ What's New
|
||||||
1. See the ZoneMinder release notes for a list of new features:
|
1. See the ZoneMinder release notes for a list of new features:
|
||||||
https://github.com/ZoneMinder/zoneminder/releases
|
https://github.com/ZoneMinder/zoneminder/releases
|
||||||
|
|
||||||
|
2. The contents of the ZoneMinder Apache config file have changed. In
|
||||||
|
addition, this ZoneMinder package now requires you to manually symlink the
|
||||||
|
ZoneMinder Apache config file. See new install step 6 and upgrade step 3
|
||||||
|
below for details.
|
||||||
|
|
||||||
New installs
|
New installs
|
||||||
============
|
============
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
%global _hardened_build 1
|
%global _hardened_build 1
|
||||||
|
|
||||||
Name: zoneminder
|
Name: zoneminder
|
||||||
Version: 1.31.43
|
Version: 1.31.44
|
||||||
Release: 1%{?dist}
|
Release: 1%{?dist}
|
||||||
Summary: A camera monitoring and analysis tool
|
Summary: A camera monitoring and analysis tool
|
||||||
Group: System Environment/Daemons
|
Group: System Environment/Daemons
|
||||||
|
|
|
@ -245,7 +245,8 @@ sub initialise( @ ) {
|
||||||
$tempSyslogLevel = $level if defined($level = $this->getTargettedEnv('LOG_LEVEL_SYSLOG'));
|
$tempSyslogLevel = $level if defined($level = $this->getTargettedEnv('LOG_LEVEL_SYSLOG'));
|
||||||
|
|
||||||
if ( $Config{ZM_LOG_DEBUG} ) {
|
if ( $Config{ZM_LOG_DEBUG} ) {
|
||||||
foreach my $target ( split( /\|/, $Config{ZM_LOG_DEBUG_TARGET} ) ) {
|
# Splitting on an empty string doesn't return an empty string, it returns an empty array
|
||||||
|
foreach my $target ( $Config{ZM_LOG_DEBUG_TARGET} ? split(/\|/, $Config{ZM_LOG_DEBUG_TARGET}) : '' ) {
|
||||||
if ( $target eq $this->{id}
|
if ( $target eq $this->{id}
|
||||||
|| $target eq '_'.$this->{id}
|
|| $target eq '_'.$this->{id}
|
||||||
|| $target eq $this->{idRoot}
|
|| $target eq $this->{idRoot}
|
||||||
|
@ -278,6 +279,9 @@ sub initialise( @ ) {
|
||||||
|
|
||||||
$this->{initialised} = !undef;
|
$this->{initialised} = !undef;
|
||||||
|
|
||||||
|
# this function can get called on a previously initialized log Object, so clean any sth's
|
||||||
|
$this->{sth} = undef;
|
||||||
|
|
||||||
Debug( 'LogOpts: level='.$codes{$this->{level}}
|
Debug( 'LogOpts: level='.$codes{$this->{level}}
|
||||||
.'/'.$codes{$this->{effectiveLevel}}
|
.'/'.$codes{$this->{effectiveLevel}}
|
||||||
.', screen='.$codes{$this->{termLevel}}
|
.', screen='.$codes{$this->{termLevel}}
|
||||||
|
@ -319,6 +323,8 @@ sub reinitialise {
|
||||||
my $screenLevel = $this->termLevel();
|
my $screenLevel = $this->termLevel();
|
||||||
$this->termLevel(NOLOG);
|
$this->termLevel(NOLOG);
|
||||||
$this->termLevel($screenLevel) if $screenLevel > NOLOG;
|
$this->termLevel($screenLevel) if $screenLevel > NOLOG;
|
||||||
|
|
||||||
|
$this->{sth} = undef;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Prevents undefined logging levels
|
# Prevents undefined logging levels
|
||||||
|
@ -392,6 +398,12 @@ sub level {
|
||||||
|
|
||||||
# ICON: I am remarking this out because I don't see the point of having an effective level, if we are just going to set it to level.
|
# ICON: I am remarking this out because I don't see the point of having an effective level, if we are just going to set it to level.
|
||||||
#$this->{effectiveLevel} = $this->{level} if ( $this->{level} > $this->{effectiveLevel} );
|
#$this->{effectiveLevel} = $this->{level} if ( $this->{level} > $this->{effectiveLevel} );
|
||||||
|
# ICON: The point is that LOG_DEBUG can be set either in db or in env var and will get passed in here.
|
||||||
|
# So this will turn on debug, even if not output has Debug level turned on. I think it should be the other way around
|
||||||
|
|
||||||
|
# ICON: Let's try this line instead. effectiveLevel is 1 DEBUG from above, but LOG_DEBUG is off, then $this->level will be 0, and
|
||||||
|
# so effectiveLevel will become 0
|
||||||
|
$this->{effectiveLevel} = $this->{level} if ( $this->{level} < $this->{effectiveLevel} );
|
||||||
}
|
}
|
||||||
return $this->{level};
|
return $this->{level};
|
||||||
}
|
}
|
||||||
|
@ -474,7 +486,7 @@ sub openSyslog {
|
||||||
|
|
||||||
sub closeSyslog {
|
sub closeSyslog {
|
||||||
my $this = shift;
|
my $this = shift;
|
||||||
#closelog();
|
closelog();
|
||||||
}
|
}
|
||||||
|
|
||||||
sub logFile {
|
sub logFile {
|
||||||
|
@ -517,17 +529,19 @@ sub logPrint {
|
||||||
|
|
||||||
if ( $level <= $this->{effectiveLevel} ) {
|
if ( $level <= $this->{effectiveLevel} ) {
|
||||||
$string =~ s/[\r\n]+$//g;
|
$string =~ s/[\r\n]+$//g;
|
||||||
|
if ( $level <= $this->{syslogLevel} ) {
|
||||||
my $code = $codes{$level};
|
syslog($priorities{$level}, $codes{$level}.' [%s]', $string);
|
||||||
|
}
|
||||||
|
|
||||||
my ($seconds, $microseconds) = gettimeofday();
|
my ($seconds, $microseconds) = gettimeofday();
|
||||||
|
if ( $level <= $this->{fileLevel} or $level <= $this->{termLevel} ) {
|
||||||
my $message = sprintf(
|
my $message = sprintf(
|
||||||
'%s.%06d %s[%d].%s [%s]'
|
'%s.%06d %s[%d].%s [%s]'
|
||||||
, strftime('%x %H:%M:%S', localtime($seconds))
|
, strftime('%x %H:%M:%S', localtime($seconds))
|
||||||
, $microseconds
|
, $microseconds
|
||||||
, $this->{id}
|
, $this->{id}
|
||||||
, $$
|
, $$
|
||||||
, $code
|
, $codes{$level}
|
||||||
, $string
|
, $string
|
||||||
);
|
);
|
||||||
if ( $this->{trace} ) {
|
if ( $this->{trace} ) {
|
||||||
|
@ -535,26 +549,33 @@ sub logPrint {
|
||||||
} else {
|
} else {
|
||||||
$message = $message."\n";
|
$message = $message."\n";
|
||||||
}
|
}
|
||||||
if ( $level <= $this->{syslogLevel} ) {
|
|
||||||
syslog($priorities{$level}, $code.' [%s]', $string);
|
|
||||||
}
|
|
||||||
print($LOGFILE $message) if $level <= $this->{fileLevel};
|
print($LOGFILE $message) if $level <= $this->{fileLevel};
|
||||||
print(STDERR $message) if $level <= $this->{termLevel};
|
print(STDERR $message) if $level <= $this->{termLevel};
|
||||||
|
}
|
||||||
|
|
||||||
if ( $level <= $this->{databaseLevel} ) {
|
if ( $level <= $this->{databaseLevel} ) {
|
||||||
if ( ( $this->{dbh} and $this->{dbh}->ping() ) or ( $this->{dbh} = ZoneMinder::Database::zmDbConnect() ) ) {
|
if ( ! ( $this->{dbh} and $this->{dbh}->ping() ) ) {
|
||||||
|
$this->{sth} = undef;
|
||||||
|
if ( ! ( $this->{dbh} = ZoneMinder::Database::zmDbConnect() ) ) {
|
||||||
|
print(STDERR "Can't log to database: ");
|
||||||
|
$this->{databaseLevel} = NOLOG;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
my $sql = 'INSERT INTO Logs ( TimeKey, Component, Pid, Level, Code, Message, File, Line ) VALUES ( ?, ?, ?, ?, ?, ?, ?, NULL )';
|
my $sql = 'INSERT INTO Logs ( TimeKey, Component, Pid, Level, Code, Message, File, Line ) VALUES ( ?, ?, ?, ?, ?, ?, ?, NULL )';
|
||||||
$this->{sth} = $this->{dbh}->prepare_cached($sql);
|
$this->{sth} = $this->{dbh}->prepare_cached($sql) if ! $this->{sth};
|
||||||
if ( !$this->{sth} ) {
|
if ( !$this->{sth} ) {
|
||||||
$this->{databaseLevel} = NOLOG;
|
$this->{databaseLevel} = NOLOG;
|
||||||
Error("Can't prepare log entry '$sql': ".$this->{dbh}->errstr());
|
Error("Can't prepare log entry '$sql': ".$this->{dbh}->errstr());
|
||||||
} else {
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
my $res = $this->{sth}->execute($seconds+($microseconds/1000000.0)
|
my $res = $this->{sth}->execute($seconds+($microseconds/1000000.0)
|
||||||
, $this->{id}
|
, $this->{id}
|
||||||
, $$
|
, $$
|
||||||
, $level
|
, $level
|
||||||
, $code
|
, $codes{$level}
|
||||||
, $string
|
, $string
|
||||||
, $this->{fileName}
|
, $this->{fileName}
|
||||||
);
|
);
|
||||||
|
@ -562,10 +583,6 @@ sub logPrint {
|
||||||
$this->{databaseLevel} = NOLOG;
|
$this->{databaseLevel} = NOLOG;
|
||||||
Error("Can't execute log entry '$sql': ".$this->{dbh}->errstr());
|
Error("Can't execute log entry '$sql': ".$this->{dbh}->errstr());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} else {
|
|
||||||
print(STDERR "Can't log to database: ");
|
|
||||||
}
|
|
||||||
} # end if doing db logging
|
} # end if doing db logging
|
||||||
} # end if level < effectivelevel
|
} # end if level < effectivelevel
|
||||||
}
|
}
|
||||||
|
|
|
@ -139,7 +139,7 @@ foreach my $arg ( @ARGV ) {
|
||||||
# Detaint arguments, if they look ok
|
# Detaint arguments, if they look ok
|
||||||
#if ( $arg =~ /^(-{0,2}[\w]+)/ )
|
#if ( $arg =~ /^(-{0,2}[\w]+)/ )
|
||||||
if ( $arg =~ /^(-{0,2}[\w\/?&=.-]+)$/ ) {
|
if ( $arg =~ /^(-{0,2}[\w\/?&=.-]+)$/ ) {
|
||||||
push( @args, $1 );
|
push @args, $1;
|
||||||
} else {
|
} else {
|
||||||
print(STDERR "Bogus argument '$arg' found");
|
print(STDERR "Bogus argument '$arg' found");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
|
@ -245,6 +245,16 @@ our %terminating_processes;
|
||||||
our $zm_terminate = 0;
|
our $zm_terminate = 0;
|
||||||
|
|
||||||
sub run {
|
sub run {
|
||||||
|
|
||||||
|
# Call this first otherwise stdout/stderror redirects to the pidfile = bad
|
||||||
|
if ( open(my $PID, '>', ZM_PID) ) {
|
||||||
|
print($PID $$);
|
||||||
|
close($PID);
|
||||||
|
} else {
|
||||||
|
# Log not initialized at this point so use die instead
|
||||||
|
die "Can't open pid file at ".ZM_PID."\n";
|
||||||
|
}
|
||||||
|
|
||||||
my $fd = 0;
|
my $fd = 0;
|
||||||
while( $fd < POSIX::sysconf(&POSIX::_SC_OPEN_MAX) ) {
|
while( $fd < POSIX::sysconf(&POSIX::_SC_OPEN_MAX) ) {
|
||||||
POSIX::close($fd++);
|
POSIX::close($fd++);
|
||||||
|
@ -252,6 +262,8 @@ sub run {
|
||||||
|
|
||||||
setpgrp();
|
setpgrp();
|
||||||
|
|
||||||
|
# dbh got closed with the rest of the fd's above, so need to reconnect.
|
||||||
|
my $dbh = zmDbConnect(1);
|
||||||
logInit();
|
logInit();
|
||||||
|
|
||||||
dPrint(ZoneMinder::Logger::INFO, 'Server starting at '
|
dPrint(ZoneMinder::Logger::INFO, 'Server starting at '
|
||||||
|
@ -259,18 +271,10 @@ sub run {
|
||||||
."\n"
|
."\n"
|
||||||
);
|
);
|
||||||
|
|
||||||
if ( open(my $PID, '>', ZM_PID) ) {
|
|
||||||
print($PID $$);
|
|
||||||
close($PID);
|
|
||||||
} else {
|
|
||||||
Error("Can't open pid file at " . ZM_PID);
|
|
||||||
}
|
|
||||||
|
|
||||||
# Tell any existing processes to die, wait 1 second between TERM and KILL
|
# Tell any existing processes to die, wait 1 second between TERM and KILL
|
||||||
killAll(1);
|
killAll(1);
|
||||||
|
|
||||||
dPrint(ZoneMinder::Logger::INFO, 'Socket should be open at ' .main::SOCK_FILE);
|
dPrint(ZoneMinder::Logger::INFO, 'Socket should be open at ' .main::SOCK_FILE);
|
||||||
my $dbh = zmDbConnect(1);
|
|
||||||
socket(SERVER, PF_UNIX, SOCK_STREAM, 0) or Fatal("Can't open socket: $!");
|
socket(SERVER, PF_UNIX, SOCK_STREAM, 0) or Fatal("Can't open socket: $!");
|
||||||
unlink(main::SOCK_FILE) or Error('Unable to unlink ' . main::SOCK_FILE .". Error message was: $!") if -e main::SOCK_FILE;
|
unlink(main::SOCK_FILE) or Error('Unable to unlink ' . main::SOCK_FILE .". Error message was: $!") if -e main::SOCK_FILE;
|
||||||
bind(SERVER, $saddr) or Fatal("Can't bind to " . main::SOCK_FILE . ": $!");
|
bind(SERVER, $saddr) or Fatal("Can't bind to " . main::SOCK_FILE . ": $!");
|
||||||
|
@ -306,7 +310,7 @@ sub run {
|
||||||
$dbh = zmDbConnect();
|
$dbh = zmDbConnect();
|
||||||
}
|
}
|
||||||
my @cpuload = CpuLoad();
|
my @cpuload = CpuLoad();
|
||||||
Debug("UPdating Server record @cpuload");
|
Debug("Updating Server record @cpuload");
|
||||||
if ( ! defined $dbh->do(q{UPDATE Servers SET Status=?,CpuLoad=?,TotalMem=?,FreeMem=?,TotalSwap=?,FreeSwap=? WHERE Id=?}, undef,
|
if ( ! defined $dbh->do(q{UPDATE Servers SET Status=?,CpuLoad=?,TotalMem=?,FreeMem=?,TotalSwap=?,FreeSwap=? WHERE Id=?}, undef,
|
||||||
'Running', $cpuload[0], &totalmem, &freemem, &totalswap, &freeswap, $Config{ZM_SERVER_ID} ) ) {
|
'Running', $cpuload[0], &totalmem, &freemem, &totalswap, &freeswap, $Config{ZM_SERVER_ID} ) ) {
|
||||||
Error("Failed Updating status of Server record for Id=$Config{ZM_SERVER_ID}".$dbh->errstr());
|
Error("Failed Updating status of Server record for Id=$Config{ZM_SERVER_ID}".$dbh->errstr());
|
||||||
|
@ -315,7 +319,6 @@ sub run {
|
||||||
$secs_count += 1;
|
$secs_count += 1;
|
||||||
}
|
}
|
||||||
my $nfound = select(my $rout = $rin, undef, undef, $timeout);
|
my $nfound = select(my $rout = $rin, undef, undef, $timeout);
|
||||||
Debug("Aftere select $nfound");
|
|
||||||
if ( $nfound > 0 ) {
|
if ( $nfound > 0 ) {
|
||||||
if ( vec($rout, fileno(SERVER), 1) ) {
|
if ( vec($rout, fileno(SERVER), 1) ) {
|
||||||
my $paddr = accept(CLIENT, SERVER);
|
my $paddr = accept(CLIENT, SERVER);
|
||||||
|
@ -370,9 +373,7 @@ Debug("Aftere select $nfound");
|
||||||
#print( "Select timed out\n" );
|
#print( "Select timed out\n" );
|
||||||
}
|
}
|
||||||
|
|
||||||
Debug("restartPending");
|
|
||||||
restartPending();
|
restartPending();
|
||||||
Debug("check_for_processes_to_kill");
|
|
||||||
check_for_processes_to_kill();
|
check_for_processes_to_kill();
|
||||||
|
|
||||||
} # end while
|
} # end while
|
||||||
|
@ -382,7 +383,7 @@ Debug("check_for_processes_to_kill");
|
||||||
."\n"
|
."\n"
|
||||||
);
|
);
|
||||||
if ( $Config{ZM_SERVER_ID} ) {
|
if ( $Config{ZM_SERVER_ID} ) {
|
||||||
$dbh = zmDbConnect() if ! $dbh->ping();
|
$dbh = zmDbConnect() if ! ($dbh and $dbh->ping());
|
||||||
if ( ! defined $dbh->do(q{UPDATE Servers SET Status='NotRunning' WHERE Id=?}, undef, $Config{ZM_SERVER_ID}) ) {
|
if ( ! defined $dbh->do(q{UPDATE Servers SET Status='NotRunning' WHERE Id=?}, undef, $Config{ZM_SERVER_ID}) ) {
|
||||||
Error("Failed Updating status of Server record for Id=$Config{ZM_SERVER_ID}".$dbh->errstr());
|
Error("Failed Updating status of Server record for Id=$Config{ZM_SERVER_ID}".$dbh->errstr());
|
||||||
}
|
}
|
||||||
|
@ -399,6 +400,7 @@ sub cPrint {
|
||||||
# I think the purpose of this is to echo the logs to the client process so it can then display them.
|
# I think the purpose of this is to echo the logs to the client process so it can then display them.
|
||||||
sub dPrint {
|
sub dPrint {
|
||||||
my $logLevel = shift;
|
my $logLevel = shift;
|
||||||
|
# One thought here, if no client exists to read these... does it block?
|
||||||
if ( fileno(CLIENT) ) {
|
if ( fileno(CLIENT) ) {
|
||||||
print CLIENT @_
|
print CLIENT @_
|
||||||
}
|
}
|
||||||
|
@ -435,12 +437,10 @@ sub start {
|
||||||
|
|
||||||
my $sigset = POSIX::SigSet->new;
|
my $sigset = POSIX::SigSet->new;
|
||||||
my $blockset = POSIX::SigSet->new(SIGCHLD);
|
my $blockset = POSIX::SigSet->new(SIGCHLD);
|
||||||
Debug("Blocking SIGCHLD");
|
|
||||||
sigprocmask(SIG_BLOCK, $blockset, $sigset) or Fatal("Can't block SIGCHLD: $!");
|
sigprocmask(SIG_BLOCK, $blockset, $sigset) or Fatal("Can't block SIGCHLD: $!");
|
||||||
Debug("forking");
|
|
||||||
if ( my $cpid = fork() ) {
|
if ( my $cpid = fork() ) {
|
||||||
# This logReinit is required. Not sure why.
|
# This logReinit is required. Not sure why.
|
||||||
logReinit();
|
#logReinit();
|
||||||
|
|
||||||
$process->{pid} = $cpid;
|
$process->{pid} = $cpid;
|
||||||
$process->{started} = time();
|
$process->{started} = time();
|
||||||
|
@ -453,7 +453,6 @@ sub start {
|
||||||
|
|
||||||
$cmd_hash{$process->{command}} = $pid_hash{$cpid} = $process;
|
$cmd_hash{$process->{command}} = $pid_hash{$cpid} = $process;
|
||||||
sigprocmask(SIG_SETMASK, $sigset) or Fatal("Can't restore SIGCHLD: $!");
|
sigprocmask(SIG_SETMASK, $sigset) or Fatal("Can't restore SIGCHLD: $!");
|
||||||
Debug("unblocking child");
|
|
||||||
} elsif ( defined($cpid) ) {
|
} elsif ( defined($cpid) ) {
|
||||||
# Force reconnection to the db.
|
# Force reconnection to the db.
|
||||||
$dbh = zmDbConnect(1);
|
$dbh = zmDbConnect(1);
|
||||||
|
@ -708,7 +707,6 @@ sub reaper {
|
||||||
} # end while waitpid
|
} # end while waitpid
|
||||||
$SIG{CHLD} = \&reaper;
|
$SIG{CHLD} = \&reaper;
|
||||||
$! = $saved_status;
|
$! = $saved_status;
|
||||||
Debug("Leaving reaper");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sub restartPending {
|
sub restartPending {
|
||||||
|
@ -720,7 +718,6 @@ sub restartPending {
|
||||||
start($process->{daemon}, @{$process->{args}});
|
start($process->{daemon}, @{$process->{args}});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Debug("done restartPending");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sub shutdownAll {
|
sub shutdownAll {
|
||||||
|
|
|
@ -70,12 +70,14 @@ use Getopt::Long;
|
||||||
use autouse 'Pod::Usage'=>qw(pod2usage);
|
use autouse 'Pod::Usage'=>qw(pod2usage);
|
||||||
use autouse 'Data::Dumper'=>qw(Dumper);
|
use autouse 'Data::Dumper'=>qw(Dumper);
|
||||||
|
|
||||||
|
my $daemon = 0;
|
||||||
my $filter_name = '';
|
my $filter_name = '';
|
||||||
my $filter_id;
|
my $filter_id;
|
||||||
my $version = 0;
|
my $version = 0;
|
||||||
my $zm_terminate = 0;
|
my $zm_terminate = 0;
|
||||||
|
|
||||||
GetOptions(
|
GetOptions(
|
||||||
|
'daemon' =>\$daemon,
|
||||||
'filter=s' =>\$filter_name,
|
'filter=s' =>\$filter_name,
|
||||||
'filter_id=s' =>\$filter_id,
|
'filter_id=s' =>\$filter_id,
|
||||||
'version' =>\$version
|
'version' =>\$version
|
||||||
|
@ -201,7 +203,7 @@ while( !$zm_terminate ) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
last if $filter_name or $filter_id or $zm_terminate;
|
last if (!$daemon and ($filter_name or $filter_id)) or $zm_terminate;
|
||||||
|
|
||||||
Debug("Sleeping for $delay seconds\n");
|
Debug("Sleeping for $delay seconds\n");
|
||||||
sleep($delay);
|
sleep($delay);
|
||||||
|
|
|
@ -41,9 +41,10 @@ use autouse 'Pod::Usage'=>qw(pod2usage);
|
||||||
$ENV{PATH} = '/bin:/usr/bin:/usr/local/bin';
|
$ENV{PATH} = '/bin:/usr/bin:/usr/local/bin';
|
||||||
$ENV{SHELL} = '/bin/sh' if exists $ENV{SHELL};
|
$ENV{SHELL} = '/bin/sh' if exists $ENV{SHELL};
|
||||||
delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};
|
delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};
|
||||||
my $store_state=""; # PP - will remember state name passed
|
my $store_state=''; # PP - will remember state name passed
|
||||||
|
|
||||||
logInit();
|
logInit();
|
||||||
|
Info("Aftere LogInit");
|
||||||
|
|
||||||
my $command = $ARGV[0]||'';
|
my $command = $ARGV[0]||'';
|
||||||
if ( $command eq 'version' ) {
|
if ( $command eq 'version' ) {
|
||||||
|
@ -53,11 +54,10 @@ if ( $command eq 'version' ) {
|
||||||
|
|
||||||
my $state;
|
my $state;
|
||||||
|
|
||||||
my $dbh;
|
my $dbh = zmDbConnect();
|
||||||
|
Info("Command: $command");
|
||||||
if ( !$command || $command !~ /^(?:start|stop|restart|status|logrot|version)$/ ) {
|
if ( !$command || $command !~ /^(?:start|stop|restart|status|logrot|version)$/ ) {
|
||||||
if ( $command ) {
|
if ( $command ) {
|
||||||
$dbh = zmDbConnect();
|
|
||||||
# Check to see if it's a valid run state
|
# Check to see if it's a valid run state
|
||||||
my $sql = 'SELECT * FROM States WHERE Name=?';
|
my $sql = 'SELECT * FROM States WHERE Name=?';
|
||||||
my $sth = $dbh->prepare_cached($sql)
|
my $sth = $dbh->prepare_cached($sql)
|
||||||
|
@ -65,10 +65,10 @@ if ( !$command || $command !~ /^(?:start|stop|restart|status|logrot|version)$/ )
|
||||||
my $res = $sth->execute($command)
|
my $res = $sth->execute($command)
|
||||||
or Fatal("Can't execute: ".$sth->errstr());
|
or Fatal("Can't execute: ".$sth->errstr());
|
||||||
if ( $state = $sth->fetchrow_hashref() ) {
|
if ( $state = $sth->fetchrow_hashref() ) {
|
||||||
$state->{Name} = $command;
|
#$state->{Name} = $command;
|
||||||
$state->{Definitions} = [];
|
$state->{Definitions} = [];
|
||||||
foreach( split( /,/, $state->{Definition} ) ) {
|
foreach( split(',', $state->{Definition}) ) {
|
||||||
my ( $id, $function, $enabled ) = split( /:/, $_ );
|
my ( $id, $function, $enabled ) = split(':', $_);
|
||||||
push( @{$state->{Definitions}},
|
push( @{$state->{Definitions}},
|
||||||
{ Id=>$id, Function=>$function, Enabled=>$enabled }
|
{ Id=>$id, Function=>$function, Enabled=>$enabled }
|
||||||
);
|
);
|
||||||
|
@ -82,24 +82,26 @@ if ( !$command || $command !~ /^(?:start|stop|restart|status|logrot|version)$/ )
|
||||||
if ( !$command ) {
|
if ( !$command ) {
|
||||||
pod2usage(-exitstatus => -1);
|
pod2usage(-exitstatus => -1);
|
||||||
}
|
}
|
||||||
}
|
} # end if not one of the usual commands
|
||||||
$dbh = zmDbConnect() if ! $dbh;
|
|
||||||
# PP - Sane state check
|
# PP - Sane state check
|
||||||
|
Debug("StartisActiveSSantiyCheck");
|
||||||
isActiveSanityCheck();
|
isActiveSanityCheck();
|
||||||
|
Debug("Done isActiveSSantiyCheck");
|
||||||
|
|
||||||
# Move to the right place
|
# Move to the right place
|
||||||
chdir($Config{ZM_PATH_WEB})
|
chdir($Config{ZM_PATH_WEB})
|
||||||
or Fatal( "Can't chdir to '".$Config{ZM_PATH_WEB}."': $!" );
|
or Fatal("Can't chdir to '$Config{ZM_PATH_WEB}': $!");
|
||||||
|
|
||||||
my $dbg_id = '';
|
my $dbg_id = '';
|
||||||
|
|
||||||
Info( "Command: $command\n" );
|
Info("Command: $command");
|
||||||
|
|
||||||
my $retval = 0;
|
my $retval = 0;
|
||||||
|
|
||||||
if ( $command eq 'state' ) {
|
if ( $command eq 'state' ) {
|
||||||
Info( "Updating DB: $state->{Name}\n" );
|
Info("Updating DB: $state->{Name}");
|
||||||
my $sql = $Config{ZM_SERVER_ID} ? 'SELECT * FROM Monitors WHERE ServerId=? ORDER BY Id ASC' : 'SELECT * FROM Monitors ORDER BY Id ASC';
|
my $sql = 'SELECT * FROM Monitors' . ($Config{ZM_SERVER_ID} ? ' WHERE ServerId=?' : '' ) .' ORDER BY Id ASC';
|
||||||
my $sth = $dbh->prepare_cached($sql)
|
my $sth = $dbh->prepare_cached($sql)
|
||||||
or Fatal("Can't prepare '$sql': ".$dbh->errstr());
|
or Fatal("Can't prepare '$sql': ".$dbh->errstr());
|
||||||
my $res = $sth->execute($Config{ZM_SERVER_ID} ? $Config{ZM_SERVER_ID}: ())
|
my $res = $sth->execute($Config{ZM_SERVER_ID} ? $Config{ZM_SERVER_ID}: ())
|
||||||
|
@ -124,14 +126,14 @@ chdir( $Config{ZM_PATH_WEB} )
|
||||||
or Fatal("Can't prepare '$sql': ".$dbh->errstr());
|
or Fatal("Can't prepare '$sql': ".$dbh->errstr());
|
||||||
my $res = $sth->execute($monitor->{NewFunction}, $monitor->{NewEnabled}, $monitor->{Id})
|
my $res = $sth->execute($monitor->{NewFunction}, $monitor->{NewEnabled}, $monitor->{Id})
|
||||||
or Fatal("Can't execute: ".$sth->errstr());
|
or Fatal("Can't execute: ".$sth->errstr());
|
||||||
}
|
} # end if change of function or enablement
|
||||||
}
|
} # end foreach monitor
|
||||||
$sth->finish();
|
$sth->finish();
|
||||||
|
|
||||||
# PP - Now mark a specific state as active
|
# PP - Now mark a specific state as active
|
||||||
resetStates();
|
resetStates();
|
||||||
Info("Marking $store_state as Enabled");
|
Info("Marking $store_state as Enabled");
|
||||||
$sql = "UPDATE States SET IsActive = '1' WHERE Name = ?";
|
$sql = 'UPDATE States SET IsActive = 1 WHERE Name = ?';
|
||||||
$sth = $dbh->prepare_cached($sql)
|
$sth = $dbh->prepare_cached($sql)
|
||||||
or Fatal("Can't prepare '$sql': ".$dbh->errstr());
|
or Fatal("Can't prepare '$sql': ".$dbh->errstr());
|
||||||
$res = $sth->execute($store_state)
|
$res = $sth->execute($store_state)
|
||||||
|
@ -139,7 +141,7 @@ chdir( $Config{ZM_PATH_WEB} )
|
||||||
|
|
||||||
# PP - zero out other states isActive
|
# PP - zero out other states isActive
|
||||||
$command = 'restart';
|
$command = 'restart';
|
||||||
}
|
} # end if command = state
|
||||||
|
|
||||||
# Check if we are running systemd and if we have been called by the system
|
# Check if we are running systemd and if we have been called by the system
|
||||||
if ( $command =~ /^(start|stop|restart)$/ ) {
|
if ( $command =~ /^(start|stop|restart)$/ ) {
|
||||||
|
@ -154,6 +156,7 @@ if ( $command =~ /^(start|stop|restart)$/ ) {
|
||||||
|
|
||||||
if ( $command =~ /^(?:stop|restart)$/ ) {
|
if ( $command =~ /^(?:stop|restart)$/ ) {
|
||||||
my $status = runCommand('zmdc.pl check');
|
my $status = runCommand('zmdc.pl check');
|
||||||
|
Debug("zmdc.pl check = $status");
|
||||||
|
|
||||||
if ( $status eq 'running' ) {
|
if ( $status eq 'running' ) {
|
||||||
runCommand('zmdc.pl shutdown');
|
runCommand('zmdc.pl shutdown');
|
||||||
|
@ -163,10 +166,9 @@ if ( $command =~ /^(?:stop|restart)$/ ) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#runCommand( "zmupdate.pl -f" );
|
|
||||||
|
|
||||||
if ( $command =~ /^(?:start|restart)$/ ) {
|
if ( $command =~ /^(?:start|restart)$/ ) {
|
||||||
my $status = runCommand('zmdc.pl check');
|
my $status = runCommand('zmdc.pl check');
|
||||||
|
Debug("zmdc.pl check = $status");
|
||||||
|
|
||||||
if ( $status eq 'stopped' ) {
|
if ( $status eq 'stopped' ) {
|
||||||
if ( $Config{ZM_DYN_DB_VERSION}
|
if ( $Config{ZM_DYN_DB_VERSION}
|
||||||
|
@ -196,7 +198,7 @@ if ( $command =~ /^(?:start|restart)$/ ) {
|
||||||
my @values;
|
my @values;
|
||||||
if ( $Config{ZM_SERVER_ID} ) {
|
if ( $Config{ZM_SERVER_ID} ) {
|
||||||
require ZoneMinder::Server;
|
require ZoneMinder::Server;
|
||||||
Info("Multi-server configuration detected. Starting up services for server $Config{ZM_SERVER_ID}\n");
|
Info("Multi-server configuration detected. Starting up services for server $Config{ZM_SERVER_ID}");
|
||||||
$Server = new ZoneMinder::Server($Config{ZM_SERVER_ID});
|
$Server = new ZoneMinder::Server($Config{ZM_SERVER_ID});
|
||||||
$sql = 'SELECT * FROM Monitors WHERE ServerId=?';
|
$sql = 'SELECT * FROM Monitors WHERE ServerId=?';
|
||||||
@values = ( $Config{ZM_SERVER_ID} );
|
@values = ( $Config{ZM_SERVER_ID} );
|
||||||
|
@ -221,16 +223,19 @@ if ( $command =~ /^(?:start|restart)$/ ) {
|
||||||
runCommand("zmdc.pl start zma -m $monitor->{Id}");
|
runCommand("zmdc.pl start zma -m $monitor->{Id}");
|
||||||
}
|
}
|
||||||
if ( $Config{ZM_OPT_CONTROL} ) {
|
if ( $Config{ZM_OPT_CONTROL} ) {
|
||||||
if ( $monitor->{Function} eq 'Modect' || $monitor->{Function} eq 'Mocord' ) {
|
|
||||||
if ( $monitor->{Controllable} && $monitor->{TrackMotion} ) {
|
if ( $monitor->{Controllable} && $monitor->{TrackMotion} ) {
|
||||||
|
if ( $monitor->{Function} eq 'Modect' || $monitor->{Function} eq 'Mocord' ) {
|
||||||
runCommand( "zmdc.pl start zmtrack.pl -m $monitor->{Id}" );
|
runCommand( "zmdc.pl start zmtrack.pl -m $monitor->{Id}" );
|
||||||
}
|
} else {
|
||||||
}
|
Warning(' Monitor is set to track motion, but does not have motion detection enabled.');
|
||||||
}
|
} # end if Has motion enabled
|
||||||
}
|
} # end if track motion
|
||||||
}
|
} # end if ZM_OPT_CONTROL
|
||||||
|
} # end if function is not none or Website
|
||||||
|
} # end foreach monitor
|
||||||
$sth->finish();
|
$sth->finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
my $sql = 'SELECT Id FROM Filters WHERE Background=1';
|
my $sql = 'SELECT Id FROM Filters WHERE Background=1';
|
||||||
my $sth = $dbh->prepare_cached($sql)
|
my $sth = $dbh->prepare_cached($sql)
|
||||||
|
@ -240,7 +245,7 @@ if ( $command =~ /^(?:start|restart)$/ ) {
|
||||||
if ( $sth->rows ) {
|
if ( $sth->rows ) {
|
||||||
while( my $filter = $sth->fetchrow_hashref() ) {
|
while( my $filter = $sth->fetchrow_hashref() ) {
|
||||||
# This is now started unconditionally
|
# This is now started unconditionally
|
||||||
runCommand("zmdc.pl start zmfilter.pl --filter_id=$$filter{Id}");
|
runCommand("zmdc.pl start zmfilter.pl --filter_id=$$filter{Id} --daemon");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
runCommand('zmdc.pl start zmfilter.pl');
|
runCommand('zmdc.pl start zmfilter.pl');
|
||||||
|
@ -283,7 +288,7 @@ if ( $command =~ /^(?:start|restart)$/ ) {
|
||||||
} else {
|
} else {
|
||||||
$retval = 1;
|
$retval = 1;
|
||||||
}
|
}
|
||||||
}
|
} # end if command is start or restart
|
||||||
|
|
||||||
if ( $command eq 'status' ) {
|
if ( $command eq 'status' ) {
|
||||||
my $status = runCommand('zmdc.pl check');
|
my $status = runCommand('zmdc.pl check');
|
||||||
|
@ -302,7 +307,7 @@ sub isActiveSanityCheck {
|
||||||
$dbh = zmDbConnect() if ! $dbh;
|
$dbh = zmDbConnect() if ! $dbh;
|
||||||
|
|
||||||
# PP - First, make sure default exists and there is only one
|
# PP - First, make sure default exists and there is only one
|
||||||
my $sql = "SELECT Name FROM States WHERE Name='default'";
|
my $sql = q`SELECT Name FROM States WHERE Name='default'`;
|
||||||
my $sth = $dbh->prepare_cached($sql)
|
my $sth = $dbh->prepare_cached($sql)
|
||||||
or Fatal("Can't prepare '$sql': ".$dbh->errstr());
|
or Fatal("Can't prepare '$sql': ".$dbh->errstr());
|
||||||
my $res = $sth->execute()
|
my $res = $sth->execute()
|
||||||
|
@ -316,16 +321,15 @@ sub isActiveSanityCheck {
|
||||||
or Fatal( "Can't prepare '$sql': ".$dbh->errstr() );
|
or Fatal( "Can't prepare '$sql': ".$dbh->errstr() );
|
||||||
$res = $sth->execute()
|
$res = $sth->execute()
|
||||||
or Fatal( "Can't execute: ".$sth->errstr() );
|
or Fatal( "Can't execute: ".$sth->errstr() );
|
||||||
$sql = "INSERT INTO States (Name,Definition,IsActive) VALUES ('default','','1');";
|
$sql = q`"INSERT INTO States (Name,Definition,IsActive) VALUES ('default','','1');`;
|
||||||
$sth = $dbh->prepare_cached($sql)
|
$sth = $dbh->prepare_cached($sql)
|
||||||
or Fatal("Can't prepare '$sql': ".$dbh->errstr());
|
or Fatal("Can't prepare '$sql': ".$dbh->errstr());
|
||||||
$res = $sth->execute()
|
$res = $sth->execute()
|
||||||
or Fatal("Can't execute: ".$sth->errstr());
|
or Fatal("Can't execute: ".$sth->errstr());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# PP - Now make sure no two states have IsActive=1
|
# PP - Now make sure no two states have IsActive=1
|
||||||
$sql = "SELECT Name FROM States WHERE IsActive = '1'";
|
$sql = 'SELECT Name FROM States WHERE IsActive = 1';
|
||||||
$sth = $dbh->prepare_cached($sql)
|
$sth = $dbh->prepare_cached($sql)
|
||||||
or Fatal("Can't prepare '$sql': ".$dbh->errstr());
|
or Fatal("Can't prepare '$sql': ".$dbh->errstr());
|
||||||
$res = $sth->execute()
|
$res = $sth->execute()
|
||||||
|
@ -334,51 +338,36 @@ sub isActiveSanityCheck {
|
||||||
if ( $sth->rows != 1 ) {
|
if ( $sth->rows != 1 ) {
|
||||||
Info('Fixing States table so only one run state is active');
|
Info('Fixing States table so only one run state is active');
|
||||||
resetStates();
|
resetStates();
|
||||||
$sql = "UPDATE States SET IsActive='1' WHERE Name='default'";
|
$sql = q`UPDATE States SET IsActive=1 WHERE Name='default'`;
|
||||||
$sth = $dbh->prepare_cached($sql)
|
$sth = $dbh->prepare_cached($sql)
|
||||||
or Fatal("Can't prepare '$sql': ".$dbh->errstr());
|
or Fatal("Can't prepare '$sql': ".$dbh->errstr());
|
||||||
$res = $sth->execute()
|
$res = $sth->execute()
|
||||||
or Fatal("Can't execute: ".$sth->errstr());
|
or Fatal("Can't execute: ".$sth->errstr());
|
||||||
}
|
}
|
||||||
}
|
} # end sub isActiveSanityCheck
|
||||||
|
|
||||||
|
|
||||||
# PP - zeroes out isActive for all states
|
# PP - zeroes out isActive for all states
|
||||||
sub resetStates {
|
sub resetStates {
|
||||||
$dbh = zmDbConnect() if ! $dbh;
|
$dbh = zmDbConnect() if ! $dbh;
|
||||||
my $sql = "UPDATE States SET IsActive='0'";
|
my $sql = 'UPDATE States SET IsActive=0';
|
||||||
my $sth = $dbh->prepare_cached($sql)
|
my $sth = $dbh->prepare_cached($sql)
|
||||||
or Fatal("Can't prepare '$sql': ".$dbh->errstr());
|
or Fatal("Can't prepare '$sql': ".$dbh->errstr());
|
||||||
my $res = $sth->execute()
|
my $res = $sth->execute()
|
||||||
or Fatal("Can't execute: ".$sth->errstr());
|
or Fatal("Can't execute: ".$sth->errstr());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sub systemdRunning {
|
sub systemdRunning {
|
||||||
my $result = 0;
|
|
||||||
|
|
||||||
my $output = qx(ps -o comm="" -p 1);
|
my $output = qx(ps -o comm="" -p 1);
|
||||||
chomp( $output );
|
return scalar ( $output =~ /systemd/ );
|
||||||
|
|
||||||
if ( $output =~ /systemd/ ) {
|
|
||||||
$result = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sub calledBysystem {
|
sub calledBysystem {
|
||||||
my $result = 0;
|
|
||||||
my $ppid = getppid();
|
my $ppid = getppid();
|
||||||
|
|
||||||
my $output = qx(ps -o comm="" -p $ppid);
|
my $output = qx(ps -o comm="" -p $ppid);
|
||||||
chomp( $output );
|
#chomp( $output );
|
||||||
|
|
||||||
if ($output =~ /^(?:systemd|init)$/) {
|
return ($output =~ /^(?:systemd|init)$/);
|
||||||
$result = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sub verifyFolder {
|
sub verifyFolder {
|
||||||
|
@ -394,16 +383,14 @@ sub verifyFolder {
|
||||||
# Not running as web user, so should be root in which case
|
# Not running as web user, so should be root in which case
|
||||||
# chown the directory
|
# chown the directory
|
||||||
my ( $webName, $webPass, $webUid, $webGid ) = getpwnam($Config{ZM_WEB_USER})
|
my ( $webName, $webPass, $webUid, $webGid ) = getpwnam($Config{ZM_WEB_USER})
|
||||||
or Fatal( "Can't get user details for web user '"
|
or Fatal("Can't get details for web user '$Config{ZM_WEB_USER}': $!");
|
||||||
.$Config{ZM_WEB_USER}."': $!"
|
chown($webUid, $webGid, $folder)
|
||||||
|
or Fatal("Can't change ownership of '$folder' to '"
|
||||||
|
.$Config{ZM_WEB_USER}.':'.$Config{ZM_WEB_GROUP}."': $!"
|
||||||
);
|
);
|
||||||
chown( $webUid, $webGid, "$folder" )
|
} # end if runName ne ZM_WEB_USER
|
||||||
or Fatal( "Can't change ownership of directory '$folder' to '"
|
} # end if folder doesn't exist
|
||||||
.$Config{ZM_WEB_USER}.":".$Config{ZM_WEB_GROUP}."': $!"
|
} # end sub verifyFolder
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
1;
|
1;
|
||||||
__END__
|
__END__
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
#include "zm_db.h"
|
#include "zm_db.h"
|
||||||
|
|
||||||
MYSQL dbconn;
|
MYSQL dbconn;
|
||||||
Mutex db_mutex;
|
RecursiveMutex db_mutex;
|
||||||
|
|
||||||
bool zmDbConnected = false;
|
bool zmDbConnected = false;
|
||||||
|
|
||||||
|
@ -98,8 +98,8 @@ MYSQL_RES * zmDbFetch(const char * query) {
|
||||||
db_mutex.lock();
|
db_mutex.lock();
|
||||||
|
|
||||||
if ( mysql_query(&dbconn, query) ) {
|
if ( mysql_query(&dbconn, query) ) {
|
||||||
Error("Can't run query: %s", mysql_error(&dbconn));
|
|
||||||
db_mutex.unlock();
|
db_mutex.unlock();
|
||||||
|
Error("Can't run query: %s", mysql_error(&dbconn));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
Debug(4, "Success running query: %s", query);
|
Debug(4, "Success running query: %s", query);
|
||||||
|
|
|
@ -41,7 +41,7 @@ class zmDbRow {
|
||||||
};
|
};
|
||||||
|
|
||||||
extern MYSQL dbconn;
|
extern MYSQL dbconn;
|
||||||
extern Mutex db_mutex;
|
extern RecursiveMutex db_mutex;
|
||||||
|
|
||||||
bool zmDbConnect();
|
bool zmDbConnect();
|
||||||
void zmDbClose();
|
void zmDbClose();
|
||||||
|
|
|
@ -95,6 +95,15 @@ bool Mutex::locked() {
|
||||||
return( state == EBUSY );
|
return( state == EBUSY );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RecursiveMutex::RecursiveMutex() {
|
||||||
|
pthread_mutexattr_t attr;
|
||||||
|
pthread_mutexattr_init(&attr);
|
||||||
|
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
|
||||||
|
|
||||||
|
if ( pthread_mutex_init(&mMutex, &attr) < 0 )
|
||||||
|
Error("Unable to create pthread mutex: %s", strerror(errno));
|
||||||
|
}
|
||||||
|
|
||||||
Condition::Condition( Mutex &mutex ) : mMutex( mutex ) {
|
Condition::Condition( Mutex &mutex ) : mMutex( mutex ) {
|
||||||
if ( pthread_cond_init( &mCondition, NULL ) < 0 )
|
if ( pthread_cond_init( &mCondition, NULL ) < 0 )
|
||||||
throw ThreadException( stringtf( "Unable to create pthread condition: %s", strerror(errno) ) );
|
throw ThreadException( stringtf( "Unable to create pthread condition: %s", strerror(errno) ) );
|
||||||
|
|
|
@ -70,7 +70,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
pthread_mutex_t *getMutex() {
|
pthread_mutex_t *getMutex() {
|
||||||
return( &mMutex );
|
return &mMutex;
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -82,6 +82,13 @@ public:
|
||||||
bool locked();
|
bool locked();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class RecursiveMutex : public Mutex {
|
||||||
|
private:
|
||||||
|
pthread_mutex_t mMutex;
|
||||||
|
public:
|
||||||
|
RecursiveMutex();
|
||||||
|
};
|
||||||
|
|
||||||
class ScopedMutex {
|
class ScopedMutex {
|
||||||
private:
|
private:
|
||||||
Mutex &mMutex;
|
Mutex &mMutex;
|
||||||
|
|
|
@ -86,7 +86,6 @@ int main( int argc, const char *argv[] ) {
|
||||||
|
|
||||||
zmLoadConfig();
|
zmLoadConfig();
|
||||||
|
|
||||||
|
|
||||||
const char *query = getenv("QUERY_STRING");
|
const char *query = getenv("QUERY_STRING");
|
||||||
if ( query ) {
|
if ( query ) {
|
||||||
Debug(1, "Query: %s", query);
|
Debug(1, "Query: %s", query);
|
||||||
|
@ -204,10 +203,10 @@ int main( int argc, const char *argv[] ) {
|
||||||
Error("Unable to authenticate user");
|
Error("Unable to authenticate user");
|
||||||
logTerm();
|
logTerm();
|
||||||
zmDbClose();
|
zmDbClose();
|
||||||
return( -1 );
|
return -1;
|
||||||
}
|
}
|
||||||
ValidateAccess(user, monitor_id);
|
ValidateAccess(user, monitor_id);
|
||||||
}
|
} // end if config.opt_use_auth
|
||||||
|
|
||||||
hwcaps_detect();
|
hwcaps_detect();
|
||||||
zmSetDefaultTermHandler();
|
zmSetDefaultTermHandler();
|
||||||
|
|
|
@ -22,13 +22,9 @@ if ( sem_acquire($semaphore,1) !== false ) {
|
||||||
if ( file_exists( $localSocketFile ) ) {
|
if ( file_exists( $localSocketFile ) ) {
|
||||||
Warning("sock file $localSocketFile already exists?! Is someone else talking to zms?");
|
Warning("sock file $localSocketFile already exists?! Is someone else talking to zms?");
|
||||||
// They could be. We can maybe have concurrent requests from a browser.
|
// They could be. We can maybe have concurrent requests from a browser.
|
||||||
} else {
|
|
||||||
Logger::Debug("socket file does not exist, we should be good to connect.");
|
|
||||||
}
|
}
|
||||||
if ( ! socket_bind( $socket, $localSocketFile ) ) {
|
if ( ! socket_bind( $socket, $localSocketFile ) ) {
|
||||||
ajaxError("socket_bind( $localSocketFile ) failed: ".socket_strerror(socket_last_error()) );
|
ajaxError("socket_bind( $localSocketFile ) failed: ".socket_strerror(socket_last_error()) );
|
||||||
} else {
|
|
||||||
Logger::Debug("Bound to $localSocketFile");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch ( $_REQUEST['command'] ) {
|
switch ( $_REQUEST['command'] ) {
|
||||||
|
@ -81,7 +77,6 @@ if ( sem_acquire($semaphore,1) !== false ) {
|
||||||
$eSockets = NULL;
|
$eSockets = NULL;
|
||||||
|
|
||||||
$timeout = MSG_TIMEOUT - ( time() - $start_time );
|
$timeout = MSG_TIMEOUT - ( time() - $start_time );
|
||||||
Logger::Debug("TImeout is: $timeout/1000 seconds. " );
|
|
||||||
|
|
||||||
$numSockets = socket_select( $rSockets, $wSockets, $eSockets, intval($timeout/1000), ($timeout%1000)*1000 );
|
$numSockets = socket_select( $rSockets, $wSockets, $eSockets, intval($timeout/1000), ($timeout%1000)*1000 );
|
||||||
|
|
||||||
|
|
|
@ -332,24 +332,17 @@ class MonitorsController extends AppController {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function daemonControl($id, $command, $monitor=null, $daemon=null) {
|
public function daemonControl($id, $command, $monitor=null, $daemon=null) {
|
||||||
$args = '';
|
|
||||||
$daemons = array();
|
$daemons = array();
|
||||||
|
|
||||||
if ( !$monitor ) {
|
if ( !$monitor ) {
|
||||||
// Need to see if it is local or remote
|
// Need to see if it is local or remote
|
||||||
$monitor = $this->Monitor->find('first', array(
|
$monitor = $this->Monitor->find('first', array(
|
||||||
'fields' => array('Type', 'Function'),
|
'fields' => array('Type', 'Function', 'Device'),
|
||||||
'conditions' => array('Id' => $id)
|
'conditions' => array('Id' => $id)
|
||||||
));
|
));
|
||||||
$monitor = $monitor['Monitor'];
|
$monitor = $monitor['Monitor'];
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($monitor['Type'] == 'Local') {
|
|
||||||
$args = '-d ' . $monitor['Device'];
|
|
||||||
} else {
|
|
||||||
$args = '-m ' . $id;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( $monitor['Function'] == 'Monitor' ) {
|
if ( $monitor['Function'] == 'Monitor' ) {
|
||||||
array_push($daemons, 'zmc');
|
array_push($daemons, 'zmc');
|
||||||
} else {
|
} else {
|
||||||
|
@ -359,6 +352,13 @@ class MonitorsController extends AppController {
|
||||||
$zm_path_bin = Configure::read('ZM_PATH_BIN');
|
$zm_path_bin = Configure::read('ZM_PATH_BIN');
|
||||||
|
|
||||||
foreach ($daemons as $daemon) {
|
foreach ($daemons as $daemon) {
|
||||||
|
$args = '';
|
||||||
|
if ( $daemon == 'zmc' and $monitor['Type'] == 'Local') {
|
||||||
|
$args = '-d ' . $monitor['Device'];
|
||||||
|
} else {
|
||||||
|
$args = '-m ' . $id;
|
||||||
|
}
|
||||||
|
|
||||||
$shellcmd = escapeshellcmd("$zm_path_bin/zmdc.pl $command $daemon $args");
|
$shellcmd = escapeshellcmd("$zm_path_bin/zmdc.pl $command $daemon $args");
|
||||||
$status = exec( $shellcmd );
|
$status = exec( $shellcmd );
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ public $defaults = array(
|
||||||
'limit' => 100,
|
'limit' => 100,
|
||||||
'Query' => array(),
|
'Query' => array(),
|
||||||
'sort_field' => ZM_WEB_EVENT_SORT_FIELD,
|
'sort_field' => ZM_WEB_EVENT_SORT_FIELD,
|
||||||
'sort_asc' => ZM_WEB_EVENT_SORT_ORDER == 'asc' ? 'asc' : 'desc',
|
'sort_asc' => ZM_WEB_EVENT_SORT_ORDER,
|
||||||
);
|
);
|
||||||
|
|
||||||
public function __construct( $IdOrRow=NULL ) {
|
public function __construct( $IdOrRow=NULL ) {
|
||||||
|
|
|
@ -476,15 +476,12 @@ if ( canEdit( 'Monitors' ) ) {
|
||||||
);
|
);
|
||||||
|
|
||||||
if ( $_REQUEST['newMonitor']['ServerId'] == 'auto' ) {
|
if ( $_REQUEST['newMonitor']['ServerId'] == 'auto' ) {
|
||||||
Logger::Debug("Auto selecting server");
|
|
||||||
$_REQUEST['newMonitor']['ServerId'] = dbFetchOne('SELECT Id FROM Servers WHERE Status=\'Running\' ORDER BY FreeMem DESC, CpuLoad ASC LIMIT 1', 'Id');
|
$_REQUEST['newMonitor']['ServerId'] = dbFetchOne('SELECT Id FROM Servers WHERE Status=\'Running\' ORDER BY FreeMem DESC, CpuLoad ASC LIMIT 1', 'Id');
|
||||||
Logger::Debug("Auto selecting server: Got " . $_REQUEST['newMonitor']['ServerId'] );
|
Logger::Debug("Auto selecting server: Got " . $_REQUEST['newMonitor']['ServerId'] );
|
||||||
if ( ( ! $_REQUEST['newMonitor'] ) and defined('ZM_SERVER_ID') ) {
|
if ( ( ! $_REQUEST['newMonitor'] ) and defined('ZM_SERVER_ID') ) {
|
||||||
$_REQUEST['newMonitor']['ServerId'] = ZM_SERVER_ID;
|
$_REQUEST['newMonitor']['ServerId'] = ZM_SERVER_ID;
|
||||||
Logger::Debug("Auto selecting server to " . ZM_SERVER_ID);
|
Logger::Debug("Auto selecting server to " . ZM_SERVER_ID);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
Logger::Debug("NOT Auto selecting server" . $_REQUEST['newMonitor']['ServerId']);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$columns = getTableColumns('Monitors');
|
$columns = getTableColumns('Monitors');
|
||||||
|
@ -571,6 +568,7 @@ if ( canEdit( 'Monitors' ) ) {
|
||||||
|
|
||||||
$restart = true;
|
$restart = true;
|
||||||
} # end if count(changes)
|
} # end if count(changes)
|
||||||
|
|
||||||
if (
|
if (
|
||||||
( !isset($_POST['newMonitor']['GroupIds']) )
|
( !isset($_POST['newMonitor']['GroupIds']) )
|
||||||
or
|
or
|
||||||
|
|
|
@ -200,7 +200,7 @@ isset($view) || $view = NULL;
|
||||||
isset($request) || $request = NULL;
|
isset($request) || $request = NULL;
|
||||||
isset($action) || $action = NULL;
|
isset($action) || $action = NULL;
|
||||||
|
|
||||||
if ( ZM_ENABLE_CSRF_MAGIC && $action != 'login' && $view != 'view_video' && $view != 'video' && $request != 'control' && $view != 'frames' && $view != 'archive' ) {
|
if ( ZM_ENABLE_CSRF_MAGIC && $action != 'login' && $view != 'view_video' && $request != 'control' && $view != 'frames' && $view != 'archive' ) {
|
||||||
require_once( 'includes/csrf/csrf-magic.php' );
|
require_once( 'includes/csrf/csrf-magic.php' );
|
||||||
#Logger::Debug("Calling csrf_check with the following values: \$request = \"$request\", \$view = \"$view\", \$action = \"$action\"");
|
#Logger::Debug("Calling csrf_check with the following values: \$request = \"$request\", \$view = \"$view\", \$action = \"$action\"");
|
||||||
csrf_check();
|
csrf_check();
|
||||||
|
|
|
@ -38,13 +38,6 @@
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
#dvrControls input {
|
|
||||||
height: 20px;
|
|
||||||
width: 28px;
|
|
||||||
padding-bottom: 3px;
|
|
||||||
margin: 0 3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#dvrControls input[disabled] {
|
#dvrControls input[disabled] {
|
||||||
color: #aaaaaa;
|
color: #aaaaaa;
|
||||||
}
|
}
|
||||||
|
|
|
@ -375,16 +375,11 @@ function xhtmlFooter() {
|
||||||
global $running;
|
global $running;
|
||||||
if ( canEdit('System') ) {
|
if ( canEdit('System') ) {
|
||||||
include("skins/$skin/views/state.php");
|
include("skins/$skin/views/state.php");
|
||||||
?>
|
|
||||||
<?php
|
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
</body>
|
</body>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">$j('.chosen').chosen();</script>
|
||||||
$j('.chosen').chosen();
|
|
||||||
</script>
|
|
||||||
</html>
|
</html>
|
||||||
<?php
|
<?php
|
||||||
} // end xhtmlFooter
|
} // end xhtmlFooter
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
|
|
@ -192,7 +192,13 @@ if ( currentView != 'none' ) {
|
||||||
});
|
});
|
||||||
|
|
||||||
function getNavBar() {
|
function getNavBar() {
|
||||||
$j.getJSON(thisUrl + '?view=request&request=status&entity=navBar', setNavBar);
|
$j.getJSON(thisUrl + '?view=request&request=status&entity=navBar')
|
||||||
|
.done(setNavBar)
|
||||||
|
.fail(function( jqxhr, textStatus, error ) {
|
||||||
|
var err = textStatus + ", " + error;
|
||||||
|
console.log( "Request Failed: " + err );
|
||||||
|
window.location.href = thisUrl;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function setNavBar(data) {
|
function setNavBar(data) {
|
||||||
|
|
|
@ -223,7 +223,7 @@ ob_start();
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody class="consoleTableBody">
|
<tbody id="consoleTableBody">
|
||||||
<?php
|
<?php
|
||||||
$table_head = ob_get_contents();
|
$table_head = ob_get_contents();
|
||||||
ob_end_clean();
|
ob_end_clean();
|
||||||
|
@ -318,7 +318,7 @@ for( $monitor_i = 0; $monitor_i < count($displayMonitors); $monitor_i += 1 ) {
|
||||||
<?php
|
<?php
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
<td class="colZones"><?php echo makePopupLink( '?view=zones&mid='.$monitor['Id'], 'zmZones', array( 'zones', $monitor['Width'], $monitor['Height'] ), $monitor['ZoneCount'], $running && canView('Monitors') ) ?></td>
|
<td class="colZones"><?php echo makePopupLink('?view=zones&mid='.$monitor['Id'], 'zmZones', array('zones', $monitor['Width'], $monitor['Height']), $monitor['ZoneCount'], canView('Monitors')) ?></td>
|
||||||
<?php
|
<?php
|
||||||
if ( canEdit('Monitors') ) {
|
if ( canEdit('Monitors') ) {
|
||||||
?>
|
?>
|
||||||
|
|
|
@ -279,7 +279,7 @@ foreach( array_map( 'basename', glob('skins/'.$current_skin.'/css/*',GLOB_ONLYDI
|
||||||
<td class="colScheme"><?php echo makePopupLink( '?view=storage&id='.$Storage->Id(), 'zmStorage', 'storage', validHtmlStr($Storage->Scheme()), $canEdit ) ?></td>
|
<td class="colScheme"><?php echo makePopupLink( '?view=storage&id='.$Storage->Id(), 'zmStorage', 'storage', validHtmlStr($Storage->Scheme()), $canEdit ) ?></td>
|
||||||
<td class="colServer"><?php
|
<td class="colServer"><?php
|
||||||
echo makePopupLink( '?view=storage&id='.$Storage->Id(), 'zmStorage', 'storage', validHtmlStr($Storage->Name()), $canEdit ) ?></td>
|
echo makePopupLink( '?view=storage&id='.$Storage->Id(), 'zmStorage', 'storage', validHtmlStr($Storage->Name()), $canEdit ) ?></td>
|
||||||
<td class="colDiskSpace"><?php echo human_filesize($Storage->disk_used_space()) . ' of ' . human_filesize($Storage->disk_total_space()) ?><?td>
|
<td class="colDiskSpace"><?php echo human_filesize($Storage->disk_used_space()) . ' of ' . human_filesize($Storage->disk_total_space()) ?></td>
|
||||||
<td class="colMark"><input type="checkbox" name="markIds[]" value="<?php echo $Storage->Id() ?>" onclick="configureDeleteButton(this);"<?php if ( !$canEdit ) { ?> disabled="disabled"<?php } ?>/></td>
|
<td class="colMark"><input type="checkbox" name="markIds[]" value="<?php echo $Storage->Id() ?>" onclick="configureDeleteButton(this);"<?php if ( !$canEdit ) { ?> disabled="disabled"<?php } ?>/></td>
|
||||||
</tr>
|
</tr>
|
||||||
<?php } #end foreach Server ?>
|
<?php } #end foreach Server ?>
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
if ( !canView('Events') ) {
|
if ( !canView('Events') ) {
|
||||||
$view = "error";
|
$view = 'error';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,6 +82,8 @@ if ( isset($_REQUEST['deleteIndex']) ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( isset($_REQUEST['downloadIndex']) ) {
|
if ( isset($_REQUEST['downloadIndex']) ) {
|
||||||
|
// can't be output buffering, as this file might be large
|
||||||
|
ob_end_clean();
|
||||||
$downloadIndex = validInt($_REQUEST['downloadIndex']);
|
$downloadIndex = validInt($_REQUEST['downloadIndex']);
|
||||||
header('Pragma: public');
|
header('Pragma: public');
|
||||||
header('Expires: 0');
|
header('Expires: 0');
|
||||||
|
@ -123,19 +125,19 @@ if ( isset($_REQUEST['showIndex']) ) {
|
||||||
?>
|
?>
|
||||||
<form name="contentForm" id="contentForm" method="post" action="<?php echo $_SERVER['PHP_SELF'] ?>">
|
<form name="contentForm" id="contentForm" method="post" action="<?php echo $_SERVER['PHP_SELF'] ?>">
|
||||||
<input type="hidden" name="id" value="<?php echo $event['Id'] ?>"/>
|
<input type="hidden" name="id" value="<?php echo $event['Id'] ?>"/>
|
||||||
<table id="contentTable" class="minor" cellspacing="0">
|
<table id="contentTable" class="minor">
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row"><?php echo translate('VideoFormat') ?></th>
|
<th scope="row"><?php echo translate('VideoFormat') ?></th>
|
||||||
<td><?php echo buildSelect( "videoFormat", $videoFormats ) ?></td>
|
<td><?php echo buildSelect('videoFormat', $videoFormats) ?></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row"><?php echo translate('FrameRate') ?></th>
|
<th scope="row"><?php echo translate('FrameRate') ?></th>
|
||||||
<td><?php echo buildSelect( "rate", $rates ) ?></td>
|
<td><?php echo buildSelect('rate', $rates) ?></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row"><?php echo translate('VideoSize') ?></th>
|
<th scope="row"><?php echo translate('VideoSize') ?></th>
|
||||||
<td><?php echo buildSelect( "scale", $scales ) ?></td>
|
<td><?php echo buildSelect('scale', $scales) ?></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row"><?php echo translate('OverwriteExisting') ?></th>
|
<th scope="row"><?php echo translate('OverwriteExisting') ?></th>
|
||||||
|
@ -148,11 +150,17 @@ if ( isset($_REQUEST['showIndex']) ) {
|
||||||
<?php
|
<?php
|
||||||
if ( isset($_REQUEST['generated']) ) {
|
if ( isset($_REQUEST['generated']) ) {
|
||||||
?>
|
?>
|
||||||
<h2 id="videoProgress" class="<?php echo $_REQUEST['generated']?'infoText':'errorText' ?>"><span id="videoProgressText"><?php echo $_REQUEST['generated']?translate('VideoGenSucceeded'):translate('VideoGenFailed') ?></span><span id="videoProgressTicker"></span></h2>
|
<h2 id="videoProgress" class="<?php echo $_REQUEST['generated']?'infoText':'errorText' ?>">
|
||||||
|
<span id="videoProgressText"><?php echo $_REQUEST['generated']?translate('VideoGenSucceeded'):translate('VideoGenFailed') ?></span>
|
||||||
|
<span id="videoProgressTicker"></span>
|
||||||
|
</h2>
|
||||||
<?php
|
<?php
|
||||||
} else {
|
} else {
|
||||||
?>
|
?>
|
||||||
<h2 id="videoProgress" class="hidden warnText"><span id="videoProgressText"><?php echo translate('GeneratingVideo') ?></span><span id="videoProgressTicker"></span></h2>
|
<h2 id="videoProgress" class="hidden warnText">
|
||||||
|
<span id="videoProgressText"><?php echo translate('GeneratingVideo') ?></span>
|
||||||
|
<span id="videoProgressTicker"></span>
|
||||||
|
</h2>
|
||||||
<?php
|
<?php
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
|
@ -164,7 +172,7 @@ if ( isset($_REQUEST['showIndex']) ) {
|
||||||
<?php
|
<?php
|
||||||
} else {
|
} else {
|
||||||
?>
|
?>
|
||||||
<table id="videoTable" class="major" cellspacing="0">
|
<table id="videoTable" class="major">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row"><?php echo translate('Format') ?></th>
|
<th scope="row"><?php echo translate('Format') ?></th>
|
||||||
|
@ -184,11 +192,11 @@ if ( isset($_REQUEST['showIndex']) ) {
|
||||||
$rate = (int)(100 * preg_replace( '/_/', '.', $temp_matches[1] ) );
|
$rate = (int)(100 * preg_replace( '/_/', '.', $temp_matches[1] ) );
|
||||||
$rateText = isset($rates[$rate])?$rates[$rate]:($rate."x");
|
$rateText = isset($rates[$rate])?$rates[$rate]:($rate."x");
|
||||||
} elseif ( preg_match('/^F(.+)$/', $matches[2], $temp_matches) ) {
|
} elseif ( preg_match('/^F(.+)$/', $matches[2], $temp_matches) ) {
|
||||||
$rateText = $temp_matches[1]."fps";
|
$rateText = $temp_matches[1].'fps';
|
||||||
}
|
}
|
||||||
if ( preg_match('/^s(.+)$/', $matches[3], $temp_matches) ) {
|
if ( preg_match('/^s(.+)$/', $matches[3], $temp_matches) ) {
|
||||||
$scale = (int)(100 * preg_replace('/_/', '.', $temp_matches[1]) );
|
$scale = (int)(100 * preg_replace('/_/', '.', $temp_matches[1]) );
|
||||||
$scaleText = isset($scales[$scale])?$scales[$scale]:($scale."x");
|
$scaleText = isset($scales[$scale])?$scales[$scale]:($scale.'x');
|
||||||
} elseif ( preg_match('/^S(.+)$/', $matches[3], $temp_matches) ) {
|
} elseif ( preg_match('/^S(.+)$/', $matches[3], $temp_matches) ) {
|
||||||
$scaleText = $temp_matches[1];
|
$scaleText = $temp_matches[1];
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,7 +85,13 @@ if ( empty($_REQUEST['path']) ) {
|
||||||
$Frame->Delta(1);
|
$Frame->Delta(1);
|
||||||
$Frame->FrameId('snapshot');
|
$Frame->FrameId('snapshot');
|
||||||
}
|
}
|
||||||
|
$Monitor = $Event->Monitor();
|
||||||
|
if ( $Monitor->SaveJPEGs() & 1 ) {
|
||||||
|
# If we store Frames as jpgs, then we don't store a snapshot
|
||||||
|
$path = $Event->Path().'/'.sprintf('%0'.ZM_EVENT_IMAGE_DIGITS.'d',$Frame->FrameId()).'-'.$show.'.jpg';
|
||||||
|
} else {
|
||||||
$path = $Event->Path().'/snapshot.jpg';
|
$path = $Event->Path().'/snapshot.jpg';
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
$Frame = Frame::find_one(array('EventId'=>$_REQUEST['eid'], 'FrameId'=>$_REQUEST['fid']));
|
$Frame = Frame::find_one(array('EventId'=>$_REQUEST['eid'], 'FrameId'=>$_REQUEST['fid']));
|
||||||
|
|
Loading…
Reference in New Issue