FOSSology  4.4.0
Open Source License Compliance by Open Source Software
scancode_wrapper.cc
1 /*
2  SPDX-FileCopyrightText: © 2021 Sarita Singh <saritasingh.0425@gmail.com>
3 
4  SPDX-License-Identifier: GPL-2.0-only
5 */
6 
7 #include "scancode_wrapper.hpp"
8 
9 #define MINSCORE 50
10 
22 unsigned getFilePointer(const string &filename, size_t start_line,
23  const string &match_text) {
24  ifstream checkfile(filename);
25  string str;
26  if (checkfile.is_open()) {
27  for (size_t i = 0; i < start_line - 1; i++) {
28  getline(checkfile, str);
29  }
30  unsigned int file_p = checkfile.tellg();
31  getline(checkfile, str);
32  unsigned int pos = str.find(match_text);
33  if (pos != string::npos) {
34  return file_p + pos;
35  }else{
36  LOG_NOTICE("Failed to find startbyte for %s\n", filename.c_str());
37  }
38  }
39  return 0;
40 }
41 
42 
65 void scanFileWithScancode(const State &state, string fileLocation, string outputFile) {
66  string projectUser = fo_config_get(sysconfig, "DIRECTORIES", "PROJECTUSER",
67  NULL);
68  string cacheDir = fo_config_get(sysconfig, "DIRECTORIES", "CACHEDIR",
69  NULL);
70 
71  string command =
72  "PYTHONPATH='/home/" + projectUser + "/pythondeps/' " +
73  "python3 runscanonfiles.py -" + state.getCliOptions() + " " +
74  ((state.getCliOptions().find('l') != string::npos) ? "-m " +
75  to_string(MINSCORE): "") + " " + fileLocation + " " + outputFile;
76 
77  int returnvalue = system(command.c_str());
78 
79  if (returnvalue != 0) {
80  LOG_FATAL("could not execute scancode command: %s \n", command.c_str());
81  bail(1);
82  }
83 
84  if (unlink(fileLocation.c_str()) != 0)
85  {
86  LOG_FATAL("Unable to delete file %s \n", fileLocation.c_str());
87  }
88 }
89 
117 map<string, vector<Match>> extractDataFromScancodeResult(const string& scancodeResult, const string& filename) {
118  Json::CharReaderBuilder json_reader_builder;
119  auto scanner = unique_ptr<Json::CharReader>(json_reader_builder.newCharReader());
120  Json::Value scancodevalue;
121  string errors;
122  const bool isSuccessful = scanner->parse(scancodeResult.c_str(),
123  scancodeResult.c_str() + scancodeResult.length(), &scancodevalue, &errors);
124  map<string, vector<Match>> result;
125  vector<Match> licenses;
126  if (isSuccessful) {
127  Json::Value licensearrays = scancodevalue["licenses"];
128  if(licensearrays.empty())
129  {
130  result["scancode_license"].push_back(Match("No_license_found"));
131  }
132  else
133  {
134  for (auto oneresult : licensearrays)
135  {
136  string licensename = oneresult["spdx_license_key"].asString();
137  int percentage = (int)oneresult["score"].asFloat();
138  string full_name=oneresult["name"].asString();
139  string text_url=oneresult["text_url"].asString();
140  string match_text = oneresult["matched_text"].asString();
141  unsigned long start_line=oneresult["start_line"].asUInt();
142  string temp_text= match_text.substr(0,match_text.find("\n"));
143  unsigned start_pointer = getFilePointer(filename, start_line, temp_text);
144  unsigned length = match_text.length();
145  result["scancode_license"].push_back(Match(licensename,percentage,full_name,text_url,start_pointer,length));
146  }
147  }
148 
149  Json::Value copyarrays = scancodevalue["copyrights"];
150  for (auto oneresult : copyarrays) {
151  string copyrightname = oneresult["value"].asString();
152  unsigned long start_line=oneresult["start"].asUInt();
153  string temp_text= copyrightname.substr(0,copyrightname.find("[\n\t]"));
154  unsigned start_pointer = getFilePointer(filename, start_line, temp_text);
155  unsigned length = copyrightname.length();
156  string type="scancode_statement";
157  result["scancode_statement"].push_back(Match(copyrightname,type,start_pointer,length));
158  }
159 
160  Json::Value holderarrays = scancodevalue["holders"];
161  for (auto oneresult : holderarrays) {
162  string holdername = oneresult["value"].asString();
163  unsigned long start_line=oneresult["start"].asUInt();
164  string temp_text= holdername.substr(0,holdername.find("\n"));
165  unsigned start_pointer = getFilePointer(filename, start_line, temp_text);
166  unsigned length = holdername.length();
167  string type="scancode_author";
168  result["scancode_author"].push_back(Match(holdername,type,start_pointer,length));
169  }
170 
171  Json::Value emailarrays = scancodevalue["emails"];
172  for (auto oneresult : emailarrays) {
173  string emailname = oneresult["value"].asString();
174  unsigned long start_line=oneresult["start"].asUInt();
175  string temp_text= emailname.substr(0,emailname.find("\n"));
176  unsigned start_pointer = getFilePointer(filename, start_line, temp_text);
177  unsigned length = emailname.length();
178  string type="scancode_email";
179  result["scancode_email"].push_back(Match(emailname,type,start_pointer,length));
180  }
181 
182  Json::Value urlarrays = scancodevalue["urls"];
183  for (auto oneresult : urlarrays) {
184  string urlname = oneresult["value"].asString();
185  unsigned long start_line=oneresult["start"].asUInt();
186  string temp_text= urlname.substr(0,urlname.find("\n"));
187  unsigned start_pointer = getFilePointer(filename, start_line, temp_text);
188  unsigned length = urlname.length();
189  string type="scancode_url";
190  result["scancode_url"].push_back(Match(urlname,type,start_pointer,length));
191  }
192  } else {
193  LOG_FATAL("JSON parsing failed %s \n", errors.c_str());
194  }
195  return result;
196 }
Definition: state.hpp:16
string getCliOptions() const
getter function for cliOptions
Abstract class to provide interface to scanners.
Definition: scanners.hpp:52
void bail(int exitval)
Disconnect with scheduler returning an error code and exit.
char * fo_config_get(fo_conf *conf, const char *group, const char *key, GError **error)
Gets an element based on its group name and key name. If the group or key is not found,...
Definition: fossconfig.c:336
fo_conf * sysconfig
Definition: match.h:20