rpm 5.2.1

- Main Page
- Related Pages
- Modules
- Data Structures
- Files

- File List
- Globals

build/pack.c
Go to the documentation of this file.

    00001
    00006 #include "system.h"
    00007
    00008 #include <rpmio_internal.h>     /* XXX fdGetFp, fdInitDigest, fdFiniDigest */
    00009 #include <rpmcb.h>
    00010 #include <argv.h>
    00011
    00012 #include <rpmtypes.h>
    00013 #include <rpmtag.h>
    00014
    00015 #include <pkgio.h>
    00016 #include "signature.h"          /* XXX rpmTempFile */
    00017
    00018 #define _RPMFI_INTERNAL         /* XXX fi->fsm */
    00019 #define _RPMEVR_INTERNAL        /* XXX RPMSENSE_ANY */
    00020 #define _RPMTAG_INTERNAL
    00021 #include <rpmbuild.h>
    00022
    00023 #include "rpmfi.h"
    00024 #include "fsm.h"
    00025
    00026 #include <rpmversion.h>
    00027 #include "buildio.h"
    00028
    00029 #include "debug.h"
    00030
    00031 /*@access rpmts @*/
    00032 /*@access rpmfi @*/     /* compared with NULL */
    00033 /*@access Header @*/    /* compared with NULL */
    00034 /*@access FD_t @*/      /* compared with NULL */
    00035 /*@access CSA_t @*/
    00036
    00040 static rpmRC cpio_doio(FD_t fdo, /*@unused@*/ Header h, CSA_t csa,
    00041                 const char * payload_format, const char * fmodeMacro)
    00042         /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
    00043         /*@modifies fdo, csa, rpmGlobalMacroContext,
    00044                 fileSystem, internalState @*/
    00045 {
    00046     rpmts ts = rpmtsCreate();
    00047     rpmfi fi = csa->cpioList;
    00048     const char *failedFile = NULL;
    00049     FD_t cfd;
    00050     rpmRC rc = RPMRC_OK;
    00051     int xx;
    00052
    00053     {   const char *fmode = rpmExpand(fmodeMacro, NULL);
    00054         if (!(fmode && fmode[0] == 'w'))
    00055             fmode = xstrdup("w9.gzdio");
    00056         /*@-nullpass@*/
    00057         (void) Fflush(fdo);
    00058         cfd = Fdopen(fdDup(Fileno(fdo)), fmode);
    00059         /*@=nullpass@*/
    00060         fmode = _free(fmode);
    00061     }
    00062     if (cfd == NULL)
    00063         return RPMRC_FAIL;
    00064
    00065     xx = fsmSetup(fi->fsm, IOSM_PKGBUILD, payload_format, ts, fi, cfd,
    00066                 &csa->cpioArchiveSize, &failedFile);
    00067     if (xx)
    00068         rc = RPMRC_FAIL;
    00069     (void) Fclose(cfd);
    00070     xx = fsmTeardown(fi->fsm);
    00071     if (rc == RPMRC_OK && xx) rc = RPMRC_FAIL;
    00072
    00073     if (rc) {
    00074         const char * msg = iosmStrerror(rc);
    00075         if (failedFile)
    00076             rpmlog(RPMLOG_ERR, _("create archive failed on file %s: %s\n"),
    00077                 failedFile, msg);
    00078         else
    00079             rpmlog(RPMLOG_ERR, _("create archive failed: %s\n"), msg);
    00080         msg = _free(msg);
    00081         rc = RPMRC_FAIL;
    00082     }
    00083
    00084     failedFile = _free(failedFile);
    00085     (void)rpmtsFree(ts);
    00086     ts = NULL;
    00087
    00088     return rc;
    00089 }
    00090
    00093 static rpmRC cpio_copy(FD_t fdo, CSA_t csa)
    00094         /*@globals fileSystem, internalState @*/
    00095         /*@modifies fdo, csa, fileSystem, internalState @*/
    00096 {
    00097     char buf[BUFSIZ];
    00098     size_t nb;
    00099
    00100     while((nb = Fread(buf, sizeof(buf[0]), sizeof(buf), csa->cpioFdIn)) > 0) {
    00101         if (Fwrite(buf, sizeof(buf[0]), nb, fdo) != nb) {
    00102             rpmlog(RPMLOG_ERR, _("cpio_copy write failed: %s\n"),
    00103                         Fstrerror(fdo));
    00104             return RPMRC_FAIL;
    00105         }
    00106         csa->cpioArchiveSize += nb;
    00107     }
    00108     if (Ferror(csa->cpioFdIn)) {
    00109         rpmlog(RPMLOG_ERR, _("cpio_copy read failed: %s\n"),
    00110                 Fstrerror(csa->cpioFdIn));
    00111         return RPMRC_FAIL;
    00112     }
    00113     return RPMRC_OK;
    00114 }
    00115
    00118 static /*@only@*/ /*@null@*/ rpmiob addFileToTagAux(Spec spec,
    00119                 const char * file, /*@only@*/ rpmiob iob)
    00120         /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
    00121         /*@modifies rpmGlobalMacroContext, fileSystem, internalState @*/
    00122 {
    00123     char buf[BUFSIZ];
    00124     const char * fn = buf;
    00125     FILE * f;
    00126     FD_t fd;
    00127
    00128     fn = rpmGetPath("%{_builddir}/%{?buildsubdir:%{buildsubdir}/}", file, NULL);
    00129
    00130     fd = Fopen(fn, "r.fdio");
    00131     if (fn != buf) fn = _free(fn);
    00132     if (fd == NULL || Ferror(fd)) {
    00133         iob = rpmiobFree(iob);
    00134         return NULL;
    00135     }
    00136     /*@-type@*/ /* FIX: cast? */
    00137     if ((f = fdGetFp(fd)) != NULL)
    00138     /*@=type@*/
    00139     while (fgets(buf, (int)sizeof(buf), f)) {
    00140         /* XXX display fn in error msg */
    00141         if (expandMacros(spec, spec->macros, buf, sizeof(buf))) {
    00142             rpmlog(RPMLOG_ERR, _("line: %s\n"), buf);
    00143             iob = rpmiobFree(iob);
    00144             break;
    00145         }
    00146         iob = rpmiobAppend(iob, buf, 0);
    00147     }
    00148     (void) Fclose(fd);
    00149
    00150     return iob;
    00151 }
    00152
    00155 static int addFileToTag(Spec spec, const char * file, Header h, rpmTag tag)
    00156         /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
    00157         /*@modifies h, rpmGlobalMacroContext, fileSystem, internalState @*/
    00158 {
    00159     HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
    00160     rpmiob iob = rpmiobNew(0);
    00161     int xx;
    00162
    00163     he->tag = tag;
    00164     xx = headerGet(h, he, 0);
    00165     if (xx) {
    00166         iob = rpmiobAppend(iob, he->p.str, 1);
    00167         xx = headerDel(h, he, 0);
    00168     }
    00169     he->p.ptr = _free(he->p.ptr);
    00170
    00171     if ((iob = addFileToTagAux(spec, file, iob)) == NULL)
    00172         return 1;
    00173
    00174     he->tag = tag;
    00175     he->t = RPM_STRING_TYPE;
    00176     he->p.str = rpmiobStr(iob);
    00177     he->c = 1;
    00178     xx = headerPut(h, he, 0);
    00179
    00180     iob = rpmiobFree(iob);
    00181     return 0;
    00182 }
    00183
    00186 static int addFileToArrayTag(Spec spec, const char *file, Header h, rpmTag tag)
    00187         /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
    00188         /*@modifies h, rpmGlobalMacroContext, fileSystem, internalState  @*/
    00189 {
    00190     HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
    00191     rpmiob iob = rpmiobNew(0);
    00192     const char *s;
    00193     int xx;
    00194
    00195     if ((iob = addFileToTagAux(spec, file, iob)) == NULL)
    00196         return 1;
    00197
    00198     s = rpmiobStr(iob);
    00199
    00200     he->tag = tag;
    00201     he->t = RPM_STRING_ARRAY_TYPE;
    00202     he->p.argv = &s;
    00203     he->c = 1;
    00204     he->append = 1;
    00205     xx = headerPut(h, he, 0);
    00206     he->append = 0;
    00207
    00208     iob = rpmiobFree(iob);
    00209     return 0;
    00210 }
    00211
    00212 rpmRC processScriptFiles(Spec spec, Package pkg)
    00213         /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
    00214         /*@modifies pkg->header, rpmGlobalMacroContext,
    00215                 fileSystem, internalState @*/
    00216 {
    00217     HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
    00218     struct TriggerFileEntry *p;
    00219     int xx;
    00220
    00221     if (pkg->preInFile) {
    00222         if (addFileToTag(spec, pkg->preInFile, pkg->header, RPMTAG_PREIN)) {
    00223             rpmlog(RPMLOG_ERR,
    00224                      _("Could not open PreIn file: %s\n"), pkg->preInFile);
    00225             return RPMRC_FAIL;
    00226         }
    00227     }
    00228     if (pkg->preUnFile) {
    00229         if (addFileToTag(spec, pkg->preUnFile, pkg->header, RPMTAG_PREUN)) {
    00230             rpmlog(RPMLOG_ERR,
    00231                      _("Could not open PreUn file: %s\n"), pkg->preUnFile);
    00232             return RPMRC_FAIL;
    00233         }
    00234     }
    00235     if (pkg->preTransFile) {
    00236         if (addFileToTag(spec, pkg->preTransFile, pkg->header, RPMTAG_PRETRANS)) {
    00237             rpmlog(RPMLOG_ERR,
    00238                      _("Could not open PreTrans file: %s\n"), pkg->preTransFile);
    00239             return RPMRC_FAIL;
    00240         }
    00241     }
    00242     if (pkg->postInFile) {
    00243         if (addFileToTag(spec, pkg->postInFile, pkg->header, RPMTAG_POSTIN)) {
    00244             rpmlog(RPMLOG_ERR,
    00245                      _("Could not open PostIn file: %s\n"), pkg->postInFile);
    00246             return RPMRC_FAIL;
    00247         }
    00248     }
    00249     if (pkg->postUnFile) {
    00250         if (addFileToTag(spec, pkg->postUnFile, pkg->header, RPMTAG_POSTUN)) {
    00251             rpmlog(RPMLOG_ERR,
    00252                      _("Could not open PostUn file: %s\n"), pkg->postUnFile);
    00253             return RPMRC_FAIL;
    00254         }
    00255     }
    00256     if (pkg->postTransFile) {
    00257         if (addFileToTag(spec, pkg->postTransFile, pkg->header, RPMTAG_POSTTRANS)) {
    00258             rpmlog(RPMLOG_ERR,
    00259                      _("Could not open PostTrans file: %s\n"), pkg->postTransFile);
    00260             return RPMRC_FAIL;
    00261         }
    00262     }
    00263     if (pkg->verifyFile) {
    00264         if (addFileToTag(spec, pkg->verifyFile, pkg->header,
    00265                          RPMTAG_VERIFYSCRIPT)) {
    00266             rpmlog(RPMLOG_ERR,
    00267                      _("Could not open VerifyScript file: %s\n"), pkg->verifyFile);
    00268             return RPMRC_FAIL;
    00269         }
    00270     }
    00271
    00272     if (pkg->sanityCheckFile) {
    00273         if (addFileToTag(spec, pkg->sanityCheckFile, pkg->header, RPMTAG_SANITYCHECK)) {
    00274             rpmlog(RPMLOG_ERR, _("Could not open Test file: %s\n"), pkg->sanityCheckFile);
    00275             return RPMRC_FAIL;
    00276         }
    00277     }
    00278
    00279     for (p = pkg->triggerFiles; p != NULL; p = p->next) {
    00280         he->tag = RPMTAG_TRIGGERSCRIPTPROG;
    00281         he->t = RPM_STRING_ARRAY_TYPE;
    00282         he->p.argv = (const char **)&p->prog;   /* XXX NOCAST */
    00283         he->c = 1;
    00284         he->append = 1;
    00285         xx = headerPut(pkg->header, he, 0);
    00286         he->append = 0;
    00287         if (p->script) {
    00288             he->tag = RPMTAG_TRIGGERSCRIPTS;
    00289             he->t = RPM_STRING_ARRAY_TYPE;
    00290             he->p.argv = (const char **)&p->script;     /* XXX NOCAST */
    00291             he->c = 1;
    00292             he->append = 1;
    00293             xx = headerPut(pkg->header, he, 0);
    00294             he->append = 0;
    00295         } else if (p->fileName) {
    00296             if (addFileToArrayTag(spec, p->fileName, pkg->header,
    00297                                   RPMTAG_TRIGGERSCRIPTS)) {
    00298                 rpmlog(RPMLOG_ERR,
    00299                          _("Could not open Trigger script file: %s\n"),
    00300                          p->fileName);
    00301                 return RPMRC_FAIL;
    00302             }
    00303         } else {
    00304             /*@observer@*/
    00305             static const char *bull = "";
    00306             he->tag = RPMTAG_TRIGGERSCRIPTS;
    00307             he->t = RPM_STRING_ARRAY_TYPE;
    00308             he->p.argv = &bull;
    00309             he->c = 1;
    00310             he->append = 1;
    00311             xx = headerPut(pkg->header, he, 0);
    00312             he->append = 0;
    00313         }
    00314     }
    00315
    00316     return RPMRC_OK;
    00317 }
    00318
    00319 #if defined(DEAD)
    00320 int readRPM(const char *fileName, Spec *specp, void * l,
    00321                 Header *sigs, CSA_t csa)
    00322 {
    00323     const char * msg = "";
    00324     FD_t fdi;
    00325     Spec spec;
    00326     rpmRC rc;
    00327
    00328     fdi = (fileName != NULL)
    00329         ? Fopen(fileName, "r.fdio")
    00330         : fdDup(STDIN_FILENO);
    00331
    00332     if (fdi == NULL || Ferror(fdi)) {
    00333         rpmlog(RPMLOG_ERR, _("readRPM: open %s: %s\n"),
    00334                 (fileName ? fileName : "<stdin>"),
    00335                 Fstrerror(fdi));
    00336         if (fdi) (void) Fclose(fdi);
    00337         return RPMRC_FAIL;
    00338     }
    00339
    00340     {   const char item[] = "Lead";
    00341         size_t nl = rpmpkgSizeof(item, NULL);
    00342
    00343         if (nl == 0) {
    00344             rc = RPMRC_FAIL;
    00345             msg = xstrdup("item size is zero");
    00346         } else {
    00347             l = xcalloc(1, nl);         /* XXX memory leak */
    00348             msg = NULL;
    00349             rc = rpmpkgRead(item, fdi, l, &msg);
    00350         }
    00351     }
    00352
    00353     if (rc != RPMRC_OK) {
    00354         rpmlog(RPMLOG_ERR, _("readRPM: read %s: %s\n"),
    00355                 (fileName ? fileName : "<stdin>"), msg);
    00356         msg = _free(msg);
    00357         return RPMRC_FAIL;
    00358     }
    00359     msg = _free(msg);
    00360     /*@=sizeoftype@*/
    00361
    00362     /* XXX FIXME: EPIPE on <stdin> */
    00363     if (Fseek(fdi, 0, SEEK_SET) == -1) {
    00364         rpmlog(RPMLOG_ERR, _("%s: Fseek failed: %s\n"),
    00365                         (fileName ? fileName : "<stdin>"), Fstrerror(fdi));
    00366         return RPMRC_FAIL;
    00367     }
    00368
    00369     /* Reallocate build data structures */
    00370     spec = newSpec();
    00371     spec->packages = newPackage(spec);
    00372
    00373     /* XXX the header just allocated will be allocated again */
    00374     (void)headerFree(spec->packages->header);
    00375     spec->packages->header = NULL;
    00376
    00377     /* Read the rpm lead, signatures, and header */
    00378     {   rpmts ts = rpmtsCreate();
    00379
    00380         /* XXX W2DO? pass fileName? */
    00381         /*@-mustmod@*/      /* LCL: segfault */
    00382         rc = rpmReadPackageFile(ts, fdi, "readRPM",
    00383                          &spec->packages->header);
    00384         /*@=mustmod@*/
    00385
    00386         (void)rpmtsFree(ts);
    00387         ts = NULL;
    00388
    00389         if (sigs) *sigs = NULL;                 /* XXX HACK */
    00390     }
    00391
    00392     switch (rc) {
    00393     case RPMRC_OK:
    00394     case RPMRC_NOKEY:
    00395     case RPMRC_NOTTRUSTED:
    00396         break;
    00397     case RPMRC_NOTFOUND:
    00398         rpmlog(RPMLOG_ERR, _("readRPM: %s is not an RPM package\n"),
    00399                 (fileName ? fileName : "<stdin>"));
    00400         return RPMRC_FAIL;
    00401     case RPMRC_FAIL:
    00402     default:
    00403         rpmlog(RPMLOG_ERR, _("readRPM: reading header from %s\n"),
    00404                 (fileName ? fileName : "<stdin>"));
    00405         return RPMRC_FAIL;
    00406         /*@notreached@*/ break;
    00407     }
    00408
    00409     if (specp)
    00410         *specp = spec;
    00411     else
    00412         spec = freeSpec(spec);
    00413
    00414     if (csa != NULL)
    00415         csa->cpioFdIn = fdi;
    00416     else
    00417         (void) Fclose(fdi);
    00418
    00419     return 0;
    00420 }
    00421 #endif
    00422
    00423 #if defined(DEAD)
    00424 #define RPMPKGVERSION_MIN       30004
    00425 #define RPMPKGVERSION_MAX       40003
    00426 /*@unchecked@*/
    00427 static int rpmpkg_version = -1;
    00428
    00429 static int rpmLeadVersion(void)
    00430         /*@globals rpmpkg_version, rpmGlobalMacroContext, h_errno @*/
    00431         /*@modifies rpmpkg_version, rpmGlobalMacroContext @*/
    00432 {
    00433     int rpmlead_version;
    00434
    00435     /* Intitialize packaging version from macro configuration. */
    00436     if (rpmpkg_version < 0) {
    00437         rpmpkg_version = rpmExpandNumeric("%{_package_version}");
    00438         if (rpmpkg_version < RPMPKGVERSION_MIN)
    00439             rpmpkg_version = RPMPKGVERSION_MIN;
    00440         if (rpmpkg_version > RPMPKGVERSION_MAX)
    00441             rpmpkg_version = RPMPKGVERSION_MAX;
    00442     }
    00443
    00444     rpmlead_version = rpmpkg_version / 10000;
    00445     /* XXX silly sanity check. */
    00446     if (rpmlead_version < 3 || rpmlead_version > 4)
    00447         rpmlead_version = 3;
    00448     return rpmlead_version;
    00449 }
    00450 #endif
    00451
    00452 void providePackageNVR(Header h)
    00453 {
    00454     HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
    00455     const char *N, *V, *R;
    00456 #ifdef RPM_VENDOR_MANDRIVA
    00457     const char *D;
    00458     int gotD;
    00459 #endif
    00460     rpmuint32_t E;
    00461     int gotE;
    00462     const char *pEVR;
    00463     char *p;
    00464     rpmuint32_t pFlags = RPMSENSE_EQUAL;
    00465     const char ** provides = NULL;
    00466     const char ** providesEVR = NULL;
    00467     rpmuint32_t * provideFlags = NULL;
    00468     int providesCount;
    00469     int bingo = 1;
    00470     size_t nb;
    00471     int xx;
    00472     int i;
    00473
    00474     /* Generate provides for this package N-V-R. */
    00475     xx = headerNEVRA(h, &N, NULL, &V, &R, NULL);
    00476     if (!(N && V && R))
    00477         return;
    00478
    00479     nb = 21 + strlen(V) + 1 + strlen(R) + 1;
    00480 #ifdef  RPM_VENDOR_MANDRIVA
    00481     he->tag = RPMTAG_DISTEPOCH;
    00482     gotD = headerGet(h, he, 0);
    00483     D = (he->p.str ? he->p.str : NULL);
    00484     nb += (gotD ? strlen(D) + 1 : 0);
    00485 #endif
    00486     pEVR = p = alloca(nb);
    00487     *p = '\0';
    00488     he->tag = RPMTAG_EPOCH;
    00489     gotE = headerGet(h, he, 0);
    00490     E = (he->p.ui32p ? he->p.ui32p[0] : 0);
    00491     he->p.ptr = _free(he->p.ptr);
    00492     if (gotE) {
    00493         sprintf(p, "%d:", E);
    00494         p += strlen(p);
    00495     }
    00496     p = stpcpy( stpcpy( stpcpy(p, V) , "-") , R);
    00497 #ifdef  RPM_VENDOR_MANDRIVA
    00498     if (gotD) {
    00499         p = stpcpy( stpcpy( p, ":"), D);
    00500         D = _free(D);
    00501     }
    00502 #endif
    00503     V = _free(V);
    00504     R = _free(R);
    00505
    00506     /*
    00507      * Rpm prior to 3.0.3 does not have versioned provides.
    00508      * If no provides at all are available, we can just add.
    00509      */
    00510     he->tag = RPMTAG_PROVIDENAME;
    00511 /*@-nullstate@*/
    00512     xx = headerGet(h, he, 0);
    00513 /*@=nullstate@*/
    00514     provides = he->p.argv;
    00515     providesCount = he->c;
    00516     if (!xx)
    00517         goto exit;
    00518
    00519     /*
    00520      * Otherwise, fill in entries on legacy packages.
    00521      */
    00522     he->tag = RPMTAG_PROVIDEVERSION;
    00523 /*@-nullstate@*/
    00524     xx = headerGet(h, he, 0);
    00525 /*@=nullstate@*/
    00526     providesEVR = he->p.argv;
    00527     if (!xx) {
    00528         for (i = 0; i < providesCount; i++) {
    00529             /*@observer@*/
    00530             static const char * vdummy = "";
    00531             static rpmsenseFlags fdummy = RPMSENSE_ANY;
    00532
    00533             he->tag = RPMTAG_PROVIDEVERSION;
    00534             he->t = RPM_STRING_ARRAY_TYPE;
    00535             he->p.argv = &vdummy;
    00536             he->c = 1;
    00537             he->append = 1;
    00538 /*@-nullstate@*/
    00539             xx = headerPut(h, he, 0);
    00540 /*@=nullstate@*/
    00541             he->append = 0;
    00542
    00543             he->tag = RPMTAG_PROVIDEFLAGS;
    00544             he->t = RPM_UINT32_TYPE;
    00545             he->p.ui32p = (rpmuint32_t *) &fdummy;
    00546             he->c = 1;
    00547             he->append = 1;
    00548 /*@-nullstate@*/
    00549             xx = headerPut(h, he, 0);
    00550 /*@=nullstate@*/
    00551             he->append = 0;
    00552         }
    00553         goto exit;
    00554     }
    00555
    00556     he->tag = RPMTAG_PROVIDEFLAGS;
    00557 /*@-nullstate@*/
    00558     xx = headerGet(h, he, 0);
    00559 /*@=nullstate@*/
    00560     provideFlags = he->p.ui32p;
    00561
    00562     /*@-nullderef@*/    /* LCL: providesEVR is not NULL */
    00563     if (provides && providesEVR && provideFlags)
    00564     for (i = 0; i < providesCount; i++) {
    00565         if (!(provides[i] && providesEVR[i]))
    00566             continue;
    00567         if (!(provideFlags[i] == RPMSENSE_EQUAL &&
    00568             !strcmp(N, provides[i]) && !strcmp(pEVR, providesEVR[i])))
    00569             continue;
    00570         bingo = 0;
    00571         break;
    00572     }
    00573     /*@=nullderef@*/
    00574
    00575 exit:
    00576 /*@-usereleased@*/
    00577     provides = _free(provides);
    00578     providesEVR = _free(providesEVR);
    00579     provideFlags = _free(provideFlags);
    00580 /*@=usereleased@*/
    00581
    00582     if (bingo) {
    00583         he->tag = RPMTAG_PROVIDENAME;
    00584         he->t = RPM_STRING_ARRAY_TYPE;
    00585         he->p.argv = &N;
    00586         he->c = 1;
    00587         he->append = 1;
    00588 /*@-nullstate@*/
    00589         xx = headerPut(h, he, 0);
    00590 /*@=nullstate@*/
    00591         he->append = 0;
    00592
    00593         he->tag = RPMTAG_PROVIDEVERSION;
    00594         he->t = RPM_STRING_ARRAY_TYPE;
    00595         he->p.argv = &pEVR;
    00596         he->c = 1;
    00597         he->append = 1;
    00598 /*@-nullstate@*/
    00599         xx = headerPut(h, he, 0);
    00600 /*@=nullstate@*/
    00601         he->append = 0;
    00602
    00603         he->tag = RPMTAG_PROVIDEFLAGS;
    00604         he->t = RPM_UINT32_TYPE;
    00605         he->p.ui32p = &pFlags;
    00606         he->c = 1;
    00607         he->append = 1;
    00608 /*@-nullstate@*/
    00609         xx = headerPut(h, he, 0);
    00610 /*@=nullstate@*/
    00611         he->append = 0;
    00612     }
    00613     N = _free(N);
    00614 }
    00615
    00616 rpmRC writeRPM(Header *hdrp, unsigned char ** pkgidp, const char *fileName,
    00617                 CSA_t csa, char *passPhrase, const char **cookie)
    00618 {
    00619     HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
    00620     FD_t fd = NULL;
    00621     FD_t ifd = NULL;
    00622     rpmuint32_t sigtag;
    00623     const char * sigtarget;
    00624     const char * rpmio_flags = NULL;
    00625     const char * payload_format = NULL;
    00626     const char * SHA1 = NULL;
    00627     const char * msg = NULL;
    00628     char *s;
    00629     char buf[BUFSIZ];
    00630     Header h;
    00631     Header sigh = NULL;
    00632     int addsig = 0;
    00633     int isSource;
    00634     rpmRC rc = RPMRC_OK;
    00635     size_t nbr;
    00636     size_t nbw;
    00637     int xx;
    00638
    00639     /* Transfer header reference form *hdrp to h. */
    00640     h = headerLink(*hdrp);
    00641     (void)headerFree(*hdrp);
    00642     *hdrp = NULL;
    00643
    00644     if (pkgidp)
    00645         *pkgidp = NULL;
    00646
    00647     /* Save payload information */
    00648     isSource =
    00649         (headerIsEntry(h, RPMTAG_SOURCERPM) == 0 &&
    00650          headerIsEntry(h, RPMTAG_ARCH) != 0);
    00651     if (isSource) {
    00652         payload_format = rpmExpand("%{?_source_payload_format}", NULL);
    00653         rpmio_flags = rpmExpand("%{?_source_payload}", NULL);
    00654     } else {
    00655         payload_format = rpmExpand("%{?_binary_payload_format}", NULL);
    00656         rpmio_flags = rpmExpand("%{?_binary_payload}", NULL);
    00657     }
    00658
    00659     if (!(payload_format && *payload_format)) {
    00660         payload_format = _free(payload_format);
    00661         payload_format = xstrdup("cpio");
    00662     }
    00663     if (!(rpmio_flags && *rpmio_flags)) {
    00664         rpmio_flags = _free(rpmio_flags);
    00665         rpmio_flags = xstrdup("w9.gzdio");
    00666     }
    00667     s = strchr(rpmio_flags, '.');
    00668     if (s) {
    00669
    00670         if (payload_format) {
    00671             if (!strcmp(payload_format, "tar")
    00672              || !strcmp(payload_format, "ustar")) {
    00673                 /* XXX addition to header is too late to be displayed/sorted. */
    00674                 /* Add prereq on rpm version that understands tar payloads */
    00675                 (void) rpmlibNeedsFeature(h, "PayloadIsUstar", "4.4.4-1");
    00676             }
    00677 #if defined(SUPPORT_AR_PAYLOADS)
    00678             if (!strcmp(payload_format, "ar")) {
    00679                 /* XXX addition to header is too late to be displayed/sorted. */
    00680                 /* Add prereq on rpm version that understands tar payloads */
    00681                 (void) rpmlibNeedsFeature(h, "PayloadIsAr", "5.1-1");
    00682             }
    00683 #endif
    00684
    00685             he->tag = RPMTAG_PAYLOADFORMAT;
    00686             he->t = RPM_STRING_TYPE;
    00687             he->p.str = payload_format;
    00688             he->c = 1;
    00689             xx = headerPut(h, he, 0);
    00690         }
    00691
    00692         /* XXX addition to header is too late to be displayed/sorted. */
    00693         if (s[1] == 'g' && s[2] == 'z') {
    00694             he->tag = RPMTAG_PAYLOADCOMPRESSOR;
    00695             he->t = RPM_STRING_TYPE;
    00696             he->p.str = xstrdup("gzip");
    00697             he->c = 1;
    00698             xx = headerPut(h, he, 0);
    00699             he->p.ptr = _free(he->p.ptr);
    00700         } else if (s[1] == 'b' && s[2] == 'z') {
    00701             he->tag = RPMTAG_PAYLOADCOMPRESSOR;
    00702             he->t = RPM_STRING_TYPE;
    00703             he->p.str = xstrdup("bzip2");
    00704             he->c = 1;
    00705             xx = headerPut(h, he, 0);
    00706             he->p.ptr = _free(he->p.ptr);
    00707         } else if (s[1] == 'l' && s[2] == 'z') {
    00708             he->tag = RPMTAG_PAYLOADCOMPRESSOR;
    00709             he->t = RPM_STRING_TYPE;
    00710             he->p.str = xstrdup("lzma");
    00711             he->c = 1;
    00712             xx = headerPut(h, he, 0);
    00713             he->p.ptr = _free(he->p.ptr);
    00714             (void) rpmlibNeedsFeature(h, "PayloadIsLzma", "4.4.6-1");
    00715         } else if (s[1] == 'x' && s[2] == 'z') {
    00716             he->tag = RPMTAG_PAYLOADCOMPRESSOR;
    00717             he->t = RPM_STRING_TYPE;
    00718             he->p.str = xstrdup("xz");
    00719             he->c = 1;
    00720             xx = headerPut(h, he, 0);
    00721             he->p.ptr = _free(he->p.ptr);
    00722             (void) rpmlibNeedsFeature(h, "PayloadIsXz", "5.2-1");
    00723         }
    00724         strcpy(buf, rpmio_flags);
    00725         buf[s - rpmio_flags] = '\0';
    00726
    00727         he->tag = RPMTAG_PAYLOADFLAGS;
    00728         he->t = RPM_STRING_TYPE;
    00729         he->p.str = buf+1;
    00730         he->c = 1;
    00731         xx = headerPut(h, he, 0);
    00732     }
    00733
    00734     /* Create and add the cookie */
    00735     if (cookie) {
    00736         sprintf(buf, "%s %u", buildHost(), (unsigned) (*getBuildTime()));
    00737         *cookie = xstrdup(buf);         /* XXX memory leak */
    00738         he->tag = RPMTAG_COOKIE;
    00739         he->t = RPM_STRING_TYPE;
    00740         he->p.str = *cookie;
    00741         he->c = 1;
    00742         xx = headerPut(h, he, 0);
    00743     }
    00744
    00745     /* Reallocate the header into one contiguous region. */
    00746     h = headerReload(h, RPMTAG_HEADERIMMUTABLE);
    00747     if (h == NULL) {    /* XXX can't happen */
    00748         rpmlog(RPMLOG_ERR, _("Unable to create immutable header region.\n"));
    00749         rc = RPMRC_FAIL;
    00750         goto exit;
    00751     }
    00752     /* Re-reference reallocated header. */
    00753     *hdrp = headerLink(h);
    00754
    00755     /*
    00756      * Write the header+archive into a temp file so that the size of
    00757      * archive (after compression) can be added to the header.
    00758      */
    00759     sigtarget = NULL;
    00760     if (rpmTempFile(NULL, &sigtarget, &fd)) {
    00761         rpmlog(RPMLOG_ERR, _("Unable to open temp file.\n"));
    00762         rc = RPMRC_FAIL;
    00763         goto exit;
    00764     }
    00765
    00766     /* Write the header to a temp file, computing header SHA1 on the fly. */
    00767     fdInitDigest(fd, PGPHASHALGO_SHA1, 0);
    00768     {   const char item[] = "Header";
    00769         msg = NULL;
    00770         rc = rpmpkgWrite(item, fd, h, &msg);
    00771         if (rc != RPMRC_OK) {
    00772             rpmlog(RPMLOG_ERR, "%s: %s: %s\n", sigtarget, item,
    00773                 (msg && *msg ? msg : "write failed\n"));
    00774             msg = _free(msg);
    00775             rc = RPMRC_FAIL;
    00776             goto exit;
    00777         }
    00778         msg = _free(msg);
    00779         (void) Fflush(fd);
    00780     }
    00781     fdFiniDigest(fd, PGPHASHALGO_SHA1, &SHA1, NULL, 1);
    00782
    00783     /* Append the payload to the temp file. */
    00784     if (csa->cpioList != NULL)
    00785         rc = cpio_doio(fd, h, csa, payload_format, rpmio_flags);
    00786     else if (Fileno(csa->cpioFdIn) >= 0)
    00787         rc = cpio_copy(fd, csa);
    00788     else
    00789 assert(0);
    00790
    00791     rpmio_flags = _free(rpmio_flags);
    00792     payload_format = _free(payload_format);
    00793     if (rc != RPMRC_OK)
    00794         goto exit;
    00795
    00796     (void) Fclose(fd);
    00797     fd = NULL;
    00798     (void) Unlink(fileName);
    00799
    00800     /* Generate the signature */
    00801     (void) fflush(stdout);
    00802     sigh = headerNew();
    00803     (void) rpmAddSignature(sigh, sigtarget, RPMSIGTAG_SIZE, passPhrase);
    00804     (void) rpmAddSignature(sigh, sigtarget, RPMSIGTAG_MD5, passPhrase);
    00805
    00806     sigtag = RPMSIGTAG_GPG;
    00807     addsig = (passPhrase && passPhrase[0]);
    00808
    00809     if (addsig) {
    00810         rpmlog(RPMLOG_NOTICE, _("Generating signature: %d\n"), sigtag);
    00811         (void) rpmAddSignature(sigh, sigtarget, sigtag, passPhrase);
    00812     }
    00813
    00814     if (SHA1) {
    00815         he->tag = (rpmTag) RPMSIGTAG_SHA1;
    00816         he->t = RPM_STRING_TYPE;
    00817         he->p.str = SHA1;
    00818         he->c = 1;
    00819         xx = headerPut(sigh, he, 0);
    00820         SHA1 = _free(SHA1);
    00821     }
    00822
    00823     {   rpmuint32_t payloadSize = csa->cpioArchiveSize;
    00824         he->tag = (rpmTag) RPMSIGTAG_PAYLOADSIZE;
    00825         he->t = RPM_UINT32_TYPE;
    00826         he->p.ui32p = &payloadSize;
    00827         he->c = 1;
    00828         xx = headerPut(sigh, he, 0);
    00829     }
    00830
    00831     /* Reallocate the signature into one contiguous region. */
    00832     sigh = headerReload(sigh, RPMTAG_HEADERSIGNATURES);
    00833     if (sigh == NULL) { /* XXX can't happen */
    00834         rpmlog(RPMLOG_ERR, _("Unable to reload signature header.\n"));
    00835         rc = RPMRC_FAIL;
    00836         goto exit;
    00837     }
    00838
    00839     /* Pad the signature header to put the metadata header at known offset. */
    00840     {   size_t slen = 0;
    00841         void * uh = headerUnload(sigh, &slen);
    00842         static const size_t align = 1024;
    00843         size_t nb = align - 96 - 16 - 16;
    00844         rpmuint8_t * b;
    00845
    00846         uh = _free(uh);
    00847 assert(slen < nb);
    00848         nb -= slen;
    00849         b = memset(alloca(nb), 0, nb);
    00850         he->tag = (rpmTag) RPMSIGTAG_PADDING;
    00851         he->t = RPM_BIN_TYPE;
    00852         he->p.ui8p = b;
    00853         he->c = nb;
    00854         xx = headerPut(sigh, he, 0);
    00855         sigh = headerReload(sigh, RPMTAG_HEADERSIGNATURES);
    00856 assert(sigh != NULL);
    00857     }
    00858
    00859     /* Open the output file */
    00860     fd = Fopen(fileName, "w.fdio");
    00861     if (fd == NULL || Ferror(fd)) {
    00862         rpmlog(RPMLOG_ERR, _("Could not open %s: %s\n"),
    00863                 fileName, Fstrerror(fd));
    00864         rc = RPMRC_FAIL;
    00865         goto exit;
    00866     }
    00867
    00868     /* Write the lead section into the package. */
    00869     {   const char item[] = "Lead";
    00870         size_t nl = rpmpkgSizeof(item, NULL);
    00871
    00872         msg = NULL;
    00873         if (nl == 0)
    00874             rc = RPMRC_FAIL;
    00875         else {
    00876             void * l = memset(alloca(nl), 0, nl);
    00877             const char *N, *V, *R;
    00878             (void) headerNEVRA(h, &N, NULL, &V, &R, NULL);
    00879             sprintf(buf, "%s-%s-%s", N, V, R);
    00880             N = _free(N);
    00881             V = _free(V);
    00882             R = _free(R);
    00883             msg = buf;
    00884             rc = rpmpkgWrite(item, fd, l, &msg);
    00885         }
    00886
    00887         if (rc != RPMRC_OK) {
    00888             rpmlog(RPMLOG_ERR, _("Unable to write package: %s\n"),
    00889                  Fstrerror(fd));
    00890             rc = RPMRC_FAIL;
    00891             goto exit;
    00892         }
    00893     }
    00894
    00895     /* Write the signature section into the package. */
    00896     {   const char item[] = "Signature";
    00897
    00898         msg = NULL;
    00899         rc = rpmpkgWrite(item, fd, sigh, &msg);
    00900         if (rc != RPMRC_OK) {
    00901             rpmlog(RPMLOG_ERR, "%s: %s: %s\n", fileName, item,
    00902                 (msg && *msg ? msg : "write failed\n"));
    00903             msg = _free(msg);
    00904             rc = RPMRC_FAIL;
    00905             goto exit;
    00906         }
    00907         msg = _free(msg);
    00908     }
    00909
    00910     /* Append the header and archive */
    00911     ifd = Fopen(sigtarget, "r.fdio");
    00912     if (ifd == NULL || Ferror(ifd)) {
    00913         rpmlog(RPMLOG_ERR, _("Unable to open sigtarget %s: %s\n"),
    00914                 sigtarget, Fstrerror(ifd));
    00915         rc = RPMRC_FAIL;
    00916         goto exit;
    00917     }
    00918
    00919     /* Add signatures to header, and write header into the package. */
    00920     {   const char item[] = "Header";
    00921         Header nh = NULL;
    00922
    00923         msg = NULL;
    00924         rc = rpmpkgRead(item, ifd, &nh, &msg);
    00925         if (rc != RPMRC_OK) {
    00926             rpmlog(RPMLOG_ERR, "%s: %s: %s\n", sigtarget, item,
    00927                 (msg && *msg ? msg : "read failed\n"));
    00928             msg = _free(msg);
    00929             rc = RPMRC_FAIL;
    00930             goto exit;
    00931         }
    00932         msg = _free(msg);
    00933
    00934 #ifdef  NOTYET
    00935         (void) headerMergeLegacySigs(nh, sigh);
    00936 #endif
    00937
    00938         msg = NULL;
    00939         rc = rpmpkgWrite(item, fd, nh, &msg);
    00940         (void)headerFree(nh);
    00941         nh = NULL;
    00942         if (rc != RPMRC_OK) {
    00943             rpmlog(RPMLOG_ERR, "%s: %s: %s\n", fileName, item,
    00944                 (msg && *msg ? msg : "write failed\n"));
    00945             msg = _free(msg);
    00946             rc = RPMRC_FAIL;
    00947             goto exit;
    00948         }
    00949         msg = _free(msg);
    00950     }
    00951
    00952     /* Write the payload into the package. */
    00953     while ((nbr = Fread(buf, sizeof(buf[0]), sizeof(buf), ifd)) > 0) {
    00954         if (Ferror(ifd)) {
    00955             rpmlog(RPMLOG_ERR, _("Unable to read payload from %s: %s\n"),
    00956                      sigtarget, Fstrerror(ifd));
    00957             rc = RPMRC_FAIL;
    00958             goto exit;
    00959         }
    00960         nbw = (int)Fwrite(buf, sizeof(buf[0]), nbr, fd);
    00961         if (nbr != nbw || Ferror(fd)) {
    00962             rpmlog(RPMLOG_ERR, _("Unable to write payload to %s: %s\n"),
    00963                      fileName, Fstrerror(fd));
    00964             rc = RPMRC_FAIL;
    00965             goto exit;
    00966         }
    00967     }
    00968     rc = RPMRC_OK;
    00969
    00970 exit:
    00971     SHA1 = _free(SHA1);
    00972     (void)headerFree(h);
    00973     h = NULL;
    00974
    00975     /* XXX Fish the pkgid out of the signature header. */
    00976     if (sigh != NULL && pkgidp != NULL) {
    00977         he->tag = (rpmTag) RPMSIGTAG_MD5;
    00978         xx = headerGet(sigh, he, 0);
    00979         if (he->t == RPM_BIN_TYPE && he->p.ptr != NULL && he->c == 16)
    00980             *pkgidp = he->p.ui8p;               /* XXX memory leak */
    00981     }
    00982
    00983     (void)headerFree(sigh);
    00984     sigh = NULL;
    00985     if (ifd) {
    00986         (void) Fclose(ifd);
    00987         ifd = NULL;
    00988     }
    00989     if (fd) {
    00990         (void) Fclose(fd);
    00991         fd = NULL;
    00992     }
    00993     if (sigtarget) {
    00994         (void) Unlink(sigtarget);
    00995         sigtarget = _free(sigtarget);
    00996     }
    00997
    00998     if (rc == RPMRC_OK)
    00999         rpmlog(RPMLOG_NOTICE, _("Wrote: %s\n"), fileName);
    01000     else
    01001         (void) Unlink(fileName);
    01002
    01003     return rc;
    01004 }
    01005
    01006 static int rpmlibMarkers(Header h)
    01007         /*@modifies h @*/
    01008 {
    01009     HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
    01010     rpmuint32_t val;
    01011     int xx;
    01012
    01013     he->tag = RPMTAG_RPMVERSION;
    01014     he->t = RPM_STRING_TYPE;
    01015     he->p.str = xstrdup(VERSION);
    01016     he->c = 1;
    01017     xx = headerPut(h, he, 0);
    01018     he->p.ptr = _free(he->p.ptr);
    01019
    01020   if (!(_rpmbuildFlags & 4)) {
    01021     val = (rpmuint32_t)rpmlibTimestamp();
    01022     he->tag = RPMTAG_RPMLIBTIMESTAMP;
    01023     he->t = RPM_UINT32_TYPE;
    01024     he->p.ui32p = &val;
    01025     he->c = 1;
    01026     xx = headerPut(h, he, 0);
    01027
    01028     val = (rpmuint32_t)rpmlibVendor();
    01029     he->tag = RPMTAG_RPMLIBVENDOR;
    01030     he->t = RPM_UINT32_TYPE;
    01031     he->p.ui32p = &val;
    01032     he->c = 1;
    01033     xx = headerPut(h, he, 0);
    01034
    01035     val = (rpmuint32_t)rpmlibVersion();
    01036     he->tag = RPMTAG_RPMLIBVERSION;
    01037     he->t = RPM_UINT32_TYPE;
    01038     he->p.ui32p = &val;
    01039     he->c = 1;
    01040     xx = headerPut(h, he, 0);
    01041   }
    01042
    01043     he->tag = RPMTAG_BUILDHOST;
    01044     he->t = RPM_STRING_TYPE;
    01045     he->p.str = buildHost();
    01046     he->c = 1;
    01047     xx = headerPut(h, he, 0);
    01048
    01049     he->tag = RPMTAG_BUILDTIME;
    01050     he->t = RPM_UINT32_TYPE;
    01051     he->p.ui32p = getBuildTime();
    01052     he->c = 1;
    01053     xx = headerPut(h, he, 0);
    01054
    01055     return 0;
    01056 }
    01057
    01058 /*@unchecked@*/
    01059 static rpmTag copyTags[] = {
    01060     RPMTAG_CHANGELOGTIME,
    01061     RPMTAG_CHANGELOGNAME,
    01062     RPMTAG_CHANGELOGTEXT,
    01063     0
    01064 };
    01065
    01066 rpmRC packageBinaries(Spec spec)
    01067 {
    01068     HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
    01069     struct cpioSourceArchive_s csabuf;
    01070     CSA_t csa = &csabuf;
    01071     const char *errorString;
    01072     Package pkg;
    01073     rpmRC rc;
    01074     int xx;
    01075
    01076     for (pkg = spec->packages; pkg != NULL; pkg = pkg->next) {
    01077         const char *fn;
    01078
    01079         if (pkg->fileList == NULL)
    01080             continue;
    01081
    01082         if (spec->cookie) {
    01083             he->tag = RPMTAG_COOKIE;
    01084             he->t = RPM_STRING_TYPE;
    01085             he->p.str = spec->cookie;
    01086             he->c = 1;
    01087             xx = headerPut(pkg->header, he, 0);
    01088         }
    01089
    01090         /* Copy changelog from src rpm */
    01091         headerCopyTags(spec->packages->header, pkg->header, copyTags);
    01092
    01093         /* Add rpmlib markers for tracking. */
    01094         (void) rpmlibMarkers(pkg->header);
    01095
    01096         he->tag = RPMTAG_OPTFLAGS;
    01097         he->t = RPM_STRING_TYPE;
    01098         he->p.str = rpmExpand("%{optflags}", NULL);
    01099         he->c = 1;
    01100         xx = headerPut(pkg->header, he, 0);
    01101         he->p.ptr = _free(he->p.ptr);
    01102
    01103 if (!(_rpmbuildFlags & 4)) {
    01104         if (spec->sourcePkgId != NULL) {
    01105             he->tag = RPMTAG_SOURCEPKGID;
    01106             he->t = RPM_BIN_TYPE;
    01107             he->p.ptr = spec->sourcePkgId;
    01108             he->c = 16;
    01109             xx = headerPut(pkg->header, he, 0);
    01110         }
    01111 }
    01112
    01113         {   const char *binFormat = rpmGetPath("%{_rpmfilename}", NULL);
    01114             char *binRpm, *binDir;
    01115             binRpm = headerSprintf(pkg->header, binFormat, NULL,
    01116                                rpmHeaderFormats, &errorString);
    01117             binFormat = _free(binFormat);
    01118             if (binRpm == NULL) {
    01119                 he->tag = RPMTAG_NVRA;
    01120                 xx = headerGet(pkg->header, he, 0);
    01121                 rpmlog(RPMLOG_ERR, _("Could not generate output "
    01122                      "filename for package %s: %s\n"), he->p.str, errorString);
    01123                 he->p.ptr = _free(he->p.ptr);
    01124 /*@-usereleased@*/
    01125                 return RPMRC_FAIL;
    01126 /*@=usereleased@*/
    01127             }
    01128             fn = rpmGetPath("%{_rpmdir}/", binRpm, NULL);
    01129             if ((binDir = strchr(binRpm, '/')) != NULL) {
    01130                 struct stat st;
    01131                 const char *dn;
    01132                 *binDir = '\0';
    01133                 dn = rpmGetPath("%{_rpmdir}/", binRpm, NULL);
    01134                 if (Stat(dn, &st) < 0) {
    01135                     switch(errno) {
    01136                     case  ENOENT:
    01137                         if (rpmioMkpath(dn, 0755, -1, -1) == 0)
    01138                             /*@switchbreak@*/ break;
    01139                         /*@fallthrough@*/
    01140                     default:
    01141                         rpmlog(RPMLOG_ERR,_("cannot create %s: %s\n"),
    01142                             dn, strerror(errno));
    01143                         /*@switchbreak@*/ break;
    01144                     }
    01145                 }
    01146                 dn = _free(dn);
    01147             }
    01148             binRpm = _free(binRpm);
    01149         }
    01150
    01151         memset(csa, 0, sizeof(*csa));
    01152         csa->cpioArchiveSize = 0;
    01153         /*@-type@*/ /* LCL: function typedefs */
    01154 /*@-onlytrans@*/
    01155         csa->cpioFdIn = fdNew("init (packageBinaries)");
    01156 /*@=onlytrans@*/
    01157 /*@-assignexpose -newreftrans@*/
    01158         csa->cpioList = rpmfiLink(pkg->cpioList, "packageBinaries");
    01159 /*@=assignexpose =newreftrans@*/
    01160 assert(csa->cpioList != NULL);
    01161
    01162         rc = writeRPM(&pkg->header, NULL, fn,
    01163                     csa, spec->passPhrase, NULL);
    01164
    01165 /*@-onlytrans@*/
    01166         csa->cpioList->te = _free(csa->cpioList->te);   /* XXX memory leak */
    01167 /*@=onlytrans@*/
    01168         csa->cpioList = rpmfiFree(csa->cpioList);
    01169 /*@-nullpass -onlytrans -refcounttrans @*/
    01170         csa->cpioFdIn = fdFree(csa->cpioFdIn, "init (packageBinaries)");
    01171 /*@=nullpass =onlytrans =refcounttrans @*/
    01172         /*@=type@*/
    01173         fn = _free(fn);
    01174         if (rc)
    01175             return rc;
    01176     }
    01177
    01178     return RPMRC_OK;
    01179 }
    01180
    01181 rpmRC packageSources(Spec spec)
    01182 {
    01183     HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
    01184     struct cpioSourceArchive_s csabuf;
    01185     CSA_t csa = &csabuf;
    01186     rpmRC rc;
    01187     int xx;
    01188 #if defined(RPM_VENDOR_OPENPKG) || defined(RPM_VENDOR_FEDORA) || defined(RPM_VENDOR_MANDRIVA) || defined(RPM_VENDOR_ARK) /* backward-compat-rpmtag-sourcepackage */
    01189     rpmuint32_t val;
    01190 #endif
    01191
    01192     /* Add rpmlib markers for tracking. */
    01193     (void) rpmlibMarkers(spec->sourceHeader);
    01194
    01195 #if defined(RPM_VENDOR_OPENPKG) || defined(RPM_VENDOR_FEDORA) || defined(RPM_VENDOR_MANDRIVA) || defined(RPM_VENDOR_ARK) /* backward-compat-rpmtag-sourcepackage */
    01196     /* Mark package as a SRPM for backward compatibility with RPM < 4.4.6 */
    01197     he->tag = RPMTAG_SOURCEPACKAGE;
    01198     he->t = RPM_UINT32_TYPE;
    01199     val = 1;
    01200     he->p.ui32p = &val;
    01201     he->c = 1;
    01202     xx = headerPut(spec->sourceHeader, he, 0);
    01203 #endif
    01204
    01205     /* Add macros used during build to SRPM's. */
    01206     {   const char ** av = NULL;
    01207         (void)rpmGetMacroEntries(NULL, NULL, 1, &av);
    01208         if (av != NULL && av[0] != NULL) {
    01209             he->tag = RPMTAG_BUILDMACROS;
    01210             he->t = RPM_STRING_ARRAY_TYPE;
    01211             he->p.argv = av;
    01212             he->c = argvCount(av);
    01213             xx = headerPut(spec->sourceHeader, he, 0);
    01214         }
    01215 /*@-nullstate@*/
    01216         av = argvFree(av);
    01217 /*@=nullstate@*/
    01218     }
    01219
    01220     spec->cookie = _free(spec->cookie);
    01221
    01222     /* XXX this should be %_srpmdir */
    01223     {   const char *srcrpmdir = rpmGetPath("%{_srcrpmdir}/", NULL);
    01224         const char *fn = rpmGetPath("%{_srcrpmdir}/", spec->sourceRpmName,NULL);
    01225
    01226         rc = rpmioMkpath(srcrpmdir, 0755, -1, -1);
    01227
    01228         memset(csa, 0, sizeof(*csa));
    01229         csa->cpioArchiveSize = 0;
    01230         /*@-type@*/ /* LCL: function typedefs */
    01231 /*@-onlytrans@*/
    01232         csa->cpioFdIn = fdNew("init (packageSources)");
    01233 /*@=onlytrans@*/
    01234 /*@-assignexpose -newreftrans@*/
    01235         csa->cpioList = rpmfiLink(spec->sourceCpioList, "packageSources");
    01236 /*@=assignexpose =newreftrans@*/
    01237 assert(csa->cpioList != NULL);
    01238
    01239         spec->sourcePkgId = NULL;
    01240         rc = writeRPM(&spec->sourceHeader, &spec->sourcePkgId, fn,
    01241                 csa, spec->passPhrase, &(spec->cookie));
    01242
    01243 /*@-onlytrans@*/
    01244         csa->cpioList->te = _free(csa->cpioList->te);   /* XXX memory leak */
    01245 /*@=onlytrans@*/
    01246         csa->cpioList = rpmfiFree(csa->cpioList);
    01247 /*@-nullpass -onlytrans -refcounttrans @*/
    01248         csa->cpioFdIn = fdFree(csa->cpioFdIn, "init (packageSources)");
    01249 /*@=nullpass =onlytrans =refcounttrans @*/
    01250         /*@=type@*/
    01251         srcrpmdir = _free(srcrpmdir);
    01252         fn = _free(fn);
    01253     }
    01254
    01255     return (rc ? RPMRC_FAIL : RPMRC_OK);
    01256 }