00001
00006 #include "system.h"
00007
00008 #include <rpmio_internal.h>
00009 #define _RPMEVR_INTERNAL
00010 #include <rpmbuild.h>
00011
00012 #include "rpmps.h"
00013
00014 #include "cpio.h"
00015 #include "fsm.h"
00016 #include "psm.h"
00017
00018 #define _RPMFI_INTERNAL
00019 #include "rpmfi.h"
00020 #include "rpmts.h"
00021
00022 #include "buildio.h"
00023
00024 #include "signature.h"
00025 #include "rpmlead.h"
00026 #include "debug.h"
00027
00028
00029
00030
00031
00032
00033
00034
00037 static inline int genSourceRpmName(Spec spec)
00038
00039 {
00040 if (spec->sourceRpmName == NULL) {
00041 const char *name, *version, *release;
00042 char fileName[BUFSIZ];
00043
00044 (void) headerNVR(spec->packages->header, &name, &version, &release);
00045 sprintf(fileName, "%s-%s-%s.%ssrc.rpm", name, version, release,
00046 spec->noSource ? "no" : "");
00047 spec->sourceRpmName = xstrdup(fileName);
00048 }
00049
00050 return 0;
00051 }
00052
00056 static int cpio_doio(FD_t fdo, Header h, CSA_t csa,
00057 const char * payload_format, const char * fmodeMacro)
00058
00059
00060
00061 {
00062 rpmts ts = rpmtsCreate();
00063 rpmfi fi = csa->cpioList;
00064 const char *failedFile = NULL;
00065 FD_t cfd;
00066 int rc, ec;
00067
00068
00069 { const char *fmode = rpmExpand(fmodeMacro, NULL);
00070 if (!(fmode && fmode[0] == 'w'))
00071 fmode = xstrdup("w9.gzdio");
00072
00073 (void) Fflush(fdo);
00074 cfd = Fdopen(fdDup(Fileno(fdo)), fmode);
00075
00076 fmode = _free(fmode);
00077 }
00078
00079 if (cfd == NULL)
00080 return 1;
00081
00082 rc = fsmSetup(fi->fsm, FSM_PKGBUILD, payload_format, ts, fi, cfd,
00083 &csa->cpioArchiveSize, &failedFile);
00084 (void) Fclose(cfd);
00085 ec = fsmTeardown(fi->fsm);
00086 if (!rc) rc = ec;
00087
00088 if (rc) {
00089 if (failedFile)
00090 rpmError(RPMERR_CPIO, _("create archive failed on file %s: %s\n"),
00091 failedFile, cpioStrerror(rc));
00092 else
00093 rpmError(RPMERR_CPIO, _("create archive failed: %s\n"),
00094 cpioStrerror(rc));
00095 rc = 1;
00096 }
00097
00098 failedFile = _free(failedFile);
00099 ts = rpmtsFree(ts);
00100
00101 return rc;
00102 }
00103
00106 static int cpio_copy(FD_t fdo, CSA_t csa)
00107
00108
00109 {
00110 char buf[BUFSIZ];
00111 size_t nb;
00112
00113 while((nb = Fread(buf, sizeof(buf[0]), sizeof(buf), csa->cpioFdIn)) > 0) {
00114 if (Fwrite(buf, sizeof(buf[0]), nb, fdo) != nb) {
00115 rpmError(RPMERR_CPIO, _("cpio_copy write failed: %s\n"),
00116 Fstrerror(fdo));
00117 return 1;
00118 }
00119 csa->cpioArchiveSize += nb;
00120 }
00121 if (Ferror(csa->cpioFdIn)) {
00122 rpmError(RPMERR_CPIO, _("cpio_copy read failed: %s\n"),
00123 Fstrerror(csa->cpioFdIn));
00124 return 1;
00125 }
00126 return 0;
00127 }
00128
00131 static StringBuf addFileToTagAux(Spec spec,
00132 const char * file, StringBuf sb)
00133
00134
00135 {
00136 char buf[BUFSIZ];
00137 const char * fn = buf;
00138 FILE * f;
00139 FD_t fd;
00140
00141 fn = rpmGetPath("%{_builddir}/%{?buildsubdir:%{buildsubdir}/}", file, NULL);
00142
00143 fd = Fopen(fn, "r");
00144 if (fn != buf) fn = _free(fn);
00145 if (fd == NULL || Ferror(fd)) {
00146 sb = freeStringBuf(sb);
00147 return NULL;
00148 }
00149
00150 if ((f = fdGetFp(fd)) != NULL)
00151
00152 while (fgets(buf, sizeof(buf), f)) {
00153
00154 if (expandMacros(spec, spec->macros, buf, sizeof(buf))) {
00155 rpmError(RPMERR_BADSPEC, _("line: %s\n"), buf);
00156 sb = freeStringBuf(sb);
00157 break;
00158 }
00159 appendStringBuf(sb, buf);
00160 }
00161 (void) Fclose(fd);
00162
00163 return sb;
00164 }
00165
00168 static int addFileToTag(Spec spec, const char * file, Header h, int tag)
00169
00170
00171 {
00172 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00173 StringBuf sb = newStringBuf();
00174 char *s;
00175
00176 if (hge(h, tag, NULL, (void **)&s, NULL)) {
00177 appendLineStringBuf(sb, s);
00178 (void) headerRemoveEntry(h, tag);
00179 }
00180
00181 if ((sb = addFileToTagAux(spec, file, sb)) == NULL)
00182 return 1;
00183
00184 (void) headerAddEntry(h, tag, RPM_STRING_TYPE, getStringBuf(sb), 1);
00185
00186 sb = freeStringBuf(sb);
00187 return 0;
00188 }
00189
00192 static int addFileToArrayTag(Spec spec, const char *file, Header h, int tag)
00193
00194
00195 {
00196 StringBuf sb = newStringBuf();
00197 char *s;
00198
00199 if ((sb = addFileToTagAux(spec, file, sb)) == NULL)
00200 return 1;
00201
00202 s = getStringBuf(sb);
00203 (void) headerAddOrAppendEntry(h, tag, RPM_STRING_ARRAY_TYPE, &s, 1);
00204
00205 sb = freeStringBuf(sb);
00206 return 0;
00207 }
00208
00209 int processScriptFiles(Spec spec, Package pkg)
00210
00211
00212
00213 {
00214 struct TriggerFileEntry *p;
00215
00216 if (pkg->preInFile) {
00217 if (addFileToTag(spec, pkg->preInFile, pkg->header, RPMTAG_PREIN)) {
00218 rpmError(RPMERR_BADFILENAME,
00219 _("Could not open PreIn file: %s\n"), pkg->preInFile);
00220 return RPMERR_BADFILENAME;
00221 }
00222 }
00223 if (pkg->preUnFile) {
00224 if (addFileToTag(spec, pkg->preUnFile, pkg->header, RPMTAG_PREUN)) {
00225 rpmError(RPMERR_BADFILENAME,
00226 _("Could not open PreUn file: %s\n"), pkg->preUnFile);
00227 return RPMERR_BADFILENAME;
00228 }
00229 }
00230 if (pkg->preTransFile) {
00231 if (addFileToTag(spec, pkg->preTransFile, pkg->header, RPMTAG_PRETRANS)) {
00232 rpmError(RPMERR_BADFILENAME,
00233 _("Could not open PreIn file: %s\n"), pkg->preTransFile);
00234 return RPMERR_BADFILENAME;
00235 }
00236 }
00237 if (pkg->postInFile) {
00238 if (addFileToTag(spec, pkg->postInFile, pkg->header, RPMTAG_POSTIN)) {
00239 rpmError(RPMERR_BADFILENAME,
00240 _("Could not open PostIn file: %s\n"), pkg->postInFile);
00241 return RPMERR_BADFILENAME;
00242 }
00243 }
00244 if (pkg->postUnFile) {
00245 if (addFileToTag(spec, pkg->postUnFile, pkg->header, RPMTAG_POSTUN)) {
00246 rpmError(RPMERR_BADFILENAME,
00247 _("Could not open PostUn file: %s\n"), pkg->postUnFile);
00248 return RPMERR_BADFILENAME;
00249 }
00250 }
00251 if (pkg->postTransFile) {
00252 if (addFileToTag(spec, pkg->postTransFile, pkg->header, RPMTAG_POSTTRANS)) {
00253 rpmError(RPMERR_BADFILENAME,
00254 _("Could not open PostUn file: %s\n"), pkg->postTransFile);
00255 return RPMERR_BADFILENAME;
00256 }
00257 }
00258 if (pkg->verifyFile) {
00259 if (addFileToTag(spec, pkg->verifyFile, pkg->header,
00260 RPMTAG_VERIFYSCRIPT)) {
00261 rpmError(RPMERR_BADFILENAME,
00262 _("Could not open VerifyScript file: %s\n"), pkg->verifyFile);
00263 return RPMERR_BADFILENAME;
00264 }
00265 }
00266
00267 for (p = pkg->triggerFiles; p != NULL; p = p->next) {
00268 (void) headerAddOrAppendEntry(pkg->header, RPMTAG_TRIGGERSCRIPTPROG,
00269 RPM_STRING_ARRAY_TYPE, &(p->prog), 1);
00270 if (p->script) {
00271 (void) headerAddOrAppendEntry(pkg->header, RPMTAG_TRIGGERSCRIPTS,
00272 RPM_STRING_ARRAY_TYPE, &(p->script), 1);
00273 } else if (p->fileName) {
00274 if (addFileToArrayTag(spec, p->fileName, pkg->header,
00275 RPMTAG_TRIGGERSCRIPTS)) {
00276 rpmError(RPMERR_BADFILENAME,
00277 _("Could not open Trigger script file: %s\n"),
00278 p->fileName);
00279 return RPMERR_BADFILENAME;
00280 }
00281 } else {
00282
00283
00284 char *bull = "";
00285 (void) headerAddOrAppendEntry(pkg->header, RPMTAG_TRIGGERSCRIPTS,
00286 RPM_STRING_ARRAY_TYPE, &bull, 1);
00287 }
00288 }
00289
00290 return 0;
00291 }
00292
00293
00294 int readRPM(const char *fileName, Spec *specp, struct rpmlead *lead,
00295 Header *sigs, CSA_t csa)
00296 {
00297 FD_t fdi;
00298 Spec spec;
00299 rpmRC rc;
00300
00301 fdi = (fileName != NULL)
00302 ? Fopen(fileName, "r")
00303 : fdDup(STDIN_FILENO);
00304
00305 if (fdi == NULL || Ferror(fdi)) {
00306 rpmError(RPMERR_BADMAGIC, _("readRPM: open %s: %s\n"),
00307 (fileName ? fileName : "<stdin>"),
00308 Fstrerror(fdi));
00309 if (fdi) (void) Fclose(fdi);
00310 return RPMERR_BADMAGIC;
00311 }
00312
00313
00314
00315 if ((rc = Fread(lead, sizeof(char), sizeof(*lead), fdi)) != sizeof(*lead)) {
00316 rpmError(RPMERR_BADMAGIC, _("readRPM: read %s: %s\n"),
00317 (fileName ? fileName : "<stdin>"),
00318 Fstrerror(fdi));
00319 return RPMERR_BADMAGIC;
00320 }
00321
00322
00323
00324 if (Fseek(fdi, 0, SEEK_SET) == -1) {
00325 rpmError(RPMERR_FSEEK, _("%s: Fseek failed: %s\n"),
00326 (fileName ? fileName : "<stdin>"), Fstrerror(fdi));
00327 return RPMERR_FSEEK;
00328 }
00329
00330
00331 spec = newSpec();
00332 spec->packages = newPackage(spec);
00333
00334
00335 spec->packages->header = headerFree(spec->packages->header);
00336
00337
00338 { rpmts ts = rpmtsCreate();
00339
00340
00341
00342 rc = rpmReadPackageFile(ts, fdi, "readRPM",
00343 &spec->packages->header);
00344
00345
00346 ts = rpmtsFree(ts);
00347
00348 if (sigs) *sigs = NULL;
00349 }
00350
00351 switch (rc) {
00352 case RPMRC_OK:
00353 case RPMRC_NOKEY:
00354 case RPMRC_NOTTRUSTED:
00355 break;
00356 case RPMRC_NOTFOUND:
00357 rpmError(RPMERR_BADMAGIC, _("readRPM: %s is not an RPM package\n"),
00358 (fileName ? fileName : "<stdin>"));
00359 return RPMERR_BADMAGIC;
00360 case RPMRC_FAIL:
00361 default:
00362 rpmError(RPMERR_BADMAGIC, _("readRPM: reading header from %s\n"),
00363 (fileName ? fileName : "<stdin>"));
00364 return RPMERR_BADMAGIC;
00365 break;
00366 }
00367
00368
00369 if (specp)
00370 *specp = spec;
00371 else
00372 spec = freeSpec(spec);
00373
00374
00375 if (csa != NULL)
00376 csa->cpioFdIn = fdi;
00377 else
00378 (void) Fclose(fdi);
00379
00380 return 0;
00381 }
00382
00383
00384 #ifdef DYING
00385
00386 static unsigned char header_magic[8] = {
00387 0x8e, 0xad, 0xe8, 0x01, 0x00, 0x00, 0x00, 0x00
00388 };
00389 #endif
00390
00391 #define RPMPKGVERSION_MIN 30004
00392 #define RPMPKGVERSION_MAX 40003
00393
00394 static int rpmpkg_version = -1;
00395
00396 static int rpmLeadVersion(void)
00397
00398
00399 {
00400 int rpmlead_version;
00401
00402
00403 if (rpmpkg_version < 0) {
00404 rpmpkg_version = rpmExpandNumeric("%{_package_version}");
00405 if (rpmpkg_version < RPMPKGVERSION_MIN)
00406 rpmpkg_version = RPMPKGVERSION_MIN;
00407 if (rpmpkg_version > RPMPKGVERSION_MAX)
00408 rpmpkg_version = RPMPKGVERSION_MAX;
00409 }
00410
00411 rpmlead_version = rpmpkg_version / 10000;
00412
00413 if (rpmlead_version < 3 || rpmlead_version > 4)
00414 rpmlead_version = 3;
00415 return rpmlead_version;
00416 }
00417
00418 void providePackageNVR(Header h)
00419 {
00420 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00421 HFD_t hfd = headerFreeData;
00422 const char *name, *version, *release;
00423 int_32 * epoch;
00424 const char *pEVR;
00425 char *p;
00426 int_32 pFlags = RPMSENSE_EQUAL;
00427 const char ** provides = NULL;
00428 const char ** providesEVR = NULL;
00429 rpmTagType pnt, pvt;
00430 int_32 * provideFlags = NULL;
00431 int providesCount;
00432 int i, xx;
00433 int bingo = 1;
00434
00435
00436 xx = headerNVR(h, &name, &version, &release);
00437 if (!(name && version && release))
00438 return;
00439 pEVR = p = alloca(21 + strlen(version) + 1 + strlen(release) + 1);
00440 *p = '\0';
00441 if (hge(h, RPMTAG_EPOCH, NULL, (void **) &epoch, NULL)) {
00442 sprintf(p, "%d:", *epoch);
00443 while (*p != '\0')
00444 p++;
00445 }
00446 (void) stpcpy( stpcpy( stpcpy(p, version) , "-") , release);
00447
00448
00449
00450
00451
00452 if (!hge(h, RPMTAG_PROVIDENAME, &pnt, (void **) &provides, &providesCount))
00453 goto exit;
00454
00455
00456
00457
00458 if (!hge(h, RPMTAG_PROVIDEVERSION, &pvt, (void **) &providesEVR, NULL)) {
00459 for (i = 0; i < providesCount; i++) {
00460 char * vdummy = "";
00461 int_32 fdummy = RPMSENSE_ANY;
00462 xx = headerAddOrAppendEntry(h, RPMTAG_PROVIDEVERSION, RPM_STRING_ARRAY_TYPE,
00463 &vdummy, 1);
00464 xx = headerAddOrAppendEntry(h, RPMTAG_PROVIDEFLAGS, RPM_INT32_TYPE,
00465 &fdummy, 1);
00466 }
00467 goto exit;
00468 }
00469
00470 xx = hge(h, RPMTAG_PROVIDEFLAGS, NULL, (void **) &provideFlags, NULL);
00471
00472
00473 if (provides && providesEVR && provideFlags)
00474 for (i = 0; i < providesCount; i++) {
00475 if (!(provides[i] && providesEVR[i]))
00476 continue;
00477 if (!(provideFlags[i] == RPMSENSE_EQUAL &&
00478 !strcmp(name, provides[i]) && !strcmp(pEVR, providesEVR[i])))
00479 continue;
00480 bingo = 0;
00481 break;
00482 }
00483
00484
00485 exit:
00486 provides = hfd(provides, pnt);
00487 providesEVR = hfd(providesEVR, pvt);
00488
00489 if (bingo) {
00490 xx = headerAddOrAppendEntry(h, RPMTAG_PROVIDENAME, RPM_STRING_ARRAY_TYPE,
00491 &name, 1);
00492 xx = headerAddOrAppendEntry(h, RPMTAG_PROVIDEFLAGS, RPM_INT32_TYPE,
00493 &pFlags, 1);
00494 xx = headerAddOrAppendEntry(h, RPMTAG_PROVIDEVERSION, RPM_STRING_ARRAY_TYPE,
00495 &pEVR, 1);
00496 }
00497 }
00498
00499
00500 int writeRPM(Header *hdrp, unsigned char ** pkgidp, const char *fileName,
00501 int type, CSA_t csa, char *passPhrase, const char **cookie)
00502 {
00503 FD_t fd = NULL;
00504 FD_t ifd = NULL;
00505 int_32 count, sigtag;
00506 const char * sigtarget;
00507 const char * rpmio_flags = NULL;
00508 const char * payload_format = NULL;
00509 const char * SHA1 = NULL;
00510 char *s;
00511 char buf[BUFSIZ];
00512 Header h;
00513 Header sig = NULL;
00514 int rc = 0;
00515
00516
00517 h = headerLink(*hdrp);
00518 *hdrp = headerFree(*hdrp);
00519
00520 if (pkgidp)
00521 *pkgidp = NULL;
00522
00523 #ifdef DYING
00524 if (Fileno(csa->cpioFdIn) < 0) {
00525 csa->cpioArchiveSize = 0;
00526
00527 (void) headerAddEntry(h, RPMTAG_ARCHIVESIZE, RPM_INT32_TYPE,
00528 &csa->cpioArchiveSize, 1);
00529 }
00530 #endif
00531
00532
00533
00534 switch(type) {
00535 case RPMLEAD_SOURCE:
00536 payload_format = rpmExpand("%{?_source_payload_format}", NULL);
00537 rpmio_flags = rpmExpand("%{?_source_payload}", NULL);
00538 break;
00539 case RPMLEAD_BINARY:
00540 payload_format = rpmExpand("%{?_binary_payload_format}", NULL);
00541 rpmio_flags = rpmExpand("%{?_binary_payload}", NULL);
00542 break;
00543 }
00544
00545 if (!(payload_format && *payload_format)) {
00546 payload_format = _free(payload_format);
00547 payload_format = xstrdup("cpio");
00548 }
00549 if (!(rpmio_flags && *rpmio_flags)) {
00550 rpmio_flags = _free(rpmio_flags);
00551 rpmio_flags = xstrdup("w9.gzdio");
00552 }
00553 s = strchr(rpmio_flags, '.');
00554 if (s) {
00555
00556 if (payload_format) {
00557 if (!strcmp(payload_format, "tar")
00558 || !strcmp(payload_format, "ustar")) {
00559
00560
00561 (void) rpmlibNeedsFeature(h, "PayloadIsUstar", "4.4.4-1");
00562 }
00563
00564 (void) headerAddEntry(h, RPMTAG_PAYLOADFORMAT, RPM_STRING_TYPE,
00565 payload_format, 1);
00566 }
00567
00568
00569 if (s[1] == 'g' && s[2] == 'z')
00570 (void) headerAddEntry(h, RPMTAG_PAYLOADCOMPRESSOR, RPM_STRING_TYPE,
00571 "gzip", 1);
00572 else if (s[1] == 'b' && s[2] == 'z')
00573 (void) headerAddEntry(h, RPMTAG_PAYLOADCOMPRESSOR, RPM_STRING_TYPE,
00574 "bzip2", 1);
00575 else if (s[1] == 'l' && s[2] == 'z') {
00576 (void) headerAddEntry(h, RPMTAG_PAYLOADCOMPRESSOR, RPM_STRING_TYPE,
00577 "lzma", 1);
00578 (void) rpmlibNeedsFeature(h, "PayloadIsLzma", "4.4.6-1");
00579 }
00580 strcpy(buf, rpmio_flags);
00581 buf[s - rpmio_flags] = '\0';
00582 (void) headerAddEntry(h, RPMTAG_PAYLOADFLAGS, RPM_STRING_TYPE, buf+1, 1);
00583 }
00584
00585
00586 if (cookie) {
00587 sprintf(buf, "%s %d", buildHost(), (int) (*getBuildTime()));
00588 *cookie = xstrdup(buf);
00589 (void) headerAddEntry(h, RPMTAG_COOKIE, RPM_STRING_TYPE, *cookie, 1);
00590 }
00591
00592
00593 h = headerReload(h, RPMTAG_HEADERIMMUTABLE);
00594 if (h == NULL) {
00595 rc = RPMERR_RELOAD;
00596 rpmError(RPMERR_RELOAD, _("Unable to create immutable header region.\n"));
00597 goto exit;
00598 }
00599
00600 *hdrp = headerLink(h);
00601
00602
00603
00604
00605
00606 sigtarget = NULL;
00607 if (makeTempFile(NULL, &sigtarget, &fd)) {
00608 rc = RPMERR_CREATE;
00609 rpmError(RPMERR_CREATE, _("Unable to open temp file.\n"));
00610 goto exit;
00611 }
00612
00613 fdInitDigest(fd, PGPHASHALGO_SHA1, 0);
00614 if (headerWrite(fd, h, HEADER_MAGIC_YES)) {
00615 rc = RPMERR_NOSPACE;
00616 rpmError(RPMERR_NOSPACE, _("Unable to write temp header\n"));
00617 } else {
00618 (void) Fflush(fd);
00619 fdFiniDigest(fd, PGPHASHALGO_SHA1, (void **)&SHA1, NULL, 1);
00620 if (csa->cpioList != NULL) {
00621 rc = cpio_doio(fd, h, csa, payload_format, rpmio_flags);
00622 } else if (Fileno(csa->cpioFdIn) >= 0) {
00623 rc = cpio_copy(fd, csa);
00624 } else {
00625 rc = RPMERR_BADARG;
00626 rpmError(RPMERR_BADARG, _("Bad CSA data\n"));
00627 }
00628 }
00629 rpmio_flags = _free(rpmio_flags);
00630 payload_format = _free(payload_format);
00631
00632 if (rc)
00633 goto exit;
00634
00635 #ifdef DYING
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646 if (Fileno(csa->cpioFdIn) < 0) {
00647 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00648 int_32 * archiveSize;
00649 if (hge(h, RPMTAG_ARCHIVESIZE, NULL, (void *)&archiveSize, NULL))
00650 *archiveSize = csa->cpioArchiveSize;
00651 }
00652
00653 (void) Fflush(fd);
00654 if (Fseek(fd, 0, SEEK_SET) == -1) {
00655 rc = RPMERR_FSEEK;
00656 rpmError(RPMERR_FSEEK, _("%s: Fseek failed: %s\n"),
00657 sigtarget, Fstrerror(fd));
00658 }
00659
00660 fdInitDigest(fd, PGPHASHALGO_SHA1, 0);
00661 if (headerWrite(fd, h, HEADER_MAGIC_YES)) {
00662 rc = RPMERR_NOSPACE;
00663 rpmError(RPMERR_NOSPACE, _("Unable to write final header\n"));
00664 }
00665 (void) Fflush(fd);
00666 fdFiniDigest(fd, PGPHASHALGO_SHA1, (void **)&SHA1, NULL, 1);
00667 #endif
00668
00669 (void) Fclose(fd);
00670 fd = NULL;
00671 (void) Unlink(fileName);
00672
00673 if (rc)
00674 goto exit;
00675
00676
00677 (void) fflush(stdout);
00678 sig = rpmNewSignature();
00679 (void) rpmAddSignature(sig, sigtarget, RPMSIGTAG_SIZE, passPhrase);
00680 (void) rpmAddSignature(sig, sigtarget, RPMSIGTAG_MD5, passPhrase);
00681
00682 if ((sigtag = rpmLookupSignatureType(RPMLOOKUPSIG_QUERY)) > 0) {
00683 rpmMessage(RPMMESS_NORMAL, _("Generating signature: %d\n"), sigtag);
00684 (void) rpmAddSignature(sig, sigtarget, sigtag, passPhrase);
00685 }
00686
00687 if (SHA1) {
00688 (void) headerAddEntry(sig, RPMSIGTAG_SHA1, RPM_STRING_TYPE, SHA1, 1);
00689 SHA1 = _free(SHA1);
00690 }
00691
00692 { int_32 payloadSize = csa->cpioArchiveSize;
00693 (void) headerAddEntry(sig, RPMSIGTAG_PAYLOADSIZE, RPM_INT32_TYPE,
00694 &payloadSize, 1);
00695 }
00696
00697
00698 sig = headerReload(sig, RPMTAG_HEADERSIGNATURES);
00699 if (sig == NULL) {
00700 rc = RPMERR_RELOAD;
00701 rpmError(RPMERR_RELOAD, _("Unable to reload signature header.\n"));
00702 goto exit;
00703 }
00704
00705
00706 fd = Fopen(fileName, "w");
00707 if (fd == NULL || Ferror(fd)) {
00708 rc = RPMERR_CREATE;
00709 rpmError(RPMERR_CREATE, _("Could not open %s: %s\n"),
00710 fileName, Fstrerror(fd));
00711 goto exit;
00712 }
00713
00714
00715 { int archnum = -1;
00716 int osnum = -1;
00717 struct rpmlead lead;
00718
00719 if (Fileno(csa->cpioFdIn) < 0) {
00720
00721 archnum = 0;
00722 osnum = 0;
00723 } else if (csa->lead != NULL) {
00724 archnum = csa->lead->archnum;
00725 osnum = csa->lead->osnum;
00726 }
00727
00728 memset(&lead, 0, sizeof(lead));
00729 lead.major = rpmLeadVersion();
00730 lead.minor = 0;
00731 lead.type = type;
00732 lead.archnum = archnum;
00733 lead.osnum = osnum;
00734 lead.signature_type = RPMSIGTYPE_HEADERSIG;
00735
00736 { const char *name, *version, *release;
00737 (void) headerNVR(h, &name, &version, &release);
00738 sprintf(buf, "%s-%s-%s", name, version, release);
00739 strncpy(lead.name, buf, sizeof(lead.name));
00740 }
00741
00742 if (writeLead(fd, &lead) != RPMRC_OK) {
00743 rc = RPMERR_NOSPACE;
00744 rpmError(RPMERR_NOSPACE, _("Unable to write package: %s\n"),
00745 Fstrerror(fd));
00746 goto exit;
00747 }
00748 }
00749
00750
00751 rc = rpmWriteSignature(fd, sig);
00752 if (rc)
00753 goto exit;
00754
00755
00756 ifd = Fopen(sigtarget, "r");
00757 if (ifd == NULL || Ferror(ifd)) {
00758 rc = RPMERR_READ;
00759 rpmError(RPMERR_READ, _("Unable to open sigtarget %s: %s\n"),
00760 sigtarget, Fstrerror(ifd));
00761 goto exit;
00762 }
00763
00764
00765
00766 { Header nh = headerRead(ifd, HEADER_MAGIC_YES);
00767
00768 if (nh == NULL) {
00769 rc = RPMERR_READ;
00770 rpmError(RPMERR_READ, _("Unable to read header from %s: %s\n"),
00771 sigtarget, Fstrerror(ifd));
00772 goto exit;
00773 }
00774
00775 #ifdef NOTYET
00776 (void) headerMergeLegacySigs(nh, sig);
00777 #endif
00778
00779 rc = headerWrite(fd, nh, HEADER_MAGIC_YES);
00780 nh = headerFree(nh);
00781
00782 if (rc) {
00783 rc = RPMERR_NOSPACE;
00784 rpmError(RPMERR_NOSPACE, _("Unable to write header to %s: %s\n"),
00785 fileName, Fstrerror(fd));
00786 goto exit;
00787 }
00788 }
00789
00790
00791 while ((count = Fread(buf, sizeof(buf[0]), sizeof(buf), ifd)) > 0) {
00792 if (count == -1) {
00793 rc = RPMERR_READ;
00794 rpmError(RPMERR_READ, _("Unable to read payload from %s: %s\n"),
00795 sigtarget, Fstrerror(ifd));
00796 goto exit;
00797 }
00798 if (Fwrite(buf, sizeof(buf[0]), count, fd) != count) {
00799 rc = RPMERR_NOSPACE;
00800 rpmError(RPMERR_NOSPACE, _("Unable to write payload to %s: %s\n"),
00801 fileName, Fstrerror(fd));
00802 goto exit;
00803 }
00804 }
00805 rc = 0;
00806
00807 exit:
00808 SHA1 = _free(SHA1);
00809 h = headerFree(h);
00810
00811
00812 if (sig != NULL && pkgidp != NULL) {
00813 int_32 tagType;
00814 unsigned char * MD5 = NULL;
00815 int_32 c;
00816 int xx;
00817 xx = headerGetEntry(sig, RPMSIGTAG_MD5, &tagType, (void **)&MD5, &c);
00818 if (tagType == RPM_BIN_TYPE && MD5 != NULL && c == 16)
00819 *pkgidp = MD5;
00820 }
00821
00822 sig = rpmFreeSignature(sig);
00823 if (ifd) {
00824 (void) Fclose(ifd);
00825 ifd = NULL;
00826 }
00827 if (fd) {
00828 (void) Fclose(fd);
00829 fd = NULL;
00830 }
00831 if (sigtarget) {
00832 (void) Unlink(sigtarget);
00833 sigtarget = _free(sigtarget);
00834 }
00835
00836 if (rc == 0)
00837 rpmMessage(RPMMESS_NORMAL, _("Wrote: %s\n"), fileName);
00838 else
00839 (void) Unlink(fileName);
00840
00841 return rc;
00842 }
00843
00844
00845
00846 static int_32 copyTags[] = {
00847 RPMTAG_CHANGELOGTIME,
00848 RPMTAG_CHANGELOGNAME,
00849 RPMTAG_CHANGELOGTEXT,
00850 0
00851 };
00852
00853
00854 int packageBinaries(Spec spec)
00855 {
00856 struct cpioSourceArchive_s csabuf;
00857 CSA_t csa = &csabuf;
00858 int rc;
00859 const char *errorString;
00860 Package pkg;
00861
00862 for (pkg = spec->packages; pkg != NULL; pkg = pkg->next) {
00863 const char *fn;
00864
00865 if (pkg->fileList == NULL)
00866 continue;
00867
00868 if (spec->cookie) {
00869 (void) headerAddEntry(pkg->header, RPMTAG_COOKIE,
00870 RPM_STRING_TYPE, spec->cookie, 1);
00871 }
00872
00873
00874 headerCopyTags(spec->packages->header, pkg->header, copyTags);
00875
00876 (void) headerAddEntry(pkg->header, RPMTAG_RPMVERSION,
00877 RPM_STRING_TYPE, VERSION, 1);
00878 (void) headerAddEntry(pkg->header, RPMTAG_BUILDHOST,
00879 RPM_STRING_TYPE, buildHost(), 1);
00880 (void) headerAddEntry(pkg->header, RPMTAG_BUILDTIME,
00881 RPM_INT32_TYPE, getBuildTime(), 1);
00882
00883 { const char * optflags = rpmExpand("%{optflags}", NULL);
00884 (void) headerAddEntry(pkg->header, RPMTAG_OPTFLAGS, RPM_STRING_TYPE,
00885 optflags, 1);
00886 optflags = _free(optflags);
00887 }
00888
00889 (void) genSourceRpmName(spec);
00890 (void) headerAddEntry(pkg->header, RPMTAG_SOURCERPM, RPM_STRING_TYPE,
00891 spec->sourceRpmName, 1);
00892 if (spec->sourcePkgId != NULL) {
00893 (void) headerAddEntry(pkg->header, RPMTAG_SOURCEPKGID, RPM_BIN_TYPE,
00894 spec->sourcePkgId, 16);
00895 }
00896
00897 { const char *binFormat = rpmGetPath("%{_rpmfilename}", NULL);
00898 char *binRpm, *binDir;
00899 binRpm = headerSprintf(pkg->header, binFormat, rpmTagTable,
00900 rpmHeaderFormats, &errorString);
00901 binFormat = _free(binFormat);
00902 if (binRpm == NULL) {
00903 const char *name;
00904 (void) headerNVR(pkg->header, &name, NULL, NULL);
00905 rpmError(RPMERR_BADFILENAME, _("Could not generate output "
00906 "filename for package %s: %s\n"), name, errorString);
00907 return RPMERR_BADFILENAME;
00908 }
00909 fn = rpmGetPath("%{_rpmdir}/", binRpm, NULL);
00910 if ((binDir = strchr(binRpm, '/')) != NULL) {
00911 struct stat st;
00912 const char *dn;
00913 *binDir = '\0';
00914 dn = rpmGetPath("%{_rpmdir}/", binRpm, NULL);
00915 if (Stat(dn, &st) < 0) {
00916 switch(errno) {
00917 case ENOENT:
00918 if (Mkdir(dn, 0755) == 0)
00919 break;
00920
00921 default:
00922 rpmError(RPMERR_BADFILENAME,_("cannot create %s: %s\n"),
00923 dn, strerror(errno));
00924 break;
00925 }
00926 }
00927 dn = _free(dn);
00928 }
00929 binRpm = _free(binRpm);
00930 }
00931
00932 memset(csa, 0, sizeof(*csa));
00933 csa->cpioArchiveSize = 0;
00934
00935 csa->cpioFdIn = fdNew("init (packageBinaries)");
00936
00937 csa->cpioList = rpmfiLink(pkg->cpioList, "packageBinaries");
00938
00939
00940 rc = writeRPM(&pkg->header, NULL, fn, RPMLEAD_BINARY,
00941 csa, spec->passPhrase, NULL);
00942
00943 csa->cpioList = rpmfiFree(csa->cpioList);
00944 csa->cpioFdIn = fdFree(csa->cpioFdIn, "init (packageBinaries)");
00945
00946 fn = _free(fn);
00947 if (rc)
00948 return rc;
00949 }
00950
00951 return 0;
00952 }
00953
00954
00955
00956 int packageSources(Spec spec)
00957 {
00958 struct cpioSourceArchive_s csabuf;
00959 CSA_t csa = &csabuf;
00960 int rc;
00961
00962
00963 (void) headerAddEntry(spec->sourceHeader, RPMTAG_RPMVERSION,
00964 RPM_STRING_TYPE, VERSION, 1);
00965 (void) headerAddEntry(spec->sourceHeader, RPMTAG_BUILDHOST,
00966 RPM_STRING_TYPE, buildHost(), 1);
00967 (void) headerAddEntry(spec->sourceHeader, RPMTAG_BUILDTIME,
00968 RPM_INT32_TYPE, getBuildTime(), 1);
00969
00970 (void) genSourceRpmName(spec);
00971
00972 spec->cookie = _free(spec->cookie);
00973
00974
00975 { const char *fn = rpmGetPath("%{_srcrpmdir}/", spec->sourceRpmName,NULL);
00976
00977 memset(csa, 0, sizeof(*csa));
00978 csa->cpioArchiveSize = 0;
00979
00980 csa->cpioFdIn = fdNew("init (packageSources)");
00981
00982 csa->cpioList = rpmfiLink(spec->sourceCpioList, "packageSources");
00983
00984
00985 spec->sourcePkgId = NULL;
00986 rc = writeRPM(&spec->sourceHeader, &spec->sourcePkgId, fn, RPMLEAD_SOURCE,
00987 csa, spec->passPhrase, &(spec->cookie));
00988
00989 csa->cpioList = rpmfiFree(csa->cpioList);
00990 csa->cpioFdIn = fdFree(csa->cpioFdIn, "init (packageSources)");
00991
00992 fn = _free(fn);
00993 }
00994 return rc;
00995 }
00996