FOSSology  4.4.0
Open Source License Compliance by Open Source Software
libfossagent.c
Go to the documentation of this file.
1 /*
2  libfossagent: Set of generic functions handy for agent development.
3 
4  SPDX-FileCopyrightText: © 2009-2013 Hewlett-Packard Development Company, L.P.
5  SPDX-FileCopyrightText: © 2015 Siemens AG
6 
7  SPDX-License-Identifier: GPL-2.0-only
8 */
9 
15 #include "libfossology.h"
16 
17 #define FUNCTION
18 
26 {
27  char* result;
28  PGresult* resTableName = fo_dbManager_ExecPrepared(
29  fo_dbManager_PrepareStamement(
30  dbManager,
31  "getUploadTreeTableName",
32  "SELECT uploadtree_tablename from upload where upload_pk=$1 limit 1",
33  int),
34  uploadId
35  );
36  if (!resTableName)
37  {
38  result = g_strdup("uploadtree");
39  return result;
40  }
41 
42  if (PQntuples(resTableName) == 0)
43  {
44  PQclear(resTableName);
45  result = g_strdup("uploadtree");
46  return result;
47  }
48 
49  result = g_strdup(PQgetvalue(resTableName, 0, 0));
50  PQclear(resTableName);
51  return result;
52 }
53 
61 PGresult* queryFileIdsForUpload(fo_dbManager* dbManager, int uploadId, bool ignoreFilesWithMimeType)
62 {
63  PGresult* result;
64  char SQL[1024];
65 
66  char* uploadtreeTableName = getUploadTreeTableName(dbManager, uploadId);
67  char* queryName;
68 
69  if (strcmp(uploadtreeTableName, "uploadtree_a") == 0)
70  {
71  queryName = g_strdup_printf("queryFileIdsForUpload.%s", uploadtreeTableName);
72  g_snprintf(SQL, sizeof(SQL), "select distinct(pfile_fk) from %s join pfile on pfile_pk=pfile_fk where upload_fk=$1 and (ufile_mode&x'3C000000'::int)=0",
73  uploadtreeTableName);
74  }
75  else {
76  queryName = g_strdup_printf("queryFileIdsForUpload.%s", uploadtreeTableName);
77  g_snprintf(SQL, sizeof(SQL), "select distinct(pfile_fk) from %s join pfile on pfile_pk=pfile_fk where (ufile_mode&x'3C000000'::int)=0",
78  uploadtreeTableName);
79  }
80 
81  if (ignoreFilesWithMimeType)
82  {
83  queryName = g_strdup_printf("%s.%s", queryName, "WithMimeType");
84  strcat(SQL, " AND (pfile_mimetypefk not in (SELECT mimetype_pk from mimetype where mimetype_name=any(string_to_array(( \
85  SELECT conf_value from sysconfig where variablename='SkipFiles'),','))))");
86  }
87 
88  if (strcmp(uploadtreeTableName, "uploadtree_a") == 0)
89  {
91  fo_dbManager_PrepareStamement(
92  dbManager,
93  queryName,
94  SQL,
95  int),
96  uploadId
97  );
98  g_free(queryName);
99  }
100  else
101  {
102  result = fo_dbManager_ExecPrepared(
103  fo_dbManager_PrepareStamement(
104  dbManager,
105  queryName,
106  SQL)
107  );
108  g_free(queryName);
109  }
110 
111  g_free(uploadtreeTableName);
112 
113  return result;
114 }
115 
123 {
124  PGresult* fileNameResult = fo_dbManager_ExecPrepared(
125  fo_dbManager_PrepareStamement(
126  dbManager,
127  "queryPFileForFileId",
128  "select pfile_sha1 || '.' || pfile_md5 ||'.'|| pfile_size AS pfilename from pfile where pfile_pk=$1",
129  long),
130  fileId
131  );
132 
133  if (PQntuples(fileNameResult) == 0)
134  {
135  PQclear(fileNameResult);
136  return NULL;
137  }
138 
139  char* pFile = g_strdup(PQgetvalue(fileNameResult, 0, 0));
140  PQclear(fileNameResult);
141  return pFile;
142 }
143 
158 FUNCTION int fo_GetAgentKey(PGconn* pgConn, const char* agent_name, long Upload_pk, const char* rev, const char* agent_desc)
159 {
160  int Agent_pk = -1; /* agent identifier */
161  char sql[256];
162  char sqlselect[256];
163  char sqlupdate[256];
164  PGresult* result;
165 
166  /* get the exact agent rec requested */
167  sprintf(sqlselect, "SELECT agent_pk,agent_desc FROM agent WHERE agent_name ='%s' order by agent_ts desc limit 1",
168  agent_name);
169  result = PQexec(pgConn, sqlselect);
170  if (fo_checkPQresult(pgConn, result, sqlselect, __FILE__, __LINE__)) return 0;
171  if (PQntuples(result) == 0)
172  {
173  PQclear(result);
174  /* no match, so add an agent rec */
175  sprintf(sql, "INSERT INTO agent (agent_name,agent_desc,agent_enabled,agent_rev) VALUES ('%s',E'%s','%d', '%s')",
176  agent_name, agent_desc, 1, rev);
177  result = PQexec(pgConn, sql);
178  if (fo_checkPQcommand(pgConn, result, sqlselect, __FILE__, __LINE__)) return 0;
179 
180  result = PQexec(pgConn, sqlselect);
181  if (fo_checkPQresult(pgConn, result, sqlselect, __FILE__, __LINE__)) return 0;
182  }
183 
184  Agent_pk = atol(PQgetvalue(result, 0, 0));
185  /* Compare agent_desc */
186  if(!(strcmp(PQgetvalue(result, 0, 1),agent_desc) == 0)){
187  PQclear(result);
188  sprintf(sqlupdate, "UPDATE agent SET agent_desc = E'%s' where agent_pk = '%d'",agent_desc, Agent_pk);
189  result = PQexec(pgConn, sqlupdate);
190  }
191  PQclear(result);
192  return Agent_pk;
193 } /* fo_GetAgentKey() */
194 
195 
214 FUNCTION int fo_WriteARS(PGconn* pgConn, int ars_pk, int upload_pk, int agent_pk,
215  const char* tableName, const char* ars_status, int ars_success)
216 {
217  char sql[1024];
218  PGresult* result;
219 
220  /* does ars table exist? If not, create it. */
221  if (!fo_CreateARSTable(pgConn, tableName)) return (0);
222 
223  /* If ars_pk is null,
224  * write the ars_status=false record
225  * and return the ars_pk.
226  */
227  if (!ars_pk)
228  {
229  snprintf(sql, sizeof(sql), "insert into %s (agent_fk, upload_fk) values(%d,%d)",
230  tableName, agent_pk, upload_pk);
231  result = PQexec(pgConn, sql);
232  if (fo_checkPQcommand(pgConn, result, sql, __FILE__, __LINE__)) return 0;
233 
234  /* get primary key */
235  snprintf(sql, sizeof(sql), "SELECT currval('nomos_ars_ars_pk_seq')");
236  result = PQexec(pgConn, sql);
237  if (fo_checkPQresult(pgConn, result, sql, __FILE__, __LINE__))
238  return (0);
239  ars_pk = atoi(PQgetvalue(result, 0, 0));
240  PQclear(result);
241  }
242  else
243  {
244  /* If ars_pk is not null, update success, status and endtime */
245  if (ars_status)
246  {
247  snprintf(sql, sizeof(sql), "update %s set ars_success=%s, ars_status='%s',ars_endtime=now() where ars_pk = %d",
248  tableName, ars_success ? "True" : "False", ars_status, ars_pk);
249  }
250  else
251  {
252  snprintf(sql, sizeof(sql), "update %s set ars_success=%s, ars_endtime=now() where ars_pk = %d",
253  tableName, ars_success ? "True" : "False", ars_pk);
254  }
255  result = PQexec(pgConn, sql);
256  if (fo_checkPQcommand(pgConn, result, sql, __FILE__, __LINE__)) return 0;
257  }
258  return (ars_pk);
259 } /* fo_WriteARS() */
260 
261 
270 FUNCTION int fo_CreateARSTable(PGconn* pgConn, const char* tableName)
271 {
272  char sql[1024];
273  PGresult* result;
274 
275  if (fo_tableExists(pgConn, tableName)) return 1; // table already exists
276 
277  snprintf(sql, sizeof(sql), "create table %s() inherits(ars_master);\
278  ALTER TABLE ONLY %s ADD CONSTRAINT %s_agent_fk_fkc FOREIGN KEY (agent_fk) REFERENCES agent(agent_pk);\
279  ALTER TABLE ONLY %s ADD CONSTRAINT %s_upload_fk_fkc FOREIGN KEY (upload_fk) REFERENCES upload(upload_pk) ON DELETE CASCADE;",
280  tableName, tableName, tableName, tableName, tableName);
281 /* ALTER TABLE ONLY %s ADD CONSTRAINT %s_pkey1 PRIMARY KEY (ars_pk); \ */
282 
283 
284  result = PQexec(pgConn, sql);
285  if (fo_checkPQcommand(pgConn, result, sql, __FILE__, __LINE__)) return 0;
286  return 1; /* success */
287 } /* fo_CreateARSTable() */
288 
295 FUNCTION int max(int permGroup, int permPublic)
296 {
297  return ( permGroup > permPublic ) ? permGroup : permPublic;
298 }
299 
306 FUNCTION int min(int user_perm, int permExternal)
307 {
308  return ( user_perm < permExternal ) ? user_perm: permExternal;
309 }
310 
321 FUNCTION int getEffectivePermissionOnUpload(PGconn* pgConn, long UploadPk, int user_pk, int user_perm)
322 {
323  PGresult* result;
324  char SQL[1024];
325  int permGroup=0, permPublic=0;
326 
327 
328  /* Get the user permission level for this upload */
329  snprintf(SQL, sizeof(SQL),
330  "select max(perm) as perm \
331  from perm_upload, group_user_member \
332  where perm_upload.upload_fk=%ld \
333  and user_fk=%d \
334  and group_user_member.group_fk=perm_upload.group_fk",
335  UploadPk, user_pk);
336  result = PQexec(pgConn, SQL);
337  if (!fo_checkPQresult(pgConn, result, SQL, __FILE__, __LINE__)
338  && PQntuples(result) > 0)
339  {
340  permGroup = atoi(PQgetvalue(result, 0, 0));
341  }
342  PQclear(result);
343 
344  /* Get the public permission level */
345  snprintf(SQL, sizeof(SQL),
346  "select public_perm \
347  from upload \
348  where upload_pk=%ld",
349  UploadPk);
350  result = PQexec(pgConn, SQL);
351  fo_checkPQresult(pgConn, result, SQL, __FILE__, __LINE__);
352  if (!fo_checkPQresult(pgConn, result, SQL, __FILE__, __LINE__)
353  && PQntuples(result) > 0)
354  {
355  permPublic = atoi(PQgetvalue(result, 0, 0));
356  }
357  PQclear(result);
358 
359  if (user_perm >= PLUGIN_DB_ADMIN)
360  {
361  return PERM_ADMIN;
362  }
363  else
364  {
365  return min(user_perm, max(permGroup, permPublic));
366  }
367 }
368 
378 FUNCTION int GetUploadPerm(PGconn* pgConn, long UploadPk, int user_pk)
379 {
380  PGresult* result;
381  char SQL[1024];
382  int user_perm;
383 
384  /* Check the users PLUGIN_DB level. PLUGIN_DB_ADMIN are superusers. */
385  snprintf(SQL, sizeof(SQL), "select user_perm from users where user_pk='%d'", user_pk);
386  result = PQexec(pgConn, SQL);
387  fo_checkPQresult(pgConn, result, SQL, __FILE__, __LINE__);
388  if (PQntuples(result) < 1)
389  {
390  LOG_ERROR("No records returned in %s", SQL);
391  return PERM_NONE;
392  }
393  user_perm = atoi(PQgetvalue(result, 0, 0));
394  PQclear(result);
395  if (user_perm >= PLUGIN_DB_ADMIN)
396  {
397  return PERM_ADMIN;
398  }
399 
400  return getEffectivePermissionOnUpload(pgConn, UploadPk, user_pk, user_perm);
401 }
402 
403 
414 FUNCTION char* GetUploadtreeTableName(PGconn* pgConn, int upload_pk)
415 {
416  PGresult* result;
417  char* uploadtree_tablename = 0;
418  char SQL[1024];
419 
420  /* Get the uploadtree table name from the upload table */
421  snprintf(SQL, sizeof(SQL), "select uploadtree_tablename from upload where upload_pk='%d'", upload_pk);
422  result = PQexec(pgConn, SQL);
423  fo_checkPQresult(pgConn, result, SQL, __FILE__, __LINE__);
424  if (PQntuples(result) == 1) uploadtree_tablename = g_strdup(PQgetvalue(result, 0, 0));
425  PQclear(result);
426 
427  return (uploadtree_tablename);
428 }
429 
430 
442 PGresult* checkDuplicateReq(PGconn* pgConn, int uploadPk, int agentPk)
443 {
444  PGresult* result;
445  char SQL[1024];
446  /* if it is duplicate request (same upload_pk, sameagent_fk), then do not repeat */
447  snprintf(SQL, sizeof(SQL),
448  "select ars_pk from ars_master,agent \
449  where agent_pk=agent_fk and ars_success=true \
450  and upload_fk='%d' and agent_fk='%d'",
451  uploadPk, agentPk);
452  result = PQexec(pgConn, SQL);
453  return result;
454 }
455 
456 
469 PGresult* getSelectedPFiles(PGconn* pgConn, int uploadPk, int agentPk, bool ignoreFilesWithMimeType)
470 {
471  PGresult* result;
472  char SQL[1024];
473 
474  snprintf(SQL, sizeof(SQL),
475  "SELECT pfile_pk, pfile_sha1 || '.' || pfile_md5 || '.' || pfile_size AS pfilename \
476  FROM (SELECT distinct(pfile_fk) AS PF FROM uploadtree WHERE upload_fk='%d' and (ufile_mode&x'3C000000'::int)=0) as SS \
477  left outer join license_file on (PF=pfile_fk and agent_fk='%d') inner join pfile on PF=pfile_pk \
478  WHERE (fl_pk IS null or agent_fk <>'%d')",
479  uploadPk, agentPk, agentPk);
480 
481  if (ignoreFilesWithMimeType)
482  {
483  strcat(SQL, " AND (pfile_mimetypefk not in ( \
484  SELECT mimetype_pk from mimetype where mimetype_name=any(string_to_array(( \
485  SELECT conf_value from sysconfig where variablename='SkipFiles'),','))))");
486  }
487  result = PQexec(pgConn, SQL);
488  return result;
489 }
char SQL[256]
SQL query to execute.
Definition: adj2nest.c:78
PGconn * pgConn
Database connection.
Definition: adj2nest.c:86
char * uploadtree_tablename
upload.uploadtree_tablename
Definition: adj2nest.c:100
int agent_pk
Definition: agent.h:74
int Agent_pk
agent identifier
Definition: finder.c:19
char * queryPFileForFileId(fo_dbManager *dbManager, long fileId)
Get the pfile name for a given file ID.
Definition: libfossagent.c:122
FUNCTION char * GetUploadtreeTableName(PGconn *pgConn, int upload_pk)
Get the uploadtree table name for this upload_pk If upload_pk does not exist, return "uploadtree".
Definition: libfossagent.c:414
FUNCTION int GetUploadPerm(PGconn *pgConn, long UploadPk, int user_pk)
Get users permission to this upload.
Definition: libfossagent.c:378
FUNCTION int max(int permGroup, int permPublic)
Get the maximum group privilege.
Definition: libfossagent.c:295
char * getUploadTreeTableName(fo_dbManager *dbManager, int uploadId)
Get the upload tree table name for a given upload.
Definition: libfossagent.c:25
FUNCTION int fo_CreateARSTable(PGconn *pgConn, const char *tableName)
Create ars table if it doesn't already exist.
Definition: libfossagent.c:270
PGresult * checkDuplicateReq(PGconn *pgConn, int uploadPk, int agentPk)
Get the upload_pk and agent_pk to find out the agent has already scanned the package.
Definition: libfossagent.c:442
PGresult * queryFileIdsForUpload(fo_dbManager *dbManager, int uploadId, bool ignoreFilesWithMimeType)
Get all file IDs (pfile_fk) for a given upload.
Definition: libfossagent.c:61
FUNCTION int getEffectivePermissionOnUpload(PGconn *pgConn, long UploadPk, int user_pk, int user_perm)
Get users permission to this upload.
Definition: libfossagent.c:321
FUNCTION int min(int user_perm, int permExternal)
Get the minimum permission level required.
Definition: libfossagent.c:306
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
PGresult * getSelectedPFiles(PGconn *pgConn, int uploadPk, int agentPk, bool ignoreFilesWithMimeType)
Get the upload_pk, agent_pk and ignoreFilesWithMimeType to get all the file Ids for nomos.
Definition: libfossagent.c:469
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
The main FOSSology C library.
#define PERM_ADMIN
Administrator.
Definition: libfossology.h:34
#define PERM_NONE
User has no permission (not logged in)
Definition: libfossology.h:31
#define PLUGIN_DB_ADMIN
Plugin requires admin level permission on DB.
Definition: libfossology.h:39
fo_dbManager * dbManager
fo_dbManager object
Definition: process.c:16
PGresult * fo_dbManager_ExecPrepared(fo_dbManager_PreparedStatement *preparedStatement,...)
Execute a prepared statement.
Definition: standalone.c:36
const char * upload_pk
Definition: sqlstatements.h:82