Barry debian version 0.18.5-1
[barry.git] / tools / bjavaloader.cc
blob867ec0fd9a3b1d456ddddd2d13408f2ca0a7b7c9
1 ///
2 /// \file bjavaloader.cc
3 ///
4 ///
6 /*
7 Copyright (C) 2008-2009, Nicolas VIVIEN
8 Copyright (C) 2005-2013, Net Direct Inc. (http://www.netdirect.ca/)
10 Some parts are inspired from btool.cc
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
21 See the GNU General Public License in the COPYING file at the
22 root directory of this project for more details.
26 #include <barry/barry.h>
27 #include <iostream>
28 #include <vector>
29 #include <string>
30 #include <cstring>
31 #include <algorithm>
32 #include <fstream>
33 #include <string.h>
34 #include <time.h>
35 #include "i18n.h"
37 #include "barrygetopt.h"
39 // supported javaloader commands
40 #define CMD_LIST "dir"
41 #define CMD_ERASE "erase"
42 #define CMD_LOAD "load"
43 #define CMD_SCREENSHOT "screenshot"
44 #define CMD_SETTIME "settime"
45 #define CMD_EVENTLOG "eventlog"
46 #define CMD_CLEAR_LOG "cleareventlog"
47 #define CMD_SAVE "save"
48 #define CMD_DEVICEINFO "deviceinfo"
49 #define CMD_WIPE "wipe"
50 #define CMD_LOGSTRACES "logstacktraces"
51 #define CMD_RESETFACTORY "resettofactory"
53 // time string format specifier and user friendly description
54 #define TIME_FMT "%Y-%m-%d %H:%M:%S"
55 #define TIME_FMT_EXAMPLE "yyyy-mm-dd HH:MM:SS"
57 using namespace std;
58 using namespace Barry;
60 void Usage()
62 int logical, major, minor;
63 const char *Version = Barry::Version(logical, major, minor);
65 cerr << string_vprintf(
66 _("bjavaloader - Command line USB Blackberry Java Loader\n"
67 " Copyright 2008-2009, Nicolas VIVIEN.\n"
68 " Copyright 2005-2013, Net Direct Inc. (http://www.netdirect.ca/)\n"
69 " Using: %s\n"
70 "\n"
71 " -A Save all modules found\n"
72 " -a Wipe applications only\n"
73 " -i Wipe filesystem only\n"
74 " -f Force erase, if module is in use\n"
75 " -h This help\n"
76 " -s List sibling in module list\n"
77 " -p pin PIN of device to talk with\n"
78 " If only one device is plugged in, this flag is optional\n"
79 " -P pass Simplistic method to specify device password\n"
80 " -v Dump protocol data during operation\n"
81 "\n"
82 "Commands:\n"
83 "\n"
84 " %s [-s]\n"
85 " Lists modules on the handheld\n"
86 "\n"
87 " %s\n"
88 " Provides information on the handheld\n"
89 "\n"
90 " %s <.cod file> ...\n"
91 " Loads modules onto the handheld\n"
92 "\n"
93 " %s [-A] <module name> ...\n"
94 " Retrieves modules from the handheld and writes to .cod file\n"
95 " Note: will overwrite existing files!\n"
96 "\n"
97 " %s [-a | -i]\n"
98 " Wipes the handheld\n"
99 " Use Caution: Wiping filesystem will remove all data\n"
100 " such as messages, contacts, etc.\n"
101 " Wiping applications will remove all .cod files\n"
102 " on the device, including OS .cod files.\n"
103 "\n"
104 " %s\n"
105 " Reset IT policy to factory defaults\n"
106 " Use Caution: Resetting IT policy to factory defaults will\n"
107 " also perform a filesystem wipe which will remove\n"
108 " all data such as messages, contacts, etc.\n"
109 "\n"
110 " %s [-f] <module name> ...\n"
111 " Erase module from handheld\n"
112 "\n"
113 " %s\n"
114 " Retrieves the handheld event log\n"
115 "\n"
116 " %s\n"
117 " Clears the handheld event log\n"
118 "\n"
119 " %s\n"
120 " Dump the stack traces for all threads to the event log\n"
121 "\n"
122 " %s <.bmp file>\n"
123 " Make a screenshot of handheld\n"
124 "\n"
125 " %s [%s]\n"
126 " Sets the time on the handheld to the current time\n"
127 " Or the time specified as an argument to %s\n"
128 " If given as argument, current system timezone is assumed\n"),
129 Version,
130 CMD_LIST,
131 CMD_DEVICEINFO,
132 CMD_LOAD,
133 CMD_SAVE,
134 CMD_WIPE,
135 CMD_RESETFACTORY,
136 CMD_ERASE,
137 CMD_EVENTLOG,
138 CMD_CLEAR_LOG,
139 CMD_LOGSTRACES,
140 CMD_SCREENSHOT,
141 CMD_SETTIME, TIME_FMT_EXAMPLE, CMD_SETTIME)
142 << endl;
146 class AutoClose
148 FILE *fp;
150 public:
151 AutoClose(FILE *fh) : fp(fh) {}
152 ~AutoClose()
154 fclose(fp);
158 void SetTime(Barry::Mode::JavaLoader *javaloader, const char *timestr)
160 time_t when;
162 if( timestr ) {
163 struct tm timeinfo;
164 memset(&timeinfo, 0, sizeof(timeinfo));
166 // parse time string
167 char *p = strptime(timestr, TIME_FMT, &timeinfo);
169 // NULL is return when strptime fails to match all of the format
170 // string, and returns a pointer to the NULL byte at the end of
171 // the input string on success
172 if( p == NULL || p != (timestr + strlen(timestr)) ) {
173 throw runtime_error(string(_("Unable to parse time string: ")) + timestr);
176 when = mktime(&timeinfo);
177 } else { // time string is NULL, get current time
178 time(&when);
181 javaloader->SetTime(when);
184 void SendAppFile(Barry::Mode::JavaLoader *javaloader, const char *filename)
186 ifstream file(filename);
187 javaloader->LoadApp(file);
190 void GetScreenshot(Barry::Mode::JavaLoader *javaloader, const char *filename)
193 // Take a screenshot
194 // - info object contains the screenshot properties (width, height...)
195 // - image will be filled with the raw pixel screenshot data
196 JLScreenInfo info;
197 Data image;
198 javaloader->GetScreenshot(info, image);
201 // Convert to BMP format
202 Data bitmap(-1, GetTotalBitmapSize(info));
203 ScreenshotToBitmap(info, image, bitmap);
205 // Write BMP file
206 FILE *fp = fopen(filename, "wb");
207 if (fp == NULL) {
208 throw runtime_error(string(_("Can't open: ")) + filename);
210 AutoClose ac(fp);
212 fwrite(bitmap.GetData(), bitmap.GetSize(), 1, fp);
215 void SaveModule(Barry::Mode::JavaLoader *javaloader, const char *filename)
217 string fname(filename), module;
219 size_t ext_index = fname.rfind(".cod");
220 if( ext_index != string::npos ) {
221 // filename contains .cod extension, strip it for module name
222 module = fname.substr(0, ext_index);
224 else {
225 // filename does not contain .cod extension, use it as module name
226 module = fname;
227 // append extension to file name
228 fname.append(".cod");
231 ofstream file(fname.c_str(), ios::binary | ios::trunc);
232 javaloader->Save(module.c_str(), file);
236 int main(int argc, char *argv[])
238 INIT_I18N(PACKAGE);
240 cout.sync_with_stdio(true); // leave this on, since libusb uses
241 // stdio for debug messages
243 try {
245 uint32_t pin = 0;
246 bool list_siblings = false,
247 force_erase = false,
248 data_dump = false,
249 all_modules = false,
250 wipe_apps = true,
251 wipe_fs = true;
252 string password;
253 vector<string> params;
254 string busname;
255 string devname;
256 string iconvCharset;
257 Usb::EndpointPair epOverride;
259 // process command line options
260 for(;;) {
261 int cmd = getopt(argc, argv, "Aaifhsp:P:v");
262 if( cmd == -1 )
263 break;
265 switch( cmd )
267 case 'p': // Blackberry PIN
268 pin = strtoul(optarg, NULL, 16);
269 break;
271 case 'P': // Device password
272 password = optarg;
273 break;
275 case 'f': // turn on 'force' mode for erase
276 force_erase = true;
277 break;
279 case 's': // turn on listing of sibling modules
280 list_siblings = true;
281 break;
283 case 'v': // data dump on
284 data_dump = true;
285 break;
287 case 'A': // save all modules
288 all_modules = true;
289 break;
291 case 'a': // wipe apps only
292 wipe_fs = false;
293 break;
295 case 'i': // wipe filesystem
296 wipe_apps = false;
297 break;
299 case 'h': // help
300 default:
301 Usage();
302 return 0;
306 argc -= optind;
307 argv += optind;
309 if( argc < 1 ) {
310 cerr << _("missing command") << endl;
311 Usage();
312 return 1;
315 // Fetch command from remaining arguments
316 string cmd = argv[0];
317 argc --;
318 argv ++;
320 // Put the remaining arguments into an array
321 for (; argc > 0; argc --, argv ++) {
322 params.push_back(string(argv[0]));
325 // Initialize the barry library. Must be called before
326 // anything else.
327 Barry::Init(data_dump);
329 // Probe the USB bus for Blackberry devices and display.
330 // If user has specified a PIN, search for it in the
331 // available device list here as well
332 Barry::Probe probe;
333 int activeDevice = probe.FindActive(pin);
334 if( activeDevice == -1 ) {
335 cerr << _("No device selected, or PIN not found")
336 << endl;
337 return 1;
340 // Create our controller object
341 Barry::Controller con(probe.Get(activeDevice));
342 Barry::Mode::JavaLoader javaloader(con);
345 // execute each mode that was turned on
347 javaloader.Open(password.c_str());
348 javaloader.StartStream();
350 if( cmd == CMD_LIST ) {
351 JLDirectory dir;
352 javaloader.GetDirectory(dir, list_siblings);
353 cout << dir;
355 else if( cmd == CMD_LOAD ) {
356 if( params.size() == 0 ) {
357 cerr << _("specify at least one .cod file to load") << endl;
358 Usage();
359 return 1;
362 vector<string>::iterator i = params.begin(), end = params.end();
363 for( ; i != end; ++i ) {
364 cout << _("loading: ") << (*i) << "... ";
365 SendAppFile(&javaloader, (*i).c_str());
366 cout << _("done.") << endl;
369 else if( cmd == CMD_ERASE ) {
370 if( params.size() == 0 ) {
371 cerr << _("specify at least one module to erase") << endl;
372 Usage();
373 return 1;
376 vector<string>::iterator i = params.begin(), end = params.end();
377 for( ; i != end; ++i ) {
378 cout << _("erasing: ") << (*i) << "... ";
379 if( force_erase )
380 javaloader.ForceErase((*i));
381 else
382 javaloader.Erase((*i));
383 cout << _("done.") << endl;
386 else if( cmd == CMD_SCREENSHOT ) {
387 if( params.size() == 0 ) {
388 cerr << _("specify a .bmp filename") << endl;
389 Usage();
390 return 1;
393 GetScreenshot(&javaloader, params[0].c_str());
395 else if( cmd == CMD_SETTIME ) {
396 if( params.size() > 0 ) {
397 SetTime(&javaloader, params[0].c_str());
398 } else {
399 SetTime(&javaloader, NULL);
402 else if( cmd == CMD_EVENTLOG ) {
403 JLEventlog log;
404 javaloader.GetEventlog(log);
405 cout << log;
407 else if( cmd == CMD_CLEAR_LOG ) {
408 javaloader.ClearEventlog();
410 else if( cmd == CMD_LOGSTRACES ) {
411 javaloader.LogStackTraces();
413 else if( cmd == CMD_SAVE ) {
414 if( all_modules ) {
415 JLDirectory dir;
416 javaloader.GetDirectory(dir, false);
417 JLDirectory::BaseIterator i = dir.begin();
418 for( ; i != dir.end(); ++i ) {
419 cout << _("saving: ") << i->Name << "... ";
420 SaveModule(&javaloader,i->Name.c_str());
421 cout << _("done.") << endl;
424 else if( params.size() == 0 ) {
425 cerr << _("specify at least one module to save") << endl;
426 Usage();
427 return 1;
429 else {
430 vector<string>::iterator i = params.begin(), end = params.end();
431 for( ; i != end; ++i ) {
432 cout << _("saving: ") << (*i) << "... ";
433 SaveModule(&javaloader, (*i).c_str());
434 cout << _("done.") << endl;
438 else if( cmd == CMD_DEVICEINFO ) {
439 JLDeviceInfo info;
440 javaloader.DeviceInfo(info);
441 cout << info;
443 else if( cmd == CMD_WIPE ) {
444 cout << string_vprintf(
445 // TRANSLATORS: you may translate yes/no as long as you also
446 // translate "yes" to match.
447 _("Use Caution: Wiping filesystem will remove all data\n"
448 " such as messages, contacts, etc.\n"
449 " Wiping applications will remove all .cod files\n"
450 " on the device, including OS .cod files.\n\n"
451 "You have selected to wipe the filesystem of device '%s'\n"
452 "Continue with wipe? (yes/no) "), probe.Get(activeDevice).m_pin.Str().c_str());
453 string confirm;
454 getline(cin, confirm);
455 if( confirm == _("yes") ) {
456 javaloader.Wipe(wipe_apps, wipe_fs);
458 else {
459 cout << _("Response of 'yes' not received, aborting.") << endl;
462 else if( cmd == CMD_RESETFACTORY ) {
463 cout << string_vprintf(
464 _("Use Caution: Resetting IT policy to factory defaults will\n"
465 " also perform a filesystem wipe which will remove\n"
466 " all data such as messages, contacts, etc.\n\n"
467 "You have selected to reset device '%s' to factory defaults\n"
468 "Continue with wipe? (yes/no) "), probe.Get(activeDevice).m_pin.Str().c_str());
469 string confirm;
470 getline(cin, confirm);
471 if( confirm == _("yes") ) {
472 javaloader.ResetToFactory();
474 else {
475 cout << _("Response of 'yes' not received, aborting.") << endl;
478 else {
479 cerr << _("invalid command: ") << cmd << endl;
480 Usage();
481 return 1;
484 // Stop
485 javaloader.StopStream();
488 catch( Usb::Error &ue) {
489 std::cout << endl; // flush any normal output first
490 std::cerr << _("Usb::Error caught: ") << ue.what() << endl;
491 return 1;
493 catch( Barry::Error &se ) {
494 std::cout << endl;
495 std::cerr << _("Barry::Error caught: ") << se.what() << endl;
496 return 1;
498 catch( std::exception &e ) {
499 std::cout << endl;
500 std::cerr << _("std::exception caught: ") << e.what() << endl;
501 return 1;
504 return 0;