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