From cf7aefb47f7eab8f07d78f3a55832d1dab185ce0 Mon Sep 17 00:00:00 2001 From: cdfrey Date: Thu, 8 Dec 2005 07:21:58 +0000 Subject: [PATCH] - added preliminary Contact protocol record building support - Contact record.h class now saves unknown Group Link field, for later saving --- src/protocol.h | 2 ++ src/record.cc | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--- src/record.h | 20 ++++++++++-- 3 files changed, 110 insertions(+), 8 deletions(-) diff --git a/src/protocol.h b/src/protocol.h index 4b7b1429..af786825 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -44,6 +44,8 @@ // DB Operation Command +#define SB_DBOP_SET_RECORD 0x41 +#define SB_DBOP_CLEAR_DATABASE 0x43 #define SB_DBOP_GET_DBDB 0x4a #define SB_DBOP_OLD_GET_DBDB 0x4c #define SB_DBOP_GET_COUNT 0x4e diff --git a/src/record.cc b/src/record.cc index f03b95aa..e1b2ad75 100644 --- a/src/record.cc +++ b/src/record.cc @@ -55,6 +55,35 @@ void ParseCommonFields(Record &rec, const void *begin, const void *end) b = rec.ParseField(b, e); } +void BuildField(Data &data, int &size, uint8_t type, const std::string &str) +{ + // include null terminator + size_t strsize = str.size() + 1; + int fieldsize = COMMON_FIELD_HEADER_SIZE + strsize; + unsigned char *pd = data.GetBuffer(size + fieldsize) + size; + CommonField *field = (CommonField *) pd; + + field->size = strsize; + field->type = type; + memcpy(field->data.raw, str.c_str(), strsize); + + size += fieldsize; +} + +void BuildField(Data &data, int &size, uint8_t type, const Barry::GroupLink &link) +{ + size_t linksize = sizeof(Barry::GroupLink); + int fieldsize = COMMON_FIELD_HEADER_SIZE + linksize; + unsigned char *pd = data.GetBuffer(size + fieldsize) + size; + CommonField *field = (CommonField *) pd; + + field->size = linksize; + field->type = type; + field->data.link = link; + + size += fieldsize; +} + /////////////////////////////////////////////////////////////////////////////// // CommandTable class @@ -395,7 +424,9 @@ const unsigned char* Contact::ParseField(const unsigned char *begin, case CFC_GROUP_LINK: // just add the unique ID to the list - GroupLinks.push_back(field->data.link.uniqueId); + GroupLinks.push_back( + GroupLink(field->data.link.uniqueId, + field->data.link.unknown)); return begin; } @@ -435,6 +466,61 @@ void Contact::Parse(const Data &data, unsigned int operation) } // +// Build +// +/// Build a raw protocol packet based on data in the class. +/// +void Contact::Build(Data &data, unsigned int databaseId) const +{ + data.Zap(); + + int size = SB_PACKET_CONTACT_UPLOAD_HEADER_SIZE; + unsigned char *pd = data.GetBuffer(size); + MAKE_PACKETPTR_BUF(spack, pd); + + spack->data.db.data.contact_up.operation = SB_DBOP_SET_RECORD; + spack->data.db.data.contact_up.databaseId = databaseId; + spack->data.db.data.contact_up.unknown = 0; + spack->data.db.data.contact_up.uniqueId = m_recordId; + spack->data.db.data.contact_up.unknown2 = 1; + + // special fields not in type table + BuildField(data, size, CFC_NAME, FirstName); + BuildField(data, size, CFC_NAME, LastName); + + // cycle through the type table + for( FieldLink *b = ContactFieldLinks; + b->type != CFC_INVALID_FIELD; + b++ ) + { + // print only fields with data + const std::string &field = this->*(b->strMember); + if( field.size() ) { + BuildField(data, size, b->type, field); + } + } + + // save any group links + GroupLinksType::const_iterator + gb = GroupLinks.begin(), ge = GroupLinks.end(); + for( ; gb != ge; gb++ ) { + Barry::GroupLink link; + link.uniqueId = gb->Link; + link.unknown = gb->Unknown; + BuildField(data, size, CFC_GROUP_LINK, link); + } + + // and finally save unknowns + UnknownsType::const_iterator + ub = Unknowns.begin(), ue = Unknowns.end(); + for( ; ub != ue; ub++ ) { + BuildField(data, size, ub->type, ub->data); + } + + data.ReleaseBuffer(size); +} + +// // GetPostalAddress // /// Format a mailing address, handling missing fields. @@ -495,12 +581,12 @@ void Contact::Dump(std::ostream &os) const } // print any group links - std::vector::const_iterator + GroupLinksType::const_iterator gb = GroupLinks.begin(), ge = GroupLinks.end(); if( gb != ge ) os << " GroupLinks:\n"; for( ; gb != ge; gb++ ) { - os << " ID: 0x" << setbase(16) << *gb << "\n"; + os << " ID: 0x" << setbase(16) << gb->Link << "\n"; } // and finally print unknowns @@ -564,12 +650,12 @@ void Contact::DumpLdif(std::ostream &os, const std::string &baseDN) const /* // print any group links - std::vector::const_iterator + GroupLinksType::const_iterator gb = GroupLinks.begin(), ge = GroupLinks.end(); if( gb != ge ) os << " GroupLinks:\n"; for( ; gb != ge; gb++ ) { - os << " ID: 0x" << setbase(16) << *gb << "\n"; + os << " ID: 0x" << setbase(16) << gb->Link << "\n"; } */ diff --git a/src/record.h b/src/record.h index 91cfda88..c8ec7c2e 100644 --- a/src/record.h +++ b/src/record.h @@ -139,9 +139,22 @@ class Contact { private: // private contact management data - uint64_t m_recordId; + uint32_t m_recordId; public: + struct GroupLink + { + uint32_t Link; + uint16_t Unknown; + + GroupLink(uint32_t link, uint16_t unknown) + : Link(link), Unknown(unknown) + {} + }; + + typedef std::vector GroupLinksType; + typedef std::vector UnknownsType; + // contact specific data std::string Email, @@ -167,8 +180,8 @@ public: PublicKey, Notes; - std::vector GroupLinks; - std::vector Unknowns; + GroupLinksType GroupLinks; + UnknownsType Unknowns; //protected: @@ -184,6 +197,7 @@ public: std::string GetPostalAddress() const; void Parse(const Data &data, unsigned int operation); + void Build(Data &data, unsigned int databaseId) const; void Clear(); // erase everything void Dump(std::ostream &os) const; -- 2.11.4.GIT