1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: profile.c,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
34 #include <osl/diagnose.h>
35 #include <osl/profile.h>
36 #include <osl/process.h>
37 #include <osl/thread.h>
38 #include <rtl/alloc.h>
43 #define SECTIONS_INI 5
44 #define SECTIONS_ADD 3
49 #define STR_INI_EXTENSION "rc"
50 #define STR_INI_METAHOME "?~"
51 #define STR_INI_METASYS "?$"
52 #define STR_INI_METACFG "?^"
53 #define STR_INI_METAINS "?#"
55 #define STR_INI_BOOLYES "yes"
56 #define STR_INI_BOOLON "on"
57 #define STR_INI_BOOLONE "1"
58 #define STR_INI_BOOLNO "no"
59 #define STR_INI_BOOLOFF "off"
60 #define STR_INI_BOOLZERO "0"
62 #define FLG_USER 0x00FF
63 #define FLG_AUTOOPEN 0x0100
64 #define FLG_MODIFIED 0x0200
66 #define SVERSION_LOCATION STR_INI_METACFG
67 #define SVERSION_FALLBACK STR_INI_METASYS
68 #define SVERSION_NAME "sversion"
69 #define SVERSION_SECTION "Versions"
70 #define SVERSION_SOFFICE "StarOffice"
71 #define SVERSION_PROFILE "sofficerc"
72 #define SVERSION_OPTION "userid:"
73 #define SVERSION_DIRS { "bin", "program" }
74 #define SVERSION_USER "user"
76 #define DEFAULT_PMODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)
78 #define _BUILD_STR_(n) # n
79 #define BUILD_STR(n) _BUILD_STR_(n)
82 /*#define DEBUG_OSL_PROFILE*/
83 /*#define TRACE_OSL_PROFILE*/
85 /*****************************************************************************/
86 /* Data Type Definition */
87 /*****************************************************************************/
89 typedef time_t osl_TStamp
;
91 typedef enum _osl_TLockMode
93 un_lock
, read_lock
, write_lock
96 typedef struct _osl_TFile
100 sal_Char m_ReadBuf
[512];
101 sal_Char
* m_pWriteBuf
;
102 sal_uInt32 m_nWriteBufLen
;
103 sal_uInt32 m_nWriteBufFree
;
106 typedef struct _osl_TProfileEntry
113 typedef struct _osl_TProfileSection
118 sal_uInt32 m_NoEntries
;
119 sal_uInt32 m_MaxEntries
;
120 osl_TProfileEntry
* m_Entries
;
121 } osl_TProfileSection
;
125 Profile-data structure hidden behind oslProfile:
127 typedef struct _osl_TProfileImpl
132 sal_Char m_FileName
[PATH_MAX
+ 1];
133 sal_uInt32 m_NoLines
;
134 sal_uInt32 m_MaxLines
;
135 sal_uInt32 m_NoSections
;
136 sal_uInt32 m_MaxSections
;
138 osl_TProfileSection
* m_Sections
;
139 pthread_mutex_t m_AccessLock
;
144 /*****************************************************************************/
145 /* Static Module Function Declarations */
146 /*****************************************************************************/
148 static osl_TFile
* openFileImpl(const sal_Char
* pszFilename
, oslProfileOption ProfileFlags
);
149 static osl_TStamp
closeFileImpl(osl_TFile
* pFile
, oslProfileOption Flags
);
150 static sal_Bool
OslProfile_lockFile(const osl_TFile
* pFile
, osl_TLockMode eMode
);
151 static sal_Bool
OslProfile_rewindFile(osl_TFile
* pFile
, sal_Bool bTruncate
);
152 static osl_TStamp
OslProfile_getFileStamp(osl_TFile
* pFile
);
154 static sal_Char
* OslProfile_getLine(osl_TFile
* pFile
);
155 static sal_Bool
OslProfile_putLine(osl_TFile
* pFile
, const sal_Char
*pszLine
);
156 static sal_Char
* stripBlanks(sal_Char
* String
, sal_uInt32
* pLen
);
157 static sal_Char
* addLine(osl_TProfileImpl
* pProfile
, const sal_Char
* Line
);
158 static sal_Char
* insertLine(osl_TProfileImpl
* pProfile
, const sal_Char
* Line
, sal_uInt32 LineNo
);
159 static void removeLine(osl_TProfileImpl
* pProfile
, sal_uInt32 LineNo
);
160 static void setEntry(osl_TProfileImpl
* pProfile
, osl_TProfileSection
* pSection
,
161 sal_uInt32 NoEntry
, sal_uInt32 Line
,
162 sal_Char
* Entry
, sal_uInt32 Len
);
163 static sal_Bool
addEntry(osl_TProfileImpl
* pProfile
, osl_TProfileSection
*pSection
,
164 int Line
, sal_Char
* Entry
, sal_uInt32 Len
);
165 static void removeEntry(osl_TProfileSection
*pSection
, sal_uInt32 NoEntry
);
166 static sal_Bool
addSection(osl_TProfileImpl
* pProfile
, int Line
, const sal_Char
* Section
, sal_uInt32 Len
);
167 static void removeSection(osl_TProfileImpl
* pProfile
, osl_TProfileSection
*pSection
);
168 static osl_TProfileSection
* findEntry(osl_TProfileImpl
* pProfile
, const sal_Char
* Section
,
169 const sal_Char
* Entry
, sal_uInt32
*pNoEntry
);
170 static sal_Bool
loadProfile(osl_TFile
* pFile
, osl_TProfileImpl
* pProfile
);
171 static sal_Bool
storeProfile(osl_TProfileImpl
* pProfile
, sal_Bool bCleanup
);
172 static osl_TProfileImpl
* acquireProfile(oslProfile Profile
, sal_Bool bWriteable
);
173 static sal_Bool
releaseProfile(osl_TProfileImpl
* pProfile
);
175 static sal_Bool
writeProfileImpl (osl_TFile
* pFile
);
176 static osl_TFile
* osl_openTmpProfileImpl(osl_TProfileImpl
*);
177 static sal_Bool
osl_ProfileSwapProfileNames(osl_TProfileImpl
*);
178 static void osl_ProfileGenerateExtension(sal_Char
* pszFileName
, sal_Char
* pszExtension
, sal_Char
* pszTmpName
);
179 static oslProfile SAL_CALL
osl_psz_openProfile(const sal_Char
*pszProfileName
, oslProfileOption Flags
);
181 /* implemented in file.c */
182 extern oslFileError
FileURLToPath( char *, size_t, rtl_uString
* );
184 /*****************************************************************************/
185 /* Exported Module Functions */
186 /*****************************************************************************/
187 oslProfile SAL_CALL
osl_openProfile(rtl_uString
*ustrProfileName
, oslProfileOption Options
)
189 char profilePath
[PATH_MAX
] = "";
191 if ( ustrProfileName
!= 0 && ustrProfileName
->buffer
[0] != 0 )
192 FileURLToPath( profilePath
, PATH_MAX
, ustrProfileName
);
194 return osl_psz_openProfile( profilePath
,Options
);
198 static oslProfile SAL_CALL
osl_psz_openProfile(const sal_Char
*pszProfileName
, oslProfileOption Flags
)
201 osl_TProfileImpl
* pProfile
;
202 sal_Char Filename
[PATH_MAX
];
203 sal_Bool bRet
= sal_False
;
207 #ifdef TRACE_OSL_PROFILE
208 OSL_TRACE("In osl_openProfile\n");
211 #ifdef DEBUG_OSL_PROFILE
212 Flags
=osl_Profile_FLUSHWRITE
;
214 OSL_TRACE("opening '%s'\n",pszProfileName
);
215 if ( Flags
== osl_Profile_DEFAULT
)
217 OSL_TRACE("with osl_Profile_DEFAULT\n");
219 if ( Flags
& osl_Profile_SYSTEM
)
221 OSL_TRACE("with osl_Profile_SYSTEM\n");
223 if ( Flags
& osl_Profile_READLOCK
)
225 OSL_TRACE("with osl_Profile_READLOCK\n");
227 if ( Flags
& osl_Profile_WRITELOCK
)
229 OSL_TRACE("with osl_Profile_WRITELOCK\n");
231 if ( Flags
& osl_Profile_FLUSHWRITE
)
233 OSL_TRACE("with osl_Profile_FLUSHWRITE\n");
238 if ( ( pFile
= openFileImpl(pszProfileName
, Flags
) ) == NULL
)
240 #ifdef TRACE_OSL_PROFILE
241 OSL_TRACE("Out osl_openProfile [not opened]\n");
247 pProfile
= (osl_TProfileImpl
*)calloc(1, sizeof(osl_TProfileImpl
));
254 pProfile
->m_Flags
= Flags
& FLG_USER
;
256 if ( Flags
& ( osl_Profile_READLOCK
| osl_Profile_WRITELOCK
| osl_Profile_FLUSHWRITE
) )
258 pProfile
->m_pFile
= pFile
;
261 pthread_mutex_init(&(pProfile
->m_AccessLock
),PTHREAD_MUTEXATTR_DEFAULT
);
262 pProfile
->m_bIsValid
=sal_True
;
264 pProfile
->m_Stamp
= OslProfile_getFileStamp(pFile
);
265 bRet
=loadProfile(pFile
, pProfile
);
268 /* #109261# using osl profiles is deprecated */
269 /* OSL_VERIFY(NULL != realpath(pszProfileName, pProfile->m_FileName)); */
270 realpath(pszProfileName
, pProfile
->m_FileName
);
272 if (pProfile
->m_pFile
== NULL
)
273 closeFileImpl(pFile
,pProfile
->m_Flags
);
275 #ifdef TRACE_OSL_PROFILE
276 OSL_TRACE("Out osl_openProfile [ok]\n");
281 sal_Bool SAL_CALL
osl_closeProfile(oslProfile Profile
)
283 osl_TProfileImpl
* pProfile
= (osl_TProfileImpl
*)Profile
;
284 sal_Bool bRet
= sal_False
;
286 #ifdef TRACE_OSL_PROFILE
287 OSL_TRACE("In osl_closeProfile\n");
292 #ifdef TRACE_OSL_PROFILE
293 OSL_TRACE("Out osl_closeProfile [profile==0]\n");
298 pthread_mutex_lock(&(pProfile
->m_AccessLock
));
300 if ( pProfile
->m_bIsValid
== sal_False
)
302 OSL_ASSERT(pProfile
->m_bIsValid
);
303 pthread_mutex_unlock(&(pProfile
->m_AccessLock
));
304 #ifdef TRACE_OSL_PROFILE
305 OSL_TRACE("Out osl_closeProfile [not valid]\n");
310 pProfile
->m_bIsValid
=sal_False
;
312 if ( ! ( pProfile
->m_Flags
& osl_Profile_READLOCK
) && ( pProfile
->m_Flags
& FLG_MODIFIED
) )
314 pProfile
= acquireProfile(Profile
,sal_True
);
318 bRet
=storeProfile(pProfile
, sal_True
);
324 pProfile
= acquireProfile(Profile
,sal_False
);
330 pthread_mutex_unlock(&(pProfile
->m_AccessLock
));
331 #ifdef TRACE_OSL_PROFILE
332 OSL_TRACE("Out osl_closeProfile [pProfile==0]\n");
337 if (pProfile
->m_pFile
!= NULL
)
338 closeFileImpl(pProfile
->m_pFile
,pProfile
->m_Flags
);
340 pProfile
->m_pFile
= NULL
;
341 pProfile
->m_FileName
[0] = '\0';
343 /* release whole profile data types memory */
344 if ( pProfile
->m_NoLines
> 0)
347 if ( pProfile
->m_Lines
!= 0 )
349 for ( idx
= 0 ; idx
< pProfile
->m_NoLines
; ++idx
)
351 if ( pProfile
->m_Lines
[idx
] != 0 )
353 free(pProfile
->m_Lines
[idx
]);
354 pProfile
->m_Lines
[idx
]=0;
357 free(pProfile
->m_Lines
);
360 if ( pProfile
->m_Sections
!= 0 )
362 /*osl_TProfileSection* pSections=pProfile->m_Sections;*/
363 for ( idx
= 0 ; idx
< pProfile
->m_NoSections
; ++idx
)
365 if ( pProfile
->m_Sections
[idx
].m_Entries
!= 0 )
367 free(pProfile
->m_Sections
[idx
].m_Entries
);
368 pProfile
->m_Sections
[idx
].m_Entries
=0;
371 free(pProfile
->m_Sections
);
372 pProfile
->m_Sections
=0;
376 pthread_mutex_unlock(&(pProfile
->m_AccessLock
));
378 pthread_mutex_destroy(&(pProfile
->m_AccessLock
));
382 #ifdef TRACE_OSL_PROFILE
383 OSL_TRACE("Out osl_closeProfile [ok]\n");
389 sal_Bool SAL_CALL
osl_flushProfile(oslProfile Profile
)
391 osl_TProfileImpl
* pProfile
= (osl_TProfileImpl
*) Profile
;
393 sal_Bool bRet
= sal_False
;
395 #ifdef TRACE_OSL_PROFILE
396 OSL_TRACE("In osl_flushProfile()\n");
401 #ifdef TRACE_OSL_PROFILE
402 OSL_TRACE("Out osl_flushProfile() [pProfile == 0]\n");
407 pthread_mutex_lock(&(pProfile
->m_AccessLock
));
409 if ( pProfile
->m_bIsValid
== sal_False
)
411 OSL_ASSERT(pProfile
->m_bIsValid
);
412 pthread_mutex_unlock(&(pProfile
->m_AccessLock
));
413 #ifdef TRACE_OSL_PROFILE
414 OSL_TRACE("Out osl_flushProfile [not valid]\n");
419 pFile
= pProfile
->m_pFile
;
420 if ( !( pFile
!= 0 && pFile
->m_Handle
>= 0 ) )
422 pthread_mutex_unlock(&(pProfile
->m_AccessLock
));
423 #ifdef TRACE_OSL_PROFILE
424 OSL_TRACE("Out osl_flushProfile() [invalid file]\n");
429 if ( pProfile
->m_Flags
& FLG_MODIFIED
)
431 #ifdef DEBUG_OSL_PROFILE
432 OSL_TRACE("swapping to storeprofile\n");
434 bRet
= storeProfile(pProfile
,sal_False
);
438 #ifdef TRACE_OSL_PROFILE
439 OSL_TRACE("Out osl_flushProfile() [ok]\n");
441 pthread_mutex_unlock(&(pProfile
->m_AccessLock
));
445 static sal_Bool
writeProfileImpl(osl_TFile
* pFile
)
448 #if OSL_DEBUG_LEVEL > 1
452 #ifdef TRACE_OSL_PROFILE
453 OSL_TRACE("In osl_writeProfileImpl()\n");
456 if ( !( pFile
!= 0 && pFile
->m_Handle
>= 0 ) || ( pFile
->m_pWriteBuf
== 0 ) )
458 #ifdef TRACE_OSL_PROFILE
459 OSL_TRACE("Out osl_writeProfileImpl() [invalid args]\n");
464 #if OSL_DEBUG_LEVEL > 1
465 nLen
=strlen(pFile
->m_pWriteBuf
);
466 OSL_ASSERT(nLen
== (pFile
->m_nWriteBufLen
- pFile
->m_nWriteBufFree
));
469 BytesWritten
= write(pFile
->m_Handle
, pFile
->m_pWriteBuf
, pFile
->m_nWriteBufLen
- pFile
->m_nWriteBufFree
);
471 if ( BytesWritten
<= 0 )
473 OSL_TRACE("write failed '%s'\n",strerror(errno
));
477 #if OSL_DEBUG_LEVEL > 1
479 BytesWritten
>= 0 && SAL_INT_CAST(unsigned int, BytesWritten
) == nLen
);
482 free(pFile
->m_pWriteBuf
);
483 pFile
->m_pWriteBuf
=0;
484 pFile
->m_nWriteBufLen
=0;
485 pFile
->m_nWriteBufFree
=0;
486 #ifdef TRACE_OSL_PROFILE
487 OSL_TRACE("Out osl_writeProfileImpl() [ok]\n");
493 sal_Bool SAL_CALL
osl_readProfileString(oslProfile Profile
,
494 const sal_Char
* pszSection
, const sal_Char
* pszEntry
,
495 sal_Char
* pszString
, sal_uInt32 MaxLen
,
496 const sal_Char
* pszDefault
)
500 osl_TProfileSection
* pSec
;
501 osl_TProfileImpl
* pProfile
=0;
502 osl_TProfileImpl
* pTmpProfile
=0;
503 sal_Bool bRet
= sal_False
;
505 #ifdef TRACE_OSL_PROFILE
506 OSL_TRACE("In osl_readProfileString\n");
509 pTmpProfile
= (osl_TProfileImpl
*) Profile
;
511 if ( pTmpProfile
== 0 )
513 #ifdef TRACE_OSL_PROFILE
514 OSL_TRACE("Out osl_readProfileString [pTmpProfile==0]\n");
519 pthread_mutex_lock(&(pTmpProfile
->m_AccessLock
));
521 if ( pTmpProfile
->m_bIsValid
== sal_False
)
523 OSL_ASSERT(pProfile
->m_bIsValid
);
524 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
525 #ifdef TRACE_OSL_PROFILE
526 OSL_TRACE("Out osl_readProfileString [not valid]\n");
531 pProfile
= acquireProfile(Profile
, sal_False
);
533 if ( pProfile
== NULL
)
535 #ifdef TRACE_OSL_PROFILE
536 OSL_TRACE("Out osl_readProfileString [pProfile==0]\n");
541 if (! (pProfile
->m_Flags
& osl_Profile_SYSTEM
))
543 if (((pSec
= findEntry(pProfile
, pszSection
, pszEntry
, &NoEntry
)) != NULL
) &&
544 (NoEntry
< pSec
->m_NoEntries
) &&
545 ((pStr
= strchr(pProfile
->m_Lines
[pSec
->m_Entries
[NoEntry
].m_Line
],
552 pStr
=(sal_Char
*)pszDefault
;
557 pStr
= stripBlanks(pStr
, NULL
);
558 MaxLen
= (MaxLen
- 1 < strlen(pStr
)) ? (MaxLen
- 1) : strlen(pStr
);
559 pStr
= stripBlanks(pStr
, &MaxLen
);
560 strncpy(pszString
, pStr
, MaxLen
);
561 pszString
[MaxLen
] = '\0';
565 { /* not implemented */ }
568 bRet
=releaseProfile(pProfile
);
573 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
574 #ifdef TRACE_OSL_PROFILE
575 OSL_TRACE("Out osl_readProfileString [pStr==0]\n");
580 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
582 #ifdef TRACE_OSL_PROFILE
583 OSL_TRACE("Out osl_readProfileString [ok]\n");
590 sal_Bool SAL_CALL
osl_readProfileBool(oslProfile Profile
,
591 const sal_Char
* pszSection
, const sal_Char
* pszEntry
,
597 #ifdef TRACE_OSL_PROFILE
598 OSL_TRACE("In osl_readProfileBool\n");
601 if (osl_readProfileString(Profile
, pszSection
, pszEntry
, Line
, sizeof(Line
), ""))
603 if ((strcasecmp(Line
, STR_INI_BOOLYES
) == 0) ||
604 (strcasecmp(Line
, STR_INI_BOOLON
) == 0) ||
605 (strcasecmp(Line
, STR_INI_BOOLONE
) == 0))
608 if ((strcasecmp(Line
, STR_INI_BOOLNO
) == 0) ||
609 (strcasecmp(Line
, STR_INI_BOOLOFF
) == 0) ||
610 (strcasecmp(Line
, STR_INI_BOOLZERO
) == 0))
614 #ifdef TRACE_OSL_PROFILE
615 OSL_TRACE("Out osl_readProfileBool [ok]\n");
622 sal_uInt32 SAL_CALL
osl_readProfileIdent(oslProfile Profile
,
623 const sal_Char
* pszSection
, const sal_Char
* pszEntry
,
624 sal_uInt32 FirstId
, const sal_Char
* Strings
[],
631 #ifdef TRACE_OSL_PROFILE
632 OSL_TRACE("In osl_readProfileIdent\n");
635 if (osl_readProfileString(Profile
, pszSection
, pszEntry
, Line
, sizeof(Line
), ""))
638 while (Strings
[i
] != NULL
)
640 if (strcasecmp(Line
, Strings
[i
]) == 0)
642 Default
= i
+ FirstId
;
649 #ifdef TRACE_OSL_PROFILE
650 OSL_TRACE("Out osl_readProfileIdent [ok]\n");
655 sal_Bool SAL_CALL
osl_writeProfileString(oslProfile Profile
,
656 const sal_Char
* pszSection
, const sal_Char
* pszEntry
,
657 const sal_Char
* pszString
)
660 sal_Bool bRet
= sal_False
;
664 osl_TProfileSection
* pSec
;
665 osl_TProfileImpl
* pProfile
= 0;
666 osl_TProfileImpl
* pTmpProfile
= 0;
668 #ifdef TRACE_OSL_PROFILE
669 OSL_TRACE("In osl_writeProfileString\n");
672 pTmpProfile
= (osl_TProfileImpl
*) Profile
;
674 if ( pTmpProfile
== 0 )
676 #ifdef TRACE_OSL_PROFILE
677 OSL_TRACE("Out osl_writeProfileString [pTmpProfile==0]\n");
682 pthread_mutex_lock(&(pTmpProfile
->m_AccessLock
));
684 if ( pTmpProfile
->m_bIsValid
== sal_False
)
686 OSL_ASSERT(pTmpProfile
->m_bIsValid
);
687 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
688 #ifdef TRACE_OSL_PROFILE
689 OSL_TRACE("Out osl_writeProfileString [not valid]\n");
694 pProfile
=acquireProfile(Profile
, sal_True
);
696 if (pProfile
== NULL
)
698 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
699 #ifdef TRACE_OSL_PROFILE
700 OSL_TRACE("Out osl_writeProfileString [pProfile==0]\n");
705 Line
= (sal_Char
*) malloc(strlen(pszEntry
)+strlen(pszString
)+48);
707 if (! (pProfile
->m_Flags
& osl_Profile_SYSTEM
))
709 if ((pSec
= findEntry(pProfile
, pszSection
, pszEntry
, &NoEntry
)) == NULL
)
712 addLine(pProfile
, Line
);
715 strcpy(&Line
[1], pszSection
);
716 Line
[1 + strlen(pszSection
)] = ']';
717 Line
[2 + strlen(pszSection
)] = '\0';
719 if (((pStr
= addLine(pProfile
, Line
)) == NULL
) ||
720 (! addSection(pProfile
, pProfile
->m_NoLines
- 1, &pStr
[1], strlen(pszSection
))))
722 bRet
=releaseProfile(pProfile
);
725 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
729 #ifdef TRACE_OSL_PROFILE
730 OSL_TRACE("Out osl_writeProfileString [not added]\n");
735 pSec
= &pProfile
->m_Sections
[pProfile
->m_NoSections
- 1];
736 NoEntry
= pSec
->m_NoEntries
;
740 strcpy(&Line
[0], pszEntry
);
741 Line
[0 + strlen(pszEntry
)] = '=';
742 strcpy(&Line
[1 + strlen(pszEntry
)], pszString
);
744 if (NoEntry
>= pSec
->m_NoEntries
)
746 if (pSec
->m_NoEntries
> 0)
747 i
= pSec
->m_Entries
[pSec
->m_NoEntries
- 1].m_Line
+ 1;
749 i
= pSec
->m_Line
+ 1;
751 if (((pStr
= insertLine(pProfile
, Line
, i
)) == NULL
) ||
752 (! addEntry(pProfile
, pSec
, i
, pStr
, strlen(pszEntry
))))
754 bRet
=releaseProfile(pProfile
);
757 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
760 #ifdef TRACE_OSL_PROFILE
761 OSL_TRACE("Out osl_writeProfileString [not inserted]\n");
766 pProfile
->m_Flags
|= FLG_MODIFIED
;
770 i
= pSec
->m_Entries
[NoEntry
].m_Line
;
771 free(pProfile
->m_Lines
[i
]);
772 pProfile
->m_Lines
[i
] = strdup(Line
);
773 setEntry(pProfile
, pSec
, NoEntry
, i
, pProfile
->m_Lines
[i
], strlen(pszEntry
));
775 pProfile
->m_Flags
|= FLG_MODIFIED
;
779 /* not implemented */
782 bRet
= releaseProfile(pProfile
);
785 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
791 #ifdef TRACE_OSL_PROFILE
792 OSL_TRACE("Out osl_writeProfileString [ok]\n");
799 sal_Bool SAL_CALL
osl_writeProfileBool(oslProfile Profile
,
800 const sal_Char
* pszSection
, const sal_Char
* pszEntry
,
803 sal_Bool bRet
=sal_False
;
805 #ifdef TRACE_OSL_PROFILE
806 OSL_TRACE("In osl_writeProfileBool\n");
810 bRet
=osl_writeProfileString(Profile
, pszSection
, pszEntry
, STR_INI_BOOLONE
);
812 bRet
=osl_writeProfileString(Profile
, pszSection
, pszEntry
, STR_INI_BOOLZERO
);
814 #ifdef TRACE_OSL_PROFILE
815 OSL_TRACE("Out osl_writeProfileBool [ok]\n");
822 sal_Bool SAL_CALL
osl_writeProfileIdent(oslProfile Profile
,
823 const sal_Char
* pszSection
, const sal_Char
* pszEntry
,
824 sal_uInt32 FirstId
, const sal_Char
* Strings
[],
828 sal_Bool bRet
=sal_False
;
830 #ifdef TRACE_OSL_PROFILE
831 OSL_TRACE("In osl_writeProfileIdent\n");
834 for (n
= 0; Strings
[n
] != NULL
; n
++);
836 if ((i
= Value
- FirstId
) >= n
)
839 bRet
= osl_writeProfileString(Profile
, pszSection
, pszEntry
, Strings
[i
]);
841 #ifdef TRACE_OSL_PROFILE
842 OSL_TRACE("Out osl_writeProfileIdent\n");
848 sal_Bool SAL_CALL
osl_removeProfileEntry(oslProfile Profile
,
849 const sal_Char
*pszSection
, const sal_Char
*pszEntry
)
852 osl_TProfileSection
* pSec
;
853 osl_TProfileImpl
* pProfile
= 0;
854 osl_TProfileImpl
* pTmpProfile
= 0;
855 sal_Bool bRet
= sal_False
;
857 #ifdef TRACE_OSL_PROFILE
858 OSL_TRACE("In osl_removeProfileEntry\n");
861 pTmpProfile
= (osl_TProfileImpl
*) Profile
;
863 if ( pTmpProfile
== 0 )
865 #ifdef TRACE_OSL_PROFILE
866 OSL_TRACE("Out osl_removeProfileEntry [pProfile==0]\n");
871 pthread_mutex_lock(&(pTmpProfile
->m_AccessLock
));
873 if ( pTmpProfile
->m_bIsValid
== sal_False
)
875 OSL_ASSERT(pTmpProfile
->m_bIsValid
);
876 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
877 #ifdef TRACE_OSL_PROFILE
878 OSL_TRACE("Out osl_removeProfileEntry [not valid]\n");
884 pProfile
= acquireProfile(Profile
, sal_True
);
886 if (pProfile
== NULL
)
888 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
889 #ifdef TRACE_OSL_PROFILE
890 OSL_TRACE("Out osl_removeProfileEntry [pProfile==0]\n");
896 if (! (pProfile
->m_Flags
& osl_Profile_SYSTEM
))
898 if (((pSec
= findEntry(pProfile
, pszSection
, pszEntry
, &NoEntry
)) != NULL
) &&
899 (NoEntry
< pSec
->m_NoEntries
))
901 removeLine(pProfile
, pSec
->m_Entries
[NoEntry
].m_Line
);
902 removeEntry(pSec
, NoEntry
);
903 if (pSec
->m_NoEntries
== 0)
905 removeLine(pProfile
, pSec
->m_Line
);
907 /* remove any empty separation line */
908 if ((pSec
->m_Line
> 0) && (pProfile
->m_Lines
[pSec
->m_Line
- 1][0] == '\0'))
909 removeLine(pProfile
, pSec
->m_Line
- 1);
911 removeSection(pProfile
, pSec
);
914 pProfile
->m_Flags
|= FLG_MODIFIED
;
918 { /* not implemented */ }
921 bRet
= releaseProfile(pProfile
);
924 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
926 #ifdef TRACE_OSL_PROFILE
927 OSL_TRACE("Out osl_removeProfileEntry [ok]\n");
933 sal_uInt32 SAL_CALL
osl_getProfileSectionEntries(oslProfile Profile
, const sal_Char
*pszSection
,
934 sal_Char
* pszBuffer
, sal_uInt32 MaxLen
)
938 osl_TProfileSection
* pSec
;
939 osl_TProfileImpl
* pProfile
= 0;
940 osl_TProfileImpl
* pTmpProfile
= 0;
941 sal_Bool bRet
= sal_False
;
943 #ifdef TRACE_OSL_PROFILE
944 OSL_TRACE("In osl_getProfileSectionEntries\n");
947 pTmpProfile
= (osl_TProfileImpl
*) Profile
;
949 if ( pTmpProfile
== 0 )
951 #ifdef TRACE_OSL_PROFILE
952 OSL_TRACE("Out osl_getProfileSectionEntries [pTmpProfile==0]\n");
958 pthread_mutex_lock(&(pTmpProfile
->m_AccessLock
));
960 if ( pTmpProfile
->m_bIsValid
== sal_False
)
962 OSL_ASSERT(pTmpProfile
->m_bIsValid
);
964 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
966 #ifdef TRACE_OSL_PROFILE
967 OSL_TRACE("Out osl_getProfileSectionEntries [not valid]\n");
973 pProfile
= acquireProfile(Profile
, sal_False
);
975 if (pProfile
== NULL
)
977 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
979 #ifdef TRACE_OSL_PROFILE
980 OSL_TRACE("Out osl_getProfileSectionEntries [pProfile=0]\n");
987 if (! (pProfile
->m_Flags
& osl_Profile_SYSTEM
))
989 if ((pSec
= findEntry(pProfile
, pszSection
, "", &NoEntry
)) != NULL
)
993 for (i
= 0; i
< pSec
->m_NoEntries
; i
++)
995 if ((n
+ pSec
->m_Entries
[i
].m_Len
+ 1) < MaxLen
)
997 strncpy(&pszBuffer
[n
], &pProfile
->m_Lines
[pSec
->m_Entries
[i
].m_Line
]
998 [pSec
->m_Entries
[i
].m_Offset
], pSec
->m_Entries
[i
].m_Len
);
999 n
+= pSec
->m_Entries
[i
].m_Len
;
1000 pszBuffer
[n
++] = '\0';
1007 pszBuffer
[n
++] = '\0';
1011 for (i
= 0; i
< pSec
->m_NoEntries
; i
++)
1012 n
+= pSec
->m_Entries
[i
].m_Len
+ 1;
1021 /* not implemented */
1024 bRet
=releaseProfile(pProfile
);
1027 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
1029 #ifdef TRACE_OSL_PROFILE
1030 OSL_TRACE("Out osl_getProfileSectionEntries [ok]\n");
1036 sal_uInt32 SAL_CALL
osl_getProfileSections(oslProfile Profile
, sal_Char
* pszBuffer
, sal_uInt32 MaxLen
)
1038 sal_uInt32 i
, n
= 0;
1039 osl_TProfileSection
* pSec
;
1040 osl_TProfileImpl
* pProfile
= 0;
1041 osl_TProfileImpl
* pTmpProfile
= 0;
1042 sal_Bool bRet
= sal_False
;
1044 #ifdef TRACE_OSL_PROFILE
1045 OSL_TRACE("In osl_getProfileSections\n");
1048 pTmpProfile
= (osl_TProfileImpl
*) Profile
;
1050 if ( pTmpProfile
== 0 )
1052 #ifdef TRACE_OSL_PROFILE
1053 OSL_TRACE("Out osl_getProfileSections [pTmpProfile==0]\n");
1058 pthread_mutex_lock(&(pTmpProfile
->m_AccessLock
));
1060 if ( pTmpProfile
->m_bIsValid
== sal_False
)
1062 OSL_ASSERT(pTmpProfile
->m_bIsValid
);
1063 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
1064 #ifdef TRACE_OSL_PROFILE
1065 OSL_TRACE("Out osl_getProfileSections [not valid]\n");
1070 pProfile
= acquireProfile(Profile
, sal_False
);
1072 if (pProfile
== NULL
)
1074 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
1076 #ifdef TRACE_OSL_PROFILE
1077 OSL_TRACE("Out osl_getProfileSections [pProfile==0]\n");
1082 if (! (pProfile
->m_Flags
& osl_Profile_SYSTEM
))
1086 for (i
= 0; i
< pProfile
->m_NoSections
; i
++)
1088 pSec
= &pProfile
->m_Sections
[i
];
1090 if ((n
+ pSec
->m_Len
+ 1) < MaxLen
)
1092 strncpy(&pszBuffer
[n
], &pProfile
->m_Lines
[pSec
->m_Line
][pSec
->m_Offset
],
1095 pszBuffer
[n
++] = '\0';
1101 pszBuffer
[n
++] = '\0';
1105 for (i
= 0; i
< pProfile
->m_NoSections
; i
++)
1106 n
+= pProfile
->m_Sections
[i
].m_Len
+ 1;
1112 { /* not implemented */ }
1115 bRet
=releaseProfile(pProfile
);
1118 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
1120 #ifdef TRACE_OSL_PROFILE
1121 OSL_TRACE("Out osl_getProfileSections [ok]\n");
1127 /*****************************************************************************/
1128 /* Static Module Functions */
1129 /*****************************************************************************/
1131 static osl_TStamp
OslProfile_getFileStamp(osl_TFile
* pFile
)
1135 if ( (pFile
->m_Handle
< 0) || (fstat(pFile
->m_Handle
, &status
) < 0) )
1141 return (status
.st_mtime
);
1144 static sal_Bool
OslProfile_lockFile(const osl_TFile
* pFile
, osl_TLockMode eMode
)
1147 /* boring hack, but initializers for static vars must be constant */
1148 static sal_Bool bIsInitialized
= sal_False
;
1149 static sal_Bool bLockingDisabled
;
1151 #ifdef TRACE_OSL_PROFILE
1152 OSL_TRACE("In OslProfile_lockFile\n");
1155 if ( !bIsInitialized
)
1157 sal_Char
* pEnvValue
;
1158 pEnvValue
= getenv( "STAR_PROFILE_LOCKING_DISABLED" );
1160 if ( pEnvValue
== 0 )
1162 bLockingDisabled
= sal_False
;
1167 bLockingDisabled
= sal_True
;
1170 bIsInitialized
= sal_True
;
1173 if (pFile
->m_Handle
< 0)
1175 #ifdef TRACE_OSL_PROFILE
1176 OSL_TRACE("Out OslProfile_lockFile [invalid file handle]\n");
1182 if ( bLockingDisabled
)
1184 #ifdef TRACE_OSL_PROFILE
1185 OSL_TRACE("Out OslProfile_lockFile [locking disabled]\n");
1192 lock
.l_whence
= SEEK_SET
;
1198 lock
.l_type
= F_UNLCK
;
1202 lock
.l_type
= F_RDLCK
;
1206 lock
.l_type
= F_WRLCK
;
1210 #ifndef MACOSX // not MAC OSX
1211 if ( fcntl(pFile
->m_Handle
, F_SETLKW
, &lock
) == -1 )
1213 /* Mac OSX will return ENOTSUP for webdav drives so we should ignore it */
1214 if ( fcntl(pFile
->m_Handle
, F_SETLKW
, &lock
) == -1 && errno
!= ENOTSUP
)
1217 OSL_TRACE("fcntl returned -1 (%s)\n",strerror(errno
));
1218 #ifdef TRACE_OSL_PROFILE
1219 OSL_TRACE("Out OslProfile_lockFile [fcntl F_SETLKW]\n");
1224 #ifdef TRACE_OSL_PROFILE
1225 OSL_TRACE("Out OslProfile_lockFile [ok]\n");
1230 static osl_TFile
* openFileImpl(const sal_Char
* pszFilename
, oslProfileOption ProfileFlags
)
1233 osl_TFile
* pFile
= (osl_TFile
*) calloc(1, sizeof(osl_TFile
));
1234 sal_Bool bWriteable
= sal_False
;
1236 if ( ProfileFlags
& ( osl_Profile_WRITELOCK
| osl_Profile_FLUSHWRITE
) )
1238 #ifdef DEBUG_OSL_PROFILE
1239 OSL_TRACE("setting bWriteable to TRUE\n");
1241 bWriteable
=sal_True
;
1246 #ifdef DEBUG_OSL_PROFILE
1247 OSL_TRACE("opening '%s' read only\n",pszFilename
);
1250 pFile
->m_Handle
= open(pszFilename
, O_RDONLY
);
1251 /* mfe: argghh!!! do not check if the file could be openend */
1252 /* default mode expects it that way!!! */
1256 #ifdef DEBUG_OSL_PROFILE
1257 OSL_TRACE("opening '%s' read/write\n",pszFilename
);
1259 if (((pFile
->m_Handle
= open(pszFilename
, O_RDWR
| O_CREAT
| O_EXCL
, DEFAULT_PMODE
)) < 0) &&
1260 ((pFile
->m_Handle
= open(pszFilename
, O_RDWR
)) < 0))
1263 #ifdef TRACE_OSL_PROFILE
1264 OSL_TRACE("Out openFileImpl [open read/write]\n");
1270 /* set close-on-exec flag */
1271 if ((Flags
= fcntl(pFile
->m_Handle
, F_GETFD
, 0)) != -1)
1273 Flags
|= FD_CLOEXEC
;
1274 fcntl(pFile
->m_Handle
, F_SETFD
, Flags
);
1277 pFile
->m_pWriteBuf
=0;
1278 pFile
->m_nWriteBufFree
=0;
1279 pFile
->m_nWriteBufLen
=0;
1281 if ( ProfileFlags
& (osl_Profile_WRITELOCK
| osl_Profile_READLOCK
) )
1283 #ifdef DEBUG_OSL_PROFILE
1284 OSL_TRACE("locking '%s' file\n",pszFilename
);
1286 OslProfile_lockFile(pFile
, bWriteable
? write_lock
: read_lock
);
1289 #ifdef TRACE_OSL_PROFILE
1290 OSL_TRACE("Out openFileImpl [ok]\n");
1295 static osl_TStamp
closeFileImpl(osl_TFile
* pFile
, oslProfileOption Flags
)
1297 osl_TStamp stamp
= 0;
1299 #ifdef TRACE_OSL_PROFILE
1300 OSL_TRACE("In closeFileImpl\n");
1305 #ifdef TRACE_OSL_PROFILE
1306 OSL_TRACE("Out closeFileImpl [pFile == 0]\n");
1311 if ( pFile
->m_Handle
>= 0 )
1313 stamp
= OslProfile_getFileStamp(pFile
);
1315 if ( Flags
& (osl_Profile_WRITELOCK
| osl_Profile_WRITELOCK
) )
1317 OslProfile_lockFile(pFile
, un_lock
);
1320 close(pFile
->m_Handle
);
1321 pFile
->m_Handle
= -1;
1325 if ( pFile
->m_pWriteBuf
)
1327 free(pFile
->m_pWriteBuf
);
1332 #ifdef TRACE_OSL_PROFILE
1333 OSL_TRACE("Out closeFileImpl [ok]\n");
1339 static sal_Bool
OslProfile_rewindFile(osl_TFile
* pFile
, sal_Bool bTruncate
)
1341 #ifdef TRACE_OSL_PROFILE
1342 OSL_TRACE("In osl_OslProfile_rewindFile\n");
1345 if (pFile
->m_Handle
>= 0)
1347 pFile
->m_pReadPtr
= pFile
->m_ReadBuf
+ sizeof(pFile
->m_ReadBuf
);
1349 #ifdef DEBUG_OSL_PROFILE
1350 OSL_TRACE("rewinding\n");
1352 lseek(pFile
->m_Handle
, SEEK_SET
, 0L);
1356 #ifdef DEBUG_OSL_PROFILE
1357 OSL_TRACE("truncating\n");
1359 ftruncate(pFile
->m_Handle
, 0L);
1364 #ifdef TRACE_OSL_PROFILE
1365 OSL_TRACE("Out osl_OslProfile_rewindFile [ok]\n");
1371 static sal_Char
* OslProfile_getLine(osl_TFile
* pFile
)
1373 int Max
, Free
, Bytes
, nLineBytes
= 0;
1375 sal_Char
* pLine
= NULL
;
1383 if (pFile
->m_Handle
< 0)
1388 Bytes
= sizeof(pFile
->m_ReadBuf
) - (pFile
->m_pReadPtr
- pFile
->m_ReadBuf
);
1393 memcpy(pFile
->m_ReadBuf
, pFile
->m_pReadPtr
, Bytes
);
1394 pFile
->m_pReadPtr
= pFile
->m_ReadBuf
;
1396 Free
= sizeof(pFile
->m_ReadBuf
) - Bytes
;
1398 if ((Max
= read(pFile
->m_Handle
, &pFile
->m_ReadBuf
[Bytes
], Free
)) < 0)
1400 OSL_TRACE("read failed '%s'\n",strerror(errno
));
1403 rtl_freeMemory( pLine
);
1410 if ((Max
== 0) && ! pLine
)
1413 pFile
->m_ReadBuf
[Bytes
+ Max
] = '\0';
1417 for (pChr
= pFile
->m_pReadPtr
;
1418 (*pChr
!= '\n') && (*pChr
!= '\r') && (*pChr
!= '\0') &&
1419 (pChr
< (pFile
->m_ReadBuf
+ sizeof(pFile
->m_ReadBuf
) - 1));
1422 Max
= pChr
- pFile
->m_pReadPtr
;
1423 pNewLine
= (sal_Char
*) rtl_allocateMemory( nLineBytes
+ Max
+ 1 );
1426 memcpy( pNewLine
, pLine
, nLineBytes
);
1427 rtl_freeMemory( pLine
);
1429 memcpy(pNewLine
+nLineBytes
, pFile
->m_pReadPtr
, Max
);
1431 pNewLine
[ nLineBytes
] = 0;
1434 if (pChr
< (pFile
->m_ReadBuf
+ sizeof(pFile
->m_ReadBuf
) - 1))
1438 if ((pChr
[0] == '\r') && (pChr
[1] == '\n'))
1444 if ((pChr
< (pFile
->m_ReadBuf
+ sizeof(pFile
->m_ReadBuf
))) &&
1446 pChr
= pFile
->m_ReadBuf
+ sizeof(pFile
->m_ReadBuf
);
1448 /* setting Max to -1 indicates terminating read loop */
1452 pFile
->m_pReadPtr
= pChr
;
1459 static sal_Bool
OslProfile_putLine(osl_TFile
* pFile
, const sal_Char
*pszLine
)
1461 unsigned int Len
= strlen(pszLine
);
1463 #ifdef DEBUG_OSL_PROFILE
1467 if ( pFile
== 0 || pFile
->m_Handle
< 0 )
1472 if ( pFile
->m_pWriteBuf
== 0 )
1474 pFile
->m_pWriteBuf
= (sal_Char
*) malloc(Len
+3);
1475 pFile
->m_nWriteBufLen
= Len
+3;
1476 pFile
->m_nWriteBufFree
= Len
+3;
1480 if ( pFile
->m_nWriteBufFree
<= Len
+ 3 )
1484 pTmp
=(sal_Char
*) realloc(pFile
->m_pWriteBuf
,( ( pFile
->m_nWriteBufLen
+ Len
) * 2) );
1489 pFile
->m_pWriteBuf
= pTmp
;
1490 pFile
->m_nWriteBufFree
= pFile
->m_nWriteBufFree
+ pFile
->m_nWriteBufLen
+ ( 2 * Len
);
1491 pFile
->m_nWriteBufLen
= ( pFile
->m_nWriteBufLen
+ Len
) * 2;
1492 memset( (pFile
->m_pWriteBuf
) + ( pFile
->m_nWriteBufLen
- pFile
->m_nWriteBufFree
), 0, pFile
->m_nWriteBufFree
);
1498 memcpy(pFile
->m_pWriteBuf
+ ( pFile
->m_nWriteBufLen
- pFile
->m_nWriteBufFree
),pszLine
,Len
+1);
1499 #ifdef DEBUG_OSL_PROFILE
1500 strLen
= strlen(pFile
->m_pWriteBuf
);
1502 pFile
->m_pWriteBuf
[pFile
->m_nWriteBufLen
- pFile
->m_nWriteBufFree
+ Len
]='\n';
1503 pFile
->m_pWriteBuf
[pFile
->m_nWriteBufLen
- pFile
->m_nWriteBufFree
+ Len
+ 1]='\0';
1505 pFile
->m_nWriteBufFree
-=Len
+1;
1510 /* platform specific end */
1512 static sal_Char
* stripBlanks(sal_Char
* String
, sal_uInt32
* pLen
)
1514 if ( ( pLen
!= NULL
) && ( *pLen
!= 0 ) )
1516 while ((String
[*pLen
- 1] == ' ') || (String
[*pLen
- 1] == '\t'))
1519 while ( (*String
== ' ') || (*String
== '\t') )
1526 while ( (*String
== ' ') || (*String
== '\t') )
1532 static sal_Char
* addLine(osl_TProfileImpl
* pProfile
, const sal_Char
* Line
)
1534 if (pProfile
->m_NoLines
>= pProfile
->m_MaxLines
)
1536 if (pProfile
->m_Lines
== NULL
)
1538 pProfile
->m_MaxLines
= LINES_INI
;
1539 pProfile
->m_Lines
= (sal_Char
**)malloc(pProfile
->m_MaxLines
* sizeof(sal_Char
*));
1540 memset(pProfile
->m_Lines
,0,pProfile
->m_MaxLines
* sizeof(sal_Char
*));
1545 unsigned int oldmax
=pProfile
->m_MaxLines
;
1547 pProfile
->m_MaxLines
+= LINES_ADD
;
1548 pProfile
->m_Lines
= (sal_Char
**)realloc(pProfile
->m_Lines
,
1549 pProfile
->m_MaxLines
* sizeof(sal_Char
*));
1550 for ( idx
= oldmax
; idx
< pProfile
->m_MaxLines
; ++idx
)
1552 pProfile
->m_Lines
[idx
]=0;
1556 if (pProfile
->m_Lines
== NULL
)
1558 pProfile
->m_NoLines
= 0;
1559 pProfile
->m_MaxLines
= 0;
1565 if ( pProfile
->m_Lines
!= 0 && pProfile
->m_Lines
[pProfile
->m_NoLines
] != 0 )
1567 free(pProfile
->m_Lines
[pProfile
->m_NoLines
]);
1569 pProfile
->m_Lines
[pProfile
->m_NoLines
++] = strdup(Line
);
1571 return (pProfile
->m_Lines
[pProfile
->m_NoLines
- 1]);
1574 static sal_Char
* insertLine(osl_TProfileImpl
* pProfile
, const sal_Char
* Line
, sal_uInt32 LineNo
)
1576 if (pProfile
->m_NoLines
>= pProfile
->m_MaxLines
)
1578 if (pProfile
->m_Lines
== NULL
)
1580 pProfile
->m_MaxLines
= LINES_INI
;
1581 pProfile
->m_Lines
= (sal_Char
**)malloc(pProfile
->m_MaxLines
* sizeof(sal_Char
*));
1582 memset(pProfile
->m_Lines
,0,pProfile
->m_MaxLines
* sizeof(sal_Char
*));
1586 pProfile
->m_MaxLines
+= LINES_ADD
;
1587 pProfile
->m_Lines
= (sal_Char
**)realloc(pProfile
->m_Lines
,
1588 pProfile
->m_MaxLines
* sizeof(sal_Char
*));
1590 memset(&pProfile
->m_Lines
[pProfile
->m_NoLines
],
1592 (pProfile
->m_MaxLines
- pProfile
->m_NoLines
- 1) * sizeof(sal_Char
*));
1595 if (pProfile
->m_Lines
== NULL
)
1597 pProfile
->m_NoLines
= 0;
1598 pProfile
->m_MaxLines
= 0;
1603 LineNo
= LineNo
> pProfile
->m_NoLines
? pProfile
->m_NoLines
: LineNo
;
1605 if (LineNo
< pProfile
->m_NoLines
)
1608 osl_TProfileSection
* pSec
;
1610 memmove(&pProfile
->m_Lines
[LineNo
+ 1], &pProfile
->m_Lines
[LineNo
],
1611 (pProfile
->m_NoLines
- LineNo
) * sizeof(sal_Char
*));
1614 /* adjust line references */
1615 for (i
= 0; i
< pProfile
->m_NoSections
; i
++)
1617 pSec
= &pProfile
->m_Sections
[i
];
1619 if (pSec
->m_Line
>= LineNo
)
1622 for (n
= 0; n
< pSec
->m_NoEntries
; n
++)
1623 if (pSec
->m_Entries
[n
].m_Line
>= LineNo
)
1624 pSec
->m_Entries
[n
].m_Line
++;
1628 pProfile
->m_NoLines
++;
1630 pProfile
->m_Lines
[LineNo
] = strdup(Line
);
1632 return (pProfile
->m_Lines
[LineNo
]);
1635 static void removeLine(osl_TProfileImpl
* pProfile
, sal_uInt32 LineNo
)
1637 if (LineNo
< pProfile
->m_NoLines
)
1639 free(pProfile
->m_Lines
[LineNo
]);
1640 pProfile
->m_Lines
[LineNo
]=0;
1641 if (pProfile
->m_NoLines
- LineNo
> 1)
1644 osl_TProfileSection
* pSec
;
1646 memmove(&pProfile
->m_Lines
[LineNo
], &pProfile
->m_Lines
[LineNo
+ 1],
1647 (pProfile
->m_NoLines
- LineNo
- 1) * sizeof(sal_Char
*));
1649 memset(&pProfile
->m_Lines
[pProfile
->m_NoLines
- 1],
1651 (pProfile
->m_MaxLines
- pProfile
->m_NoLines
) * sizeof(sal_Char
*));
1653 /* adjust line references */
1654 for (i
= 0; i
< pProfile
->m_NoSections
; i
++)
1656 pSec
= &pProfile
->m_Sections
[i
];
1658 if (pSec
->m_Line
> LineNo
)
1661 for (n
= 0; n
< pSec
->m_NoEntries
; n
++)
1662 if (pSec
->m_Entries
[n
].m_Line
> LineNo
)
1663 pSec
->m_Entries
[n
].m_Line
--;
1668 pProfile
->m_Lines
[LineNo
] = 0;
1671 pProfile
->m_NoLines
--;
1677 static void setEntry(osl_TProfileImpl
* pProfile
, osl_TProfileSection
* pSection
,
1678 sal_uInt32 NoEntry
, sal_uInt32 Line
,
1679 sal_Char
* Entry
, sal_uInt32 Len
)
1681 Entry
= stripBlanks(Entry
, &Len
);
1682 pSection
->m_Entries
[NoEntry
].m_Line
= Line
;
1683 pSection
->m_Entries
[NoEntry
].m_Offset
= Entry
- pProfile
->m_Lines
[Line
];
1684 pSection
->m_Entries
[NoEntry
].m_Len
= Len
;
1689 static sal_Bool
addEntry(osl_TProfileImpl
* pProfile
, osl_TProfileSection
*pSection
,
1690 int Line
, sal_Char
* Entry
, sal_uInt32 Len
)
1692 if (pSection
!= NULL
)
1694 if (pSection
->m_NoEntries
>= pSection
->m_MaxEntries
)
1696 if (pSection
->m_Entries
== NULL
)
1698 pSection
->m_MaxEntries
= ENTRIES_INI
;
1699 pSection
->m_Entries
= (osl_TProfileEntry
*)malloc(
1700 pSection
->m_MaxEntries
* sizeof(osl_TProfileEntry
));
1704 pSection
->m_MaxEntries
+= ENTRIES_ADD
;
1705 pSection
->m_Entries
= (osl_TProfileEntry
*)realloc(pSection
->m_Entries
,
1706 pSection
->m_MaxEntries
* sizeof(osl_TProfileEntry
));
1709 if (pSection
->m_Entries
== NULL
)
1711 pSection
->m_NoEntries
= 0;
1712 pSection
->m_MaxEntries
= 0;
1717 pSection
->m_NoEntries
++;
1719 Entry
= stripBlanks(Entry
, &Len
);
1720 setEntry(pProfile
, pSection
, pSection
->m_NoEntries
- 1, Line
,
1729 static void removeEntry(osl_TProfileSection
*pSection
, sal_uInt32 NoEntry
)
1731 if (NoEntry
< pSection
->m_NoEntries
)
1733 if (pSection
->m_NoEntries
- NoEntry
> 1)
1735 memmove(&pSection
->m_Entries
[NoEntry
],
1736 &pSection
->m_Entries
[NoEntry
+ 1],
1737 (pSection
->m_NoEntries
- NoEntry
- 1) * sizeof(osl_TProfileEntry
));
1738 pSection
->m_Entries
[pSection
->m_NoEntries
- 1].m_Line
=0;
1739 pSection
->m_Entries
[pSection
->m_NoEntries
- 1].m_Offset
=0;
1740 pSection
->m_Entries
[pSection
->m_NoEntries
- 1].m_Len
=0;
1743 pSection
->m_NoEntries
--;
1749 static sal_Bool
addSection(osl_TProfileImpl
* pProfile
, int Line
, const sal_Char
* Section
, sal_uInt32 Len
)
1751 if (pProfile
->m_NoSections
>= pProfile
->m_MaxSections
)
1753 if (pProfile
->m_Sections
== NULL
)
1755 pProfile
->m_MaxSections
= SECTIONS_INI
;
1756 pProfile
->m_Sections
= (osl_TProfileSection
*)malloc(pProfile
->m_MaxSections
* sizeof(osl_TProfileSection
));
1757 memset(pProfile
->m_Sections
,0,pProfile
->m_MaxSections
* sizeof(osl_TProfileSection
));
1762 unsigned int oldmax
=pProfile
->m_MaxSections
;
1764 pProfile
->m_MaxSections
+= SECTIONS_ADD
;
1765 pProfile
->m_Sections
= (osl_TProfileSection
*)realloc(pProfile
->m_Sections
,
1766 pProfile
->m_MaxSections
* sizeof(osl_TProfileSection
));
1767 for ( idx
= oldmax
; idx
< pProfile
->m_MaxSections
; ++idx
)
1769 pProfile
->m_Sections
[idx
].m_Entries
=0;
1773 if (pProfile
->m_Sections
== NULL
)
1775 pProfile
->m_NoSections
= 0;
1776 pProfile
->m_MaxSections
= 0;
1781 pProfile
->m_NoSections
++;
1783 if ( pProfile
->m_Sections
[(pProfile
->m_NoSections
) - 1].m_Entries
!= 0 )
1785 free(pProfile
->m_Sections
[(pProfile
->m_NoSections
) - 1].m_Entries
);
1787 pProfile
->m_Sections
[pProfile
->m_NoSections
- 1].m_Entries
= NULL
;
1788 pProfile
->m_Sections
[pProfile
->m_NoSections
- 1].m_NoEntries
= 0;
1789 pProfile
->m_Sections
[pProfile
->m_NoSections
- 1].m_MaxEntries
= 0;
1791 pProfile
->m_Sections
[pProfile
->m_NoSections
- 1].m_Line
= Line
;
1792 pProfile
->m_Sections
[pProfile
->m_NoSections
- 1].m_Offset
= Section
- pProfile
->m_Lines
[Line
];
1793 pProfile
->m_Sections
[pProfile
->m_NoSections
- 1].m_Len
= Len
;
1798 static void removeSection(osl_TProfileImpl
* pProfile
, osl_TProfileSection
*pSection
)
1802 if ((Section
= pSection
- pProfile
->m_Sections
) < pProfile
->m_NoSections
)
1804 free (pSection
->m_Entries
);
1805 pSection
->m_Entries
=0;
1806 if (pProfile
->m_NoSections
- Section
> 1)
1808 memmove(&pProfile
->m_Sections
[Section
], &pProfile
->m_Sections
[Section
+ 1],
1809 (pProfile
->m_NoSections
- Section
- 1) * sizeof(osl_TProfileSection
));
1811 memset(&pProfile
->m_Sections
[pProfile
->m_NoSections
- 1],
1813 (pProfile
->m_MaxSections
- pProfile
->m_NoSections
) * sizeof(osl_TProfileSection
));
1814 pProfile
->m_Sections
[pProfile
->m_NoSections
- 1].m_Entries
= 0;
1818 pSection
->m_Entries
= 0;
1821 pProfile
->m_NoSections
--;
1827 static osl_TProfileSection
* findEntry(osl_TProfileImpl
* pProfile
, const sal_Char
* Section
,
1828 const sal_Char
* Entry
, sal_uInt32
*pNoEntry
)
1830 static sal_uInt32 Sect
= 0;
1833 const sal_Char
* pStr
;
1834 osl_TProfileSection
* pSec
=0;
1836 Len
= strlen(Section
);
1840 for (i
= 0; i
< pProfile
->m_NoSections
; i
++)
1842 n
%= pProfile
->m_NoSections
;
1843 pSec
= &pProfile
->m_Sections
[n
];
1844 if ((Len
== pSec
->m_Len
) &&
1845 (strncasecmp(Section
, &pProfile
->m_Lines
[pSec
->m_Line
][pSec
->m_Offset
], pSec
->m_Len
)
1853 if (i
< pProfile
->m_NoSections
)
1855 Len
= strlen(Entry
);
1857 *pNoEntry
= pSec
->m_NoEntries
;
1859 for (i
= 0; i
< pSec
->m_NoEntries
; i
++)
1861 pStr
= &pProfile
->m_Lines
[pSec
->m_Entries
[i
].m_Line
]
1862 [pSec
->m_Entries
[i
].m_Offset
];
1863 if ((Len
== pSec
->m_Entries
[i
].m_Len
) &&
1864 (strncasecmp(Entry
, pStr
, pSec
->m_Entries
[i
].m_Len
)
1878 static sal_Bool
loadProfile(osl_TFile
* pFile
, osl_TProfileImpl
* pProfile
)
1885 sal_Char
* bWasAdded
= NULL
;
1887 pProfile
->m_NoLines
= 0;
1888 pProfile
->m_NoSections
= 0;
1895 if ( pProfile
== 0 )
1900 OSL_VERIFY(OslProfile_rewindFile(pFile
, sal_False
));
1902 while ( ( pLine
=OslProfile_getLine(pFile
) ) != 0 )
1904 bWasAdded
= addLine( pProfile
, pLine
);
1905 rtl_freeMemory( pLine
);
1906 OSL_ASSERT(bWasAdded
);
1911 for (i
= 0; i
< pProfile
->m_NoLines
; i
++)
1913 pStr
= (sal_Char
*)stripBlanks(pProfile
->m_Lines
[i
], NULL
);
1915 if ((*pStr
== '\0') || (*pStr
== ';'))
1918 if ((*pStr
!= '[') || ((pChar
= strrchr(pStr
, ']')) == NULL
) ||
1919 ((pChar
- pStr
) <= 2))
1923 if (pProfile
->m_NoSections
< 1)
1926 if ((pChar
= strchr(pStr
, '=')) == NULL
)
1927 pChar
= pStr
+ strlen(pStr
);
1929 if (! addEntry(pProfile
, &pProfile
->m_Sections
[pProfile
->m_NoSections
- 1],
1930 i
, pStr
, pChar
- pStr
))
1941 if (! addSection(pProfile
, i
, pStr
+ 1, pChar
- pStr
- 1))
1953 static sal_Bool
storeProfile(osl_TProfileImpl
* pProfile
, sal_Bool bCleanup
)
1955 #ifdef TRACE_OSL_PROFILE
1956 OSL_TRACE("In storeProfile\n");
1959 if (pProfile
->m_Lines
!= NULL
)
1961 if (pProfile
->m_Flags
& FLG_MODIFIED
)
1965 osl_TFile
* pTmpFile
= osl_openTmpProfileImpl(pProfile
);
1967 if ( pTmpFile
== 0 )
1972 OSL_VERIFY(OslProfile_rewindFile(pTmpFile
, sal_True
));
1974 for ( i
= 0 ; i
< pProfile
->m_NoLines
; i
++ )
1976 OSL_VERIFY(OslProfile_putLine(pTmpFile
, pProfile
->m_Lines
[i
]));
1979 if ( ! writeProfileImpl(pTmpFile
) )
1981 if ( pTmpFile
->m_pWriteBuf
!= 0 )
1983 free(pTmpFile
->m_pWriteBuf
);
1986 pTmpFile
->m_pWriteBuf
=0;
1987 pTmpFile
->m_nWriteBufLen
=0;
1988 pTmpFile
->m_nWriteBufFree
=0;
1990 #ifdef TRACE_OSL_PROFILE
1991 OSL_TRACE("Out storeProfile [not flushed]\n");
1993 closeFileImpl(pTmpFile
,pProfile
->m_Flags
);
1998 pProfile
->m_Flags
&= ~FLG_MODIFIED
;
2000 closeFileImpl(pProfile
->m_pFile
,pProfile
->m_Flags
);
2001 closeFileImpl(pTmpFile
,pProfile
->m_Flags
);
2003 osl_ProfileSwapProfileNames(pProfile
);
2005 pProfile
->m_pFile
= openFileImpl(pProfile
->m_FileName
,pProfile
->m_Flags
);
2011 while (pProfile
->m_NoLines
> 0)
2012 removeLine(pProfile
, pProfile
->m_NoLines
- 1);
2014 free(pProfile
->m_Lines
);
2015 pProfile
->m_Lines
= NULL
;
2016 pProfile
->m_NoLines
= 0;
2017 pProfile
->m_MaxLines
= 0;
2019 while (pProfile
->m_NoSections
> 0)
2020 removeSection(pProfile
, &pProfile
->m_Sections
[pProfile
->m_NoSections
- 1]);
2022 free(pProfile
->m_Sections
);
2023 pProfile
->m_Sections
= NULL
;
2024 pProfile
->m_NoSections
= 0;
2025 pProfile
->m_MaxSections
= 0;
2029 #ifdef TRACE_OSL_PROFILE
2030 OSL_TRACE("Out storeProfile [ok]\n");
2036 static osl_TFile
* osl_openTmpProfileImpl(osl_TProfileImpl
* pProfile
)
2039 sal_Char
* pszExtension
= "tmp";
2040 sal_Char pszTmpName
[PATH_MAX
];
2041 oslProfileOption PFlags
=0;
2043 pszTmpName
[0] = '\0';
2045 /* generate tmp profilename */
2046 osl_ProfileGenerateExtension(pProfile
->m_FileName
,pszExtension
,pszTmpName
);
2048 if ( pszTmpName
[0] == 0 )
2053 if ( ! ( pProfile
->m_Flags
& osl_Profile_READLOCK
) )
2055 PFlags
|= osl_Profile_WRITELOCK
;
2058 /* open this file */
2059 pFile
= openFileImpl(pszTmpName
,pProfile
->m_Flags
| PFlags
);
2062 /* return new pFile */
2066 static sal_Bool
osl_ProfileSwapProfileNames(osl_TProfileImpl
* pProfile
)
2068 sal_Bool bRet
= sal_False
;
2070 sal_Char pszBakFile
[PATH_MAX
];
2071 sal_Char pszTmpFile
[PATH_MAX
];
2072 sal_Char pszIniFile
[PATH_MAX
];
2074 pszBakFile
[0] = '\0';
2075 pszTmpFile
[0] = '\0';
2076 pszIniFile
[0] = '\0';
2078 osl_ProfileGenerateExtension(pProfile
->m_FileName
,"bak",pszBakFile
);
2080 strcpy(pszIniFile
,pProfile
->m_FileName
);
2082 osl_ProfileGenerateExtension(pProfile
->m_FileName
,"tmp",pszTmpFile
);
2085 unlink( pszBakFile
);
2087 /* rename ini bak */
2088 rename( pszIniFile
, pszBakFile
);
2090 /* rename tmp ini */
2091 rename( pszTmpFile
, pszIniFile
);
2097 static void osl_ProfileGenerateExtension(sal_Char
* pszFileName
, sal_Char
* pszExtension
, sal_Char
* pszTmpName
)
2100 strcpy(pszTmpName
,pszFileName
);
2101 strcat(pszTmpName
,".");
2102 strcat(pszTmpName
,pszExtension
);
2108 static osl_TProfileImpl
* acquireProfile(oslProfile Profile
, sal_Bool bWriteable
)
2110 osl_TProfileImpl
* pProfile
= (osl_TProfileImpl
*)Profile
;
2111 oslProfileOption PFlags
=0;
2112 sal_Bool bRet
=sal_False
;
2116 PFlags
= osl_Profile_DEFAULT
| osl_Profile_WRITELOCK
;
2120 PFlags
= osl_Profile_DEFAULT
;
2124 if (pProfile
== NULL
)
2126 #ifdef DEBUG_OSL_PROFILE
2127 OSL_TRACE("AUTOOPEN MODE\n");
2130 if ( ( pProfile
= (osl_TProfileImpl
*) osl_openProfile(0, PFlags
) ) != NULL
)
2132 pProfile
->m_Flags
|= FLG_AUTOOPEN
;
2137 #ifdef DEBUG_OSL_PROFILE
2138 OSL_TRACE("try to acquire\n");
2141 if (! (pProfile
->m_Flags
& osl_Profile_SYSTEM
))
2143 if (! (pProfile
->m_Flags
& (osl_Profile_READLOCK
| osl_Profile_WRITELOCK
| osl_Profile_FLUSHWRITE
)))
2147 #ifdef DEBUG_OSL_PROFILE
2148 OSL_TRACE("Profile acquire DEFAULT MODE\n");
2150 if (! (pProfile
->m_pFile
= openFileImpl(pProfile
->m_FileName
, pProfile
->m_Flags
| PFlags
)))
2153 Stamp
= OslProfile_getFileStamp(pProfile
->m_pFile
);
2155 if (memcmp(&Stamp
, &(pProfile
->m_Stamp
), sizeof(osl_TStamp
)))
2157 pProfile
->m_Stamp
= Stamp
;
2159 bRet
=loadProfile(pProfile
->m_pFile
, pProfile
);
2165 #ifdef DEBUG_OSL_PROFILE
2166 OSL_TRACE("Profile acquire READ/WRITELOCK MODE\n");
2168 /* A readlock file could not be written */
2169 if ((pProfile
->m_Flags
& osl_Profile_READLOCK
) && bWriteable
)
2180 static sal_Bool
releaseProfile(osl_TProfileImpl
* pProfile
)
2182 sal_Bool bRet
=sal_False
;
2184 #ifdef TRACE_OSL_PROFILE
2185 OSL_TRACE("In releaseProfile\n");
2188 if ( pProfile
== 0 )
2190 #ifdef TRACE_OSL_PROFILE
2191 OSL_TRACE("Out releaseProfile [profile==0]\n");
2196 if (pProfile
->m_Flags
& FLG_AUTOOPEN
)
2198 #ifdef TRACE_OSL_PROFILE
2199 OSL_TRACE("Out releaseProfile [AUTOOPEN]\n");
2201 return (osl_closeProfile((oslProfile
)pProfile
));
2205 #ifdef DEBUG_OSL_PROFILE
2206 OSL_TRACE("DEFAULT MODE\n");
2208 if (! (pProfile
->m_Flags
& (osl_Profile_READLOCK
| osl_Profile_WRITELOCK
| osl_Profile_FLUSHWRITE
)))
2210 if (pProfile
->m_Flags
& FLG_MODIFIED
)
2212 bRet
=storeProfile(pProfile
, sal_False
);
2217 closeFileImpl(pProfile
->m_pFile
,pProfile
->m_Flags
);
2218 pProfile
->m_pFile
= NULL
;
2222 #ifdef TRACE_OSL_PROFILE
2223 OSL_TRACE("Out releaseProfile [ok]\n");