db2bin.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. #!/usr/bin/env python
  2. from io import BytesIO, open
  3. import struct
  4. import hashlib
  5. from dbparse import DBParser
  6. import sys
  7. MAGIC = 0x52474442
  8. VERSION = 19
  9. if len(sys.argv) < 3:
  10. print('Usage: %s output-file input-file [key-file]' % sys.argv[0])
  11. sys.exit(2)
  12. def create_rules(countries):
  13. result = {}
  14. for c in countries.values():
  15. for rule in c.permissions:
  16. result[rule] = 1
  17. return list(result)
  18. def create_collections(countries):
  19. result = {}
  20. for c in countries.values():
  21. result[c.permissions] = 1
  22. return list(result)
  23. def be32(output, val):
  24. output.write(struct.pack('>I', val))
  25. class PTR(object):
  26. def __init__(self, output):
  27. self._output = output
  28. self._pos = output.tell()
  29. be32(output, 0xFFFFFFFF)
  30. def set(self, val=None):
  31. if val is None:
  32. val = self._output.tell()
  33. self._offset = val
  34. pos = self._output.tell()
  35. self._output.seek(self._pos)
  36. be32(self._output, val)
  37. self._output.seek(pos)
  38. def get(self):
  39. return self._offset
  40. p = DBParser()
  41. countries = p.parse(open(sys.argv[2], 'r', encoding='utf-8'))
  42. countrynames = list(countries)
  43. countrynames.sort()
  44. power = []
  45. bands = []
  46. for alpha2 in countrynames:
  47. for perm in countries[alpha2].permissions:
  48. if not perm.freqband in bands:
  49. bands.append(perm.freqband)
  50. if not perm.power in power:
  51. power.append(perm.power)
  52. rules = create_rules(countries)
  53. rules.sort()
  54. collections = create_collections(countries)
  55. collections.sort()
  56. output = BytesIO()
  57. # struct regdb_file_header
  58. be32(output, MAGIC)
  59. be32(output, VERSION)
  60. reg_country_ptr = PTR(output)
  61. # add number of countries
  62. be32(output, len(countries))
  63. siglen = PTR(output)
  64. power_rules = {}
  65. for pr in power:
  66. power_rules[pr] = output.tell()
  67. pr = [int(v * 100.0) for v in (pr.max_ant_gain, pr.max_eirp)]
  68. # struct regdb_file_power_rule
  69. output.write(struct.pack('>II', *pr))
  70. freq_ranges = {}
  71. for fr in bands:
  72. freq_ranges[fr] = output.tell()
  73. fr = [int(f * 1000.0) for f in (fr.start, fr.end, fr.maxbw)]
  74. # struct regdb_file_freq_range
  75. output.write(struct.pack('>III', *fr))
  76. reg_rules = {}
  77. for reg_rule in rules:
  78. freq_range, power_rule = reg_rule.freqband, reg_rule.power
  79. reg_rules[reg_rule] = output.tell()
  80. # struct regdb_file_reg_rule
  81. output.write(struct.pack('>III', freq_ranges[freq_range], power_rules[power_rule],
  82. reg_rule.flags))
  83. reg_rules_collections = {}
  84. for coll in collections:
  85. reg_rules_collections[coll] = output.tell()
  86. # struct regdb_file_reg_rules_collection
  87. coll = list(coll)
  88. be32(output, len(coll))
  89. coll.sort()
  90. for regrule in coll:
  91. be32(output, reg_rules[regrule])
  92. # update country pointer now!
  93. reg_country_ptr.set()
  94. for alpha2 in countrynames:
  95. coll = countries[alpha2]
  96. # struct regdb_file_reg_country
  97. output.write(struct.pack('>BBxBI', alpha2[0], alpha2[1], coll.dfs_region, reg_rules_collections[coll.permissions]))
  98. if len(sys.argv) > 3:
  99. # Load RSA only now so people can use this script
  100. # without having those libraries installed to verify
  101. # their SQL changes
  102. from M2Crypto import RSA
  103. # determine signature length
  104. key = RSA.load_key(sys.argv[3])
  105. hash = hashlib.sha1()
  106. hash.update(output.getvalue())
  107. sig = key.sign(hash.digest())
  108. # write it to file
  109. siglen.set(len(sig))
  110. # sign again
  111. hash = hashlib.sha1()
  112. hash.update(output.getvalue())
  113. sig = key.sign(hash.digest())
  114. output.write(sig)
  115. else:
  116. siglen.set(0)
  117. outfile = open(sys.argv[1], 'wb')
  118. outfile.write(output.getvalue())