rpm  5.4.15
rpmrollback.c
Go to the documentation of this file.
1 
5 #include "system.h"
6 
7 #include <rpmio.h>
8 #include <rpmiotypes.h>
9 #include <rpmcb.h>
10 #include <argv.h>
11 
12 #include <rpmtypes.h>
13 #include <rpmtag.h>
14 #include <pkgio.h>
15 #include <rpmdb.h>
16 
17 #include <rpmds.h>
18 #include "manifest.h"
19 #include "misc.h" /* XXX rpmGlob() */
20 
21 #define _RPMTE_INTERNAL /* XXX findErases needs rpmte internals. */
22 #define _RPMTS_INTERNAL /* XXX ts->teErase, ts->probs */
23 #define _RPMTS_PRINT
24 #include <rpmgi.h> /* XXX rpmgiEscapeSpaces */
25 
26 #include <rpmcli.h>
27 #define _RPMROLLBACK_INTERNAL
28 #include <rpmrollback.h>
29 
30 #include "debug.h"
31 
32 /*@access FD_t @*/ /* XXX void * arg */
33 /*@access rpmts @*/
34 /*@access rpmte @*/ /* XXX p->hdrid, p->pkgid, p->NEVRA */
35 /*@access IDTX @*/
36 /*@access IDT @*/
37 
38 #ifdef __cplusplus
39 
40 #define QVA_ISSET(_qvaflags, _FLAG) ((_qvaflags) & (VERIFY_##_FLAG))
41 
42 #define VSF_ISSET(_vsflags, _FLAG) ((_vsflags) & (RPMVSF_##_FLAG))
43 #define VSF_SET(_vsflags, _FLAG) \
44  (*((unsigned *)&(_vsflags)) |= (RPMVSF_##_FLAG))
45 #define VSF_CLR(_vsflags, _FLAG) \
46  (*((unsigned *)&(_vsflags)) &= ~(RPMVSF_##_FLAG))
47 
48 GENfree(IDTX)
49 GENfree(IDT)
50 
51 #else /* __cplusplus */
52 
53 #define QVA_ISSET(_qvaflags, _FLAG) ((_qvaflags) & (VERIFY_##_FLAG))
54 
55 #define VSF_ISSET(_vsflags, _FLAG) ((_vsflags) & (RPMVSF_##_FLAG))
56 #define VSF_SET(_vsflags, _FLAG) (_vsflags) |= (RPMVSF_##_FLAG)
57 #define VSF_CLR(_vsflags, _FLAG) (_vsflags) &= ~(RPMVSF_##_FLAG)
58 
59 #endif /* __cplusplus */
60 
61 /*@unchecked@*/
62 static int reverse = -1;
63 
66 static int IDTintcmp(const void * a, const void * b)
67  /*@*/
68 {
69  /*@-castexpose@*/
70  return ( reverse * (((IDT)a)->val.u32 - ((IDT)b)->val.u32) );
71  /*@=castexpose@*/
72 }
73 
75 {
76  if (idtx) {
77  int i;
78  if (idtx->idt)
79  for (i = 0; i < idtx->nidt; i++) {
80  IDT idt = idtx->idt + i;
81  (void)headerFree(idt->h);
82  idt->h = NULL;
83  idt->key = _free(idt->key);
84  }
85  idtx->idt = _free(idtx->idt);
86  idtx = _free(idtx);
87  }
88  return NULL;
89 }
90 
92 {
93  IDTX idtx = (IDTX) xcalloc(1, sizeof(*idtx));
94  idtx->delta = 10;
95  idtx->size = (int)sizeof(*((IDT)0));
96  return idtx;
97 }
98 
99 IDTX IDTXgrow(IDTX idtx, int need)
100 {
101  if (need < 0) return NULL;
102  if (idtx == NULL)
103  idtx = IDTXnew();
104  if (need == 0) return idtx;
105 
106  if ((idtx->nidt + need) > idtx->alloced) {
107  while (need > 0) {
108  idtx->alloced += idtx->delta;
109  need -= idtx->delta;
110  }
111  idtx->idt = (IDT) xrealloc(idtx->idt, (idtx->alloced * idtx->size));
112  }
113  return idtx;
114 }
115 
117 {
118  if (idtx != NULL && idtx->idt != NULL && idtx->nidt > 0)
119  qsort(idtx->idt, idtx->nidt, idtx->size, IDTintcmp);
120  return idtx;
121 }
122 
124 {
125  HE_t he = (HE_t) memset(alloca(sizeof(*he)), 0, sizeof(*he));
126  IDTX idtx = NULL;
127  rpmmi mi;
128  Header h;
129  rpmuint32_t tid;
130  int xx;
131 
132  mi = rpmtsInitIterator(ts, tag, NULL, 0);
133 #ifdef NOTYET
134  (void) rpmmiAddPattern(mi, RPMTAG_NAME, RPMMIRE_DEFAULT, '!gpg-pubkey');
135 #endif
136  while ((h = rpmmiNext(mi)) != NULL) {
137  he->tag = tag;
138  xx = headerGet(h, he, 0);
139  if (!xx || he->p.ui32p == NULL)
140  continue;
141  tid = (he->p.ui32p ? he->p.ui32p[0] : 0);
142  he->p.ptr = _free(he->p.ptr);
143 
144  if (tid == 0 || tid == 0xffffffff)
145  continue;
146 
147  /* Don't bother with headers installed prior to the rollback goal. */
148  if (tid < rbtid)
149  continue;
150 
151  idtx = IDTXgrow(idtx, 1);
152  if (idtx == NULL || idtx->idt == NULL)
153  continue;
154 
155  { IDT idt;
156  /*@-nullderef@*/
157  idt = idtx->idt + idtx->nidt;
158  /*@=nullderef@*/
159  idt->done = 0;
160  idt->h = headerLink(h);
161  idt->key = NULL;
162  idt->instance = rpmmiInstance(mi);
163  idt->val.u32 = tid;
164  }
165  idtx->nidt++;
166  }
167  mi = rpmmiFree(mi);
168 
169  return IDTXsort(idtx);
170 }
171 
172 IDTX IDTXglob(rpmts ts, const char * globstr, rpmTag tag, rpmuint32_t rbtid)
173 {
174  HE_t he = (HE_t) memset(alloca(sizeof(*he)), 0, sizeof(*he));
175  IDTX idtx = NULL;
176  Header h;
177  rpmuint32_t tid;
178  FD_t fd;
179  const char ** av = NULL;
180  const char * fn;
181  int ac = 0;
182  rpmRC rpmrc;
183  int xx;
184  int i;
185 
186  av = NULL; ac = 0;
187  fn = rpmgiEscapeSpaces(globstr);
188  xx = rpmGlob(fn, &ac, &av);
189  fn = _free(fn);
190 
191  if (xx == 0)
192  for (i = 0; i < ac; i++) {
193  int isSource;
194 
195  fd = Fopen(av[i], "r.fdio");
196  if (fd == NULL || Ferror(fd)) {
197  rpmlog(RPMLOG_ERR, _("open of %s failed: %s\n"), av[i],
198  Fstrerror(fd));
199  if (fd != NULL) (void) Fclose(fd);
200  continue;
201  }
202 
203  rpmrc = rpmReadPackageFile(ts, fd, av[i], &h);
204  (void) Fclose(fd);
205  switch (rpmrc) {
206  default:
207  goto bottom;
208  /*@notreached@*/ /*@switchbreak@*/ break;
209  case RPMRC_NOTTRUSTED:
210  case RPMRC_NOKEY:
211  case RPMRC_OK:
212  isSource =
213  (headerIsEntry(h, RPMTAG_SOURCERPM) == 0 &&
214  headerIsEntry(h, RPMTAG_ARCH) != 0);
215  if (isSource)
216  goto bottom;
217  /*@switchbreak@*/ break;
218  }
219 
220 { const char * origin = headerGetOrigin(h);
221 assert(origin != NULL);
222 assert(!strcmp(av[i], origin));
223 }
224  he->tag = tag;
225  xx = headerGet(h, he, 0);
226  if (!xx || he->p.ui32p == NULL)
227  goto bottom;
228  tid = (he->p.ui32p ? he->p.ui32p[0] : 0);
229  he->p.ptr = _free(he->p.ptr);
230 
231  /* Don't bother with headers installed prior to the rollback goal. */
232  if (tid < rbtid)
233  goto bottom;
234 
235  idtx = IDTXgrow(idtx, 1);
236  if (idtx == NULL || idtx->idt == NULL)
237  goto bottom;
238 
239  { IDT idt;
240  idt = idtx->idt + idtx->nidt;
241  idt->done = 0;
242  idt->h = headerLink(h);
243  idt->key = av[i];
244  av[i] = NULL;
245  idt->instance = 0;
246  idt->val.u32 = tid;
247  }
248  idtx->nidt++;
249 bottom:
250  (void)headerFree(h);
251  h = NULL;
252  }
253 
254  for (i = 0; i < ac; i++)
255  av[i] = _free(av[i]);
256  av = _free(av); ac = 0;
257 
258  return IDTXsort(idtx);
259 }
260 
270 static int cmpArgvStr(rpmts ts, const char *lname, const char ** AV, int AC,
271  /*@null@*/ const char * B)
272  /*@modifies ts @*/
273 {
274  const char * A;
275  int i;
276 
277  if (AV != NULL && AC > 0 && B == NULL) {
278  if (!strcmp(lname, "NEVRA")) {
279  rpmps ps = rpmtsProblems(ts);
280  for (i = 0; i < AC && (A = AV[i]) != NULL; i++) {
282  NULL, NULL, /* NEVRA, key */
283  lname, NULL, /* dn, bn */
284  A, /* altNEVRA */
285  0);
286  }
287  ps = rpmpsFree(ps);
288  }
289  return 0;
290  }
291 
292  if (AV != NULL && B != NULL)
293  for (i = 0; i < AC && (A = AV[i]) != NULL; i++) {
294  if (*A && *B && !strcmp(A, B))
295  return 1;
296  }
297  return 0;
298 }
299 
315 static int findErases(rpmts ts, /*@null@*/ rpmte p, unsigned thistid,
316  /*@null@*/ IDT ip, int niids)
317  /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
318  /*@modifies ts, p, ip, rpmGlobalMacroContext, fileSystem, internalState @*/
319 {
320  HE_t he = (HE_t) memset(alloca(sizeof(*he)), 0, sizeof(*he));
321  int rc = 0;
322  int xx;
323 
324  /* Erase the previously installed packages for this transaction.
325  * Provided this transaction is not excluded from the rollback.
326  */
327  while (ip != NULL && ip->val.u32 == thistid) {
328 
329  if (ip->done)
330  goto bottom;
331 
332  {
333  const char ** flinkPkgid = NULL;
334  const char ** flinkHdrid = NULL;
335  const char ** flinkNEVRA = NULL;
336  rpmuint32_t pn, hn, nn;
337  int bingo;
338 
339  he->tag = RPMTAG_BLINKPKGID;
340  xx = headerGet(ip->h, he, 0);
341  flinkPkgid = he->p.argv;
342  pn = he->c;
343 
344  /* XXX Always erase packages at beginning of upgrade chain. */
345  if (pn == 1 && flinkPkgid[0] != NULL && !strcmp(flinkPkgid[0], RPMTE_CHAIN_END)) {
346  flinkPkgid = _free(flinkPkgid);
347  goto erase;
348  }
349 
350  he->tag = RPMTAG_BLINKHDRID;
351  xx = headerGet(ip->h, he, 0);
352  flinkHdrid = he->p.argv;
353  hn = he->c;
354  he->tag = RPMTAG_BLINKNEVRA;
355  xx = headerGet(ip->h, he, 0);
356  flinkNEVRA = he->p.argv;
357  nn = he->c;
358 
359  /*
360  * Link data may be missing and can have multiple entries.
361  */
362  /* XXX Until link tags are reliably populated, check in the order
363  * NEVRA -> hdrid -> pkgid
364  * because NEVRA is easier to debug (hdrid/pkgid are more precise.)
365  */
366  bingo = 0;
367  if (!bingo)
368  bingo = cmpArgvStr(ts, "NEVRA", flinkNEVRA, nn, (p ? p->NEVRA : NULL));
369  if (!bingo)
370  bingo = cmpArgvStr(ts, "Hdrid", flinkHdrid, hn, (p ? p->hdrid : NULL));
371 /*@-nullstate@*/
372  if (!bingo)
373  bingo = cmpArgvStr(ts, "Pkgid", flinkPkgid, pn, (p ? p->pkgid : NULL));
374 /*@=nullstate@*/
375  flinkPkgid = _free(flinkPkgid);
376  flinkHdrid = _free(flinkHdrid);
377  flinkNEVRA = _free(flinkNEVRA);
378 
379  if (bingo < 0) {
380  rc = -1;
381  goto exit;
382  }
383 
384  if (!bingo)
385  goto bottom;
386  }
387 
388 erase:
389  rpmlog(RPMLOG_DEBUG, D_("\t--- erase h#%u\n"), ip->instance);
390 
391  rc = rpmtsAddEraseElement(ts, ip->h, ip->instance);
392  if (rc != 0)
393  goto exit;
394 
395  /* Cross link the transaction elements to mimic --upgrade. */
396  if (p != NULL) {
397  rpmte q = ts->teErase;
398  xx = rpmteChain(p, q, ip->h, "Rollback");
399  }
400 
401 #ifdef NOTYET
402  ip->instance = 0;
403 #endif
404  ip->done = 1;
405 
406 bottom:
407 
408  /* Go to the next header in the rpmdb */
409  niids--;
410  if (niids > 0)
411  ip++;
412  else
413  ip = NULL;
414  }
415 
416 exit:
417  return rc;
418 }
419 
421 int rpmRollback(rpmts ts, QVA_t ia, const char ** argv)
422 {
424  unsigned thistid = 0xffffffff;
425  unsigned prevtid;
426  time_t tid;
427  IDTX itids = NULL;
428  IDTX rtids = NULL;
429  IDT rp;
430  int nrids = 0;
431  IDT ip;
432  int niids = 0;
433  int rc = 0;
434  rpmVSFlags vsflags, ovsflags;
435  int numAdded;
436  int numRemoved;
437  unsigned int _unsafe_rollbacks = 0;
438  rpmtransFlags transFlags = ia->transFlags;
439  rpmdepFlags depFlags = ia->depFlags;
440  int xx;
441 
442  if (argv != NULL && *argv != NULL) {
443  rc = -1;
444  goto exit;
445  }
446 
447  _unsafe_rollbacks = rpmExpandNumeric("%{?_unsafe_rollbacks}");
448 
449  vsflags = (rpmVSFlags) rpmExpandNumeric("%{?_vsflags_erase}");
450  vsflags = (rpmVSFlags) 0; /* XXX FIXME: ignore default disablers. */
451 #if defined(SUPPORT_NOSIGNATURES)
452  if (!QVA_ISSET(ia->qva_flags, DIGEST)) {
453  VSF_SET(vsflags, NOSHA1HEADER);
454  VSF_SET(vsflags, NOMD5HEADER);
455  VSF_SET(vsflags, NOSHA1);
456  VSF_SET(vsflags, NOMD5);
457  }
458  if (!QVA_ISSET(ia->qva_flags, SIGNATURE)) {
459  VSF_SET(vsflags, NODSAHEADER);
460  VSF_SET(vsflags, NORSAHEADER);
461  VSF_SET(vsflags, NODSA);
462  VSF_SET(vsflags, NORSA);
463  }
464  if (!QVA_ISSET(ia->qva_flags, HDRCHK)) {
465  VSF_SET(vsflags, NOHDRCHK);
466  }
467  VSF_SET(vsflags, NEEDPAYLOAD); /* XXX needed? */
468 #endif
469  ovsflags = rpmtsSetVSFlags(ts, vsflags);
470 
471  (void) rpmtsSetFlags(ts, transFlags);
472  (void) rpmtsSetDFlags(ts, depFlags);
473 
474  /* Make the transaction a rollback transaction. In a rollback
475  * a best effort is what we want
476  */
478 
479  itids = IDTXload(ts, RPMTAG_INSTALLTID, ia->rbtid);
480  if (itids != NULL) {
481  ip = itids->idt;
482  niids = itids->nidt;
483  } else {
484  ip = NULL;
485  niids = 0;
486  }
487 
488  { const char * globstr = rpmExpand("%{_repackage_dir}/*/*.rpm", NULL);
489  if (globstr == NULL || *globstr == '%') {
490  globstr = _free(globstr);
491  rc = -1;
492  goto exit;
493  }
494  rtids = IDTXglob(ts, globstr, RPMTAG_REMOVETID, ia->rbtid);
495 
496  if (rtids != NULL) {
497  rp = rtids->idt;
498  nrids = rtids->nidt;
499  } else {
500  rp = NULL;
501  nrids = 0;
502  }
503  globstr = _free(globstr);
504  }
505 
506  { int notifyFlags;
507  notifyFlags = ia->installInterfaceFlags | (rpmIsVerbose() ? INSTALL_LABEL : 0 );
508  xx = rpmtsSetNotifyCallback(ts,
509  rpmShowProgress, (void *) ((long)notifyFlags));
510  }
511 
512  /* Run transactions until rollback goal is achieved. */
513  do {
514  prevtid = thistid;
515  rc = 0;
517  numAdded = 0;
518  numRemoved = 0;
520  (ia->installInterfaceFlags & ~ifmask);
521 
522  /* Find larger of the remaining install/erase transaction id's. */
523  thistid = 0;
524  if (ip != NULL && ip->val.u32 > thistid)
525  thistid = ip->val.u32;
526  if (rp != NULL && rp->val.u32 > thistid)
527  thistid = rp->val.u32;
528 
529  /* If we've achieved the rollback goal, then we're done. */
530  if (thistid == 0 || thistid < ia->rbtid)
531  break;
532 
533  /* If we've reached the (configured) rollback goal, then we're done. */
534  if (_unsafe_rollbacks && thistid <= _unsafe_rollbacks)
535  break;
536 
537  /* Is this transaction excluded from the rollback? */
538  if (ia->rbtidExcludes != NULL && ia->numrbtidExcludes > 0)
539  {
540  rpmuint32_t *excludedTID;
541  int excluded = 0;
542  for(excludedTID = ia->rbtidExcludes;
543  excludedTID < ia->rbtidExcludes + ia->numrbtidExcludes;
544  excludedTID++) {
545  if (thistid == *excludedTID) {
546  time_t ttid = (time_t)thistid;
548  _("Excluding TID from rollback: %-24.24s (0x%08x)\n"),
549  ctime(&ttid), thistid);
550  excluded = 1;
551  /*@innerbreak@*/ break;
552  }
553  }
554  if (excluded) {
555  /* Iterate over repackaged packages */
556  while (rp != NULL && rp->val.u32 == thistid) {
557  /* Go to the next repackaged package */
558  nrids--;
559  if (nrids > 0)
560  rp++;
561  else
562  rp = NULL;
563  }
564  /* Iterate over installed packages */
565  while (ip != NULL && ip->val.u32 == thistid) {
566  /* Go to the next header in the rpmdb */
567  niids--;
568  if (niids > 0)
569  ip++;
570  else
571  ip = NULL;
572  }
573  continue; /* with next transaction */
574  }
575  }
576 
577  rpmtsEmpty(ts);
578  (void) rpmtsSetFlags(ts, transFlags);
579  (void) rpmtsSetDFlags(ts, depFlags);
580  ts->probs = rpmpsFree(ts->probs);
581 
582  /* Install the previously erased packages for this transaction.
583  */
584  while (rp != NULL && rp->val.u32 == thistid) {
585  if (!rp->done) {
586  rpmlog(RPMLOG_DEBUG, D_("\t+++ install %s\n"),
587  (rp->key ? rp->key : "???"));
588 
589 /*@-abstract@*/
590  rc = rpmtsAddInstallElement(ts, rp->h, (fnpyKey)rp->key,
591  0, ia->relocations);
592 /*@=abstract@*/
593  if (rc != 0)
594  goto exit;
595 
596  numAdded++;
598  if (!(ia->installInterfaceFlags & ifmask))
601 
602  /* Re-add linked (i.e. from upgrade/obsoletes) erasures. */
603  rc = findErases(ts, ts->teInstall, thistid, ip, niids);
604  if (rc < 0)
605  goto exit;
606 #ifdef NOTYET
607  (void)headerFree(rp->h);
608  rpm->h = NULL;
609 #endif
610  rp->done = 1;
611  }
612 
613  /* Go to the next repackaged package */
614  nrids--;
615  if (nrids > 0)
616  rp++;
617  else
618  rp = NULL;
619  }
620 
621  /* Re-add pure (i.e. not from upgrade/obsoletes) erasures. */
622  rc = findErases(ts, NULL, thistid, ip, niids);
623  if (rc < 0)
624  goto exit;
625 
626  /* Check that all erasures have been re-added. */
627  while (ip != NULL && ip->val.u32 == thistid) {
628 #ifdef NOTNOW
629 /* XXX Prevent incomplete rollback transactions. */
630 assert(ip->done || ia->no_rollback_links);
631 #endif
632  if (!(ip->done || ia->no_rollback_links)) {
633  numRemoved++;
634 
635  if (_unsafe_rollbacks != 0)
637 
638  if (!(ia->installInterfaceFlags & ifmask))
641  }
642 
643  /* Go to the next header in the rpmdb */
644  niids--;
645  if (niids > 0)
646  ip++;
647  else
648  ip = NULL;
649  }
650 
651  /* Print any rollback transaction problems */
652  xx = rpmcliInstallProblems(ts, _("Missing re-packaged package(s)"), 1);
653 
654  /* Anything to do? */
655  if (rpmcliPackagesTotal <= 0)
656  break;
657 
658  tid = (time_t)thistid;
660  _("Rollback packages (+%d/-%d) to %-24.24s (0x%08x):\n"),
661  numAdded, numRemoved, ctime(&tid), thistid);
662 
663  rc = (ia->rbCheck ? (*ia->rbCheck) (ts) : 0);
664  if (rc != 0)
665  goto exit;
666 
667  rc = (ia->rbOrder ? (*ia->rbOrder) (ts) : 0);
668  if (rc != 0)
669  goto exit;
670 
671  /* Drop added/available package indices and dependency sets. */
672  rpmtsClean(ts);
673 
674  /* Print the transaction set. */
675  xx = rpmtsPrint(ts, stdout);
676 
677  rc = (ia->rbRun
679  : 0);
680  if (rc != 0)
681  goto exit;
682 
683  /* Remove repackaged packages after successful reinstall. */
684  if (rtids && !rpmIsDebug()) {
685  int i;
686  rpmlog(RPMLOG_NOTICE, _("Cleaning up repackaged packages:\n"));
687  if (rtids->idt)
688  for (i = 0; i < rtids->nidt; i++) {
689  IDT rrp = rtids->idt + i;
690  if (rrp->val.u32 != thistid)
691  /*@innercontinue@*/ continue;
692  if (rrp->key) { /* XXX can't happen */
693  rpmlog(RPMLOG_NOTICE, _("\tRemoving %s:\n"), rrp->key);
694  (void) unlink(rrp->key); /* XXX: Should check rc??? */
695  }
696  }
697  }
698 
699  /* The rpmdb has changed, so reload installed package chains. */
700  itids = IDTXfree(itids);
701  itids = IDTXload(ts, RPMTAG_INSTALLTID, ia->rbtid);
702  if (itids != NULL) {
703  ip = itids->idt;
704  niids = itids->nidt;
705  } else {
706  ip = NULL;
707  niids = 0;
708  }
709 
710  /* Re-position the iterator at the current install tid. */
711  while (ip != NULL && ip->val.u32 == thistid) {
712  /* Go to the next header in the rpmdb */
713  niids--;
714  if (niids > 0)
715  ip++;
716  else
717  ip = NULL;
718  }
719 
720  } while (1);
721 
722 exit:
723  rtids = IDTXfree(rtids);
724  itids = IDTXfree(itids);
725 
726  rpmtsEmpty(ts);
727  (void) rpmtsSetFlags(ts, transFlags);
728  (void) rpmtsSetDFlags(ts, depFlags);
729 
730  return rc;
731 }
rpmRelocation relocations
Definition: rpmcli.h:683
const bson * b
Definition: bson.h:280
struct IDTindex_s * IDTX
Definition: rpmrollback.h:17
int rpmteChain(rpmte p, rpmte q, Header oh, const char *msg)
Chain p <-> q forward/backward transaction element links.
Definition: rpmte.c:682
rpmTag tag
Definition: rpmtag.h:503
const char ** argv
Definition: rpmtag.h:75
rpmdepFlags depFlags
Definition: rpmcli.h:671
int headerIsEntry(Header h, rpmTag tag)
Check if tag is in header.
Definition: header.c:1439
const char bson_timestamp_t * ts
Definition: bson.h:1004
static int cmpArgvStr(rpmts ts, const char *lname, const char **AV, int AC, const char *B)
Search for string B in argv array AV.
Definition: rpmrollback.c:270
enum rpmInstallInterfaceFlags_e rpmInstallInterfaceFlags
Bit(s) to control rpmcliInstall() and rpmErase() operation.
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
uint32_t rpmmiInstance(rpmmi mi)
Return header instance for current position of rpmdb iterator.
Definition: rpmdb.c:1747
rpmuint32_t * ui32p
Definition: rpmtag.h:70
FD_t Fopen(const char *path, const char *_fmode)
fopen(3) clone.
Definition: rpmio.c:2840
int rpmtsAddInstallElement(rpmts ts, Header h, fnpyKey key, int upgrade, rpmRelocation relocs)
Add package to be installed to transaction set.
Definition: depends.c:547
struct IDT_s * IDT
Definition: rpmrollback.h:13
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:2231
IDTX IDTXglob(rpmts ts, const char *globstr, rpmTag tag, rpmuint32_t rbtid)
Load tag (instance,value) pairs from packages, and return sorted id index.
Definition: rpmrollback.c:172
The Header data structure.
rpmQueryFlags qva_flags
Definition: rpmcli.h:633
static rpmVSFlags vsflags
Definition: rpmcache.c:547
Definition: rpmdb.c:436
int rpmtsSetNotifyCallback(rpmts ts, rpmCallbackFunction notify, rpmCallbackData notifyData)
Set transaction notify callback function and argument.
Definition: rpmts.c:1460
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:25
const char * rpmgiEscapeSpaces(const char *s)
Escape isspace(3) characters in string.
Definition: rpmgi.c:364
Command line option information.
Definition: rpmcli.h:630
void * rpmShowProgress(const void *arg, const rpmCallbackType what, const rpmuint64_t amount, const rpmuint64_t total, fnpyKey key, void *data)
The rpm CLI generic transaction callback handler.
Definition: rpminstall.c:126
struct rpmte_s * rpmte
An element of a transaction set, i.e.
Definition: rpmtypes.h:38
int numrbtidExcludes
Definition: rpmcli.h:678
char * alloca()
rpmtransFlags rpmtsSetFlags(rpmts ts, rpmtransFlags transFlags)
Set transaction flags, i.e.
Definition: rpmts.c:1347
int rpmGlob(const char *patterns, int *argcPtr, const char ***argvPtr)
Return URL path(s) from a (URL prefixed) pattern glob.
Definition: macro.c:2611
unsigned int rpmuint32_t
Definition: rpmiotypes.h:28
struct _HE_s * HE_t
Definition: rpmtag.h:59
const char * Fstrerror(FD_t fd)
strerror(3) clone.
Definition: rpmio.c:2401
void * xcalloc(size_t nmemb, size_t size)
Definition: rpmmalloc.c:300
void * ptr
Definition: rpmtag.h:67
static int reverse
Definition: rpmrollback.c:62
int rpmcliInstallProblems(rpmts ts, const char *msg, int rc)
Report package problems (if any).
Definition: rpminstall.c:311
IDTX IDTXgrow(IDTX idtx, int need)
Insure that index has room for "need" elements.
Definition: rpmrollback.c:99
rpmTagData p
Definition: rpmtag.h:506
enum rpmdepFlags_e rpmdepFlags
Bit(s) to control rpmtsCheck() and rpmtsOrder() operation.
rpmtransFlags transFlags
Definition: rpmcli.h:672
rpmuint32_t rbtid
Definition: rpmcli.h:676
Routines to expand a manifest containing glob expressions into an argv list.
rpmRC rpmReadPackageFile(rpmts ts, FD_t fd, const char *fn, Header *hdrp)
Return package header from file handle, verifying digests/signatures.
Definition: package.c:114
Structure(s) used for dependency tag sets.
#define QVA_ISSET(_qvaflags, _FLAG)
Definition: rpmrollback.c:53
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
int rpmRollback(rpmts ts, QVA_t ia, const char **argv)
Rollback transactions, erasing new, reinstalling old, package(s).
Definition: rpmrollback.c:421
rpmTagCount c
Definition: rpmtag.h:507
pgpVSFlags rpmVSFlags
Bit(s) to control digest and signature verification.
Definition: rpmts.h:35
Header headerFree(Header h)
Dereference a header instance.
char * rpmExpand(const char *arg,...)
Return (malloc'ed) concatenated macro expansion(s).
Definition: macro.c:3252
const char * headerGetOrigin(Header h)
Return header origin (e.g path or URL).
Definition: header.c:1184
rpmuint32_t * rbtidExcludes
Definition: rpmcli.h:677
void rpmtsSetType(rpmts ts, rpmTSType type)
Set transaction type.
Definition: rpmts.c:875
IDTX IDTXfree(IDTX idtx)
Destroy id index.
Definition: rpmrollback.c:74
rpmInstallInterfaceFlags installInterfaceFlags
Definition: rpmcli.h:674
rpmmi rpmmiFree(rpmmi mi)
Destroy rpm database iterator.
int Fclose(FD_t fd)
fclose(3) clone.
Definition: rpmio.c:2534
rpmprobFilterFlags probFilter
Definition: rpmcli.h:673
rpmps rpmpsFree(rpmps ps)
Destroy a problem set.
Header headerLink(Header h)
Reference a header instance.
IDTX IDTXload(rpmts ts, rpmTag tag, rpmuint32_t rbtid)
Load tag (instance,value) pairs from rpm databse, and return sorted id index.
Definition: rpmrollback.c:123
IDTX IDTXsort(IDTX idtx)
Sort tag (instance,value) pairs.
Definition: rpmrollback.c:116
enum rpmRC_e rpmRC
RPM return codes.
int Ferror(FD_t fd)
ferror(3) clone.
Definition: rpmio.c:2951
int rpmmiAddPattern(rpmmi mi, rpmTag tag, rpmMireMode mode, const char *pattern)
Add pattern to iterator selector.
Definition: rpmdb.c:1910
Definition: rpmtag.h:502
const char const int i
Definition: bson.h:778
rpmdepFlags rpmtsSetDFlags(rpmts ts, rpmdepFlags depFlags)
Set dependency flags, i.e.
Definition: rpmts.c:1368
Methods to handle package elements.
rpmps rpmtsProblems(rpmts ts)
Return current transaction set problems.
Definition: rpmts.c:584
enum rpmtransFlags_e rpmtransFlags
Bit(s) to control rpmtsRun() operation.
static int IDTintcmp(const void *a, const void *b)
Definition: rpmrollback.c:66
rpmVSFlags rpmtsSetVSFlags(rpmts ts, rpmVSFlags vsflags)
Set verify signatures flag(s).
Definition: rpmts.c:845
struct rpmts_s * rpmts
The RPM Transaction Set.
Definition: rpmtypes.h:14
static void * _free(const void *p)
Wrapper to free(3), hides const compilation noise, permit NULL, return NULL.
Definition: rpmiotypes.h:756
const void * fnpyKey
Definition: rpmiotypes.h:134
Header rpmmiNext(rpmmi mi)
Return next package header from iteration.
Definition: rpmdb.c:2252
int rpmcliPackagesTotal
Definition: rpminstall.c:63
int rpmtsAddEraseElement(rpmts ts, Header h, uint32_t hdrNum)
Add package to be erased to transaction set.
Definition: depends.c:834
int no_rollback_links
Definition: rpmcli.h:681
int(* rbOrder)(rpmts ts)
Definition: rpmcli.h:691
#define rpmIsVerbose()
Definition: rpmcb.h:21
int(* rbCheck)(rpmts ts)
Definition: rpmcli.h:690
#define rpmIsDebug()
Definition: rpmcb.h:23
#define _(Text)
Definition: system.h:29
#define VSF_SET(_vsflags, _FLAG)
Definition: rpmrollback.c:56
Access RPM indices using Berkeley DB interface(s).
enum rpmTag_e rpmTag
Definition: rpmtag.h:470
#define D_(Text)
Definition: system.h:526
IDTX IDTXnew(void)
Create id index.
Definition: rpmrollback.c:91
int rpmExpandNumeric(const char *arg)
Return macro expansion as a numeric value.
Definition: macro.c:3326
#define xrealloc
Definition: system.h:35
void rpmtsEmpty(rpmts ts)
Re-create an empty transaction set.
Definition: rpmts.c:625
void rpmtsClean(rpmts ts)
Free memory needed only for dependency checks and ordering.
Definition: rpmts.c:598
int(* rbRun)(rpmts ts, rpmps okProbs, rpmprobFilterFlags ignoreSet)
Definition: rpmcli.h:692
static int findErases(rpmts ts, rpmte p, unsigned thistid, IDT ip, int niids)
Find (and add to transaction set) all erase elements with matching blink.
Definition: rpmrollback.c:315
#define RPMTE_CHAIN_END
Definition: rpmte.h:722