Main Page | Modules | Data Structures | File List | Data Fields | Globals | Related Pages

build/pack.c

Go to the documentation of this file.
00001 
00006 #include "system.h"
00007 
00008 #include <rpmio_internal.h>
00009 #include <rpmbuild.h>
00010 #include "buildio.h"
00011 
00012 #include "misc.h"
00013 #include "signature.h"
00014 #include "rpmlead.h"
00015 #include "debug.h"
00016 
00017 /*@-redecl@*/
00018 extern int _noDirTokens;
00019 /*@=redecl@*/
00020 
00021 /*@access StringBuf @*/ /* compared with NULL */
00022 /*@access TFI_t @*/     /* compared with NULL */
00023 /*@access Header @*/    /* compared with NULL */
00024 /*@access FD_t @*/      /* compared with NULL */
00025 /*@access CSA_t @*/
00026 
00029 static inline int genSourceRpmName(Spec spec)
00030         /*@modifies spec->sourceRpmName @*/
00031 {
00032     if (spec->sourceRpmName == NULL) {
00033         const char *name, *version, *release;
00034         char fileName[BUFSIZ];
00035 
00036         (void) headerNVR(spec->packages->header, &name, &version, &release);
00037         sprintf(fileName, "%s-%s-%s.%ssrc.rpm", name, version, release,
00038             spec->noSource ? "no" : "");
00039         spec->sourceRpmName = xstrdup(fileName);
00040     }
00041 
00042     return 0;
00043 }
00044 
00048 static int cpio_doio(FD_t fdo, /*@unused@*/ Header h, CSA_t csa,
00049                 const char * fmodeMacro)
00050         /*@globals rpmGlobalMacroContext,
00051                 fileSystem@*/
00052         /*@modifies fdo, csa, rpmGlobalMacroContext, fileSystem @*/
00053 {
00054     const char * rootDir = "/";
00055     rpmdb rpmdb = NULL;
00056     rpmTransactionSet ts = rpmtransCreateSet(rpmdb, rootDir);
00057     TFI_t fi = csa->cpioList;
00058     const char *failedFile = NULL;
00059     FD_t cfd;
00060     int rc, ec;
00061 
00062     {   const char *fmode = rpmExpand(fmodeMacro, NULL);
00063         if (!(fmode && fmode[0] == 'w'))
00064             fmode = xstrdup("w9.gzdio");
00065         /*@-nullpass@*/
00066         (void) Fflush(fdo);
00067         cfd = Fdopen(fdDup(Fileno(fdo)), fmode);
00068         /*@=nullpass@*/
00069         fmode = _free(fmode);
00070     }
00071     if (cfd == NULL)
00072         return 1;
00073 
00074     rc = fsmSetup(fi->fsm, FSM_PKGBUILD, ts, fi, cfd,
00075                 &csa->cpioArchiveSize, &failedFile);
00076     (void) Fclose(cfd);
00077     ec = fsmTeardown(fi->fsm);
00078     if (!rc) rc = ec;
00079 
00080     if (rc) {
00081         if (failedFile)
00082             rpmError(RPMERR_CPIO, _("create archive failed on file %s: %s\n"),
00083                 failedFile, cpioStrerror(rc));
00084         else
00085             rpmError(RPMERR_CPIO, _("create archive failed: %s\n"),
00086                 cpioStrerror(rc));
00087       rc = 1;
00088     }
00089 
00090     failedFile = _free(failedFile);
00091     ts = rpmtransFree(ts);
00092 
00093     return rc;
00094 }
00095 
00098 static int cpio_copy(FD_t fdo, CSA_t csa)
00099         /*@globals fileSystem@*/
00100         /*@modifies fdo, csa, fileSystem @*/
00101 {
00102     char buf[BUFSIZ];
00103     size_t nb;
00104 
00105     while((nb = Fread(buf, sizeof(buf[0]), sizeof(buf), csa->cpioFdIn)) > 0) {
00106         if (Fwrite(buf, sizeof(buf[0]), nb, fdo) != nb) {
00107             rpmError(RPMERR_CPIO, _("cpio_copy write failed: %s\n"),
00108                         Fstrerror(fdo));
00109             return 1;
00110         }
00111         csa->cpioArchiveSize += nb;
00112     }
00113     if (Ferror(csa->cpioFdIn)) {
00114         rpmError(RPMERR_CPIO, _("cpio_copy read failed: %s\n"),
00115                 Fstrerror(csa->cpioFdIn));
00116         return 1;
00117     }
00118     return 0;
00119 }
00120 
00123 static /*@only@*/ /*@null@*/ StringBuf addFileToTagAux(Spec spec,
00124                 const char * file, /*@only@*/ StringBuf sb)
00125         /*@globals rpmGlobalMacroContext,
00126                 fileSystem@*/
00127         /*@modifies rpmGlobalMacroContext, fileSystem @*/
00128 {
00129     char buf[BUFSIZ];
00130     const char * fn = buf;
00131     FILE * f;
00132     FD_t fd;
00133 
00134     /* XXX use rpmGenPath(rootdir, "%{_buildir}/%{_buildsubdir}/", file) */
00135     fn = rpmGetPath("%{_builddir}/", spec->buildSubdir, "/", file, NULL);
00136 
00137     fd = Fopen(fn, "r.ufdio");
00138     if (fn != buf) fn = _free(fn);
00139     if (fd == NULL || Ferror(fd)) {
00140         sb = freeStringBuf(sb);
00141         return NULL;
00142     }
00143     /*@-type@*/ /* FIX: cast? */
00144     if ((f = fdGetFp(fd)) != NULL)
00145     /*@=type@*/
00146     while (fgets(buf, sizeof(buf), f)) {
00147         /* XXX display fn in error msg */
00148         if (expandMacros(spec, spec->macros, buf, sizeof(buf))) {
00149             rpmError(RPMERR_BADSPEC, _("line: %s\n"), buf);
00150             sb = freeStringBuf(sb);
00151             break;
00152         }
00153         appendStringBuf(sb, buf);
00154     }
00155     (void) Fclose(fd);
00156 
00157     return sb;
00158 }
00159 
00162 static int addFileToTag(Spec spec, const char * file, Header h, int tag)
00163         /*@globals rpmGlobalMacroContext,
00164                 fileSystem@*/
00165         /*@modifies h, rpmGlobalMacroContext, fileSystem @*/
00166 {
00167     HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00168     StringBuf sb = newStringBuf();
00169     char *s;
00170 
00171     if (hge(h, tag, NULL, (void **)&s, NULL)) {
00172         appendLineStringBuf(sb, s);
00173         (void) headerRemoveEntry(h, tag);
00174     }
00175 
00176     if ((sb = addFileToTagAux(spec, file, sb)) == NULL)
00177         return 1;
00178     
00179     (void) headerAddEntry(h, tag, RPM_STRING_TYPE, getStringBuf(sb), 1);
00180 
00181     sb = freeStringBuf(sb);
00182     return 0;
00183 }
00184 
00187 static int addFileToArrayTag(Spec spec, const char *file, Header h, int tag)
00188         /*@globals rpmGlobalMacroContext,
00189                 fileSystem@*/
00190         /*@modifies h, rpmGlobalMacroContext, fileSystem @*/
00191 {
00192     StringBuf sb = newStringBuf();
00193     char *s;
00194 
00195     if ((sb = addFileToTagAux(spec, file, sb)) == NULL)
00196         return 1;
00197 
00198     s = getStringBuf(sb);
00199     (void) headerAddOrAppendEntry(h, tag, RPM_STRING_ARRAY_TYPE, &s, 1);
00200 
00201     sb = freeStringBuf(sb);
00202     return 0;
00203 }
00204 
00207 static int processScriptFiles(Spec spec, Package pkg)
00208         /*@globals rpmGlobalMacroContext,
00209                 fileSystem@*/
00210         /*@modifies pkg->header, rpmGlobalMacroContext, fileSystem @*/
00211 {
00212     struct TriggerFileEntry *p;
00213     
00214     if (pkg->preInFile) {
00215         if (addFileToTag(spec, pkg->preInFile, pkg->header, RPMTAG_PREIN)) {
00216             rpmError(RPMERR_BADFILENAME,
00217                      _("Could not open PreIn file: %s\n"), pkg->preInFile);
00218             return RPMERR_BADFILENAME;
00219         }
00220     }
00221     if (pkg->preUnFile) {
00222         if (addFileToTag(spec, pkg->preUnFile, pkg->header, RPMTAG_PREUN)) {
00223             rpmError(RPMERR_BADFILENAME,
00224                      _("Could not open PreUn file: %s\n"), pkg->preUnFile);
00225             return RPMERR_BADFILENAME;
00226         }
00227     }
00228     if (pkg->postInFile) {
00229         if (addFileToTag(spec, pkg->postInFile, pkg->header, RPMTAG_POSTIN)) {
00230             rpmError(RPMERR_BADFILENAME,
00231                      _("Could not open PostIn file: %s\n"), pkg->postInFile);
00232             return RPMERR_BADFILENAME;
00233         }
00234     }
00235     if (pkg->postUnFile) {
00236         if (addFileToTag(spec, pkg->postUnFile, pkg->header, RPMTAG_POSTUN)) {
00237             rpmError(RPMERR_BADFILENAME,
00238                      _("Could not open PostUn file: %s\n"), pkg->postUnFile);
00239             return RPMERR_BADFILENAME;
00240         }
00241     }
00242     if (pkg->verifyFile) {
00243         if (addFileToTag(spec, pkg->verifyFile, pkg->header,
00244                          RPMTAG_VERIFYSCRIPT)) {
00245             rpmError(RPMERR_BADFILENAME,
00246                      _("Could not open VerifyScript file: %s\n"), pkg->verifyFile);
00247             return RPMERR_BADFILENAME;
00248         }
00249     }
00250 
00251     for (p = pkg->triggerFiles; p != NULL; p = p->next) {
00252         (void) headerAddOrAppendEntry(pkg->header, RPMTAG_TRIGGERSCRIPTPROG,
00253                                RPM_STRING_ARRAY_TYPE, &(p->prog), 1);
00254         if (p->script) {
00255             (void) headerAddOrAppendEntry(pkg->header, RPMTAG_TRIGGERSCRIPTS,
00256                                    RPM_STRING_ARRAY_TYPE, &(p->script), 1);
00257         } else if (p->fileName) {
00258             if (addFileToArrayTag(spec, p->fileName, pkg->header,
00259                                   RPMTAG_TRIGGERSCRIPTS)) {
00260                 rpmError(RPMERR_BADFILENAME,
00261                          _("Could not open Trigger script file: %s\n"),
00262                          p->fileName);
00263                 return RPMERR_BADFILENAME;
00264             }
00265         } else {
00266             /* This is dumb.  When the header supports NULL string */
00267             /* this will go away.                                  */
00268             char *bull = "";
00269             (void) headerAddOrAppendEntry(pkg->header, RPMTAG_TRIGGERSCRIPTS,
00270                                    RPM_STRING_ARRAY_TYPE, &bull, 1);
00271         }
00272     }
00273 
00274     return 0;
00275 }
00276 
00277 int readRPM(const char *fileName, Spec *specp, struct rpmlead *lead,
00278                 Header *sigs, CSA_t csa)
00279 {
00280     FD_t fdi;
00281     Spec spec;
00282     rpmRC rc;
00283 
00284     fdi = (fileName != NULL)
00285         ? Fopen(fileName, "r.ufdio")
00286         : fdDup(STDIN_FILENO);
00287 
00288     if (fdi == NULL || Ferror(fdi)) {
00289         rpmError(RPMERR_BADMAGIC, _("readRPM: open %s: %s\n"),
00290                 (fileName ? fileName : "<stdin>"),
00291                 Fstrerror(fdi));
00292         if (fdi) (void) Fclose(fdi);
00293         return RPMERR_BADMAGIC;
00294     }
00295 
00296     /* Get copy of lead */
00297     /*@-sizeoftype@*/
00298     if ((rc = Fread(lead, sizeof(char), sizeof(*lead), fdi)) != sizeof(*lead)) {
00299         rpmError(RPMERR_BADMAGIC, _("readRPM: read %s: %s\n"),
00300                 (fileName ? fileName : "<stdin>"),
00301                 Fstrerror(fdi));
00302         return RPMERR_BADMAGIC;
00303     }
00304     /*@=sizeoftype@*/
00305 
00306     /* XXX FIXME: EPIPE on <stdin> */
00307     if (Fseek(fdi, 0, SEEK_SET) == -1) {
00308         rpmError(RPMERR_FSEEK, _("%s: Fseek failed: %s\n"),
00309                         (fileName ? fileName : "<stdin>"), Fstrerror(fdi));
00310         return RPMERR_FSEEK;
00311     }
00312 
00313     /* Reallocate build data structures */
00314     spec = newSpec();
00315     spec->packages = newPackage(spec);
00316 
00317     /* XXX the header just allocated will be allocated again */
00318     spec->packages->header = headerFree(spec->packages->header);
00319 
00320    /* Read the rpm lead, signatures, and header */
00321     rc = rpmReadPackageInfo(fdi, sigs, &spec->packages->header);
00322     switch (rc) {
00323     case RPMRC_BADMAGIC:
00324         rpmError(RPMERR_BADMAGIC, _("readRPM: %s is not an RPM package\n"),
00325                 (fileName ? fileName : "<stdin>"));
00326         return RPMERR_BADMAGIC;
00327     case RPMRC_OK:
00328         break;
00329     case RPMRC_FAIL:
00330     case RPMRC_BADSIZE:
00331     case RPMRC_SHORTREAD:
00332     default:
00333         rpmError(RPMERR_BADMAGIC, _("readRPM: reading header from %s\n"),
00334                 (fileName ? fileName : "<stdin>"));
00335         return RPMERR_BADMAGIC;
00336         /*@notreached@*/ break;
00337     }
00338 
00339     /*@-branchstate@*/
00340     if (specp)
00341         *specp = spec;
00342     else
00343         spec = freeSpec(spec);
00344     /*@=branchstate@*/
00345 
00346     if (csa != NULL)
00347         csa->cpioFdIn = fdi;
00348     else
00349         (void) Fclose(fdi);
00350 
00351     return 0;
00352 }
00353 
00354 /*@unchecked@*/
00355 static unsigned char header_magic[8] = {
00356         0x8e, 0xad, 0xe8, 0x01, 0x00, 0x00, 0x00, 0x00
00357 };
00358 
00359 #define RPMPKGVERSION_MIN       30004
00360 #define RPMPKGVERSION_MAX       40003
00361 /*@unchecked@*/
00362 static int rpmpkg_version = -1;
00363 
00364 static int rpmLeadVersion(void)
00365         /*@globals rpmpkg_version, rpmGlobalMacroContext @*/
00366         /*@modifies rpmpkg_version, rpmGlobalMacroContext @*/
00367 {
00368     int rpmlead_version;
00369 
00370     /* Intitialize packaging version from macro configuration. */
00371     if (rpmpkg_version < 0) {
00372         rpmpkg_version = rpmExpandNumeric("%{_package_version}");
00373         if (rpmpkg_version < RPMPKGVERSION_MIN)
00374             rpmpkg_version = RPMPKGVERSION_MIN;
00375         if (rpmpkg_version > RPMPKGVERSION_MAX)
00376             rpmpkg_version = RPMPKGVERSION_MAX;
00377     }
00378 
00379     rpmlead_version = rpmpkg_version / 10000;
00380     if (_noDirTokens || (rpmlead_version < 3 || rpmlead_version > 4))
00381         rpmlead_version = 3;
00382     return rpmlead_version;
00383 }
00384 
00385 int writeRPM(Header *hdrp, const char *fileName, int type,
00386                     CSA_t csa, char *passPhrase, const char **cookie)
00387 {
00388     FD_t fd = NULL;
00389     FD_t ifd = NULL;
00390     int count, sigtype;
00391     const char * sigtarget;
00392     const char * rpmio_flags = NULL;
00393     const char * sha1 = NULL;
00394     char *s;
00395     char buf[BUFSIZ];
00396     Header h;
00397     Header sig = NULL;
00398     int rc = 0;
00399 
00400     /* Transfer header reference form *hdrp to h. */
00401     h = headerLink(*hdrp);
00402     *hdrp = headerFree(*hdrp);
00403 
00404     if (Fileno(csa->cpioFdIn) < 0) {
00405         csa->cpioArchiveSize = 0;
00406         /* Add a bogus archive size to the Header */
00407         (void) headerAddEntry(h, RPMTAG_ARCHIVESIZE, RPM_INT32_TYPE,
00408                 &csa->cpioArchiveSize, 1);
00409     }
00410 
00411     /* Binary packages now have explicit Provides: name = version-release. */
00412     if (type == RPMLEAD_BINARY)
00413         providePackageNVR(h);
00414 
00415     /* Save payload information */
00416     /*@-branchstate@*/
00417     switch(type) {
00418     case RPMLEAD_SOURCE:
00419         rpmio_flags = rpmExpand("%{?_source_payload}", NULL);
00420         break;
00421     case RPMLEAD_BINARY:
00422         rpmio_flags = rpmExpand("%{?_binary_payload}", NULL);
00423         break;
00424     }
00425     /*@=branchstate@*/
00426     if (!(rpmio_flags && *rpmio_flags)) {
00427         rpmio_flags = _free(rpmio_flags);
00428         rpmio_flags = xstrdup("w9.gzdio");
00429     }
00430     s = strchr(rpmio_flags, '.');
00431     if (s) {
00432         (void) headerAddEntry(h, RPMTAG_PAYLOADFORMAT, RPM_STRING_TYPE, "cpio", 1);
00433         if (s[1] == 'g' && s[2] == 'z')
00434             (void) headerAddEntry(h, RPMTAG_PAYLOADCOMPRESSOR, RPM_STRING_TYPE,
00435                 "gzip", 1);
00436         if (s[1] == 'b' && s[2] == 'z') {
00437             (void) headerAddEntry(h, RPMTAG_PAYLOADCOMPRESSOR, RPM_STRING_TYPE,
00438                 "bzip2", 1);
00439             /* Add prereq on rpm version that understands bzip2 payloads */
00440             (void) rpmlibNeedsFeature(h, "PayloadIsBzip2", "3.0.5-1");
00441         }
00442         strcpy(buf, rpmio_flags);
00443         buf[s - rpmio_flags] = '\0';
00444         (void) headerAddEntry(h, RPMTAG_PAYLOADFLAGS, RPM_STRING_TYPE, buf+1, 1);
00445     }
00446 
00447     /* Create and add the cookie */
00448     if (cookie) {
00449         sprintf(buf, "%s %d", buildHost(), (int) (*getBuildTime()));
00450         *cookie = xstrdup(buf);
00451         (void) headerAddEntry(h, RPMTAG_COOKIE, RPM_STRING_TYPE, *cookie, 1);
00452     }
00453     
00454     /* Reallocate the header into one contiguous region. */
00455     h = headerReload(h, RPMTAG_HEADERIMMUTABLE);
00456     if (h == NULL) {    /* XXX can't happen */
00457         rc = RPMERR_RELOAD;
00458         rpmError(RPMERR_RELOAD, _("Unable to create immutable header region.\n"));
00459         goto exit;
00460     }
00461     /* Re-reference reallocated header. */
00462     *hdrp = headerLink(h);
00463 
00464     /*
00465      * Write the header+archive into a temp file so that the size of
00466      * archive (after compression) can be added to the header.
00467      */
00468     if (makeTempFile(NULL, &sigtarget, &fd)) {
00469         rc = RPMERR_CREATE;
00470         rpmError(RPMERR_CREATE, _("Unable to open temp file.\n"));
00471         goto exit;
00472     }
00473 
00474     if (headerWrite(fd, h, HEADER_MAGIC_YES)) {
00475         rc = RPMERR_NOSPACE;
00476         rpmError(RPMERR_NOSPACE, _("Unable to write temp header\n"));
00477     } else { /* Write the archive and get the size */
00478         if (csa->cpioList != NULL) {
00479             rc = cpio_doio(fd, h, csa, rpmio_flags);
00480         } else if (Fileno(csa->cpioFdIn) >= 0) {
00481             rc = cpio_copy(fd, csa);
00482         } else {
00483             rc = RPMERR_BADARG;
00484             rpmError(RPMERR_BADARG, _("Bad CSA data\n"));
00485         }
00486     }
00487     rpmio_flags = _free(rpmio_flags);
00488 
00489     if (rc)
00490         goto exit;
00491 
00492     /*
00493      * Set the actual archive size, and rewrite the header.
00494      * This used to be done using headerModifyEntry(), but now that headers
00495      * have regions, the value is scribbled directly into the header data
00496      * area. Some new scheme for adding the final archive size will have
00497      * to be devised if headerGetEntryMinMemory() ever changes to return
00498      * a pointer to memory not in the region, probably by appending
00499      * the archive size to the header region rather than including the
00500      * archive size within the header region.
00501      */
00502     if (Fileno(csa->cpioFdIn) < 0) {
00503         HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00504         int_32 * archiveSize;
00505         if (hge(h, RPMTAG_ARCHIVESIZE, NULL, (void *)&archiveSize, NULL))
00506             *archiveSize = csa->cpioArchiveSize;
00507     }
00508 
00509     (void) Fflush(fd);
00510     if (Fseek(fd, sizeof(header_magic), SEEK_SET) == -1) {
00511         rc = RPMERR_FSEEK;
00512         rpmError(RPMERR_FSEEK, _("%s: Fseek failed: %s\n"),
00513                         sigtarget, Fstrerror(fd));
00514     }
00515 
00516     fdInitDigest(fd, PGPHASHALGO_SHA1, 0);
00517     if (headerWrite(fd, h, HEADER_MAGIC_NO)) {
00518         rc = RPMERR_NOSPACE;
00519         rpmError(RPMERR_NOSPACE, _("Unable to write final header\n"));
00520     }
00521     (void) Fflush(fd);
00522     fdFiniDigest(fd, PGPHASHALGO_SHA1, (void **)&sha1, NULL, 1);
00523 
00524     (void) Fclose(fd);
00525     fd = NULL;
00526     (void) Unlink(fileName);
00527 
00528     if (rc)
00529         goto exit;
00530 
00531     /* Generate the signature */
00532     (void) fflush(stdout);
00533     sig = rpmNewSignature();
00534     (void) rpmAddSignature(sig, sigtarget, RPMSIGTAG_SIZE, passPhrase);
00535     (void) rpmAddSignature(sig, sigtarget, RPMSIGTAG_MD5, passPhrase);
00536     if ((sigtype = rpmLookupSignatureType(RPMLOOKUPSIG_QUERY)) > 0) {
00537         rpmMessage(RPMMESS_NORMAL, _("Generating signature: %d\n"), sigtype);
00538         (void) rpmAddSignature(sig, sigtarget, sigtype, passPhrase);
00539     }
00540     
00541     if (sha1) {
00542         (void) headerAddEntry(sig, RPMTAG_SHA1HEADER, RPM_STRING_TYPE, sha1, 1);
00543         sha1 = _free(sha1);
00544     }
00545 
00546     /* Reallocate the signature into one contiguous region. */
00547     sig = headerReload(sig, RPMTAG_HEADERSIGNATURES);
00548     if (sig == NULL) {  /* XXX can't happen */
00549         rc = RPMERR_RELOAD;
00550         rpmError(RPMERR_RELOAD, _("Unable to reload signature header.\n"));
00551         goto exit;
00552     }
00553 
00554     /* Open the output file */
00555     fd = Fopen(fileName, "w.ufdio");
00556     if (fd == NULL || Ferror(fd)) {
00557         rc = RPMERR_CREATE;
00558         rpmError(RPMERR_CREATE, _("Could not open %s: %s\n"),
00559                 fileName, Fstrerror(fd));
00560         goto exit;
00561     }
00562 
00563     /* Write the lead section into the package. */
00564     {   int archnum = -1;
00565         int osnum = -1;
00566         struct rpmlead lead;
00567 
00568         if (Fileno(csa->cpioFdIn) < 0) {
00569 #ifndef DYING
00570             rpmGetArchInfo(NULL, &archnum);
00571             rpmGetOsInfo(NULL, &osnum);
00572 #endif
00573         } else if (csa->lead != NULL) {
00574             archnum = csa->lead->archnum;
00575             osnum = csa->lead->osnum;
00576         }
00577 
00578         memset(&lead, 0, sizeof(lead));
00579         lead.major = rpmLeadVersion();
00580         lead.minor = 0;
00581         lead.type = type;
00582         lead.archnum = archnum;
00583         lead.osnum = osnum;
00584         lead.signature_type = RPMSIGTYPE_HEADERSIG;
00585 
00586         {   const char *name, *version, *release;
00587             (void) headerNVR(h, &name, &version, &release);
00588             sprintf(buf, "%s-%s-%s", name, version, release);
00589             strncpy(lead.name, buf, sizeof(lead.name));
00590         }
00591 
00592         if (writeLead(fd, &lead)) {
00593             rc = RPMERR_NOSPACE;
00594             rpmError(RPMERR_NOSPACE, _("Unable to write package: %s\n"),
00595                  Fstrerror(fd));
00596             goto exit;
00597         }
00598     }
00599 
00600     /* Write the signature section into the package. */
00601     rc = rpmWriteSignature(fd, sig);
00602     if (rc)
00603         goto exit;
00604 
00605     /* Append the header and archive */
00606     ifd = Fopen(sigtarget, "r.ufdio");
00607     if (ifd == NULL || Ferror(ifd)) {
00608         rc = RPMERR_READ;
00609         rpmError(RPMERR_READ, _("Unable to open sigtarget %s: %s\n"),
00610                 sigtarget, Fstrerror(ifd));
00611         goto exit;
00612     }
00613 
00614     /* Add signatures to header, and write header into the package. */
00615     {   Header nh = headerRead(ifd, HEADER_MAGIC_YES);
00616 
00617         if (nh == NULL) {
00618             rc = RPMERR_READ;
00619             rpmError(RPMERR_READ, _("Unable to read header from %s: %s\n"),
00620                         sigtarget, Fstrerror(ifd));
00621             goto exit;
00622         }
00623 
00624 #ifdef  NOTYET
00625         (void) headerMergeLegacySigs(nh, sig);
00626 #endif
00627 
00628         rc = headerWrite(fd, nh, HEADER_MAGIC_YES);
00629         nh = headerFree(nh);
00630 
00631         if (rc) {
00632             rc = RPMERR_NOSPACE;
00633             rpmError(RPMERR_NOSPACE, _("Unable to write header to %s: %s\n"),
00634                         fileName, Fstrerror(fd));
00635             goto exit;
00636         }
00637     }
00638         
00639     /* Write the payload into the package. */
00640     while ((count = Fread(buf, sizeof(buf[0]), sizeof(buf), ifd)) > 0) {
00641         if (count == -1) {
00642             rc = RPMERR_READ;
00643             rpmError(RPMERR_READ, _("Unable to read payload from %s: %s\n"),
00644                      sigtarget, Fstrerror(ifd));
00645             goto exit;
00646         }
00647         if (Fwrite(buf, sizeof(buf[0]), count, fd) != count) {
00648             rc = RPMERR_NOSPACE;
00649             rpmError(RPMERR_NOSPACE, _("Unable to write payload to %s: %s\n"),
00650                      fileName, Fstrerror(fd));
00651             goto exit;
00652         }
00653     }
00654     rc = 0;
00655 
00656 exit:
00657     sha1 = _free(sha1);
00658     h = headerFree(h);
00659     sig = rpmFreeSignature(sig);
00660     if (ifd) {
00661         (void) Fclose(ifd);
00662         ifd = NULL;
00663     }
00664     if (fd) {
00665         (void) Fclose(fd);
00666         fd = NULL;
00667     }
00668     if (sigtarget) {
00669         (void) Unlink(sigtarget);
00670         sigtarget = _free(sigtarget);
00671     }
00672 
00673     if (rc == 0)
00674         rpmMessage(RPMMESS_NORMAL, _("Wrote: %s\n"), fileName);
00675     else
00676         (void) Unlink(fileName);
00677 
00678     return rc;
00679 }
00680 
00681 /*@unchecked@*/
00682 static int_32 copyTags[] = {
00683     RPMTAG_CHANGELOGTIME,
00684     RPMTAG_CHANGELOGNAME,
00685     RPMTAG_CHANGELOGTEXT,
00686     0
00687 };
00688 
00689 int packageBinaries(Spec spec)
00690 {
00691     struct cpioSourceArchive_s csabuf;
00692     CSA_t csa = &csabuf;
00693     int rc;
00694     const char *errorString;
00695     Package pkg;
00696 
00697     for (pkg = spec->packages; pkg != NULL; pkg = pkg->next) {
00698         const char *fn;
00699 
00700         if (pkg->fileList == NULL)
00701             continue;
00702 
00703         if ((rc = processScriptFiles(spec, pkg)))
00704             return rc;
00705         
00706         if (spec->cookie) {
00707             (void) headerAddEntry(pkg->header, RPMTAG_COOKIE,
00708                            RPM_STRING_TYPE, spec->cookie, 1);
00709         }
00710 
00711         /* Copy changelog from src rpm */
00712         headerCopyTags(spec->packages->header, pkg->header, copyTags);
00713         
00714         (void) headerAddEntry(pkg->header, RPMTAG_RPMVERSION,
00715                        RPM_STRING_TYPE, VERSION, 1);
00716         (void) headerAddEntry(pkg->header, RPMTAG_BUILDHOST,
00717                        RPM_STRING_TYPE, buildHost(), 1);
00718         (void) headerAddEntry(pkg->header, RPMTAG_BUILDTIME,
00719                        RPM_INT32_TYPE, getBuildTime(), 1);
00720 
00721         providePackageNVR(pkg->header);
00722 
00723     {   const char * optflags = rpmExpand("%{optflags}", NULL);
00724         (void) headerAddEntry(pkg->header, RPMTAG_OPTFLAGS, RPM_STRING_TYPE,
00725                         optflags, 1);
00726         optflags = _free(optflags);
00727     }
00728 
00729         (void) genSourceRpmName(spec);
00730         (void) headerAddEntry(pkg->header, RPMTAG_SOURCERPM, RPM_STRING_TYPE,
00731                        spec->sourceRpmName, 1);
00732         
00733         {   const char *binFormat = rpmGetPath("%{_rpmfilename}", NULL);
00734             char *binRpm, *binDir;
00735             binRpm = headerSprintf(pkg->header, binFormat, rpmTagTable,
00736                                rpmHeaderFormats, &errorString);
00737             binFormat = _free(binFormat);
00738             if (binRpm == NULL) {
00739                 const char *name;
00740                 (void) headerNVR(pkg->header, &name, NULL, NULL);
00741                 rpmError(RPMERR_BADFILENAME, _("Could not generate output "
00742                      "filename for package %s: %s\n"), name, errorString);
00743                 return RPMERR_BADFILENAME;
00744             }
00745             fn = rpmGetPath("%{_rpmdir}/", binRpm, NULL);
00746             if ((binDir = strchr(binRpm, '/')) != NULL) {
00747                 struct stat st;
00748                 const char *dn;
00749                 *binDir = '\0';
00750                 dn = rpmGetPath("%{_rpmdir}/", binRpm, NULL);
00751                 if (Stat(dn, &st) < 0) {
00752                     switch(errno) {
00753                     case  ENOENT:
00754                         if (Mkdir(dn, 0755) == 0)
00755                             /*@switchbreak@*/ break;
00756                         /*@fallthrough@*/
00757                     default:
00758                         rpmError(RPMERR_BADFILENAME,_("cannot create %s: %s\n"),
00759                             dn, strerror(errno));
00760                         /*@switchbreak@*/ break;
00761                     }
00762                 }
00763                 dn = _free(dn);
00764             }
00765             binRpm = _free(binRpm);
00766         }
00767 
00768         memset(csa, 0, sizeof(*csa));
00769         csa->cpioArchiveSize = 0;
00770         /*@-type@*/ /* LCL: function typedefs */
00771         csa->cpioFdIn = fdNew("init (packageBinaries)");
00772         /*@-assignexpose -newreftrans@*/
00773 /*@i@*/ csa->cpioList = pkg->cpioList;
00774         /*@=assignexpose =newreftrans@*/
00775 
00776         rc = writeRPM(&pkg->header, fn, RPMLEAD_BINARY,
00777                     csa, spec->passPhrase, NULL);
00778         csa->cpioFdIn = fdFree(csa->cpioFdIn, "init (packageBinaries)");
00779         /*@=type@*/
00780         fn = _free(fn);
00781         if (rc)
00782             return rc;
00783     }
00784     
00785     return 0;
00786 }
00787 
00788 int packageSources(Spec spec)
00789 {
00790     struct cpioSourceArchive_s csabuf;
00791     CSA_t csa = &csabuf;
00792     int rc;
00793 
00794     /* Add some cruft */
00795     (void) headerAddEntry(spec->sourceHeader, RPMTAG_RPMVERSION,
00796                    RPM_STRING_TYPE, VERSION, 1);
00797     (void) headerAddEntry(spec->sourceHeader, RPMTAG_BUILDHOST,
00798                    RPM_STRING_TYPE, buildHost(), 1);
00799     (void) headerAddEntry(spec->sourceHeader, RPMTAG_BUILDTIME,
00800                    RPM_INT32_TYPE, getBuildTime(), 1);
00801 
00802     (void) genSourceRpmName(spec);
00803 
00804     spec->cookie = _free(spec->cookie);
00805     
00806     /* XXX this should be %_srpmdir */
00807     {   const char *fn = rpmGetPath("%{_srcrpmdir}/", spec->sourceRpmName,NULL);
00808 
00809         memset(csa, 0, sizeof(*csa));
00810         csa->cpioArchiveSize = 0;
00811         /*@-type@*/ /* LCL: function typedefs */
00812         csa->cpioFdIn = fdNew("init (packageSources)");
00813         /*@-assignexpose -newreftrans@*/
00814 /*@i@*/ csa->cpioList = spec->sourceCpioList;
00815         /*@=assignexpose =newreftrans@*/
00816 
00817         rc = writeRPM(&spec->sourceHeader, fn, RPMLEAD_SOURCE,
00818                 csa, spec->passPhrase, &(spec->cookie));
00819         csa->cpioFdIn = fdFree(csa->cpioFdIn, "init (packageSources)");
00820         /*@=type@*/
00821         fn = _free(fn);
00822     }
00823     return rc;
00824 }

Generated on Fri Jan 21 18:52:00 2005 for rpm by doxygen 1.3.6