rpm  5.4.15
pack.c
Go to the documentation of this file.
1 
6 #include "system.h"
7 
8 #include <rpmio_internal.h> /* XXX fdGetFp, fdInitDigest, fdFiniDigest */
9 #include <rpmcb.h>
10 #include <argv.h>
11 
12 #include <rpmtypes.h>
13 #include <rpmtag.h>
14 
15 #include <pkgio.h>
16 #include "signature.h" /* XXX rpmTempFile */
17 
18 #define _RPMFI_INTERNAL /* XXX fi->fsm */
19 #define _RPMEVR_INTERNAL /* XXX RPMSENSE_ANY */
20 #define _RPMTAG_INTERNAL
21 #include <rpmbuild.h>
22 
23 #include "rpmfi.h"
24 #include "fsm.h"
25 
26 #include <rpmversion.h>
27 #include "buildio.h"
28 
29 #include "debug.h"
30 
31 /*@access rpmts @*/
32 /*@access rpmfi @*/ /* compared with NULL */
33 /*@access Header @*/ /* compared with NULL */
34 /*@access FD_t @*/ /* compared with NULL */
35 /*@access CSA_t @*/
36 
40 static rpmRC cpio_doio(FD_t fdo, /*@unused@*/ Header h, CSA_t csa,
41  const char * payload_format, const char * fmodeMacro)
42  /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
43  /*@modifies fdo, csa, rpmGlobalMacroContext,
44  fileSystem, internalState @*/
45 {
46  rpmts ts = rpmtsCreate();
47  rpmfi fi = csa->fi;
48  const char *failedFile = NULL;
49  FD_t cfd;
50  rpmRC rc = RPMRC_OK;
51  int xx;
52 
53  { const char *fmode = rpmExpand(fmodeMacro, NULL);
54  if (!(fmode && fmode[0] == 'w')) {
55  fmode = _free(fmode);
56  fmode = xstrdup("w9.gzdio");
57  }
58  /*@-nullpass@*/
59  (void) Fflush(fdo);
60  cfd = Fdopen(fdDup(Fileno(fdo)), fmode);
61  /*@=nullpass@*/
62  fmode = _free(fmode);
63  }
64  if (cfd == NULL)
65  return RPMRC_FAIL;
66 
67  xx = fsmSetup(fi->fsm, IOSM_PKGBUILD, payload_format, ts, fi, cfd,
68  &csa->cpioArchiveSize, &failedFile);
69  if (xx)
70  rc = RPMRC_FAIL;
71  (void) Fclose(cfd);
72  xx = fsmTeardown(fi->fsm);
73  if (rc == RPMRC_OK && xx) rc = RPMRC_FAIL;
74 
75  if (rc) {
76  const char * msg = iosmStrerror(rc);
77  if (failedFile)
78  rpmlog(RPMLOG_ERR, _("create archive failed on file %s: %s\n"),
79  failedFile, msg);
80  else
81  rpmlog(RPMLOG_ERR, _("create archive failed: %s\n"), msg);
82  msg = _free(msg);
83  rc = RPMRC_FAIL;
84  }
85 
86  failedFile = _free(failedFile);
87  (void)rpmtsFree(ts);
88  ts = NULL;
89 
90  return rc;
91 }
92 
95 static rpmRC cpio_copy(FD_t fdo, CSA_t csa)
96  /*@globals fileSystem, internalState @*/
97  /*@modifies fdo, csa, fileSystem, internalState @*/
98 {
99  char buf[BUFSIZ];
100  size_t nb;
101 
102  while((nb = Fread(buf, sizeof(buf[0]), sizeof(buf), csa->cpioFdIn)) > 0) {
103  if (Fwrite(buf, sizeof(buf[0]), nb, fdo) != nb) {
104  rpmlog(RPMLOG_ERR, _("cpio_copy write failed: %s\n"),
105  Fstrerror(fdo));
106  return RPMRC_FAIL;
107  }
108  csa->cpioArchiveSize += nb;
109  }
110  if (Ferror(csa->cpioFdIn)) {
111  rpmlog(RPMLOG_ERR, _("cpio_copy read failed: %s\n"),
112  Fstrerror(csa->cpioFdIn));
113  return RPMRC_FAIL;
114  }
115  return RPMRC_OK;
116 }
117 
120 static /*@only@*/ /*@null@*/ rpmiob addFileToTagAux(Spec spec,
121  const char * file, /*@only@*/ rpmiob iob)
122  /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
123  /*@modifies rpmGlobalMacroContext, fileSystem, internalState @*/
124 {
125  char buf[BUFSIZ];
126  const char * fn = buf;
127  FILE * f;
128  FD_t fd;
129 
130  fn = rpmGetPath("%{_builddir}/%{?buildsubdir:%{buildsubdir}/}", file, NULL);
131 
132  fd = Fopen(fn, "r.fdio");
133  if (fn != buf) fn = _free(fn);
134  if (fd == NULL || Ferror(fd)) {
135  iob = rpmiobFree(iob);
136  return NULL;
137  }
138  /*@-type@*/ /* FIX: cast? */
139  if ((f = fdGetFp(fd)) != NULL)
140  /*@=type@*/
141  while (fgets(buf, (int)sizeof(buf), f)) {
142  /* XXX display fn in error msg */
143  if (expandMacros(spec, spec->macros, buf, sizeof(buf))) {
144  rpmlog(RPMLOG_ERR, _("line: %s\n"), buf);
145  iob = rpmiobFree(iob);
146  break;
147  }
148  iob = rpmiobAppend(iob, buf, 0);
149  }
150  (void) Fclose(fd);
151 
152  return iob;
153 }
154 
157 static int addFileToTag(Spec spec, const char * file, Header h, rpmTag tag)
158  /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
159  /*@modifies h, rpmGlobalMacroContext, fileSystem, internalState @*/
160 {
161  HE_t he = (HE_t) memset(alloca(sizeof(*he)), 0, sizeof(*he));
162  rpmiob iob = rpmiobNew(0);
163  int xx;
164 
165  he->tag = tag;
166  xx = headerGet(h, he, 0);
167  if (xx) {
168  iob = rpmiobAppend(iob, he->p.str, 1);
169  xx = headerDel(h, he, 0);
170  }
171  he->p.ptr = _free(he->p.ptr);
172 
173  if ((iob = addFileToTagAux(spec, file, iob)) == NULL)
174  return 1;
175 
176  he->tag = tag;
177  he->t = RPM_STRING_TYPE;
178  he->p.str = rpmiobStr(iob);
179  he->c = 1;
180  xx = headerPut(h, he, 0);
181 
182  iob = rpmiobFree(iob);
183  return 0;
184 }
185 
188 static int addFileToArrayTag(Spec spec, const char *file, Header h, rpmTag tag)
189  /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
190  /*@modifies h, rpmGlobalMacroContext, fileSystem, internalState @*/
191 {
192  HE_t he = (HE_t) memset(alloca(sizeof(*he)), 0, sizeof(*he));
193  rpmiob iob = rpmiobNew(0);
194  const char *s;
195  int xx;
196 
197  if ((iob = addFileToTagAux(spec, file, iob)) == NULL)
198  return 1;
199 
200  s = rpmiobStr(iob);
201 
202  he->tag = tag;
203  he->t = RPM_STRING_ARRAY_TYPE;
204  he->p.argv = &s;
205  he->c = 1;
206  he->append = 1;
207  xx = headerPut(h, he, 0);
208  he->append = 0;
209 
210  iob = rpmiobFree(iob);
211  return 0;
212 }
213 
215  /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
216  /*@modifies pkg->header, rpmGlobalMacroContext,
217  fileSystem, internalState @*/
218 {
219  HE_t he = (HE_t) memset(alloca(sizeof(*he)), 0, sizeof(*he));
220  struct TriggerFileEntry *p;
221  int xx;
222 
223  if (pkg->preInFile) {
224  if (addFileToTag(spec, pkg->preInFile, pkg->header, RPMTAG_PREIN)) {
226  _("Could not open PreIn file: %s\n"), pkg->preInFile);
227  return RPMRC_FAIL;
228  }
229  }
230  if (pkg->preUnFile) {
231  if (addFileToTag(spec, pkg->preUnFile, pkg->header, RPMTAG_PREUN)) {
233  _("Could not open PreUn file: %s\n"), pkg->preUnFile);
234  return RPMRC_FAIL;
235  }
236  }
237  if (pkg->preTransFile) {
238  if (addFileToTag(spec, pkg->preTransFile, pkg->header, RPMTAG_PRETRANS)) {
240  _("Could not open PreTrans file: %s\n"), pkg->preTransFile);
241  return RPMRC_FAIL;
242  }
243  }
244  if (pkg->postInFile) {
245  if (addFileToTag(spec, pkg->postInFile, pkg->header, RPMTAG_POSTIN)) {
247  _("Could not open PostIn file: %s\n"), pkg->postInFile);
248  return RPMRC_FAIL;
249  }
250  }
251  if (pkg->postUnFile) {
252  if (addFileToTag(spec, pkg->postUnFile, pkg->header, RPMTAG_POSTUN)) {
254  _("Could not open PostUn file: %s\n"), pkg->postUnFile);
255  return RPMRC_FAIL;
256  }
257  }
258  if (pkg->postTransFile) {
259  if (addFileToTag(spec, pkg->postTransFile, pkg->header, RPMTAG_POSTTRANS)) {
261  _("Could not open PostTrans file: %s\n"), pkg->postTransFile);
262  return RPMRC_FAIL;
263  }
264  }
265  if (pkg->verifyFile) {
266  if (addFileToTag(spec, pkg->verifyFile, pkg->header,
269  _("Could not open VerifyScript file: %s\n"), pkg->verifyFile);
270  return RPMRC_FAIL;
271  }
272  }
273 
274  if (pkg->sanityCheckFile) {
275  if (addFileToTag(spec, pkg->sanityCheckFile, pkg->header, RPMTAG_SANITYCHECK)) {
276  rpmlog(RPMLOG_ERR, _("Could not open Test file: %s\n"), pkg->sanityCheckFile);
277  return RPMRC_FAIL;
278  }
279  }
280 
281  for (p = pkg->triggerFiles; p != NULL; p = p->next) {
283  he->t = RPM_STRING_ARRAY_TYPE;
284  he->p.argv = (const char **)&p->prog; /* XXX NOCAST */
285  he->c = 1;
286  he->append = 1;
287  xx = headerPut(pkg->header, he, 0);
288  he->append = 0;
289  if (p->script) {
291  he->t = RPM_STRING_ARRAY_TYPE;
292  he->p.argv = (const char **)&p->script; /* XXX NOCAST */
293  he->c = 1;
294  he->append = 1;
295  xx = headerPut(pkg->header, he, 0);
296  he->append = 0;
297  } else if (p->fileName) {
298  if (addFileToArrayTag(spec, p->fileName, pkg->header,
301  _("Could not open Trigger script file: %s\n"),
302  p->fileName);
303  return RPMRC_FAIL;
304  }
305  } else {
306  /*@observer@*/
307  static const char *bull = "";
309  he->t = RPM_STRING_ARRAY_TYPE;
310  he->p.argv = &bull;
311  he->c = 1;
312  he->append = 1;
313  xx = headerPut(pkg->header, he, 0);
314  he->append = 0;
315  }
316  }
317 
318  return RPMRC_OK;
319 }
320 
321 #if defined(DEAD)
322 int readRPM(const char *fileName, Spec *specp, void * l,
323  Header *sigs, CSA_t csa)
324 {
325  const char * msg = "";
326  FD_t fdi;
327  Spec spec;
328  rpmRC rc;
329 
330  fdi = (fileName != NULL)
331  ? Fopen(fileName, "r.fdio")
332  : fdDup(STDIN_FILENO);
333 
334  if (fdi == NULL || Ferror(fdi)) {
335  rpmlog(RPMLOG_ERR, _("readRPM: open %s: %s\n"),
336  (fileName ? fileName : "<stdin>"),
337  Fstrerror(fdi));
338  if (fdi) (void) Fclose(fdi);
339  return RPMRC_FAIL;
340  }
341 
342  { const char item[] = "Lead";
343  size_t nl = rpmpkgSizeof(item, NULL);
344 
345  if (nl == 0) {
346  rc = RPMRC_FAIL;
347  msg = xstrdup("item size is zero");
348  } else {
349  l = xcalloc(1, nl); /* XXX memory leak */
350  msg = NULL;
351  rc = rpmpkgRead(item, fdi, l, &msg);
352  }
353  }
354 
355  if (rc != RPMRC_OK) {
356  rpmlog(RPMLOG_ERR, _("readRPM: read %s: %s\n"),
357  (fileName ? fileName : "<stdin>"), msg);
358  msg = _free(msg);
359  return RPMRC_FAIL;
360  }
361  msg = _free(msg);
362  /*@=sizeoftype@*/
363 
364  /* XXX FIXME: EPIPE on <stdin> */
365  if (Fseek(fdi, 0, SEEK_SET) == -1) {
366  rpmlog(RPMLOG_ERR, _("%s: Fseek failed: %s\n"),
367  (fileName ? fileName : "<stdin>"), Fstrerror(fdi));
368  return RPMRC_FAIL;
369  }
370 
371  /* Reallocate build data structures */
372  spec = newSpec();
373  spec->packages = newPackage(spec);
374 
375  /* XXX the header just allocated will be allocated again */
376  (void)headerFree(spec->packages->header);
377  spec->packages->header = NULL;
378 
379  /* Read the rpm lead, signatures, and header */
380  { rpmts ts = rpmtsCreate();
381 
382  /* XXX W2DO? pass fileName? */
383  /*@-mustmod@*/ /* LCL: segfault */
384  rc = rpmReadPackageFile(ts, fdi, "readRPM",
385  &spec->packages->header);
386  /*@=mustmod@*/
387 
388  (void)rpmtsFree(ts);
389  ts = NULL;
390 
391  if (sigs) *sigs = NULL; /* XXX HACK */
392  }
393 
394  switch (rc) {
395  case RPMRC_OK:
396  case RPMRC_NOKEY:
397  case RPMRC_NOTTRUSTED:
398  break;
399  case RPMRC_NOTFOUND:
400  rpmlog(RPMLOG_ERR, _("readRPM: %s is not an RPM package\n"),
401  (fileName ? fileName : "<stdin>"));
402  return RPMRC_FAIL;
403  case RPMRC_FAIL:
404  default:
405  rpmlog(RPMLOG_ERR, _("readRPM: reading header from %s\n"),
406  (fileName ? fileName : "<stdin>"));
407  return RPMRC_FAIL;
408  /*@notreached@*/ break;
409  }
410 
411  if (specp)
412  *specp = spec;
413  else
414  spec = freeSpec(spec);
415 
416  if (csa != NULL)
417  csa->cpioFdIn = fdi;
418  else
419  (void) Fclose(fdi);
420 
421  return 0;
422 }
423 #endif
424 
425 #if defined(DEAD)
426 #define RPMPKGVERSION_MIN 30004
427 #define RPMPKGVERSION_MAX 40003
428 /*@unchecked@*/
429 static int rpmpkg_version = -1;
430 
431 static int rpmLeadVersion(void)
432  /*@globals rpmpkg_version, rpmGlobalMacroContext, h_errno @*/
433  /*@modifies rpmpkg_version, rpmGlobalMacroContext @*/
434 {
435  int rpmlead_version;
436 
437  /* Intitialize packaging version from macro configuration. */
438  if (rpmpkg_version < 0) {
439  rpmpkg_version = rpmExpandNumeric("%{_package_version}");
440  if (rpmpkg_version < RPMPKGVERSION_MIN)
441  rpmpkg_version = RPMPKGVERSION_MIN;
442  if (rpmpkg_version > RPMPKGVERSION_MAX)
443  rpmpkg_version = RPMPKGVERSION_MAX;
444  }
445 
446  rpmlead_version = rpmpkg_version / 10000;
447  /* XXX silly sanity check. */
448  if (rpmlead_version < 3 || rpmlead_version > 4)
449  rpmlead_version = 3;
450  return rpmlead_version;
451 }
452 #endif
453 
455 {
456  HE_t he = (HE_t) memset(alloca(sizeof(*he)), 0, sizeof(*he));
457  const char *N, *V, *R;
458 #ifdef RPM_VENDOR_MANDRIVA
459  const char *D;
460  int gotD;
461 #endif
462  rpmuint32_t E;
463  int gotE;
464  const char *pEVR;
465  char *p;
466  rpmuint32_t pFlags = RPMSENSE_EQUAL;
467  const char ** provides = NULL;
468  const char ** providesEVR = NULL;
469  rpmuint32_t * provideFlags = NULL;
470  int providesCount;
471  int bingo = 1;
472  size_t nb;
473  int xx;
474  int i;
475 
476  /* Generate provides for this package N-V-R. */
477  xx = headerNEVRA(h, &N, NULL, &V, &R, NULL);
478  if (!(N && V && R)) {
479  N = _free(N);
480  V = _free(V);
481  R = _free(R);
482  return;
483  }
484 
485  nb = 21 + strlen(V) + 1 + strlen(R) + 1;
486 #ifdef RPM_VENDOR_MANDRIVA
487  he->tag = RPMTAG_DISTEPOCH;
488  gotD = headerGet(h, he, 0);
489  D = (he->p.str ? he->p.str : NULL);
490  nb += (gotD ? strlen(D) + 1 : 0);
491 #endif
492  pEVR = p = alloca(nb);
493  *p = '\0';
494  he->tag = RPMTAG_EPOCH;
495  gotE = headerGet(h, he, 0);
496  E = (he->p.ui32p ? he->p.ui32p[0] : 0);
497  he->p.ptr = _free(he->p.ptr);
498  if (gotE) {
499  sprintf(p, "%d:", E);
500  p += strlen(p);
501  }
502  p = stpcpy( stpcpy( stpcpy(p, V) , "-") , R);
503 #ifdef RPM_VENDOR_MANDRIVA
504  if (gotD) {
505  p = stpcpy( stpcpy( p, ":"), D);
506  D = _free(D);
507  }
508 #endif
509  V = _free(V);
510  R = _free(R);
511 
512  /*
513  * Rpm prior to 3.0.3 does not have versioned provides.
514  * If no provides at all are available, we can just add.
515  */
516  he->tag = RPMTAG_PROVIDENAME;
517 /*@-nullstate@*/
518  xx = headerGet(h, he, 0);
519 /*@=nullstate@*/
520  provides = he->p.argv;
521  providesCount = he->c;
522  if (!xx)
523  goto exit;
524 
525  /*
526  * Otherwise, fill in entries on legacy packages.
527  */
529 /*@-nullstate@*/
530  xx = headerGet(h, he, 0);
531 /*@=nullstate@*/
532  providesEVR = he->p.argv;
533  if (!xx) {
534  for (i = 0; i < providesCount; i++) {
535  /*@observer@*/
536  static const char * vdummy = "";
537  static rpmsenseFlags fdummy = RPMSENSE_ANY;
538 
540  he->t = RPM_STRING_ARRAY_TYPE;
541  he->p.argv = &vdummy;
542  he->c = 1;
543  he->append = 1;
544 /*@-nullstate@*/
545  xx = headerPut(h, he, 0);
546 /*@=nullstate@*/
547  he->append = 0;
548 
549  he->tag = RPMTAG_PROVIDEFLAGS;
550  he->t = RPM_UINT32_TYPE;
551  he->p.ui32p = (void *) &fdummy;
552  he->c = 1;
553  he->append = 1;
554 /*@-nullstate@*/
555  xx = headerPut(h, he, 0);
556 /*@=nullstate@*/
557  he->append = 0;
558  }
559  goto exit;
560  }
561 
562  he->tag = RPMTAG_PROVIDEFLAGS;
563 /*@-nullstate@*/
564  xx = headerGet(h, he, 0);
565 /*@=nullstate@*/
566  provideFlags = he->p.ui32p;
567 
568  /*@-nullderef@*/ /* LCL: providesEVR is not NULL */
569  if (provides && providesEVR && provideFlags)
570  for (i = 0; i < providesCount; i++) {
571  if (!(provides[i] && providesEVR[i]))
572  continue;
573  if (!(provideFlags[i] == RPMSENSE_EQUAL &&
574  !strcmp(N, provides[i]) && !strcmp(pEVR, providesEVR[i])))
575  continue;
576  bingo = 0;
577  break;
578  }
579  /*@=nullderef@*/
580 
581 exit:
582 /*@-usereleased@*/
583  provides = _free(provides);
584  providesEVR = _free(providesEVR);
585  provideFlags = _free(provideFlags);
586 /*@=usereleased@*/
587 
588  if (bingo) {
589  he->tag = RPMTAG_PROVIDENAME;
590  he->t = RPM_STRING_ARRAY_TYPE;
591  he->p.argv = &N;
592  he->c = 1;
593  he->append = 1;
594 /*@-nullstate@*/
595  xx = headerPut(h, he, 0);
596 /*@=nullstate@*/
597  he->append = 0;
598 
600  he->t = RPM_STRING_ARRAY_TYPE;
601  he->p.argv = &pEVR;
602  he->c = 1;
603  he->append = 1;
604 /*@-nullstate@*/
605  xx = headerPut(h, he, 0);
606 /*@=nullstate@*/
607  he->append = 0;
608 
609  he->tag = RPMTAG_PROVIDEFLAGS;
610  he->t = RPM_UINT32_TYPE;
611  he->p.ui32p = &pFlags;
612  he->c = 1;
613  he->append = 1;
614 /*@-nullstate@*/
615  xx = headerPut(h, he, 0);
616 /*@=nullstate@*/
617  he->append = 0;
618  }
619  N = _free(N);
620 }
621 
627 static
628 unsigned char nibble(char c)
629  /*@*/
630 {
631  if (c >= '0' && c <= '9')
632  return (unsigned char) (c - '0');
633  if (c >= 'A' && c <= 'F')
634  return (unsigned char)((int)(c - 'A') + 10);
635  if (c >= 'a' && c <= 'f')
636  return (unsigned char)((int)(c - 'a') + 10);
637  return (unsigned char) '\0';
638 }
639 
640 rpmRC writeRPM(Header *hdrp, unsigned char ** pkgidp, const char * fn,
641  CSA_t csa, char * passPhrase, const char ** cookie, void * _dig)
642 
643 {
644  HE_t he = (HE_t) memset(alloca(sizeof(*he)), 0, sizeof(*he));
645  FD_t fd = NULL;
646  FD_t ifd = NULL;
647 pgpDig dig = _dig;
648  rpmuint32_t sigtag;
649  const char * sigtarget = NULL; /* XXX coverity #1035966 */
650  const char * rpmio_flags = NULL;
651  const char * payload_format = NULL;
652  const char * SHA1 = NULL;
653  const char * msg = NULL;
654  char * s;
655  char buf[BUFSIZ];
656  Header h;
657  Header sigh = NULL;
658  int addsig = 0;
659  int isSource;
660  rpmRC rc = RPMRC_OK;
661  size_t nbr;
662  size_t nbw;
663  int xx;
664 
665  /* Transfer header reference form *hdrp to h. */
666  h = headerLink(*hdrp);
667 
668  (void)headerFree(*hdrp);
669  *hdrp = NULL;
670 
671  if (pkgidp)
672  *pkgidp = NULL;
673 
674  /* Save payload information */
675  isSource =
676  (headerIsEntry(h, RPMTAG_SOURCERPM) == 0 &&
677  headerIsEntry(h, RPMTAG_ARCH) != 0);
678  if (isSource) {
679  payload_format = rpmExpand("%{?_source_payload_format}", NULL);
680  rpmio_flags = rpmExpand("%{?_source_payload}", NULL);
681  } else {
682  payload_format = rpmExpand("%{?_binary_payload_format}", NULL);
683  rpmio_flags = rpmExpand("%{?_binary_payload}", NULL);
684  }
685 
686  if (!(payload_format && *payload_format)) {
687  payload_format = _free(payload_format);
688  payload_format = xstrdup("cpio");
689  }
690  if (!(rpmio_flags && *rpmio_flags)) {
691  rpmio_flags = _free(rpmio_flags);
692  rpmio_flags = xstrdup("w9.gzdio");
693  }
694  s = strchr(rpmio_flags, '.');
695  if (s) {
696 
697  if (payload_format) {
698  if (!strcmp(payload_format, "tar")
699  || !strcmp(payload_format, "ustar")) {
700  /* XXX addition to header is too late to be displayed/sorted. */
701  /* Add prereq on rpm version that understands tar payloads */
702  (void) rpmlibNeedsFeature(h, "PayloadIsUstar", "4.4.4-1");
703  }
704 #if defined(SUPPORT_AR_PAYLOADS)
705  if (!strcmp(payload_format, "ar")) {
706  /* XXX addition to header is too late to be displayed/sorted. */
707  /* Add prereq on rpm version that understands tar payloads */
708  (void) rpmlibNeedsFeature(h, "PayloadIsAr", "5.1-1");
709  }
710 #endif
711 
713  he->t = RPM_STRING_TYPE;
714  he->p.str = payload_format;
715  he->c = 1;
716  xx = headerPut(h, he, 0);
717  }
718 
719  /* XXX addition to header is too late to be displayed/sorted. */
720  if (s[1] == 'g' && s[2] == 'z') {
722  he->t = RPM_STRING_TYPE;
723  he->p.str = xstrdup("gzip");
724  he->c = 1;
725  xx = headerPut(h, he, 0);
726  he->p.ptr = _free(he->p.ptr);
727  } else if (s[1] == 'b' && s[2] == 'z') {
729  he->t = RPM_STRING_TYPE;
730  he->p.str = xstrdup("bzip2");
731  he->c = 1;
732  xx = headerPut(h, he, 0);
733  he->p.ptr = _free(he->p.ptr);
734  } else if (s[1] == 'l' && s[2] == 'z') {
736  he->t = RPM_STRING_TYPE;
737  he->p.str = xstrdup("lzma");
738  he->c = 1;
739  xx = headerPut(h, he, 0);
740  he->p.ptr = _free(he->p.ptr);
741  (void) rpmlibNeedsFeature(h, "PayloadIsLzma", "4.4.6-1");
742  } else if (s[1] == 'x' && s[2] == 'z') {
744  he->t = RPM_STRING_TYPE;
745  he->p.str = xstrdup("xz");
746  he->c = 1;
747  xx = headerPut(h, he, 0);
748  he->p.ptr = _free(he->p.ptr);
749  (void) rpmlibNeedsFeature(h, "PayloadIsXz", "5.2-1");
750  }
751  strncpy(buf, rpmio_flags, sizeof(buf)-1);
752  buf[s - rpmio_flags] = '\0';
753 
754  he->tag = RPMTAG_PAYLOADFLAGS;
755  he->t = RPM_STRING_TYPE;
756  he->p.str = buf+1;
757  he->c = 1;
758  xx = headerPut(h, he, 0);
759  }
760  s = NULL;
761 
762  /* Create and add the cookie */
763  if (cookie) {
764  sprintf(buf, "%s %u", buildHost(), (unsigned) (*getBuildTime()));
765  *cookie = xstrdup(buf); /* XXX memory leak */
766  he->tag = RPMTAG_COOKIE;
767  he->t = RPM_STRING_TYPE;
768  he->p.str = *cookie;
769  he->c = 1;
770  xx = headerPut(h, he, 0);
771  }
772 
773  /* Add the non-repudiable public key (skip if --sign was specified) */
774  if (!addsig && dig && dig->pub && dig->publen > 0) {
775  rpmuint8_t atype = PGPARMOR_PUBKEY;
776  s = pgpArmorWrap(atype, dig->pub, dig->publen);
777 assert(s);
778  he->tag = (rpmTag) RPMTAG_PUBKEYS;
779  he->t = RPM_STRING_ARRAY_TYPE;
780  he->p.argv = (const char **) &s;
781  he->c = 1;
782  he->append = 1;
783  xx = headerPut(h, he, 0);
784  he->append = 0;
785  s = _free(s);
786  }
787 
788  /* Reallocate the header into one contiguous region. */
790  if (h == NULL) { /* XXX can't happen */
791  rpmlog(RPMLOG_ERR, _("Unable to create immutable header region.\n"));
792  rc = RPMRC_FAIL;
793  goto exit;
794  }
795  /* Re-reference reallocated header. */
796  *hdrp = headerLink(h);
797 
798  /*
799  * Write the header+archive into a temp file so that the size of
800  * archive (after compression) can be added to the header.
801  */
802  sigtarget = NULL;
803  if (rpmTempFile(NULL, &sigtarget, &fd)) {
804  rpmlog(RPMLOG_ERR, _("Unable to open temp file.\n"));
805  rc = RPMRC_FAIL;
806  goto exit;
807  }
808 
809 pgpDigParams sigp = pgpGetSignature(dig);
810 pgpDigParams pubp = pgpGetPubkey(dig);
811 
812  /* Write the header to a temp file, computing header SHA1 on the fly. */
814 assert(fd->ndigests == 1);
815  if (sigp->hash_algo != PGPHASHALGO_SHA1) {
816  fdInitDigest(fd, sigp->hash_algo, 0);
817 assert(fd->ndigests == 2);
818  }
819  { const char item[] = "Header";
820  msg = NULL;
821  rc = rpmpkgWrite(item, fd, h, &msg);
822  if (rc != RPMRC_OK) {
823  rpmlog(RPMLOG_ERR, "%s: %s: %s\n", sigtarget, item,
824  (msg && *msg ? msg : "write failed\n"));
825  msg = _free(msg);
826  rc = RPMRC_FAIL;
827  goto exit;
828  }
829  msg = _free(msg);
830  (void) Fflush(fd);
831  }
832 
833  { /* XXX Dupe the header digest for the non-repudiable signature. */
834  DIGEST_CTX ctx = (dig ? rpmDigestDup(fd->digests[fd->ndigests-1]) : NULL);
835 
836  /* Finalize the header signature digest. */
837  /* XXX FIXME: get binary octets, not ASCII. */
838  fdFiniDigest(fd, PGPHASHALGO_SHA1, &SHA1, NULL, 1);
839 
840 sigp->signhash16[0] = (rpmuint8_t) (nibble(SHA1[0]) << 4) | nibble(SHA1[1]);
841 sigp->signhash16[1] = (rpmuint8_t) (nibble(SHA1[2]) << 4) | nibble(SHA1[3]);
842 
843  /* Sign the header SHA1. */
844  if (ctx)
845  xx = pgpExportSignature(dig, ctx);
846 
847  }
848 
849  /* Append the payload to the temp file. */
850  if (csa->fi != NULL)
851  rc = cpio_doio(fd, h, csa, payload_format, rpmio_flags);
852  else if (Fileno(csa->cpioFdIn) >= 0)
853  rc = cpio_copy(fd, csa);
854  else
855 assert(0);
856 
857  if (rc != RPMRC_OK)
858  goto exit;
859 
860  (void) Fclose(fd);
861  fd = NULL;
862  (void) Unlink(fn);
863 
864  /* Generate the signature */
865  (void) fflush(stdout);
866  sigh = headerNew();
867  (void) rpmAddSignature(sigh, sigtarget, RPMSIGTAG_SIZE, passPhrase);
868  (void) rpmAddSignature(sigh, sigtarget, RPMSIGTAG_MD5, passPhrase);
869 
870  sigtag = RPMSIGTAG_GPG;
871  addsig = (passPhrase && passPhrase[0]);
872 
873  if (addsig) {
874  rpmlog(RPMLOG_NOTICE, _("Generating signature: %d\n"), sigtag);
875  (void) rpmAddSignature(sigh, sigtarget, sigtag, passPhrase);
876  }
877  else if (dig && dig->sig && dig->siglen > 0) {
878  switch (pubp->pubkey_algo) {
879  default:
880 assert(0);
881  break;
882  case PGPPUBKEYALGO_RSA:
883  he->tag = (rpmTag) RPMSIGTAG_RSA;
884  break;
885  case PGPPUBKEYALGO_DSA:
886  he->tag = (rpmTag) RPMSIGTAG_DSA;
887  break;
888  case PGPPUBKEYALGO_ECDSA:
889  he->tag = (rpmTag) RPMSIGTAG_ECDSA;
890  break;
891  }
892  he->t = RPM_BIN_TYPE;
893  he->p.ptr = (void *) dig->sig;
894  he->c = dig->siglen;
895  xx = headerPut(sigh, he, 0);
896  dig->sig = _free(dig->sig); /* XXX lazily instead? */
897  dig->siglen = 0;
898  }
899 
900  if (SHA1) {
901  he->tag = (rpmTag) RPMSIGTAG_SHA1;
902  he->t = RPM_STRING_TYPE;
903  he->p.str = SHA1;
904  he->c = 1;
905  xx = headerPut(sigh, he, 0);
906  SHA1 = _free(SHA1);
907  }
908 
909  { rpmuint32_t payloadSize = csa->cpioArchiveSize;
911  he->t = RPM_UINT32_TYPE;
912  he->p.ui32p = &payloadSize;
913  he->c = 1;
914  xx = headerPut(sigh, he, 0);
915  }
916 
917  /* Reallocate the signature header into one contiguous region. */
919  if (sigh == NULL) { /* XXX can't happen */
920  rpmlog(RPMLOG_ERR, _("Unable to reload signature header.\n"));
921  rc = RPMRC_FAIL;
922  goto exit;
923  }
924 
925  /* Pad the signature header to put the metadata header at known offset. */
926  { size_t slen = 0;
927  void * uh = headerUnload(sigh, &slen);
928  static const size_t align = 1024;
929  size_t nb = align - 96 - 16 - 16;
930  rpmuint8_t * b;
931 
932  uh = _free(uh);
933 assert(slen < nb);
934  nb -= slen;
935  b = memset(alloca(nb), 0, nb);
936  he->tag = (rpmTag) RPMSIGTAG_PADDING;
937  he->t = RPM_BIN_TYPE;
938  he->p.ui8p = b;
939  he->c = nb;
940  xx = headerPut(sigh, he, 0);
942 assert(sigh != NULL);
943  }
944 
945  /* Open the output file */
946  fd = Fopen(fn, "w.fdio");
947  if (fd == NULL || Ferror(fd)) {
948  rpmlog(RPMLOG_ERR, _("Could not open %s: %s\n"),
949  fn, Fstrerror(fd));
950  rc = RPMRC_FAIL;
951  goto exit;
952  }
953 
954  /* Write the lead section into the package. */
955  { const char item[] = "Lead";
956  size_t nl = rpmpkgSizeof(item, NULL);
957 
958  msg = NULL;
959  if (nl == 0)
960  rc = RPMRC_FAIL;
961  else {
962  void * l = memset(alloca(nl), 0, nl);
963  const char *N, *V, *R;
964  (void) headerNEVRA(h, &N, NULL, &V, &R, NULL);
965  sprintf(buf, "%s-%s-%s", N, V, R);
966  N = _free(N);
967  V = _free(V);
968  R = _free(R);
969  msg = buf;
970  rc = rpmpkgWrite(item, fd, l, &msg);
971  }
972 
973  if (rc != RPMRC_OK) {
974  rpmlog(RPMLOG_ERR, _("Unable to write package: %s\n"),
975  Fstrerror(fd));
976  rc = RPMRC_FAIL;
977  goto exit;
978  }
979  }
980 
981  /* Write the signature section into the package. */
982  { const char item[] = "Signature";
983 
984  msg = NULL;
985  rc = rpmpkgWrite(item, fd, sigh, &msg);
986  if (rc != RPMRC_OK) {
987  rpmlog(RPMLOG_ERR, "%s: %s: %s\n", fn, item,
988  (msg && *msg ? msg : "write failed\n"));
989  msg = _free(msg);
990  rc = RPMRC_FAIL;
991  goto exit;
992  }
993  msg = _free(msg);
994  }
995 
996  /* Append the header and archive */
997  ifd = Fopen(sigtarget, "r.fdio");
998  if (ifd == NULL || Ferror(ifd)) {
999  rpmlog(RPMLOG_ERR, _("Unable to open sigtarget %s: %s\n"),
1000  sigtarget, Fstrerror(ifd));
1001  rc = RPMRC_FAIL;
1002  goto exit;
1003  }
1004 
1005  /* Add signatures to header, and write header into the package. */
1006  { const char item[] = "Header";
1007  Header nh = NULL;
1008 
1009  msg = NULL;
1010  rc = rpmpkgRead(item, ifd, &nh, &msg);
1011  if (rc != RPMRC_OK) {
1012  rpmlog(RPMLOG_ERR, "%s: %s: %s\n", sigtarget, item,
1013  (msg && *msg ? msg : "read failed\n"));
1014  msg = _free(msg);
1015  rc = RPMRC_FAIL;
1016  goto exit;
1017  }
1018  msg = _free(msg);
1019 
1020 #ifdef NOTYET
1021  (void) headerMergeLegacySigs(nh, sigh);
1022 #endif
1023 
1024  msg = NULL;
1025  rc = rpmpkgWrite(item, fd, nh, &msg);
1026  (void)headerFree(nh);
1027  nh = NULL;
1028  if (rc != RPMRC_OK) {
1029  rpmlog(RPMLOG_ERR, "%s: %s: %s\n", fn, item,
1030  (msg && *msg ? msg : "write failed\n"));
1031  msg = _free(msg);
1032  rc = RPMRC_FAIL;
1033  goto exit;
1034  }
1035  msg = _free(msg);
1036  }
1037 
1038  /* Write the payload into the package. */
1039  while ((nbr = Fread(buf, sizeof(buf[0]), sizeof(buf), ifd)) > 0) {
1040  if (Ferror(ifd)) {
1041  rpmlog(RPMLOG_ERR, _("Unable to read payload from %s: %s\n"),
1042  sigtarget, Fstrerror(ifd));
1043  rc = RPMRC_FAIL;
1044  goto exit;
1045  }
1046  nbw = (int)Fwrite(buf, sizeof(buf[0]), nbr, fd);
1047  if (nbr != nbw || Ferror(fd)) {
1048  rpmlog(RPMLOG_ERR, _("Unable to write payload to %s: %s\n"),
1049  fn, Fstrerror(fd));
1050  rc = RPMRC_FAIL;
1051  goto exit;
1052  }
1053  }
1054  rc = RPMRC_OK;
1055 
1056 exit:
1057  SHA1 = _free(SHA1);
1058  rpmio_flags = _free(rpmio_flags);
1059  payload_format = _free(payload_format);
1060  (void)headerFree(h);
1061  h = NULL;
1062 
1063  /* XXX Fish the pkgid out of the signature header. */
1064  if (sigh != NULL && pkgidp != NULL) {
1065  he->tag = (rpmTag) RPMSIGTAG_MD5;
1066  xx = headerGet(sigh, he, 0);
1067  if (he->t == RPM_BIN_TYPE && he->p.ptr != NULL && he->c == 16)
1068  *pkgidp = he->p.ui8p; /* XXX memory leak */
1069  }
1070 
1071  (void)headerFree(sigh);
1072  sigh = NULL;
1073  if (ifd) {
1074  (void) Fclose(ifd);
1075  ifd = NULL;
1076  }
1077  if (fd) {
1078  (void) Fclose(fd);
1079  fd = NULL;
1080  }
1081  if (sigtarget) {
1082  (void) Unlink(sigtarget);
1083  sigtarget = _free(sigtarget);
1084  }
1085 
1086  if (rc == RPMRC_OK)
1087  rpmlog(RPMLOG_NOTICE, _("Wrote: %s\n"), fn);
1088  else
1089  (void) Unlink(fn);
1090 
1091  return rc;
1092 }
1093 
1094 static int rpmlibMarkers(Header h)
1095  /*@modifies h @*/
1096 {
1097  HE_t he = (HE_t) memset(alloca(sizeof(*he)), 0, sizeof(*he));
1098  rpmuint32_t val;
1099  int xx;
1100 
1101  he->tag = RPMTAG_RPMVERSION;
1102  he->t = RPM_STRING_TYPE;
1103  he->p.str = xstrdup(VERSION);
1104  he->c = 1;
1105  xx = headerPut(h, he, 0);
1106  he->p.ptr = _free(he->p.ptr);
1107 
1108  if (!(_rpmbuildFlags & 4)) {
1109  val = (rpmuint32_t)rpmlibTimestamp();
1111  he->t = RPM_UINT32_TYPE;
1112  he->p.ui32p = &val;
1113  he->c = 1;
1114  xx = headerPut(h, he, 0);
1115 
1116  val = (rpmuint32_t)rpmlibVendor();
1117  he->tag = RPMTAG_RPMLIBVENDOR;
1118  he->t = RPM_UINT32_TYPE;
1119  he->p.ui32p = &val;
1120  he->c = 1;
1121  xx = headerPut(h, he, 0);
1122 
1123  val = (rpmuint32_t)rpmlibVersion();
1124  he->tag = RPMTAG_RPMLIBVERSION;
1125  he->t = RPM_UINT32_TYPE;
1126  he->p.ui32p = &val;
1127  he->c = 1;
1128  xx = headerPut(h, he, 0);
1129  }
1130 
1131  he->tag = RPMTAG_BUILDHOST;
1132  he->t = RPM_STRING_TYPE;
1133  he->p.str = buildHost();
1134  he->c = 1;
1135  xx = headerPut(h, he, 0);
1136 
1137  he->tag = RPMTAG_BUILDTIME;
1138  he->t = RPM_UINT32_TYPE;
1139  he->p.ui32p = getBuildTime();
1140  he->c = 1;
1141  xx = headerPut(h, he, 0);
1142 
1143  return 0;
1144 }
1145 
1146 /*@unchecked@*/
1147 static rpmTag copyTags[] = {
1151  0
1152 };
1153 
1154 static rpmRC checkPackages(const char *pkgcheck)
1155 {
1156  int fail = rpmExpandNumeric("%{?_nonzero_exit_pkgcheck_terminate_build}");
1157  int xx;
1158 
1159  rpmlog(RPMLOG_NOTICE, _("Executing \"%s\":\n"), pkgcheck);
1160  /* XXX FIXME: use popen(3) through %(...) instead. */
1161  xx = system(pkgcheck);
1162  if (WEXITSTATUS(xx) == -1 || WEXITSTATUS(xx) == 127) {
1163  rpmlog(RPMLOG_ERR, _("Execution of \"%s\" failed.\n"), pkgcheck);
1164  if (fail) return 127;
1165  }
1166  if (WEXITSTATUS(xx) != 0) {
1167  rpmlog(RPMLOG_ERR, _("Package check \"%s\" failed.\n"), pkgcheck);
1168  if (fail) return RPMRC_FAIL;
1169  }
1170 
1171  return RPMRC_OK;
1172 }
1173 
1175 {
1176  HE_t he = (HE_t) memset(alloca(sizeof(*he)), 0, sizeof(*he));
1177  struct cpioSourceArchive_s csabuf;
1178  CSA_t csa = &csabuf;
1179  const char *errorString;
1180  Package pkg;
1181  rpmRC rc = RPMRC_OK; /* assume success */
1182  int xx;
1183  ARGV_t pkglist = NULL;
1184 
1185  for (pkg = spec->packages; pkg != NULL; pkg = pkg->next) {
1186  const char *fn;
1187 
1188  if (pkg->fileList == NULL)
1189  continue;
1190 
1191  if (spec->cookie) {
1192  he->tag = RPMTAG_COOKIE;
1193  he->t = RPM_STRING_TYPE;
1194  he->p.str = spec->cookie;
1195  he->c = 1;
1196  xx = headerPut(pkg->header, he, 0);
1197  }
1198 
1199  /* Copy changelog from src rpm */
1200  headerCopyTags(spec->packages->header, pkg->header, copyTags);
1201 
1202  /* Add rpmlib markers for tracking. */
1203  (void) rpmlibMarkers(pkg->header);
1204 
1205  he->tag = RPMTAG_OPTFLAGS;
1206  he->t = RPM_STRING_TYPE;
1207  he->p.str = rpmExpand("%{optflags}", NULL);
1208  he->c = 1;
1209  xx = headerPut(pkg->header, he, 0);
1210  he->p.ptr = _free(he->p.ptr);
1211 
1212 if (!(_rpmbuildFlags & 4)) {
1213  if (spec->sourcePkgId != NULL) {
1214  he->tag = RPMTAG_SOURCEPKGID;
1215  he->t = RPM_BIN_TYPE;
1216  he->p.ptr = spec->sourcePkgId;
1217  he->c = 16;
1218  xx = headerPut(pkg->header, he, 0);
1219  }
1220 }
1221 
1222  { const char *binFormat = rpmGetPath("%{_rpmfilename}", NULL);
1223  char *binRpm, *binDir;
1224  binRpm = headerSprintf(pkg->header, binFormat, NULL,
1225  rpmHeaderFormats, &errorString);
1226  binFormat = _free(binFormat);
1227  if (binRpm == NULL) {
1228  he->tag = RPMTAG_NVRA;
1229  xx = headerGet(pkg->header, he, 0);
1230  rpmlog(RPMLOG_ERR, _("Could not generate output "
1231  "filename for package %s: %s\n"), he->p.str, errorString);
1232  he->p.ptr = _free(he->p.ptr);
1233  rc = RPMRC_FAIL;
1234  goto exit;
1235  }
1236  fn = rpmGetPath("%{_rpmdir}/", binRpm, NULL);
1237  if ((binDir = strchr(binRpm, '/')) != NULL) {
1238  struct stat st;
1239  const char *dn;
1240  *binDir = '\0';
1241  dn = rpmGetPath("%{_rpmdir}/", binRpm, NULL);
1242  if (Stat(dn, &st) < 0) {
1243  switch(errno) {
1244  case ENOENT:
1245  if (rpmioMkpath(dn, 0755, -1, -1) == 0)
1246  /*@switchbreak@*/ break;
1247  /*@fallthrough@*/
1248  default:
1249  rpmlog(RPMLOG_ERR,_("cannot create %s: %s\n"),
1250  dn, strerror(errno));
1251  /*@switchbreak@*/ break;
1252  }
1253  }
1254  dn = _free(dn);
1255  }
1256  binRpm = _free(binRpm);
1257  }
1258 
1259  memset(csa, 0, sizeof(*csa));
1260  csa->cpioArchiveSize = 0;
1261  /*@-type@*/ /* LCL: function typedefs */
1262 /*@-onlytrans@*/
1263  csa->cpioFdIn = fdNew("init (packageBinaries)");
1264 /*@=onlytrans@*/
1265 /*@-assignexpose -newreftrans@*/
1266  csa->fi = rpmfiLink(pkg->fi, "packageBinaries");
1267 /*@=assignexpose =newreftrans@*/
1268 assert(csa->fi != NULL);
1269 
1270  rc = writeRPM(&pkg->header, NULL, fn,
1271  csa, spec->passPhrase, NULL, spec->dig);
1272 
1273 /*@-onlytrans@*/
1274  csa->fi->te = _free(csa->fi->te); /* XXX memory leak */
1275 /*@=onlytrans@*/
1276  csa->fi = rpmfiFree(csa->fi);
1277 /*@-nullpass -onlytrans -refcounttrans @*/
1278  csa->cpioFdIn = fdFree(csa->cpioFdIn, "init (packageBinaries)");
1279 /*@=nullpass =onlytrans =refcounttrans @*/
1280  /*@=type@*/
1281  if (rc == RPMRC_OK) {
1282  /* Do check each written package if enabled */
1283  char *pkgcheck = rpmExpand("%{?_build_pkgcheck} ", fn, NULL);
1284  if (pkgcheck[0] != ' ') {
1285  rc = checkPackages(pkgcheck);
1286  }
1287  pkgcheck = _free(pkgcheck);
1288  xx = argvAdd(&pkglist, fn);
1289  }
1290  fn = _free(fn);
1291  if (rc) {
1292  pkglist = argvFree(pkglist);
1293  goto exit;
1294  }
1295  }
1296 
1297  /* Now check the package set if enabled */
1298  if (pkglist != NULL) {
1299  char *pkgcheck_set = NULL;
1300  char *pkgs = NULL;
1301  size_t pkglen = 0;
1302  int i;
1303  for (i = 0; i < argvCount(pkglist); i++)
1304  pkglen += strlen(pkglist[i]) + 1;
1305  pkgs = xcalloc(1, pkglen);
1306  for (i = 0; i < argvCount(pkglist); i++) {
1307  if (i)
1308  strcat(pkgs, " ");
1309  strcat(pkgs, pkglist[i]);
1310  }
1311 
1312  pkgcheck_set = rpmExpand("%{?_build_pkgcheck_set} ", pkgs, NULL);
1313  if (pkgcheck_set[0] != ' ') { /* run only if _build_pkgcheck_set is defined */
1314  rc = checkPackages(pkgcheck_set);
1315  }
1316  pkgcheck_set = _free(pkgcheck_set);
1317  pkglist = argvFree(pkglist);
1318  pkgs = _free(pkgs);
1319  }
1320 
1321 exit:
1322 
1323  return rc;
1324 }
1325 
1327 {
1328  HE_t he = (HE_t) memset(alloca(sizeof(*he)), 0, sizeof(*he));
1329  struct cpioSourceArchive_s csabuf;
1330  CSA_t csa = &csabuf;
1331  rpmRC rc;
1332  int xx;
1333 #if defined(RPM_VENDOR_OPENPKG) || defined(RPM_VENDOR_FEDORA) || defined(RPM_VENDOR_MANDRIVA) || defined(RPM_VENDOR_ARK) /* backward-compat-rpmtag-sourcepackage */
1334  rpmuint32_t val;
1335 #endif
1336 
1337  /* Add rpmlib markers for tracking. */
1338  (void) rpmlibMarkers(spec->sourceHeader);
1339 
1340 #if defined(RPM_VENDOR_OPENPKG) || defined(RPM_VENDOR_FEDORA) || defined(RPM_VENDOR_MANDRIVA) || defined(RPM_VENDOR_ARK) /* backward-compat-rpmtag-sourcepackage */
1341  /* Mark package as a SRPM for backward compatibility with RPM < 4.4.6 */
1342  he->tag = RPMTAG_SOURCEPACKAGE;
1343  he->t = RPM_UINT32_TYPE;
1344  val = 1;
1345  he->p.ui32p = &val;
1346  he->c = 1;
1347  xx = headerPut(spec->sourceHeader, he, 0);
1348 #endif
1349 
1350  /* Add build scriptlet status/time (if any) to SRPM's. */
1351  { size_t ix; /* XXX coverity #1035951 */
1352  for (ix = 0; ix < RPMSCRIPT_MAX; ix++) {
1353  if (spec->sstates[ix] == 0)
1354  continue;
1355  if (spec->smetrics[ix] == 0)
1356  continue;
1357  break;
1358  }
1359  if (ix < RPMSCRIPT_MAX) {
1360  he->tag = RPMTAG_SCRIPTSTATES;
1361  he->t = RPM_UINT32_TYPE;
1362  he->p.ui32p = spec->sstates;
1363  he->c = RPMSCRIPT_MAX;
1364  xx = headerPut(spec->sourceHeader, he, 0);
1365  he->tag = RPMTAG_SCRIPTMETRICS;
1366  he->t = RPM_UINT32_TYPE;
1367  he->p.ui32p = spec->smetrics;
1368  he->c = RPMSCRIPT_MAX;
1369  xx = headerPut(spec->sourceHeader, he, 0);
1370  }
1371  }
1372 
1373  /* Add macros used during build to SRPM's. */
1374  { const char ** av = NULL;
1375  (void)rpmGetMacroEntries(NULL, NULL, 1, &av);
1376  if (av != NULL && av[0] != NULL) {
1377  he->tag = RPMTAG_BUILDMACROS;
1378  he->t = RPM_STRING_ARRAY_TYPE;
1379  he->p.argv = av;
1380  he->c = argvCount(av);
1381  xx = headerPut(spec->sourceHeader, he, 0);
1382  }
1383 /*@-nullstate@*/
1384  av = argvFree(av);
1385 /*@=nullstate@*/
1386  }
1387 
1388  spec->cookie = _free(spec->cookie);
1389 
1390  /* XXX this should be %_srpmdir */
1391  { const char *srcrpmdir = rpmGetPath("%{_srcrpmdir}/", NULL);
1392  const char *fn = rpmGetPath("%{_srcrpmdir}/", spec->sourceRpmName,NULL);
1393  const char *pkgcheck = rpmExpand("%{?_build_pkgcheck_srpm} ", fn, NULL);
1394 
1395  rc = rpmioMkpath(srcrpmdir, 0755, -1, -1);
1396 
1397  memset(csa, 0, sizeof(*csa));
1398  csa->cpioArchiveSize = 0;
1399  /*@-type@*/ /* LCL: function typedefs */
1400 /*@-onlytrans@*/
1401  csa->cpioFdIn = fdNew("init (packageSources)");
1402 /*@=onlytrans@*/
1403 /*@-assignexpose -newreftrans@*/
1404  csa->fi = rpmfiLink(spec->fi, "packageSources");
1405 /*@=assignexpose =newreftrans@*/
1406 #ifdef DYING
1407 assert(csa->fi != NULL);
1408 #else
1409  if (csa->fi == NULL) { /* XXX segfault avoidance */
1410  srcrpmdir = _free(srcrpmdir);
1411  fn = _free(fn);
1412  pkgcheck = _free(pkgcheck);
1413  return RPMRC_FAIL;
1414  }
1415 #endif
1416 
1417  spec->sourcePkgId = NULL;
1418  rc = writeRPM(&spec->sourceHeader, &spec->sourcePkgId, fn,
1419  csa, spec->passPhrase, &spec->cookie, spec->dig);
1420 
1421  /* Do check SRPM package if enabled */
1422  if (rc == RPMRC_OK && pkgcheck[0] != ' ') {
1423  rc = checkPackages(pkgcheck);
1424  }
1425 
1426 /*@-onlytrans@*/
1427  csa->fi->te = _free(csa->fi->te); /* XXX memory leak */
1428 /*@=onlytrans@*/
1429  csa->fi = rpmfiFree(csa->fi);
1430 /*@-nullpass -onlytrans -refcounttrans @*/
1431  csa->cpioFdIn = fdFree(csa->cpioFdIn, "init (packageSources)");
1432 /*@=nullpass =onlytrans =refcounttrans @*/
1433  /*@=type@*/
1434  srcrpmdir = _free(srcrpmdir);
1435  fn = _free(fn);
1436  pkgcheck = _free(pkgcheck);
1437  }
1438 
1439  rc = (rc ? RPMRC_FAIL : RPMRC_OK);
1440 
1441  return rc;
1442 }
const bson * b
Definition: bson.h:280
rpmTagType t
Definition: rpmtag.h:504
char * fileName
Definition: rpmspec.h:31
pgpDigParams pgpGetPubkey(pgpDig dig)
Return OpenPGP pubkey parameters.
Definition: rpmpgp.c:1397
const char * str
Definition: rpmtag.h:73
rpmTag tag
Definition: rpmtag.h:503
const char ** argv
Definition: rpmtag.h:75
int rpmAddSignature(Header sigh, const char *file, rpmSigTag sigTag, const char *passPhrase)
Generate signature(s) from a header+payload file, save in signature header.
Definition: signature.c:477
int headerIsEntry(Header h, rpmTag tag)
Check if tag is in header.
Definition: header.c:1439
const char * buildHost(void)
Return build hostname.
Definition: names.c:206
static int addFileToTag(Spec spec, const char *file, Header h, rpmTag tag)
Definition: pack.c:157
const char bson_timestamp_t * ts
Definition: bson.h:1004
const char * sourceRpmName
Definition: rpmspec.h:167
void headerMergeLegacySigs(Header h, const Header sigh)
Translate and merge legacy signature tags into header.
Definition: hdrNVR.c:242
static rpmTag copyTags[]
Definition: pack.c:1147
Package next
Definition: rpmspec.h:255
static void * fdGetFp(FD_t fd)
rpmiob fileList
Definition: rpmspec.h:253
Package newPackage(Spec spec)
Create and initialize package control structure.
Definition: spec.c:204
rpmRC rpmpkgWrite(const char *fn, FD_t fd, void *ptr, const char **msg)
Write item onto file descriptor.
Definition: pkgio.c:1692
const char * postInFile
Definition: rpmspec.h:230
int _rpmbuildFlags
Definition: poptBT.c:53
size_t Fwrite(const void *buf, size_t size, size_t nmemb, FD_t fd)
fwrite(3) clone.
Definition: rpmio.c:2434
char * xstrdup(const char *str)
Definition: rpmmalloc.c:321
rpmuint32_t * ui32p
Definition: rpmtag.h:70
FD_t Fopen(const char *path, const char *_fmode)
fopen(3) clone.
Definition: rpmio.c:2840
struct pgpDigParams_s * pgpDigParams
Definition: rpmiotypes.h:101
char * rpmGetPath(const char *path,...)
Return (malloc'ed) expanded, canonicalized, file path.
Definition: macro.c:3445
static int addFileToArrayTag(Spec spec, const char *file, Header h, rpmTag tag)
Definition: pack.c:188
Structure(s) used for file info tag sets.
int headerGet(Header h, HE_t he, unsigned int flags)
Retrieve extension or tag value from a header.
Definition: header.c:2231
int headerPut(Header h, HE_t he, unsigned int flags)
Add or append tag container to header.
Definition: header.c:2294
char * prog
Definition: rpmspec.h:35
The Header data structure.
int rpmioMkpath(const char *path, mode_t mode, uid_t uid, gid_t gid)
Insure that directories in path exist, creating as needed.
Definition: rpmio.c:3024
headerSprintfExtension rpmHeaderFormats
Table of query format extensions.
Definition: formats.c:305
static unsigned char nibble(char c)
Convert hex to binary nibble.
Definition: pack.c:628
#define VERSION
Definition: config.h:1306
int Stat(const char *path, struct stat *st)
stat(2) clone.
Definition: rpmrpc.c:1361
char * pgpArmorWrap(rpmuint8_t atype, const unsigned char *s, size_t ns)
Wrap a OpenPGP packets in ascii armor for transport.
Definition: rpmpgp.c:1749
int Fflush(FD_t fd)
fflush(3) clone.
Definition: rpmio.c:2923
int errno
Header sourceHeader
Definition: rpmspec.h:171
rpmfi rpmfiFree(rpmfi fi)
Destroy a file info set.
int headerDel(Header h, HE_t he, unsigned int flags)
Remove tag container from header.
Definition: header.c:2313
rpmiob rpmiobFree(rpmiob iob)
Destroy a I/O buffer instance.
static void rpmlog(int code, const char *fmt,...)
Definition: rpmlog.h:299
FD_t fdDup(int fdno)
Definition: rpmio.c:266
rpmiob rpmiobAppend(rpmiob iob, const char *s, size_t nl)
Append string to I/O buffer.
Definition: rpmiob.c:77
int Fseek(FD_t fd, _libio_off_t offset, int whence)
fseek(3) clone.
Definition: rpmio.c:2457
char * passPhrase
Definition: rpmspec.h:156
static void fdInitDigest(FD_t fd, pgpHashAlgo hashalgo, int _flags)
Attach digest to fd.
FD_t fdNew(const char *msg)
static int rpmlibMarkers(Header h)
Definition: pack.c:1094
char * headerSprintf(Header h, const char *fmt, headerTagTableEntry tags, headerSprintfExtension exts, errmsg_t *errmsg)
Return formatted output string from header tags.
Definition: hdrfmt.c:6730
DIGEST_CTX * digests
void * headerUnload(Header h, size_t *lenp)
headerUnload.
Definition: header.c:648
char * alloca()
Header header
Definition: rpmspec.h:217
unsigned int rpmuint32_t
Definition: rpmiotypes.h:28
rpmuint32_t rpmlibVendor(void)
Definition: rpmversion.c:21
struct _HE_s * HE_t
Definition: rpmtag.h:59
const char * Fstrerror(FD_t fd)
strerror(3) clone.
Definition: rpmio.c:2401
void * xcalloc(size_t nmemb, size_t size)
Definition: rpmmalloc.c:300
void * ptr
Definition: rpmtag.h:67
rpmRC packageSources(Spec spec)
Generate source package.
Definition: pack.c:1326
const char * cookie
Definition: rpmspec.h:159
int rpmGetMacroEntries(MacroContext mc, void *_mire, int used, const char ***avp)
Return macro entries as string array.
Definition: macro.c:321
FD_t fdFree(FD_t fd, const char *msg)
size_t rpmpkgSizeof(const char *fn, const void *ptr)
Return size of item in bytes.
Definition: pkgio.c:1646
unsigned char rpmuint8_t
Private int typedefs to avoid C99 portability issues.
Definition: rpmiotypes.h:26
struct rpmfi_s * rpmfi
File info tag sets from a header, so that a header can be discarded early.
Definition: rpmfi.h:83
int rpmTempFile(const char *prefix, const char **fnptr, void *fdptr)
Return file handle for a temporaray file.
Definition: signature.c:30
int argvCount(const ARGV_t argv)
Return no.
Definition: argv.c:71
enum evrFlags_e rpmsenseFlags
Definition: rpmevr.h:74
rpmTagData p
Definition: rpmtag.h:506
MacroContext macros
Definition: rpmspec.h:177
ARGV_t argvFree(ARGV_t argv)
Destroy an argv array.
Definition: argv.c:44
pgpDigParams pgpGetSignature(pgpDig dig)
Return OpenPGP signature parameters.
Definition: rpmpgp.c:1392
rpmuint32_t * getBuildTime(void)
Return build time stamp.
Definition: names.c:197
rpmuint32_t sstates[RPMSCRIPT_MAX]
Definition: rpmspec.h:182
static const char * file
Definition: parseFiles.c:20
static rpmiob addFileToTagAux(Spec spec, const char *file, rpmiob iob)
Definition: pack.c:120
#define fail(_err)
Definition: yarn.c:199
rpmRC rpmReadPackageFile(rpmts ts, FD_t fd, const char *fn, Header *hdrp)
Return package header from file handle, verifying digests/signatures.
Definition: package.c:114
struct TriggerFileEntry * triggerFiles
Definition: rpmspec.h:248
Digest private data.
Definition: digest.c:130
rpmuint32_t smetrics[RPMSCRIPT_MAX]
Definition: rpmspec.h:183
static rpmRC checkPackages(const char *pkgcheck)
Definition: pack.c:1154
The FD_t File Handle data structure.
static void fdFiniDigest(FD_t fd, pgpHashAlgo hashalgo, void *datap, size_t *lenp, int asAscii)
struct pgpDig_s * pgpDig
Definition: rpmiotypes.h:97
int argvAdd(ARGV_t *argvp, ARGstr_t val)
Add a string to an argv array.
Definition: argv.c:199
rpmTagCount c
Definition: rpmtag.h:507
Generate and verify rpm package signatures.
The structure used to store values parsed from a spec file.
Definition: rpmspec.h:113
Header headerFree(Header h)
Dereference a header instance.
rpmuint32_t cpioArchiveSize
Definition: buildio.h:16
char * rpmExpand(const char *arg,...)
Return (malloc'ed) concatenated macro expansion(s).
Definition: macro.c:3252
Spec freeSpec(Spec spec)
Destroy a spec file control structure.
static rpmRC cpio_copy(FD_t fdo, CSA_t csa)
Definition: pack.c:95
const char * preInFile
Definition: rpmspec.h:228
size_t Fread(void *buf, size_t size, size_t nmemb, FD_t fd)
fread(3) clone.
Definition: rpmio.c:2412
struct TriggerFileEntry * next
Definition: rpmspec.h:37
rpmuint8_t * ui8p
Definition: rpmtag.h:68
char * script
Definition: rpmspec.h:33
rpmuint32_t rpmlibVersion(void)
Definition: rpmversion.c:11
int Fclose(FD_t fd)
fclose(3) clone.
Definition: rpmio.c:2534
char * iosmStrerror(int rc)
Return formatted error message on payload handling failure.
Definition: iosm.c:2769
rpmiob rpmiobNew(size_t len)
Create an I/O buffer.
Definition: rpmiob.c:44
int fsmTeardown(void *_fsm)
Clean file state machine.
Definition: fsm.c:751
Header headerLink(Header h)
Reference a header instance.
Routines to read and write packages.
Spec newSpec(void)
Create and initialize Spec structure.
Definition: spec.c:642
rpmuint32_t rpmlibTimestamp(void)
Definition: rpmversion.c:16
const char * postUnFile
Definition: rpmspec.h:234
size_t ndigests
enum rpmRC_e rpmRC
RPM return codes.
int Ferror(FD_t fd)
ferror(3) clone.
Definition: rpmio.c:2951
char * rpmiobStr(rpmiob iob)
Return I/O buffer (as string).
Definition: rpmiob.c:112
Package packages
Definition: rpmspec.h:204
Definition: rpmtag.h:502
const char const int i
Definition: bson.h:778
void headerCopyTags(Header headerFrom, Header headerTo, rpmTag *tagstocopy)
Duplicate tag values from one header into another.
Definition: header.c:2211
This is the only module users of librpmbuild should need to include.
rpmfi rpmfiLink(rpmfi fi, const char *msg)
Reference a file info set instance.
rpmts rpmtsFree(rpmts ts)
Destroy transaction set, closing the database as well.
rpmRC packageBinaries(Spec spec)
Generate binary package(s).
Definition: pack.c:1174
rpmts rpmtsCreate(void)
Create an empty transaction set.
Definition: rpmts.c:1470
Methods to handle package elements.
#define SEEK_SET
Definition: system.h:226
char * stpcpy(char *dest, const char *src)
struct rpmts_s * rpmts
The RPM Transaction Set.
Definition: rpmtypes.h:14
static void * _free(const void *p)
Wrapper to free(3), hides const compilation noise, permit NULL, return NULL.
Definition: rpmiotypes.h:756
struct rpmiob_s * rpmiob
Definition: rpmiotypes.h:60
Header headerReload(Header h, rpmTag tag)
Convert header to on-disk representation, and then reload.
Definition: header.c:1314
int headerNEVRA(Header h, const char **np, const char **ep, const char **vp, const char **rp, const char **ap)
Return name, epoch, version, release, arch strings from header.
Definition: hdrNVR.c:162
rpmfi fi
Definition: filetriggers.h:15
FD_t Fdopen(FD_t ofd, const char *fmode)
Definition: rpmio.c:2725
File state machine to handle a payload within an rpm package.
rpmRC processScriptFiles(Spec spec, Package pkg)
Append files (if any) to scriptlet tags.
Definition: pack.c:214
int fsmSetup(void *_fsm, iosmFileStage goal, const char *afmt, const void *_ts, const void *_fi, FD_t cfd, unsigned int *archiveSize, const char **failedFile)
Load external data into file state machine.
Definition: fsm.c:627
rpmRC writeRPM(Header *hdrp, unsigned char **pkgidp, const char *fn, CSA_t csa, char *passPhrase, const char **cookie, void *_dig)
Write rpm package to file.
Definition: pack.c:640
rpmfi fi
Definition: rpmspec.h:173
const char * verifyFile
Definition: rpmspec.h:240
int expandMacros(void *spec, MacroContext mc, char *sbuf, size_t slen)
Expand macro into buffer.
Definition: macro.c:2751
int Fileno(FD_t fd)
fileno(3) clone.
Definition: rpmio.c:2998
#define _(Text)
Definition: system.h:29
The structure used to store values for a package.
Definition: rpmspec.h:214
const char * preUnFile
Definition: rpmspec.h:232
rpmRC rpmpkgRead(const char *fn, FD_t fd, void *ptr, const char **msg)
Read item from file descriptor.
Definition: pkgio.c:1674
ARGstr_t * ARGV_t
Definition: argv.h:12
static rpmRC cpio_doio(FD_t fdo, Header h, CSA_t csa, const char *payload_format, const char *fmodeMacro)
Definition: pack.c:40
rpmfi fi
Definition: rpmspec.h:221
enum rpmTag_e rpmTag
Definition: rpmtag.h:470
Header headerNew(void)
Create new (empty) header instance.
Definition: header.c:180
void providePackageNVR(Header h)
Retrofit an explicit Provides: N = E:V-R dependency into package headers.
Definition: pack.c:454
const char * postTransFile
Definition: rpmspec.h:238
int rpmExpandNumeric(const char *arg)
Return macro expansion as a numeric value.
Definition: macro.c:3326
void * dig
Definition: rpmspec.h:202
DIGEST_CTX rpmDigestDup(DIGEST_CTX octx)
Duplicate a digest context.
Definition: digest.c:212
const char * preTransFile
Definition: rpmspec.h:236
unsigned char * sourcePkgId
Definition: rpmspec.h:169
int pgpExportSignature(pgpDig dig, DIGEST_CTX ctx)
Definition: rpmpgp.c:1365
const char * sanityCheckFile
Definition: rpmspec.h:242
int rpmlibNeedsFeature(Header h, const char *feature, const char *featureEVR)
Add rpmlib feature dependency.
Definition: reqprov.c:212
unsigned int append
Definition: rpmtag.h:511
int Unlink(const char *path)
unlink(2) clone.
Definition: rpmrpc.c:397