1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include "readwrite_helper.h"
23 #include <osl/diagnose.h>
24 #include <osl/profile.h>
25 #include <osl/process.h>
26 #include <osl/thread.h>
27 #include <rtl/alloc.h>
28 #include <sal/log.hxx>
32 #define SECTIONS_INI 5
33 #define SECTIONS_ADD 3
37 #define STR_INI_BOOLYES "yes"
38 #define STR_INI_BOOLON "on"
39 #define STR_INI_BOOLONE "1"
40 #define STR_INI_BOOLNO "no"
41 #define STR_INI_BOOLOFF "off"
42 #define STR_INI_BOOLZERO "0"
44 #define FLG_USER 0x00FF
45 #define FLG_AUTOOPEN 0x0100
46 #define FLG_MODIFIED 0x0200
48 #define DEFAULT_PMODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)
50 /*#define DEBUG_OSL_PROFILE*/
51 /*#define TRACE_OSL_PROFILE*/
53 typedef time_t osl_TStamp
;
55 typedef enum _osl_TLockMode
57 un_lock
, read_lock
, write_lock
60 typedef struct _osl_TFile
64 sal_Char m_ReadBuf
[512];
65 sal_Char
* m_pWriteBuf
;
66 sal_uInt32 m_nWriteBufLen
;
67 sal_uInt32 m_nWriteBufFree
;
70 typedef struct _osl_TProfileEntry
77 typedef struct _osl_TProfileSection
82 sal_uInt32 m_NoEntries
;
83 sal_uInt32 m_MaxEntries
;
84 osl_TProfileEntry
* m_Entries
;
85 } osl_TProfileSection
;
87 /* Profile-data structure hidden behind oslProfile: */
88 typedef struct _osl_TProfileImpl
93 sal_Char m_FileName
[PATH_MAX
+ 1];
95 sal_uInt32 m_MaxLines
;
96 sal_uInt32 m_NoSections
;
97 sal_uInt32 m_MaxSections
;
99 osl_TProfileSection
* m_Sections
;
100 pthread_mutex_t m_AccessLock
;
104 static osl_TFile
* openFileImpl(const sal_Char
* pszFilename
, oslProfileOption ProfileFlags
);
105 static osl_TStamp
closeFileImpl(osl_TFile
* pFile
, oslProfileOption Flags
);
106 static bool OslProfile_lockFile(const osl_TFile
* pFile
, osl_TLockMode eMode
);
107 static bool OslProfile_rewindFile(osl_TFile
* pFile
, bool bTruncate
);
108 static osl_TStamp
OslProfile_getFileStamp(osl_TFile
* pFile
);
110 static sal_Char
* OslProfile_getLine(osl_TFile
* pFile
);
111 static bool OslProfile_putLine(osl_TFile
* pFile
, const sal_Char
*pszLine
);
112 static sal_Char
* stripBlanks(sal_Char
* String
, sal_uInt32
* pLen
);
113 static sal_Char
* addLine(osl_TProfileImpl
* pProfile
, const sal_Char
* Line
);
114 static sal_Char
* insertLine(osl_TProfileImpl
* pProfile
, const sal_Char
* Line
, sal_uInt32 LineNo
);
115 static void removeLine(osl_TProfileImpl
* pProfile
, sal_uInt32 LineNo
);
116 static void setEntry(osl_TProfileImpl
* pProfile
, osl_TProfileSection
* pSection
,
117 sal_uInt32 NoEntry
, sal_uInt32 Line
,
118 sal_Char
* Entry
, sal_uInt32 Len
);
119 static bool addEntry(osl_TProfileImpl
* pProfile
, osl_TProfileSection
*pSection
,
120 int Line
, sal_Char
* Entry
, sal_uInt32 Len
);
121 static void removeEntry(osl_TProfileSection
*pSection
, sal_uInt32 NoEntry
);
122 static bool addSection(osl_TProfileImpl
* pProfile
, int Line
, const sal_Char
* Section
, sal_uInt32 Len
);
123 static void removeSection(osl_TProfileImpl
* pProfile
, osl_TProfileSection
*pSection
);
124 static osl_TProfileSection
* findEntry(osl_TProfileImpl
* pProfile
, const sal_Char
* Section
,
125 const sal_Char
* Entry
, sal_uInt32
*pNoEntry
);
126 static bool loadProfile(osl_TFile
* pFile
, osl_TProfileImpl
* pProfile
);
127 static bool storeProfile(osl_TProfileImpl
* pProfile
, bool bCleanup
);
128 static osl_TProfileImpl
* acquireProfile(oslProfile Profile
, bool bWriteable
);
129 static bool releaseProfile(osl_TProfileImpl
* pProfile
);
131 static bool writeProfileImpl (osl_TFile
* pFile
);
132 static osl_TFile
* osl_openTmpProfileImpl(osl_TProfileImpl
*);
133 static bool osl_ProfileSwapProfileNames(osl_TProfileImpl
*);
134 static void osl_ProfileGenerateExtension(const sal_Char
* pszFileName
, const sal_Char
* pszExtension
, sal_Char
* pszTmpName
, int BufferMaxLen
);
135 static oslProfile SAL_CALL
osl_psz_openProfile(const sal_Char
*pszProfileName
, oslProfileOption Flags
);
137 /* implemented in file.c */
138 extern "C" oslFileError
FileURLToPath( char *, size_t, rtl_uString
* );
140 oslProfile SAL_CALL
osl_openProfile(rtl_uString
*ustrProfileName
, oslProfileOption Options
)
142 char profilePath
[PATH_MAX
] = "";
144 if ( ustrProfileName
!= 0 && ustrProfileName
->buffer
[0] != 0 )
145 FileURLToPath( profilePath
, PATH_MAX
, ustrProfileName
);
147 return osl_psz_openProfile( profilePath
,Options
);
150 static oslProfile SAL_CALL
osl_psz_openProfile(const sal_Char
*pszProfileName
, oslProfileOption Flags
)
153 osl_TProfileImpl
* pProfile
;
156 #ifdef TRACE_OSL_PROFILE
157 OSL_TRACE("In osl_openProfile");
160 #ifdef DEBUG_OSL_PROFILE
161 Flags
=osl_Profile_FLUSHWRITE
;
163 OSL_TRACE("opening '%s'",pszProfileName
);
164 if ( Flags
== osl_Profile_DEFAULT
)
166 OSL_TRACE("with osl_Profile_DEFAULT");
168 if ( Flags
& osl_Profile_SYSTEM
)
170 OSL_TRACE("with osl_Profile_SYSTEM");
172 if ( Flags
& osl_Profile_READLOCK
)
174 OSL_TRACE("with osl_Profile_READLOCK");
176 if ( Flags
& osl_Profile_WRITELOCK
)
178 OSL_TRACE("with osl_Profile_WRITELOCK");
180 if ( Flags
& osl_Profile_FLUSHWRITE
)
182 OSL_TRACE("with osl_Profile_FLUSHWRITE");
186 if ( ( pFile
= openFileImpl(pszProfileName
, Flags
) ) == NULL
)
188 #ifdef TRACE_OSL_PROFILE
189 OSL_TRACE("Out osl_openProfile [not opened]");
194 pProfile
= (osl_TProfileImpl
*)calloc(1, sizeof(osl_TProfileImpl
));
198 closeFileImpl(pFile
, Flags
);
202 pProfile
->m_Flags
= Flags
& FLG_USER
;
204 if ( Flags
& ( osl_Profile_READLOCK
| osl_Profile_WRITELOCK
| osl_Profile_FLUSHWRITE
) )
206 pProfile
->m_pFile
= pFile
;
209 pthread_mutex_init(&(pProfile
->m_AccessLock
),PTHREAD_MUTEXATTR_DEFAULT
);
210 pProfile
->m_bIsValid
= true;
212 pProfile
->m_Stamp
= OslProfile_getFileStamp(pFile
);
213 bRet
=loadProfile(pFile
, pProfile
);
214 bRet
&= realpath(pszProfileName
, pProfile
->m_FileName
) != NULL
;
217 if (pProfile
->m_pFile
== NULL
)
218 closeFileImpl(pFile
,pProfile
->m_Flags
);
220 #ifdef TRACE_OSL_PROFILE
221 OSL_TRACE("Out osl_openProfile [ok]");
226 sal_Bool SAL_CALL
osl_closeProfile(oslProfile Profile
)
228 osl_TProfileImpl
* pProfile
= (osl_TProfileImpl
*)Profile
;
229 osl_TProfileImpl
* pTmpProfile
;
231 #ifdef TRACE_OSL_PROFILE
232 OSL_TRACE("In osl_closeProfile");
237 #ifdef TRACE_OSL_PROFILE
238 OSL_TRACE("Out osl_closeProfile [profile==0]");
243 pthread_mutex_lock(&(pProfile
->m_AccessLock
));
245 if ( pProfile
->m_bIsValid
== false )
247 OSL_ASSERT(pProfile
->m_bIsValid
);
248 pthread_mutex_unlock(&(pProfile
->m_AccessLock
));
249 #ifdef TRACE_OSL_PROFILE
250 OSL_TRACE("Out osl_closeProfile [not valid]");
255 pProfile
->m_bIsValid
= false;
257 if ( ! ( pProfile
->m_Flags
& osl_Profile_READLOCK
) && ( pProfile
->m_Flags
& FLG_MODIFIED
) )
259 pTmpProfile
= acquireProfile(Profile
, true);
261 if ( pTmpProfile
!= 0 )
263 bool bRet
= storeProfile(pTmpProfile
, true);
270 pTmpProfile
= acquireProfile(Profile
, false);
273 if ( pTmpProfile
== 0 )
275 pthread_mutex_unlock(&(pProfile
->m_AccessLock
));
276 #ifdef TRACE_OSL_PROFILE
277 OSL_TRACE("Out osl_closeProfile [pProfile==0]");
282 pProfile
= pTmpProfile
;
284 if (pProfile
->m_pFile
!= NULL
)
285 closeFileImpl(pProfile
->m_pFile
,pProfile
->m_Flags
);
287 pProfile
->m_pFile
= NULL
;
288 pProfile
->m_FileName
[0] = '\0';
290 /* release whole profile data types memory */
291 if ( pProfile
->m_NoLines
> 0)
294 if ( pProfile
->m_Lines
!= 0 )
296 for ( idx
= 0 ; idx
< pProfile
->m_NoLines
; ++idx
)
298 if ( pProfile
->m_Lines
[idx
] != 0 )
300 free(pProfile
->m_Lines
[idx
]);
301 pProfile
->m_Lines
[idx
]=0;
304 free(pProfile
->m_Lines
);
307 if ( pProfile
->m_Sections
!= 0 )
309 /*osl_TProfileSection* pSections=pProfile->m_Sections;*/
310 for ( idx
= 0 ; idx
< pProfile
->m_NoSections
; ++idx
)
312 if ( pProfile
->m_Sections
[idx
].m_Entries
!= 0 )
314 free(pProfile
->m_Sections
[idx
].m_Entries
);
315 pProfile
->m_Sections
[idx
].m_Entries
=0;
318 free(pProfile
->m_Sections
);
319 pProfile
->m_Sections
=0;
323 pthread_mutex_unlock(&(pProfile
->m_AccessLock
));
325 pthread_mutex_destroy(&(pProfile
->m_AccessLock
));
329 #ifdef TRACE_OSL_PROFILE
330 OSL_TRACE("Out osl_closeProfile [ok]");
335 sal_Bool SAL_CALL
osl_flushProfile(oslProfile Profile
)
337 osl_TProfileImpl
* pProfile
= (osl_TProfileImpl
*) Profile
;
341 #ifdef TRACE_OSL_PROFILE
342 OSL_TRACE("In osl_flushProfile()");
347 #ifdef TRACE_OSL_PROFILE
348 OSL_TRACE("Out osl_flushProfile() [pProfile == 0]");
353 pthread_mutex_lock(&(pProfile
->m_AccessLock
));
355 if ( pProfile
->m_bIsValid
== false )
357 OSL_ASSERT(pProfile
->m_bIsValid
);
358 pthread_mutex_unlock(&(pProfile
->m_AccessLock
));
359 #ifdef TRACE_OSL_PROFILE
360 OSL_TRACE("Out osl_flushProfile [not valid]");
365 pFile
= pProfile
->m_pFile
;
366 if ( !( pFile
!= 0 && pFile
->m_Handle
>= 0 ) )
368 pthread_mutex_unlock(&(pProfile
->m_AccessLock
));
369 #ifdef TRACE_OSL_PROFILE
370 OSL_TRACE("Out osl_flushProfile() [invalid file]");
375 if ( pProfile
->m_Flags
& FLG_MODIFIED
)
377 #ifdef DEBUG_OSL_PROFILE
378 OSL_TRACE("swapping to storeprofile");
380 bRet
= storeProfile(pProfile
, false);
384 #ifdef TRACE_OSL_PROFILE
385 OSL_TRACE("Out osl_flushProfile() [ok]");
387 pthread_mutex_unlock(&(pProfile
->m_AccessLock
));
391 static bool writeProfileImpl(osl_TFile
* pFile
)
393 #if OSL_DEBUG_LEVEL > 1
397 #ifdef TRACE_OSL_PROFILE
398 OSL_TRACE("In osl_writeProfileImpl()");
401 if ( !( pFile
!= 0 && pFile
->m_Handle
>= 0 ) || ( pFile
->m_pWriteBuf
== 0 ) )
403 #ifdef TRACE_OSL_PROFILE
404 OSL_TRACE("Out osl_writeProfileImpl() [invalid args]");
409 #if OSL_DEBUG_LEVEL > 1
410 nLen
=strlen(pFile
->m_pWriteBuf
);
411 OSL_ASSERT(nLen
== (pFile
->m_nWriteBufLen
- pFile
->m_nWriteBufFree
));
414 if ( !safeWrite(pFile
->m_Handle
, pFile
->m_pWriteBuf
, pFile
->m_nWriteBufLen
- pFile
->m_nWriteBufFree
) )
416 OSL_TRACE("write failed '%s'",strerror(errno
));
420 free(pFile
->m_pWriteBuf
);
421 pFile
->m_pWriteBuf
=0;
422 pFile
->m_nWriteBufLen
=0;
423 pFile
->m_nWriteBufFree
=0;
424 #ifdef TRACE_OSL_PROFILE
425 OSL_TRACE("Out osl_writeProfileImpl() [ok]");
430 sal_Bool SAL_CALL
osl_readProfileString(oslProfile Profile
,
431 const sal_Char
* pszSection
,
432 const sal_Char
* pszEntry
,
435 const sal_Char
* pszDefault
)
439 osl_TProfileSection
* pSec
;
440 osl_TProfileImpl
* pProfile
=0;
441 osl_TProfileImpl
* pTmpProfile
=0;
444 #ifdef TRACE_OSL_PROFILE
445 OSL_TRACE("In osl_readProfileString");
448 pTmpProfile
= (osl_TProfileImpl
*) Profile
;
450 if ( pTmpProfile
== 0 )
452 #ifdef TRACE_OSL_PROFILE
453 OSL_TRACE("Out osl_readProfileString [pTmpProfile==0]");
458 pthread_mutex_lock(&(pTmpProfile
->m_AccessLock
));
460 if ( pTmpProfile
->m_bIsValid
== false )
462 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
463 #ifdef TRACE_OSL_PROFILE
464 OSL_TRACE("Out osl_readProfileString [not valid]");
469 pProfile
= acquireProfile(Profile
, false);
471 if ( pProfile
== NULL
)
473 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
474 #ifdef TRACE_OSL_PROFILE
475 OSL_TRACE("Out osl_readProfileString [pProfile==0]");
480 if (! (pProfile
->m_Flags
& osl_Profile_SYSTEM
))
482 if (((pSec
= findEntry(pProfile
, pszSection
, pszEntry
, &NoEntry
)) != NULL
) &&
483 (NoEntry
< pSec
->m_NoEntries
) &&
484 ((pStr
= strchr(pProfile
->m_Lines
[pSec
->m_Entries
[NoEntry
].m_Line
],
491 pStr
=(sal_Char
*)pszDefault
;
496 pStr
= stripBlanks(pStr
, NULL
);
497 MaxLen
= (MaxLen
- 1 < strlen(pStr
)) ? (MaxLen
- 1) : strlen(pStr
);
498 pStr
= stripBlanks(pStr
, &MaxLen
);
499 strncpy(pszString
, pStr
, MaxLen
);
500 pszString
[MaxLen
] = '\0';
504 { /* not implemented */ }
506 bRet
=releaseProfile(pProfile
);
512 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
513 #ifdef TRACE_OSL_PROFILE
514 OSL_TRACE("Out osl_readProfileString [pStr==0]");
519 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
521 #ifdef TRACE_OSL_PROFILE
522 OSL_TRACE("Out osl_readProfileString [ok]");
528 sal_Bool SAL_CALL
osl_readProfileBool(oslProfile Profile
,
529 const sal_Char
* pszSection
,
530 const sal_Char
* pszEntry
,
536 #ifdef TRACE_OSL_PROFILE
537 OSL_TRACE("In osl_readProfileBool");
540 if (osl_readProfileString(Profile
, pszSection
, pszEntry
, Line
, sizeof(Line
), ""))
542 if ((strcasecmp(Line
, STR_INI_BOOLYES
) == 0) ||
543 (strcasecmp(Line
, STR_INI_BOOLON
) == 0) ||
544 (strcasecmp(Line
, STR_INI_BOOLONE
) == 0))
547 if ((strcasecmp(Line
, STR_INI_BOOLNO
) == 0) ||
548 (strcasecmp(Line
, STR_INI_BOOLOFF
) == 0) ||
549 (strcasecmp(Line
, STR_INI_BOOLZERO
) == 0))
553 #ifdef TRACE_OSL_PROFILE
554 OSL_TRACE("Out osl_readProfileBool [ok]");
560 sal_uInt32 SAL_CALL
osl_readProfileIdent(oslProfile Profile
,
561 const sal_Char
* pszSection
,
562 const sal_Char
* pszEntry
,
564 const sal_Char
* Strings
[],
571 #ifdef TRACE_OSL_PROFILE
572 OSL_TRACE("In osl_readProfileIdent");
575 if (osl_readProfileString(Profile
, pszSection
, pszEntry
, Line
, sizeof(Line
), ""))
578 while (Strings
[i
] != NULL
)
580 if (strcasecmp(Line
, Strings
[i
]) == 0)
582 Default
= i
+ FirstId
;
589 #ifdef TRACE_OSL_PROFILE
590 OSL_TRACE("Out osl_readProfileIdent [ok]");
595 sal_Bool SAL_CALL
osl_writeProfileString(oslProfile Profile
,
596 const sal_Char
* pszSection
,
597 const sal_Char
* pszEntry
,
598 const sal_Char
* pszString
)
605 osl_TProfileSection
* pSec
;
606 osl_TProfileImpl
* pProfile
= 0;
607 osl_TProfileImpl
* pTmpProfile
= 0;
609 #ifdef TRACE_OSL_PROFILE
610 OSL_TRACE("In osl_writeProfileString");
613 pTmpProfile
= (osl_TProfileImpl
*) Profile
;
615 if ( pTmpProfile
== 0 )
617 #ifdef TRACE_OSL_PROFILE
618 OSL_TRACE("Out osl_writeProfileString [pTmpProfile==0]");
623 pthread_mutex_lock(&(pTmpProfile
->m_AccessLock
));
625 if ( pTmpProfile
->m_bIsValid
== false )
627 OSL_ASSERT(pTmpProfile
->m_bIsValid
);
628 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
629 #ifdef TRACE_OSL_PROFILE
630 OSL_TRACE("Out osl_writeProfileString [not valid]");
635 pProfile
=acquireProfile(Profile
, true);
637 if (pProfile
== NULL
)
639 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
640 #ifdef TRACE_OSL_PROFILE
641 OSL_TRACE("Out osl_writeProfileString [pProfile==0]");
646 Line
= (sal_Char
*) malloc(strlen(pszEntry
)+strlen(pszString
)+48);
648 if (! (pProfile
->m_Flags
& osl_Profile_SYSTEM
))
650 if ((pSec
= findEntry(pProfile
, pszSection
, pszEntry
, &NoEntry
)) == NULL
)
653 addLine(pProfile
, Line
);
656 strcpy(&Line
[1], pszSection
);
657 Line
[1 + strlen(pszSection
)] = ']';
658 Line
[2 + strlen(pszSection
)] = '\0';
660 if (((pStr
= addLine(pProfile
, Line
)) == NULL
) ||
661 (! addSection(pProfile
, pProfile
->m_NoLines
- 1, &pStr
[1], strlen(pszSection
))))
663 bRet
=releaseProfile(pProfile
);
666 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
670 #ifdef TRACE_OSL_PROFILE
671 OSL_TRACE("Out osl_writeProfileString [not added]");
676 pSec
= &pProfile
->m_Sections
[pProfile
->m_NoSections
- 1];
677 NoEntry
= pSec
->m_NoEntries
;
681 strcpy(&Line
[0], pszEntry
);
682 Line
[0 + strlen(pszEntry
)] = '=';
683 strcpy(&Line
[1 + strlen(pszEntry
)], pszString
);
685 if (NoEntry
>= pSec
->m_NoEntries
)
687 if (pSec
->m_NoEntries
> 0)
688 i
= pSec
->m_Entries
[pSec
->m_NoEntries
- 1].m_Line
+ 1;
690 i
= pSec
->m_Line
+ 1;
692 if (((pStr
= insertLine(pProfile
, Line
, i
)) == NULL
) ||
693 (! addEntry(pProfile
, pSec
, i
, pStr
, strlen(pszEntry
))))
695 bRet
=releaseProfile(pProfile
);
698 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
701 #ifdef TRACE_OSL_PROFILE
702 OSL_TRACE("Out osl_writeProfileString [not inserted]");
707 pProfile
->m_Flags
|= FLG_MODIFIED
;
711 i
= pSec
->m_Entries
[NoEntry
].m_Line
;
712 free(pProfile
->m_Lines
[i
]);
713 pProfile
->m_Lines
[i
] = strdup(Line
);
714 setEntry(pProfile
, pSec
, NoEntry
, i
, pProfile
->m_Lines
[i
], strlen(pszEntry
));
716 pProfile
->m_Flags
|= FLG_MODIFIED
;
720 /* not implemented */
723 bRet
= releaseProfile(pProfile
);
726 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
732 #ifdef TRACE_OSL_PROFILE
733 OSL_TRACE("Out osl_writeProfileString [ok]");
739 sal_Bool SAL_CALL
osl_writeProfileBool(oslProfile Profile
,
740 const sal_Char
* pszSection
,
741 const sal_Char
* pszEntry
,
746 #ifdef TRACE_OSL_PROFILE
747 OSL_TRACE("In osl_writeProfileBool");
751 bRet
=osl_writeProfileString(Profile
, pszSection
, pszEntry
, STR_INI_BOOLONE
);
753 bRet
=osl_writeProfileString(Profile
, pszSection
, pszEntry
, STR_INI_BOOLZERO
);
755 #ifdef TRACE_OSL_PROFILE
756 OSL_TRACE("Out osl_writeProfileBool [ok]");
762 sal_Bool SAL_CALL
osl_writeProfileIdent(oslProfile Profile
,
763 const sal_Char
* pszSection
,
764 const sal_Char
* pszEntry
,
766 const sal_Char
* Strings
[],
772 #ifdef TRACE_OSL_PROFILE
773 OSL_TRACE("In osl_writeProfileIdent");
776 while (Strings
[n
] != NULL
)
779 if ((i
= Value
- FirstId
) >= n
)
782 bRet
= osl_writeProfileString(Profile
, pszSection
, pszEntry
, Strings
[i
]);
784 #ifdef TRACE_OSL_PROFILE
785 OSL_TRACE("Out osl_writeProfileIdent");
790 sal_Bool SAL_CALL
osl_removeProfileEntry(oslProfile Profile
,
791 const sal_Char
*pszSection
,
792 const sal_Char
*pszEntry
)
795 osl_TProfileSection
* pSec
;
796 osl_TProfileImpl
* pProfile
= 0;
797 osl_TProfileImpl
* pTmpProfile
= 0;
800 #ifdef TRACE_OSL_PROFILE
801 OSL_TRACE("In osl_removeProfileEntry");
804 pTmpProfile
= (osl_TProfileImpl
*) Profile
;
806 if ( pTmpProfile
== 0 )
808 #ifdef TRACE_OSL_PROFILE
809 OSL_TRACE("Out osl_removeProfileEntry [pProfile==0]");
814 pthread_mutex_lock(&(pTmpProfile
->m_AccessLock
));
816 if ( pTmpProfile
->m_bIsValid
== false )
818 OSL_ASSERT(pTmpProfile
->m_bIsValid
);
819 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
820 #ifdef TRACE_OSL_PROFILE
821 OSL_TRACE("Out osl_removeProfileEntry [not valid]");
826 pProfile
= acquireProfile(Profile
, true);
828 if (pProfile
== NULL
)
830 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
831 #ifdef TRACE_OSL_PROFILE
832 OSL_TRACE("Out osl_removeProfileEntry [pProfile==0]");
837 if (! (pProfile
->m_Flags
& osl_Profile_SYSTEM
))
839 if (((pSec
= findEntry(pProfile
, pszSection
, pszEntry
, &NoEntry
)) != NULL
) &&
840 (NoEntry
< pSec
->m_NoEntries
))
842 removeLine(pProfile
, pSec
->m_Entries
[NoEntry
].m_Line
);
843 removeEntry(pSec
, NoEntry
);
844 if (pSec
->m_NoEntries
== 0)
846 removeLine(pProfile
, pSec
->m_Line
);
848 /* remove any empty separation line */
849 if ((pSec
->m_Line
> 0) && (pProfile
->m_Lines
[pSec
->m_Line
- 1][0] == '\0'))
850 removeLine(pProfile
, pSec
->m_Line
- 1);
852 removeSection(pProfile
, pSec
);
855 pProfile
->m_Flags
|= FLG_MODIFIED
;
859 { /* not implemented */ }
861 bRet
= releaseProfile(pProfile
);
864 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
866 #ifdef TRACE_OSL_PROFILE
867 OSL_TRACE("Out osl_removeProfileEntry [ok]");
872 sal_uInt32 SAL_CALL
osl_getProfileSectionEntries(oslProfile Profile
,
873 const sal_Char
*pszSection
,
879 osl_TProfileSection
* pSec
;
880 osl_TProfileImpl
* pProfile
= 0;
881 osl_TProfileImpl
* pTmpProfile
= 0;
884 #ifdef TRACE_OSL_PROFILE
885 OSL_TRACE("In osl_getProfileSectionEntries");
888 pTmpProfile
= (osl_TProfileImpl
*) Profile
;
890 if ( pTmpProfile
== 0 )
892 #ifdef TRACE_OSL_PROFILE
893 OSL_TRACE("Out osl_getProfileSectionEntries [pTmpProfile==0]");
899 pthread_mutex_lock(&(pTmpProfile
->m_AccessLock
));
901 if ( pTmpProfile
->m_bIsValid
== false )
903 OSL_ASSERT(pTmpProfile
->m_bIsValid
);
905 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
907 #ifdef TRACE_OSL_PROFILE
908 OSL_TRACE("Out osl_getProfileSectionEntries [not valid]");
914 pProfile
= acquireProfile(Profile
, false);
916 if (pProfile
== NULL
)
918 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
920 #ifdef TRACE_OSL_PROFILE
921 OSL_TRACE("Out osl_getProfileSectionEntries [pProfile=0]");
927 if (! (pProfile
->m_Flags
& osl_Profile_SYSTEM
))
929 if ((pSec
= findEntry(pProfile
, pszSection
, "", &NoEntry
)) != NULL
)
933 for (i
= 0; i
< pSec
->m_NoEntries
; i
++)
935 if ((n
+ pSec
->m_Entries
[i
].m_Len
+ 1) < MaxLen
)
937 strncpy(&pszBuffer
[n
], &pProfile
->m_Lines
[pSec
->m_Entries
[i
].m_Line
]
938 [pSec
->m_Entries
[i
].m_Offset
], pSec
->m_Entries
[i
].m_Len
);
939 n
+= pSec
->m_Entries
[i
].m_Len
;
940 pszBuffer
[n
++] = '\0';
947 pszBuffer
[n
++] = '\0';
951 for (i
= 0; i
< pSec
->m_NoEntries
; i
++)
952 n
+= pSec
->m_Entries
[i
].m_Len
+ 1;
961 /* not implemented */
964 bRet
=releaseProfile(pProfile
);
968 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
970 #ifdef TRACE_OSL_PROFILE
971 OSL_TRACE("Out osl_getProfileSectionEntries [ok]");
977 sal_uInt32 SAL_CALL
osl_getProfileSections(oslProfile Profile
,
982 osl_TProfileSection
* pSec
;
983 osl_TProfileImpl
* pProfile
= 0;
984 osl_TProfileImpl
* pTmpProfile
= 0;
987 #ifdef TRACE_OSL_PROFILE
988 OSL_TRACE("In osl_getProfileSections");
991 pTmpProfile
= (osl_TProfileImpl
*) Profile
;
993 if ( pTmpProfile
== 0 )
995 #ifdef TRACE_OSL_PROFILE
996 OSL_TRACE("Out osl_getProfileSections [pTmpProfile==0]");
1001 pthread_mutex_lock(&(pTmpProfile
->m_AccessLock
));
1003 if ( pTmpProfile
->m_bIsValid
== false )
1005 OSL_ASSERT(pTmpProfile
->m_bIsValid
);
1006 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
1007 #ifdef TRACE_OSL_PROFILE
1008 OSL_TRACE("Out osl_getProfileSections [not valid]");
1013 pProfile
= acquireProfile(Profile
, false);
1015 if (pProfile
== NULL
)
1017 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
1019 #ifdef TRACE_OSL_PROFILE
1020 OSL_TRACE("Out osl_getProfileSections [pProfile==0]");
1025 if (! (pProfile
->m_Flags
& osl_Profile_SYSTEM
))
1029 for (i
= 0; i
< pProfile
->m_NoSections
; i
++)
1031 pSec
= &pProfile
->m_Sections
[i
];
1033 if ((n
+ pSec
->m_Len
+ 1) < MaxLen
)
1035 strncpy(&pszBuffer
[n
], &pProfile
->m_Lines
[pSec
->m_Line
][pSec
->m_Offset
],
1038 pszBuffer
[n
++] = '\0';
1044 pszBuffer
[n
++] = '\0';
1048 for (i
= 0; i
< pProfile
->m_NoSections
; i
++)
1049 n
+= pProfile
->m_Sections
[i
].m_Len
+ 1;
1055 { /* not implemented */ }
1057 bRet
=releaseProfile(pProfile
);
1061 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
1063 #ifdef TRACE_OSL_PROFILE
1064 OSL_TRACE("Out osl_getProfileSections [ok]");
1070 static osl_TStamp
OslProfile_getFileStamp(osl_TFile
* pFile
)
1074 if ( (pFile
->m_Handle
< 0) || (fstat(pFile
->m_Handle
, &status
) < 0) )
1079 return (status
.st_mtime
);
1082 static bool OslProfile_lockFile(const osl_TFile
* pFile
, osl_TLockMode eMode
)
1085 /* boring hack, but initializers for static vars must be constant */
1086 static bool bIsInitialized
= false;
1087 static bool bLockingDisabled
;
1089 #ifdef TRACE_OSL_PROFILE
1090 OSL_TRACE("In OslProfile_lockFile");
1093 if ( !bIsInitialized
)
1095 sal_Char
* pEnvValue
;
1096 pEnvValue
= getenv( "STAR_PROFILE_LOCKING_DISABLED" );
1098 if ( pEnvValue
== 0 )
1100 bLockingDisabled
= false;
1105 bLockingDisabled
= true;
1108 bIsInitialized
= true;
1111 if (pFile
->m_Handle
< 0)
1113 #ifdef TRACE_OSL_PROFILE
1114 OSL_TRACE("Out OslProfile_lockFile [invalid file handle]");
1119 if ( bLockingDisabled
)
1121 #ifdef TRACE_OSL_PROFILE
1122 OSL_TRACE("Out OslProfile_lockFile [locking disabled]");
1128 lock
.l_whence
= SEEK_SET
;
1134 lock
.l_type
= F_UNLCK
;
1138 lock
.l_type
= F_RDLCK
;
1142 lock
.l_type
= F_WRLCK
;
1147 if ( fcntl(pFile
->m_Handle
, F_SETLKW
, &lock
) == -1 )
1149 /* Mac OSX will return ENOTSUP for webdav drives so we should ignore it */
1150 if ( fcntl(pFile
->m_Handle
, F_SETLKW
, &lock
) == -1 && errno
!= ENOTSUP
)
1153 OSL_TRACE("fcntl returned -1 (%s)",strerror(errno
));
1154 #ifdef TRACE_OSL_PROFILE
1155 OSL_TRACE("Out OslProfile_lockFile [fcntl F_SETLKW]");
1160 #ifdef TRACE_OSL_PROFILE
1161 OSL_TRACE("Out OslProfile_lockFile [ok]");
1166 static osl_TFile
* openFileImpl(const sal_Char
* pszFilename
, oslProfileOption ProfileFlags
)
1169 osl_TFile
* pFile
= (osl_TFile
*) calloc(1, sizeof(osl_TFile
));
1170 bool bWriteable
= false;
1172 if ( ProfileFlags
& ( osl_Profile_WRITELOCK
| osl_Profile_FLUSHWRITE
) )
1174 #ifdef DEBUG_OSL_PROFILE
1175 OSL_TRACE("setting bWriteable to TRUE");
1182 #ifdef DEBUG_OSL_PROFILE
1183 OSL_TRACE("opening '%s' read only",pszFilename
);
1186 pFile
->m_Handle
= open(pszFilename
, O_RDONLY
);
1187 /* mfe: argghh!!! do not check if the file could be openend */
1188 /* default mode expects it that way!!! */
1192 #ifdef DEBUG_OSL_PROFILE
1193 OSL_TRACE("opening '%s' read/write",pszFilename
);
1195 if (((pFile
->m_Handle
= open(pszFilename
, O_RDWR
| O_CREAT
| O_EXCL
, DEFAULT_PMODE
)) < 0) &&
1196 ((pFile
->m_Handle
= open(pszFilename
, O_RDWR
)) < 0))
1199 #ifdef TRACE_OSL_PROFILE
1200 OSL_TRACE("Out openFileImpl [open read/write]");
1206 /* set close-on-exec flag */
1207 if ((Flags
= fcntl(pFile
->m_Handle
, F_GETFD
, 0)) != -1)
1209 Flags
|= FD_CLOEXEC
;
1210 int e
= fcntl(pFile
->m_Handle
, F_SETFD
, Flags
);
1213 "fcntl to set FD_CLOEXEC failed for " << pszFilename
);
1216 pFile
->m_pWriteBuf
=0;
1217 pFile
->m_nWriteBufFree
=0;
1218 pFile
->m_nWriteBufLen
=0;
1220 if ( ProfileFlags
& (osl_Profile_WRITELOCK
| osl_Profile_READLOCK
) )
1222 #ifdef DEBUG_OSL_PROFILE
1223 OSL_TRACE("locking '%s' file",pszFilename
);
1225 OslProfile_lockFile(pFile
, bWriteable
? write_lock
: read_lock
);
1228 #ifdef TRACE_OSL_PROFILE
1229 OSL_TRACE("Out openFileImpl [ok]");
1234 static osl_TStamp
closeFileImpl(osl_TFile
* pFile
, oslProfileOption Flags
)
1236 osl_TStamp stamp
= 0;
1238 #ifdef TRACE_OSL_PROFILE
1239 OSL_TRACE("In closeFileImpl");
1244 #ifdef TRACE_OSL_PROFILE
1245 OSL_TRACE("Out closeFileImpl [pFile == 0]");
1250 if ( pFile
->m_Handle
>= 0 )
1252 stamp
= OslProfile_getFileStamp(pFile
);
1254 if ( Flags
& (osl_Profile_WRITELOCK
| osl_Profile_READLOCK
) )
1256 OslProfile_lockFile(pFile
, un_lock
);
1259 close(pFile
->m_Handle
);
1260 pFile
->m_Handle
= -1;
1263 if ( pFile
->m_pWriteBuf
)
1265 free(pFile
->m_pWriteBuf
);
1270 #ifdef TRACE_OSL_PROFILE
1271 OSL_TRACE("Out closeFileImpl [ok]");
1277 static bool OslProfile_rewindFile(osl_TFile
* pFile
, bool bTruncate
)
1280 #ifdef TRACE_OSL_PROFILE
1281 OSL_TRACE("In osl_OslProfile_rewindFile");
1284 if (pFile
->m_Handle
>= 0)
1286 pFile
->m_pReadPtr
= pFile
->m_ReadBuf
+ sizeof(pFile
->m_ReadBuf
);
1288 #ifdef DEBUG_OSL_PROFILE
1289 OSL_TRACE("rewinding");
1291 bRet
= (lseek(pFile
->m_Handle
, SEEK_SET
, 0L) == 0L);
1295 #ifdef DEBUG_OSL_PROFILE
1296 OSL_TRACE("truncating");
1298 bRet
&= (ftruncate(pFile
->m_Handle
, 0L) == 0);
1303 #ifdef TRACE_OSL_PROFILE
1304 OSL_TRACE("Out osl_OslProfile_rewindFile [ok]");
1309 static sal_Char
* OslProfile_getLine(osl_TFile
* pFile
)
1311 int Max
, Free
, Bytes
, nLineBytes
= 0;
1313 sal_Char
* pLine
= NULL
;
1321 if (pFile
->m_Handle
< 0)
1326 Bytes
= sizeof(pFile
->m_ReadBuf
) - (pFile
->m_pReadPtr
- pFile
->m_ReadBuf
);
1331 memcpy(pFile
->m_ReadBuf
, pFile
->m_pReadPtr
, Bytes
);
1332 pFile
->m_pReadPtr
= pFile
->m_ReadBuf
;
1334 Free
= sizeof(pFile
->m_ReadBuf
) - Bytes
;
1336 if ((Max
= read(pFile
->m_Handle
, &pFile
->m_ReadBuf
[Bytes
], Free
)) < 0)
1338 OSL_TRACE("read failed '%s'",strerror(errno
));
1341 rtl_freeMemory( pLine
);
1348 if ((Max
== 0) && ! pLine
)
1351 pFile
->m_ReadBuf
[Bytes
+ Max
] = '\0';
1355 for (pChr
= pFile
->m_pReadPtr
;
1356 (*pChr
!= '\n') && (*pChr
!= '\r') && (*pChr
!= '\0') &&
1357 (pChr
< (pFile
->m_ReadBuf
+ sizeof(pFile
->m_ReadBuf
) - 1));
1360 Max
= pChr
- pFile
->m_pReadPtr
;
1361 pNewLine
= (sal_Char
*) rtl_allocateMemory( nLineBytes
+ Max
+ 1 );
1364 memcpy( pNewLine
, pLine
, nLineBytes
);
1365 rtl_freeMemory( pLine
);
1367 memcpy(pNewLine
+nLineBytes
, pFile
->m_pReadPtr
, Max
);
1369 pNewLine
[ nLineBytes
] = 0;
1372 if (pChr
< (pFile
->m_ReadBuf
+ sizeof(pFile
->m_ReadBuf
) - 1))
1376 if ((pChr
[0] == '\r') && (pChr
[1] == '\n'))
1382 if ((pChr
< (pFile
->m_ReadBuf
+ sizeof(pFile
->m_ReadBuf
))) &&
1384 pChr
= pFile
->m_ReadBuf
+ sizeof(pFile
->m_ReadBuf
);
1386 /* setting Max to -1 indicates terminating read loop */
1390 pFile
->m_pReadPtr
= pChr
;
1397 static bool OslProfile_putLine(osl_TFile
* pFile
, const sal_Char
*pszLine
)
1399 unsigned int Len
= strlen(pszLine
);
1401 #ifdef DEBUG_OSL_PROFILE
1405 if ( pFile
== 0 || pFile
->m_Handle
< 0 )
1410 if ( pFile
->m_pWriteBuf
== 0 )
1412 pFile
->m_pWriteBuf
= (sal_Char
*) malloc(Len
+3);
1413 pFile
->m_nWriteBufLen
= Len
+3;
1414 pFile
->m_nWriteBufFree
= Len
+3;
1418 if ( pFile
->m_nWriteBufFree
<= Len
+ 3 )
1422 pTmp
=(sal_Char
*) realloc(pFile
->m_pWriteBuf
,( ( pFile
->m_nWriteBufLen
+ Len
) * 2) );
1427 pFile
->m_pWriteBuf
= pTmp
;
1428 pFile
->m_nWriteBufFree
= pFile
->m_nWriteBufFree
+ pFile
->m_nWriteBufLen
+ ( 2 * Len
);
1429 pFile
->m_nWriteBufLen
= ( pFile
->m_nWriteBufLen
+ Len
) * 2;
1430 memset( (pFile
->m_pWriteBuf
) + ( pFile
->m_nWriteBufLen
- pFile
->m_nWriteBufFree
), 0, pFile
->m_nWriteBufFree
);
1434 memcpy(pFile
->m_pWriteBuf
+ ( pFile
->m_nWriteBufLen
- pFile
->m_nWriteBufFree
),pszLine
,Len
+1);
1435 #ifdef DEBUG_OSL_PROFILE
1436 strLen
= strlen(pFile
->m_pWriteBuf
);
1438 pFile
->m_pWriteBuf
[pFile
->m_nWriteBufLen
- pFile
->m_nWriteBufFree
+ Len
]='\n';
1439 pFile
->m_pWriteBuf
[pFile
->m_nWriteBufLen
- pFile
->m_nWriteBufFree
+ Len
+ 1]='\0';
1441 pFile
->m_nWriteBufFree
-=Len
+1;
1446 static sal_Char
* stripBlanks(sal_Char
* String
, sal_uInt32
* pLen
)
1448 if ( ( pLen
!= NULL
) && ( *pLen
!= 0 ) )
1450 while ((String
[*pLen
- 1] == ' ') || (String
[*pLen
- 1] == '\t'))
1453 while ( (*String
== ' ') || (*String
== '\t') )
1460 while ( (*String
== ' ') || (*String
== '\t') )
1466 static sal_Char
* addLine(osl_TProfileImpl
* pProfile
, const sal_Char
* Line
)
1468 if (pProfile
->m_NoLines
>= pProfile
->m_MaxLines
)
1470 if (pProfile
->m_Lines
== NULL
)
1472 pProfile
->m_MaxLines
= LINES_INI
;
1473 pProfile
->m_Lines
= (sal_Char
**)malloc(pProfile
->m_MaxLines
* sizeof(sal_Char
*));
1474 memset(pProfile
->m_Lines
,0,pProfile
->m_MaxLines
* sizeof(sal_Char
*));
1479 unsigned int oldmax
=pProfile
->m_MaxLines
;
1481 pProfile
->m_MaxLines
+= LINES_ADD
;
1482 pProfile
->m_Lines
= (sal_Char
**)realloc(pProfile
->m_Lines
,
1483 pProfile
->m_MaxLines
* sizeof(sal_Char
*));
1484 for ( idx
= oldmax
; idx
< pProfile
->m_MaxLines
; ++idx
)
1486 pProfile
->m_Lines
[idx
]=0;
1490 if (pProfile
->m_Lines
== NULL
)
1492 pProfile
->m_NoLines
= 0;
1493 pProfile
->m_MaxLines
= 0;
1497 if ( pProfile
->m_Lines
[pProfile
->m_NoLines
] != 0 )
1499 free(pProfile
->m_Lines
[pProfile
->m_NoLines
]);
1501 pProfile
->m_Lines
[pProfile
->m_NoLines
++] = strdup(Line
);
1503 return (pProfile
->m_Lines
[pProfile
->m_NoLines
- 1]);
1506 static sal_Char
* insertLine(osl_TProfileImpl
* pProfile
, const sal_Char
* Line
, sal_uInt32 LineNo
)
1508 if (pProfile
->m_NoLines
>= pProfile
->m_MaxLines
)
1510 if (pProfile
->m_Lines
== NULL
)
1512 pProfile
->m_MaxLines
= LINES_INI
;
1513 pProfile
->m_Lines
= (sal_Char
**)malloc(pProfile
->m_MaxLines
* sizeof(sal_Char
*));
1514 memset(pProfile
->m_Lines
,0,pProfile
->m_MaxLines
* sizeof(sal_Char
*));
1518 pProfile
->m_MaxLines
+= LINES_ADD
;
1519 pProfile
->m_Lines
= (sal_Char
**)realloc(pProfile
->m_Lines
,
1520 pProfile
->m_MaxLines
* sizeof(sal_Char
*));
1522 memset(&pProfile
->m_Lines
[pProfile
->m_NoLines
],
1524 (pProfile
->m_MaxLines
- pProfile
->m_NoLines
- 1) * sizeof(sal_Char
*));
1527 if (pProfile
->m_Lines
== NULL
)
1529 pProfile
->m_NoLines
= 0;
1530 pProfile
->m_MaxLines
= 0;
1535 LineNo
= LineNo
> pProfile
->m_NoLines
? pProfile
->m_NoLines
: LineNo
;
1537 if (LineNo
< pProfile
->m_NoLines
)
1540 osl_TProfileSection
* pSec
;
1542 memmove(&pProfile
->m_Lines
[LineNo
+ 1], &pProfile
->m_Lines
[LineNo
],
1543 (pProfile
->m_NoLines
- LineNo
) * sizeof(sal_Char
*));
1545 /* adjust line references */
1546 for (i
= 0; i
< pProfile
->m_NoSections
; i
++)
1548 pSec
= &pProfile
->m_Sections
[i
];
1550 if (pSec
->m_Line
>= LineNo
)
1553 for (n
= 0; n
< pSec
->m_NoEntries
; n
++)
1554 if (pSec
->m_Entries
[n
].m_Line
>= LineNo
)
1555 pSec
->m_Entries
[n
].m_Line
++;
1559 pProfile
->m_NoLines
++;
1561 pProfile
->m_Lines
[LineNo
] = strdup(Line
);
1563 return (pProfile
->m_Lines
[LineNo
]);
1566 static void removeLine(osl_TProfileImpl
* pProfile
, sal_uInt32 LineNo
)
1568 if (LineNo
< pProfile
->m_NoLines
)
1570 free(pProfile
->m_Lines
[LineNo
]);
1571 pProfile
->m_Lines
[LineNo
]=0;
1572 if (pProfile
->m_NoLines
- LineNo
> 1)
1575 osl_TProfileSection
* pSec
;
1577 memmove(&pProfile
->m_Lines
[LineNo
], &pProfile
->m_Lines
[LineNo
+ 1],
1578 (pProfile
->m_NoLines
- LineNo
- 1) * sizeof(sal_Char
*));
1580 memset(&pProfile
->m_Lines
[pProfile
->m_NoLines
- 1],
1582 (pProfile
->m_MaxLines
- pProfile
->m_NoLines
) * sizeof(sal_Char
*));
1584 /* adjust line references */
1585 for (i
= 0; i
< pProfile
->m_NoSections
; i
++)
1587 pSec
= &pProfile
->m_Sections
[i
];
1589 if (pSec
->m_Line
> LineNo
)
1592 for (n
= 0; n
< pSec
->m_NoEntries
; n
++)
1593 if (pSec
->m_Entries
[n
].m_Line
> LineNo
)
1594 pSec
->m_Entries
[n
].m_Line
--;
1599 pProfile
->m_Lines
[LineNo
] = 0;
1602 pProfile
->m_NoLines
--;
1608 static void setEntry(osl_TProfileImpl
* pProfile
, osl_TProfileSection
* pSection
,
1609 sal_uInt32 NoEntry
, sal_uInt32 Line
,
1610 sal_Char
* Entry
, sal_uInt32 Len
)
1612 Entry
= stripBlanks(Entry
, &Len
);
1613 pSection
->m_Entries
[NoEntry
].m_Line
= Line
;
1614 pSection
->m_Entries
[NoEntry
].m_Offset
= Entry
- pProfile
->m_Lines
[Line
];
1615 pSection
->m_Entries
[NoEntry
].m_Len
= Len
;
1620 static bool addEntry(osl_TProfileImpl
* pProfile
,
1621 osl_TProfileSection
*pSection
,
1622 int Line
, sal_Char
* Entry
,
1625 if (pSection
!= NULL
)
1627 if (pSection
->m_NoEntries
>= pSection
->m_MaxEntries
)
1629 if (pSection
->m_Entries
== NULL
)
1631 pSection
->m_MaxEntries
= ENTRIES_INI
;
1632 pSection
->m_Entries
= (osl_TProfileEntry
*)malloc(
1633 pSection
->m_MaxEntries
* sizeof(osl_TProfileEntry
));
1637 pSection
->m_MaxEntries
+= ENTRIES_ADD
;
1638 pSection
->m_Entries
= (osl_TProfileEntry
*)realloc(pSection
->m_Entries
,
1639 pSection
->m_MaxEntries
* sizeof(osl_TProfileEntry
));
1642 if (pSection
->m_Entries
== NULL
)
1644 pSection
->m_NoEntries
= 0;
1645 pSection
->m_MaxEntries
= 0;
1650 pSection
->m_NoEntries
++;
1652 Entry
= stripBlanks(Entry
, &Len
);
1653 setEntry(pProfile
, pSection
, pSection
->m_NoEntries
- 1, Line
,
1662 static void removeEntry(osl_TProfileSection
*pSection
, sal_uInt32 NoEntry
)
1664 if (NoEntry
< pSection
->m_NoEntries
)
1666 if (pSection
->m_NoEntries
- NoEntry
> 1)
1668 memmove(&pSection
->m_Entries
[NoEntry
],
1669 &pSection
->m_Entries
[NoEntry
+ 1],
1670 (pSection
->m_NoEntries
- NoEntry
- 1) * sizeof(osl_TProfileEntry
));
1671 pSection
->m_Entries
[pSection
->m_NoEntries
- 1].m_Line
=0;
1672 pSection
->m_Entries
[pSection
->m_NoEntries
- 1].m_Offset
=0;
1673 pSection
->m_Entries
[pSection
->m_NoEntries
- 1].m_Len
=0;
1676 pSection
->m_NoEntries
--;
1682 static bool addSection(osl_TProfileImpl
* pProfile
, int Line
, const sal_Char
* Section
, sal_uInt32 Len
)
1684 if (pProfile
->m_NoSections
>= pProfile
->m_MaxSections
)
1686 if (pProfile
->m_Sections
== NULL
)
1688 pProfile
->m_MaxSections
= SECTIONS_INI
;
1689 pProfile
->m_Sections
= (osl_TProfileSection
*)malloc(pProfile
->m_MaxSections
* sizeof(osl_TProfileSection
));
1690 memset(pProfile
->m_Sections
,0,pProfile
->m_MaxSections
* sizeof(osl_TProfileSection
));
1695 unsigned int oldmax
=pProfile
->m_MaxSections
;
1697 pProfile
->m_MaxSections
+= SECTIONS_ADD
;
1698 pProfile
->m_Sections
= (osl_TProfileSection
*)realloc(pProfile
->m_Sections
,
1699 pProfile
->m_MaxSections
* sizeof(osl_TProfileSection
));
1700 for ( idx
= oldmax
; idx
< pProfile
->m_MaxSections
; ++idx
)
1702 pProfile
->m_Sections
[idx
].m_Entries
=0;
1706 if (pProfile
->m_Sections
== NULL
)
1708 pProfile
->m_NoSections
= 0;
1709 pProfile
->m_MaxSections
= 0;
1714 pProfile
->m_NoSections
++;
1716 if ( pProfile
->m_Sections
[(pProfile
->m_NoSections
) - 1].m_Entries
!= 0 )
1718 free(pProfile
->m_Sections
[(pProfile
->m_NoSections
) - 1].m_Entries
);
1720 pProfile
->m_Sections
[pProfile
->m_NoSections
- 1].m_Entries
= NULL
;
1721 pProfile
->m_Sections
[pProfile
->m_NoSections
- 1].m_NoEntries
= 0;
1722 pProfile
->m_Sections
[pProfile
->m_NoSections
- 1].m_MaxEntries
= 0;
1724 pProfile
->m_Sections
[pProfile
->m_NoSections
- 1].m_Line
= Line
;
1725 pProfile
->m_Sections
[pProfile
->m_NoSections
- 1].m_Offset
= Section
- pProfile
->m_Lines
[Line
];
1726 pProfile
->m_Sections
[pProfile
->m_NoSections
- 1].m_Len
= Len
;
1731 static void removeSection(osl_TProfileImpl
* pProfile
, osl_TProfileSection
*pSection
)
1735 if ((Section
= pSection
- pProfile
->m_Sections
) < pProfile
->m_NoSections
)
1737 free (pSection
->m_Entries
);
1738 pSection
->m_Entries
=0;
1739 if (pProfile
->m_NoSections
- Section
> 1)
1741 memmove(&pProfile
->m_Sections
[Section
], &pProfile
->m_Sections
[Section
+ 1],
1742 (pProfile
->m_NoSections
- Section
- 1) * sizeof(osl_TProfileSection
));
1744 memset(&pProfile
->m_Sections
[pProfile
->m_NoSections
- 1],
1746 (pProfile
->m_MaxSections
- pProfile
->m_NoSections
) * sizeof(osl_TProfileSection
));
1747 pProfile
->m_Sections
[pProfile
->m_NoSections
- 1].m_Entries
= 0;
1751 pSection
->m_Entries
= 0;
1754 pProfile
->m_NoSections
--;
1760 static osl_TProfileSection
* findEntry(osl_TProfileImpl
* pProfile
,
1761 const sal_Char
* Section
,
1762 const sal_Char
* Entry
,
1763 sal_uInt32
*pNoEntry
)
1765 static sal_uInt32 Sect
= 0;
1768 const sal_Char
* pStr
;
1769 osl_TProfileSection
* pSec
=0;
1771 Len
= strlen(Section
);
1775 for (i
= 0; i
< pProfile
->m_NoSections
; i
++)
1777 n
%= pProfile
->m_NoSections
;
1778 pSec
= &pProfile
->m_Sections
[n
];
1779 if ((Len
== pSec
->m_Len
) &&
1780 (strncasecmp(Section
, &pProfile
->m_Lines
[pSec
->m_Line
][pSec
->m_Offset
], pSec
->m_Len
)
1788 if (i
< pProfile
->m_NoSections
)
1790 Len
= strlen(Entry
);
1792 *pNoEntry
= pSec
->m_NoEntries
;
1794 for (i
= 0; i
< pSec
->m_NoEntries
; i
++)
1796 pStr
= &pProfile
->m_Lines
[pSec
->m_Entries
[i
].m_Line
]
1797 [pSec
->m_Entries
[i
].m_Offset
];
1798 if ((Len
== pSec
->m_Entries
[i
].m_Len
) &&
1799 (strncasecmp(Entry
, pStr
, pSec
->m_Entries
[i
].m_Len
)
1813 static bool loadProfile(osl_TFile
* pFile
, osl_TProfileImpl
* pProfile
)
1820 sal_Char
* bWasAdded
= NULL
;
1832 pProfile
->m_NoLines
= 0;
1833 pProfile
->m_NoSections
= 0;
1835 OSL_VERIFY(OslProfile_rewindFile(pFile
, false));
1837 while ( ( pLine
=OslProfile_getLine(pFile
) ) != 0 )
1839 bWasAdded
= addLine( pProfile
, pLine
);
1840 rtl_freeMemory( pLine
);
1841 OSL_ASSERT(bWasAdded
);
1846 for (i
= 0; i
< pProfile
->m_NoLines
; i
++)
1848 pStr
= (sal_Char
*)stripBlanks(pProfile
->m_Lines
[i
], NULL
);
1850 if ((*pStr
== '\0') || (*pStr
== ';'))
1853 if ((*pStr
!= '[') || ((pChar
= strrchr(pStr
, ']')) == NULL
) ||
1854 ((pChar
- pStr
) <= 2))
1858 if (pProfile
->m_NoSections
< 1)
1861 if ((pChar
= strchr(pStr
, '=')) == NULL
)
1862 pChar
= pStr
+ strlen(pStr
);
1864 if (! addEntry(pProfile
, &pProfile
->m_Sections
[pProfile
->m_NoSections
- 1],
1865 i
, pStr
, pChar
- pStr
))
1876 if (! addSection(pProfile
, i
, pStr
+ 1, pChar
- pStr
- 1))
1888 static bool storeProfile(osl_TProfileImpl
* pProfile
, bool bCleanup
)
1890 #ifdef TRACE_OSL_PROFILE
1891 OSL_TRACE("In storeProfile");
1894 if (pProfile
->m_Lines
!= NULL
)
1896 if (pProfile
->m_Flags
& FLG_MODIFIED
)
1900 osl_TFile
* pTmpFile
= osl_openTmpProfileImpl(pProfile
);
1902 if ( pTmpFile
== 0 )
1907 OSL_VERIFY(OslProfile_rewindFile(pTmpFile
, true));
1909 for ( i
= 0 ; i
< pProfile
->m_NoLines
; i
++ )
1911 OSL_VERIFY(OslProfile_putLine(pTmpFile
, pProfile
->m_Lines
[i
]));
1914 if ( ! writeProfileImpl(pTmpFile
) )
1916 if ( pTmpFile
->m_pWriteBuf
!= 0 )
1918 free(pTmpFile
->m_pWriteBuf
);
1921 pTmpFile
->m_pWriteBuf
=0;
1922 pTmpFile
->m_nWriteBufLen
=0;
1923 pTmpFile
->m_nWriteBufFree
=0;
1925 #ifdef TRACE_OSL_PROFILE
1926 OSL_TRACE("Out storeProfile [not flushed]");
1928 closeFileImpl(pTmpFile
,pProfile
->m_Flags
);
1933 pProfile
->m_Flags
&= ~FLG_MODIFIED
;
1935 closeFileImpl(pProfile
->m_pFile
,pProfile
->m_Flags
);
1936 closeFileImpl(pTmpFile
,pProfile
->m_Flags
);
1938 osl_ProfileSwapProfileNames(pProfile
);
1940 pProfile
->m_pFile
= openFileImpl(pProfile
->m_FileName
,pProfile
->m_Flags
);
1946 while (pProfile
->m_NoLines
> 0)
1947 removeLine(pProfile
, pProfile
->m_NoLines
- 1);
1949 free(pProfile
->m_Lines
);
1950 pProfile
->m_Lines
= NULL
;
1951 pProfile
->m_NoLines
= 0;
1952 pProfile
->m_MaxLines
= 0;
1954 while (pProfile
->m_NoSections
> 0)
1955 removeSection(pProfile
, &pProfile
->m_Sections
[pProfile
->m_NoSections
- 1]);
1957 free(pProfile
->m_Sections
);
1958 pProfile
->m_Sections
= NULL
;
1959 pProfile
->m_NoSections
= 0;
1960 pProfile
->m_MaxSections
= 0;
1964 #ifdef TRACE_OSL_PROFILE
1965 OSL_TRACE("Out storeProfile [ok]");
1970 static osl_TFile
* osl_openTmpProfileImpl(osl_TProfileImpl
* pProfile
)
1973 sal_Char
const * pszExtension
= "tmp";
1974 sal_Char pszTmpName
[PATH_MAX
];
1975 oslProfileOption PFlags
=0;
1977 pszTmpName
[0] = '\0';
1979 /* generate tmp profilename */
1980 osl_ProfileGenerateExtension(pProfile
->m_FileName
, pszExtension
, pszTmpName
, PATH_MAX
);
1982 if ( pszTmpName
[0] == 0 )
1987 if ( ! ( pProfile
->m_Flags
& osl_Profile_READLOCK
) )
1989 PFlags
|= osl_Profile_WRITELOCK
;
1992 /* open this file */
1993 pFile
= openFileImpl(pszTmpName
,pProfile
->m_Flags
| PFlags
);
1995 /* return new pFile */
1999 static bool osl_ProfileSwapProfileNames(osl_TProfileImpl
* pProfile
)
2001 sal_Char pszBakFile
[PATH_MAX
];
2002 sal_Char pszTmpFile
[PATH_MAX
];
2004 pszBakFile
[0] = '\0';
2005 pszTmpFile
[0] = '\0';
2007 osl_ProfileGenerateExtension(pProfile
->m_FileName
, "bak", pszBakFile
, PATH_MAX
);
2008 osl_ProfileGenerateExtension(pProfile
->m_FileName
, "tmp", pszTmpFile
, PATH_MAX
);
2011 unlink( pszBakFile
);
2013 // Rename ini -> bak, then tmp -> ini:
2014 return rename( pProfile
->m_FileName
, pszBakFile
) == 0
2015 && rename( pszTmpFile
, pProfile
->m_FileName
) == 0;
2018 static void osl_ProfileGenerateExtension(const sal_Char
* pszFileName
, const sal_Char
* pszExtension
, sal_Char
* pszTmpName
, int BufferMaxLen
)
2020 sal_Char
* cursor
= pszTmpName
;
2023 /* concatenate filename + "." + extension, limited to the size of the
2024 * output buffer; in case of overrun, data is truncated at the end...
2025 * and the result is always 0-terminated.
2027 len
= strlen(pszFileName
);
2028 if(len
< BufferMaxLen
)
2030 memcpy(cursor
, pszFileName
, len
);
2032 BufferMaxLen
-= len
;
2036 memcpy(cursor
, pszFileName
, BufferMaxLen
- 1);
2037 cursor
+= BufferMaxLen
- 1;
2040 if(BufferMaxLen
> 1)
2045 len
= strlen(pszExtension
);
2046 if(len
< BufferMaxLen
)
2048 memcpy(cursor
, pszExtension
, len
);
2053 memcpy(cursor
, pszExtension
, BufferMaxLen
- 1);
2054 cursor
+= BufferMaxLen
- 1;
2062 static osl_TProfileImpl
* acquireProfile(oslProfile Profile
, bool bWriteable
)
2064 osl_TProfileImpl
* pProfile
= (osl_TProfileImpl
*)Profile
;
2065 oslProfileOption PFlags
=0;
2069 PFlags
= osl_Profile_DEFAULT
| osl_Profile_WRITELOCK
;
2073 PFlags
= osl_Profile_DEFAULT
;
2076 if (pProfile
== NULL
)
2078 #ifdef DEBUG_OSL_PROFILE
2079 OSL_TRACE("AUTOOPEN MODE");
2082 if ( ( pProfile
= (osl_TProfileImpl
*) osl_openProfile(0, PFlags
) ) != NULL
)
2084 pProfile
->m_Flags
|= FLG_AUTOOPEN
;
2089 #ifdef DEBUG_OSL_PROFILE
2090 OSL_TRACE("try to acquire");
2093 if (! (pProfile
->m_Flags
& osl_Profile_SYSTEM
))
2095 if (! (pProfile
->m_Flags
& (osl_Profile_READLOCK
| osl_Profile_WRITELOCK
| osl_Profile_FLUSHWRITE
)))
2099 #ifdef DEBUG_OSL_PROFILE
2100 OSL_TRACE("Profile acquire DEFAULT MODE");
2102 if (! (pProfile
->m_pFile
= openFileImpl(pProfile
->m_FileName
, pProfile
->m_Flags
| PFlags
)))
2105 Stamp
= OslProfile_getFileStamp(pProfile
->m_pFile
);
2107 if (memcmp(&Stamp
, &(pProfile
->m_Stamp
), sizeof(osl_TStamp
)))
2111 pProfile
->m_Stamp
= Stamp
;
2113 bRet
=loadProfile(pProfile
->m_pFile
, pProfile
);
2120 #ifdef DEBUG_OSL_PROFILE
2121 OSL_TRACE("Profile acquire READ/WRITELOCK MODE");
2123 /* A readlock file could not be written */
2124 if ((pProfile
->m_Flags
& osl_Profile_READLOCK
) && bWriteable
)
2135 static bool releaseProfile(osl_TProfileImpl
* pProfile
)
2137 #ifdef TRACE_OSL_PROFILE
2138 OSL_TRACE("In releaseProfile");
2141 if ( pProfile
== 0 )
2143 #ifdef TRACE_OSL_PROFILE
2144 OSL_TRACE("Out releaseProfile [profile==0]");
2149 if (pProfile
->m_Flags
& FLG_AUTOOPEN
)
2151 #ifdef TRACE_OSL_PROFILE
2152 OSL_TRACE("Out releaseProfile [AUTOOPEN]");
2154 return (osl_closeProfile((oslProfile
)pProfile
));
2158 #ifdef DEBUG_OSL_PROFILE
2159 OSL_TRACE("DEFAULT MODE");
2161 if (! (pProfile
->m_Flags
& (osl_Profile_READLOCK
| osl_Profile_WRITELOCK
| osl_Profile_FLUSHWRITE
)))
2163 if (pProfile
->m_Flags
& FLG_MODIFIED
)
2165 bool bRet
= storeProfile(pProfile
, false);
2170 closeFileImpl(pProfile
->m_pFile
,pProfile
->m_Flags
);
2171 pProfile
->m_pFile
= NULL
;
2175 #ifdef TRACE_OSL_PROFILE
2176 OSL_TRACE("Out releaseProfile [ok]");
2181 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */