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

This commit is contained in:
Isaac Connor 2018-06-09 12:19:50 -04:00
commit 09dae432ce
24 changed files with 418 additions and 389 deletions

View File

@ -4,6 +4,11 @@ What's New
1. See the ZoneMinder release notes for a list of new features:
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
============

View File

@ -4,6 +4,11 @@ What's New
1. See the ZoneMinder release notes for a list of new features:
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
============

View File

@ -26,7 +26,7 @@
%global _hardened_build 1
Name: zoneminder
Version: 1.31.43
Version: 1.31.44
Release: 1%{?dist}
Summary: A camera monitoring and analysis tool
Group: System Environment/Daemons

View File

@ -245,7 +245,8 @@ sub initialise( @ ) {
$tempSyslogLevel = $level if defined($level = $this->getTargettedEnv('LOG_LEVEL_SYSLOG'));
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}
|| $target eq '_'.$this->{id}
|| $target eq $this->{idRoot}
@ -278,6 +279,9 @@ sub initialise( @ ) {
$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}}
.'/'.$codes{$this->{effectiveLevel}}
.', screen='.$codes{$this->{termLevel}}
@ -319,6 +323,8 @@ sub reinitialise {
my $screenLevel = $this->termLevel();
$this->termLevel(NOLOG);
$this->termLevel($screenLevel) if $screenLevel > NOLOG;
$this->{sth} = undef;
}
# 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.
#$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};
}
@ -474,7 +486,7 @@ sub openSyslog {
sub closeSyslog {
my $this = shift;
#closelog();
closelog();
}
sub logFile {
@ -517,17 +529,19 @@ sub logPrint {
if ( $level <= $this->{effectiveLevel} ) {
$string =~ s/[\r\n]+$//g;
my $code = $codes{$level};
if ( $level <= $this->{syslogLevel} ) {
syslog($priorities{$level}, $codes{$level}.' [%s]', $string);
}
my ($seconds, $microseconds) = gettimeofday();
if ( $level <= $this->{fileLevel} or $level <= $this->{termLevel} ) {
my $message = sprintf(
'%s.%06d %s[%d].%s [%s]'
, strftime('%x %H:%M:%S', localtime($seconds))
, $microseconds
, $this->{id}
, $$
, $code
, $codes{$level}
, $string
);
if ( $this->{trace} ) {
@ -535,26 +549,33 @@ sub logPrint {
} else {
$message = $message."\n";
}
if ( $level <= $this->{syslogLevel} ) {
syslog($priorities{$level}, $code.' [%s]', $string);
}
print($LOGFILE $message) if $level <= $this->{fileLevel};
print(STDERR $message) if $level <= $this->{termLevel};
}
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 )';
$this->{sth} = $this->{dbh}->prepare_cached($sql);
$this->{sth} = $this->{dbh}->prepare_cached($sql) if ! $this->{sth};
if ( !$this->{sth} ) {
$this->{databaseLevel} = NOLOG;
Error("Can't prepare log entry '$sql': ".$this->{dbh}->errstr());
} else {
return;
}
my $res = $this->{sth}->execute($seconds+($microseconds/1000000.0)
, $this->{id}
, $$
, $level
, $code
, $codes{$level}
, $string
, $this->{fileName}
);
@ -562,10 +583,6 @@ sub logPrint {
$this->{databaseLevel} = NOLOG;
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 level < effectivelevel
}

View File

@ -139,7 +139,7 @@ foreach my $arg ( @ARGV ) {
# Detaint arguments, if they look ok
#if ( $arg =~ /^(-{0,2}[\w]+)/ )
if ( $arg =~ /^(-{0,2}[\w\/?&=.-]+)$/ ) {
push( @args, $1 );
push @args, $1;
} else {
print(STDERR "Bogus argument '$arg' found");
exit(-1);
@ -245,6 +245,16 @@ our %terminating_processes;
our $zm_terminate = 0;
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;
while( $fd < POSIX::sysconf(&POSIX::_SC_OPEN_MAX) ) {
POSIX::close($fd++);
@ -252,6 +262,8 @@ sub run {
setpgrp();
# dbh got closed with the rest of the fd's above, so need to reconnect.
my $dbh = zmDbConnect(1);
logInit();
dPrint(ZoneMinder::Logger::INFO, 'Server starting at '
@ -259,18 +271,10 @@ sub run {
."\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
killAll(1);
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: $!");
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 . ": $!");
@ -306,7 +310,7 @@ sub run {
$dbh = zmDbConnect();
}
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,
'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());
@ -315,7 +319,6 @@ sub run {
$secs_count += 1;
}
my $nfound = select(my $rout = $rin, undef, undef, $timeout);
Debug("Aftere select $nfound");
if ( $nfound > 0 ) {
if ( vec($rout, fileno(SERVER), 1) ) {
my $paddr = accept(CLIENT, SERVER);
@ -370,9 +373,7 @@ Debug("Aftere select $nfound");
#print( "Select timed out\n" );
}
Debug("restartPending");
restartPending();
Debug("check_for_processes_to_kill");
check_for_processes_to_kill();
} # end while
@ -382,7 +383,7 @@ Debug("check_for_processes_to_kill");
."\n"
);
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}) ) {
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.
sub dPrint {
my $logLevel = shift;
# One thought here, if no client exists to read these... does it block?
if ( fileno(CLIENT) ) {
print CLIENT @_
}
@ -435,12 +437,10 @@ sub start {
my $sigset = POSIX::SigSet->new;
my $blockset = POSIX::SigSet->new(SIGCHLD);
Debug("Blocking SIGCHLD");
sigprocmask(SIG_BLOCK, $blockset, $sigset) or Fatal("Can't block SIGCHLD: $!");
Debug("forking");
if ( my $cpid = fork() ) {
# This logReinit is required. Not sure why.
logReinit();
#logReinit();
$process->{pid} = $cpid;
$process->{started} = time();
@ -453,7 +453,6 @@ sub start {
$cmd_hash{$process->{command}} = $pid_hash{$cpid} = $process;
sigprocmask(SIG_SETMASK, $sigset) or Fatal("Can't restore SIGCHLD: $!");
Debug("unblocking child");
} elsif ( defined($cpid) ) {
# Force reconnection to the db.
$dbh = zmDbConnect(1);
@ -708,7 +707,6 @@ sub reaper {
} # end while waitpid
$SIG{CHLD} = \&reaper;
$! = $saved_status;
Debug("Leaving reaper");
}
sub restartPending {
@ -720,7 +718,6 @@ sub restartPending {
start($process->{daemon}, @{$process->{args}});
}
}
Debug("done restartPending");
}
sub shutdownAll {

View File

@ -70,12 +70,14 @@ use Getopt::Long;
use autouse 'Pod::Usage'=>qw(pod2usage);
use autouse 'Data::Dumper'=>qw(Dumper);
my $daemon = 0;
my $filter_name = '';
my $filter_id;
my $version = 0;
my $zm_terminate = 0;
GetOptions(
'daemon' =>\$daemon,
'filter=s' =>\$filter_name,
'filter_id=s' =>\$filter_id,
'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");
sleep($delay);

View File

@ -41,9 +41,10 @@ use autouse 'Pod::Usage'=>qw(pod2usage);
$ENV{PATH} = '/bin:/usr/bin:/usr/local/bin';
$ENV{SHELL} = '/bin/sh' if exists $ENV{SHELL};
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();
Info("Aftere LogInit");
my $command = $ARGV[0]||'';
if ( $command eq 'version' ) {
@ -53,11 +54,10 @@ if ( $command eq 'version' ) {
my $state;
my $dbh;
my $dbh = zmDbConnect();
Info("Command: $command");
if ( !$command || $command !~ /^(?:start|stop|restart|status|logrot|version)$/ ) {
if ( $command ) {
$dbh = zmDbConnect();
# Check to see if it's a valid run state
my $sql = 'SELECT * FROM States WHERE Name=?';
my $sth = $dbh->prepare_cached($sql)
@ -65,10 +65,10 @@ if ( !$command || $command !~ /^(?:start|stop|restart|status|logrot|version)$/ )
my $res = $sth->execute($command)
or Fatal("Can't execute: ".$sth->errstr());
if ( $state = $sth->fetchrow_hashref() ) {
$state->{Name} = $command;
#$state->{Name} = $command;
$state->{Definitions} = [];
foreach( split( /,/, $state->{Definition} ) ) {
my ( $id, $function, $enabled ) = split( /:/, $_ );
foreach( split(',', $state->{Definition}) ) {
my ( $id, $function, $enabled ) = split(':', $_);
push( @{$state->{Definitions}},
{ Id=>$id, Function=>$function, Enabled=>$enabled }
);
@ -82,24 +82,26 @@ if ( !$command || $command !~ /^(?:start|stop|restart|status|logrot|version)$/ )
if ( !$command ) {
pod2usage(-exitstatus => -1);
}
}
$dbh = zmDbConnect() if ! $dbh;
} # end if not one of the usual commands
# PP - Sane state check
Debug("StartisActiveSSantiyCheck");
isActiveSanityCheck();
Debug("Done isActiveSSantiyCheck");
# Move to the right place
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 = '';
Info( "Command: $command\n" );
Info("Command: $command");
my $retval = 0;
if ( $command eq 'state' ) {
Info( "Updating DB: $state->{Name}\n" );
my $sql = $Config{ZM_SERVER_ID} ? 'SELECT * FROM Monitors WHERE ServerId=? ORDER BY Id ASC' : 'SELECT * FROM Monitors ORDER BY Id ASC';
Info("Updating DB: $state->{Name}");
my $sql = 'SELECT * FROM Monitors' . ($Config{ZM_SERVER_ID} ? ' WHERE ServerId=?' : '' ) .' ORDER BY Id ASC';
my $sth = $dbh->prepare_cached($sql)
or Fatal("Can't prepare '$sql': ".$dbh->errstr());
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());
my $res = $sth->execute($monitor->{NewFunction}, $monitor->{NewEnabled}, $monitor->{Id})
or Fatal("Can't execute: ".$sth->errstr());
}
}
} # end if change of function or enablement
} # end foreach monitor
$sth->finish();
# PP - Now mark a specific state as active
resetStates();
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)
or Fatal("Can't prepare '$sql': ".$dbh->errstr());
$res = $sth->execute($store_state)
@ -139,7 +141,7 @@ chdir( $Config{ZM_PATH_WEB} )
# PP - zero out other states isActive
$command = 'restart';
}
} # end if command = state
# Check if we are running systemd and if we have been called by the system
if ( $command =~ /^(start|stop|restart)$/ ) {
@ -154,6 +156,7 @@ if ( $command =~ /^(start|stop|restart)$/ ) {
if ( $command =~ /^(?:stop|restart)$/ ) {
my $status = runCommand('zmdc.pl check');
Debug("zmdc.pl check = $status");
if ( $status eq 'running' ) {
runCommand('zmdc.pl shutdown');
@ -163,10 +166,9 @@ if ( $command =~ /^(?:stop|restart)$/ ) {
}
}
#runCommand( "zmupdate.pl -f" );
if ( $command =~ /^(?:start|restart)$/ ) {
my $status = runCommand('zmdc.pl check');
Debug("zmdc.pl check = $status");
if ( $status eq 'stopped' ) {
if ( $Config{ZM_DYN_DB_VERSION}
@ -196,7 +198,7 @@ if ( $command =~ /^(?:start|restart)$/ ) {
my @values;
if ( $Config{ZM_SERVER_ID} ) {
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});
$sql = 'SELECT * FROM Monitors WHERE ServerId=?';
@values = ( $Config{ZM_SERVER_ID} );
@ -221,16 +223,19 @@ if ( $command =~ /^(?:start|restart)$/ ) {
runCommand("zmdc.pl start zma -m $monitor->{Id}");
}
if ( $Config{ZM_OPT_CONTROL} ) {
if ( $monitor->{Function} eq 'Modect' || $monitor->{Function} eq 'Mocord' ) {
if ( $monitor->{Controllable} && $monitor->{TrackMotion} ) {
if ( $monitor->{Function} eq 'Modect' || $monitor->{Function} eq 'Mocord' ) {
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();
}
{
my $sql = 'SELECT Id FROM Filters WHERE Background=1';
my $sth = $dbh->prepare_cached($sql)
@ -240,7 +245,7 @@ if ( $command =~ /^(?:start|restart)$/ ) {
if ( $sth->rows ) {
while( my $filter = $sth->fetchrow_hashref() ) {
# 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 {
runCommand('zmdc.pl start zmfilter.pl');
@ -283,7 +288,7 @@ if ( $command =~ /^(?:start|restart)$/ ) {
} else {
$retval = 1;
}
}
} # end if command is start or restart
if ( $command eq 'status' ) {
my $status = runCommand('zmdc.pl check');
@ -302,7 +307,7 @@ sub isActiveSanityCheck {
$dbh = zmDbConnect() if ! $dbh;
# 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)
or Fatal("Can't prepare '$sql': ".$dbh->errstr());
my $res = $sth->execute()
@ -316,16 +321,15 @@ sub isActiveSanityCheck {
or Fatal( "Can't prepare '$sql': ".$dbh->errstr() );
$res = $sth->execute()
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)
or Fatal("Can't prepare '$sql': ".$dbh->errstr());
$res = $sth->execute()
or Fatal("Can't execute: ".$sth->errstr());
}
# 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)
or Fatal("Can't prepare '$sql': ".$dbh->errstr());
$res = $sth->execute()
@ -334,51 +338,36 @@ sub isActiveSanityCheck {
if ( $sth->rows != 1 ) {
Info('Fixing States table so only one run state is active');
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)
or Fatal("Can't prepare '$sql': ".$dbh->errstr());
$res = $sth->execute()
or Fatal("Can't execute: ".$sth->errstr());
}
}
} # end sub isActiveSanityCheck
# PP - zeroes out isActive for all states
sub resetStates {
$dbh = zmDbConnect() if ! $dbh;
my $sql = "UPDATE States SET IsActive='0'";
my $sql = 'UPDATE States SET IsActive=0';
my $sth = $dbh->prepare_cached($sql)
or Fatal("Can't prepare '$sql': ".$dbh->errstr());
my $res = $sth->execute()
or Fatal("Can't execute: ".$sth->errstr());
}
sub systemdRunning {
my $result = 0;
my $output = qx(ps -o comm="" -p 1);
chomp( $output );
if ( $output =~ /systemd/ ) {
$result = 1;
}
return $result;
return scalar ( $output =~ /systemd/ );
}
sub calledBysystem {
my $result = 0;
my $ppid = getppid();
my $output = qx(ps -o comm="" -p $ppid);
chomp( $output );
#chomp( $output );
if ($output =~ /^(?:systemd|init)$/) {
$result = 1;
}
return $result;
return ($output =~ /^(?:systemd|init)$/);
}
sub verifyFolder {
@ -394,16 +383,14 @@ sub verifyFolder {
# Not running as web user, so should be root in which case
# chown the directory
my ( $webName, $webPass, $webUid, $webGid ) = getpwnam($Config{ZM_WEB_USER})
or Fatal( "Can't get user details for web user '"
.$Config{ZM_WEB_USER}."': $!"
or Fatal("Can't get details for 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" )
or Fatal( "Can't change ownership of directory '$folder' to '"
.$Config{ZM_WEB_USER}.":".$Config{ZM_WEB_GROUP}."': $!"
);
}
}
}
} # end if runName ne ZM_WEB_USER
} # end if folder doesn't exist
} # end sub verifyFolder
1;
__END__

View File

@ -24,7 +24,7 @@
#include "zm_db.h"
MYSQL dbconn;
Mutex db_mutex;
RecursiveMutex db_mutex;
bool zmDbConnected = false;
@ -98,8 +98,8 @@ MYSQL_RES * zmDbFetch(const char * query) {
db_mutex.lock();
if ( mysql_query(&dbconn, query) ) {
Error("Can't run query: %s", mysql_error(&dbconn));
db_mutex.unlock();
Error("Can't run query: %s", mysql_error(&dbconn));
return NULL;
}
Debug(4, "Success running query: %s", query);

View File

@ -41,7 +41,7 @@ class zmDbRow {
};
extern MYSQL dbconn;
extern Mutex db_mutex;
extern RecursiveMutex db_mutex;
bool zmDbConnect();
void zmDbClose();

View File

@ -95,6 +95,15 @@ bool Mutex::locked() {
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 ) {
if ( pthread_cond_init( &mCondition, NULL ) < 0 )
throw ThreadException( stringtf( "Unable to create pthread condition: %s", strerror(errno) ) );

View File

@ -70,7 +70,7 @@ public:
private:
pthread_mutex_t *getMutex() {
return( &mMutex );
return &mMutex;
}
public:
@ -82,6 +82,13 @@ public:
bool locked();
};
class RecursiveMutex : public Mutex {
private:
pthread_mutex_t mMutex;
public:
RecursiveMutex();
};
class ScopedMutex {
private:
Mutex &mMutex;

View File

@ -86,7 +86,6 @@ int main( int argc, const char *argv[] ) {
zmLoadConfig();
const char *query = getenv("QUERY_STRING");
if ( query ) {
Debug(1, "Query: %s", query);
@ -204,10 +203,10 @@ int main( int argc, const char *argv[] ) {
Error("Unable to authenticate user");
logTerm();
zmDbClose();
return( -1 );
return -1;
}
ValidateAccess(user, monitor_id);
}
} // end if config.opt_use_auth
hwcaps_detect();
zmSetDefaultTermHandler();

View File

@ -22,13 +22,9 @@ if ( sem_acquire($semaphore,1) !== false ) {
if ( file_exists( $localSocketFile ) ) {
Warning("sock file $localSocketFile already exists?! Is someone else talking to zms?");
// 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 ) ) {
ajaxError("socket_bind( $localSocketFile ) failed: ".socket_strerror(socket_last_error()) );
} else {
Logger::Debug("Bound to $localSocketFile");
}
switch ( $_REQUEST['command'] ) {
@ -81,7 +77,6 @@ if ( sem_acquire($semaphore,1) !== false ) {
$eSockets = NULL;
$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 );

View File

@ -332,24 +332,17 @@ class MonitorsController extends AppController {
}
public function daemonControl($id, $command, $monitor=null, $daemon=null) {
$args = '';
$daemons = array();
if ( !$monitor ) {
// Need to see if it is local or remote
$monitor = $this->Monitor->find('first', array(
'fields' => array('Type', 'Function'),
'fields' => array('Type', 'Function', 'Device'),
'conditions' => array('Id' => $id)
));
$monitor = $monitor['Monitor'];
}
if ($monitor['Type'] == 'Local') {
$args = '-d ' . $monitor['Device'];
} else {
$args = '-m ' . $id;
}
if ( $monitor['Function'] == 'Monitor' ) {
array_push($daemons, 'zmc');
} else {
@ -359,6 +352,13 @@ class MonitorsController extends AppController {
$zm_path_bin = Configure::read('ZM_PATH_BIN');
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");
$status = exec( $shellcmd );
}

View File

@ -20,7 +20,7 @@ public $defaults = array(
'limit' => 100,
'Query' => array(),
'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 ) {

View File

@ -476,15 +476,12 @@ if ( canEdit( 'Monitors' ) ) {
);
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');
Logger::Debug("Auto selecting server: Got " . $_REQUEST['newMonitor']['ServerId'] );
if ( ( ! $_REQUEST['newMonitor'] ) and defined('ZM_SERVER_ID') ) {
$_REQUEST['newMonitor']['ServerId'] = 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');
@ -571,6 +568,7 @@ if ( canEdit( 'Monitors' ) ) {
$restart = true;
} # end if count(changes)
if (
( !isset($_POST['newMonitor']['GroupIds']) )
or

View File

@ -200,7 +200,7 @@ isset($view) || $view = NULL;
isset($request) || $request = 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' );
#Logger::Debug("Calling csrf_check with the following values: \$request = \"$request\", \$view = \"$view\", \$action = \"$action\"");
csrf_check();

View File

@ -38,13 +38,6 @@
text-align: center;
}
#dvrControls input {
height: 20px;
width: 28px;
padding-bottom: 3px;
margin: 0 3px;
}
#dvrControls input[disabled] {
color: #aaaaaa;
}

View File

@ -375,16 +375,11 @@ function xhtmlFooter() {
global $running;
if ( canEdit('System') ) {
include("skins/$skin/views/state.php");
?>
<?php
}
?>
</body>
<script type="text/javascript">
$j('.chosen').chosen();
</script>
<script type="text/javascript">$j('.chosen').chosen();</script>
</html>
<?php
} // end xhtmlFooter
?>

View File

@ -192,7 +192,13 @@ if ( currentView != 'none' ) {
});
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) {

View File

@ -223,7 +223,7 @@ ob_start();
<?php } ?>
</tr>
</thead>
<tbody class="consoleTableBody">
<tbody id="consoleTableBody">
<?php
$table_head = ob_get_contents();
ob_end_clean();
@ -318,7 +318,7 @@ for( $monitor_i = 0; $monitor_i < count($displayMonitors); $monitor_i += 1 ) {
<?php
}
?>
<td class="colZones"><?php echo makePopupLink( '?view=zones&amp;mid='.$monitor['Id'], 'zmZones', array( 'zones', $monitor['Width'], $monitor['Height'] ), $monitor['ZoneCount'], $running && canView('Monitors') ) ?></td>
<td class="colZones"><?php echo makePopupLink('?view=zones&amp;mid='.$monitor['Id'], 'zmZones', array('zones', $monitor['Width'], $monitor['Height']), $monitor['ZoneCount'], canView('Monitors')) ?></td>
<?php
if ( canEdit('Monitors') ) {
?>

View File

@ -279,7 +279,7 @@ foreach( array_map( 'basename', glob('skins/'.$current_skin.'/css/*',GLOB_ONLYDI
<td class="colScheme"><?php echo makePopupLink( '?view=storage&amp;id='.$Storage->Id(), 'zmStorage', 'storage', validHtmlStr($Storage->Scheme()), $canEdit ) ?></td>
<td class="colServer"><?php
echo makePopupLink( '?view=storage&amp;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>
</tr>
<?php } #end foreach Server ?>

View File

@ -19,7 +19,7 @@
//
if ( !canView('Events') ) {
$view = "error";
$view = 'error';
return;
}
@ -82,6 +82,8 @@ if ( isset($_REQUEST['deleteIndex']) ) {
}
if ( isset($_REQUEST['downloadIndex']) ) {
// can't be output buffering, as this file might be large
ob_end_clean();
$downloadIndex = validInt($_REQUEST['downloadIndex']);
header('Pragma: public');
header('Expires: 0');
@ -123,19 +125,19 @@ if ( isset($_REQUEST['showIndex']) ) {
?>
<form name="contentForm" id="contentForm" method="post" action="<?php echo $_SERVER['PHP_SELF'] ?>">
<input type="hidden" name="id" value="<?php echo $event['Id'] ?>"/>
<table id="contentTable" class="minor" cellspacing="0">
<table id="contentTable" class="minor">
<tbody>
<tr>
<th scope="row"><?php echo translate('VideoFormat') ?></th>
<td><?php echo buildSelect( "videoFormat", $videoFormats ) ?></td>
<td><?php echo buildSelect('videoFormat', $videoFormats) ?></td>
</tr>
<tr>
<th scope="row"><?php echo translate('FrameRate') ?></th>
<td><?php echo buildSelect( "rate", $rates ) ?></td>
<td><?php echo buildSelect('rate', $rates) ?></td>
</tr>
<tr>
<th scope="row"><?php echo translate('VideoSize') ?></th>
<td><?php echo buildSelect( "scale", $scales ) ?></td>
<td><?php echo buildSelect('scale', $scales) ?></td>
</tr>
<tr>
<th scope="row"><?php echo translate('OverwriteExisting') ?></th>
@ -148,11 +150,17 @@ if ( isset($_REQUEST['showIndex']) ) {
<?php
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
} 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
}
?>
@ -164,7 +172,7 @@ if ( isset($_REQUEST['showIndex']) ) {
<?php
} else {
?>
<table id="videoTable" class="major" cellspacing="0">
<table id="videoTable" class="major">
<thead>
<tr>
<th scope="row"><?php echo translate('Format') ?></th>
@ -184,11 +192,11 @@ if ( isset($_REQUEST['showIndex']) ) {
$rate = (int)(100 * preg_replace( '/_/', '.', $temp_matches[1] ) );
$rateText = isset($rates[$rate])?$rates[$rate]:($rate."x");
} 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) ) {
$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) ) {
$scaleText = $temp_matches[1];
}

View File

@ -85,7 +85,13 @@ if ( empty($_REQUEST['path']) ) {
$Frame->Delta(1);
$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';
}
} else {
$Frame = Frame::find_one(array('EventId'=>$_REQUEST['eid'], 'FrameId'=>$_REQUEST['fid']));