source: other-projects/gs2-export-cdrom-installer/trunk/unInstall.cpp@ 28892

Last change on this file since 28892 was 11664, checked in by mdewsnip, 18 years ago

Fixed the line endings... for real this time, I hope.

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