1 // distribution boxbackup-0.11_trunk_2979 (svn version: 2979) 2 // Box Backup, http://www.boxbackup.org/ 3 // 4 // Copyright (c) 2003-2010, Ben Summers and contributors. 5 // All rights reserved. 6 // 7 // Note that this project uses mixed licensing. Any file with this license 8 // attached, or where the code LICENSE-GPL appears on the first line, falls 9 // under the "Box Backup GPL" license. See the file COPYING.txt for more 10 // information about this license. 11 // 12 // --------------------------------------------------------------------- 13 // This program is free software; you can redistribute it and/or 14 // modify it under the terms of the GNU General Public License 15 // as published by the Free Software Foundation; either version 2 16 // of the License, or (at your option) any later version. 17 // 18 // This program is distributed in the hope that it will be useful, 19 // but WITHOUT ANY WARRANTY; without even the implied warranty of 20 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 // GNU General Public License for more details. 22 // 23 // You should have received a copy of the GNU General Public License 24 // along with this program; if not, write to the Free Software 25 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 26 // 27 // [http://www.gnu.org/licenses/old-licenses/gpl-2.0.html#SEC4] 28 // 29 // As a special exception to the GPLv2, the Box Backup Project gives 30 // permission to link any code falling under this license (the Box Backup 31 // GPL) with any software that can be downloaded from 32 // the OpenSSL website [http://www.openssl.org] under either the 33 // "OpenSSL License" or the "Original SSLeay License", and to distribute 34 // the linked executables under the terms of the "Box Backup GPL" license. 35 // 36 // As a special exception to the GPLv2, the Box Backup Project gives 37 // permission to link any code falling under this license (the Box Backup 38 // GPL) with any version of Microsoft's Volume Shadow Copy Service 7.2 SDK 39 // or Microsoft Windows Software Development Kit (SDK), including 40 // vssapi.lib, that can be downloaded from the Microsoft website 41 // [*.microsoft.com], and to distribute the linked executables under the 42 // terms of the "Box Backup GPL" license. 43 // -------------------------------------------------------------------------- 44 // 45 // File 46 // Name: BackupStoreDirectory.h 47 // Purpose: Representation of a backup directory 48 // Created: 2003/08/26 49 // 50 // -------------------------------------------------------------------------- 51 52 #ifndef BACKUPSTOREDIRECTORY__H 53 #define BACKUPSTOREDIRECTORY__H 54 55 #include <string> 56 #include <vector> 57 58 #include "BackupStoreFilenameClear.h" 59 #include "StreamableMemBlock.h" 60 #include "BoxTime.h" 61 62 class IOStream; 63 64 // -------------------------------------------------------------------------- 65 // 66 // Class 67 // Name: BackupStoreDirectory 68 // Purpose: In memory representation of a directory 69 // Created: 2003/08/26 70 // 71 // -------------------------------------------------------------------------- 72 class BackupStoreDirectory 73 { 74 public: 75 BackupStoreDirectory(); 76 BackupStoreDirectory(int64_t ObjectID, int64_t ContainerID); 77 private: 78 // Copying not allowed 79 BackupStoreDirectory(const BackupStoreDirectory &rToCopy); 80 public: 81 ~BackupStoreDirectory(); 82 83 class Entry 84 { 85 public: 86 friend class BackupStoreDirectory; 87 88 Entry(); 89 ~Entry(); 90 Entry(const Entry &rToCopy); 91 Entry(const BackupStoreFilename &rName, box_time_t ModificationTime, int64_t ObjectID, int64_t SizeInBlocks, int16_t Flags, uint64_t AttributesHash); 92 93 void ReadFromStream(IOStream &rStream, int Timeout); 94 void WriteToStream(IOStream &rStream) const; 95 GetName()96 const BackupStoreFilename &GetName() const {return mName;} GetModificationTime()97 box_time_t GetModificationTime() const {return mModificationTime;} GetObjectID()98 int64_t GetObjectID() const {return mObjectID;} GetSizeInBlocks()99 int64_t GetSizeInBlocks() const {return mSizeInBlocks;} GetFlags()100 int16_t GetFlags() const {return mFlags;} AddFlags(int16_t Flags)101 void AddFlags(int16_t Flags) {mFlags |= Flags;} RemoveFlags(int16_t Flags)102 void RemoveFlags(int16_t Flags) {mFlags &= ~Flags;} 103 104 // Some things can be changed SetName(const BackupStoreFilename & rNewName)105 void SetName(const BackupStoreFilename &rNewName) {mName = rNewName;} SetSizeInBlocks(int64_t SizeInBlocks)106 void SetSizeInBlocks(int64_t SizeInBlocks) {mSizeInBlocks = SizeInBlocks;} 107 108 // Attributes HasAttributes()109 bool HasAttributes() const {return !mAttributes.IsEmpty();} SetAttributes(const StreamableMemBlock & rAttr,uint64_t AttributesHash)110 void SetAttributes(const StreamableMemBlock &rAttr, uint64_t AttributesHash) {mAttributes.Set(rAttr); mAttributesHash = AttributesHash;} GetAttributes()111 const StreamableMemBlock &GetAttributes() const {return mAttributes;} GetAttributesHash()112 uint64_t GetAttributesHash() const {return mAttributesHash;} 113 114 // Marks 115 // The lowest mark number a version of a file of this name has ever had GetMinMarkNumber()116 uint32_t GetMinMarkNumber() const {return mMinMarkNumber;} 117 // The mark number on this file GetMarkNumber()118 uint32_t GetMarkNumber() const {return mMarkNumber;} 119 120 // Make sure these flags are synced with those in backupprocotol.txt 121 // ListDirectory command 122 enum 123 { 124 Flags_INCLUDE_EVERYTHING = -1, 125 Flags_EXCLUDE_NOTHING = 0, 126 Flags_EXCLUDE_EVERYTHING = 31, // make sure this is kept as sum of ones below! 127 Flags_File = 1, 128 Flags_Dir = 2, 129 Flags_Deleted = 4, 130 Flags_OldVersion = 8, 131 Flags_RemoveASAP = 16 // if this flag is set, housekeeping will remove it as it is marked Deleted or OldVersion 132 }; 133 // characters for textual listing of files -- see bbackupquery/BackupQueries 134 #define BACKUPSTOREDIRECTORY_ENTRY_FLAGS_DISPLAY_NAMES "fdXoR" 135 136 // convenience methods IsDir()137 bool inline IsDir() 138 { 139 return GetFlags() & Flags_Dir; 140 } IsFile()141 bool inline IsFile() 142 { 143 return GetFlags() & Flags_File; 144 } IsOld()145 bool inline IsOld() 146 { 147 return GetFlags() & Flags_OldVersion; 148 } IsDeleted()149 bool inline IsDeleted() 150 { 151 return GetFlags() & Flags_Deleted; 152 } MatchesFlags(int16_t FlagsMustBeSet,int16_t FlagsNotToBeSet)153 bool inline MatchesFlags(int16_t FlagsMustBeSet, int16_t FlagsNotToBeSet) 154 { 155 return ((FlagsMustBeSet == Flags_INCLUDE_EVERYTHING) || ((mFlags & FlagsMustBeSet) == FlagsMustBeSet)) 156 && ((mFlags & FlagsNotToBeSet) == 0); 157 }; 158 159 // Get dependency info 160 // new version this depends on GetDependsNewer()161 int64_t GetDependsNewer() const {return mDependsNewer;} SetDependsNewer(int64_t ObjectID)162 void SetDependsNewer(int64_t ObjectID) {mDependsNewer = ObjectID;} 163 // older version which depends on this GetDependsOlder()164 int64_t GetDependsOlder() const {return mDependsOlder;} SetDependsOlder(int64_t ObjectID)165 void SetDependsOlder(int64_t ObjectID) {mDependsOlder = ObjectID;} 166 167 // Dependency info saving HasDependencies()168 bool HasDependencies() {return mDependsNewer != 0 || mDependsOlder != 0;} 169 void ReadFromStreamDependencyInfo(IOStream &rStream, int Timeout); 170 void WriteToStreamDependencyInfo(IOStream &rStream) const; 171 172 private: 173 BackupStoreFilename mName; 174 box_time_t mModificationTime; 175 int64_t mObjectID; 176 int64_t mSizeInBlocks; 177 int16_t mFlags; 178 uint64_t mAttributesHash; 179 StreamableMemBlock mAttributes; 180 uint32_t mMinMarkNumber; 181 uint32_t mMarkNumber; 182 183 uint64_t mDependsNewer; // new version this depends on 184 uint64_t mDependsOlder; // older version which depends on this 185 }; 186 187 void ReadFromStream(IOStream &rStream, int Timeout); 188 void WriteToStream(IOStream &rStream, 189 int16_t FlagsMustBeSet = Entry::Flags_INCLUDE_EVERYTHING, 190 int16_t FlagsNotToBeSet = Entry::Flags_EXCLUDE_NOTHING, 191 bool StreamAttributes = true, bool StreamDependencyInfo = true) const; 192 193 Entry *AddEntry(const Entry &rEntryToCopy); 194 Entry *AddEntry(const BackupStoreFilename &rName, box_time_t ModificationTime, int64_t ObjectID, int64_t SizeInBlocks, int16_t Flags, box_time_t AttributesModTime); 195 void DeleteEntry(int64_t ObjectID); 196 Entry *FindEntryByID(int64_t ObjectID) const; 197 GetObjectID()198 int64_t GetObjectID() const {return mObjectID;} GetContainerID()199 int64_t GetContainerID() const {return mContainerID;} 200 201 // Need to be able to update the container ID when moving objects SetContainerID(int64_t ContainerID)202 void SetContainerID(int64_t ContainerID) {mContainerID = ContainerID;} 203 204 // Purely for use of server -- not serialised into streams GetRevisionID()205 int64_t GetRevisionID() const {return mRevisionID;} SetRevisionID(int64_t RevisionID)206 void SetRevisionID(int64_t RevisionID) {mRevisionID = RevisionID;} 207 GetNumberOfEntries()208 unsigned int GetNumberOfEntries() const {return mEntries.size();} 209 210 // User info -- not serialised into streams GetUserInfo1_SizeInBlocks()211 int64_t GetUserInfo1_SizeInBlocks() const {return mUserInfo1;} SetUserInfo1_SizeInBlocks(int64_t UserInfo1)212 void SetUserInfo1_SizeInBlocks(int64_t UserInfo1) {mUserInfo1 = UserInfo1;} 213 214 // Attributes HasAttributes()215 bool HasAttributes() const {return !mAttributes.IsEmpty();} SetAttributes(const StreamableMemBlock & rAttr,box_time_t AttributesModTime)216 void SetAttributes(const StreamableMemBlock &rAttr, box_time_t AttributesModTime) {mAttributes.Set(rAttr); mAttributesModTime = AttributesModTime;} GetAttributes()217 const StreamableMemBlock &GetAttributes() const {return mAttributes;} GetAttributesModTime()218 box_time_t GetAttributesModTime() const {return mAttributesModTime;} 219 220 class Iterator 221 { 222 public: Iterator(const BackupStoreDirectory & rDir)223 Iterator(const BackupStoreDirectory &rDir) 224 : mrDir(rDir), i(rDir.mEntries.begin()) 225 { 226 } 227 228 BackupStoreDirectory::Entry *Next(int16_t FlagsMustBeSet = Entry::Flags_INCLUDE_EVERYTHING, int16_t FlagsNotToBeSet = Entry::Flags_EXCLUDE_NOTHING) 229 { 230 // Skip over things which don't match the required flags 231 while(i != mrDir.mEntries.end() && !(*i)->MatchesFlags(FlagsMustBeSet, FlagsNotToBeSet)) 232 { 233 ++i; 234 } 235 // Not the last one? 236 if(i == mrDir.mEntries.end()) 237 { 238 return 0; 239 } 240 // Return entry, and increment 241 return (*(i++)); 242 } 243 244 // WARNING: This function is really very inefficient. 245 // Only use when you want to look up ONE filename, not in a loop looking up lots. 246 // In a looping situation, cache the decrypted filenames in another memory structure. 247 BackupStoreDirectory::Entry *FindMatchingClearName(const BackupStoreFilenameClear &rFilename, int16_t FlagsMustBeSet = Entry::Flags_INCLUDE_EVERYTHING, int16_t FlagsNotToBeSet = Entry::Flags_EXCLUDE_NOTHING) 248 { 249 // Skip over things which don't match the required flags or filename 250 while( (i != mrDir.mEntries.end()) 251 && ( (!(*i)->MatchesFlags(FlagsMustBeSet, FlagsNotToBeSet)) 252 || (BackupStoreFilenameClear((*i)->GetName()).GetClearFilename() != rFilename.GetClearFilename()) ) ) 253 { 254 ++i; 255 } 256 // Not the last one? 257 if(i == mrDir.mEntries.end()) 258 { 259 return 0; 260 } 261 // Return entry, and increment 262 return (*(i++)); 263 } 264 265 private: 266 const BackupStoreDirectory &mrDir; 267 std::vector<Entry*>::const_iterator i; 268 }; 269 270 friend class Iterator; 271 272 class ReverseIterator 273 { 274 public: ReverseIterator(const BackupStoreDirectory & rDir)275 ReverseIterator(const BackupStoreDirectory &rDir) 276 : mrDir(rDir), i(rDir.mEntries.rbegin()) 277 { 278 } 279 280 BackupStoreDirectory::Entry *Next(int16_t FlagsMustBeSet = Entry::Flags_INCLUDE_EVERYTHING, int16_t FlagsNotToBeSet = Entry::Flags_EXCLUDE_NOTHING) 281 { 282 // Skip over things which don't match the required flags 283 while(i != mrDir.mEntries.rend() && !(*i)->MatchesFlags(FlagsMustBeSet, FlagsNotToBeSet)) 284 { 285 ++i; 286 } 287 // Not the last one? 288 if(i == mrDir.mEntries.rend()) 289 { 290 return 0; 291 } 292 // Return entry, and increment 293 return (*(i++)); 294 } 295 296 private: 297 const BackupStoreDirectory &mrDir; 298 std::vector<Entry*>::const_reverse_iterator i; 299 }; 300 301 friend class ReverseIterator; 302 303 // For recovery of the store 304 // Implemented in BackupStoreCheck2.cpp 305 bool CheckAndFix(); 306 void AddUnattactedObject(const BackupStoreFilename &rName, box_time_t ModificationTime, int64_t ObjectID, int64_t SizeInBlocks, int16_t Flags); 307 bool NameInUse(const BackupStoreFilename &rName); 308 // Don't use these functions in normal code! 309 310 // For testing TESTONLY_SetObjectID(int64_t ObjectID)311 void TESTONLY_SetObjectID(int64_t ObjectID) {mObjectID = ObjectID;} 312 313 // Debug and diagonistics 314 void Dump(void *clibFileHandle, bool ToTrace); // first arg is FILE *, but avoid including stdio.h everywhere 315 316 private: 317 int64_t mRevisionID; 318 int64_t mObjectID; 319 int64_t mContainerID; 320 std::vector<Entry*> mEntries; 321 box_time_t mAttributesModTime; 322 StreamableMemBlock mAttributes; 323 int64_t mUserInfo1; 324 }; 325 326 #endif // BACKUPSTOREDIRECTORY__H 327 328