secureswitools/swisistools/source/interpretsis/commandparser.cpp
changeset 0 ba25891c3a9e
child 12 7ca52d38f8c3
--- /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;
+    }