11c68bc686bf0baa3a7f5ff2e552e1642aee07ca
[apt.git] / apt-pkg / rpm / rpmcallback.cc
1 #include <map>
2 #include <stdio.h>
3 #include <rpm/rpmlib.h>
4 #include <apti18n.h>
5
6 #include <apt-pkg/progress.h>
7 #include "rpmcallback.h"
8
9 #include <iostream>
10 using namespace std;
11
12 static char *copyTags[] = {"name", 
13                            "version", 
14                            "release", 
15                            "arch", 
16                            "summary", 
17                            NULL};
18
19 static void getPackageData(const Header h, map<string,string> &Data)
20 {
21    char **Tag = &copyTags[0];
22    char rTag[20];
23    Data.clear();
24    for (Tag = &copyTags[0]; *Tag != NULL; *Tag++) {
25       sprintf(rTag, "%{%s}", *Tag);
26       char *s = headerSprintf(h, rTag, rpmTagTable, rpmHeaderFormats, NULL);
27       Data[*Tag] = s;
28       free(s);
29    }
30
31 }
32
33 #if RPM_VERSION < 0x040000
34 void * rpmCallback(const Header h,
35 #else
36 void * rpmCallback(const void * arg, 
37 #endif
38                    const rpmCallbackType what,
39                    const rpmCallbackSize_t amount,
40                    const rpmCallbackSize_t total,
41                    const void * pkgKey, void * data)
42
43 {
44 #if RPM_VERSION >= 0x040000
45    Header h = (Header) arg;
46 #endif
47
48    char * s;
49    InstProgress *Prog = (InstProgress*)data;
50    void * rc = NULL;
51    const char * filename = (const char *) pkgKey;
52    static FD_t fd = NULL;
53    static rpmCallbackType state;
54    static bool repackage;
55    static map<string,string> Data;
56
57    switch (what) {
58    case RPMCALLBACK_INST_OPEN_FILE:
59       if (filename == NULL || filename[0] == '\0')
60          return NULL;
61       fd = Fopen(filename, "r.ufdio");
62       if (fd)
63          fd = fdLink(fd, "persist (showProgress)");
64       return fd;
65       break;
66
67    case RPMCALLBACK_INST_CLOSE_FILE:
68       fd = fdFree(fd, "persist (showProgress)");
69       if (fd) {
70          (void) Fclose(fd);
71          fd = NULL;
72       }
73       break;
74
75    case RPMCALLBACK_INST_START:
76       if (state != what && repackage == false) {
77          state = what;
78          Prog->OverallProgress(0,1,1, "Installing");
79          Prog->SetState(InstProgress::Installing);
80       }
81
82       getPackageData(h, Data);
83       Prog->SubProgress(total, Data["name"]);
84       Prog->Progress(amount);
85       break;
86
87    case RPMCALLBACK_TRANS_PROGRESS:
88    case RPMCALLBACK_INST_PROGRESS:
89       Prog->Progress(amount);
90       break;
91
92    case RPMCALLBACK_TRANS_START:
93       state = what;
94       repackage = false;
95       Prog->SetState(InstProgress::Preparing);
96       Prog->SubProgress(total, "Preparing");
97       Prog->Progress(0);
98       Prog->SetPackageData(&Data);
99    break;
100
101    case RPMCALLBACK_TRANS_STOP:
102       Prog->Done();
103       break;
104
105    case RPMCALLBACK_REPACKAGE_START:
106       repackage = true;
107       Prog->OverallProgress(0,1,1, "Repackaging");
108       Prog->SetState(InstProgress::Repackaging);
109       break;
110
111    case RPMCALLBACK_REPACKAGE_PROGRESS:
112       Prog->Progress(amount);
113       break;
114
115    case RPMCALLBACK_REPACKAGE_STOP:
116       repackage = false;
117       break;
118
119    case RPMCALLBACK_UNINST_PROGRESS:
120       break;
121
122    case RPMCALLBACK_UNINST_START:
123       if (state != what) {
124          state = what;
125          Prog->OverallProgress(0,1,1, "Removing");
126          Prog->SetState(InstProgress::Removing);
127       }
128       if (h == NULL) {
129          break;
130       }
131       getPackageData(h, Data);
132       Prog->SubProgress(100, Data["name"]);
133       Prog->Progress(0);
134       break;
135
136    case RPMCALLBACK_UNINST_STOP:
137       Prog->Progress(100);
138       if (h == NULL)
139          break;
140       getPackageData(h, Data);
141       break;
142    default: // Fall through
143       break;
144  
145    }
146    return rc;
147 }       
148
149 // vim:sts=3:sw=3