00001
00006 #include "system.h"
00007
00008 #define _MIRE_INTERNAL
00009
00010 #include <rpmio_internal.h>
00011 #include <rpmcb.h>
00012 #include <rpmmacro.h>
00013 #include <rpmurl.h>
00014
00015 #include <rpmficl.h>
00016 #include <rpmjs.h>
00017 #include <rpmlua.h>
00018 #include <rpmperl.h>
00019 #include <rpmpython.h>
00020 #include <rpmruby.h>
00021 #include <rpmtcl.h>
00022
00023 #include <rpmtag.h>
00024 #include <rpmtypes.h>
00025 #include <rpmlib.h>
00026
00027 #define _RPMFI_INTERNAL
00028 #include "rpmfi.h"
00029 #include "fsm.h"
00030 #define _RPMSQ_INTERNAL
00031 #include "psm.h"
00032 #define F_ISSET(_psm, _FLAG) ((_psm)->flags & (RPMPSM_FLAGS_##_FLAG))
00033 #define F_SET(_psm, _FLAG) ((_psm)->flags |= (RPMPSM_FLAGS_##_FLAG))
00034 #define F_CLR(_psm, _FLAG) ((_psm)->flags &= ~(RPMPSM_FLAGS_##_FLAG))
00035
00036 #define _RPMEVR_INTERNAL
00037 #include "rpmds.h"
00038
00039 #define _RPMTE_INTERNAL
00040 #include "rpmte.h"
00041
00042 #define _RPMTS_INTERNAL
00043 #include "rpmts.h"
00044
00045 #include <pkgio.h>
00046 #include "misc.h"
00047 #include "rpmdb.h"
00048 #include "signature.h"
00049
00050 #include <rpmcli.h>
00051
00052 #include "debug.h"
00053
00054 #define _PSM_DEBUG 0
00055
00056 int _psm_debug = _PSM_DEBUG;
00057
00058 int _psm_threads = 0;
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00077 static rpmRC markReplacedFiles(const rpmpsm psm)
00078
00079
00080 {
00081 HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
00082 const rpmts ts = psm->ts;
00083 rpmte te = psm->te;
00084 rpmfi fi = psm->fi;
00085 sharedFileInfo replaced = (te ? te->replaced : NULL);
00086 sharedFileInfo sfi;
00087 rpmmi mi;
00088 Header h;
00089 int * offsets;
00090 rpmuint32_t prev;
00091 int num;
00092 int xx;
00093
00094 if (!(rpmfiFC(fi) > 0 && replaced != NULL))
00095 return RPMRC_OK;
00096
00097 num = prev = 0;
00098 for (sfi = replaced; sfi->otherPkg; sfi++) {
00099 if (prev && prev == sfi->otherPkg)
00100 continue;
00101 prev = sfi->otherPkg;
00102 num++;
00103 }
00104 if (num == 0)
00105 return RPMRC_OK;
00106
00107 offsets = alloca(num * sizeof(*offsets));
00108 offsets[0] = 0;
00109 num = prev = 0;
00110 for (sfi = replaced; sfi->otherPkg; sfi++) {
00111 if (prev && prev == sfi->otherPkg)
00112 continue;
00113 prev = sfi->otherPkg;
00114 offsets[num++] = sfi->otherPkg;
00115 }
00116
00117 mi = rpmtsInitIterator(ts, RPMDBI_PACKAGES, NULL, 0);
00118 xx = rpmmiGrow(mi, offsets, num);
00119 xx = rpmmiSetRewrite(mi, 1);
00120
00121 sfi = replaced;
00122 while ((h = rpmmiNext(mi)) != NULL) {
00123 int modified;
00124
00125 modified = 0;
00126
00127
00128 he->tag = RPMTAG_FILESTATES;
00129 xx = headerGet(h, he, 0);
00130 if (!xx)
00131 continue;
00132
00133 prev = rpmmiInstance(mi);
00134 num = 0;
00135 while (sfi->otherPkg && sfi->otherPkg == prev) {
00136 assert(sfi->otherFileNum < he->c);
00137 if (he->p.ui8p[sfi->otherFileNum] != RPMFILE_STATE_REPLACED) {
00138 he->p.ui8p[sfi->otherFileNum] = RPMFILE_STATE_REPLACED;
00139 if (modified == 0) {
00140
00141 modified = 1;
00142 xx = rpmmiSetModified(mi, modified);
00143 }
00144 num++;
00145 }
00146 sfi++;
00147 }
00148 he->p.ptr = _free(he->p.ptr);
00149 }
00150 mi = rpmmiFree(mi);
00151
00152 return RPMRC_OK;
00153 }
00154
00155 #if defined(RPM_VENDOR_OPENPKG)
00156 static rpmRC createDir(rpmfi fi, rpmts ts, const char ** fn, const char * name)
00157 #else
00158 static rpmRC createDir(rpmts ts, const char ** fn, const char * name)
00159 #endif
00160
00161
00162 {
00163 const char * N = rpmGenPath(rpmtsRootDir(ts), name, "");
00164 char * t = xstrdup(name+2);
00165 rpmRC rc;
00166
00167 t[strlen(t)-1] = '\0';
00168
00169 if(fn) *fn = N;
00170
00171 rc = rpmMkdirPath(N, t+1);
00172 if (rc != RPMRC_OK) {
00173 if (Access(N, W_OK))
00174 rpmlog(RPMLOG_ERR, _("cannot write to %%%s %s\n"), t, N);
00175 #if defined(RPM_VENDOR_OPENPKG)
00176 else
00177 Chown(N, fi->uid, fi->gid);
00178 #endif
00179 }
00180 t = _free(t);
00181 return rc;
00182 }
00183
00184 rpmRC rpmInstallSourcePackage(rpmts ts, void * _fd,
00185 const char ** specFilePtr, const char ** cookie)
00186 {
00187 HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
00188 FD_t fd = _fd;
00189 int scareMem = 0;
00190 rpmfi fi = NULL;
00191 const char * _sourcedir = NULL;
00192 const char * _specdir = NULL;
00193 const char * specFile = NULL;
00194 Header h = NULL;
00195 struct rpmpsm_s psmbuf;
00196 rpmpsm psm = &psmbuf;
00197 int isSource;
00198 rpmRC rpmrc;
00199 int xx;
00200 int i;
00201
00202 memset(psm, 0, sizeof(*psm));
00203
00204 psm->ts = rpmtsLink(ts, "InstallSourcePackage");
00205
00206
00207
00208 rpmrc = rpmReadPackageFile(ts, fd, "InstallSourcePackage", &h);
00209
00210 switch (rpmrc) {
00211 case RPMRC_NOTTRUSTED:
00212 case RPMRC_NOKEY:
00213 case RPMRC_OK:
00214 break;
00215 default:
00216 goto exit;
00217 break;
00218 }
00219 if (h == NULL)
00220 goto exit;
00221
00222 rpmrc = RPMRC_OK;
00223
00224 isSource =
00225 (headerIsEntry(h, RPMTAG_SOURCERPM) == 0 &&
00226 headerIsEntry(h, RPMTAG_ARCH) != 0);
00227
00228 if (!isSource) {
00229 rpmlog(RPMLOG_ERR, _("source package expected, binary found\n"));
00230 rpmrc = RPMRC_FAIL;
00231 goto exit;
00232 }
00233
00234 (void) rpmtsAddInstallElement(ts, h, NULL, 0, NULL);
00235
00236 fi = rpmfiNew(ts, h, RPMTAG_BASENAMES, scareMem);
00237 fi->h = headerLink(h);
00238 (void)headerFree(h);
00239 h = NULL;
00240
00241 if (fi == NULL) {
00242 rpmrc = RPMRC_FAIL;
00243 goto exit;
00244 }
00245
00246
00247 fi->te = rpmtsElement(ts, 0);
00248
00249 if (fi->te == NULL) {
00250 rpmrc = RPMRC_FAIL;
00251 goto exit;
00252 }
00253
00254 assert(fi->h != NULL);
00255 assert(((rpmte)fi->te)->h == NULL);
00256 (void) rpmteSetHeader(fi->te, fi->h);
00257
00258
00259 ((rpmte)fi->te)->fd = fdLink(fd, "installSourcePackage");
00260
00261
00262
00263 (void) headerMacrosLoad(fi->h);
00264
00265 psm->fi = rpmfiLink(fi, NULL);
00266
00267 psm->te = fi->te;
00268
00269
00270 if (cookie) {
00271 *cookie = NULL;
00272 he->tag = RPMTAG_COOKIE;
00273 xx = headerGet(fi->h, he, 0);
00274 *cookie = he->p.str;
00275 }
00276
00277
00278 fi->fmapflags = _free(fi->fmapflags);
00279 fi->mapflags = IOSM_MAP_PATH | IOSM_MAP_MODE | IOSM_MAP_UID | IOSM_MAP_GID;
00280
00281 fi->uid = getuid();
00282 fi->gid = getgid();
00283 #if defined(RPM_VENDOR_OPENPKG)
00284
00285
00286
00287
00288
00289
00290 if (fi->uid == 0) {
00291 char *muid_str;
00292 char *mgid_str;
00293 uid_t muid;
00294 gid_t mgid;
00295 if ((muid_str = rpmExpand("%{l_muid}", NULL)) != NULL)
00296 if ((muid = (uid_t)strtol(muid_str, (char **)NULL, 10)) > 0)
00297 fi->uid = muid;
00298 if ((mgid_str = rpmExpand("%{l_mgid}", NULL)) != NULL)
00299 if ((mgid = (gid_t)strtol(mgid_str, (char **)NULL, 10)) > 0)
00300 fi->gid = mgid;
00301 }
00302 #endif
00303 fi->astriplen = 0;
00304 fi->striplen = 0;
00305
00306 for (i = 0; i < (int)fi->fc; i++)
00307 fi->actions[i] = FA_CREATE;
00308
00309 i = fi->fc;
00310
00311 if (fi->h != NULL) {
00312 he->tag = RPMTAG_FILEPATHS;
00313 xx = headerGet(fi->h, he, 0);
00314 fi->apath = he->p.argv;
00315
00316 if (headerIsEntry(fi->h, RPMTAG_COOKIE))
00317 for (i = 0; i < (int)fi->fc; i++)
00318 if (fi->fflags[i] & RPMFILE_SPECFILE) break;
00319 }
00320
00321 if (i == (int)fi->fc) {
00322
00323 for (i = 0; i < (int)fi->fc; i++) {
00324 const char * t = fi->apath[i];
00325 t += strlen(fi->apath[i]) - 5;
00326 if (!strcmp(t, ".spec")) break;
00327 }
00328 }
00329
00330 #if defined(RPM_VENDOR_OPENPKG)
00331 if(createDir(fi, ts, NULL, "%{_topdir}") ||
00332 createDir(fi, ts, NULL, "%{_builddir}") ||
00333 createDir(fi, ts, NULL, "%{_rpmdir}") ||
00334 createDir(fi, ts, NULL, "%{_srcrpmdir}") ||
00335 createDir(fi, ts, &_sourcedir, "%{_sourcedir}") ||
00336 createDir(fi, ts, &_specdir, "%{_specdir}"))
00337 #else
00338 if(createDir(ts, NULL, "%{_topdir}") ||
00339 createDir(ts, NULL, "%{_builddir}") ||
00340 createDir(ts, NULL, "%{_rpmdir}") ||
00341 createDir(ts, NULL, "%{_srcrpmdir}") ||
00342 createDir(ts, &_sourcedir, "%{_sourcedir}") ||
00343 createDir(ts, &_specdir, "%{_specdir}"))
00344 #endif
00345 goto exit;
00346
00347
00348 if (i < (int)fi->fc) {
00349 size_t speclen = strlen(_specdir) + 2;
00350 size_t sourcelen = strlen(_sourcedir) + 2;
00351 char * t;
00352
00353 fi->dnl = _free(fi->dnl);
00354
00355 fi->dc = 2;
00356 fi->dnl = xmalloc(fi->dc * sizeof(*fi->dnl)
00357 + fi->fc * sizeof(*fi->dil)
00358 + speclen + sourcelen);
00359
00360 fi->dil = (unsigned int *)(fi->dnl + fi->dc);
00361
00362 memset(fi->dil, 0, fi->fc * sizeof(*fi->dil));
00363 fi->dil[i] = 1;
00364
00365 fi->dnl[0] = t = (char *)(fi->dil + fi->fc);
00366 fi->dnl[1] = t = stpcpy( stpcpy(t, _sourcedir), "/") + 1;
00367
00368 (void) stpcpy( stpcpy(t, _specdir), "/");
00369
00370 t = xmalloc(speclen + strlen(fi->bnl[i]) + 1);
00371 (void) stpcpy( stpcpy( stpcpy(t, _specdir), "/"), fi->bnl[i]);
00372 specFile = t;
00373 } else {
00374 rpmlog(RPMLOG_ERR, _("source package contains no .spec file\n"));
00375 rpmrc = RPMRC_FAIL;
00376 goto exit;
00377 }
00378
00379 psm->goal = PSM_PKGINSTALL;
00380
00381
00382 rpmrc = rpmpsmStage(psm, PSM_PROCESS);
00383
00384 (void) rpmpsmStage(psm, PSM_FINI);
00385
00386
00387 if (rpmrc) rpmrc = RPMRC_FAIL;
00388
00389 exit:
00390 if (specFilePtr && specFile && rpmrc == RPMRC_OK)
00391 *specFilePtr = specFile;
00392 else
00393 specFile = _free(specFile);
00394
00395 _specdir = _free(_specdir);
00396 _sourcedir = _free(_sourcedir);
00397
00398 psm->fi = rpmfiFree(psm->fi);
00399 psm->te = NULL;
00400
00401 if (h != NULL) (void)headerFree(h);
00402 h = NULL;
00403
00404 if (fi != NULL) {
00405 (void) rpmteSetHeader(fi->te, NULL);
00406
00407 if (((rpmte)fi->te)->fd != NULL)
00408 (void) Fclose(((rpmte)fi->te)->fd);
00409
00410 ((rpmte)fi->te)->fd = NULL;
00411 fi->te = NULL;
00412 #if 0
00413 fi = rpmfiFree(fi);
00414 #endif
00415 }
00416
00417
00418 rpmtsClean(ts);
00419
00420 (void)rpmtsFree(psm->ts);
00421 psm->ts = NULL;
00422
00423 return rpmrc;
00424 }
00425
00426
00427 static char * SCRIPT_PATH = "PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/X11R6/bin";
00428
00434 static const char * tag2sln(rpmTag tag)
00435
00436 {
00437 switch (tag) {
00438 case RPMTAG_PRETRANS: return "%pretrans";
00439 case RPMTAG_TRIGGERPREIN: return "%triggerprein";
00440 case RPMTAG_PREIN: return "%pre";
00441 case RPMTAG_POSTIN: return "%post";
00442 case RPMTAG_TRIGGERIN: return "%triggerin";
00443 case RPMTAG_TRIGGERUN: return "%triggerun";
00444 case RPMTAG_PREUN: return "%preun";
00445 case RPMTAG_POSTUN: return "%postun";
00446 case RPMTAG_POSTTRANS: return "%posttrans";
00447 case RPMTAG_TRIGGERPOSTUN: return "%triggerpostun";
00448 case RPMTAG_VERIFYSCRIPT: return "%verify";
00449 case RPMTAG_SANITYCHECK: return "%sanitycheck";
00450 default: break;
00451 }
00452 return "%unknownscript";
00453 }
00454
00460 static rpmScriptID tag2slx(rpmTag tag)
00461
00462 {
00463 switch (tag) {
00464 case RPMTAG_PRETRANS: return RPMSCRIPT_PRETRANS;
00465 case RPMTAG_TRIGGERPREIN: return RPMSCRIPT_TRIGGERPREIN;
00466 case RPMTAG_PREIN: return RPMSCRIPT_PREIN;
00467 case RPMTAG_POSTIN: return RPMSCRIPT_POSTIN;
00468 case RPMTAG_TRIGGERIN: return RPMSCRIPT_TRIGGERIN;
00469 case RPMTAG_TRIGGERUN: return RPMSCRIPT_TRIGGERUN;
00470 case RPMTAG_PREUN: return RPMSCRIPT_PREUN;
00471 case RPMTAG_POSTUN: return RPMSCRIPT_POSTUN;
00472 case RPMTAG_POSTTRANS: return RPMSCRIPT_POSTTRANS;
00473 case RPMTAG_TRIGGERPOSTUN: return RPMSCRIPT_TRIGGERPOSTUN;
00474 case RPMTAG_VERIFYSCRIPT: return RPMSCRIPT_VERIFY;
00475 case RPMTAG_SANITYCHECK: return RPMSCRIPT_SANITYCHECK;
00476 default: break;
00477 }
00478 return RPMSCRIPT_UNKNOWN;
00479 }
00480
00486 static pid_t psmWait(rpmpsm psm)
00487
00488
00489 {
00490 const rpmts ts = psm->ts;
00491 rpmtime_t msecs;
00492
00493 (void) rpmsqWait(&psm->sq);
00494 msecs = psm->sq.op.usecs/1000;
00495 (void) rpmswAdd(rpmtsOp(ts, RPMTS_OP_SCRIPTLETS), &psm->sq.op);
00496
00497 rpmlog(RPMLOG_DEBUG,
00498 D_("%s: waitpid(%d) rc %d status %x secs %u.%03u\n"),
00499 psm->stepName, (unsigned)psm->sq.child,
00500 (unsigned)psm->sq.reaped, psm->sq.status,
00501 (unsigned)msecs/1000, (unsigned)msecs%1000);
00502
00503 if (psm->sstates != NULL)
00504 { int * ssp = psm->sstates + tag2slx(psm->scriptTag);
00505 *ssp &= ~0xffff;
00506 *ssp |= (psm->sq.status & 0xffff);
00507 *ssp |= RPMSCRIPT_STATE_REAPED;
00508 }
00509
00510 return psm->sq.reaped;
00511 }
00512
00513 #ifdef WITH_LUA
00514
00525 static rpmRC runLuaScript(rpmpsm psm, const char * sln, HE_t Phe,
00526 const char *script, int arg1, int arg2)
00527
00528
00529 {
00530 rpmRC rc = RPMRC_OK;
00531 int xx;
00532 rpmlua lua = NULL;
00533 rpmluav var;
00534
00535
00536 rpmluaPushTable(lua, "arg");
00537 var = rpmluavNew();
00538 rpmluavSetListMode(var, 1);
00539
00540 if (Phe->p.argv) {
00541 int i;
00542 for (i = 0; i < (int)Phe->c && Phe->p.argv[i]; i++) {
00543 rpmluavSetValue(var, RPMLUAV_STRING, Phe->p.argv[i]);
00544 rpmluaSetVar(lua, var);
00545 }
00546 }
00547 if (arg1 >= 0) {
00548 rpmluavSetValueNum(var, arg1);
00549 rpmluaSetVar(lua, var);
00550 }
00551 if (arg2 >= 0) {
00552 rpmluavSetValueNum(var, arg2);
00553 rpmluaSetVar(lua, var);
00554 }
00555
00556
00557 var = rpmluavFree(var);
00558
00559 rpmluaPop(lua);
00560
00561 { char buf[BUFSIZ];
00562 xx = snprintf(buf, BUFSIZ, "%s(%s)", sln, psm->NVRA);
00563 xx = rpmluaRunScript(lua, script, buf);
00564 if (xx == -1) {
00565 void * ptr = rpmtsNotify(psm->ts, psm->te, RPMCALLBACK_SCRIPT_ERROR,
00566 psm->scriptTag, 1);
00567 ptr = ptr;
00568 rc = RPMRC_FAIL;
00569 } else
00570 rc = RPMRC_OK;
00571 }
00572 rpmluaDelVar(lua, "arg");
00573
00574 return rc;
00575 }
00576 #endif
00577
00578 #if defined(WITH_LUA) || defined(WITH_FICL) || defined(WITH_JS) || defined(WITH_PERLEMBED) || defined(WITH_PYTHONEMBED) || defined(WITH_RUBYEMBED) || defined(WITH_TCL)
00579 static int enterChroot(rpmpsm psm, int * fdnop)
00580
00581
00582 {
00583 const rpmts ts = psm->ts;
00584 int inChroot;
00585 int xx;
00586
00587
00588 if (fdnop)
00589 (*fdnop) = open(".", O_RDONLY, 0);
00590
00591
00592 if (!rpmtsChrootDone(ts)) {
00593 const char *rootDir = rpmtsRootDir(ts);
00594 inChroot = 0;
00595
00596 if (rootDir != NULL && strcmp(rootDir, "/") && *rootDir == '/') {
00597 xx = Chroot(rootDir);
00598
00599 xx = rpmtsSetChrootDone(ts, 1);
00600 }
00601 } else
00602 inChroot = 1;
00603
00604
00605 xx = Chdir("/");
00606
00607 return inChroot;
00608 }
00609
00610 static int exitChroot(rpmpsm psm, int inChroot, int rootFdno)
00611
00612
00613 {
00614 const rpmts ts = psm->ts;
00615 const char *rootDir = rpmtsRootDir(ts);
00616 int xx;
00617
00618 if (rpmtsChrootDone(ts) && !inChroot) {
00619 xx = fchdir(rootFdno);
00620
00621 if (rootDir != NULL && strcmp(rootDir, "/") && *rootDir == '/') {
00622 xx = Chroot(".");
00623
00624 xx = rpmtsSetChrootDone(ts, 0);
00625 }
00626 } else
00627 xx = fchdir(rootFdno);
00628
00629 xx = close(rootFdno);
00630
00631 return 0;
00632 }
00633
00645 static rpmRC runEmbeddedScript(rpmpsm psm, const char * sln, HE_t Phe,
00646 const char *script, int arg1, int arg2)
00647
00648
00649 {
00650 char * av[] = { NULL, NULL, NULL, NULL };
00651 int rootFdno = -1;
00652 rpmRC rc = RPMRC_OK;
00653 int xx = 0;
00654 int * ssp = NULL;
00655 int inChroot = enterChroot(psm, &rootFdno);
00656
00657 if (psm->sstates != NULL)
00658 ssp = psm->sstates + tag2slx(psm->scriptTag);
00659 if (ssp != NULL)
00660 *ssp |= (RPMSCRIPT_STATE_LUA|RPMSCRIPT_STATE_EXEC);
00661
00662 av[0] = (char *) Phe->p.argv[0];
00663 if (arg1 >= 0)
00664 (void) sprintf((av[1] = alloca(32)), "%d", arg1);
00665 if (arg2 >= 0)
00666 (void) sprintf((av[2] = alloca(32)), "%d", arg2);
00667
00668 #if defined(WITH_LUA)
00669 if (!strcmp(Phe->p.argv[0], "<lua>")) {
00670 rc = runLuaScript(psm, sln, Phe, script, arg1, arg2);
00671 } else
00672 #endif
00673 #if defined(WITH_FICL)
00674 if (!strcmp(Phe->p.argv[0], "<ficl>")) {
00675 rpmficl ficl = rpmficlNew((const char **)av, 0);
00676 rc = rpmficlRun(ficl, script, NULL) == RPMRC_OK
00677 ? RPMRC_OK : RPMRC_FAIL;
00678 ficl = rpmficlFree(ficl);
00679 } else
00680 #endif
00681 #if defined(WITH_JS)
00682 if (!strcmp(Phe->p.argv[0], "<js>")) {
00683 rpmjs js = rpmjsNew((const char **)av, 0);
00684 rc = rpmjsRun(js, script, NULL) == RPMRC_OK
00685 ? RPMRC_OK : RPMRC_FAIL;
00686 js = rpmjsFree(js);
00687 } else
00688 #endif
00689 #if defined(WITH_PERLEMBED)
00690 if (!strcmp(Phe->p.argv[0], "<perl>")) {
00691 rpmperl perl = rpmperlNew((const char **)av, 0);
00692 rc = rpmperlRun(perl, script, NULL) == RPMRC_OK
00693 ? RPMRC_OK : RPMRC_FAIL;
00694 perl = rpmperlFree(perl);
00695 } else
00696 #endif
00697 #if defined(WITH_PYTHONEMBED)
00698 if (!strcmp(Phe->p.argv[0], "<python>")) {
00699 rpmpython python = rpmpythonNew((const char **)av, 0);
00700 rc = rpmpythonRun(python, script, NULL) == RPMRC_OK
00701 ? RPMRC_OK : RPMRC_FAIL;
00702 python = rpmpythonFree(python);
00703 } else
00704 #endif
00705 #if defined(WITH_RUBYEMBED)
00706 if (!strcmp(Phe->p.argv[0], "<ruby>")) {
00707 rpmruby ruby = rpmrubyNew((const char **)av, 0);
00708 rc = rpmrubyRun(ruby, script, NULL) == RPMRC_OK
00709 ? RPMRC_OK : RPMRC_FAIL;
00710 ruby = rpmrubyFree(ruby);
00711 } else
00712 #endif
00713 #if defined(WITH_TCL)
00714 if (!strcmp(Phe->p.argv[0], "<tcl>")) {
00715 rpmtcl tcl = rpmtclNew((const char **)av, 0);
00716 rc = rpmtclRun(tcl, script, NULL) == RPMRC_OK
00717 ? RPMRC_OK : RPMRC_FAIL;
00718 tcl = rpmtclFree(tcl);
00719 } else
00720 #endif
00721 rc = RPMRC_NOTFOUND;
00722
00723 if (ssp != NULL) {
00724 *ssp &= ~0xffff;
00725 *ssp |= (xx & 0xffff);
00726 *ssp |= RPMSCRIPT_STATE_REAPED;
00727 }
00728
00729 xx = exitChroot(psm, inChroot, rootFdno);
00730
00731 return rc;
00732 }
00733 #endif
00734
00737
00738 static int ldconfig_done = 0;
00739
00740
00741 static const char * ldconfig_path = "/sbin/ldconfig";
00742
00759 static rpmRC runScript(rpmpsm psm, Header h, const char * sln, HE_t Phe,
00760 const char * script, int arg1, int arg2)
00761
00762
00763
00764
00765 {
00766 const rpmts ts = psm->ts;
00767 const char * NVRA = psm->NVRA;
00768 HE_t IPhe = psm->IPhe;
00769 const char ** argv = NULL;
00770 int argc = 0;
00771 const char ** IP = NULL;
00772 int nIP;
00773 size_t maxPrefixLength;
00774 size_t len;
00775 char * prefixBuf = NULL;
00776 const char * fn = NULL;
00777 FD_t scriptFd = NULL;
00778 FD_t out = NULL;
00779 rpmRC rc = RPMRC_FAIL;
00780 const char * body = NULL;
00781 int * ssp = NULL;
00782 pid_t pid;
00783 int xx;
00784 int i;
00785
00786 if (psm->sstates != NULL)
00787 ssp = psm->sstates + tag2slx(psm->scriptTag);
00788 if (ssp != NULL)
00789 *ssp = RPMSCRIPT_STATE_UNKNOWN;
00790
00791 if (Phe->p.argv == NULL && script == NULL)
00792 return RPMRC_OK;
00793
00794
00795 body = rpmExpand(script, NULL);
00796
00797
00798 if (NVRA == NULL) {
00799 HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
00800 he->tag = RPMTAG_NVRA;
00801 xx = headerGet(h, he, 0);
00802 assert(he->p.str != NULL);
00803 psm->NVRA = NVRA = he->p.str;
00804 }
00805
00806 if (Phe->p.argv && Phe->p.argv[0])
00807 if (!strcmp(Phe->p.argv[0], "<lua>")
00808 || !strcmp(Phe->p.argv[0], "<ficl>")
00809 || !strcmp(Phe->p.argv[0], "<js>")
00810 || !strcmp(Phe->p.argv[0], "<perl>")
00811 || !strcmp(Phe->p.argv[0], "<python>")
00812 || !strcmp(Phe->p.argv[0], "<ruby>")
00813 || !strcmp(Phe->p.argv[0], "<tcl>"))
00814 {
00815 #if defined(WITH_LUA) || defined(WITH_FICL) || defined(WITH_JS) || defined(WITH_PERLEMBED) || defined(WITH_PYTHONEMBED) || defined(WITH_RUBYEMBED) || defined(WITH_TCL)
00816 rpmlog(RPMLOG_DEBUG,
00817 D_("%s: %s(%s) running %s scriptlet.\n"),
00818 psm->stepName, tag2sln(psm->scriptTag), NVRA, Phe->p.argv[0]);
00819 rc = runEmbeddedScript(psm, sln, Phe, body, arg1, arg2);
00820 #endif
00821 goto exit;
00822 }
00823
00824 psm->sq.reaper = 1;
00825
00826
00827
00828
00829 if (ldconfig_path && Phe->p.argv != NULL && F_ISSET(psm, UNORDERED)) {
00830 if (ldconfig_done && !strcmp(Phe->p.argv[0], ldconfig_path)) {
00831 rpmlog(RPMLOG_DEBUG,
00832 D_("%s: %s(%s) skipping redundant \"%s\".\n"),
00833 psm->stepName, tag2sln(psm->scriptTag), NVRA,
00834 Phe->p.argv[0]);
00835 rc = RPMRC_OK;
00836 goto exit;
00837 }
00838 }
00839
00840 rpmlog(RPMLOG_DEBUG,
00841 D_("%s: %s(%s) %ssynchronous scriptlet start\n"),
00842 psm->stepName, tag2sln(psm->scriptTag), NVRA,
00843 (F_ISSET(psm, UNORDERED) ? "a" : ""));
00844
00845 if (Phe->p.argv == NULL) {
00846 argv = alloca(5 * sizeof(*argv));
00847 argv[0] = "/bin/sh";
00848 argc = 1;
00849 ldconfig_done = 0;
00850 } else {
00851 argv = alloca((Phe->c + 4) * sizeof(*argv));
00852 memcpy(argv, Phe->p.argv, Phe->c * sizeof(*argv));
00853 argc = Phe->c;
00854 ldconfig_done = (ldconfig_path && !strcmp(argv[0], ldconfig_path)
00855 ? 1 : 0);
00856 }
00857
00858
00859 if (IPhe->tag == 0) {
00860 IPhe->tag = RPMTAG_INSTPREFIXES;
00861 xx = headerGet(h, IPhe, 0);
00862 if (!xx) {
00863 IPhe->p.ptr = _free(IPhe->p.ptr);
00864 IPhe->tag = RPMTAG_INSTALLPREFIX;
00865 xx = headerGet(h, IPhe, 0);
00866 if (xx) {
00867 const char ** av =
00868 xmalloc(sizeof(*av) + strlen(IPhe->p.argv[0]) + 1);
00869 char * t = (char *) &av[1];
00870
00871 av[0] = t;
00872 t = stpcpy(t, IPhe->p.argv[0]);
00873 *t = '\0';
00874 IPhe->p.ptr = _free(IPhe->p.ptr);
00875 IPhe->t = RPM_STRING_ARRAY_TYPE;
00876 IPhe->p.argv = av;
00877 IPhe->c = 1;
00878 } else {
00879 IPhe->p.argv = NULL;
00880 IPhe->c = 0;
00881 }
00882 }
00883 }
00884 IP = IPhe->p.argv;
00885 nIP = IPhe->c;
00886
00887 maxPrefixLength = 0;
00888 if (IP != NULL)
00889 for (i = 0; i < nIP; i++) {
00890 len = strlen(IP[i]);
00891 if (len > maxPrefixLength) maxPrefixLength = len;
00892 }
00893 prefixBuf = alloca(maxPrefixLength + 50);
00894
00895 if (script) {
00896 const char * rootDir = rpmtsRootDir(ts);
00897 FD_t fd;
00898 size_t nw;
00899
00900 if (rpmTempFile((!rpmtsChrootDone(ts) ? rootDir : "/"), &fn, &fd))
00901 goto exit;
00902
00903 if (rpmIsDebug() &&
00904 (!strcmp(argv[0], "/bin/sh") || !strcmp(argv[0], "/bin/bash")))
00905 {
00906 static const char set_x[] = "set -x\n";
00907 nw = Fwrite(set_x, sizeof(set_x[0]), sizeof(set_x)-1, fd);
00908 }
00909
00910 if (ldconfig_path && strstr(body, ldconfig_path) != NULL)
00911 ldconfig_done = 1;
00912
00913 nw = Fwrite(body, sizeof(body[0]), strlen(body), fd);
00914 xx = Fclose(fd);
00915
00916 { const char * sn = fn;
00917 if (!rpmtsChrootDone(ts) && rootDir != NULL &&
00918 !(rootDir[0] == '/' && rootDir[1] == '\0'))
00919 {
00920 sn += strlen(rootDir)-1;
00921 }
00922 argv[argc++] = sn;
00923 }
00924
00925 if (arg1 >= 0) {
00926 char *av = alloca(20);
00927 sprintf(av, "%d", arg1);
00928 argv[argc++] = av;
00929 }
00930 if (arg2 >= 0) {
00931 char *av = alloca(20);
00932 sprintf(av, "%d", arg2);
00933 argv[argc++] = av;
00934 }
00935 }
00936
00937 argv[argc] = NULL;
00938
00939 scriptFd = rpmtsScriptFd(ts);
00940 if (scriptFd != NULL) {
00941 if (rpmIsVerbose()) {
00942 out = fdDup(Fileno(scriptFd));
00943 } else {
00944 out = Fopen("/dev/null", "w.fdio");
00945 if (Ferror(out)) {
00946 out = fdDup(Fileno(scriptFd));
00947 }
00948 }
00949 } else {
00950 out = fdDup(STDOUT_FILENO);
00951 }
00952 if (out == NULL)
00953 goto exit;
00954
00955 pid = rpmsqFork(&psm->sq);
00956 if (psm->sq.child == 0) {
00957 int pipes[2];
00958 int flag;
00959 int fdno;
00960
00961 pipes[0] = pipes[1] = 0;
00962
00963 xx = pipe(pipes);
00964 xx = close(pipes[1]);
00965 xx = dup2(pipes[0], STDIN_FILENO);
00966 xx = close(pipes[0]);
00967
00968
00969 for (fdno = 3; fdno < 100; fdno++) {
00970 flag = fcntl(fdno, F_GETFD);
00971 if (flag == -1 || (flag & FD_CLOEXEC))
00972 continue;
00973 rpmlog(RPMLOG_DEBUG,
00974 D_("%s: %s(%s)\tfdno(%d) missing FD_CLOEXEC\n"),
00975 psm->stepName, sln, NVRA,
00976 fdno);
00977 xx = fcntl(fdno, F_SETFD, FD_CLOEXEC);
00978
00979 }
00980
00981 if (scriptFd != NULL) {
00982 int sfdno = Fileno(scriptFd);
00983 int ofdno = Fileno(out);
00984 if (sfdno != STDERR_FILENO)
00985 xx = dup2(sfdno, STDERR_FILENO);
00986 if (ofdno != STDOUT_FILENO)
00987 xx = dup2(ofdno, STDOUT_FILENO);
00988
00989 if (ofdno > STDERR_FILENO && ofdno != sfdno)
00990 xx = Fclose (out);
00991 if (sfdno > STDERR_FILENO && ofdno != sfdno)
00992 xx = Fclose (scriptFd);
00993 }
00994
00995 { const char *ipath = rpmExpand("PATH=%{_install_script_path}", NULL);
00996 const char *path = SCRIPT_PATH;
00997
00998 if (ipath && ipath[5] != '%')
00999 path = ipath;
01000
01001 xx = doputenv(path);
01002
01003 ipath = _free(ipath);
01004
01005 }
01006
01007 if (IP != NULL)
01008 for (i = 0; i < nIP; i++) {
01009 sprintf(prefixBuf, "RPM_INSTALL_PREFIX%d=%s", i, IP[i]);
01010 xx = doputenv(prefixBuf);
01011
01012
01013 if (i == 0) {
01014 sprintf(prefixBuf, "RPM_INSTALL_PREFIX=%s", IP[i]);
01015 xx = doputenv(prefixBuf);
01016 }
01017 }
01018
01019 { const char * rootDir = rpmtsRootDir(ts);
01020 if (!rpmtsChrootDone(ts) && rootDir != NULL &&
01021 !(rootDir[0] == '/' && rootDir[1] == '\0'))
01022 {
01023
01024 xx = Chroot(rootDir);
01025
01026 }
01027 xx = Chdir("/");
01028 rpmlog(RPMLOG_DEBUG, D_("%s: %s(%s)\texecv(%s) pid %d\n"),
01029 psm->stepName, sln, NVRA,
01030 argv[0], (unsigned)getpid());
01031
01032
01033 unsetenv("MALLOC_CHECK_");
01034
01035 if (ssp != NULL)
01036 *ssp |= RPMSCRIPT_STATE_EXEC;
01037
01038
01039 if (rpmtsSELinuxEnabled(ts) == 1) {
01040 if (ssp != NULL)
01041 *ssp |= RPMSCRIPT_STATE_SELINUX;
01042
01043 xx = rpm_execcon(0, argv[0], (char *const *)argv, environ);
01044
01045 } else {
01046
01047 xx = execv(argv[0], (char *const *)argv);
01048
01049 }
01050 }
01051
01052 if (ssp != NULL)
01053 *ssp &= ~RPMSCRIPT_STATE_EXEC;
01054
01055 _exit(-1);
01056
01057 }
01058
01059 if (psm->sq.child == (pid_t)-1) {
01060 rpmlog(RPMLOG_ERR, _("Couldn't fork %s: %s\n"), sln, strerror(errno));
01061 goto exit;
01062 }
01063
01064 (void) psmWait(psm);
01065
01066
01067 if (!(psm->sq.reaped >= 0 && !strcmp(argv[0], "/usr/sbin/glibc_post_upgrade") && WEXITSTATUS(psm->sq.status) == 110)) {
01068 void *ptr = NULL;
01069 if (psm->sq.reaped < 0) {
01070 rpmlog(RPMLOG_ERR,
01071 _("%s(%s) scriptlet failed, waitpid(%d) rc %d: %s\n"),
01072 sln, NVRA, (int)psm->sq.child, (int)psm->sq.reaped,
01073 strerror(errno));
01074 goto exit;
01075 } else
01076 if (!WIFEXITED(psm->sq.status) || WEXITSTATUS(psm->sq.status)) {
01077 if (WIFSIGNALED(psm->sq.status)) {
01078 ptr = rpmtsNotify(ts, psm->te, RPMCALLBACK_SCRIPT_ERROR,
01079 psm->scriptTag, WTERMSIG(psm->sq.status));
01080 rpmlog(RPMLOG_ERR,
01081 _("%s(%s) scriptlet failed, signal %d\n"),
01082 sln, NVRA, WTERMSIG(psm->sq.status));
01083 } else {
01084 ptr = rpmtsNotify(ts, psm->te, RPMCALLBACK_SCRIPT_ERROR,
01085 psm->scriptTag, WEXITSTATUS(psm->sq.status));
01086 rpmlog(RPMLOG_ERR,
01087 _("%s(%s) scriptlet failed, exit status %d\n"),
01088 sln, NVRA, WEXITSTATUS(psm->sq.status));
01089 }
01090 goto exit;
01091 }
01092 }
01093
01094 rc = RPMRC_OK;
01095
01096 exit:
01097 if (out)
01098 xx = Fclose(out);
01099
01100 if (script) {
01101 if (!rpmIsDebug() && fn != NULL)
01102 xx = Unlink(fn);
01103 fn = _free(fn);
01104 }
01105
01106 body = _free(body);
01107
01108 return rc;
01109 }
01110
01116 static rpmRC runInstScript(rpmpsm psm)
01117
01118
01119 {
01120 HE_t Phe = memset(alloca(sizeof(*Phe)), 0, sizeof(*Phe));
01121 HE_t She = memset(alloca(sizeof(*She)), 0, sizeof(*She));
01122 rpmfi fi = psm->fi;
01123 const char * argv0 = NULL;
01124 rpmRC rc = RPMRC_OK;
01125
01126 assert(fi->h != NULL);
01127 She->tag = psm->scriptTag;
01128 if (!headerGet(fi->h, She, 0))
01129 goto exit;
01130
01131 Phe->tag = psm->progTag;
01132 if (!headerGet(fi->h, Phe, 0))
01133 goto exit;
01134
01135
01136 if (Phe->t == RPM_STRING_TYPE) {
01137 const char * s = Phe->p.str;
01138 char * t;
01139 Phe->p.argv = xmalloc(sizeof(Phe->p.argv[0]) + strlen(s) + 1);
01140 Phe->p.argv[0] = t = (char *) &Phe->p.argv[1];
01141 t = stpcpy(t, s);
01142 *t = '\0';
01143 s = _free(s);
01144 }
01145
01146
01147 if (Phe->p.argv[0][0] == '%')
01148 Phe->p.argv[0] = argv0 = rpmExpand(Phe->p.argv[0], NULL);
01149
01150 rc = runScript(psm, fi->h, tag2sln(psm->scriptTag), Phe,
01151 She->p.str, psm->scriptArg, -1);
01152
01153 exit:
01154 argv0 = _free(argv0);
01155 Phe->p.ptr = _free(Phe->p.ptr);
01156 She->p.ptr = _free(She->p.ptr);
01157 return rc;
01158 }
01159
01160
01161 static rpmTag _trigger_tag;
01162
01171 static rpmRC handleOneTrigger(const rpmpsm psm,
01172 Header sourceH, Header triggeredH, int arg2)
01173
01174
01175
01176 {
01177 static int scareMem = 0;
01178 HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
01179 HE_t Ihe = memset(alloca(sizeof(*Ihe)), 0, sizeof(*Ihe));
01180 HE_t She = memset(alloca(sizeof(*She)), 0, sizeof(*She));
01181 HE_t Phe = memset(alloca(sizeof(*Phe)), 0, sizeof(*Phe));
01182 miRE mire = NULL;
01183 const rpmts ts = psm->ts;
01184 rpmds Tds = NULL;
01185 rpmds Fds = NULL;
01186 rpmds Dds = NULL;
01187 rpmds Pds = NULL;
01188 const char * sourceName;
01189 const char * triggerName;
01190 rpmRC rc = RPMRC_OK;
01191 int arg1;
01192 int xx;
01193 int i;
01194
01195 he->tag = RPMTAG_NAME;
01196 xx = headerGet(sourceH, he, 0);
01197 sourceName = he->p.str;
01198
01199 he->tag = RPMTAG_NAME;
01200 xx = headerGet(triggeredH, he, 0);
01201 triggerName = he->p.str;
01202
01203 arg1 = rpmdbCountPackages(rpmtsGetRdb(ts), triggerName);
01204 if (arg1 < 0) {
01205
01206 rc = RPMRC_FAIL;
01207 goto exit;
01208 }
01209 arg1 += psm->countCorrection;
01210
01211 Tds = rpmdsNew(triggeredH, RPMTAG_TRIGGERNAME, scareMem);
01212 if (Tds == NULL)
01213 goto exit;
01214 xx = rpmdsSetNoPromote(Tds, 1);
01215
01216 Ihe->tag = RPMTAG_TRIGGERINDEX;
01217 if (!headerGet(triggeredH, Ihe, 0))
01218 goto exit;
01219
01220 She->tag = RPMTAG_TRIGGERSCRIPTS;
01221 if (!headerGet(triggeredH, She, 0))
01222 goto exit;
01223
01224 Phe->tag = RPMTAG_TRIGGERSCRIPTPROG;
01225 if (!headerGet(triggeredH, Phe, 0))
01226 goto exit;
01227
01228 if ((Tds = rpmdsInit(Tds)) != NULL)
01229 while ((i = rpmdsNext(Tds)) >= 0) {
01230 rpmuint32_t Flags = rpmdsFlags(Tds);
01231 char * depName;
01232 int bingo;
01233
01234
01235 if (!(Flags & psm->sense))
01236 continue;
01237
01238 bingo = 0;
01239 depName = (char *) rpmdsN(Tds);
01240 if (depName[0] == '/') {
01241 size_t nb = strlen(depName);
01242 if (Glob_pattern_p(depName, 0)) {
01243 rpmds ds = NULL;
01244 if (depName[nb-1] == '/') {
01245
01246 if (Dds == NULL)
01247 Dds = rpmdsNew(sourceH, RPMTAG_DIRNAMES, 0x2);
01248 ds = rpmdsLink(Dds, "Triggers");
01249 } else {
01250 if (Fds == NULL)
01251 Fds = rpmdsNew(sourceH, RPMTAG_BASENAMES, 0);
01252 ds = rpmdsLink(Fds, "Triggers");
01253 }
01254 if (mire == NULL)
01255 mire = mireNew(RPMMIRE_GLOB, 0);
01256
01257 xx = mireRegcomp(mire, depName);
01258 if ((ds = rpmdsInit(ds)) != NULL)
01259 while (rpmdsNext(ds) >= 0) {
01260 const char * N = rpmdsN(ds);
01261 xx = mireRegexec(mire, N, 0);
01262 if (xx < 0)
01263 continue;
01264 bingo = 1;
01265 break;
01266 }
01267 (void)rpmdsFree(ds);
01268 ds = NULL;
01269 xx = mireClean(mire);
01270 }
01271
01272
01273 if (!bingo && depName[nb-1] == '/') {
01274
01275 if (Dds == NULL)
01276 Dds = rpmdsNew(sourceH, RPMTAG_DIRNAMES, 0x2);
01277 bingo = rpmdsMatch(Tds, Dds);
01278 }
01279
01280
01281 if (!bingo) {
01282 if (Fds == NULL)
01283 Fds = rpmdsNew(sourceH, RPMTAG_BASENAMES, 0);
01284 bingo = rpmdsMatch(Tds, Fds);
01285 }
01286 }
01287
01288
01289 if (!bingo) {
01290 if (Pds == NULL)
01291 Pds = rpmdsNew(sourceH, RPMTAG_PROVIDENAME, 0);
01292 bingo = rpmdsMatch(Tds, Pds);
01293 bingo = rpmdsNegateRC(Tds, bingo);
01294 }
01295 if (!bingo)
01296 continue;
01297
01298
01299
01300 { int index = Ihe->p.ui32p[i];
01301 const char * s = Phe->p.argv[index];
01302 char * t;
01303
01304 he->tag = Phe->tag;
01305 he->t = RPM_STRING_ARRAY_TYPE;
01306 he->c = 1;
01307 he->p.argv = xmalloc(sizeof(Phe->p.argv[0]) + strlen(s) + 1);
01308 he->p.argv[0] = t = (char *) &he->p.argv[1];
01309 t = stpcpy(t, s);
01310 *t = '\0';
01311
01312 rc |= runScript(psm, triggeredH, "%trigger", he,
01313 She->p.argv[index], arg1, arg2);
01314
01315 he->p.ptr = _free(he->p.ptr);
01316 }
01317 }
01318
01319 mire = mireFree(mire);
01320 (void)rpmdsFree(Pds);
01321 Pds = NULL;
01322 (void)rpmdsFree(Dds);
01323 Dds = NULL;
01324 (void)rpmdsFree(Fds);
01325 Fds = NULL;
01326 (void)rpmdsFree(Tds);
01327 Tds = NULL;
01328
01329 exit:
01330 Ihe->p.ptr = _free(Ihe->p.ptr);
01331 She->p.ptr = _free(She->p.ptr);
01332 Phe->p.ptr = _free(Phe->p.ptr);
01333 triggerName = _free(triggerName);
01334 sourceName = _free(sourceName);
01335
01336 return rc;
01337 }
01338
01339
01340 static int rpmdbTriggerGlobs(rpmpsm psm)
01341
01342
01343 {
01344 const rpmts ts = psm->ts;
01345 ARGV_t keys = NULL;
01346 int xx = rpmdbMireApply(rpmtsGetRdb(ts), RPMTAG_TRIGGERNAME,
01347 RPMMIRE_STRCMP, NULL, &keys);
01348 int nkeys = argvCount(keys);
01349 int i;
01350
01351 if (keys)
01352 for (i = 0; i < nkeys; i++) {
01353 char * t = (char *) keys[i];
01354 if (!Glob_pattern_p(t, 0))
01355 continue;
01356 xx = mireAppend(RPMMIRE_GLOB, 0, t, NULL,
01357 (miRE *)&psm->Tmires, &psm->nTmires);
01358 xx = argvAdd(&psm->Tpats, t);
01359 }
01360 keys = argvFree(keys);
01361 return 0;
01362 }
01363
01371 static rpmRC runTriggersLoop(rpmpsm psm, rpmTag tagno, int arg2)
01372
01373
01374
01375
01376 {
01377 static int scareMem = 0;
01378 const rpmts ts = psm->ts;
01379 rpmfi fi = psm->fi;
01380 rpmds ds = rpmdsNew(fi->h, tagno, scareMem);
01381 char * depName = NULL;
01382 ARGI_t instances = NULL;
01383 rpmmi mi;
01384 Header triggeredH;
01385 rpmRC rc = RPMRC_OK;
01386 int i;
01387 int xx;
01388
01389
01390 if ((ds = rpmdsInit(ds)) != NULL)
01391 while ((i = rpmdsNext(ds)) >= 0) {
01392 const char * Name = rpmdsN(ds);
01393 size_t nName = strlen(Name);
01394 unsigned prev, instance;
01395 unsigned nvals;
01396 ARGint_t vals;
01397
01398 depName = _free(depName);
01399 depName = xmalloc(nName + 1 + 1);
01400 (void) stpcpy(depName, Name);
01401
01402 depName[nName] = (tagno == RPMTAG_DIRNAMES ? '/' : '\0');
01403 depName[nName+1] = '\0';
01404
01405 if (depName[0] == '/' && psm->Tmires != NULL) {
01406 miRE mire;
01407 int j;
01408
01409
01410 for (j = 0, mire = psm->Tmires; j < psm->nTmires; j++, mire++) {
01411 const char * pattern = psm->Tpats[j];
01412 if (depName[nName-1] != '/') {
01413 size_t npattern = strlen(pattern);
01414 depName[nName] = (pattern[npattern-1] == '/') ? '/' : '\0';
01415 }
01416 if (mireRegexec(mire, depName, 0) < 0)
01417 continue;
01418
01419
01420 depName = _free(depName);
01421 depName = xstrdup(pattern);
01422 break;
01423 }
01424 }
01425
01426
01427 mi = rpmtsInitIterator(ts, RPMTAG_TRIGGERNAME, depName, 0);
01428
01429 nvals = argiCount(instances);
01430 vals = argiData(instances);
01431 if (nvals > 0)
01432 xx = rpmmiPrune(mi, (int *)vals, nvals, 1);
01433
01434 prev = 0;
01435 while((triggeredH = rpmmiNext(mi)) != NULL) {
01436 instance = rpmmiInstance(mi);
01437 if (prev == instance)
01438 continue;
01439 rc |= handleOneTrigger(psm, fi->h, triggeredH, arg2);
01440 prev = instance;
01441 xx = argiAdd(&instances, -1, instance);
01442 xx = argiSort(instances, NULL);
01443 }
01444
01445 mi = rpmmiFree(mi);
01446 }
01447
01448 instances = argiFree(instances);
01449 depName = _free(depName);
01450 (void)rpmdsFree(ds);
01451 ds = NULL;
01452
01453 return rc;
01454 }
01455
01461 static rpmRC runTriggers(rpmpsm psm)
01462
01463
01464
01465
01466 {
01467 const rpmts ts = psm->ts;
01468 rpmfi fi = psm->fi;
01469 int numPackage;
01470 rpmTag tagno;
01471 rpmRC rc = RPMRC_OK;
01472
01473
01474 if (_trigger_tag == 0) {
01475 const char * t = rpmExpand("%{?_trigger_tag}", NULL);
01476
01477 _trigger_tag = (!strcmp(t, "name") ? RPMTAG_NAME : RPMTAG_PROVIDENAME);
01478
01479 t = _free(t);
01480 }
01481 tagno = _trigger_tag;
01482
01483 assert(psm->te != NULL);
01484 { const char * N = rpmteN(psm->te);
01485 assert(N != NULL);
01486 numPackage = rpmdbCountPackages(rpmtsGetRdb(ts), N);
01487 numPackage += psm->countCorrection;
01488 if (numPackage < 0)
01489 return RPMRC_NOTFOUND;
01490 }
01491 assert(fi != NULL);
01492 assert(fi->h != NULL);
01493
01494
01495 { int countCorrection = psm->countCorrection;
01496
01497 psm->countCorrection = 0;
01498
01499
01500 rc |= runTriggersLoop(psm, tagno, numPackage);
01501
01502
01503 if (tagno != RPMTAG_NAME) {
01504 int xx;
01505
01506 xx = rpmdbTriggerGlobs(psm);
01507
01508 rc |= runTriggersLoop(psm, RPMTAG_BASENAMES, numPackage);
01509 rc |= runTriggersLoop(psm, RPMTAG_DIRNAMES, numPackage);
01510
01511 psm->Tpats = argvFree(psm->Tpats);
01512 psm->Tmires = mireFreeAll(psm->Tmires, psm->nTmires);
01513 psm->nTmires = 0;
01514 }
01515
01516 psm->countCorrection = countCorrection;
01517 }
01518
01519 return rc;
01520 }
01521
01527 static rpmRC runImmedTriggers(rpmpsm psm)
01528
01529
01530
01531
01532 {
01533 HE_t Ihe = memset(alloca(sizeof(*Ihe)), 0, sizeof(*Ihe));
01534 const rpmts ts = psm->ts;
01535 rpmfi fi = psm->fi;
01536 rpmds triggers = NULL;
01537 rpmmi mi;
01538 ARGV_t keys = NULL;
01539 ARGI_t instances = NULL;
01540 Header sourceH = NULL;
01541 const char * Name;
01542 rpmTag tagno;
01543 rpmRC rc = RPMRC_OK;
01544 int i;
01545 int xx;
01546
01547 assert(fi->h != NULL);
01548
01549
01550 if (_trigger_tag == 0) {
01551 const char * t = rpmExpand("%{?_trigger_tag}", NULL);
01552
01553 _trigger_tag = (!strcmp(t, "name") ? RPMTAG_NAME : RPMTAG_PROVIDENAME);
01554
01555 t = _free(t);
01556 }
01557 tagno = _trigger_tag;
01558
01559
01560 triggers = rpmdsLink(psm->triggers, "ImmedTriggers");
01561
01562 if (triggers == NULL)
01563 goto exit;
01564
01565 Ihe->tag = RPMTAG_TRIGGERINDEX;
01566 xx = headerGet(fi->h, Ihe, 0);
01567 if (!(xx && Ihe->p.ui32p && Ihe->c)) goto exit;
01568
01569
01570 triggers = rpmdsInit(triggers);
01571 if (triggers != NULL)
01572 while ((i = rpmdsNext(triggers)) >= 0) {
01573 evrFlags Flags = rpmdsFlags(triggers);
01574 const char * N = rpmdsN(triggers);
01575 const char * EVR = rpmdsEVR(triggers);
01576
01577
01578 if (!(Flags & psm->sense))
01579 continue;
01580
01581
01582 if (tagno != RPMTAG_NAME) {
01583
01584 if (N[0] == '/')
01585 tagno = (N[strlen(N)-1] == '/')
01586 ? RPMTAG_DIRNAMES : RPMTAG_FILEPATHS;
01587 }
01588
01589 if ((EVR == NULL || *EVR == '\0') && Glob_pattern_p(N, 0))
01590 xx = rpmdbMireApply(rpmtsGetRdb(ts), tagno, RPMMIRE_GLOB, N, &keys);
01591 else
01592 xx = argvAdd(&keys, N);
01593 }
01594 (void)rpmdsFree(triggers);
01595 triggers = NULL;
01596
01597
01598 if (keys != NULL)
01599 for (i = 0; (Name = keys[i]) != NULL; i++) {
01600 unsigned prev, instance;
01601 unsigned nvals;
01602 ARGint_t vals;
01603
01604
01605 if (tagno != RPMTAG_NAME) {
01606
01607 if (Name[0] == '/')
01608 tagno = (Name[strlen(Name)-1] == '/')
01609 ? RPMTAG_DIRNAMES : RPMTAG_FILEPATHS;
01610 }
01611
01612 mi = rpmtsInitIterator(ts, tagno, Name, 0);
01613
01614
01615 nvals = argiCount(instances);
01616 vals = argiData(instances);
01617 if (nvals > 0)
01618 xx = rpmmiPrune(mi, (int *)vals, nvals, 1);
01619
01620 prev = 0;
01621 while((sourceH = rpmmiNext(mi)) != NULL) {
01622
01623
01624 instance = rpmmiInstance(mi);
01625 if (prev == instance)
01626 continue;
01627
01628 rc |= handleOneTrigger(psm, sourceH, fi->h, rpmmiCount(mi));
01629
01630
01631 prev = instance;
01632 xx = argiAdd(&instances, -1, instance);
01633 xx = argiSort(instances, NULL);
01634 }
01635
01636 mi = rpmmiFree(mi);
01637 }
01638
01639 exit:
01640 instances = argiFree(instances);
01641 keys = argvFree(keys);
01642 Ihe->p.ptr = _free(Ihe->p.ptr);
01643 return rc;
01644 }
01645
01646
01647 static const char * pkgStageString(pkgStage a)
01648
01649 {
01650 switch(a) {
01651 case PSM_UNKNOWN: return "unknown";
01652
01653 case PSM_PKGINSTALL: return " install";
01654 case PSM_PKGERASE: return " erase";
01655 case PSM_PKGCOMMIT: return " commit";
01656 case PSM_PKGSAVE: return "repackage";
01657
01658 case PSM_INIT: return "init";
01659 case PSM_PRE: return "pre";
01660 case PSM_PROCESS: return "process";
01661 case PSM_POST: return "post";
01662 case PSM_UNDO: return "undo";
01663 case PSM_FINI: return "fini";
01664
01665 case PSM_CREATE: return "create";
01666 case PSM_NOTIFY: return "notify";
01667 case PSM_DESTROY: return "destroy";
01668 case PSM_COMMIT: return "commit";
01669
01670 case PSM_CHROOT_IN: return "chrootin";
01671 case PSM_CHROOT_OUT: return "chrootout";
01672 case PSM_SCRIPT: return "script";
01673 case PSM_TRIGGERS: return "triggers";
01674 case PSM_IMMED_TRIGGERS: return "immedtriggers";
01675
01676 case PSM_RPMIO_FLAGS: return "rpmioflags";
01677
01678 case PSM_RPMDB_LOAD: return "rpmdbload";
01679 case PSM_RPMDB_ADD: return "rpmdbadd";
01680 case PSM_RPMDB_REMOVE: return "rpmdbremove";
01681
01682 default: return "???";
01683 }
01684
01685 }
01686
01687
01688 static void rpmpsmFini(void * _psm)
01689
01690 {
01691 rpmpsm psm = _psm;
01692
01693
01694 psm->fi = rpmfiFree(psm->fi);
01695 #ifdef NOTYET
01696 psm->te = rpmteFree(psm->te);
01697 #else
01698 psm->te = NULL;
01699 #endif
01700
01701 (void)rpmtsFree(psm->ts);
01702 psm->ts = NULL;
01703
01704
01705 psm->sstates = _free(psm->sstates);
01706 psm->IPhe->p.ptr = _free(psm->IPhe->p.ptr);
01707 psm->IPhe = _free(psm->IPhe);
01708 psm->NVRA = _free(psm->NVRA);
01709 (void)rpmdsFree(psm->triggers);
01710 psm->triggers = NULL;
01711
01712 }
01713
01714
01715
01716 rpmioPool _psmPool;
01717
01718 static rpmpsm rpmpsmGetPool( rpmioPool pool)
01719
01720
01721 {
01722 rpmpsm psm;
01723
01724 if (_psmPool == NULL) {
01725 _psmPool = rpmioNewPool("psm", sizeof(*psm), -1, _psm_debug,
01726 NULL, NULL, rpmpsmFini);
01727 pool = _psmPool;
01728 }
01729 return (rpmpsm) rpmioGetPool(pool, sizeof(*psm));
01730 }
01731
01732 rpmpsm rpmpsmNew(rpmts ts, rpmte te, rpmfi fi)
01733 {
01734 static const char msg[] = "rpmpsmNew";
01735 rpmpsm psm = rpmpsmGetPool(_psmPool);
01736
01737
01738 if (ts) psm->ts = rpmtsLink(ts, msg);
01739 #ifdef NOTYET
01740 if (te) psm->te = rpmteLink(te, msg);
01741 #else
01742
01743 if (te) psm->te = te;
01744
01745 #endif
01746 if (fi) psm->fi = rpmfiLink(fi, msg);
01747
01748
01749 psm->triggers = NULL;
01750 psm->NVRA = NULL;
01751 psm->IPhe = xcalloc(1, sizeof(*psm->IPhe));
01752 psm->sstates = xcalloc(RPMSCRIPT_MAX, sizeof(*psm->sstates));
01753
01754 return rpmpsmLink(psm, msg);
01755 }
01756
01763 static rpmuint32_t hLoadTID(Header h, rpmTag tag)
01764
01765
01766 {
01767 HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
01768 rpmuint32_t val;
01769 int xx;
01770
01771 he->tag = tag;
01772 xx = headerGet(h, he, 0);
01773 val = (xx && he->p.ui32p ? he->p.ui32p[0] : 0);
01774 he->p.ptr = _free(he->p.ptr);
01775 return val;
01776 }
01777
01785 static int hCopyTag(Header sh, Header th, rpmTag tag)
01786
01787
01788 {
01789 HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
01790 int xx = 1;
01791
01792 he->tag = tag;
01793 if (headerGet(sh, he, 0) && he->c > 0)
01794 xx = headerPut(th, he, 0);
01795 he->p.ptr = _free(he->p.ptr);
01796 return 0;
01797 }
01798
01805 static int hSaveBlinks(Header h, const struct rpmChainLink_s * blink)
01806
01807 {
01808 HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
01809
01810 static const char * chain_end = RPMTE_CHAIN_END;
01811 int ac;
01812 int xx = 1;
01813
01814
01815 he->tag = RPMTAG_BLINKNEVRA;
01816 he->t = RPM_STRING_ARRAY_TYPE;
01817 ac = argvCount(blink->NEVRA);
01818 if (ac > 0) {
01819 he->p.argv = argvData(blink->NEVRA);
01820 he->c = ac;
01821 } else {
01822 he->p.argv = &chain_end;
01823 he->c = 1;
01824 }
01825 xx = headerPut(h, he, 0);
01826
01827 he->tag = RPMTAG_BLINKPKGID;
01828 he->t = RPM_STRING_ARRAY_TYPE;
01829 ac = argvCount(blink->Pkgid);
01830 if (ac > 0) {
01831 he->p.argv = argvData(blink->Pkgid);
01832 he->c = ac;
01833 } else {
01834 he->p.argv = &chain_end;
01835 he->c = 1;
01836 }
01837 xx = headerPut(h, he, 0);
01838
01839 he->tag = RPMTAG_BLINKHDRID;
01840 he->t = RPM_STRING_ARRAY_TYPE;
01841 ac = argvCount(blink->Hdrid);
01842 if (ac > 0) {
01843 he->p.argv = argvData(blink->Hdrid);
01844 he->c = ac;
01845 } else {
01846 he->p.argv = &chain_end;
01847 he->c = 1;
01848 }
01849 xx = headerPut(h, he, 0);
01850
01851 return 0;
01852 }
01853
01860 static int hSaveFlinks(Header h, const struct rpmChainLink_s * flink)
01861
01862 {
01863 HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
01864 #ifdef NOTYET
01865
01866 static const char * chain_end = RPMTE_CHAIN_END;
01867 #endif
01868 int ac;
01869 int xx = 1;
01870
01871
01872 he->tag = RPMTAG_FLINKNEVRA;
01873 he->t = RPM_STRING_ARRAY_TYPE;
01874 ac = argvCount(flink->NEVRA);
01875 if (ac > 0) {
01876 he->p.argv = argvData(flink->NEVRA);
01877 he->c = ac;
01878 }
01879 #ifdef NOTYET
01880 else {
01881 he->p.argv = &chain_end;
01882 he->c = 1;
01883 }
01884 #endif
01885 xx = headerPut(h, he, 0);
01886
01887 he->tag = RPMTAG_FLINKPKGID;
01888 he->t = RPM_STRING_ARRAY_TYPE;
01889 ac = argvCount(flink->Pkgid);
01890 if (ac > 0) {
01891 he->p.argv = argvData(flink->Pkgid);
01892 he->c = ac;
01893 }
01894 #ifdef NOTYET
01895 else {
01896 he->p.argv = &chain_end;
01897 he->c = 1;
01898 }
01899 #endif
01900 xx = headerPut(h, he, 0);
01901
01902 he->tag = RPMTAG_FLINKHDRID;
01903 he->t = RPM_STRING_ARRAY_TYPE;
01904 ac = argvCount(flink->Hdrid);
01905 if (ac > 0) {
01906 he->p.argv = argvData(flink->Hdrid);
01907 he->c = ac;
01908 }
01909 #ifdef NOTYET
01910 else {
01911 he->p.argv = &chain_end;
01912 he->c = 1;
01913 }
01914 #endif
01915 xx = headerPut(h, he, 0);
01916
01917 return 0;
01918 }
01919
01927 static int populateInstallHeader(const rpmts ts, const rpmte te, rpmfi fi)
01928
01929
01930 {
01931 HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
01932 rpmuint32_t tscolor = rpmtsColor(ts);
01933 rpmuint32_t tecolor = rpmteColor(te);
01934 rpmuint32_t * uip;
01935 rpmuint32_t installTime[2];
01936 rpmuint32_t originTime[2];
01937 rpmuint32_t originTid[2];
01938 int xx = 1;
01939
01940 assert(fi->h != NULL);
01941
01942 { struct timeval tv;
01943 xx = gettimeofday(&tv, NULL);
01944 installTime[0] = (rpmuint32_t) tv.tv_sec;
01945 installTime[1] = (rpmuint32_t) tv.tv_usec;
01946 }
01947 he->tag = RPMTAG_INSTALLTIME;
01948 he->t = RPM_UINT32_TYPE;
01949 he->p.ui32p = &installTime[0];
01950 he->c = 2;
01951 xx = headerPut(fi->h, he, 0);
01952
01953
01954 if ((uip = rpmteOriginTime(te)) != NULL)
01955 memcpy(originTime, uip, sizeof(originTime));
01956 if (originTime[0] == 0)
01957 memcpy(originTime, installTime, sizeof(originTime));
01958 he->tag = RPMTAG_ORIGINTIME;
01959 he->t = RPM_UINT32_TYPE;
01960 he->p.ui32p = originTime;
01961 he->c = 2;
01962 xx = headerPut(fi->h, he, 0);
01963
01964 if ((uip = rpmteOriginTid(te)) != NULL)
01965 memcpy(originTid, uip, sizeof(originTid));
01966 if (originTid[0] == 0)
01967 memcpy(originTid, ts->tid, sizeof(originTid));
01968 he->tag = RPMTAG_ORIGINTID;
01969 he->t = RPM_UINT32_TYPE;
01970 he->p.ui32p = originTid;
01971 he->c = 2;
01972 xx = headerPut(fi->h, he, 0);
01973
01974 he->tag = RPMTAG_INSTALLCOLOR;
01975 he->t = RPM_UINT32_TYPE;
01976 he->p.ui32p = &tscolor;
01977 he->c = 1;
01978 xx = headerPut(fi->h, he, 0);
01979
01980
01981
01982 he->tag = RPMTAG_PACKAGECOLOR;
01983 he->t = RPM_UINT32_TYPE;
01984 he->p.ui32p = &tecolor;
01985 he->c = 1;
01986 xx = headerPut(fi->h, he, 0);
01987
01988
01989 { const char * fn = headerGetOrigin(fi->h);
01990 const char * digest = headerGetDigest(fi->h);
01991 struct stat * st = headerGetStatbuf(fi->h);
01992
01993 if (fn != NULL) {
01994 he->tag = RPMTAG_PACKAGEORIGIN;
01995 he->t = RPM_STRING_TYPE;
01996 he->p.str = xstrdup(fn);
01997 he->c = 1;
01998 xx = headerPut(fi->h, he, 0);
01999 he->p.ptr = _free(he->p.ptr);
02000
02001 if (digest != NULL) {
02002 he->tag = RPMTAG_PACKAGEDIGEST;
02003 he->t = RPM_STRING_TYPE;
02004 he->p.str = headerGetDigest(fi->h);
02005 he->c = 1;
02006 xx = headerPut(fi->h, he, 0);
02007 }
02008 if (st != NULL) {
02009
02010 #ifndef DYING
02011 int ut = urlPath(fn, NULL);
02012
02013 if (!(ut == URL_IS_HTTP || ut == URL_IS_HTTPS))
02014 if (st->st_mode == 0 && st->st_mtime == 0 && st->st_size == 0)
02015 xx = Stat(fn, st);
02016 #endif
02017 if (st->st_mode != 0) {
02018 he->tag = RPMTAG_PACKAGESTAT;
02019 he->t = RPM_BIN_TYPE;
02020 he->p.ptr = (void *)st;
02021 he->c = (rpmTagCount) sizeof(*st);
02022 xx = headerPut(fi->h, he, 0);
02023 }
02024 }
02025 }
02026 }
02027
02028
02029 if (rpmtsType(ts) != RPMTRANS_TYPE_ROLLBACK)
02030 xx = hSaveBlinks(fi->h, &te->blink);
02031
02032 return 0;
02033 }
02034
02035
02043 static int postPopulateInstallHeader( const rpmts ts,
02044 const rpmte te, rpmfi fi)
02045
02046 {
02047 HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
02048 int fc = rpmfiFC(fi);
02049 int xx = 1;
02050
02051 if (fi->fstates != NULL && fc > 0) {
02052 he->tag = RPMTAG_FILESTATES;
02053 he->t = RPM_UINT8_TYPE;
02054 he->p.ui8p = fi->fstates;
02055 he->c = fc;
02056 xx = headerPut(fi->h, he, 0);
02057 }
02058
02059 return 0;
02060 }
02061
02062 #if defined(WITH_PTHREADS)
02063 static void * rpmpsmThread(void * arg)
02064
02065
02066 {
02067 rpmpsm psm = arg;
02068
02069 return ((void *) rpmpsmStage(psm, psm->nstage));
02070
02071 }
02072 #endif
02073
02074 static int rpmpsmNext(rpmpsm psm, pkgStage nstage)
02075
02076
02077 {
02078 psm->nstage = nstage;
02079 #if defined(WITH_PTHREADS)
02080 if (_psm_threads)
02081 return rpmsqJoin( rpmsqThread(rpmpsmThread, psm) );
02082 #endif
02083 return rpmpsmStage(psm, psm->nstage);
02084 }
02085
02090
02091 rpmRC rpmpsmStage(rpmpsm psm, pkgStage stage)
02092 {
02093 HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
02094 const rpmts ts = psm->ts;
02095 rpmuint32_t tscolor = rpmtsColor(ts);
02096 rpmfi fi = psm->fi;
02097 rpmRC rc = psm->rc;
02098 int saveerrno;
02099 int xx;
02100
02101
02102
02103 if (fi->h == NULL && fi->te && ((rpmte)fi->te)->h != NULL) fi->h = headerLink(((rpmte)fi->te)->h);
02104
02105
02106 switch (stage) {
02107 case PSM_UNKNOWN:
02108 break;
02109 case PSM_INIT:
02110 rpmlog(RPMLOG_DEBUG, D_("%s: %s has %d files, test = %d\n"),
02111 psm->stepName, rpmteNEVR(psm->te),
02112 rpmfiFC(fi), (rpmtsFlags(ts) & RPMTRANS_FLAG_TEST));
02113
02114
02115
02116
02117
02118
02119 psm->npkgs_installed = rpmdbCountPackages(rpmtsGetRdb(ts), rpmteN(psm->te));
02120 if (psm->npkgs_installed < 0) {
02121 rc = RPMRC_FAIL;
02122 break;
02123 }
02124
02125
02126 assert(psm->te != NULL);
02127 if (rpmtsType(ts) == RPMTRANS_TYPE_AUTOROLLBACK &&
02128 (psm->goal & ~(PSM_PKGSAVE|PSM_PKGERASE)))
02129 {
02130 if (psm->te->downgrade)
02131 psm->npkgs_installed--;
02132 }
02133
02134 if (psm->goal == PSM_PKGINSTALL) {
02135 int fc = rpmfiFC(fi);
02136 const char * hdrid;
02137
02138
02139 xx = populateInstallHeader(ts, psm->te, fi);
02140
02141 psm->scriptArg = psm->npkgs_installed + 1;
02142
02143 assert(psm->mi == NULL);
02144 hdrid = rpmteHdrid(psm->te);
02145 if (hdrid != NULL) {
02146
02147 psm->mi = rpmtsInitIterator(ts, RPMTAG_SHA1HEADER, hdrid, 0);
02148 } else {
02149 psm->mi = rpmtsInitIterator(ts, RPMTAG_NAME, rpmteN(psm->te),0);
02150 xx = rpmmiAddPattern(psm->mi, RPMTAG_EPOCH, RPMMIRE_STRCMP,
02151 rpmteE(psm->te));
02152 xx = rpmmiAddPattern(psm->mi, RPMTAG_VERSION, RPMMIRE_STRCMP,
02153 rpmteV(psm->te));
02154 xx = rpmmiAddPattern(psm->mi, RPMTAG_RELEASE, RPMMIRE_STRCMP,
02155 rpmteR(psm->te));
02156 #ifdef RPM_VENDOR_MANDRIVA
02157 xx = rpmmiAddPattern(psm->mi, RPMTAG_DISTEPOCH, RPMMIRE_STRCMP,
02158 rpmteD(psm->te));
02159 #endif
02160 if (tscolor) {
02161 xx = rpmmiAddPattern(psm->mi,RPMTAG_ARCH, RPMMIRE_STRCMP,
02162 rpmteA(psm->te));
02163 xx = rpmmiAddPattern(psm->mi, RPMTAG_OS, RPMMIRE_STRCMP,
02164 rpmteO(psm->te));
02165 }
02166 }
02167
02168 while ((psm->oh = rpmmiNext(psm->mi)) != NULL) {
02169 fi->record = rpmmiInstance(psm->mi);
02170 psm->oh = NULL;
02171 break;
02172 }
02173 psm->mi = rpmmiFree(psm->mi);
02174
02175 rc = RPMRC_OK;
02176
02177
02178 if (fi->fstates == NULL && fc > 0) {
02179 fi->fstates = xmalloc(sizeof(*fi->fstates) * fc);
02180 memset(fi->fstates, RPMFILE_STATE_NORMAL, fc);
02181 }
02182
02183 if (rpmtsFlags(ts) & RPMTRANS_FLAG_JUSTDB) break;
02184 if (fc <= 0) break;
02185
02186
02187
02188
02189
02190
02191 he->tag = RPMTAG_DEFAULTPREFIX;
02192 xx = headerGet(fi->h, he, 0);
02193 fi->striplen = (xx && he->p.str ? strlen(he->p.str) + 1 : 1);
02194 he->p.ptr = _free(he->p.ptr);
02195 fi->mapflags =
02196 IOSM_MAP_PATH | IOSM_MAP_MODE | IOSM_MAP_UID | IOSM_MAP_GID | (fi->mapflags & IOSM_SBIT_CHECK);
02197
02198 if (headerIsEntry(fi->h, RPMTAG_ORIGBASENAMES))
02199 he->tag = RPMTAG_ORIGPATHS;
02200 else
02201 he->tag = RPMTAG_FILEPATHS;
02202 xx = headerGet(fi->h, he, 0);
02203 assert(he->p.argv != NULL);
02204 fi->apath = he->p.argv;
02205
02206 if (fi->fuser == NULL) {
02207 he->tag = RPMTAG_FILEUSERNAME;
02208 xx = headerGet(fi->h, he, 0);
02209 fi->fuser = he->p.argv;
02210 }
02211 if (fi->fgroup == NULL) {
02212 he->tag = RPMTAG_FILEGROUPNAME;
02213 xx = headerGet(fi->h, he, 0);
02214 fi->fgroup = he->p.argv;
02215 }
02216 rc = RPMRC_OK;
02217 }
02218 if (psm->goal == PSM_PKGERASE || psm->goal == PSM_PKGSAVE) {
02219 psm->scriptArg = psm->npkgs_installed - 1;
02220
02221
02222 rc = rpmpsmNext(psm, PSM_RPMDB_LOAD);
02223 #ifdef DYING
02224 if (rc == RPMRC_OK)
02225 if (psm->te)
02226 psm->te->h = headerLink(fi->h);
02227 #else
02228 if (rc == RPMRC_OK && psm->te)
02229 (void) rpmteSetHeader(psm->te, fi->h);
02230 #endif
02231 }
02232 if (psm->goal == PSM_PKGSAVE) {
02233
02234 { char tiddn[32];
02235 const char * bfmt;
02236 const char * pkgdn;
02237 const char * pkgbn;
02238 char * pkgdn_buf;
02239
02240 xx = snprintf(tiddn, sizeof(tiddn), "%d", rpmtsGetTid(ts));
02241 bfmt = rpmGetPath(tiddn, "/", "%{_repackage_name_fmt}", NULL);
02242 pkgbn = headerSprintf(fi->h, bfmt,
02243 NULL, rpmHeaderFormats, NULL);
02244 bfmt = _free(bfmt);
02245 psm->pkgURL = rpmGenPath("%{?_repackage_root}",
02246 "%{?_repackage_dir}",
02247 pkgbn);
02248 pkgbn = _free(pkgbn);
02249 (void) urlPath(psm->pkgURL, &psm->pkgfn);
02250 pkgdn_buf = xstrdup(psm->pkgfn);
02251
02252 pkgdn = dirname(pkgdn_buf);
02253
02254 rc = rpmMkdirPath(pkgdn, "_repackage_dir");
02255 pkgdn_buf = _free(pkgdn_buf);
02256 if (rc == RPMRC_FAIL)
02257 break;
02258 psm->fd = Fopen(psm->pkgfn, "w.fdio");
02259 if (psm->fd == NULL || Ferror(psm->fd)) {
02260 rc = RPMRC_FAIL;
02261 break;
02262 }
02263 }
02264 }
02265 break;
02266 case PSM_PRE:
02267 if (rpmtsFlags(ts) & RPMTRANS_FLAG_TEST) break;
02268
02269
02270 #ifdef NOTYET
02271 { static int oneshot = 0;
02272 dbiIndex dbi;
02273 if (!oneshot) {
02274 dbi = dbiOpen(rpmtsGetRdb(ts), RPMTAG_TRIGGERNAME, 0);
02275 oneshot++;
02276 }
02277 }
02278 #endif
02279
02280
02281 rc = rpmpsmNext(psm, PSM_CHROOT_IN);
02282
02283 if (psm->goal == PSM_PKGINSTALL) {
02284 psm->scriptTag = RPMTAG_PREIN;
02285 psm->progTag = RPMTAG_PREINPROG;
02286 psm->sense = RPMSENSE_TRIGGERPREIN;
02287 psm->countCorrection = 0;
02288
02289 if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOTRIGGERPREIN)) {
02290
02291
02292 rc = rpmpsmNext(psm, PSM_TRIGGERS);
02293 if (rc) break;
02294
02295
02296 rc = rpmpsmNext(psm, PSM_IMMED_TRIGGERS);
02297 if (rc) break;
02298 }
02299
02300 if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOPRE)) {
02301 rc = rpmpsmNext(psm, PSM_SCRIPT);
02302 if (rc != RPMRC_OK) {
02303 rpmlog(RPMLOG_ERR,
02304 _("%s: %s scriptlet failed (%d), skipping %s\n"),
02305 psm->stepName, tag2sln(psm->scriptTag), rc,
02306 rpmteNEVR(psm->te));
02307 break;
02308 }
02309 }
02310 }
02311
02312 if (psm->goal == PSM_PKGERASE) {
02313 psm->scriptTag = RPMTAG_PREUN;
02314 psm->progTag = RPMTAG_PREUNPROG;
02315 psm->sense = RPMSENSE_TRIGGERUN;
02316 psm->countCorrection = -1;
02317
02318 if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOTRIGGERUN)) {
02319
02320 rc = rpmpsmNext(psm, PSM_IMMED_TRIGGERS);
02321 if (rc) break;
02322
02323
02324 rc = rpmpsmNext(psm, PSM_TRIGGERS);
02325 if (rc) break;
02326 }
02327
02328 if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOPREUN))
02329 rc = rpmpsmNext(psm, PSM_SCRIPT);
02330 }
02331 if (psm->goal == PSM_PKGSAVE) {
02332 int noArchiveSize = 0;
02333 const char * origin = NULL;
02334 const char * digest = NULL;
02335 const struct stat * st = NULL;
02336 size_t nstbytes = 0;
02337
02338
02339 { void * uh = NULL;
02340
02341
02342 he->tag = RPMTAG_PACKAGEORIGIN;
02343 xx = headerGet(fi->h, he, 0);
02344 origin = he->p.str;
02345 he->tag = RPMTAG_PACKAGEDIGEST;
02346 xx = headerGet(fi->h, he, 0);
02347 if (xx && he->p.str != NULL)
02348 digest = he->p.str;
02349 he->tag = RPMTAG_PACKAGESTAT;
02350 xx = headerGet(fi->h, he, 0);
02351 if (xx && he->p.ptr != NULL && (size_t)he->c == sizeof(*st)) {
02352 st = he->p.ptr;
02353 nstbytes = he->c;
02354 }
02355
02356
02357 he->tag = RPMTAG_HEADERIMMUTABLE;
02358 xx = headerGet(fi->h, he, 0);
02359 uh = he->p.ptr;
02360 if (xx && uh != NULL) {
02361 psm->oh = headerCopyLoad(uh);
02362 uh = _free(uh);
02363 } else {
02364 he->tag = RPMTAG_HEADERIMAGE;
02365 xx = headerGet(fi->h, he, 0);
02366 uh = he->p.ptr;
02367 if (xx && uh != NULL) {
02368 HeaderIterator hi;
02369 Header oh;
02370
02371
02372 oh = headerCopyLoad(uh);
02373
02374
02375 psm->oh = headerNew();
02376
02377 for (hi = headerInit(oh);
02378 headerNext(hi, he, 0);
02379 he->p.ptr = _free(he->p.ptr))
02380 {
02381 if (he->tag == RPMTAG_ARCHIVESIZE)
02382 noArchiveSize = 1;
02383 xx = headerPut(psm->oh, he, 0);
02384 }
02385 hi = headerFini(hi);
02386
02387 (void)headerFree(oh);
02388 oh = NULL;
02389 uh = _free(uh);
02390 } else
02391 break;
02392 }
02393 }
02394
02395
02396
02397 rc = rpmpsmNext(psm, PSM_RPMIO_FLAGS);
02398
02399
02400
02401 { static const char item[] = "Lead";
02402 const char * NEVR = rpmteNEVR(psm->te);
02403 size_t nb = rpmpkgSizeof(item, NULL);
02404
02405 if (nb == 0)
02406 rc = RPMRC_FAIL;
02407 else {
02408 void * l = alloca(nb);
02409 memset(l, 0, nb);
02410 rc = rpmpkgWrite(item, psm->fd, l, &NEVR);
02411 }
02412 if (rc != RPMRC_OK) {
02413 rpmlog(RPMLOG_ERR, _("Unable to write package: %s\n"),
02414 Fstrerror(psm->fd));
02415 break;
02416 }
02417 }
02418
02419
02420
02421 { static const char item[] = "Signature";
02422 Header sigh = headerRegenSigHeader(fi->h, noArchiveSize);
02423
02424 sigh = headerReload(sigh, RPMTAG_HEADERSIGNATURES);
02425 if (sigh == NULL) {
02426 rpmlog(RPMLOG_ERR, _("Unable to reload signature header\n"));
02427 rc = RPMRC_FAIL;
02428 break;
02429 }
02430 rc = rpmpkgWrite(item, psm->fd, sigh, NULL);
02431 (void)headerFree(sigh);
02432 sigh = NULL;
02433 if (rc != RPMRC_OK) {
02434 break;
02435 }
02436 }
02437
02438
02439 if (psm->oh != NULL)
02440 { rpmuint32_t tid = rpmtsGetTid(ts);
02441
02442 he->tag = RPMTAG_REMOVETID;
02443 he->t = RPM_UINT32_TYPE;
02444 he->p.ui32p = &tid;
02445 he->c = 1;
02446 xx = headerPut(psm->oh, he, 0);
02447
02448
02449 if (origin != NULL) {
02450 he->tag = RPMTAG_PACKAGEORIGIN;
02451 he->t = RPM_STRING_TYPE;
02452 he->p.str = origin;
02453 he->c = 1;
02454 xx = headerPut(psm->oh, he, 0);
02455 origin = _free(origin);
02456 }
02457 if (digest != NULL) {
02458 he->tag = RPMTAG_PACKAGEDIGEST;
02459 he->t = RPM_STRING_TYPE;
02460 he->p.str = digest;
02461 he->c = 1;
02462 xx = headerPut(psm->oh, he, 0);
02463 digest = _free(digest);
02464 }
02465 if (st != NULL) {
02466 he->tag = RPMTAG_PACKAGESTAT;
02467 he->t = RPM_BIN_TYPE;
02468 he->p.ptr = (void *)st;
02469 he->c = (rpmTagCount)nstbytes;
02470 xx = headerPut(psm->oh, he, 0);
02471 st = _free(st);
02472 }
02473
02474
02475 xx = hCopyTag(fi->h, psm->oh, RPMTAG_INSTALLTID);
02476 xx = hCopyTag(fi->h, psm->oh, RPMTAG_BLINKPKGID);
02477 xx = hCopyTag(fi->h, psm->oh, RPMTAG_BLINKHDRID);
02478 xx = hCopyTag(fi->h, psm->oh, RPMTAG_BLINKNEVRA);
02479
02480 assert(psm->te != NULL);
02481 xx = hSaveFlinks(psm->oh, &psm->te->flink);
02482 }
02483
02484
02485 { const char item[] = "Header";
02486 const char * msg = NULL;
02487 rc = rpmpkgWrite(item, psm->fd, psm->oh, &msg);
02488 if (rc != RPMRC_OK) {
02489 rpmlog(RPMLOG_ERR, "%s: %s: %s", psm->pkgfn, item,
02490 (msg && *msg ? msg : "write failed\n"));
02491 msg = _free(msg);
02492 }
02493 }
02494 }
02495 break;
02496 case PSM_PROCESS:
02497 if (rpmtsFlags(ts) & RPMTRANS_FLAG_TEST) break;
02498
02499 if (psm->goal == PSM_PKGINSTALL) {
02500
02501 if (rpmtsFlags(ts) & RPMTRANS_FLAG_JUSTDB) break;
02502
02503
02504 if (rpmfiFC(fi) <= 0) {
02505 void * ptr;
02506 ptr = rpmtsNotify(ts, fi->te, RPMCALLBACK_INST_START, 0, 100);
02507 ptr = rpmtsNotify(ts, fi->te, RPMCALLBACK_INST_PROGRESS, 100, 100);
02508 break;
02509 }
02510
02511
02512 rc = rpmpsmNext(psm, PSM_RPMIO_FLAGS);
02513
02514 if (rpmteFd(fi->te) == NULL) {
02515 rc = RPMRC_FAIL;
02516 break;
02517 }
02518
02519
02520 psm->cfd = Fdopen(fdDup(Fileno(rpmteFd(fi->te))), psm->rpmio_flags);
02521
02522 if (psm->cfd == NULL) {
02523 rc = RPMRC_FAIL;
02524 break;
02525 }
02526
02527 rc = fsmSetup(fi->fsm, IOSM_PKGINSTALL, psm->payload_format, ts, fi,
02528 psm->cfd, NULL, &psm->failedFile);
02529 (void) rpmswAdd(rpmtsOp(ts, RPMTS_OP_UNCOMPRESS),
02530 fdstat_op(psm->cfd, FDSTAT_READ));
02531 (void) rpmswAdd(rpmtsOp(ts, RPMTS_OP_DIGEST),
02532 fdstat_op(psm->cfd, FDSTAT_DIGEST));
02533 xx = fsmTeardown(fi->fsm);
02534
02535 saveerrno = errno;
02536 xx = Fclose(psm->cfd);
02537 psm->cfd = NULL;
02538
02539 errno = saveerrno;
02540
02541
02542 if (!rc)
02543 rc = rpmpsmNext(psm, PSM_COMMIT);
02544
02545
02546 psm->what = RPMCALLBACK_INST_PROGRESS;
02547 psm->amount = (fi->archiveSize ? fi->archiveSize : 100);
02548 psm->total = psm->amount;
02549 xx = rpmpsmNext(psm, PSM_NOTIFY);
02550
02551 if (rc) {
02552 const char * msg = iosmStrerror(rc);
02553 rpmlog(RPMLOG_ERR,
02554 _("unpacking of archive failed%s%s: %s\n"),
02555 (psm->failedFile != NULL ? _(" on file ") : ""),
02556 (psm->failedFile != NULL ? psm->failedFile : ""),
02557 msg);
02558 msg = _free(msg);
02559 rc = RPMRC_FAIL;
02560
02561
02562 psm->what = RPMCALLBACK_UNPACK_ERROR;
02563 psm->amount = 0;
02564 psm->total = 0;
02565 xx = rpmpsmNext(psm, PSM_NOTIFY);
02566
02567 break;
02568 }
02569 }
02570 if (psm->goal == PSM_PKGERASE) {
02571 int fc = rpmfiFC(fi);
02572
02573 if (rpmtsFlags(ts) & RPMTRANS_FLAG_JUSTDB) break;
02574 if (rpmtsFlags(ts) & RPMTRANS_FLAG_APPLYONLY) break;
02575
02576 psm->what = RPMCALLBACK_UNINST_START;
02577 psm->amount = fc;
02578 psm->total = (fc ? fc : 100);
02579 xx = rpmpsmNext(psm, PSM_NOTIFY);
02580
02581 if (fc > 0) {
02582 rc = fsmSetup(fi->fsm, IOSM_PKGERASE, psm->payload_format, ts, fi,
02583 NULL, NULL, &psm->failedFile);
02584 xx = fsmTeardown(fi->fsm);
02585 }
02586
02587 psm->what = RPMCALLBACK_UNINST_STOP;
02588 psm->amount = (fc ? fc : 100);
02589 psm->total = (fc ? fc : 100);
02590 xx = rpmpsmNext(psm, PSM_NOTIFY);
02591
02592 }
02593 if (psm->goal == PSM_PKGSAVE) {
02594 iosmFileAction * actions = (iosmFileAction *) fi->actions;
02595 iosmFileAction action = (iosmFileAction) fi->action;
02596
02597 fi->action = FA_COPYOUT;
02598 fi->actions = NULL;
02599
02600 if (psm->fd == NULL) {
02601 rc = RPMRC_FAIL;
02602 break;
02603 }
02604
02605 xx = Fflush(psm->fd);
02606 psm->cfd = Fdopen(fdDup(Fileno(psm->fd)), psm->rpmio_flags);
02607
02608 if (psm->cfd == NULL) {
02609 rc = RPMRC_FAIL;
02610 break;
02611 }
02612
02613 rc = fsmSetup(fi->fsm, IOSM_PKGBUILD, psm->payload_format, ts, fi,
02614 psm->cfd, NULL, &psm->failedFile);
02615 (void) rpmswAdd(rpmtsOp(ts, RPMTS_OP_COMPRESS),
02616 fdstat_op(psm->cfd, FDSTAT_WRITE));
02617 (void) rpmswAdd(rpmtsOp(ts, RPMTS_OP_DIGEST),
02618 fdstat_op(psm->cfd, FDSTAT_DIGEST));
02619 xx = fsmTeardown(fi->fsm);
02620
02621 saveerrno = errno;
02622 xx = Fclose(psm->cfd);
02623 psm->cfd = NULL;
02624
02625 errno = saveerrno;
02626
02627
02628
02629 psm->what = RPMCALLBACK_INST_PROGRESS;
02630 psm->amount = (fi->archiveSize ? fi->archiveSize : 100);
02631 psm->total = psm->amount;
02632 xx = rpmpsmNext(psm, PSM_NOTIFY);
02633
02634 fi->action = (int) action;
02635 fi->actions = (int *) actions;
02636 }
02637 break;
02638 case PSM_POST:
02639 if (rpmtsFlags(ts) & RPMTRANS_FLAG_TEST) break;
02640
02641 if (psm->goal == PSM_PKGINSTALL) {
02642
02643
02644
02645
02646
02647 if (fi->record && !(rpmtsFlags(ts) & RPMTRANS_FLAG_APPLYONLY)) {
02648 rc = rpmpsmNext(psm, PSM_RPMDB_REMOVE);
02649 if (rc) break;
02650 }
02651
02652
02653 xx = postPopulateInstallHeader(ts, psm->te, fi);
02654
02655 rc = rpmpsmNext(psm, PSM_RPMDB_ADD);
02656 if (rc) break;
02657
02658 psm->scriptTag = RPMTAG_POSTIN;
02659 psm->progTag = RPMTAG_POSTINPROG;
02660 psm->sense = RPMSENSE_TRIGGERIN;
02661 psm->countCorrection = 0;
02662
02663 if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOPOST)) {
02664 rc = rpmpsmNext(psm, PSM_SCRIPT);
02665 if (rc) break;
02666 }
02667 if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOTRIGGERIN)) {
02668
02669 rc = rpmpsmNext(psm, PSM_TRIGGERS);
02670 if (rc) break;
02671
02672
02673 rc = rpmpsmNext(psm, PSM_IMMED_TRIGGERS);
02674 if (rc) break;
02675 }
02676
02677 if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_APPLYONLY))
02678 rc = markReplacedFiles(psm);
02679
02680 }
02681 if (psm->goal == PSM_PKGERASE) {
02682
02683 psm->scriptTag = RPMTAG_POSTUN;
02684 psm->progTag = RPMTAG_POSTUNPROG;
02685 psm->sense = RPMSENSE_TRIGGERPOSTUN;
02686 psm->countCorrection = -1;
02687
02688 if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOPOSTUN)) {
02689 rc = rpmpsmNext(psm, PSM_SCRIPT);
02690 if (rc) break;
02691 }
02692
02693 if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOTRIGGERPOSTUN)) {
02694
02695 rc = rpmpsmNext(psm, PSM_TRIGGERS);
02696 if (rc) break;
02697
02698
02699 rc = rpmpsmNext(psm, PSM_IMMED_TRIGGERS);
02700 if (rc) break;
02701 }
02702
02703 if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_APPLYONLY))
02704 rc = rpmpsmNext(psm, PSM_RPMDB_REMOVE);
02705 }
02706 if (psm->goal == PSM_PKGSAVE) {
02707 }
02708
02709
02710 xx = rpmpsmNext(psm, PSM_CHROOT_OUT);
02711 break;
02712 case PSM_UNDO:
02713 break;
02714 case PSM_FINI:
02715
02716 xx = rpmpsmNext(psm, PSM_CHROOT_OUT);
02717
02718 if (psm->fd != NULL) {
02719 saveerrno = errno;
02720 xx = Fclose(psm->fd);
02721 psm->fd = NULL;
02722
02723 errno = saveerrno;
02724
02725 }
02726
02727 if (psm->goal == PSM_PKGSAVE) {
02728 if (!rc && ts && ts->notify == NULL) {
02729 rpmlog(RPMLOG_INFO, _("Wrote: %s\n"),
02730 (psm->pkgURL ? psm->pkgURL : "???"));
02731 }
02732 }
02733
02734 if (rc) {
02735 const char * msg = iosmStrerror(rc);
02736 if (psm->failedFile)
02737 rpmlog(RPMLOG_ERR,
02738 _("%s failed on file %s: %s\n"),
02739 psm->stepName, psm->failedFile, msg);
02740 else
02741 rpmlog(RPMLOG_ERR, _("%s failed: %s\n"),
02742 psm->stepName, msg);
02743 msg = _free(msg);
02744
02745
02746 psm->what = RPMCALLBACK_CPIO_ERROR;
02747 psm->amount = 0;
02748 psm->total = 0;
02749
02750 xx = rpmpsmNext(psm, PSM_NOTIFY);
02751
02752 }
02753
02754 if (psm->goal == PSM_PKGERASE || psm->goal == PSM_PKGSAVE) {
02755 #ifdef DYING
02756 if (psm->te != NULL)
02757 if (psm->te->h != NULL) {
02758 (void)headerFree(psm->te->h);
02759 psm->te->h = NULL;
02760 }
02761 #else
02762 if (psm->te != NULL)
02763 (void) rpmteSetHeader(psm->te, NULL);
02764 #endif
02765 if (fi->h != NULL) {
02766 (void)headerFree(fi->h);
02767 fi->h = NULL;
02768 }
02769 }
02770 (void)headerFree(psm->oh);
02771 psm->oh = NULL;
02772 psm->pkgURL = _free(psm->pkgURL);
02773 psm->rpmio_flags = _free(psm->rpmio_flags);
02774 psm->payload_format = _free(psm->payload_format);
02775 psm->failedFile = _free(psm->failedFile);
02776
02777 fi->fgroup = _free(fi->fgroup);
02778 fi->fuser = _free(fi->fuser);
02779 fi->apath = _free(fi->apath);
02780 fi->fstates = _free(fi->fstates);
02781 break;
02782
02783 case PSM_PKGINSTALL:
02784 case PSM_PKGERASE:
02785 case PSM_PKGSAVE:
02786 psm->goal = stage;
02787 psm->rc = RPMRC_OK;
02788 psm->stepName = pkgStageString(stage);
02789
02790 rc = rpmpsmNext(psm, PSM_INIT);
02791 if (!rc) rc = rpmpsmNext(psm, PSM_PRE);
02792 if (!rc) rc = rpmpsmNext(psm, PSM_PROCESS);
02793 if (!rc) rc = rpmpsmNext(psm, PSM_POST);
02794 xx = rpmpsmNext(psm, PSM_FINI);
02795 break;
02796 case PSM_PKGCOMMIT:
02797 break;
02798
02799 case PSM_CREATE:
02800 break;
02801 case PSM_NOTIFY:
02802 { void * ptr;
02803
02804 ptr = rpmtsNotify(ts, psm->te, psm->what, psm->amount, psm->total);
02805
02806 } break;
02807 case PSM_DESTROY:
02808 break;
02809 case PSM_COMMIT:
02810 if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_PKGCOMMIT)) break;
02811 if (rpmtsFlags(ts) & RPMTRANS_FLAG_APPLYONLY) break;
02812
02813 rc = fsmSetup(fi->fsm, IOSM_PKGCOMMIT, psm->payload_format, ts, fi,
02814 NULL, NULL, &psm->failedFile);
02815 xx = fsmTeardown(fi->fsm);
02816 break;
02817
02818 case PSM_CHROOT_IN:
02819 { const char * rootDir = rpmtsRootDir(ts);
02820
02821 if (rootDir != NULL && !(rootDir[0] == '/' && rootDir[1] == '\0')
02822 && !rpmtsChrootDone(ts) && !F_ISSET(psm, CHROOTDONE))
02823 {
02824 static int _pw_loaded = 0;
02825 static int _gr_loaded = 0;
02826
02827 if (!_pw_loaded) {
02828 (void)getpwnam("root");
02829 endpwent();
02830 _pw_loaded++;
02831 }
02832 if (!_gr_loaded) {
02833 (void)getgrnam("root");
02834 endgrent();
02835 _gr_loaded++;
02836 }
02837
02838 xx = Chdir("/");
02839
02840 if (rootDir != NULL && strcmp(rootDir, "/") && *rootDir == '/')
02841 rc = Chroot(rootDir);
02842
02843 F_SET(psm, CHROOTDONE);
02844 (void) rpmtsSetChrootDone(ts, 1);
02845 }
02846 } break;
02847 case PSM_CHROOT_OUT:
02848
02849 if (F_ISSET(psm, CHROOTDONE)) {
02850 const char * rootDir = rpmtsRootDir(ts);
02851 const char * currDir = rpmtsCurrDir(ts);
02852
02853 if (rootDir != NULL && strcmp(rootDir, "/") && *rootDir == '/')
02854 rc = Chroot(".");
02855
02856 F_CLR(psm, CHROOTDONE);
02857 (void) rpmtsSetChrootDone(ts, 0);
02858 if (currDir != NULL)
02859 xx = Chdir(currDir);
02860 }
02861 break;
02862 case PSM_SCRIPT:
02863 rc = runInstScript(psm);
02864 break;
02865 case PSM_TRIGGERS:
02866
02867 if (rpmtsFlags(ts) & RPMTRANS_FLAG_TEST) break;
02868 rc = runTriggers(psm);
02869 break;
02870 case PSM_IMMED_TRIGGERS:
02871
02872 if (rpmtsFlags(ts) & RPMTRANS_FLAG_TEST) break;
02873 if (!F_ISSET(psm, GOTTRIGGERS)) {
02874 psm->triggers = rpmdsNew(fi->h, RPMTAG_TRIGGERNAME, 0);
02875 F_SET(psm, GOTTRIGGERS);
02876 }
02877 if (psm->triggers != NULL)
02878 rc = runImmedTriggers(psm);
02879 break;
02880
02881 case PSM_RPMIO_FLAGS:
02882 { const char * payload_compressor = NULL;
02883 const char * payload_format = NULL;
02884 char * t;
02885
02886 he->tag = RPMTAG_PAYLOADCOMPRESSOR;
02887 xx = headerGet(fi->h, he, 0);
02888 payload_compressor = he->p.str;
02889 if (payload_compressor == NULL)
02890 payload_compressor = xstrdup("gzip");
02891
02892 psm->rpmio_flags = t = xmalloc(sizeof("w9.gzdio"));
02893 *t = '\0';
02894 t = stpcpy(t, ((psm->goal == PSM_PKGSAVE) ? "w9" : "r"));
02895 if (!strcmp(payload_compressor, "gzip"))
02896 t = stpcpy(t, ".gzdio");
02897 if (!strcmp(payload_compressor, "bzip2"))
02898 t = stpcpy(t, ".bzdio");
02899 if (!strcmp(payload_compressor, "lzma"))
02900 t = stpcpy(t, ".lzdio");
02901 if (!strcmp(payload_compressor, "xz"))
02902 t = stpcpy(t, ".xzdio");
02903 payload_compressor = _free(payload_compressor);
02904
02905 he->tag = RPMTAG_PAYLOADFORMAT;
02906 xx = headerGet(fi->h, he, 0);
02907 payload_format = he->p.str;
02908 if (!xx || payload_format == NULL || !(
02909 !strcmp(payload_format, "tar") || !strcmp(payload_format, "ustar")
02910 #if defined(SUPPORT_AR_PAYLOADS)
02911 || !strcmp(payload_format, "ar")
02912 #endif
02913 ))
02914 {
02915 payload_format = _free(payload_format);
02916 payload_format = xstrdup("cpio");
02917 }
02918 psm->payload_format = _free(psm->payload_format);
02919 psm->payload_format = payload_format;
02920 rc = RPMRC_OK;
02921 } break;
02922
02923 case PSM_RPMDB_LOAD:
02924 assert(psm->mi == NULL);
02925 psm->mi = rpmtsInitIterator(ts, RPMDBI_PACKAGES,
02926 &fi->record, sizeof(fi->record));
02927 fi->h = rpmmiNext(psm->mi);
02928
02929 if (fi->h != NULL)
02930 fi->h = headerLink(fi->h);
02931
02932 psm->mi = rpmmiFree(psm->mi);
02933
02934 if (fi->h != NULL) {
02935 (void) headerSetInstance(fi->h, fi->record);
02936 rc = RPMRC_OK;
02937 } else
02938 rc = RPMRC_FAIL;
02939 break;
02940 case PSM_RPMDB_ADD:
02941 if (rpmtsFlags(ts) & RPMTRANS_FLAG_TEST) break;
02942 if (rpmtsFlags(ts) & RPMTRANS_FLAG_NORPMDB) break;
02943 if (fi->isSource) break;
02944 if (fi->h == NULL) break;
02945
02946
02947
02948 { rpmuint32_t tid = ((rpmtsType(ts) == RPMTRANS_TYPE_ROLLBACK)
02949 ? hLoadTID(fi->h, RPMTAG_INSTALLTID) : rpmtsGetTid(ts));
02950 (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_DBADD), 0);
02951 if (!(rpmtsVSFlags(ts) & RPMVSF_NOHDRCHK))
02952 rc = rpmdbAdd(rpmtsGetRdb(ts), tid, fi->h, ts);
02953 else
02954 rc = rpmdbAdd(rpmtsGetRdb(ts), tid, fi->h, NULL);
02955 (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_DBADD), 0);
02956 #if defined(HAVE_SYSLOG_H) && defined(RPM_VENDOR_MANDRIVA)
02957 {
02958 char *s;
02959
02960 s = headerSprintf(fi->h, "%{NAME}-%{VERSION}-%{RELEASE}",
02961 rpmTagTable, rpmHeaderFormats, NULL);
02962 syslog(LOG_NOTICE, "[RPM] %s installed\n", s);
02963 s = _free(s);
02964 }
02965 #endif
02966 }
02967
02968 if (rc != RPMRC_OK) break;
02969
02970 assert(psm->te != NULL);
02971
02972 if (rpmtsType(ts) != RPMTRANS_TYPE_ROLLBACK)
02973 psm->te->installed = 1;
02974
02975
02976 rpmteSetDBInstance(psm->te, headerGetInstance(fi->h));
02977
02978 break;
02979 case PSM_RPMDB_REMOVE:
02980 {
02981 if (rpmtsFlags(ts) & RPMTRANS_FLAG_TEST) break;
02982 if (rpmtsFlags(ts) & RPMTRANS_FLAG_NORPMDB) break;
02983
02984 (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_DBREMOVE), 0);
02985 rc = rpmdbRemove(rpmtsGetRdb(ts), rpmtsGetTid(ts), fi->record, NULL);
02986 (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_DBREMOVE), 0);
02987 #if defined(HAVE_SYSLOG_H) && defined(RPM_VENDOR_MANDRIVA)
02988 {
02989 char *s;
02990
02991 s = headerSprintf(fi->h, "%{NAME}-%{VERSION}-%{RELEASE}",
02992 rpmTagTable, rpmHeaderFormats, NULL);
02993 syslog(LOG_NOTICE, "[RPM] %s removed\n", s);
02994 s = _free(s);
02995 }
02996 #endif
02997
02998 if (rc != RPMRC_OK) break;
02999
03000
03001 if (psm->te != NULL)
03002 psm->te->u.removed.dboffset = 0;
03003
03004 } break;
03005
03006 default:
03007 break;
03008 }
03009
03010
03011 return rc;
03012
03013 }
03014