// this is the "wrapper" file for the zip/unzip functions to expose to BOINC clients #pragma warning( disable : 4786 ) // Disable warning messages for vector #ifdef __cplusplus extern "C" { #else extern { #endif int unzip_main(int argc, char** argv); int zip_main(int argc, char** argv); } #ifdef _WIN32 #include #else #include "config.h" #include #include using std::string; #endif #include "./unzip/unzip.h" #include "./zip/zip.h" #include "boinc_zip.h" #include "filesys.h" // from BOINC for DirScan #include // send in an output filename, advanced options (usually NULL), and numFileIn, szfileIn #ifndef _MAX_PATH #define _MAX_PATH 255 #endif unsigned char g_ucSort; // a "binary predicate" for use by the std::sort algorithm // return true if "first > second" according to the g_ucSort type bool StringVectorSort(const std::string& first, const std::string& second) { bool bRet = false; if (g_ucSort & SORT_NAME && g_ucSort & SORT_ASCENDING && strcmp(first.c_str(), second.c_str())<0) bRet = true; else if (g_ucSort & SORT_NAME && g_ucSort & SORT_DESCENDING && strcmp(first.c_str(), second.c_str())>0) bRet = true; else if (g_ucSort & SORT_TIME) { struct stat st[2]; stat(first.c_str(), &st[0]); stat(second.c_str(), &st[1]); if (g_ucSort & SORT_ASCENDING) { bRet = st[0].st_mtime < st[1].st_mtime; } else { bRet = st[0].st_mtime > st[1].st_mtime; } } return bRet; } int boinc_zip(int bZipType, const std::string szFileZip, const std::string szFileIn) { ZipFileList tempvec; tempvec.push_back(szFileIn); return boinc_zip(bZipType, szFileZip, &tempvec); } int boinc_zip(int bZipType, const char* szFileZip, const char* szFileIn) { // just use the regular boinc_zip std::string strFileZip, strFileIn; strFileZip.assign(szFileZip); strFileIn.assign(szFileIn); ZipFileList tempvec; tempvec.push_back(strFileIn); return boinc_zip(bZipType, strFileZip, &tempvec); } int boinc_zip(int bZipType, const std::string szFileZip, const ZipFileList* pvectszFileIn) { int carg; char** av; int iRet = 0, i = 0, nVecSize = 0; if (pvectszFileIn) nVecSize = pvectszFileIn->size(); // if unzipping but no file out, so it just uses cwd, only 3 args //if (bZipType == UNZIP_IT) // carg = 3 + nVecSize; //else carg = 3 + nVecSize; // make a dynamic array av = (char**) calloc(carg, sizeof(char*)); for (i=0;iat(jj).c_str()); } else { strcpy(av[0], "unzip"); // default unzip options -- preserve subdirs, overwrite if (strlen(av[1])==0) strcpy(av[1], "-o"); strcpy(av[2], szFileZip.c_str()); // if they passed in a directory unzip there if (carg == 4) sprintf(av[3], "-d%s", pvectszFileIn->at(0).c_str()); } // strcpy(av[carg-1], ""); // null arg // printf("args: %s %s %s %s\n", av[0], av[1], av[2], av[3]); if (bZipType == ZIP_IT) { if (access(szFileZip.c_str(), 0) == 0) { // old zip file exists so unlink (otherwise zip will reuse, doesn't seem to be a flag to // bypass zip reusing it unlink(szFileZip.c_str()); } iRet = zip_main(carg, av); } else { // make sure zip file exists if (access(szFileZip.c_str(), 0) == 0) iRet = unzip_main(carg, av); else iRet = 2; } for (i=0;iclear(); // removes old entries that may be in pList // first tack on a final slash on user dir if required if (strUserDir[iLen-1] != '\\' && strUserDir[iLen] != '/') { // need a final slash, but what type? // / is safe on all OS's for CPDN at least // but if they already used \ use that // well they didn't use a backslash so just use a slash if (strUserDir.find("\\") == string::npos) strUserDir += "/"; else strUserDir += "\\"; } // transform strDir to either all \\ or all / int j; for (j=0; j<(int)directory.size(); j++) { // take off final / or backslash if (j == ((int)directory.size()-1) && (strDir[j] == '/' || strDir[j]=='\\')) strDir.resize(directory.size()-1); else { #ifdef _WIN32 // transform paths appropriate for OS if (directory[j] == '/') strDir[j] = '\\'; #else if (directory[j] == '\\') strDir[j] = '/'; #endif } } DirScanner dirscan(strDir); memset(strPart, 0x00, 3*32); while (dirscan.scan(strFile)) { iCtr = 0; lastPos = 0; iPos[0] = -1; iPos[1] = -1; iPos[2] = -1; // match the whole filename returned against the regexp to see if it's a hit // first get all the |'s to get the pieces to verify while (iCtr<3 && (iPos[iCtr] = (int) spattern.find('|', lastPos)) > -1) { if (iCtr==0) { strncpy(strPart[0], spattern.c_str(), iPos[iCtr]); } else { strncpy(strPart[iCtr], spattern.c_str()+lastPos, iPos[iCtr]-lastPos); } lastPos = iPos[iCtr]+1; iCtr++; } if (iCtr>0) // found a | so need to get the part from lastpos onward { strncpy(strPart[iCtr], spattern.c_str()+lastPos, spattern.length() - lastPos); } // check no | were found at all if (iCtr == 0) { strcpy(strPart[0], spattern.c_str()); iCtr++; // fake iCtr up 1 to get in the loop below } bool bFound = true; for (i = 0; i <= iCtr && bFound; i++) { if (i==0) { iFnd = (int) strFile.find(strPart[0]); bFound = (bool) (iFnd > -1); } else { // search forward of the old part found iFnd = (int) strFile.find(strPart[i], iFnd+1); bFound = bFound && (bool) (iFnd > -1); } } if (bFound) { // this pattern matched the file, add to vector // NB: first get stat to make sure it really is a file strFullPath = strUserDir + strFile; // only add if the file really exists (i.e. not a directory) if (is_file(strFullPath.c_str())) { pList->push_back(strFullPath); } } } // sort by file creation time if (pList->size()>1) { // sort if list is greather than 1 std::sort(pList->begin(), pList->end(), StringVectorSort); // may as well sort it? } return true; } const char *BOINC_RCSID_bdf38b2dfb = "$Id$";