diff -r 000000000000 -r ba25891c3a9e secureswitools/swisistools/source/interpretsis/commandparser.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/secureswitools/swisistools/source/interpretsis/commandparser.cpp Thu Dec 17 08:51:10 2009 +0200 @@ -0,0 +1,612 @@ +/* +* Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#ifdef _MSC_VER +#pragma warning (disable: 4786) +#endif // _MSC_VER + +// System includes +#include +#include +#include +#include +#include + +#ifndef __TOOLS2_LINUX__ +#include +#endif + +// User includes +#include "commandparser.h" +#include "openssllicense.h" +#include "sisregistry.h" +#include "parameterlist.h" +#include "is_utils.h" +#include "stringutils.h" + +// Global/static variables +CCommandParser::WarnMap CCommandParser::KString2Warning; + + +CCommandParser::CCommandParser(): + iWarnLevel( WARN_WARN ) + { + } + +CCommandParser::~CCommandParser() + { + } + +void CCommandParser::DisplayError( int aError ) + { + const wchar_t* msg; + // + switch( aError ) + { + case ECmdLineUnknownOption: + msg = L"Unknown option specified"; + break; + case ECmdLineMissingParamFile: + msg = L"Can't open the parameter file specified"; + break; + case ECmdLineNoDirArgument: + msg = L"No directory(s) specified"; + break; + case ECmdLineNoSisArgument: + msg = L"No SIS file(s) specified"; + break; + case ECmdLineNoRomRofsLogsArgument: + msg = L"No ROM/ROFS[BUILD] log file(s) specified"; + break; + case ECmdLineNoConfigFileArgument: + msg = L"No configuration file specified"; + break; + case ECmdLineNoSisStubPathArgument: + msg = L"No SIS stub directory specified"; + break; + case ECmdLineMissingParams: + msg = L"Missing parameters"; + break; + case ECmdLineInvalidLanguage: + msg = L"Invalid language code"; + break; + case ECmdLineMissingPackageUID: + msg = L"Package UID not found"; + break; + default: + msg = L"Unknown error"; + break; + } + // + LERROR(msg << std::endl); + DisplayUsage(); + } + +void CCommandParser::DisplayOpenSSLCopyright() + { + //displays OpenSSL copyright notice. + for (int index = 0; index < (sizeof(openSSLLicenseString)/sizeof(openSSLLicenseString[0])); ++index) + { + std::cout << openSSLLicenseString [index] << std::endl; + } + } + +void CCommandParser::DisplayUsage() + { + DisplayVersion(); + + std::cout + #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK + << "Usage: " << CommandName () << " [-z dir] [-c dir] [-e] [-f] [-k [4.0 | 5.0 | 5.1 | 5.2 | 5.3 | 5.4]]\n" + #else + << "Usage: " << CommandName () << " [-z dir] [-c dir] [-e] [-k [4.0 | 5.0 | 5.1 | 5.2 | 5.3 | 5.4]]\n" + #endif + << "\t\t[-s [sisfile | dir] [+drive [+mcard | +mcardnr | +mcardalone | +mcardalonenr] [+sucert]]] [-s ...]\n" + << "\t\t[-p param_file] [-d drive] [-r rofsbuild_log_file1,rofsbuild_log_file2,...]\n" + << "\t\t[-t romstubdir] [-n language_code] [-i config_file] \n" + << "\t\t[-x pkgUID[,pkgUID2,...]] [-w [off | error | warn | info]] [-l logfile]\n\n" + << "Where:\t-h\t\tDisplays help\n" + << "\t-c\t\tThe directory representing the system drive on the device\n" + << "\t-d\t\tThe system drive letter [default to 'C']\n" + << "\t-e\t\tDisable eclipsing and SID checks using Z drive \n" + << "\t \t\t-z or -r not required when this option used \n" + #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK + << "\t-f\t\tUsed to specify that origin of a component has not been verified during installation.\n" + << "\t\t\tBy default the origin is verified. This option should not be provided along with registry version information.\n" + #endif + + << "\t-i\t\tConfig file with HAL attribute values for installation \n"; + std::cout + #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK + << "\t-k\t\tSIS Registry version to generate (default is to generate the db related registry entry) \n" + #else + << "\t-k\t\tSIS Registry version to generate (default v" << SisRegistry::KSisRegistryMajorVersion + << "." << SisRegistry::KSisRegistryMinorVersion << ") \n" + #endif //SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK + << "\t-l\t\tThe file to write diagnostics to (stderr by default)\n" + << "\t-n\t\tLanguage code - decimal number as defined in TLanguage enum\n" + << "\t-o\t\tOutput licence information\n" + << "\t-p\t\tA file to take additional parameters from.\n" + << "\t \t\tCommand line args after the file will override the file contents\n" + << "\t-r\t\tList of rom/rofs build log files; should not use with -z option or\n" + << "\t \t\tdefine the Z drive in the config file\n" + << "\t-s\t\tThe SIS file(s) to install. Any directory passed in will be searched\n" + << "\t\t\tfor SIS files; should not use with -x option\n" + + << "\t-t\t\tROM Stub sis files directory, must be used with -r option\n" + << "\t-v\t\tDisplays the version of the tool\n" + << "\t-w\t\tThe level of diagnostics to display- WARN, ERROR, INFO, OFF\n" + << "\t \t\t(warn by default)\n" + + << "\t-x\t\tRemove the files installed of a package; should not use with -s option\n" + << "\t-z\t\tThe directory representing the Z: drive on the device\n" + << "\tpkgUID\t\tThe installed package UID either in Hex or Decimal format (e.g. 0x12345678, 305419896)\n" + << "\tsisfile\t\tThe SIS file to be installed\n" + << "\tdir\t\tThe directory that contains the installing SIS files\n" + << "\tdrive\t\tThe drive letter on the device\n" + << "\tmcard\t\tOption to generate the stub SIS file for the installing package\n" + << "\tmcardnr\t\tOption to generate the non-removable stub SIS file for the installing package\n" + << "\tmcardalone\tOption to just create a pre-installed package to the media card\n" + << "\tmcardalonenr\tOption to generate the non-removable stub SIS file for the installing" << std::endl + << "\t\t\tpackage without generating the SISregistry entry\n" + << "\tsucert\t\tTo indicate that the SIS file has been signed with a SU certificate\n\n"; + } + +void CCommandParser::DisplayVersion() + { + std::cout << "\nINTERPRETSIS " << " Version 2.1.2 ." << std::endl; + std::cout << "Copyright (c) 2009 Symbian Software Ltd. All rights reserved.\n " << std::endl; + } + + +CParameterList* CCommandParser::ParseOptions(int argc, const char**argv) + { + CParameterList* paramList = new CParameterList(); + bool bAbort = ParseParam(argc, argv, paramList); + if(bAbort) + { + delete paramList; + paramList = NULL; + } + return paramList; + } +bool CCommandParser::ParseParam(int argc, const char**argv, CParameterList* aParamList) + { + if (argc < 2) + { + throw CCommandParser::ECmdLineUnknownOption; + } + + bool bContinue = true; + + while ((--argc > 0) && bContinue) + { + ++argv; + if (**argv != '-') + { + continue; + } + + bool err = false; + const char* optPtr = *argv; + + switch (toupper(*++optPtr)) + { + case 'C': + { + if (argc <= 1) + throw CCommandParser::ECmdLineNoDirArgument; + + --argc; + aParamList->SetSystemDrive(*(++argv)); + break; + } + case 'D': + { + --argc; + wchar_t buf[2048]; + ConvertMultiByteToWideChar(*++argv,-1, buf, 2048); + aParamList->SetSystemDriveLetter(tolower(buf[0])); + break; + } + case 'E': + { + aParamList->SetFlag(CParameterList::EFlagsDisableZDriveChecksSet); + break; + } + #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK + case 'F': + { + aParamList->SetOriginVerificationStatus(false); + break; + } + #endif + case 'H': + case '?': + { + DisplayUsage(); + bContinue = false; + break; + } + case 'I': + { + if (argc <= 1) + throw CCommandParser::ECmdLineNoConfigFileArgument; + + --argc; + aParamList->SetConfigFile(*(++argv)); + break; + } + case 'K': + { + // Last command + if (argc == 1) + { + aParamList->SetSisRegistryVersion(SisRegistry::KRegistryV40string); + } + else + { + // Check that the next arg is valid + std::string versionStr = *(++argv); + + if (**argv == '-') + { + aParamList->SetSisRegistryVersion(SisRegistry::KRegistryV40string); + --argv; + } + else + { + --argc; + aParamList->SetSisRegistryVersion(versionStr); + } + } + break; + } + case 'L': + { + if (argc > 1) + { + --argc; + wchar_t buf[2048]; + ConvertMultiByteToWideChar(*++argv,-1, buf, 2048); + iLogFile = buf; + } + break; + } + case 'N': + { + if (argc <= 1) + throw CCommandParser::ECmdLineInvalidLanguage; + + --argc; + aParamList->SetLanguage(static_cast< CSISLanguage::TLanguage >( String2Language( *(++argv) ) )); + break; + } + case 'O': + { + DisplayOpenSSLCopyright(); + bContinue = false; + break; + } + case 'P': + { + if (!(err = argc <= 1)) + { + --argc; + std::string paramFile = *(++argv); + ParseParam(argc, paramFile, aParamList); + } + break; + } + case 'R': + { + if (argc <= 1) + throw CCommandParser::ECmdLineNoRomRofsLogsArgument; + + --argc; + aParamList->EmptyRomLogFiles(); +#ifdef _MSC_VER + FilePtr funtionPtr = aParamList->AddRomLogFile; +#else + FilePtr funtionPtr = &(aParamList->AddRomLogFile); +#endif // _MSC_VER + String2List(*aParamList, funtionPtr, *(++argv) ); + break; + } + case 'S': + { + if (argc <= 1) + throw CCommandParser::ECmdLineNoSisArgument; + + --argc; + + String2SISFileList(*aParamList, argc, ++argv); + break; + } + case 'T': + { + if (argc <= 1) + throw CCommandParser::ECmdLineNoSisStubPathArgument; + + --argc; + aParamList->SetStubDir(*(++argv)); + break; + } + case 'V': + { + DisplayVersion(); + bContinue = false; + break; + } + case 'W': + { + --argc; + iWarnLevel = String2Warn(*(++argv)); + break; + } + case 'X': + { + if (argc <= 1) + throw CCommandParser::ECmdLineMissingPackageUID; + + --argc; + aParamList->EmptyPkgUids(); +#ifdef _MSC_VER + FilePtr funtionPtr = (aParamList->AddPkgUid); +#else + FilePtr funtionPtr = &(aParamList->AddPkgUid); +#endif // _MSC_VER + String2List(*aParamList, funtionPtr, *(++argv) ); + break; + } + case 'Z': + { + if (argc <= 1) + throw CCommandParser::ECmdLineNoDirArgument; + + --argc; + aParamList->SetZDrive(*(++argv)); + break; + } + default: + { + LERROR(Utf8ToUcs2(std::string(optPtr))); + throw CCommandParser::ECmdLineUnknownOption; + } + } + + if (err) + { + throw CCommandParser::ECmdLineUnknownOption; + } + } // Finished parsing all the command line options + + return !bContinue; + } + + +void CCommandParser::ParseParam(int argc, const std::string& paramFile, CParameterList* aParamList) + { + if (paramFile.size() > 0) + { + std::ifstream params; + params.open(paramFile.c_str(), std::ios::in); + + if (!params.good()) + { + throw CCommandParser::ECmdLineMissingParamFile; + } + + std::vector tokens; + argc = 0; + while (params.good()) + { + std::string token; + params >> token; + if(token != "") + { + argc++; + tokens.push_back(token); + } + } + + const char** newArgv = new const char*[tokens.size()+1]; + for (int i = 0 ; i < tokens.size() ; ++i) + { + newArgv[i+1] = tokens[i].c_str(); + } + + ParseParam(argc+1, newArgv, aParamList); + delete [] newArgv; + params.close(); + } + } + +void CCommandParser::String2List(CParameterList& aParamList, FilePtr& aFilePtr, const std::string& aOptionsString) + { + std::string::const_iterator it = aOptionsString.begin(); + std::string::const_iterator end = aOptionsString.end(); + std::string::const_iterator currentPos = it; + // + while (currentPos != end) + { + currentPos = std::find(it, end, ','); + std::wstring x; + Utf8ToUcs2(std::string(it,(currentPos-it)), x); + //aOptionsList.push_back(x); + (aParamList.*aFilePtr)(x); + + if (currentPos == end) + { + return; + } + + it = currentPos; + ++it; + } + } + +void CCommandParser::String2SISFileList(CParameterList& aParamList, int aArgc, const char**aArgv) + { + std::string sisFileOption(*aArgv); + + std::string::const_iterator it = sisFileOption.begin(); + std::string::const_iterator end = sisFileOption.end(); + std::string::const_iterator currentPos = it; + + currentPos = std::find(it, end, ','); + + while (currentPos != end) + { + currentPos = std::find(it, end, ','); + std::wstring x; + Utf8ToUcs2(std::string(it,(currentPos-it)), x); + + InstallSISFile sisFileName(x, '$', false); + aParamList.AddSISFile(sisFileName); + + if (currentPos == end) + { + return; + } + + it = currentPos; + ++it; + } + + // At this stage, aArgv could be something like: file.sis +e +mcard +sucert + // As the sisfile attributes are predetermined input, therefore we can just + // parse according to the predetermined inputs. + + std::wstring fileName; + Utf8ToUcs2(sisFileOption, fileName); + + InstallSISFile sisFileName(fileName, '$', false); + + while (--aArgc > 0) + { // Process associated SIS file attributes + ++aArgv; + + if (**aArgv == '-') + { // No more attribute to process + aParamList.AddSISFile(sisFileName); + + --aArgv; + ++aArgc; + return; + } + + if (**aArgv == '+') + { + std::string versionStr; + + // Check that the next arg is valid + versionStr = *(aArgv); + + if (versionStr.size() == 2) + { + // Found the associated SIS file drive; e.g. +e + const char* optPtr = *aArgv; + + char drive = tolower(*++optPtr); + + if (drive < 'a' || drive > 'y') + throw CCommandParser::ECmdLineInvalidSISFileAttribute; + + // Set target drive + sisFileName.iTargetDrive = drive; + + continue; + } + + versionStr = StringUtils::ToUpper( versionStr ); + + if (versionStr == "+MCARD") + { + sisFileName.iGenerateStub = true; + } + else if (versionStr == "+MCARDNR") + { + sisFileName.iGenerateStub = true; + sisFileName.iNonRemovable = true; + } + else if (versionStr == "+MCARDALONE") + { + sisFileName.iGenerateStub = true; + sisFileName.iNotRegister = true; + } + else if (versionStr == "+MCARDALONENR") + { + sisFileName.iGenerateStub = true; + sisFileName.iNotRegister = true; + sisFileName.iNonRemovable = true; + } + else if (versionStr == "+SUCERT") + { + sisFileName.iSUFlag = true; + } + else + throw CCommandParser::ECmdLineInvalidSISFileAttribute; + } + else + { + throw CCommandParser::ECmdLineInvalidSISFileAttribute; + } + } + aParamList.AddSISFile(sisFileName); + } + + +WarnLevel CCommandParser::String2Warn(const std::string& level) + { + std::string l(level); + std::transform(l.begin(),l.end(),l.begin(), toupper); + // + if (KString2Warning.size() == 0) + { + KString2Warning["OFF"] = WARN_OFF; + KString2Warning["WARN"] = WARN_WARN; + KString2Warning["ERROR"] = WARN_ERROR; + KString2Warning["INFO"] = WARN_INFO; + } + // + WarnMap::const_iterator result = KString2Warning.find(l); + if (result == KString2Warning.end()) + { + throw CCommandParser::ECmdLineUnknownOption; + } + // + return result->second; + } + + +int CCommandParser::String2Language( const std::string& aLanguage ) + { + std::istringstream stringStream( aLanguage ); + int language = 1; + // + if ( stringStream >> language ) + { + } + else + { + throw CCommandParser::ECmdLineInvalidLanguage; + } + // + return language; + }