From 1ab8d24ba5bf7e39cc974fd72079f36e79abc4dd Mon Sep 17 00:00:00 2001 From: darode Date: Fri, 16 Jul 2010 11:43:07 +0000 Subject: [PATCH] 2010-07-16 Dario Rodriguez * misc/pandora_file.cc, pandora_file.h: Added function to remove directories recursively * win32/pandora_windows_service.cc, pandora_windows_service.h: Added support for unzip collections and improved functionality to manage collections. git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@3015 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f --- pandora_agents/win32/ChangeLog | 16 ++ pandora_agents/win32/misc/pandora_file.cc | 84 ++++++- pandora_agents/win32/misc/pandora_file.h | 1 + .../win32/pandora_windows_service.cc | 209 ++++++++++++++++++ .../win32/pandora_windows_service.h | 4 +- 5 files changed, 310 insertions(+), 4 deletions(-) diff --git a/pandora_agents/win32/ChangeLog b/pandora_agents/win32/ChangeLog index 09d621eea0..72808b1537 100644 --- a/pandora_agents/win32/ChangeLog +++ b/pandora_agents/win32/ChangeLog @@ -1,3 +1,19 @@ +2010-07-16 Dario Rodriguez + + * misc/pandora_file.cc, pandora_file.h: Added function to remove directories + recursively + + * win32/pandora_windows_service.cc, pandora_windows_service.h: Added + support for unzip collections and improved functionality to manage + collections. + +2010-07-14 Dario Rodriguez + + * win32/pandora_agent_conf.cc, pandora_agent_conf.h: Added functionality + to get collection from configuration file. + * win32/pandora_windows_service.cc, pandora_windows_service.h: Added + support for manage collections + 2010-07-13 Dario Rodriguez * pandora_agent_conf.cc: Added support to parse collections diff --git a/pandora_agents/win32/misc/pandora_file.cc b/pandora_agents/win32/misc/pandora_file.cc index 21f6543a84..9407ab7f1c 100644 --- a/pandora_agents/win32/misc/pandora_file.cc +++ b/pandora_agents/win32/misc/pandora_file.cc @@ -23,6 +23,11 @@ #include #include #include +#include +#include +#include + + using namespace std; @@ -120,11 +125,11 @@ Pandora_File::readBinFile (const string filepath, char **buffer) { } /** - * Delete a file from a directory. + * Delete a file or a directory recursively. * - * @param filepath Path of the file to delete. + * @param filepath Path of the file or directory to delete. * - * @exception Delete_Error if the file could not be deleted. + * @return non zero if the file could not be deleted. */ int Pandora_File::removeFile (const string filepath) { @@ -133,6 +138,79 @@ Pandora_File::removeFile (const string filepath) { } } +/** + * Delete a directory with all its content. + * + * @param filepath Path of the directory to delete. + * + * @return Delete_Error if the file could not be deleted. + */ +int +Pandora_File::removeDir (const string filepath) { + DIR *dir; + struct dirent *dir_content; + struct stat file; + string tmp; + + /*Open the directory*/ + dir = opendir (filepath.c_str ()); + + /*If not open*/ + if (dir == NULL) { + /**If not exists*/ + if(errno == ENOENT) { + return 0; + } else { + /*If its a file, delete it*/ + if(errno == ENOTDIR) { + if (remove (filepath.c_str ()) == -1) { + return DELETE_ERROR; + } + return 0; + } else { + return DELETE_ERROR; + } + } + } + + /*If open*/ + /*Read the directory looking for files and folders*/ + dir_content = readdir(dir); + + while (dir_content != NULL) { + + string tmp = filepath+"\\"+dir_content->d_name; + + stat(tmp.c_str(),&file); + + switch (file.st_mode & S_IFMT) { + case S_IFDIR: + /*If tmp is a folder, recursive delete*/ + if ( (strcmp(dir_content->d_name,".") != 0) && (strcmp(dir_content->d_name,"..") != 0)){ + removeDir(tmp); + } + + break; + default: + /*If tmp is a file, it will be deleted*/ + if (remove (tmp.c_str ()) == -1) { + return DELETE_ERROR; + } + break; + } + + /*Next item*/ + dir_content = readdir(dir); + } + + /*When the folder is empty, delete the folder*/ + if (rmdir (filepath.c_str ()) == -1) { + return DELETE_ERROR; + } + + return 0; +} + /** * Write data into a text file. * diff --git a/pandora_agents/win32/misc/pandora_file.h b/pandora_agents/win32/misc/pandora_file.h index 6eaabed72b..8c3db124f9 100644 --- a/pandora_agents/win32/misc/pandora_file.h +++ b/pandora_agents/win32/misc/pandora_file.h @@ -54,6 +54,7 @@ namespace Pandora_File { bool fileExists (const string filename); int readFile (const string filepath, string &result); int readBinFile (const string filepath, char **buffer); + int removeDir (const string filepath); int removeFile (const string filename); void writeFile (const string filename, const string data); void writeBinFile (const string filepath, const char *buffer, int size); diff --git a/pandora_agents/win32/pandora_windows_service.cc b/pandora_agents/win32/pandora_windows_service.cc index 8780592866..436c20e98c 100644 --- a/pandora_agents/win32/pandora_windows_service.cc +++ b/pandora_agents/win32/pandora_windows_service.cc @@ -591,6 +591,215 @@ Pandora_Windows_Service::copyLocalDataFile (string remote_path, } } +int +Pandora_Windows_Service::unzipCollection(string zip_path, string dest_dir) { + string unzip_cmd, dest_cmd; + PROCESS_INFORMATION pi; + STARTUPINFO si; + mode_t mode; + DWORD rc; + + /*Delete dest directory*/ + Pandora_File::removeDir(dest_dir); + + /* Build the command to create destination diectory*/ + rc = mkdir (dest_dir.c_str()); + + if (rc != 0) { + pandoraLog ("Pandora_Windows_Service::unzipCollection: Can not create dir %s", dest_dir.c_str()); + return -1; + } + + /* Build the command to launch the Tentacle client */ + unzip_cmd = "unzip.exe \"" + zip_path + "\" -d \"" + dest_dir + "\""; + + ZeroMemory (&si, sizeof (si)); + ZeroMemory (&pi, sizeof (pi)); + if (CreateProcess (NULL , (CHAR *)unzip_cmd.c_str (), NULL, NULL, FALSE, + CREATE_NO_WINDOW, NULL, NULL, &si, &pi) == 0) { + return -1; + } + + /* Get the return code of the tentacle client*/ + WaitForSingleObject(pi.hProcess, INFINITE); + GetExitCodeProcess (pi.hProcess, &rc); + + if (rc != 0) { + CloseHandle (pi.hProcess); + pandoraLog ("Pandora_Windows_Service::unzipCollection: Can not unzip file %s", zip_path.c_str()); + return -1; + } + + CloseHandle (pi.hProcess); + return 0; +} + +void +Pandora_Windows_Service::checkCollections () { + + int flag, i; + char *coll_md5 = NULL, *server_coll_md5 = NULL; + string collection_name, collections_dir, collection_md5, tmp; + string collection_zip, install_dir, temp_dir, dest_dir, path, env; + + /*Get collections directory*/ + install_dir = Pandora::getPandoraInstallDir (); + collections_dir = install_dir+"collections\\"; + + /* Get temporal directory */ + temp_dir = conf->getValue ("temporal"); + if (temp_dir[temp_dir.length () - 1] != '\\') { + temp_dir += "\\"; + } + + /*Set iterator in the firs collection*/ + conf->goFirstCollection(); + + while (! conf->isLastCollection()) { + + collection_name = conf->getCurrentCollection(); + collection_zip = collection_name+".zip"; + collection_md5 = collection_name + ".md5"; + tmp = collections_dir+collection_md5; + + /*Reading local collection md5*/ + try { + if (Pandora_File::readBinFile (tmp, &coll_md5) < 32) { + pandoraLog ("Pandora_Windows_Service::checkCollection: Invalid remote md5", tmp.c_str()); + if (coll_md5 != NULL) { + delete[] coll_md5; + } + return; + } + } catch (...) { + /*Getting new md5*/ + try { + /*Downloading md5 file*/ + recvDataFile (collection_md5); + + /*Reading new md5 file*/ + tmp = temp_dir + collection_md5; + + if (Pandora_File::readBinFile (tmp, &coll_md5) < 32) { + pandoraLog ("Pandora_Windows_Service::checkCollection: Invalid remote md5", tmp.c_str()); + if (coll_md5 != NULL) { + delete[] coll_md5; + } + return; + } + + Pandora_File::removeFile (tmp); + + /* Save new md5 file */ + tmp = collections_dir + collection_md5; + Pandora_File::writeBinFile (tmp, coll_md5, 32); + + } catch(...) { + pandoraLog ("Pandora_Windows_Service::checkCollection: Can not download %s", collection_md5.c_str()); + return; + } + + /*Getting new zipped collection*/ + try { + /*Downloading zipped collection*/ + recvDataFile (collection_zip); + + /*Uncompress zipped collection*/ + tmp = temp_dir + collection_zip; + dest_dir = collections_dir + collection_name; + unzipCollection(tmp,dest_dir); + + /*Add the collection directory to the path*/ + tmp = collections_dir + collection_name; + path = getenv ("PATH"); + env = "PATH=" + path + ";" + tmp; + putenv (env.c_str ()); + + } catch (...) { + pandoraLog ("Pandora_Windows_Service::checkCollection: Can not download %s", collection_zip.c_str()); + return; + } + + conf->goNextCollection(); + continue; + } + + /*Reading server collection md5*/ + try { + + recvDataFile(collection_md5); + tmp = temp_dir+collection_md5; + if (Pandora_File::readBinFile (tmp, &server_coll_md5) < 32) { + pandoraLog ("Pandora_Windows_Service::checkCollection: Invalid remote md5", tmp.c_str()); + if (server_coll_md5 != NULL) { + delete[] server_coll_md5; + } + return; + } + Pandora_File::removeFile (tmp); + + } catch (...) { + pandoraLog ("Pandora_Windows_Service::checkCollection: Can not download %s", collection_md5.c_str()); + return; + } + + /*Check both md5*/ + flag = 0; + for (i = 0; i < 32; i++) { + if (coll_md5[i] != server_coll_md5[i]) { + flag = 1; + break; + } + } + + /*If the two md5 are equals, exit*/ + if (flag == 0) { + return; + } + + pandoraLog("Pandora_Windows_Service::checkCollections: Collection %s has changed", collection_md5.c_str ()); + + /*Getting new zipped collection*/ + try { + /*Downloading zipped collection*/ + recvDataFile (collection_zip); + + /*Uncompress zipped collection*/ + tmp = temp_dir + collection_zip; + dest_dir = collections_dir + collection_name; + unzipCollection(tmp,dest_dir); + + /*Add the collection directory to the path*/ + /*Add the collection directory to the path*/ + tmp = collections_dir + collection_name; + path = getenv ("PATH"); + env = "PATH=" + path + ";" + tmp; + putenv (env.c_str ()); + + } catch (...) { + pandoraLog ("Pandora_Windows_Service::checkCollection: Can not download %s", collection_zip.c_str()); + return; + } + + /* Save new md5 file */ + tmp = collections_dir + collection_md5; + Pandora_File::writeBinFile (tmp, server_coll_md5, 32); + + /*Free coll_md5*/ + if (coll_md5 != NULL) { + delete[] coll_md5; + } + + /*Free server_coll_md5*/ + if (server_coll_md5 != NULL) { + delete[] server_coll_md5; + } + + /*Go to next collection*/ + conf->goNextCollection(); + } +} + void Pandora_Windows_Service::checkCollections () { diff --git a/pandora_agents/win32/pandora_windows_service.h b/pandora_agents/win32/pandora_windows_service.h index fb2ae5b743..777d80360d 100644 --- a/pandora_agents/win32/pandora_windows_service.h +++ b/pandora_agents/win32/pandora_windows_service.h @@ -68,7 +68,9 @@ namespace Pandora { void recvDataFile (string filename); void recvTentacleDataFile (string host, string filename); - void checkCollections (); + + int unzipCollection(string zip_path, string dest_dir); + void checkCollections (); void checkConfig (); Pandora_Windows_Service ();