5a09022fb96b2b65f35491dcfbf6f5dc8898900b
[apt.git] / apt-pkg / rpm / rpmshowprogress.cc
1
2 #include <stdio.h>
3 #include <rpm/rpmlib.h>
4 #include <apti18n.h>
5
6 #include "rpmshowprogress.h"
7
8 static int hashesTotal = 0;
9 static int hashesCurrent = 0;
10 static int progressCurrent = 0;
11 static int progressTotal = 0;
12
13 int packagesTotal;
14
15 static void printHash(const unsigned long amount, const unsigned long total)
16 {
17     int hashesNeeded;
18
19     hashesTotal = (isatty (STDOUT_FILENO) ? 44 : 50);
20
21     if (hashesCurrent != hashesTotal) {
22         float pct = (total ? (((float) amount) / total) : 1.0);
23         hashesNeeded = (int) ((hashesTotal * pct) + 0.5);
24         while (hashesNeeded > hashesCurrent) {
25             if (isatty (STDOUT_FILENO)) {
26                 int i;
27                 for (i = 0; i < hashesCurrent; i++)
28                     (void) putchar ('#');
29                 for (; i < hashesTotal; i++)
30                     (void) putchar (' ');
31                 fprintf(stdout, "(%3d%%)", (int)((100 * pct) + 0.5));
32                 for (i = 0; i < (hashesTotal + 6); i++)
33                     (void) putchar ('\b');
34             } else
35                 fprintf(stdout, "#");
36
37             hashesCurrent++;
38         }
39         (void) fflush(stdout);
40
41         if (hashesCurrent == hashesTotal) {
42             int i;
43             progressCurrent++;
44             if (isatty(STDOUT_FILENO)) {
45                 for (i = 1; i < hashesCurrent; i++)
46                     (void) putchar ('#');
47                 pct = (progressTotal
48                     ? (((float) progressCurrent) / progressTotal)
49                     : 1);
50                 fprintf(stdout, " [%3d%%]", (int)((100 * pct) + 0.5));
51             }
52             fprintf(stdout, "\n");
53         }
54         (void) fflush(stdout);
55     }
56 }
57
58 #if RPM_VERSION < 0x040000
59 void * rpmpmShowProgress(const Header h,
60 #else
61 void * rpmpmShowProgress(const void * arg, 
62 #endif
63                         const rpmCallbackType what,
64                         const unsigned long amount,
65                         const unsigned long total,
66                         const void * pkgKey, void * data)
67 {
68 #if RPM_VERSION >= 0x040000
69     Header h = (Header) arg;
70 #endif
71
72     char * s;
73     int flags = (int) ((long)data);
74     void * rc = NULL;
75     const char * filename = (const char *) pkgKey;
76     static FD_t fd = NULL;
77     static rpmCallbackType state;
78
79     switch (what) {
80     case RPMCALLBACK_INST_OPEN_FILE:
81         if (filename == NULL || filename[0] == '\0')
82             return NULL;
83         fd = Fopen(filename, "r.ufdio");
84         if (fd)
85             fd = fdLink(fd, "persist (showProgress)");
86         return fd;
87         /*@notreached@*/ break;
88
89     case RPMCALLBACK_INST_CLOSE_FILE:
90         fd = fdFree(fd, "persist (showProgress)");
91         if (fd) {
92             (void) Fclose(fd);
93             fd = NULL;
94         }
95         break;
96
97     case RPMCALLBACK_INST_START:
98         hashesCurrent = 0;
99         if (h == NULL || !(flags & INSTALL_LABEL))
100             break;
101
102         if (state != what) {
103             state = what;
104             fprintf(stdout, "%s\n", _("Installing / Updating..."));
105             (void) fflush(stdout);
106         }
107
108         if (flags & INSTALL_HASH) {
109             s = headerSprintf(h, "%{NAME}.%{ARCH}",
110                                 rpmTagTable, rpmHeaderFormats, NULL);
111             if (isatty (STDOUT_FILENO))
112                 fprintf(stdout, "%4d:%-23.23s", progressCurrent + 1, s);
113             else
114                 fprintf(stdout, "%-28.28s", s);
115             (void) fflush(stdout);
116             free(s);
117             s = NULL;
118         } else {
119             s = headerSprintf(h, "%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}",
120                                   rpmTagTable, rpmHeaderFormats, NULL);
121             fprintf(stdout, "%s\n", s);
122             (void) fflush(stdout);
123             free(s);
124             s = NULL;
125         }
126         break;
127
128     case RPMCALLBACK_TRANS_PROGRESS:
129     case RPMCALLBACK_INST_PROGRESS:
130         if (flags & INSTALL_PERCENT)
131             fprintf(stdout, "%%%% %f\n", (double) (total
132                                 ? ((((float) amount) / total) * 100)
133                                 : 100.0));
134         else if (flags & INSTALL_HASH)
135             printHash(amount, total);
136         (void) fflush(stdout);
137         break;
138
139     case RPMCALLBACK_TRANS_START:
140         state = what;
141         hashesCurrent = 0;
142         progressTotal = 1;
143         progressCurrent = 0;
144         if (!(flags & INSTALL_LABEL))
145             break;
146         if (flags & INSTALL_HASH)
147             fprintf(stdout, "%-28s", _("Preparing..."));
148         else
149             fprintf(stdout, "%s\n", _("Preparing..."));
150         (void) fflush(stdout);
151         break;
152
153     case RPMCALLBACK_TRANS_STOP:
154         if (flags & INSTALL_HASH)
155             printHash(1, 1);    /* Fixes "preparing..." progress bar */
156         progressTotal = packagesTotal;
157         progressCurrent = 0;
158         break;
159
160     case RPMCALLBACK_REPACKAGE_START:
161         hashesCurrent = 0;
162         progressTotal = total;
163         progressCurrent = 0;
164         if (!(flags & INSTALL_LABEL))
165             break;
166         if (flags & INSTALL_HASH)
167             fprintf(stdout, "%-28s\n", _("Repackaging..."));
168         else
169             fprintf(stdout, "%s\n", _("Repackaging..."));
170         (void) fflush(stdout);
171         break;
172
173     case RPMCALLBACK_REPACKAGE_PROGRESS:
174         if (amount && (flags & INSTALL_HASH))
175             printHash(1, 1);    /* Fixes "preparing..." progress bar */
176         break;
177
178     case RPMCALLBACK_REPACKAGE_STOP:
179         progressTotal = total;
180         progressCurrent = total;
181         if (flags & INSTALL_HASH)
182             printHash(1, 1);    /* Fixes "preparing..." progress bar */
183         progressTotal = packagesTotal;
184         progressCurrent = 0;
185         if (!(flags & INSTALL_LABEL))
186             break;
187         if (flags & INSTALL_HASH)
188             fprintf(stdout, "%-28s\n", _("Upgrading..."));
189         else
190             fprintf(stdout, "%s\n", _("Upgrading..."));
191         (void) fflush(stdout);
192         break;
193
194     case RPMCALLBACK_UNINST_PROGRESS:
195         break;
196     case RPMCALLBACK_UNINST_START:
197         hashesCurrent = 0;
198         if (!(flags & INSTALL_LABEL))
199             break;
200         if (state != what) {
201             state = what;
202             fprintf(stdout, "%s\n", _("Removing / Cleaning up..."));
203             (void) fflush(stdout);
204         }
205         break;
206
207     case RPMCALLBACK_UNINST_STOP:
208         if (h == NULL || !(flags & INSTALL_LABEL))
209             break;
210         s = headerSprintf(h, "%{NAME}.%{ARCH}", rpmTagTable, rpmHeaderFormats, NULL);
211         if (flags & INSTALL_HASH) {
212             fprintf(stdout, "%4d:%-23.23s", progressCurrent + 1, s);
213             printHash(1, 1);
214         } else {
215             fprintf(stdout, "%-28.28s", s);
216         }
217         fflush(stdout);
218         s = NULL;
219         break;
220     default: // Fall through
221         break;
222     }
223  
224     return rc;
225 }       
226