void CArchiveScanner::ScanDirs(const std::vector<std::string>& scanDirs) { std::lock_guard<spring::recursive_mutex> lck(scannerMutex); std::deque<std::string> foundArchives; isDirty = true; // scan for all archives for (const std::string& dir: scanDirs) { if (FileSystem::DirExists(dir)) { LOG("Scanning: %s", dir.c_str()); ScanDir(dir, foundArchives); } } // check for duplicates reached by links //XXX too slow also ScanArchive() skips duplicates itself, too /*for (auto it = foundArchives.begin(); it != foundArchives.end(); ++it) { auto jt = it; ++jt; while (jt != foundArchives.end()) { std::string f1 = StringToLower(FileSystem::GetFilename(*it)); std::string f2 = StringToLower(FileSystem::GetFilename(*jt)); if ((f1 == f2) || FileSystem::ComparePaths(*it, *jt)) { jt = foundArchives.erase(jt); } else { ++jt; } } }*/ // Create archiveInfos etc. if not in cache already for (const std::string& archive: foundArchives) { ScanArchive(archive, false); #if !defined(DEDICATED) && !defined(UNITSYNC) Watchdog::ClearTimer(WDT_MAIN); #endif } // Now we'll have to parse the replaces-stuff found in the mods for (auto& aii: archiveInfos) { for (const std::string& replaceName: aii.second.archiveData.GetReplaces()) { // Overwrite the info for this archive with a replaced pointer const std::string& lcname = StringToLower(replaceName); ArchiveInfo& ai = archiveInfos[lcname]; ai.path = ""; ai.origName = lcname; ai.modified = 1; ai.archiveData = ArchiveData(); ai.updated = true; ai.replaced = aii.first; } } }
void CArchiveScanner::Scan(const std::string& curPath, bool doChecksum) { isDirty = true; const int flags = (FileSystem::INCLUDE_DIRS | FileSystem::RECURSE); const std::vector<std::string> &found = filesystem.FindFiles(curPath, "*", flags); for (std::vector<std::string>::const_iterator it = found.begin(); it != found.end(); ++it) { std::string fullName = *it; // Strip const char lastFullChar = fullName[fullName.size() - 1]; if ((lastFullChar == '/') || (lastFullChar == '\\')) { fullName = fullName.substr(0, fullName.size() - 1); } const std::string fpath = filesystem.GetDirectory(fullName); const std::string lcfpath = StringToLower(fpath); // Exclude archivefiles found inside directory archives (.sdd) if (lcfpath.find(".sdd") != std::string::npos) { continue; } // Exclude archivefiles found inside hidden directories if ((lcfpath.find("/hidden/") != std::string::npos) || (lcfpath.find("\\hidden\\") != std::string::npos)) { continue; } // Is this an archive we should look into? if (CArchiveFactory::IsScanArchive(fullName)) { ScanArchive(fullName, doChecksum); } } // Now we'll have to parse the replaces-stuff found in the mods for (std::map<std::string, ArchiveInfo>::iterator aii = archiveInfo.begin(); aii != archiveInfo.end(); ++aii) { for (std::vector<std::string>::const_iterator i = aii->second.archiveData.GetReplaces().begin(); i != aii->second.archiveData.GetReplaces().end(); ++i) { const std::string lcname = StringToLower(*i); std::map<std::string, ArchiveInfo>::iterator ar = archiveInfo.find(lcname); // If it's not there, we will create a new entry if (ar == archiveInfo.end()) { ArchiveInfo tmp; archiveInfo[lcname] = tmp; ar = archiveInfo.find(lcname); } // Overwrite the info for this archive with a replaced pointer ar->second.path = ""; ar->second.origName = lcname; ar->second.modified = 1; ArchiveData empty; ar->second.archiveData = empty; ar->second.updated = true; ar->second.replaced = aii->first; } } }
/* * Upload a file. */ int Upload() { int Area, rc; unsigned int OldArea; char *arc, *temp; up_list *up = NULL, *tmpf; WhosDoingWhat(UPLOAD, NULL); Enter(1); Area = OldArea = iAreaNumber; /* * If there is a special upload area for the current area * then select it. */ if (area.Upload) Area = area.Upload; SetFileArea(Area); Syslog('+', "Upload area is %d %s", Area, area.Name); /* * Check upload access for the real upload directory. */ if (!Access(exitinfo.Security, area.UPSec)) { Enter(1); /* You do not have enough access to upload to this area */ pout(CFG.HiliteF, CFG.HiliteB, (char *) Language(278)); Enter(2); SetFileArea(OldArea); Pause(); return 0; } clear(); Enter(2); rc = upload(&up); if (rc) { Syslog('+', "Upload failed, rc=%d", rc); SetFileArea(OldArea); return 0; } Syslog('b', "upload done, start checks"); Enter(2); pout(CFG.UnderlineColourF, CFG.UnderlineColourB, (char *)"Checking your upload(s)"); Enter(1); temp = calloc(PATH_MAX, sizeof(char)); for (tmpf = up; tmpf; tmpf = tmpf->next) { snprintf(temp, PATH_MAX, "%s/%s/upl", CFG.bbs_usersdir, exitinfo.Name); chdir(temp); Syslog('b', "Checking upload %s", tmpf->filename); if ((arc = GetFileType(tmpf->filename)) == NULL) { /* * If the filetype is unknown, it is probably * a textfile or so. Import it direct. */ Syslog('b', "Unknown file type"); if (!ScanDirect(basename(tmpf->filename))) ImportFile(tmpf->filename, Area, FALSE, tmpf->size); } else { /* * We figured out the type of the uploaded file. */ Syslog('b', "File type is %s", arc); /* * MS-DOS executables are handled direct. */ if ((strcmp("EXE", arc) == 0) || (strcmp("COM", arc) == 0)) { if (!ScanDirect(basename(tmpf->filename))) ImportFile(tmpf->filename, Area, FALSE, tmpf->size); } else { switch (ScanArchive(basename(tmpf->filename), arc)) { case 0: ImportFile(tmpf->filename, Area, TRUE, tmpf->size); break; case 1: break; case 2: break; case 3: /* * No valid unarchiver found, just import after scanning, * may catch macro viri. */ if (!ScanDirect(basename(tmpf->filename))) ImportFile(tmpf->filename, Area, FALSE, tmpf->size); break; } } } } tidy_upload(&up); free(temp); Home(); SetFileArea(OldArea); Pause(); return 1; }
/* * Function will upload to users home directory */ int Upload_Home() { char *temp, *arc; int rc = 0, Count = 0; up_list *up = NULL, *tmpf; WhosDoingWhat(UPLOAD, NULL); temp = calloc(PATH_MAX, sizeof(char)); clear(); Enter(2); rc = upload(&up); if (rc) { Syslog('+', "Upload home failed, rc=%d", rc); Home(); return 1; } Syslog('b', "Start checking uploaded files"); Enter(2); pout(CFG.UnderlineColourF, CFG.UnderlineColourB, (char *)"Checking your upload(s)"); Enter(2); for (tmpf = up; tmpf; tmpf = tmpf->next) { snprintf(temp, PATH_MAX, "%s/%s/upl", CFG.bbs_usersdir, exitinfo.Name); chdir(temp); Syslog('b', "Checking upload %s", tmpf->filename); if ((arc = GetFileType(tmpf->filename)) == NULL) { /* * If the filetype is unknown, it is probably * a textfile or so. Import it direct. */ Syslog('b', "Unknown file type"); ImportHome(basename(tmpf->filename)); Count++; } else { /* * We figured out the type of the uploaded file. */ Syslog('b', "File type is %s", arc); /* * MS-DOS executables are handled direct. */ if ((strcmp("EXE", arc) == 0) || (strcmp("COM", arc) == 0)) { if (!ScanDirect(basename(tmpf->filename))) { ImportHome(basename(tmpf->filename)); Count++; } } else { switch(ScanArchive(basename(tmpf->filename), arc)) { case 0: ImportHome(basename(tmpf->filename)); Count++; break; case 1: break; case 2: break; case 3: /* * No valid unarchiver found, just import */ ImportHome(basename(tmpf->filename)); Count++; break; } } } } Home(); ReadExitinfo(); exitinfo.Uploads += Count; mib_uploads += Count; WriteExitinfo(); tidy_upload(&up); Pause(); free(temp); return rc; }
void CArchiveScanner::ComputeChecksumForArchive(const std::string& filePath) { ScanArchive(filePath, true); }