// distribution boxbackup-0.10 (svn version: 494) // // Copyright (c) 2003 - 2006 // Ben Summers and contributors. All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // 3. All use of this software and associated advertising materials must // display the following acknowledgment: // This product includes software developed by Ben Summers. // 4. The names of the Authors may not be used to endorse or promote // products derived from this software without specific prior written // permission. // // [Where legally impermissible the Authors do not disclaim liability for // direct physical injury or death caused solely by defects in the software // unless it is modified by a third party.] // // THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE // DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. // // // // -------------------------------------------------------------------------- // // File // Name: BackupStoreObjectDump.cpp // Purpose: Implementations of dumping objects to stdout/TRACE // Created: 3/5/04 // // -------------------------------------------------------------------------- #include "Box.h" #include #include #include #include "BackupStoreDirectory.h" #include "BackupStoreFile.h" #include "BackupStoreFileWire.h" #include "autogen_BackupStoreException.h" #include "BackupStoreFilename.h" #include "BackupClientFileAttributes.h" #include "BackupStoreObjectMagic.h" #include "MemLeakFindOn.h" // -------------------------------------------------------------------------- // // Function // Name: static void OutputLine(FILE *, bool, const char *, ...) // Purpose: Output a line for the object dumping, to file and/or trace... // Created: 3/5/04 // // -------------------------------------------------------------------------- static void OutputLine(FILE *file, bool ToTrace, const char *format, ...) { char text[512]; int r = 0; va_list ap; va_start(ap, format); r = vsnprintf(text, sizeof(text), format, ap); va_end(ap); if(file != 0) { ::fprintf(file, "%s", text); } if(ToTrace) { TRACE1("%s", text); } } // -------------------------------------------------------------------------- // // Function // Name: BackupStoreDirectory::Dump(void *clibFileHandle, bool ToTrace) // Purpose: (first arg is FILE *, but avoid including stdio.h everywhere) // Dump the contents to a file, or trace. // Created: 3/5/04 // // -------------------------------------------------------------------------- void BackupStoreDirectory::Dump(void *clibFileHandle, bool ToTrace) { FILE *file = (FILE*)clibFileHandle; OutputLine(file, ToTrace, "Directory object.\nObject ID: %llx\nContainer ID: %llx\nNumber entries: %d\n"\ "Attributes mod time: %llx\nAttributes size: %d\n", mObjectID, mContainerID, mEntries.size(), mAttributesModTime, mAttributes.GetSize()); // So repeated filenames can be illustrated, even though they can't be decoded std::map nameNum; int nameNumI = 0; // Dump items OutputLine(file, ToTrace, "Items:\nID Size AttrHash AtSz NSz NIdx Flags\n"); for(std::vector::const_iterator i(mEntries.begin()); i != mEntries.end(); ++i) { // Choose file name index number for this file std::map::iterator nn(nameNum.find((*i)->GetName())); int ni = nameNumI; if(nn != nameNum.end()) { ni = nn->second; } else { nameNum[(*i)->GetName()] = nameNumI; ++nameNumI; } // Do dependencies char depends[128]; depends[0] = '\0'; int depends_l = 0; if((*i)->GetDependsNewer() != 0) { #ifdef _MSC_VER depends_l += ::sprintf(depends + depends_l, " depNew(%I64x)", (*i)->GetDependsNewer()); #else depends_l += ::sprintf(depends + depends_l, " depNew(%llx)", (long long)((*i)->GetDependsNewer())); #endif } if((*i)->GetDependsOlder() != 0) { #ifdef _MSC_VER depends_l += ::sprintf(depends + depends_l, " depOld(%I64x)", (*i)->GetDependsOlder()); #else depends_l += ::sprintf(depends + depends_l, " depOld(%llx)", (long long)((*i)->GetDependsOlder())); #endif } // Output item int16_t f = (*i)->GetFlags(); OutputLine(file, ToTrace, "%06llx %4lld %016llx %4d %3d %4d%s%s%s%s%s%s\n", (*i)->GetObjectID(), (*i)->GetSizeInBlocks(), (*i)->GetAttributesHash(), (*i)->GetAttributes().GetSize(), (*i)->GetName().size(), ni, ((f & BackupStoreDirectory::Entry::Flags_File)?" file":""), ((f & BackupStoreDirectory::Entry::Flags_Dir)?" dir":""), ((f & BackupStoreDirectory::Entry::Flags_Deleted)?" del":""), ((f & BackupStoreDirectory::Entry::Flags_OldVersion)?" old":""), ((f & BackupStoreDirectory::Entry::Flags_RemoveASAP)?" removeASAP":""), depends); } } // -------------------------------------------------------------------------- // // Function // Name: BackupStoreFile::DumpFile(void *, bool, IOStream &) // Purpose: (first arg is FILE *, but avoid including stdio.h everywhere) // Dump the contents to a file, or trace. // Created: 4/5/04 // // -------------------------------------------------------------------------- void BackupStoreFile::DumpFile(void *clibFileHandle, bool ToTrace, IOStream &rFile) { FILE *file = (FILE*)clibFileHandle; // Read header file_StreamFormat hdr; if(!rFile.ReadFullBuffer(&hdr, sizeof(hdr), 0 /* not interested in bytes read if this fails */, IOStream::TimeOutInfinite)) { // Couldn't read header THROW_EXCEPTION(BackupStoreException, WhenDecodingExpectedToReadButCouldnt) } // Check and output header info if(hdr.mMagicValue != (int32_t)htonl(OBJECTMAGIC_FILE_MAGIC_VALUE_V1) && hdr.mMagicValue != (int32_t)htonl(OBJECTMAGIC_FILE_MAGIC_VALUE_V0)) { OutputLine(file, ToTrace, "File header doesn't have the correct magic, aborting dump\n"); return; } OutputLine(file, ToTrace, "File object.\nContainer ID: %llx\nModification time: %llx\n"\ "Max block clear size: %d\nOptions: %08x\nNum blocks: %d\n", box_ntoh64(hdr.mContainerID), box_ntoh64(hdr.mModificationTime), ntohl(hdr.mMaxBlockClearSize), ntohl(hdr.mOptions), box_ntoh64(hdr.mNumBlocks)); // Read the next two objects BackupStoreFilename fn; fn.ReadFromStream(rFile, IOStream::TimeOutInfinite); OutputLine(file, ToTrace, "Filename size: %d\n", fn.size()); BackupClientFileAttributes attr; attr.ReadFromStream(rFile, IOStream::TimeOutInfinite); OutputLine(file, ToTrace, "Attributes size: %d\n", attr.GetSize()); // Dump the blocks rFile.Seek(0, IOStream::SeekType_Absolute); BackupStoreFile::MoveStreamPositionToBlockIndex(rFile); // Read in header file_BlockIndexHeader bhdr; rFile.ReadFullBuffer(&bhdr, sizeof(bhdr), 0); if(bhdr.mMagicValue != (int32_t)htonl(OBJECTMAGIC_FILE_BLOCKS_MAGIC_VALUE_V1) && bhdr.mMagicValue != (int32_t)htonl(OBJECTMAGIC_FILE_BLOCKS_MAGIC_VALUE_V0)) { OutputLine(file, ToTrace, "WARNING: Block header doesn't have the correct magic\n"); } // number of blocks int64_t nblocks = box_ntoh64(bhdr.mNumBlocks); OutputLine(file, ToTrace, "Other file ID (for block refs): %llx\nNum blocks (in blk hdr): %lld\n", box_ntoh64(bhdr.mOtherFileID), nblocks); // Dump info about each block OutputLine(file, ToTrace, "======== ===== ==========\n Index Where EncSz/Idx\n"); int64_t nnew = 0, nold = 0; for(int64_t b = 0; b < nblocks; ++b) { file_BlockIndexEntry en; if(!rFile.ReadFullBuffer(&en, sizeof(en), 0)) { OutputLine(file, ToTrace, "Didn't manage to read block %lld from file\n", b); continue; } int64_t s = box_ntoh64(en.mEncodedSize); if(s > 0) { nnew++; TRACE2("%8lld this s=%8lld\n", b, s); } else { nold++; TRACE2("%8lld other i=%8lld\n", b, 0 - s); } } TRACE0("======== ===== ==========\n"); }