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