blob: e783b3a18838e4771d42252bd2cf1c6acb10ff47 [file] [log] [blame]
#!/usr/bin/env python
from cStringIO import StringIO
import struct
import sha
from dbparse import DBParser
import sys
MAGIC = 0x52474442
VERSION = 19
if len(sys.argv) < 3:
print 'Usage: %s output-file input-file [key-file]' % sys.argv[0]
sys.exit(2)
def create_rules(countries):
result = {}
for c in countries.itervalues():
for rule in c.permissions:
result[rule] = 1
return result.keys()
def create_collections(countries):
result = {}
for c in countries.itervalues():
result[c.permissions] = 1
return result.keys()
def be32(output, val):
output.write(struct.pack('>I', val))
class PTR(object):
def __init__(self, output):
self._output = output
self._pos = output.tell()
be32(output, 0xFFFFFFFF)
def set(self, val=None):
if val is None:
val = self._output.tell()
self._offset = val
pos = self._output.tell()
self._output.seek(self._pos)
be32(self._output, val)
self._output.seek(pos)
def get(self):
return self._offset
p = DBParser()
countries = p.parse(file(sys.argv[2]))
power = []
bands = []
for c in countries.itervalues():
for perm in c.permissions:
if not perm.freqband in bands:
bands.append(perm.freqband)
if not perm.power in power:
power.append(perm.power)
rules = create_rules(countries)
rules.sort(cmp=lambda x, y: cmp(x.freqband, y.freqband))
collections = create_collections(countries)
collections.sort(cmp=lambda x, y: cmp(x[0].freqband, y[0].freqband))
output = StringIO()
# struct regdb_file_header
be32(output, MAGIC)
be32(output, VERSION)
reg_country_ptr = PTR(output)
# add number of countries
be32(output, len(countries))
siglen = PTR(output)
power_rules = {}
for pr in power:
power_rules[pr] = output.tell()
pr = [int(v * 100.0) for v in (pr.max_ant_gain, pr.max_eirp)]
# struct regdb_file_power_rule
output.write(struct.pack('>II', *pr))
freq_ranges = {}
for fr in bands:
freq_ranges[fr] = output.tell()
fr = [int(f * 1000.0) for f in (fr.start, fr.end, fr.maxbw)]
# struct regdb_file_freq_range
output.write(struct.pack('>III', *fr))
reg_rules = {}
for reg_rule in rules:
freq_range, power_rule = reg_rule.freqband, reg_rule.power
reg_rules[reg_rule] = output.tell()
# struct regdb_file_reg_rule
output.write(struct.pack('>III', freq_ranges[freq_range], power_rules[power_rule],
reg_rule.flags))
reg_rules_collections = {}
for coll in collections:
reg_rules_collections[coll] = output.tell()
# struct regdb_file_reg_rules_collection
coll = list(coll)
be32(output, len(coll))
coll.sort(cmp=lambda x, y: cmp(x.freqband, y.freqband))
for regrule in coll:
be32(output, reg_rules[regrule])
# update country pointer now!
reg_country_ptr.set()
countrynames = countries.keys()
countrynames.sort()
for alpha2 in countrynames:
coll = countries[alpha2]
# struct regdb_file_reg_country
output.write(struct.pack('>ccxxI', str(alpha2[0]), str(alpha2[1]), reg_rules_collections[coll.permissions]))
if len(sys.argv) > 3:
# Load RSA only now so people can use this script
# without having those libraries installed to verify
# their SQL changes
from M2Crypto import RSA
# determine signature length
key = RSA.load_key(sys.argv[3])
hash = sha.new()
hash.update(output.getvalue())
sig = key.sign(hash.digest())
# write it to file
siglen.set(len(sig))
# sign again
hash = sha.new()
hash.update(output.getvalue())
sig = key.sign(hash.digest())
output.write(sig)
else:
siglen.set(0)
outfile = open(sys.argv[1], 'w')
outfile.write(output.getvalue())