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) |
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 { |