FOSSology  3.2.0rc1
Open Source License Compliance by Open Source Software
utils.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 "ninkawrapper.hpp"
20 #include "utils.hpp"
21 
22 using namespace fo;
23 
25 {
26  int agentId = queryAgentId(dbManager);
27  return State(agentId);
28 }
29 
31 {
32  char* COMMIT_HASH = fo_sysconfig(AGENT_NAME, "COMMIT_HASH");
33  char* VERSION = fo_sysconfig(AGENT_NAME, "VERSION");
34  char* agentRevision;
35 
36  if (!asprintf(&agentRevision, "%s.%s", VERSION, COMMIT_HASH))
37  bail(-1);
38 
39  int agentId = fo_GetAgentKey(dbManager.getConnection(), AGENT_NAME, 0, agentRevision, AGENT_DESC);
40  free(agentRevision);
41 
42  if (agentId <= 0)
43  bail(1);
44 
45  return agentId;
46 }
47 
48 int writeARS(const State& state, int arsId, int uploadId, int success, DbManager& dbManager)
49 {
50  PGconn* connection = dbManager.getConnection();
51  int agentId = state.getAgentId();
52 
53  return fo_WriteARS(connection, arsId, uploadId, agentId, AGENT_ARS, NULL, success);
54 }
55 
56 void bail(int exitval)
57 {
58  fo_scheduler_disconnect(exitval);
59  exit(exitval);
60 }
61 
62 bool processUploadId(const State& state, int uploadId, NinkaDatabaseHandler& databaseHandler)
63 {
64  vector<unsigned long> fileIds = databaseHandler.queryFileIdsForUpload(uploadId);
65 
66  bool errors = false;
67 #pragma omp parallel
68  {
69  NinkaDatabaseHandler threadLocalDatabaseHandler(databaseHandler.spawn());
70 
71  size_t pFileCount = fileIds.size();
72 #pragma omp for
73  for (size_t it = 0; it < pFileCount; ++it)
74  {
75  if (errors)
76  continue;
77 
78  unsigned long pFileId = fileIds[it];
79 
80  if (pFileId == 0)
81  continue;
82 
83  if (!matchPFileWithLicenses(state, pFileId, threadLocalDatabaseHandler))
84  {
85  errors = true;
86  }
87 
89  }
90  }
91 
92  return !errors;
93 }
94 
95 bool matchPFileWithLicenses(const State& state, unsigned long pFileId, NinkaDatabaseHandler& databaseHandler)
96 {
97  char* pFile = databaseHandler.getPFileNameForFileId(pFileId);
98 
99  if (!pFile)
100  {
101  cout << "File not found " << pFileId << endl;
102  bail(8);
103  }
104 
105  char* fileName = NULL;
106  {
107 #pragma omp critical (repo_mk_path)
108  fileName = fo_RepMkPath("files", pFile);
109  }
110  if (fileName)
111  {
112  fo::File file(pFileId, fileName);
113 
114  if (!matchFileWithLicenses(state, file, databaseHandler))
115  return false;
116 
117  free(fileName);
118  free(pFile);
119  }
120  else
121  {
122  cout << "PFile not found in repo " << pFileId << endl;
123  bail(7);
124  }
125 
126  return true;
127 }
128 
129 bool matchFileWithLicenses(const State& state, const fo::File& file, NinkaDatabaseHandler& databaseHandler)
130 {
131  string ninkaResult = scanFileWithNinka(state, file);
132  vector<string> ninkaLicenseNames = extractLicensesFromNinkaResult(ninkaResult);
133  vector<LicenseMatch> matches = createMatches(ninkaLicenseNames);
134  return saveLicenseMatchesToDatabase(state, matches, file.getId(), databaseHandler);
135 }
136 
137 bool saveLicenseMatchesToDatabase(const State& state, const vector<LicenseMatch>& matches, unsigned long pFileId, NinkaDatabaseHandler& databaseHandler)
138 {
139  for (vector<LicenseMatch>::const_iterator it = matches.begin(); it != matches.end(); ++it)
140  {
141  const LicenseMatch& match = *it;
142  databaseHandler.insertOrCacheLicenseIdForName(match.getLicenseName());
143  }
144 
145  if (!databaseHandler.begin())
146  return false;
147 
148  for (vector<LicenseMatch>::const_iterator it = matches.begin(); it != matches.end(); ++it)
149  {
150  const LicenseMatch& match = *it;
151 
152  int agentId = state.getAgentId();
153  string rfShortname = match.getLicenseName();
154  unsigned percent = match.getPercentage();
155 
156  unsigned long licenseId = databaseHandler.getCachedLicenseIdForName(rfShortname);
157 
158  if (licenseId == 0)
159  {
160  databaseHandler.rollback();
161  cout << "cannot get licenseId for shortname '" + rfShortname + "'" << endl;
162  return false;
163  }
164 
165 
166  if (!databaseHandler.saveLicenseMatch(agentId, pFileId, licenseId, percent))
167  {
168  databaseHandler.rollback();
169  cout << "failing save licenseMatch" << endl;
170  return false;
171  };
172  }
173 
174  return databaseHandler.commit();
175 }
void bail(int exitval)
Disconnect with scheduler returning an error code and exit.
DB wrapper for agents.
Store the results of a regex match.
Definition: scanners.hpp:39
bool commit() const
COMMIT a transaction block in DB.
CopyrightState getState(CliOptions &&cliOptions)
Create a new state for the current agent based on CliOptions.
bool rollback() const
ROLLBACK a transaction block in DB.
void fo_scheduler_disconnect(int retcode)
Disconnect the scheduler connection.
char * getPFileNameForFileId(unsigned long pfileId) const
Get the file name of a give pfile id.
PGconn * getConnection() const
void matchFileWithLicenses(const string &sContent, unsigned long pFileId, CopyrightState const &state, int agentId, CopyrightDatabaseHandler &databaseHandler)
Scan a given file with all available scanners and save findings to database.
Class to handle file related operations.
Definition: files.hpp:29
Definition: state.hpp:26
bool processUploadId(const CopyrightState &state, int agentId, int uploadId, CopyrightDatabaseHandler &databaseHandler, bool ignoreFilesWithMimeType)
Process a given upload id, scan from statements and add to database.
bool begin() const
BEGIN a transaction block in DB.
char * fo_RepMkPath(const char *Type, char *Filename)
Given a filename, construct the full path to the file.
Definition: libfossrepo.c:364
unsigned long getId() const
Definition: files.cc:119
fo_dbManager * dbManager
fo_dbManager object
Definition: process.c:28
int queryAgentId(PGconn *dbConn)
Get agent id, exit if agent id is incorrect.
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.
Definition: libfossagent.c:172
fo namespace holds the FOSSology library functions.
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.
Definition: libfossagent.c:228
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...
int writeARS(int agentId, int arsId, int uploadId, int success, const fo::DbManager &dbManager)
Call C function fo_WriteARS() and translate the arguments.
void matchPFileWithLicenses(CopyrightState const &state, int agentId, unsigned long pFileId, CopyrightDatabaseHandler &databaseHandler)
Get the file contents, scan for statements and save findings to database.
char * fo_sysconfig(const char *sectionname, const char *variablename)
gets a system configuration variable from the configuration data.