01f4073b632720fa659f5c771cef511cb2f06716
[platform/upstream/rpm.git] / lib / trb.c
1 #include "system.h"
2 #include "rpmcli.h"
3 #include "misc.h"
4
5 #include "debug.h"
6
7 #define UP2DATEGLOB     "/var/spool/up2date/*.rpm"
8
9 #ifdef  DYING
10 static int XrpmRollback(struct rpmInstallArguments_s * ia, const char ** argv)
11 {
12     rpmdb db = NULL;
13     rpmTransactionSet ts = NULL;
14     rpmProblemSet probs = NULL;
15     IDTX itids = NULL;
16     IDTX rtids = NULL;
17     unsigned thistid = 0xffffffff;
18     unsigned prevtid;
19     time_t tid;
20     IDT rp;
21     IDT ip;
22     int rc;
23
24     if (argv != NULL && *argv != NULL) {
25         rc = -1;
26         goto exit;
27     }
28
29     rc = rpmdbOpen(ia->rootdir, &db, O_RDWR, 0644);
30     if (rc != 0)
31         goto exit;
32
33     itids = IDTXload(db, RPMTAG_INSTALLTID);
34     ip = (itids != NULL && itids->nidt > 0) ? itids->idt : NULL;
35
36     {   const char * globstr = rpmExpand("%{_repackage_dir}/*.rpm", NULL);
37         if (globstr == NULL || *globstr == '%') {
38             globstr = _free(globstr);
39             rc = -1;
40             goto exit;
41         }
42         rtids = IDTXglob(globstr, RPMTAG_REMOVETID);
43         rp = (rtids != NULL && rtids->nidt > 0) ? rtids->idt : NULL;
44         globstr = _free(globstr);
45     }
46
47     /* Run transactions until rollback goal is achieved. */
48     do {
49         prevtid = thistid;
50         rc = 0;
51         packagesTotal = 0;
52
53         /* Find larger of the remaining install/erase transaction id's. */
54         thistid = 0;
55         if (ip != NULL && ip->val.u32 > thistid)
56             thistid = ip->val.u32;
57         if (rp != NULL && rp->val.u32 > thistid)
58             thistid = rp->val.u32;
59
60         /* If we've achieved the rollback goal, then we're done. */
61         if (thistid == 0 || thistid < ia->rbtid)
62             break;
63
64         ts = rpmtransCreateSet(db, ia->rootdir);
65
66         /* Install the previously erased packages for this transaction. */
67         while (rp != NULL && rp->val.u32 == thistid) {
68
69             rpmMessage(RPMMESS_DEBUG, "\t+++ %s\n", rp->key);
70
71             rc = rpmtransAddPackage(ts, rp->h, NULL, rp->key,
72                         (ia->installInterfaceFlags & INSTALL_UPGRADE) != 0,
73                         ia->relocations);
74             if (rc != 0)
75                 goto exit;
76
77             packagesTotal++;
78
79             rp->h = headerFree(rp->h);
80             rtids->nidt--;
81             if (rtids->nidt > 0)
82                 rp++;
83             else
84                 rp = NULL;
85         }
86
87         /* Erase the previously installed packages for this transaction. */
88         while (ip != NULL && ip->val.u32 == thistid) {
89
90             rpmMessage(RPMMESS_DEBUG,
91                         "\t--- rpmdb instance #%u\n", ip->instance);
92
93             rc = rpmtransRemovePackage(ts, ip->instance);
94             if (rc != 0)
95                 goto exit;
96
97             packagesTotal++;
98
99             ip->instance = 0;
100             itids->nidt--;
101             if (itids->nidt > 0)
102                 ip++;
103             else
104                 ip = NULL;
105         }
106
107         /* Anything to do? */
108         if (packagesTotal <= 0)
109             break;
110
111         tid = (time_t)thistid;
112         rpmMessage(RPMMESS_DEBUG, _("rollback %d packages to %s"),
113                         packagesTotal, ctime(&tid));
114
115         rc = rpmdepOrder(ts);
116         if (rc != 0)
117             goto exit;
118
119         probs = NULL;
120         rc = rpmRunTransactions(ts,  rpmShowProgress,
121                 (void *) ((long)ia->installInterfaceFlags),
122                 NULL, &probs, ia->transFlags,
123                 (ia->probFilter|RPMPROB_FILTER_OLDPACKAGE));
124         if (rc > 0) {
125             rpmProblemSetPrint(stderr, probs);
126             goto exit;
127         }
128
129         if (probs != NULL) {
130             rpmProblemSetFree(probs);
131             probs = NULL;
132         }
133         ts = rpmtransFree(ts);
134
135     } while (1);
136
137 exit:
138     if (probs != NULL) {
139         rpmProblemSetFree(probs);
140         probs = NULL;
141     }
142     ts = rpmtransFree(ts);
143
144     if (db != NULL) (void) rpmdbClose(db);
145
146     rtids = IDTXfree(rtids);
147     itids = IDTXfree(itids);
148
149     return rc;
150 }
151 #endif
152
153 static struct poptOption optionsTable[] = {
154  { "verbose", 'v', 0, 0, 'v',
155         N_("provide more detailed output"), NULL},
156  { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmInstallPoptTable, 0,
157         N_("Install/Upgrade/Erase options:"),
158         NULL },
159    POPT_AUTOHELP
160    POPT_TABLEEND
161 };
162
163 int
164 main(int argc, const char *argv[])
165 {
166     poptContext optCon;
167     struct rpmInstallArguments_s * ia = &rpmIArgs;
168     int arg;
169     int ec = 0;
170
171 #if HAVE_MCHECK_H && HAVE_MTRACE
172     mtrace();   /* Trace malloc only if MALLOC_TRACE=mtrace-output-file. */
173 #endif
174     setprogname(argv[0]);       /* Retrofit glibc __progname */
175
176     /* set up the correct locale */
177     (void) setlocale(LC_ALL, "" );
178
179     bindtextdomain(PACKAGE, LOCALEDIR);
180     textdomain(PACKAGE);
181
182     rpmSetVerbosity(RPMMESS_NORMAL);
183
184     optCon = poptGetContext(argv[0], argc, argv, optionsTable, 0);
185     (void) poptReadConfigFile(optCon, LIBRPMALIAS_FILENAME);
186     (void) poptReadDefaultConfig(optCon, 1);
187     poptSetExecPath(optCon, RPMCONFIGDIR, 1);
188
189     while ((arg = poptGetNextOpt(optCon)) > 0) {
190         switch(arg) {
191         case 'v':
192             rpmIncreaseVerbosity();
193             break;
194         default:
195             break;
196         }
197     }
198
199     if (ia->rbtid == 0) {
200         fprintf(stderr, "--rollback <timestamp> is required\n");
201         exit(1);
202     }
203
204     if (rpmReadConfigFiles(NULL, NULL))
205         exit(1);
206
207     ec = rpmRollback(ia, NULL);
208
209     optCon = poptFreeContext(optCon);
210     rpmFreeMacros(NULL);
211
212 #if HAVE_MCHECK_H && HAVE_MTRACE
213     muntrace();   /* Trace malloc only if MALLOC_TRACE=mtrace-output-file. */
214 #endif
215
216     return ec;
217 }