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_codemaker.hxx"
26 #include "osl/process.h"
27 #include "rtl/strbuf.hxx"
28 #include "rtl/ustring.hxx"
29 #include "osl/thread.h"
30 #include "osl/file.hxx"
31 
32 #include <string.h>
33 #if defined(SAL_W32) || defined(SAL_OS2)
34 #include <io.h>
35 
36 #include <direct.h>
37 #include <errno.h>
38 #endif
39 
40 #ifdef UNX
41 #include <sys/stat.h>
42 #include <errno.h>
43 #include <unistd.h>
44 #endif
45 
46 #include "codemaker/global.hxx"
47 
48 #ifdef SAL_UNX
49 #define SEPARATOR '/'
50 #else
51 #define SEPARATOR '\\'
52 #endif
53 
54 using namespace ::rtl;
55 using namespace ::osl;
56 
57 
getTempDir(const OString & sFileName)58 OString getTempDir(const OString& sFileName)
59 {
60     sal_Int32 index = 0;
61 #ifdef SAL_UNX
62     if ((index=sFileName.lastIndexOf('/')) > 0)
63         return sFileName.copy(0, index);
64 #else
65     if ((index=sFileName.lastIndexOf('\\')) > 0)
66         return sFileName.copy(0, index);
67 #endif
68     return ".";
69 }
70 
createFileNameFromType(const OString & destination,const OString typeName,const OString postfix,sal_Bool bLowerCase,const OString prefix)71 OString createFileNameFromType( const OString& destination,
72 								const OString typeName,
73 								const OString postfix,
74 								sal_Bool bLowerCase,
75 								const OString prefix )
76 {
77 	OString type(typeName);
78 
79 	if (bLowerCase)
80 	{
81 		type = typeName.toAsciiLowerCase();
82 	}
83 
84 	sal_uInt32 length = destination.getLength();
85 
86 	sal_Bool withPoint = sal_False;
87 	if (length == 0)
88 	{
89 		length++;
90 		withPoint = sal_True;
91 	}
92 
93 	length += prefix.getLength() + type.getLength() + postfix.getLength();
94 
95 	sal_Bool withSeperator = sal_False;
96 	if (destination.getStr()[destination.getLength()] != '\\' &&
97 		destination.getStr()[destination.getLength()] != '/' &&
98 		type.getStr()[0] != '\\' &&
99 		type.getStr()[0] != '/')
100 	{
101 		length++;
102 		withSeperator = sal_True;
103 	}
104 
105 	OStringBuffer nameBuffer(length);
106 
107 	if (withPoint)
108 		nameBuffer.append('.');
109 	else
110 		nameBuffer.append(destination.getStr(), destination.getLength());
111 
112 	if (withSeperator)
113 		nameBuffer.append("/", 1);
114 
115 	OString tmpStr(type);
116 	if ( !prefix.isEmpty() )
117 	{
118 		tmpStr = type.replaceAt(type.lastIndexOf('/')+1, 0, prefix);
119 	}
120 
121 	nameBuffer.append(tmpStr.getStr(), tmpStr.getLength());
122 	nameBuffer.append(postfix.getStr(), postfix.getLength());
123 
124 	OString fileName(nameBuffer);
125 
126 	sal_Char token;
127 #ifdef SAL_UNX
128 	fileName = fileName.replace('\\', '/');
129 	token = '/';
130 #else
131 	fileName = fileName.replace('/', '\\');
132 	token = '\\';
133 #endif
134 
135 	nameBuffer = OStringBuffer(length);
136 
137     sal_Int32 nIndex = 0;
138     do
139 	{
140 		nameBuffer.append(fileName.getToken(0, token, nIndex).getStr());
141         if( nIndex == -1 )
142             break;
143 
144 		if (nameBuffer.getLength() == 0 || OString(".") == nameBuffer.getStr())
145 		{
146 			nameBuffer.append(token);
147 			continue;
148 		}
149 
150 #if defined(SAL_UNX) || defined(SAL_OS2)
151         if (mkdir((char*)nameBuffer.getStr(), 0777) == -1)
152 #else
153         if (mkdir((char*)nameBuffer.getStr()) == -1)
154 #endif
155 		{
156 			if ( errno == ENOENT )
157 				return OString();
158 		}
159 
160 		nameBuffer.append(token);
161 	} while( nIndex != -1 );
162 
163     OUString uSysFileName;
164     OSL_VERIFY( FileBase::getSystemPathFromFileURL(
165         convertToFileUrl(fileName), uSysFileName) == FileBase::E_None );
166 	return OUStringToOString(uSysFileName, osl_getThreadTextEncoding());;
167 }
168 
fileExists(const OString & fileName)169 sal_Bool fileExists(const OString& fileName)
170 {
171 	FILE  *f= fopen(fileName.getStr(), "r");
172 
173 	if (f != NULL)
174 	{
175 		fclose(f);
176 		return sal_True;
177 	}
178 
179 	return sal_False;
180 }
181 
checkFileContent(const OString & targetFileName,const OString & tmpFileName)182 sal_Bool checkFileContent(const OString& targetFileName, const OString& tmpFileName)
183 {
184     FILE  *target = fopen(targetFileName.getStr(), "r");
185     FILE  *tmp = fopen(tmpFileName.getStr(), "r");
186     sal_Bool 	bFindChanges = sal_False;
187 
188     if (target != NULL && tmp != NULL)
189     {
190         sal_Char 	buffer1[1024+1];
191         sal_Char 	buffer2[1024+1];
192         sal_Int32 	n1 = 0;
193         sal_Int32 	n2 = 0;
194 
195         while ( !bFindChanges && !feof(target) && !feof(tmp))
196         {
197             n1 = fread(buffer1, sizeof(sal_Char), 1024, target);
198             n2 = fread(buffer2, sizeof(sal_Char), 1024, tmp);
199 
200             if ( n1 != n2 )
201 				bFindChanges = sal_True;
202             else
203                 if ( rtl_compareMemory(buffer1, buffer2, n2) != 0 )
204                     bFindChanges =  sal_True;
205         }
206     }
207 
208     if (target) fclose(target);
209     if (tmp) fclose(tmp);
210 
211     return bFindChanges;
212 }
213 
makeValidTypeFile(const OString & targetFileName,const OString & tmpFileName,sal_Bool bFileCheck)214 sal_Bool makeValidTypeFile(const OString& targetFileName, const OString& tmpFileName,
215                            sal_Bool bFileCheck)
216 {
217     if (bFileCheck) {
218         if (checkFileContent(targetFileName, tmpFileName)) {
219             if ( !unlink(targetFileName.getStr()) )
220                 if ( !rename(tmpFileName.getStr(), targetFileName.getStr()) )
221                     return sal_True;
222         } else
223             return removeTypeFile(tmpFileName);
224     } else {
225         if (fileExists(targetFileName))
226             if (!removeTypeFile(targetFileName))
227                 return sal_False;
228 
229         if ( rename(tmpFileName.getStr(), targetFileName.getStr()) ) {
230             if (errno == EEXIST)
231                 return sal_True;
232         } else
233             return sal_True;
234     }
235     return sal_False;
236 }
237 
removeTypeFile(const OString & fileName)238 sal_Bool removeTypeFile(const OString& fileName)
239 {
240     if ( !unlink(fileName.getStr()) )
241         return sal_True;
242 
243     return sal_False;
244 }
245 
isFileUrl(const OString & fileName)246 static sal_Bool isFileUrl(const OString& fileName)
247 {
248     if (fileName.indexOf("file://") == 0 )
249         return sal_True;
250     return sal_False;
251 }
252 
convertToFileUrl(const OString & fileName)253 OUString convertToFileUrl(const OString& fileName)
254 {
255     if ( isFileUrl(fileName) )
256     {
257         return OStringToOUString(fileName, osl_getThreadTextEncoding());
258     }
259 
260     OUString uUrlFileName;
261     OUString uFileName(fileName.getStr(), fileName.getLength(), osl_getThreadTextEncoding());
262     if ( fileName.indexOf('.') == 0 || fileName.indexOf(SEPARATOR) < 0 )
263     {
264         OUString uWorkingDir;
265         if (osl_getProcessWorkingDir(&uWorkingDir.pData) != osl_Process_E_None)
266         {
267             OSL_ASSERT(false);
268         }
269         if (FileBase::getAbsoluteFileURL(uWorkingDir, uFileName, uUrlFileName)
270             != FileBase::E_None)
271         {
272             OSL_ASSERT(false);
273         }
274     } else
275     {
276         if (FileBase::getFileURLFromSystemPath(uFileName, uUrlFileName)
277             != FileBase::E_None)
278         {
279             OSL_ASSERT(false);
280         }
281     }
282 
283     return uUrlFileName;
284 }
285 
286 
287 //*************************************************************************
288 // FileStream
289 //*************************************************************************
FileStream()290 FileStream::FileStream()
291 	: m_file(NULL)
292 {
293 }
294 
FileStream(const OString & name,FileAccessMode mode)295 FileStream::FileStream(const OString& name, FileAccessMode mode)
296 	: m_file(NULL)
297 {
298     if ( !name.isEmpty() )
299     {
300         OUString sUrl(convertToFileUrl(name));
301 #ifdef SAL_UNX
302         sal_uInt64 uAttr = osl_File_Attribute_OwnWrite |
303                            osl_File_Attribute_OwnRead |
304                            osl_File_Attribute_GrpWrite |
305                            osl_File_Attribute_GrpRead |
306                            osl_File_Attribute_OthRead;
307         if (osl_openFile(sUrl.pData, &m_file, checkAccessMode(mode)) == osl_File_E_None &&
308             osl_setFileAttributes(sUrl.pData, uAttr) == osl_File_E_None)
309 #else
310         if (osl_openFile(sUrl.pData, &m_file, checkAccessMode(mode)) == osl_File_E_None)
311 #endif
312             m_name = name;
313         else
314             m_file = NULL;
315     }
316 }
317 
~FileStream()318 FileStream::~FileStream()
319 {
320     if ( isValid() )
321         osl_closeFile(m_file);
322 }
323 
isValid()324 sal_Bool FileStream::isValid()
325 {
326     if ( m_file )
327         return sal_True;
328 
329 	return sal_False;
330 }
331 
createTempFile(const OString & sPath)332 void FileStream::createTempFile(const OString& sPath)
333 {
334     OString sTmp(".");
335     OUString sTmpPath;
336     OUString sTmpName;
337 
338     if ( !sPath.isEmpty() )
339         sTmp = sPath;
340 
341     sTmpPath = convertToFileUrl(sTmp);
342 
343     if (osl_createTempFile(sTmpPath.pData, &m_file, &sTmpName.pData) == osl_File_E_None) {
344 #ifdef SAL_UNX
345         sal_uInt64 uAttr = osl_File_Attribute_OwnWrite |
346                            osl_File_Attribute_OwnRead |
347                            osl_File_Attribute_GrpWrite |
348                            osl_File_Attribute_GrpRead |
349                            osl_File_Attribute_OthRead;
350         if (osl_setFileAttributes(sTmpName.pData, uAttr) != osl_File_E_None) {
351             m_file = NULL;
352             return;
353         }
354 #endif
355         OUString sSysTmpName;
356         FileBase::getSystemPathFromFileURL(sTmpName, sSysTmpName);
357         m_name = OUStringToOString(sSysTmpName, osl_getThreadTextEncoding());
358     } else
359         m_file = NULL;
360 }
361 
open(const OString & name,FileAccessMode mode)362 void FileStream::open(const OString& name, FileAccessMode mode)
363 {
364 	if ( !name.isEmpty() )
365 	{
366         oslFileError ret =  osl_File_E_None;
367         if ((ret = osl_openFile(convertToFileUrl(name).pData, &m_file, checkAccessMode(mode))) == osl_File_E_None)
368             m_name = name;
369         else
370             m_file = NULL;
371     }
372 }
373 
close()374 void FileStream::close()
375 {
376     if ( isValid() )
377     {
378         osl_closeFile(m_file);
379         m_file = NULL;
380         m_name = OString();
381     }
382 }
383 
checkAccessMode(FileAccessMode mode)384 sal_uInt32 FileStream::checkAccessMode(FileAccessMode mode)
385 {
386     switch( mode )
387     {
388     case FAM_READ:
389         return osl_File_OpenFlag_Read;
390     case FAM_WRITE:
391         return osl_File_OpenFlag_Write;
392     case FAM_READWRITE_EXIST:
393         return osl_File_OpenFlag_Read | osl_File_OpenFlag_Write;
394     case FAM_READWRITE:
395         return osl_File_OpenFlag_Read | osl_File_OpenFlag_Write | osl_File_OpenFlag_Create;
396     }
397     return osl_File_OpenFlag_Read | osl_File_OpenFlag_Write | osl_File_OpenFlag_Create;
398 }
399 
write(void const * buffer,sal_uInt64 size)400 bool FileStream::write(void const * buffer, sal_uInt64 size) {
401     while (size > 0) {
402         sal_uInt64 written;
403         if (osl_writeFile(m_file, buffer, size, &written) != osl_File_E_None) {
404             return false;
405         }
406         OSL_ASSERT(written <= size);
407         size -= written;
408         buffer = static_cast< char const * >(buffer) + written;
409     }
410     return true;
411 }
412 
operator <<(FileStream & o,sal_uInt32 i)413 FileStream &operator<<(FileStream& o, sal_uInt32 i) {
414     sal_uInt64 writtenBytes;
415     OString s = OString::valueOf((sal_Int32)i);
416     osl_writeFile(o.m_file, s.getStr(), s.getLength() * sizeof(sal_Char), &writtenBytes);
417     return o;
418 }
operator <<(FileStream & o,char const * s)419 FileStream &operator<<(FileStream& o, char const * s) {
420     sal_uInt64 writtenBytes;
421     osl_writeFile(o.m_file, s, strlen(s), &writtenBytes);
422     return o;
423 }
operator <<(FileStream & o,::rtl::OString * s)424 FileStream &operator<<(FileStream& o, ::rtl::OString* s) {
425     sal_uInt64 writtenBytes;
426     osl_writeFile(o.m_file, s->getStr(), s->getLength() * sizeof(sal_Char), &writtenBytes);
427     return o;
428 }
operator <<(FileStream & o,const::rtl::OString & s)429 FileStream &operator<<(FileStream& o, const ::rtl::OString& s) {
430     sal_uInt64 writtenBytes;
431     osl_writeFile(o.m_file, s.getStr(), s.getLength() * sizeof(sal_Char), &writtenBytes);
432     return o;
433 
434 }
operator <<(FileStream & o,::rtl::OStringBuffer * s)435 FileStream &operator<<(FileStream& o, ::rtl::OStringBuffer* s) {
436     sal_uInt64 writtenBytes;
437     osl_writeFile(o.m_file, s->getStr(), s->getLength() * sizeof(sal_Char), &writtenBytes);
438     return o;
439 }
operator <<(FileStream & o,const::rtl::OStringBuffer & s)440 FileStream &operator<<(FileStream& o, const ::rtl::OStringBuffer& s) {
441     sal_uInt64 writtenBytes;
442     osl_writeFile(
443         o.m_file, s.getStr(), s.getLength() * sizeof(sal_Char), &writtenBytes);
444     return o;
445 }
446