rpm  5.4.10
transaction.c
Go to the documentation of this file.
1 
5 #include "system.h"
6 
7 #include <rpmio.h>
8 #include <rpmiotypes.h>
9 #include <rpmlog.h>
10 #include <rpmmacro.h> /* XXX for rpmExpand */
11 #include <rpmsx.h>
12 
13 #include <rpmtypes.h>
14 #include <rpmtag.h>
15 #include <pkgio.h>
16 
17 #define _FPRINT_INTERNAL
18 #include "fprint.h"
19 
20 #define _RPMDB_INTERNAL /* XXX for dbiIndexFoo() */
21 #include <rpmdb.h>
22 #include "legacy.h" /* XXX dodigest */
23 
24 #define _RPMFI_INTERNAL
25 #include <rpmfi.h>
26 #include "fsm.h"
27 
28 #define _RPMTE_INTERNAL
29 #include "rpmte.h"
30 #define _RPMTS_INTERNAL
31 #include "rpmts.h"
32 
33 #define _RPMSQ_INTERNAL
34 #define _RPMPSM_INTERNAL
35 #include "psm.h"
36 
37 #include "rpmds.h"
38 
39 #include "rpmlock.h"
40 
41 #include "misc.h" /* XXX currentDirectory */
42 
43 #if defined(RPM_VENDOR_MANDRIVA)
44 #include "filetriggers.h" /* XXX mayAddToFilesAwaitingFiletriggers, rpmRunFileTriggers */
45 #endif
46 
47 #include <rpmcli.h> /* XXX QVA_t INSTALL_FOO flags */
48 #include <rpmrollback.h> /* IDTX prototypes */
49 
50 #include "debug.h"
51 
52 /*@access dbiIndexSet @*/
53 
54 /*@access fnpyKey @*/
55 
56 /*@access alKey @*/
57 /*@access rpmdb @*/ /* XXX cast */
58 
59 /*@access rpmfi @*/
60 /*@access rpmps @*/ /* XXX need rpmProblemSetOK() */
61 /*@access rpmpsm @*/
62 
63 /*@access rpmte @*/
64 /*@access rpmtsi @*/
65 /*@access rpmts @*/
66 
67 /*@access IDT @*/
68 /*@access IDTX @*/
69 /*@access FD_t @*/
70 
71 #ifdef __cplusplus
72 
73 #define FF_ISSET(_fflags, _FLAG) ((_fflags) & (RPMFILE_##_FLAG))
74 
75 #define QVA_ISSET(_qvaflags, _FLAG) ((_qvaflags) & (VERIFY_##_FLAG))
76 
77 #define VSF_ISSET(_vsflags, _FLAG) ((_vsflags) & (RPMVSF_##_FLAG))
78 #define VSF_SET(_vsflags, _FLAG) \
79  (*((unsigned *)&(_vsflags)) |= (RPMVSF_##_FLAG))
80 #define VSF_CLR(_vsflags, _FLAG) \
81  (*((unsigned *)&(_vsflags)) &= ~(RPMVSF_##_FLAG))
82 
83 #define TSF_ISSET(_tsflags, _FLAG) ((_tsflags) & (RPMTRANS_FLAG_##_FLAG))
84 #define TSF_SET(_tsflags, _FLAG) \
85  (*((unsigned *)&(_tsflags)) |= (RPMTRANS_FLAG_##_FLAG))
86 #define TSF_CLR(_tsflags, _FLAG) \
87  (*((unsigned *)&(_tsflags)) &= ~(RPMTRANS_FLAG_##_FLAG))
88 
89 #define IIF_ISSET(_iflags, _FLAG) ((_iflags) & (INSTALL_##_FLAG))
90 #define IIF_SET(_iflags, _FLAG) \
91  (*((unsigned *)&(_iflags)) |= (INSTALL_##_FLAG))
92 #define IIF_CLR(_iflags, _FLAG) \
93  (*((unsigned *)&(_iflags)) &= ~(INSTALL_##_FLAG))
94 
95 GENfree(int *)
96 GENfree(struct fingerPrint_s *)
97 
98 #else /* __cplusplus */
99 
100 #define FF_ISSET(_fflags, _FLAG) ((_fflags) & (RPMFILE_##_FLAG))
101 
102 #define QVA_ISSET(_qvaflags, _FLAG) ((_qvaflags) & (VERIFY_##_FLAG))
103 
104 #define VSF_ISSET(_vsflags, _FLAG) ((_vsflags) & (RPMVSF_##_FLAG))
105 #define VSF_SET(_vsflags, _FLAG) (_vsflags) |= (RPMVSF_##_FLAG)
106 #define VSF_CLR(_vsflags, _FLAG) (_vsflags) &= ~(RPMVSF_##_FLAG)
107 
108 #define TSF_ISSET(_tsflags, _FLAG) ((_tsflags) & (RPMTRANS_FLAG_##_FLAG))
109 #define TSF_SET(_tsflags, _FLAG) (_tsflags) |= (RPMTRANS_FLAG_##_FLAG)
110 #define TSF_CLR(_tsflags, _FLAG) (_tsflags) &= ~(RPMTRANS_FLAG_##_FLAG)
111 
112 #define IIF_ISSET(_iflags, _FLAG) ((_iflags) & (INSTALL_##_FLAG))
113 #define IIF_SET(_iflags, _FLAG) (_iflags) |= (INSTALL_##_FLAG)
114 #define IIF_CLR(_iflags, _FLAG) (_iflags) &= ~(INSTALL_##_FLAG)
115 
116 #endif /* __cplusplus */
117 
118 static int handleInstInstalledFile(const rpmts ts, rpmte p, rpmfi fi,
119  Header otherHeader, rpmfi otherFi,
120  int beingRemoved)
121  /*@modifies ts, p, fi @*/
122 {
123  unsigned int fx = rpmfiFX(fi);
124  int isCfgFile = (FF_ISSET(rpmfiFFlags(otherFi), CONFIG) || FF_ISSET(rpmfiFFlags(fi), CONFIG));
125 #ifdef REFERENCE
126  rpmfs fs = rpmteGetFileStates(p);
127  if (XFA_SKIPPING(rpmfsGetAction(fs, fx)))
128 #else
129  if (iosmFileActionSkipped((iosmFileAction) fi->actions[fx]))
130 #endif
131  return 0;
132 
133  if (rpmfiCompare(otherFi, fi)) {
134 #ifdef REFERENCE
135  rpm_color_t tscolor = rpmtsColor(ts);
136  rpm_color_t prefcolor = rpmtsPrefColor(ts);
137  rpm_color_t FColor = rpmfiFColor(fi) & tscolor;
138  rpm_color_t oFColor = rpmfiFColor(otherFi) & tscolor;
139 #else
140  rpmuint32_t tscolor = rpmtsColor(ts);
141  rpmuint32_t prefcolor = rpmtsPrefColor(ts);
142  rpmuint32_t FColor = rpmfiFColor(fi) & tscolor;
143  rpmuint32_t oFColor = rpmfiFColor(otherFi) & tscolor;
144 #endif
145  int rConflicts;
146 
147  rConflicts = !(beingRemoved || (rpmtsFilterFlags(ts) & RPMPROB_FILTER_REPLACEOLDFILES));
148  /* Resolve file conflicts to prefer Elf64 (if not forced). */
149  if (tscolor != 0 && FColor != 0 && FColor != oFColor) {
150  if (oFColor & prefcolor) {
151 #ifdef REFERENCE
152  rpmfsSetAction(fs, fx, FA_SKIPCOLOR);
153 #else
154  fi->actions[fx] = FA_SKIPCOLOR;
155 #endif
156  rConflicts = 0;
157  } else if (FColor & prefcolor) {
158 #ifdef REFERENCE
159  rpmfsSetAction(fs, fx, FA_CREATE);
160 #else
161  fi->actions[fx] = FA_CREATE;
162 #endif
163  rConflicts = 0;
164  }
165  }
166 
167  if (rConflicts) {
168  HE_t he = (HE_t) memset(alloca(sizeof(*he)), 0, sizeof(*he));
169  rpmps ps = rpmtsProblems(ts);
170  int xx;
171  he->tag = RPMTAG_NVRA;
172  xx = headerGet(otherHeader, he, 0);
174  rpmteNEVRA(p), rpmteKey(p),
175  rpmfiDN(fi), rpmfiBN(fi),
176  he->p.str,
177  0);
178  he->p.ptr = _free(he->p.ptr);
179  ps = rpmpsFree(ps);
180  }
181 
182  /* Save file identifier to mark as state REPLACED. */
183 #ifdef REFERENCE
184  if ( !(isCfgFile || XFA_SKIPPING(rpmfsGetAction(fs, fx))) ) {
185  if (!beingRemoved)
186  rpmfsAddReplaced(rpmteGetFileStates(p), rpmfiFX(fi),
187  headerGetInstance(otherHeader),
188  rpmfiFX(otherFi));
189  }
190 #else
191  if ( !(isCfgFile || iosmFileActionSkipped((iosmFileAction) fi->actions[fx])) ) {
192  if (!beingRemoved) {
193  struct sharedFileInfo_s _shared;
194 
195  p->replaced = (sharedFileInfo) xrealloc(p->replaced,
196  sizeof(*p->replaced) * (p->nreplaced + 1));
197  memset(p->replaced + p->nreplaced, 0, sizeof(*p->replaced));
198 
199  _shared.pkgFileNum = fx;
200  _shared.otherFileNum = rpmfiFX(otherFi);
201  _shared.otherPkg = headerGetInstance(otherHeader);
202  _shared.isRemoved = 0;
203  p->replaced[p->nreplaced++] = _shared;
204  }
205  }
206 #endif
207  }
208 
209  /* Determine config file disposition, skipping missing files (if any). */
210  if (isCfgFile) {
211  rpmtransFlags tsflags = rpmtsFlags(ts);
212  int skipMissing = (TSF_ISSET(tsflags, ALLFILES) ? 0 : 1);
213 #ifdef REFERENCE
214  rpmFileAction action = rpmfiDecideFate(otherFi, fi, skipMissing);
215  rpmfsSetAction(fs, fx, action);
216 #else
217  fi->actions[fx] = rpmfiDecideFate(otherFi, fi, skipMissing);
218 #endif
219  }
220 #ifdef REFERENCE
221  rpmfiSetFReplacedSize(fi, rpmfiFSize(otherFi));
222 #else
223  fi->replacedSizes[fx] = rpmfiFSize(otherFi);
224 #endif
225 
226  return 0;
227 }
228 
229 #define ISROOT(_d) (((_d)[0] == '/' && (_d)[1] == '\0') ? "" : (_d))
230 
231 /*@unchecked@*/
232 int _fps_debug = 0;
233 #define FPSDEBUG(_debug, _list) if ((_debug) || _fps_debug) fprintf _list
234 
238 /* XXX only ts->{probs,di} modified */
239 static void handleOverlappedFiles(const rpmts ts, const rpmte p, rpmfi fi)
240  /*@globals h_errno, fileSystem, internalState @*/
241  /*@modifies ts, fi, fileSystem, internalState @*/
242 {
243  uint32_t fixupSize = 0;
244  rpmps ps;
245  const char * fn;
246  int i, j;
247 
248  uint32_t tscolor = rpmtsColor(ts);
249  uint32_t prefcolor = rpmtsPrefColor(ts);
250 #ifdef REFERENCE
251  rpmfs fs = rpmteGetFileStates(p);
252  rpmfs otherFs;
253 #endif /* REFERENCE */
254 
255 FPSDEBUG(0, (stderr, "--> %s(%p,%p,%p)\n", __FUNCTION__, ts, p, fi));
256  ps = rpmtsProblems(ts);
257  fi = rpmfiInit(fi, 0);
258  if (fi != NULL)
259  while ((i = rpmfiNext(fi)) >= 0) {
260  uint32_t oFColor;
261  uint32_t FColor;
262  struct fingerPrint_s * fiFps;
263  int otherPkgNum, otherFileNum;
264  rpmfi otherFi;
265 
266  rpmte otherTe;
267 #ifdef REFERENCE
268  rpmfileAttrs FFlags;
269  rpm_mode_t FMode;
270 #else /* REFERENCE */
271  rpmuint32_t FFlags;
272  rpmuint16_t FMode;
273 #endif /* REFERENCE */
274  struct rpmffi_s ** recs;
275  int numRecs;
276 
277  if (iosmFileActionSkipped((iosmFileAction) fi->actions[i]))
278  continue;
279 
280  fn = rpmfiFN(fi);
281 #ifdef REFERENCE
282  fiFps = rpmfiFpsIndex(fi, i);
283 #else /* REFERENCE */
284  fiFps = fi->fps + i;
285 #endif /* REFERENCE */
286  FFlags = rpmfiFFlags(fi);
287  FMode = rpmfiFMode(fi);
288  FColor = rpmfiFColor(fi);
289  FColor &= tscolor;
290 
291  fixupSize = 0;
292 
293  /*
294  * Retrieve all records that apply to this file. Note that the
295  * file info records were built in the same order as the packages
296  * will be installed and removed so the records for an overlapped
297  * files will be sorted in exactly the same order.
298  */
299  recs = NULL;
300  numRecs = 0;
301 #ifdef REFERENCE
302  (void) rpmFpHashGetEntry(ht, fiFps, &recs, &numRecs, NULL);
303 #else /* REFERENCE */
304  (void) htGetEntry(ts->ht, fiFps, &recs, &numRecs, NULL);
305 #endif /* REFERENCE */
306 
307  /*
308  * If this package is being added, look only at other packages
309  * being added -- removed packages dance to a different tune.
310  *
311  * If both this and the other package are being added, overlapped
312  * files must be identical (or marked as a conflict). The
313  * disposition of already installed config files leads to
314  * a small amount of extra complexity.
315  *
316  * If this package is being removed, then there are two cases that
317  * need to be worried about:
318  * If the other package is being added, then skip any overlapped files
319  * so that this package removal doesn't nuke the overlapped files
320  * that were just installed.
321  * If both this and the other package are being removed, then each
322  * file removal from preceding packages needs to be skipped so that
323  * the file removal occurs only on the last occurrence of an overlapped
324  * file in the transaction set.
325  */
326 
327  /* Locate this overlapped file in the set of added/removed packages. */
328  for (j = 0; j < numRecs && recs[j]->p != p; j++) {
329 FPSDEBUG(0, (stderr, "\trecs %p[%u:%u] te %p != %p\n", recs, (unsigned)j, (unsigned)numRecs, recs[j]->p, p));
330  }
331 FPSDEBUG(0, (stderr, "*** got recs %p[%u:%u]\n", recs, (unsigned)j, (unsigned)numRecs));
332 
333  /* Find what the previous disposition of this file was. */
334  otherFileNum = -1; /* keep gcc quiet */
335  otherFi = NULL;
336  otherTe = NULL;
337 #ifdef REFERENCE
338  otherFs = NULL;
339 #endif /* REFERENCE */
340 
341  for (otherPkgNum = j - 1; otherPkgNum >= 0; otherPkgNum--) {
342 FPSDEBUG(0, (stderr, "\trecs %p[%u:%u] %p -> {%p,%d}\n", recs, (unsigned)otherPkgNum, (unsigned)numRecs, recs[otherPkgNum], recs[otherPkgNum]->p, recs[otherPkgNum]->fileno));
343  otherTe = recs[otherPkgNum]->p;
344  otherFi = rpmteFI(otherTe, RPMTAG_BASENAMES);
345  otherFileNum = recs[otherPkgNum]->fileno;
346 #ifdef REFERENCE
347  otherFs = rpmteGetFileStates(otherTe);
348 #endif /* REFERENCE */
349 
350  /* Added packages need only look at other added packages. */
351  if (rpmteType(p) == TR_ADDED && rpmteType(otherTe) != TR_ADDED)
352  /*@innercontinue@*/ continue;
353 
354  (void) rpmfiSetFX(otherFi, otherFileNum);
355 
356  /* XXX Happens iff fingerprint for incomplete package install. */
357  if (otherFi->actions[otherFileNum] != FA_UNKNOWN)
358  /*@innerbreak@*/ break;
359  }
360 
361  oFColor = rpmfiFColor(otherFi);
362  oFColor &= tscolor;
363 
364  switch (rpmteType(p)) {
365  case TR_ADDED:
366  { int reportConflicts =
368  int done = 0;
369 
370  if (otherPkgNum < 0) {
371  iosmFileAction action;
372  /* XXX is this test still necessary? */
373  if (fi->actions[i] != FA_UNKNOWN)
374  /*@switchbreak@*/ break;
375 #ifdef REFERENCE
376  if (rpmfiConfigConflict(fi))
377 #else
378  if (FF_ISSET(FFlags, CONFIG) && FF_ISSET(FFlags, EXISTS))
379 #endif
380  {
381  /* Here is a non-overlapped pre-existing config file. */
382  action = FF_ISSET(FFlags, NOREPLACE)
383  ? FA_ALTNAME : FA_BACKUP;
384  } else {
385  action = FA_CREATE;
386  }
387 #ifdef REFERENCE
388  rpmfsSetAction(fs, i, action);
389 #else
390  fi->actions[i] = action;
391 #endif
392  /*@switchbreak@*/ break;
393  }
394 
395 assert(otherFi != NULL);
396  /* Mark added overlapped non-identical files as a conflict. */
397  if (rpmfiCompare(otherFi, fi)) {
398  int rConflicts;
399 
400  rConflicts = reportConflicts;
401  /* Resolve file conflicts to prefer Elf64 (if not forced) ... */
402  if (tscolor != 0) {
403  if (FColor & prefcolor) {
404  /* ... last file of preferred colour is installed ... */
405  if (!iosmFileActionSkipped((iosmFileAction) fi->actions[i])) {
406 #ifdef DEAD
407  /* XXX static helpers are order dependent. Ick. */
408  if (strcmp(fn, "/usr/sbin/libgcc_post_upgrade")
409  && strcmp(fn, "/usr/sbin/glibc_post_upgrade"))
410 #endif
411  otherFi->actions[otherFileNum] = FA_SKIPCOLOR;
412  }
413  fi->actions[i] = FA_CREATE;
414  rConflicts = 0;
415  } else
416  if (oFColor & prefcolor) {
417  /* ... first file of preferred colour is installed ... */
418  if (iosmFileActionSkipped((iosmFileAction) fi->actions[i]))
419  otherFi->actions[otherFileNum] = FA_CREATE;
420  fi->actions[i] = FA_SKIPCOLOR;
421  rConflicts = 0;
422  } else
423  if (FColor == 0 && oFColor == 0) {
424  /* ... otherwise, do both, last in wins. */
425  otherFi->actions[otherFileNum] = FA_CREATE;
426  fi->actions[i] = FA_CREATE;
427  rConflicts = 0;
428  }
429  done = 1;
430  }
431 
432  if (rConflicts) {
434  rpmteNEVR(p), rpmteKey(p),
435  fn, NULL,
436  rpmteNEVR((rpmte) otherFi->te),
437  0);
438  }
439  }
440 
441  /* Try to get the disk accounting correct even if a conflict. */
442  fixupSize = rpmfiFSize(otherFi);
443 
444 #ifdef REFERENCE
445  if (rpmfiConfigConflict(fi))
446 #else /* REFERENCE */
447  if (FF_ISSET(FFlags, CONFIG) && FF_ISSET(FFlags, EXISTS))
448 #endif /* REFERENCE */
449  {
450  /* Here is an overlapped pre-existing config file. */
451  fi->actions[i] = FF_ISSET(FFlags, NOREPLACE)
452  ? FA_ALTNAME : FA_SKIP;
453  } else {
454  if (!done)
455  fi->actions[i] = FA_CREATE;
456  }
457  } /*@switchbreak@*/ break;
458 
459  case TR_REMOVED:
460  if (otherPkgNum >= 0) {
461 assert(otherFi != NULL);
462  /* Here is an overlapped added file we don't want to nuke. */
463  if (otherFi->actions[otherFileNum] != FA_ERASE) {
464  /* On updates, don't remove files. */
465  fi->actions[i] = FA_SKIP;
466  /*@switchbreak@*/ break;
467  }
468  /* Here is an overlapped removed file: skip in previous. */
469  otherFi->actions[otherFileNum] = FA_SKIP;
470  }
471  if (iosmFileActionSkipped((iosmFileAction) fi->actions[i]))
472  /*@switchbreak@*/ break;
474  /*@switchbreak@*/ break;
475 
476  /* Disposition is assumed to be FA_ERASE. */
477  fi->actions[i] = FA_ERASE;
478  if (!(S_ISREG(FMode) && FF_ISSET(FFlags, CONFIG)))
479  /*@switchbreak@*/ break;
480 
481  /* Check for pre-existing modified config file that needs saving. */
482  if (!FF_ISSET(FFlags,SPARSE))
483  { int dalgo = 0;
484  size_t dlen = 0;
485  const unsigned char * digest = rpmfiDigest(fi, &dalgo, &dlen);
486  unsigned char * fdigest;
487 assert(digest != NULL);
488 
489  fdigest = (unsigned char *) xcalloc(1, dlen);
490  /* Save (by renaming) locally modified config files. */
491  if (!dodigest(dalgo, fn, fdigest, 0, NULL)
492  && memcmp(digest, fdigest, dlen))
493  fi->actions[i] = FA_BACKUP;
494  fdigest = _free(fdigest);
495  }
496  /*@switchbreak@*/ break;
497  }
498 
499  /* Update disk space info for a file. */
500 #ifdef REFERENCE
501  rpmtsUpdateDSI(ts, fiFps->entry->dev, rpmfiFSize(fi),
502  rpmfiFReplacedSize(fi), fixupSize, rpmfsGetAction(fs, i));
503 #else
504  rpmtsUpdateDSI(ts, fiFps->entry->dev, rpmfiFSize(fi),
505  fi->replacedSizes[i], fixupSize, fi->actions[i]);
506 #endif
507 
508  }
509  ps = rpmpsFree(ps);
510 }
511 
519 /*@-nullpass@*/
520 static int ensureOlder(rpmts ts,
521  const rpmte p, const Header h)
522  /*@globals internalState @*/
523  /*@modifies ts, internalState @*/
524 {
525  HE_t he = (HE_t) memset(alloca(sizeof(*he)), 0, sizeof(*he));
527  const char * reqEVR;
528  rpmds req;
529  char * t;
530  size_t nb;
531  int rc;
532 
533 FPSDEBUG(0, (stderr, "--> %s(%p,%p,%p)\n", __FUNCTION__, ts, p, h));
534  if (p == NULL || h == NULL)
535  return 1;
536 
537  nb = strlen(rpmteNEVR(p)) + (rpmteE(p) != NULL ? strlen(rpmteE(p)) : 0) + 1;
538 #ifdef RPM_VENDOR_MANDRIVA
539  nb += (rpmteD(p) != NULL ? strlen(rpmteD(p)) + 1 : 0);
540 #endif
541  t = (char *) alloca(nb);
542  *t = '\0';
543  reqEVR = t;
544  if (rpmteE(p) != NULL) t = stpcpy( stpcpy(t, rpmteE(p)), ":");
545  if (rpmteV(p) != NULL) t = stpcpy(t, rpmteV(p));
546  *t++ = '-';
547  if (rpmteR(p) != NULL) t = stpcpy(t, rpmteR(p));
548 #ifdef RPM_VENDOR_MANDRIVA
549  if (rpmteD(p) != NULL) *t++ = ':', t = stpcpy(t, rpmteD(p));
550 #endif
551 
552  req = rpmdsSingle(RPMTAG_REQUIRENAME, rpmteN(p), reqEVR, reqFlags);
553  rc = rpmdsNVRMatchesDep(h, req, _rpmds_nopromote);
554  (void)rpmdsFree(req);
555  req = NULL;
556 
557  if (rc == 0) {
558  rpmps ps = rpmtsProblems(ts);
559  he->tag = RPMTAG_NVRA;
560  rc = headerGet(h, he, 0);
561 assert(he->p.str != NULL);
563  rpmteNEVR(p), rpmteKey(p),
564  NULL, NULL,
565  he->p.str,
566  0);
567  he->p.ptr = _free(he->p.ptr);
568  ps = rpmpsFree(ps);
569  rc = 1;
570  } else
571  rc = 0;
572 
573  return rc;
574 }
575 /*@=nullpass@*/
576 
582 /*@-mustmod@*/ /* FIX: fi->actions is modified. */
583 /*@-nullpass@*/
584 static void rpmtsSkipFiles(const rpmts ts, rpmfi fi)
585  /*@globals rpmGlobalMacroContext, h_errno, internalState @*/
586  /*@modifies fi, rpmGlobalMacroContext, internalState @*/
587 {
588  rpmuint32_t tscolor = rpmtsColor(ts);
589  rpmuint32_t FColor;
590  rpmtransFlags tsflags = rpmtsFlags(ts);
591  int noConfigs = TSF_ISSET(tsflags, NOCONFIGS);
592  int noDocs = TSF_ISSET(tsflags, NODOCS);
593  ARGV_t netsharedPaths = NULL;
594  ARGV_t languages = NULL;
595  const char * dn, * bn;
596  size_t dnlen, bnlen;
597  int ix;
598  const char * s;
599  int * drc;
600  char * dff;
601  int dc;
602  int i, j;
603  int xx;
604 
605 FPSDEBUG(0, (stderr, "--> %s(%p,%p)\n", __FUNCTION__, ts, fi));
606 #if defined(RPM_VENDOR_OPENPKG) /* allow-excludedocs-default */
607  /* The "%_excludedocs" macro is intended to set the _default_ if
608  both --excludedocs and --includedocs are not specified and it
609  is evaluated already before. So, do not override it here again,
610  because it would not allow us to make "%_excludedocs 1" the
611  default. */
612 #else
613  if (!noDocs)
614  noDocs = rpmExpandNumeric("%{_excludedocs}");
615 #endif
616 
617  { const char *tmpPath = rpmExpand("%{?_netsharedpath}", NULL);
618  if (tmpPath && *tmpPath)
619  xx = argvSplit(&netsharedPaths, tmpPath, ":");
620  tmpPath = _free(tmpPath);
621  }
622 
623  s = rpmExpand("%{?_install_langs}", NULL);
624  if (!(s && *s))
625  s = _free(s);
626  if (s) {
627  xx = argvSplit(&languages, s, ":");
628  s = _free(s);
629  }
630 
631  /* Compute directory refcount, skip directory if now empty. */
632  dc = rpmfiDC(fi);
633  drc = (int *) alloca(dc * sizeof(*drc));
634  memset(drc, 0, dc * sizeof(*drc));
635  dff = (char *) alloca(dc * sizeof(*dff));
636  memset(dff, 0, dc * sizeof(*dff));
637 
638  fi = rpmfiInit(fi, 0);
639  if (fi != NULL) /* XXX lclint */
640  while ((i = rpmfiNext(fi)) >= 0)
641  {
642  ARGV_t nsp;
643 
644  bn = rpmfiBN(fi);
645  bnlen = strlen(bn);
646  ix = rpmfiDX(fi);
647  dn = rpmfiDN(fi);
648  if (dn == NULL)
649  continue; /* XXX can't happen */
650  dnlen = strlen(dn);
651 
652  drc[ix]++;
653 
654  /* Don't bother with skipped files */
655  if (iosmFileActionSkipped((iosmFileAction) fi->actions[i])) {
656  drc[ix]--; dff[ix] = 1;
657  continue;
658  }
659 
660  /* Ignore colored files not in our rainbow. */
661  FColor = rpmfiFColor(fi);
662  if (tscolor && FColor && !(tscolor & FColor)) {
663  drc[ix]--; dff[ix] = 1;
664  fi->actions[i] = FA_SKIPCOLOR;
665  continue;
666  }
667 
668  /*
669  * Skip net shared paths.
670  * Net shared paths are not relative to the current root (though
671  * they do need to take package relocations into account).
672  */
673  for (nsp = netsharedPaths; nsp && *nsp; nsp++) {
674  size_t len;
675 
676  len = strlen(*nsp);
677  if (dnlen >= len) {
678  if (strncmp(dn, *nsp, len))
679  /*@innercontinue@*/ continue;
680  /* Only directories or complete file paths can be net shared */
681  if (!(dn[len] == '/' || dn[len] == '\0'))
682  /*@innercontinue@*/ continue;
683  } else {
684  if (len < (dnlen + bnlen))
685  /*@innercontinue@*/ continue;
686  if (strncmp(dn, *nsp, dnlen))
687  /*@innercontinue@*/ continue;
688  /* Insure that only the netsharedpath basename is compared. */
689  if ((s = strchr((*nsp) + dnlen, '/')) != NULL && s[1] != '\0')
690  /*@innercontinue@*/ continue;
691  if (strncmp(bn, (*nsp) + dnlen, bnlen))
692  /*@innercontinue@*/ continue;
693  len = dnlen + bnlen;
694  /* Only directories or complete file paths can be net shared */
695  if (!((*nsp)[len] == '/' || (*nsp)[len] == '\0'))
696  /*@innercontinue@*/ continue;
697  }
698 
699  /*@innerbreak@*/ break;
700  }
701 
702  if (nsp && *nsp) {
703  drc[ix]--; dff[ix] = 1;
704  fi->actions[i] = FA_SKIPNETSHARED;
705  continue;
706  }
707 
708  /*
709  * Skip i18n language specific files.
710  */
711  if (languages != NULL && fi->flangs != NULL && *fi->flangs[i]) {
712  ARGV_t lang;
713  const char *l, *le;
714  for (lang = languages; *lang != NULL; lang++) {
715  if (!strcmp(*lang, "all"))
716  /*@innerbreak@*/ break;
717  for (l = fi->flangs[i]; *l != '\0'; l = le) {
718  for (le = l; *le != '\0' && *le != '|'; le++)
719  {};
720  if ((le-l) > 0 && !strncmp(*lang, l, (le-l)))
721  /*@innerbreak@*/ break;
722  if (*le == '|') le++; /* skip over | */
723  }
724  if (*l != '\0')
725  /*@innerbreak@*/ break;
726  }
727  if (*lang == NULL) {
728  drc[ix]--; dff[ix] = 1;
729  fi->actions[i] = FA_SKIPNSTATE;
730  continue;
731  }
732  }
733 
734  /*
735  * Skip config files if requested.
736  */
737  if (noConfigs && FF_ISSET(rpmfiFFlags(fi), CONFIG)) {
738  drc[ix]--; dff[ix] = 1;
739  fi->actions[i] = FA_SKIPNSTATE;
740  continue;
741  }
742 
743  /*
744  * Skip documentation if requested.
745  */
746  if (noDocs && FF_ISSET(rpmfiFFlags(fi), DOC)) {
747  drc[ix]--; dff[ix] = 1;
748  fi->actions[i] = FA_SKIPNSTATE;
749  continue;
750  }
751  }
752 
753  /* Skip (now empty) directories that had skipped files. */
754 #ifndef NOTYET
755  if (fi != NULL) /* XXX can't happen */
756  for (j = 0; j < dc; j++)
757 #else
758  if ((fi = rpmfiInitD(fi)) != NULL)
759  while (j = rpmfiNextD(fi) >= 0)
760 #endif
761  {
762 
763  if (drc[j]) continue; /* dir still has files. */
764  if (!dff[j]) continue; /* dir was not emptied here. */
765 
766  /* Find parent directory and basename. */
767  dn = fi->dnl[j]; dnlen = strlen(dn) - 1;
768  bn = dn + dnlen; bnlen = 0;
769  while (bn > dn && bn[-1] != '/') {
770  bnlen++;
771  dnlen--;
772  bn--;
773  }
774 
775  /* If explicitly included in the package, skip the directory. */
776  fi = rpmfiInit(fi, 0);
777  if (fi != NULL) /* XXX lclint */
778  while ((i = rpmfiNext(fi)) >= 0) {
779  const char * fdn, * fbn;
780  rpmuint16_t fFMode;
781 
782  if (iosmFileActionSkipped((iosmFileAction) fi->actions[i]))
783  /*@innercontinue@*/ continue;
784 
785  fFMode = rpmfiFMode(fi);
786 
787  if (!S_ISDIR(fFMode))
788  /*@innercontinue@*/ continue;
789  fdn = rpmfiDN(fi);
790  if (strlen(fdn) != dnlen)
791  /*@innercontinue@*/ continue;
792  if (strncmp(fdn, dn, dnlen))
793  /*@innercontinue@*/ continue;
794  fbn = rpmfiBN(fi);
795  if (strlen(fbn) != bnlen)
796  /*@innercontinue@*/ continue;
797  if (strncmp(fbn, bn, bnlen))
798  /*@innercontinue@*/ continue;
799  rpmlog(RPMLOG_DEBUG, D_("excluding directory %s\n"), dn);
800  fi->actions[i] = FA_SKIPNSTATE;
801  /*@innerbreak@*/ break;
802  }
803  }
804 
805 /*@-dependenttrans@*/
806  netsharedPaths = argvFree(netsharedPaths);
807  languages = argvFree(languages);
808 /*@=dependenttrans@*/
809 }
810 /*@=nullpass@*/
811 /*@=mustmod@*/
812 
819 static /*@null@*/
821  /*@*/
822 {
823  rpmfi fi = NULL;
824 
825  if (tsi != NULL && tsi->ocsave != -1) {
826  /*@-type -abstract@*/ /* FIX: rpmte not opaque */
827  rpmte te = rpmtsElement(tsi->ts, tsi->ocsave);
828  /*@-assignexpose@*/
829  if (te != NULL && (fi = te->fi) != NULL)
830  fi->te = te;
831  /*@=assignexpose@*/
832  /*@=type =abstract@*/
833  }
834  /*@-compdef -refcounttrans -usereleased @*/
835  return fi;
836  /*@=compdef =refcounttrans =usereleased @*/
837 }
838 
845 static int cmpArgvStr(/*@null@*/ const char ** AV, /*@null@*/ const char * B)
846  /*@*/
847 {
848  const char ** a;
849 
850  if (AV != NULL && B != NULL)
851  for (a = AV; *a != NULL; a++) {
852  if (**a && *B && !strcmp(*a, B))
853  return 1;
854  }
855  return 0;
856 }
857 
865  /*@globals fileSystem @*/
866  /*@modifies ts, p, fileSystem @*/
867 {
868  rpmtsi qi; rpmte q;
869  int bingo;
870 
871  p->linkFailed = 1;
872 
873  qi = rpmtsiInit(ts);
874  while ((q = rpmtsiNext(qi, TR_REMOVED)) != NULL) {
875 
876  if (q->done)
877  continue;
878 
879  /*
880  * Either element may have missing data and can have multiple entries.
881  * Try for hdrid, then pkgid, finally NEVRA, argv vs. argv compares.
882  */
883  bingo = cmpArgvStr(q->flink.Hdrid, p->hdrid);
884  if (!bingo)
885  bingo = cmpArgvStr(q->flink.Pkgid, p->pkgid);
886  if (!bingo)
887  bingo = cmpArgvStr(q->flink.NEVRA, p->NEVRA);
888 
889  if (!bingo)
890  continue;
891 
892  q->linkFailed = p->linkFailed;
893  }
894  qi = rpmtsiFree(qi);
895 
896  return 0;
897 }
898 
899 /* ================================================================= */
900 
901 /* Get a rpmdbMatchIterator containing all files in
902  * the rpmdb that share the basename with one from
903  * the transaction.
904  * @param ts transaction set
905  * @param fileCount no. of files
906  * @return rpmmi sorted by (package, fileNum)
907  */
908 static
909 rpmmi rpmtsFindBaseNamesInDB(rpmts ts, uint32_t fileCount)
910  /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
911  /*@modifies ts, rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
912 {
913  rpmtsi pi; rpmte p;
914  rpmfi fi;
915  rpmmi mi;
916  int i, xx;
917  const char * s;
918  size_t ns;
919  void * ptr;
920  static rpmTag _tag = RPMTAG_BASENAMES;
921  size_t n = (fileCount > 10 ? fileCount : 10);
922  static double e = 1.0e-4;
923  size_t m = 0;
924  size_t k = 0;
925  rpmbf bf;
926 
927 FPSDEBUG(0, (stderr, "--> %s(%p,%u)\n", __FUNCTION__, ts, (unsigned)fileCount));
928  rpmbfParams(n, e, &m, &k);
929  bf = rpmbfNew(m, k, 0);
930 
931  mi = rpmmiInit(rpmtsGetRdb(ts), _tag, NULL, 0);
932 
933  pi = rpmtsiInit(ts);
934  while ((p = rpmtsiNext(pi, (rpmElementType) 0)) != NULL) {
935 
936  (void) rpmdbCheckSignals();
937 
938  if ((fi = rpmteFI(p, _tag)) == NULL)
939  continue; /* XXX can't happen */
940 
941  ptr = rpmtsNotify(ts, NULL, RPMCALLBACK_TRANS_PROGRESS, rpmtsiOc(pi),
942  ts->orderCount);
943 
944  /* Gather all installed headers with matching basename's. */
945  fi = rpmfiInit(fi, 0);
946  while ((i = rpmfiNext(fi)) >= 0) {
947  s = rpmfiBN(fi);
948  ns = strlen(s);
949 
950  if (ns == 0) /* XXX "/" fixup */
951  /*@innercontinue@*/ continue;
952  if (rpmbfChk(bf, s, ns))
953  /*@innercontinue@*/ continue;
954 
955  xx = rpmmiGrowBasename(mi, s);
956 
957  xx = rpmbfAdd(bf, s, ns);
958  }
959  }
960  pi = rpmtsiFree(pi);
961  bf = rpmbfFree(bf);
962 
963  (void) rpmmiSort(mi);
964 
965  return mi;
966 }
967 
968 /* Check files in the transactions against the rpmdb
969  * Lookup all files with the same basename in the rpmdb
970  * and then check for matching finger prints
971  * @param ts transaction set
972  * @param fpc global finger print cache
973  */
974 static
975 int rpmtsCheckInstalledFiles(rpmts ts, uint32_t fileCount,
976  hashTable ht, fingerPrintCache fpc)
977  /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
978  /*@modifies ts, fpc, rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
979 {
980  HE_t he = (HE_t) memset(alloca(sizeof(*he)), 0, sizeof(*he));
981  rpmTagData BN = { NULL };
982  rpmTagData DN = { NULL };
983  rpmTagData DI = { NULL };
984  rpmTagData FSTATES = { NULL };
985  rpmuint32_t fc;
986 
987  rpmte p;
988  rpmmi mi;
989  Header h;
990  rpmfi fi;
991 
992  const char * oldDir;
993  int beingRemoved;
994  rpmfi otherFi = NULL;
995  unsigned int fileNum;
996  int xx;
997  int rc = 0;
998 
999 FPSDEBUG(0, (stderr, "--> %s(%p,%u,%p,%p)\n", __FUNCTION__, ts, (unsigned)fileCount, ht, fpc));
1000 
1001 rpmlog(RPMLOG_DEBUG, D_("computing file dispositions\n"));
1002 
1003  /* XXX fileCount == 0 installing src.rpm's */
1004  if (fileCount == 0)
1005  return rc;
1006 
1007  mi = rpmtsFindBaseNamesInDB(ts, fileCount);
1008 
1009  /* Loop over all packages from the rpmdb */
1010  while ((h = rpmmiNext(mi)) != NULL) {
1011  fingerPrint fp;
1012  uint32_t hdrNum = rpmmiInstance(mi);
1013  uint32_t tagNum = rpmmiBNTag(mi);
1014  int i;
1015  int j;
1016 
1017  /* Is this package being removed? */
1018  beingRemoved = 0;
1019  if (ts->removedPackages != NULL)
1020  for (j = 0; j < ts->numRemovedPackages; j++) {
1021  if (ts->removedPackages[j] != hdrNum)
1022  /*@innercontinue@*/ continue;
1023  beingRemoved = 1;
1024  /*@innerbreak@*/ break;
1025  }
1026 
1027  he->tag = RPMTAG_BASENAMES;
1028  xx = headerGet(h, he, 0);
1029  BN.argv = (xx ? he->p.argv : NULL);
1030  fc = (xx ? he->c : 0);
1031 
1032  he->tag = RPMTAG_DIRNAMES;
1033  xx = headerGet(h, he, 0);
1034  DN.argv = (xx ? he->p.argv : NULL);
1035  he->tag = RPMTAG_DIRINDEXES;
1036  xx = headerGet(h, he, 0);
1037  DI.ui32p = (xx ? he->p.ui32p : NULL);
1038  he->tag = RPMTAG_FILESTATES;
1039  xx = headerGet(h, he, 0);
1040  FSTATES.ui8p = (xx ? he->p.ui8p : NULL);
1041 
1042  /* loop over all interesting files in that package */
1043  oldDir = NULL;
1044  for (i = 0; i < (int)fc; i++) {
1045  const char * baseName = BN.argv[i];
1046  rpmuint32_t baseKey = hashFunctionString(0, baseName, 0);
1047  int gotRecs;
1048  struct rpmffi_s ** recs;
1049  int numRecs;
1050  const char * dirName;
1051 
1052  /* Skip uninteresting basenames. */
1053  if (baseKey != tagNum)
1054  /*@innercontinue@*/ continue;
1055  fileNum = i;
1056  dirName = DN.argv[DI.ui32p[fileNum]];
1057 
1058  /* lookup finger print for this file */
1059  if (dirName == oldDir) {
1060  /* directory is the same as last round */
1061  fp.baseName = baseName;
1062  } else {
1063  fp = fpLookup(fpc, dirName, baseName, 1);
1064  oldDir = dirName;
1065  }
1066 
1067  /* search for files in the transaction with same finger print */
1068  recs = NULL;
1069  numRecs = 0;
1070 #ifdef REFERENCE
1071  gotRecs = rpmFpHashGetEntry(ht, &fp, &recs, &numRecs, NULL);
1072 #else /* REFERENCE */
1073  gotRecs = (htGetEntry(ts->ht, &fp, &recs, &numRecs, NULL) == 0);
1074 #endif /* REFERENCE */
1075 
1076  for (j = 0; j < numRecs && gotRecs; j++) {
1077  p = recs[j]->p;
1078  fi = rpmteFI(p, RPMTAG_BASENAMES);
1079 
1080  /* Determine the fate of each file. */
1081  switch (rpmteType(p)) {
1082  case TR_ADDED:
1083  if (otherFi == NULL) {
1084  static int scareMem = 0;
1085  otherFi = rpmfiNew(ts, h, RPMTAG_BASENAMES, scareMem);
1086  }
1087  (void) rpmfiSetFX(fi, recs[j]->fileno);
1088  (void) rpmfiSetFX(otherFi, fileNum);
1089  xx = handleInstInstalledFile(ts, p, fi, h, otherFi, beingRemoved);
1090  /*@switchbreak@*/ break;
1091  case TR_REMOVED:
1092  if (!beingRemoved) {
1093  (void) rpmfiSetFX(fi, recs[j]->fileno);
1094 #ifdef REFERENCE
1095  if (*rpmtdGetChar(&ostates) == RPMFILE_STATE_NORMAL) {
1096  rpmfs fs = rpmteGetFileStates(p);
1097  rpmfsSetAction(fs, recs[j].fileno, FA_SKIP);
1098  }
1099 #else
1100  if (FSTATES.ui8p[fileNum] == RPMFILE_STATE_NORMAL)
1101  fi->actions[recs[j]->fileno] = FA_SKIP;
1102 #endif
1103  }
1104  /*@switchbreak@*/ break;
1105  }
1106  }
1107 
1108  }
1109 
1110  otherFi = rpmfiFree(otherFi);
1111  FSTATES.ptr = _free(FSTATES.ptr);
1112  DI.ptr = _free(DI.ptr);
1113  DN.ptr = _free(DN.ptr);
1114  BN.ptr = _free(BN.ptr);
1115  }
1116 
1117  mi = rpmmiFree(mi);
1118 
1119  return rc;
1120 }
1121 
1122 /*
1123  * For packages being installed:
1124  * - verify package arch/os.
1125  * - verify package epoch:version-release is newer.
1126  */
1127 static rpmps rpmtsSanityCheck(rpmts ts, uint32_t * tfcp)
1128  /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
1129  /*@modifies ts, *tfcp, rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
1130 {
1131  rpmps ps;
1132  rpmtsi pi;
1133  rpmte p;
1134  rpmfi fi;
1135  uint32_t totalFileCount = 0;
1136  int fc;
1137 
1138 FPSDEBUG(0, (stderr, "--> %s(%p,%p)\n", __FUNCTION__, ts, tfcp));
1139 rpmlog(RPMLOG_DEBUG, D_("sanity checking %d elements\n"), rpmtsNElements(ts));
1140  ps = rpmtsProblems(ts);
1141  /* The ordering doesn't matter here */
1142  pi = rpmtsiInit(ts);
1143  /* XXX Only added packages need be checked. */
1144  while ((p = rpmtsiNext(pi, TR_ADDED)) != NULL) {
1145  int xx;
1146 
1147  if (p->isSource) continue;
1148  if ((fi = rpmtsiFi(pi)) == NULL)
1149  continue; /* XXX can't happen */
1150  fc = rpmfiFC(fi);
1151 
1152 #ifdef REFERENCE
1154  if (!archOkay(rpmteA(p)))
1156  rpmteNEVRA(p), rpmteKey(p),
1157  rpmteA(p), NULL,
1158  NULL, 0);
1159 
1161  if (!osOkay(rpmteO(p)))
1163  rpmteNEVRA(p), rpmteKey(p),
1164  rpmteO(p), NULL,
1165  NULL, 0);
1166 #endif /* REFERENCE */
1167 
1169  rpmmi mi = rpmtsInitIterator(ts, RPMTAG_NAME, rpmteN(p), 0);
1170  Header h;
1171  while ((h = rpmmiNext(mi)) != NULL)
1172  xx = ensureOlder(ts, p, h);
1173  mi = rpmmiFree(mi);
1174  }
1175 
1177  ARGV_t keys = NULL;
1178  int nkeys;
1180  RPMMIRE_STRCMP, rpmteNEVRA(p), &keys);
1181  nkeys = argvCount(keys);
1182 
1183  /* mdvbz: #63711
1184  * workaround for epoch & distepoch not being part of RPMTAG_NVRA,
1185  * leading to packages of same VRA but with different epoch or distepoch
1186  * being treated as the same package */
1187  if (nkeys > 0) {
1188  int i, t;
1189  rpmTag tags[2] = { RPMTAG_EPOCH, RPMTAG_DISTEPOCH };
1190  for (t = 0; t < 2; t++) {
1191  for (i = 0; i < nkeys; i++) {
1192  rpmmi mi = rpmtsInitIterator(ts, RPMTAG_NVRA, keys[i], 0);
1193  Header h;
1194  while ((h = rpmmiNext(mi)) != NULL) {
1195  HE_t he = (HE_t) memset(alloca(sizeof(*he)), 0, sizeof(*he));
1196  const char *val = NULL;
1197  he->tag = tags[t];
1198  xx = headerGet(h, he, 0);
1199  if (he->tag == RPMTAG_EPOCH) {
1200  val = rpmteE(p);
1201  if (val ? atoi(val) : 0 != he->p.ui32p ? *(he->p.ui32p) : 0)
1202  nkeys--;
1203  } else if (he->tag == RPMTAG_DISTEPOCH) {
1204  val = rpmteD(p);
1205  if (strcmp(he->p.str ? he->p.str : "", val ? val : ""))
1206  nkeys--;
1207  }
1208  he->p.ptr = _free(he->p.ptr);
1209  }
1210  mi = rpmmiFree(mi);
1211  }
1212  }
1213  }
1214  if (nkeys > 0)
1216  rpmteNEVR(p), rpmteKey(p),
1217  NULL, NULL,
1218  NULL, 0);
1219  keys = argvFree(keys);
1220  }
1221 
1222 #ifdef REFERENCE
1223  /* XXX rpmte problems can only be relocation problems atm */
1225  rpmpsi psi = rpmpsInitIterator(rpmteProblems(p));
1226  while (rpmpsNextIterator(psi) >= 0) {
1227  rpmpsAppendProblem(ps, rpmpsGetProblem(psi));
1228  }
1229  rpmpsFreeIterator(psi);
1230  }
1231 #endif /* REFERENCE */
1232 
1233  /* Count no. of files (if any). */
1234  totalFileCount += fc;
1235 
1236  }
1237  pi = rpmtsiFree(pi);
1238 
1239  /* The ordering doesn't matter here */
1240  pi = rpmtsiInit(ts);
1241  while ((p = rpmtsiNext(pi, TR_REMOVED)) != NULL) {
1242 
1243  if (p->isSource) continue;
1244  if ((fi = rpmtsiFi(pi)) == NULL)
1245  continue; /* XXX can't happen */
1246  fc = rpmfiFC(fi);
1247 
1248  totalFileCount += fc;
1249  }
1250  pi = rpmtsiFree(pi);
1251 
1252  if (tfcp)
1253  *tfcp = totalFileCount;
1254 
1255  return ps;
1256 }
1257 
1258 /*
1259  * Run pre/post transaction script.
1260  * param ts transaction set
1261  * param stag RPMTAG_PRETRANS or RPMTAG_POSTTRANS
1262  * return 0 on success
1263  */
1264 static int rpmtsRunScript(rpmts ts, rpmTag stag)
1265  /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
1266  /*@modifies ts, rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
1267 {
1268  rpmtsi pi;
1269  rpmte p;
1270  rpmfi fi;
1271  rpmpsm psm;
1272  int xx;
1273  rpmTag ptag;
1274 
1275 FPSDEBUG(0, (stderr, "--> %s(%p,%s(%u))\n", __FUNCTION__, ts, tagName(stag), (unsigned)stag));
1276  switch (stag) {
1277  default:
1278 assert(0);
1279  /*@notreached@*/ break;
1280  case RPMTAG_PRETRANS: ptag = RPMTAG_PRETRANSPROG; break;
1281  case RPMTAG_POSTTRANS: ptag = RPMTAG_POSTTRANSPROG; break;
1282  }
1283 
1284  pi = rpmtsiInit(ts);
1285  while ((p = rpmtsiNext(pi, TR_ADDED)) != NULL) {
1286  if (p->isSource) continue;
1287  if ((fi = rpmtsiFi(pi)) == NULL)
1288  continue; /* XXX can't happen */
1289 
1290  /* If no prre/post transaction script, then don't bother. */
1291  if (!rpmteHaveTransScript(p, stag))
1292  continue;
1293 
1294  if (rpmteOpen(p, ts, 0)) {
1295  if (p->fi != NULL) /* XXX can't happen */
1296  p->fi->te = p;
1297 #ifdef REFERENCE
1298  psm = rpmpsmNew(ts, p);
1299 #else /* REFERENCE */
1300  psm = rpmpsmNew(ts, p, p->fi);
1301 #endif /* REFERENCE */
1302  xx = rpmpsmScriptStage(psm, stag, ptag);
1303  psm = rpmpsmFree(psm, __FUNCTION__);
1304  xx = rpmteClose(p, ts, 0);
1305  }
1306  }
1307  pi = rpmtsiFree(pi);
1308 
1309  return 0;
1310 }
1311 
1312 /*
1313  * Run pre/post transaction script.
1314  * param ts transaction set
1315  * param stag RPMTAG_TRIGGERPRETRANS or RPMTAG_TRIGGERPOSTTRANS
1316  * return 0 on success
1317  */
1318 static int rpmtsRunScriptTriggers(rpmts ts, rpmTag stag)
1319  /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
1320  /*@modifies ts, rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
1321 {
1322  rpmtsi pi;
1323  rpmte p;
1324  rpmfi fi;
1325  rpmpsm psm;
1326  int xx;
1327  rpmTag ptag;
1328 
1329 FPSDEBUG(0, (stderr, "--> %s(%p,%s(%u))\n", __FUNCTION__, ts, tagName(stag), (unsigned)stag));
1330  switch (stag) {
1331  default:
1332 assert(0);
1333  /*@notreached@*/ break;
1335  case RPMTAG_TRIGGERPRETRANSUN: ptag = RPMTAG_PRETRANSPROG; break;
1337  case RPMTAG_TRIGGERPOSTTRANSUN: ptag = RPMTAG_POSTTRANSPROG; break;
1338  }
1339 
1340  psm = rpmpsmNew(ts, NULL, NULL);
1342  xx = rpmpsmScriptStage(psm, stag, ptag);
1343  psm = rpmpsmFree(psm, __FUNCTION__);
1344 
1345  return 0;
1346 }
1347 /* Add fingerprint for each file not skipped. */
1348 static void rpmtsAddFingerprints(rpmts ts, uint32_t fileCount, hashTable ht,
1349  fingerPrintCache fpc)
1350  /*@modifies ts, fpc @*/
1351 {
1352  rpmtsi pi;
1353  rpmte p;
1354  rpmfi fi;
1355  int i;
1356 
1357  hashTable symlinks = htCreate(fileCount/16+16, 0, 0, fpHashFunction, fpEqual);
1358 
1359 FPSDEBUG(0, (stderr, "--> %s(%p,%u,%p,%p)\n", __FUNCTION__, ts, (unsigned)fileCount, ht, fpc));
1360  pi = rpmtsiInit(ts);
1361  while ((p = rpmtsiNext(pi, (rpmElementType) 0)) != NULL) {
1362  (void) rpmdbCheckSignals();
1363 
1364  if (p->isSource) continue;
1365  if ((fi = rpmtsiFi(pi)) == NULL)
1366  continue; /* XXX can't happen */
1367 
1368  (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_FINGERPRINT), 0);
1369 
1370  rpmfiFpLookup(fi, fpc);
1371 
1372  /* Collect symlinks. */
1373  fi = rpmfiInit(fi, 0);
1374  if (fi != NULL) /* XXX lclint */
1375  while ((i = rpmfiNext(fi)) >= 0) {
1376  char const *linktarget;
1377  linktarget = rpmfiFLink(fi);
1378  if (!(linktarget && *linktarget != '\0'))
1379  /*@innercontinue@*/ continue;
1380  if (iosmFileActionSkipped((iosmFileAction) fi->actions[i]))
1381  /*@innercontinue@*/ continue;
1382 #ifdef REFERENCE
1383  { struct rpmffi_s ffi;
1384  ffi.p = p;
1385  ffi.fileno = i;
1386  htAddEntry(symlinks, rpmfiFpsIndex(fi, i), ffi);
1387  }
1388 #else
1389  { struct rpmffi_s *ffip = (struct rpmffi_s *) alloca(sizeof(*ffip));
1390 /*@-dependenttrans@*/
1391  ffip->p = p;
1392 /*@=dependenttrans@*/
1393  ffip->fileno = i;
1394  htAddEntry(symlinks, fi->fps + i, (void *) ffip);
1395  }
1396 #endif
1397  }
1398 
1399  (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_FINGERPRINT), rpmfiFC(fi));
1400 
1401  }
1402  pi = rpmtsiFree(pi);
1403 
1404  /* ===============================================
1405  * Check fingerprints if they contain symlinks
1406  * and add them to the hash table
1407  */
1408 
1409  pi = rpmtsiInit(ts);
1410  while ((p = rpmtsiNext(pi, (rpmElementType) 0)) != NULL) {
1411  (void) rpmdbCheckSignals();
1412 
1413  if (p->isSource) continue;
1414  if ((fi = rpmteFI(p, RPMTAG_BASENAMES)) == NULL)
1415  continue; /* XXX can't happen */
1416  fi = rpmfiInit(fi, 0);
1417  (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_FINGERPRINT), 0);
1418  while ((i = rpmfiNext(fi)) >= 0) {
1419 #ifdef REFERENCE
1420  if (XFA_SKIPPING(rpmfsGetAction(rpmteGetFileStates(p), i)))
1421  continue;
1422 #else
1423  if (iosmFileActionSkipped((iosmFileAction) fi->actions[i]))
1424  /*@innercontinue@*/ continue;
1425 #endif
1426  fpLookupSubdir(symlinks, ht, fpc, p, i);
1427  }
1428  (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_FINGERPRINT), 0);
1429  }
1430  pi = rpmtsiFree(pi);
1431 
1432  symlinks = htFree(symlinks);
1433 
1434 }
1435 
1436 static int rpmtsSetup(rpmts ts, rpmprobFilterFlags ignoreSet, rpmsx * sxp)
1437  /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
1438  /*@modifies ts, *sxp, rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
1439 {
1440  rpmtransFlags tsflags = rpmtsFlags(ts);
1441  int xx;
1442 
1443 /*@+voidabstract@*/
1444 FPSDEBUG(0, (stderr, "--> %s(%p,0x%x,%p)\n", __FUNCTION__, ts, ignoreSet, (void *)sxp));
1445 /*@=voidabstract@*/
1446  /* --noscripts implies no scripts or triggers, duh. */
1447  if (TSF_ISSET(tsflags, NOSCRIPTS)) {
1448  TSF_SET(tsflags, NOPRETRANS);
1449  TSF_SET(tsflags, NOPRE);
1450  TSF_SET(tsflags, NOPOST);
1451  TSF_SET(tsflags, NOPREUN);
1452  TSF_SET(tsflags, NOPOSTUN);
1453  TSF_SET(tsflags, NOPOSTTRANS);
1454 
1455  TSF_SET(tsflags, NOTRIGGERPREIN);
1456  TSF_SET(tsflags, NOTRIGGERIN);
1457  TSF_SET(tsflags, NOTRIGGERUN);
1458  TSF_SET(tsflags, NOTRIGGERPOSTUN);
1459 
1460  (void) rpmtsSetFlags(ts, tsflags);
1461  }
1462  /* --notriggers implies no triggers, duh. */
1463  if (TSF_ISSET(tsflags, NOTRIGGERS)) {
1464  TSF_SET(tsflags, NOTRIGGERPREIN);
1465  TSF_SET(tsflags, NOTRIGGERIN);
1466  TSF_SET(tsflags, NOTRIGGERUN);
1467  TSF_SET(tsflags, NOTRIGGERPOSTUN);
1468  (void) rpmtsSetFlags(ts, tsflags);
1469  }
1470 
1471  /* --justdb implies no scripts or triggers, duh. */
1472  if (TSF_ISSET(tsflags, JUSTDB)) {
1473  TSF_SET(tsflags, NOPRETRANS);
1474  TSF_SET(tsflags, NOPRE);
1475  TSF_SET(tsflags, NOPOST);
1476  TSF_SET(tsflags, NOPREUN);
1477  TSF_SET(tsflags, NOPOSTUN);
1478  TSF_SET(tsflags, NOPOSTTRANS);
1479 
1480  TSF_SET(tsflags, NOTRIGGERPREIN);
1481  TSF_SET(tsflags, NOTRIGGERIN);
1482  TSF_SET(tsflags, NOTRIGGERUN);
1483  TSF_SET(tsflags, NOTRIGGERPOSTUN);
1484 
1485  (void) rpmtsSetFlags(ts, tsflags);
1486  }
1487 
1488  /* if SELinux isn't enabled or init fails, don't bother... */
1489  if (!rpmtsSELinuxEnabled(ts)) {
1490  TSF_SET(tsflags, NOCONTEXTS);
1491  TSF_SET(tsflags, NOPOLICY);
1492  (void) rpmtsSetFlags(ts, tsflags);
1493  }
1494 
1495  if (!(TSF_ISSET(tsflags, NOCONTEXTS) || TSF_ISSET(tsflags, NOPOLICY))) {
1496  *sxp = rpmsxNew("%{?_install_file_context_path}", 0);
1497  if (*sxp == NULL) {
1498  TSF_SET(tsflags, NOCONTEXTS);
1499  TSF_SET(tsflags, NOPOLICY);
1500  (void) rpmtsSetFlags(ts, tsflags);
1501  }
1502  } else
1503  *sxp = NULL;
1504 
1505  /* XXX Make sure the database is open RDWR for package install/erase. */
1506  { int dbmode = O_RDONLY;
1507 
1508  if (!TSF_ISSET(tsflags, TEST)) {
1509  rpmtsi pi;
1510  rpmte p;
1511  pi = rpmtsiInit(ts);
1512  while ((p = rpmtsiNext(pi, (rpmElementType) 0)) != NULL) {
1513  if (p->isSource) continue;
1514  dbmode = (O_RDWR|O_CREAT);
1515  break;
1516  }
1517  pi = rpmtsiFree(pi);
1518  }
1519 
1520  /* Open database RDWR for installing packages. */
1521  if (rpmtsOpenDB(ts, dbmode))
1522  return -1; /* XXX W2DO? */
1523 
1524  }
1525 
1526  ts->ignoreSet = ignoreSet;
1527  ts->probs = rpmpsFree(ts->probs);
1528 
1529  { const char * currDir = currentDirectory();
1530  rpmtsSetCurrDir(ts, currDir);
1531  currDir = _free(currDir);
1532  }
1533 
1534  (void) rpmtsSetChrootDone(ts, 0);
1535 
1536  /* XXX rpmtsCreate() sets the transaction id, but apps may not honor. */
1537  { rpmuint32_t tid = (rpmuint32_t) time(NULL);
1538  (void) rpmtsSetTid(ts, tid);
1539  }
1540 
1541  /* Get available space on mounted file systems. */
1542  xx = rpmtsInitDSI(ts);
1543 
1544  return 0;
1545 }
1546 
1547 static int rpmtsFinish(rpmts ts, /*@only@*/ rpmsx sx)
1548  /*@modifies sx @*/
1549 {
1550 FPSDEBUG(0, (stderr, "--> %s(%p,%p)\n", __FUNCTION__, ts, sx));
1551 #ifdef REFERENCE
1552  rpmtransFlags tsflags = rpmtsFlags(ts);
1553  if (!TSF_ISSET(tsflags, NOCONTEXTS))
1554  matchpathcon_fini();
1555 #else /* REFERENCE */
1556  if (sx != NULL) sx = rpmsxFree(sx);
1557 #endif /* REFERENCE */
1558  return 0;
1559 }
1560 
1561 static int rpmtsPrepare(rpmts ts, rpmsx sx, uint32_t fileCount,
1562  uint32_t * nrmvdp)
1563  /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
1564  /*@modifies ts, *nrmvdp, rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
1565 {
1566  rpmtsi pi;
1567  rpmte p;
1568  fingerPrintCache fpc;
1569  rpmfi fi;
1570  int xx;
1571  int rc = 0;
1572 
1573 #ifdef REFERENCE
1574  uint64_t fileCount = countFiles(ts);
1575  const char * rootDir = rpmtsRootDir(ts);
1576  int dochroot = (rootDir != NULL && strcmp(rootDir, "/") && *rootDir == '/');
1577 
1578  rpmFpHash ht = rpmFpHashCreate(fileCount/2+1, fpHashFunction, fpEqual,
1579  NULL, NULL);
1580 
1581  fpc = fpCacheCreate(fileCount/2 + 10001);
1582 
1583  rpmlog(RPMLOG_DEBUG, "computing %" PRIu64 " file fingerprints\n", fileCount);
1584 
1585  /* Skip netshared paths, not our i18n files, and excluded docs */
1586  pi = rpmtsiInit(ts);
1587  while ((p = rpmtsiNext(pi, TR_ADDED)) != NULL) {
1588  if ((fi = rpmteFI(p)) == NULL)
1589  continue; /* XXX can't happen */
1590 
1591  if (rpmfiFC(fi) > 0)
1592  rpmtsSkipFiles(ts, p);
1593  }
1594  pi = rpmtsiFree(pi);
1595 
1596  /* Enter chroot for fingerprinting if necessary */
1597  if (!rpmtsChrootDone(ts)) {
1598  xx = chdir("/");
1599  if (dochroot) {
1600  /* opening db before chroot not optimal, see rhbz#103852 c#3 */
1601  xx = rpmdbOpenAll(ts->rdb);
1602  if (chroot(rootDir) == -1) {
1603  rpmlog(RPMLOG_ERR, _("Unable to change root directory: %m\n"));
1604  rc = -1;
1605  goto exit;
1606  }
1607  }
1608  (void) rpmtsSetChrootDone(ts, 1);
1609  }
1610 
1611 #else /* REFERENCE */
1612 
1613  void * ptr;
1614  uint32_t numAdded = 0;
1615  uint32_t numRemoved = 0;
1616 
1617 FPSDEBUG(0, (stderr, "--> %s(%p,%p,%u,%p)\n", __FUNCTION__, ts, sx, (unsigned)fileCount, nrmvdp));
1618 rpmlog(RPMLOG_DEBUG, D_("computing %u file fingerprints\n"), (unsigned)fileCount);
1619 
1620  pi = rpmtsiInit(ts);
1621  while ((p = rpmtsiNext(pi, (rpmElementType) 0)) != NULL) {
1622  int fc;
1623 
1624  if (p->isSource) continue;
1625  if ((fi = rpmtsiFi(pi)) == NULL)
1626  continue; /* XXX can't happen */
1627  fc = rpmfiFC(fi);
1628 
1629  switch (rpmteType(p)) {
1630  case TR_ADDED:
1631  numAdded++;
1632  fi->record = 0;
1633  /* Skip netshared paths, not our i18n files, and excluded docs */
1634  if (fc > 0)
1635  rpmtsSkipFiles(ts, fi);
1636  /*@switchbreak@*/ break;
1637  case TR_REMOVED:
1638  numRemoved++;
1639  fi->record = rpmteDBOffset(p);
1640  /*@switchbreak@*/ break;
1641  }
1642 
1643  fi->fps = (struct fingerPrint_s *)
1644  (fc > 0 ? xmalloc(fc * sizeof(*fi->fps)) : NULL);
1645  }
1646  pi = rpmtsiFree(pi);
1647 
1648  if (nrmvdp)
1649  *nrmvdp = numRemoved;
1650 
1651  if (!rpmtsChrootDone(ts)) {
1652  const char * rootDir = rpmtsRootDir(ts);
1653  static int openall_before_chroot = -1;
1654 
1655  if (openall_before_chroot < 0)
1656  openall_before_chroot = rpmExpandNumeric("%{?_openall_before_chroot}");
1657 
1658  xx = Chdir("/");
1659  /*@-modobserver@*/
1660  if (rootDir != NULL && strcmp(rootDir, "/") && *rootDir == '/') {
1661  if (openall_before_chroot)
1662  xx = rpmdbOpenAll(rpmtsGetRdb(ts));
1663  xx = Chroot(rootDir);
1664  }
1665  /*@=modobserver@*/
1666  (void) rpmtsSetChrootDone(ts, 1);
1667  }
1668 
1669  ts->ht = htCreate(fileCount/2 + 1, 0, 1, fpHashFunction, fpEqual);
1670  fpc = fpCacheCreate(fileCount/2 + 10001);
1671 
1672 #endif /* REFERENCE */
1673 
1674  ptr = rpmtsNotify(ts, NULL, RPMCALLBACK_TRANS_START, 6, ts->orderCount);
1675 
1676  /* ===============================================
1677  * Add fingerprint for each file not skipped.
1678  */
1679 #ifdef REFERENCE
1680  rpmtsAddFingerprints(ts, fileCount, ht, fpc);
1681 #else /* REFERENCE */
1682  rpmtsAddFingerprints(ts, fileCount, ts->ht, fpc);
1683 #endif /* REFERENCE */
1684 
1685  /* ===============================================
1686  * Compute file disposition for each package in transaction set.
1687  */
1688 #ifdef REFERENCE
1689  rpmtsCheckInstalledFiles(ts, fileCount, ht, fpc);
1690 #else /* REFERENCE */
1691  rc = rpmtsCheckInstalledFiles(ts, fileCount, ts->ht, fpc);
1692  if (rc)
1693  goto exit;
1694 #endif /* REFERENCE */
1695 
1696  pi = rpmtsiInit(ts);
1697  while ((p = rpmtsiNext(pi, (rpmElementType) 0)) != NULL) {
1698  if ((fi = rpmteFI(p, RPMTAG_BASENAMES)) == NULL)
1699  continue; /* XXX can't happen */
1700  /* XXX Set all SRPM files to FA_CREATE. */
1701  if (p->isSource) {
1702  int i;
1703  fi = rpmfiInit(fi, 0);
1704  if (fi != NULL)
1705  while ((i = rpmfiNext(fi)) >= 0)
1706  fi->actions[i] = FA_CREATE;
1707  continue;
1708  }
1709 
1710  (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_FINGERPRINT), 0);
1711 
1712  /* Update disk space needs on each partition for this package. */
1713 /*@-nullpass@*/
1714 #ifdef REFERENCE
1715  handleOverlappedFiles(ts, ht, p, fi);
1716 #else /* REFERENCE */
1717  handleOverlappedFiles(ts, p, fi);
1718 #endif /* REFERENCE */
1719 /*@=nullpass@*/
1720 
1721  /* Check added package has sufficient space on each partition used. */
1722  switch (rpmteType(p)) {
1723  case TR_ADDED:
1724  rpmtsCheckDSIProblems(ts, p);
1725  /*@switchbreak@*/ break;
1726  case TR_REMOVED:
1727  /*@switchbreak@*/ break;
1728  }
1729  (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_FINGERPRINT), rpmfiFC(fi));
1730  }
1731  pi = rpmtsiFree(pi);
1732 
1733  if (rpmtsChrootDone(ts)) {
1734  const char * rootDir = rpmtsRootDir(ts);
1735  const char * currDir = rpmtsCurrDir(ts);
1736  /*@-modobserver@*/
1737  if (rootDir != NULL && strcmp(rootDir, "/") && *rootDir == '/')
1738  xx = Chroot(".");
1739  /*@=modobserver@*/
1740  (void) rpmtsSetChrootDone(ts, 0);
1741  if (currDir != NULL)
1742  xx = Chdir(currDir);
1743  }
1744 
1745  ptr = rpmtsNotify(ts, NULL, RPMCALLBACK_TRANS_STOP, 6, ts->orderCount);
1746 
1747  /* ===============================================
1748  * Free unused memory as soon as possible.
1749  */
1750 #ifdef REFERENCE
1751  pi = rpmtsiInit(ts);
1752  while ((p = rpmtsiNext(pi, (rpmElementType) 0)) != NULL) {
1753  rpmteSetFI(p, NULL);
1754  }
1755  pi = rpmtsiFree(pi);
1756 #else /* REFERENCE */
1757  pi = rpmtsiInit(ts);
1758  while ((p = rpmtsiNext(pi, (rpmElementType) 0)) != NULL) {
1759  if (p->isSource) continue;
1760  if ((fi = rpmtsiFi(pi)) == NULL)
1761  continue; /* XXX can't happen */
1762  if (rpmfiFC(fi) == 0)
1763  continue;
1764  fi->fps = _free(fi->fps);
1765  }
1766  pi = rpmtsiFree(pi);
1767 #endif /* REFERENCE */
1768 
1769 exit:
1770 #ifdef REFERENCE
1771  ht = rpmFpHashFree(ht);
1772 #else /* REFERENCE */
1773  ts->ht = htFree(ts->ht);
1774 #endif /* REFERENCE */
1775  fpc = fpCacheFree(fpc);
1776 
1777  return rc;
1778 }
1779 
1780 /*
1781  * Transaction main loop: install and remove packages
1782  */
1783 static int rpmtsProcess(rpmts ts, rpmprobFilterFlags ignoreSet,
1784  int rollbackFailures)
1785  /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
1786  /*@modifies ts, rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
1787 {
1788  rpmtsi pi;
1789  rpmte p;
1790  int rc = 0;
1791 
1792 FPSDEBUG(0, (stderr, "--> %s(%p,0x%x,%d)\n", __FUNCTION__, ts, ignoreSet, rollbackFailures));
1793  pi = rpmtsiInit(ts);
1794  while ((p = rpmtsiNext(pi, (rpmElementType) 0)) != NULL) {
1795  rpmfi fi;
1796  rpmop sw;
1797  rpmpsm psm = NULL;
1798  pkgStage stage = PSM_UNKNOWN;
1799  int failed;
1800  int gotfd;
1801  int xx;
1802 
1803 #ifdef REFERENCE
1804  rpmElementType tetype = rpmteType(p);
1805  rpmtsOpX op = (tetype == TR_ADDED) ? RPMTS_OP_INSTALL : RPMTS_OP_ERASE;
1806 #endif /* REFERENCE */
1807 
1808  (void) rpmdbCheckSignals();
1809 
1810  failed = 1;
1811  gotfd = 0;
1812  if ((fi = rpmtsiFi(pi)) == NULL)
1813  continue; /* XXX can't happen */
1814 
1815  if (rpmteFailed(p)) {
1816  /* XXX this should be a warning, need a better message though */
1817  rpmlog(RPMLOG_DEBUG, D_("element %s marked as failed, skipping\n"),
1818  rpmteNEVRA(p));
1819  rc++;
1820  continue;
1821  }
1822 
1823  psm = rpmpsmNew(ts, p, fi);
1824  { int async = (rpmtsiOc(pi) >= rpmtsUnorderedSuccessors(ts, -1)) ?
1825  1 : 0;
1826  rpmpsmSetAsync(psm, async);
1827  }
1828 
1829  switch (rpmteType(p)) {
1830  case TR_ADDED:
1831  rpmlog(RPMLOG_DEBUG, "========== +++ %s %s-%s 0x%x\n",
1832  rpmteNEVR(p), rpmteA(p), rpmteO(p), rpmteColor(p));
1833  stage = PSM_PKGINSTALL;
1834  sw = rpmtsOp(ts, RPMTS_OP_INSTALL);
1835 #ifdef REFERENCE
1836  if (rpmteOpen(p, ts, 1)) {
1837  (void) rpmswEnter(rpmtsOp(ts, op), 0);
1838  failed = rpmpsmStage(psm, stage);
1839  (void) rpmswExit(rpmtsOp(ts, op), 0);
1840  rpmteClose(p, ts, 1);
1841  }
1842 #else /* REFERENCE */
1843  if ((p->h = rpmteFDHeader(ts, p)) != NULL)
1844  gotfd = 1;
1845 
1846  if (gotfd && rpmteFd(p) != NULL) {
1847  /*
1848  * XXX Sludge necessary to transfer existing fstates/actions
1849  * XXX around a recreated file info set.
1850  */
1851  rpmuint8_t * fstates = fi->fstates;
1852  iosmFileAction * actions = (iosmFileAction *) fi->actions;
1853  int mapflags = fi->mapflags;
1854  rpmte savep;
1855  int scareMem = 0;
1856 
1857  psm->fi = rpmfiFree(psm->fi);
1858 
1859  fi->fstates = NULL;
1860  fi->actions = NULL;
1861 /*@-nullstate@*/ /* FIX: fi->actions is NULL */
1862  fi = rpmfiFree(fi);
1863 /*@=nullstate@*/
1864 
1865  savep = rpmtsSetRelocateElement(ts, p);
1866  fi = rpmfiNew(ts, p->h, RPMTAG_BASENAMES, scareMem);
1867  (void) rpmtsSetRelocateElement(ts, savep);
1868 
1869  if (fi != NULL) { /* XXX can't happen */
1870  fi->te = p;
1871  fi->fstates = _free(fi->fstates);
1872  fi->fstates = fstates;
1873  fi->actions = _free(fi->actions);
1874  fi->actions = (int *) actions;
1875  if (mapflags & IOSM_SBIT_CHECK)
1876  fi->mapflags |= IOSM_SBIT_CHECK;
1877  p->fi = fi;
1878  }
1879 
1880  psm->fi = rpmfiLink(p->fi, __FUNCTION__);
1881 
1882  (void) rpmswEnter(sw, 0);
1883  failed = (rpmpsmStage(psm, stage) != RPMRC_OK);
1884  (void) rpmswExit(sw, 0);
1885 
1886  xx = rpmteClose(p, ts, 0);
1887  gotfd = 0;
1888  }
1889 
1890 #endif /* REFERENCE */
1891  /*@switchbreak@*/ break;
1892 
1893  case TR_REMOVED:
1894  rpmlog(RPMLOG_DEBUG, "========== --- %s %s-%s 0x%x\n",
1895  rpmteNEVR(p), rpmteA(p), rpmteO(p), rpmteColor(p));
1896  stage = PSM_PKGERASE;
1897  sw = rpmtsOp(ts, RPMTS_OP_ERASE);
1898 #ifdef REFERENCE
1899  if (rpmteOpen(p, ts, 1)) {
1900  (void) rpmswEnter(rpmtsOp(ts, op), 0);
1901  failed = rpmpsmStage(psm, stage);
1902  (void) rpmswExit(rpmtsOp(ts, op), 0);
1903  rpmteClose(p, ts, 1);
1904  }
1905 #else /* REFERENCE */
1906  (void) rpmswEnter(sw, 0);
1907  failed = (rpmpsmStage(psm, stage) != RPMRC_OK);
1908  (void) rpmswExit(sw, 0);
1909 #endif /* REFERENCE */
1910  /*@switchbreak@*/ break;
1911  }
1912 
1913 #if defined(RPM_VENDOR_MANDRIVA)
1914  { rpmtransFlags tsflags = rpmtsFlags(ts);
1915  if (!failed && !TSF_ISSET(tsflags, TEST)) {
1916  if(!rpmteIsSource(p))
1917  xx = mayAddToFilesAwaitingFiletriggers(rpmtsRootDir(ts),
1918  fi, (rpmteType(p) == TR_ADDED ? 1 : 0));
1919  p->done = 1;
1920  }
1921  }
1922 #endif
1923 
1924 /*@-nullstate@*/ /* FIX: psm->fi may be NULL */
1925  psm = rpmpsmFree(psm, __FUNCTION__);
1926 /*@=nullstate@*/
1927 
1928  if (failed) {
1929  rc++;
1930 #ifdef REFERENCE
1931  rpmteMarkFailed(p, ts);
1932 #else /* REFERENCE */
1933  xx = rpmtsMarkLinkedFailed(ts, p);
1934  /* If we received an error, lets break out and rollback, provided
1935  * autorollback is enabled.
1936  */
1937  if (rollbackFailures) {
1938  xx = rpmtsRollback(ts, ignoreSet, 1, p);
1939  break;
1940  }
1941 #endif /* REFERENCE */
1942  }
1943 
1944  if (p->h != NULL) {
1945  (void) headerFree(p->h);
1946  p->h = NULL;
1947  }
1948 
1949 #ifdef REFERENCE
1950  (void) rpmdbSync(rpmtsGetRdb(ts));
1951 #endif /* REFERENCE */
1952 
1953  }
1954  pi = rpmtsiFree(pi);
1955  return rc;
1956 }
1957 
1958 /* ================================================================= */
1959 static int rpmtsRepackage(rpmts ts, uint32_t numRemoved)
1960  /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
1961  /*@modifies ts, rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
1962 {
1963  rpmtransFlags tsflags = rpmtsFlags(ts);
1964  rpmpsm psm;
1965  rpmfi fi;
1966  rpmtsi pi;
1967  rpmte p;
1968  void * ptr;
1969  int progress = 0;
1970  int rc = 0;
1971  int xx;
1972 
1973 FPSDEBUG(0, (stderr, "--> %s(%p,%u)\n", __FUNCTION__, ts, (unsigned)numRemoved));
1974  pi = rpmtsiInit(ts);
1975  while ((p = rpmtsiNext(pi, (rpmElementType) 0)) != NULL) {
1976 
1977  (void) rpmdbCheckSignals();
1978 
1979  if (p->isSource) continue;
1980  if ((fi = rpmtsiFi(pi)) == NULL)
1981  continue; /* XXX can't happen */
1982  switch (rpmteType(p)) {
1983  case TR_ADDED:
1984  /*@switchbreak@*/ break;
1985  case TR_REMOVED:
1986  if (!TSF_ISSET(tsflags, REPACKAGE))
1987  /*@switchbreak@*/ break;
1988  if (!progress)
1989  ptr = rpmtsNotify(ts, NULL, RPMCALLBACK_REPACKAGE_START,
1990  7, numRemoved);
1991 
1993  progress, numRemoved);
1994  progress++;
1995 
1996  (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_REPACKAGE), 0);
1997 
1998  /* XXX TR_REMOVED needs IOSM_MAP_{ABSOLUTE,ADDDOT} IOSM_ALL_HARDLINKS */
1999  fi->mapflags |= IOSM_MAP_ABSOLUTE;
2000  fi->mapflags |= IOSM_MAP_ADDDOT;
2001  fi->mapflags |= IOSM_ALL_HARDLINKS;
2002  psm = rpmpsmNew(ts, p, fi);
2003 assert(psm != NULL);
2004  xx = rpmpsmStage(psm, PSM_PKGSAVE);
2005  psm = rpmpsmFree(psm, __FUNCTION__);
2006  fi->mapflags &= ~IOSM_MAP_ABSOLUTE;
2007  fi->mapflags &= ~IOSM_MAP_ADDDOT;
2008  fi->mapflags &= ~IOSM_ALL_HARDLINKS;
2009 
2010  (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_REPACKAGE), 0);
2011 
2012  /*@switchbreak@*/ break;
2013  }
2014  }
2015  pi = rpmtsiFree(pi);
2016  if (progress)
2017  ptr = rpmtsNotify(ts, NULL, RPMCALLBACK_REPACKAGE_STOP, 7, numRemoved);
2018 
2019  return rc;
2020 }
2021 
2028 /*@-nullpass@*/
2030  /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
2031  /*@modifies ts, p, rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
2032 {
2033  int rc = RPMRC_OK; /* assume success */
2034 
2035 FPSDEBUG(0, (stderr, "--> %s(%p,%p)\n", __FUNCTION__, ts, p));
2036  /* Handle failed packages. */
2037  /* XXX TODO: Add header to rpmdb in PSM_INIT, not PSM_POST. */
2038  if (p != NULL && rpmteType(p) == TR_ADDED && !p->installed) {
2039 /*@-compdef -usereleased@*/ /* p->fi->te undefined */
2040  rpmpsm psm = rpmpsmNew(ts, p, p->fi);
2041 /*@=compdef =usereleased@*/
2042  /*
2043  * If it died before the header was put in the rpmdb, we need
2044  * do to something wacky which is add the header to the DB anyway.
2045  * This will allow us to add the failed package as an erase
2046  * to the rollback transaction. This must be done because we
2047  * want the the erase scriptlets to run, and the only way that
2048  * is going is if the header is in the rpmdb.
2049  */
2050 assert(psm != NULL);
2051  psm->stepName = "failed"; /* XXX W2DO? */
2052  rc = rpmpsmStage(psm, PSM_RPMDB_ADD);
2053  psm = rpmpsmFree(psm, __FUNCTION__);
2054  }
2055  return (rpmRC) rc;
2056 }
2057 /*@=nullpass@*/
2058 
2059 /*@-nullpass@*/
2060 rpmRC rpmtsRollback(rpmts rbts, rpmprobFilterFlags ignoreSet, int running, rpmte rbte)
2061  /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
2062  /*@modifies rbts, rpmGlobalMacroContext, fileSystem, internalState @*/
2063 {
2064  const char * semfn = NULL;
2065  rpmRC rc = (rpmRC) 0;
2066  rpmuint32_t arbgoal = rpmtsARBGoal(rbts);
2067  QVA_t ia = (QVA_t) memset(alloca(sizeof(*ia)), 0, sizeof(*ia));
2068  time_t ttid;
2069  int xx;
2070 
2071 FPSDEBUG(0, (stderr, "--> %s(%p,0x%x,%d,%p)\n", __FUNCTION__, rbts, ignoreSet, running, rbte));
2072  /* Don't attempt rollback's of rollback transactions */
2073  if ((rpmtsType(rbts) & RPMTRANS_TYPE_ROLLBACK) ||
2075  return RPMRC_OK;
2076 
2077  if (arbgoal == 0xffffffff)
2078  arbgoal = rpmtsGetTid(rbts);
2079 
2080  /* Don't attempt rollbacks if no goal is set. */
2081  if (!running && arbgoal == 0xffffffff)
2082  return RPMRC_OK;
2083 
2084  /* We need to remove an headers that were going to be removed so
2085  * as to not foul up the regular rollback mechanism which will not
2086  * handle properly a file being in the repackaged package directory
2087  * and also its header still in the DB.
2088  */
2089  { rpmtsi tsi;
2090  rpmte te;
2091 
2092  /* XXX Insure an O_RDWR rpmdb. */
2093  xx = rpmtsOpenDB(rbts, O_RDWR);
2094 
2095  tsi = rpmtsiInit(rbts);
2096  while((te = rpmtsiNext(tsi, TR_REMOVED)) != NULL) {
2097  if (te->isSource) continue;
2098  if(!te->u.removed.dboffset)
2099  continue;
2100  rc = (rpmRC) rpmdbRemove(rpmtsGetRdb(rbts),
2101  rpmtsGetTid(rbts),
2102  te->u.removed.dboffset, NULL);
2103  if (rc != RPMRC_OK) {
2104  rpmlog(RPMLOG_ERR, _("rpmdb erase failed. NEVRA: %s\n"),
2105  rpmteNEVRA(te));
2106  break;
2107  }
2108  }
2109  tsi = rpmtsiFree(tsi);
2110  if (rc != RPMRC_OK)
2111  goto cleanup;
2112  }
2113 
2114  /* Process the failed package */
2115  rc = _processFailedPackage(rbts, rbte);
2116  if (rc != RPMRC_OK)
2117  goto cleanup;
2118 
2119  rpmtsEmpty(rbts);
2120 
2121  ttid = (time_t)arbgoal;
2122  rpmlog(RPMLOG_NOTICE, _("Rollback to %-24.24s (0x%08x)\n"),
2123  ctime(&ttid), arbgoal);
2124 
2125  /* Set the verify signature flags:
2126  * - can't verify signatures/digests on repackaged packages.
2127  * - header check are out.
2128  */
2129  {
2130  rpmVSFlags vsflags = (rpmVSFlags) rpmExpandNumeric("%{?_vsflags_erase}");
2131  vsflags = (rpmVSFlags) 0; /* XXX FIXME: ignore default disablers. */
2132 #if defined(SUPPORT_NOSIGNATURES)
2133  /* --nodigest */
2134  VSF_SET(vsflags, NOSHA1HEADER);
2135  VSF_SET(vsflags, NOMD5HEADER);
2136  VSF_SET(vsflags, NOSHA1);
2137  VSF_SET(vsflags, NOMD5);
2138  /* --nosignature */
2139  VSF_SET(vsflags, NODSAHEADER);
2140  VSF_SET(vsflags, NORSAHEADER);
2141  VSF_SET(vsflags, NODSA);
2142  VSF_SET(vsflags, NORSA);
2143  /* --nohdrchk */
2144  VSF_SET(vsflags, NOHDRCHK);
2145  VSF_SET(vsflags, NEEDPAYLOAD); /* XXX needed? */
2146 #endif
2147  xx = rpmtsSetVSFlags(rbts, vsflags);
2148  }
2149 
2150  /* Set transaction flags to be the same as the running transaction */
2151  {
2152  rpmtransFlags tsflags = rpmtsFlags(rbts);
2153  TSF_CLR(tsflags, DIRSTASH); /* No repackage of rollbacks */
2154  TSF_CLR(tsflags, REPACKAGE); /* No repackage of rollbacks */
2155  TSF_SET(tsflags, NOFDIGESTS); /* Don't check file digests */
2156  tsflags = rpmtsSetFlags(rbts, tsflags);
2157  }
2158 
2159  /* Create install arguments structure */
2160  ia->rbtid = arbgoal;
2161  /* transFlags/depFlags from rbts, (re-)set in rpmRollback(). */
2162  ia->transFlags = rpmtsFlags(rbts);
2163  ia->depFlags = rpmtsDFlags(rbts);
2164  /* XXX probFilter is normally set in main(). */
2165  ia->probFilter = ignoreSet; /* XXX RPMPROB_FILTER_NONE? */
2166  /* XXX installInterfaceFlags is normally set in main(). */
2167  IIF_SET(ia->installInterfaceFlags, UPGRADE);
2168  IIF_SET(ia->installInterfaceFlags, HASH);
2169 
2170  /* rpmtsCheck and rpmtsOrder failures do not have links. */
2171  ia->no_rollback_links = 1;
2172 
2173  /* Create a file semaphore. */
2174  semfn = rpmExpand("%{?semaphore_backout}", NULL);
2175  if (semfn && *semfn) {
2176  FD_t fd = Fopen(semfn, "w.fdio");
2177  if (fd)
2178  xx = Fclose(fd);
2179  }
2180 
2181 /*@-compmempass@*/
2182  rc = (rpmRC) rpmRollback(rbts, ia, NULL);
2183 /*@=compmempass@*/
2184 
2185 cleanup:
2186  /* Remove the file semaphore. */
2187  if (semfn && *semfn)
2188  xx = Unlink(semfn);
2189  semfn = _free(semfn);
2190 
2191  return rc;
2192 }
2193 /*@=nullpass@*/
2194 
2195 int _rpmtsRun(rpmts ts, rpmps okProbs, rpmprobFilterFlags ignoreSet)
2196 {
2197  rpmtransFlags tsflags = rpmtsFlags(ts);
2198  int ourrc = -1; /* assume failure */
2199  uint32_t totalFileCount = 0;
2200  rpmps ps;
2201  rpmsx sx = NULL;
2202  uint32_t numRemoved;
2203  int rollbackFailures = 0;
2204  void * lock = NULL;
2205  int xx;
2206 
2207 FPSDEBUG(0, (stderr, "--> %s(%p,%p,0x%x)\n", __FUNCTION__, ts, okProbs, ignoreSet));
2208 if (_rpmts_debug)
2209 fprintf(stderr, "--> %s(%p,%p,0x%x) tsflags 0x%x\n", __FUNCTION__, ts, okProbs, (unsigned) ignoreSet, tsflags);
2210 
2211  /* XXX programmer error segfault avoidance. */
2212  if (rpmtsNElements(ts) <= 0) {
2214  _("Invalid number of transaction elements.\n"));
2215  return -1;
2216  }
2217 
2218  /* Don't acquire the transaction lock if testing. */
2219  if (!TSF_ISSET(tsflags, TEST))
2220  lock = rpmtsAcquireLock(ts);
2221 
2222  rollbackFailures = rpmExpandNumeric("%{?_rollback_transaction_on_failure}");
2223  /* Don't rollback unless repackaging. */
2224  if (!TSF_ISSET(tsflags, REPACKAGE))
2225  rollbackFailures = 0;
2226  /* Don't rollback if testing. */
2227  if (TSF_ISSET(tsflags, TEST))
2228  rollbackFailures = 0;
2229 
2231  rollbackFailures = 0;
2232 
2233  /* ===============================================
2234  * Setup flags and such, open the rpmdb in O_RDWR mode.
2235  */
2236  sx = NULL;
2237  if (rpmtsSetup(ts, ignoreSet, &sx))
2238  goto exit;
2239 
2240  /* ===============================================
2241  * For packages being installed:
2242  * - verify package epoch:version-release is newer.
2243  * - count files.
2244  * For packages being removed:
2245  * - count files.
2246  */
2247 
2248  totalFileCount = 0;
2249  ps = rpmtsSanityCheck(ts, &totalFileCount);
2250  ps = rpmpsFree(ps);
2251 
2252  /* ===============================================
2253  * Run pre-transaction scripts, but only if no known problems exist.
2254  */
2255  if (!TSF_ISSET(tsflags, NOPRETRANS) &&
2256  (!(TSF_ISSET(tsflags, BUILD_PROBS) || TSF_ISSET(tsflags, TEST))
2257  || (rpmpsNumProblems(ts->probs) &&
2258  (okProbs == NULL || rpmpsTrim(ts->probs, okProbs)))))
2259  {
2260  rpmlog(RPMLOG_DEBUG, D_("running pre-transaction scripts\n"));
2261  xx = rpmtsRunScript(ts, RPMTAG_PRETRANS);
2262 
2263  /* Run *after* pre-transaction scripts so that they may perform
2264  * any changes affecting pre-transaction triggers first if necessary.
2265  */
2266  rpmlog(RPMLOG_DEBUG, D_("running pre-transaction triggers\n"));
2269  }
2270 
2271  /* ===============================================
2272  * Compute file disposition for each package in transaction set.
2273  */
2274  numRemoved = 0;
2275  if (rpmtsPrepare(ts, sx, totalFileCount, &numRemoved))
2276  goto exit;
2277 
2278  /* ===============================================
2279  * If unfiltered problems exist, free memory and return.
2280  */
2281  if (TSF_ISSET(tsflags, BUILD_PROBS)
2282  || (rpmpsNumProblems(ts->probs) &&
2283  (okProbs == NULL || rpmpsTrim(ts->probs, okProbs)))
2284  )
2285  {
2286  lock = rpmtsFreeLock(lock);
2287  if (sx != NULL) sx = rpmsxFree(sx);
2288  return ts->orderCount;
2289  }
2290 
2291  /* ===============================================
2292  * Save removed files before erasing (w/o --justdb).
2293  */
2294  if ((TSF_ISSET(tsflags, DIRSTASH) || TSF_ISSET(tsflags, REPACKAGE))
2295  && !TSF_ISSET(tsflags, JUSTDB))
2296  {
2297  xx = rpmtsRepackage(ts, numRemoved);
2298  }
2299 
2300 #ifdef NOTYET
2301  xx = rpmtxnBegin(rpmtsGetRdb(ts), NULL, &ts->txn);
2302 #endif
2303 
2304  /* ===============================================
2305  * Install and remove packages.
2306  */
2307  ourrc = rpmtsProcess(ts, ignoreSet, rollbackFailures);
2308 
2309  /* ===============================================
2310  * Run post-transaction scripts unless disabled.
2311  */
2312  if (!TSF_ISSET(tsflags, NOPOSTTRANS) && !TSF_ISSET(tsflags, TEST))
2313  {
2314 
2315 #if defined(RPM_VENDOR_MANDRIVA)
2316  /* XXX FIXME: simplify the logic. */
2317  if (!TSF_ISSET(tsflags, NOTRIGGERPREIN)
2318  || !TSF_ISSET(tsflags, NOTRIGGERIN)
2319  || !TSF_ISSET(tsflags, NOTRIGGERUN)
2320  || !TSF_ISSET(tsflags, NOTRIGGERPOSTUN))
2321  rpmRunFileTriggers(rpmtsRootDir(ts));
2322 #endif
2323 
2324  rpmlog(RPMLOG_DEBUG, D_("running post-transaction scripts\n"));
2325  xx = rpmtsRunScript(ts, RPMTAG_POSTTRANS);
2326 
2327  rpmlog(RPMLOG_DEBUG, D_("running post-transaction triggers\n"));
2330  }
2331 
2332 exit:
2333  xx = rpmtsFinish(ts, sx);
2334 
2335  lock = rpmtsFreeLock(lock);
2336 
2337  /*@-nullstate@*/ /* FIX: ts->flList may be NULL */
2338  if (ourrc) {
2339  if (ts->txn != NULL)
2340  xx = rpmtxnAbort(ts->txn);
2341  ts->txn = NULL;
2342  return -1;
2343  } else {
2344  if (ts->txn != NULL)
2345  xx = rpmtxnCommit(ts->txn);
2346  ts->txn = NULL;
2347  xx = rpmtxnCheckpoint(rpmtsGetRdb(ts));
2348  return 0;
2349  }
2350  /*@=nullstate@*/
2351 }
2352 
2353 int (*rpmtsRun) (rpmts ts, rpmps okProbs, rpmprobFilterFlags ignoreSet)
2354  = _rpmtsRun;
rpmuint32_t rpmfiFFlags(rpmfi fi)
Return current file flags from file info set.
Definition: rpmfi.c:217
rpmds rpmdsSingle(rpmTag tagN, const char *N, const char *EVR, evrFlags Flags)
Create, load and initialize a dependency set of size 1.
Definition: rpmds.c:609
Definition: iosm.h:34
struct rpmpsi_s * rpmpsi
Definition: rpmps.h:26
int rpmdbOpenAll(rpmdb db)
Open all database indices.
Definition: rpmdb.c:787
fingerPrint fpLookup(fingerPrintCache cache, const char *dirName, const char *baseName, int scareMem)
Return finger print of a file path.
Definition: fprint.c:190
const char * str
Definition: rpmtag.h:72
rpmTag tag
Definition: rpmtag.h:504
int rpmteClose(rpmte te, rpmts ts, int reset_fi)
Definition: rpmte.c:922
static int rpmtsPrepare(rpmts ts, rpmsx sx, uint32_t fileCount, uint32_t *nrmvdp)
Definition: transaction.c:1561
FD_t rpmteFd(rpmte te)
Retrieve file handle from transaction element.
Definition: rpmte.c:561
const char ** argv
Definition: rpmtag.h:74
rpmdepFlags depFlags
Definition: rpmcli.h:675
int rpmmiGrowBasename(rpmmi mi, const char *bn)
Append packages containing common basename to iterator.
Definition: rpmdb.c:1491
rpmuint32_t rpmteColor(rpmte te)
Retrieve color bits of transaction element.
Definition: rpmte.c:360
rpmtime_t rpmswExit(rpmop op, ssize_t rc)
Exit timed operation.
Definition: rpmsw.c:264
int rpmfiDX(rpmfi fi)
Return current directory index from file info set.
Definition: rpmfi.c:120
int rpmteOpen(rpmte te, rpmts ts, int reload_fi)
Definition: rpmte.c:880
static int rpmtsCheckInstalledFiles(rpmts ts, uint32_t fileCount, hashTable ht, fingerPrintCache fpc)
Definition: transaction.c:975
Header rpmteFDHeader(rpmts ts, rpmte te)
Definition: rpmte.c:856
void * rpmtsNotify(rpmts ts, rpmte te, rpmCallbackType what, rpmuint64_t amount, rpmuint64_t total)
Perform transaction progress notify callback.
Definition: rpmts.c:1291
static int rpmtsProcess(rpmts ts, rpmprobFilterFlags ignoreSet, int rollbackFailures)
Definition: transaction.c:1783
void rpmfiFpLookup(rpmfi fi, fingerPrintCache fpc)
Definition: rpmfi.c:518
rpmProblem rpmpsGetProblem(rpmps ps, int num)
Return a problem from problem set.
Definition: rpmps.c:386
const char * baseName
Definition: fprint.h:57
const char * rpmtsRootDir(rpmts ts)
Get transaction rootDir, i.e.
Definition: rpmts.c:901
rpmte rpmtsElement(rpmts ts, int ix)
Return (ordered) transaction set element.
Definition: rpmts.c:1327
void rpmpsAppend(rpmps ps, rpmProblemType type, const char *pkgNEVR, fnpyKey key, const char *dn, const char *bn, const char *altNEVR, rpmuint64_t ulong1)
Append a problem to current set of problems.
Definition: rpmps.c:123
enum iosmFileAction_e iosmFileAction
File disposition(s) during package install/erase processing.
#define TSF_ISSET(_tsflags, _FLAG)
Definition: transaction.c:108
int Chroot(const char *path)
chroot(2) clone.
Definition: rpmrpc.c:176
uint32_t rpmmiInstance(rpmmi mi)
Return header instance for current position of rpmdb iterator.
Definition: rpmdb.c:1743
Structures used for an "rpmte" transaction element.
static int cmpArgvStr(const char **AV, const char *B)
Search for string B in argv array AV.
Definition: transaction.c:845
rpmuint32_t * ui32p
Definition: rpmtag.h:69
FD_t Fopen(const char *path, const char *_fmode)
fopen(3) clone.
Definition: rpmio.c:2833
Structure(s) used for file info tag sets.
enum rpmprobFilterFlags_e rpmprobFilterFlags
int headerGet(Header h, HE_t he, unsigned int flags)
Retrieve extension or tag value from a header.
Definition: header.c:2222
rpmpsi rpmpsFreeIterator(rpmpsi psi)
Destroy problem set iterator.
Definition: rpmps.c:91
#define TSF_SET(_tsflags, _FLAG)
Definition: transaction.c:109
rpmsx rpmsxFree(rpmsx sx)
Destroy a SELinux wrapper.
The Header data structure.
const char * rpmteN(rpmte te)
Retrieve name string of transaction element.
Definition: rpmte.c:316
rpmuint32_t fpHashFunction(rpmuint32_t h, const void *data, size_t size)
Definition: fprint.c:196
rpmRC rpmtsRollback(rpmts rbts, rpmprobFilterFlags ignoreSet, int running, rpmte rbte)
Rollback a failed transaction.
Definition: transaction.c:2060
static rpmlogRec recs
Definition: rpmlog.c:21
int rpmfiSetFX(rpmfi fi, int fx)
Set current file index in file info set.
Definition: rpmfi.c:108
struct rpmpsm_s * rpmpsm
Package state machine data.
Definition: psm.h:13
static rpmVSFlags vsflags
Definition: rpmcache.c:547
Definition: rpmdb.c:436
rpmfi rpmfiFree(rpmfi fi)
Destroy a file info set.
rpmop rpmtsOp(rpmts ts, rpmtsOpX opx)
Retrieve operation timestamp from a transaction set.
Definition: pkgio.c:133
const char * rpmfiFN(rpmfi fi)
Return current file name from file info set.
Definition: rpmfi.c:163
int rpmdbCheckSignals(void)
Check for and exit on termination signals.
Definition: rpmdb.c:523
unsigned short rpmuint16_t
Definition: rpmiotypes.h:24
int rpmfiDecideFate(const rpmfi ofi, rpmfi nfi, int skipMissing)
Return file disposition.
Definition: rpmfi.c:671
enum rpmtsOpX_e rpmtsOpX
Indices for timestamps.
int dodigest(int dalgo, const char *fn, unsigned char *digest, unsigned dflags, size_t *fsizep)
Return digest and size of a file.
Definition: legacy.c:178
int rpmtsSetChrootDone(rpmts ts, int chrootDone)
Set chrootDone flag, i.e.
Definition: rpmts.c:1010
rpmtsi rpmtsiFree(rpmtsi tsi)
Destroy transaction element iterator.
struct rpmtsi_s * rpmtsi
Transaction element iterator.
Definition: rpmte.h:25
int _rpmtsRun(rpmts ts, rpmps okProbs, rpmprobFilterFlags ignoreSet)
Definition: transaction.c:2195
rpmTSType rpmtsType(rpmts ts)
Return the type of a transaction.
Definition: rpmts.c:868
static void rpmlog(int code, const char *fmt,...)
Definition: rpmlog.h:299
struct rpmps_s * rpmps
Transaction problems found while processing a transaction set/.
Definition: rpmps.h:22
rpmElementType rpmteType(rpmte te)
Retrieve type of transaction element.
Definition: rpmte.c:311
fingerPrintCache fpCacheFree(fingerPrintCache cache)
Destroy finger print cache.
Definition: fprint.c:31
int rpmdsNVRMatchesDep(const Header h, const rpmds req, int nopromote)
Compare package name-version-release from header with a single dependency.
Definition: rpmds.c:4578
const char * rpmteA(rpmte te)
Retrieve arch string of transaction element.
Definition: rpmte.c:345
rpmfi rpmfiNew(const void *_ts, Header h, rpmTag tagN, int flags)
Create and load a file info set.
Definition: rpmfi.c:1403
struct rpmds_s * rpmds
Dependency tag sets from a header, so that a header can be discarded early.
Definition: rpmtypes.h:28
static int rpmtsRunScript(rpmts ts, rpmTag stag)
Definition: transaction.c:1264
rpmuint32_t rpmfiFColor(rpmfi fi)
Return current file color bits from file info set.
Definition: rpmfi.c:371
int rpmteHaveTransScript(rpmte te, rpmTag tag)
Definition: rpmte.c:950
const char * rpmfiBN(rpmfi fi)
Return current base name from file info set.
Definition: rpmfi.c:141
rpmds rpmdsFree(rpmds ds)
Destroy a dependency set.
Command line option information.
Definition: rpmcli.h:634
int rpmfiFC(rpmfi fi)
Return file count from file info set.
Definition: rpmfi.c:87
rpmuint32_t rpmfiFSize(rpmfi fi)
Return current file size from file info set.
Definition: rpmfi.c:328
int rpmpsTrim(rpmps ps, rpmps filter)
Filter a problem set.
Definition: rpmps.c:166
struct rpmte_s * rpmte
An element of a transaction set, i.e.
Definition: rpmtypes.h:38
const char * rpmteE(rpmte te)
Retrieve epoch string of transaction element.
Definition: rpmte.c:321
rpmmi rpmmiInit(rpmdb db, rpmTag tag, const void *keyp, size_t keylen)
Return database iterator.
Definition: rpmdb.c:2491
int htGetEntry(hashTable ht, const void *key, const void *data, int *dataCount, const void *tableKey)
Retrieve item from hash table.
Definition: rpmhash.c:188
int rpmtsInitDSI(const rpmts ts)
Initialize disk space info for each and every mounted file systems.
Definition: rpmts.c:1065
int rpmpsNumProblems(rpmps ps)
Return number of problems in set.
Definition: rpmps.c:70
const char * rpmtsCurrDir(rpmts ts)
Get transaction currDir, i.e.
Definition: rpmts.c:951
struct fingerPrint_s * rpmfiFpsIndex(rpmfi fi, int ix)
Definition: rpmfi.c:509
enum evrFlags_e evrFlags
Dependency Attributes.
static rpmfi rpmtsiFi(const rpmtsi tsi)
Return transaction element&#39;s file info.
Definition: transaction.c:820
char * alloca()
int _rpmts_debug
Definition: rpmts.c:93
Yet Another syslog(3) API clone.
enum rpmElementType_e rpmElementType
Transaction element type.
int rpmfiNextD(rpmfi fi)
Return next directory iterator index.
Definition: rpmfi.c:562
rpmuint32_t rpmtsSetTid(rpmts ts, rpmuint32_t tid)
Set transaction id, i.e.
Definition: rpmts.c:1031
rpmtransFlags rpmtsSetFlags(rpmts ts, rpmtransFlags transFlags)
Set transaction flags, i.e.
Definition: rpmts.c:1357
unsigned int rpmuint32_t
Definition: rpmiotypes.h:25
struct _HE_s * HE_t
Definition: rpmtag.h:58
const char * rpmteV(rpmte te)
Retrieve version string of transaction element.
Definition: rpmte.c:326
const char * rpmteNEVR(rpmte te)
Retrieve name-version-release string from transaction element.
Definition: rpmte.c:536
void * xcalloc(size_t nmemb, size_t size)
Definition: rpmmalloc.c:301
void * ptr
Definition: rpmtag.h:66
const char * rpmfiDN(rpmfi fi)
Return current directory name from file info set.
Definition: rpmfi.c:152
static int rpmtsRunScriptTriggers(rpmts ts, rpmTag stag)
Definition: transaction.c:1318
int rpmmiSort(rpmmi mi)
Sort iterator instances.
Definition: rpmdb.c:2416
static int rpmtsRepackage(rpmts ts, uint32_t numRemoved)
Definition: transaction.c:1959
rpmfi rpmteFI(rpmte te, rpmTag tag)
Retrieve file info tag set from transaction element.
Definition: rpmte.c:587
char * currentDirectory(void)
Return (malloc&#39;d) current working directory.
Definition: misc.c:72
int rpmpsNextIterator(rpmpsi psi)
Return next problem set iterator index.
Definition: rpmps.c:100
unsigned char rpmuint8_t
Private int typedefs to avoid C99 portability issues.
Definition: rpmiotypes.h:23
struct rpmfi_s * rpmfi
File info tag sets from a header, so that a header can be discarded early.
Definition: rpmfi.h:78
int argvCount(const ARGV_t argv)
Return no.
Definition: argv.c:71
int rpmdbRemove(rpmdb db, int rid, uint32_t hdrNum, rpmts ts)
Remove package header from rpm database and indices.
Definition: rpmdb.c:2773
rpmuint16_t rpmfiFMode(rpmfi fi)
Return current file mode from file info set.
Definition: rpmfi.c:265
rpmTagData p
Definition: rpmtag.h:507
hashTable htFree(hashTable ht)
Destroy hash table.
ARGV_t argvFree(ARGV_t argv)
Destroy an argv array.
Definition: argv.c:44
#define VSF_SET(_vsflags, _FLAG)
Definition: transaction.c:105
int iosmFileActionSkipped(iosmFileAction action)
Is the file going to be skipped?
Definition: iosm.c:2672
int rpmtsNElements(rpmts ts)
Return number of (ordered) transaction set elements.
Definition: rpmts.c:1318
const char * tagName(rpmTag tag)
Return tag name from value.
Definition: tagname.c:436
rpmtransFlags transFlags
Definition: rpmcli.h:676
rpmuint32_t rbtid
Definition: rpmcli.h:680
enum pkgStage_e pkgStage
rpmuint32_t rpmtsPrefColor(rpmts ts)
Retrieve preferred file color.
Definition: rpmts.c:1465
Structure(s) used for dependency tag sets.
static rpmps rpmtsSanityCheck(rpmts ts, uint32_t *tfcp)
Definition: transaction.c:1127
The FD_t File Handle data structure.
rpmmi rpmtsInitIterator(const rpmts ts, rpmTag rpmtag, const void *keyp, size_t keylen)
Return transaction database iterator.
Definition: rpmts.c:212
const char * rpmteD(rpmte te)
Retrieve distepoch string of transaction element.
Definition: rpmte.c:336
rpmpsm rpmpsmNew(rpmts ts, rpmte te, rpmfi fi)
Create and load a package state machine.
Definition: psm.c:2220
int rpmtsChrootDone(rpmts ts)
Get chrootDone flag, i.e.
Definition: rpmts.c:1005
const char * rpmteNEVRA(rpmte te)
Retrieve name-version-release.arch string from transaction element.
Definition: rpmte.c:541
int rpmRollback(rpmts ts, QVA_t ia, const char **argv)
Definition: rpmrollback.c:421
void rpmtsUpdateDSI(const rpmts ts, dev_t dev, rpmuint32_t fileSize, rpmuint32_t prevSize, rpmuint32_t fixupSize, int _action)
Update disk space info for a file.
Definition: rpmts.c:1179
rpmTagCount c
Definition: rpmtag.h:508
int rpmdbMireApply(rpmdb db, rpmTag tag, rpmMireMode mode, const char *pat, const char ***argvp)
Return array of keys matching a pattern.
Definition: rpmdb.c:1482
rpmpsi rpmpsInitIterator(rpmps ps)
Initialize problem set iterator.
Definition: rpmps.c:78
static const char * lang
Definition: iosm.h:32
pgpVSFlags rpmVSFlags
Bit(s) to control digest and signature verification.
Definition: rpmts.h:30
Header headerFree(Header h)
Dereference a header instance.
int rpmswEnter(rpmop op, ssize_t rc)
Enter timed operation.
Definition: rpmsw.c:248
char * rpmExpand(const char *arg,...)
Return (malloc&#39;ed) concatenated macro expansion(s).
Definition: macro.c:3117
int Chdir(const char *path)
chdir(2) clone.
Definition: rpmrpc.c:105
rpmuint32_t rpmtsARBGoal(rpmts ts)
Return the autorollback goal.
Definition: rpmts.c:879
int fpEqual(const void *key1, const void *key2)
Compare two finger print entries.
Definition: fprint.c:212
Identify a file name path by a unique "finger print".
static int rpmtsFinish(rpmts ts, rpmsx sx)
Definition: transaction.c:1547
rpmRC rpmpsmStage(rpmpsm psm, pkgStage stage)
Package state machine driver.
Definition: psm.c:2592
rpmuint8_t * ui8p
Definition: rpmtag.h:67
const char * rpmteO(rpmte te)
Retrieve os string of transaction element.
Definition: rpmte.c:350
static rpmdc dc
Definition: rpmdigest.c:91
void rpmtsSetCurrDir(rpmts ts, const char *currDir)
Set transaction currDir, i.e.
Definition: rpmts.c:960
rpmInstallInterfaceFlags installInterfaceFlags
Definition: rpmcli.h:678
rpmmi rpmmiFree(rpmmi mi)
Destroy rpm database iterator.
static rpmmi rpmtsFindBaseNamesInDB(rpmts ts, uint32_t fileCount)
Definition: transaction.c:909
int Fclose(FD_t fd)
fclose(3) clone.
Definition: rpmio.c:2534
static int rpmtsSetup(rpmts ts, rpmprobFilterFlags ignoreSet, rpmsx *sxp)
Definition: transaction.c:1436
Cumulative statistics for an operation.
Definition: rpmsw.h:33
struct rpmsx_s * rpmsx
Definition: rpmsx.h:11
rpmte rpmtsiNext(rpmtsi tsi, rpmElementType type)
Return next transaction element of type.
Definition: rpmte.c:831
rpmprobFilterFlags probFilter
Definition: rpmcli.h:677
enum rpmfileAttrs_e rpmfileAttrs
File Attributes.
Associates a trailing sub-directory and final base name with an existing directory finger print...
Definition: fprint.h:50
int rpmfiNext(rpmfi fi)
Return next file iterator index.
Definition: rpmfi.c:526
rpmps rpmpsFree(rpmps ps)
Destroy a problem set.
rpmdb rpmtsGetRdb(rpmts ts)
Get transaction set database handle.
Definition: pkgio.c:151
int rpmfiDC(rpmfi fi)
Return directory count from file info set.
Definition: rpmfi.c:92
int rpmtsiOc(rpmtsi tsi)
Return transaction element index.
Definition: rpmte.c:755
fnpyKey rpmteKey(rpmte te)
Retrieve key from transaction element.
Definition: rpmte.c:568
#define IIF_SET(_iflags, _FLAG)
Definition: transaction.c:113
enum rpmRC_e rpmRC
RPM return codes.
void rpmtsCheckDSIProblems(const rpmts ts, const rpmte te)
Check a transaction element for disk space problems.
Definition: rpmts.c:1242
Definition: rpmtag.h:503
static const char * dirName
Definition: parsePrep.c:28
rpmfi rpmfiInit(rpmfi fi, int fx)
Initialize file iterator index.
Definition: rpmfi.c:548
static void rpmtsAddFingerprints(rpmts ts, uint32_t fileCount, hashTable ht, fingerPrintCache fpc)
Definition: transaction.c:1348
rpmuint32_t rpmtsColor(rpmts ts)
Retrieve color bits of transaction set.
Definition: rpmts.c:1450
Definition: rpmte.h:31
void htAddEntry(hashTable ht, const void *key, const void *data)
Add item to hash table.
Definition: rpmhash.c:150
Package state machine to handle a package from a transaction set.
rpmdepFlags rpmtsDFlags(rpmts ts)
Get dependency flags, i.e.
Definition: rpmts.c:1373
static void handleOverlappedFiles(const rpmts ts, const rpmte p, rpmfi fi)
Update disk space needs on each partition for this package&#39;s files.
Definition: transaction.c:239
rpmfi rpmfiLink(rpmfi fi, const char *msg)
Reference a file info set instance.
const struct fprintCacheEntry_s * entry
Definition: fprint.h:52
int _fps_debug
Definition: transaction.c:232
const char * rpmfiFLink(rpmfi fi)
Return current file linkto (i.e.
Definition: rpmfi.c:317
Definition: iosm.h:29
Methods to handle package elements.
rpmte rpmtsSetRelocateElement(rpmts ts, rpmte relocateElement)
Set current relocate transaction element.
Definition: rpmts.c:1411
rpmps rpmtsProblems(rpmts ts)
Return current transaction set problems.
Definition: rpmts.c:582
enum rpmtransFlags_e rpmtransFlags
Bit(s) to control rpmtsRun() operation.
rpmVSFlags rpmtsSetVSFlags(rpmts ts, rpmVSFlags vsflags)
Set verify signatures flag(s).
Definition: rpmts.c:843
struct fprintCache_s * fingerPrintCache
Definition: fprint.h:13
uint32_t rpmmiBNTag(rpmmi mi)
Return basename tag for current position of rpmdb iterator.
Definition: rpmdb.c:1752
char * stpcpy(char *dest, const char *src)
struct rpmts_s * rpmts
The RPM Transaction Set.
Definition: rpmtypes.h:14
struct rpmQVKArguments_s * QVA_t
Definition: rpmcli.h:255
static void * _free(const void *p)
Wrapper to free(3), hides const compilation noise, permit NULL, return NULL.
Definition: rpmiotypes.h:647
int rpmteDBOffset(rpmte te)
Retrieve rpmdb instance of TR_REMOVED transaction element.
Definition: rpmte.c:531
static void rpmtsSkipFiles(const rpmts ts, rpmfi fi)
Skip any files that do not match install policies.
Definition: transaction.c:584
Structures and prototypes used for an "rpmts" transaction set.
Definition: iosm.h:36
Header rpmmiNext(rpmmi mi)
Return next package header from iteration.
Definition: rpmdb.c:2248
rpmfileState rpmfiFState(rpmfi fi)
Return current file state from file info set.
Definition: rpmfi.c:276
rpmfi rpmteSetFI(rpmte te, rpmfi fi)
Definition: rpmte.c:601
File state machine to handle a payload within an rpm package.
rpmfi rpmfiInitD(rpmfi fi, int dx)
Initialize directory iterator index.
Definition: rpmfi.c:582
int no_rollback_links
Definition: rpmcli.h:685
rpmsx rpmsxNew(const char *fn, unsigned int flags)
Create and load a SELinux wrapper.
Definition: rpmsx.c:97
static rpmRC _processFailedPackage(rpmts ts, rpmte p)
Force add a failed package into the rpmdb.
Definition: transaction.c:2029
const unsigned char * rpmfiDigest(rpmfi fi, int *algop, size_t *lenp)
Return current file (binary) digest from file info set.
Definition: rpmfi.c:300
int argvSplit(ARGV_t *argvp, const char *str, const char *seps)
Split a string into an argv array.
Definition: argv.c:233
void fpLookupSubdir(hashTable symlinks, hashTable fphash, fingerPrintCache fpc, void *_p, int filenr)
Check file for to be installed symlinks in their path, correct their fingerprint and add it to newht...
Definition: fprint.c:299
int rpmtsUnorderedSuccessors(rpmts ts, int first)
Set index of 1st element of successors.
Definition: rpmts.c:890
static int rpmtsMarkLinkedFailed(rpmts ts, rpmte p)
Mark all erasure elements linked to installed element p as failed.
Definition: transaction.c:864
int rpmtsOpenDB(rpmts ts, int dbmode)
Open the database used by the transaction.
Definition: rpmts.c:115
int rpmfiCompare(const rpmfi afi, const rpmfi bfi)
Return file info comparison.
Definition: rpmfi.c:637
rpmpsm rpmpsmFree(rpmpsm psm, const char *msg)
Destroy a package state machine.
int _rpmds_nopromote
Definition: rpmds.c:126
rpmuint32_t hashFunctionString(rpmuint32_t h, const void *data, size_t size)
Return hash value of a string.
Definition: rpmhash.c:83
static int ensureOlder(rpmts ts, const rpmte p, const Header h)
Ensure that current package is newer than installed package.
Definition: transaction.c:520
rpmprobFilterFlags rpmtsFilterFlags(rpmts ts)
Get problem ignore bit mask, i.e.
Definition: rpmts.c:1339
#define _(Text)
Definition: system.h:30
int rpmteFailed(rpmte te)
Definition: rpmte.c:945
#define xmalloc
Definition: system.h:33
int rpmtsSELinuxEnabled(rpmts ts)
Get selinuxEnabled flag, i.e.
Definition: rpmts.c:997
rpmuint32_t rpmtsGetTid(rpmts ts)
Get transaction id, i.e.
Definition: rpmts.c:1022
rpmtsi rpmtsiInit(rpmts ts)
Create transaction element iterator.
ARGstr_t * ARGV_t
Definition: argv.h:9
Access RPM indices using Berkeley DB interface(s).
enum rpmTag_e rpmTag
Definition: rpmtag.h:471
#define TSF_CLR(_tsflags, _FLAG)
Definition: transaction.c:110
#define D_(Text)
Definition: system.h:485
static int handleInstInstalledFile(const rpmts ts, rpmte p, rpmfi fi, Header otherHeader, rpmfi otherFi, int beingRemoved)
Definition: transaction.c:118
hashTable htCreate(int numBuckets, size_t keySize, int freeData, hashFunctionType fn, hashEqualityType eq)
Create hash table.
Definition: rpmhash.c:277
rpmtransFlags rpmtsFlags(rpmts ts)
Get transaction flags, i.e.
Definition: rpmts.c:1344
#define FF_ISSET(_fflags, _FLAG)
Definition: transaction.c:100
rpmRC rpmpsmScriptStage(rpmpsm psm, rpmTag scriptTag, rpmTag progTag)
Run rpmpsmStage(PSM_SCRIPT) for scriptTag and progTag.
Definition: psm.c:2146
const char * rpmteR(rpmte te)
Retrieve release string of transaction element.
Definition: rpmte.c:331
uint32_t headerGetInstance(Header h)
Return header instance (if from rpmdb).
Definition: header.c:1275
int rpmfiFX(rpmfi fi)
Return current file index from file info set.
Definition: rpmfi.c:103
int rpmExpandNumeric(const char *arg)
Return macro expansion as a numeric value.
Definition: macro.c:3191
int(* rpmtsRun)(rpmts ts, rpmps okProbs, rpmprobFilterFlags ignoreSet)
Process all package elements in a transaction set.
Definition: transaction.c:2353
#define xrealloc
Definition: system.h:36
void rpmtsEmpty(rpmts ts)
Re-create an empty transaction set.
Definition: rpmts.c:623
int rpmteIsSource(rpmte te)
Retrieve isSource attribute of transaction element.
Definition: rpmte.c:355
fingerPrintCache fpCacheCreate(int sizeHint)
Create finger print cache.
Definition: fprint.c:21
void rpmpsmSetAsync(rpmpsm psm, int async)
Definition: psm.c:2133
#define FPSDEBUG(_debug, _list)
Definition: transaction.c:233
int Unlink(const char *path)
unlink(2) clone.
Definition: rpmrpc.c:397