source: trunk/gsinstaller/unInstall.cpp@ 3177

Last change on this file since 3177 was 2532, checked in by cs025, 23 years ago

Added better reporting of installation.

  • Property svn:keywords set to Author Date Id Revision
File size: 7.4 KB
Line 
1#include "unInstall.h"
2
3#include <stdio.h>
4#include <stdarg.h>
5#include "File.h"
6
7bool installManager::logExists()
8{
9 HANDLE fHandle;
10
11 fHandle = CreateFile(this->logfileName.c_str(), GENERIC_READ | GENERIC_WRITE,
12 FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
13 FILE_ATTRIBUTE_NORMAL, NULL);
14 if (fHandle == INVALID_HANDLE_VALUE)
15 { return false;
16 }
17 CloseHandle(fHandle);
18 return true;
19}
20
21bool installManager::ensureLog()
22{
23 if (this->logExists() == false)
24 { HANDLE fHandle;
25
26 unInstallCommand command("InstallRoot");
27 // Get the parent directory of the log file, and store it as the root
28 FilePath p(this->logfileName);
29 FilePath *parent = p.parent();
30 command.addParameter(parent->pathString());
31 delete parent;
32
33 if (this->modules["default"].begin()->command != "InstallRoot")
34 { this->modules["default"].insert(this->modules["default"].begin(), command);
35 }
36 fHandle = CreateFile(this->logfileName.c_str(), GENERIC_READ | GENERIC_WRITE,
37 FILE_SHARE_WRITE, NULL, CREATE_NEW,
38 FILE_ATTRIBUTE_NORMAL, NULL);
39 if (fHandle != INVALID_HANDLE_VALUE)
40 {
41 CloseHandle(fHandle);
42 return true;
43 }
44 return false;
45 }
46 else
47 { if (this->modules["default"].begin()->command == "InstallRoot")
48 { this->logfileName = this->modules["default"].begin()->parameters[0];
49 }
50 }
51 return true;
52}
53
54bool installManager::setLogFile(string filename)
55{ this->logfileName = filename;
56 this->setModule("default");
57 return true;
58}
59
60bool installManager::readLog()
61{ string command;
62 stringArray params;
63
64 // don't try to open an non-existing log; this has serious
65 // repercussions with bad old VC++
66 if (!this->logExists())
67 { this->setModule("default");
68 this->changed = false;
69 return true;
70 }
71
72 // open the log file
73 this->logfile.open(this->logfileName.c_str(), ios::in);
74#ifndef __BORLANDC__
75 if (this->logfile.is_open())
76#else
77 if (this->logfile.rdbuf()->is_open())
78#endif
79 {
80 // Get the commands into this object from the existing log file
81 while ((command = this->readCommand(params)) != "")
82 { if (command[0] == '[' && command[command.length()-1] == ']')
83 { this->setModule(command.substr(1, command.length() - 2));
84 }
85 else
86 { unInstallCommand action(command, params);
87
88 this->storeCommand(action);
89 }
90 }
91
92 // close the logfile
93 this->logfile.close();
94
95 // and clear the status bits, 'cos VC++ doesn't clear them when
96 // we reopen the file later.
97 this->logfile.clear();
98 }
99 this->changed = false;
100
101 // set to the default module
102 this->setModule("default");
103 return true;
104}
105
106void installManager::setModule(string moduleName)
107{ this->currentModule = moduleName;
108}
109
110bool installManager::storeCommand(unInstallCommand &command)
111{
112 this->modules[this->currentModule].push_back(command);
113
114 this->changed = true; // set the "changed" flag
115 return true;
116}
117
118bool installManager::writeCommand(unInstallCommand &command)
119{ if (!this->writeString(command.command))
120 { return false;
121 }
122 for (unsigned int p = 0; p < command.parameters.size(); p ++)
123 { if (!this->writeSeparator())
124 { return false;
125 }
126 if (!this->writeString(command.parameters[p]))
127 { return false;
128 }
129 }
130 if (!this->writeString("\n"))
131 { return false;
132 }
133 return true;
134}
135
136bool installManager::writeString(char *buffer)
137{ string s(buffer);
138 return this->writeString(s);
139}
140
141bool installManager::writeString(string str)
142{ bool quote;
143
144 // TODO: check for space characters in str and quote if necessary
145 quote = str.find_first_of(' ') < str.length();
146
147 if (quote)
148 { this->logfile << "\"";
149 }
150 this->logfile << str;
151 if (quote)
152 { this->logfile << "\"";
153 }
154 return true;
155}
156
157bool installManager::writeSeparator()
158{ this->logfile << " ";
159 return true;
160}
161
162string installManager::readString()
163{ string reply = "";
164 char c;
165
166 if (this->logfile.eof())
167 { return reply;
168 }
169
170 this->logfile >> c;
171 while (c <= ' ' && !this->logfile.eof())
172 { this->logfile.get();
173 }
174
175 if (this->logfile.eof())
176 { return reply;
177 }
178
179 if (c == '\"')
180 { do
181 { c = this->logfile.get();
182 if (c != '\"')
183 { reply += c;
184 }
185 }
186 while (c != '\"' && !this->logfile.eof());
187 }
188 else
189 { while (c > ' ')
190 { reply += c;
191 if (this->logfile.eof())
192 { break;
193 }
194 c = this->logfile.get();
195 }
196 if (!this->logfile.eof())
197 { this->logfile.putback(c);
198 }
199 //this->logfile >> reply;
200 }
201 return reply;
202}
203
204string installManager::readCommand(stringArray &array)
205{ string reply = "";
206 char c;
207
208 array.clear();
209
210 if (this->logfile.eof())
211 { return reply;
212 }
213
214 reply = this->readString();
215 if (reply == "")
216 { return reply;
217 }
218
219 while(!this->logfile.eof() &&
220 (c = this->logfile.get()) != '\n')
221 { this->logfile.putback(c);
222 array.add(this->readString());
223 }
224 if (!this->logfile.eof())
225 { this->logfile.putback(c);
226 }
227
228 return reply;
229}
230
231string installManager::popCommand(stringArray &array)
232{ string command;
233
234 if (this->modules[this->currentModule].size() == 0)
235 { command = "";
236 }
237 else
238 { unsigned int last;
239
240 last = this->modules[this->currentModule].size() - 1;
241 command = this->modules[this->currentModule][last].commandName();
242 array = this->modules[this->currentModule][last].parameterList();
243 this->modules[this->currentModule].erase(this->modules[this->currentModule].begin() + last);
244 }
245 return command;
246}
247void installManager::abortLog()
248{ this->changed = false;
249}
250bool installManager::recordLog()
251{ // just return if there are no changes to record
252 if (this->changed == false)
253 { return true;
254 }
255
256 // if the file didn't open, then this is almost certainly being compiled
257 // with Microsoft Visual C++ which has a library which fails to open the
258 // file if it doesn't already exist. Do a createfile and hope for success.
259 // TODO: add proper error handling here
260 this->ensureLog();
261 this->logfile.open(this->logfileName.c_str(), ios::out);
262#ifndef __BORLANDC__
263 if (!this->logfile.is_open())
264#else
265 if (!this->logfile.rdbuf()->is_open())
266#endif
267 { MessageBox(0, "Unable to open log file", this->logfileName.c_str(), MB_OK);
268 }
269
270 unInstallCommandMap::iterator here = this->modules.begin();
271 unInstallCommandMap::iterator end = this->modules.end();
272
273 while (here != end)
274 {
275 this->writeString("[" + (*here).first + "]\n");
276
277 unInstallCommandList::iterator ahere = (*here).second.begin();
278 unInstallCommandList::iterator aend = (*here).second.end();
279
280 while (ahere != aend)
281 { this->writeCommand(*ahere);
282 ahere ++;
283 }
284 here ++;
285 }
286 this->logfile.close();
287
288 this->changed = false;
289
290 return true;
291}
292
293bool installManager::isEmpty()
294{ unInstallCommandMap::iterator here = this->modules.begin();
295 unInstallCommandMap::iterator end = this->modules.end();
296
297 while (here != end)
298 { this->writeString("[" + (*here).first + "]\n");
299
300 unInstallCommandList::iterator ahere = (*here).second.begin();
301 unInstallCommandList::iterator aend = (*here).second.end();
302 if (ahere != aend)
303 { return false;
304 }
305 here ++;
306 }
307 return true;
308}
309
310string installManager::installRoot()
311{ if (this->modules["default"].begin()->command != "InstallRoot")
312 return "";
313 return this->modules["default"].begin()->parameters[0];
314}
315
316installManager::~installManager()
317{ this->recordLog();
318}
Note: See TracBrowser for help on using the repository browser.