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