bool File::Open(PackageFile* package, const String& fileName) { Close(); if (!package) return false; const PackageEntry* entry = package->GetEntry(fileName); if (!entry) return false; #ifdef WIN32 handle_ = _wfopen(GetWideNativePath(package->GetName()).CString(), L"rb"); #else handle_ = fopen(GetNativePath(package->GetName()).CString(), "rb"); #endif if (!handle_) { LOGERROR("Could not open package file " + fileName); return false; } fileName_ = fileName; mode_ = FILE_READ; offset_ = entry->offset_; checksum_ = entry->checksum_; position_ = 0; size_ = entry->size_; compressed_ = package->IsCompressed(); fseek((FILE*)handle_, offset_, SEEK_SET); return true; }
String PlatformAndroid::GetAndroidCommand() const { ToolPrefs* prefs = GetSubsystem<ToolEnvironment>()->GetToolPrefs(); String androidCommand = GetNativePath(prefs->GetAndroidSDKPath()); if (!androidCommand.Length()) return String::EMPTY; #ifdef ATOMIC_PLATFORM_OSX //Vector<String> args = String("list targets").Split(' '); androidCommand += "/tools/android"; #endif #ifdef ATOMIC_PLATFORM_WINDOWS // android is a batch file on windows, so have to run with cmd /c androidCommand += "\\tools\\android.bat"; //androidCommand = "cmd"; #endif #ifdef ATOMIC_PLATFORM_LINUX androidCommand += "/tools/android"; #endif return androidCommand; }
String FileUtils::OpenProjectFileDialog() { nfdchar_t *outPath = NULL; String upath; #ifdef ATOMIC_PLATFORM_LINUX upath = GetSubsystem<FileSystem>()->GetUserDocumentsDir(); #endif nfdresult_t result = NFD_OpenDialog( "atomic", upath.Length() ? GetNativePath(upath).CString() : "", &outPath); String fullpath; if (outPath && result == NFD_OKAY) { fullpath = outPath; } GetSubsystem<Graphics>()->RaiseWindow(); if (outPath) free(outPath); return fullpath; }
String FileUtils::NewProjectFileDialog() { String projectPath; nfdchar_t *outPath = NULL; String upath; #ifdef ATOMIC_PLATFORM_LINUX upath = GetSubsystem<FileSystem>()->GetUserDocumentsDir(); #endif nfdresult_t result = NFD_PickFolder(upath.Length() ? GetNativePath(upath).CString() : "", &outPath); if (outPath && result == NFD_OKAY) { projectPath = outPath; } GetSubsystem<Graphics>()->RaiseWindow(); if (outPath) free(outPath); return projectPath; }
bool PosixFileSystem::GetFileTime( const char *path, xtime::TimeDate &td, FileOptions options ) { RAD_ASSERT(path); String nativePath; if (options & kFileOption_NativePath) { nativePath = CStr(path); } else { if (!GetNativePath(path, nativePath)) return false; } struct stat s; if (::stat(nativePath.c_str, &s) != 0) return false; struct tm t; localtime_r(&s.st_mtime, &t); td.dayOfMonth = (U8)t.tm_mday; td.month = (U8)t.tm_mon; td.year = (U16)t.tm_year; td.hour = (U8)t.tm_hour; td.minute = (U8)t.tm_min; td.second = (U8)t.tm_sec; td.dayOfWeek = (U8)t.tm_wday; td.millis = 0; return true; }
bool AssetImporter::Move(const String& newPath) { FileSystem* fs = GetSubsystem<FileSystem>(); if (newPath == asset_->path_) return false; String oldPath = asset_->path_; String oldName = asset_->name_; String pathName, newName, ext; SplitPath(newPath, pathName, newName, ext); // rename asset first, ahead of the filesystem watcher, so the assetdatabase doesn't see a new asset asset_->name_ = newName; asset_->path_ = newPath; // first rename the .asset file if (!fs->Rename(oldPath + ".asset", newPath + ".asset")) { asset_->name_ = oldName; asset_->path_ = oldPath; LOGERRORF("Unable to rename asset: %s to %s", GetNativePath(oldPath + ".asset").CString(), GetNativePath(newPath + ".asset").CString()); return false; } // now rename the asset file itself if (!fs->Rename(oldPath, newPath)) { asset_->name_ = oldName; asset_->path_ = oldPath; // restore .asset fs->Rename(newPath + ".asset", oldPath + ".asset"); LOGERRORF("Unable to rename: %s to %s", GetNativePath(oldPath).CString(), GetNativePath(newPath).CString()); return false; } return true; }
bool PosixFileSystem::DeleteDirectory( const char *path, FileOptions options ) { RAD_ASSERT(path); String nativePath; if (options & kFileOption_NativePath) { nativePath = CStr(path); } else { if (!GetNativePath(path, nativePath)) return false; } return DeleteDirectory_r(nativePath.c_str); }
/** * Returns full path to a file. Makes sure that the full path is bellow * this directory (security measure) * * Caller should free the returned string * * @param relativePath relative path * @return full path to a file */ char* nsFolderSpec::MakeFullPath(char* relativePath, char* *errorMsg) { // Security check. Make sure that we do not have '.. in the name // if ( (GetSecurityTargetID() == SoftwareUpdate.LIMITED_INSTALL) && // ( relativePath.regionMatches(0, "..", 0, 2))) // throw new SoftUpdateException(Strings.error_IllegalPath(), SoftwareUpdate.ILLEGAL_RELATIVE_PATH ); char *fullPath=NULL; char *dir_path; *errorMsg = NULL; dir_path = GetDirectoryPath(); if (dir_path == NULL) { return NULL; } fullPath = XP_Cat(dir_path, GetNativePath(relativePath)); return fullPath; }
String FileUtils::FindPath(const String& title, const String& defaultPath) { String resultPath; nfdchar_t *outPath = NULL; nfdresult_t result = NFD_PickFolder(defaultPath.Length() ? GetNativePath(defaultPath).CString() : "", &outPath); if (outPath && result == NFD_OKAY) { resultPath = outPath; } if (outPath) free(outPath); GetSubsystem<Graphics>()->RaiseWindow(); return GetInternalPath(resultPath); }
/* FullPathPointsToFolder(fullPath) Returns true if the path points to an existing folder, false if it points to a file or does not point to anything. fullPath may be a Macintosh or a Windows path. Thread Safety: FullPathPointsToFolder is thread-safe with Igor Pro 6.20 or later. */ int FullPathPointsToFolder(const char* fullPath) { char nativePath[MAX_PATH_LEN+1]; DWORD attributes; int err; if (err = GetNativePath(fullPath, nativePath)) return err; attributes = GetFileAttributes(nativePath); if (attributes == 0xFFFFFFFF) // Error? return 0; if ((attributes & FILE_ATTRIBUTE_DIRECTORY) == 0) return 0; // Points to a file. return 1; }
String FileUtils::FindFile (const String& filterlist, const String& defaultPath) { String fullpath; nfdchar_t *outPath = NULL; nfdresult_t result = NFD_OpenDialog( filterlist.CString(), defaultPath.Length() ? GetNativePath(defaultPath).CString() : "", &outPath); if (outPath && result == NFD_OKAY) { fullpath = outPath; } GetSubsystem<Graphics>()->RaiseWindow(); if (outPath) free(outPath); return fullpath; }
bool PosixFileSystem::CreateDirectory( const char *path, FileOptions options ) { RAD_ASSERT(path); String nativePath; if (options & kFileOption_NativePath) { nativePath = CStr(path); } else { if (!GetNativePath(path, nativePath)) return false; } // create intermediate directory structure. path = nativePath.c_str; for (int i = 0; path[i]; ++i) { if ((path[i] == '/') && (i > 2)) { char dir[256]; string::ncpy(dir, path, i+1); if (mkdir(dir, 0777) == -1) { if (errno != EEXIST) return false; } } } if (nativePath[0] != '/' || (nativePath.numBytes > 2)) { if (mkdir(nativePath.c_str, 0777) == -1) { if (errno != EEXIST) return false; } } return true; }
NS_IMETHODIMP nsLocalFile::CreateUnique(uint32_t aType, uint32_t aAttributes) { nsresult rv; bool longName; #ifdef XP_WIN nsAutoString pathName, leafName, rootName, suffix; rv = GetPath(pathName); #else nsAutoCString pathName, leafName, rootName, suffix; rv = GetNativePath(pathName); #endif if (NS_FAILED(rv)) { return rv; } longName = (pathName.Length() + kMaxSequenceNumberLength > kMaxFilenameLength); if (!longName) { rv = Create(aType, aAttributes); if (rv != NS_ERROR_FILE_ALREADY_EXISTS) { return rv; } } #ifdef XP_WIN rv = GetLeafName(leafName); if (NS_FAILED(rv)) { return rv; } const int32_t lastDot = leafName.RFindChar(char16_t('.')); #else rv = GetNativeLeafName(leafName); if (NS_FAILED(rv)) { return rv; } const int32_t lastDot = leafName.RFindChar('.'); #endif if (lastDot == kNotFound) { rootName = leafName; } else { suffix = Substring(leafName, lastDot); // include '.' rootName = Substring(leafName, 0, lastDot); // strip suffix and dot } if (longName) { int32_t maxRootLength = (kMaxFilenameLength - (pathName.Length() - leafName.Length()) - suffix.Length() - kMaxSequenceNumberLength); // We cannot create an item inside a directory whose name is too long. // Also, ensure that at least one character remains after we truncate // the root name, as we don't want to end up with an empty leaf name. if (maxRootLength < 2) { return NS_ERROR_FILE_UNRECOGNIZED_PATH; } #ifdef XP_WIN // ensure that we don't cut the name in mid-UTF16-character rootName.SetLength(NS_IS_LOW_SURROGATE(rootName[maxRootLength]) ? maxRootLength - 1 : maxRootLength); SetLeafName(rootName + suffix); #else if (NS_IsNativeUTF8()) { // ensure that we don't cut the name in mid-UTF8-character // (assume the name is valid UTF8 to begin with) while (UTF8traits::isInSeq(rootName[maxRootLength])) { --maxRootLength; } // Another check to avoid ending up with an empty leaf name. if (maxRootLength == 0 && suffix.IsEmpty()) { return NS_ERROR_FILE_UNRECOGNIZED_PATH; } } rootName.SetLength(maxRootLength); SetNativeLeafName(rootName + suffix); #endif nsresult rv = Create(aType, aAttributes); if (rv != NS_ERROR_FILE_ALREADY_EXISTS) { return rv; } } for (int indx = 1; indx < 10000; ++indx) { // start with "Picture-1.jpg" after "Picture.jpg" exists #ifdef XP_WIN SetLeafName(rootName + NS_ConvertASCIItoUTF16(nsPrintfCString("-%d", indx)) + suffix); #else SetNativeLeafName(rootName + nsPrintfCString("-%d", indx) + suffix); #endif rv = Create(aType, aAttributes); if (NS_SUCCEEDED(rv) || rv != NS_ERROR_FILE_ALREADY_EXISTS) { return rv; } } // The disk is full, sort of return NS_ERROR_FILE_TOO_BIG; }
bool File::Open(const String& fileName, FileMode mode) { Close(); FileSystem* fileSystem = GetSubsystem<FileSystem>(); if (fileSystem && !fileSystem->CheckAccess(GetPath(fileName))) { LOGERROR("Access denied to " + fileName); return false; } #ifdef ANDROID if (fileName.StartsWith("/apk/")) { if (mode != FILE_READ) { LOGERROR("Only read mode is supported for asset files"); return false; } assetHandle_ = SDL_RWFromFile(fileName.Substring(5).CString(), "rb"); if (!assetHandle_) { LOGERROR("Could not open asset file " + fileName); return false; } else { fileName_ = fileName; mode_ = mode; position_ = 0; offset_ = 0; checksum_ = 0; size_ = assetHandle_->hidden.androidio.size; readBuffer_ = new unsigned char[READ_BUFFER_SIZE]; readBufferOffset_ = 0; readBufferSize_ = 0; return true; } } #endif if (fileName.Empty()) { LOGERROR("Could not open file with empty name"); return false; } #ifdef WIN32 handle_ = _wfopen(GetWideNativePath(fileName).CString(), openMode[mode]); #else handle_ = fopen(GetNativePath(fileName).CString(), openMode[mode]); #endif if (!handle_) { LOGERROR("Could not open file " + fileName); return false; } fileName_ = fileName; mode_ = mode; position_ = 0; offset_ = 0; checksum_ = 0; compressed_ = false; fseek((FILE*)handle_, 0, SEEK_END); size_ = ftell((FILE*)handle_); fseek((FILE*)handle_, 0, SEEK_SET); return true; }
bool File::OpenInternal(const String& fileName, FileMode mode, bool fromPackage) { Close(); compressed_ = false; readSyncNeeded_ = false; writeSyncNeeded_ = false; FileSystem* fileSystem = GetSubsystem<FileSystem>(); if (fileSystem && !fileSystem->CheckAccess(GetPath(fileName))) { ATOMIC_LOGERRORF("Access denied to %s", fileName.CString()); return false; } if (fileName.Empty()) { ATOMIC_LOGERROR("Could not open file with empty name"); return false; } #ifdef __ANDROID__ if (ATOMIC_IS_ASSET(fileName)) { if (mode != FILE_READ) { ATOMIC_LOGERROR("Only read mode is supported for Android asset files"); return false; } assetHandle_ = SDL_RWFromFile(ATOMIC_ASSET(fileName), "rb"); if (!assetHandle_) { ATOMIC_LOGERRORF("Could not open Android asset file %s", fileName.CString()); return false; } else { fileName_ = fileName; mode_ = mode; position_ = 0; if (!fromPackage) { size_ = SDL_RWsize(assetHandle_); offset_ = 0; } checksum_ = 0; return true; } } #endif #ifdef _WIN32 handle_ = _wfopen(GetWideNativePath(fileName).CString(), openMode[mode]); #else handle_ = fopen(GetNativePath(fileName).CString(), openMode[mode]); #endif // If file did not exist in readwrite mode, retry with write-update mode if (mode == FILE_READWRITE && !handle_) { #ifdef _WIN32 handle_ = _wfopen(GetWideNativePath(fileName).CString(), openMode[mode + 1]); #else handle_ = fopen(GetNativePath(fileName).CString(), openMode[mode + 1]); #endif } if (!handle_) { ATOMIC_LOGERRORF("Could not open file %s", fileName.CString()); return false; } if (!fromPackage) { fseek((FILE*)handle_, 0, SEEK_END); long size = ftell((FILE*)handle_); fseek((FILE*)handle_, 0, SEEK_SET); if (size > M_MAX_UNSIGNED) { ATOMIC_LOGERRORF("Could not open file %s which is larger than 4GB", fileName.CString()); Close(); size_ = 0; return false; } size_ = (unsigned)size; offset_ = 0; } fileName_ = fileName; mode_ = mode; position_ = 0; checksum_ = 0; return true; }
WebBrowserHost::WebBrowserHost(Context* context) : Object (context) { const Vector<String>& arguments = GetArguments(); #ifdef ATOMIC_PLATFORM_LINUX XSetErrorHandler(XErrorHandlerImpl); XSetIOErrorHandler(XIOErrorHandlerImpl); // Install a signal handler so we clean up after ourselves. signal(SIGINT, TerminationSignalHandler); signal(SIGTERM, TerminationSignalHandler); #endif // IMPORTANT: See flags being set in implementation of void WebAppBrowser::OnBeforeCommandLineProcessing // these include "--enable-media-stream", "--enable-usermedia-screen-capturing", "--off-screen-rendering-enabled", "--transparent-painting-enabled" #ifdef ATOMIC_PLATFORM_LINUX static const char* _argv[2] = { "AtomicWebView", "--disable-setuid-sandbox" }; CefMainArgs args(2, (char**) &_argv); #else CefMainArgs args; #endif CefSettings settings; settings.windowless_rendering_enabled = 1; FileSystem* fs = GetSubsystem<FileSystem>(); // Set CEF log file to existing log folder if any avoid attempting to write // to executable folder, which is likely not writeable Log* log = GetSubsystem<Log>(); if (log && log->GetLogFile()) { const File* logFile = log->GetLogFile(); String logPath = logFile->GetName (); if (logPath.Length()) { String pathName, fileName, ext; SplitPath(logPath, pathName, fileName, ext); if (pathName.Length()) { pathName = AddTrailingSlash(pathName) + "CEF.log"; CefString(&settings.log_file).FromASCII(GetNativePath(pathName).CString()); } } } // default background is white, add a setting // settings.background_color = 0; if (productVersion_.Length()) { CefString(&settings.product_version).FromASCII(productVersion_.CString()); } if (userAgent_.Length()) { CefString(&settings.user_agent).FromASCII(userAgent_.CString()); } String fullPath; // If we've specified the absolute path to a root cache folder, use it if (rootCacheFolder_.Length() && cacheName_.Length()) { fullPath = rootCacheFolder_ + "/" + cacheName_; CefString(&settings.cache_path).FromASCII(fullPath.CString()); } else { fullPath = fs->GetAppPreferencesDir(cacheName_.CString(), "WebCache"); } CefString(&settings.cache_path).FromASCII(fullPath.CString()); settings.remote_debugging_port = debugPort_; d_ = new WebBrowserHostPrivate(this); // If losing OSX system menu, it means we're calling this // before initializing graphics subsystem if (!CefInitialize(args, settings, d_->app_, nullptr)) { ATOMIC_LOGERROR("CefInitialize - Error"); } RegisterWebSchemeHandlers(this); // Ensure cookie manager is created CefCookieManager::GetGlobalManager(nullptr); SubscribeToEvent(E_UPDATE, ATOMIC_HANDLER(WebBrowserHost, HandleUpdate)); instance_ = this; }
bool FileWatcher::StartWatching(const String& pathName, bool watchSubDirs) { if (!fileSystem_) { LOGERROR("No FileSystem, can not start watching"); return false; } // Stop any previous watching StopWatching(); #if defined(ENABLE_FILEWATCHER) #if defined(WIN32) String nativePath = GetNativePath(RemoveTrailingSlash(pathName)); dirHandle_ = (void*)CreateFileW( WString(nativePath).CString(), FILE_LIST_DIRECTORY, FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0); if (dirHandle_ != INVALID_HANDLE_VALUE) { path_ = AddTrailingSlash(pathName); watchSubDirs_ = watchSubDirs; Start(); LOGDEBUG("Started watching path " + pathName); return true; } else { LOGERROR("Failed to start watching path " + pathName); return false; } #elif defined(__linux__) int flags = IN_CREATE|IN_DELETE|IN_MODIFY|IN_MOVED_FROM|IN_MOVED_TO; int handle = inotify_add_watch(watchHandle_, pathName.CString(), flags); if (handle < 0) { LOGERROR("Failed to start watching path " + pathName); return false; } else { // Store the root path here when reconstructed with inotify later dirHandle_[handle] = ""; path_ = AddTrailingSlash(pathName); watchSubDirs_ = watchSubDirs; if (watchSubDirs_) { Vector<String> subDirs; fileSystem_->ScanDir(subDirs, pathName, "*", SCAN_DIRS, true); for (unsigned i = 0; i < subDirs.Size(); ++i) { String subDirFullPath = AddTrailingSlash(path_ + subDirs[i]); // Don't watch ./ or ../ sub-directories if (!subDirFullPath.EndsWith("./")) { handle = inotify_add_watch(watchHandle_, subDirFullPath.CString(), flags); if (handle < 0) LOGERROR("Failed to start watching subdirectory path " + subDirFullPath); else { // Store sub-directory to reconstruct later from inotify dirHandle_[handle] = AddTrailingSlash(subDirs[i]); } } } } Start(); LOGDEBUG("Started watching path " + pathName); return true; } #elif defined(__APPLE__) && !defined(IOS) if (!supported_) { LOGERROR("Individual file watching not supported by this OS version, can not start watching path " + pathName); return false; } watcher_ = CreateFileWatcher(pathName.CString(), watchSubDirs); if (watcher_) { path_ = AddTrailingSlash(pathName); watchSubDirs_ = watchSubDirs; Start(); LOGDEBUG("Started watching path " + pathName); return true; } else { LOGERROR("Failed to start watching path " + pathName); return false; } #else LOGERROR("FileWatcher not implemented, can not start watching path " + pathName); return false; #endif #else LOGDEBUG("FileWatcher feature not enabled"); return false; #endif }