Updated core
[LibreOffice.git] / sal / osl / unx / profile.c
blobd27dda76546394a9f64475cf5821d42df5723d6f
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 "system.h"
22 #include "readwrite_helper.h"
24 #include <osl/diagnose.h>
25 #include <osl/profile.h>
26 #include <osl/process.h>
27 #include <osl/thread.h>
28 #include <rtl/alloc.h>
29 #include <osl/util.h>
31 #define LINES_INI 32
32 #define LINES_ADD 10
33 #define SECTIONS_INI 5
34 #define SECTIONS_ADD 3
35 #define ENTRIES_INI 5
36 #define ENTRIES_ADD 3
38 #define STR_INI_BOOLYES "yes"
39 #define STR_INI_BOOLON "on"
40 #define STR_INI_BOOLONE "1"
41 #define STR_INI_BOOLNO "no"
42 #define STR_INI_BOOLOFF "off"
43 #define STR_INI_BOOLZERO "0"
45 #define FLG_USER 0x00FF
46 #define FLG_AUTOOPEN 0x0100
47 #define FLG_MODIFIED 0x0200
49 #define DEFAULT_PMODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)
51 /*#define DEBUG_OSL_PROFILE*/
52 /*#define TRACE_OSL_PROFILE*/
54 /*****************************************************************************/
55 /* Data Type Definition */
56 /*****************************************************************************/
58 typedef time_t osl_TStamp;
60 typedef enum _osl_TLockMode
62 un_lock, read_lock, write_lock
63 } osl_TLockMode;
65 typedef struct _osl_TFile
67 int m_Handle;
68 sal_Char* m_pReadPtr;
69 sal_Char m_ReadBuf[512];
70 sal_Char* m_pWriteBuf;
71 sal_uInt32 m_nWriteBufLen;
72 sal_uInt32 m_nWriteBufFree;
73 } osl_TFile;
75 typedef struct _osl_TProfileEntry
77 sal_uInt32 m_Line;
78 sal_uInt32 m_Offset;
79 sal_uInt32 m_Len;
80 } osl_TProfileEntry;
82 typedef struct _osl_TProfileSection
84 sal_uInt32 m_Line;
85 sal_uInt32 m_Offset;
86 sal_uInt32 m_Len;
87 sal_uInt32 m_NoEntries;
88 sal_uInt32 m_MaxEntries;
89 osl_TProfileEntry* m_Entries;
90 } osl_TProfileSection;
94 Profile-data structure hidden behind oslProfile:
96 typedef struct _osl_TProfileImpl
98 sal_uInt32 m_Flags;
99 osl_TFile* m_pFile;
100 osl_TStamp m_Stamp;
101 sal_Char m_FileName[PATH_MAX + 1];
102 sal_uInt32 m_NoLines;
103 sal_uInt32 m_MaxLines;
104 sal_uInt32 m_NoSections;
105 sal_uInt32 m_MaxSections;
106 sal_Char** m_Lines;
107 osl_TProfileSection* m_Sections;
108 pthread_mutex_t m_AccessLock;
109 sal_Bool m_bIsValid;
110 } osl_TProfileImpl;
113 /*****************************************************************************/
114 /* Static Module Function Declarations */
115 /*****************************************************************************/
117 static osl_TFile* openFileImpl(const sal_Char* pszFilename, oslProfileOption ProfileFlags);
118 static osl_TStamp closeFileImpl(osl_TFile* pFile, oslProfileOption Flags);
119 static sal_Bool OslProfile_lockFile(const osl_TFile* pFile, osl_TLockMode eMode);
120 static sal_Bool OslProfile_rewindFile(osl_TFile* pFile, sal_Bool bTruncate);
121 static osl_TStamp OslProfile_getFileStamp(osl_TFile* pFile);
123 static sal_Char* OslProfile_getLine(osl_TFile* pFile);
124 static sal_Bool OslProfile_putLine(osl_TFile* pFile, const sal_Char *pszLine);
125 static sal_Char* stripBlanks(sal_Char* String, sal_uInt32* pLen);
126 static sal_Char* addLine(osl_TProfileImpl* pProfile, const sal_Char* Line);
127 static sal_Char* insertLine(osl_TProfileImpl* pProfile, const sal_Char* Line, sal_uInt32 LineNo);
128 static void removeLine(osl_TProfileImpl* pProfile, sal_uInt32 LineNo);
129 static void setEntry(osl_TProfileImpl* pProfile, osl_TProfileSection* pSection,
130 sal_uInt32 NoEntry, sal_uInt32 Line,
131 sal_Char* Entry, sal_uInt32 Len);
132 static sal_Bool addEntry(osl_TProfileImpl* pProfile, osl_TProfileSection *pSection,
133 int Line, sal_Char* Entry, sal_uInt32 Len);
134 static void removeEntry(osl_TProfileSection *pSection, sal_uInt32 NoEntry);
135 static sal_Bool addSection(osl_TProfileImpl* pProfile, int Line, const sal_Char* Section, sal_uInt32 Len);
136 static void removeSection(osl_TProfileImpl* pProfile, osl_TProfileSection *pSection);
137 static osl_TProfileSection* findEntry(osl_TProfileImpl* pProfile, const sal_Char* Section,
138 const sal_Char* Entry, sal_uInt32 *pNoEntry);
139 static sal_Bool loadProfile(osl_TFile* pFile, osl_TProfileImpl* pProfile);
140 static sal_Bool storeProfile(osl_TProfileImpl* pProfile, sal_Bool bCleanup);
141 static osl_TProfileImpl* acquireProfile(oslProfile Profile, sal_Bool bWriteable);
142 static sal_Bool releaseProfile(osl_TProfileImpl* pProfile);
144 static sal_Bool writeProfileImpl (osl_TFile* pFile);
145 static osl_TFile* osl_openTmpProfileImpl(osl_TProfileImpl*);
146 static sal_Bool osl_ProfileSwapProfileNames(osl_TProfileImpl*);
147 static void osl_ProfileGenerateExtension(sal_Char* pszFileName, sal_Char* pszExtension, sal_Char* pszTmpName);
148 static oslProfile SAL_CALL osl_psz_openProfile(const sal_Char *pszProfileName, oslProfileOption Flags);
150 /* implemented in file.c */
151 extern oslFileError FileURLToPath( char *, size_t, rtl_uString* );
153 /*****************************************************************************/
154 /* Exported Module Functions */
155 /*****************************************************************************/
156 oslProfile SAL_CALL osl_openProfile(rtl_uString *ustrProfileName, oslProfileOption Options)
158 char profilePath[PATH_MAX] = "";
160 if ( ustrProfileName != 0 && ustrProfileName->buffer[0] != 0 )
161 FileURLToPath( profilePath, PATH_MAX, ustrProfileName );
163 return osl_psz_openProfile( profilePath,Options );
167 static oslProfile SAL_CALL osl_psz_openProfile(const sal_Char *pszProfileName, oslProfileOption Flags)
169 osl_TFile* pFile;
170 osl_TProfileImpl* pProfile;
171 sal_Bool bRet = sal_False;
173 #ifdef TRACE_OSL_PROFILE
174 OSL_TRACE("In osl_openProfile");
175 #endif
177 #ifdef DEBUG_OSL_PROFILE
178 Flags=osl_Profile_FLUSHWRITE;
180 OSL_TRACE("opening '%s'",pszProfileName);
181 if ( Flags == osl_Profile_DEFAULT )
183 OSL_TRACE("with osl_Profile_DEFAULT");
185 if ( Flags & osl_Profile_SYSTEM )
187 OSL_TRACE("with osl_Profile_SYSTEM");
189 if ( Flags & osl_Profile_READLOCK )
191 OSL_TRACE("with osl_Profile_READLOCK");
193 if ( Flags & osl_Profile_WRITELOCK )
195 OSL_TRACE("with osl_Profile_WRITELOCK");
197 if ( Flags & osl_Profile_FLUSHWRITE )
199 OSL_TRACE("with osl_Profile_FLUSHWRITE");
201 #endif
204 if ( ( pFile = openFileImpl(pszProfileName, Flags ) ) == NULL )
206 #ifdef TRACE_OSL_PROFILE
207 OSL_TRACE("Out osl_openProfile [not opened]");
208 #endif
209 return (NULL);
213 pProfile = (osl_TProfileImpl*)calloc(1, sizeof(osl_TProfileImpl));
215 if ( pProfile == 0 )
217 closeFileImpl(pFile, Flags);
218 return 0;
221 pProfile->m_Flags = Flags & FLG_USER;
223 if ( Flags & ( osl_Profile_READLOCK | osl_Profile_WRITELOCK | osl_Profile_FLUSHWRITE ) )
225 pProfile->m_pFile = pFile;
228 pthread_mutex_init(&(pProfile->m_AccessLock),PTHREAD_MUTEXATTR_DEFAULT);
229 pProfile->m_bIsValid=sal_True;
231 pProfile->m_Stamp = OslProfile_getFileStamp(pFile);
232 bRet=loadProfile(pFile, pProfile);
233 bRet &= realpath(pszProfileName, pProfile->m_FileName) != NULL;
234 OSL_ASSERT(bRet);
236 if (pProfile->m_pFile == NULL)
237 closeFileImpl(pFile,pProfile->m_Flags);
239 #ifdef TRACE_OSL_PROFILE
240 OSL_TRACE("Out osl_openProfile [ok]");
241 #endif
242 return (pProfile);
245 sal_Bool SAL_CALL osl_closeProfile(oslProfile Profile)
247 osl_TProfileImpl* pProfile = (osl_TProfileImpl*)Profile;
248 osl_TProfileImpl* pTmpProfile;
250 #ifdef TRACE_OSL_PROFILE
251 OSL_TRACE("In osl_closeProfile");
252 #endif
254 if ( Profile == 0 )
256 #ifdef TRACE_OSL_PROFILE
257 OSL_TRACE("Out osl_closeProfile [profile==0]");
258 #endif
259 return sal_False;
262 pthread_mutex_lock(&(pProfile->m_AccessLock));
264 if ( pProfile->m_bIsValid == sal_False )
266 OSL_ASSERT(pProfile->m_bIsValid);
267 pthread_mutex_unlock(&(pProfile->m_AccessLock));
268 #ifdef TRACE_OSL_PROFILE
269 OSL_TRACE("Out osl_closeProfile [not valid]");
270 #endif
271 return sal_False;
274 pProfile->m_bIsValid=sal_False;
276 if ( ! ( pProfile->m_Flags & osl_Profile_READLOCK ) && ( pProfile->m_Flags & FLG_MODIFIED ) )
278 pTmpProfile = acquireProfile(Profile,sal_True);
280 if ( pTmpProfile != 0 )
282 sal_Bool bRet = storeProfile(pTmpProfile, sal_True);
283 OSL_ASSERT(bRet);
284 (void)bRet;
287 else
289 pTmpProfile = acquireProfile(Profile,sal_False);
293 if ( pTmpProfile == 0 )
295 pthread_mutex_unlock(&(pProfile->m_AccessLock));
296 #ifdef TRACE_OSL_PROFILE
297 OSL_TRACE("Out osl_closeProfile [pProfile==0]");
298 #endif
299 return sal_False;
302 pProfile = pTmpProfile;
304 if (pProfile->m_pFile != NULL)
305 closeFileImpl(pProfile->m_pFile,pProfile->m_Flags);
307 pProfile->m_pFile = NULL;
308 pProfile->m_FileName[0] = '\0';
310 /* release whole profile data types memory */
311 if ( pProfile->m_NoLines > 0)
313 unsigned int idx=0;
314 if ( pProfile->m_Lines != 0 )
316 for ( idx = 0 ; idx < pProfile->m_NoLines ; ++idx)
318 if ( pProfile->m_Lines[idx] != 0 )
320 free(pProfile->m_Lines[idx]);
321 pProfile->m_Lines[idx]=0;
324 free(pProfile->m_Lines);
325 pProfile->m_Lines=0;
327 if ( pProfile->m_Sections != 0 )
329 /*osl_TProfileSection* pSections=pProfile->m_Sections;*/
330 for ( idx = 0 ; idx < pProfile->m_NoSections ; ++idx )
332 if ( pProfile->m_Sections[idx].m_Entries != 0 )
334 free(pProfile->m_Sections[idx].m_Entries);
335 pProfile->m_Sections[idx].m_Entries=0;
338 free(pProfile->m_Sections);
339 pProfile->m_Sections=0;
343 pthread_mutex_unlock(&(pProfile->m_AccessLock));
345 pthread_mutex_destroy(&(pProfile->m_AccessLock));
347 free(pProfile);
349 #ifdef TRACE_OSL_PROFILE
350 OSL_TRACE("Out osl_closeProfile [ok]");
351 #endif
352 return (sal_True);
356 sal_Bool SAL_CALL osl_flushProfile(oslProfile Profile)
358 osl_TProfileImpl* pProfile = (osl_TProfileImpl*) Profile;
359 osl_TFile* pFile;
360 sal_Bool bRet = sal_False;
362 #ifdef TRACE_OSL_PROFILE
363 OSL_TRACE("In osl_flushProfile()");
364 #endif
366 if ( pProfile == 0 )
368 #ifdef TRACE_OSL_PROFILE
369 OSL_TRACE("Out osl_flushProfile() [pProfile == 0]");
370 #endif
371 return sal_False;
374 pthread_mutex_lock(&(pProfile->m_AccessLock));
376 if ( pProfile->m_bIsValid == sal_False )
378 OSL_ASSERT(pProfile->m_bIsValid);
379 pthread_mutex_unlock(&(pProfile->m_AccessLock));
380 #ifdef TRACE_OSL_PROFILE
381 OSL_TRACE("Out osl_flushProfile [not valid]");
382 #endif
383 return sal_False;
386 pFile = pProfile->m_pFile;
387 if ( !( pFile != 0 && pFile->m_Handle >= 0 ) )
389 pthread_mutex_unlock(&(pProfile->m_AccessLock));
390 #ifdef TRACE_OSL_PROFILE
391 OSL_TRACE("Out osl_flushProfile() [invalid file]");
392 #endif
393 return sal_False;
396 if ( pProfile->m_Flags & FLG_MODIFIED )
398 #ifdef DEBUG_OSL_PROFILE
399 OSL_TRACE("swapping to storeprofile");
400 #endif
401 bRet = storeProfile(pProfile,sal_False);
402 OSL_ASSERT(bRet);
405 #ifdef TRACE_OSL_PROFILE
406 OSL_TRACE("Out osl_flushProfile() [ok]");
407 #endif
408 pthread_mutex_unlock(&(pProfile->m_AccessLock));
409 return bRet;
412 static sal_Bool writeProfileImpl(osl_TFile* pFile)
414 #if OSL_DEBUG_LEVEL > 1
415 unsigned int nLen=0;
416 #endif
418 #ifdef TRACE_OSL_PROFILE
419 OSL_TRACE("In osl_writeProfileImpl()");
420 #endif
422 if ( !( pFile != 0 && pFile->m_Handle >= 0 ) || ( pFile->m_pWriteBuf == 0 ) )
424 #ifdef TRACE_OSL_PROFILE
425 OSL_TRACE("Out osl_writeProfileImpl() [invalid args]");
426 #endif
427 return sal_False;
430 #if OSL_DEBUG_LEVEL > 1
431 nLen=strlen(pFile->m_pWriteBuf);
432 OSL_ASSERT(nLen == (pFile->m_nWriteBufLen - pFile->m_nWriteBufFree));
433 #endif
435 if ( !safeWrite(pFile->m_Handle, pFile->m_pWriteBuf, pFile->m_nWriteBufLen - pFile->m_nWriteBufFree) )
437 OSL_TRACE("write failed '%s'",strerror(errno));
438 return (sal_False);
441 free(pFile->m_pWriteBuf);
442 pFile->m_pWriteBuf=0;
443 pFile->m_nWriteBufLen=0;
444 pFile->m_nWriteBufFree=0;
445 #ifdef TRACE_OSL_PROFILE
446 OSL_TRACE("Out osl_writeProfileImpl() [ok]");
447 #endif
448 return sal_True;
452 sal_Bool SAL_CALL osl_readProfileString(oslProfile Profile,
453 const sal_Char* pszSection, const sal_Char* pszEntry,
454 sal_Char* pszString, sal_uInt32 MaxLen,
455 const sal_Char* pszDefault)
457 sal_uInt32 NoEntry;
458 sal_Char* pStr=0;
459 osl_TProfileSection* pSec;
460 osl_TProfileImpl* pProfile=0;
461 osl_TProfileImpl* pTmpProfile=0;
462 sal_Bool bRet = sal_False;
464 #ifdef TRACE_OSL_PROFILE
465 OSL_TRACE("In osl_readProfileString");
466 #endif
468 pTmpProfile = (osl_TProfileImpl*) Profile;
470 if ( pTmpProfile == 0 )
472 #ifdef TRACE_OSL_PROFILE
473 OSL_TRACE("Out osl_readProfileString [pTmpProfile==0]");
474 #endif
475 return sal_False;
478 pthread_mutex_lock(&(pTmpProfile->m_AccessLock));
480 if ( pTmpProfile->m_bIsValid == sal_False )
482 pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
483 #ifdef TRACE_OSL_PROFILE
484 OSL_TRACE("Out osl_readProfileString [not valid]");
485 #endif
486 return sal_False;
489 pProfile = acquireProfile(Profile, sal_False);
491 if ( pProfile == NULL )
493 pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
494 #ifdef TRACE_OSL_PROFILE
495 OSL_TRACE("Out osl_readProfileString [pProfile==0]");
496 #endif
497 return (sal_False);
500 if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
502 if (((pSec = findEntry(pProfile, pszSection, pszEntry, &NoEntry)) != NULL) &&
503 (NoEntry < pSec->m_NoEntries) &&
504 ((pStr = strchr(pProfile->m_Lines[pSec->m_Entries[NoEntry].m_Line],
505 '=')) != NULL))
507 pStr++;
509 else
511 pStr=(sal_Char*)pszDefault;
514 if ( pStr != 0 )
516 pStr = stripBlanks(pStr, NULL);
517 MaxLen = (MaxLen - 1 < strlen(pStr)) ? (MaxLen - 1) : strlen(pStr);
518 pStr = stripBlanks(pStr, &MaxLen);
519 strncpy(pszString, pStr, MaxLen);
520 pszString[MaxLen] = '\0';
523 else
524 { /* not implemented */ }
527 bRet=releaseProfile(pProfile);
528 OSL_ASSERT(bRet);
529 (void)bRet;
531 if ( pStr == 0 )
533 pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
534 #ifdef TRACE_OSL_PROFILE
535 OSL_TRACE("Out osl_readProfileString [pStr==0]");
536 #endif
537 return sal_False;
540 pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
542 #ifdef TRACE_OSL_PROFILE
543 OSL_TRACE("Out osl_readProfileString [ok]");
544 #endif
546 return (sal_True);
550 sal_Bool SAL_CALL osl_readProfileBool(oslProfile Profile,
551 const sal_Char* pszSection, const sal_Char* pszEntry,
552 sal_Bool Default)
554 sal_Char Line[32];
555 Line[0] = '\0';
557 #ifdef TRACE_OSL_PROFILE
558 OSL_TRACE("In osl_readProfileBool");
559 #endif
561 if (osl_readProfileString(Profile, pszSection, pszEntry, Line, sizeof(Line), ""))
563 if ((strcasecmp(Line, STR_INI_BOOLYES) == 0) ||
564 (strcasecmp(Line, STR_INI_BOOLON) == 0) ||
565 (strcasecmp(Line, STR_INI_BOOLONE) == 0))
566 Default = sal_True;
567 else
568 if ((strcasecmp(Line, STR_INI_BOOLNO) == 0) ||
569 (strcasecmp(Line, STR_INI_BOOLOFF) == 0) ||
570 (strcasecmp(Line, STR_INI_BOOLZERO) == 0))
571 Default = sal_False;
574 #ifdef TRACE_OSL_PROFILE
575 OSL_TRACE("Out osl_readProfileBool [ok]");
576 #endif
578 return (Default);
582 sal_uInt32 SAL_CALL osl_readProfileIdent(oslProfile Profile,
583 const sal_Char* pszSection, const sal_Char* pszEntry,
584 sal_uInt32 FirstId, const sal_Char* Strings[],
585 sal_uInt32 Default)
587 sal_uInt32 i;
588 sal_Char Line[256];
589 Line[0] = '\0';
591 #ifdef TRACE_OSL_PROFILE
592 OSL_TRACE("In osl_readProfileIdent");
593 #endif
595 if (osl_readProfileString(Profile, pszSection, pszEntry, Line, sizeof(Line), ""))
597 i = 0;
598 while (Strings[i] != NULL)
600 if (strcasecmp(Line, Strings[i]) == 0)
602 Default = i + FirstId;
603 break;
605 i++;
609 #ifdef TRACE_OSL_PROFILE
610 OSL_TRACE("Out osl_readProfileIdent [ok]");
611 #endif
612 return (Default);
615 sal_Bool SAL_CALL osl_writeProfileString(oslProfile Profile,
616 const sal_Char* pszSection, const sal_Char* pszEntry,
617 const sal_Char* pszString)
619 sal_uInt32 i;
620 sal_Bool bRet = sal_False;
621 sal_uInt32 NoEntry;
622 sal_Char* pStr;
623 sal_Char* Line = 0;
624 osl_TProfileSection* pSec;
625 osl_TProfileImpl* pProfile = 0;
626 osl_TProfileImpl* pTmpProfile = 0;
628 #ifdef TRACE_OSL_PROFILE
629 OSL_TRACE("In osl_writeProfileString");
630 #endif
632 pTmpProfile = (osl_TProfileImpl*) Profile;
634 if ( pTmpProfile == 0 )
636 #ifdef TRACE_OSL_PROFILE
637 OSL_TRACE("Out osl_writeProfileString [pTmpProfile==0]");
638 #endif
639 return sal_False;
642 pthread_mutex_lock(&(pTmpProfile->m_AccessLock));
644 if ( pTmpProfile->m_bIsValid == sal_False )
646 OSL_ASSERT(pTmpProfile->m_bIsValid);
647 pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
648 #ifdef TRACE_OSL_PROFILE
649 OSL_TRACE("Out osl_writeProfileString [not valid]");
650 #endif
651 return sal_False;
654 pProfile=acquireProfile(Profile, sal_True);
656 if (pProfile == NULL)
658 pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
659 #ifdef TRACE_OSL_PROFILE
660 OSL_TRACE("Out osl_writeProfileString [pProfile==0]");
661 #endif
662 return (sal_False);
665 Line = (sal_Char*) malloc(strlen(pszEntry)+strlen(pszString)+48);
667 if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
669 if ((pSec = findEntry(pProfile, pszSection, pszEntry, &NoEntry)) == NULL)
671 Line[0] = '\0';
672 addLine(pProfile, Line);
674 Line[0] = '[';
675 strcpy(&Line[1], pszSection);
676 Line[1 + strlen(pszSection)] = ']';
677 Line[2 + strlen(pszSection)] = '\0';
679 if (((pStr = addLine(pProfile, Line)) == NULL) ||
680 (! addSection(pProfile, pProfile->m_NoLines - 1, &pStr[1], strlen(pszSection))))
682 bRet=releaseProfile(pProfile);
683 OSL_ASSERT(bRet);
685 pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
687 free(Line);
689 #ifdef TRACE_OSL_PROFILE
690 OSL_TRACE("Out osl_writeProfileString [not added]");
691 #endif
692 return (sal_False);
695 pSec = &pProfile->m_Sections[pProfile->m_NoSections - 1];
696 NoEntry = pSec->m_NoEntries;
699 Line[0] = '\0';
700 strcpy(&Line[0], pszEntry);
701 Line[0 + strlen(pszEntry)] = '=';
702 strcpy(&Line[1 + strlen(pszEntry)], pszString);
704 if (NoEntry >= pSec->m_NoEntries)
706 if (pSec->m_NoEntries > 0)
707 i = pSec->m_Entries[pSec->m_NoEntries - 1].m_Line + 1;
708 else
709 i = pSec->m_Line + 1;
711 if (((pStr = insertLine(pProfile, Line, i)) == NULL) ||
712 (! addEntry(pProfile, pSec, i, pStr, strlen(pszEntry))))
714 bRet=releaseProfile(pProfile);
715 OSL_ASSERT(bRet);
717 pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
718 free(Line);
720 #ifdef TRACE_OSL_PROFILE
721 OSL_TRACE("Out osl_writeProfileString [not inserted]");
722 #endif
723 return (sal_False);
726 pProfile->m_Flags |= FLG_MODIFIED;
728 else
730 i = pSec->m_Entries[NoEntry].m_Line;
731 free(pProfile->m_Lines[i]);
732 pProfile->m_Lines[i] = strdup(Line);
733 setEntry(pProfile, pSec, NoEntry, i, pProfile->m_Lines[i], strlen(pszEntry));
735 pProfile->m_Flags |= FLG_MODIFIED;
738 else {
739 /* not implemented */
742 bRet = releaseProfile(pProfile);
743 OSL_ASSERT(bRet);
745 pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
746 if ( Line!= 0 )
748 free(Line);
751 #ifdef TRACE_OSL_PROFILE
752 OSL_TRACE("Out osl_writeProfileString [ok]");
753 #endif
755 return bRet;
759 sal_Bool SAL_CALL osl_writeProfileBool(oslProfile Profile,
760 const sal_Char* pszSection, const sal_Char* pszEntry,
761 sal_Bool Value)
763 sal_Bool bRet=sal_False;
765 #ifdef TRACE_OSL_PROFILE
766 OSL_TRACE("In osl_writeProfileBool");
767 #endif
769 if (Value)
770 bRet=osl_writeProfileString(Profile, pszSection, pszEntry, STR_INI_BOOLONE);
771 else
772 bRet=osl_writeProfileString(Profile, pszSection, pszEntry, STR_INI_BOOLZERO);
774 #ifdef TRACE_OSL_PROFILE
775 OSL_TRACE("Out osl_writeProfileBool [ok]");
776 #endif
778 return bRet;
782 sal_Bool SAL_CALL osl_writeProfileIdent(oslProfile Profile,
783 const sal_Char* pszSection, const sal_Char* pszEntry,
784 sal_uInt32 FirstId, const sal_Char* Strings[],
785 sal_uInt32 Value)
787 int i, n = 0;
788 sal_Bool bRet=sal_False;
790 #ifdef TRACE_OSL_PROFILE
791 OSL_TRACE("In osl_writeProfileIdent");
792 #endif
794 while (Strings[n] != NULL)
795 ++n;
797 if ((i = Value - FirstId) >= n)
798 bRet = sal_False;
799 else
800 bRet = osl_writeProfileString(Profile, pszSection, pszEntry, Strings[i]);
802 #ifdef TRACE_OSL_PROFILE
803 OSL_TRACE("Out osl_writeProfileIdent");
804 #endif
805 return bRet;
809 sal_Bool SAL_CALL osl_removeProfileEntry(oslProfile Profile,
810 const sal_Char *pszSection, const sal_Char *pszEntry)
812 sal_uInt32 NoEntry;
813 osl_TProfileSection* pSec;
814 osl_TProfileImpl* pProfile = 0;
815 osl_TProfileImpl* pTmpProfile = 0;
816 sal_Bool bRet = sal_False;
818 #ifdef TRACE_OSL_PROFILE
819 OSL_TRACE("In osl_removeProfileEntry");
820 #endif
822 pTmpProfile = (osl_TProfileImpl*) Profile;
824 if ( pTmpProfile == 0 )
826 #ifdef TRACE_OSL_PROFILE
827 OSL_TRACE("Out osl_removeProfileEntry [pProfile==0]");
828 #endif
829 return sal_False;
832 pthread_mutex_lock(&(pTmpProfile->m_AccessLock));
834 if ( pTmpProfile->m_bIsValid == sal_False )
836 OSL_ASSERT(pTmpProfile->m_bIsValid);
837 pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
838 #ifdef TRACE_OSL_PROFILE
839 OSL_TRACE("Out osl_removeProfileEntry [not valid]");
840 #endif
841 return sal_False;
845 pProfile = acquireProfile(Profile, sal_True);
847 if (pProfile == NULL)
849 pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
850 #ifdef TRACE_OSL_PROFILE
851 OSL_TRACE("Out osl_removeProfileEntry [pProfile==0]");
852 #endif
853 return (sal_False);
857 if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
859 if (((pSec = findEntry(pProfile, pszSection, pszEntry, &NoEntry)) != NULL) &&
860 (NoEntry < pSec->m_NoEntries))
862 removeLine(pProfile, pSec->m_Entries[NoEntry].m_Line);
863 removeEntry(pSec, NoEntry);
864 if (pSec->m_NoEntries == 0)
866 removeLine(pProfile, pSec->m_Line);
868 /* remove any empty separation line */
869 if ((pSec->m_Line > 0) && (pProfile->m_Lines[pSec->m_Line - 1][0] == '\0'))
870 removeLine(pProfile, pSec->m_Line - 1);
872 removeSection(pProfile, pSec);
875 pProfile->m_Flags |= FLG_MODIFIED;
878 else
879 { /* not implemented */ }
882 bRet = releaseProfile(pProfile);
883 OSL_ASSERT(bRet);
885 pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
887 #ifdef TRACE_OSL_PROFILE
888 OSL_TRACE("Out osl_removeProfileEntry [ok]");
889 #endif
890 return bRet;
894 sal_uInt32 SAL_CALL osl_getProfileSectionEntries(oslProfile Profile, const sal_Char *pszSection,
895 sal_Char* pszBuffer, sal_uInt32 MaxLen)
897 sal_uInt32 i, n = 0;
898 sal_uInt32 NoEntry;
899 osl_TProfileSection* pSec;
900 osl_TProfileImpl* pProfile = 0;
901 osl_TProfileImpl* pTmpProfile = 0;
902 sal_Bool bRet = sal_False;
904 #ifdef TRACE_OSL_PROFILE
905 OSL_TRACE("In osl_getProfileSectionEntries");
906 #endif
908 pTmpProfile = (osl_TProfileImpl*) Profile;
910 if ( pTmpProfile == 0 )
912 #ifdef TRACE_OSL_PROFILE
913 OSL_TRACE("Out osl_getProfileSectionEntries [pTmpProfile==0]");
914 #endif
915 return sal_False;
919 pthread_mutex_lock(&(pTmpProfile->m_AccessLock));
921 if ( pTmpProfile->m_bIsValid == sal_False )
923 OSL_ASSERT(pTmpProfile->m_bIsValid);
925 pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
927 #ifdef TRACE_OSL_PROFILE
928 OSL_TRACE("Out osl_getProfileSectionEntries [not valid]");
929 #endif
931 return sal_False;
934 pProfile = acquireProfile(Profile, sal_False);
936 if (pProfile == NULL)
938 pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
940 #ifdef TRACE_OSL_PROFILE
941 OSL_TRACE("Out osl_getProfileSectionEntries [pProfile=0]");
942 #endif
944 return (0);
948 if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
950 if ((pSec = findEntry(pProfile, pszSection, "", &NoEntry)) != NULL)
952 if (MaxLen != 0)
954 for (i = 0; i < pSec->m_NoEntries; i++)
956 if ((n + pSec->m_Entries[i].m_Len + 1) < MaxLen)
958 strncpy(&pszBuffer[n], &pProfile->m_Lines[pSec->m_Entries[i].m_Line]
959 [pSec->m_Entries[i].m_Offset], pSec->m_Entries[i].m_Len);
960 n += pSec->m_Entries[i].m_Len;
961 pszBuffer[n++] = '\0';
963 else
964 break;
968 pszBuffer[n++] = '\0';
970 else
972 for (i = 0; i < pSec->m_NoEntries; i++)
973 n += pSec->m_Entries[i].m_Len + 1;
975 n += 1;
978 else
979 n = 0;
981 else {
982 /* not implemented */
985 bRet=releaseProfile(pProfile);
986 OSL_ASSERT(bRet);
987 (void)bRet;
989 pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
991 #ifdef TRACE_OSL_PROFILE
992 OSL_TRACE("Out osl_getProfileSectionEntries [ok]");
993 #endif
995 return (n);
998 sal_uInt32 SAL_CALL osl_getProfileSections(oslProfile Profile, sal_Char* pszBuffer, sal_uInt32 MaxLen)
1000 sal_uInt32 i, n = 0;
1001 osl_TProfileSection* pSec;
1002 osl_TProfileImpl* pProfile = 0;
1003 osl_TProfileImpl* pTmpProfile = 0;
1004 sal_Bool bRet = sal_False;
1006 #ifdef TRACE_OSL_PROFILE
1007 OSL_TRACE("In osl_getProfileSections");
1008 #endif
1010 pTmpProfile = (osl_TProfileImpl*) Profile;
1012 if ( pTmpProfile == 0 )
1014 #ifdef TRACE_OSL_PROFILE
1015 OSL_TRACE("Out osl_getProfileSections [pTmpProfile==0]");
1016 #endif
1017 return sal_False;
1020 pthread_mutex_lock(&(pTmpProfile->m_AccessLock));
1022 if ( pTmpProfile->m_bIsValid == sal_False )
1024 OSL_ASSERT(pTmpProfile->m_bIsValid);
1025 pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
1026 #ifdef TRACE_OSL_PROFILE
1027 OSL_TRACE("Out osl_getProfileSections [not valid]");
1028 #endif
1029 return sal_False;
1032 pProfile = acquireProfile(Profile, sal_False);
1034 if (pProfile == NULL)
1036 pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
1038 #ifdef TRACE_OSL_PROFILE
1039 OSL_TRACE("Out osl_getProfileSections [pProfile==0]");
1040 #endif
1041 return (0);
1044 if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
1046 if (MaxLen != 0)
1048 for (i = 0; i < pProfile->m_NoSections; i++)
1050 pSec = &pProfile->m_Sections[i];
1052 if ((n + pSec->m_Len + 1) < MaxLen)
1054 strncpy(&pszBuffer[n], &pProfile->m_Lines[pSec->m_Line][pSec->m_Offset],
1055 pSec->m_Len);
1056 n += pSec->m_Len;
1057 pszBuffer[n++] = '\0';
1059 else
1060 break;
1063 pszBuffer[n++] = '\0';
1065 else
1067 for (i = 0; i < pProfile->m_NoSections; i++)
1068 n += pProfile->m_Sections[i].m_Len + 1;
1070 n += 1;
1073 else
1074 { /* not implemented */ }
1077 bRet=releaseProfile(pProfile);
1078 OSL_ASSERT(bRet);
1079 (void)bRet;
1081 pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
1083 #ifdef TRACE_OSL_PROFILE
1084 OSL_TRACE("Out osl_getProfileSections [ok]");
1085 #endif
1087 return (n);
1090 /*****************************************************************************/
1091 /* Static Module Functions */
1092 /*****************************************************************************/
1094 static osl_TStamp OslProfile_getFileStamp(osl_TFile* pFile)
1096 struct stat status;
1098 if ( (pFile->m_Handle < 0) || (fstat(pFile->m_Handle, &status) < 0) )
1100 return (0);
1104 return (status.st_mtime);
1107 static sal_Bool OslProfile_lockFile(const osl_TFile* pFile, osl_TLockMode eMode)
1109 struct flock lock;
1110 /* boring hack, but initializers for static vars must be constant */
1111 static sal_Bool bIsInitialized = sal_False;
1112 static sal_Bool bLockingDisabled;
1114 #ifdef TRACE_OSL_PROFILE
1115 OSL_TRACE("In OslProfile_lockFile");
1116 #endif
1118 if ( !bIsInitialized )
1120 sal_Char* pEnvValue;
1121 pEnvValue = getenv( "STAR_PROFILE_LOCKING_DISABLED" );
1123 if ( pEnvValue == 0 )
1125 bLockingDisabled = sal_False;
1128 else
1130 bLockingDisabled = sal_True;
1133 bIsInitialized = sal_True;
1136 if (pFile->m_Handle < 0)
1138 #ifdef TRACE_OSL_PROFILE
1139 OSL_TRACE("Out OslProfile_lockFile [invalid file handle]");
1140 #endif
1141 return (sal_False);
1145 if ( bLockingDisabled )
1147 #ifdef TRACE_OSL_PROFILE
1148 OSL_TRACE("Out OslProfile_lockFile [locking disabled]");
1149 #endif
1150 return (sal_True);
1154 lock.l_start = 0;
1155 lock.l_whence = SEEK_SET;
1156 lock.l_len = 0;
1158 switch (eMode)
1160 case un_lock:
1161 lock.l_type = F_UNLCK;
1162 break;
1164 case read_lock:
1165 lock.l_type = F_RDLCK;
1166 break;
1168 case write_lock:
1169 lock.l_type = F_WRLCK;
1170 break;
1173 #ifndef MACOSX // not MAC OSX
1174 if ( fcntl(pFile->m_Handle, F_SETLKW, &lock) == -1 )
1175 #else
1176 /* Mac OSX will return ENOTSUP for webdav drives so we should ignore it */
1177 if ( fcntl(pFile->m_Handle, F_SETLKW, &lock) == -1 && errno != ENOTSUP )
1178 #endif /* MACOSX */
1180 OSL_TRACE("fcntl returned -1 (%s)",strerror(errno));
1181 #ifdef TRACE_OSL_PROFILE
1182 OSL_TRACE("Out OslProfile_lockFile [fcntl F_SETLKW]");
1183 #endif
1184 return sal_False;
1187 #ifdef TRACE_OSL_PROFILE
1188 OSL_TRACE("Out OslProfile_lockFile [ok]");
1189 #endif
1190 return sal_True;
1193 static osl_TFile* openFileImpl(const sal_Char* pszFilename, oslProfileOption ProfileFlags )
1195 int Flags;
1196 osl_TFile* pFile = (osl_TFile*) calloc(1, sizeof(osl_TFile));
1197 sal_Bool bWriteable = sal_False;
1199 if ( ProfileFlags & ( osl_Profile_WRITELOCK | osl_Profile_FLUSHWRITE ) )
1201 #ifdef DEBUG_OSL_PROFILE
1202 OSL_TRACE("setting bWriteable to TRUE");
1203 #endif
1204 bWriteable=sal_True;
1207 if (! bWriteable)
1209 #ifdef DEBUG_OSL_PROFILE
1210 OSL_TRACE("opening '%s' read only",pszFilename);
1211 #endif
1213 pFile->m_Handle = open(pszFilename, O_RDONLY);
1214 /* mfe: argghh!!! do not check if the file could be openend */
1215 /* default mode expects it that way!!! */
1217 else
1219 #ifdef DEBUG_OSL_PROFILE
1220 OSL_TRACE("opening '%s' read/write",pszFilename);
1221 #endif
1222 if (((pFile->m_Handle = open(pszFilename, O_RDWR | O_CREAT | O_EXCL, DEFAULT_PMODE)) < 0) &&
1223 ((pFile->m_Handle = open(pszFilename, O_RDWR)) < 0))
1225 free(pFile);
1226 #ifdef TRACE_OSL_PROFILE
1227 OSL_TRACE("Out openFileImpl [open read/write]");
1228 #endif
1229 return (NULL);
1233 /* set close-on-exec flag */
1234 if ((Flags = fcntl(pFile->m_Handle, F_GETFD, 0)) != -1)
1236 Flags |= FD_CLOEXEC;
1237 fcntl(pFile->m_Handle, F_SETFD, Flags);
1240 pFile->m_pWriteBuf=0;
1241 pFile->m_nWriteBufFree=0;
1242 pFile->m_nWriteBufLen=0;
1244 if ( ProfileFlags & (osl_Profile_WRITELOCK | osl_Profile_READLOCK ) )
1246 #ifdef DEBUG_OSL_PROFILE
1247 OSL_TRACE("locking '%s' file",pszFilename);
1248 #endif
1249 OslProfile_lockFile(pFile, bWriteable ? write_lock : read_lock);
1252 #ifdef TRACE_OSL_PROFILE
1253 OSL_TRACE("Out openFileImpl [ok]");
1254 #endif
1255 return (pFile);
1258 static osl_TStamp closeFileImpl(osl_TFile* pFile, oslProfileOption Flags)
1260 osl_TStamp stamp = 0;
1262 #ifdef TRACE_OSL_PROFILE
1263 OSL_TRACE("In closeFileImpl");
1264 #endif
1266 if ( pFile == 0 )
1268 #ifdef TRACE_OSL_PROFILE
1269 OSL_TRACE("Out closeFileImpl [pFile == 0]");
1270 #endif
1271 return stamp;
1274 if ( pFile->m_Handle >= 0 )
1276 stamp = OslProfile_getFileStamp(pFile);
1278 if ( Flags & (osl_Profile_WRITELOCK | osl_Profile_READLOCK ) )
1280 OslProfile_lockFile(pFile, un_lock);
1283 close(pFile->m_Handle);
1284 pFile->m_Handle = -1;
1288 if ( pFile->m_pWriteBuf )
1290 free(pFile->m_pWriteBuf);
1293 free(pFile);
1295 #ifdef TRACE_OSL_PROFILE
1296 OSL_TRACE("Out closeFileImpl [ok]");
1297 #endif
1299 return(stamp);
1302 static sal_Bool OslProfile_rewindFile(osl_TFile* pFile, sal_Bool bTruncate)
1304 sal_Bool bRet = sal_True;
1305 #ifdef TRACE_OSL_PROFILE
1306 OSL_TRACE("In osl_OslProfile_rewindFile");
1307 #endif
1309 if (pFile->m_Handle >= 0)
1311 pFile->m_pReadPtr = pFile->m_ReadBuf + sizeof(pFile->m_ReadBuf);
1313 #ifdef DEBUG_OSL_PROFILE
1314 OSL_TRACE("rewinding");
1315 #endif
1316 bRet = (lseek(pFile->m_Handle, SEEK_SET, 0L) == 0L);
1318 if (bTruncate)
1320 #ifdef DEBUG_OSL_PROFILE
1321 OSL_TRACE("truncating");
1322 #endif
1323 bRet &= (ftruncate(pFile->m_Handle, 0L) == 0);
1328 #ifdef TRACE_OSL_PROFILE
1329 OSL_TRACE("Out osl_OslProfile_rewindFile [ok]");
1330 #endif
1331 return bRet;
1335 static sal_Char* OslProfile_getLine(osl_TFile* pFile)
1337 int Max, Free, Bytes, nLineBytes = 0;
1338 sal_Char* pChr;
1339 sal_Char* pLine = NULL;
1340 sal_Char* pNewLine;
1342 if ( pFile == 0 )
1344 return 0;
1347 if (pFile->m_Handle < 0)
1348 return NULL;
1352 Bytes = sizeof(pFile->m_ReadBuf) - (pFile->m_pReadPtr - pFile->m_ReadBuf);
1354 if (Bytes <= 1)
1356 /* refill buffer */
1357 memcpy(pFile->m_ReadBuf, pFile->m_pReadPtr, Bytes);
1358 pFile->m_pReadPtr = pFile->m_ReadBuf;
1360 Free = sizeof(pFile->m_ReadBuf) - Bytes;
1362 if ((Max = read(pFile->m_Handle, &pFile->m_ReadBuf[Bytes], Free)) < 0)
1364 OSL_TRACE("read failed '%s'",strerror(errno));
1366 if( pLine )
1367 rtl_freeMemory( pLine );
1368 pLine = NULL;
1369 break;
1372 if (Max < Free)
1374 if ((Max == 0) && ! pLine)
1375 break;
1377 pFile->m_ReadBuf[Bytes + Max] = '\0';
1381 for (pChr = pFile->m_pReadPtr;
1382 (*pChr != '\n') && (*pChr != '\r') && (*pChr != '\0') &&
1383 (pChr < (pFile->m_ReadBuf + sizeof(pFile->m_ReadBuf) - 1));
1384 pChr++);
1386 Max = pChr - pFile->m_pReadPtr;
1387 pNewLine = (sal_Char*) rtl_allocateMemory( nLineBytes + Max + 1 );
1388 if( pLine )
1390 memcpy( pNewLine, pLine, nLineBytes );
1391 rtl_freeMemory( pLine );
1393 memcpy(pNewLine+nLineBytes, pFile->m_pReadPtr, Max);
1394 nLineBytes += Max;
1395 pNewLine[ nLineBytes ] = 0;
1396 pLine = pNewLine;
1398 if (pChr < (pFile->m_ReadBuf + sizeof(pFile->m_ReadBuf) - 1))
1400 if (*pChr != '\0')
1402 if ((pChr[0] == '\r') && (pChr[1] == '\n'))
1403 pChr += 2;
1404 else
1405 pChr += 1;
1408 if ((pChr < (pFile->m_ReadBuf + sizeof(pFile->m_ReadBuf))) &&
1409 (*pChr == '\0'))
1410 pChr = pFile->m_ReadBuf + sizeof(pFile->m_ReadBuf);
1412 /* setting Max to -1 indicates terminating read loop */
1413 Max = -1;
1416 pFile->m_pReadPtr = pChr;
1418 while (Max > 0);
1420 return pLine;
1423 static sal_Bool OslProfile_putLine(osl_TFile* pFile, const sal_Char *pszLine)
1425 unsigned int Len = strlen(pszLine);
1427 #ifdef DEBUG_OSL_PROFILE
1428 int strLen=0;
1429 #endif
1431 if ( pFile == 0 || pFile->m_Handle < 0 )
1433 return (sal_False);
1436 if ( pFile->m_pWriteBuf == 0 )
1438 pFile->m_pWriteBuf = (sal_Char*) malloc(Len+3);
1439 pFile->m_nWriteBufLen = Len+3;
1440 pFile->m_nWriteBufFree = Len+3;
1442 else
1444 if ( pFile->m_nWriteBufFree <= Len + 3 )
1446 sal_Char* pTmp;
1448 pTmp=(sal_Char*) realloc(pFile->m_pWriteBuf,( ( pFile->m_nWriteBufLen + Len ) * 2) );
1449 if ( pTmp == 0 )
1451 return sal_False;
1453 pFile->m_pWriteBuf = pTmp;
1454 pFile->m_nWriteBufFree = pFile->m_nWriteBufFree + pFile->m_nWriteBufLen + ( 2 * Len );
1455 pFile->m_nWriteBufLen = ( pFile->m_nWriteBufLen + Len ) * 2;
1456 memset( (pFile->m_pWriteBuf) + ( pFile->m_nWriteBufLen - pFile->m_nWriteBufFree ), 0, pFile->m_nWriteBufFree);
1462 memcpy(pFile->m_pWriteBuf + ( pFile->m_nWriteBufLen - pFile->m_nWriteBufFree ),pszLine,Len+1);
1463 #ifdef DEBUG_OSL_PROFILE
1464 strLen = strlen(pFile->m_pWriteBuf);
1465 #endif
1466 pFile->m_pWriteBuf[pFile->m_nWriteBufLen - pFile->m_nWriteBufFree + Len]='\n';
1467 pFile->m_pWriteBuf[pFile->m_nWriteBufLen - pFile->m_nWriteBufFree + Len + 1]='\0';
1469 pFile->m_nWriteBufFree-=Len+1;
1471 return sal_True;
1474 /* platform specific end */
1476 static sal_Char* stripBlanks(sal_Char* String, sal_uInt32* pLen)
1478 if ( ( pLen != NULL ) && ( *pLen != 0 ) )
1480 while ((String[*pLen - 1] == ' ') || (String[*pLen - 1] == '\t'))
1481 (*pLen)--;
1483 while ( (*String == ' ') || (*String == '\t') )
1485 String++;
1486 (*pLen)--;
1489 else
1490 while ( (*String == ' ') || (*String == '\t') )
1491 String++;
1493 return (String);
1496 static sal_Char* addLine(osl_TProfileImpl* pProfile, const sal_Char* Line)
1498 if (pProfile->m_NoLines >= pProfile->m_MaxLines)
1500 if (pProfile->m_Lines == NULL)
1502 pProfile->m_MaxLines = LINES_INI;
1503 pProfile->m_Lines = (sal_Char **)malloc(pProfile->m_MaxLines * sizeof(sal_Char *));
1504 memset(pProfile->m_Lines,0,pProfile->m_MaxLines * sizeof(sal_Char *));
1506 else
1508 unsigned int idx=0;
1509 unsigned int oldmax=pProfile->m_MaxLines;
1511 pProfile->m_MaxLines += LINES_ADD;
1512 pProfile->m_Lines = (sal_Char **)realloc(pProfile->m_Lines,
1513 pProfile->m_MaxLines * sizeof(sal_Char *));
1514 for ( idx = oldmax ; idx < pProfile->m_MaxLines ; ++idx )
1516 pProfile->m_Lines[idx]=0;
1520 if (pProfile->m_Lines == NULL)
1522 pProfile->m_NoLines = 0;
1523 pProfile->m_MaxLines = 0;
1524 return (NULL);
1529 if ( pProfile->m_Lines != 0 && pProfile->m_Lines[pProfile->m_NoLines] != 0 )
1531 free(pProfile->m_Lines[pProfile->m_NoLines]);
1533 pProfile->m_Lines[pProfile->m_NoLines++] = strdup(Line);
1535 return (pProfile->m_Lines[pProfile->m_NoLines - 1]);
1538 static sal_Char* insertLine(osl_TProfileImpl* pProfile, const sal_Char* Line, sal_uInt32 LineNo)
1540 if (pProfile->m_NoLines >= pProfile->m_MaxLines)
1542 if (pProfile->m_Lines == NULL)
1544 pProfile->m_MaxLines = LINES_INI;
1545 pProfile->m_Lines = (sal_Char **)malloc(pProfile->m_MaxLines * sizeof(sal_Char *));
1546 memset(pProfile->m_Lines,0,pProfile->m_MaxLines * sizeof(sal_Char *));
1548 else
1550 pProfile->m_MaxLines += LINES_ADD;
1551 pProfile->m_Lines = (sal_Char **)realloc(pProfile->m_Lines,
1552 pProfile->m_MaxLines * sizeof(sal_Char *));
1554 memset(&pProfile->m_Lines[pProfile->m_NoLines],
1556 (pProfile->m_MaxLines - pProfile->m_NoLines - 1) * sizeof(sal_Char*));
1559 if (pProfile->m_Lines == NULL)
1561 pProfile->m_NoLines = 0;
1562 pProfile->m_MaxLines = 0;
1563 return (NULL);
1567 LineNo = LineNo > pProfile->m_NoLines ? pProfile->m_NoLines : LineNo;
1569 if (LineNo < pProfile->m_NoLines)
1571 sal_uInt32 i, n;
1572 osl_TProfileSection* pSec;
1574 memmove(&pProfile->m_Lines[LineNo + 1], &pProfile->m_Lines[LineNo],
1575 (pProfile->m_NoLines - LineNo) * sizeof(sal_Char *));
1578 /* adjust line references */
1579 for (i = 0; i < pProfile->m_NoSections; i++)
1581 pSec = &pProfile->m_Sections[i];
1583 if (pSec->m_Line >= LineNo)
1584 pSec->m_Line++;
1586 for (n = 0; n < pSec->m_NoEntries; n++)
1587 if (pSec->m_Entries[n].m_Line >= LineNo)
1588 pSec->m_Entries[n].m_Line++;
1592 pProfile->m_NoLines++;
1594 pProfile->m_Lines[LineNo] = strdup(Line);
1596 return (pProfile->m_Lines[LineNo]);
1599 static void removeLine(osl_TProfileImpl* pProfile, sal_uInt32 LineNo)
1601 if (LineNo < pProfile->m_NoLines)
1603 free(pProfile->m_Lines[LineNo]);
1604 pProfile->m_Lines[LineNo]=0;
1605 if (pProfile->m_NoLines - LineNo > 1)
1607 sal_uInt32 i, n;
1608 osl_TProfileSection* pSec;
1610 memmove(&pProfile->m_Lines[LineNo], &pProfile->m_Lines[LineNo + 1],
1611 (pProfile->m_NoLines - LineNo - 1) * sizeof(sal_Char *));
1613 memset(&pProfile->m_Lines[pProfile->m_NoLines - 1],
1615 (pProfile->m_MaxLines - pProfile->m_NoLines) * sizeof(sal_Char*));
1617 /* adjust line references */
1618 for (i = 0; i < pProfile->m_NoSections; i++)
1620 pSec = &pProfile->m_Sections[i];
1622 if (pSec->m_Line > LineNo)
1623 pSec->m_Line--;
1625 for (n = 0; n < pSec->m_NoEntries; n++)
1626 if (pSec->m_Entries[n].m_Line > LineNo)
1627 pSec->m_Entries[n].m_Line--;
1630 else
1632 pProfile->m_Lines[LineNo] = 0;
1635 pProfile->m_NoLines--;
1638 return;
1641 static void setEntry(osl_TProfileImpl* pProfile, osl_TProfileSection* pSection,
1642 sal_uInt32 NoEntry, sal_uInt32 Line,
1643 sal_Char* Entry, sal_uInt32 Len)
1645 Entry = stripBlanks(Entry, &Len);
1646 pSection->m_Entries[NoEntry].m_Line = Line;
1647 pSection->m_Entries[NoEntry].m_Offset = Entry - pProfile->m_Lines[Line];
1648 pSection->m_Entries[NoEntry].m_Len = Len;
1650 return;
1653 static sal_Bool addEntry(osl_TProfileImpl* pProfile, osl_TProfileSection *pSection,
1654 int Line, sal_Char* Entry, sal_uInt32 Len)
1656 if (pSection != NULL)
1658 if (pSection->m_NoEntries >= pSection->m_MaxEntries)
1660 if (pSection->m_Entries == NULL)
1662 pSection->m_MaxEntries = ENTRIES_INI;
1663 pSection->m_Entries = (osl_TProfileEntry *)malloc(
1664 pSection->m_MaxEntries * sizeof(osl_TProfileEntry));
1666 else
1668 pSection->m_MaxEntries += ENTRIES_ADD;
1669 pSection->m_Entries = (osl_TProfileEntry *)realloc(pSection->m_Entries,
1670 pSection->m_MaxEntries * sizeof(osl_TProfileEntry));
1673 if (pSection->m_Entries == NULL)
1675 pSection->m_NoEntries = 0;
1676 pSection->m_MaxEntries = 0;
1677 return (sal_False);
1681 pSection->m_NoEntries++;
1683 Entry = stripBlanks(Entry, &Len);
1684 setEntry(pProfile, pSection, pSection->m_NoEntries - 1, Line,
1685 Entry, Len);
1687 return (sal_True);
1690 return (sal_False);
1693 static void removeEntry(osl_TProfileSection *pSection, sal_uInt32 NoEntry)
1695 if (NoEntry < pSection->m_NoEntries)
1697 if (pSection->m_NoEntries - NoEntry > 1)
1699 memmove(&pSection->m_Entries[NoEntry],
1700 &pSection->m_Entries[NoEntry + 1],
1701 (pSection->m_NoEntries - NoEntry - 1) * sizeof(osl_TProfileEntry));
1702 pSection->m_Entries[pSection->m_NoEntries - 1].m_Line=0;
1703 pSection->m_Entries[pSection->m_NoEntries - 1].m_Offset=0;
1704 pSection->m_Entries[pSection->m_NoEntries - 1].m_Len=0;
1707 pSection->m_NoEntries--;
1710 return;
1713 static sal_Bool addSection(osl_TProfileImpl* pProfile, int Line, const sal_Char* Section, sal_uInt32 Len)
1715 if (pProfile->m_NoSections >= pProfile->m_MaxSections)
1717 if (pProfile->m_Sections == NULL)
1719 pProfile->m_MaxSections = SECTIONS_INI;
1720 pProfile->m_Sections = (osl_TProfileSection *)malloc(pProfile->m_MaxSections * sizeof(osl_TProfileSection));
1721 memset(pProfile->m_Sections,0,pProfile->m_MaxSections * sizeof(osl_TProfileSection));
1723 else
1725 unsigned int idx=0;
1726 unsigned int oldmax=pProfile->m_MaxSections;
1728 pProfile->m_MaxSections += SECTIONS_ADD;
1729 pProfile->m_Sections = (osl_TProfileSection *)realloc(pProfile->m_Sections,
1730 pProfile->m_MaxSections * sizeof(osl_TProfileSection));
1731 for ( idx = oldmax ; idx < pProfile->m_MaxSections ; ++idx )
1733 pProfile->m_Sections[idx].m_Entries=0;
1737 if (pProfile->m_Sections == NULL)
1739 pProfile->m_NoSections = 0;
1740 pProfile->m_MaxSections = 0;
1741 return (sal_False);
1745 pProfile->m_NoSections++;
1747 if ( pProfile->m_Sections[(pProfile->m_NoSections) - 1].m_Entries != 0 )
1749 free(pProfile->m_Sections[(pProfile->m_NoSections) - 1].m_Entries);
1751 pProfile->m_Sections[pProfile->m_NoSections - 1].m_Entries = NULL;
1752 pProfile->m_Sections[pProfile->m_NoSections - 1].m_NoEntries = 0;
1753 pProfile->m_Sections[pProfile->m_NoSections - 1].m_MaxEntries = 0;
1755 pProfile->m_Sections[pProfile->m_NoSections - 1].m_Line = Line;
1756 pProfile->m_Sections[pProfile->m_NoSections - 1].m_Offset = Section - pProfile->m_Lines[Line];
1757 pProfile->m_Sections[pProfile->m_NoSections - 1].m_Len = Len;
1759 return (sal_True);
1762 static void removeSection(osl_TProfileImpl* pProfile, osl_TProfileSection *pSection)
1764 sal_uInt32 Section;
1766 if ((Section = pSection - pProfile->m_Sections) < pProfile->m_NoSections)
1768 free (pSection->m_Entries);
1769 pSection->m_Entries=0;
1770 if (pProfile->m_NoSections - Section > 1)
1772 memmove(&pProfile->m_Sections[Section], &pProfile->m_Sections[Section + 1],
1773 (pProfile->m_NoSections - Section - 1) * sizeof(osl_TProfileSection));
1775 memset(&pProfile->m_Sections[pProfile->m_NoSections - 1],
1777 (pProfile->m_MaxSections - pProfile->m_NoSections) * sizeof(osl_TProfileSection));
1778 pProfile->m_Sections[pProfile->m_NoSections - 1].m_Entries = 0;
1780 else
1782 pSection->m_Entries = 0;
1785 pProfile->m_NoSections--;
1788 return;
1791 static osl_TProfileSection* findEntry(osl_TProfileImpl* pProfile, const sal_Char* Section,
1792 const sal_Char* Entry, sal_uInt32 *pNoEntry)
1794 static sal_uInt32 Sect = 0;
1795 sal_uInt32 i, n;
1796 sal_uInt32 Len;
1797 const sal_Char* pStr;
1798 osl_TProfileSection* pSec=0;
1800 Len = strlen(Section);
1802 n = Sect;
1804 for (i = 0; i < pProfile->m_NoSections; i++)
1806 n %= pProfile->m_NoSections;
1807 pSec = &pProfile->m_Sections[n];
1808 if ((Len == pSec->m_Len) &&
1809 (strncasecmp(Section, &pProfile->m_Lines[pSec->m_Line][pSec->m_Offset], pSec->m_Len)
1810 == 0))
1811 break;
1812 n++;
1815 Sect = n;
1817 if (i < pProfile->m_NoSections)
1819 Len = strlen(Entry);
1821 *pNoEntry = pSec->m_NoEntries;
1823 for (i = 0; i < pSec->m_NoEntries; i++)
1825 pStr = &pProfile->m_Lines[pSec->m_Entries[i].m_Line]
1826 [pSec->m_Entries[i].m_Offset];
1827 if ((Len == pSec->m_Entries[i].m_Len) &&
1828 (strncasecmp(Entry, pStr, pSec->m_Entries[i].m_Len)
1829 == 0))
1831 *pNoEntry = i;
1832 break;
1836 else
1837 pSec = NULL;
1839 return (pSec);
1842 static sal_Bool loadProfile(osl_TFile* pFile, osl_TProfileImpl* pProfile)
1844 sal_uInt32 i;
1845 sal_Char* pStr;
1846 sal_Char* pChar;
1848 sal_Char* pLine;
1849 sal_Char* bWasAdded = NULL;
1852 if ( !pFile )
1854 return sal_False;
1857 if ( !pProfile )
1859 return sal_False;
1862 pProfile->m_NoLines = 0;
1863 pProfile->m_NoSections = 0;
1865 OSL_VERIFY(OslProfile_rewindFile(pFile, sal_False));
1867 while ( ( pLine=OslProfile_getLine(pFile) ) != 0 )
1869 bWasAdded = addLine( pProfile, pLine );
1870 rtl_freeMemory( pLine );
1871 OSL_ASSERT(bWasAdded);
1872 if ( ! bWasAdded )
1873 return (sal_False);
1876 for (i = 0; i < pProfile->m_NoLines; i++)
1878 pStr = (sal_Char *)stripBlanks(pProfile->m_Lines[i], NULL);
1880 if ((*pStr == '\0') || (*pStr == ';'))
1881 continue;
1883 if ((*pStr != '[') || ((pChar = strrchr(pStr, ']')) == NULL) ||
1884 ((pChar - pStr) <= 2))
1886 /* insert entry */
1888 if (pProfile->m_NoSections < 1)
1889 continue;
1891 if ((pChar = strchr(pStr, '=')) == NULL)
1892 pChar = pStr + strlen(pStr);
1894 if (! addEntry(pProfile, &pProfile->m_Sections[pProfile->m_NoSections - 1],
1895 i, pStr, pChar - pStr))
1897 OSL_ASSERT(0);
1898 continue;
1902 else
1904 /* new section */
1906 if (! addSection(pProfile, i, pStr + 1, pChar - pStr - 1))
1908 OSL_ASSERT(0);
1909 continue;
1915 return (sal_True);
1918 static sal_Bool storeProfile(osl_TProfileImpl* pProfile, sal_Bool bCleanup)
1920 #ifdef TRACE_OSL_PROFILE
1921 OSL_TRACE("In storeProfile");
1922 #endif
1924 if (pProfile->m_Lines != NULL)
1926 if (pProfile->m_Flags & FLG_MODIFIED)
1928 sal_uInt32 i;
1930 osl_TFile* pTmpFile = osl_openTmpProfileImpl(pProfile);
1932 if ( pTmpFile == 0 )
1934 return sal_False;
1937 OSL_VERIFY(OslProfile_rewindFile(pTmpFile, sal_True));
1939 for ( i = 0 ; i < pProfile->m_NoLines ; i++ )
1941 OSL_VERIFY(OslProfile_putLine(pTmpFile, pProfile->m_Lines[i]));
1944 if ( ! writeProfileImpl(pTmpFile) )
1946 if ( pTmpFile->m_pWriteBuf != 0 )
1948 free(pTmpFile->m_pWriteBuf);
1951 pTmpFile->m_pWriteBuf=0;
1952 pTmpFile->m_nWriteBufLen=0;
1953 pTmpFile->m_nWriteBufFree=0;
1955 #ifdef TRACE_OSL_PROFILE
1956 OSL_TRACE("Out storeProfile [not flushed]");
1957 #endif
1958 closeFileImpl(pTmpFile,pProfile->m_Flags);
1960 return sal_False;
1963 pProfile->m_Flags &= ~FLG_MODIFIED;
1965 closeFileImpl(pProfile->m_pFile,pProfile->m_Flags);
1966 closeFileImpl(pTmpFile,pProfile->m_Flags);
1968 osl_ProfileSwapProfileNames(pProfile);
1970 pProfile->m_pFile = openFileImpl(pProfile->m_FileName,pProfile->m_Flags);
1974 if (bCleanup)
1976 while (pProfile->m_NoLines > 0)
1977 removeLine(pProfile, pProfile->m_NoLines - 1);
1979 free(pProfile->m_Lines);
1980 pProfile->m_Lines = NULL;
1981 pProfile->m_NoLines = 0;
1982 pProfile->m_MaxLines = 0;
1984 while (pProfile->m_NoSections > 0)
1985 removeSection(pProfile, &pProfile->m_Sections[pProfile->m_NoSections - 1]);
1987 free(pProfile->m_Sections);
1988 pProfile->m_Sections = NULL;
1989 pProfile->m_NoSections = 0;
1990 pProfile->m_MaxSections = 0;
1994 #ifdef TRACE_OSL_PROFILE
1995 OSL_TRACE("Out storeProfile [ok]");
1996 #endif
1997 return (sal_True);
2001 static osl_TFile* osl_openTmpProfileImpl(osl_TProfileImpl* pProfile)
2003 osl_TFile* pFile=0;
2004 sal_Char* pszExtension = "tmp";
2005 sal_Char pszTmpName[PATH_MAX];
2006 oslProfileOption PFlags=0;
2008 pszTmpName[0] = '\0';
2010 /* generate tmp profilename */
2011 osl_ProfileGenerateExtension(pProfile->m_FileName,pszExtension,pszTmpName);
2013 if ( pszTmpName[0] == 0 )
2015 return 0;
2018 if ( ! ( pProfile->m_Flags & osl_Profile_READLOCK ) )
2020 PFlags |= osl_Profile_WRITELOCK;
2023 /* open this file */
2024 pFile = openFileImpl(pszTmpName,pProfile->m_Flags | PFlags);
2027 /* return new pFile */
2028 return pFile;
2031 static sal_Bool osl_ProfileSwapProfileNames(osl_TProfileImpl* pProfile)
2033 sal_Bool bRet = sal_False;
2035 sal_Char pszBakFile[PATH_MAX];
2036 sal_Char pszTmpFile[PATH_MAX];
2037 sal_Char pszIniFile[PATH_MAX];
2039 pszBakFile[0] = '\0';
2040 pszTmpFile[0] = '\0';
2041 pszIniFile[0] = '\0';
2043 osl_ProfileGenerateExtension(pProfile->m_FileName,"bak",pszBakFile);
2045 strcpy(pszIniFile,pProfile->m_FileName);
2047 osl_ProfileGenerateExtension(pProfile->m_FileName,"tmp",pszTmpFile);
2049 /* unlink bak */
2050 unlink( pszBakFile );
2052 /* rename ini bak */
2053 rename( pszIniFile, pszBakFile );
2055 /* rename tmp ini */
2056 rename( pszTmpFile, pszIniFile );
2058 return bRet;
2062 static void osl_ProfileGenerateExtension(sal_Char* pszFileName, sal_Char* pszExtension, sal_Char* pszTmpName)
2065 strcpy(pszTmpName,pszFileName);
2066 strcat(pszTmpName,".");
2067 strcat(pszTmpName,pszExtension);
2069 return;
2073 static osl_TProfileImpl* acquireProfile(oslProfile Profile, sal_Bool bWriteable)
2075 osl_TProfileImpl* pProfile = (osl_TProfileImpl*)Profile;
2076 oslProfileOption PFlags=0;
2078 if ( bWriteable )
2080 PFlags = osl_Profile_DEFAULT | osl_Profile_WRITELOCK;
2082 else
2084 PFlags = osl_Profile_DEFAULT;
2088 if (pProfile == NULL)
2090 #ifdef DEBUG_OSL_PROFILE
2091 OSL_TRACE("AUTOOPEN MODE");
2092 #endif
2094 if ( ( pProfile = (osl_TProfileImpl*) osl_openProfile(0, PFlags ) ) != NULL )
2096 pProfile->m_Flags |= FLG_AUTOOPEN;
2099 else
2101 #ifdef DEBUG_OSL_PROFILE
2102 OSL_TRACE("try to acquire");
2103 #endif
2105 if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
2107 if (! (pProfile->m_Flags & (osl_Profile_READLOCK | osl_Profile_WRITELOCK | osl_Profile_FLUSHWRITE )))
2109 osl_TStamp Stamp;
2111 #ifdef DEBUG_OSL_PROFILE
2112 OSL_TRACE("Profile acquire DEFAULT MODE");
2113 #endif
2114 if (! (pProfile->m_pFile = openFileImpl(pProfile->m_FileName, pProfile->m_Flags | PFlags )))
2115 return NULL;
2117 Stamp = OslProfile_getFileStamp(pProfile->m_pFile);
2119 if (memcmp(&Stamp, &(pProfile->m_Stamp), sizeof(osl_TStamp)))
2121 sal_Bool bRet=sal_False;
2123 pProfile->m_Stamp = Stamp;
2125 bRet=loadProfile(pProfile->m_pFile, pProfile);
2126 OSL_ASSERT(bRet);
2127 (void)bRet;
2130 else
2132 #ifdef DEBUG_OSL_PROFILE
2133 OSL_TRACE("Profile acquire READ/WRITELOCK MODE");
2134 #endif
2135 /* A readlock file could not be written */
2136 if ((pProfile->m_Flags & osl_Profile_READLOCK) && bWriteable)
2138 return (NULL);
2144 return (pProfile);
2147 static sal_Bool releaseProfile(osl_TProfileImpl* pProfile)
2149 #ifdef TRACE_OSL_PROFILE
2150 OSL_TRACE("In releaseProfile");
2151 #endif
2153 if ( pProfile == 0 )
2155 #ifdef TRACE_OSL_PROFILE
2156 OSL_TRACE("Out releaseProfile [profile==0]");
2157 #endif
2158 return sal_False;
2161 if (pProfile->m_Flags & FLG_AUTOOPEN)
2163 #ifdef TRACE_OSL_PROFILE
2164 OSL_TRACE("Out releaseProfile [AUTOOPEN]");
2165 #endif
2166 return (osl_closeProfile((oslProfile)pProfile));
2168 else
2170 #ifdef DEBUG_OSL_PROFILE
2171 OSL_TRACE("DEFAULT MODE");
2172 #endif
2173 if (! (pProfile->m_Flags & (osl_Profile_READLOCK | osl_Profile_WRITELOCK | osl_Profile_FLUSHWRITE )))
2175 if (pProfile->m_Flags & FLG_MODIFIED)
2177 sal_Bool bRet=storeProfile(pProfile, sal_False);
2178 OSL_ASSERT(bRet);
2179 (void)bRet;
2182 closeFileImpl(pProfile->m_pFile,pProfile->m_Flags);
2183 pProfile->m_pFile = NULL;
2187 #ifdef TRACE_OSL_PROFILE
2188 OSL_TRACE("Out releaseProfile [ok]");
2189 #endif
2190 return (sal_True);
2193 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */