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