Patcher from Dani Church, removed coreutils-gnu dependance and fixed init script.
[ussd-widget] / ussd4all / rtcom / rtcompatcher.py
1 #!/usr/bin/python
2
3 ## This program is free software; you can redistribute it and/or modify
4 ## it under the terms of the GNU General Public License as published
5 ## by the Free Software Foundation; version 2 and higer.
6 ##
7 ## Dani Church 2010
8
9 import hashlib
10
11 patch_config = {
12     'known_md5sums': [
13         '5a51e4fbb38dac338e4444e6b713e9b3',
14         '44d6b8258fb4fb9c849162704120ba53',
15     ],
16     'check_ranges': [
17         (194380, 'f04f2de920b08de2'),
18         (195340, 'f04f2de920b08de2'),
19     ],
20     'patch_ranges': [
21         (194380, '0010a0e3001097e5'),
22         (195340, '0010a0e3001097e5'),
23     ],
24 }
25
26 class Patcher:
27     known_md5sums = []
28     check_ranges = []
29     patch_ranges = []
30
31     def __init__(self, config):
32         self.known_md5sums = config['known_md5sums']
33         self.check_ranges = config['check_ranges']
34         self.patch_ranges = config['patch_ranges']
35
36     def check_md5sum(self, filename):
37         md5 = hashlib.md5()
38         f = open(filename, 'rb')
39         while True:
40             d = f.read(8096)
41             if not d: break
42             md5.update(d)
43         f.close()
44
45         md5sum = md5.hexdigest()
46         for known_sum in self.known_md5sums:
47             if md5sum == known_sum: return True
48
49         return False
50
51     def check_data(self, filename):
52         f = open(filename, 'rb')
53
54         for seek, hexbytes in self.check_ranges:
55             bytes = hexbytes.decode('hex')
56             f.seek(seek)
57             actual = f.read(len(bytes))
58             if actual != bytes:
59                 f.close()
60                 return False
61
62         f.close()
63         return True
64         
65     def patch_file(self, filename):
66         f = open(filename, 'r+b')
67
68         for seek, hexbytes in self.patch_ranges:
69             bytes = hexbytes.decode('hex')
70             f.seek(seek)
71             f.write(bytes)
72
73         f.close()
74
75 if __name__ == '__main__':
76     import sys, os, shutil
77
78     library = '/usr/lib/librtcom-call-ui.so.0.0.0'
79
80     if os.access(library+'.orig', os.F_OK):
81         print "It looks like %s has already been patched. Aborting." % (library,)
82         sys.exit(1)
83
84     patcher = Patcher(patch_config)
85
86     if not patcher.check_md5sum(library):
87         if not patcher.check_data(library):
88             print "Your %s is not recognized. So I won't patch it." % (library,)
89             sys.exit(1)
90         if len(sys.argv) > 1 and sys.argv[1] == '--force':
91             print "Patching an unrecognized %s. Please test your system before rebooting." % (library,)
92         else:
93             message = "Your %s is not recognized, but it seems to match the patterns.\nRun '%s --force' to try patching anyway, but understand that\nTHIS MAY BREAK YOUR SYSTEM.  If you do, test your system thoroughly before rebooting." % (library,library,sys.argv[0])
94             subprocess.call(["dbus-send --type=method_call --dest=org.freedesktop.Notifications /org/freedesktop/Notifications org.freedesktop.Notifications.SystemNoteDialog string:\""+message+"\" uint32:0 string:\"OK\""],shell=True)
95             sys.exit(1)
96
97     shutil.copy2(library, library+'.orig')
98     patcher.patch_file(library)