FOSSology  3.2.0rc1
Open Source License Compliance by Open Source Software
inits.c
Go to the documentation of this file.
1 /***************************************************************
2  Copyright (C) 2010 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 extern int debug;
25 
34 FUNCTION int getBucketpool_pk(PGconn *pgConn, char *bucketpool_name)
35 {
36  char *fcnName = "getBucketpool";
37  int bucketpool_pk=0;
38  char sqlbuf[128];
39  PGresult *result;
40 
41  /* Skip file if it has already been processed for buckets. */
42  sprintf(sqlbuf, "select bucketpool_pk from bucketpool where (bucketpool_name='%s') and (active='Y') order by version desc",
43  bucketpool_name);
44  result = PQexec(pgConn, sqlbuf);
45  if (fo_checkPQresult(pgConn, result, sqlbuf, fcnName, __LINE__)) return 0;
46  if (PQntuples(result) > 0) bucketpool_pk = atoi(PQgetvalue(result, 0, 0));
47  PQclear(result);
48  return bucketpool_pk;
49 }
50 
51 
63 FUNCTION pbucketdef_t initBuckets(PGconn *pgConn, int bucketpool_pk, cacheroot_t *pcroot)
64 {
65  char *fcnName = "initBuckets";
66  char sqlbuf[256];
67  char filepath[256];
68  char hostname[256];
69  PGresult *result;
70  pbucketdef_t bucketDefList = 0;
71  int numRows, rowNum;
72  int rv, numErrors=0;
73  struct stat statbuf;
74 
75  /* reasonable input validation */
76  if ((!pgConn) || (!bucketpool_pk))
77  {
78  printf("ERROR: %s.%s.%d Invalid input pgConn: %lx, bucketpool_pk: %d.\n",
79  __FILE__, fcnName, __LINE__, (unsigned long)pgConn, bucketpool_pk);
80  return 0;
81  }
82 
83  /* get bucket defs from db */
84  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);
85  result = PQexec(pgConn, sqlbuf);
86  if (fo_checkPQresult(pgConn, result, sqlbuf, fcnName, __LINE__)) return 0;
87  numRows = PQntuples(result);
88  if (numRows == 0) /* no bucket recs for pool? return error */
89  {
90  printf("ERROR: %s.%s.%d No bucket defs for pool %d.\n",
91  __FILE__, fcnName, __LINE__, bucketpool_pk);
92  PQclear(result);
93  return 0;
94  }
95 
96  bucketDefList = calloc(numRows+1, sizeof(bucketdef_t));
97  if (bucketDefList == 0)
98  {
99  printf("ERROR: %s.%s.%d No memory to allocate %d bucket defs.\n",
100  __FILE__, fcnName, __LINE__, numRows);
101  return 0;
102  }
103 
104  /* put each db bucket def into bucketDefList in eval order */
105  for (rowNum=0; rowNum<numRows; rowNum++)
106  {
107  bucketDefList[rowNum].bucket_pk = atoi(PQgetvalue(result, rowNum, 0));
108  bucketDefList[rowNum].bucket_type = atoi(PQgetvalue(result, rowNum, 1));
109  bucketDefList[rowNum].bucketpool_pk = bucketpool_pk;
110 
111  /* compile regex if type 3 (REGEX) */
112  if (bucketDefList[rowNum].bucket_type == 3)
113  {
114  rv = regcomp(&bucketDefList[rowNum].compRegex, PQgetvalue(result, rowNum, 2),
115  REG_NOSUB | REG_ICASE | REG_EXTENDED);
116  if (rv != 0)
117  {
118  printf("ERROR: %s.%s.%d Invalid regular expression for bucketpool_pk: %d, bucket: %s\n",
119  __FILE__, fcnName, __LINE__, bucketpool_pk, PQgetvalue(result, rowNum, 5));
120  numErrors++;
121  }
122  bucketDefList[rowNum].regex = strdup(PQgetvalue(result, rowNum, 2));
123  }
124 
125  bucketDefList[rowNum].dataFilename = strdup(PQgetvalue(result, rowNum, 3));
126 
127  /* verify that external file dataFilename exists */
128  if (strlen(bucketDefList[rowNum].dataFilename) > 0)
129  {
130  snprintf(filepath, sizeof(filepath), "%s/bucketpools/%d/%s",
131  PROJECTSTATEDIR, bucketpool_pk, bucketDefList[rowNum].dataFilename);
132  if (stat(filepath, &statbuf) == -1)
133  {
134  hostname[0] = 0;
135  gethostname(hostname, sizeof(hostname));
136  printf("ERROR: %s.%s.%d File: %s is missing on host: %s. bucketpool_pk: %d, bucket: %s\n",
137  __FILE__, fcnName, __LINE__, filepath, hostname, bucketpool_pk, PQgetvalue(result, rowNum, 5));
138  numErrors++;
139  }
140  }
141 
142  /* MATCH_EVERY */
143  if (bucketDefList[rowNum].bucket_type == 1)
144  bucketDefList[rowNum].match_every = getMatchEvery(pgConn, bucketpool_pk, bucketDefList[rowNum].dataFilename, pcroot);
145 
146  /* MATCH_ONLY */
147  if (bucketDefList[rowNum].bucket_type == 2)
148  {
149  bucketDefList[rowNum].match_only = getMatchOnly(pgConn, bucketpool_pk, bucketDefList[rowNum].dataFilename, pcroot);
150  }
151 
152  /* REGEX-FILE */
153  if (bucketDefList[rowNum].bucket_type == 5)
154  {
155  bucketDefList[rowNum].regex_row = getRegexFile(pgConn, bucketpool_pk, bucketDefList[rowNum].dataFilename, pcroot);
156  }
157 
158  bucketDefList[rowNum].stopon = *PQgetvalue(result, rowNum, 4);
159  bucketDefList[rowNum].bucket_name = strdup(PQgetvalue(result, rowNum, 5));
160  bucketDefList[rowNum].applies_to = *PQgetvalue(result, rowNum, 6);
161  }
162  PQclear(result);
163  if (numErrors) return 0;
164 
165  if (debug)
166  {
167  for (rowNum=0; rowNum<numRows; rowNum++)
168  {
169  printf("\nbucket_pk[%d] = %d\n", rowNum, bucketDefList[rowNum].bucket_pk);
170  printf("bucket_name[%d] = %s\n", rowNum, bucketDefList[rowNum].bucket_name);
171  printf("bucket_type[%d] = %d\n", rowNum, bucketDefList[rowNum].bucket_type);
172  printf("dataFilename[%d] = %s\n", rowNum, bucketDefList[rowNum].dataFilename);
173  printf("stopon[%d] = %c\n", rowNum, bucketDefList[rowNum].stopon);
174  printf("applies_to[%d] = %c\n", rowNum, bucketDefList[rowNum].applies_to);
175  printf("nomos_agent_pk[%d] = %d\n", rowNum, bucketDefList[rowNum].nomos_agent_pk);
176  printf("bucket_agent_pk[%d] = %d\n", rowNum, bucketDefList[rowNum].bucket_agent_pk);
177  printf("regex[%d] = %s\n", rowNum, bucketDefList[rowNum].regex);
178  }
179  }
180 
181  return bucketDefList;
182 }
183 
184 
196 FUNCTION int *getMatchOnly(PGconn *pgConn, int bucketpool_pk,
197  char *filename, cacheroot_t *pcroot)
198 {
199  char *fcnName = "getMatchOnly";
200  char *delims = ",\t\n\r";
201  char *sp;
202  char filepath[256];
203  char inbuf[256];
204  int *match_only = 0;
205  int line_count = 0;
206  int lr_pk;
207  int matchNumb = 0;
208  FILE *fin;
209 
210  /* put together complete file path to match_only file */
211  snprintf(filepath, sizeof(filepath), "%s/bucketpools/%d/%s",
212  PROJECTSTATEDIR, bucketpool_pk, filename);
213 
214  /* open filepath */
215  fin = fopen(filepath, "r");
216  if (!fin)
217  {
218  printf("FATAL: %s.%s.%d Failure to open bucket file %s (pool=%d).\nError: %s\n",
219  __FILE__, fcnName, __LINE__, filepath, bucketpool_pk, strerror(errno));
220  return 0;
221  }
222 
223  /* count lines in file */
224  while (fgets(inbuf, sizeof(inbuf), fin)) line_count++;
225 
226  /* calloc match_only array as lines+1. This set the array to
227  the max possible size +1 for null termination */
228  match_only = calloc(line_count+1, sizeof(int));
229  if (!match_only)
230  {
231  printf("FATAL: %s.%s.%d Unable to allocate %d int array.\n",
232  __FILE__, fcnName, __LINE__, line_count+1);
233  fclose(fin);
234  return 0;
235  }
236 
237  /* read each line fgets
238  A match_only file has one license per line, no leading whitespace.
239  Comments start with leading #
240  */
241  rewind(fin);
242  while (fgets(inbuf, sizeof(inbuf), fin))
243  {
244  /* input string should only contain 1 token (license name) */
245  sp = strtok(inbuf, delims);
246 
247  /* comment? */
248  if ((sp == 0) || (*sp == '#')) continue;
249 
250  /* look up license rf_pk */
251  lr_pk = lrcache_lookup(pcroot, sp);
252  if (lr_pk)
253  {
254  /* save rf_pk in match_only array */
255  match_only[matchNumb++] = lr_pk;
256 //printf("MATCH_ONLY license: %s, FOUND\n", sp);
257  }
258  else
259  {
260 //printf("MATCH_ONLY license: %s, NOT FOUND in DB - ignored\n", sp);
261  }
262  }
263  fclose(fin);
264 
265  return match_only;
266 }
267 
268 
280 FUNCTION int **getMatchEvery(PGconn *pgConn, int bucketpool_pk,
281  char *filename, cacheroot_t *pcroot)
282 {
283  char *fcnName = "getMatchEvery";
284  char filepath[256];
285  char inbuf[256];
286  int **match_every = 0;
287  int **match_every_head = 0;
288  int line_count = 0;
289  int *lr_pkArray;
290  int matchNumb = 0;
291  FILE *fin;
292 
293  /* put together complete file path to match_every file */
294  snprintf(filepath, sizeof(filepath), "%s/bucketpools/%d/%s",
295  PROJECTSTATEDIR, bucketpool_pk, filename);
296 
297  /* open filepath */
298  fin = fopen(filepath, "r");
299  if (!fin)
300  {
301  printf("FATAL: %s.%s.%d Failure to initialize bucket %s (pool=%d).\nError: %s\n",
302  __FILE__, fcnName, __LINE__, filepath, bucketpool_pk, strerror(errno));
303  return 0;
304  }
305 
306  /* count lines in file */
307  while (fgets(inbuf, sizeof(inbuf), fin)) line_count++;
308 
309  /* calloc match_every array as lines+1. This sets the array to
310  the max possible size +1 for null termination */
311  match_every = calloc(line_count+1, sizeof(int *));
312  if (!match_every)
313  {
314  printf("FATAL: %s.%s.%d Unable to allocate %d int array.\n",
315  __FILE__, fcnName, __LINE__, line_count+1);
316  fclose(fin);
317  return 0;
318  }
319  match_every_head = match_every;
320 
321  /* read each line fgets
322  A match_every file has 1-n licenses per line
323  Comments start with leading #
324  */
325  rewind(fin);
326  while (fgets(inbuf, sizeof(inbuf), fin))
327  {
328  /* comment? */
329  if (inbuf[0] == '#') continue;
330  lr_pkArray = getLicsInStr(pgConn, inbuf, pcroot);
331  if (lr_pkArray)
332  {
333  /* save rf_pk in match_every array */
334  match_every[matchNumb++] = lr_pkArray;
335  }
336  }
337 
338  if (!matchNumb)
339  {
340  free(match_every_head);
341  match_every_head = 0;
342  }
343  fclose(fin);
344  return match_every_head;
345 }
346 
347 
371 FUNCTION regex_file_t *getRegexFile(PGconn *pgConn, int bucketpool_pk,
372  char *filename, cacheroot_t *pcroot)
373 {
374  char *fcnName = "getRegexFile";
375  char filepath[256];
376  char inbuf[256];
377  regex_file_t *regex_row_head = 0;
378  int line_count = 0;
379  int rv;
380  int rowNumb = 0;
381  int errorCount = 0;
382  char *Delims = " \t\n\r";
383  char *token;
384  char *saveptr;
385  FILE *fin;
386 
387  /* put together complete file path to match_every file */
388  snprintf(filepath, sizeof(filepath), "%s/bucketpools/%d/%s",
389  PROJECTSTATEDIR, bucketpool_pk, filename);
390 
391  /* open filepath */
392  fin = fopen(filepath, "r");
393  if (!fin)
394  {
395  printf("FATAL: %s.%s.%d Failure to initialize bucket %s (pool=%d).\nError: %s\n",
396  __FILE__, fcnName, __LINE__, filepath, bucketpool_pk, strerror(errno));
397  printf("In v1.3, files were in %s. To be LSB compliate, v1.4 now requires them to be in %s\n",
398  DATADIR, PROJECTSTATEDIR);
399  return 0;
400  }
401 
402  /* count lines in file */
403  while (fgets(inbuf, sizeof(inbuf), fin)) line_count++;
404 
405  /* calloc array as lines+1. This sets the array to
406  the max possible size +1 for null termination */
407  regex_row_head = calloc(line_count+1, sizeof(regex_file_t));
408  if (!regex_row_head)
409  {
410  printf("FATAL: %s.%s.%d Unable to allocate %d regex_file_t array.\n",
411  __FILE__, fcnName, __LINE__, line_count+1);
412  fclose(fin);
413  return 0;
414  }
415 
416  /* read each line fgets
417  File has 1-n expressions per line
418  Comments start with leading #
419  */
420  rewind(fin);
421  while (fgets(inbuf, sizeof(inbuf), fin))
422  {
423  /* comment? */
424  if (inbuf[0] == '#') continue;
425 
426  /* get first token ftype1 */
427  token = strtok_r(inbuf, Delims, &saveptr);
428 
429  /* empty line? */
430  if (token[0] == 0) continue;
431 
432  regex_row_head[rowNumb].ftype1 = getRegexFiletype(token, filepath);
433  if (regex_row_head[rowNumb].ftype1 == 0) break;
434 
435  /* get regex1 */
436  token = strtok_r(NULL, Delims, &saveptr);
437  regex_row_head[rowNumb].regex1 = strdup(token);
438  rv = regcomp(&regex_row_head[rowNumb].compRegex1, token, REG_NOSUB | REG_ICASE);
439  if (rv != 0)
440  {
441  printf("ERROR: %s.%s.%d Invalid regular expression for file: %s, [%s], row: %d\n",
442  __FILE__, fcnName, __LINE__, filepath, token, rowNumb+1);
443  errorCount++;
444  break;
445  }
446 
447  /* get optional operator 'and'=1 or 'or'=2 'not'=3 */
448  token = strtok_r(NULL, Delims, &saveptr);
449  if (!token)
450  {
451  rowNumb++;
452  continue;
453  }
454  else
455  {
456  if (strcasecmp(token, "and") == 0) regex_row_head[rowNumb].op = 1;
457  else
458  if (strcasecmp(token, "or") == 0) regex_row_head[rowNumb].op = 2;
459  else
460  if (strcasecmp(token, "not") == 0) regex_row_head[rowNumb].op = 3;
461  else
462  {
463  printf("ERROR: %s.%s.%d Invalid operator in file: %s, [%s], row: %d\n",
464  __FILE__, fcnName, __LINE__, filepath, token, rowNumb+1);
465  errorCount++;
466  break;
467  }
468  }
469 
470  /* get token ftype2 */
471  token = strtok_r(NULL, Delims, &saveptr);
472  regex_row_head[rowNumb].ftype2 = getRegexFiletype(token, filepath);
473  if (regex_row_head[rowNumb].ftype2 == 0) break;
474 
475  /* get regex2 */
476  token = strtok_r(NULL, Delims, &saveptr);
477  regex_row_head[rowNumb].regex2 = strdup(token);
478  rv = regcomp(&regex_row_head[rowNumb].compRegex2, token, REG_NOSUB | REG_ICASE);
479  if (rv != 0)
480  {
481  printf("ERROR: %s.%s.%d Invalid regular expression for file: %s, [%s], row: %d\n",
482  __FILE__, fcnName, __LINE__, filepath, token, rowNumb+1);
483  errorCount++;
484  break;
485  }
486 
487  rowNumb++;
488  }
489 
490  /* bad file data. Die unceremoniously.
491  * \todo: die more gracefully.
492  */
493  if (errorCount) exit(-1);
494 
495  if (!rowNumb)
496  {
497  free(regex_row_head);
498  regex_row_head = 0;
499  }
500  fclose(fin);
501  return regex_row_head;
502 }
503 
504 
515 FUNCTION int getRegexFiletype(char *token, char *filepath)
516 {
517  if (strcasecmp(token, "filename") == 0) return(1);
518  else
519  if (strcasecmp(token, "license") == 0) return(2);
520  printf("FATAL: Invalid bucket file (%s), unknown filetype (%s)\n",
521  filepath, token);
522  return(0);
523 }
524 
525 
540 FUNCTION int *getLicsInStr(PGconn *pgConn, char *nameStr,
541  cacheroot_t *pcroot)
542 {
543  char *fcnName = "getLicsInStr";
544  char *delims = "|\n\r ";
545  char *sp;
546  int *pkArray;
547  int *pkArrayHead = 0;
548  int lic_count = 1;
549  int lr_pk;
550  int matchNumb = 0;
551 
552  if (!nameStr) return 0;
553 
554  /* count how many seperators are in nameStr
555  number of licenses is the count +1 */
556  sp = nameStr;
557  while (*sp) if (*sp++ == *delims) lic_count++;
558 
559  /* we need lic_count+1 int array. This sets the array to
560  the max possible size +1 for null termination */
561  pkArray = calloc(lic_count+1, sizeof(int));
562  if (!pkArray)
563  {
564  printf("FATAL: %s.%s.%d Unable to allocate %d int array.\n",
565  __FILE__, fcnName, __LINE__, lic_count+1);
566  return 0;
567  }
568  pkArrayHead = pkArray; /* save head of array */
569 
570  /* read each line then read each license in the line
571  Comments start with leading #
572  */
573  while ((sp = strtok(nameStr, delims)) != 0)
574  {
575  /* look up license rf_pk */
576  lr_pk = lrcache_lookup(pcroot, sp);
577  if (lr_pk)
578  {
579  /* save rf_pk in match_every array */
580  pkArray[matchNumb++] = lr_pk;
581  }
582  else
583  {
584  /* license not found in license_ref table, so this can never match */
585  matchNumb = 0;
586  break;
587  }
588  nameStr = 0; // for strtok
589  }
590 
591  if (matchNumb == 0)
592  {
593  free(pkArrayHead);
594  pkArrayHead = 0;
595  }
596 
597  return pkArrayHead;
598 }
599 
600 
614 FUNCTION int LatestNomosAgent(PGconn *pgConn, int upload_pk)
615 {
616  char *fcnName = "LatestNomosAgent";
617  char sql[512];
618  PGresult *result;
619  int nomos_agent_pk = 0;
620 
621  /*** Find the latest enabled nomos agent_pk ***/
622 
623  snprintf(sql, sizeof(sql),
624  "select agent_fk from nomos_ars, agent \
625  WHERE agent_pk=agent_fk and ars_success=true and upload_fk='%d' \
626  and agent_enabled=true order by agent_ts desc limit 1",
627  upload_pk);
628  result = PQexec(pgConn, sql);
629  if (fo_checkPQresult(pgConn, result, sql, fcnName, __LINE__)) return 0;
630  if (PQntuples(result) == 0) return 0;
631  nomos_agent_pk = atoi(PQgetvalue(result,0,0));
632  PQclear(result);
633  return nomos_agent_pk;
634 }
635 
636 
650 FUNCTION int childParent(PGconn *pgConn, int uploadtree_pk)
651 {
652  char *fcnName = "childParent";
653  char sql[256];
654  PGresult *result;
655  int childParent_pk = 0; /* uploadtree_pk */
656 
657  do
658  {
659  snprintf(sql, sizeof(sql),
660  "select uploadtree_pk,ufile_mode from uploadtree where parent=%d limit 1",
661  uploadtree_pk);
662  result = PQexec(pgConn, sql);
663  if (fo_checkPQresult(pgConn, result, sql, fcnName, __LINE__)) break;
664  if (PQntuples(result) == 0) break; /* empty container */
665 
666  /* not an artifact? */
667  if ((atoi(PQgetvalue(result, 0, 1)) & 1<<28) == 0)
668  {
669  childParent_pk = uploadtree_pk;
670  break;
671  }
672  uploadtree_pk = atoi(PQgetvalue(result, 0, 0));
673  PQclear(result);
674  } while (childParent_pk == 0);
675 
676  PQclear(result);
677  return childParent_pk;
678 }
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
int debug
Definition: buckets.c:68
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:146
char * regex
Definition: buckets.h:73
char * regex1
Definition: buckets.h:55
PGconn * pgConn
Database connection.
Definition: adj2nest.c:98
int * match_only
Definition: buckets.h:76
FUNCTION int childParent(PGconn *pgConn, int uploadtree_pk)
Given an uploadtree_pk of a container, find the uploadtree_pk of it&#39;s children (i.e. scan down through artifacts to get the children&#39;s parent.
Definition: inits.c:650
FUNCTION int LatestNomosAgent(PGconn *pgConn, int upload_pk)
Get the latest nomos agent_pk that has data for this this uploadtree.
Definition: inits.c:614
char * dataFilename
Definition: buckets.h:75
regex_file_t * regex_row
Definition: buckets.h:78
REGEX-FILE bucket type.
Definition: buckets.h:52
FUNCTION int * getMatchOnly(PGconn *pgConn, int bucketpool_pk, char *filename, cacheroot_t *pcroot)
Read the match only file (bucket type 2)
Definition: inits.c:196
FUNCTION int getBucketpool_pk(PGconn *pgConn, char *bucketpool_name)
Get a bucketpool_pk based on the bucketpool_name.
Definition: inits.c:34
char applies_to
Definition: buckets.h:80
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:280
FUNCTION int getRegexFiletype(char *token, char *filepath)
Given a filetype token from REGEX-FILE return the token int representation.
Definition: inits.c:515
int ** match_every
Definition: buckets.h:77
char * bucket_name
Definition: buckets.h:71
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:371
FUNCTION int * getLicsInStr(PGconn *pgConn, char *nameStr, cacheroot_t *pcroot)
Given a string with | separated license names return an integer array of rf_pk&#39;s. ...
Definition: inits.c:540
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:63
const char * upload_pk
Definition: sqlstatements.h:93
char * regex2
Definition: buckets.h:59