Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / tools / checklicenses.py
blob115adb35e9af38da5185690c2fbc6e97aeab6877
1 #!/usr/bin/env python3
2 # Copyright (c) 2013 The Chromium Authors. All rights reserved.
4 # SPDX-License-Identifier: BSD-3-Clause
6 """Makes sure that all files contain proper licensing information."""
9 import optparse
10 import os.path
11 import subprocess
12 import sys
15 def PrintUsage():
16 print("""Usage: python checklicenses.py [--root <root>] [tocheck]
17 --root Specifies the repository root. This defaults to ".." relative
18 to the script file. This will be correct given the normal location
19 of the script in "<root>/tools".
21 --ignore-suppressions Ignores path-specific allowed license. Useful when
22 trying to remove a suppression/allowed entry.
24 --list-allowed Print a list of allowed licenses and exit.
26 tocheck Specifies the directory, relative to root, to check. This defaults
27 to "." so it checks everything.
29 Examples:
30 python checklicenses.py
31 python checklicenses.py --root ~/chromium/src third_party""")
34 ALLOWED_LICENSES = [
35 'BSD (1 clause)',
36 'BSD (2 clause)',
37 'BSD (2 clause) GPL (v2 or later)',
38 'BSD (3 clause)',
39 'BSD (4 clause (University of California-Specific))',
40 'GPL (v2 or later)',
41 'ISC',
42 'ISC GPL (v2 or later)',
43 'LGPL (v2 or later)',
44 'LGPL (v2.1 or later)',
45 'MIT/X11 (BSD like)',
46 'Public domain',
47 'Public domain GPL (v2 or later)',
48 'Public domain MIT/X11 (BSD like)',
49 'zlib/libpng',
50 'zlib/libpng GPL (v2 or later)',
54 PATH_SPECIFIC_ALLOWED_LICENSES = {
55 'wsutil/strnatcmp.c': [
56 'Zlib',
58 'wsutil/strnatcmp.h': [
59 'Zlib',
61 'resources/protocols/dtds': [
62 'UNKNOWN',
64 'resources/protocols/diameter/dictionary.dtd': [
65 'UNKNOWN',
67 'resources/protocols/wimaxasncp/dictionary.dtd': [
68 'UNKNOWN',
70 'doc/': [
71 'UNKNOWN',
73 'doc/custom_layer_chm.xsl': [
74 'UNKNOWN',
76 'doc/custom_layer_single_html.xsl': [
77 'UNKNOWN',
79 'fix': [
80 'UNKNOWN',
82 'wsutil/g711.c': [
83 'UNKNOWN',
85 'packaging/macosx': [
86 'UNKNOWN',
88 'epan/except.c': [
89 'UNKNOWN',
91 'epan/except.h': [
92 'UNKNOWN',
94 # Generated header files by lex/lemon/whatever
95 'epan/dtd_grammar.h': [
96 'UNKNOWN',
98 'epan/dfilter/grammar.h': [
99 'UNKNOWN',
101 'epan/dfilter/grammar.c': [
102 'UNKNOWN',
104 'epan/dissectors/packet-ieee80211-radiotap-iter.': [ # Using ISC license only
105 'ISC GPL (v2)'
107 # Mentions BSD-3-clause twice due to embedding of code:
108 'epan/dissectors/packet-communityid.c': [
109 'BSD (3 clause) BSD (3 clause)',
111 'plugins/mate/mate_grammar.h': [
112 'UNKNOWN',
114 'vcs_version.h': [
115 'UNKNOWN',
117 # Special IDL license that appears to be compatible as far as I (not a
118 # lawyer) can tell. See
119 # https://lists.wireshark.org/archives/wireshark-dev/201310/msg00234.html
120 'epan/dissectors/pidl/idl_types.h': [
121 'UNKNOWN',
123 # The following tools are under incompatible licenses (mostly GPLv3 or
124 # GPLv3+), but this is OK since they are not actually linked into Wireshark
125 'tools/pidl': [
126 'UNKNOWN',
128 'tools/lemon': [
129 'UNKNOWN',
131 'tools/licensecheck.pl': [
132 'GPL (v2)'
134 '.gitlab/': [
135 'UNKNOWN',
137 'wsutil/dtoa.c': [
138 'dtoa',
140 'wsutil/dtoa.h': [
141 'dtoa',
143 'wsutil/safe-math.h': [ # Public domain (CC0)
144 'UNKNOWN',
148 def check_licenses(options, args):
149 if options.list_allowed:
150 print('\n'.join(ALLOWED_LICENSES))
151 sys.exit(0)
153 # Figure out which directory we have to check.
154 if len(args) == 0:
155 # No directory to check specified, use the repository root.
156 start_dir = options.base_directory
157 elif len(args) == 1:
158 # Directory specified. Start here. It's supposed to be relative to the
159 # base directory.
160 start_dir = os.path.abspath(os.path.join(options.base_directory, args[0]))
161 else:
162 # More than one argument, we don't handle this.
163 PrintUsage()
164 return 1
166 print("Using base directory: %s" % options.base_directory)
167 print("Checking: %s" % start_dir)
168 print("")
170 licensecheck_path = os.path.abspath(os.path.join(options.base_directory,
171 'tools',
172 'licensecheck.pl'))
174 licensecheck = subprocess.Popen([licensecheck_path,
175 '-l', '160',
176 '-r', start_dir],
177 stdout=subprocess.PIPE,
178 stderr=subprocess.PIPE)
179 stdout, stderr = licensecheck.communicate()
180 stdout = stdout.decode('utf-8')
181 stderr = stderr.decode('utf-8')
182 if options.verbose:
183 print('----------- licensecheck stdout -----------')
184 print(stdout)
185 print('--------- end licensecheck stdout ---------')
186 if licensecheck.returncode != 0 or stderr:
187 print('----------- licensecheck stderr -----------')
188 print(stderr)
189 print('--------- end licensecheck stderr ---------')
190 print("\nFAILED\n")
191 return 1
193 success = True
194 exit_status = 0
195 for line in stdout.splitlines():
196 filename, license = line.split(':', 1)
197 filename = os.path.relpath(filename.strip(), options.base_directory)
199 # All files in the build output directory are generated one way or another.
200 # There's no need to check them.
201 if os.path.dirname(filename).startswith('build'):
202 continue
204 # For now we're just interested in the license.
205 license = license.replace('*No copyright*', '').strip()
207 # Skip generated files.
208 if 'GENERATED FILE' in license:
209 continue
211 # Support files which provide a choice between licenses.
212 if any(item in ALLOWED_LICENSES for item in license.split(';')):
213 continue
215 if not options.ignore_suppressions:
216 found_path_specific = False
217 for prefix in PATH_SPECIFIC_ALLOWED_LICENSES:
218 if (filename.startswith(prefix) and
219 license in PATH_SPECIFIC_ALLOWED_LICENSES[prefix]):
220 found_path_specific = True
221 break
222 if found_path_specific:
223 continue
225 reason = "License '%s' for '%s' is not allowed." % (license, filename)
226 success = False
227 print(reason)
228 exit_status = 1
230 if success:
231 print("\nSUCCESS\n")
232 return 0
233 else:
234 print("\nFAILED\n")
235 return exit_status
238 def main():
239 default_root = os.path.abspath(
240 os.path.join(os.path.dirname(__file__), '..'))
241 option_parser = optparse.OptionParser()
242 option_parser.add_option('--root', default=default_root,
243 dest='base_directory',
244 help='Specifies the repository root. This defaults '
245 'to "../.." relative to the script file, which '
246 'will normally be the repository root.')
247 option_parser.add_option('-v', '--verbose', action='store_true',
248 default=False, help='Print debug logging')
249 option_parser.add_option('--list-allowed',
250 action='store_true',
251 default=False,
252 help='Print a list of allowed licenses and exit.')
253 option_parser.add_option('--ignore-suppressions',
254 action='store_true',
255 default=False,
256 help='Ignore path-specific allowed license.')
257 options, args = option_parser.parse_args()
258 return check_licenses(options, args)
261 if '__main__' == __name__:
262 sys.exit(main())