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 = MkdirP(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 char arg1_str [sizeof(int)*3+1] = "";
00855 char arg2_str [sizeof(int)*3+1] = "";
00856
00857 if (!progArgv && !script)
00858 return 0;
00859
00860 if (!progArgv) {
00861 argv = alloca(5 * sizeof(*argv));
00862 argv[0] = "/bin/sh";
00863 argc = 1;
00864 } else {
00865 argv = alloca((progArgc + 4) * sizeof(*argv));
00866 memcpy(argv, progArgv, progArgc * sizeof(*argv));
00867 argc = progArgc;
00868 }
00869
00870 xx = headerNVR(h, &n, &v, &r);
00871
00872 if (arg1 >= 0)
00873 sprintf(arg1_str, "%d", arg1);
00874 if (arg2 >= 0)
00875 sprintf(arg2_str, "%d", arg2);
00876
00877 if (hge(h, RPMTAG_INSTPREFIXES, &ipt, (void **) &prefixes, &numPrefixes)) {
00878 freePrefixes = 1;
00879 } else if (hge(h, RPMTAG_INSTALLPREFIX, NULL, (void **) &oldPrefix, NULL)) {
00880 prefixes = &oldPrefix;
00881 numPrefixes = 1;
00882 } else {
00883 numPrefixes = 0;
00884 }
00885
00886 maxPrefixLength = 0;
00887 for (i = 0; i < numPrefixes; i++) {
00888 len = strlen(prefixes[i]);
00889 if (len > maxPrefixLength) maxPrefixLength = len;
00890 }
00891 prefixBuf = alloca(maxPrefixLength + 50);
00892
00893 if (script) {
00894 FD_t fd;
00895
00896 if (makeTempFile((!ts->chrootDone ? ts->rootDir : "/"), &fn, &fd)) {
00897 if (freePrefixes) free(prefixes);
00898 return 1;
00899 }
00900
00901
00902 if (rpmIsDebug() &&
00903 (!strcmp(argv[0], "/bin/sh") || !strcmp(argv[0], "/bin/bash")))
00904 xx = Fwrite("set -x\n", sizeof(char), 7, fd);
00905
00906 xx = Fwrite(script, sizeof(script[0]), strlen(script), fd);
00907 xx = Fclose(fd);
00908
00909 { const char * sn = fn;
00910 if (!ts->chrootDone &&
00911 !(ts->rootDir[0] == '/' && ts->rootDir[1] == '\0'))
00912 {
00913 sn += strlen(ts->rootDir)-1;
00914 }
00915 argv[argc++] = sn;
00916 }
00917
00918 if (*arg1_str)
00919 argv[argc++] = arg1_str;
00920 if (*arg2_str)
00921 argv[argc++] = arg2_str;
00922 }
00923
00924 argv[argc] = NULL;
00925
00926 if (ts->scriptFd != NULL) {
00927 if (rpmIsVerbose()) {
00928 out = fdDup(Fileno(ts->scriptFd));
00929 } else {
00930 out = Fopen("/dev/null", "w.fdio");
00931 if (Ferror(out)) {
00932 out = fdDup(Fileno(ts->scriptFd));
00933 }
00934 }
00935 } else {
00936 out = fdDup(STDOUT_FILENO);
00937 #ifdef DYING
00938 out = fdLink(out, "runScript persist");
00939 #endif
00940 }
00941 if (out == NULL) return 1;
00942
00943
00944 if (!(child = fork())) {
00945 const char * rootDir;
00946 int pipes[2];
00947
00948 pipes[0] = pipes[1] = 0;
00949
00950 xx = pipe(pipes);
00951 xx = close(pipes[1]);
00952 xx = dup2(pipes[0], STDIN_FILENO);
00953 xx = close(pipes[0]);
00954
00955 if (ts->scriptFd != NULL) {
00956 if (Fileno(ts->scriptFd) != STDERR_FILENO)
00957 xx = dup2(Fileno(ts->scriptFd), STDERR_FILENO);
00958 if (Fileno(out) != STDOUT_FILENO)
00959 xx = dup2(Fileno(out), STDOUT_FILENO);
00960
00961 if (Fileno(out) > STDERR_FILENO && Fileno(out) != Fileno(ts->scriptFd)) {
00962 xx = Fclose (out);
00963 }
00964 if (Fileno(ts->scriptFd) > STDERR_FILENO) {
00965 xx = Fclose (ts->scriptFd);
00966 }
00967 }
00968
00969 { const char *ipath = rpmExpand("PATH=%{_install_script_path}", NULL);
00970 const char *path = SCRIPT_PATH;
00971
00972 if (ipath && ipath[5] != '%')
00973 path = ipath;
00974 xx = doputenv(path);
00975
00976 ipath = _free(ipath);
00977
00978 }
00979
00980 for (i = 0; i < numPrefixes; i++) {
00981 sprintf(prefixBuf, "RPM_INSTALL_PREFIX%d=%s", i, prefixes[i]);
00982 xx = doputenv(prefixBuf);
00983
00984
00985 if (i == 0) {
00986 sprintf(prefixBuf, "RPM_INSTALL_PREFIX=%s", prefixes[i]);
00987 xx = doputenv(prefixBuf);
00988 }
00989 }
00990
00991 dosetenv ("RPM_INSTALL_NAME", n, 1);
00992
00993 if (*arg1_str)
00994 dosetenv ("RPM_INSTALL_ARG1", arg1_str, 1);
00995 if (*arg2_str)
00996 dosetenv ("RPM_INSTALL_ARG2", arg2_str, 1);
00997
00998 if ( rpm_close_all() ) {
00999 perror( "rpm_close_all" );
01000 _exit( -1 );
01001 }
01002
01003 if ((rootDir = ts->rootDir) != NULL)
01004 switch(urlIsURL(rootDir)) {
01005 case URL_IS_PATH:
01006 rootDir += sizeof("file://") - 1;
01007 rootDir = strchr(rootDir, '/');
01008
01009 case URL_IS_UNKNOWN:
01010 if (!ts->chrootDone && !(rootDir[0] == '/' && rootDir[1] == '\0')) {
01011
01012 xx = chroot(rootDir);
01013
01014 }
01015 xx = chdir("/");
01016 xx = execv(argv[0], (char *const *)argv);
01017 break;
01018 default:
01019 break;
01020 }
01021
01022 _exit(-1);
01023
01024 }
01025
01026
01027 if (waitpid(child, &status, 0) < 0) {
01028 rpmError(RPMERR_SCRIPT,
01029 _("execution of %s scriptlet from %s-%s-%s failed, waitpid returned %s\n"),
01030 sln, n, v, r, strerror (errno));
01031
01032 rc = RPMRC_OK;
01033 } else {
01034 if (!WIFEXITED(status) || WEXITSTATUS(status)) {
01035 rpmError(RPMERR_SCRIPT,
01036 _("execution of %s scriptlet from %s-%s-%s failed, exit status %d\n"),
01037 sln, n, v, r, WEXITSTATUS(status));
01038 rc = RPMRC_FAIL;
01039 }
01040 }
01041
01042 if (freePrefixes) prefixes = hfd(prefixes, ipt);
01043
01044 xx = Fclose(out);
01045
01046 if (script) {
01047 if (!rpmIsDebug())
01048 xx = unlink(fn);
01049 fn = _free(fn);
01050 }
01051
01052 return rc;
01053 }
01054
01060 static rpmRC runInstScript(PSM_t psm)
01061
01062
01063
01064
01065 {
01066 TFI_t fi = psm->fi;
01067 HGE_t hge = fi->hge;
01068 HFD_t hfd = (fi->hfd ? fi->hfd : headerFreeData);
01069 void ** programArgv;
01070 int programArgc;
01071 const char ** argv;
01072 rpmTagType ptt, stt;
01073 const char * script;
01074 rpmRC rc = RPMRC_OK;
01075 int xx;
01076
01077
01078
01079
01080
01081 xx = hge(fi->h, psm->progTag, &ptt, (void **) &programArgv, &programArgc);
01082 xx = hge(fi->h, psm->scriptTag, &stt, (void **) &script, NULL);
01083
01084 if (programArgv && ptt == RPM_STRING_TYPE) {
01085 argv = alloca(sizeof(char *));
01086 *argv = (const char *) programArgv;
01087 } else {
01088 argv = (const char **) programArgv;
01089 }
01090
01091 rc = runScript(psm, fi->h, tag2sln(psm->scriptTag), programArgc, argv,
01092 script, psm->scriptArg, -1);
01093
01094 programArgv = hfd(programArgv, ptt);
01095 script = hfd(script, stt);
01096 return rc;
01097 }
01098
01107 static int handleOneTrigger(PSM_t psm, Header sourceH, Header triggeredH,
01108 int arg2, unsigned char * triggersAlreadyRun)
01109
01110
01111
01112
01113 {
01114 const rpmTransactionSet ts = psm->ts;
01115 TFI_t fi = psm->fi;
01116 HGE_t hge = fi->hge;
01117 HFD_t hfd = (fi->hfd ? fi->hfd : headerFreeData);
01118 const char ** triggerNames;
01119 const char ** triggerEVR;
01120 const char ** triggerScripts;
01121 const char ** triggerProgs;
01122 int_32 * triggerFlags;
01123 int_32 * triggerIndices;
01124 rpmTagType tnt, tvt, tft;
01125 const char * triggerPackageName;
01126 const char * sourceName;
01127 int numTriggers;
01128 rpmRC rc = RPMRC_OK;
01129 int i;
01130 int skip;
01131 int xx;
01132
01133 if (!( hge(triggeredH, RPMTAG_TRIGGERNAME, &tnt,
01134 (void **) &triggerNames, &numTriggers) &&
01135 hge(triggeredH, RPMTAG_TRIGGERFLAGS, &tft,
01136 (void **) &triggerFlags, NULL) &&
01137 hge(triggeredH, RPMTAG_TRIGGERVERSION, &tvt,
01138 (void **) &triggerEVR, NULL))
01139 )
01140 return 0;
01141
01142 xx = headerNVR(sourceH, &sourceName, NULL, NULL);
01143
01144 for (i = 0; i < numTriggers; i++) {
01145 rpmTagType tit, tst, tpt;
01146
01147 if (!(triggerFlags[i] & psm->sense)) continue;
01148 if (strcmp(triggerNames[i], sourceName)) continue;
01149
01150
01151
01152
01153
01154
01155
01156 skip = strlen(triggerNames[i]);
01157 if (!strncmp(triggerEVR[i], triggerNames[i], skip) &&
01158 (triggerEVR[i][skip] == '-'))
01159 skip++;
01160 else
01161 skip = 0;
01162
01163 if (!headerMatchesDepFlags(sourceH, triggerNames[i],
01164 triggerEVR[i] + skip, triggerFlags[i]))
01165 continue;
01166
01167 if (!( hge(triggeredH, RPMTAG_TRIGGERINDEX, &tit,
01168 (void **) &triggerIndices, NULL) &&
01169 hge(triggeredH, RPMTAG_TRIGGERSCRIPTS, &tst,
01170 (void **) &triggerScripts, NULL) &&
01171 hge(triggeredH, RPMTAG_TRIGGERSCRIPTPROG, &tpt,
01172 (void **) &triggerProgs, NULL))
01173 )
01174 continue;
01175
01176 xx = headerNVR(triggeredH, &triggerPackageName, NULL, NULL);
01177
01178 { int arg1;
01179 int index;
01180
01181 arg1 = rpmdbCountPackages(ts->rpmdb, triggerPackageName);
01182 if (arg1 < 0) {
01183
01184 rc = RPMRC_FAIL;
01185 } else {
01186 arg1 += psm->countCorrection;
01187 index = triggerIndices[i];
01188 if (triggersAlreadyRun == NULL ||
01189 triggersAlreadyRun[index] == 0)
01190 {
01191 rc = runScript(psm, triggeredH, "%trigger", 1,
01192 triggerProgs + index, triggerScripts[index],
01193 arg1, arg2);
01194 if (triggersAlreadyRun != NULL)
01195 triggersAlreadyRun[index] = 1;
01196 }
01197 }
01198 }
01199
01200 triggerIndices = hfd(triggerIndices, tit);
01201 triggerScripts = hfd(triggerScripts, tst);
01202 triggerProgs = hfd(triggerProgs, tpt);
01203
01204
01205
01206
01207
01208 break;
01209 }
01210
01211 triggerNames = hfd(triggerNames, tnt);
01212 triggerFlags = hfd(triggerFlags, tft);
01213 triggerEVR = hfd(triggerEVR, tvt);
01214
01215 return rc;
01216 }
01217
01223 static int runTriggers(PSM_t psm)
01224
01225
01226
01227
01228 {
01229 const rpmTransactionSet ts = psm->ts;
01230 TFI_t fi = psm->fi;
01231 int numPackage;
01232 rpmRC rc = RPMRC_OK;
01233
01234 numPackage = rpmdbCountPackages(ts->rpmdb, fi->name) + psm->countCorrection;
01235 if (numPackage < 0)
01236 return 1;
01237
01238 { Header triggeredH;
01239 rpmdbMatchIterator mi;
01240 int countCorrection = psm->countCorrection;
01241
01242 psm->countCorrection = 0;
01243 mi = rpmdbInitIterator(ts->rpmdb, RPMTAG_TRIGGERNAME, fi->name, 0);
01244 while((triggeredH = rpmdbNextIterator(mi)) != NULL) {
01245 rc |= handleOneTrigger(psm, fi->h, triggeredH, numPackage, NULL);
01246 }
01247
01248 mi = rpmdbFreeIterator(mi);
01249 psm->countCorrection = countCorrection;
01250 }
01251
01252 return rc;
01253 }
01254
01260 static int runImmedTriggers(PSM_t psm)
01261
01262
01263
01264
01265 {
01266 const rpmTransactionSet ts = psm->ts;
01267 TFI_t fi = psm->fi;
01268 HGE_t hge = fi->hge;
01269 HFD_t hfd = (fi->hfd ? fi->hfd : headerFreeData);
01270 const char ** triggerNames;
01271 int numTriggers;
01272 int_32 * triggerIndices;
01273 rpmTagType tnt, tit;
01274 int numTriggerIndices;
01275 unsigned char * triggersRun;
01276 rpmRC rc = RPMRC_OK;
01277
01278 if (!( hge(fi->h, RPMTAG_TRIGGERNAME, &tnt,
01279 (void **) &triggerNames, &numTriggers) &&
01280 hge(fi->h, RPMTAG_TRIGGERINDEX, &tit,
01281 (void **) &triggerIndices, &numTriggerIndices))
01282 )
01283 return 0;
01284
01285 triggersRun = alloca(sizeof(*triggersRun) * numTriggerIndices);
01286 memset(triggersRun, 0, sizeof(*triggersRun) * numTriggerIndices);
01287
01288 { Header sourceH = NULL;
01289 int i;
01290
01291 for (i = 0; i < numTriggers; i++) {
01292 rpmdbMatchIterator mi;
01293
01294 if (triggersRun[triggerIndices[i]] != 0) continue;
01295
01296 mi = rpmdbInitIterator(ts->rpmdb, RPMTAG_NAME, triggerNames[i], 0);
01297
01298 while((sourceH = rpmdbNextIterator(mi)) != NULL) {
01299 rc |= handleOneTrigger(psm, sourceH, fi->h,
01300 rpmdbGetIteratorCount(mi),
01301 triggersRun);
01302 }
01303
01304 mi = rpmdbFreeIterator(mi);
01305 }
01306 }
01307 triggerIndices = hfd(triggerIndices, tit);
01308 triggerNames = hfd(triggerNames, tnt);
01309 return rc;
01310 }
01311
01312 static const char *const pkgStageString(pkgStage a)
01313
01314 {
01315 switch(a) {
01316 case PSM_UNKNOWN: return "unknown";
01317
01318 case PSM_PKGINSTALL: return " install";
01319 case PSM_PKGERASE: return " erase";
01320 case PSM_PKGCOMMIT: return " commit";
01321 case PSM_PKGSAVE: return "repackage";
01322
01323 case PSM_INIT: return "init";
01324 case PSM_PRE: return "pre";
01325 case PSM_PROCESS: return "process";
01326 case PSM_POST: return "post";
01327 case PSM_UNDO: return "undo";
01328 case PSM_FINI: return "fini";
01329
01330 case PSM_CREATE: return "create";
01331 case PSM_NOTIFY: return "notify";
01332 case PSM_DESTROY: return "destroy";
01333 case PSM_COMMIT: return "commit";
01334
01335 case PSM_CHROOT_IN: return "chrootin";
01336 case PSM_CHROOT_OUT: return "chrootout";
01337 case PSM_SCRIPT: return "script";
01338 case PSM_TRIGGERS: return "triggers";
01339 case PSM_IMMED_TRIGGERS: return "immedtriggers";
01340
01341 case PSM_RPMIO_FLAGS: return "rpmioflags";
01342
01343 case PSM_RPMDB_LOAD: return "rpmdbload";
01344 case PSM_RPMDB_ADD: return "rpmdbadd";
01345 case PSM_RPMDB_REMOVE: return "rpmdbremove";
01346
01347 default: return "???";
01348 }
01349
01350 }
01351
01356 int psmStage(PSM_t psm, pkgStage stage)
01357 {
01358 const rpmTransactionSet ts = psm->ts;
01359 TFI_t fi = psm->fi;
01360 HGE_t hge = fi->hge;
01361 HME_t hme = fi->hme;
01362 HFD_t hfd = (fi->hfd ? fi->hfd : headerFreeData);
01363 rpmRC rc = psm->rc;
01364 int saveerrno;
01365 int xx;
01366
01367
01368 switch (stage) {
01369 case PSM_UNKNOWN:
01370 break;
01371 case PSM_INIT:
01372 rpmMessage(RPMMESS_DEBUG, _("%s: %s-%s-%s has %d files, test = %d\n"),
01373 psm->stepName, fi->name, fi->version, fi->release,
01374 fi->fc, (ts->transFlags & RPMTRANS_FLAG_TEST));
01375
01376
01377
01378
01379
01380
01381 psm->npkgs_installed = rpmdbCountPackages(ts->rpmdb, fi->name);
01382 if (psm->npkgs_installed < 0) {
01383 rc = RPMRC_FAIL;
01384 break;
01385 }
01386
01387 if (psm->goal == PSM_PKGINSTALL) {
01388 psm->scriptArg = psm->npkgs_installed + 1;
01389
01390 assert(psm->mi == NULL);
01391 psm->mi = rpmdbInitIterator(ts->rpmdb, RPMTAG_NAME, fi->name, 0);
01392 xx = rpmdbSetIteratorRE(psm->mi, RPMTAG_VERSION,
01393 RPMMIRE_DEFAULT, fi->version);
01394 xx = rpmdbSetIteratorRE(psm->mi, RPMTAG_RELEASE,
01395 RPMMIRE_DEFAULT, fi->release);
01396
01397 while ((psm->oh = rpmdbNextIterator(psm->mi))) {
01398 fi->record = rpmdbGetIteratorOffset(psm->mi);
01399 if (ts->transFlags & RPMTRANS_FLAG_MULTILIB)
01400 psm->oh = headerCopy(psm->oh);
01401 else
01402 psm->oh = NULL;
01403 break;
01404 }
01405 psm->mi = rpmdbFreeIterator(psm->mi);
01406 rc = RPMRC_OK;
01407
01408 if (fi->fc > 0 && fi->fstates == NULL) {
01409 fi->fstates = xmalloc(sizeof(*fi->fstates) * fi->fc);
01410 memset(fi->fstates, RPMFILE_STATE_NORMAL, fi->fc);
01411 }
01412
01413 if (fi->fc <= 0) break;
01414 if (ts->transFlags & RPMTRANS_FLAG_JUSTDB) break;
01415
01416
01417
01418
01419
01420
01421 { const char * p;
01422 rc = hge(fi->h, RPMTAG_DEFAULTPREFIX, NULL, (void **) &p, NULL);
01423 fi->striplen = (rc ? strlen(p) + 1 : 1);
01424 }
01425 fi->mapflags =
01426 CPIO_MAP_PATH | CPIO_MAP_MODE | CPIO_MAP_UID | CPIO_MAP_GID;
01427
01428 if (headerIsEntry(fi->h, RPMTAG_ORIGBASENAMES))
01429 buildOrigFileList(fi->h, &fi->apath, NULL);
01430 else
01431 rpmBuildFileList(fi->h, &fi->apath, NULL);
01432
01433 if (fi->fuser == NULL)
01434 xx = hge(fi->h, RPMTAG_FILEUSERNAME, NULL,
01435 (void **) &fi->fuser, NULL);
01436 if (fi->fgroup == NULL)
01437 xx = hge(fi->h, RPMTAG_FILEGROUPNAME, NULL,
01438 (void **) &fi->fgroup, NULL);
01439 if (fi->fuids == NULL)
01440 fi->fuids = xcalloc(sizeof(*fi->fuids), fi->fc);
01441 if (fi->fgids == NULL)
01442 fi->fgids = xcalloc(sizeof(*fi->fgids), fi->fc);
01443 rc = RPMRC_OK;
01444 }
01445 if (psm->goal == PSM_PKGERASE || psm->goal == PSM_PKGSAVE) {
01446 psm->scriptArg = psm->npkgs_installed - 1;
01447
01448
01449 rc = psmStage(psm, PSM_RPMDB_LOAD);
01450 }
01451 if (psm->goal == PSM_PKGSAVE) {
01452
01453 { const char * bfmt = rpmGetPath("%{_repackage_name_fmt}", NULL);
01454 const char * pkgbn =
01455 headerSprintf(fi->h, bfmt, rpmTagTable, rpmHeaderFormats, NULL);
01456
01457 bfmt = _free(bfmt);
01458 psm->pkgURL = rpmGenPath("%{?_repackage_root:%{_repackage_root}}",
01459 "%{?_repackage_dir:%{_repackage_dir}}",
01460 pkgbn);
01461 pkgbn = _free(pkgbn);
01462 (void) urlPath(psm->pkgURL, &psm->pkgfn);
01463 psm->fd = Fopen(psm->pkgfn, "w.ufdio");
01464 if (psm->fd == NULL || Ferror(psm->fd)) {
01465 rc = RPMRC_FAIL;
01466 break;
01467 }
01468 }
01469 }
01470 break;
01471 case PSM_PRE:
01472 if (ts->transFlags & RPMTRANS_FLAG_TEST) break;
01473
01474
01475 rc = psmStage(psm, PSM_CHROOT_IN);
01476
01477 if (psm->goal == PSM_PKGINSTALL) {
01478 psm->scriptTag = RPMTAG_PREIN;
01479 psm->progTag = RPMTAG_PREINPROG;
01480
01481 if (!(ts->transFlags & RPMTRANS_FLAG_NOTRIGGERPREIN)) {
01482
01483 }
01484
01485 if (!(ts->transFlags & RPMTRANS_FLAG_NOPRE)) {
01486 rc = psmStage(psm, PSM_SCRIPT);
01487 if (rc) {
01488 rpmError(RPMERR_SCRIPT,
01489 _("%s: %s scriptlet failed (%d), skipping %s-%s-%s\n"),
01490 psm->stepName, tag2sln(psm->scriptTag), rc,
01491 fi->name, fi->version, fi->release);
01492 break;
01493 }
01494 }
01495 }
01496
01497 if (psm->goal == PSM_PKGERASE) {
01498 psm->scriptTag = RPMTAG_PREUN;
01499 psm->progTag = RPMTAG_PREUNPROG;
01500 psm->sense = RPMSENSE_TRIGGERUN;
01501 psm->countCorrection = -1;
01502
01503 if (!(ts->transFlags & RPMTRANS_FLAG_NOTRIGGERUN)) {
01504
01505 rc = psmStage(psm, PSM_TRIGGERS);
01506 if (rc) break;
01507
01508
01509 rc = psmStage(psm, PSM_IMMED_TRIGGERS);
01510 if (rc) break;
01511 }
01512
01513 if (!(ts->transFlags & RPMTRANS_FLAG_NOPREUN))
01514 rc = psmStage(psm, PSM_SCRIPT);
01515 }
01516 if (psm->goal == PSM_PKGSAVE) {
01517
01518 { void * uh = NULL;
01519 int_32 uht, uhc;
01520
01521 if (headerGetEntry(fi->h, RPMTAG_HEADERIMMUTABLE, &uht, &uh, &uhc))
01522 {
01523 psm->oh = headerCopyLoad(uh);
01524 uh = hfd(uh, uht);
01525 } else
01526 if (headerGetEntry(fi->h, RPMTAG_HEADERIMAGE, &uht, &uh, &uhc))
01527 {
01528 HeaderIterator hi;
01529 int_32 tag, type, count;
01530 hPTR_t ptr;
01531 Header oh;
01532
01533
01534 oh = headerCopyLoad(uh);
01535
01536
01537 psm->oh = headerNew();
01538
01539
01540 for (hi = headerInitIterator(oh);
01541 headerNextIterator(hi, &tag, &type, &ptr, &count);
01542 ptr = headerFreeData((void *)ptr, type))
01543 {
01544 if (ptr) (void) headerAddEntry(psm->oh, tag, type, ptr, count);
01545 }
01546 hi = headerFreeIterator(hi);
01547
01548
01549 headerFree(oh);
01550 uh = hfd(uh, uht);
01551 } else {
01552 break;
01553 }
01554 }
01555
01556
01557
01558 rc = psmStage(psm, PSM_RPMIO_FLAGS);
01559
01560
01561
01562 { int archnum = -1;
01563 int osnum = -1;
01564 struct rpmlead lead;
01565
01566 #ifndef DYING
01567 rpmGetArchInfo(NULL, &archnum);
01568 rpmGetOsInfo(NULL, &osnum);
01569 #endif
01570
01571 memset(&lead, 0, sizeof(lead));
01572
01573 lead.major = 3;
01574 lead.minor = 0;
01575 lead.type = RPMLEAD_BINARY;
01576 lead.archnum = archnum;
01577 lead.osnum = osnum;
01578 lead.signature_type = RPMSIGTYPE_HEADERSIG;
01579
01580 { char buf[256];
01581 sprintf(buf, "%s-%s-%s", fi->name, fi->version, fi->release);
01582 strncpy(lead.name, buf, sizeof(lead.name));
01583 }
01584
01585 rc = writeLead(psm->fd, &lead);
01586 if (rc) {
01587 rpmError(RPMERR_NOSPACE, _("Unable to write package: %s\n"),
01588 Fstrerror(psm->fd));
01589 rc = RPMRC_FAIL;
01590 break;
01591 }
01592 }
01593
01594
01595 { Header sig = headerRegenSigHeader(fi->h);
01596 rc = rpmWriteSignature(psm->fd, sig);
01597 sig = rpmFreeSignature(sig);
01598 if (rc) break;
01599 }
01600
01601
01602 if (psm->oh)
01603 { int_32 tid = ts->id;
01604 xx = headerAddEntry(psm->oh, RPMTAG_REMOVETID,
01605 RPM_INT32_TYPE, &tid, 1);
01606 }
01607
01608
01609 rc = headerWrite(psm->fd, psm->oh, HEADER_MAGIC_YES);
01610 if (rc) break;
01611 }
01612 break;
01613 case PSM_PROCESS:
01614 if (ts->transFlags & RPMTRANS_FLAG_TEST) break;
01615
01616 if (psm->goal == PSM_PKGINSTALL) {
01617 struct availablePackage * alp = fi->ap;
01618 int i;
01619
01620 if (fi->fc <= 0) break;
01621 if (ts->transFlags & RPMTRANS_FLAG_JUSTDB) break;
01622
01623 for (i = 0; i < fi->fc; i++) {
01624 uid_t uid;
01625 gid_t gid;
01626
01627 uid = fi->uid;
01628 gid = fi->gid;
01629 if (fi->fuser && unameToUid(fi->fuser[i], &uid)) {
01630 rpmMessage(RPMMESS_WARNING,
01631 _("user %s does not exist - using root\n"),
01632 fi->fuser[i]);
01633 uid = 0;
01634
01635 fi->fmodes[i] &= ~S_ISUID;
01636 }
01637
01638 if (fi->fgroup && gnameToGid(fi->fgroup[i], &gid)) {
01639 rpmMessage(RPMMESS_WARNING,
01640 _("group %s does not exist - using root\n"),
01641 fi->fgroup[i]);
01642 gid = 0;
01643
01644 fi->fmodes[i] &= ~S_ISGID;
01645 }
01646 if (fi->fuids) fi->fuids[i] = uid;
01647 if (fi->fgids) fi->fgids[i] = gid;
01648 }
01649
01650
01651 rc = psmStage(psm, PSM_RPMIO_FLAGS);
01652
01653 if (alp->fd == NULL) {
01654 rc = RPMRC_FAIL;
01655 break;
01656 }
01657
01658 psm->cfd = Fdopen(fdDup(Fileno(alp->fd)), psm->rpmio_flags);
01659
01660 if (psm->cfd == NULL) {
01661 rc = RPMRC_FAIL;
01662 break;
01663 }
01664
01665 rc = fsmSetup(fi->fsm, FSM_PKGINSTALL, ts, fi,
01666 psm->cfd, NULL, &psm->failedFile);
01667 xx = fsmTeardown(fi->fsm);
01668
01669 saveerrno = errno;
01670 xx = Fclose(psm->cfd);
01671 psm->cfd = NULL;
01672
01673 errno = saveerrno;
01674
01675
01676 if (!rc)
01677 rc = psmStage(psm, PSM_COMMIT);
01678
01679 if (rc) {
01680 rpmError(RPMERR_CPIO,
01681 _("unpacking of archive failed%s%s: %s\n"),
01682 (psm->failedFile != NULL ? _(" on file ") : ""),
01683 (psm->failedFile != NULL ? psm->failedFile : ""),
01684 cpioStrerror(rc));
01685 rc = RPMRC_FAIL;
01686
01687
01688 psm->what = RPMCALLBACK_UNPACK_ERROR;
01689 psm->amount = 0;
01690 psm->total = 0;
01691 xx = psmStage(psm, PSM_NOTIFY);
01692
01693 break;
01694 }
01695 psm->what = RPMCALLBACK_INST_PROGRESS;
01696 psm->amount = (fi->archiveSize ? fi->archiveSize : 100);
01697 psm->total = psm->amount;
01698 xx = psmStage(psm, PSM_NOTIFY);
01699 }
01700 if (psm->goal == PSM_PKGERASE) {
01701
01702 if (fi->fc <= 0) break;
01703 if (ts->transFlags & RPMTRANS_FLAG_JUSTDB) break;
01704 if (ts->transFlags & RPMTRANS_FLAG_APPLYONLY) break;
01705
01706 psm->what = RPMCALLBACK_UNINST_START;
01707 psm->amount = fi->fc;
01708 psm->total = fi->fc;
01709 xx = psmStage(psm, PSM_NOTIFY);
01710
01711 rc = fsmSetup(fi->fsm, FSM_PKGERASE, ts, fi,
01712 NULL, NULL, &psm->failedFile);
01713 xx = fsmTeardown(fi->fsm);
01714
01715 psm->what = RPMCALLBACK_UNINST_STOP;
01716 psm->amount = 0;
01717 psm->total = fi->fc;
01718 xx = psmStage(psm, PSM_NOTIFY);
01719
01720 }
01721 if (psm->goal == PSM_PKGSAVE) {
01722 fileAction * actions = fi->actions;
01723 fileAction action = fi->action;
01724
01725 fi->action = FA_COPYOUT;
01726 fi->actions = NULL;
01727
01728 if (psm->fd == NULL) {
01729 rc = RPMRC_FAIL;
01730 break;
01731 }
01732
01733 xx = Fflush(psm->fd);
01734 psm->cfd = Fdopen(fdDup(Fileno(psm->fd)), psm->rpmio_flags);
01735
01736 if (psm->cfd == NULL) {
01737 rc = RPMRC_FAIL;
01738 break;
01739 }
01740
01741 rc = fsmSetup(fi->fsm, FSM_PKGBUILD, ts, fi, psm->cfd,
01742 NULL, &psm->failedFile);
01743 xx = fsmTeardown(fi->fsm);
01744
01745 saveerrno = errno;
01746 xx = Fclose(psm->cfd);
01747 psm->cfd = NULL;
01748
01749 errno = saveerrno;
01750
01751
01752 fi->action = action;
01753 fi->actions = actions;
01754 }
01755 break;
01756 case PSM_POST:
01757 if (ts->transFlags & RPMTRANS_FLAG_TEST) break;
01758
01759 if (psm->goal == PSM_PKGINSTALL) {
01760 int_32 installTime = (int_32) time(NULL);
01761
01762 if (fi->fstates != NULL && fi->fc > 0)
01763 xx = headerAddEntry(fi->h, RPMTAG_FILESTATES, RPM_CHAR_TYPE,
01764 fi->fstates, fi->fc);
01765
01766 xx = headerAddEntry(fi->h, RPMTAG_INSTALLTIME, RPM_INT32_TYPE,
01767 &installTime, 1);
01768
01769 if (ts->transFlags & RPMTRANS_FLAG_MULTILIB) {
01770 uint_32 multiLib, * newMultiLib, * p;
01771
01772 if (hge(fi->h, RPMTAG_MULTILIBS, NULL,
01773 (void **) &newMultiLib, NULL) &&
01774 hge(psm->oh, RPMTAG_MULTILIBS, NULL,
01775 (void **) &p, NULL))
01776 {
01777 multiLib = *p;
01778 multiLib |= *newMultiLib;
01779 xx = hme(psm->oh, RPMTAG_MULTILIBS, RPM_INT32_TYPE,
01780 &multiLib, 1);
01781 }
01782 rc = mergeFiles(fi, psm->oh, fi->h);
01783 if (rc) break;
01784 }
01785
01786
01787
01788
01789
01790
01791 if (fi->record && !(ts->transFlags & RPMTRANS_FLAG_APPLYONLY)) {
01792 rc = psmStage(psm, PSM_RPMDB_REMOVE);
01793 if (rc) break;
01794 }
01795
01796 rc = psmStage(psm, PSM_RPMDB_ADD);
01797 if (rc) break;
01798
01799 psm->scriptTag = RPMTAG_POSTIN;
01800 psm->progTag = RPMTAG_POSTINPROG;
01801 psm->sense = RPMSENSE_TRIGGERIN;
01802 psm->countCorrection = 0;
01803
01804 if (!(ts->transFlags & RPMTRANS_FLAG_NOPOST)) {
01805 rc = psmStage(psm, PSM_SCRIPT);
01806 if (rc) break;
01807 }
01808 if (!(ts->transFlags & RPMTRANS_FLAG_NOTRIGGERIN)) {
01809
01810 rc = psmStage(psm, PSM_TRIGGERS);
01811 if (rc) break;
01812
01813
01814 rc = psmStage(psm, PSM_IMMED_TRIGGERS);
01815 if (rc) break;
01816 }
01817
01818 if (!(ts->transFlags & RPMTRANS_FLAG_APPLYONLY))
01819 rc = markReplacedFiles(psm);
01820
01821 }
01822 if (psm->goal == PSM_PKGERASE) {
01823
01824 psm->scriptTag = RPMTAG_POSTUN;
01825 psm->progTag = RPMTAG_POSTUNPROG;
01826 psm->sense = RPMSENSE_TRIGGERPOSTUN;
01827 psm->countCorrection = -1;
01828
01829 if (!(ts->transFlags & RPMTRANS_FLAG_NOPOSTUN)) {
01830 rc = psmStage(psm, PSM_SCRIPT);
01831
01832 }
01833
01834 if (!(ts->transFlags & RPMTRANS_FLAG_NOTRIGGERPOSTUN)) {
01835
01836 rc = psmStage(psm, PSM_TRIGGERS);
01837 if (rc) break;
01838 }
01839
01840 if (!(ts->transFlags & RPMTRANS_FLAG_APPLYONLY))
01841 rc = psmStage(psm, PSM_RPMDB_REMOVE);
01842 }
01843 if (psm->goal == PSM_PKGSAVE) {
01844 }
01845
01846
01847 xx = psmStage(psm, PSM_CHROOT_OUT);
01848 break;
01849 case PSM_UNDO:
01850 break;
01851 case PSM_FINI:
01852
01853 xx = psmStage(psm, PSM_CHROOT_OUT);
01854
01855 if (psm->fd) {
01856 saveerrno = errno;
01857 xx = Fclose(psm->fd);
01858 psm->fd = NULL;
01859
01860 errno = saveerrno;
01861
01862 }
01863
01864 if (psm->goal == PSM_PKGSAVE) {
01865 if (!rc) {
01866 rpmMessage(RPMMESS_VERBOSE, _("Wrote: %s\n"),
01867 (psm->pkgURL ? psm->pkgURL : "???"));
01868 }
01869 }
01870
01871 if (rc) {
01872 if (psm->failedFile)
01873 rpmError(RPMERR_CPIO,
01874 _("%s failed on file %s: %s\n"),
01875 psm->stepName, psm->failedFile, cpioStrerror(rc));
01876 else
01877 rpmError(RPMERR_CPIO, _("%s failed: %s\n"),
01878 psm->stepName, cpioStrerror(rc));
01879
01880
01881 psm->what = RPMCALLBACK_CPIO_ERROR;
01882 psm->amount = 0;
01883 psm->total = 0;
01884 xx = psmStage(psm, PSM_NOTIFY);
01885 }
01886
01887 if (fi->h && (psm->goal == PSM_PKGERASE || psm->goal == PSM_PKGSAVE))
01888 fi->h = headerFree(fi->h);
01889 psm->oh = headerFree(psm->oh);
01890 psm->pkgURL = _free(psm->pkgURL);
01891 psm->rpmio_flags = _free(psm->rpmio_flags);
01892 psm->failedFile = _free(psm->failedFile);
01893
01894 fi->fgids = _free(fi->fgids);
01895 fi->fuids = _free(fi->fuids);
01896 fi->fgroup = hfd(fi->fgroup, -1);
01897 fi->fuser = hfd(fi->fuser, -1);
01898 fi->apath = _free(fi->apath);
01899 fi->fstates = _free(fi->fstates);
01900 break;
01901
01902 case PSM_PKGINSTALL:
01903 case PSM_PKGERASE:
01904 case PSM_PKGSAVE:
01905 psm->goal = stage;
01906 psm->rc = RPMRC_OK;
01907 psm->stepName = pkgStageString(stage);
01908
01909 rc = psmStage(psm, PSM_INIT);
01910 if (!rc) rc = psmStage(psm, PSM_PRE);
01911 if (!rc) rc = psmStage(psm, PSM_PROCESS);
01912 if (!rc) rc = psmStage(psm, PSM_POST);
01913 xx = psmStage(psm, PSM_FINI);
01914 break;
01915 case PSM_PKGCOMMIT:
01916 break;
01917
01918 case PSM_CREATE:
01919 break;
01920 case PSM_NOTIFY:
01921 if (ts && ts->notify) {
01922
01923 (void) ts->notify(fi->h, psm->what, psm->amount, psm->total,
01924 (fi->ap ? fi->ap->key : NULL), ts->notifyData);
01925
01926 }
01927 break;
01928 case PSM_DESTROY:
01929 break;
01930 case PSM_COMMIT:
01931 if (!(ts->transFlags & RPMTRANS_FLAG_PKGCOMMIT)) break;
01932 if (ts->transFlags & RPMTRANS_FLAG_APPLYONLY) break;
01933
01934 rc = fsmSetup(fi->fsm, FSM_PKGCOMMIT, ts, fi,
01935 NULL, NULL, &psm->failedFile);
01936 xx = fsmTeardown(fi->fsm);
01937 break;
01938
01939 case PSM_CHROOT_IN:
01940
01941 if (ts->rootDir && !(ts->rootDir[0] == '/' && ts->rootDir[1] == '\0') &&
01942 !ts->chrootDone && !psm->chrootDone) {
01943 static int _loaded = 0;
01944
01945
01946
01947
01948
01949 if (!_loaded) {
01950 (void)getpwnam("root");
01951 endpwent();
01952 _loaded++;
01953 }
01954
01955 xx = chdir("/");
01956
01957 rc = chroot(ts->rootDir);
01958
01959 psm->chrootDone = ts->chrootDone = 1;
01960 if (ts->rpmdb != NULL) ts->rpmdb->db_chrootDone = 1;
01961 #ifdef DYING
01962
01963 chroot_prefix = ts->rootDir;
01964
01965 #endif
01966 }
01967 break;
01968 case PSM_CHROOT_OUT:
01969
01970 if (psm->chrootDone) {
01971
01972 rc = chroot(".");
01973
01974 psm->chrootDone = ts->chrootDone = 0;
01975 if (ts->rpmdb != NULL) ts->rpmdb->db_chrootDone = 0;
01976 #ifdef DYING
01977 chroot_prefix = NULL;
01978 #endif
01979 xx = chdir(ts->currDir);
01980 }
01981 break;
01982 case PSM_SCRIPT:
01983 rpmMessage(RPMMESS_DEBUG, _("%s: running %s script(s) (if any)\n"),
01984 psm->stepName, tag2sln(psm->scriptTag));
01985 rc = runInstScript(psm);
01986 break;
01987 case PSM_TRIGGERS:
01988
01989 rc = runTriggers(psm);
01990 break;
01991 case PSM_IMMED_TRIGGERS:
01992
01993 rc = runImmedTriggers(psm);
01994 break;
01995
01996 case PSM_RPMIO_FLAGS:
01997 { const char * payload_compressor = NULL;
01998 char * t;
01999
02000 if (!hge(fi->h, RPMTAG_PAYLOADCOMPRESSOR, NULL,
02001 (void **) &payload_compressor, NULL))
02002 payload_compressor = "gzip";
02003 psm->rpmio_flags = t = xmalloc(sizeof("w9.gzdio"));
02004 *t = '\0';
02005 t = stpcpy(t, ((psm->goal == PSM_PKGSAVE) ? "w9" : "r"));
02006 if (!strcmp(payload_compressor, "gzip"))
02007 t = stpcpy(t, ".gzdio");
02008 if (!strcmp(payload_compressor, "bzip2"))
02009 t = stpcpy(t, ".bzdio");
02010 rc = RPMRC_OK;
02011 } break;
02012
02013 case PSM_RPMDB_LOAD:
02014 assert(psm->mi == NULL);
02015 psm->mi = rpmdbInitIterator(ts->rpmdb, RPMDBI_PACKAGES,
02016 &fi->record, sizeof(fi->record));
02017
02018 fi->h = rpmdbNextIterator(psm->mi);
02019 if (fi->h)
02020 fi->h = headerLink(fi->h);
02021 else {
02022 fprintf(stderr, "*** PSM_RDB_LOAD: header #%u not found\n", fi->record);
02023 }
02024 psm->mi = rpmdbFreeIterator(psm->mi);
02025 rc = (fi->h ? RPMRC_OK : RPMRC_FAIL);
02026 break;
02027 case PSM_RPMDB_ADD:
02028 if (ts->transFlags & RPMTRANS_FLAG_TEST) break;
02029 if (fi->h != NULL)
02030 rc = rpmdbAdd(ts->rpmdb, ts->id, fi->h);
02031 #if HAVE_SYSLOG_H
02032 syslog( LOG_NOTICE, "%s-%u:%s-%s installed\n", fi->name, (-1 == fi->epoch) ? 0 : fi->epoch, fi->version, fi->release);
02033 #endif
02034 break;
02035 case PSM_RPMDB_REMOVE:
02036 if (ts->transFlags & RPMTRANS_FLAG_TEST) break;
02037 rc = rpmdbRemove(ts->rpmdb, ts->id, fi->record);
02038 #if HAVE_SYSLOG_H
02039 syslog( LOG_NOTICE, "%s-%u:%s-%s removed\n", fi->name, (-1 == fi->epoch) ? 0 : fi->epoch, fi->version, fi->release);
02040 #endif
02041 break;
02042
02043 default:
02044 break;
02045 }
02046
02047
02048
02049 return rc;
02050
02051 }