FOSSology  4.4.0
Open Source License Compliance by Open Source Software
ninkawrapper.cc
1 /*
2  SPDX-FileCopyrightText: © 2014-2015 Siemens AG
3 
4  SPDX-License-Identifier: GPL-2.0-only
5 */
6 
7 #include <iostream>
8 #include <boost/tokenizer.hpp>
9 #include "ninkawrapper.hpp"
10 #include "utils.hpp"
11 
12 string scanFileWithNinka(const State& state, const fo::File& file)
13 {
14  FILE* in;
15  char buffer[512];
16  string command = "ninka " + file.getFileName();
17  string result;
18 
19  if (!(in = popen(command.c_str(), "r")))
20  {
21  cout << "could not execute ninka command: " << command << endl;
22  bail(1);
23  }
24 
25  while (fgets(buffer, sizeof(buffer), in) != NULL)
26  {
27  result += buffer;
28  }
29 
30  if (pclose(in) != 0)
31  {
32  cout << "could not execute ninka command: " << command << endl;
33  bail(1);
34  }
35 
36  return result;
37 }
38 
39 vector<string> extractLicensesFromNinkaResult(string ninkaResult)
40 {
41  string licensePart = extractLicensePartFromNinkaResult(ninkaResult);
42  return splitLicensePart(licensePart);
43 }
44 
45 // Ninka result format: filename;license1,license2,...,licenseN;details...
46 string extractLicensePartFromNinkaResult(string ninkaResult)
47 {
48  string delimiters = ";\r\n";
49 
50  size_t first = ninkaResult.find_first_of(delimiters);
51  size_t last = ninkaResult.find_first_of(delimiters, first + 1);
52 
53  return ninkaResult.substr(first + 1, last - 1 - first);
54 }
55 
56 vector<string> splitLicensePart(string licensePart)
57 {
58  typedef boost::tokenizer<boost::char_separator<char>> tokenizer;
59  boost::char_separator<char> separator(",");
60  tokenizer tokens(licensePart, separator);
61 
62  vector<string> licenses;
63 
64  for (tokenizer::iterator iter = tokens.begin(); iter != tokens.end(); ++iter)
65  {
66  licenses.push_back(*iter);
67  }
68 
69  return licenses;
70 }
71 
72 vector<LicenseMatch> createMatches(vector<string> ninkaLicenseNames)
73 {
74  vector<LicenseMatch> matches;
75  for (vector<string>::const_iterator it = ninkaLicenseNames.begin(); it != ninkaLicenseNames.end(); ++it)
76  {
77  const string& ninkaLicenseName = *it;
78  if(isLicenseCollection(ninkaLicenseName,matches))
79  {
80  continue;
81  }
82  string fossologyLicenseName = mapLicenseFromNinkaToFossology(ninkaLicenseName);
83  unsigned percentage = (ninkaLicenseName.compare("NONE") == 0 || ninkaLicenseName.compare("UNKNOWN") == 0) ? 0 : 100;
84  LicenseMatch match = LicenseMatch(fossologyLicenseName, percentage);
85  matches.push_back(match);
86  }
87  return matches;
88 }
89 
90 string mapLicenseFromNinkaToFossology(string name)
91 {
92  if (name.compare("NONE") == 0) return string("No_license_found");
93  if (name.compare("UNKNOWN") == 0) return string("UnclassifiedLicense");
94  if (name.compare("spdxMIT") ==0 ) return string("MIT");
95  if (name.compare("Apachev1.0") == 0) return string("Apache-1.0");
96  if (name.compare("Apachev2") == 0
97  || name.compare("Apache-2") == 0) return string("Apache-2.0");
98  if (name.compare("GPLv1+") == 0) return string("GPL-1.0+");
99  if (name.compare("GPLv2") == 0) return string("GPL-2.0");
100  if (name.compare("GPLv2+") == 0) return string("GPL-2.0+");
101  if (name.compare("GPLv3") == 0) return string("GPL-3.0");
102  if (name.compare("GPLv3+") == 0) return string("GPL-3.0+");
103  if (name.compare("LGPLv2") == 0) return string("LGPL-2.0");
104  if (name.compare("LGPLv2+") == 0) return string("LGPL-2.0+");
105  if (name.compare("LGPLv2_1") == 0
106  || name.compare("LGPLv2.1") == 0) return string("LGPL-2.1");
107  if (name.compare("LGPLv2_1+") == 0) return string("LGPL-2.1+");
108  if (name.compare("LGPLv3") == 0) return string("LGPL-3.0");
109  if (name.compare("LGPLv3+") == 0) return string("LGPL-3.0+");
110  if (name.compare("GPLnoVersion") == 0) return string("GPL");
111  if (name.compare("LesserGPLnoVersion") == 0
112  || name.compare("LibraryGPLnoVersion")==0) return string("LGPL");
113  if (name.compare("intelBSDLicense") == 0) return string("Intel-EULA");
114  if (name.compare("spdxSleepyCat") == 0
115  || name.compare("SleepyCat") == 0) return string("Sleepycat");
116  if (name.compare("spdxBSD2") == 0
117  || name.compare("BSD2") == 0) return string("BSD-2-Clause");
118  if (name.compare("spdxBSD3") == 0
119  || name.compare("BSD3") == 0) return string("BSD-3-Clause");
120  if (name.compare("BSD3") == 0) return string("BSD-4-Clause");
121  if (name.compare("spdxMIT") == 0) return string("MIT");
122  if (name.compare("ZLIB") == 0) return string("Zlib");
123  if (name.compare("openSSL") == 0
124  || name.compare("openSSLvar1") ==0
125  || name.compare("openSSLvar3") ==0) return string("OpenSSL");
126  if (name.compare("QPLt") == 0) return string("QT(Commercial)");
127  if (name.compare("Cecill") == 0) return string("CECILL");
128  if (name.compare("QPLv1") == 0) return string("QPL-1.0");
129  if (name.compare("MPLv1_1") == 0) return string("MPL-1.1");
130  if (name.compare("NPLv1_1") == 0) return string("NPL-1.1");
131  if (name.compare("MPLv1_0") == 0) return string("MPL-1.0");
132  if (name.compare("NPLv1_0") == 0) return string("NPL-1.0");
133  if (name.compare("MPLv2") == 0) return string("MPL-2.0");
134  if (name.compare("MITVariant") == 0) return string("MIT-style");
135  if (name.compare("EPLv1") == 0) return string("EPL-1.0");
136  if (name.compare("CDDLic") == 0) return string("CDDL");
137  if (name.compare("CDDLicV1") == 0) return string("CDDL-1.0");
138  if (name.compare("publicDomain") == 0) return string("Public-domain");
139  if (name.compare("ClassPathExceptionGPLv2") == 0) return string("GPL-2.0-with-classpath-exception");
140  if (name.compare("CPLv1") == 0) return string("CPL-1.0");
141  if (name.compare("CPLv0.5") == 0) return string("CPL-0.5");
142  if (name.compare("SeeFile") == 0) return string("See-file");
143  if (name.compare("LibGCJLic") == 0) return string("LIBGCJ");
144  if (name.compare("W3CLic") == 0) return string("W3C");
145  if (name.compare("IBMv1") == 0) return string("IPL-1.0");
146  if (name.compare("ArtisticLicensev1") == 0) return string("Artistic-1.0");
147  if (name.compare("MX4JLicensev1") == 0) return string("MX4J-1.0");
148  if (name.compare("phpLicV3.01") == 0) return string("PHP-3.01");
149  if (name.compare("postgresql") == 0
150  || name.compare("postgresqlRef") == 0) return string("PostgreSQL");
151  if (name.compare("FSFUnlimited") == 0) return string("FSF");
152 
153  return name;
154 };
155 
156 bool isLicenseCollection(string name, vector<LicenseMatch>& matches)
157 {
158  if (name.compare("spdxBSD4") == 0)
159  {
160  matches.push_back(LicenseMatch(string("BSD-4-Clause"), 50));
161  matches.push_back(LicenseMatch(string("BSD-4-Clause-UC"), 50));
162  return true;
163  }
164  if (name.compare("GPL2orBSD3") == 0)
165  {
166  matches.push_back(LicenseMatch(string("BSD-3-Clause"), 50));
167  matches.push_back(LicenseMatch(string("GPL-2.0"), 50));
168  return true;
169  }
170  if (name.compare("LGPLv2orv3") == 0)
171  {
172  matches.push_back(LicenseMatch(string("LGPL-2.0"), 50));
173  matches.push_back(LicenseMatch(string("LGPL-3.0"), 50));
174  return true;
175  }
176  if (name.compare("LGPLv2_1orv3") == 0)
177  {
178  matches.push_back(LicenseMatch(string("LGPL-2.1"), 50));
179  matches.push_back(LicenseMatch(string("LGPL-3.0"), 50));
180  return true;
181  }
182  if (name.compare("LGPLv2+MISTAKE") == 0)
183  {
184  matches.push_back(LicenseMatch(string("LGPL-2.1+"), 50));
185  matches.push_back(LicenseMatch(string("LGPL-2.0+"), 50));
186  return true;
187  }
188  if (name.compare("LGPLv2MISTAKE") == 0)
189  {
190  matches.push_back(LicenseMatch(string("LGPL-2.1"), 50));
191  matches.push_back(LicenseMatch(string("LGPL-2.0"), 50));
192  return true;
193  }
194  if (name.compare("GPLv1orArtistic") == 0)
195  {
196  matches.push_back(LicenseMatch(string("GPL-1.0"), 50));
197  matches.push_back(LicenseMatch(string("Artistic-1.0"), 25));
198  matches.push_back(LicenseMatch(string("Artistic-2.0"), 25));
199  return true;
200  }
201  if (name.compare("GPL2orOpenIB") == 0)
202  {
203  matches.push_back(LicenseMatch(string("GPL-2.0"), 50));
204  matches.push_back(LicenseMatch(string("BSD-2-Clause"), 50));
205  return true;
206  }
207  if (name.compare("CDDLv1orGPLv2") == 0)
208  {
209  matches.push_back(LicenseMatch(string("CDDL-1.0"), 50));
210  matches.push_back(LicenseMatch(string("GPL-2.0"), 50));
211  return true;
212  }
213  if (name.compare("Apache-2orLGPLgeneric") == 0)
214  {
215  matches.push_back(LicenseMatch(string("Apache-2.0"), 50));
216  matches.push_back(LicenseMatch(string("LGPL"), 50));
217  return true;
218  }
219  if (name.compare("orLGPLVer2.1") == 0)
220  {
221  matches.push_back(LicenseMatch(string("QT(Commercial)"), 50));
222  matches.push_back(LicenseMatch(string("LGPL-2.1"), 50));
223  return true;
224  }
225  if (name.compare("orLGPLVer2") == 0)
226  {
227  matches.push_back(LicenseMatch(string("QT(Commercial)"), 50));
228  matches.push_back(LicenseMatch(string("LGPL-2.0"), 50));
229  return true;
230  }
231  if (name.compare("orGPLv3") == 0)
232  {
233  matches.push_back(LicenseMatch(string("QT(Commercial)"), 50));
234  matches.push_back(LicenseMatch(string("GPL-3.0"), 50));
235  return true;
236  }
237  if (name.compare("CDDLv1orGPLv2") == 0)
238  {
239  matches.push_back(LicenseMatch(string("CDDL-1.0"), 50));
240  matches.push_back(LicenseMatch(string("GPL-2.0"), 50));
241  return true;
242  }
243  if (name.compare("CDDLorGPLv2") == 0)
244  {
245  matches.push_back(LicenseMatch(string("CDDL"), 50));
246  matches.push_back(LicenseMatch(string("GPL-2.0"), 50));
247  return true;
248  }
249  if (name.compare("MPLGPL2orLGPLv2_1") == 0)
250  {
251  matches.push_back(LicenseMatch(string("MPL-1.0"), 32));
252  matches.push_back(LicenseMatch(string("GPL-2.0"), 34));
253  matches.push_back(LicenseMatch(string("LGPL-2.1"), 34));
254  return true;
255  }
256  if (name.compare("MPL1_1andLGPLv2_1") == 0)
257  {
258  matches.push_back(LicenseMatch(string("MPL-1.1"), 99));
259  matches.push_back(LicenseMatch(string("GPL-2.1"), 99));
260  return true;
261  }
262  if (name.compare("MPL_LGPLsee") == 0)
263  {
264  matches.push_back(LicenseMatch(string("MPL-1.0"), 50));
265  matches.push_back(LicenseMatch(string("LGPL"), 40));
266  return true;
267  }
268  if (name.compare("MITX11BSDvar") == 0)
269  {
270  matches.push_back(LicenseMatch(string("MIT"), 33));
271  matches.push_back(LicenseMatch(string("X11"), 33));
272  matches.push_back(LicenseMatch(string("BSD-style"), 34));
273  return true;
274  }
275  if (name.compare("MITCMU") == 0 || name.compare("MITCMUvar2") == 0 || name.compare("MITCMUvar3") == 0)
276  {
277  matches.push_back(LicenseMatch(string("MIT"), 50));
278  matches.push_back(LicenseMatch(string("CMU"), 50));
279  return true;
280  }
281  if (name.compare("MITX11") == 0 || name.compare("MITX11noNotice") == 0 || name.compare("MITX11simple") == 0)
282  {
283  matches.push_back(LicenseMatch(string("MIT"), 50));
284  matches.push_back(LicenseMatch(string("X11"), 50));
285  return true;
286  }
287  if (name.compare("MITandGPL") == 0)
288  {
289  matches.push_back(LicenseMatch(string("MIT"), 99));
290  matches.push_back(LicenseMatch(string("GPL"), 99));
291  return true;
292  }
293  if (name.compare("BisonException") == 0)
294  {
295  matches.push_back(LicenseMatch(string("GPL-2.0-with-bison-exception"), 50));
296  matches.push_back(LicenseMatch(string("GPL-3.0-with-bison-exception"), 50));
297  return true;
298  }
299  if (name.compare("ClassPathException") == 0)
300  {
301  matches.push_back(LicenseMatch(string("GPL-2.0-with-classpath-exception"), 30));
302  matches.push_back(LicenseMatch(string("GPL-2.0+-with-classpath-exception"), 30));
303  matches.push_back(LicenseMatch(string("GPL-3.0-with-classpath-exception"), 40));
304  return true;
305  }
306  if (name.compare("autoConfException") == 0)
307  {
308  matches.push_back(LicenseMatch(string("GPL-2.0-with-autoconf-exception"), 50));
309  matches.push_back(LicenseMatch(string("GPL-3.0-with-autoconf-exception"), 50));
310  return true;
311  }
312  if (name.compare("CPLv1orGPLv2+orLGPLv2+") == 0)
313  {
314  matches.push_back(LicenseMatch(string("CPL-1.0"), 34));
315  matches.push_back(LicenseMatch(string("GPL-2.0+"), 33));
316  matches.push_back(LicenseMatch(string("LGPL-2.0+"), 33));
317  return true;
318  }
319  if (name.compare("GPLVer2or3KDE+") == 0)
320  {
321  matches.push_back(LicenseMatch(string("GPL-2.0+-KDE-exception"), 50));
322  matches.push_back(LicenseMatch(string("GPL-3.0+-KDE-exception"), 50));
323  return true;
324  }
325  if (name.compare("LGPLVer2.1or3KDE+") == 0)
326  {
327  matches.push_back(LicenseMatch(string("LGPL-2.1+-KDE-exception"), 50));
328  matches.push_back(LicenseMatch(string("LGPL-3.0+-KDE-exception"), 50));
329  return true;
330  }
331  if (name.compare("GPLv2orLGPLv2.1") == 0)
332  {
333  matches.push_back(LicenseMatch(string("GPL-2.0"), 50));
334  matches.push_back(LicenseMatch(string("LGPL-2.1"), 50));
335  return true;
336  }
337  if (name.compare("GPLv2+orLGPLv2.1") == 0)
338  {
339  matches.push_back(LicenseMatch(string("GPL-2.0+"), 50));
340  matches.push_back(LicenseMatch(string("LGPL-2.1"), 50));
341  return true;
342  }
343 
344  return false;
345 }
346 
347 /*
348  * unmatched in lib/Ninka/rules.dict:
349  *
350 BSD2AdvInsteadOfBinary:BSDpre,BSDcondSource,BSDcondAdvRULE,BSDasIs,BSDWarr
351 BSD1:BSDpre,BSDcondBinary,BSDasIs,BSDWarr
352 BSDOnlyAdv:BSDpre,BSDcondAdvRULE,BSDasIs,BSDWarr
353 BSDOnlyEndorseNoWarranty:BSDpreLike,BSDcondEndorseRULE,BSDasIs
354 BSD2var1:BSDpre,BSDCondSourceVariant,BSDcondBinary,BSDasIs,BSDWarr
355 BSD2var2:BSDpre,BSDCondSourceVariant2,BSDcondBinary,BSDasIs,BSDWarr
356 BSD2aic700:BSDpre,BSDcondSource,BSDcondBinaryVar1,AsIsVariant2,LiabilityBSDVariantAIC700
357 BSD2SoftAndDoc:BSDpreSoftAndDoc,BSDcondSourceOrDoc,BSDcondBinary,BSDasIsSoftAndDoc,BSDWarr
358 BSDCairoStyleWarr:BSDpre,BSDcondSource,BSDcondBinary,BSDcondAdvPart2,OpenSSLwritCond,OpenSSLName,BSDasIs,BSDWarr
359 BSDdovecotStyle:BSDpre,BSDcondSource,BSDcondBinary,OpenSSLendorse,DovecotwriteCod,OpenSSLAckPart1,BSDcondAdvPart2,MITstyleCairoWarranty
360 ZLIBref:ZLibRef
361 boost-1:boostPermission,boostPreserve,boostAsIs,boostWarr
362 boost-1:boostRefv1
363 boost-1ref:boostSeev1
364 SSLeay:SSLCopy,SSLeayAttrib,SSLeayAdType,BSDpre,BSDcondSource,BSDcondBinary,BSDcondAdvRULE,SSLeayCrypto,SSLeayWindows,BSDasIs,BSDWarr,SSLeayCantChangeLic
365 SimpleOnlyKeepCopyright:SimpleOnlyKeepCopyright
366 MPL-MIT-dual:MPL-MIT-dual1,MPL-MIT-dual2
367 orGPLv2+orLGPLv2.1+:Altern,GPLv2orLGPLv2\.1Ver2\+,MPLoptionNOTGPLVer0,MPLoptionIfNotDelete3licsVer0
368 MIToldwithoutSell:MITperNoSell,MITnorep,MITasis
369 MIToldwithoutSellCMUVariant:MITpermNoSell,X11CMUAsIs,X11CMULiability,X11CMUredistribute
370 MIToldwithoutSell:MITpermNoSell,MITandGPLasis,MITandGPLwar
371 MIToldwithoutSellandNoDocumentationRequi:MITpermNoSellNoDoc,BSDasIs,BSDWarr
372 MIToldwithoutSellandNoDocumentationRequi:MITpermNoSellNoDoc,MITnorep,MITasis
373 MIToldMichiganVersion:MITpermNoSell,WarrantySupplied
374 X11mit:MITpermWithoutEndor,X11notice,X11asIs,X11asLiable,X11adv
375 X11Festival:X11FestivalPerm,X11FestivalNotice,X11FestivalNoEndorse,MITstyleCairoWarranty
376 MITmodern:MITmodermPerm,MITmodernLiable,MITmodermWarr,MitmodernAsIs
377 MITX11NoSellNoDocDocBSDvar:MITpermNoSellNoDoc,X11asIsLike,BSDWarr
378 BindMITX11Var:MITpermAndOr,X11asIsLike,BSDWarr
379 Exception:Exception
380 LinkException:LinkException
381 LinkExceptionBison:LinkExceptionBison
382 LinkExceptionGPL:LinkExceptionGPL
383 LinkExceptionLeGPL:LinkExceptionLeGPL
384 LinkExceptionOpenSSL:LinkExceptionOpenSSL
385 WxException:wxLinkExceptionPart1,wxLinkExceptionPart2,wxLinkExceptionPart3Ver0,wxLinkExceptionPart4,wxLinkExceptionPart5,wxLinkExceptionPart6
386 qtWindowsException1.3:qtExceptionNoticeVer1.3
387 qtExceptionWindows:qtExceptionWindows
388 digiaQTExceptionNoticeVer1.1:digiaQTExceptionNoticeVer1.1
389 BeerWareVer42:BeerWareVer42LicPart1,BeerWareVer42LicPart2,BeerWareVer42LicPart3,BeerWareVer42LicPart4
390 IntelACPILic:IntelPart02,IntelPart03,IntelPart04,IntelPart05,IntelPart06,IntelPart07,IntelPart08,IntelPart09,IntelPart10,IntelPart11,IntelPart12,IntelPart13,IntelPart14,IntelPart15,IntelPart16,IntelPart17,IntelPart18,IntelPart19,IntelPart20,IntelPart21,IntelPart22,IntelPart23,IntelPart24,IntelPart25,IntelPart26,IntelPart27,IntelPart28
391 simpleLicense1:simpleLic1part1
392 simpleLic2:simpleLic2
393 simpleLic:simpleLic
394 sunRPC:sunRPCLic1,sunRPCLic2,sunRCPnoWarranty,sunRCPnoSupport
395 SunSimpleLic:SunSimpleLic
396 emacsLic:EmacsLicense
397 SameTermsAs:SameTermsAs
398 GhostscriptGPL:GhostscriptGPL
399 SameAsPerl:SameAsPerl
400 QplGPLv2or3:qtGPLv2or3
401 FreeType:FreeType
402 Postfix:Postfix
403 subversion+:subversion,subversionPlus
404 subversion:subversion
405 svnkit+:svnkitPlus
406 svnkit:svnkit
407 sequenceLic:sequenceLic
408 tmate+:tmatePlus
409 subversionError:subversionError
410 artifex:artifex
411 SimpleLic:SimpleLic
412 dovecotSeeCopying:dovecotSeeCopying
413 zendv2:zendv2
414 kerberos:exportLicRequired,exportNoLia,exportMITper,exportMITmodify,MITnorep,MITasis
415 GPL-2or3,AlternTrolltechKDE-approved:GPLv2orv3Ver0,Altern,laterTrolltechKDE-approvedVer0
416  * */
Definition: state.hpp:16
Class to handle file related operations.
Definition: files.hpp:26
const std::string & getFileName() const
Definition: files.cc:90
void bail(int exitval)
Disconnect with scheduler returning an error code and exit.
char buffer[2048]
The last thing received from the scheduler.
Store the results of a regex match.
Definition: scanners.hpp:28