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