rpm  5.4.14
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 
937 
938  if ((fi = rpmteFI(p, _tag)) == NULL)
939  continue; /* XXX can't happen */
940 
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 
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 /* Add fingerprint for each file not skipped. */
1313 static void rpmtsAddFingerprints(rpmts ts, uint32_t fileCount, hashTable ht,
1314  fingerPrintCache fpc)
1315  /*@modifies ts, fpc @*/
1316 {
1317  rpmtsi pi;
1318  rpmte p;
1319  rpmfi fi;
1320  int i;
1321 
1322  hashTable symlinks = htCreate(fileCount/16+16, 0, 0, fpHashFunction, fpEqual);
1323 
1324 FPSDEBUG(0, (stderr, "--> %s(%p,%u,%p,%p)\n", __FUNCTION__, ts, (unsigned)fileCount, ht, fpc));
1325  pi = rpmtsiInit(ts);
1326  while ((p = rpmtsiNext(pi, (rpmElementType) 0)) != NULL) {
1327  (void) rpmdbCheckSignals();
1328 
1329  if (p->isSource) continue;
1330  if ((fi = rpmtsiFi(pi)) == NULL)
1331  continue; /* XXX can't happen */
1332 
1334 
1335  rpmfiFpLookup(fi, fpc);
1336 
1337  /* Collect symlinks. */
1338  fi = rpmfiInit(fi, 0);
1339  if (fi != NULL) /* XXX lclint */
1340  while ((i = rpmfiNext(fi)) >= 0) {
1341  char const *linktarget;
1342  linktarget = rpmfiFLink(fi);
1343  if (!(linktarget && *linktarget != '\0'))
1344  /*@innercontinue@*/ continue;
1345  if (iosmFileActionSkipped((iosmFileAction) fi->actions[i]))
1346  /*@innercontinue@*/ continue;
1347 #ifdef REFERENCE
1348  { struct rpmffi_s ffi;
1349  ffi.p = p;
1350  ffi.fileno = i;
1351  htAddEntry(symlinks, rpmfiFpsIndex(fi, i), ffi);
1352  }
1353 #else
1354  { struct rpmffi_s *ffip = (struct rpmffi_s *) alloca(sizeof(*ffip));
1355 /*@-dependenttrans@*/
1356  ffip->p = p;
1357 /*@=dependenttrans@*/
1358  ffip->fileno = i;
1359  htAddEntry(symlinks, fi->fps + i, (void *) ffip);
1360  }
1361 #endif
1362  }
1363 
1365 
1366  }
1367  pi = rpmtsiFree(pi);
1368 
1369  /* ===============================================
1370  * Check fingerprints if they contain symlinks
1371  * and add them to the hash table
1372  */
1373 
1374  pi = rpmtsiInit(ts);
1375  while ((p = rpmtsiNext(pi, (rpmElementType) 0)) != NULL) {
1376  (void) rpmdbCheckSignals();
1377 
1378  if (p->isSource) continue;
1379  if ((fi = rpmteFI(p, RPMTAG_BASENAMES)) == NULL)
1380  continue; /* XXX can't happen */
1381  fi = rpmfiInit(fi, 0);
1383  while ((i = rpmfiNext(fi)) >= 0) {
1384 #ifdef REFERENCE
1385  if (XFA_SKIPPING(rpmfsGetAction(rpmteGetFileStates(p), i)))
1386  continue;
1387 #else
1388  if (iosmFileActionSkipped((iosmFileAction) fi->actions[i]))
1389  /*@innercontinue@*/ continue;
1390 #endif
1391  fpLookupSubdir(symlinks, ht, fpc, p, i);
1392  }
1394  }
1395  pi = rpmtsiFree(pi);
1396 
1397  symlinks = htFree(symlinks);
1398 
1399 }
1400 
1402  /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
1403  /*@modifies ts, *sxp, rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
1404 {
1405  rpmtransFlags tsflags = rpmtsFlags(ts);
1406  int xx;
1407 
1408 /*@+voidabstract@*/
1409 FPSDEBUG(0, (stderr, "--> %s(%p,0x%x,%p)\n", __FUNCTION__, ts, ignoreSet, (void *)sxp));
1410 /*@=voidabstract@*/
1411  /* --noscripts implies no scripts or triggers, duh. */
1412  if (TSF_ISSET(tsflags, NOSCRIPTS)) {
1413  TSF_SET(tsflags, NOPRETRANS);
1414  TSF_SET(tsflags, NOPRE);
1415  TSF_SET(tsflags, NOPOST);
1416  TSF_SET(tsflags, NOPREUN);
1417  TSF_SET(tsflags, NOPOSTUN);
1418  TSF_SET(tsflags, NOPOSTTRANS);
1419 
1420  TSF_SET(tsflags, NOTRIGGERPREIN);
1421  TSF_SET(tsflags, NOTRIGGERIN);
1422  TSF_SET(tsflags, NOTRIGGERUN);
1423  TSF_SET(tsflags, NOTRIGGERPOSTUN);
1424 
1425  (void) rpmtsSetFlags(ts, tsflags);
1426  }
1427  /* --notriggers implies no triggers, duh. */
1428  if (TSF_ISSET(tsflags, NOTRIGGERS)) {
1429  TSF_SET(tsflags, NOTRIGGERPREIN);
1430  TSF_SET(tsflags, NOTRIGGERIN);
1431  TSF_SET(tsflags, NOTRIGGERUN);
1432  TSF_SET(tsflags, NOTRIGGERPOSTUN);
1433  (void) rpmtsSetFlags(ts, tsflags);
1434  }
1435 
1436  /* --justdb implies no scripts or triggers, duh. */
1437  if (TSF_ISSET(tsflags, JUSTDB)) {
1438  TSF_SET(tsflags, NOPRETRANS);
1439  TSF_SET(tsflags, NOPRE);
1440  TSF_SET(tsflags, NOPOST);
1441  TSF_SET(tsflags, NOPREUN);
1442  TSF_SET(tsflags, NOPOSTUN);
1443  TSF_SET(tsflags, NOPOSTTRANS);
1444 
1445  TSF_SET(tsflags, NOTRIGGERPREIN);
1446  TSF_SET(tsflags, NOTRIGGERIN);
1447  TSF_SET(tsflags, NOTRIGGERUN);
1448  TSF_SET(tsflags, NOTRIGGERPOSTUN);
1449 
1450  (void) rpmtsSetFlags(ts, tsflags);
1451  }
1452 
1453  /* if SELinux isn't enabled or init fails, don't bother... */
1454  if (!rpmtsSELinuxEnabled(ts)) {
1455  TSF_SET(tsflags, NOCONTEXTS);
1456  TSF_SET(tsflags, NOPOLICY);
1457  (void) rpmtsSetFlags(ts, tsflags);
1458  }
1459 
1460  if (!(TSF_ISSET(tsflags, NOCONTEXTS) || TSF_ISSET(tsflags, NOPOLICY))) {
1461  *sxp = rpmsxNew("%{?_install_file_context_path}", 0);
1462  if (*sxp == NULL) {
1463  TSF_SET(tsflags, NOCONTEXTS);
1464  TSF_SET(tsflags, NOPOLICY);
1465  (void) rpmtsSetFlags(ts, tsflags);
1466  }
1467  } else
1468  *sxp = NULL;
1469 
1470  /* XXX Make sure the database is open RDWR for package install/erase. */
1471  { int dbmode = O_RDONLY;
1472 
1473  if (!TSF_ISSET(tsflags, TEST)) {
1474  rpmtsi pi;
1475  rpmte p;
1476  pi = rpmtsiInit(ts);
1477  while ((p = rpmtsiNext(pi, (rpmElementType) 0)) != NULL) {
1478  if (p->isSource) continue;
1479  dbmode = (O_RDWR|O_CREAT);
1480  break;
1481  }
1482  pi = rpmtsiFree(pi);
1483  }
1484 
1485  /* Open database RDWR for installing packages. */
1486  if (rpmtsOpenDB(ts, dbmode))
1487  return -1; /* XXX W2DO? */
1488 
1489  }
1490 
1491  ts->ignoreSet = ignoreSet;
1492  ts->probs = rpmpsFree(ts->probs);
1493 
1494  { const char * currDir = currentDirectory();
1495  rpmtsSetCurrDir(ts, currDir);
1496  currDir = _free(currDir);
1497  }
1498 
1499  (void) rpmtsSetChrootDone(ts, 0);
1500 
1501  /* XXX rpmtsCreate() sets the transaction id, but apps may not honor. */
1502  { rpmuint32_t tid = (rpmuint32_t) time(NULL);
1503  (void) rpmtsSetTid(ts, tid);
1504  }
1505 
1506  /* Get available space on mounted file systems. */
1507  xx = rpmtsInitDSI(ts);
1508 
1509  return 0;
1510 }
1511 
1512 static int rpmtsFinish(rpmts ts, /*@only@*/ rpmsx sx)
1513  /*@modifies sx @*/
1514 {
1515 FPSDEBUG(0, (stderr, "--> %s(%p,%p)\n", __FUNCTION__, ts, sx));
1516 #ifdef REFERENCE
1517  rpmtransFlags tsflags = rpmtsFlags(ts);
1518  if (!TSF_ISSET(tsflags, NOCONTEXTS))
1519  matchpathcon_fini();
1520 #else /* REFERENCE */
1521  if (sx != NULL) sx = rpmsxFree(sx);
1522 #endif /* REFERENCE */
1523  return 0;
1524 }
1525 
1526 static int rpmtsPrepare(rpmts ts, rpmsx sx, uint32_t fileCount,
1527  uint32_t * nrmvdp)
1528  /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
1529  /*@modifies ts, *nrmvdp, rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
1530 {
1531  rpmtsi pi;
1532  rpmte p;
1533  fingerPrintCache fpc;
1534  rpmfi fi;
1535  int xx;
1536  int rc = 0;
1537 
1538 #ifdef REFERENCE
1539  uint64_t fileCount = countFiles(ts);
1540  const char * rootDir = rpmtsRootDir(ts);
1541  int dochroot = (rootDir != NULL && strcmp(rootDir, "/") && *rootDir == '/');
1542 
1543  rpmFpHash ht = rpmFpHashCreate(fileCount/2+1, fpHashFunction, fpEqual,
1544  NULL, NULL);
1545 
1546  fpc = fpCacheCreate(fileCount/2 + 10001);
1547 
1548  rpmlog(RPMLOG_DEBUG, "computing %" PRIu64 " file fingerprints\n", fileCount);
1549 
1550  /* Skip netshared paths, not our i18n files, and excluded docs */
1551  pi = rpmtsiInit(ts);
1552  while ((p = rpmtsiNext(pi, TR_ADDED)) != NULL) {
1553  if ((fi = rpmteFI(p)) == NULL)
1554  continue; /* XXX can't happen */
1555 
1556  if (rpmfiFC(fi) > 0)
1557  rpmtsSkipFiles(ts, p);
1558  }
1559  pi = rpmtsiFree(pi);
1560 
1561  /* Enter chroot for fingerprinting if necessary */
1562  if (!rpmtsChrootDone(ts)) {
1563  xx = chdir("/");
1564  if (dochroot) {
1565  /* opening db before chroot not optimal, see rhbz#103852 c#3 */
1566  xx = rpmdbOpenAll(ts->rdb);
1567  if (chroot(rootDir) == -1) {
1568  rpmlog(RPMLOG_ERR, _("Unable to change root directory: %m\n"));
1569  rc = -1;
1570  goto exit;
1571  }
1572  }
1573  (void) rpmtsSetChrootDone(ts, 1);
1574  }
1575 
1576 #else /* REFERENCE */
1577 
1578  void * ptr;
1579  uint32_t numAdded = 0;
1580  uint32_t numRemoved = 0;
1581 
1582 FPSDEBUG(0, (stderr, "--> %s(%p,%p,%u,%p)\n", __FUNCTION__, ts, sx, (unsigned)fileCount, nrmvdp));
1583 rpmlog(RPMLOG_DEBUG, D_("computing %u file fingerprints\n"), (unsigned)fileCount);
1584 
1585  pi = rpmtsiInit(ts);
1586  while ((p = rpmtsiNext(pi, (rpmElementType) 0)) != NULL) {
1587  int fc;
1588 
1589  if (p->isSource) continue;
1590  if ((fi = rpmtsiFi(pi)) == NULL)
1591  continue; /* XXX can't happen */
1592  fc = rpmfiFC(fi);
1593 
1594  switch (rpmteType(p)) {
1595  case TR_ADDED:
1596  numAdded++;
1597  fi->record = 0;
1598  /* Skip netshared paths, not our i18n files, and excluded docs */
1599  if (fc > 0)
1600  rpmtsSkipFiles(ts, fi);
1601  /*@switchbreak@*/ break;
1602  case TR_REMOVED:
1603  numRemoved++;
1604  fi->record = rpmteDBOffset(p);
1605  /*@switchbreak@*/ break;
1606  }
1607 
1608  fi->fps = (struct fingerPrint_s *)
1609  (fc > 0 ? xmalloc(fc * sizeof(*fi->fps)) : NULL);
1610  }
1611  pi = rpmtsiFree(pi);
1612 
1613  if (nrmvdp)
1614  *nrmvdp = numRemoved;
1615 
1616  if (!rpmtsChrootDone(ts)) {
1617  const char * rootDir = rpmtsRootDir(ts);
1618  static int openall_before_chroot = -1;
1619 
1620  if (openall_before_chroot < 0)
1621  openall_before_chroot = rpmExpandNumeric("%{?_openall_before_chroot}");
1622 
1623  xx = Chdir("/");
1624  /*@-modobserver@*/
1625  if (rootDir != NULL && strcmp(rootDir, "/") && *rootDir == '/') {
1626  if (openall_before_chroot)
1627  xx = rpmdbOpenAll(rpmtsGetRdb(ts));
1628  xx = Chroot(rootDir);
1629  }
1630  /*@=modobserver@*/
1631  (void) rpmtsSetChrootDone(ts, 1);
1632  }
1633 
1634  ts->ht = htCreate(fileCount/2 + 1, 0, 1, fpHashFunction, fpEqual);
1635  fpc = fpCacheCreate(fileCount/2 + 10001);
1636 
1637 #endif /* REFERENCE */
1638 
1639  ptr = rpmtsNotify(ts, NULL, RPMCALLBACK_TRANS_START, 6, ts->orderCount);
1640 
1641  /* ===============================================
1642  * Add fingerprint for each file not skipped.
1643  */
1644 #ifdef REFERENCE
1645  rpmtsAddFingerprints(ts, fileCount, ht, fpc);
1646 #else /* REFERENCE */
1647  rpmtsAddFingerprints(ts, fileCount, ts->ht, fpc);
1648 #endif /* REFERENCE */
1649 
1650  /* ===============================================
1651  * Compute file disposition for each package in transaction set.
1652  */
1653 #ifdef REFERENCE
1654  rpmtsCheckInstalledFiles(ts, fileCount, ht, fpc);
1655 #else /* REFERENCE */
1656  rc = rpmtsCheckInstalledFiles(ts, fileCount, ts->ht, fpc);
1657  if (rc)
1658  goto exit;
1659 #endif /* REFERENCE */
1660 
1661  pi = rpmtsiInit(ts);
1662  while ((p = rpmtsiNext(pi, (rpmElementType) 0)) != NULL) {
1663  if ((fi = rpmteFI(p, RPMTAG_BASENAMES)) == NULL)
1664  continue; /* XXX can't happen */
1665  /* XXX Set all SRPM files to FA_CREATE. */
1666  if (p->isSource) {
1667  int i;
1668  fi = rpmfiInit(fi, 0);
1669  if (fi != NULL)
1670  while ((i = rpmfiNext(fi)) >= 0)
1671  fi->actions[i] = FA_CREATE;
1672  continue;
1673  }
1674 
1676 
1677  /* Update disk space needs on each partition for this package. */
1678 /*@-nullpass@*/
1679 #ifdef REFERENCE
1680  handleOverlappedFiles(ts, ht, p, fi);
1681 #else /* REFERENCE */
1682  handleOverlappedFiles(ts, p, fi);
1683 #endif /* REFERENCE */
1684 /*@=nullpass@*/
1685 
1686  /* Check added package has sufficient space on each partition used. */
1687  switch (rpmteType(p)) {
1688  case TR_ADDED:
1689  rpmtsCheckDSIProblems(ts, p);
1690  /*@switchbreak@*/ break;
1691  case TR_REMOVED:
1692  /*@switchbreak@*/ break;
1693  }
1695  }
1696  pi = rpmtsiFree(pi);
1697 
1698  if (rpmtsChrootDone(ts)) {
1699  const char * rootDir = rpmtsRootDir(ts);
1700  const char * currDir = rpmtsCurrDir(ts);
1701  /*@-modobserver@*/
1702  if (rootDir != NULL && strcmp(rootDir, "/") && *rootDir == '/')
1703  xx = Chroot(".");
1704  /*@=modobserver@*/
1705  (void) rpmtsSetChrootDone(ts, 0);
1706  if (currDir != NULL)
1707  xx = Chdir(currDir);
1708  }
1709 
1710  ptr = rpmtsNotify(ts, NULL, RPMCALLBACK_TRANS_STOP, 6, ts->orderCount);
1711 
1712  /* ===============================================
1713  * Free unused memory as soon as possible.
1714  */
1715 #ifdef REFERENCE
1716  pi = rpmtsiInit(ts);
1717  while ((p = rpmtsiNext(pi, (rpmElementType) 0)) != NULL) {
1718  rpmteSetFI(p, NULL);
1719  }
1720  pi = rpmtsiFree(pi);
1721 #else /* REFERENCE */
1722  pi = rpmtsiInit(ts);
1723  while ((p = rpmtsiNext(pi, (rpmElementType) 0)) != NULL) {
1724  if (p->isSource) continue;
1725  if ((fi = rpmtsiFi(pi)) == NULL)
1726  continue; /* XXX can't happen */
1727  if (rpmfiFC(fi) == 0)
1728  continue;
1729  fi->fps = _free(fi->fps);
1730  }
1731  pi = rpmtsiFree(pi);
1732 #endif /* REFERENCE */
1733 
1734 exit:
1735 #ifdef REFERENCE
1736  ht = rpmFpHashFree(ht);
1737 #else /* REFERENCE */
1738  ts->ht = htFree(ts->ht);
1739 #endif /* REFERENCE */
1740  fpc = fpCacheFree(fpc);
1741 
1742  return rc;
1743 }
1744 
1745 /*
1746  * Transaction main loop: install and remove packages
1747  */
1749  int rollbackFailures)
1750  /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
1751  /*@modifies ts, rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
1752 {
1753  rpmtsi pi;
1754  rpmte p;
1755  int rc = 0;
1756 
1757 FPSDEBUG(0, (stderr, "--> %s(%p,0x%x,%d)\n", __FUNCTION__, ts, ignoreSet, rollbackFailures));
1758  pi = rpmtsiInit(ts);
1759  while ((p = rpmtsiNext(pi, (rpmElementType) 0)) != NULL) {
1760  rpmfi fi;
1761  rpmop sw;
1762  rpmpsm psm = NULL;
1763  pkgStage stage = PSM_UNKNOWN;
1764  int failed;
1765  int gotfd;
1766  int xx;
1767 
1768 #ifdef REFERENCE
1769  rpmElementType tetype = rpmteType(p);
1771 #endif /* REFERENCE */
1772 
1773  (void) rpmdbCheckSignals();
1774 
1775  failed = 1;
1776  gotfd = 0;
1777  if ((fi = rpmtsiFi(pi)) == NULL)
1778  continue; /* XXX can't happen */
1779 
1780  if (rpmteFailed(p)) {
1781  /* XXX this should be a warning, need a better message though */
1782  rpmlog(RPMLOG_DEBUG, D_("element %s marked as failed, skipping\n"),
1783  rpmteNEVRA(p));
1784  rc++;
1785  continue;
1786  }
1787 
1788  psm = rpmpsmNew(ts, p, fi);
1789  { int async = (rpmtsiOc(pi) >= rpmtsUnorderedSuccessors(ts, -1)) ?
1790  1 : 0;
1791  rpmpsmSetAsync(psm, async);
1792  }
1793 
1794  switch (rpmteType(p)) {
1795  case TR_ADDED:
1796  rpmlog(RPMLOG_DEBUG, "========== +++ %s %s-%s 0x%x\n",
1797  rpmteNEVR(p), rpmteA(p), rpmteO(p), rpmteColor(p));
1798  stage = PSM_PKGINSTALL;
1799  sw = rpmtsOp(ts, RPMTS_OP_INSTALL);
1800 #ifdef REFERENCE
1801  if (rpmteOpen(p, ts, 1)) {
1802  (void) rpmswEnter(rpmtsOp(ts, op), 0);
1803  failed = rpmpsmStage(psm, stage);
1804  (void) rpmswExit(rpmtsOp(ts, op), 0);
1805  rpmteClose(p, ts, 1);
1806  }
1807 #else /* REFERENCE */
1808  if ((p->h = rpmteFDHeader(ts, p)) != NULL)
1809  gotfd = 1;
1810 
1811  if (gotfd && rpmteFd(p) != NULL) {
1812  /*
1813  * XXX Sludge necessary to transfer existing fstates/actions
1814  * XXX around a recreated file info set.
1815  */
1816  rpmuint8_t * fstates = fi->fstates;
1817  iosmFileAction * actions = (iosmFileAction *) fi->actions;
1818  int mapflags = fi->mapflags;
1819  rpmte savep;
1820  int scareMem = 0;
1821 
1822  psm->fi = rpmfiFree(psm->fi);
1823 
1824  fi->fstates = NULL;
1825  fi->actions = NULL;
1826 /*@-nullstate@*/ /* FIX: fi->actions is NULL */
1827  fi = rpmfiFree(fi);
1828 /*@=nullstate@*/
1829 
1830  savep = rpmtsSetRelocateElement(ts, p);
1831  fi = rpmfiNew(ts, p->h, RPMTAG_BASENAMES, scareMem);
1832  (void) rpmtsSetRelocateElement(ts, savep);
1833 
1834  if (fi != NULL) { /* XXX can't happen */
1835  fi->te = p;
1836  fi->fstates = _free(fi->fstates);
1837  fi->fstates = fstates;
1838  fi->actions = _free(fi->actions);
1839  fi->actions = (int *) actions;
1840  if (mapflags & IOSM_SBIT_CHECK)
1841  fi->mapflags |= IOSM_SBIT_CHECK;
1842  p->fi = fi;
1843  }
1844 
1845  psm->fi = rpmfiLink(p->fi, __FUNCTION__);
1846 
1847  (void) rpmswEnter(sw, 0);
1848  failed = (rpmpsmStage(psm, stage) != RPMRC_OK);
1849  (void) rpmswExit(sw, 0);
1850 
1851  xx = rpmteClose(p, ts, 0);
1852  gotfd = 0;
1853  }
1854 
1855 #endif /* REFERENCE */
1856  /*@switchbreak@*/ break;
1857 
1858  case TR_REMOVED:
1859  rpmlog(RPMLOG_DEBUG, "========== --- %s %s-%s 0x%x\n",
1860  rpmteNEVR(p), rpmteA(p), rpmteO(p), rpmteColor(p));
1861  stage = PSM_PKGERASE;
1862  sw = rpmtsOp(ts, RPMTS_OP_ERASE);
1863 #ifdef REFERENCE
1864  if (rpmteOpen(p, ts, 1)) {
1865  (void) rpmswEnter(rpmtsOp(ts, op), 0);
1866  failed = rpmpsmStage(psm, stage);
1867  (void) rpmswExit(rpmtsOp(ts, op), 0);
1868  rpmteClose(p, ts, 1);
1869  }
1870 #else /* REFERENCE */
1871  (void) rpmswEnter(sw, 0);
1872  failed = (rpmpsmStage(psm, stage) != RPMRC_OK);
1873  (void) rpmswExit(sw, 0);
1874 #endif /* REFERENCE */
1875  /*@switchbreak@*/ break;
1876  }
1877 
1878 #if defined(RPM_VENDOR_MANDRIVA)
1879  { rpmtransFlags tsflags = rpmtsFlags(ts);
1880  if (!failed && !TSF_ISSET(tsflags, TEST)) {
1881  if(!rpmteIsSource(p))
1882  xx = mayAddToFilesAwaitingFiletriggers(rpmtsRootDir(ts),
1883  fi, (rpmteType(p) == TR_ADDED ? 1 : 0));
1884  p->done = 1;
1885  }
1886  }
1887 #endif
1888 
1889 /*@-nullstate@*/ /* FIX: psm->fi may be NULL */
1890  psm = rpmpsmFree(psm, __FUNCTION__);
1891 /*@=nullstate@*/
1892 
1893  if (failed) {
1894  rc++;
1895 #ifdef REFERENCE
1896  rpmteMarkFailed(p, ts);
1897 #else /* REFERENCE */
1898  xx = rpmtsMarkLinkedFailed(ts, p);
1899  /* If we received an error, lets break out and rollback, provided
1900  * autorollback is enabled.
1901  */
1902  if (rollbackFailures) {
1903  xx = rpmtsRollback(ts, ignoreSet, 1, p);
1904  break;
1905  }
1906 #endif /* REFERENCE */
1907  }
1908 
1909  if (p->h != NULL) {
1910  (void) headerFree(p->h);
1911  p->h = NULL;
1912  }
1913 
1914 #ifdef REFERENCE
1915  (void) rpmdbSync(rpmtsGetRdb(ts));
1916 #endif /* REFERENCE */
1917 
1918  }
1919  pi = rpmtsiFree(pi);
1920  return rc;
1921 }
1922 
1923 /* ================================================================= */
1924 static int rpmtsRepackage(rpmts ts, uint32_t numRemoved)
1925  /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
1926  /*@modifies ts, rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
1927 {
1928  rpmtransFlags tsflags = rpmtsFlags(ts);
1929  rpmpsm psm;
1930  rpmfi fi;
1931  rpmtsi pi;
1932  rpmte p;
1933  void * ptr;
1934  int progress = 0;
1935  int rc = 0;
1936  int xx;
1937 
1938 FPSDEBUG(0, (stderr, "--> %s(%p,%u)\n", __FUNCTION__, ts, (unsigned)numRemoved));
1939  pi = rpmtsiInit(ts);
1940  while ((p = rpmtsiNext(pi, (rpmElementType) 0)) != NULL) {
1941 
1942  (void) rpmdbCheckSignals();
1943 
1944  if (p->isSource) continue;
1945  if ((fi = rpmtsiFi(pi)) == NULL)
1946  continue; /* XXX can't happen */
1947  switch (rpmteType(p)) {
1948  case TR_ADDED:
1949  /*@switchbreak@*/ break;
1950  case TR_REMOVED:
1951  if (!TSF_ISSET(tsflags, REPACKAGE))
1952  /*@switchbreak@*/ break;
1953  if (!progress)
1955  7, numRemoved);
1956 
1958  progress, numRemoved);
1959  progress++;
1960 
1962 
1963  /* XXX TR_REMOVED needs IOSM_MAP_{ABSOLUTE,ADDDOT} IOSM_ALL_HARDLINKS */
1964  fi->mapflags |= IOSM_MAP_ABSOLUTE;
1965  fi->mapflags |= IOSM_MAP_ADDDOT;
1966  fi->mapflags |= IOSM_ALL_HARDLINKS;
1967  psm = rpmpsmNew(ts, p, fi);
1968 assert(psm != NULL);
1969  xx = rpmpsmStage(psm, PSM_PKGSAVE);
1970  psm = rpmpsmFree(psm, __FUNCTION__);
1971  fi->mapflags &= ~IOSM_MAP_ABSOLUTE;
1972  fi->mapflags &= ~IOSM_MAP_ADDDOT;
1973  fi->mapflags &= ~IOSM_ALL_HARDLINKS;
1974 
1976 
1977  /*@switchbreak@*/ break;
1978  }
1979  }
1980  pi = rpmtsiFree(pi);
1981  if (progress)
1982  ptr = rpmtsNotify(ts, NULL, RPMCALLBACK_REPACKAGE_STOP, 7, numRemoved);
1983 
1984  return rc;
1985 }
1986 
1993 /*@-nullpass@*/
1995  /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
1996  /*@modifies ts, p, rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
1997 {
1998  int rc = RPMRC_OK; /* assume success */
1999 
2000 FPSDEBUG(0, (stderr, "--> %s(%p,%p)\n", __FUNCTION__, ts, p));
2001  /* Handle failed packages. */
2002  /* XXX TODO: Add header to rpmdb in PSM_INIT, not PSM_POST. */
2003  if (p != NULL && rpmteType(p) == TR_ADDED && !p->installed) {
2004 /*@-compdef -usereleased@*/ /* p->fi->te undefined */
2005  rpmpsm psm = rpmpsmNew(ts, p, p->fi);
2006 /*@=compdef =usereleased@*/
2007  /*
2008  * If it died before the header was put in the rpmdb, we need
2009  * do to something wacky which is add the header to the DB anyway.
2010  * This will allow us to add the failed package as an erase
2011  * to the rollback transaction. This must be done because we
2012  * want the the erase scriptlets to run, and the only way that
2013  * is going is if the header is in the rpmdb.
2014  */
2015 assert(psm != NULL);
2016  psm->stepName = "failed"; /* XXX W2DO? */
2017  rc = rpmpsmStage(psm, PSM_RPMDB_ADD);
2018  psm = rpmpsmFree(psm, __FUNCTION__);
2019  }
2020  return (rpmRC) rc;
2021 }
2022 /*@=nullpass@*/
2023 
2024 /*@-nullpass@*/
2026  /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
2027  /*@modifies rbts, rpmGlobalMacroContext, fileSystem, internalState @*/
2028 {
2029  const char * semfn = NULL;
2030  rpmRC rc = (rpmRC) 0;
2031  rpmuint32_t arbgoal = rpmtsARBGoal(rbts);
2032  QVA_t ia = (QVA_t) memset(alloca(sizeof(*ia)), 0, sizeof(*ia));
2033  time_t ttid;
2034  int xx;
2035 
2036 FPSDEBUG(0, (stderr, "--> %s(%p,0x%x,%d,%p)\n", __FUNCTION__, rbts, ignoreSet, running, rbte));
2037  /* Don't attempt rollback's of rollback transactions */
2038  if ((rpmtsType(rbts) & RPMTRANS_TYPE_ROLLBACK) ||
2040  return RPMRC_OK;
2041 
2042  if (arbgoal == 0xffffffff)
2043  arbgoal = rpmtsGetTid(rbts);
2044 
2045  /* Don't attempt rollbacks if no goal is set. */
2046  if (!running && arbgoal == 0xffffffff)
2047  return RPMRC_OK;
2048 
2049  /* We need to remove an headers that were going to be removed so
2050  * as to not foul up the regular rollback mechanism which will not
2051  * handle properly a file being in the repackaged package directory
2052  * and also its header still in the DB.
2053  */
2054  { rpmtsi tsi;
2055  rpmte te;
2056 
2057  /* XXX Insure an O_RDWR rpmdb. */
2058  xx = rpmtsOpenDB(rbts, O_RDWR);
2059 
2060  tsi = rpmtsiInit(rbts);
2061  while((te = rpmtsiNext(tsi, TR_REMOVED)) != NULL) {
2062  if (te->isSource) continue;
2063  if(!te->u.removed.dboffset)
2064  continue;
2065  rc = (rpmRC) rpmdbRemove(rpmtsGetRdb(rbts),
2066  rpmtsGetTid(rbts),
2067  te->u.removed.dboffset, NULL);
2068  if (rc != RPMRC_OK) {
2069  rpmlog(RPMLOG_ERR, _("rpmdb erase failed. NEVRA: %s\n"),
2070  rpmteNEVRA(te));
2071  break;
2072  }
2073  }
2074  tsi = rpmtsiFree(tsi);
2075  if (rc != RPMRC_OK)
2076  goto cleanup;
2077  }
2078 
2079  /* Process the failed package */
2080  rc = _processFailedPackage(rbts, rbte);
2081  if (rc != RPMRC_OK)
2082  goto cleanup;
2083 
2084  rpmtsEmpty(rbts);
2085 
2086  ttid = (time_t)arbgoal;
2087  rpmlog(RPMLOG_NOTICE, _("Rollback to %-24.24s (0x%08x)\n"),
2088  ctime(&ttid), arbgoal);
2089 
2090  /* Set the verify signature flags:
2091  * - can't verify signatures/digests on repackaged packages.
2092  * - header check are out.
2093  */
2094  {
2095  rpmVSFlags vsflags = (rpmVSFlags) rpmExpandNumeric("%{?_vsflags_erase}");
2096  vsflags = (rpmVSFlags) 0; /* XXX FIXME: ignore default disablers. */
2097 #if defined(SUPPORT_NOSIGNATURES)
2098  /* --nodigest */
2099  VSF_SET(vsflags, NOSHA1HEADER);
2100  VSF_SET(vsflags, NOMD5HEADER);
2101  VSF_SET(vsflags, NOSHA1);
2102  VSF_SET(vsflags, NOMD5);
2103  /* --nosignature */
2104  VSF_SET(vsflags, NODSAHEADER);
2105  VSF_SET(vsflags, NORSAHEADER);
2106  VSF_SET(vsflags, NODSA);
2107  VSF_SET(vsflags, NORSA);
2108  /* --nohdrchk */
2109  VSF_SET(vsflags, NOHDRCHK);
2110  VSF_SET(vsflags, NEEDPAYLOAD); /* XXX needed? */
2111 #endif
2112  xx = rpmtsSetVSFlags(rbts, vsflags);
2113  }
2114 
2115  /* Set transaction flags to be the same as the running transaction */
2116  {
2117  rpmtransFlags tsflags = rpmtsFlags(rbts);
2118  TSF_CLR(tsflags, DIRSTASH); /* No repackage of rollbacks */
2119  TSF_CLR(tsflags, REPACKAGE); /* No repackage of rollbacks */
2120  TSF_SET(tsflags, NOFDIGESTS); /* Don't check file digests */
2121  tsflags = rpmtsSetFlags(rbts, tsflags);
2122  }
2123 
2124  /* Create install arguments structure */
2125  ia->rbtid = arbgoal;
2126  /* transFlags/depFlags from rbts, (re-)set in rpmRollback(). */
2127  ia->transFlags = rpmtsFlags(rbts);
2128  ia->depFlags = rpmtsDFlags(rbts);
2129  /* XXX probFilter is normally set in main(). */
2130  ia->probFilter = ignoreSet; /* XXX RPMPROB_FILTER_NONE? */
2131  /* XXX installInterfaceFlags is normally set in main(). */
2132  IIF_SET(ia->installInterfaceFlags, UPGRADE);
2133  IIF_SET(ia->installInterfaceFlags, HASH);
2134 
2135  /* rpmtsCheck and rpmtsOrder failures do not have links. */
2136  ia->no_rollback_links = 1;
2137 
2138  /* Create a file semaphore. */
2139  semfn = rpmExpand("%{?semaphore_backout}", NULL);
2140  if (semfn && *semfn) {
2141  FD_t fd = Fopen(semfn, "w.fdio");
2142  if (fd)
2143  xx = Fclose(fd);
2144  }
2145 
2146 /*@-compmempass@*/
2147  rc = (rpmRC) rpmRollback(rbts, ia, NULL);
2148 /*@=compmempass@*/
2149 
2150 cleanup:
2151  /* Remove the file semaphore. */
2152  if (semfn && *semfn)
2153  xx = Unlink(semfn);
2154  semfn = _free(semfn);
2155 
2156  return rc;
2157 }
2158 /*@=nullpass@*/
2159 
2161 {
2162  rpmtransFlags tsflags = rpmtsFlags(ts);
2163  int ourrc = -1; /* assume failure */
2164  uint32_t totalFileCount = 0;
2165  rpmps ps;
2166  rpmsx sx = NULL;
2167  uint32_t numRemoved;
2168  int rollbackFailures = 0;
2169  void * lock = NULL;
2170  int xx;
2171 
2172 FPSDEBUG(0, (stderr, "--> %s(%p,%p,0x%x)\n", __FUNCTION__, ts, okProbs, ignoreSet));
2173 if (_rpmts_debug)
2174 fprintf(stderr, "--> %s(%p,%p,0x%x) tsflags 0x%x\n", __FUNCTION__, ts, okProbs, (unsigned) ignoreSet, tsflags);
2175 
2176  /* XXX programmer error segfault avoidance. */
2177  if (rpmtsNElements(ts) <= 0) {
2179  _("Invalid number of transaction elements.\n"));
2180  return -1;
2181  }
2182 
2183  /* Don't acquire the transaction lock if testing. */
2184  if (!TSF_ISSET(tsflags, TEST))
2185  lock = rpmtsAcquireLock(ts);
2186 
2187  rollbackFailures = rpmExpandNumeric("%{?_rollback_transaction_on_failure}");
2188  /* Don't rollback unless repackaging. */
2189  if (!TSF_ISSET(tsflags, REPACKAGE))
2190  rollbackFailures = 0;
2191  /* Don't rollback if testing. */
2192  if (TSF_ISSET(tsflags, TEST))
2193  rollbackFailures = 0;
2194 
2196  rollbackFailures = 0;
2197 
2198  /* ===============================================
2199  * Setup flags and such, open the rpmdb in O_RDWR mode.
2200  */
2201  sx = NULL;
2202  if (rpmtsSetup(ts, ignoreSet, &sx))
2203  goto exit;
2204 
2205  /* ===============================================
2206  * For packages being installed:
2207  * - verify package epoch:version-release is newer.
2208  * - count files.
2209  * For packages being removed:
2210  * - count files.
2211  */
2212 
2213  totalFileCount = 0;
2214  ps = rpmtsSanityCheck(ts, &totalFileCount);
2215  ps = rpmpsFree(ps);
2216 
2217  /* ===============================================
2218  * Run pre-transaction scripts, but only if no known problems exist.
2219  */
2220  if (!TSF_ISSET(tsflags, NOPRETRANS) &&
2221  (!(TSF_ISSET(tsflags, BUILD_PROBS) || TSF_ISSET(tsflags, TEST))
2222  || (rpmpsNumProblems(ts->probs) &&
2223  (okProbs == NULL || rpmpsTrim(ts->probs, okProbs)))))
2224  {
2225  rpmlog(RPMLOG_DEBUG, D_("running pre-transaction scripts\n"));
2226  xx = rpmtsRunScript(ts, RPMTAG_PRETRANS);
2227  }
2228 
2229  /* ===============================================
2230  * Compute file disposition for each package in transaction set.
2231  */
2232  numRemoved = 0;
2233  if (rpmtsPrepare(ts, sx, totalFileCount, &numRemoved))
2234  goto exit;
2235 
2236  /* ===============================================
2237  * If unfiltered problems exist, free memory and return.
2238  */
2239  if (TSF_ISSET(tsflags, BUILD_PROBS)
2240  || (rpmpsNumProblems(ts->probs) &&
2241  (okProbs == NULL || rpmpsTrim(ts->probs, okProbs)))
2242  )
2243  {
2244  lock = rpmtsFreeLock(lock);
2245  if (sx != NULL) sx = rpmsxFree(sx);
2246  return ts->orderCount;
2247  }
2248 
2249  /* ===============================================
2250  * Save removed files before erasing (w/o --justdb).
2251  */
2252  if ((TSF_ISSET(tsflags, DIRSTASH) || TSF_ISSET(tsflags, REPACKAGE))
2253  && !TSF_ISSET(tsflags, JUSTDB))
2254  {
2255  xx = rpmtsRepackage(ts, numRemoved);
2256  }
2257 
2258 #ifdef NOTYET
2259  xx = rpmtxnBegin(rpmtsGetRdb(ts), NULL, &ts->txn);
2260 #endif
2261 
2262  /* ===============================================
2263  * Install and remove packages.
2264  */
2265  ourrc = rpmtsProcess(ts, ignoreSet, rollbackFailures);
2266 
2267  /* ===============================================
2268  * Run post-transaction scripts unless disabled.
2269  */
2270  if (!TSF_ISSET(tsflags, NOPOSTTRANS) && !TSF_ISSET(tsflags, TEST))
2271  {
2272 
2273 #if defined(RPM_VENDOR_MANDRIVA)
2274  /* XXX FIXME: simplify the logic. */
2275  if (!TSF_ISSET(tsflags, NOTRIGGERPREIN)
2276  || !TSF_ISSET(tsflags, NOTRIGGERIN)
2277  || !TSF_ISSET(tsflags, NOTRIGGERUN)
2278  || !TSF_ISSET(tsflags, NOTRIGGERPOSTUN))
2279  rpmRunFileTriggers(rpmtsRootDir(ts));
2280 #endif
2281 
2282  rpmlog(RPMLOG_DEBUG, D_("running post-transaction scripts\n"));
2283  xx = rpmtsRunScript(ts, RPMTAG_POSTTRANS);
2284  }
2285 
2286 exit:
2287  xx = rpmtsFinish(ts, sx);
2288 
2289  lock = rpmtsFreeLock(lock);
2290 
2291  /*@-nullstate@*/ /* FIX: ts->flList may be NULL */
2292  if (ourrc) {
2293  if (ts->txn != NULL)
2294  xx = rpmtxnAbort(ts->txn);
2295  ts->txn = NULL;
2296  return -1;
2297  } else {
2298  if (ts->txn != NULL)
2299  xx = rpmtxnCommit(ts->txn);
2300  ts->txn = NULL;
2301  xx = rpmtxnCheckpoint(rpmtsGetRdb(ts));
2302  return 0;
2303  }
2304  /*@=nullstate@*/
2305 }
2306 
2308  = _rpmtsRun;
const char * rpmteV(rpmte te)
Retrieve version string of transaction element.
Definition: rpmte.c:326
rpmuint32_t rpmfiFFlags(rpmfi fi)
Return current file flags from file info set.
Definition: rpmfi.c:217
Definition: iosm.h:34
int _rpmtsRun(rpmts ts, rpmps okProbs, rpmprobFilterFlags ignoreSet)
Definition: transaction.c:2160
const char * rpmteNEVRA(rpmte te)
Retrieve name-version-release.arch string from transaction element.
Definition: rpmte.c:541
struct rpmpsi_s * rpmpsi
Definition: rpmps.h:29
int rpmtsChrootDone(rpmts ts)
Get chrootDone flag, i.e.
Definition: rpmts.c:1005
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:73
int xx
Definition: spec.c:744
rpmTag tag
Definition: rpmtag.h:501
int rpmteClose(rpmte te, rpmts ts, int reset_fi)
Definition: rpmte.c:922
iter fi
Definition: fsm.c:170
rpmop rpmtsOp(rpmts ts, rpmtsOpX opx)
Retrieve operation timestamp from a transaction set.
Definition: pkgio.c:133
static int rpmtsPrepare(rpmts ts, rpmsx sx, uint32_t fileCount, uint32_t *nrmvdp)
Definition: transaction.c:1526
rpmte rpmtsSetRelocateElement(rpmts ts, rpmte relocateElement)
Set current relocate transaction element.
Definition: rpmts.c:1399
rpmprobFilterFlags rpmtsFilterFlags(rpmts ts)
Get problem ignore bit mask, i.e.
Definition: rpmts.c:1327
const char ** argv
Definition: rpmtag.h:75
rpmdepFlags depFlags
Definition: rpmcli.h:671
struct rpmQVKArguments_s * QVA_t
Definition: rpmcli.h:256
const char * fdigest
Definition: rpmfi-py.c:248
#define headerFree(_h)
Definition: rpmtag.h:870
int rpmfiDX(rpmfi fi)
Return current directory index from file info set.
Definition: rpmfi.c:120
rpmlog(RPMLOG_ERR,"%s\n", buf)
int rpmteOpen(rpmte te, rpmts ts, int reload_fi)
Definition: rpmte.c:880
int rpmmiGrowBasename(rpmmi mi, const char *bn)
Append packages containing common basename to iterator.
Definition: rpmdb.c:1491
static int rpmtsCheckInstalledFiles(rpmts ts, uint32_t fileCount, hashTable ht, fingerPrintCache fpc)
Definition: transaction.c:975
rpmuint32_t rpmteColor(rpmte te)
Retrieve color bits of transaction element.
Definition: rpmte.c:360
Header rpmteFDHeader(rpmts ts, rpmte te)
Definition: rpmte.c:856
int rpmtsInitDSI(const rpmts ts)
Initialize disk space info for each and every mounted file systems.
Definition: rpmts.c:1065
struct rpmte_s * rpmte
An element of a transaction set, i.e.
Definition: rpmtypes.h:38
static int rpmtsProcess(rpmts ts, rpmprobFilterFlags ignoreSet, int rollbackFailures)
Definition: transaction.c:1748
void rpmfiFpLookup(rpmfi fi, fingerPrintCache fpc)
Definition: rpmfi.c:518
int(* rpmtsRun)(rpmts ts, rpmps okProbs, rpmprobFilterFlags ignoreSet)
Process all package elements in a transaction set.
Definition: transaction.c:2307
rpmProblem rpmpsGetProblem(rpmps ps, int num)
Return a problem from problem set.
Definition: rpmps.c:386
const char * baseName
Definition: fprint.h:57
uint32_t headerGetInstance(Header h)
Return header instance (if from rpmdb).
Definition: header.c:1275
q
Definition: macro.c:451
struct rpmpsm_s * rpmpsm
Package state machine data.
Definition: psm.h:13
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
Structures used for an &quot;rpmte&quot; 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:70
FD_t Fopen(const char *path, const char *_fmode)
fopen(3) clone.
Definition: rpmio.c:2831
uint32_t rpmmiInstance(rpmmi mi)
Return header instance for current position of rpmdb iterator.
Definition: rpmdb.c:1743
Structure(s) used for file info tag sets.
rpmfi rpmteFI(rpmte te, rpmTag tag)
Retrieve file info tag set from transaction element.
Definition: rpmte.c:587
static char *size_t nb
fgets(3) analogue that reads \ continuations.
Definition: macro.c:409
enum rpmprobFilterFlags_e rpmprobFilterFlags
rpmpsi rpmpsFreeIterator(rpmpsi psi)
Destroy problem set iterator.
Definition: rpmps.c:91
rpmtransFlags rpmtsSetFlags(rpmts ts, rpmtransFlags transFlags)
Set transaction flags, i.e.
Definition: rpmts.c:1345
struct rpmts_s * rpmts
The RPM Transaction Set.
Definition: rpmtypes.h:14
int rc
Definition: poptALL.c:670
rpmdb rpmtsGetRdb(rpmts ts)
Get transaction set database handle.
Definition: pkgio.c:151
#define TSF_SET(_tsflags, _FLAG)
Definition: transaction.c:109
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
rpmsx rpmsxFree(rpmsx sx)
Destroy a SELinux wrapper.
The Header data structure.
rpmuint32_t rpmtsSetTid(rpmts ts, rpmuint32_t tid)
Set transaction id, i.e.
Definition: rpmts.c:1031
rpmuint32_t fpHashFunction(rpmuint32_t h, const void *data, size_t size)
Definition: fprint.c:196
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
int rpmtsUnorderedSuccessors(rpmts ts, int first)
Set index of 1st element of successors.
Definition: rpmts.c:890
Definition: rpmdb.c:436
fts m
Definition: rpmmtree.c:3827
enum rpmTag_e rpmTag
Definition: rpmtag.h:468
rpmte rpmtsiNext(rpmtsi tsi, rpmElementType type)
Return next transaction element of type.
Definition: rpmte.c:831
rpmTSType rpmtsType(rpmts ts)
Return the type of a transaction.
Definition: rpmts.c:868
rpmfi rpmfiFree(rpmfi fi)
Destroy a file info set.
const char * rpmfiFN(rpmfi fi)
Return current file name from file info set.
Definition: rpmfi.c:163
unsigned short rpmuint16_t
Definition: rpmiotypes.h:27
int rpmfiDecideFate(const rpmfi ofi, rpmfi nfi, int skipMissing)
Return file disposition.
Definition: rpmfi.c:671
void rpmtsEmpty(rpmts ts)
Re-create an empty transaction set.
Definition: rpmts.c:623
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
FD_t rpmteFd(rpmte te)
Retrieve file handle from transaction element.
Definition: rpmte.c:561
struct rpmps_s * rpmps
Transaction problems found while processing a transaction set/.
Definition: rpmps.h:25
const char * rpmteN(rpmte te)
Retrieve name string of transaction element.
Definition: rpmte.c:316
int rpmdsNVRMatchesDep(const Header h, const rpmds req, int nopromote)
Compare package name-version-release from header with a single dependency.
Definition: rpmds.c:4262
fingerPrintCache fpCacheFree(fingerPrintCache cache)
Destroy finger print cache.
Definition: fprint.c:31
rpmfi rpmfiNew(const void *_ts, Header h, rpmTag tagN, int flags)
Create and load a file info set.
Definition: rpmfi.c:1403
static int rpmtsRunScript(rpmts ts, rpmTag stag)
Definition: transaction.c:1264
Header h
Definition: spec.c:739
rpmuint32_t rpmfiFColor(rpmfi fi)
Return current file color bits from file info set.
Definition: rpmfi.c:371
rpmuint32_t rpmtsGetTid(rpmts ts)
Get transaction id, i.e.
Definition: rpmts.c:1022
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
Command line option information.
Definition: rpmcli.h:630
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
int rpmdbRemove(rpmdb db, int rid, uint32_t hdrNum, rpmts ts)
Remove package header from rpm database and indices.
Definition: rpmdb.c:2772
unsigned char rpmuint8_t
Private int typedefs to avoid C99 portability issues.
Definition: rpmiotypes.h:26
void rpmtsSetCurrDir(rpmts ts, const char *currDir)
Set transaction currDir, i.e.
Definition: rpmts.c:960
const char * rpmteA(rpmte te)
Retrieve arch string of transaction element.
Definition: rpmte.c:345
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 rpmpsNumProblems(rpmps ps)
Return number of problems in set.
Definition: rpmps.c:70
exit Fhe p ptr
Definition: db3.c:2119
struct fingerPrint_s * rpmfiFpsIndex(rpmfi fi, int ix)
Definition: rpmfi.c:509
enum evrFlags_e evrFlags
Dependency Attributes.
int rpmtsiOc(rpmtsi tsi)
Return transaction element index.
Definition: rpmte.c:755
static rpmfi rpmtsiFi(const rpmtsi tsi)
Return transaction element&#39;s file info.
Definition: transaction.c:820
char * alloca()
enum rpmRC_e rpmRC
RPM return codes.
Definition: signature.c:616
int _rpmts_debug
Definition: rpmts.c:93
Yet Another syslog(3) API clone.
int rpmfiNextD(rpmfi fi)
Return next directory iterator index.
Definition: rpmfi.c:562
goto exit
Definition: db3.c:1903
void rpmtsCheckDSIProblems(const rpmts ts, const rpmte te)
Check a transaction element for disk space problems.
Definition: rpmts.c:1230
memset(_r, 0, sizeof(*_r))
size_t ns
Definition: db3.c:1892
enum rpmElementType_e rpmElementType
Transaction element type.
static PyObject *static PyObject *static PyObject *static PyObject *static PyObject *static PyObject *static PyObject *static PyObject *static PyObject *static PyObject *static PyObject *static PyObject *size_t dlen
Definition: rpmfi-py.c:246
unsigned int rpmuint32_t
Definition: rpmiotypes.h:28
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
void * xcalloc(size_t nmemb, size_t size)
Definition: rpmmalloc.c:300
assert(key->size==sizeof(hdrNum))
void * ptr
Definition: rpmtag.h:67
const char * rpmfiDN(rpmfi fi)
Return current directory name from file info set.
Definition: rpmfi.c:152
int ix
Definition: rpmps-py.c:174
char * p
Definition: macro.c:413
rpmmi rpmmiFree(rpmmi mi)
Destroy rpm database iterator.
static int rpmtsRepackage(rpmts ts, uint32_t numRemoved)
Definition: transaction.c:1924
fprintf(stderr,"--> %s(%p,%p,%p) sig %p sigp %p\n", __FUNCTION__, dig, t, rsactx, sig, sigp)
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
uint32_t hdrNum
Definition: db3.c:1889
enum rpmtsOpX_e rpmtsOpX
Indices for timestamps.
int argvCount(const ARGV_t argv)
Return no.
Definition: argv.c:71
rpmuint16_t rpmfiFMode(rpmfi fi)
Return current file mode from file info set.
Definition: rpmfi.c:265
rpmTagData p
Definition: rpmtag.h:504
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:2676
const char * tagName(rpmTag tag)
Return tag name from value.
Definition: tagname.c:436
void rpmswExit(op, 0)
rpmtransFlags transFlags
Definition: rpmcli.h:672
rpmuint32_t rbtid
Definition: rpmcli.h:676
enum pkgStage_e pkgStage
Header rpmmiNext(rpmmi mi)
Return next package header from iteration.
Definition: rpmdb.c:2248
struct _HE_s * HE_t
Destroy an extension cache.
Definition: rpmtag.h:59
rpmuint32_t rpmtsColor(rpmts ts)
Retrieve color bits of transaction set.
Definition: rpmts.c:1438
Structure(s) used for dependency tag sets.
static rpmps rpmtsSanityCheck(rpmts ts, uint32_t *tfcp)
Definition: transaction.c:1127
int headerGet(Header h, HE_t he, unsigned int flags)
Retrieve extension or tag value from a header.
Definition: header.c:2230
void * rpmtsNotify(rpmts ts, rpmte te, rpmCallbackType what, rpmuint64_t amount, rpmuint64_t total)
Perform transaction progress notify callback.
Definition: rpmts.c:1279
The FD_t File Handle data structure.
rpmpsm rpmpsmNew(rpmts ts, rpmte te, rpmfi fi)
Create and load a package state machine.
Definition: psm.c:1825
return k val
Definition: rpmmtree.c:401
int rpmRollback(rpmts ts, QVA_t ia, const char **argv)
Definition: rpmrollback.c:421
const char * rpmtsRootDir(rpmts ts)
Get transaction rootDir, i.e.
Definition: rpmts.c:901
rpmTagCount c
Definition: rpmtag.h:505
rpmpsi rpmpsInitIterator(rpmps ps)
Initialize problem set iterator.
Definition: rpmps.c:78
static const char * lang
Definition: iosm.h:32
int rpmdbCheckSignals(void)
Check for and exit on termination signals.
Definition: rpmdb.c:523
char * rpmExpand(const char *arg,...)
Return (malloc&#39;ed) concatenated macro expansion(s).
Definition: macro.c:3178
int Chdir(const char *path)
chdir(2) clone.
Definition: rpmrpc.c:105
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 &quot;finger print&quot;.
static int rpmtsFinish(rpmts ts, rpmsx sx)
Definition: transaction.c:1512
int rpmtsOpenDB(rpmts ts, int dbmode)
Open the database used by the transaction.
Definition: rpmts.c:115
rpmtsi rpmtsiFree(rpmtsi tsi)
Destroy transaction element iterator.
rpmte rpmtsElement(rpmts ts, int ix)
Return (ordered) transaction set element.
Definition: rpmts.c:1315
rpmRC rpmpsmStage(rpmpsm psm, pkgStage stage)
Package state machine driver.
Definition: psm.c:2197
rpmuint8_t * ui8p
Definition: rpmtag.h:68
* op
Definition: rpmps-py.c:266
pgpVSFlags rpmVSFlags
Bit(s) to control digest and signature verification.
Definition: rpmts.h:35
static rpmdc dc
Definition: rpmdigest.c:91
node fd
Definition: rpmfd-py.c:124
rpmInstallInterfaceFlags installInterfaceFlags
Definition: rpmcli.h:674
static rpmmi rpmtsFindBaseNamesInDB(rpmts ts, uint32_t fileCount)
Definition: transaction.c:909
int Fclose(FD_t fd)
fclose(3) clone.
Definition: rpmio.c:2532
static int rpmtsSetup(rpmts ts, rpmprobFilterFlags ignoreSet, rpmsx *sxp)
Definition: transaction.c:1401
int j
Definition: spec.c:743
char * n
Definition: macro.c:744
Cumulative statistics for an operation.
Definition: rpmsw.h:39
struct rpmsx_s * rpmsx
Definition: rpmsx.h:11
uint32_t rpmmiBNTag(rpmmi mi)
Return basename tag for current position of rpmdb iterator.
Definition: rpmdb.c:1752
static PyObject *s psi
Definition: rpmps-py.c:30
struct rpmds_s * rpmds
Dependency tag sets from a header, so that a header can be discarded early.
Definition: rpmtypes.h:28
rpmprobFilterFlags probFilter
Definition: rpmcli.h:673
Definition: rpmte.h:37
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
int rpmteIsSource(rpmte te)
Retrieve isSource attribute of transaction element.
Definition: rpmte.c:355
fts keys
Definition: rpmmtree.c:3666
rpmps rpmpsFree(rpmps ps)
Destroy a problem set.
rpmds rpmdsFree(rpmds ds)
Destroy a dependency set.
const char * rpmteD(rpmte te)
Retrieve distepoch string of transaction element.
Definition: rpmte.c:336
int rpmfiDC(rpmfi fi)
Return directory count from file info set.
Definition: rpmfi.c:92
rpmVSFlags rpmtsSetVSFlags(rpmts ts, rpmVSFlags vsflags)
Set verify signatures flag(s).
Definition: rpmts.c:843
#define IIF_SET(_iflags, _FLAG)
Definition: transaction.c:113
Definition: rpmtag.h:500
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:1313
struct rpmtsi_s * rpmtsi
Transaction element iterator.
Definition: rpmte.h:31
return strcmp(ame->name, bme->name)
void htAddEntry(hashTable ht, const void *key, const void *data)
Add item to hash table.
Definition: rpmhash.c:150
const char * s
Definition: poptALL.c:734
Package state machine to handle a package from a transaction set.
char * t
Definition: rpmds.c:2716
int rpmtsSELinuxEnabled(rpmts ts)
Get selinuxEnabled flag, i.e.
Definition: rpmts.c:997
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
const char * rpmteO(rpmte te)
Retrieve os string of transaction element.
Definition: rpmte.c:350
rpmfi rpmfiLink(rpmfi fi, const char *msg)
Reference a file info set instance.
const char * rpmfiFLink(rpmfi fi)
Return current file linkto (i.e.
Definition: rpmfi.c:317
Definition: iosm.h:29
enum rpmtransFlags_e rpmtransFlags
Bit(s) to control rpmtsRun() operation.
Methods to handle package elements.
const char * rpmteE(rpmte te)
Retrieve epoch string of transaction element.
Definition: rpmte.c:321
int rpmtsNElements(rpmts ts)
Return number of (ordered) transaction set elements.
Definition: rpmts.c:1306
struct fprintCache_s * fingerPrintCache
Definition: fprint.h:13
mi
Definition: rpmdb-py.c:159
int _fps_debug
Definition: transaction.c:232
char * stpcpy(char *dest, const char *src)
te
Definition: macro.c:552
rpmtransFlags rpmtsFlags(rpmts ts)
Get transaction flags, i.e.
Definition: rpmts.c:1332
ps
Definition: rpmts-py.c:548
rpmuint32_t rpmtsARBGoal(rpmts ts)
Return the autorollback goal.
Definition: rpmts.c:879
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 &quot;rpmts&quot; transaction set.
Definition: iosm.h:36
rpmRC rpmtsRollback(rpmts rbts, rpmprobFilterFlags ignoreSet, int running, rpmte rbte)
Rollback a failed transaction.
Definition: transaction.c:2025
s ignoreSet
Definition: rpmts-py.c:1217
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
rpmElementType rpmteType(rpmte te)
Retrieve type of transaction element.
Definition: rpmte.c:311
int no_rollback_links
Definition: rpmcli.h:681
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:1994
const unsigned char * rpmfiDigest(rpmfi fi, int *algop, size_t *lenp)
Return current file (binary) digest from file info set.
Definition: rpmfi.c:300
struct fprintCacheEntry_s * entry
Definition: fprint.h:52
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
return NULL
Definition: poptALL.c:613
const char * rpmtsCurrDir(rpmts ts)
Get transaction currDir, i.e.
Definition: rpmts.c:951
static int rpmtsMarkLinkedFailed(rpmts ts, rpmte p)
Mark all erasure elements linked to installed element p as failed.
Definition: transaction.c:864
int rpmdbOpenAll(rpmdb db)
Open all database indices.
Definition: rpmdb.c:787
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
static void
Print copy of spec file, filling in Group/Description/Summary from specspo.
Definition: spec.c:737
int rpmtsSetChrootDone(rpmts ts, int chrootDone)
Set chrootDone flag, i.e.
Definition: rpmts.c:1010
rpmuint32_t hashFunctionString(rpmuint32_t h, const void *data, size_t size)
Return hash value of a string.
Definition: rpmhash.c:83
k
Definition: rpmmtree.c:394
static int ensureOlder(rpmts ts, const rpmte p, const Header h)
Ensure that current package is newer than installed package.
Definition: transaction.c:520
#define _(Text)
Definition: system.h:29
const char * rpmteNEVR(rpmte te)
Retrieve name-version-release string from transaction element.
Definition: rpmte.c:536
int rpmteFailed(rpmte te)
Definition: rpmte.c:945
int
Save source and expand field into target.
Definition: rpmds.c:2709
struct rpmfi_s * rpmfi
File info tag sets from a header, so that a header can be discarded early.
Definition: rpmfi.h:83
#define xmalloc
Definition: system.h:32
const char * rpmteR(rpmte te)
Retrieve release string of transaction element.
Definition: rpmte.c:331
rpmuint32_t rpmtsPrefColor(rpmts ts)
Retrieve preferred file color.
Definition: rpmts.c:1453
fnpyKey rpmteKey(rpmte te)
Retrieve key from transaction element.
Definition: rpmte.c:568
ARGstr_t * ARGV_t
Definition: argv.h:12
Access RPM indices using Berkeley DB interface(s).
void rpmswEnter(op, 0)
#define TSF_CLR(_tsflags, _FLAG)
Definition: transaction.c:110
#define D_(Text)
Definition: system.h:526
int rpmteDBOffset(rpmte te)
Retrieve rpmdb instance of TR_REMOVED transaction element.
Definition: rpmte.c:531
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
rpmVSFlags vsflags
Definition: rpmrepo.c:161
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
rpmdepFlags rpmtsDFlags(rpmts ts)
Get dependency flags, i.e.
Definition: rpmts.c:1361
rpmmi rpmtsInitIterator(const rpmts ts, rpmTag rpmtag, const void *keyp, size_t keylen)
Return transaction database iterator.
Definition: rpmts.c:212
static void * _free(const void *p)
Wrapper to free(3), hides const compilation noise, permit NULL, return NULL.
Definition: rpmiotypes.h:647
#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:1763
int i
Definition: spec.c:743
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:3252
#define xrealloc
Definition: system.h:35
size_t fn
Definition: macro.c:1698
int rpmmiSort(rpmmi mi)
Sort iterator instances.
Definition: rpmdb.c:2416
rpmtsi rpmtsiInit(rpmts ts)
Create transaction element iterator.
int len
Definition: rpmdb-py.c:119
rpmmi rpmmiInit(rpmdb db, rpmTag tag, const void *keyp, size_t keylen)
Return database iterator.
Definition: rpmdb.c:2491
rpmps rpmtsProblems(rpmts ts)
Return current transaction set problems.
Definition: rpmts.c:582
fingerPrintCache fpCacheCreate(int sizeHint)
Create finger print cache.
Definition: fprint.c:21
void rpmpsmSetAsync(rpmpsm psm, int async)
Definition: psm.c:1750
const unsigned char * digest
Definition: rpmfi-py.c:247
#define FPSDEBUG(_debug, _list)
Definition: transaction.c:233
int Unlink(const char *path)
unlink(2) clone.
Definition: rpmrpc.c:397