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, (void **) &epochOne, NULL))
00060 epochOne = &zero;
00061 if (!headerGetEntry(second, RPMTAG_EPOCH, NULL, (void **) &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, (void **) &one, NULL);
00072 rc = headerGetEntry(second, RPMTAG_VERSION, NULL, (void **) &two, NULL);
00073
00074 rc = rpmvercmp(one, two);
00075 if (rc)
00076 return rc;
00077
00078 rc = headerGetEntry(first, RPMTAG_RELEASE, NULL, (void **) &one, NULL);
00079 rc = headerGetEntry(second, RPMTAG_RELEASE, NULL, (void **) &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, (void **)&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 _("%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, (void **) &a, NULL);
00633
00634 if (progArgv && strcmp(progArgv[0], "<lua>") == 0) {
00635 #ifdef WITH_LUA
00636 rpmMessage(RPMMESS_DEBUG,
00637 _("%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 _("%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 _("%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, (void **) &prefixes, &numPrefixes)) {
00717 freePrefixes = 1;
00718 } else if (hge(h, RPMTAG_INSTALLPREFIX, NULL, (void **) &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, (void **) &script, NULL);
00982 xx = hge(fi->h, psm->progTag, &ptt, (void **) &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