|
1 """ |
|
2 Copyright (c) 2006, Jari Sukanen |
|
3 All rights reserved. |
|
4 |
|
5 Redistribution and use in source and binary forms, with or |
|
6 without modification, are permitted provided that the following |
|
7 conditions are met: |
|
8 * Redistributions of source code must retain the above copyright |
|
9 notice, this list of conditions and the following disclaimer. |
|
10 * Redistributions in binary form must reproduce the above copyright |
|
11 notice, this list of conditions and the following disclaimer in |
|
12 the documentation and/or other materials provided with the |
|
13 distribution. |
|
14 * Names of the contributors may not be used to endorse or promote |
|
15 products derived from this software without specific prior written |
|
16 permission. |
|
17 |
|
18 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
19 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
|
20 TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
|
21 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS |
|
22 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
|
23 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
|
24 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
|
25 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
|
26 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
|
27 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
|
28 THE POSSIBILITY OF SUCH DAMAGE. |
|
29 """ |
|
30 from sis import sisinfo, sisfields |
|
31 import optparse |
|
32 import sys, os |
|
33 |
|
34 APP_PATH = "epoc32" + os.sep + "apps" |
|
35 IBY_PATH = "epoc32" + os.sep + "rom" + os.sep + "include" |
|
36 CRLF = '\r\n' |
|
37 |
|
38 try: |
|
39 os.uname() |
|
40 ZIP_CMD = 'zip -r ' |
|
41 except: # no uname on windows |
|
42 ZIP_CMD = '7z a ' |
|
43 |
|
44 PyASN1Availabe = True |
|
45 |
|
46 try : |
|
47 from pyasn1.codec.der import decoder |
|
48 from pyasn1.type import univ, base |
|
49 except : |
|
50 PyASN1Availabe = False |
|
51 |
|
52 def _findItem(item, itemParent, index, objectIdentifier) : |
|
53 if isinstance(item, base.AbstractSimpleAsn1Item) : |
|
54 if item == objectIdentifier : |
|
55 return itemParent[index+1] |
|
56 else : |
|
57 for i in range(len(item)) : |
|
58 found = _findItem(item[i], item, i, objectIdentifier) |
|
59 if found : |
|
60 return found |
|
61 |
|
62 def findItem(decodedCert, objectIdentifier) : |
|
63 return _findItem(decodedCert, None, 0, objectIdentifier) |
|
64 |
|
65 |
|
66 class CertificateOrganization : |
|
67 def __init__(self) : |
|
68 pass |
|
69 |
|
70 def parse(self, decodedCert) : |
|
71 self.commonName = findItem(decodedCert, (2,5,4,3)) |
|
72 self.countryCode = findItem(decodedCert, (2,5,4,6)) |
|
73 self.locality = findItem(decodedCert, (2,5,4,7)) |
|
74 self.state = findItem(decodedCert, (2,5,4,8)) |
|
75 self.street = findItem(decodedCert, (2,5,4,9)) |
|
76 self.organization = findItem(decodedCert, (2,5,4,10)) |
|
77 |
|
78 def readableStr(self) : |
|
79 buf = "" |
|
80 if self.commonName : |
|
81 buf += self.commonName.prettyPrint() + "\n" |
|
82 if self.countryCode : |
|
83 buf += self.countryCode.prettyPrint() + "\n" |
|
84 if self.locality : |
|
85 buf += self.locality.prettyPrint() + "\n" |
|
86 if self.state : |
|
87 buf += self.state.prettyPrint() + "\n" |
|
88 if self.street : |
|
89 buf += self.street.prettyPrint() + "\n" |
|
90 if self.organization : |
|
91 buf += self.organization.prettyPrint() |
|
92 return buf |
|
93 |
|
94 class CertificateInfo : |
|
95 def __init__(self) : |
|
96 pass |
|
97 |
|
98 def parse(self, decodedCert) : |
|
99 self.issuer = CertificateOrganization() |
|
100 self.issuer.parse(decodedCert[0][3]) |
|
101 |
|
102 self.signer = CertificateOrganization() |
|
103 self.signer.parse(decodedCert[0][5]) |
|
104 |
|
105 def readableStr(self) : |
|
106 buf = "Signer:\n " + "\n ".join(self.signer.readableStr().split('\n')) + "\n" |
|
107 buf += "Issuer:\n " + "\n ".join(self.issuer.readableStr().split('\n')) + "\n" |
|
108 return buf |
|
109 |
|
110 |
|
111 class Handler : |
|
112 def __init__(self) : |
|
113 self.files = [] |
|
114 self.fileDatas = [] |
|
115 self.signatureCertificateChains = [] |
|
116 |
|
117 def handleField(self, field, depth) : |
|
118 if field.type == sisfields.FileDescriptionField : |
|
119 self.files.append(field) |
|
120 elif field.type == sisfields.FileDataField : |
|
121 self.fileDatas.append(field) |
|
122 elif field.type == sisfields.SignatureCertificateChainField : |
|
123 self.signatureCertificateChains.append(field) |
|
124 |
|
125 def print_iby_for_file(self, iby, extracted_file, install_path): |
|
126 #binarypath="file=ABI_DIR\\BUILD_DIR\\" |
|
127 #datapath="data=DATAZ_\\RESOURCE_FILES_DIR\\" |
|
128 binarypath="file=\\" |
|
129 datapath="data=\\" |
|
130 #privatepath="data=\\epoc32\\data\\z\\" |
|
131 |
|
132 install_path=install_path.replace('c:', 'z:') |
|
133 #basename = filepath[filepath.rfind('\\')+1:] |
|
134 |
|
135 if extracted_file.endswith('exe') or extracted_file.endswith('dll'): |
|
136 iby.write( binarypath + extracted_file + '\t\t' + install_path + CRLF) |
|
137 else: |
|
138 iby.write( datapath + extracted_file + '\t\t' + install_path + CRLF) |
|
139 |
|
140 |
|
141 def execute(self,outputname, iby) : |
|
142 for f in self.files : |
|
143 buf = f.findField(sisfields.StringField)[0].readableStr() |
|
144 # caps = f.findField(sisfields.CapabilitiesField)[0] |
|
145 # if caps : |
|
146 # buf += " [" + " ".join(f.findField(sisfields.CapabilitiesField)[0].readableCaps) + "]" |
|
147 |
|
148 install_path=buf |
|
149 parts = f.findField(sisfields.StringField)[0].readableStr().split("\\") |
|
150 #for part in parts: |
|
151 # print part |
|
152 if len(parts[len(parts) - 1]) > 0 : |
|
153 path = os.getcwd() + os.sep + APP_PATH |
|
154 |
|
155 path += os.sep + os.sep.join(parts[1:-1]) |
|
156 rel_file = APP_PATH + os.sep + outputname + os.sep + os.sep.join(parts[1:]) |
|
157 rel_file = rel_file.replace('/','\\') |
|
158 if not os.path.exists(path) : |
|
159 os.makedirs(path) |
|
160 extracted_file = path + os.sep + parts[len(parts) - 1] |
|
161 newFile = file(extracted_file, "wb") |
|
162 newFile.write(self.fileDatas[f.fileIndex].findField(sisfields.CompressedField)[0].data) |
|
163 newFile.close() |
|
164 self.print_iby_for_file(iby,rel_file, install_path) |
|
165 |
|
166 class ContentPrinter : |
|
167 def __init__(self) : |
|
168 pass |
|
169 |
|
170 def handleField(self, field, depth) : |
|
171 buf = "" |
|
172 for i in range(depth) : |
|
173 buf += " " |
|
174 buf += sisfields.FieldNames[field.type] + " " |
|
175 if len(field.readableStr()) > 0 : |
|
176 buf += field.readableStr() |
|
177 print buf |
|
178 |
|
179 import pdb |
|
180 |
|
181 if __name__ == "__main__" : |
|
182 if len(sys.argv) == 1: |
|
183 print "usage: %s <sisfile>" % sys.argv[0] |
|
184 exit() |
|
185 |
|
186 sisname = sys.argv[1] |
|
187 sisInfo = sisinfo.SISInfo() |
|
188 sisInfo.parse(sisname) |
|
189 |
|
190 handler = Handler() |
|
191 sisInfo.traverse(handler) |
|
192 |
|
193 tmp = sisname.lower() |
|
194 |
|
195 if tmp.find(os.sep): |
|
196 tmp = sisname[sisname.rfind(os.sep)+1:] |
|
197 |
|
198 if tmp.find('sisx'): |
|
199 tmp = tmp[0:len(tmp)-4] |
|
200 elif tmp.find('sis'): |
|
201 tmp = tmp[0:len(tmp)-3] |
|
202 |
|
203 iby_path = os.getcwd() + os.sep + IBY_PATH + os.sep |
|
204 iby_file = tmp + ".iby" |
|
205 |
|
206 if not os.path.exists(iby_path) : |
|
207 os.makedirs(iby_path) |
|
208 |
|
209 iby = open(iby_path + iby_file,'w') |
|
210 print "Creating IBY file..." |
|
211 iby.write( "#ifndef __%s_IBY__" % tmp.upper() + CRLF) |
|
212 iby.write( "#define __%s_IBY__" % tmp.upper() + CRLF) |
|
213 print "Extracting SIS..." |
|
214 handler.execute(tmp, iby) |
|
215 iby.write( "#endif" + CRLF) |
|
216 iby.close() |
|
217 print "Zipping..." |
|
218 os.system(ZIP_CMD + tmp + '.zip epoc32') |
|
219 print "All done. Remember to #include <%s> in your main IBY file" % iby_file |