1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include "readwrite_helper.h"
23 #include <osl/diagnose.h>
24 #include <osl/profile.h>
25 #include <osl/process.h>
26 #include <osl/thread.h>
27 #include <rtl/alloc.h>
31 #define SECTIONS_INI 5
32 #define SECTIONS_ADD 3
36 #define STR_INI_BOOLYES "yes"
37 #define STR_INI_BOOLON "on"
38 #define STR_INI_BOOLONE "1"
39 #define STR_INI_BOOLNO "no"
40 #define STR_INI_BOOLOFF "off"
41 #define STR_INI_BOOLZERO "0"
43 #define FLG_USER 0x00FF
44 #define FLG_AUTOOPEN 0x0100
45 #define FLG_MODIFIED 0x0200
47 #define DEFAULT_PMODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)
49 /*#define DEBUG_OSL_PROFILE*/
50 /*#define TRACE_OSL_PROFILE*/
52 typedef time_t osl_TStamp
;
54 typedef enum _osl_TLockMode
56 un_lock
, read_lock
, write_lock
59 typedef struct _osl_TFile
63 sal_Char m_ReadBuf
[512];
64 sal_Char
* m_pWriteBuf
;
65 sal_uInt32 m_nWriteBufLen
;
66 sal_uInt32 m_nWriteBufFree
;
69 typedef struct _osl_TProfileEntry
76 typedef struct _osl_TProfileSection
81 sal_uInt32 m_NoEntries
;
82 sal_uInt32 m_MaxEntries
;
83 osl_TProfileEntry
* m_Entries
;
84 } osl_TProfileSection
;
87 /* Profile-data structure hidden behind oslProfile: */
88 typedef struct _osl_TProfileImpl
93 sal_Char m_FileName
[PATH_MAX
+ 1];
95 sal_uInt32 m_MaxLines
;
96 sal_uInt32 m_NoSections
;
97 sal_uInt32 m_MaxSections
;
99 osl_TProfileSection
* m_Sections
;
100 pthread_mutex_t m_AccessLock
;
104 static osl_TFile
* openFileImpl(const sal_Char
* pszFilename
, oslProfileOption ProfileFlags
);
105 static osl_TStamp
closeFileImpl(osl_TFile
* pFile
, oslProfileOption Flags
);
106 static sal_Bool
OslProfile_lockFile(const osl_TFile
* pFile
, osl_TLockMode eMode
);
107 static sal_Bool
OslProfile_rewindFile(osl_TFile
* pFile
, sal_Bool bTruncate
);
108 static osl_TStamp
OslProfile_getFileStamp(osl_TFile
* pFile
);
110 static sal_Char
* OslProfile_getLine(osl_TFile
* pFile
);
111 static sal_Bool
OslProfile_putLine(osl_TFile
* pFile
, const sal_Char
*pszLine
);
112 static sal_Char
* stripBlanks(sal_Char
* String
, sal_uInt32
* pLen
);
113 static sal_Char
* addLine(osl_TProfileImpl
* pProfile
, const sal_Char
* Line
);
114 static sal_Char
* insertLine(osl_TProfileImpl
* pProfile
, const sal_Char
* Line
, sal_uInt32 LineNo
);
115 static void removeLine(osl_TProfileImpl
* pProfile
, sal_uInt32 LineNo
);
116 static void setEntry(osl_TProfileImpl
* pProfile
, osl_TProfileSection
* pSection
,
117 sal_uInt32 NoEntry
, sal_uInt32 Line
,
118 sal_Char
* Entry
, sal_uInt32 Len
);
119 static sal_Bool
addEntry(osl_TProfileImpl
* pProfile
, osl_TProfileSection
*pSection
,
120 int Line
, sal_Char
* Entry
, sal_uInt32 Len
);
121 static void removeEntry(osl_TProfileSection
*pSection
, sal_uInt32 NoEntry
);
122 static sal_Bool
addSection(osl_TProfileImpl
* pProfile
, int Line
, const sal_Char
* Section
, sal_uInt32 Len
);
123 static void removeSection(osl_TProfileImpl
* pProfile
, osl_TProfileSection
*pSection
);
124 static osl_TProfileSection
* findEntry(osl_TProfileImpl
* pProfile
, const sal_Char
* Section
,
125 const sal_Char
* Entry
, sal_uInt32
*pNoEntry
);
126 static sal_Bool
loadProfile(osl_TFile
* pFile
, osl_TProfileImpl
* pProfile
);
127 static sal_Bool
storeProfile(osl_TProfileImpl
* pProfile
, sal_Bool bCleanup
);
128 static osl_TProfileImpl
* acquireProfile(oslProfile Profile
, sal_Bool bWriteable
);
129 static sal_Bool
releaseProfile(osl_TProfileImpl
* pProfile
);
131 static sal_Bool
writeProfileImpl (osl_TFile
* pFile
);
132 static osl_TFile
* osl_openTmpProfileImpl(osl_TProfileImpl
*);
133 static sal_Bool
osl_ProfileSwapProfileNames(osl_TProfileImpl
*);
134 static void osl_ProfileGenerateExtension(const sal_Char
* pszFileName
, const sal_Char
* pszExtension
, sal_Char
* pszTmpName
, int BufferMaxLen
);
135 static oslProfile SAL_CALL
osl_psz_openProfile(const sal_Char
*pszProfileName
, oslProfileOption Flags
);
137 /* implemented in file.c */
138 extern oslFileError
FileURLToPath( char *, size_t, rtl_uString
* );
140 oslProfile SAL_CALL
osl_openProfile(rtl_uString
*ustrProfileName
, oslProfileOption Options
)
142 char profilePath
[PATH_MAX
] = "";
144 if ( ustrProfileName
!= 0 && ustrProfileName
->buffer
[0] != 0 )
145 FileURLToPath( profilePath
, PATH_MAX
, ustrProfileName
);
147 return osl_psz_openProfile( profilePath
,Options
);
150 static oslProfile SAL_CALL
osl_psz_openProfile(const sal_Char
*pszProfileName
, oslProfileOption Flags
)
153 osl_TProfileImpl
* pProfile
;
154 sal_Bool bRet
= sal_False
;
156 #ifdef TRACE_OSL_PROFILE
157 OSL_TRACE("In osl_openProfile");
160 #ifdef DEBUG_OSL_PROFILE
161 Flags
=osl_Profile_FLUSHWRITE
;
163 OSL_TRACE("opening '%s'",pszProfileName
);
164 if ( Flags
== osl_Profile_DEFAULT
)
166 OSL_TRACE("with osl_Profile_DEFAULT");
168 if ( Flags
& osl_Profile_SYSTEM
)
170 OSL_TRACE("with osl_Profile_SYSTEM");
172 if ( Flags
& osl_Profile_READLOCK
)
174 OSL_TRACE("with osl_Profile_READLOCK");
176 if ( Flags
& osl_Profile_WRITELOCK
)
178 OSL_TRACE("with osl_Profile_WRITELOCK");
180 if ( Flags
& osl_Profile_FLUSHWRITE
)
182 OSL_TRACE("with osl_Profile_FLUSHWRITE");
187 if ( ( pFile
= openFileImpl(pszProfileName
, Flags
) ) == NULL
)
189 #ifdef TRACE_OSL_PROFILE
190 OSL_TRACE("Out osl_openProfile [not opened]");
196 pProfile
= (osl_TProfileImpl
*)calloc(1, sizeof(osl_TProfileImpl
));
200 closeFileImpl(pFile
, Flags
);
204 pProfile
->m_Flags
= Flags
& FLG_USER
;
206 if ( Flags
& ( osl_Profile_READLOCK
| osl_Profile_WRITELOCK
| osl_Profile_FLUSHWRITE
) )
208 pProfile
->m_pFile
= pFile
;
211 pthread_mutex_init(&(pProfile
->m_AccessLock
),PTHREAD_MUTEXATTR_DEFAULT
);
212 pProfile
->m_bIsValid
=sal_True
;
214 pProfile
->m_Stamp
= OslProfile_getFileStamp(pFile
);
215 bRet
=loadProfile(pFile
, pProfile
);
216 bRet
&= realpath(pszProfileName
, pProfile
->m_FileName
) != NULL
;
219 if (pProfile
->m_pFile
== NULL
)
220 closeFileImpl(pFile
,pProfile
->m_Flags
);
222 #ifdef TRACE_OSL_PROFILE
223 OSL_TRACE("Out osl_openProfile [ok]");
228 sal_Bool SAL_CALL
osl_closeProfile(oslProfile Profile
)
230 osl_TProfileImpl
* pProfile
= (osl_TProfileImpl
*)Profile
;
231 osl_TProfileImpl
* pTmpProfile
;
233 #ifdef TRACE_OSL_PROFILE
234 OSL_TRACE("In osl_closeProfile");
239 #ifdef TRACE_OSL_PROFILE
240 OSL_TRACE("Out osl_closeProfile [profile==0]");
245 pthread_mutex_lock(&(pProfile
->m_AccessLock
));
247 if ( pProfile
->m_bIsValid
== sal_False
)
249 OSL_ASSERT(pProfile
->m_bIsValid
);
250 pthread_mutex_unlock(&(pProfile
->m_AccessLock
));
251 #ifdef TRACE_OSL_PROFILE
252 OSL_TRACE("Out osl_closeProfile [not valid]");
257 pProfile
->m_bIsValid
=sal_False
;
259 if ( ! ( pProfile
->m_Flags
& osl_Profile_READLOCK
) && ( pProfile
->m_Flags
& FLG_MODIFIED
) )
261 pTmpProfile
= acquireProfile(Profile
,sal_True
);
263 if ( pTmpProfile
!= 0 )
265 sal_Bool bRet
= storeProfile(pTmpProfile
, sal_True
);
272 pTmpProfile
= acquireProfile(Profile
,sal_False
);
276 if ( pTmpProfile
== 0 )
278 pthread_mutex_unlock(&(pProfile
->m_AccessLock
));
279 #ifdef TRACE_OSL_PROFILE
280 OSL_TRACE("Out osl_closeProfile [pProfile==0]");
285 pProfile
= pTmpProfile
;
287 if (pProfile
->m_pFile
!= NULL
)
288 closeFileImpl(pProfile
->m_pFile
,pProfile
->m_Flags
);
290 pProfile
->m_pFile
= NULL
;
291 pProfile
->m_FileName
[0] = '\0';
293 /* release whole profile data types memory */
294 if ( pProfile
->m_NoLines
> 0)
297 if ( pProfile
->m_Lines
!= 0 )
299 for ( idx
= 0 ; idx
< pProfile
->m_NoLines
; ++idx
)
301 if ( pProfile
->m_Lines
[idx
] != 0 )
303 free(pProfile
->m_Lines
[idx
]);
304 pProfile
->m_Lines
[idx
]=0;
307 free(pProfile
->m_Lines
);
310 if ( pProfile
->m_Sections
!= 0 )
312 /*osl_TProfileSection* pSections=pProfile->m_Sections;*/
313 for ( idx
= 0 ; idx
< pProfile
->m_NoSections
; ++idx
)
315 if ( pProfile
->m_Sections
[idx
].m_Entries
!= 0 )
317 free(pProfile
->m_Sections
[idx
].m_Entries
);
318 pProfile
->m_Sections
[idx
].m_Entries
=0;
321 free(pProfile
->m_Sections
);
322 pProfile
->m_Sections
=0;
326 pthread_mutex_unlock(&(pProfile
->m_AccessLock
));
328 pthread_mutex_destroy(&(pProfile
->m_AccessLock
));
332 #ifdef TRACE_OSL_PROFILE
333 OSL_TRACE("Out osl_closeProfile [ok]");
339 sal_Bool SAL_CALL
osl_flushProfile(oslProfile Profile
)
341 osl_TProfileImpl
* pProfile
= (osl_TProfileImpl
*) Profile
;
343 sal_Bool bRet
= sal_False
;
345 #ifdef TRACE_OSL_PROFILE
346 OSL_TRACE("In osl_flushProfile()");
351 #ifdef TRACE_OSL_PROFILE
352 OSL_TRACE("Out osl_flushProfile() [pProfile == 0]");
357 pthread_mutex_lock(&(pProfile
->m_AccessLock
));
359 if ( pProfile
->m_bIsValid
== sal_False
)
361 OSL_ASSERT(pProfile
->m_bIsValid
);
362 pthread_mutex_unlock(&(pProfile
->m_AccessLock
));
363 #ifdef TRACE_OSL_PROFILE
364 OSL_TRACE("Out osl_flushProfile [not valid]");
369 pFile
= pProfile
->m_pFile
;
370 if ( !( pFile
!= 0 && pFile
->m_Handle
>= 0 ) )
372 pthread_mutex_unlock(&(pProfile
->m_AccessLock
));
373 #ifdef TRACE_OSL_PROFILE
374 OSL_TRACE("Out osl_flushProfile() [invalid file]");
379 if ( pProfile
->m_Flags
& FLG_MODIFIED
)
381 #ifdef DEBUG_OSL_PROFILE
382 OSL_TRACE("swapping to storeprofile");
384 bRet
= storeProfile(pProfile
,sal_False
);
388 #ifdef TRACE_OSL_PROFILE
389 OSL_TRACE("Out osl_flushProfile() [ok]");
391 pthread_mutex_unlock(&(pProfile
->m_AccessLock
));
395 static sal_Bool
writeProfileImpl(osl_TFile
* pFile
)
397 #if OSL_DEBUG_LEVEL > 1
401 #ifdef TRACE_OSL_PROFILE
402 OSL_TRACE("In osl_writeProfileImpl()");
405 if ( !( pFile
!= 0 && pFile
->m_Handle
>= 0 ) || ( pFile
->m_pWriteBuf
== 0 ) )
407 #ifdef TRACE_OSL_PROFILE
408 OSL_TRACE("Out osl_writeProfileImpl() [invalid args]");
413 #if OSL_DEBUG_LEVEL > 1
414 nLen
=strlen(pFile
->m_pWriteBuf
);
415 OSL_ASSERT(nLen
== (pFile
->m_nWriteBufLen
- pFile
->m_nWriteBufFree
));
418 if ( !safeWrite(pFile
->m_Handle
, pFile
->m_pWriteBuf
, pFile
->m_nWriteBufLen
- pFile
->m_nWriteBufFree
) )
420 OSL_TRACE("write failed '%s'",strerror(errno
));
424 free(pFile
->m_pWriteBuf
);
425 pFile
->m_pWriteBuf
=0;
426 pFile
->m_nWriteBufLen
=0;
427 pFile
->m_nWriteBufFree
=0;
428 #ifdef TRACE_OSL_PROFILE
429 OSL_TRACE("Out osl_writeProfileImpl() [ok]");
435 sal_Bool SAL_CALL
osl_readProfileString(oslProfile Profile
,
436 const sal_Char
* pszSection
,
437 const sal_Char
* pszEntry
,
440 const sal_Char
* pszDefault
)
444 osl_TProfileSection
* pSec
;
445 osl_TProfileImpl
* pProfile
=0;
446 osl_TProfileImpl
* pTmpProfile
=0;
447 sal_Bool bRet
= sal_False
;
449 #ifdef TRACE_OSL_PROFILE
450 OSL_TRACE("In osl_readProfileString");
453 pTmpProfile
= (osl_TProfileImpl
*) Profile
;
455 if ( pTmpProfile
== 0 )
457 #ifdef TRACE_OSL_PROFILE
458 OSL_TRACE("Out osl_readProfileString [pTmpProfile==0]");
463 pthread_mutex_lock(&(pTmpProfile
->m_AccessLock
));
465 if ( pTmpProfile
->m_bIsValid
== sal_False
)
467 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
468 #ifdef TRACE_OSL_PROFILE
469 OSL_TRACE("Out osl_readProfileString [not valid]");
474 pProfile
= acquireProfile(Profile
, sal_False
);
476 if ( pProfile
== NULL
)
478 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
479 #ifdef TRACE_OSL_PROFILE
480 OSL_TRACE("Out osl_readProfileString [pProfile==0]");
485 if (! (pProfile
->m_Flags
& osl_Profile_SYSTEM
))
487 if (((pSec
= findEntry(pProfile
, pszSection
, pszEntry
, &NoEntry
)) != NULL
) &&
488 (NoEntry
< pSec
->m_NoEntries
) &&
489 ((pStr
= strchr(pProfile
->m_Lines
[pSec
->m_Entries
[NoEntry
].m_Line
],
496 pStr
=(sal_Char
*)pszDefault
;
501 pStr
= stripBlanks(pStr
, NULL
);
502 MaxLen
= (MaxLen
- 1 < strlen(pStr
)) ? (MaxLen
- 1) : strlen(pStr
);
503 pStr
= stripBlanks(pStr
, &MaxLen
);
504 strncpy(pszString
, pStr
, MaxLen
);
505 pszString
[MaxLen
] = '\0';
509 { /* not implemented */ }
512 bRet
=releaseProfile(pProfile
);
518 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
519 #ifdef TRACE_OSL_PROFILE
520 OSL_TRACE("Out osl_readProfileString [pStr==0]");
525 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
527 #ifdef TRACE_OSL_PROFILE
528 OSL_TRACE("Out osl_readProfileString [ok]");
534 sal_Bool SAL_CALL
osl_readProfileBool(oslProfile Profile
,
535 const sal_Char
* pszSection
,
536 const sal_Char
* pszEntry
,
542 #ifdef TRACE_OSL_PROFILE
543 OSL_TRACE("In osl_readProfileBool");
546 if (osl_readProfileString(Profile
, pszSection
, pszEntry
, Line
, sizeof(Line
), ""))
548 if ((strcasecmp(Line
, STR_INI_BOOLYES
) == 0) ||
549 (strcasecmp(Line
, STR_INI_BOOLON
) == 0) ||
550 (strcasecmp(Line
, STR_INI_BOOLONE
) == 0))
553 if ((strcasecmp(Line
, STR_INI_BOOLNO
) == 0) ||
554 (strcasecmp(Line
, STR_INI_BOOLOFF
) == 0) ||
555 (strcasecmp(Line
, STR_INI_BOOLZERO
) == 0))
559 #ifdef TRACE_OSL_PROFILE
560 OSL_TRACE("Out osl_readProfileBool [ok]");
566 sal_uInt32 SAL_CALL
osl_readProfileIdent(oslProfile Profile
,
567 const sal_Char
* pszSection
,
568 const sal_Char
* pszEntry
,
570 const sal_Char
* Strings
[],
577 #ifdef TRACE_OSL_PROFILE
578 OSL_TRACE("In osl_readProfileIdent");
581 if (osl_readProfileString(Profile
, pszSection
, pszEntry
, Line
, sizeof(Line
), ""))
584 while (Strings
[i
] != NULL
)
586 if (strcasecmp(Line
, Strings
[i
]) == 0)
588 Default
= i
+ FirstId
;
595 #ifdef TRACE_OSL_PROFILE
596 OSL_TRACE("Out osl_readProfileIdent [ok]");
601 sal_Bool SAL_CALL
osl_writeProfileString(oslProfile Profile
,
602 const sal_Char
* pszSection
,
603 const sal_Char
* pszEntry
,
604 const sal_Char
* pszString
)
607 sal_Bool bRet
= sal_False
;
611 osl_TProfileSection
* pSec
;
612 osl_TProfileImpl
* pProfile
= 0;
613 osl_TProfileImpl
* pTmpProfile
= 0;
615 #ifdef TRACE_OSL_PROFILE
616 OSL_TRACE("In osl_writeProfileString");
619 pTmpProfile
= (osl_TProfileImpl
*) Profile
;
621 if ( pTmpProfile
== 0 )
623 #ifdef TRACE_OSL_PROFILE
624 OSL_TRACE("Out osl_writeProfileString [pTmpProfile==0]");
629 pthread_mutex_lock(&(pTmpProfile
->m_AccessLock
));
631 if ( pTmpProfile
->m_bIsValid
== sal_False
)
633 OSL_ASSERT(pTmpProfile
->m_bIsValid
);
634 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
635 #ifdef TRACE_OSL_PROFILE
636 OSL_TRACE("Out osl_writeProfileString [not valid]");
641 pProfile
=acquireProfile(Profile
, sal_True
);
643 if (pProfile
== NULL
)
645 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
646 #ifdef TRACE_OSL_PROFILE
647 OSL_TRACE("Out osl_writeProfileString [pProfile==0]");
652 Line
= (sal_Char
*) malloc(strlen(pszEntry
)+strlen(pszString
)+48);
654 if (! (pProfile
->m_Flags
& osl_Profile_SYSTEM
))
656 if ((pSec
= findEntry(pProfile
, pszSection
, pszEntry
, &NoEntry
)) == NULL
)
659 addLine(pProfile
, Line
);
662 strcpy(&Line
[1], pszSection
);
663 Line
[1 + strlen(pszSection
)] = ']';
664 Line
[2 + strlen(pszSection
)] = '\0';
666 if (((pStr
= addLine(pProfile
, Line
)) == NULL
) ||
667 (! addSection(pProfile
, pProfile
->m_NoLines
- 1, &pStr
[1], strlen(pszSection
))))
669 bRet
=releaseProfile(pProfile
);
672 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
676 #ifdef TRACE_OSL_PROFILE
677 OSL_TRACE("Out osl_writeProfileString [not added]");
682 pSec
= &pProfile
->m_Sections
[pProfile
->m_NoSections
- 1];
683 NoEntry
= pSec
->m_NoEntries
;
687 strcpy(&Line
[0], pszEntry
);
688 Line
[0 + strlen(pszEntry
)] = '=';
689 strcpy(&Line
[1 + strlen(pszEntry
)], pszString
);
691 if (NoEntry
>= pSec
->m_NoEntries
)
693 if (pSec
->m_NoEntries
> 0)
694 i
= pSec
->m_Entries
[pSec
->m_NoEntries
- 1].m_Line
+ 1;
696 i
= pSec
->m_Line
+ 1;
698 if (((pStr
= insertLine(pProfile
, Line
, i
)) == NULL
) ||
699 (! addEntry(pProfile
, pSec
, i
, pStr
, strlen(pszEntry
))))
701 bRet
=releaseProfile(pProfile
);
704 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
707 #ifdef TRACE_OSL_PROFILE
708 OSL_TRACE("Out osl_writeProfileString [not inserted]");
713 pProfile
->m_Flags
|= FLG_MODIFIED
;
717 i
= pSec
->m_Entries
[NoEntry
].m_Line
;
718 free(pProfile
->m_Lines
[i
]);
719 pProfile
->m_Lines
[i
] = strdup(Line
);
720 setEntry(pProfile
, pSec
, NoEntry
, i
, pProfile
->m_Lines
[i
], strlen(pszEntry
));
722 pProfile
->m_Flags
|= FLG_MODIFIED
;
726 /* not implemented */
729 bRet
= releaseProfile(pProfile
);
732 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
738 #ifdef TRACE_OSL_PROFILE
739 OSL_TRACE("Out osl_writeProfileString [ok]");
745 sal_Bool SAL_CALL
osl_writeProfileBool(oslProfile Profile
,
746 const sal_Char
* pszSection
,
747 const sal_Char
* pszEntry
,
750 sal_Bool bRet
=sal_False
;
752 #ifdef TRACE_OSL_PROFILE
753 OSL_TRACE("In osl_writeProfileBool");
757 bRet
=osl_writeProfileString(Profile
, pszSection
, pszEntry
, STR_INI_BOOLONE
);
759 bRet
=osl_writeProfileString(Profile
, pszSection
, pszEntry
, STR_INI_BOOLZERO
);
761 #ifdef TRACE_OSL_PROFILE
762 OSL_TRACE("Out osl_writeProfileBool [ok]");
768 sal_Bool SAL_CALL
osl_writeProfileIdent(oslProfile Profile
,
769 const sal_Char
* pszSection
,
770 const sal_Char
* pszEntry
,
772 const sal_Char
* Strings
[],
776 sal_Bool bRet
=sal_False
;
778 #ifdef TRACE_OSL_PROFILE
779 OSL_TRACE("In osl_writeProfileIdent");
782 while (Strings
[n
] != NULL
)
785 if ((i
= Value
- FirstId
) >= n
)
788 bRet
= osl_writeProfileString(Profile
, pszSection
, pszEntry
, Strings
[i
]);
790 #ifdef TRACE_OSL_PROFILE
791 OSL_TRACE("Out osl_writeProfileIdent");
796 sal_Bool SAL_CALL
osl_removeProfileEntry(oslProfile Profile
,
797 const sal_Char
*pszSection
,
798 const sal_Char
*pszEntry
)
801 osl_TProfileSection
* pSec
;
802 osl_TProfileImpl
* pProfile
= 0;
803 osl_TProfileImpl
* pTmpProfile
= 0;
804 sal_Bool bRet
= sal_False
;
806 #ifdef TRACE_OSL_PROFILE
807 OSL_TRACE("In osl_removeProfileEntry");
810 pTmpProfile
= (osl_TProfileImpl
*) Profile
;
812 if ( pTmpProfile
== 0 )
814 #ifdef TRACE_OSL_PROFILE
815 OSL_TRACE("Out osl_removeProfileEntry [pProfile==0]");
820 pthread_mutex_lock(&(pTmpProfile
->m_AccessLock
));
822 if ( pTmpProfile
->m_bIsValid
== sal_False
)
824 OSL_ASSERT(pTmpProfile
->m_bIsValid
);
825 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
826 #ifdef TRACE_OSL_PROFILE
827 OSL_TRACE("Out osl_removeProfileEntry [not valid]");
833 pProfile
= acquireProfile(Profile
, sal_True
);
835 if (pProfile
== NULL
)
837 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
838 #ifdef TRACE_OSL_PROFILE
839 OSL_TRACE("Out osl_removeProfileEntry [pProfile==0]");
845 if (! (pProfile
->m_Flags
& osl_Profile_SYSTEM
))
847 if (((pSec
= findEntry(pProfile
, pszSection
, pszEntry
, &NoEntry
)) != NULL
) &&
848 (NoEntry
< pSec
->m_NoEntries
))
850 removeLine(pProfile
, pSec
->m_Entries
[NoEntry
].m_Line
);
851 removeEntry(pSec
, NoEntry
);
852 if (pSec
->m_NoEntries
== 0)
854 removeLine(pProfile
, pSec
->m_Line
);
856 /* remove any empty separation line */
857 if ((pSec
->m_Line
> 0) && (pProfile
->m_Lines
[pSec
->m_Line
- 1][0] == '\0'))
858 removeLine(pProfile
, pSec
->m_Line
- 1);
860 removeSection(pProfile
, pSec
);
863 pProfile
->m_Flags
|= FLG_MODIFIED
;
867 { /* not implemented */ }
870 bRet
= releaseProfile(pProfile
);
873 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
875 #ifdef TRACE_OSL_PROFILE
876 OSL_TRACE("Out osl_removeProfileEntry [ok]");
881 sal_uInt32 SAL_CALL
osl_getProfileSectionEntries(oslProfile Profile
,
882 const sal_Char
*pszSection
,
888 osl_TProfileSection
* pSec
;
889 osl_TProfileImpl
* pProfile
= 0;
890 osl_TProfileImpl
* pTmpProfile
= 0;
891 sal_Bool bRet
= sal_False
;
893 #ifdef TRACE_OSL_PROFILE
894 OSL_TRACE("In osl_getProfileSectionEntries");
897 pTmpProfile
= (osl_TProfileImpl
*) Profile
;
899 if ( pTmpProfile
== 0 )
901 #ifdef TRACE_OSL_PROFILE
902 OSL_TRACE("Out osl_getProfileSectionEntries [pTmpProfile==0]");
908 pthread_mutex_lock(&(pTmpProfile
->m_AccessLock
));
910 if ( pTmpProfile
->m_bIsValid
== sal_False
)
912 OSL_ASSERT(pTmpProfile
->m_bIsValid
);
914 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
916 #ifdef TRACE_OSL_PROFILE
917 OSL_TRACE("Out osl_getProfileSectionEntries [not valid]");
923 pProfile
= acquireProfile(Profile
, sal_False
);
925 if (pProfile
== NULL
)
927 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
929 #ifdef TRACE_OSL_PROFILE
930 OSL_TRACE("Out osl_getProfileSectionEntries [pProfile=0]");
937 if (! (pProfile
->m_Flags
& osl_Profile_SYSTEM
))
939 if ((pSec
= findEntry(pProfile
, pszSection
, "", &NoEntry
)) != NULL
)
943 for (i
= 0; i
< pSec
->m_NoEntries
; i
++)
945 if ((n
+ pSec
->m_Entries
[i
].m_Len
+ 1) < MaxLen
)
947 strncpy(&pszBuffer
[n
], &pProfile
->m_Lines
[pSec
->m_Entries
[i
].m_Line
]
948 [pSec
->m_Entries
[i
].m_Offset
], pSec
->m_Entries
[i
].m_Len
);
949 n
+= pSec
->m_Entries
[i
].m_Len
;
950 pszBuffer
[n
++] = '\0';
957 pszBuffer
[n
++] = '\0';
961 for (i
= 0; i
< pSec
->m_NoEntries
; i
++)
962 n
+= pSec
->m_Entries
[i
].m_Len
+ 1;
971 /* not implemented */
974 bRet
=releaseProfile(pProfile
);
978 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
980 #ifdef TRACE_OSL_PROFILE
981 OSL_TRACE("Out osl_getProfileSectionEntries [ok]");
987 sal_uInt32 SAL_CALL
osl_getProfileSections(oslProfile Profile
,
992 osl_TProfileSection
* pSec
;
993 osl_TProfileImpl
* pProfile
= 0;
994 osl_TProfileImpl
* pTmpProfile
= 0;
995 sal_Bool bRet
= sal_False
;
997 #ifdef TRACE_OSL_PROFILE
998 OSL_TRACE("In osl_getProfileSections");
1001 pTmpProfile
= (osl_TProfileImpl
*) Profile
;
1003 if ( pTmpProfile
== 0 )
1005 #ifdef TRACE_OSL_PROFILE
1006 OSL_TRACE("Out osl_getProfileSections [pTmpProfile==0]");
1011 pthread_mutex_lock(&(pTmpProfile
->m_AccessLock
));
1013 if ( pTmpProfile
->m_bIsValid
== sal_False
)
1015 OSL_ASSERT(pTmpProfile
->m_bIsValid
);
1016 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
1017 #ifdef TRACE_OSL_PROFILE
1018 OSL_TRACE("Out osl_getProfileSections [not valid]");
1023 pProfile
= acquireProfile(Profile
, sal_False
);
1025 if (pProfile
== NULL
)
1027 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
1029 #ifdef TRACE_OSL_PROFILE
1030 OSL_TRACE("Out osl_getProfileSections [pProfile==0]");
1035 if (! (pProfile
->m_Flags
& osl_Profile_SYSTEM
))
1039 for (i
= 0; i
< pProfile
->m_NoSections
; i
++)
1041 pSec
= &pProfile
->m_Sections
[i
];
1043 if ((n
+ pSec
->m_Len
+ 1) < MaxLen
)
1045 strncpy(&pszBuffer
[n
], &pProfile
->m_Lines
[pSec
->m_Line
][pSec
->m_Offset
],
1048 pszBuffer
[n
++] = '\0';
1054 pszBuffer
[n
++] = '\0';
1058 for (i
= 0; i
< pProfile
->m_NoSections
; i
++)
1059 n
+= pProfile
->m_Sections
[i
].m_Len
+ 1;
1065 { /* not implemented */ }
1068 bRet
=releaseProfile(pProfile
);
1072 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
1074 #ifdef TRACE_OSL_PROFILE
1075 OSL_TRACE("Out osl_getProfileSections [ok]");
1081 static osl_TStamp
OslProfile_getFileStamp(osl_TFile
* pFile
)
1085 if ( (pFile
->m_Handle
< 0) || (fstat(pFile
->m_Handle
, &status
) < 0) )
1091 return (status
.st_mtime
);
1094 static sal_Bool
OslProfile_lockFile(const osl_TFile
* pFile
, osl_TLockMode eMode
)
1097 /* boring hack, but initializers for static vars must be constant */
1098 static sal_Bool bIsInitialized
= sal_False
;
1099 static sal_Bool bLockingDisabled
;
1101 #ifdef TRACE_OSL_PROFILE
1102 OSL_TRACE("In OslProfile_lockFile");
1105 if ( !bIsInitialized
)
1107 sal_Char
* pEnvValue
;
1108 pEnvValue
= getenv( "STAR_PROFILE_LOCKING_DISABLED" );
1110 if ( pEnvValue
== 0 )
1112 bLockingDisabled
= sal_False
;
1117 bLockingDisabled
= sal_True
;
1120 bIsInitialized
= sal_True
;
1123 if (pFile
->m_Handle
< 0)
1125 #ifdef TRACE_OSL_PROFILE
1126 OSL_TRACE("Out OslProfile_lockFile [invalid file handle]");
1132 if ( bLockingDisabled
)
1134 #ifdef TRACE_OSL_PROFILE
1135 OSL_TRACE("Out OslProfile_lockFile [locking disabled]");
1142 lock
.l_whence
= SEEK_SET
;
1148 lock
.l_type
= F_UNLCK
;
1152 lock
.l_type
= F_RDLCK
;
1156 lock
.l_type
= F_WRLCK
;
1161 if ( fcntl(pFile
->m_Handle
, F_SETLKW
, &lock
) == -1 )
1163 /* Mac OSX will return ENOTSUP for webdav drives so we should ignore it */
1164 if ( fcntl(pFile
->m_Handle
, F_SETLKW
, &lock
) == -1 && errno
!= ENOTSUP
)
1167 OSL_TRACE("fcntl returned -1 (%s)",strerror(errno
));
1168 #ifdef TRACE_OSL_PROFILE
1169 OSL_TRACE("Out OslProfile_lockFile [fcntl F_SETLKW]");
1174 #ifdef TRACE_OSL_PROFILE
1175 OSL_TRACE("Out OslProfile_lockFile [ok]");
1180 static osl_TFile
* openFileImpl(const sal_Char
* pszFilename
, oslProfileOption ProfileFlags
)
1183 osl_TFile
* pFile
= (osl_TFile
*) calloc(1, sizeof(osl_TFile
));
1184 sal_Bool bWriteable
= sal_False
;
1186 if ( ProfileFlags
& ( osl_Profile_WRITELOCK
| osl_Profile_FLUSHWRITE
) )
1188 #ifdef DEBUG_OSL_PROFILE
1189 OSL_TRACE("setting bWriteable to TRUE");
1191 bWriteable
=sal_True
;
1196 #ifdef DEBUG_OSL_PROFILE
1197 OSL_TRACE("opening '%s' read only",pszFilename
);
1200 pFile
->m_Handle
= open(pszFilename
, O_RDONLY
);
1201 /* mfe: argghh!!! do not check if the file could be openend */
1202 /* default mode expects it that way!!! */
1206 #ifdef DEBUG_OSL_PROFILE
1207 OSL_TRACE("opening '%s' read/write",pszFilename
);
1209 if (((pFile
->m_Handle
= open(pszFilename
, O_RDWR
| O_CREAT
| O_EXCL
, DEFAULT_PMODE
)) < 0) &&
1210 ((pFile
->m_Handle
= open(pszFilename
, O_RDWR
)) < 0))
1213 #ifdef TRACE_OSL_PROFILE
1214 OSL_TRACE("Out openFileImpl [open read/write]");
1220 /* set close-on-exec flag */
1221 if ((Flags
= fcntl(pFile
->m_Handle
, F_GETFD
, 0)) != -1)
1223 Flags
|= FD_CLOEXEC
;
1224 fcntl(pFile
->m_Handle
, F_SETFD
, Flags
);
1227 pFile
->m_pWriteBuf
=0;
1228 pFile
->m_nWriteBufFree
=0;
1229 pFile
->m_nWriteBufLen
=0;
1231 if ( ProfileFlags
& (osl_Profile_WRITELOCK
| osl_Profile_READLOCK
) )
1233 #ifdef DEBUG_OSL_PROFILE
1234 OSL_TRACE("locking '%s' file",pszFilename
);
1236 OslProfile_lockFile(pFile
, bWriteable
? write_lock
: read_lock
);
1239 #ifdef TRACE_OSL_PROFILE
1240 OSL_TRACE("Out openFileImpl [ok]");
1245 static osl_TStamp
closeFileImpl(osl_TFile
* pFile
, oslProfileOption Flags
)
1247 osl_TStamp stamp
= 0;
1249 #ifdef TRACE_OSL_PROFILE
1250 OSL_TRACE("In closeFileImpl");
1255 #ifdef TRACE_OSL_PROFILE
1256 OSL_TRACE("Out closeFileImpl [pFile == 0]");
1261 if ( pFile
->m_Handle
>= 0 )
1263 stamp
= OslProfile_getFileStamp(pFile
);
1265 if ( Flags
& (osl_Profile_WRITELOCK
| osl_Profile_READLOCK
) )
1267 OslProfile_lockFile(pFile
, un_lock
);
1270 close(pFile
->m_Handle
);
1271 pFile
->m_Handle
= -1;
1275 if ( pFile
->m_pWriteBuf
)
1277 free(pFile
->m_pWriteBuf
);
1282 #ifdef TRACE_OSL_PROFILE
1283 OSL_TRACE("Out closeFileImpl [ok]");
1289 static sal_Bool
OslProfile_rewindFile(osl_TFile
* pFile
, sal_Bool bTruncate
)
1291 sal_Bool bRet
= sal_True
;
1292 #ifdef TRACE_OSL_PROFILE
1293 OSL_TRACE("In osl_OslProfile_rewindFile");
1296 if (pFile
->m_Handle
>= 0)
1298 pFile
->m_pReadPtr
= pFile
->m_ReadBuf
+ sizeof(pFile
->m_ReadBuf
);
1300 #ifdef DEBUG_OSL_PROFILE
1301 OSL_TRACE("rewinding");
1303 bRet
= (lseek(pFile
->m_Handle
, SEEK_SET
, 0L) == 0L);
1307 #ifdef DEBUG_OSL_PROFILE
1308 OSL_TRACE("truncating");
1310 bRet
&= (ftruncate(pFile
->m_Handle
, 0L) == 0);
1315 #ifdef TRACE_OSL_PROFILE
1316 OSL_TRACE("Out osl_OslProfile_rewindFile [ok]");
1322 static sal_Char
* OslProfile_getLine(osl_TFile
* pFile
)
1324 int Max
, Free
, Bytes
, nLineBytes
= 0;
1326 sal_Char
* pLine
= NULL
;
1334 if (pFile
->m_Handle
< 0)
1339 Bytes
= sizeof(pFile
->m_ReadBuf
) - (pFile
->m_pReadPtr
- pFile
->m_ReadBuf
);
1344 memcpy(pFile
->m_ReadBuf
, pFile
->m_pReadPtr
, Bytes
);
1345 pFile
->m_pReadPtr
= pFile
->m_ReadBuf
;
1347 Free
= sizeof(pFile
->m_ReadBuf
) - Bytes
;
1349 if ((Max
= read(pFile
->m_Handle
, &pFile
->m_ReadBuf
[Bytes
], Free
)) < 0)
1351 OSL_TRACE("read failed '%s'",strerror(errno
));
1354 rtl_freeMemory( pLine
);
1361 if ((Max
== 0) && ! pLine
)
1364 pFile
->m_ReadBuf
[Bytes
+ Max
] = '\0';
1368 for (pChr
= pFile
->m_pReadPtr
;
1369 (*pChr
!= '\n') && (*pChr
!= '\r') && (*pChr
!= '\0') &&
1370 (pChr
< (pFile
->m_ReadBuf
+ sizeof(pFile
->m_ReadBuf
) - 1));
1373 Max
= pChr
- pFile
->m_pReadPtr
;
1374 pNewLine
= (sal_Char
*) rtl_allocateMemory( nLineBytes
+ Max
+ 1 );
1377 memcpy( pNewLine
, pLine
, nLineBytes
);
1378 rtl_freeMemory( pLine
);
1380 memcpy(pNewLine
+nLineBytes
, pFile
->m_pReadPtr
, Max
);
1382 pNewLine
[ nLineBytes
] = 0;
1385 if (pChr
< (pFile
->m_ReadBuf
+ sizeof(pFile
->m_ReadBuf
) - 1))
1389 if ((pChr
[0] == '\r') && (pChr
[1] == '\n'))
1395 if ((pChr
< (pFile
->m_ReadBuf
+ sizeof(pFile
->m_ReadBuf
))) &&
1397 pChr
= pFile
->m_ReadBuf
+ sizeof(pFile
->m_ReadBuf
);
1399 /* setting Max to -1 indicates terminating read loop */
1403 pFile
->m_pReadPtr
= pChr
;
1410 static sal_Bool
OslProfile_putLine(osl_TFile
* pFile
, const sal_Char
*pszLine
)
1412 unsigned int Len
= strlen(pszLine
);
1414 #ifdef DEBUG_OSL_PROFILE
1418 if ( pFile
== 0 || pFile
->m_Handle
< 0 )
1423 if ( pFile
->m_pWriteBuf
== 0 )
1425 pFile
->m_pWriteBuf
= (sal_Char
*) malloc(Len
+3);
1426 pFile
->m_nWriteBufLen
= Len
+3;
1427 pFile
->m_nWriteBufFree
= Len
+3;
1431 if ( pFile
->m_nWriteBufFree
<= Len
+ 3 )
1435 pTmp
=(sal_Char
*) realloc(pFile
->m_pWriteBuf
,( ( pFile
->m_nWriteBufLen
+ Len
) * 2) );
1440 pFile
->m_pWriteBuf
= pTmp
;
1441 pFile
->m_nWriteBufFree
= pFile
->m_nWriteBufFree
+ pFile
->m_nWriteBufLen
+ ( 2 * Len
);
1442 pFile
->m_nWriteBufLen
= ( pFile
->m_nWriteBufLen
+ Len
) * 2;
1443 memset( (pFile
->m_pWriteBuf
) + ( pFile
->m_nWriteBufLen
- pFile
->m_nWriteBufFree
), 0, pFile
->m_nWriteBufFree
);
1449 memcpy(pFile
->m_pWriteBuf
+ ( pFile
->m_nWriteBufLen
- pFile
->m_nWriteBufFree
),pszLine
,Len
+1);
1450 #ifdef DEBUG_OSL_PROFILE
1451 strLen
= strlen(pFile
->m_pWriteBuf
);
1453 pFile
->m_pWriteBuf
[pFile
->m_nWriteBufLen
- pFile
->m_nWriteBufFree
+ Len
]='\n';
1454 pFile
->m_pWriteBuf
[pFile
->m_nWriteBufLen
- pFile
->m_nWriteBufFree
+ Len
+ 1]='\0';
1456 pFile
->m_nWriteBufFree
-=Len
+1;
1461 static sal_Char
* stripBlanks(sal_Char
* String
, sal_uInt32
* pLen
)
1463 if ( ( pLen
!= NULL
) && ( *pLen
!= 0 ) )
1465 while ((String
[*pLen
- 1] == ' ') || (String
[*pLen
- 1] == '\t'))
1468 while ( (*String
== ' ') || (*String
== '\t') )
1475 while ( (*String
== ' ') || (*String
== '\t') )
1481 static sal_Char
* addLine(osl_TProfileImpl
* pProfile
, const sal_Char
* Line
)
1483 if (pProfile
->m_NoLines
>= pProfile
->m_MaxLines
)
1485 if (pProfile
->m_Lines
== NULL
)
1487 pProfile
->m_MaxLines
= LINES_INI
;
1488 pProfile
->m_Lines
= (sal_Char
**)malloc(pProfile
->m_MaxLines
* sizeof(sal_Char
*));
1489 memset(pProfile
->m_Lines
,0,pProfile
->m_MaxLines
* sizeof(sal_Char
*));
1494 unsigned int oldmax
=pProfile
->m_MaxLines
;
1496 pProfile
->m_MaxLines
+= LINES_ADD
;
1497 pProfile
->m_Lines
= (sal_Char
**)realloc(pProfile
->m_Lines
,
1498 pProfile
->m_MaxLines
* sizeof(sal_Char
*));
1499 for ( idx
= oldmax
; idx
< pProfile
->m_MaxLines
; ++idx
)
1501 pProfile
->m_Lines
[idx
]=0;
1505 if (pProfile
->m_Lines
== NULL
)
1507 pProfile
->m_NoLines
= 0;
1508 pProfile
->m_MaxLines
= 0;
1514 if ( pProfile
->m_Lines
!= 0 && pProfile
->m_Lines
[pProfile
->m_NoLines
] != 0 )
1516 free(pProfile
->m_Lines
[pProfile
->m_NoLines
]);
1518 pProfile
->m_Lines
[pProfile
->m_NoLines
++] = strdup(Line
);
1520 return (pProfile
->m_Lines
[pProfile
->m_NoLines
- 1]);
1523 static sal_Char
* insertLine(osl_TProfileImpl
* pProfile
, const sal_Char
* Line
, sal_uInt32 LineNo
)
1525 if (pProfile
->m_NoLines
>= pProfile
->m_MaxLines
)
1527 if (pProfile
->m_Lines
== NULL
)
1529 pProfile
->m_MaxLines
= LINES_INI
;
1530 pProfile
->m_Lines
= (sal_Char
**)malloc(pProfile
->m_MaxLines
* sizeof(sal_Char
*));
1531 memset(pProfile
->m_Lines
,0,pProfile
->m_MaxLines
* sizeof(sal_Char
*));
1535 pProfile
->m_MaxLines
+= LINES_ADD
;
1536 pProfile
->m_Lines
= (sal_Char
**)realloc(pProfile
->m_Lines
,
1537 pProfile
->m_MaxLines
* sizeof(sal_Char
*));
1539 memset(&pProfile
->m_Lines
[pProfile
->m_NoLines
],
1541 (pProfile
->m_MaxLines
- pProfile
->m_NoLines
- 1) * sizeof(sal_Char
*));
1544 if (pProfile
->m_Lines
== NULL
)
1546 pProfile
->m_NoLines
= 0;
1547 pProfile
->m_MaxLines
= 0;
1552 LineNo
= LineNo
> pProfile
->m_NoLines
? pProfile
->m_NoLines
: LineNo
;
1554 if (LineNo
< pProfile
->m_NoLines
)
1557 osl_TProfileSection
* pSec
;
1559 memmove(&pProfile
->m_Lines
[LineNo
+ 1], &pProfile
->m_Lines
[LineNo
],
1560 (pProfile
->m_NoLines
- LineNo
) * sizeof(sal_Char
*));
1563 /* adjust line references */
1564 for (i
= 0; i
< pProfile
->m_NoSections
; i
++)
1566 pSec
= &pProfile
->m_Sections
[i
];
1568 if (pSec
->m_Line
>= LineNo
)
1571 for (n
= 0; n
< pSec
->m_NoEntries
; n
++)
1572 if (pSec
->m_Entries
[n
].m_Line
>= LineNo
)
1573 pSec
->m_Entries
[n
].m_Line
++;
1577 pProfile
->m_NoLines
++;
1579 pProfile
->m_Lines
[LineNo
] = strdup(Line
);
1581 return (pProfile
->m_Lines
[LineNo
]);
1584 static void removeLine(osl_TProfileImpl
* pProfile
, sal_uInt32 LineNo
)
1586 if (LineNo
< pProfile
->m_NoLines
)
1588 free(pProfile
->m_Lines
[LineNo
]);
1589 pProfile
->m_Lines
[LineNo
]=0;
1590 if (pProfile
->m_NoLines
- LineNo
> 1)
1593 osl_TProfileSection
* pSec
;
1595 memmove(&pProfile
->m_Lines
[LineNo
], &pProfile
->m_Lines
[LineNo
+ 1],
1596 (pProfile
->m_NoLines
- LineNo
- 1) * sizeof(sal_Char
*));
1598 memset(&pProfile
->m_Lines
[pProfile
->m_NoLines
- 1],
1600 (pProfile
->m_MaxLines
- pProfile
->m_NoLines
) * sizeof(sal_Char
*));
1602 /* adjust line references */
1603 for (i
= 0; i
< pProfile
->m_NoSections
; i
++)
1605 pSec
= &pProfile
->m_Sections
[i
];
1607 if (pSec
->m_Line
> LineNo
)
1610 for (n
= 0; n
< pSec
->m_NoEntries
; n
++)
1611 if (pSec
->m_Entries
[n
].m_Line
> LineNo
)
1612 pSec
->m_Entries
[n
].m_Line
--;
1617 pProfile
->m_Lines
[LineNo
] = 0;
1620 pProfile
->m_NoLines
--;
1626 static void setEntry(osl_TProfileImpl
* pProfile
, osl_TProfileSection
* pSection
,
1627 sal_uInt32 NoEntry
, sal_uInt32 Line
,
1628 sal_Char
* Entry
, sal_uInt32 Len
)
1630 Entry
= stripBlanks(Entry
, &Len
);
1631 pSection
->m_Entries
[NoEntry
].m_Line
= Line
;
1632 pSection
->m_Entries
[NoEntry
].m_Offset
= Entry
- pProfile
->m_Lines
[Line
];
1633 pSection
->m_Entries
[NoEntry
].m_Len
= Len
;
1638 static sal_Bool
addEntry(osl_TProfileImpl
* pProfile
,
1639 osl_TProfileSection
*pSection
,
1640 int Line
, sal_Char
* Entry
,
1643 if (pSection
!= NULL
)
1645 if (pSection
->m_NoEntries
>= pSection
->m_MaxEntries
)
1647 if (pSection
->m_Entries
== NULL
)
1649 pSection
->m_MaxEntries
= ENTRIES_INI
;
1650 pSection
->m_Entries
= (osl_TProfileEntry
*)malloc(
1651 pSection
->m_MaxEntries
* sizeof(osl_TProfileEntry
));
1655 pSection
->m_MaxEntries
+= ENTRIES_ADD
;
1656 pSection
->m_Entries
= (osl_TProfileEntry
*)realloc(pSection
->m_Entries
,
1657 pSection
->m_MaxEntries
* sizeof(osl_TProfileEntry
));
1660 if (pSection
->m_Entries
== NULL
)
1662 pSection
->m_NoEntries
= 0;
1663 pSection
->m_MaxEntries
= 0;
1668 pSection
->m_NoEntries
++;
1670 Entry
= stripBlanks(Entry
, &Len
);
1671 setEntry(pProfile
, pSection
, pSection
->m_NoEntries
- 1, Line
,
1680 static void removeEntry(osl_TProfileSection
*pSection
, sal_uInt32 NoEntry
)
1682 if (NoEntry
< pSection
->m_NoEntries
)
1684 if (pSection
->m_NoEntries
- NoEntry
> 1)
1686 memmove(&pSection
->m_Entries
[NoEntry
],
1687 &pSection
->m_Entries
[NoEntry
+ 1],
1688 (pSection
->m_NoEntries
- NoEntry
- 1) * sizeof(osl_TProfileEntry
));
1689 pSection
->m_Entries
[pSection
->m_NoEntries
- 1].m_Line
=0;
1690 pSection
->m_Entries
[pSection
->m_NoEntries
- 1].m_Offset
=0;
1691 pSection
->m_Entries
[pSection
->m_NoEntries
- 1].m_Len
=0;
1694 pSection
->m_NoEntries
--;
1700 static sal_Bool
addSection(osl_TProfileImpl
* pProfile
, int Line
, const sal_Char
* Section
, sal_uInt32 Len
)
1702 if (pProfile
->m_NoSections
>= pProfile
->m_MaxSections
)
1704 if (pProfile
->m_Sections
== NULL
)
1706 pProfile
->m_MaxSections
= SECTIONS_INI
;
1707 pProfile
->m_Sections
= (osl_TProfileSection
*)malloc(pProfile
->m_MaxSections
* sizeof(osl_TProfileSection
));
1708 memset(pProfile
->m_Sections
,0,pProfile
->m_MaxSections
* sizeof(osl_TProfileSection
));
1713 unsigned int oldmax
=pProfile
->m_MaxSections
;
1715 pProfile
->m_MaxSections
+= SECTIONS_ADD
;
1716 pProfile
->m_Sections
= (osl_TProfileSection
*)realloc(pProfile
->m_Sections
,
1717 pProfile
->m_MaxSections
* sizeof(osl_TProfileSection
));
1718 for ( idx
= oldmax
; idx
< pProfile
->m_MaxSections
; ++idx
)
1720 pProfile
->m_Sections
[idx
].m_Entries
=0;
1724 if (pProfile
->m_Sections
== NULL
)
1726 pProfile
->m_NoSections
= 0;
1727 pProfile
->m_MaxSections
= 0;
1732 pProfile
->m_NoSections
++;
1734 if ( pProfile
->m_Sections
[(pProfile
->m_NoSections
) - 1].m_Entries
!= 0 )
1736 free(pProfile
->m_Sections
[(pProfile
->m_NoSections
) - 1].m_Entries
);
1738 pProfile
->m_Sections
[pProfile
->m_NoSections
- 1].m_Entries
= NULL
;
1739 pProfile
->m_Sections
[pProfile
->m_NoSections
- 1].m_NoEntries
= 0;
1740 pProfile
->m_Sections
[pProfile
->m_NoSections
- 1].m_MaxEntries
= 0;
1742 pProfile
->m_Sections
[pProfile
->m_NoSections
- 1].m_Line
= Line
;
1743 pProfile
->m_Sections
[pProfile
->m_NoSections
- 1].m_Offset
= Section
- pProfile
->m_Lines
[Line
];
1744 pProfile
->m_Sections
[pProfile
->m_NoSections
- 1].m_Len
= Len
;
1749 static void removeSection(osl_TProfileImpl
* pProfile
, osl_TProfileSection
*pSection
)
1753 if ((Section
= pSection
- pProfile
->m_Sections
) < pProfile
->m_NoSections
)
1755 free (pSection
->m_Entries
);
1756 pSection
->m_Entries
=0;
1757 if (pProfile
->m_NoSections
- Section
> 1)
1759 memmove(&pProfile
->m_Sections
[Section
], &pProfile
->m_Sections
[Section
+ 1],
1760 (pProfile
->m_NoSections
- Section
- 1) * sizeof(osl_TProfileSection
));
1762 memset(&pProfile
->m_Sections
[pProfile
->m_NoSections
- 1],
1764 (pProfile
->m_MaxSections
- pProfile
->m_NoSections
) * sizeof(osl_TProfileSection
));
1765 pProfile
->m_Sections
[pProfile
->m_NoSections
- 1].m_Entries
= 0;
1769 pSection
->m_Entries
= 0;
1772 pProfile
->m_NoSections
--;
1778 static osl_TProfileSection
* findEntry(osl_TProfileImpl
* pProfile
,
1779 const sal_Char
* Section
,
1780 const sal_Char
* Entry
,
1781 sal_uInt32
*pNoEntry
)
1783 static sal_uInt32 Sect
= 0;
1786 const sal_Char
* pStr
;
1787 osl_TProfileSection
* pSec
=0;
1789 Len
= strlen(Section
);
1793 for (i
= 0; i
< pProfile
->m_NoSections
; i
++)
1795 n
%= pProfile
->m_NoSections
;
1796 pSec
= &pProfile
->m_Sections
[n
];
1797 if ((Len
== pSec
->m_Len
) &&
1798 (strncasecmp(Section
, &pProfile
->m_Lines
[pSec
->m_Line
][pSec
->m_Offset
], pSec
->m_Len
)
1806 if (i
< pProfile
->m_NoSections
)
1808 Len
= strlen(Entry
);
1810 *pNoEntry
= pSec
->m_NoEntries
;
1812 for (i
= 0; i
< pSec
->m_NoEntries
; i
++)
1814 pStr
= &pProfile
->m_Lines
[pSec
->m_Entries
[i
].m_Line
]
1815 [pSec
->m_Entries
[i
].m_Offset
];
1816 if ((Len
== pSec
->m_Entries
[i
].m_Len
) &&
1817 (strncasecmp(Entry
, pStr
, pSec
->m_Entries
[i
].m_Len
)
1831 static sal_Bool
loadProfile(osl_TFile
* pFile
, osl_TProfileImpl
* pProfile
)
1838 sal_Char
* bWasAdded
= NULL
;
1851 pProfile
->m_NoLines
= 0;
1852 pProfile
->m_NoSections
= 0;
1854 OSL_VERIFY(OslProfile_rewindFile(pFile
, sal_False
));
1856 while ( ( pLine
=OslProfile_getLine(pFile
) ) != 0 )
1858 bWasAdded
= addLine( pProfile
, pLine
);
1859 rtl_freeMemory( pLine
);
1860 OSL_ASSERT(bWasAdded
);
1865 for (i
= 0; i
< pProfile
->m_NoLines
; i
++)
1867 pStr
= (sal_Char
*)stripBlanks(pProfile
->m_Lines
[i
], NULL
);
1869 if ((*pStr
== '\0') || (*pStr
== ';'))
1872 if ((*pStr
!= '[') || ((pChar
= strrchr(pStr
, ']')) == NULL
) ||
1873 ((pChar
- pStr
) <= 2))
1877 if (pProfile
->m_NoSections
< 1)
1880 if ((pChar
= strchr(pStr
, '=')) == NULL
)
1881 pChar
= pStr
+ strlen(pStr
);
1883 if (! addEntry(pProfile
, &pProfile
->m_Sections
[pProfile
->m_NoSections
- 1],
1884 i
, pStr
, pChar
- pStr
))
1895 if (! addSection(pProfile
, i
, pStr
+ 1, pChar
- pStr
- 1))
1907 static sal_Bool
storeProfile(osl_TProfileImpl
* pProfile
, sal_Bool bCleanup
)
1909 #ifdef TRACE_OSL_PROFILE
1910 OSL_TRACE("In storeProfile");
1913 if (pProfile
->m_Lines
!= NULL
)
1915 if (pProfile
->m_Flags
& FLG_MODIFIED
)
1919 osl_TFile
* pTmpFile
= osl_openTmpProfileImpl(pProfile
);
1921 if ( pTmpFile
== 0 )
1926 OSL_VERIFY(OslProfile_rewindFile(pTmpFile
, sal_True
));
1928 for ( i
= 0 ; i
< pProfile
->m_NoLines
; i
++ )
1930 OSL_VERIFY(OslProfile_putLine(pTmpFile
, pProfile
->m_Lines
[i
]));
1933 if ( ! writeProfileImpl(pTmpFile
) )
1935 if ( pTmpFile
->m_pWriteBuf
!= 0 )
1937 free(pTmpFile
->m_pWriteBuf
);
1940 pTmpFile
->m_pWriteBuf
=0;
1941 pTmpFile
->m_nWriteBufLen
=0;
1942 pTmpFile
->m_nWriteBufFree
=0;
1944 #ifdef TRACE_OSL_PROFILE
1945 OSL_TRACE("Out storeProfile [not flushed]");
1947 closeFileImpl(pTmpFile
,pProfile
->m_Flags
);
1952 pProfile
->m_Flags
&= ~FLG_MODIFIED
;
1954 closeFileImpl(pProfile
->m_pFile
,pProfile
->m_Flags
);
1955 closeFileImpl(pTmpFile
,pProfile
->m_Flags
);
1957 osl_ProfileSwapProfileNames(pProfile
);
1959 pProfile
->m_pFile
= openFileImpl(pProfile
->m_FileName
,pProfile
->m_Flags
);
1965 while (pProfile
->m_NoLines
> 0)
1966 removeLine(pProfile
, pProfile
->m_NoLines
- 1);
1968 free(pProfile
->m_Lines
);
1969 pProfile
->m_Lines
= NULL
;
1970 pProfile
->m_NoLines
= 0;
1971 pProfile
->m_MaxLines
= 0;
1973 while (pProfile
->m_NoSections
> 0)
1974 removeSection(pProfile
, &pProfile
->m_Sections
[pProfile
->m_NoSections
- 1]);
1976 free(pProfile
->m_Sections
);
1977 pProfile
->m_Sections
= NULL
;
1978 pProfile
->m_NoSections
= 0;
1979 pProfile
->m_MaxSections
= 0;
1983 #ifdef TRACE_OSL_PROFILE
1984 OSL_TRACE("Out storeProfile [ok]");
1989 static osl_TFile
* osl_openTmpProfileImpl(osl_TProfileImpl
* pProfile
)
1992 sal_Char
* pszExtension
= "tmp";
1993 sal_Char pszTmpName
[PATH_MAX
];
1994 oslProfileOption PFlags
=0;
1996 pszTmpName
[0] = '\0';
1998 /* generate tmp profilename */
1999 osl_ProfileGenerateExtension(pProfile
->m_FileName
, pszExtension
, pszTmpName
, PATH_MAX
);
2001 if ( pszTmpName
[0] == 0 )
2006 if ( ! ( pProfile
->m_Flags
& osl_Profile_READLOCK
) )
2008 PFlags
|= osl_Profile_WRITELOCK
;
2011 /* open this file */
2012 pFile
= openFileImpl(pszTmpName
,pProfile
->m_Flags
| PFlags
);
2015 /* return new pFile */
2019 static sal_Bool
osl_ProfileSwapProfileNames(osl_TProfileImpl
* pProfile
)
2021 sal_Bool bRet
= sal_False
;
2023 sal_Char pszBakFile
[PATH_MAX
];
2024 sal_Char pszTmpFile
[PATH_MAX
];
2025 sal_Char pszIniFile
[PATH_MAX
];
2027 pszBakFile
[0] = '\0';
2028 pszTmpFile
[0] = '\0';
2029 pszIniFile
[0] = '\0';
2031 osl_ProfileGenerateExtension(pProfile
->m_FileName
, "bak", pszBakFile
, PATH_MAX
);
2033 strcpy(pszIniFile
,pProfile
->m_FileName
);
2035 osl_ProfileGenerateExtension(pProfile
->m_FileName
, "tmp", pszTmpFile
, PATH_MAX
);
2038 unlink( pszBakFile
);
2040 /* rename ini bak */
2041 rename( pszIniFile
, pszBakFile
);
2043 /* rename tmp ini */
2044 rename( pszTmpFile
, pszIniFile
);
2049 static void osl_ProfileGenerateExtension(const sal_Char
* pszFileName
, const sal_Char
* pszExtension
, sal_Char
* pszTmpName
, int BufferMaxLen
)
2051 sal_Char
* cursor
= pszTmpName
;
2054 /* concatenate filename + "." + extension, limited to the size of the
2055 * output buffer; in case of overrun, data is truncated at the end...
2056 * and the result is always 0-terminated.
2058 len
= strlen(pszFileName
);
2059 if(len
< BufferMaxLen
)
2061 memcpy(cursor
, pszFileName
, len
);
2063 BufferMaxLen
-= len
;
2067 memcpy(cursor
, pszFileName
, BufferMaxLen
- 1);
2068 cursor
+= BufferMaxLen
- 1;
2071 if(BufferMaxLen
> 1)
2076 len
= strlen(pszExtension
);
2077 if(len
< BufferMaxLen
)
2079 memcpy(cursor
, pszExtension
, len
);
2084 memcpy(cursor
, pszExtension
, BufferMaxLen
- 1);
2085 cursor
+= BufferMaxLen
- 1;
2094 static osl_TProfileImpl
* acquireProfile(oslProfile Profile
, sal_Bool bWriteable
)
2096 osl_TProfileImpl
* pProfile
= (osl_TProfileImpl
*)Profile
;
2097 oslProfileOption PFlags
=0;
2101 PFlags
= osl_Profile_DEFAULT
| osl_Profile_WRITELOCK
;
2105 PFlags
= osl_Profile_DEFAULT
;
2109 if (pProfile
== NULL
)
2111 #ifdef DEBUG_OSL_PROFILE
2112 OSL_TRACE("AUTOOPEN MODE");
2115 if ( ( pProfile
= (osl_TProfileImpl
*) osl_openProfile(0, PFlags
) ) != NULL
)
2117 pProfile
->m_Flags
|= FLG_AUTOOPEN
;
2122 #ifdef DEBUG_OSL_PROFILE
2123 OSL_TRACE("try to acquire");
2126 if (! (pProfile
->m_Flags
& osl_Profile_SYSTEM
))
2128 if (! (pProfile
->m_Flags
& (osl_Profile_READLOCK
| osl_Profile_WRITELOCK
| osl_Profile_FLUSHWRITE
)))
2132 #ifdef DEBUG_OSL_PROFILE
2133 OSL_TRACE("Profile acquire DEFAULT MODE");
2135 if (! (pProfile
->m_pFile
= openFileImpl(pProfile
->m_FileName
, pProfile
->m_Flags
| PFlags
)))
2138 Stamp
= OslProfile_getFileStamp(pProfile
->m_pFile
);
2140 if (memcmp(&Stamp
, &(pProfile
->m_Stamp
), sizeof(osl_TStamp
)))
2142 sal_Bool bRet
=sal_False
;
2144 pProfile
->m_Stamp
= Stamp
;
2146 bRet
=loadProfile(pProfile
->m_pFile
, pProfile
);
2153 #ifdef DEBUG_OSL_PROFILE
2154 OSL_TRACE("Profile acquire READ/WRITELOCK MODE");
2156 /* A readlock file could not be written */
2157 if ((pProfile
->m_Flags
& osl_Profile_READLOCK
) && bWriteable
)
2168 static sal_Bool
releaseProfile(osl_TProfileImpl
* pProfile
)
2170 #ifdef TRACE_OSL_PROFILE
2171 OSL_TRACE("In releaseProfile");
2174 if ( pProfile
== 0 )
2176 #ifdef TRACE_OSL_PROFILE
2177 OSL_TRACE("Out releaseProfile [profile==0]");
2182 if (pProfile
->m_Flags
& FLG_AUTOOPEN
)
2184 #ifdef TRACE_OSL_PROFILE
2185 OSL_TRACE("Out releaseProfile [AUTOOPEN]");
2187 return (osl_closeProfile((oslProfile
)pProfile
));
2191 #ifdef DEBUG_OSL_PROFILE
2192 OSL_TRACE("DEFAULT MODE");
2194 if (! (pProfile
->m_Flags
& (osl_Profile_READLOCK
| osl_Profile_WRITELOCK
| osl_Profile_FLUSHWRITE
)))
2196 if (pProfile
->m_Flags
& FLG_MODIFIED
)
2198 sal_Bool bRet
=storeProfile(pProfile
, sal_False
);
2203 closeFileImpl(pProfile
->m_pFile
,pProfile
->m_Flags
);
2204 pProfile
->m_pFile
= NULL
;
2208 #ifdef TRACE_OSL_PROFILE
2209 OSL_TRACE("Out releaseProfile [ok]");
2214 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */