예제 #1
0
파일: FS.cpp 프로젝트: TurboK234/dolphin
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;
}
예제 #2
0
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;
}
예제 #3
0
ResultCode HostFileSystem::Format(Uid uid)
{
  const std::string root = BuildFilename("/");
  if (!File::DeleteDirRecursively(root) || !File::CreateDir(root))
    return ResultCode::UnknownError;
  return ResultCode::Success;
}
예제 #4
0
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;
}
예제 #5
0
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;
}
예제 #6
0
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;
}
예제 #7
0
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;
}
예제 #8
0
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;
}
예제 #9
0
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;
}
예제 #10
0
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;
}
예제 #11
0
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;
}
예제 #12
0
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));
  }
}