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 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 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 127 void removeIfExists(const OString& pathname) 128 { 129 unlink(pathname.getStr()); 130 } 131 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