Bump for 3.6-28
[LibreOffice.git] / sal / osl / unx / profile.c
blobcfdb5ea9bcce1d79e17d569b04be80721ada3d1d
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
30 #include "system.h"
31 #include "readwrite_helper.h"
33 #include <osl/diagnose.h>
34 #include <osl/profile.h>
35 #include <osl/process.h>
36 #include <osl/thread.h>
37 #include <rtl/alloc.h>
38 #include <osl/util.h>
40 #define LINES_INI 32
41 #define LINES_ADD 10
42 #define SECTIONS_INI 5
43 #define SECTIONS_ADD 3
44 #define ENTRIES_INI 5
45 #define ENTRIES_ADD 3
48 #define STR_INI_EXTENSION "rc"
49 #define STR_INI_METAHOME "?~"
50 #define STR_INI_METASYS "?$"
51 #define STR_INI_METACFG "?^"
52 #define STR_INI_METAINS "?#"
54 #define STR_INI_BOOLYES "yes"
55 #define STR_INI_BOOLON "on"
56 #define STR_INI_BOOLONE "1"
57 #define STR_INI_BOOLNO "no"
58 #define STR_INI_BOOLOFF "off"
59 #define STR_INI_BOOLZERO "0"
61 #define FLG_USER 0x00FF
62 #define FLG_AUTOOPEN 0x0100
63 #define FLG_MODIFIED 0x0200
65 #define SVERSION_LOCATION STR_INI_METACFG
66 #define SVERSION_FALLBACK STR_INI_METASYS
67 #define SVERSION_NAME "sversion"
68 #define SVERSION_SECTION "Versions"
69 #define SVERSION_SOFFICE "StarOffice"
70 #define SVERSION_PROFILE "sofficerc"
71 #define SVERSION_OPTION "userid:"
72 #define SVERSION_DIRS { "bin", "program" }
73 #define SVERSION_USER "user"
75 #define DEFAULT_PMODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)
77 #define _BUILD_STR_(n) # n
78 #define BUILD_STR(n) _BUILD_STR_(n)
81 /*#define DEBUG_OSL_PROFILE*/
82 /*#define TRACE_OSL_PROFILE*/
84 /*****************************************************************************/
85 /* Data Type Definition */
86 /*****************************************************************************/
88 typedef time_t osl_TStamp;
90 typedef enum _osl_TLockMode
92 un_lock, read_lock, write_lock
93 } osl_TLockMode;
95 typedef struct _osl_TFile
97 int m_Handle;
98 sal_Char* m_pReadPtr;
99 sal_Char m_ReadBuf[512];
100 sal_Char* m_pWriteBuf;
101 sal_uInt32 m_nWriteBufLen;
102 sal_uInt32 m_nWriteBufFree;
103 } osl_TFile;
105 typedef struct _osl_TProfileEntry
107 sal_uInt32 m_Line;
108 sal_uInt32 m_Offset;
109 sal_uInt32 m_Len;
110 } osl_TProfileEntry;
112 typedef struct _osl_TProfileSection
114 sal_uInt32 m_Line;
115 sal_uInt32 m_Offset;
116 sal_uInt32 m_Len;
117 sal_uInt32 m_NoEntries;
118 sal_uInt32 m_MaxEntries;
119 osl_TProfileEntry* m_Entries;
120 } osl_TProfileSection;
124 Profile-data structure hidden behind oslProfile:
126 typedef struct _osl_TProfileImpl
128 sal_uInt32 m_Flags;
129 osl_TFile* m_pFile;
130 osl_TStamp m_Stamp;
131 sal_Char m_FileName[PATH_MAX + 1];
132 sal_uInt32 m_NoLines;
133 sal_uInt32 m_MaxLines;
134 sal_uInt32 m_NoSections;
135 sal_uInt32 m_MaxSections;
136 sal_Char** m_Lines;
137 osl_TProfileSection* m_Sections;
138 pthread_mutex_t m_AccessLock;
139 sal_Bool m_bIsValid;
140 } osl_TProfileImpl;
143 /*****************************************************************************/
144 /* Static Module Function Declarations */
145 /*****************************************************************************/
147 static osl_TFile* openFileImpl(const sal_Char* pszFilename, oslProfileOption ProfileFlags);
148 static osl_TStamp closeFileImpl(osl_TFile* pFile, oslProfileOption Flags);
149 static sal_Bool OslProfile_lockFile(const osl_TFile* pFile, osl_TLockMode eMode);
150 static sal_Bool OslProfile_rewindFile(osl_TFile* pFile, sal_Bool bTruncate);
151 static osl_TStamp OslProfile_getFileStamp(osl_TFile* pFile);
153 static sal_Char* OslProfile_getLine(osl_TFile* pFile);
154 static sal_Bool OslProfile_putLine(osl_TFile* pFile, const sal_Char *pszLine);
155 static sal_Char* stripBlanks(sal_Char* String, sal_uInt32* pLen);
156 static sal_Char* addLine(osl_TProfileImpl* pProfile, const sal_Char* Line);
157 static sal_Char* insertLine(osl_TProfileImpl* pProfile, const sal_Char* Line, sal_uInt32 LineNo);
158 static void removeLine(osl_TProfileImpl* pProfile, sal_uInt32 LineNo);
159 static void setEntry(osl_TProfileImpl* pProfile, osl_TProfileSection* pSection,
160 sal_uInt32 NoEntry, sal_uInt32 Line,
161 sal_Char* Entry, sal_uInt32 Len);
162 static sal_Bool addEntry(osl_TProfileImpl* pProfile, osl_TProfileSection *pSection,
163 int Line, sal_Char* Entry, sal_uInt32 Len);
164 static void removeEntry(osl_TProfileSection *pSection, sal_uInt32 NoEntry);
165 static sal_Bool addSection(osl_TProfileImpl* pProfile, int Line, const sal_Char* Section, sal_uInt32 Len);
166 static void removeSection(osl_TProfileImpl* pProfile, osl_TProfileSection *pSection);
167 static osl_TProfileSection* findEntry(osl_TProfileImpl* pProfile, const sal_Char* Section,
168 const sal_Char* Entry, sal_uInt32 *pNoEntry);
169 static sal_Bool loadProfile(osl_TFile* pFile, osl_TProfileImpl* pProfile);
170 static sal_Bool storeProfile(osl_TProfileImpl* pProfile, sal_Bool bCleanup);
171 static osl_TProfileImpl* acquireProfile(oslProfile Profile, sal_Bool bWriteable);
172 static sal_Bool releaseProfile(osl_TProfileImpl* pProfile);
174 static sal_Bool writeProfileImpl (osl_TFile* pFile);
175 static osl_TFile* osl_openTmpProfileImpl(osl_TProfileImpl*);
176 static sal_Bool osl_ProfileSwapProfileNames(osl_TProfileImpl*);
177 static void osl_ProfileGenerateExtension(sal_Char* pszFileName, sal_Char* pszExtension, sal_Char* pszTmpName);
178 static oslProfile SAL_CALL osl_psz_openProfile(const sal_Char *pszProfileName, oslProfileOption Flags);
180 /* implemented in file.c */
181 extern oslFileError FileURLToPath( char *, size_t, rtl_uString* );
183 /*****************************************************************************/
184 /* Exported Module Functions */
185 /*****************************************************************************/
186 oslProfile SAL_CALL osl_openProfile(rtl_uString *ustrProfileName, oslProfileOption Options)
188 char profilePath[PATH_MAX] = "";
190 if ( ustrProfileName != 0 && ustrProfileName->buffer[0] != 0 )
191 FileURLToPath( profilePath, PATH_MAX, ustrProfileName );
193 return osl_psz_openProfile( profilePath,Options );
197 static oslProfile SAL_CALL osl_psz_openProfile(const sal_Char *pszProfileName, oslProfileOption Flags)
199 osl_TFile* pFile;
200 osl_TProfileImpl* pProfile;
201 sal_Bool bRet = sal_False;
203 #ifdef TRACE_OSL_PROFILE
204 OSL_TRACE("In osl_openProfile");
205 #endif
207 #ifdef DEBUG_OSL_PROFILE
208 Flags=osl_Profile_FLUSHWRITE;
210 OSL_TRACE("opening '%s'",pszProfileName);
211 if ( Flags == osl_Profile_DEFAULT )
213 OSL_TRACE("with osl_Profile_DEFAULT");
215 if ( Flags & osl_Profile_SYSTEM )
217 OSL_TRACE("with osl_Profile_SYSTEM");
219 if ( Flags & osl_Profile_READLOCK )
221 OSL_TRACE("with osl_Profile_READLOCK");
223 if ( Flags & osl_Profile_WRITELOCK )
225 OSL_TRACE("with osl_Profile_WRITELOCK");
227 if ( Flags & osl_Profile_FLUSHWRITE )
229 OSL_TRACE("with osl_Profile_FLUSHWRITE");
231 #endif
234 if ( ( pFile = openFileImpl(pszProfileName, Flags ) ) == NULL )
236 #ifdef TRACE_OSL_PROFILE
237 OSL_TRACE("Out osl_openProfile [not opened]");
238 #endif
239 return (NULL);
243 pProfile = (osl_TProfileImpl*)calloc(1, sizeof(osl_TProfileImpl));
245 if ( pProfile == 0 )
247 closeFileImpl(pFile, Flags);
248 return 0;
251 pProfile->m_Flags = Flags & FLG_USER;
253 if ( Flags & ( osl_Profile_READLOCK | osl_Profile_WRITELOCK | osl_Profile_FLUSHWRITE ) )
255 pProfile->m_pFile = pFile;
258 pthread_mutex_init(&(pProfile->m_AccessLock),PTHREAD_MUTEXATTR_DEFAULT);
259 pProfile->m_bIsValid=sal_True;
261 pProfile->m_Stamp = OslProfile_getFileStamp(pFile);
262 bRet=loadProfile(pFile, pProfile);
263 bRet &= realpath(pszProfileName, pProfile->m_FileName) != NULL;
264 OSL_ASSERT(bRet);
266 if (pProfile->m_pFile == NULL)
267 closeFileImpl(pFile,pProfile->m_Flags);
269 #ifdef TRACE_OSL_PROFILE
270 OSL_TRACE("Out osl_openProfile [ok]");
271 #endif
272 return (pProfile);
275 sal_Bool SAL_CALL osl_closeProfile(oslProfile Profile)
277 osl_TProfileImpl* pProfile = (osl_TProfileImpl*)Profile;
278 osl_TProfileImpl* pTmpProfile;
280 #ifdef TRACE_OSL_PROFILE
281 OSL_TRACE("In osl_closeProfile");
282 #endif
284 if ( Profile == 0 )
286 #ifdef TRACE_OSL_PROFILE
287 OSL_TRACE("Out osl_closeProfile [profile==0]");
288 #endif
289 return sal_False;
292 pthread_mutex_lock(&(pProfile->m_AccessLock));
294 if ( pProfile->m_bIsValid == sal_False )
296 OSL_ASSERT(pProfile->m_bIsValid);
297 pthread_mutex_unlock(&(pProfile->m_AccessLock));
298 #ifdef TRACE_OSL_PROFILE
299 OSL_TRACE("Out osl_closeProfile [not valid]");
300 #endif
301 return sal_False;
304 pProfile->m_bIsValid=sal_False;
306 if ( ! ( pProfile->m_Flags & osl_Profile_READLOCK ) && ( pProfile->m_Flags & FLG_MODIFIED ) )
308 pTmpProfile = acquireProfile(Profile,sal_True);
310 if ( pTmpProfile != 0 )
312 sal_Bool bRet = storeProfile(pTmpProfile, sal_True);
313 OSL_ASSERT(bRet);
314 (void)bRet;
317 else
319 pTmpProfile = acquireProfile(Profile,sal_False);
323 if ( pTmpProfile == 0 )
325 pthread_mutex_unlock(&(pProfile->m_AccessLock));
326 #ifdef TRACE_OSL_PROFILE
327 OSL_TRACE("Out osl_closeProfile [pProfile==0]");
328 #endif
329 return sal_False;
332 pProfile = pTmpProfile;
334 if (pProfile->m_pFile != NULL)
335 closeFileImpl(pProfile->m_pFile,pProfile->m_Flags);
337 pProfile->m_pFile = NULL;
338 pProfile->m_FileName[0] = '\0';
340 /* release whole profile data types memory */
341 if ( pProfile->m_NoLines > 0)
343 unsigned int idx=0;
344 if ( pProfile->m_Lines != 0 )
346 for ( idx = 0 ; idx < pProfile->m_NoLines ; ++idx)
348 if ( pProfile->m_Lines[idx] != 0 )
350 free(pProfile->m_Lines[idx]);
351 pProfile->m_Lines[idx]=0;
354 free(pProfile->m_Lines);
355 pProfile->m_Lines=0;
357 if ( pProfile->m_Sections != 0 )
359 /*osl_TProfileSection* pSections=pProfile->m_Sections;*/
360 for ( idx = 0 ; idx < pProfile->m_NoSections ; ++idx )
362 if ( pProfile->m_Sections[idx].m_Entries != 0 )
364 free(pProfile->m_Sections[idx].m_Entries);
365 pProfile->m_Sections[idx].m_Entries=0;
368 free(pProfile->m_Sections);
369 pProfile->m_Sections=0;
373 pthread_mutex_unlock(&(pProfile->m_AccessLock));
375 pthread_mutex_destroy(&(pProfile->m_AccessLock));
377 free(pProfile);
379 #ifdef TRACE_OSL_PROFILE
380 OSL_TRACE("Out osl_closeProfile [ok]");
381 #endif
382 return (sal_True);
386 sal_Bool SAL_CALL osl_flushProfile(oslProfile Profile)
388 osl_TProfileImpl* pProfile = (osl_TProfileImpl*) Profile;
389 osl_TFile* pFile;
390 sal_Bool bRet = sal_False;
392 #ifdef TRACE_OSL_PROFILE
393 OSL_TRACE("In osl_flushProfile()");
394 #endif
396 if ( pProfile == 0 )
398 #ifdef TRACE_OSL_PROFILE
399 OSL_TRACE("Out osl_flushProfile() [pProfile == 0]");
400 #endif
401 return sal_False;
404 pthread_mutex_lock(&(pProfile->m_AccessLock));
406 if ( pProfile->m_bIsValid == sal_False )
408 OSL_ASSERT(pProfile->m_bIsValid);
409 pthread_mutex_unlock(&(pProfile->m_AccessLock));
410 #ifdef TRACE_OSL_PROFILE
411 OSL_TRACE("Out osl_flushProfile [not valid]");
412 #endif
413 return sal_False;
416 pFile = pProfile->m_pFile;
417 if ( !( pFile != 0 && pFile->m_Handle >= 0 ) )
419 pthread_mutex_unlock(&(pProfile->m_AccessLock));
420 #ifdef TRACE_OSL_PROFILE
421 OSL_TRACE("Out osl_flushProfile() [invalid file]");
422 #endif
423 return sal_False;
426 if ( pProfile->m_Flags & FLG_MODIFIED )
428 #ifdef DEBUG_OSL_PROFILE
429 OSL_TRACE("swapping to storeprofile");
430 #endif
431 bRet = storeProfile(pProfile,sal_False);
432 OSL_ASSERT(bRet);
435 #ifdef TRACE_OSL_PROFILE
436 OSL_TRACE("Out osl_flushProfile() [ok]");
437 #endif
438 pthread_mutex_unlock(&(pProfile->m_AccessLock));
439 return bRet;
442 static sal_Bool writeProfileImpl(osl_TFile* pFile)
444 #if OSL_DEBUG_LEVEL > 1
445 unsigned int nLen=0;
446 #endif
448 #ifdef TRACE_OSL_PROFILE
449 OSL_TRACE("In osl_writeProfileImpl()");
450 #endif
452 if ( !( pFile != 0 && pFile->m_Handle >= 0 ) || ( pFile->m_pWriteBuf == 0 ) )
454 #ifdef TRACE_OSL_PROFILE
455 OSL_TRACE("Out osl_writeProfileImpl() [invalid args]");
456 #endif
457 return sal_False;
460 #if OSL_DEBUG_LEVEL > 1
461 nLen=strlen(pFile->m_pWriteBuf);
462 OSL_ASSERT(nLen == (pFile->m_nWriteBufLen - pFile->m_nWriteBufFree));
463 #endif
465 if ( !safeWrite(pFile->m_Handle, pFile->m_pWriteBuf, pFile->m_nWriteBufLen - pFile->m_nWriteBufFree) )
467 OSL_TRACE("write failed '%s'",strerror(errno));
468 return (sal_False);
471 free(pFile->m_pWriteBuf);
472 pFile->m_pWriteBuf=0;
473 pFile->m_nWriteBufLen=0;
474 pFile->m_nWriteBufFree=0;
475 #ifdef TRACE_OSL_PROFILE
476 OSL_TRACE("Out osl_writeProfileImpl() [ok]");
477 #endif
478 return sal_True;
482 sal_Bool SAL_CALL osl_readProfileString(oslProfile Profile,
483 const sal_Char* pszSection, const sal_Char* pszEntry,
484 sal_Char* pszString, sal_uInt32 MaxLen,
485 const sal_Char* pszDefault)
487 sal_uInt32 NoEntry;
488 sal_Char* pStr=0;
489 osl_TProfileSection* pSec;
490 osl_TProfileImpl* pProfile=0;
491 osl_TProfileImpl* pTmpProfile=0;
492 sal_Bool bRet = sal_False;
494 #ifdef TRACE_OSL_PROFILE
495 OSL_TRACE("In osl_readProfileString");
496 #endif
498 pTmpProfile = (osl_TProfileImpl*) Profile;
500 if ( pTmpProfile == 0 )
502 #ifdef TRACE_OSL_PROFILE
503 OSL_TRACE("Out osl_readProfileString [pTmpProfile==0]");
504 #endif
505 return sal_False;
508 pthread_mutex_lock(&(pTmpProfile->m_AccessLock));
510 if ( pTmpProfile->m_bIsValid == sal_False )
512 pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
513 #ifdef TRACE_OSL_PROFILE
514 OSL_TRACE("Out osl_readProfileString [not valid]");
515 #endif
516 return sal_False;
519 pProfile = acquireProfile(Profile, sal_False);
521 if ( pProfile == NULL )
523 #ifdef TRACE_OSL_PROFILE
524 OSL_TRACE("Out osl_readProfileString [pProfile==0]");
525 #endif
526 return (sal_False);
529 if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
531 if (((pSec = findEntry(pProfile, pszSection, pszEntry, &NoEntry)) != NULL) &&
532 (NoEntry < pSec->m_NoEntries) &&
533 ((pStr = strchr(pProfile->m_Lines[pSec->m_Entries[NoEntry].m_Line],
534 '=')) != NULL))
536 pStr++;
538 else
540 pStr=(sal_Char*)pszDefault;
543 if ( pStr != 0 )
545 pStr = stripBlanks(pStr, NULL);
546 MaxLen = (MaxLen - 1 < strlen(pStr)) ? (MaxLen - 1) : strlen(pStr);
547 pStr = stripBlanks(pStr, &MaxLen);
548 strncpy(pszString, pStr, MaxLen);
549 pszString[MaxLen] = '\0';
552 else
553 { /* not implemented */ }
556 bRet=releaseProfile(pProfile);
557 OSL_ASSERT(bRet);
558 (void)bRet;
560 if ( pStr == 0 )
562 pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
563 #ifdef TRACE_OSL_PROFILE
564 OSL_TRACE("Out osl_readProfileString [pStr==0]");
565 #endif
566 return sal_False;
569 pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
571 #ifdef TRACE_OSL_PROFILE
572 OSL_TRACE("Out osl_readProfileString [ok]");
573 #endif
575 return (sal_True);
579 sal_Bool SAL_CALL osl_readProfileBool(oslProfile Profile,
580 const sal_Char* pszSection, const sal_Char* pszEntry,
581 sal_Bool Default)
583 sal_Char Line[32];
584 Line[0] = '\0';
586 #ifdef TRACE_OSL_PROFILE
587 OSL_TRACE("In osl_readProfileBool");
588 #endif
590 if (osl_readProfileString(Profile, pszSection, pszEntry, Line, sizeof(Line), ""))
592 if ((strcasecmp(Line, STR_INI_BOOLYES) == 0) ||
593 (strcasecmp(Line, STR_INI_BOOLON) == 0) ||
594 (strcasecmp(Line, STR_INI_BOOLONE) == 0))
595 Default = sal_True;
596 else
597 if ((strcasecmp(Line, STR_INI_BOOLNO) == 0) ||
598 (strcasecmp(Line, STR_INI_BOOLOFF) == 0) ||
599 (strcasecmp(Line, STR_INI_BOOLZERO) == 0))
600 Default = sal_False;
603 #ifdef TRACE_OSL_PROFILE
604 OSL_TRACE("Out osl_readProfileBool [ok]");
605 #endif
607 return (Default);
611 sal_uInt32 SAL_CALL osl_readProfileIdent(oslProfile Profile,
612 const sal_Char* pszSection, const sal_Char* pszEntry,
613 sal_uInt32 FirstId, const sal_Char* Strings[],
614 sal_uInt32 Default)
616 sal_uInt32 i;
617 sal_Char Line[256];
618 Line[0] = '\0';
620 #ifdef TRACE_OSL_PROFILE
621 OSL_TRACE("In osl_readProfileIdent");
622 #endif
624 if (osl_readProfileString(Profile, pszSection, pszEntry, Line, sizeof(Line), ""))
626 i = 0;
627 while (Strings[i] != NULL)
629 if (strcasecmp(Line, Strings[i]) == 0)
631 Default = i + FirstId;
632 break;
634 i++;
638 #ifdef TRACE_OSL_PROFILE
639 OSL_TRACE("Out osl_readProfileIdent [ok]");
640 #endif
641 return (Default);
644 sal_Bool SAL_CALL osl_writeProfileString(oslProfile Profile,
645 const sal_Char* pszSection, const sal_Char* pszEntry,
646 const sal_Char* pszString)
648 sal_uInt32 i;
649 sal_Bool bRet = sal_False;
650 sal_uInt32 NoEntry;
651 sal_Char* pStr;
652 sal_Char* Line = 0;
653 osl_TProfileSection* pSec;
654 osl_TProfileImpl* pProfile = 0;
655 osl_TProfileImpl* pTmpProfile = 0;
657 #ifdef TRACE_OSL_PROFILE
658 OSL_TRACE("In osl_writeProfileString");
659 #endif
661 pTmpProfile = (osl_TProfileImpl*) Profile;
663 if ( pTmpProfile == 0 )
665 #ifdef TRACE_OSL_PROFILE
666 OSL_TRACE("Out osl_writeProfileString [pTmpProfile==0]");
667 #endif
668 return sal_False;
671 pthread_mutex_lock(&(pTmpProfile->m_AccessLock));
673 if ( pTmpProfile->m_bIsValid == sal_False )
675 OSL_ASSERT(pTmpProfile->m_bIsValid);
676 pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
677 #ifdef TRACE_OSL_PROFILE
678 OSL_TRACE("Out osl_writeProfileString [not valid]");
679 #endif
680 return sal_False;
683 pProfile=acquireProfile(Profile, sal_True);
685 if (pProfile == NULL)
687 pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
688 #ifdef TRACE_OSL_PROFILE
689 OSL_TRACE("Out osl_writeProfileString [pProfile==0]");
690 #endif
691 return (sal_False);
694 Line = (sal_Char*) malloc(strlen(pszEntry)+strlen(pszString)+48);
696 if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
698 if ((pSec = findEntry(pProfile, pszSection, pszEntry, &NoEntry)) == NULL)
700 Line[0] = '\0';
701 addLine(pProfile, Line);
703 Line[0] = '[';
704 strcpy(&Line[1], pszSection);
705 Line[1 + strlen(pszSection)] = ']';
706 Line[2 + strlen(pszSection)] = '\0';
708 if (((pStr = addLine(pProfile, Line)) == NULL) ||
709 (! addSection(pProfile, pProfile->m_NoLines - 1, &pStr[1], strlen(pszSection))))
711 bRet=releaseProfile(pProfile);
712 OSL_ASSERT(bRet);
714 pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
716 free(Line);
718 #ifdef TRACE_OSL_PROFILE
719 OSL_TRACE("Out osl_writeProfileString [not added]");
720 #endif
721 return (sal_False);
724 pSec = &pProfile->m_Sections[pProfile->m_NoSections - 1];
725 NoEntry = pSec->m_NoEntries;
728 Line[0] = '\0';
729 strcpy(&Line[0], pszEntry);
730 Line[0 + strlen(pszEntry)] = '=';
731 strcpy(&Line[1 + strlen(pszEntry)], pszString);
733 if (NoEntry >= pSec->m_NoEntries)
735 if (pSec->m_NoEntries > 0)
736 i = pSec->m_Entries[pSec->m_NoEntries - 1].m_Line + 1;
737 else
738 i = pSec->m_Line + 1;
740 if (((pStr = insertLine(pProfile, Line, i)) == NULL) ||
741 (! addEntry(pProfile, pSec, i, pStr, strlen(pszEntry))))
743 bRet=releaseProfile(pProfile);
744 OSL_ASSERT(bRet);
746 pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
747 free(Line);
749 #ifdef TRACE_OSL_PROFILE
750 OSL_TRACE("Out osl_writeProfileString [not inserted]");
751 #endif
752 return (sal_False);
755 pProfile->m_Flags |= FLG_MODIFIED;
757 else
759 i = pSec->m_Entries[NoEntry].m_Line;
760 free(pProfile->m_Lines[i]);
761 pProfile->m_Lines[i] = strdup(Line);
762 setEntry(pProfile, pSec, NoEntry, i, pProfile->m_Lines[i], strlen(pszEntry));
764 pProfile->m_Flags |= FLG_MODIFIED;
767 else {
768 /* not implemented */
771 bRet = releaseProfile(pProfile);
772 OSL_ASSERT(bRet);
774 pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
775 if ( Line!= 0 )
777 free(Line);
780 #ifdef TRACE_OSL_PROFILE
781 OSL_TRACE("Out osl_writeProfileString [ok]");
782 #endif
784 return bRet;
788 sal_Bool SAL_CALL osl_writeProfileBool(oslProfile Profile,
789 const sal_Char* pszSection, const sal_Char* pszEntry,
790 sal_Bool Value)
792 sal_Bool bRet=sal_False;
794 #ifdef TRACE_OSL_PROFILE
795 OSL_TRACE("In osl_writeProfileBool");
796 #endif
798 if (Value)
799 bRet=osl_writeProfileString(Profile, pszSection, pszEntry, STR_INI_BOOLONE);
800 else
801 bRet=osl_writeProfileString(Profile, pszSection, pszEntry, STR_INI_BOOLZERO);
803 #ifdef TRACE_OSL_PROFILE
804 OSL_TRACE("Out osl_writeProfileBool [ok]");
805 #endif
807 return bRet;
811 sal_Bool SAL_CALL osl_writeProfileIdent(oslProfile Profile,
812 const sal_Char* pszSection, const sal_Char* pszEntry,
813 sal_uInt32 FirstId, const sal_Char* Strings[],
814 sal_uInt32 Value)
816 int i, n;
817 sal_Bool bRet=sal_False;
819 #ifdef TRACE_OSL_PROFILE
820 OSL_TRACE("In osl_writeProfileIdent");
821 #endif
823 for (n = 0; Strings[n] != NULL; n++);
825 if ((i = Value - FirstId) >= n)
826 bRet=sal_False;
827 else
828 bRet = osl_writeProfileString(Profile, pszSection, pszEntry, Strings[i]);
830 #ifdef TRACE_OSL_PROFILE
831 OSL_TRACE("Out osl_writeProfileIdent");
832 #endif
833 return bRet;
837 sal_Bool SAL_CALL osl_removeProfileEntry(oslProfile Profile,
838 const sal_Char *pszSection, const sal_Char *pszEntry)
840 sal_uInt32 NoEntry;
841 osl_TProfileSection* pSec;
842 osl_TProfileImpl* pProfile = 0;
843 osl_TProfileImpl* pTmpProfile = 0;
844 sal_Bool bRet = sal_False;
846 #ifdef TRACE_OSL_PROFILE
847 OSL_TRACE("In osl_removeProfileEntry");
848 #endif
850 pTmpProfile = (osl_TProfileImpl*) Profile;
852 if ( pTmpProfile == 0 )
854 #ifdef TRACE_OSL_PROFILE
855 OSL_TRACE("Out osl_removeProfileEntry [pProfile==0]");
856 #endif
857 return sal_False;
860 pthread_mutex_lock(&(pTmpProfile->m_AccessLock));
862 if ( pTmpProfile->m_bIsValid == sal_False )
864 OSL_ASSERT(pTmpProfile->m_bIsValid);
865 pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
866 #ifdef TRACE_OSL_PROFILE
867 OSL_TRACE("Out osl_removeProfileEntry [not valid]");
868 #endif
869 return sal_False;
873 pProfile = acquireProfile(Profile, sal_True);
875 if (pProfile == NULL)
877 pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
878 #ifdef TRACE_OSL_PROFILE
879 OSL_TRACE("Out osl_removeProfileEntry [pProfile==0]");
880 #endif
881 return (sal_False);
885 if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
887 if (((pSec = findEntry(pProfile, pszSection, pszEntry, &NoEntry)) != NULL) &&
888 (NoEntry < pSec->m_NoEntries))
890 removeLine(pProfile, pSec->m_Entries[NoEntry].m_Line);
891 removeEntry(pSec, NoEntry);
892 if (pSec->m_NoEntries == 0)
894 removeLine(pProfile, pSec->m_Line);
896 /* remove any empty separation line */
897 if ((pSec->m_Line > 0) && (pProfile->m_Lines[pSec->m_Line - 1][0] == '\0'))
898 removeLine(pProfile, pSec->m_Line - 1);
900 removeSection(pProfile, pSec);
903 pProfile->m_Flags |= FLG_MODIFIED;
906 else
907 { /* not implemented */ }
910 bRet = releaseProfile(pProfile);
911 OSL_ASSERT(bRet);
913 pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
915 #ifdef TRACE_OSL_PROFILE
916 OSL_TRACE("Out osl_removeProfileEntry [ok]");
917 #endif
918 return bRet;
922 sal_uInt32 SAL_CALL osl_getProfileSectionEntries(oslProfile Profile, const sal_Char *pszSection,
923 sal_Char* pszBuffer, sal_uInt32 MaxLen)
925 sal_uInt32 i, n = 0;
926 sal_uInt32 NoEntry;
927 osl_TProfileSection* pSec;
928 osl_TProfileImpl* pProfile = 0;
929 osl_TProfileImpl* pTmpProfile = 0;
930 sal_Bool bRet = sal_False;
932 #ifdef TRACE_OSL_PROFILE
933 OSL_TRACE("In osl_getProfileSectionEntries");
934 #endif
936 pTmpProfile = (osl_TProfileImpl*) Profile;
938 if ( pTmpProfile == 0 )
940 #ifdef TRACE_OSL_PROFILE
941 OSL_TRACE("Out osl_getProfileSectionEntries [pTmpProfile==0]");
942 #endif
943 return sal_False;
947 pthread_mutex_lock(&(pTmpProfile->m_AccessLock));
949 if ( pTmpProfile->m_bIsValid == sal_False )
951 OSL_ASSERT(pTmpProfile->m_bIsValid);
953 pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
955 #ifdef TRACE_OSL_PROFILE
956 OSL_TRACE("Out osl_getProfileSectionEntries [not valid]");
957 #endif
959 return sal_False;
962 pProfile = acquireProfile(Profile, sal_False);
964 if (pProfile == NULL)
966 pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
968 #ifdef TRACE_OSL_PROFILE
969 OSL_TRACE("Out osl_getProfileSectionEntries [pProfile=0]");
970 #endif
972 return (0);
976 if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
978 if ((pSec = findEntry(pProfile, pszSection, "", &NoEntry)) != NULL)
980 if (MaxLen != 0)
982 for (i = 0; i < pSec->m_NoEntries; i++)
984 if ((n + pSec->m_Entries[i].m_Len + 1) < MaxLen)
986 strncpy(&pszBuffer[n], &pProfile->m_Lines[pSec->m_Entries[i].m_Line]
987 [pSec->m_Entries[i].m_Offset], pSec->m_Entries[i].m_Len);
988 n += pSec->m_Entries[i].m_Len;
989 pszBuffer[n++] = '\0';
991 else
992 break;
996 pszBuffer[n++] = '\0';
998 else
1000 for (i = 0; i < pSec->m_NoEntries; i++)
1001 n += pSec->m_Entries[i].m_Len + 1;
1003 n += 1;
1006 else
1007 n = 0;
1009 else {
1010 /* not implemented */
1013 bRet=releaseProfile(pProfile);
1014 OSL_ASSERT(bRet);
1015 (void)bRet;
1017 pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
1019 #ifdef TRACE_OSL_PROFILE
1020 OSL_TRACE("Out osl_getProfileSectionEntries [ok]");
1021 #endif
1023 return (n);
1026 sal_uInt32 SAL_CALL osl_getProfileSections(oslProfile Profile, sal_Char* pszBuffer, sal_uInt32 MaxLen)
1028 sal_uInt32 i, n = 0;
1029 osl_TProfileSection* pSec;
1030 osl_TProfileImpl* pProfile = 0;
1031 osl_TProfileImpl* pTmpProfile = 0;
1032 sal_Bool bRet = sal_False;
1034 #ifdef TRACE_OSL_PROFILE
1035 OSL_TRACE("In osl_getProfileSections");
1036 #endif
1038 pTmpProfile = (osl_TProfileImpl*) Profile;
1040 if ( pTmpProfile == 0 )
1042 #ifdef TRACE_OSL_PROFILE
1043 OSL_TRACE("Out osl_getProfileSections [pTmpProfile==0]");
1044 #endif
1045 return sal_False;
1048 pthread_mutex_lock(&(pTmpProfile->m_AccessLock));
1050 if ( pTmpProfile->m_bIsValid == sal_False )
1052 OSL_ASSERT(pTmpProfile->m_bIsValid);
1053 pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
1054 #ifdef TRACE_OSL_PROFILE
1055 OSL_TRACE("Out osl_getProfileSections [not valid]");
1056 #endif
1057 return sal_False;
1060 pProfile = acquireProfile(Profile, sal_False);
1062 if (pProfile == NULL)
1064 pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
1066 #ifdef TRACE_OSL_PROFILE
1067 OSL_TRACE("Out osl_getProfileSections [pProfile==0]");
1068 #endif
1069 return (0);
1072 if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
1074 if (MaxLen != 0)
1076 for (i = 0; i < pProfile->m_NoSections; i++)
1078 pSec = &pProfile->m_Sections[i];
1080 if ((n + pSec->m_Len + 1) < MaxLen)
1082 strncpy(&pszBuffer[n], &pProfile->m_Lines[pSec->m_Line][pSec->m_Offset],
1083 pSec->m_Len);
1084 n += pSec->m_Len;
1085 pszBuffer[n++] = '\0';
1087 else
1088 break;
1091 pszBuffer[n++] = '\0';
1093 else
1095 for (i = 0; i < pProfile->m_NoSections; i++)
1096 n += pProfile->m_Sections[i].m_Len + 1;
1098 n += 1;
1101 else
1102 { /* not implemented */ }
1105 bRet=releaseProfile(pProfile);
1106 OSL_ASSERT(bRet);
1107 (void)bRet;
1109 pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
1111 #ifdef TRACE_OSL_PROFILE
1112 OSL_TRACE("Out osl_getProfileSections [ok]");
1113 #endif
1115 return (n);
1118 /*****************************************************************************/
1119 /* Static Module Functions */
1120 /*****************************************************************************/
1122 static osl_TStamp OslProfile_getFileStamp(osl_TFile* pFile)
1124 struct stat status;
1126 if ( (pFile->m_Handle < 0) || (fstat(pFile->m_Handle, &status) < 0) )
1128 return (0);
1132 return (status.st_mtime);
1135 static sal_Bool OslProfile_lockFile(const osl_TFile* pFile, osl_TLockMode eMode)
1137 struct flock lock;
1138 /* boring hack, but initializers for static vars must be constant */
1139 static sal_Bool bIsInitialized = sal_False;
1140 static sal_Bool bLockingDisabled;
1142 #ifdef TRACE_OSL_PROFILE
1143 OSL_TRACE("In OslProfile_lockFile");
1144 #endif
1146 if ( !bIsInitialized )
1148 sal_Char* pEnvValue;
1149 pEnvValue = getenv( "STAR_PROFILE_LOCKING_DISABLED" );
1151 if ( pEnvValue == 0 )
1153 bLockingDisabled = sal_False;
1156 else
1158 bLockingDisabled = sal_True;
1161 bIsInitialized = sal_True;
1164 if (pFile->m_Handle < 0)
1166 #ifdef TRACE_OSL_PROFILE
1167 OSL_TRACE("Out OslProfile_lockFile [invalid file handle]");
1168 #endif
1169 return (sal_False);
1173 if ( bLockingDisabled )
1175 #ifdef TRACE_OSL_PROFILE
1176 OSL_TRACE("Out OslProfile_lockFile [locking disabled]");
1177 #endif
1178 return (sal_True);
1182 lock.l_start = 0;
1183 lock.l_whence = SEEK_SET;
1184 lock.l_len = 0;
1186 switch (eMode)
1188 case un_lock:
1189 lock.l_type = F_UNLCK;
1190 break;
1192 case read_lock:
1193 lock.l_type = F_RDLCK;
1194 break;
1196 case write_lock:
1197 lock.l_type = F_WRLCK;
1198 break;
1201 #ifndef MACOSX // not MAC OSX
1202 if ( fcntl(pFile->m_Handle, F_SETLKW, &lock) == -1 )
1203 #else
1204 /* Mac OSX will return ENOTSUP for webdav drives so we should ignore it */
1205 if ( fcntl(pFile->m_Handle, F_SETLKW, &lock) == -1 && errno != ENOTSUP )
1206 #endif /* MACOSX */
1208 OSL_TRACE("fcntl returned -1 (%s)",strerror(errno));
1209 #ifdef TRACE_OSL_PROFILE
1210 OSL_TRACE("Out OslProfile_lockFile [fcntl F_SETLKW]");
1211 #endif
1212 return sal_False;
1215 #ifdef TRACE_OSL_PROFILE
1216 OSL_TRACE("Out OslProfile_lockFile [ok]");
1217 #endif
1218 return sal_True;
1221 static osl_TFile* openFileImpl(const sal_Char* pszFilename, oslProfileOption ProfileFlags )
1223 int Flags;
1224 osl_TFile* pFile = (osl_TFile*) calloc(1, sizeof(osl_TFile));
1225 sal_Bool bWriteable = sal_False;
1227 if ( ProfileFlags & ( osl_Profile_WRITELOCK | osl_Profile_FLUSHWRITE ) )
1229 #ifdef DEBUG_OSL_PROFILE
1230 OSL_TRACE("setting bWriteable to TRUE");
1231 #endif
1232 bWriteable=sal_True;
1235 if (! bWriteable)
1237 #ifdef DEBUG_OSL_PROFILE
1238 OSL_TRACE("opening '%s' read only",pszFilename);
1239 #endif
1241 pFile->m_Handle = open(pszFilename, O_RDONLY);
1242 /* mfe: argghh!!! do not check if the file could be openend */
1243 /* default mode expects it that way!!! */
1245 else
1247 #ifdef DEBUG_OSL_PROFILE
1248 OSL_TRACE("opening '%s' read/write",pszFilename);
1249 #endif
1250 if (((pFile->m_Handle = open(pszFilename, O_RDWR | O_CREAT | O_EXCL, DEFAULT_PMODE)) < 0) &&
1251 ((pFile->m_Handle = open(pszFilename, O_RDWR)) < 0))
1253 free(pFile);
1254 #ifdef TRACE_OSL_PROFILE
1255 OSL_TRACE("Out openFileImpl [open read/write]");
1256 #endif
1257 return (NULL);
1261 /* set close-on-exec flag */
1262 if ((Flags = fcntl(pFile->m_Handle, F_GETFD, 0)) != -1)
1264 Flags |= FD_CLOEXEC;
1265 fcntl(pFile->m_Handle, F_SETFD, Flags);
1268 pFile->m_pWriteBuf=0;
1269 pFile->m_nWriteBufFree=0;
1270 pFile->m_nWriteBufLen=0;
1272 if ( ProfileFlags & (osl_Profile_WRITELOCK | osl_Profile_READLOCK ) )
1274 #ifdef DEBUG_OSL_PROFILE
1275 OSL_TRACE("locking '%s' file",pszFilename);
1276 #endif
1277 OslProfile_lockFile(pFile, bWriteable ? write_lock : read_lock);
1280 #ifdef TRACE_OSL_PROFILE
1281 OSL_TRACE("Out openFileImpl [ok]");
1282 #endif
1283 return (pFile);
1286 static osl_TStamp closeFileImpl(osl_TFile* pFile, oslProfileOption Flags)
1288 osl_TStamp stamp = 0;
1290 #ifdef TRACE_OSL_PROFILE
1291 OSL_TRACE("In closeFileImpl");
1292 #endif
1294 if ( pFile == 0 )
1296 #ifdef TRACE_OSL_PROFILE
1297 OSL_TRACE("Out closeFileImpl [pFile == 0]");
1298 #endif
1299 return stamp;
1302 if ( pFile->m_Handle >= 0 )
1304 stamp = OslProfile_getFileStamp(pFile);
1306 if ( Flags & (osl_Profile_WRITELOCK | osl_Profile_WRITELOCK ) )
1308 OslProfile_lockFile(pFile, un_lock);
1311 close(pFile->m_Handle);
1312 pFile->m_Handle = -1;
1316 if ( pFile->m_pWriteBuf )
1318 free(pFile->m_pWriteBuf);
1321 free(pFile);
1323 #ifdef TRACE_OSL_PROFILE
1324 OSL_TRACE("Out closeFileImpl [ok]");
1325 #endif
1327 return(stamp);
1330 static sal_Bool OslProfile_rewindFile(osl_TFile* pFile, sal_Bool bTruncate)
1332 sal_Bool bRet = sal_True;
1333 #ifdef TRACE_OSL_PROFILE
1334 OSL_TRACE("In osl_OslProfile_rewindFile");
1335 #endif
1337 if (pFile->m_Handle >= 0)
1339 pFile->m_pReadPtr = pFile->m_ReadBuf + sizeof(pFile->m_ReadBuf);
1341 #ifdef DEBUG_OSL_PROFILE
1342 OSL_TRACE("rewinding");
1343 #endif
1344 bRet = (lseek(pFile->m_Handle, SEEK_SET, 0L) == 0L);
1346 if (bTruncate)
1348 #ifdef DEBUG_OSL_PROFILE
1349 OSL_TRACE("truncating");
1350 #endif
1351 bRet &= (ftruncate(pFile->m_Handle, 0L) == 0);
1356 #ifdef TRACE_OSL_PROFILE
1357 OSL_TRACE("Out osl_OslProfile_rewindFile [ok]");
1358 #endif
1359 return bRet;
1363 static sal_Char* OslProfile_getLine(osl_TFile* pFile)
1365 int Max, Free, Bytes, nLineBytes = 0;
1366 sal_Char* pChr;
1367 sal_Char* pLine = NULL;
1368 sal_Char* pNewLine;
1370 if ( pFile == 0 )
1372 return 0;
1375 if (pFile->m_Handle < 0)
1376 return NULL;
1380 Bytes = sizeof(pFile->m_ReadBuf) - (pFile->m_pReadPtr - pFile->m_ReadBuf);
1382 if (Bytes <= 1)
1384 /* refill buffer */
1385 memcpy(pFile->m_ReadBuf, pFile->m_pReadPtr, Bytes);
1386 pFile->m_pReadPtr = pFile->m_ReadBuf;
1388 Free = sizeof(pFile->m_ReadBuf) - Bytes;
1390 if ((Max = read(pFile->m_Handle, &pFile->m_ReadBuf[Bytes], Free)) < 0)
1392 OSL_TRACE("read failed '%s'",strerror(errno));
1394 if( pLine )
1395 rtl_freeMemory( pLine );
1396 pLine = NULL;
1397 break;
1400 if (Max < Free)
1402 if ((Max == 0) && ! pLine)
1403 break;
1405 pFile->m_ReadBuf[Bytes + Max] = '\0';
1409 for (pChr = pFile->m_pReadPtr;
1410 (*pChr != '\n') && (*pChr != '\r') && (*pChr != '\0') &&
1411 (pChr < (pFile->m_ReadBuf + sizeof(pFile->m_ReadBuf) - 1));
1412 pChr++);
1414 Max = pChr - pFile->m_pReadPtr;
1415 pNewLine = (sal_Char*) rtl_allocateMemory( nLineBytes + Max + 1 );
1416 if( pLine )
1418 memcpy( pNewLine, pLine, nLineBytes );
1419 rtl_freeMemory( pLine );
1421 memcpy(pNewLine+nLineBytes, pFile->m_pReadPtr, Max);
1422 nLineBytes += Max;
1423 pNewLine[ nLineBytes ] = 0;
1424 pLine = pNewLine;
1426 if (pChr < (pFile->m_ReadBuf + sizeof(pFile->m_ReadBuf) - 1))
1428 if (*pChr != '\0')
1430 if ((pChr[0] == '\r') && (pChr[1] == '\n'))
1431 pChr += 2;
1432 else
1433 pChr += 1;
1436 if ((pChr < (pFile->m_ReadBuf + sizeof(pFile->m_ReadBuf))) &&
1437 (*pChr == '\0'))
1438 pChr = pFile->m_ReadBuf + sizeof(pFile->m_ReadBuf);
1440 /* setting Max to -1 indicates terminating read loop */
1441 Max = -1;
1444 pFile->m_pReadPtr = pChr;
1446 while (Max > 0);
1448 return pLine;
1451 static sal_Bool OslProfile_putLine(osl_TFile* pFile, const sal_Char *pszLine)
1453 unsigned int Len = strlen(pszLine);
1455 #ifdef DEBUG_OSL_PROFILE
1456 int strLen=0;
1457 #endif
1459 if ( pFile == 0 || pFile->m_Handle < 0 )
1461 return (sal_False);
1464 if ( pFile->m_pWriteBuf == 0 )
1466 pFile->m_pWriteBuf = (sal_Char*) malloc(Len+3);
1467 pFile->m_nWriteBufLen = Len+3;
1468 pFile->m_nWriteBufFree = Len+3;
1470 else
1472 if ( pFile->m_nWriteBufFree <= Len + 3 )
1474 sal_Char* pTmp;
1476 pTmp=(sal_Char*) realloc(pFile->m_pWriteBuf,( ( pFile->m_nWriteBufLen + Len ) * 2) );
1477 if ( pTmp == 0 )
1479 return sal_False;
1481 pFile->m_pWriteBuf = pTmp;
1482 pFile->m_nWriteBufFree = pFile->m_nWriteBufFree + pFile->m_nWriteBufLen + ( 2 * Len );
1483 pFile->m_nWriteBufLen = ( pFile->m_nWriteBufLen + Len ) * 2;
1484 memset( (pFile->m_pWriteBuf) + ( pFile->m_nWriteBufLen - pFile->m_nWriteBufFree ), 0, pFile->m_nWriteBufFree);
1490 memcpy(pFile->m_pWriteBuf + ( pFile->m_nWriteBufLen - pFile->m_nWriteBufFree ),pszLine,Len+1);
1491 #ifdef DEBUG_OSL_PROFILE
1492 strLen = strlen(pFile->m_pWriteBuf);
1493 #endif
1494 pFile->m_pWriteBuf[pFile->m_nWriteBufLen - pFile->m_nWriteBufFree + Len]='\n';
1495 pFile->m_pWriteBuf[pFile->m_nWriteBufLen - pFile->m_nWriteBufFree + Len + 1]='\0';
1497 pFile->m_nWriteBufFree-=Len+1;
1499 return sal_True;
1502 /* platform specific end */
1504 static sal_Char* stripBlanks(sal_Char* String, sal_uInt32* pLen)
1506 if ( ( pLen != NULL ) && ( *pLen != 0 ) )
1508 while ((String[*pLen - 1] == ' ') || (String[*pLen - 1] == '\t'))
1509 (*pLen)--;
1511 while ( (*String == ' ') || (*String == '\t') )
1513 String++;
1514 (*pLen)--;
1517 else
1518 while ( (*String == ' ') || (*String == '\t') )
1519 String++;
1521 return (String);
1524 static sal_Char* addLine(osl_TProfileImpl* pProfile, const sal_Char* Line)
1526 if (pProfile->m_NoLines >= pProfile->m_MaxLines)
1528 if (pProfile->m_Lines == NULL)
1530 pProfile->m_MaxLines = LINES_INI;
1531 pProfile->m_Lines = (sal_Char **)malloc(pProfile->m_MaxLines * sizeof(sal_Char *));
1532 memset(pProfile->m_Lines,0,pProfile->m_MaxLines * sizeof(sal_Char *));
1534 else
1536 unsigned int idx=0;
1537 unsigned int oldmax=pProfile->m_MaxLines;
1539 pProfile->m_MaxLines += LINES_ADD;
1540 pProfile->m_Lines = (sal_Char **)realloc(pProfile->m_Lines,
1541 pProfile->m_MaxLines * sizeof(sal_Char *));
1542 for ( idx = oldmax ; idx < pProfile->m_MaxLines ; ++idx )
1544 pProfile->m_Lines[idx]=0;
1548 if (pProfile->m_Lines == NULL)
1550 pProfile->m_NoLines = 0;
1551 pProfile->m_MaxLines = 0;
1552 return (NULL);
1557 if ( pProfile->m_Lines != 0 && pProfile->m_Lines[pProfile->m_NoLines] != 0 )
1559 free(pProfile->m_Lines[pProfile->m_NoLines]);
1561 pProfile->m_Lines[pProfile->m_NoLines++] = strdup(Line);
1563 return (pProfile->m_Lines[pProfile->m_NoLines - 1]);
1566 static sal_Char* insertLine(osl_TProfileImpl* pProfile, const sal_Char* Line, sal_uInt32 LineNo)
1568 if (pProfile->m_NoLines >= pProfile->m_MaxLines)
1570 if (pProfile->m_Lines == NULL)
1572 pProfile->m_MaxLines = LINES_INI;
1573 pProfile->m_Lines = (sal_Char **)malloc(pProfile->m_MaxLines * sizeof(sal_Char *));
1574 memset(pProfile->m_Lines,0,pProfile->m_MaxLines * sizeof(sal_Char *));
1576 else
1578 pProfile->m_MaxLines += LINES_ADD;
1579 pProfile->m_Lines = (sal_Char **)realloc(pProfile->m_Lines,
1580 pProfile->m_MaxLines * sizeof(sal_Char *));
1582 memset(&pProfile->m_Lines[pProfile->m_NoLines],
1584 (pProfile->m_MaxLines - pProfile->m_NoLines - 1) * sizeof(sal_Char*));
1587 if (pProfile->m_Lines == NULL)
1589 pProfile->m_NoLines = 0;
1590 pProfile->m_MaxLines = 0;
1591 return (NULL);
1595 LineNo = LineNo > pProfile->m_NoLines ? pProfile->m_NoLines : LineNo;
1597 if (LineNo < pProfile->m_NoLines)
1599 sal_uInt32 i, n;
1600 osl_TProfileSection* pSec;
1602 memmove(&pProfile->m_Lines[LineNo + 1], &pProfile->m_Lines[LineNo],
1603 (pProfile->m_NoLines - LineNo) * sizeof(sal_Char *));
1606 /* adjust line references */
1607 for (i = 0; i < pProfile->m_NoSections; i++)
1609 pSec = &pProfile->m_Sections[i];
1611 if (pSec->m_Line >= LineNo)
1612 pSec->m_Line++;
1614 for (n = 0; n < pSec->m_NoEntries; n++)
1615 if (pSec->m_Entries[n].m_Line >= LineNo)
1616 pSec->m_Entries[n].m_Line++;
1620 pProfile->m_NoLines++;
1622 pProfile->m_Lines[LineNo] = strdup(Line);
1624 return (pProfile->m_Lines[LineNo]);
1627 static void removeLine(osl_TProfileImpl* pProfile, sal_uInt32 LineNo)
1629 if (LineNo < pProfile->m_NoLines)
1631 free(pProfile->m_Lines[LineNo]);
1632 pProfile->m_Lines[LineNo]=0;
1633 if (pProfile->m_NoLines - LineNo > 1)
1635 sal_uInt32 i, n;
1636 osl_TProfileSection* pSec;
1638 memmove(&pProfile->m_Lines[LineNo], &pProfile->m_Lines[LineNo + 1],
1639 (pProfile->m_NoLines - LineNo - 1) * sizeof(sal_Char *));
1641 memset(&pProfile->m_Lines[pProfile->m_NoLines - 1],
1643 (pProfile->m_MaxLines - pProfile->m_NoLines) * sizeof(sal_Char*));
1645 /* adjust line references */
1646 for (i = 0; i < pProfile->m_NoSections; i++)
1648 pSec = &pProfile->m_Sections[i];
1650 if (pSec->m_Line > LineNo)
1651 pSec->m_Line--;
1653 for (n = 0; n < pSec->m_NoEntries; n++)
1654 if (pSec->m_Entries[n].m_Line > LineNo)
1655 pSec->m_Entries[n].m_Line--;
1658 else
1660 pProfile->m_Lines[LineNo] = 0;
1663 pProfile->m_NoLines--;
1666 return;
1669 static void setEntry(osl_TProfileImpl* pProfile, osl_TProfileSection* pSection,
1670 sal_uInt32 NoEntry, sal_uInt32 Line,
1671 sal_Char* Entry, sal_uInt32 Len)
1673 Entry = stripBlanks(Entry, &Len);
1674 pSection->m_Entries[NoEntry].m_Line = Line;
1675 pSection->m_Entries[NoEntry].m_Offset = Entry - pProfile->m_Lines[Line];
1676 pSection->m_Entries[NoEntry].m_Len = Len;
1678 return;
1681 static sal_Bool addEntry(osl_TProfileImpl* pProfile, osl_TProfileSection *pSection,
1682 int Line, sal_Char* Entry, sal_uInt32 Len)
1684 if (pSection != NULL)
1686 if (pSection->m_NoEntries >= pSection->m_MaxEntries)
1688 if (pSection->m_Entries == NULL)
1690 pSection->m_MaxEntries = ENTRIES_INI;
1691 pSection->m_Entries = (osl_TProfileEntry *)malloc(
1692 pSection->m_MaxEntries * sizeof(osl_TProfileEntry));
1694 else
1696 pSection->m_MaxEntries += ENTRIES_ADD;
1697 pSection->m_Entries = (osl_TProfileEntry *)realloc(pSection->m_Entries,
1698 pSection->m_MaxEntries * sizeof(osl_TProfileEntry));
1701 if (pSection->m_Entries == NULL)
1703 pSection->m_NoEntries = 0;
1704 pSection->m_MaxEntries = 0;
1705 return (sal_False);
1709 pSection->m_NoEntries++;
1711 Entry = stripBlanks(Entry, &Len);
1712 setEntry(pProfile, pSection, pSection->m_NoEntries - 1, Line,
1713 Entry, Len);
1715 return (sal_True);
1718 return (sal_False);
1721 static void removeEntry(osl_TProfileSection *pSection, sal_uInt32 NoEntry)
1723 if (NoEntry < pSection->m_NoEntries)
1725 if (pSection->m_NoEntries - NoEntry > 1)
1727 memmove(&pSection->m_Entries[NoEntry],
1728 &pSection->m_Entries[NoEntry + 1],
1729 (pSection->m_NoEntries - NoEntry - 1) * sizeof(osl_TProfileEntry));
1730 pSection->m_Entries[pSection->m_NoEntries - 1].m_Line=0;
1731 pSection->m_Entries[pSection->m_NoEntries - 1].m_Offset=0;
1732 pSection->m_Entries[pSection->m_NoEntries - 1].m_Len=0;
1735 pSection->m_NoEntries--;
1738 return;
1741 static sal_Bool addSection(osl_TProfileImpl* pProfile, int Line, const sal_Char* Section, sal_uInt32 Len)
1743 if (pProfile->m_NoSections >= pProfile->m_MaxSections)
1745 if (pProfile->m_Sections == NULL)
1747 pProfile->m_MaxSections = SECTIONS_INI;
1748 pProfile->m_Sections = (osl_TProfileSection *)malloc(pProfile->m_MaxSections * sizeof(osl_TProfileSection));
1749 memset(pProfile->m_Sections,0,pProfile->m_MaxSections * sizeof(osl_TProfileSection));
1751 else
1753 unsigned int idx=0;
1754 unsigned int oldmax=pProfile->m_MaxSections;
1756 pProfile->m_MaxSections += SECTIONS_ADD;
1757 pProfile->m_Sections = (osl_TProfileSection *)realloc(pProfile->m_Sections,
1758 pProfile->m_MaxSections * sizeof(osl_TProfileSection));
1759 for ( idx = oldmax ; idx < pProfile->m_MaxSections ; ++idx )
1761 pProfile->m_Sections[idx].m_Entries=0;
1765 if (pProfile->m_Sections == NULL)
1767 pProfile->m_NoSections = 0;
1768 pProfile->m_MaxSections = 0;
1769 return (sal_False);
1773 pProfile->m_NoSections++;
1775 if ( pProfile->m_Sections[(pProfile->m_NoSections) - 1].m_Entries != 0 )
1777 free(pProfile->m_Sections[(pProfile->m_NoSections) - 1].m_Entries);
1779 pProfile->m_Sections[pProfile->m_NoSections - 1].m_Entries = NULL;
1780 pProfile->m_Sections[pProfile->m_NoSections - 1].m_NoEntries = 0;
1781 pProfile->m_Sections[pProfile->m_NoSections - 1].m_MaxEntries = 0;
1783 pProfile->m_Sections[pProfile->m_NoSections - 1].m_Line = Line;
1784 pProfile->m_Sections[pProfile->m_NoSections - 1].m_Offset = Section - pProfile->m_Lines[Line];
1785 pProfile->m_Sections[pProfile->m_NoSections - 1].m_Len = Len;
1787 return (sal_True);
1790 static void removeSection(osl_TProfileImpl* pProfile, osl_TProfileSection *pSection)
1792 sal_uInt32 Section;
1794 if ((Section = pSection - pProfile->m_Sections) < pProfile->m_NoSections)
1796 free (pSection->m_Entries);
1797 pSection->m_Entries=0;
1798 if (pProfile->m_NoSections - Section > 1)
1800 memmove(&pProfile->m_Sections[Section], &pProfile->m_Sections[Section + 1],
1801 (pProfile->m_NoSections - Section - 1) * sizeof(osl_TProfileSection));
1803 memset(&pProfile->m_Sections[pProfile->m_NoSections - 1],
1805 (pProfile->m_MaxSections - pProfile->m_NoSections) * sizeof(osl_TProfileSection));
1806 pProfile->m_Sections[pProfile->m_NoSections - 1].m_Entries = 0;
1808 else
1810 pSection->m_Entries = 0;
1813 pProfile->m_NoSections--;
1816 return;
1819 static osl_TProfileSection* findEntry(osl_TProfileImpl* pProfile, const sal_Char* Section,
1820 const sal_Char* Entry, sal_uInt32 *pNoEntry)
1822 static sal_uInt32 Sect = 0;
1823 sal_uInt32 i, n;
1824 sal_uInt32 Len;
1825 const sal_Char* pStr;
1826 osl_TProfileSection* pSec=0;
1828 Len = strlen(Section);
1830 n = Sect;
1832 for (i = 0; i < pProfile->m_NoSections; i++)
1834 n %= pProfile->m_NoSections;
1835 pSec = &pProfile->m_Sections[n];
1836 if ((Len == pSec->m_Len) &&
1837 (strncasecmp(Section, &pProfile->m_Lines[pSec->m_Line][pSec->m_Offset], pSec->m_Len)
1838 == 0))
1839 break;
1840 n++;
1843 Sect = n;
1845 if (i < pProfile->m_NoSections)
1847 Len = strlen(Entry);
1849 *pNoEntry = pSec->m_NoEntries;
1851 for (i = 0; i < pSec->m_NoEntries; i++)
1853 pStr = &pProfile->m_Lines[pSec->m_Entries[i].m_Line]
1854 [pSec->m_Entries[i].m_Offset];
1855 if ((Len == pSec->m_Entries[i].m_Len) &&
1856 (strncasecmp(Entry, pStr, pSec->m_Entries[i].m_Len)
1857 == 0))
1859 *pNoEntry = i;
1860 break;
1864 else
1865 pSec = NULL;
1867 return (pSec);
1870 static sal_Bool loadProfile(osl_TFile* pFile, osl_TProfileImpl* pProfile)
1872 sal_uInt32 i;
1873 sal_Char* pStr;
1874 sal_Char* pChar;
1876 sal_Char* pLine;
1877 sal_Char* bWasAdded = NULL;
1879 pProfile->m_NoLines = 0;
1880 pProfile->m_NoSections = 0;
1882 if ( pFile == 0 )
1884 return sal_False;
1887 if ( pProfile == 0 )
1889 return sal_False;
1892 OSL_VERIFY(OslProfile_rewindFile(pFile, sal_False));
1894 while ( ( pLine=OslProfile_getLine(pFile) ) != 0 )
1896 bWasAdded = addLine( pProfile, pLine );
1897 rtl_freeMemory( pLine );
1898 OSL_ASSERT(bWasAdded);
1899 if ( ! bWasAdded )
1900 return (sal_False);
1903 for (i = 0; i < pProfile->m_NoLines; i++)
1905 pStr = (sal_Char *)stripBlanks(pProfile->m_Lines[i], NULL);
1907 if ((*pStr == '\0') || (*pStr == ';'))
1908 continue;
1910 if ((*pStr != '[') || ((pChar = strrchr(pStr, ']')) == NULL) ||
1911 ((pChar - pStr) <= 2))
1913 /* insert entry */
1915 if (pProfile->m_NoSections < 1)
1916 continue;
1918 if ((pChar = strchr(pStr, '=')) == NULL)
1919 pChar = pStr + strlen(pStr);
1921 if (! addEntry(pProfile, &pProfile->m_Sections[pProfile->m_NoSections - 1],
1922 i, pStr, pChar - pStr))
1924 OSL_ASSERT(0);
1925 continue;
1929 else
1931 /* new section */
1933 if (! addSection(pProfile, i, pStr + 1, pChar - pStr - 1))
1935 OSL_ASSERT(0);
1936 continue;
1942 return (sal_True);
1945 static sal_Bool storeProfile(osl_TProfileImpl* pProfile, sal_Bool bCleanup)
1947 #ifdef TRACE_OSL_PROFILE
1948 OSL_TRACE("In storeProfile");
1949 #endif
1951 if (pProfile->m_Lines != NULL)
1953 if (pProfile->m_Flags & FLG_MODIFIED)
1955 sal_uInt32 i;
1957 osl_TFile* pTmpFile = osl_openTmpProfileImpl(pProfile);
1959 if ( pTmpFile == 0 )
1961 return sal_False;
1964 OSL_VERIFY(OslProfile_rewindFile(pTmpFile, sal_True));
1966 for ( i = 0 ; i < pProfile->m_NoLines ; i++ )
1968 OSL_VERIFY(OslProfile_putLine(pTmpFile, pProfile->m_Lines[i]));
1971 if ( ! writeProfileImpl(pTmpFile) )
1973 if ( pTmpFile->m_pWriteBuf != 0 )
1975 free(pTmpFile->m_pWriteBuf);
1978 pTmpFile->m_pWriteBuf=0;
1979 pTmpFile->m_nWriteBufLen=0;
1980 pTmpFile->m_nWriteBufFree=0;
1982 #ifdef TRACE_OSL_PROFILE
1983 OSL_TRACE("Out storeProfile [not flushed]");
1984 #endif
1985 closeFileImpl(pTmpFile,pProfile->m_Flags);
1987 return sal_False;
1990 pProfile->m_Flags &= ~FLG_MODIFIED;
1992 closeFileImpl(pProfile->m_pFile,pProfile->m_Flags);
1993 closeFileImpl(pTmpFile,pProfile->m_Flags);
1995 osl_ProfileSwapProfileNames(pProfile);
1997 pProfile->m_pFile = openFileImpl(pProfile->m_FileName,pProfile->m_Flags);
2001 if (bCleanup)
2003 while (pProfile->m_NoLines > 0)
2004 removeLine(pProfile, pProfile->m_NoLines - 1);
2006 free(pProfile->m_Lines);
2007 pProfile->m_Lines = NULL;
2008 pProfile->m_NoLines = 0;
2009 pProfile->m_MaxLines = 0;
2011 while (pProfile->m_NoSections > 0)
2012 removeSection(pProfile, &pProfile->m_Sections[pProfile->m_NoSections - 1]);
2014 free(pProfile->m_Sections);
2015 pProfile->m_Sections = NULL;
2016 pProfile->m_NoSections = 0;
2017 pProfile->m_MaxSections = 0;
2021 #ifdef TRACE_OSL_PROFILE
2022 OSL_TRACE("Out storeProfile [ok]");
2023 #endif
2024 return (sal_True);
2028 static osl_TFile* osl_openTmpProfileImpl(osl_TProfileImpl* pProfile)
2030 osl_TFile* pFile=0;
2031 sal_Char* pszExtension = "tmp";
2032 sal_Char pszTmpName[PATH_MAX];
2033 oslProfileOption PFlags=0;
2035 pszTmpName[0] = '\0';
2037 /* generate tmp profilename */
2038 osl_ProfileGenerateExtension(pProfile->m_FileName,pszExtension,pszTmpName);
2040 if ( pszTmpName[0] == 0 )
2042 return 0;
2045 if ( ! ( pProfile->m_Flags & osl_Profile_READLOCK ) )
2047 PFlags |= osl_Profile_WRITELOCK;
2050 /* open this file */
2051 pFile = openFileImpl(pszTmpName,pProfile->m_Flags | PFlags);
2054 /* return new pFile */
2055 return pFile;
2058 static sal_Bool osl_ProfileSwapProfileNames(osl_TProfileImpl* pProfile)
2060 sal_Bool bRet = sal_False;
2062 sal_Char pszBakFile[PATH_MAX];
2063 sal_Char pszTmpFile[PATH_MAX];
2064 sal_Char pszIniFile[PATH_MAX];
2066 pszBakFile[0] = '\0';
2067 pszTmpFile[0] = '\0';
2068 pszIniFile[0] = '\0';
2070 osl_ProfileGenerateExtension(pProfile->m_FileName,"bak",pszBakFile);
2072 strcpy(pszIniFile,pProfile->m_FileName);
2074 osl_ProfileGenerateExtension(pProfile->m_FileName,"tmp",pszTmpFile);
2076 /* unlink bak */
2077 unlink( pszBakFile );
2079 /* rename ini bak */
2080 rename( pszIniFile, pszBakFile );
2082 /* rename tmp ini */
2083 rename( pszTmpFile, pszIniFile );
2085 return bRet;
2089 static void osl_ProfileGenerateExtension(sal_Char* pszFileName, sal_Char* pszExtension, sal_Char* pszTmpName)
2092 strcpy(pszTmpName,pszFileName);
2093 strcat(pszTmpName,".");
2094 strcat(pszTmpName,pszExtension);
2096 return;
2100 static osl_TProfileImpl* acquireProfile(oslProfile Profile, sal_Bool bWriteable)
2102 osl_TProfileImpl* pProfile = (osl_TProfileImpl*)Profile;
2103 oslProfileOption PFlags=0;
2105 if ( bWriteable )
2107 PFlags = osl_Profile_DEFAULT | osl_Profile_WRITELOCK;
2109 else
2111 PFlags = osl_Profile_DEFAULT;
2115 if (pProfile == NULL)
2117 #ifdef DEBUG_OSL_PROFILE
2118 OSL_TRACE("AUTOOPEN MODE");
2119 #endif
2121 if ( ( pProfile = (osl_TProfileImpl*) osl_openProfile(0, PFlags ) ) != NULL )
2123 pProfile->m_Flags |= FLG_AUTOOPEN;
2126 else
2128 #ifdef DEBUG_OSL_PROFILE
2129 OSL_TRACE("try to acquire");
2130 #endif
2132 if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
2134 if (! (pProfile->m_Flags & (osl_Profile_READLOCK | osl_Profile_WRITELOCK | osl_Profile_FLUSHWRITE )))
2136 osl_TStamp Stamp;
2138 #ifdef DEBUG_OSL_PROFILE
2139 OSL_TRACE("Profile acquire DEFAULT MODE");
2140 #endif
2141 if (! (pProfile->m_pFile = openFileImpl(pProfile->m_FileName, pProfile->m_Flags | PFlags )))
2142 return NULL;
2144 Stamp = OslProfile_getFileStamp(pProfile->m_pFile);
2146 if (memcmp(&Stamp, &(pProfile->m_Stamp), sizeof(osl_TStamp)))
2148 sal_Bool bRet=sal_False;
2150 pProfile->m_Stamp = Stamp;
2152 bRet=loadProfile(pProfile->m_pFile, pProfile);
2153 OSL_ASSERT(bRet);
2154 (void)bRet;
2157 else
2159 #ifdef DEBUG_OSL_PROFILE
2160 OSL_TRACE("Profile acquire READ/WRITELOCK MODE");
2161 #endif
2162 /* A readlock file could not be written */
2163 if ((pProfile->m_Flags & osl_Profile_READLOCK) && bWriteable)
2165 return (NULL);
2171 return (pProfile);
2174 static sal_Bool releaseProfile(osl_TProfileImpl* pProfile)
2176 #ifdef TRACE_OSL_PROFILE
2177 OSL_TRACE("In releaseProfile");
2178 #endif
2180 if ( pProfile == 0 )
2182 #ifdef TRACE_OSL_PROFILE
2183 OSL_TRACE("Out releaseProfile [profile==0]");
2184 #endif
2185 return sal_False;
2188 if (pProfile->m_Flags & FLG_AUTOOPEN)
2190 #ifdef TRACE_OSL_PROFILE
2191 OSL_TRACE("Out releaseProfile [AUTOOPEN]");
2192 #endif
2193 return (osl_closeProfile((oslProfile)pProfile));
2195 else
2197 #ifdef DEBUG_OSL_PROFILE
2198 OSL_TRACE("DEFAULT MODE");
2199 #endif
2200 if (! (pProfile->m_Flags & (osl_Profile_READLOCK | osl_Profile_WRITELOCK | osl_Profile_FLUSHWRITE )))
2202 if (pProfile->m_Flags & FLG_MODIFIED)
2204 sal_Bool bRet=storeProfile(pProfile, sal_False);
2205 OSL_ASSERT(bRet);
2206 (void)bRet;
2209 closeFileImpl(pProfile->m_pFile,pProfile->m_Flags);
2210 pProfile->m_pFile = NULL;
2214 #ifdef TRACE_OSL_PROFILE
2215 OSL_TRACE("Out releaseProfile [ok]");
2216 #endif
2217 return (sal_True);
2220 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */