srcanamdw/appdep/src/appdep_sisfiles.cpp
changeset 0 509e4801c378
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/srcanamdw/appdep/src/appdep_sisfiles.cpp	Sat Jan 09 10:04:12 2010 +0530
@@ -0,0 +1,324 @@
+/*
+* Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "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:  Handling of sis files 
+*
+*/
+
+
+#include "appdep.hpp"
+
+// ----------------------------------------------------------------------------------------------------------
+// Note that in C/C++ code \ has been replaced with \\ and " with \".
+// ----------------------------------------------------------------------------------------------------------
+
+void DoInitialChecksAndPreparationsForSisFiles()
+{
+    // specify full location for dumpsis
+    _dumpsis_location = _cl_releasedir + DUMPSIS_LOCATION;
+
+    // check if dumpsis can be found
+ 	if (!FileExists(_dumpsis_location))
+	{
+		cerr << "ERROR: Unable to find " + _dumpsis_location << ", check -release param" << endl;
+		cerr << "Please notice that this feature is available only in Symbian OS 9.x" << endl;
+		cerr << "It is possible the user to copy dumpsis.exe from some other release under" << endl;
+		cerr << "this release to support this feature." << endl;
+		exit(EXIT_DUMPSIS_NOT_FOUND);
+	}         
+
+    // insert quotes to the dumpsis location to avoid any problems caused by white spaces
+    InsertQuotesToFilePath(_dumpsis_location);
+
+    // parse commandline argument "sisfiles" from sisfile;sisfile;...
+    int last_found_semicolon_pos = -1;
+    for (unsigned int i=0; i<_cl_sisfiles.length(); i++)
+    {   
+        // try to find ';' characters 
+        string::size_type semicolon_pos = _cl_sisfiles.find(";", i);
+        
+        if (semicolon_pos == string::npos)
+        {
+            // could not find the ';' character, append last part of the list
+            string sis_file = _cl_sisfiles.substr(last_found_semicolon_pos+1,_cl_sisfiles.length()-last_found_semicolon_pos-1);
+            _sisfiles.push_back(sis_file);
+            break;
+        }
+        else
+        {
+            // found a ';' character, append to the list, but needs to check if there are more
+            string sis_file = _cl_sisfiles.substr(last_found_semicolon_pos+1, semicolon_pos-last_found_semicolon_pos-1);
+            
+            if (sis_file.length() > 0)
+                _sisfiles.push_back(sis_file);
+            
+            last_found_semicolon_pos = semicolon_pos;
+            i = last_found_semicolon_pos;
+        }    
+    }
+
+    // check that all given sisfiles can be found and it is supported
+    for (unsigned int i=0; i<_sisfiles.size(); i++)
+    { 
+        // report an error if the file does not exist
+        if (!FileExists(_sisfiles.at(i)))
+        {
+     		cerr << "ERROR: Unable to find " + _sisfiles.at(i) << ", check -sisfiles parameter" << endl;
+    		exit(EXIT_SIS_FILE_NOT_FOUND);           
+        }
+        
+        // open the sis file for reading to check if it is supported    
+        ifstream sisf(_sisfiles.at(i).c_str(), ios::binary);
+		if (sisf.is_open())
+		{
+            int c1, c2, c3, c4;
+            c1 = sisf.get();
+            c2 = sisf.get();
+            c3 = sisf.get();
+            c4 = sisf.get();
+            
+            // in valid sis first four bytes of the file are 7A1A2010
+            if (c1==0x7A && c2==0x1A && c3==0x20 && c4==0x10)
+            {
+                //cerr << _sisfiles.at(i) << " is supported" << endl;
+            }
+            else
+            {
+                // if starting from offset 8, four next bytes are 19040010, the file is
+                // unsupported SIS file used in previous Symbian OS releases.    
+                sisf.seekg(8, ios::beg);
+                c1 = sisf.get();
+                c2 = sisf.get();
+                c3 = sisf.get();
+                c4 = sisf.get();
+                sisf.close();
+
+                if (c1==0x19 && c2==0x04 && c3==0x00 && c4==0x10)
+                {
+                    cerr << "ERROR: " + _sisfiles.at(i) << " is a pre-Symbian OS 9.x" << endl;
+                    cerr << "sisfile which is not supported, check -sisfiles parameter" << endl;
+                    exit(EXIT_SIS_FILE_NOT_SUPPORTED); 
+                }
+                else
+                {
+                    cerr << "ERROR: " + _sisfiles.at(i) << " is not a valid sis file," << endl;
+                    cerr << "check -sisfiles parameter" << endl;
+                    exit(EXIT_NOT_SIS_FILE);                     
+                }
+            }    
+            sisf.close();
+        }
+        else
+        {
+     		cerr << "ERROR: Cannot open " + _sisfiles.at(i) << " for reading, check -sisfiles parameter" << endl;
+    		exit(EXIT_SIS_FILE_CANNOT_OPEN_FOR_READING); 
+        }
+    }    
+}
+
+// ----------------------------------------------------------------------------------------------------------
+
+void AnalyseSisFiles()
+{
+    // create a new target and set some defaults
+    target sis_target;
+    sis_target.name = "sis";
+    sis_target.cache_dir = _cl_cachedir + sis_target.name + DIR_SEPARATOR;
+    sis_target.dep_cache_path = sis_target.cache_dir + CACHE_DEP_FILENAME;
+
+    cerr << "Analysing sis files..." << endl;
+
+    // define path to a temp directory where dumpsis will extract the files    
+    const string tempdir = _cl_cachedir + SIS_TEMP_DIR + DIR_SEPARATOR;
+    const string tempdir2 = _cl_cachedir + SIS_TEMP_DIR;
+
+    // do analysis for each file
+    for (unsigned int i=0; i<_sisfiles.size(); i++)
+    { 
+        // create the temporary directory
+        MkDirAll(tempdir);
+
+        cerr << "Binaries in " << _sisfiles.at(i) << " are:" << endl;
+        
+        // due to bugginess of a specific version of dumpsis, we need to copy the source file under the temporary directory
+        const string new_sis_loc = tempdir + "tempsis.sis";
+        
+        ifstream src_sis_f(_sisfiles.at(i).c_str(), ios::binary);
+        if (src_sis_f.is_open())
+		{
+            ofstream trgt_sis_f(new_sis_loc.c_str(), ios::binary);
+            if (trgt_sis_f.is_open())
+    		{
+                // read all bytes from source and write to the target
+                int c1;
+
+                while(!src_sis_f.eof())
+                {
+                    c1 = src_sis_f.get();
+                    trgt_sis_f.put(c1);
+                }
+                
+                trgt_sis_f.close();            
+            
+            }
+            else
+            {
+         		cerr << "ERROR: Cannot open " + new_sis_loc << " for writing, check write permissions" << endl;
+        		exit(EXIT_TEMP_SIS_FILE_CANNOT_OPEN_FOR_WRITING); 
+            }             
+
+            src_sis_f.close();
+                        
+        }
+        else
+        {
+     		cerr << "ERROR: Cannot open " + _sisfiles.at(i) << " for reading, check -sisfiles parameter" << endl;
+    		exit(EXIT_SIS_FILE_CANNOT_OPEN_FOR_READING); 
+        }        
+        
+        
+
+        // execute dumpsis        
+        string cmd = _dumpsis_location + " -x -d \"" + tempdir2 + "\" \"" + new_sis_loc + "\" " + CERR_TO_NULL;
+        
+        vector<string> tempVector;
+        ExecuteCommand(cmd, tempVector);
+        
+       
+        // check if pkg file found
+        string pkgfile_location = tempdir + "tempsis.pkg";
+        
+        if (!FileExists(pkgfile_location))
+        {
+            // try again with an alternative
+            pkgfile_location = tempdir + "tempsis.sis.pkg";
+
+            if (!FileExists(pkgfile_location))
+            {
+         		RemoveDirectoryWithAllFiles(tempdir);
+                cerr << "ERROR: Dumpsis failed for " << _sisfiles.at(i) << " since it does not contain a pkg file, check -sisfiles parameter" << endl;
+        		exit(EXIT_NO_PKG_FILE_FOUND); 
+            }            
+        }
+
+        // open the pkg file for reading
+        ifstream pkgf(pkgfile_location.c_str(), ios::binary);
+		if (pkgf.is_open())
+		{
+            int c1, c2;
+            c1 = pkgf.get();
+            c2 = pkgf.get();
+            
+            // we only support unicode format
+            if (c1 == 0xFF && c2 == 0xFE)
+            {
+                string line;
+
+                 // read more chars
+                 while(!pkgf.eof())
+                 {
+                    c1 = pkgf.get();
+                    c2 = pkgf.get();
+                    
+                 //   if (c1 == 0x0D && c2 == 0x00)  // new line marker #1
+                  //  {
+                      //  c1 = pkgf.get();
+                      //  c2 = pkgf.get();                        
+
+                        if (c1 == 0x0A && c2 == 0x00)  // new line marker #2
+                        {
+                            // full line is now available, parse it
+                                                        
+                            boost::regex re1("^\\\"(.+)\\\"-\\\".*\\\\(\\S+)\\\",.*$");
+                            boost::cmatch matches1;                
+                            if (boost::regex_match(line.c_str(), matches1, re1))
+                            {
+                                // match found
+                                string ms1(matches1[1].first, matches1[1].second); // source name
+                                string ms2(matches1[2].first, matches1[2].second); // target name
+                                
+                                binary_info b_info;
+                                b_info.directory = tempdir;
+                                b_info.filename = ms1;
+
+                                GetImportTableWithPetran(_petran_location, b_info);
+                                
+                                // make sure that Petran succeeded for this file since we don't do any file
+                                // extension checks when parsering the file
+                                if (b_info.binary_format != UNKNOWN)
+                                {
+                                    // print name of the destination binary
+                                    cerr << ms2 << endl;
+                                
+                                    b_info.directory = "";
+                                    b_info.filename = ms2;
+    
+                                    // get statistics of the file and set the modification time
+                                    struct stat stat_p;
+                                    stat((tempdir + ms1).c_str(), &stat_p);
+                                    b_info.mod_time = stat_p.st_mtime;
+                                    
+                                    // create a new entry to list of binary files
+                                    sis_target.binaries.push_back( b_info );                                      
+                                }
+                                              
+                            }
+                            
+                            // clear the buffer since we start scanning another line
+                            line = "";
+                        }                        
+                    //}
+                    else
+                    {
+                        char c(c1);  // simple unicode to ascii conversion, just ignore c2
+                        line += c;  // append the char to end of the line      
+                    }    
+                 }       
+            }
+            else
+            {
+                pkgf.close();
+                RemoveDirectoryWithAllFiles(tempdir);
+                cerr << "ERROR: Pkg file " + pkgfile_location << " is not supported, check -sisfiles parameter" << endl;
+                exit(EXIT_PKG_FILE_CANNOT_OPEN_FOR_READING); 
+            } 
+        
+        }
+        else
+        {
+      		RemoveDirectoryWithAllFiles(tempdir);
+     		cerr << "ERROR: Cannot open " + pkgfile_location << " for reading, check -sisfiles parameter" << endl;
+    		exit(EXIT_PKG_FILE_CANNOT_OPEN_FOR_READING); 
+        }                
+
+        // close handles and clear any temp files        
+        pkgf.close();
+        RemoveDirectoryWithAllFiles(tempdir);
+    }    
+
+    // make sure that the cache directory exists
+    MkDirAll(sis_target.cache_dir); 
+        
+    // write the dependencies cache of the sis files
+    WriteDataToDependenciesCacheFile(sis_target);
+    
+    // append to targets
+    _targets.push_back(sis_target);
+    
+    cerr << endl;
+
+}
+
+// ----------------------------------------------------------------------------------------------------------
+    
+