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 .
22 #include "readwrite_helper.h"
24 #include <osl/diagnose.h>
25 #include <osl/profile.h>
26 #include <osl/process.h>
27 #include <osl/thread.h>
28 #include <rtl/alloc.h>
33 #define SECTIONS_INI 5
34 #define SECTIONS_ADD 3
38 #define STR_INI_BOOLYES "yes"
39 #define STR_INI_BOOLON "on"
40 #define STR_INI_BOOLONE "1"
41 #define STR_INI_BOOLNO "no"
42 #define STR_INI_BOOLOFF "off"
43 #define STR_INI_BOOLZERO "0"
45 #define FLG_USER 0x00FF
46 #define FLG_AUTOOPEN 0x0100
47 #define FLG_MODIFIED 0x0200
49 #define DEFAULT_PMODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)
51 /*#define DEBUG_OSL_PROFILE*/
52 /*#define TRACE_OSL_PROFILE*/
54 /*****************************************************************************/
55 /* Data Type Definition */
56 /*****************************************************************************/
58 typedef time_t osl_TStamp
;
60 typedef enum _osl_TLockMode
62 un_lock
, read_lock
, write_lock
65 typedef struct _osl_TFile
69 sal_Char m_ReadBuf
[512];
70 sal_Char
* m_pWriteBuf
;
71 sal_uInt32 m_nWriteBufLen
;
72 sal_uInt32 m_nWriteBufFree
;
75 typedef struct _osl_TProfileEntry
82 typedef struct _osl_TProfileSection
87 sal_uInt32 m_NoEntries
;
88 sal_uInt32 m_MaxEntries
;
89 osl_TProfileEntry
* m_Entries
;
90 } osl_TProfileSection
;
94 Profile-data structure hidden behind oslProfile:
96 typedef struct _osl_TProfileImpl
101 sal_Char m_FileName
[PATH_MAX
+ 1];
102 sal_uInt32 m_NoLines
;
103 sal_uInt32 m_MaxLines
;
104 sal_uInt32 m_NoSections
;
105 sal_uInt32 m_MaxSections
;
107 osl_TProfileSection
* m_Sections
;
108 pthread_mutex_t m_AccessLock
;
113 /*****************************************************************************/
114 /* Static Module Function Declarations */
115 /*****************************************************************************/
117 static osl_TFile
* openFileImpl(const sal_Char
* pszFilename
, oslProfileOption ProfileFlags
);
118 static osl_TStamp
closeFileImpl(osl_TFile
* pFile
, oslProfileOption Flags
);
119 static sal_Bool
OslProfile_lockFile(const osl_TFile
* pFile
, osl_TLockMode eMode
);
120 static sal_Bool
OslProfile_rewindFile(osl_TFile
* pFile
, sal_Bool bTruncate
);
121 static osl_TStamp
OslProfile_getFileStamp(osl_TFile
* pFile
);
123 static sal_Char
* OslProfile_getLine(osl_TFile
* pFile
);
124 static sal_Bool
OslProfile_putLine(osl_TFile
* pFile
, const sal_Char
*pszLine
);
125 static sal_Char
* stripBlanks(sal_Char
* String
, sal_uInt32
* pLen
);
126 static sal_Char
* addLine(osl_TProfileImpl
* pProfile
, const sal_Char
* Line
);
127 static sal_Char
* insertLine(osl_TProfileImpl
* pProfile
, const sal_Char
* Line
, sal_uInt32 LineNo
);
128 static void removeLine(osl_TProfileImpl
* pProfile
, sal_uInt32 LineNo
);
129 static void setEntry(osl_TProfileImpl
* pProfile
, osl_TProfileSection
* pSection
,
130 sal_uInt32 NoEntry
, sal_uInt32 Line
,
131 sal_Char
* Entry
, sal_uInt32 Len
);
132 static sal_Bool
addEntry(osl_TProfileImpl
* pProfile
, osl_TProfileSection
*pSection
,
133 int Line
, sal_Char
* Entry
, sal_uInt32 Len
);
134 static void removeEntry(osl_TProfileSection
*pSection
, sal_uInt32 NoEntry
);
135 static sal_Bool
addSection(osl_TProfileImpl
* pProfile
, int Line
, const sal_Char
* Section
, sal_uInt32 Len
);
136 static void removeSection(osl_TProfileImpl
* pProfile
, osl_TProfileSection
*pSection
);
137 static osl_TProfileSection
* findEntry(osl_TProfileImpl
* pProfile
, const sal_Char
* Section
,
138 const sal_Char
* Entry
, sal_uInt32
*pNoEntry
);
139 static sal_Bool
loadProfile(osl_TFile
* pFile
, osl_TProfileImpl
* pProfile
);
140 static sal_Bool
storeProfile(osl_TProfileImpl
* pProfile
, sal_Bool bCleanup
);
141 static osl_TProfileImpl
* acquireProfile(oslProfile Profile
, sal_Bool bWriteable
);
142 static sal_Bool
releaseProfile(osl_TProfileImpl
* pProfile
);
144 static sal_Bool
writeProfileImpl (osl_TFile
* pFile
);
145 static osl_TFile
* osl_openTmpProfileImpl(osl_TProfileImpl
*);
146 static sal_Bool
osl_ProfileSwapProfileNames(osl_TProfileImpl
*);
147 static void osl_ProfileGenerateExtension(sal_Char
* pszFileName
, sal_Char
* pszExtension
, sal_Char
* pszTmpName
);
148 static oslProfile SAL_CALL
osl_psz_openProfile(const sal_Char
*pszProfileName
, oslProfileOption Flags
);
150 /* implemented in file.c */
151 extern oslFileError
FileURLToPath( char *, size_t, rtl_uString
* );
153 /*****************************************************************************/
154 /* Exported Module Functions */
155 /*****************************************************************************/
156 oslProfile SAL_CALL
osl_openProfile(rtl_uString
*ustrProfileName
, oslProfileOption Options
)
158 char profilePath
[PATH_MAX
] = "";
160 if ( ustrProfileName
!= 0 && ustrProfileName
->buffer
[0] != 0 )
161 FileURLToPath( profilePath
, PATH_MAX
, ustrProfileName
);
163 return osl_psz_openProfile( profilePath
,Options
);
167 static oslProfile SAL_CALL
osl_psz_openProfile(const sal_Char
*pszProfileName
, oslProfileOption Flags
)
170 osl_TProfileImpl
* pProfile
;
171 sal_Bool bRet
= sal_False
;
173 #ifdef TRACE_OSL_PROFILE
174 OSL_TRACE("In osl_openProfile");
177 #ifdef DEBUG_OSL_PROFILE
178 Flags
=osl_Profile_FLUSHWRITE
;
180 OSL_TRACE("opening '%s'",pszProfileName
);
181 if ( Flags
== osl_Profile_DEFAULT
)
183 OSL_TRACE("with osl_Profile_DEFAULT");
185 if ( Flags
& osl_Profile_SYSTEM
)
187 OSL_TRACE("with osl_Profile_SYSTEM");
189 if ( Flags
& osl_Profile_READLOCK
)
191 OSL_TRACE("with osl_Profile_READLOCK");
193 if ( Flags
& osl_Profile_WRITELOCK
)
195 OSL_TRACE("with osl_Profile_WRITELOCK");
197 if ( Flags
& osl_Profile_FLUSHWRITE
)
199 OSL_TRACE("with osl_Profile_FLUSHWRITE");
204 if ( ( pFile
= openFileImpl(pszProfileName
, Flags
) ) == NULL
)
206 #ifdef TRACE_OSL_PROFILE
207 OSL_TRACE("Out osl_openProfile [not opened]");
213 pProfile
= (osl_TProfileImpl
*)calloc(1, sizeof(osl_TProfileImpl
));
217 closeFileImpl(pFile
, Flags
);
221 pProfile
->m_Flags
= Flags
& FLG_USER
;
223 if ( Flags
& ( osl_Profile_READLOCK
| osl_Profile_WRITELOCK
| osl_Profile_FLUSHWRITE
) )
225 pProfile
->m_pFile
= pFile
;
228 pthread_mutex_init(&(pProfile
->m_AccessLock
),PTHREAD_MUTEXATTR_DEFAULT
);
229 pProfile
->m_bIsValid
=sal_True
;
231 pProfile
->m_Stamp
= OslProfile_getFileStamp(pFile
);
232 bRet
=loadProfile(pFile
, pProfile
);
233 bRet
&= realpath(pszProfileName
, pProfile
->m_FileName
) != NULL
;
236 if (pProfile
->m_pFile
== NULL
)
237 closeFileImpl(pFile
,pProfile
->m_Flags
);
239 #ifdef TRACE_OSL_PROFILE
240 OSL_TRACE("Out osl_openProfile [ok]");
245 sal_Bool SAL_CALL
osl_closeProfile(oslProfile Profile
)
247 osl_TProfileImpl
* pProfile
= (osl_TProfileImpl
*)Profile
;
248 osl_TProfileImpl
* pTmpProfile
;
250 #ifdef TRACE_OSL_PROFILE
251 OSL_TRACE("In osl_closeProfile");
256 #ifdef TRACE_OSL_PROFILE
257 OSL_TRACE("Out osl_closeProfile [profile==0]");
262 pthread_mutex_lock(&(pProfile
->m_AccessLock
));
264 if ( pProfile
->m_bIsValid
== sal_False
)
266 OSL_ASSERT(pProfile
->m_bIsValid
);
267 pthread_mutex_unlock(&(pProfile
->m_AccessLock
));
268 #ifdef TRACE_OSL_PROFILE
269 OSL_TRACE("Out osl_closeProfile [not valid]");
274 pProfile
->m_bIsValid
=sal_False
;
276 if ( ! ( pProfile
->m_Flags
& osl_Profile_READLOCK
) && ( pProfile
->m_Flags
& FLG_MODIFIED
) )
278 pTmpProfile
= acquireProfile(Profile
,sal_True
);
280 if ( pTmpProfile
!= 0 )
282 sal_Bool bRet
= storeProfile(pTmpProfile
, sal_True
);
289 pTmpProfile
= acquireProfile(Profile
,sal_False
);
293 if ( pTmpProfile
== 0 )
295 pthread_mutex_unlock(&(pProfile
->m_AccessLock
));
296 #ifdef TRACE_OSL_PROFILE
297 OSL_TRACE("Out osl_closeProfile [pProfile==0]");
302 pProfile
= pTmpProfile
;
304 if (pProfile
->m_pFile
!= NULL
)
305 closeFileImpl(pProfile
->m_pFile
,pProfile
->m_Flags
);
307 pProfile
->m_pFile
= NULL
;
308 pProfile
->m_FileName
[0] = '\0';
310 /* release whole profile data types memory */
311 if ( pProfile
->m_NoLines
> 0)
314 if ( pProfile
->m_Lines
!= 0 )
316 for ( idx
= 0 ; idx
< pProfile
->m_NoLines
; ++idx
)
318 if ( pProfile
->m_Lines
[idx
] != 0 )
320 free(pProfile
->m_Lines
[idx
]);
321 pProfile
->m_Lines
[idx
]=0;
324 free(pProfile
->m_Lines
);
327 if ( pProfile
->m_Sections
!= 0 )
329 /*osl_TProfileSection* pSections=pProfile->m_Sections;*/
330 for ( idx
= 0 ; idx
< pProfile
->m_NoSections
; ++idx
)
332 if ( pProfile
->m_Sections
[idx
].m_Entries
!= 0 )
334 free(pProfile
->m_Sections
[idx
].m_Entries
);
335 pProfile
->m_Sections
[idx
].m_Entries
=0;
338 free(pProfile
->m_Sections
);
339 pProfile
->m_Sections
=0;
343 pthread_mutex_unlock(&(pProfile
->m_AccessLock
));
345 pthread_mutex_destroy(&(pProfile
->m_AccessLock
));
349 #ifdef TRACE_OSL_PROFILE
350 OSL_TRACE("Out osl_closeProfile [ok]");
356 sal_Bool SAL_CALL
osl_flushProfile(oslProfile Profile
)
358 osl_TProfileImpl
* pProfile
= (osl_TProfileImpl
*) Profile
;
360 sal_Bool bRet
= sal_False
;
362 #ifdef TRACE_OSL_PROFILE
363 OSL_TRACE("In osl_flushProfile()");
368 #ifdef TRACE_OSL_PROFILE
369 OSL_TRACE("Out osl_flushProfile() [pProfile == 0]");
374 pthread_mutex_lock(&(pProfile
->m_AccessLock
));
376 if ( pProfile
->m_bIsValid
== sal_False
)
378 OSL_ASSERT(pProfile
->m_bIsValid
);
379 pthread_mutex_unlock(&(pProfile
->m_AccessLock
));
380 #ifdef TRACE_OSL_PROFILE
381 OSL_TRACE("Out osl_flushProfile [not valid]");
386 pFile
= pProfile
->m_pFile
;
387 if ( !( pFile
!= 0 && pFile
->m_Handle
>= 0 ) )
389 pthread_mutex_unlock(&(pProfile
->m_AccessLock
));
390 #ifdef TRACE_OSL_PROFILE
391 OSL_TRACE("Out osl_flushProfile() [invalid file]");
396 if ( pProfile
->m_Flags
& FLG_MODIFIED
)
398 #ifdef DEBUG_OSL_PROFILE
399 OSL_TRACE("swapping to storeprofile");
401 bRet
= storeProfile(pProfile
,sal_False
);
405 #ifdef TRACE_OSL_PROFILE
406 OSL_TRACE("Out osl_flushProfile() [ok]");
408 pthread_mutex_unlock(&(pProfile
->m_AccessLock
));
412 static sal_Bool
writeProfileImpl(osl_TFile
* pFile
)
414 #if OSL_DEBUG_LEVEL > 1
418 #ifdef TRACE_OSL_PROFILE
419 OSL_TRACE("In osl_writeProfileImpl()");
422 if ( !( pFile
!= 0 && pFile
->m_Handle
>= 0 ) || ( pFile
->m_pWriteBuf
== 0 ) )
424 #ifdef TRACE_OSL_PROFILE
425 OSL_TRACE("Out osl_writeProfileImpl() [invalid args]");
430 #if OSL_DEBUG_LEVEL > 1
431 nLen
=strlen(pFile
->m_pWriteBuf
);
432 OSL_ASSERT(nLen
== (pFile
->m_nWriteBufLen
- pFile
->m_nWriteBufFree
));
435 if ( !safeWrite(pFile
->m_Handle
, pFile
->m_pWriteBuf
, pFile
->m_nWriteBufLen
- pFile
->m_nWriteBufFree
) )
437 OSL_TRACE("write failed '%s'",strerror(errno
));
441 free(pFile
->m_pWriteBuf
);
442 pFile
->m_pWriteBuf
=0;
443 pFile
->m_nWriteBufLen
=0;
444 pFile
->m_nWriteBufFree
=0;
445 #ifdef TRACE_OSL_PROFILE
446 OSL_TRACE("Out osl_writeProfileImpl() [ok]");
452 sal_Bool SAL_CALL
osl_readProfileString(oslProfile Profile
,
453 const sal_Char
* pszSection
, const sal_Char
* pszEntry
,
454 sal_Char
* pszString
, sal_uInt32 MaxLen
,
455 const sal_Char
* pszDefault
)
459 osl_TProfileSection
* pSec
;
460 osl_TProfileImpl
* pProfile
=0;
461 osl_TProfileImpl
* pTmpProfile
=0;
462 sal_Bool bRet
= sal_False
;
464 #ifdef TRACE_OSL_PROFILE
465 OSL_TRACE("In osl_readProfileString");
468 pTmpProfile
= (osl_TProfileImpl
*) Profile
;
470 if ( pTmpProfile
== 0 )
472 #ifdef TRACE_OSL_PROFILE
473 OSL_TRACE("Out osl_readProfileString [pTmpProfile==0]");
478 pthread_mutex_lock(&(pTmpProfile
->m_AccessLock
));
480 if ( pTmpProfile
->m_bIsValid
== sal_False
)
482 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
483 #ifdef TRACE_OSL_PROFILE
484 OSL_TRACE("Out osl_readProfileString [not valid]");
489 pProfile
= acquireProfile(Profile
, sal_False
);
491 if ( pProfile
== NULL
)
493 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
494 #ifdef TRACE_OSL_PROFILE
495 OSL_TRACE("Out osl_readProfileString [pProfile==0]");
500 if (! (pProfile
->m_Flags
& osl_Profile_SYSTEM
))
502 if (((pSec
= findEntry(pProfile
, pszSection
, pszEntry
, &NoEntry
)) != NULL
) &&
503 (NoEntry
< pSec
->m_NoEntries
) &&
504 ((pStr
= strchr(pProfile
->m_Lines
[pSec
->m_Entries
[NoEntry
].m_Line
],
511 pStr
=(sal_Char
*)pszDefault
;
516 pStr
= stripBlanks(pStr
, NULL
);
517 MaxLen
= (MaxLen
- 1 < strlen(pStr
)) ? (MaxLen
- 1) : strlen(pStr
);
518 pStr
= stripBlanks(pStr
, &MaxLen
);
519 strncpy(pszString
, pStr
, MaxLen
);
520 pszString
[MaxLen
] = '\0';
524 { /* not implemented */ }
527 bRet
=releaseProfile(pProfile
);
533 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
534 #ifdef TRACE_OSL_PROFILE
535 OSL_TRACE("Out osl_readProfileString [pStr==0]");
540 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
542 #ifdef TRACE_OSL_PROFILE
543 OSL_TRACE("Out osl_readProfileString [ok]");
550 sal_Bool SAL_CALL
osl_readProfileBool(oslProfile Profile
,
551 const sal_Char
* pszSection
, const sal_Char
* pszEntry
,
557 #ifdef TRACE_OSL_PROFILE
558 OSL_TRACE("In osl_readProfileBool");
561 if (osl_readProfileString(Profile
, pszSection
, pszEntry
, Line
, sizeof(Line
), ""))
563 if ((strcasecmp(Line
, STR_INI_BOOLYES
) == 0) ||
564 (strcasecmp(Line
, STR_INI_BOOLON
) == 0) ||
565 (strcasecmp(Line
, STR_INI_BOOLONE
) == 0))
568 if ((strcasecmp(Line
, STR_INI_BOOLNO
) == 0) ||
569 (strcasecmp(Line
, STR_INI_BOOLOFF
) == 0) ||
570 (strcasecmp(Line
, STR_INI_BOOLZERO
) == 0))
574 #ifdef TRACE_OSL_PROFILE
575 OSL_TRACE("Out osl_readProfileBool [ok]");
582 sal_uInt32 SAL_CALL
osl_readProfileIdent(oslProfile Profile
,
583 const sal_Char
* pszSection
, const sal_Char
* pszEntry
,
584 sal_uInt32 FirstId
, const sal_Char
* Strings
[],
591 #ifdef TRACE_OSL_PROFILE
592 OSL_TRACE("In osl_readProfileIdent");
595 if (osl_readProfileString(Profile
, pszSection
, pszEntry
, Line
, sizeof(Line
), ""))
598 while (Strings
[i
] != NULL
)
600 if (strcasecmp(Line
, Strings
[i
]) == 0)
602 Default
= i
+ FirstId
;
609 #ifdef TRACE_OSL_PROFILE
610 OSL_TRACE("Out osl_readProfileIdent [ok]");
615 sal_Bool SAL_CALL
osl_writeProfileString(oslProfile Profile
,
616 const sal_Char
* pszSection
, const sal_Char
* pszEntry
,
617 const sal_Char
* pszString
)
620 sal_Bool bRet
= sal_False
;
624 osl_TProfileSection
* pSec
;
625 osl_TProfileImpl
* pProfile
= 0;
626 osl_TProfileImpl
* pTmpProfile
= 0;
628 #ifdef TRACE_OSL_PROFILE
629 OSL_TRACE("In osl_writeProfileString");
632 pTmpProfile
= (osl_TProfileImpl
*) Profile
;
634 if ( pTmpProfile
== 0 )
636 #ifdef TRACE_OSL_PROFILE
637 OSL_TRACE("Out osl_writeProfileString [pTmpProfile==0]");
642 pthread_mutex_lock(&(pTmpProfile
->m_AccessLock
));
644 if ( pTmpProfile
->m_bIsValid
== sal_False
)
646 OSL_ASSERT(pTmpProfile
->m_bIsValid
);
647 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
648 #ifdef TRACE_OSL_PROFILE
649 OSL_TRACE("Out osl_writeProfileString [not valid]");
654 pProfile
=acquireProfile(Profile
, sal_True
);
656 if (pProfile
== NULL
)
658 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
659 #ifdef TRACE_OSL_PROFILE
660 OSL_TRACE("Out osl_writeProfileString [pProfile==0]");
665 Line
= (sal_Char
*) malloc(strlen(pszEntry
)+strlen(pszString
)+48);
667 if (! (pProfile
->m_Flags
& osl_Profile_SYSTEM
))
669 if ((pSec
= findEntry(pProfile
, pszSection
, pszEntry
, &NoEntry
)) == NULL
)
672 addLine(pProfile
, Line
);
675 strcpy(&Line
[1], pszSection
);
676 Line
[1 + strlen(pszSection
)] = ']';
677 Line
[2 + strlen(pszSection
)] = '\0';
679 if (((pStr
= addLine(pProfile
, Line
)) == NULL
) ||
680 (! addSection(pProfile
, pProfile
->m_NoLines
- 1, &pStr
[1], strlen(pszSection
))))
682 bRet
=releaseProfile(pProfile
);
685 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
689 #ifdef TRACE_OSL_PROFILE
690 OSL_TRACE("Out osl_writeProfileString [not added]");
695 pSec
= &pProfile
->m_Sections
[pProfile
->m_NoSections
- 1];
696 NoEntry
= pSec
->m_NoEntries
;
700 strcpy(&Line
[0], pszEntry
);
701 Line
[0 + strlen(pszEntry
)] = '=';
702 strcpy(&Line
[1 + strlen(pszEntry
)], pszString
);
704 if (NoEntry
>= pSec
->m_NoEntries
)
706 if (pSec
->m_NoEntries
> 0)
707 i
= pSec
->m_Entries
[pSec
->m_NoEntries
- 1].m_Line
+ 1;
709 i
= pSec
->m_Line
+ 1;
711 if (((pStr
= insertLine(pProfile
, Line
, i
)) == NULL
) ||
712 (! addEntry(pProfile
, pSec
, i
, pStr
, strlen(pszEntry
))))
714 bRet
=releaseProfile(pProfile
);
717 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
720 #ifdef TRACE_OSL_PROFILE
721 OSL_TRACE("Out osl_writeProfileString [not inserted]");
726 pProfile
->m_Flags
|= FLG_MODIFIED
;
730 i
= pSec
->m_Entries
[NoEntry
].m_Line
;
731 free(pProfile
->m_Lines
[i
]);
732 pProfile
->m_Lines
[i
] = strdup(Line
);
733 setEntry(pProfile
, pSec
, NoEntry
, i
, pProfile
->m_Lines
[i
], strlen(pszEntry
));
735 pProfile
->m_Flags
|= FLG_MODIFIED
;
739 /* not implemented */
742 bRet
= releaseProfile(pProfile
);
745 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
751 #ifdef TRACE_OSL_PROFILE
752 OSL_TRACE("Out osl_writeProfileString [ok]");
759 sal_Bool SAL_CALL
osl_writeProfileBool(oslProfile Profile
,
760 const sal_Char
* pszSection
, const sal_Char
* pszEntry
,
763 sal_Bool bRet
=sal_False
;
765 #ifdef TRACE_OSL_PROFILE
766 OSL_TRACE("In osl_writeProfileBool");
770 bRet
=osl_writeProfileString(Profile
, pszSection
, pszEntry
, STR_INI_BOOLONE
);
772 bRet
=osl_writeProfileString(Profile
, pszSection
, pszEntry
, STR_INI_BOOLZERO
);
774 #ifdef TRACE_OSL_PROFILE
775 OSL_TRACE("Out osl_writeProfileBool [ok]");
782 sal_Bool SAL_CALL
osl_writeProfileIdent(oslProfile Profile
,
783 const sal_Char
* pszSection
, const sal_Char
* pszEntry
,
784 sal_uInt32 FirstId
, const sal_Char
* Strings
[],
788 sal_Bool bRet
=sal_False
;
790 #ifdef TRACE_OSL_PROFILE
791 OSL_TRACE("In osl_writeProfileIdent");
794 while (Strings
[n
] != NULL
)
797 if ((i
= Value
- FirstId
) >= n
)
800 bRet
= osl_writeProfileString(Profile
, pszSection
, pszEntry
, Strings
[i
]);
802 #ifdef TRACE_OSL_PROFILE
803 OSL_TRACE("Out osl_writeProfileIdent");
809 sal_Bool SAL_CALL
osl_removeProfileEntry(oslProfile Profile
,
810 const sal_Char
*pszSection
, const sal_Char
*pszEntry
)
813 osl_TProfileSection
* pSec
;
814 osl_TProfileImpl
* pProfile
= 0;
815 osl_TProfileImpl
* pTmpProfile
= 0;
816 sal_Bool bRet
= sal_False
;
818 #ifdef TRACE_OSL_PROFILE
819 OSL_TRACE("In osl_removeProfileEntry");
822 pTmpProfile
= (osl_TProfileImpl
*) Profile
;
824 if ( pTmpProfile
== 0 )
826 #ifdef TRACE_OSL_PROFILE
827 OSL_TRACE("Out osl_removeProfileEntry [pProfile==0]");
832 pthread_mutex_lock(&(pTmpProfile
->m_AccessLock
));
834 if ( pTmpProfile
->m_bIsValid
== sal_False
)
836 OSL_ASSERT(pTmpProfile
->m_bIsValid
);
837 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
838 #ifdef TRACE_OSL_PROFILE
839 OSL_TRACE("Out osl_removeProfileEntry [not valid]");
845 pProfile
= acquireProfile(Profile
, sal_True
);
847 if (pProfile
== NULL
)
849 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
850 #ifdef TRACE_OSL_PROFILE
851 OSL_TRACE("Out osl_removeProfileEntry [pProfile==0]");
857 if (! (pProfile
->m_Flags
& osl_Profile_SYSTEM
))
859 if (((pSec
= findEntry(pProfile
, pszSection
, pszEntry
, &NoEntry
)) != NULL
) &&
860 (NoEntry
< pSec
->m_NoEntries
))
862 removeLine(pProfile
, pSec
->m_Entries
[NoEntry
].m_Line
);
863 removeEntry(pSec
, NoEntry
);
864 if (pSec
->m_NoEntries
== 0)
866 removeLine(pProfile
, pSec
->m_Line
);
868 /* remove any empty separation line */
869 if ((pSec
->m_Line
> 0) && (pProfile
->m_Lines
[pSec
->m_Line
- 1][0] == '\0'))
870 removeLine(pProfile
, pSec
->m_Line
- 1);
872 removeSection(pProfile
, pSec
);
875 pProfile
->m_Flags
|= FLG_MODIFIED
;
879 { /* not implemented */ }
882 bRet
= releaseProfile(pProfile
);
885 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
887 #ifdef TRACE_OSL_PROFILE
888 OSL_TRACE("Out osl_removeProfileEntry [ok]");
894 sal_uInt32 SAL_CALL
osl_getProfileSectionEntries(oslProfile Profile
, const sal_Char
*pszSection
,
895 sal_Char
* pszBuffer
, sal_uInt32 MaxLen
)
899 osl_TProfileSection
* pSec
;
900 osl_TProfileImpl
* pProfile
= 0;
901 osl_TProfileImpl
* pTmpProfile
= 0;
902 sal_Bool bRet
= sal_False
;
904 #ifdef TRACE_OSL_PROFILE
905 OSL_TRACE("In osl_getProfileSectionEntries");
908 pTmpProfile
= (osl_TProfileImpl
*) Profile
;
910 if ( pTmpProfile
== 0 )
912 #ifdef TRACE_OSL_PROFILE
913 OSL_TRACE("Out osl_getProfileSectionEntries [pTmpProfile==0]");
919 pthread_mutex_lock(&(pTmpProfile
->m_AccessLock
));
921 if ( pTmpProfile
->m_bIsValid
== sal_False
)
923 OSL_ASSERT(pTmpProfile
->m_bIsValid
);
925 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
927 #ifdef TRACE_OSL_PROFILE
928 OSL_TRACE("Out osl_getProfileSectionEntries [not valid]");
934 pProfile
= acquireProfile(Profile
, sal_False
);
936 if (pProfile
== NULL
)
938 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
940 #ifdef TRACE_OSL_PROFILE
941 OSL_TRACE("Out osl_getProfileSectionEntries [pProfile=0]");
948 if (! (pProfile
->m_Flags
& osl_Profile_SYSTEM
))
950 if ((pSec
= findEntry(pProfile
, pszSection
, "", &NoEntry
)) != NULL
)
954 for (i
= 0; i
< pSec
->m_NoEntries
; i
++)
956 if ((n
+ pSec
->m_Entries
[i
].m_Len
+ 1) < MaxLen
)
958 strncpy(&pszBuffer
[n
], &pProfile
->m_Lines
[pSec
->m_Entries
[i
].m_Line
]
959 [pSec
->m_Entries
[i
].m_Offset
], pSec
->m_Entries
[i
].m_Len
);
960 n
+= pSec
->m_Entries
[i
].m_Len
;
961 pszBuffer
[n
++] = '\0';
968 pszBuffer
[n
++] = '\0';
972 for (i
= 0; i
< pSec
->m_NoEntries
; i
++)
973 n
+= pSec
->m_Entries
[i
].m_Len
+ 1;
982 /* not implemented */
985 bRet
=releaseProfile(pProfile
);
989 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
991 #ifdef TRACE_OSL_PROFILE
992 OSL_TRACE("Out osl_getProfileSectionEntries [ok]");
998 sal_uInt32 SAL_CALL
osl_getProfileSections(oslProfile Profile
, sal_Char
* pszBuffer
, sal_uInt32 MaxLen
)
1000 sal_uInt32 i
, n
= 0;
1001 osl_TProfileSection
* pSec
;
1002 osl_TProfileImpl
* pProfile
= 0;
1003 osl_TProfileImpl
* pTmpProfile
= 0;
1004 sal_Bool bRet
= sal_False
;
1006 #ifdef TRACE_OSL_PROFILE
1007 OSL_TRACE("In osl_getProfileSections");
1010 pTmpProfile
= (osl_TProfileImpl
*) Profile
;
1012 if ( pTmpProfile
== 0 )
1014 #ifdef TRACE_OSL_PROFILE
1015 OSL_TRACE("Out osl_getProfileSections [pTmpProfile==0]");
1020 pthread_mutex_lock(&(pTmpProfile
->m_AccessLock
));
1022 if ( pTmpProfile
->m_bIsValid
== sal_False
)
1024 OSL_ASSERT(pTmpProfile
->m_bIsValid
);
1025 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
1026 #ifdef TRACE_OSL_PROFILE
1027 OSL_TRACE("Out osl_getProfileSections [not valid]");
1032 pProfile
= acquireProfile(Profile
, sal_False
);
1034 if (pProfile
== NULL
)
1036 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
1038 #ifdef TRACE_OSL_PROFILE
1039 OSL_TRACE("Out osl_getProfileSections [pProfile==0]");
1044 if (! (pProfile
->m_Flags
& osl_Profile_SYSTEM
))
1048 for (i
= 0; i
< pProfile
->m_NoSections
; i
++)
1050 pSec
= &pProfile
->m_Sections
[i
];
1052 if ((n
+ pSec
->m_Len
+ 1) < MaxLen
)
1054 strncpy(&pszBuffer
[n
], &pProfile
->m_Lines
[pSec
->m_Line
][pSec
->m_Offset
],
1057 pszBuffer
[n
++] = '\0';
1063 pszBuffer
[n
++] = '\0';
1067 for (i
= 0; i
< pProfile
->m_NoSections
; i
++)
1068 n
+= pProfile
->m_Sections
[i
].m_Len
+ 1;
1074 { /* not implemented */ }
1077 bRet
=releaseProfile(pProfile
);
1081 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
1083 #ifdef TRACE_OSL_PROFILE
1084 OSL_TRACE("Out osl_getProfileSections [ok]");
1090 /*****************************************************************************/
1091 /* Static Module Functions */
1092 /*****************************************************************************/
1094 static osl_TStamp
OslProfile_getFileStamp(osl_TFile
* pFile
)
1098 if ( (pFile
->m_Handle
< 0) || (fstat(pFile
->m_Handle
, &status
) < 0) )
1104 return (status
.st_mtime
);
1107 static sal_Bool
OslProfile_lockFile(const osl_TFile
* pFile
, osl_TLockMode eMode
)
1110 /* boring hack, but initializers for static vars must be constant */
1111 static sal_Bool bIsInitialized
= sal_False
;
1112 static sal_Bool bLockingDisabled
;
1114 #ifdef TRACE_OSL_PROFILE
1115 OSL_TRACE("In OslProfile_lockFile");
1118 if ( !bIsInitialized
)
1120 sal_Char
* pEnvValue
;
1121 pEnvValue
= getenv( "STAR_PROFILE_LOCKING_DISABLED" );
1123 if ( pEnvValue
== 0 )
1125 bLockingDisabled
= sal_False
;
1130 bLockingDisabled
= sal_True
;
1133 bIsInitialized
= sal_True
;
1136 if (pFile
->m_Handle
< 0)
1138 #ifdef TRACE_OSL_PROFILE
1139 OSL_TRACE("Out OslProfile_lockFile [invalid file handle]");
1145 if ( bLockingDisabled
)
1147 #ifdef TRACE_OSL_PROFILE
1148 OSL_TRACE("Out OslProfile_lockFile [locking disabled]");
1155 lock
.l_whence
= SEEK_SET
;
1161 lock
.l_type
= F_UNLCK
;
1165 lock
.l_type
= F_RDLCK
;
1169 lock
.l_type
= F_WRLCK
;
1173 #ifndef MACOSX // not MAC OSX
1174 if ( fcntl(pFile
->m_Handle
, F_SETLKW
, &lock
) == -1 )
1176 /* Mac OSX will return ENOTSUP for webdav drives so we should ignore it */
1177 if ( fcntl(pFile
->m_Handle
, F_SETLKW
, &lock
) == -1 && errno
!= ENOTSUP
)
1180 OSL_TRACE("fcntl returned -1 (%s)",strerror(errno
));
1181 #ifdef TRACE_OSL_PROFILE
1182 OSL_TRACE("Out OslProfile_lockFile [fcntl F_SETLKW]");
1187 #ifdef TRACE_OSL_PROFILE
1188 OSL_TRACE("Out OslProfile_lockFile [ok]");
1193 static osl_TFile
* openFileImpl(const sal_Char
* pszFilename
, oslProfileOption ProfileFlags
)
1196 osl_TFile
* pFile
= (osl_TFile
*) calloc(1, sizeof(osl_TFile
));
1197 sal_Bool bWriteable
= sal_False
;
1199 if ( ProfileFlags
& ( osl_Profile_WRITELOCK
| osl_Profile_FLUSHWRITE
) )
1201 #ifdef DEBUG_OSL_PROFILE
1202 OSL_TRACE("setting bWriteable to TRUE");
1204 bWriteable
=sal_True
;
1209 #ifdef DEBUG_OSL_PROFILE
1210 OSL_TRACE("opening '%s' read only",pszFilename
);
1213 pFile
->m_Handle
= open(pszFilename
, O_RDONLY
);
1214 /* mfe: argghh!!! do not check if the file could be openend */
1215 /* default mode expects it that way!!! */
1219 #ifdef DEBUG_OSL_PROFILE
1220 OSL_TRACE("opening '%s' read/write",pszFilename
);
1222 if (((pFile
->m_Handle
= open(pszFilename
, O_RDWR
| O_CREAT
| O_EXCL
, DEFAULT_PMODE
)) < 0) &&
1223 ((pFile
->m_Handle
= open(pszFilename
, O_RDWR
)) < 0))
1226 #ifdef TRACE_OSL_PROFILE
1227 OSL_TRACE("Out openFileImpl [open read/write]");
1233 /* set close-on-exec flag */
1234 if ((Flags
= fcntl(pFile
->m_Handle
, F_GETFD
, 0)) != -1)
1236 Flags
|= FD_CLOEXEC
;
1237 fcntl(pFile
->m_Handle
, F_SETFD
, Flags
);
1240 pFile
->m_pWriteBuf
=0;
1241 pFile
->m_nWriteBufFree
=0;
1242 pFile
->m_nWriteBufLen
=0;
1244 if ( ProfileFlags
& (osl_Profile_WRITELOCK
| osl_Profile_READLOCK
) )
1246 #ifdef DEBUG_OSL_PROFILE
1247 OSL_TRACE("locking '%s' file",pszFilename
);
1249 OslProfile_lockFile(pFile
, bWriteable
? write_lock
: read_lock
);
1252 #ifdef TRACE_OSL_PROFILE
1253 OSL_TRACE("Out openFileImpl [ok]");
1258 static osl_TStamp
closeFileImpl(osl_TFile
* pFile
, oslProfileOption Flags
)
1260 osl_TStamp stamp
= 0;
1262 #ifdef TRACE_OSL_PROFILE
1263 OSL_TRACE("In closeFileImpl");
1268 #ifdef TRACE_OSL_PROFILE
1269 OSL_TRACE("Out closeFileImpl [pFile == 0]");
1274 if ( pFile
->m_Handle
>= 0 )
1276 stamp
= OslProfile_getFileStamp(pFile
);
1278 if ( Flags
& (osl_Profile_WRITELOCK
| osl_Profile_READLOCK
) )
1280 OslProfile_lockFile(pFile
, un_lock
);
1283 close(pFile
->m_Handle
);
1284 pFile
->m_Handle
= -1;
1288 if ( pFile
->m_pWriteBuf
)
1290 free(pFile
->m_pWriteBuf
);
1295 #ifdef TRACE_OSL_PROFILE
1296 OSL_TRACE("Out closeFileImpl [ok]");
1302 static sal_Bool
OslProfile_rewindFile(osl_TFile
* pFile
, sal_Bool bTruncate
)
1304 sal_Bool bRet
= sal_True
;
1305 #ifdef TRACE_OSL_PROFILE
1306 OSL_TRACE("In osl_OslProfile_rewindFile");
1309 if (pFile
->m_Handle
>= 0)
1311 pFile
->m_pReadPtr
= pFile
->m_ReadBuf
+ sizeof(pFile
->m_ReadBuf
);
1313 #ifdef DEBUG_OSL_PROFILE
1314 OSL_TRACE("rewinding");
1316 bRet
= (lseek(pFile
->m_Handle
, SEEK_SET
, 0L) == 0L);
1320 #ifdef DEBUG_OSL_PROFILE
1321 OSL_TRACE("truncating");
1323 bRet
&= (ftruncate(pFile
->m_Handle
, 0L) == 0);
1328 #ifdef TRACE_OSL_PROFILE
1329 OSL_TRACE("Out osl_OslProfile_rewindFile [ok]");
1335 static sal_Char
* OslProfile_getLine(osl_TFile
* pFile
)
1337 int Max
, Free
, Bytes
, nLineBytes
= 0;
1339 sal_Char
* pLine
= NULL
;
1347 if (pFile
->m_Handle
< 0)
1352 Bytes
= sizeof(pFile
->m_ReadBuf
) - (pFile
->m_pReadPtr
- pFile
->m_ReadBuf
);
1357 memcpy(pFile
->m_ReadBuf
, pFile
->m_pReadPtr
, Bytes
);
1358 pFile
->m_pReadPtr
= pFile
->m_ReadBuf
;
1360 Free
= sizeof(pFile
->m_ReadBuf
) - Bytes
;
1362 if ((Max
= read(pFile
->m_Handle
, &pFile
->m_ReadBuf
[Bytes
], Free
)) < 0)
1364 OSL_TRACE("read failed '%s'",strerror(errno
));
1367 rtl_freeMemory( pLine
);
1374 if ((Max
== 0) && ! pLine
)
1377 pFile
->m_ReadBuf
[Bytes
+ Max
] = '\0';
1381 for (pChr
= pFile
->m_pReadPtr
;
1382 (*pChr
!= '\n') && (*pChr
!= '\r') && (*pChr
!= '\0') &&
1383 (pChr
< (pFile
->m_ReadBuf
+ sizeof(pFile
->m_ReadBuf
) - 1));
1386 Max
= pChr
- pFile
->m_pReadPtr
;
1387 pNewLine
= (sal_Char
*) rtl_allocateMemory( nLineBytes
+ Max
+ 1 );
1390 memcpy( pNewLine
, pLine
, nLineBytes
);
1391 rtl_freeMemory( pLine
);
1393 memcpy(pNewLine
+nLineBytes
, pFile
->m_pReadPtr
, Max
);
1395 pNewLine
[ nLineBytes
] = 0;
1398 if (pChr
< (pFile
->m_ReadBuf
+ sizeof(pFile
->m_ReadBuf
) - 1))
1402 if ((pChr
[0] == '\r') && (pChr
[1] == '\n'))
1408 if ((pChr
< (pFile
->m_ReadBuf
+ sizeof(pFile
->m_ReadBuf
))) &&
1410 pChr
= pFile
->m_ReadBuf
+ sizeof(pFile
->m_ReadBuf
);
1412 /* setting Max to -1 indicates terminating read loop */
1416 pFile
->m_pReadPtr
= pChr
;
1423 static sal_Bool
OslProfile_putLine(osl_TFile
* pFile
, const sal_Char
*pszLine
)
1425 unsigned int Len
= strlen(pszLine
);
1427 #ifdef DEBUG_OSL_PROFILE
1431 if ( pFile
== 0 || pFile
->m_Handle
< 0 )
1436 if ( pFile
->m_pWriteBuf
== 0 )
1438 pFile
->m_pWriteBuf
= (sal_Char
*) malloc(Len
+3);
1439 pFile
->m_nWriteBufLen
= Len
+3;
1440 pFile
->m_nWriteBufFree
= Len
+3;
1444 if ( pFile
->m_nWriteBufFree
<= Len
+ 3 )
1448 pTmp
=(sal_Char
*) realloc(pFile
->m_pWriteBuf
,( ( pFile
->m_nWriteBufLen
+ Len
) * 2) );
1453 pFile
->m_pWriteBuf
= pTmp
;
1454 pFile
->m_nWriteBufFree
= pFile
->m_nWriteBufFree
+ pFile
->m_nWriteBufLen
+ ( 2 * Len
);
1455 pFile
->m_nWriteBufLen
= ( pFile
->m_nWriteBufLen
+ Len
) * 2;
1456 memset( (pFile
->m_pWriteBuf
) + ( pFile
->m_nWriteBufLen
- pFile
->m_nWriteBufFree
), 0, pFile
->m_nWriteBufFree
);
1462 memcpy(pFile
->m_pWriteBuf
+ ( pFile
->m_nWriteBufLen
- pFile
->m_nWriteBufFree
),pszLine
,Len
+1);
1463 #ifdef DEBUG_OSL_PROFILE
1464 strLen
= strlen(pFile
->m_pWriteBuf
);
1466 pFile
->m_pWriteBuf
[pFile
->m_nWriteBufLen
- pFile
->m_nWriteBufFree
+ Len
]='\n';
1467 pFile
->m_pWriteBuf
[pFile
->m_nWriteBufLen
- pFile
->m_nWriteBufFree
+ Len
+ 1]='\0';
1469 pFile
->m_nWriteBufFree
-=Len
+1;
1474 /* platform specific end */
1476 static sal_Char
* stripBlanks(sal_Char
* String
, sal_uInt32
* pLen
)
1478 if ( ( pLen
!= NULL
) && ( *pLen
!= 0 ) )
1480 while ((String
[*pLen
- 1] == ' ') || (String
[*pLen
- 1] == '\t'))
1483 while ( (*String
== ' ') || (*String
== '\t') )
1490 while ( (*String
== ' ') || (*String
== '\t') )
1496 static sal_Char
* addLine(osl_TProfileImpl
* pProfile
, const sal_Char
* Line
)
1498 if (pProfile
->m_NoLines
>= pProfile
->m_MaxLines
)
1500 if (pProfile
->m_Lines
== NULL
)
1502 pProfile
->m_MaxLines
= LINES_INI
;
1503 pProfile
->m_Lines
= (sal_Char
**)malloc(pProfile
->m_MaxLines
* sizeof(sal_Char
*));
1504 memset(pProfile
->m_Lines
,0,pProfile
->m_MaxLines
* sizeof(sal_Char
*));
1509 unsigned int oldmax
=pProfile
->m_MaxLines
;
1511 pProfile
->m_MaxLines
+= LINES_ADD
;
1512 pProfile
->m_Lines
= (sal_Char
**)realloc(pProfile
->m_Lines
,
1513 pProfile
->m_MaxLines
* sizeof(sal_Char
*));
1514 for ( idx
= oldmax
; idx
< pProfile
->m_MaxLines
; ++idx
)
1516 pProfile
->m_Lines
[idx
]=0;
1520 if (pProfile
->m_Lines
== NULL
)
1522 pProfile
->m_NoLines
= 0;
1523 pProfile
->m_MaxLines
= 0;
1529 if ( pProfile
->m_Lines
!= 0 && pProfile
->m_Lines
[pProfile
->m_NoLines
] != 0 )
1531 free(pProfile
->m_Lines
[pProfile
->m_NoLines
]);
1533 pProfile
->m_Lines
[pProfile
->m_NoLines
++] = strdup(Line
);
1535 return (pProfile
->m_Lines
[pProfile
->m_NoLines
- 1]);
1538 static sal_Char
* insertLine(osl_TProfileImpl
* pProfile
, const sal_Char
* Line
, sal_uInt32 LineNo
)
1540 if (pProfile
->m_NoLines
>= pProfile
->m_MaxLines
)
1542 if (pProfile
->m_Lines
== NULL
)
1544 pProfile
->m_MaxLines
= LINES_INI
;
1545 pProfile
->m_Lines
= (sal_Char
**)malloc(pProfile
->m_MaxLines
* sizeof(sal_Char
*));
1546 memset(pProfile
->m_Lines
,0,pProfile
->m_MaxLines
* sizeof(sal_Char
*));
1550 pProfile
->m_MaxLines
+= LINES_ADD
;
1551 pProfile
->m_Lines
= (sal_Char
**)realloc(pProfile
->m_Lines
,
1552 pProfile
->m_MaxLines
* sizeof(sal_Char
*));
1554 memset(&pProfile
->m_Lines
[pProfile
->m_NoLines
],
1556 (pProfile
->m_MaxLines
- pProfile
->m_NoLines
- 1) * sizeof(sal_Char
*));
1559 if (pProfile
->m_Lines
== NULL
)
1561 pProfile
->m_NoLines
= 0;
1562 pProfile
->m_MaxLines
= 0;
1567 LineNo
= LineNo
> pProfile
->m_NoLines
? pProfile
->m_NoLines
: LineNo
;
1569 if (LineNo
< pProfile
->m_NoLines
)
1572 osl_TProfileSection
* pSec
;
1574 memmove(&pProfile
->m_Lines
[LineNo
+ 1], &pProfile
->m_Lines
[LineNo
],
1575 (pProfile
->m_NoLines
- LineNo
) * sizeof(sal_Char
*));
1578 /* adjust line references */
1579 for (i
= 0; i
< pProfile
->m_NoSections
; i
++)
1581 pSec
= &pProfile
->m_Sections
[i
];
1583 if (pSec
->m_Line
>= LineNo
)
1586 for (n
= 0; n
< pSec
->m_NoEntries
; n
++)
1587 if (pSec
->m_Entries
[n
].m_Line
>= LineNo
)
1588 pSec
->m_Entries
[n
].m_Line
++;
1592 pProfile
->m_NoLines
++;
1594 pProfile
->m_Lines
[LineNo
] = strdup(Line
);
1596 return (pProfile
->m_Lines
[LineNo
]);
1599 static void removeLine(osl_TProfileImpl
* pProfile
, sal_uInt32 LineNo
)
1601 if (LineNo
< pProfile
->m_NoLines
)
1603 free(pProfile
->m_Lines
[LineNo
]);
1604 pProfile
->m_Lines
[LineNo
]=0;
1605 if (pProfile
->m_NoLines
- LineNo
> 1)
1608 osl_TProfileSection
* pSec
;
1610 memmove(&pProfile
->m_Lines
[LineNo
], &pProfile
->m_Lines
[LineNo
+ 1],
1611 (pProfile
->m_NoLines
- LineNo
- 1) * sizeof(sal_Char
*));
1613 memset(&pProfile
->m_Lines
[pProfile
->m_NoLines
- 1],
1615 (pProfile
->m_MaxLines
- pProfile
->m_NoLines
) * sizeof(sal_Char
*));
1617 /* adjust line references */
1618 for (i
= 0; i
< pProfile
->m_NoSections
; i
++)
1620 pSec
= &pProfile
->m_Sections
[i
];
1622 if (pSec
->m_Line
> LineNo
)
1625 for (n
= 0; n
< pSec
->m_NoEntries
; n
++)
1626 if (pSec
->m_Entries
[n
].m_Line
> LineNo
)
1627 pSec
->m_Entries
[n
].m_Line
--;
1632 pProfile
->m_Lines
[LineNo
] = 0;
1635 pProfile
->m_NoLines
--;
1641 static void setEntry(osl_TProfileImpl
* pProfile
, osl_TProfileSection
* pSection
,
1642 sal_uInt32 NoEntry
, sal_uInt32 Line
,
1643 sal_Char
* Entry
, sal_uInt32 Len
)
1645 Entry
= stripBlanks(Entry
, &Len
);
1646 pSection
->m_Entries
[NoEntry
].m_Line
= Line
;
1647 pSection
->m_Entries
[NoEntry
].m_Offset
= Entry
- pProfile
->m_Lines
[Line
];
1648 pSection
->m_Entries
[NoEntry
].m_Len
= Len
;
1653 static sal_Bool
addEntry(osl_TProfileImpl
* pProfile
, osl_TProfileSection
*pSection
,
1654 int Line
, sal_Char
* Entry
, sal_uInt32 Len
)
1656 if (pSection
!= NULL
)
1658 if (pSection
->m_NoEntries
>= pSection
->m_MaxEntries
)
1660 if (pSection
->m_Entries
== NULL
)
1662 pSection
->m_MaxEntries
= ENTRIES_INI
;
1663 pSection
->m_Entries
= (osl_TProfileEntry
*)malloc(
1664 pSection
->m_MaxEntries
* sizeof(osl_TProfileEntry
));
1668 pSection
->m_MaxEntries
+= ENTRIES_ADD
;
1669 pSection
->m_Entries
= (osl_TProfileEntry
*)realloc(pSection
->m_Entries
,
1670 pSection
->m_MaxEntries
* sizeof(osl_TProfileEntry
));
1673 if (pSection
->m_Entries
== NULL
)
1675 pSection
->m_NoEntries
= 0;
1676 pSection
->m_MaxEntries
= 0;
1681 pSection
->m_NoEntries
++;
1683 Entry
= stripBlanks(Entry
, &Len
);
1684 setEntry(pProfile
, pSection
, pSection
->m_NoEntries
- 1, Line
,
1693 static void removeEntry(osl_TProfileSection
*pSection
, sal_uInt32 NoEntry
)
1695 if (NoEntry
< pSection
->m_NoEntries
)
1697 if (pSection
->m_NoEntries
- NoEntry
> 1)
1699 memmove(&pSection
->m_Entries
[NoEntry
],
1700 &pSection
->m_Entries
[NoEntry
+ 1],
1701 (pSection
->m_NoEntries
- NoEntry
- 1) * sizeof(osl_TProfileEntry
));
1702 pSection
->m_Entries
[pSection
->m_NoEntries
- 1].m_Line
=0;
1703 pSection
->m_Entries
[pSection
->m_NoEntries
- 1].m_Offset
=0;
1704 pSection
->m_Entries
[pSection
->m_NoEntries
- 1].m_Len
=0;
1707 pSection
->m_NoEntries
--;
1713 static sal_Bool
addSection(osl_TProfileImpl
* pProfile
, int Line
, const sal_Char
* Section
, sal_uInt32 Len
)
1715 if (pProfile
->m_NoSections
>= pProfile
->m_MaxSections
)
1717 if (pProfile
->m_Sections
== NULL
)
1719 pProfile
->m_MaxSections
= SECTIONS_INI
;
1720 pProfile
->m_Sections
= (osl_TProfileSection
*)malloc(pProfile
->m_MaxSections
* sizeof(osl_TProfileSection
));
1721 memset(pProfile
->m_Sections
,0,pProfile
->m_MaxSections
* sizeof(osl_TProfileSection
));
1726 unsigned int oldmax
=pProfile
->m_MaxSections
;
1728 pProfile
->m_MaxSections
+= SECTIONS_ADD
;
1729 pProfile
->m_Sections
= (osl_TProfileSection
*)realloc(pProfile
->m_Sections
,
1730 pProfile
->m_MaxSections
* sizeof(osl_TProfileSection
));
1731 for ( idx
= oldmax
; idx
< pProfile
->m_MaxSections
; ++idx
)
1733 pProfile
->m_Sections
[idx
].m_Entries
=0;
1737 if (pProfile
->m_Sections
== NULL
)
1739 pProfile
->m_NoSections
= 0;
1740 pProfile
->m_MaxSections
= 0;
1745 pProfile
->m_NoSections
++;
1747 if ( pProfile
->m_Sections
[(pProfile
->m_NoSections
) - 1].m_Entries
!= 0 )
1749 free(pProfile
->m_Sections
[(pProfile
->m_NoSections
) - 1].m_Entries
);
1751 pProfile
->m_Sections
[pProfile
->m_NoSections
- 1].m_Entries
= NULL
;
1752 pProfile
->m_Sections
[pProfile
->m_NoSections
- 1].m_NoEntries
= 0;
1753 pProfile
->m_Sections
[pProfile
->m_NoSections
- 1].m_MaxEntries
= 0;
1755 pProfile
->m_Sections
[pProfile
->m_NoSections
- 1].m_Line
= Line
;
1756 pProfile
->m_Sections
[pProfile
->m_NoSections
- 1].m_Offset
= Section
- pProfile
->m_Lines
[Line
];
1757 pProfile
->m_Sections
[pProfile
->m_NoSections
- 1].m_Len
= Len
;
1762 static void removeSection(osl_TProfileImpl
* pProfile
, osl_TProfileSection
*pSection
)
1766 if ((Section
= pSection
- pProfile
->m_Sections
) < pProfile
->m_NoSections
)
1768 free (pSection
->m_Entries
);
1769 pSection
->m_Entries
=0;
1770 if (pProfile
->m_NoSections
- Section
> 1)
1772 memmove(&pProfile
->m_Sections
[Section
], &pProfile
->m_Sections
[Section
+ 1],
1773 (pProfile
->m_NoSections
- Section
- 1) * sizeof(osl_TProfileSection
));
1775 memset(&pProfile
->m_Sections
[pProfile
->m_NoSections
- 1],
1777 (pProfile
->m_MaxSections
- pProfile
->m_NoSections
) * sizeof(osl_TProfileSection
));
1778 pProfile
->m_Sections
[pProfile
->m_NoSections
- 1].m_Entries
= 0;
1782 pSection
->m_Entries
= 0;
1785 pProfile
->m_NoSections
--;
1791 static osl_TProfileSection
* findEntry(osl_TProfileImpl
* pProfile
, const sal_Char
* Section
,
1792 const sal_Char
* Entry
, sal_uInt32
*pNoEntry
)
1794 static sal_uInt32 Sect
= 0;
1797 const sal_Char
* pStr
;
1798 osl_TProfileSection
* pSec
=0;
1800 Len
= strlen(Section
);
1804 for (i
= 0; i
< pProfile
->m_NoSections
; i
++)
1806 n
%= pProfile
->m_NoSections
;
1807 pSec
= &pProfile
->m_Sections
[n
];
1808 if ((Len
== pSec
->m_Len
) &&
1809 (strncasecmp(Section
, &pProfile
->m_Lines
[pSec
->m_Line
][pSec
->m_Offset
], pSec
->m_Len
)
1817 if (i
< pProfile
->m_NoSections
)
1819 Len
= strlen(Entry
);
1821 *pNoEntry
= pSec
->m_NoEntries
;
1823 for (i
= 0; i
< pSec
->m_NoEntries
; i
++)
1825 pStr
= &pProfile
->m_Lines
[pSec
->m_Entries
[i
].m_Line
]
1826 [pSec
->m_Entries
[i
].m_Offset
];
1827 if ((Len
== pSec
->m_Entries
[i
].m_Len
) &&
1828 (strncasecmp(Entry
, pStr
, pSec
->m_Entries
[i
].m_Len
)
1842 static sal_Bool
loadProfile(osl_TFile
* pFile
, osl_TProfileImpl
* pProfile
)
1849 sal_Char
* bWasAdded
= NULL
;
1862 pProfile
->m_NoLines
= 0;
1863 pProfile
->m_NoSections
= 0;
1865 OSL_VERIFY(OslProfile_rewindFile(pFile
, sal_False
));
1867 while ( ( pLine
=OslProfile_getLine(pFile
) ) != 0 )
1869 bWasAdded
= addLine( pProfile
, pLine
);
1870 rtl_freeMemory( pLine
);
1871 OSL_ASSERT(bWasAdded
);
1876 for (i
= 0; i
< pProfile
->m_NoLines
; i
++)
1878 pStr
= (sal_Char
*)stripBlanks(pProfile
->m_Lines
[i
], NULL
);
1880 if ((*pStr
== '\0') || (*pStr
== ';'))
1883 if ((*pStr
!= '[') || ((pChar
= strrchr(pStr
, ']')) == NULL
) ||
1884 ((pChar
- pStr
) <= 2))
1888 if (pProfile
->m_NoSections
< 1)
1891 if ((pChar
= strchr(pStr
, '=')) == NULL
)
1892 pChar
= pStr
+ strlen(pStr
);
1894 if (! addEntry(pProfile
, &pProfile
->m_Sections
[pProfile
->m_NoSections
- 1],
1895 i
, pStr
, pChar
- pStr
))
1906 if (! addSection(pProfile
, i
, pStr
+ 1, pChar
- pStr
- 1))
1918 static sal_Bool
storeProfile(osl_TProfileImpl
* pProfile
, sal_Bool bCleanup
)
1920 #ifdef TRACE_OSL_PROFILE
1921 OSL_TRACE("In storeProfile");
1924 if (pProfile
->m_Lines
!= NULL
)
1926 if (pProfile
->m_Flags
& FLG_MODIFIED
)
1930 osl_TFile
* pTmpFile
= osl_openTmpProfileImpl(pProfile
);
1932 if ( pTmpFile
== 0 )
1937 OSL_VERIFY(OslProfile_rewindFile(pTmpFile
, sal_True
));
1939 for ( i
= 0 ; i
< pProfile
->m_NoLines
; i
++ )
1941 OSL_VERIFY(OslProfile_putLine(pTmpFile
, pProfile
->m_Lines
[i
]));
1944 if ( ! writeProfileImpl(pTmpFile
) )
1946 if ( pTmpFile
->m_pWriteBuf
!= 0 )
1948 free(pTmpFile
->m_pWriteBuf
);
1951 pTmpFile
->m_pWriteBuf
=0;
1952 pTmpFile
->m_nWriteBufLen
=0;
1953 pTmpFile
->m_nWriteBufFree
=0;
1955 #ifdef TRACE_OSL_PROFILE
1956 OSL_TRACE("Out storeProfile [not flushed]");
1958 closeFileImpl(pTmpFile
,pProfile
->m_Flags
);
1963 pProfile
->m_Flags
&= ~FLG_MODIFIED
;
1965 closeFileImpl(pProfile
->m_pFile
,pProfile
->m_Flags
);
1966 closeFileImpl(pTmpFile
,pProfile
->m_Flags
);
1968 osl_ProfileSwapProfileNames(pProfile
);
1970 pProfile
->m_pFile
= openFileImpl(pProfile
->m_FileName
,pProfile
->m_Flags
);
1976 while (pProfile
->m_NoLines
> 0)
1977 removeLine(pProfile
, pProfile
->m_NoLines
- 1);
1979 free(pProfile
->m_Lines
);
1980 pProfile
->m_Lines
= NULL
;
1981 pProfile
->m_NoLines
= 0;
1982 pProfile
->m_MaxLines
= 0;
1984 while (pProfile
->m_NoSections
> 0)
1985 removeSection(pProfile
, &pProfile
->m_Sections
[pProfile
->m_NoSections
- 1]);
1987 free(pProfile
->m_Sections
);
1988 pProfile
->m_Sections
= NULL
;
1989 pProfile
->m_NoSections
= 0;
1990 pProfile
->m_MaxSections
= 0;
1994 #ifdef TRACE_OSL_PROFILE
1995 OSL_TRACE("Out storeProfile [ok]");
2001 static osl_TFile
* osl_openTmpProfileImpl(osl_TProfileImpl
* pProfile
)
2004 sal_Char
* pszExtension
= "tmp";
2005 sal_Char pszTmpName
[PATH_MAX
];
2006 oslProfileOption PFlags
=0;
2008 pszTmpName
[0] = '\0';
2010 /* generate tmp profilename */
2011 osl_ProfileGenerateExtension(pProfile
->m_FileName
,pszExtension
,pszTmpName
);
2013 if ( pszTmpName
[0] == 0 )
2018 if ( ! ( pProfile
->m_Flags
& osl_Profile_READLOCK
) )
2020 PFlags
|= osl_Profile_WRITELOCK
;
2023 /* open this file */
2024 pFile
= openFileImpl(pszTmpName
,pProfile
->m_Flags
| PFlags
);
2027 /* return new pFile */
2031 static sal_Bool
osl_ProfileSwapProfileNames(osl_TProfileImpl
* pProfile
)
2033 sal_Bool bRet
= sal_False
;
2035 sal_Char pszBakFile
[PATH_MAX
];
2036 sal_Char pszTmpFile
[PATH_MAX
];
2037 sal_Char pszIniFile
[PATH_MAX
];
2039 pszBakFile
[0] = '\0';
2040 pszTmpFile
[0] = '\0';
2041 pszIniFile
[0] = '\0';
2043 osl_ProfileGenerateExtension(pProfile
->m_FileName
,"bak",pszBakFile
);
2045 strcpy(pszIniFile
,pProfile
->m_FileName
);
2047 osl_ProfileGenerateExtension(pProfile
->m_FileName
,"tmp",pszTmpFile
);
2050 unlink( pszBakFile
);
2052 /* rename ini bak */
2053 rename( pszIniFile
, pszBakFile
);
2055 /* rename tmp ini */
2056 rename( pszTmpFile
, pszIniFile
);
2062 static void osl_ProfileGenerateExtension(sal_Char
* pszFileName
, sal_Char
* pszExtension
, sal_Char
* pszTmpName
)
2065 strcpy(pszTmpName
,pszFileName
);
2066 strcat(pszTmpName
,".");
2067 strcat(pszTmpName
,pszExtension
);
2073 static osl_TProfileImpl
* acquireProfile(oslProfile Profile
, sal_Bool bWriteable
)
2075 osl_TProfileImpl
* pProfile
= (osl_TProfileImpl
*)Profile
;
2076 oslProfileOption PFlags
=0;
2080 PFlags
= osl_Profile_DEFAULT
| osl_Profile_WRITELOCK
;
2084 PFlags
= osl_Profile_DEFAULT
;
2088 if (pProfile
== NULL
)
2090 #ifdef DEBUG_OSL_PROFILE
2091 OSL_TRACE("AUTOOPEN MODE");
2094 if ( ( pProfile
= (osl_TProfileImpl
*) osl_openProfile(0, PFlags
) ) != NULL
)
2096 pProfile
->m_Flags
|= FLG_AUTOOPEN
;
2101 #ifdef DEBUG_OSL_PROFILE
2102 OSL_TRACE("try to acquire");
2105 if (! (pProfile
->m_Flags
& osl_Profile_SYSTEM
))
2107 if (! (pProfile
->m_Flags
& (osl_Profile_READLOCK
| osl_Profile_WRITELOCK
| osl_Profile_FLUSHWRITE
)))
2111 #ifdef DEBUG_OSL_PROFILE
2112 OSL_TRACE("Profile acquire DEFAULT MODE");
2114 if (! (pProfile
->m_pFile
= openFileImpl(pProfile
->m_FileName
, pProfile
->m_Flags
| PFlags
)))
2117 Stamp
= OslProfile_getFileStamp(pProfile
->m_pFile
);
2119 if (memcmp(&Stamp
, &(pProfile
->m_Stamp
), sizeof(osl_TStamp
)))
2121 sal_Bool bRet
=sal_False
;
2123 pProfile
->m_Stamp
= Stamp
;
2125 bRet
=loadProfile(pProfile
->m_pFile
, pProfile
);
2132 #ifdef DEBUG_OSL_PROFILE
2133 OSL_TRACE("Profile acquire READ/WRITELOCK MODE");
2135 /* A readlock file could not be written */
2136 if ((pProfile
->m_Flags
& osl_Profile_READLOCK
) && bWriteable
)
2147 static sal_Bool
releaseProfile(osl_TProfileImpl
* pProfile
)
2149 #ifdef TRACE_OSL_PROFILE
2150 OSL_TRACE("In releaseProfile");
2153 if ( pProfile
== 0 )
2155 #ifdef TRACE_OSL_PROFILE
2156 OSL_TRACE("Out releaseProfile [profile==0]");
2161 if (pProfile
->m_Flags
& FLG_AUTOOPEN
)
2163 #ifdef TRACE_OSL_PROFILE
2164 OSL_TRACE("Out releaseProfile [AUTOOPEN]");
2166 return (osl_closeProfile((oslProfile
)pProfile
));
2170 #ifdef DEBUG_OSL_PROFILE
2171 OSL_TRACE("DEFAULT MODE");
2173 if (! (pProfile
->m_Flags
& (osl_Profile_READLOCK
| osl_Profile_WRITELOCK
| osl_Profile_FLUSHWRITE
)))
2175 if (pProfile
->m_Flags
& FLG_MODIFIED
)
2177 sal_Bool bRet
=storeProfile(pProfile
, sal_False
);
2182 closeFileImpl(pProfile
->m_pFile
,pProfile
->m_Flags
);
2183 pProfile
->m_pFile
= NULL
;
2187 #ifdef TRACE_OSL_PROFILE
2188 OSL_TRACE("Out releaseProfile [ok]");
2193 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */