// Returns the size of filename (64bit) u64 GetSize(const std::string &filename) { struct stat64 file_info; #if defined(_WIN32) && defined(UNICODE) int result = _wstat64(ConvertUTF8ToWString(filename).c_str(), &file_info); #else int result = stat64(filename.c_str(), &file_info); #endif if (result != 0) { WARN_LOG(COMMON, "GetSize: failed %s: No such file", filename.c_str()); return 0; } if (IsDirectory(file_info)) { WARN_LOG(COMMON, "GetSize: failed %s: is a directory", filename.c_str()); return 0; } DEBUG_LOG(COMMON, "GetSize: %s: %lld", filename.c_str(), (long long)file_info.st_size); return file_info.st_size; }
/* * Look up an Internet e-mail address in the directory. * On success: returns 0, and Citadel address stored in 'target' * On failure: returns nonzero */ int CtdlDirectoryLookup(char *target, char *internet_addr, size_t targbuflen) { struct cdbdata *cdbrec; char key[SIZ]; /* Dump it in there unchanged, just for kicks */ safestrncpy(target, internet_addr, targbuflen); /* Only do lookups for addresses with hostnames in them */ if (num_tokens(internet_addr, '@') != 2) return(-1); /* Only do lookups for domains in the directory */ if (IsDirectory(internet_addr, 0) == 0) return(-1); directory_key(key, internet_addr); cdbrec = cdb_fetch(CDB_DIRECTORY, key, strlen(key) ); if (cdbrec != NULL) { safestrncpy(target, cdbrec->ptr, targbuflen); cdb_free(cdbrec); return(0); } return(-1); }
// Create directory and copy contents (does not overwrite existing files) void CopyDir(const std::string &source_path, const std::string &dest_path) { #ifndef _WIN32 if (source_path == dest_path) return; if (!File::Exists(source_path)) return; if (!File::Exists(dest_path)) File::CreateFullPath(dest_path); struct dirent_large { struct dirent entry; char padding[FILENAME_MAX+1]; }; struct dirent_large diren; struct dirent *result = NULL; DIR *dirp = opendir(source_path.c_str()); if (!dirp) return; while (!readdir_r(dirp, (dirent*) &diren, &result) && result) { const std::string virtualName(result->d_name); // check for "." and ".." if (((virtualName[0] == '.') && (virtualName[1] == '\0')) || ((virtualName[0] == '.') && (virtualName[1] == '.') && (virtualName[2] == '\0'))) continue; std::string source, dest; source = source_path + virtualName; dest = dest_path + virtualName; if (IsDirectory(source)) { source += '/'; dest += '/'; if (!File::Exists(dest)) File::CreateFullPath(dest); CopyDir(source, dest); } else if (!File::Exists(dest)) File::Copy(source, dest); } closedir(dirp); #endif }
// Create directory and copy contents (does not overwrite existing files) void CopyDir(const std::string &source_path, const std::string &dest_path) { #ifndef _WIN32 if (source_path == dest_path) return; if (!File::Exists(source_path)) return; if (!File::Exists(dest_path)) File::CreateFullPath(dest_path); struct dirent *result = NULL; DIR *dirp = opendir(source_path.c_str()); if (!dirp) return; while ((result = readdir(dirp))) { const std::string virtualName(result->d_name); // check for "." and ".." if (((virtualName[0] == '.') && (virtualName[1] == '\0')) || ((virtualName[0] == '.') && (virtualName[1] == '.') && (virtualName[2] == '\0'))) continue; std::string source, dest; source = source_path + virtualName; dest = dest_path + virtualName; if (IsDirectory(source)) { source += '/'; dest += '/'; if (!File::Exists(dest)) File::CreateFullPath(dest); CopyDir(source, dest); } else if (!File::Exists(dest)) File::Copy(source, dest); } closedir(dirp); #else ERROR_LOG(COMMON, "CopyDir not supported on this platform"); #endif }
void UserTable::GetDirectoryTree(const std::string& sPath, TPathList& rResults) { struct dirent* ent; DIR* dir; dir = opendir(sPath.c_str()); if (!dir) { syslog(LOG_WARNING, "could not open directory %s: %s", sPath.c_str(), strerror(errno)); return; } rResults.push_back(sPath); ent = readdir(dir); while (ent) { std::string sFullPath = sPath + "/" + ent->d_name; std::string sEntry(ent->d_name); if ("." != sEntry && ".." != sEntry && IsDirectory(sFullPath)) { GetDirectoryTree(sFullPath, rResults); } ent = readdir(dir); } closedir(dir); }
/* Removes a single directory passed in. Returns true on success, false on failure. On a failure, errno will be set (but may be of dubious quality) and an error logged. If the path does not exist, return immediately as success. if the path exists, but is not a directory, the behavior is currently to return immediately as success, but in the future might fail with errno==ENOTDIR. This assumes that the top level directory requires an euid of condor to remove. */ static bool remove_spool_directory(const char * dir) { if ( ! IsDirectory(dir) ) { return true; } Directory spool_dir(dir); if( ! spool_dir.Remove_Entire_Directory() ) { dprintf(D_ALWAYS,"Failed to remove %s\n", dir); errno = EPERM; // Wild guess. return false; } TemporaryPrivSentry tps(PRIV_CONDOR); if( rmdir(dir) == 0 ) { return true; } // Save errno in case dprintf mangles. int tmp_errno = errno; if( errno != ENOENT ) { dprintf(D_ALWAYS,"Failed to remove %s: %s (errno %d)\n", dir, strerror(errno), errno ); } errno = tmp_errno; return false; }
/*---------------------------------------------------------------------*/ BOOL ValidatePath(CHAR * path, H_ARCHIVE harchive) { _archive[harchive].last_error = ARC_NO_ERROR; _archive_error = ARC_NO_ERROR; /* Check out the path */ if (path == NULL) _archive_error = ARC_BAD_PATH; if (strlen(path) > MAX_PATH_LEN - ARC_PATH_LEN) _archive_error = ARC_BAD_PATH; if (!IsDirectory(path)) _archive_error = ARC_BAD_PATH; if (_archive_error != ARC_NO_ERROR) return (FALSE); /* Fully qualify the path */ QualifyPath(_archive[harchive].path, path); return (TRUE); }
bool CTGitPath::Delete(bool bTrash) const { EnsureBackslashPathSet(); ::SetFileAttributes(m_sBackslashPath, FILE_ATTRIBUTE_NORMAL); bool bRet = false; if (Exists()) { if ((bTrash)||(IsDirectory())) { std::unique_ptr<TCHAR[]> buf(new TCHAR[m_sBackslashPath.GetLength() + 2]); _tcscpy_s(buf.get(), m_sBackslashPath.GetLength() + 2, m_sBackslashPath); buf[m_sBackslashPath.GetLength()] = 0; buf[m_sBackslashPath.GetLength()+1] = 0; bRet = CTGitPathList::DeleteViaShell(buf.get(), bTrash); } else { bRet = !!::DeleteFile(m_sBackslashPath); } } m_bExists = false; m_bExistsKnown = true; return bRet; }
// Creates the full path of fullPath returns true on success bool CreateFullPath(const std::string& fullPath) { int panicCounter = 100; INFO_LOG(COMMON, "CreateFullPath: path %s", fullPath.c_str()); if (Exists(fullPath)) { INFO_LOG(COMMON, "CreateFullPath: path exists %s", fullPath.c_str()); return true; } size_t position = 0; while (true) { // Find next sub path position = fullPath.find(DIR_SEP_CHR, position); // we're done, yay! if (position == fullPath.npos) return true; // Include the '/' so the first call is CreateDir("/") rather than CreateDir("") std::string const subPath(fullPath.substr(0, position + 1)); if (!IsDirectory(subPath)) File::CreateDir(subPath); // A safety check panicCounter--; if (panicCounter <= 0) { ERROR_LOG(COMMON, "CreateFullPath: directory structure is too deep"); return false; } position++; } }
// Deletes a given filename, return true on success // Doesn't supports deleting a directory bool Delete(const std::string &filename) { INFO_LOG(COMMON, "Delete: file %s", filename.c_str()); // Return true because we care about the file no // being there, not the actual delete. if (!Exists(filename)) { WARN_LOG(COMMON, "Delete: %s does not exists", filename.c_str()); return true; } // We can't delete a directory if (IsDirectory(filename)) { WARN_LOG(COMMON, "Delete failed: %s is a directory", filename.c_str()); return false; } #ifdef _WIN32 if (!DeleteFile(ConvertUTF8ToWString(filename).c_str())) { WARN_LOG(COMMON, "Delete: DeleteFile failed on %s: %s", filename.c_str(), GetLastErrorMsg()); return false; } #else if (unlink(filename.c_str()) == -1) { WARN_LOG(COMMON, "Delete: unlink failed on %s: %s", filename.c_str(), GetLastErrorMsg()); return false; } #endif return true; }
//---------------------------------------------------------------------------------------- nsresult nsFileSpec::MoveToDir(const nsFileSpec& inNewParentDirectory) //---------------------------------------------------------------------------------------- { // We can only copy into a directory, and (for now) can not copy entire directories if (inNewParentDirectory.IsDirectory() && (! IsDirectory() ) ) { char *leafname = GetLeafName(); nsSimpleCharString destPath(inNewParentDirectory.GetCString()); destPath += "\\"; destPath += leafname; nsCRT::free(leafname); // MoveFile returns non-zero if succeeds int copyOK = MoveFile(GetCString(), destPath); if (copyOK) { *this = inNewParentDirectory + GetLeafName(); return NS_OK; } } return NS_FILE_FAILURE; } // nsFileSpec::MoveToDir
void InitHomeDir(void) { const std::string & home = Settings::GetHomeDir(); if(! home.empty()) { const std::string home_maps = home + SEPARATOR + std::string("maps"); const std::string home_files = home + SEPARATOR + std::string("files"); const std::string home_files_save = home_files + SEPARATOR + std::string("save"); if(! IsDirectory(home)) MKDIR(home.c_str()); if(IsDirectory(home, true) && ! IsDirectory(home_maps)) MKDIR(home_maps.c_str()); if(IsDirectory(home, true) && ! IsDirectory(home_files)) MKDIR(home_files.c_str()); if(IsDirectory(home_files, true) && ! IsDirectory(home_files_save)) MKDIR(home_files_save.c_str()); } }
// Scans the directory tree gets, starting from _Directory and adds the // results into parentEntry. Returns the number of files+directories found u32 ScanDirectoryTree(const std::string &directory, FSTEntry& parentEntry) { INFO_LOG(COMMON, "ScanDirectoryTree: directory %s", directory.c_str()); // How many files + directories we found u32 foundEntries = 0; #ifdef _WIN32 // Find the first file in the directory. WIN32_FIND_DATA ffd; HANDLE hFind = FindFirstFile(UTF8ToTStr(directory + "\\*").c_str(), &ffd); if (hFind == INVALID_HANDLE_VALUE) { FindClose(hFind); return foundEntries; } // windows loop do { FSTEntry entry; const std::string virtualName(TStrToUTF8(ffd.cFileName)); #else struct dirent dirent, *result = NULL; DIR *dirp = opendir(directory.c_str()); if (!dirp) return 0; // non windows loop while (!readdir_r(dirp, &dirent, &result) && result) { FSTEntry entry; const std::string virtualName(result->d_name); #endif // check for "." and ".." if (((virtualName[0] == '.') && (virtualName[1] == '\0')) || ((virtualName[0] == '.') && (virtualName[1] == '.') && (virtualName[2] == '\0'))) continue; entry.virtualName = virtualName; entry.physicalName = directory; entry.physicalName += DIR_SEP + entry.virtualName; if (IsDirectory(entry.physicalName.c_str())) { entry.isDirectory = true; // is a directory, lets go inside entry.size = ScanDirectoryTree(entry.physicalName, entry); foundEntries += (u32)entry.size; } else { // is a file entry.isDirectory = false; entry.size = GetSize(entry.physicalName.c_str()); } ++foundEntries; // Push into the tree parentEntry.children.push_back(entry); #ifdef _WIN32 } while (FindNextFile(hFind, &ffd) != 0); FindClose(hFind); #else } closedir(dirp); #endif // Return number of entries found. return foundEntries; }
/* * EditFile - read a file into text */ vi_rc EditFile( char *name, bool dammit ) { char *fn, **list, *currfn; int i, cnt, ocnt; int j, len; window_id wn = NO_WINDOW; char cdir[FILENAME_MAX]; info *ci, *il; bool usedir = false; char mask[FILENAME_MAX]; bool reset_dir; int index; char *altname = NULL; vi_rc rc; fn = MemAlloc( FILENAME_MAX ); /* * get file name */ strcpy( cdir, CurrentDirectory ); reset_dir = false; RemoveLeadingSpaces( name ); if( name[0] == '$' ) { EliminateFirstN( name, 1 ); usedir = true; } fn[0] = 0; // if( NextWord1( name, fn ) <= 0 ) if( GetStringWithPossibleQuote2( name, fn, false ) != ERR_NO_ERR ) { usedir = true; mask[0] = '*'; mask[1] = 0; } if( usedir ) { if( EditFlags.ExMode ) { MemFree( fn ); return( ERR_INVALID_IN_EX_MODE ); } len = strlen( fn ); if( len > 0 ) { i = len - 1; strcpy( mask, fn ); cnt = 0; while( i >= 0 ) { if( fn[i] == FILE_SEP ) { for( j = i + 1; j <= len; j++ ) { mask[j - (i + 1)] = fn[j]; } cnt = i; break; } i--; } fn[cnt] = 0; } if( fn[0] != 0 ) { rc = SelectFileOpen( fn, &fn, mask, true ); } else { #ifdef __WIN__ if( name[0] == '\0' ) { altname = MemAlloc( 1000 ); rc = SelectFileOpen( CurrentDirectory, &altname, mask, true ); NextWord1( altname, fn ); // if multiple, kill path if( isMultipleFiles( altname ) ) { NextWord1( altname, fn ); // get 1st name } } else { rc = SelectFileOpen( CurrentDirectory, &fn, mask, true ); } #else rc = SelectFileOpen( CurrentDirectory, &fn, mask, true ); #endif } if( altname ) { name = altname; } if( rc != ERR_NO_ERR || fn[0] == 0 ) { MemFree( fn ); SetCWD( cdir ); return( rc ); } } /* * loop through all files */ rc = ERR_NO_ERR; EditFlags.WatchForBreak = true; #ifdef __WIN__ ToggleHourglass( true ); #endif do { if( IsDirectory( fn ) ) { if( EditFlags.ExMode ) { rc = ERR_INVALID_IN_EX_MODE; reset_dir = true; break; } rc = SelectFileOpen( fn, &fn, "*", false ); if( rc != ERR_NO_ERR ) { reset_dir = true; break; } if( fn[0] == 0 ) { reset_dir = true; rc = ERR_NO_ERR; break; } } currfn = fn; ocnt = cnt = ExpandFileNames( currfn, &list ); if( !cnt ) { cnt = 1; } else { currfn = list[0]; } /* * loop through all expanded files */ index = 1; while( cnt > 0 ) { cnt--; /* * quit current file if ! specified, else just save current state */ if( dammit ) { ci = InfoHead; if( CurrentInfo == ci ) { ci = ci->next; } RemoveFromAutoSaveList(); #ifdef __WIN__ CloseAChildWindow( CurrentWindow ); #else CloseAWindow( CurrentWindow ); #endif FreeUndoStacks(); FreeMarkList(); FreeEntireFile( CurrentFile ); MemFree( DeleteLLItem( (ss **)&InfoHead, (ss **)&InfoTail, (ss *)CurrentInfo ) ); CurrentInfo = NULL; CurrentWindow = NO_WINDOW; } else { ci = CurrentInfo; SaveCurrentInfo(); wn = CurrentWindow; } /* * see if new file is already being edited */ SaveCurrentInfo(); for( il = InfoHead; il != NULL; il = il->next ) { if( SameFile( il->CurrentFile->name, currfn ) ) { break; } if( strcmp( CurrentDirectory, il->CurrentFile->home ) ) { /* directory has changed -- check with full path * note that this will fail if an absolute path * was specified thus we do the regular check first */ char path[FILENAME_MAX]; char drive[_MAX_DRIVE]; char dir[_MAX_DIR]; char fname[_MAX_FNAME]; char ext[_MAX_EXT]; _splitpath( il->CurrentFile->name, drive, dir, fname, ext ); if( !strlen( drive ) ) { _splitpath( il->CurrentFile->home, drive, NULL, NULL, NULL ); } if( !strlen( dir ) ) { _splitpath( il->CurrentFile->home, NULL, dir, NULL, NULL ); } else if( dir[0] != '\\' ) { char dir2[_MAX_DIR]; _splitpath( il->CurrentFile->home, NULL, dir2, NULL, NULL ); strcat( dir2, dir ); strcpy( dir, dir2 ); } _makepath( path, drive, dir, fname, ext ); if( SameFile( path, currfn ) ) { break; } } } if( il != NULL ) { BringUpFile( il, true ); } else { /* * file not edited, go get it */ rc = NewFile( currfn, false ); if( rc != ERR_NO_ERR && rc != NEW_FILE ) { RestoreInfo( ci ); DCDisplayAllLines(); break; } if( !dammit ) { InactiveWindow( wn ); } if( EditFlags.BreakPressed ) { break; } } if( cnt > 0 ) { currfn = list[index]; index++; } } if( ocnt > 0 ) { MemFreeList( ocnt, list ); } if( EditFlags.BreakPressed ) { ClearBreak(); break; } } while( NextWord1( name, fn ) > 0 ); if( altname ) { MemFree( altname ); } MemFree( fn ); #ifdef __WIN__ ToggleHourglass( false ); #endif EditFlags.WatchForBreak = false; if( reset_dir ) { SetCWD( cdir ); } return( rc ); } /* EditFile */
}; //============================================================================ // Test case //---------------------------------------------------------------------------- TEST_NFILEUTILITIES("Directories") { // Perform the test theFile = NFileUtilities::GetDirectory(kNLocationHome); REQUIRE(theFile.IsDirectory()); theFile = NFileUtilities::GetDirectory(kNLocationDesktop); REQUIRE(theFile.IsDirectory()); theFile = NFileUtilities::GetDirectory(kNLocationPreferences); REQUIRE(theFile.IsDirectory()); theFile = NFileUtilities::GetCWD(); REQUIRE(theFile.IsDirectory()); }
int CompletePath(const char *Base, char *Match, int Count) { char Name[MAXPATH]; const char *dirp; char *namep; int len, count = 0; char cname[MAXPATH]; int hascname = 0; RxMatchRes RM; FileFind *ff; FileInfo *fi; int rc; if (strcmp(Base, "") == 0) { if (ExpandPath(".", Name, sizeof(Name)) != 0) return -1; } else { if (ExpandPath(Base, Name, sizeof(Name)) != 0) return -1; } // SlashDir(Name); dirp = Name; namep = SepRChr(Name); if (namep == Name) { dirp = SSLASH; namep = Name + 1; } else if (namep == NULL) { namep = Name; dirp = SDOT; } else { *namep = 0; namep++; } len = strlen(namep); strcpy(Match, dirp); SlashDir(Match); cname[0] = 0; ff = new FileFind(dirp, "*", ffDIRECTORY | ffHIDDEN #if defined(USE_DIRENT) | ffFAST // for SPEED #endif ); if (ff == 0) return 0; rc = ff->FindFirst(&fi); while (rc == 0) { const char *dname = fi->Name(); // filter out unwanted files if ((strcmp(dname, ".") != 0) && (strcmp(dname, "..") != 0) && (!CompletionFilter || RxExec(CompletionFilter, dname, strlen(dname), dname, &RM) != 1)) { if (( #if defined(UNIX) strncmp #else // os2, nt, ... strnicmp #endif (namep, dname, len) == 0) && (dname[0] != '.' || namep[0] == '.')) { count++; if (Count == count) { Slash(Match, 1); strcat(Match, dname); if ( #if defined(USE_DIRENT) // for SPEED IsDirectory(Match) #else fi->Type() == fiDIRECTORY #endif ) Slash(Match, 1); } else if (Count == -1) { if (!hascname) { strcpy(cname, dname); hascname = 1; } else { int o = 0; #ifdef UNIX while (cname[o] && dname[o] && (cname[o] == dname[o])) o++; #endif #if defined(OS2) || defined(NT) while (cname[o] && dname[o] && (toupper(cname[o]) == toupper(dname[o]))) o++; #endif cname[o] = 0; } } } } delete fi; rc = ff->FindNext(&fi); } delete ff; if (Count == -1) { Slash(Match, 1); strcat(Match, cname); if (count == 1) SlashDir(Match); } return count; }
FileList::FileList(const FilePath & filepath) { DVASSERT(filepath.IsDirectoryPathname()); path = filepath; // Windows version #if defined(__DAVAENGINE_WIN32__) //char tmp[_MAX_PATH]; //_getcwd(tmp, _MAX_PATH); //Path = tmp; FilePath prevDir = FileSystem::Instance()->GetCurrentWorkingDirectory(); BOOL res = SetCurrentDirectoryA(path.GetAbsolutePathname().c_str()); if (res) { struct _finddata_t c_file; intptr_t hFile; FileEntry entry; if( (hFile = _findfirst( "*", &c_file )) != -1L ) { do { //TODO: need to check for Win32 entry.path = filepath + c_file.name; entry.name = c_file.name; entry.size = c_file.size; entry.isDirectory = (_A_SUBDIR & c_file.attrib) != 0; if(entry.isDirectory) { entry.path.MakeDirectoryPathname(); } fileList.push_back(entry); //Logger::FrameworkDebug("filelist: %s %s", filepath.c_str(), entry.name.c_str()); } while( _findnext( hFile, &c_file ) == 0 ); _findclose( hFile ); } } FileSystem::Instance()->SetCurrentWorkingDirectory(prevDir); //TODO add drives //entry.Name = "E:\\"; //entry.isDirectory = true; //Files.push_back(entry); #elif defined(__DAVAENGINE_MACOS__) || defined(__DAVAENGINE_IPHONE__) || defined (__DAVAENGINE_ANDROID__) struct dirent **namelist; FileEntry entry; #if defined (__DAVAENGINE_ANDROID__) int32 n = scandir(path.GetAbsolutePathname().c_str(), &namelist, 0, alphasortAndroid); #else //#if defined (__DAVAENGINE_ANDROID__) int32 n = scandir(path.GetAbsolutePathname().c_str(), &namelist, 0, alphasort); #endif //#if defined (__DAVAENGINE_ANDROID__) if (n >= 0) { while(n--) { entry.path = path + namelist[n]->d_name; entry.name = namelist[n]->d_name; entry.size = 0; entry.isDirectory = namelist[n]->d_type == DT_DIR; if(entry.isDirectory) { entry.path.MakeDirectoryPathname(); } fileList.push_back(entry); free(namelist[n]); } free(namelist); } #endif //PLATFORMS directoryCount = 0; fileCount = 0; for (int fi = 0; fi < GetCount(); ++fi) { if (IsDirectory(fi)) { if (!IsNavigationDirectory(fi)) directoryCount++; }else fileCount++; } }
int VanillaProc::StartJob() { dprintf(D_FULLDEBUG,"in VanillaProc::StartJob()\n"); // vanilla jobs, unlike standard jobs, are allowed to run // shell scripts (or as is the case on NT, batch files). so // edit the ad so we start up a shell, pass the executable as // an argument to the shell, if we are asked to run a .bat file. #ifdef WIN32 CHAR interpreter[MAX_PATH+1], systemshell[MAX_PATH+1]; const char* jobtmp = Starter->jic->origJobName(); int joblen = strlen(jobtmp); const char *extension = joblen > 0 ? &(jobtmp[joblen-4]) : NULL; bool binary_executable = ( extension && ( MATCH == strcasecmp ( ".exe", extension ) || MATCH == strcasecmp ( ".com", extension ) ) ), java_universe = ( CONDOR_UNIVERSE_JAVA == job_universe ); ArgList arguments; MyString filename, jobname, error; if ( extension && !java_universe && !binary_executable ) { /** since we do not actually know how long the extension of the file is, we'll need to hunt down the '.' in the path, if it exists */ extension = strrchr ( jobtmp, '.' ); if ( !extension ) { dprintf ( D_ALWAYS, "VanillaProc::StartJob(): Failed to extract " "the file's extension.\n" ); /** don't fail here, since we want executables to run as usual. That is, some condor jobs submit executables that do not have the '.exe' extension, but are, nonetheless, executable binaries. For instance, a submit script may contain: executable = executable$(OPSYS) */ } else { /** pull out the path to the executable */ if ( !JobAd->LookupString ( ATTR_JOB_CMD, jobname ) ) { /** fall back on Starter->jic->origJobName() */ jobname = jobtmp; } /** If we transferred the job, it may have been renamed to condor_exec.exe even though it is not an executable. Here we rename it back to a the correct extension before it will run. */ if ( MATCH == strcasecmp ( CONDOR_EXEC, condor_basename ( jobname.Value () ) ) ) { filename.formatstr ( "condor_exec%s", extension ); if (rename(CONDOR_EXEC, filename.Value()) != 0) { dprintf (D_ALWAYS, "VanillaProc::StartJob(): ERROR: " "failed to rename executable from %s to %s\n", CONDOR_EXEC, filename.Value() ); } } else { filename = jobname; } /** Since we've renamed our executable, we need to update the job ad to reflect this change. */ if ( !JobAd->Assign ( ATTR_JOB_CMD, filename ) ) { dprintf ( D_ALWAYS, "VanillaProc::StartJob(): ERROR: failed to " "set new executable name.\n" ); return FALSE; } /** We've moved the script to argv[1], so we need to add the remaining arguments to positions argv[2].. argv[/n/]. */ if ( !arguments.AppendArgsFromClassAd ( JobAd, &error ) || !arguments.InsertArgsIntoClassAd ( JobAd, NULL, &error ) ) { dprintf ( D_ALWAYS, "VanillaProc::StartJob(): ERROR: failed to " "get arguments from job ad: %s\n", error.Value () ); return FALSE; } /** Since we know already we don't want this file returned to us, we explicitly add it to an exception list which will stop the file transfer mechanism from considering it for transfer back to its submitter */ Starter->jic->removeFromOutputFiles ( filename.Value () ); } } #endif // set up a FamilyInfo structure to tell OsProc to register a family // with the ProcD in its call to DaemonCore::Create_Process // FamilyInfo fi; // take snapshots at no more than 15 seconds in between, by default // fi.max_snapshot_interval = param_integer("PID_SNAPSHOT_INTERVAL", 15); m_dedicated_account = Starter->jic->getExecuteAccountIsDedicated(); if( ThisProcRunsAlongsideMainProc() ) { // If we track a secondary proc's family tree (such as // sshd) using the same dedicated account as the job's // family tree, we could end up killing the job when we // clean up the secondary family. m_dedicated_account = NULL; } if (m_dedicated_account) { // using login-based family tracking fi.login = m_dedicated_account; // The following message is documented in the manual as the // way to tell whether the dedicated execution account // configuration is being used. dprintf(D_ALWAYS, "Tracking process family by login \"%s\"\n", fi.login); } FilesystemRemap * fs_remap = NULL; #if defined(LINUX) // on Linux, we also have the ability to track processes via // a phony supplementary group ID // gid_t tracking_gid = 0; if (param_boolean("USE_GID_PROCESS_TRACKING", false)) { if (!can_switch_ids() && (Starter->condorPrivSepHelper() == NULL)) { EXCEPT("USE_GID_PROCESS_TRACKING enabled, but can't modify " "the group list of our children unless running as " "root or using PrivSep"); } fi.group_ptr = &tracking_gid; } #endif #if defined(HAVE_EXT_LIBCGROUP) // Determine the cgroup std::string cgroup_base; param(cgroup_base, "BASE_CGROUP", ""); MyString cgroup_str; const char *cgroup = NULL; if (cgroup_base.length()) { MyString cgroup_uniq; std::string starter_name, execute_str; param(execute_str, "EXECUTE", "EXECUTE_UNKNOWN"); // Note: Starter is a global variable from os_proc.cpp Starter->jic->machClassAd()->EvalString(ATTR_NAME, NULL, starter_name); ASSERT (starter_name.size()); cgroup_uniq.formatstr("%s_%s", execute_str.c_str(), starter_name.c_str()); const char dir_delim[2] = {DIR_DELIM_CHAR, '\0'}; cgroup_uniq.replaceString(dir_delim, "_"); cgroup_str.formatstr("%s%ccondor%s", cgroup_base.c_str(), DIR_DELIM_CHAR, cgroup_uniq.Value()); cgroup = cgroup_str.Value(); ASSERT (cgroup != NULL); fi.cgroup = cgroup; dprintf(D_FULLDEBUG, "Requesting cgroup %s for job.\n", cgroup); } #endif // The chroot stuff really only works on linux #ifdef LINUX { // Have Condor manage a chroot std::string requested_chroot_name; JobAd->EvalString("RequestedChroot", NULL, requested_chroot_name); const char * allowed_root_dirs = param("NAMED_CHROOT"); if (requested_chroot_name.size()) { dprintf(D_FULLDEBUG, "Checking for chroot: %s\n", requested_chroot_name.c_str()); StringList chroot_list(allowed_root_dirs); chroot_list.rewind(); const char * next_chroot; bool acceptable_chroot = false; std::string requested_chroot; while ( (next_chroot=chroot_list.next()) ) { MyString chroot_spec(next_chroot); chroot_spec.Tokenize(); const char * chroot_name = chroot_spec.GetNextToken("=", false); if (chroot_name == NULL) { dprintf(D_ALWAYS, "Invalid named chroot: %s\n", chroot_spec.Value()); } const char * next_dir = chroot_spec.GetNextToken("=", false); if (chroot_name == NULL) { dprintf(D_ALWAYS, "Invalid named chroot: %s\n", chroot_spec.Value()); } dprintf(D_FULLDEBUG, "Considering directory %s for chroot %s.\n", next_dir, chroot_spec.Value()); if (IsDirectory(next_dir) && chroot_name && (strcmp(requested_chroot_name.c_str(), chroot_name) == 0)) { acceptable_chroot = true; requested_chroot = next_dir; } } // TODO: path to chroot MUST be all root-owned, or we have a nice security exploit. // Is this the responsibility of Condor to check, or the sysadmin who set it up? if (!acceptable_chroot) { return FALSE; } dprintf(D_FULLDEBUG, "Will attempt to set the chroot to %s.\n", requested_chroot.c_str()); std::stringstream ss; std::stringstream ss2; ss2 << Starter->GetExecuteDir() << DIR_DELIM_CHAR << "dir_" << getpid(); std::string execute_dir = ss2.str(); ss << requested_chroot << DIR_DELIM_CHAR << ss2.str(); std::string full_dir_str = ss.str(); if (is_trivial_rootdir(requested_chroot)) { dprintf(D_FULLDEBUG, "Requested a trivial chroot %s; this is a no-op.\n", requested_chroot.c_str()); } else if (IsDirectory(execute_dir.c_str())) { { TemporaryPrivSentry sentry(PRIV_ROOT); if( mkdir(full_dir_str.c_str(), S_IRWXU) < 0 ) { dprintf( D_FAILURE|D_ALWAYS, "Failed to create sandbox directory in chroot (%s): %s\n", full_dir_str.c_str(), strerror(errno) ); return FALSE; } if (chown(full_dir_str.c_str(), get_user_uid(), get_user_gid()) == -1) { EXCEPT("chown error on %s: %s", full_dir_str.c_str(), strerror(errno)); } } if (!fs_remap) { fs_remap = new FilesystemRemap(); } dprintf(D_FULLDEBUG, "Adding mapping: %s -> %s.\n", execute_dir.c_str(), full_dir_str.c_str()); if (fs_remap->AddMapping(execute_dir, full_dir_str)) { // FilesystemRemap object prints out an error message for us. return FALSE; } dprintf(D_FULLDEBUG, "Adding mapping %s -> %s.\n", requested_chroot.c_str(), "/"); std::string root_str("/"); if (fs_remap->AddMapping(requested_chroot, root_str)) { return FALSE; } } else { dprintf(D_ALWAYS, "Unable to do chroot because working dir %s does not exist.\n", execute_dir.c_str()); } } else { dprintf(D_FULLDEBUG, "Value of RequestedChroot is unset.\n"); } } // End of chroot #endif // On Linux kernel 2.4.19 and later, we can give each job its // own FS mounts. char * mount_under_scratch = param("MOUNT_UNDER_SCRATCH"); if (mount_under_scratch) { std::string working_dir = Starter->GetWorkingDir(); if (IsDirectory(working_dir.c_str())) { StringList mount_list(mount_under_scratch); free(mount_under_scratch); mount_list.rewind(); if (!fs_remap) { fs_remap = new FilesystemRemap(); } char * next_dir; while ( (next_dir=mount_list.next()) ) { if (!*next_dir) { // empty string? mount_list.deleteCurrent(); continue; } std::string next_dir_str(next_dir); // Gah, I wish I could throw an exception to clean up these nested if statements. if (IsDirectory(next_dir)) { char * full_dir = dirscat(working_dir, next_dir_str); if (full_dir) { std::string full_dir_str(full_dir); delete [] full_dir; full_dir = NULL; if (!mkdir_and_parents_if_needed( full_dir_str.c_str(), S_IRWXU, PRIV_USER )) { dprintf(D_ALWAYS, "Failed to create scratch directory %s\n", full_dir_str.c_str()); return FALSE; } dprintf(D_FULLDEBUG, "Adding mapping: %s -> %s.\n", full_dir_str.c_str(), next_dir_str.c_str()); if (fs_remap->AddMapping(full_dir_str, next_dir_str)) { // FilesystemRemap object prints out an error message for us. return FALSE; } } else { dprintf(D_ALWAYS, "Unable to concatenate %s and %s.\n", working_dir.c_str(), next_dir_str.c_str()); return FALSE; } } else { dprintf(D_ALWAYS, "Unable to add mapping %s -> %s because %s doesn't exist.\n", working_dir.c_str(), next_dir, next_dir); } } } else { dprintf(D_ALWAYS, "Unable to perform mappings because %s doesn't exist.\n", working_dir.c_str()); return FALSE; } } // have OsProc start the job // int retval = OsProc::StartJob(&fi, fs_remap); if (fs_remap != NULL) { delete fs_remap; } #if defined(HAVE_EXT_LIBCGROUP) // Set fairshare limits. Note that retval == 1 indicates success, 0 is failure. if (cgroup && retval) { std::string mem_limit; param(mem_limit, "MEMORY_LIMIT", "soft"); bool mem_is_soft = mem_limit == "soft"; std::string cgroup_string = cgroup; CgroupLimits climits(cgroup_string); if (mem_is_soft || (mem_limit == "hard")) { ClassAd * MachineAd = Starter->jic->machClassAd(); int MemMb; if (MachineAd->LookupInteger(ATTR_MEMORY, MemMb)) { uint64_t MemMb_big = MemMb; climits.set_memory_limit_bytes(1024*1024*MemMb_big, mem_is_soft); } else { dprintf(D_ALWAYS, "Not setting memory soft limit in cgroup because " "Memory attribute missing in machine ad.\n"); } } else if (mem_limit == "none") { dprintf(D_FULLDEBUG, "Not enforcing memory soft limit.\n"); } else { dprintf(D_ALWAYS, "Invalid value of MEMORY_LIMIT: %s. Ignoring.\n", mem_limit.c_str()); } // Now, set the CPU shares ClassAd * MachineAd = Starter->jic->machClassAd(); int slotWeight; if (MachineAd->LookupInteger(ATTR_SLOT_WEIGHT, slotWeight)) { climits.set_cpu_shares(slotWeight*100); } else { dprintf(D_FULLDEBUG, "Invalid value of SlotWeight in machine ClassAd; ignoring.\n"); } } #endif return retval; }
void recurse_compile( string basedir, vector<string>* files ) { long s_compiled, s_uptodate, s_errors; clock_t start, finish; if ( !IsDirectory( basedir.c_str() ) ) return; s_compiled = s_uptodate = s_errors = 0; start = clock(); for( DirList dl( basedir.c_str() ); !dl.at_end(); dl.next() ) { string name = dl.name(), ext; if (name[0] == '.') continue; string::size_type pos = name.rfind("."); if (pos != string::npos) ext = name.substr(pos); try { if ( pos != string::npos && (!ext.compare(".src") || !ext.compare(".hsr") || (compilercfg.CompileAspPages && !ext.compare(".asp"))) ) { s_compiled++; if (files==NULL) { if (compile_file( (basedir + name).c_str() )) { ++summary.CompiledScripts; } else { ++s_uptodate; ++summary.UpToDateScripts; } } else files->push_back((basedir + name)); } else { recurse_compile( basedir + name + "/", files ); } } catch( std::exception& ) { ++summary.CompiledScripts; ++summary.ScriptsWithCompileErrors; if (!keep_building) throw; s_errors++; } } if (files==NULL) return; finish = clock(); if ( (!quiet || timing_quiet_override) && show_timing_details && s_compiled > 0 && files==NULL) { cout << "Compiled " << s_compiled << " script" << (s_compiled==1?"":"s") << " in " << basedir << " in " << (long)((finish-start)/CLOCKS_PER_SEC) << " second(s)" << endl; if ( s_uptodate > 0 ) cout << " " << s_uptodate << " script" << (s_uptodate==1?" was":"s were") << " already up-to-date." << endl; if ( s_errors > 0 ) cout << " " << s_errors << " script" << (s_errors==1?"":"s") << " had errors." << endl; } }
int main() { int argc; wchar_t **argv = CommandLineToArgvW(GetCommandLineW(), &argc); #else int main(int argc, char *argv[]) { #endif // _WIN32 is_fast = false; is_verbose = false; iterations = 15; depth = 1; max_depth = INT_MAX; #ifdef _WIN32 is_pause = !getenv("PROMPT"); #endif // _WIN32 int i; for (i = 1; i < argc && argv[i][0] == L'-'; i++) { #ifdef _WIN32 // do not pause if any options are given is_pause = false; #endif // _WIN32 int num_optargs = 0; for (int j = 1; argv[i][j]; j++) { switch (argv[i][j]) { case 'f': is_fast = true; break; case 'i': if (i < argc - 1) { iterations = STRTOL(argv[i + ++num_optargs], nullptr, 10); // strtol will return 0 on fail if (iterations == 0) { std::cerr << "There should be a positive number after -i option." << std::endl; PrintInfo(); return 1; } } break; case 'd': if (i < argc - 1) { max_depth = STRTOL(argv[i + ++num_optargs], nullptr, 10); // strtol will return 0 on fail if (max_depth == 0) { std::cerr << "There should be a positive number after -d option." << std::endl; PrintInfo(); return 1; } } break; case 'q': std::cout.setstate(std::ios::failbit); is_verbose = false; break; case 'v': std::cout.clear(); is_verbose = true; break; case '-': if (STRCMP(argv[i] + j + 1, "fastmode") == 0) { j += 7; argv[i][j + 1] = 'f'; } else if (STRCMP(argv[i] + j + 1, "iteration") == 0) { j += 8; argv[i][j + 1] = 'i'; } else if (STRCMP(argv[i] + j + 1, "max_depth") == 0) { j += 8; argv[i][j + 1] = 'd'; } else if (STRCMP(argv[i] + j + 1, "quiet") == 0) { j += 4; argv[i][j + 1] = 'q'; } else if (STRCMP(argv[i] + j + 1, "verbose") == 0) { j += 6; argv[i][j + 1] = 'v'; } else if (STRCMP(argv[i] + j + 1, "keep-exif") == 0) { j += 9; Jpeg::keep_exif = true; } else { #ifdef _WIN32 char mbs[64] = { 0 }; WideCharToMultiByte(CP_ACP, 0, argv[i] + j + 1, -1, mbs, sizeof(mbs) - 1, nullptr, nullptr); std::cerr << "Unknown option: " << mbs << std::endl; #else std::cerr << "Unknown option: " << argv[i] + j + 1 << std::endl; #endif // _WIN32 PrintInfo(); return 1; } break; default: std::cerr << "Unknown option: " << (char)argv[i][j] << std::endl; PrintInfo(); return 1; } } i += num_optargs; } if (i == argc) { std::cerr << "No file path provided." << std::endl; PrintInfo(); return 1; } std::cout << std::fixed; std::cout.precision(2); // support multiple input file do { if (IsDirectory(argv[i])) { // directory TraverseDirectory(argv[i], ProcessFile); } else { // file ProcessFile(argv[i]); } } while (++i < argc); PauseIfNotTerminal(); return 0; }
CString CTSVNPath::GetFilename() const { ATLASSERT(!IsDirectory()); return GetFileOrDirectoryName(); }
int VanillaProc::StartJob() { dprintf(D_FULLDEBUG,"in VanillaProc::StartJob()\n"); // vanilla jobs, unlike standard jobs, are allowed to run // shell scripts (or as is the case on NT, batch files). so // edit the ad so we start up a shell, pass the executable as // an argument to the shell, if we are asked to run a .bat file. #ifdef WIN32 CHAR interpreter[MAX_PATH+1], systemshell[MAX_PATH+1]; const char* jobtmp = Starter->jic->origJobName(); int joblen = strlen(jobtmp); const char *extension = joblen > 0 ? &(jobtmp[joblen-4]) : NULL; bool binary_executable = ( extension && ( MATCH == strcasecmp ( ".exe", extension ) || MATCH == strcasecmp ( ".com", extension ) ) ), java_universe = ( CONDOR_UNIVERSE_JAVA == job_universe ); ArgList arguments; MyString filename, jobname, error; if ( extension && !java_universe && !binary_executable ) { /** since we do not actually know how long the extension of the file is, we'll need to hunt down the '.' in the path, if it exists */ extension = strrchr ( jobtmp, '.' ); if ( !extension ) { dprintf ( D_ALWAYS, "VanillaProc::StartJob(): Failed to extract " "the file's extension.\n" ); /** don't fail here, since we want executables to run as usual. That is, some condor jobs submit executables that do not have the '.exe' extension, but are, nonetheless, executable binaries. For instance, a submit script may contain: executable = executable$(OPSYS) */ } else { /** pull out the path to the executable */ if ( !JobAd->LookupString ( ATTR_JOB_CMD, jobname ) ) { /** fall back on Starter->jic->origJobName() */ jobname = jobtmp; } /** If we transferred the job, it may have been renamed to condor_exec.exe even though it is not an executable. Here we rename it back to a the correct extension before it will run. */ if ( MATCH == strcasecmp ( CONDOR_EXEC, condor_basename ( jobname.Value () ) ) ) { filename.formatstr ( "condor_exec%s", extension ); if (rename(CONDOR_EXEC, filename.Value()) != 0) { dprintf (D_ALWAYS, "VanillaProc::StartJob(): ERROR: " "failed to rename executable from %s to %s\n", CONDOR_EXEC, filename.Value() ); } } else { filename = jobname; } /** Since we've renamed our executable, we need to update the job ad to reflect this change. */ if ( !JobAd->Assign ( ATTR_JOB_CMD, filename ) ) { dprintf ( D_ALWAYS, "VanillaProc::StartJob(): ERROR: failed to " "set new executable name.\n" ); return FALSE; } /** We've moved the script to argv[1], so we need to add the remaining arguments to positions argv[2].. argv[/n/]. */ if ( !arguments.AppendArgsFromClassAd ( JobAd, &error ) || !arguments.InsertArgsIntoClassAd ( JobAd, NULL, &error ) ) { dprintf ( D_ALWAYS, "VanillaProc::StartJob(): ERROR: failed to " "get arguments from job ad: %s\n", error.Value () ); return FALSE; } /** Since we know already we don't want this file returned to us, we explicitly add it to an exception list which will stop the file transfer mechanism from considering it for transfer back to its submitter */ Starter->jic->removeFromOutputFiles ( filename.Value () ); } } #endif // set up a FamilyInfo structure to tell OsProc to register a family // with the ProcD in its call to DaemonCore::Create_Process // FamilyInfo fi; // take snapshots at no more than 15 seconds in between, by default // fi.max_snapshot_interval = param_integer("PID_SNAPSHOT_INTERVAL", 15); m_dedicated_account = Starter->jic->getExecuteAccountIsDedicated(); if( ThisProcRunsAlongsideMainProc() ) { // If we track a secondary proc's family tree (such as // sshd) using the same dedicated account as the job's // family tree, we could end up killing the job when we // clean up the secondary family. m_dedicated_account = NULL; } if (m_dedicated_account) { // using login-based family tracking fi.login = m_dedicated_account; // The following message is documented in the manual as the // way to tell whether the dedicated execution account // configuration is being used. dprintf(D_ALWAYS, "Tracking process family by login \"%s\"\n", fi.login); } FilesystemRemap * fs_remap = NULL; #if defined(LINUX) // on Linux, we also have the ability to track processes via // a phony supplementary group ID // gid_t tracking_gid = 0; if (param_boolean("USE_GID_PROCESS_TRACKING", false)) { if (!can_switch_ids() && (Starter->condorPrivSepHelper() == NULL)) { EXCEPT("USE_GID_PROCESS_TRACKING enabled, but can't modify " "the group list of our children unless running as " "root or using PrivSep"); } fi.group_ptr = &tracking_gid; } // Increase the OOM score of this process; the child will inherit it. // This way, the job will be heavily preferred to be killed over a normal process. // OOM score is currently exponential - a score of 4 is a factor-16 increase in // the OOM score. setupOOMScore(4,800); #endif #if defined(HAVE_EXT_LIBCGROUP) // Determine the cgroup std::string cgroup_base; param(cgroup_base, "BASE_CGROUP", ""); MyString cgroup_str; const char *cgroup = NULL; /* Note on CONDOR_UNIVERSE_LOCAL - The cgroup setup code below * requires a unique name for the cgroup. It relies on * uniqueness of the MachineAd's Name * attribute. Unfortunately, in the local universe the * MachineAd (mach_ad elsewhere) is never populated, because * there is no machine. As a result the ASSERT on * starter_name fails. This means that the local universe * will not work on any machine that has BASE_CGROUP * configured. A potential workaround is to set * STARTER.BASE_CGROUP on any machine that is also running a * schedd, but that disables cgroup support from a * co-resident startd. Instead, I'm disabling cgroup support * from within the local universe until the intraction of * local universe and cgroups can be properly worked * out. -matt 7 nov '12 */ if (CONDOR_UNIVERSE_LOCAL != job_universe && cgroup_base.length()) { MyString cgroup_uniq; std::string starter_name, execute_str; param(execute_str, "EXECUTE", "EXECUTE_UNKNOWN"); // Note: Starter is a global variable from os_proc.cpp Starter->jic->machClassAd()->EvalString(ATTR_NAME, NULL, starter_name); if (starter_name.size() == 0) { char buf[16]; sprintf(buf, "%d", getpid()); starter_name = buf; } //ASSERT (starter_name.size()); cgroup_uniq.formatstr("%s_%s", execute_str.c_str(), starter_name.c_str()); const char dir_delim[2] = {DIR_DELIM_CHAR, '\0'}; cgroup_uniq.replaceString(dir_delim, "_"); cgroup_str.formatstr("%s%ccondor%s", cgroup_base.c_str(), DIR_DELIM_CHAR, cgroup_uniq.Value()); cgroup_str += this->CgroupSuffix(); cgroup = cgroup_str.Value(); ASSERT (cgroup != NULL); fi.cgroup = cgroup; dprintf(D_FULLDEBUG, "Requesting cgroup %s for job.\n", cgroup); } #endif // The chroot stuff really only works on linux #ifdef LINUX { // Have Condor manage a chroot std::string requested_chroot_name; JobAd->EvalString("RequestedChroot", NULL, requested_chroot_name); const char * allowed_root_dirs = param("NAMED_CHROOT"); if (requested_chroot_name.size()) { dprintf(D_FULLDEBUG, "Checking for chroot: %s\n", requested_chroot_name.c_str()); StringList chroot_list(allowed_root_dirs); chroot_list.rewind(); const char * next_chroot; bool acceptable_chroot = false; std::string requested_chroot; while ( (next_chroot=chroot_list.next()) ) { MyString chroot_spec(next_chroot); chroot_spec.Tokenize(); const char * chroot_name = chroot_spec.GetNextToken("=", false); if (chroot_name == NULL) { dprintf(D_ALWAYS, "Invalid named chroot: %s\n", chroot_spec.Value()); } const char * next_dir = chroot_spec.GetNextToken("=", false); if (chroot_name == NULL) { dprintf(D_ALWAYS, "Invalid named chroot: %s\n", chroot_spec.Value()); } dprintf(D_FULLDEBUG, "Considering directory %s for chroot %s.\n", next_dir, chroot_spec.Value()); if (IsDirectory(next_dir) && chroot_name && (strcmp(requested_chroot_name.c_str(), chroot_name) == 0)) { acceptable_chroot = true; requested_chroot = next_dir; } } // TODO: path to chroot MUST be all root-owned, or we have a nice security exploit. // Is this the responsibility of Condor to check, or the sysadmin who set it up? if (!acceptable_chroot) { return FALSE; } dprintf(D_FULLDEBUG, "Will attempt to set the chroot to %s.\n", requested_chroot.c_str()); std::stringstream ss; std::stringstream ss2; ss2 << Starter->GetExecuteDir() << DIR_DELIM_CHAR << "dir_" << getpid(); std::string execute_dir = ss2.str(); ss << requested_chroot << DIR_DELIM_CHAR << ss2.str(); std::string full_dir_str = ss.str(); if (is_trivial_rootdir(requested_chroot)) { dprintf(D_FULLDEBUG, "Requested a trivial chroot %s; this is a no-op.\n", requested_chroot.c_str()); } else if (IsDirectory(execute_dir.c_str())) { { TemporaryPrivSentry sentry(PRIV_ROOT); if( mkdir(full_dir_str.c_str(), S_IRWXU) < 0 ) { dprintf( D_FAILURE|D_ALWAYS, "Failed to create sandbox directory in chroot (%s): %s\n", full_dir_str.c_str(), strerror(errno) ); return FALSE; } if (chown(full_dir_str.c_str(), get_user_uid(), get_user_gid()) == -1) { EXCEPT("chown error on %s: %s", full_dir_str.c_str(), strerror(errno)); } } if (!fs_remap) { fs_remap = new FilesystemRemap(); } dprintf(D_FULLDEBUG, "Adding mapping: %s -> %s.\n", execute_dir.c_str(), full_dir_str.c_str()); if (fs_remap->AddMapping(execute_dir, full_dir_str)) { // FilesystemRemap object prints out an error message for us. return FALSE; } dprintf(D_FULLDEBUG, "Adding mapping %s -> %s.\n", requested_chroot.c_str(), "/"); std::string root_str("/"); if (fs_remap->AddMapping(requested_chroot, root_str)) { return FALSE; } } else { dprintf(D_ALWAYS, "Unable to do chroot because working dir %s does not exist.\n", execute_dir.c_str()); } } else { dprintf(D_FULLDEBUG, "Value of RequestedChroot is unset.\n"); } } // End of chroot #endif // On Linux kernel 2.4.19 and later, we can give each job its // own FS mounts. auto_free_ptr mount_under_scratch(param("MOUNT_UNDER_SCRATCH")); if (mount_under_scratch) { // try evaluating mount_under_scratch as a classad expression, if it is // an expression it must return a string. if it's not an expression, just // use it as a string (as we did before 8.3.6) classad::Value value; if (JobAd->EvaluateExpr(mount_under_scratch.ptr(), value)) { const char * pval = NULL; if (value.IsStringValue(pval)) { mount_under_scratch.set(strdup(pval)); } else { // was an expression, but not a string, so report and error and fail. dprintf(D_ALWAYS | D_ERROR, "ERROR: MOUNT_UNDER_SCRATCH does not evaluate to a string, it is : %s\n", ClassAdValueToString(value)); return FALSE; } } } // if execute dir is encrypted, add /tmp and /var/tmp to mount_under_scratch bool encrypt_execdir = false; JobAd->LookupBool(ATTR_ENCRYPT_EXECUTE_DIRECTORY,encrypt_execdir); if (encrypt_execdir || param_boolean_crufty("ENCRYPT_EXECUTE_DIRECTORY",false)) { // prepend /tmp, /var/tmp to whatever admin wanted. don't worry // if admin already listed /tmp etc - subdirs can appear twice // in this list because AddMapping() ok w/ duplicate entries MyString buf("/tmp,/var/tmp,"); buf += mount_under_scratch.ptr(); mount_under_scratch.set(buf.StrDup()); } if (mount_under_scratch) { std::string working_dir = Starter->GetWorkingDir(); if (IsDirectory(working_dir.c_str())) { StringList mount_list(mount_under_scratch); mount_list.rewind(); if (!fs_remap) { fs_remap = new FilesystemRemap(); } char * next_dir; while ( (next_dir=mount_list.next()) ) { if (!*next_dir) { // empty string? mount_list.deleteCurrent(); continue; } std::string next_dir_str(next_dir); // Gah, I wish I could throw an exception to clean up these nested if statements. if (IsDirectory(next_dir)) { char * full_dir = dirscat(working_dir, next_dir_str); if (full_dir) { std::string full_dir_str(full_dir); delete [] full_dir; full_dir = NULL; if (!mkdir_and_parents_if_needed( full_dir_str.c_str(), S_IRWXU, PRIV_USER )) { dprintf(D_ALWAYS, "Failed to create scratch directory %s\n", full_dir_str.c_str()); delete fs_remap; return FALSE; } dprintf(D_FULLDEBUG, "Adding mapping: %s -> %s.\n", full_dir_str.c_str(), next_dir_str.c_str()); if (fs_remap->AddMapping(full_dir_str, next_dir_str)) { // FilesystemRemap object prints out an error message for us. delete fs_remap; return FALSE; } } else { dprintf(D_ALWAYS, "Unable to concatenate %s and %s.\n", working_dir.c_str(), next_dir_str.c_str()); delete fs_remap; return FALSE; } } else { dprintf(D_ALWAYS, "Unable to add mapping %s -> %s because %s doesn't exist.\n", working_dir.c_str(), next_dir, next_dir); } } } else { dprintf(D_ALWAYS, "Unable to perform mappings because %s doesn't exist.\n", working_dir.c_str()); delete fs_remap; return FALSE; } mount_under_scratch.clear(); } #if defined(LINUX) // On Linux kernel 2.6.24 and later, we can give each // job its own PID namespace if (param_boolean("USE_PID_NAMESPACES", false)) { if (!can_switch_ids()) { EXCEPT("USE_PID_NAMESPACES enabled, but can't perform this " "call in Linux unless running as root."); } fi.want_pid_namespace = this->SupportsPIDNamespace(); if (fi.want_pid_namespace) { if (!fs_remap) { fs_remap = new FilesystemRemap(); } fs_remap->RemapProc(); } // When PID Namespaces are enabled, need to run the job // under the condor_pid_ns_init program, so that signals // propagate through to the child. // First tell the program where to log output status // via an environment variable if (param_boolean("USE_PID_NAMESPACE_INIT", true)) { Env env; MyString env_errors; MyString arg_errors; std::string filename; filename = Starter->GetWorkingDir(); filename += "/.condor_pid_ns_status"; env.MergeFrom(JobAd, &env_errors); env.SetEnv("_CONDOR_PID_NS_INIT_STATUS_FILENAME", filename); env.InsertEnvIntoClassAd(JobAd, &env_errors); Starter->jic->removeFromOutputFiles(condor_basename(filename.c_str())); this->m_pid_ns_status_filename = filename; // Now, set the job's CMD to the wrapper, and shift // over the arguments by one ArgList args; std::string cmd; JobAd->LookupString(ATTR_JOB_CMD, cmd); args.AppendArg(cmd); args.AppendArgsFromClassAd(JobAd, &arg_errors); args.InsertArgsIntoClassAd(JobAd, NULL, & arg_errors); std::string libexec; if( !param(libexec,"LIBEXEC") ) { dprintf(D_ALWAYS, "Cannot find LIBEXEC so can not run condor_pid_ns_init\n"); return 0; } std::string c_p_n_i = libexec + "/condor_pid_ns_init"; JobAd->Assign(ATTR_JOB_CMD, c_p_n_i); } } dprintf(D_FULLDEBUG, "PID namespace option: %s\n", fi.want_pid_namespace ? "true" : "false"); #endif // have OsProc start the job // int retval = OsProc::StartJob(&fi, fs_remap); if (fs_remap != NULL) { delete fs_remap; } #if defined(HAVE_EXT_LIBCGROUP) // Set fairshare limits. Note that retval == 1 indicates success, 0 is failure. // See Note near setup of param(BASE_CGROUP) if (CONDOR_UNIVERSE_LOCAL != job_universe && cgroup && retval) { std::string mem_limit; param(mem_limit, "CGROUP_MEMORY_LIMIT_POLICY", "soft"); bool mem_is_soft = mem_limit == "soft"; std::string cgroup_string = cgroup; CgroupLimits climits(cgroup_string); if (mem_is_soft || (mem_limit == "hard")) { ClassAd * MachineAd = Starter->jic->machClassAd(); int MemMb; if (MachineAd->LookupInteger(ATTR_MEMORY, MemMb)) { uint64_t MemMb_big = MemMb; m_memory_limit = MemMb_big; climits.set_memory_limit_bytes(1024*1024*MemMb_big, mem_is_soft); // Note that ATTR_VIRTUAL_MEMORY on Linux // is sum of memory and swap, in Kilobytes int VMemKb; if (MachineAd->LookupInteger(ATTR_VIRTUAL_MEMORY, VMemKb)) { uint64_t memsw_limit = ((uint64_t)1024) * VMemKb; if (VMemKb > 0) { // we're not allowed to set memsw limit < // the hard memory limit. If we haven't set the hard // memory limit, the default may be infinity. // So, if we've set soft, set hard limit to memsw - one page if (mem_is_soft) { uint64_t hard_limit = memsw_limit - 4096; climits.set_memory_limit_bytes(hard_limit, false); } climits.set_memsw_limit_bytes(memsw_limit); } } else { dprintf(D_ALWAYS, "Not setting virtual memory limit in cgroup because " "Virtual Memory attribute missing in machine ad.\n"); } } else { dprintf(D_ALWAYS, "Not setting memory limit in cgroup because " "Memory attribute missing in machine ad.\n"); } } else if (mem_limit == "none") { dprintf(D_FULLDEBUG, "Not enforcing memory limit.\n"); } else { dprintf(D_ALWAYS, "Invalid value of CGROUP_MEMORY_LIMIT_POLICY: %s. Ignoring.\n", mem_limit.c_str()); } // Now, set the CPU shares ClassAd * MachineAd = Starter->jic->machClassAd(); int numCores = 1; if (MachineAd->LookupInteger(ATTR_CPUS, numCores)) { climits.set_cpu_shares(numCores*100); } else { dprintf(D_FULLDEBUG, "Invalid value of Cpus in machine ClassAd; ignoring.\n"); } setupOOMEvent(cgroup); } m_statistics.Reconfig(); // Now that the job is started, decrease the likelihood that the starter // is killed instead of the job itself. if (retval) { setupOOMScore(0,0); } #endif return retval; }
void find_deps(const string& loc, GLEInterface* iface) { vector<GLEFindEntry*> tofind; vector<string*> result; string gle_paths = ";"; ConfigCollection* collection = iface->getConfig()->getRCFile(); #ifdef __WIN32__ GLEFindEntry* findGLE = new GLEFindEntry(&gle_paths); findGLE->addToFind("gle.exe"); findGLE->addToFind("gle_ps.exe"); tofind.push_back(findGLE); #endif // Create GLEFindEntry for each tool (ghostscript, pdflatex, ...) ConfigSection* tools = collection->getSection(GLE_CONFIG_TOOLS); for (int j = 0; j <= GLE_TOOL_GHOSTSCRIPT_LIB; j++) { CmdLineArgString* strarg = (CmdLineArgString*)tools->getOption(j)->getArg(0); GLEFindEntry* findTool = new GLEFindEntry(strarg->getValuePtr()); char_separator separator(",", ";"); tokenizer<char_separator> tokens(strarg->getDefault(), separator); while (tokens.has_more()) { const string& toolName = tokens.next_token(); if (toolName == ";") { if (tokens.has_more() && strarg->isDefault()) { findTool->setNotFound(tokens.next_token()); } break; } else { if (!IsAbsPath(toolName)) { findTool->addToFind(toolName); } } } if (findTool->getNbFind() != 0) tofind.push_back(findTool); else delete findTool; } // Initialize output and progress indicator GLEOutputStream* output = iface->getOutput(); ostringstream out1; out1 << "Running GLE -finddeps \""; out1 << loc; out1 << ("\" to locate installed software (e.g., Ghostscript and LaTeX): "); output->println(out1.str().c_str()); GLEProgressIndicatorInterface progress(iface); // Perform search at specified location if (loc != "") { if (IsDirectory(loc, true)) { GLEFindFiles(loc, tofind, &progress); for (unsigned int i = 0; i < tofind.size(); i++) { tofind[i]->updateResult(false); } } else { // Name of old GLERC file given if (try_load_config(loc)) { // Override old version number collection->setStringValue(GLE_CONFIG_GLE, GLE_CONFIG_GLE_VERSION, GLEVN); } else { ostringstream err; err << "Can't load configuration from '" << loc << "'" << endl; output->println(err.str().c_str()); } } } #ifdef __UNIX__ // Find programs in search path on Unix GLEFindPrograms(tofind, &progress); #endif #ifdef __MACOS__ // Search for frameworks on Mac GLEFindFiles(string("/Library/Frameworks"), tofind, &progress); string home = GetHomeDir(); if (home != "") { home += "Library/Frameworks"; GLEFindFiles(home, tofind, &progress); } #endif for (unsigned int i = 0; i < tofind.size(); i++) { tofind[i]->updateResult(true); } #ifdef __UNIX__ // Search for libraries in typical directories and in LD_LIBRARY_PATH string gslibloc = GLEFindLibrary("libgs", &progress); if (gslibloc != "") { CmdLineArgString* gslib_stra = (CmdLineArgString*)tools->getOption(GLE_TOOL_GHOSTSCRIPT_LIB)->getArg(0); gslib_stra->setValue(gslibloc.c_str()); } #endif output->println(); // Write installed GLE's to config section ConfigSection* gle = collection->getSection(GLE_CONFIG_GLE); CmdLineArgSPairList* installs = (CmdLineArgSPairList*)gle->getOption(GLE_CONFIG_GLE_INSTALL)->getArg(0); char_separator separator(";", ""); tokenizer<char_separator> tokens(gle_paths, separator); while (tokens.has_more()) { string path = tokens.next_token(); if (path.length() > 0 && !installs->hasValue2(path)) { installs->addPair("?", path); } } // Find versions of installed GLEs and set value of gleexe ostringstream out; string gle_version = GLEVN; if (installs->size() > 1) { // Only need to find out versions if more than one installed // otherwise assume it is "this" version for (int i = 0; i < installs->size(); i++) { const string& cr_gle = installs->getValue2(i); string& version = installs->getValue1(i); if (version == "?") { get_version_soft(cr_gle, version); if (version == "?") { // cout << "Use hard method for: " << cr_gle << endl; get_version_hard(cr_gle, version); } } if (str_i_equals(version, gle_version)) { out << "Found: GLE " << version << " in " << cr_gle << " (*)" << endl; } else { out << "Found: GLE " << version << " in " << cr_gle << endl; } } } else if (installs->size() == 1) { out << "Found: GLE in " << installs->getValue2(0) << endl; // Do not need to remember installed GLEs if there is only one // because then the "-v" option makes no sense installs->reset(); } // Show locations of other tools for (int j = 0; j <= GLE_TOOL_GHOSTSCRIPT_LIB; j++) { CmdLineOption* opt = tools->getOption(j); CmdLineArgString* strarg = (CmdLineArgString*)opt->getArg(0); if (strarg->isDefault()) { out << "Found: " << opt->getName() << " in '?'" << endl; } else { out << "Found: " << opt->getName() << " in '" << strarg->getValue() << "'" << endl; } } output->println(out.str().c_str()); for (unsigned int i = 0; i < tofind.size(); i++) { delete tofind[i]; } }
/* Determine where data folder is situated and store it's path into DataFolder member */ void CSettings::FindDataFolder() { AppParams* params = AppParams::instance(); if (IsDirectory(WinUtils::GetAppFolder() + _T("Data"))) { DataFolder = WinUtils::GetAppFolder() + _T("Data\\"); SettingsFolder = IuCoreUtils::WstringToUtf8(static_cast<LPCTSTR>(DataFolder)); params->setDataDirectory(IuStringUtils::Replace(IuCoreUtils::WstringToUtf8((LPCTSTR)DataFolder), "\\", "/")); params->setSettingsDirectory(IuStringUtils::Replace(SettingsFolder, "\\", "/")); IsPortable = true; return; } SettingsFolder = IuCoreUtils::WstringToUtf8(static_cast<LPCTSTR>(GetApplicationDataPath() + _T("Image Uploader\\"))); params->setSettingsDirectory(IuStringUtils::Replace(SettingsFolder, "\\", "/")); #if !defined(IU_SERVERLISTTOOL) && !defined (IU_CLI) && !defined(IU_SHELLEXT) { CRegistry Reg; CString lang; Reg.SetRootKey(HKEY_CURRENT_USER); if (Reg.SetKey("Software\\Zenden.ws\\Image Uploader", false)) { CString dir = Reg.ReadString("DataPath"); if (!dir.IsEmpty() && IsDirectory(dir)) { DataFolder = dir; params->setDataDirectory(IuStringUtils::Replace(IuCoreUtils::WstringToUtf8((LPCTSTR)DataFolder), "\\", "/")); return; } } } { CRegistry Reg; Reg.SetRootKey(HKEY_LOCAL_MACHINE); if (Reg.SetKey("Software\\Zenden.ws\\Image Uploader", false)) { CString dir = Reg.ReadString("DataPath"); if (!dir.IsEmpty() && IsDirectory(dir)) { DataFolder = dir; params->setDataDirectory(IuStringUtils::Replace(IuCoreUtils::WstringToUtf8((LPCTSTR)DataFolder), "\\", "/")); return; } } } if (FileExists(GetCommonApplicationDataPath() + SETTINGS_FILE_NAME)) { DataFolder = GetCommonApplicationDataPath() + _T("Image Uploader\\"); params->setDataDirectory(IuStringUtils::Replace(IuCoreUtils::WstringToUtf8((LPCTSTR)DataFolder), "\\", "/")); } else #endif { DataFolder = GetApplicationDataPath() + _T("Image Uploader\\"); params->setDataDirectory(IuStringUtils::Replace(IuCoreUtils::WstringToUtf8((LPCTSTR)DataFolder), "\\", "/")); } }
CSettings::CSettings() { #if !defined(IU_CLI) && !defined(IU_SERVERLISTTOOL) IsPortable = false; FindDataFolder(); if (!IsDirectory(DataFolder)) { CreateDirectory(DataFolder, 0); } if (!IsDirectory(IuCoreUtils::Utf8ToWstring(SettingsFolder).c_str())) { CreateDirectory(IuCoreUtils::Utf8ToWstring(SettingsFolder).c_str(), 0); } BOOL isElevated = false; IsElevated(&isElevated); if ( isElevated || CmdLine.IsOption(L"afterupdate")) { WinUtils::MakeDirectoryWritable(DataFolder); } #endif #if !defined(IU_CLI) && !defined(IU_SERVERLISTTOOL) CString copyFrom = WinUtils::GetAppFolder() + SETTINGS_FILE_NAME; CString copyTo = DataFolder + SETTINGS_FILE_NAME; if (FileExists(copyFrom) && !FileExists(copyTo)) { MoveFile(copyFrom, copyTo); } // Default values of settings ExplorerCascadedMenu = true; ConnectionSettings.UseProxy = FALSE; ConnectionSettings.ProxyPort = 0; ConnectionSettings.NeedsAuth = false; ConnectionSettings.ProxyType = 0; #endif LastUpdateTime = 0; UploadBufferSize = /*65536*/1024*1024; FileRetryLimit = 3; ActionRetryLimit = 2; #if !defined(IU_SHELLEXT) && !defined(IU_CLI) && !defined(IU_SERVERLISTTOOL) if ( !IsFFmpegAvailable() ){ VideoSettings.Engine = VideoEngineDirectshow; } WatchClipboard = true; ShowTrayIcon = false; ShowTrayIcon_changed = false; *m_Directory = 0; UseTxtTemplate = false; UseDirectLinks = true; CodeLang = 0; ConfirmOnExit = 1; ExplorerContextMenu = false; ExplorerVideoContextMenu = true; ExplorerContextMenu_changed = false; ThumbsPerLine = 4; SendToContextMenu_changed = false; SendToContextMenu = 0; QuickUpload = 1; ParseSubDirs = 1; UseNewIcon = false; RememberImageServer = true; RememberFileServer = true; ShowUploadErrorDialog = true; ImageEditorPath = _T("mspaint.exe \"%1\""); AutoCopyToClipboard = false; AutoShowLog = true; // StringToFont(_T("Tahoma,7,b,204"), &ThumbSettings.ThumbFont); StringToFont(_T("Tahoma,8,,204"), &VideoSettings.Font); /*ThumbSettings.CreateThumbs = true; ThumbSettings.ThumbWidth = 180; ThumbSettings.ThumbHeight = 140; ThumbSettings.DrawFrame = true; ThumbSettings.ThumbAddImageSize = true; ThumbSettings.FrameColor = RGB( 0, 74, 111); ThumbSettings.BackgroundColor = RGB( 255, 255, 255);f ThumbSettings.ThumbColor1 = RGB( 13, 86, 125); ThumbSettings.ThumbColor2 = RGB( 6, 174, 255); ThumbSettings.UseServerThumbs = false; ThumbSettings.ScaleByHeight = false; ThumbSettings.ThumbTextColor = RGB( 255, 255, 255); ThumbSettings.ThumbAlpha = 120; ThumbSettings.Text = _T("%width%x%height% (%size%)"); ThumbSettings.Format = ThumbCreatingParams::tfJPEG; ThumbSettings.FileName = "default"; ThumbSettings.Quality = 85;*/ VideoSettings.Columns = 3; VideoSettings.TileWidth = 200; VideoSettings.GapWidth = 5; VideoSettings.GapHeight = 7; VideoSettings.NumOfFrames = 8; VideoSettings.JPEGQuality = 100; VideoSettings.UseAviInfo = TRUE; VideoSettings.ShowMediaInfo = TRUE; VideoSettings.TextColor = RGB(0, 0, 0); VideoSettings.SnapshotsFolder = IuCoreUtils::Utf8ToWstring(Settings.SettingsFolder).c_str() + CString(_T("Snapshots")); VideoSettings.SnapshotFileTemplate = _T("%f%_%cx%_%cy%_%uid%\\grab_%i%.png"); VideoSettings.Engine = IsFFmpegAvailable() ? VideoEngineAuto : VideoEngineDirectshow; ScreenshotSettings.Format = 1; ScreenshotSettings.Quality = 85; ScreenshotSettings.WindowHidingDelay = 450; ScreenshotSettings.Delay = 1; ScreenshotSettings.brushColor = RGB(255, 0, 0); ScreenshotSettings.ShowForeground = false; ScreenshotSettings.FilenameTemplate = _T("screenshot %y-%m-%d %i"); ScreenshotSettings.CopyToClipboard = false; ScreenshotSettings.RemoveCorners = !WinUtils::IsWindows8orLater(); ScreenshotSettings.AddShadow = false; ScreenshotSettings.RemoveBackground = false; ScreenshotSettings.OpenInEditor = true; ScreenshotSettings.UseOldRegionScreenshotMethod = false; TrayIconSettings.LeftClickCommand = 0; // without action TrayIconSettings.LeftDoubleClickCommand = 12; TrayIconSettings.RightClickCommand = 1; // context menu TrayIconSettings.MiddleClickCommand = 7; // region screenshot TrayIconSettings.DontLaunchCopy = FALSE; TrayIconSettings.ShortenLinks = FALSE; TrayIconSettings.TrayScreenshotAction = TRAY_SCREENSHOT_OPENINEDITOR; ImageEditorSettings.BackgroundColor = Gdiplus::Color(255,255,255); ImageEditorSettings.ForegroundColor = Gdiplus::Color(255,0,0); ImageEditorSettings.PenSize = 12; ImageEditorSettings.RoundingRadius = ImageEditorSettings.PenSize; StringToFont(_T("Arial,12,b,204"), &ImageEditorSettings.Font); ImageReuploaderSettings.PasteHtmlOnCtrlV = true; Hotkeys_changed = false; #endif /* binding settings */ SettingsNode& general = mgr_["General"]; general.n_bind(LastUpdateTime); #if !defined(IU_CLI) && !defined(IU_SERVERLISTTOOL) general.n_bind(Language); general.n_bind(ExplorerContextMenu); /*general.n_bind(ExplorerVideoContextMenu); general.n_bind(ExplorerCascadedMenu);*/ #endif #if !defined(IU_SHELLEXT) && !defined(IU_CLI) && !defined(IU_SERVERLISTTOOL) general.n_bind(ConfirmOnExit); general.n_bind(SendToContextMenu); general.n_bind(ParseSubDirs); general.n_bind(ImageEditorPath); //general.n_bind(AutoStartup); general.n_bind(ShowTrayIcon); general.n_bind(AutoCopyToClipboard); general.n_bind(AutoShowLog); general.n_bind(ImagesFolder); general.n_bind(VideoFolder); general.n_bind(WatchClipboard); general.n_bind(UseNewIcon); general.n_bind(RememberFileServer); general.n_bind(RememberImageServer); #ifndef IU_SERVERLISTTOOL general.n_bind(Hotkeys); #endif SettingsNode& screenshot = mgr_["Screenshot"]; screenshot.nm_bind(ScreenshotSettings, Delay); screenshot.nm_bind(ScreenshotSettings, Format); screenshot.nm_bind(ScreenshotSettings, Quality); screenshot.nm_bind(ScreenshotSettings, ShowForeground); screenshot.nm_bind(ScreenshotSettings, FilenameTemplate); screenshot.nm_bind(ScreenshotSettings, Folder); screenshot.nm_bind(ScreenshotSettings, AddShadow); screenshot.nm_bind(ScreenshotSettings, RemoveBackground); screenshot.nm_bind(ScreenshotSettings, RemoveCorners); screenshot.nm_bind(ScreenshotSettings, CopyToClipboard); screenshot.nm_bind(ScreenshotSettings, brushColor); screenshot.nm_bind(ScreenshotSettings, WindowHidingDelay); screenshot.nm_bind(ScreenshotSettings, OpenInEditor); screenshot.nm_bind(ScreenshotSettings, UseOldRegionScreenshotMethod); SettingsNode& imageEditor = mgr_["ImageEditor"]; imageEditor.nm_bind(ImageEditorSettings, ForegroundColor); imageEditor.nm_bind(ImageEditorSettings, BackgroundColor); imageEditor.nm_bind(ImageEditorSettings, PenSize); imageEditor.nm_bind(ImageEditorSettings, RoundingRadius); imageEditor.nm_bind(ImageEditorSettings, Font); SettingsNode& image = mgr_["Image"]; image["CurrentProfile"].bind(CurrentConvertProfileName); image.nm_bind(UploadProfile, KeepAsIs); /*SettingsNode& thumbnails = mgr_["Thumbnails"]; thumbnails.nm_bind(ThumbSettings, FileName); thumbnails.nm_bind(ThumbSettings, CreateThumbs); thumbnails.nm_bind(ThumbSettings, ThumbWidth); thumbnails.nm_bind(ThumbSettings, ThumbHeight); thumbnails.nm_bind(ThumbSettings, ScaleByHeight); thumbnails.nm_bind(ThumbSettings, FrameColor); thumbnails.nm_bind(ThumbSettings, ThumbColor1); thumbnails.nm_bind(ThumbSettings, ThumbColor2); thumbnails.nm_bind(ThumbSettings, UseServerThumbs); thumbnails.nm_bind(ThumbSettings, ThumbAddImageSize); thumbnails.nm_bind(ThumbSettings, DrawFrame); thumbnails.nm_bind(ThumbSettings, Quality); thumbnails.nm_bind(ThumbSettings, Format); thumbnails.nm_bind(ThumbSettings, Text); thumbnails["Text"]["@Color"].bind(ThumbSettings.ThumbTextColor); thumbnails["Text"]["@Font"].bind(ThumbSettings.ThumbFont); thumbnails["Text"]["@TextOverThumb"].bind(ThumbSettings.TextOverThumb); thumbnails["Text"]["@ThumbAlpha"].bind(ThumbSettings.ThumbAlpha);*/ SettingsNode& video = mgr_["VideoGrabber"]; video.nm_bind(VideoSettings, Columns); video.nm_bind(VideoSettings, TileWidth); video.nm_bind(VideoSettings, GapWidth); video.nm_bind(VideoSettings, GapHeight); video.nm_bind(VideoSettings, NumOfFrames); video.nm_bind(VideoSettings, JPEGQuality); video.nm_bind(VideoSettings, ShowMediaInfo); video.nm_bind(VideoSettings, TextColor); video.nm_bind(VideoSettings, Font); video.nm_bind(VideoSettings, Engine); video.nm_bind(VideoSettings, SnapshotsFolder); video.nm_bind(VideoSettings, SnapshotFileTemplate); SettingsNode& tray = mgr_["TrayIcon"]; tray.nm_bind(TrayIconSettings, LeftDoubleClickCommand); tray.nm_bind(TrayIconSettings, LeftClickCommand); tray.nm_bind(TrayIconSettings, RightClickCommand); tray.nm_bind(TrayIconSettings, MiddleClickCommand); tray.nm_bind(TrayIconSettings, DontLaunchCopy); tray.nm_bind(TrayIconSettings, ShortenLinks); tray.nm_bind(TrayIconSettings, TrayScreenshotAction); SettingsNode& history = mgr_["History"]; history.nm_bind(HistorySettings, EnableDownloading); SettingsNode& imageReuploader = mgr_["ImageReuploader"]; imageReuploader.nm_bind(ImageReuploaderSettings, PasteHtmlOnCtrlV); #endif SettingsNode& upload = mgr_["Uploading"]; #if !defined(IU_CLI) && !defined(IU_SERVERLISTTOOL) upload.n_bind(ServerName); upload.n_bind(FileServerName); // upload.n_bind(UrlShorteningServer); upload.n_bind(QuickUpload); upload.n_bind(QuickServerName); upload.n_bind(CodeLang); upload.n_bind(ThumbsPerLine); upload.n_bind(UseDirectLinks); upload.n_bind(UseTxtTemplate); upload.n_bind(CodeType); upload.n_bind(ShowUploadErrorDialog); imageServer.bind(upload["Server"]); fileServer.bind(upload["FileServer"]); quickScreenshotServer.bind(upload["QuickScreenshotServer"]); contextMenuServer.bind(upload["ContextMenuServer"]); urlShorteningServer.bind(upload["UrlShorteningServer"]); ConvertProfiles["Default"] = ImageConvertingParams(); CurrentConvertProfileName = "Default"; #endif upload.n_bind(UploadBufferSize); upload.n_bind(FileRetryLimit); upload.n_bind(ActionRetryLimit); #if !defined (IU_CLI) && !defined(IU_SHELLEXT) && !defined(IU_SERVERLISTTOOL) SettingsNode& proxy = upload["Proxy"]; proxy["@UseProxy"].bind(ConnectionSettings.UseProxy); proxy["@NeedsAuth"].bind(ConnectionSettings.NeedsAuth); proxy.nm_bind(ConnectionSettings, ServerAddress); proxy.nm_bind(ConnectionSettings, ProxyPort); proxy.nm_bind(ConnectionSettings, ProxyType); proxy.nm_bind(ConnectionSettings, ProxyUser); proxy.nm_bind(ConnectionSettings, ProxyPassword);; #endif }
__drv_mustHoldCriticalRegion NTSTATUS RfsdCleanup (IN PRFSD_IRP_CONTEXT IrpContext) { PDEVICE_OBJECT DeviceObject; NTSTATUS Status = STATUS_SUCCESS; PRFSD_VCB Vcb = 0; BOOLEAN VcbResourceAcquired = FALSE; PFILE_OBJECT FileObject; PRFSD_FCB Fcb = 0; BOOLEAN FcbResourceAcquired = FALSE; BOOLEAN FcbPagingIoAcquired = FALSE; PRFSD_CCB Ccb; PIRP Irp; PAGED_CODE(); _SEH2_TRY { ASSERT(IrpContext != NULL); ASSERT((IrpContext->Identifier.Type == RFSDICX) && (IrpContext->Identifier.Size == sizeof(RFSD_IRP_CONTEXT))); DeviceObject = IrpContext->DeviceObject; if (DeviceObject == RfsdGlobal->DeviceObject) { Status = STATUS_SUCCESS; _SEH2_LEAVE; } Vcb = (PRFSD_VCB) DeviceObject->DeviceExtension; ASSERT(Vcb != NULL); ASSERT((Vcb->Identifier.Type == RFSDVCB) && (Vcb->Identifier.Size == sizeof(RFSD_VCB))); if (!IsFlagOn(Vcb->Flags, VCB_INITIALIZED)) { Status = STATUS_SUCCESS; _SEH2_LEAVE; } #ifdef _MSC_VER #pragma prefast( suppress: 28137, "by design" ) #endif if (!ExAcquireResourceExclusiveLite( &Vcb->MainResource, IrpContext->IsSynchronous )) { Status = STATUS_PENDING; _SEH2_LEAVE; } VcbResourceAcquired = TRUE; FileObject = IrpContext->FileObject; Fcb = (PRFSD_FCB) FileObject->FsContext; if (!Fcb) { Status = STATUS_SUCCESS; _SEH2_LEAVE; } if (Fcb->Identifier.Type == RFSDVCB) { if (IsFlagOn(Vcb->Flags, VCB_VOLUME_LOCKED) && (Vcb->LockFile == FileObject) ) { ClearFlag(Vcb->Flags, VCB_VOLUME_LOCKED); Vcb->LockFile = NULL; RfsdClearVpbFlag(Vcb->Vpb, VPB_LOCKED); } Vcb->OpenHandleCount--; if (!Vcb->OpenHandleCount) { IoRemoveShareAccess(FileObject, &Vcb->ShareAccess); } Status = STATUS_SUCCESS; _SEH2_LEAVE; } ASSERT((Fcb->Identifier.Type == RFSDFCB) && (Fcb->Identifier.Size == sizeof(RFSD_FCB))); /* if ( !IsFlagOn(Vcb->Flags, VCB_READ_ONLY) && !IsFlagOn(Fcb->Flags, FCB_PAGE_FILE)) */ { #ifdef _MSC_VER #pragma prefast( suppress: 28137, "by design" ) #endif if (!ExAcquireResourceExclusiveLite( &Fcb->MainResource, IrpContext->IsSynchronous )) { Status = STATUS_PENDING; _SEH2_LEAVE; } FcbResourceAcquired = TRUE; } Ccb = (PRFSD_CCB) FileObject->FsContext2; if (!Ccb) { Status = STATUS_SUCCESS; _SEH2_LEAVE; } if (IsFlagOn(FileObject->Flags, FO_CLEANUP_COMPLETE)) { if ( IsFlagOn(FileObject->Flags, FO_FILE_MODIFIED) && IsFlagOn(Vcb->Flags, VCB_FLOPPY_DISK) && !IsFlagOn(Vcb->Flags, VCB_WRITE_PROTECTED) ) { Status = RfsdFlushFile(Fcb); } _SEH2_LEAVE; } ASSERT((Ccb->Identifier.Type == RFSDCCB) && (Ccb->Identifier.Size == sizeof(RFSD_CCB))); Irp = IrpContext->Irp; Fcb->OpenHandleCount--; if (!IsFlagOn(FileObject->Flags, FO_CACHE_SUPPORTED )) { Fcb->NonCachedOpenCount--; } Vcb->OpenFileHandleCount--; if (IsFlagOn(Fcb->Flags, FCB_DELETE_ON_CLOSE)) { SetFlag(Fcb->Flags, FCB_DELETE_PENDING); if (IsDirectory(Fcb)) { FsRtlNotifyFullChangeDirectory( Vcb->NotifySync, &Vcb->NotifyList, Fcb, NULL, FALSE, FALSE, 0, NULL, NULL, NULL ); } } if (IsDirectory(Fcb)) { FsRtlNotifyCleanup( Vcb->NotifySync, &Vcb->NotifyList, Ccb ); } else { // // Drop any byte range locks this process may have on the file. // FsRtlFastUnlockAll( &Fcb->FileLockAnchor, FileObject, IoGetRequestorProcess(Irp), NULL ); // // If there are no byte range locks owned by other processes on the // file the fast I/O read/write functions doesn't have to check for // locks so we set IsFastIoPossible to FastIoIsPossible again. // if (!FsRtlGetNextFileLock(&Fcb->FileLockAnchor, TRUE)) { if (Fcb->Header.IsFastIoPossible != FastIoIsPossible) { RfsdPrint(( DBG_INFO, ": %-16.16s %-31s %s\n", RfsdGetCurrentProcessName(), "FastIoIsPossible", Fcb->AnsiFileName.Buffer )); Fcb->Header.IsFastIoPossible = FastIoIsPossible; } } } if ( IsFlagOn( FileObject->Flags, FO_CACHE_SUPPORTED) && (Fcb->NonCachedOpenCount != 0) && (Fcb->NonCachedOpenCount == Fcb->ReferenceCount) && (Fcb->SectionObject.DataSectionObject != NULL)) { if( !IsFlagOn(Vcb->Flags, VCB_READ_ONLY) && !IsFlagOn(Vcb->Flags, VCB_WRITE_PROTECTED)) { CcFlushCache(&Fcb->SectionObject, NULL, 0, NULL); } ExAcquireResourceExclusiveLite(&(Fcb->PagingIoResource), TRUE); ExReleaseResourceLite(&(Fcb->PagingIoResource)); CcPurgeCacheSection( &Fcb->SectionObject, NULL, 0, FALSE ); } if (Fcb->OpenHandleCount == 0) { if (IsFlagOn(Fcb->Flags, FCB_DELETE_PENDING)) { // // Have to delete this file... // #ifdef _MSC_VER #pragma prefast( suppress: 28137, "by design" ) #endif if (!ExAcquireResourceExclusiveLite( &Fcb->PagingIoResource, IrpContext->IsSynchronous )) { Status = STATUS_PENDING; _SEH2_LEAVE; } FcbPagingIoAcquired = TRUE; DbgBreak(); #if DISABLED Status = RfsdDeleteFile(IrpContext, Vcb, Fcb); if (NT_SUCCESS(Status)) { if (IsDirectory(Fcb)) { RfsdNotifyReportChange( IrpContext, Vcb, Fcb, FILE_NOTIFY_CHANGE_DIR_NAME, FILE_ACTION_REMOVED ); } else { RfsdNotifyReportChange( IrpContext, Vcb, Fcb, FILE_NOTIFY_CHANGE_FILE_NAME, FILE_ACTION_REMOVED ); } } #endif if (CcIsFileCached(FileObject)) { CcSetFileSizes(FileObject, (PCC_FILE_SIZES)(&(Fcb->Header.AllocationSize))); SetFlag(FileObject->Flags, FO_FILE_MODIFIED); } if (FcbPagingIoAcquired) { ExReleaseResourceForThreadLite( &Fcb->PagingIoResource, ExGetCurrentResourceThread() ); FcbPagingIoAcquired = FALSE; } } } if (!IsDirectory(Fcb) && FileObject->PrivateCacheMap) { RfsdPrint((DBG_INFO, "RfsdCleanup: CcUninitializeCacheMap is called for %s.\n", Fcb->AnsiFileName.Buffer )); CcUninitializeCacheMap( FileObject, (PLARGE_INTEGER)(&(Fcb->Header.FileSize)), NULL ); } if (!Fcb->OpenHandleCount) { IoRemoveShareAccess(FileObject, &Fcb->ShareAccess); } RfsdPrint((DBG_INFO, "RfsdCleanup: OpenCount: %u ReferCount: %u %s\n", Fcb->OpenHandleCount, Fcb->ReferenceCount, Fcb->AnsiFileName.Buffer )); Status = STATUS_SUCCESS; if (FileObject) { SetFlag(FileObject->Flags, FO_CLEANUP_COMPLETE); } } _SEH2_FINALLY { if (FcbPagingIoAcquired) { ExReleaseResourceForThreadLite( &Fcb->PagingIoResource, ExGetCurrentResourceThread() ); } if (FcbResourceAcquired) { ExReleaseResourceForThreadLite( &Fcb->MainResource, ExGetCurrentResourceThread() ); } if (VcbResourceAcquired) { ExReleaseResourceForThreadLite( &Vcb->MainResource, ExGetCurrentResourceThread()); } if (!IrpContext->ExceptionInProgress) { if (Status == STATUS_PENDING) { RfsdQueueRequest(IrpContext); } else { IrpContext->Irp->IoStatus.Status = Status; RfsdCompleteIrpContext(IrpContext, Status); } } } _SEH2_END; return Status; }
// Deletes the given directory and anything under it. Returns true on success. bool DeleteDirRecursively(const std::string &directory) { INFO_LOG(COMMON, "DeleteDirRecursively: %s", directory.c_str()); #ifdef _WIN32 // Find the first file in the directory. WIN32_FIND_DATA ffd; HANDLE hFind = FindFirstFile(UTF8ToTStr(directory + "\\*").c_str(), &ffd); if (hFind == INVALID_HANDLE_VALUE) { FindClose(hFind); return false; } // windows loop do { const std::string virtualName(TStrToUTF8(ffd.cFileName)); #else struct dirent dirent, *result = NULL; DIR *dirp = opendir(directory.c_str()); if (!dirp) return false; // non windows loop while (!readdir_r(dirp, &dirent, &result) && result) { const std::string virtualName = result->d_name; #endif // check for "." and ".." if (((virtualName[0] == '.') && (virtualName[1] == '\0')) || ((virtualName[0] == '.') && (virtualName[1] == '.') && (virtualName[2] == '\0'))) continue; std::string newPath = directory + DIR_SEP_CHR + virtualName; if (IsDirectory(newPath)) { if (!DeleteDirRecursively(newPath)) { #ifndef _WIN32 closedir(dirp); #endif return false; } } else { if (!File::Delete(newPath)) { #ifndef _WIN32 closedir(dirp); #endif return false; } } #ifdef _WIN32 } while (FindNextFile(hFind, &ffd) != 0); FindClose(hFind); #else } closedir(dirp); #endif File::DeleteDir(directory); return true; }
//-------------------------------------------------------------------------------- bool CDirectory::Exists() { return IsDirectory(GetPath()); }
void RemoveNewShadowDroppings(char *cluster, char *proc) { char names[2][1024]; int j; char *ckpt_name; char *myspool; struct stat buf; int clusternum, procnum; memset(&names[0], 0, 1024); memset(&names[1], 0, 1024); /* XXX I'm sorry. There are some incompatibilities between the new shadow and the old shadow. The new shadow now makes a _directory_ with the usual ckeckpoint name because there might eventually be more than one file that has to get checkpointed with a job. The old shadow is dumb, and it only makes a _file_ named the usual checkpoint name. So a contention happens when we are using opsys/arch to choose an executable name for both NT and UNIX between vanilla only jobs and standard universe jobs. What happens is that the old shadow gets back a correct stat() on the new shadow created directory but misinterprets it as a file and hilarity ensues. So, my nasty hack is to make the old shadow determine if the file it found is actually a directory and if so, then remove it and everything underneath it. I somehow feel that this might bite us in the ass in the future, so each time the shadow does this, it logs it so a human can figure out what happened. I don't have to worry about the converse issue of a new shadow starting up with an old file-based checkpoint because whomever adds standard universe support to the new shadow will have to do something intelligent, and our submit program places expressions into the requirements attribute in the job forcing a checkpointed job to always run on the architecture it checkpointed on. -psilord 7/30/01 */ myspool = param("SPOOL"); if (myspool == NULL) { EXCEPT ("RemoveNewShadowDroppings(): No Spool directory!?!\n"); } clusternum = atoi(cluster); procnum = atoi(proc); if (clusternum < 0 || procnum < 0) /* sanity checks */ { dprintf(D_ALWAYS, "RemoveNewShadowDroppings(): Asked to deal with " "negative cluster or proc numbers. Ignoring.\n"); free(myspool); return; } ckpt_name = gen_ckpt_name( myspool, clusternum, procnum, 0 ); strcpy(names[0], ckpt_name); strcpy(names[1], ckpt_name); strcat(names[1], ".tmp"); free(ckpt_name); ckpt_name = NULL; for (j = 0; j < 2; j++) { if (stat(names[j], &buf) == 0) { /* ok, we have a hit, let's see if it is a directory... */ if (IsDirectory(names[j]) == true) { /* it is, so blow away everything inside it */ { Directory todd_droppings(names[j]); if (todd_droppings.Remove_Entire_Directory() == false) { dprintf(D_ALWAYS, "RemoveNewShadowDroppings(): Old " "shadow failed to remove new shadow ckpt directory " "contents: %s\n", names[j]); } } /* now delete the directory itself */ if (rmdir(names[j]) < 0 && errno != ENOENT) { dprintf(D_ALWAYS, "RemoveNewShadowDroppings(): Old shadow " "failed to remove new shadow ckpt directory: %s (%s)\n", names[j], strerror(errno)); } else { dprintf(D_ALWAYS, "RemoveNewShadowDroppings(): Old shadow " "removed new shadow ckpt directory: %s\n", names[j]); } } } } free(myspool); }
NTSTATUS Ext2ReadFile(IN PEXT2_IRP_CONTEXT IrpContext) { NTSTATUS Status = STATUS_UNSUCCESSFUL; PEXT2_VCB Vcb = NULL; PEXT2_FCB Fcb = NULL; PEXT2_CCB Ccb = NULL; PFILE_OBJECT FileObject = NULL; PDEVICE_OBJECT DeviceObject = NULL; PIRP Irp = NULL; PIO_STACK_LOCATION IoStackLocation = NULL; ULONG Length; ULONG ReturnedLength = 0; LARGE_INTEGER ByteOffset; BOOLEAN OpPostIrp = FALSE; BOOLEAN PagingIo; BOOLEAN Nocache; BOOLEAN SynchronousIo; BOOLEAN MainResourceAcquired = FALSE; BOOLEAN PagingIoResourceAcquired = FALSE; PUCHAR Buffer; __try { ASSERT(IrpContext); ASSERT((IrpContext->Identifier.Type == EXT2ICX) && (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT))); DeviceObject = IrpContext->DeviceObject; Vcb = (PEXT2_VCB) DeviceObject->DeviceExtension; ASSERT(Vcb != NULL); ASSERT((Vcb->Identifier.Type == EXT2VCB) && (Vcb->Identifier.Size == sizeof(EXT2_VCB))); FileObject = IrpContext->FileObject; Fcb = (PEXT2_FCB) FileObject->FsContext; ASSERT(Fcb); ASSERT((Fcb->Identifier.Type == EXT2FCB) && (Fcb->Identifier.Size == sizeof(EXT2_FCB))); Ccb = (PEXT2_CCB) FileObject->FsContext2; Irp = IrpContext->Irp; IoStackLocation = IoGetCurrentIrpStackLocation(Irp); Length = IoStackLocation->Parameters.Read.Length; ByteOffset = IoStackLocation->Parameters.Read.ByteOffset; PagingIo = IsFlagOn(Irp->Flags, IRP_PAGING_IO); Nocache = IsFlagOn(Irp->Flags, IRP_NOCACHE); SynchronousIo = IsFlagOn(FileObject->Flags, FO_SYNCHRONOUS_IO); if (PagingIo) { ASSERT(Nocache); } DEBUG(DL_INF, ("Ext2ReadFile: reading %wZ Off=%I64xh Len=%xh Paging=%xh Nocache=%xh\n", &Fcb->Mcb->ShortName, ByteOffset.QuadPart, Length, PagingIo, Nocache)); if ((IsSymLink(Fcb) && IsFileDeleted(Fcb->Mcb->Target)) || IsFileDeleted(Fcb->Mcb)) { Status = STATUS_FILE_DELETED; __leave; } if (Length == 0) { Irp->IoStatus.Information = 0; Status = STATUS_SUCCESS; __leave; } if (Nocache && (ByteOffset.LowPart & (SECTOR_SIZE - 1) || Length & (SECTOR_SIZE - 1))) { Status = STATUS_INVALID_PARAMETER; DbgBreak(); __leave; } if (FlagOn(IrpContext->MinorFunction, IRP_MN_DPC)) { ClearFlag(IrpContext->MinorFunction, IRP_MN_DPC); Status = STATUS_PENDING; DbgBreak(); __leave; } if (!PagingIo && Nocache && (FileObject->SectionObjectPointer->DataSectionObject != NULL)) { CcFlushCache( FileObject->SectionObjectPointer, &ByteOffset, Length, &Irp->IoStatus ); if (!NT_SUCCESS(Irp->IoStatus.Status)) { __leave; } } ReturnedLength = Length; if (PagingIo) { if (!ExAcquireResourceSharedLite( &Fcb->PagingIoResource, IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT) )) { Status = STATUS_PENDING; __leave; } PagingIoResourceAcquired = TRUE; } else { if (Nocache) { if (!ExAcquireResourceExclusiveLite( &Fcb->MainResource, IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT) )) { Status = STATUS_PENDING; __leave; } MainResourceAcquired = TRUE; } else { if (!ExAcquireResourceSharedLite( &Fcb->MainResource, IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT) )) { Status = STATUS_PENDING; __leave; } MainResourceAcquired = TRUE; } if (!FsRtlCheckLockForReadAccess( &Fcb->FileLockAnchor, Irp )) { Status = STATUS_FILE_LOCK_CONFLICT; __leave; } } if ((ByteOffset.QuadPart + (LONGLONG)Length) > Fcb->Header.FileSize.QuadPart) { if (ByteOffset.QuadPart >= Fcb->Header.FileSize.QuadPart) { Irp->IoStatus.Information = 0; Status = STATUS_END_OF_FILE; __leave; } ReturnedLength = (ULONG)(Fcb->Header.FileSize.QuadPart - ByteOffset.QuadPart); } if (!IsDirectory(Fcb) && Ccb != NULL) { Status = FsRtlCheckOplock( &Fcb->Oplock, Irp, IrpContext, Ext2OplockComplete, Ext2LockIrp ); if (Status != STATUS_SUCCESS) { OpPostIrp = TRUE; __leave; } // // Set the flag indicating if Fast I/O is possible // Fcb->Header.IsFastIoPossible = Ext2IsFastIoPossible(Fcb); } if (!Nocache) { if (IsDirectory(Fcb)) { __leave; } if (FileObject->PrivateCacheMap == NULL) { CcInitializeCacheMap( FileObject, (PCC_FILE_SIZES)(&Fcb->Header.AllocationSize), FALSE, &Ext2Global->CacheManagerCallbacks, Fcb ); CcSetReadAheadGranularity( FileObject, READ_AHEAD_GRANULARITY ); } if (FlagOn(IrpContext->MinorFunction, IRP_MN_MDL)) { CcMdlRead( FileObject, (&ByteOffset), ReturnedLength, &Irp->MdlAddress, &Irp->IoStatus ); Status = Irp->IoStatus.Status; } else { Buffer = Ext2GetUserBuffer(Irp); if (Buffer == NULL) { Status = STATUS_INVALID_USER_BUFFER; DbgBreak(); __leave; } if (!CcCopyRead(FileObject, &ByteOffset, ReturnedLength, Ext2CanIWait(), Buffer, &Irp->IoStatus)) { if (Ext2CanIWait() || !CcCopyRead(FileObject, &ByteOffset, ReturnedLength, TRUE, Buffer, &Irp->IoStatus)) { Status = STATUS_PENDING; DbgBreak(); __leave; } } Status = Irp->IoStatus.Status; } } else { ULONG BytesRead = ReturnedLength; PUCHAR SystemVA = Ext2GetUserBuffer(IrpContext->Irp); if (ByteOffset.QuadPart + BytesRead > Fcb->Header.ValidDataLength.QuadPart) { if (ByteOffset.QuadPart >= Fcb->Header.ValidDataLength.QuadPart) { if (SystemVA) { SafeZeroMemory(SystemVA, Length); } Irp->IoStatus.Information = ReturnedLength; Status = STATUS_SUCCESS; __leave; } else { BytesRead = (ULONG)(Fcb->Header.ValidDataLength.QuadPart - ByteOffset.QuadPart); if (SystemVA) { SafeZeroMemory(SystemVA + BytesRead, Length - BytesRead); } } } Status = Ext2LockUserBuffer( IrpContext->Irp, BytesRead, IoReadAccess ); if (!NT_SUCCESS(Status)) { __leave; } Status = Ext2ReadInode( IrpContext, Vcb, Fcb->Mcb, ByteOffset.QuadPart, NULL, BytesRead, TRUE, NULL ); /* we need re-queue this request in case STATUS_CANT_WAIT and fail it in other failure cases */ if (!NT_SUCCESS(Status)) { __leave; } /* pended by low level device */ if (Status == STATUS_PENDING) { IrpContext->Irp = Irp = NULL; __leave; } Irp = IrpContext->Irp; ASSERT(Irp); Status = Irp->IoStatus.Status; if (!NT_SUCCESS(Status)) { Ext2NormalizeAndRaiseStatus(IrpContext, Status); } } Irp->IoStatus.Information = ReturnedLength; } __finally { if (Irp) { if (PagingIoResourceAcquired) { ExReleaseResourceLite(&Fcb->PagingIoResource); } if (MainResourceAcquired) { ExReleaseResourceLite(&Fcb->MainResource); } } if (!OpPostIrp && !IrpContext->ExceptionInProgress) { if (Irp) { if ( Status == STATUS_PENDING || Status == STATUS_CANT_WAIT) { Status = Ext2LockUserBuffer( IrpContext->Irp, Length, IoWriteAccess ); if (NT_SUCCESS(Status)) { Status = Ext2QueueRequest(IrpContext); } else { Ext2CompleteIrpContext(IrpContext, Status); } } else { if (NT_SUCCESS(Status)) { if (!PagingIo) { if (SynchronousIo) { FileObject->CurrentByteOffset.QuadPart = ByteOffset.QuadPart + Irp->IoStatus.Information; } FileObject->Flags |= FO_FILE_FAST_IO_READ; } } Ext2CompleteIrpContext(IrpContext, Status); } } else { Ext2FreeIrpContext(IrpContext); } } } DEBUG(DL_IO, ("Ext2ReadFile: %wZ fetch at Off=%I64xh Len=%xh Paging=%xh Nocache=%xh Returned=%xh Status=%xh\n", &Fcb->Mcb->ShortName, ByteOffset.QuadPart, Length, PagingIo, Nocache, ReturnedLength, Status)); return Status; }