srcanamdw/appdep/src/appdep_sisfiles.cpp
changeset 0 509e4801c378
equal deleted inserted replaced
-1:000000000000 0:509e4801c378
       
     1 /*
       
     2 * Copyright (c) 2007 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 "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:  Handling of sis files 
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "appdep.hpp"
       
    20 
       
    21 // ----------------------------------------------------------------------------------------------------------
       
    22 // Note that in C/C++ code \ has been replaced with \\ and " with \".
       
    23 // ----------------------------------------------------------------------------------------------------------
       
    24 
       
    25 void DoInitialChecksAndPreparationsForSisFiles()
       
    26 {
       
    27     // specify full location for dumpsis
       
    28     _dumpsis_location = _cl_releasedir + DUMPSIS_LOCATION;
       
    29 
       
    30     // check if dumpsis can be found
       
    31  	if (!FileExists(_dumpsis_location))
       
    32 	{
       
    33 		cerr << "ERROR: Unable to find " + _dumpsis_location << ", check -release param" << endl;
       
    34 		cerr << "Please notice that this feature is available only in Symbian OS 9.x" << endl;
       
    35 		cerr << "It is possible the user to copy dumpsis.exe from some other release under" << endl;
       
    36 		cerr << "this release to support this feature." << endl;
       
    37 		exit(EXIT_DUMPSIS_NOT_FOUND);
       
    38 	}         
       
    39 
       
    40     // insert quotes to the dumpsis location to avoid any problems caused by white spaces
       
    41     InsertQuotesToFilePath(_dumpsis_location);
       
    42 
       
    43     // parse commandline argument "sisfiles" from sisfile;sisfile;...
       
    44     int last_found_semicolon_pos = -1;
       
    45     for (unsigned int i=0; i<_cl_sisfiles.length(); i++)
       
    46     {   
       
    47         // try to find ';' characters 
       
    48         string::size_type semicolon_pos = _cl_sisfiles.find(";", i);
       
    49         
       
    50         if (semicolon_pos == string::npos)
       
    51         {
       
    52             // could not find the ';' character, append last part of the list
       
    53             string sis_file = _cl_sisfiles.substr(last_found_semicolon_pos+1,_cl_sisfiles.length()-last_found_semicolon_pos-1);
       
    54             _sisfiles.push_back(sis_file);
       
    55             break;
       
    56         }
       
    57         else
       
    58         {
       
    59             // found a ';' character, append to the list, but needs to check if there are more
       
    60             string sis_file = _cl_sisfiles.substr(last_found_semicolon_pos+1, semicolon_pos-last_found_semicolon_pos-1);
       
    61             
       
    62             if (sis_file.length() > 0)
       
    63                 _sisfiles.push_back(sis_file);
       
    64             
       
    65             last_found_semicolon_pos = semicolon_pos;
       
    66             i = last_found_semicolon_pos;
       
    67         }    
       
    68     }
       
    69 
       
    70     // check that all given sisfiles can be found and it is supported
       
    71     for (unsigned int i=0; i<_sisfiles.size(); i++)
       
    72     { 
       
    73         // report an error if the file does not exist
       
    74         if (!FileExists(_sisfiles.at(i)))
       
    75         {
       
    76      		cerr << "ERROR: Unable to find " + _sisfiles.at(i) << ", check -sisfiles parameter" << endl;
       
    77     		exit(EXIT_SIS_FILE_NOT_FOUND);           
       
    78         }
       
    79         
       
    80         // open the sis file for reading to check if it is supported    
       
    81         ifstream sisf(_sisfiles.at(i).c_str(), ios::binary);
       
    82 		if (sisf.is_open())
       
    83 		{
       
    84             int c1, c2, c3, c4;
       
    85             c1 = sisf.get();
       
    86             c2 = sisf.get();
       
    87             c3 = sisf.get();
       
    88             c4 = sisf.get();
       
    89             
       
    90             // in valid sis first four bytes of the file are 7A1A2010
       
    91             if (c1==0x7A && c2==0x1A && c3==0x20 && c4==0x10)
       
    92             {
       
    93                 //cerr << _sisfiles.at(i) << " is supported" << endl;
       
    94             }
       
    95             else
       
    96             {
       
    97                 // if starting from offset 8, four next bytes are 19040010, the file is
       
    98                 // unsupported SIS file used in previous Symbian OS releases.    
       
    99                 sisf.seekg(8, ios::beg);
       
   100                 c1 = sisf.get();
       
   101                 c2 = sisf.get();
       
   102                 c3 = sisf.get();
       
   103                 c4 = sisf.get();
       
   104                 sisf.close();
       
   105 
       
   106                 if (c1==0x19 && c2==0x04 && c3==0x00 && c4==0x10)
       
   107                 {
       
   108                     cerr << "ERROR: " + _sisfiles.at(i) << " is a pre-Symbian OS 9.x" << endl;
       
   109                     cerr << "sisfile which is not supported, check -sisfiles parameter" << endl;
       
   110                     exit(EXIT_SIS_FILE_NOT_SUPPORTED); 
       
   111                 }
       
   112                 else
       
   113                 {
       
   114                     cerr << "ERROR: " + _sisfiles.at(i) << " is not a valid sis file," << endl;
       
   115                     cerr << "check -sisfiles parameter" << endl;
       
   116                     exit(EXIT_NOT_SIS_FILE);                     
       
   117                 }
       
   118             }    
       
   119             sisf.close();
       
   120         }
       
   121         else
       
   122         {
       
   123      		cerr << "ERROR: Cannot open " + _sisfiles.at(i) << " for reading, check -sisfiles parameter" << endl;
       
   124     		exit(EXIT_SIS_FILE_CANNOT_OPEN_FOR_READING); 
       
   125         }
       
   126     }    
       
   127 }
       
   128 
       
   129 // ----------------------------------------------------------------------------------------------------------
       
   130 
       
   131 void AnalyseSisFiles()
       
   132 {
       
   133     // create a new target and set some defaults
       
   134     target sis_target;
       
   135     sis_target.name = "sis";
       
   136     sis_target.cache_dir = _cl_cachedir + sis_target.name + DIR_SEPARATOR;
       
   137     sis_target.dep_cache_path = sis_target.cache_dir + CACHE_DEP_FILENAME;
       
   138 
       
   139     cerr << "Analysing sis files..." << endl;
       
   140 
       
   141     // define path to a temp directory where dumpsis will extract the files    
       
   142     const string tempdir = _cl_cachedir + SIS_TEMP_DIR + DIR_SEPARATOR;
       
   143     const string tempdir2 = _cl_cachedir + SIS_TEMP_DIR;
       
   144 
       
   145     // do analysis for each file
       
   146     for (unsigned int i=0; i<_sisfiles.size(); i++)
       
   147     { 
       
   148         // create the temporary directory
       
   149         MkDirAll(tempdir);
       
   150 
       
   151         cerr << "Binaries in " << _sisfiles.at(i) << " are:" << endl;
       
   152         
       
   153         // due to bugginess of a specific version of dumpsis, we need to copy the source file under the temporary directory
       
   154         const string new_sis_loc = tempdir + "tempsis.sis";
       
   155         
       
   156         ifstream src_sis_f(_sisfiles.at(i).c_str(), ios::binary);
       
   157         if (src_sis_f.is_open())
       
   158 		{
       
   159             ofstream trgt_sis_f(new_sis_loc.c_str(), ios::binary);
       
   160             if (trgt_sis_f.is_open())
       
   161     		{
       
   162                 // read all bytes from source and write to the target
       
   163                 int c1;
       
   164 
       
   165                 while(!src_sis_f.eof())
       
   166                 {
       
   167                     c1 = src_sis_f.get();
       
   168                     trgt_sis_f.put(c1);
       
   169                 }
       
   170                 
       
   171                 trgt_sis_f.close();            
       
   172             
       
   173             }
       
   174             else
       
   175             {
       
   176          		cerr << "ERROR: Cannot open " + new_sis_loc << " for writing, check write permissions" << endl;
       
   177         		exit(EXIT_TEMP_SIS_FILE_CANNOT_OPEN_FOR_WRITING); 
       
   178             }             
       
   179 
       
   180             src_sis_f.close();
       
   181                         
       
   182         }
       
   183         else
       
   184         {
       
   185      		cerr << "ERROR: Cannot open " + _sisfiles.at(i) << " for reading, check -sisfiles parameter" << endl;
       
   186     		exit(EXIT_SIS_FILE_CANNOT_OPEN_FOR_READING); 
       
   187         }        
       
   188         
       
   189         
       
   190 
       
   191         // execute dumpsis        
       
   192         string cmd = _dumpsis_location + " -x -d \"" + tempdir2 + "\" \"" + new_sis_loc + "\" " + CERR_TO_NULL;
       
   193         
       
   194         vector<string> tempVector;
       
   195         ExecuteCommand(cmd, tempVector);
       
   196         
       
   197        
       
   198         // check if pkg file found
       
   199         string pkgfile_location = tempdir + "tempsis.pkg";
       
   200         
       
   201         if (!FileExists(pkgfile_location))
       
   202         {
       
   203             // try again with an alternative
       
   204             pkgfile_location = tempdir + "tempsis.sis.pkg";
       
   205 
       
   206             if (!FileExists(pkgfile_location))
       
   207             {
       
   208          		RemoveDirectoryWithAllFiles(tempdir);
       
   209                 cerr << "ERROR: Dumpsis failed for " << _sisfiles.at(i) << " since it does not contain a pkg file, check -sisfiles parameter" << endl;
       
   210         		exit(EXIT_NO_PKG_FILE_FOUND); 
       
   211             }            
       
   212         }
       
   213 
       
   214         // open the pkg file for reading
       
   215         ifstream pkgf(pkgfile_location.c_str(), ios::binary);
       
   216 		if (pkgf.is_open())
       
   217 		{
       
   218             int c1, c2;
       
   219             c1 = pkgf.get();
       
   220             c2 = pkgf.get();
       
   221             
       
   222             // we only support unicode format
       
   223             if (c1 == 0xFF && c2 == 0xFE)
       
   224             {
       
   225                 string line;
       
   226 
       
   227                  // read more chars
       
   228                  while(!pkgf.eof())
       
   229                  {
       
   230                     c1 = pkgf.get();
       
   231                     c2 = pkgf.get();
       
   232                     
       
   233                  //   if (c1 == 0x0D && c2 == 0x00)  // new line marker #1
       
   234                   //  {
       
   235                       //  c1 = pkgf.get();
       
   236                       //  c2 = pkgf.get();                        
       
   237 
       
   238                         if (c1 == 0x0A && c2 == 0x00)  // new line marker #2
       
   239                         {
       
   240                             // full line is now available, parse it
       
   241                                                         
       
   242                             boost::regex re1("^\\\"(.+)\\\"-\\\".*\\\\(\\S+)\\\",.*$");
       
   243                             boost::cmatch matches1;                
       
   244                             if (boost::regex_match(line.c_str(), matches1, re1))
       
   245                             {
       
   246                                 // match found
       
   247                                 string ms1(matches1[1].first, matches1[1].second); // source name
       
   248                                 string ms2(matches1[2].first, matches1[2].second); // target name
       
   249                                 
       
   250                                 binary_info b_info;
       
   251                                 b_info.directory = tempdir;
       
   252                                 b_info.filename = ms1;
       
   253 
       
   254                                 GetImportTableWithPetran(_petran_location, b_info);
       
   255                                 
       
   256                                 // make sure that Petran succeeded for this file since we don't do any file
       
   257                                 // extension checks when parsering the file
       
   258                                 if (b_info.binary_format != UNKNOWN)
       
   259                                 {
       
   260                                     // print name of the destination binary
       
   261                                     cerr << ms2 << endl;
       
   262                                 
       
   263                                     b_info.directory = "";
       
   264                                     b_info.filename = ms2;
       
   265     
       
   266                                     // get statistics of the file and set the modification time
       
   267                                     struct stat stat_p;
       
   268                                     stat((tempdir + ms1).c_str(), &stat_p);
       
   269                                     b_info.mod_time = stat_p.st_mtime;
       
   270                                     
       
   271                                     // create a new entry to list of binary files
       
   272                                     sis_target.binaries.push_back( b_info );                                      
       
   273                                 }
       
   274                                               
       
   275                             }
       
   276                             
       
   277                             // clear the buffer since we start scanning another line
       
   278                             line = "";
       
   279                         }                        
       
   280                     //}
       
   281                     else
       
   282                     {
       
   283                         char c(c1);  // simple unicode to ascii conversion, just ignore c2
       
   284                         line += c;  // append the char to end of the line      
       
   285                     }    
       
   286                  }       
       
   287             }
       
   288             else
       
   289             {
       
   290                 pkgf.close();
       
   291                 RemoveDirectoryWithAllFiles(tempdir);
       
   292                 cerr << "ERROR: Pkg file " + pkgfile_location << " is not supported, check -sisfiles parameter" << endl;
       
   293                 exit(EXIT_PKG_FILE_CANNOT_OPEN_FOR_READING); 
       
   294             } 
       
   295         
       
   296         }
       
   297         else
       
   298         {
       
   299       		RemoveDirectoryWithAllFiles(tempdir);
       
   300      		cerr << "ERROR: Cannot open " + pkgfile_location << " for reading, check -sisfiles parameter" << endl;
       
   301     		exit(EXIT_PKG_FILE_CANNOT_OPEN_FOR_READING); 
       
   302         }                
       
   303 
       
   304         // close handles and clear any temp files        
       
   305         pkgf.close();
       
   306         RemoveDirectoryWithAllFiles(tempdir);
       
   307     }    
       
   308 
       
   309     // make sure that the cache directory exists
       
   310     MkDirAll(sis_target.cache_dir); 
       
   311         
       
   312     // write the dependencies cache of the sis files
       
   313     WriteDataToDependenciesCacheFile(sis_target);
       
   314     
       
   315     // append to targets
       
   316     _targets.push_back(sis_target);
       
   317     
       
   318     cerr << endl;
       
   319 
       
   320 }
       
   321 
       
   322 // ----------------------------------------------------------------------------------------------------------
       
   323     
       
   324