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 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_idlc.hxx"
26 #include <idlc/idlc.hxx>
27 #include <idlc/astmodule.hxx>
28 #include <rtl/strbuf.hxx>
29 #include <osl/file.hxx>
30 #include <osl/thread.h>
31
32 #if defined(SAL_W32) || defined(SAL_OS2)
33 #include <io.h>
34 #include <direct.h>
35 #include <errno.h>
36 #endif
37
38 #ifdef SAL_UNX
39 #include <unistd.h>
40 #include <sys/stat.h>
41 #include <errno.h>
42 #endif
43
44 #include <string.h>
45
46 using namespace ::rtl;
47 using namespace ::osl;
48
49 StringList* pCreatedDirectories = NULL;
50
checkOutputPath(const OString & completeName)51 static sal_Bool checkOutputPath(const OString& completeName)
52 {
53 OString sysPathName = convertToAbsoluteSystemPath(completeName);
54 OStringBuffer buffer(sysPathName.getLength());
55
56 if ( sysPathName.indexOf( SEPARATOR ) == -1 )
57 return sal_True;
58
59 sal_Int32 nIndex = 0;
60 OString token(sysPathName.getToken(0, SEPARATOR, nIndex));
61 const sal_Char* p = token.getStr();
62 if (strcmp(p, "..") == 0
63 || *(p+1) == ':'
64 || strcmp(p, ".") == 0)
65 {
66 buffer.append(token);
67 buffer.append(SEPARATOR);
68 }
69 else
70 nIndex = 0;
71
72 do
73 {
74 buffer.append(sysPathName.getToken(0, SEPARATOR, nIndex));
75
76 if ( buffer.getLength() > 0 && nIndex != -1 )
77 {
78 #if defined(SAL_UNX) || defined(SAL_OS2)
79 if (mkdir((char*)buffer.getStr(), 0777) == -1)
80 #else
81 if (mkdir((char*)buffer.getStr()) == -1)
82 #endif
83 {
84 if (errno == ENOENT)
85 {
86 fprintf(stderr, "%s: cannot create directory '%s'\n",
87 idlc()->getOptions()->getProgramName().getStr(), buffer.getStr());
88 return sal_False;
89 }
90 } else
91 {
92 if ( !pCreatedDirectories )
93 pCreatedDirectories = new StringList();
94 pCreatedDirectories->push_front(buffer.getStr());
95 }
96 }
97 buffer.append(SEPARATOR);
98 } while( nIndex != -1 );
99 return sal_True;
100 }
101
cleanPath()102 static sal_Bool cleanPath()
103 {
104 if ( pCreatedDirectories )
105 {
106 StringList::iterator iter = pCreatedDirectories->begin();
107 StringList::iterator end = pCreatedDirectories->end();
108 while ( iter != end )
109 {
110 //#ifdef SAL_UNX
111 // if (rmdir((char*)(*iter).getStr(), 0777) == -1)
112 //#else
113 if (rmdir((char*)(*iter).getStr()) == -1)
114 //#endif
115 {
116 fprintf(stderr, "%s: cannot remove directory '%s'\n",
117 idlc()->getOptions()->getProgramName().getStr(), (*iter).getStr());
118 return sal_False;
119 }
120 ++iter;
121 }
122 delete pCreatedDirectories;
123 }
124 return sal_True;
125 }
126
removeIfExists(const OString & pathname)127 void removeIfExists(const OString& pathname)
128 {
129 unlink(pathname.getStr());
130 }
131
produceFile(const OString & regFileName)132 sal_Int32 SAL_CALL produceFile(const OString& regFileName)
133 {
134 Options* pOptions = idlc()->getOptions();
135
136 OString regTmpName = regFileName.replaceAt(regFileName.getLength() -3, 3, "_idlc_");
137
138 if ( !checkOutputPath(regFileName) )
139 {
140 fprintf(stderr, "%s: could not create path of registry file '%s'.\n",
141 pOptions->getProgramName().getStr(), regFileName.getStr());
142 return 1;
143 }
144
145 removeIfExists(regTmpName);
146 OString urlRegTmpName = convertToFileUrl(regTmpName);
147
148 Registry regFile;
149 if ( regFile.create(OStringToOUString(urlRegTmpName, RTL_TEXTENCODING_UTF8)) != REG_NO_ERROR )
150 {
151 fprintf(stderr, "%s: could not create registry file '%s'\n",
152 pOptions->getProgramName().getStr(), regTmpName.getStr());
153 removeIfExists(regTmpName);
154 removeIfExists(regFileName);
155 cleanPath();
156 return 1;
157 }
158
159 RegistryKey rootKey;
160 if ( regFile.openRootKey(rootKey) != REG_NO_ERROR )
161 {
162 fprintf(stderr, "%s: could not open root of registry file '%s'\n",
163 pOptions->getProgramName().getStr(), regFileName.getStr());
164 removeIfExists(regTmpName);
165 removeIfExists(regFileName);
166 cleanPath();
167 return 1;
168 }
169
170 // produce registry file
171 if ( !idlc()->getRoot()->dump(rootKey) )
172 {
173 rootKey.releaseKey();
174 regFile.close();
175 regFile.destroy(OStringToOUString(regFileName, RTL_TEXTENCODING_UTF8));
176 removeIfExists(regFileName);
177 cleanPath();
178 return 1;
179 }
180
181 rootKey.releaseKey();
182 if ( regFile.close() != REG_NO_ERROR )
183 {
184 fprintf(stderr, "%s: could not close registry file '%s'\n",
185 pOptions->getProgramName().getStr(), regFileName.getStr());
186 removeIfExists(regTmpName);
187 removeIfExists(regFileName);
188 cleanPath();
189 return 1;
190 }
191
192 removeIfExists(regFileName);
193
194 if ( File::move(OStringToOUString(regTmpName, osl_getThreadTextEncoding()),
195 OStringToOUString(regFileName, osl_getThreadTextEncoding())) != FileBase::E_None ) {
196 fprintf(stderr, "%s: cannot rename temporary registry '%s' to '%s'\n",
197 idlc()->getOptions()->getProgramName().getStr(),
198 regTmpName.getStr(), regFileName.getStr());
199 removeIfExists(regTmpName);
200 cleanPath();
201 return 1;
202 }
203 removeIfExists(regTmpName);
204
205 return 0;
206 }
207