ResultCode HostFileSystem::Rename(Uid, Gid, const std::string& old_path, const std::string& new_path) { if (!IsValidWiiPath(old_path)) return ResultCode::Invalid; const std::string old_name = BuildFilename(old_path); if (!IsValidWiiPath(new_path)) return ResultCode::Invalid; const std::string new_name = BuildFilename(new_path); // try to make the basis directory File::CreateFullPath(new_name); // if there is already a file, delete it if (File::Exists(old_name) && File::Exists(new_name)) { File::Delete(new_name); } // finally try to rename the file if (!File::Rename(old_name, new_name)) { ERROR_LOG(IOS_FS, "Rename %s to %s - failed", old_name.c_str(), new_name.c_str()); return ResultCode::NotFound; } return ResultCode::Success; }
Result<Metadata> HostFileSystem::GetMetadata(Uid, Gid, const std::string& path) { Metadata metadata; metadata.uid = 0; metadata.gid = 0x3031; // this is also known as makercd, 01 (0x3031) for nintendo and 08 // (0x3038) for MH3 etc if (!IsValidWiiPath(path)) return ResultCode::Invalid; std::string file_name = BuildFilename(path); metadata.modes = {Mode::ReadWrite, Mode::ReadWrite, Mode::ReadWrite}; metadata.attribute = 0x00; // no attributes // Hack: if the path that is being accessed is within an installed title directory, get the // UID/GID from the installed title TMD. Kernel* ios = GetIOS(); u64 title_id; if (ios && IsTitlePath(file_name, Common::FROM_SESSION_ROOT, &title_id)) { IOS::ES::TMDReader tmd = ios->GetES()->FindInstalledTMD(title_id); if (tmd.IsValid()) metadata.gid = tmd.GetGroupId(); } const File::FileInfo info{file_name}; metadata.is_file = info.IsFile(); metadata.size = info.GetSize(); if (!info.Exists()) return ResultCode::NotFound; return metadata; }
ResultCode HostFileSystem::Format(Uid uid) { const std::string root = BuildFilename("/"); if (!File::DeleteDirRecursively(root) || !File::CreateDir(root)) return ResultCode::UnknownError; return ResultCode::Success; }
ResultCode HostFileSystem::CreateDirectory(Uid, Gid, const std::string& path, FileAttribute, Modes) { if (!IsValidWiiPath(path)) return ResultCode::Invalid; std::string name(BuildFilename(path)); name += "/"; File::CreateFullPath(name); DEBUG_ASSERT_MSG(IOS_FS, File::IsDirectory(name), "CREATE_DIR %s failed", name.c_str()); return ResultCode::Success; }
ResultCode HostFileSystem::Rename(Uid, Gid, const std::string& old_path, const std::string& new_path) { if (!IsValidWiiPath(old_path)) return ResultCode::Invalid; const std::string old_name = BuildFilename(old_path); if (!IsValidWiiPath(new_path)) return ResultCode::Invalid; const std::string new_name = BuildFilename(new_path); // try to make the basis directory File::CreateFullPath(new_name); // If there is already something of the same type at the new path, delete it. if (File::Exists(new_name)) { const bool old_is_file = File::IsFile(old_name); const bool new_is_file = File::IsFile(new_name); if (old_is_file && new_is_file) File::Delete(new_name); else if (!old_is_file && !new_is_file) File::DeleteDirRecursively(new_name); else return ResultCode::Invalid; } // finally try to rename the file if (!File::Rename(old_name, new_name)) { ERROR_LOG(IOS_FS, "Rename %s to %s - failed", old_name.c_str(), new_name.c_str()); return ResultCode::NotFound; } return ResultCode::Success; }
ResultCode HostFileSystem::Delete(Uid, Gid, const std::string& path) { if (!IsValidWiiPath(path)) return ResultCode::Invalid; const std::string file_name = BuildFilename(path); if (File::Delete(file_name)) INFO_LOG(IOS_FS, "DeleteFile %s", file_name.c_str()); else if (File::DeleteDirRecursively(file_name)) INFO_LOG(IOS_FS, "DeleteDir %s", file_name.c_str()); else WARN_LOG(IOS_FS, "DeleteFile %s - failed!!!", file_name.c_str()); return ResultCode::Success; }
ResultCode HostFileSystem::CreateFile(Uid, Gid, const std::string& path, FileAttribute, Modes) { std::string file_name(BuildFilename(path)); // check if the file already exist if (File::Exists(file_name)) return ResultCode::AlreadyExists; // create the file File::CreateFullPath(file_name); // just to be sure if (!File::CreateEmptyFile(file_name)) { ERROR_LOG(IOS_FS, "couldn't create new file"); return ResultCode::Invalid; } return ResultCode::Success; }
Result<DirectoryStats> HostFileSystem::GetDirectoryStats(const std::string& wii_path) { if (!IsValidWiiPath(wii_path)) return ResultCode::Invalid; DirectoryStats stats{}; std::string path(BuildFilename(wii_path)); if (File::IsDirectory(path)) { File::FSTEntry parent_dir = File::ScanDirectoryTree(path, true); // add one for the folder itself stats.used_inodes = 1 + (u32)parent_dir.size; u64 total_size = ComputeTotalFileSize(parent_dir); // "Real" size to convert to nand blocks stats.used_clusters = (u32)(total_size / (16 * 1024)); // one block is 16kb } else { WARN_LOG(IOS_FS, "fsBlock failed, cannot find directory: %s", path.c_str()); } return stats; }
TigerVersion OGRTigerDataSource::TigerCheckVersion( TigerVersion nOldVersion, const char *pszFilename ) { if( nOldVersion != TIGER_2002 ) return nOldVersion; char *pszRTCFilename = BuildFilename( pszFilename, "C" ); VSILFILE *fp = VSIFOpenL( pszRTCFilename, "rb" ); CPLFree( pszRTCFilename ); if( fp == nullptr ) return nOldVersion; char szHeader[115]; if( VSIFReadL( szHeader, sizeof(szHeader)-1, 1, fp ) < 1 ) { VSIFCloseL( fp ); return nOldVersion; } VSIFCloseL( fp ); /* -------------------------------------------------------------------- */ /* Is the record length 112? If so, it is an older version */ /* than 2002. */ /* -------------------------------------------------------------------- */ if( szHeader[112] == 10 || szHeader[112] == 13 ) { CPLDebug( "TIGER", "Forcing version back to UA2000 since RTC records are short." ); return TIGER_UA2000; } return nOldVersion; }
int CreateDatabase(DBProvider *pdb) { char buffer[10240]; char *pBuf = buffer; char line[1024]; gchar *szFile = BuildFilename("gnubg.sql"); FILE *fp = g_fopen(szFile, "r"); if (!fp) { g_free(szFile); return FALSE; } buffer[0] = '\0'; while (fgets(line, sizeof(line), fp) != NULL) { char *pLine = line + strlen(line) - 1; while (pLine >= line && isspace(*pLine)) { *pLine = '\0'; pLine--; } pLine = line; while (isspace(*pLine)) pLine++; if (pLine[0] != '-' || pLine[1] != '-') { size_t len = strlen(pLine); if (len > 0) { strcat(buffer, pLine); pBuf += len; if (pLine[len - 1] == ';') { if (!pdb->UpdateCommand(buffer)) { fclose(fp); g_free(szFile); return FALSE; } pBuf = buffer; buffer[0] = '\0'; } } } } if (ferror(fp)) { outputerr(szFile); g_free(szFile); fclose(fp); return FALSE; } g_free(szFile); fclose(fp); pBuf = g_strdup_printf("INSERT INTO control VALUES ('version', %d)", DB_VERSION); pdb->UpdateCommand(pBuf); g_free(pBuf); pdb->Commit(); return TRUE; }
int OGRTigerDataSource::Open( const char * pszFilename, int bTestOpen, char ** papszLimitedFileList ) { pszName = CPLStrdup( pszFilename ); /* -------------------------------------------------------------------- */ /* Is the given path a directory or a regular file? */ /* -------------------------------------------------------------------- */ VSIStatBufL stat; if( VSIStatExL( pszFilename, &stat, VSI_STAT_EXISTS_FLAG | VSI_STAT_NATURE_FLAG ) != 0 || (!VSI_ISDIR(stat.st_mode) && !VSI_ISREG(stat.st_mode)) ) { if( !bTestOpen ) CPLError( CE_Failure, CPLE_AppDefined, "%s is neither a file or directory, Tiger access failed.\n", pszFilename ); return FALSE; } /* -------------------------------------------------------------------- */ /* Build a list of filenames we figure are Tiger files. */ /* -------------------------------------------------------------------- */ char **papszFileList = nullptr; if( VSI_ISREG(stat.st_mode) ) { char szModule[128]; if( strlen(CPLGetFilename(pszFilename)) == 0 ) { return FALSE; } pszPath = CPLStrdup( CPLGetPath(pszFilename) ); strncpy( szModule, CPLGetFilename(pszFilename), sizeof(szModule)-1 ); /* Make sure the buffer is 0 terminated */ szModule[sizeof(szModule)-1] = '\0'; /* And now remove last character of filename */ szModule[strlen(szModule)-1] = '\0'; papszFileList = CSLAddString( papszFileList, szModule ); } else { char **candidateFileList = VSIReadDir( pszFilename ); pszPath = CPLStrdup( pszFilename ); for( int i = 0; candidateFileList != nullptr && candidateFileList[i] != nullptr; i++ ) { size_t nCandidateLen = strlen(candidateFileList[i]); if( papszLimitedFileList != nullptr && CSLFindString(papszLimitedFileList, CPLGetBasename(candidateFileList[i])) == -1 ) { continue; } if( nCandidateLen > 4 && candidateFileList[i][nCandidateLen-4] == '.' && candidateFileList[i][nCandidateLen-1] == '1') { char szModule[128]; snprintf( szModule, sizeof(szModule), "%s", candidateFileList[i] ); const size_t nLen = strlen(szModule); if( nLen ) szModule[nLen-1] = '\0'; papszFileList = CSLAddString(papszFileList, szModule); } } CSLDestroy( candidateFileList ); if( CSLCount(papszFileList) == 0 ) { if( !bTestOpen ) CPLError( CE_Failure, CPLE_OpenFailed, "No candidate Tiger files (TGR*.RT1) found in\n" "directory: %s", pszFilename ); CSLDestroy(papszFileList); return FALSE; } } /* -------------------------------------------------------------------- */ /* Loop over all these files trying to open them. In testopen */ /* mode we first read the first 80 characters, to verify that */ /* it looks like an Tiger file. Note that we don't keep the file */ /* open ... we don't want to occupy a lot of file handles when */ /* handling a whole directory. */ /* -------------------------------------------------------------------- */ papszModules = nullptr; for( int i = 0; papszFileList && papszFileList[i] != nullptr; i++ ) { if( bTestOpen || i == 0 ) { char *l_pszFilename = BuildFilename( papszFileList[i], "1" ); VSILFILE *fp = VSIFOpenL( l_pszFilename, "rb" ); CPLFree( l_pszFilename ); if( fp == nullptr ) continue; char szHeader[500] = {}; if( VSIFReadL( szHeader, sizeof(szHeader)-1, 1, fp ) < 1 ) { VSIFCloseL( fp ); continue; } VSIFCloseL( fp ); char *pszRecStart = szHeader; szHeader[sizeof(szHeader)-1] = '\0'; bool bIsGDT = false; if( STARTS_WITH_CI(pszRecStart, "Copyright (C)") && strstr(pszRecStart,"Geographic Data Tech") != nullptr ) { bIsGDT = true; while( *pszRecStart != '\0' && *pszRecStart != 10 && *pszRecStart != 13 ) pszRecStart++; while( *pszRecStart == 10 || *pszRecStart == 13 ) pszRecStart++; } if( pszRecStart[0] != '1' ) continue; if( !isdigit(pszRecStart[1]) || !isdigit(pszRecStart[2]) || !isdigit(pszRecStart[3]) || !isdigit(pszRecStart[4]) ) continue; nVersionCode = atoi(TigerFileBase::GetField( pszRecStart, 2, 5 )); nVersion = TigerClassifyVersion( nVersionCode ); nVersion = TigerCheckVersion( nVersion, papszFileList[i] ); CPLDebug( "OGR", "Tiger Version Code=%d, Classified as %s ", nVersionCode, TigerVersionString(nVersion) ); if( nVersionCode != 0 && nVersionCode != 2 && nVersionCode != 3 && nVersionCode != 5 && nVersionCode != 21 && nVersionCode != 24 && pszRecStart[3] != '9' && pszRecStart[3] != DIGIT_ZERO && !bIsGDT ) continue; // we could (and should) add a bunch more validation here. } papszModules = CSLAddString( papszModules, papszFileList[i] ); } CSLDestroy( papszFileList ); nModules = CSLCount( papszModules ); if( nModules == 0 || papszModules == nullptr ) { if( !bTestOpen ) { if( VSI_ISREG(stat.st_mode) ) CPLError( CE_Failure, CPLE_OpenFailed, "No TIGER/Line files (TGR*.RT1) found in\n" "directory: %s", pszFilename ); else CPLError( CE_Failure, CPLE_OpenFailed, "File %s does not appear to be a TIGER/Line .RT1 file.", pszFilename ); } return FALSE; } /* -------------------------------------------------------------------- */ /* Do we have a user provided version override? */ /* -------------------------------------------------------------------- */ const char *pszRequestedVersion = CPLGetConfigOption( "TIGER_VERSION", nullptr ); if( pszRequestedVersion != nullptr ) { if( STARTS_WITH_CI(pszRequestedVersion, "TIGER_") ) { int iCode = 1; // Used after for. for( ; iCode < TIGER_Unknown; iCode++ ) { if( EQUAL(TigerVersionString((TigerVersion)iCode), pszRequestedVersion) ) { nVersion = (TigerVersion) iCode; break; } } if( iCode == TIGER_Unknown ) { CPLError( CE_Failure, CPLE_AppDefined, "Failed to recognise TIGER_VERSION setting: %s", pszRequestedVersion ); return FALSE; } CPLDebug( "OGR", "OVERRIDE Tiger Version %s ", TigerVersionString(nVersion) ); } else { nVersionCode = atoi(pszRequestedVersion); nVersion = TigerClassifyVersion( nVersionCode ); CPLDebug( "OGR", "OVERRIDE Tiger Version Code=%d, Classified as %s ", nVersionCode, TigerVersionString(nVersion) ); } } /* -------------------------------------------------------------------- */ /* Create the layers which appear to exist. */ /* -------------------------------------------------------------------- */ // RT1, RT2, RT3 AddLayer( new OGRTigerLayer( this, new TigerCompleteChain( this, papszModules[0]) )); /* should we have kept track of whether we encountered an RT4 file? */ // RT4 AddLayer( new OGRTigerLayer( this, new TigerAltName( this, papszModules[0]) )); // RT5 AddLayer( new OGRTigerLayer( this, new TigerFeatureIds( this, papszModules[0]) )); // RT6 AddLayer( new OGRTigerLayer( this, new TigerZipCodes( this, papszModules[0]) )); // RT7 AddLayer( new OGRTigerLayer( this, new TigerLandmarks( this, papszModules[0]) )); // RT8 AddLayer( new OGRTigerLayer( this, new TigerAreaLandmarks( this, papszModules[0]) )); // RT9 if (nVersion < TIGER_2002) { AddLayer( new OGRTigerLayer( this, new TigerKeyFeatures( this, papszModules[0]) )); } // RTA, RTS AddLayer( new OGRTigerLayer( this, new TigerPolygon( this, papszModules[0]) )); // RTB if (nVersion >= TIGER_2002) { AddLayer( new OGRTigerLayer( this, new TigerPolygonCorrections( this, papszModules[0]) )); } // RTC AddLayer( new OGRTigerLayer( this, new TigerEntityNames( this, papszModules[0]) )); // RTE if (nVersion >= TIGER_2002) { AddLayer( new OGRTigerLayer( this, new TigerPolygonEconomic( this, papszModules[0]) )); } // RTH AddLayer( new OGRTigerLayer( this, new TigerIDHistory( this, papszModules[0]) )); // RTI AddLayer( new OGRTigerLayer( this, new TigerPolyChainLink( this, papszModules[0]) )); // RTM AddLayer( new OGRTigerLayer( this, new TigerSpatialMetadata( this, papszModules[0] ) ) ); // RTP AddLayer( new OGRTigerLayer( this, new TigerPIP( this, papszModules[0]) )); // RTR AddLayer( new OGRTigerLayer( this, new TigerTLIDRange( this, papszModules[0]) )); // RTT if (nVersion >= TIGER_2002) { AddLayer( new OGRTigerLayer( this, new TigerZeroCellID( this, papszModules[0]) )); } // RTU if (nVersion >= TIGER_2002) { AddLayer( new OGRTigerLayer( this, new TigerOverUnder( this, papszModules[0]) )); } // RTZ AddLayer( new OGRTigerLayer( this, new TigerZipPlus4( this, papszModules[0]) )); return TRUE; }
void HostFileSystem::DoState(PointerWrap& p) { p.Do(m_root_path); // Temporarily close the file, to prevent any issues with the savestating of /tmp for (Handle& handle : m_handles) handle.host_file.reset(); // handle /tmp std::string Path = BuildFilename("/tmp"); if (p.GetMode() == PointerWrap::MODE_READ) { File::DeleteDirRecursively(Path); File::CreateDir(Path); // now restore from the stream while (1) { char type = 0; p.Do(type); if (!type) break; std::string file_name; p.Do(file_name); std::string name = Path + "/" + file_name; switch (type) { case 'd': { File::CreateDir(name); break; } case 'f': { u32 size = 0; p.Do(size); File::IOFile handle(name, "wb"); char buf[65536]; u32 count = size; while (count > 65536) { p.DoArray(buf); handle.WriteArray(&buf[0], 65536); count -= 65536; } p.DoArray(&buf[0], count); handle.WriteArray(&buf[0], count); break; } } } } else { // recurse through tmp and save dirs and files File::FSTEntry parent_entry = File::ScanDirectoryTree(Path, true); std::deque<File::FSTEntry> todo; todo.insert(todo.end(), parent_entry.children.begin(), parent_entry.children.end()); while (!todo.empty()) { File::FSTEntry& entry = todo.front(); std::string name = entry.physicalName; name.erase(0, Path.length() + 1); char type = entry.isDirectory ? 'd' : 'f'; p.Do(type); p.Do(name); if (entry.isDirectory) { todo.insert(todo.end(), entry.children.begin(), entry.children.end()); } else { u32 size = (u32)entry.size; p.Do(size); File::IOFile handle(entry.physicalName, "rb"); char buf[65536]; u32 count = size; while (count > 65536) { handle.ReadArray(&buf[0], 65536); p.DoArray(buf); count -= 65536; } handle.ReadArray(&buf[0], count); p.DoArray(&buf[0], count); } todo.pop_front(); } char type = 0; p.Do(type); } for (Handle& handle : m_handles) { p.Do(handle.opened); p.Do(handle.mode); p.Do(handle.wii_path); p.Do(handle.file_offset); if (handle.opened) handle.host_file = OpenHostFile(BuildFilename(handle.wii_path)); } }