Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  profile.cxx   Sprache: C

 
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */


#include "system.hxx"
#include "readwrite_helper.hxx"
#include "file_url.hxx"
#include "unixerrnostring.hxx"

#include <osl/diagnose.h>
#include <osl/profile.h>
#include <sal/log.hxx>

#include <fcntl.h>
#include <limits.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>

#define LINES_INI       32
#define LINES_ADD       10
#define SECTIONS_INI    5
#define SECTIONS_ADD    3
#define ENTRIES_INI     5
#define ENTRIES_ADD     3

#define STR_INI_BOOLYES     "yes"
#define STR_INI_BOOLON      "on"
#define STR_INI_BOOLONE     "1"
#define STR_INI_BOOLNO      "no"
#define STR_INI_BOOLOFF     "off"
#define STR_INI_BOOLZERO    "0"

#define FLG_USER            0x00FF
#define FLG_AUTOOPEN        0x0100
#define FLG_MODIFIED        0x0200

#define DEFAULT_PMODE   (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)

typedef time_t  osl_TStamp;

namespace {

enum osl_TLockMode
{
    un_lock, read_lock, write_lock
};

struct osl_TFile
{
    int     m_Handle;
    char*   m_pReadPtr;
    char    m_ReadBuf[512];
    char*   m_pWriteBuf;
    sal_uInt32  m_nWriteBufLen;
    sal_uInt32  m_nWriteBufFree;
};

struct osl_TProfileEntry
{
    sal_uInt32  m_Line;
    sal_uInt32  m_Offset;
    sal_uInt32  m_Len;
};

struct osl_TProfileSection
{
    sal_uInt32  m_Line;
    sal_uInt32  m_Offset;
    sal_uInt32  m_Len;
    sal_uInt32  m_NoEntries;
    sal_uInt32  m_MaxEntries;
    osl_TProfileEntry*  m_Entries;
};

/* Profile-data structure hidden behind oslProfile: */
struct osl_TProfileImpl
{
    sal_uInt32  m_Flags;
    osl_TFile*  m_pFile;
    osl_TStamp  m_Stamp;
    char    m_FileName[PATH_MAX + 1];
    sal_uInt32  m_NoLines;
    sal_uInt32  m_MaxLines;
    sal_uInt32  m_NoSections;
    sal_uInt32  m_MaxSections;
    char**  m_Lines;
    osl_TProfileSection* m_Sections;
    pthread_mutex_t m_AccessLock;
    bool        m_bIsValid;
};

}

static osl_TFile* openFileImpl(const char* pszFilename, oslProfileOption ProfileFlags);
static osl_TStamp closeFileImpl(osl_TFile* pFile, oslProfileOption Flags);
static bool   OslProfile_lockFile(const osl_TFile* pFile, osl_TLockMode eMode);
static bool   OslProfile_rewindFile(osl_TFile* pFile, bool bTruncate);
static osl_TStamp OslProfile_getFileStamp(osl_TFile* pFile);

static char*   OslProfile_getLine(osl_TFile* pFile);
static bool   OslProfile_putLine(osl_TFile* pFile, const char *pszLine);
static char* stripBlanks(char* String, sal_uInt32* pLen);
static char* addLine(osl_TProfileImpl* pProfile, const char* Line);
static char* insertLine(osl_TProfileImpl* pProfile, const char* Line, sal_uInt32 LineNo);
static void removeLine(osl_TProfileImpl* pProfile, sal_uInt32 LineNo);
static void setEntry(osl_TProfileImpl* pProfile, osl_TProfileSection* pSection,
                     sal_uInt32 NoEntry, sal_uInt32 Line,
                     char* Entry, sal_uInt32 Len);
static bool addEntry(osl_TProfileImpl* pProfile, osl_TProfileSection *pSection,
                     int Line, char* Entry, sal_uInt32 Len);
static void removeEntry(osl_TProfileSection *pSection, sal_uInt32 NoEntry);
static bool addSection(osl_TProfileImpl* pProfile, int Line, const char* Section, sal_uInt32 Len);
static void removeSection(osl_TProfileImpl* pProfile, osl_TProfileSection *pSection);
static osl_TProfileSection* findEntry(osl_TProfileImpl* pProfile, const char* Section,
                                      const char* Entry, sal_uInt32 *pNoEntry);
static bool loadProfile(osl_TFile* pFile, osl_TProfileImpl* pProfile);
static bool storeProfile(osl_TProfileImpl* pProfile, bool bCleanup);
static osl_TProfileImpl* acquireProfile(oslProfile Profile, bool bWriteable);
static bool releaseProfile(osl_TProfileImpl* pProfile);

static bool writeProfileImpl (osl_TFile* pFile);
static osl_TFile* osl_openTmpProfileImpl(osl_TProfileImpl*);
static bool osl_ProfileSwapProfileNames(osl_TProfileImpl*);
static void osl_ProfileGenerateExtension(const char* pszFileName, const char* pszExtension, char* pszTmpName, int BufferMaxLen);
static oslProfile osl_psz_openProfile(const char *pszProfileName, oslProfileOption Flags);

oslProfile SAL_CALL osl_openProfile(rtl_uString *ustrProfileName, oslProfileOption Options)
{
    char profilePath[PATH_MAX] = "";
    return
        (ustrProfileName == nullptr
         || ustrProfileName->buffer[0] == 0
         || (FileURLToPath(profilePath, PATH_MAX, ustrProfileName)
             == osl_File_E_None))
        ? osl_psz_openProfile(profilePath, Options)
        : nullptr;
}

static oslProfile osl_psz_openProfile(const char *pszProfileName, oslProfileOption Flags)
{
    osl_TFile*        pFile;
    osl_TProfileImpl* pProfile;
    bool bRet = false;

    if ( ( pFile = openFileImpl(pszProfileName, Flags ) ) == nullptr )
    {
        return nullptr;
    }

    pProfile = static_cast<osl_TProfileImpl*>(calloc(1, sizeof(osl_TProfileImpl)));

    if ( pProfile == nullptr )
    {
        closeFileImpl(pFile, Flags);
        return nullptr;
    }

    pProfile->m_Flags = Flags & FLG_USER;

    if ( Flags & ( osl_Profile_READLOCK | osl_Profile_WRITELOCK | osl_Profile_FLUSHWRITE ) )
    {
        pProfile->m_pFile = pFile;
    }

    pthread_mutex_init(&(pProfile->m_AccessLock),PTHREAD_MUTEXATTR_DEFAULT);
    pProfile->m_bIsValid = true;

    pProfile->m_Stamp = OslProfile_getFileStamp(pFile);
    bRet=loadProfile(pFile, pProfile);
    bRet &= realpath(pszProfileName, pProfile->m_FileName) != nullptr;
    SAL_WARN_IF(!bRet, "sal.osl""realpath(pszProfileName, pProfile->m_FileName) != NULL ==> false");

    if (pProfile->m_pFile == nullptr)
        closeFileImpl(pFile,pProfile->m_Flags);

    // coverity[leaked_storage] - pFile is not leaked
    return pProfile;
}

sal_Bool SAL_CALL osl_closeProfile(oslProfile Profile)
{
    osl_TProfileImpl* pProfile = static_cast<osl_TProfileImpl*>(Profile);
    osl_TProfileImpl* pTmpProfile;

    if ( Profile == nullptr )
    {
        return false;
    }

    pthread_mutex_lock(&(pProfile->m_AccessLock));

    if ( !pProfile->m_bIsValid )
    {
        SAL_WARN("sal.osl""!pProfile->m_bIsValid");
        pthread_mutex_unlock(&(pProfile->m_AccessLock));

        return false;
    }

    pProfile->m_bIsValid = false;

    if ( ! ( pProfile->m_Flags & osl_Profile_READLOCK ) && ( pProfile->m_Flags & FLG_MODIFIED ) )
    {
        pTmpProfile = acquireProfile(Profile, true);

        if ( pTmpProfile != nullptr )
        {
            bool bRet = storeProfile(pTmpProfile, true);
            SAL_WARN_IF(!bRet, "sal.osl""storeProfile(pTmpProfile, true) ==> false");
        }
    }
    else
    {
        pTmpProfile = acquireProfile(Profile, false);
    }

    if ( pTmpProfile == nullptr )
    {
        pthread_mutex_unlock(&(pProfile->m_AccessLock));

        SAL_INFO("sal.osl""Out osl_closeProfile [pProfile==0]");
        return false;
    }

    pProfile = pTmpProfile;

    if (pProfile->m_pFile != nullptr)
        closeFileImpl(pProfile->m_pFile,pProfile->m_Flags);

    pProfile->m_pFile = nullptr;
    pProfile->m_FileName[0] = '\0';

    /* release whole profile data types memory */
    if ( pProfile->m_NoLines > 0)
    {
        unsigned int idx=0;
        if ( pProfile->m_Lines != nullptr )
        {
            for ( idx = 0 ; idx < pProfile->m_NoLines ; ++idx)
            {
                if ( pProfile->m_Lines[idx] != nullptr )
                {
                    free(pProfile->m_Lines[idx]);
                    pProfile->m_Lines[idx]=nullptr;
                }
            }
            free(pProfile->m_Lines);
            pProfile->m_Lines=nullptr;
        }
        if ( pProfile->m_Sections != nullptr )
        {
            /*osl_TProfileSection* pSections=pProfile->m_Sections;*/
            for ( idx = 0 ; idx < pProfile->m_NoSections ; ++idx )
            {
                if ( pProfile->m_Sections[idx].m_Entries != nullptr )
                {
                    free(pProfile->m_Sections[idx].m_Entries);
                    pProfile->m_Sections[idx].m_Entries=nullptr;
                }
            }
            free(pProfile->m_Sections);
            pProfile->m_Sections=nullptr;
        }
    }

    pthread_mutex_unlock(&(pProfile->m_AccessLock));

    pthread_mutex_destroy(&(pProfile->m_AccessLock));

    free(pProfile);

    return true;
}

sal_Bool SAL_CALL osl_flushProfile(oslProfile Profile)
{
    osl_TProfileImpl* pProfile = static_cast<osl_TProfileImpl*>(Profile);
    osl_TFile* pFile;
    bool bRet = false;

    if ( pProfile == nullptr )
    {
        return false;
    }

    pthread_mutex_lock(&(pProfile->m_AccessLock));

    if ( !pProfile->m_bIsValid )
    {
        SAL_WARN_IF(!pProfile->m_bIsValid, "sal.osl""!pProfile->m_bIsValid");
        pthread_mutex_unlock(&(pProfile->m_AccessLock));
        return false;
    }

    pFile = pProfile->m_pFile;
    if ( pFile == nullptr || pFile->m_Handle < 0 )
    {
        pthread_mutex_unlock(&(pProfile->m_AccessLock));

        return false;
    }

    if ( pProfile->m_Flags & FLG_MODIFIED )
    {
        bRet = storeProfile(pProfile, false);
        SAL_WARN_IF(!bRet, "sal.osl""storeProfile(pProfile, false) ==> false");
    }

    pthread_mutex_unlock(&(pProfile->m_AccessLock));
    return bRet;
}

static bool writeProfileImpl(osl_TFile* pFile)
{
    if ( pFile == nullptr || pFile->m_Handle < 0 || pFile->m_pWriteBuf == nullptr )
    {
        return false;
    }

    SAL_WARN_IF(
        (strlen(pFile->m_pWriteBuf)
         != pFile->m_nWriteBufLen - pFile->m_nWriteBufFree),
        "sal.osl",
        strlen(pFile->m_pWriteBuf) << " != "
            << (pFile->m_nWriteBufLen - pFile->m_nWriteBufFree));

    if ( !safeWrite(pFile->m_Handle, pFile->m_pWriteBuf, pFile->m_nWriteBufLen - pFile->m_nWriteBufFree) )
    {
        SAL_INFO("sal.osl""write failed: " << UnixErrnoString(errno));
        return false;
    }

    free(pFile->m_pWriteBuf);
    pFile->m_pWriteBuf=nullptr;
    pFile->m_nWriteBufLen=0;
    pFile->m_nWriteBufFree=0;

    return true;
}

sal_Bool SAL_CALL osl_readProfileString(oslProfile Profile,
                                        const char* pszSection,
                                        const char* pszEntry,
                                        char* pszString,
                                        sal_uInt32 MaxLen,
                                        const char* pszDefault)
{
    sal_uInt32    NoEntry;
    char* pStr=nullptr;
    osl_TProfileImpl*    pProfile=nullptr;
    osl_TProfileImpl*    pTmpProfile=nullptr;
    bool bRet = false;

    pTmpProfile = static_cast<osl_TProfileImpl*>(Profile);

    if ( pTmpProfile == nullptr )
    {
        return false;
    }

    pthread_mutex_lock(&(pTmpProfile->m_AccessLock));

    if ( !pTmpProfile->m_bIsValid )
    {
        pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));

        return false;
    }

    pProfile = acquireProfile(Profile, false);

    if ( pProfile == nullptr )
    {
        pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));

        return false;
    }

    if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
    {
        osl_TProfileSection* pSec = findEntry(pProfile, pszSection, pszEntry, &NoEntry);
        if ((pSec != nullptr) &&
            (NoEntry < pSec->m_NoEntries) &&
            ((pStr = strchr(pProfile->m_Lines[pSec->m_Entries[NoEntry].m_Line],
                            '=')) != nullptr))
        {
            pStr++;
        }
        else
        {
            pStr=const_cast<char*>(pszDefault);
        }

        if ( pStr != nullptr )
        {
            pStr = stripBlanks(pStr, nullptr);
            MaxLen = (MaxLen - 1 < strlen(pStr)) ? (MaxLen - 1) : strlen(pStr);
            pStr = stripBlanks(pStr, &MaxLen);
            strncpy(pszString, pStr, MaxLen);
            pszString[MaxLen] = '\0';
        }
    }
    else
    { /* not implemented */ }

    bRet=releaseProfile(pProfile);
    SAL_WARN_IF(!bRet, "sal.osl""releaseProfile(pProfile) ==> false");

    if ( pStr == nullptr )
    {
        pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));

        return false;
    }

    pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));

    return true;
}

sal_Bool SAL_CALL osl_readProfileBool(oslProfile Profile,
                                      const char* pszSection,
                                      const char* pszEntry,
                                      sal_Bool Default)
{
    char Line[32];
    Line[0] = '\0';

    if (osl_readProfileString(Profile, pszSection, pszEntry, Line, sizeof(Line), ""))
    {
        if ((strcasecmp(Line, STR_INI_BOOLYES) == 0) ||
            (strcasecmp(Line, STR_INI_BOOLON)  == 0) ||
            (strcasecmp(Line, STR_INI_BOOLONE) == 0))
            Default = true;
        else
            if ((strcasecmp(Line, STR_INI_BOOLNO)   == 0) ||
                (strcasecmp(Line, STR_INI_BOOLOFF)  == 0) ||
                (strcasecmp(Line, STR_INI_BOOLZERO) == 0))
                Default = false;
    }

    return Default;
}

sal_uInt32 SAL_CALL osl_readProfileIdent(oslProfile Profile,
                                         const char* pszSection,
                                         const char* pszEntry,
                                         sal_uInt32 FirstId,
                                         const char* Strings[],
                                         sal_uInt32 Default)
{
    sal_uInt32  i;
    char    Line[256];
    Line[0] = '\0';

    if (osl_readProfileString(Profile, pszSection, pszEntry, Line, sizeof(Line), ""))
    {
        i = 0;
        while (Strings[i] != nullptr)
        {
            if (strcasecmp(Line, Strings[i]) == 0)
            {
                Default = i + FirstId;
                break;
            }
            i++;
        }
    }

    return Default;
}

sal_Bool SAL_CALL osl_writeProfileString(oslProfile Profile,
                                         const char* pszSection,
                                         const char* pszEntry,
                                         const char* pszString)
{
    bool bRet = false;
    sal_uInt32    NoEntry;
    char* pStr;
    char*       Line = nullptr;
    osl_TProfileImpl*    pProfile = nullptr;
    osl_TProfileImpl*    pTmpProfile = static_cast<osl_TProfileImpl*>(Profile);

    if ( pTmpProfile == nullptr )
    {
        return false;
    }

    pthread_mutex_lock(&(pTmpProfile->m_AccessLock));

    if ( !pTmpProfile->m_bIsValid )
    {
        SAL_WARN_IF(!pTmpProfile->m_bIsValid, "sal.osl""!pTmpProfile->m_bIsValid");
        pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));

        return false;
    }

    pProfile=acquireProfile(Profile, true);

    if (pProfile == nullptr)
    {
        pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));

        return false;
    }

    Line = static_cast<char*>(malloc(strlen(pszEntry)+strlen(pszString)+48));

    if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
    {
        osl_TProfileSection* pSec;
        if ((pSec = findEntry(pProfile, pszSection, pszEntry, &NoEntry)) == nullptr)
        {
            Line[0] = '\0';
            addLine(pProfile, Line);

            Line[0] = '[';
            strcpy(&Line[1], pszSection);
            Line[1 + strlen(pszSection)] = ']';
            Line[2 + strlen(pszSection)] = '\0';

            pStr = addLine(pProfile, Line);
            if ((pStr == nullptr) ||
                (! addSection(pProfile, pProfile->m_NoLines - 1, &pStr[1], strlen(pszSection))))
            {
                bRet=releaseProfile(pProfile);
                SAL_WARN_IF(!bRet, "sal.osl""releaseProfile(pProfile) ==> false");

                pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));

                free(Line);
                return false;
            }

            pSec = &pProfile->m_Sections[pProfile->m_NoSections - 1];
            NoEntry = pSec->m_NoEntries;
        }

        Line[0] = '\0';
        strcpy(&Line[0], pszEntry);
        Line[0 + strlen(pszEntry)] = '=';
        strcpy(&Line[1 + strlen(pszEntry)], pszString);

        if (NoEntry >= pSec->m_NoEntries)
        {
            sal_uInt32  i;
            if (pSec->m_NoEntries > 0)
                i = pSec->m_Entries[pSec->m_NoEntries - 1].m_Line + 1;
            else
                i = pSec->m_Line + 1;

            pStr = insertLine(pProfile, Line, i);
            if ((pStr == nullptr) ||
                (! addEntry(pProfile, pSec, i, pStr, strlen(pszEntry))))
            {
                bRet=releaseProfile(pProfile);
                SAL_WARN_IF(!bRet, "sal.osl""releaseProfile(pProfile) ==> false");

                pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
                free(Line);

                return false;
            }

            pProfile->m_Flags |= FLG_MODIFIED;
        }
        else
        {
            sal_uInt32  i = pSec->m_Entries[NoEntry].m_Line;
            free(pProfile->m_Lines[i]);
            pProfile->m_Lines[i] = strdup(Line);
            setEntry(pProfile, pSec, NoEntry, i, pProfile->m_Lines[i], strlen(pszEntry));

            pProfile->m_Flags |= FLG_MODIFIED;
        }
    }
    else {
        /* not implemented */
    }

    bRet = releaseProfile(pProfile);
    SAL_WARN_IF(!bRet, "sal.osl""releaseProfile(pProfile) ==> false");

    pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
    if ( Line!= nullptr )
    {
        free(Line);
    }

    return bRet;
}

sal_Bool SAL_CALL osl_writeProfileBool(oslProfile Profile,
                                       const char* pszSection,
                                       const char* pszEntry,
                                       sal_Bool Value)
{
    bool bRet = false;

    if (Value)
        bRet=osl_writeProfileString(Profile, pszSection, pszEntry, STR_INI_BOOLONE);
    else
        bRet=osl_writeProfileString(Profile, pszSection, pszEntry, STR_INI_BOOLZERO);

    return bRet;
}

sal_Bool SAL_CALL osl_writeProfileIdent(oslProfile Profile,
                                        const char* pszSection,
                                        const char* pszEntry,
                                        sal_uInt32 FirstId,
                                        const char* Strings[],
                                        sal_uInt32 Value)
{
    int i, n = 0;
    bool bRet = false;

    while (Strings[n] != nullptr)
        ++n;

    if ((i = Value - FirstId) >= n)
        bRet = false;
    else
        bRet = osl_writeProfileString(Profile, pszSection, pszEntry, Strings[i]);

    return bRet;
}

sal_Bool SAL_CALL osl_removeProfileEntry(oslProfile Profile,
                                         const char *pszSection,
                                         const char *pszEntry)
{
    sal_uInt32    NoEntry;
    osl_TProfileImpl*    pProfile = nullptr;
    osl_TProfileImpl*    pTmpProfile = nullptr;
    bool bRet = false;

    pTmpProfile = static_cast<osl_TProfileImpl*>(Profile);

    if ( pTmpProfile == nullptr )
    {
        return false;
    }

    pthread_mutex_lock(&(pTmpProfile->m_AccessLock));

    if ( !pTmpProfile->m_bIsValid )
    {
        SAL_WARN_IF(!pTmpProfile->m_bIsValid, "sal.osl""!pTmpProfile->m_bIsValid");
        pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
        return false;
    }

    pProfile = acquireProfile(Profile, true);

    if (pProfile == nullptr)
    {
        pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));

        return false;
    }

    if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
    {
        osl_TProfileSection* pSec = findEntry(pProfile, pszSection, pszEntry, &NoEntry);
        if ((pSec != nullptr) &&
            (NoEntry < pSec->m_NoEntries))
        {
            removeLine(pProfile, pSec->m_Entries[NoEntry].m_Line);
            removeEntry(pSec, NoEntry);
            if (pSec->m_NoEntries == 0)
            {
                removeLine(pProfile, pSec->m_Line);

                /* remove any empty separation line */
                if ((pSec->m_Line > 0) && (pProfile->m_Lines[pSec->m_Line - 1][0] == '\0'))
                    removeLine(pProfile, pSec->m_Line - 1);

                removeSection(pProfile, pSec);
            }

            pProfile->m_Flags |= FLG_MODIFIED;
        }
    }
    else
    { /* not implemented */ }

    bRet = releaseProfile(pProfile);
    SAL_WARN_IF(!bRet, "sal.osl""releaseProfile(pProfile) ==> false");

    pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));

    return bRet;
}

sal_uInt32 SAL_CALL osl_getProfileSectionEntries(oslProfile Profile,
                                                 const char *pszSection,
                                                 char* pszBuffer,
                                                 sal_uInt32 MaxLen)
{
    sal_uInt32    i, n = 0;
    sal_uInt32    NoEntry;
    osl_TProfileImpl*    pProfile = nullptr;
    osl_TProfileImpl*    pTmpProfile = nullptr;
    bool bRet = false;

    pTmpProfile = static_cast<osl_TProfileImpl*>(Profile);

    if ( pTmpProfile == nullptr )
    {
        return 0;

    }

    pthread_mutex_lock(&(pTmpProfile->m_AccessLock));

    if ( !pTmpProfile->m_bIsValid )
    {
        SAL_WARN_IF(!pTmpProfile->m_bIsValid, "sal.osl""!pTmpProfile->m_bIsValid"); 

        pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));

        return 0;
    }

    pProfile = acquireProfile(Profile, false);

    if (pProfile == nullptr)
    {
        pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));

        return 0;
    }

    if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
    {
        osl_TProfileSection* pSec;
        if ((pSec = findEntry(pProfile, pszSection, "", &NoEntry)) != nullptr)
        {
            if (MaxLen != 0)
            {
                for (i = 0; i < pSec->m_NoEntries; i++)
                {
                    if ((n + pSec->m_Entries[i].m_Len + 1) < MaxLen)
                    {
                        strncpy(&pszBuffer[n], &pProfile->m_Lines[pSec->m_Entries[i].m_Line]
                                [pSec->m_Entries[i].m_Offset], pSec->m_Entries[i].m_Len);
                        n += pSec->m_Entries[i].m_Len;
                        pszBuffer[n++] = '\0';
                    }
                    else
                        break;

                }

                pszBuffer[n++] = '\0';
            }
            else
            {
                for (i = 0; i < pSec->m_NoEntries; i++)
                    n += pSec->m_Entries[i].m_Len + 1;

                n += 1;
            }
        }
        else
            n = 0;
    }
    else {
        /* not implemented */
    }

    bRet=releaseProfile(pProfile);
    SAL_WARN_IF(!bRet, "sal.osl""releaseProfile(pProfile) ==> false");

    pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));

    return n;
}

sal_uInt32 SAL_CALL osl_getProfileSections(oslProfile Profile,
                                           char* pszBuffer,
                                           sal_uInt32 MaxLen)
{
    sal_uInt32    i, n = 0;
    osl_TProfileImpl*    pProfile = nullptr;
    osl_TProfileImpl*    pTmpProfile = nullptr;
    bool bRet = false;

    pTmpProfile = static_cast<osl_TProfileImpl*>(Profile);

    if ( pTmpProfile == nullptr )
    {
        return 0;
    }

    pthread_mutex_lock(&(pTmpProfile->m_AccessLock));

    if ( !pTmpProfile->m_bIsValid )
    {
        SAL_WARN_IF(!pTmpProfile->m_bIsValid, "sal.osl""!pTmpProfile->m_bIsValid"); 
        pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));

        return 0;
    }

    pProfile = acquireProfile(Profile, false);

    if (pProfile == nullptr)
    {
        pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));

        return 0;
    }

    if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
    {
        if (MaxLen != 0)
        {
            for (i = 0; i < pProfile->m_NoSections; i++)
            {
                osl_TProfileSection* pSec = &pProfile->m_Sections[i];

                if ((n + pSec->m_Len + 1) < MaxLen)
                {
                    strncpy(&pszBuffer[n], &pProfile->m_Lines[pSec->m_Line][pSec->m_Offset],
                            pSec->m_Len);
                    n += pSec->m_Len;
                    pszBuffer[n++] = '\0';
                }
                else
                    break;
            }

            pszBuffer[n++] = '\0';
        }
        else
        {
            for (i = 0; i < pProfile->m_NoSections; i++)
                n += pProfile->m_Sections[i].m_Len + 1;

            n += 1;
        }
    }
    else
    { /* not implemented */ }

    bRet=releaseProfile(pProfile);
    SAL_WARN_IF(!bRet, "sal.osl""releaseProfile(pProfile) ==> false");

    pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));

    return n;
}

static osl_TStamp OslProfile_getFileStamp(osl_TFile* pFile)
{
    struct stat status;

    if ( (pFile->m_Handle < 0) || (fstat(pFile->m_Handle, &status) < 0) )
    {
        return 0;
    }

    return status.st_mtime;
}

static bool OslProfile_lockFile(const osl_TFile* pFile, osl_TLockMode eMode)
{
    struct flock lock;
    static bool const bLockingDisabled = getenv( "STAR_PROFILE_LOCKING_DISABLED" ) != nullptr;

    if (pFile->m_Handle < 0)
    {
        return false;
    }

    if ( bLockingDisabled )
    {
        return true;
    }

    lock.l_start  = 0;
    lock.l_whence = SEEK_SET;
    lock.l_len    = 0;

    switch (eMode)
    {
        case un_lock:
            lock.l_type = F_UNLCK;
            break;

        case read_lock:
            lock.l_type = F_RDLCK;
            break;

        case write_lock:
            lock.l_type = F_WRLCK;
            break;
    }

#ifndef MACOSX
    if ( fcntl(pFile->m_Handle, F_SETLKW, &lock) == -1 )
#else
    /* Mac OSX will return ENOTSUP for webdav drives so we should ignore it */
    if ( fcntl(pFile->m_Handle, F_SETLKW, &lock) == -1 && errno != ENOTSUP )
#endif
    {
        SAL_INFO("sal.osl""fcntl failed: " << UnixErrnoString(errno));
        return false;
    }

    return true;
}

static osl_TFile* openFileImpl(const char* pszFilename, oslProfileOption ProfileFlags )
{
    int        Flags;
    osl_TFile* pFile = static_cast<osl_TFile*>(calloc(1, sizeof(osl_TFile)));
    bool       bWriteable = false;

    if ( ProfileFlags & ( osl_Profile_WRITELOCK | osl_Profile_FLUSHWRITE ) )
    {
        bWriteable = true;
    }

    if (! bWriteable)
    {
        pFile->m_Handle = open(pszFilename, O_RDONLY);

        if (pFile->m_Handle == -1)
        {
            int e = errno;
            SAL_INFO("sal.file""open(" << pszFilename << ",O_RDONLY): " << UnixErrnoString(e));
        }
        else
            SAL_INFO("sal.file""open(" << pszFilename << ",O_RDONLY) => " << pFile->m_Handle);

        /* mfe: argghh!!! do not check if the file could be opened */
        /*      default mode expects it that way!!!                 */
    }
    else
    {
        if (((pFile->m_Handle = open(pszFilename, O_RDWR | O_CREAT | O_EXCL, DEFAULT_PMODE)) < 0) &&
            ((pFile->m_Handle = open(pszFilename, O_RDWR)) < 0))
        {
            int e = errno;
            SAL_INFO("sal.file""open(" << pszFilename << ",...): " << UnixErrnoString(e));
            free(pFile);
            return nullptr;
        }
        else
            SAL_INFO("sal.file""open(" << pszFilename << ",...) => " << pFile->m_Handle);
    }

    /* set close-on-exec flag */
    if ((Flags = fcntl(pFile->m_Handle, F_GETFD, 0)) != -1)
    {
        Flags |= FD_CLOEXEC;
        int e = fcntl(pFile->m_Handle, F_SETFD, Flags);
        SAL_INFO_IF(
            e != 0, "sal.osl",
            "fcntl to set FD_CLOEXEC failed for " << pszFilename);
    }

    pFile->m_pWriteBuf=nullptr;
    pFile->m_nWriteBufFree=0;
    pFile->m_nWriteBufLen=0;

    if ( ProfileFlags & (osl_Profile_WRITELOCK | osl_Profile_READLOCK ) )
    {
        OslProfile_lockFile(pFile, bWriteable ? write_lock : read_lock);
    }

    return pFile;
}

static osl_TStamp closeFileImpl(osl_TFile* pFile, oslProfileOption Flags)
{
    osl_TStamp stamp = 0;

    if ( pFile == nullptr )
    {
        return stamp;
    }

    if ( pFile->m_Handle >= 0 )
    {
        stamp = OslProfile_getFileStamp(pFile);

        if ( Flags & (osl_Profile_WRITELOCK | osl_Profile_READLOCK ) )
        {
            OslProfile_lockFile(pFile, un_lock);
        }

        close(pFile->m_Handle);
        SAL_INFO("sal.file""close(" << pFile->m_Handle << ")");
        pFile->m_Handle = -1;
    }

    if ( pFile->m_pWriteBuf )
    {
        free(pFile->m_pWriteBuf);
    }

    free(pFile);

    return stamp;
}

static bool OslProfile_rewindFile(osl_TFile* pFile, bool bTruncate)
{
    bool bRet = true;

    if (pFile->m_Handle >= 0)
    {
        pFile->m_pReadPtr  = pFile->m_ReadBuf + sizeof(pFile->m_ReadBuf);

        bRet = (lseek(pFile->m_Handle, SEEK_SET, 0) == 0);

        if (bTruncate)
        {
            bRet &= (ftruncate(pFile->m_Handle, 0) == 0);
        }

    }

    return bRet;
}

static char* OslProfile_getLine(osl_TFile* pFile)
{
    ssize_t Max, nLineBytes = 0;
    char* pChr;
    char* pLine = nullptr;
    char* pNewLine;

    if ( pFile == nullptr )
    {
        return nullptr;
    }

    if (pFile->m_Handle < 0)
        return nullptr;

    do
    {
        ssize_t Bytes = sizeof(pFile->m_ReadBuf) - (pFile->m_pReadPtr - pFile->m_ReadBuf);

        if (Bytes <= 1)
        {
            /* refill buffer */
            memcpy(pFile->m_ReadBuf, pFile->m_pReadPtr, Bytes);
            pFile->m_pReadPtr = pFile->m_ReadBuf;

            ssize_t Free = sizeof(pFile->m_ReadBuf) - Bytes;

            Max = read(pFile->m_Handle, &pFile->m_ReadBuf[Bytes], Free);
            if (Max < 0)
            {
                SAL_INFO("sal.osl""read failed: " << UnixErrnoString(errno));

                if( pLine )
                    free( pLine );
                pLine = nullptr;
                break;
            }

            if (Max < Free)
            {
                 if ((Max == 0) && ! pLine)
                     break;

                 pFile->m_ReadBuf[Bytes + Max] = '\0';
            }
        }

        for (pChr = pFile->m_pReadPtr;
             (*pChr != '\n') && (*pChr != '\r') && (*pChr != '\0') &&
             (pChr < (pFile->m_ReadBuf + sizeof(pFile->m_ReadBuf) - 1));
             pChr++);

        Max = pChr - pFile->m_pReadPtr;
        pNewLine = static_cast<char*>(malloc( nLineBytes + Max + 1 ));
        if( pLine )
        {
            memcpy( pNewLine, pLine, nLineBytes );
            free( pLine );
        }
        memcpy(pNewLine+nLineBytes, pFile->m_pReadPtr, Max);
        nLineBytes += Max;
        pNewLine[ nLineBytes ] = 0;
        pLine = pNewLine;

        if (pChr < (pFile->m_ReadBuf + sizeof(pFile->m_ReadBuf) - 1))
        {
            if (*pChr != '\0')
            {
                if ((pChr[0] == '\r') && (pChr[1] == '\n'))
                    pChr += 2;
                else
                    pChr += 1;
            }

            if ((pChr < (pFile->m_ReadBuf + sizeof(pFile->m_ReadBuf))) &&
                (*pChr == '\0'))
                pChr = pFile->m_ReadBuf + sizeof(pFile->m_ReadBuf);

            /* setting Max to -1 indicates terminating read loop */
            Max = -1;
        }

        pFile->m_pReadPtr = pChr;
    }
    while (Max > 0) ;

    return pLine;
}

static bool OslProfile_putLine(osl_TFile* pFile, const char *pszLine)
{
    unsigned int Len = strlen(pszLine);

    if ( pFile == nullptr || pFile->m_Handle < 0 )
    {
        return false;
    }

    if ( pFile->m_pWriteBuf == nullptr )
    {
        pFile->m_pWriteBuf = static_cast<char*>(malloc(Len+3));
        pFile->m_nWriteBufLen = Len+3;
        pFile->m_nWriteBufFree = Len+3;
    }
    else
    {
        if ( pFile->m_nWriteBufFree <= Len + 3 )
        {
            char* pTmp;

            pTmp=static_cast<char*>(realloc(pFile->m_pWriteBuf,( ( pFile->m_nWriteBufLen + Len ) * 2) ));
            if ( pTmp == nullptr )
            {
                return false;
            }
            pFile->m_pWriteBuf = pTmp;
            pFile->m_nWriteBufFree = pFile->m_nWriteBufFree + pFile->m_nWriteBufLen + ( 2 * Len );
            pFile->m_nWriteBufLen = ( pFile->m_nWriteBufLen + Len ) * 2;
            memset( (pFile->m_pWriteBuf) + ( pFile->m_nWriteBufLen - pFile->m_nWriteBufFree ), 0, pFile->m_nWriteBufFree);
        }
    }

    memcpy(pFile->m_pWriteBuf + ( pFile->m_nWriteBufLen - pFile->m_nWriteBufFree ),pszLine,Len+1);
    pFile->m_pWriteBuf[pFile->m_nWriteBufLen - pFile->m_nWriteBufFree + Len]='\n';
    pFile->m_pWriteBuf[pFile->m_nWriteBufLen - pFile->m_nWriteBufFree + Len + 1]='\0';

    pFile->m_nWriteBufFree-=Len+1;

    return true;
}

static char* stripBlanks(char* String, sal_uInt32* pLen)
{
    if ( ( pLen != nullptr ) && ( *pLen != 0 ) )
    {
        while ((String[*pLen - 1] == ' ') || (String[*pLen - 1] == '\t'))
            (*pLen)--;

        while ( (*String == ' ') || (*String == '\t') )
        {
            String++;
            (*pLen)--;
        }
    }
    else
        while ( (*String == ' ') || (*String == '\t') )
            String++;

    return String;
}

static char* addLine(osl_TProfileImpl* pProfile, const char* Line)
{
    if (pProfile->m_NoLines >= pProfile->m_MaxLines)
    {
        if (pProfile->m_Lines == nullptr)
        {
            pProfile->m_MaxLines = LINES_INI;
            pProfile->m_Lines = static_cast<char **>(calloc(pProfile->m_MaxLines, sizeof(char *)));
        }
        else
        {
            unsigned int idx=0;
            unsigned int oldmax=pProfile->m_MaxLines;

            pProfile->m_MaxLines += LINES_ADD;
            pProfile->m_Lines = static_cast<char **>(realloc(pProfile->m_Lines,
                                                 pProfile->m_MaxLines * sizeof(char *)));
            for ( idx = oldmax ; idx < pProfile->m_MaxLines ; ++idx )
            {
                pProfile->m_Lines[idx]=nullptr;
            }
        }
    }
    if (pProfile->m_Lines == nullptr)
    {
        pProfile->m_NoLines  = 0;
        pProfile->m_MaxLines = 0;
        return nullptr;
    }

    if ( pProfile->m_Lines[pProfile->m_NoLines] != nullptr )
    {
        free(pProfile->m_Lines[pProfile->m_NoLines]);
    }
    pProfile->m_Lines[pProfile->m_NoLines++] = strdup(Line);

    return pProfile->m_Lines[pProfile->m_NoLines - 1];
}

static char* insertLine(osl_TProfileImpl* pProfile, const char* Line, sal_uInt32 LineNo)
{
    if (pProfile->m_NoLines >= pProfile->m_MaxLines)
    {
        if (pProfile->m_Lines == nullptr)
        {
            pProfile->m_MaxLines = LINES_INI;
            pProfile->m_Lines = static_cast<char **>(calloc(pProfile->m_MaxLines, sizeof(char *)));
        }
        else
        {
            pProfile->m_MaxLines += LINES_ADD;
            pProfile->m_Lines = static_cast<char **>(realloc(pProfile->m_Lines,
                                                 pProfile->m_MaxLines * sizeof(char *)));

            memset(&pProfile->m_Lines[pProfile->m_NoLines],
                0,
                (pProfile->m_MaxLines - pProfile->m_NoLines - 1) * sizeof(char*));
        }

        if (pProfile->m_Lines == nullptr)
        {
            pProfile->m_NoLines  = 0;
            pProfile->m_MaxLines = 0;
            return nullptr;
        }
    }

    LineNo = std::min(LineNo, pProfile->m_NoLines);

    if (LineNo < pProfile->m_NoLines)
    {
        sal_uInt32 i, n;

        memmove(&pProfile->m_Lines[LineNo + 1], &pProfile->m_Lines[LineNo],
                (pProfile->m_NoLines - LineNo) * sizeof(char *));

        /* adjust line references */
        for (i = 0; i < pProfile->m_NoSections; i++)
        {
            osl_TProfileSection* pSec = &pProfile->m_Sections[i];

            if (pSec->m_Line >= LineNo)
                pSec->m_Line++;

            for (n = 0; n < pSec->m_NoEntries; n++)
                if (pSec->m_Entries[n].m_Line >= LineNo)
                    pSec->m_Entries[n].m_Line++;
        }
    }

    pProfile->m_NoLines++;

    pProfile->m_Lines[LineNo] = strdup(Line);

    return pProfile->m_Lines[LineNo];
}

static void removeLine(osl_TProfileImpl* pProfile, sal_uInt32 LineNo)
{
    if (LineNo >= pProfile->m_NoLines)
        return;

    free(pProfile->m_Lines[LineNo]);
    pProfile->m_Lines[LineNo]=nullptr;
    if (pProfile->m_NoLines - LineNo > 1)
    {
        sal_uInt32 i, n;

        memmove(&pProfile->m_Lines[LineNo], &pProfile->m_Lines[LineNo + 1],
                (pProfile->m_NoLines - LineNo - 1) * sizeof(char *));

        memset(&pProfile->m_Lines[pProfile->m_NoLines - 1],
            0,
            (pProfile->m_MaxLines - pProfile->m_NoLines) * sizeof(char*));

        /* adjust line references */
        for (i = 0; i < pProfile->m_NoSections; i++)
        {
            osl_TProfileSection* pSec = &pProfile->m_Sections[i];

            if (pSec->m_Line > LineNo)
                pSec->m_Line--;

            for (n = 0; n < pSec->m_NoEntries; n++)
                if (pSec->m_Entries[n].m_Line > LineNo)
                    pSec->m_Entries[n].m_Line--;
        }
    }
    else
    {
        pProfile->m_Lines[LineNo] = nullptr;
    }

    pProfile->m_NoLines--;
}

static void setEntry(osl_TProfileImpl* pProfile, osl_TProfileSection* pSection,
                     sal_uInt32 NoEntry, sal_uInt32 Line,
                     char* Entry, sal_uInt32 Len)
{
    Entry = stripBlanks(Entry, &Len);
    pSection->m_Entries[NoEntry].m_Line   = Line;
    pSection->m_Entries[NoEntry].m_Offset = Entry - pProfile->m_Lines[Line];
    pSection->m_Entries[NoEntry].m_Len    = Len;
}

static bool addEntry(osl_TProfileImpl* pProfile,
                     osl_TProfileSection *pSection,
                     int Line, char* Entry,
                     sal_uInt32 Len)
{
    if (pSection != nullptr)
    {
        if (pSection->m_NoEntries >= pSection->m_MaxEntries)
        {
            if (pSection->m_Entries == nullptr)
            {
                pSection->m_MaxEntries = ENTRIES_INI;
                pSection->m_Entries = static_cast<osl_TProfileEntry *>(malloc(
                                pSection->m_MaxEntries * sizeof(osl_TProfileEntry)));
            }
            else
            {
                pSection->m_MaxEntries += ENTRIES_ADD;
                pSection->m_Entries = static_cast<osl_TProfileEntry *>(realloc(pSection->m_Entries,
                                pSection->m_MaxEntries * sizeof(osl_TProfileEntry)));
            }

            if (pSection->m_Entries == nullptr)
            {
                pSection->m_NoEntries  = 0;
                pSection->m_MaxEntries = 0;
                return false;
            }
        }

        pSection->m_NoEntries++;

        Entry = stripBlanks(Entry, &Len);
        setEntry(pProfile, pSection, pSection->m_NoEntries - 1, Line,
                 Entry, Len);

        return true;
    }

    return false;
}

static void removeEntry(osl_TProfileSection *pSection, sal_uInt32 NoEntry)
{
    if (NoEntry >= pSection->m_NoEntries)
        return;

    if (pSection->m_NoEntries - NoEntry > 1)
    {
        memmove(&pSection->m_Entries[NoEntry],
                &pSection->m_Entries[NoEntry + 1],
                (pSection->m_NoEntries - NoEntry - 1) * sizeof(osl_TProfileEntry));
        pSection->m_Entries[pSection->m_NoEntries - 1].m_Line=0;
        pSection->m_Entries[pSection->m_NoEntries - 1].m_Offset=0;
        pSection->m_Entries[pSection->m_NoEntries - 1].m_Len=0;
    }

    pSection->m_NoEntries--;

}

static bool addSection(osl_TProfileImpl* pProfile, int Line, const char* Section, sal_uInt32 Len)
{
    if (pProfile->m_NoSections >= pProfile->m_MaxSections)
    {
        if (pProfile->m_Sections == nullptr)
        {
            pProfile->m_MaxSections = SECTIONS_INI;
            pProfile->m_Sections = static_cast<osl_TProfileSection *>(calloc(pProfile->m_MaxSections, sizeof(osl_TProfileSection)));
        }
        else
        {
            unsigned int idx=0;
            unsigned int oldmax=pProfile->m_MaxSections;

            pProfile->m_MaxSections += SECTIONS_ADD;
            pProfile->m_Sections = static_cast<osl_TProfileSection *>(realloc(pProfile->m_Sections,
                                          pProfile->m_MaxSections * sizeof(osl_TProfileSection)));
            for ( idx = oldmax ; idx < pProfile->m_MaxSections ; ++idx )
            {
                pProfile->m_Sections[idx].m_Entries=nullptr;
            }
        }

        if (pProfile->m_Sections == nullptr)
        {
            pProfile->m_NoSections = 0;
            pProfile->m_MaxSections = 0;
            return false;
        }
    }

    pProfile->m_NoSections++;

    if ( pProfile->m_Sections[(pProfile->m_NoSections) - 1].m_Entries != nullptr )
    {
         free(pProfile->m_Sections[(pProfile->m_NoSections) - 1].m_Entries);
    }
    pProfile->m_Sections[pProfile->m_NoSections - 1].m_Entries    = nullptr;
    pProfile->m_Sections[pProfile->m_NoSections - 1].m_NoEntries  = 0;
    pProfile->m_Sections[pProfile->m_NoSections - 1].m_MaxEntries = 0;

    pProfile->m_Sections[pProfile->m_NoSections - 1].m_Line = Line;
    pProfile->m_Sections[pProfile->m_NoSections - 1].m_Offset = Section - pProfile->m_Lines[Line];
    pProfile->m_Sections[pProfile->m_NoSections - 1].m_Len = Len;

    return true;
}

static void removeSection(osl_TProfileImpl* pProfile, osl_TProfileSection *pSection)
{
    sal_uInt32 Section;

    if ((Section = pSection - pProfile->m_Sections) >= pProfile->m_NoSections)
        return;

    free (pSection->m_Entries);
    pSection->m_Entries=nullptr;
    if (pProfile->m_NoSections - Section > 1)
    {
        memmove(&pProfile->m_Sections[Section], &pProfile->m_Sections[Section + 1],
                (pProfile->m_NoSections - Section - 1) * sizeof(osl_TProfileSection));

        memset(&pProfile->m_Sections[pProfile->m_NoSections - 1],
               0,
               (pProfile->m_MaxSections - pProfile->m_NoSections) * sizeof(osl_TProfileSection));
        pProfile->m_Sections[pProfile->m_NoSections - 1].m_Entries = nullptr;
    }
    else
    {
        pSection->m_Entries = nullptr;
    }

    pProfile->m_NoSections--;
}

static osl_TProfileSection* findEntry(osl_TProfileImpl* pProfile,
                                      const char* Section,
                                      const char* Entry,
                                      sal_uInt32 *pNoEntry)
{
    static  sal_uInt32    Sect = 0;
    sal_uInt32    i, n;
    sal_uInt32  Len;
    osl_TProfileSection* pSec=nullptr;

    Len = strlen(Section);

    n = Sect;

    for (i = 0; i < pProfile->m_NoSections; i++)
    {
        n %= pProfile->m_NoSections;
        pSec = &pProfile->m_Sections[n];
        if ((Len == pSec->m_Len) &&
            (strncasecmp(Section, &pProfile->m_Lines[pSec->m_Line][pSec->m_Offset], pSec->m_Len)
             == 0))
            break;
        n++;
    }

    Sect = n;

    if (i < pProfile->m_NoSections)
    {
        Len = strlen(Entry);

        *pNoEntry = pSec->m_NoEntries;

        for (i = 0; i < pSec->m_NoEntries; i++)
        {
            const char* pStr = &pProfile->m_Lines[pSec->m_Entries[i].m_Line]
                                     [pSec->m_Entries[i].m_Offset];
            if ((Len == pSec->m_Entries[i].m_Len) &&
                (strncasecmp(Entry, pStr, pSec->m_Entries[i].m_Len)
                 == 0))
            {
                *pNoEntry = i;
                break;
            }
        }
    }
    else
        pSec = nullptr;

    return pSec;
}

static bool loadProfile(osl_TFile* pFile, osl_TProfileImpl* pProfile)
{
    sal_uInt32  i;
    char*   pStr;
    char*   pChar;

    char* pLine;

    if ( !pFile )
    {
        return false;
    }

    if ( !pProfile )
    {
        return false;
    }

    pProfile->m_NoLines    = 0;
    pProfile->m_NoSections = 0;

    OSL_VERIFY(OslProfile_rewindFile(pFile, false));

    while ( ( pLine=OslProfile_getLine(pFile) ) != nullptr )
    {
        char* bWasAdded = addLine( pProfile, pLine );
        free( pLine );
        SAL_WARN_IF(!bWasAdded, "sal.osl""addLine( pProfile, pLine ) ==> false");
        if ( ! bWasAdded )
            return false;
    }

    for (i = 0; i < pProfile->m_NoLines; i++)
    {
        pStr = stripBlanks(pProfile->m_Lines[i], nullptr);

        if ((*pStr == '\0') || (*pStr == ';'))
            continue;

        if ((*pStr != '[') || ((pChar = strrchr(pStr, ']')) == nullptr) ||
            ((pChar - pStr) <= 2))
        {
            /* insert entry */

            if (pProfile->m_NoSections < 1)
                continue;

            if ((pChar = strchr(pStr, '=')) == nullptr)
                pChar = pStr + strlen(pStr);

            if (! addEntry(pProfile, &pProfile->m_Sections[pProfile->m_NoSections - 1],
                           i, pStr, pChar - pStr))
            {
                SAL_WARN("sal.osl""Adding entry => false");
                continue;
            }

        }
        else
        {
            /* new section */

            if (! addSection(pProfile, i, pStr + 1, pChar - pStr - 1))
            {
                SAL_WARN("sal.osl""Adding section => false");
                continue;
            }

        }
    }

    return true;
}

static bool storeProfile(osl_TProfileImpl* pProfile, bool bCleanup)
{
    if (pProfile->m_Lines != nullptr)
    {
        if (pProfile->m_Flags & FLG_MODIFIED)
        {
            sal_uInt32 i;

            osl_TFile* pTmpFile = osl_openTmpProfileImpl(pProfile);

            if ( pTmpFile == nullptr )
            {
                return false;
            }

            OSL_VERIFY(OslProfile_rewindFile(pTmpFile, true));

            for ( i = 0 ; i < pProfile->m_NoLines ; i++ )
            {
                OSL_VERIFY(OslProfile_putLine(pTmpFile, pProfile->m_Lines[i]));
            }

            if ( ! writeProfileImpl(pTmpFile) )
            {
                if ( pTmpFile->m_pWriteBuf != nullptr )
                {
                    free(pTmpFile->m_pWriteBuf);
                }

                pTmpFile->m_pWriteBuf=nullptr;
                pTmpFile->m_nWriteBufLen=0;
                pTmpFile->m_nWriteBufFree=0;

                closeFileImpl(pTmpFile,pProfile->m_Flags);

                return false;
            }

            pProfile->m_Flags &= ~FLG_MODIFIED;

            closeFileImpl(pProfile->m_pFile,pProfile->m_Flags);
            closeFileImpl(pTmpFile,pProfile->m_Flags);

            osl_ProfileSwapProfileNames(pProfile);

            pProfile->m_pFile = openFileImpl(pProfile->m_FileName,pProfile->m_Flags);

        }

        if (bCleanup)
        {
            while (pProfile->m_NoLines > 0)
                removeLine(pProfile, pProfile->m_NoLines - 1);

            free(pProfile->m_Lines);
            pProfile->m_Lines = nullptr;
            pProfile->m_NoLines = 0;
            pProfile->m_MaxLines = 0;

            while (pProfile->m_NoSections > 0)
                removeSection(pProfile, &pProfile->m_Sections[pProfile->m_NoSections - 1]);

            free(pProfile->m_Sections);
            pProfile->m_Sections = nullptr;
            pProfile->m_NoSections = 0;
            pProfile->m_MaxSections = 0;
        }
    }

    return true;
}

static osl_TFile* osl_openTmpProfileImpl(osl_TProfileImpl* pProfile)
{
    osl_TFile* pFile=nullptr;
    char const * const pszExtension = "tmp";
    char pszTmpName[PATH_MAX];
    oslProfileOption PFlags=0;

    pszTmpName[0] = '\0';

    /* generate tmp profilename */
    osl_ProfileGenerateExtension(pProfile->m_FileName, pszExtension, pszTmpName, PATH_MAX);

    if ( pszTmpName[0] == 0 )
    {
        return nullptr;
    }

    if ( ! ( pProfile->m_Flags & osl_Profile_READLOCK ) )
    {
        PFlags |= osl_Profile_WRITELOCK;
    }

    /* open this file */
    pFile = openFileImpl(pszTmpName,pProfile->m_Flags | PFlags);

    /* return new pFile */
    return pFile;
}

static bool osl_ProfileSwapProfileNames(osl_TProfileImpl* pProfile)
{
    char pszBakFile[PATH_MAX];
    char pszTmpFile[PATH_MAX];

    pszBakFile[0] = '\0';
    pszTmpFile[0] = '\0';

    osl_ProfileGenerateExtension(pProfile->m_FileName, "bak", pszBakFile, PATH_MAX);
    osl_ProfileGenerateExtension(pProfile->m_FileName, "tmp", pszTmpFile, PATH_MAX);

    /* unlink bak */
    unlink( pszBakFile );

    // Rename ini -> bak, then tmp -> ini:
    bool result = rename( pProfile->m_FileName, pszBakFile ) == 0;
    if (!result)
    {
        int e = errno;
        SAL_INFO("sal.file""rename(" << pProfile->m_FileName << "," << pszBakFile << "): " << UnixErrnoString(e));
    }
    else
    {
        SAL_INFO("sal.file""rename(" << pProfile->m_FileName << "," << pszBakFile << "): OK");
        result = rename( pszTmpFile, pProfile->m_FileName ) == 0;
        if (!result)
        {
            int e = errno;
            SAL_INFO("sal.file""rename(" << pszTmpFile << "," << pProfile->m_FileName << "): " << UnixErrnoString(e));
        }
        else
        {
            SAL_INFO("sal.file""rename(" << pszTmpFile << "," << pProfile->m_FileName << "): OK");
        }
    }
    return result;
}

static void osl_ProfileGenerateExtension(const char* pszFileName, const char* pszExtension, char* pszTmpName, int BufferMaxLen)
{
    char* cursor = pszTmpName;
    int len;

    /* concatenate filename + "." + extension, limited to the size of the
     * output buffer; in case of overrun, data is truncated at the end...
     * and the result is always 0-terminated.
     */

    len = strlen(pszFileName);
    if(len < BufferMaxLen)
    {
        memcpy(cursor, pszFileName, len);
        cursor += len;
        BufferMaxLen -= len;
    }
    else
    {
        memcpy(cursor, pszFileName, BufferMaxLen - 1);
        cursor += BufferMaxLen - 1;
        BufferMaxLen = 1;
    }
    if(BufferMaxLen > 1)
    {
        *cursor++ = '.';
        BufferMaxLen -= 1;
    }
    len = strlen(pszExtension);
    if(len < BufferMaxLen)
    {
        memcpy(cursor, pszExtension, len);
        cursor += len;
    }
    else
    {
        memcpy(cursor, pszExtension, BufferMaxLen - 1);
        cursor += BufferMaxLen - 1;
    }
    *cursor = 0;
}

static osl_TProfileImpl* acquireProfile(oslProfile Profile, bool bWriteable)
{
    osl_TProfileImpl* pProfile = static_cast<osl_TProfileImpl*>(Profile);
    oslProfileOption PFlags=0;

    if ( bWriteable )
    {
        PFlags = osl_Profile_DEFAULT | osl_Profile_WRITELOCK;
    }
    else
    {
        PFlags = osl_Profile_DEFAULT;
    }

    if (pProfile == nullptr)
    {
        if ( ( pProfile = static_cast<osl_TProfileImpl*>(osl_openProfile(nullptr, PFlags )) ) != nullptr )
        {
            pProfile->m_Flags |= FLG_AUTOOPEN;
        }
    }
    else
    {
        if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
        {
            if (! (pProfile->m_Flags & (osl_Profile_READLOCK | osl_Profile_WRITELOCK | osl_Profile_FLUSHWRITE )))
            {
                osl_TStamp Stamp;

                if (! (pProfile->m_pFile = openFileImpl(pProfile->m_FileName, pProfile->m_Flags | PFlags )))
                    return nullptr;

                Stamp = OslProfile_getFileStamp(pProfile->m_pFile);

                if (memcmp(&Stamp, &(pProfile->m_Stamp), sizeof(osl_TStamp)))
                {
                    pProfile->m_Stamp = Stamp;
                    bool bRet = loadProfile(pProfile->m_pFile, pProfile);
                    SAL_WARN_IF(!bRet, "sal.osl""loadProfile(pProfile->m_pFile, pProfile) ==> false");
                }
            }
            else
            {
                /* A readlock file could not be written */
                if ((pProfile->m_Flags & osl_Profile_READLOCK) && bWriteable)
                {
                    return nullptr;
                }
            }
        }
    }

    return pProfile;
}

static bool releaseProfile(osl_TProfileImpl* pProfile)
{
    if ( pProfile == nullptr )
    {
        return false;
    }

    if (pProfile->m_Flags & FLG_AUTOOPEN)
    {
        return osl_closeProfile(static_cast<oslProfile>(pProfile));
    }

    if (! (pProfile->m_Flags & (osl_Profile_READLOCK | osl_Profile_WRITELOCK | osl_Profile_FLUSHWRITE )))
    {
        if (pProfile->m_Flags & FLG_MODIFIED)
        {
            bool bRet = storeProfile(pProfile, false);
            SAL_WARN_IF(!bRet, "sal.osl""storeProfile(pProfile, false) ==> false");
        }

        closeFileImpl(pProfile->m_pFile,pProfile->m_Flags);
        pProfile->m_pFile = nullptr;
    }

    return true;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Messung V0.5
C=97 H=81 G=89

¤ Dauer der Verarbeitung: 0.17 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge