1 /* $NetBSD: license.c,v 1.10 2009/10/25 21:32:48 wiz Exp $ */
4 * Copyright (c) 2009 Joerg Sonnenberger <joerg@NetBSD.org>.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
24 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
28 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48 const char *default_acceptable_licenses
=
50 "gnu-fdl-v1.1 gnu-fdl-v1.2 gnu-fdl-v1.3 "
51 "gnu-gpl-v2 gnu-lgpl-v2 gnu-lgpl-v2.1 "
52 "gnu-gpl-v3 gnu-lgpl-v3 "
53 "original-bsd modified-bsd 2-clause-bsd "
55 "apache-1.1 apache-2.0 "
56 "artistic artistic-2.0 "
64 static size_t hash_collisions
;
67 static char **license_hash
[HASH_SIZE
];
68 static const char license_spaces
[] = " \t\n";
69 static const char license_chars
[] =
70 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-.";
73 hash_license(const char *license
, size_t len
)
77 for (hash
= 0; *license
&& len
; ++license
, --len
)
78 hash
= *license
+ hash
* 32;
79 return hash
% HASH_SIZE
;
83 add_license_internal(const char *license
, size_t len
)
88 slot
= hash_license(license
, len
);
90 new_license
= malloc(len
+ 1);
91 memcpy(new_license
, license
, len
);
92 new_license
[len
] = '\0';
94 if (license_hash
[slot
] == NULL
) {
95 license_hash
[slot
] = calloc(sizeof(char *), 2);
96 license_hash
[slot
][0] = new_license
;
98 for (i
= 0; license_hash
[slot
][i
]; ++i
) {
99 if (!memcmp(license_hash
[slot
][i
], license
, len
) &&
100 license_hash
[slot
][i
][len
] == '\0') {
110 license_hash
[slot
] = realloc(license_hash
[slot
],
111 sizeof(char *) * (i
+ 2));
112 license_hash
[slot
][i
] = new_license
;
113 license_hash
[slot
][i
+ 1] = NULL
;
118 add_licenses(const char *line
)
125 for (line
+= strspn(line
, license_spaces
); line
; ) {
126 next
= line
+ strspn(line
, license_chars
);
128 return *line
? -1 : 0;
129 add_license_internal(line
, next
- line
);
130 line
= next
+ strspn(next
, license_spaces
);
132 return *line
? -1 : 0;
138 acceptable_license_internal(const char *license
, size_t len
)
142 slot
= hash_license(license
, len
);
144 if (license_hash
[slot
] == NULL
)
147 for (i
= 0; license_hash
[slot
][i
]; ++i
) {
148 if (strncmp(license_hash
[slot
][i
], license
, len
) == 0 &&
149 license_hash
[slot
][i
][len
] == '\0')
157 acceptable_license(const char *license
)
161 len
= strlen(license
);
162 if (strspn(license
, license_chars
) != len
) {
163 warnx("Invalid character in license name at position %zu", len
);
167 return acceptable_license_internal(license
, len
);
171 acceptable_pkg_license_internal(const char **licensep
, int toplevel
, const char *start
)
173 const char *license
= *licensep
;
174 int need_parenthesis
, is_true
= 0;
175 int expr_type
= 0; /* 0: unset, 1: or, 2: and */
178 license
+= strspn(license
, license_spaces
);
180 if (*license
== '(' && !toplevel
) {
181 need_parenthesis
= 1;
183 license
+= strspn(license
, license_spaces
);
185 need_parenthesis
= 0;
189 if (*license
== '(') {
190 switch (acceptable_pkg_license_internal(&license
, 0, start
)) {
201 license
+= strspn(license
, license_spaces
);
203 len
= strspn(license
, license_chars
);
205 warnx("Invalid character in license name at position %zu", license
- start
+ 1);
209 if (acceptable_license_internal(license
, len
)) {
212 } else if (expr_type
== 2) {
218 len
= strspn(license
, license_spaces
);
219 if (len
== 0 && *license
&& *license
!= ')') {
220 warnx("Missing space at position %zu", license
- start
+ 1);
226 if (*license
== ')') {
227 if (!need_parenthesis
) {
228 warnx("Missing open parenthesis at position %zu", license
- start
+ 1);
231 *licensep
= license
+ 1;
234 if (*license
== '\0') {
235 if (need_parenthesis
) {
236 warnx("Unbalanced parenthesis at position %zu", license
- start
+ 1);
243 if (strncmp(license
, "AND", 3) == 0) {
244 if (expr_type
== 1) {
245 warnx("Invalid operator in OR expression at position %zu", license
- start
+ 1);
250 } else if (strncmp(license
, "OR", 2) == 0) {
251 if (expr_type
== 2) {
252 warnx("Invalid operator in AND expression at position %zu", license
- start
+ 1);
258 warnx("Invalid operator at position %zu", license
- start
+ 1);
261 len
= strspn(license
, license_spaces
);
262 if (len
== 0 && *license
!= '(') {
263 warnx("Missing space at position %zu", license
- start
+ 1);
271 acceptable_pkg_license(const char *license
)
275 ret
= acceptable_pkg_license_internal(&license
, 1, license
);
278 license
+= strspn(license
, license_spaces
);
280 warnx("Trailing garbage in license specification");
287 load_license_lists(void)
289 if (add_licenses(getenv("PKGSRC_ACCEPTABLE_LICENSES")))
290 errx(EXIT_FAILURE
, "syntax error in PKGSRC_ACCEPTABLE_LICENSES");
291 if (add_licenses(acceptable_licenses
))
292 errx(EXIT_FAILURE
, "syntax error in ACCEPTABLE_LICENSES");
293 if (add_licenses(getenv("PKGSRC_DEFAULT_ACCEPTABLE_LICENSES")))
294 errx(EXIT_FAILURE
, "syntax error in PKGSRC_DEFAULT_ACCEPTABLE_LICENSES");
295 if (add_licenses(default_acceptable_licenses
))
296 errx(EXIT_FAILURE
, "syntax error in DEFAULT_ACCEPTABLE_LICENSES");