LCOV - code coverage report
Current view: top level - sal/osl/unx - profile.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 458 767 59.7 %
Date: 2015-06-13 12:38:46 Functions: 30 38 78.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include "system.hxx"
      21             : #include "readwrite_helper.hxx"
      22             : #include "file_url.hxx"
      23             : 
      24             : #include <osl/diagnose.h>
      25             : #include <osl/profile.h>
      26             : #include <osl/process.h>
      27             : #include <osl/thread.h>
      28             : #include <rtl/alloc.h>
      29             : #include <sal/log.hxx>
      30             : 
      31             : #define LINES_INI       32
      32             : #define LINES_ADD       10
      33             : #define SECTIONS_INI    5
      34             : #define SECTIONS_ADD    3
      35             : #define ENTRIES_INI     5
      36             : #define ENTRIES_ADD     3
      37             : 
      38             : #define STR_INI_BOOLYES     "yes"
      39             : #define STR_INI_BOOLON      "on"
      40             : #define STR_INI_BOOLONE     "1"
      41             : #define STR_INI_BOOLNO      "no"
      42             : #define STR_INI_BOOLOFF     "off"
      43             : #define STR_INI_BOOLZERO    "0"
      44             : 
      45             : #define FLG_USER            0x00FF
      46             : #define FLG_AUTOOPEN        0x0100
      47             : #define FLG_MODIFIED        0x0200
      48             : 
      49             : #define DEFAULT_PMODE   (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)
      50             : 
      51             : typedef time_t  osl_TStamp;
      52             : 
      53             : typedef enum _osl_TLockMode
      54             : {
      55             :     un_lock, read_lock, write_lock
      56             : } osl_TLockMode;
      57             : 
      58             : typedef struct _osl_TFile
      59             : {
      60             :     int     m_Handle;
      61             :     sal_Char*   m_pReadPtr;
      62             :     sal_Char    m_ReadBuf[512];
      63             :     sal_Char*   m_pWriteBuf;
      64             :     sal_uInt32  m_nWriteBufLen;
      65             :     sal_uInt32  m_nWriteBufFree;
      66             : } osl_TFile;
      67             : 
      68             : typedef struct _osl_TProfileEntry
      69             : {
      70             :     sal_uInt32  m_Line;
      71             :     sal_uInt32  m_Offset;
      72             :     sal_uInt32  m_Len;
      73             : } osl_TProfileEntry;
      74             : 
      75             : typedef struct _osl_TProfileSection
      76             : {
      77             :     sal_uInt32  m_Line;
      78             :     sal_uInt32  m_Offset;
      79             :     sal_uInt32  m_Len;
      80             :     sal_uInt32  m_NoEntries;
      81             :     sal_uInt32  m_MaxEntries;
      82             :     osl_TProfileEntry*  m_Entries;
      83             : } osl_TProfileSection;
      84             : 
      85             : /* Profile-data structure hidden behind oslProfile: */
      86             : typedef struct _osl_TProfileImpl
      87             : {
      88             :     sal_uInt32  m_Flags;
      89             :     osl_TFile*  m_pFile;
      90             :     osl_TStamp  m_Stamp;
      91             :     sal_Char    m_FileName[PATH_MAX + 1];
      92             :     sal_uInt32  m_NoLines;
      93             :     sal_uInt32  m_MaxLines;
      94             :     sal_uInt32  m_NoSections;
      95             :     sal_uInt32  m_MaxSections;
      96             :     sal_Char**  m_Lines;
      97             :     osl_TProfileSection* m_Sections;
      98             :     pthread_mutex_t m_AccessLock;
      99             :     bool        m_bIsValid;
     100             : } osl_TProfileImpl;
     101             : 
     102             : static osl_TFile* openFileImpl(const sal_Char* pszFilename, oslProfileOption ProfileFlags);
     103             : static osl_TStamp closeFileImpl(osl_TFile* pFile, oslProfileOption Flags);
     104             : static bool   OslProfile_lockFile(const osl_TFile* pFile, osl_TLockMode eMode);
     105             : static bool   OslProfile_rewindFile(osl_TFile* pFile, bool bTruncate);
     106             : static osl_TStamp OslProfile_getFileStamp(osl_TFile* pFile);
     107             : 
     108             : static sal_Char*   OslProfile_getLine(osl_TFile* pFile);
     109             : static bool   OslProfile_putLine(osl_TFile* pFile, const sal_Char *pszLine);
     110             : static sal_Char* stripBlanks(sal_Char* String, sal_uInt32* pLen);
     111             : static sal_Char* addLine(osl_TProfileImpl* pProfile, const sal_Char* Line);
     112             : static sal_Char* insertLine(osl_TProfileImpl* pProfile, const sal_Char* Line, sal_uInt32 LineNo);
     113             : static void removeLine(osl_TProfileImpl* pProfile, sal_uInt32 LineNo);
     114             : static void setEntry(osl_TProfileImpl* pProfile, osl_TProfileSection* pSection,
     115             :                      sal_uInt32 NoEntry, sal_uInt32 Line,
     116             :                      sal_Char* Entry, sal_uInt32 Len);
     117             : static bool addEntry(osl_TProfileImpl* pProfile, osl_TProfileSection *pSection,
     118             :                      int Line, sal_Char* Entry, sal_uInt32 Len);
     119             : static void removeEntry(osl_TProfileSection *pSection, sal_uInt32 NoEntry);
     120             : static bool addSection(osl_TProfileImpl* pProfile, int Line, const sal_Char* Section, sal_uInt32 Len);
     121             : static void removeSection(osl_TProfileImpl* pProfile, osl_TProfileSection *pSection);
     122             : static osl_TProfileSection* findEntry(osl_TProfileImpl* pProfile, const sal_Char* Section,
     123             :                                       const sal_Char* Entry, sal_uInt32 *pNoEntry);
     124             : static bool loadProfile(osl_TFile* pFile, osl_TProfileImpl* pProfile);
     125             : static bool storeProfile(osl_TProfileImpl* pProfile, bool bCleanup);
     126             : static osl_TProfileImpl* acquireProfile(oslProfile Profile, bool bWriteable);
     127             : static bool releaseProfile(osl_TProfileImpl* pProfile);
     128             : 
     129             : static bool writeProfileImpl (osl_TFile* pFile);
     130             : static osl_TFile* osl_openTmpProfileImpl(osl_TProfileImpl*);
     131             : static bool osl_ProfileSwapProfileNames(osl_TProfileImpl*);
     132             : static void osl_ProfileGenerateExtension(const sal_Char* pszFileName, const sal_Char* pszExtension, sal_Char* pszTmpName, int BufferMaxLen);
     133             : static oslProfile SAL_CALL osl_psz_openProfile(const sal_Char *pszProfileName, oslProfileOption Flags);
     134             : 
     135           4 : oslProfile SAL_CALL osl_openProfile(rtl_uString *ustrProfileName, oslProfileOption Options)
     136             : {
     137           4 :     char profilePath[PATH_MAX] = "";
     138             :     return
     139             :         (ustrProfileName == nullptr
     140           4 :          || ustrProfileName->buffer[0] == 0
     141           4 :          || (FileURLToPath(profilePath, PATH_MAX, ustrProfileName)
     142             :              == osl_File_E_None))
     143             :         ? osl_psz_openProfile(profilePath, Options)
     144           8 :         : nullptr;
     145             : }
     146             : 
     147           4 : static oslProfile SAL_CALL osl_psz_openProfile(const sal_Char *pszProfileName, oslProfileOption Flags)
     148             : {
     149             :     osl_TFile*        pFile;
     150             :     osl_TProfileImpl* pProfile;
     151           4 :     bool bRet = false;
     152             : 
     153           4 :     if ( ( pFile = openFileImpl(pszProfileName, Flags ) ) == NULL )
     154             :     {
     155           1 :         return NULL;
     156             :     }
     157             : 
     158           3 :     pProfile = static_cast<osl_TProfileImpl*>(calloc(1, sizeof(osl_TProfileImpl)));
     159             : 
     160           3 :     if ( pProfile == 0 )
     161             :     {
     162           0 :         closeFileImpl(pFile, Flags);
     163           0 :         return 0;
     164             :     }
     165             : 
     166           3 :     pProfile->m_Flags = Flags & FLG_USER;
     167             : 
     168           3 :     if ( Flags & ( osl_Profile_READLOCK | osl_Profile_WRITELOCK | osl_Profile_FLUSHWRITE ) )
     169             :     {
     170           1 :         pProfile->m_pFile = pFile;
     171             :     }
     172             : 
     173           3 :     pthread_mutex_init(&(pProfile->m_AccessLock),PTHREAD_MUTEXATTR_DEFAULT);
     174           3 :     pProfile->m_bIsValid = true;
     175             : 
     176           3 :     pProfile->m_Stamp = OslProfile_getFileStamp(pFile);
     177           3 :     bRet=loadProfile(pFile, pProfile);
     178           3 :     bRet &= realpath(pszProfileName, pProfile->m_FileName) != NULL;
     179             :     SAL_WARN_IF(!bRet, "sal.osl", "realpath(pszProfileName, pProfile->m_FileName) != NULL ==> false");
     180             : 
     181           3 :     if (pProfile->m_pFile == NULL)
     182           2 :         closeFileImpl(pFile,pProfile->m_Flags);
     183             : 
     184           3 :     return pProfile;
     185             : }
     186             : 
     187           3 : sal_Bool SAL_CALL osl_closeProfile(oslProfile Profile)
     188             : {
     189           3 :     osl_TProfileImpl* pProfile = static_cast<osl_TProfileImpl*>(Profile);
     190             :     osl_TProfileImpl* pTmpProfile;
     191             : 
     192           3 :     if ( Profile == 0 )
     193             :     {
     194           0 :         return sal_False;
     195             :     }
     196             : 
     197           3 :     pthread_mutex_lock(&(pProfile->m_AccessLock));
     198             : 
     199           3 :     if ( !pProfile->m_bIsValid )
     200             :     {
     201             :         SAL_WARN("sal.osl", "!pProfile->m_bIsValid");
     202           0 :         pthread_mutex_unlock(&(pProfile->m_AccessLock));
     203             : 
     204           0 :         return sal_False;
     205             :     }
     206             : 
     207           3 :     pProfile->m_bIsValid = false;
     208             : 
     209           3 :     if ( ! ( pProfile->m_Flags & osl_Profile_READLOCK ) && ( pProfile->m_Flags & FLG_MODIFIED ) )
     210             :     {
     211           1 :         pTmpProfile = acquireProfile(Profile, true);
     212             : 
     213           1 :         if ( pTmpProfile != 0 )
     214             :         {
     215           1 :             bool bRet = storeProfile(pTmpProfile, true);
     216             :             SAL_WARN_IF(!bRet, "sal.osl", "storeProfile(pTmpProfile, true) ==> false");
     217             :             (void)bRet;
     218           1 :         }
     219             :     }
     220             :     else
     221             :     {
     222           2 :         pTmpProfile = acquireProfile(Profile, false);
     223             :     }
     224             : 
     225           3 :     if ( pTmpProfile == 0 )
     226             :     {
     227           0 :         pthread_mutex_unlock(&(pProfile->m_AccessLock));
     228             : 
     229             :         SAL_INFO("sal.osl", "Out osl_closeProfile [pProfile==0]");
     230           0 :         return sal_False;
     231             :     }
     232             : 
     233           3 :     pProfile = pTmpProfile;
     234             : 
     235           3 :     if (pProfile->m_pFile != NULL)
     236           3 :         closeFileImpl(pProfile->m_pFile,pProfile->m_Flags);
     237             : 
     238           3 :     pProfile->m_pFile = NULL;
     239           3 :     pProfile->m_FileName[0] = '\0';
     240             : 
     241             :     /* release whole profile data types memory */
     242           3 :     if ( pProfile->m_NoLines > 0)
     243             :     {
     244           2 :         unsigned int idx=0;
     245           2 :         if ( pProfile->m_Lines != 0 )
     246             :         {
     247          22 :             for ( idx = 0 ; idx < pProfile->m_NoLines ; ++idx)
     248             :             {
     249          20 :                 if ( pProfile->m_Lines[idx] != 0 )
     250             :                 {
     251          20 :                     free(pProfile->m_Lines[idx]);
     252          20 :                     pProfile->m_Lines[idx]=0;
     253             :                 }
     254             :             }
     255           2 :             free(pProfile->m_Lines);
     256           2 :             pProfile->m_Lines=0;
     257             :         }
     258           2 :         if ( pProfile->m_Sections != 0 )
     259             :         {
     260             :             /*osl_TProfileSection* pSections=pProfile->m_Sections;*/
     261           4 :             for ( idx = 0 ; idx < pProfile->m_NoSections ; ++idx )
     262             :             {
     263           2 :                 if ( pProfile->m_Sections[idx].m_Entries != 0 )
     264             :                 {
     265           2 :                     free(pProfile->m_Sections[idx].m_Entries);
     266           2 :                     pProfile->m_Sections[idx].m_Entries=0;
     267             :                 }
     268             :             }
     269           2 :             free(pProfile->m_Sections);
     270           2 :             pProfile->m_Sections=0;
     271             :         }
     272             :     }
     273             : 
     274           3 :     pthread_mutex_unlock(&(pProfile->m_AccessLock));
     275             : 
     276           3 :     pthread_mutex_destroy(&(pProfile->m_AccessLock));
     277             : 
     278           3 :     free(pProfile);
     279             : 
     280           3 :     return sal_True;
     281             : }
     282             : 
     283           0 : sal_Bool SAL_CALL osl_flushProfile(oslProfile Profile)
     284             : {
     285           0 :     osl_TProfileImpl* pProfile = static_cast<osl_TProfileImpl*>(Profile);
     286             :     osl_TFile* pFile;
     287           0 :     bool bRet = false;
     288             : 
     289           0 :     if ( pProfile == 0 )
     290             :     {
     291           0 :         return sal_False;
     292             :     }
     293             : 
     294           0 :     pthread_mutex_lock(&(pProfile->m_AccessLock));
     295             : 
     296           0 :     if ( !pProfile->m_bIsValid )
     297             :     {
     298             :         SAL_WARN_IF(!pProfile->m_bIsValid, "sal.osl", "!pProfile->m_bIsValid");
     299           0 :         pthread_mutex_unlock(&(pProfile->m_AccessLock));
     300           0 :         return sal_False;
     301             :     }
     302             : 
     303           0 :     pFile = pProfile->m_pFile;
     304           0 :     if ( !( pFile != 0 && pFile->m_Handle >= 0 ) )
     305             :     {
     306           0 :         pthread_mutex_unlock(&(pProfile->m_AccessLock));
     307             : 
     308           0 :         return sal_False;
     309             :     }
     310             : 
     311           0 :     if ( pProfile->m_Flags & FLG_MODIFIED )
     312             :     {
     313           0 :         bRet = storeProfile(pProfile, false);
     314             :         SAL_WARN_IF(!bRet, "sal.osl", "storeProfile(pProfile, false) ==> false");
     315             :     }
     316             : 
     317           0 :     pthread_mutex_unlock(&(pProfile->m_AccessLock));
     318           0 :     return bRet;
     319             : }
     320             : 
     321           1 : static bool writeProfileImpl(osl_TFile* pFile)
     322             : {
     323             : #if OSL_DEBUG_LEVEL > 1
     324             :     unsigned int nLen=0;
     325             : #endif
     326             : 
     327           1 :     if ( !( pFile != 0 && pFile->m_Handle >= 0 ) || ( pFile->m_pWriteBuf == 0 ) )
     328             :     {
     329           0 :         return false;
     330             :     }
     331             : 
     332             : #if OSL_DEBUG_LEVEL > 1
     333             :     nLen=strlen(pFile->m_pWriteBuf);
     334             :     SAL_WARN_IF(nLen != (pFile->m_nWriteBufLen - pFile->m_nWriteBufFree), "sal.osl", "nLen != (pFile->m_nWriteBufLen - pFile->m_nWriteBufFree)");
     335             : #endif
     336             : 
     337           1 :     if ( !safeWrite(pFile->m_Handle, pFile->m_pWriteBuf, pFile->m_nWriteBufLen - pFile->m_nWriteBufFree) )
     338             :     {
     339             :         SAL_INFO("sal.osl", "write failed " << strerror(errno));
     340           0 :         return false;
     341             :     }
     342             : 
     343           1 :     free(pFile->m_pWriteBuf);
     344           1 :     pFile->m_pWriteBuf=0;
     345           1 :     pFile->m_nWriteBufLen=0;
     346           1 :     pFile->m_nWriteBufFree=0;
     347             : 
     348           1 :     return true;
     349             : }
     350             : 
     351           2 : sal_Bool SAL_CALL osl_readProfileString(oslProfile Profile,
     352             :                                         const sal_Char* pszSection,
     353             :                                         const sal_Char* pszEntry,
     354             :                                         sal_Char* pszString,
     355             :                                         sal_uInt32 MaxLen,
     356             :                                         const sal_Char* pszDefault)
     357             : {
     358             :     sal_uInt32    NoEntry;
     359           2 :     sal_Char* pStr=0;
     360           2 :     osl_TProfileImpl*    pProfile=0;
     361           2 :     osl_TProfileImpl*    pTmpProfile=0;
     362           2 :     bool bRet = false;
     363             : 
     364           2 :     pTmpProfile = static_cast<osl_TProfileImpl*>(Profile);
     365             : 
     366           2 :     if ( pTmpProfile == 0 )
     367             :     {
     368           0 :         return sal_False;
     369             :     }
     370             : 
     371           2 :     pthread_mutex_lock(&(pTmpProfile->m_AccessLock));
     372             : 
     373           2 :     if ( !pTmpProfile->m_bIsValid )
     374             :     {
     375           0 :         pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
     376             : 
     377           0 :         return sal_False;
     378             :     }
     379             : 
     380           2 :     pProfile = acquireProfile(Profile, false);
     381             : 
     382           2 :     if ( pProfile == NULL )
     383             :     {
     384           0 :         pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
     385             : 
     386           0 :         return sal_False;
     387             :     }
     388             : 
     389           2 :     if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
     390             :     {
     391             :         osl_TProfileSection* pSec;
     392           4 :         if (((pSec = findEntry(pProfile, pszSection, pszEntry, &NoEntry)) != NULL) &&
     393           4 :             (NoEntry < pSec->m_NoEntries) &&
     394           2 :             ((pStr = strchr(pProfile->m_Lines[pSec->m_Entries[NoEntry].m_Line],
     395           2 :                             '=')) != NULL))
     396             :         {
     397           2 :             pStr++;
     398             :         }
     399             :         else
     400             :         {
     401           0 :             pStr=const_cast<sal_Char*>(pszDefault);
     402             :         }
     403             : 
     404           2 :         if ( pStr != 0 )
     405             :         {
     406           2 :             pStr = stripBlanks(pStr, NULL);
     407           2 :             MaxLen = (MaxLen - 1 < strlen(pStr)) ? (MaxLen - 1) : strlen(pStr);
     408           2 :             pStr = stripBlanks(pStr, &MaxLen);
     409           2 :             strncpy(pszString, pStr, MaxLen);
     410           2 :             pszString[MaxLen] = '\0';
     411             :         }
     412             :     }
     413             :     else
     414             :     { /* not implemented */ }
     415             : 
     416           2 :     bRet=releaseProfile(pProfile);
     417             :     SAL_WARN_IF(!bRet, "sal.osl", "releaseProfile(pProfile) ==> false");
     418             :     (void)bRet;
     419             : 
     420           2 :     if ( pStr == 0 )
     421             :     {
     422           0 :         pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
     423             : 
     424           0 :         return sal_False;
     425             :     }
     426             : 
     427           2 :     pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
     428             : 
     429           2 :     return sal_True;
     430             : }
     431             : 
     432           0 : sal_Bool SAL_CALL osl_readProfileBool(oslProfile Profile,
     433             :                                       const sal_Char* pszSection,
     434             :                                       const sal_Char* pszEntry,
     435             :                                       sal_Bool Default)
     436             : {
     437             :     sal_Char Line[32];
     438           0 :     Line[0] = '\0';
     439             : 
     440           0 :     if (osl_readProfileString(Profile, pszSection, pszEntry, Line, sizeof(Line), ""))
     441             :     {
     442           0 :         if ((strcasecmp(Line, STR_INI_BOOLYES) == 0) ||
     443           0 :             (strcasecmp(Line, STR_INI_BOOLON)  == 0) ||
     444           0 :             (strcasecmp(Line, STR_INI_BOOLONE) == 0))
     445           0 :             Default = sal_True;
     446             :         else
     447           0 :             if ((strcasecmp(Line, STR_INI_BOOLNO)   == 0) ||
     448           0 :                 (strcasecmp(Line, STR_INI_BOOLOFF)  == 0) ||
     449           0 :                 (strcasecmp(Line, STR_INI_BOOLZERO) == 0))
     450           0 :                 Default = sal_False;
     451             :     }
     452             : 
     453           0 :     return Default;
     454             : }
     455             : 
     456           0 : sal_uInt32 SAL_CALL osl_readProfileIdent(oslProfile Profile,
     457             :                                          const sal_Char* pszSection,
     458             :                                          const sal_Char* pszEntry,
     459             :                                          sal_uInt32 FirstId,
     460             :                                          const sal_Char* Strings[],
     461             :                                          sal_uInt32 Default)
     462             : {
     463             :     sal_uInt32  i;
     464             :     sal_Char    Line[256];
     465           0 :     Line[0] = '\0';
     466             : 
     467           0 :     if (osl_readProfileString(Profile, pszSection, pszEntry, Line, sizeof(Line), ""))
     468             :     {
     469           0 :         i = 0;
     470           0 :         while (Strings[i] != NULL)
     471             :         {
     472           0 :             if (strcasecmp(Line, Strings[i]) == 0)
     473             :             {
     474           0 :                 Default = i + FirstId;
     475           0 :                 break;
     476             :             }
     477           0 :             i++;
     478             :         }
     479             :     }
     480             : 
     481           0 :     return Default;
     482             : }
     483             : 
     484           1 : sal_Bool SAL_CALL osl_writeProfileString(oslProfile Profile,
     485             :                                          const sal_Char* pszSection,
     486             :                                          const sal_Char* pszEntry,
     487             :                                          const sal_Char* pszString)
     488             : {
     489             :     sal_uInt32  i;
     490           1 :     bool bRet = false;
     491             :     sal_uInt32    NoEntry;
     492             :     sal_Char* pStr;
     493           1 :     sal_Char*       Line = 0;
     494             :     osl_TProfileSection* pSec;
     495           1 :     osl_TProfileImpl*    pProfile = 0;
     496           1 :     osl_TProfileImpl*    pTmpProfile = 0;
     497             : 
     498           1 :     pTmpProfile = static_cast<osl_TProfileImpl*>(Profile);
     499             : 
     500           1 :     if ( pTmpProfile == 0 )
     501             :     {
     502           0 :         return sal_False;
     503             :     }
     504             : 
     505           1 :     pthread_mutex_lock(&(pTmpProfile->m_AccessLock));
     506             : 
     507           1 :     if ( !pTmpProfile->m_bIsValid )
     508             :     {
     509             :         SAL_WARN_IF(!pTmpProfile->m_bIsValid, "sal.osl", "!pTmpProfile->m_bIsValid");
     510           0 :         pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
     511             : 
     512           0 :         return sal_False;
     513             :     }
     514             : 
     515           1 :     pProfile=acquireProfile(Profile, true);
     516             : 
     517           1 :     if (pProfile == NULL)
     518             :     {
     519           0 :         pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
     520             : 
     521           0 :         return sal_False;
     522             :     }
     523             : 
     524           1 :     Line = static_cast<sal_Char*>(malloc(strlen(pszEntry)+strlen(pszString)+48));
     525             : 
     526           1 :     if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
     527             :     {
     528           1 :         if ((pSec = findEntry(pProfile, pszSection, pszEntry, &NoEntry)) == NULL)
     529             :         {
     530           1 :             Line[0] = '\0';
     531           1 :             addLine(pProfile, Line);
     532             : 
     533           1 :             Line[0] = '[';
     534           1 :             strcpy(&Line[1], pszSection);
     535           1 :             Line[1 + strlen(pszSection)] = ']';
     536           1 :             Line[2 + strlen(pszSection)] = '\0';
     537             : 
     538           2 :             if (((pStr = addLine(pProfile, Line)) == NULL) ||
     539           1 :                 (! addSection(pProfile, pProfile->m_NoLines - 1, &pStr[1], strlen(pszSection))))
     540             :             {
     541           0 :                 bRet=releaseProfile(pProfile);
     542             :                 SAL_WARN_IF(!bRet, "sal.osl", "releaseProfile(pProfile) ==> false");
     543             : 
     544           0 :                 pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
     545             : 
     546           0 :                 free(Line);
     547           0 :                 return sal_False;
     548             :             }
     549             : 
     550           1 :             pSec = &pProfile->m_Sections[pProfile->m_NoSections - 1];
     551           1 :             NoEntry = pSec->m_NoEntries;
     552             :         }
     553             : 
     554           1 :         Line[0] = '\0';
     555           1 :         strcpy(&Line[0], pszEntry);
     556           1 :         Line[0 + strlen(pszEntry)] = '=';
     557           1 :         strcpy(&Line[1 + strlen(pszEntry)], pszString);
     558             : 
     559           1 :         if (NoEntry >= pSec->m_NoEntries)
     560             :         {
     561           1 :             if (pSec->m_NoEntries > 0)
     562           0 :                 i = pSec->m_Entries[pSec->m_NoEntries - 1].m_Line + 1;
     563             :             else
     564           1 :                 i = pSec->m_Line + 1;
     565             : 
     566           2 :             if (((pStr = insertLine(pProfile, Line, i)) == NULL) ||
     567           1 :                 (! addEntry(pProfile, pSec, i, pStr, strlen(pszEntry))))
     568             :             {
     569           0 :                 bRet=releaseProfile(pProfile);
     570             :                 SAL_WARN_IF(!bRet, "sal.osl", "releaseProfile(pProfile) ==> false");
     571             : 
     572           0 :                 pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
     573           0 :                 free(Line);
     574             : 
     575           0 :                 return sal_False;
     576             :             }
     577             : 
     578           1 :             pProfile->m_Flags |= FLG_MODIFIED;
     579             :         }
     580             :         else
     581             :         {
     582           0 :             i = pSec->m_Entries[NoEntry].m_Line;
     583           0 :             free(pProfile->m_Lines[i]);
     584           0 :             pProfile->m_Lines[i] = strdup(Line);
     585           0 :             setEntry(pProfile, pSec, NoEntry, i, pProfile->m_Lines[i], strlen(pszEntry));
     586             : 
     587           0 :             pProfile->m_Flags |= FLG_MODIFIED;
     588             :         }
     589             :     }
     590             :     else {
     591             :         /* not implemented */
     592             :     }
     593             : 
     594           1 :     bRet = releaseProfile(pProfile);
     595             :     SAL_WARN_IF(!bRet, "sal.osl", "releaseProfile(pProfile) ==> false");
     596             : 
     597           1 :     pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
     598           1 :     if ( Line!= 0 )
     599             :     {
     600           1 :         free(Line);
     601             :     }
     602             : 
     603           1 :     return bRet;
     604             : }
     605             : 
     606           1 : sal_Bool SAL_CALL osl_writeProfileBool(oslProfile Profile,
     607             :                                        const sal_Char* pszSection,
     608             :                                        const sal_Char* pszEntry,
     609             :                                        sal_Bool Value)
     610             : {
     611           1 :     bool bRet = false;
     612             : 
     613           1 :     if (Value)
     614           1 :         bRet=osl_writeProfileString(Profile, pszSection, pszEntry, STR_INI_BOOLONE);
     615             :     else
     616           0 :         bRet=osl_writeProfileString(Profile, pszSection, pszEntry, STR_INI_BOOLZERO);
     617             : 
     618           1 :     return bRet;
     619             : }
     620             : 
     621           0 : sal_Bool SAL_CALL osl_writeProfileIdent(oslProfile Profile,
     622             :                                         const sal_Char* pszSection,
     623             :                                         const sal_Char* pszEntry,
     624             :                                         sal_uInt32 FirstId,
     625             :                                         const sal_Char* Strings[],
     626             :                                         sal_uInt32 Value)
     627             : {
     628           0 :     int i, n = 0;
     629           0 :     bool bRet = false;
     630             : 
     631           0 :     while (Strings[n] != NULL)
     632           0 :         ++n;
     633             : 
     634           0 :     if ((i = Value - FirstId) >= n)
     635           0 :         bRet = false;
     636             :     else
     637           0 :         bRet = osl_writeProfileString(Profile, pszSection, pszEntry, Strings[i]);
     638             : 
     639           0 :     return bRet;
     640             : }
     641             : 
     642           0 : sal_Bool SAL_CALL osl_removeProfileEntry(oslProfile Profile,
     643             :                                          const sal_Char *pszSection,
     644             :                                          const sal_Char *pszEntry)
     645             : {
     646             :     sal_uInt32    NoEntry;
     647           0 :     osl_TProfileImpl*    pProfile = 0;
     648           0 :     osl_TProfileImpl*    pTmpProfile = 0;
     649           0 :     bool bRet = false;
     650             : 
     651           0 :     pTmpProfile = static_cast<osl_TProfileImpl*>(Profile);
     652             : 
     653           0 :     if ( pTmpProfile == 0 )
     654             :     {
     655           0 :         return sal_False;
     656             :     }
     657             : 
     658           0 :     pthread_mutex_lock(&(pTmpProfile->m_AccessLock));
     659             : 
     660           0 :     if ( !pTmpProfile->m_bIsValid )
     661             :     {
     662             :         SAL_WARN_IF(!pTmpProfile->m_bIsValid, "sal.osl", "!pTmpProfile->m_bIsValid");
     663           0 :         pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
     664           0 :         return sal_False;
     665             :     }
     666             : 
     667           0 :     pProfile = acquireProfile(Profile, true);
     668             : 
     669           0 :     if (pProfile == NULL)
     670             :     {
     671           0 :         pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
     672             : 
     673           0 :         return sal_False;
     674             :     }
     675             : 
     676           0 :     if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
     677             :     {
     678             :         osl_TProfileSection* pSec;
     679           0 :         if (((pSec = findEntry(pProfile, pszSection, pszEntry, &NoEntry)) != NULL) &&
     680           0 :             (NoEntry < pSec->m_NoEntries))
     681             :         {
     682           0 :             removeLine(pProfile, pSec->m_Entries[NoEntry].m_Line);
     683           0 :             removeEntry(pSec, NoEntry);
     684           0 :             if (pSec->m_NoEntries == 0)
     685             :             {
     686           0 :                 removeLine(pProfile, pSec->m_Line);
     687             : 
     688             :                 /* remove any empty separation line */
     689           0 :                 if ((pSec->m_Line > 0) && (pProfile->m_Lines[pSec->m_Line - 1][0] == '\0'))
     690           0 :                     removeLine(pProfile, pSec->m_Line - 1);
     691             : 
     692           0 :                 removeSection(pProfile, pSec);
     693             :             }
     694             : 
     695           0 :             pProfile->m_Flags |= FLG_MODIFIED;
     696             :         }
     697             :     }
     698             :     else
     699             :     { /* not implemented */ }
     700             : 
     701           0 :     bRet = releaseProfile(pProfile);
     702             :     SAL_WARN_IF(!bRet, "sal.osl", "releaseProfile(pProfile) ==> false");
     703             : 
     704           0 :     pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
     705             : 
     706           0 :     return bRet;
     707             : }
     708             : 
     709           0 : sal_uInt32 SAL_CALL osl_getProfileSectionEntries(oslProfile Profile,
     710             :                                                  const sal_Char *pszSection,
     711             :                                                  sal_Char* pszBuffer,
     712             :                                                  sal_uInt32 MaxLen)
     713             : {
     714           0 :     sal_uInt32    i, n = 0;
     715             :     sal_uInt32    NoEntry;
     716           0 :     osl_TProfileImpl*    pProfile = 0;
     717           0 :     osl_TProfileImpl*    pTmpProfile = 0;
     718           0 :     bool bRet = false;
     719             : 
     720           0 :     pTmpProfile = static_cast<osl_TProfileImpl*>(Profile);
     721             : 
     722           0 :     if ( pTmpProfile == 0 )
     723             :     {
     724           0 :         return sal_False;
     725             : 
     726             :     }
     727             : 
     728           0 :     pthread_mutex_lock(&(pTmpProfile->m_AccessLock));
     729             : 
     730           0 :     if ( !pTmpProfile->m_bIsValid )
     731             :     {
     732             :         SAL_WARN_IF(!pTmpProfile->m_bIsValid, "sal.osl", "!pTmpProfile->m_bIsValid"); 
     733             : 
     734           0 :         pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
     735             : 
     736           0 :         return sal_False;
     737             :     }
     738             : 
     739           0 :     pProfile = acquireProfile(Profile, false);
     740             : 
     741           0 :     if (pProfile == NULL)
     742             :     {
     743           0 :         pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
     744             : 
     745           0 :         return 0;
     746             :     }
     747             : 
     748           0 :     if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
     749             :     {
     750             :         osl_TProfileSection* pSec;
     751           0 :         if ((pSec = findEntry(pProfile, pszSection, "", &NoEntry)) != NULL)
     752             :         {
     753           0 :             if (MaxLen != 0)
     754             :             {
     755           0 :                 for (i = 0; i < pSec->m_NoEntries; i++)
     756             :                 {
     757           0 :                     if ((n + pSec->m_Entries[i].m_Len + 1) < MaxLen)
     758             :                     {
     759           0 :                         strncpy(&pszBuffer[n], &pProfile->m_Lines[pSec->m_Entries[i].m_Line]
     760           0 :                                 [pSec->m_Entries[i].m_Offset], pSec->m_Entries[i].m_Len);
     761           0 :                         n += pSec->m_Entries[i].m_Len;
     762           0 :                         pszBuffer[n++] = '\0';
     763             :                     }
     764             :                     else
     765           0 :                         break;
     766             : 
     767             :                 }
     768             : 
     769           0 :                 pszBuffer[n++] = '\0';
     770             :             }
     771             :             else
     772             :             {
     773           0 :                 for (i = 0; i < pSec->m_NoEntries; i++)
     774           0 :                     n += pSec->m_Entries[i].m_Len + 1;
     775             : 
     776           0 :                 n += 1;
     777             :             }
     778             :         }
     779             :         else
     780           0 :             n = 0;
     781             :     }
     782             :     else {
     783             :         /* not implemented */
     784             :     }
     785             : 
     786           0 :     bRet=releaseProfile(pProfile);
     787             :     SAL_WARN_IF(!bRet, "sal.osl", "releaseProfile(pProfile) ==> false");
     788             :     (void)bRet;
     789             : 
     790           0 :     pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
     791             : 
     792           0 :     return n;
     793             : }
     794             : 
     795           0 : sal_uInt32 SAL_CALL osl_getProfileSections(oslProfile Profile,
     796             :                                            sal_Char* pszBuffer,
     797             :                                            sal_uInt32 MaxLen)
     798             : {
     799           0 :     sal_uInt32    i, n = 0;
     800           0 :     osl_TProfileImpl*    pProfile = 0;
     801           0 :     osl_TProfileImpl*    pTmpProfile = 0;
     802           0 :     bool bRet = false;
     803             : 
     804           0 :     pTmpProfile = static_cast<osl_TProfileImpl*>(Profile);
     805             : 
     806           0 :     if ( pTmpProfile == 0 )
     807             :     {
     808           0 :         return sal_False;
     809             :     }
     810             : 
     811           0 :     pthread_mutex_lock(&(pTmpProfile->m_AccessLock));
     812             : 
     813           0 :     if ( !pTmpProfile->m_bIsValid )
     814             :     {
     815             :         SAL_WARN_IF(!pTmpProfile->m_bIsValid, "sal.osl", "!pTmpProfile->m_bIsValid"); 
     816           0 :         pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
     817             : 
     818           0 :         return sal_False;
     819             :     }
     820             : 
     821           0 :     pProfile = acquireProfile(Profile, false);
     822             : 
     823           0 :     if (pProfile == NULL)
     824             :     {
     825           0 :         pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
     826             : 
     827           0 :         return 0;
     828             :     }
     829             : 
     830           0 :     if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
     831             :     {
     832           0 :         if (MaxLen != 0)
     833             :         {
     834           0 :             for (i = 0; i < pProfile->m_NoSections; i++)
     835             :             {
     836           0 :                 osl_TProfileSection* pSec = &pProfile->m_Sections[i];
     837             : 
     838           0 :                 if ((n + pSec->m_Len + 1) < MaxLen)
     839             :                 {
     840           0 :                     strncpy(&pszBuffer[n], &pProfile->m_Lines[pSec->m_Line][pSec->m_Offset],
     841           0 :                             pSec->m_Len);
     842           0 :                     n += pSec->m_Len;
     843           0 :                     pszBuffer[n++] = '\0';
     844             :                 }
     845             :                 else
     846           0 :                     break;
     847             :             }
     848             : 
     849           0 :             pszBuffer[n++] = '\0';
     850             :         }
     851             :         else
     852             :         {
     853           0 :             for (i = 0; i < pProfile->m_NoSections; i++)
     854           0 :                 n += pProfile->m_Sections[i].m_Len + 1;
     855             : 
     856           0 :             n += 1;
     857             :         }
     858             :     }
     859             :     else
     860             :     { /* not implemented */ }
     861             : 
     862           0 :     bRet=releaseProfile(pProfile);
     863             :     SAL_WARN_IF(!bRet, "sal.osl", "releaseProfile(pProfile) ==> false");
     864             :     (void)bRet;
     865             : 
     866           0 :     pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
     867             : 
     868           0 :     return n;
     869             : }
     870             : 
     871          16 : static osl_TStamp OslProfile_getFileStamp(osl_TFile* pFile)
     872             : {
     873             :     struct stat status;
     874             : 
     875          16 :     if ( (pFile->m_Handle < 0) || (fstat(pFile->m_Handle, &status) < 0) )
     876             :     {
     877           0 :         return 0;
     878             :     }
     879             : 
     880          16 :     return status.st_mtime;
     881             : }
     882             : 
     883           6 : static bool OslProfile_lockFile(const osl_TFile* pFile, osl_TLockMode eMode)
     884             : {
     885             :     struct flock lock;
     886             :     /* boring hack, but initializers for static vars must be constant */
     887             :     static bool bIsInitialized = false;
     888             :     static bool bLockingDisabled;
     889             : 
     890           6 :     if ( !bIsInitialized )
     891             :     {
     892             :         sal_Char* pEnvValue;
     893           1 :         pEnvValue = getenv( "STAR_PROFILE_LOCKING_DISABLED" );
     894             : 
     895           1 :         if ( pEnvValue == 0 )
     896             :         {
     897           1 :             bLockingDisabled = false;
     898             : 
     899             :         }
     900             :         else
     901             :         {
     902           0 :             bLockingDisabled = true;
     903             :         }
     904             : 
     905           1 :         bIsInitialized = true;
     906             :     }
     907             : 
     908           6 :     if (pFile->m_Handle < 0)
     909             :     {
     910           0 :         return false;
     911             :     }
     912             : 
     913           6 :     if ( bLockingDisabled )
     914             :     {
     915           0 :         return true;
     916             :     }
     917             : 
     918           6 :     lock.l_start  = 0;
     919           6 :     lock.l_whence = SEEK_SET;
     920           6 :     lock.l_len    = 0;
     921             : 
     922           6 :     switch (eMode)
     923             :     {
     924             :         case un_lock:
     925           3 :             lock.l_type = F_UNLCK;
     926           3 :             break;
     927             : 
     928             :         case read_lock:
     929           0 :             lock.l_type = F_RDLCK;
     930           0 :             break;
     931             : 
     932             :         case write_lock:
     933           3 :             lock.l_type = F_WRLCK;
     934           3 :             break;
     935             :     }
     936             : 
     937             : #ifndef MACOSX
     938           6 :      if ( fcntl(pFile->m_Handle, F_SETLKW, &lock) == -1 )
     939             : #else
     940             :     /* Mac OSX will return ENOTSUP for webdav drives so we should ignore it */
     941             :     if ( fcntl(pFile->m_Handle, F_SETLKW, &lock) == -1 && errno != ENOTSUP )
     942             : #endif
     943             :     {
     944             :         SAL_INFO("sal.osl", "fcntl returned -1 (" << strerror(errno) << ")");
     945           0 :         return false;
     946             :     }
     947             : 
     948           6 :     return true;
     949             : }
     950             : 
     951          10 : static osl_TFile* openFileImpl(const sal_Char* pszFilename, oslProfileOption ProfileFlags )
     952             : {
     953             :     int        Flags;
     954          10 :     osl_TFile* pFile = static_cast<osl_TFile*>(calloc(1, sizeof(osl_TFile)));
     955          10 :     bool       bWriteable = false;
     956             : 
     957          10 :     if ( ProfileFlags & ( osl_Profile_WRITELOCK | osl_Profile_FLUSHWRITE ) )
     958             :     {
     959           4 :         bWriteable = true;
     960             :     }
     961             : 
     962          10 :     if (! bWriteable)
     963             :     {
     964           6 :         pFile->m_Handle = open(pszFilename, O_RDONLY);
     965             :         /* mfe: argghh!!! do not check if the file could be openend */
     966             :         /*      default mode expects it that way!!!                 */
     967             :     }
     968             :     else
     969             :     {
     970           8 :         if (((pFile->m_Handle = open(pszFilename, O_RDWR | O_CREAT | O_EXCL, DEFAULT_PMODE)) < 0) &&
     971           4 :             ((pFile->m_Handle = open(pszFilename, O_RDWR)) < 0))
     972             :         {
     973           1 :             free(pFile);
     974           1 :             return NULL;
     975             :         }
     976             :     }
     977             : 
     978             :     /* set close-on-exec flag */
     979           9 :     if ((Flags = fcntl(pFile->m_Handle, F_GETFD, 0)) != -1)
     980             :     {
     981           9 :         Flags |= FD_CLOEXEC;
     982           9 :         int e = fcntl(pFile->m_Handle, F_SETFD, Flags);
     983             :         SAL_INFO_IF(
     984             :             e != 0, "sal.osl",
     985             :             "fcntl to set FD_CLOEXEC failed for " << pszFilename);
     986             :     }
     987             : 
     988           9 :     pFile->m_pWriteBuf=0;
     989           9 :     pFile->m_nWriteBufFree=0;
     990           9 :     pFile->m_nWriteBufLen=0;
     991             : 
     992           9 :     if ( ProfileFlags & (osl_Profile_WRITELOCK | osl_Profile_READLOCK ) )
     993             :     {
     994           3 :         OslProfile_lockFile(pFile, bWriteable ? write_lock : read_lock);
     995             :     }
     996             : 
     997           9 :     return pFile;
     998             : }
     999             : 
    1000           9 : static osl_TStamp closeFileImpl(osl_TFile* pFile, oslProfileOption Flags)
    1001             : {
    1002           9 :     osl_TStamp stamp = 0;
    1003             : 
    1004           9 :     if ( pFile == 0 )
    1005             :     {
    1006           0 :         return stamp;
    1007             :     }
    1008             : 
    1009           9 :     if ( pFile->m_Handle >= 0 )
    1010             :     {
    1011           9 :         stamp = OslProfile_getFileStamp(pFile);
    1012             : 
    1013           9 :         if ( Flags & (osl_Profile_WRITELOCK | osl_Profile_READLOCK ) )
    1014             :         {
    1015           3 :             OslProfile_lockFile(pFile, un_lock);
    1016             :         }
    1017             : 
    1018           9 :         close(pFile->m_Handle);
    1019           9 :         pFile->m_Handle = -1;
    1020             :     }
    1021             : 
    1022           9 :     if ( pFile->m_pWriteBuf )
    1023             :     {
    1024           0 :         free(pFile->m_pWriteBuf);
    1025             :     }
    1026             : 
    1027           9 :     free(pFile);
    1028             : 
    1029           9 :     return stamp;
    1030             : }
    1031             : 
    1032           4 : static bool OslProfile_rewindFile(osl_TFile* pFile, bool bTruncate)
    1033             : {
    1034           4 :     bool bRet = true;
    1035             : 
    1036           4 :     if (pFile->m_Handle >= 0)
    1037             :     {
    1038           4 :         pFile->m_pReadPtr  = pFile->m_ReadBuf + sizeof(pFile->m_ReadBuf);
    1039             : 
    1040           4 :         bRet = (lseek(pFile->m_Handle, SEEK_SET, 0L) == 0L);
    1041             : 
    1042           4 :         if (bTruncate)
    1043             :         {
    1044           1 :             bRet &= (ftruncate(pFile->m_Handle, 0L) == 0);
    1045             :         }
    1046             : 
    1047             :     }
    1048             : 
    1049           4 :     return bRet;
    1050             : }
    1051             : 
    1052          23 : static sal_Char* OslProfile_getLine(osl_TFile* pFile)
    1053             : {
    1054          23 :     int   Max, Free, nLineBytes = 0;
    1055             :     sal_Char* pChr;
    1056          23 :     sal_Char* pLine = NULL;
    1057             :     sal_Char* pNewLine;
    1058             : 
    1059          23 :     if ( pFile == 0 )
    1060             :     {
    1061           0 :         return 0;
    1062             :     }
    1063             : 
    1064          23 :     if (pFile->m_Handle < 0)
    1065           0 :         return NULL;
    1066             : 
    1067          20 :     do
    1068             :     {
    1069          23 :         int Bytes = sizeof(pFile->m_ReadBuf) - (pFile->m_pReadPtr - pFile->m_ReadBuf);
    1070             : 
    1071          23 :         if (Bytes <= 1)
    1072             :         {
    1073             :             /* refill buffer */
    1074           5 :             memcpy(pFile->m_ReadBuf, pFile->m_pReadPtr, Bytes);
    1075           5 :             pFile->m_pReadPtr = pFile->m_ReadBuf;
    1076             : 
    1077           5 :             Free = sizeof(pFile->m_ReadBuf) - Bytes;
    1078             : 
    1079           5 :             if ((Max = read(pFile->m_Handle, &pFile->m_ReadBuf[Bytes], Free)) < 0)
    1080             :             {
    1081             :                 SAL_INFO("sal.osl", "read failed " << strerror(errno));
    1082             : 
    1083           0 :                 if( pLine )
    1084           0 :                     rtl_freeMemory( pLine );
    1085           0 :                 pLine = NULL;
    1086           0 :                 break;
    1087             :             }
    1088             : 
    1089           5 :             if (Max < Free)
    1090             :             {
    1091           5 :                  if ((Max == 0) && ! pLine)
    1092           3 :                      break;
    1093             : 
    1094           2 :                  pFile->m_ReadBuf[Bytes + Max] = '\0';
    1095             :             }
    1096             :         }
    1097             : 
    1098         732 :         for (pChr = pFile->m_pReadPtr;
    1099        2096 :              (*pChr != '\n') && (*pChr != '\r') && (*pChr != '\0') &&
    1100         692 :              (pChr < (pFile->m_ReadBuf + sizeof(pFile->m_ReadBuf) - 1));
    1101             :              pChr++);
    1102             : 
    1103          20 :         Max = pChr - pFile->m_pReadPtr;
    1104          20 :         pNewLine = static_cast<sal_Char*>(rtl_allocateMemory( nLineBytes + Max + 1 ));
    1105          20 :         if( pLine )
    1106             :         {
    1107           0 :             memcpy( pNewLine, pLine, nLineBytes );
    1108           0 :             rtl_freeMemory( pLine );
    1109             :         }
    1110          20 :         memcpy(pNewLine+nLineBytes, pFile->m_pReadPtr, Max);
    1111          20 :         nLineBytes += Max;
    1112          20 :         pNewLine[ nLineBytes ] = 0;
    1113          20 :         pLine = pNewLine;
    1114             : 
    1115          20 :         if (pChr < (pFile->m_ReadBuf + sizeof(pFile->m_ReadBuf) - 1))
    1116             :         {
    1117          20 :             if (*pChr != '\0')
    1118             :             {
    1119          20 :                 if ((pChr[0] == '\r') && (pChr[1] == '\n'))
    1120           0 :                     pChr += 2;
    1121             :                 else
    1122          20 :                     pChr += 1;
    1123             :             }
    1124             : 
    1125          40 :             if ((pChr < (pFile->m_ReadBuf + sizeof(pFile->m_ReadBuf))) &&
    1126          20 :                 (*pChr == '\0'))
    1127           2 :                 pChr = pFile->m_ReadBuf + sizeof(pFile->m_ReadBuf);
    1128             : 
    1129             :             /* setting Max to -1 indicates terminating read loop */
    1130          20 :             Max = -1;
    1131             :         }
    1132             : 
    1133          20 :         pFile->m_pReadPtr = pChr;
    1134             :     }
    1135             :     while (Max > 0) ;
    1136             : 
    1137          23 :     return pLine;
    1138             : }
    1139             : 
    1140           3 : static bool OslProfile_putLine(osl_TFile* pFile, const sal_Char *pszLine)
    1141             : {
    1142           3 :     unsigned int Len = strlen(pszLine);
    1143             : 
    1144           3 :     if ( pFile == 0 || pFile->m_Handle < 0 )
    1145             :     {
    1146           0 :         return false;
    1147             :     }
    1148             : 
    1149           3 :     if ( pFile->m_pWriteBuf == 0 )
    1150             :     {
    1151           1 :         pFile->m_pWriteBuf = static_cast<sal_Char*>(malloc(Len+3));
    1152           1 :         pFile->m_nWriteBufLen = Len+3;
    1153           1 :         pFile->m_nWriteBufFree = Len+3;
    1154             :     }
    1155             :     else
    1156             :     {
    1157           2 :         if ( pFile->m_nWriteBufFree <= Len + 3 )
    1158             :         {
    1159             :             sal_Char* pTmp;
    1160             : 
    1161           1 :             pTmp=static_cast<sal_Char*>(realloc(pFile->m_pWriteBuf,( ( pFile->m_nWriteBufLen + Len ) * 2) ));
    1162           1 :             if ( pTmp == 0 )
    1163             :             {
    1164           0 :                 return false;
    1165             :             }
    1166           1 :             pFile->m_pWriteBuf = pTmp;
    1167           1 :             pFile->m_nWriteBufFree = pFile->m_nWriteBufFree + pFile->m_nWriteBufLen + ( 2 * Len );
    1168           1 :             pFile->m_nWriteBufLen = ( pFile->m_nWriteBufLen + Len ) * 2;
    1169           1 :             memset( (pFile->m_pWriteBuf) + ( pFile->m_nWriteBufLen - pFile->m_nWriteBufFree ), 0, pFile->m_nWriteBufFree);
    1170             :         }
    1171             :     }
    1172             : 
    1173           3 :     memcpy(pFile->m_pWriteBuf + ( pFile->m_nWriteBufLen - pFile->m_nWriteBufFree ),pszLine,Len+1);
    1174           3 :     pFile->m_pWriteBuf[pFile->m_nWriteBufLen - pFile->m_nWriteBufFree + Len]='\n';
    1175           3 :     pFile->m_pWriteBuf[pFile->m_nWriteBufLen - pFile->m_nWriteBufFree + Len + 1]='\0';
    1176             : 
    1177           3 :     pFile->m_nWriteBufFree-=Len+1;
    1178             : 
    1179           3 :     return true;
    1180             : }
    1181             : 
    1182          62 : static sal_Char* stripBlanks(sal_Char* String, sal_uInt32* pLen)
    1183             : {
    1184         102 :     if ( ( pLen != NULL ) && ( *pLen != 0 ) )
    1185             :     {
    1186          80 :         while ((String[*pLen - 1] == ' ') || (String[*pLen - 1] == '\t'))
    1187           0 :             (*pLen)--;
    1188             : 
    1189          80 :         while ( (*String == ' ') || (*String == '\t') )
    1190             :         {
    1191           0 :             String++;
    1192           0 :             (*pLen)--;
    1193             :         }
    1194             :     }
    1195             :     else
    1196          44 :         while ( (*String == ' ') || (*String == '\t') )
    1197           0 :             String++;
    1198             : 
    1199          62 :     return String;
    1200             : }
    1201             : 
    1202          22 : static sal_Char* addLine(osl_TProfileImpl* pProfile, const sal_Char* Line)
    1203             : {
    1204          22 :     if (pProfile->m_NoLines >= pProfile->m_MaxLines)
    1205             :     {
    1206           3 :         if (pProfile->m_Lines == NULL)
    1207             :         {
    1208           3 :             pProfile->m_MaxLines = LINES_INI;
    1209           3 :             pProfile->m_Lines = static_cast<sal_Char **>(malloc(pProfile->m_MaxLines * sizeof(sal_Char *)));
    1210           3 :             memset(pProfile->m_Lines,0,pProfile->m_MaxLines * sizeof(sal_Char *));
    1211             :         }
    1212             :         else
    1213             :         {
    1214           0 :             unsigned int idx=0;
    1215           0 :             unsigned int oldmax=pProfile->m_MaxLines;
    1216             : 
    1217           0 :             pProfile->m_MaxLines += LINES_ADD;
    1218             :             pProfile->m_Lines = static_cast<sal_Char **>(realloc(pProfile->m_Lines,
    1219           0 :                                                  pProfile->m_MaxLines * sizeof(sal_Char *)));
    1220           0 :             for ( idx = oldmax ; idx < pProfile->m_MaxLines ; ++idx )
    1221             :             {
    1222           0 :                 pProfile->m_Lines[idx]=0;
    1223             :             }
    1224             :         }
    1225             :     }
    1226          22 :     if (pProfile->m_Lines == NULL)
    1227             :     {
    1228           0 :         pProfile->m_NoLines  = 0;
    1229           0 :         pProfile->m_MaxLines = 0;
    1230           0 :         return NULL;
    1231             :     }
    1232             : 
    1233          22 :     if ( pProfile->m_Lines[pProfile->m_NoLines] != 0 )
    1234             :     {
    1235           0 :         free(pProfile->m_Lines[pProfile->m_NoLines]);
    1236             :     }
    1237          22 :     pProfile->m_Lines[pProfile->m_NoLines++] = strdup(Line);
    1238             : 
    1239          22 :     return pProfile->m_Lines[pProfile->m_NoLines - 1];
    1240             : }
    1241             : 
    1242           1 : static sal_Char* insertLine(osl_TProfileImpl* pProfile, const sal_Char* Line, sal_uInt32 LineNo)
    1243             : {
    1244           1 :     if (pProfile->m_NoLines >= pProfile->m_MaxLines)
    1245             :     {
    1246           0 :         if (pProfile->m_Lines == NULL)
    1247             :         {
    1248           0 :             pProfile->m_MaxLines = LINES_INI;
    1249           0 :             pProfile->m_Lines = static_cast<sal_Char **>(malloc(pProfile->m_MaxLines * sizeof(sal_Char *)));
    1250           0 :             memset(pProfile->m_Lines,0,pProfile->m_MaxLines * sizeof(sal_Char *));
    1251             :         }
    1252             :         else
    1253             :         {
    1254           0 :             pProfile->m_MaxLines += LINES_ADD;
    1255             :             pProfile->m_Lines = static_cast<sal_Char **>(realloc(pProfile->m_Lines,
    1256           0 :                                                  pProfile->m_MaxLines * sizeof(sal_Char *)));
    1257             : 
    1258           0 :             memset(&pProfile->m_Lines[pProfile->m_NoLines],
    1259             :                 0,
    1260           0 :                 (pProfile->m_MaxLines - pProfile->m_NoLines - 1) * sizeof(sal_Char*));
    1261             :         }
    1262             : 
    1263           0 :         if (pProfile->m_Lines == NULL)
    1264             :         {
    1265           0 :             pProfile->m_NoLines  = 0;
    1266           0 :             pProfile->m_MaxLines = 0;
    1267           0 :             return NULL;
    1268             :         }
    1269             :     }
    1270             : 
    1271           1 :     LineNo = LineNo > pProfile->m_NoLines ? pProfile->m_NoLines : LineNo;
    1272             : 
    1273           1 :     if (LineNo < pProfile->m_NoLines)
    1274             :     {
    1275             :         sal_uInt32 i, n;
    1276             : 
    1277           0 :         memmove(&pProfile->m_Lines[LineNo + 1], &pProfile->m_Lines[LineNo],
    1278           0 :                 (pProfile->m_NoLines - LineNo) * sizeof(sal_Char *));
    1279             : 
    1280             :         /* adjust line references */
    1281           0 :         for (i = 0; i < pProfile->m_NoSections; i++)
    1282             :         {
    1283           0 :             osl_TProfileSection* pSec = &pProfile->m_Sections[i];
    1284             : 
    1285           0 :             if (pSec->m_Line >= LineNo)
    1286           0 :                 pSec->m_Line++;
    1287             : 
    1288           0 :             for (n = 0; n < pSec->m_NoEntries; n++)
    1289           0 :                 if (pSec->m_Entries[n].m_Line >= LineNo)
    1290           0 :                     pSec->m_Entries[n].m_Line++;
    1291             :         }
    1292             :     }
    1293             : 
    1294           1 :     pProfile->m_NoLines++;
    1295             : 
    1296           1 :     pProfile->m_Lines[LineNo] = strdup(Line);
    1297             : 
    1298           1 :     return pProfile->m_Lines[LineNo];
    1299             : }
    1300             : 
    1301           3 : static void removeLine(osl_TProfileImpl* pProfile, sal_uInt32 LineNo)
    1302             : {
    1303           3 :     if (LineNo < pProfile->m_NoLines)
    1304             :     {
    1305           3 :         free(pProfile->m_Lines[LineNo]);
    1306           3 :         pProfile->m_Lines[LineNo]=0;
    1307           3 :         if (pProfile->m_NoLines - LineNo > 1)
    1308             :         {
    1309             :             sal_uInt32 i, n;
    1310             : 
    1311           0 :             memmove(&pProfile->m_Lines[LineNo], &pProfile->m_Lines[LineNo + 1],
    1312           0 :                     (pProfile->m_NoLines - LineNo - 1) * sizeof(sal_Char *));
    1313             : 
    1314           0 :             memset(&pProfile->m_Lines[pProfile->m_NoLines - 1],
    1315             :                 0,
    1316           0 :                 (pProfile->m_MaxLines - pProfile->m_NoLines) * sizeof(sal_Char*));
    1317             : 
    1318             :             /* adjust line references */
    1319           0 :             for (i = 0; i < pProfile->m_NoSections; i++)
    1320             :             {
    1321           0 :                 osl_TProfileSection* pSec = &pProfile->m_Sections[i];
    1322             : 
    1323           0 :                 if (pSec->m_Line > LineNo)
    1324           0 :                     pSec->m_Line--;
    1325             : 
    1326           0 :                 for (n = 0; n < pSec->m_NoEntries; n++)
    1327           0 :                     if (pSec->m_Entries[n].m_Line > LineNo)
    1328           0 :                         pSec->m_Entries[n].m_Line--;
    1329             :             }
    1330             :         }
    1331             :         else
    1332             :         {
    1333           3 :             pProfile->m_Lines[LineNo] = 0;
    1334             :         }
    1335             : 
    1336           3 :         pProfile->m_NoLines--;
    1337             :     }
    1338             : 
    1339           3 :     return;
    1340             : }
    1341             : 
    1342          19 : static void setEntry(osl_TProfileImpl* pProfile, osl_TProfileSection* pSection,
    1343             :                      sal_uInt32 NoEntry, sal_uInt32 Line,
    1344             :                      sal_Char* Entry, sal_uInt32 Len)
    1345             : {
    1346          19 :     Entry = stripBlanks(Entry, &Len);
    1347          19 :     pSection->m_Entries[NoEntry].m_Line   = Line;
    1348          19 :     pSection->m_Entries[NoEntry].m_Offset = Entry - pProfile->m_Lines[Line];
    1349          19 :     pSection->m_Entries[NoEntry].m_Len    = Len;
    1350             : 
    1351          19 :     return;
    1352             : }
    1353             : 
    1354          19 : static bool addEntry(osl_TProfileImpl* pProfile,
    1355             :                      osl_TProfileSection *pSection,
    1356             :                      int Line, sal_Char* Entry,
    1357             :                      sal_uInt32 Len)
    1358             : {
    1359          19 :     if (pSection != NULL)
    1360             :     {
    1361          19 :         if (pSection->m_NoEntries >= pSection->m_MaxEntries)
    1362             :         {
    1363           7 :             if (pSection->m_Entries == NULL)
    1364             :             {
    1365           3 :                 pSection->m_MaxEntries = ENTRIES_INI;
    1366             :                 pSection->m_Entries = static_cast<osl_TProfileEntry *>(malloc(
    1367           3 :                                 pSection->m_MaxEntries * sizeof(osl_TProfileEntry)));
    1368             :             }
    1369             :             else
    1370             :             {
    1371           4 :                 pSection->m_MaxEntries += ENTRIES_ADD;
    1372             :                 pSection->m_Entries = static_cast<osl_TProfileEntry *>(realloc(pSection->m_Entries,
    1373           4 :                                 pSection->m_MaxEntries * sizeof(osl_TProfileEntry)));
    1374             :             }
    1375             : 
    1376           7 :             if (pSection->m_Entries == NULL)
    1377             :             {
    1378           0 :                 pSection->m_NoEntries  = 0;
    1379           0 :                 pSection->m_MaxEntries = 0;
    1380           0 :                 return false;
    1381             :             }
    1382             :         }
    1383             : 
    1384          19 :         pSection->m_NoEntries++;
    1385             : 
    1386          19 :         Entry = stripBlanks(Entry, &Len);
    1387             :         setEntry(pProfile, pSection, pSection->m_NoEntries - 1, Line,
    1388          19 :                  Entry, Len);
    1389             : 
    1390          19 :         return true;
    1391             :     }
    1392             : 
    1393           0 :     return false;
    1394             : }
    1395             : 
    1396           0 : static void removeEntry(osl_TProfileSection *pSection, sal_uInt32 NoEntry)
    1397             : {
    1398           0 :     if (NoEntry < pSection->m_NoEntries)
    1399             :     {
    1400           0 :         if (pSection->m_NoEntries - NoEntry > 1)
    1401             :         {
    1402           0 :             memmove(&pSection->m_Entries[NoEntry],
    1403           0 :                     &pSection->m_Entries[NoEntry + 1],
    1404           0 :                     (pSection->m_NoEntries - NoEntry - 1) * sizeof(osl_TProfileEntry));
    1405           0 :             pSection->m_Entries[pSection->m_NoEntries - 1].m_Line=0;
    1406           0 :             pSection->m_Entries[pSection->m_NoEntries - 1].m_Offset=0;
    1407           0 :             pSection->m_Entries[pSection->m_NoEntries - 1].m_Len=0;
    1408             :         }
    1409             : 
    1410           0 :         pSection->m_NoEntries--;
    1411             :     }
    1412             : 
    1413           0 :     return;
    1414             : }
    1415             : 
    1416           3 : static bool addSection(osl_TProfileImpl* pProfile, int Line, const sal_Char* Section, sal_uInt32 Len)
    1417             : {
    1418           3 :     if (pProfile->m_NoSections >= pProfile->m_MaxSections)
    1419             :     {
    1420           3 :         if (pProfile->m_Sections == NULL)
    1421             :         {
    1422           3 :             pProfile->m_MaxSections = SECTIONS_INI;
    1423           3 :             pProfile->m_Sections = static_cast<osl_TProfileSection *>(malloc(pProfile->m_MaxSections * sizeof(osl_TProfileSection)));
    1424           3 :             memset(pProfile->m_Sections,0,pProfile->m_MaxSections * sizeof(osl_TProfileSection));
    1425             :         }
    1426             :         else
    1427             :         {
    1428           0 :             unsigned int idx=0;
    1429           0 :             unsigned int oldmax=pProfile->m_MaxSections;
    1430             : 
    1431           0 :             pProfile->m_MaxSections += SECTIONS_ADD;
    1432             :             pProfile->m_Sections = static_cast<osl_TProfileSection *>(realloc(pProfile->m_Sections,
    1433           0 :                                           pProfile->m_MaxSections * sizeof(osl_TProfileSection)));
    1434           0 :             for ( idx = oldmax ; idx < pProfile->m_MaxSections ; ++idx )
    1435             :             {
    1436           0 :                 pProfile->m_Sections[idx].m_Entries=0;
    1437             :             }
    1438             :         }
    1439             : 
    1440           3 :         if (pProfile->m_Sections == NULL)
    1441             :         {
    1442           0 :             pProfile->m_NoSections = 0;
    1443           0 :             pProfile->m_MaxSections = 0;
    1444           0 :             return false;
    1445             :         }
    1446             :     }
    1447             : 
    1448           3 :     pProfile->m_NoSections++;
    1449             : 
    1450           3 :     if ( pProfile->m_Sections[(pProfile->m_NoSections) - 1].m_Entries != 0 )
    1451             :     {
    1452           0 :          free(pProfile->m_Sections[(pProfile->m_NoSections) - 1].m_Entries);
    1453             :     }
    1454           3 :     pProfile->m_Sections[pProfile->m_NoSections - 1].m_Entries    = NULL;
    1455           3 :     pProfile->m_Sections[pProfile->m_NoSections - 1].m_NoEntries  = 0;
    1456           3 :     pProfile->m_Sections[pProfile->m_NoSections - 1].m_MaxEntries = 0;
    1457             : 
    1458           3 :     pProfile->m_Sections[pProfile->m_NoSections - 1].m_Line = Line;
    1459           3 :     pProfile->m_Sections[pProfile->m_NoSections - 1].m_Offset = Section - pProfile->m_Lines[Line];
    1460           3 :     pProfile->m_Sections[pProfile->m_NoSections - 1].m_Len = Len;
    1461             : 
    1462           3 :     return true;
    1463             : }
    1464             : 
    1465           1 : static void removeSection(osl_TProfileImpl* pProfile, osl_TProfileSection *pSection)
    1466             : {
    1467             :     sal_uInt32 Section;
    1468             : 
    1469           1 :     if ((Section = pSection - pProfile->m_Sections) < pProfile->m_NoSections)
    1470             :     {
    1471           1 :         free (pSection->m_Entries);
    1472           1 :         pSection->m_Entries=0;
    1473           1 :         if (pProfile->m_NoSections - Section > 1)
    1474             :         {
    1475           0 :             memmove(&pProfile->m_Sections[Section], &pProfile->m_Sections[Section + 1],
    1476           0 :                     (pProfile->m_NoSections - Section - 1) * sizeof(osl_TProfileSection));
    1477             : 
    1478           0 :             memset(&pProfile->m_Sections[pProfile->m_NoSections - 1],
    1479             :                    0,
    1480           0 :                    (pProfile->m_MaxSections - pProfile->m_NoSections) * sizeof(osl_TProfileSection));
    1481           0 :             pProfile->m_Sections[pProfile->m_NoSections - 1].m_Entries = 0;
    1482             :         }
    1483             :         else
    1484             :         {
    1485           1 :             pSection->m_Entries = 0;
    1486             :         }
    1487             : 
    1488           1 :         pProfile->m_NoSections--;
    1489             :     }
    1490             : 
    1491           1 :     return;
    1492             : }
    1493             : 
    1494           3 : static osl_TProfileSection* findEntry(osl_TProfileImpl* pProfile,
    1495             :                                       const sal_Char* Section,
    1496             :                                       const sal_Char* Entry,
    1497             :                                       sal_uInt32 *pNoEntry)
    1498             : {
    1499             :     static  sal_uInt32    Sect = 0;
    1500             :             sal_uInt32    i, n;
    1501             :             sal_uInt32  Len;
    1502           3 :             osl_TProfileSection* pSec=0;
    1503             : 
    1504           3 :     Len = strlen(Section);
    1505             : 
    1506           3 :     n = Sect;
    1507             : 
    1508           3 :     for (i = 0; i < pProfile->m_NoSections; i++)
    1509             :     {
    1510           2 :         n %= pProfile->m_NoSections;
    1511           2 :         pSec = &pProfile->m_Sections[n];
    1512           4 :         if ((Len == pSec->m_Len) &&
    1513           2 :             (strncasecmp(Section, &pProfile->m_Lines[pSec->m_Line][pSec->m_Offset], pSec->m_Len)
    1514             :              == 0))
    1515           2 :             break;
    1516           0 :         n++;
    1517             :     }
    1518             : 
    1519           3 :     Sect = n;
    1520             : 
    1521           3 :     if (i < pProfile->m_NoSections)
    1522             :     {
    1523           2 :         Len = strlen(Entry);
    1524             : 
    1525           2 :         *pNoEntry = pSec->m_NoEntries;
    1526             : 
    1527          10 :         for (i = 0; i < pSec->m_NoEntries; i++)
    1528             :         {
    1529          10 :             const sal_Char* pStr = &pProfile->m_Lines[pSec->m_Entries[i].m_Line]
    1530          10 :                                      [pSec->m_Entries[i].m_Offset];
    1531          12 :             if ((Len == pSec->m_Entries[i].m_Len) &&
    1532           2 :                 (strncasecmp(Entry, pStr, pSec->m_Entries[i].m_Len)
    1533             :                  == 0))
    1534             :             {
    1535           2 :                 *pNoEntry = i;
    1536           2 :                 break;
    1537             :             }
    1538             :         }
    1539             :     }
    1540             :     else
    1541           1 :         pSec = NULL;
    1542             : 
    1543           3 :     return pSec;
    1544             : }
    1545             : 
    1546           3 : static bool loadProfile(osl_TFile* pFile, osl_TProfileImpl* pProfile)
    1547             : {
    1548             :     sal_uInt32  i;
    1549             :     sal_Char*   pStr;
    1550             :     sal_Char*   pChar;
    1551             : 
    1552             :     sal_Char* pLine;
    1553             : 
    1554           3 :     if ( !pFile )
    1555             :     {
    1556           0 :         return false;
    1557             :     }
    1558             : 
    1559           3 :     if ( !pProfile )
    1560             :     {
    1561           0 :         return false;
    1562             :     }
    1563             : 
    1564           3 :     pProfile->m_NoLines    = 0;
    1565           3 :     pProfile->m_NoSections = 0;
    1566             : 
    1567           3 :     OSL_VERIFY(OslProfile_rewindFile(pFile, false));
    1568             : 
    1569          26 :     while ( ( pLine=OslProfile_getLine(pFile) ) != 0 )
    1570             :     {
    1571          20 :         sal_Char* bWasAdded = addLine( pProfile, pLine );
    1572          20 :         rtl_freeMemory( pLine );
    1573             :         SAL_WARN_IF(!bWasAdded, "sal.osl", "addLine( pProfile, pLine ) ==> false");
    1574          20 :         if ( ! bWasAdded )
    1575           0 :             return false;
    1576             :     }
    1577             : 
    1578          23 :     for (i = 0; i < pProfile->m_NoLines; i++)
    1579             :     {
    1580          20 :         pStr = stripBlanks(pProfile->m_Lines[i], NULL);
    1581             : 
    1582          20 :         if ((*pStr == '\0') || (*pStr == ';'))
    1583           0 :             continue;
    1584             : 
    1585          22 :         if ((*pStr != '[') || ((pChar = strrchr(pStr, ']')) == NULL) ||
    1586           2 :             ((pChar - pStr) <= 2))
    1587             :         {
    1588             :             /* insert entry */
    1589             : 
    1590          18 :             if (pProfile->m_NoSections < 1)
    1591           0 :                 continue;
    1592             : 
    1593          18 :             if ((pChar = strchr(pStr, '=')) == NULL)
    1594           0 :                 pChar = pStr + strlen(pStr);
    1595             : 
    1596          36 :             if (! addEntry(pProfile, &pProfile->m_Sections[pProfile->m_NoSections - 1],
    1597          36 :                            i, pStr, pChar - pStr))
    1598             :             {
    1599             :                 SAL_WARN("sal.osl", "Adding entry => false");
    1600           0 :                 continue;
    1601             :             }
    1602             : 
    1603             :         }
    1604             :         else
    1605             :         {
    1606             :             /* new section */
    1607             : 
    1608           2 :             if (! addSection(pProfile, i, pStr + 1, pChar - pStr - 1))
    1609             :             {
    1610             :                 SAL_WARN("sal.osl", "Adding section => false");
    1611           0 :                 continue;
    1612             :             }
    1613             : 
    1614             :         }
    1615             :     }
    1616             : 
    1617           3 :     return true;
    1618             : }
    1619             : 
    1620           1 : static bool storeProfile(osl_TProfileImpl* pProfile, bool bCleanup)
    1621             : {
    1622           1 :     if (pProfile->m_Lines != NULL)
    1623             :     {
    1624           1 :         if (pProfile->m_Flags & FLG_MODIFIED)
    1625             :         {
    1626             :             sal_uInt32 i;
    1627             : 
    1628           1 :             osl_TFile* pTmpFile = osl_openTmpProfileImpl(pProfile);
    1629             : 
    1630           1 :             if ( pTmpFile == 0 )
    1631             :             {
    1632           0 :                 return false;
    1633             :             }
    1634             : 
    1635           1 :             OSL_VERIFY(OslProfile_rewindFile(pTmpFile, true));
    1636             : 
    1637           4 :             for ( i = 0 ; i < pProfile->m_NoLines ; i++ )
    1638             :             {
    1639           3 :                 OSL_VERIFY(OslProfile_putLine(pTmpFile, pProfile->m_Lines[i]));
    1640             :             }
    1641             : 
    1642           1 :             if ( ! writeProfileImpl(pTmpFile) )
    1643             :             {
    1644           0 :                 if ( pTmpFile->m_pWriteBuf != 0 )
    1645             :                 {
    1646           0 :                     free(pTmpFile->m_pWriteBuf);
    1647             :                 }
    1648             : 
    1649           0 :                 pTmpFile->m_pWriteBuf=0;
    1650           0 :                 pTmpFile->m_nWriteBufLen=0;
    1651           0 :                 pTmpFile->m_nWriteBufFree=0;
    1652             : 
    1653           0 :                 closeFileImpl(pTmpFile,pProfile->m_Flags);
    1654             : 
    1655           0 :                 return false;
    1656             :             }
    1657             : 
    1658           1 :             pProfile->m_Flags &= ~FLG_MODIFIED;
    1659             : 
    1660           1 :             closeFileImpl(pProfile->m_pFile,pProfile->m_Flags);
    1661           1 :             closeFileImpl(pTmpFile,pProfile->m_Flags);
    1662             : 
    1663           1 :             osl_ProfileSwapProfileNames(pProfile);
    1664             : 
    1665           1 :             pProfile->m_pFile = openFileImpl(pProfile->m_FileName,pProfile->m_Flags);
    1666             : 
    1667             :         }
    1668             : 
    1669           1 :         if (bCleanup)
    1670             :         {
    1671           5 :             while (pProfile->m_NoLines > 0)
    1672           3 :                 removeLine(pProfile, pProfile->m_NoLines - 1);
    1673             : 
    1674           1 :             free(pProfile->m_Lines);
    1675           1 :             pProfile->m_Lines = NULL;
    1676           1 :             pProfile->m_NoLines = 0;
    1677           1 :             pProfile->m_MaxLines = 0;
    1678             : 
    1679           3 :             while (pProfile->m_NoSections > 0)
    1680           1 :                 removeSection(pProfile, &pProfile->m_Sections[pProfile->m_NoSections - 1]);
    1681             : 
    1682           1 :             free(pProfile->m_Sections);
    1683           1 :             pProfile->m_Sections = NULL;
    1684           1 :             pProfile->m_NoSections = 0;
    1685           1 :             pProfile->m_MaxSections = 0;
    1686             :         }
    1687             :     }
    1688             : 
    1689           1 :     return true;
    1690             : }
    1691             : 
    1692           1 : static osl_TFile* osl_openTmpProfileImpl(osl_TProfileImpl* pProfile)
    1693             : {
    1694           1 :     osl_TFile* pFile=0;
    1695           1 :     sal_Char const * pszExtension = "tmp";
    1696             :     sal_Char pszTmpName[PATH_MAX];
    1697           1 :     oslProfileOption PFlags=0;
    1698             : 
    1699           1 :     pszTmpName[0] = '\0';
    1700             : 
    1701             :     /* generate tmp profilename */
    1702           1 :     osl_ProfileGenerateExtension(pProfile->m_FileName, pszExtension, pszTmpName, PATH_MAX);
    1703             : 
    1704           1 :     if ( pszTmpName[0] == 0 )
    1705             :     {
    1706           0 :         return 0;
    1707             :     }
    1708             : 
    1709           1 :     if ( ! ( pProfile->m_Flags & osl_Profile_READLOCK ) )
    1710             :     {
    1711           1 :         PFlags |= osl_Profile_WRITELOCK;
    1712             :     }
    1713             : 
    1714             :     /* open this file */
    1715           1 :     pFile = openFileImpl(pszTmpName,pProfile->m_Flags | PFlags);
    1716             : 
    1717             :     /* return new pFile */
    1718           1 :     return pFile;
    1719             : }
    1720             : 
    1721           1 : static bool osl_ProfileSwapProfileNames(osl_TProfileImpl* pProfile)
    1722             : {
    1723             :     sal_Char pszBakFile[PATH_MAX];
    1724             :     sal_Char pszTmpFile[PATH_MAX];
    1725             : 
    1726           1 :     pszBakFile[0] = '\0';
    1727           1 :     pszTmpFile[0] = '\0';
    1728             : 
    1729           1 :     osl_ProfileGenerateExtension(pProfile->m_FileName, "bak", pszBakFile, PATH_MAX);
    1730           1 :     osl_ProfileGenerateExtension(pProfile->m_FileName, "tmp", pszTmpFile, PATH_MAX);
    1731             : 
    1732             :     /* unlink bak */
    1733           1 :     unlink( pszBakFile );
    1734             : 
    1735             :     // Rename ini -> bak, then tmp -> ini:
    1736           1 :     return rename( pProfile->m_FileName, pszBakFile ) == 0
    1737           1 :         && rename( pszTmpFile, pProfile->m_FileName ) == 0;
    1738             : }
    1739             : 
    1740           3 : static void osl_ProfileGenerateExtension(const sal_Char* pszFileName, const sal_Char* pszExtension, sal_Char* pszTmpName, int BufferMaxLen)
    1741             : {
    1742           3 :     sal_Char* cursor = pszTmpName;
    1743             :     int len;
    1744             : 
    1745             :     /* concatenate filename + "." + extension, limited to the size of the
    1746             :      * output buffer; in case of overrun, data is truncated at the end...
    1747             :      * and the result is always 0-terminated.
    1748             :      */
    1749           3 :     len = strlen(pszFileName);
    1750           3 :     if(len < BufferMaxLen)
    1751             :     {
    1752           3 :         memcpy(cursor, pszFileName, len);
    1753           3 :         cursor += len;
    1754           3 :         BufferMaxLen -= len;
    1755             :     }
    1756             :     else
    1757             :     {
    1758           0 :         memcpy(cursor, pszFileName, BufferMaxLen - 1);
    1759           0 :         cursor += BufferMaxLen - 1;
    1760           0 :         BufferMaxLen = 1;
    1761             :     }
    1762           3 :     if(BufferMaxLen > 1)
    1763             :     {
    1764           3 :         *cursor++ = '.';
    1765           3 :         BufferMaxLen -= 1;
    1766             :     }
    1767           3 :     len = strlen(pszExtension);
    1768           3 :     if(len < BufferMaxLen)
    1769             :     {
    1770           3 :         memcpy(cursor, pszExtension, len);
    1771           3 :         cursor += len;
    1772             :     }
    1773             :     else
    1774             :     {
    1775           0 :         memcpy(cursor, pszExtension, BufferMaxLen - 1);
    1776           0 :         cursor += BufferMaxLen - 1;
    1777             :     }
    1778           3 :     *cursor = 0;
    1779             : 
    1780           3 :     return;
    1781             : }
    1782             : 
    1783           6 : static osl_TProfileImpl* acquireProfile(oslProfile Profile, bool bWriteable)
    1784             : {
    1785           6 :     osl_TProfileImpl* pProfile = static_cast<osl_TProfileImpl*>(Profile);
    1786           6 :     oslProfileOption PFlags=0;
    1787             : 
    1788           6 :     if ( bWriteable )
    1789             :     {
    1790           2 :         PFlags = osl_Profile_DEFAULT | osl_Profile_WRITELOCK;
    1791             :     }
    1792             :     else
    1793             :     {
    1794           4 :         PFlags = osl_Profile_DEFAULT;
    1795             :     }
    1796             : 
    1797           6 :     if (pProfile == NULL)
    1798             :     {
    1799           0 :         if ( ( pProfile = static_cast<osl_TProfileImpl*>(osl_openProfile(0, PFlags )) ) != NULL )
    1800             :         {
    1801           0 :             pProfile->m_Flags |= FLG_AUTOOPEN;
    1802             :         }
    1803             :     }
    1804             :     else
    1805             :     {
    1806           6 :         if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
    1807             :         {
    1808           6 :             if (! (pProfile->m_Flags & (osl_Profile_READLOCK | osl_Profile_WRITELOCK | osl_Profile_FLUSHWRITE )))
    1809             :             {
    1810             :                 osl_TStamp Stamp;
    1811             : 
    1812           4 :                 if (! (pProfile->m_pFile = openFileImpl(pProfile->m_FileName, pProfile->m_Flags | PFlags )))
    1813           0 :                     return NULL;
    1814             : 
    1815           4 :                 Stamp = OslProfile_getFileStamp(pProfile->m_pFile);
    1816             : 
    1817           4 :                 if (memcmp(&Stamp, &(pProfile->m_Stamp), sizeof(osl_TStamp)))
    1818             :                 {
    1819           0 :                     pProfile->m_Stamp = Stamp;
    1820           0 :                     bool bRet = loadProfile(pProfile->m_pFile, pProfile);
    1821             :                     SAL_WARN_IF(!bRet, "sal.osl", "loadProfile(pProfile->m_pFile, pProfile) ==> false");
    1822             :                     (void)bRet;
    1823             :                 }
    1824             :             }
    1825             :             else
    1826             :             {
    1827             :                 /* A readlock file could not be written */
    1828           2 :                 if ((pProfile->m_Flags & osl_Profile_READLOCK) && bWriteable)
    1829             :                 {
    1830           0 :                     return NULL;
    1831             :                 }
    1832             :             }
    1833             :         }
    1834             :     }
    1835             : 
    1836           6 :     return pProfile;
    1837             : }
    1838             : 
    1839           3 : static bool releaseProfile(osl_TProfileImpl* pProfile)
    1840             : {
    1841           3 :     if ( pProfile == 0 )
    1842             :     {
    1843           0 :         return false;
    1844             :     }
    1845             : 
    1846           3 :     if (pProfile->m_Flags & FLG_AUTOOPEN)
    1847             :     {
    1848           0 :         return osl_closeProfile(static_cast<oslProfile>(pProfile));
    1849             :     }
    1850             :     else
    1851             :     {
    1852           3 :         if (! (pProfile->m_Flags & (osl_Profile_READLOCK | osl_Profile_WRITELOCK | osl_Profile_FLUSHWRITE )))
    1853             :         {
    1854           2 :             if (pProfile->m_Flags & FLG_MODIFIED)
    1855             :             {
    1856           0 :                 bool bRet = storeProfile(pProfile, false);
    1857             :                 SAL_WARN_IF(!bRet, "sal.osl", "storeProfile(pProfile, false) ==> false");
    1858             :                 (void)bRet;
    1859             :             }
    1860             : 
    1861           2 :             closeFileImpl(pProfile->m_pFile,pProfile->m_Flags);
    1862           2 :             pProfile->m_pFile = NULL;
    1863             :         }
    1864             :     }
    1865             : 
    1866           3 :     return true;
    1867             : }
    1868             : 
    1869             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11