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

Generated on Wed Mar 13 15:34:46 2002 for rpm by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002