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

Generated by: LCOV version 1.10