FOSSology  4.4.0
Open Source License Compliance by Open Source Software
main.c
1 // SPDX-License-Identifier: GPL-2.0-only
20 #include "snippet_scan.h"
21 #include "string.h"
22 
23 #include <stdio.h>
24 #include <sys/stat.h>
25 #include <unistd.h>
26 #include <json-c/json.h>
27 
28 #ifdef COMMIT_HASH_S
29 char BuildVersion[] = "scanoss build version: " VERSION_S " r(" COMMIT_HASH_S ").\n";
30 #else
31 char BuildVersion[] = "scanoss build version: NULL.\n";
32 #endif
33 char *baseTMP = "/tmp/scanoss";
34 int Agent_pk;
35 char ApiUrl[400];
36 char accToken[100];
37 extern PGconn *db_conn;
38 void *pgConn = NULL;
39 //#define _SCANOSS_LOGME
40 extern void ParseResults(char *folder);
41 extern int ScanFolder(char *folder);
42 extern int RebuildUpload(long upload_pk,char *tempFolder);
43 void logme(char *msg)
44 {
45  #ifdef _SCANOSS_LOGME
46  FILE *fptr;
47 
48  // use appropriate location if you are using MacOS or Linux
49  fptr = fopen("/home/fossy/snippet_scan.txt", "a");
50 
51  if (fptr == NULL)
52  {
53  printf("Error!");
54  exit(1);
55  }
56  fprintf(fptr, "->%s", msg);
57  fclose(fptr);
58  #endif
59 }
60 void loadAgentConfiguration(PGconn *pg_conn)
61 {
62  PGresult *result;
63  char sqlA[] = "select conf_value from sysconfig where variablename='ScAPIURL';";
64 
65  result = PQexec(pg_conn, sqlA);
66  // check if ApiUrl exists
67  if (fo_checkPQresult(pg_conn, result, sqlA, __FILE__, __LINE__)) {
68  sprintf(ApiUrl, "%s", "");
69  } else {
70  if(PQgetisnull(result,0,0)){
71  char sqlHost[]="INSERT INTO sysconfig (variablename, conf_value, ui_label, vartype, group_name, group_order, description, validation_function, option_value) \
72  VALUES('ScAPIURL', '', 'SCANOSS API URL', 2, 'SCANOSS', 1, '(leave blank for default https://osskb.org/api/scan/direct))', NULL, NULL);";
73  result = PQexec(pg_conn, sqlHost);
74  if (fo_checkPQcommand(pg_conn, result, sqlHost, __FILE__, __LINE__)) {
75  LOG_ERROR("Can't default ScAPIURL") ;
76  }
77  sprintf(ApiUrl, "%s", "");
78  } else {
79  sprintf(ApiUrl, "%s", PQgetvalue(result, 0, 0));
80  }
81  }
82 
83 
84  char sqlB[] = "select conf_value from sysconfig where variablename='ScToken';";
85 
86  result = PQexec(pg_conn, sqlB);
87  if (fo_checkPQresult(pg_conn, result, sqlB, __FILE__, __LINE__))
88  {
89  memset(accToken,'\0',100);
90 
91  } else {
92  if(PQgetisnull(result,0,0)){
93  char sqlToken[]="INSERT INTO sysconfig ( variablename, conf_value, ui_label, vartype, group_name, group_order, description, validation_function, option_value) \
94  VALUES( 'ScToken', '', 'SCANOSS access token', 2, 'SCANOSS', 2, 'Set token to access full scanning service.', NULL, NULL);";
95  result = PQexec(pg_conn, sqlToken);
96  if (fo_checkPQcommand(pg_conn, result, sqlToken, __FILE__, __LINE__)) {
97  LOG_ERROR("Can't store default ScToken") ;
98  }
99  printf(accToken, "%s", "");
100  } else {
101  sprintf(accToken, "%s", PQgetvalue(result, 0, 0));
102  }
103  }
104 
105 }
106 
107 
108 
109 int createTables(PGconn* pgConn)
110 {
111  char sql[8192];
112  PGresult* result;
113 
114  if (!fo_tableExists(pgConn, "scanoss_fileinfo")) {
115 
116  snprintf(sql, sizeof(sql), "\
117  CREATE TABLE scanoss_fileinfo (\
118  pfile_fk int4 NOT NULL,\
119  matchtype text NULL,\
120  lineranges text NULL,\
121  purl varchar NULL,\
122  url varchar NULL,\
123  filepath varchar NULL,\
124  fileinfo_pk serial4 NOT NULL\
125  );");
126 
127  result = PQexec(pgConn, sql);
128  if (fo_checkPQcommand(pgConn, result, sql, __FILE__, __LINE__)) {
129 
130  // Can 't create table scanoss_fileinfo
131  }
132  }
133 return 0;
134 
135 }
136 
137 
138 
145 int main(int argc, char *argv[])
146 {
147  int c;
148  char *agent_desc = "scanoss";
149 
150  int ars_pk = 0;
151 
152  int upload_pk = 0; /* the upload primary key */
153  int user_pk = 0; // the user primary key
154  char *AgentARSName = "scanoss_ars";
155  int rv;
156  char sqlbuf[1024];
157  char *COMMIT_HASH;
158  char *VERSION;
159  char agent_rev[MAXCMD];
160  int CmdlineFlag = 0; /* run from command line flag, 1 yes, 0 not */
161 
162  fo_scheduler_connect(&argc, argv, &db_conn);
163 
164  COMMIT_HASH = fo_sysconfig("scanoss", "COMMIT_HASH");
165  VERSION = fo_sysconfig("scanoss", "VERSION");
166  sprintf(agent_rev, "%s.%s", VERSION, COMMIT_HASH);
167 
168  Agent_pk = fo_GetAgentKey(db_conn, basename(argv[0]), 0, agent_rev, agent_desc);
169  createTables(db_conn);
170  loadAgentConfiguration(db_conn);
171  mkdir(baseTMP, 0700);
172 
173  /* Process command-line */
174  char filename[200];
175 
176  while ((c = getopt(argc, argv, "ic:CvVh")) != -1)
177  {
178  switch (c)
179  {
180  case 'i':
181  PQfinish(db_conn); /* DB was opened above, now close it and exit */
182  exit(0);
183  case 'v':
184  break;
185  case 'c':
186  break; /* handled by fo_scheduler_connect() */
187  case 'C':
188  CmdlineFlag = 1;
189  strcpy(filename, argv[2]);
190  break;
191  case 'V':
192  printf("%s", BuildVersion);
193  PQfinish(db_conn);
194  return (0);
195  default:
196  Usage(argv[0]);
197  PQfinish(db_conn);
198  exit(-1);
199  }
200  }
201 
202  if (CmdlineFlag == 0) /* If no args, run from scheduler! */
203  {
204  user_pk = fo_scheduler_userID(); /* get user_pk for user who queued the agent */
205  while (fo_scheduler_next())
206  {
208  if (GetUploadPerm(db_conn, upload_pk, user_pk) < PERM_WRITE) /* Check Permissions */
209  {
210  LOG_ERROR("You have no update permissions on upload %d", upload_pk);
211  continue;
212  }
213  rv = fo_tableExists(db_conn, AgentARSName);
214  if (!rv)
215  {
216  rv = fo_CreateARSTable(db_conn, AgentARSName);
217  if (!rv)
218  return (0);
219  }
220  memset(sqlbuf, 0, sizeof(sqlbuf));
221  snprintf(sqlbuf, sizeof(sqlbuf),
222  "select ars_pk from scanoss_ars,agent \
223  where agent_pk=agent_fk and ars_success=true \
224  and upload_fk='%d' and agent_fk='%d'",
226 
227  ars_pk = fo_WriteARS(db_conn, ars_pk, upload_pk, Agent_pk, AgentARSName, 0, 0);
228  if (upload_pk == 0)
229  continue;
230  char tempFolder[512];
231  sprintf(tempFolder,"%s/%d",baseTMP,upload_pk);
232  mkdir(tempFolder, 0700);
233  char aux[100];
234  sprintf(aux,"ready to process %d",upload_pk );
235  if (RebuildUpload(upload_pk,tempFolder) != 0) /* process the upload_pk code */{
236  LOG_ERROR("Error processing upload\n");
237  } else {
238  ScanFolder(tempFolder);
239  ParseResults(tempFolder);
240  char cmdRemove[600];
241  memset(cmdRemove,0,600);
242  sprintf(cmdRemove,"rm -r %s",tempFolder);
243  // FILE *removes = popen(cmdRemove, "r"); /* Run the command */
244  // pclose(removes);
245  }
246  ars_pk = fo_WriteARS(db_conn, ars_pk, upload_pk, Agent_pk, AgentARSName, NULL, 1);
247  }
248  }
249  else
250  {
251  /* Run the scanner from command line */
252  char Cmd[MAXCMD];
253  char outputFile[MAXCMD];
254  unsigned char apiurl[410];
255  unsigned char key[110];
256 
257  if(ApiUrl[0] != '\0') {
258  sprintf((char *) apiurl,"--apiurl %s", ApiUrl);
259  }
260  else {
261  memset(apiurl, 0, sizeof(apiurl));
262  }
263 
264  if(accToken[0]!='\0' && accToken[0]!=' ') {
265  sprintf((char *)key,"--key %s", accToken);
266  }
267  else {
268  memset(key, 0, sizeof(key));
269  }
270 
271  char tempFolder[512];
272  sprintf(tempFolder, "%s/%ld", baseTMP, time(NULL));
273  mkdir(tempFolder, 0700);
274  sprintf(outputFile, "%s/result.json", tempFolder);
275 
276  sprintf(Cmd, "PYTHONPATH='/home/%s/pythondeps/' /home/%s/pythondeps/bin/scanoss-py "
277  "scan %s %s -o %s %s", FO_USER_S, FO_USER_S, apiurl, key,
278  outputFile, filename); /* Create the command to run */
279  FILE *Fin = popen(Cmd, "r"); /* Run the command */
280  if (!Fin) {
281  LOG_ERROR("Snippet scan: failed to start scan %s", strerror(errno));
282  pclose(Fin);
283  return -1;
284  }
285  pclose(Fin);
286 
287  struct json_object *result_json = json_object_from_file(outputFile);
288  if (result_json == NULL) {
289 #if JSON_C_MINOR_VERSION > 12
290  LOG_ERROR("Unable to parse json output: %s", json_util_get_last_err());
291 #else
292  LOG_ERROR("Unable to parse json output.");
293 #endif
294  return -1;
295  }
296  sprintf(Cmd, "rm -rf %s", tempFolder);
297  system(Cmd);
298  json_object_object_foreach(result_json, obj_filename, obj_val)
299  {
300  for (int i = 0; i < json_object_array_length(obj_val); ++i) {
301  struct json_object *inner_obj = json_object_array_get_idx(obj_val, i);
302  struct json_object *licenses_array = json_object_object_get(inner_obj, "licenses");
303  if (licenses_array == NULL) {
304  continue;
305  }
306  for (int j = 0; j < json_object_array_length(licenses_array); ++j) {
307  struct json_object *license_obj = json_object_array_get_idx(licenses_array, j);
308  printf("%s -> %s\n", obj_filename,
309  json_object_get_string(json_object_object_get(license_obj, "name")));
310  }
311  const char *matched = json_object_get_string(
312  json_object_object_get(inner_obj, "matched"));
313  printf("%s matched with purls: ", matched);
314  struct json_object *purl_array = json_object_object_get(inner_obj, "purl");
315  for (int j = 0; j < json_object_array_length(purl_array); ++j) {
316  printf("%s,", json_object_get_string(
317  json_object_array_get_idx(purl_array, j)));
318  }
319  printf("\n");
320  }
321  }
322  }
323  PQfinish(db_conn);
325  return (0);
326 } /* main() */
PGconn * pgConn
Database connection.
Definition: adj2nest.c:86
char BuildVersion[]
Definition: buckets.c:68
int Agent_pk
agent identifier
Definition: finder.c:19
Usage()
Print Usage statement.
Definition: fo_dbcheck.php:63
FUNCTION int GetUploadPerm(PGconn *pgConn, long UploadPk, int user_pk)
Get users permission to this upload.
Definition: libfossagent.c:378
FUNCTION int fo_CreateARSTable(PGconn *pgConn, const char *tableName)
Create ars table if it doesn't already exist.
Definition: libfossagent.c:270
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:214
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:158
int fo_checkPQresult(PGconn *pgConn, PGresult *result, char *sql, char *FileID, int LineNumb)
Check the result status of a postgres SELECT.
Definition: libfossdb.c:170
int fo_tableExists(PGconn *pgConn, const char *tableName)
Check if table exists. Note, this assumes the database name is 'fossology'.
Definition: libfossdb.c:232
int fo_checkPQcommand(PGconn *pgConn, PGresult *result, char *sql, char *FileID, int LineNumb)
Check the result status of a postgres commands (not select) If an error occured, write the error to s...
Definition: libfossdb.c:204
#define PERM_WRITE
Read-Write permission.
Definition: libfossology.h:33
void fo_scheduler_disconnect(int retcode)
Disconnect the scheduler connection.
char * fo_sysconfig(const char *sectionname, const char *variablename)
gets a system configuration variable from the configuration data.
int fo_scheduler_userID()
Gets the id of the user that created the job that the agent is running.
char * fo_scheduler_current()
Get the last read string from the scheduler.
char * fo_scheduler_next()
Get the next data to process from the scheduler.
void fo_scheduler_connect(int *argc, char **argv, PGconn **db_conn)
Establish a connection between an agent and the scheduler.
int main(int argc, char *argv[])
main function for the pkgagent
Definition: main.c:76
PGconn * db_conn
The connection to Database.
Definition: pkgagent.c:22
void ParseResults(char *folder)
Parse results from a temporary file and store results on database.
Definition: snippet_scan.c:185
int ScanFolder(char *folder)
Scans a Temporary folder.
Definition: snippet_scan.c:269
scanoss header
const char * upload_pk
Definition: sqlstatements.h:82