00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <barry/barry.h>
00023 #include <barry/barrysync.h>
00024 #include <iomanip>
00025 #include <iostream>
00026 #include <fstream>
00027 #include <sstream>
00028 #include <vector>
00029 #include <string>
00030 #include <algorithm>
00031 #include <getopt.h>
00032 #include "i18n.h"
00033
00034
00035 using namespace std;
00036 using namespace Barry;
00037
00038 void Usage()
00039 {
00040 int major, minor;
00041 const char *Version = Barry::Version(major, minor);
00042
00043 cerr
00044 << "btool - Command line USB Blackberry Test Tool\n"
00045 << " Copyright 2005-2010, Net Direct Inc. (http://www.netdirect.ca/)\n"
00046 << " Using: " << Version << "\n"
00047 << " Compiled "
00048 #ifdef __BARRY_BOOST_MODE__
00049 << "with"
00050 #else
00051 << "without"
00052 #endif
00053 << " Boost support\n"
00054 << "\n"
00055 << " -B bus Specify which USB bus to search on\n"
00056 << " -N dev Specify which system device, using system specific string\n"
00057 << "\n"
00058 << " -a db Erase / clear database 'db' FROM device, deleting all\n"
00059 << " its records. Can be used multiple times to clear more\n"
00060 << " than one DB.\n"
00061 << " -c dn Convert address book database to LDIF format, using the\n"
00062 << " specified baseDN\n"
00063 << " -C dnattr LDIF attribute name to use when building the FQDN\n"
00064 << " Defaults to 'cn'\n"
00065 << " -d db Load database 'db' FROM device and dump to screen\n"
00066 << " Can be used multiple times to fetch more than one DB\n"
00067 << " -e epp Override endpoint pair detection. 'epp' is a single\n"
00068 << " string separated by a comma, holding the read,write\n"
00069 << " endpoint pair. Example: -e 83,5\n"
00070 << " Note: Endpoints are specified in hex.\n"
00071 << " You should never need to use this option.\n"
00072 #ifdef __BARRY_BOOST_MODE__
00073 << " -f file Filename to save or load handheld data to/from\n"
00074 #endif
00075 << " -h This help\n"
00076 << " -i cs International charset for string conversions\n"
00077 << " Valid values here are available with 'iconv --list'\n"
00078 << " -I Sort records before output\n"
00079 << " -l List devices\n"
00080 << " -L List Contact field names\n"
00081 << " -m Map LDIF name to Contact field / Unmap LDIF name\n"
00082 << " Map: ldif,read,write - maps ldif to read/write Contact fields\n"
00083 << " Unmap: ldif name alone\n"
00084 << " -M List current LDIF mapping\n"
00085 << " -n Use null parser on all databases.\n"
00086 << " -p pin PIN of device to talk with\n"
00087 << " If only one device is plugged in, this flag is optional\n"
00088 << " -P pass Simplistic method to specify device password\n"
00089 << " -s db Save database 'db' TO device from data loaded from -f file\n"
00090 << " -S Show list of supported database parsers\n"
00091 << " -t Show database database table\n"
00092 << " -T db Show record state table for given database\n"
00093 << " -v Dump protocol data during operation\n"
00094 << " -V Dump records using MIME vformats where possible\n"
00095 << " -X Reset device\n"
00096 << " -z Use non-threaded sockets\n"
00097 << " -Z Use threaded socket router (default)\n"
00098 << "\n"
00099 << " -d Command modifiers: (can be used multiple times for more than 1 record)\n"
00100 << "\n"
00101 << " -r # Record index number as seen in the -T state table.\n"
00102 << " This overrides the default -d behaviour, and only\n"
00103 << " downloads the one specified record, sending to stdout.\n"
00104 << " -R # Same as -r, but also clears the record's dirty flags.\n"
00105 << " -D # Record index number as seen in the -T state table,\n"
00106 << " which indicates the record to delete. Used with the -d\n"
00107 << " command to specify the database.\n"
00108 << endl;
00109 }
00110
00111 class Contact2Ldif
00112 {
00113 public:
00114 Barry::ContactLdif &ldif;
00115
00116 Contact2Ldif(Barry::ContactLdif &ldif) : ldif(ldif) {}
00117
00118 void operator()(const Contact &rec)
00119 {
00120 ldif.DumpLdif(cout, rec);
00121 }
00122 };
00123
00124 template <class Record>
00125 class MimeDump
00126 {
00127 public:
00128 void Dump(std::ostream &os, const Record &rec)
00129 {
00130 os << rec << endl;
00131 }
00132
00133 static bool Supported() { return false; }
00134 };
00135
00136 template <>
00137 class MimeDump<Contact>
00138 {
00139 public:
00140 void Dump(std::ostream &os, const Contact &rec)
00141 {
00142 Sync::vCard vcard;
00143 os << vcard.ToVCard(rec) << endl;
00144 }
00145
00146 static bool Supported() { return true; }
00147 };
00148
00149 template <>
00150 class MimeDump<Calendar>
00151 {
00152 public:
00153 void Dump(std::ostream &os, const Calendar &rec)
00154 {
00155 Sync::vTimeConverter vtc;
00156 Sync::vCalendar vcal(vtc);
00157 os << vcal.ToVCal(rec) << endl;
00158 }
00159
00160 static bool Supported() { return true; }
00161 };
00162
00163 template <>
00164 class MimeDump<Memo>
00165 {
00166 public:
00167 void Dump(std::ostream &os, const Memo &rec)
00168 {
00169 Sync::vJournal vjournal;
00170 os << vjournal.ToMemo(rec) << endl;
00171 }
00172
00173 static bool Supported() { return true; }
00174 };
00175
00176 template <>
00177 class MimeDump<Task>
00178 {
00179 public:
00180 void Dump(std::ostream &os, const Task &rec)
00181 {
00182 Sync::vTimeConverter vtc;
00183 Sync::vTodo vtodo(vtc);
00184 os << vtodo.ToTask(rec) << endl;
00185 }
00186
00187 static bool Supported() { return true; }
00188 };
00189
00190 template <class Record>
00191 struct Store
00192 {
00193 std::vector<Record> records;
00194 mutable typename std::vector<Record>::const_iterator rec_it;
00195 std::string filename;
00196 bool load;
00197 bool immediate_display;
00198 bool vformat_mode;
00199 int count;
00200
00201 Store(const string &filename, bool load, bool immediate_display,
00202 bool vformat_mode)
00203 : rec_it(records.end()),
00204 filename(filename),
00205 load(load),
00206 immediate_display(immediate_display),
00207 vformat_mode(vformat_mode),
00208 count(0)
00209 {
00210 #ifdef __BARRY_BOOST_MODE__
00211 try {
00212
00213 if( load && filename.size() ) {
00214
00215 cout << "Loading: " << filename << endl;
00216 ifstream ifs(filename.c_str());
00217 std::string dbName;
00218 getline(ifs, dbName);
00219 boost::archive::text_iarchive ia(ifs);
00220 ia >> records;
00221 cout << records.size()
00222 << " records loaded from '"
00223 << filename << "'" << endl;
00224 sort(records.begin(), records.end());
00225 rec_it = records.begin();
00226
00227
00228 typename std::vector<Record>::const_iterator beg = records.begin(), end = records.end();
00229 for( ; beg != end; beg++ ) {
00230 cout << (*beg) << endl;
00231 }
00232 }
00233
00234 } catch( boost::archive::archive_exception &ae ) {
00235 cerr << "Archive exception in ~Store(): "
00236 << ae.what() << endl;
00237 }
00238 #endif
00239 }
00240
00241 ~Store()
00242 {
00243 if( !immediate_display ) {
00244
00245 sort(records.begin(), records.end());
00246 DumpAll();
00247 }
00248
00249 cout << "Store counted " << dec << count << " records." << endl;
00250 #ifdef __BARRY_BOOST_MODE__
00251 try {
00252
00253 if( !load && filename.size() ) {
00254
00255 cout << "Saving: " << filename << endl;
00256 const std::vector<Record> &r = records;
00257 ofstream ofs(filename.c_str());
00258 ofs << Record::GetDBName() << endl;
00259 boost::archive::text_oarchive oa(ofs);
00260 oa << r;
00261 cout << dec << r.size() << " records saved to '"
00262 << filename << "'" << endl;
00263 }
00264
00265 } catch( boost::archive::archive_exception &ae ) {
00266 cerr << "Archive exception in ~Store(): "
00267 << ae.what() << endl;
00268 }
00269 #endif
00270 }
00271
00272 void DumpAll()
00273 {
00274 typename vector<Record>::const_iterator i = records.begin();
00275 for( ; i != records.end(); ++i ) {
00276 Dump(*i);
00277 }
00278 }
00279
00280 void Dump(const Record &rec)
00281 {
00282 if( vformat_mode ) {
00283 MimeDump<Record> md;
00284 md.Dump(cout, rec);
00285 }
00286 else {
00287 cout << rec << endl;
00288 }
00289 }
00290
00291
00292 void operator()(const Record &rec)
00293 {
00294 count++;
00295 if( immediate_display )
00296 Dump(rec);
00297 records.push_back(rec);
00298 }
00299
00300
00301 bool operator()(Record &rec, unsigned int databaseId) const
00302 {
00303 if( rec_it == records.end() )
00304 return false;
00305 rec = *rec_it;
00306 rec_it++;
00307 return true;
00308 }
00309 };
00310
00311 class DataDumpParser : public Barry::Parser
00312 {
00313 uint32_t m_id;
00314
00315 public:
00316 virtual void Clear() {}
00317
00318 virtual void SetIds(uint8_t RecType, uint32_t UniqueId)
00319 {
00320 m_id = UniqueId;
00321 }
00322
00323 virtual void ParseHeader(const Data &, size_t &) {}
00324
00325 virtual void ParseFields(const Barry::Data &data, size_t &offset,
00326 const IConverter *ic)
00327 {
00328 std::cout << "Raw record dump for record: "
00329 << std::hex << m_id << std::endl;
00330 std::cout << data << std::endl;
00331 }
00332
00333 virtual void Store() {}
00334 };
00335
00336 auto_ptr<Parser> GetParser(const string &name,
00337 const string &filename,
00338 bool null_parser,
00339 bool immediate_display,
00340 bool vformat_mode)
00341 {
00342 bool dnow = immediate_display;
00343 bool vmode = vformat_mode;
00344
00345 if( null_parser ) {
00346
00347 return auto_ptr<Parser>( new DataDumpParser );
00348 }
00349
00350 else if( name == Contact::GetDBName() ) {
00351 return auto_ptr<Parser>(
00352 new RecordParser<Contact, Store<Contact> > (
00353 new Store<Contact>(filename, false, dnow, vmode)));
00354 }
00355 else if( name == Message::GetDBName() ) {
00356 return auto_ptr<Parser>(
00357 new RecordParser<Message, Store<Message> > (
00358 new Store<Message>(filename, false, dnow, vmode)));
00359 }
00360 else if( name == Calendar::GetDBName() ) {
00361 return auto_ptr<Parser>(
00362 new RecordParser<Calendar, Store<Calendar> > (
00363 new Store<Calendar>(filename, false, dnow, vmode)));
00364 }
00365 else if( name == CalendarAll::GetDBName() ) {
00366 return auto_ptr<Parser>(
00367 new RecordParser<CalendarAll, Store<CalendarAll> > (
00368 new Store<CalendarAll>(filename, false, dnow, vmode)));
00369 }
00370 else if( name == CallLog::GetDBName() ) {
00371 return auto_ptr<Parser>(
00372 new RecordParser<CallLog, Store<CallLog> > (
00373 new Store<CallLog>(filename, false, dnow, vmode)));
00374 }
00375 else if( name == ServiceBook::GetDBName() ) {
00376 return auto_ptr<Parser>(
00377 new RecordParser<ServiceBook, Store<ServiceBook> > (
00378 new Store<ServiceBook>(filename, false, dnow, vmode)));
00379 }
00380
00381 else if( name == Memo::GetDBName() ) {
00382 return auto_ptr<Parser>(
00383 new RecordParser<Memo, Store<Memo> > (
00384 new Store<Memo>(filename, false, dnow, vmode)));
00385 }
00386 else if( name == Task::GetDBName() ) {
00387 return auto_ptr<Parser>(
00388 new RecordParser<Task, Store<Task> > (
00389 new Store<Task>(filename, false, dnow, vmode)));
00390 }
00391 else if( name == PINMessage::GetDBName() ) {
00392 return auto_ptr<Parser>(
00393 new RecordParser<PINMessage, Store<PINMessage> > (
00394 new Store<PINMessage>(filename, false, dnow, vmode)));
00395 }
00396 else if( name == SavedMessage::GetDBName() ) {
00397 return auto_ptr<Parser>(
00398 new RecordParser<SavedMessage, Store<SavedMessage> > (
00399 new Store<SavedMessage>(filename, false, dnow, vmode)));
00400 }
00401 else if( name == Sms::GetDBName() ) {
00402 return auto_ptr<Parser>(
00403 new RecordParser<Sms, Store<Sms> > (
00404 new Store<Sms>(filename, false, dnow, vmode)));
00405 }
00406 else if( name == Folder::GetDBName() ) {
00407 return auto_ptr<Parser>(
00408 new RecordParser<Folder, Store<Folder> > (
00409 new Store<Folder>(filename, false, dnow, vmode)));
00410 }
00411 else if( name == Timezone::GetDBName() ) {
00412 return auto_ptr<Parser>(
00413 new RecordParser<Timezone, Store<Timezone> > (
00414 new Store<Timezone>(filename, false, dnow, vmode)));
00415 }
00416 else {
00417
00418 return auto_ptr<Parser>( new DataDumpParser );
00419 }
00420 }
00421
00422 auto_ptr<Builder> GetBuilder(const string &name, const string &filename)
00423 {
00424
00425 if( name == Contact::GetDBName() ) {
00426 return auto_ptr<Builder>(
00427 new RecordBuilder<Contact, Store<Contact> > (
00428 new Store<Contact>(filename, true, true, false)));
00429 }
00430 else if( name == Calendar::GetDBName() ) {
00431 return auto_ptr<Builder>(
00432 new RecordBuilder<Calendar, Store<Calendar> > (
00433 new Store<Calendar>(filename, true, true, false)));
00434 }
00435 else if( name == CalendarAll::GetDBName() ) {
00436 return auto_ptr<Builder>(
00437 new RecordBuilder<CalendarAll, Store<CalendarAll> > (
00438 new Store<CalendarAll>(filename, true, true, false)));
00439 }
00440 else if( name == Memo::GetDBName() ) {
00441 return auto_ptr<Builder>(
00442 new RecordBuilder<Memo, Store<Memo> > (
00443 new Store<Memo>(filename, true, true, false)));
00444 }
00445 else if( name == Task::GetDBName() ) {
00446 return auto_ptr<Builder>(
00447 new RecordBuilder<Task, Store<Task> > (
00448 new Store<Task>(filename, true, true, false)));
00449 }
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462 else {
00463 throw std::runtime_error("No Builder available for database");
00464 }
00465 }
00466
00467 void ShowParsers()
00468 {
00469 cout << "Supported Database parsers:\n"
00470 << " (* = can display in vformat MIME mode)\n"
00471 << " Address Book *\n"
00472 << " Messages\n"
00473 << " Calendar *\n"
00474 << " Calendar - All *\n"
00475 << " Phone Call Logs\n"
00476 << " Service Book\n"
00477 << " Memos *\n"
00478 << " Tasks *\n"
00479 << " PIN Messages\n"
00480 << " Saved Email Messages\n"
00481 << " SMS Messages\n"
00482 << " Folders\n"
00483 << " Time Zones (read only)\n"
00484 << "\n"
00485 << "Supported Database builders:\n"
00486 << " Address Book\n"
00487 << " Calendar\n"
00488 << " Calendar - All\n"
00489 << " Memo\n"
00490 << " Task\n"
00491 << endl;
00492 }
00493
00494 struct StateTableCommand
00495 {
00496 char flag;
00497 bool clear;
00498 unsigned int index;
00499
00500 StateTableCommand(char f, bool c, unsigned int i)
00501 : flag(f), clear(c), index(i) {}
00502 };
00503
00504 bool SplitMap(const string &map, string &ldif, string &read, string &write)
00505 {
00506 string::size_type a = map.find(',');
00507 if( a == string::npos )
00508 return false;
00509
00510 string::size_type b = map.find(',', a+1);
00511 if( b == string::npos )
00512 return false;
00513
00514 ldif.assign(map, 0, a);
00515 read.assign(map, a + 1, b - a - 1);
00516 write.assign(map, b + 1, map.size() - b - 1);
00517
00518 return ldif.size() && read.size() && write.size();
00519 }
00520
00521 void DoMapping(ContactLdif &ldif, const vector<string> &mapCommands)
00522 {
00523 for( vector<string>::const_iterator i = mapCommands.begin();
00524 i != mapCommands.end();
00525 ++i )
00526 {
00527
00528 if( i->find(',') == string::npos ) {
00529
00530 cerr << "Unmapping: " << *i << endl;
00531 ldif.Unmap(*i);
00532 }
00533 else {
00534 cerr << "Mapping: " << *i << endl;
00535
00536
00537 string ldifname, read, write;
00538 if( SplitMap(*i, ldifname, read, write) ) {
00539 if( !ldif.Map(ldifname, read, write) ) {
00540 cerr << "Read/Write name unknown: " << *i << endl;
00541 }
00542 }
00543 else {
00544 cerr << "Invalid map format: " << *i << endl;
00545 }
00546 }
00547 }
00548 }
00549
00550 bool ParseEpOverride(const char *arg, Usb::EndpointPair *epp)
00551 {
00552 int read, write;
00553 char comma;
00554 istringstream iss(arg);
00555 iss >> hex >> read >> comma >> write;
00556 if( !iss )
00557 return false;
00558 epp->read = read;
00559 epp->write = write;
00560 return true;
00561 }
00562
00563 int main(int argc, char *argv[])
00564 {
00565 INIT_I18N(PACKAGE);
00566
00567 cout.sync_with_stdio(true);
00568
00569
00570 try {
00571
00572 uint32_t pin = 0;
00573 bool list_only = false,
00574 show_dbdb = false,
00575 ldif_contacts = false,
00576 data_dump = false,
00577 vformat_mode = false,
00578 reset_device = false,
00579 list_contact_fields = false,
00580 list_ldif_map = false,
00581 epp_override = false,
00582 threaded_sockets = true,
00583 record_state = false,
00584 clear_database = false,
00585 null_parser = false,
00586 sort_records = false;
00587 string ldifBaseDN, ldifDnAttr;
00588 string filename;
00589 string password;
00590 string busname;
00591 string devname;
00592 string iconvCharset;
00593 vector<string> dbNames, saveDbNames, mapCommands, clearDbNames;
00594 vector<StateTableCommand> stCommands;
00595 Usb::EndpointPair epOverride;
00596
00597
00598 for(;;) {
00599 int cmd = getopt(argc, argv, "a:B:c:C:d:D:e:f:hi:IlLm:MnN:p:P:r:R:Ss:tT:vVXzZ");
00600 if( cmd == -1 )
00601 break;
00602
00603 switch( cmd )
00604 {
00605 case 'a':
00606 clear_database = true;
00607 clearDbNames.push_back(string(optarg));
00608 break;
00609
00610 case 'B':
00611 busname = optarg;
00612 break;
00613
00614 case 'c':
00615 ldif_contacts = true;
00616 ldifBaseDN = optarg;
00617 break;
00618
00619 case 'C':
00620 ldifDnAttr = optarg;
00621 break;
00622
00623 case 'd':
00624 dbNames.push_back(string(optarg));
00625 break;
00626
00627 case 'D':
00628 stCommands.push_back(
00629 StateTableCommand('D', false, atoi(optarg)));
00630 break;
00631
00632 case 'e':
00633 if( !ParseEpOverride(optarg, &epOverride) ) {
00634 Usage();
00635 return 1;
00636 }
00637 epp_override = true;
00638 break;
00639
00640 case 'f':
00641 #ifdef __BARRY_BOOST_MODE__
00642 filename = optarg;
00643 #else
00644 cerr << "-f option not supported - no Boost "
00645 "serialization support available\n";
00646 return 1;
00647 #endif
00648 break;
00649
00650 case 'i':
00651 iconvCharset = optarg;
00652 break;
00653
00654 case 'I':
00655 sort_records = true;
00656 break;
00657
00658 case 'l':
00659 list_only = true;
00660 break;
00661
00662 case 'L':
00663 list_contact_fields = true;
00664 break;
00665
00666 case 'm':
00667 mapCommands.push_back(string(optarg));
00668 break;
00669
00670 case 'M':
00671 list_ldif_map = true;
00672 break;
00673
00674 case 'n':
00675 null_parser = true;
00676 break;
00677
00678 case 'N':
00679 devname = optarg;
00680 break;
00681
00682 case 'p':
00683 pin = strtoul(optarg, NULL, 16);
00684 break;
00685
00686 case 'P':
00687 password = optarg;
00688 break;
00689
00690 case 'r':
00691 stCommands.push_back(
00692 StateTableCommand('r', false, atoi(optarg)));
00693 break;
00694
00695 case 'R':
00696 stCommands.push_back(
00697 StateTableCommand('r', true, atoi(optarg)));
00698 break;
00699
00700 case 's':
00701 saveDbNames.push_back(string(optarg));
00702 break;
00703
00704 case 'S':
00705 ShowParsers();
00706 return 0;
00707
00708 case 't':
00709 show_dbdb = true;
00710 break;
00711
00712 case 'T':
00713 record_state = true;
00714 dbNames.push_back(string(optarg));
00715 break;
00716
00717 case 'v':
00718 data_dump = true;
00719 break;
00720
00721 case 'V':
00722 vformat_mode = true;
00723 break;
00724
00725 case 'X':
00726 reset_device = true;
00727 break;
00728
00729 case 'z':
00730 threaded_sockets = false;
00731 break;
00732
00733 case 'Z':
00734 threaded_sockets = true;
00735 break;
00736
00737 case 'h':
00738 default:
00739 Usage();
00740 return 0;
00741 }
00742 }
00743
00744
00745
00746 Barry::Init(data_dump);
00747 if( data_dump ) {
00748 int major, minor;
00749 const char *Version = Barry::Version(major, minor);
00750 cout << Version << endl;
00751 }
00752
00753
00754 auto_ptr<IConverter> ic;
00755 if( iconvCharset.size() ) {
00756 ic.reset( new IConverter(iconvCharset.c_str(), true) );
00757 }
00758
00759
00760 ContactLdif ldif(ldifBaseDN);
00761 DoMapping(ldif, mapCommands);
00762 if( ldifDnAttr.size() ) {
00763 if( !ldif.SetDNAttr(ldifDnAttr) ) {
00764 cerr << "Unable to set DN Attr: " << ldifDnAttr << endl;
00765 }
00766 }
00767
00768
00769
00770
00771 Barry::Probe probe(busname.c_str(), devname.c_str(),
00772 epp_override ? &epOverride : 0);
00773 int activeDevice = -1;
00774
00775
00776 if( probe.GetFailCount() ) {
00777 if( ldif_contacts )
00778 cout << "# ";
00779 cout << "Blackberry device errors with errors during probe:" << endl;
00780 for( int i = 0; i < probe.GetFailCount(); i++ ) {
00781 if( ldif_contacts )
00782 cout << "# ";
00783 cout << probe.GetFailMsg(i) << endl;
00784 }
00785 }
00786
00787
00788 if( ldif_contacts )
00789 cout << "# ";
00790 cout << "Blackberry devices found:" << endl;
00791 for( int i = 0; i < probe.GetCount(); i++ ) {
00792 if( ldif_contacts )
00793 cout << "# ";
00794 if( data_dump )
00795 probe.Get(i).DumpAll(cout);
00796 else
00797 cout << probe.Get(i);
00798 cout << endl;
00799 if( probe.Get(i).m_pin == pin )
00800 activeDevice = i;
00801 }
00802
00803 if( list_only )
00804 return 0;
00805
00806 if( activeDevice == -1 ) {
00807 if( pin == 0 ) {
00808
00809 if( probe.GetCount() == 1 )
00810 activeDevice = 0;
00811 else {
00812 cerr << "No device selected" << endl;
00813 return 1;
00814 }
00815 }
00816 else {
00817 cerr << "PIN " << setbase(16) << pin
00818 << " not found" << endl;
00819 return 1;
00820 }
00821 }
00822
00823 if( ldif_contacts )
00824 cout << "# ";
00825 cout << "Using device (PIN): "
00826 << probe.Get(activeDevice).m_pin.str() << endl;
00827
00828 if( reset_device ) {
00829 Usb::Device dev(probe.Get(activeDevice).m_dev);
00830 dev.Reset();
00831 return 0;
00832 }
00833
00834
00835 Barry::ProbeResult device = probe.Get(activeDevice);
00836 if( epp_override ) {
00837 device.m_ep.read = epOverride.read;
00838 device.m_ep.write = epOverride.write;
00839 device.m_ep.type = 2;
00840 cout << "Endpoint pair (read,write) overridden with: "
00841 << hex
00842 << (unsigned int) device.m_ep.read << ","
00843 << (unsigned int) device.m_ep.write << endl;
00844 }
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856 auto_ptr<SocketRoutingQueue> router;
00857 auto_ptr<Barry::Controller> pcon;
00858 if( threaded_sockets ) {
00859 router.reset( new SocketRoutingQueue );
00860 router->SpinoffSimpleReadThread();
00861 pcon.reset( new Barry::Controller(device, *router) );
00862 }
00863 else {
00864 pcon.reset( new Barry::Controller(device) );
00865 }
00866
00867 Barry::Controller &con = *pcon;
00868 Barry::Mode::Desktop desktop(con, *ic);
00869
00870
00871
00872
00873
00874
00875
00876 if( show_dbdb ) {
00877
00878 desktop.Open(password.c_str());
00879 cout << desktop.GetDBDB() << endl;
00880 }
00881
00882
00883 if( list_contact_fields ) {
00884 for( const ContactLdif::NameToFunc *n = ldif.GetFieldNames(); n->name; n++ ) {
00885 cout.fill(' ');
00886 cout << " " << left << setw(20) << n->name << ": "
00887 << n->description << endl;
00888 }
00889 }
00890
00891
00892 if( list_ldif_map ) {
00893 cout << ldif << endl;
00894 }
00895
00896
00897
00898 if( ldif_contacts ) {
00899
00900 desktop.Open(password.c_str());
00901
00902
00903
00904 Contact2Ldif storage(ldif);
00905
00906
00907 desktop.LoadDatabaseByType<Barry::Contact>(storage);
00908 }
00909
00910
00911 if( record_state ) {
00912 if( dbNames.size() == 0 ) {
00913 cout << "No db names to process" << endl;
00914 return 1;
00915 }
00916
00917 desktop.Open(password.c_str());
00918
00919 vector<string>::iterator b = dbNames.begin();
00920 for( ; b != dbNames.end(); b++ ) {
00921 unsigned int id = desktop.GetDBID(*b);
00922 RecordStateTable state;
00923 desktop.GetRecordStateTable(id, state);
00924 cout << "Record state table for: " << *b << endl;
00925 cout << state;
00926 }
00927 return 0;
00928 }
00929
00930
00931 if( stCommands.size() ) {
00932 if( dbNames.size() != 1 ) {
00933 cout << "Must have 1 db name to process" << endl;
00934 return 1;
00935 }
00936
00937 desktop.Open(password.c_str());
00938 unsigned int id = desktop.GetDBID(dbNames[0]);
00939 auto_ptr<Parser> parse = GetParser(dbNames[0],filename,
00940 null_parser, true, vformat_mode);
00941
00942 for( unsigned int i = 0; i < stCommands.size(); i++ ) {
00943 desktop.GetRecord(id, stCommands[i].index, *parse.get());
00944
00945 if( stCommands[i].flag == 'r' && stCommands[i].clear ) {
00946 cout << "Clearing record's dirty flags..." << endl;
00947 desktop.ClearDirty(id, stCommands[i].index);
00948 }
00949
00950 if( stCommands[i].flag == 'D' ) {
00951 desktop.DeleteRecord(id, stCommands[i].index);
00952 }
00953 }
00954
00955 return 0;
00956 }
00957
00958
00959 if (clear_database) {
00960 if( clearDbNames.size() == 0 ) {
00961 cout << "No db names to erase" << endl;
00962 return 1;
00963 }
00964
00965 vector<string>::iterator b = clearDbNames.begin();
00966
00967 desktop.Open(password.c_str());
00968
00969 for( ; b != clearDbNames.end(); b++ ) {
00970 unsigned int id = desktop.GetDBID(*b);
00971 cout << "Deleting all records from " << (*b) << "..." << endl;
00972 desktop.ClearDatabase(id);
00973 }
00974
00975 return 0;
00976 }
00977
00978
00979
00980
00981 if( dbNames.size() ) {
00982 vector<string>::iterator b = dbNames.begin();
00983
00984 desktop.Open(password.c_str());
00985 for( ; b != dbNames.end(); b++ ) {
00986 auto_ptr<Parser> parse = GetParser(*b,filename,
00987 null_parser, !sort_records,
00988 vformat_mode);
00989 unsigned int id = desktop.GetDBID(*b);
00990 desktop.LoadDatabase(id, *parse.get());
00991 }
00992 }
00993
00994
00995
00996 if( saveDbNames.size() ) {
00997 vector<string>::iterator b = saveDbNames.begin();
00998
00999 desktop.Open(password.c_str());
01000 for( ; b != saveDbNames.end(); b++ ) {
01001 auto_ptr<Builder> build =
01002 GetBuilder(*b, filename);
01003 unsigned int id = desktop.GetDBID(*b);
01004 desktop.SaveDatabase(id, *build);
01005 }
01006 }
01007
01008 }
01009 catch( Usb::Error &ue) {
01010 std::cerr << "Usb::Error caught: " << ue.what() << endl;
01011 return 1;
01012 }
01013 catch( Barry::Error &se ) {
01014 std::cerr << "Barry::Error caught: " << se.what() << endl;
01015 return 1;
01016 }
01017 catch( std::exception &e ) {
01018 std::cerr << "std::exception caught: " << e.what() << endl;
01019 return 1;
01020 }
01021
01022 return 0;
01023 }
01024