FOSSology  4.4.0
Open Source License Compliance by Open Source Software
inits.c
Go to the documentation of this file.
1 /*
2  SPDX-FileCopyrightText: © 2010 Hewlett-Packard Development Company, L.P.
3 
4  SPDX-License-Identifier: GPL-2.0-only
5 */
6 
12 #include "buckets.h"
13 extern int debug;
14 
23 FUNCTION int getBucketpool_pk(PGconn *pgConn, char *bucketpool_name)
24 {
25  char *fcnName = "getBucketpool";
26  int bucketpool_pk=0;
27  char sqlbuf[128];
28  PGresult *result;
29 
30  /* Skip file if it has already been processed for buckets. */
31  sprintf(sqlbuf, "select bucketpool_pk from bucketpool where (bucketpool_name='%s') and (active='Y') order by version desc",
32  bucketpool_name);
33  result = PQexec(pgConn, sqlbuf);
34  if (fo_checkPQresult(pgConn, result, sqlbuf, fcnName, __LINE__)) return 0;
35  if (PQntuples(result) > 0) bucketpool_pk = atoi(PQgetvalue(result, 0, 0));
36  PQclear(result);
37  return bucketpool_pk;
38 }
39 
40 
52 FUNCTION pbucketdef_t initBuckets(PGconn *pgConn, int bucketpool_pk, cacheroot_t *pcroot)
53 {
54  char *fcnName = "initBuckets";
55  char sqlbuf[256];
56  char filepath[256];
57  char hostname[256];
58  PGresult *result;
59  pbucketdef_t bucketDefList = 0;
60  int numRows, rowNum;
61  int rv, numErrors=0;
62  struct stat statbuf;
63 
64  /* reasonable input validation */
65  if ((!pgConn) || (!bucketpool_pk))
66  {
67  printf("ERROR: %s.%s.%d Invalid input pgConn: %lx, bucketpool_pk: %d.\n",
68  __FILE__, fcnName, __LINE__, (unsigned long)pgConn, bucketpool_pk);
69  return 0;
70  }
71 
72  /* get bucket defs from db */
73  sprintf(sqlbuf, "select bucket_pk, bucket_type, bucket_regex, bucket_filename, stopon, bucket_name, applies_to from bucket_def where bucketpool_fk=%d order by bucket_evalorder asc", bucketpool_pk);
74  result = PQexec(pgConn, sqlbuf);
75  if (fo_checkPQresult(pgConn, result, sqlbuf, fcnName, __LINE__)) return 0;
76  numRows = PQntuples(result);
77  if (numRows == 0) /* no bucket recs for pool? return error */
78  {
79  printf("ERROR: %s.%s.%d No bucket defs for pool %d.\n",
80  __FILE__, fcnName, __LINE__, bucketpool_pk);
81  PQclear(result);
82  return 0;
83  }
84 
85  bucketDefList = calloc(numRows+1, sizeof(bucketdef_t));
86  if (bucketDefList == 0)
87  {
88  printf("ERROR: %s.%s.%d No memory to allocate %d bucket defs.\n",
89  __FILE__, fcnName, __LINE__, numRows);
90  return 0;
91  }
92 
93  /* put each db bucket def into bucketDefList in eval order */
94  for (rowNum=0; rowNum<numRows; rowNum++)
95  {
96  bucketDefList[rowNum].bucket_pk = atoi(PQgetvalue(result, rowNum, 0));
97  bucketDefList[rowNum].bucket_type = atoi(PQgetvalue(result, rowNum, 1));
98  bucketDefList[rowNum].bucketpool_pk = bucketpool_pk;
99 
100  /* compile regex if type 3 (REGEX) */
101  if (bucketDefList[rowNum].bucket_type == 3)
102  {
103  rv = regcomp(&bucketDefList[rowNum].compRegex, PQgetvalue(result, rowNum, 2),
104  REG_NOSUB | REG_ICASE | REG_EXTENDED);
105  if (rv != 0)
106  {
107  printf("ERROR: %s.%s.%d Invalid regular expression for bucketpool_pk: %d, bucket: %s\n",
108  __FILE__, fcnName, __LINE__, bucketpool_pk, PQgetvalue(result, rowNum, 5));
109  numErrors++;
110  }
111  bucketDefList[rowNum].regex = strdup(PQgetvalue(result, rowNum, 2));
112  }
113 
114  bucketDefList[rowNum].dataFilename = strdup(PQgetvalue(result, rowNum, 3));
115 
116  /* verify that external file dataFilename exists */
117  if (strlen(bucketDefList[rowNum].dataFilename) > 0)
118  {
119  snprintf(filepath, sizeof(filepath), "%s/bucketpools/%d/%s",
120  PROJECTSTATEDIR, bucketpool_pk, bucketDefList[rowNum].dataFilename);
121  if (stat(filepath, &statbuf) == -1)
122  {
123  hostname[0] = 0;
124  gethostname(hostname, sizeof(hostname));
125  printf("ERROR: %s.%s.%d File: %s is missing on host: %s. bucketpool_pk: %d, bucket: %s\n",
126  __FILE__, fcnName, __LINE__, filepath, hostname, bucketpool_pk, PQgetvalue(result, rowNum, 5));
127  numErrors++;
128  }
129  }
130 
131  /* MATCH_EVERY */
132  if (bucketDefList[rowNum].bucket_type == 1)
133  bucketDefList[rowNum].match_every = getMatchEvery(pgConn, bucketpool_pk, bucketDefList[rowNum].dataFilename, pcroot);
134 
135  /* MATCH_ONLY */
136  if (bucketDefList[rowNum].bucket_type == 2)
137  {
138  bucketDefList[rowNum].match_only = getMatchOnly(pgConn, bucketpool_pk, bucketDefList[rowNum].dataFilename, pcroot);
139  }
140 
141  /* REGEX-FILE */
142  if (bucketDefList[rowNum].bucket_type == 5)
143  {
144  bucketDefList[rowNum].regex_row = getRegexFile(pgConn, bucketpool_pk, bucketDefList[rowNum].dataFilename, pcroot);
145  }
146 
147  bucketDefList[rowNum].stopon = *PQgetvalue(result, rowNum, 4);
148  bucketDefList[rowNum].bucket_name = strdup(PQgetvalue(result, rowNum, 5));
149  bucketDefList[rowNum].applies_to = *PQgetvalue(result, rowNum, 6);
150  }
151  PQclear(result);
152  if (numErrors) return 0;
153 
154  if (debug)
155  {
156  for (rowNum=0; rowNum<numRows; rowNum++)
157  {
158  printf("\nbucket_pk[%d] = %d\n", rowNum, bucketDefList[rowNum].bucket_pk);
159  printf("bucket_name[%d] = %s\n", rowNum, bucketDefList[rowNum].bucket_name);
160  printf("bucket_type[%d] = %d\n", rowNum, bucketDefList[rowNum].bucket_type);
161  printf("dataFilename[%d] = %s\n", rowNum, bucketDefList[rowNum].dataFilename);
162  printf("stopon[%d] = %c\n", rowNum, bucketDefList[rowNum].stopon);
163  printf("applies_to[%d] = %c\n", rowNum, bucketDefList[rowNum].applies_to);
164  printf("nomos_agent_pk[%d] = %d\n", rowNum, bucketDefList[rowNum].nomos_agent_pk);
165  printf("bucket_agent_pk[%d] = %d\n", rowNum, bucketDefList[rowNum].bucket_agent_pk);
166  printf("regex[%d] = %s\n", rowNum, bucketDefList[rowNum].regex);
167  }
168  }
169 
170  return bucketDefList;
171 }
172 
173 
185 FUNCTION int *getMatchOnly(PGconn *pgConn, int bucketpool_pk,
186  char *filename, cacheroot_t *pcroot)
187 {
188  char *fcnName = "getMatchOnly";
189  char *delims = ",\t\n\r";
190  char *sp;
191  char filepath[256];
192  char inbuf[256];
193  int *match_only = 0;
194  int line_count = 0;
195  int lr_pk;
196  int matchNumb = 0;
197  FILE *fin;
198 
199  /* put together complete file path to match_only file */
200  snprintf(filepath, sizeof(filepath), "%s/bucketpools/%d/%s",
201  PROJECTSTATEDIR, bucketpool_pk, filename);
202 
203  /* open filepath */
204  fin = fopen(filepath, "r");
205  if (!fin)
206  {
207  printf("FATAL: %s.%s.%d Failure to open bucket file %s (pool=%d).\nError: %s\n",
208  __FILE__, fcnName, __LINE__, filepath, bucketpool_pk, strerror(errno));
209  return 0;
210  }
211 
212  /* count lines in file */
213  while (fgets(inbuf, sizeof(inbuf), fin)) line_count++;
214 
215  /* calloc match_only array as lines+1. This set the array to
216  the max possible size +1 for null termination */
217  match_only = calloc(line_count+1, sizeof(int));
218  if (!match_only)
219  {
220  printf("FATAL: %s.%s.%d Unable to allocate %d int array.\n",
221  __FILE__, fcnName, __LINE__, line_count+1);
222  fclose(fin);
223  return 0;
224  }
225 
226  /* read each line fgets
227  A match_only file has one license per line, no leading whitespace.
228  Comments start with leading #
229  */
230  rewind(fin);
231  while (fgets(inbuf, sizeof(inbuf), fin))
232  {
233  /* input string should only contain 1 token (license name) */
234  sp = strtok(inbuf, delims);
235 
236  /* comment? */
237  if ((sp == 0) || (*sp == '#')) continue;
238 
239  /* look up license rf_pk */
240  lr_pk = lrcache_lookup(pcroot, sp);
241  if (lr_pk)
242  {
243  /* save rf_pk in match_only array */
244  match_only[matchNumb++] = lr_pk;
245 //printf("MATCH_ONLY license: %s, FOUND\n", sp);
246  }
247  else
248  {
249 //printf("MATCH_ONLY license: %s, NOT FOUND in DB - ignored\n", sp);
250  }
251  }
252  fclose(fin);
253 
254  return match_only;
255 }
256 
257 
269 FUNCTION int **getMatchEvery(PGconn *pgConn, int bucketpool_pk,
270  char *filename, cacheroot_t *pcroot)
271 {
272  char *fcnName = "getMatchEvery";
273  char filepath[256];
274  char inbuf[256];
275  int **match_every = 0;
276  int **match_every_head = 0;
277  int line_count = 0;
278  int *lr_pkArray;
279  int matchNumb = 0;
280  FILE *fin;
281 
282  /* put together complete file path to match_every file */
283  snprintf(filepath, sizeof(filepath), "%s/bucketpools/%d/%s",
284  PROJECTSTATEDIR, bucketpool_pk, filename);
285 
286  /* open filepath */
287  fin = fopen(filepath, "r");
288  if (!fin)
289  {
290  printf("FATAL: %s.%s.%d Failure to initialize bucket %s (pool=%d).\nError: %s\n",
291  __FILE__, fcnName, __LINE__, filepath, bucketpool_pk, strerror(errno));
292  return 0;
293  }
294 
295  /* count lines in file */
296  while (fgets(inbuf, sizeof(inbuf), fin)) line_count++;
297 
298  /* calloc match_every array as lines+1. This sets the array to
299  the max possible size +1 for null termination */
300  match_every = calloc(line_count+1, sizeof(int *));
301  if (!match_every)
302  {
303  printf("FATAL: %s.%s.%d Unable to allocate %d int array.\n",
304  __FILE__, fcnName, __LINE__, line_count+1);
305  fclose(fin);
306  return 0;
307  }
308  match_every_head = match_every;
309 
310  /* read each line fgets
311  A match_every file has 1-n licenses per line
312  Comments start with leading #
313  */
314  rewind(fin);
315  while (fgets(inbuf, sizeof(inbuf), fin))
316  {
317  /* comment? */
318  if (inbuf[0] == '#') continue;
319  lr_pkArray = getLicsInStr(pgConn, inbuf, pcroot);
320  if (lr_pkArray)
321  {
322  /* save rf_pk in match_every array */
323  match_every[matchNumb++] = lr_pkArray;
324  }
325  }
326 
327  if (!matchNumb)
328  {
329  free(match_every_head);
330  match_every_head = 0;
331  }
332  fclose(fin);
333  return match_every_head;
334 }
335 
336 
360 FUNCTION regex_file_t *getRegexFile(PGconn *pgConn, int bucketpool_pk,
361  char *filename, cacheroot_t *pcroot)
362 {
363  char *fcnName = "getRegexFile";
364  char filepath[256];
365  char inbuf[256];
366  regex_file_t *regex_row_head = 0;
367  int line_count = 0;
368  int rv;
369  int rowNumb = 0;
370  int errorCount = 0;
371  char *Delims = " \t\n\r";
372  char *token;
373  char *saveptr;
374  FILE *fin;
375 
376  /* put together complete file path to match_every file */
377  snprintf(filepath, sizeof(filepath), "%s/bucketpools/%d/%s",
378  PROJECTSTATEDIR, bucketpool_pk, filename);
379 
380  /* open filepath */
381  fin = fopen(filepath, "r");
382  if (!fin)
383  {
384  printf("FATAL: %s.%s.%d Failure to initialize bucket %s (pool=%d).\nError: %s\n",
385  __FILE__, fcnName, __LINE__, filepath, bucketpool_pk, strerror(errno));
386  printf("In v1.3, files were in %s. To be LSB compliate, v1.4 now requires them to be in %s\n",
387  DATADIR, PROJECTSTATEDIR);
388  return 0;
389  }
390 
391  /* count lines in file */
392  while (fgets(inbuf, sizeof(inbuf), fin)) line_count++;
393 
394  /* calloc array as lines+1. This sets the array to
395  the max possible size +1 for null termination */
396  regex_row_head = calloc(line_count+1, sizeof(regex_file_t));
397  if (!regex_row_head)
398  {
399  printf("FATAL: %s.%s.%d Unable to allocate %d regex_file_t array.\n",
400  __FILE__, fcnName, __LINE__, line_count+1);
401  fclose(fin);
402  return 0;
403  }
404 
405  /* read each line fgets
406  File has 1-n expressions per line
407  Comments start with leading #
408  */
409  rewind(fin);
410  while (fgets(inbuf, sizeof(inbuf), fin))
411  {
412  /* comment? */
413  if (inbuf[0] == '#') continue;
414 
415  /* get first token ftype1 */
416  token = strtok_r(inbuf, Delims, &saveptr);
417 
418  /* empty line? */
419  if (token[0] == 0) continue;
420 
421  regex_row_head[rowNumb].ftype1 = getRegexFiletype(token, filepath);
422  if (regex_row_head[rowNumb].ftype1 == 0) break;
423 
424  /* get regex1 */
425  token = strtok_r(NULL, Delims, &saveptr);
426  regex_row_head[rowNumb].regex1 = strdup(token);
427  rv = regcomp(&regex_row_head[rowNumb].compRegex1, token, REG_NOSUB | REG_ICASE);
428  if (rv != 0)
429  {
430  printf("ERROR: %s.%s.%d Invalid regular expression for file: %s, [%s], row: %d\n",
431  __FILE__, fcnName, __LINE__, filepath, token, rowNumb+1);
432  errorCount++;
433  break;
434  }
435 
436  /* get optional operator 'and'=1 or 'or'=2 'not'=3 */
437  token = strtok_r(NULL, Delims, &saveptr);
438  if (!token)
439  {
440  rowNumb++;
441  continue;
442  }
443  else
444  {
445  if (strcasecmp(token, "and") == 0) regex_row_head[rowNumb].op = 1;
446  else
447  if (strcasecmp(token, "or") == 0) regex_row_head[rowNumb].op = 2;
448  else
449  if (strcasecmp(token, "not") == 0) regex_row_head[rowNumb].op = 3;
450  else
451  {
452  printf("ERROR: %s.%s.%d Invalid operator in file: %s, [%s], row: %d\n",
453  __FILE__, fcnName, __LINE__, filepath, token, rowNumb+1);
454  errorCount++;
455  break;
456  }
457  }
458 
459  /* get token ftype2 */
460  token = strtok_r(NULL, Delims, &saveptr);
461  regex_row_head[rowNumb].ftype2 = getRegexFiletype(token, filepath);
462  if (regex_row_head[rowNumb].ftype2 == 0) break;
463 
464  /* get regex2 */
465  token = strtok_r(NULL, Delims, &saveptr);
466  regex_row_head[rowNumb].regex2 = strdup(token);
467  rv = regcomp(&regex_row_head[rowNumb].compRegex2, token, REG_NOSUB | REG_ICASE);
468  if (rv != 0)
469  {
470  printf("ERROR: %s.%s.%d Invalid regular expression for file: %s, [%s], row: %d\n",
471  __FILE__, fcnName, __LINE__, filepath, token, rowNumb+1);
472  errorCount++;
473  break;
474  }
475 
476  rowNumb++;
477  }
478 
479  /* bad file data. Die unceremoniously.
480  * \todo: die more gracefully.
481  */
482  if (errorCount) exit(-1);
483 
484  if (!rowNumb)
485  {
486  free(regex_row_head);
487  regex_row_head = 0;
488  }
489  fclose(fin);
490  return regex_row_head;
491 }
492 
493 
504 FUNCTION int getRegexFiletype(char *token, char *filepath)
505 {
506  if (strcasecmp(token, "filename") == 0) return(1);
507  else
508  if (strcasecmp(token, "license") == 0) return(2);
509  printf("FATAL: Invalid bucket file (%s), unknown filetype (%s)\n",
510  filepath, token);
511  return(0);
512 }
513 
514 
529 FUNCTION int *getLicsInStr(PGconn *pgConn, char *nameStr,
530  cacheroot_t *pcroot)
531 {
532  char *fcnName = "getLicsInStr";
533  char *delims = "|\n\r ";
534  char *sp;
535  int *pkArray;
536  int *pkArrayHead = 0;
537  int lic_count = 1;
538  int lr_pk;
539  int matchNumb = 0;
540 
541  if (!nameStr) return 0;
542 
543  /* count how many seperators are in nameStr
544  number of licenses is the count +1 */
545  sp = nameStr;
546  while (*sp) if (*sp++ == *delims) lic_count++;
547 
548  /* we need lic_count+1 int array. This sets the array to
549  the max possible size +1 for null termination */
550  pkArray = calloc(lic_count+1, sizeof(int));
551  if (!pkArray)
552  {
553  printf("FATAL: %s.%s.%d Unable to allocate %d int array.\n",
554  __FILE__, fcnName, __LINE__, lic_count+1);
555  return 0;
556  }
557  pkArrayHead = pkArray; /* save head of array */
558 
559  /* read each line then read each license in the line
560  Comments start with leading #
561  */
562  while ((sp = strtok(nameStr, delims)) != 0)
563  {
564  /* look up license rf_pk */
565  lr_pk = lrcache_lookup(pcroot, sp);
566  if (lr_pk)
567  {
568  /* save rf_pk in match_every array */
569  pkArray[matchNumb++] = lr_pk;
570  }
571  else
572  {
573  /* license not found in license_ref table, so this can never match */
574  matchNumb = 0;
575  break;
576  }
577  nameStr = 0; // for strtok
578  }
579 
580  if (matchNumb == 0)
581  {
582  free(pkArrayHead);
583  pkArrayHead = 0;
584  }
585 
586  return pkArrayHead;
587 }
588 
589 
603 FUNCTION int LatestNomosAgent(PGconn *pgConn, int upload_pk)
604 {
605  char *fcnName = "LatestNomosAgent";
606  char sql[512];
607  PGresult *result;
608  int nomos_agent_pk = 0;
609 
610  /*** Find the latest enabled nomos agent_pk ***/
611 
612  snprintf(sql, sizeof(sql),
613  "select agent_fk from nomos_ars, agent \
614  WHERE agent_pk=agent_fk and ars_success=true and upload_fk='%d' \
615  and agent_enabled=true order by agent_ts desc limit 1",
616  upload_pk);
617  result = PQexec(pgConn, sql);
618  if (fo_checkPQresult(pgConn, result, sql, fcnName, __LINE__)) return 0;
619  if (PQntuples(result) == 0) return 0;
620  nomos_agent_pk = atoi(PQgetvalue(result,0,0));
621  PQclear(result);
622  return nomos_agent_pk;
623 }
624 
625 
639 FUNCTION int childParent(PGconn *pgConn, int uploadtree_pk)
640 {
641  char *fcnName = "childParent";
642  char sql[256];
643  PGresult *result;
644  int childParent_pk = 0; /* uploadtree_pk */
645 
646  do
647  {
648  snprintf(sql, sizeof(sql),
649  "select uploadtree_pk,ufile_mode from uploadtree where parent=%d limit 1",
650  uploadtree_pk);
651  result = PQexec(pgConn, sql);
652  if (fo_checkPQresult(pgConn, result, sql, fcnName, __LINE__)) break;
653  if (PQntuples(result) == 0) break; /* empty container */
654 
655  /* not an artifact? */
656  if ((atoi(PQgetvalue(result, 0, 1)) & 1<<28) == 0)
657  {
658  childParent_pk = uploadtree_pk;
659  break;
660  }
661  uploadtree_pk = atoi(PQgetvalue(result, 0, 0));
662  PQclear(result);
663  } while (childParent_pk == 0);
664 
665  PQclear(result);
666  return childParent_pk;
667 }
PGconn * pgConn
Database connection.
Definition: adj2nest.c:86
FUNCTION int ** getMatchEvery(PGconn *pgConn, int bucketpool_pk, char *filename, cacheroot_t *pcroot)
Read the match every file filename, for bucket type 1.
Definition: inits.c:269
FUNCTION int * getMatchOnly(PGconn *pgConn, int bucketpool_pk, char *filename, cacheroot_t *pcroot)
Read the match only file (bucket type 2)
Definition: inits.c:185
FUNCTION int LatestNomosAgent(PGconn *pgConn, int upload_pk)
Get the latest nomos agent_pk that has data for this this uploadtree.
Definition: inits.c:603
FUNCTION int getRegexFiletype(char *token, char *filepath)
Given a filetype token from REGEX-FILE return the token int representation.
Definition: inits.c:504
FUNCTION int getBucketpool_pk(PGconn *pgConn, char *bucketpool_name)
Get a bucketpool_pk based on the bucketpool_name.
Definition: inits.c:23
FUNCTION int childParent(PGconn *pgConn, int uploadtree_pk)
Given an uploadtree_pk of a container, find the uploadtree_pk of it's children (i....
Definition: inits.c:639
FUNCTION int * getLicsInStr(PGconn *pgConn, char *nameStr, cacheroot_t *pcroot)
Given a string with | separated license names return an integer array of rf_pk's.
Definition: inits.c:529
FUNCTION regex_file_t * getRegexFile(PGconn *pgConn, int bucketpool_pk, char *filename, cacheroot_t *pcroot)
Parse filename, for bucket type 5 REGEX-FILE Lines are in format:
Definition: inits.c:360
int debug
Definition: buckets.c:57
FUNCTION pbucketdef_t initBuckets(PGconn *pgConn, int bucketpool_pk, cacheroot_t *pcroot)
Initialize the bucket definition list. If an error occured, write the error to stdout.
Definition: inits.c:52
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
FUNCTION long lrcache_lookup(cacheroot_t *pcroot, char *rf_shortname)
Lookup rf_pk in the license_ref cache rf_shortname is the key.
Definition: liccache.c:135
const char * upload_pk
Definition: sqlstatements.h:82
char * bucket_name
Definition: buckets.h:60
char * regex
Definition: buckets.h:62
int ** match_every
Definition: buckets.h:66
char applies_to
Definition: buckets.h:69
regex_file_t * regex_row
Definition: buckets.h:67
char * dataFilename
Definition: buckets.h:64
int * match_only
Definition: buckets.h:65
REGEX-FILE bucket type.
Definition: buckets.h:42
char * regex1
Definition: buckets.h:44
char * regex2
Definition: buckets.h:48