1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
#!/usr/bin/env python3
import errno, filecmp, fnmatch, glob, os.path, re, sys
from debian import deb822
from enum import Enum
sys.path.insert(0, "debian/lib/python")
rules_defs = dict((match.group(1), match.group(2))
for line in open('debian/rules.defs')
for match in [re.match(r'(\w+)\s*:=\s*(.*)\n', line)])
sys.path.append('/usr/share/linux-support-%s/lib/python' %
rules_defs['KERNELVERSION'])
from debian_linux.firmware import FirmwareWhence
from config import Config, pattern_to_re
class DistState(Enum):
undistributable = 1
non_free = 2
free = 3
def is_source_available(section):
for file_info in section.files.values():
if not (file_info.source
or file_info.binary.endswith('.txt')
or file_info.binary.endswith('.cis')):
return False
return True
def check_section(section):
if section.licence is None:
# Maybe undistributable
return DistState.undistributable
elif re.search(r'^BSD\b'
r'|^GPLv2 or OpenIB\.org BSD\b'
r'|\bPermission\s+is\s+hereby\s+granted\s+for\s+the\s+'
r'distribution\s+of\s+this\s+firmware\s+(?:data|image)\b'
r'(?!\s+as\s+part\s+of)'
r'|\bRedistribution\s+and\s+use\s+in(?:\s+source\s+and)?'
r'\s+binary\s+forms\b'
r'|\bPermission\s+is\s+hereby\s+granted\b[^.]+\sto'
r'\s+deal\s+in\s+the\s+Software\s+without'
r'\s+restriction\b'
r'|\bredistributable\s+in\s+binary\s+form\b'
r'|\bgrants\s+permission\s+to\s+use\s+and\s+redistribute'
r'\s+these\s+firmware\s+files\b',
section.licence):
return (DistState.free if is_source_available(section)
else DistState.non_free)
elif re.match(r'^(?:D|Red)istributable\b', section.licence):
return DistState.non_free
elif re.match(r'^GPL(?:v[23]|\+)?\b|^Dual GPL(?:v[23])?/', section.licence):
return (DistState.free if is_source_available(section)
else DistState.undistributable)
else:
# Unrecognised and probably undistributable
return DistState.undistributable
def main(source_dir='.'):
config = Config()
over_dirs = ['debian/config/' + package for
package in config['base',]['packages']]
with open("debian/copyright") as f:
exclusions = deb822.Deb822(f).get("Files-Excluded", '').strip().split()
package_file_res = []
for package in config['base',]['packages']:
config_entry = config['base', package]
package_file_res.append(
([pattern_to_re(pattern)
for pattern in config_entry['files']],
[pattern_to_re(pattern)
for pattern in config_entry.get('files-exclude', [])])
)
for section in FirmwareWhence(open(os.path.join(source_dir, 'WHENCE'))):
dist_state = check_section(section)
for file_info in section.files.values():
if dist_state == DistState.non_free:
if not any(fnmatch.fnmatch(file_info.binary, exclusion)
for exclusion in exclusions):
if any(
(any(inc_re.fullmatch(file_info.binary)
for inc_re in inc_res)
and not any(exc_re.fullmatch(file_info.binary)
for exc_re in exc_res))
for inc_res, exc_res in package_file_res
):
update_file(source_dir, over_dirs, file_info.binary)
elif os.path.isfile(file_info.binary):
print('I: %s is not included in any binary package' %
file_info.binary)
else:
print('I: %s: could be added' % file_info.binary)
elif dist_state == DistState.undistributable:
if os.path.isfile(file_info.binary):
print('W: %s appears to be undistributable' %
file_info.binary)
def update_file(source_dir, over_dirs, filename):
source_file = os.path.join(source_dir, filename)
for over_dir in over_dirs:
for over_file in ([os.path.join(over_dir, filename)] +
glob.glob(os.path.join(over_dir, filename + '-*'))):
if os.path.isfile(over_file):
if not filecmp.cmp(source_file, over_file, True):
print('I: %s: changed' % filename)
return
if __name__ == '__main__':
main(*sys.argv[1:])
|