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

Generated on Mon Nov 29 2010 05:18:41 for rpm by  doxygen 1.7.2