bin/patch_capabilities.pl
changeset 30 5dc02b23752f
parent 18 2f34d5167611
child 33 3e2da88830cd
equal deleted inserted replaced
29:b72c6db6890b 30:5dc02b23752f
    44 #
    44 #
    45 # A script for setting binary capabilities based on .pkg file contents.
    45 # A script for setting binary capabilities based on .pkg file contents.
    46 #
    46 #
    47 #######################################################################
    47 #######################################################################
    48 
    48 
       
    49 use File::Copy;
       
    50 
    49 sub Usage() {
    51 sub Usage() {
    50     print("This script can be used to set capabilities of all binaries\n");
    52     print("This script can be used to set capabilities of all binaries\n");
    51     print("specified for deployment in a .pkg file.\n");
    53     print("specified for deployment in a .pkg file.\n");
    52     print("If no capabilities are given, the binaries will be given the\n");
    54     print("If no capabilities are given, the binaries will be given the\n");
    53     print("capabilities supported by self-signed certificates.\n");
    55     print("capabilities supported by self-signed certificates.\n\n");
    54     print("\n *** NOTE: If *_template.pkg file is given, 'target-platform' is REQUIRED. ***\n");
    56     print(" *** NOTE: If *_template.pkg file is given and one is using symbian-abld or\n");
    55     print("\nUsage: patch_capabilities.pl pkg_filename <target-platform> [capability list]\n");
    57     print(" symbian-sbsv2 platform, 'target-platform' is REQUIRED. ***\n");
       
    58     print("\nUsage: patch_capabilities.pl pkg_filename [target-platform [capability list]]\n");
    56     print("\nE.g. patch_capabilities.pl myapp_template.pkg release-armv5 \"All -TCB\"\n");
    59     print("\nE.g. patch_capabilities.pl myapp_template.pkg release-armv5 \"All -TCB\"\n");
    57     exit();
    60     exit();
    58 }
    61 }
    59 
    62 
    60 my @capabilitiesToSet = ("LocalServices", "NetworkServices", "ReadUserData", "UserEnvironment", "WriteUserData");
    63 sub trim($) {
       
    64     my $string = shift;
       
    65     $string =~ s/^\s+//;
       
    66     $string =~ s/\s+$//;
       
    67     return $string;
       
    68 }
       
    69 
       
    70 my $nullDevice = "/dev/null";
       
    71 $nullDevice = "NUL" if ($^O =~ /MSWin/);
       
    72 
       
    73 my @capabilitiesToAllow = ("LocalServices", "NetworkServices", "ReadUserData", "UserEnvironment", "WriteUserData");
       
    74 my @capabilitiesSpecified = ();
    61 
    75 
    62 # If arguments were given to the script,
    76 # If arguments were given to the script,
    63 if (@ARGV)
    77 if (@ARGV)
    64 {
    78 {
    65     # Parse the first given script argument as a ".pkg" file name.
    79     # Parse the first given script argument as a ".pkg" file name.
    71 
    85 
    72     # Check if using template .pkg and set target/platform variables
    86     # Check if using template .pkg and set target/platform variables
    73     if (($pkgFileName =~ m|_template\.pkg$|i) && -r($pkgFileName))
    87     if (($pkgFileName =~ m|_template\.pkg$|i) && -r($pkgFileName))
    74     {
    88     {
    75         my $targetplatform;
    89         my $targetplatform;
    76         unless ($targetplatform = shift(@ARGV))
    90         my $templateFile;
       
    91         my $templateContents;
       
    92         open($templateFile, "< $pkgFileName") or die ("Could not open $pkgFileName");
       
    93         $templateContents = <$templateFile>;
       
    94         close($templateFile);
       
    95         unless (($targetplatform = shift(@ARGV)) || $templateContents !~ /\$\(PLATFORM\)/)
    77         {
    96         {
    78             Usage();
    97             Usage();
    79         }
    98         }
    80 
    99         $targetplatform = "-" if (!$targetplatform);
    81         my @tmpvalues = split('-', $targetplatform);
   100         my @tmpvalues = split('-', $targetplatform);
    82         $target = $tmpvalues[0];
   101         $target = $tmpvalues[0];
    83         $platform = $tmpvalues[1];
   102         $platform = $tmpvalues[1];
    84 
   103 
    85         # Convert visual target to real target (debug->udeb and release->urel)
   104         # Convert visual target to real target (debug->udeb and release->urel)
    88     }
   107     }
    89 
   108 
    90     # If the specified ".pkg" file exists (and can be read),
   109     # If the specified ".pkg" file exists (and can be read),
    91     if (($pkgFileName =~ m|\.pkg$|i) && -r($pkgFileName))
   110     if (($pkgFileName =~ m|\.pkg$|i) && -r($pkgFileName))
    92     {
   111     {
       
   112         print ("\n");
       
   113         print ("Patching package file and relevant binaries...\n");
       
   114 
    93         # If there are more arguments given, parse them as capabilities.
   115         # If there are more arguments given, parse them as capabilities.
    94         if (@ARGV)
   116         if (@ARGV)
    95         {
   117         {
    96             @capabilitiesToSet = ();
   118             @capabilitiesSpecified = ();
    97             while (@ARGV)
   119             while (@ARGV)
    98             {
   120             {
    99                 push (@capabilitiesToSet, pop(@ARGV));
   121                 push (@capabilitiesSpecified, pop(@ARGV));
   100             }
   122             }
   101         }
   123         }
   102 
   124 
   103         # Start with no binaries listed.
   125         # Start with no binaries listed.
   104         my @binaries = ();
   126         my @binaries = ();
   161             if ($line =~ m/^ENDIF.*MANUFACTURER$/)
   183             if ($line =~ m/^ENDIF.*MANUFACTURER$/)
   162             {
   184             {
   163                 $manufacturerElseBlock = 0;
   185                 $manufacturerElseBlock = 0;
   164             }
   186             }
   165 
   187 
   166             print NEW_PKG $newLine;
       
   167 
       
   168             chomp ($line);
       
   169 
       
   170             # If the line specifies a file, parse the source and destination locations.
   188             # If the line specifies a file, parse the source and destination locations.
   171             if ($line =~ m|\"([^\"]+)\"\s*\-\s*\"([^\"]+)\"|)
   189             if ($line =~ m|\"([^\"]+)\"\s*\-\s*\"([^\"]+)\"|)
   172             {
   190             {
   173                 my $sourcePath = $1;
   191                 my $sourcePath = $1;
   174                 my $destinationPath = $2;
       
   175 
   192 
   176                 # If the given file is a binary, check the target and binary type (+ the actual filename) from its path.
   193                 # If the given file is a binary, check the target and binary type (+ the actual filename) from its path.
   177                 if ($sourcePath =~ m:/epoc32/release/([^/]+)/(udeb|urel|\$\(TARGET\))/(\w+(\.dll|\.exe)):i)
   194                 if ($sourcePath =~ m:\w+(\.dll|\.exe)$:i)
   178                 {
   195                 {
   179                     # Do preprocessing for template pkg,
   196                     # Do preprocessing for template pkg,
   180                     # In case of template pkg target and platform variables are set
   197                     # In case of template pkg target and platform variables are set
   181                     if(length($target) && length($platform))
   198                     if(length($target) && length($platform))
   182                     {
   199                     {
   183                         $sourcePath =~ s/\$\(PLATFORM\)/$platform/gm;
   200                         $sourcePath =~ s/\$\(PLATFORM\)/$platform/gm;
   184                         $sourcePath =~ s/\$\(TARGET\)/$target/gm;
   201                         $sourcePath =~ s/\$\(TARGET\)/$target/gm;
   185                     }
   202                     }
   186 
   203 
   187                     push (@binaries, $sourcePath);
   204                     # Change the source file name (but only if not already patched)
       
   205                     my $patchedSourcePath = $sourcePath;
       
   206                     if ($patchedSourcePath !~ m/_patched_caps/)
       
   207                     {
       
   208                         $newLine =~ s/(^.*)(\.dll|\.exe)(.*)(\.dll|\.exe)/$1_patched_caps$2$3$4/i;
       
   209                         $patchedSourcePath =~ s/(^.*)(\.dll|\.exe)/$1_patched_caps$2/i;
       
   210 
       
   211                         copy($sourcePath, $patchedSourcePath) or die "$sourcePath cannot be copied for patching.";
       
   212                     }
       
   213                     push (@binaries, $patchedSourcePath);
   188                 }
   214                 }
   189             }
   215             }
       
   216 
       
   217             print NEW_PKG $newLine;
       
   218 
       
   219             chomp ($line);
   190         }
   220         }
   191 
   221 
   192         close (PKG);
   222         close (PKG);
   193         close (NEW_PKG);
   223         close (NEW_PKG);
   194 
   224 
   195         unlink($pkgFileName);
   225         unlink($pkgFileName);
   196         rename($tempPkgFileName, $pkgFileName);
   226         rename($tempPkgFileName, $pkgFileName);
   197 
   227 
   198         print ("\n");
   228         print ("\n");
   199 
   229 
   200         my $baseCommandToExecute = "elftran -vid 0x0 -capability \"";
   230         my $baseCommandToExecute = "elftran -vid 0x0 -capability \"%s\" ";
   201         if (@capabilitiesToSet)
       
   202         {
       
   203             $baseCommandToExecute .= join(" ", @capabilitiesToSet);
       
   204         }
       
   205         $baseCommandToExecute .= "\" ";
       
   206 
   231 
   207         # Actually set the capabilities of the listed binaries.
   232         # Actually set the capabilities of the listed binaries.
   208         foreach my $binaryPath(@binaries)
   233         foreach my $binaryPath(@binaries)
   209         {
   234         {
   210             # Create the command line for setting the capabilities.
   235             # Create the command line for setting the capabilities.
   211             my $commandToExecute = $baseCommandToExecute;
   236             my $commandToExecute = $baseCommandToExecute;
       
   237             if (@capabilitiesSpecified)
       
   238             {
       
   239                 $commandToExecute = sprintf($baseCommandToExecute, join(" ", @capabilitiesSpecified));
       
   240             } else {
       
   241                 # Test which capabilities are present and then restrict them to the allowed set.
       
   242                 # This avoid raising the capabilities of apps that already have none.
       
   243                 my $dllCaps;
       
   244                 open($dllCaps, "elftran -dump s $binaryPath |") or die ("Could not execute elftran");
       
   245                 my $capsFound = 0;
       
   246                 my @capabilitiesToSet;
       
   247                 my $capabilitiesToAllow = join(" ", @capabilitiesToAllow);
       
   248                 while (<$dllCaps>) {
       
   249                     if (!$capsFound) {
       
   250                         $capsFound = 1 if (/Capabilities:/);
       
   251                     } else {
       
   252                         $_ = trim($_);
       
   253                         if ($capabilitiesToAllow =~ /$_/) {
       
   254                             push(@capabilitiesToSet, $_);
       
   255                         }
       
   256                     }
       
   257                 }
       
   258                 close($dllCaps);
       
   259                 $commandToExecute = sprintf($baseCommandToExecute, join(" ", @capabilitiesToSet));
       
   260             }
   212             $commandToExecute .= $binaryPath;
   261             $commandToExecute .= $binaryPath;
   213 
   262 
   214             # Actually execute the elftran command to set the capabilities.
   263             # Actually execute the elftran command to set the capabilities.
   215             system ($commandToExecute." > NUL");
   264             print ("Executing ".$commandToExecute."\n");
   216             print ("Executed ".$commandToExecute."\n");
   265             system ($commandToExecute." > $nullDevice");
   217 
   266 
   218             ## Create another command line to check that the set capabilities are correct.
   267             ## Create another command line to check that the set capabilities are correct.
   219             #$commandToExecute = "elftran -dump s ".$binaryPath;
   268             #$commandToExecute = "elftran -dump s ".$binaryPath;
   220         }
   269         }
   221 
   270 
       
   271         print ("\n");
       
   272         print ("NOTE: A patched package should not be used for distribution!\n");
   222         print ("\n");
   273         print ("\n");
   223     }
   274     }
   224 }
   275 }
   225 else
   276 else
   226 {
   277 {