1#!/usr/bin/env python
2
3import ConfigParser
4import uuid
5import struct
6import sys
7
8type_2_guid = {
9# official guid for gpt partition type
10    'fat' : 'ebd0a0a2-b9e5-4433-87c0-68b6b72699c7',
11    'esp' : 'c12a7328-f81f-11d2-ba4b-00a0c93ec93b',
12    'linux' : '0fc63daf-8483-4772-8e79-3d69d8477de4',
13    'linux-swap' : '0657fd6d-a4ab-43c4-84e5-0933c84b4f4f',
14# generated guid for android
15    'boot' : '49a4d17f-93a3-45c1-a0de-f50b2ebe2599',
16    'recovery' : '4177c722-9e92-4aab-8644-43502bfd5506',
17    'misc' : 'ef32a33b-a409-486c-9141-9ffb711f6266',
18    'metadata' : '20ac26be-20b7-11e3-84c5-6cfdb94711e9',
19    'tertiary' : '767941d0-2085-11e3-ad3b-6cfdb94711e9',
20    'factory' : '9fdaa6ef-4b3f-40d2-ba8d-bff16bfb887b' }
21
22def zero_pad(s, size):
23    if (len(s) > size):
24        print 'error', len(s)
25    s += '\0' * (size - len(s))
26    return s
27
28def preparse_partitions(gpt_in, cfg):
29    with open(gpt_in, 'r') as f:
30        data = f.read()
31
32    partitions = cfg.get('base', 'partitions').split()
33
34    for l in data.split('\n'):
35        words = l.split()
36        if len(words) > 2:
37            if words[0] == 'partitions' and words[1] == '+=':
38                partitions += words[2:]
39
40    return partitions
41
42def main():
43    if len(sys.argv) != 2:
44        print 'Usage : ', sys.argv[0], 'gpt_in1.ini'
45        print '    write binary to stdout'
46        sys.exit(1)
47
48    gpt_in = sys.argv[1]
49
50    cfg = ConfigParser.SafeConfigParser()
51
52    cfg.read(gpt_in)
53
54    part = preparse_partitions(gpt_in, cfg)
55
56    magic = 0x6a8b0da1
57    start_lba = 0
58    if cfg.has_option('base', 'start_lba'):
59        start_lba = cfg.getint('base', 'start_lba')
60    npart = len(part)
61
62    out = sys.stdout
63    out.write(struct.pack('<I', magic))
64    out.write(struct.pack('<I', start_lba))
65    out.write(struct.pack('<I', npart))
66    for p in part:
67        length = cfg.get('partition.' + p, 'len')
68        out.write(struct.pack('<i', int(length)))
69
70        label = cfg.get('partition.' + p, 'label').encode('utf-16le')
71        out.write(zero_pad(label, 36 * 2))
72
73        guid_type = cfg.get('partition.' + p, 'type')
74        guid_type = uuid.UUID(type_2_guid[guid_type])
75        out.write(guid_type.bytes_le)
76
77        guid = uuid.UUID(cfg.get('partition.' + p, 'guid'))
78        out.write(guid.bytes_le)
79
80if __name__ == "__main__":
81    main()
82