summaryrefslogtreecommitdiff
path: root/indra/llvfs/llvfs.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llvfs/llvfs.cpp')
-rw-r--r--indra/llvfs/llvfs.cpp389
1 files changed, 184 insertions, 205 deletions
diff --git a/indra/llvfs/llvfs.cpp b/indra/llvfs/llvfs.cpp
index 417e48c07c..c1fe21c57d 100644
--- a/indra/llvfs/llvfs.cpp
+++ b/indra/llvfs/llvfs.cpp
@@ -2,30 +2,25 @@
* @file llvfs.cpp
* @brief Implementation of virtual file system
*
- * $LicenseInfo:firstyear=2002&license=viewergpl$
- *
- * Copyright (c) 2002-2007, Linden Research, Inc.
- *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
* Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlife.com/developers/opensource/gplv2
+ * Copyright (C) 2010, Linden Research, Inc.
*
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at http://secondlife.com/developers/opensource/flossexception
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
*
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -45,7 +40,9 @@
#endif
#include "llvfs.h"
+
#include "llstl.h"
+#include "lltimer.h"
const S32 FILE_BLOCK_MASK = 0x000003FF; // 1024-byte blocks
const S32 VFS_CLEANUP_SIZE = 5242880; // how much space we free up in a single stroke
@@ -231,9 +228,11 @@ struct LLVFSFileBlock_less
const S32 LLVFSFileBlock::SERIAL_SIZE = 34;
-
-LLVFS::LLVFS(const char *index_filename, const char *data_filename, const BOOL read_only, const U32 presize, const BOOL remove_after_crash)
-: mRemoveAfterCrash(remove_after_crash)
+
+LLVFS::LLVFS(const std::string& index_filename, const std::string& data_filename, const BOOL read_only, const U32 presize, const BOOL remove_after_crash)
+: mRemoveAfterCrash(remove_after_crash),
+ mDataFP(NULL),
+ mIndexFP(NULL)
{
mDataMutex = new LLMutex(0);
@@ -244,29 +243,26 @@ LLVFS::LLVFS(const char *index_filename, const char *data_filename, const BOOL r
}
mValid = VFSVALID_OK;
mReadOnly = read_only;
- mIndexFilename = new char[strlen(index_filename) + 1]; /* Flawfinder: ignore */
- mDataFilename = new char[strlen(data_filename) + 1]; /* Flawfinder: ignore */
- if (mIndexFilename == NULL || mDataFilename == NULL)
- {
- llerrs << "Memory Allocation Failure" << llendl;
- return;
- }
- strcpy(mIndexFilename, index_filename); /* Flawfinder: ignore */
- strcpy(mDataFilename, data_filename); /* Flawfinder: ignore */
+ mIndexFilename = index_filename;
+ mDataFilename = data_filename;
const char *file_mode = mReadOnly ? "rb" : "r+b";
- if (! (mDataFP = openAndLock(mDataFilename, file_mode, mReadOnly)))
+ LL_INFOS("VFS") << "Attempting to open VFS index file " << mIndexFilename << LL_ENDL;
+ LL_INFOS("VFS") << "Attempting to open VFS data file " << mDataFilename << LL_ENDL;
+
+ mDataFP = openAndLock(mDataFilename, file_mode, mReadOnly);
+ if (!mDataFP)
{
-
if (mReadOnly)
{
- llwarns << "Can't find " << mDataFilename << " to open read-only VFS" << llendl;
+ LL_WARNS("VFS") << "Can't find " << mDataFilename << " to open read-only VFS" << LL_ENDL;
mValid = VFSVALID_BAD_CANNOT_OPEN_READONLY;
return;
}
-
- if((mDataFP = openAndLock(mDataFilename, "w+b", FALSE)))
+
+ mDataFP = openAndLock(mDataFilename, "w+b", FALSE);
+ if (mDataFP)
{
// Since we're creating this data file, assume any index file is bogus
// remove the index, since this vfs is now blank
@@ -274,56 +270,12 @@ LLVFS::LLVFS(const char *index_filename, const char *data_filename, const BOOL r
}
else
{
- llwarns << "Can't open VFS data file " << mDataFilename << " attempting to use alternate" << llendl;
-
- char *temp_index = new char[strlen(mIndexFilename) + 10]; /* Flawfinder: ignore */
- if (!temp_index)
- {
- llerrs << "Out of the memory in LLVFS::LLVFS(const char *index_filename, const char *data_filename, const BOOL read_only, const U32 presize, const BOOL remove_after_crash)" << llendl;
- return;
- }
- char *temp_data = new char[strlen(mDataFilename) + 10]; /* Flawfinder: ignore */
- if (!temp_data)
- {
- llerrs << "Out of the memory in LLVFS::LLVFS(const char *index_filename, const char *data_filename, const BOOL read_only, const U32 presize, const BOOL remove_after_crash)" << llendl;
- return;
- }
-
- for (U32 count = 0; count < 256; count++)
- {
- sprintf(temp_index, "%s.%u", mIndexFilename, count); /* Flawfinder: ignore */
- sprintf(temp_data, "%s.%u", mDataFilename, count); /* Flawfinder: ignore */
-
- // try just opening, then creating, each alternate
- if ((mDataFP = openAndLock(temp_data, "r+b", FALSE)))
- {
- break;
- }
-
- if ((mDataFP = openAndLock(temp_data, "w+b", FALSE)))
- {
- // we're creating the datafile, so nuke the indexfile
- LLFile::remove(temp_index);
- break;
- }
- }
-
- if (! mDataFP)
- {
- llwarns << "Couldn't open vfs data file after trying many alternates" << llendl;
- mValid = VFSVALID_BAD_CANNOT_CREATE;
- delete[] temp_index;
- delete[] temp_data;
- return;
- }
-
- delete[] mIndexFilename;
- delete[] mDataFilename;
-
- mIndexFilename = temp_index;
- mDataFilename = temp_data;
+ LL_WARNS("VFS") << "Couldn't open vfs data file "
+ << mDataFilename << LL_ENDL;
+ mValid = VFSVALID_BAD_CANNOT_CREATE;
+ return;
}
-
+
if (presize)
{
presizeDataFile(presize);
@@ -335,20 +287,14 @@ LLVFS::LLVFS(const char *index_filename, const char *data_filename, const BOOL r
if (!mReadOnly && mRemoveAfterCrash)
{
llstat marker_info;
- char* marker = new char[strlen(mDataFilename) + strlen(".open") + 1]; /* Flawfinder: ignore */
- if (!marker )
- {
- llerrs << "Out of memory in LLVFS::LLVFS(const char *index_filename, const char *data_filename, const BOOL read_only, const U32 presize, const BOOL remove_after_crash)" << llendl;
- return;
- }
- sprintf(marker, "%s.open", mDataFilename); /* Flawfinder: ignore */
+ std::string marker = mDataFilename + ".open";
if (!LLFile::stat(marker, &marker_info))
{
// marker exists, kill the lock and the VFS files
unlockAndClose(mDataFP);
mDataFP = NULL;
- llwarns << "VFS: File left open on last run, removing old VFS file " << mDataFilename << llendl;
+ LL_WARNS("VFS") << "VFS: File left open on last run, removing old VFS file " << mDataFilename << LL_ENDL;
LLFile::remove(mIndexFilename);
LLFile::remove(mDataFilename);
LLFile::remove(marker);
@@ -356,7 +302,7 @@ LLVFS::LLVFS(const char *index_filename, const char *data_filename, const BOOL r
mDataFP = openAndLock(mDataFilename, "w+b", FALSE);
if (!mDataFP)
{
- llwarns << "Can't open VFS data file in crash recovery" << llendl;
+ LL_WARNS("VFS") << "Can't open VFS data file in crash recovery" << LL_ENDL;
mValid = VFSVALID_BAD_CANNOT_CREATE;
return;
}
@@ -366,8 +312,6 @@ LLVFS::LLVFS(const char *index_filename, const char *data_filename, const BOOL r
presizeDataFile(presize);
}
}
- delete [] marker;
- marker = NULL;
}
// determine the real file size
@@ -380,21 +324,20 @@ LLVFS::LLVFS(const char *index_filename, const char *data_filename, const BOOL r
llstat fbuf;
if (! LLFile::stat(mIndexFilename, &fbuf) &&
fbuf.st_size >= LLVFSFileBlock::SERIAL_SIZE &&
- (mIndexFP = openAndLock(mIndexFilename, file_mode, mReadOnly))
+ (mIndexFP = openAndLock(mIndexFilename, file_mode, mReadOnly)) // Yes, this is an assignment and not '=='
)
{
- U8 *buffer = new U8[fbuf.st_size];
- size_t nread = fread(buffer, 1, fbuf.st_size, mIndexFP);
-
- U8 *tmp_ptr = buffer;
-
+ std::vector<U8> buffer(fbuf.st_size);
+ size_t buf_offset = 0;
+ size_t nread = fread(&buffer[0], 1, fbuf.st_size, mIndexFP);
+
std::vector<LLVFSFileBlock*> files_by_loc;
- while (tmp_ptr < buffer + nread)
+ while (buf_offset < nread)
{
LLVFSFileBlock *block = new LLVFSFileBlock();
- block->deserialize(tmp_ptr, (S32)(tmp_ptr - buffer));
+ block->deserialize(&buffer[buf_offset], (S32)buf_offset);
// Do sanity check on this block.
// Note that this skips zero size blocks, which helps VFS
@@ -414,11 +357,10 @@ LLVFS::LLVFS(const char *index_filename, const char *data_filename, const BOOL r
if (block->mLength && block->mSize > 0)
{
// this is corrupt, not empty
- llwarns << "VFS corruption: " << block->mFileID << " (" << block->mFileType << ") at index " << block->mIndexLocation << " DS: " << data_size << llendl;
- llwarns << "Length: " << block->mLength << "\tLocation: " << block->mLocation << "\tSize: " << block->mSize << llendl;
- llwarns << "File has bad data - VFS removed" << llendl;
+ LL_WARNS("VFS") << "VFS corruption: " << block->mFileID << " (" << block->mFileType << ") at index " << block->mIndexLocation << " DS: " << data_size << LL_ENDL;
+ LL_WARNS("VFS") << "Length: " << block->mLength << "\tLocation: " << block->mLocation << "\tSize: " << block->mSize << LL_ENDL;
+ LL_WARNS("VFS") << "File has bad data - VFS removed" << LL_ENDL;
- delete[] buffer;
delete block;
unlockAndClose( mIndexFP );
@@ -429,21 +371,25 @@ LLVFS::LLVFS(const char *index_filename, const char *data_filename, const BOOL r
mDataFP = NULL;
LLFile::remove( mDataFilename );
+ LL_WARNS("VFS") << "Deleted corrupt VFS files "
+ << mDataFilename
+ << " and "
+ << mIndexFilename
+ << LL_ENDL;
+
mValid = VFSVALID_BAD_CORRUPT;
return;
}
else
{
// this is a null or bad entry, skip it
- S32 index_loc = (S32)(tmp_ptr - buffer);
- mIndexHoles.push_back(index_loc);
+ mIndexHoles.push_back(buf_offset);
delete block;
}
- tmp_ptr += LLVFSFileBlock::SERIAL_SIZE;
+ buf_offset += LLVFSFileBlock::SERIAL_SIZE;
}
- delete[] buffer;
std::sort(
files_by_loc.begin(),
@@ -481,13 +427,13 @@ LLVFS::LLVFS(const char *index_filename, const char *data_filename, const BOOL r
if (cur_file_block->mLocation == last_file_block->mLocation
&& cur_file_block->mLength == last_file_block->mLength)
{
- llwarns << "VFS: removing duplicate entry"
+ LL_WARNS("VFS") << "VFS: removing duplicate entry"
<< " at " << cur_file_block->mLocation
<< " length " << cur_file_block->mLength
<< " size " << cur_file_block->mSize
<< " ID " << cur_file_block->mFileID
<< " type " << cur_file_block->mFileType
- << llendl;
+ << LL_ENDL;
// Duplicate entries. Nuke them both for safety.
mFileBlocks.erase(*cur_file_block); // remove ID/type entry
@@ -528,12 +474,19 @@ LLVFS::LLVFS(const char *index_filename, const char *data_filename, const BOOL r
mDataFP = NULL;
LLFile::remove( mDataFilename );
- llwarns << "VFS: overlapping entries"
+ LL_WARNS("VFS") << "VFS: overlapping entries"
<< " at " << cur_file_block->mLocation
<< " length " << cur_file_block->mLength
<< " ID " << cur_file_block->mFileID
<< " type " << cur_file_block->mFileType
- << llendl;
+ << LL_ENDL;
+
+ LL_WARNS("VFS") << "Deleted corrupt VFS files "
+ << mDataFilename
+ << " and "
+ << mIndexFilename
+ << LL_ENDL;
+
mValid = VFSVALID_BAD_CORRUPT;
return;
}
@@ -559,11 +512,11 @@ LLVFS::LLVFS(const char *index_filename, const char *data_filename, const BOOL r
addFreeBlock(new LLVFSBlock(0, data_size));
}
}
- else
+ else // Pre-existing index file wasn't opened
{
if (mReadOnly)
{
- llwarns << "Can't find " << mIndexFilename << " to open read-only VFS" << llendl;
+ LL_WARNS("VFS") << "Can't find " << mIndexFilename << " to open read-only VFS" << LL_ENDL;
mValid = VFSVALID_BAD_CANNOT_OPEN_READONLY;
return;
}
@@ -572,7 +525,7 @@ LLVFS::LLVFS(const char *index_filename, const char *data_filename, const BOOL r
mIndexFP = openAndLock(mIndexFilename, "w+b", FALSE);
if (!mIndexFP)
{
- llwarns << "Couldn't open an index file for the VFS, probably a sharing violation!" << llendl;
+ LL_WARNS("VFS") << "Couldn't open an index file for the VFS, probably a sharing violation!" << LL_ENDL;
unlockAndClose( mDataFP );
mDataFP = NULL;
@@ -590,24 +543,17 @@ LLVFS::LLVFS(const char *index_filename, const char *data_filename, const BOOL r
// Open marker file to look for bad shutdowns
if (!mReadOnly && mRemoveAfterCrash)
{
- char* marker = new char[strlen(mDataFilename) + strlen(".open") + 1];
- if (!marker)
- {
- llerrs << "Out of memory in LLVFS::LLVFS(const char *index_filename, const char *data_filename, const BOOL read_only, const U32 presize, const BOOL remove_after_crash)" << llendl;
- return;
- }
- sprintf(marker, "%s.open", mDataFilename); /* Flawfinder: ignore */
- FILE* marker_fp = LLFile::fopen(marker, "w"); /* Flawfinder: ignore */
+ std::string marker = mDataFilename + ".open";
+ LLFILE* marker_fp = LLFile::fopen(marker, "w"); /* Flawfinder: ignore */
if (marker_fp)
{
fclose(marker_fp);
marker_fp = NULL;
}
- delete [] marker;
- marker = NULL;
}
- llinfos << "VFS: Using index file " << mIndexFilename << " and data file " << mDataFilename << llendl;
+ LL_INFOS("VFS") << "Using VFS index file " << mIndexFilename << LL_ENDL;
+ LL_INFOS("VFS") << "Using VFS data file " << mDataFilename << LL_ENDL;
mValid = VFSVALID_OK;
}
@@ -616,7 +562,7 @@ LLVFS::~LLVFS()
{
if (mDataMutex->isLocked())
{
- llerrs << "LLVFS destroyed with mutex locked" << llendl;
+ LL_ERRS("VFS") << "LLVFS destroyed with mutex locked" << LL_ENDL;
}
unlockAndClose(mIndexFP);
@@ -639,26 +585,54 @@ LLVFS::~LLVFS()
// Remove marker file
if (!mReadOnly && mRemoveAfterCrash)
{
- char* marker_file = new char[strlen(mDataFilename) + strlen(".open") + 1];
- if (marker_file == NULL)
- {
- llerrs << "Memory Allocation Failure" << llendl;
- return;
+ std::string marker = mDataFilename + ".open";
+ LLFile::remove(marker);
+ }
+
+ delete mDataMutex;
+}
+
+
+// Use this function normally to create LLVFS files.
+// Will append digits to the end of the filename with multiple re-trys
+// static
+LLVFS * LLVFS::createLLVFS(const std::string& index_filename,
+ const std::string& data_filename,
+ const BOOL read_only,
+ const U32 presize,
+ const BOOL remove_after_crash)
+{
+ LLVFS * new_vfs = new LLVFS(index_filename, data_filename, read_only, presize, remove_after_crash);
+
+ if( !new_vfs->isValid() )
+ { // First name failed, retry with new names
+ std::string retry_vfs_index_name;
+ std::string retry_vfs_data_name;
+ S32 count = 0;
+ while (!new_vfs->isValid() &&
+ count < 256)
+ { // Append '.<number>' to end of filenames
+ retry_vfs_index_name = index_filename + llformat(".%u",count);
+ retry_vfs_data_name = data_filename + llformat(".%u", count);
+
+ delete new_vfs; // Delete bad VFS and try again
+ new_vfs = new LLVFS(retry_vfs_index_name, retry_vfs_data_name, read_only, presize, remove_after_crash);
+
+ count++;
}
- sprintf(marker_file, "%s.open", mDataFilename); /* Flawfinder: ignore */
- LLFile::remove(marker_file);
- delete [] marker_file;
- marker_file = NULL;
}
- delete[] mIndexFilename;
- mIndexFilename = NULL;
- delete[] mDataFilename;
- mDataFilename = NULL;
+ if( !new_vfs->isValid() )
+ {
+ delete new_vfs; // Delete bad VFS
+ new_vfs = NULL; // Total failure
+ }
- delete mDataMutex;
+ return new_vfs;
}
+
+
void LLVFS::presizeDataFile(const U32 size)
{
if (!mDataFP)
@@ -767,8 +741,14 @@ S32 LLVFS::getMaxSize(const LLUUID &file_id, const LLAssetType::EType file_type
BOOL LLVFS::checkAvailable(S32 max_size)
{
+ lockData();
+
blocks_length_map_t::iterator iter = mFreeBlocksByLength.lower_bound(max_size); // first entry >= size
- return (iter == mFreeBlocksByLength.end()) ? FALSE : TRUE;
+ const BOOL res(iter == mFreeBlocksByLength.end() ? FALSE : TRUE);
+
+ unlockData();
+
+ return res;
}
BOOL LLVFS::setMaxSize(const LLUUID &file_id, const LLAssetType::EType file_type, S32 max_size)
@@ -874,40 +854,42 @@ BOOL LLVFS::setMaxSize(const LLUUID &file_id, const LLAssetType::EType file_type
if (free_block)
{
+ // Save location where data is going, useFreeSpace will move free_block->mLocation;
+ U32 new_data_location = free_block->mLocation;
+
+ //mark the free block as used so it does not
+ //interfere with other operations such as addFreeBlock
+ useFreeSpace(free_block, max_size); // useFreeSpace takes ownership (and may delete) free_block
+
if (block->mLength > 0)
{
// create a new free block where this file used to be
LLVFSBlock *new_free_block = new LLVFSBlock(block->mLocation, block->mLength);
addFreeBlock(new_free_block);
-
+
if (block->mSize > 0)
{
// move the file into the new block
- U8 *buffer = new U8[block->mSize];
+ std::vector<U8> buffer(block->mSize);
fseek(mDataFP, block->mLocation, SEEK_SET);
- if (fread(buffer, block->mSize, 1, mDataFP) == 1)
+ if (fread(&buffer[0], block->mSize, 1, mDataFP) == 1)
{
- fseek(mDataFP, free_block->mLocation, SEEK_SET);
- if (fwrite(buffer, block->mSize, 1, mDataFP) != 1)
+ fseek(mDataFP, new_data_location, SEEK_SET);
+ if (fwrite(&buffer[0], block->mSize, 1, mDataFP) != 1)
{
llwarns << "Short write" << llendl;
}
} else {
llwarns << "Short read" << llendl;
}
-
- delete[] buffer;
}
}
- block->mLocation = free_block->mLocation;
+ block->mLocation = new_data_location;
block->mLength = max_size;
- // Must call useFreeSpace before sync(), as sync()
- // unlocks data structures.
- useFreeSpace(free_block, max_size);
sync(block);
@@ -1122,14 +1104,14 @@ S32 LLVFS::getData(const LLUUID &file_id, const LLAssetType::EType file_type, U8
}
}
- unlockData();
-
if (do_read)
{
fseek(mDataFP, location, SEEK_SET);
bytesread = (S32)fread(buffer, 1, length, mDataFP);
}
+ unlockData();
+
return bytesread;
}
@@ -1194,8 +1176,6 @@ S32 LLVFS::storeData(const LLUUID &file_id, const LLAssetType::EType file_type,
}
U32 file_location = location + block->mLocation;
- unlockData();
-
fseek(mDataFP, file_location, SEEK_SET);
S32 write_len = (S32)fwrite(buffer, 1, length, mDataFP);
if (write_len != length)
@@ -1204,7 +1184,6 @@ S32 LLVFS::storeData(const LLUUID &file_id, const LLAssetType::EType file_type,
}
// fflush(mDataFP);
- lockData();
if (location + length > block->mSize)
{
block->mSize = location + write_len;
@@ -1316,7 +1295,7 @@ void LLVFS::eraseBlockLength(LLVFSBlock *block)
}
if(!found_block)
{
- llwarns << "eraseBlock could not find block" << llendl;
+ llerrs << "eraseBlock could not find block" << llendl;
}
}
@@ -1453,7 +1432,7 @@ void LLVFS::addFreeBlock(LLVFSBlock *block)
// }
//}
-
+// length bytes from free_block are going to be used (so they are no longer free)
void LLVFS::useFreeSpace(LLVFSBlock *free_block, S32 length)
{
if (free_block->mLength == length)
@@ -1536,8 +1515,6 @@ void LLVFS::sync(LLVFSFileBlock *block, BOOL remove)
block->serialize(buffer);
}
- unlockData();
-
// If set_index_to_end, file pointer is already at seek_pos
// and we don't need to do anything. Only seek if not at end.
if (!set_index_to_end)
@@ -1549,11 +1526,10 @@ void LLVFS::sync(LLVFSFileBlock *block, BOOL remove)
{
llwarns << "Short write" << llendl;
}
-
+
+ // *NOTE: Why was this commented out?
// fflush(mIndexFP);
- lockData();
-
return;
}
@@ -1730,32 +1706,32 @@ void LLVFS::audit()
fflush(mIndexFP);
fseek(mIndexFP, 0, SEEK_END);
- long index_size = ftell(mIndexFP);
+ size_t index_size = ftell(mIndexFP);
fseek(mIndexFP, 0, SEEK_SET);
BOOL vfs_corrupt = FALSE;
- U8 *buffer = new U8[index_size];
+ std::vector<U8> buffer(index_size);
- if (fread(buffer, 1, index_size, mIndexFP) != index_size)
+ if (fread(&buffer[0], 1, index_size, mIndexFP) != index_size)
{
llwarns << "Index truncated" << llendl;
vfs_corrupt = TRUE;
}
- U8 *tmp_ptr = buffer;
+ size_t buf_offset = 0;
std::map<LLVFSFileSpecifier, LLVFSFileBlock*> found_files;
U32 cur_time = (U32)time(NULL);
std::vector<LLVFSFileBlock*> audit_blocks;
- while (!vfs_corrupt && tmp_ptr < buffer + index_size)
+ while (!vfs_corrupt && buf_offset < index_size)
{
LLVFSFileBlock *block = new LLVFSFileBlock();
audit_blocks.push_back(block);
- block->deserialize(tmp_ptr, (S32)(tmp_ptr - buffer));
- tmp_ptr += block->SERIAL_SIZE;
+ block->deserialize(&buffer[buf_offset], (S32)buf_offset);
+ buf_offset += block->SERIAL_SIZE;
// do sanity check on this block
if (block->mLength >= 0 &&
@@ -1814,8 +1790,6 @@ void LLVFS::audit()
}
}
- delete[] buffer;
-
if (!vfs_corrupt)
{
for (fileblock_map::iterator it = mFileBlocks.begin(); it != mFileBlocks.end(); ++it)
@@ -2041,31 +2015,30 @@ void LLVFS::dumpStatistics()
}
// Debug Only!
-LLString get_extension(LLAssetType::EType type)
+std::string get_extension(LLAssetType::EType type)
{
- LLString extension;
+ std::string extension;
switch(type)
{
- case LLAssetType::AT_TEXTURE:
- extension = ".j2c";
+ case LLAssetType::AT_TEXTURE:
+ extension = ".jp2"; // formerly ".j2c"
break;
- case LLAssetType::AT_SOUND:
+ case LLAssetType::AT_SOUND:
extension = ".ogg";
break;
- case LLAssetType::AT_SOUND_WAV:
+ case LLAssetType::AT_SOUND_WAV:
extension = ".wav";
break;
- case LLAssetType::AT_TEXTURE_TGA:
+ case LLAssetType::AT_TEXTURE_TGA:
extension = ".tga";
break;
- case LLAssetType::AT_IMAGE_JPEG:
- extension = ".jpeg";
- break;
- case LLAssetType::AT_ANIMATION:
+ case LLAssetType::AT_ANIMATION:
extension = ".lla";
break;
- default:
- extension = ".data";
+ default:
+ // Just use the asset server filename extension in most cases
+ extension += ".";
+ extension += LLAssetType::lookup(type);
break;
}
return extension;
@@ -2084,7 +2057,7 @@ void LLVFS::listFiles()
if (length != BLOCK_LENGTH_INVALID && size > 0)
{
LLUUID id = file_spec.mFileID;
- LLString extension = get_extension(file_spec.mFileType);
+ std::string extension = get_extension(file_spec.mFileType);
llinfos << " File: " << id
<< " Type: " << LLAssetType::getDesc(file_spec.mFileType)
<< " Size: " << size
@@ -2100,6 +2073,7 @@ void LLVFS::dumpFiles()
{
lockData();
+ S32 files_extracted = 0;
for (fileblock_map::iterator it = mFileBlocks.begin(); it != mFileBlocks.end(); ++it)
{
LLVFSFileSpecifier file_spec = it->first;
@@ -2110,23 +2084,28 @@ void LLVFS::dumpFiles()
{
LLUUID id = file_spec.mFileID;
LLAssetType::EType type = file_spec.mFileType;
- U8* buffer = new U8[size];
+ std::vector<U8> buffer(size);
unlockData();
- getData(id, type, buffer, 0, size);
+ getData(id, type, &buffer[0], 0, size);
lockData();
- LLString extension = get_extension(type);
- LLString filename = id.asString() + extension;
+ std::string extension = get_extension(type);
+ std::string filename = id.asString() + extension;
llinfos << " Writing " << filename << llendl;
- apr_file_t* file = ll_apr_file_open(filename, LL_APR_WB);
- ll_apr_file_write(file, buffer, size);
- apr_file_close(file);
- delete[] buffer;
+
+ LLAPRFile outfile;
+ outfile.open(filename, LL_APR_WB);
+ outfile.write(&buffer[0], size);
+ outfile.close();
+
+ files_extracted++;
}
}
unlockData();
+
+ llinfos << "Extracted " << files_extracted << " files out of " << mFileBlocks.size() << llendl;
}
//============================================================================
@@ -2134,7 +2113,7 @@ void LLVFS::dumpFiles()
//============================================================================
// static
-FILE *LLVFS::openAndLock(const char *filename, const char *mode, BOOL read_lock)
+LLFILE *LLVFS::openAndLock(const std::string& filename, const char* mode, BOOL read_lock)
{
#if LL_WINDOWS
@@ -2142,7 +2121,7 @@ FILE *LLVFS::openAndLock(const char *filename, const char *mode, BOOL read_lock)
#else
- FILE *fp;
+ LLFILE *fp;
int fd;
// first test the lock in a non-destructive way
@@ -2152,7 +2131,7 @@ FILE *LLVFS::openAndLock(const char *filename, const char *mode, BOOL read_lock)
fl.l_start = 0;
fl.l_len = 1;
#else // !LL_SOLARIS
- if (strstr(mode, "w"))
+ if (strchr(mode, 'w') != NULL)
{
fp = LLFile::fopen(filename, "rb"); /* Flawfinder: ignore */
if (fp)
@@ -2192,7 +2171,7 @@ FILE *LLVFS::openAndLock(const char *filename, const char *mode, BOOL read_lock)
}
// static
-void LLVFS::unlockAndClose(FILE *fp)
+void LLVFS::unlockAndClose(LLFILE *fp)
{
if (fp)
{