// This file is part of BOINC. // http://boinc.berkeley.edu // Copyright (C) 2019 University of California // // BOINC is free software; you can redistribute it and/or modify it // under the terms of the GNU Lesser General Public License // as published by the Free Software Foundation, // either version 3 of the License, or (at your option) any later version. // // BOINC is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // See the GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with BOINC. If not, see . #if defined(_WIN32) && !defined(__STDWX_H__) #pragma warning( disable : 4786 ) // Disable warning messages for vector #include "boinc_win.h" #elif defined(_WIN32) && defined(__STDWX_H__) #include "stdwx.h" #else #ifndef __APPLE_CC__ #include "config.h" #endif #include #include #include using std::string; #endif #ifdef __cplusplus extern "C" { #else extern { #endif int unzip(int argc, char** argv); //int zipmain(int argc, char** argv); #include "./unzip/unzip.h" #include "./zip/zip.h" } #include "boinc_zip.h" #include "filesys.h" // from BOINC for DirScan // 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); } // same, but with char[] instead of string // int boinc_zip(int bZipType, const char* szFileZip, const char* szFileIn) { 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+1, sizeof(char*)); for (i=0;i<(carg+1);i++) { av[i] = (char*) calloc(_MAX_PATH,sizeof(char)); } // just form an argc/argv to spoof the "main" // default options are to recurse into directories //if (options && strlen(options)) // strcpy(av[1], options); if (bZipType == ZIP_IT) { strcpy(av[0], "zip"); // default zip options -- no dir names, no subdirs, highest compression, quiet mode if (strlen(av[1])==0) { strcpy(av[1], "-j9q"); } strcpy(av[2], szFileZip.c_str()); //sz 3 onward will be each vector int jj; for (jj=0; jjat(jj).c_str()); } } else { strcpy(av[0], "unzip"); // default unzip options -- preserve subdirs, overwrite if (strlen(av[1])==0) { strcpy(av[1], "-oq"); } 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()); } } av[carg] = NULL; // 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 = zipmain(carg, av); } else { // make sure zip file exists if (access(szFileZip.c_str(), 0) == 0) { iRet = UzpMain(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 filename 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 // sort if list is greather than 1 if (pList->size()>1) { sort(pList->begin(), pList->end(), StringVectorSort); // may as well sort it? } return true; } // Read compressed file to memory. // int boinc_UnzipToMemory (char *zip, char *file, string &retstr) { UzpOpts opts; // options for UzpUnzipToMemory() UzpCB funcs; // function pointers for UzpUnzipToMemory() UzpBuffer buf; int ret; memset(&opts, 0, sizeof(opts)); memset(&funcs, 0, sizeof(funcs)); funcs.structlen = sizeof(UzpCB); funcs.msgfn = (MsgFn *)printf; funcs.inputfn = (InputFn *)scanf; funcs.pausefn = (PauseFn *)(0x01); funcs.passwdfn = (PasswdFn *)(NULL); memset(&buf, 0, sizeof(buf)); // data-blocks needs to be empty ret = UzpUnzipToMemory(zip, file, &opts, &funcs, &buf); if (ret) { retstr = (string) buf.strptr; } if (buf.strptr) free (buf.strptr); return ret; }