DAT2::type_filelist::const_iterator DAT2::findFileEntry(const std::string& path) const { // Either the normalization is bogus, or we have to do // it here, too. Otherwise we can't load the files returned // by listFiles. std::string name = path; // Normalize the path if (name.find("./") == 0) { name.erase(0, 2); } type_filelist::const_iterator i = m_filelist.find(name); // We might have another chance to find the file // if the number of file entries not zero. if ( m_filecount && i == m_filelist.end()) { FL_LOG(_log, LMsg("MFFalloutDAT2") << "Missing '" << name << "' in partially(" << m_filecount <<") loaded "<< m_datpath); while( m_filecount && i == m_filelist.end()) { readFileEntry(); i = m_filelist.find(name); } } return i; }
std::set<std::string> DAT2::list(const std::string& pathstr, bool dirs) const { std::set<std::string> list; std::string path = pathstr; // Force loading the complete file entries // This is a costly operation... right after startup. // Later this should do nothing. while( m_filecount ) { readFileEntry(); } // Normalize the path if (path.find("./") == 0) { path.erase(0, 2); } size_t lastIndex = path.size(); if (lastIndex != 0 && path[lastIndex-1] != '/') { path += '/'; } type_filelist::const_iterator end = m_filelist.end(); for (type_filelist::const_iterator i = m_filelist.begin(); i != end; ++i) { const std::string& file = i->first; if (file.find(path) == 0) { std::string cleanedfile = file.substr(path.size(), file.size()); // strip the pathstr bool isdir = cleanedfile.find('/') != std::string::npos; // if we still have a / it's a subdir if (isdir) { cleanedfile = cleanedfile.substr(0, cleanedfile.find('/')); if (cleanedfile.find('/') != cleanedfile.rfind('/')) { // check if this is a direct subdir continue; } } if (isdir == dirs) { list.insert(cleanedfile); } } } return list; }
int main(int argc, char** argv){ int i; FILEENTRY fe; // open image and read bootsector FILE * f = fopen(argv[1],"r"); BOOTSECTOR bs = readBootsector (f); // change to / fseek(f,getRootDir(&bs),SEEK_SET); // change to requested directory char* path = argv[2]; char buffer [9]; // buffer to read until next / int j = 0; for ( i = 1; path[i-1] != 0; ++i ){ if ( path[i] == '/' || path[i] == 0 ){ if ( j == 0 ) break; while ( j < 8 ) buffer[j++] = ' '; if ( !changeWorkDir(f,&bs,buffer) ) return 1; j = 0; } else { buffer[j] = path[i]; j++; } } // list files while ( 1 ){ // read file entry fe = readFileEntry(f); // print file entries if ( fe.name [0] == 0 ) break; if ( fe.name [0] != FILE_ENTRY_ERASED && fe.flags != FILE_ENTRY_IGNORABLE ){ printFileEntry(&fe); } } return 0; }
// change work dir int changeWorkDir (FILE* f, BOOTSECTOR* bs, char* dir){ FILEENTRY fe; int pos; while ( 1 ){ // read file entry fe = readFileEntry(f); // last entry reached? if ( fe.name [0] == 0 ){ printf("dir '%s' not found\n",dir); return 0; } // dir found? if ( fe.name [0] != FILE_ENTRY_ERASED && fe.flags == FILE_ENTRY_DIRECTORY ){ if ( dirstrcmp(fe.name,dir) ){ // yes! we've found it printf("changing work dir to '%s'\n",dir); seekCluster(f,bs,fe.data); return 1; } } } }
void MergeLineSection::readLineSect( MergeFile * file, MergeOffset& moff ) //------------------------------------------------------------------------ { MergeOffset startOff = moff;// offset of start of line section uint_16 i; const char * string; MergeStringHdl name; uint_32 lineEnd; // offset of end of compunit's line info uint_8 opcode; // standard opcode uint_32 oplen; uint_32 extopcode; uint_32 total_length; // length of compunit's line information uint_16 version; uint_32 prologue_length; // length of prologue for this compunit uint_8 op_base; // number of first special opcode uint_8 * standard_opcode_lengths; total_length = file->readDWord( DR_DEBUG_LINE, moff.offset ); version = file->readWord( DR_DEBUG_LINE, moff.offset ); prologue_length = file->readDWord( DR_DEBUG_LINE, moff.offset ); lineEnd = startOff.offset + sizeof(uint_32) + total_length; // skip minimum_instruction_length, default_is_stmt, line_base, line_range moff.offset += 1 + 1 + 1 + 1; op_base = file->readByte( DR_DEBUG_LINE, moff.offset ); standard_opcode_lengths = new uint_8[ op_base ]; for( i = 0; i < op_base - 1; i += 1 ) { standard_opcode_lengths[ i ] = file->readByte( DR_DEBUG_LINE, moff.offset ); } // directory indicies start at 1 for( i = 1; moff.offset < lineEnd; i += 1 ) { string = file->readString( DR_DEBUG_LINE, moff.offset ); if( string == NULL ) break; // <------- end of directories name = string; addDirectory( moff.fileIdx, i, name ); } for( i = 1; moff.offset < lineEnd; i += 1 ) { if( !readFileEntry( file, moff, i ) ) break; // <----- end of files } while( moff.offset < lineEnd ) { opcode = file->readByte( DR_DEBUG_LINE, moff.offset ); if( opcode == 0 ) { // extended opcode oplen = file->readULEB128( DR_DEBUG_LINE, moff.offset ); extopcode = file->readULEB128( DR_DEBUG_LINE, moff.offset ); if( extopcode == DW_LNE_define_file ) { readFileEntry( file, moff, i ); i += 1; } else { moff.offset += oplen; // skip unwanted extended opcode } } else { if( opcode < op_base ) { if( opcode == DW_LNS_fixed_advance_pc ) { moff.offset += sizeof(unsigned_16); // it's a fixed size } else { // it's variable # of leb's oplen = standard_opcode_lengths[opcode]; while( oplen > 0 ) { file->readULEB128( DR_DEBUG_LINE, moff.offset ); // skip oplen--; } } } else { // it was a special opcode, only one byte long, so we // already skipped it } } } delete standard_opcode_lengths; }