1
#!/usr/bin/perl
2
#############################################################################
3
##
4
## Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
5
## All rights reserved.
6
## Contact: Nokia Corporation (qt-info@nokia.com)
7
##
8
## This file is part of the S60 port of the Qt Toolkit.
9
##
10
## $QT_BEGIN_LICENSE:LGPL$
11
## No Commercial Usage
12
## This file contains pre-release code and may not be distributed.
13
## You may use this file in accordance with the terms and conditions
14
## contained in the Technology Preview License Agreement accompanying
15
## this package.
16
##
17
## GNU Lesser General Public License Usage
18
## Alternatively, this file may be used under the terms of the GNU Lesser
19
## General Public License version 2.1 as published by the Free Software
20
## Foundation and appearing in the file LICENSE.LGPL included in the
21
## packaging of this file.  Please review the following information to
22
## ensure the GNU Lesser General Public License version 2.1 requirements
23
## will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24
##
25
## In addition, as a special exception, Nokia gives you certain additional
26
## rights.  These rights are described in the Nokia Qt LGPL Exception
27
## version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28
##
29
## If you have questions regarding the use of this file, please contact
30
## Nokia at qt-info@nokia.com.
31
##
32
##
33
##
34
##
35
##
36
##
37
##
38
##
39
## $QT_END_LICENSE$
40
##
41
#############################################################################
42
43
#######################################################################
44
#
45
# A script for setting binary capabilities based on .pkg file contents.
46
#
47
#######################################################################
48
49
sub Usage() {
50
    print("This script can be used to set capabilities of all binaries\n");
51
    print("specified for deployment in a .pkg file.\n");
52
    print("If no capabilities are given, the binaries will be given the\n");
53
    print("capabilities supported by self-signed certificates.\n");
54
    print("\n *** NOTE: If *_template.pkg file is given, 'target-platform' is REQUIRED. ***\n");
55
    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");
57
    exit();
58
}
59
60
my @capabilitiesToSet = ("LocalServices", "NetworkServices", "ReadUserData", "UserEnvironment", "WriteUserData");
61
62
# If arguments were given to the script,
63
if (@ARGV)
64
{
65
    # Parse the first given script argument as a ".pkg" file name.
66
    my $pkgFileName = shift(@ARGV);
67
68
    # These variables will only be set for template .pkg files.
69
    my $target;
70
    my $platform;
71
72
    # Check if using template .pkg and set target/platform variables
73
    if (($pkgFileName =~ m|_template\.pkg$|i) && -r($pkgFileName))
74
    {
75
        my $targetplatform;
76
        unless ($targetplatform = shift(@ARGV))
77
        {
78
            Usage();
79
        }
80
81
        my @tmpvalues = split('-', $targetplatform);
82
        $target = $tmpvalues[0];
83
        $platform = $tmpvalues[1];
84
85
        # Convert visual target to real target (debug->udeb and release->urel)
86
        $target =~ s/debug/udeb/i;
87
        $target =~ s/release/urel/i;
88
    }
89
90
    # If the specified ".pkg" file exists (and can be read),
91
    if (($pkgFileName =~ m|\.pkg$|i) && -r($pkgFileName))
92
    {
93
        # If there are more arguments given, parse them as capabilities.
94
        if (@ARGV)
95
        {
96
            @capabilitiesToSet = ();
97
            while (@ARGV)
98
            {
99
                push (@capabilitiesToSet, pop(@ARGV));
100
            }
101
        }
102
103
        # Start with no binaries listed.
104
        my @binaries = ();
105
106
        my $tempPkgFileName = $pkgFileName."_@@TEMP@@";
107
        unlink($tempPkgFileName);
108
        open (NEW_PKG, ">>".$tempPkgFileName);
109
        open (PKG, "<".$pkgFileName);
110
111
        my $manufacturerElseBlock = 0;
112
113
        # Parse each line.
114
        while (<PKG>)
115
        {
116
            # Patch pkg UID
117
            my $line = $_;
118
            my $newLine = $line;
119
            if ($line =~ m/^\#.*\(0x[0-9|a-f|A-F]*\).*$/)
120
            {
121
                $newLine =~ s/\(0x./\(0xE/;
122
            }
123
124
            # Patch embedded sis name and UID
125
            if ($line =~ m/^@.*\.sis.*\(0x[0-9|a-f|A-F]*\).*$/)
126
            {
127
                $newLine =~ s/\(0x./\(0xE/;
128
                if ($line !~ m/^.*_selfsigned.sis.*$/)
129
                {
130
                    $newLine =~ s/\.sis/_selfsigned\.sis/i;
131
                }
132
            }
133
134
            # Remove dependencies to known problem packages (i.e. packages that are likely to be patched, also)
135
            # to reduce unnecessary error messages.
136
            if ($line =~ m/^\(0x2002af5f\).*\{.*\}$/)
137
            {
138
                $newLine = "\n"
139
            }
140
            if ($line =~ m/^\(0x2001E61C\).*\{.*\}$/)
141
            {
142
                $newLine = "\n"
143
            }
144
145
            # Remove manufacturer ifdef
146
            if ($line =~ m/^.*\(MANUFACTURER\)\=\(.*\).*$/)
147
            {
148
                $newLine = "\n";
149
            }
150
151
            if ($line =~ m/^ELSEIF.*MANUFACTURER$/)
152
            {
153
                $manufacturerElseBlock = 1;
154
            }
155
156
            if ($manufacturerElseBlock eq 1)
157
            {
158
                $newLine = "\n";
159
            }
160
161
            if ($line =~ m/^ENDIF.*MANUFACTURER$/)
162
            {
163
                $manufacturerElseBlock = 0;
164
            }
165
166
            print NEW_PKG $newLine;
167
168
            chomp ($line);
169
170
            # If the line specifies a file, parse the source and destination locations.
171
            if ($line =~ m|\"([^\"]+)\"\s*\-\s*\"([^\"]+)\"|)
172
            {
173
                my $sourcePath = $1;
174
                my $destinationPath = $2;
175
176
                # 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)
178
                {
179
                    # Do preprocessing for template pkg,
180
                    # In case of template pkg target and platform variables are set
181
                    if(length($target) && length($platform))
182
                    {
183
                        $sourcePath =~ s/\$\(PLATFORM\)/$platform/gm;
184
                        $sourcePath =~ s/\$\(TARGET\)/$target/gm;
185
                    }
186
187
                    push (@binaries, $sourcePath);
188
                }
189
            }
190
        }
191
192
        close (PKG);
193
        close (NEW_PKG);
194
195
        unlink($pkgFileName);
196
        rename($tempPkgFileName, $pkgFileName);
197
198
        print ("\n");
199
200
        my $baseCommandToExecute = "elftran -vid 0x0 -capability \"";
201
        if (@capabilitiesToSet)
202
        {
203
            $baseCommandToExecute .= join(" ", @capabilitiesToSet);
204
        }
205
        $baseCommandToExecute .= "\" ";
206
207
        # Actually set the capabilities of the listed binaries.
208
        foreach my $binaryPath(@binaries)
209
        {
210
            # Create the command line for setting the capabilities.
211
            my $commandToExecute = $baseCommandToExecute;
212
            $commandToExecute .= $binaryPath;
213
214
            # Actually execute the elftran command to set the capabilities.
215
            system ($commandToExecute." > NUL");
216
            print ("Executed ".$commandToExecute."\n");
217
218
            ## Create another command line to check that the set capabilities are correct.
219
            #$commandToExecute = "elftran -dump s ".$binaryPath;
220
        }
221
222
        print ("\n");
223
    }
224
}
225
else
226
{
227
    Usage();
228
}