| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: license.c,v 1.1.1.2.6.2 2009/06/05 17:02:00 snj Exp $ */ | | 1 | /* $NetBSD: license.c,v 1.1.1.2.6.3 2009/06/21 11:42:52 bouyer Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2009 Joerg Sonnenberger <joerg@NetBSD.org>. | | 4 | * Copyright (c) 2009 Joerg Sonnenberger <joerg@NetBSD.org>. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Redistribution and use in source and binary forms, with or without | | 7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions | | 8 | * modification, are permitted provided that the following conditions |
9 | * are met: | | 9 | * are met: |
10 | * | | 10 | * |
11 | * 1. Redistributions of source code must retain the above copyright | | 11 | * 1. Redistributions of source code must retain the above copyright |
12 | * notice, this list of conditions and the following disclaimer. | | 12 | * notice, this list of conditions and the following disclaimer. |
13 | * 2. Redistributions in binary form must reproduce the above copyright | | 13 | * 2. Redistributions in binary form must reproduce the above copyright |
14 | * notice, this list of conditions and the following disclaimer in | | 14 | * notice, this list of conditions and the following disclaimer in |
| @@ -41,27 +41,27 @@ | | | @@ -41,27 +41,27 @@ |
41 | #include <stdlib.h> | | 41 | #include <stdlib.h> |
42 | #include <string.h> | | 42 | #include <string.h> |
43 | | | 43 | |
44 | #include "lib.h" | | 44 | #include "lib.h" |
45 | | | 45 | |
46 | #define HASH_SIZE 521 | | 46 | #define HASH_SIZE 521 |
47 | | | 47 | |
48 | const char *default_acceptable_licenses = | | 48 | const char *default_acceptable_licenses = |
49 | "public-domain " | | 49 | "public-domain " |
50 | "gnu-fdl-v1.1 gnu-fdl-v1.2 gnu-fdl-v1.3 " | | 50 | "gnu-fdl-v1.1 gnu-fdl-v1.2 gnu-fdl-v1.3 " |
51 | "gnu-gpl-v2 gnu-lgpl-v2 gnu-lgpl-v2.1 " | | 51 | "gnu-gpl-v2 gnu-lgpl-v2 gnu-lgpl-v2.1 " |
52 | "gnu-gpl-v3 gnu-lgpl-v3 " | | 52 | "gnu-gpl-v3 gnu-lgpl-v3 " |
53 | "original-bsd modified-bsd " | | 53 | "original-bsd modified-bsd " |
54 | "x11 " | | 54 | "x11 mit miros " |
55 | "apache-1.1 apache-2.0 " | | 55 | "apache-1.1 apache-2.0 " |
56 | "artistic artistic-2.0 " | | 56 | "artistic artistic-2.0 " |
57 | "cddl-1.0 " | | 57 | "cddl-1.0 " |
58 | "cpl-1.0 " | | 58 | "cpl-1.0 " |
59 | "open-font-license "; | | 59 | "open-font-license "; |
60 | | | 60 | |
61 | #ifdef DEBUG | | 61 | #ifdef DEBUG |
62 | static size_t hash_collisions; | | 62 | static size_t hash_collisions; |
63 | #endif | | 63 | #endif |
64 | | | 64 | |
65 | static char **license_hash[HASH_SIZE]; | | 65 | static char **license_hash[HASH_SIZE]; |
66 | static const char license_spaces[] = " \t\n"; | | 66 | static const char license_spaces[] = " \t\n"; |
67 | static const char license_chars[] = "abcdefghijklmnopqrstuvwxyz0123456789_-."; | | 67 | static const char license_chars[] = "abcdefghijklmnopqrstuvwxyz0123456789_-."; |
| @@ -146,130 +146,149 @@ acceptable_license_internal(const char * | | | @@ -146,130 +146,149 @@ acceptable_license_internal(const char * |
146 | license_hash[slot][i][len] == '\0') | | 146 | license_hash[slot][i][len] == '\0') |
147 | return 1; | | 147 | return 1; |
148 | } | | 148 | } |
149 | | | 149 | |
150 | return 0; | | 150 | return 0; |
151 | } | | 151 | } |
152 | | | 152 | |
153 | int | | 153 | int |
154 | acceptable_license(const char *license) | | 154 | acceptable_license(const char *license) |
155 | { | | 155 | { |
156 | size_t len; | | 156 | size_t len; |
157 | | | 157 | |
158 | len = strlen(license); | | 158 | len = strlen(license); |
159 | if (strspn(license, license_chars) != len) | | 159 | if (strspn(license, license_chars) != len) { |
| | | 160 | warnx("Invalid character in license name at position %zu", len); |
160 | return -1; | | 161 | return -1; |
| | | 162 | } |
161 | | | 163 | |
162 | return acceptable_license_internal(license, len); | | 164 | return acceptable_license_internal(license, len); |
163 | } | | 165 | } |
164 | | | 166 | |
165 | static int | | 167 | static int |
166 | acceptable_pkg_license_internal(const char **licensep, int toplevel) | | 168 | acceptable_pkg_license_internal(const char **licensep, int toplevel, const char *start) |
167 | { | | 169 | { |
168 | const char *license = *licensep; | | 170 | const char *license = *licensep; |
169 | int need_parenthesis, is_true = 0; | | 171 | int need_parenthesis, is_true = 0; |
170 | int expr_type = 0; /* 0: unset, 1: or, 2: and */ | | 172 | int expr_type = 0; /* 0: unset, 1: or, 2: and */ |
171 | size_t len; | | 173 | size_t len; |
172 | | | 174 | |
173 | license += strspn(license, license_spaces); | | 175 | license += strspn(license, license_spaces); |
174 | | | 176 | |
175 | if (*license == '(' && !toplevel) { | | 177 | if (*license == '(' && !toplevel) { |
176 | need_parenthesis = 1; | | 178 | need_parenthesis = 1; |
177 | ++license; | | 179 | ++license; |
178 | license += strspn(license, license_spaces); | | 180 | license += strspn(license, license_spaces); |
179 | } else { | | 181 | } else { |
180 | need_parenthesis = 0; | | 182 | need_parenthesis = 0; |
181 | } | | 183 | } |
182 | | | 184 | |
183 | for (;;) { | | 185 | for (;;) { |
184 | if (*license == '(') { | | 186 | if (*license == '(') { |
185 | switch (acceptable_pkg_license_internal(&license, 0)) { | | 187 | switch (acceptable_pkg_license_internal(&license, 0, start)) { |
186 | case -1: | | 188 | case -1: |
187 | return -1; | | 189 | return -1; |
188 | case 0: | | 190 | case 0: |
189 | if (expr_type == 2) | | 191 | if (expr_type == 2) |
190 | is_true = 0; | | 192 | is_true = 0; |
191 | break; | | 193 | break; |
192 | case 1: | | 194 | case 1: |
193 | is_true = 1; | | 195 | is_true = 1; |
194 | break; | | 196 | break; |
195 | } | | 197 | } |
196 | license += strspn(license, license_spaces); | | 198 | license += strspn(license, license_spaces); |
197 | } else { | | 199 | } else { |
198 | len = strspn(license, license_chars); | | 200 | len = strspn(license, license_chars); |
199 | if (len == 0) | | 201 | if (len == 0) { |
| | | 202 | warnx("Invalid character in license name at position %zu", license - start + 1); |
200 | return -1; | | 203 | return -1; |
| | | 204 | } |
201 | | | 205 | |
202 | if (acceptable_license_internal(license, len)) { | | 206 | if (acceptable_license_internal(license, len)) { |
203 | if (expr_type != 2) | | 207 | if (expr_type != 2) |
204 | is_true = 1; | | 208 | is_true = 1; |
205 | } else if (expr_type == 2) { | | 209 | } else if (expr_type == 2) { |
206 | is_true = 0; | | 210 | is_true = 0; |
207 | } | | 211 | } |
208 | | | 212 | |
209 | license += len; | | 213 | license += len; |
210 | | | 214 | |
211 | len = strspn(license, license_spaces); | | 215 | len = strspn(license, license_spaces); |
212 | if (len == 0 && *license && *license != ')') | | 216 | if (len == 0 && *license && *license != ')') { |
| | | 217 | warnx("Missing space at position %zu", license - start + 1); |
213 | return -1; | | 218 | return -1; |
| | | 219 | } |
214 | license += len; | | 220 | license += len; |
215 | } | | 221 | } |
216 | | | 222 | |
217 | if (*license == ')') { | | 223 | if (*license == ')') { |
218 | if (!need_parenthesis) | | 224 | if (!need_parenthesis) { |
| | | 225 | warnx("Missing open parenthesis at position %zu", license - start + 1); |
219 | return -1; | | 226 | return -1; |
| | | 227 | } |
220 | *licensep = license + 1; | | 228 | *licensep = license + 1; |
221 | return is_true; | | 229 | return is_true; |
222 | } | | 230 | } |
223 | if (*license == '\0') { | | 231 | if (*license == '\0') { |
224 | if (need_parenthesis) | | 232 | if (need_parenthesis) { |
| | | 233 | warnx("Unbalanced parenthesis at position %zu", license - start + 1); |
225 | return -1; | | 234 | return -1; |
| | | 235 | } |
226 | *licensep = license; | | 236 | *licensep = license; |
227 | return is_true; | | 237 | return is_true; |
228 | } | | 238 | } |
229 | | | 239 | |
230 | if (strncmp(license, "AND", 3) == 0) { | | 240 | if (strncmp(license, "AND", 3) == 0) { |
231 | if (expr_type == 1) | | 241 | if (expr_type == 1) { |
| | | 242 | warnx("Invalid operator in OR expression at position %zu", license - start + 1); |
232 | return -1; | | 243 | return -1; |
| | | 244 | } |
233 | expr_type = 2; | | 245 | expr_type = 2; |
234 | license += 3; | | 246 | license += 3; |
235 | } else if (strncmp(license, "OR", 2) == 0) { | | 247 | } else if (strncmp(license, "OR", 2) == 0) { |
236 | if (expr_type == 2) | | 248 | if (expr_type == 2) { |
| | | 249 | warnx("Invalid operator in AND expression at position %zu", license - start + 1); |
237 | return -1; | | 250 | return -1; |
| | | 251 | } |
238 | expr_type = 1; | | 252 | expr_type = 1; |
239 | license += 2; | | 253 | license += 2; |
240 | } else { | | 254 | } else { |
| | | 255 | warnx("Invalid operator at position %zu", license - start + 1); |
241 | return -1; | | 256 | return -1; |
242 | } | | 257 | } |
243 | len = strspn(license, license_spaces); | | 258 | len = strspn(license, license_spaces); |
244 | if (len == 0 && *license != '(') | | 259 | if (len == 0 && *license != '(') { |
| | | 260 | warnx("Missing space at position %zu", license - start + 1); |
245 | return -1; | | 261 | return -1; |
| | | 262 | } |
246 | license += len; | | 263 | license += len; |
247 | } | | 264 | } |
248 | | | 265 | |
249 | return is_true; | | 266 | return is_true; |
250 | } | | 267 | } |
251 | | | 268 | |
252 | int | | 269 | int |
253 | acceptable_pkg_license(const char *license) | | 270 | acceptable_pkg_license(const char *license) |
254 | { | | 271 | { |
255 | int ret; | | 272 | int ret; |
256 | | | 273 | |
257 | ret = acceptable_pkg_license_internal(&license, 1); | | 274 | ret = acceptable_pkg_license_internal(&license, 1, license); |
258 | if (ret == -1) | | 275 | if (ret == -1) |
259 | return -1; | | 276 | return -1; |
260 | license += strspn(license, license_spaces); | | 277 | license += strspn(license, license_spaces); |
261 | if (*license) | | 278 | if (*license) { |
| | | 279 | warnx("Trailing garbage in license specification"); |
262 | return -1; | | 280 | return -1; |
| | | 281 | } |
263 | return ret; | | 282 | return ret; |
264 | } | | 283 | } |
265 | | | 284 | |
266 | void | | 285 | void |
267 | load_license_lists(void) | | 286 | load_license_lists(void) |
268 | { | | 287 | { |
269 | if (add_licenses(getenv("PKGSRC_ACCEPTABLE_LICENSES"))) | | 288 | if (add_licenses(getenv("PKGSRC_ACCEPTABLE_LICENSES"))) |
270 | errx(EXIT_FAILURE, "syntax error in PKGSRC_ACCEPTABLE_LICENSES"); | | 289 | errx(EXIT_FAILURE, "syntax error in PKGSRC_ACCEPTABLE_LICENSES"); |
271 | if (add_licenses(acceptable_licenses)) | | 290 | if (add_licenses(acceptable_licenses)) |
272 | errx(EXIT_FAILURE, "syntax error in ACCEPTABLE_LICENSES"); | | 291 | errx(EXIT_FAILURE, "syntax error in ACCEPTABLE_LICENSES"); |
273 | if (add_licenses(getenv("PKGSRC_DEFAULT_ACCEPTABLE_LICENSES"))) | | 292 | if (add_licenses(getenv("PKGSRC_DEFAULT_ACCEPTABLE_LICENSES"))) |
274 | errx(EXIT_FAILURE, "syntax error in PKGSRC_DEFAULT_ACCEPTABLE_LICENSES"); | | 293 | errx(EXIT_FAILURE, "syntax error in PKGSRC_DEFAULT_ACCEPTABLE_LICENSES"); |
275 | if (add_licenses(default_acceptable_licenses)) | | 294 | if (add_licenses(default_acceptable_licenses)) |