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.hxx"
22 #include "file_url.hxx"
23 #include "unixerrnostring.hxx"
25 #include <osl/diagnose.h>
26 #include <osl/profile.h>
27 #include <osl/process.h>
28 #include <osl/thread.h>
29 #include <rtl/alloc.h>
30 #include <sal/log.hxx>
34 #define SECTIONS_INI 5
35 #define SECTIONS_ADD 3
39 #define STR_INI_BOOLYES "yes"
40 #define STR_INI_BOOLON "on"
41 #define STR_INI_BOOLONE "1"
42 #define STR_INI_BOOLNO "no"
43 #define STR_INI_BOOLOFF "off"
44 #define STR_INI_BOOLZERO "0"
46 #define FLG_USER 0x00FF
47 #define FLG_AUTOOPEN 0x0100
48 #define FLG_MODIFIED 0x0200
50 #define DEFAULT_PMODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)
52 typedef time_t osl_TStamp
;
58 un_lock
, read_lock
, write_lock
67 sal_uInt32 m_nWriteBufLen
;
68 sal_uInt32 m_nWriteBufFree
;
71 struct osl_TProfileEntry
78 struct osl_TProfileSection
83 sal_uInt32 m_NoEntries
;
84 sal_uInt32 m_MaxEntries
;
85 osl_TProfileEntry
* m_Entries
;
88 /* Profile-data structure hidden behind oslProfile: */
89 struct osl_TProfileImpl
94 char m_FileName
[PATH_MAX
+ 1];
96 sal_uInt32 m_MaxLines
;
97 sal_uInt32 m_NoSections
;
98 sal_uInt32 m_MaxSections
;
100 osl_TProfileSection
* m_Sections
;
101 pthread_mutex_t m_AccessLock
;
107 static osl_TFile
* openFileImpl(const char* pszFilename
, oslProfileOption ProfileFlags
);
108 static osl_TStamp
closeFileImpl(osl_TFile
* pFile
, oslProfileOption Flags
);
109 static bool OslProfile_lockFile(const osl_TFile
* pFile
, osl_TLockMode eMode
);
110 static bool OslProfile_rewindFile(osl_TFile
* pFile
, bool bTruncate
);
111 static osl_TStamp
OslProfile_getFileStamp(osl_TFile
* pFile
);
113 static char* OslProfile_getLine(osl_TFile
* pFile
);
114 static bool OslProfile_putLine(osl_TFile
* pFile
, const char *pszLine
);
115 static char* stripBlanks(char* String
, sal_uInt32
* pLen
);
116 static char* addLine(osl_TProfileImpl
* pProfile
, const char* Line
);
117 static char* insertLine(osl_TProfileImpl
* pProfile
, const char* Line
, sal_uInt32 LineNo
);
118 static void removeLine(osl_TProfileImpl
* pProfile
, sal_uInt32 LineNo
);
119 static void setEntry(osl_TProfileImpl
* pProfile
, osl_TProfileSection
* pSection
,
120 sal_uInt32 NoEntry
, sal_uInt32 Line
,
121 char* Entry
, sal_uInt32 Len
);
122 static bool addEntry(osl_TProfileImpl
* pProfile
, osl_TProfileSection
*pSection
,
123 int Line
, char* Entry
, sal_uInt32 Len
);
124 static void removeEntry(osl_TProfileSection
*pSection
, sal_uInt32 NoEntry
);
125 static bool addSection(osl_TProfileImpl
* pProfile
, int Line
, const char* Section
, sal_uInt32 Len
);
126 static void removeSection(osl_TProfileImpl
* pProfile
, osl_TProfileSection
*pSection
);
127 static osl_TProfileSection
* findEntry(osl_TProfileImpl
* pProfile
, const char* Section
,
128 const char* Entry
, sal_uInt32
*pNoEntry
);
129 static bool loadProfile(osl_TFile
* pFile
, osl_TProfileImpl
* pProfile
);
130 static bool storeProfile(osl_TProfileImpl
* pProfile
, bool bCleanup
);
131 static osl_TProfileImpl
* acquireProfile(oslProfile Profile
, bool bWriteable
);
132 static bool releaseProfile(osl_TProfileImpl
* pProfile
);
134 static bool writeProfileImpl (osl_TFile
* pFile
);
135 static osl_TFile
* osl_openTmpProfileImpl(osl_TProfileImpl
*);
136 static bool osl_ProfileSwapProfileNames(osl_TProfileImpl
*);
137 static void osl_ProfileGenerateExtension(const char* pszFileName
, const char* pszExtension
, char* pszTmpName
, int BufferMaxLen
);
138 static oslProfile
osl_psz_openProfile(const char *pszProfileName
, oslProfileOption Flags
);
140 oslProfile SAL_CALL
osl_openProfile(rtl_uString
*ustrProfileName
, oslProfileOption Options
)
142 char profilePath
[PATH_MAX
] = "";
144 (ustrProfileName
== nullptr
145 || ustrProfileName
->buffer
[0] == 0
146 || (FileURLToPath(profilePath
, PATH_MAX
, ustrProfileName
)
148 ? osl_psz_openProfile(profilePath
, Options
)
152 static oslProfile
osl_psz_openProfile(const char *pszProfileName
, oslProfileOption Flags
)
155 osl_TProfileImpl
* pProfile
;
158 if ( ( pFile
= openFileImpl(pszProfileName
, Flags
) ) == nullptr )
163 pProfile
= static_cast<osl_TProfileImpl
*>(calloc(1, sizeof(osl_TProfileImpl
)));
165 if ( pProfile
== nullptr )
167 closeFileImpl(pFile
, Flags
);
171 pProfile
->m_Flags
= Flags
& FLG_USER
;
173 if ( Flags
& ( osl_Profile_READLOCK
| osl_Profile_WRITELOCK
| osl_Profile_FLUSHWRITE
) )
175 pProfile
->m_pFile
= pFile
;
178 pthread_mutex_init(&(pProfile
->m_AccessLock
),PTHREAD_MUTEXATTR_DEFAULT
);
179 pProfile
->m_bIsValid
= true;
181 pProfile
->m_Stamp
= OslProfile_getFileStamp(pFile
);
182 bRet
=loadProfile(pFile
, pProfile
);
183 bRet
&= realpath(pszProfileName
, pProfile
->m_FileName
) != nullptr;
184 SAL_WARN_IF(!bRet
, "sal.osl", "realpath(pszProfileName, pProfile->m_FileName) != NULL ==> false");
186 if (pProfile
->m_pFile
== nullptr)
187 closeFileImpl(pFile
,pProfile
->m_Flags
);
189 // coverity[leaked_storage] - pFile is not leaked
193 sal_Bool SAL_CALL
osl_closeProfile(oslProfile Profile
)
195 osl_TProfileImpl
* pProfile
= static_cast<osl_TProfileImpl
*>(Profile
);
196 osl_TProfileImpl
* pTmpProfile
;
198 if ( Profile
== nullptr )
203 pthread_mutex_lock(&(pProfile
->m_AccessLock
));
205 if ( !pProfile
->m_bIsValid
)
207 SAL_WARN("sal.osl", "!pProfile->m_bIsValid");
208 pthread_mutex_unlock(&(pProfile
->m_AccessLock
));
213 pProfile
->m_bIsValid
= false;
215 if ( ! ( pProfile
->m_Flags
& osl_Profile_READLOCK
) && ( pProfile
->m_Flags
& FLG_MODIFIED
) )
217 pTmpProfile
= acquireProfile(Profile
, true);
219 if ( pTmpProfile
!= nullptr )
221 bool bRet
= storeProfile(pTmpProfile
, true);
222 SAL_WARN_IF(!bRet
, "sal.osl", "storeProfile(pTmpProfile, true) ==> false");
227 pTmpProfile
= acquireProfile(Profile
, false);
230 if ( pTmpProfile
== nullptr )
232 pthread_mutex_unlock(&(pProfile
->m_AccessLock
));
234 SAL_INFO("sal.osl", "Out osl_closeProfile [pProfile==0]");
238 pProfile
= pTmpProfile
;
240 if (pProfile
->m_pFile
!= nullptr)
241 closeFileImpl(pProfile
->m_pFile
,pProfile
->m_Flags
);
243 pProfile
->m_pFile
= nullptr;
244 pProfile
->m_FileName
[0] = '\0';
246 /* release whole profile data types memory */
247 if ( pProfile
->m_NoLines
> 0)
250 if ( pProfile
->m_Lines
!= nullptr )
252 for ( idx
= 0 ; idx
< pProfile
->m_NoLines
; ++idx
)
254 if ( pProfile
->m_Lines
[idx
] != nullptr )
256 free(pProfile
->m_Lines
[idx
]);
257 pProfile
->m_Lines
[idx
]=nullptr;
260 free(pProfile
->m_Lines
);
261 pProfile
->m_Lines
=nullptr;
263 if ( pProfile
->m_Sections
!= nullptr )
265 /*osl_TProfileSection* pSections=pProfile->m_Sections;*/
266 for ( idx
= 0 ; idx
< pProfile
->m_NoSections
; ++idx
)
268 if ( pProfile
->m_Sections
[idx
].m_Entries
!= nullptr )
270 free(pProfile
->m_Sections
[idx
].m_Entries
);
271 pProfile
->m_Sections
[idx
].m_Entries
=nullptr;
274 free(pProfile
->m_Sections
);
275 pProfile
->m_Sections
=nullptr;
279 pthread_mutex_unlock(&(pProfile
->m_AccessLock
));
281 pthread_mutex_destroy(&(pProfile
->m_AccessLock
));
288 sal_Bool SAL_CALL
osl_flushProfile(oslProfile Profile
)
290 osl_TProfileImpl
* pProfile
= static_cast<osl_TProfileImpl
*>(Profile
);
294 if ( pProfile
== nullptr )
299 pthread_mutex_lock(&(pProfile
->m_AccessLock
));
301 if ( !pProfile
->m_bIsValid
)
303 SAL_WARN_IF(!pProfile
->m_bIsValid
, "sal.osl", "!pProfile->m_bIsValid");
304 pthread_mutex_unlock(&(pProfile
->m_AccessLock
));
308 pFile
= pProfile
->m_pFile
;
309 if ( pFile
== nullptr || pFile
->m_Handle
< 0 )
311 pthread_mutex_unlock(&(pProfile
->m_AccessLock
));
316 if ( pProfile
->m_Flags
& FLG_MODIFIED
)
318 bRet
= storeProfile(pProfile
, false);
319 SAL_WARN_IF(!bRet
, "sal.osl", "storeProfile(pProfile, false) ==> false");
322 pthread_mutex_unlock(&(pProfile
->m_AccessLock
));
326 static bool writeProfileImpl(osl_TFile
* pFile
)
328 if ( pFile
== nullptr || pFile
->m_Handle
< 0 || pFile
->m_pWriteBuf
== nullptr )
334 (strlen(pFile
->m_pWriteBuf
)
335 != pFile
->m_nWriteBufLen
- pFile
->m_nWriteBufFree
),
337 strlen(pFile
->m_pWriteBuf
) << " != "
338 << (pFile
->m_nWriteBufLen
- pFile
->m_nWriteBufFree
));
340 if ( !safeWrite(pFile
->m_Handle
, pFile
->m_pWriteBuf
, pFile
->m_nWriteBufLen
- pFile
->m_nWriteBufFree
) )
342 SAL_INFO("sal.osl", "write failed: " << UnixErrnoString(errno
));
346 free(pFile
->m_pWriteBuf
);
347 pFile
->m_pWriteBuf
=nullptr;
348 pFile
->m_nWriteBufLen
=0;
349 pFile
->m_nWriteBufFree
=0;
354 sal_Bool SAL_CALL
osl_readProfileString(oslProfile Profile
,
355 const char* pszSection
,
356 const char* pszEntry
,
359 const char* pszDefault
)
363 osl_TProfileImpl
* pProfile
=nullptr;
364 osl_TProfileImpl
* pTmpProfile
=nullptr;
367 pTmpProfile
= static_cast<osl_TProfileImpl
*>(Profile
);
369 if ( pTmpProfile
== nullptr )
374 pthread_mutex_lock(&(pTmpProfile
->m_AccessLock
));
376 if ( !pTmpProfile
->m_bIsValid
)
378 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
383 pProfile
= acquireProfile(Profile
, false);
385 if ( pProfile
== nullptr )
387 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
392 if (! (pProfile
->m_Flags
& osl_Profile_SYSTEM
))
394 osl_TProfileSection
* pSec
= findEntry(pProfile
, pszSection
, pszEntry
, &NoEntry
);
395 if ((pSec
!= nullptr) &&
396 (NoEntry
< pSec
->m_NoEntries
) &&
397 ((pStr
= strchr(pProfile
->m_Lines
[pSec
->m_Entries
[NoEntry
].m_Line
],
404 pStr
=const_cast<char*>(pszDefault
);
407 if ( pStr
!= nullptr )
409 pStr
= stripBlanks(pStr
, nullptr);
410 MaxLen
= (MaxLen
- 1 < strlen(pStr
)) ? (MaxLen
- 1) : strlen(pStr
);
411 pStr
= stripBlanks(pStr
, &MaxLen
);
412 strncpy(pszString
, pStr
, MaxLen
);
413 pszString
[MaxLen
] = '\0';
417 { /* not implemented */ }
419 bRet
=releaseProfile(pProfile
);
420 SAL_WARN_IF(!bRet
, "sal.osl", "releaseProfile(pProfile) ==> false");
422 if ( pStr
== nullptr )
424 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
429 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
434 sal_Bool SAL_CALL
osl_readProfileBool(oslProfile Profile
,
435 const char* pszSection
,
436 const char* pszEntry
,
442 if (osl_readProfileString(Profile
, pszSection
, pszEntry
, Line
, sizeof(Line
), ""))
444 if ((strcasecmp(Line
, STR_INI_BOOLYES
) == 0) ||
445 (strcasecmp(Line
, STR_INI_BOOLON
) == 0) ||
446 (strcasecmp(Line
, STR_INI_BOOLONE
) == 0))
449 if ((strcasecmp(Line
, STR_INI_BOOLNO
) == 0) ||
450 (strcasecmp(Line
, STR_INI_BOOLOFF
) == 0) ||
451 (strcasecmp(Line
, STR_INI_BOOLZERO
) == 0))
458 sal_uInt32 SAL_CALL
osl_readProfileIdent(oslProfile Profile
,
459 const char* pszSection
,
460 const char* pszEntry
,
462 const char* Strings
[],
469 if (osl_readProfileString(Profile
, pszSection
, pszEntry
, Line
, sizeof(Line
), ""))
472 while (Strings
[i
] != nullptr)
474 if (strcasecmp(Line
, Strings
[i
]) == 0)
476 Default
= i
+ FirstId
;
486 sal_Bool SAL_CALL
osl_writeProfileString(oslProfile Profile
,
487 const char* pszSection
,
488 const char* pszEntry
,
489 const char* pszString
)
494 char* Line
= nullptr;
495 osl_TProfileImpl
* pProfile
= nullptr;
496 osl_TProfileImpl
* pTmpProfile
= static_cast<osl_TProfileImpl
*>(Profile
);
498 if ( pTmpProfile
== nullptr )
503 pthread_mutex_lock(&(pTmpProfile
->m_AccessLock
));
505 if ( !pTmpProfile
->m_bIsValid
)
507 SAL_WARN_IF(!pTmpProfile
->m_bIsValid
, "sal.osl", "!pTmpProfile->m_bIsValid");
508 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
513 pProfile
=acquireProfile(Profile
, true);
515 if (pProfile
== nullptr)
517 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
522 Line
= static_cast<char*>(malloc(strlen(pszEntry
)+strlen(pszString
)+48));
524 if (! (pProfile
->m_Flags
& osl_Profile_SYSTEM
))
526 osl_TProfileSection
* pSec
;
527 if ((pSec
= findEntry(pProfile
, pszSection
, pszEntry
, &NoEntry
)) == nullptr)
530 addLine(pProfile
, Line
);
533 strcpy(&Line
[1], pszSection
);
534 Line
[1 + strlen(pszSection
)] = ']';
535 Line
[2 + strlen(pszSection
)] = '\0';
537 pStr
= addLine(pProfile
, Line
);
538 if ((pStr
== nullptr) ||
539 (! addSection(pProfile
, pProfile
->m_NoLines
- 1, &pStr
[1], strlen(pszSection
))))
541 bRet
=releaseProfile(pProfile
);
542 SAL_WARN_IF(!bRet
, "sal.osl", "releaseProfile(pProfile) ==> false");
544 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
550 pSec
= &pProfile
->m_Sections
[pProfile
->m_NoSections
- 1];
551 NoEntry
= pSec
->m_NoEntries
;
555 strcpy(&Line
[0], pszEntry
);
556 Line
[0 + strlen(pszEntry
)] = '=';
557 strcpy(&Line
[1 + strlen(pszEntry
)], pszString
);
559 if (NoEntry
>= pSec
->m_NoEntries
)
562 if (pSec
->m_NoEntries
> 0)
563 i
= pSec
->m_Entries
[pSec
->m_NoEntries
- 1].m_Line
+ 1;
565 i
= pSec
->m_Line
+ 1;
567 pStr
= insertLine(pProfile
, Line
, i
);
568 if ((pStr
== nullptr) ||
569 (! addEntry(pProfile
, pSec
, i
, pStr
, strlen(pszEntry
))))
571 bRet
=releaseProfile(pProfile
);
572 SAL_WARN_IF(!bRet
, "sal.osl", "releaseProfile(pProfile) ==> false");
574 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
580 pProfile
->m_Flags
|= FLG_MODIFIED
;
584 sal_uInt32 i
= pSec
->m_Entries
[NoEntry
].m_Line
;
585 free(pProfile
->m_Lines
[i
]);
586 pProfile
->m_Lines
[i
] = strdup(Line
);
587 setEntry(pProfile
, pSec
, NoEntry
, i
, pProfile
->m_Lines
[i
], strlen(pszEntry
));
589 pProfile
->m_Flags
|= FLG_MODIFIED
;
593 /* not implemented */
596 bRet
= releaseProfile(pProfile
);
597 SAL_WARN_IF(!bRet
, "sal.osl", "releaseProfile(pProfile) ==> false");
599 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
600 if ( Line
!= nullptr )
608 sal_Bool SAL_CALL
osl_writeProfileBool(oslProfile Profile
,
609 const char* pszSection
,
610 const char* pszEntry
,
616 bRet
=osl_writeProfileString(Profile
, pszSection
, pszEntry
, STR_INI_BOOLONE
);
618 bRet
=osl_writeProfileString(Profile
, pszSection
, pszEntry
, STR_INI_BOOLZERO
);
623 sal_Bool SAL_CALL
osl_writeProfileIdent(oslProfile Profile
,
624 const char* pszSection
,
625 const char* pszEntry
,
627 const char* Strings
[],
633 while (Strings
[n
] != nullptr)
636 if ((i
= Value
- FirstId
) >= n
)
639 bRet
= osl_writeProfileString(Profile
, pszSection
, pszEntry
, Strings
[i
]);
644 sal_Bool SAL_CALL
osl_removeProfileEntry(oslProfile Profile
,
645 const char *pszSection
,
646 const char *pszEntry
)
649 osl_TProfileImpl
* pProfile
= nullptr;
650 osl_TProfileImpl
* pTmpProfile
= nullptr;
653 pTmpProfile
= static_cast<osl_TProfileImpl
*>(Profile
);
655 if ( pTmpProfile
== nullptr )
660 pthread_mutex_lock(&(pTmpProfile
->m_AccessLock
));
662 if ( !pTmpProfile
->m_bIsValid
)
664 SAL_WARN_IF(!pTmpProfile
->m_bIsValid
, "sal.osl", "!pTmpProfile->m_bIsValid");
665 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
669 pProfile
= acquireProfile(Profile
, true);
671 if (pProfile
== nullptr)
673 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
678 if (! (pProfile
->m_Flags
& osl_Profile_SYSTEM
))
680 osl_TProfileSection
* pSec
= findEntry(pProfile
, pszSection
, pszEntry
, &NoEntry
);
681 if ((pSec
!= nullptr) &&
682 (NoEntry
< pSec
->m_NoEntries
))
684 removeLine(pProfile
, pSec
->m_Entries
[NoEntry
].m_Line
);
685 removeEntry(pSec
, NoEntry
);
686 if (pSec
->m_NoEntries
== 0)
688 removeLine(pProfile
, pSec
->m_Line
);
690 /* remove any empty separation line */
691 if ((pSec
->m_Line
> 0) && (pProfile
->m_Lines
[pSec
->m_Line
- 1][0] == '\0'))
692 removeLine(pProfile
, pSec
->m_Line
- 1);
694 removeSection(pProfile
, pSec
);
697 pProfile
->m_Flags
|= FLG_MODIFIED
;
701 { /* not implemented */ }
703 bRet
= releaseProfile(pProfile
);
704 SAL_WARN_IF(!bRet
, "sal.osl", "releaseProfile(pProfile) ==> false");
706 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
711 sal_uInt32 SAL_CALL
osl_getProfileSectionEntries(oslProfile Profile
,
712 const char *pszSection
,
718 osl_TProfileImpl
* pProfile
= nullptr;
719 osl_TProfileImpl
* pTmpProfile
= nullptr;
722 pTmpProfile
= static_cast<osl_TProfileImpl
*>(Profile
);
724 if ( pTmpProfile
== nullptr )
730 pthread_mutex_lock(&(pTmpProfile
->m_AccessLock
));
732 if ( !pTmpProfile
->m_bIsValid
)
734 SAL_WARN_IF(!pTmpProfile
->m_bIsValid
, "sal.osl", "!pTmpProfile->m_bIsValid");
736 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
741 pProfile
= acquireProfile(Profile
, false);
743 if (pProfile
== nullptr)
745 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
750 if (! (pProfile
->m_Flags
& osl_Profile_SYSTEM
))
752 osl_TProfileSection
* pSec
;
753 if ((pSec
= findEntry(pProfile
, pszSection
, "", &NoEntry
)) != nullptr)
757 for (i
= 0; i
< pSec
->m_NoEntries
; i
++)
759 if ((n
+ pSec
->m_Entries
[i
].m_Len
+ 1) < MaxLen
)
761 strncpy(&pszBuffer
[n
], &pProfile
->m_Lines
[pSec
->m_Entries
[i
].m_Line
]
762 [pSec
->m_Entries
[i
].m_Offset
], pSec
->m_Entries
[i
].m_Len
);
763 n
+= pSec
->m_Entries
[i
].m_Len
;
764 pszBuffer
[n
++] = '\0';
771 pszBuffer
[n
++] = '\0';
775 for (i
= 0; i
< pSec
->m_NoEntries
; i
++)
776 n
+= pSec
->m_Entries
[i
].m_Len
+ 1;
785 /* not implemented */
788 bRet
=releaseProfile(pProfile
);
789 SAL_WARN_IF(!bRet
, "sal.osl", "releaseProfile(pProfile) ==> false");
791 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
796 sal_uInt32 SAL_CALL
osl_getProfileSections(oslProfile Profile
,
801 osl_TProfileImpl
* pProfile
= nullptr;
802 osl_TProfileImpl
* pTmpProfile
= nullptr;
805 pTmpProfile
= static_cast<osl_TProfileImpl
*>(Profile
);
807 if ( pTmpProfile
== nullptr )
812 pthread_mutex_lock(&(pTmpProfile
->m_AccessLock
));
814 if ( !pTmpProfile
->m_bIsValid
)
816 SAL_WARN_IF(!pTmpProfile
->m_bIsValid
, "sal.osl", "!pTmpProfile->m_bIsValid");
817 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
822 pProfile
= acquireProfile(Profile
, false);
824 if (pProfile
== nullptr)
826 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
831 if (! (pProfile
->m_Flags
& osl_Profile_SYSTEM
))
835 for (i
= 0; i
< pProfile
->m_NoSections
; i
++)
837 osl_TProfileSection
* pSec
= &pProfile
->m_Sections
[i
];
839 if ((n
+ pSec
->m_Len
+ 1) < MaxLen
)
841 strncpy(&pszBuffer
[n
], &pProfile
->m_Lines
[pSec
->m_Line
][pSec
->m_Offset
],
844 pszBuffer
[n
++] = '\0';
850 pszBuffer
[n
++] = '\0';
854 for (i
= 0; i
< pProfile
->m_NoSections
; i
++)
855 n
+= pProfile
->m_Sections
[i
].m_Len
+ 1;
861 { /* not implemented */ }
863 bRet
=releaseProfile(pProfile
);
864 SAL_WARN_IF(!bRet
, "sal.osl", "releaseProfile(pProfile) ==> false");
866 pthread_mutex_unlock(&(pTmpProfile
->m_AccessLock
));
871 static osl_TStamp
OslProfile_getFileStamp(osl_TFile
* pFile
)
875 if ( (pFile
->m_Handle
< 0) || (fstat(pFile
->m_Handle
, &status
) < 0) )
880 return status
.st_mtime
;
883 static bool OslProfile_lockFile(const osl_TFile
* pFile
, osl_TLockMode eMode
)
886 static bool const bLockingDisabled
= getenv( "STAR_PROFILE_LOCKING_DISABLED" ) != nullptr;
888 if (pFile
->m_Handle
< 0)
893 if ( bLockingDisabled
)
899 lock
.l_whence
= SEEK_SET
;
905 lock
.l_type
= F_UNLCK
;
909 lock
.l_type
= F_RDLCK
;
913 lock
.l_type
= F_WRLCK
;
918 if ( fcntl(pFile
->m_Handle
, F_SETLKW
, &lock
) == -1 )
920 /* Mac OSX will return ENOTSUP for webdav drives so we should ignore it */
921 if ( fcntl(pFile
->m_Handle
, F_SETLKW
, &lock
) == -1 && errno
!= ENOTSUP
)
924 SAL_INFO("sal.osl", "fcntl failed: " << UnixErrnoString(errno
));
931 static osl_TFile
* openFileImpl(const char* pszFilename
, oslProfileOption ProfileFlags
)
934 osl_TFile
* pFile
= static_cast<osl_TFile
*>(calloc(1, sizeof(osl_TFile
)));
935 bool bWriteable
= false;
937 if ( ProfileFlags
& ( osl_Profile_WRITELOCK
| osl_Profile_FLUSHWRITE
) )
944 pFile
->m_Handle
= open(pszFilename
, O_RDONLY
);
946 if (pFile
->m_Handle
== -1)
949 SAL_INFO("sal.file", "open(" << pszFilename
<< ",O_RDONLY): " << UnixErrnoString(e
));
952 SAL_INFO("sal.file", "open(" << pszFilename
<< ",O_RDONLY) => " << pFile
->m_Handle
);
954 /* mfe: argghh!!! do not check if the file could be opened */
955 /* default mode expects it that way!!! */
959 if (((pFile
->m_Handle
= open(pszFilename
, O_RDWR
| O_CREAT
| O_EXCL
, DEFAULT_PMODE
)) < 0) &&
960 ((pFile
->m_Handle
= open(pszFilename
, O_RDWR
)) < 0))
963 SAL_INFO("sal.file", "open(" << pszFilename
<< ",...): " << UnixErrnoString(e
));
968 SAL_INFO("sal.file", "open(" << pszFilename
<< ",...) => " << pFile
->m_Handle
);
971 /* set close-on-exec flag */
972 if ((Flags
= fcntl(pFile
->m_Handle
, F_GETFD
, 0)) != -1)
975 int e
= fcntl(pFile
->m_Handle
, F_SETFD
, Flags
);
978 "fcntl to set FD_CLOEXEC failed for " << pszFilename
);
981 pFile
->m_pWriteBuf
=nullptr;
982 pFile
->m_nWriteBufFree
=0;
983 pFile
->m_nWriteBufLen
=0;
985 if ( ProfileFlags
& (osl_Profile_WRITELOCK
| osl_Profile_READLOCK
) )
987 OslProfile_lockFile(pFile
, bWriteable
? write_lock
: read_lock
);
993 static osl_TStamp
closeFileImpl(osl_TFile
* pFile
, oslProfileOption Flags
)
995 osl_TStamp stamp
= 0;
997 if ( pFile
== nullptr )
1002 if ( pFile
->m_Handle
>= 0 )
1004 stamp
= OslProfile_getFileStamp(pFile
);
1006 if ( Flags
& (osl_Profile_WRITELOCK
| osl_Profile_READLOCK
) )
1008 OslProfile_lockFile(pFile
, un_lock
);
1011 close(pFile
->m_Handle
);
1012 SAL_INFO("sal.file", "close(" << pFile
->m_Handle
<< ")");
1013 pFile
->m_Handle
= -1;
1016 if ( pFile
->m_pWriteBuf
)
1018 free(pFile
->m_pWriteBuf
);
1026 static bool OslProfile_rewindFile(osl_TFile
* pFile
, bool bTruncate
)
1030 if (pFile
->m_Handle
>= 0)
1032 pFile
->m_pReadPtr
= pFile
->m_ReadBuf
+ sizeof(pFile
->m_ReadBuf
);
1034 bRet
= (lseek(pFile
->m_Handle
, SEEK_SET
, 0) == 0);
1038 bRet
&= (ftruncate(pFile
->m_Handle
, 0) == 0);
1046 static char* OslProfile_getLine(osl_TFile
* pFile
)
1048 int Max
, Free
, nLineBytes
= 0;
1050 char* pLine
= nullptr;
1053 if ( pFile
== nullptr )
1058 if (pFile
->m_Handle
< 0)
1063 int Bytes
= sizeof(pFile
->m_ReadBuf
) - (pFile
->m_pReadPtr
- pFile
->m_ReadBuf
);
1068 memcpy(pFile
->m_ReadBuf
, pFile
->m_pReadPtr
, Bytes
);
1069 pFile
->m_pReadPtr
= pFile
->m_ReadBuf
;
1071 Free
= sizeof(pFile
->m_ReadBuf
) - Bytes
;
1073 if ((Max
= read(pFile
->m_Handle
, &pFile
->m_ReadBuf
[Bytes
], Free
)) < 0)
1075 SAL_INFO("sal.osl", "read failed: " << UnixErrnoString(errno
));
1085 if ((Max
== 0) && ! pLine
)
1088 pFile
->m_ReadBuf
[Bytes
+ Max
] = '\0';
1092 for (pChr
= pFile
->m_pReadPtr
;
1093 (*pChr
!= '\n') && (*pChr
!= '\r') && (*pChr
!= '\0') &&
1094 (pChr
< (pFile
->m_ReadBuf
+ sizeof(pFile
->m_ReadBuf
) - 1));
1097 Max
= pChr
- pFile
->m_pReadPtr
;
1098 pNewLine
= static_cast<char*>(malloc( nLineBytes
+ Max
+ 1 ));
1101 memcpy( pNewLine
, pLine
, nLineBytes
);
1104 memcpy(pNewLine
+nLineBytes
, pFile
->m_pReadPtr
, Max
);
1106 pNewLine
[ nLineBytes
] = 0;
1109 if (pChr
< (pFile
->m_ReadBuf
+ sizeof(pFile
->m_ReadBuf
) - 1))
1113 if ((pChr
[0] == '\r') && (pChr
[1] == '\n'))
1119 if ((pChr
< (pFile
->m_ReadBuf
+ sizeof(pFile
->m_ReadBuf
))) &&
1121 pChr
= pFile
->m_ReadBuf
+ sizeof(pFile
->m_ReadBuf
);
1123 /* setting Max to -1 indicates terminating read loop */
1127 pFile
->m_pReadPtr
= pChr
;
1134 static bool OslProfile_putLine(osl_TFile
* pFile
, const char *pszLine
)
1136 unsigned int Len
= strlen(pszLine
);
1138 if ( pFile
== nullptr || pFile
->m_Handle
< 0 )
1143 if ( pFile
->m_pWriteBuf
== nullptr )
1145 pFile
->m_pWriteBuf
= static_cast<char*>(malloc(Len
+3));
1146 pFile
->m_nWriteBufLen
= Len
+3;
1147 pFile
->m_nWriteBufFree
= Len
+3;
1151 if ( pFile
->m_nWriteBufFree
<= Len
+ 3 )
1155 pTmp
=static_cast<char*>(realloc(pFile
->m_pWriteBuf
,( ( pFile
->m_nWriteBufLen
+ Len
) * 2) ));
1156 if ( pTmp
== nullptr )
1160 pFile
->m_pWriteBuf
= pTmp
;
1161 pFile
->m_nWriteBufFree
= pFile
->m_nWriteBufFree
+ pFile
->m_nWriteBufLen
+ ( 2 * Len
);
1162 pFile
->m_nWriteBufLen
= ( pFile
->m_nWriteBufLen
+ Len
) * 2;
1163 memset( (pFile
->m_pWriteBuf
) + ( pFile
->m_nWriteBufLen
- pFile
->m_nWriteBufFree
), 0, pFile
->m_nWriteBufFree
);
1167 memcpy(pFile
->m_pWriteBuf
+ ( pFile
->m_nWriteBufLen
- pFile
->m_nWriteBufFree
),pszLine
,Len
+1);
1168 pFile
->m_pWriteBuf
[pFile
->m_nWriteBufLen
- pFile
->m_nWriteBufFree
+ Len
]='\n';
1169 pFile
->m_pWriteBuf
[pFile
->m_nWriteBufLen
- pFile
->m_nWriteBufFree
+ Len
+ 1]='\0';
1171 pFile
->m_nWriteBufFree
-=Len
+1;
1176 static char* stripBlanks(char* String
, sal_uInt32
* pLen
)
1178 if ( ( pLen
!= nullptr ) && ( *pLen
!= 0 ) )
1180 while ((String
[*pLen
- 1] == ' ') || (String
[*pLen
- 1] == '\t'))
1183 while ( (*String
== ' ') || (*String
== '\t') )
1190 while ( (*String
== ' ') || (*String
== '\t') )
1196 static char* addLine(osl_TProfileImpl
* pProfile
, const char* Line
)
1198 if (pProfile
->m_NoLines
>= pProfile
->m_MaxLines
)
1200 if (pProfile
->m_Lines
== nullptr)
1202 pProfile
->m_MaxLines
= LINES_INI
;
1203 pProfile
->m_Lines
= static_cast<char **>(calloc(pProfile
->m_MaxLines
, sizeof(char *)));
1208 unsigned int oldmax
=pProfile
->m_MaxLines
;
1210 pProfile
->m_MaxLines
+= LINES_ADD
;
1211 pProfile
->m_Lines
= static_cast<char **>(realloc(pProfile
->m_Lines
,
1212 pProfile
->m_MaxLines
* sizeof(char *)));
1213 for ( idx
= oldmax
; idx
< pProfile
->m_MaxLines
; ++idx
)
1215 pProfile
->m_Lines
[idx
]=nullptr;
1219 if (pProfile
->m_Lines
== nullptr)
1221 pProfile
->m_NoLines
= 0;
1222 pProfile
->m_MaxLines
= 0;
1226 if ( pProfile
->m_Lines
[pProfile
->m_NoLines
] != nullptr )
1228 free(pProfile
->m_Lines
[pProfile
->m_NoLines
]);
1230 pProfile
->m_Lines
[pProfile
->m_NoLines
++] = strdup(Line
);
1232 return pProfile
->m_Lines
[pProfile
->m_NoLines
- 1];
1235 static char* insertLine(osl_TProfileImpl
* pProfile
, const char* Line
, sal_uInt32 LineNo
)
1237 if (pProfile
->m_NoLines
>= pProfile
->m_MaxLines
)
1239 if (pProfile
->m_Lines
== nullptr)
1241 pProfile
->m_MaxLines
= LINES_INI
;
1242 pProfile
->m_Lines
= static_cast<char **>(calloc(pProfile
->m_MaxLines
, sizeof(char *)));
1246 pProfile
->m_MaxLines
+= LINES_ADD
;
1247 pProfile
->m_Lines
= static_cast<char **>(realloc(pProfile
->m_Lines
,
1248 pProfile
->m_MaxLines
* sizeof(char *)));
1250 memset(&pProfile
->m_Lines
[pProfile
->m_NoLines
],
1252 (pProfile
->m_MaxLines
- pProfile
->m_NoLines
- 1) * sizeof(char*));
1255 if (pProfile
->m_Lines
== nullptr)
1257 pProfile
->m_NoLines
= 0;
1258 pProfile
->m_MaxLines
= 0;
1263 LineNo
= std::min(LineNo
, pProfile
->m_NoLines
);
1265 if (LineNo
< pProfile
->m_NoLines
)
1269 memmove(&pProfile
->m_Lines
[LineNo
+ 1], &pProfile
->m_Lines
[LineNo
],
1270 (pProfile
->m_NoLines
- LineNo
) * sizeof(char *));
1272 /* adjust line references */
1273 for (i
= 0; i
< pProfile
->m_NoSections
; i
++)
1275 osl_TProfileSection
* pSec
= &pProfile
->m_Sections
[i
];
1277 if (pSec
->m_Line
>= LineNo
)
1280 for (n
= 0; n
< pSec
->m_NoEntries
; n
++)
1281 if (pSec
->m_Entries
[n
].m_Line
>= LineNo
)
1282 pSec
->m_Entries
[n
].m_Line
++;
1286 pProfile
->m_NoLines
++;
1288 pProfile
->m_Lines
[LineNo
] = strdup(Line
);
1290 return pProfile
->m_Lines
[LineNo
];
1293 static void removeLine(osl_TProfileImpl
* pProfile
, sal_uInt32 LineNo
)
1295 if (LineNo
>= pProfile
->m_NoLines
)
1298 free(pProfile
->m_Lines
[LineNo
]);
1299 pProfile
->m_Lines
[LineNo
]=nullptr;
1300 if (pProfile
->m_NoLines
- LineNo
> 1)
1304 memmove(&pProfile
->m_Lines
[LineNo
], &pProfile
->m_Lines
[LineNo
+ 1],
1305 (pProfile
->m_NoLines
- LineNo
- 1) * sizeof(char *));
1307 memset(&pProfile
->m_Lines
[pProfile
->m_NoLines
- 1],
1309 (pProfile
->m_MaxLines
- pProfile
->m_NoLines
) * sizeof(char*));
1311 /* adjust line references */
1312 for (i
= 0; i
< pProfile
->m_NoSections
; i
++)
1314 osl_TProfileSection
* pSec
= &pProfile
->m_Sections
[i
];
1316 if (pSec
->m_Line
> LineNo
)
1319 for (n
= 0; n
< pSec
->m_NoEntries
; n
++)
1320 if (pSec
->m_Entries
[n
].m_Line
> LineNo
)
1321 pSec
->m_Entries
[n
].m_Line
--;
1326 pProfile
->m_Lines
[LineNo
] = nullptr;
1329 pProfile
->m_NoLines
--;
1332 static void setEntry(osl_TProfileImpl
* pProfile
, osl_TProfileSection
* pSection
,
1333 sal_uInt32 NoEntry
, sal_uInt32 Line
,
1334 char* Entry
, sal_uInt32 Len
)
1336 Entry
= stripBlanks(Entry
, &Len
);
1337 pSection
->m_Entries
[NoEntry
].m_Line
= Line
;
1338 pSection
->m_Entries
[NoEntry
].m_Offset
= Entry
- pProfile
->m_Lines
[Line
];
1339 pSection
->m_Entries
[NoEntry
].m_Len
= Len
;
1342 static bool addEntry(osl_TProfileImpl
* pProfile
,
1343 osl_TProfileSection
*pSection
,
1344 int Line
, char* Entry
,
1347 if (pSection
!= nullptr)
1349 if (pSection
->m_NoEntries
>= pSection
->m_MaxEntries
)
1351 if (pSection
->m_Entries
== nullptr)
1353 pSection
->m_MaxEntries
= ENTRIES_INI
;
1354 pSection
->m_Entries
= static_cast<osl_TProfileEntry
*>(malloc(
1355 pSection
->m_MaxEntries
* sizeof(osl_TProfileEntry
)));
1359 pSection
->m_MaxEntries
+= ENTRIES_ADD
;
1360 pSection
->m_Entries
= static_cast<osl_TProfileEntry
*>(realloc(pSection
->m_Entries
,
1361 pSection
->m_MaxEntries
* sizeof(osl_TProfileEntry
)));
1364 if (pSection
->m_Entries
== nullptr)
1366 pSection
->m_NoEntries
= 0;
1367 pSection
->m_MaxEntries
= 0;
1372 pSection
->m_NoEntries
++;
1374 Entry
= stripBlanks(Entry
, &Len
);
1375 setEntry(pProfile
, pSection
, pSection
->m_NoEntries
- 1, Line
,
1384 static void removeEntry(osl_TProfileSection
*pSection
, sal_uInt32 NoEntry
)
1386 if (NoEntry
>= pSection
->m_NoEntries
)
1389 if (pSection
->m_NoEntries
- NoEntry
> 1)
1391 memmove(&pSection
->m_Entries
[NoEntry
],
1392 &pSection
->m_Entries
[NoEntry
+ 1],
1393 (pSection
->m_NoEntries
- NoEntry
- 1) * sizeof(osl_TProfileEntry
));
1394 pSection
->m_Entries
[pSection
->m_NoEntries
- 1].m_Line
=0;
1395 pSection
->m_Entries
[pSection
->m_NoEntries
- 1].m_Offset
=0;
1396 pSection
->m_Entries
[pSection
->m_NoEntries
- 1].m_Len
=0;
1399 pSection
->m_NoEntries
--;
1403 static bool addSection(osl_TProfileImpl
* pProfile
, int Line
, const char* Section
, sal_uInt32 Len
)
1405 if (pProfile
->m_NoSections
>= pProfile
->m_MaxSections
)
1407 if (pProfile
->m_Sections
== nullptr)
1409 pProfile
->m_MaxSections
= SECTIONS_INI
;
1410 pProfile
->m_Sections
= static_cast<osl_TProfileSection
*>(calloc(pProfile
->m_MaxSections
, sizeof(osl_TProfileSection
)));
1415 unsigned int oldmax
=pProfile
->m_MaxSections
;
1417 pProfile
->m_MaxSections
+= SECTIONS_ADD
;
1418 pProfile
->m_Sections
= static_cast<osl_TProfileSection
*>(realloc(pProfile
->m_Sections
,
1419 pProfile
->m_MaxSections
* sizeof(osl_TProfileSection
)));
1420 for ( idx
= oldmax
; idx
< pProfile
->m_MaxSections
; ++idx
)
1422 pProfile
->m_Sections
[idx
].m_Entries
=nullptr;
1426 if (pProfile
->m_Sections
== nullptr)
1428 pProfile
->m_NoSections
= 0;
1429 pProfile
->m_MaxSections
= 0;
1434 pProfile
->m_NoSections
++;
1436 if ( pProfile
->m_Sections
[(pProfile
->m_NoSections
) - 1].m_Entries
!= nullptr )
1438 free(pProfile
->m_Sections
[(pProfile
->m_NoSections
) - 1].m_Entries
);
1440 pProfile
->m_Sections
[pProfile
->m_NoSections
- 1].m_Entries
= nullptr;
1441 pProfile
->m_Sections
[pProfile
->m_NoSections
- 1].m_NoEntries
= 0;
1442 pProfile
->m_Sections
[pProfile
->m_NoSections
- 1].m_MaxEntries
= 0;
1444 pProfile
->m_Sections
[pProfile
->m_NoSections
- 1].m_Line
= Line
;
1445 pProfile
->m_Sections
[pProfile
->m_NoSections
- 1].m_Offset
= Section
- pProfile
->m_Lines
[Line
];
1446 pProfile
->m_Sections
[pProfile
->m_NoSections
- 1].m_Len
= Len
;
1451 static void removeSection(osl_TProfileImpl
* pProfile
, osl_TProfileSection
*pSection
)
1455 if ((Section
= pSection
- pProfile
->m_Sections
) >= pProfile
->m_NoSections
)
1458 free (pSection
->m_Entries
);
1459 pSection
->m_Entries
=nullptr;
1460 if (pProfile
->m_NoSections
- Section
> 1)
1462 memmove(&pProfile
->m_Sections
[Section
], &pProfile
->m_Sections
[Section
+ 1],
1463 (pProfile
->m_NoSections
- Section
- 1) * sizeof(osl_TProfileSection
));
1465 memset(&pProfile
->m_Sections
[pProfile
->m_NoSections
- 1],
1467 (pProfile
->m_MaxSections
- pProfile
->m_NoSections
) * sizeof(osl_TProfileSection
));
1468 pProfile
->m_Sections
[pProfile
->m_NoSections
- 1].m_Entries
= nullptr;
1472 pSection
->m_Entries
= nullptr;
1475 pProfile
->m_NoSections
--;
1478 static osl_TProfileSection
* findEntry(osl_TProfileImpl
* pProfile
,
1479 const char* Section
,
1481 sal_uInt32
*pNoEntry
)
1483 static sal_uInt32 Sect
= 0;
1486 osl_TProfileSection
* pSec
=nullptr;
1488 Len
= strlen(Section
);
1492 for (i
= 0; i
< pProfile
->m_NoSections
; i
++)
1494 n
%= pProfile
->m_NoSections
;
1495 pSec
= &pProfile
->m_Sections
[n
];
1496 if ((Len
== pSec
->m_Len
) &&
1497 (strncasecmp(Section
, &pProfile
->m_Lines
[pSec
->m_Line
][pSec
->m_Offset
], pSec
->m_Len
)
1505 if (i
< pProfile
->m_NoSections
)
1507 Len
= strlen(Entry
);
1509 *pNoEntry
= pSec
->m_NoEntries
;
1511 for (i
= 0; i
< pSec
->m_NoEntries
; i
++)
1513 const char* pStr
= &pProfile
->m_Lines
[pSec
->m_Entries
[i
].m_Line
]
1514 [pSec
->m_Entries
[i
].m_Offset
];
1515 if ((Len
== pSec
->m_Entries
[i
].m_Len
) &&
1516 (strncasecmp(Entry
, pStr
, pSec
->m_Entries
[i
].m_Len
)
1530 static bool loadProfile(osl_TFile
* pFile
, osl_TProfileImpl
* pProfile
)
1548 pProfile
->m_NoLines
= 0;
1549 pProfile
->m_NoSections
= 0;
1551 OSL_VERIFY(OslProfile_rewindFile(pFile
, false));
1553 while ( ( pLine
=OslProfile_getLine(pFile
) ) != nullptr )
1555 char* bWasAdded
= addLine( pProfile
, pLine
);
1557 SAL_WARN_IF(!bWasAdded
, "sal.osl", "addLine( pProfile, pLine ) ==> false");
1562 for (i
= 0; i
< pProfile
->m_NoLines
; i
++)
1564 pStr
= stripBlanks(pProfile
->m_Lines
[i
], nullptr);
1566 if ((*pStr
== '\0') || (*pStr
== ';'))
1569 if ((*pStr
!= '[') || ((pChar
= strrchr(pStr
, ']')) == nullptr) ||
1570 ((pChar
- pStr
) <= 2))
1574 if (pProfile
->m_NoSections
< 1)
1577 if ((pChar
= strchr(pStr
, '=')) == nullptr)
1578 pChar
= pStr
+ strlen(pStr
);
1580 if (! addEntry(pProfile
, &pProfile
->m_Sections
[pProfile
->m_NoSections
- 1],
1581 i
, pStr
, pChar
- pStr
))
1583 SAL_WARN("sal.osl", "Adding entry => false");
1592 if (! addSection(pProfile
, i
, pStr
+ 1, pChar
- pStr
- 1))
1594 SAL_WARN("sal.osl", "Adding section => false");
1604 static bool storeProfile(osl_TProfileImpl
* pProfile
, bool bCleanup
)
1606 if (pProfile
->m_Lines
!= nullptr)
1608 if (pProfile
->m_Flags
& FLG_MODIFIED
)
1612 osl_TFile
* pTmpFile
= osl_openTmpProfileImpl(pProfile
);
1614 if ( pTmpFile
== nullptr )
1619 OSL_VERIFY(OslProfile_rewindFile(pTmpFile
, true));
1621 for ( i
= 0 ; i
< pProfile
->m_NoLines
; i
++ )
1623 OSL_VERIFY(OslProfile_putLine(pTmpFile
, pProfile
->m_Lines
[i
]));
1626 if ( ! writeProfileImpl(pTmpFile
) )
1628 if ( pTmpFile
->m_pWriteBuf
!= nullptr )
1630 free(pTmpFile
->m_pWriteBuf
);
1633 pTmpFile
->m_pWriteBuf
=nullptr;
1634 pTmpFile
->m_nWriteBufLen
=0;
1635 pTmpFile
->m_nWriteBufFree
=0;
1637 closeFileImpl(pTmpFile
,pProfile
->m_Flags
);
1642 pProfile
->m_Flags
&= ~FLG_MODIFIED
;
1644 closeFileImpl(pProfile
->m_pFile
,pProfile
->m_Flags
);
1645 closeFileImpl(pTmpFile
,pProfile
->m_Flags
);
1647 osl_ProfileSwapProfileNames(pProfile
);
1649 pProfile
->m_pFile
= openFileImpl(pProfile
->m_FileName
,pProfile
->m_Flags
);
1655 while (pProfile
->m_NoLines
> 0)
1656 removeLine(pProfile
, pProfile
->m_NoLines
- 1);
1658 free(pProfile
->m_Lines
);
1659 pProfile
->m_Lines
= nullptr;
1660 pProfile
->m_NoLines
= 0;
1661 pProfile
->m_MaxLines
= 0;
1663 while (pProfile
->m_NoSections
> 0)
1664 removeSection(pProfile
, &pProfile
->m_Sections
[pProfile
->m_NoSections
- 1]);
1666 free(pProfile
->m_Sections
);
1667 pProfile
->m_Sections
= nullptr;
1668 pProfile
->m_NoSections
= 0;
1669 pProfile
->m_MaxSections
= 0;
1676 static osl_TFile
* osl_openTmpProfileImpl(osl_TProfileImpl
* pProfile
)
1678 osl_TFile
* pFile
=nullptr;
1679 char const * const pszExtension
= "tmp";
1680 char pszTmpName
[PATH_MAX
];
1681 oslProfileOption PFlags
=0;
1683 pszTmpName
[0] = '\0';
1685 /* generate tmp profilename */
1686 osl_ProfileGenerateExtension(pProfile
->m_FileName
, pszExtension
, pszTmpName
, PATH_MAX
);
1688 if ( pszTmpName
[0] == 0 )
1693 if ( ! ( pProfile
->m_Flags
& osl_Profile_READLOCK
) )
1695 PFlags
|= osl_Profile_WRITELOCK
;
1698 /* open this file */
1699 pFile
= openFileImpl(pszTmpName
,pProfile
->m_Flags
| PFlags
);
1701 /* return new pFile */
1705 static bool osl_ProfileSwapProfileNames(osl_TProfileImpl
* pProfile
)
1707 char pszBakFile
[PATH_MAX
];
1708 char pszTmpFile
[PATH_MAX
];
1710 pszBakFile
[0] = '\0';
1711 pszTmpFile
[0] = '\0';
1713 osl_ProfileGenerateExtension(pProfile
->m_FileName
, "bak", pszBakFile
, PATH_MAX
);
1714 osl_ProfileGenerateExtension(pProfile
->m_FileName
, "tmp", pszTmpFile
, PATH_MAX
);
1717 unlink( pszBakFile
);
1719 // Rename ini -> bak, then tmp -> ini:
1720 bool result
= rename( pProfile
->m_FileName
, pszBakFile
) == 0;
1724 SAL_INFO("sal.file", "rename(" << pProfile
->m_FileName
<< "," << pszBakFile
<< "): " << UnixErrnoString(e
));
1728 SAL_INFO("sal.file", "rename(" << pProfile
->m_FileName
<< "," << pszBakFile
<< "): OK");
1729 result
= rename( pszTmpFile
, pProfile
->m_FileName
) == 0;
1733 SAL_INFO("sal.file", "rename(" << pszTmpFile
<< "," << pProfile
->m_FileName
<< "): " << UnixErrnoString(e
));
1737 SAL_INFO("sal.file", "rename(" << pszTmpFile
<< "," << pProfile
->m_FileName
<< "): OK");
1743 static void osl_ProfileGenerateExtension(const char* pszFileName
, const char* pszExtension
, char* pszTmpName
, int BufferMaxLen
)
1745 char* cursor
= pszTmpName
;
1748 /* concatenate filename + "." + extension, limited to the size of the
1749 * output buffer; in case of overrun, data is truncated at the end...
1750 * and the result is always 0-terminated.
1752 len
= strlen(pszFileName
);
1753 if(len
< BufferMaxLen
)
1755 memcpy(cursor
, pszFileName
, len
);
1757 BufferMaxLen
-= len
;
1761 memcpy(cursor
, pszFileName
, BufferMaxLen
- 1);
1762 cursor
+= BufferMaxLen
- 1;
1765 if(BufferMaxLen
> 1)
1770 len
= strlen(pszExtension
);
1771 if(len
< BufferMaxLen
)
1773 memcpy(cursor
, pszExtension
, len
);
1778 memcpy(cursor
, pszExtension
, BufferMaxLen
- 1);
1779 cursor
+= BufferMaxLen
- 1;
1784 static osl_TProfileImpl
* acquireProfile(oslProfile Profile
, bool bWriteable
)
1786 osl_TProfileImpl
* pProfile
= static_cast<osl_TProfileImpl
*>(Profile
);
1787 oslProfileOption PFlags
=0;
1791 PFlags
= osl_Profile_DEFAULT
| osl_Profile_WRITELOCK
;
1795 PFlags
= osl_Profile_DEFAULT
;
1798 if (pProfile
== nullptr)
1800 if ( ( pProfile
= static_cast<osl_TProfileImpl
*>(osl_openProfile(nullptr, PFlags
)) ) != nullptr )
1802 pProfile
->m_Flags
|= FLG_AUTOOPEN
;
1807 if (! (pProfile
->m_Flags
& osl_Profile_SYSTEM
))
1809 if (! (pProfile
->m_Flags
& (osl_Profile_READLOCK
| osl_Profile_WRITELOCK
| osl_Profile_FLUSHWRITE
)))
1813 if (! (pProfile
->m_pFile
= openFileImpl(pProfile
->m_FileName
, pProfile
->m_Flags
| PFlags
)))
1816 Stamp
= OslProfile_getFileStamp(pProfile
->m_pFile
);
1818 if (memcmp(&Stamp
, &(pProfile
->m_Stamp
), sizeof(osl_TStamp
)))
1820 pProfile
->m_Stamp
= Stamp
;
1821 bool bRet
= loadProfile(pProfile
->m_pFile
, pProfile
);
1822 SAL_WARN_IF(!bRet
, "sal.osl", "loadProfile(pProfile->m_pFile, pProfile) ==> false");
1827 /* A readlock file could not be written */
1828 if ((pProfile
->m_Flags
& osl_Profile_READLOCK
) && bWriteable
)
1839 static bool releaseProfile(osl_TProfileImpl
* pProfile
)
1841 if ( pProfile
== nullptr )
1846 if (pProfile
->m_Flags
& FLG_AUTOOPEN
)
1848 return osl_closeProfile(static_cast<oslProfile
>(pProfile
));
1851 if (! (pProfile
->m_Flags
& (osl_Profile_READLOCK
| osl_Profile_WRITELOCK
| osl_Profile_FLUSHWRITE
)))
1853 if (pProfile
->m_Flags
& FLG_MODIFIED
)
1855 bool bRet
= storeProfile(pProfile
, false);
1856 SAL_WARN_IF(!bRet
, "sal.osl", "storeProfile(pProfile, false) ==> false");
1859 closeFileImpl(pProfile
->m_pFile
,pProfile
->m_Flags
);
1860 pProfile
->m_pFile
= nullptr;
1866 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */