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 = (passPhrase && passPhrase[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 
863  if (addsig) {
864  rpmlog(RPMLOG_NOTICE, _("Generating signature: %d\n"), sigtag);
865  (void) rpmAddSignature(sigh, sigtarget, sigtag, passPhrase);
866  }
867  else if (dig && dig->sig && dig->siglen > 0) {
868  he->tag = (rpmTag) RPMSIGTAG_DSA; /* XXX DSA assumed */
869  he->t = RPM_BIN_TYPE;
870  he->p.ptr = (void *) dig->sig;
871  he->c = dig->siglen;
872  xx = headerPut(sigh, he, 0);
873  dig->sig = _free(dig->sig); /* XXX lazily instead? */
874  dig->siglen = 0;
875  }
876 
877  if (SHA1) {
878  he->tag = (rpmTag) RPMSIGTAG_SHA1;
879  he->t = RPM_STRING_TYPE;
880  he->p.str = SHA1;
881  he->c = 1;
882  xx = headerPut(sigh, he, 0);
883  SHA1 = _free(SHA1);
884  }
885 
886  { rpmuint32_t payloadSize = csa->cpioArchiveSize;
888  he->t = RPM_UINT32_TYPE;
889  he->p.ui32p = &payloadSize;
890  he->c = 1;
891  xx = headerPut(sigh, he, 0);
892  }
893 
894  /* Reallocate the signature header into one contiguous region. */
896  if (sigh == NULL) { /* XXX can't happen */
897  rpmlog(RPMLOG_ERR, _("Unable to reload signature header.\n"));
898  rc = RPMRC_FAIL;
899  goto exit;
900  }
901 
902  /* Pad the signature header to put the metadata header at known offset. */
903  { size_t slen = 0;
904  void * uh = headerUnload(sigh, &slen);
905  static const size_t align = 1024;
906  size_t nb = align - 96 - 16 - 16;
907  rpmuint8_t * b;
908 
909  uh = _free(uh);
910 assert(slen < nb);
911  nb -= slen;
912  b = memset(alloca(nb), 0, nb);
913  he->tag = (rpmTag) RPMSIGTAG_PADDING;
914  he->t = RPM_BIN_TYPE;
915  he->p.ui8p = b;
916  he->c = nb;
917  xx = headerPut(sigh, he, 0);
919 assert(sigh != NULL);
920  }
921 
922  /* Open the output file */
923  fd = Fopen(fn, "w.fdio");
924  if (fd == NULL || Ferror(fd)) {
925  rpmlog(RPMLOG_ERR, _("Could not open %s: %s\n"),
926  fn, Fstrerror(fd));
927  rc = RPMRC_FAIL;
928  goto exit;
929  }
930 
931  /* Write the lead section into the package. */
932  { const char item[] = "Lead";
933  size_t nl = rpmpkgSizeof(item, NULL);
934 
935  msg = NULL;
936  if (nl == 0)
937  rc = RPMRC_FAIL;
938  else {
939  void * l = memset(alloca(nl), 0, nl);
940  const char *N, *V, *R;
941  (void) headerNEVRA(h, &N, NULL, &V, &R, NULL);
942  sprintf(buf, "%s-%s-%s", N, V, R);
943  N = _free(N);
944  V = _free(V);
945  R = _free(R);
946  msg = buf;
947  rc = rpmpkgWrite(item, fd, l, &msg);
948  }
949 
950  if (rc != RPMRC_OK) {
951  rpmlog(RPMLOG_ERR, _("Unable to write package: %s\n"),
952  Fstrerror(fd));
953  rc = RPMRC_FAIL;
954  goto exit;
955  }
956  }
957 
958  /* Write the signature section into the package. */
959  { const char item[] = "Signature";
960 
961  msg = NULL;
962  rc = rpmpkgWrite(item, fd, sigh, &msg);
963  if (rc != RPMRC_OK) {
964  rpmlog(RPMLOG_ERR, "%s: %s: %s\n", fn, item,
965  (msg && *msg ? msg : "write failed\n"));
966  msg = _free(msg);
967  rc = RPMRC_FAIL;
968  goto exit;
969  }
970  msg = _free(msg);
971  }
972 
973  /* Append the header and archive */
974  ifd = Fopen(sigtarget, "r.fdio");
975  if (ifd == NULL || Ferror(ifd)) {
976  rpmlog(RPMLOG_ERR, _("Unable to open sigtarget %s: %s\n"),
977  sigtarget, Fstrerror(ifd));
978  rc = RPMRC_FAIL;
979  goto exit;
980  }
981 
982  /* Add signatures to header, and write header into the package. */
983  { const char item[] = "Header";
984  Header nh = NULL;
985 
986  msg = NULL;
987  rc = rpmpkgRead(item, ifd, &nh, &msg);
988  if (rc != RPMRC_OK) {
989  rpmlog(RPMLOG_ERR, "%s: %s: %s\n", sigtarget, item,
990  (msg && *msg ? msg : "read failed\n"));
991  msg = _free(msg);
992  rc = RPMRC_FAIL;
993  goto exit;
994  }
995  msg = _free(msg);
996 
997 #ifdef NOTYET
998  (void) headerMergeLegacySigs(nh, sigh);
999 #endif
1000 
1001  msg = NULL;
1002  rc = rpmpkgWrite(item, fd, nh, &msg);
1003  (void)headerFree(nh);
1004  nh = NULL;
1005  if (rc != RPMRC_OK) {
1006  rpmlog(RPMLOG_ERR, "%s: %s: %s\n", fn, item,
1007  (msg && *msg ? msg : "write failed\n"));
1008  msg = _free(msg);
1009  rc = RPMRC_FAIL;
1010  goto exit;
1011  }
1012  msg = _free(msg);
1013  }
1014 
1015  /* Write the payload into the package. */
1016  while ((nbr = Fread(buf, sizeof(buf[0]), sizeof(buf), ifd)) > 0) {
1017  if (Ferror(ifd)) {
1018  rpmlog(RPMLOG_ERR, _("Unable to read payload from %s: %s\n"),
1019  sigtarget, Fstrerror(ifd));
1020  rc = RPMRC_FAIL;
1021  goto exit;
1022  }
1023  nbw = (int)Fwrite(buf, sizeof(buf[0]), nbr, fd);
1024  if (nbr != nbw || Ferror(fd)) {
1025  rpmlog(RPMLOG_ERR, _("Unable to write payload to %s: %s\n"),
1026  fn, Fstrerror(fd));
1027  rc = RPMRC_FAIL;
1028  goto exit;
1029  }
1030  }
1031  rc = RPMRC_OK;
1032 
1033 exit:
1034  SHA1 = _free(SHA1);
1035  (void)headerFree(h);
1036  h = NULL;
1037 
1038  /* XXX Fish the pkgid out of the signature header. */
1039  if (sigh != NULL && pkgidp != NULL) {
1040  he->tag = (rpmTag) RPMSIGTAG_MD5;
1041  xx = headerGet(sigh, he, 0);
1042  if (he->t == RPM_BIN_TYPE && he->p.ptr != NULL && he->c == 16)
1043  *pkgidp = he->p.ui8p; /* XXX memory leak */
1044  }
1045 
1046  (void)headerFree(sigh);
1047  sigh = NULL;
1048  if (ifd) {
1049  (void) Fclose(ifd);
1050  ifd = NULL;
1051  }
1052  if (fd) {
1053  (void) Fclose(fd);
1054  fd = NULL;
1055  }
1056  if (sigtarget) {
1057  (void) Unlink(sigtarget);
1058  sigtarget = _free(sigtarget);
1059  }
1060 
1061  if (rc == RPMRC_OK)
1062  rpmlog(RPMLOG_NOTICE, _("Wrote: %s\n"), fn);
1063  else
1064  (void) Unlink(fn);
1065 
1066  return rc;
1067 }
1068 
1069 static int rpmlibMarkers(Header h)
1070  /*@modifies h @*/
1071 {
1072  HE_t he = (HE_t) memset(alloca(sizeof(*he)), 0, sizeof(*he));
1073  rpmuint32_t val;
1074  int xx;
1075 
1076  he->tag = RPMTAG_RPMVERSION;
1077  he->t = RPM_STRING_TYPE;
1078  he->p.str = xstrdup(VERSION);
1079  he->c = 1;
1080  xx = headerPut(h, he, 0);
1081  he->p.ptr = _free(he->p.ptr);
1082 
1083  if (!(_rpmbuildFlags & 4)) {
1084  val = (rpmuint32_t)rpmlibTimestamp();
1086  he->t = RPM_UINT32_TYPE;
1087  he->p.ui32p = &val;
1088  he->c = 1;
1089  xx = headerPut(h, he, 0);
1090 
1091  val = (rpmuint32_t)rpmlibVendor();
1092  he->tag = RPMTAG_RPMLIBVENDOR;
1093  he->t = RPM_UINT32_TYPE;
1094  he->p.ui32p = &val;
1095  he->c = 1;
1096  xx = headerPut(h, he, 0);
1097 
1098  val = (rpmuint32_t)rpmlibVersion();
1099  he->tag = RPMTAG_RPMLIBVERSION;
1100  he->t = RPM_UINT32_TYPE;
1101  he->p.ui32p = &val;
1102  he->c = 1;
1103  xx = headerPut(h, he, 0);
1104  }
1105 
1106  he->tag = RPMTAG_BUILDHOST;
1107  he->t = RPM_STRING_TYPE;
1108  he->p.str = buildHost();
1109  he->c = 1;
1110  xx = headerPut(h, he, 0);
1111 
1112  he->tag = RPMTAG_BUILDTIME;
1113  he->t = RPM_UINT32_TYPE;
1114  he->p.ui32p = getBuildTime();
1115  he->c = 1;
1116  xx = headerPut(h, he, 0);
1117 
1118  return 0;
1119 }
1120 
1121 /*@unchecked@*/
1122 static rpmTag copyTags[] = {
1126  0
1127 };
1128 
1129 static rpmRC checkPackages(const char *pkgcheck)
1130 {
1131  int fail = rpmExpandNumeric("%{?_nonzero_exit_pkgcheck_terminate_build}");
1132  int xx;
1133 
1134  rpmlog(RPMLOG_NOTICE, _("Executing \"%s\":\n"), pkgcheck);
1135  /* XXX FIXME: use popen(3) through %(...) instead. */
1136  xx = system(pkgcheck);
1137  if (WEXITSTATUS(xx) == -1 || WEXITSTATUS(xx) == 127) {
1138  rpmlog(RPMLOG_ERR, _("Execution of \"%s\" failed.\n"), pkgcheck);
1139  if (fail) return 127;
1140  }
1141  if (WEXITSTATUS(xx) != 0) {
1142  rpmlog(RPMLOG_ERR, _("Package check \"%s\" failed.\n"), pkgcheck);
1143  if (fail) return RPMRC_FAIL;
1144  }
1145 
1146  return RPMRC_OK;
1147 }
1148 
1150 {
1151  HE_t he = (HE_t) memset(alloca(sizeof(*he)), 0, sizeof(*he));
1152  struct cpioSourceArchive_s csabuf;
1153  CSA_t csa = &csabuf;
1154  const char *errorString;
1155  Package pkg;
1156  rpmRC rc = RPMRC_OK; /* assume success */
1157  int xx;
1158  ARGV_t pkglist = NULL;
1159 
1160  for (pkg = spec->packages; pkg != NULL; pkg = pkg->next) {
1161  const char *fn;
1162 
1163  if (pkg->fileList == NULL)
1164  continue;
1165 
1166  if (spec->cookie) {
1167  he->tag = RPMTAG_COOKIE;
1168  he->t = RPM_STRING_TYPE;
1169  he->p.str = spec->cookie;
1170  he->c = 1;
1171  xx = headerPut(pkg->header, he, 0);
1172  }
1173 
1174  /* Copy changelog from src rpm */
1175  headerCopyTags(spec->packages->header, pkg->header, copyTags);
1176 
1177  /* Add rpmlib markers for tracking. */
1178  (void) rpmlibMarkers(pkg->header);
1179 
1180  he->tag = RPMTAG_OPTFLAGS;
1181  he->t = RPM_STRING_TYPE;
1182  he->p.str = rpmExpand("%{optflags}", NULL);
1183  he->c = 1;
1184  xx = headerPut(pkg->header, he, 0);
1185  he->p.ptr = _free(he->p.ptr);
1186 
1187 if (!(_rpmbuildFlags & 4)) {
1188  if (spec->sourcePkgId != NULL) {
1189  he->tag = RPMTAG_SOURCEPKGID;
1190  he->t = RPM_BIN_TYPE;
1191  he->p.ptr = spec->sourcePkgId;
1192  he->c = 16;
1193  xx = headerPut(pkg->header, he, 0);
1194  }
1195 }
1196 
1197  { const char *binFormat = rpmGetPath("%{_rpmfilename}", NULL);
1198  char *binRpm, *binDir;
1199  binRpm = headerSprintf(pkg->header, binFormat, NULL,
1200  rpmHeaderFormats, &errorString);
1201  binFormat = _free(binFormat);
1202  if (binRpm == NULL) {
1203  he->tag = RPMTAG_NVRA;
1204  xx = headerGet(pkg->header, he, 0);
1205  rpmlog(RPMLOG_ERR, _("Could not generate output "
1206  "filename for package %s: %s\n"), he->p.str, errorString);
1207  he->p.ptr = _free(he->p.ptr);
1208  rc = RPMRC_FAIL;
1209  goto exit;
1210  }
1211  fn = rpmGetPath("%{_rpmdir}/", binRpm, NULL);
1212  if ((binDir = strchr(binRpm, '/')) != NULL) {
1213  struct stat st;
1214  const char *dn;
1215  *binDir = '\0';
1216  dn = rpmGetPath("%{_rpmdir}/", binRpm, NULL);
1217  if (Stat(dn, &st) < 0) {
1218  switch(errno) {
1219  case ENOENT:
1220  if (rpmioMkpath(dn, 0755, -1, -1) == 0)
1221  /*@switchbreak@*/ break;
1222  /*@fallthrough@*/
1223  default:
1224  rpmlog(RPMLOG_ERR,_("cannot create %s: %s\n"),
1225  dn, strerror(errno));
1226  /*@switchbreak@*/ break;
1227  }
1228  }
1229  dn = _free(dn);
1230  }
1231  binRpm = _free(binRpm);
1232  }
1233 
1234  memset(csa, 0, sizeof(*csa));
1235  csa->cpioArchiveSize = 0;
1236  /*@-type@*/ /* LCL: function typedefs */
1237 /*@-onlytrans@*/
1238  csa->cpioFdIn = fdNew("init (packageBinaries)");
1239 /*@=onlytrans@*/
1240 /*@-assignexpose -newreftrans@*/
1241  csa->fi = rpmfiLink(pkg->fi, "packageBinaries");
1242 /*@=assignexpose =newreftrans@*/
1243 assert(csa->fi != NULL);
1244 
1245  rc = writeRPM(&pkg->header, NULL, fn,
1246  csa, spec->passPhrase, NULL, spec->dig);
1247 
1248 /*@-onlytrans@*/
1249  csa->fi->te = _free(csa->fi->te); /* XXX memory leak */
1250 /*@=onlytrans@*/
1251  csa->fi = rpmfiFree(csa->fi);
1252 /*@-nullpass -onlytrans -refcounttrans @*/
1253  csa->cpioFdIn = fdFree(csa->cpioFdIn, "init (packageBinaries)");
1254 /*@=nullpass =onlytrans =refcounttrans @*/
1255  /*@=type@*/
1256  if (rc == RPMRC_OK) {
1257  /* Do check each written package if enabled */
1258  char *pkgcheck = rpmExpand("%{?_build_pkgcheck} ", fn, NULL);
1259  if (pkgcheck[0] != ' ') {
1260  rc = checkPackages(pkgcheck);
1261  }
1262  pkgcheck = _free(pkgcheck);
1263  xx = argvAdd(&pkglist, fn);
1264  }
1265  fn = _free(fn);
1266  if (rc) {
1267  pkglist = argvFree(pkglist);
1268  goto exit;
1269  }
1270  }
1271 
1272  /* Now check the package set if enabled */
1273  if (pkglist != NULL) {
1274  char *pkgcheck_set = NULL;
1275  char *pkgs = NULL;
1276  size_t pkglen = 0;
1277  int i;
1278  for (i = 0; i < argvCount(pkglist); i++)
1279  pkglen += strlen(pkglist[i]) + 1;
1280  pkgs = xcalloc(1, pkglen);
1281  for (i = 0; i < argvCount(pkglist); i++) {
1282  if (i)
1283  strcat(pkgs, " ");
1284  strcat(pkgs, pkglist[i]);
1285  }
1286 
1287  pkgcheck_set = rpmExpand("%{?_build_pkgcheck_set} ", pkgs, NULL);
1288  if (pkgcheck_set[0] != ' ') { /* run only if _build_pkgcheck_set is defined */
1289  rc = checkPackages(pkgcheck_set);
1290  }
1291  pkgcheck_set = _free(pkgcheck_set);
1292  pkglist = argvFree(pkglist);
1293  pkgs = _free(pkgs);
1294  }
1295 
1296 exit:
1297 
1298  return rc;
1299 }
1300 
1302 {
1303  HE_t he = (HE_t) memset(alloca(sizeof(*he)), 0, sizeof(*he));
1304  struct cpioSourceArchive_s csabuf;
1305  CSA_t csa = &csabuf;
1306  rpmRC rc;
1307  int xx;
1308 #if defined(RPM_VENDOR_OPENPKG) || defined(RPM_VENDOR_FEDORA) || defined(RPM_VENDOR_MANDRIVA) || defined(RPM_VENDOR_ARK) /* backward-compat-rpmtag-sourcepackage */
1309  rpmuint32_t val;
1310 #endif
1311 
1312  /* Add rpmlib markers for tracking. */
1313  (void) rpmlibMarkers(spec->sourceHeader);
1314 
1315 #if defined(RPM_VENDOR_OPENPKG) || defined(RPM_VENDOR_FEDORA) || defined(RPM_VENDOR_MANDRIVA) || defined(RPM_VENDOR_ARK) /* backward-compat-rpmtag-sourcepackage */
1316  /* Mark package as a SRPM for backward compatibility with RPM < 4.4.6 */
1317  he->tag = RPMTAG_SOURCEPACKAGE;
1318  he->t = RPM_UINT32_TYPE;
1319  val = 1;
1320  he->p.ui32p = &val;
1321  he->c = 1;
1322  xx = headerPut(spec->sourceHeader, he, 0);
1323 #endif
1324 
1325  /* Add build scriptlet status/time (if any) to SRPM's. */
1326  { int ix;
1327  for (ix = 0; ix < RPMSCRIPT_MAX; ix++) {
1328  if (spec->sstates[ix] == 0)
1329  continue;
1330  if (spec->smetrics[ix] == 0)
1331  continue;
1332  break;
1333  }
1334  if (ix >= 0 && ix < RPMSCRIPT_MAX) {
1335  he->tag = RPMTAG_SCRIPTSTATES;
1336  he->t = RPM_UINT32_TYPE;
1337  he->p.ui32p = spec->sstates;
1338  he->c = RPMSCRIPT_MAX;
1339  xx = headerPut(spec->sourceHeader, he, 0);
1340  he->tag = RPMTAG_SCRIPTMETRICS;
1341  he->t = RPM_UINT32_TYPE;
1342  he->p.ui32p = spec->smetrics;
1343  he->c = RPMSCRIPT_MAX;
1344  xx = headerPut(spec->sourceHeader, he, 0);
1345  }
1346  }
1347 
1348  /* Add macros used during build to SRPM's. */
1349  { const char ** av = NULL;
1350  (void)rpmGetMacroEntries(NULL, NULL, 1, &av);
1351  if (av != NULL && av[0] != NULL) {
1352  he->tag = RPMTAG_BUILDMACROS;
1353  he->t = RPM_STRING_ARRAY_TYPE;
1354  he->p.argv = av;
1355  he->c = argvCount(av);
1356  xx = headerPut(spec->sourceHeader, he, 0);
1357  }
1358 /*@-nullstate@*/
1359  av = argvFree(av);
1360 /*@=nullstate@*/
1361  }
1362 
1363  spec->cookie = _free(spec->cookie);
1364 
1365  /* XXX this should be %_srpmdir */
1366  { const char *srcrpmdir = rpmGetPath("%{_srcrpmdir}/", NULL);
1367  const char *fn = rpmGetPath("%{_srcrpmdir}/", spec->sourceRpmName,NULL);
1368  const char *pkgcheck = rpmExpand("%{?_build_pkgcheck_srpm} ", fn, NULL);
1369 
1370  rc = rpmioMkpath(srcrpmdir, 0755, -1, -1);
1371 
1372  memset(csa, 0, sizeof(*csa));
1373  csa->cpioArchiveSize = 0;
1374  /*@-type@*/ /* LCL: function typedefs */
1375 /*@-onlytrans@*/
1376  csa->cpioFdIn = fdNew("init (packageSources)");
1377 /*@=onlytrans@*/
1378 /*@-assignexpose -newreftrans@*/
1379  csa->fi = rpmfiLink(spec->fi, "packageSources");
1380 /*@=assignexpose =newreftrans@*/
1381 #ifdef DYING
1382 assert(csa->fi != NULL);
1383 #else
1384  if (csa->fi == NULL) /* XXX segfault avoidance */
1385  return RPMRC_FAIL;
1386 #endif
1387 
1388  spec->sourcePkgId = NULL;
1389  rc = writeRPM(&spec->sourceHeader, &spec->sourcePkgId, fn,
1390  csa, spec->passPhrase, &spec->cookie, spec->dig);
1391 
1392  /* Do check SRPM package if enabled */
1393  if (rc == RPMRC_OK && pkgcheck[0] != ' ') {
1394  rc = checkPackages(pkgcheck);
1395  }
1396 
1397 /*@-onlytrans@*/
1398  csa->fi->te = _free(csa->fi->te); /* XXX memory leak */
1399 /*@=onlytrans@*/
1400  csa->fi = rpmfiFree(csa->fi);
1401 /*@-nullpass -onlytrans -refcounttrans @*/
1402  csa->cpioFdIn = fdFree(csa->cpioFdIn, "init (packageSources)");
1403 /*@=nullpass =onlytrans =refcounttrans @*/
1404  /*@=type@*/
1405  srcrpmdir = _free(srcrpmdir);
1406  fn = _free(fn);
1407  pkgcheck = _free(pkgcheck);
1408  }
1409 
1410  rc = (rc ? RPMRC_FAIL : RPMRC_OK);
1411 
1412  return rc;
1413 }
rpmTagType t
Definition: rpmtag.h:505
char * fileName
Definition: rpmspec.h:26
const char * str
Definition: rpmtag.h:72
rpmTag tag
Definition: rpmtag.h:504
const char ** argv
Definition: rpmtag.h:74
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:433
int headerIsEntry(Header h, rpmTag tag)
Check if tag is in header.
Definition: header.c:1431
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:155
const char * sourceRpmName
Definition: rpmspec.h:162
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:1122
Package next
Definition: rpmspec.h:248
static void * fdGetFp(FD_t fd)
rpmiob fileList
Definition: rpmspec.h:246
Package newPackage(Spec spec)
Create and initialize package control structure.
Definition: spec.c:208
rpmRC rpmpkgWrite(const char *fn, FD_t fd, void *ptr, const char **msg)
Write item onto file descriptor.
Definition: pkgio.c:1665
const char * postInFile
Definition: rpmspec.h:223
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:322
rpmuint32_t * ui32p
Definition: rpmtag.h:69
FD_t Fopen(const char *path, const char *_fmode)
fopen(3) clone.
Definition: rpmio.c:2833
struct pgpDigParams_s * pgpDigParams
Definition: rpmiotypes.h:87
char * rpmGetPath(const char *path,...)
Return (malloc&#39;ed) expanded, canonicalized, file path.
Definition: macro.c:3310
static int addFileToArrayTag(Spec spec, const char *file, Header h, rpmTag tag)
Definition: pack.c:186
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:2222
int headerPut(Header h, HE_t he, unsigned int flags)
Add or append tag container to header.
Definition: header.c:2285
char * prog
Definition: rpmspec.h:30
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:3017
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:622
#define VERSION
Definition: config.h:1270
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:1574
int Fflush(FD_t fd)
fflush(3) clone.
Definition: rpmio.c:2916
int errno
Header sourceHeader
Definition: rpmspec.h:166
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:2304
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:264
rpmiob rpmiobAppend(rpmiob iob, const char *s, size_t nl)
Append string to I/O buffer.
Definition: rpmiob.c:78
int Fseek(FD_t fd, _libio_off_t offset, int whence)
fseek(3) clone.
Definition: rpmio.c:2457
char * passPhrase
Definition: rpmspec.h:151
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:1069
char * headerSprintf(Header h, const char *fmt, headerTagTableEntry tags, headerSprintfExtension exts, errmsg_t *errmsg)
Return formatted output string from header tags.
Definition: hdrfmt.c:6700
DIGEST_CTX * digests
void * headerUnload(Header h, size_t *lenp)
headerUnload.
Definition: header.c:648
char * alloca()
Header header
Definition: rpmspec.h:210
unsigned int rpmuint32_t
Definition: rpmiotypes.h:25
rpmuint32_t rpmlibVendor(void)
Definition: rpmversion.c:21
struct _HE_s * HE_t
Definition: rpmtag.h:58
const char * Fstrerror(FD_t fd)
strerror(3) clone.
Definition: rpmio.c:2401
void * xcalloc(size_t nmemb, size_t size)
Definition: rpmmalloc.c:301
void * ptr
Definition: rpmtag.h:66
rpmRC packageSources(Spec spec)
Generate source package.
Definition: pack.c:1301
const char * cookie
Definition: rpmspec.h:154
int rpmGetMacroEntries(MacroContext mc, void *_mire, int used, const char ***avp)
Return macro entries as string array.
Definition: macro.c:319
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:1619
unsigned char rpmuint8_t
Private int typedefs to avoid C99 portability issues.
Definition: rpmiotypes.h:23
struct rpmfi_s * rpmfi
File info tag sets from a header, so that a header can be discarded early.
Definition: rpmfi.h:78
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:72
rpmTagData p
Definition: rpmtag.h:507
MacroContext macros
Definition: rpmspec.h:172
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:1227
rpmuint32_t * getBuildTime(void)
Return build time stamp.
Definition: names.c:197
rpmuint32_t sstates[RPMSCRIPT_MAX]
Definition: rpmspec.h:177
static const char * file
Definition: parseFiles.c:20
static rpmiob addFileToTagAux(Spec spec, const char *file, rpmiob iob)
Definition: pack.c:118
rpmRC rpmReadPackageFile(rpmts ts, FD_t fd, const char *fn, Header *hdrp)
Return package header from file handle, verifying digests/signatures.
Definition: package.c:428
struct TriggerFileEntry * triggerFiles
Definition: rpmspec.h:241
Digest private data.
Definition: digest.c:127
rpmuint32_t smetrics[RPMSCRIPT_MAX]
Definition: rpmspec.h:178
static rpmRC checkPackages(const char *pkgcheck)
Definition: pack.c:1129
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:83
int argvAdd(ARGV_t *argvp, ARGstr_t val)
Add a string to an argv array.
Definition: argv.c:199
rpmTagCount c
Definition: rpmtag.h:508
Generate and verify rpm package signatures.
The structure used to store values parsed from a spec file.
Definition: rpmspec.h:108
Header headerFree(Header h)
Dereference a header instance.
rpmuint32_t cpioArchiveSize
Definition: buildio.h:16
char * rpmExpand(const char *arg,...)
Return (malloc&#39;ed) concatenated macro expansion(s).
Definition: macro.c:3117
Spec freeSpec(Spec spec)
Destroy a spec file control structure.
static rpmRC cpio_copy(FD_t fdo, CSA_t csa)
Definition: pack.c:93
const char * preInFile
Definition: rpmspec.h:221
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:32
rpmuint8_t * ui8p
Definition: rpmtag.h:67
char * script
Definition: rpmspec.h:28
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:2763
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:756
int rpmbcExportSignature(pgpDig dig, DIGEST_CTX ctx)
Definition: rpmbc.c:923
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:645
rpmuint32_t rpmlibTimestamp(void)
Definition: rpmversion.c:16
const char * postUnFile
Definition: rpmspec.h:227
size_t ndigests
enum rpmRC_e rpmRC
RPM return codes.
int Ferror(FD_t fd)
ferror(3) clone.
Definition: rpmio.c:2944
char * rpmiobStr(rpmiob iob)
Return I/O buffer (as string).
Definition: rpmiob.c:113
Package packages
Definition: rpmspec.h:197
Definition: rpmtag.h:503
void headerCopyTags(Header headerFrom, Header headerTo, rpmTag *tagstocopy)
Duplicate tag values from one header into another.
Definition: header.c:2202
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:1149
rpmts rpmtsCreate(void)
Create an empty transaction set.
Definition: rpmts.c:1480
Methods to handle package elements.
#define SEEK_SET
Definition: system.h:211
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:647
struct rpmiob_s * rpmiob
Definition: rpmiotypes.h:57
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
FD_t Fdopen(FD_t ofd, const char *fmode)
Definition: rpmio.c:2718
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:212
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:632
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:634
rpmfi fi
Definition: rpmspec.h:168
const char * verifyFile
Definition: rpmspec.h:233
int expandMacros(void *spec, MacroContext mc, char *sbuf, size_t slen)
Expand macro into buffer.
Definition: macro.c:2649
int Fileno(FD_t fd)
fileno(3) clone.
Definition: rpmio.c:2991
#define _(Text)
Definition: system.h:30
The structure used to store values for a package.
Definition: rpmspec.h:207
const char * preUnFile
Definition: rpmspec.h:225
rpmRC rpmpkgRead(const char *fn, FD_t fd, void *ptr, const char **msg)
Read item from file descriptor.
Definition: pkgio.c:1647
ARGstr_t * ARGV_t
Definition: argv.h:9
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:214
enum rpmTag_e rpmTag
Definition: rpmtag.h:471
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:452
const char * postTransFile
Definition: rpmspec.h:231
int rpmExpandNumeric(const char *arg)
Return macro expansion as a numeric value.
Definition: macro.c:3191
void * dig
Definition: rpmspec.h:195
DIGEST_CTX rpmDigestDup(DIGEST_CTX octx)
Duplicate a digest context.
Definition: digest.c:209
const char * preTransFile
Definition: rpmspec.h:229
unsigned char * sourcePkgId
Definition: rpmspec.h:164
const char * sanityCheckFile
Definition: rpmspec.h:235
int rpmlibNeedsFeature(Header h, const char *feature, const char *featureEVR)
Add rpmlib feature dependency.
Definition: reqprov.c:258
unsigned int append
Definition: rpmtag.h:512
int Unlink(const char *path)
unlink(2) clone.
Definition: rpmrpc.c:397