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         if (!headerGetEntry(h, RPMTAG_BUILDHOST, NULL, (void **)&s, NULL))
00450             s = buildHost();
00451         sprintf(buf, "%s %d", s, (int) (*getBuildTime()));
00452         *cookie = xstrdup(buf);
00453         (void) headerAddEntry(h, RPMTAG_COOKIE, RPM_STRING_TYPE, *cookie, 1);
00454     }
00455     
00456     /* Reallocate the header into one contiguous region. */
00457     h = headerReload(h, RPMTAG_HEADERIMMUTABLE);
00458     if (h == NULL) {    /* XXX can't happen */
00459         rc = RPMERR_RELOAD;
00460         rpmError(RPMERR_RELOAD, _("Unable to create immutable header region.\n"));
00461         goto exit;
00462     }
00463     /* Re-reference reallocated header. */
00464     *hdrp = headerLink(h);
00465 
00466     /*
00467      * Write the header+archive into a temp file so that the size of
00468      * archive (after compression) can be added to the header.
00469      */
00470     if (makeTempFile(NULL, &sigtarget, &fd)) {
00471         rc = RPMERR_CREATE;
00472         rpmError(RPMERR_CREATE, _("Unable to open temp file.\n"));
00473         goto exit;
00474     }
00475 
00476     if (headerWrite(fd, h, HEADER_MAGIC_YES)) {
00477         rc = RPMERR_NOSPACE;
00478         rpmError(RPMERR_NOSPACE, _("Unable to write temp header\n"));
00479     } else { /* Write the archive and get the size */
00480         if (csa->cpioList != NULL) {
00481             rc = cpio_doio(fd, h, csa, rpmio_flags);
00482         } else if (Fileno(csa->cpioFdIn) >= 0) {
00483             rc = cpio_copy(fd, csa);
00484         } else {
00485             rc = RPMERR_BADARG;
00486             rpmError(RPMERR_BADARG, _("Bad CSA data\n"));
00487         }
00488     }
00489     rpmio_flags = _free(rpmio_flags);
00490 
00491     if (rc)
00492         goto exit;
00493 
00494     /*
00495      * Set the actual archive size, and rewrite the header.
00496      * This used to be done using headerModifyEntry(), but now that headers
00497      * have regions, the value is scribbled directly into the header data
00498      * area. Some new scheme for adding the final archive size will have
00499      * to be devised if headerGetEntryMinMemory() ever changes to return
00500      * a pointer to memory not in the region, probably by appending
00501      * the archive size to the header region rather than including the
00502      * archive size within the header region.
00503      */
00504     if (Fileno(csa->cpioFdIn) < 0) {
00505         HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00506         int_32 * archiveSize;
00507         if (hge(h, RPMTAG_ARCHIVESIZE, NULL, (void *)&archiveSize, NULL))
00508             *archiveSize = csa->cpioArchiveSize;
00509     }
00510 
00511     (void) Fflush(fd);
00512     if (Fseek(fd, 0L, SEEK_SET) == -1) {
00513         rc = RPMERR_FSEEK;
00514         rpmError(RPMERR_FSEEK, _("%s: Fseek failed: %s\n"),
00515                         sigtarget, Fstrerror(fd));
00516     }
00517 
00518     fdInitDigest(fd, PGPHASHALGO_SHA1, 0);
00519     if (headerWrite(fd, h, HEADER_MAGIC_YES)) {
00520         rc = RPMERR_NOSPACE;
00521         rpmError(RPMERR_NOSPACE, _("Unable to write final header\n"));
00522     }
00523     (void) Fflush(fd);
00524     fdFiniDigest(fd, PGPHASHALGO_SHA1, (void **)&sha1, NULL, 1);
00525 
00526     (void) Fclose(fd);
00527     fd = NULL;
00528     (void) Unlink(fileName);
00529 
00530     if (rc)
00531         goto exit;
00532 
00533     /* Generate the signature */
00534     (void) fflush(stdout);
00535     sig = rpmNewSignature();
00536     (void) rpmAddSignature(sig, sigtarget, RPMSIGTAG_SIZE, passPhrase);
00537     (void) rpmAddSignature(sig, sigtarget, RPMSIGTAG_MD5, passPhrase);
00538     if ((sigtype = rpmLookupSignatureType(RPMLOOKUPSIG_QUERY)) > 0) {
00539         rpmMessage(RPMMESS_NORMAL, _("Generating signature: %d\n"), sigtype);
00540         (void) rpmAddSignature(sig, sigtarget, sigtype, passPhrase);
00541     }
00542     
00543     if (sha1) {
00544         (void) headerAddEntry(sig, RPMTAG_SHA1HEADER, RPM_STRING_TYPE, sha1, 1);
00545         sha1 = _free(sha1);
00546     }
00547 
00548     /* Reallocate the signature into one contiguous region. */
00549     sig = headerReload(sig, RPMTAG_HEADERSIGNATURES);
00550     if (sig == NULL) {  /* XXX can't happen */
00551         rc = RPMERR_RELOAD;
00552         rpmError(RPMERR_RELOAD, _("Unable to reload signature header.\n"));
00553         goto exit;
00554     }
00555 
00556     /* Open the output file */
00557     fd = Fopen(fileName, "w.ufdio");
00558     if (fd == NULL || Ferror(fd)) {
00559         rc = RPMERR_CREATE;
00560         rpmError(RPMERR_CREATE, _("Could not open %s: %s\n"),
00561                 fileName, Fstrerror(fd));
00562         goto exit;
00563     }
00564 
00565     /* Write the lead section into the package. */
00566     {   int archnum = -1;
00567         int osnum = -1;
00568         struct rpmlead lead;
00569 
00570         if (Fileno(csa->cpioFdIn) < 0) {
00571 #ifndef DYING
00572             rpmGetArchInfo(NULL, &archnum);
00573             rpmGetOsInfo(NULL, &osnum);
00574 #endif
00575         } else if (csa->lead != NULL) {
00576             archnum = csa->lead->archnum;
00577             osnum = csa->lead->osnum;
00578         }
00579 
00580         memset(&lead, 0, sizeof(lead));
00581         lead.major = rpmLeadVersion();
00582         lead.minor = 0;
00583         lead.type = type;
00584         lead.archnum = archnum;
00585         lead.osnum = osnum;
00586         lead.signature_type = RPMSIGTYPE_HEADERSIG;
00587 
00588         {   const char *name, *version, *release;
00589             (void) headerNVR(h, &name, &version, &release);
00590             sprintf(buf, "%s-%s-%s", name, version, release);
00591             strncpy(lead.name, buf, sizeof(lead.name));
00592         }
00593 
00594         if (writeLead(fd, &lead)) {
00595             rc = RPMERR_NOSPACE;
00596             rpmError(RPMERR_NOSPACE, _("Unable to write package: %s\n"),
00597                  Fstrerror(fd));
00598             goto exit;
00599         }
00600     }
00601 
00602     /* Write the signature section into the package. */
00603     rc = rpmWriteSignature(fd, sig);
00604     if (rc)
00605         goto exit;
00606 
00607     /* Append the header and archive */
00608     ifd = Fopen(sigtarget, "r.ufdio");
00609     if (ifd == NULL || Ferror(ifd)) {
00610         rc = RPMERR_READ;
00611         rpmError(RPMERR_READ, _("Unable to open sigtarget %s: %s\n"),
00612                 sigtarget, Fstrerror(ifd));
00613         goto exit;
00614     }
00615 
00616     /* Add signatures to header, and write header into the package. */
00617     {   Header nh = headerRead(ifd, HEADER_MAGIC_YES);
00618 
00619         if (nh == NULL) {
00620             rc = RPMERR_READ;
00621             rpmError(RPMERR_READ, _("Unable to read header from %s: %s\n"),
00622                         sigtarget, Fstrerror(ifd));
00623             goto exit;
00624         }
00625 
00626 #ifdef  NOTYET
00627         (void) headerMergeLegacySigs(nh, sig);
00628 #endif
00629 
00630         rc = headerWrite(fd, nh, HEADER_MAGIC_YES);
00631         nh = headerFree(nh);
00632 
00633         if (rc) {
00634             rc = RPMERR_NOSPACE;
00635             rpmError(RPMERR_NOSPACE, _("Unable to write header to %s: %s\n"),
00636                         fileName, Fstrerror(fd));
00637             goto exit;
00638         }
00639     }
00640         
00641     /* Write the payload into the package. */
00642     while ((count = Fread(buf, sizeof(buf[0]), sizeof(buf), ifd)) > 0) {
00643         if (count == -1) {
00644             rc = RPMERR_READ;
00645             rpmError(RPMERR_READ, _("Unable to read payload from %s: %s\n"),
00646                      sigtarget, Fstrerror(ifd));
00647             goto exit;
00648         }
00649         if (Fwrite(buf, sizeof(buf[0]), count, fd) != count) {
00650             rc = RPMERR_NOSPACE;
00651             rpmError(RPMERR_NOSPACE, _("Unable to write payload to %s: %s\n"),
00652                      fileName, Fstrerror(fd));
00653             goto exit;
00654         }
00655     }
00656     rc = 0;
00657 
00658 exit:
00659     sha1 = _free(sha1);
00660     h = headerFree(h);
00661     sig = rpmFreeSignature(sig);
00662     if (ifd) {
00663         (void) Fclose(ifd);
00664         ifd = NULL;
00665     }
00666     if (fd) {
00667         (void) Fclose(fd);
00668         fd = NULL;
00669     }
00670     if (sigtarget) {
00671         (void) Unlink(sigtarget);
00672         sigtarget = _free(sigtarget);
00673     }
00674 
00675     if (rc == 0)
00676         rpmMessage(RPMMESS_NORMAL, _("Wrote: %s\n"), fileName);
00677     else
00678         (void) Unlink(fileName);
00679 
00680     return rc;
00681 }
00682 
00683 /*@unchecked@*/
00684 static int_32 copyTags[] = {
00685     RPMTAG_CHANGELOGTIME,
00686     RPMTAG_CHANGELOGNAME,
00687     RPMTAG_CHANGELOGTEXT,
00688     0
00689 };
00690 
00691 int packageBinaries(Spec spec)
00692 {
00693     struct cpioSourceArchive_s csabuf;
00694     CSA_t csa = &csabuf;
00695     int rc;
00696     const char *errorString;
00697     Package pkg;
00698 
00699     for (pkg = spec->packages; pkg != NULL; pkg = pkg->next) {
00700         const char *fn;
00701 
00702         if (pkg->fileList == NULL)
00703             continue;
00704 
00705         if ((rc = processScriptFiles(spec, pkg)))
00706             return rc;
00707         
00708         if (spec->cookie) {
00709             (void) headerAddEntry(pkg->header, RPMTAG_COOKIE,
00710                            RPM_STRING_TYPE, spec->cookie, 1);
00711         }
00712 
00713         /* Copy changelog from src rpm */
00714         headerCopyTags(spec->packages->header, pkg->header, copyTags);
00715         
00716         (void) headerAddEntry(pkg->header, RPMTAG_RPMVERSION,
00717                        RPM_STRING_TYPE, VERSION, 1);
00718         if (!headerIsEntry(pkg->header, RPMTAG_BUILDHOST))
00719             (void) headerAddEntry(pkg->header, RPMTAG_BUILDHOST,
00720                        RPM_STRING_TYPE, buildHost(), 1);
00721         (void) headerAddEntry(pkg->header, RPMTAG_BUILDTIME,
00722                        RPM_INT32_TYPE, getBuildTime(), 1);
00723 
00724         providePackageNVR(pkg->header);
00725 
00726     {   const char * optflags = rpmExpand("%{optflags}", NULL);
00727         (void) headerAddEntry(pkg->header, RPMTAG_OPTFLAGS, RPM_STRING_TYPE,
00728                         optflags, 1);
00729         optflags = _free(optflags);
00730     }
00731 
00732         (void) genSourceRpmName(spec);
00733         (void) headerAddEntry(pkg->header, RPMTAG_SOURCERPM, RPM_STRING_TYPE,
00734                        spec->sourceRpmName, 1);
00735         
00736         {   const char *binFormat = rpmGetPath("%{_rpmfilename}", NULL);
00737             char *binRpm, *binDir;
00738             binRpm = headerSprintf(pkg->header, binFormat, rpmTagTable,
00739                                rpmHeaderFormats, &errorString);
00740             binFormat = _free(binFormat);
00741             if (binRpm == NULL) {
00742                 const char *name;
00743                 (void) headerNVR(pkg->header, &name, NULL, NULL);
00744                 rpmError(RPMERR_BADFILENAME, _("Could not generate output "
00745                      "filename for package %s: %s\n"), name, errorString);
00746                 return RPMERR_BADFILENAME;
00747             }
00748             fn = rpmGetPath("%{_rpmdir}/", binRpm, NULL);
00749             if ((binDir = strchr(binRpm, '/')) != NULL) {
00750                 struct stat st;
00751                 const char *dn;
00752                 *binDir = '\0';
00753                 dn = rpmGetPath("%{_rpmdir}/", binRpm, NULL);
00754                 if (Stat(dn, &st) < 0) {
00755                     switch(errno) {
00756                     case  ENOENT:
00757                         if (MkdirP(dn, 0755) == 0)
00758                             /*@switchbreak@*/ break;
00759                         /*@fallthrough@*/
00760                     default:
00761                         rpmError(RPMERR_BADFILENAME,_("cannot create %s: %s\n"),
00762                             dn, strerror(errno));
00763                         /*@switchbreak@*/ break;
00764                     }
00765                 }
00766                 dn = _free(dn);
00767             }
00768             binRpm = _free(binRpm);
00769         }
00770 
00771         memset(csa, 0, sizeof(*csa));
00772         csa->cpioArchiveSize = 0;
00773         /*@-type@*/ /* LCL: function typedefs */
00774         csa->cpioFdIn = fdNew("init (packageBinaries)");
00775         /*@-assignexpose -newreftrans@*/
00776 /*@i@*/ csa->cpioList = pkg->cpioList;
00777         /*@=assignexpose =newreftrans@*/
00778 
00779         rc = writeRPM(&pkg->header, fn, RPMLEAD_BINARY,
00780                     csa, spec->passPhrase, NULL);
00781         csa->cpioFdIn = fdFree(csa->cpioFdIn, "init (packageBinaries)");
00782         /*@=type@*/
00783         fn = _free(fn);
00784         if (rc)
00785             return rc;
00786     }
00787     
00788     return 0;
00789 }
00790 
00791 int packageSources(Spec spec)
00792 {
00793     struct cpioSourceArchive_s csabuf;
00794     CSA_t csa = &csabuf;
00795     int rc;
00796 
00797     /* Add some cruft */
00798     (void) headerAddEntry(spec->sourceHeader, RPMTAG_RPMVERSION,
00799                    RPM_STRING_TYPE, VERSION, 1);
00800     if (!headerIsEntry(spec->sourceHeader, RPMTAG_BUILDHOST))
00801         (void) headerAddEntry(spec->sourceHeader, RPMTAG_BUILDHOST,
00802                    RPM_STRING_TYPE, buildHost(), 1);
00803     (void) headerAddEntry(spec->sourceHeader, RPMTAG_BUILDTIME,
00804                    RPM_INT32_TYPE, getBuildTime(), 1);
00805 
00806     (void) genSourceRpmName(spec);
00807 
00808     spec->cookie = _free(spec->cookie);
00809     
00810     /* XXX this should be %_srpmdir */
00811     {   const char *fn = rpmGetPath("%{_srcrpmdir}/", spec->sourceRpmName,NULL);
00812 
00813         memset(csa, 0, sizeof(*csa));
00814         csa->cpioArchiveSize = 0;
00815         /*@-type@*/ /* LCL: function typedefs */
00816         csa->cpioFdIn = fdNew("init (packageSources)");
00817         /*@-assignexpose -newreftrans@*/
00818 /*@i@*/ csa->cpioList = spec->sourceCpioList;
00819         /*@=assignexpose =newreftrans@*/
00820 
00821         rc = writeRPM(&spec->sourceHeader, fn, RPMLEAD_SOURCE,
00822                 csa, spec->passPhrase, &(spec->cookie));
00823         csa->cpioFdIn = fdFree(csa->cpioFdIn, "init (packageSources)");
00824         /*@=type@*/
00825         fn = _free(fn);
00826     }
00827     return rc;
00828 }

Generated on Sun Feb 2 23:31:59 2003 for rpm by doxygen1.2.18