2010-07-16 Dario Rodriguez <dario.rodriguez@artica.es>

* 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
This commit is contained in:
darode 2010-07-16 11:43:07 +00:00
parent 9dacdae5ff
commit 1ab8d24ba5
5 changed files with 310 additions and 4 deletions

View File

@ -1,3 +1,19 @@
2010-07-16 Dario Rodriguez <dario.rodriguez@artica.es>
* 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 <dario.rodriguez@artica.es>
* 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 <dario.rodriguez@artica.es>
* pandora_agent_conf.cc: Added support to parse collections

View File

@ -23,6 +23,11 @@
#include <iostream>
#include <stdio.h>
#include <windows.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>
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.
*

View File

@ -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);

View File

@ -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 () {

View File

@ -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 ();