e2341545b40b87c37a6f6116fdece3bf9b7a3c89
[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       //cout << "RPMCALLBACK_TRANS_PROGRESS " << amount << " " << total << endl << flush;
89    case RPMCALLBACK_INST_PROGRESS:
90       //cout << "RPMCALLBACK_INST_PROGRESS " << amount << " " << total << endl << flush;
91       Prog->Progress(amount);
92       break;
93
94    case RPMCALLBACK_TRANS_START:
95       //cout << "RPMCALLBACK_TRANS_START " << amount << " " << total << endl << flush;
96       state = what;
97       repackage = false;
98       Prog->SetState(InstProgress::Preparing);
99       Prog->SubProgress(total, "Preparing");
100       Prog->SetPackageData(&Data);
101    break;
102
103    case RPMCALLBACK_TRANS_STOP:
104       Prog->Done();
105       break;
106
107    case RPMCALLBACK_REPACKAGE_START:
108       repackage = true;
109       Prog->OverallProgress(0,1,1, "Repackaging");
110       Prog->SetState(InstProgress::Repackaging);
111       break;
112
113    case RPMCALLBACK_REPACKAGE_PROGRESS:
114       Prog->Progress(amount);
115       break;
116
117    case RPMCALLBACK_REPACKAGE_STOP:
118       repackage = false;
119       break;
120
121    case RPMCALLBACK_UNINST_PROGRESS:
122       break;
123
124    case RPMCALLBACK_UNINST_START:
125       if (h == NULL) {
126          cout << "uninst start, header null ;(" << endl;
127          break;
128       }
129       if (state != what) {
130          state = what;
131          Prog->SetState(InstProgress::Removing);
132          Prog->OverallProgress(0,1,1, "Removing");
133       }
134       getPackageData(h, Data);
135       Prog->SubProgress(total, Data["name"]);
136       Prog->Progress(total);
137       break;
138
139    case RPMCALLBACK_UNINST_STOP:
140       Prog->Progress(total);
141       if (h == NULL)
142          break;
143       getPackageData(h, Data);
144       break;
145    default: // Fall through
146       break;
147  
148    }
149    return rc;
150 }       
151
152 // vim:sts=3:sw=3