FOSSology  3.2.0rc1
Open Source License Compliance by Open Source Software
pkgagent.c
Go to the documentation of this file.
1 /***************************************************************
2  Copyright (C) 2011-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  ***************************************************************/
31 #include "pkgagent.h"
32 
33 int Verbose = 0;
34 PGconn* db_conn = NULL;
35 
37 int tag[15] = { RPMTAG_NAME,
38  RPMTAG_EPOCH,
39  RPMTAG_ARCH,
40  RPMTAG_VERSION,
41  RPMTAG_LICENSE,
42  RPMTAG_GROUP,
43  RPMTAG_PACKAGER,
44  RPMTAG_RELEASE,
45  RPMTAG_BUILDTIME,
46  RPMTAG_VENDOR,
47  RPMTAG_URL,
48  RPMTAG_SOURCERPM,
49  RPMTAG_SUMMARY,
50  RPMTAG_DESCRIPTION,
51  RPMTAG_REQUIRENAME
52 };
53 
63 void EscapeString (char *sourceString, char *escString, int esclen)
64 {
65  int len;
66  int error;
67 
68  /* remove any backslashes from the string as they don't escape properly
69  * for example, "don\'t" in the input will cause an insert error
70  */
71  char *cp = (char *)sourceString;
72  while(*cp)
73  {
74  if (*cp == '\\') *cp = ' ';
75  cp++;
76  }
77 
78  /* Revert changes of revision 3721
79  * If the size of input string larger than destination buffer,
80  * will cut of the input string with destination buffer
81  */
82  len = strlen(sourceString);
83  if ( len > esclen/2 )
84  len = esclen/2 - 1;
85 
86  /* check the size of the destination buffer */
87  /* comment this changes, will revisit later */
88  /*
89  if((len = strlen(sourceString)) > esclen/2) {
90  printf("ERROR %s.%d: length of input string is too large\n", __FILE__, __LINE__);
91  printf("ERROR length of string was %d, max length is %d\n", len, esclen/2);
92  return;
93  }
94  */
95  //printf("TEST:esclen---%d,sourcelen---%d\n",esclen,len);
96  PQescapeStringConn(db_conn, escString, sourceString, len, &error);
97  if (error)
98  printf("WARNING: %s line %d: Error escaping string with multibype character set?\n",__FILE__, __LINE__ );
99 }
100 
113 char * GetFieldValue (char *Sin, char *Field, int FieldMax,
114  char *Value, int ValueMax, char Separator)
115 {
116  int s,f,v;
117  int GotQuote;
118 
119  memset(Field,0,FieldMax);
120  memset(Value,0,ValueMax);
121 
122  while(isspace(Sin[0])) Sin++; /* skip initial spaces */
123  if (Sin[0]=='\0') return(NULL);
124  f=0; v=0;
125 
126  for(s=0; (Sin[s] != '\0') && !isspace(Sin[s]) && (Sin[s] != '='); s++)
127  {
128  Field[f++] = Sin[s];
129  }
130  while(isspace(Sin[s])) s++; /* skip spaces after field name */
131  if (Sin[s] != Separator) /* if it is not a field, then just return it. */
132  {
133  return(Sin+s);
134  }
135  if (Sin[s]=='\0') return(NULL);
136  s++; /* skip '=' */
137  while(isspace(Sin[s])) s++; /* skip spaces after '=' */
138  if (Sin[s]=='\0') return(NULL);
139 
140  GotQuote='\0';
141  if ((Sin[s]=='\'') || (Sin[s]=='"'))
142  {
143  GotQuote = Sin[s];
144  s++; /* skip quote */
145  if (Sin[s]=='\0') return(NULL);
146  }
147  if (GotQuote)
148  {
149  for( ; (Sin[s] != '\0') && (Sin[s] != GotQuote); s++)
150  {
151  if (Sin[s]=='\\') Value[v++]=Sin[++s];
152  else Value[v++]=Sin[s];
153  }
154  }
155  else
156  {
157  /* if it gets here, then there is no quote */
158  for( ; (Sin[s] != '\0') && !isspace(Sin[s]); s++)
159  {
160  if (Sin[s]=='\\') Value[v++]=Sin[++s];
161  else Value[v++]=Sin[s];
162  }
163  }
164  while(isspace(Sin[s])) s++; /* skip spaces */
165  return(Sin+s);
166 } /* GetFieldValue() */
167 
168 
175 {
176  char mimetype[128];
177  char sqlbuf[1024];
178  PGresult *result;
179  int mimetypepk = 0;
180  int debmimetypepk = 0;
181  int debsrcmimetypepk = 0;
182  int numrows;
183  int i;
184  char *uploadtree_tablename;
185 
186  struct rpmpkginfo *pi;
187  struct debpkginfo *dpi;
188 
189  pi = (struct rpmpkginfo *)malloc(sizeof(struct rpmpkginfo));
190  dpi = (struct debpkginfo *)malloc(sizeof(struct debpkginfo));
191 
192  rpmReadConfigFiles(NULL, NULL);
193 
194  /* "pkgagent" needs to know what? */
195 
196  /* "pkgagent" needs to know the mimetype for
197  * 'application/x-rpm' and 'application/x-debian-package' and 'application/x-debian-source'*/
198  snprintf(sqlbuf, sizeof(sqlbuf), "SELECT mimetype_pk FROM mimetype WHERE mimetype_name = 'application/x-rpm' LIMIT 1;");
199  result = PQexec(db_conn, sqlbuf);
200  if (fo_checkPQresult(db_conn, result, sqlbuf, __FILE__, __LINE__))
201  {
202  free(pi);
203  free(dpi);
204  exit(-1);
205  }
206  mimetypepk = atoi(PQgetvalue(result, 0, 0));
207  PQclear(result);
208  if ( mimetypepk == 0 )
209  {
210  snprintf(sqlbuf, sizeof(sqlbuf), "INSERT INTO mimetype (mimetype_name) VALUES ('application/x-rpm');");
211  result = PQexec(db_conn, sqlbuf);
212  if (fo_checkPQcommand(db_conn, result, sqlbuf, __FILE__, __LINE__))
213  {
214  free(pi);
215  free(dpi);
216  exit(-1);
217  }
218  snprintf(sqlbuf, sizeof(sqlbuf), "SELECT mimetype_pk FROM mimetype WHERE mimetype_name = 'application/x-rpm' LIMIT 1;");
219  result = PQexec(db_conn, sqlbuf);
220  if (fo_checkPQresult(db_conn, result, sqlbuf, __FILE__, __LINE__))
221  {
222  free(pi);
223  free(dpi);
224  exit(-1);
225  }
226  mimetypepk = atoi(PQgetvalue(result, 0, 0));
227  PQclear(result);
228  if ( mimetypepk == 0 )
229  {
230  LOG_ERROR("pkgagent rpm mimetype not installed!");
231  free(pi);
232  free(dpi);
233  return (-1);
234  }
235  }
236  snprintf(sqlbuf, sizeof(sqlbuf), "SELECT mimetype_pk FROM mimetype WHERE mimetype_name = 'application/x-debian-package' LIMIT 1;");
237  result = PQexec(db_conn, sqlbuf);
238  if (fo_checkPQresult(db_conn, result, sqlbuf, __FILE__, __LINE__))
239  {
240  free(pi);
241  free(dpi);
242  exit(-1);
243  }
244  debmimetypepk = atoi(PQgetvalue(result, 0, 0));
245  PQclear(result);
246  if ( debmimetypepk == 0 )
247  {
248  snprintf(sqlbuf, sizeof(sqlbuf), "INSERT INTO mimetype (mimetype_name) VALUES ('application/x-debian-package');");
249  result = PQexec(db_conn, sqlbuf);
250  if (fo_checkPQcommand(db_conn, result, sqlbuf, __FILE__, __LINE__))
251  {
252  free(pi);
253  free(dpi);
254  exit(-1);
255  }
256  snprintf(sqlbuf, sizeof(sqlbuf), "SELECT mimetype_pk FROM mimetype WHERE mimetype_name = 'application/x-debian-package' LIMIT 1;");
257  result = PQexec(db_conn, sqlbuf);
258  if (fo_checkPQresult(db_conn, result, sqlbuf, __FILE__, __LINE__))
259  {
260  free(pi);
261  free(dpi);
262  exit(-1);
263  }
264  debmimetypepk = atoi(PQgetvalue(result, 0, 0));
265  PQclear(result);
266  if ( debmimetypepk == 0 )
267  {
268  LOG_ERROR("pkgagent deb mimetype not installed!");
269  free(pi);
270  free(dpi);
271  return (-1);
272  }
273  }
274  snprintf(sqlbuf, sizeof(sqlbuf), "SELECT mimetype_pk FROM mimetype WHERE mimetype_name = 'application/x-debian-source' LIMIT 1;");
275  result = PQexec(db_conn, sqlbuf);
276  if (fo_checkPQresult(db_conn, result, sqlbuf, __FILE__, __LINE__))
277  {
278  free(pi);
279  free(dpi);
280  exit(-1);
281  }
282  debsrcmimetypepk = atoi(PQgetvalue(result, 0, 0));
283  PQclear(result);
284  if ( debsrcmimetypepk == 0 )
285  {
286  snprintf(sqlbuf, sizeof(sqlbuf), "INSERT INTO mimetype (mimetype_name) VALUES ('application/x-debian-source');");
287  result = PQexec(db_conn, sqlbuf);
288  if (fo_checkPQcommand(db_conn, result, sqlbuf, __FILE__, __LINE__))
289  {
290  free(pi);
291  free(dpi);
292  exit(-1);
293  }
294  snprintf(sqlbuf, sizeof(sqlbuf), "SELECT mimetype_pk FROM mimetype WHERE mimetype_name = 'application/x-debian-source' LIMIT 1;");
295  result = PQexec(db_conn, sqlbuf);
296  if (fo_checkPQresult(db_conn, result, sqlbuf, __FILE__, __LINE__))
297  {
298  free(pi);
299  free(dpi);
300  exit(-1);
301  }
302  debsrcmimetypepk = atoi(PQgetvalue(result, 0, 0));
303  PQclear(result);
304  if ( debsrcmimetypepk == 0 )
305  {
306  LOG_ERROR("pkgagent deb source mimetype not installed!");
307  free(pi);
308  free(dpi);
309  return (-1);
310  }
311  }
312 
313  if (!upload_pk) // when upload_pk is empty
314  {
315  free(pi);
316  free(dpi);
317  return -1;
318  }
319  uploadtree_tablename = GetUploadtreeTableName(db_conn, upload_pk);
320  if (NULL == uploadtree_tablename) uploadtree_tablename = strdup("uploadtree_a");
321  /* retrieve the records to process */
322  snprintf(sqlbuf, sizeof(sqlbuf),
323  "SELECT pfile_pk as pfile_pk, pfile_sha1 || '.' || pfile_md5 || '.' || pfile_size AS pfilename, mimetype_name as mimetype from pfile, mimetype, (SELECT distinct(pfile_fk) as PF from %s where upload_fk='%ld') as SS where PF=pfile_pk and (pfile_mimetypefk='%d' or pfile_mimetypefk='%d' OR pfile_mimetypefk='%d') and mimetype_pk=pfile_mimetypefk and (not exists (SELECT 1 from pkg_rpm where pkg_rpm.pfile_fk = pfile_pk)) and (not exists (SELECT 1 from pkg_deb where pkg_deb.pfile_fk = pfile_pk))", uploadtree_tablename, upload_pk, mimetypepk, debmimetypepk, debsrcmimetypepk);
324  result = PQexec(db_conn, sqlbuf);
325  if (fo_checkPQresult(db_conn, result, sqlbuf, __FILE__, __LINE__))
326  {
327  free(pi);
328  free(dpi);
329  exit(-1);
330  }
331 
332  numrows = PQntuples(result);
333  for (i=0; i<numrows; i++)
334  {
335  char *repFile = NULL;
336 
337  memset(pi,0,sizeof(struct rpmpkginfo));
338  memset(dpi,0,sizeof(struct debpkginfo));
339 
340  strcpy(mimetype, PQgetvalue(result, i, 2));
341  /*
342  * if mimetype='application/x-rpm' process RPM packages
343  * if mimetype='application/x-debian-package' process DEBIAN packages
344  * if mimetype='application/x-debian-source' process DEBIAN source packages
345  * */
346  if (!strcasecmp(mimetype,"application/x-rpm")) {
347  pi->pFileFk = atoi(PQgetvalue(result, i, 0));
348  strncpy(pi->pFile, PQgetvalue(result, i, 1), sizeof(pi->pFile)-1);
349  pi->pFile[sizeof(pi->pFile)-1] = '\0';
350  repFile = fo_RepMkPath("files", pi->pFile);
351  if (!repFile) {
352  LOG_FATAL("pfile %ld PkgAgent unable to open file %s",
353  pi->pFileFk, pi->pFile);
354  return (-1);
355  }
356  if (GetMetadata(repFile,pi) != -1){
357  RecordMetadataRPM(pi);
358  }
359  /* free memory */
360  int i;
361  for(i=0; i< pi->req_size;i++)
362  free(pi->requires[i]);
363  free(pi->requires);
364  }
365  else if (!strcasecmp(mimetype, "application/x-debian-package")){
366  dpi->pFileFk = atoi(PQgetvalue(result, i, 0));
367  strncpy(dpi->pFile, PQgetvalue(result, i, 1), sizeof(dpi->pFile)-1);
368  dpi->pFile[sizeof(dpi->pFile)-1] = '\0';
369  if (GetMetadataDebBinary(upload_pk, dpi) != -1){
370  if (RecordMetadataDEB(dpi) != 0) continue;
371  }
372  /* free memory */
373  int i;
374  for(i=0; i< dpi->dep_size;i++)
375  free(dpi->depends[i]);
376  free(dpi->depends);
377  }
378  else if (!strcasecmp(mimetype, "application/x-debian-source")){
379  dpi->pFileFk = atoi(PQgetvalue(result, i, 0));
380  strncpy(dpi->pFile, PQgetvalue(result, i, 1), sizeof(dpi->pFile)-1);
381  dpi->pFile[sizeof(dpi->pFile)-1] = '\0';
382  repFile = fo_RepMkPath("files", dpi->pFile);
383  if (!repFile) {
384  LOG_FATAL("pfile %ld PkgAgent unable to open file %s\n",
385  dpi->pFileFk, dpi->pFile);
386  return (-1);
387  }
388  if (GetMetadataDebSource(repFile,dpi) != -1){
389  RecordMetadataDEB(dpi);
390  }
391  /* free memory */
392  int i;
393  for(i=0; i< dpi->dep_size;i++)
394  free(dpi->depends[i]);
395  free(dpi->depends);
396  } else {
397  printf("LOG: Not RPM and DEBIAN package!\n");
398  }
400  }
401  PQclear(result);
402  rpmFreeCrypto();
403  rpmFreeMacros(NULL);
404  free(pi);
405  free(dpi);
406  return (0);
407 }/*ProcessUpload (long upload_pk)*/
408 
414 void ReadHeaderInfo(Header header, struct rpmpkginfo *pi)
415 {
416  char fmt[128];
417  char * msgstr;
418  const char * errstr;
419  int i,j;
420  long *tp,t;
421  int header_status;
422 
423  struct rpmtd_s req;
424  rpm_count_t data_size;
425 
426  for (i = 0; i < 14; i++) {
427  memset(fmt, 0, sizeof(fmt));
428  strcat( fmt, "%{");
429  strcat( fmt, rpmTagGetName(tag[i]));
430  strcat( fmt, "}\n");
431 
432  msgstr = headerFormat(header, fmt, &errstr);
433  if (msgstr != NULL){
434  trim(msgstr);
435  printf("%s:%s\n",rpmTagGetName(tag[i]),msgstr);
436  switch (tag[i]) {
437  case RPMTAG_NAME:
438  EscapeString(msgstr, pi->pkgName, sizeof(pi->pkgName));
439  break;
440  case RPMTAG_EPOCH:
441  EscapeString(msgstr, pi->pkgAlias, sizeof(pi->pkgAlias));
442  break;
443  case RPMTAG_ARCH:
444  EscapeString(msgstr, pi->pkgArch, sizeof(pi->pkgArch));
445  break;
446  case RPMTAG_VERSION:
447  EscapeString(msgstr, pi->version, sizeof(pi->version));
448  break;
449  case RPMTAG_LICENSE:
450  EscapeString(msgstr, pi->license, sizeof(pi->license));
451  break;
452  case RPMTAG_GROUP:
453  EscapeString(msgstr, pi->group, sizeof(pi->group));
454  break;
455  case RPMTAG_PACKAGER:
456  EscapeString(msgstr, pi->packager, sizeof(pi->packager));
457  break;
458  case RPMTAG_RELEASE:
459  EscapeString(msgstr, pi->release, sizeof(pi->release));
460  break;
461  case RPMTAG_BUILDTIME:
462  t = atol(msgstr);
463  tp = &t;
464  strncpy(pi->buildDate,trim(asctime(gmtime((time_t*)tp))),sizeof(pi->buildDate)-1);
465  pi->buildDate[sizeof(pi->buildDate)-1] = '\0';
466  break;
467  case RPMTAG_VENDOR:
468  EscapeString(msgstr, pi->vendor, sizeof(pi->vendor));
469  break;
470  case RPMTAG_URL:
471  EscapeString(msgstr, pi->url, sizeof(pi->url));
472  break;
473  case RPMTAG_SOURCERPM:
474  EscapeString(msgstr, pi->sourceRPM,sizeof(pi->sourceRPM));
475  break;
476  case RPMTAG_SUMMARY:
477  EscapeString(msgstr, pi->summary, sizeof(pi->summary));
478  break;
479  case RPMTAG_DESCRIPTION:
480  EscapeString(msgstr, pi->description, sizeof(pi->description));
481  break;
482  default:
483  break;
484  }
485  }
486  free((void *)msgstr);
487  }
488  if (Verbose > 1) { printf("Name:%s\n",pi->pkgName);}
489  header_status = headerGet(header, tag[14], &req, HEADERGET_DEFAULT);
490  if (header_status) {
491  data_size = rpmtdCount(&req);
492  pi->requires = calloc(data_size, sizeof(char *));
493  for (j=0; j<data_size;j++){
494  const char * temp = rpmtdNextString(&req);
495  pi->requires[j] = malloc(MAXCMD);
496  strcpy(pi->requires[j],temp);
497  }
498  pi->req_size = data_size;
499  rpmtdFreeData(&req);
500  }
501 
502  if (Verbose > 1) {
503  printf("Size:%d\n",pi->req_size);
504  for (j=0; j<pi->req_size;j++){
505  printf("REQ:%s\n",pi->requires[j]);
506  }
507  printf("Name:%s\n",pi->sourceRPM);
508  }
509 } /* ReadHeaderInfo(Header header, struct rpmpkginfo *pi) */
510 
517 int GetMetadata (char *pkg, struct rpmpkginfo *pi)
518 {
519  //rpmpi.pFileFk = 4234634;
520  //if (PKG_RPM)
521  //{
522  FD_t fd;
523  rpmRC rpmrc;
524  Header header;
525  rpmts ts;
526  rpmVSFlags vsflags;
527 
528  vsflags = RPMVSF_DEFAULT;
529  ts = (rpmts) rpmtsCreate();
530 
531  fd = Fopen(pkg,"r");
532  if ( fd == NULL ||Ferror(fd)){
533  rpmlog(RPMLOG_ERR, "open of %s failed: %s\n", pkg, Fstrerror(fd));
534  if (fd){
535  Fclose(fd);
536  }
537  return (-1);
538  }
539 
540  vsflags |= _RPMVSF_NOSIGNATURES;
541  vsflags |= _RPMVSF_NODIGESTS;
542  vsflags |= RPMVSF_NOHDRCHK;
543  vsflags |= RPMVSF_NEEDPAYLOAD;
544 
545  rpmtsSetVSFlags(ts, vsflags);
546 
547  //rpmReadConfigFiles(NULL, NULL);
548  rpmrc = rpmReadPackageFile(ts, fd, pkg,&header);
549  Fclose(fd);
550  ts = (rpmts) rpmtsFree(ts);
551 
552  switch (rpmrc) {
553  case RPMRC_OK:
554  case RPMRC_NOKEY:
555  case RPMRC_NOTTRUSTED:
556  break;
557  case RPMRC_NOTFOUND:
558  case RPMRC_FAIL:
559  default:
560  rpmlog(RPMLOG_ERR, "%s cannot be read or is not an RPM.\n", pkg);
561  return (-1);
562  }
563  ReadHeaderInfo(header, pi);
564  //rpmFreeMacros(NULL);
565  header = headerFree(header);
566  //}
567  return (0);
568 } /* GetMetadata(char *pkg, struct rpmpkginfo *pi) */
569 
576 {
577  char SQL[MAXCMD];
578  PGresult *result;
579  int pkg_pk;
580 
581  memset(SQL,0,sizeof(SQL));
582  snprintf(SQL,sizeof(SQL),"SELECT pfile_fk FROM pkg_rpm WHERE pfile_fk = %ld;",pi->pFileFk);
583  result = PQexec(db_conn, SQL);
584  if (fo_checkPQresult(db_conn, result, SQL, __FILE__, __LINE__)) exit(-1);
585  if (PQntuples(result) <=0)
586  {
587  PQclear(result);
588  memset(SQL,0,sizeof(SQL));
589  result = PQexec(db_conn, "BEGIN;");
590  if (fo_checkPQcommand(db_conn, result, SQL, __FILE__, __LINE__)) exit(-1);
591  PQclear(result);
592 
593  snprintf(SQL,sizeof(SQL),"INSERT INTO pkg_rpm (pkg_name,pkg_alias,pkg_arch,version,rpm_filename,license,pkg_group,packager,release,build_date,vendor,url,source_rpm,summary,description,pfile_fk) values (E'%s',E'%s',E'%s',E'%s',E'%s',E'%s',E'%s',E'%s',E'%s',E'%s',E'%s',E'%s',E'%s',E'%s',E'%s',%ld);",
594  trim(pi->pkgName),trim(pi->pkgAlias),trim(pi->pkgArch),trim(pi->version),
595  trim(pi->rpmFilename),trim(pi->license),trim(pi->group),trim(pi->packager),
596  trim(pi->release),pi->buildDate,trim(pi->vendor),trim(pi->url),trim(pi->sourceRPM),
597  trim(pi->summary),trim(pi->description),pi->pFileFk);
598  result = PQexec(db_conn, SQL);
599  if (fo_checkPQcommand(db_conn, result, SQL, __FILE__, __LINE__))
600  {
601  PQexec(db_conn, "ROLLBACK;");
602  return (-1);
603  }
604  PQclear(result);
605 
606  result = PQexec(db_conn,"SELECT currval('pkg_rpm_pkg_pk_seq'::regclass);");
607  if (fo_checkPQresult(db_conn, result, SQL, __FILE__, __LINE__)) exit(-1);
608  pkg_pk = atoi(PQgetvalue(result,0,0));
609  PQclear(result);
610 
611  if (Verbose) { printf("pkg_pk:%d\n",pkg_pk);}
612  int i;
613  for (i=0;i<pi->req_size;i++)
614  {
615  memset(SQL,0,sizeof(SQL));
616  snprintf(SQL,sizeof(SQL),"INSERT INTO pkg_rpm_req (pkg_fk,req_value) values (%d,E'%s');",pkg_pk,trim(pi->requires[i]));
617  result = PQexec(db_conn, SQL);
618  if (fo_checkPQcommand(db_conn, result, SQL, __FILE__, __LINE__))
619  {
620  PQexec(db_conn, "ROLLBACK;");
621  return (-1);
622  }
623  PQclear(result);
624  }
625  result = PQexec(db_conn, "COMMIT;");
626  if (fo_checkPQcommand(db_conn, result, SQL, __FILE__, __LINE__)) exit(-1);
627  PQclear(result);
628  }
629  return (0);
630 } /* RecordMetadata(struct rpmpkginfo *pi) */
631 
632 
641 char * ParseDebFile(char *Sin, char *Field, char *Value)
642 {
643  int s,f,v;
644 
645  memset(Field,0,MAXCMD);
646  memset(Value,0,MAXCMD);
647 
648  f=0; v=0;
649  if(!isspace(Sin[0]))
650  {
651  for(s=0; (Sin[s] != '\0') && !isspace(Sin[s]) && (Sin[s] != ':'); s++)
652  {
653  Field[f++] = Sin[s];
654  }
655  while(isspace(Sin[s])) s++;
656  if (Sin[s] != ':')
657  {
658  return(Sin+s);
659  }
660  s++;
661  while(isspace(Sin[s])) s++;
662 
663  for( ; Sin[s] != '\0'; s++)
664  {
665  Value[v++]=Sin[s];
666  }
667  if (Verbose) { printf("Field is %s and Value is %s", Field, Value);}
668  return(Sin+s);
669  } else
670  {
671  if (Verbose) { printf("ExValue is %s", Sin);}
672  return(Sin);
673  }
674 } /* ParseDebFile(char *Sin, char *Field, char *Value) */
675 
683 {
684  char *repfile;
685  char *filename;
686  char SQL[MAXCMD];
687  PGresult *result;
688  unsigned long lft, rgt;
689 
690  FILE *fp;
691  char field[MAXCMD];
692  char value[MAXCMD];
693  char line[MAXCMD];
694  char *s = NULL;
695  char temp[MAXCMD];
696  char *uploadtree_tablename;
697 
698  if (!upload_pk) return -1; // when upload_pk is empty
699  uploadtree_tablename = GetUploadtreeTableName(db_conn, upload_pk);
700  if (NULL == uploadtree_tablename) uploadtree_tablename = strdup("uploadtree_a");
701  /* Get the debian control file's repository path */
702  /* First get the uploadtree bounds (lft,rgt) for the package */
703  snprintf(SQL,sizeof(SQL),"SELECT lft,rgt FROM %s WHERE upload_fk = %ld AND pfile_fk = %ld limit 1",
704  uploadtree_tablename, upload_pk, pi->pFileFk);
705  result = PQexec(db_conn, SQL);
706  if (fo_checkPQresult(db_conn, result, SQL, __FILE__, __LINE__)) exit(-1);
707  if (PQntuples(result) == 0)
708  {
709  LOG_ERROR("Missing debian package (internal data inconsistancy). SQL: %s\n", SQL);
710  PQclear(result);
711  return (-1);
712  }
713  lft = strtoul(PQgetvalue(result,0,0), NULL, 10);
714  rgt = strtoul(PQgetvalue(result,0,1), NULL, 10);
715  PQclear(result);
716 
717  snprintf(SQL,sizeof(SQL),"SELECT pfile_sha1 || '.' || pfile_md5 || '.' || pfile_size FROM pfile, uploadtree where (pfile_pk=pfile_fk) and (upload_fk = %ld) AND (lft > %ld) AND (rgt < %ld) AND (ufile_name = 'control')",
718  upload_pk, lft, rgt);
719  result = PQexec(db_conn, SQL);
720  if (fo_checkPQresult(db_conn, result, SQL, __FILE__, __LINE__)) exit(-1);
721  if (PQntuples(result) > 0)
722  {
723  filename = PQgetvalue(result,0,0);
724  repfile = fo_RepMkPath("files", filename);
725  if (!repfile) {
726  LOG_FATAL("PkgAgent unable to open file %s\n",filename);
727  return (-1);
728  }
729  PQclear(result);
730  }
731  else
732  {
733  PQclear(result);
734  printf("LOG: Unable to find debian/control file! This file had wrong mimetype, ignore it!\n");
735  memset(SQL,0,sizeof(SQL));
736  snprintf(SQL,sizeof(SQL),"UPDATE pfile SET pfile_mimetypefk = NULL WHERE pfile_pk = %ld;", pi->pFileFk);
737  result = PQexec(db_conn, SQL);
738  if (fo_checkPQcommand(db_conn, result, SQL, __FILE__, __LINE__)) exit(-1);
739  PQclear(result);
740  return (-1);
741  }
742 
743  /* Parse the debian/control file to get every Field and Value */
744  if ((fp = fopen(repfile, "r")) == NULL){
745  LOG_FATAL("Unable to open debian/control file %s\n",repfile);
746  return (-1);
747  }
748 
749  while (fgets(line,MAXCMD,fp)!=NULL)
750  {
751  s = ParseDebFile(line,field,value);
752  trim(value);
753  if (!strcasecmp(field, "Description")) {
754  EscapeString(value, pi->summary, sizeof(pi->summary));
755  strcpy(temp, "");
756  }
757  if (s[0] != '\0') {
758  if ((strlen(temp) + strlen(s)) >= MAXCMD )
759  continue;
760  else
761  strcat(temp,s);
762  }
763  if (!strcasecmp(field, "Package")) {
764  EscapeString(value, pi->pkgName, sizeof(pi->pkgName));
765  }
766  if (!strcasecmp(field, "Version")) {
767  EscapeString(value, pi->version, sizeof(pi->version));
768  }
769  if (!strcasecmp(field, "Architecture")) {
770  EscapeString(value, pi->pkgArch, sizeof(pi->pkgArch));
771  }
772  if (!strcasecmp(field, "Maintainer")) {
773  EscapeString(value, pi->maintainer, sizeof(pi->maintainer));
774  }
775  if (!strcasecmp(field, "Installed-Size")) {
776  pi->installedSize=atol(value);
777  }
778  if (!strcasecmp(field, "Section")) {
779  EscapeString(value, pi->section, sizeof(pi->section));
780  }
781  if (!strcasecmp(field, "Priority")) {
782  EscapeString(value, pi->priority, sizeof(pi->priority));
783  }
784  if (!strcasecmp(field, "Homepage")) {
785  EscapeString(value, pi->homepage, sizeof(pi->homepage));
786  }
787  if (!strcasecmp(field, "Source")) {
788  EscapeString(value, pi->source, sizeof(pi->source));
789  }
790  if (!strcasecmp(field, "Depends")) {
791  char *depends = NULL;
792  char tempvalue[MAXCMD];
793  int size,i,length;
794  length = MAXLENGTH;
795  size = 0;
796  if (value[0] != '\0'){
797  strncpy(tempvalue, value, sizeof(tempvalue));
798  depends = strtok(value, ",");
799  while (depends && (depends[0] != '\0')) {
800  if (strlen(depends) >= length)
801  length = strlen(depends) + 1;
802  depends = strtok(NULL, ",");
803  size++;
804  }
805  if (Verbose) { printf("SIZE:%d\n", size);}
806 
807  pi->depends = calloc(size, sizeof(char *));
808  pi->depends[0] = calloc(length, sizeof(char));
809  strcpy(pi->depends[0],strtok(tempvalue,","));
810  for (i=1;i<size;i++){
811  pi->depends[i] = calloc(length, sizeof(char));
812  strcpy(pi->depends[i],strtok(NULL, ","));
813  }
814  pi->dep_size = size;
815  }
816  }
817  }
818  EscapeString(temp, pi->description, sizeof(pi->description));
819 
820  fclose(fp);
821  free(repfile);
822  return (0);
823 }/* GetMetadataDebBinary(struct debpkginfo *pi) */
824 
831 {
832  char SQL[MAXCMD];
833  PGresult *result;
834  int pkg_pk;
835 
836  memset(SQL,0,sizeof(SQL));
837  snprintf(SQL,sizeof(SQL),"SELECT pfile_fk FROM pkg_deb WHERE pfile_fk = %ld;",pi->pFileFk);
838  result = PQexec(db_conn, SQL);
839  if (fo_checkPQresult(db_conn, result, SQL, __FILE__, __LINE__)) exit(-1);
840  if (PQntuples(result) <=0)
841  {
842  PQclear(result);
843  memset(SQL,0,sizeof(SQL));
844  result = PQexec(db_conn, "BEGIN;");
845  if (fo_checkPQcommand(db_conn, result, SQL, __FILE__, __LINE__)) exit(-1);
846  PQclear(result);
847 
848  snprintf(SQL,sizeof(SQL),"INSERT INTO pkg_deb (pkg_name,pkg_arch,version,maintainer,installed_size,section,priority,homepage,source,summary,description,format,uploaders,standards_version,pfile_fk) values (E'%s',E'%s',E'%s',E'%s',%d,E'%s',E'%s',E'%s',E'%s',E'%s',E'%s',E'%s',E'%s',E'%s',%ld);",
849  trim(pi->pkgName),trim(pi->pkgArch),trim(pi->version),trim(pi->maintainer),
850  pi->installedSize,trim(pi->section),trim(pi->priority),trim(pi->homepage),
851  trim(pi->source),trim(pi->summary),trim(pi->description),trim(pi->format),
852  trim(pi->uploaders),trim(pi->standardsVersion),pi->pFileFk);
853  result = PQexec(db_conn, SQL);
854  // ignore error
855  if ((result==0) || ((PQresultStatus(result) != PGRES_COMMAND_OK)))
856  {
857  LOG_FATAL("Error inserting, SQL is: %s, error code is:%s\n", SQL, PQresultErrorField(result, PG_DIAG_SQLSTATE));
858  PQexec(db_conn, "ROLLBACK;");
859  if (result) PQclear(result);
860  return (-1);
861  } else
862  {
863  PQclear(result);
864  }
865 
866  result = PQexec(db_conn,"SELECT currval('pkg_deb_pkg_pk_seq'::regclass);");
867  if (fo_checkPQresult(db_conn, result, SQL, __FILE__, __LINE__)) exit(-1);
868  pkg_pk = atoi(PQgetvalue(result,0,0));
869  PQclear(result);
870 
871  if (Verbose) { printf("pkg_pk:%d\n",pkg_pk);}
872  int i;
873  for (i=0;i<pi->dep_size;i++)
874  {
875  memset(SQL,0,sizeof(SQL));
876  snprintf(SQL,sizeof(SQL),"INSERT INTO pkg_deb_req (pkg_fk,req_value) values (%d,E'%s');",pkg_pk,trim(pi->depends[i]));
877  if (Verbose) { printf("DEPENDS:%s\n",pi->depends[i]);}
878  result = PQexec(db_conn, SQL);
879  if (fo_checkPQcommand(db_conn, result, SQL, __FILE__, __LINE__))
880  {
881  PQexec(db_conn, "ROLLBACK;");
882  return (-1);
883  }
884  PQclear(result);
885  }
886  result = PQexec(db_conn, "COMMIT;");
887  if (fo_checkPQcommand(db_conn, result, SQL, __FILE__, __LINE__)) exit(-1);
888  PQclear(result);
889  }
890  else
891  {
892  PQclear(result);
893  }
894  return (0);
895 }/* RecordMetadataDEB(struct debpkginfo *pi) */
896 
904 int GetMetadataDebSource (char *repFile, struct debpkginfo *pi)
905 {
906  FILE *fp;
907  char field[MAXCMD];
908  char value[MAXCMD];
909  char line[MAXCMD];
910 
911  /* Parse the debian .dsc file to get every Field and Value */
912  if ((fp = fopen(repFile, "r")) == NULL){
913  LOG_FATAL("Unable to open .dsc file %s\n",repFile);
914  return (-1);
915  }
916 
917  while (fgets(line,MAXCMD,fp)!=NULL)
918  {
919  ParseDebFile(line,field,value);
920 
921  trim(value);
922  if (!strcasecmp(field, "Format")) {
923  EscapeString(value, pi->format, sizeof(pi->format));
924  }
925  if (!strcasecmp(field, "Source")) {
926  EscapeString(value, pi->source, sizeof(pi->source));
927  }
928  if (!strcasecmp(field, "Source")) {
929  EscapeString(value, pi->pkgName, sizeof(pi->pkgName));
930  }
931  if (!strcasecmp(field, "Architecture")) {
932  EscapeString(value, pi->pkgArch, sizeof(pi->pkgArch));
933  }
934  if (!strcasecmp(field, "Version")) {
935  if (strlen(pi->version) == 0)
936  EscapeString(value, pi->version, sizeof(pi->version));
937  }
938  if (!strcasecmp(field, "Maintainer")) {
939  EscapeString(value, pi->maintainer, sizeof(pi->maintainer));
940  }
941  if (!strcasecmp(field, "Homepage")) {
942  EscapeString(value, pi->homepage, sizeof(pi->homepage));
943  }
944  if (!strcasecmp(field, "Uploaders")) {
945  EscapeString(value, pi->uploaders, sizeof(pi->uploaders));
946  }
947  if (!strcasecmp(field, "Standards-Version")) {
948  EscapeString(value, pi->standardsVersion, sizeof(pi->standardsVersion));
949  }
950  if (!strcasecmp(field, "Build-Depends")) {
951  char *depends = NULL;
952  char tempvalue[MAXCMD];
953  int size,i,length;
954  size = 0;
955  length = MAXLENGTH;
956  if (value[0] != '\0'){
957  strncpy(tempvalue, value, sizeof(tempvalue));
958  depends = strtok(value, ",");
959  while (depends && (depends[0] != '\0')) {
960  if (strlen(depends) >= length)
961  length = strlen(depends) + 1;
962  depends = strtok(NULL, ",");
963  size++;
964  }
965  if (Verbose) { printf("SIZE:%d\n", size);}
966 
967  pi->depends = calloc(size, sizeof(char *));
968  pi->depends[0] = calloc(length, sizeof(char));
969  strcpy(pi->depends[0],strtok(tempvalue,","));
970  for (i=1;i<size;i++){
971  pi->depends[i] = calloc(length, sizeof(char));
972  strcpy(pi->depends[i],strtok(NULL, ","));
973  }
974  pi->dep_size = size;
975  }
976  }
977  }
978 
979  fclose(fp);
980  return (0);
981 }/* GetMetadataDebSource(char *repFile, struct debpkginfo *pi) */
982 
983 /***********************************************
984  Usage():
985  Command line options allow you to write the agent so it works
986  stand alone, in addition to working with the scheduler.
987  This simplifies code development and testing.
988  So if you have options, have a Usage().
989  Here are some suggested options (in addition to the program
990  specific options you may already have).
991  ***********************************************/
992 void Usage (char *Name)
993 {
994  printf("Usage: %s [options] [file [file [...]]\n",Name);
995  printf(" -i :: initialize the database, then exit.\n");
996  printf(" -v :: verbose (-vv = more verbose)\n");
997  printf(" -c :: Specify the directory for the system configuration.\n");
998  printf(" -C :: run from command line.\n");
999  printf(" file :: if files are rpm package listed, display their package information.\n");
1000  printf(" no file :: process data from the scheduler.\n");
1001  printf(" -V :: print the version info, then exit.\n");
1002 } /* Usage() */
1003 
char ** depends
Package dependency list.
Definition: pkgagent.h:91
int installedSize
Size of package after install.
Definition: pkgagent.h:84
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
char maintainer[MAXCMD]
Package maintainer.
Definition: pkgagent.h:85
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 * GetFieldValue(char *Sin, char *Field, int FieldMax, char *Value, int ValueMax, char Separator)
Given a string that contains field=&#39;value&#39; pairs, save the items.
Definition: pkgagent.c:113
int GetMetadata(char *pkg, struct rpmpkginfo *pi)
Get RPM package info.
Definition: pkgagent.c:517
char version[MAXCMD]
Package version.
Definition: pkgagent.h:80
char license[512]
RPM licenses.
Definition: pkgagent.h:56
char pFile[MAXCMD]
Package pfile hash.
Definition: pkgagent.h:67
char homepage[MAXCMD]
Package link.
Definition: pkgagent.h:86
long pFileFk
Package pfile in FOSSology.
Definition: pkgagent.h:89
char description[MAXCMD]
Package description.
Definition: pkgagent.h:65
int s
The socket that the CLI will use to communicate.
Definition: fo_cli.c:48
int tag[15]
Definition: pkgagent.c:37
int RecordMetadataRPM(struct rpmpkginfo *pi)
Store rpm package info into database.
Definition: pkgagent.c:575
char packager[1024]
Packager.
Definition: pkgagent.h:58
char buildDate[128]
Package build date.
Definition: pkgagent.h:60
int dep_size
Package dependency list size.
Definition: pkgagent.h:92
char sourceRPM[256]
Package source.
Definition: pkgagent.h:63
char pkgName[256]
RPM package name.
Definition: pkgagent.h:51
Holds meta info of rpm packages.
Definition: pkgagent.h:49
char * ParseDebFile(char *Sin, char *Field, char *Value)
Parse Debian binary control file with Field/Value pairs.
Definition: pkgagent.c:641
char version[64]
Package version.
Definition: pkgagent.h:54
char standardsVersion[MAXCMD]
Package standards version.
Definition: pkgagent.h:95
char pkgArch[MAXCMD]
Package architecture.
Definition: pkgagent.h:83
Holds meta info of Debian packages.
Definition: pkgagent.h:76
char pkgName[MAXCMD]
Package name.
Definition: pkgagent.h:78
int GetMetadataDebSource(char *repFile, struct debpkginfo *pi)
Get debian source package info from .dsc file.
Definition: pkgagent.c:904
char summary[MAXCMD]
Package summary.
Definition: pkgagent.h:87
void Usage(char *Name)
Say how to run this program.
Definition: pkgagent.c:992
char description[MAXCMD]
Package description.
Definition: pkgagent.h:88
char ** requires
Package dependency list.
Definition: pkgagent.h:68
pkgagent header
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 uploaders[MAXCMD]
Package contributors.
Definition: pkgagent.h:93
char SQL[256]
SQL query to execute.
Definition: adj2nest.c:90
char summary[MAXCMD]
Package summary.
Definition: pkgagent.h:64
char pkgAlias[256]
Package alias.
Definition: pkgagent.h:52
void EscapeString(char *sourceString, char *escString, int esclen)
Escaping special characters(single quote)
Definition: pkgagent.c:63
char * fo_RepMkPath(const char *Type, char *Filename)
Given a filename, construct the full path to the file.
Definition: libfossrepo.c:364
char pkgArch[64]
Package architecture.
Definition: pkgagent.h:53
char * uploadtree_tablename
upload.uploadtree_tablename
Definition: adj2nest.c:112
PGconn * db_conn
The connection to Database.
Definition: pkgagent.c:34
int Verbose
Verbose level.
Definition: pkgagent.c:33
#define MAXLENGTH
Buffer length.
Definition: util.c:35
void ReadHeaderInfo(Header header, struct rpmpkginfo *pi)
Get RPM package info from rpm file header use rpm library.
Definition: pkgagent.c:414
char rpmFilename[256]
RPM file name.
Definition: pkgagent.h:55
int GetMetadataDebBinary(long upload_pk, struct debpkginfo *pi)
Get debian binary package info.
Definition: pkgagent.c:682
void fo_scheduler_heart(int i)
This function must be called by agents to let the scheduler know they are alive and how many items th...
char vendor[128]
Package vendor.
Definition: pkgagent.h:61
char priority[MAXCMD]
Package priority.
Definition: pkgagent.h:82
char section[MAXCMD]
Package section.
Definition: pkgagent.h:81
int ProcessUpload(long upload_pk)
Get all pfile need to processed use upload_pk.
Definition: pkgagent.c:174
char group[128]
Package group.
Definition: pkgagent.h:57
char pFile[MAXCMD]
Package pfile hash.
Definition: pkgagent.h:90
char format[MAXCMD]
Package format.
Definition: pkgagent.h:94
int RecordMetadataDEB(struct debpkginfo *pi)
Store debian package info into database.
Definition: pkgagent.c:830
char release[64]
Package release.
Definition: pkgagent.h:59
char url[256]
Package link.
Definition: pkgagent.h:62
char source[MAXCMD]
Package source.
Definition: pkgagent.h:79
int req_size
Package dependency list size.
Definition: pkgagent.h:69
long pFileFk
Package pfile in FOSSology.
Definition: pkgagent.h:66
const char * upload_pk
Definition: sqlstatements.h:93
char * trim(char *ptext)
Trimming whitespace.
Definition: fossconfig.c:695