xref: /aoo41x/main/idlc/source/idlcproduce.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_idlc.hxx"
30 #include <idlc/idlc.hxx>
31 #include <idlc/astmodule.hxx>
32 #include <rtl/strbuf.hxx>
33 #include <osl/file.hxx>
34 #include <osl/thread.h>
35 
36 #if defined(SAL_W32) || defined(SAL_OS2)
37 #include <io.h>
38 #include <direct.h>
39 #include <errno.h>
40 #endif
41 
42 #ifdef SAL_UNX
43 #include <unistd.h>
44 #include <sys/stat.h>
45 #include <errno.h>
46 #endif
47 
48 #include <string.h>
49 
50 using namespace ::rtl;
51 using namespace ::osl;
52 
53 StringList* pCreatedDirectories = NULL;
54 
55 static sal_Bool checkOutputPath(const OString& completeName)
56 {
57     OString sysPathName = convertToAbsoluteSystemPath(completeName);
58 	OStringBuffer buffer(sysPathName.getLength());
59 
60 	if ( sysPathName.indexOf( SEPARATOR ) == -1 )
61 		return sal_True;
62 
63     sal_Int32 nIndex = 0;
64 	OString token(sysPathName.getToken(0, SEPARATOR, nIndex));
65 	const sal_Char* p = token.getStr();
66 	if (strcmp(p, "..") == 0
67         || *(p+1) == ':'
68         || strcmp(p, ".") == 0)
69 	{
70 		buffer.append(token);
71 		buffer.append(SEPARATOR);
72 	}
73     else
74         nIndex = 0;
75 
76     do
77 	{
78 		buffer.append(sysPathName.getToken(0, SEPARATOR, nIndex));
79 
80 		if ( buffer.getLength() > 0 && nIndex != -1 )
81 		{
82 #if defined(SAL_UNX) || defined(SAL_OS2)
83 			if (mkdir((char*)buffer.getStr(), 0777) == -1)
84 #else
85 			if (mkdir((char*)buffer.getStr()) == -1)
86 #endif
87 			{
88 				if (errno == ENOENT)
89 				{
90 					fprintf(stderr, "%s: cannot create directory '%s'\n",
91 							idlc()->getOptions()->getProgramName().getStr(), buffer.getStr());
92 					return sal_False;
93 				}
94 	        } else
95 			{
96 				if ( !pCreatedDirectories )
97 					pCreatedDirectories = new StringList();
98 				pCreatedDirectories->push_front(buffer.getStr());
99 			}
100 		}
101         buffer.append(SEPARATOR);
102 	} while( nIndex != -1 );
103 	return sal_True;
104 }
105 
106 static sal_Bool cleanPath()
107 {
108 	if ( pCreatedDirectories )
109 	{
110 		StringList::iterator iter = pCreatedDirectories->begin();
111 		StringList::iterator end = pCreatedDirectories->end();
112 		while ( iter != end )
113 		{
114 //#ifdef SAL_UNX
115 //			if (rmdir((char*)(*iter).getStr(), 0777) == -1)
116 //#else
117 			if (rmdir((char*)(*iter).getStr()) == -1)
118 //#endif
119 			{
120 				fprintf(stderr, "%s: cannot remove directory '%s'\n",
121 						idlc()->getOptions()->getProgramName().getStr(), (*iter).getStr());
122 				return sal_False;
123 			}
124 			++iter;
125 		}
126 		delete pCreatedDirectories;
127 	}
128 	return sal_True;
129 }
130 
131 void removeIfExists(const OString& pathname)
132 {
133     unlink(pathname.getStr());
134 }
135 
136 sal_Int32 SAL_CALL produceFile(const OString& regFileName)
137 {
138 	Options* pOptions = idlc()->getOptions();
139 
140     OString regTmpName = regFileName.replaceAt(regFileName.getLength() -3, 3, "_idlc_");
141 
142 	if ( !checkOutputPath(regFileName) )
143 	{
144 		fprintf(stderr, "%s: could not create path of registry file '%s'.\n",
145 				pOptions->getProgramName().getStr(), regFileName.getStr());
146 		return 1;
147 	}
148 
149 	removeIfExists(regTmpName);
150     OString urlRegTmpName = convertToFileUrl(regTmpName);
151 
152 	Registry regFile;
153 	if ( regFile.create(OStringToOUString(urlRegTmpName, RTL_TEXTENCODING_UTF8)) != REG_NO_ERROR )
154 	{
155 		fprintf(stderr, "%s: could not create registry file '%s'\n",
156 				pOptions->getProgramName().getStr(), regTmpName.getStr());
157 		removeIfExists(regTmpName);
158 		removeIfExists(regFileName);
159 		cleanPath();
160 		return 1;
161 	}
162 
163 	RegistryKey rootKey;
164 	if ( regFile.openRootKey(rootKey) != REG_NO_ERROR )
165 	{
166 		fprintf(stderr, "%s: could not open root of registry file '%s'\n",
167 				pOptions->getProgramName().getStr(), regFileName.getStr());
168 		removeIfExists(regTmpName);
169 		removeIfExists(regFileName);
170 		cleanPath();
171 		return 1;
172 	}
173 
174 	// produce registry file
175 	if ( !idlc()->getRoot()->dump(rootKey) )
176 	{
177 		rootKey.releaseKey();
178 		regFile.close();
179 		regFile.destroy(OStringToOUString(regFileName, RTL_TEXTENCODING_UTF8));
180 		removeIfExists(regFileName);
181 		cleanPath();
182 		return 1;
183 	}
184 
185 	rootKey.releaseKey();
186 	if ( regFile.close() != REG_NO_ERROR )
187 	{
188 		fprintf(stderr, "%s: could not close registry file '%s'\n",
189 				pOptions->getProgramName().getStr(), regFileName.getStr());
190 		removeIfExists(regTmpName);
191 		removeIfExists(regFileName);
192 		cleanPath();
193 		return 1;
194 	}
195 
196 	removeIfExists(regFileName);
197 
198     if ( File::move(OStringToOUString(regTmpName, osl_getThreadTextEncoding()),
199                     OStringToOUString(regFileName, osl_getThreadTextEncoding())) != FileBase::E_None ) {
200 		fprintf(stderr, "%s: cannot rename temporary registry '%s' to '%s'\n",
201 				idlc()->getOptions()->getProgramName().getStr(),
202 				regTmpName.getStr(), regFileName.getStr());
203 		removeIfExists(regTmpName);
204 		cleanPath();
205 		return 1;
206     }
207 	removeIfExists(regTmpName);
208 
209 	return 0;
210 }
211