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