source: trunk/gsinstaller/unInstall.cpp@ 2013

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

Updates and fixes to permit removal of the main install directory successfully.

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