diff options
author | Chris Wilson <chris+github@qwirx.com> | 2011-08-27 14:06:46 +0000 |
---|---|---|
committer | Chris Wilson <chris+github@qwirx.com> | 2011-08-27 14:06:46 +0000 |
commit | a473bb0923b0f7800bb95ef96ba20f5cf6cbe5b4 (patch) | |
tree | 68620eb4a0566889c5a2e903a5b2fb0b678d9613 /lib | |
parent | 50aac86024fae12072a240e6b952c9bb11437956 (diff) |
Combine client and server protocols to make way for an offline/local protocol.
Rename ProtocolObject to Message.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/backupclient/BackupClientRestore.cpp | 6 | ||||
-rw-r--r-- | lib/backupstore/BackupCommands.cpp | 152 | ||||
-rw-r--r-- | lib/backupstore/BackupStoreContext.cpp | 3 | ||||
-rw-r--r-- | lib/backupstore/BackupStoreContext.h | 14 | ||||
-rw-r--r-- | lib/backupstore/BackupStoreFile.h | 3 | ||||
-rw-r--r-- | lib/backupstore/Makefile.extra | 11 | ||||
-rw-r--r-- | lib/backupstore/backupprotocol.txt | 5 | ||||
-rw-r--r-- | lib/server/Message.cpp (renamed from lib/server/ProtocolObject.cpp) | 36 | ||||
-rw-r--r-- | lib/server/Message.h (renamed from lib/server/ProtocolObject.h) | 40 | ||||
-rw-r--r-- | lib/server/Protocol.cpp | 105 | ||||
-rw-r--r-- | lib/server/Protocol.h | 40 | ||||
-rwxr-xr-x | lib/server/makeprotocol.pl.in | 1142 |
12 files changed, 842 insertions, 715 deletions
diff --git a/lib/backupclient/BackupClientRestore.cpp b/lib/backupclient/BackupClientRestore.cpp index fa61bb59..4993f6ae 100644 --- a/lib/backupclient/BackupClientRestore.cpp +++ b/lib/backupclient/BackupClientRestore.cpp @@ -22,7 +22,7 @@ #include <errno.h> #include "BackupClientRestore.h" -#include "autogen_BackupProtocolClient.h" +#include "autogen_BackupProtocol.h" #include "CommonException.h" #include "BackupClientFileAttributes.h" #include "IOStream.h" @@ -443,8 +443,8 @@ static int BackupClientRestoreDir(BackupProtocolClient &rConnection, // list of files which is appropriate to the restore type rConnection.QueryListDirectory( DirectoryID, - Params.RestoreDeleted?(BackupProtocolClientListDirectory::Flags_Deleted):(BackupProtocolClientListDirectory::Flags_INCLUDE_EVERYTHING), - BackupProtocolClientListDirectory::Flags_OldVersion | (Params.RestoreDeleted?(0):(BackupProtocolClientListDirectory::Flags_Deleted)), + Params.RestoreDeleted?(BackupProtocolListDirectory::Flags_Deleted):(BackupProtocolListDirectory::Flags_INCLUDE_EVERYTHING), + BackupProtocolListDirectory::Flags_OldVersion | (Params.RestoreDeleted?(0):(BackupProtocolListDirectory::Flags_Deleted)), true /* want attributes */); // Retrieve the directory from the stream following diff --git a/lib/backupstore/BackupCommands.cpp b/lib/backupstore/BackupCommands.cpp index 34f813df..9552d831 100644 --- a/lib/backupstore/BackupCommands.cpp +++ b/lib/backupstore/BackupCommands.cpp @@ -12,7 +12,7 @@ #include <set> #include <sstream> -#include "autogen_BackupProtocolServer.h" +#include "autogen_BackupProtocol.h" #include "autogen_RaidFileException.h" #include "BackupConstants.h" #include "BackupStoreContext.h" @@ -31,9 +31,9 @@ #include "MemLeakFindOn.h" #define PROTOCOL_ERROR(code) \ - std::auto_ptr<ProtocolObject>(new BackupProtocolServerError( \ - BackupProtocolServerError::ErrorType, \ - BackupProtocolServerError::code)); + std::auto_ptr<BackupProtocolMessage>(new BackupProtocolError( \ + BackupProtocolError::ErrorType, \ + BackupProtocolError::code)); #define CHECK_PHASE(phase) \ if(rContext.GetPhase() != BackupStoreContext::phase) \ @@ -50,12 +50,12 @@ // -------------------------------------------------------------------------- // // Function -// Name: BackupProtocolServerVersion::DoCommand(Protocol &, BackupStoreContext &) +// Name: BackupProtocolVersion::DoCommand(Protocol &, BackupStoreContext &) // Purpose: Return the current version, or an error if the requested version isn't allowed // Created: 2003/08/20 // // -------------------------------------------------------------------------- -std::auto_ptr<ProtocolObject> BackupProtocolServerVersion::DoCommand(BackupProtocolServer &rProtocol, BackupStoreContext &rContext) +std::auto_ptr<BackupProtocolMessage> BackupProtocolVersion::DoCommand(BackupProtocolReplyable &rProtocol, BackupStoreContext &rContext) const { CHECK_PHASE(Phase_Version) @@ -69,18 +69,18 @@ std::auto_ptr<ProtocolObject> BackupProtocolServerVersion::DoCommand(BackupProto rContext.SetPhase(BackupStoreContext::Phase_Login); // Return our version - return std::auto_ptr<ProtocolObject>(new BackupProtocolServerVersion(BACKUP_STORE_SERVER_VERSION)); + return std::auto_ptr<BackupProtocolMessage>(new BackupProtocolVersion(BACKUP_STORE_SERVER_VERSION)); } // -------------------------------------------------------------------------- // // Function -// Name: BackupProtocolServerLogin::DoCommand(Protocol &, BackupStoreContext &) +// Name: BackupProtocolLogin::DoCommand(Protocol &, BackupStoreContext &) // Purpose: Return the current version, or an error if the requested version isn't allowed // Created: 2003/08/20 // // -------------------------------------------------------------------------- -std::auto_ptr<ProtocolObject> BackupProtocolServerLogin::DoCommand(BackupProtocolServer &rProtocol, BackupStoreContext &rContext) +std::auto_ptr<BackupProtocolMessage> BackupProtocolLogin::DoCommand(BackupProtocolReplyable &rProtocol, BackupStoreContext &rContext) const { CHECK_PHASE(Phase_Login) @@ -138,18 +138,18 @@ std::auto_ptr<ProtocolObject> BackupProtocolServerLogin::DoCommand(BackupProtoco rContext.GetStoreDiscUsageInfo(blocksUsed, blocksSoftLimit, blocksHardLimit); // Return success - return std::auto_ptr<ProtocolObject>(new BackupProtocolServerLoginConfirmed(clientStoreMarker, blocksUsed, blocksSoftLimit, blocksHardLimit)); + return std::auto_ptr<BackupProtocolMessage>(new BackupProtocolLoginConfirmed(clientStoreMarker, blocksUsed, blocksSoftLimit, blocksHardLimit)); } // -------------------------------------------------------------------------- // // Function -// Name: BackupProtocolServerFinished::DoCommand(Protocol &, BackupStoreContext &) +// Name: BackupProtocolFinished::DoCommand(Protocol &, BackupStoreContext &) // Purpose: Marks end of conversation (Protocol framework handles this) // Created: 2003/08/20 // // -------------------------------------------------------------------------- -std::auto_ptr<ProtocolObject> BackupProtocolServerFinished::DoCommand(BackupProtocolServer &rProtocol, BackupStoreContext &rContext) +std::auto_ptr<BackupProtocolMessage> BackupProtocolFinished::DoCommand(BackupProtocolReplyable &rProtocol, BackupStoreContext &rContext) const { BOX_NOTICE("Session finished for Client ID " << BOX_FORMAT_ACCOUNT(rContext.GetClientID())); @@ -158,19 +158,19 @@ std::auto_ptr<ProtocolObject> BackupProtocolServerFinished::DoCommand(BackupProt rContext.ReceivedFinishCommand(); // can be called in any phase - return std::auto_ptr<ProtocolObject>(new BackupProtocolServerFinished); + return std::auto_ptr<BackupProtocolMessage>(new BackupProtocolFinished); } // -------------------------------------------------------------------------- // // Function -// Name: BackupProtocolServerListDirectory::DoCommand(Protocol &, BackupStoreContext &) +// Name: BackupProtocolListDirectory::DoCommand(Protocol &, BackupStoreContext &) // Purpose: Command to list a directory // Created: 2003/09/02 // // -------------------------------------------------------------------------- -std::auto_ptr<ProtocolObject> BackupProtocolServerListDirectory::DoCommand(BackupProtocolServer &rProtocol, BackupStoreContext &rContext) +std::auto_ptr<BackupProtocolMessage> BackupProtocolListDirectory::DoCommand(BackupProtocolReplyable &rProtocol, BackupStoreContext &rContext) const { CHECK_PHASE(Phase_Commands) @@ -200,24 +200,24 @@ std::auto_ptr<ProtocolObject> BackupProtocolServerListDirectory::DoCommand(Backu // Get the protocol to send the stream rProtocol.SendStreamAfterCommand(stream.release()); - return std::auto_ptr<ProtocolObject>( - new BackupProtocolServerSuccess(mObjectID)); + return std::auto_ptr<BackupProtocolMessage>( + new BackupProtocolSuccess(mObjectID)); } // -------------------------------------------------------------------------- // // Function -// Name: BackupProtocolServerStoreFile::DoCommand(Protocol &, BackupStoreContext &) +// Name: BackupProtocolStoreFile::DoCommand(Protocol &, BackupStoreContext &) // Purpose: Command to store a file on the server // Created: 2003/09/02 // // -------------------------------------------------------------------------- -std::auto_ptr<ProtocolObject> BackupProtocolServerStoreFile::DoCommand(BackupProtocolServer &rProtocol, BackupStoreContext &rContext) +std::auto_ptr<BackupProtocolMessage> BackupProtocolStoreFile::DoCommand(BackupProtocolReplyable &rProtocol, BackupStoreContext &rContext) const { CHECK_PHASE(Phase_Commands) CHECK_WRITEABLE_SESSION - std::auto_ptr<ProtocolObject> hookResult = + std::auto_ptr<BackupProtocolMessage> hookResult = rContext.StartCommandHook(*this); if(hookResult.get()) { @@ -263,7 +263,7 @@ std::auto_ptr<ProtocolObject> BackupProtocolServerStoreFile::DoCommand(BackupPro } // Tell the caller what the file was - return std::auto_ptr<ProtocolObject>(new BackupProtocolServerSuccess(id)); + return std::auto_ptr<BackupProtocolMessage>(new BackupProtocolSuccess(id)); } @@ -272,19 +272,19 @@ std::auto_ptr<ProtocolObject> BackupProtocolServerStoreFile::DoCommand(BackupPro // -------------------------------------------------------------------------- // // Function -// Name: BackupProtocolServerGetObject::DoCommand(Protocol &, BackupStoreContext &) +// Name: BackupProtocolGetObject::DoCommand(Protocol &, BackupStoreContext &) // Purpose: Command to get an arbitary object from the server // Created: 2003/09/03 // // -------------------------------------------------------------------------- -std::auto_ptr<ProtocolObject> BackupProtocolServerGetObject::DoCommand(BackupProtocolServer &rProtocol, BackupStoreContext &rContext) +std::auto_ptr<BackupProtocolMessage> BackupProtocolGetObject::DoCommand(BackupProtocolReplyable &rProtocol, BackupStoreContext &rContext) const { CHECK_PHASE(Phase_Commands) // Check the object exists if(!rContext.ObjectExists(mObjectID)) { - return std::auto_ptr<ProtocolObject>(new BackupProtocolServerSuccess(NoObject)); + return std::auto_ptr<BackupProtocolMessage>(new BackupProtocolSuccess(NoObject)); } // Open the object @@ -294,19 +294,19 @@ std::auto_ptr<ProtocolObject> BackupProtocolServerGetObject::DoCommand(BackupPro rProtocol.SendStreamAfterCommand(object.release()); // Tell the caller what the file was - return std::auto_ptr<ProtocolObject>(new BackupProtocolServerSuccess(mObjectID)); + return std::auto_ptr<BackupProtocolMessage>(new BackupProtocolSuccess(mObjectID)); } // -------------------------------------------------------------------------- // // Function -// Name: BackupProtocolServerGetFile::DoCommand(Protocol &, BackupStoreContext &) +// Name: BackupProtocolGetFile::DoCommand(Protocol &, BackupStoreContext &) // Purpose: Command to get an file object from the server -- may have to do a bit of // work to get the object. // Created: 2003/09/03 // // -------------------------------------------------------------------------- -std::auto_ptr<ProtocolObject> BackupProtocolServerGetFile::DoCommand(BackupProtocolServer &rProtocol, BackupStoreContext &rContext) +std::auto_ptr<BackupProtocolMessage> BackupProtocolGetFile::DoCommand(BackupProtocolReplyable &rProtocol, BackupStoreContext &rContext) const { CHECK_PHASE(Phase_Commands) @@ -460,19 +460,19 @@ std::auto_ptr<ProtocolObject> BackupProtocolServerGetFile::DoCommand(BackupProto stream.release(); // Tell the caller what the file was - return std::auto_ptr<ProtocolObject>(new BackupProtocolServerSuccess(mObjectID)); + return std::auto_ptr<BackupProtocolMessage>(new BackupProtocolSuccess(mObjectID)); } // -------------------------------------------------------------------------- // // Function -// Name: BackupProtocolServerCreateDirectory::DoCommand(Protocol &, BackupStoreContext &) +// Name: BackupProtocolCreateDirectory::DoCommand(Protocol &, BackupStoreContext &) // Purpose: Create directory command // Created: 2003/09/04 // // -------------------------------------------------------------------------- -std::auto_ptr<ProtocolObject> BackupProtocolServerCreateDirectory::DoCommand(BackupProtocolServer &rProtocol, BackupStoreContext &rContext) +std::auto_ptr<BackupProtocolMessage> BackupProtocolCreateDirectory::DoCommand(BackupProtocolReplyable &rProtocol, BackupStoreContext &rContext) const { CHECK_PHASE(Phase_Commands) CHECK_WRITEABLE_SESSION @@ -500,7 +500,7 @@ std::auto_ptr<ProtocolObject> BackupProtocolServerCreateDirectory::DoCommand(Bac } // Tell the caller what the file was - return std::auto_ptr<ProtocolObject>(new BackupProtocolServerSuccess(id)); + return std::auto_ptr<BackupProtocolMessage>(new BackupProtocolSuccess(id)); } @@ -508,12 +508,12 @@ std::auto_ptr<ProtocolObject> BackupProtocolServerCreateDirectory::DoCommand(Bac // -------------------------------------------------------------------------- // // Function -// Name: BackupProtocolServerChangeDirAttributes::DoCommand(Protocol &, BackupStoreContext &) +// Name: BackupProtocolChangeDirAttributes::DoCommand(Protocol &, BackupStoreContext &) // Purpose: Change attributes on directory // Created: 2003/09/06 // // -------------------------------------------------------------------------- -std::auto_ptr<ProtocolObject> BackupProtocolServerChangeDirAttributes::DoCommand(BackupProtocolServer &rProtocol, BackupStoreContext &rContext) +std::auto_ptr<BackupProtocolMessage> BackupProtocolChangeDirAttributes::DoCommand(BackupProtocolReplyable &rProtocol, BackupStoreContext &rContext) const { CHECK_PHASE(Phase_Commands) CHECK_WRITEABLE_SESSION @@ -529,19 +529,19 @@ std::auto_ptr<ProtocolObject> BackupProtocolServerChangeDirAttributes::DoCommand rContext.ChangeDirAttributes(mObjectID, attr, mAttributesModTime); // Tell the caller what the file was - return std::auto_ptr<ProtocolObject>(new BackupProtocolServerSuccess(mObjectID)); + return std::auto_ptr<BackupProtocolMessage>(new BackupProtocolSuccess(mObjectID)); } // -------------------------------------------------------------------------- // // Function -// Name: BackupProtocolServerSetReplacementFileAttributes::DoCommand(Protocol &, BackupStoreContext &) +// Name: BackupProtocolSetReplacementFileAttributes::DoCommand(Protocol &, BackupStoreContext &) // Purpose: Change attributes on directory // Created: 2003/09/06 // // -------------------------------------------------------------------------- -std::auto_ptr<ProtocolObject> BackupProtocolServerSetReplacementFileAttributes::DoCommand(BackupProtocolServer &rProtocol, BackupStoreContext &rContext) +std::auto_ptr<BackupProtocolMessage> BackupProtocolSetReplacementFileAttributes::DoCommand(BackupProtocolReplyable &rProtocol, BackupStoreContext &rContext) const { CHECK_PHASE(Phase_Commands) CHECK_WRITEABLE_SESSION @@ -562,7 +562,7 @@ std::auto_ptr<ProtocolObject> BackupProtocolServerSetReplacementFileAttributes:: } // Tell the caller what the file was - return std::auto_ptr<ProtocolObject>(new BackupProtocolServerSuccess(objectID)); + return std::auto_ptr<BackupProtocolMessage>(new BackupProtocolSuccess(objectID)); } @@ -570,12 +570,12 @@ std::auto_ptr<ProtocolObject> BackupProtocolServerSetReplacementFileAttributes:: // -------------------------------------------------------------------------- // // Function -// Name: BackupProtocolServerDeleteFile::DoCommand(BackupProtocolServer &, BackupStoreContext &) +// Name: BackupProtocolDeleteFile::DoCommand(BackupProtocolReplyable &, BackupStoreContext &) // Purpose: Delete a file // Created: 2003/10/21 // // -------------------------------------------------------------------------- -std::auto_ptr<ProtocolObject> BackupProtocolServerDeleteFile::DoCommand(BackupProtocolServer &rProtocol, BackupStoreContext &rContext) +std::auto_ptr<BackupProtocolMessage> BackupProtocolDeleteFile::DoCommand(BackupProtocolReplyable &rProtocol, BackupStoreContext &rContext) const { CHECK_PHASE(Phase_Commands) CHECK_WRITEABLE_SESSION @@ -585,21 +585,21 @@ std::auto_ptr<ProtocolObject> BackupProtocolServerDeleteFile::DoCommand(BackupPr rContext.DeleteFile(mFilename, mInDirectory, objectID); // return the object ID or zero for not found - return std::auto_ptr<ProtocolObject>(new BackupProtocolServerSuccess(objectID)); + return std::auto_ptr<BackupProtocolMessage>(new BackupProtocolSuccess(objectID)); } // -------------------------------------------------------------------------- // // Function -// Name: BackupProtocolServerUndeleteFile::DoCommand( -// BackupProtocolServer &, BackupStoreContext &) +// Name: BackupProtocolUndeleteFile::DoCommand( +// BackupProtocolBase &, BackupStoreContext &) // Purpose: Undelete a file // Created: 2008-09-12 // // -------------------------------------------------------------------------- -std::auto_ptr<ProtocolObject> BackupProtocolServerUndeleteFile::DoCommand( - BackupProtocolServer &rProtocol, BackupStoreContext &rContext) +std::auto_ptr<BackupProtocolMessage> BackupProtocolUndeleteFile::DoCommand( + BackupProtocolReplyable &rProtocol, BackupStoreContext &rContext) const { CHECK_PHASE(Phase_Commands) CHECK_WRITEABLE_SESSION @@ -608,20 +608,20 @@ std::auto_ptr<ProtocolObject> BackupProtocolServerUndeleteFile::DoCommand( bool result = rContext.UndeleteFile(mObjectID, mInDirectory); // return the object ID or zero for not found - return std::auto_ptr<ProtocolObject>( - new BackupProtocolServerSuccess(result ? mObjectID : 0)); + return std::auto_ptr<BackupProtocolMessage>( + new BackupProtocolSuccess(result ? mObjectID : 0)); } // -------------------------------------------------------------------------- // // Function -// Name: BackupProtocolServerDeleteDirectory::DoCommand(BackupProtocolServer &, BackupStoreContext &) +// Name: BackupProtocolDeleteDirectory::DoCommand(BackupProtocolReplyable &, BackupStoreContext &) // Purpose: Delete a directory // Created: 2003/10/21 // // -------------------------------------------------------------------------- -std::auto_ptr<ProtocolObject> BackupProtocolServerDeleteDirectory::DoCommand(BackupProtocolServer &rProtocol, BackupStoreContext &rContext) +std::auto_ptr<BackupProtocolMessage> BackupProtocolDeleteDirectory::DoCommand(BackupProtocolReplyable &rProtocol, BackupStoreContext &rContext) const { CHECK_PHASE(Phase_Commands) CHECK_WRITEABLE_SESSION @@ -648,19 +648,19 @@ std::auto_ptr<ProtocolObject> BackupProtocolServerDeleteDirectory::DoCommand(Bac } // return the object ID - return std::auto_ptr<ProtocolObject>(new BackupProtocolServerSuccess(mObjectID)); + return std::auto_ptr<BackupProtocolMessage>(new BackupProtocolSuccess(mObjectID)); } // -------------------------------------------------------------------------- // // Function -// Name: BackupProtocolServerUndeleteDirectory::DoCommand(BackupProtocolServer &, BackupStoreContext &) +// Name: BackupProtocolUndeleteDirectory::DoCommand(BackupProtocolReplyable &, BackupStoreContext &) // Purpose: Undelete a directory // Created: 23/11/03 // // -------------------------------------------------------------------------- -std::auto_ptr<ProtocolObject> BackupProtocolServerUndeleteDirectory::DoCommand(BackupProtocolServer &rProtocol, BackupStoreContext &rContext) +std::auto_ptr<BackupProtocolMessage> BackupProtocolUndeleteDirectory::DoCommand(BackupProtocolReplyable &rProtocol, BackupStoreContext &rContext) const { CHECK_PHASE(Phase_Commands) CHECK_WRITEABLE_SESSION @@ -675,18 +675,18 @@ std::auto_ptr<ProtocolObject> BackupProtocolServerUndeleteDirectory::DoCommand(B rContext.DeleteDirectory(mObjectID, true /* undelete */); // return the object ID - return std::auto_ptr<ProtocolObject>(new BackupProtocolServerSuccess(mObjectID)); + return std::auto_ptr<BackupProtocolMessage>(new BackupProtocolSuccess(mObjectID)); } // -------------------------------------------------------------------------- // // Function -// Name: BackupProtocolServerSetClientStoreMarker::DoCommand(BackupProtocolServer &, BackupStoreContext &) +// Name: BackupProtocolSetClientStoreMarker::DoCommand(BackupProtocolReplyable &, BackupStoreContext &) // Purpose: Command to set the client's store marker // Created: 2003/10/29 // // -------------------------------------------------------------------------- -std::auto_ptr<ProtocolObject> BackupProtocolServerSetClientStoreMarker::DoCommand(BackupProtocolServer &rProtocol, BackupStoreContext &rContext) +std::auto_ptr<BackupProtocolMessage> BackupProtocolSetClientStoreMarker::DoCommand(BackupProtocolReplyable &rProtocol, BackupStoreContext &rContext) const { CHECK_PHASE(Phase_Commands) CHECK_WRITEABLE_SESSION @@ -695,19 +695,19 @@ std::auto_ptr<ProtocolObject> BackupProtocolServerSetClientStoreMarker::DoComman rContext.SetClientStoreMarker(mClientStoreMarker); // return store marker set - return std::auto_ptr<ProtocolObject>(new BackupProtocolServerSuccess(mClientStoreMarker)); + return std::auto_ptr<BackupProtocolMessage>(new BackupProtocolSuccess(mClientStoreMarker)); } // -------------------------------------------------------------------------- // // Function -// Name: BackupProtocolServerMoveObject::DoCommand(BackupProtocolServer &, BackupStoreContext &) +// Name: BackupProtocolMoveObject::DoCommand(BackupProtocolReplyable &, BackupStoreContext &) // Purpose: Command to move an object from one directory to another // Created: 2003/11/12 // // -------------------------------------------------------------------------- -std::auto_ptr<ProtocolObject> BackupProtocolServerMoveObject::DoCommand(BackupProtocolServer &rProtocol, BackupStoreContext &rContext) +std::auto_ptr<BackupProtocolMessage> BackupProtocolMoveObject::DoCommand(BackupProtocolReplyable &rProtocol, BackupStoreContext &rContext) const { CHECK_PHASE(Phase_Commands) CHECK_WRITEABLE_SESSION @@ -736,19 +736,19 @@ std::auto_ptr<ProtocolObject> BackupProtocolServerMoveObject::DoCommand(BackupPr } // Return the object ID - return std::auto_ptr<ProtocolObject>(new BackupProtocolServerSuccess(mObjectID)); + return std::auto_ptr<BackupProtocolMessage>(new BackupProtocolSuccess(mObjectID)); } // -------------------------------------------------------------------------- // // Function -// Name: BackupProtocolServerGetObjectName::DoCommand(BackupProtocolServer &, BackupStoreContext &) +// Name: BackupProtocolGetObjectName::DoCommand(BackupProtocolReplyable &, BackupStoreContext &) // Purpose: Command to find the name of an object // Created: 12/11/03 // // -------------------------------------------------------------------------- -std::auto_ptr<ProtocolObject> BackupProtocolServerGetObjectName::DoCommand(BackupProtocolServer &rProtocol, BackupStoreContext &rContext) +std::auto_ptr<BackupProtocolMessage> BackupProtocolGetObjectName::DoCommand(BackupProtocolReplyable &rProtocol, BackupStoreContext &rContext) const { CHECK_PHASE(Phase_Commands) @@ -771,7 +771,7 @@ std::auto_ptr<ProtocolObject> BackupProtocolServerGetObjectName::DoCommand(Backu // Check the directory really exists if(!rContext.ObjectExists(dirID, BackupStoreContext::ObjectExists_Directory)) { - return std::auto_ptr<ProtocolObject>(new BackupProtocolServerObjectName(BackupProtocolServerObjectName::NumNameElements_ObjectDoesntExist, 0, 0, 0)); + return std::auto_ptr<BackupProtocolMessage>(new BackupProtocolObjectName(BackupProtocolObjectName::NumNameElements_ObjectDoesntExist, 0, 0, 0)); } // Load up the directory @@ -786,7 +786,7 @@ std::auto_ptr<ProtocolObject> BackupProtocolServerGetObjectName::DoCommand(Backu if(en == 0) { // Abort! - return std::auto_ptr<ProtocolObject>(new BackupProtocolServerObjectName(BackupProtocolServerObjectName::NumNameElements_ObjectDoesntExist, 0, 0, 0)); + return std::auto_ptr<BackupProtocolMessage>(new BackupProtocolObjectName(BackupProtocolObjectName::NumNameElements_ObjectDoesntExist, 0, 0, 0)); } // Store flags? @@ -826,7 +826,7 @@ std::auto_ptr<ProtocolObject> BackupProtocolServerGetObjectName::DoCommand(Backu } // Make reply - return std::auto_ptr<ProtocolObject>(new BackupProtocolServerObjectName(numNameElements, modTime, attrModHash, objectFlags)); + return std::auto_ptr<BackupProtocolMessage>(new BackupProtocolObjectName(numNameElements, modTime, attrModHash, objectFlags)); } @@ -834,12 +834,12 @@ std::auto_ptr<ProtocolObject> BackupProtocolServerGetObjectName::DoCommand(Backu // -------------------------------------------------------------------------- // // Function -// Name: BackupProtocolServerGetBlockIndexByID::DoCommand(BackupProtocolServer &, BackupStoreContext &) +// Name: BackupProtocolGetBlockIndexByID::DoCommand(BackupProtocolReplyable &, BackupStoreContext &) // Purpose: Get the block index from a file, by ID // Created: 19/1/04 // // -------------------------------------------------------------------------- -std::auto_ptr<ProtocolObject> BackupProtocolServerGetBlockIndexByID::DoCommand(BackupProtocolServer &rProtocol, BackupStoreContext &rContext) +std::auto_ptr<BackupProtocolMessage> BackupProtocolGetBlockIndexByID::DoCommand(BackupProtocolReplyable &rProtocol, BackupStoreContext &rContext) const { CHECK_PHASE(Phase_Commands) @@ -853,19 +853,19 @@ std::auto_ptr<ProtocolObject> BackupProtocolServerGetBlockIndexByID::DoCommand(B rProtocol.SendStreamAfterCommand(stream.release()); // Return the object ID - return std::auto_ptr<ProtocolObject>(new BackupProtocolServerSuccess(mObjectID)); + return std::auto_ptr<BackupProtocolMessage>(new BackupProtocolSuccess(mObjectID)); } // -------------------------------------------------------------------------- // // Function -// Name: BackupProtocolServerGetBlockIndexByName::DoCommand(BackupProtocolServer &, BackupStoreContext &) +// Name: BackupProtocolGetBlockIndexByName::DoCommand(BackupProtocolReplyable &, BackupStoreContext &) // Purpose: Get the block index from a file, by name within a directory // Created: 19/1/04 // // -------------------------------------------------------------------------- -std::auto_ptr<ProtocolObject> BackupProtocolServerGetBlockIndexByName::DoCommand(BackupProtocolServer &rProtocol, BackupStoreContext &rContext) +std::auto_ptr<BackupProtocolMessage> BackupProtocolGetBlockIndexByName::DoCommand(BackupProtocolReplyable &rProtocol, BackupStoreContext &rContext) const { CHECK_PHASE(Phase_Commands) @@ -892,7 +892,7 @@ std::auto_ptr<ProtocolObject> BackupProtocolServerGetBlockIndexByName::DoCommand if(objectID == 0) { // No... return a zero object ID - return std::auto_ptr<ProtocolObject>(new BackupProtocolServerSuccess(0)); + return std::auto_ptr<BackupProtocolMessage>(new BackupProtocolSuccess(0)); } // Open the file @@ -905,19 +905,19 @@ std::auto_ptr<ProtocolObject> BackupProtocolServerGetBlockIndexByName::DoCommand rProtocol.SendStreamAfterCommand(stream.release()); // Return the object ID - return std::auto_ptr<ProtocolObject>(new BackupProtocolServerSuccess(objectID)); + return std::auto_ptr<BackupProtocolMessage>(new BackupProtocolSuccess(objectID)); } // -------------------------------------------------------------------------- // // Function -// Name: BackupProtocolServerGetAccountUsage::DoCommand(BackupProtocolServer &, BackupStoreContext &) +// Name: BackupProtocolGetAccountUsage::DoCommand(BackupProtocolReplyable &, BackupStoreContext &) // Purpose: Return the amount of disc space used // Created: 19/4/04 // // -------------------------------------------------------------------------- -std::auto_ptr<ProtocolObject> BackupProtocolServerGetAccountUsage::DoCommand(BackupProtocolServer &rProtocol, BackupStoreContext &rContext) +std::auto_ptr<BackupProtocolMessage> BackupProtocolGetAccountUsage::DoCommand(BackupProtocolReplyable &rProtocol, BackupStoreContext &rContext) const { CHECK_PHASE(Phase_Commands) @@ -929,7 +929,7 @@ std::auto_ptr<ProtocolObject> BackupProtocolServerGetAccountUsage::DoCommand(Bac RaidFileDiscSet &rdiscSet(rcontroller.GetDiscSet(rinfo.GetDiscSetNumber())); // Return info - return std::auto_ptr<ProtocolObject>(new BackupProtocolServerAccountUsage( + return std::auto_ptr<BackupProtocolMessage>(new BackupProtocolAccountUsage( rinfo.GetBlocksUsed(), rinfo.GetBlocksInOldFiles(), rinfo.GetBlocksInDeletedFiles(), @@ -943,17 +943,17 @@ std::auto_ptr<ProtocolObject> BackupProtocolServerGetAccountUsage::DoCommand(Bac // -------------------------------------------------------------------------- // // Function -// Name: BackupProtocolServerGetIsAlive::DoCommand(BackupProtocolServer &, BackupStoreContext &) +// Name: BackupProtocolGetIsAlive::DoCommand(BackupProtocolReplyable &, BackupStoreContext &) // Purpose: Return the amount of disc space used // Created: 19/4/04 // // -------------------------------------------------------------------------- -std::auto_ptr<ProtocolObject> BackupProtocolServerGetIsAlive::DoCommand(BackupProtocolServer &rProtocol, BackupStoreContext &rContext) +std::auto_ptr<BackupProtocolMessage> BackupProtocolGetIsAlive::DoCommand(BackupProtocolReplyable &rProtocol, BackupStoreContext &rContext) const { CHECK_PHASE(Phase_Commands) // // NOOP // - return std::auto_ptr<ProtocolObject>(new BackupProtocolServerIsAlive()); + return std::auto_ptr<BackupProtocolMessage>(new BackupProtocolIsAlive()); } diff --git a/lib/backupstore/BackupStoreContext.cpp b/lib/backupstore/BackupStoreContext.cpp index a62655d3..e44fa29d 100644 --- a/lib/backupstore/BackupStoreContext.cpp +++ b/lib/backupstore/BackupStoreContext.cpp @@ -27,10 +27,9 @@ #include "RaidFileWrite.h" #include "StoreStructure.h" -class BackupStoreDaemon; - #include "MemLeakFindOn.h" + // Maximum number of directories to keep in the cache // When the cache is bigger than this, everything gets // deleted. diff --git a/lib/backupstore/BackupStoreContext.h b/lib/backupstore/BackupStoreContext.h index 44a05dd8..d46ac295 100644 --- a/lib/backupstore/BackupStoreContext.h +++ b/lib/backupstore/BackupStoreContext.h @@ -16,15 +16,14 @@ #include "BackupStoreRefCountDatabase.h" #include "NamedLock.h" -#include "ProtocolObject.h" +#include "Message.h" #include "Utils.h" class BackupStoreDirectory; class BackupStoreFilename; -class BackupStoreDaemon; class BackupStoreInfo; class IOStream; -class BackupProtocolObject; +class BackupProtocolMessage; class StreamableMemBlock; class HousekeepingInterface @@ -161,21 +160,22 @@ public: class TestHook { public: - virtual std::auto_ptr<ProtocolObject> StartCommand(BackupProtocolObject& - rCommand) = 0; + virtual std::auto_ptr<BackupProtocolMessage> + StartCommand(const BackupProtocolMessage& rCommand) = 0; virtual ~TestHook() { } }; void SetTestHook(TestHook& rTestHook) { mpTestHook = &rTestHook; } - std::auto_ptr<ProtocolObject> StartCommandHook(BackupProtocolObject& rCommand) + std::auto_ptr<BackupProtocolMessage> + StartCommandHook(const BackupProtocolMessage& rCommand) { if(mpTestHook) { return mpTestHook->StartCommand(rCommand); } - return std::auto_ptr<ProtocolObject>(); + return std::auto_ptr<BackupProtocolMessage>(); } private: diff --git a/lib/backupstore/BackupStoreFile.h b/lib/backupstore/BackupStoreFile.h index f5bc1924..b390320e 100644 --- a/lib/backupstore/BackupStoreFile.h +++ b/lib/backupstore/BackupStoreFile.h @@ -18,7 +18,6 @@ #include "BackupStoreFilename.h" #include "IOStream.h" #include "ReadLoggingStream.h" -#include "RunStatusProvider.h" typedef struct { @@ -27,6 +26,8 @@ typedef struct int64_t mTotalFileStreamSize; } BackupStoreFileStats; +class RunStatusProvider; + // Uncomment to disable backwards compatibility //#define BOX_DISABLE_BACKWARDS_COMPATIBILITY_BACKUPSTOREFILE diff --git a/lib/backupstore/Makefile.extra b/lib/backupstore/Makefile.extra index bc807fb6..c55fd549 100644 --- a/lib/backupstore/Makefile.extra +++ b/lib/backupstore/Makefile.extra @@ -1,16 +1,11 @@ - MAKEPROTOCOL = ../../lib/server/makeprotocol.pl -GEN_CMD_CLI = $(MAKEPROTOCOL) Client backupprotocol.txt -GEN_CMD_SRV = $(MAKEPROTOCOL) Server backupprotocol.txt +GEN_CMD = $(MAKEPROTOCOL) backupprotocol.txt # AUTOGEN SEEDING -autogen_BackupProtocolClient.cpp autogen_BackupProtocolClient.h: $(MAKEPROTOCOL) backupprotocol.txt - $(_PERL) $(GEN_CMD_CLI) +autogen_BackupProtocol.cpp autogen_BackupProtocol.h: $(MAKEPROTOCOL) backupprotocol.txt + $(_PERL) $(GEN_CMD) -# AUTOGEN SEEDING -autogen_BackupProtocolServer.cpp autogen_BackupProtocolServer.h: $(MAKEPROTOCOL) backupprotocol.txt - $(_PERL) $(GEN_CMD_SRV) MAKEEXCEPTION = ../../lib/common/makeexception.pl diff --git a/lib/backupstore/backupprotocol.txt b/lib/backupstore/backupprotocol.txt index 011458e8..9df62459 100644 --- a/lib/backupstore/backupprotocol.txt +++ b/lib/backupstore/backupprotocol.txt @@ -6,14 +6,13 @@ Name Backup IdentString Box-Backup:v=C ServerContextClass BackupStoreContext BackupStoreContext.h -ClientType Filename BackupStoreFilenameClear BackupStoreFilenameClear.h -ServerType Filename BackupStoreFilename BackupStoreFilename.h +AddType Filename BackupStoreFilenameClear BackupStoreFilenameClear.h ImplementLog Server syslog ImplementLog Client syslog ImplementLog Client file -LogTypeToText Client Filename \"%s\" VAR.GetClearFilename().c_str() +LogTypeToText Filename "%s" VAR.GetClearFilenameIfPossible("OPAQUE").c_str() BEGIN_OBJECTS diff --git a/lib/server/ProtocolObject.cpp b/lib/server/Message.cpp index fb09f820..2ff9e6ae 100644 --- a/lib/server/ProtocolObject.cpp +++ b/lib/server/Message.cpp @@ -1,14 +1,14 @@ // -------------------------------------------------------------------------- // // File -// Name: ProtocolObject.h +// Name: Message.h // Purpose: Protocol object base class // Created: 2003/08/19 // // -------------------------------------------------------------------------- #include "Box.h" -#include "ProtocolObject.h" +#include "Message.h" #include "CommonException.h" #include "MemLeakFindOn.h" @@ -16,48 +16,48 @@ // -------------------------------------------------------------------------- // // Function -// Name: ProtocolObject::ProtocolObject() +// Name: Message::Message() // Purpose: Default constructor // Created: 2003/08/19 // // -------------------------------------------------------------------------- -ProtocolObject::ProtocolObject() +Message::Message() { } // -------------------------------------------------------------------------- // // Function -// Name: ProtocolObject::ProtocolObject() +// Name: Message::Message() // Purpose: Destructor // Created: 2003/08/19 // // -------------------------------------------------------------------------- -ProtocolObject::~ProtocolObject() +Message::~Message() { } // -------------------------------------------------------------------------- // // Function -// Name: ProtocolObject::ProtocolObject() +// Name: Message::Message() // Purpose: Copy constructor // Created: 2003/08/19 // // -------------------------------------------------------------------------- -ProtocolObject::ProtocolObject(const ProtocolObject &rToCopy) +Message::Message(const Message &rToCopy) { } // -------------------------------------------------------------------------- // // Function -// Name: ProtocolObject::IsError(int &, int &) +// Name: Message::IsError(int &, int &) // Purpose: Does this represent an error, and if so, what is the type and subtype? // Created: 2003/08/19 // // -------------------------------------------------------------------------- -bool ProtocolObject::IsError(int &rTypeOut, int &rSubTypeOut) const +bool Message::IsError(int &rTypeOut, int &rSubTypeOut) const { return false; } @@ -65,12 +65,12 @@ bool ProtocolObject::IsError(int &rTypeOut, int &rSubTypeOut) const // -------------------------------------------------------------------------- // // Function -// Name: ProtocolObject::IsConversationEnd() +// Name: Message::IsConversationEnd() // Purpose: Does this command end the conversation? // Created: 2003/08/19 // // -------------------------------------------------------------------------- -bool ProtocolObject::IsConversationEnd() const +bool Message::IsConversationEnd() const { return false; } @@ -79,12 +79,12 @@ bool ProtocolObject::IsConversationEnd() const // -------------------------------------------------------------------------- // // Function -// Name: ProtocolObject::GetType() +// Name: Message::GetType() // Purpose: Return type of the object // Created: 2003/08/19 // // -------------------------------------------------------------------------- -int ProtocolObject::GetType() const +int Message::GetType() const { // This isn't implemented in the base class! THROW_EXCEPTION(CommonException, Internal) @@ -94,12 +94,12 @@ int ProtocolObject::GetType() const // -------------------------------------------------------------------------- // // Function -// Name: ProtocolObject::SetPropertiesFromStreamData(Protocol &) +// Name: Message::SetPropertiesFromStreamData(Protocol &) // Purpose: Set the properties of the object from the stream data ready in the Protocol object // Created: 2003/08/19 // // -------------------------------------------------------------------------- -void ProtocolObject::SetPropertiesFromStreamData(Protocol &rProtocol) +void Message::SetPropertiesFromStreamData(Protocol &rProtocol) { // This isn't implemented in the base class! THROW_EXCEPTION(CommonException, Internal) @@ -110,12 +110,12 @@ void ProtocolObject::SetPropertiesFromStreamData(Protocol &rProtocol) // -------------------------------------------------------------------------- // // Function -// Name: ProtocolObject::WritePropertiesToStreamData(Protocol &) +// Name: Message::WritePropertiesToStreamData(Protocol &) // Purpose: Write the properties of the object into the stream data in the Protocol object // Created: 2003/08/19 // // -------------------------------------------------------------------------- -void ProtocolObject::WritePropertiesToStreamData(Protocol &rProtocol) const +void Message::WritePropertiesToStreamData(Protocol &rProtocol) const { // This isn't implemented in the base class! THROW_EXCEPTION(CommonException, Internal) diff --git a/lib/server/ProtocolObject.h b/lib/server/Message.h index 0a127ab5..0d073d49 100644 --- a/lib/server/ProtocolObject.h +++ b/lib/server/Message.h @@ -1,7 +1,7 @@ // -------------------------------------------------------------------------- // // File -// Name: ProtocolObject.h +// Name: Message.h // Purpose: Protocol object base class // Created: 2003/08/19 // @@ -10,22 +10,25 @@ #ifndef PROTOCOLOBJECT__H #define PROTOCOLOBJECT__H +#include <memory> + class Protocol; +class ProtocolContext; // -------------------------------------------------------------------------- // // Class -// Name: ProtocolObject +// Name: Message // Purpose: Basic object representation of objects to pass through a Protocol session // Created: 2003/08/19 // // -------------------------------------------------------------------------- -class ProtocolObject +class Message { public: - ProtocolObject(); - virtual ~ProtocolObject(); - ProtocolObject(const ProtocolObject &rToCopy); + Message(); + virtual ~Message(); + Message(const Message &rToCopy); // Info about this object virtual int GetType() const; @@ -35,7 +38,32 @@ public: // reading and writing with Protocol objects virtual void SetPropertiesFromStreamData(Protocol &rProtocol); virtual void WritePropertiesToStreamData(Protocol &rProtocol) const; + + virtual void LogSysLog(const char *Action) const { } + virtual void LogFile(const char *Action, FILE *file) const { } +}; + +/* +class Reply; + +class Request : public Message +{ +public: + Request() { } + virtual ~Request() { } + Request(const Request &rToCopy) { } + virtual std::auto_ptr<Reply> DoCommand(Protocol &rProtocol, + ProtocolContext &rContext) = 0; +}; + +class Reply : public Message +{ +public: + Reply() { } + virtual ~Reply() { } + Reply(const Reply &rToCopy) { } }; +*/ #endif // PROTOCOLOBJECT__H diff --git a/lib/server/Protocol.cpp b/lib/server/Protocol.cpp index 5dc5d0b1..82836007 100644 --- a/lib/server/Protocol.cpp +++ b/lib/server/Protocol.cpp @@ -11,8 +11,9 @@ #include <sys/types.h> -#include <stdlib.h> -#include <string.h> +#include <cstdlib> +#include <cstring> +#include <cstdio> #include <new> @@ -44,17 +45,17 @@ // // -------------------------------------------------------------------------- Protocol::Protocol(IOStream &rStream) - : mrStream(rStream), - mHandshakeDone(false), - mMaxObjectSize(PROTOCOL_DEFAULT_MAXOBJSIZE), - mTimeout(PROTOCOL_DEFAULT_TIMEOUT), - mpBuffer(0), - mBufferSize(0), - mReadOffset(-1), - mWriteOffset(-1), - mValidDataSize(-1), - mLastErrorType(NoError), - mLastErrorSubType(NoError) +: mrStream(rStream), + mHandshakeDone(false), + mMaxObjectSize(PROTOCOL_DEFAULT_MAXOBJSIZE), + mTimeout(PROTOCOL_DEFAULT_TIMEOUT), + mpBuffer(0), + mBufferSize(0), + mReadOffset(-1), + mWriteOffset(-1), + mValidDataSize(-1), + mLogToSysLog(false), + mLogToFile(NULL) { BOX_TRACE("Send block allocation size is " << PROTOCOL_ALLOCATE_SEND_BLOCK_CHUNK); @@ -82,34 +83,6 @@ Protocol::~Protocol() // -------------------------------------------------------------------------- // // Function -// Name: Protocol::GetLastError(int &, int &) -// Purpose: Returns true if there was an error, and type and subtype if there was. -// Created: 2003/08/19 -// -// -------------------------------------------------------------------------- -bool Protocol::GetLastError(int &rTypeOut, int &rSubTypeOut) -{ - if(mLastErrorType == NoError) - { - // no error. - return false; - } - - // Return type and subtype in args - rTypeOut = mLastErrorType; - rSubTypeOut = mLastErrorSubType; - - // and unset them - mLastErrorType = NoError; - mLastErrorSubType = NoError; - - return true; -} - - -// -------------------------------------------------------------------------- -// -// Function // Name: Protocol::Handshake() // Purpose: Handshake with peer (exchange ident strings) // Created: 2003/08/20 @@ -127,7 +100,7 @@ void Protocol::Handshake() PW_Handshake hsSend; ::memset(&hsSend, 0, sizeof(hsSend)); // Copy in ident string - ::strncpy(hsSend.mIdent, GetIdentString(), sizeof(hsSend.mIdent)); + ::strncpy(hsSend.mIdent, GetProtocolIdentString(), sizeof(hsSend.mIdent)); // Send it mrStream.Write(&hsSend, sizeof(hsSend)); @@ -200,7 +173,7 @@ void Protocol::CheckAndReadHdr(void *hdr) // Created: 2003/08/19 // // -------------------------------------------------------------------------- -std::auto_ptr<ProtocolObject> Protocol::Receive() +std::auto_ptr<Message> Protocol::ReceiveInternal() { // Get object header PW_ObjectHeader objHeader; @@ -220,7 +193,7 @@ std::auto_ptr<ProtocolObject> Protocol::Receive() } // Create a blank object - std::auto_ptr<ProtocolObject> obj(MakeProtocolObject(ntohl(objHeader.mObjType))); + std::auto_ptr<Message> obj(MakeMessage(ntohl(objHeader.mObjType))); // Make sure memory is allocated to read it into EnsureBufferAllocated(objSize); @@ -272,7 +245,7 @@ std::auto_ptr<ProtocolObject> Protocol::Receive() // Created: 2003/08/19 // // -------------------------------------------------------------------------- -void Protocol::Send(const ProtocolObject &rObject) +void Protocol::SendInternal(const Message &rObject) { // Check usage if(mValidDataSize != -1 || mWriteOffset != -1 || mReadOffset != -1) @@ -854,7 +827,26 @@ int Protocol::SendStreamSendBlock(uint8_t *Block, int BytesInBlock) // -------------------------------------------------------------------------- void Protocol::InformStreamReceiving(u_int32_t Size) { - // Do nothing + if(GetLogToSysLog()) + { + if(Size == Protocol::ProtocolStream_SizeUncertain) + { + BOX_TRACE("Receiving stream, size uncertain"); + } + else + { + BOX_TRACE("Receiving stream, size " << Size); + } + } + + if(GetLogToFile()) + { + ::fprintf(GetLogToFile(), + (Size == Protocol::ProtocolStream_SizeUncertain) + ? "Receiving stream, size uncertain\n" + : "Receiving stream, size %d\n", Size); + ::fflush(GetLogToFile()); + } } // -------------------------------------------------------------------------- @@ -867,7 +859,26 @@ void Protocol::InformStreamReceiving(u_int32_t Size) // -------------------------------------------------------------------------- void Protocol::InformStreamSending(u_int32_t Size) { - // Do nothing + if(GetLogToSysLog()) + { + if(Size == Protocol::ProtocolStream_SizeUncertain) + { + BOX_TRACE("Sending stream, size uncertain"); + } + else + { + BOX_TRACE("Sending stream, size " << Size); + } + } + + if(GetLogToFile()) + { + ::fprintf(GetLogToFile(), + (Size == Protocol::ProtocolStream_SizeUncertain) + ? "Sending stream, size uncertain\n" + : "Sending stream, size %d\n", Size); + ::fflush(GetLogToFile()); + } } diff --git a/lib/server/Protocol.h b/lib/server/Protocol.h index e037e33c..42cb0ff8 100644 --- a/lib/server/Protocol.h +++ b/lib/server/Protocol.h @@ -12,12 +12,14 @@ #include <sys/types.h> -class IOStream; -#include "ProtocolObject.h" #include <memory> #include <vector> #include <string> +#include "Message.h" + +class IOStream; + // default timeout is 15 minutes #define PROTOCOL_DEFAULT_TIMEOUT (15*60*1000) // 16 default maximum object size -- should be enough @@ -40,11 +42,14 @@ public: private: Protocol(const Protocol &rToCopy); +protected: + // Unsafe to make public, as they may allow sending objects + // from a different protocol. The derived class prevents this. + std::auto_ptr<Message> ReceiveInternal(); + void SendInternal(const Message &rObject); + public: void Handshake(); - std::auto_ptr<ProtocolObject> Receive(); - void Send(const ProtocolObject &rObject); - std::auto_ptr<IOStream> ReceiveStream(); void SendStream(IOStream &rStream); @@ -54,8 +59,6 @@ public: UnknownError = 0 }; - bool GetLastError(int &rTypeOut, int &rSubTypeOut); - // -------------------------------------------------------------------------- // // Function @@ -87,7 +90,7 @@ public: // -------------------------------------------------------------------------- void SetMaxObjectSize(unsigned int NewMaxObjSize) {mMaxObjectSize = NewMaxObjSize;} - // For ProtocolObject derived classes + // For Message derived classes void Read(void *Buffer, int Size); void Read(std::string &rOut, int Size); void Read(int64_t &rOut); @@ -168,11 +171,15 @@ public: { ProtocolStream_SizeUncertain = 0xffffffff }; + bool GetLogToSysLog() { return mLogToSysLog; } + FILE *GetLogToFile() { return mLogToFile; } + void SetLogToSysLog(bool Log = false) {mLogToSysLog = Log;} + void SetLogToFile(FILE *File = 0) {mLogToFile = File;} -protected: - virtual std::auto_ptr<ProtocolObject> MakeProtocolObject(int ObjType) = 0; - virtual const char *GetIdentString() = 0; - void SetError(int Type, int SubType) {mLastErrorType = Type; mLastErrorSubType = SubType;} +protected: + virtual std::auto_ptr<Message> MakeMessage(int ObjType) = 0; + virtual const char *GetProtocolIdentString() = 0; + void CheckAndReadHdr(void *hdr); // don't use type here to avoid dependency // Will be used for logging @@ -183,7 +190,6 @@ private: void EnsureBufferAllocated(int Size); int SendStreamSendBlock(uint8_t *Block, int BytesInBlock); -private: IOStream &mrStream; bool mHandshakeDone; unsigned int mMaxObjectSize; @@ -193,8 +199,12 @@ private: int mReadOffset; int mWriteOffset; int mValidDataSize; - int mLastErrorType; - int mLastErrorSubType; + bool mLogToSysLog; + FILE *mLogToFile; +}; + +class ProtocolContext +{ }; #endif // PROTOCOL__H diff --git a/lib/server/makeprotocol.pl.in b/lib/server/makeprotocol.pl.in index 91ba55b0..da4b9447 100755 --- a/lib/server/makeprotocol.pl.in +++ b/lib/server/makeprotocol.pl.in @@ -30,24 +30,19 @@ my %log_display_types = 'string' => ['%s', 'VAR.c_str()'] ); - - -my ($type, $file) = @ARGV; - -if($type ne 'Server' && $type ne 'Client') +if (@ARGV != 1) { - die "Neither Server or Client is specified on command line\n"; + die "Usage: $0 <protocol-txt-file>\n"; } +my ($file) = @ARGV; + open IN, $file or die "Can't open input file $file\n"; -print "Making $type protocol classes from $file...\n"; +print "Making protocol classes from $file...\n"; my @extra_header_files; -my $implement_syslog = 0; -my $implement_filelog = 0; - # read attributes my %attr; while(<IN>) @@ -59,41 +54,18 @@ while(<IN>) my ($k,$v) = split /\s+/,$l,2; - if($k eq 'ClientType') - { - add_type($v) if $type eq 'Client'; - } - elsif($k eq 'ServerType') + if($k eq 'AddType') { - add_type($v) if $type eq 'Server'; + add_type($v); } elsif($k eq 'ImplementLog') { - my ($log_if_type,$log_type) = split /\s+/,$v; - if($type eq $log_if_type) - { - if($log_type eq 'syslog') - { - $implement_syslog = 1; - } - elsif($log_type eq 'file') - { - $implement_filelog = 1; - } - else - { - printf("ERROR: Unknown log type for implementation: $log_type\n"); - exit(1); - } - } + # Always implement logging } elsif($k eq 'LogTypeToText') { - my ($log_if_type,$type_name,$printf_format,$arg_template) = split /\s+/,$v; - if($type eq $log_if_type) - { - $log_display_types{$type_name} = [$printf_format,$arg_template] - } + my ($type_name,$printf_format,$arg_template) = split /\s+/,$v; + $log_display_types{$type_name} = [$printf_format,$arg_template] } else { @@ -169,10 +141,12 @@ close IN; # open files -my $h_filename = 'autogen_'.$protocol_name.'Protocol'.$type.'.h'; -open CPP,'>autogen_'.$protocol_name.'Protocol'.$type.'.cpp'; +my $h_filename = 'autogen_'.$protocol_name.'Protocol.h'; +open CPP,'>autogen_'.$protocol_name.'Protocol.cpp'; open H,">$h_filename"; +my $guardname = uc 'AUTOGEN_'.$protocol_name.'Protocol_H'; + print CPP <<__E; // Auto-generated file -- do not edit @@ -183,149 +157,125 @@ print CPP <<__E; #include "$h_filename" #include "IOStream.h" - __E -if($implement_syslog) -{ - print H <<EOF; -#ifndef WIN32 -#include <syslog.h> -#endif -EOF -} - - -my $guardname = uc 'AUTOGEN_'.$protocol_name.'Protocol'.$type.'_H'; print H <<__E; - // Auto-generated file -- do not edit #ifndef $guardname #define $guardname +#include <cstdio> +#include <list> + +#ifndef WIN32 +#include <syslog.h> +#endif + #include "Protocol.h" -#include "ProtocolObject.h" +#include "Message.h" #include "ServerException.h" class IOStream; -__E -if($implement_filelog) -{ - print H qq~#include <stdio.h>\n~; -} +__E # extra headers for(@extra_header_files) { - print H qq~#include "$_"\n~ + print H qq@#include "$_"\n@; } -print H "\n"; -if($type eq 'Server') -{ - # need utils file for the server - print H '#include "Utils.h"',"\n\n" -} +print H <<__E; + +// need utils file for the server +#include "Utils.h" +__E -my $derive_objects_from = 'ProtocolObject'; +my $message_base_class = "${protocol_name}ProtocolMessage"; my $objects_extra_h = ''; my $objects_extra_cpp = ''; -if($type eq 'Server') -{ - # define the context - print H "class $context_class;\n\n"; - print CPP "#include \"$context_class_inc\"\n\n"; - - # change class we derive the objects from - $derive_objects_from = $protocol_name.'ProtocolObject'; - - $objects_extra_h = <<__E; - virtual std::auto_ptr<ProtocolObject> DoCommand(${protocol_name}ProtocolServer &rProtocol, $context_class &rContext); -__E - $objects_extra_cpp = <<__E; -std::auto_ptr<ProtocolObject> ${derive_objects_from}::DoCommand(${protocol_name}ProtocolServer &rProtocol, $context_class &rContext) -{ - THROW_EXCEPTION(ConnectionException, Conn_Protocol_TriedToExecuteReplyCommand) -} + +# define the context +print H "class $context_class;\n\n"; +print CPP <<__E; +#include "$context_class_inc" +#include "MemLeakFindOn.h" __E -} -print CPP qq~#include "MemLeakFindOn.h"\n~; +my $request_base_class = "${protocol_name}ProtocolRequest"; +my $reply_base_class = "${protocol_name}ProtocolReply"; +# the abstract protocol interface +my $protocol_base_class = $protocol_name."ProtocolBase"; +my $replyable_base_class = $protocol_name."ProtocolReplyable"; -if($type eq 'Client' && ($implement_syslog || $implement_filelog)) -{ - # change class we derive the objects from - $derive_objects_from = $protocol_name.'ProtocolObjectCl'; -} -if($implement_syslog) -{ - $objects_extra_h .= <<__E; - virtual void LogSysLog(const char *Action) const = 0; -__E -} -if($implement_filelog) -{ - $objects_extra_h .= <<__E; - virtual void LogFile(const char *Action, FILE *file) const = 0; -__E -} +print H <<__E; +class $protocol_base_class; +class $replyable_base_class; +class $reply_base_class; -if($derive_objects_from ne 'ProtocolObject') -{ - # output a definition for the protocol object derived class - print H <<__E; -class ${protocol_name}ProtocolServer; - -class $derive_objects_from : public ProtocolObject +class $message_base_class : public Message { public: - $derive_objects_from(); - virtual ~$derive_objects_from(); - $derive_objects_from(const $derive_objects_from &rToCopy); - -$objects_extra_h + virtual std::auto_ptr<$message_base_class> DoCommand($replyable_base_class &rProtocol, + $context_class &rContext) const; }; -__E - # and some cpp definitions - print CPP <<__E; -${derive_objects_from}::${derive_objects_from}() +class $reply_base_class { -} -${derive_objects_from}::~${derive_objects_from}() +}; + +class $request_base_class { -} -${derive_objects_from}::${derive_objects_from}(const $derive_objects_from &rToCopy) +}; + +__E + +print CPP <<__E; +std::auto_ptr<$message_base_class> $message_base_class\::DoCommand($replyable_base_class &rProtocol, + $context_class &rContext) const { + THROW_EXCEPTION(ConnectionException, Conn_Protocol_TriedToExecuteReplyCommand) } -$objects_extra_cpp __E -} - - -my $classname_base = $protocol_name.'Protocol'.$type; +my %cmd_class; # output the classes -for my $cmd (@cmd_list) +foreach my $cmd (@cmd_list) { + my @cmd_base_classes = ($message_base_class); + + if(obj_is_type($cmd, 'Command')) + { + push @cmd_base_classes, $request_base_class; + } + + if(obj_is_type($cmd, 'Reply')) + { + push @cmd_base_classes, $reply_base_class; + } + + my $cmd_base_class = join(", ", map {"public $_"} @cmd_base_classes); + my $cmd_class = $protocol_name."ProtocolClient".$cmd; + $cmd_class{$cmd} = $cmd_class; + print H <<__E; -class $classname_base$cmd : public $derive_objects_from +class $cmd_class : $cmd_base_class { public: - $classname_base$cmd(); - $classname_base$cmd(const $classname_base$cmd &rToCopy); - ~$classname_base$cmd(); + $cmd_class(); + $cmd_class(const $cmd_class &rToCopy); + ~$cmd_class(); int GetType() const; enum { TypeID = $cmd_id{$cmd} }; __E + # constants if(exists $cmd_constants{$cmd}) { @@ -333,72 +283,63 @@ __E print H join(",\n\t\t",@{$cmd_constants{$cmd}}); print H "\n\t};\n"; } + # flags if(obj_is_type($cmd,'EndsConversation')) { print H "\tbool IsConversationEnd() const;\n"; } + if(obj_is_type($cmd,'IsError')) { print H "\tbool IsError(int &rTypeOut, int &rSubTypeOut) const;\n"; print H "\tstd::string GetMessage() const;\n"; } - if($type eq 'Server' && obj_is_type($cmd, 'Command')) + + if(obj_is_type($cmd, 'Command')) { - print H "\tstd::auto_ptr<ProtocolObject> DoCommand(${protocol_name}ProtocolServer &rProtocol, $context_class &rContext); // IMPLEMENT THIS\n" + print H <<__E; + std::auto_ptr<$message_base_class> DoCommand($replyable_base_class &rProtocol, + $context_class &rContext) const; // IMPLEMENT THIS\n +__E } # want to be able to read from streams? - my $read_from_streams = (obj_is_type($cmd,'Command') && $type eq 'Server') || (obj_is_type($cmd,'Reply') && $type eq 'Client'); - my $write_to_streams = (obj_is_type($cmd,'Command') && $type eq 'Client') || (obj_is_type($cmd,'Reply') && $type eq 'Server'); + print H "\tvoid SetPropertiesFromStreamData(Protocol &rProtocol);\n"; - if($read_from_streams) + # write Get functions + for(my $x = 0; $x < $#{$cmd_contents{$cmd}}; $x+=2) { - print H "\tvoid SetPropertiesFromStreamData(Protocol &rProtocol);\n"; + my ($ty,$nm) = (${$cmd_contents{$cmd}}[$x], ${$cmd_contents{$cmd}}[$x+1]); - # write Get functions - for(my $x = 0; $x < $#{$cmd_contents{$cmd}}; $x+=2) - { - my ($ty,$nm) = (${$cmd_contents{$cmd}}[$x], ${$cmd_contents{$cmd}}[$x+1]); - - print H "\t".translate_type_to_arg_type($ty)." Get$nm() {return m$nm;}\n"; - } + print H "\t".translate_type_to_arg_type($ty)." Get$nm() {return m$nm;}\n"; } + my $param_con_args = ''; - if($write_to_streams) + # extra constructor? + if($#{$cmd_contents{$cmd}} >= 0) { - # extra constructor? - if($#{$cmd_contents{$cmd}} >= 0) - { - my @a; - for(my $x = 0; $x < $#{$cmd_contents{$cmd}}; $x+=2) - { - my ($ty,$nm) = (${$cmd_contents{$cmd}}[$x], ${$cmd_contents{$cmd}}[$x+1]); - - push @a,translate_type_to_arg_type($ty)." $nm"; - } - $param_con_args = join(', ',@a); - print H "\t$classname_base$cmd(".$param_con_args.");\n"; - } - print H "\tvoid WritePropertiesToStreamData(Protocol &rProtocol) const;\n"; - # set functions + my @a; for(my $x = 0; $x < $#{$cmd_contents{$cmd}}; $x+=2) { my ($ty,$nm) = (${$cmd_contents{$cmd}}[$x], ${$cmd_contents{$cmd}}[$x+1]); - - print H "\tvoid Set$nm(".translate_type_to_arg_type($ty)." $nm) {m$nm = $nm;}\n"; - } - } - - if($implement_syslog) - { - print H "\tvirtual void LogSysLog(const char *Action) const;\n"; + + push @a,translate_type_to_arg_type($ty)." $nm"; + } + $param_con_args = join(', ',@a); + print H "\t$cmd_class(".$param_con_args.");\n"; } - if($implement_filelog) + print H "\tvoid WritePropertiesToStreamData(Protocol &rProtocol) const;\n"; + # set functions + for(my $x = 0; $x < $#{$cmd_contents{$cmd}}; $x+=2) { - print H "\tvirtual void LogFile(const char *Action, FILE *file) const;\n"; + my ($ty,$nm) = (${$cmd_contents{$cmd}}[$x], ${$cmd_contents{$cmd}}[$x+1]); + + print H "\tvoid Set$nm(".translate_type_to_arg_type($ty)." $nm) {m$nm = $nm;}\n"; } - + + print H "\tvirtual void LogSysLog(const char *Action) const;\n"; + print H "\tvirtual void LogFile(const char *Action, FILE *file) const;\n"; # write member variables and setup for cpp file my @def_constructor_list; @@ -432,77 +373,73 @@ __E my $param_con_vars = join(",\n\t ",@param_constructor_list); $param_con_vars = "\n\t: ".$param_con_vars if $param_con_vars ne ''; - my $class = "$classname_base$cmd".'::'; print CPP <<__E; -$class$classname_base$cmd()$def_con_vars +$cmd_class\::$cmd_class()$def_con_vars { } -$class$classname_base$cmd(const $classname_base$cmd &rToCopy)$copy_con_vars +$cmd_class\::$cmd_class(const $cmd_class &rToCopy)$copy_con_vars { } -$class~$classname_base$cmd() +$cmd_class\::~$cmd_class() { } -int ${class}GetType() const +int $cmd_class\::GetType() const { return $cmd_id{$cmd}; } __E - if($read_from_streams) + print CPP "void $cmd_class\::SetPropertiesFromStreamData(Protocol &rProtocol)\n{\n"; + for(my $x = 0; $x < $#{$cmd_contents{$cmd}}; $x+=2) { - print CPP "void ${class}SetPropertiesFromStreamData(Protocol &rProtocol)\n{\n"; - for(my $x = 0; $x < $#{$cmd_contents{$cmd}}; $x+=2) + my ($ty,$nm) = (${$cmd_contents{$cmd}}[$x], ${$cmd_contents{$cmd}}[$x+1]); + if($ty =~ m/\Avector/) { - my ($ty,$nm) = (${$cmd_contents{$cmd}}[$x], ${$cmd_contents{$cmd}}[$x+1]); - if($ty =~ m/\Avector/) - { - print CPP "\trProtocol.ReadVector(m$nm);\n"; - } - else - { - print CPP "\trProtocol.Read(m$nm);\n"; - } + print CPP "\trProtocol.ReadVector(m$nm);\n"; + } + else + { + print CPP "\trProtocol.Read(m$nm);\n"; } - print CPP "}\n"; } - if($write_to_streams) + print CPP "}\n"; + + # implement extra constructor? + if($param_con_vars ne '') + { + print CPP "$cmd_class\::$cmd_class($param_con_args)$param_con_vars\n{\n}\n"; + } + print CPP "void $cmd_class\::WritePropertiesToStreamData(Protocol &rProtocol) const\n{\n"; + for(my $x = 0; $x < $#{$cmd_contents{$cmd}}; $x+=2) { - # implement extra constructor? - if($param_con_vars ne '') + my ($ty,$nm) = (${$cmd_contents{$cmd}}[$x], ${$cmd_contents{$cmd}}[$x+1]); + if($ty =~ m/\Avector/) { - print CPP "$class$classname_base$cmd($param_con_args)$param_con_vars\n{\n}\n"; + print CPP "\trProtocol.WriteVector(m$nm);\n"; } - print CPP "void ${class}WritePropertiesToStreamData(Protocol &rProtocol) const\n{\n"; - for(my $x = 0; $x < $#{$cmd_contents{$cmd}}; $x+=2) + else { - my ($ty,$nm) = (${$cmd_contents{$cmd}}[$x], ${$cmd_contents{$cmd}}[$x+1]); - if($ty =~ m/\Avector/) - { - print CPP "\trProtocol.WriteVector(m$nm);\n"; - } - else - { - print CPP "\trProtocol.Write(m$nm);\n"; - } + print CPP "\trProtocol.Write(m$nm);\n"; } - print CPP "}\n"; } + print CPP "}\n"; + if(obj_is_type($cmd,'EndsConversation')) { - print CPP "bool ${class}IsConversationEnd() const\n{\n\treturn true;\n}\n"; + print CPP "bool $cmd_class\::IsConversationEnd() const\n{\n\treturn true;\n}\n"; } + if(obj_is_type($cmd,'IsError')) { # get parameters my ($mem_type,$mem_subtype) = split /,/,obj_get_type_params($cmd,'IsError'); print CPP <<__E; -bool ${class}IsError(int &rTypeOut, int &rSubTypeOut) const +bool $cmd_class\::IsError(int &rTypeOut, int &rSubTypeOut) const { rTypeOut = m$mem_type; rSubTypeOut = m$mem_subtype; return true; } -std::string ${class}GetMessage() const +std::string $cmd_class\::GetMessage() const { switch(m$mem_subtype) { @@ -526,21 +463,13 @@ __E __E } - if($implement_syslog) - { - my ($log) = make_log_strings_framework($cmd); - print CPP <<__E; -void ${class}LogSysLog(const char *Action) const + my ($log) = make_log_strings_framework($cmd); + print CPP <<__E; +void $cmd_class\::LogSysLog(const char *Action) const { BOX_TRACE($log); } -__E - } - if($implement_filelog) - { - my ($log) = make_log_strings_framework($cmd); - print CPP <<__E; -void ${class}LogFile(const char *Action, FILE *File) const +void $cmd_class\::LogFile(const char *Action, FILE *File) const { std::ostringstream oss; oss << $log; @@ -548,208 +477,476 @@ void ${class}LogFile(const char *Action, FILE *File) const ::fflush(File); } __E - } } -# finally, the protocol object itself +my $error_class = $protocol_name."ProtocolError"; + +# the abstract protocol interface print H <<__E; -class $classname_base : public Protocol +class $protocol_base_class { public: - $classname_base(IOStream &rStream); - virtual ~$classname_base(); + $protocol_base_class(); + virtual ~$protocol_base_class(); + virtual const char *GetIdentString(); + bool GetLastError(int &rTypeOut, int &rSubTypeOut); + +protected: + void CheckReply(const std::string& requestCommand, + const $message_base_class &rReply, int expectedType); + void SetLastError(int Type, int SubType) + { + mLastErrorType = Type; + mLastErrorSubType = SubType; + } + +private: + $protocol_base_class(const $protocol_base_class &rToCopy); /* do not call */ + int mLastErrorType; + int mLastErrorSubType; +}; + +class $replyable_base_class : public virtual $protocol_base_class +{ +public: + $replyable_base_class(); + virtual ~$replyable_base_class(); + + /* + virtual std::auto_ptr<$message_base_class> Receive() = 0; + virtual void Send(const ${message_base_class} &rObject) = 0; + */ + + virtual std::auto_ptr<IOStream> ReceiveStream() = 0; + virtual int GetTimeout() = 0; + void SendStreamAfterCommand(IOStream *pStream); + +protected: + std::list<IOStream*> mStreamsToSend; + void DeleteStreamsToSend(); + +private: + $replyable_base_class(const $replyable_base_class &rToCopy); /* do not call */ +}; - std::auto_ptr<$derive_objects_from> Receive(); - void Send(const ${derive_objects_from} &rObject); __E -if($implement_syslog) + +print CPP <<__E; +$protocol_base_class\::$protocol_base_class() +: mLastErrorType(Protocol::NoError), + mLastErrorSubType(Protocol::NoError) +{ } + +$protocol_base_class\::~$protocol_base_class() +{ } + +const char *$protocol_base_class\::GetIdentString() { - print H "\tvoid SetLogToSysLog(bool Log = false) {mLogToSysLog = Log;}\n"; + return "$ident_string"; } -if($implement_filelog) + +$replyable_base_class\::$replyable_base_class() +{ } + +$replyable_base_class\::~$replyable_base_class() +{ } + +void $replyable_base_class\::SendStreamAfterCommand(IOStream *pStream) { - print H "\tvoid SetLogToFile(FILE *File = 0) {mLogToFile = File;}\n"; + ASSERT(pStream != NULL); + mStreamsToSend.push_back(pStream); } -if($type eq 'Server') + +void $replyable_base_class\::DeleteStreamsToSend() { - # need to put in the conversation function - print H "\tvoid DoServer($context_class &rContext);\n\n"; - # and the send vector thing - print H "\tvoid SendStreamAfterCommand(IOStream *pStream);\n\n"; + for(std::list<IOStream*>::iterator i(mStreamsToSend.begin()); i != mStreamsToSend.end(); ++i) + { + delete (*i); + } + mStreamsToSend.clear(); } -if($type eq 'Client') + +void $protocol_base_class\::CheckReply(const std::string& requestCommand, + const $message_base_class &rReply, int expectedType) { - # add plain object taking query functions - my $with_params; - for my $cmd (@cmd_list) + if(rReply.GetType() == expectedType) + { + // Correct response, do nothing + } + else { - if(obj_is_type($cmd,'Command')) + // Set protocol error + int type, subType; + + if(rReply.IsError(type, subType)) { - my $has_stream = obj_is_type($cmd,'StreamWithCommand'); - my $argextra = $has_stream?', IOStream &rStream':''; - my $queryextra = $has_stream?', rStream':''; - my $reply = obj_get_type_params($cmd,'Command'); - print H "\tstd::auto_ptr<$classname_base$reply> Query(const $classname_base$cmd &rQuery$argextra);\n"; - my @a; - my @na; - for(my $x = 0; $x < $#{$cmd_contents{$cmd}}; $x+=2) - { - my ($ty,$nm) = (${$cmd_contents{$cmd}}[$x], ${$cmd_contents{$cmd}}[$x+1]); - push @a,translate_type_to_arg_type($ty)." $nm"; - push @na,"$nm"; - } - my $ar = join(', ',@a); - my $nar = join(', ',@na); - $nar = "($nar)" if $nar ne ''; - - $with_params .= "\tinline std::auto_ptr<$classname_base$reply> Query$cmd($ar$argextra)\n\t{\n"; - $with_params .= "\t\t$classname_base$cmd send$nar;\n"; - $with_params .= "\t\treturn Query(send$queryextra);\n"; - $with_params .= "\t}\n"; + SetLastError(type, subType); + BOX_WARNING(requestCommand << " command failed: " + "received error " << + (($error_class&)rReply).GetMessage()); + } + else + { + SetLastError(Protocol::UnknownError, Protocol::UnknownError); + BOX_WARNING(requestCommand << " command failed: " + "received unexpected response type " << + rReply.GetType()); } + + // Throw an exception + THROW_EXCEPTION(ConnectionException, Conn_Protocol_UnexpectedReply) } - # quick hack to correct bad argument lists for commands with zero paramters but with streams - $with_params =~ s/\(, /(/g; - print H "\n",$with_params,"\n"; } -print H <<__E; -private: - $classname_base(const $classname_base &rToCopy); -__E -if($type eq 'Server') + +// -------------------------------------------------------------------------- +// +// Function +// Name: Protocol::GetLastError(int &, int &) +// Purpose: Returns true if there was an error, and type and subtype if there was. +// Created: 2003/08/19 +// +// -------------------------------------------------------------------------- +bool $protocol_base_class\::GetLastError(int &rTypeOut, int &rSubTypeOut) { - # need to put the streams to send vector - print H "\tstd::vector<IOStream*> mStreamsToSend;\n\tvoid DeleteStreamsToSend();\n"; + if(mLastErrorType == Protocol::NoError) + { + // no error. + return false; + } + + // Return type and subtype in args + rTypeOut = mLastErrorType; + rSubTypeOut = mLastErrorSubType; + + // and unset them + mLastErrorType = Protocol::NoError; + mLastErrorSubType = Protocol::NoError; + + return true; } -if($implement_filelog || $implement_syslog) -{ - print H <<__E; - virtual void InformStreamReceiving(u_int32_t Size); - virtual void InformStreamSending(u_int32_t Size); __E -} -if($implement_syslog) +# the callable protocol interface (implemented by Client and Local classes) +# with Query methods that don't take a context parameter +my $callable_base_class = $protocol_name."ProtocolCallable"; +print H <<__E; +class $callable_base_class : public virtual $protocol_base_class { - print H "private:\n\tbool mLogToSysLog;\n"; -} -if($implement_filelog) +public: + virtual std::auto_ptr<IOStream> ReceiveStream() = 0; + virtual int GetTimeout() = 0; +__E + +# add plain object taking query functions +my $with_params; +for my $cmd (@cmd_list) { - print H "private:\n\tFILE *mLogToFile;\n"; + if(obj_is_type($cmd,'Command')) + { + my $has_stream = obj_is_type($cmd,'StreamWithCommand'); + my $argextra = $has_stream?', IOStream &rStream':''; + my $queryextra = $has_stream?', rStream':''; + my $request_class = $cmd_class{$cmd}; + my $reply_class = $cmd_class{obj_get_type_params($cmd,'Command')}; + + print H "\tvirtual std::auto_ptr<$reply_class> Query(const $request_class &rQuery$argextra) = 0;\n"; + my @a; + my @na; + for(my $x = 0; $x < $#{$cmd_contents{$cmd}}; $x+=2) + { + my ($ty,$nm) = (${$cmd_contents{$cmd}}[$x], ${$cmd_contents{$cmd}}[$x+1]); + push @a,translate_type_to_arg_type($ty)." $nm"; + push @na,"$nm"; + } + my $ar = join(', ',@a); + my $nar = join(', ',@na); + $nar = "($nar)" if $nar ne ''; + + $with_params .= <<__E; + inline std::auto_ptr<$reply_class> Query$cmd($ar$argextra) + { + $request_class send$nar; + return Query(send$queryextra); + } +__E + } } + +# quick hack to correct bad argument lists for commands with zero parameters but with streams +$with_params =~ s/\(, /(/g; + print H <<__E; -protected: - virtual std::auto_ptr<ProtocolObject> MakeProtocolObject(int ObjType); - virtual const char *GetIdentString(); +$with_params }; - __E -my $constructor_extra = ''; -$constructor_extra .= ', mLogToSysLog(false)' if $implement_syslog; -$constructor_extra .= ', mLogToFile(0)' if $implement_filelog; +# standard remote protocol objects +foreach my $type ('Client', 'Server', 'Local') +{ + my $writing_client = ($type eq 'Client'); + my $writing_server = ($type eq 'Server'); + my $writing_local = ($type eq 'Local'); + + my $server_or_client_class = $protocol_name."Protocol".$type; + my @base_classes; -my $destructor_extra = ($type eq 'Server')?"\n\tDeleteStreamsToSend();":''; + if (not $writing_client) + { + push @base_classes, $replyable_base_class; + } + if (not $writing_server) + { + push @base_classes, $callable_base_class; + } + if (not $writing_local) + { + push @base_classes, "Protocol"; + } -my $prefix = $classname_base.'::'; -print CPP <<__E; -$prefix$classname_base(IOStream &rStream) - : Protocol(rStream)$constructor_extra + my $base_classes_str = join(", ", map {"public $_"} @base_classes); + + print H <<__E; +class $server_or_client_class : $base_classes_str { -} -$prefix~$classname_base() +public: +__E + + if($writing_local) + { + print H <<__E; + $server_or_client_class($context_class &rContext); +__E + } + else + { + print H <<__E; + $server_or_client_class(IOStream &rStream); + std::auto_ptr<$message_base_class> Receive(); + void Send(const $message_base_class &rObject); +__E + } + + print H <<__E; + virtual ~$server_or_client_class(); +__E + + if($writing_server) + { + # need to put in the conversation function + print H <<__E; + void DoServer($context_class &rContext); + +__E + } + + if($writing_client or $writing_local) + { + # add plain object taking query functions + for my $cmd (@cmd_list) + { + if(obj_is_type($cmd,'Command')) + { + my $has_stream = obj_is_type($cmd,'StreamWithCommand'); + my $argextra = $has_stream?', IOStream &rStream':''; + my $queryextra = $has_stream?', rStream':''; + my $request_class = $cmd_class{$cmd}; + my $reply_class = $cmd_class{obj_get_type_params($cmd,'Command')}; + print H "\tstd::auto_ptr<$reply_class> Query(const $request_class &rQuery$argextra);\n"; + } + } + } + + if($writing_local) + { + print H <<__E; +private: + $context_class &mrContext; +__E + } + + print H <<__E; + +protected: + virtual std::auto_ptr<Message> MakeMessage(int ObjType); + +__E + + if($writing_local) + { + print H <<__E; + virtual void InformStreamReceiving(u_int32_t Size) { } + virtual void InformStreamSending(u_int32_t Size) { } + +public: + virtual std::auto_ptr<IOStream> ReceiveStream() + { + std::auto_ptr<IOStream> apStream(mStreamsToSend.front()); + mStreamsToSend.pop_front(); + return apStream; + } +__E + } + else + { + print H <<__E; + virtual void InformStreamReceiving(u_int32_t Size) + { + this->Protocol::InformStreamReceiving(Size); + } + virtual void InformStreamSending(u_int32_t Size) + { + this->Protocol::InformStreamSending(Size); + } + +public: + virtual std::auto_ptr<IOStream> ReceiveStream() + { + return this->Protocol::ReceiveStream(); + } +__E + } + + print H <<__E; + virtual const char *GetProtocolIdentString() + { + return GetIdentString(); + } +__E + + if($writing_local) + { + print H <<__E; + virtual int GetTimeout() + { + return IOStream::TimeOutInfinite; + } +__E + } + else + { + print H <<__E; + virtual int GetTimeout() + { + return this->Protocol::GetTimeout(); + } +__E + } + + print H <<__E; + /* + virtual void Handshake() + { + this->Protocol::Handshake(); + } + virtual bool GetLastError(int &rTypeOut, int &rSubTypeOut) + { + return this->Protocol::GetLastError(rTypeOut, rSubTypeOut); + } + */ + +private: + $server_or_client_class(const $server_or_client_class &rToCopy); /* no copies */ +}; + +__E + + my $destructor_extra = ($writing_server) ? "\n\tDeleteStreamsToSend();" + : ''; + + if($writing_local) + { + print CPP <<__E; +$server_or_client_class\::$server_or_client_class($context_class &rContext) +: mrContext(rContext) +{ } +__E + } + else + { + print CPP <<__E; +$server_or_client_class\::$server_or_client_class(IOStream &rStream) +: Protocol(rStream) +{ } +__E + } + + print CPP <<__E; +$server_or_client_class\::~$server_or_client_class() {$destructor_extra } -const char *${prefix}GetIdentString() -{ - return "$ident_string"; -} -std::auto_ptr<ProtocolObject> ${prefix}MakeProtocolObject(int ObjType) +__E + + # write receive and send functions + print CPP <<__E; +std::auto_ptr<Message> $server_or_client_class\::MakeMessage(int ObjType) { switch(ObjType) { __E -# do objects within this -for my $cmd (@cmd_list) -{ - print CPP <<__E; + # do objects within this + for my $cmd (@cmd_list) + { + print CPP <<__E; case $cmd_id{$cmd}: - return std::auto_ptr<ProtocolObject>(new $classname_base$cmd); + return std::auto_ptr<Message>(new $cmd_class{$cmd}()); break; __E -} + } -print CPP <<__E; + print CPP <<__E; default: THROW_EXCEPTION(ConnectionException, Conn_Protocol_UnknownCommandRecieved) } } __E -# write receive and send functions -print CPP <<__E; -std::auto_ptr<$derive_objects_from> ${prefix}Receive() -{ - std::auto_ptr<${derive_objects_from}> preply((${derive_objects_from}*)(Protocol::Receive().release())); -__E - if($implement_syslog) + if(not $writing_local) { print CPP <<__E; - if(mLogToSysLog) +std::auto_ptr<$message_base_class> $server_or_client_class\::Receive() +{ + std::auto_ptr<$message_base_class> preply(($message_base_class *) + Protocol::ReceiveInternal().release()); + + if(GetLogToSysLog()) { preply->LogSysLog("Receive"); } -__E - } - if($implement_filelog) - { - print CPP <<__E; - if(mLogToFile != 0) + + if(GetLogToFile() != 0) { - preply->LogFile("Receive", mLogToFile); + preply->LogFile("Receive", GetLogToFile()); } -__E - } -print CPP <<__E; return preply; } -void ${prefix}Send(const ${derive_objects_from} &rObject) +void $server_or_client_class\::Send(const $message_base_class &rObject) { -__E - if($implement_syslog) - { - print CPP <<__E; - if(mLogToSysLog) + if(GetLogToSysLog()) { rObject.LogSysLog("Send"); } -__E - } - if($implement_filelog) - { - print CPP <<__E; - if(mLogToFile != 0) + + if(GetLogToFile() != 0) { - rObject.LogFile("Send", mLogToFile); - } -__E + rObject.LogFile("Send", GetLogToFile()); } -print CPP <<__E; - Protocol::Send(rObject); + Protocol::SendInternal(rObject); } __E -# write server function? -if($type eq 'Server') -{ - print CPP <<__E; -void ${prefix}DoServer($context_class &rContext) + } + + # write server function? + if($writing_server) + { + print CPP <<__E; +void $server_or_client_class\::DoServer($context_class &rContext) { // Handshake with client Handshake(); @@ -759,20 +956,22 @@ void ${prefix}DoServer($context_class &rContext) while(inProgress) { // Get an object from the conversation - std::auto_ptr<${derive_objects_from}> pobj(Receive()); + std::auto_ptr<$message_base_class> pobj = Receive(); // Run the command - std::auto_ptr<${derive_objects_from}> preply((${derive_objects_from}*)(pobj->DoCommand(*this, rContext).release())); + std::auto_ptr<$message_base_class> preply = pobj->DoCommand(*this, rContext); // Send the reply - Send(*(preply.get())); + Send(*preply); // Send any streams - for(unsigned int s = 0; s < mStreamsToSend.size(); s++) + for(std::list<IOStream*>::iterator + i = mStreamsToSend.begin(); + i != mStreamsToSend.end(); ++i) { - // Send the streams - SendStream(*mStreamsToSend[s]); + SendStream(**i); } + // Delete these streams DeleteStreamsToSend(); @@ -784,161 +983,82 @@ void ${prefix}DoServer($context_class &rContext) } } -void ${prefix}SendStreamAfterCommand(IOStream *pStream) -{ - ASSERT(pStream != NULL); - mStreamsToSend.push_back(pStream); -} - -void ${prefix}DeleteStreamsToSend() -{ - for(std::vector<IOStream*>::iterator i(mStreamsToSend.begin()); i != mStreamsToSend.end(); ++i) - { - delete (*i); - } - mStreamsToSend.clear(); -} - -__E -} - -# write logging functions? -if($implement_filelog || $implement_syslog) -{ - my ($fR,$fS); - - if($implement_syslog) - { - $fR .= <<__E; - if(mLogToSysLog) - { - if(Size==Protocol::ProtocolStream_SizeUncertain) - { - BOX_TRACE("Receiving stream, size uncertain"); - } - else - { - BOX_TRACE("Receiving stream, size " << Size); - } - } -__E - - $fS .= <<__E; - if(mLogToSysLog) - { - if(Size==Protocol::ProtocolStream_SizeUncertain) - { - BOX_TRACE("Sending stream, size uncertain"); - } - else - { - BOX_TRACE("Sending stream, size " << Size); - } - } -__E - } - - if($implement_filelog) - { - $fR .= <<__E; - if(mLogToFile) - { - ::fprintf(mLogToFile, - (Size==Protocol::ProtocolStream_SizeUncertain) - ?"Receiving stream, size uncertain\\n" - :"Receiving stream, size %d\\n", Size); - ::fflush(mLogToFile); - } -__E - $fS .= <<__E; - if(mLogToFile) - { - ::fprintf(mLogToFile, - (Size==Protocol::ProtocolStream_SizeUncertain) - ?"Sending stream, size uncertain\\n" - :"Sending stream, size %d\\n", Size); - ::fflush(mLogToFile); - } __E } - print CPP <<__E; - -void ${prefix}InformStreamReceiving(u_int32_t Size) -{ -$fR} - -void ${prefix}InformStreamSending(u_int32_t Size) -{ -$fS} - -__E -} - - -# write client Query functions? -if($type eq 'Client') -{ - for my $cmd (@cmd_list) + # write client Query functions? + if($writing_client or $writing_local) { - if(obj_is_type($cmd,'Command')) + for my $cmd (@cmd_list) { - my $reply = obj_get_type_params($cmd,'Command'); - my $reply_id = $cmd_id{$reply}; - my $has_stream = obj_is_type($cmd,'StreamWithCommand'); - my $argextra = $has_stream?', IOStream &rStream':''; - my $send_stream_extra = ''; - if($has_stream) + if(obj_is_type($cmd,'Command')) { - $send_stream_extra = <<__E; - + my $request_class = $cmd_class{$cmd}; + my $reply_msg = obj_get_type_params($cmd,'Command'); + my $reply_class = $cmd_class{$reply_msg}; + my $reply_id = $cmd_id{$reply_msg}; + my $has_stream = obj_is_type($cmd,'StreamWithCommand'); + my $argextra = $has_stream?', IOStream &rStream':''; + my $send_stream_extra = ''; + my $send_stream_method = $writing_client ? "SendStream" + : "SendStreamAfterCommand"; + + if($writing_client) + { + if($has_stream) + { + $send_stream_extra = <<__E; // Send stream after the command SendStream(rStream); __E - } - print CPP <<__E; -std::auto_ptr<$classname_base$reply> ${classname_base}::Query(const $classname_base$cmd &rQuery$argextra) + } + + print CPP <<__E; +std::auto_ptr<$reply_class> $server_or_client_class\::Query(const $request_class &rQuery$argextra) { // Send query Send(rQuery); $send_stream_extra + // Wait for the reply - std::auto_ptr<${derive_objects_from}> preply(Receive().release()); + std::auto_ptr<$message_base_class> preply = Receive(); + + CheckReply("$cmd", *preply, $reply_id); - if(preply->GetType() == $reply_id) - { - // Correct response - return std::auto_ptr<$classname_base$reply>(($classname_base$reply*)preply.release()); - } - else - { - // Set protocol error - int type, subType; - if(preply->IsError(type, subType)) - { - SetError(type, subType); - BOX_WARNING("$cmd command failed: received error " << - ((${classname_base}Error&)*preply).GetMessage()); - } - else - { - SetError(Protocol::UnknownError, Protocol::UnknownError); - BOX_WARNING("$cmd command failed: received " - "unexpected response type " << - preply->GetType()); - } - - // Throw an exception - THROW_EXCEPTION(ConnectionException, Conn_Protocol_UnexpectedReply) - } + // Correct response, if no exception thrown by CheckReply + return std::auto_ptr<$reply_class>(($reply_class *)preply.release()); +} +__E + } + elsif($writing_local) + { + if($has_stream) + { + $send_stream_extra = <<__E; + // Send stream after the command + SendStreamAfterCommand(&rStream); +__E + } + + print CPP <<__E; +std::auto_ptr<$reply_class> $server_or_client_class\::Query(const $request_class &rQuery$argextra) +{ + // Send query + $send_stream_extra + std::auto_ptr<$message_base_class> preply = rQuery.DoCommand(*this, mrContext); + + CheckReply("$cmd", *preply, $reply_id); + + // Correct response, if no exception thrown by CheckReply + return std::auto_ptr<$reply_class>(($reply_class *)preply.release()); } __E + } + } } } } - - print H <<__E; #endif // $guardname @@ -948,8 +1068,7 @@ __E close H; close CPP; - -sub obj_is_type +sub obj_is_type ($$) { my ($c,$ty) = @_; for(@{$cmd_attributes{$c}}) @@ -1003,40 +1122,6 @@ sub translate_type_to_member_type return $typename } -sub make_log_strings -{ - my ($cmd) = @_; - - my @str; - my @arg; - for(my $x = 0; $x < $#{$cmd_contents{$cmd}}; $x+=2) - { - my ($ty,$nm) = (${$cmd_contents{$cmd}}[$x], ${$cmd_contents{$cmd}}[$x+1]); - - if(exists $log_display_types{$ty}) - { - # need to translate it - my ($format,$arg) = @{$log_display_types{$ty}}; - $arg =~ s/VAR/m$nm/g; - - if ($format eq "0x%llx" and $target_windows) - { - $format = "0x%I64x"; - $arg = "(uint64_t)$arg"; - } - - push @str,$format; - push @arg,$arg; - } - else - { - # is opaque - push @str,'OPAQUE'; - } - } - return ($cmd.'('.join(',',@str).')', join(',','',@arg)); -} - sub make_log_strings_framework { my ($cmd) = @_; @@ -1053,7 +1138,7 @@ sub make_log_strings_framework my ($format,$arg) = @{$log_display_types{$ty}}; $arg =~ s/VAR/m$nm/g; - if ($format eq '\\"%s\\"') + if ($format eq '"%s"') { $arg = "\"\\\"\" << $arg << \"\\\"\""; } @@ -1090,4 +1175,3 @@ sub make_log_strings_framework return $log_cmd; } - |