Bug Summary

File:sal/osl/unx/file_misc.cxx
Location:line 932, column 9
Description:Value stored to 'nRet' is never read

Annotated Source Code

1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*************************************************************************
3 *
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 *
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 *
8 * OpenOffice.org - a multi-platform office productivity suite
9 *
10 * This file is part of OpenOffice.org.
11 *
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
15 *
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
21 *
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
26 *
27 ************************************************************************/
28
29#include "osl/file.hxx"
30#include "osl/detail/file.h"
31
32#include "osl/diagnose.h"
33#include "osl/thread.h"
34#include <osl/signal.h>
35#include "rtl/alloc.h"
36
37#include "system.h"
38#include "file_impl.hxx"
39#include "file_error_transl.h"
40#include "file_path_helper.hxx"
41#include "file_url.h"
42#include "uunxapi.hxx"
43#include "readwrite_helper.h"
44
45#include <sys/types.h>
46#include <errno(*__errno_location ()).h>
47#include <dirent.h>
48#include <limits.h>
49#include <stdio.h>
50#include <string.h>
51#include <unistd.h>
52#include <sys/stat.h>
53#include <sys/mman.h>
54
55#include <algorithm>
56
57#ifdef ANDROID
58#include <osl/detail/android-bootstrap.h>
59#endif
60
61/************************************************************************
62 * ToDo
63 *
64 * - Fix: check for corresponding struct sizes in exported functions
65 * - check size/use of oslDirectory
66 * - check size/use of oslDirectoryItem
67 ***********************************************************************/
68/******************************************************************************
69 *
70 * Data Type Definition
71 *
72 ******************************************************************************/
73
74typedef struct
75{
76 rtl_uString* ustrPath; /* holds native directory path */
77 DIR* pDirStruct;
78#ifdef ANDROID
79 enum Kind
80 {
81 KIND_DIRENT = 1,
82 KIND_ASSETS = 2
83 };
84 int eKind;
85 lo_apk_dir* pApkDirStruct;
86#endif
87} oslDirectoryImpl;
88
89DirectoryItem_Impl::DirectoryItem_Impl(
90 rtl_uString * ustrFilePath, unsigned char DType)
91 : m_RefCount (1),
92 m_ustrFilePath (ustrFilePath),
93 m_DType (DType)
94{
95 if (m_ustrFilePath != 0)
96 rtl_uString_acquire(m_ustrFilePath);
97}
98DirectoryItem_Impl::~DirectoryItem_Impl()
99{
100 if (m_ustrFilePath != 0)
101 rtl_uString_release(m_ustrFilePath);
102}
103
104void * DirectoryItem_Impl::operator new(size_t n)
105{
106 return rtl_allocateMemory(n);
107}
108void DirectoryItem_Impl::operator delete(void * p)
109{
110 rtl_freeMemory(p);
111}
112
113void DirectoryItem_Impl::acquire()
114{
115 ++m_RefCount;
116}
117void DirectoryItem_Impl::release()
118{
119 if (0 == --m_RefCount)
120 delete this;
121}
122
123oslFileType DirectoryItem_Impl::getFileType() const
124{
125 switch (m_DType)
126 {
127#ifdef _DIRENT_HAVE_D_TYPE
128 case DT_LNKDT_LNK:
129 return osl_File_Type_Link;
130 case DT_DIRDT_DIR:
131 return osl_File_Type_Directory;
132 case DT_REGDT_REG:
133 return osl_File_Type_Regular;
134 case DT_FIFODT_FIFO:
135 return osl_File_Type_Fifo;
136 case DT_SOCKDT_SOCK:
137 return osl_File_Type_Socket;
138 case DT_CHRDT_CHR:
139 case DT_BLKDT_BLK:
140 return osl_File_Type_Special;
141#endif /* _DIRENT_HAVE_D_TYPE */
142 default:
143 break;
144 }
145 return osl_File_Type_Unknown;
146}
147
148/******************************************************************************
149 *
150 * C-String Function Declarations
151 *
152 *****************************************************************************/
153
154static oslFileError osl_psz_createDirectory(const sal_Char* pszPath);
155static oslFileError osl_psz_removeDirectory(const sal_Char* pszPath);
156
157/*******************************************************************
158 * osl_openDirectory
159 ******************************************************************/
160
161oslFileError SAL_CALL osl_openDirectory(rtl_uString* ustrDirectoryURL, oslDirectory* pDirectory)
162{
163 rtl_uString* ustrSystemPath = NULL__null;
164 oslFileError eRet;
165
166 char path[PATH_MAX4096];
167
168 if ((0 == ustrDirectoryURL) || (0 == ustrDirectoryURL->length) || (0 == pDirectory))
169 return osl_File_E_INVAL;
170
171 /* convert file URL to system path */
172 eRet = osl_getSystemPathFromFileURL_Ex(ustrDirectoryURL, &ustrSystemPath, sal_False((sal_Bool)0));
173
174 if( osl_File_E_None != eRet )
175 return eRet;
176
177 osl_systemPathRemoveSeparator(ustrSystemPath);
178
179 /* convert unicode path to text */
180 if ( UnicodeToText( path, PATH_MAX4096, ustrSystemPath->buffer, ustrSystemPath->length )
181#ifdef MACOSX
182 && macxp_resolveAlias( path, PATH_MAX4096 ) == 0
183#endif /* MACOSX */
184 )
185 {
186#ifdef ANDROID
187 if( strncmp( path, "/assets/", sizeof( "/assets/" ) - 1) == 0 )
188 {
189 lo_apk_dir *pdir = lo_apk_opendir( path );
190
191 if( pdir )
192 {
193 oslDirectoryImpl* pDirImpl = (oslDirectoryImpl*) rtl_allocateMemory( sizeof(oslDirectoryImpl) );
194
195 if( pDirImpl )
196 {
197 pDirImpl->eKind = oslDirectoryImpl::KIND_ASSETS;
198 pDirImpl->pApkDirStruct = pdir;
199 pDirImpl->ustrPath = ustrSystemPath;
200
201 *pDirectory = (oslDirectory) pDirImpl;
202 return osl_File_E_None;
203 }
204 else
205 {
206 errno(*__errno_location ()) = ENOMEM12;
207 lo_apk_closedir( pdir );
208 }
209 }
210 }
211 else
212#endif
213 {
214 /* open directory */
215 DIR *pdir = opendir( path );
216
217 if( pdir )
218 {
219 /* create and initialize impl structure */
220 oslDirectoryImpl* pDirImpl = (oslDirectoryImpl*) rtl_allocateMemory( sizeof(oslDirectoryImpl) );
221
222 if( pDirImpl )
223 {
224 pDirImpl->pDirStruct = pdir;
225 pDirImpl->ustrPath = ustrSystemPath;
226#ifdef ANDROID
227 pDirImpl->eKind = oslDirectoryImpl::KIND_DIRENT;
228#endif
229 *pDirectory = (oslDirectory) pDirImpl;
230 return osl_File_E_None;
231 }
232 else
233 {
234 errno(*__errno_location ()) = ENOMEM12;
235 closedir( pdir );
236 }
237 }
238 else
239 {
240#ifdef DEBUG_OSL_FILE
241 perror ("osl_openDirectory"); fprintf (stderrstderr, path);
242#endif
243 }
244 }
245 }
246
247 rtl_uString_release( ustrSystemPath );
248
249 return oslTranslateFileError(OSL_FET_ERROR((sal_Bool)1), errno(*__errno_location ()));
250}
251
252/****************************************************************************/
253/* osl_closeDirectory */
254/****************************************************************************/
255
256oslFileError SAL_CALL osl_closeDirectory( oslDirectory Directory )
257{
258 oslDirectoryImpl* pDirImpl = (oslDirectoryImpl*) Directory;
259 oslFileError err = osl_File_E_None;
260
261 OSL_ASSERT( Directory )do { if (true && (!(Directory))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/usr/local/src/libreoffice/sal/osl/unx/file_misc.cxx"
":" "261" ": "), "OSL_ASSERT: %s", "Directory"); } } while (
false)
;
262
263 if( NULL__null == pDirImpl )
264 return osl_File_E_INVAL;
265
266#ifdef ANDROID
267 if( pDirImpl->eKind == oslDirectoryImpl::KIND_ASSETS )
268 {
269 if (lo_apk_closedir( pDirImpl->pApkDirStruct ))
270 err = osl_File_E_IO;
271 }
272 else
273#endif
274 {
275 if( closedir( pDirImpl->pDirStruct ) )
276 err = oslTranslateFileError(OSL_FET_ERROR((sal_Bool)1), errno(*__errno_location ()));
277 }
278
279 /* cleanup members */
280 rtl_uString_release( pDirImpl->ustrPath );
281
282 rtl_freeMemory( pDirImpl );
283
284 return err;
285}
286
287/**********************************************
288 * osl_readdir_impl_
289 *
290 * readdir wrapper, filters out "." and ".."
291 * on request
292 *********************************************/
293
294static struct dirent* osl_readdir_impl_(DIR* pdir, sal_Bool bFilterLocalAndParentDir)
295{
296 struct dirent* pdirent;
297
298 while ((pdirent = readdir(pdir)) != NULL__null)
299 {
300 if (bFilterLocalAndParentDir &&
301 ((0 == strcmp(pdirent->d_name, ".")) || (0 == strcmp(pdirent->d_name, ".."))))
302 continue;
303 else
304 break;
305 }
306
307 return pdirent;
308}
309
310/****************************************************************************
311 * osl_getNextDirectoryItem
312 ***************************************************************************/
313
314oslFileError SAL_CALL osl_getNextDirectoryItem(oslDirectory Directory, oslDirectoryItem* pItem, SAL_UNUSED_PARAMETER__attribute__ ((unused)) sal_uInt32 /*uHint*/)
315{
316 oslDirectoryImpl* pDirImpl = (oslDirectoryImpl*)Directory;
317 rtl_uString* ustrFileName = NULL__null;
318 rtl_uString* ustrFilePath = NULL__null;
319 struct dirent* pEntry;
320
321 OSL_ASSERT(Directory)do { if (true && (!(Directory))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/usr/local/src/libreoffice/sal/osl/unx/file_misc.cxx"
":" "321" ": "), "OSL_ASSERT: %s", "Directory"); } } while (
false)
;
322 OSL_ASSERT(pItem)do { if (true && (!(pItem))) { sal_detail_logFormat((
SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/usr/local/src/libreoffice/sal/osl/unx/file_misc.cxx"
":" "322" ": "), "OSL_ASSERT: %s", "pItem"); } } while (false
)
;
323
324 if ((NULL__null == Directory) || (NULL__null == pItem))
325 return osl_File_E_INVAL;
326
327#ifdef ANDROID
328 if( pDirImpl->eKind == oslDirectoryImpl::KIND_ASSETS )
329 {
330 pEntry = lo_apk_readdir(pDirImpl->pApkDirStruct);
331 }
332 else
333#endif
334 {
335 pEntry = osl_readdir_impl_(pDirImpl->pDirStruct, sal_True((sal_Bool)1));
336 }
337
338 if (NULL__null == pEntry)
339 return osl_File_E_NOENT;
340
341
342#if defined(MACOSX)
343
344 // convert decomposed filename to precomposed unicode
345 char composed_name[BUFSIZ8192];
346 CFMutableStringRef strRef = CFStringCreateMutable (NULL__null, 0 );
347 CFStringAppendCString( strRef, pEntry->d_name, kCFStringEncodingUTF8 ); //UTF8 is default on Mac OSX
348 CFStringNormalize( strRef, kCFStringNormalizationFormC );
349 CFStringGetCString( strRef, composed_name, BUFSIZ8192, kCFStringEncodingUTF8 );
350 CFRelease( strRef );
351 rtl_string2UString( &ustrFileName, composed_name, strlen( composed_name),
352 osl_getThreadTextEncoding(), OSTRING_TO_OUSTRING_CVTFLAGS(((sal_uInt32)0x0003) | ((sal_uInt32)0x0030) | ((sal_uInt32)0x0300
))
);
353
354#else // not MACOSX
355 /* convert file name to unicode */
356 rtl_string2UString( &ustrFileName, pEntry->d_name, strlen( pEntry->d_name ),
357 osl_getThreadTextEncoding(), OSTRING_TO_OUSTRING_CVTFLAGS(((sal_uInt32)0x0003) | ((sal_uInt32)0x0030) | ((sal_uInt32)0x0300
))
);
358 OSL_ASSERT(ustrFileName != 0)do { if (true && (!(ustrFileName != 0))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/usr/local/src/libreoffice/sal/osl/unx/file_misc.cxx"
":" "358" ": "), "OSL_ASSERT: %s", "ustrFileName != 0"); } }
while (false)
;
359
360#endif
361
362 osl_systemPathMakeAbsolutePath(pDirImpl->ustrPath, ustrFileName, &ustrFilePath);
363 rtl_uString_release( ustrFileName );
364
365 DirectoryItem_Impl * pImpl = static_cast< DirectoryItem_Impl* >(*pItem);
366 if (0 != pImpl)
367 {
368 pImpl->release(), pImpl = 0;
369 }
370#ifdef _DIRENT_HAVE_D_TYPE
371 pImpl = new DirectoryItem_Impl(ustrFilePath, pEntry->d_type);
372#else
373 pImpl = new DirectoryItem_Impl(ustrFilePath);
374#endif /* _DIRENT_HAVE_D_TYPE */
375 *pItem = pImpl;
376 rtl_uString_release( ustrFilePath );
377
378 return osl_File_E_None;
379}
380
381/****************************************************************************/
382/* osl_getDirectoryItem */
383/****************************************************************************/
384
385oslFileError SAL_CALL osl_getDirectoryItem( rtl_uString* ustrFileURL, oslDirectoryItem* pItem )
386{
387 rtl_uString* ustrSystemPath = NULL__null;
388 oslFileError osl_error = osl_File_E_INVAL;
389
390 OSL_ASSERT((0 != ustrFileURL) && (0 != pItem))do { if (true && (!((0 != ustrFileURL) && (0 !=
pItem)))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN)
, ("legacy.osl"), ("/usr/local/src/libreoffice/sal/osl/unx/file_misc.cxx"
":" "390" ": "), "OSL_ASSERT: %s", "(0 != ustrFileURL) && (0 != pItem)"
); } } while (false)
;
391 if ((0 == ustrFileURL) || (0 == ustrFileURL->length) || (0 == pItem))
392 return osl_File_E_INVAL;
393
394 osl_error = osl_getSystemPathFromFileURL_Ex(ustrFileURL, &ustrSystemPath, sal_False((sal_Bool)0));
395 if (osl_File_E_None != osl_error)
396 return osl_error;
397
398 osl_systemPathRemoveSeparator(ustrSystemPath);
399
400 if (-1 == access_u(ustrSystemPath, F_OK0))
401 {
402 osl_error = oslTranslateFileError(OSL_FET_ERROR((sal_Bool)1), errno(*__errno_location ()));
403 }
404 else
405 {
406 *pItem = new DirectoryItem_Impl(ustrSystemPath);
407 }
408 rtl_uString_release(ustrSystemPath);
409
410 return osl_error;
411}
412
413
414/****************************************************************************/
415/* osl_acquireDirectoryItem */
416/****************************************************************************/
417
418oslFileError SAL_CALL osl_acquireDirectoryItem( oslDirectoryItem Item )
419{
420 DirectoryItem_Impl * pImpl = static_cast< DirectoryItem_Impl* >(Item);
421 if (0 == pImpl)
422 return osl_File_E_INVAL;
423
424 pImpl->acquire();
425 return osl_File_E_None;
426}
427
428/****************************************************************************/
429/* osl_releaseDirectoryItem */
430/****************************************************************************/
431
432oslFileError SAL_CALL osl_releaseDirectoryItem( oslDirectoryItem Item )
433{
434 DirectoryItem_Impl * pImpl = static_cast< DirectoryItem_Impl* >(Item);
435 if (0 == pImpl)
436 return osl_File_E_INVAL;
437
438 pImpl->release();
439 return osl_File_E_None;
440}
441
442/****************************************************************************/
443/* osl_createDirectory */
444/****************************************************************************/
445
446oslFileError SAL_CALL osl_createDirectory( rtl_uString* ustrDirectoryURL )
447{
448 char path[PATH_MAX4096];
449 oslFileError eRet;
450
451 OSL_ASSERT( ustrDirectoryURL )do { if (true && (!(ustrDirectoryURL))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/usr/local/src/libreoffice/sal/osl/unx/file_misc.cxx"
":" "451" ": "), "OSL_ASSERT: %s", "ustrDirectoryURL"); } } while
(false)
;
452
453 /* convert directory url to system path */
454 eRet = FileURLToPath( path, PATH_MAX4096, ustrDirectoryURL );
455 if( eRet != osl_File_E_None )
456 return eRet;
457
458#ifdef MACOSX
459 if ( macxp_resolveAlias( path, PATH_MAX4096 ) != 0 )
460 return oslTranslateFileError( OSL_FET_ERROR((sal_Bool)1), errno(*__errno_location ()) );
461#endif/* MACOSX */
462
463 return osl_psz_createDirectory( path );
464}
465
466/****************************************************************************/
467/* osl_removeDirectory */
468/****************************************************************************/
469
470oslFileError SAL_CALL osl_removeDirectory( rtl_uString* ustrDirectoryURL )
471{
472 char path[PATH_MAX4096];
473 oslFileError eRet;
474
475 OSL_ASSERT( ustrDirectoryURL )do { if (true && (!(ustrDirectoryURL))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/usr/local/src/libreoffice/sal/osl/unx/file_misc.cxx"
":" "475" ": "), "OSL_ASSERT: %s", "ustrDirectoryURL"); } } while
(false)
;
476
477 /* convert directory url to system path */
478 eRet = FileURLToPath( path, PATH_MAX4096, ustrDirectoryURL );
479 if( eRet != osl_File_E_None )
480 return eRet;
481
482#ifdef MACOSX
483 if ( macxp_resolveAlias( path, PATH_MAX4096 ) != 0 )
484 return oslTranslateFileError( OSL_FET_ERROR((sal_Bool)1), errno(*__errno_location ()) );
485#endif/* MACOSX */
486
487 return osl_psz_removeDirectory( path );
488}
489
490/*****************************************
491 * osl_psz_createDirectory
492 ****************************************/
493
494static oslFileError osl_psz_createDirectory( const sal_Char* pszPath )
495{
496 int nRet=0;
497 int mode = S_IRWXU(0400|0200|0100) | S_IRWXG((0400|0200|0100) >> 3) | S_IRWXO(((0400|0200|0100) >> 3) >> 3);
498
499 nRet = mkdir(pszPath,mode);
500
501 if ( nRet < 0 )
502 {
503 nRet=errno(*__errno_location ());
504 return oslTranslateFileError(OSL_FET_ERROR((sal_Bool)1), nRet);
505 }
506
507 return osl_File_E_None;
508}
509
510/*****************************************
511 * osl_psz_removeDirectory
512 ****************************************/
513
514static oslFileError osl_psz_removeDirectory( const sal_Char* pszPath )
515{
516 int nRet=0;
517
518 nRet = rmdir(pszPath);
519
520 if ( nRet < 0 )
521 {
522 nRet=errno(*__errno_location ());
523 return oslTranslateFileError(OSL_FET_ERROR((sal_Bool)1), nRet);
524 }
525
526 return osl_File_E_None;
527}
528
529/****************************************************************************/
530/* osl_createDirectoryPath */
531/****************************************************************************/
532
533static int path_make_parent(sal_Unicode* path)
534{
535 int i = rtl_ustr_lastIndexOfChar(path, '/');
536
537 if (i > 0)
538 {
539 *(path + i) = 0;
540 return i;
541 }
542 else
543 return 0;
544}
545
546static int create_dir_with_callback(
547 sal_Unicode* directory_path,
548 oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc,
549 void* pData)
550{
551 int mode = S_IRWXU(0400|0200|0100) | S_IRWXG((0400|0200|0100) >> 3) | S_IRWXO(((0400|0200|0100) >> 3) >> 3);
552
553 if (osl::mkdir(directory_path, mode) == 0)
554 {
555 if (aDirectoryCreationCallbackFunc)
556 {
557 rtl::OUString url;
558 osl::FileBase::getFileURLFromSystemPath(directory_path, url);
559 aDirectoryCreationCallbackFunc(pData, url.pData);
560 }
561 return 0;
562 }
563 return errno(*__errno_location ());
564}
565
566static oslFileError create_dir_recursively_(
567 sal_Unicode* dir_path,
568 oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc,
569 void* pData)
570{
571 OSL_PRECOND((rtl_ustr_getLength(dir_path) > 0) && ((dir_path + (rtl_ustr_getLength(dir_path) - 1)) != (dir_path + rtl_ustr_lastIndexOfChar(dir_path, '/'))), \do { if (true && (!((rtl_ustr_getLength(dir_path) >
0) && ((dir_path + (rtl_ustr_getLength(dir_path) - 1
)) != (dir_path + rtl_ustr_lastIndexOfChar(dir_path, '/')))))
) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"
), ("/usr/local/src/libreoffice/sal/osl/unx/file_misc.cxx" ":"
"572" ": "), "%s", "Path must not end with a slash"); } } while
(false)
572 "Path must not end with a slash")do { if (true && (!((rtl_ustr_getLength(dir_path) >
0) && ((dir_path + (rtl_ustr_getLength(dir_path) - 1
)) != (dir_path + rtl_ustr_lastIndexOfChar(dir_path, '/')))))
) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"
), ("/usr/local/src/libreoffice/sal/osl/unx/file_misc.cxx" ":"
"572" ": "), "%s", "Path must not end with a slash"); } } while
(false)
;
573
574 int native_err = create_dir_with_callback(
575 dir_path, aDirectoryCreationCallbackFunc, pData);
576
577 if (native_err == 0)
578 return osl_File_E_None;
579
580 if (native_err != ENOENT2)
581 return oslTranslateFileError(OSL_FET_ERROR((sal_Bool)1), native_err);
582
583 // we step back until '/a_dir' at maximum because
584 // we should get an error unequal ENOENT when
585 // we try to create 'a_dir' at '/' and would so
586 // return before
587 int pos = path_make_parent(dir_path);
588
589 oslFileError osl_error = create_dir_recursively_(
590 dir_path, aDirectoryCreationCallbackFunc, pData);
591
592 if (osl_File_E_None != osl_error)
593 return osl_error;
594
595 dir_path[pos] = '/';
596
597 return create_dir_recursively_(dir_path, aDirectoryCreationCallbackFunc, pData);
598}
599
600oslFileError SAL_CALL osl_createDirectoryPath(
601 rtl_uString* aDirectoryUrl,
602 oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc,
603 void* pData)
604{
605 if (aDirectoryUrl == NULL__null)
606 return osl_File_E_INVAL;
607
608 rtl::OUString sys_path;
609 oslFileError osl_error = osl_getSystemPathFromFileURL_Ex(
610 aDirectoryUrl, &sys_path.pData, sal_False((sal_Bool)0));
611
612 if (osl_error != osl_File_E_None)
613 return osl_error;
614
615 osl::systemPathRemoveSeparator(sys_path);
616
617 // const_cast because sys_path is a local copy which we want to modify inplace instead of
618 // coyp it into another buffer on the heap again
619 return create_dir_recursively_(sys_path.pData->buffer, aDirectoryCreationCallbackFunc, pData);
620}
621
622/******************************************************************************
623 *
624 * C-String Function Declarations
625 *
626 *****************************************************************************/
627
628static oslFileError osl_psz_removeFile(const sal_Char* pszPath);
629static oslFileError osl_psz_copyFile(const sal_Char* pszPath, const sal_Char* pszDestPath);
630static oslFileError osl_psz_moveFile(const sal_Char* pszPath, const sal_Char* pszDestPath);
631
632
633/******************************************************************************
634 *
635 * Static Module Utility Function Declarations
636 *
637 *****************************************************************************/
638
639static oslFileError oslDoCopy(const sal_Char* pszSourceFileName, const sal_Char* pszDestFileName, mode_t nMode, size_t nSourceSize, int DestFileExists);
640static oslFileError oslChangeFileModes(const sal_Char* pszFileName, mode_t nMode, time_t nAcTime, time_t nModTime, uid_t nUID, gid_t nGID);
641static int oslDoCopyLink(const sal_Char* pszSourceFileName, const sal_Char* pszDestFileName);
642static int oslDoCopyFile(const sal_Char* pszSourceFileName, const sal_Char* pszDestFileName, size_t nSourceSize, mode_t mode);
643static oslFileError oslDoMoveFile(const sal_Char* pszPath, const sal_Char* pszDestPath);
644
645/****************************************************************************/
646/* osl_moveFile */
647/****************************************************************************/
648
649oslFileError SAL_CALL osl_moveFile( rtl_uString* ustrFileURL, rtl_uString* ustrDestURL )
650{
651 char srcPath[PATH_MAX4096];
652 char destPath[PATH_MAX4096];
653 oslFileError eRet;
654
655 OSL_ASSERT( ustrFileURL )do { if (true && (!(ustrFileURL))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/usr/local/src/libreoffice/sal/osl/unx/file_misc.cxx"
":" "655" ": "), "OSL_ASSERT: %s", "ustrFileURL"); } } while
(false)
;
656 OSL_ASSERT( ustrDestURL )do { if (true && (!(ustrDestURL))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/usr/local/src/libreoffice/sal/osl/unx/file_misc.cxx"
":" "656" ": "), "OSL_ASSERT: %s", "ustrDestURL"); } } while
(false)
;
657
658 /* convert source url to system path */
659 eRet = FileURLToPath( srcPath, PATH_MAX4096, ustrFileURL );
660 if( eRet != osl_File_E_None )
661 return eRet;
662
663 /* convert destination url to system path */
664 eRet = FileURLToPath( destPath, PATH_MAX4096, ustrDestURL );
665 if( eRet != osl_File_E_None )
666 return eRet;
667
668#ifdef MACOSX
669 if ( macxp_resolveAlias( srcPath, PATH_MAX4096 ) != 0 || macxp_resolveAlias( destPath, PATH_MAX4096 ) != 0 )
670 return oslTranslateFileError( OSL_FET_ERROR((sal_Bool)1), errno(*__errno_location ()) );
671#endif/* MACOSX */
672
673 return oslDoMoveFile( srcPath, destPath );
674}
675
676/****************************************************************************/
677/* osl_copyFile */
678/****************************************************************************/
679
680oslFileError SAL_CALL osl_copyFile( rtl_uString* ustrFileURL, rtl_uString* ustrDestURL )
681{
682 char srcPath[PATH_MAX4096];
683 char destPath[PATH_MAX4096];
684 oslFileError eRet;
685
686 OSL_ASSERT( ustrFileURL )do { if (true && (!(ustrFileURL))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/usr/local/src/libreoffice/sal/osl/unx/file_misc.cxx"
":" "686" ": "), "OSL_ASSERT: %s", "ustrFileURL"); } } while
(false)
;
687 OSL_ASSERT( ustrDestURL )do { if (true && (!(ustrDestURL))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/usr/local/src/libreoffice/sal/osl/unx/file_misc.cxx"
":" "687" ": "), "OSL_ASSERT: %s", "ustrDestURL"); } } while
(false)
;
688
689 /* convert source url to system path */
690 eRet = FileURLToPath( srcPath, PATH_MAX4096, ustrFileURL );
691 if( eRet != osl_File_E_None )
692 return eRet;
693
694 /* convert destination url to system path */
695 eRet = FileURLToPath( destPath, PATH_MAX4096, ustrDestURL );
696 if( eRet != osl_File_E_None )
697 return eRet;
698
699#ifdef MACOSX
700 if ( macxp_resolveAlias( srcPath, PATH_MAX4096 ) != 0 || macxp_resolveAlias( destPath, PATH_MAX4096 ) != 0 )
701 return oslTranslateFileError( OSL_FET_ERROR((sal_Bool)1), errno(*__errno_location ()) );
702#endif/* MACOSX */
703
704 return osl_psz_copyFile( srcPath, destPath );
705}
706
707/****************************************************************************/
708/* osl_removeFile */
709/****************************************************************************/
710
711oslFileError SAL_CALL osl_removeFile( rtl_uString* ustrFileURL )
712{
713 char path[PATH_MAX4096];
714 oslFileError eRet;
715
716 OSL_ASSERT( ustrFileURL )do { if (true && (!(ustrFileURL))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/usr/local/src/libreoffice/sal/osl/unx/file_misc.cxx"
":" "716" ": "), "OSL_ASSERT: %s", "ustrFileURL"); } } while
(false)
;
717
718 /* convert file url to system path */
719 eRet = FileURLToPath( path, PATH_MAX4096, ustrFileURL );
720 if( eRet != osl_File_E_None )
721 return eRet;
722
723#ifdef MACOSX
724 if ( macxp_resolveAlias( path, PATH_MAX4096 ) != 0 )
725 return oslTranslateFileError( OSL_FET_ERROR((sal_Bool)1), errno(*__errno_location ()) );
726#endif/* MACOSX */
727
728 return osl_psz_removeFile( path );
729}
730
731/******************************************************************************
732 *
733 * Utility Functions
734 *
735 *****************************************************************************/
736
737/*****************************************
738 * oslDoMoveFile
739 ****************************************/
740
741static oslFileError oslDoMoveFile( const sal_Char* pszPath, const sal_Char* pszDestPath)
742{
743 oslFileError tErr=osl_File_E_invalidError;
744
745 tErr = osl_psz_moveFile(pszPath,pszDestPath);
746 if ( tErr == osl_File_E_None )
747 {
748 return tErr;
749 }
750
751 if ( tErr != osl_File_E_XDEV )
752 {
753 return tErr;
754 }
755
756 tErr=osl_psz_copyFile(pszPath,pszDestPath);
757
758 if ( tErr != osl_File_E_None )
759 {
760 osl_psz_removeFile(pszDestPath);
761 return tErr;
762 }
763
764 tErr=osl_psz_removeFile(pszPath);
765
766 return tErr;
767}
768
769/*****************************************
770 * osl_psz_removeFile
771 ****************************************/
772static oslFileError osl_psz_removeFile( const sal_Char* pszPath )
773{
774 int nRet=0;
775 struct stat aStat;
776
777 nRet = lstat_c(pszPath,&aStat);
778 if ( nRet < 0 )
779 {
780 nRet=errno(*__errno_location ());
781 return oslTranslateFileError(OSL_FET_ERROR((sal_Bool)1), nRet);
782 }
783
784 if ( S_ISDIR(aStat.st_mode)((((aStat.st_mode)) & 0170000) == (0040000)) )
785 {
786 return osl_File_E_ISDIR;
787 }
788
789 nRet = unlink(pszPath);
790 if ( nRet < 0 )
791 {
792 nRet=errno(*__errno_location ());
793 return oslTranslateFileError(OSL_FET_ERROR((sal_Bool)1), nRet);
794 }
795
796 return osl_File_E_None;
797}
798
799/*****************************************
800 * osl_psz_moveFile
801 ****************************************/
802
803static oslFileError osl_psz_moveFile(const sal_Char* pszPath, const sal_Char* pszDestPath)
804{
805
806 int nRet = 0;
807
808 nRet = rename(pszPath,pszDestPath);
809
810 if ( nRet < 0 )
811 {
812 nRet=errno(*__errno_location ());
813 return oslTranslateFileError(OSL_FET_ERROR((sal_Bool)1), nRet);
814 }
815
816 return osl_File_E_None;
817}
818
819/*****************************************
820 * osl_psz_copyFile
821 ****************************************/
822
823static oslFileError osl_psz_copyFile( const sal_Char* pszPath, const sal_Char* pszDestPath )
824{
825 time_t nAcTime=0;
826 time_t nModTime=0;
827 uid_t nUID=0;
828 gid_t nGID=0;
829 int nRet=0;
830 mode_t nMode=0;
831 struct stat aFileStat;
832 oslFileError tErr=osl_File_E_invalidError;
833 size_t nSourceSize=0;
834 int DestFileExists=1;
835
836 /* mfe: does the source file really exists? */
837 nRet = lstat_c(pszPath,&aFileStat);
838
839 if ( nRet < 0 )
840 {
841 nRet=errno(*__errno_location ());
842 return oslTranslateFileError(OSL_FET_ERROR((sal_Bool)1), nRet);
843 }
844
845 /* mfe: we do only copy files here! */
846 if ( S_ISDIR(aFileStat.st_mode)((((aFileStat.st_mode)) & 0170000) == (0040000)) )
847 {
848 return osl_File_E_ISDIR;
849 }
850
851 nSourceSize=(size_t)aFileStat.st_size;
852 nMode=aFileStat.st_mode;
853 nAcTime=aFileStat.st_atimest_atim.tv_sec;
854 nModTime=aFileStat.st_mtimest_mtim.tv_sec;
855 nUID=aFileStat.st_uid;
856 nGID=aFileStat.st_gid;
857
858 nRet = stat(pszDestPath,&aFileStat);
859 if ( nRet < 0 )
860 {
861 nRet=errno(*__errno_location ());
862
863 if ( nRet == ENOENT2 )
864 {
865 DestFileExists=0;
866 }
867/* return oslTranslateFileError(nRet);*/
868 }
869
870 /* mfe: the destination file must not be a directory! */
871 if ( nRet == 0 && S_ISDIR(aFileStat.st_mode)((((aFileStat.st_mode)) & 0170000) == (0040000)) )
872 {
873 return osl_File_E_ISDIR;
874 }
875 else
876 {
877 /* mfe: file does not exists or is no dir */
878 }
879
880 tErr = oslDoCopy(pszPath,pszDestPath,nMode,nSourceSize,DestFileExists);
881
882 if ( tErr != osl_File_E_None )
883 {
884 return tErr;
885 }
886
887 /*
888 * mfe: ignore return code
889 * since only the success of the copy is
890 * important
891 */
892 oslChangeFileModes(pszDestPath,nMode,nAcTime,nModTime,nUID,nGID);
893
894 return tErr;
895}
896
897
898/******************************************************************************
899 *
900 * Utility Functions
901 *
902 *****************************************************************************/
903
904/*****************************************
905 * oslDoCopy
906 ****************************************/
907
908#define TMP_DEST_FILE_EXTENSION".osl-tmp" ".osl-tmp"
909
910static oslFileError oslDoCopy(const sal_Char* pszSourceFileName, const sal_Char* pszDestFileName, mode_t nMode, size_t nSourceSize, int DestFileExists)
911{
912 int nRet=0;
913 sal_Char pszTmpDestFile[PATH_MAX4096];
914 size_t size_tmp_dest_buff = sizeof(pszTmpDestFile);
915
916 /* Quick fix for #106048, the whole copy file function seems
917 to be erroneous anyway and needs to be rewritten.
918 */
919 memset(pszTmpDestFile, 0, size_tmp_dest_buff);
920
921 if ( DestFileExists )
922 {
923 strncpy(pszTmpDestFile, pszDestFileName, size_tmp_dest_buff - 1);
924
925 if ((strlen(pszTmpDestFile) + strlen(TMP_DEST_FILE_EXTENSION".osl-tmp")) >= size_tmp_dest_buff)
926 return osl_File_E_NAMETOOLONG;
927
928 strncat(pszTmpDestFile, TMP_DEST_FILE_EXTENSION".osl-tmp", strlen(TMP_DEST_FILE_EXTENSION".osl-tmp"));
929
930 /* FIXME: what if pszTmpDestFile already exists? */
931 /* with getcanonical??? */
932 nRet=rename(pszDestFileName,pszTmpDestFile);
Value stored to 'nRet' is never read
933 }
934
935 /* mfe: should be S_ISREG */
936 if ( !S_ISLNK(nMode)((((nMode)) & 0170000) == (0120000)) )
937 {
938 /* copy SourceFile to DestFile */
939 nRet = oslDoCopyFile(pszSourceFileName,pszDestFileName,nSourceSize, nMode);
940 }
941 /* mfe: OK redundant at the moment */
942 else if ( S_ISLNK(nMode)((((nMode)) & 0170000) == (0120000)) )
943 {
944 nRet = oslDoCopyLink(pszSourceFileName,pszDestFileName);
945 }
946 else
947 {
948 /* mfe: what to do here? */
949 nRet=ENOSYS38;
950 }
951
952 if ( nRet > 0 && DestFileExists == 1 )
953 {
954 unlink(pszDestFileName);
955 rename(pszTmpDestFile,pszDestFileName);
956 }
957
958 if ( nRet > 0 )
959 {
960 return oslTranslateFileError(OSL_FET_ERROR((sal_Bool)1), nRet);
961 }
962
963 if ( DestFileExists == 1 )
964 {
965 unlink(pszTmpDestFile);
966 }
967
968 return osl_File_E_None;
969}
970
971/*****************************************
972 * oslChangeFileModes
973 ****************************************/
974
975static oslFileError oslChangeFileModes( const sal_Char* pszFileName, mode_t nMode, time_t nAcTime, time_t nModTime, uid_t nUID, gid_t nGID)
976{
977 int nRet=0;
978 struct utimbuf aTimeBuffer;
979
980 nRet = chmod(pszFileName,nMode);
981 if ( nRet < 0 )
982 {
983 nRet=errno(*__errno_location ());
984 return oslTranslateFileError(OSL_FET_ERROR((sal_Bool)1), nRet);
985 }
986
987 aTimeBuffer.actime=nAcTime;
988 aTimeBuffer.modtime=nModTime;
989 nRet=utime(pszFileName,&aTimeBuffer);
990 if ( nRet < 0 )
991 {
992 nRet=errno(*__errno_location ());
993 return oslTranslateFileError(OSL_FET_ERROR((sal_Bool)1), nRet);
994 }
995
996 if ( nUID != getuid() )
997 {
998 nUID=getuid();
999 }
1000
1001 nRet=chown(pszFileName,nUID,nGID);
1002 if ( nRet < 0 )
1003 {
1004 nRet=errno(*__errno_location ());
1005
1006 /* mfe: do not return an error here! */
1007 /* return oslTranslateFileError(nRet);*/
1008 }
1009
1010 return osl_File_E_None;
1011}
1012
1013/*****************************************
1014 * oslDoCopyLink
1015 ****************************************/
1016
1017static int oslDoCopyLink(const sal_Char* pszSourceFileName, const sal_Char* pszDestFileName)
1018{
1019 int nRet=0;
1020
1021 /* mfe: if dest file is symbolic link remove the link and place the file instead (hro says so) */
1022 /* mfe: if source is a link copy the link and not the file it points to (hro says so) */
1023 sal_Char pszLinkContent[PATH_MAX4096];
1024
1025 pszLinkContent[0] = '\0';
1026
1027 nRet = readlink(pszSourceFileName,pszLinkContent,PATH_MAX4096);
1028
1029 if ( nRet < 0 )
1030 {
1031 nRet=errno(*__errno_location ());
1032 return nRet;
1033 }
1034 else
1035 pszLinkContent[ nRet ] = 0;
1036
1037 nRet = symlink(pszLinkContent,pszDestFileName);
1038
1039 if ( nRet < 0 )
1040 {
1041 nRet=errno(*__errno_location ());
1042 return nRet;
1043 }
1044
1045 return 0;
1046}
1047
1048/*****************************************
1049 * oslDoCopyFile
1050 ****************************************/
1051
1052static int oslDoCopyFile(const sal_Char* pszSourceFileName, const sal_Char* pszDestFileName, size_t nSourceSize, mode_t mode)
1053{
1054 oslFileHandle SourceFileFH=0;
1055 int DestFileFD=0;
1056 int nRet=0;
1057
1058 if (osl_openFilePath(pszSourceFileName,
1059 &SourceFileFH,
1060 osl_File_OpenFlag_Read0x00000001L|osl_File_OpenFlag_NoLock0x00000008L|osl_File_OpenFlag_NoExcl0x00000020L) != osl_File_E_None)
1061 {
1062 // Let's hope errno is still set relevantly after osl_openFilePath...
1063 nRet=errno(*__errno_location ());
1064 return nRet;
1065 }
1066
1067 DestFileFD=open(pszDestFileName, O_WRONLY01 | O_CREAT0100, mode);
1068
1069 if ( DestFileFD < 0 )
1070 {
1071 nRet=errno(*__errno_location ());
1072 osl_closeFile(SourceFileFH);
1073 return nRet;
1074 }
1075
1076 size_t nRemains = nSourceSize;
1077
1078 if ( nRemains )
1079 {
1080 /* mmap has problems, try the direct streaming */
1081 char pBuffer[0x7FFF];
1082
1083 do
1084 {
1085 size_t nToRead = std::min( sizeof(pBuffer), nRemains );
1086 sal_uInt64 nRead;
1087 sal_Bool succeeded;
1088 if ( osl_readFile( SourceFileFH, pBuffer, nToRead, &nRead ) != osl_File_E_None || nRead > nToRead || nRead == 0 )
1089 break;
1090
1091 succeeded = safeWrite( DestFileFD, pBuffer, nRead );
1092 if ( !succeeded )
1093 break;
1094
1095 // We know nRead <= nToRead, so it must fit in a size_t
1096 nRemains -= (size_t) nRead;
1097 }
1098 while( nRemains );
1099 }
1100
1101 if ( nRemains )
1102 {
1103 if ( errno(*__errno_location ()) )
1104 nRet = errno(*__errno_location ());
1105 else
1106 nRet = ENOSPC28;
1107 }
1108
1109 osl_closeFile( SourceFileFH );
1110 if ( close( DestFileFD ) == -1 && nRet == 0 )
1111 nRet = errno(*__errno_location ());
1112
1113 return nRet;
1114}
1115
1116/* vim:set shiftwidth=4 softtabstop=4 expandtab: */