00001
00006 #include "system.h"
00007
00008 #include "psm.h"
00009 #include <rpmmacro.h>
00010 #include <rpmurl.h>
00011
00012 #include "depends.h"
00013
00014 #include "rpmlead.h"
00015 #include "signature.h"
00016 #include "ugid.h"
00017 #include "misc.h"
00018 #include "rpmdb.h"
00019 #include "debug.h"
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #ifdef DYING
00031
00032 extern const char * chroot_prefix;
00033
00034 #endif
00035
00036 int rpmVersionCompare(Header first, Header second)
00037 {
00038 const char * one, * two;
00039 int_32 * epochOne, * epochTwo;
00040 int rc;
00041
00042 if (!headerGetEntry(first, RPMTAG_EPOCH, NULL, (void **) &epochOne, NULL))
00043 epochOne = NULL;
00044 if (!headerGetEntry(second, RPMTAG_EPOCH, NULL, (void **) &epochTwo,
00045 NULL))
00046 epochTwo = NULL;
00047
00048 if (epochOne && !epochTwo)
00049 return 1;
00050 else if (!epochOne && epochTwo)
00051 return -1;
00052 else if (epochOne && epochTwo) {
00053 if (*epochOne < *epochTwo)
00054 return -1;
00055 else if (*epochOne > *epochTwo)
00056 return 1;
00057 }
00058
00059 rc = headerGetEntry(first, RPMTAG_VERSION, NULL, (void **) &one, NULL);
00060 rc = headerGetEntry(second, RPMTAG_VERSION, NULL, (void **) &two, NULL);
00061
00062 rc = rpmvercmp(one, two);
00063 if (rc)
00064 return rc;
00065
00066 (void) headerGetEntry(first, RPMTAG_RELEASE, NULL, (void **) &one, NULL);
00067 (void) headerGetEntry(second, RPMTAG_RELEASE, NULL, (void **) &two, NULL);
00068
00069 return rpmvercmp(one, two);
00070 }
00071
00072 void loadFi(Header h, TFI_t fi)
00073 {
00074 HGE_t hge;
00075 HFD_t hfd;
00076 uint_32 * uip;
00077 int len;
00078 int rc;
00079 int i;
00080
00081 if (fi->fsm == NULL)
00082 fi->fsm = newFSM();
00083
00084
00085 hge = (fi->type == TR_ADDED)
00086 ? (HGE_t) headerGetEntryMinMemory : (HGE_t) headerGetEntry;
00087 fi->hge = hge;
00088 fi->hae = (HAE_t) headerAddEntry;
00089 fi->hme = (HME_t) headerModifyEntry;
00090 fi->hre = (HRE_t) headerRemoveEntry;
00091 fi->hfd = hfd = headerFreeData;
00092
00093 if (h && fi->h == NULL) fi->h = headerLink(h);
00094
00095
00096 rc = hge(fi->h, RPMTAG_NAME, NULL, (void **) &fi->name, NULL);
00097 fi->name = xstrdup(fi->name);
00098 rc = hge(fi->h, RPMTAG_VERSION, NULL, (void **) &fi->version, NULL);
00099 fi->version = xstrdup(fi->version);
00100 rc = hge(fi->h, RPMTAG_RELEASE, NULL, (void **) &fi->release, NULL);
00101 fi->release = xstrdup(fi->release);
00102
00103
00104 rc = hge(fi->h, RPMTAG_EPOCH, NULL, (void **) &uip, NULL);
00105 fi->epoch = (rc ? *uip : -1);
00106
00107 rc = hge(fi->h, RPMTAG_ARCHIVESIZE, NULL, (void **) &uip, NULL);
00108 fi->archiveSize = (rc ? *uip : 0);
00109
00110 if (!hge(fi->h, RPMTAG_BASENAMES, NULL, (void **) &fi->bnl, &fi->fc)) {
00111 fi->dc = 0;
00112 fi->fc = 0;
00113 return;
00114 }
00115
00116 rc = hge(fi->h, RPMTAG_DIRINDEXES, NULL, (void **) &fi->dil, NULL);
00117 rc = hge(fi->h, RPMTAG_DIRNAMES, NULL, (void **) &fi->dnl, &fi->dc);
00118 rc = hge(fi->h, RPMTAG_FILEMODES, NULL, (void **) &fi->fmodes, NULL);
00119 rc = hge(fi->h, RPMTAG_FILEFLAGS, NULL, (void **) &fi->fflags, NULL);
00120 rc = hge(fi->h, RPMTAG_FILESIZES, NULL, (void **) &fi->fsizes, NULL);
00121 rc = hge(fi->h, RPMTAG_FILESTATES, NULL, (void **) &fi->fstates, NULL);
00122
00123 fi->action = FA_UNKNOWN;
00124 fi->flags = 0;
00125
00126
00127 if (fi->actions == NULL)
00128 fi->actions = xcalloc(fi->fc, sizeof(*fi->actions));
00129
00130 switch (fi->type) {
00131 case TR_ADDED:
00132 fi->mapflags =
00133 CPIO_MAP_PATH | CPIO_MAP_MODE | CPIO_MAP_UID | CPIO_MAP_GID;
00134 rc = hge(fi->h, RPMTAG_FILEMD5S, NULL, (void **) &fi->fmd5s, NULL);
00135 rc = hge(fi->h, RPMTAG_FILELINKTOS, NULL, (void **) &fi->flinks, NULL);
00136 rc = hge(fi->h, RPMTAG_FILELANGS, NULL, (void **) &fi->flangs, NULL);
00137 rc = hge(fi->h, RPMTAG_FILEMTIMES, NULL, (void **) &fi->fmtimes, NULL);
00138 rc = hge(fi->h, RPMTAG_FILERDEVS, NULL, (void **) &fi->frdevs, NULL);
00139
00140
00141 fi->replacedSizes = xcalloc(fi->fc, sizeof(*fi->replacedSizes));
00142
00143 break;
00144 case TR_REMOVED:
00145 fi->mapflags =
00146 CPIO_MAP_ABSOLUTE | CPIO_MAP_ADDDOT | CPIO_ALL_HARDLINKS |
00147 CPIO_MAP_PATH | CPIO_MAP_MODE | CPIO_MAP_UID | CPIO_MAP_GID;
00148 rc = hge(fi->h, RPMTAG_FILEMD5S, NULL, (void **) &fi->fmd5s, NULL);
00149 rc = hge(fi->h, RPMTAG_FILELINKTOS, NULL, (void **) &fi->flinks, NULL);
00150 fi->fsizes = memcpy(xmalloc(fi->fc * sizeof(*fi->fsizes)),
00151 fi->fsizes, fi->fc * sizeof(*fi->fsizes));
00152 fi->fflags = memcpy(xmalloc(fi->fc * sizeof(*fi->fflags)),
00153 fi->fflags, fi->fc * sizeof(*fi->fflags));
00154 fi->fmodes = memcpy(xmalloc(fi->fc * sizeof(*fi->fmodes)),
00155 fi->fmodes, fi->fc * sizeof(*fi->fmodes));
00156
00157 if (fi->fstates)
00158 fi->fstates = memcpy(xmalloc(fi->fc * sizeof(*fi->fstates)),
00159 fi->fstates, fi->fc * sizeof(*fi->fstates));
00160 else
00161 fi->fstates = xcalloc(1, fi->fc * sizeof(*fi->fstates));
00162 fi->dil = memcpy(xmalloc(fi->fc * sizeof(*fi->dil)),
00163 fi->dil, fi->fc * sizeof(*fi->dil));
00164 fi->h = headerFree(fi->h);
00165 break;
00166 }
00167
00168 fi->dnlmax = -1;
00169 for (i = 0; i < fi->dc; i++) {
00170 if ((len = strlen(fi->dnl[i])) > fi->dnlmax)
00171 fi->dnlmax = len;
00172 }
00173
00174 fi->bnlmax = -1;
00175 for (i = 0; i < fi->fc; i++) {
00176 if ((len = strlen(fi->bnl[i])) > fi->bnlmax)
00177 fi->bnlmax = len;
00178 }
00179
00180 fi->dperms = 0755;
00181 fi->fperms = 0644;
00182
00183
00184 return;
00185
00186 }
00187
00188 void freeFi(TFI_t fi)
00189 {
00190 HFD_t hfd = (fi->hfd ? fi->hfd : headerFreeData);
00191
00192 fi->name = _free(fi->name);
00193 fi->version = _free(fi->version);
00194 fi->release = _free(fi->release);
00195 fi->actions = _free(fi->actions);
00196 fi->replacedSizes = _free(fi->replacedSizes);
00197 fi->replaced = _free(fi->replaced);
00198
00199 fi->bnl = hfd(fi->bnl, -1);
00200 fi->dnl = hfd(fi->dnl, -1);
00201 fi->obnl = hfd(fi->obnl, -1);
00202 fi->odnl = hfd(fi->odnl, -1);
00203 fi->flinks = hfd(fi->flinks, -1);
00204 fi->fmd5s = hfd(fi->fmd5s, -1);
00205 fi->fuser = hfd(fi->fuser, -1);
00206 fi->fgroup = hfd(fi->fgroup, -1);
00207 fi->flangs = hfd(fi->flangs, -1);
00208
00209 fi->apath = _free(fi->apath);
00210 fi->fuids = _free(fi->fuids);
00211 fi->fgids = _free(fi->fgids);
00212 fi->fmapflags = _free(fi->fmapflags);
00213
00214 fi->fsm = freeFSM(fi->fsm);
00215
00216 switch (fi->type) {
00217 case TR_ADDED:
00218 break;
00219 case TR_REMOVED:
00220 fi->fsizes = hfd(fi->fsizes, -1);
00221 fi->fflags = hfd(fi->fflags, -1);
00222 fi->fmodes = hfd(fi->fmodes, -1);
00223 fi->fstates = hfd(fi->fstates, -1);
00224 fi->dil = hfd(fi->dil, -1);
00225 break;
00226 }
00227
00228 fi->h = headerFree(fi->h);
00229
00230
00231 return;
00232
00233 }
00234
00235 const char *const fiTypeString(TFI_t fi)
00236 {
00237 switch(fi->type) {
00238 case TR_ADDED: return " install";
00239 case TR_REMOVED: return " erase";
00240 default: return "???";
00241 }
00242
00243 }
00244
00249
00250 static struct tagMacro {
00251 const char * macroname;
00252 rpmTag tag;
00253 } tagMacros[] = {
00254 { "name", RPMTAG_NAME },
00255 { "version", RPMTAG_VERSION },
00256 { "release", RPMTAG_RELEASE },
00257 { "epoch", RPMTAG_EPOCH },
00258 { NULL, 0 }
00259 };
00260
00267 static int rpmInstallLoadMacros(TFI_t fi, Header h)
00268
00269
00270 {
00271 HGE_t hge = (HGE_t) fi->hge;
00272 struct tagMacro * tagm;
00273 union {
00274 void * ptr;
00275 const char ** argv;
00276 const char * str;
00277 int_32 * i32p;
00278 } body;
00279 char numbuf[32];
00280 rpmTagType type;
00281
00282 for (tagm = tagMacros; tagm->macroname != NULL; tagm++) {
00283 if (!hge(h, tagm->tag, &type, (void **) &body, NULL))
00284 continue;
00285 switch (type) {
00286 case RPM_INT32_TYPE:
00287 sprintf(numbuf, "%d", *body.i32p);
00288 addMacro(NULL, tagm->macroname, NULL, numbuf, -1);
00289 break;
00290 case RPM_STRING_TYPE:
00291 addMacro(NULL, tagm->macroname, NULL, body.str, -1);
00292 break;
00293 case RPM_NULL_TYPE:
00294 case RPM_CHAR_TYPE:
00295 case RPM_INT8_TYPE:
00296 case RPM_INT16_TYPE:
00297 case RPM_BIN_TYPE:
00298 case RPM_STRING_ARRAY_TYPE:
00299 case RPM_I18NSTRING_TYPE:
00300 default:
00301 break;
00302 }
00303 }
00304 return 0;
00305 }
00306
00314 static int mergeFiles(TFI_t fi, Header h, Header newH)
00315
00316 {
00317 HGE_t hge = (HGE_t)fi->hge;
00318 HME_t hme = (HME_t)fi->hme;
00319 HFD_t hfd = (fi->hfd ? fi->hfd : headerFreeData);
00320 fileAction * actions = fi->actions;
00321 int i, j, k, fc, xx;
00322 rpmTagType type = 0;
00323 int_32 count = 0;
00324 int_32 dirNamesCount, dirCount;
00325 void * data, * newdata;
00326 int_32 * dirIndexes, * newDirIndexes;
00327 uint_32 * fileSizes, fileSize;
00328 const char ** dirNames;
00329 const char ** newDirNames;
00330 static rpmTag mergeTags[] = {
00331 RPMTAG_FILESIZES,
00332 RPMTAG_FILESTATES,
00333 RPMTAG_FILEMODES,
00334 RPMTAG_FILERDEVS,
00335 RPMTAG_FILEMTIMES,
00336 RPMTAG_FILEMD5S,
00337 RPMTAG_FILELINKTOS,
00338 RPMTAG_FILEFLAGS,
00339 RPMTAG_FILEUSERNAME,
00340 RPMTAG_FILEGROUPNAME,
00341 RPMTAG_FILEVERIFYFLAGS,
00342 RPMTAG_FILEDEVICES,
00343 RPMTAG_FILEINODES,
00344 RPMTAG_FILELANGS,
00345 RPMTAG_BASENAMES,
00346 0,
00347 };
00348 static rpmTag requireTags[] = {
00349 RPMTAG_REQUIRENAME, RPMTAG_REQUIREVERSION, RPMTAG_REQUIREFLAGS,
00350 RPMTAG_PROVIDENAME, RPMTAG_PROVIDEVERSION, RPMTAG_PROVIDEFLAGS,
00351 RPMTAG_CONFLICTNAME, RPMTAG_CONFLICTVERSION, RPMTAG_CONFLICTFLAGS
00352 };
00353
00354 xx = hge(h, RPMTAG_SIZE, NULL, (void **) &fileSizes, NULL);
00355 fileSize = *fileSizes;
00356 xx = hge(newH, RPMTAG_FILESIZES, NULL, (void **) &fileSizes, &count);
00357 for (i = 0, fc = 0; i < count; i++)
00358 if (actions[i] != FA_SKIPMULTILIB) {
00359 fc++;
00360 fileSize += fileSizes[i];
00361 }
00362 xx = hme(h, RPMTAG_SIZE, RPM_INT32_TYPE, &fileSize, 1);
00363
00364
00365 for (i = 0; mergeTags[i]; i++) {
00366 if (!hge(newH, mergeTags[i], &type, (void **) &data, &count))
00367 continue;
00368 switch (type) {
00369 case RPM_CHAR_TYPE:
00370 case RPM_INT8_TYPE:
00371 newdata = xcalloc(fc, sizeof(int_8));
00372 for (j = 0, k = 0; j < count; j++)
00373 if (actions[j] != FA_SKIPMULTILIB)
00374 ((int_8 *) newdata)[k++] = ((int_8 *) data)[j];
00375 xx = headerAddOrAppendEntry(h, mergeTags[i], type, newdata, fc);
00376 free (newdata);
00377 break;
00378 case RPM_INT16_TYPE:
00379 newdata = xcalloc(fc, sizeof(int_16));
00380 for (j = 0, k = 0; j < count; j++)
00381 if (actions[j] != FA_SKIPMULTILIB)
00382 ((int_16 *) newdata)[k++] = ((int_16 *) data)[j];
00383 xx = headerAddOrAppendEntry(h, mergeTags[i], type, newdata, fc);
00384 free (newdata);
00385 break;
00386 case RPM_INT32_TYPE:
00387 newdata = xcalloc(fc, sizeof(int_32));
00388 for (j = 0, k = 0; j < count; j++)
00389 if (actions[j] != FA_SKIPMULTILIB)
00390 ((int_32 *) newdata)[k++] = ((int_32 *) data)[j];
00391 xx = headerAddOrAppendEntry(h, mergeTags[i], type, newdata, fc);
00392 free (newdata);
00393 break;
00394 case RPM_STRING_ARRAY_TYPE:
00395 newdata = xcalloc(fc, sizeof(char *));
00396 for (j = 0, k = 0; j < count; j++)
00397 if (actions[j] != FA_SKIPMULTILIB)
00398 ((char **) newdata)[k++] = ((char **) data)[j];
00399 xx = headerAddOrAppendEntry(h, mergeTags[i], type, newdata, fc);
00400 free (newdata);
00401 break;
00402 default:
00403 rpmError(RPMERR_DATATYPE, _("Data type %d not supported\n"),
00404 (int) type);
00405 return 1;
00406 break;
00407 }
00408 data = hfd(data, type);
00409 }
00410
00411 xx = hge(newH, RPMTAG_DIRINDEXES, NULL, (void **) &newDirIndexes, &count);
00412 xx = hge(newH, RPMTAG_DIRNAMES, NULL, (void **) &newDirNames, NULL);
00413 xx = hge(h, RPMTAG_DIRINDEXES, NULL, (void **) &dirIndexes, NULL);
00414 xx = hge(h, RPMTAG_DIRNAMES, NULL, (void **) &data, &dirNamesCount);
00415
00416 dirNames = xcalloc(dirNamesCount + fc, sizeof(*dirNames));
00417 for (i = 0; i < dirNamesCount; i++)
00418 dirNames[i] = ((char **) data)[i];
00419 dirCount = dirNamesCount;
00420 newdata = xcalloc(fc, sizeof(*newDirIndexes));
00421 for (i = 0, k = 0; i < count; i++) {
00422 if (actions[i] == FA_SKIPMULTILIB)
00423 continue;
00424 for (j = 0; j < dirCount; j++)
00425 if (!strcmp(dirNames[j], newDirNames[newDirIndexes[i]]))
00426 break;
00427 if (j == dirCount)
00428 dirNames[dirCount++] = newDirNames[newDirIndexes[i]];
00429 ((int_32 *) newdata)[k++] = j;
00430 }
00431 xx = headerAddOrAppendEntry(h, RPMTAG_DIRINDEXES, RPM_INT32_TYPE, newdata, fc);
00432 if (dirCount > dirNamesCount)
00433 xx = headerAddOrAppendEntry(h, RPMTAG_DIRNAMES, RPM_STRING_ARRAY_TYPE,
00434 dirNames + dirNamesCount,
00435 dirCount - dirNamesCount);
00436 data = hfd(data, -1);
00437 newDirNames = hfd(newDirNames, -1);
00438 free (newdata);
00439 free (dirNames);
00440
00441 for (i = 0; i < 9; i += 3) {
00442 const char **Names, **EVR, **newNames, **newEVR;
00443 rpmTagType nnt, nvt, rnt;
00444 uint_32 *Flags, *newFlags;
00445 int Count = 0, newCount = 0;
00446
00447 if (!hge(newH, requireTags[i], &nnt, (void **) &newNames, &newCount))
00448 continue;
00449
00450 xx = hge(newH, requireTags[i+1], &nvt, (void **) &newEVR, NULL);
00451 xx = hge(newH, requireTags[i+2], NULL, (void **) &newFlags, NULL);
00452 if (hge(h, requireTags[i], &rnt, (void **) &Names, &Count))
00453 {
00454 (void) hge(h, requireTags[i+1], NULL, (void **) &EVR, NULL);
00455 (void) hge(h, requireTags[i+2], NULL, (void **) &Flags, NULL);
00456 for (j = 0; j < newCount; j++)
00457 for (k = 0; k < Count; k++)
00458 if (!strcmp (newNames[j], Names[k])
00459 && !strcmp (newEVR[j], EVR[k])
00460 && (newFlags[j] & RPMSENSE_SENSEMASK) ==
00461 (Flags[k] & RPMSENSE_SENSEMASK))
00462 {
00463 newNames[j] = NULL;
00464 break;
00465 }
00466 }
00467 for (j = 0, k = 0; j < newCount; j++) {
00468 if (!newNames[j] || !isDependsMULTILIB(newFlags[j]))
00469 continue;
00470 if (j != k) {
00471 newNames[k] = newNames[j];
00472 newEVR[k] = newEVR[j];
00473 newFlags[k] = newFlags[j];
00474 }
00475 k++;
00476 }
00477 if (k) {
00478 xx = headerAddOrAppendEntry(h, requireTags[i],
00479 RPM_STRING_ARRAY_TYPE, newNames, k);
00480 xx = headerAddOrAppendEntry(h, requireTags[i+1],
00481 RPM_STRING_ARRAY_TYPE, newEVR, k);
00482 xx = headerAddOrAppendEntry(h, requireTags[i+2], RPM_INT32_TYPE,
00483 newFlags, k);
00484 }
00485 newNames = hfd(newNames, nnt);
00486 newEVR = hfd(newEVR, nvt);
00487 Names = hfd(Names, rnt);
00488 }
00489 return 0;
00490 }
00491
00497 static int markReplacedFiles(PSM_t psm)
00498
00499
00500 {
00501 const rpmTransactionSet ts = psm->ts;
00502 TFI_t fi = psm->fi;
00503 HGE_t hge = (HGE_t)fi->hge;
00504 const struct sharedFileInfo * replaced = fi->replaced;
00505 const struct sharedFileInfo * sfi;
00506 rpmdbMatchIterator mi;
00507 Header h;
00508 unsigned int * offsets;
00509 unsigned int prev;
00510 int num, xx;
00511
00512 if (!(fi->fc > 0 && fi->replaced))
00513 return 0;
00514
00515 num = prev = 0;
00516 for (sfi = replaced; sfi->otherPkg; sfi++) {
00517 if (prev && prev == sfi->otherPkg)
00518 continue;
00519 prev = sfi->otherPkg;
00520 num++;
00521 }
00522 if (num == 0)
00523 return 0;
00524
00525 offsets = alloca(num * sizeof(*offsets));
00526 num = prev = 0;
00527 for (sfi = replaced; sfi->otherPkg; sfi++) {
00528 if (prev && prev == sfi->otherPkg)
00529 continue;
00530 prev = sfi->otherPkg;
00531 offsets[num++] = sfi->otherPkg;
00532 }
00533
00534 mi = rpmdbInitIterator(ts->rpmdb, RPMDBI_PACKAGES, NULL, 0);
00535 xx = rpmdbAppendIterator(mi, offsets, num);
00536 xx = rpmdbSetIteratorRewrite(mi, 1);
00537
00538 sfi = replaced;
00539 while ((h = rpmdbNextIterator(mi)) != NULL) {
00540 char * secStates;
00541 int modified;
00542 int count;
00543
00544 modified = 0;
00545
00546 if (!hge(h, RPMTAG_FILESTATES, NULL, (void **)&secStates, &count))
00547 continue;
00548
00549 prev = rpmdbGetIteratorOffset(mi);
00550 num = 0;
00551 while (sfi->otherPkg && sfi->otherPkg == prev) {
00552 assert(sfi->otherFileNum < count);
00553 if (secStates[sfi->otherFileNum] != RPMFILE_STATE_REPLACED) {
00554 secStates[sfi->otherFileNum] = RPMFILE_STATE_REPLACED;
00555 if (modified == 0) {
00556
00557 modified = 1;
00558 xx = rpmdbSetIteratorModified(mi, modified);
00559 }
00560 num++;
00561 }
00562 sfi++;
00563 }
00564 }
00565 mi = rpmdbFreeIterator(mi);
00566
00567 return 0;
00568 }
00569
00577 static rpmRC chkdir (const char * dpath, const char * dname)
00578
00579
00580 {
00581 struct stat st;
00582 int rc;
00583
00584 if ((rc = Stat(dpath, &st)) < 0) {
00585 int ut = urlPath(dpath, NULL);
00586 switch (ut) {
00587 case URL_IS_PATH:
00588 case URL_IS_UNKNOWN:
00589 if (errno != ENOENT)
00590 break;
00591
00592 case URL_IS_FTP:
00593 case URL_IS_HTTP:
00594 rc = Mkdir(dpath, 0755);
00595 break;
00596 case URL_IS_DASH:
00597 break;
00598 }
00599 if (rc < 0) {
00600 rpmError(RPMERR_CREATE, _("cannot create %%%s %s\n"),
00601 dname, dpath);
00602 return RPMRC_FAIL;
00603 }
00604 }
00605 if ((rc = Access(dpath, W_OK))) {
00606 rpmError(RPMERR_CREATE, _("cannot write to %%%s %s\n"), dname, dpath);
00607 return RPMRC_FAIL;
00608 }
00609 return RPMRC_OK;
00610 }
00611
00612 rpmRC rpmInstallSourcePackage(const char * rootDir, FD_t fd,
00613 const char ** specFilePtr,
00614 rpmCallbackFunction notify, rpmCallbackData notifyData,
00615 char ** cookie)
00616 {
00617 rpmdb rpmdb = NULL;
00618 rpmTransactionSet ts = rpmtransCreateSet(rpmdb, rootDir);
00619 TFI_t fi = xcalloc(sizeof(*fi), 1);
00620 const char * _sourcedir = NULL;
00621 const char * _specdir = NULL;
00622 const char * specFile = NULL;
00623 HGE_t hge;
00624 HFD_t hfd;
00625 Header h = NULL;
00626 struct psm_s psmbuf;
00627 PSM_t psm = &psmbuf;
00628 int isSource;
00629 rpmRC rc;
00630 int i;
00631
00632 ts->notify = notify;
00633
00634 ts->notifyData = notifyData;
00635
00636
00637
00638 rc = rpmReadPackageHeader(fd, &h, &isSource, NULL, NULL);
00639
00640 if (rc)
00641 goto exit;
00642
00643 if (!isSource) {
00644 rpmError(RPMERR_NOTSRPM, _("source package expected, binary found\n"));
00645 rc = RPMRC_FAIL;
00646 goto exit;
00647 }
00648
00649 (void) rpmtransAddPackage(ts, h, fd, NULL, 0, NULL);
00650 if (ts->addedPackages.list == NULL) {
00651 rc = RPMRC_FAIL;
00652 goto exit;
00653 }
00654
00655 fi->type = TR_ADDED;
00656 fi->ap = ts->addedPackages.list;
00657 loadFi(h, fi);
00658 hge = fi->hge;
00659 hfd = (fi->hfd ? fi->hfd : headerFreeData);
00660 h = headerFree(h);
00661
00662 (void) rpmInstallLoadMacros(fi, fi->h);
00663
00664 memset(psm, 0, sizeof(*psm));
00665 psm->ts = ts;
00666 psm->fi = fi;
00667
00668 if (cookie) {
00669 *cookie = NULL;
00670 if (hge(fi->h, RPMTAG_COOKIE, NULL, (void **) cookie, NULL))
00671 *cookie = xstrdup(*cookie);
00672 }
00673
00674
00675 fi->fmd5s = hfd(fi->fmd5s, -1);
00676
00677
00678 fi->fmapflags = _free(fi->fmapflags);
00679 fi->mapflags = CPIO_MAP_PATH | CPIO_MAP_MODE | CPIO_MAP_UID | CPIO_MAP_GID;
00680
00681 fi->uid = getuid();
00682 fi->gid = getgid();
00683 fi->astriplen = 0;
00684 fi->striplen = 0;
00685
00686 fi->fuids = xcalloc(sizeof(*fi->fuids), fi->fc);
00687 fi->fgids = xcalloc(sizeof(*fi->fgids), fi->fc);
00688 for (i = 0; i < fi->fc; i++) {
00689 fi->fuids[i] = fi->uid;
00690 fi->fgids[i] = fi->gid;
00691 }
00692
00693 for (i = 0; i < fi->fc; i++)
00694 fi->actions[i] = FA_CREATE;
00695
00696 rpmBuildFileList(fi->h, &fi->apath, NULL);
00697
00698 i = fi->fc;
00699 if (headerIsEntry(fi->h, RPMTAG_COOKIE))
00700 for (i = 0; i < fi->fc; i++)
00701 if (fi->fflags[i] & RPMFILE_SPECFILE) break;
00702
00703 if (i == fi->fc) {
00704
00705 for (i = 0; i < fi->fc; i++) {
00706 const char * t = fi->apath[i];
00707 t += strlen(fi->apath[i]) - 5;
00708 if (!strcmp(t, ".spec")) break;
00709 }
00710 }
00711
00712 _sourcedir = rpmGenPath(ts->rootDir, "%{_sourcedir}", "");
00713 rc = chkdir(_sourcedir, "sourcedir");
00714 if (rc) {
00715 rc = RPMRC_FAIL;
00716 goto exit;
00717 }
00718
00719 _specdir = rpmGenPath(ts->rootDir, "%{_specdir}", "");
00720 rc = chkdir(_specdir, "specdir");
00721 if (rc) {
00722 rc = RPMRC_FAIL;
00723 goto exit;
00724 }
00725
00726
00727 if (i < fi->fc) {
00728 int speclen = strlen(_specdir) + 2;
00729 int sourcelen = strlen(_sourcedir) + 2;
00730 char * t;
00731
00732 fi->dnl = hfd(fi->dnl, -1);
00733
00734 fi->dc = 2;
00735 fi->dnl = xmalloc(fi->dc * sizeof(*fi->dnl) + fi->fc * sizeof(*fi->dil) +
00736 speclen + sourcelen);
00737 fi->dil = (int *)(fi->dnl + fi->dc);
00738 memset(fi->dil, 0, fi->fc * sizeof(*fi->dil));
00739 fi->dil[i] = 1;
00740
00741 fi->dnl[0] = t = (char *)(fi->dil + fi->fc);
00742 fi->dnl[1] = t = stpcpy( stpcpy(t, _sourcedir), "/") + 1;
00743
00744 (void) stpcpy( stpcpy(t, _specdir), "/");
00745
00746 t = xmalloc(speclen + strlen(fi->bnl[i]) + 1);
00747 (void) stpcpy( stpcpy( stpcpy(t, _specdir), "/"), fi->bnl[i]);
00748 specFile = t;
00749 } else {
00750 rpmError(RPMERR_NOSPEC, _("source package contains no .spec file\n"));
00751 rc = RPMRC_FAIL;
00752 goto exit;
00753 }
00754
00755 psm->goal = PSM_PKGINSTALL;
00756
00757
00758 rc = psmStage(psm, PSM_PROCESS);
00759
00760 (void) psmStage(psm, PSM_FINI);
00761
00762
00763 if (rc) rc = RPMRC_FAIL;
00764
00765 exit:
00766 if (specFilePtr && specFile && rc == RPMRC_OK)
00767 *specFilePtr = specFile;
00768 else
00769 specFile = _free(specFile);
00770
00771 _specdir = _free(_specdir);
00772 _sourcedir = _free(_sourcedir);
00773
00774 if (h) h = headerFree(h);
00775
00776 if (fi) {
00777 freeFi(fi);
00778 fi = _free(fi);
00779 }
00780 ts = rpmtransFree(ts);
00781
00782 return rc;
00783 }
00784
00785
00786 static char * SCRIPT_PATH =
00787 "PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/X11R6/bin";
00788
00794 static const char * const tag2sln(int tag)
00795
00796 {
00797 switch (tag) {
00798 case RPMTAG_PREIN: return "%pre";
00799 case RPMTAG_POSTIN: return "%post";
00800 case RPMTAG_PREUN: return "%preun";
00801 case RPMTAG_POSTUN: return "%postun";
00802 case RPMTAG_VERIFYSCRIPT: return "%verify";
00803 }
00804 return "%unknownscript";
00805 }
00806
00825 static int runScript(PSM_t psm, Header h,
00826 const char * sln,
00827 int progArgc, const char ** progArgv,
00828 const char * script, int arg1, int arg2)
00829
00830
00831
00832 {
00833 const rpmTransactionSet ts = psm->ts;
00834 TFI_t fi = psm->fi;
00835 HGE_t hge = fi->hge;
00836 HFD_t hfd = (fi->hfd ? fi->hfd : headerFreeData);
00837 const char ** argv = NULL;
00838 int argc = 0;
00839 const char ** prefixes = NULL;
00840 int numPrefixes;
00841 rpmTagType ipt;
00842 const char * oldPrefix;
00843 int maxPrefixLength;
00844 int len;
00845 char * prefixBuf = NULL;
00846 pid_t child;
00847 int status = 0;
00848 const char * fn = NULL;
00849 int i, xx;
00850 int freePrefixes = 0;
00851 FD_t out;
00852 rpmRC rc = RPMRC_OK;
00853 const char *n, *v, *r;
00854
00855 if (!progArgv && !script)
00856 return 0;
00857
00858 if (!progArgv) {
00859 argv = alloca(5 * sizeof(*argv));
00860 argv[0] = "/bin/sh";
00861 argc = 1;
00862 } else {
00863 argv = alloca((progArgc + 4) * sizeof(*argv));
00864 memcpy(argv, progArgv, progArgc * sizeof(*argv));
00865 argc = progArgc;
00866 }
00867
00868 xx = headerNVR(h, &n, &v, &r);
00869 if (hge(h, RPMTAG_INSTPREFIXES, &ipt, (void **) &prefixes, &numPrefixes)) {
00870 freePrefixes = 1;
00871 } else if (hge(h, RPMTAG_INSTALLPREFIX, NULL, (void **) &oldPrefix, NULL)) {
00872 prefixes = &oldPrefix;
00873 numPrefixes = 1;
00874 } else {
00875 numPrefixes = 0;
00876 }
00877
00878 maxPrefixLength = 0;
00879 for (i = 0; i < numPrefixes; i++) {
00880 len = strlen(prefixes[i]);
00881 if (len > maxPrefixLength) maxPrefixLength = len;
00882 }
00883 prefixBuf = alloca(maxPrefixLength + 50);
00884
00885 if (script) {
00886 FD_t fd;
00887
00888 if (makeTempFile((!ts->chrootDone ? ts->rootDir : "/"), &fn, &fd)) {
00889 if (freePrefixes) free(prefixes);
00890 return 1;
00891 }
00892
00893
00894 if (rpmIsDebug() &&
00895 (!strcmp(argv[0], "/bin/sh") || !strcmp(argv[0], "/bin/bash")))
00896 xx = Fwrite("set -x\n", sizeof(char), 7, fd);
00897
00898 xx = Fwrite(script, sizeof(script[0]), strlen(script), fd);
00899 xx = Fclose(fd);
00900
00901 { const char * sn = fn;
00902 if (!ts->chrootDone &&
00903 !(ts->rootDir[0] == '/' && ts->rootDir[1] == '\0'))
00904 {
00905 sn += strlen(ts->rootDir)-1;
00906 }
00907 argv[argc++] = sn;
00908 }
00909
00910 if (arg1 >= 0) {
00911 char *av = alloca(20);
00912 sprintf(av, "%d", arg1);
00913 argv[argc++] = av;
00914 }
00915 if (arg2 >= 0) {
00916 char *av = alloca(20);
00917 sprintf(av, "%d", arg2);
00918 argv[argc++] = av;
00919 }
00920 }
00921
00922 argv[argc] = NULL;
00923
00924 if (ts->scriptFd != NULL) {
00925 if (rpmIsVerbose()) {
00926 out = fdDup(Fileno(ts->scriptFd));
00927 } else {
00928 out = Fopen("/dev/null", "w.fdio");
00929 if (Ferror(out)) {
00930 out = fdDup(Fileno(ts->scriptFd));
00931 }
00932 }
00933 } else {
00934 out = fdDup(STDOUT_FILENO);
00935 #ifdef DYING
00936 out = fdLink(out, "runScript persist");
00937 #endif
00938 }
00939 if (out == NULL) return 1;
00940
00941
00942 if (!(child = fork())) {
00943 const char * rootDir;
00944 int pipes[2];
00945
00946 pipes[0] = pipes[1] = 0;
00947
00948 xx = pipe(pipes);
00949 xx = close(pipes[1]);
00950 xx = dup2(pipes[0], STDIN_FILENO);
00951 xx = close(pipes[0]);
00952
00953 if (ts->scriptFd != NULL) {
00954 if (Fileno(ts->scriptFd) != STDERR_FILENO)
00955 xx = dup2(Fileno(ts->scriptFd), STDERR_FILENO);
00956 if (Fileno(out) != STDOUT_FILENO)
00957 xx = dup2(Fileno(out), STDOUT_FILENO);
00958
00959 if (Fileno(out) > STDERR_FILENO && Fileno(out) != Fileno(ts->scriptFd)) {
00960 xx = Fclose (out);
00961 }
00962 if (Fileno(ts->scriptFd) > STDERR_FILENO) {
00963 xx = Fclose (ts->scriptFd);
00964 }
00965 }
00966
00967 { const char *ipath = rpmExpand("PATH=%{_install_script_path}", NULL);
00968 const char *path = SCRIPT_PATH;
00969
00970 if (ipath && ipath[5] != '%')
00971 path = ipath;
00972 xx = doputenv(path);
00973
00974 ipath = _free(ipath);
00975
00976 }
00977
00978 for (i = 0; i < numPrefixes; i++) {
00979 sprintf(prefixBuf, "RPM_INSTALL_PREFIX%d=%s", i, prefixes[i]);
00980 xx = doputenv(prefixBuf);
00981
00982
00983 if (i == 0) {
00984 sprintf(prefixBuf, "RPM_INSTALL_PREFIX=%s", prefixes[i]);
00985 xx = doputenv(prefixBuf);
00986 }
00987 }
00988
00989 if ((rootDir = ts->rootDir) != NULL)
00990 switch(urlIsURL(rootDir)) {
00991 case URL_IS_PATH:
00992 rootDir += sizeof("file://") - 1;
00993 rootDir = strchr(rootDir, '/');
00994
00995 case URL_IS_UNKNOWN:
00996 if (!ts->chrootDone && !(rootDir[0] == '/' && rootDir[1] == '\0')) {
00997
00998 xx = chroot(rootDir);
00999
01000 }
01001 xx = chdir("/");
01002 xx = execv(argv[0], (char *const *)argv);
01003 break;
01004 default:
01005 break;
01006 }
01007
01008 _exit(-1);
01009
01010 }
01011
01012
01013 if (waitpid(child, &status, 0) < 0) {
01014 rpmError(RPMERR_SCRIPT,
01015 _("execution of %s scriptlet from %s-%s-%s failed, waitpid returned %s\n"),
01016 sln, n, v, r, strerror (errno));
01017
01018 rc = RPMRC_OK;
01019 } else {
01020 if (!WIFEXITED(status) || WEXITSTATUS(status)) {
01021 rpmError(RPMERR_SCRIPT,
01022 _("execution of %s scriptlet from %s-%s-%s failed, exit status %d\n"),
01023 sln, n, v, r, WEXITSTATUS(status));
01024 rc = RPMRC_FAIL;
01025 }
01026 }
01027
01028 if (freePrefixes) prefixes = hfd(prefixes, ipt);
01029
01030 xx = Fclose(out);
01031
01032 if (script) {
01033 if (!rpmIsDebug())
01034 xx = unlink(fn);
01035 fn = _free(fn);
01036 }
01037
01038 return rc;
01039 }
01040
01046 static rpmRC runInstScript(PSM_t psm)
01047
01048
01049
01050
01051 {
01052 TFI_t fi = psm->fi;
01053 HGE_t hge = fi->hge;
01054 HFD_t hfd = (fi->hfd ? fi->hfd : headerFreeData);
01055 void ** programArgv;
01056 int programArgc;
01057 const char ** argv;
01058 rpmTagType ptt, stt;
01059 const char * script;
01060 rpmRC rc = RPMRC_OK;
01061 int xx;
01062
01063
01064
01065
01066
01067 xx = hge(fi->h, psm->progTag, &ptt, (void **) &programArgv, &programArgc);
01068 xx = hge(fi->h, psm->scriptTag, &stt, (void **) &script, NULL);
01069
01070 if (programArgv && ptt == RPM_STRING_TYPE) {
01071 argv = alloca(sizeof(char *));
01072 *argv = (const char *) programArgv;
01073 } else {
01074 argv = (const char **) programArgv;
01075 }
01076
01077 rc = runScript(psm, fi->h, tag2sln(psm->scriptTag), programArgc, argv,
01078 script, psm->scriptArg, -1);
01079
01080 programArgv = hfd(programArgv, ptt);
01081 script = hfd(script, stt);
01082 return rc;
01083 }
01084
01093 static int handleOneTrigger(PSM_t psm, Header sourceH, Header triggeredH,
01094 int arg2, unsigned char * triggersAlreadyRun)
01095
01096
01097
01098
01099 {
01100 const rpmTransactionSet ts = psm->ts;
01101 TFI_t fi = psm->fi;
01102 HGE_t hge = fi->hge;
01103 HFD_t hfd = (fi->hfd ? fi->hfd : headerFreeData);
01104 const char ** triggerNames;
01105 const char ** triggerEVR;
01106 const char ** triggerScripts;
01107 const char ** triggerProgs;
01108 int_32 * triggerFlags;
01109 int_32 * triggerIndices;
01110 rpmTagType tnt, tvt, tft;
01111 const char * triggerPackageName;
01112 const char * sourceName;
01113 int numTriggers;
01114 rpmRC rc = RPMRC_OK;
01115 int i;
01116 int skip;
01117 int xx;
01118
01119 if (!( hge(triggeredH, RPMTAG_TRIGGERNAME, &tnt,
01120 (void **) &triggerNames, &numTriggers) &&
01121 hge(triggeredH, RPMTAG_TRIGGERFLAGS, &tft,
01122 (void **) &triggerFlags, NULL) &&
01123 hge(triggeredH, RPMTAG_TRIGGERVERSION, &tvt,
01124 (void **) &triggerEVR, NULL))
01125 )
01126 return 0;
01127
01128 xx = headerNVR(sourceH, &sourceName, NULL, NULL);
01129
01130 for (i = 0; i < numTriggers; i++) {
01131 rpmTagType tit, tst, tpt;
01132
01133 if (!(triggerFlags[i] & psm->sense)) continue;
01134 if (strcmp(triggerNames[i], sourceName)) continue;
01135
01136
01137
01138
01139
01140
01141
01142 skip = strlen(triggerNames[i]);
01143 if (!strncmp(triggerEVR[i], triggerNames[i], skip) &&
01144 (triggerEVR[i][skip] == '-'))
01145 skip++;
01146 else
01147 skip = 0;
01148
01149 if (!headerMatchesDepFlags(sourceH, triggerNames[i],
01150 triggerEVR[i] + skip, triggerFlags[i]))
01151 continue;
01152
01153 if (!( hge(triggeredH, RPMTAG_TRIGGERINDEX, &tit,
01154 (void **) &triggerIndices, NULL) &&
01155 hge(triggeredH, RPMTAG_TRIGGERSCRIPTS, &tst,
01156 (void **) &triggerScripts, NULL) &&
01157 hge(triggeredH, RPMTAG_TRIGGERSCRIPTPROG, &tpt,
01158 (void **) &triggerProgs, NULL))
01159 )
01160 continue;
01161
01162 xx = headerNVR(triggeredH, &triggerPackageName, NULL, NULL);
01163
01164 { int arg1;
01165 int index;
01166
01167 arg1 = rpmdbCountPackages(ts->rpmdb, triggerPackageName);
01168 if (arg1 < 0) {
01169
01170 rc = RPMRC_FAIL;
01171 } else {
01172 arg1 += psm->countCorrection;
01173 index = triggerIndices[i];
01174 if (triggersAlreadyRun == NULL ||
01175 triggersAlreadyRun[index] == 0)
01176 {
01177 rc = runScript(psm, triggeredH, "%trigger", 1,
01178 triggerProgs + index, triggerScripts[index],
01179 arg1, arg2);
01180 if (triggersAlreadyRun != NULL)
01181 triggersAlreadyRun[index] = 1;
01182 }
01183 }
01184 }
01185
01186 triggerIndices = hfd(triggerIndices, tit);
01187 triggerScripts = hfd(triggerScripts, tst);
01188 triggerProgs = hfd(triggerProgs, tpt);
01189
01190
01191
01192
01193
01194 break;
01195 }
01196
01197 triggerNames = hfd(triggerNames, tnt);
01198 triggerFlags = hfd(triggerFlags, tft);
01199 triggerEVR = hfd(triggerEVR, tvt);
01200
01201 return rc;
01202 }
01203
01209 static int runTriggers(PSM_t psm)
01210
01211
01212
01213
01214 {
01215 const rpmTransactionSet ts = psm->ts;
01216 TFI_t fi = psm->fi;
01217 int numPackage;
01218 rpmRC rc = RPMRC_OK;
01219
01220 numPackage = rpmdbCountPackages(ts->rpmdb, fi->name) + psm->countCorrection;
01221 if (numPackage < 0)
01222 return 1;
01223
01224 { Header triggeredH;
01225 rpmdbMatchIterator mi;
01226 int countCorrection = psm->countCorrection;
01227
01228 psm->countCorrection = 0;
01229 mi = rpmdbInitIterator(ts->rpmdb, RPMTAG_TRIGGERNAME, fi->name, 0);
01230 while((triggeredH = rpmdbNextIterator(mi)) != NULL) {
01231 rc |= handleOneTrigger(psm, fi->h, triggeredH, numPackage, NULL);
01232 }
01233
01234 mi = rpmdbFreeIterator(mi);
01235 psm->countCorrection = countCorrection;
01236 }
01237
01238 return rc;
01239 }
01240
01246 static int runImmedTriggers(PSM_t psm)
01247
01248
01249
01250
01251 {
01252 const rpmTransactionSet ts = psm->ts;
01253 TFI_t fi = psm->fi;
01254 HGE_t hge = fi->hge;
01255 HFD_t hfd = (fi->hfd ? fi->hfd : headerFreeData);
01256 const char ** triggerNames;
01257 int numTriggers;
01258 int_32 * triggerIndices;
01259 rpmTagType tnt, tit;
01260 int numTriggerIndices;
01261 unsigned char * triggersRun;
01262 rpmRC rc = RPMRC_OK;
01263
01264 if (!( hge(fi->h, RPMTAG_TRIGGERNAME, &tnt,
01265 (void **) &triggerNames, &numTriggers) &&
01266 hge(fi->h, RPMTAG_TRIGGERINDEX, &tit,
01267 (void **) &triggerIndices, &numTriggerIndices))
01268 )
01269 return 0;
01270
01271 triggersRun = alloca(sizeof(*triggersRun) * numTriggerIndices);
01272 memset(triggersRun, 0, sizeof(*triggersRun) * numTriggerIndices);
01273
01274 { Header sourceH = NULL;
01275 int i;
01276
01277 for (i = 0; i < numTriggers; i++) {
01278 rpmdbMatchIterator mi;
01279
01280 if (triggersRun[triggerIndices[i]] != 0) continue;
01281
01282 mi = rpmdbInitIterator(ts->rpmdb, RPMTAG_NAME, triggerNames[i], 0);
01283
01284 while((sourceH = rpmdbNextIterator(mi)) != NULL) {
01285 rc |= handleOneTrigger(psm, sourceH, fi->h,
01286 rpmdbGetIteratorCount(mi),
01287 triggersRun);
01288 }
01289
01290 mi = rpmdbFreeIterator(mi);
01291 }
01292 }
01293 triggerIndices = hfd(triggerIndices, tit);
01294 triggerNames = hfd(triggerNames, tnt);
01295 return rc;
01296 }
01297
01298 static const char *const pkgStageString(pkgStage a)
01299
01300 {
01301 switch(a) {
01302 case PSM_UNKNOWN: return "unknown";
01303
01304 case PSM_PKGINSTALL: return " install";
01305 case PSM_PKGERASE: return " erase";
01306 case PSM_PKGCOMMIT: return " commit";
01307 case PSM_PKGSAVE: return "repackage";
01308
01309 case PSM_INIT: return "init";
01310 case PSM_PRE: return "pre";
01311 case PSM_PROCESS: return "process";
01312 case PSM_POST: return "post";
01313 case PSM_UNDO: return "undo";
01314 case PSM_FINI: return "fini";
01315
01316 case PSM_CREATE: return "create";
01317 case PSM_NOTIFY: return "notify";
01318 case PSM_DESTROY: return "destroy";
01319 case PSM_COMMIT: return "commit";
01320
01321 case PSM_CHROOT_IN: return "chrootin";
01322 case PSM_CHROOT_OUT: return "chrootout";
01323 case PSM_SCRIPT: return "script";
01324 case PSM_TRIGGERS: return "triggers";
01325 case PSM_IMMED_TRIGGERS: return "immedtriggers";
01326
01327 case PSM_RPMIO_FLAGS: return "rpmioflags";
01328
01329 case PSM_RPMDB_LOAD: return "rpmdbload";
01330 case PSM_RPMDB_ADD: return "rpmdbadd";
01331 case PSM_RPMDB_REMOVE: return "rpmdbremove";
01332
01333 default: return "???";
01334 }
01335
01336 }
01337
01342 int psmStage(PSM_t psm, pkgStage stage)
01343 {
01344 const rpmTransactionSet ts = psm->ts;
01345 TFI_t fi = psm->fi;
01346 HGE_t hge = fi->hge;
01347 HME_t hme = fi->hme;
01348 HFD_t hfd = (fi->hfd ? fi->hfd : headerFreeData);
01349 rpmRC rc = psm->rc;
01350 int saveerrno;
01351 int xx;
01352
01353
01354 switch (stage) {
01355 case PSM_UNKNOWN:
01356 break;
01357 case PSM_INIT:
01358 rpmMessage(RPMMESS_DEBUG, _("%s: %s-%s-%s has %d files, test = %d\n"),
01359 psm->stepName, fi->name, fi->version, fi->release,
01360 fi->fc, (ts->transFlags & RPMTRANS_FLAG_TEST));
01361
01362
01363
01364
01365
01366
01367 psm->npkgs_installed = rpmdbCountPackages(ts->rpmdb, fi->name);
01368 if (psm->npkgs_installed < 0) {
01369 rc = RPMRC_FAIL;
01370 break;
01371 }
01372
01373 if (psm->goal == PSM_PKGINSTALL) {
01374 psm->scriptArg = psm->npkgs_installed + 1;
01375
01376 assert(psm->mi == NULL);
01377 psm->mi = rpmdbInitIterator(ts->rpmdb, RPMTAG_NAME, fi->name, 0);
01378 xx = rpmdbSetIteratorRE(psm->mi, RPMTAG_VERSION,
01379 RPMMIRE_DEFAULT, fi->version);
01380 xx = rpmdbSetIteratorRE(psm->mi, RPMTAG_RELEASE,
01381 RPMMIRE_DEFAULT, fi->release);
01382
01383 while ((psm->oh = rpmdbNextIterator(psm->mi))) {
01384 fi->record = rpmdbGetIteratorOffset(psm->mi);
01385 if (ts->transFlags & RPMTRANS_FLAG_MULTILIB)
01386 psm->oh = headerCopy(psm->oh);
01387 else
01388 psm->oh = NULL;
01389 break;
01390 }
01391 psm->mi = rpmdbFreeIterator(psm->mi);
01392 rc = RPMRC_OK;
01393
01394 if (fi->fc > 0 && fi->fstates == NULL) {
01395 fi->fstates = xmalloc(sizeof(*fi->fstates) * fi->fc);
01396 memset(fi->fstates, RPMFILE_STATE_NORMAL, fi->fc);
01397 }
01398
01399 if (fi->fc <= 0) break;
01400 if (ts->transFlags & RPMTRANS_FLAG_JUSTDB) break;
01401
01402
01403
01404
01405
01406
01407 { const char * p;
01408 rc = hge(fi->h, RPMTAG_DEFAULTPREFIX, NULL, (void **) &p, NULL);
01409 fi->striplen = (rc ? strlen(p) + 1 : 1);
01410 }
01411 fi->mapflags =
01412 CPIO_MAP_PATH | CPIO_MAP_MODE | CPIO_MAP_UID | CPIO_MAP_GID;
01413
01414 if (headerIsEntry(fi->h, RPMTAG_ORIGBASENAMES))
01415 buildOrigFileList(fi->h, &fi->apath, NULL);
01416 else
01417 rpmBuildFileList(fi->h, &fi->apath, NULL);
01418
01419 if (fi->fuser == NULL)
01420 xx = hge(fi->h, RPMTAG_FILEUSERNAME, NULL,
01421 (void **) &fi->fuser, NULL);
01422 if (fi->fgroup == NULL)
01423 xx = hge(fi->h, RPMTAG_FILEGROUPNAME, NULL,
01424 (void **) &fi->fgroup, NULL);
01425 if (fi->fuids == NULL)
01426 fi->fuids = xcalloc(sizeof(*fi->fuids), fi->fc);
01427 if (fi->fgids == NULL)
01428 fi->fgids = xcalloc(sizeof(*fi->fgids), fi->fc);
01429 rc = RPMRC_OK;
01430 }
01431 if (psm->goal == PSM_PKGERASE || psm->goal == PSM_PKGSAVE) {
01432 psm->scriptArg = psm->npkgs_installed - 1;
01433
01434
01435 rc = psmStage(psm, PSM_RPMDB_LOAD);
01436 }
01437 if (psm->goal == PSM_PKGSAVE) {
01438
01439 { const char * bfmt = rpmGetPath("%{_repackage_name_fmt}", NULL);
01440 const char * pkgbn =
01441 headerSprintf(fi->h, bfmt, rpmTagTable, rpmHeaderFormats, NULL);
01442
01443 bfmt = _free(bfmt);
01444 psm->pkgURL = rpmGenPath("%{?_repackage_root:%{_repackage_root}}",
01445 "%{?_repackage_dir:%{_repackage_dir}}",
01446 pkgbn);
01447 pkgbn = _free(pkgbn);
01448 (void) urlPath(psm->pkgURL, &psm->pkgfn);
01449 psm->fd = Fopen(psm->pkgfn, "w.ufdio");
01450 if (psm->fd == NULL || Ferror(psm->fd)) {
01451 rc = RPMRC_FAIL;
01452 break;
01453 }
01454 }
01455 }
01456 break;
01457 case PSM_PRE:
01458 if (ts->transFlags & RPMTRANS_FLAG_TEST) break;
01459
01460
01461 rc = psmStage(psm, PSM_CHROOT_IN);
01462
01463 if (psm->goal == PSM_PKGINSTALL) {
01464 psm->scriptTag = RPMTAG_PREIN;
01465 psm->progTag = RPMTAG_PREINPROG;
01466
01467 if (!(ts->transFlags & RPMTRANS_FLAG_NOTRIGGERPREIN)) {
01468
01469 }
01470
01471 if (!(ts->transFlags & RPMTRANS_FLAG_NOPRE)) {
01472 rc = psmStage(psm, PSM_SCRIPT);
01473 if (rc) {
01474 rpmError(RPMERR_SCRIPT,
01475 _("%s: %s scriptlet failed (%d), skipping %s-%s-%s\n"),
01476 psm->stepName, tag2sln(psm->scriptTag), rc,
01477 fi->name, fi->version, fi->release);
01478 break;
01479 }
01480 }
01481 }
01482
01483 if (psm->goal == PSM_PKGERASE) {
01484 psm->scriptTag = RPMTAG_PREUN;
01485 psm->progTag = RPMTAG_PREUNPROG;
01486 psm->sense = RPMSENSE_TRIGGERUN;
01487 psm->countCorrection = -1;
01488
01489 if (!(ts->transFlags & RPMTRANS_FLAG_NOTRIGGERUN)) {
01490
01491 rc = psmStage(psm, PSM_TRIGGERS);
01492 if (rc) break;
01493
01494
01495 rc = psmStage(psm, PSM_IMMED_TRIGGERS);
01496 if (rc) break;
01497 }
01498
01499 if (!(ts->transFlags & RPMTRANS_FLAG_NOPREUN))
01500 rc = psmStage(psm, PSM_SCRIPT);
01501 }
01502 if (psm->goal == PSM_PKGSAVE) {
01503
01504 { void * uh = NULL;
01505 int_32 uht, uhc;
01506
01507 if (headerGetEntry(fi->h, RPMTAG_HEADERIMMUTABLE, &uht, &uh, &uhc))
01508 {
01509 psm->oh = headerCopyLoad(uh);
01510 uh = hfd(uh, uht);
01511 } else
01512 if (headerGetEntry(fi->h, RPMTAG_HEADERIMAGE, &uht, &uh, &uhc))
01513 {
01514 HeaderIterator hi;
01515 int_32 tag, type, count;
01516 hPTR_t ptr;
01517 Header oh;
01518
01519
01520 oh = headerCopyLoad(uh);
01521
01522
01523 psm->oh = headerNew();
01524
01525
01526 for (hi = headerInitIterator(oh);
01527 headerNextIterator(hi, &tag, &type, &ptr, &count);
01528 ptr = headerFreeData((void *)ptr, type))
01529 {
01530 if (ptr) (void) headerAddEntry(psm->oh, tag, type, ptr, count);
01531 }
01532 hi = headerFreeIterator(hi);
01533
01534
01535 headerFree(oh);
01536 uh = hfd(uh, uht);
01537 } else {
01538 break;
01539 }
01540 }
01541
01542
01543
01544 rc = psmStage(psm, PSM_RPMIO_FLAGS);
01545
01546
01547
01548 { int archnum = -1;
01549 int osnum = -1;
01550 struct rpmlead lead;
01551
01552 #ifndef DYING
01553 rpmGetArchInfo(NULL, &archnum);
01554 rpmGetOsInfo(NULL, &osnum);
01555 #endif
01556
01557 memset(&lead, 0, sizeof(lead));
01558
01559 lead.major = 3;
01560 lead.minor = 0;
01561 lead.type = RPMLEAD_BINARY;
01562 lead.archnum = archnum;
01563 lead.osnum = osnum;
01564 lead.signature_type = RPMSIGTYPE_HEADERSIG;
01565
01566 { char buf[256];
01567 sprintf(buf, "%s-%s-%s", fi->name, fi->version, fi->release);
01568 strncpy(lead.name, buf, sizeof(lead.name));
01569 }
01570
01571 rc = writeLead(psm->fd, &lead);
01572 if (rc) {
01573 rpmError(RPMERR_NOSPACE, _("Unable to write package: %s\n"),
01574 Fstrerror(psm->fd));
01575 rc = RPMRC_FAIL;
01576 break;
01577 }
01578 }
01579
01580
01581 { Header sig = headerRegenSigHeader(fi->h);
01582 rc = rpmWriteSignature(psm->fd, sig);
01583 sig = rpmFreeSignature(sig);
01584 if (rc) break;
01585 }
01586
01587
01588 if (psm->oh)
01589 { int_32 tid = ts->id;
01590 xx = headerAddEntry(psm->oh, RPMTAG_REMOVETID,
01591 RPM_INT32_TYPE, &tid, 1);
01592 }
01593
01594
01595 rc = headerWrite(psm->fd, psm->oh, HEADER_MAGIC_YES);
01596 if (rc) break;
01597 }
01598 break;
01599 case PSM_PROCESS:
01600 if (ts->transFlags & RPMTRANS_FLAG_TEST) break;
01601
01602 if (psm->goal == PSM_PKGINSTALL) {
01603 struct availablePackage * alp = fi->ap;
01604 int i;
01605
01606 if (fi->fc <= 0) break;
01607 if (ts->transFlags & RPMTRANS_FLAG_JUSTDB) break;
01608
01609 for (i = 0; i < fi->fc; i++) {
01610 uid_t uid;
01611 gid_t gid;
01612
01613 uid = fi->uid;
01614 gid = fi->gid;
01615 if (fi->fuser && unameToUid(fi->fuser[i], &uid)) {
01616 rpmMessage(RPMMESS_WARNING,
01617 _("user %s does not exist - using root\n"),
01618 fi->fuser[i]);
01619 uid = 0;
01620
01621 fi->fmodes[i] &= ~S_ISUID;
01622 }
01623
01624 if (fi->fgroup && gnameToGid(fi->fgroup[i], &gid)) {
01625 rpmMessage(RPMMESS_WARNING,
01626 _("group %s does not exist - using root\n"),
01627 fi->fgroup[i]);
01628 gid = 0;
01629
01630 fi->fmodes[i] &= ~S_ISGID;
01631 }
01632 if (fi->fuids) fi->fuids[i] = uid;
01633 if (fi->fgids) fi->fgids[i] = gid;
01634 }
01635
01636
01637 rc = psmStage(psm, PSM_RPMIO_FLAGS);
01638
01639 if (alp->fd == NULL) {
01640 rc = RPMRC_FAIL;
01641 break;
01642 }
01643
01644 psm->cfd = Fdopen(fdDup(Fileno(alp->fd)), psm->rpmio_flags);
01645
01646 if (psm->cfd == NULL) {
01647 rc = RPMRC_FAIL;
01648 break;
01649 }
01650
01651 rc = fsmSetup(fi->fsm, FSM_PKGINSTALL, ts, fi,
01652 psm->cfd, NULL, &psm->failedFile);
01653 xx = fsmTeardown(fi->fsm);
01654
01655 saveerrno = errno;
01656 xx = Fclose(psm->cfd);
01657 psm->cfd = NULL;
01658
01659 errno = saveerrno;
01660
01661
01662 if (!rc)
01663 rc = psmStage(psm, PSM_COMMIT);
01664
01665 if (rc) {
01666 rpmError(RPMERR_CPIO,
01667 _("unpacking of archive failed%s%s: %s\n"),
01668 (psm->failedFile != NULL ? _(" on file ") : ""),
01669 (psm->failedFile != NULL ? psm->failedFile : ""),
01670 cpioStrerror(rc));
01671 rc = RPMRC_FAIL;
01672
01673
01674 psm->what = RPMCALLBACK_UNPACK_ERROR;
01675 psm->amount = 0;
01676 psm->total = 0;
01677 xx = psmStage(psm, PSM_NOTIFY);
01678
01679 break;
01680 }
01681 psm->what = RPMCALLBACK_INST_PROGRESS;
01682 psm->amount = (fi->archiveSize ? fi->archiveSize : 100);
01683 psm->total = psm->amount;
01684 xx = psmStage(psm, PSM_NOTIFY);
01685 }
01686 if (psm->goal == PSM_PKGERASE) {
01687
01688 if (fi->fc <= 0) break;
01689 if (ts->transFlags & RPMTRANS_FLAG_JUSTDB) break;
01690 if (ts->transFlags & RPMTRANS_FLAG_APPLYONLY) break;
01691
01692 psm->what = RPMCALLBACK_UNINST_START;
01693 psm->amount = fi->fc;
01694 psm->total = fi->fc;
01695 xx = psmStage(psm, PSM_NOTIFY);
01696
01697 rc = fsmSetup(fi->fsm, FSM_PKGERASE, ts, fi,
01698 NULL, NULL, &psm->failedFile);
01699 xx = fsmTeardown(fi->fsm);
01700
01701 psm->what = RPMCALLBACK_UNINST_STOP;
01702 psm->amount = 0;
01703 psm->total = fi->fc;
01704 xx = psmStage(psm, PSM_NOTIFY);
01705
01706 }
01707 if (psm->goal == PSM_PKGSAVE) {
01708 fileAction * actions = fi->actions;
01709 fileAction action = fi->action;
01710
01711 fi->action = FA_COPYOUT;
01712 fi->actions = NULL;
01713
01714 if (psm->fd == NULL) {
01715 rc = RPMRC_FAIL;
01716 break;
01717 }
01718
01719 xx = Fflush(psm->fd);
01720 psm->cfd = Fdopen(fdDup(Fileno(psm->fd)), psm->rpmio_flags);
01721
01722 if (psm->cfd == NULL) {
01723 rc = RPMRC_FAIL;
01724 break;
01725 }
01726
01727 rc = fsmSetup(fi->fsm, FSM_PKGBUILD, ts, fi, psm->cfd,
01728 NULL, &psm->failedFile);
01729 xx = fsmTeardown(fi->fsm);
01730
01731 saveerrno = errno;
01732 xx = Fclose(psm->cfd);
01733 psm->cfd = NULL;
01734
01735 errno = saveerrno;
01736
01737
01738 fi->action = action;
01739 fi->actions = actions;
01740 }
01741 break;
01742 case PSM_POST:
01743 if (ts->transFlags & RPMTRANS_FLAG_TEST) break;
01744
01745 if (psm->goal == PSM_PKGINSTALL) {
01746 int_32 installTime = (int_32) time(NULL);
01747
01748 if (fi->fstates != NULL && fi->fc > 0)
01749 xx = headerAddEntry(fi->h, RPMTAG_FILESTATES, RPM_CHAR_TYPE,
01750 fi->fstates, fi->fc);
01751
01752 xx = headerAddEntry(fi->h, RPMTAG_INSTALLTIME, RPM_INT32_TYPE,
01753 &installTime, 1);
01754
01755 if (ts->transFlags & RPMTRANS_FLAG_MULTILIB) {
01756 uint_32 multiLib, * newMultiLib, * p;
01757
01758 if (hge(fi->h, RPMTAG_MULTILIBS, NULL,
01759 (void **) &newMultiLib, NULL) &&
01760 hge(psm->oh, RPMTAG_MULTILIBS, NULL,
01761 (void **) &p, NULL))
01762 {
01763 multiLib = *p;
01764 multiLib |= *newMultiLib;
01765 xx = hme(psm->oh, RPMTAG_MULTILIBS, RPM_INT32_TYPE,
01766 &multiLib, 1);
01767 }
01768 rc = mergeFiles(fi, psm->oh, fi->h);
01769 if (rc) break;
01770 }
01771
01772
01773
01774
01775
01776
01777 if (fi->record && !(ts->transFlags & RPMTRANS_FLAG_APPLYONLY)) {
01778 rc = psmStage(psm, PSM_RPMDB_REMOVE);
01779 if (rc) break;
01780 }
01781
01782 rc = psmStage(psm, PSM_RPMDB_ADD);
01783 if (rc) break;
01784
01785 psm->scriptTag = RPMTAG_POSTIN;
01786 psm->progTag = RPMTAG_POSTINPROG;
01787 psm->sense = RPMSENSE_TRIGGERIN;
01788 psm->countCorrection = 0;
01789
01790 if (!(ts->transFlags & RPMTRANS_FLAG_NOPOST)) {
01791 rc = psmStage(psm, PSM_SCRIPT);
01792 if (rc) break;
01793 }
01794 if (!(ts->transFlags & RPMTRANS_FLAG_NOTRIGGERIN)) {
01795
01796 rc = psmStage(psm, PSM_TRIGGERS);
01797 if (rc) break;
01798
01799
01800 rc = psmStage(psm, PSM_IMMED_TRIGGERS);
01801 if (rc) break;
01802 }
01803
01804 if (!(ts->transFlags & RPMTRANS_FLAG_APPLYONLY))
01805 rc = markReplacedFiles(psm);
01806
01807 }
01808 if (psm->goal == PSM_PKGERASE) {
01809
01810 psm->scriptTag = RPMTAG_POSTUN;
01811 psm->progTag = RPMTAG_POSTUNPROG;
01812 psm->sense = RPMSENSE_TRIGGERPOSTUN;
01813 psm->countCorrection = -1;
01814
01815 if (!(ts->transFlags & RPMTRANS_FLAG_NOPOSTUN)) {
01816 rc = psmStage(psm, PSM_SCRIPT);
01817
01818 }
01819
01820 if (!(ts->transFlags & RPMTRANS_FLAG_NOTRIGGERPOSTUN)) {
01821
01822 rc = psmStage(psm, PSM_TRIGGERS);
01823 if (rc) break;
01824 }
01825
01826 if (!(ts->transFlags & RPMTRANS_FLAG_APPLYONLY))
01827 rc = psmStage(psm, PSM_RPMDB_REMOVE);
01828 }
01829 if (psm->goal == PSM_PKGSAVE) {
01830 }
01831
01832
01833 xx = psmStage(psm, PSM_CHROOT_OUT);
01834 break;
01835 case PSM_UNDO:
01836 break;
01837 case PSM_FINI:
01838
01839 xx = psmStage(psm, PSM_CHROOT_OUT);
01840
01841 if (psm->fd) {
01842 saveerrno = errno;
01843 xx = Fclose(psm->fd);
01844 psm->fd = NULL;
01845
01846 errno = saveerrno;
01847
01848 }
01849
01850 if (psm->goal == PSM_PKGSAVE) {
01851 if (!rc) {
01852 rpmMessage(RPMMESS_VERBOSE, _("Wrote: %s\n"),
01853 (psm->pkgURL ? psm->pkgURL : "???"));
01854 }
01855 }
01856
01857 if (rc) {
01858 if (psm->failedFile)
01859 rpmError(RPMERR_CPIO,
01860 _("%s failed on file %s: %s\n"),
01861 psm->stepName, psm->failedFile, cpioStrerror(rc));
01862 else
01863 rpmError(RPMERR_CPIO, _("%s failed: %s\n"),
01864 psm->stepName, cpioStrerror(rc));
01865
01866
01867 psm->what = RPMCALLBACK_CPIO_ERROR;
01868 psm->amount = 0;
01869 psm->total = 0;
01870 xx = psmStage(psm, PSM_NOTIFY);
01871 }
01872
01873 if (fi->h && (psm->goal == PSM_PKGERASE || psm->goal == PSM_PKGSAVE))
01874 fi->h = headerFree(fi->h);
01875 psm->oh = headerFree(psm->oh);
01876 psm->pkgURL = _free(psm->pkgURL);
01877 psm->rpmio_flags = _free(psm->rpmio_flags);
01878 psm->failedFile = _free(psm->failedFile);
01879
01880 fi->fgids = _free(fi->fgids);
01881 fi->fuids = _free(fi->fuids);
01882 fi->fgroup = hfd(fi->fgroup, -1);
01883 fi->fuser = hfd(fi->fuser, -1);
01884 fi->apath = _free(fi->apath);
01885 fi->fstates = _free(fi->fstates);
01886 break;
01887
01888 case PSM_PKGINSTALL:
01889 case PSM_PKGERASE:
01890 case PSM_PKGSAVE:
01891 psm->goal = stage;
01892 psm->rc = RPMRC_OK;
01893 psm->stepName = pkgStageString(stage);
01894
01895 rc = psmStage(psm, PSM_INIT);
01896 if (!rc) rc = psmStage(psm, PSM_PRE);
01897 if (!rc) rc = psmStage(psm, PSM_PROCESS);
01898 if (!rc) rc = psmStage(psm, PSM_POST);
01899 xx = psmStage(psm, PSM_FINI);
01900 break;
01901 case PSM_PKGCOMMIT:
01902 break;
01903
01904 case PSM_CREATE:
01905 break;
01906 case PSM_NOTIFY:
01907 if (ts && ts->notify) {
01908
01909 (void) ts->notify(fi->h, psm->what, psm->amount, psm->total,
01910 (fi->ap ? fi->ap->key : NULL), ts->notifyData);
01911
01912 }
01913 break;
01914 case PSM_DESTROY:
01915 break;
01916 case PSM_COMMIT:
01917 if (!(ts->transFlags & RPMTRANS_FLAG_PKGCOMMIT)) break;
01918 if (ts->transFlags & RPMTRANS_FLAG_APPLYONLY) break;
01919
01920 rc = fsmSetup(fi->fsm, FSM_PKGCOMMIT, ts, fi,
01921 NULL, NULL, &psm->failedFile);
01922 xx = fsmTeardown(fi->fsm);
01923 break;
01924
01925 case PSM_CHROOT_IN:
01926
01927 if (ts->rootDir && !ts->chrootDone && !psm->chrootDone) {
01928 static int _loaded = 0;
01929
01930
01931
01932
01933
01934 if (!_loaded) {
01935 (void)getpwnam("root");
01936 endpwent();
01937 _loaded++;
01938 }
01939
01940 xx = chdir("/");
01941
01942 rc = chroot(ts->rootDir);
01943
01944 psm->chrootDone = ts->chrootDone = 1;
01945 if (ts->rpmdb != NULL) ts->rpmdb->db_chrootDone = 1;
01946 #ifdef DYING
01947
01948 chroot_prefix = ts->rootDir;
01949
01950 #endif
01951 }
01952 break;
01953 case PSM_CHROOT_OUT:
01954
01955 if (psm->chrootDone) {
01956
01957 rc = chroot(".");
01958
01959 psm->chrootDone = ts->chrootDone = 0;
01960 if (ts->rpmdb != NULL) ts->rpmdb->db_chrootDone = 0;
01961 #ifdef DYING
01962 chroot_prefix = NULL;
01963 #endif
01964 xx = chdir(ts->currDir);
01965 }
01966 break;
01967 case PSM_SCRIPT:
01968 rpmMessage(RPMMESS_DEBUG, _("%s: running %s script(s) (if any)\n"),
01969 psm->stepName, tag2sln(psm->scriptTag));
01970 rc = runInstScript(psm);
01971 break;
01972 case PSM_TRIGGERS:
01973
01974 rc = runTriggers(psm);
01975 break;
01976 case PSM_IMMED_TRIGGERS:
01977
01978 rc = runImmedTriggers(psm);
01979 break;
01980
01981 case PSM_RPMIO_FLAGS:
01982 { const char * payload_compressor = NULL;
01983 char * t;
01984
01985 if (!hge(fi->h, RPMTAG_PAYLOADCOMPRESSOR, NULL,
01986 (void **) &payload_compressor, NULL))
01987 payload_compressor = "gzip";
01988 psm->rpmio_flags = t = xmalloc(sizeof("w9.gzdio"));
01989 *t = '\0';
01990 t = stpcpy(t, ((psm->goal == PSM_PKGSAVE) ? "w9" : "r"));
01991 if (!strcmp(payload_compressor, "gzip"))
01992 t = stpcpy(t, ".gzdio");
01993 if (!strcmp(payload_compressor, "bzip2"))
01994 t = stpcpy(t, ".bzdio");
01995 rc = RPMRC_OK;
01996 } break;
01997
01998 case PSM_RPMDB_LOAD:
01999 assert(psm->mi == NULL);
02000 psm->mi = rpmdbInitIterator(ts->rpmdb, RPMDBI_PACKAGES,
02001 &fi->record, sizeof(fi->record));
02002
02003 fi->h = rpmdbNextIterator(psm->mi);
02004 if (fi->h)
02005 fi->h = headerLink(fi->h);
02006 else {
02007 fprintf(stderr, "*** PSM_RDB_LOAD: header #%u not found\n", fi->record);
02008 }
02009 psm->mi = rpmdbFreeIterator(psm->mi);
02010 rc = (fi->h ? RPMRC_OK : RPMRC_FAIL);
02011 break;
02012 case PSM_RPMDB_ADD:
02013 if (ts->transFlags & RPMTRANS_FLAG_TEST) break;
02014 if (fi->h != NULL)
02015 rc = rpmdbAdd(ts->rpmdb, ts->id, fi->h);
02016 break;
02017 case PSM_RPMDB_REMOVE:
02018 if (ts->transFlags & RPMTRANS_FLAG_TEST) break;
02019 rc = rpmdbRemove(ts->rpmdb, ts->id, fi->record);
02020 break;
02021
02022 default:
02023 break;
02024 }
02025
02026
02027
02028 return rc;
02029
02030 }