1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #include <stdio.h>
25 #include <osl/file.hxx>
26 #include <osl/process.h>
27 #include <codemaker/typemanager.hxx>
28 #include <codemaker/dependency.hxx>
29 
30 #ifndef _RTL_OSTRINGBUFFER_HXX_
31 #include <rtl/strbuf.hxx>
32 #endif
33 
34 #if defined(SAL_W32) || defined(SAL_OS2)
35 #include <io.h>
36 #include <direct.h>
37 #include <errno.h>
38 #endif
39 
40 #ifdef UNX
41 #include <stdlib.h>
42 #include <sys/stat.h>
43 #include <errno.h>
44 #include <unistd.h>
45 #endif
46 
47 #include "specialtypemanager.hxx"
48 #include "rdboptions.hxx"
49 #include "rdbtype.hxx"
50 
51 #define PATH_DELEMITTER	'/'
52 
53 using namespace rtl;
54 using namespace osl;
55 
56 FileStream 			listFile;
57 RegistryKey			rootKey;
58 Registry			regFile;
59 sal_Bool			useSpecial;
60 TypeManager*		pTypeMgr = NULL;
61 StringList			dirEntries;
62 StringSet			filterTypes;
63 
getFullNameOfApplicatRdb()64 OString getFullNameOfApplicatRdb()
65 {
66 	OUString bootReg;
67 	OUString uTmpStr;
68 	if( osl_getExecutableFile(&uTmpStr.pData) == osl_Process_E_None )
69 	{
70 		sal_uInt32 	lastIndex = uTmpStr.lastIndexOf(PATH_DELEMITTER);
71 		OUString	tmpReg;
72 
73 		if ( lastIndex > 0 )
74 		{
75 			tmpReg =uTmpStr.copy(0, lastIndex + 1);
76 		}
77 
78 		tmpReg += OUString( RTL_CONSTASCII_USTRINGPARAM("applicat.rdb") );
79 
80 		FileBase::getSystemPathFromFileURL(tmpReg, bootReg);
81 	}
82 
83 	return OUStringToOString(bootReg, RTL_TEXTENCODING_ASCII_US);
84 }
85 
initFilterTypes(RdbOptions * pOptions)86 void initFilterTypes(RdbOptions* pOptions)
87 {
88 	if (pOptions->isValid("-FT"))
89 	{
90 		OString fOption(pOptions->getOption("-FT"));
91 		sal_Int32 nIndex = 0;
92 		do
93 		{
94 			filterTypes.insert( fOption.getToken( 0, ';', nIndex ).replace('.', '/') );
95 		}
96 		while ( nIndex >= 0 );
97 	}
98 	if (pOptions->isValid("-F"))
99 	{
100 		FILE  *f = fopen(pOptions->getOption("-F").getStr(), "r");
101 
102 		if (f)
103 		{
104 			sal_Char buffer[1024+1];
105 			sal_Char *pBuf = fgets(buffer, 1024, f);
106 			sal_Char *s = NULL;
107 			sal_Char *p = NULL;
108 			while ( pBuf && !feof(f))
109 			{
110 				p = pBuf;
111 				if (*p != '\n' && *p != '\r')
112 				{
113 					while (*p == ' ' && *p =='\t')
114 						p++;
115 
116 					s = p;
117 					while (*p != '\n' && *p != '\r' && *p != ' ' && *p != '\t')
118 						p++;
119 
120 					*p = '\0';
121 					filterTypes.insert( OString(s).replace('.', '/') );
122 				}
123 
124 				pBuf = fgets(buffer, 1024, f);
125 			}
126 
127 			fclose(f);
128 		}
129 	}
130 }
131 
checkFilterTypes(const OString & type)132 sal_Bool checkFilterTypes(const OString& type)
133 {
134 	StringSet::iterator iter = filterTypes.begin();
135 	while ( iter != filterTypes.end() )
136 	{
137 		if ( type.indexOf( *iter ) == 0 )
138 		{
139 			return sal_True;
140 		}
141 
142 		iter++;
143 	}
144 
145 	return sal_False;
146 }
147 
cleanUp(sal_Bool bError)148 void cleanUp( sal_Bool bError)
149 {
150 	if ( pTypeMgr )
151 	{
152 		delete pTypeMgr;
153 	}
154 	if (useSpecial)
155 	{
156 		pTypeMgr = new SpecialTypeManager();
157 	}else
158 	{
159 		pTypeMgr = new RegistryTypeManager();
160 	}
161 
162 	if ( rootKey.isValid() )
163 	{
164 		rootKey.closeKey();
165 	}
166 	if ( regFile.isValid() )
167 	{
168 		if ( bError )
169 		{
170 			regFile.destroy(OUString());
171 		} else
172 		{
173 			regFile.close();
174 		}
175 	}
176 	if ( listFile.isValid() )
177 	{
178 		listFile.close();
179 		unlink(listFile.getName().getStr());
180 	}
181 
182 	StringList::reverse_iterator iter = dirEntries.rbegin();
183 	while ( iter != dirEntries.rend() )
184 	{
185 	   	if (rmdir((char*)(*iter).getStr()) == -1)
186 		{
187 			break;
188 		}
189 
190 		iter++;
191 	}
192 }
193 
createFileName(const OString & path)194 OString createFileName(const OString& path)
195 {
196 	OString fileName(path);
197 
198 	sal_Char token;
199 #ifdef SAL_UNX
200 	fileName = fileName.replace('\\', '/');
201 	token = '/';
202 #else
203 	fileName = fileName.replace('/', '\\');
204 	token = '\\';
205 #endif
206 
207 	OStringBuffer nameBuffer( path.getLength() );
208 
209 	sal_Int32 nIndex = 0;
210     do
211 	{
212 		nameBuffer.append(fileName.getToken( 0, token, nIndex ).getStr());
213 		if ( nIndex == -1 ) break;
214 
215 		if (nameBuffer.getLength() == 0 || OString(".") == nameBuffer.getStr())
216 		{
217 			nameBuffer.append(token);
218 			continue;
219 		}
220 
221 #if defined(SAL_UNX) || defined(SAL_OS2)
222 	    if (mkdir((char*)nameBuffer.getStr(), 0777) == -1)
223 #else
224 	   	if (mkdir((char*)nameBuffer.getStr()) == -1)
225 #endif
226 		{
227 			if ( errno == ENOENT )
228 				return OString();
229 		} else
230 		{
231 			dirEntries.push_back(nameBuffer.getStr());
232 		}
233 
234 		nameBuffer.append(token);
235 	}
236 	while ( nIndex >= 0 );
237 
238 	return fileName;
239 }
240 
produceAllTypes(const OString & typeName,TypeManager & typeMgr,TypeDependency & typeDependencies,RdbOptions * pOptions,sal_Bool bFullScope,FileStream & o,RegistryKey & regKey,StringSet & filterTypes2)241 sal_Bool produceAllTypes(const OString& typeName,
242 						 TypeManager& typeMgr,
243 						 TypeDependency& typeDependencies,
244 						 RdbOptions* pOptions,
245 						 sal_Bool bFullScope,
246 						 FileStream& o,
247 						 RegistryKey& regKey,
248 						 StringSet& filterTypes2)
249 	throw( CannotDumpException )
250 {
251 	if (!produceType(typeName, typeMgr,	typeDependencies, pOptions, o, regKey, filterTypes2))
252 	{
253 		fprintf(stderr, "%s ERROR: %s\n",
254 				pOptions->getProgramName().getStr(),
255 				OString("cannot dump Type '" + typeName + "'").getStr());
256 		cleanUp(sal_True);
257 		exit(99);
258 	}
259 
260 	RegistryKey	typeKey = typeMgr.getTypeKey(typeName);
261 	RegistryKeyNames subKeys;
262 
263 	if (typeKey.getKeyNames(OUString(), subKeys))
264 		return sal_False;
265 
266 	OString tmpName;
267 	for (sal_uInt32 i=0; i < subKeys.getLength(); i++)
268 	{
269 		tmpName = OUStringToOString(subKeys.getElement(i), RTL_TEXTENCODING_UTF8);
270 
271 		if (pOptions->isValid("-B"))
272 			tmpName = tmpName.copy(tmpName.indexOf('/', 1) + 1);
273 		else
274 			tmpName = tmpName.copy(1);
275 
276 		if (bFullScope)
277 		{
278 			if (!produceAllTypes(tmpName, typeMgr, typeDependencies, pOptions, sal_True,
279 								 o, regKey, filterTypes2))
280 				return sal_False;
281 		} else
282 		{
283 			if (!produceType(tmpName, typeMgr, typeDependencies, pOptions, o, regKey, filterTypes2))
284 				return sal_False;
285 		}
286 	}
287 
288 	return sal_True;
289 }
290 
291 
292 #if (defined UNX) || (defined OS2)
main(int argc,char * argv[])293 int main( int argc, char * argv[] )
294 #else
295 int _cdecl main( int argc, char * argv[] )
296 #endif
297 {
298 	RdbOptions options;
299 
300 	try
301 	{
302 		if (!options.initOptions(argc, argv))
303 		{
304 			cleanUp(sal_True);
305 			exit(1);
306 		}
307 	}
308 	catch( IllegalArgument& e)
309 	{
310 		fprintf(stderr, "Illegal option: %s\n", e.m_message.getStr());
311 		cleanUp(sal_True);
312 		exit(99);
313 	}
314 
315 	TypeDependency	typeDependencies;
316 
317 	OString bootReg;
318 
319 	if ( options.isValid("-R") )
320 	{
321 		bootReg = options.getOption("-R");
322 	} else
323 	{
324 		if (options.getInputFiles().empty())
325 		{
326 			bootReg = getFullNameOfApplicatRdb();
327 		}
328 	}
329 
330 	if ( bootReg.getLength() )
331 	{
332 		pTypeMgr = new SpecialTypeManager();
333 		useSpecial = sal_True;
334 	} else
335 	{
336 		pTypeMgr = new RegistryTypeManager();
337 		useSpecial = sal_False;
338 	}
339 
340 	TypeManager& typeMgr = *pTypeMgr;
341 
342 	if ( useSpecial && !typeMgr.init( bootReg ) )
343 	{
344 		fprintf(stderr, "%s : init typemanager failed, check your environment for bootstrapping uno.\n", options.getProgramName().getStr());
345 		cleanUp(sal_True);
346 		exit(99);
347 	}
348 	if ( !useSpecial && !typeMgr.init(!options.isValid("-T"), options.getInputFiles()))
349 	{
350 		fprintf(stderr, "%s : init registries failed, check your registry files.\n", options.getProgramName().getStr());
351 		cleanUp(sal_True);
352 		exit(99);
353 	}
354 
355 	initFilterTypes(&options);
356 
357 	if (options.isValid("-B"))
358 	{
359 		typeMgr.setBase(options.getOption("-B"));
360 	}
361 
362 	if ( !options.isValid("-O") )
363 	{
364 		fprintf(stderr, "%s ERROR: %s\n",
365 				options.getProgramName().getStr(),
366 				"no output file is specified.");
367 		cleanUp(sal_True);
368 		exit(99);
369 	}
370 
371 	if ( options.generateTypeList() )
372 	{
373 		OString fileName = createFileName( options.getOption("-O") );
374 		listFile.open(fileName);
375 
376 		if ( !listFile.isValid() )
377 		{
378 			fprintf(stderr, "%s ERROR: %s\n",
379 					options.getProgramName().getStr(),
380 					"could not open output file.");
381 			cleanUp(sal_True);
382 			exit(99);
383 		}
384 	} else
385 	{
386 		OUString fileName( OStringToOUString(createFileName( options.getOption("-O") ), RTL_TEXTENCODING_UTF8) );
387 		if ( regFile.create(fileName) )
388 		{
389 			fprintf(stderr, "%s ERROR: %s\n",
390 					options.getProgramName().getStr(),
391 					"could not create registry output file.");
392 			cleanUp(sal_True);
393 			exit(99);
394 		}
395 
396 
397 		if (options.isValid("-b"))
398 		{
399 			RegistryKey tmpKey;
400 			regFile.openRootKey(tmpKey);
401 
402 			tmpKey.createKey( OStringToOUString(options.getOption("-b"), RTL_TEXTENCODING_UTF8), rootKey);
403 		} else
404 		{
405 			regFile.openRootKey(rootKey);
406 		}
407 	}
408 
409 	try
410 	{
411 		if (options.isValid("-T"))
412 		{
413 			OString tOption(options.getOption("-T"));
414 			OString typeName, tmpName;
415 			sal_Bool ret = sal_False;
416 			sal_Int32 nIndex = 0;
417 			do
418 			{
419 				typeName = tOption.getToken( 0, ';', nIndex);
420 				sal_Int32 lastIndex = typeName.lastIndexOf('.');
421 				tmpName = typeName.copy( lastIndex+1 );
422 				if (tmpName == "*")
423 				{
424 					if (bootReg.getLength())
425 					{
426 						fprintf(stderr, "%s ERROR: %s\n",
427 								options.getProgramName().getStr(),
428 								"dumping all types of a scope is not possible if -R option is used.");
429 						exit(99);
430 					}
431 					// produce this type and his scope, but the scope is not recursively  generated.
432 					if (typeName.equals("*"))
433 					{
434 						tmpName = "/";
435 					} else
436 					{
437 						tmpName = typeName.copy(0, typeName.lastIndexOf('.')).replace('.', '/');
438 						if (tmpName.getLength() == 0)
439 							tmpName = "/";
440 						else
441 							tmpName.replace('.', '/');
442 					}
443 					ret = produceAllTypes(tmpName, typeMgr, typeDependencies, &options, sal_False,
444 										  listFile, rootKey, filterTypes);
445 				} else
446 				{
447 					// produce only this type
448 					ret = produceType(typeName.replace('.', '/'), typeMgr, typeDependencies,
449 									  &options, listFile, rootKey, filterTypes);
450 				}
451 /*
452 				// produce only this type
453 				ret = produceType(typeName.replace('.', '/'), typeMgr, typeDependencies,
454 								  &options, listFile, rootKey, filterTypes);
455 */
456 				if (!ret)
457 				{
458 					fprintf(stderr, "%s ERROR: %s\n",
459 							options.getProgramName().getStr(),
460 							OString("cannot dump Type '" + typeName + "'").getStr());
461 					cleanUp(sal_True);
462 					exit(99);
463 				}
464 			}
465 			while ( nIndex >= 0 );
466 		} else
467 		if (options.isValid("-X"))
468 		{
469 		} else
470 		{
471 			if (!bootReg.getLength())
472 			{
473 				// produce all types
474 				if (!produceAllTypes("/", typeMgr, typeDependencies, &options, sal_True,
475 									 listFile, rootKey, filterTypes))
476 				{
477 					fprintf(stderr, "%s ERROR: %s\n",
478 							options.getProgramName().getStr(),
479 							"an error occurs while dumping all types.");
480 					exit(99);
481 				}
482 			} else
483 			{
484 				fprintf(stderr, "%s ERROR: %s\n",
485 						options.getProgramName().getStr(),
486 						"dumping all types is not possible if -R option is used.");
487 				exit(99);
488 			}
489 		}
490 	}
491 	catch( CannotDumpException& e)
492 	{
493 		fprintf(stderr, "%s ERROR: %s\n",
494 				options.getProgramName().getStr(),
495 				e.m_message.getStr());
496 		cleanUp(sal_True);
497 		exit(99);
498 	}
499 
500 	cleanUp(sal_False);
501 	return 0;
502 }
503 
504 
505