source: trunk/gsinstaller/gsManifest.cpp@ 1475

Last change on this file since 1475 was 1475, checked in by cs025, 24 years ago

Updated sources with most of uninstall added

  • Property svn:keywords set to Author Date Id Revision
File size: 7.2 KB
Line 
1#include "gsManifest.h"
2
3#include <string.h>
4#include <stdio.h>
5
6#include <windows.h>
7
8gsManifest::gsManifest(installManager &manager)
9 : installAgent(manager)
10{ // do nothing!
11}
12
13gsManifest::gsManifest(installManager &manager, FilePath &root)
14 : installAgent(manager), fileCopyMonitor()
15{ this->getManifest(root);
16 this->expandGroups();
17}
18
19bool gsManifest::getManifest(FilePath &root)
20{ FilePath *manifestPath = new FilePath((char *) root.cString(), "manifest.cfg");
21 FILE * file;
22 DWORD fileSize;
23 string currentgroup;
24 char * buffer;
25 char * line;
26 char * eol;
27
28 // open file handle for read access
29 file = fopen(manifestPath->cString(), "rb");
30 if (file == NULL)
31 { return false;
32 }
33
34 // get size of file
35 File f(manifestPath->cString());
36 fileSize = f.getFileSize();
37
38 // allocate buffer for whole file and read it in
39 buffer = new char[fileSize];
40 if (fread(buffer, 1, fileSize, file) < fileSize)
41 { // TODO: error handling
42 }
43 fclose(file);
44
45 //parse file into lines and send to the line fn
46 line = buffer;
47 while ((eol = strchr(line, '\x0a')) != NULL) // use 0a for the eol to remove
48 // dependency on dos 0d,0a eol
49 { *eol = '\0';
50
51 this->getManifestLine(line, currentgroup);
52
53 line = eol + 1;
54 }
55 this->getManifestLine(line, currentgroup);
56
57 delete buffer;
58 return true;
59}
60
61bool gsManifest::getManifestLine(char *line, string &group)
62{ char *eol; // we (potentially) need to clean up the end of
63 // line, and we won't use the eol from the main
64 // getManifest fn. as for the last line it'd be
65 // null.
66
67 // clean up the start of the line
68 while (*line <= ' ' && *line != '\0')
69 { line ++;
70 }
71
72 // it's a blank line - don't bother!
73 if (line == '\0')
74 { return true;
75 }
76
77 // clean up the end of line
78 eol = line + strlen(line) - 1;
79 while (*eol <= ' ' && eol >= line)
80 { *eol = '\0';
81 eol --;
82 }
83
84 // does the line end with a colon?; if so take it as a group definition
85 if (*eol == ':')
86 { if (eol == line) // if it's literally just a colon do nothing
87 { return true;
88 }
89
90 // note the new group name
91 string newgroup(line, 0, eol - line);
92 group = newgroup;
93 }
94 // if it starts with a hash it's just a comment line; skip it
95 else if (*line == '#')
96 { // do nothing!
97 }
98 // an actual line of member items; read them in
99 else
100 { stringArray array;
101 array = stringArray::words(line);
102
103 if (group.length() == 0)
104 { this->manifests["all"].add(array);
105 }
106 else
107 { this->manifests[group].add(array);
108 }
109 }
110 return true;
111}
112
113/**
114 * Expand all groups
115 */
116void gsManifest::expandGroups()
117{ strArrayMap::iterator here = this->manifests.begin();
118 strArrayMap::iterator end = this->manifests.end();
119
120 while (here != end)
121 { this->expandGroup((*here).first);
122 here ++;
123 }
124}
125
126/**
127 * expand a particular group
128 */
129void gsManifest::expandGroup(string &group)
130{ stringArray &array = this->manifests[group];
131
132 unsigned int i = 0;
133 while (i < array.size())
134 { if (this->isGroup(array[i]))
135 { this->expandGroupInstance(group, array[i]);
136 }
137 else
138 { i ++;
139 }
140 }
141}
142
143/**
144 * expand a group instance inside a given group
145 */
146void gsManifest::expandGroupInstance(string parentgroup, string groupName)
147{ // remove the group instance from the parent
148 this->manifests[parentgroup].remove(groupName);
149
150 // create a "clean" name without the { } brackets
151 string group(groupName, 1, groupName.length() - 2);
152
153 // circular reference - we're kind and ignore it!!
154 if (parentgroup.compare(group) == 0)
155 { return;
156 }
157
158 // lookup chidl group and add it to the parent
159 this->manifests[parentgroup].add(this->manifests[group]);
160}
161
162/**
163 * Check if a member of a group is itself a group - look for { } brackets
164 * around the name
165 */
166bool gsManifest::isGroup(string &name)
167{ if (name[0] == '{' && name[name.length()-1] == '}')
168 { return true;
169 }
170 return false;
171}
172
173void gsManifest::expandMacro(string macro, string value)
174{ string macroRef = "\$(" + macro + ")";
175
176 strArrayMap::iterator here = this->manifests.begin();
177 strArrayMap::iterator end = this->manifests.end();
178
179 while (here != end)
180 { stringArray &array = this->manifests[(*here).first];
181
182 unsigned int i = 0;
183 while (i < array.size())
184 { unsigned int pos;
185 while ((pos = array[i].find(macroRef)) < array[i].length() && pos != -1)
186 { array[i].replace(pos, macroRef.length(), value);
187 }
188 i ++;
189 }
190 here ++;
191 }
192}
193
194void gsManifest::clearSelection()
195{ this->selected.empty();
196}
197
198void gsManifest::selectGroup(string groupName, FilePath &destination)
199{ stringArray &groupArray = this->manifests[groupName];
200
201 groupArray = this->manifests[groupName];
202 this->selected[destination].add(groupArray);
203}
204
205/**
206 * Copy the manifest
207 */
208bool gsManifest::copy(FilePath *source)
209{ fileCopier copy(this);
210
211 pathStringArrayMap::iterator here = this->selected.begin();
212 pathStringArrayMap::iterator end = this->selected.end();
213
214 // add all the sets to copy to the manifest
215 while (here != end)
216 { FileVector *fileList;
217 stringArray &array = (*here).second;
218 FilePath path((*here).first);
219
220 // TODO: eliminate inefficiency; we're doing FilePath->string->FilePath in
221 // effect between constructing the copy lists, and then the sets, as far
222 // as the destinations go
223 fileList = this->selection(*source, array);
224 fileCopySet copySet(*fileList, *source, path);
225 copy.addSet(copySet);
226 delete fileList;
227 here ++;
228 }
229
230 // check that we've got enough space @ the destination(s)
231 if (!copy.checkSpace())
232 { return false;
233 }
234
235 // do the actual copying
236 copy.copy();
237 return true;
238}
239
240void gsManifest::copied(string from, string to, bool isDir)
241{ if (isDir)
242 { this->logAction("Manifest.CreateDir", to);
243 }
244 else
245 { this->logAction("Manifest.CopyFile", from, to);
246 }
247}
248
249void gsManifest::logAction(string actionName, string file)
250{ manager->writeString(actionName);
251 manager->writeSeparator();
252 manager->writeString(file);
253 manager->writeString("\n");
254}
255
256void gsManifest::logAction(string actionName, string source, string dest)
257{ manager->writeString(actionName);
258 manager->writeSeparator();
259 manager->writeString(source);
260 manager->writeSeparator();
261 manager->writeString(dest);
262 manager->writeString("\n");
263}
264
265bool gsManifest::undoAction(string actionName, stringArray &params)
266{ if (actionName == "Manifest.CreateDir" || actionName == "CreateDir")
267 { RemoveDirectory(params[0].c_str());
268 return true;
269 }
270 else if (actionName == "Manifest.CopyFile" || actionName == "CopyFile")
271 { DeleteFile(params[1].c_str());
272 return true;
273 }
274 return false;
275}
276
277FileVector *gsManifest::selection(FilePath &root, stringArray &array)
278{ FileVector *reply = new FileVector();
279
280 for (unsigned int i = 0; i < array.size(); i++)
281 { FilePath fileName(root.pathString(), array[i]);
282 File file(fileName.pathString());
283 reply->push_back(file);
284 }
285 return reply;
286}
287
288FileVector *gsManifest::selection(FilePath &source, FilePath &destination)
289{ return this->selection(source, this->selected[destination]);
290}
291
Note: See TracBrowser for help on using the repository browser.