PackageManager
[reactos.git] / rosapps / packmgr / lib / package.cpp
1 ////////////////////////////////////////////////////////
2 //
3 // package.cpp
4 //
5 // package related functions
6 //
7 //
8 // Maarten Bosma, 09.01.2004
9 // maarten.paul@bosma.de
10 //
11 ////////////////////////////////////////////////////////////////////
12
13 #include "package.hpp"
14 #include "expat.h"
15 #include "log.h"
16
17 int PML_XmlDownload (const char* url, void* usrdata, XML_StartElementHandler start,
18 XML_EndElementHandler end, XML_CharacterDataHandler text=0);
19
20
21 // expat callback for start of a package tag
22 void pack_start (void* usrdata, const char* tag, const char** arg)
23 {
24 int i, id;
25 PACKAGE* pack = (PACKAGE*)usrdata;
26
27 // if the tag is a script tag ...
28 if(!strcmp(tag, "scripts"))
29 {
30 // ... read the arguments
31 for (i=0; arg[i]; i+=2)
32 {
33 if(!strcmp(arg[i], "inst"))
34 id = 0;
35
36 else if(!strcmp(arg[i], "update"))
37 id = 1;
38
39 else if(!strcmp(arg[i], "uinst"))
40 id = 2;
41
42 else if(!strcmp(arg[i], "srcinst"))
43 id = 3;
44
45 else
46 continue;
47
48 pack->files[id] = new char [strlen(arg[i+1])+1];
49 strcpy(pack->files[id], arg[i+1]);
50 }
51 }
52
53 // ... save the field
54 else
55 {
56 if(!strcmp(tag, "name"))
57 pack->field = &pack->name;
58
59 else if(!strcmp(tag, "description"))
60 pack->field = &pack->description;
61 }
62 }
63
64 // expat callback for end of a package tag
65 void pack_end (void* usrdata, const char* tag)
66 {
67 PACKAGE* pack = (PACKAGE*)usrdata;
68
69 pack->field = NULL;
70 }
71
72 // expat callback for text
73 void pack_text (void* usrdata, const char* data, int len)
74 {
75 PACKAGE* pack = (PACKAGE*)usrdata;
76
77 if(!pack->field)
78 return;
79
80 *pack->field = new char[len+1];
81 strncpy(*pack->field, data, len);
82 (*pack->field)[len] = '\0';
83 }
84
85
86 // The user clicks on a package
87 extern "C" int PML_LoadPackage (TREE* tree, int id, PML_SetButton SetButton)
88 {
89 PACKAGE* pack = &tree->packages[id];
90 tree->setButton = SetButton;
91
92 if(SetButton)
93 {
94 SetButton(1, pack->action);
95 SetButton(2, pack->inst); // && pack->action != 0
96 SetButton(3, pack->src_inst);
97 SetButton(4, pack->update);
98 SetButton(5, pack->uninstall);
99 }
100
101 // root notes (like network) return here
102 if(!pack->path)
103 return 1;
104
105 if(!pack->loaded)
106 {
107 PML_XmlDownload (pack->path, (void*)pack, pack_start, pack_end, pack_text);
108 pack->loaded = TRUE;
109 }
110
111 return ERR_OK;
112 }
113
114 extern "C" int PML_FindItem (TREE* tree, const char* what)
115 {
116 int i, j;
117 bool found;
118
119 // if we have children, same action for them
120 for (i=1; (UINT)i<tree->packages.size(); i++)
121 {
122 found = true;
123
124 for(j=0; (UINT)j<strlen(what); j++)
125 {
126 if(tolower(what[j]) != tolower(tree->packages[i].name[j]))
127 {
128 found = false;
129 break;
130 }
131 }
132
133 if(found)
134 return i;
135 }
136
137 return 0;
138 }
139
140 // The user chooses a actions like Install
141 extern "C" int PML_SetAction (TREE* tree, int id, int action, PML_SetIcon SetIcon)
142 {
143 UINT i;
144 int ret = ERR_OK;
145
146 tree->setIcon = SetIcon;
147 PACKAGE* pack = &tree->packages[id];
148
149 // if we have children, same action for them
150 for (i=0; i<pack->children.size(); i++)
151 ret = ret || PML_SetAction(tree, pack->children[i], action, SetIcon);
152
153 // is the action possible ?
154 if(!pack->actions[action])
155 return ERR_GENERIC;
156
157 // is it already set
158 if(pack->action == action)
159 return ERR_OK;
160
161 // set the icon
162 if(!pack->icon)
163 if(SetIcon)
164 SetIcon(id, action);
165
166 // can't do src install yet
167 if(action == 2)
168 {
169 MessageBox(0, L"Sorry, but source install is not implemented yet.", 0,0);
170 return ERR_OK;
171 }
172
173 // everything but undoing is done here
174 else if (action != 0)
175 {
176 // since we are setting a action we undo it again
177 if(tree->setButton)
178 tree->setButton(1, 1);
179 //tree->setButton(action+1, 0);
180 pack->action = action;
181
182 // root notes (like network) return here
183 if(!pack->path)
184 return ret;
185
186 // load it if it's not loaded yet
187 if(!pack->loaded)
188 {
189 PML_XmlDownload (pack->path, (void*)pack, pack_start, pack_end, pack_text);
190 pack->loaded = TRUE;
191 }
192
193 // save the name of the corresponding script in a vector
194 tree->todo.push_back(pack->files[action-1]);
195 }
196
197 // undoing
198 else
199 {
200 // set other things back
201 if(tree->setButton)
202 tree->setButton(1, 0);
203 //tree->setButton(pack->action+1, 1);
204 pack->action = 0;
205
206 // root notes (like network) return here
207 if(!pack->path || pack->action==0)
208 return ret;
209
210 // erase from todo list
211 for(i=0; i<tree->todo.size(); i++)
212 if(!strcmp(tree->todo[i], pack->files[pack->action-1])) // look for right entry
213 tree->todo.erase(tree->todo.begin()+i); // delete it
214
215 return ERR_OK;
216 }
217
218 return ret;
219 }
220
221 //
222 extern "C" char* PML_GetDescription (TREE* tree, int id)
223 {
224 PML_LoadPackage(tree, id, NULL);
225
226 return tree->packages[id].description;
227 }
228