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

This commit is contained in:
Isaac Connor 2018-04-25 10:31:47 -07:00
commit dd6683f0be
11 changed files with 210 additions and 186 deletions

View File

@ -54,7 +54,7 @@ Depends: ${shlibs:Depends}, ${misc:Depends}, ${perl:Depends}
,liburi-encode-perl ,liburi-encode-perl
,libwww-perl ,libwww-perl
,libdata-uuid-perl ,libdata-uuid-perl
,libnumber-bytes-human ,libnumber-bytes-human-perl
,libfile-slurp-perl ,libfile-slurp-perl
,mysql-client | virtual-mysql-client ,mysql-client | virtual-mysql-client
,perl-modules ,perl-modules

View File

@ -118,7 +118,7 @@ if ( $command eq 'version' ) {
exit(0); exit(0);
} }
my $needs_daemon = $command !~ /(?:startup|shutdown|status|check|logrot|version)/; my $needs_daemon = $command !~ /(?:startup|shutdown|status|check|logrot|version)/;
my $daemon = shift( @ARGV ); my $daemon = shift @ARGV;
if ( $needs_daemon && ! $daemon ) { if ( $needs_daemon && ! $daemon ) {
print(STDERR "No daemon given\n"); print(STDERR "No daemon given\n");
pod2usage(-exitstatus => -1); pod2usage(-exitstatus => -1);
@ -209,7 +209,6 @@ if ( ($command eq 'check') && !$daemon ) {
} }
# The server is there, connect to it # The server is there, connect to it
#print( "Writing commands\n" );
CLIENT->autoflush(); CLIENT->autoflush();
my $message = join(';', $command, ( $daemon ? $daemon : () ), @args ); my $message = join(';', $command, ( $daemon ? $daemon : () ), @args );
print(CLIENT $message); print(CLIENT $message);
@ -218,9 +217,7 @@ while( my $line = <CLIENT> ) {
chomp($line); chomp($line);
print("$line\n"); print("$line\n");
} }
# And we're done!
close(CLIENT); close(CLIENT);
#print( "Finished writing, bye\n" );
exit; exit;
@ -319,7 +316,7 @@ sub run {
next if !$message; next if !$message;
my ( $command, $daemon, @args ) = split( /;/, $message ); my ( $command, $daemon, @args ) = split(';', $message);
if ( $command eq 'start' ) { if ( $command eq 'start' ) {
start($daemon, @args); start($daemon, @args);
@ -425,7 +422,7 @@ sub start {
.strftime('%y/%m/%d %H:%M:%S', localtime($process->{started})) .strftime('%y/%m/%d %H:%M:%S', localtime($process->{started}))
.", pid = $process->{pid}\n" .", pid = $process->{pid}\n"
); );
return(); return;
} }
my $sigset = POSIX::SigSet->new; my $sigset = POSIX::SigSet->new;
@ -436,7 +433,7 @@ sub start {
$process->{pid} = $cpid; $process->{pid} = $cpid;
$process->{started} = time(); $process->{started} = time();
delete( $process->{pending} ); delete $process->{pending};
dPrint(ZoneMinder::Logger::INFO, "'$command' starting at " dPrint(ZoneMinder::Logger::INFO, "'$command' starting at "
.strftime('%y/%m/%d %H:%M:%S', localtime($process->{started})) .strftime('%y/%m/%d %H:%M:%S', localtime($process->{started}))
@ -450,8 +447,7 @@ sub start {
$dbh = zmDbConnect(1); $dbh = zmDbConnect(1);
logReinit(); logReinit();
dPrint( ZoneMinder::Logger::INFO, "'".join( ' ', ( $daemon, @args ) ) dPrint(ZoneMinder::Logger::INFO, "'$command' started at "
."' started at "
.strftime('%y/%m/%d %H:%M:%S', localtime()) .strftime('%y/%m/%d %H:%M:%S', localtime())
."\n" ."\n"
); );
@ -466,7 +462,7 @@ sub start {
foreach my $arg ( @args ) { foreach my $arg ( @args ) {
# Detaint arguments, if they look ok # Detaint arguments, if they look ok
if ( $arg =~ /^(-{0,2}[\w\/?&=.-]+)$/ ) { if ( $arg =~ /^(-{0,2}[\w\/?&=.-]+)$/ ) {
push( @good_args, $1 ); push @good_args, $1;
} else { } else {
Fatal("Bogus argument '$arg' found"); Fatal("Bogus argument '$arg' found");
} }
@ -490,7 +486,7 @@ sub start {
} else { } else {
Fatal("Can't fork: $!"); Fatal("Can't fork: $!");
} }
} } # end sub start
# Sends the stop signal, without waiting around to see if the process died. # Sends the stop signal, without waiting around to see if the process died.
sub send_stop { sub send_stop {
@ -499,7 +495,7 @@ sub send_stop {
my $command = $process->{command}; my $command = $process->{command};
if ( $process->{pending} ) { if ( $process->{pending} ) {
delete( $cmd_hash{$command} ); delete $cmd_hash{$command};
dPrint(ZoneMinder::Logger::INFO, "Command '$command' removed from pending list at " dPrint(ZoneMinder::Logger::INFO, "Command '$command' removed from pending list at "
.strftime('%y/%m/%d %H:%M:%S', localtime()) .strftime('%y/%m/%d %H:%M:%S', localtime())
."\n" ."\n"
@ -522,7 +518,6 @@ sub send_stop {
$process->{pending} = 0; $process->{pending} = 0;
$terminating_processes{$command} = $process; $terminating_processes{$command} = $process;
kill('TERM', $pid); kill('TERM', $pid);
return $pid; return $pid;
} # end sub send_stop } # end sub send_stop
@ -534,6 +529,7 @@ sub check_for_processes_to_kill {
sigprocmask(SIG_BLOCK, $blockset, $sigset) or die "dying at block...\n"; sigprocmask(SIG_BLOCK, $blockset, $sigset) or die "dying at block...\n";
foreach my $command ( %terminating_processes ) { foreach my $command ( %terminating_processes ) {
my $process = $cmd_hash{$command}; my $process = $cmd_hash{$command};
Debug("Have process $command at pid $$process{pid} $$process{term_sent_at}");
if ( $$process{term_sent_at} - time > KILL_DELAY ) { if ( $$process{term_sent_at} - time > KILL_DELAY ) {
dPrint(ZoneMinder::Logger::WARNING, "'$$process{command}' has not stopped at " dPrint(ZoneMinder::Logger::WARNING, "'$$process{command}' has not stopped at "
.strftime('%y/%m/%d %H:%M:%S', localtime()) .strftime('%y/%m/%d %H:%M:%S', localtime())
@ -591,7 +587,7 @@ sub reload {
sub logrot { sub logrot {
logReinit(); logReinit();
foreach my $process ( values(%pid_hash) ) { foreach my $process ( values %pid_hash ) {
if ( $process->{pid} ) { if ( $process->{pid} ) {
# && $process->{command} =~ /^zm.*\.pl/ ) { # && $process->{command} =~ /^zm.*\.pl/ ) {
kill('HUP', $process->{pid}); kill('HUP', $process->{pid});

View File

@ -834,7 +834,7 @@ double Monitor::GetFPS() const {
Snapshot *snap1 = &image_buffer[index1]; Snapshot *snap1 = &image_buffer[index1];
if ( !snap1->timestamp || !snap1->timestamp->tv_sec ) { if ( !snap1->timestamp || !snap1->timestamp->tv_sec ) {
// This should be impossible // This should be impossible
Warning("Impossible situation. No timestamp on captured image"); Warning("Impossible situation. No timestamp on captured image index was %d, image-buffer_count was (%d)", index1, image_buffer_count);
return 0.0; return 0.0;
} }
struct timeval time1 = *snap1->timestamp; struct timeval time1 = *snap1->timestamp;

View File

@ -21,6 +21,7 @@
#include "zm_rtsp_auth.h" #include "zm_rtsp_auth.h"
#include "zm_mem_utils.h" #include "zm_mem_utils.h"
#include "zm_signal.h"
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h> #include <sys/socket.h>
@ -194,7 +195,7 @@ int RemoteCameraHttp::ReadData( Buffer &buffer, unsigned int bytes_expected ) {
int n_found = select(sd+1, &rfds, NULL, NULL, &temp_timeout); int n_found = select(sd+1, &rfds, NULL, NULL, &temp_timeout);
if( n_found == 0 ) { if( n_found == 0 ) {
Debug( 4, "Select timed out timeout was %d secs %d usecs", temp_timeout.tv_sec, temp_timeout.tv_usec ); Debug( 1, "Select timed out timeout was %d secs %d usecs", temp_timeout.tv_sec, temp_timeout.tv_usec );
int error = 0; int error = 0;
socklen_t len = sizeof (error); socklen_t len = sizeof (error);
int retval = getsockopt (sd, SOL_SOCKET, SO_ERROR, &error, &len); int retval = getsockopt (sd, SOL_SOCKET, SO_ERROR, &error, &len);
@ -206,10 +207,10 @@ int RemoteCameraHttp::ReadData( Buffer &buffer, unsigned int bytes_expected ) {
} }
// Why are we disconnecting? It's just a timeout, meaning that data wasn't available. // Why are we disconnecting? It's just a timeout, meaning that data wasn't available.
//Disconnect(); //Disconnect();
return( 0 ); return 0;
} else if ( n_found < 0) { } else if ( n_found < 0) {
Error("Select error: %s", strerror(errno)); Error("Select error: %s", strerror(errno));
return( -1 ); return -1;
} }
unsigned int total_bytes_to_read = 0; unsigned int total_bytes_to_read = 0;
@ -309,13 +310,14 @@ int RemoteCameraHttp::GetResponse()
static RegExpr *content_length_expr = 0; static RegExpr *content_length_expr = 0;
static RegExpr *content_type_expr = 0; static RegExpr *content_type_expr = 0;
while ( ! ( buffer_len = ReadData( buffer ) ) ) { while ( !( buffer_len = ReadData(buffer) ) && !zm_terminate ) {
Debug(4, "Timeout waiting for REGEXP HEADER"); Debug(4, "Timeout waiting for REGEXP HEADER");
} }
if ( buffer_len < 0 ) { if ( buffer_len < 0 ) {
Error( "Unable to read header data" ); Error( "Unable to read header data" );
return( -1 ); return( -1 );
} }
bytes += buffer_len;
if ( !header_expr ) if ( !header_expr )
header_expr = new RegExpr( "^(.+?\r?\n\r?\n)", PCRE_DOTALL ); header_expr = new RegExpr( "^(.+?\r?\n\r?\n)", PCRE_DOTALL );
if ( header_expr->Match( (char*)buffer, buffer.size() ) == 2 ) if ( header_expr->Match( (char*)buffer, buffer.size() ) == 2 )
@ -483,13 +485,14 @@ int RemoteCameraHttp::GetResponse()
else else
{ {
Debug( 3, "Unable to extract subheader from stream, retrying" ); Debug( 3, "Unable to extract subheader from stream, retrying" );
while ( ! ( buffer_len = ReadData( buffer ) ) ) { while ( !( buffer_len = ReadData(buffer) ) && !zm_terminate ) {
Debug(4, "Timeout waiting to extract subheader"); Debug(4, "Timeout waiting to extract subheader");
} }
if ( buffer_len < 0 ) { if ( buffer_len < 0 ) {
Error( "Unable to extract subheader data" ); Error( "Unable to extract subheader data" );
return( -1 ); return( -1 );
} }
bytes += buffer_len;
} }
break; break;
} }
@ -522,13 +525,16 @@ int RemoteCameraHttp::GetResponse()
if ( content_length ) if ( content_length )
{ {
while ( (long)buffer.size() < content_length ) while ( ((long)buffer.size() < content_length ) && ! zm_terminate )
{ {
Debug(3, "Need more data buffer %d < content length %d", buffer.size(), content_length ); Debug(3, "Need more data buffer %d < content length %d", buffer.size(), content_length );
if ( ReadData( buffer ) < 0 ) { int bytes_read = ReadData( buffer );
if ( bytes_read < 0 ) {
Error( "Unable to read content" ); Error( "Unable to read content" );
return( -1 ); return( -1 );
} }
bytes += bytes_read;
} }
Debug( 3, "Got end of image by length, content-length = %d", content_length ); Debug( 3, "Got end of image by length, content-length = %d", content_length );
} }
@ -536,13 +542,14 @@ int RemoteCameraHttp::GetResponse()
{ {
while ( !content_length ) while ( !content_length )
{ {
while ( ! ( buffer_len = ReadData( buffer ) ) ) { while ( !( buffer_len = ReadData(buffer) ) && !zm_terminate ) {
Debug(4, "Timeout waiting for content"); Debug(4, "Timeout waiting for content");
} }
if ( buffer_len < 0 ) { if ( buffer_len < 0 ) {
Error( "Unable to read content" ); Error( "Unable to read content" );
return( -1 ); return( -1 );
} }
bytes += buffer_len;
static RegExpr *content_expr = 0; static RegExpr *content_expr = 0;
if ( mode == MULTI_IMAGE ) if ( mode == MULTI_IMAGE )
{ {
@ -656,13 +663,14 @@ int RemoteCameraHttp::GetResponse()
} }
case HEADERCONT : case HEADERCONT :
{ {
while ( ! ( buffer_len = ReadData( buffer ) ) ) { while ( !( buffer_len = ReadData(buffer) ) && !zm_terminate ) {
Debug(4, "Timeout waiting for HEADERCONT"); Debug(4, "Timeout waiting for HEADERCONT");
} }
if ( buffer_len < 0 ) { if ( buffer_len < 0 ) {
Error( "Unable to read header" ); Error( "Unable to read header" );
return( -1 ); return( -1 );
} }
bytes += buffer_len;
char *crlf = 0; char *crlf = 0;
char *header_ptr = (char *)buffer; char *header_ptr = (char *)buffer;
@ -941,13 +949,14 @@ int RemoteCameraHttp::GetResponse()
state = CONTENT; state = CONTENT;
} else { } else {
Debug( 3, "Unable to extract subheader from stream, retrying" ); Debug( 3, "Unable to extract subheader from stream, retrying" );
while ( ! ( buffer_len = ReadData( buffer ) ) ) { while ( !( buffer_len = ReadData(buffer) ) &&!zm_terminate ) {
Debug(1, "Timeout waiting to extra subheader non regexp"); Debug(1, "Timeout waiting to extra subheader non regexp");
} }
if ( buffer_len < 0 ) { if ( buffer_len < 0 ) {
Error( "Unable to read subheader" ); Error( "Unable to read subheader" );
return( -1 ); return( -1 );
} }
bytes += buffer_len;
state = SUBHEADERCONT; state = SUBHEADERCONT;
} }
break; break;
@ -980,18 +989,19 @@ int RemoteCameraHttp::GetResponse()
} }
if ( content_length ) { if ( content_length ) {
while ( (long)buffer.size() < content_length ) { while ( ( (long)buffer.size() < content_length ) && ! zm_terminate ) {
//int buffer_len = ReadData( buffer, content_length-buffer.size() );
Debug(4, "getting more data"); Debug(4, "getting more data");
if ( ReadData( buffer ) < 0 ) { int bytes_read = ReadData(buffer);
if ( bytes_read < 0 ) {
Error("Unable to read content"); Error("Unable to read content");
return( -1 ); return -1;
} }
bytes += bytes_read;
} }
Debug( 3, "Got end of image by length, content-length = %d", content_length ); Debug( 3, "Got end of image by length, content-length = %d", content_length );
} else { } else {
// Read until we find the end of image or the stream closes. // Read until we find the end of image or the stream closes.
while ( !content_length ) { while ( !content_length && !zm_terminate ) {
Debug(4, "!content_length, ReadData"); Debug(4, "!content_length, ReadData");
buffer_len = ReadData( buffer ); buffer_len = ReadData( buffer );
if ( buffer_len < 0 ) if ( buffer_len < 0 )
@ -999,6 +1009,7 @@ int RemoteCameraHttp::GetResponse()
Error( "Unable to read content" ); Error( "Unable to read content" );
return( -1 ); return( -1 );
} }
bytes += buffer_len;
int buffer_size = buffer.size(); int buffer_size = buffer.size();
if ( buffer_len ) { if ( buffer_len ) {
// Got some data // Got some data

View File

@ -711,7 +711,7 @@ int VideoStore::writeVideoFramePacket(AVPacket *ipkt) {
opkt.dts = video_next_dts; opkt.dts = video_next_dts;
opkt.duration = 0; opkt.duration = 0;
int duration; int64_t duration;
if ( !video_last_pts ) { if ( !video_last_pts ) {
duration = 0; duration = 0;
} else { } else {
@ -723,7 +723,7 @@ int VideoStore::writeVideoFramePacket(AVPacket *ipkt) {
video_last_pts, video_last_pts,
duration); duration);
if (duration < 0) { if (duration < 0) {
duration = ipkt->duration; duration = ipkt->duration ? ipkt->duration : av_rescale_q(1,video_in_stream->time_base, video_out_stream->time_base);
} }
} }

View File

@ -228,6 +228,7 @@ int main(int argc, char *argv[]) {
sigset_t block_set; sigset_t block_set;
sigemptyset(&block_set); sigemptyset(&block_set);
sigaddset(&block_set, SIGHUP);
sigaddset(&block_set, SIGUSR1); sigaddset(&block_set, SIGUSR1);
sigaddset(&block_set, SIGUSR2); sigaddset(&block_set, SIGUSR2);

View File

@ -256,6 +256,9 @@ private $control_fields = array(
public function set($data) { public function set($data) {
foreach ($data as $k => $v) { foreach ($data as $k => $v) {
if ( method_exists($this, $k) ) {
$this->{$k}($v);
} else {
if ( is_array( $v ) ) { if ( is_array( $v ) ) {
# perhaps should turn into a comma-separated string # perhaps should turn into a comma-separated string
$this->{$k} = implode(',',$v); $this->{$k} = implode(',',$v);
@ -269,7 +272,8 @@ private $control_fields = array(
Error( "Unknown type $k => $v of var " . gettype( $v ) ); Error( "Unknown type $k => $v of var " . gettype( $v ) );
$this->{$k} = $v; $this->{$k} = $v;
} }
} } # end if method_exists
} # end foreach $data as $k=>$v
} }
public static function find_all( $parameters = null, $options = null ) { public static function find_all( $parameters = null, $options = null ) {
$filters = array(); $filters = array();
@ -400,10 +404,20 @@ private $control_fields = array(
} }
} // end if we are on the recording server } // end if we are on the recording server
} }
public function GroupIds( ) { public function GroupIds( $new='') {
if ( $new != '' ) {
if(!is_array($new)) {
$this->{'GroupIds'} = array($new);
} else {
$this->{'GroupIds'} = $new;
}
}
if ( !array_key_exists('GroupIds', $this) ) { if ( !array_key_exists('GroupIds', $this) ) {
if ( array_key_exists('Id', $this) and $this->{'Id'} ) { if ( array_key_exists('Id', $this) and $this->{'Id'} ) {
$this->{'GroupIds'} = dbFetchAll('SELECT GroupId FROM Groups_Monitors WHERE MonitorId=?', 'GroupId', array($this->{'Id'}) ); $this->{'GroupIds'} = dbFetchAll('SELECT GroupId FROM Groups_Monitors WHERE MonitorId=?', 'GroupId', array($this->{'Id'}) );
if ( ! $this->{'GroupIds'} )
$this->{'GroupIds'} = array();
} else { } else {
$this->{'GroupIds'} = array(); $this->{'GroupIds'} = array();
} }

View File

@ -565,6 +565,8 @@ if ( canEdit( 'Monitors' ) ) {
return; return;
} }
$restart = true;
} # end if count(changes)
if ( if (
( !isset($_POST['newMonitor']['GroupIds']) ) ( !isset($_POST['newMonitor']['GroupIds']) )
or or
@ -581,8 +583,6 @@ if ( canEdit( 'Monitors' ) ) {
} }
} }
} // end if there has been a change of groups } // end if there has been a change of groups
$restart = true;
} # end if count(changes)
if ( ZM_OPT_X10 ) { if ( ZM_OPT_X10 ) {
$x10Changes = getFormChanges( $x10Monitor, $_REQUEST['newX10Monitor'] ); $x10Changes = getFormChanges( $x10Monitor, $_REQUEST['newX10Monitor'] );

View File

@ -133,10 +133,7 @@ function dbQuery( $sql, $params=NULL ) {
} }
} else { } else {
if ( defined('ZM_DB_DEBUG') ) { if ( defined('ZM_DB_DEBUG') ) {
if ( $params ) Logger::Debug("SQL: $sql values:" . $params?implode(',',$params):'' );
Warning("SQL: $sql" . implode(',',$params) );
else
Warning("SQL: $sql:" );
} }
$result = $dbConn->query($sql); $result = $dbConn->query($sql);
} }
@ -186,7 +183,7 @@ function dbFetchAll( $sql, $col=false, $params=NULL ) {
$dbRows = array(); $dbRows = array();
while( $dbRow = $result->fetch( PDO::FETCH_ASSOC ) ) while( $dbRow = $result->fetch( PDO::FETCH_ASSOC ) )
$dbRows[] = $col?$dbRow[$col]:$dbRow; $dbRows[] = $col?$dbRow[$col]:$dbRow;
return( $dbRows ); return $dbRows;
} }
function dbFetchAssoc( $sql, $indexCol, $dataCol=false ) { function dbFetchAssoc( $sql, $indexCol, $dataCol=false ) {

View File

@ -486,7 +486,7 @@ function getFormChanges( $values, $newValues, $types=false, $columns=false ) {
$types = array(); $types = array();
foreach( $newValues as $key=>$value ) { foreach( $newValues as $key=>$value ) {
if ( $columns && !$columns[$key] ) if ( $columns && !isset($columns[$key]) )
continue; continue;
if ( !isset($types[$key]) ) if ( !isset($types[$key]) )

View File

@ -62,7 +62,7 @@ if ( ! $monitor ) {
$nextId = getTableAutoInc( 'Monitors' ); $nextId = getTableAutoInc( 'Monitors' );
if ( isset( $_REQUEST['dupId'] ) ) { if ( isset( $_REQUEST['dupId'] ) ) {
$monitor = new Monitor( $_REQUEST['dupId'] ); $monitor = new Monitor( $_REQUEST['dupId'] );
$monitor->GroupIds(); // have to lead before we change the Id $monitor->GroupIds(); // have to load before we change the Id
if ( ZM_OPT_X10 ) if ( ZM_OPT_X10 )
$x10Monitor = dbFetchOne( 'SELECT * FROM TriggersX10 WHERE MonitorId = ?', NULL, array($_REQUEST['dupId']) ); $x10Monitor = dbFetchOne( 'SELECT * FROM TriggersX10 WHERE MonitorId = ?', NULL, array($_REQUEST['dupId']) );
$clonedName = $monitor->Name(); $clonedName = $monitor->Name();
@ -534,6 +534,11 @@ if ( $tab != 'general' ) {
<input type="hidden" name="newMonitor[Name]" value="<?php echo validHtmlStr($monitor->Name()) ?>"/> <input type="hidden" name="newMonitor[Name]" value="<?php echo validHtmlStr($monitor->Name()) ?>"/>
<input type="hidden" name="newMonitor[ServerId]" value="<?php echo validHtmlStr($monitor->ServerId() ) ?>"/> <input type="hidden" name="newMonitor[ServerId]" value="<?php echo validHtmlStr($monitor->ServerId() ) ?>"/>
<input type="hidden" name="newMonitor[StorageId]" value="<?= validHtmlStr($monitor->StorageId() ) ?>"/> <input type="hidden" name="newMonitor[StorageId]" value="<?= validHtmlStr($monitor->StorageId() ) ?>"/>
<?php
foreach ( $monitor->GroupIds() as $group_id ) {
echo '<input type="hidden" name="newMonitor[GroupIds][]" value="'.$group_id.'"/>';
}
?>
<input type="hidden" name="newMonitor[Type]" value="<?php echo validHtmlStr($monitor->Type()) ?>"/> <input type="hidden" name="newMonitor[Type]" value="<?php echo validHtmlStr($monitor->Type()) ?>"/>
<input type="hidden" name="newMonitor[Function]" value="<?php echo validHtmlStr($monitor->Function()) ?>"/> <input type="hidden" name="newMonitor[Function]" value="<?php echo validHtmlStr($monitor->Function()) ?>"/>
<input type="hidden" name="newMonitor[Enabled]" value="<?php echo validHtmlStr($monitor->Enabled()) ?>"/> <input type="hidden" name="newMonitor[Enabled]" value="<?php echo validHtmlStr($monitor->Enabled()) ?>"/>