1 /* $NetBSD: license.c,v 1.1 2009/04/25 21:31:14 joerg 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
=
51 "gnu-lgpl-v2 gnu-lgpl-v2.1 "
52 "gnu-gpl-v3 gnu-lgpl-v3 "
53 "original-bsd modified-bsd x11 "
55 "artistic artistic-2.0 "
60 static size_t hash_collisions
;
63 static char **license_hash
[HASH_SIZE
];
64 static const char license_spaces
[] = " \t\n";
65 static const char license_chars
[] = "abcdefghijklmnopqrstuvwxyz0123456789_-.";
68 hash_license(const char *license
, size_t len
)
72 for (hash
= 0; *license
&& len
; ++license
, --len
)
73 hash
= *license
+ hash
* 32;
74 return hash
% HASH_SIZE
;
78 add_license_internal(const char *license
, size_t len
)
83 slot
= hash_license(license
, len
);
85 new_license
= malloc(len
+ 1);
86 memcpy(new_license
, license
, len
);
87 new_license
[len
] = '\0';
89 if (license_hash
[slot
] == NULL
) {
90 license_hash
[slot
] = calloc(sizeof(char *), 2);
91 license_hash
[slot
][0] = new_license
;
93 for (i
= 0; license_hash
[slot
][i
]; ++i
) {
94 if (!memcmp(license_hash
[slot
][i
], license
, len
) &&
95 license_hash
[slot
][i
][len
] == '\0') {
105 license_hash
[slot
] = realloc(license_hash
[slot
],
106 sizeof(char *) * (i
+ 2));
107 license_hash
[slot
][i
] = new_license
;
108 license_hash
[slot
][i
+ 1] = NULL
;
113 add_licenses(const char *line
)
120 for (line
+= strspn(line
, license_spaces
); line
; ) {
121 next
= line
+ strspn(line
, license_chars
);
123 return *line
? -1 : 0;
124 add_license_internal(line
, next
- line
);
125 line
= next
+ strspn(next
, license_spaces
);
127 return *line
? -1 : 0;
133 acceptable_license_internal(const char *license
, size_t len
)
137 slot
= hash_license(license
, len
);
139 if (license_hash
[slot
] == NULL
)
142 for (i
= 0; license_hash
[slot
][i
]; ++i
) {
143 if (strncmp(license_hash
[slot
][i
], license
, len
) == 0 &&
144 license_hash
[slot
][i
][len
] == '\0')
152 acceptable_license(const char *license
)
156 len
= strlen(license
);
157 if (strspn(license
, license_chars
) != len
)
160 return acceptable_license_internal(license
, len
);
164 acceptable_pkg_license_internal(const char **licensep
, int toplevel
)
166 const char *license
= *licensep
;
167 int need_parenthesis
, is_true
= 0;
168 int expr_type
= 0; /* 0: unset, 1: or, 2: and */
171 license
+= strspn(license
, license_spaces
);
173 if (*license
== '(' && !toplevel
) {
174 need_parenthesis
= 1;
176 license
+= strspn(license
, license_spaces
);
178 need_parenthesis
= 0;
182 if (*license
== '(') {
183 switch (acceptable_pkg_license_internal(&license
, 0)) {
194 license
+= strspn(license
, license_spaces
);
196 len
= strspn(license
, license_chars
);
200 if (acceptable_license_internal(license
, len
)) {
203 } else if (expr_type
== 2) {
209 len
= strspn(license
, license_spaces
);
210 if (len
== 0 && *license
&& *license
!= ')')
215 if (*license
== ')') {
216 if (!need_parenthesis
)
218 *licensep
= license
+ 1;
221 if (*license
== '\0') {
222 if (need_parenthesis
)
228 if (strncmp(license
, "AND", 3) == 0) {
233 } else if (strncmp(license
, "OR", 2) == 0) {
241 len
= strspn(license
, license_spaces
);
242 if (len
== 0 && *license
!= '(')
251 acceptable_pkg_license(const char *license
)
255 ret
= acceptable_pkg_license_internal(&license
, 1);
258 license
+= strspn(license
, license_spaces
);
265 load_license_lists(void)
267 if (add_licenses(getenv("PKGSRC_ACCEPTABLE_LICENSES")))
268 errx(EXIT_FAILURE
, "syntax error in PKGSRC_ACCEPTABLE_LICENSES");
269 if (add_licenses(acceptable_licenses
))
270 errx(EXIT_FAILURE
, "syntax error in ACCEPTABLE_LICENSES");
271 if (add_licenses(getenv("PKGSRC_DEFAULT_ACCEPTABLE_LICENSES")))
272 errx(EXIT_FAILURE
, "syntax error in PKGSRC_DEFAULT_ACCEPTABLE_LICENSES");
273 if (add_licenses(default_acceptable_licenses
))
274 errx(EXIT_FAILURE
, "syntax error in DEFAULT_ACCEPTABLE_LICENSES");