7 #include "scancode_utils.hpp"
9 namespace po = boost::program_options;
15 void bail(
int exitval) {
27 return State(agentId);
36 char *COMMIT_HASH =
fo_sysconfig(AGENT_NAME,
"COMMIT_HASH");
40 if (!asprintf(&agentRevision,
"%s.%s", VERSION, COMMIT_HASH))
44 agentRevision, AGENT_DESC);
62 int writeARS(
const State &state,
int arsId,
int uploadId,
int success,
64 PGconn *connection =
dbManager.getConnection();
67 return fo_WriteARS(connection, arsId, uploadId, agentId, AGENT_ARS, NULL,
80 vector<unsigned long> fileIds =
83 unordered_map<unsigned long, string> fileIdsMap;
84 unordered_map<string, unsigned long> fileIdsMapReverse;
88 char fileLocationTpl[] =
"/tmp/scancode_input_XXXXXX";
89 int fdInput = mkstemp(fileLocationTpl);
91 LOG_ERROR(
"Failed to create temporary input file.\n");
95 string fileLocation(fileLocationTpl);
97 char outputFileTpl[] =
"/tmp/scancode_output_XXXXXX";
98 int fdOutput = mkstemp(outputFileTpl);
100 LOG_ERROR(
"Failed to create temporary output file.\n");
101 unlink(fileLocationTpl);
105 string outputFile(outputFileTpl);
107 size_t pFileCount = fileIds.size();
108 for (
size_t it = 0; it < pFileCount; ++it) {
109 unsigned long pFileId = fileIds[it];
114 mapFileNameWithId(pFileId, fileIdsMap, fileIdsMapReverse, databaseHandler);
119 writeFileNameToTextFile(fileIdsMap, fileLocation);
120 scanFileWithScancode(state, fileLocation, outputFile);
122 std::ifstream opfile(outputFile);
124 LOG_ERROR(
"Error opening the JSON file.\n");
130 while (getline(opfile, line)) {
134 #pragma omp parallel default(none) \
135 shared(databaseHandler, scanResults, fileIdsMapReverse, state, errors)
141 Json::CharReaderBuilder json_reader_builder;
142 auto scanner = unique_ptr<Json::CharReader>(json_reader_builder.newCharReader());
143 Json::Value scancodeValue;
150 string fileName = scancodeValue[
"file"].asString();
151 unsigned long fileId = 0;
153 auto it = fileIdsMapReverse.find(fileName);
154 if (it != fileIdsMapReverse.end()) {
164 if (unlink(outputFile.c_str()) != 0) {
165 LOG_FATAL(
"Unable to delete file %s \n", outputFile.c_str());
167 if (unlink(fileLocation.c_str()) != 0) {
168 LOG_FATAL(
"Unable to delete file %s \n", fileLocation.c_str());
180 void mapFileNameWithId(
unsigned long pFileId,
181 unordered_map<unsigned long, string> &fileIdsMap,
182 unordered_map<string, unsigned long> &fileIdsMapReverse,
186 LOG_FATAL(
"File not found %lu \n", pFileId);
190 char *fileName = NULL;
197 fileIdsMap[file.getId()] = file.getFileName();
198 fileIdsMapReverse[file.getFileName()] = file.getId();
203 LOG_FATAL(
"PFile not found in repo %lu \n", pFileId);
212 void writeFileNameToTextFile(unordered_map<unsigned long, string> &fileIdsMap,
string fileLocation) {
213 std::ofstream outputFile(fileLocation, std::ios::app);
215 if (!outputFile.is_open()) {
216 LOG_FATAL(
"Unable to open file");
219 for (
auto const& x : fileIdsMap)
221 outputFile << x.second <<
"\n";
232 string getScanResult(
const string& line) {
235 size_t startIndex = 0;
236 size_t braceCount = 0;
238 for (
size_t i = 0; i < line.length(); ++i) {
242 if (braceCount == 0) {
246 }
else if (c ==
'}') {
248 if (braceCount == 0) {
249 scanResult = line.substr(startIndex, i - startIndex + 1);
269 string scancodeResult,
string &filename,
unsigned long fileId) {
270 map<string, vector<Match>> scancodeData =
271 extractDataFromScancodeResult(scancodeResult, filename);
272 return saveLicenseMatchesToDatabase(
273 state, scancodeData[
"scancode_license"], fileId,
275 saveOtherMatchesToDatabase(
276 state, scancodeData[
"scancode_statement"], fileId,
278 saveOtherMatchesToDatabase(
279 state, scancodeData[
"scancode_author"], fileId,
281 saveOtherMatchesToDatabase(
282 state, scancodeData[
"scancode_email"], fileId,
284 saveOtherMatchesToDatabase(
285 state, scancodeData[
"scancode_url"], fileId,
302 bool saveLicenseMatchesToDatabase(
const State &state,
303 const vector<Match> &matches,
304 unsigned long pFileId,
307 for (
const auto &
match : matches) {
312 if (!databaseHandler.
begin()) {
315 for (
const auto &
match : matches) {
317 string rfShortname =
match.getMatchName();
318 int percent =
match.getPercentage();
320 unsigned length =
match.getLength();
321 unsigned long licenseId =
324 if (licenseId == 0) {
326 LOG_ERROR(
"cannot get licenseId for shortname '%s' \n",
327 rfShortname.c_str());
330 if (rfShortname ==
"No_license_found") {
333 LOG_ERROR(
"failing save licenseMatch \n");
339 if (licenseFileId > 0) {
344 LOG_ERROR(
"failing save licensehighlight \n");
348 LOG_ERROR(
"failing save licenseMatch \n");
353 return databaseHandler.
commit();
364 bool saveOtherMatchesToDatabase(
const State &state,
365 const vector<Match> &matches,
366 unsigned long pFileId,
369 if (!databaseHandler.
begin())
372 for (
const auto &
match : matches) {
378 LOG_ERROR(
"failing save otherMatches \n");
382 return databaseHandler.
commit();
395 bool parseCommandLine(
int argc,
char **argv,
string &cliOption,
bool &ignoreFilesWithMimeType)
397 po::options_description desc(AGENT_NAME
": available options");
399 (
"help,h",
"show this help")
400 (
"ignoreFilesWithMimeType,I",
"ignoreFilesWithMimeType")
401 (
"license,l",
"scancode license")
402 (
"copyright,r",
"scancode copyright")
403 (
"email,e",
"scancode email")
404 (
"url,u",
"scancode url")
405 (
"config,c", po::value<string>(),
"path to the sysconfigdir")
406 (
"scheduler_start",
"specifies, that the command was called by the scheduler")
407 (
"userID", po::value<int>(),
"the id of the user that created the job (only in combination with --scheduler_start)")
408 (
"groupID", po::value<int>(),
"the id of the group of the user that created the job (only in combination with --scheduler_start)")
409 (
"jobId", po::value<int>(),
"the id of the job (only in combination with --scheduler_start)");
410 po::variables_map vm;
413 po::store(po::command_line_parser(argc, argv).options(desc).run(), vm);
414 if (vm.count(
"help") > 0)
416 cout << desc <<
"\n";
420 cliOption += vm.count(
"license") > 0 ?
"l" :
"";
421 cliOption += vm.count(
"copyright") > 0 ?
"c" :
"";
422 cliOption += vm.count(
"email") > 0 ?
"e" :
"";
423 cliOption += vm.count(
"url") > 0 ?
"u" :
"";
424 ignoreFilesWithMimeType =
425 vm.count(
"ignoreFilesWithMimeType") > 0 ? true :
false;
427 catch (boost::bad_any_cast &)
429 LOG_FATAL(
"wrong parameter type\n ");
430 cout << desc <<
"\n";
435 LOG_FATAL(
"wrong command line arguments\n");
436 cout << desc <<
"\n";
bool processUploadId(const CompatibilityState &state, int uploadId, CompatibilityDatabaseHandler &databaseHandler, int groupId)
CompatibilityState getState(DbManager &dbManager, CompatibilityCliOptions &&cliOptions)
Create a new state for the current agent based on CliOptions.
int writeARS(const CompatibilityState &state, int arsId, int uploadId, int success, DbManager &dbManager)
int queryAgentId(DbManager &dbManager)
Query and register the agent id. Bails on failure.
void bail(int exitval)
Disconnect scheduler and exit.
Maps agent data to database schema.
bool saveHighlightInfo(long licenseFileId, unsigned start, unsigned length)
save highlight information in the highlight table
unsigned long getCachedLicenseIdForName(std::string const &rfShortName) const
for given short name search license
long saveLicenseMatch(int agentId, long pFileId, long licenseId, int percentMatch)
save license match with license_ref table in license_file table Insert license if already not present...
bool insertInDatabase(DatabaseEntry &entry) const
insert copyright/author in scancode_copyright/scancode_author table
void insertOrCacheLicenseIdForName(std::string const &rfShortName, std::string const &rfFullname, std::string const &rfTexturl)
calling function for selectOrInsertLicenseIdForName
bool insertNoResultInDatabase(int agentId, long pFileId, long licenseId)
Insert null value of license for uploads having no licenses.
std::vector< unsigned long > queryFileIdsForUpload(int uploadId, bool ignoreFilesWithMimeType)
Function to get pfile ID for uploads.
ScancodeDatabaseHandler spawn() const
Instantiate a new object spawn for ScanCode Database handler Used to create new objects for threads.
int getAgentId() const
getter function for agent Id
bool commit() const
COMMIT a transaction block in DB.
bool begin() const
BEGIN a transaction block in DB.
char * getPFileNameForFileId(unsigned long pfileId) const
Get the file name of a give pfile id.
bool rollback() const
ROLLBACK a transaction block in DB.
Class to handle file related operations.
Abstract class to provide interface to scanners.
void matchFileWithLicenses(const string &sContent, unsigned long pFileId, CopyrightState const &state, int agentId, CopyrightDatabaseHandler &databaseHandler, int uploadId, const string &uploadTreeTableName)
Scan a given file with all available scanners and save findings to database.
FUNCTION int fo_WriteARS(PGconn *pgConn, int ars_pk, int upload_pk, int agent_pk, const char *tableName, const char *ars_status, int ars_success)
Write ars record.
FUNCTION int fo_GetAgentKey(PGconn *pgConn, const char *agent_name, long Upload_pk, const char *rev, const char *agent_desc)
Get the latest enabled agent key (agent_pk) from the database.
char * fo_RepMkPath(const char *Type, char *Filename)
Given a filename, construct the full path to the file.
void fo_scheduler_disconnect(int retcode)
Disconnect the scheduler connection.
void fo_scheduler_heart(int i)
This function must be called by agents to let the scheduler know they are alive and how many items th...
char * fo_sysconfig(const char *sectionname, const char *variablename)
gets a system configuration variable from the configuration data.
fo_dbManager * dbManager
fo_dbManager object
start($application)
start the application Assumes application is restartable via /etc/init.d/<script>....
Store the results of a regex match.