FOSSology  3.2.0rc1
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 Copyright (C) 2009-2013 Hewlett-Packard Development Company, L.P.
5 Copyright (C) 2015 Siemens AG
6 
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License
9 version 2 as published by the Free Software Foundation.
10 
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License along
17 with this program; if not, write to the Free Software Foundation, Inc.,
18 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 
20 ***************************************************************/
21 
27 #include "libfossology.h"
28 
29 #define FUNCTION
30 
38 {
39  char* result;
40  PGresult* resTableName = fo_dbManager_ExecPrepared(
41  fo_dbManager_PrepareStamement(
42  dbManager,
43  "getUploadTreeTableName",
44  "SELECT uploadtree_tablename from upload where upload_pk=$1 limit 1",
45  int),
46  uploadId
47  );
48  if (!resTableName)
49  {
50  result = g_strdup("uploadtree");
51  return result;
52  }
53 
54  if (PQntuples(resTableName) == 0)
55  {
56  PQclear(resTableName);
57  result = g_strdup("uploadtree");
58  return result;
59  }
60 
61  result = g_strdup(PQgetvalue(resTableName, 0, 0));
62  PQclear(resTableName);
63  return result;
64 }
65 
73 PGresult* queryFileIdsForUpload(fo_dbManager* dbManager, int uploadId, bool ignoreFilesWithMimeType)
74 {
75  PGresult* result;
76  char SQL[1024];
77 
78  char* uploadtreeTableName = getUploadTreeTableName(dbManager, uploadId);
79  char* queryName;
80 
81  if (strcmp(uploadtreeTableName, "uploadtree_a") == 0)
82  {
83  queryName = g_strdup_printf("queryFileIdsForUpload.%s", uploadtreeTableName);
84  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",
85  uploadtreeTableName);
86  }
87  else {
88  queryName = g_strdup_printf("queryFileIdsForUpload.%s", uploadtreeTableName);
89  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",
90  uploadtreeTableName);
91  }
92 
93  if (ignoreFilesWithMimeType)
94  {
95  queryName = g_strdup_printf("%s.%s", queryName, "WithMimeType");
96  strcat(SQL, " AND (pfile_mimetypefk not in (SELECT mimetype_pk from mimetype where mimetype_name=any(string_to_array(( \
97  SELECT conf_value from sysconfig where variablename='SkipFiles'),','))))");
98  }
99 
100  if (strcmp(uploadtreeTableName, "uploadtree_a") == 0)
101  {
102  result = fo_dbManager_ExecPrepared(
103  fo_dbManager_PrepareStamement(
104  dbManager,
105  queryName,
106  SQL,
107  int),
108  uploadId
109  );
110  g_free(queryName);
111  }
112  else
113  {
114  result = fo_dbManager_ExecPrepared(
115  fo_dbManager_PrepareStamement(
116  dbManager,
117  queryName,
118  SQL,
119  int),
120  uploadId
121  );
122  g_free(queryName);
123  }
124 
125  g_free(uploadtreeTableName);
126 
127  return result;
128 }
129 
137 {
138  PGresult* fileNameResult = fo_dbManager_ExecPrepared(
139  fo_dbManager_PrepareStamement(
140  dbManager,
141  "queryPFileForFileId",
142  "select pfile_sha1 || '.' || pfile_md5 ||'.'|| pfile_size AS pfilename from pfile where pfile_pk=$1",
143  long),
144  fileId
145  );
146 
147  if (PQntuples(fileNameResult) == 0)
148  {
149  PQclear(fileNameResult);
150  return NULL;
151  }
152 
153  char* pFile = g_strdup(PQgetvalue(fileNameResult, 0, 0));
154  PQclear(fileNameResult);
155  return pFile;
156 }
157 
172 FUNCTION int fo_GetAgentKey(PGconn* pgConn, const char* agent_name, long Upload_pk, const char* rev, const char* agent_desc)
173 {
174  int Agent_pk = -1; /* agent identifier */
175  char sql[256];
176  char sqlselect[256];
177  char sqlupdate[256];
178  PGresult* result;
179 
180  /* get the exact agent rec requested */
181  sprintf(sqlselect, "SELECT agent_pk,agent_desc FROM agent WHERE agent_name ='%s' order by agent_ts desc limit 1",
182  agent_name);
183  result = PQexec(pgConn, sqlselect);
184  if (fo_checkPQresult(pgConn, result, sqlselect, __FILE__, __LINE__)) return 0;
185  if (PQntuples(result) == 0)
186  {
187  PQclear(result);
188  /* no match, so add an agent rec */
189  sprintf(sql, "INSERT INTO agent (agent_name,agent_desc,agent_enabled,agent_rev) VALUES ('%s',E'%s','%d', '%s')",
190  agent_name, agent_desc, 1, rev);
191  result = PQexec(pgConn, sql);
192  if (fo_checkPQcommand(pgConn, result, sqlselect, __FILE__, __LINE__)) return 0;
193 
194  result = PQexec(pgConn, sqlselect);
195  if (fo_checkPQresult(pgConn, result, sqlselect, __FILE__, __LINE__)) return 0;
196  }
197 
198  Agent_pk = atol(PQgetvalue(result, 0, 0));
199  /* Compare agent_desc */
200  if(!(strcmp(PQgetvalue(result, 0, 1),agent_desc) == 0)){
201  PQclear(result);
202  sprintf(sqlupdate, "UPDATE agent SET agent_desc = E'%s' where agent_pk = '%d'",agent_desc, Agent_pk);
203  result = PQexec(pgConn, sqlupdate);
204  }
205  PQclear(result);
206  return Agent_pk;
207 } /* fo_GetAgentKey() */
208 
209 
228 FUNCTION int fo_WriteARS(PGconn* pgConn, int ars_pk, int upload_pk, int agent_pk,
229  const char* tableName, const char* ars_status, int ars_success)
230 {
231  char sql[1024];
232  PGresult* result;
233 
234  /* does ars table exist? If not, create it. */
235  if (!fo_CreateARSTable(pgConn, tableName)) return (0);
236 
237  /* If ars_pk is null,
238  * write the ars_status=false record
239  * and return the ars_pk.
240  */
241  if (!ars_pk)
242  {
243  snprintf(sql, sizeof(sql), "insert into %s (agent_fk, upload_fk) values(%d,%d)",
244  tableName, agent_pk, upload_pk);
245  result = PQexec(pgConn, sql);
246  if (fo_checkPQcommand(pgConn, result, sql, __FILE__, __LINE__)) return 0;
247 
248  /* get primary key */
249  snprintf(sql, sizeof(sql), "SELECT currval('nomos_ars_ars_pk_seq')");
250  result = PQexec(pgConn, sql);
251  if (fo_checkPQresult(pgConn, result, sql, __FILE__, __LINE__))
252  return (0);
253  ars_pk = atoi(PQgetvalue(result, 0, 0));
254  PQclear(result);
255  }
256  else
257  {
258  /* If ars_pk is not null, update success, status and endtime */
259  if (ars_status)
260  {
261  snprintf(sql, sizeof(sql), "update %s set ars_success=%s, ars_status='%s',ars_endtime=now() where ars_pk = %d",
262  tableName, ars_success ? "True" : "False", ars_status, ars_pk);
263  }
264  else
265  {
266  snprintf(sql, sizeof(sql), "update %s set ars_success=%s, ars_endtime=now() where ars_pk = %d",
267  tableName, ars_success ? "True" : "False", ars_pk);
268  }
269  result = PQexec(pgConn, sql);
270  if (fo_checkPQcommand(pgConn, result, sql, __FILE__, __LINE__)) return 0;
271  }
272  return (ars_pk);
273 } /* fo_WriteARS() */
274 
275 
284 FUNCTION int fo_CreateARSTable(PGconn* pgConn, const char* tableName)
285 {
286  char sql[1024];
287  PGresult* result;
288 
289  if (fo_tableExists(pgConn, tableName)) return 1; // table already exists
290 
291  snprintf(sql, sizeof(sql), "create table %s() inherits(ars_master);\
292  ALTER TABLE ONLY %s ADD CONSTRAINT %s_agent_fk_fkc FOREIGN KEY (agent_fk) REFERENCES agent(agent_pk);\
293  ALTER TABLE ONLY %s ADD CONSTRAINT %s_upload_fk_fkc FOREIGN KEY (upload_fk) REFERENCES upload(upload_pk) ON DELETE CASCADE;",
294  tableName, tableName, tableName, tableName, tableName);
295 /* ALTER TABLE ONLY %s ADD CONSTRAINT %s_pkey1 PRIMARY KEY (ars_pk); \ */
296 
297 
298  result = PQexec(pgConn, sql);
299  if (fo_checkPQcommand(pgConn, result, sql, __FILE__, __LINE__)) return 0;
300  return 1; /* success */
301 } /* fo_CreateARSTable() */
302 
309 FUNCTION int max(int permGroup, int permPublic)
310 {
311  return ( permGroup > permPublic ) ? permGroup : permPublic;
312 }
313 
320 FUNCTION int min(int user_perm, int permExternal)
321 {
322  return ( user_perm < permExternal ) ? user_perm: permExternal;
323 }
324 
335 FUNCTION int getEffectivePermissionOnUpload(PGconn* pgConn, long UploadPk, int user_pk, int user_perm)
336 {
337  PGresult* result;
338  char SQL[1024];
339  int permGroup=0, permPublic=0;
340 
341 
342  /* Get the user permission level for this upload */
343  snprintf(SQL, sizeof(SQL),
344  "select max(perm) as perm \
345  from perm_upload, group_user_member \
346  where perm_upload.upload_fk=%ld \
347  and user_fk=%d \
348  and group_user_member.group_fk=perm_upload.group_fk",
349  UploadPk, user_pk);
350  result = PQexec(pgConn, SQL);
351  if (!fo_checkPQresult(pgConn, result, SQL, __FILE__, __LINE__)
352  && PQntuples(result) > 0)
353  {
354  permGroup = atoi(PQgetvalue(result, 0, 0));
355  }
356  PQclear(result);
357 
358  /* Get the public permission level */
359  snprintf(SQL, sizeof(SQL),
360  "select public_perm \
361  from upload \
362  where upload_pk=%ld",
363  UploadPk);
364  result = PQexec(pgConn, SQL);
365  fo_checkPQresult(pgConn, result, SQL, __FILE__, __LINE__);
366  if (!fo_checkPQresult(pgConn, result, SQL, __FILE__, __LINE__)
367  && PQntuples(result) > 0)
368  {
369  permPublic = atoi(PQgetvalue(result, 0, 0));
370  }
371  PQclear(result);
372 
373  return min(user_perm, max(permGroup, permPublic));
374 }
375 
385 FUNCTION int GetUploadPerm(PGconn* pgConn, long UploadPk, int user_pk)
386 {
387  PGresult* result;
388  char SQL[1024];
389  int user_perm;
390 
391  /* Check the users PLUGIN_DB level. PLUGIN_DB_ADMIN are superusers. */
392  snprintf(SQL, sizeof(SQL), "select user_perm from users where user_pk='%d'", user_pk);
393  result = PQexec(pgConn, SQL);
394  fo_checkPQresult(pgConn, result, SQL, __FILE__, __LINE__);
395  if (PQntuples(result) < 1)
396  {
397  LOG_ERROR("No records returned in %s", SQL);
398  return PERM_NONE;
399  }
400  user_perm = atoi(PQgetvalue(result, 0, 0));
401  PQclear(result);
402  if (user_perm >= PLUGIN_DB_ADMIN)
403  {
404  return PERM_ADMIN;
405  }
406 
407  return getEffectivePermissionOnUpload(pgConn, UploadPk, user_pk, user_perm);
408 }
409 
410 
421 FUNCTION char* GetUploadtreeTableName(PGconn* pgConn, int upload_pk)
422 {
423  PGresult* result;
424  char* uploadtree_tablename = 0;
425  char SQL[1024];
426 
427  /* Get the uploadtree table name from the upload table */
428  snprintf(SQL, sizeof(SQL), "select uploadtree_tablename from upload where upload_pk='%d'", upload_pk);
429  result = PQexec(pgConn, SQL);
430  fo_checkPQresult(pgConn, result, SQL, __FILE__, __LINE__);
431  if (PQntuples(result) == 1) uploadtree_tablename = g_strdup(PQgetvalue(result, 0, 0));
432  PQclear(result);
433 
434  return (uploadtree_tablename);
435 }
436 
437 
449 PGresult* checkDuplicateReq(PGconn* pgConn, int uploadPk, int agentPk)
450 {
451  PGresult* result;
452  char SQL[1024];
453  /* if it is duplicate request (same upload_pk, sameagent_fk), then do not repeat */
454  snprintf(SQL, sizeof(SQL),
455  "select ars_pk from ars_master,agent \
456  where agent_pk=agent_fk and ars_success=true \
457  and upload_fk='%d' and agent_fk='%d'",
458  uploadPk, agentPk);
459  result = PQexec(pgConn, SQL);
460  return result;
461 }
462 
463 
476 PGresult* getSelectedPFiles(PGconn* pgConn, int uploadPk, int agentPk, bool ignoreFilesWithMimeType)
477 {
478  PGresult* result;
479  char SQL[1024];
480 
481  snprintf(SQL, sizeof(SQL),
482  "SELECT pfile_pk, pfile_sha1 || '.' || pfile_md5 || '.' || pfile_size AS pfilename \
483  FROM (SELECT distinct(pfile_fk) AS PF FROM uploadtree WHERE upload_fk='%d' and (ufile_mode&x'3C000000'::int)=0) as SS \
484  left outer join license_file on (PF=pfile_fk and agent_fk='%d') inner join pfile on PF=pfile_pk \
485  WHERE (fl_pk IS null or agent_fk <>'%d')",
486  uploadPk, agentPk, agentPk);
487 
488  if (ignoreFilesWithMimeType)
489  {
490  strcat(SQL, " AND (pfile_mimetypefk not in ( \
491  SELECT mimetype_pk from mimetype where mimetype_name=any(string_to_array(( \
492  SELECT conf_value from sysconfig where variablename='SkipFiles'),','))))");
493  }
494  result = PQexec(pgConn, SQL);
495  return result;
496 }
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:421
int fo_checkPQresult(PGconn *pgConn, PGresult *result, char *sql, char *FileID, int LineNumb)
Check the result status of a postgres SELECT.
Definition: libfossdb.c:181
char * queryPFileForFileId(fo_dbManager *dbManager, long fileId)
Get the pfile name for a given file ID.
Definition: libfossagent.c:136
#define PLUGIN_DB_ADMIN
Plugin requires admin level permission on DB.
Definition: libfossology.h:51
PGconn * pgConn
Database connection.
Definition: adj2nest.c:98
char * getUploadTreeTableName(fo_dbManager *dbManager, int uploadId)
Get the upload tree table name for a given upload.
Definition: libfossagent.c:37
PGresult * fo_dbManager_ExecPrepared(fo_dbManager_PreparedStatement *preparedStatement,...)
Execute a prepared statement.
Definition: standalone.c:31
#define PERM_NONE
User has no permission (not logged in)
Definition: libfossology.h:43
FUNCTION int min(int user_perm, int permExternal)
Get the minimum permission level required.
Definition: libfossagent.c:320
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:215
char SQL[256]
SQL query to execute.
Definition: adj2nest.c:90
int Agent_pk
agent identifier
Definition: finder.c:30
FUNCTION int max(int permGroup, int permPublic)
Get the maximum group privilege.
Definition: libfossagent.c:309
The main FOSSology C library.
FUNCTION int getEffectivePermissionOnUpload(PGconn *pgConn, long UploadPk, int user_pk, int user_perm)
Get users permission to this upload.
Definition: libfossagent.c:335
char * uploadtree_tablename
upload.uploadtree_tablename
Definition: adj2nest.c:112
FUNCTION int fo_CreateARSTable(PGconn *pgConn, const char *tableName)
Create ars table if it doesn&#39;t already exist.
Definition: libfossagent.c:284
fo_dbManager * dbManager
fo_dbManager object
Definition: process.c:28
int agent_pk
Definition: agent.h:85
int fo_tableExists(PGconn *pgConn, const char *tableName)
Check if table exists. Note, this assumes the database name is &#39;fossology&#39;.
Definition: libfossdb.c:243
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
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
FUNCTION int GetUploadPerm(PGconn *pgConn, long UploadPk, int user_pk)
Get users permission to this upload.
Definition: libfossagent.c:385
PGresult * queryFileIdsForUpload(fo_dbManager *dbManager, int uploadId, bool ignoreFilesWithMimeType)
Get all file IDs (pfile_fk) for a given upload.
Definition: libfossagent.c:73
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:476
const char * upload_pk
Definition: sqlstatements.h:93
#define PERM_ADMIN
Administrator.
Definition: libfossology.h:46
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:449