1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
31 #include "readwrite_helper.h"
33 #include <osl/diagnose.h>
34 #include <osl/profile.h>
35 #include <osl/process.h>
36 #include <osl/thread.h>
37 #include <rtl/alloc.h>
42 #define SECTIONS_INI 5
43 #define SECTIONS_ADD 3
48 #define STR_INI_EXTENSION "rc"
49 #define STR_INI_METAHOME "?~"
50 #define STR_INI_METASYS "?$"
51 #define STR_INI_METACFG "?^"
52 #define STR_INI_METAINS "?#"
54 #define STR_INI_BOOLYES "yes"
55 #define STR_INI_BOOLON "on"
56 #define STR_INI_BOOLONE "1"
57 #define STR_INI_BOOLNO "no"
58 #define STR_INI_BOOLOFF "off"
59 #define STR_INI_BOOLZERO "0"
61 #define FLG_USER 0x00FF
62 #define FLG_AUTOOPEN 0x0100
63 #define FLG_MODIFIED 0x0200
65 #define SVERSION_LOCATION STR_INI_METACFG
66 #define SVERSION_FALLBACK STR_INI_METASYS
67 #define SVERSION_NAME "sversion"
68 #define SVERSION_SECTION "Versions"
69 #define SVERSION_SOFFICE "StarOffice"
70 #define SVERSION_PROFILE "sofficerc"
71 #define SVERSION_OPTION "userid:"
72 #define SVERSION_DIRS { "bin", "program" }
73 #define SVERSION_USER "user"
75 #define DEFAULT_PMODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)
77 #define _BUILD_STR_(n) # n
78 #define BUILD_STR(n) _BUILD_STR_(n)
81 /*#define DEBUG_OSL_PROFILE*/
82 /*#define TRACE_OSL_PROFILE*/
84 /*****************************************************************************/
85 /* Data Type Definition */
86 /*****************************************************************************/
88 typedef time_t osl_TStamp
;
90 typedef enum _osl_TLockMode
92 un_lock
, read_lock
, write_lock
95 typedef struct _osl_TFile
99 sal_Char m_ReadBuf
[512];
100 sal_Char
* m_pWriteBuf
;
101 sal_uInt32 m_nWriteBufLen
;
102 sal_uInt32 m_nWriteBufFree
;
105 typedef struct _osl_TProfileEntry
112 typedef struct _osl_TProfileSection
117 sal_uInt32 m_NoEntries
;
118 sal_uInt32 m_MaxEntries
;
119 osl_TProfileEntry
* m_Entries
;
120 } osl_TProfileSection
;
124 Profile-data structure hidden behind oslProfile:
126 typedef struct _osl_TProfileImpl
131 sal_Char m_FileName
[PATH_MAX
+ 1];
132 sal_uInt32 m_NoLines
;
133 sal_uInt32 m_MaxLines
;
134 sal_uInt32 m_NoSections
;
135 sal_uInt32 m_MaxSections
;
137 osl_TProfileSection
* m_Sections
;
138 pthread_mutex_t m_AccessLock
;
143 /*****************************************************************************/
144 /* Static Module Function Declarations */
145 /*****************************************************************************/
147 static osl_TFile
* openFileImpl(const sal_Char
* pszFilename
, oslProfileOption ProfileFlags
);
148 static osl_TStamp
closeFileImpl(osl_TFile
* pFile
, oslProfileOption Flags
);
149 static sal_Bool
OslProfile_lockFile(const osl_TFile
* pFile
, osl_TLockMode eMode
);
150 static sal_Bool
OslProfile_rewindFile(osl_TFile
* pFile
, sal_Bool bTruncate
);
151 static osl_TStamp
OslProfile_getFileStamp(osl_TFile
* pFile
);
153 static sal_Char
* OslProfile_getLine(osl_TFile
* pFile
);
154 static sal_Bool
OslProfile_putLine(osl_TFile
* pFile
, const sal_Char
*pszLine
);
155 static sal_Char
* stripBlanks(sal_Char
* String
, sal_uInt32
* pLen
);
156 static sal_Char
* addLine(osl_TProfileImpl
* pProfile
, const sal_Char
* Line
);
157 static sal_Char
* insertLine(osl_TProfileImpl
* pProfile
, const sal_Char
* Line
, sal_uInt32 LineNo
);
158 static void removeLine(osl_TProfileImpl
* pProfile
, sal_uInt32 LineNo
);
159 static void setEntry(osl_TProfileImpl
* pProfile
, osl_TProfileSection
* pSection
,
160 sal_uInt32 NoEntry
, sal_uInt32 Line
,
161 sal_Char
* Entry
, sal_uInt32 Len
);
162 static sal_Bool
addEntry(osl_TProfileImpl
* pProfile
, osl_TProfileSection
*pSection
,
163 int Line
, sal_Char
* Entry
, sal_uInt32 Len
);
164 static void removeEntry(osl_TProfileSection
*pSection
, sal_uInt32 NoEntry
);
165 static sal_Bool
addSection(osl_TProfileImpl
* pProfile
, int Line
, const sal_Char
* Section
, sal_uInt32 Len
);
166 static void removeSection(osl_TProfileImpl
* pProfile
, osl_TProfileSection
*pSection
);
167 static osl_TProfileSection
* findEntry(osl_TProfileImpl
* pProfile
, const sal_Char
* Section
,
168 const sal_Char
* Entry
, sal_uInt32
*pNoEntry
);
169 static sal_Bool
loadProfile(osl_TFile
* pFile
, osl_TProfileImpl
* pProfile
);
170 static sal_Bool
storeProfile(osl_TProfileImpl
* pProfile
, sal_Bool bCleanup
);
171 static osl_TProfileImpl
* acquireProfile(oslProfile Profile
, sal_Bool bWriteable
);
172 static sal_Bool
releaseProfile(osl_TProfileImpl
* pProfile
);
174 static sal_Bool
writeProfileImpl (osl_TFile
* pFile
);
175 static osl_TFile
* osl_openTmpProfileImpl(osl_TProfileImpl
*);
176 static sal_Bool
osl_ProfileSwapProfileNames(osl_TProfileImpl
*);
177 static void osl_ProfileGenerateExtension(sal_Char
* pszFileName
, sal_Char
* pszExtension
, sal_Char
* pszTmpName
);
178 static oslProfile SAL_CALL
osl_psz_openProfile(const sal_Char
*pszProfileName
, oslProfileOption Flags
);
180 /* implemented in file.c */
181 extern oslFileError
FileURLToPath( char *, size_t, rtl_uString
* );
183 /*****************************************************************************/
184 /* Exported Module Functions */
185 /*****************************************************************************/
186 oslProfile SAL_CALL
osl_openProfile(rtl_uString
*ustrProfileName
, oslProfileOption Options
)
188 char profilePath
[PATH_MAX
] = "";
190 if ( ustrProfileName
!= 0 && ustrProfileName
->buffer
[0] != 0 )
191 FileURLToPath( profilePath
, PATH_MAX
, ustrProfileName
);
193 return osl_psz_openProfile( profilePath
,Options
);
197 static oslProfile SAL_CALL
osl_psz_openProfile(const sal_Char
*pszProfileName
, oslProfileOption Flags
)
200 osl_TProfileImpl
* pProfile
;
201 sal_Bool bRet
= sal_False
;
203 #ifdef TRACE_OSL_PROFILE
204 OSL_TRACE("In osl_openProfile");
207 #ifdef DEBUG_OSL_PROFILE
208 Flags
=osl_Profile_FLUSHWRITE
;
210 OSL_TRACE("opening '%s'",pszProfileName
);
211 if ( Flags
== osl_Profile_DEFAULT
)
213 OSL_TRACE("with osl_Profile_DEFAULT");
215 if ( Flags
& osl_Profile_SYSTEM
)
217 OSL_TRACE("with osl_Profile_SYSTEM");
219 if ( Flags
& osl_Profile_READLOCK
)
221 OSL_TRACE("with osl_Profile_READLOCK");
223 if ( Flags
& osl_Profile_WRITELOCK
)
225 OSL_TRACE("with osl_Profile_WRITELOCK");
227 if ( Flags
& osl_Profile_FLUSHWRITE
)
229 OSL_TRACE("with osl_Profile_FLUSHWRITE");
234 if ( ( pFile
= openFileImpl(pszProfileName
, Flags
) ) == NULL
)
236 #ifdef TRACE_OSL_PROFILE
237 OSL_TRACE("Out osl_openProfile [not opened]");
243 pProfile
= (osl_TProfileImpl
*)calloc(1, sizeof(osl_TProfileImpl
));
247 closeFileImpl(pFile
, Flags
);
251 pProfile
->m_Flags
= Flags
& FLG_USER
;
253 if ( Flags
& ( osl_Profile_READLOCK
| osl_Profile_WRITELOCK
| osl_Profile_FLUSHWRITE
) )
255 pProfile
->m_pFile
= pFile
;
258 pthread_mutex_init(&(pProfile
->m_AccessLock
),PTHREAD_MUTEXATTR_DEFAULT
);
259 pProfile
->m_bIsValid
=sal_True
;
261 pProfile
->m_Stamp
= OslProfile_getFileStamp(pFile
);
262 bRet
=loadProfile(pFile
, pProfile
);
263 bRet
&= realpath(pszProfileName
, pProfile
->m_FileName
) != NULL
;
266 if (pProfile
->m_pFile
== NULL
)
267 closeFileImpl(pFile
,pProfile
->m_Flags
);
269 #ifdef TRACE_OSL_PROFILE
270 OSL_TRACE("Out osl_openProfile [ok]");
275 sal_Bool SAL_CALL
osl_closeProfile(oslProfile Profile
)
277 osl_TProfileImpl
* pProfile
= (osl_TProfileImpl
*)Profile
;
278 osl_TProfileImpl
* pTmpProfile
;
280 #ifdef TRACE_OSL_PROFILE
281 OSL_TRACE("In osl_closeProfile");
286 #ifdef TRACE_OSL_PROFILE
287 OSL_TRACE("Out osl_closeProfile [profile==0]");
292 pthread_mutex_lock(&(pProfile
->m_AccessLock
));
294 if ( pProfile
->m_bIsValid
== sal_False
)
296 OSL_ASSERT(pProfile
->m_bIsValid
);
297 pthread_mutex_unlock(&(pProfile
->m_AccessLock
));
298 #ifdef TRACE_OSL_PROFILE
299 OSL_TRACE("Out osl_closeProfile [not valid]");
304 pProfile
->m_bIsValid
=sal_False
;
306 if ( ! ( pProfile
->m_Flags
& osl_Profile_READLOCK
) && ( pProfile
->m_Flags
& FLG_MODIFIED
) )
308 pTmpProfile
= acquireProfile(Profile
,sal_True
);
310 if ( pTmpProfile
!= 0 )
312 sal_Bool bRet
= storeProfile(pTmpProfile
, sal_True
);
319 pTmpProfile
= acquireProfile(Profile
,sal_False
);
323 if ( pTmpProfile
== 0 )
325 pthread_mutex_unlock(&(pProfile
->m_AccessLock
));
326 #ifdef TRACE_OSL_PROFILE
327 OSL_TRACE("Out osl_closeProfile [pProfile==0]");
332 pProfile
= pTmpProfile
;
334 if (pProfile
->m_pFile
!= NULL
)
335 closeFileImpl(pProfile
->m_pFile
,pProfile
->m_Flags
);
337 pProfile
->m_pFile
= NULL
;
338 pProfile
->m_FileName
[0] = '\0';
340 /* release whole profile data types memory */
341 if ( pProfile
->m_NoLines
> 0)
344 if ( pProfile
->m_Lines
!= 0 )
346 for ( idx
= 0 ; idx
< pProfile
->m_NoLines
; ++idx
)
348 if ( pProfile
->m_Lines
[idx
] != 0 )
350 free(pProfile
->m_Lines
[idx
]);
351 pProfile
->m_Lines
[idx
]=0;
354 free(pProfile
->m_Lines
);
357 if ( pProfile
->m_Sections
!= 0 )
359 /*osl_TProfileSection* pSections=pProfile->m_Sections;*/
360 for ( idx
= 0 ; idx
< pProfile
->m_NoSections
; ++idx
)
362 if ( pProfile
->m_Sections
[idx
].m_Entries
!= 0 )
364 free(pProfile
->m_Sections
[idx
].m_Entries
);
365 pProfile
->m_Sections
[idx
].m_Entries
=0;
368 free(pProfile
->m_Sections
);
369 pProfile
->m_Sections
=0;
373 pthread_mutex_unlock(&(pProfile
->m_AccessLock
));
375 pthread_mutex_destroy(&(pProfile
->m_AccessLock
));
379 #ifdef TRACE_OSL_PROFILE
380 OSL_TRACE("Out osl_closeProfile [ok]");
386 sal_Bool SAL_CALL
osl_flushProfile(oslProfile Profile
)
388 osl_TProfileImpl
* pProfile
= (osl_TProfileImpl
*) Profile
;
390 sal_Bool bRet
= sal_False
;
392 #ifdef TRACE_OSL_PROFILE
393 OSL_TRACE("In osl_flushProfile()");
398 #ifdef TRACE_OSL_PROFILE
399 OSL_TRACE("Out osl_flushProfile() [pProfile == 0]");
404 pthread_mutex_lock(&(pProfile
->m_AccessLock
));
406 if ( pProfile
->m_bIsValid
== sal_False
)
408 OSL_ASSERT(pProfile
->m_bIsValid
);
409 pthread_mutex_unlock(&(pProfile
->m_AccessLock
));
410 #ifdef TRACE_OSL_PROFILE
411 OSL_TRACE("Out osl_flushProfile [not valid]");
416 pFile
= pProfile
->m_pFile
;
417 if ( !( pFile
!= 0 && pFile
->m_Handle
>= 0 ) )
419 pthread_mutex_unlock(&(pProfile
->m_AccessLock
));
420 #ifdef TRACE_OSL_PROFILE
421 OSL_TRACE("Out osl_flushProfile() [invalid file]");
426 if ( pProfile
->m_Flags
& FLG_MODIFIED
)
428 #ifdef DEBUG_OSL_PROFILE
429 OSL_TRACE("swapping to storeprofile");
431 bRet
= storeProfile(pProfile
,sal_False
);
435 #ifdef TRACE_OSL_PROFILE
436 OSL_TRACE("Out osl_flushProfile() [ok]");
438 pthread_mutex_unlock(&(pProfile
->m_AccessLock
));
442 static sal_Bool
writeProfileImpl(osl_TFile
* pFile
)
444 #if OSL_DEBUG_LEVEL > 1
448 #ifdef TRACE_OSL_PROFILE
449 OSL_TRACE("In osl_writeProfileImpl()");
452 if ( !( pFile
!= 0 && pFile
->m_Handle
>= 0 ) || ( pFile
->m_pWriteBuf
== 0 ) )
454 #ifdef TRACE_OSL_PROFILE
455 OSL_TRACE("Out osl_writeProfileImpl() [invalid args]");
460 #if OSL_DEBUG_LEVEL > 1
461 nLen
=strlen(pFile
->m_pWriteBuf
);
462 OSL_ASSERT(nLen
== (pFile
->m_nWriteBufLen
- pFile
->m_nWriteBufFree
));
465 if ( !safeWrite(pFile
->m_Handle
, pFile
->m_pWriteBuf
, pFile
->m_nWriteBufLen
- pFile
->m_nWriteBufFree
) )
467 OSL_TRACE("write failed '%s'",strerror(errno
));
471 free(pFile
->m_pWriteBuf
);
472 pFile
->m_pWriteBuf
=0;
473 pFile
->m_nWriteBufLen
=0;
474 pFile
->m_nWriteBufFree
=0;
475 #ifdef TRACE_OSL_PROFILE
476 OSL_TRACE("Out osl_writeProfileImpl() [ok]");
482 sal_Bool SAL_CALL
osl_readProfileString(oslProfile Profile
,
483 const sal_Char
* pszSection
, const sal_Char
* pszEntry
,
484 sal_Char
* pszString
, sal_uInt32 MaxLen
,
485 const sal_Char
* pszDefault
)
489 osl_TProfileSection
* pSec
;
490 osl_TProfileImpl
* pProfile
=0;
491 osl_TProfileImpl
* pTmpProfile
=0;
492 sal_Bool bRet
= sal_False
;
494 #ifdef TRACE_OSL_PROFILE
495 OSL_TRACE("In osl_readProfileString");
498 pTmpProfile
= (osl_TProfileImpl
*) Profile
;
500 if ( pTmpProfile
== 0 )
502 #ifdef TRACE_OSL_PROFILE
503 OSL_TRACE("Out osl_readProfileString [pTmpProfile==0]");
508 pthread_mutex_lock(&(pTmpProfile
->m_AccessLock
));
510 if ( pTmpProfile
->m_bIsValid
== sal_False
)
512 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
513 #ifdef TRACE_OSL_PROFILE
514 OSL_TRACE("Out osl_readProfileString [not valid]");
519 pProfile
= acquireProfile(Profile
, sal_False
);
521 if ( pProfile
== NULL
)
523 #ifdef TRACE_OSL_PROFILE
524 OSL_TRACE("Out osl_readProfileString [pProfile==0]");
529 if (! (pProfile
->m_Flags
& osl_Profile_SYSTEM
))
531 if (((pSec
= findEntry(pProfile
, pszSection
, pszEntry
, &NoEntry
)) != NULL
) &&
532 (NoEntry
< pSec
->m_NoEntries
) &&
533 ((pStr
= strchr(pProfile
->m_Lines
[pSec
->m_Entries
[NoEntry
].m_Line
],
540 pStr
=(sal_Char
*)pszDefault
;
545 pStr
= stripBlanks(pStr
, NULL
);
546 MaxLen
= (MaxLen
- 1 < strlen(pStr
)) ? (MaxLen
- 1) : strlen(pStr
);
547 pStr
= stripBlanks(pStr
, &MaxLen
);
548 strncpy(pszString
, pStr
, MaxLen
);
549 pszString
[MaxLen
] = '\0';
553 { /* not implemented */ }
556 bRet
=releaseProfile(pProfile
);
562 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
563 #ifdef TRACE_OSL_PROFILE
564 OSL_TRACE("Out osl_readProfileString [pStr==0]");
569 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
571 #ifdef TRACE_OSL_PROFILE
572 OSL_TRACE("Out osl_readProfileString [ok]");
579 sal_Bool SAL_CALL
osl_readProfileBool(oslProfile Profile
,
580 const sal_Char
* pszSection
, const sal_Char
* pszEntry
,
586 #ifdef TRACE_OSL_PROFILE
587 OSL_TRACE("In osl_readProfileBool");
590 if (osl_readProfileString(Profile
, pszSection
, pszEntry
, Line
, sizeof(Line
), ""))
592 if ((strcasecmp(Line
, STR_INI_BOOLYES
) == 0) ||
593 (strcasecmp(Line
, STR_INI_BOOLON
) == 0) ||
594 (strcasecmp(Line
, STR_INI_BOOLONE
) == 0))
597 if ((strcasecmp(Line
, STR_INI_BOOLNO
) == 0) ||
598 (strcasecmp(Line
, STR_INI_BOOLOFF
) == 0) ||
599 (strcasecmp(Line
, STR_INI_BOOLZERO
) == 0))
603 #ifdef TRACE_OSL_PROFILE
604 OSL_TRACE("Out osl_readProfileBool [ok]");
611 sal_uInt32 SAL_CALL
osl_readProfileIdent(oslProfile Profile
,
612 const sal_Char
* pszSection
, const sal_Char
* pszEntry
,
613 sal_uInt32 FirstId
, const sal_Char
* Strings
[],
620 #ifdef TRACE_OSL_PROFILE
621 OSL_TRACE("In osl_readProfileIdent");
624 if (osl_readProfileString(Profile
, pszSection
, pszEntry
, Line
, sizeof(Line
), ""))
627 while (Strings
[i
] != NULL
)
629 if (strcasecmp(Line
, Strings
[i
]) == 0)
631 Default
= i
+ FirstId
;
638 #ifdef TRACE_OSL_PROFILE
639 OSL_TRACE("Out osl_readProfileIdent [ok]");
644 sal_Bool SAL_CALL
osl_writeProfileString(oslProfile Profile
,
645 const sal_Char
* pszSection
, const sal_Char
* pszEntry
,
646 const sal_Char
* pszString
)
649 sal_Bool bRet
= sal_False
;
653 osl_TProfileSection
* pSec
;
654 osl_TProfileImpl
* pProfile
= 0;
655 osl_TProfileImpl
* pTmpProfile
= 0;
657 #ifdef TRACE_OSL_PROFILE
658 OSL_TRACE("In osl_writeProfileString");
661 pTmpProfile
= (osl_TProfileImpl
*) Profile
;
663 if ( pTmpProfile
== 0 )
665 #ifdef TRACE_OSL_PROFILE
666 OSL_TRACE("Out osl_writeProfileString [pTmpProfile==0]");
671 pthread_mutex_lock(&(pTmpProfile
->m_AccessLock
));
673 if ( pTmpProfile
->m_bIsValid
== sal_False
)
675 OSL_ASSERT(pTmpProfile
->m_bIsValid
);
676 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
677 #ifdef TRACE_OSL_PROFILE
678 OSL_TRACE("Out osl_writeProfileString [not valid]");
683 pProfile
=acquireProfile(Profile
, sal_True
);
685 if (pProfile
== NULL
)
687 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
688 #ifdef TRACE_OSL_PROFILE
689 OSL_TRACE("Out osl_writeProfileString [pProfile==0]");
694 Line
= (sal_Char
*) malloc(strlen(pszEntry
)+strlen(pszString
)+48);
696 if (! (pProfile
->m_Flags
& osl_Profile_SYSTEM
))
698 if ((pSec
= findEntry(pProfile
, pszSection
, pszEntry
, &NoEntry
)) == NULL
)
701 addLine(pProfile
, Line
);
704 strcpy(&Line
[1], pszSection
);
705 Line
[1 + strlen(pszSection
)] = ']';
706 Line
[2 + strlen(pszSection
)] = '\0';
708 if (((pStr
= addLine(pProfile
, Line
)) == NULL
) ||
709 (! addSection(pProfile
, pProfile
->m_NoLines
- 1, &pStr
[1], strlen(pszSection
))))
711 bRet
=releaseProfile(pProfile
);
714 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
718 #ifdef TRACE_OSL_PROFILE
719 OSL_TRACE("Out osl_writeProfileString [not added]");
724 pSec
= &pProfile
->m_Sections
[pProfile
->m_NoSections
- 1];
725 NoEntry
= pSec
->m_NoEntries
;
729 strcpy(&Line
[0], pszEntry
);
730 Line
[0 + strlen(pszEntry
)] = '=';
731 strcpy(&Line
[1 + strlen(pszEntry
)], pszString
);
733 if (NoEntry
>= pSec
->m_NoEntries
)
735 if (pSec
->m_NoEntries
> 0)
736 i
= pSec
->m_Entries
[pSec
->m_NoEntries
- 1].m_Line
+ 1;
738 i
= pSec
->m_Line
+ 1;
740 if (((pStr
= insertLine(pProfile
, Line
, i
)) == NULL
) ||
741 (! addEntry(pProfile
, pSec
, i
, pStr
, strlen(pszEntry
))))
743 bRet
=releaseProfile(pProfile
);
746 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
749 #ifdef TRACE_OSL_PROFILE
750 OSL_TRACE("Out osl_writeProfileString [not inserted]");
755 pProfile
->m_Flags
|= FLG_MODIFIED
;
759 i
= pSec
->m_Entries
[NoEntry
].m_Line
;
760 free(pProfile
->m_Lines
[i
]);
761 pProfile
->m_Lines
[i
] = strdup(Line
);
762 setEntry(pProfile
, pSec
, NoEntry
, i
, pProfile
->m_Lines
[i
], strlen(pszEntry
));
764 pProfile
->m_Flags
|= FLG_MODIFIED
;
768 /* not implemented */
771 bRet
= releaseProfile(pProfile
);
774 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
780 #ifdef TRACE_OSL_PROFILE
781 OSL_TRACE("Out osl_writeProfileString [ok]");
788 sal_Bool SAL_CALL
osl_writeProfileBool(oslProfile Profile
,
789 const sal_Char
* pszSection
, const sal_Char
* pszEntry
,
792 sal_Bool bRet
=sal_False
;
794 #ifdef TRACE_OSL_PROFILE
795 OSL_TRACE("In osl_writeProfileBool");
799 bRet
=osl_writeProfileString(Profile
, pszSection
, pszEntry
, STR_INI_BOOLONE
);
801 bRet
=osl_writeProfileString(Profile
, pszSection
, pszEntry
, STR_INI_BOOLZERO
);
803 #ifdef TRACE_OSL_PROFILE
804 OSL_TRACE("Out osl_writeProfileBool [ok]");
811 sal_Bool SAL_CALL
osl_writeProfileIdent(oslProfile Profile
,
812 const sal_Char
* pszSection
, const sal_Char
* pszEntry
,
813 sal_uInt32 FirstId
, const sal_Char
* Strings
[],
817 sal_Bool bRet
=sal_False
;
819 #ifdef TRACE_OSL_PROFILE
820 OSL_TRACE("In osl_writeProfileIdent");
823 for (n
= 0; Strings
[n
] != NULL
; n
++);
825 if ((i
= Value
- FirstId
) >= n
)
828 bRet
= osl_writeProfileString(Profile
, pszSection
, pszEntry
, Strings
[i
]);
830 #ifdef TRACE_OSL_PROFILE
831 OSL_TRACE("Out osl_writeProfileIdent");
837 sal_Bool SAL_CALL
osl_removeProfileEntry(oslProfile Profile
,
838 const sal_Char
*pszSection
, const sal_Char
*pszEntry
)
841 osl_TProfileSection
* pSec
;
842 osl_TProfileImpl
* pProfile
= 0;
843 osl_TProfileImpl
* pTmpProfile
= 0;
844 sal_Bool bRet
= sal_False
;
846 #ifdef TRACE_OSL_PROFILE
847 OSL_TRACE("In osl_removeProfileEntry");
850 pTmpProfile
= (osl_TProfileImpl
*) Profile
;
852 if ( pTmpProfile
== 0 )
854 #ifdef TRACE_OSL_PROFILE
855 OSL_TRACE("Out osl_removeProfileEntry [pProfile==0]");
860 pthread_mutex_lock(&(pTmpProfile
->m_AccessLock
));
862 if ( pTmpProfile
->m_bIsValid
== sal_False
)
864 OSL_ASSERT(pTmpProfile
->m_bIsValid
);
865 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
866 #ifdef TRACE_OSL_PROFILE
867 OSL_TRACE("Out osl_removeProfileEntry [not valid]");
873 pProfile
= acquireProfile(Profile
, sal_True
);
875 if (pProfile
== NULL
)
877 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
878 #ifdef TRACE_OSL_PROFILE
879 OSL_TRACE("Out osl_removeProfileEntry [pProfile==0]");
885 if (! (pProfile
->m_Flags
& osl_Profile_SYSTEM
))
887 if (((pSec
= findEntry(pProfile
, pszSection
, pszEntry
, &NoEntry
)) != NULL
) &&
888 (NoEntry
< pSec
->m_NoEntries
))
890 removeLine(pProfile
, pSec
->m_Entries
[NoEntry
].m_Line
);
891 removeEntry(pSec
, NoEntry
);
892 if (pSec
->m_NoEntries
== 0)
894 removeLine(pProfile
, pSec
->m_Line
);
896 /* remove any empty separation line */
897 if ((pSec
->m_Line
> 0) && (pProfile
->m_Lines
[pSec
->m_Line
- 1][0] == '\0'))
898 removeLine(pProfile
, pSec
->m_Line
- 1);
900 removeSection(pProfile
, pSec
);
903 pProfile
->m_Flags
|= FLG_MODIFIED
;
907 { /* not implemented */ }
910 bRet
= releaseProfile(pProfile
);
913 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
915 #ifdef TRACE_OSL_PROFILE
916 OSL_TRACE("Out osl_removeProfileEntry [ok]");
922 sal_uInt32 SAL_CALL
osl_getProfileSectionEntries(oslProfile Profile
, const sal_Char
*pszSection
,
923 sal_Char
* pszBuffer
, sal_uInt32 MaxLen
)
927 osl_TProfileSection
* pSec
;
928 osl_TProfileImpl
* pProfile
= 0;
929 osl_TProfileImpl
* pTmpProfile
= 0;
930 sal_Bool bRet
= sal_False
;
932 #ifdef TRACE_OSL_PROFILE
933 OSL_TRACE("In osl_getProfileSectionEntries");
936 pTmpProfile
= (osl_TProfileImpl
*) Profile
;
938 if ( pTmpProfile
== 0 )
940 #ifdef TRACE_OSL_PROFILE
941 OSL_TRACE("Out osl_getProfileSectionEntries [pTmpProfile==0]");
947 pthread_mutex_lock(&(pTmpProfile
->m_AccessLock
));
949 if ( pTmpProfile
->m_bIsValid
== sal_False
)
951 OSL_ASSERT(pTmpProfile
->m_bIsValid
);
953 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
955 #ifdef TRACE_OSL_PROFILE
956 OSL_TRACE("Out osl_getProfileSectionEntries [not valid]");
962 pProfile
= acquireProfile(Profile
, sal_False
);
964 if (pProfile
== NULL
)
966 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
968 #ifdef TRACE_OSL_PROFILE
969 OSL_TRACE("Out osl_getProfileSectionEntries [pProfile=0]");
976 if (! (pProfile
->m_Flags
& osl_Profile_SYSTEM
))
978 if ((pSec
= findEntry(pProfile
, pszSection
, "", &NoEntry
)) != NULL
)
982 for (i
= 0; i
< pSec
->m_NoEntries
; i
++)
984 if ((n
+ pSec
->m_Entries
[i
].m_Len
+ 1) < MaxLen
)
986 strncpy(&pszBuffer
[n
], &pProfile
->m_Lines
[pSec
->m_Entries
[i
].m_Line
]
987 [pSec
->m_Entries
[i
].m_Offset
], pSec
->m_Entries
[i
].m_Len
);
988 n
+= pSec
->m_Entries
[i
].m_Len
;
989 pszBuffer
[n
++] = '\0';
996 pszBuffer
[n
++] = '\0';
1000 for (i
= 0; i
< pSec
->m_NoEntries
; i
++)
1001 n
+= pSec
->m_Entries
[i
].m_Len
+ 1;
1010 /* not implemented */
1013 bRet
=releaseProfile(pProfile
);
1017 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
1019 #ifdef TRACE_OSL_PROFILE
1020 OSL_TRACE("Out osl_getProfileSectionEntries [ok]");
1026 sal_uInt32 SAL_CALL
osl_getProfileSections(oslProfile Profile
, sal_Char
* pszBuffer
, sal_uInt32 MaxLen
)
1028 sal_uInt32 i
, n
= 0;
1029 osl_TProfileSection
* pSec
;
1030 osl_TProfileImpl
* pProfile
= 0;
1031 osl_TProfileImpl
* pTmpProfile
= 0;
1032 sal_Bool bRet
= sal_False
;
1034 #ifdef TRACE_OSL_PROFILE
1035 OSL_TRACE("In osl_getProfileSections");
1038 pTmpProfile
= (osl_TProfileImpl
*) Profile
;
1040 if ( pTmpProfile
== 0 )
1042 #ifdef TRACE_OSL_PROFILE
1043 OSL_TRACE("Out osl_getProfileSections [pTmpProfile==0]");
1048 pthread_mutex_lock(&(pTmpProfile
->m_AccessLock
));
1050 if ( pTmpProfile
->m_bIsValid
== sal_False
)
1052 OSL_ASSERT(pTmpProfile
->m_bIsValid
);
1053 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
1054 #ifdef TRACE_OSL_PROFILE
1055 OSL_TRACE("Out osl_getProfileSections [not valid]");
1060 pProfile
= acquireProfile(Profile
, sal_False
);
1062 if (pProfile
== NULL
)
1064 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
1066 #ifdef TRACE_OSL_PROFILE
1067 OSL_TRACE("Out osl_getProfileSections [pProfile==0]");
1072 if (! (pProfile
->m_Flags
& osl_Profile_SYSTEM
))
1076 for (i
= 0; i
< pProfile
->m_NoSections
; i
++)
1078 pSec
= &pProfile
->m_Sections
[i
];
1080 if ((n
+ pSec
->m_Len
+ 1) < MaxLen
)
1082 strncpy(&pszBuffer
[n
], &pProfile
->m_Lines
[pSec
->m_Line
][pSec
->m_Offset
],
1085 pszBuffer
[n
++] = '\0';
1091 pszBuffer
[n
++] = '\0';
1095 for (i
= 0; i
< pProfile
->m_NoSections
; i
++)
1096 n
+= pProfile
->m_Sections
[i
].m_Len
+ 1;
1102 { /* not implemented */ }
1105 bRet
=releaseProfile(pProfile
);
1109 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
1111 #ifdef TRACE_OSL_PROFILE
1112 OSL_TRACE("Out osl_getProfileSections [ok]");
1118 /*****************************************************************************/
1119 /* Static Module Functions */
1120 /*****************************************************************************/
1122 static osl_TStamp
OslProfile_getFileStamp(osl_TFile
* pFile
)
1126 if ( (pFile
->m_Handle
< 0) || (fstat(pFile
->m_Handle
, &status
) < 0) )
1132 return (status
.st_mtime
);
1135 static sal_Bool
OslProfile_lockFile(const osl_TFile
* pFile
, osl_TLockMode eMode
)
1138 /* boring hack, but initializers for static vars must be constant */
1139 static sal_Bool bIsInitialized
= sal_False
;
1140 static sal_Bool bLockingDisabled
;
1142 #ifdef TRACE_OSL_PROFILE
1143 OSL_TRACE("In OslProfile_lockFile");
1146 if ( !bIsInitialized
)
1148 sal_Char
* pEnvValue
;
1149 pEnvValue
= getenv( "STAR_PROFILE_LOCKING_DISABLED" );
1151 if ( pEnvValue
== 0 )
1153 bLockingDisabled
= sal_False
;
1158 bLockingDisabled
= sal_True
;
1161 bIsInitialized
= sal_True
;
1164 if (pFile
->m_Handle
< 0)
1166 #ifdef TRACE_OSL_PROFILE
1167 OSL_TRACE("Out OslProfile_lockFile [invalid file handle]");
1173 if ( bLockingDisabled
)
1175 #ifdef TRACE_OSL_PROFILE
1176 OSL_TRACE("Out OslProfile_lockFile [locking disabled]");
1183 lock
.l_whence
= SEEK_SET
;
1189 lock
.l_type
= F_UNLCK
;
1193 lock
.l_type
= F_RDLCK
;
1197 lock
.l_type
= F_WRLCK
;
1201 #ifndef MACOSX // not MAC OSX
1202 if ( fcntl(pFile
->m_Handle
, F_SETLKW
, &lock
) == -1 )
1204 /* Mac OSX will return ENOTSUP for webdav drives so we should ignore it */
1205 if ( fcntl(pFile
->m_Handle
, F_SETLKW
, &lock
) == -1 && errno
!= ENOTSUP
)
1208 OSL_TRACE("fcntl returned -1 (%s)",strerror(errno
));
1209 #ifdef TRACE_OSL_PROFILE
1210 OSL_TRACE("Out OslProfile_lockFile [fcntl F_SETLKW]");
1215 #ifdef TRACE_OSL_PROFILE
1216 OSL_TRACE("Out OslProfile_lockFile [ok]");
1221 static osl_TFile
* openFileImpl(const sal_Char
* pszFilename
, oslProfileOption ProfileFlags
)
1224 osl_TFile
* pFile
= (osl_TFile
*) calloc(1, sizeof(osl_TFile
));
1225 sal_Bool bWriteable
= sal_False
;
1227 if ( ProfileFlags
& ( osl_Profile_WRITELOCK
| osl_Profile_FLUSHWRITE
) )
1229 #ifdef DEBUG_OSL_PROFILE
1230 OSL_TRACE("setting bWriteable to TRUE");
1232 bWriteable
=sal_True
;
1237 #ifdef DEBUG_OSL_PROFILE
1238 OSL_TRACE("opening '%s' read only",pszFilename
);
1241 pFile
->m_Handle
= open(pszFilename
, O_RDONLY
);
1242 /* mfe: argghh!!! do not check if the file could be openend */
1243 /* default mode expects it that way!!! */
1247 #ifdef DEBUG_OSL_PROFILE
1248 OSL_TRACE("opening '%s' read/write",pszFilename
);
1250 if (((pFile
->m_Handle
= open(pszFilename
, O_RDWR
| O_CREAT
| O_EXCL
, DEFAULT_PMODE
)) < 0) &&
1251 ((pFile
->m_Handle
= open(pszFilename
, O_RDWR
)) < 0))
1254 #ifdef TRACE_OSL_PROFILE
1255 OSL_TRACE("Out openFileImpl [open read/write]");
1261 /* set close-on-exec flag */
1262 if ((Flags
= fcntl(pFile
->m_Handle
, F_GETFD
, 0)) != -1)
1264 Flags
|= FD_CLOEXEC
;
1265 fcntl(pFile
->m_Handle
, F_SETFD
, Flags
);
1268 pFile
->m_pWriteBuf
=0;
1269 pFile
->m_nWriteBufFree
=0;
1270 pFile
->m_nWriteBufLen
=0;
1272 if ( ProfileFlags
& (osl_Profile_WRITELOCK
| osl_Profile_READLOCK
) )
1274 #ifdef DEBUG_OSL_PROFILE
1275 OSL_TRACE("locking '%s' file",pszFilename
);
1277 OslProfile_lockFile(pFile
, bWriteable
? write_lock
: read_lock
);
1280 #ifdef TRACE_OSL_PROFILE
1281 OSL_TRACE("Out openFileImpl [ok]");
1286 static osl_TStamp
closeFileImpl(osl_TFile
* pFile
, oslProfileOption Flags
)
1288 osl_TStamp stamp
= 0;
1290 #ifdef TRACE_OSL_PROFILE
1291 OSL_TRACE("In closeFileImpl");
1296 #ifdef TRACE_OSL_PROFILE
1297 OSL_TRACE("Out closeFileImpl [pFile == 0]");
1302 if ( pFile
->m_Handle
>= 0 )
1304 stamp
= OslProfile_getFileStamp(pFile
);
1306 if ( Flags
& (osl_Profile_WRITELOCK
| osl_Profile_WRITELOCK
) )
1308 OslProfile_lockFile(pFile
, un_lock
);
1311 close(pFile
->m_Handle
);
1312 pFile
->m_Handle
= -1;
1316 if ( pFile
->m_pWriteBuf
)
1318 free(pFile
->m_pWriteBuf
);
1323 #ifdef TRACE_OSL_PROFILE
1324 OSL_TRACE("Out closeFileImpl [ok]");
1330 static sal_Bool
OslProfile_rewindFile(osl_TFile
* pFile
, sal_Bool bTruncate
)
1332 sal_Bool bRet
= sal_True
;
1333 #ifdef TRACE_OSL_PROFILE
1334 OSL_TRACE("In osl_OslProfile_rewindFile");
1337 if (pFile
->m_Handle
>= 0)
1339 pFile
->m_pReadPtr
= pFile
->m_ReadBuf
+ sizeof(pFile
->m_ReadBuf
);
1341 #ifdef DEBUG_OSL_PROFILE
1342 OSL_TRACE("rewinding");
1344 bRet
= (lseek(pFile
->m_Handle
, SEEK_SET
, 0L) == 0L);
1348 #ifdef DEBUG_OSL_PROFILE
1349 OSL_TRACE("truncating");
1351 bRet
&= (ftruncate(pFile
->m_Handle
, 0L) == 0);
1356 #ifdef TRACE_OSL_PROFILE
1357 OSL_TRACE("Out osl_OslProfile_rewindFile [ok]");
1363 static sal_Char
* OslProfile_getLine(osl_TFile
* pFile
)
1365 int Max
, Free
, Bytes
, nLineBytes
= 0;
1367 sal_Char
* pLine
= NULL
;
1375 if (pFile
->m_Handle
< 0)
1380 Bytes
= sizeof(pFile
->m_ReadBuf
) - (pFile
->m_pReadPtr
- pFile
->m_ReadBuf
);
1385 memcpy(pFile
->m_ReadBuf
, pFile
->m_pReadPtr
, Bytes
);
1386 pFile
->m_pReadPtr
= pFile
->m_ReadBuf
;
1388 Free
= sizeof(pFile
->m_ReadBuf
) - Bytes
;
1390 if ((Max
= read(pFile
->m_Handle
, &pFile
->m_ReadBuf
[Bytes
], Free
)) < 0)
1392 OSL_TRACE("read failed '%s'",strerror(errno
));
1395 rtl_freeMemory( pLine
);
1402 if ((Max
== 0) && ! pLine
)
1405 pFile
->m_ReadBuf
[Bytes
+ Max
] = '\0';
1409 for (pChr
= pFile
->m_pReadPtr
;
1410 (*pChr
!= '\n') && (*pChr
!= '\r') && (*pChr
!= '\0') &&
1411 (pChr
< (pFile
->m_ReadBuf
+ sizeof(pFile
->m_ReadBuf
) - 1));
1414 Max
= pChr
- pFile
->m_pReadPtr
;
1415 pNewLine
= (sal_Char
*) rtl_allocateMemory( nLineBytes
+ Max
+ 1 );
1418 memcpy( pNewLine
, pLine
, nLineBytes
);
1419 rtl_freeMemory( pLine
);
1421 memcpy(pNewLine
+nLineBytes
, pFile
->m_pReadPtr
, Max
);
1423 pNewLine
[ nLineBytes
] = 0;
1426 if (pChr
< (pFile
->m_ReadBuf
+ sizeof(pFile
->m_ReadBuf
) - 1))
1430 if ((pChr
[0] == '\r') && (pChr
[1] == '\n'))
1436 if ((pChr
< (pFile
->m_ReadBuf
+ sizeof(pFile
->m_ReadBuf
))) &&
1438 pChr
= pFile
->m_ReadBuf
+ sizeof(pFile
->m_ReadBuf
);
1440 /* setting Max to -1 indicates terminating read loop */
1444 pFile
->m_pReadPtr
= pChr
;
1451 static sal_Bool
OslProfile_putLine(osl_TFile
* pFile
, const sal_Char
*pszLine
)
1453 unsigned int Len
= strlen(pszLine
);
1455 #ifdef DEBUG_OSL_PROFILE
1459 if ( pFile
== 0 || pFile
->m_Handle
< 0 )
1464 if ( pFile
->m_pWriteBuf
== 0 )
1466 pFile
->m_pWriteBuf
= (sal_Char
*) malloc(Len
+3);
1467 pFile
->m_nWriteBufLen
= Len
+3;
1468 pFile
->m_nWriteBufFree
= Len
+3;
1472 if ( pFile
->m_nWriteBufFree
<= Len
+ 3 )
1476 pTmp
=(sal_Char
*) realloc(pFile
->m_pWriteBuf
,( ( pFile
->m_nWriteBufLen
+ Len
) * 2) );
1481 pFile
->m_pWriteBuf
= pTmp
;
1482 pFile
->m_nWriteBufFree
= pFile
->m_nWriteBufFree
+ pFile
->m_nWriteBufLen
+ ( 2 * Len
);
1483 pFile
->m_nWriteBufLen
= ( pFile
->m_nWriteBufLen
+ Len
) * 2;
1484 memset( (pFile
->m_pWriteBuf
) + ( pFile
->m_nWriteBufLen
- pFile
->m_nWriteBufFree
), 0, pFile
->m_nWriteBufFree
);
1490 memcpy(pFile
->m_pWriteBuf
+ ( pFile
->m_nWriteBufLen
- pFile
->m_nWriteBufFree
),pszLine
,Len
+1);
1491 #ifdef DEBUG_OSL_PROFILE
1492 strLen
= strlen(pFile
->m_pWriteBuf
);
1494 pFile
->m_pWriteBuf
[pFile
->m_nWriteBufLen
- pFile
->m_nWriteBufFree
+ Len
]='\n';
1495 pFile
->m_pWriteBuf
[pFile
->m_nWriteBufLen
- pFile
->m_nWriteBufFree
+ Len
+ 1]='\0';
1497 pFile
->m_nWriteBufFree
-=Len
+1;
1502 /* platform specific end */
1504 static sal_Char
* stripBlanks(sal_Char
* String
, sal_uInt32
* pLen
)
1506 if ( ( pLen
!= NULL
) && ( *pLen
!= 0 ) )
1508 while ((String
[*pLen
- 1] == ' ') || (String
[*pLen
- 1] == '\t'))
1511 while ( (*String
== ' ') || (*String
== '\t') )
1518 while ( (*String
== ' ') || (*String
== '\t') )
1524 static sal_Char
* addLine(osl_TProfileImpl
* pProfile
, const sal_Char
* Line
)
1526 if (pProfile
->m_NoLines
>= pProfile
->m_MaxLines
)
1528 if (pProfile
->m_Lines
== NULL
)
1530 pProfile
->m_MaxLines
= LINES_INI
;
1531 pProfile
->m_Lines
= (sal_Char
**)malloc(pProfile
->m_MaxLines
* sizeof(sal_Char
*));
1532 memset(pProfile
->m_Lines
,0,pProfile
->m_MaxLines
* sizeof(sal_Char
*));
1537 unsigned int oldmax
=pProfile
->m_MaxLines
;
1539 pProfile
->m_MaxLines
+= LINES_ADD
;
1540 pProfile
->m_Lines
= (sal_Char
**)realloc(pProfile
->m_Lines
,
1541 pProfile
->m_MaxLines
* sizeof(sal_Char
*));
1542 for ( idx
= oldmax
; idx
< pProfile
->m_MaxLines
; ++idx
)
1544 pProfile
->m_Lines
[idx
]=0;
1548 if (pProfile
->m_Lines
== NULL
)
1550 pProfile
->m_NoLines
= 0;
1551 pProfile
->m_MaxLines
= 0;
1557 if ( pProfile
->m_Lines
!= 0 && pProfile
->m_Lines
[pProfile
->m_NoLines
] != 0 )
1559 free(pProfile
->m_Lines
[pProfile
->m_NoLines
]);
1561 pProfile
->m_Lines
[pProfile
->m_NoLines
++] = strdup(Line
);
1563 return (pProfile
->m_Lines
[pProfile
->m_NoLines
- 1]);
1566 static sal_Char
* insertLine(osl_TProfileImpl
* pProfile
, const sal_Char
* Line
, sal_uInt32 LineNo
)
1568 if (pProfile
->m_NoLines
>= pProfile
->m_MaxLines
)
1570 if (pProfile
->m_Lines
== NULL
)
1572 pProfile
->m_MaxLines
= LINES_INI
;
1573 pProfile
->m_Lines
= (sal_Char
**)malloc(pProfile
->m_MaxLines
* sizeof(sal_Char
*));
1574 memset(pProfile
->m_Lines
,0,pProfile
->m_MaxLines
* sizeof(sal_Char
*));
1578 pProfile
->m_MaxLines
+= LINES_ADD
;
1579 pProfile
->m_Lines
= (sal_Char
**)realloc(pProfile
->m_Lines
,
1580 pProfile
->m_MaxLines
* sizeof(sal_Char
*));
1582 memset(&pProfile
->m_Lines
[pProfile
->m_NoLines
],
1584 (pProfile
->m_MaxLines
- pProfile
->m_NoLines
- 1) * sizeof(sal_Char
*));
1587 if (pProfile
->m_Lines
== NULL
)
1589 pProfile
->m_NoLines
= 0;
1590 pProfile
->m_MaxLines
= 0;
1595 LineNo
= LineNo
> pProfile
->m_NoLines
? pProfile
->m_NoLines
: LineNo
;
1597 if (LineNo
< pProfile
->m_NoLines
)
1600 osl_TProfileSection
* pSec
;
1602 memmove(&pProfile
->m_Lines
[LineNo
+ 1], &pProfile
->m_Lines
[LineNo
],
1603 (pProfile
->m_NoLines
- LineNo
) * sizeof(sal_Char
*));
1606 /* adjust line references */
1607 for (i
= 0; i
< pProfile
->m_NoSections
; i
++)
1609 pSec
= &pProfile
->m_Sections
[i
];
1611 if (pSec
->m_Line
>= LineNo
)
1614 for (n
= 0; n
< pSec
->m_NoEntries
; n
++)
1615 if (pSec
->m_Entries
[n
].m_Line
>= LineNo
)
1616 pSec
->m_Entries
[n
].m_Line
++;
1620 pProfile
->m_NoLines
++;
1622 pProfile
->m_Lines
[LineNo
] = strdup(Line
);
1624 return (pProfile
->m_Lines
[LineNo
]);
1627 static void removeLine(osl_TProfileImpl
* pProfile
, sal_uInt32 LineNo
)
1629 if (LineNo
< pProfile
->m_NoLines
)
1631 free(pProfile
->m_Lines
[LineNo
]);
1632 pProfile
->m_Lines
[LineNo
]=0;
1633 if (pProfile
->m_NoLines
- LineNo
> 1)
1636 osl_TProfileSection
* pSec
;
1638 memmove(&pProfile
->m_Lines
[LineNo
], &pProfile
->m_Lines
[LineNo
+ 1],
1639 (pProfile
->m_NoLines
- LineNo
- 1) * sizeof(sal_Char
*));
1641 memset(&pProfile
->m_Lines
[pProfile
->m_NoLines
- 1],
1643 (pProfile
->m_MaxLines
- pProfile
->m_NoLines
) * sizeof(sal_Char
*));
1645 /* adjust line references */
1646 for (i
= 0; i
< pProfile
->m_NoSections
; i
++)
1648 pSec
= &pProfile
->m_Sections
[i
];
1650 if (pSec
->m_Line
> LineNo
)
1653 for (n
= 0; n
< pSec
->m_NoEntries
; n
++)
1654 if (pSec
->m_Entries
[n
].m_Line
> LineNo
)
1655 pSec
->m_Entries
[n
].m_Line
--;
1660 pProfile
->m_Lines
[LineNo
] = 0;
1663 pProfile
->m_NoLines
--;
1669 static void setEntry(osl_TProfileImpl
* pProfile
, osl_TProfileSection
* pSection
,
1670 sal_uInt32 NoEntry
, sal_uInt32 Line
,
1671 sal_Char
* Entry
, sal_uInt32 Len
)
1673 Entry
= stripBlanks(Entry
, &Len
);
1674 pSection
->m_Entries
[NoEntry
].m_Line
= Line
;
1675 pSection
->m_Entries
[NoEntry
].m_Offset
= Entry
- pProfile
->m_Lines
[Line
];
1676 pSection
->m_Entries
[NoEntry
].m_Len
= Len
;
1681 static sal_Bool
addEntry(osl_TProfileImpl
* pProfile
, osl_TProfileSection
*pSection
,
1682 int Line
, sal_Char
* Entry
, sal_uInt32 Len
)
1684 if (pSection
!= NULL
)
1686 if (pSection
->m_NoEntries
>= pSection
->m_MaxEntries
)
1688 if (pSection
->m_Entries
== NULL
)
1690 pSection
->m_MaxEntries
= ENTRIES_INI
;
1691 pSection
->m_Entries
= (osl_TProfileEntry
*)malloc(
1692 pSection
->m_MaxEntries
* sizeof(osl_TProfileEntry
));
1696 pSection
->m_MaxEntries
+= ENTRIES_ADD
;
1697 pSection
->m_Entries
= (osl_TProfileEntry
*)realloc(pSection
->m_Entries
,
1698 pSection
->m_MaxEntries
* sizeof(osl_TProfileEntry
));
1701 if (pSection
->m_Entries
== NULL
)
1703 pSection
->m_NoEntries
= 0;
1704 pSection
->m_MaxEntries
= 0;
1709 pSection
->m_NoEntries
++;
1711 Entry
= stripBlanks(Entry
, &Len
);
1712 setEntry(pProfile
, pSection
, pSection
->m_NoEntries
- 1, Line
,
1721 static void removeEntry(osl_TProfileSection
*pSection
, sal_uInt32 NoEntry
)
1723 if (NoEntry
< pSection
->m_NoEntries
)
1725 if (pSection
->m_NoEntries
- NoEntry
> 1)
1727 memmove(&pSection
->m_Entries
[NoEntry
],
1728 &pSection
->m_Entries
[NoEntry
+ 1],
1729 (pSection
->m_NoEntries
- NoEntry
- 1) * sizeof(osl_TProfileEntry
));
1730 pSection
->m_Entries
[pSection
->m_NoEntries
- 1].m_Line
=0;
1731 pSection
->m_Entries
[pSection
->m_NoEntries
- 1].m_Offset
=0;
1732 pSection
->m_Entries
[pSection
->m_NoEntries
- 1].m_Len
=0;
1735 pSection
->m_NoEntries
--;
1741 static sal_Bool
addSection(osl_TProfileImpl
* pProfile
, int Line
, const sal_Char
* Section
, sal_uInt32 Len
)
1743 if (pProfile
->m_NoSections
>= pProfile
->m_MaxSections
)
1745 if (pProfile
->m_Sections
== NULL
)
1747 pProfile
->m_MaxSections
= SECTIONS_INI
;
1748 pProfile
->m_Sections
= (osl_TProfileSection
*)malloc(pProfile
->m_MaxSections
* sizeof(osl_TProfileSection
));
1749 memset(pProfile
->m_Sections
,0,pProfile
->m_MaxSections
* sizeof(osl_TProfileSection
));
1754 unsigned int oldmax
=pProfile
->m_MaxSections
;
1756 pProfile
->m_MaxSections
+= SECTIONS_ADD
;
1757 pProfile
->m_Sections
= (osl_TProfileSection
*)realloc(pProfile
->m_Sections
,
1758 pProfile
->m_MaxSections
* sizeof(osl_TProfileSection
));
1759 for ( idx
= oldmax
; idx
< pProfile
->m_MaxSections
; ++idx
)
1761 pProfile
->m_Sections
[idx
].m_Entries
=0;
1765 if (pProfile
->m_Sections
== NULL
)
1767 pProfile
->m_NoSections
= 0;
1768 pProfile
->m_MaxSections
= 0;
1773 pProfile
->m_NoSections
++;
1775 if ( pProfile
->m_Sections
[(pProfile
->m_NoSections
) - 1].m_Entries
!= 0 )
1777 free(pProfile
->m_Sections
[(pProfile
->m_NoSections
) - 1].m_Entries
);
1779 pProfile
->m_Sections
[pProfile
->m_NoSections
- 1].m_Entries
= NULL
;
1780 pProfile
->m_Sections
[pProfile
->m_NoSections
- 1].m_NoEntries
= 0;
1781 pProfile
->m_Sections
[pProfile
->m_NoSections
- 1].m_MaxEntries
= 0;
1783 pProfile
->m_Sections
[pProfile
->m_NoSections
- 1].m_Line
= Line
;
1784 pProfile
->m_Sections
[pProfile
->m_NoSections
- 1].m_Offset
= Section
- pProfile
->m_Lines
[Line
];
1785 pProfile
->m_Sections
[pProfile
->m_NoSections
- 1].m_Len
= Len
;
1790 static void removeSection(osl_TProfileImpl
* pProfile
, osl_TProfileSection
*pSection
)
1794 if ((Section
= pSection
- pProfile
->m_Sections
) < pProfile
->m_NoSections
)
1796 free (pSection
->m_Entries
);
1797 pSection
->m_Entries
=0;
1798 if (pProfile
->m_NoSections
- Section
> 1)
1800 memmove(&pProfile
->m_Sections
[Section
], &pProfile
->m_Sections
[Section
+ 1],
1801 (pProfile
->m_NoSections
- Section
- 1) * sizeof(osl_TProfileSection
));
1803 memset(&pProfile
->m_Sections
[pProfile
->m_NoSections
- 1],
1805 (pProfile
->m_MaxSections
- pProfile
->m_NoSections
) * sizeof(osl_TProfileSection
));
1806 pProfile
->m_Sections
[pProfile
->m_NoSections
- 1].m_Entries
= 0;
1810 pSection
->m_Entries
= 0;
1813 pProfile
->m_NoSections
--;
1819 static osl_TProfileSection
* findEntry(osl_TProfileImpl
* pProfile
, const sal_Char
* Section
,
1820 const sal_Char
* Entry
, sal_uInt32
*pNoEntry
)
1822 static sal_uInt32 Sect
= 0;
1825 const sal_Char
* pStr
;
1826 osl_TProfileSection
* pSec
=0;
1828 Len
= strlen(Section
);
1832 for (i
= 0; i
< pProfile
->m_NoSections
; i
++)
1834 n
%= pProfile
->m_NoSections
;
1835 pSec
= &pProfile
->m_Sections
[n
];
1836 if ((Len
== pSec
->m_Len
) &&
1837 (strncasecmp(Section
, &pProfile
->m_Lines
[pSec
->m_Line
][pSec
->m_Offset
], pSec
->m_Len
)
1845 if (i
< pProfile
->m_NoSections
)
1847 Len
= strlen(Entry
);
1849 *pNoEntry
= pSec
->m_NoEntries
;
1851 for (i
= 0; i
< pSec
->m_NoEntries
; i
++)
1853 pStr
= &pProfile
->m_Lines
[pSec
->m_Entries
[i
].m_Line
]
1854 [pSec
->m_Entries
[i
].m_Offset
];
1855 if ((Len
== pSec
->m_Entries
[i
].m_Len
) &&
1856 (strncasecmp(Entry
, pStr
, pSec
->m_Entries
[i
].m_Len
)
1870 static sal_Bool
loadProfile(osl_TFile
* pFile
, osl_TProfileImpl
* pProfile
)
1877 sal_Char
* bWasAdded
= NULL
;
1879 pProfile
->m_NoLines
= 0;
1880 pProfile
->m_NoSections
= 0;
1887 if ( pProfile
== 0 )
1892 OSL_VERIFY(OslProfile_rewindFile(pFile
, sal_False
));
1894 while ( ( pLine
=OslProfile_getLine(pFile
) ) != 0 )
1896 bWasAdded
= addLine( pProfile
, pLine
);
1897 rtl_freeMemory( pLine
);
1898 OSL_ASSERT(bWasAdded
);
1903 for (i
= 0; i
< pProfile
->m_NoLines
; i
++)
1905 pStr
= (sal_Char
*)stripBlanks(pProfile
->m_Lines
[i
], NULL
);
1907 if ((*pStr
== '\0') || (*pStr
== ';'))
1910 if ((*pStr
!= '[') || ((pChar
= strrchr(pStr
, ']')) == NULL
) ||
1911 ((pChar
- pStr
) <= 2))
1915 if (pProfile
->m_NoSections
< 1)
1918 if ((pChar
= strchr(pStr
, '=')) == NULL
)
1919 pChar
= pStr
+ strlen(pStr
);
1921 if (! addEntry(pProfile
, &pProfile
->m_Sections
[pProfile
->m_NoSections
- 1],
1922 i
, pStr
, pChar
- pStr
))
1933 if (! addSection(pProfile
, i
, pStr
+ 1, pChar
- pStr
- 1))
1945 static sal_Bool
storeProfile(osl_TProfileImpl
* pProfile
, sal_Bool bCleanup
)
1947 #ifdef TRACE_OSL_PROFILE
1948 OSL_TRACE("In storeProfile");
1951 if (pProfile
->m_Lines
!= NULL
)
1953 if (pProfile
->m_Flags
& FLG_MODIFIED
)
1957 osl_TFile
* pTmpFile
= osl_openTmpProfileImpl(pProfile
);
1959 if ( pTmpFile
== 0 )
1964 OSL_VERIFY(OslProfile_rewindFile(pTmpFile
, sal_True
));
1966 for ( i
= 0 ; i
< pProfile
->m_NoLines
; i
++ )
1968 OSL_VERIFY(OslProfile_putLine(pTmpFile
, pProfile
->m_Lines
[i
]));
1971 if ( ! writeProfileImpl(pTmpFile
) )
1973 if ( pTmpFile
->m_pWriteBuf
!= 0 )
1975 free(pTmpFile
->m_pWriteBuf
);
1978 pTmpFile
->m_pWriteBuf
=0;
1979 pTmpFile
->m_nWriteBufLen
=0;
1980 pTmpFile
->m_nWriteBufFree
=0;
1982 #ifdef TRACE_OSL_PROFILE
1983 OSL_TRACE("Out storeProfile [not flushed]");
1985 closeFileImpl(pTmpFile
,pProfile
->m_Flags
);
1990 pProfile
->m_Flags
&= ~FLG_MODIFIED
;
1992 closeFileImpl(pProfile
->m_pFile
,pProfile
->m_Flags
);
1993 closeFileImpl(pTmpFile
,pProfile
->m_Flags
);
1995 osl_ProfileSwapProfileNames(pProfile
);
1997 pProfile
->m_pFile
= openFileImpl(pProfile
->m_FileName
,pProfile
->m_Flags
);
2003 while (pProfile
->m_NoLines
> 0)
2004 removeLine(pProfile
, pProfile
->m_NoLines
- 1);
2006 free(pProfile
->m_Lines
);
2007 pProfile
->m_Lines
= NULL
;
2008 pProfile
->m_NoLines
= 0;
2009 pProfile
->m_MaxLines
= 0;
2011 while (pProfile
->m_NoSections
> 0)
2012 removeSection(pProfile
, &pProfile
->m_Sections
[pProfile
->m_NoSections
- 1]);
2014 free(pProfile
->m_Sections
);
2015 pProfile
->m_Sections
= NULL
;
2016 pProfile
->m_NoSections
= 0;
2017 pProfile
->m_MaxSections
= 0;
2021 #ifdef TRACE_OSL_PROFILE
2022 OSL_TRACE("Out storeProfile [ok]");
2028 static osl_TFile
* osl_openTmpProfileImpl(osl_TProfileImpl
* pProfile
)
2031 sal_Char
* pszExtension
= "tmp";
2032 sal_Char pszTmpName
[PATH_MAX
];
2033 oslProfileOption PFlags
=0;
2035 pszTmpName
[0] = '\0';
2037 /* generate tmp profilename */
2038 osl_ProfileGenerateExtension(pProfile
->m_FileName
,pszExtension
,pszTmpName
);
2040 if ( pszTmpName
[0] == 0 )
2045 if ( ! ( pProfile
->m_Flags
& osl_Profile_READLOCK
) )
2047 PFlags
|= osl_Profile_WRITELOCK
;
2050 /* open this file */
2051 pFile
= openFileImpl(pszTmpName
,pProfile
->m_Flags
| PFlags
);
2054 /* return new pFile */
2058 static sal_Bool
osl_ProfileSwapProfileNames(osl_TProfileImpl
* pProfile
)
2060 sal_Bool bRet
= sal_False
;
2062 sal_Char pszBakFile
[PATH_MAX
];
2063 sal_Char pszTmpFile
[PATH_MAX
];
2064 sal_Char pszIniFile
[PATH_MAX
];
2066 pszBakFile
[0] = '\0';
2067 pszTmpFile
[0] = '\0';
2068 pszIniFile
[0] = '\0';
2070 osl_ProfileGenerateExtension(pProfile
->m_FileName
,"bak",pszBakFile
);
2072 strcpy(pszIniFile
,pProfile
->m_FileName
);
2074 osl_ProfileGenerateExtension(pProfile
->m_FileName
,"tmp",pszTmpFile
);
2077 unlink( pszBakFile
);
2079 /* rename ini bak */
2080 rename( pszIniFile
, pszBakFile
);
2082 /* rename tmp ini */
2083 rename( pszTmpFile
, pszIniFile
);
2089 static void osl_ProfileGenerateExtension(sal_Char
* pszFileName
, sal_Char
* pszExtension
, sal_Char
* pszTmpName
)
2092 strcpy(pszTmpName
,pszFileName
);
2093 strcat(pszTmpName
,".");
2094 strcat(pszTmpName
,pszExtension
);
2100 static osl_TProfileImpl
* acquireProfile(oslProfile Profile
, sal_Bool bWriteable
)
2102 osl_TProfileImpl
* pProfile
= (osl_TProfileImpl
*)Profile
;
2103 oslProfileOption PFlags
=0;
2107 PFlags
= osl_Profile_DEFAULT
| osl_Profile_WRITELOCK
;
2111 PFlags
= osl_Profile_DEFAULT
;
2115 if (pProfile
== NULL
)
2117 #ifdef DEBUG_OSL_PROFILE
2118 OSL_TRACE("AUTOOPEN MODE");
2121 if ( ( pProfile
= (osl_TProfileImpl
*) osl_openProfile(0, PFlags
) ) != NULL
)
2123 pProfile
->m_Flags
|= FLG_AUTOOPEN
;
2128 #ifdef DEBUG_OSL_PROFILE
2129 OSL_TRACE("try to acquire");
2132 if (! (pProfile
->m_Flags
& osl_Profile_SYSTEM
))
2134 if (! (pProfile
->m_Flags
& (osl_Profile_READLOCK
| osl_Profile_WRITELOCK
| osl_Profile_FLUSHWRITE
)))
2138 #ifdef DEBUG_OSL_PROFILE
2139 OSL_TRACE("Profile acquire DEFAULT MODE");
2141 if (! (pProfile
->m_pFile
= openFileImpl(pProfile
->m_FileName
, pProfile
->m_Flags
| PFlags
)))
2144 Stamp
= OslProfile_getFileStamp(pProfile
->m_pFile
);
2146 if (memcmp(&Stamp
, &(pProfile
->m_Stamp
), sizeof(osl_TStamp
)))
2148 sal_Bool bRet
=sal_False
;
2150 pProfile
->m_Stamp
= Stamp
;
2152 bRet
=loadProfile(pProfile
->m_pFile
, pProfile
);
2159 #ifdef DEBUG_OSL_PROFILE
2160 OSL_TRACE("Profile acquire READ/WRITELOCK MODE");
2162 /* A readlock file could not be written */
2163 if ((pProfile
->m_Flags
& osl_Profile_READLOCK
) && bWriteable
)
2174 static sal_Bool
releaseProfile(osl_TProfileImpl
* pProfile
)
2176 #ifdef TRACE_OSL_PROFILE
2177 OSL_TRACE("In releaseProfile");
2180 if ( pProfile
== 0 )
2182 #ifdef TRACE_OSL_PROFILE
2183 OSL_TRACE("Out releaseProfile [profile==0]");
2188 if (pProfile
->m_Flags
& FLG_AUTOOPEN
)
2190 #ifdef TRACE_OSL_PROFILE
2191 OSL_TRACE("Out releaseProfile [AUTOOPEN]");
2193 return (osl_closeProfile((oslProfile
)pProfile
));
2197 #ifdef DEBUG_OSL_PROFILE
2198 OSL_TRACE("DEFAULT MODE");
2200 if (! (pProfile
->m_Flags
& (osl_Profile_READLOCK
| osl_Profile_WRITELOCK
| osl_Profile_FLUSHWRITE
)))
2202 if (pProfile
->m_Flags
& FLG_MODIFIED
)
2204 sal_Bool bRet
=storeProfile(pProfile
, sal_False
);
2209 closeFileImpl(pProfile
->m_pFile
,pProfile
->m_Flags
);
2210 pProfile
->m_pFile
= NULL
;
2214 #ifdef TRACE_OSL_PROFILE
2215 OSL_TRACE("Out releaseProfile [ok]");
2220 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */