FOSSology  4.4.0
Open Source License Compliance by Open Source Software
walk.c
Go to the documentation of this file.
1 /*
2  SPDX-FileCopyrightText: © 2010-2014 Hewlett-Packard Development Company, L.P.
3 
4  SPDX-License-Identifier: GPL-2.0-only
5 */
6 
12 #include "buckets.h"
13 
14 extern int debug;
15 
34 FUNCTION int walkTree(PGconn *pgConn, pbucketdef_t bucketDefArray, int agent_pk,
35  int uploadtree_pk, int skipProcessedCheck,
36  int hasPrules)
37 {
38  char *fcnName = "walkTree";
39  char sqlbuf[128];
40  PGresult *result, *origresult;
41  int numChildren, childIdx;
42  int rv = 0;
43  int bucketpool_pk = bucketDefArray->bucketpool_pk;
45  uploadtree_t childuploadtree;
46 
47  if (debug) printf("---- START walkTree, uploadtree_pk=%d ----\n",uploadtree_pk);
48 
49  /* get uploadtree rec for uploadtree_pk */
50  sprintf(sqlbuf, "select pfile_fk, lft, rgt, ufile_mode, ufile_name, upload_fk from %s where uploadtree_pk=%d",
51  bucketDefArray->uploadtree_tablename, uploadtree_pk);
52  origresult = PQexec(pgConn, sqlbuf);
53  if (fo_checkPQresult(pgConn, origresult, sqlbuf, fcnName, __LINE__)) return -1;
54  if (PQntuples(origresult) == 0)
55  {
56  printf("FATAL: %s.%s missing uploadtree_pk %d\n", __FILE__, fcnName, uploadtree_pk);
57  return -1;
58  }
59  uploadtree.uploadtree_pk = uploadtree_pk;
60  uploadtree.pfile_fk = atol(PQgetvalue(origresult, 0, 0));
61  uploadtree.lft = atol(PQgetvalue(origresult, 0, 1));
62  uploadtree.rgt = atol(PQgetvalue(origresult, 0, 2));
63  uploadtree.ufile_mode = atol(PQgetvalue(origresult, 0, 3));
64  uploadtree.ufile_name = strdup(PQgetvalue(origresult, 0, 4));
65  uploadtree.upload_fk = atol(PQgetvalue(origresult, 0, 5));
66 
67  if (!skipProcessedCheck)
68  if (processed(pgConn, agent_pk, bucketDefArray->nomos_agent_pk, uploadtree.pfile_fk, uploadtree.uploadtree_pk, bucketpool_pk, 0)) return 0;
69 
70  /* If this is a leaf node, process it
71  (i.e. determine what bucket it belongs in).
72  This will only be executed in the case where the unpacked upload
73  is itself a single file.
74  */
75  if (uploadtree.rgt == (uploadtree.lft+1))
76  {
77  return processFile(pgConn, bucketDefArray, &uploadtree, agent_pk, hasPrules);
78  }
79 
80  /* Since uploadtree_pk isn't a leaf, find its immediate children and
81  process (if child is leaf) or recurse on container.
82  Packages need both processing (check bucket_def rules) and recursion.
83  */
84  sprintf(sqlbuf, "select uploadtree_pk,pfile_fk, lft, rgt, ufile_mode, ufile_name from %s where parent=%d",
85  bucketDefArray->uploadtree_tablename, uploadtree_pk);
86  result = PQexec(pgConn, sqlbuf);
87  if (fo_checkPQresult(pgConn, result, sqlbuf, fcnName, __LINE__)) return -1;
88  numChildren = PQntuples(result);
89  if (numChildren == 0)
90  {
91  printf("FATAL: %s.%s: Inconsistent uploadtree. uploadtree_pk %d should have children based on lft and rgt\n",
92  __FILE__, fcnName, uploadtree_pk);
93  return -1;
94  }
95 
96  /* process (find buckets for) each child */
97  for (childIdx = 0; childIdx < numChildren; childIdx++)
98  {
99  childuploadtree.uploadtree_pk = atol(PQgetvalue(result, childIdx, 0));
100  childuploadtree.pfile_fk = atol(PQgetvalue(result, childIdx, 1));
101  if (processed(pgConn, agent_pk, bucketDefArray->nomos_agent_pk, childuploadtree.pfile_fk, childuploadtree.uploadtree_pk, bucketpool_pk, 0)) continue;
102 
103  childuploadtree.lft = atoi(PQgetvalue(result, childIdx, 2));
104  childuploadtree.rgt = atoi(PQgetvalue(result, childIdx, 3));
105  childuploadtree.ufile_mode = atoi(PQgetvalue(result, childIdx, 4));
106  childuploadtree.ufile_name = strdup(PQgetvalue(result, childIdx, 5));
107  childuploadtree.upload_fk = uploadtree.upload_fk;
108 
109  /* if child is a leaf, just process rather than recurse
110  */
111  if (childuploadtree.rgt == (childuploadtree.lft+1))
112  {
113  if (childuploadtree.pfile_fk > 0)
114  processFile(pgConn, bucketDefArray, &childuploadtree,
115  agent_pk, hasPrules);
116  free(childuploadtree.ufile_name);
117  continue;
118  }
119 
120  /* not a leaf so recurse */
121  rv = walkTree(pgConn, bucketDefArray, agent_pk, childuploadtree.uploadtree_pk,
122  1, hasPrules);
123  if (rv)
124  {
125  free(childuploadtree.ufile_name);
126  return rv;
127  }
128 
129  /* done processing children, now processes (find buckets) for the container */
130  processFile(pgConn, bucketDefArray, &childuploadtree, agent_pk,
131  hasPrules);
132 
133  free(childuploadtree.ufile_name);
134  } // end of child processing
135 
136 
137  PQclear(result);
138  PQclear(origresult);
139  return rv;
140 } /* walkTree */
141 
142 
167 FUNCTION int processFile(PGconn *pgConn, pbucketdef_t bucketDefArray,
168  puploadtree_t puploadtree, int agent_pk, int hasPrules)
169 {
170  int *bucketList; // null terminated list of bucket_pk's
171  int rv = 0;
172  int isPkg = 0;
173  char *fcnName = "processFile";
174  char sql[1024];
175  PGresult *result;
176  package_t package;
177 
178  /* Can skip processing for terminal artifacts (e.g. empty artifact container,
179  and "artifact.meta" files.
180  */
181  if (IsArtifact(puploadtree->ufile_mode)
182  && (puploadtree->rgt == puploadtree->lft+1)) return 0;
183 
184  package.pkgname[0] = 0;
185  package.pkgvers[0] = 0;
186  package.vendor[0] = 0;
187  package.srcpkgname[0] = 0;
188 
189  /* If is a container and hasPrules and pfile_pk != 0,
190  then get the package record (if it is a package).
191  */
192  if ((puploadtree->pfile_fk && (IsContainer(puploadtree->ufile_mode))) && hasPrules)
193  {
194  /* note: for binary packages, srcpkg is the name of the source package.
195  srcpkg is null if the pkg is a source package.
196  For debian, srcpkg may also be null if the source and binary packages
197  have the same name and version.
198  */
199  snprintf(sql, sizeof(sql),
200  "select pkg_name, version, '' as vendor, source as srcpkg from pkg_deb where pfile_fk='%d' \
201  union all \
202  select pkg_name, version, vendor, source_rpm as srcpkg from pkg_rpm where pfile_fk='%d' ",
203  puploadtree->pfile_fk, puploadtree->pfile_fk);
204  result = PQexec(pgConn, sql);
205  if (fo_checkPQresult(pgConn, result, sql, fcnName, __LINE__)) return 0;
206  isPkg = PQntuples(result);
207 
208  /* is the file a package?
209  Then replace any terminal newline with a null in the package name.
210  If not, continue on to the next bucket def.
211  */
212  if (isPkg)
213  {
214  strncpy(package.pkgname, PQgetvalue(result, 0, 0), sizeof(package.pkgname)-1);
215  package.pkgname[sizeof(package.pkgname)-1] = 0;
216  if (package.pkgname[strlen(package.pkgname)-1] == '\n')
217  package.pkgname[strlen(package.pkgname)-1] = 0;
218 
219  strncpy(package.pkgvers, PQgetvalue(result, 0, 1), sizeof(package.pkgvers)-1);
220  package.pkgvers[sizeof(package.pkgvers)-1] = 0;
221  if (package.pkgvers[strlen(package.pkgvers)-1] == '\n')
222  package.pkgvers[strlen(package.pkgvers)-1] = 0;
223 
224  strncpy(package.vendor, PQgetvalue(result, 0, 2), sizeof(package.vendor)-1);
225  package.vendor[sizeof(package.vendor)-1] = 0;
226  if (package.vendor[strlen(package.vendor)-1] == '\n')
227  package.vendor[strlen(package.vendor)-1] = 0;
228 
229  strncpy(package.srcpkgname, PQgetvalue(result, 0, 3), sizeof(package.srcpkgname)-1);
230  package.srcpkgname[sizeof(package.srcpkgname)-1] = 0;
231  if (package.srcpkgname[strlen(package.srcpkgname)-1] == '\n')
232  package.srcpkgname[strlen(package.srcpkgname)-1] = 0;
233  }
234  PQclear(result);
235  }
236 
237  if (debug) printf("\nFile name: %s\n", puploadtree->ufile_name);
238 
239  /* getContainerBuckets() handles:
240  1) items with no pfile
241  2) artifacts (both with pfile and without)
242  3) all containers
243  */
244  if ((puploadtree->pfile_fk == 0) || (IsArtifact(puploadtree->ufile_mode))
245  || (IsContainer(puploadtree->ufile_mode)))
246  {
247  bucketList = getContainerBuckets(pgConn, bucketDefArray, puploadtree->uploadtree_pk);
248  rv = writeBuckets(pgConn, puploadtree->pfile_fk, puploadtree->uploadtree_pk, bucketList,
249  agent_pk, bucketDefArray->nomos_agent_pk, bucketDefArray->bucketpool_pk);
250  if (bucketList) free(bucketList);
251 
252  /* process packages because they are treated as leafs and as containers */
253  rv = processLeaf(pgConn, bucketDefArray, puploadtree, &package,
254  agent_pk, hasPrules);
255  }
256  else /* processLeaf handles everything else. */
257  {
258  rv = processLeaf(pgConn, bucketDefArray, puploadtree, &package,
259  agent_pk, hasPrules);
260  }
261 
262  return rv;
263 }
PGconn * pgConn
Database connection.
Definition: adj2nest.c:86
int agent_pk
Definition: agent.h:74
FUNCTION int * getContainerBuckets(PGconn *pgConn, pbucketdef_t bucketDefArray, int uploadtree_pk)
Given a container uploadtree_pk and bucketdef, determine what buckets the container is in.
Definition: container.c:36
FUNCTION int processLeaf(PGconn *pgConn, pbucketdef_t bucketDefArray, puploadtree_t puploadtree, ppackage_t ppackage, int agent_pk, int hasPrules)
Determine which bucket(s) a leaf node is in and write results.
Definition: leaf.c:30
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 nomos_agent_pk
Definition: buckets.h:70
char vendor[256]
Definition: buckets.h:119
char pkgname[256]
Definition: buckets.h:117
char srcpkgname[256]
Definition: buckets.h:120
char pkgvers[256]
Definition: buckets.h:118
char * ufile_name
Definition: buckets.h:102
Contains information required by uploadtree elements.
Definition: adj2nest.c:93
FUNCTION int processed(PGconn *pgConn, int agent_pk, int nomos_agent_pk, int pfile_pk, int uploadtree_pk, int bucketpool_pk, int bucket_pk)
Has this pfile or uploadtree_pk already been bucket processed? This only works if the bucket has been...
Definition: validate.c:139
FUNCTION int walkTree(PGconn *pgConn, pbucketdef_t bucketDefArray, int agent_pk, int uploadtree_pk, int skipProcessedCheck, int hasPrules)
This function does a recursive depth first walk through a file tree (uploadtree).
Definition: walk.c:34
FUNCTION int processFile(PGconn *pgConn, pbucketdef_t bucketDefArray, puploadtree_t puploadtree, int agent_pk, int hasPrules)
Process a file.
Definition: walk.c:167
int debug
Definition: buckets.c:57
FUNCTION int writeBuckets(PGconn *pgConn, int pfile_pk, int uploadtree_pk, int *bucketList, int agent_pk, int nomosagent_pk, int bucketpool_pk)
Write bucket results to either db (bucket_file, bucket_container) or stdout.
Definition: write.c:29