--- /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 <iosfwd>
+#include <sstream>
+#include <iostream>
+#include <fstream>
+#include <algorithm>
+
+#ifndef __TOOLS2_LINUX__
+#include <windows.h>
+#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<std::string> 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;
+ }