Merge branch 'release-1.34' of github.com:ZoneMinder/zoneminder into release-1.34

This commit is contained in:
Isaac Connor 2020-05-08 17:26:02 -04:00
commit 1f6e68c129
31 changed files with 732 additions and 528 deletions

View File

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

View File

@ -33,37 +33,33 @@
// Class used for storing a box, which is defined as a region
// defined by two coordinates
//
class Box
{
class Box {
private:
Coord lo, hi;
Coord size;
public:
inline Box()
{
}
inline Box() { }
explicit inline Box( int p_size ) : lo( 0, 0 ), hi ( p_size-1, p_size-1 ), size( Coord::Range( hi, lo ) ) { }
inline Box( int p_x_size, int p_y_size ) : lo( 0, 0 ), hi ( p_x_size-1, p_y_size-1 ), size( Coord::Range( hi, lo ) ) { }
inline Box( int lo_x, int lo_y, int hi_x, int hi_y ) : lo( lo_x, lo_y ), hi( hi_x, hi_y ), size( Coord::Range( hi, lo ) ) { }
inline Box( const Coord &p_lo, const Coord &p_hi ) : lo( p_lo ), hi( p_hi ), size( Coord::Range( hi, lo ) ) { }
inline const Coord &Lo() const { return( lo ); }
inline int LoX() const { return( lo.X() ); }
inline int LoY() const { return( lo.Y() ); }
inline const Coord &Hi() const { return( hi ); }
inline int HiX() const { return( hi.X() ); }
inline int HiY() const { return( hi.Y() ); }
inline const Coord &Size() const { return( size ); }
inline int Width() const { return( size.X() ); }
inline int Height() const { return( size.Y() ); }
inline int Area() const { return( size.X()*size.Y() ); }
inline const Coord &Lo() const { return lo; }
inline int LoX() const { return lo.X(); }
inline int LoY() const { return lo.Y(); }
inline const Coord &Hi() const { return hi; }
inline int HiX() const { return hi.X(); }
inline int HiY() const { return hi.Y(); }
inline const Coord &Size() const { return size; }
inline int Width() const { return size.X(); }
inline int Height() const { return size.Y(); }
inline int Area() const { return size.X()*size.Y(); }
inline const Coord Centre() const
{
inline const Coord Centre() const {
int mid_x = int(round(lo.X()+(size.X()/2.0)));
int mid_y = int(round(lo.Y()+(size.Y()/2.0)));
return( Coord( mid_x, mid_y ) );
return Coord( mid_x, mid_y );
}
inline bool Inside( const Coord &coord ) const
{

View File

@ -63,7 +63,9 @@ void zmLoadConfig() {
closedir(configSubFolder);
}
zmDbConnect();
if ( !zmDbConnect() ) {
Fatal("Can't connect to db. Can't continue.");
}
config.Load();
config.Assign();

View File

@ -25,8 +25,7 @@
//
// Class used for storing an x,y pair, i.e. a coordinate
//
class Coord
{
class Coord {
private:
int x, y;
@ -44,8 +43,7 @@ public:
inline int &Y() { return( y ); }
inline const int &Y() const { return( y ); }
inline static Coord Range( const Coord &coord1, const Coord &coord2 )
{
inline static Coord Range( const Coord &coord1, const Coord &coord2 ) {
Coord result( (coord1.x-coord2.x)+1, (coord1.y-coord2.y)+1 );
return( result );
}

View File

@ -164,7 +164,22 @@ bool EventStream::loadEventData(uint64_t event_id) {
event_data->Orientation = (Monitor::Orientation)(dbrow[8] == NULL ? 0 : atoi(dbrow[8]));
mysql_free_result(result);
Storage * storage = new Storage(event_data->storage_id);
if ( !monitor ) {
monitor = Monitor::Load(event_data->monitor_id, false, Monitor::QUERY);
} else if ( monitor->Id() != event_data->monitor_id ) {
delete monitor;
monitor = Monitor::Load(event_data->monitor_id, false, Monitor::QUERY);
}
if ( !monitor ) {
Fatal("Unable to load monitor id %d for streaming", event_data->monitor_id);
}
if ( !storage ) {
storage = new Storage(event_data->storage_id);
} else if ( storage->Id() != event_data->storage_id ) {
delete storage;
storage = new Storage(event_data->storage_id);
}
const char *storage_path = storage->Path();
if ( event_data->scheme == Storage::DEEP ) {
@ -206,7 +221,6 @@ bool EventStream::loadEventData(uint64_t event_id) {
staticConfig.PATH_WEB.c_str(), storage_path, event_data->monitor_id,
event_data->event_id);
}
delete storage; storage = NULL;
updateFrameRate((double)event_data->frame_count/event_data->duration);
Debug(3, "fps set by frame_count(%d)/duration(%f)",
@ -246,7 +260,7 @@ bool EventStream::loadEventData(uint64_t event_id) {
event_data->frames[i-1].timestamp = last_timestamp + ((i-last_id)*frame_delta);
event_data->frames[i-1].offset = event_data->frames[i-1].timestamp - event_data->start_time;
event_data->frames[i-1].in_db = false;
Debug(3,"Frame %d timestamp:(%f), offset(%f) delta(%f), in_db(%d)",
Debug(3, "Frame %d timestamp:(%f), offset(%f) delta(%f), in_db(%d)",
i,
event_data->frames[i-1].timestamp,
event_data->frames[i-1].offset,
@ -277,7 +291,10 @@ bool EventStream::loadEventData(uint64_t event_id) {
mysql_free_result(result);
if ( event_data->video_file[0] ) {
if ( event_data->video_file[0] || (monitor->GetOptVideoWriter() > 0) ) {
if ( !event_data->video_file[0] ) {
snprintf(event_data->video_file, sizeof(event_data->video_file), "%" PRIu64 "-%s", event_data->event_id, "video.mp4");
}
std::string filepath = std::string(event_data->path) + "/" + std::string(event_data->video_file);
//char filepath[PATH_MAX];
//snprintf(filepath, sizeof(filepath), "%s/%s", event_data->path, event_data->video_file);
@ -305,7 +322,7 @@ bool EventStream::loadEventData(uint64_t event_id) {
void EventStream::processCommand(const CmdMsg *msg) {
Debug(2, "Got message, type %d, msg %d", msg->msg_type, msg->msg_data[0]);
// Check for incoming command
switch( (MsgCommand)msg->msg_data[0] ) {
switch ( (MsgCommand)msg->msg_data[0] ) {
case CMD_PAUSE :
Debug(1, "Got PAUSE command");
@ -657,7 +674,8 @@ bool EventStream::sendFrame(int delta_us) {
Image *send_image = prepareImage(&image);
if ( !vid_stream ) {
vid_stream = new VideoStream("pipe:", format, bitrate, effective_fps, send_image->Colours(), send_image->SubpixelOrder(), send_image->Width(), send_image->Height());
vid_stream = new VideoStream("pipe:", format, bitrate, effective_fps,
send_image->Colours(), send_image->SubpixelOrder(), send_image->Width(), send_image->Height());
fprintf(stdout, "Content-type: %s\r\n\r\n", vid_stream->MimeType());
vid_stream->OpenStream();
}
@ -700,9 +718,10 @@ Debug(1, "Loading image");
} else if ( ffmpeg_input ) {
// Get the frame from the mp4 input
Debug(1,"Getting frame from ffmpeg");
AVFrame *frame;
FrameData *frame_data = &event_data->frames[curr_frame_id-1];
frame = ffmpeg_input->get_frame( ffmpeg_input->get_video_stream_id(), frame_data->offset );
AVFrame *frame = ffmpeg_input->get_frame(
ffmpeg_input->get_video_stream_id(),
frame_data->offset);
if ( frame ) {
image = new Image(frame);
//av_frame_free(&frame);
@ -982,8 +1001,8 @@ void EventStream::runStream() {
// you can calculate the relationship between now and the start
// or calc the relationship from the last frame. I think from the start is better as it self-corrects
if ( send_frame && type != STREAM_MPEG ) {
if ( delta_us > 0) {
if ( send_frame && (type != STREAM_MPEG) ) {
if ( delta_us > 0 ) {
if ( delta_us > MAX_SLEEP_USEC ) {
Debug(1, "Limiting sleep to %d because calculated sleep is too long %d", MAX_SLEEP_USEC, delta_us);
delta_us = MAX_SLEEP_USEC;
@ -1026,18 +1045,12 @@ void EventStream::runStream() {
closeComms();
} // void EventStream::runStream()
void EventStream::setStreamStart( uint64_t init_event_id, unsigned int init_frame_id=0 ) {
void EventStream::setStreamStart(
uint64_t init_event_id,
unsigned int init_frame_id=0) {
loadInitialEventData(init_event_id, init_frame_id);
if ( !(monitor = Monitor::Load(event_data->monitor_id, false, Monitor::QUERY)) ) {
Fatal("Unable to load monitor id %d for streaming", event_data->monitor_id);
return;
}
}
} // end void EventStream::setStreamStart(init_event_id,init_frame_id=0)
void EventStream::setStreamStart(int monitor_id, time_t event_time) {
loadInitialEventData(monitor_id, event_time);
if ( !(monitor = Monitor::Load(event_data->monitor_id, false, Monitor::QUERY)) ) {
Fatal("Unable to load monitor id %d for streaming", monitor_id);
return;
}
}

View File

@ -20,9 +20,6 @@
#ifndef ZM_EVENTSTREAM_H
#define ZM_EVENTSTREAM_H
#include <set>
#include <map>
#include "zm_image.h"
#include "zm_stream.h"
#include "zm_video.h"
@ -83,7 +80,6 @@ class EventStream : public StreamBase {
struct timeval start; // clock time when started the event
EventData *event_data;
FFmpeg_Input *ffmpeg_input;
protected:
bool loadEventData( uint64_t event_id );
@ -95,24 +91,41 @@ class EventStream : public StreamBase {
bool sendFrame( int delta_us );
public:
EventStream() {
mode = DEFAULT_MODE;
replay_rate = DEFAULT_RATE;
forceEventChange = false;
curr_frame_id = 0;
curr_stream_time = 0.0;
send_frame = false;
event_data = 0;
EventStream() :
mode(DEFAULT_MODE),
forceEventChange(false),
curr_frame_id(0),
curr_stream_time(0.0),
send_frame(false),
event_data(0),
storage(NULL),
ffmpeg_input(NULL),
// Used when loading frames from an mp4
input_codec_context = 0;
input_codec = 0;
input_codec_context(0),
input_codec(0)
{}
~EventStream() {
if ( event_data ) {
if ( event_data->frames ) {
delete[] event_data->frames;
event_data->frames = NULL;
}
delete event_data;
event_data = NULL;
}
if ( monitor ) {
delete monitor;
monitor = NULL;
}
if ( storage ) {
delete storage;
storage = NULL;
}
if ( ffmpeg_input ) {
delete ffmpeg_input;
ffmpeg_input = NULL;
}
}
void setStreamStart( uint64_t init_event_id, unsigned int init_frame_id );
void setStreamStart( int monitor_id, time_t event_time );
void setStreamMode( StreamMode p_mode ) {
@ -121,6 +134,8 @@ class EventStream : public StreamBase {
void runStream();
Image *getImage();
private:
Storage *storage;
FFmpeg_Input *ffmpeg_input;
AVCodecContext *input_codec_context;
AVCodec *input_codec;
};

View File

@ -321,6 +321,7 @@ void zm_dump_codecpar(const AVCodecParameters *par);
frame->pts \
);
#if LIBAVUTIL_VERSION_CHECK(54, 4, 0, 74, 100)
#define zm_dump_video_frame(frame,text) Debug(1, "%s: format %d %s %dx%d linesize:%dx%d pts: %" PRId64, \
text, \
frame->format, \
@ -331,6 +332,18 @@ void zm_dump_codecpar(const AVCodecParameters *par);
frame->pts \
);
#else
#define zm_dump_video_frame(frame,text) Debug(1, "%s: format %d %s %dx%d linesize:%dx%d pts: %" PRId64, \
text, \
frame->format, \
"unsupported", \
frame->width, \
frame->height, \
frame->linesize[0], frame->linesize[1], \
frame->pts \
);
#endif
#if LIBAVCODEC_VERSION_CHECK(56, 8, 0, 60, 100)
#define zm_av_packet_unref( packet ) av_packet_unref( packet )
#define zm_av_packet_ref( dst, src ) av_packet_ref( dst, src )

View File

@ -15,10 +15,26 @@ FFmpeg_Input::FFmpeg_Input() {
FFmpeg_Input::~FFmpeg_Input() {
if ( streams ) {
for ( unsigned int i = 0; i < input_format_context->nb_streams; i += 1 ) {
avcodec_close(streams[i].context);
streams[i].context = NULL;
}
delete streams;
streams = NULL;
}
}
if ( frame ) {
av_frame_free(&frame);
frame = NULL;
}
if ( input_format_context ) {
#if !LIBAVFORMAT_VERSION_CHECK(53, 17, 0, 25, 0)
av_close_input_file(input_format_context);
#else
avformat_close_input(&input_format_context);
#endif
input_format_context = NULL;
}
} // end ~FFmpeg_Input()
int FFmpeg_Input::Open(const char *filepath) {
@ -90,6 +106,7 @@ int FFmpeg_Input::Open(const char *filepath) {
avcodec_free_context(&streams[i].context);
#endif
avformat_close_input(&input_format_context);
input_format_context = NULL;
return error;
}
} // end foreach stream
@ -103,7 +120,6 @@ int FFmpeg_Input::Open(const char *filepath) {
} // end int FFmpeg_Input::Open( const char * filepath )
AVFrame *FFmpeg_Input::get_frame(int stream_id) {
int frameComplete = false;
AVPacket packet;
av_init_packet(&packet);
@ -139,8 +155,8 @@ AVFrame *FFmpeg_Input::get_frame(int stream_id) {
}
ret = zm_send_packet_receive_frame(context, frame, packet);
if ( ret < 0 ) {
Error("Unable to decode frame at frame %d: %s, continuing",
streams[packet.stream_index].frame_count, av_make_error_string(ret).c_str());
Error("Unable to decode frame at frame %d: %d %s, continuing",
streams[packet.stream_index].frame_count, ret, av_make_error_string(ret).c_str());
zm_av_packet_unref(&packet);
av_frame_free(&frame);
continue;
@ -214,12 +230,14 @@ AVFrame *FFmpeg_Input::get_frame(int stream_id, double at) {
if ( frame->pts <= seek_target ) {
zm_dump_frame(frame, "pts <= seek_target");
while ( frame && (frame->pts < seek_target) ) {
if ( !get_frame(stream_id) )
if ( !get_frame(stream_id) ) {
Warning("Got no frame. returning nothing");
return frame;
}
}
zm_dump_frame(frame, "frame->pts <= seek_target, got");
return frame;
}
return get_frame(stream_id);
} // end AVFrame *FFmpeg_Input::get_frame( int stream_id, struct timeval at)

View File

@ -48,6 +48,8 @@ static short *g_v_table;
static short *g_u_table;
static short *b_u_table;
struct SwsContext *sws_convert_context = NULL;
jpeg_compress_struct *Image::writejpg_ccinfo[101] = { 0 };
jpeg_compress_struct *Image::encodejpg_ccinfo[101] = { 0 };
jpeg_decompress_struct *Image::readjpg_dcinfo = 0;
@ -160,15 +162,17 @@ Image::Image( int p_width, int p_height, int p_colours, int p_subpixelorder, uin
update_function_pointers();
}
Image::Image( const AVFrame *frame ) {
Image::Image(const AVFrame *frame) {
AVFrame *dest_frame = zm_av_frame_alloc();
text[0] = '\0';
width = frame->width;
height = frame->height;
pixels = width*height;
colours = ZM_COLOUR_RGB32;
subpixelorder = ZM_SUBPIX_ORDER_RGBA;
size = pixels*colours;
buffer = 0;
holdbuffer = 0;
@ -183,26 +187,28 @@ Image::Image( const AVFrame *frame ) {
#endif
#if HAVE_LIBSWSCALE
struct SwsContext *mConvertContext = sws_getContext(
sws_convert_context = sws_getCachedContext(
sws_convert_context,
width,
height,
(AVPixelFormat)frame->format,
width, height,
AV_PIX_FMT_RGBA, SWS_BICUBIC, NULL,
NULL, NULL);
if ( mConvertContext == NULL )
Fatal( "Unable to create conversion context" );
if ( sws_convert_context == NULL )
Fatal("Unable to create conversion context");
if ( sws_scale(mConvertContext, frame->data, frame->linesize, 0, frame->height, dest_frame->data, dest_frame->linesize) < 0 )
if ( sws_scale(sws_convert_context, frame->data, frame->linesize, 0, frame->height,
dest_frame->data, dest_frame->linesize) < 0 )
Fatal("Unable to convert raw format %u to target format %u", frame->format, AV_PIX_FMT_RGBA);
#else // HAVE_LIBSWSCALE
Fatal("You must compile ffmpeg with the --enable-swscale option to use ffmpeg cameras");
#endif // HAVE_LIBSWSCALE
av_frame_free( &dest_frame );
av_frame_free(&dest_frame);
update_function_pointers();
}
} // end Image::Image(const AVFrame *frame)
Image::Image( const Image &p_image ) {
Image::Image(const Image &p_image) {
if ( !initialised )
Initialise();
width = p_image.width;
@ -215,7 +221,7 @@ Image::Image( const Image &p_image ) {
holdbuffer = 0;
AllocImgBuffer(size);
(*fptr_imgbufcpy)(buffer, p_image.buffer, size);
strncpy( text, p_image.text, sizeof(text) );
strncpy(text, p_image.text, sizeof(text));
update_function_pointers();
}
@ -225,7 +231,7 @@ Image::~Image() {
/* Should be called as part of program shutdown to free everything */
void Image::Deinitialise() {
if ( initialised ) {
if ( !initialised ) return;
/*
delete[] y_table;
delete[] uv_table;
@ -252,8 +258,12 @@ void Image::Deinitialise() {
writejpg_ccinfo[quality] = NULL;
}
} // end foreach quality
if ( sws_convert_context ) {
sws_freeContext(sws_convert_context);
sws_convert_context = NULL;
}
}
} // end void Image::Deinitialise()
void Image::Initialise() {
/* Assign the blend pointer to function */
@ -655,15 +665,16 @@ void Image::Assign( const Image &image ) {
return;
}
if ( !buffer || image.width != width || image.height != height || image.colours != colours || image.subpixelorder != subpixelorder) {
if ( !buffer || image.width != width || image.height != height
|| image.colours != colours || image.subpixelorder != subpixelorder) {
if (holdbuffer && buffer) {
if (new_size > allocation) {
if ( holdbuffer && buffer ) {
if ( new_size > allocation ) {
Error("Held buffer is undersized for assigned buffer");
return;
}
} else {
if(new_size > allocation || !buffer) {
if ( new_size > allocation || !buffer) {
// DumpImgBuffer(); This is also done in AllocImgBuffer
AllocImgBuffer(new_size);
}

View File

@ -121,7 +121,7 @@ protected:
};
inline void DumpImgBuffer() {
DumpBuffer(buffer,buffertype);
DumpBuffer(buffer, buffertype);
buffer = NULL;
allocation = 0;
}

View File

@ -1655,7 +1655,7 @@ bool Monitor::Analyse() {
Info("%s: %03d - Left alarm state (%" PRIu64 ") - %d(%d) images",
name, image_count, event->Id(), event->Frames(), event->AlarmFrames());
//if ( function != MOCORD || event_close_mode == CLOSE_ALARM || event->Cause() == SIGNAL_CAUSE )
if ( function != MOCORD || event_close_mode == CLOSE_ALARM ) {
if ( ( function != MOCORD && function != RECORD ) || event_close_mode == CLOSE_ALARM ) {
shared_data->state = state = IDLE;
Info("%s: %03d - Closing event %" PRIu64 ", alarm end%s",
name, image_count, event->Id(), (function==MOCORD)?", section truncated":"");

View File

@ -26,11 +26,9 @@
#include <cmath>
#endif
void Polygon::calcArea()
{
void Polygon::calcArea() {
double float_area = 0.0L;
for ( int i = 0, j = n_coords-1; i < n_coords; j = i++ )
{
for ( int i = 0, j = n_coords-1; i < n_coords; j = i++ ) {
double trap_area = ((coords[i].X()-coords[j].X())*((coords[i].Y()+coords[j].Y())))/2.0L;
float_area += trap_area;
//printf( "%.2f (%.2f)\n", float_area, trap_area );
@ -38,13 +36,11 @@ void Polygon::calcArea()
area = (int)round(fabs(float_area));
}
void Polygon::calcCentre()
{
void Polygon::calcCentre() {
if ( !area && n_coords )
calcArea();
double float_x = 0.0L, float_y = 0.0L;
for ( int i = 0, j = n_coords-1; i < n_coords; j = i++ )
{
for ( int i = 0, j = n_coords-1; i < n_coords; j = i++ ) {
float_x += ((coords[i].Y()-coords[j].Y())*((coords[i].X()*2)+(coords[i].X()*coords[j].X())+(coords[j].X()*2)));
float_y += ((coords[j].X()-coords[i].X())*((coords[i].Y()*2)+(coords[i].Y()*coords[j].Y())+(coords[j].Y()*2)));
}
@ -54,16 +50,14 @@ void Polygon::calcCentre()
centre = Coord( (int)round(float_x), (int)round(float_y) );
}
Polygon::Polygon( int p_n_coords, const Coord *p_coords ) : n_coords( p_n_coords )
{
Polygon::Polygon(int p_n_coords, const Coord *p_coords) : n_coords( p_n_coords ) {
coords = new Coord[n_coords];
int min_x = -1;
int max_x = -1;
int min_y = -1;
int max_y = -1;
for( int i = 0; i < n_coords; i++ )
{
for ( int i = 0; i < n_coords; i++ ) {
coords[i] = p_coords[i];
if ( min_x == -1 || coords[i].X() < min_x )
min_x = coords[i].X();
@ -79,38 +73,36 @@ Polygon::Polygon( int p_n_coords, const Coord *p_coords ) : n_coords( p_n_coords
calcCentre();
}
Polygon::Polygon( const Polygon &p_polygon ) : n_coords( p_polygon.n_coords ), extent( p_polygon.extent ), area( p_polygon.area ), centre( p_polygon.centre )
Polygon::Polygon( const Polygon &p_polygon ) :
n_coords(p_polygon.n_coords),
extent(p_polygon.extent),
area(p_polygon.area),
centre(p_polygon.centre)
{
coords = new Coord[n_coords];
for( int i = 0; i < n_coords; i++ )
{
for( int i = 0; i < n_coords; i++ ) {
coords[i] = p_polygon.coords[i];
}
}
Polygon &Polygon::operator=( const Polygon &p_polygon )
{
if ( n_coords < p_polygon.n_coords )
{
Polygon &Polygon::operator=( const Polygon &p_polygon ) {
if ( n_coords < p_polygon.n_coords ) {
delete[] coords;
coords = new Coord[p_polygon.n_coords];
}
n_coords = p_polygon.n_coords;
for( int i = 0; i < n_coords; i++ )
{
for ( int i = 0; i < n_coords; i++ ) {
coords[i] = p_polygon.coords[i];
}
extent = p_polygon.extent;
area = p_polygon.area;
centre = p_polygon.centre;
return( *this );
return *this ;
}
bool Polygon::isInside( const Coord &coord ) const
{
bool Polygon::isInside( const Coord &coord ) const {
bool inside = false;
for ( int i = 0, j = n_coords-1; i < n_coords; j = i++ )
{
for ( int i = 0, j = n_coords-1; i < n_coords; j = i++ ) {
if ( (((coords[i].Y() <= coord.Y()) && (coord.Y() < coords[j].Y()) )
|| ((coords[j].Y() <= coord.Y()) && (coord.Y() < coords[i].Y())))
&& (coord.X() < (coords[j].X() - coords[i].X()) * (coord.Y() - coords[i].Y()) / (coords[j].Y() - coords[i].Y()) + coords[i].X()))
@ -118,5 +110,5 @@ bool Polygon::isInside( const Coord &coord ) const
inside = !inside;
}
}
return( inside );
return inside;
}

View File

@ -41,13 +41,13 @@ protected:
static int CompareYX( const void *p1, const void *p2 ) {
const Edge *e1 = reinterpret_cast<const Edge *>(p1), *e2 = reinterpret_cast<const Edge *>(p2);
if ( e1->min_y == e2->min_y )
return( int(e1->min_x - e2->min_x) );
return int(e1->min_x - e2->min_x);
else
return( int(e1->min_y - e2->min_y) );
return int(e1->min_y - e2->min_y);
}
static int CompareX( const void *p1, const void *p2 ) {
const Edge *e1 = reinterpret_cast<const Edge *>(p1), *e2 = reinterpret_cast<const Edge *>(p2);
return( int(e1->min_x - e2->min_x) );
return int(e1->min_x - e2->min_x);
}
};
@ -83,32 +83,32 @@ protected:
void calcCentre();
public:
inline Polygon() : n_coords( 0 ), coords( 0 ), area( 0 ), edges(0), slices(0) {
inline Polygon() : n_coords(0), coords(0), area(0), edges(0), slices(0) {
}
Polygon( int p_n_coords, const Coord *p_coords );
Polygon( const Polygon &p_polygon );
Polygon(int p_n_coords, const Coord *p_coords);
Polygon(const Polygon &p_polygon);
~Polygon() {
delete[] coords;
}
Polygon &operator=( const Polygon &p_polygon );
inline int getNumCoords() const { return( n_coords ); }
inline int getNumCoords() const { return n_coords; }
inline const Coord &getCoord( int index ) const {
return( coords[index] );
return coords[index];
}
inline const Box &Extent() const { return( extent ); }
inline int LoX() const { return( extent.LoX() ); }
inline int HiX() const { return( extent.HiX() ); }
inline int LoY() const { return( extent.LoY() ); }
inline int HiY() const { return( extent.HiY() ); }
inline int Width() const { return( extent.Width() ); }
inline int Height() const { return( extent.Height() ); }
inline const Box &Extent() const { return extent; }
inline int LoX() const { return extent.LoX(); }
inline int HiX() const { return extent.HiX(); }
inline int LoY() const { return extent.LoY(); }
inline int HiY() const { return extent.HiY(); }
inline int Width() const { return extent.Width(); }
inline int Height() const { return extent.Height(); }
inline int Area() const { return( area ); }
inline int Area() const { return area; }
inline const Coord &Centre() const {
return( centre );
return centre;
}
bool isInside( const Coord &coord ) const;
};

View File

@ -114,7 +114,7 @@ bool StreamBase::checkCommandQueue() {
return false;
}
Image *StreamBase::prepareImage( Image *image ) {
Image *StreamBase::prepareImage(Image *image) {
// Do not bother to scale zoomed in images, just crop them and let the browser scale
// Works in FF2 but breaks FF3 which doesn't like image sizes changing in mid stream.
@ -124,51 +124,52 @@ Image *StreamBase::prepareImage( Image *image ) {
int mag = (scale * zoom) / ZM_SCALE_BASE;
int act_mag = optimisedScaling?(mag > ZM_SCALE_BASE?ZM_SCALE_BASE:mag):mag;
Debug( 3, "Scaling by %d, zooming by %d = magnifying by %d(%d)", scale, zoom, mag, act_mag );
int last_mag = (last_scale * last_zoom) / ZM_SCALE_BASE;
int last_act_mag = last_mag > ZM_SCALE_BASE?ZM_SCALE_BASE:last_mag;
Debug( 3, "Last scaling by %d, zooming by %d = magnifying by %d(%d)", last_scale, last_zoom, last_mag, last_act_mag );
int base_image_width = image->Width(), base_image_height = image->Height();
Debug( 3, "Base image width = %d, height = %d", base_image_width, base_image_height );
int virt_image_width = (base_image_width * mag) / ZM_SCALE_BASE, virt_image_height = (base_image_height * mag) / ZM_SCALE_BASE;
Debug( 3, "Virtual image width = %d, height = %d", virt_image_width, virt_image_height );
int last_virt_image_width = (base_image_width * last_mag) / ZM_SCALE_BASE, last_virt_image_height = (base_image_height * last_mag) / ZM_SCALE_BASE;
Debug( 3, "Last virtual image width = %d, height = %d", last_virt_image_width, last_virt_image_height );
int act_image_width = (base_image_width * act_mag ) / ZM_SCALE_BASE, act_image_height = (base_image_height * act_mag ) / ZM_SCALE_BASE;
Debug( 3, "Actual image width = %d, height = %d", act_image_width, act_image_height );
int last_act_image_width = (base_image_width * last_act_mag ) / ZM_SCALE_BASE, last_act_image_height = (base_image_height * last_act_mag ) / ZM_SCALE_BASE;
Debug( 3, "Last actual image width = %d, height = %d", last_act_image_width, last_act_image_height );
int disp_image_width = (image->Width() * scale) / ZM_SCALE_BASE, disp_image_height = (image->Height() * scale) / ZM_SCALE_BASE;
Debug( 3, "Display image width = %d, height = %d", disp_image_width, disp_image_height );
int last_disp_image_width = (image->Width() * last_scale) / ZM_SCALE_BASE, last_disp_image_height = (image->Height() * last_scale) / ZM_SCALE_BASE;
Debug( 3, "Last display image width = %d, height = %d", last_disp_image_width, last_disp_image_height );
int send_image_width = (disp_image_width * act_mag ) / mag, send_image_height = (disp_image_height * act_mag ) / mag;
Debug( 3, "Send image width = %d, height = %d", send_image_width, send_image_height );
int last_send_image_width = (last_disp_image_width * last_act_mag ) / last_mag, last_send_image_height = (last_disp_image_height * last_act_mag ) / last_mag;
Debug( 3, "Last send image width = %d, height = %d", last_send_image_width, last_send_image_height );
if ( mag != ZM_SCALE_BASE ) {
if ( act_mag != ZM_SCALE_BASE ) {
Debug(3,
"Scaling by %d, zooming by %d = magnifying by %d(%d)\n"
"Last scaling by %d, zooming by %d = magnifying by %d(%d)\n"
"Base image width = %d, height = %d\n"
"Virtual image width = %d, height = %d\n"
"Last virtual image width = %d, height = %d\n"
"Actual image width = %d, height = %d\n"
"Last actual image width = %d, height = %d\n"
"Display image width = %d, height = %d\n"
"Last display image width = %d, height = %d\n"
"Send image width = %d, height = %d\n"
"Last send image width = %d, height = %d\n",
scale, zoom, mag, act_mag,
last_scale, last_zoom, last_mag, last_act_mag,
base_image_width, base_image_height,
virt_image_width, virt_image_height,
last_virt_image_width, last_virt_image_height,
act_image_width, act_image_height,
last_act_image_width, last_act_image_height,
disp_image_width, disp_image_height,
last_disp_image_width, last_disp_image_height,
send_image_width, send_image_height,
last_send_image_width, last_send_image_height
);
if ( ( mag != ZM_SCALE_BASE ) && (act_mag != ZM_SCALE_BASE) ) {
Debug(3, "Magnifying by %d", mag);
if ( !image_copied ) {
static Image copy_image;
copy_image.Assign(*image);
image = &copy_image;
image_copied = true;
}
image->Scale(mag);
}
}
Debug(3, "Real image width = %d, height = %d", image->Width(), image->Height());
@ -176,26 +177,22 @@ Image *StreamBase::prepareImage( Image *image ) {
static Box last_crop;
if ( mag != last_mag || x != last_x || y != last_y ) {
Debug( 3, "Got click at %d,%d x %d", x, y, mag );
//if ( !last_mag )
//last_mag = mag;
Debug(3, "Got click at %d,%d x %d", x, y, mag);
if ( !(last_disp_image_width < last_virt_image_width || last_disp_image_height < last_virt_image_height) )
last_crop = Box();
Debug( 3, "Recalculating crop" );
// Recalculate crop parameters, as %ges
int click_x = (last_crop.LoX() * 100 ) / last_act_image_width; // Initial crop offset from last image
click_x += ( x * 100 ) / last_virt_image_width;
int click_y = (last_crop.LoY() * 100 ) / last_act_image_height; // Initial crop offset from last image
click_y += ( y * 100 ) / last_virt_image_height;
Debug( 3, "Got adjusted click at %d%%,%d%%", click_x, click_y );
Debug(3, "Got adjusted click at %d%%,%d%%", click_x, click_y);
// Convert the click locations to the current image pixels
click_x = ( click_x * act_image_width ) / 100;
click_y = ( click_y * act_image_height ) / 100;
Debug( 3, "Got readjusted click at %d,%d", click_x, click_y );
Debug(3, "Got readjusted click at %d,%d", click_x, click_y);
int lo_x = click_x - (send_image_width/2);
if ( lo_x < 0 )
@ -214,23 +211,25 @@ Image *StreamBase::prepareImage( Image *image ) {
lo_y = hi_y - (send_image_height - 1);
}
last_crop = Box( lo_x, lo_y, hi_x, hi_y );
}
Debug( 3, "Cropping to %d,%d -> %d,%d", last_crop.LoX(), last_crop.LoY(), last_crop.HiX(), last_crop.HiY() );
} // end if ( mag != last_mag || x != last_x || y != last_y )
Debug(3, "Cropping to %d,%d -> %d,%d", last_crop.LoX(), last_crop.LoY(), last_crop.HiX(), last_crop.HiY());
if ( !image_copied ) {
static Image copy_image;
copy_image.Assign( *image );
copy_image.Assign(*image);
image = &copy_image;
image_copied = true;
}
image->Crop( last_crop );
}
image->Crop(last_crop);
} // end if difference in image vs displayed dimensions
last_scale = scale;
last_zoom = zoom;
last_x = x;
last_y = y;
return image;
}
} // end Image *StreamBase::prepareImage(Image *image)
bool StreamBase::sendTextFrame(const char *frame_text) {
Debug(2, "Sending %dx%d * %d text frame '%s'",
@ -349,7 +348,7 @@ void StreamBase::openComms() {
}
snprintf(rem_sock_path, sizeof(rem_sock_path), "%s/zms-%06dw.sock", staticConfig.PATH_SOCKS.c_str(), connkey);
strncpy(rem_addr.sun_path, rem_sock_path, sizeof(rem_addr.sun_path)-1);
strncpy(rem_addr.sun_path, rem_sock_path, sizeof(rem_addr.sun_path));
rem_addr.sun_family = AF_UNIX;
gettimeofday(&last_comm_update, NULL);

View File

@ -77,11 +77,11 @@ protected:
protected:
int connkey;
int sd;
char loc_sock_path[PATH_MAX];
char loc_sock_path[108];
struct sockaddr_un loc_addr;
char rem_sock_path[PATH_MAX];
char rem_sock_path[108];
struct sockaddr_un rem_addr;
char sock_path_lock[PATH_MAX];
char sock_path_lock[108];
int lock_fd;
protected:

View File

@ -26,6 +26,7 @@
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <utility>
#if HAVE_GNUTLS_GNUTLS_H
#include <gnutls/gnutls.h>
@ -35,7 +36,7 @@
#include <gcrypt.h>
#elif HAVE_LIBCRYPTO
#include <openssl/md5.h>
#endif // HAVE_L || HAVE_LIBCRYPTO
#endif // HAVE_GCRYPT_H || HAVE_LIBCRYPTO
#include "zm_utils.h"
#include "zm_crypt.h"
@ -52,7 +53,7 @@ User::User(const MYSQL_ROW &dbrow) {
id = atoi(dbrow[index++]);
strncpy(username, dbrow[index++], sizeof(username)-1);
strncpy(password, dbrow[index++], sizeof(password)-1);
enabled = (bool)atoi(dbrow[index++]);
enabled = static_cast<bool>(atoi(dbrow[index++]));
stream = (Permission)atoi(dbrow[index++]);
events = (Permission)atoi(dbrow[index++]);
control = (Permission)atoi(dbrow[index++]);
@ -61,7 +62,7 @@ User::User(const MYSQL_ROW &dbrow) {
char *monitor_ids_str = dbrow[index++];
if ( monitor_ids_str && *monitor_ids_str ) {
StringVector ids = split(monitor_ids_str, ",");
for( StringVector::iterator i = ids.begin(); i < ids.end(); ++i ) {
for ( StringVector::iterator i = ids.begin(); i < ids.end(); ++i ) {
monitor_ids.push_back(atoi((*i).c_str()));
}
}
@ -72,9 +73,9 @@ User::~User() {
}
void User::Copy(const User &u) {
id=u.id;
strncpy(username, u.username, sizeof(username)-1);
strncpy(password, u.password, sizeof(password)-1);
id = u.id;
strncpy(username, u.username, sizeof(username));
strncpy(password, u.password, sizeof(password));
enabled = u.enabled;
stream = u.stream;
events = u.events;
@ -88,7 +89,8 @@ bool User::canAccess(int monitor_id) {
if ( monitor_ids.empty() )
return true;
for ( std::vector<int>::iterator i = monitor_ids.begin(); i != monitor_ids.end(); ++i ) {
for ( std::vector<int>::iterator i = monitor_ids.begin();
i != monitor_ids.end(); ++i ) {
if ( *i == monitor_id ) {
return true;
}
@ -103,18 +105,23 @@ User *zmLoadUser(const char *username, const char *password) {
int username_length = strlen(username);
char *safer_username = new char[(username_length * 2) + 1];
// According to docs, size of safer_whatever must be 2*length+1 due to unicode conversions + null terminator.
// According to docs, size of safer_whatever must be 2*length+1
// due to unicode conversions + null terminator.
mysql_real_escape_string(&dbconn, safer_username, username, username_length);
snprintf(sql, sizeof(sql),
"SELECT `Id`, `Username`, `Password`, `Enabled`, `Stream`+0, `Events`+0, `Control`+0, `Monitors`+0, `System`+0, `MonitorIds`"
" FROM `Users` WHERE `Username` = '%s' AND `Enabled` = 1", safer_username);
"SELECT `Id`, `Username`, `Password`, `Enabled`,"
" `Stream`+0, `Events`+0, `Control`+0, `Monitors`+0, `System`+0,"
" `MonitorIds`"
" FROM `Users` WHERE `Username` = '%s' AND `Enabled` = 1",
safer_username);
delete[] safer_username;
safer_username = NULL;
if ( mysql_query(&dbconn, sql) ) {
Error("Can't run query: %s", mysql_error(&dbconn));
exit(mysql_errno(&dbconn));
}
delete safer_username;
MYSQL_RES *result = mysql_store_result(&dbconn);
if ( !result ) {
@ -122,68 +129,67 @@ User *zmLoadUser(const char *username, const char *password) {
exit(mysql_errno(&dbconn));
}
if ( mysql_num_rows(result) != 1 ) {
mysql_free_result(result);
Warning("Unable to authenticate user %s", username);
return NULL;
}
if ( mysql_num_rows(result) == 1 ) {
MYSQL_ROW dbrow = mysql_fetch_row(result);
User *user = new User(dbrow);
mysql_free_result(result);
if ( !password ) {
// relay type must be none
return user;
}
if ( verifyPassword(username, password, user->getPassword()) ) {
if (
(! password ) // relay type must be none
||
verifyPassword(username, password, user->getPassword()) ) {
Info("Authenticated user '%s'", user->getUsername());
return user;
}
} // end if 1 result from db
mysql_free_result(result);
Warning("Unable to authenticate user %s", username);
return NULL;
}
} // end User *zmLoadUser(const char *username, const char *password)
User *zmLoadTokenUser (std::string jwt_token_str, bool use_remote_addr ) {
User *zmLoadTokenUser(std::string jwt_token_str, bool use_remote_addr) {
std::string key = config.auth_hash_secret;
std::string remote_addr = "";
if (use_remote_addr) {
remote_addr = std::string(getenv( "REMOTE_ADDR" ));
if ( use_remote_addr ) {
remote_addr = std::string(getenv("REMOTE_ADDR"));
if ( remote_addr == "" ) {
Warning( "Can't determine remote address, using null" );
Warning("Can't determine remote address, using null");
remote_addr = "";
}
key += remote_addr;
}
Debug (1,"Inside zmLoadTokenUser, formed key=%s", key.c_str());
Debug(1, "Inside zmLoadTokenUser, formed key=%s", key.c_str());
std::pair<std::string, unsigned int> ans = verifyToken(jwt_token_str, key);
std::string username = ans.first;
unsigned int iat = ans.second;
Debug (1,"retrieved user '%s' from token", username.c_str());
Debug(1, "retrieved user '%s' from token", username.c_str());
if ( username == "" ) {
return NULL;
}
if (username != "") {
char sql[ZM_SQL_MED_BUFSIZ] = "";
snprintf(sql, sizeof(sql),
"SELECT `Id`, `Username`, `Password`, `Enabled`, `Stream`+0, `Events`+0, `Control`+0, `Monitors`+0, `System`+0, `MonitorIds`, `TokenMinExpiry`"
" FROM `Users` WHERE `Username` = '%s' AND `Enabled` = 1", username.c_str() );
"SELECT `Id`, `Username`, `Password`, `Enabled`, `Stream`+0, `Events`+0,"
" `Control`+0, `Monitors`+0, `System`+0, `MonitorIds`, `TokenMinExpiry`"
" FROM `Users` WHERE `Username` = '%s' AND `Enabled` = 1", username.c_str());
if ( mysql_query(&dbconn, sql) ) {
Error("Can't run query: %s", mysql_error(&dbconn));
exit(mysql_errno(&dbconn));
return NULL;
}
MYSQL_RES *result = mysql_store_result(&dbconn);
if ( !result ) {
Error("Can't use query result: %s", mysql_error(&dbconn));
exit(mysql_errno(&dbconn));
return NULL;
}
int n_users = mysql_num_rows(result);
int n_users = mysql_num_rows(result);
if ( n_users != 1 ) {
mysql_free_result(result);
Error("Unable to authenticate user '%s'", username.c_str());
@ -192,92 +198,88 @@ User *zmLoadTokenUser (std::string jwt_token_str, bool use_remote_addr ) {
MYSQL_ROW dbrow = mysql_fetch_row(result);
User *user = new User(dbrow);
unsigned int stored_iat = strtoul(dbrow[10], NULL,0 );
unsigned int stored_iat = strtoul(dbrow[10], NULL, 0);
if (stored_iat > iat ) { // admin revoked tokens
if ( stored_iat > iat ) { // admin revoked tokens
mysql_free_result(result);
Error("Token was revoked for '%s'", username.c_str());
return NULL;
}
Debug (1,"Got last token revoke time of: %u",stored_iat);
Debug (1,"Authenticated user '%s' via token", username.c_str());
Debug(1, "Authenticated user '%s' via token with last revoke time: %u",
username.c_str(), stored_iat);
mysql_free_result(result);
return user;
}
else {
return NULL;
}
}
} // User *zmLoadTokenUser(std::string jwt_token_str, bool use_remote_addr)
// Function to validate an authentication string
User *zmLoadAuthUser( const char *auth, bool use_remote_addr ) {
User *zmLoadAuthUser(const char *auth, bool use_remote_addr) {
#if HAVE_DECL_MD5 || HAVE_DECL_GNUTLS_FINGERPRINT
#ifdef HAVE_GCRYPT_H
// Special initialisation for libgcrypt
if ( !gcry_check_version( GCRYPT_VERSION ) ) {
Fatal( "Unable to initialise libgcrypt" );
if ( !gcry_check_version(GCRYPT_VERSION) ) {
Fatal("Unable to initialise libgcrypt");
}
gcry_control( GCRYCTL_DISABLE_SECMEM, 0 );
gcry_control( GCRYCTL_INITIALIZATION_FINISHED, 0 );
gcry_control(GCRYCTL_DISABLE_SECMEM, 0);
gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0);
#endif // HAVE_GCRYPT_H
const char *remote_addr = "";
if ( use_remote_addr ) {
remote_addr = getenv( "REMOTE_ADDR" );
remote_addr = getenv("REMOTE_ADDR");
if ( !remote_addr ) {
Warning( "Can't determine remote address, using null" );
Warning("Can't determine remote address, using null");
remote_addr = "";
}
}
Debug( 1, "Attempting to authenticate user from auth string '%s'", auth );
Debug(1, "Attempting to authenticate user from auth string '%s'", auth);
char sql[ZM_SQL_SML_BUFSIZ] = "";
snprintf( sql, sizeof(sql), "SELECT `Id`, `Username`, `Password`, `Enabled`, `Stream`+0, `Events`+0, `Control`+0, `Monitors`+0, `System`+0, `MonitorIds` FROM `Users` WHERE `Enabled` = 1" );
snprintf(sql, sizeof(sql),
"SELECT `Id`, `Username`, `Password`, `Enabled`,"
" `Stream`+0, `Events`+0, `Control`+0, `Monitors`+0, `System`+0,"
" `MonitorIds` FROM `Users` WHERE `Enabled` = 1");
if ( mysql_query( &dbconn, sql ) ) {
Error( "Can't run query: %s", mysql_error( &dbconn ) );
exit( mysql_errno( &dbconn ) );
if ( mysql_query(&dbconn, sql) ) {
Error("Can't run query: %s", mysql_error(&dbconn));
exit(mysql_errno(&dbconn));
}
MYSQL_RES *result = mysql_store_result( &dbconn );
MYSQL_RES *result = mysql_store_result(&dbconn);
if ( !result ) {
Error( "Can't use query result: %s", mysql_error( &dbconn ) );
exit( mysql_errno( &dbconn ) );
Error("Can't use query result: %s", mysql_error(&dbconn));
return NULL;
}
int n_users = mysql_num_rows( result );
int n_users = mysql_num_rows(result);
if ( n_users < 1 ) {
mysql_free_result( result );
Warning( "Unable to authenticate user" );
return( 0 );
mysql_free_result(result);
Warning("Unable to authenticate user");
return NULL;
}
while( MYSQL_ROW dbrow = mysql_fetch_row( result ) ) {
const char *user = dbrow[1];
const char *pass = dbrow[2];
time_t now = time(0);
unsigned int hours = config.auth_hash_ttl;
if ( ! hours ) {
Warning("No value set for ZM_AUTH_HASH_TTL. Defaulting to 2.");
hours = 2;
} else {
Debug(1, "AUTH_HASH_TTL is %d", hours);
}
char auth_key[512] = "";
char auth_md5[32+1] = "";
size_t md5len = 16;
unsigned char md5sum[md5len];
time_t now = time( 0 );
unsigned int hours = config.auth_hash_ttl;
const char * hex = "0123456789abcdef";
while ( MYSQL_ROW dbrow = mysql_fetch_row(result) ) {
const char *user = dbrow[1];
const char *pass = dbrow[2];
if ( ! hours ) {
Warning("No value set for ZM_AUTH_HASH_TTL. Defaulting to 2.");
hours = 2;
} else {
Debug( 1, "AUTH_HASH_TTL is %d", hours );
}
time_t our_now = now;
for ( unsigned int i = 0; i < hours; i++, our_now -= 3600 ) {
struct tm *now_tm = localtime(&our_now);
for ( unsigned int i = 0; i < hours; i++, now -= 3600 ) {
struct tm *now_tm = localtime( &now );
snprintf( auth_key, sizeof(auth_key), "%s%s%s%s%d%d%d%d",
snprintf(auth_key, sizeof(auth_key)-1, "%s%s%s%s%d%d%d%d",
config.auth_hash_secret,
user,
pass,
@ -285,51 +287,57 @@ User *zmLoadAuthUser( const char *auth, bool use_remote_addr ) {
now_tm->tm_hour,
now_tm->tm_mday,
now_tm->tm_mon,
now_tm->tm_year
);
now_tm->tm_year);
#if HAVE_DECL_MD5
MD5( (unsigned char *)auth_key, strlen(auth_key), md5sum );
MD5((unsigned char *)auth_key, strlen(auth_key), md5sum);
#elif HAVE_DECL_GNUTLS_FINGERPRINT
gnutls_datum_t md5data = { (unsigned char *)auth_key, strlen(auth_key) };
gnutls_fingerprint( GNUTLS_DIG_MD5, &md5data, md5sum, &md5len );
gnutls_datum_t md5data = { (unsigned char *)auth_key, (unsigned int)strlen(auth_key) };
gnutls_fingerprint(GNUTLS_DIG_MD5, &md5data, md5sum, &md5len);
#endif
auth_md5[0] = '\0';
unsigned char *md5sum_ptr = md5sum;
char *auth_md5_ptr = auth_md5;
for ( unsigned int j = 0; j < md5len; j++ ) {
sprintf( &auth_md5[2*j], "%02x", md5sum[j] );
*auth_md5_ptr++ = hex[(*md5sum_ptr>>4)&0xf];
*auth_md5_ptr++ = hex[(*md5sum_ptr++)&0xf];
}
Debug( 1, "Checking auth_key '%s' -> auth_md5 '%s' == '%s'", auth_key, auth_md5, auth );
*auth_md5_ptr = 0;
if ( !strcmp( auth, auth_md5 ) ) {
Debug(1, "Checking auth_key '%s' -> auth_md5 '%s' == '%s'",
auth_key, auth_md5, auth);
if ( !strcmp(auth, auth_md5) ) {
// We have a match
User *user = new User( dbrow );
Debug(1, "Authenticated user '%s'", user->getUsername() );
mysql_free_result( result );
return( user );
User *user = new User(dbrow);
Debug(1, "Authenticated user '%s'", user->getUsername());
mysql_free_result(result);
return user;
} else {
Debug(1, "No match for %s", auth );
Debug(1, "No match for %s", auth);
}
}
}
mysql_free_result( result );
#else // HAVE_DECL_MD5
Error( "You need to build with gnutls or openssl installed to use hash based authentication" );
#endif // HAVE_DECL_MD5
Debug(1, "No user found for auth_key %s", auth );
return 0;
}
} // end foreach hour
} // end foreach user
mysql_free_result(result);
#else // HAVE_DECL_MD5 || HAVE_DECL_GNUTLS_FINGERPRINT
Error("You need to build with gnutls or openssl to use hash based auth");
#endif // HAVE_DECL_MD5 || HAVE_DECL_GNUTLS_FINGERPRINT
Debug(1, "No user found for auth_key %s", auth);
return NULL;
} // end User *zmLoadAuthUser( const char *auth, bool use_remote_addr )
//Function to check Username length
bool checkUser ( const char *username) {
if ( ! username )
// Function to check Username length
bool checkUser(const char *username) {
if ( !username )
return false;
if ( strlen(username) > 32 )
return false;
return true;
}
//Function to check password length
bool checkPass (const char *password) {
// Function to check password length
bool checkPass(const char *password) {
if ( !password )
return false;
if ( strlen(password) > 64 )

View File

@ -184,7 +184,7 @@ int main(int argc, const char *argv[]) {
logInit(log_id_string);
if ( config.opt_use_auth ) {
User *user = 0;
User *user = NULL;
if ( jwt_token_str != "" ) {
// user = zmLoadTokenUser(jwt_token_str, config.auth_hash_ips);
@ -195,21 +195,13 @@ int main(int argc, const char *argv[]) {
} else {
Error("Bad username");
}
} else {
// if ( strcmp( config.auth_relay, "hashed" ) == 0 )
{
if ( *auth ) {
user = zmLoadAuthUser(auth, config.auth_hash_ips);
}
}
// else if ( strcmp( config.auth_relay, "plain" ) == 0 )
{
if ( username.length() && password.length() ) {
} else if ( username.length() && password.length() ) {
user = zmLoadUser(username.c_str(), password.c_str());
}
}
}
if ( !user ) {
fputs("HTTP/1.0 403 Forbidden\r\n\r\n", stdout);
Error("Unable to authenticate user");
@ -218,11 +210,15 @@ int main(int argc, const char *argv[]) {
return 0;
}
if ( !ValidateAccess(user, monitor_id) ) {
delete user;
user = NULL;
fputs("HTTP/1.0 403 Forbidden\r\n\r\n", stdout);
logTerm();
zmDbClose();
return 0;
}
delete user;
user = NULL;
} // end if config.opt_use_auth
hwcaps_detect();
@ -336,5 +332,5 @@ int main(int argc, const char *argv[]) {
logTerm();
zmDbClose();
return(0);
return 0;
}

View File

@ -1 +1 @@
1.34.10
1.34.11

View File

@ -39,7 +39,7 @@ class Monitor extends ZM_Object {
'Height' => null,
'Colours' => 4,
'Palette' => '0',
'Orientation' => null,
'Orientation' => 'ROTATE_0',
'Deinterlacing' => 0,
'DecoderHWAccelName' => null,
'DecoderHWAccelDevice' => null,
@ -495,12 +495,16 @@ class Monitor extends ZM_Object {
}
}
if ( !count($options) ) {
if ( $command == 'quit' ) {
$options['command'] = 'quit';
} else if ( $command == 'start' ) {
$options['command'] = 'start';
} else if ( $command == 'stop' ) {
$options['command'] = 'stop';
if ( $command == 'quit' or $command == 'start' or $command == 'stop' ) {
# These are special as we now run zmcontrol as a daemon through zmdc.
$status = daemonStatus('zmcontrol.pl', array('--id', $this->{'Id'}));
Logger::Debug("Current status $status");
if ( $status or ( (!defined('ZM_SERVER_ID')) or ( property_exists($this, 'ServerId') and (ZM_SERVER_ID==$this->{'ServerId'}) ) ) ) {
daemonControl($command, 'zmcontrol.pl', '--id '.$this->{'Id'});
return;
}
$options['command'] = $command;
} else {
Warning("No commands to send to zmcontrol from $command");
return false;
@ -538,12 +542,12 @@ class Monitor extends ZM_Object {
$url = ZM_BASE_PROTOCOL . '://'.$Server->Hostname().'/zm/api/monitors/daemonControl/'.$this->{'Id'}.'/'.$command.'/zmcontrol.pl.json';
if ( ZM_OPT_USE_AUTH ) {
if ( ZM_AUTH_RELAY == 'hashed' ) {
$url .= '?auth='.generateAuthHash( ZM_AUTH_HASH_IPS );
$url .= '?auth='.generateAuthHash(ZM_AUTH_HASH_IPS);
} else if ( ZM_AUTH_RELAY == 'plain' ) {
$url = '?user='.$_SESSION['username'];
$url = '?pass='.$_SESSION['password'];
$url .= '?user='.$_SESSION['username'];
$url .= '?pass='.$_SESSION['password'];
} else if ( ZM_AUTH_RELAY == 'none' ) {
$url = '?user='.$_SESSION['username'];
$url .= '?user='.$_SESSION['username'];
}
}
Logger::Debug("sending command to $url");

View File

@ -249,7 +249,7 @@ class ZM_Object {
}
}
} else if ( array_key_exists($field, $this->defaults) ) {
if ( is_array($this->defaults[$field]) ) {
if ( is_array($this->defaults[$field]) and isset($this->defaults[$field]['default']) ) {
$default = $this->defaults[$field]['default'];
} else {
$default = $this->defaults[$field];

41
web/includes/Zone.php Normal file
View File

@ -0,0 +1,41 @@
<?php
namespace ZM;
require_once('database.php');
require_once('Object.php');
class Zone extends ZM_Object {
protected static $table = 'Zones';
protected $defaults = array(
'Id' => null,
'Name' => '',
'Type' => 'Active',
'Units' => 'Pixels',
'CheckMethod' => 'Blobs',
'MinPixelThreshold' => null,
'MaxPixelThreshold' => null,
'MinAlarmPixels' => null,
'MaxAlarmPixels' => null,
'FilterX' => null,
'FilterY' => null,
'MinFilterPixels' => null,
'MaxFilterPixels' => null,
'MinBlobPixels' => null,
'MaxBlobPixels' => null,
'MinBlobs' => null,
'MaxBlobs' => null,
'OverloadFrames' => 0,
'ExtendAlarmFrames' => 0,
);
public static function find( $parameters = array(), $options = array() ) {
return ZM_Object::_find(get_class(), $parameters, $options);
}
public static function find_one( $parameters = array(), $options = array() ) {
return ZM_Object::_find_one(get_class(), $parameters, $options);
}
} # end class Zone
?>

View File

@ -52,6 +52,9 @@ require_once('includes/Event.php');
require_once('includes/Group.php');
require_once('includes/Monitor.php');
global $Servers;
$Servers = ZM\Server::find();
if (
(isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on')
or
@ -71,7 +74,7 @@ define('ZM_BASE_URL', '');
require_once('includes/functions.php');
if ( $_SERVER['REQUEST_METHOD'] == 'OPTIONS' ) {
ZM\Logger::Debug("OPTIONS Method, only doing CORS");
ZM\Logger::Debug('OPTIONS Method, only doing CORS');
# Add Cross domain access headers
CORSHeaders();
return;
@ -152,8 +155,6 @@ if (
setcookie('zmCSS', $css, time()+3600*24*30*12*10);
}
# Running is global but only do the daemonCheck if it is actually needed
$running = null;
@ -174,7 +175,6 @@ $user = null;
if ( isset($_REQUEST['view']) )
$view = detaintPath($_REQUEST['view']);
# Add CSP Headers
$cspNonce = bin2hex(zm_random_bytes(16));

View File

@ -25,15 +25,15 @@ function controlFocus($monitor, $cmds) {
?>
<div class="arrowControl focusControls">
<div class="arrowLabel"><?php echo translate('Near') ?></div>
<button type="button" class="longArrowBtn upBtn" value="<?php echo $cmds['FocusNear'] ?>" data-on-click-this="controlCmd" data-xtell="0" data-ytell="-1"></button>
<button type="button" class="arrowCenter"<?php if ( $control->CanFocusCon() ) { ?> data-on-click-this="controlCmd" value="<?php echo $cmds['FocusStop'] ?>"<?php } ?>><?php echo translate('Focus') ?></button>
<button type="button" class="longArrowBtn downBtn" data-on-click-this="controlCmd" value="<?php echo $cmds['FocusFar'] ?>" data-xtell="0" data-ytell="1"></button>
<button type="button" class="longArrowBtn upBtn" value="<?php echo $cmds['FocusNear'] ?>" data-on-click="controlCmd" data-xtell="0" data-ytell="-1"></button>
<button type="button" class="arrowCenter"<?php if ( $control->CanFocusCon() ) { ?> data-on-click="controlCmd" value="<?php echo $cmds['FocusStop'] ?>"<?php } ?>><?php echo translate('Focus') ?></button>
<button type="button" class="longArrowBtn downBtn" data-on-click="controlCmd" value="<?php echo $cmds['FocusFar'] ?>" data-xtell="0" data-ytell="1"></button>
<div class="arrowLabel"><?php echo translate('Far') ?></div>
<?php
if ( $control->CanAutoFocus() ) {
?>
<button type="button" class="ptzTextBtn" value="<?php echo $cmds['FocusAuto'] ?>" data-on-click-this="controlCmd"><?php echo translate('Auto') ?></button>
<button type="button" class="ptzTextBtn" value="<?php echo $cmds['FocusMan'] ?>" data-on-click-this="controlCmd"><?php echo translate('Man') ?></button>
<button type="button" class="ptzTextBtn" value="<?php echo $cmds['FocusAuto'] ?>" data-on-click="controlCmd"><?php echo translate('Auto') ?></button>
<button type="button" class="ptzTextBtn" value="<?php echo $cmds['FocusMan'] ?>" data-on-click="controlCmd"><?php echo translate('Man') ?></button>
<?php
}
?>
@ -48,15 +48,15 @@ function controlZoom($monitor, $cmds) {
?>
<div class="arrowControl zoomControls">
<div class="arrowLabel"><?php echo translate('Tele') ?></div>
<button type="button" class="longArrowBtn upBtn" data-on-click-this="controlCmd" value="<?php echo $cmds['ZoomTele'] ?>" data-xtell="0" data-ytell="-1"></button>
<button type="button" class="arrowCenter"<?php if ( $control->CanZoomCon() ) { ?> data-on-click-this="controlCmd" value="<?php echo $cmds['ZoomStop'] ?>"<?php } ?>><?php echo translate('Zoom') ?></button>
<button type="button" class="longArrowBtn downBtn" data-on-click-data="controlCmd" value="<?php echo $cmds['ZoomWide'] ?>" data-xtell="0" data-ytell="1"></button>
<button type="button" class="longArrowBtn upBtn" data-on-click="controlCmd" value="<?php echo $cmds['ZoomTele'] ?>" data-xtell="0" data-ytell="-1"></button>
<button type="button" class="arrowCenter"<?php if ( $control->CanZoomCon() ) { ?> data-on-click="controlCmd" value="<?php echo $cmds['ZoomStop'] ?>"<?php } ?>><?php echo translate('Zoom') ?></button>
<button type="button" class="longArrowBtn downBtn" data-on-click="controlCmd" value="<?php echo $cmds['ZoomWide'] ?>" data-xtell="0" data-ytell="1"></button>
<div class="arrowLabel"><?php echo translate('Wide') ?></div>
<?php
if ( $control->CanAutoZoom() ) {
?>
<button type="button" class="ptzTextBtn" value="Auto" data-on-click-this="controlCmd" value="<?php echo $cmds['ZoomAuto'] ?>"><?php echo translate('Auto') ?></button>
<button type="button" class="ptzTextBtn" value="Man" data-on-click-this="controlCmd" value="<?php echo $cmds['ZoomMan'] ?>"><?php echo translate('Man') ?></button>
<button type="button" class="ptzTextBtn" data-on-click="controlCmd" value="<?php echo $cmds['ZoomAuto'] ?>"><?php echo translate('Auto') ?></button>
<button type="button" class="ptzTextBtn" data-on-click="controlCmd" value="<?php echo $cmds['ZoomMan'] ?>"><?php echo translate('Man') ?></button>
<?php
}
?>
@ -70,15 +70,15 @@ function controlIris($monitor, $cmds) {
?>
<div class="arrowControl irisControls">
<div class="arrowLabel"><?php echo translate('Open') ?></div>
<button type="button" class="longArrowBtn upBtn" data-on-click-this="controlCmd" value="<?php echo $cmds['IrisOpen'] ?>" data-xtell="0" data-ytell="-1"></button>
<button type="button" class="arrowCenter"<?php if ( $control->CanIrisCon() ) { ?> data-on-click-this="controlCmd" value="<?php echo $cmds['IrisStop'] ?>"<?php } ?>><?php echo translate('Iris') ?></button>
<button type="button" class="longArrowBtn downBtn" data-on-click-this="controlCmd" value="<?php echo $cmds['IrisClose'] ?>" data-xtell="0" data-ytell="1"></button>
<button type="button" class="longArrowBtn upBtn" data-on-click="controlCmd" value="<?php echo $cmds['IrisOpen'] ?>" data-xtell="0" data-ytell="-1"></button>
<button type="button" class="arrowCenter"<?php if ( $control->CanIrisCon() ) { ?> data-on-click="controlCmd" value="<?php echo $cmds['IrisStop'] ?>"<?php } ?>><?php echo translate('Iris') ?></button>
<button type="button" class="longArrowBtn downBtn" data-on-click="controlCmd" value="<?php echo $cmds['IrisClose'] ?>" data-xtell="0" data-ytell="1"></button>
<div class="arrowLabel"><?php echo translate('Close') ?></div>
<?php
if ( $control->CanAutoIris() ) {
?>
<button type="button" class="ptzTextBtn" value="Auto" data-on-click-this="controlCmd" value="<?php echo $cmds['IrisAuto'] ?>"><?php echo translate('Auto') ?></button>
<button type="button" class="ptzTextBtn" value="Man" data-on-click-this="controlCmd" value="<?php echo $cmds['IrisMan'] ?>"><?php echo translate('Man') ?></button>
<button type="button" class="ptzTextBtn" data-on-click="controlCmd" value="<?php echo $cmds['IrisAuto'] ?>"><?php echo translate('Auto') ?></button>
<button type="button" class="ptzTextBtn" data-on-click="controlCmd" value="<?php echo $cmds['IrisMan'] ?>"><?php echo translate('Man') ?></button>
<?php
}
?>
@ -93,15 +93,15 @@ function controlWhite($monitor, $cmds) {
?>
<div class="arrowControl whiteControls">
<div class="arrowLabel"><?php echo translate('In') ?></div>
<button type="button" class="longArrowBtn upBtn" data-on-click-this="controlCmd" value="<?php echo $cmds['WhiteIn'] ?>" data-xtell="0" data-ytell="-1"></button>
<button type="button" class="arrowCenter"<?php if ( $control->CanWhiteCon() ) { ?> data-on-click-this="controlCmd" value="<?php echo $cmds['WhiteStop'] ?>"<?php } ?>><?php echo translate('White') ?></button>
<button type="button" class="longArrowBtn downBtn" data-on-click-this="controlCmd" value="<?php echo $cmds['WhiteOut'] ?>" data-xtell="0" data-ytell="1)"></button>
<button type="button" class="longArrowBtn upBtn" data-on-click="controlCmd" value="<?php echo $cmds['WhiteIn'] ?>" data-xtell="0" data-ytell="-1"></button>
<button type="button" class="arrowCenter"<?php if ( $control->CanWhiteCon() ) { ?> data-on-click="controlCmd" value="<?php echo $cmds['WhiteStop'] ?>"<?php } ?>><?php echo translate('White') ?></button>
<button type="button" class="longArrowBtn downBtn" data-on-click="controlCmd" value="<?php echo $cmds['WhiteOut'] ?>" data-xtell="0" data-ytell="1)"></button>
<div class="arrowLabel"><?php echo translate('Out') ?></div>
<?php
if ( $control->CanAutoWhite() ) {
?>
<button type="button" class="ptzTextBtn" value="Auto" data-on-click-this="controlCmd" value="<?php echo $cmds['WhiteAuto'] ?>"><?php echo translate('Auto') ?></button>
<button type="button" class="ptzTextBtn" value="Man" data-on-click-this="controlCmd" value="<?php echo $cmds['WhiteMan'] ?>"><?php echo translate('Man') ?></button>
<button type="button" class="ptzTextBtn" data-on-click="controlCmd" value="<?php echo $cmds['WhiteAuto'] ?>"><?php echo translate('Auto') ?></button>
<button type="button" class="ptzTextBtn" data-on-click="controlCmd" value="<?php echo $cmds['WhiteMan'] ?>"><?php echo translate('Man') ?></button>
<?php
}
?>
@ -122,19 +122,19 @@ function controlPanTilt($monitor, $cmds) {
$hasTilt = $control->CanTilt();
$hasDiag = $hasPan && $hasTilt && $control->CanMoveDiag();
?>
<button type="button" class="arrowBtn upLeftBtn<?php echo $hasDiag?'':' invisible' ?>" data-on-click-this="controlCmd" value="<?php echo $cmds['MoveUpLeft'] ?>" data-xtell="-1" data-ytell="-1"></button>
<button type="button" class="arrowBtn upBtn<?php echo $hasTilt?'':' invisible' ?>" data-on-click-this="controlCmd" value="<?php echo $cmds['MoveUp'] ?>" data-xtell="0" data-ytell="-1"></button>
<button type="button" class="arrowBtn upRightBtn<?php echo $hasDiag?'':' invisible' ?>" data-on-click-this="controlCmd" value="<?php echo $cmds['MoveUpRight'] ?>" data-xtell="1" data-ytell="-1"></button>
<button type="button" class="arrowBtn leftBtn<?php echo $hasPan?'':' invisible' ?>" data-on-click-this="controlCmd" value="<?php echo $cmds['MoveLeft'] ?>" data-xtell="-1" data-ytell="0"></button>
<button type="button" class="arrowBtn upLeftBtn<?php echo $hasDiag?'':' invisible' ?>" data-on-click="controlCmd" value="<?php echo $cmds['MoveUpLeft'] ?>" data-xtell="-1" data-ytell="-1"></button>
<button type="button" class="arrowBtn upBtn<?php echo $hasTilt?'':' invisible' ?>" data-on-click="controlCmd" value="<?php echo $cmds['MoveUp'] ?>" data-xtell="0" data-ytell="-1"></button>
<button type="button" class="arrowBtn upRightBtn<?php echo $hasDiag?'':' invisible' ?>" data-on-click="controlCmd" value="<?php echo $cmds['MoveUpRight'] ?>" data-xtell="1" data-ytell="-1"></button>
<button type="button" class="arrowBtn leftBtn<?php echo $hasPan?'':' invisible' ?>" data-on-click="controlCmd" value="<?php echo $cmds['MoveLeft'] ?>" data-xtell="-1" data-ytell="0"></button>
<?php if ( isset($cmds['Center']) ) { ?>
<button type="button" class="arrowBtn centerBtn" data-on-click-this="controlCmd" value="<?php echo $cmds['Center'] ?>"></button>
<button type="button" class="arrowBtn centerBtn" data-on-click="controlCmd" value="<?php echo $cmds['Center'] ?>"></button>
<?php } else { ?>
<button type="button" class="arrowBtn NocenterBtn"></button>
<?php } ?>
<button type="button" class="arrowBtn rightBtn<?php echo $hasPan?'':' invisible' ?>" data-on-click-this="controlCmd" value="<?php echo $cmds['MoveRight'] ?>" data-xtell="1" data-ytell="0"></button>
<button type="button" class="arrowBtn downLeftBtn<?php echo $hasDiag?'':' invisible' ?>" data-on-click-this="controlCmd" value="<?php echo $cmds['MoveDownLeft'] ?>" data-xtell="-1" data-ytell="1"></button>
<button type="button" class="arrowBtn downBtn<?php echo $hasTilt?'':' invisible' ?>" data-on-click-this="controlCmd" value="<?php echo $cmds['MoveDown'] ?>" data-xtell="0" data-ytell="1"></button>
<button type="button" class="arrowBtn downRightBtn<?php echo $hasDiag?'':' invisible' ?>" data-on-click-this="controlCmd" value="<?php echo $cmds['MoveDownRight'] ?>" data-xtell="1" data-ytell="1"></button>
<button type="button" class="arrowBtn rightBtn<?php echo $hasPan?'':' invisible' ?>" data-on-click="controlCmd" value="<?php echo $cmds['MoveRight'] ?>" data-xtell="1" data-ytell="0"></button>
<button type="button" class="arrowBtn downLeftBtn<?php echo $hasDiag?'':' invisible' ?>" data-on-click="controlCmd" value="<?php echo $cmds['MoveDownLeft'] ?>" data-xtell="-1" data-ytell="1"></button>
<button type="button" class="arrowBtn downBtn<?php echo $hasTilt?'':' invisible' ?>" data-on-click="controlCmd" value="<?php echo $cmds['MoveDown'] ?>" data-xtell="0" data-ytell="1"></button>
<button type="button" class="arrowBtn downRightBtn<?php echo $hasDiag?'':' invisible' ?>" data-on-click="controlCmd" value="<?php echo $cmds['MoveDownRight'] ?>" data-xtell="1" data-ytell="1"></button>
</div>
</div>
<?php
@ -162,7 +162,7 @@ function controlPresets($monitor, $cmds) {
<?php
for ( $i = 1; $i <= $control->NumPresets(); $i++ ) {
?>
<button type="button" class="ptzNumBtn" title="<?php echo isset($labels[$i])?htmlentities($labels[$i]):'' ?>" value="<?php echo $i ?>" data-on-click-this="controlCmd" value="<?php echo $cmds['PresetGoto'] ?><?php echo $i ?>"/><?php echo $i ?></button>
<button type="button" class="ptzNumBtn" title="<?php echo isset($labels[$i])?htmlentities($labels[$i]):'' ?>" data-on-click="controlCmd" value="<?php echo $cmds['PresetGoto'].$i ?>"/><?php echo $i ?></button>
<?php
} // end foreach preset
?>
@ -171,7 +171,7 @@ function controlPresets($monitor, $cmds) {
<?php
if ( $control->HasHomePreset() ) {
?>
<button type="button" class="ptzTextBtn" data-on-click-this="controlCmd" value="<?php echo $cmds['PresetHome'] ?>"><?php echo translate('Home') ?></button>
<button type="button" class="ptzTextBtn" data-on-click="controlCmd" value="<?php echo $cmds['PresetHome'] ?>"><?php echo translate('Home') ?></button>
<?php
}
if ( canEdit('Monitors') && $control->CanSetPresets() ) {
@ -196,22 +196,22 @@ function controlPower($monitor, $cmds) {
<?php
if ( $control->CanWake() ) {
?>
<button type="button" class="ptzTextBtn" data-on-click-this="controlCmd" value="<?php echo $cmds['Wake'] ?>"><?php echo translate('Wake') ?></button>
<button type="button" class="ptzTextBtn" data-on-click="controlCmd" value="<?php echo $cmds['Wake'] ?>"><?php echo translate('Wake') ?></button>
<?php
}
if ( $control->CanSleep() ) {
?>
<button type="button" class="ptzTextBtn" data-on-click-this="controlCmd" value="<?php echo $cmds['Sleep'] ?>"><?php echo translate('Sleep') ?></button>
<button type="button" class="ptzTextBtn" data-on-click="controlCmd" value="<?php echo $cmds['Sleep'] ?>"><?php echo translate('Sleep') ?></button>
<?php
}
if ( $control->CanReset() ) {
?>
<button type="button" class="ptzTextBtn" data-on-click-this="controlCmd" value="<?php echo $cmds['Reset'] ?>"><?php echo translate('Reset') ?></button>
<button type="button" class="ptzTextBtn" data-on-click="controlCmd" value="<?php echo $cmds['Reset'] ?>"><?php echo translate('Reset') ?></button>
<?php
}
if ( $control->CanReboot() ) {
?>
<button type="button" class="ptzTextBtn" data-on-click-this="controlCmd" value="<?php echo $cmds['Reboot'] ?>"><?php echo translate('Reboot') ?></button>
<button type="button" class="ptzTextBtn" data-on-click="controlCmd" value="<?php echo $cmds['Reboot'] ?>"><?php echo translate('Reboot') ?></button>
<?php
}
?>
@ -223,9 +223,7 @@ function controlPower($monitor, $cmds) {
function ptzControls($monitor) {
$control = $monitor->Control();
//ZM\Error("Control: " . print_r($control,true));
$cmds = $control->commands();
//ZM\Error("Cmds: " . print_r($cmds, true));
ob_start();
?>
<div class="controlsPanel">

View File

@ -182,8 +182,8 @@ window.addEventListener("DOMContentLoaded", function onSkinDCL() {
return;
}
el.onclick = function() {
window[fnName]();
el.onclick = function(ev) {
window[fnName](ev);
};
});

View File

@ -71,6 +71,22 @@ var focusWindow = <?php echo !empty($focusWindow)?'true':'false' ?>;
var imagePrefix = "<?php echo '?view=image&eid=' ?>";
var auth_hash;
<?php if ( ZM_OPT_USE_AUTH && ZM_AUTH_HASH_LOGINS ) { ?>
auth_hash = '<?php echo generateAuthHash(ZM_AUTH_HASH_IPS) ?>';
<?php } ?>
var auth_relay;
<?php
if ( ZM_OPT_USE_AUTH ) {
if ( ZM_AUTH_RELAY == 'hashed' ) {
echo ' auth_hash = \''.generateAuthHash(ZM_AUTH_HASH_IPS).'\';
';
} else if ( ZM_AUTH_RELAY == 'plain' ) {
// password probably needs to be escaped
echo ' auth_relay=\'username='.$_SESSION['username'].'&password='.$_SESSION['password'].'\';
';
} else if ( ZM_AUTH_RELAY == 'none' ) {
// password probably needs to be escaped
echo ' auth_relay=\'username='.$_SESSION['username'].'\';
';
} else {
ZM\Error('Unknown value for ZM_AUTH_RELAY ' . ZM_AUTH_RELAY);
}
}
?>

View File

@ -258,7 +258,7 @@ while ( $event_row = dbFetchNext($results) ) {
echo '<td class="colThumbnail">';
$imgSrc = $event->getThumbnailSrc(array(),'&amp;');
$streamSrc = $event->getStreamSrc(array(
'mode'=>'jpeg', 'scale'=>$scale, 'maxfps'=>ZM_WEB_VIDEO_MAXFPS, 'replay'=>'single'), '&amp;');
'mode'=>'jpeg', 'scale'=>$scale, 'maxfps'=>ZM_WEB_VIDEO_MAXFPS, 'replay'=>'single', 'rate'=>'400'), '&amp;');
$imgHtml = '<img id="thumbnail'.$event->Id().'" src="'.$imgSrc.'" alt="'. validHtmlStr('Event '.$event->Id()) .'" style="width:'. validInt($event->ThumbnailWidth()) .'px;height:'. validInt($event->ThumbnailHeight()).'px;" stream_src="'.$streamSrc.'" still_src="'.$imgSrc.'"/>';
echo '<a href="?view=event&amp;eid='. $event->Id().$filterQuery.$sortQuery.'&amp;page=1">'.$imgHtml.'</a>';

View File

@ -13,6 +13,8 @@ function Monitor(monitorData) {
this.streamCmdParms = 'view=request&request=stream&connkey='+this.connKey;
if ( auth_hash ) {
this.streamCmdParms += '&auth='+auth_hash;
} else if ( auth_relay ) {
this.streamCmdParms += '&'+auth_relay;
}
this.streamCmdTimer = null;
this.type = monitorData.type;

View File

@ -21,13 +21,13 @@
}
?>';
if ( querySuffix == '?view=login' ) {
if ( querySuffix == '?view=login' || querySuffix == '' ) {
// If we didn't redirect elsewhere, then don't show login page, go to console
querySuffix = '?view=console';
}
var newUrl = querySuffix;
console.log("Redirecting to" + newUrl + ' ' + thisUrl);
console.log("Current location: " + window.location);
console.log("Redirecting to (" + newUrl + ') from :' + thisUrl);
window.location.replace(newUrl);
}
).delay( 500 );

View File

@ -546,42 +546,62 @@ function getEventCmdResponse( respObj, respText ) {
} );
for ( var i = 0; i < dbEvents.length; i++ ) {
var event = dbEvents[i];
var row = $('event'+event.Id);
var zm_event = dbEvents[i];
var row = $('event'+zm_event.Id);
var newEvent = (row == null ? true : false);
if ( newEvent ) {
row = new Element( 'tr', {'id': 'event'+event.Id} );
new Element( 'td', {'class': 'colId'} ).inject( row );
new Element( 'td', {'class': 'colName'} ).inject( row );
new Element( 'td', {'class': 'colTime'} ).inject( row );
new Element( 'td', {'class': 'colSecs'} ).inject( row );
new Element( 'td', {'class': 'colFrames'} ).inject( row );
new Element( 'td', {'class': 'colScore'} ).inject( row );
new Element( 'td', {'class': 'colDelete'} ).inject( row );
row = new Element('tr', {'id': 'event'+zm_event.Id});
new Element('td', {'class': 'colId'}).inject(row);
new Element('td', {'class': 'colName'}).inject(row);
new Element('td', {'class': 'colTime'}).inject(row);
new Element('td', {'class': 'colSecs'}).inject(row);
new Element('td', {'class': 'colFrames'}).inject(row);
new Element('td', {'class': 'colScore'}).inject(row);
new Element('td', {'class': 'colDelete'}).inject(row);
var link = new Element( 'a', {'href': '#', 'events': {'click': createEventPopup.pass( [event.Id, '&filter[Query][terms][0][attr]=MonitorId&filter[Query][terms][0][op]=%3d&filter[Query][terms][0][val]='+monitorId+'&page=1&popup=1', event.Width, event.Height] )}});
link.set( 'text', event.Id );
link.inject( row.getElement( 'td.colId' ) );
var link = new Element('a', {
'href': '#',
'events': {
'click': createEventPopup.pass( [
zm_event.Id,
'&filter[Query][terms][0][attr]=MonitorId&filter[Query][terms][0][op]=%3d&filter[Query][terms][0][val]='+monitorId+'&page=1&popup=1',
zm_event.Width,
zm_event.Height
] )
}
});
link.set('text', zm_event.Id);
link.inject(row.getElement('td.colId'));
link = new Element( 'a', {'href': '#', 'events': {'click': createEventPopup.pass( [event.Id, '&filter[Query][terms][0][attr]=MonitorId&filter[Query][terms][0][op]=%3d&filter[Query][terms][0][val]='+monitorId+'&page=1&popup=1', event.Width, event.Height] )}});
link.set( 'text', event.Name );
link.inject( row.getElement( 'td.colName' ) );
link = new Element('a', {
'href': '#',
'events': {
'click': createEventPopup.pass( [
zm_event.Id,
'&filter[Query][terms][0][attr]=MonitorId&filter[Query][terms][0][op]=%3d&filter[Query][terms][0][val]='+monitorId+'&page=1&popup=1',
zm_event.Width,
zm_event.Height
] )
}
});
link.set('text', zm_event.Name);
link.inject(row.getElement('td.colName'));
row.getElement( 'td.colTime' ).set( 'text', event.StartTime );
row.getElement( 'td.colSecs' ).set( 'text', event.Length );
row.getElement('td.colTime').set('text', zm_event.StartTime);
row.getElement('td.colSecs').set('text', zm_event.Length);
link = new Element( 'a', {'href': '#', 'events': {'click': createFramesPopup.pass( [event.Id, event.Width, event.Height] )}});
link.set( 'text', event.Frames+'/'+event.AlarmFrames );
link.inject( row.getElement( 'td.colFrames' ) );
link = new Element('a', {'href': '#', 'events': {'click': createFramesPopup.pass( [zm_event.Id, zm_event.Width, zm_event.Height] )}});
link.set('text', zm_event.Frames+'/'+zm_event.AlarmFrames);
link.inject(row.getElement('td.colFrames'));
link = new Element( 'a', {'href': '#', 'events': {'click': createFramePopup.pass( [event.Id, '0', event.Width, event.Height] )}});
link.set( 'text', event.AvgScore+'/'+event.MaxScore );
link.inject( row.getElement( 'td.colScore' ) );
link = new Element('a', {'href': '#', 'events': {'click': createFramePopup.pass( [zm_event.Id, '0', zm_event.Width, zm_event.Height] )}});
link.set('text', zm_event.AvgScore+'/'+zm_event.MaxScore);
link.inject(row.getElement('td.colScore'));
link = new Element( 'button', {
link = new Element('button', {
'type': 'button',
'title': deleteString,
'data-event-id': event.Id,
'data-event-id': zm_event.Id,
'events': {
'click': function(e) {
var event_id = e.target.getAttribute('data-event-id');
@ -608,14 +628,14 @@ function getEventCmdResponse( respObj, respText ) {
}
}
} else {
row.getElement('td.colName a').set('text', event.Name);
row.getElement('td.colSecs').set('text', event.Length);
row.getElement('td.colFrames a').set('text', event.Frames+'/'+event.AlarmFrames);
row.getElement('td.colScore a').set('text', event.AvgScore+'/'+event.MaxScore);
row.getElement('td.colName a').set('text', zm_event.Name);
row.getElement('td.colSecs').set('text', zm_event.Length);
row.getElement('td.colFrames a').set('text', zm_event.Frames+'/'+zm_event.AlarmFrames);
row.getElement('td.colScore a').set('text', zm_event.AvgScore+'/'+zm_event.MaxScore);
row.removeClass('recent');
}
row.addClass('updated');
}
} // end foreach event
var rows = $(eventListBody).getElements('tr');
for ( var i = 0; i < rows.length; i++ ) {
@ -631,7 +651,7 @@ function getEventCmdResponse( respObj, respText ) {
}
} else {
checkStreamForErrors('getEventCmdResponse', respObj);
}
} // end if objresult == ok
var eventCmdTimeout = eventsRefreshTimeout;
if ( alarmState == STATE_ALARM || alarmState == STATE_ALERT ) {
@ -672,7 +692,8 @@ function getControlResponse(respObj, respText) {
}
}
function controlCmd(button) {
function controlCmd(event) {
button = event.target;
control = button.getAttribute('value');
xtell = button.getAttribute('xtell');
ytell = button.getAttribute('ytell');
@ -687,7 +708,7 @@ function controlCmd(button) {
var y = event.pageY - coords.top;
if ( xtell ) {
var xge = parseInt( (x*100)/coords.width );
var xge = parseInt((x*100)/coords.width);
if ( xtell == -1 ) {
xge = 100 - xge;
} else if ( xtell == 2 ) {
@ -696,7 +717,7 @@ function controlCmd(button) {
locParms += '&xge='+xge;
}
if ( ytell ) {
var yge = parseInt( (y*100)/coords.height );
var yge = parseInt((y*100)/coords.height);
if ( ytell == -1 ) {
yge = 100 - yge;
} else if ( ytell == 2 ) {

View File

@ -782,20 +782,23 @@ include('_monitor_source_nvsocket.php');
} else if ( $monitor->Type() == 'Remote' ) {
?>
<tr><td><?php echo translate('RemoteProtocol') ?></td><td><?php echo htmlSelect( "newMonitor[Protocol]", $remoteProtocols, $monitor->Protocol(), "updateMethods( this );if(this.value=='rtsp'){\$('RTSPDescribe').setStyle('display','table-row');}else{\$('RTSPDescribe').hide();}" ); ?></td></tr>
<?php
?>
<tr>
<td><?php echo translate('RemoteMethod') ?></td>
<td>
<?php
if ( !$monitor->Protocol() || $monitor->Protocol() == 'http' ) {
?>
<tr><td><?php echo translate('RemoteMethod') ?></td><td><?php echo htmlSelect( "newMonitor[Method]", $httpMethods, $monitor->Method() ); ?></td></tr>
<?php
echo htmlSelect('newMonitor[Method]', $httpMethods, $monitor->Method() );
} else {
?>
<tr><td><?php echo translate('RemoteMethod') ?></td><td><?php echo htmlSelect( "newMonitor[Method]", $rtspMethods, $monitor->Method() ); ?></td></tr>
<?php
echo htmlSelect('newMonitor[Method]', $rtspMethods, $monitor->Method() );
}
?>
<tr><td><?php echo translate('RemoteHostName') ?></td><td><input type="text" name="newMonitor[Host]" value="<?php echo validHtmlStr($monitor->Host()) ?>" size="36"/></td></tr>
</td>
</tr>
<tr><td><?php echo translate('RemoteHostName') ?></td><td><input type="text" name="newMonitor[Host]" value="<?php echo validHtmlStr($monitor->Host()) ?>"/></td></tr>
<tr><td><?php echo translate('RemoteHostPort') ?></td><td><input type="number" name="newMonitor[Port]" value="<?php echo validHtmlStr($monitor->Port()) ?>" size="6"/></td></tr>
<tr><td><?php echo translate('RemoteHostPath') ?></td><td><input type="text" name="newMonitor[Path]" value="<?php echo validHtmlStr($monitor->Path()) ?>" size="36"/></td></tr>
<tr><td><?php echo translate('RemoteHostPath') ?></td><td><input type="text" name="newMonitor[Path]" value="<?php echo validHtmlStr($monitor->Path()) ?>"/></td></tr>
<?php
} else if ( $monitor->Type() == 'File' ) {
?>
@ -803,23 +806,44 @@ include('_monitor_source_nvsocket.php');
<?php
} elseif ( $monitor->Type() == 'cURL' ) {
?>
<tr><td><?php echo 'URL' ?></td><td><input type="text" name="newMonitor[Path]" value="<?php echo validHtmlStr($monitor->Path()) ?>" size="36"/></td></tr>
<tr><td><?php echo 'Username' ?></td><td><input type="text" name="newMonitor[User]" value="<?php echo validHtmlStr($monitor->User()) ?>" size="12"/></td></tr>
<tr><td><?php echo 'Password' ?></td><td><input type="text" name="newMonitor[Pass]" value="<?php echo validHtmlStr($monitor->Pass()) ?>" size="12"/></td></tr>
<tr><td><?php echo 'URL' ?></td><td><input type="text" name="newMonitor[Path]" value="<?php echo validHtmlStr($monitor->Path()) ?>"/></td></tr>
<tr><td><?php echo 'Username' ?></td><td><input type="text" name="newMonitor[User]" value="<?php echo validHtmlStr($monitor->User()) ?>"/></td></tr>
<tr><td><?php echo 'Password' ?></td><td><input type="text" name="newMonitor[Pass]" value="<?php echo validHtmlStr($monitor->Pass()) ?>"/></td></tr>
<?php
} elseif ( $monitor->Type() == 'WebSite' ) {
?>
<tr><td><?php echo translate('WebSiteUrl') ?></td><td><input type="text" name="newMonitor[Path]" value="<?php echo validHtmlStr($monitor->Path()) ?>" size="36"/></td></tr>
<tr><td><?php echo translate('Width') ?> (<?php echo translate('Pixels') ?>)</td><td><input type="text" name="newMonitor[Width]" value="<?php echo validHtmlStr($monitor->Width()) ?>" size="4";"/></td></tr>
<tr><td><?php echo translate('Height') ?> (<?php echo translate('Pixels') ?>)</td><td><input type="text" name="newMonitor[Height]" value="<?php echo validHtmlStr($monitor->Height()) ?>" size="4";"/></td></tr>
<tr><td><?php echo 'Web Site Refresh (Optional)' ?></td><td><input type="number" name="newMonitor[Refresh]" value="<?php echo validHtmlStr($monitor->Refresh()); ?>"/></td></tr>
<tr>
<td><?php echo translate('WebSiteUrl') ?></td>
<td><input type="text" name="newMonitor[Path]" value="<?php echo validHtmlStr($monitor->Path()) ?>"/></td>
</tr>
<tr>
<td><?php echo translate('Width') ?> (<?php echo translate('Pixels') ?>)</td>
<td><input type="number" name="newMonitor[Width]" value="<?php echo validHtmlStr($monitor->Width()) ?>" size="4"/></td>
</tr>
<tr>
<td><?php echo translate('Height') ?> (<?php echo translate('Pixels') ?>)</td>
<td><input type="number" name="newMonitor[Height]" value="<?php echo validHtmlStr($monitor->Height()) ?>" size="4"/></td>
</tr>
<tr>
<td><?php echo 'Web Site Refresh (Optional)' ?></td>
<td><input type="number" name="newMonitor[Refresh]" value="<?php echo validHtmlStr($monitor->Refresh()) ?>"/></td>
</tr>
<?php
} elseif ( $monitor->Type() == 'Ffmpeg' || $monitor->Type() == 'Libvlc' ) {
} else if ( $monitor->Type() == 'Ffmpeg' || $monitor->Type() == 'Libvlc' ) {
?>
<tr class="SourcePath"><td><?php echo translate('SourcePath') ?></td><td><input type="text" name="newMonitor[Path]" value="<?php echo validHtmlStr($monitor->Path()) ?>" /></td></tr>
<tr><td><?php echo translate('RemoteMethod') ?>&nbsp;(<?php echo makePopupLink('?view=optionhelp&amp;option=OPTIONS_RTSPTrans', 'zmOptionHelp', 'optionhelp', '?' ) ?>)</td><td><?php echo htmlSelect( "newMonitor[Method]", $rtspFFMpegMethods, $monitor->Method() ); ?></td></tr>
<tr class="SourcePath">
<td><?php echo translate('SourcePath') ?></td>
<td><input type="text" name="newMonitor[Path]" value="<?php echo validHtmlStr($monitor->Path()) ?>" /></td>
</tr>
<tr>
<td><?php
echo translate('RemoteMethod');
echo makePopupLink('?view=optionhelp&amp;option=OPTIONS_RTSPTrans', 'zmOptionHelp', 'optionhelp', '?' );
?>)</td>
<td><?php echo htmlSelect('newMonitor[Method]', $rtspFFMpegMethods, $monitor->Method()) ?></td>
</tr>
<tr class="SourceOptions">
<td><?php echo translate('Options') ?>&nbsp;(<?php echo makePopupLink( '?view=optionhelp&amp;option=OPTIONS_'.strtoupper($monitor->Type()), 'zmOptionHelp', 'optionhelp', '?' ) ?>)</td>
<td><?php echo translate('Options') ?>&nbsp;(<?php echo makePopupLink('?view=optionhelp&amp;option=OPTIONS_'.strtoupper($monitor->Type()), 'zmOptionHelp', 'optionhelp', '?' ) ?>)</td>
<td><input type="text" name="newMonitor[Options]" value="<?php echo validHtmlStr($monitor->Options()) ?>"/></td>
</tr>
<?php
@ -840,10 +864,12 @@ include('_monitor_source_nvsocket.php');
</tr>
<?php
}
if ( $monitor->Type() != 'NVSocket' && $monitor->Type() != 'WebSite' ) {
if ( $monitor->Type() != 'NVSocket' && $monitor->Type() != 'WebSite' ) {
?>
<tr><td><?php echo translate('TargetColorspace') ?></td><td><?php echo htmlSelect('newMonitor[Colours]', $Colours, $monitor->Colours() ); ?>
</td></tr>
<tr>
<td><?php echo translate('TargetColorspace') ?></td>
<td><?php echo htmlSelect('newMonitor[Colours]', $Colours, $monitor->Colours()) ?></td>
</tr>
<tr>
<td><?php echo translate('CaptureResolution') ?> (<?php echo translate('Pixels') ?>)</td>
<td>
@ -884,18 +910,22 @@ if ( $monitor->Type() != 'NVSocket' && $monitor->Type() != 'WebSite' ) {
<td><?php echo htmlselect('newMonitor[Orientation]', $orientations, $monitor->Orientation());?></td>
</tr>
<?php
}
if ( $monitor->Type() == 'Local' ) {
}
if ( $monitor->Type() == 'Local' ) {
?>
<tr><td><?php echo translate('Deinterlacing') ?></td><td><select name="newMonitor[Deinterlacing]"><?php foreach ( $deinterlaceopts_v4l2 as $name => $value ) { ?><option value="<?php echo validHtmlStr($value); ?>"<?php if ( $value == $monitor->Deinterlacing()) { ?> selected="selected"<?php } ?>><?php echo validHtmlStr($name); ?></option><?php } ?></select></td></tr>
<?php
<tr>
<td><?php echo translate('Deinterlacing') ?></td>
<td><?php echo htmlselect('newMonitor[Deinterlacing]', $deinterlaceopts_v4l2, $monitor->Deinterlacing())?></td>
</tr>
<?php
} else if ( $monitor->Type() != 'WebSite' ) {
?>
<tr><td><?php echo translate('Deinterlacing') ?></td><td><select name="newMonitor[Deinterlacing]"><?php foreach ( $deinterlaceopts as $name => $value ) { ?><option value="<?php echo validHtmlStr($value); ?>"<?php if ( $value == $monitor->Deinterlacing()) { ?> selected="selected"<?php } ?>><?php echo validHtmlStr($name); ?></option><?php } ?></select></td></tr>
<tr>
<td><?php echo translate('Deinterlacing') ?></td>
<td><?php echo htmlselect('newMonitor[Deinterlacing]', $deinterlaceopts, $monitor->Deinterlacing())?></td>
</tr>
<?php
}
?>
<?php
if ( $monitor->Type() == 'Remote' ) {
?>
<tr id="RTSPDescribe"<?php if ( $monitor->Protocol()!= 'rtsp' ) { echo ' style="display:none;"'; } ?>><td><?php echo translate('RTSPDescribe') ?>&nbsp;(<?php echo makePopupLink( '?view=optionhelp&amp;option=OPTIONS_RTSPDESCRIBE', 'zmOptionHelp', 'optionhelp', '?' ) ?>) </td><td><input type="checkbox" name="newMonitor[RTSPDescribe]" value="1"<?php if ( $monitor->RTSPDescribe() ) { ?> checked="checked"<?php } ?>/></td></tr>
@ -939,15 +969,17 @@ if ( $monitor->Type() == 'Local' ) {
$videowriteropts[1] = 'X264 Encode';
if ($monitor->Type() == 'Ffmpeg' )
if ( $monitor->Type() == 'Ffmpeg' )
$videowriteropts[2] = 'H264 Camera Passthrough';
else
$videowriteropts[2] = array('text'=>'H264 Camera Passthrough - only for FFMPEG','disabled'=>1);
echo htmlselect( 'newMonitor[VideoWriter]', $videowriteropts, $monitor->VideoWriter() );
echo htmlselect('newMonitor[VideoWriter]', $videowriteropts, $monitor->VideoWriter());
?>
</td></tr>
<tr><td><?php echo translate('OptionalEncoderParam') ?></td><td><textarea name="newMonitor[EncoderParameters]" rows="4" cols="36"><?php echo validHtmlStr($monitor->EncoderParameters()) ?></textarea></td></tr>
<tr>
<td><?php echo translate('OptionalEncoderParam') ?></td>
<td><textarea name="newMonitor[EncoderParameters]" rows="4" cols="36"><?php echo validHtmlStr($monitor->EncoderParameters()) ?></textarea></td></tr>
<tr><td><?php echo translate('RecordAudio') ?></td><td>
<?php if ( $monitor->Type() == 'Ffmpeg' ) { ?>
<input type="checkbox" name="newMonitor[RecordAudio]" value="1"<?php if ( $monitor->RecordAudio() ) { ?> checked="checked"<?php } ?>/>
@ -962,22 +994,52 @@ if ( $monitor->Type() == 'Local' ) {
case 'timestamp' :
{
?>
<tr><td><?php echo translate('TimestampLabelFormat') ?></td><td><input type="text" name="newMonitor[LabelFormat]" value="<?php echo validHtmlStr($monitor->LabelFormat()) ?>" size="32"/></td></tr>
<tr><td><?php echo translate('TimestampLabelX') ?></td><td><input type="text" name="newMonitor[LabelX]" value="<?php echo validHtmlStr($monitor->LabelX()) ?>" size="4"/></td></tr>
<tr><td><?php echo translate('TimestampLabelY') ?></td><td><input type="text" name="newMonitor[LabelY]" value="<?php echo validHtmlStr($monitor->LabelY()) ?>" size="4"/></td></tr>
<tr><td><?php echo translate('TimestampLabelSize') ?></td><td><select name="newMonitor[LabelSize]"><?php foreach ( $label_size as $name => $value ) { ?><option value="<?php echo validHtmlStr($value); ?>"<?php if ( $value == $monitor->LabelSize() ) { ?> selected="selected"<?php } ?>><?php echo validHtmlStr($name); ?></option><?php } ?></select></td></tr>
<tr>
<td><?php echo translate('TimestampLabelFormat') ?></td>
<td><input type="text" name="newMonitor[LabelFormat]" value="<?php echo validHtmlStr($monitor->LabelFormat()) ?>"/></td>
</tr>
<tr>
<td><?php echo translate('TimestampLabelX') ?></td>
<td><input type="number" name="newMonitor[LabelX]" value="<?php echo validHtmlStr($monitor->LabelX()) ?>" size="4"/></td>
</tr>
<tr>
<td><?php echo translate('TimestampLabelY') ?></td>
<td><input type="number" name="newMonitor[LabelY]" value="<?php echo validHtmlStr($monitor->LabelY()) ?>" size="4"/></td>
</tr>
<tr>
<td><?php echo translate('TimestampLabelSize') ?></td>
<td><?php echo htmlselect('newMonitor[LabelSize]', $label_size, $monitor->LabelSize()) ?></td>
</tr>
<?php
break;
}
case 'buffers' :
{
?>
<tr><td><?php echo translate('ImageBufferSize') ?></td><td><input type="text" name="newMonitor[ImageBufferCount]" value="<?php echo validHtmlStr($monitor->ImageBufferCount()) ?>" size="6"/></td></tr>
<tr><td><?php echo translate('WarmupFrames') ?></td><td><input type="text" name="newMonitor[WarmupCount]" value="<?php echo validHtmlStr($monitor->WarmupCount()) ?>" size="4"/></td></tr>
<tr><td><?php echo translate('PreEventImageBuffer') ?></td><td><input type="text" name="newMonitor[PreEventCount]" value="<?php echo validHtmlStr($monitor->PreEventCount()) ?>" size="4"/></td></tr>
<tr><td><?php echo translate('PostEventImageBuffer') ?></td><td><input type="text" name="newMonitor[PostEventCount]" value="<?php echo validHtmlStr($monitor->PostEventCount()) ?>" size="4"/></td></tr>
<tr><td><?php echo translate('StreamReplayBuffer') ?></td><td><input type="text" name="newMonitor[StreamReplayBuffer]" value="<?php echo validHtmlStr($monitor->StreamReplayBuffer()) ?>" size="6"/></td></tr>
<tr><td><?php echo translate('AlarmFrameCount') ?></td><td><input type="text" name="newMonitor[AlarmFrameCount]" value="<?php echo validHtmlStr($monitor->AlarmFrameCount()) ?>" size="4"/></td></tr>
<tr>
<td><?php echo translate('ImageBufferSize') ?></td>
<td><input type="number" name="newMonitor[ImageBufferCount]" value="<?php echo validHtmlStr($monitor->ImageBufferCount()) ?>" size="6"/></td>
</tr>
<tr>
<td><?php echo translate('WarmupFrames') ?></td>
<td><input type="number" name="newMonitor[WarmupCount]" value="<?php echo validHtmlStr($monitor->WarmupCount()) ?>" size="4"/></td>
</tr>
<tr>
<td><?php echo translate('PreEventImageBuffer') ?></td>
<td><input type="number" name="newMonitor[PreEventCount]" value="<?php echo validHtmlStr($monitor->PreEventCount()) ?>" size="4"/></td>
</tr>
<tr>
<td><?php echo translate('PostEventImageBuffer') ?></td>
<td><input type="number" name="newMonitor[PostEventCount]" value="<?php echo validHtmlStr($monitor->PostEventCount()) ?>" size="4"/></td>
</tr>
<tr>
<td><?php echo translate('StreamReplayBuffer') ?></td>
<td><input type="number" name="newMonitor[StreamReplayBuffer]" value="<?php echo validHtmlStr($monitor->StreamReplayBuffer()) ?>" size="6"/></td>
</tr>
<tr>
<td><?php echo translate('AlarmFrameCount') ?></td>
<td><input type="number" name="newMonitor[AlarmFrameCount]" value="<?php echo validHtmlStr($monitor->AlarmFrameCount()) ?>" size="4"/></td>
</tr>
<?php
break;
}
@ -986,7 +1048,8 @@ if ( $monitor->Type() == 'Local' ) {
?>
<tr>
<td><?php echo translate('Controllable') ?></td>
<td><input type="checkbox" name="newMonitor[Controllable]" value="1"<?php if ( $monitor->Controllable() ) { ?> checked="checked"<?php } ?>/></td></tr>
<td><input type="checkbox" name="newMonitor[Controllable]" value="1"<?php if ( $monitor->Controllable() ) { ?> checked="checked"<?php } ?>/></td>
</tr>
<tr>
<td><?php echo translate('ControlType') ?></td>
<td><?php echo htmlSelect('newMonitor[ControlId]', $controlTypes, $monitor->ControlId());
@ -1011,20 +1074,19 @@ if ( canEdit('Control') ) {
<td><?php echo translate('TrackMotion') ?></td>
<td><input type="checkbox" name="newMonitor[TrackMotion]" value="1"<?php if ( $monitor->TrackMotion() ) { ?> checked="checked"<?php } ?>/></td>
</tr>
<?php
$return_options = array(
'-1' => translate('None'),
'0' => translate('Home'),
'1' => translate('Preset').' 1',
);
?>
<tr>
<td><?php echo translate('TrackDelay') ?></td>
<td><input type="number" name="newMonitor[TrackDelay]" value="<?php echo validHtmlStr($monitor->TrackDelay()) ?>"/></td>
</tr>
<tr>
<td><?php echo translate('ReturnLocation') ?></td>
<td><?php echo htmlSelect('newMonitor[ReturnLocation]', $return_options, $monitor->ReturnLocation()); ?></td>
<td><?php
$return_options = array(
'-1' => translate('None'),
'0' => translate('Home'),
'1' => translate('Preset').' 1',
);
echo htmlSelect('newMonitor[ReturnLocation]', $return_options, $monitor->ReturnLocation()); ?></td>
</tr>
<tr>
<td><?php echo translate('ReturnDelay') ?></td>

View File

@ -1,6 +1,6 @@
<?php
//
// ZoneMinder web watch feed view file, $Date$, $Revision$
// ZoneMinder web watch feed view file
// Copyright (C) 2001-2008 Philip Coombes
//
// This program is free software; you can redistribute it and/or
@ -46,17 +46,16 @@ if ( isset($_REQUEST['scale']) ) {
} else if ( isset($_COOKIE['zmWatchScale'.$mid]) ) {
$scale = $_COOKIE['zmWatchScale'.$mid];
} else {
$scale = reScale(SCALE_BASE, $monitor->DefaultScale(), ZM_WEB_DEFAULT_SCALE);
$scale = $monitor->DefaultScale();
}
$connkey = generateConnKey();
$streamMode = getStreamMode();
noCacheHeaders();
$popup = ((isset($_REQUEST['popup'])) && ($_REQUEST['popup'] == 1));
noCacheHeaders();
xhtmlHeaders(__FILE__, $monitor->Name().' - '.translate('Feed'));
?>
<body>
@ -77,7 +76,7 @@ if ( canView('Control') && $monitor->Type() == 'Local' ) {
<div id="closeControl"><a href="#" data-on-click="<?php echo $popup ? 'closeWindow' : 'backWindow' ?>"><?php echo $popup ? translate('Close') : translate('Back') ?></a></div>
</div>
<?php
if ( $monitor->Status() != 'Connected' ) {
if ( $monitor->Status() != 'Connected' and $monitor->Type() != 'WebSite' ) {
echo '<div class="warning">Monitor is not capturing. We will be unable to provide an image</div>';
}
?>