joachim99@80
|
1 // uninstallHelper.cpp : Defines the entry point for the console application.
|
joachim99@80
|
2 //
|
joachim99@80
|
3 #include <iostream>
|
joachim99@80
|
4 #include <string>
|
joachim99@80
|
5 #include <vector>
|
joachim99@80
|
6 #include <list>
|
joachim99@80
|
7 #include <windows.h>
|
joachim99@80
|
8 #include <string.h>
|
joachim99@80
|
9 #include <io.h>
|
joachim99@80
|
10
|
joachim99@80
|
11 //#define __stdcall
|
joachim99@80
|
12
|
joachim99@80
|
13 #ifndef KREPLACEMENTS_H
|
joachim99@80
|
14 // For compilation download the NSIS source package and modify the following
|
joachim99@80
|
15 // line to point to the exdll.h-file
|
joachim99@80
|
16 #include "C:/Programme/NSIS/Contrib/ExDll/exdll.h"
|
joachim99@80
|
17 #endif
|
joachim99@80
|
18
|
joachim99@80
|
19 struct ReplacementItem
|
Chris@112
|
20 { const char* fileType; const char* operationType; };
|
joachim99@80
|
21
|
joachim99@80
|
22 ReplacementItem g_replacementTable[] = {
|
joachim99@80
|
23 {"text_file_delta", "xcompare"},
|
joachim99@80
|
24 {"text_file_delta", "xmerge"},
|
joachim99@80
|
25 {"whole_copy", "xcompare"},
|
joachim99@80
|
26 {"whole_copy", "xmerge"},
|
joachim99@80
|
27 {"z_text_file_delta", "xcompare"},
|
joachim99@80
|
28 {"z_text_file_delta", "xmerge"},
|
joachim99@80
|
29 {"z_whole_copy", "xcompare"},
|
joachim99@80
|
30 {"z_whole_copy", "xmerge"},
|
joachim99@80
|
31 {"_xml", "xcompare"},
|
joachim99@80
|
32 {"_xml", "xmerge"},
|
joachim99@80
|
33 {"_xml2", "xcompare"},
|
joachim99@80
|
34 {"_xml2", "xmerge"},
|
joachim99@80
|
35 {"_rftdef", "xcompare"},
|
joachim99@80
|
36 {"_rftmap", "xcompare"},
|
joachim99@80
|
37 {"_rftvp", "xcompare"},
|
joachim99@80
|
38 {"_xtools", "xcompare"},
|
joachim99@80
|
39 {0,0}
|
joachim99@80
|
40 };
|
joachim99@80
|
41
|
joachim99@80
|
42 struct LineItem
|
joachim99@80
|
43 {
|
joachim99@80
|
44 std::string fileType;
|
joachim99@80
|
45 std::string opType;
|
joachim99@80
|
46 std::string command;
|
joachim99@80
|
47 std::string fileOpPart;
|
joachim99@80
|
48 };
|
joachim99@80
|
49
|
joachim99@80
|
50 // Return true if successful, else false
|
joachim99@80
|
51 bool readAndParseMapFile( const std::string& filename, std::list<LineItem>& lineItemList )
|
joachim99@80
|
52 {
|
joachim99@80
|
53 // Read file
|
joachim99@80
|
54 FILE* pFile = fopen( filename.c_str(), "r" );
|
joachim99@80
|
55 if (pFile)
|
joachim99@80
|
56 {
|
joachim99@80
|
57 fseek(pFile,0,SEEK_END);
|
joachim99@80
|
58 int size = ftell(pFile);
|
joachim99@80
|
59 fseek(pFile,0,SEEK_SET);
|
joachim99@80
|
60 std::vector<char> buf( size );
|
joachim99@80
|
61 fread( &buf[0], 1, size, pFile );
|
joachim99@80
|
62 fclose( pFile );
|
joachim99@80
|
63
|
joachim99@80
|
64 // Replace strings
|
joachim99@80
|
65 int lineStartPos=0;
|
joachim99@80
|
66 int wordInLine = 0;
|
joachim99@80
|
67 LineItem lineItem;
|
joachim99@80
|
68 for( int i=0; i<size; )
|
joachim99@80
|
69 {
|
joachim99@80
|
70 if( buf[i] == '\n' || buf[i] == '\r' )
|
joachim99@80
|
71 {
|
joachim99@80
|
72 ++i;
|
joachim99@80
|
73 wordInLine = 0;
|
joachim99@80
|
74 lineStartPos = i;
|
joachim99@80
|
75 continue;
|
joachim99@80
|
76 }
|
joachim99@80
|
77 if( buf[i] == ' ' || buf[i] == '\t' )
|
joachim99@80
|
78 {
|
joachim99@80
|
79 ++i;
|
joachim99@80
|
80 continue;
|
joachim99@80
|
81 }
|
joachim99@80
|
82 else
|
joachim99@80
|
83 {
|
joachim99@80
|
84 int wordStartPos = i;
|
joachim99@80
|
85 if (wordInLine<2)
|
joachim99@80
|
86 {
|
joachim99@80
|
87 while ( i<size && !( buf[i] == ' ' || buf[i] == '\t' ) )
|
joachim99@80
|
88 ++i;
|
joachim99@80
|
89
|
joachim99@80
|
90 std::string word( &buf[wordStartPos], i-wordStartPos );
|
joachim99@80
|
91 if (wordInLine==0)
|
joachim99@80
|
92 lineItem.fileType = word;
|
joachim99@80
|
93 else
|
joachim99@80
|
94 lineItem.opType = word;
|
joachim99@80
|
95 ++wordInLine;
|
joachim99@80
|
96 }
|
joachim99@80
|
97 else
|
joachim99@80
|
98 {
|
joachim99@80
|
99 lineItem.fileOpPart = std::string( &buf[lineStartPos], i-lineStartPos );
|
joachim99@80
|
100 while ( i<size && !( buf[i] == '\n' || buf[i] == '\r' ) )
|
joachim99@80
|
101 ++i;
|
joachim99@80
|
102
|
joachim99@80
|
103 std::string word( &buf[wordStartPos], i-wordStartPos );
|
joachim99@80
|
104 lineItem.command = word;
|
joachim99@80
|
105 lineItemList.push_back( lineItem );
|
joachim99@80
|
106 }
|
joachim99@80
|
107 }
|
joachim99@80
|
108 }
|
joachim99@80
|
109 }
|
joachim99@80
|
110 else
|
joachim99@80
|
111 {
|
joachim99@80
|
112 return false;
|
joachim99@80
|
113 }
|
joachim99@80
|
114 return true;
|
joachim99@80
|
115 }
|
joachim99@80
|
116
|
joachim99@80
|
117 bool writeMapFile( const std::string& filename, const std::list<LineItem>& lineItemList )
|
joachim99@80
|
118 {
|
joachim99@80
|
119 FILE* pFile = fopen( filename.c_str(), "w" );
|
joachim99@80
|
120 if (pFile)
|
joachim99@80
|
121 {
|
joachim99@80
|
122 std::list<LineItem>::const_iterator i = lineItemList.begin();
|
joachim99@80
|
123 for( ; i!=lineItemList.end(); ++i )
|
joachim99@80
|
124 {
|
joachim99@80
|
125 const LineItem& li = *i;
|
joachim99@80
|
126 fprintf( pFile, "%s%s\n", li.fileOpPart.c_str(), li.command.c_str() );
|
joachim99@80
|
127 }
|
joachim99@80
|
128 fclose( pFile );
|
joachim99@80
|
129 }
|
joachim99@80
|
130 else
|
joachim99@80
|
131 {
|
joachim99@80
|
132 return false;
|
joachim99@80
|
133 }
|
joachim99@80
|
134 return true;
|
joachim99@80
|
135 }
|
joachim99@80
|
136
|
joachim99@80
|
137 std::string toUpper( const std::string& s )
|
joachim99@80
|
138 {
|
joachim99@80
|
139 std::string s2 = s;
|
joachim99@80
|
140
|
joachim99@80
|
141 for( unsigned int i=0; i<s.length(); ++i )
|
joachim99@80
|
142 {
|
joachim99@80
|
143 s2[i] = toupper( s2[i] );
|
joachim99@80
|
144 }
|
joachim99@80
|
145 return s2;
|
joachim99@80
|
146 }
|
joachim99@80
|
147
|
joachim99@80
|
148 int integrateWithClearCase( const char* subCommand, const char* kdiff3CommandPath )
|
joachim99@80
|
149 {
|
joachim99@80
|
150 std::string installCommand = subCommand; // "install" or "uninstall" or "existsClearCase"
|
joachim99@80
|
151 std::string kdiff3Command = kdiff3CommandPath;
|
joachim99@80
|
152
|
joachim99@80
|
153 /*
|
joachim99@80
|
154 std::wstring installCommand = subCommand; // "install" or "uninstall"
|
joachim99@80
|
155 std::wstring wKDiff3Command = kdiff3CommandPath;
|
joachim99@80
|
156 std::string kdiff3Command;
|
joachim99@80
|
157 kdiff3Command.reserve( wKDiff3Command.length()+1 );
|
joachim99@80
|
158 kdiff3Command.resize( wKDiff3Command.length() );
|
joachim99@80
|
159 BOOL bUsedDefaultChar = FALSE;
|
joachim99@80
|
160 int successLen = WideCharToMultiByte( CP_ACP, 0,
|
joachim99@80
|
161 wKDiff3Command.c_str(), int(wKDiff3Command.length()),
|
joachim99@80
|
162 &kdiff3Command[0], int(kdiff3Command.length()), 0, &bUsedDefaultChar );
|
joachim99@80
|
163
|
joachim99@80
|
164 if ( successLen != kdiff3Command.length() || bUsedDefaultChar )
|
joachim99@80
|
165 {
|
joachim99@80
|
166 std::cerr << "KDiff3 command contains characters that don't map to ansi code page.\n"
|
joachim99@80
|
167 "Aborting clearcase installation.\n"
|
joachim99@80
|
168 "Try to install KDiff3 in another path that doesn't require special characters.\n";
|
joachim99@80
|
169 return -1;
|
joachim99@80
|
170 }
|
joachim99@80
|
171 */
|
joachim99@80
|
172
|
joachim99@80
|
173 // Try to locate cleartool, the clearcase tool in the path
|
joachim99@80
|
174 char buffer[1000];
|
joachim99@80
|
175 char* pLastPart = 0;
|
joachim99@80
|
176 int len = SearchPathA(0, "cleartool.exe", 0, sizeof(buffer)/sizeof(buffer[0]),
|
joachim99@80
|
177 buffer, &pLastPart );
|
joachim99@80
|
178 if ( len>0 && len+1<int(sizeof(buffer)/sizeof(buffer[0])) && pLastPart )
|
joachim99@80
|
179 {
|
joachim99@80
|
180 pLastPart[-1] = 0;
|
joachim99@80
|
181 pLastPart = strrchr( buffer, '\\' ); // cd up (because cleartool.exe is in bin subdir)
|
joachim99@80
|
182 if ( pLastPart )
|
joachim99@80
|
183 pLastPart[1]=0;
|
joachim99@80
|
184
|
joachim99@80
|
185 std::string path( buffer );
|
joachim99@80
|
186 path += "lib\\mgrs\\map";
|
joachim99@80
|
187 std::string bakName = path + ".preKDiff3Install";
|
joachim99@80
|
188
|
joachim99@80
|
189 if ( installCommand == "existsClearCase")
|
joachim99@80
|
190 {
|
joachim99@80
|
191 return 1;
|
joachim99@80
|
192 }
|
joachim99@80
|
193 else if ( installCommand == "install")
|
joachim99@80
|
194 {
|
joachim99@80
|
195 std::list<LineItem> lineItemList;
|
joachim99@80
|
196 bool bSuccess = readAndParseMapFile( path, lineItemList );
|
joachim99@80
|
197 if ( !bSuccess )
|
joachim99@80
|
198 {
|
joachim99@80
|
199 std::cerr << "Error reading original map file.\n";
|
joachim99@80
|
200 return -1;
|
joachim99@80
|
201 }
|
joachim99@80
|
202
|
joachim99@80
|
203 // Create backup
|
joachim99@80
|
204 if ( access( bakName.c_str(), 0 )!=0 ) // Create backup only if not exists yet
|
joachim99@80
|
205 {
|
joachim99@80
|
206 if ( rename( path.c_str(), bakName.c_str() ) )
|
joachim99@80
|
207 {
|
joachim99@80
|
208 std::cerr << "Error renaming original map file.\n";
|
joachim99@80
|
209 return -1;
|
joachim99@80
|
210 }
|
joachim99@80
|
211 }
|
joachim99@80
|
212
|
joachim99@80
|
213 std::list<LineItem>::iterator i = lineItemList.begin();
|
joachim99@80
|
214 for( ; i!=lineItemList.end(); ++i )
|
joachim99@80
|
215 {
|
joachim99@80
|
216 LineItem& li = *i;
|
joachim99@80
|
217 for (int j=0;;++j)
|
joachim99@80
|
218 {
|
joachim99@80
|
219 ReplacementItem& ri = g_replacementTable[j];
|
joachim99@80
|
220 if ( ri.fileType==0 || ri.operationType==0 )
|
joachim99@80
|
221 break;
|
joachim99@80
|
222 if ( li.fileType == ri.fileType && li.opType == ri.operationType )
|
joachim99@80
|
223 {
|
joachim99@80
|
224 li.command = kdiff3Command.c_str();
|
joachim99@80
|
225 break;
|
joachim99@80
|
226 }
|
joachim99@80
|
227 }
|
joachim99@80
|
228 }
|
joachim99@80
|
229
|
joachim99@80
|
230 bSuccess = writeMapFile( path, lineItemList );
|
joachim99@80
|
231 if ( !bSuccess )
|
joachim99@80
|
232 {
|
joachim99@80
|
233 if ( rename( bakName.c_str(), path.c_str() ) )
|
joachim99@80
|
234 std::cerr << "Error writing new map file, restoring old file also failed.\n";
|
joachim99@80
|
235 else
|
joachim99@80
|
236 std::cerr << "Error writing new map file, old file restored.\n";
|
joachim99@80
|
237
|
joachim99@80
|
238 return -1;
|
joachim99@80
|
239 }
|
joachim99@80
|
240 }
|
joachim99@80
|
241 else if ( installCommand == "uninstall" )
|
joachim99@80
|
242 {
|
joachim99@80
|
243 std::list<LineItem> lineItemList;
|
joachim99@80
|
244 bool bSuccess = readAndParseMapFile( path, lineItemList );
|
joachim99@80
|
245 if ( !bSuccess )
|
joachim99@80
|
246 {
|
joachim99@80
|
247 std::cerr << "Error reading original map file\n.";
|
joachim99@80
|
248 return -1;
|
joachim99@80
|
249 }
|
joachim99@80
|
250
|
joachim99@80
|
251 std::list<LineItem> lineItemListBak;
|
joachim99@80
|
252 bSuccess = readAndParseMapFile( bakName, lineItemListBak );
|
joachim99@80
|
253 if ( !bSuccess )
|
joachim99@80
|
254 {
|
joachim99@80
|
255 std::cerr << "Error reading backup map file.\n";
|
joachim99@80
|
256 return -1;
|
joachim99@80
|
257 }
|
joachim99@80
|
258
|
joachim99@80
|
259 std::list<LineItem>::iterator i = lineItemList.begin();
|
joachim99@80
|
260 for( ; i!=lineItemList.end(); ++i )
|
joachim99@80
|
261 {
|
joachim99@80
|
262 LineItem& li = *i;
|
joachim99@80
|
263 if ((int)toUpper(li.command).find("KDIFF3")>=0)
|
joachim99@80
|
264 {
|
joachim99@80
|
265 std::list<LineItem>::const_iterator j = lineItemListBak.begin();
|
joachim99@80
|
266 for (;j!=lineItemListBak.end();++j)
|
joachim99@80
|
267 {
|
joachim99@80
|
268 const LineItem& bi = *j; // backup iterator
|
joachim99@80
|
269 if ( li.fileType == bi.fileType && li.opType == bi.opType )
|
joachim99@80
|
270 {
|
joachim99@80
|
271 li.command = bi.command;
|
joachim99@80
|
272 break;
|
joachim99@80
|
273 }
|
joachim99@80
|
274 }
|
joachim99@80
|
275 }
|
joachim99@80
|
276 }
|
joachim99@80
|
277
|
joachim99@80
|
278 bSuccess = writeMapFile( path, lineItemList );
|
joachim99@80
|
279 if ( !bSuccess )
|
joachim99@80
|
280 {
|
joachim99@80
|
281 std::cerr << "Error writing map file.";
|
joachim99@80
|
282
|
joachim99@80
|
283 return -1;
|
joachim99@80
|
284 }
|
joachim99@80
|
285 }
|
joachim99@80
|
286 }
|
joachim99@80
|
287 return 0;
|
joachim99@80
|
288 }
|
joachim99@80
|
289
|
joachim99@80
|
290 #ifndef KREPLACEMENTS_H
|
joachim99@80
|
291
|
joachim99@80
|
292 extern "C"
|
joachim99@80
|
293 void __declspec(dllexport) nsisPlugin(HWND hwndParent, int string_size,
|
joachim99@80
|
294 char *variables, stack_t **stacktop,
|
joachim99@80
|
295 extra_parameters *extra)
|
joachim99@80
|
296 {
|
joachim99@80
|
297 //g_hwndParent=hwndParent;
|
joachim99@80
|
298
|
joachim99@80
|
299 EXDLL_INIT();
|
joachim99@80
|
300 {
|
joachim99@80
|
301 std::string param1( g_stringsize, ' ' );
|
joachim99@80
|
302 int retVal = popstring( ¶m1[0] );
|
joachim99@80
|
303 if ( retVal == 0 )
|
joachim99@80
|
304 {
|
joachim99@80
|
305 std::string param2( g_stringsize, ' ' );
|
joachim99@80
|
306 retVal = popstring( ¶m2[0] );
|
joachim99@80
|
307 if ( retVal == 0 )
|
joachim99@80
|
308 install( param1.c_str(), param2.c_str() );
|
joachim99@80
|
309 return;
|
joachim99@80
|
310 }
|
joachim99@80
|
311 std::cerr << "Not enough parameters." << std::endl;
|
joachim99@80
|
312 }
|
joachim99@80
|
313 }
|
joachim99@80
|
314
|
joachim99@80
|
315 #endif
|
joachim99@80
|
316 /*
|
joachim99@80
|
317 int _tmain(int argc, _TCHAR* argv[])
|
joachim99@80
|
318 {
|
joachim99@80
|
319 if ( argc<3 )
|
joachim99@80
|
320 {
|
joachim99@80
|
321 std::cout << "This program is needed to install/uninstall KDiff3 for clearcase.\n"
|
joachim99@80
|
322 "It tries to patch the map file (clearcase-subdir\\lib\\mgrs\\map)\n"
|
joachim99@80
|
323 "Usage 1: ccInstHelper install pathToKdiff3.exe\n"
|
joachim99@80
|
324 "Usage 2: ccInstHelper uninstall pathToKdiff3.exe\n"
|
joachim99@80
|
325 "Backups of the original map files are created in the dir of the map file.\n";
|
joachim99@80
|
326 }
|
joachim99@80
|
327 else
|
joachim99@80
|
328 {
|
joachim99@80
|
329 return install( argv[1], argv[2] );
|
joachim99@80
|
330 }
|
joachim99@80
|
331
|
joachim99@80
|
332 return 0;
|
joachim99@80
|
333 }
|
joachim99@80
|
334 */
|