summaryrefslogtreecommitdiff
path: root/lib/backupstore/BackupStoreAccountDatabase.cpp
diff options
context:
space:
mode:
authorReinhard Tartler <siretart@tauware.de>2007-02-14 09:01:45 +0100
committerReinhard Tartler <siretart@tauware.de>2007-02-14 09:01:45 +0100
commitaa2943800f9c00823720af98da036813ebf5cd2c (patch)
tree099cc0264d32a36ab89aa3f48cbf34612c3cd225 /lib/backupstore/BackupStoreAccountDatabase.cpp
initial commit
Diffstat (limited to 'lib/backupstore/BackupStoreAccountDatabase.cpp')
-rw-r--r--lib/backupstore/BackupStoreAccountDatabase.cpp408
1 files changed, 408 insertions, 0 deletions
diff --git a/lib/backupstore/BackupStoreAccountDatabase.cpp b/lib/backupstore/BackupStoreAccountDatabase.cpp
new file mode 100644
index 00000000..8e276ba2
--- /dev/null
+++ b/lib/backupstore/BackupStoreAccountDatabase.cpp
@@ -0,0 +1,408 @@
+// 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: BackupStoreAccountDatabase.cpp
+// Purpose: Database of accounts for the backup store
+// Created: 2003/08/20
+//
+// --------------------------------------------------------------------------
+
+#include "Box.h"
+
+#include <stdlib.h>
+#include <string>
+#include <map>
+#include <stdio.h>
+#include <sys/stat.h>
+
+#include "BackupStoreAccountDatabase.h"
+#include "Guards.h"
+#include "FdGetLine.h"
+#include "BackupStoreException.h"
+#include "CommonException.h"
+#include "FileModificationTime.h"
+
+#include "MemLeakFindOn.h"
+
+class _BackupStoreAccountDatabase
+{
+public:
+ std::string mFilename;
+ std::map<int32_t, BackupStoreAccountDatabase::Entry> mDatabase;
+ box_time_t mModificationTime;
+};
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: BackupStoreAccountDatabase::BackupStoreAccountDatabase(const char *)
+// Purpose: Constructor
+// Created: 2003/08/20
+//
+// --------------------------------------------------------------------------
+BackupStoreAccountDatabase::BackupStoreAccountDatabase(const char *Filename)
+ : pImpl(new _BackupStoreAccountDatabase)
+{
+ pImpl->mFilename = Filename;
+ pImpl->mModificationTime = 0;
+}
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: BackupStoreAccountDatabase::~BackupStoreAccountDatabase()
+// Purpose: Destructor
+// Created: 2003/08/20
+//
+// --------------------------------------------------------------------------
+BackupStoreAccountDatabase::~BackupStoreAccountDatabase()
+{
+ delete pImpl;
+}
+
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: BackupStoreAccountDatabase::Entry::Entry()
+// Purpose: Default constructor
+// Created: 2003/08/21
+//
+// --------------------------------------------------------------------------
+BackupStoreAccountDatabase::Entry::Entry()
+ : mID(-1),
+ mDiscSet(-1)
+{
+}
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: BackupStoreAccountDatabase::Entry::Entry(int32_t, int)
+// Purpose: Constructor
+// Created: 2003/08/21
+//
+// --------------------------------------------------------------------------
+BackupStoreAccountDatabase::Entry::Entry(int32_t ID, int DiscSet)
+ : mID(ID),
+ mDiscSet(DiscSet)
+{
+}
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: BackupStoreAccountDatabase::Entry::Entry(const Entry &)
+// Purpose: Copy constructor
+// Created: 2003/08/21
+//
+// --------------------------------------------------------------------------
+BackupStoreAccountDatabase::Entry::Entry(const Entry &rEntry)
+ : mID(rEntry.mID),
+ mDiscSet(rEntry.mDiscSet)
+{
+}
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: BackupStoreAccountDatabase::Entry::~Entry()
+// Purpose: Destructor
+// Created: 2003/08/21
+//
+// --------------------------------------------------------------------------
+BackupStoreAccountDatabase::Entry::~Entry()
+{
+}
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: BackupStoreAccountDatabase::Read(const char *)
+// Purpose: Read in a database from disc
+// Created: 2003/08/21
+//
+// --------------------------------------------------------------------------
+std::auto_ptr<BackupStoreAccountDatabase> BackupStoreAccountDatabase::Read(const char *Filename)
+{
+ // Database object to use
+ std::auto_ptr<BackupStoreAccountDatabase> db(new BackupStoreAccountDatabase(Filename));
+
+ // Read in the file
+ db->ReadFile();
+
+ // Return to called
+ return db;
+}
+
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: BackupStoreAccountDatabase::ReadFile()
+// Purpose: Read the file off disc
+// Created: 21/1/04
+//
+// --------------------------------------------------------------------------
+void BackupStoreAccountDatabase::ReadFile() const
+{
+ // Open file
+ FileHandleGuard<> file(pImpl->mFilename.c_str());
+
+ // Clear existing entries
+ pImpl->mDatabase.clear();
+
+ // Read in lines
+ FdGetLine getLine(file);
+
+ while(!getLine.IsEOF())
+ {
+ // Read and split up line
+ std::string l(getLine.GetLine(true));
+
+ if(!l.empty())
+ {
+ // Check...
+ int32_t id;
+ int discSet;
+ if(::sscanf(l.c_str(), "%x:%d", &id, &discSet) != 2)
+ {
+ THROW_EXCEPTION(BackupStoreException, BadAccountDatabaseFile)
+ }
+
+ // Make a new entry
+ pImpl->mDatabase[id] = Entry(id, discSet);
+ }
+ }
+
+ // Store the modification time of the file
+ pImpl->mModificationTime = GetDBFileModificationTime();
+}
+
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: BackupStoreAccountDatabase::CheckUpToDate()
+// Purpose: Private. Ensure that the in memory database matches the one on disc
+// Created: 21/1/04
+//
+// --------------------------------------------------------------------------
+void BackupStoreAccountDatabase::CheckUpToDate() const
+{
+ if(pImpl->mModificationTime != GetDBFileModificationTime())
+ {
+ // File has changed -- load it in again
+ ReadFile();
+ }
+}
+
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: BackupStoreAccountDatabase::GetDBFileModificationTime()
+// Purpose: Get the current modification time of the database
+// Created: 21/1/04
+//
+// --------------------------------------------------------------------------
+box_time_t BackupStoreAccountDatabase::GetDBFileModificationTime() const
+{
+ struct stat st;
+ if(::stat(pImpl->mFilename.c_str(), &st) == -1)
+ {
+ THROW_EXCEPTION(CommonException, OSFileError)
+ }
+
+ return FileModificationTime(st);
+}
+
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: BackupStoreAccountDatabase::Write()
+// Purpose: Write the database back to disc after modifying it
+// Created: 2003/08/21
+//
+// --------------------------------------------------------------------------
+void BackupStoreAccountDatabase::Write()
+{
+ // Open file for writing
+ // Would use this...
+ // FileHandleGuard<O_WRONLY | O_TRUNC> file(pImpl->mFilename.c_str());
+ // but gcc fails randomly on it on some platforms. Weird.
+
+ int file = ::open(pImpl->mFilename.c_str(), O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
+ if(file == -1)
+ {
+ THROW_EXCEPTION(CommonException, OSFileOpenError)
+ }
+
+ try
+ {
+ // Then write each entry
+ for(std::map<int32_t, BackupStoreAccountDatabase::Entry>::const_iterator i(pImpl->mDatabase.begin());
+ i != pImpl->mDatabase.end(); ++i)
+ {
+ // Write out the entry
+ char line[256]; // more than enough for a couple of integers in string form
+ int s = ::sprintf(line, "%x:%d\n", i->second.GetID(), i->second.GetDiscSet());
+ if(::write(file, line, s) != s)
+ {
+ THROW_EXCEPTION(CommonException, OSFileError)
+ }
+ }
+
+ ::close(file);
+ }
+ catch(...)
+ {
+ ::close(file);
+ throw;
+ }
+
+ // Done.
+}
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: BackupStoreAccountDatabase::EntryExists(int32_t)
+// Purpose: Does an entry exist in the database?
+// Created: 2003/08/21
+//
+// --------------------------------------------------------------------------
+bool BackupStoreAccountDatabase::EntryExists(int32_t ID) const
+{
+ // Check that we're using the latest version of the database
+ CheckUpToDate();
+
+ return pImpl->mDatabase.find(ID) != pImpl->mDatabase.end();
+}
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: BackupStoreAccountDatabase::GetEntry(int32_t)
+// Purpose: Retrieve an entry
+// Created: 2003/08/21
+//
+// --------------------------------------------------------------------------
+const BackupStoreAccountDatabase::Entry &BackupStoreAccountDatabase::GetEntry(int32_t ID) const
+{
+ // Check that we're using the latest version of the database
+ CheckUpToDate();
+
+ std::map<int32_t, BackupStoreAccountDatabase::Entry>::const_iterator i(pImpl->mDatabase.find(ID));
+ if(i == pImpl->mDatabase.end())
+ {
+ THROW_EXCEPTION(BackupStoreException, AccountDatabaseNoSuchEntry)
+ }
+
+ return i->second;
+}
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: BackupStoreAccountDatabase::AddEntry(int32_t, int)
+// Purpose: Add a new entry to the database
+// Created: 2003/08/21
+//
+// --------------------------------------------------------------------------
+void BackupStoreAccountDatabase::AddEntry(int32_t ID, int DiscSet)
+{
+ // Check that we're using the latest version of the database
+ CheckUpToDate();
+
+ pImpl->mDatabase[ID] = Entry(ID, DiscSet);
+}
+
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: BackupStoreAccountDatabase::DeleteEntry(int32_t)
+// Purpose: Delete an entry from the database
+// Created: 2003/08/21
+//
+// --------------------------------------------------------------------------
+void BackupStoreAccountDatabase::DeleteEntry(int32_t ID)
+{
+ // Check that we're using the latest version of the database
+ CheckUpToDate();
+
+ std::map<int32_t, BackupStoreAccountDatabase::Entry>::iterator i(pImpl->mDatabase.find(ID));
+ if(i == pImpl->mDatabase.end())
+ {
+ THROW_EXCEPTION(BackupStoreException, AccountDatabaseNoSuchEntry)
+ }
+
+ pImpl->mDatabase.erase(i);
+}
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: BackupStoreAccountDatabase::GetAllAccountIDs(std::vector<int32_t>)
+// Purpose:
+// Created: 11/12/03
+//
+// --------------------------------------------------------------------------
+void BackupStoreAccountDatabase::GetAllAccountIDs(std::vector<int32_t> &rIDsOut)
+{
+ // Check that we're using the latest version of the database
+ CheckUpToDate();
+
+ // Delete everything in the output list
+ rIDsOut.clear();
+
+ std::map<int32_t, BackupStoreAccountDatabase::Entry>::iterator i(pImpl->mDatabase.begin());
+ for(; i != pImpl->mDatabase.end(); ++i)
+ {
+ rIDsOut.push_back(i->first);
+ }
+}
+
+
+
+