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