00001
00006 #include "system.h"
00007
00008 #include <rpmio_internal.h>
00009 #include <rpmlib.h>
00010 #include <rpmmacro.h>
00011 #include <rpmurl.h>
00012 #include <rpmlua.h>
00013
00014 #include "cpio.h"
00015 #include "fsm.h"
00016 #include "psm.h"
00017
00018 #define _RPMEVR_INTERNAL
00019 #include "rpmds.h"
00020
00021 #define _RPMFI_INTERNAL
00022 #include "rpmfi.h"
00023
00024 #define _RPMTE_INTERNAL
00025 #include "rpmte.h"
00026
00027 #define _RPMTS_INTERNAL
00028 #include "rpmts.h"
00029
00030 #include "rpmlead.h"
00031 #include "signature.h"
00032 #include "legacy.h"
00033 #include "misc.h"
00034 #include "rpmdb.h"
00035 #include "debug.h"
00036
00037 #define _PSM_DEBUG 0
00038
00039 int _psm_debug = _PSM_DEBUG;
00040
00041 int _psm_threads = 0;
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 int rpmVersionCompare(Header first, Header second)
00053 {
00054 const char * one, * two;
00055 int_32 * epochOne, * epochTwo;
00056 static int_32 zero = 0;
00057 int rc;
00058
00059 if (!headerGetEntry(first, RPMTAG_EPOCH, NULL, &epochOne, NULL))
00060 epochOne = &zero;
00061 if (!headerGetEntry(second, RPMTAG_EPOCH, NULL, &epochTwo, NULL))
00062 epochTwo = &zero;
00063
00064
00065 if (*epochOne < *epochTwo)
00066 return -1;
00067 else if (*epochOne > *epochTwo)
00068 return 1;
00069
00070
00071 rc = headerGetEntry(first, RPMTAG_VERSION, NULL, &one, NULL);
00072 rc = headerGetEntry(second, RPMTAG_VERSION, NULL, &two, NULL);
00073
00074 rc = rpmvercmp(one, two);
00075 if (rc)
00076 return rc;
00077
00078 rc = headerGetEntry(first, RPMTAG_RELEASE, NULL, &one, NULL);
00079 rc = headerGetEntry(second, RPMTAG_RELEASE, NULL, &two, NULL);
00080
00081 return rpmvercmp(one, two);
00082 }
00083
00089
00090 static rpmRC markReplacedFiles(const rpmpsm psm)
00091
00092
00093 {
00094 const rpmts ts = psm->ts;
00095 rpmfi fi = psm->fi;
00096 HGE_t hge = (HGE_t)fi->hge;
00097 sharedFileInfo replaced = fi->replaced;
00098 sharedFileInfo sfi;
00099 rpmdbMatchIterator mi;
00100 Header h;
00101 unsigned int * offsets;
00102 unsigned int prev;
00103 int num, xx;
00104
00105 if (!(rpmfiFC(fi) > 0 && fi->replaced))
00106 return RPMRC_OK;
00107
00108 num = prev = 0;
00109 for (sfi = replaced; sfi->otherPkg; sfi++) {
00110 if (prev && prev == sfi->otherPkg)
00111 continue;
00112 prev = sfi->otherPkg;
00113 num++;
00114 }
00115 if (num == 0)
00116 return RPMRC_OK;
00117
00118 offsets = alloca(num * sizeof(*offsets));
00119 offsets[0] = 0;
00120 num = prev = 0;
00121 for (sfi = replaced; sfi->otherPkg; sfi++) {
00122 if (prev && prev == sfi->otherPkg)
00123 continue;
00124 prev = sfi->otherPkg;
00125 offsets[num++] = sfi->otherPkg;
00126 }
00127
00128 mi = rpmtsInitIterator(ts, RPMDBI_PACKAGES, NULL, 0);
00129 xx = rpmdbAppendIterator(mi, offsets, num);
00130 xx = rpmdbSetIteratorRewrite(mi, 1);
00131
00132 sfi = replaced;
00133 while ((h = rpmdbNextIterator(mi)) != NULL) {
00134 char * secStates;
00135 int modified;
00136 int count;
00137
00138 modified = 0;
00139
00140 if (!hge(h, RPMTAG_FILESTATES, NULL, &secStates, &count))
00141 continue;
00142
00143 prev = rpmdbGetIteratorOffset(mi);
00144 num = 0;
00145 while (sfi->otherPkg && sfi->otherPkg == prev) {
00146 assert(sfi->otherFileNum < count);
00147 if (secStates[sfi->otherFileNum] != RPMFILE_STATE_REPLACED) {
00148 secStates[sfi->otherFileNum] = RPMFILE_STATE_REPLACED;
00149 if (modified == 0) {
00150
00151 modified = 1;
00152 xx = rpmdbSetIteratorModified(mi, modified);
00153 }
00154 num++;
00155 }
00156 sfi++;
00157 }
00158 }
00159 mi = rpmdbFreeIterator(mi);
00160
00161 return RPMRC_OK;
00162 }
00163
00164
00165 rpmRC rpmInstallSourcePackage(rpmts ts, FD_t fd,
00166 const char ** specFilePtr, const char ** cookie)
00167 {
00168 int scareMem = 1;
00169 rpmfi fi = NULL;
00170 const char * _sourcedir = NULL;
00171 const char * _specdir = NULL;
00172 const char * specFile = NULL;
00173 HGE_t hge;
00174 HFD_t hfd;
00175 Header h = NULL;
00176 struct rpmpsm_s psmbuf;
00177 rpmpsm psm = &psmbuf;
00178 int isSource;
00179 rpmRC rpmrc;
00180 int i;
00181
00182 memset(psm, 0, sizeof(*psm));
00183 psm->ts = rpmtsLink(ts, "InstallSourcePackage");
00184
00185 rpmrc = rpmReadPackageFile(ts, fd, "InstallSourcePackage", &h);
00186 switch (rpmrc) {
00187 case RPMRC_NOTTRUSTED:
00188 case RPMRC_NOKEY:
00189 case RPMRC_OK:
00190 break;
00191 default:
00192 goto exit;
00193 break;
00194 }
00195 if (h == NULL)
00196 goto exit;
00197
00198 rpmrc = RPMRC_OK;
00199
00200 isSource = (headerIsEntry(h, RPMTAG_SOURCERPM) == 0);
00201
00202 if (!isSource) {
00203 rpmError(RPMERR_NOTSRPM, _("source package expected, binary found\n"));
00204 rpmrc = RPMRC_FAIL;
00205 goto exit;
00206 }
00207
00208 (void) rpmtsAddInstallElement(ts, h, NULL, 0, NULL);
00209
00210 fi = rpmfiNew(ts, h, RPMTAG_BASENAMES, scareMem);
00211 h = headerFree(h);
00212
00213 if (fi == NULL) {
00214 rpmrc = RPMRC_FAIL;
00215 goto exit;
00216 }
00217
00218
00219 fi->te = rpmtsElement(ts, 0);
00220
00221 if (fi->te == NULL) {
00222 rpmrc = RPMRC_FAIL;
00223 goto exit;
00224 }
00225
00226 assert(fi->h != NULL);
00227 fi->te->h = headerLink(fi->h);
00228 fi->te->fd = fdLink(fd, "installSourcePackage");
00229 hge = fi->hge;
00230 hfd = fi->hfd;
00231
00232 (void) headerMacrosLoad(fi->h);
00233
00234 psm->fi = rpmfiLink(fi, NULL);
00235
00236 psm->te = fi->te;
00237
00238
00239 if (cookie) {
00240 *cookie = NULL;
00241 if (hge(fi->h, RPMTAG_COOKIE, NULL, (void **) cookie, NULL))
00242 *cookie = xstrdup(*cookie);
00243 }
00244
00245
00246 fi->fmapflags = _free(fi->fmapflags);
00247 fi->mapflags = CPIO_MAP_PATH | CPIO_MAP_MODE | CPIO_MAP_UID | CPIO_MAP_GID;
00248
00249 fi->uid = getuid();
00250 fi->gid = getgid();
00251 fi->astriplen = 0;
00252 fi->striplen = 0;
00253
00254 for (i = 0; i < fi->fc; i++)
00255 fi->actions[i] = FA_CREATE;
00256
00257 i = fi->fc;
00258
00259 if (fi->h != NULL) {
00260 rpmfiBuildFNames(fi->h, RPMTAG_BASENAMES, &fi->apath, NULL);
00261
00262 if (headerIsEntry(fi->h, RPMTAG_COOKIE))
00263 for (i = 0; i < fi->fc; i++)
00264 if (fi->fflags[i] & RPMFILE_SPECFILE) break;
00265 }
00266
00267 if (i == fi->fc) {
00268
00269 for (i = 0; i < fi->fc; i++) {
00270 const char * t = fi->apath[i];
00271 t += strlen(fi->apath[i]) - 5;
00272 if (!strcmp(t, ".spec")) break;
00273 }
00274 }
00275
00276 _sourcedir = rpmGenPath(rpmtsRootDir(ts), "%{_sourcedir}", "");
00277 rpmrc = rpmMkdirPath(_sourcedir, "sourcedir");
00278 if (rpmrc) {
00279 rpmrc = RPMRC_FAIL;
00280 goto exit;
00281 }
00282 if (Access(_sourcedir, W_OK)) {
00283 rpmError(RPMERR_CREATE, _("cannot write to %%%s %s\n"),
00284 "_sourcedir", _sourcedir);
00285 rpmrc = RPMRC_FAIL;
00286 goto exit;
00287 }
00288
00289 _specdir = rpmGenPath(rpmtsRootDir(ts), "%{_specdir}", "");
00290 rpmrc = rpmMkdirPath(_specdir, "specdir");
00291 if (rpmrc) {
00292 rpmrc = RPMRC_FAIL;
00293 goto exit;
00294 }
00295 if (Access(_specdir, W_OK)) {
00296 rpmError(RPMERR_CREATE, _("cannot write to %%%s %s\n"),
00297 "_specdir", _specdir);
00298 rpmrc = RPMRC_FAIL;
00299 goto exit;
00300 }
00301
00302
00303 if (i < fi->fc) {
00304 int speclen = strlen(_specdir) + 2;
00305 int sourcelen = strlen(_sourcedir) + 2;
00306 char * t;
00307
00308 fi->dnl = hfd(fi->dnl, -1);
00309
00310 fi->dc = 2;
00311 fi->dnl = xmalloc(fi->dc * sizeof(*fi->dnl)
00312 + fi->fc * sizeof(*fi->dil)
00313 + speclen + sourcelen);
00314
00315 fi->dil = (int *)(fi->dnl + fi->dc);
00316
00317 memset(fi->dil, 0, fi->fc * sizeof(*fi->dil));
00318 fi->dil[i] = 1;
00319
00320 fi->dnl[0] = t = (char *)(fi->dil + fi->fc);
00321 fi->dnl[1] = t = stpcpy( stpcpy(t, _sourcedir), "/") + 1;
00322
00323 (void) stpcpy( stpcpy(t, _specdir), "/");
00324
00325 t = xmalloc(speclen + strlen(fi->bnl[i]) + 1);
00326 (void) stpcpy( stpcpy( stpcpy(t, _specdir), "/"), fi->bnl[i]);
00327 specFile = t;
00328 } else {
00329 rpmError(RPMERR_NOSPEC, _("source package contains no .spec file\n"));
00330 rpmrc = RPMRC_FAIL;
00331 goto exit;
00332 }
00333
00334 psm->goal = PSM_PKGINSTALL;
00335
00336
00337 rpmrc = rpmpsmStage(psm, PSM_PROCESS);
00338
00339 (void) rpmpsmStage(psm, PSM_FINI);
00340
00341
00342 if (rpmrc) rpmrc = RPMRC_FAIL;
00343
00344 exit:
00345 if (specFilePtr && specFile && rpmrc == RPMRC_OK)
00346 *specFilePtr = specFile;
00347 else
00348 specFile = _free(specFile);
00349
00350 _specdir = _free(_specdir);
00351 _sourcedir = _free(_sourcedir);
00352
00353 psm->fi = rpmfiFree(psm->fi);
00354 psm->te = NULL;
00355
00356 if (h != NULL) h = headerFree(h);
00357
00358
00359 if (fi != NULL) {
00360 fi->te->h = headerFree(fi->te->h);
00361 if (fi->te->fd != NULL)
00362 (void) Fclose(fi->te->fd);
00363 fi->te->fd = NULL;
00364 fi->te = NULL;
00365 fi = rpmfiFree(fi);
00366 }
00367
00368
00369
00370 rpmtsClean(ts);
00371
00372 psm->ts = rpmtsFree(psm->ts);
00373
00374 return rpmrc;
00375 }
00376
00377
00378 static char * SCRIPT_PATH = "PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/X11R6/bin";
00379
00385 static const char * tag2sln(int tag)
00386
00387 {
00388 switch (tag) {
00389 case RPMTAG_PRETRANS: return "%pretrans";
00390 case RPMTAG_TRIGGERPREIN: return "%triggerprein";
00391 case RPMTAG_PREIN: return "%pre";
00392 case RPMTAG_POSTIN: return "%post";
00393 case RPMTAG_TRIGGERIN: return "%triggerin";
00394 case RPMTAG_TRIGGERUN: return "%triggerun";
00395 case RPMTAG_PREUN: return "%preun";
00396 case RPMTAG_POSTUN: return "%postun";
00397 case RPMTAG_POSTTRANS: return "%posttrans";
00398 case RPMTAG_TRIGGERPOSTUN: return "%triggerpostun";
00399 case RPMTAG_VERIFYSCRIPT: return "%verify";
00400 }
00401 return "%unknownscript";
00402 }
00403
00409 static rpmScriptID tag2slx(int tag)
00410
00411 {
00412 switch (tag) {
00413 case RPMTAG_PRETRANS: return RPMSCRIPT_PRETRANS;
00414 case RPMTAG_TRIGGERPREIN: return RPMSCRIPT_TRIGGERPREIN;
00415 case RPMTAG_PREIN: return RPMSCRIPT_PREIN;
00416 case RPMTAG_POSTIN: return RPMSCRIPT_POSTIN;
00417 case RPMTAG_TRIGGERIN: return RPMSCRIPT_TRIGGERIN;
00418 case RPMTAG_TRIGGERUN: return RPMSCRIPT_TRIGGERUN;
00419 case RPMTAG_PREUN: return RPMSCRIPT_PREUN;
00420 case RPMTAG_POSTUN: return RPMSCRIPT_POSTUN;
00421 case RPMTAG_POSTTRANS: return RPMSCRIPT_POSTTRANS;
00422 case RPMTAG_TRIGGERPOSTUN: return RPMSCRIPT_TRIGGERPOSTUN;
00423 case RPMTAG_VERIFYSCRIPT: return RPMSCRIPT_VERIFY;
00424 }
00425 return RPMSCRIPT_UNKNOWN;
00426 }
00427
00433 static pid_t psmWait(rpmpsm psm)
00434
00435
00436 {
00437 const rpmts ts = psm->ts;
00438 rpmtime_t msecs;
00439
00440 (void) rpmsqWait(&psm->sq);
00441 msecs = psm->sq.op.usecs/1000;
00442 (void) rpmswAdd(rpmtsOp(ts, RPMTS_OP_SCRIPTLETS), &psm->sq.op);
00443
00444 rpmMessage(RPMMESS_DEBUG,
00445 D_("%s: waitpid(%d) rc %d status %x secs %u.%03u\n"),
00446 psm->stepName, (unsigned)psm->sq.child,
00447 (unsigned)psm->sq.reaped, psm->sq.status,
00448 (unsigned)msecs/1000, (unsigned)msecs%1000);
00449
00450 if (psm->sstates != NULL)
00451 { int * ssp = psm->sstates + tag2slx(psm->scriptTag);
00452 *ssp &= ~0xffff;
00453 *ssp |= (psm->sq.status & 0xffff);
00454 *ssp |= RPMSCRIPT_STATE_REAPED;
00455 }
00456
00457 return psm->sq.reaped;
00458 }
00459
00460 #ifdef WITH_LUA
00461
00464 static rpmRC runLuaScript(rpmpsm psm, Header h, const char *sln,
00465 int progArgc, const char **progArgv,
00466 const char *script, int arg1, int arg2)
00467
00468
00469 {
00470 const rpmts ts = psm->ts;
00471 int rootFdno = -1;
00472 const char *n, *v, *r;
00473 rpmRC rc = RPMRC_OK;
00474 int i;
00475 int xx;
00476 rpmlua lua = NULL;
00477 rpmluav var;
00478 int * ssp = NULL;
00479
00480 if (psm->sstates != NULL)
00481 ssp = psm->sstates + tag2slx(psm->scriptTag);
00482 if (ssp != NULL)
00483 *ssp |= (RPMSCRIPT_STATE_LUA|RPMSCRIPT_STATE_EXEC);
00484
00485 xx = headerNVR(h, &n, &v, &r);
00486
00487
00488
00489 rootFdno = open(".", O_RDONLY, 0);
00490
00491
00492
00493 if (!rpmtsChrootDone(ts)) {
00494 const char *rootDir = rpmtsRootDir(ts);
00495
00496 if (rootDir != NULL && strcmp(rootDir, "/") && *rootDir == '/') {
00497 xx = Chroot(rootDir);
00498
00499 xx = rpmtsSetChrootDone(ts, 1);
00500 }
00501 }
00502
00503
00504 xx = Chdir("/");
00505
00506
00507 rpmluaPushTable(lua, "arg");
00508 var = rpmluavNew();
00509 rpmluavSetListMode(var, 1);
00510
00511 if (progArgv) {
00512 for (i = 0; i < progArgc && progArgv[i]; i++) {
00513 rpmluavSetValue(var, RPMLUAV_STRING, progArgv[i]);
00514 rpmluaSetVar(lua, var);
00515 }
00516 }
00517 if (arg1 >= 0) {
00518 rpmluavSetValueNum(var, arg1);
00519 rpmluaSetVar(lua, var);
00520 }
00521 if (arg2 >= 0) {
00522 rpmluavSetValueNum(var, arg2);
00523 rpmluaSetVar(lua, var);
00524 }
00525
00526
00527 var = rpmluavFree(var);
00528
00529 rpmluaPop(lua);
00530
00531 {
00532 char buf[BUFSIZ];
00533 xx = snprintf(buf, BUFSIZ, "%s(%s-%s-%s)", sln, n, v, r);
00534 xx = rpmluaRunScript(lua, script, buf);
00535 if (xx == -1)
00536 rc = RPMRC_FAIL;
00537 if (ssp != NULL) {
00538 *ssp &= ~0xffff;
00539 *ssp |= (xx & 0xffff);
00540 *ssp |= RPMSCRIPT_STATE_REAPED;
00541 }
00542 }
00543
00544 rpmluaDelVar(lua, "arg");
00545
00546
00547 if (rpmtsChrootDone(ts)) {
00548 const char *rootDir = rpmtsRootDir(ts);
00549 xx = fchdir(rootFdno);
00550
00551 if (rootDir != NULL && strcmp(rootDir, "/") && *rootDir == '/') {
00552 xx = Chroot(".");
00553
00554 xx = rpmtsSetChrootDone(ts, 0);
00555 }
00556 } else
00557 xx = fchdir(rootFdno);
00558
00559 xx = close(rootFdno);
00560
00561 return rc;
00562 }
00563 #endif
00564
00567
00568 static int ldconfig_done = 0;
00569
00570
00571 static const char * ldconfig_path = "/sbin/ldconfig";
00572
00591 static rpmRC runScript(rpmpsm psm, Header h, const char * sln,
00592 int progArgc, const char ** progArgv,
00593 const char * script, int arg1, int arg2)
00594
00595
00596
00597
00598 {
00599 const rpmts ts = psm->ts;
00600 rpmfi fi = psm->fi;
00601 HGE_t hge = fi->hge;
00602 HFD_t hfd = (fi->hfd ? fi->hfd : headerFreeData);
00603 const char ** argv = NULL;
00604 int argc = 0;
00605 const char ** prefixes = NULL;
00606 int numPrefixes;
00607 rpmTagType ipt;
00608 const char * oldPrefix;
00609 int maxPrefixLength;
00610 int len;
00611 char * prefixBuf = NULL;
00612 const char * fn = NULL;
00613 int xx;
00614 int i;
00615 int freePrefixes = 0;
00616 FD_t scriptFd;
00617 FD_t out;
00618 rpmRC rc = RPMRC_OK;
00619 const char *n, *v, *r, *a;
00620 int * ssp = NULL;
00621
00622 if (psm->sstates != NULL)
00623 ssp = psm->sstates + tag2slx(psm->scriptTag);
00624 if (ssp != NULL)
00625 *ssp = RPMSCRIPT_STATE_UNKNOWN;
00626
00627 if (progArgv == NULL && script == NULL)
00628 return rc;
00629
00630
00631 xx = headerNVR(h, &n, &v, &r);
00632 xx = hge(h, RPMTAG_ARCH, NULL, &a, NULL);
00633
00634 if (progArgv && strcmp(progArgv[0], "<lua>") == 0) {
00635 #ifdef WITH_LUA
00636 rpmMessage(RPMMESS_DEBUG,
00637 D_("%s: %s(%s-%s-%s.%s) running <lua> scriptlet.\n"),
00638 psm->stepName, tag2sln(psm->scriptTag), n, v, r, a);
00639 return runLuaScript(psm, h, sln, progArgc, progArgv,
00640 script, arg1, arg2);
00641 #else
00642 return RPMRC_FAIL;
00643 #endif
00644 }
00645
00646 psm->sq.reaper = 1;
00647
00648
00649 if (!strcmp(n, "libtermcap"))
00650 ldconfig_done = 0;
00651
00652
00653
00654
00655 if (ldconfig_path && progArgv != NULL && psm->unorderedSuccessor) {
00656 if (ldconfig_done && !strcmp(progArgv[0], ldconfig_path)) {
00657 rpmMessage(RPMMESS_DEBUG,
00658 D_("%s: %s(%s-%s-%s.%s) skipping redundant \"%s\".\n"),
00659 psm->stepName, tag2sln(psm->scriptTag), n, v, r, a,
00660 progArgv[0]);
00661 return rc;
00662 }
00663 }
00664
00665 rpmMessage(RPMMESS_DEBUG,
00666 D_("%s: %s(%s-%s-%s.%s) %ssynchronous scriptlet start\n"),
00667 psm->stepName, tag2sln(psm->scriptTag), n, v, r, a,
00668 (psm->unorderedSuccessor ? "a" : ""));
00669
00670 if (!progArgv) {
00671 argv = alloca(5 * sizeof(*argv));
00672 argv[0] = "/bin/sh";
00673 argc = 1;
00674 ldconfig_done = 0;
00675 } else {
00676 argv = alloca((progArgc + 4) * sizeof(*argv));
00677 memcpy(argv, progArgv, progArgc * sizeof(*argv));
00678 argc = progArgc;
00679 ldconfig_done = (ldconfig_path && !strcmp(argv[0], ldconfig_path)
00680 ? 1 : 0);
00681 }
00682
00683 #if __ia64__
00684
00685 if ((a != NULL && a[0] == 'i' && a[1] != '\0' && a[2] == '8' && a[3] == '6')
00686 && strcmp(argv[0], "/sbin/ldconfig"))
00687 {
00688 const char * fmt = rpmGetPath("%{?_autorelocate_path}", NULL);
00689 const char * errstr;
00690 char * newPath;
00691 char * t;
00692
00693 newPath = headerSprintf(h, fmt, rpmTagTable, rpmHeaderFormats, &errstr);
00694 fmt = _free(fmt);
00695
00696
00697 if (newPath != NULL && *newPath != '\0'
00698 && strlen(newPath) >= (sizeof("/emul/i386")-1)
00699 && newPath[0] == '/' && newPath[1] == 'e' && newPath[2] == 'm'
00700 && newPath[3] == 'u' && newPath[4] == 'l' && newPath[5] == '/'
00701 && newPath[6] == 'i' && newPath[8] == '8' && newPath[9] == '6')
00702 {
00703 newPath[7] = 'a';
00704 newPath[8] = '3';
00705 newPath[9] = '2';
00706 }
00707
00708 t = alloca(strlen(newPath) + strlen(argv[0]) + 1);
00709 *t = '\0';
00710 (void) stpcpy( stpcpy(t, newPath), argv[0]);
00711 newPath = _free(newPath);
00712 argv[0] = t;
00713 }
00714 #endif
00715
00716 if (hge(h, RPMTAG_INSTPREFIXES, &ipt, &prefixes, &numPrefixes)) {
00717 freePrefixes = 1;
00718 } else if (hge(h, RPMTAG_INSTALLPREFIX, NULL, &oldPrefix, NULL)) {
00719 prefixes = &oldPrefix;
00720 numPrefixes = 1;
00721 } else {
00722 numPrefixes = 0;
00723 }
00724
00725 maxPrefixLength = 0;
00726 if (prefixes != NULL)
00727 for (i = 0; i < numPrefixes; i++) {
00728 len = strlen(prefixes[i]);
00729 if (len > maxPrefixLength) maxPrefixLength = len;
00730 }
00731 prefixBuf = alloca(maxPrefixLength + 50);
00732
00733 if (script) {
00734 const char * rootDir = rpmtsRootDir(ts);
00735 FD_t fd;
00736
00737
00738 if (makeTempFile((!rpmtsChrootDone(ts) ? rootDir : "/"), &fn, &fd)) {
00739 if (prefixes != NULL && freePrefixes) free(prefixes);
00740 return RPMRC_FAIL;
00741 }
00742
00743
00744 if (rpmIsDebug() &&
00745 (!strcmp(argv[0], "/bin/sh") || !strcmp(argv[0], "/bin/bash")))
00746 {
00747 static const char set_x[] = "set -x\n";
00748 xx = Fwrite(set_x, sizeof(set_x[0]), sizeof(set_x)-1, fd);
00749 }
00750
00751 if (ldconfig_path && strstr(script, ldconfig_path) != NULL)
00752 ldconfig_done = 1;
00753
00754 xx = Fwrite(script, sizeof(script[0]), strlen(script), fd);
00755 xx = Fclose(fd);
00756
00757 { const char * sn = fn;
00758 if (!rpmtsChrootDone(ts) && rootDir != NULL &&
00759 !(rootDir[0] == '/' && rootDir[1] == '\0'))
00760 {
00761 sn += strlen(rootDir)-1;
00762 }
00763 argv[argc++] = sn;
00764 }
00765
00766 if (arg1 >= 0) {
00767 char *av = alloca(20);
00768 sprintf(av, "%d", arg1);
00769 argv[argc++] = av;
00770 }
00771 if (arg2 >= 0) {
00772 char *av = alloca(20);
00773 sprintf(av, "%d", arg2);
00774 argv[argc++] = av;
00775 }
00776 }
00777
00778 argv[argc] = NULL;
00779
00780 scriptFd = rpmtsScriptFd(ts);
00781 if (scriptFd != NULL) {
00782 if (rpmIsVerbose()) {
00783 out = fdDup(Fileno(scriptFd));
00784 } else {
00785 out = Fopen("/dev/null", "w.fdio");
00786 if (Ferror(out)) {
00787 out = fdDup(Fileno(scriptFd));
00788 }
00789 }
00790 } else {
00791 out = fdDup(STDOUT_FILENO);
00792 }
00793 if (out == NULL) return RPMRC_FAIL;
00794
00795
00796 xx = rpmsqFork(&psm->sq);
00797 if (psm->sq.child == 0) {
00798 const char * rootDir;
00799 int pipes[2];
00800 int flag;
00801 int fdno;
00802
00803 pipes[0] = pipes[1] = 0;
00804
00805 xx = pipe(pipes);
00806 xx = close(pipes[1]);
00807 xx = dup2(pipes[0], STDIN_FILENO);
00808 xx = close(pipes[0]);
00809
00810
00811 for (fdno = 3; fdno < 100; fdno++) {
00812 flag = fcntl(fdno, F_GETFD);
00813 if (flag == -1 || (flag & FD_CLOEXEC))
00814 continue;
00815 xx = fcntl(fdno, F_SETFD, FD_CLOEXEC);
00816
00817 }
00818
00819 if (scriptFd != NULL) {
00820 int sfdno = Fileno(scriptFd);
00821 int ofdno = Fileno(out);
00822 if (sfdno != STDERR_FILENO)
00823 xx = dup2(sfdno, STDERR_FILENO);
00824 if (ofdno != STDOUT_FILENO)
00825 xx = dup2(ofdno, STDOUT_FILENO);
00826
00827 if (ofdno > STDERR_FILENO && ofdno != sfdno)
00828 xx = Fclose (out);
00829 if (sfdno > STDERR_FILENO)
00830 xx = Fclose (scriptFd);
00831 else {
00832
00833 xx = Fclose(out);
00834
00835 }
00836 }
00837
00838 { const char *ipath = rpmExpand("PATH=%{_install_script_path}", NULL);
00839 const char *path = SCRIPT_PATH;
00840
00841 if (ipath && ipath[5] != '%')
00842 path = ipath;
00843
00844 xx = doputenv(path);
00845
00846 ipath = _free(ipath);
00847
00848 }
00849
00850 if (prefixes != NULL)
00851 for (i = 0; i < numPrefixes; i++) {
00852 sprintf(prefixBuf, "RPM_INSTALL_PREFIX%d=%s", i, prefixes[i]);
00853 xx = doputenv(prefixBuf);
00854
00855
00856 if (i == 0) {
00857 sprintf(prefixBuf, "RPM_INSTALL_PREFIX=%s", prefixes[i]);
00858 xx = doputenv(prefixBuf);
00859 }
00860 }
00861
00862 rootDir = ts->rootDir;
00863 if (rootDir != NULL)
00864 switch(urlIsURL(rootDir)) {
00865 case URL_IS_PATH:
00866 rootDir += sizeof("file://") - 1;
00867 rootDir = strchr(rootDir, '/');
00868
00869 case URL_IS_UNKNOWN:
00870 if (!rpmtsChrootDone(ts) &&
00871 !(rootDir[0] == '/' && rootDir[1] == '\0'))
00872 {
00873
00874 xx = Chroot(rootDir);
00875
00876 }
00877 xx = Chdir("/");
00878 rpmMessage(RPMMESS_DEBUG, "%s: %s(%s-%s-%s.%s)\texecv(%s) pid %d\n",
00879 psm->stepName, sln, n, v, r, a,
00880 argv[0], (unsigned)getpid());
00881
00882
00883 unsetenv("MALLOC_CHECK_");
00884
00885 if (ssp != NULL)
00886 *ssp |= RPMSCRIPT_STATE_EXEC;
00887
00888
00889 if (rpmtsSELinuxEnabled(ts) == 1) {
00890 if (ssp != NULL)
00891 *ssp |= RPMSCRIPT_STATE_SELINUX;
00892
00893 xx = rpm_execcon(0, argv[0], argv, environ);
00894
00895 if (xx != 0)
00896 break;
00897 }
00898
00899
00900 xx = execv(argv[0], (char *const *)argv);
00901
00902 break;
00903 case URL_IS_HTTPS:
00904 case URL_IS_HTTP:
00905 case URL_IS_FTP:
00906 case URL_IS_DASH:
00907 case URL_IS_HKP:
00908 default:
00909 break;
00910 }
00911
00912 if (ssp != NULL)
00913 *ssp &= ~RPMSCRIPT_STATE_EXEC;
00914
00915 _exit(-1);
00916
00917 }
00918
00919
00920 (void) psmWait(psm);
00921
00922
00923 if (!(psm->sq.reaped >= 0 && !strcmp(argv[0], "/usr/sbin/glibc_post_upgrade") && WEXITSTATUS(psm->sq.status) == 110)) {
00924 if (psm->sq.reaped < 0) {
00925 rpmError(RPMERR_SCRIPT,
00926 _("%s(%s-%s-%s.%s) scriptlet failed, waitpid(%d) rc %d: %s\n"),
00927 sln, n, v, r, a, psm->sq.child, psm->sq.reaped, strerror(errno));
00928 rc = RPMRC_FAIL;
00929 } else
00930 if (!WIFEXITED(psm->sq.status) || WEXITSTATUS(psm->sq.status)) {
00931 if (WIFSIGNALED(psm->sq.status)) {
00932 rpmError(RPMERR_SCRIPT,
00933 _("%s(%s-%s-%s.%s) scriptlet failed, signal %d\n"),
00934 sln, n, v, r, a, WTERMSIG(psm->sq.status));
00935 } else {
00936 rpmError(RPMERR_SCRIPT,
00937 _("%s(%s-%s-%s.%s) scriptlet failed, exit status %d\n"),
00938 sln, n, v, r, a, WEXITSTATUS(psm->sq.status));
00939 }
00940 rc = RPMRC_FAIL;
00941 }
00942 }
00943
00944 if (freePrefixes) prefixes = hfd(prefixes, ipt);
00945
00946 xx = Fclose(out);
00947
00948
00949 if (script) {
00950 if (!rpmIsDebug())
00951 xx = unlink(fn);
00952 fn = _free(fn);
00953 }
00954
00955
00956 return rc;
00957 }
00958
00964 static rpmRC runInstScript(rpmpsm psm)
00965
00966
00967 {
00968 rpmfi fi = psm->fi;
00969 HGE_t hge = fi->hge;
00970 HFD_t hfd = (fi->hfd ? fi->hfd : headerFreeData);
00971 void ** progArgv = NULL;
00972 int progArgc;
00973 const char * argv0 = NULL;
00974 const char ** argv;
00975 rpmTagType ptt, stt;
00976 const char * script;
00977 rpmRC rc = RPMRC_OK;
00978 int xx;
00979
00980 assert(fi->h != NULL);
00981 xx = hge(fi->h, psm->scriptTag, &stt, &script, NULL);
00982 xx = hge(fi->h, psm->progTag, &ptt, &progArgv, &progArgc);
00983 if (progArgv == NULL && script == NULL)
00984 goto exit;
00985
00986
00987 if (progArgv && ptt == RPM_STRING_TYPE) {
00988 argv = alloca(sizeof(*argv));
00989 *argv = (const char *) progArgv;
00990 } else {
00991 argv = (const char **) progArgv;
00992 }
00993
00994
00995 if (argv[0][0] == '%')
00996 argv[0] = argv0 = rpmExpand(argv[0], NULL);
00997
00998 if (fi->h != NULL)
00999 rc = runScript(psm, fi->h, tag2sln(psm->scriptTag), progArgc, argv,
01000 script, psm->scriptArg, -1);
01001
01002 exit:
01003 argv0 = _free(argv0);
01004 progArgv = hfd(progArgv, ptt);
01005 script = hfd(script, stt);
01006 return rc;
01007 }
01008
01019 static rpmRC handleOneTrigger(const rpmpsm psm,
01020 Header sourceH, Header triggeredH,
01021 int arg2, unsigned char * triggersAlreadyRun)
01022
01023
01024
01025 {
01026 int scareMem = 0;
01027 const rpmts ts = psm->ts;
01028 rpmfi fi = psm->fi;
01029 HGE_t hge = fi->hge;
01030 HFD_t hfd = (fi->hfd ? fi->hfd : headerFreeData);
01031 rpmds trigger = NULL;
01032 const char ** triggerScripts;
01033 const char ** triggerProgs;
01034 int_32 * triggerIndices;
01035 const char * sourceName;
01036 const char * triggerName;
01037 rpmRC rc = RPMRC_OK;
01038 int xx;
01039 int i;
01040
01041 xx = headerNVR(sourceH, &sourceName, NULL, NULL);
01042 xx = headerNVR(triggeredH, &triggerName, NULL, NULL);
01043
01044 trigger = rpmdsInit(rpmdsNew(triggeredH, RPMTAG_TRIGGERNAME, scareMem));
01045 if (trigger == NULL)
01046 return rc;
01047
01048 (void) rpmdsSetNoPromote(trigger, 1);
01049
01050 while ((i = rpmdsNext(trigger)) >= 0) {
01051 rpmTagType tit, tst, tpt;
01052 const char * Name;
01053 int_32 Flags = rpmdsFlags(trigger);
01054
01055 if ((Name = rpmdsN(trigger)) == NULL)
01056 continue;
01057
01058 if (strcmp(Name, sourceName))
01059 continue;
01060 if (!(Flags & psm->sense))
01061 continue;
01062
01063
01064
01065
01066 if (!rpmdsAnyMatchesDep(sourceH, trigger, 1))
01067 continue;
01068
01069 if (!( hge(triggeredH, RPMTAG_TRIGGERINDEX, &tit,
01070 &triggerIndices, NULL) &&
01071 hge(triggeredH, RPMTAG_TRIGGERSCRIPTS, &tst,
01072 &triggerScripts, NULL) &&
01073 hge(triggeredH, RPMTAG_TRIGGERSCRIPTPROG, &tpt,
01074 &triggerProgs, NULL))
01075 )
01076 continue;
01077
01078 { int arg1;
01079 int index;
01080
01081 arg1 = rpmdbCountPackages(rpmtsGetRdb(ts), triggerName);
01082 if (arg1 < 0) {
01083
01084 rc = RPMRC_FAIL;
01085 } else {
01086 arg1 += psm->countCorrection;
01087 index = triggerIndices[i];
01088 if (triggersAlreadyRun == NULL ||
01089 triggersAlreadyRun[index] == 0)
01090 {
01091 rc = runScript(psm, triggeredH, "%trigger", 1,
01092 triggerProgs + index, triggerScripts[index],
01093 arg1, arg2);
01094 if (triggersAlreadyRun != NULL)
01095 triggersAlreadyRun[index] = 1;
01096 }
01097 }
01098 }
01099
01100 triggerIndices = hfd(triggerIndices, tit);
01101 triggerScripts = hfd(triggerScripts, tst);
01102 triggerProgs = hfd(triggerProgs, tpt);
01103
01104
01105
01106
01107
01108 break;
01109 }
01110
01111 trigger = rpmdsFree(trigger);
01112
01113 return rc;
01114 }
01115
01121 static rpmRC runTriggers(rpmpsm psm)
01122
01123
01124
01125
01126 {
01127 const rpmts ts = psm->ts;
01128 rpmfi fi = psm->fi;
01129 int numPackage = -1;
01130 rpmRC rc = RPMRC_OK;
01131 const char * N = NULL;
01132
01133 if (psm->te)
01134 N = rpmteN(psm->te);
01135
01136 if (N)
01137 numPackage = rpmdbCountPackages(rpmtsGetRdb(ts), N)
01138 + psm->countCorrection;
01139 if (numPackage < 0)
01140 return RPMRC_NOTFOUND;
01141
01142 if (fi != NULL && fi->h != NULL)
01143 { Header triggeredH;
01144 rpmdbMatchIterator mi;
01145 int countCorrection = psm->countCorrection;
01146
01147 psm->countCorrection = 0;
01148 mi = rpmtsInitIterator(ts, RPMTAG_TRIGGERNAME, N, 0);
01149 while((triggeredH = rpmdbNextIterator(mi)) != NULL)
01150 rc |= handleOneTrigger(psm, fi->h, triggeredH, numPackage, NULL);
01151 mi = rpmdbFreeIterator(mi);
01152 psm->countCorrection = countCorrection;
01153 }
01154
01155 return rc;
01156 }
01157
01163 static rpmRC runImmedTriggers(rpmpsm psm)
01164
01165
01166
01167
01168 {
01169 const rpmts ts = psm->ts;
01170 rpmfi fi = psm->fi;
01171 HGE_t hge = fi->hge;
01172 HFD_t hfd = (fi->hfd ? fi->hfd : headerFreeData);
01173 const char ** triggerNames;
01174 int numTriggers;
01175 int_32 * triggerIndices;
01176 rpmTagType tnt, tit;
01177 int numTriggerIndices;
01178 unsigned char * triggersRun;
01179 rpmRC rc = RPMRC_OK;
01180 size_t nb;
01181
01182 if (fi->h == NULL) return rc;
01183
01184 if (!( hge(fi->h, RPMTAG_TRIGGERNAME, &tnt,
01185 &triggerNames, &numTriggers) &&
01186 hge(fi->h, RPMTAG_TRIGGERINDEX, &tit,
01187 &triggerIndices, &numTriggerIndices))
01188 )
01189 return rc;
01190
01191 nb = sizeof(*triggersRun) * numTriggerIndices;
01192 triggersRun = memset(alloca(nb), 0, nb);
01193
01194 { Header sourceH = NULL;
01195 int i;
01196
01197 for (i = 0; i < numTriggers; i++) {
01198 rpmdbMatchIterator mi;
01199
01200 if (triggersRun[triggerIndices[i]] != 0) continue;
01201
01202 mi = rpmtsInitIterator(ts, RPMTAG_NAME, triggerNames[i], 0);
01203
01204 while((sourceH = rpmdbNextIterator(mi)) != NULL) {
01205 rc |= handleOneTrigger(psm, sourceH, fi->h,
01206 rpmdbGetIteratorCount(mi),
01207 triggersRun);
01208 }
01209
01210 mi = rpmdbFreeIterator(mi);
01211 }
01212 }
01213 triggerIndices = hfd(triggerIndices, tit);
01214 triggerNames = hfd(triggerNames, tnt);
01215 return rc;
01216 }
01217
01218
01219 static const char * pkgStageString(pkgStage a)
01220
01221 {
01222 switch(a) {
01223 case PSM_UNKNOWN: return "unknown";
01224
01225 case PSM_PKGINSTALL: return " install";
01226 case PSM_PKGERASE: return " erase";
01227 case PSM_PKGCOMMIT: return " commit";
01228 case PSM_PKGSAVE: return "repackage";
01229
01230 case PSM_INIT: return "init";
01231 case PSM_PRE: return "pre";
01232 case PSM_PROCESS: return "process";
01233 case PSM_POST: return "post";
01234 case PSM_UNDO: return "undo";
01235 case PSM_FINI: return "fini";
01236
01237 case PSM_CREATE: return "create";
01238 case PSM_NOTIFY: return "notify";
01239 case PSM_DESTROY: return "destroy";
01240 case PSM_COMMIT: return "commit";
01241
01242 case PSM_CHROOT_IN: return "chrootin";
01243 case PSM_CHROOT_OUT: return "chrootout";
01244 case PSM_SCRIPT: return "script";
01245 case PSM_TRIGGERS: return "triggers";
01246 case PSM_IMMED_TRIGGERS: return "immedtriggers";
01247
01248 case PSM_RPMIO_FLAGS: return "rpmioflags";
01249
01250 case PSM_RPMDB_LOAD: return "rpmdbload";
01251 case PSM_RPMDB_ADD: return "rpmdbadd";
01252 case PSM_RPMDB_REMOVE: return "rpmdbremove";
01253
01254 default: return "???";
01255 }
01256
01257 }
01258
01259 rpmpsm XrpmpsmUnlink(rpmpsm psm, const char * msg, const char * fn, unsigned ln)
01260 {
01261 if (psm == NULL) return NULL;
01262
01263 if (_psm_debug && msg != NULL)
01264 fprintf(stderr, "--> psm %p -- %d %s at %s:%u\n", psm, psm->nrefs, msg, fn, ln);
01265
01266 psm->nrefs--;
01267 return NULL;
01268 }
01269
01270 rpmpsm XrpmpsmLink(rpmpsm psm, const char * msg, const char * fn, unsigned ln)
01271 {
01272 if (psm == NULL) return NULL;
01273 psm->nrefs++;
01274
01275
01276 if (_psm_debug && msg != NULL)
01277 fprintf(stderr, "--> psm %p ++ %d %s at %s:%u\n", psm, psm->nrefs, msg, fn, ln);
01278
01279
01280 return psm;
01281 }
01282
01283 rpmpsm rpmpsmFree(rpmpsm psm)
01284 {
01285 const char * msg = "rpmpsmFree";
01286 if (psm == NULL)
01287 return NULL;
01288
01289 if (psm->nrefs > 1)
01290 return rpmpsmUnlink(psm, msg);
01291
01292
01293 psm->fi = rpmfiFree(psm->fi);
01294 #ifdef NOTYET
01295 psm->te = rpmteFree(psm->te);
01296 #else
01297 psm->te = NULL;
01298 #endif
01299
01300 psm->ts = rpmtsFree(psm->ts);
01301
01302
01303 psm->sstates = _free(psm->sstates);
01304
01305 (void) rpmpsmUnlink(psm, msg);
01306
01307
01308
01309 memset(psm, 0, sizeof(*psm));
01310
01311 psm = _free(psm);
01312
01313
01314 return NULL;
01315
01316 }
01317
01318 rpmpsm rpmpsmNew(rpmts ts, rpmte te, rpmfi fi)
01319 {
01320 const char * msg = "rpmpsmNew";
01321 rpmpsm psm = xcalloc(1, sizeof(*psm));
01322
01323 if (ts) psm->ts = rpmtsLink(ts, msg);
01324 #ifdef NOTYET
01325 if (te) psm->te = rpmteLink(te, msg);
01326 #else
01327
01328 if (te) psm->te = te;
01329
01330 #endif
01331 if (fi) psm->fi = rpmfiLink(fi, msg);
01332
01333 psm->sstates = xcalloc(RPMSCRIPT_MAX, sizeof(*psm->sstates));
01334
01335 return rpmpsmLink(psm, msg);
01336 }
01337
01344 static uint_32 hLoadTID(Header h, int_32 tag)
01345
01346 {
01347 uint_32 val = 0;
01348 int_32 typ = 0;
01349 void * ptr = NULL;
01350 int_32 cnt = 0;
01351
01352 if (headerGetEntry(h, tag, &typ, &ptr, &cnt)
01353 && typ == RPM_INT32_TYPE && ptr != NULL && cnt == 1)
01354 val = *(uint_32 *)ptr;
01355 ptr = headerFreeData(ptr, typ);
01356 return val;
01357 }
01358
01366 static int hCopyTag(Header sh, Header th, int_32 tag)
01367
01368 {
01369 int_32 typ = 0;
01370 void * ptr = NULL;
01371 int_32 cnt = 0;
01372 int xx = 1;
01373
01374 if (headerGetEntry(sh, tag, &typ, &ptr, &cnt) && cnt > 0)
01375 xx = headerAddEntry(th, tag, typ, ptr, cnt);
01376 assert(xx);
01377 ptr = headerFreeData(ptr, typ);
01378 return 0;
01379 }
01380
01387 static int hSaveBlinks(Header h, const struct rpmChainLink_s * blink)
01388
01389 {
01390
01391 static const char * chain_end = RPMTE_CHAIN_END;
01392 int ac;
01393 int xx = 1;
01394
01395 ac = argvCount(blink->NEVRA);
01396 if (ac > 0)
01397 xx = headerAddEntry(h, RPMTAG_BLINKNEVRA, RPM_STRING_ARRAY_TYPE,
01398 argvData(blink->NEVRA), ac);
01399 else
01400 xx = headerAddEntry(h, RPMTAG_BLINKNEVRA, RPM_STRING_ARRAY_TYPE,
01401 &chain_end, 1);
01402 assert(xx);
01403
01404 ac = argvCount(blink->Pkgid);
01405 if (ac > 0)
01406 xx = headerAddEntry(h, RPMTAG_BLINKPKGID, RPM_STRING_ARRAY_TYPE,
01407 argvData(blink->Pkgid), ac);
01408 else
01409 xx = headerAddEntry(h, RPMTAG_BLINKPKGID, RPM_STRING_ARRAY_TYPE,
01410 &chain_end, 1);
01411 assert(xx);
01412
01413 ac = argvCount(blink->Hdrid);
01414 if (ac > 0)
01415 xx = headerAddEntry(h, RPMTAG_BLINKHDRID, RPM_STRING_ARRAY_TYPE,
01416 argvData(blink->Hdrid), ac);
01417 else
01418 xx = headerAddEntry(h, RPMTAG_BLINKNEVRA, RPM_STRING_ARRAY_TYPE,
01419 &chain_end, 1);
01420 assert(xx);
01421
01422 return 0;
01423 }
01424
01431 static int hSaveFlinks(Header h, const struct rpmChainLink_s * flink)
01432
01433 {
01434 #ifdef NOTYET
01435
01436 static const char * chain_end = RPMTE_CHAIN_END;
01437 #endif
01438 int ac;
01439 int xx = 1;
01440
01441
01442 ac = argvCount(flink->NEVRA);
01443 if (ac > 0)
01444 xx = headerAddEntry(h, RPMTAG_FLINKNEVRA, RPM_STRING_ARRAY_TYPE,
01445 argvData(flink->NEVRA), ac);
01446 #ifdef NOTYET
01447 else
01448 xx = headerAddEntry(h, RPMTAG_FLINKNEVRA, RPM_STRING_ARRAY_TYPE,
01449 &chain_end, 1);
01450 #endif
01451 assert(xx);
01452
01453 ac = argvCount(flink->Pkgid);
01454 if (ac > 0)
01455 xx = headerAddEntry(h, RPMTAG_FLINKPKGID, RPM_STRING_ARRAY_TYPE,
01456 argvData(flink->Pkgid), ac);
01457 #ifdef NOTYET
01458 else
01459 xx = headerAddEntry(h, RPMTAG_FLINKPKGID, RPM_STRING_ARRAY_TYPE,
01460 &chain_end, 1);
01461 #endif
01462 assert(xx);
01463
01464 ac = argvCount(flink->Hdrid);
01465 if (ac > 0)
01466 xx = headerAddEntry(h, RPMTAG_FLINKHDRID, RPM_STRING_ARRAY_TYPE,
01467 argvData(flink->Hdrid), ac);
01468 #ifdef NOTYET
01469 else
01470 xx = headerAddEntry(h, RPMTAG_FLINKNEVRA, RPM_STRING_ARRAY_TYPE,
01471 &chain_end, 1);
01472 #endif
01473 assert(xx);
01474
01475 return 0;
01476 }
01477
01485 static int populateInstallHeader(const rpmts ts, const rpmte te, rpmfi fi)
01486
01487 {
01488 uint_32 tscolor = rpmtsColor(ts);
01489 uint_32 tecolor = rpmteColor(te);
01490 int_32 installTime = (int_32) time(NULL);
01491 int fc = rpmfiFC(fi);
01492 const char * origin;
01493 int xx = 1;
01494
01495 assert(fi->h != NULL);
01496 if (fi->fstates != NULL && fc > 0)
01497 xx = headerAddEntry(fi->h, RPMTAG_FILESTATES, RPM_CHAR_TYPE,
01498 fi->fstates, fc);
01499 assert(xx);
01500
01501 xx = headerAddEntry(fi->h, RPMTAG_INSTALLTIME, RPM_INT32_TYPE,
01502 &installTime, 1);
01503 assert(xx);
01504
01505 xx = headerAddEntry(fi->h, RPMTAG_INSTALLCOLOR, RPM_INT32_TYPE,
01506 &tscolor, 1);
01507 assert(xx);
01508
01509
01510
01511 xx = headerAddEntry(fi->h, RPMTAG_PACKAGECOLOR, RPM_INT32_TYPE,
01512 &tecolor, 1);
01513 assert(xx);
01514
01515
01516 origin = headerGetOrigin(fi->h);
01517 if (origin != NULL)
01518 xx = headerAddEntry(fi->h, RPMTAG_PACKAGEORIGIN, RPM_STRING_TYPE,
01519 origin, 1);
01520 assert(xx);
01521
01522
01523 if (rpmtsType(ts) != RPMTRANS_TYPE_ROLLBACK)
01524 xx = hSaveBlinks(fi->h, &te->blink);
01525
01526 return 0;
01527 }
01528
01529 static void * rpmpsmThread(void * arg)
01530
01531
01532 {
01533 rpmpsm psm = arg;
01534
01535 return ((void *) rpmpsmStage(psm, psm->nstage));
01536
01537 }
01538
01539 static int rpmpsmNext(rpmpsm psm, pkgStage nstage)
01540
01541
01542 {
01543 psm->nstage = nstage;
01544 if (_psm_threads)
01545 return rpmsqJoin( rpmsqThread(rpmpsmThread, psm) );
01546 return rpmpsmStage(psm, psm->nstage);
01547 }
01548
01553
01554 rpmRC rpmpsmStage(rpmpsm psm, pkgStage stage)
01555 {
01556 const rpmts ts = psm->ts;
01557 uint_32 tscolor = rpmtsColor(ts);
01558 rpmfi fi = psm->fi;
01559 HGE_t hge = fi->hge;
01560 HAE_t hae = fi->hae;
01561 HFD_t hfd = (fi->hfd ? fi->hfd : headerFreeData);
01562 rpmRC rc = psm->rc;
01563 int saveerrno;
01564 int xx;
01565
01566
01567 switch (stage) {
01568 case PSM_UNKNOWN:
01569 break;
01570 case PSM_INIT:
01571 rpmMessage(RPMMESS_DEBUG, D_("%s: %s has %d files, test = %d\n"),
01572 psm->stepName, rpmteNEVR(psm->te),
01573 rpmfiFC(fi), (rpmtsFlags(ts) & RPMTRANS_FLAG_TEST));
01574
01575
01576
01577
01578
01579
01580 psm->npkgs_installed = rpmdbCountPackages(rpmtsGetRdb(ts), rpmteN(psm->te));
01581 if (psm->npkgs_installed < 0) {
01582 rc = RPMRC_FAIL;
01583 break;
01584 }
01585
01586
01587 assert(psm->te != NULL);
01588 if (rpmtsType(ts) == RPMTRANS_TYPE_AUTOROLLBACK &&
01589 (psm->goal & ~(PSM_PKGSAVE|PSM_PKGERASE)))
01590 {
01591 if (psm->te->downgrade)
01592 psm->npkgs_installed--;
01593 }
01594
01595 if (psm->goal == PSM_PKGINSTALL) {
01596 int fc = rpmfiFC(fi);
01597 const char * hdrid;
01598
01599
01600 xx = populateInstallHeader(ts, psm->te, fi);
01601
01602 psm->scriptArg = psm->npkgs_installed + 1;
01603
01604 assert(psm->mi == NULL);
01605 hdrid = rpmteHdrid(psm->te);
01606 if (hdrid != NULL) {
01607
01608 psm->mi = rpmtsInitIterator(ts, RPMTAG_SHA1HEADER, hdrid, 0);
01609 } else {
01610 psm->mi = rpmtsInitIterator(ts, RPMTAG_NAME, rpmteN(psm->te),0);
01611 xx = rpmdbSetIteratorRE(psm->mi, RPMTAG_EPOCH, RPMMIRE_STRCMP,
01612 rpmteE(psm->te));
01613 xx = rpmdbSetIteratorRE(psm->mi, RPMTAG_VERSION, RPMMIRE_STRCMP,
01614 rpmteV(psm->te));
01615 xx = rpmdbSetIteratorRE(psm->mi, RPMTAG_RELEASE, RPMMIRE_STRCMP,
01616 rpmteR(psm->te));
01617 if (tscolor) {
01618 xx = rpmdbSetIteratorRE(psm->mi,RPMTAG_ARCH, RPMMIRE_STRCMP,
01619 rpmteA(psm->te));
01620 xx = rpmdbSetIteratorRE(psm->mi, RPMTAG_OS, RPMMIRE_STRCMP,
01621 rpmteO(psm->te));
01622 }
01623 }
01624
01625 while ((psm->oh = rpmdbNextIterator(psm->mi)) != NULL) {
01626 fi->record = rpmdbGetIteratorOffset(psm->mi);
01627 psm->oh = NULL;
01628 break;
01629 }
01630 psm->mi = rpmdbFreeIterator(psm->mi);
01631
01632 rc = RPMRC_OK;
01633
01634
01635 if (fi->fstates == NULL && fc > 0) {
01636 fi->fstates = xmalloc(sizeof(*fi->fstates) * fc);
01637 memset(fi->fstates, RPMFILE_STATE_NORMAL, fc);
01638 }
01639
01640 if (rpmtsFlags(ts) & RPMTRANS_FLAG_JUSTDB) break;
01641 if (fc <= 0) break;
01642
01643
01644
01645
01646
01647
01648 { const char * p;
01649 xx = hge(fi->h, RPMTAG_DEFAULTPREFIX, NULL, &p, NULL);
01650 fi->striplen = (xx ? strlen(p) + 1 : 1);
01651 }
01652 fi->mapflags =
01653 CPIO_MAP_PATH | CPIO_MAP_MODE | CPIO_MAP_UID | CPIO_MAP_GID | (fi->mapflags & CPIO_SBIT_CHECK);
01654
01655 if (headerIsEntry(fi->h, RPMTAG_ORIGBASENAMES))
01656 rpmfiBuildFNames(fi->h, RPMTAG_ORIGBASENAMES, &fi->apath, NULL);
01657 else
01658 rpmfiBuildFNames(fi->h, RPMTAG_BASENAMES, &fi->apath, NULL);
01659
01660 if (fi->fuser == NULL)
01661 xx = hge(fi->h, RPMTAG_FILEUSERNAME, NULL,
01662 &fi->fuser, NULL);
01663 if (fi->fgroup == NULL)
01664 xx = hge(fi->h, RPMTAG_FILEGROUPNAME, NULL,
01665 &fi->fgroup, NULL);
01666 rc = RPMRC_OK;
01667 }
01668 if (psm->goal == PSM_PKGERASE || psm->goal == PSM_PKGSAVE) {
01669 psm->scriptArg = psm->npkgs_installed - 1;
01670
01671
01672 rc = rpmpsmNext(psm, PSM_RPMDB_LOAD);
01673 if (rc == RPMRC_OK)
01674 if (psm->te)
01675 psm->te->h = headerLink(fi->h);
01676 }
01677 if (psm->goal == PSM_PKGSAVE) {
01678
01679 { char tiddn[32];
01680 const char * bfmt;
01681 const char * pkgdn;
01682 const char * pkgbn;
01683
01684 xx = snprintf(tiddn, sizeof(tiddn), "%d", rpmtsGetTid(ts));
01685 bfmt = rpmGetPath(tiddn, "/", "%{_repackage_name_fmt}", NULL);
01686 pkgbn = headerSprintf(fi->h, bfmt,
01687 rpmTagTable, rpmHeaderFormats, NULL);
01688 bfmt = _free(bfmt);
01689 psm->pkgURL = rpmGenPath("%{?_repackage_root}",
01690 "%{?_repackage_dir}",
01691 pkgbn);
01692 pkgbn = _free(pkgbn);
01693 (void) urlPath(psm->pkgURL, &psm->pkgfn);
01694 pkgdn = dirname(xstrdup(psm->pkgfn));
01695 rc = rpmMkdirPath(pkgdn, "_repackage_dir");
01696 pkgdn = _free(pkgdn);
01697 if (rc == RPMRC_FAIL)
01698 break;
01699 psm->fd = Fopen(psm->pkgfn, "w");
01700 if (psm->fd == NULL || Ferror(psm->fd)) {
01701 rc = RPMRC_FAIL;
01702 break;
01703 }
01704 }
01705 }
01706 break;
01707 case PSM_PRE:
01708 if (rpmtsFlags(ts) & RPMTRANS_FLAG_TEST) break;
01709
01710
01711 #ifdef NOTYET
01712 { static int oneshot = 0;
01713 dbiIndex dbi;
01714 if (!oneshot) {
01715 dbi = dbiOpen(rpmtsGetRdb(ts), RPMTAG_TRIGGERNAME, 0);
01716 oneshot++;
01717 }
01718 }
01719 #endif
01720
01721
01722 rc = rpmpsmNext(psm, PSM_CHROOT_IN);
01723
01724 if (psm->goal == PSM_PKGINSTALL) {
01725 psm->scriptTag = RPMTAG_PREIN;
01726 psm->progTag = RPMTAG_PREINPROG;
01727 psm->sense = RPMSENSE_TRIGGERPREIN;
01728 psm->countCorrection = 0;
01729
01730 if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOTRIGGERPREIN)) {
01731
01732
01733 rc = rpmpsmNext(psm, PSM_TRIGGERS);
01734 if (rc) break;
01735
01736
01737 rc = rpmpsmNext(psm, PSM_IMMED_TRIGGERS);
01738 if (rc) break;
01739 }
01740
01741 if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOPRE)) {
01742 rc = rpmpsmNext(psm, PSM_SCRIPT);
01743 if (rc != RPMRC_OK) {
01744 rpmError(RPMERR_SCRIPT,
01745 _("%s: %s scriptlet failed (%d), skipping %s\n"),
01746 psm->stepName, tag2sln(psm->scriptTag), rc,
01747 rpmteNEVR(psm->te));
01748 break;
01749 }
01750 }
01751 }
01752
01753 if (psm->goal == PSM_PKGERASE) {
01754 psm->scriptTag = RPMTAG_PREUN;
01755 psm->progTag = RPMTAG_PREUNPROG;
01756 psm->sense = RPMSENSE_TRIGGERUN;
01757 psm->countCorrection = -1;
01758
01759 if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOTRIGGERUN)) {
01760
01761 rc = rpmpsmNext(psm, PSM_IMMED_TRIGGERS);
01762 if (rc) break;
01763
01764
01765 rc = rpmpsmNext(psm, PSM_TRIGGERS);
01766 if (rc) break;
01767 }
01768
01769 if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOPREUN))
01770 rc = rpmpsmNext(psm, PSM_SCRIPT);
01771 }
01772 if (psm->goal == PSM_PKGSAVE) {
01773 int noArchiveSize = 0;
01774 const char * origin;
01775
01776
01777 { void * uh = NULL;
01778 int_32 uht, uhc;
01779
01780
01781 origin = NULL;
01782 xx = headerGetEntry(fi->h, RPMTAG_PACKAGEORIGIN, NULL,
01783 &origin, NULL);
01784
01785
01786 if (headerGetEntry(fi->h, RPMTAG_HEADERIMMUTABLE, &uht, &uh, &uhc)) {
01787 psm->oh = headerCopyLoad(uh);
01788 uh = hfd(uh, uht);
01789 } else
01790 if (headerGetEntry(fi->h, RPMTAG_HEADERIMAGE, &uht, &uh, &uhc))
01791 {
01792 HeaderIterator hi;
01793 int_32 tag, type, count;
01794 hPTR_t ptr;
01795 Header oh;
01796
01797
01798 oh = headerCopyLoad(uh);
01799
01800
01801 psm->oh = headerNew();
01802
01803
01804 for (hi = headerInitIterator(oh);
01805 headerNextIterator(hi, &tag, &type, &ptr, &count);
01806 ptr = headerFreeData((void *)ptr, type))
01807 {
01808 if (tag == RPMTAG_ARCHIVESIZE)
01809 noArchiveSize = 1;
01810 if (ptr) xx = hae(psm->oh, tag, type, ptr, count);
01811 }
01812 hi = headerFreeIterator(hi);
01813
01814
01815 oh = headerFree(oh);
01816 uh = hfd(uh, uht);
01817 } else
01818 break;
01819 }
01820
01821
01822
01823 rc = rpmpsmNext(psm, PSM_RPMIO_FLAGS);
01824
01825
01826
01827 { struct rpmlead lead;
01828
01829 memset(&lead, 0, sizeof(lead));
01830
01831 lead.major = 3;
01832 lead.minor = 0;
01833 lead.type = RPMLEAD_BINARY;
01834
01835
01836 lead.archnum = 0;
01837 lead.osnum = 0;
01838 lead.signature_type = RPMSIGTYPE_HEADERSIG;
01839
01840 strncpy(lead.name, rpmteNEVR(psm->te), sizeof(lead.name));
01841
01842 rc = writeLead(psm->fd, &lead);
01843 if (rc != RPMRC_OK) {
01844 rpmError(RPMERR_NOSPACE, _("Unable to write package: %s\n"),
01845 Fstrerror(psm->fd));
01846 break;
01847 }
01848 }
01849
01850
01851
01852 { Header sigh = headerRegenSigHeader(fi->h, noArchiveSize);
01853
01854 sigh = headerReload(sigh, RPMTAG_HEADERSIGNATURES);
01855 if (sigh == NULL) {
01856 rpmError(RPMERR_NOSPACE, _("Unable to reload signature header\n"));
01857 rc = RPMRC_FAIL;
01858 break;
01859 }
01860 rc = rpmWriteSignature(psm->fd, sigh);
01861 sigh = rpmFreeSignature(sigh);
01862 if (rc) break;
01863 }
01864
01865
01866 if (psm->oh != NULL)
01867 { int_32 tid = rpmtsGetTid(ts);
01868
01869 xx = hae(psm->oh, RPMTAG_REMOVETID, RPM_INT32_TYPE,
01870 &tid, 1);
01871
01872
01873 if (origin != NULL)
01874 xx = hae(psm->oh, RPMTAG_PACKAGEORIGIN, RPM_STRING_TYPE,
01875 origin, 1);
01876
01877
01878 xx = hCopyTag(fi->h, psm->oh, RPMTAG_INSTALLTID);
01879 xx = hCopyTag(fi->h, psm->oh, RPMTAG_BLINKPKGID);
01880 xx = hCopyTag(fi->h, psm->oh, RPMTAG_BLINKHDRID);
01881 xx = hCopyTag(fi->h, psm->oh, RPMTAG_BLINKNEVRA);
01882
01883 assert(psm->te != NULL);
01884 xx = hSaveFlinks(psm->oh, &psm->te->flink);
01885 }
01886
01887
01888 rc = headerWrite(psm->fd, psm->oh, HEADER_MAGIC_YES);
01889 if (rc) break;
01890 }
01891 break;
01892 case PSM_PROCESS:
01893 if (rpmtsFlags(ts) & RPMTRANS_FLAG_TEST) break;
01894
01895 if (psm->goal == PSM_PKGINSTALL) {
01896
01897 if (rpmtsFlags(ts) & RPMTRANS_FLAG_JUSTDB) break;
01898
01899
01900 if (rpmfiFC(fi) <= 0) {
01901 void * ptr;
01902 ptr = rpmtsNotify(ts, fi->te, RPMCALLBACK_INST_START, 0, 100);
01903 ptr = rpmtsNotify(ts, fi->te, RPMCALLBACK_INST_PROGRESS, 100, 100);
01904 break;
01905 }
01906
01907
01908 rc = rpmpsmNext(psm, PSM_RPMIO_FLAGS);
01909
01910 if (rpmteFd(fi->te) == NULL) {
01911 rc = RPMRC_FAIL;
01912 break;
01913 }
01914
01915
01916 psm->cfd = Fdopen(fdDup(Fileno(rpmteFd(fi->te))), psm->rpmio_flags);
01917
01918 if (psm->cfd == NULL) {
01919 rc = RPMRC_FAIL;
01920 break;
01921 }
01922
01923 rc = fsmSetup(fi->fsm, FSM_PKGINSTALL, psm->payload_format, ts, fi,
01924 psm->cfd, NULL, &psm->failedFile);
01925 (void) rpmswAdd(rpmtsOp(ts, RPMTS_OP_UNCOMPRESS),
01926 fdstat_op(psm->cfd, FDSTAT_READ));
01927 (void) rpmswAdd(rpmtsOp(ts, RPMTS_OP_DIGEST),
01928 fdstat_op(psm->cfd, FDSTAT_DIGEST));
01929 xx = fsmTeardown(fi->fsm);
01930
01931 saveerrno = errno;
01932 xx = Fclose(psm->cfd);
01933 psm->cfd = NULL;
01934
01935 errno = saveerrno;
01936
01937
01938 if (!rc)
01939 rc = rpmpsmNext(psm, PSM_COMMIT);
01940
01941
01942 psm->what = RPMCALLBACK_INST_PROGRESS;
01943 psm->amount = (fi->archiveSize ? fi->archiveSize : 100);
01944 psm->total = psm->amount;
01945 xx = rpmpsmNext(psm, PSM_NOTIFY);
01946
01947 if (rc) {
01948 rpmError(RPMERR_CPIO,
01949 _("unpacking of archive failed%s%s: %s\n"),
01950 (psm->failedFile != NULL ? _(" on file ") : ""),
01951 (psm->failedFile != NULL ? psm->failedFile : ""),
01952 cpioStrerror(rc));
01953 rc = RPMRC_FAIL;
01954
01955
01956 psm->what = RPMCALLBACK_UNPACK_ERROR;
01957 psm->amount = 0;
01958 psm->total = 0;
01959 xx = rpmpsmNext(psm, PSM_NOTIFY);
01960
01961 break;
01962 }
01963 }
01964 if (psm->goal == PSM_PKGERASE) {
01965 int fc = rpmfiFC(fi);
01966
01967 if (rpmtsFlags(ts) & RPMTRANS_FLAG_JUSTDB) break;
01968 if (rpmtsFlags(ts) & RPMTRANS_FLAG_APPLYONLY) break;
01969 if (fc <= 0) break;
01970
01971 psm->what = RPMCALLBACK_UNINST_START;
01972 psm->amount = fc;
01973 psm->total = fc;
01974 xx = rpmpsmNext(psm, PSM_NOTIFY);
01975
01976 rc = fsmSetup(fi->fsm, FSM_PKGERASE, psm->payload_format, ts, fi,
01977 NULL, NULL, &psm->failedFile);
01978 xx = fsmTeardown(fi->fsm);
01979
01980 psm->what = RPMCALLBACK_UNINST_STOP;
01981 psm->amount = 0;
01982 psm->total = fc;
01983 xx = rpmpsmNext(psm, PSM_NOTIFY);
01984
01985 }
01986 if (psm->goal == PSM_PKGSAVE) {
01987 fileAction * actions = fi->actions;
01988 fileAction action = fi->action;
01989
01990 fi->action = FA_COPYOUT;
01991 fi->actions = NULL;
01992
01993 if (psm->fd == NULL) {
01994 rc = RPMRC_FAIL;
01995 break;
01996 }
01997
01998 xx = Fflush(psm->fd);
01999 psm->cfd = Fdopen(fdDup(Fileno(psm->fd)), psm->rpmio_flags);
02000
02001 if (psm->cfd == NULL) {
02002 rc = RPMRC_FAIL;
02003 break;
02004 }
02005
02006 rc = fsmSetup(fi->fsm, FSM_PKGBUILD, psm->payload_format, ts, fi,
02007 psm->cfd, NULL, &psm->failedFile);
02008 (void) rpmswAdd(rpmtsOp(ts, RPMTS_OP_COMPRESS),
02009 fdstat_op(psm->cfd, FDSTAT_WRITE));
02010 (void) rpmswAdd(rpmtsOp(ts, RPMTS_OP_DIGEST),
02011 fdstat_op(psm->cfd, FDSTAT_DIGEST));
02012 xx = fsmTeardown(fi->fsm);
02013
02014 saveerrno = errno;
02015 xx = Fclose(psm->cfd);
02016 psm->cfd = NULL;
02017
02018 errno = saveerrno;
02019
02020
02021
02022 psm->what = RPMCALLBACK_INST_PROGRESS;
02023 psm->amount = (fi->archiveSize ? fi->archiveSize : 100);
02024 psm->total = psm->amount;
02025 xx = rpmpsmNext(psm, PSM_NOTIFY);
02026
02027 fi->action = action;
02028 fi->actions = actions;
02029 }
02030 break;
02031 case PSM_POST:
02032 if (rpmtsFlags(ts) & RPMTRANS_FLAG_TEST) break;
02033
02034 if (psm->goal == PSM_PKGINSTALL) {
02035
02036
02037
02038
02039
02040 if (fi->record && !(rpmtsFlags(ts) & RPMTRANS_FLAG_APPLYONLY)) {
02041 rc = rpmpsmNext(psm, PSM_RPMDB_REMOVE);
02042 if (rc) break;
02043 }
02044
02045 rc = rpmpsmNext(psm, PSM_RPMDB_ADD);
02046 if (rc) break;
02047
02048 psm->scriptTag = RPMTAG_POSTIN;
02049 psm->progTag = RPMTAG_POSTINPROG;
02050 psm->sense = RPMSENSE_TRIGGERIN;
02051 psm->countCorrection = 0;
02052
02053 if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOPOST)) {
02054 rc = rpmpsmNext(psm, PSM_SCRIPT);
02055 if (rc) break;
02056 }
02057 if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOTRIGGERIN)) {
02058
02059 rc = rpmpsmNext(psm, PSM_TRIGGERS);
02060 if (rc) break;
02061
02062
02063 rc = rpmpsmNext(psm, PSM_IMMED_TRIGGERS);
02064 if (rc) break;
02065 }
02066
02067 if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_APPLYONLY))
02068 rc = markReplacedFiles(psm);
02069
02070 }
02071 if (psm->goal == PSM_PKGERASE) {
02072
02073 psm->scriptTag = RPMTAG_POSTUN;
02074 psm->progTag = RPMTAG_POSTUNPROG;
02075 psm->sense = RPMSENSE_TRIGGERPOSTUN;
02076 psm->countCorrection = -1;
02077
02078 if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOPOSTUN)) {
02079 rc = rpmpsmNext(psm, PSM_SCRIPT);
02080 if (rc) break;
02081 }
02082
02083 if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOTRIGGERPOSTUN)) {
02084
02085 rc = rpmpsmNext(psm, PSM_TRIGGERS);
02086 if (rc) break;
02087
02088
02089 rc = rpmpsmNext(psm, PSM_IMMED_TRIGGERS);
02090 if (rc) break;
02091 }
02092
02093 if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_APPLYONLY))
02094 rc = rpmpsmNext(psm, PSM_RPMDB_REMOVE);
02095 }
02096 if (psm->goal == PSM_PKGSAVE) {
02097 }
02098
02099
02100 xx = rpmpsmNext(psm, PSM_CHROOT_OUT);
02101 break;
02102 case PSM_UNDO:
02103 break;
02104 case PSM_FINI:
02105
02106 xx = rpmpsmNext(psm, PSM_CHROOT_OUT);
02107
02108 if (psm->fd != NULL) {
02109 saveerrno = errno;
02110 xx = Fclose(psm->fd);
02111 psm->fd = NULL;
02112
02113 errno = saveerrno;
02114
02115 }
02116
02117 if (psm->goal == PSM_PKGSAVE) {
02118 if (!rc && ts && ts->notify == NULL) {
02119 rpmMessage(RPMMESS_VERBOSE, _("Wrote: %s\n"),
02120 (psm->pkgURL ? psm->pkgURL : "???"));
02121 }
02122 }
02123
02124 if (rc) {
02125 if (psm->failedFile)
02126 rpmError(RPMERR_CPIO,
02127 _("%s failed on file %s: %s\n"),
02128 psm->stepName, psm->failedFile, cpioStrerror(rc));
02129 else
02130 rpmError(RPMERR_CPIO, _("%s failed: %s\n"),
02131 psm->stepName, cpioStrerror(rc));
02132
02133
02134 psm->what = RPMCALLBACK_CPIO_ERROR;
02135 psm->amount = 0;
02136 psm->total = 0;
02137
02138 xx = rpmpsmNext(psm, PSM_NOTIFY);
02139
02140 }
02141
02142
02143 if (psm->goal == PSM_PKGERASE || psm->goal == PSM_PKGSAVE) {
02144 if (psm->te != NULL)
02145 if (psm->te->h != NULL)
02146 psm->te->h = headerFree(psm->te->h);
02147 if (fi->h != NULL)
02148 fi->h = headerFree(fi->h);
02149 }
02150
02151 psm->oh = headerFree(psm->oh);
02152 psm->pkgURL = _free(psm->pkgURL);
02153 psm->rpmio_flags = _free(psm->rpmio_flags);
02154 psm->payload_format = _free(psm->payload_format);
02155 psm->failedFile = _free(psm->failedFile);
02156
02157 fi->fgroup = hfd(fi->fgroup, -1);
02158 fi->fuser = hfd(fi->fuser, -1);
02159 fi->apath = _free(fi->apath);
02160 fi->fstates = _free(fi->fstates);
02161 break;
02162
02163 case PSM_PKGINSTALL:
02164 case PSM_PKGERASE:
02165 case PSM_PKGSAVE:
02166 psm->goal = stage;
02167 psm->rc = RPMRC_OK;
02168 psm->stepName = pkgStageString(stage);
02169
02170 rc = rpmpsmNext(psm, PSM_INIT);
02171 if (!rc) rc = rpmpsmNext(psm, PSM_PRE);
02172 if (!rc) rc = rpmpsmNext(psm, PSM_PROCESS);
02173 if (!rc) rc = rpmpsmNext(psm, PSM_POST);
02174 xx = rpmpsmNext(psm, PSM_FINI);
02175 break;
02176 case PSM_PKGCOMMIT:
02177 break;
02178
02179 case PSM_CREATE:
02180 break;
02181 case PSM_NOTIFY:
02182 { void * ptr;
02183
02184 ptr = rpmtsNotify(ts, psm->te, psm->what, psm->amount, psm->total);
02185
02186 } break;
02187 case PSM_DESTROY:
02188 break;
02189 case PSM_COMMIT:
02190 if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_PKGCOMMIT)) break;
02191 if (rpmtsFlags(ts) & RPMTRANS_FLAG_APPLYONLY) break;
02192
02193 rc = fsmSetup(fi->fsm, FSM_PKGCOMMIT, psm->payload_format, ts, fi,
02194 NULL, NULL, &psm->failedFile);
02195 xx = fsmTeardown(fi->fsm);
02196 break;
02197
02198 case PSM_CHROOT_IN:
02199 { const char * rootDir = rpmtsRootDir(ts);
02200
02201 if (rootDir != NULL && !(rootDir[0] == '/' && rootDir[1] == '\0')
02202 && !rpmtsChrootDone(ts) && !psm->chrootDone)
02203 {
02204 static int _pw_loaded = 0;
02205 static int _gr_loaded = 0;
02206
02207 if (!_pw_loaded) {
02208 (void)getpwnam("root");
02209 endpwent();
02210 _pw_loaded++;
02211 }
02212 if (!_gr_loaded) {
02213 (void)getgrnam("root");
02214 endgrent();
02215 _gr_loaded++;
02216 }
02217
02218 xx = Chdir("/");
02219
02220 if (rootDir != NULL && strcmp(rootDir, "/") && *rootDir == '/')
02221 rc = Chroot(rootDir);
02222
02223 psm->chrootDone = 1;
02224 (void) rpmtsSetChrootDone(ts, 1);
02225 }
02226 } break;
02227 case PSM_CHROOT_OUT:
02228
02229 if (psm->chrootDone) {
02230 const char * rootDir = rpmtsRootDir(ts);
02231 const char * currDir = rpmtsCurrDir(ts);
02232
02233 if (rootDir != NULL && strcmp(rootDir, "/") && *rootDir == '/')
02234 rc = Chroot(".");
02235
02236 psm->chrootDone = 0;
02237 (void) rpmtsSetChrootDone(ts, 0);
02238 if (currDir != NULL)
02239 xx = Chdir(currDir);
02240 }
02241 break;
02242 case PSM_SCRIPT:
02243 rc = runInstScript(psm);
02244 break;
02245 case PSM_TRIGGERS:
02246
02247 if (rpmtsFlags(ts) & RPMTRANS_FLAG_TEST) break;
02248 rc = runTriggers(psm);
02249 break;
02250 case PSM_IMMED_TRIGGERS:
02251
02252 if (rpmtsFlags(ts) & RPMTRANS_FLAG_TEST) break;
02253 rc = runImmedTriggers(psm);
02254 break;
02255
02256 case PSM_RPMIO_FLAGS:
02257 { const char * payload_compressor = NULL;
02258 const char * payload_format = NULL;
02259 char * t;
02260
02261
02262 if (!hge(fi->h, RPMTAG_PAYLOADCOMPRESSOR, NULL,
02263 &payload_compressor, NULL))
02264 payload_compressor = "gzip";
02265
02266 psm->rpmio_flags = t = xmalloc(sizeof("w9.gzdio"));
02267 *t = '\0';
02268 t = stpcpy(t, ((psm->goal == PSM_PKGSAVE) ? "w9" : "r"));
02269 if (!strcmp(payload_compressor, "gzip"))
02270 t = stpcpy(t, ".gzdio");
02271 if (!strcmp(payload_compressor, "bzip2"))
02272 t = stpcpy(t, ".bzdio");
02273 if (!strcmp(payload_compressor, "lzma"))
02274 t = stpcpy(t, ".lzdio");
02275
02276
02277 if (!hge(fi->h, RPMTAG_PAYLOADFORMAT, NULL,
02278 &payload_format, NULL)
02279 || !(!strcmp(payload_format, "tar") || !strcmp(payload_format, "ustar")))
02280 payload_format = "cpio";
02281
02282 psm->payload_format = xstrdup(payload_format);
02283 rc = RPMRC_OK;
02284 } break;
02285
02286 case PSM_RPMDB_LOAD:
02287 assert(psm->mi == NULL);
02288 psm->mi = rpmtsInitIterator(ts, RPMDBI_PACKAGES,
02289 &fi->record, sizeof(fi->record));
02290 fi->h = rpmdbNextIterator(psm->mi);
02291 if (fi->h != NULL)
02292 fi->h = headerLink(fi->h);
02293 psm->mi = rpmdbFreeIterator(psm->mi);
02294
02295 if (fi->h != NULL) {
02296 (void) headerSetInstance(fi->h, fi->record);
02297 rc = RPMRC_OK;
02298 } else
02299 rc = RPMRC_FAIL;
02300 break;
02301 case PSM_RPMDB_ADD:
02302 if (rpmtsFlags(ts) & RPMTRANS_FLAG_TEST) break;
02303 if (fi->h == NULL) break;
02304
02305
02306
02307 { uint_32 tid = ((rpmtsType(ts) == RPMTRANS_TYPE_ROLLBACK)
02308 ? hLoadTID(fi->h, RPMTAG_INSTALLTID) : rpmtsGetTid(ts));
02309 (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_DBADD), 0);
02310 if (!(rpmtsVSFlags(ts) & RPMVSF_NOHDRCHK))
02311 rc = rpmdbAdd(rpmtsGetRdb(ts), tid, fi->h, ts, headerCheck);
02312 else
02313 rc = rpmdbAdd(rpmtsGetRdb(ts), tid, fi->h, NULL, NULL);
02314 (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_DBADD), 0);
02315 }
02316
02317 if (rc != RPMRC_OK) break;
02318
02319 assert(psm->te != NULL);
02320
02321 if (rpmtsType(ts) != RPMTRANS_TYPE_ROLLBACK)
02322 psm->te->installed = 1;
02323
02324
02325 rpmteSetDBInstance(psm->te, headerGetInstance(fi->h));
02326
02327 break;
02328 case PSM_RPMDB_REMOVE:
02329 {
02330 if (rpmtsFlags(ts) & RPMTRANS_FLAG_TEST) break;
02331
02332 (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_DBREMOVE), 0);
02333 rc = rpmdbRemove(rpmtsGetRdb(ts), rpmtsGetTid(ts), fi->record,
02334 NULL, NULL);
02335 (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_DBREMOVE), 0);
02336
02337 if (rc != RPMRC_OK) break;
02338
02339
02340 psm->te->u.removed.dboffset = 0;
02341
02342 } break;
02343
02344 default:
02345 break;
02346 }
02347
02348
02349
02350 return rc;
02351
02352 }
02353