From 96098f0a52ba098f3bf41eaa7b67fe75dc881445 Mon Sep 17 00:00:00 2001 From: Nicolas VIVIEN Date: Sun, 5 Dec 2010 15:33:45 +0100 Subject: [PATCH] lib: add browser bookmarks parser Barry::Bookmark --- ChangeLog | 2 + src/Makefile.am | 2 + src/parser.cc | 7 ++ src/parser.h | 3 + src/protostructs.h | 17 ++++ src/r_bookmark.cc | 253 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/r_bookmark.h | 115 ++++++++++++++++++++++++ src/record.h | 1 + src/s11n-boost.h | 14 +++ tools/btool.cc | 6 ++ 10 files changed, 420 insertions(+) create mode 100644 src/r_bookmark.cc create mode 100644 src/r_bookmark.h diff --git a/ChangeLog b/ChangeLog index dcdc7c21..cc173f26 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ Release: version 0.17.0 - 2010/01/?? ------------------------------------------------------------------------------ +2010/12/04 + - lib: add browser bookmarks parser by Nicolas VIVIEN 2010/12/02 - doc: clarified btardump help, and added btardump.1 manpage 2010/11/30 diff --git a/src/Makefile.am b/src/Makefile.am index 14a766a3..f3adbe4a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -107,6 +107,7 @@ include_barry_HEADERS = barry.h barrysync.h barrybackup.h \ r_recur_base.h \ r_calendar.h \ r_calllog.h \ + r_bookmark.h \ r_contact.h \ r_folder.h \ r_memo.h \ @@ -193,6 +194,7 @@ libbarry_la_SOURCES = dll.h \ r_recur_base.h r_recur_base.cc \ r_calendar.h r_calendar.cc \ r_calllog.h r_calllog.cc \ + r_bookmark.h r_bookmark.cc \ r_command.cc \ r_contact.h r_contact.cc \ r_dbdb.cc \ diff --git a/src/parser.cc b/src/parser.cc index 5a90f5fe..c6743d4a 100644 --- a/src/parser.cc +++ b/src/parser.cc @@ -22,6 +22,7 @@ #include "parser.h" #include "r_calendar.h" #include "r_calllog.h" +#include "r_bookmark.h" #include "r_contact.h" #include "r_memo.h" #include "r_message.h" @@ -42,6 +43,7 @@ HANDLE_TYPE(Calendar) \ HANDLE_TYPE(CalendarAll) \ HANDLE_TYPE(CallLog) \ + HANDLE_TYPE(Bookmark) \ HANDLE_TYPE(ServiceBook) \ HANDLE_TYPE(Memo) \ HANDLE_TYPE(Task) \ @@ -180,6 +182,11 @@ void AllRecordDumpStore::operator() (const Barry::CallLog &r) m_os << r << std::endl; } +void AllRecordDumpStore::operator() (const Barry::Bookmark &r) +{ + m_os << r << std::endl; +} + void AllRecordDumpStore::operator() (const Barry::ServiceBook &r) { m_os << r << std::endl; diff --git a/src/parser.h b/src/parser.h index ec7e463f..967a3830 100644 --- a/src/parser.h +++ b/src/parser.h @@ -37,6 +37,7 @@ namespace Barry { class Calendar; class CalendarAll; class CallLog; + class Bookmark; class ServiceBook; class Memo; class Task; @@ -379,6 +380,7 @@ public: virtual void operator() (const Barry::Calendar &) = 0; virtual void operator() (const Barry::CalendarAll &) = 0; virtual void operator() (const Barry::CallLog &) = 0; + virtual void operator() (const Barry::Bookmark &) = 0; virtual void operator() (const Barry::ServiceBook &) = 0; virtual void operator() (const Barry::Memo &) = 0; virtual void operator() (const Barry::Task &) = 0; @@ -410,6 +412,7 @@ public: virtual void operator() (const Barry::Calendar &); virtual void operator() (const Barry::CalendarAll &); virtual void operator() (const Barry::CallLog &); + virtual void operator() (const Barry::Bookmark &); virtual void operator() (const Barry::ServiceBook &); virtual void operator() (const Barry::Memo &); virtual void operator() (const Barry::Task &); diff --git a/src/protostructs.h b/src/protostructs.h index 5dc53257..d15a7734 100644 --- a/src/protostructs.h +++ b/src/protostructs.h @@ -315,6 +315,23 @@ struct CalendarRecurrenceDataField // as documented in the Cassis project spec #define CLL_PHONETYPE_RANGE_HIGH 3 // +// Browser Bookmarks record: field constants +// +// +#define BMK_BROWSER_AUTO 0 +#define BMK_BROWSER_BLACKBERRY 1 +#define BMK_BROWSER_FIREFOX 2 +#define BMK_BROWSER_INTERNET_EXPLORER 3 + +#define BMK_DISPLAY_AUTO 0 +#define BMK_DISPLAY_COLOMN 1 +#define BMK_DISPLAY_PAGE 2 + +#define BMK_JAVASCRIPT_AUTO 0 +#define BMK_JAVASCRIPT_ENABLED 1 +#define BMK_JAVASCRIPT_DISABLED 2 + +// // Folder record: field constants // diff --git a/src/r_bookmark.cc b/src/r_bookmark.cc new file mode 100644 index 00000000..59bfc4c2 --- /dev/null +++ b/src/r_bookmark.cc @@ -0,0 +1,253 @@ +/// +/// \file r_bookmark.cc +/// Record parsing class for the phone browser bookmarks database. +/// + +/* + Copyright (C) 2008-2010, Nicolas VIVIEN + Copyright (C) 2005-2010, Net Direct Inc. (http://www.netdirect.ca/) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License in the COPYING file at the + root directory of this project for more details. +*/ + +#include "r_bookmark.h" +#include "record-internal.h" +#include "protostructs.h" +#include "data.h" +#include "time.h" +#include "iconv.h" +#include +#include +#include + +using namespace std; +using namespace Barry::Protocol; + +namespace Barry { + +/////////////////////////////////////////////////////////////////////////////// +// Bookmark Class + +// Bookmark Field Codes +#define BMKFC_BOOKMARK_TYPE 0x01 + +#define BMKFC_NAME 0x04 +#define BMKFC_URL 0xff +#define BMKFC_ICONE 0x05 + +#define BMKFC_STRUCT1 0x11 +#define BMKFC_STRUCT2 0x12 + +#define BMKFC_END 0xffff + +static FieldLink BookmarkFieldLinks[] = { + { BMKFC_NAME, "Name", 0, 0, &Bookmark::Name, 0, 0, 0, 0, true }, + { BMKFC_URL, "URL", 0, 0, &Bookmark::URL, 0, 0, 0, 0, true }, + { BMKFC_ICONE, "Icone", 0, 0, &Bookmark::Icone, 0, 0, 0, 0, true }, + { BMKFC_END, "End of List", 0, 0, 0, 0, 0, 0, 0, false } +}; + +Bookmark::Bookmark() +{ + Clear(); +} + +Bookmark::~Bookmark() +{ +} + +const unsigned char* Bookmark::ParseField(const unsigned char *begin, + const unsigned char *end, + const IConverter *ic) +{ + const CommonField *field = (const CommonField *) begin; + + // advance and check size + begin += COMMON_FIELD_HEADER_SIZE + btohs(field->size); + if( begin > end ) // if begin==end, we are ok + return begin; + + if( !btohs(field->size) ) // if field has no size, something's up + return begin; + + if( field->type == BMKFC_BOOKMARK_TYPE ) { + if( field->u.raw[0] != 'D' ) { + throw Error( "Bookmark::ParseField: BookmarkType is not 'p'" ); + } + return begin; + } + + + uint8_t isdefined; + + const unsigned char *b = field->u.raw; + const unsigned char *e = begin; + + // handle special cases + switch( field->type ) + { + case BMKFC_STRUCT1: + while (b < e) { + const uint8_t type = *b; + + // advance and check size + b += 1; + if( b > e ) // if begin==end, we are ok + continue; + + switch (type) { + case 0x81: + b += 8; // 8 fields unknonw + break; + case 0x84: + case 0x85: + b += 5; // 4 fields unknonw + break; + case BMKFC_NAME: + isdefined = *b; + b += sizeof(uint8_t); + if (isdefined == 1) { // if field is defined + const uint16_t size = be_btohs(*((const uint16_t *) b)); + b += sizeof(uint16_t); + Name = ParseFieldString(b, size); + b += size; + } + break; + case BMKFC_ICONE: + isdefined = *b; + b += sizeof(uint8_t); + if (isdefined == 1) { // if field is defined + const uint16_t size = be_btohs(*((const uint16_t *) b)); + b += sizeof(uint16_t); + Icone = ParseFieldString(b, size); + b += size; + } + break; + case 0x08: + isdefined = *b; + b += sizeof(uint8_t); + if (isdefined == 1) { // if field is defined + const uint16_t size = be_btohs(*((const uint16_t *) b)); + b += sizeof(uint16_t); + b += size; + } + break; + } + } + + if (field->size >= 3) { + if ((Barry::Bookmark::DisplayModeType) *(begin - 3) > Barry::Bookmark::DisplayUnknown) + DisplayMode = Barry::Bookmark::DisplayUnknown; + else + DisplayMode = (Barry::Bookmark::DisplayModeType) *(begin - 3); + + if ((Barry::Bookmark::JavaScriptModeType) *(begin - 2) > Barry::Bookmark::JavaScriptUnknown) + JavaScriptMode = Barry::Bookmark::JavaScriptUnknown; + else + JavaScriptMode = (Barry::Bookmark::JavaScriptModeType) *(begin - 2); + + if ((Barry::Bookmark::BrowserIdentityType) *(begin - 1) > Barry::Bookmark::IdentityUnknown) + BrowserIdentity = Barry::Bookmark::IdentityUnknown; + else + BrowserIdentity = (Barry::Bookmark::BrowserIdentityType) *(begin - 1); + } + +// return begin; + break; + + case BMKFC_STRUCT2: + { + const uint16_t size = be_btohs(*((const uint16_t *) b)); + b += sizeof(uint16_t); + URL = ParseFieldString(b, size); + b += size; + } + +// return begin; + break; + } + + // if still not handled, add to the Unknowns list + UnknownField uf; + uf.type = field->type; + uf.data.assign((const char*)field->u.raw, btohs(field->size)); + Unknowns.push_back(uf); + + // return new pointer for next field + return begin; +} + +void Bookmark::ParseHeader(const Data &data, size_t &offset) +{ + // no header in Bookmark records +} + +void Bookmark::ParseFields(const Data &data, size_t &offset, const IConverter *ic) +{ + const unsigned char *finish = ParseCommonFields(*this, + data.GetData() + offset, data.GetData() + data.GetSize(), ic); + offset += finish - (data.GetData() + offset); +} + +void Bookmark::Dump(std::ostream &os) const +{ + static const char *DisplayModeName[] = { "Automatique", "Enabled", "Disabled", "Unknown" }; + static const char *JavaScriptModeName[] = { "Automatique", "Enabled", "Disabled", "Unknown" }; + static const char *BrowserIdentityName[] = { "Automatique", "BlackBerry", "FireFox", "Internet Explorer", "Unknown" }; + + os << "Bookmark entry: 0x" << setbase(16) << RecordId + << " (" << (unsigned int)RecType << ")\n"; + + // cycle through the type table + for( const FieldLink *b = BookmarkFieldLinks; + b->type != BMKFC_END; + b++ ) + { + if( b->strMember ) { + const std::string &s = this->*(b->strMember); + if( s.size() ) + os << " " << b->name << ": " << s << "\n"; + } + else if( b->timeMember ) { + time_t t = this->*(b->timeMember); + if( t > 0 ) + os << " " << b->name << ": " << ctime(&t); + else + os << " " << b->name << ": unknown\n"; + } + } + + os << " Display mode: " << DisplayModeName[DisplayMode] << "\n"; + os << " JavaScript mode: " << JavaScriptModeName[JavaScriptMode] << "\n"; + os << " Browser Identity mode: " << BrowserIdentityName[BrowserIdentity] << "\n"; + + os << Unknowns; + os << "\n\n"; +} + +bool Bookmark::operator<(const Bookmark &other) const +{ + int cmp = Name.compare(other.Name); + return cmp < 0; +} + +void Bookmark::Clear() +{ + Name.clear(); + URL.clear(); + + Unknowns.clear(); +} + +} // namespace Barry + diff --git a/src/r_bookmark.h b/src/r_bookmark.h new file mode 100644 index 00000000..990379db --- /dev/null +++ b/src/r_bookmark.h @@ -0,0 +1,115 @@ +/// +/// \file r_bookmark.h +/// Record parsing class for call logs +/// + +/* + Copyright (C) 2008-2009, Nicolas VIVIEN + Copyright (C) 2005-2010, Net Direct Inc. (http://www.netdirect.ca/) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License in the COPYING file at the + root directory of this project for more details. +*/ + +#ifndef __BARRY_RECORD_BOOKMARK_H__ +#define __BARRY_RECORD_BOOKMARK_H__ + +#include "dll.h" +#include "record.h" +#include +#include +#include + +namespace Barry { + +// forward declarations +class IConverter; + +class BXEXPORT Bookmark +{ +public: + typedef std::vector UnknownsType; + + uint8_t RecType; + uint32_t RecordId; + + std::string Name; + std::string Icone; + std::string URL; + + enum BrowserIdentityType + { + IdentityAuto = 0, + IdentityBlackBerry, + IdentityFireFox, + IdentityInternetExplorer, + IdentityUnknown + }; + BrowserIdentityType BrowserIdentity; + + enum DisplayModeType + { + DisplayAuto = 0, + DisplayColomn, + DisplayPage, + DisplayUnknown + }; + DisplayModeType DisplayMode; + + enum JavaScriptModeType + { + JavaScriptAuto = 0, + JavaScriptEnabled, + JavaScriptDisabled, + JavaScriptUnknown + }; + JavaScriptModeType JavaScriptMode; + + UnknownsType Unknowns; + +protected: + +public: + Bookmark(); + ~Bookmark(); + + // Parser / Builder API (see parser.h / builder.h) + const unsigned char* ParseField(const unsigned char *begin, + const unsigned char *end, const IConverter *ic = 0); + uint8_t GetRecType() const { return RecType; } + uint32_t GetUniqueId() const { return RecordId; } + void SetIds(uint8_t Type, uint32_t Id) { RecType = Type; RecordId = Id; } + void ParseHeader(const Data &data, size_t &offset); + void ParseFields(const Data &data, size_t &offset, const IConverter *ic = 0); + + void Clear(); + + void Dump(std::ostream &os) const; + + // Sorting - use enough data to make the sorting as + // consistent as possible + bool operator<(const Bookmark &other) const; + + // database name + static const char * GetDBName() { return "Browser Bookmarks"; } + static uint8_t GetDefaultRecType() { return 0; } +}; + +BXEXPORT inline std::ostream& operator<<(std::ostream &os, const Bookmark &msg) { + msg.Dump(os); + return os; +} + +} // namespace Barry + +#endif + diff --git a/src/record.h b/src/record.h index 36ee2a3d..806e9081 100644 --- a/src/record.h +++ b/src/record.h @@ -284,6 +284,7 @@ public: // Include all parser classes, to make it easy for the application to use. #include "r_calendar.h" #include "r_calllog.h" +#include "r_bookmark.h" #include "r_contact.h" #include "r_memo.h" #include "r_message.h" diff --git a/src/s11n-boost.h b/src/s11n-boost.h index b5b0eb5a..07a7cf0d 100644 --- a/src/s11n-boost.h +++ b/src/s11n-boost.h @@ -230,6 +230,20 @@ void serialize(ArchiveT &ar, Barry::CallLog &c, const unsigned int ver) } template +void serialize(ArchiveT &ar, Barry::Bookmark &c, const unsigned int ver) +{ + ar & make_nvp("RecType", c.RecType); + ar & make_nvp("RecordId", c.RecordId); + + ar & make_nvp("Name", c.Name); + ar & make_nvp("URL", c.URL); + + if( ver < BARRY_POD_MAP_VERSION ) { + ar & make_nvp("Unknowns", c.Unknowns); + } +} + +template void serialize(ArchiveT &ar, Barry::ServiceBookConfig &c, const unsigned int ver) { ar & make_nvp("Format", c.Format); diff --git a/tools/btool.cc b/tools/btool.cc index 8920832a..6a68a70e 100644 --- a/tools/btool.cc +++ b/tools/btool.cc @@ -375,6 +375,11 @@ shared_ptr GetParser(const string &name, new RecordParser > ( new Store(filename, false, dnow, vmode))); } + else if( name == Bookmark::GetDBName() ) { + return shared_ptr( + new RecordParser > ( + new Store(filename, false, dnow, vmode))); + } else if( name == ServiceBook::GetDBName() ) { return shared_ptr( new RecordParser > ( @@ -476,6 +481,7 @@ void ShowParsers() << " Calendar *\n" << " Calendar - All *\n" << " Phone Call Logs\n" + << " Browser Bookmarks\n" << " Service Book\n" << " Memos *\n" << " Tasks *\n" -- 2.11.4.GIT