Merge branch 'fix_zms'

pull/2924/head
Isaac Connor 2020-04-26 18:43:39 -04:00
commit e21ffbea7d
11 changed files with 388 additions and 320 deletions

View File

@ -22,7 +22,7 @@
#endif
#include <errno.h>
#ifdef _WIN32 || _WIN64
#if defined(_WIN32) || defined(_WIN64)
// On windows we need to generate random bytes differently.
typedef __int64 ssize_t;
#define BCRYPT_HASHSIZE 60
@ -117,7 +117,7 @@ int bcrypt_gensalt(int factor, char salt[BCRYPT_HASHSIZE])
char *aux;
// Note: Windows does not have /dev/urandom sadly.
#ifdef _WIN32 || _WIN64
#if defined(_WIN32) || defined(_WIN64)
HCRYPTPROV p;
ULONG i;

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,
@ -262,7 +276,7 @@ bool EventStream::loadEventData(uint64_t event_id) {
last_id = id;
last_delta = delta;
last_timestamp = event_data->frames[id-1].timestamp;
Debug(4, "Frame %d timestamp:(%f), offset(%f) delta(%f), in_db(%d)",
Debug(3, "Frame %d timestamp:(%f), offset(%f) delta(%f), in_db(%d)",
id,
event_data->frames[id-1].timestamp,
event_data->frames[id-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");
@ -504,6 +521,7 @@ void EventStream::processCommand(const CmdMsg *msg) {
// Do nothing, for now
break;
}
struct {
uint64_t event_id;
int progress;
@ -541,9 +559,9 @@ void EventStream::processCommand(const CmdMsg *msg) {
exit(0);
updateFrameRate((double)event_data->frame_count/event_data->duration);
} // void EventStream::processCommand(const CmdMsg *msg)
} // void EventStream::processCommand(const CmdMsg *msg)
void EventStream::checkEventLoaded() {
bool EventStream::checkEventLoaded() {
static char sql[ZM_SQL_SML_BUFSIZ];
if ( curr_frame_id <= 0 ) {
@ -558,7 +576,7 @@ void EventStream::checkEventLoaded() {
// No event change required
Debug(3, "No event change required, as curr frame %d <=> event frames %d",
curr_frame_id, event_data->frame_count);
return;
return false;
}
// Event change required.
@ -592,6 +610,7 @@ void EventStream::checkEventLoaded() {
else
curr_frame_id = 1;
Debug(2, "New frame id = %d", curr_frame_id);
return true;
} else {
Debug(2, "No next event loaded using %s. Pausing", sql);
if ( curr_frame_id <= 0 )
@ -600,7 +619,7 @@ void EventStream::checkEventLoaded() {
curr_frame_id = event_data->frame_count;
paused = true;
sendTextFrame("No more event data found");
} // end if found a new event or not
} // end if found a new event or not
mysql_free_result(result);
forceEventChange = false;
} else {
@ -611,7 +630,8 @@ void EventStream::checkEventLoaded() {
curr_frame_id = event_data->frame_count;
paused = true;
}
} // void EventStream::checkEventLoaded()
return false;
} // void EventStream::checkEventLoaded()
Image * EventStream::getImage( ) {
static char filepath[PATH_MAX];
@ -656,7 +676,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();
}
@ -699,9 +720,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);
@ -766,6 +788,10 @@ Debug(1, "Loading image");
Fatal("Unexpected frame type %d", type);
break;
}
if ( send_image != image ) {
delete send_image;
send_image = NULL;
}
delete image;
image = NULL;
} // end if send_raw or not
@ -839,6 +865,10 @@ void EventStream::runStream() {
updateFrameRate((double)event_data->frame_count/event_data->duration);
gettimeofday(&start, NULL);
uint64_t start_usec = start.tv_sec * 1000000 + start.tv_usec;
uint64_t last_frame_offset = 0;
bool in_event = true;
double time_to_event = 0;
while ( !zm_terminate ) {
gettimeofday(&now, NULL);
@ -862,73 +892,14 @@ void EventStream::runStream() {
// Get current frame data
FrameData *frame_data = &event_data->frames[curr_frame_id-1];
//Info( "cst:%.2f", curr_stream_time );
//Info( "cfid:%d", curr_frame_id );
//Info( "fdt:%d", frame_data->timestamp );
if ( !paused ) {
Debug(3, "Not paused at frame %d", curr_frame_id);
// This next bit is to determine if we are in the current event time wise
// and whether to show an image saying how long until the next event.
bool in_event = true;
double time_to_event = 0;
if ( replay_rate > 0 ) {
time_to_event = event_data->frames[0].timestamp - curr_stream_time;
if ( time_to_event > 0 )
in_event = false;
} else if ( replay_rate < 0 ) {
time_to_event = curr_stream_time - event_data->frames[event_data->frame_count-1].timestamp;
if ( time_to_event > 0 )
in_event = false;
}
Debug(1, "replay rate(%d) in_event(%d) time_to_event(%f)=curr_stream_time(%f)-frame timestamp:%f",
replay_rate, in_event, time_to_event, curr_stream_time, event_data->frames[event_data->frame_count-1].timestamp);
if ( !in_event ) {
double actual_delta_time = TV_2_FLOAT(now) - last_frame_sent;
Debug(1, "Ctual delta time = %f = %f - %f", actual_delta_time , TV_2_FLOAT(now) , last_frame_sent);
// > 1 second
if ( actual_delta_time > 1 ) {
Debug(1, "Sending time to next event frame");
static char frame_text[64];
snprintf(frame_text, sizeof(frame_text), "Time to next event = %d seconds", (int)time_to_event);
if ( !sendTextFrame(frame_text) )
zm_terminate = true;
} else {
Debug(1, "Not Sending time to next event frame because actual delta time is %f", actual_delta_time);
}
//else
//{
// FIXME ICON But we are not paused. We are somehow still in the event?
double sleep_time = (replay_rate>0?1:-1) * ((1.0L * replay_rate * STREAM_PAUSE_WAIT)/(ZM_RATE_BASE * 1000000));
//double sleep_time = (replay_rate * STREAM_PAUSE_WAIT)/(ZM_RATE_BASE * 1000000);
//// ZM_RATE_BASE == 100, and 1x replay_rate is 100
//double sleep_time = ((replay_rate/ZM_RATE_BASE) * STREAM_PAUSE_WAIT)/1000000;
if ( ! sleep_time ) {
sleep_time += STREAM_PAUSE_WAIT/1000000;
}
curr_stream_time += sleep_time;
Debug(2, "Sleeping (%dus) because we are not at the next event yet, adding %f", STREAM_PAUSE_WAIT, sleep_time);
usleep(STREAM_PAUSE_WAIT);
//curr_stream_time += (1.0L * replay_rate * STREAM_PAUSE_WAIT)/(ZM_RATE_BASE * 1000000);
//}
continue;
} // end if !in_event
// Figure out if we should send this frame
Debug(3, "cur_frame_id (%d-1) mod frame_mod(%d)", curr_frame_id, frame_mod);
Debug(3, "not paused at cur_frame_id (%d-1) mod frame_mod(%d)", curr_frame_id, frame_mod);
// If we are streaming and this frame is due to be sent
// frame mod defaults to 1 and if we are going faster than max_fps will get multiplied by 2
// so if it is 2, then we send every other frame, if is it 4 then every fourth frame, etc.
if ( (frame_mod == 1) || (((curr_frame_id-1)%frame_mod) == 0) ) {
delta_us = (unsigned int)(frame_data->delta * 1000000);
Debug(3, "frame delta %uus ", delta_us);
// if effective > base we should speed up frame delivery
delta_us = (unsigned int)((delta_us * base_fps)/effective_fps);
Debug(3, "delta %u = base_fps(%f)/effective fps(%f)", delta_us, base_fps, effective_fps);
// but must not exceed maxfps
delta_us = max(delta_us, 1000000 / maxfps);
Debug(3, "delta %u = base_fps(%f)/effective fps(%f) from 30fps", delta_us, base_fps, effective_fps);
send_frame = true;
}
} else if ( step != 0 ) {
@ -937,16 +908,48 @@ void EventStream::runStream() {
step = 0;
send_frame = true;
} else if ( !send_frame ) {
// We are paused, not stepping and doing nothing
// We are paused, not stepping and doing nothing, meaning that comms didn't set send_frame to true
double actual_delta_time = TV_2_FLOAT(now) - last_frame_sent;
if ( actual_delta_time > MAX_STREAM_DELAY ) {
// Send keepalive
Debug(2, "Sending keepalive frame");
send_frame = true;
//} else {
//Debug(2, "Not Sending keepalive frame");
}
} // end if streaming stepping or doing nothing
} // end if streaming stepping or doing nothing
// time_to_event > 0 means that we are not in the event
if ( time_to_event > 0 ) {
double actual_delta_time = TV_2_FLOAT(now) - last_frame_sent;
Debug(1, "Actual delta time = %f = %f - %f", actual_delta_time, TV_2_FLOAT(now), last_frame_sent);
// > 1 second
if ( actual_delta_time > 1 ) {
Debug(1, "Sending time to next event frame");
static char frame_text[64];
snprintf(frame_text, sizeof(frame_text), "Time to next event = %d seconds", (int)time_to_event);
if ( !sendTextFrame(frame_text) )
zm_terminate = true;
} else {
Debug(1, "Not Sending time to next event frame because actual delta time is %f", actual_delta_time);
}
//else
//{
// FIXME ICON But we are not paused. We are somehow still in the event?
double sleep_time = (replay_rate>0?1:-1) * ((1.0L * replay_rate * STREAM_PAUSE_WAIT)/(ZM_RATE_BASE * 1000000));
//double sleep_time = (replay_rate * STREAM_PAUSE_WAIT)/(ZM_RATE_BASE * 1000000);
//// ZM_RATE_BASE == 100, and 1x replay_rate is 100
//double sleep_time = ((replay_rate/ZM_RATE_BASE) * STREAM_PAUSE_WAIT)/1000000;
if ( !sleep_time ) {
sleep_time += STREAM_PAUSE_WAIT/1000000;
}
curr_stream_time += sleep_time;
time_to_event -= sleep_time;
Debug(2, "Sleeping (%dus) because we are not at the next event yet, adding %f", STREAM_PAUSE_WAIT, sleep_time);
usleep(STREAM_PAUSE_WAIT);
//curr_stream_time += (1.0L * replay_rate * STREAM_PAUSE_WAIT)/(ZM_RATE_BASE * 1000000);
//}
continue;
} // end if !in_event
if ( send_frame ) {
if ( !sendFrame(delta_us) ) {
@ -958,6 +961,17 @@ void EventStream::runStream() {
curr_stream_time = frame_data->timestamp;
if ( !paused ) {
// delta is since the last frame
delta_us = (unsigned int)(frame_data->delta * 1000000);
Debug(3, "frame delta %uus ", delta_us);
// if effective > base we should speed up frame delivery
delta_us = (unsigned int)((delta_us * base_fps)/effective_fps);
Debug(3, "delta %u = base_fps(%f)/effective fps(%f)", delta_us, base_fps, effective_fps);
// but must not exceed maxfps
delta_us = max(delta_us, 1000000/maxfps);
Debug(3, "delta %u = base_fps(%f)/effective fps(%f) from 30fps", delta_us, base_fps, effective_fps);
// +/- 1? What if we are skipping frames?
curr_frame_id += (replay_rate>0) ? frame_mod : -1*frame_mod;
// sending the frame may have taken some time, so reload now
@ -965,7 +979,12 @@ void EventStream::runStream() {
uint64_t now_usec = (now.tv_sec * 1000000 + now.tv_usec);
// we incremented by replay_rate, so might have jumped past frame_count
if ( (mode == MODE_SINGLE) && ((unsigned int)curr_frame_id >= event_data->frame_count) ) {
if ( (mode == MODE_SINGLE) && (
(curr_frame_id < 1 )
||
((unsigned int)curr_frame_id >= event_data->frame_count)
)
) {
Debug(2, "Have mode==MODE_SINGLE and at end of event, looping back to start");
curr_frame_id = 1;
// Have to reset start_usec to now when replaying
@ -980,9 +999,21 @@ void EventStream::runStream() {
// There are two ways to go about this, not sure which is correct.
// 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 ( last_frame_offset ) {
// We assume that we are going forward and the next frame is in the future.
delta_us = frame_data->offset * 1000000 - (now_usec-start_usec);
// - (now_usec - start_usec);
Debug(2, "New delta_us now %" PRIu64 " - start %" PRIu64 " = %d offset %" PRId64 " - elapsed = %dusec",
now_usec, start_usec, now_usec-start_usec, frame_data->offset * 1000000, delta_us);
} else {
Debug(2, "No last frame_offset, no sleep");
delta_us = 0;
}
last_frame_offset = frame_data->offset * 1000000;
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;
@ -1007,16 +1038,34 @@ void EventStream::runStream() {
}
usleep(delta_us);
}
} // end if !paused
//if ( step != 0 )// Adding 0 is cheaper than an if 0
// curr_frame_id starts at 1 though, so we might skip the first frame?
// We are paused, so might be stepping
//if ( step != 0 )// Adding 0 is cheaper than an if 0
// curr_frame_id starts at 1 though, so we might skip the first frame?
curr_frame_id += step;
// Detects when we hit end of event and will load the next event or previous event
if ( !paused )
checkEventLoaded();
} // end while ! zm_terminate
// Detects when we hit end of event and will load the next event or previous event
if ( checkEventLoaded() ) {
// Have change of event
// This next bit is to determine if we are in the current event time wise
// and whether to show an image saying how long until the next event.
if ( replay_rate > 0 ) {
// This doesn't make sense unless we have hit the end of the event.
time_to_event = event_data->frames[0].timestamp - curr_stream_time;
Debug(1, "replay rate(%d) time_to_event(%f)=frame timestamp:%f - curr_stream_time(%f)",
replay_rate, time_to_event,
event_data->frames[0].timestamp,
curr_stream_time);
} else if ( replay_rate < 0 ) {
time_to_event = curr_stream_time - event_data->frames[event_data->frame_count-1].timestamp;
Debug(1, "replay rate(%d) time_to_event(%f)=curr_stream_time(%f)-frame timestamp:%f",
replay_rate, time_to_event, curr_stream_time, event_data->frames[event_data->frame_count-1].timestamp);
} // end if forward or reverse
} // end if checkEventLoaded
} // end if !paused
} // end while ! zm_terminate
#if HAVE_LIBAVCODEC
if ( type == STREAM_MPEG )
delete vid_stream;
@ -1025,18 +1074,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

@ -81,13 +81,12 @@ class EventStream : public StreamBase {
EventData *event_data;
protected:
bool loadEventData( uint64_t event_id );
bool loadInitialEventData( uint64_t init_event_id, unsigned int init_frame_id );
bool loadInitialEventData( int monitor_id, time_t event_time );
void checkEventLoaded();
bool checkEventLoaded();
void processCommand( const CmdMsg *msg );
bool sendFrame( int delta_us );
@ -99,12 +98,30 @@ class EventStream : public StreamBase {
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)
{}
~EventStream() {
if ( event_data ) {
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 ) {
@ -113,6 +130,7 @@ class EventStream : public StreamBase {
void runStream();
Image *getImage();
private:
Storage *storage;
FFmpeg_Input *ffmpeg_input;
AVCodecContext *input_codec_context;
AVCodec *input_codec;

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;
@ -211,15 +227,17 @@ AVFrame *FFmpeg_Input::get_frame(int stream_id, double at) {
last_seek_request = seek_target;
// Seeking seems to typically seek to a keyframe, so then we have to decode until we get the frame we want.
if ( frame->pts <= seek_target ) {
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)
} // 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,7 +162,7 @@ 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';
@ -185,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;
@ -217,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();
}
@ -227,35 +231,39 @@ Image::~Image() {
/* Should be called as part of program shutdown to free everything */
void Image::Deinitialise() {
if ( initialised ) {
/*
delete[] y_table;
delete[] uv_table;
delete[] r_v_table;
delete[] g_v_table;
delete[] g_u_table;
delete[] b_u_table;
if ( !initialised ) return;
/*
delete[] y_table;
delete[] uv_table;
delete[] r_v_table;
delete[] g_v_table;
delete[] g_u_table;
delete[] b_u_table;
*/
initialised = false;
if ( readjpg_dcinfo ) {
jpeg_destroy_decompress( readjpg_dcinfo );
delete readjpg_dcinfo;
readjpg_dcinfo = 0;
}
if ( decodejpg_dcinfo ) {
jpeg_destroy_decompress( decodejpg_dcinfo );
delete decodejpg_dcinfo;
decodejpg_dcinfo = 0;
}
for ( unsigned int quality=0; quality <= 100; quality += 1 ) {
if ( writejpg_ccinfo[quality] ) {
jpeg_destroy_compress( writejpg_ccinfo[quality] );
delete writejpg_ccinfo[quality];
writejpg_ccinfo[quality] = NULL;
}
} // end foreach quality
initialised = false;
if ( readjpg_dcinfo ) {
jpeg_destroy_decompress( readjpg_dcinfo );
delete readjpg_dcinfo;
readjpg_dcinfo = 0;
}
}
if ( decodejpg_dcinfo ) {
jpeg_destroy_decompress( decodejpg_dcinfo );
delete decodejpg_dcinfo;
decodejpg_dcinfo = 0;
}
for ( unsigned int quality=0; quality <= 100; quality += 1 ) {
if ( writejpg_ccinfo[quality] ) {
jpeg_destroy_compress( writejpg_ccinfo[quality] );
delete writejpg_ccinfo[quality];
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 */
@ -657,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

@ -417,14 +417,14 @@ Monitor::Monitor(
auto_resume_time = 0;
if ( strcmp( config.event_close_mode, "time" ) == 0 )
if ( strcmp(config.event_close_mode, "time") == 0 )
event_close_mode = CLOSE_TIME;
else if ( strcmp( config.event_close_mode, "alarm" ) == 0 )
else if ( strcmp(config.event_close_mode, "alarm") == 0 )
event_close_mode = CLOSE_ALARM;
else
event_close_mode = CLOSE_IDLE;
Debug( 1, "monitor purpose=%d", purpose );
Debug(1, "monitor purpose=%d", purpose);
mem_size = sizeof(SharedData)
+ sizeof(TriggerData)
@ -444,17 +444,15 @@ Monitor::Monitor(
storage = new Storage(storage_id);
Debug(1, "Storage path: %s", storage->Path());
// Should maybe store this for later use
char monitor_dir[PATH_MAX] = "";
char monitor_dir[PATH_MAX];
snprintf(monitor_dir, sizeof(monitor_dir), "%s/%d", storage->Path(), id);
if ( purpose == CAPTURE ) {
if ( mkdir(monitor_dir, 0755) ) {
if ( errno != EEXIST ) {
Error("Can't mkdir %s: %s", monitor_dir, strerror(errno));
}
if ( mkdir(monitor_dir, 0755) && ( errno != EEXIST ) ) {
Error("Can't mkdir %s: %s", monitor_dir, strerror(errno));
}
if ( ! this->connect() ) {
if ( !this->connect() ) {
Error("unable to connect, but doing capture");
exit(-1);
}
@ -490,20 +488,16 @@ Monitor::Monitor(
video_store_data->size = sizeof(VideoStoreData);
//video_store_data->frameNumber = 0;
} else if ( purpose == ANALYSIS ) {
if ( ! ( this->connect() && mem_ptr ) ) exit(-1);
if ( ! (this->connect() && mem_ptr && shared_data->valid) ) {
Error("Shared data not initialised by capture daemon for monitor %s", name);
exit(-1);
}
shared_data->state = IDLE;
shared_data->last_read_time = 0;
shared_data->alarm_x = -1;
shared_data->alarm_y = -1;
}
if ( ( ! mem_ptr ) || ! shared_data->valid ) {
if ( purpose != QUERY ) {
Error("Shared data not initialised by capture daemon for monitor %s", name);
exit(-1);
}
}
start_time = last_fps_time = time( 0 );
event = 0;
@ -549,9 +543,8 @@ Monitor::Monitor(
FifoStream::fifo_create_if_missing(diag_path_d.c_str());
}
}
} // end if purpose == ANALYSIS
} // Monitor::Monitor
} // end if purpose == ANALYSIS
} // Monitor::Monitor
bool Monitor::connect() {
Debug(3, "Connecting to monitor. Purpose is %d", purpose );

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,50 +124,51 @@ 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, "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,
"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);
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'",

View File

@ -115,12 +115,13 @@ User *zmLoadUser(const char *username, const char *password) {
" `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 ) {
@ -128,29 +129,24 @@ User *zmLoadUser(const char *username, const char *password) {
exit(mysql_errno(&dbconn));
}
if ( mysql_num_rows(result) != 1 ) {
if ( mysql_num_rows(result) == 1 ) {
MYSQL_ROW dbrow = mysql_fetch_row(result);
User *user = new User(dbrow);
mysql_free_result(result);
Warning("Unable to authenticate user %s", username);
return NULL;
}
MYSQL_ROW dbrow = mysql_fetch_row(result);
User *user = new User(dbrow);
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);
if ( !password ) {
// relay type must be none
return user;
}
if ( verifyPassword(username, password, user->getPassword()) ) {
Info("Authenticated user '%s'", user->getUsername());
return user;
}
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) {
std::string key = config.auth_hash_secret;
@ -172,53 +168,50 @@ User *zmLoadTokenUser(std::string jwt_token_str, bool use_remote_addr) {
unsigned int iat = ans.second;
Debug(1, "retrieved user '%s' from token", username.c_str());
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());
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);
if ( !result ) {
Error("Can't use query result: %s", mysql_error(&dbconn));
exit(mysql_errno(&dbconn));
}
int n_users = mysql_num_rows(result);
if ( n_users != 1 ) {
mysql_free_result(result);
Error("Unable to authenticate user '%s'", username.c_str());
return NULL;
}
MYSQL_ROW dbrow = mysql_fetch_row(result);
User *user = new User(dbrow);
unsigned int stored_iat = strtoul(dbrow[10], NULL, 0);
if ( stored_iat > iat ) { // admin revoked tokens
mysql_free_result(result);
Error("Token was revoked for '%s'", username.c_str());
return NULL;
}
Debug(1, "Authenticated user '%s' via token with last revoke time: %u",
username.c_str(), stored_iat);
mysql_free_result(result);
return user;
} else {
if ( username == "" ) {
return NULL;
}
} // end User *zmLoadTokenUser(std::string jwt_token_str, bool use_remote_addr)
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());
if ( mysql_query(&dbconn, sql) ) {
Error("Can't run query: %s", mysql_error(&dbconn));
return NULL;
}
MYSQL_RES *result = mysql_store_result(&dbconn);
if ( !result ) {
Error("Can't use query result: %s", mysql_error(&dbconn));
return NULL;
}
int n_users = mysql_num_rows(result);
if ( n_users != 1 ) {
mysql_free_result(result);
Error("Unable to authenticate user '%s'", username.c_str());
return NULL;
}
MYSQL_ROW dbrow = mysql_fetch_row(result);
User *user = new User(dbrow);
unsigned int stored_iat = strtoul(dbrow[10], NULL, 0);
if ( stored_iat > iat ) { // admin revoked tokens
mysql_free_result(result);
Error("Token was revoked for '%s'", username.c_str());
return NULL;
}
Debug(1, "Authenticated user '%s' via token with last revoke time: %u",
username.c_str(), stored_iat);
mysql_free_result(result);
return user;
} // 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) {
#if HAVE_DECL_MD5 || HAVE_DECL_GNUTLS_FINGERPRINT
@ -255,36 +248,33 @@ User *zmLoadAuthUser(const char *auth, bool use_remote_addr) {
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);
if ( n_users < 1 ) {
mysql_free_result(result);
Warning("Unable to authenticate user");
return 0;
return NULL;
}
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];
const char * hex = "0123456789abcdef";
while ( MYSQL_ROW dbrow = mysql_fetch_row(result) ) {
const char *user = dbrow[1];
const char *pass = dbrow[2];
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;
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);
}
for ( unsigned int i = 0; i < hours; i++, now -= 3600 ) {
struct tm *now_tm = localtime(&now);
@ -332,7 +322,7 @@ User *zmLoadAuthUser(const char *auth, bool use_remote_addr) {
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 0;
return NULL;
} // end User *zmLoadAuthUser( const char *auth, bool use_remote_addr )
// Function to check Username length

View File

@ -53,7 +53,7 @@ void Zone::Setup(
id = p_id;
label = new char[strlen(p_label)+1];
strcpy( label, p_label );
strcpy(label, p_label);
type = p_type;
polygon = p_polygon;
alarm_rgb = p_alarm_rgb;
@ -89,10 +89,10 @@ void Zone::Setup(
overload_count = 0;
extend_alarm_count = 0;
pg_image = new Image( monitor->Width(), monitor->Height(), 1, ZM_SUBPIX_ORDER_NONE );
pg_image = new Image(monitor->Width(), monitor->Height(), 1, ZM_SUBPIX_ORDER_NONE);
pg_image->Clear();
pg_image->Fill( 0xff, polygon );
pg_image->Outline( 0xff, polygon );
pg_image->Fill(0xff, polygon);
pg_image->Outline(0xff, polygon);
ranges = new Range[monitor->Height()];
for ( unsigned int y = 0; y < monitor->Height(); y++ ) {
@ -113,8 +113,10 @@ void Zone::Setup(
}
if ( config.record_diag_images ) {
snprintf(diag_path, sizeof(diag_path), config.record_diag_images_fifo ? "%s/diagpipe-%d-poly.jpg" : "%s/diag-%d-poly.jpg", monitor->getStorage()->Path(), id);
if (config.record_diag_images_fifo)
snprintf(diag_path, sizeof(diag_path),
config.record_diag_images_fifo ? "%s/diagpipe-%d-poly.jpg" : "%s/diag-%d-poly.jpg",
monitor->getStorage()->Path(), id);
if ( config.record_diag_images_fifo )
FifoStream::fifo_create_if_missing(diag_path);
pg_image->WriteJpeg(diag_path, config.record_diag_images_fifo);
} else {

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,19 +195,11 @@ 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() ) {
user = zmLoadUser(username.c_str(), password.c_str());
}
if ( *auth ) {
user = zmLoadAuthUser(auth, config.auth_hash_ips);
} else if ( username.length() && password.length() ) {
user = zmLoadUser(username.c_str(), password.c_str());
}
}
if ( !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;
}