Optimized logs.php doc page
[barry.git] / tools / bjavaloader.cc
blob6cf329408818b7f1bebf2ea6f7f760080560acbc
1 ///
2 /// \file bjavaloader.cc
3 ///
4 ///
6 /*
7 Copyright (C) 2008-2009, Nicolas VIVIEN
8 Copyright (C) 2005-2009, 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 <barry/cod.h>
28 #include <iomanip>
29 #include <iostream>
30 #include <fstream>
31 #include <sstream>
32 #include <vector>
33 #include <string>
34 #include <cstring>
35 #include <algorithm>
36 #include <getopt.h>
37 #include <sys/types.h>
38 #include <sys/stat.h>
40 // supported javaloader commands
41 #define CMD_LIST "dir"
42 #define CMD_LOAD "load"
43 #define CMD_SETTIME "settime"
45 // time string format specifier and user friendly description
46 #define TIME_FMT "%Y-%m-%d %H:%M:%S"
47 #define TIME_FMT_EXAMPLE "yyyy-mm-dd HH:MM:SS"
49 using namespace std;
50 using namespace Barry;
52 void Usage()
54 int major, minor;
55 const char *Version = Barry::Version(major, minor);
57 cerr
58 << "bjavaloader - Command line USB Blackberry Java Loader\n"
59 << " Copyright 2008-2009, Nicolas VIVIEN.\n"
60 << " Copyright 2005-2009, Net Direct Inc. (http://www.netdirect.ca/)\n"
61 << " Using: " << Version << "\n"
62 << "\n"
63 << " -h This help\n"
64 << " -s List sibling in module list\n"
65 << " -p pin PIN of device to talk with\n"
66 << " If only one device is plugged in, this flag is optional\n"
67 << " -P pass Simplistic method to specify device password\n"
68 << " -v Dump protocol data during operation\n"
69 << "\n"
70 << "commands\n"
71 << "\n"
72 << " " << CMD_LIST << endl
73 << " Lists modules on the handheld\n"
74 << "\n"
75 << " " << CMD_LOAD << " <.cod file> ...\n"
76 << " Loads modules onto the handheld\n"
77 << "\n"
78 << " " << CMD_SETTIME << " [" << TIME_FMT_EXAMPLE << "]\n"
79 << " Sets the time on the handheld to the current time\n"
80 << " Or the time specified as an argument to " << CMD_SETTIME << "\n"
81 << " If given as argument, current system timezone is assumed\n"
82 << endl;
86 class AutoClose
88 FILE *fp;
90 public:
91 AutoClose(FILE *fh) : fp(fh) {}
92 ~AutoClose()
94 fclose(fp);
98 void SetTime(Barry::Mode::JavaLoader *javaloader, const char *timestr)
100 time_t when;
102 if( timestr ) {
103 struct tm timeinfo;
105 // parse time string
106 char *p = strptime(timestr, TIME_FMT, &timeinfo);
108 // NULL is return when strptime fails to match all of the format
109 // string, and returns a pointer to the NULL byte at the end of
110 // the input string on success
111 if( p == NULL || p != (timestr + strlen(timestr)) ) {
112 throw runtime_error(string("Unable to parse time string: ") + timestr);
115 when = mktime(&timeinfo);
116 } else { // time string is NULL, get current time
117 time(&when);
120 javaloader->SetTime(when);
123 void SendAppFile(Barry::Mode::JavaLoader *javaloader, const char *filename)
125 FILE *fp;
127 char *data = NULL;
129 codfile_header_t header;
131 size_t n;
132 size_t skip;
133 off_t filesize;
134 struct stat sb;
137 // Get file size
138 if (stat(filename, &sb) == -1) {
139 throw runtime_error(string("Can't stat: ") + filename);
142 filesize = sb.st_size;
143 if( (unsigned long)filesize > (size_t)-1 ) {
144 throw runtime_error("Filesize larger than max fread()... contact Barry developers.");
147 // Open file
148 fp = fopen(filename, "rb");
150 if (fp == NULL) {
151 throw runtime_error(string("Can't open: ") + filename);
154 AutoClose ac(fp);
156 // Read the file
157 while (!feof(fp)) {
158 n = fread(&header, sizeof(codfile_header_t), 1, fp);
160 if (n != 1)
161 continue;
163 // Is a COD file packed (a big COD file) ?
164 if (header.type == 0x4B50) {
165 if (header.size1 != header.size2)
166 continue;
168 skip = header.strsize + header.strfree;
170 if( fseek(fp, skip, SEEK_CUR) != 0 ) {
171 throw runtime_error("Can't skip COD header");
174 // this is a one-time program, so allocate and
175 // don't worry about freeing
176 data = (char *) realloc(data, header.size1 * sizeof(char));
178 n = fread(data, sizeof(char), header.size1, fp);
179 if( n != header.size1 ) {
180 throw runtime_error("Can't read packed COD header");
183 javaloader->SendStream(data, (int) header.size1);
185 // Is a simple COD file (a small COD file) ?
186 else if (header.type == 0xC0DE) {
187 rewind(fp);
189 data = (char *) malloc(filesize * sizeof(char));
191 n = fread(data, sizeof(char), filesize, fp);
192 if( (off_t) n != filesize ) {
193 throw runtime_error("Can't read COD data");
196 // Open stream
197 javaloader->SendStream(data, filesize);
203 int main(int argc, char *argv[])
205 cout.sync_with_stdio(true); // leave this on, since libusb uses
206 // stdio for debug messages
208 try {
210 uint32_t pin = 0;
211 bool list_siblings = false,
212 data_dump = false;
213 string password;
214 vector<string> params;
215 string busname;
216 string devname;
217 string iconvCharset;
218 Usb::EndpointPair epOverride;
220 // process command line options
221 for(;;) {
222 int cmd = getopt(argc, argv, "hsp:P:v");
223 if( cmd == -1 )
224 break;
226 switch( cmd )
228 case 'p': // Blackberry PIN
229 pin = strtoul(optarg, NULL, 16);
230 break;
232 case 'P': // Device password
233 password = optarg;
234 break;
236 case 's': // turn on listing of sibling modules
237 list_siblings = true;
238 break;
240 case 'v': // data dump on
241 data_dump = true;
242 break;
244 case 'h': // help
245 default:
246 Usage();
247 return 0;
251 argc -= optind;
252 argv += optind;
254 if( argc < 1 ) {
255 cerr << "missing command" << endl;
256 Usage();
257 return 1;
260 // Fetch command from remaining arguments
261 string cmd = argv[0];
262 argc --;
263 argv ++;
265 // Put the remaining arguments into an array
266 for (; argc > 0; argc --, argv ++) {
267 params.push_back(string(argv[0]));
270 // Initialize the barry library. Must be called before
271 // anything else.
272 Barry::Init(data_dump);
274 // Probe the USB bus for Blackberry devices and display.
275 // If user has specified a PIN, search for it in the
276 // available device list here as well
277 Barry::Probe probe;
278 int activeDevice = probe.FindActive(pin);
279 if( activeDevice == -1 ) {
280 cerr << "No device selected, or PIN not found" << endl;
281 return 1;
284 // Create our controller object
285 Barry::Controller con(probe.Get(activeDevice));
286 Barry::Mode::JavaLoader javaloader(con);
289 // execute each mode that was turned on
291 javaloader.Open(password.c_str());
292 javaloader.StartStream();
294 if( cmd == CMD_LIST ) {
295 JLDirectory dir;
296 javaloader.GetDirectory(dir, list_siblings);
297 cout << dir;
298 } else if( cmd == CMD_LOAD ) {
299 if( params.size() == 0 ) {
300 cerr << "specify at least one .cod file to load" << endl;
301 Usage();
302 return 1;
305 vector<string>::iterator i = params.begin(), end = params.end();
306 for( ; i != end; ++i ) {
307 cout << "loading " << (*i) << "... ";
308 SendAppFile(&javaloader, (*i).c_str());
309 cout << "done." << endl;
311 } else if( cmd == CMD_SETTIME ) {
312 if( params.size() > 0 ) {
313 SetTime(&javaloader, params[0].c_str());
314 } else {
315 SetTime(&javaloader, NULL);
317 } else {
318 cerr << "invalid command \"" << cmd << "\"" << endl;
319 Usage();
320 return 1;
323 // Stop
324 javaloader.StopStream();
327 catch( Usb::Error &ue) {
328 std::cerr << "Usb::Error caught: " << ue.what() << endl;
329 return 1;
331 catch( Barry::Error &se ) {
332 std::cerr << "Barry::Error caught: " << se.what() << endl;
333 return 1;
335 catch( std::exception &e ) {
336 std::cerr << "std::exception caught: " << e.what() << endl;
337 return 1;
340 return 0;