From 80b08a207572307ce7687541a76c70af879ec10d Mon Sep 17 00:00:00 2001 From: Peter Keresztes Schmidt Date: Fri, 25 Jun 2021 09:46:40 +0200 Subject: [PATCH 1/2] Convert path buffers depending on PATH_MAX to std::string --- src/zm_config.cpp | 20 +++--- src/zm_config.h | 12 ++-- src/zm_event.h | 24 +++---- src/zm_eventstream.cpp | 137 +++++++++++++++++++-------------------- src/zm_eventstream.h | 6 +- src/zm_fifo.cpp | 33 ++++------ src/zm_fifo.h | 13 +--- src/zm_fifo_debug.cpp | 7 +- src/zm_fifo_stream.cpp | 64 +++++++++--------- src/zm_fifo_stream.h | 11 +--- src/zm_file_camera.cpp | 12 ++-- src/zm_file_camera.h | 38 +++++------ src/zm_image.cpp | 30 ++++----- src/zm_image.h | 17 +++-- src/zm_jpeg.cpp | 24 +++---- src/zm_local_camera.cpp | 60 +++++++++-------- src/zm_local_camera.h | 2 +- src/zm_monitor.cpp | 27 ++++---- src/zm_monitorstream.cpp | 36 ++++------ src/zm_monitorstream.h | 4 +- src/zm_zone.cpp | 23 ++++--- 21 files changed, 283 insertions(+), 317 deletions(-) diff --git a/src/zm_config.cpp b/src/zm_config.cpp index 97e2f8c2a..340926d92 100644 --- a/src/zm_config.cpp +++ b/src/zm_config.cpp @@ -39,16 +39,15 @@ void zmLoadStaticConfig() { // update the Config hash with those values DIR *configSubFolder = opendir(ZM_CONFIG_SUBDIR); if (configSubFolder) { // subfolder exists and is readable - char glob_pattern[PATH_MAX] = ""; - snprintf(glob_pattern, sizeof(glob_pattern), "%s/*.conf", ZM_CONFIG_SUBDIR); + std::string glob_pattern = stringtf("%s/*.conf", ZM_CONFIG_SUBDIR); glob_t pglob; - int glob_status = glob(glob_pattern, 0, nullptr, &pglob); + int glob_status = glob(glob_pattern.c_str(), 0, nullptr, &pglob); if (glob_status != 0) { if (glob_status < 0) { - Error("Can't glob '%s': %s", glob_pattern, strerror(errno)); + Error("Can't glob '%s': %s", glob_pattern.c_str(), strerror(errno)); } else { - Debug(1, "Can't glob '%s': %d", glob_pattern, glob_status); + Debug(1, "Can't glob '%s': %d", glob_pattern.c_str(), glob_status); } } else { for (unsigned int i = 0; i < pglob.gl_pathc; i++) { @@ -100,13 +99,10 @@ void zmLoadDBConfig() { } } - snprintf(staticConfig.capture_file_format, sizeof(staticConfig.capture_file_format), "%%s/%%0%dd-capture.jpg", - config.event_image_digits); - snprintf(staticConfig.analyse_file_format, sizeof(staticConfig.analyse_file_format), "%%s/%%0%dd-analyse.jpg", - config.event_image_digits); - snprintf(staticConfig.general_file_format, sizeof(staticConfig.general_file_format), "%%s/%%0%dd-%%s", - config.event_image_digits); - snprintf(staticConfig.video_file_format, sizeof(staticConfig.video_file_format), "%%s/%%s"); + staticConfig.capture_file_format = stringtf("%%s/%%0%dd-capture.jpg", config.event_image_digits); + staticConfig.analyse_file_format = stringtf("%%s/%%0%dd-analyse.jpg", config.event_image_digits); + staticConfig.general_file_format = stringtf("%%s/%%0%dd-%%s", config.event_image_digits); + staticConfig.video_file_format = "%s/%s"; } void process_configfile(char const *configFile) { diff --git a/src/zm_config.h b/src/zm_config.h index a6d0420b4..53e181301 100644 --- a/src/zm_config.h +++ b/src/zm_config.h @@ -25,10 +25,6 @@ #include "zm_config_defines.h" #include -#if !defined(PATH_MAX) -#define PATH_MAX 1024 -#endif - #define ZM_MAX_IMAGE_WIDTH 2048 // The largest image we imagine ever handling #define ZM_MAX_IMAGE_HEIGHT 1536 // The largest image we imagine ever handling #define ZM_MAX_IMAGE_COLOURS 4 // The largest image we imagine ever handling @@ -74,10 +70,10 @@ struct StaticConfig { std::string PATH_LOGS; std::string PATH_SWAP; std::string PATH_ARP; - char capture_file_format[PATH_MAX]; - char analyse_file_format[PATH_MAX]; - char general_file_format[PATH_MAX]; - char video_file_format[PATH_MAX]; + std::string capture_file_format; + std::string analyse_file_format; + std::string general_file_format; + std::string video_file_format; }; extern StaticConfig staticConfig; diff --git a/src/zm_event.h b/src/zm_event.h index 38dc0e290..8b8e49322 100644 --- a/src/zm_event.h +++ b/src/zm_event.h @@ -24,6 +24,7 @@ #include "zm_define.h" #include "zm_storage.h" #include "zm_time.h" +#include "zm_utils.h" #include "zm_zone.h" #include @@ -128,18 +129,17 @@ class Event { bool SetPath(Storage *storage); public: - static const char *getSubPath(tm time) { - static char subpath[PATH_MAX] = ""; - snprintf(subpath, sizeof(subpath), "%02d/%02d/%02d/%02d/%02d/%02d", - time.tm_year-100, time.tm_mon+1, time.tm_mday, - time.tm_hour, time.tm_min, time.tm_sec); - return subpath; - } - static const char *getSubPath(time_t *time) { - tm time_tm = {}; - localtime_r(time, &time_tm); - return Event::getSubPath(time_tm); - } + static std::string getSubPath(tm time) { + std::string subpath = stringtf("%02d/%02d/%02d/%02d/%02d/%02d", + time.tm_year - 100, time.tm_mon + 1, time.tm_mday, + time.tm_hour, time.tm_min, time.tm_sec); + return subpath; + } + static std::string getSubPath(time_t *time) { + tm time_tm = {}; + localtime_r(time, &time_tm); + return Event::getSubPath(time_tm); + } const char* getEventFile() const { return video_file.c_str(); diff --git a/src/zm_eventstream.cpp b/src/zm_eventstream.cpp index 6c18940d2..0b501149c 100644 --- a/src/zm_eventstream.cpp +++ b/src/zm_eventstream.cpp @@ -145,7 +145,7 @@ bool EventStream::loadEventData(uint64_t event_id) { event_data->duration = std::chrono::duration_cast(event_data->end_time - event_data->start_time); event_data->frames_duration = std::chrono::duration_cast(dbrow[5] ? FPSeconds(atof(dbrow[5])) : FPSeconds(0.0)); - strncpy(event_data->video_file, dbrow[6], sizeof(event_data->video_file) - 1); + event_data->video_file = std::string(dbrow[6]); std::string scheme_str = std::string(dbrow[7]); if ( scheme_str == "Deep" ) { event_data->scheme = Storage::DEEP; @@ -180,44 +180,41 @@ bool EventStream::loadEventData(uint64_t event_id) { time_t start_time_t = std::chrono::system_clock::to_time_t(event_data->start_time); localtime_r(&start_time_t, &event_time); - if ( storage_path[0] == '/' ) - snprintf(event_data->path, sizeof(event_data->path), - "%s/%u/%02d/%02d/%02d/%02d/%02d/%02d", - storage_path, event_data->monitor_id, - event_time.tm_year-100, event_time.tm_mon+1, event_time.tm_mday, - event_time.tm_hour, event_time.tm_min, event_time.tm_sec); - else - snprintf(event_data->path, sizeof(event_data->path), - "%s/%s/%u/%02d/%02d/%02d/%02d/%02d/%02d", - staticConfig.PATH_WEB.c_str(), storage_path, event_data->monitor_id, - event_time.tm_year-100, event_time.tm_mon+1, event_time.tm_mday, - event_time.tm_hour, event_time.tm_min, event_time.tm_sec); - } else if ( event_data->scheme == Storage::MEDIUM ) { + if (storage_path[0] == '/') { + event_data->path = stringtf("%s/%u/%02d/%02d/%02d/%02d/%02d/%02d", + storage_path, event_data->monitor_id, + event_time.tm_year - 100, event_time.tm_mon + 1, event_time.tm_mday, + event_time.tm_hour, event_time.tm_min, event_time.tm_sec); + } else { + event_data->path = stringtf("%s/%s/%u/%02d/%02d/%02d/%02d/%02d/%02d", + staticConfig.PATH_WEB.c_str(), storage_path, event_data->monitor_id, + event_time.tm_year - 100, event_time.tm_mon + 1, event_time.tm_mday, + event_time.tm_hour, event_time.tm_min, event_time.tm_sec); + } + } else if (event_data->scheme == Storage::MEDIUM) { tm event_time = {}; time_t start_time_t = std::chrono::system_clock::to_time_t(event_data->start_time); localtime_r(&start_time_t, &event_time); - if ( storage_path[0] == '/' ) - snprintf(event_data->path, sizeof(event_data->path), - "%s/%u/%04d-%02d-%02d/%" PRIu64, - storage_path, event_data->monitor_id, - event_time.tm_year+1900, event_time.tm_mon+1, event_time.tm_mday, - event_data->event_id); - else - snprintf(event_data->path, sizeof(event_data->path), - "%s/%s/%u/%04d-%02d-%02d/%" PRIu64, - staticConfig.PATH_WEB.c_str(), storage_path, event_data->monitor_id, - event_time.tm_year+1900, event_time.tm_mon+1, event_time.tm_mday, - event_data->event_id); - + if (storage_path[0] == '/') { + event_data->path = stringtf("%s/%u/%04d-%02d-%02d/%" PRIu64, + storage_path, event_data->monitor_id, + event_time.tm_year + 1900, event_time.tm_mon + 1, event_time.tm_mday, + event_data->event_id); + } else { + event_data->path = stringtf("%s/%s/%u/%04d-%02d-%02d/%" PRIu64, + staticConfig.PATH_WEB.c_str(), storage_path, event_data->monitor_id, + event_time.tm_year + 1900, event_time.tm_mon + 1, event_time.tm_mday, + event_data->event_id); + } } else { - if ( storage_path[0] == '/' ) - snprintf(event_data->path, sizeof(event_data->path), "%s/%u/%" PRIu64, - storage_path, event_data->monitor_id, event_data->event_id); - else - snprintf(event_data->path, sizeof(event_data->path), "%s/%s/%u/%" PRIu64, - staticConfig.PATH_WEB.c_str(), storage_path, event_data->monitor_id, - event_data->event_id); + if (storage_path[0] == '/') { + event_data->path = stringtf("%s/%u/%" PRIu64, storage_path, event_data->monitor_id, event_data->event_id); + } else { + event_data->path = stringtf("%s/%s/%u/%" PRIu64, + staticConfig.PATH_WEB.c_str(), storage_path, event_data->monitor_id, + event_data->event_id); + } } double fps = 1.0; @@ -289,17 +286,17 @@ bool EventStream::loadEventData(uint64_t event_id) { } mysql_free_result(result); - 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"); + if (!event_data->video_file.empty() || (monitor->GetOptVideoWriter() > 0)) { + if (event_data->video_file.empty()) { + event_data->video_file = stringtf("%" PRIu64 "-%s", event_data->event_id, "video.mp4"); } - std::string filepath = std::string(event_data->path) + "/" + std::string(event_data->video_file); + + std::string filepath = event_data->path + "/" + event_data->video_file; Debug(1, "Loading video file from %s", filepath.c_str()); - if ( ffmpeg_input ) - delete ffmpeg_input; + delete ffmpeg_input; ffmpeg_input = new FFmpeg_Input(); - if ( 0 > ffmpeg_input->Open(filepath.c_str()) ) { + if (ffmpeg_input->Open(filepath.c_str()) < 0) { Warning("Unable to open ffmpeg_input %s", filepath.c_str()); delete ffmpeg_input; ffmpeg_input = nullptr; @@ -690,32 +687,30 @@ bool EventStream::checkEventLoaded() { } // void EventStream::checkEventLoaded() Image * EventStream::getImage( ) { - static char filepath[PATH_MAX]; - - snprintf(filepath, sizeof(filepath), staticConfig.capture_file_format, event_data->path, curr_frame_id); - Debug(2, "EventStream::getImage path(%s) from %s frame(%ld) ", filepath, event_data->path, curr_frame_id); - Image *image = new Image(filepath); + std::string path = stringtf(staticConfig.capture_file_format, event_data->path.c_str(), curr_frame_id); + Debug(2, "EventStream::getImage path(%s) from %s frame(%ld) ", path.c_str(), event_data->path.c_str(), curr_frame_id); + Image *image = new Image(path.c_str()); return image; } bool EventStream::sendFrame(Microseconds delta_us) { Debug(2, "Sending frame %ld", curr_frame_id); - static char filepath[PATH_MAX]; - static struct stat filestat; + std::string filepath; + struct stat filestat = {}; // This needs to be abstracted. If we are saving jpgs, then load the capture file. // If we are only saving analysis frames, then send that. - if ( event_data->SaveJPEGs & 1 ) { - snprintf(filepath, sizeof(filepath), staticConfig.capture_file_format, event_data->path, curr_frame_id); - } else if ( event_data->SaveJPEGs & 2 ) { - snprintf(filepath, sizeof(filepath), staticConfig.analyse_file_format, event_data->path, curr_frame_id); - if ( stat(filepath, &filestat) < 0 ) { - Debug(1, "analyze file %s not found will try to stream from other", filepath); - snprintf(filepath, sizeof(filepath), staticConfig.capture_file_format, event_data->path, curr_frame_id); - if ( stat(filepath, &filestat) < 0 ) { - Debug(1, "capture file %s not found either", filepath); - filepath[0] = 0; + if (event_data->SaveJPEGs & 1) { + filepath = stringtf(staticConfig.capture_file_format, event_data->path.c_str(), curr_frame_id); + } else if (event_data->SaveJPEGs & 2) { + filepath = stringtf(staticConfig.analyse_file_format, event_data->path.c_str(), curr_frame_id); + if (stat(filepath.c_str(), &filestat) < 0) { + Debug(1, "analyze file %s not found will try to stream from other", filepath.c_str()); + filepath = stringtf(staticConfig.capture_file_format, event_data->path.c_str(), curr_frame_id); + if (stat(filepath.c_str(), &filestat) < 0) { + Debug(1, "capture file %s not found either", filepath.c_str()); + filepath = ""; } } } else if ( !ffmpeg_input ) { @@ -724,7 +719,7 @@ bool EventStream::sendFrame(Microseconds delta_us) { } if ( type == STREAM_MPEG ) { - Image image(filepath); + Image image(filepath.c_str()); Image *send_image = prepareImage(&image); @@ -739,20 +734,20 @@ bool EventStream::sendFrame(Microseconds delta_us) { config.mpeg_timed_frames, delta_us.count() * 1000); } else { - bool send_raw = (type == STREAM_JPEG) && ((scale>=ZM_SCALE_BASE)&&(zoom==ZM_SCALE_BASE)) && filepath[0]; + bool send_raw = (type == STREAM_JPEG) && ((scale >= ZM_SCALE_BASE) && (zoom == ZM_SCALE_BASE)) && !filepath.empty(); fprintf(stdout, "--" BOUNDARY "\r\n"); - if ( send_raw ) { - if ( !send_file(filepath) ) { - Error("Can't send %s: %s", filepath, strerror(errno)); + if (send_raw) { + if (!send_file(filepath)) { + Error("Can't send %s: %s", filepath.c_str(), strerror(errno)); return false; } } else { Image *image = nullptr; - if ( filepath[0] ) { - image = new Image(filepath); + if (!filepath.empty()) { + image = new Image(filepath.c_str()); } else if ( ffmpeg_input ) { // Get the frame from the mp4 input FrameData *frame_data = &event_data->frames[curr_frame_id-1]; @@ -1088,24 +1083,24 @@ void EventStream::runStream() { closeComms(); } // end void EventStream::runStream() -bool EventStream::send_file(const char *filepath) { +bool EventStream::send_file(const std::string &filepath) { static unsigned char temp_img_buffer[ZM_MAX_IMAGE_SIZE]; int img_buffer_size = 0; uint8_t *img_buffer = temp_img_buffer; FILE *fdj = nullptr; - fdj = fopen(filepath, "rb"); + fdj = fopen(filepath.c_str(), "rb"); if ( !fdj ) { - Error("Can't open %s: %s", filepath, strerror(errno)); - std::string error_message = stringtf("Can't open %s: %s", filepath, strerror(errno)); + Error("Can't open %s: %s", filepath.c_str(), strerror(errno)); + std::string error_message = stringtf("Can't open %s: %s", filepath.c_str(), strerror(errno)); return sendTextFrame(error_message.c_str()); } #if HAVE_SENDFILE static struct stat filestat; if ( fstat(fileno(fdj), &filestat) < 0 ) { fclose(fdj); /* Close the file handle */ - Error("Failed getting information about file %s: %s", filepath, strerror(errno)); + Error("Failed getting information about file %s: %s", filepath.c_str(), strerror(errno)); return false; } if ( !filestat.st_size ) { @@ -1134,7 +1129,7 @@ bool EventStream::send_file(const char *filepath) { } return send_buffer(img_buffer, img_buffer_size); -} // end bool EventStream::send_file(const char * filepath) +} bool EventStream::send_buffer(uint8_t* buffer, int size) { if ( 0 > fprintf(stdout, "Content-Length: %d\r\n\r\n", size) ) { diff --git a/src/zm_eventstream.h b/src/zm_eventstream.h index 34f918fe4..387748b08 100644 --- a/src/zm_eventstream.h +++ b/src/zm_eventstream.h @@ -56,10 +56,10 @@ class EventStream : public StreamBase { SystemTimePoint end_time; Microseconds duration; Microseconds frames_duration; - char path[PATH_MAX]; + std::string path; int n_frames; // # of frame rows returned from database FrameData *frames; - char video_file[PATH_MAX]; + std::string video_file; Storage::Schemes scheme; int SaveJPEGs; Monitor::Orientation Orientation; @@ -124,7 +124,7 @@ class EventStream : public StreamBase { void runStream() override; Image *getImage(); private: - bool send_file(const char *filepath); + bool send_file(const std::string &filepath); bool send_buffer(uint8_t * buffer, int size); Storage *storage; FFmpeg_Input *ffmpeg_input; diff --git a/src/zm_fifo.cpp b/src/zm_fifo.cpp index 0204d5117..319c35c31 100644 --- a/src/zm_fifo.cpp +++ b/src/zm_fifo.cpp @@ -29,32 +29,26 @@ #define RAW_BUFFER 512 #define PIPE_SIZE 1024*1024 -void Fifo::file_create_if_missing( - const char * path, - bool is_fifo, - bool delete_fake_fifo - ) { - static struct stat st; - if ( stat(path, &st) == 0 ) { - if ( (!is_fifo) || S_ISFIFO(st.st_mode) || !delete_fake_fifo ) +void Fifo::file_create_if_missing(const std::string &path, bool is_fifo, bool delete_fake_fifo) { + struct stat st = {}; + + if (stat(path.c_str(), &st) == 0) { + if ((!is_fifo) || S_ISFIFO(st.st_mode) || !delete_fake_fifo) return; - Debug(5, "Supposed to be a fifo pipe but isn't, unlinking: %s", path); - unlink(path); + Debug(5, "Supposed to be a fifo pipe but isn't, unlinking: %s", path.c_str()); + unlink(path.c_str()); } if (!is_fifo) { - Debug(5, "Creating non fifo file as requested: %s", path); - int fd = ::open(path, O_CREAT|O_WRONLY, S_IRUSR|S_IWUSR); + Debug(5, "Creating non fifo file as requested: %s", path.c_str()); + int fd = ::open(path.c_str(), O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR); ::close(fd); return; } - Debug(5, "Making fifo file of: %s", path); - mkfifo(path, S_IRUSR|S_IWUSR); + Debug(5, "Making fifo file of: %s", path.c_str()); + mkfifo(path.c_str(), S_IRUSR | S_IWUSR); } -void Fifo::fifo_create_if_missing( - const char * path, - bool delete_fake_fifo - ) { +void Fifo::fifo_create_if_missing(const std::string &path, bool delete_fake_fifo) { file_create_if_missing(path, true, delete_fake_fifo); } @@ -62,7 +56,8 @@ Fifo::~Fifo() { close(); } bool Fifo::open() { - fifo_create_if_missing(path.c_str()); + fifo_create_if_missing(path); + if (!on_blocking_abort) { if ( (outfile = fopen(path.c_str(), "wb")) == nullptr ) { Error("Can't open %s for writing: %s", path.c_str(), strerror(errno)); diff --git a/src/zm_fifo.h b/src/zm_fifo.h index bd7f23490..5a660c6bb 100644 --- a/src/zm_fifo.h +++ b/src/zm_fifo.h @@ -32,11 +32,8 @@ class Fifo { int raw_fd; public: - static void file_create_if_missing( - const char * path, - bool is_fifo, - bool delete_fake_fifo = true - ); + static void file_create_if_missing(const std::string &path, bool is_fifo, bool delete_fake_fifo = true); + static void fifo_create_if_missing(const std::string &path, bool delete_fake_fifo = true); Fifo() : on_blocking_abort(true), @@ -51,12 +48,6 @@ class Fifo { {} ~Fifo(); - static void fifo_create_if_missing( - const char * path, - bool delete_fake_fifo = true); - - - static bool writePacket(std::string filename, const ZMPacket &packet); static bool write(std::string filename, uint8_t *data, size_t size); diff --git a/src/zm_fifo_debug.cpp b/src/zm_fifo_debug.cpp index bb82f5ec8..1b1950e3c 100644 --- a/src/zm_fifo_debug.cpp +++ b/src/zm_fifo_debug.cpp @@ -28,7 +28,7 @@ #define RAW_BUFFER 512 static bool zm_fifodbg_inited = false; FILE *zm_fifodbg_log_fd = nullptr; -char zm_fifodbg_log[PATH_MAX] = ""; +std::string zm_fifodbg_log; static bool zmFifoDbgOpen() { if ( zm_fifodbg_log_fd ) @@ -36,7 +36,7 @@ static bool zmFifoDbgOpen() { zm_fifodbg_log_fd = nullptr; signal(SIGPIPE, SIG_IGN); Fifo::fifo_create_if_missing(zm_fifodbg_log); - int fd = open(zm_fifodbg_log, O_WRONLY|O_NONBLOCK|O_TRUNC); + int fd = open(zm_fifodbg_log.c_str(), O_WRONLY | O_NONBLOCK | O_TRUNC); if ( fd < 0 ) return false; int res = flock(fd, LOCK_EX | LOCK_NB); @@ -54,8 +54,7 @@ static bool zmFifoDbgOpen() { int zmFifoDbgInit(Monitor *monitor) { zm_fifodbg_inited = true; - snprintf(zm_fifodbg_log, sizeof(zm_fifodbg_log), "%s/dbgpipe-%u.log", - staticConfig.PATH_SOCKS.c_str(), monitor->Id()); + zm_fifodbg_log = stringtf("%s/dbgpipe-%u.log", staticConfig.PATH_SOCKS.c_str(), monitor->Id()); zmFifoDbgOpen(); return 1; } diff --git a/src/zm_fifo_stream.cpp b/src/zm_fifo_stream.cpp index fcb0e7186..51d88b663 100644 --- a/src/zm_fifo_stream.cpp +++ b/src/zm_fifo_stream.cpp @@ -29,9 +29,9 @@ #define RAW_BUFFER 512 bool FifoStream::sendRAWFrames() { static unsigned char buffer[RAW_BUFFER]; - int fd = open(stream_path, O_RDONLY); + int fd = open(stream_path.c_str(), O_RDONLY); if ( fd < 0 ) { - Error("Can't open %s: %s", stream_path, strerror(errno)); + Error("Can't open %s: %s", stream_path.c_str(), strerror(errno)); return false; } while ( (bytes_read = read(fd, buffer, RAW_BUFFER)) ) { @@ -56,9 +56,9 @@ bool FifoStream::sendRAWFrames() { bool FifoStream::sendMJEGFrames() { static unsigned char buffer[ZM_MAX_IMAGE_SIZE]; - int fd = open(stream_path, O_RDONLY); + int fd = open(stream_path.c_str(), O_RDONLY); if ( fd < 0 ) { - Error("Can't open %s: %s", stream_path, strerror(errno)); + Error("Can't open %s: %s", stream_path.c_str(), strerror(errno)); return false; } total_read = 0; @@ -97,28 +97,26 @@ bool FifoStream::sendMJEGFrames() { return true; } -void FifoStream::setStreamStart(const char * path) { - stream_path = strdup(path); +void FifoStream::setStreamStart(const std::string &path) { + stream_path = path; } -void FifoStream::setStreamStart(int monitor_id, const char * format) { - char diag_path[PATH_MAX]; +void FifoStream::setStreamStart(int monitor_id, const char *format) { + std::string diag_path; std::shared_ptr monitor = Monitor::Load(monitor_id, false, Monitor::QUERY); - if ( !strcmp(format, "reference") ) { - snprintf(diag_path, sizeof(diag_path), "%s/diagpipe-r-%u.jpg", - staticConfig.PATH_SOCKS.c_str(), monitor->Id()); + if (!strcmp(format, "reference")) { + diag_path = stringtf("%s/diagpipe-r-%u.jpg", staticConfig.PATH_SOCKS.c_str(), monitor->Id()); stream_type = MJPEG; - } else if ( !strcmp(format, "delta") ) { - snprintf(diag_path, sizeof(diag_path), "%s/diagpipe-d-%u.jpg", - staticConfig.PATH_SOCKS.c_str(), monitor->Id()); + } else if (!strcmp(format, "delta")) { + diag_path = stringtf("%s/diagpipe-d-%u.jpg", staticConfig.PATH_SOCKS.c_str(), monitor->Id()); stream_type = MJPEG; } else { - if ( strcmp(format, "raw") ) { + if (strcmp(format, "raw")) { Warning("Unknown or unspecified format. Defaulting to raw"); } - snprintf(diag_path, sizeof(diag_path), "%s/dbgpipe-%u.log", - staticConfig.PATH_SOCKS.c_str(), monitor->Id()); + + diag_path = stringtf("%s/dbgpipe-%u.log", staticConfig.PATH_SOCKS.c_str(), monitor->Id()); stream_type = RAW; } @@ -126,46 +124,48 @@ void FifoStream::setStreamStart(int monitor_id, const char * format) { } void FifoStream::runStream() { - if ( stream_type == MJPEG ) { + if (stream_type == MJPEG) { fprintf(stdout, "Content-Type: multipart/x-mixed-replace;boundary=" BOUNDARY "\r\n\r\n"); } else { fprintf(stdout, "Content-Type: text/html\r\n\r\n"); } /* only 1 person can read from a fifo at a time, so use a lock */ - char lock_file[PATH_MAX]; - snprintf(lock_file, sizeof(lock_file), "%s.rlock", stream_path); + std::string lock_file = stringtf("%s.rlock", stream_path.c_str()); Fifo::file_create_if_missing(lock_file, false); - Debug(1, "Locking %s", lock_file); + Debug(1, "Locking %s", lock_file.c_str()); - int fd_lock = open(lock_file, O_RDONLY); - if ( fd_lock < 0 ) { - Error("Can't open %s: %s", lock_file, strerror(errno)); + int fd_lock = open(lock_file.c_str(), O_RDONLY); + if (fd_lock < 0) { + Error("Can't open %s: %s", lock_file.c_str(), strerror(errno)); return; } + int res = flock(fd_lock, LOCK_EX | LOCK_NB); - while ( (res < 0 and errno == EAGAIN) and (! zm_terminate) ) { - Warning("Flocking problem on %s: - %s", lock_file, strerror(errno)); + while ((res < 0 and errno == EAGAIN) and (!zm_terminate)) { + Warning("Flocking problem on %s: - %s", lock_file.c_str(), strerror(errno)); sleep(1); res = flock(fd_lock, LOCK_EX | LOCK_NB); } - if ( res < 0 ) { - Error("Flocking problem on %d != %d %s: - %s", EAGAIN, res, lock_file, strerror(errno)); + + if (res < 0) { + Error("Flocking problem on %d != %d %s: - %s", EAGAIN, res, lock_file.c_str(), strerror(errno)); close(fd_lock); return; } - while ( !zm_terminate ) { + while (!zm_terminate) { now = std::chrono::system_clock::now(); checkCommandQueue(); - if ( stream_type == MJPEG ) { - if ( !sendMJEGFrames() ) + if (stream_type == MJPEG) { + if (!sendMJEGFrames()) zm_terminate = true; } else { - if ( !sendRAWFrames() ) + if (!sendRAWFrames()) zm_terminate = true; } } + close(fd_lock); } diff --git a/src/zm_fifo_stream.h b/src/zm_fifo_stream.h index 446108d2c..911980d48 100644 --- a/src/zm_fifo_stream.h +++ b/src/zm_fifo_stream.h @@ -25,15 +25,10 @@ class Monitor; class FifoStream : public StreamBase { private: - char * stream_path; + std::string stream_path; int total_read; int bytes_read; unsigned int frame_count; - static void file_create_if_missing( - const char * path, - bool is_fifo, - bool delete_fake_fifo = true - ); protected: typedef enum { UNKNOWN, MJPEG, RAW } StreamType; @@ -44,13 +39,13 @@ class FifoStream : public StreamBase { public: FifoStream() : - stream_path(nullptr), total_read(0), bytes_read(0), frame_count(0), stream_type(UNKNOWN) {} - void setStreamStart(const char * path); + + void setStreamStart(const std::string &path); void setStreamStart(int monitor_id, const char * format); void runStream() override; }; diff --git a/src/zm_file_camera.cpp b/src/zm_file_camera.cpp index 9740fc52e..fd07515ad 100644 --- a/src/zm_file_camera.cpp +++ b/src/zm_file_camera.cpp @@ -48,20 +48,20 @@ FileCamera::FileCamera( p_capture, p_record_audio) { - strncpy( path, p_path, sizeof(path)-1 ); - if ( capture ) { + path = std::string(p_path); + if (capture) { Initialise(); } } FileCamera::~FileCamera() { - if ( capture ) { + if (capture) { Terminate(); } } void FileCamera::Initialise() { - if ( !path[0] ) { + if (path.empty()) { Fatal("No path specified for file image"); } } @@ -71,8 +71,8 @@ void FileCamera::Terminate() { int FileCamera::PreCapture() { struct stat statbuf = {}; - if (stat(path, &statbuf) < 0) { - Error("Can't stat %s: %s", path, strerror(errno)); + if (stat(path.c_str(), &statbuf) < 0) { + Error("Can't stat %s: %s", path.c_str(), strerror(errno)); return -1; } bytes += statbuf.st_size; diff --git a/src/zm_file_camera.h b/src/zm_file_camera.h index fa923ac67..cc5d38acd 100644 --- a/src/zm_file_camera.h +++ b/src/zm_file_camera.h @@ -27,26 +27,19 @@ // accessed using a single file which contains the latest jpeg data // class FileCamera : public Camera { -protected: - char path[PATH_MAX]; - -public: - FileCamera( - const Monitor *monitor, - const char *p_path, - int p_width, - int p_height, - int p_colours, - int p_brightness, - int p_contrast, - int p_hue, - int p_colour, - bool p_capture, - bool p_record_audio - ); - ~FileCamera(); - - const char *Path() const { return path; } + public: + FileCamera(const Monitor *monitor, + const char *p_path, + int p_width, + int p_height, + int p_colours, + int p_brightness, + int p_contrast, + int p_hue, + int p_colour, + bool p_capture, + bool p_record_audio); + ~FileCamera() override; void Initialise(); void Terminate(); @@ -54,6 +47,11 @@ public: int Capture(std::shared_ptr &p) override; int PostCapture() override; int Close() override { return 0; }; + + const std::string &Path() const { return path; } + + private: + std::string path; }; #endif // ZM_FILE_CAMERA_H diff --git a/src/zm_image.cpp b/src/zm_image.cpp index e0a7aa4e8..a837138bc 100644 --- a/src/zm_image.cpp +++ b/src/zm_image.cpp @@ -933,7 +933,7 @@ bool Image::WriteRaw(const char *filename) const { return true; } -bool Image::ReadJpeg(const char *filename, unsigned int p_colours, unsigned int p_subpixelorder) { +bool Image::ReadJpeg(const std::string &filename, unsigned int p_colours, unsigned int p_subpixelorder) { unsigned int new_width, new_height, new_colours, new_subpixelorder; struct jpeg_decompress_struct *cinfo = readjpg_dcinfo; @@ -946,8 +946,8 @@ bool Image::ReadJpeg(const char *filename, unsigned int p_colours, unsigned int } FILE *infile; - if ( (infile = fopen(filename, "rb")) == nullptr ) { - Error("Can't open %s: %s", filename, strerror(errno)); + if ( (infile = fopen(filename.c_str(), "rb")) == nullptr ) { + Error("Can't open %s: %s", filename.c_str(), strerror(errno)); return false; } @@ -1060,24 +1060,24 @@ cinfo->out_color_space = JCS_RGB; // Multiple calling formats to permit inclusion (or not) of non blocking, quality_override and timestamp (exif), with suitable defaults. // Note quality=zero means default -bool Image::WriteJpeg(const char *filename, int quality_override) const { +bool Image::WriteJpeg(const std::string &filename, int quality_override) const { return Image::WriteJpeg(filename, quality_override, {}, false); } -bool Image::WriteJpeg(const char *filename) const { +bool Image::WriteJpeg(const std::string &filename) const { return Image::WriteJpeg(filename, 0, {}, false); } -bool Image::WriteJpeg(const char *filename, bool on_blocking_abort) const { +bool Image::WriteJpeg(const std::string &filename, bool on_blocking_abort) const { return Image::WriteJpeg(filename, 0, {}, on_blocking_abort); } -bool Image::WriteJpeg(const char *filename, SystemTimePoint timestamp) const { +bool Image::WriteJpeg(const std::string &filename, SystemTimePoint timestamp) const { return Image::WriteJpeg(filename, 0, timestamp, false); } -bool Image::WriteJpeg(const char *filename, int quality_override, SystemTimePoint timestamp) const { +bool Image::WriteJpeg(const std::string &filename, int quality_override, SystemTimePoint timestamp) const { return Image::WriteJpeg(filename, quality_override, timestamp, false); } -bool Image::WriteJpeg(const char *filename, +bool Image::WriteJpeg(const std::string &filename, int quality_override, SystemTimePoint timestamp, bool on_blocking_abort) const { @@ -1114,17 +1114,17 @@ bool Image::WriteJpeg(const char *filename, } } - if ( !on_blocking_abort ) { - if ( (outfile = fopen(filename, "wb")) == nullptr ) { - Error("Can't open %s for writing: %s", filename, strerror(errno)); + if (!on_blocking_abort) { + if ((outfile = fopen(filename.c_str(), "wb")) == nullptr) { + Error("Can't open %s for writing: %s", filename.c_str(), strerror(errno)); return false; } } else { - raw_fd = open(filename, O_WRONLY|O_NONBLOCK|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); - if ( raw_fd < 0 ) + raw_fd = open(filename.c_str(), O_WRONLY | O_NONBLOCK | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + if (raw_fd < 0) return false; outfile = fdopen(raw_fd, "wb"); - if ( outfile == nullptr ) { + if (outfile == nullptr) { close(raw_fd); return false; } diff --git a/src/zm_image.h b/src/zm_image.h index 8322f9c17..7778747e4 100644 --- a/src/zm_image.h +++ b/src/zm_image.h @@ -233,14 +233,17 @@ class Image { bool ReadRaw(const char *filename); bool WriteRaw(const char *filename) const; - bool ReadJpeg(const char *filename, unsigned int p_colours, unsigned int p_subpixelorder); + bool ReadJpeg(const std::string &filename, unsigned int p_colours, unsigned int p_subpixelorder); - bool WriteJpeg(const char *filename) const; - bool WriteJpeg(const char *filename, bool on_blocking_abort) const; - bool WriteJpeg(const char *filename, int quality_override) const; - bool WriteJpeg(const char *filename, SystemTimePoint timestamp) const; - bool WriteJpeg(const char *filename, int quality_override, SystemTimePoint timestamp) const; - bool WriteJpeg(const char *filename, int quality_override, SystemTimePoint timestamp, bool on_blocking_abort) const; + bool WriteJpeg(const std::string &filename) const; + bool WriteJpeg(const std::string &filename, bool on_blocking_abort) const; + bool WriteJpeg(const std::string &filename, int quality_override) const; + bool WriteJpeg(const std::string &filename, SystemTimePoint timestamp) const; + bool WriteJpeg(const std::string &filename, int quality_override, SystemTimePoint timestamp) const; + bool WriteJpeg(const std::string &filename, + int quality_override, + SystemTimePoint timestamp, + bool on_blocking_abort) const; bool DecodeJpeg(const JOCTET *inbuffer, int inbuffer_size, unsigned int p_colours, unsigned int p_subpixelorder); bool EncodeJpeg(JOCTET *outbuffer, int *outbuffer_size, int quality_override=0) const; diff --git a/src/zm_jpeg.cpp b/src/zm_jpeg.cpp index c3fddec1f..a71bef48e 100644 --- a/src/zm_jpeg.cpp +++ b/src/zm_jpeg.cpp @@ -37,13 +37,13 @@ void zm_jpeg_emit_silence(j_common_ptr cinfo, int msg_level) { } void zm_jpeg_error_exit(j_common_ptr cinfo) { - static char buffer[JMSG_LENGTH_MAX]; - zm_error_ptr zmerr = (zm_error_ptr)cinfo->err; + zm_error_ptr zmerr = (zm_error_ptr) cinfo->err; - (zmerr->pub.format_message)(cinfo, buffer); + char buffer[JMSG_LENGTH_MAX]; + zmerr->pub.format_message(cinfo, buffer); Error("%s", buffer); - if ( ++jpeg_err_count == MAX_JPEG_ERRS ) { + if (++jpeg_err_count == MAX_JPEG_ERRS) { Fatal("Maximum number (%d) of JPEG errors reached, exiting", jpeg_err_count); } @@ -51,25 +51,25 @@ void zm_jpeg_error_exit(j_common_ptr cinfo) { } void zm_jpeg_emit_message(j_common_ptr cinfo, int msg_level) { - static char buffer[JMSG_LENGTH_MAX]; - zm_error_ptr zmerr = (zm_error_ptr)cinfo->err; + char buffer[JMSG_LENGTH_MAX]; + zm_error_ptr zmerr = (zm_error_ptr) cinfo->err; - if ( msg_level < 0 ) { + if (msg_level < 0) { /* It's a warning message. Since corrupt files may generate many warnings, * the policy implemented here is to show only the first warning, * unless trace_level >= 3. */ - if ( zmerr->pub.num_warnings == 0 || zmerr->pub.trace_level >= 3 ) { - (zmerr->pub.format_message)(cinfo, buffer); - if ( !strstr(buffer, "Corrupt JPEG data:") ) + if (zmerr->pub.num_warnings == 0 || zmerr->pub.trace_level >= 3) { + zmerr->pub.format_message(cinfo, buffer); + if (!strstr(buffer, "Corrupt JPEG data:")) Warning("%s", buffer); } /* Always count warnings in num_warnings. */ zmerr->pub.num_warnings++; } else { /* It's a trace message. Show it if trace_level >= msg_level. */ - if ( zmerr->pub.trace_level >= msg_level ) { - (zmerr->pub.format_message)(cinfo, buffer); + if (zmerr->pub.trace_level >= msg_level) { + zmerr->pub.format_message(cinfo, buffer); Debug(msg_level, "%s", buffer); } } diff --git a/src/zm_local_camera.cpp b/src/zm_local_camera.cpp index dea759134..95f94c32f 100644 --- a/src/zm_local_camera.cpp +++ b/src/zm_local_camera.cpp @@ -864,53 +864,56 @@ uint32_t LocalCamera::AutoSelectFormat(int p_colours) { (test) ? (prefix yesString " " capability "\n") : (prefix noString " " capability "\n") bool LocalCamera::GetCurrentSettings( - const char *device, + const std::string& device, char *output, int version, bool verbose) { output[0] = 0; char *output_ptr = output; - char queryDevice[PATH_MAX] = ""; + std::string queryDevice; int devIndex = 0; do { - if ( device ) { - strncpy(queryDevice, device, sizeof(queryDevice)-1); + if (!device.empty()) { + queryDevice = device; } else { - sprintf(queryDevice, "/dev/video%d", devIndex); + queryDevice = stringtf("/dev/video%d", devIndex); } - if ( (vid_fd = open(queryDevice, O_RDWR)) <= 0 ) { - if ( device ) { - Error("Failed to open video device %s: %s", queryDevice, strerror(errno)); - if ( verbose ) + if ((vid_fd = open(queryDevice.c_str(), O_RDWR)) <= 0) { + if (!device.empty()) { + Error("Failed to open video device %s: %s", queryDevice.c_str(), strerror(errno)); + if (verbose) { output_ptr += sprintf(output_ptr, "Error, failed to open video device %s: %s\n", - queryDevice, strerror(errno)); - else + queryDevice.c_str(), strerror(errno)); + } else { output_ptr += sprintf(output_ptr, "error%d\n", errno); + } return false; } else { return true; } } - if ( verbose ) { - output_ptr += sprintf(output_ptr, "Video Device: %s\n", queryDevice); + + if (verbose) { + output_ptr += sprintf(output_ptr, "Video Device: %s\n", queryDevice.c_str()); } else { - output_ptr += sprintf(output_ptr, "d:%s|", queryDevice); + output_ptr += sprintf(output_ptr, "d:%s|", queryDevice.c_str()); } - if ( version == 2 ) { - struct v4l2_capability vid_cap; - if ( vidioctl(vid_fd, VIDIOC_QUERYCAP, &vid_cap) < 0 ) { + if (version == 2) { + v4l2_capability vid_cap = {}; + if (vidioctl(vid_fd, VIDIOC_QUERYCAP, &vid_cap) < 0) { Error("Failed to query video device: %s", strerror(errno)); - if ( verbose ) { + if (verbose) { output_ptr += sprintf(output_ptr, "Error, failed to query video capabilities %s: %s\n", - queryDevice, strerror(errno)); + queryDevice.c_str(), strerror(errno)); } else { output_ptr += sprintf(output_ptr, "error%d\n", errno); } - if ( device ) + if (!device.empty()) { return false; + } } if ( verbose ) { @@ -953,7 +956,7 @@ bool LocalCamera::GetCurrentSettings( output_ptr += sprintf(output_ptr, verbose ? " Standards:\n" : "S:"); - struct v4l2_standard standard; + v4l2_standard standard = {}; int standardIndex = 0; do { memset(&standard, 0, sizeof(standard)); @@ -981,10 +984,10 @@ bool LocalCamera::GetCurrentSettings( *(output_ptr-1) = '|'; output_ptr += sprintf(output_ptr, verbose ? " Formats:\n" : "F:"); - struct v4l2_fmtdesc format; + int formatIndex = 0; do { - memset(&format, 0, sizeof(format)); + v4l2_fmtdesc format = {}; format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; format.index = formatIndex; @@ -1025,9 +1028,9 @@ bool LocalCamera::GetCurrentSettings( else output_ptr += sprintf(output_ptr, "Crop Capabilities\n"); - struct v4l2_cropcap cropcap; - memset(&cropcap, 0, sizeof(cropcap)); + v4l2_cropcap cropcap = {}; cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + if ( vidioctl(vid_fd, VIDIOC_CROPCAP, &cropcap) < 0 ) { if ( errno != EINVAL ) { /* Failed querying crop capability, write error to the log and continue as if crop is not supported */ @@ -1041,8 +1044,8 @@ bool LocalCamera::GetCurrentSettings( output_ptr += sprintf(output_ptr, "B:%dx%d|", 0, 0); } } else { - struct v4l2_crop crop; - memset(&crop, 0, sizeof(crop)); + v4l2_crop crop = {}; + crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if ( vidioctl(vid_fd, VIDIOC_G_CROP, &crop) < 0 ) { @@ -1159,8 +1162,9 @@ bool LocalCamera::GetCurrentSettings( } close(vid_fd); - if ( device ) + if (!device.empty()) { break; + } } while ( ++devIndex < 32 ); return true; } diff --git a/src/zm_local_camera.h b/src/zm_local_camera.h index f331929d5..d55718512 100644 --- a/src/zm_local_camera.h +++ b/src/zm_local_camera.h @@ -123,7 +123,7 @@ public: int Capture(std::shared_ptr &p) override; int PostCapture() override; int Close() override; - static bool GetCurrentSettings(const char *device, char *output, int version, bool verbose); + static bool GetCurrentSettings(const std::string &device, char *output, int version, bool verbose); }; #endif // ZM_HAS_V4L diff --git a/src/zm_monitor.cpp b/src/zm_monitor.cpp index 4dc7a3128..bf3c366f7 100644 --- a/src/zm_monitor.cpp +++ b/src/zm_monitor.cpp @@ -1184,8 +1184,7 @@ int Monitor::GetImage(int32_t index, int scale) { image = image_buffer[index]; } - static char filename[PATH_MAX]; - snprintf(filename, sizeof(filename), "Monitor%u.jpg", id); + std::string filename = stringtf("Monitor%u.jpg", id); image->WriteJpeg(filename); return 1; } @@ -1508,20 +1507,20 @@ void Monitor::DumpZoneImage(const char *zone_string) { zone_image->Outline(extra_colour, extra_zone); } - static char filename[PATH_MAX]; - snprintf(filename, sizeof(filename), "Zones%u.jpg", id); + std::string filename = stringtf("Zones%u.jpg", id); zone_image->WriteJpeg(filename); delete zone_image; } // end void Monitor::DumpZoneImage(const char *zone_string) void Monitor::DumpImage(Image *dump_image) const { - if ( image_count && !(image_count%10) ) { - static char filename[PATH_MAX]; - static char new_filename[PATH_MAX]; - snprintf(filename, sizeof(filename), "Monitor%u.jpg", id); - snprintf(new_filename, sizeof(new_filename), "Monitor%u-new.jpg", id); - if ( dump_image->WriteJpeg(new_filename) ) - rename(new_filename, filename); + if (image_count && !(image_count % 10)) { + + std::string filename = stringtf("Monitor%u.jpg", id); + std::string new_filename = stringtf("Monitor%u-new.jpg", id); + + if (dump_image->WriteJpeg(new_filename)) { + rename(new_filename.c_str(), filename.c_str()); + } } } // end void Monitor::DumpImage(Image *dump_image) @@ -2785,8 +2784,8 @@ unsigned int Monitor::DetectMotion(const Image &comp_image, Event::StringSet &zo ref_image.Delta(comp_image, &delta_image); if (config.record_diag_images) { - ref_image.WriteJpeg(diag_path_ref.c_str(), config.record_diag_images_fifo); - delta_image.WriteJpeg(diag_path_delta.c_str(), config.record_diag_images_fifo); + ref_image.WriteJpeg(diag_path_ref, config.record_diag_images_fifo); + delta_image.WriteJpeg(diag_path_delta, config.record_diag_images_fifo); } // Blank out all exclusion zones @@ -2934,7 +2933,7 @@ bool Monitor::DumpSettings(char *output, bool verbose) { sprintf( output+strlen(output), "Path : %s\n", cam->Path().c_str() ); } else if ( camera->IsFile() ) { FileCamera* cam = static_cast(camera.get()); - sprintf( output+strlen(output), "Path : %s\n", cam->Path() ); + sprintf( output+strlen(output), "Path : %s\n", cam->Path().c_str() ); } else if ( camera->IsFfmpeg() ) { FfmpegCamera* cam = static_cast(camera.get()); diff --git a/src/zm_monitorstream.cpp b/src/zm_monitorstream.cpp index 8ba498b44..a4ce41a47 100644 --- a/src/zm_monitorstream.cpp +++ b/src/zm_monitorstream.cpp @@ -320,7 +320,7 @@ void MonitorStream::processCommand(const CmdMsg *msg) { //updateFrameRate(monitor->GetFPS()); } // end void MonitorStream::processCommand(const CmdMsg *msg) -bool MonitorStream::sendFrame(const char *filepath, SystemTimePoint timestamp) { +bool MonitorStream::sendFrame(const std::string &filepath, SystemTimePoint timestamp) { bool send_raw = ((scale>=ZM_SCALE_BASE)&&(zoom==ZM_SCALE_BASE)); if ( @@ -330,19 +330,18 @@ bool MonitorStream::sendFrame(const char *filepath, SystemTimePoint timestamp) { ) send_raw = false; - if ( !send_raw ) { - Image temp_image(filepath); + if (!send_raw) { + Image temp_image(filepath.c_str()); return sendFrame(&temp_image, timestamp); } else { int img_buffer_size = 0; static unsigned char img_buffer[ZM_MAX_IMAGE_SIZE]; - FILE *fdj = nullptr; - if ( (fdj = fopen(filepath, "r")) ) { + if (FILE *fdj = fopen(filepath.c_str(), "r")) { img_buffer_size = fread(img_buffer, 1, sizeof(img_buffer), fdj); fclose(fdj); } else { - Error("Can't open %s: %s", filepath, strerror(errno)); + Error("Can't open %s: %s", filepath.c_str(), strerror(errno)); return false; } @@ -747,21 +746,13 @@ void MonitorStream::runStream() { int temp_index = temp_write_index%temp_image_buffer_count; Debug(2, "Storing frame %d", temp_index); if ( !temp_image_buffer[temp_index].valid ) { - snprintf( - temp_image_buffer[temp_index].file_name, - sizeof(temp_image_buffer[0].file_name), - "%s/zmswap-i%05d.jpg", - swap_path.c_str(), - temp_index); + temp_image_buffer[temp_index].file_name = stringtf("%s/zmswap-i%05d.jpg", swap_path.c_str(), temp_index); temp_image_buffer[temp_index].valid = true; } temp_image_buffer[temp_index].timestamp = SystemTimePoint(zm::chrono::duration_cast(monitor->shared_timestamps[index])); - monitor->image_buffer[index]->WriteJpeg( - temp_image_buffer[temp_index].file_name, - config.jpeg_file_quality - ); + monitor->image_buffer[index]->WriteJpeg(temp_image_buffer[temp_index].file_name, config.jpeg_file_quality); temp_write_index = MOD_ADD(temp_write_index, 1, temp_image_buffer_count); if ( temp_write_index == temp_read_index ) { // Go back to live viewing @@ -812,7 +803,7 @@ void MonitorStream::runStream() { if ( buffered_playback ) { Debug(1, "Cleaning swap files from %s", swap_path.c_str()); - struct stat stat_buf; + struct stat stat_buf = {}; if ( stat(swap_path.c_str(), &stat_buf) < 0 ) { if ( errno != ENOENT ) { Error("Can't stat '%s': %s", swap_path.c_str(), strerror(errno)); @@ -820,16 +811,15 @@ void MonitorStream::runStream() { } else if ( !S_ISDIR(stat_buf.st_mode) ) { Error("Swap image path '%s' is not a directory", swap_path.c_str()); } else { - char glob_pattern[PATH_MAX] = ""; - - snprintf(glob_pattern, sizeof(glob_pattern), "%s/*.*", swap_path.c_str()); + std::string glob_pattern = stringtf("%s/*.*", swap_path.c_str()); glob_t pglob; - int glob_status = glob(glob_pattern, 0, 0, &pglob); + + int glob_status = glob(glob_pattern.c_str(), 0, 0, &pglob); if ( glob_status != 0 ) { if ( glob_status < 0 ) { - Error("Can't glob '%s': %s", glob_pattern, strerror(errno)); + Error("Can't glob '%s': %s", glob_pattern.c_str(), strerror(errno)); } else { - Debug(1, "Can't glob '%s': %d", glob_pattern, glob_status); + Debug(1, "Can't glob '%s': %d", glob_pattern.c_str(), glob_status); } } else { for ( unsigned int i = 0; i < pglob.gl_pathc; i++ ) { diff --git a/src/zm_monitorstream.h b/src/zm_monitorstream.h index f07ee393d..0dc07b067 100644 --- a/src/zm_monitorstream.h +++ b/src/zm_monitorstream.h @@ -27,7 +27,7 @@ class MonitorStream : public StreamBase { struct SwapImage { bool valid = false; SystemTimePoint timestamp; - char file_name[PATH_MAX] = ""; + std::string file_name; }; private: @@ -44,7 +44,7 @@ class MonitorStream : public StreamBase { protected: bool checkSwapPath(const char *path, bool create_path); - bool sendFrame(const char *filepath, SystemTimePoint timestamp); + bool sendFrame(const std::string &filepath, SystemTimePoint timestamp); bool sendFrame(Image *image, SystemTimePoint timestamp); void processCommand(const CmdMsg *msg) override; void SingleImage(int scale=100); diff --git a/src/zm_zone.cpp b/src/zm_zone.cpp index 41174857f..5a62b22d7 100644 --- a/src/zm_zone.cpp +++ b/src/zm_zone.cpp @@ -104,7 +104,8 @@ void Zone::Setup( diag_path = stringtf("%s/diag-%d-poly.jpg", monitor->getStorage()->Path(), id); } - pg_image->WriteJpeg(diag_path.c_str(), config.record_diag_images_fifo); + + pg_image->WriteJpeg(diag_path, config.record_diag_images_fifo); } } // end Zone::Setup @@ -233,8 +234,9 @@ bool Zone::CheckAlarms(const Image *delta_image) { } */ std_alarmedpixels(diff_image, pg_image, &stats.alarm_pixels_, &pixel_diff_count); - if (config.record_diag_images) - diff_image->WriteJpeg(diag_path.c_str(), config.record_diag_images_fifo); + if (config.record_diag_images) { + diff_image->WriteJpeg(diag_path, config.record_diag_images_fifo); + } if (pixel_diff_count && stats.alarm_pixels_) stats.pixel_diff_ = pixel_diff_count/stats.alarm_pixels_; @@ -317,8 +319,9 @@ bool Zone::CheckAlarms(const Image *delta_image) { stats.alarm_filter_pixels_ = stats.alarm_pixels_; } - if (config.record_diag_images) - diff_image->WriteJpeg(diag_path.c_str(), config.record_diag_images_fifo); + if (config.record_diag_images) { + diff_image->WriteJpeg(diag_path, config.record_diag_images_fifo); + } Debug(5, "Got %d filtered pixels, need %d -> %d", stats.alarm_filter_pixels_, min_filter_pixels, max_filter_pixels); @@ -541,8 +544,9 @@ bool Zone::CheckAlarms(const Image *delta_image) { } } - if (config.record_diag_images) - diff_image->WriteJpeg(diag_path.c_str(), config.record_diag_images_fifo); + if (config.record_diag_images) { + diff_image->WriteJpeg(diag_path, config.record_diag_images_fifo); + } if (!stats.alarm_blobs_) { stats.score_ = 0; @@ -593,8 +597,9 @@ bool Zone::CheckAlarms(const Image *delta_image) { } // end if bs_count } // end for i < WHITE - if (config.record_diag_images) - diff_image->WriteJpeg(diag_path.c_str(), config.record_diag_images_fifo); + if (config.record_diag_images) { + diff_image->WriteJpeg(diag_path, config.record_diag_images_fifo); + } Debug(5, "Got %d blob pixels, %d blobs, need %d -> %d, %d -> %d", stats.alarm_blob_pixels_, stats.alarm_blobs_, min_blob_pixels, max_blob_pixels, min_blobs, max_blobs); From eaf2e51b0c33226f1acf75323e69cb4c5498d626 Mon Sep 17 00:00:00 2001 From: Peter Keresztes Schmidt Date: Fri, 25 Jun 2021 23:48:35 +0200 Subject: [PATCH 2/2] utils: Make sure the compiler can emit format warnings for stringtf Unfortunately the compilers can't emit Wformat warnings for variadic templates and those can't be annotated with the format attribute. Use a variadic function which can be annotated and thus warns on format string-args mismatches. Ref 0796a2262e43936ba50a631bb899a841652c2f76 --- src/zm_event.cpp | 4 ++-- src/zm_eventstream.cpp | 10 +++++----- src/zm_logger.cpp | 4 ++-- src/zm_utils.cpp | 21 +++++++++++++++++++++ src/zm_utils.h | 12 ++---------- 5 files changed, 32 insertions(+), 19 deletions(-) diff --git a/src/zm_event.cpp b/src/zm_event.cpp index b0215662a..be9e26a00 100644 --- a/src/zm_event.cpp +++ b/src/zm_event.cpp @@ -518,7 +518,7 @@ void Event::AddFrame(Image *image, if (image) { if (save_jpegs & 1) { - std::string event_file = stringtf(staticConfig.capture_file_format, path.c_str(), frames); + std::string event_file = stringtf(staticConfig.capture_file_format.c_str(), path.c_str(), frames); Debug(1, "Writing capture frame %d to %s", frames, event_file.c_str()); if (!WriteFrameImage(image, timestamp, event_file.c_str())) { Error("Failed to write frame image"); @@ -548,7 +548,7 @@ void Event::AddFrame(Image *image, } if (alarm_image and (save_jpegs & 2)) { - std::string event_file = stringtf(staticConfig.analyse_file_format, path.c_str(), frames); + std::string event_file = stringtf(staticConfig.analyse_file_format.c_str(), path.c_str(), frames); Debug(1, "Writing analysis frame %d", frames); if (!WriteFrameImage(alarm_image, timestamp, event_file.c_str(), true)) { Error("Failed to write analysis frame image"); diff --git a/src/zm_eventstream.cpp b/src/zm_eventstream.cpp index 0b501149c..6f017c0bc 100644 --- a/src/zm_eventstream.cpp +++ b/src/zm_eventstream.cpp @@ -44,7 +44,7 @@ constexpr Milliseconds EventStream::STREAM_PAUSE_WAIT; bool EventStream::loadInitialEventData(int monitor_id, SystemTimePoint event_time) { std::string sql = stringtf("SELECT `Id` FROM `Events` WHERE " "`MonitorId` = %d AND unix_timestamp(`EndDateTime`) > %ld " - "ORDER BY `Id` ASC LIMIT 1", monitor_id, event_time); + "ORDER BY `Id` ASC LIMIT 1", monitor_id, std::chrono::system_clock::to_time_t(event_time)); MYSQL_RES *result = zmDbFetch(sql.c_str()); if (!result) @@ -687,7 +687,7 @@ bool EventStream::checkEventLoaded() { } // void EventStream::checkEventLoaded() Image * EventStream::getImage( ) { - std::string path = stringtf(staticConfig.capture_file_format, event_data->path.c_str(), curr_frame_id); + std::string path = stringtf(staticConfig.capture_file_format.c_str(), event_data->path.c_str(), curr_frame_id); Debug(2, "EventStream::getImage path(%s) from %s frame(%ld) ", path.c_str(), event_data->path.c_str(), curr_frame_id); Image *image = new Image(path.c_str()); return image; @@ -702,12 +702,12 @@ bool EventStream::sendFrame(Microseconds delta_us) { // This needs to be abstracted. If we are saving jpgs, then load the capture file. // If we are only saving analysis frames, then send that. if (event_data->SaveJPEGs & 1) { - filepath = stringtf(staticConfig.capture_file_format, event_data->path.c_str(), curr_frame_id); + filepath = stringtf(staticConfig.capture_file_format.c_str(), event_data->path.c_str(), curr_frame_id); } else if (event_data->SaveJPEGs & 2) { - filepath = stringtf(staticConfig.analyse_file_format, event_data->path.c_str(), curr_frame_id); + filepath = stringtf(staticConfig.analyse_file_format.c_str(), event_data->path.c_str(), curr_frame_id); if (stat(filepath.c_str(), &filestat) < 0) { Debug(1, "analyze file %s not found will try to stream from other", filepath.c_str()); - filepath = stringtf(staticConfig.capture_file_format, event_data->path.c_str(), curr_frame_id); + filepath = stringtf(staticConfig.capture_file_format.c_str(), event_data->path.c_str(), curr_frame_id); if (stat(filepath.c_str(), &filestat) < 0) { Debug(1, "capture file %s not found either", filepath.c_str()); filepath = ""; diff --git a/src/zm_logger.cpp b/src/zm_logger.cpp index 580043488..993855e35 100644 --- a/src/zm_logger.cpp +++ b/src/zm_logger.cpp @@ -528,8 +528,8 @@ void Logger::logPrint(bool hex, const char *filepath, int line, int level, const "INSERT INTO `Logs` " "( `TimeKey`, `Component`, `ServerId`, `Pid`, `Level`, `Code`, `Message`, `File`, `Line` )" " VALUES " - "( %ld.%06ld, '%s', %d, %d, %d, '%s', '%s', '%s', %d )", - now_sec, now_frac.count(), mId.c_str(), staticConfig.SERVER_ID, tid, level, classString, + "( %ld.%06" PRIi64 ", '%s', %d, %d, %d, '%s', '%s', '%s', %d )", + now_sec, static_cast(now_frac.count()), mId.c_str(), staticConfig.SERVER_ID, tid, level, classString, escapedString.c_str(), file, line); dbQueue.push(std::move(sql_string)); } else { diff --git a/src/zm_utils.cpp b/src/zm_utils.cpp index 58726778e..5da5509ff 100644 --- a/src/zm_utils.cpp +++ b/src/zm_utils.cpp @@ -22,6 +22,7 @@ #include "zm_config.h" #include "zm_logger.h" #include +#include #include #include /* Definition of AT_* constants */ #include @@ -116,6 +117,26 @@ std::string Join(const StringVector &values, const std::string &delim) { return ss.str(); } +std::string stringtf(const char* format, ...) { + va_list args; + va_start(args, format); + va_list args2; + va_copy(args2, args); + + int size = vsnprintf(nullptr, 0, format, args) + 1; // Extra space for '\0' + va_end(args); + + if (size <= 0) { + throw std::runtime_error("Error during formatting."); + } + + std::unique_ptr buf(new char[size]); + vsnprintf(buf.get(), size, format, args2); + va_end(args2); + + return std::string(buf.get(), buf.get() + size - 1); // We don't want the '\0' inside +} + std::string ByteArrayToHexString(nonstd::span bytes) { static constexpr char lowercase_table[] = "0123456789abcdef"; std::string buf; diff --git a/src/zm_utils.h b/src/zm_utils.h index f4af1f1d4..d5ee88202 100644 --- a/src/zm_utils.h +++ b/src/zm_utils.h @@ -61,16 +61,8 @@ inline bool StartsWith(const std::string &haystack, const std::string &needle) { return (haystack.substr(0, needle.length()) == needle); } -template -std::string stringtf(const std::string &format, Args... args) { - int size = snprintf(nullptr, 0, format.c_str(), args...) + 1; // Extra space for '\0' - if (size <= 0) { - throw std::runtime_error("Error during formatting."); - } - std::unique_ptr buf(new char[size]); - snprintf(buf.get(), size, format.c_str(), args...); - return std::string(buf.get(), buf.get() + size - 1); // We don't want the '\0' inside -} +__attribute__((format(printf, 1, 2))) +std::string stringtf(const char* format, ...); std::string ByteArrayToHexString(nonstd::span bytes);