|
1 /* |
|
2 * Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of the License "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #ifdef _MSC_VER |
|
20 #pragma warning (disable: 4786) |
|
21 #endif // _MSC_VER |
|
22 |
|
23 // System includes |
|
24 #include <iosfwd> |
|
25 #include <sstream> |
|
26 #include <iostream> |
|
27 #include <fstream> |
|
28 #include <algorithm> |
|
29 |
|
30 #ifndef __TOOLS2_LINUX__ |
|
31 #include <windows.h> |
|
32 #endif |
|
33 |
|
34 // User includes |
|
35 #include "commandparser.h" |
|
36 #include "openssllicense.h" |
|
37 #include "sisregistry.h" |
|
38 #include "parameterlist.h" |
|
39 #include "is_utils.h" |
|
40 #include "stringutils.h" |
|
41 |
|
42 // Global/static variables |
|
43 CCommandParser::WarnMap CCommandParser::KString2Warning; |
|
44 |
|
45 |
|
46 CCommandParser::CCommandParser(): |
|
47 iWarnLevel( WARN_WARN ) |
|
48 { |
|
49 } |
|
50 |
|
51 CCommandParser::~CCommandParser() |
|
52 { |
|
53 } |
|
54 |
|
55 void CCommandParser::DisplayError( int aError ) |
|
56 { |
|
57 const wchar_t* msg; |
|
58 // |
|
59 switch( aError ) |
|
60 { |
|
61 case ECmdLineUnknownOption: |
|
62 msg = L"Unknown option specified"; |
|
63 break; |
|
64 case ECmdLineMissingParamFile: |
|
65 msg = L"Can't open the parameter file specified"; |
|
66 break; |
|
67 case ECmdLineNoDirArgument: |
|
68 msg = L"No directory(s) specified"; |
|
69 break; |
|
70 case ECmdLineNoSisArgument: |
|
71 msg = L"No SIS file(s) specified"; |
|
72 break; |
|
73 case ECmdLineNoRomRofsLogsArgument: |
|
74 msg = L"No ROM/ROFS[BUILD] log file(s) specified"; |
|
75 break; |
|
76 case ECmdLineNoConfigFileArgument: |
|
77 msg = L"No configuration file specified"; |
|
78 break; |
|
79 case ECmdLineNoSisStubPathArgument: |
|
80 msg = L"No SIS stub directory specified"; |
|
81 break; |
|
82 case ECmdLineMissingParams: |
|
83 msg = L"Missing parameters"; |
|
84 break; |
|
85 case ECmdLineInvalidLanguage: |
|
86 msg = L"Invalid language code"; |
|
87 break; |
|
88 case ECmdLineMissingPackageUID: |
|
89 msg = L"Package UID not found"; |
|
90 break; |
|
91 default: |
|
92 msg = L"Unknown error"; |
|
93 break; |
|
94 } |
|
95 // |
|
96 LERROR(msg << std::endl); |
|
97 DisplayUsage(); |
|
98 } |
|
99 |
|
100 void CCommandParser::DisplayOpenSSLCopyright() |
|
101 { |
|
102 //displays OpenSSL copyright notice. |
|
103 for (int index = 0; index < (sizeof(openSSLLicenseString)/sizeof(openSSLLicenseString[0])); ++index) |
|
104 { |
|
105 std::cout << openSSLLicenseString [index] << std::endl; |
|
106 } |
|
107 } |
|
108 |
|
109 void CCommandParser::DisplayUsage() |
|
110 { |
|
111 DisplayVersion(); |
|
112 |
|
113 std::cout |
|
114 #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK |
|
115 << "Usage: " << CommandName () << " [-z dir] [-c dir] [-e] [-f] [-k [4.0 | 5.0 | 5.1 | 5.2 | 5.3 | 5.4]]\n" |
|
116 #else |
|
117 << "Usage: " << CommandName () << " [-z dir] [-c dir] [-e] [-k [4.0 | 5.0 | 5.1 | 5.2 | 5.3 | 5.4]]\n" |
|
118 #endif |
|
119 << "\t\t[-s [sisfile | dir] [+drive [+mcard | +mcardnr | +mcardalone | +mcardalonenr] [+sucert]]] [-s ...]\n" |
|
120 << "\t\t[-p param_file] [-d drive] [-r rofsbuild_log_file1,rofsbuild_log_file2,...]\n" |
|
121 << "\t\t[-t romstubdir] [-n language_code] [-i config_file] \n" |
|
122 << "\t\t[-x pkgUID[,pkgUID2,...]] [-w [off | error | warn | info]] [-l logfile]\n\n" |
|
123 << "Where:\t-h\t\tDisplays help\n" |
|
124 << "\t-c\t\tThe directory representing the system drive on the device\n" |
|
125 << "\t-d\t\tThe system drive letter [default to 'C']\n" |
|
126 << "\t-e\t\tDisable eclipsing and SID checks using Z drive \n" |
|
127 << "\t \t\t-z or -r not required when this option used \n" |
|
128 #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK |
|
129 << "\t-f\t\tUsed to specify that origin of a component has not been verified during installation.\n" |
|
130 << "\t\t\tBy default the origin is verified. This option should not be provided along with registry version information.\n" |
|
131 #endif |
|
132 |
|
133 << "\t-i\t\tConfig file with HAL attribute values for installation \n"; |
|
134 std::cout |
|
135 #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK |
|
136 << "\t-k\t\tSIS Registry version to generate (default is to generate the db related registry entry) \n" |
|
137 #else |
|
138 << "\t-k\t\tSIS Registry version to generate (default v" << SisRegistry::KSisRegistryMajorVersion |
|
139 << "." << SisRegistry::KSisRegistryMinorVersion << ") \n" |
|
140 #endif //SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK |
|
141 << "\t-l\t\tThe file to write diagnostics to (stderr by default)\n" |
|
142 << "\t-n\t\tLanguage code - decimal number as defined in TLanguage enum\n" |
|
143 << "\t-o\t\tOutput licence information\n" |
|
144 << "\t-p\t\tA file to take additional parameters from.\n" |
|
145 << "\t \t\tCommand line args after the file will override the file contents\n" |
|
146 << "\t-r\t\tList of rom/rofs build log files; should not use with -z option or\n" |
|
147 << "\t \t\tdefine the Z drive in the config file\n" |
|
148 << "\t-s\t\tThe SIS file(s) to install. Any directory passed in will be searched\n" |
|
149 << "\t\t\tfor SIS files; should not use with -x option\n" |
|
150 |
|
151 << "\t-t\t\tROM Stub sis files directory, must be used with -r option\n" |
|
152 << "\t-v\t\tDisplays the version of the tool\n" |
|
153 << "\t-w\t\tThe level of diagnostics to display- WARN, ERROR, INFO, OFF\n" |
|
154 << "\t \t\t(warn by default)\n" |
|
155 |
|
156 << "\t-x\t\tRemove the files installed of a package; should not use with -s option\n" |
|
157 << "\t-z\t\tThe directory representing the Z: drive on the device\n" |
|
158 << "\tpkgUID\t\tThe installed package UID either in Hex or Decimal format (e.g. 0x12345678, 305419896)\n" |
|
159 << "\tsisfile\t\tThe SIS file to be installed\n" |
|
160 << "\tdir\t\tThe directory that contains the installing SIS files\n" |
|
161 << "\tdrive\t\tThe drive letter on the device\n" |
|
162 << "\tmcard\t\tOption to generate the stub SIS file for the installing package\n" |
|
163 << "\tmcardnr\t\tOption to generate the non-removable stub SIS file for the installing package\n" |
|
164 << "\tmcardalone\tOption to just create a pre-installed package to the media card\n" |
|
165 << "\tmcardalonenr\tOption to generate the non-removable stub SIS file for the installing" << std::endl |
|
166 << "\t\t\tpackage without generating the SISregistry entry\n" |
|
167 << "\tsucert\t\tTo indicate that the SIS file has been signed with a SU certificate\n\n"; |
|
168 } |
|
169 |
|
170 void CCommandParser::DisplayVersion() |
|
171 { |
|
172 std::cout << "\nINTERPRETSIS " << " Version 2.1.2 ." << std::endl; |
|
173 std::cout << "Copyright (c) 2009 Symbian Software Ltd. All rights reserved.\n " << std::endl; |
|
174 } |
|
175 |
|
176 |
|
177 CParameterList* CCommandParser::ParseOptions(int argc, const char**argv) |
|
178 { |
|
179 CParameterList* paramList = new CParameterList(); |
|
180 bool bAbort = ParseParam(argc, argv, paramList); |
|
181 if(bAbort) |
|
182 { |
|
183 delete paramList; |
|
184 paramList = NULL; |
|
185 } |
|
186 return paramList; |
|
187 } |
|
188 bool CCommandParser::ParseParam(int argc, const char**argv, CParameterList* aParamList) |
|
189 { |
|
190 if (argc < 2) |
|
191 { |
|
192 throw CCommandParser::ECmdLineUnknownOption; |
|
193 } |
|
194 |
|
195 bool bContinue = true; |
|
196 |
|
197 while ((--argc > 0) && bContinue) |
|
198 { |
|
199 ++argv; |
|
200 if (**argv != '-') |
|
201 { |
|
202 continue; |
|
203 } |
|
204 |
|
205 bool err = false; |
|
206 const char* optPtr = *argv; |
|
207 |
|
208 switch (toupper(*++optPtr)) |
|
209 { |
|
210 case 'C': |
|
211 { |
|
212 if (argc <= 1) |
|
213 throw CCommandParser::ECmdLineNoDirArgument; |
|
214 |
|
215 --argc; |
|
216 aParamList->SetSystemDrive(*(++argv)); |
|
217 break; |
|
218 } |
|
219 case 'D': |
|
220 { |
|
221 --argc; |
|
222 wchar_t buf[2048]; |
|
223 ConvertMultiByteToWideChar(*++argv,-1, buf, 2048); |
|
224 aParamList->SetSystemDriveLetter(tolower(buf[0])); |
|
225 break; |
|
226 } |
|
227 case 'E': |
|
228 { |
|
229 aParamList->SetFlag(CParameterList::EFlagsDisableZDriveChecksSet); |
|
230 break; |
|
231 } |
|
232 #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK |
|
233 case 'F': |
|
234 { |
|
235 aParamList->SetOriginVerificationStatus(false); |
|
236 break; |
|
237 } |
|
238 #endif |
|
239 case 'H': |
|
240 case '?': |
|
241 { |
|
242 DisplayUsage(); |
|
243 bContinue = false; |
|
244 break; |
|
245 } |
|
246 case 'I': |
|
247 { |
|
248 if (argc <= 1) |
|
249 throw CCommandParser::ECmdLineNoConfigFileArgument; |
|
250 |
|
251 --argc; |
|
252 aParamList->SetConfigFile(*(++argv)); |
|
253 break; |
|
254 } |
|
255 case 'K': |
|
256 { |
|
257 // Last command |
|
258 if (argc == 1) |
|
259 { |
|
260 aParamList->SetSisRegistryVersion(SisRegistry::KRegistryV40string); |
|
261 } |
|
262 else |
|
263 { |
|
264 // Check that the next arg is valid |
|
265 std::string versionStr = *(++argv); |
|
266 |
|
267 if (**argv == '-') |
|
268 { |
|
269 aParamList->SetSisRegistryVersion(SisRegistry::KRegistryV40string); |
|
270 --argv; |
|
271 } |
|
272 else |
|
273 { |
|
274 --argc; |
|
275 aParamList->SetSisRegistryVersion(versionStr); |
|
276 } |
|
277 } |
|
278 break; |
|
279 } |
|
280 case 'L': |
|
281 { |
|
282 if (argc > 1) |
|
283 { |
|
284 --argc; |
|
285 wchar_t buf[2048]; |
|
286 ConvertMultiByteToWideChar(*++argv,-1, buf, 2048); |
|
287 iLogFile = buf; |
|
288 } |
|
289 break; |
|
290 } |
|
291 case 'N': |
|
292 { |
|
293 if (argc <= 1) |
|
294 throw CCommandParser::ECmdLineInvalidLanguage; |
|
295 |
|
296 --argc; |
|
297 aParamList->SetLanguage(static_cast< CSISLanguage::TLanguage >( String2Language( *(++argv) ) )); |
|
298 break; |
|
299 } |
|
300 case 'O': |
|
301 { |
|
302 DisplayOpenSSLCopyright(); |
|
303 bContinue = false; |
|
304 break; |
|
305 } |
|
306 case 'P': |
|
307 { |
|
308 if (!(err = argc <= 1)) |
|
309 { |
|
310 --argc; |
|
311 std::string paramFile = *(++argv); |
|
312 ParseParam(argc, paramFile, aParamList); |
|
313 } |
|
314 break; |
|
315 } |
|
316 case 'R': |
|
317 { |
|
318 if (argc <= 1) |
|
319 throw CCommandParser::ECmdLineNoRomRofsLogsArgument; |
|
320 |
|
321 --argc; |
|
322 aParamList->EmptyRomLogFiles(); |
|
323 #ifdef _MSC_VER |
|
324 FilePtr funtionPtr = aParamList->AddRomLogFile; |
|
325 #else |
|
326 FilePtr funtionPtr = &(aParamList->AddRomLogFile); |
|
327 #endif // _MSC_VER |
|
328 String2List(*aParamList, funtionPtr, *(++argv) ); |
|
329 break; |
|
330 } |
|
331 case 'S': |
|
332 { |
|
333 if (argc <= 1) |
|
334 throw CCommandParser::ECmdLineNoSisArgument; |
|
335 |
|
336 --argc; |
|
337 |
|
338 String2SISFileList(*aParamList, argc, ++argv); |
|
339 break; |
|
340 } |
|
341 case 'T': |
|
342 { |
|
343 if (argc <= 1) |
|
344 throw CCommandParser::ECmdLineNoSisStubPathArgument; |
|
345 |
|
346 --argc; |
|
347 aParamList->SetStubDir(*(++argv)); |
|
348 break; |
|
349 } |
|
350 case 'V': |
|
351 { |
|
352 DisplayVersion(); |
|
353 bContinue = false; |
|
354 break; |
|
355 } |
|
356 case 'W': |
|
357 { |
|
358 --argc; |
|
359 iWarnLevel = String2Warn(*(++argv)); |
|
360 break; |
|
361 } |
|
362 case 'X': |
|
363 { |
|
364 if (argc <= 1) |
|
365 throw CCommandParser::ECmdLineMissingPackageUID; |
|
366 |
|
367 --argc; |
|
368 aParamList->EmptyPkgUids(); |
|
369 #ifdef _MSC_VER |
|
370 FilePtr funtionPtr = (aParamList->AddPkgUid); |
|
371 #else |
|
372 FilePtr funtionPtr = &(aParamList->AddPkgUid); |
|
373 #endif // _MSC_VER |
|
374 String2List(*aParamList, funtionPtr, *(++argv) ); |
|
375 break; |
|
376 } |
|
377 case 'Z': |
|
378 { |
|
379 if (argc <= 1) |
|
380 throw CCommandParser::ECmdLineNoDirArgument; |
|
381 |
|
382 --argc; |
|
383 aParamList->SetZDrive(*(++argv)); |
|
384 break; |
|
385 } |
|
386 default: |
|
387 { |
|
388 LERROR(Utf8ToUcs2(std::string(optPtr))); |
|
389 throw CCommandParser::ECmdLineUnknownOption; |
|
390 } |
|
391 } |
|
392 |
|
393 if (err) |
|
394 { |
|
395 throw CCommandParser::ECmdLineUnknownOption; |
|
396 } |
|
397 } // Finished parsing all the command line options |
|
398 |
|
399 return !bContinue; |
|
400 } |
|
401 |
|
402 |
|
403 void CCommandParser::ParseParam(int argc, const std::string& paramFile, CParameterList* aParamList) |
|
404 { |
|
405 if (paramFile.size() > 0) |
|
406 { |
|
407 std::ifstream params; |
|
408 params.open(paramFile.c_str(), std::ios::in); |
|
409 |
|
410 if (!params.good()) |
|
411 { |
|
412 throw CCommandParser::ECmdLineMissingParamFile; |
|
413 } |
|
414 |
|
415 std::vector<std::string> tokens; |
|
416 argc = 0; |
|
417 while (params.good()) |
|
418 { |
|
419 std::string token; |
|
420 params >> token; |
|
421 if(token != "") |
|
422 { |
|
423 argc++; |
|
424 tokens.push_back(token); |
|
425 } |
|
426 } |
|
427 |
|
428 const char** newArgv = new const char*[tokens.size()+1]; |
|
429 for (int i = 0 ; i < tokens.size() ; ++i) |
|
430 { |
|
431 newArgv[i+1] = tokens[i].c_str(); |
|
432 } |
|
433 |
|
434 ParseParam(argc+1, newArgv, aParamList); |
|
435 delete [] newArgv; |
|
436 params.close(); |
|
437 } |
|
438 } |
|
439 |
|
440 void CCommandParser::String2List(CParameterList& aParamList, FilePtr& aFilePtr, const std::string& aOptionsString) |
|
441 { |
|
442 std::string::const_iterator it = aOptionsString.begin(); |
|
443 std::string::const_iterator end = aOptionsString.end(); |
|
444 std::string::const_iterator currentPos = it; |
|
445 // |
|
446 while (currentPos != end) |
|
447 { |
|
448 currentPos = std::find(it, end, ','); |
|
449 std::wstring x; |
|
450 Utf8ToUcs2(std::string(it,(currentPos-it)), x); |
|
451 //aOptionsList.push_back(x); |
|
452 (aParamList.*aFilePtr)(x); |
|
453 |
|
454 if (currentPos == end) |
|
455 { |
|
456 return; |
|
457 } |
|
458 |
|
459 it = currentPos; |
|
460 ++it; |
|
461 } |
|
462 } |
|
463 |
|
464 void CCommandParser::String2SISFileList(CParameterList& aParamList, int aArgc, const char**aArgv) |
|
465 { |
|
466 std::string sisFileOption(*aArgv); |
|
467 |
|
468 std::string::const_iterator it = sisFileOption.begin(); |
|
469 std::string::const_iterator end = sisFileOption.end(); |
|
470 std::string::const_iterator currentPos = it; |
|
471 |
|
472 currentPos = std::find(it, end, ','); |
|
473 |
|
474 while (currentPos != end) |
|
475 { |
|
476 currentPos = std::find(it, end, ','); |
|
477 std::wstring x; |
|
478 Utf8ToUcs2(std::string(it,(currentPos-it)), x); |
|
479 |
|
480 InstallSISFile sisFileName(x, '$', false); |
|
481 aParamList.AddSISFile(sisFileName); |
|
482 |
|
483 if (currentPos == end) |
|
484 { |
|
485 return; |
|
486 } |
|
487 |
|
488 it = currentPos; |
|
489 ++it; |
|
490 } |
|
491 |
|
492 // At this stage, aArgv could be something like: file.sis +e +mcard +sucert |
|
493 // As the sisfile attributes are predetermined input, therefore we can just |
|
494 // parse according to the predetermined inputs. |
|
495 |
|
496 std::wstring fileName; |
|
497 Utf8ToUcs2(sisFileOption, fileName); |
|
498 |
|
499 InstallSISFile sisFileName(fileName, '$', false); |
|
500 |
|
501 while (--aArgc > 0) |
|
502 { // Process associated SIS file attributes |
|
503 ++aArgv; |
|
504 |
|
505 if (**aArgv == '-') |
|
506 { // No more attribute to process |
|
507 aParamList.AddSISFile(sisFileName); |
|
508 |
|
509 --aArgv; |
|
510 ++aArgc; |
|
511 return; |
|
512 } |
|
513 |
|
514 if (**aArgv == '+') |
|
515 { |
|
516 std::string versionStr; |
|
517 |
|
518 // Check that the next arg is valid |
|
519 versionStr = *(aArgv); |
|
520 |
|
521 if (versionStr.size() == 2) |
|
522 { |
|
523 // Found the associated SIS file drive; e.g. +e |
|
524 const char* optPtr = *aArgv; |
|
525 |
|
526 char drive = tolower(*++optPtr); |
|
527 |
|
528 if (drive < 'a' || drive > 'y') |
|
529 throw CCommandParser::ECmdLineInvalidSISFileAttribute; |
|
530 |
|
531 // Set target drive |
|
532 sisFileName.iTargetDrive = drive; |
|
533 |
|
534 continue; |
|
535 } |
|
536 |
|
537 versionStr = StringUtils::ToUpper( versionStr ); |
|
538 |
|
539 if (versionStr == "+MCARD") |
|
540 { |
|
541 sisFileName.iGenerateStub = true; |
|
542 } |
|
543 else if (versionStr == "+MCARDNR") |
|
544 { |
|
545 sisFileName.iGenerateStub = true; |
|
546 sisFileName.iNonRemovable = true; |
|
547 } |
|
548 else if (versionStr == "+MCARDALONE") |
|
549 { |
|
550 sisFileName.iGenerateStub = true; |
|
551 sisFileName.iNotRegister = true; |
|
552 } |
|
553 else if (versionStr == "+MCARDALONENR") |
|
554 { |
|
555 sisFileName.iGenerateStub = true; |
|
556 sisFileName.iNotRegister = true; |
|
557 sisFileName.iNonRemovable = true; |
|
558 } |
|
559 else if (versionStr == "+SUCERT") |
|
560 { |
|
561 sisFileName.iSUFlag = true; |
|
562 } |
|
563 else |
|
564 throw CCommandParser::ECmdLineInvalidSISFileAttribute; |
|
565 } |
|
566 else |
|
567 { |
|
568 throw CCommandParser::ECmdLineInvalidSISFileAttribute; |
|
569 } |
|
570 } |
|
571 aParamList.AddSISFile(sisFileName); |
|
572 } |
|
573 |
|
574 |
|
575 WarnLevel CCommandParser::String2Warn(const std::string& level) |
|
576 { |
|
577 std::string l(level); |
|
578 std::transform(l.begin(),l.end(),l.begin(), toupper); |
|
579 // |
|
580 if (KString2Warning.size() == 0) |
|
581 { |
|
582 KString2Warning["OFF"] = WARN_OFF; |
|
583 KString2Warning["WARN"] = WARN_WARN; |
|
584 KString2Warning["ERROR"] = WARN_ERROR; |
|
585 KString2Warning["INFO"] = WARN_INFO; |
|
586 } |
|
587 // |
|
588 WarnMap::const_iterator result = KString2Warning.find(l); |
|
589 if (result == KString2Warning.end()) |
|
590 { |
|
591 throw CCommandParser::ECmdLineUnknownOption; |
|
592 } |
|
593 // |
|
594 return result->second; |
|
595 } |
|
596 |
|
597 |
|
598 int CCommandParser::String2Language( const std::string& aLanguage ) |
|
599 { |
|
600 std::istringstream stringStream( aLanguage ); |
|
601 int language = 1; |
|
602 // |
|
603 if ( stringStream >> language ) |
|
604 { |
|
605 } |
|
606 else |
|
607 { |
|
608 throw CCommandParser::ECmdLineInvalidLanguage; |
|
609 } |
|
610 // |
|
611 return language; |
|
612 } |