rpm  5.2.1
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 }