From 9360837d385a430dc60ae87259c5a62ab299c75e Mon Sep 17 00:00:00 2001 From: Emmanuel Papin Date: Mon, 26 Jan 2015 21:13:05 +0100 Subject: [PATCH] Add a DeleteEvent function to Event cpp class --- src/zm_event.cpp | 101 +++++++++++++++++++++++++++++++++++++++++++++++ src/zm_event.h | 1 + src/zm_utils.cpp | 66 ++++++++++++++++++++++++++++++- src/zm_utils.h | 2 + 4 files changed, 169 insertions(+), 1 deletion(-) diff --git a/src/zm_event.cpp b/src/zm_event.cpp index 910a1444a..6edaf9726 100644 --- a/src/zm_event.cpp +++ b/src/zm_event.cpp @@ -35,6 +35,7 @@ #include "zm_signal.h" #include "zm_event.h" #include "zm_monitor.h" +#include "zm_utils.h" #include "zmf.h" @@ -230,6 +231,106 @@ void Event::AddCause( const std::string new_cause ) } } +// This is the transcription of JavaScript function DeleteEvent() +void Event::DeleteEvent() +{ + static char sql[ZM_SQL_MED_BUFSIZ]; + + snprintf( sql, sizeof(sql), "DELETE FROM `Events` WHERE `Id` = %d;", id ); + if ( mysql_query( &dbconn, sql) ) + { + Error( "Can't run query: %s", mysql_error( &dbconn ) ); + exit( mysql_errno( &dbconn ) ); + } + + if ( !config.opt_fast_delete ) + { + snprintf( sql, sizeof(sql), "DELETE FROM `Stats` WHERE `EventId` = %d;", id ); + if ( mysql_query( &dbconn, sql ) ) + { + Error( "Can't run query: %s", mysql_error( &dbconn ) ); + exit( mysql_errno( &dbconn ) ); + } + + snprintf( sql, sizeof(sql), "DELETE FROM `Frames` WHERE `EventId` = %d;", id ); + if ( mysql_query( &dbconn, sql ) ) + { + Error( "Can't run query: %s", mysql_error( &dbconn ) ); + exit( mysql_errno( &dbconn ) ); + } + + static char dir_events[PATH_MAX] = ""; + if ( config.dir_events[0] == '/' ) + snprintf( dir_events, sizeof(dir_events), "%s", config.dir_events ); + else + snprintf( dir_events, sizeof(dir_events), "%s/%s", staticConfig.PATH_WEB.c_str(), config.dir_events ); + + if ( config.use_deep_storage ) + { + static char event_glob[PATH_MAX] = ""; + snprintf( event_glob, sizeof(event_glob), "%s/%d/*/*/*/.%d", dir_events, monitor->Id(), id ); + + glob_t pglob; + if( glob( event_glob, GLOB_ONLYDIR, 0, &pglob ) == 0 ) + { + char *event_path = pglob.gl_pathv[0]; + static char link[PATH_MAX] = ""; + + ssize_t len; + if ( ( len = readlink(event_path, link, sizeof(link)-1 ) ) ) + { + link[len] = '\0'; + int last_slash = strrchr( event_path, '/' ) - event_path; + + char base_path[PATH_MAX] = ""; + strncpy(base_path, event_path, last_slash); + + static char link_path[PATH_MAX] = ""; + snprintf( link_path, sizeof(link_path), "%s/%s", base_path, link ); + + // Delete linked folder (remove_dir is called with second + // argument = true to force deletion of folder content) + if (remove_dir(link_path, true, false) < 0) + return; + + // Delete symlink + if (unlink(event_path) < 0) + return; + + // Now we have successfully deleted all files we can do some + // cleaning on the storage directory + // The storage folders are scanned from deep to root and + // deleted if empty + for(size_t i=strlen(link_path)-1; i>strlen(dir_events); i--) + { + if(link_path[i] != '/') + continue; + + char del_path[PATH_MAX] = ""; + strncpy(del_path, link_path, i); + + // Deletion is stopped at first non empty folder + // encountered + if(remove_dir(del_path, false, false) < 0) + break; + } + } + else + { + // Delete broken symlink + unlink(event_path); + } + } + } + else + { + static char event_path[PATH_MAX] = ""; + snprintf(event_path, sizeof(event_path), "%s/%d/%d", dir_events, monitor->Id(), id); + remove_dir(event_path, true, false); + } + } +} + int Event::sd = -1; bool Event::OpenFrameSocket( int monitor_id ) diff --git a/src/zm_event.h b/src/zm_event.h index 980b4016d..2d9e107f3 100644 --- a/src/zm_event.h +++ b/src/zm_event.h @@ -133,6 +133,7 @@ public: void AddFrames( int n_frames, Image **images, struct timeval **timestamps ); void AddFrame( Image *image, struct timeval timestamp, int score=0, Image *alarm_frame=NULL ); void AddCause( const std::string new_cause ); + void DeleteEvent(); private: void AddFramesInternal( int n_frames, int start_frame, Image **images, struct timeval **timestamps ); diff --git a/src/zm_utils.cpp b/src/zm_utils.cpp index e0c65ca61..8b42586e5 100644 --- a/src/zm_utils.cpp +++ b/src/zm_utils.cpp @@ -17,13 +17,17 @@ // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // -//#include "zm_logger.h" +#include "zm_logger.h" #include "zm.h" #include "zm_utils.h" #include #include #include +#include +#include +#include +#include unsigned int sseversion = 0; @@ -345,3 +349,63 @@ void timespec_diff(struct timespec *start, struct timespec *end, struct timespec } } +int remove_dir(const char *path, bool force, bool verbose) +{ + DIR *d = opendir(path); + size_t path_len = strlen(path); + int r = -1; + + if (d) + { + struct dirent *p; + r = 0; + + while (!r && (p=readdir(d))) + { + int r2 = -1; + char *buf; + size_t len; + + if (!strcmp(p->d_name, ".") || !strcmp(p->d_name, "..")) + continue; + + if (!force) + { + if (verbose) + Error("Can't remove directory '%s/%s': (not empty)", path, p->d_name); + return r2; + } + + len = path_len + strlen(p->d_name) + 2; + buf = (char*)malloc(len); + + if (buf) + { + struct stat statbuf; + snprintf(buf, len, "%s/%s", path, p->d_name); + if (!stat(buf, &statbuf)) + { + if (S_ISDIR(statbuf.st_mode)) + { + if (((r2 = remove_dir(buf, force)) < 0) && verbose) + Error("Can't remove directory '%s': %s", buf, strerror(errno)); + } + else + { + if (((r2 = unlink(buf)) < 0) && verbose) + Error("Can't remove file '%s': %s", buf, strerror(errno)); + } + } + free(buf); + } + r = r2; + } + closedir(d); + } + + if ((!r) && ((r = rmdir(path)) < 0) && verbose) + Error("Can't remove directory '%s': %s", path, strerror(errno)); + + return r; +} + diff --git a/src/zm_utils.h b/src/zm_utils.h index 063c74b7d..49b0266c1 100644 --- a/src/zm_utils.h +++ b/src/zm_utils.h @@ -60,4 +60,6 @@ void timespec_diff(struct timespec *start, struct timespec *end, struct timespec extern unsigned int sseversion; +int remove_dir(const char *path, bool force = false, bool verbose = false); + #endif // ZM_UTILS_H