xref: /trunk/main/sal/osl/unx/profile.c (revision 13e14e11)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 
25 #include "system.h"
26 
27 #include <osl/diagnose.h>
28 #include <osl/profile.h>
29 #include <osl/process.h>
30 #include <osl/thread.h>
31 #include <rtl/alloc.h>
32 #include <osl/util.h>
33 
34 #define LINES_INI       32
35 #define LINES_ADD       10
36 #define SECTIONS_INI    5
37 #define SECTIONS_ADD    3
38 #define ENTRIES_INI     5
39 #define ENTRIES_ADD     3
40 
41 
42 #define STR_INI_EXTENSION	"rc"
43 #define STR_INI_METAHOME	"?~"
44 #define STR_INI_METASYS		"?$"
45 #define STR_INI_METACFG		"?^"
46 #define STR_INI_METAINS		"?#"
47 
48 #define STR_INI_BOOLYES     "yes"
49 #define STR_INI_BOOLON      "on"
50 #define STR_INI_BOOLONE     "1"
51 #define STR_INI_BOOLNO      "no"
52 #define STR_INI_BOOLOFF     "off"
53 #define STR_INI_BOOLZERO    "0"
54 
55 #define FLG_USER			0x00FF
56 #define FLG_AUTOOPEN		0x0100
57 #define FLG_MODIFIED		0x0200
58 
59 #define SVERSION_LOCATION   STR_INI_METACFG
60 #define SVERSION_FALLBACK   STR_INI_METASYS
61 #define SVERSION_NAME   	"sversion"
62 #define SVERSION_SECTION    "Versions"
63 #define SVERSION_SOFFICE    "StarOffice"
64 #define SVERSION_PROFILE    "sofficerc"
65 #define SVERSION_OPTION     "userid:"
66 #define SVERSION_DIRS		{ "bin", "program" }
67 #define SVERSION_USER       "user"
68 
69 #define DEFAULT_PMODE 	(S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)
70 
71 #define _BUILD_STR_(n)	# n
72 #define BUILD_STR(n)	_BUILD_STR_(n)
73 
74 
75 /*#define DEBUG_OSL_PROFILE*/
76 /*#define TRACE_OSL_PROFILE*/
77 
78 /*****************************************************************************/
79 /* Data Type Definition */
80 /*****************************************************************************/
81 
82 typedef time_t  osl_TStamp;
83 
84 typedef enum _osl_TLockMode
85 {
86 	un_lock, read_lock, write_lock
87 } osl_TLockMode;
88 
89 typedef struct _osl_TFile
90 {
91 	int		m_Handle;
92 	sal_Char*	m_pReadPtr;
93 	sal_Char	m_ReadBuf[512];
94     sal_Char*   m_pWriteBuf;
95     sal_uInt32  m_nWriteBufLen;
96     sal_uInt32  m_nWriteBufFree;
97 } osl_TFile;
98 
99 typedef struct _osl_TProfileEntry
100 {
101     sal_uInt32	m_Line;
102     sal_uInt32  m_Offset;
103     sal_uInt32  m_Len;
104 } osl_TProfileEntry;
105 
106 typedef struct _osl_TProfileSection
107 {
108     sal_uInt32	m_Line;
109     sal_uInt32	m_Offset;
110     sal_uInt32	m_Len;
111     sal_uInt32	m_NoEntries;
112     sal_uInt32	m_MaxEntries;
113     osl_TProfileEntry*	m_Entries;
114 } osl_TProfileSection;
115 
116 
117 /*
118 	Profile-data structure hidden behind oslProfile:
119 */
120 typedef struct _osl_TProfileImpl
121 {
122 	sal_uInt32	m_Flags;
123 	osl_TFile*	m_pFile;
124 	osl_TStamp	m_Stamp;
125 	sal_Char    m_FileName[PATH_MAX + 1];
126 	sal_uInt32	m_NoLines;
127 	sal_uInt32  m_MaxLines;
128 	sal_uInt32  m_NoSections;
129 	sal_uInt32  m_MaxSections;
130 	sal_Char**	m_Lines;
131 	osl_TProfileSection* m_Sections;
132     pthread_mutex_t m_AccessLock;
133     sal_Bool    m_bIsValid;
134 } osl_TProfileImpl;
135 
136 
137 /*****************************************************************************/
138 /* Static Module Function Declarations */
139 /*****************************************************************************/
140 
141 static osl_TFile* openFileImpl(const sal_Char* pszFilename, oslProfileOption ProfileFlags);
142 static osl_TStamp closeFileImpl(osl_TFile* pFile, oslProfileOption Flags);
143 static sal_Bool   OslProfile_lockFile(const osl_TFile* pFile, osl_TLockMode eMode);
144 static sal_Bool   OslProfile_rewindFile(osl_TFile* pFile, sal_Bool bTruncate);
145 static osl_TStamp OslProfile_getFileStamp(osl_TFile* pFile);
146 
147 static sal_Char*   OslProfile_getLine(osl_TFile* pFile);
148 static sal_Bool   OslProfile_putLine(osl_TFile* pFile, const sal_Char *pszLine);
149 static sal_Char* stripBlanks(sal_Char* String, sal_uInt32* pLen);
150 static sal_Char* addLine(osl_TProfileImpl* pProfile, const sal_Char* Line);
151 static sal_Char* insertLine(osl_TProfileImpl* pProfile, const sal_Char* Line, sal_uInt32 LineNo);
152 static void removeLine(osl_TProfileImpl* pProfile, sal_uInt32 LineNo);
153 static void setEntry(osl_TProfileImpl* pProfile, osl_TProfileSection* pSection,
154                      sal_uInt32 NoEntry, sal_uInt32 Line,
155                      sal_Char* Entry, sal_uInt32 Len);
156 static sal_Bool addEntry(osl_TProfileImpl* pProfile, osl_TProfileSection *pSection,
157                          int Line, sal_Char* Entry, sal_uInt32 Len);
158 static void removeEntry(osl_TProfileSection *pSection, sal_uInt32 NoEntry);
159 static sal_Bool addSection(osl_TProfileImpl* pProfile, int Line, const sal_Char* Section, sal_uInt32 Len);
160 static void removeSection(osl_TProfileImpl* pProfile, osl_TProfileSection *pSection);
161 static osl_TProfileSection* findEntry(osl_TProfileImpl* pProfile, const sal_Char* Section,
162                                       const sal_Char* Entry, sal_uInt32 *pNoEntry);
163 static sal_Bool loadProfile(osl_TFile* pFile, osl_TProfileImpl* pProfile);
164 static sal_Bool storeProfile(osl_TProfileImpl* pProfile, sal_Bool bCleanup);
165 static osl_TProfileImpl* acquireProfile(oslProfile Profile, sal_Bool bWriteable);
166 static sal_Bool releaseProfile(osl_TProfileImpl* pProfile);
167 
168 static sal_Bool writeProfileImpl (osl_TFile* pFile);
169 static osl_TFile* osl_openTmpProfileImpl(osl_TProfileImpl*);
170 static sal_Bool osl_ProfileSwapProfileNames(osl_TProfileImpl*);
171 static void osl_ProfileGenerateExtension(sal_Char* pszFileName, sal_Char* pszExtension, sal_Char* pszTmpName);
172 static oslProfile SAL_CALL osl_psz_openProfile(const sal_Char *pszProfileName, oslProfileOption Flags);
173 
174 /* implemented in file.c */
175 extern oslFileError FileURLToPath( char *, size_t, rtl_uString* );
176 
177 /*****************************************************************************/
178 /* Exported Module Functions */
179 /*****************************************************************************/
osl_openProfile(rtl_uString * ustrProfileName,oslProfileOption Options)180 oslProfile SAL_CALL osl_openProfile(rtl_uString *ustrProfileName, oslProfileOption Options)
181 {
182     char profilePath[PATH_MAX] = "";
183 
184     if ( ustrProfileName != NULL  && ustrProfileName->buffer[0] != 0 )
185         FileURLToPath( profilePath, PATH_MAX, ustrProfileName );
186 
187     return osl_psz_openProfile( profilePath,Options );
188 }
189 
190 
osl_psz_openProfile(const sal_Char * pszProfileName,oslProfileOption Flags)191 static oslProfile SAL_CALL osl_psz_openProfile(const sal_Char *pszProfileName, oslProfileOption Flags)
192 {
193 	osl_TFile*		  pFile;
194 	osl_TProfileImpl* pProfile;
195 	sal_Char          Filename[PATH_MAX];
196     sal_Bool bRet = sal_False;
197 
198     Filename[0] = '\0';
199 
200 #ifdef TRACE_OSL_PROFILE
201     OSL_TRACE("In  osl_openProfile\n");
202 #endif
203 
204 #ifdef DEBUG_OSL_PROFILE
205     Flags=osl_Profile_FLUSHWRITE;
206 
207     OSL_TRACE("opening '%s'\n",pszProfileName);
208     if ( Flags == osl_Profile_DEFAULT )
209     {
210         OSL_TRACE("with osl_Profile_DEFAULT\n");
211     }
212     if ( Flags & osl_Profile_SYSTEM )
213     {
214         OSL_TRACE("with osl_Profile_SYSTEM\n");
215     }
216     if ( Flags & osl_Profile_READLOCK )
217     {
218         OSL_TRACE("with osl_Profile_READLOCK\n");
219     }
220     if ( Flags & osl_Profile_WRITELOCK )
221     {
222         OSL_TRACE("with osl_Profile_WRITELOCK\n");
223     }
224     if ( Flags & osl_Profile_FLUSHWRITE )
225     {
226         OSL_TRACE("with osl_Profile_FLUSHWRITE\n");
227     }
228 #endif
229 
230 
231 	if ( ( pFile = openFileImpl(pszProfileName, Flags ) ) == NULL )
232     {
233 #ifdef TRACE_OSL_PROFILE
234     OSL_TRACE("Out osl_openProfile [not opened]\n");
235 #endif
236 		return (NULL);
237     }
238 
239 
240 	pProfile = (osl_TProfileImpl*)calloc(1, sizeof(osl_TProfileImpl));
241 
242     if ( pProfile == NULL )
243     {
244         return 0;
245     }
246 
247 	pProfile->m_Flags = Flags & FLG_USER;
248 
249 	if ( Flags & ( osl_Profile_READLOCK | osl_Profile_WRITELOCK | osl_Profile_FLUSHWRITE ) )
250     {
251 		pProfile->m_pFile = pFile;
252     }
253 
254     pthread_mutex_init(&(pProfile->m_AccessLock),PTHREAD_MUTEXATTR_DEFAULT);
255     pProfile->m_bIsValid=sal_True;
256 
257 	pProfile->m_Stamp = OslProfile_getFileStamp(pFile);
258 	bRet=loadProfile(pFile, pProfile);
259     bRet &= realpath(pszProfileName, pProfile->m_FileName) != NULL;
260 	OSL_ASSERT(bRet);
261 
262 	if (pProfile->m_pFile == NULL)
263 		closeFileImpl(pFile,pProfile->m_Flags);
264 
265 #ifdef TRACE_OSL_PROFILE
266     OSL_TRACE("Out osl_openProfile [ok]\n");
267 #endif
268 	return (pProfile);
269 }
270 
osl_closeProfile(oslProfile Profile)271 sal_Bool SAL_CALL osl_closeProfile(oslProfile Profile)
272 {
273 	osl_TProfileImpl* pProfile = (osl_TProfileImpl*)Profile;
274     sal_Bool bRet = sal_False;
275 
276 #ifdef TRACE_OSL_PROFILE
277     OSL_TRACE("In  osl_closeProfile\n");
278 #endif
279 
280     if ( Profile == 0 )
281     {
282 #ifdef TRACE_OSL_PROFILE
283         OSL_TRACE("Out osl_closeProfile [profile==0]\n");
284 #endif
285         return sal_False;
286     }
287 
288     pthread_mutex_lock(&(pProfile->m_AccessLock));
289 
290     if ( pProfile->m_bIsValid == sal_False )
291     {
292         OSL_ASSERT(pProfile->m_bIsValid);
293         pthread_mutex_unlock(&(pProfile->m_AccessLock));
294 #ifdef TRACE_OSL_PROFILE
295         OSL_TRACE("Out osl_closeProfile [not valid]\n");
296 #endif
297         return sal_False;
298     }
299 
300     pProfile->m_bIsValid=sal_False;
301 
302 	if ( ! ( pProfile->m_Flags & osl_Profile_READLOCK ) && ( pProfile->m_Flags & FLG_MODIFIED ) )
303 	{
304         pProfile = acquireProfile(Profile,sal_True);
305 
306         if ( pProfile != NULL )
307         {
308 			bRet=storeProfile(pProfile, sal_True);
309             OSL_ASSERT(bRet);
310 		}
311 	}
312 	else
313 	{
314 		pProfile = acquireProfile(Profile,sal_False);
315 	}
316 
317 
318     if ( pProfile == NULL )
319     {
320 		pthread_mutex_unlock(&(pProfile->m_AccessLock));
321 #ifdef TRACE_OSL_PROFILE
322         OSL_TRACE("Out osl_closeProfile [pProfile==0]\n");
323 #endif
324         return sal_False;
325     }
326 
327     if (pProfile->m_pFile != NULL)
328         closeFileImpl(pProfile->m_pFile,pProfile->m_Flags);
329 
330     pProfile->m_pFile = NULL;
331     pProfile->m_FileName[0] = '\0';
332 
333 	/* release whole profile data types memory */
334 	if ( pProfile->m_NoLines > 0)
335 	{
336 		unsigned int idx=0;
337 		if ( pProfile->m_Lines != NULL )
338 		{
339 			for ( idx = 0 ; idx < pProfile->m_NoLines ; ++idx)
340 			{
341 				if ( pProfile->m_Lines[idx] != NULL )
342 				{
343 					free(pProfile->m_Lines[idx]);
344                     pProfile->m_Lines[idx]=NULL;
345 				}
346 			}
347 			free(pProfile->m_Lines);
348             pProfile->m_Lines=NULL;
349 		}
350 		if ( pProfile->m_Sections != NULL )
351 		{
352 			/*osl_TProfileSection* pSections=pProfile->m_Sections;*/
353 			for ( idx = 0 ; idx < pProfile->m_NoSections ; ++idx )
354 			{
355 				if ( pProfile->m_Sections[idx].m_Entries != NULL )
356 				{
357 					free(pProfile->m_Sections[idx].m_Entries);
358                     pProfile->m_Sections[idx].m_Entries=NULL;
359 				}
360 			}
361 			free(pProfile->m_Sections);
362             pProfile->m_Sections=NULL;
363 		}
364 	}
365 
366     pthread_mutex_unlock(&(pProfile->m_AccessLock));
367 
368     pthread_mutex_destroy(&(pProfile->m_AccessLock));
369 
370 	free(pProfile);
371 
372 #ifdef TRACE_OSL_PROFILE
373     OSL_TRACE("Out osl_closeProfile [ok]\n");
374 #endif
375 	return (sal_True);
376 }
377 
378 
osl_flushProfile(oslProfile Profile)379 sal_Bool SAL_CALL osl_flushProfile(oslProfile Profile)
380 {
381 	osl_TProfileImpl* pProfile = (osl_TProfileImpl*) Profile;
382 	osl_TFile* pFile;
383     sal_Bool bRet = sal_False;
384 
385 #ifdef TRACE_OSL_PROFILE
386     OSL_TRACE("In  osl_flushProfile()\n");
387 #endif
388 
389     if ( pProfile == NULL )
390     {
391 #ifdef TRACE_OSL_PROFILE
392         OSL_TRACE("Out osl_flushProfile() [pProfile == 0]\n");
393 #endif
394         return sal_False;
395     }
396 
397     pthread_mutex_lock(&(pProfile->m_AccessLock));
398 
399     if ( pProfile->m_bIsValid == sal_False )
400     {
401         OSL_ASSERT(pProfile->m_bIsValid);
402         pthread_mutex_unlock(&(pProfile->m_AccessLock));
403 #ifdef TRACE_OSL_PROFILE
404         OSL_TRACE("Out osl_flushProfile [not valid]\n");
405 #endif
406         return sal_False;
407     }
408 
409 	pFile = pProfile->m_pFile;
410     if ( !( pFile != NULL && pFile->m_Handle >= 0 ) )
411     {
412         pthread_mutex_unlock(&(pProfile->m_AccessLock));
413 #ifdef TRACE_OSL_PROFILE
414         OSL_TRACE("Out osl_flushProfile() [invalid file]\n");
415 #endif
416         return sal_False;
417     }
418 
419 	if ( pProfile->m_Flags & FLG_MODIFIED )
420 	{
421 #ifdef DEBUG_OSL_PROFILE
422         OSL_TRACE("swapping to storeprofile\n");
423 #endif
424 		bRet = storeProfile(pProfile,sal_False);
425         OSL_ASSERT(bRet);
426 	}
427 
428 #ifdef TRACE_OSL_PROFILE
429     OSL_TRACE("Out osl_flushProfile() [ok]\n");
430 #endif
431     pthread_mutex_unlock(&(pProfile->m_AccessLock));
432     return bRet;
433 }
434 
writeProfileImpl(osl_TFile * pFile)435 static sal_Bool writeProfileImpl(osl_TFile* pFile)
436 {
437 	int BytesWritten=0;
438 #if OSL_DEBUG_LEVEL > 1
439     unsigned int nLen=0;
440 #endif
441 
442 #ifdef TRACE_OSL_PROFILE
443     OSL_TRACE("In  osl_writeProfileImpl()\n");
444 #endif
445 
446     if ( !( pFile != NULL && pFile->m_Handle >= 0 ) || ( pFile->m_pWriteBuf == NULL ) )
447     {
448 #ifdef TRACE_OSL_PROFILE
449         OSL_TRACE("Out osl_writeProfileImpl() [invalid args]\n");
450 #endif
451         return sal_False;
452     }
453 
454 #if OSL_DEBUG_LEVEL > 1
455     nLen=strlen(pFile->m_pWriteBuf);
456 	OSL_ASSERT(nLen == (pFile->m_nWriteBufLen - pFile->m_nWriteBufFree));
457 #endif
458 
459     BytesWritten = write(pFile->m_Handle, pFile->m_pWriteBuf, pFile->m_nWriteBufLen - pFile->m_nWriteBufFree);
460 
461     if ( BytesWritten <= 0 )
462     {
463         OSL_TRACE("write failed '%s'\n",strerror(errno));
464         return (sal_False);
465     }
466 
467 #if OSL_DEBUG_LEVEL > 1
468     OSL_ASSERT(
469         BytesWritten >= 0 && SAL_INT_CAST(unsigned int, BytesWritten) == nLen);
470 #endif
471 
472     free(pFile->m_pWriteBuf);
473     pFile->m_pWriteBuf=NULL;
474 	pFile->m_nWriteBufLen=0;
475 	pFile->m_nWriteBufFree=0;
476 #ifdef TRACE_OSL_PROFILE
477     OSL_TRACE("Out osl_writeProfileImpl() [ok]\n");
478 #endif
479     return sal_True;
480 }
481 
482 
osl_readProfileString(oslProfile Profile,const sal_Char * pszSection,const sal_Char * pszEntry,sal_Char * pszString,sal_uInt32 MaxLen,const sal_Char * pszDefault)483 sal_Bool SAL_CALL osl_readProfileString(oslProfile Profile,
484                               const sal_Char* pszSection, const sal_Char* pszEntry,
485                               sal_Char* pszString, sal_uInt32 MaxLen,
486                               const sal_Char* pszDefault)
487 {
488     sal_uInt32    NoEntry;
489     sal_Char* pStr=NULL;
490     osl_TProfileSection* pSec;
491 	osl_TProfileImpl*    pProfile=NULL;
492 	osl_TProfileImpl*    pTmpProfile=NULL;
493     sal_Bool bRet = sal_False;
494 
495 #ifdef TRACE_OSL_PROFILE
496     OSL_TRACE("In  osl_readProfileString\n");
497 #endif
498 
499     pTmpProfile = (osl_TProfileImpl*) Profile;
500 
501     if ( pTmpProfile == NULL )
502     {
503 #ifdef TRACE_OSL_PROFILE
504         OSL_TRACE("Out osl_readProfileString [pTmpProfile==0]\n");
505 #endif
506         return sal_False;
507     }
508 
509     pthread_mutex_lock(&(pTmpProfile->m_AccessLock));
510 
511     if ( pTmpProfile->m_bIsValid == sal_False )
512     {
513         pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
514 #ifdef TRACE_OSL_PROFILE
515         OSL_TRACE("Out osl_readProfileString [not valid]\n");
516 #endif
517         return sal_False;
518     }
519 
520     pProfile = acquireProfile(Profile, sal_False);
521 
522     if ( pProfile == NULL )
523     {
524 #ifdef TRACE_OSL_PROFILE
525         OSL_TRACE("Out osl_readProfileString [pProfile==0]\n");
526 #endif
527         return (sal_False);
528     }
529 
530 	if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
531 	{
532         if (((pSec = findEntry(pProfile, pszSection, pszEntry, &NoEntry)) != NULL) &&
533             (NoEntry < pSec->m_NoEntries) &&
534             ((pStr = strchr(pProfile->m_Lines[pSec->m_Entries[NoEntry].m_Line],
535                             '=')) != NULL))
536         {
537             pStr++;
538         }
539         else
540         {
541             pStr=(sal_Char*)pszDefault;
542         }
543 
544         if ( pStr != NULL )
545         {
546             pStr = stripBlanks(pStr, NULL);
547             MaxLen = (MaxLen - 1 < strlen(pStr)) ? (MaxLen - 1) : strlen(pStr);
548             pStr = stripBlanks(pStr, &MaxLen);
549             strncpy(pszString, pStr, MaxLen);
550             pszString[MaxLen] = '\0';
551         }
552     }
553     else
554     { /* not implemented */ }
555 
556 
557     bRet=releaseProfile(pProfile);
558     OSL_ASSERT(bRet);
559 
560 	if ( pStr == NULL )
561     {
562         pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
563 #ifdef TRACE_OSL_PROFILE
564         OSL_TRACE("Out osl_readProfileString [pStr==0]\n");
565 #endif
566 		return sal_False;
567     }
568 
569     pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
570 
571 #ifdef TRACE_OSL_PROFILE
572     OSL_TRACE("Out osl_readProfileString [ok]\n");
573 #endif
574 
575     return (sal_True);
576 }
577 
578 
osl_readProfileBool(oslProfile Profile,const sal_Char * pszSection,const sal_Char * pszEntry,sal_Bool Default)579 sal_Bool SAL_CALL osl_readProfileBool(oslProfile Profile,
580                             const sal_Char* pszSection, const sal_Char* pszEntry,
581 							sal_Bool Default)
582 {
583 	sal_Char Line[32];
584     Line[0] = '\0';
585 
586 #ifdef TRACE_OSL_PROFILE
587     OSL_TRACE("In  osl_readProfileBool\n");
588 #endif
589 
590     if (osl_readProfileString(Profile, pszSection, pszEntry, Line, sizeof(Line), ""))
591     {
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;
601     }
602 
603 #ifdef TRACE_OSL_PROFILE
604     OSL_TRACE("Out osl_readProfileBool [ok]\n");
605 #endif
606 
607     return (Default);
608 }
609 
610 
osl_readProfileIdent(oslProfile Profile,const sal_Char * pszSection,const sal_Char * pszEntry,sal_uInt32 FirstId,const sal_Char * Strings[],sal_uInt32 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)
615 {
616     sal_uInt32	i;
617 	sal_Char    Line[256];
618     Line[0] = '\0';
619 
620 #ifdef TRACE_OSL_PROFILE
621     OSL_TRACE("In  osl_readProfileIdent\n");
622 #endif
623 
624     if (osl_readProfileString(Profile, pszSection, pszEntry, Line, sizeof(Line), ""))
625     {
626         i = 0;
627         while (Strings[i] != NULL)
628         {
629             if (strcasecmp(Line, Strings[i]) == 0)
630             {
631                 Default = i + FirstId;
632                 break;
633             }
634             i++;
635         }
636     }
637 
638 #ifdef TRACE_OSL_PROFILE
639     OSL_TRACE("Out osl_readProfileIdent [ok]\n");
640 #endif
641     return (Default);
642 }
643 
osl_writeProfileString(oslProfile Profile,const sal_Char * pszSection,const sal_Char * pszEntry,const sal_Char * pszString)644 sal_Bool SAL_CALL osl_writeProfileString(oslProfile Profile,
645                                const sal_Char* pszSection, const sal_Char* pszEntry,
646 							   const sal_Char* pszString)
647 {
648     sal_uInt32	i;
649     sal_Bool bRet = sal_False;
650     sal_uInt32    NoEntry;
651     sal_Char* pStr;
652 	sal_Char*		Line = NULL;
653     osl_TProfileSection* pSec;
654 	osl_TProfileImpl*    pProfile = NULL;
655 	osl_TProfileImpl*    pTmpProfile = NULL;
656 
657 #ifdef TRACE_OSL_PROFILE
658     OSL_TRACE("In  osl_writeProfileString\n");
659 #endif
660 
661     pTmpProfile = (osl_TProfileImpl*) Profile;
662 
663     if ( pTmpProfile == NULL )
664     {
665 #ifdef TRACE_OSL_PROFILE
666         OSL_TRACE("Out osl_writeProfileString [pTmpProfile==0]\n");
667 #endif
668         return sal_False;
669     }
670 
671     pthread_mutex_lock(&(pTmpProfile->m_AccessLock));
672 
673     if ( pTmpProfile->m_bIsValid == sal_False )
674     {
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]\n");
679 #endif
680         return sal_False;
681     }
682 
683     pProfile=acquireProfile(Profile, sal_True);
684 
685     if (pProfile == NULL)
686     {
687         pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
688 #ifdef TRACE_OSL_PROFILE
689         OSL_TRACE("Out osl_writeProfileString [pProfile==0]\n");
690 #endif
691         return (sal_False);
692     }
693 
694     Line = (sal_Char*)malloc(strlen(pszEntry)+strlen(pszString)+48);
695 
696 	if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
697 	{
698         if ((pSec = findEntry(pProfile, pszSection, pszEntry, &NoEntry)) == NULL)
699         {
700             Line[0] = '\0';
701             addLine(pProfile, Line);
702 
703             Line[0] = '[';
704             strcpy(&Line[1], pszSection);
705             Line[1 + strlen(pszSection)] = ']';
706             Line[2 + strlen(pszSection)] = '\0';
707 
708             if (((pStr = addLine(pProfile, Line)) == NULL) ||
709                 (! addSection(pProfile, pProfile->m_NoLines - 1, &pStr[1], strlen(pszSection))))
710             {
711                 bRet=releaseProfile(pProfile);
712                 OSL_ASSERT(bRet);
713 
714                 pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
715 
716                 free(Line);
717 
718 #ifdef TRACE_OSL_PROFILE
719                 OSL_TRACE("Out osl_writeProfileString [not added]\n");
720 #endif
721                 return (sal_False);
722             }
723 
724             pSec = &pProfile->m_Sections[pProfile->m_NoSections - 1];
725             NoEntry = pSec->m_NoEntries;
726         }
727 
728         Line[0] = '\0';
729         strcpy(&Line[0], pszEntry);
730         Line[0 + strlen(pszEntry)] = '=';
731         strcpy(&Line[1 + strlen(pszEntry)], pszString);
732 
733         if (NoEntry >= pSec->m_NoEntries)
734         {
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;
739 
740             if (((pStr = insertLine(pProfile, Line, i)) == NULL) ||
741                 (! addEntry(pProfile, pSec, i, pStr, strlen(pszEntry))))
742             {
743                 bRet=releaseProfile(pProfile);
744                 OSL_ASSERT(bRet);
745 
746                 pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
747                 free(Line);
748 
749 #ifdef TRACE_OSL_PROFILE
750                 OSL_TRACE("Out osl_writeProfileString [not inserted]\n");
751 #endif
752                 return (sal_False);
753             }
754 
755             pProfile->m_Flags |= FLG_MODIFIED;
756         }
757         else
758         {
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));
763 
764             pProfile->m_Flags |= FLG_MODIFIED;
765         }
766     }
767     else {
768         /* not implemented */
769     }
770 
771     bRet = releaseProfile(pProfile);
772     OSL_ASSERT(bRet);
773 
774     pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
775     if ( Line!= NULL )
776     {
777         free(Line);
778     }
779 
780 #ifdef TRACE_OSL_PROFILE
781     OSL_TRACE("Out osl_writeProfileString [ok]\n");
782 #endif
783 
784 	return bRet;
785 }
786 
787 
osl_writeProfileBool(oslProfile Profile,const sal_Char * pszSection,const sal_Char * pszEntry,sal_Bool Value)788 sal_Bool SAL_CALL osl_writeProfileBool(oslProfile Profile,
789                              const sal_Char* pszSection, const sal_Char* pszEntry,
790 							 sal_Bool Value)
791 {
792     sal_Bool bRet=sal_False;
793 
794 #ifdef TRACE_OSL_PROFILE
795     OSL_TRACE("In  osl_writeProfileBool\n");
796 #endif
797 
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);
802 
803 #ifdef TRACE_OSL_PROFILE
804     OSL_TRACE("Out osl_writeProfileBool [ok]\n");
805 #endif
806 
807     return bRet;
808 }
809 
810 
osl_writeProfileIdent(oslProfile Profile,const sal_Char * pszSection,const sal_Char * pszEntry,sal_uInt32 FirstId,const sal_Char * Strings[],sal_uInt32 Value)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)
815 {
816     int i, n;
817     sal_Bool bRet=sal_False;
818 
819 #ifdef TRACE_OSL_PROFILE
820     OSL_TRACE("In  osl_writeProfileIdent\n");
821 #endif
822 
823     for (n = 0; Strings[n] != NULL; n++);
824 
825     if ((i = Value - FirstId) >= n)
826         bRet=sal_False;
827     else
828         bRet = osl_writeProfileString(Profile, pszSection, pszEntry, Strings[i]);
829 
830 #ifdef TRACE_OSL_PROFILE
831     OSL_TRACE("Out osl_writeProfileIdent\n");
832 #endif
833     return bRet;
834 }
835 
836 
osl_removeProfileEntry(oslProfile Profile,const sal_Char * pszSection,const sal_Char * pszEntry)837 sal_Bool SAL_CALL osl_removeProfileEntry(oslProfile Profile,
838                                const sal_Char *pszSection, const sal_Char *pszEntry)
839 {
840     sal_uInt32    NoEntry;
841     osl_TProfileSection* pSec;
842 	osl_TProfileImpl*    pProfile = NULL;
843 	osl_TProfileImpl*    pTmpProfile = NULL;
844     sal_Bool bRet = sal_False;
845 
846 #ifdef TRACE_OSL_PROFILE
847     OSL_TRACE("In  osl_removeProfileEntry\n");
848 #endif
849 
850     pTmpProfile = (osl_TProfileImpl*) Profile;
851 
852     if ( pTmpProfile == NULL )
853     {
854 #ifdef TRACE_OSL_PROFILE
855         OSL_TRACE("Out osl_removeProfileEntry [pProfile==0]\n");
856 #endif
857         return sal_False;
858     }
859 
860     pthread_mutex_lock(&(pTmpProfile->m_AccessLock));
861 
862     if ( pTmpProfile->m_bIsValid == sal_False )
863     {
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]\n");
868 #endif
869         return sal_False;
870     }
871 
872 
873     pProfile = acquireProfile(Profile, sal_True);
874 
875     if (pProfile == NULL)
876     {
877         pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
878 #ifdef TRACE_OSL_PROFILE
879         OSL_TRACE("Out osl_removeProfileEntry [pProfile==0]\n");
880 #endif
881     	return (sal_False);
882     }
883 
884 
885 	if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
886 	{
887         if (((pSec = findEntry(pProfile, pszSection, pszEntry, &NoEntry)) != NULL) &&
888             (NoEntry < pSec->m_NoEntries))
889         {
890             removeLine(pProfile, pSec->m_Entries[NoEntry].m_Line);
891             removeEntry(pSec, NoEntry);
892             if (pSec->m_NoEntries == 0)
893             {
894                 removeLine(pProfile, pSec->m_Line);
895 
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);
899 
900                 removeSection(pProfile, pSec);
901             }
902 
903             pProfile->m_Flags |= FLG_MODIFIED;
904         }
905     }
906     else
907     { /* not implemented */ }
908 
909 
910     bRet = releaseProfile(pProfile);
911     OSL_ASSERT(bRet);
912 
913     pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
914 
915 #ifdef TRACE_OSL_PROFILE
916     OSL_TRACE("Out osl_removeProfileEntry [ok]\n");
917 #endif
918 	return bRet;
919 }
920 
921 
osl_getProfileSectionEntries(oslProfile Profile,const sal_Char * pszSection,sal_Char * pszBuffer,sal_uInt32 MaxLen)922 sal_uInt32 SAL_CALL osl_getProfileSectionEntries(oslProfile Profile, const sal_Char *pszSection,
923 									  sal_Char* pszBuffer, sal_uInt32 MaxLen)
924 {
925     sal_uInt32    i, n = 0;
926     sal_uInt32    NoEntry;
927     osl_TProfileSection* pSec;
928 	osl_TProfileImpl*    pProfile = NULL;
929 	osl_TProfileImpl*    pTmpProfile = NULL;
930     sal_Bool bRet = sal_False;
931 
932 #ifdef TRACE_OSL_PROFILE
933     OSL_TRACE("In  osl_getProfileSectionEntries\n");
934 #endif
935 
936     pTmpProfile = (osl_TProfileImpl*) Profile;
937 
938     if ( pTmpProfile == NULL )
939     {
940 #ifdef TRACE_OSL_PROFILE
941         OSL_TRACE("Out osl_getProfileSectionEntries [pTmpProfile==0]\n");
942 #endif
943         return sal_False;
944 
945     }
946 
947     pthread_mutex_lock(&(pTmpProfile->m_AccessLock));
948 
949     if ( pTmpProfile->m_bIsValid == sal_False )
950     {
951         OSL_ASSERT(pTmpProfile->m_bIsValid);
952 
953         pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
954 
955 #ifdef TRACE_OSL_PROFILE
956         OSL_TRACE("Out osl_getProfileSectionEntries [not valid]\n");
957 #endif
958 
959         return sal_False;
960     }
961 
962     pProfile = acquireProfile(Profile, sal_False);
963 
964     if (pProfile == NULL)
965     {
966         pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
967 
968 #ifdef TRACE_OSL_PROFILE
969         OSL_TRACE("Out osl_getProfileSectionEntries [pProfile=0]\n");
970 #endif
971 
972         return (0);
973     }
974 
975 
976 	if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
977 	{
978         if ((pSec = findEntry(pProfile, pszSection, "", &NoEntry)) != NULL)
979         {
980             if (MaxLen != 0)
981             {
982                 for (i = 0; i < pSec->m_NoEntries; i++)
983                 {
984                     if ((n + pSec->m_Entries[i].m_Len + 1) < MaxLen)
985                     {
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';
990                     }
991                     else
992                         break;
993 
994                 }
995 
996                 pszBuffer[n++] = '\0';
997             }
998             else
999             {
1000                 for (i = 0; i < pSec->m_NoEntries; i++)
1001                     n += pSec->m_Entries[i].m_Len + 1;
1002 
1003                 n += 1;
1004             }
1005         }
1006         else
1007             n = 0;
1008     }
1009     else {
1010         /* not implemented */
1011     }
1012 
1013 	bRet=releaseProfile(pProfile);
1014     OSL_ASSERT(bRet);
1015 
1016     pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
1017 
1018 #ifdef TRACE_OSL_PROFILE
1019     OSL_TRACE("Out osl_getProfileSectionEntries [ok]\n");
1020 #endif
1021 
1022     return (n);
1023 }
1024 
osl_getProfileSections(oslProfile Profile,sal_Char * pszBuffer,sal_uInt32 MaxLen)1025 sal_uInt32 SAL_CALL osl_getProfileSections(oslProfile Profile, sal_Char* pszBuffer, sal_uInt32 MaxLen)
1026 {
1027 	sal_uInt32    i, n = 0;
1028 	osl_TProfileSection* pSec;
1029 	osl_TProfileImpl*    pProfile = NULL;
1030 	osl_TProfileImpl*    pTmpProfile = NULL;
1031     sal_Bool bRet = sal_False;
1032 
1033 #ifdef TRACE_OSL_PROFILE
1034     OSL_TRACE("In  osl_getProfileSections\n");
1035 #endif
1036 
1037     pTmpProfile = (osl_TProfileImpl*) Profile;
1038 
1039     if ( pTmpProfile == NULL )
1040     {
1041 #ifdef TRACE_OSL_PROFILE
1042         OSL_TRACE("Out osl_getProfileSections [pTmpProfile==0]\n");
1043 #endif
1044         return sal_False;
1045     }
1046 
1047     pthread_mutex_lock(&(pTmpProfile->m_AccessLock));
1048 
1049     if ( pTmpProfile->m_bIsValid == sal_False )
1050     {
1051         OSL_ASSERT(pTmpProfile->m_bIsValid);
1052         pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
1053 #ifdef TRACE_OSL_PROFILE
1054         OSL_TRACE("Out osl_getProfileSections [not valid]\n");
1055 #endif
1056         return sal_False;
1057     }
1058 
1059     pProfile = acquireProfile(Profile, sal_False);
1060 
1061 	if (pProfile == NULL)
1062     {
1063         pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
1064 
1065 #ifdef TRACE_OSL_PROFILE
1066         OSL_TRACE("Out osl_getProfileSections [pProfile==0]\n");
1067 #endif
1068         return (0);
1069     }
1070 
1071 	if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
1072 	{
1073 		if (MaxLen != 0)
1074 		{
1075 			for (i = 0; i < pProfile->m_NoSections; i++)
1076 			{
1077 				pSec = &pProfile->m_Sections[i];
1078 
1079 				if ((n + pSec->m_Len + 1) < MaxLen)
1080 				{
1081 					strncpy(&pszBuffer[n], &pProfile->m_Lines[pSec->m_Line][pSec->m_Offset],
1082 						    pSec->m_Len);
1083 					n += pSec->m_Len;
1084 					pszBuffer[n++] = '\0';
1085 				}
1086 				else
1087 					break;
1088 			}
1089 
1090 			pszBuffer[n++] = '\0';
1091 		}
1092 		else
1093 		{
1094 			for (i = 0; i < pProfile->m_NoSections; i++)
1095 				n += pProfile->m_Sections[i].m_Len + 1;
1096 
1097 			n += 1;
1098 		}
1099 	}
1100 	else
1101 	{ /* not implemented */ }
1102 
1103 
1104     bRet=releaseProfile(pProfile);
1105     OSL_ASSERT(bRet);
1106 
1107     pthread_mutex_unlock(&(pTmpProfile->m_AccessLock));
1108 
1109 #ifdef TRACE_OSL_PROFILE
1110     OSL_TRACE("Out osl_getProfileSections [ok]\n");
1111 #endif
1112 
1113 	return (n);
1114 }
1115 
1116 /*****************************************************************************/
1117 /* Static Module Functions */
1118 /*****************************************************************************/
1119 
OslProfile_getFileStamp(osl_TFile * pFile)1120 static osl_TStamp OslProfile_getFileStamp(osl_TFile* pFile)
1121 {
1122 	struct stat status;
1123 
1124 	if ( (pFile->m_Handle < 0) || (fstat(pFile->m_Handle, &status) < 0) )
1125     {
1126 		return (0);
1127     }
1128 
1129 
1130 	return (status.st_mtime);
1131 }
1132 
OslProfile_lockFile(const osl_TFile * pFile,osl_TLockMode eMode)1133 static sal_Bool OslProfile_lockFile(const osl_TFile* pFile, osl_TLockMode eMode)
1134 {
1135 	struct flock lock;
1136 	/* boring hack, but initializers for static vars must be constant */
1137 	static sal_Bool bIsInitialized = sal_False;
1138 	static sal_Bool bLockingDisabled;
1139 
1140 #ifdef TRACE_OSL_PROFILE
1141     OSL_TRACE("In  OslProfile_lockFile\n");
1142 #endif
1143 
1144     if ( !bIsInitialized )
1145 	{
1146         sal_Char* pEnvValue;
1147         pEnvValue = getenv( "STAR_PROFILE_LOCKING_DISABLED" );
1148 
1149         if ( pEnvValue == NULL )
1150         {
1151             bLockingDisabled = sal_False;
1152 
1153         }
1154         else
1155         {
1156             bLockingDisabled = sal_True;
1157         }
1158 
1159         bIsInitialized = sal_True;
1160 	}
1161 
1162 	if (pFile->m_Handle < 0)
1163     {
1164 #ifdef TRACE_OSL_PROFILE
1165         OSL_TRACE("Out OslProfile_lockFile [invalid file handle]\n");
1166 #endif
1167 		return (sal_False);
1168     }
1169 
1170 
1171 	if ( bLockingDisabled )
1172     {
1173 #ifdef TRACE_OSL_PROFILE
1174         OSL_TRACE("Out OslProfile_lockFile [locking disabled]\n");
1175 #endif
1176 		return (sal_True);
1177     }
1178 
1179 
1180 	lock.l_start  = 0;
1181 	lock.l_whence = SEEK_SET;
1182 	lock.l_len    = 0;
1183 
1184 	switch (eMode)
1185 	{
1186 		case un_lock:
1187 			lock.l_type = F_UNLCK;
1188 			break;
1189 
1190 		case read_lock:
1191 			lock.l_type = F_RDLCK;
1192 			break;
1193 
1194 		case write_lock:
1195 			lock.l_type = F_WRLCK;
1196 			break;
1197 	}
1198 
1199 #ifndef MACOSX // not MAC OSX
1200      if ( fcntl(pFile->m_Handle, F_SETLKW, &lock) == -1 )
1201 #else
1202     /* Mac OSX will return ENOTSUP for webdav drives so we should ignore it */
1203     if ( fcntl(pFile->m_Handle, F_SETLKW, &lock) == -1 && errno != ENOTSUP )
1204 #endif  /* MACOSX */
1205     {
1206         OSL_TRACE("fcntl returned -1 (%s)\n",strerror(errno));
1207 #ifdef TRACE_OSL_PROFILE
1208         OSL_TRACE("Out OslProfile_lockFile [fcntl F_SETLKW]\n");
1209 #endif
1210         return sal_False;
1211     }
1212 
1213 #ifdef TRACE_OSL_PROFILE
1214     OSL_TRACE("Out OslProfile_lockFile [ok]\n");
1215 #endif
1216 	return sal_True;
1217 }
1218 
openFileImpl(const sal_Char * pszFilename,oslProfileOption ProfileFlags)1219 static osl_TFile* openFileImpl(const sal_Char* pszFilename, oslProfileOption ProfileFlags )
1220 {
1221 	int        Flags;
1222 	osl_TFile* pFile = (osl_TFile*)calloc(1, sizeof(osl_TFile));
1223     sal_Bool bWriteable = sal_False;
1224 
1225     if ( ProfileFlags & ( osl_Profile_WRITELOCK | osl_Profile_FLUSHWRITE ) )
1226     {
1227 #ifdef DEBUG_OSL_PROFILE
1228         OSL_TRACE("setting bWriteable to TRUE\n");
1229 #endif
1230         bWriteable=sal_True;
1231     }
1232 
1233 	if (! bWriteable)
1234     {
1235 #ifdef DEBUG_OSL_PROFILE
1236         OSL_TRACE("opening '%s' read only\n",pszFilename);
1237 #endif
1238 
1239         pFile->m_Handle = open(pszFilename, O_RDONLY);
1240         /* mfe: argghh!!! do not check if the file could be openend */
1241         /*      default mode expects it that way!!!                 */
1242     }
1243 	else
1244     {
1245 #ifdef DEBUG_OSL_PROFILE
1246         OSL_TRACE("opening '%s' read/write\n",pszFilename);
1247 #endif
1248 		if (((pFile->m_Handle = open(pszFilename, O_RDWR | O_CREAT | O_EXCL, DEFAULT_PMODE)) < 0) &&
1249 			((pFile->m_Handle = open(pszFilename, O_RDWR)) < 0))
1250 		{
1251 			free(pFile);
1252 #ifdef TRACE_OSL_PROFILE
1253             OSL_TRACE("Out openFileImpl [open read/write]\n");
1254 #endif
1255 			return (NULL);
1256 		}
1257     }
1258 
1259 	/* set close-on-exec flag */
1260 	if ((Flags = fcntl(pFile->m_Handle, F_GETFD, 0)) != -1)
1261 	{
1262 		Flags |= FD_CLOEXEC;
1263 		fcntl(pFile->m_Handle, F_SETFD, Flags);
1264 	}
1265 
1266     pFile->m_pWriteBuf=NULL;
1267     pFile->m_nWriteBufFree=0;
1268     pFile->m_nWriteBufLen=0;
1269 
1270     if ( ProfileFlags & (osl_Profile_WRITELOCK | osl_Profile_READLOCK ) )
1271     {
1272 #ifdef DEBUG_OSL_PROFILE
1273         OSL_TRACE("locking '%s' file\n",pszFilename);
1274 #endif
1275         OslProfile_lockFile(pFile, bWriteable ? write_lock : read_lock);
1276     }
1277 
1278 #ifdef TRACE_OSL_PROFILE
1279     OSL_TRACE("Out openFileImpl [ok]\n");
1280 #endif
1281 	return (pFile);
1282 }
1283 
closeFileImpl(osl_TFile * pFile,oslProfileOption Flags)1284 static osl_TStamp closeFileImpl(osl_TFile* pFile, oslProfileOption Flags)
1285 {
1286 	osl_TStamp stamp = 0;
1287 
1288 #ifdef TRACE_OSL_PROFILE
1289     OSL_TRACE("In  closeFileImpl\n");
1290 #endif
1291 
1292     if ( pFile == NULL )
1293     {
1294 #ifdef TRACE_OSL_PROFILE
1295         OSL_TRACE("Out closeFileImpl [pFile == 0]\n");
1296 #endif
1297         return stamp;
1298     }
1299 
1300 	if ( pFile->m_Handle >= 0 )
1301 	{
1302 		stamp = OslProfile_getFileStamp(pFile);
1303 
1304         if ( Flags & (osl_Profile_WRITELOCK | osl_Profile_WRITELOCK ) )
1305         {
1306             OslProfile_lockFile(pFile, un_lock);
1307         }
1308 
1309 		close(pFile->m_Handle);
1310         pFile->m_Handle = -1;
1311 	}
1312 
1313 
1314     if ( pFile->m_pWriteBuf )
1315     {
1316         free(pFile->m_pWriteBuf);
1317     }
1318 
1319 	free(pFile);
1320 
1321 #ifdef TRACE_OSL_PROFILE
1322     OSL_TRACE("Out closeFileImpl [ok]\n");
1323 #endif
1324 
1325 	return(stamp);
1326 }
1327 
OslProfile_rewindFile(osl_TFile * pFile,sal_Bool bTruncate)1328 static sal_Bool OslProfile_rewindFile(osl_TFile* pFile, sal_Bool bTruncate)
1329 {
1330     sal_Bool bRet = sal_True;
1331 #ifdef TRACE_OSL_PROFILE
1332     OSL_TRACE("In  osl_OslProfile_rewindFile\n");
1333 #endif
1334 
1335     if (pFile->m_Handle >= 0)
1336 	{
1337 		pFile->m_pReadPtr  = pFile->m_ReadBuf + sizeof(pFile->m_ReadBuf);
1338 
1339 #ifdef DEBUG_OSL_PROFILE
1340         OSL_TRACE("rewinding\n");
1341 #endif
1342 		bRet = (lseek(pFile->m_Handle, SEEK_SET, 0L) == 0L);
1343 
1344 		if (bTruncate)
1345         {
1346 #ifdef DEBUG_OSL_PROFILE
1347             OSL_TRACE("truncating\n");
1348 #endif
1349 			bRet &= (ftruncate(pFile->m_Handle, 0L) == 0);
1350         }
1351 
1352 	}
1353 
1354 #ifdef TRACE_OSL_PROFILE
1355     OSL_TRACE("Out osl_OslProfile_rewindFile [ok]\n");
1356 #endif
1357 	return bRet;
1358 }
1359 
1360 
OslProfile_getLine(osl_TFile * pFile)1361 static sal_Char* OslProfile_getLine(osl_TFile* pFile)
1362 {
1363 	int   Max, Free, Bytes, nLineBytes = 0;
1364 	sal_Char* pChr;
1365 	sal_Char* pLine = NULL;
1366 	sal_Char* pNewLine;
1367 
1368 	if ( pFile == NULL )
1369 	{
1370 		return 0;
1371 	}
1372 
1373 	if (pFile->m_Handle < 0)
1374 		return NULL;
1375 
1376 	do
1377 	{
1378 		Bytes = sizeof(pFile->m_ReadBuf) - (pFile->m_pReadPtr - pFile->m_ReadBuf);
1379 
1380 		if (Bytes <= 1)
1381 		{
1382 			/* refill buffer */
1383 			memcpy(pFile->m_ReadBuf, pFile->m_pReadPtr, Bytes);
1384 			pFile->m_pReadPtr = pFile->m_ReadBuf;
1385 
1386 			Free = sizeof(pFile->m_ReadBuf) - Bytes;
1387 
1388 			if ((Max = read(pFile->m_Handle, &pFile->m_ReadBuf[Bytes], Free)) < 0)
1389 			{
1390                 OSL_TRACE("read failed '%s'\n",strerror(errno));
1391 
1392 				if( pLine )
1393 					rtl_freeMemory( pLine );
1394 				pLine = NULL;
1395 				break;
1396 			}
1397 
1398 			if (Max < Free)
1399 			{
1400  				if ((Max == 0) && ! pLine)
1401  					break;
1402 
1403 			 	pFile->m_ReadBuf[Bytes + Max] = '\0';
1404 			}
1405 		}
1406 
1407 		for (pChr = pFile->m_pReadPtr;
1408 		     (*pChr != '\n') && (*pChr != '\r') && (*pChr != '\0') &&
1409 		     (pChr < (pFile->m_ReadBuf + sizeof(pFile->m_ReadBuf) - 1));
1410 			 pChr++);
1411 
1412 		Max = pChr - pFile->m_pReadPtr;
1413 		pNewLine = (sal_Char*) rtl_allocateMemory( nLineBytes + Max + 1 );
1414 		if( pLine )
1415 		{
1416 			memcpy( pNewLine, pLine, nLineBytes );
1417 			rtl_freeMemory( pLine );
1418 		}
1419 		memcpy(pNewLine+nLineBytes, pFile->m_pReadPtr, Max);
1420 		nLineBytes += Max;
1421 		pNewLine[ nLineBytes ] = 0;
1422 		pLine = pNewLine;
1423 
1424 		if (pChr < (pFile->m_ReadBuf + sizeof(pFile->m_ReadBuf) - 1))
1425 		{
1426 			if (*pChr != '\0')
1427 			{
1428 				if ((pChr[0] == '\r') && (pChr[1] == '\n'))
1429 					pChr += 2;
1430 				else
1431 					pChr += 1;
1432 			}
1433 
1434 			if ((pChr < (pFile->m_ReadBuf + sizeof(pFile->m_ReadBuf))) &&
1435 			    (*pChr == '\0'))
1436 				pChr = pFile->m_ReadBuf + sizeof(pFile->m_ReadBuf);
1437 
1438 			/* setting Max to -1 indicates terminating read loop */
1439 			Max = -1;
1440 		}
1441 
1442 		pFile->m_pReadPtr = pChr;
1443 	}
1444 	while (Max > 0);
1445 
1446 	return pLine;
1447 }
1448 
OslProfile_putLine(osl_TFile * pFile,const sal_Char * pszLine)1449 static sal_Bool OslProfile_putLine(osl_TFile* pFile, const sal_Char *pszLine)
1450 {
1451 	unsigned int Len = strlen(pszLine);
1452 
1453 #ifdef DEBUG_OSL_PROFILE
1454 	int strLen=0;
1455 #endif
1456 
1457 	if ( pFile == NULL || pFile->m_Handle < 0 )
1458     {
1459 		return (sal_False);
1460     }
1461 
1462     if ( pFile->m_pWriteBuf == NULL )
1463     {
1464         pFile->m_pWriteBuf = (sal_Char*)malloc(Len+3);
1465         pFile->m_nWriteBufLen = Len+3;
1466 		pFile->m_nWriteBufFree = Len+3;
1467     }
1468     else
1469     {
1470         if ( pFile->m_nWriteBufFree <= Len + 3 )
1471         {
1472             sal_Char* pTmp;
1473 
1474             pTmp = (sal_Char*)realloc(pFile->m_pWriteBuf,( ( pFile->m_nWriteBufLen + Len ) * 2) );
1475             if ( pTmp == NULL )
1476             {
1477                 return sal_False;
1478             }
1479             pFile->m_pWriteBuf = pTmp;
1480             pFile->m_nWriteBufFree = pFile->m_nWriteBufFree + pFile->m_nWriteBufLen + ( 2 * Len );
1481             pFile->m_nWriteBufLen = ( pFile->m_nWriteBufLen + Len ) * 2;
1482             memset( (pFile->m_pWriteBuf) + ( pFile->m_nWriteBufLen - pFile->m_nWriteBufFree ), 0, pFile->m_nWriteBufFree);
1483         }
1484     }
1485 
1486 
1487 
1488     memcpy(pFile->m_pWriteBuf + ( pFile->m_nWriteBufLen - pFile->m_nWriteBufFree ),pszLine,Len+1);
1489 #ifdef DEBUG_OSL_PROFILE
1490 	strLen = strlen(pFile->m_pWriteBuf);
1491 #endif
1492     pFile->m_pWriteBuf[pFile->m_nWriteBufLen - pFile->m_nWriteBufFree + Len]='\n';
1493     pFile->m_pWriteBuf[pFile->m_nWriteBufLen - pFile->m_nWriteBufFree + Len + 1]='\0';
1494 
1495     pFile->m_nWriteBufFree-=Len+1;
1496 
1497 	return sal_True;
1498 }
1499 
1500 /* platform specific end */
1501 
stripBlanks(sal_Char * String,sal_uInt32 * pLen)1502 static sal_Char* stripBlanks(sal_Char* String, sal_uInt32* pLen)
1503 {
1504     if ( ( pLen != NULL ) && ( *pLen != 0 ) )
1505     {
1506         while ((String[*pLen - 1] == ' ') || (String[*pLen - 1] == '\t'))
1507             (*pLen)--;
1508 
1509         while ( (*String == ' ') || (*String == '\t') )
1510         {
1511             String++;
1512             (*pLen)--;
1513         }
1514     }
1515     else
1516         while ( (*String == ' ') || (*String == '\t') )
1517             String++;
1518 
1519     return (String);
1520 }
1521 
addLine(osl_TProfileImpl * pProfile,const sal_Char * Line)1522 static sal_Char* addLine(osl_TProfileImpl* pProfile, const sal_Char* Line)
1523 {
1524     if (pProfile->m_NoLines >= pProfile->m_MaxLines)
1525     {
1526         if (pProfile->m_Lines == NULL)
1527         {
1528             pProfile->m_MaxLines = LINES_INI;
1529             pProfile->m_Lines = (sal_Char **)calloc(pProfile->m_MaxLines, sizeof(sal_Char *));
1530         }
1531         else
1532         {
1533 			unsigned int idx=0;
1534 			unsigned int oldmax=pProfile->m_MaxLines;
1535 
1536             pProfile->m_MaxLines += LINES_ADD;
1537             pProfile->m_Lines = (sal_Char **)realloc(pProfile->m_Lines,
1538 				                                 pProfile->m_MaxLines * sizeof(sal_Char *));
1539 			for ( idx = oldmax ; idx < pProfile->m_MaxLines ; ++idx )
1540 			{
1541 				pProfile->m_Lines[idx]=NULL;
1542 			}
1543         }
1544 
1545         if (pProfile->m_Lines == NULL)
1546         {
1547             pProfile->m_NoLines  = 0;
1548             pProfile->m_MaxLines = 0;
1549             return (NULL);
1550         }
1551 
1552     }
1553 
1554 	if ( pProfile->m_Lines != NULL && pProfile->m_Lines[pProfile->m_NoLines] != NULL )
1555 	{
1556         free(pProfile->m_Lines[pProfile->m_NoLines]);
1557 	}
1558     pProfile->m_Lines[pProfile->m_NoLines++] = strdup(Line);
1559 
1560     return (pProfile->m_Lines[pProfile->m_NoLines - 1]);
1561 }
1562 
insertLine(osl_TProfileImpl * pProfile,const sal_Char * Line,sal_uInt32 LineNo)1563 static sal_Char* insertLine(osl_TProfileImpl* pProfile, const sal_Char* Line, sal_uInt32 LineNo)
1564 {
1565     if (pProfile->m_NoLines >= pProfile->m_MaxLines)
1566     {
1567         if (pProfile->m_Lines == NULL)
1568         {
1569             pProfile->m_MaxLines = LINES_INI;
1570             pProfile->m_Lines = (sal_Char **)calloc(pProfile->m_MaxLines, sizeof(sal_Char *));
1571         }
1572         else
1573         {
1574             pProfile->m_MaxLines += LINES_ADD;
1575             pProfile->m_Lines = (sal_Char **)realloc(pProfile->m_Lines,
1576 				                                 pProfile->m_MaxLines * sizeof(sal_Char *));
1577 
1578             memset(&pProfile->m_Lines[pProfile->m_NoLines],
1579 				0,
1580 				(pProfile->m_MaxLines - pProfile->m_NoLines - 1) * sizeof(sal_Char*));
1581         }
1582 
1583         if (pProfile->m_Lines == NULL)
1584         {
1585             pProfile->m_NoLines  = 0;
1586             pProfile->m_MaxLines = 0;
1587             return (NULL);
1588         }
1589     }
1590 
1591 	LineNo = LineNo > pProfile->m_NoLines ? pProfile->m_NoLines : LineNo;
1592 
1593 	if (LineNo < pProfile->m_NoLines)
1594 	{
1595 		sal_uInt32 i, n;
1596         osl_TProfileSection* pSec;
1597 
1598 		memmove(&pProfile->m_Lines[LineNo + 1], &pProfile->m_Lines[LineNo],
1599 				(pProfile->m_NoLines - LineNo) * sizeof(sal_Char *));
1600 
1601 
1602 		/* adjust line references */
1603 		for (i = 0; i < pProfile->m_NoSections; i++)
1604 		{
1605 			pSec = &pProfile->m_Sections[i];
1606 
1607 			if (pSec->m_Line >= LineNo)
1608 				pSec->m_Line++;
1609 
1610 			for (n = 0; n < pSec->m_NoEntries; n++)
1611 				if (pSec->m_Entries[n].m_Line >= LineNo)
1612 					pSec->m_Entries[n].m_Line++;
1613 		}
1614 	}
1615 
1616 	pProfile->m_NoLines++;
1617 
1618 	pProfile->m_Lines[LineNo] = strdup(Line);
1619 
1620     return (pProfile->m_Lines[LineNo]);
1621 }
1622 
removeLine(osl_TProfileImpl * pProfile,sal_uInt32 LineNo)1623 static void removeLine(osl_TProfileImpl* pProfile, sal_uInt32 LineNo)
1624 {
1625     if (LineNo < pProfile->m_NoLines)
1626     {
1627         free(pProfile->m_Lines[LineNo]);
1628         pProfile->m_Lines[LineNo]=NULL;
1629         if (pProfile->m_NoLines - LineNo > 1)
1630 		{
1631 			sal_uInt32 i, n;
1632 			osl_TProfileSection* pSec;
1633 
1634             memmove(&pProfile->m_Lines[LineNo], &pProfile->m_Lines[LineNo + 1],
1635                     (pProfile->m_NoLines - LineNo - 1) * sizeof(sal_Char *));
1636 
1637 			memset(&pProfile->m_Lines[pProfile->m_NoLines - 1],
1638 				0,
1639 				(pProfile->m_MaxLines - pProfile->m_NoLines) * sizeof(sal_Char*));
1640 
1641 			/* adjust line references */
1642 			for (i = 0; i < pProfile->m_NoSections; i++)
1643 			{
1644 				pSec = &pProfile->m_Sections[i];
1645 
1646 				if (pSec->m_Line > LineNo)
1647 					pSec->m_Line--;
1648 
1649 				for (n = 0; n < pSec->m_NoEntries; n++)
1650 					if (pSec->m_Entries[n].m_Line > LineNo)
1651 						pSec->m_Entries[n].m_Line--;
1652 			}
1653 		}
1654 		else
1655 		{
1656 			pProfile->m_Lines[LineNo] = NULL;
1657 		}
1658 
1659         pProfile->m_NoLines--;
1660     }
1661 
1662     return;
1663 }
1664 
setEntry(osl_TProfileImpl * pProfile,osl_TProfileSection * pSection,sal_uInt32 NoEntry,sal_uInt32 Line,sal_Char * Entry,sal_uInt32 Len)1665 static void setEntry(osl_TProfileImpl* pProfile, osl_TProfileSection* pSection,
1666                      sal_uInt32 NoEntry, sal_uInt32 Line,
1667                      sal_Char* Entry, sal_uInt32 Len)
1668 {
1669     Entry = stripBlanks(Entry, &Len);
1670     pSection->m_Entries[NoEntry].m_Line   = Line;
1671     pSection->m_Entries[NoEntry].m_Offset = Entry - pProfile->m_Lines[Line];
1672     pSection->m_Entries[NoEntry].m_Len    = Len;
1673 
1674     return;
1675 }
1676 
addEntry(osl_TProfileImpl * pProfile,osl_TProfileSection * pSection,int Line,sal_Char * Entry,sal_uInt32 Len)1677 static sal_Bool addEntry(osl_TProfileImpl* pProfile, osl_TProfileSection *pSection,
1678                          int Line, sal_Char* Entry, sal_uInt32 Len)
1679 {
1680     if (pSection != NULL)
1681     {
1682         if (pSection->m_NoEntries >= pSection->m_MaxEntries)
1683         {
1684             if (pSection->m_Entries == NULL)
1685             {
1686                 pSection->m_MaxEntries = ENTRIES_INI;
1687                 pSection->m_Entries = (osl_TProfileEntry *)malloc(
1688                                 pSection->m_MaxEntries * sizeof(osl_TProfileEntry));
1689             }
1690             else
1691             {
1692                 pSection->m_MaxEntries += ENTRIES_ADD;
1693                 pSection->m_Entries = (osl_TProfileEntry *)realloc(pSection->m_Entries,
1694                                 pSection->m_MaxEntries * sizeof(osl_TProfileEntry));
1695             }
1696 
1697             if (pSection->m_Entries == NULL)
1698             {
1699                 pSection->m_NoEntries  = 0;
1700                 pSection->m_MaxEntries = 0;
1701                 return (sal_False);
1702             }
1703         }
1704 
1705         pSection->m_NoEntries++;
1706 
1707         Entry = stripBlanks(Entry, &Len);
1708         setEntry(pProfile, pSection, pSection->m_NoEntries - 1, Line,
1709                  Entry, Len);
1710 
1711         return (sal_True);
1712     }
1713 
1714     return (sal_False);
1715 }
1716 
removeEntry(osl_TProfileSection * pSection,sal_uInt32 NoEntry)1717 static void removeEntry(osl_TProfileSection *pSection, sal_uInt32 NoEntry)
1718 {
1719     if (NoEntry < pSection->m_NoEntries)
1720     {
1721         if (pSection->m_NoEntries - NoEntry > 1)
1722         {
1723             memmove(&pSection->m_Entries[NoEntry],
1724                     &pSection->m_Entries[NoEntry + 1],
1725                     (pSection->m_NoEntries - NoEntry - 1) * sizeof(osl_TProfileEntry));
1726 			pSection->m_Entries[pSection->m_NoEntries - 1].m_Line=0;
1727 			pSection->m_Entries[pSection->m_NoEntries - 1].m_Offset=0;
1728 			pSection->m_Entries[pSection->m_NoEntries - 1].m_Len=0;
1729         }
1730 
1731         pSection->m_NoEntries--;
1732     }
1733 
1734     return;
1735 }
1736 
addSection(osl_TProfileImpl * pProfile,int Line,const sal_Char * Section,sal_uInt32 Len)1737 static sal_Bool addSection(osl_TProfileImpl* pProfile, int Line, const sal_Char* Section, sal_uInt32 Len)
1738 {
1739     if (pProfile->m_NoSections >= pProfile->m_MaxSections)
1740     {
1741         if (pProfile->m_Sections == NULL)
1742         {
1743             pProfile->m_MaxSections = SECTIONS_INI;
1744             pProfile->m_Sections = (osl_TProfileSection *)calloc(pProfile->m_MaxSections, sizeof(osl_TProfileSection));
1745         }
1746         else
1747         {
1748 			unsigned int idx=0;
1749 			unsigned int oldmax=pProfile->m_MaxSections;
1750 
1751             pProfile->m_MaxSections += SECTIONS_ADD;
1752             pProfile->m_Sections = (osl_TProfileSection *)realloc(pProfile->m_Sections,
1753                                           pProfile->m_MaxSections * sizeof(osl_TProfileSection));
1754 			for ( idx = oldmax ; idx < pProfile->m_MaxSections ; ++idx )
1755 			{
1756 				pProfile->m_Sections[idx].m_Entries=NULL;
1757 			}
1758         }
1759 
1760         if (pProfile->m_Sections == NULL)
1761         {
1762             pProfile->m_NoSections = 0;
1763             pProfile->m_MaxSections = 0;
1764             return (sal_False);
1765         }
1766     }
1767 
1768     pProfile->m_NoSections++;
1769 
1770 	if ( pProfile->m_Sections[(pProfile->m_NoSections) - 1].m_Entries != NULL )
1771 	{
1772  		free(pProfile->m_Sections[(pProfile->m_NoSections) - 1].m_Entries);
1773     }
1774     pProfile->m_Sections[pProfile->m_NoSections - 1].m_Entries    = NULL;
1775     pProfile->m_Sections[pProfile->m_NoSections - 1].m_NoEntries  = 0;
1776     pProfile->m_Sections[pProfile->m_NoSections - 1].m_MaxEntries = 0;
1777 
1778     pProfile->m_Sections[pProfile->m_NoSections - 1].m_Line = Line;
1779     pProfile->m_Sections[pProfile->m_NoSections - 1].m_Offset = Section - pProfile->m_Lines[Line];
1780     pProfile->m_Sections[pProfile->m_NoSections - 1].m_Len = Len;
1781 
1782     return (sal_True);
1783 }
1784 
removeSection(osl_TProfileImpl * pProfile,osl_TProfileSection * pSection)1785 static void removeSection(osl_TProfileImpl* pProfile, osl_TProfileSection *pSection)
1786 {
1787     sal_uInt32 Section;
1788 
1789     if ((Section = pSection - pProfile->m_Sections) < pProfile->m_NoSections)
1790     {
1791         free (pSection->m_Entries);
1792 		pSection->m_Entries=NULL;
1793         if (pProfile->m_NoSections - Section > 1)
1794         {
1795             memmove(&pProfile->m_Sections[Section], &pProfile->m_Sections[Section + 1],
1796                     (pProfile->m_NoSections - Section - 1) * sizeof(osl_TProfileSection));
1797 
1798             memset(&pProfile->m_Sections[pProfile->m_NoSections - 1],
1799                    0,
1800                    (pProfile->m_MaxSections - pProfile->m_NoSections) * sizeof(osl_TProfileSection));
1801 			pProfile->m_Sections[pProfile->m_NoSections - 1].m_Entries = NULL;
1802         }
1803 		else
1804 		{
1805 			pSection->m_Entries = NULL;
1806 		}
1807 
1808         pProfile->m_NoSections--;
1809     }
1810 
1811     return;
1812 }
1813 
findEntry(osl_TProfileImpl * pProfile,const sal_Char * Section,const sal_Char * Entry,sal_uInt32 * pNoEntry)1814 static osl_TProfileSection* findEntry(osl_TProfileImpl* pProfile, const sal_Char* Section,
1815                                       const sal_Char* Entry, sal_uInt32 *pNoEntry)
1816 {
1817 static  sal_uInt32    Sect = 0;
1818         sal_uInt32    i, n;
1819         sal_uInt32	Len;
1820         const sal_Char*	pStr;
1821         osl_TProfileSection* pSec=NULL;
1822 
1823     Len = strlen(Section);
1824 
1825 	n = Sect;
1826 
1827     for (i = 0; i < pProfile->m_NoSections; i++)
1828     {
1829 		n %= pProfile->m_NoSections;
1830         pSec = &pProfile->m_Sections[n];
1831         if ((Len == pSec->m_Len) &&
1832             (strncasecmp(Section, &pProfile->m_Lines[pSec->m_Line][pSec->m_Offset], pSec->m_Len)
1833              == 0))
1834             break;
1835         n++;
1836     }
1837 
1838 	Sect = n;
1839 
1840     if (i < pProfile->m_NoSections)
1841     {
1842         Len = strlen(Entry);
1843 
1844         *pNoEntry = pSec->m_NoEntries;
1845 
1846         for (i = 0; i < pSec->m_NoEntries; i++)
1847         {
1848             pStr = &pProfile->m_Lines[pSec->m_Entries[i].m_Line]
1849                                      [pSec->m_Entries[i].m_Offset];
1850             if ((Len == pSec->m_Entries[i].m_Len) &&
1851                 (strncasecmp(Entry, pStr, pSec->m_Entries[i].m_Len)
1852                  == 0))
1853             {
1854                 *pNoEntry = i;
1855                 break;
1856             }
1857         }
1858     }
1859     else
1860         pSec = NULL;
1861 
1862     return (pSec);
1863 }
1864 
loadProfile(osl_TFile * pFile,osl_TProfileImpl * pProfile)1865 static sal_Bool loadProfile(osl_TFile* pFile, osl_TProfileImpl* pProfile)
1866 {
1867     sal_uInt32	i;
1868     sal_Char*		pStr;
1869 	sal_Char*		pChar;
1870 
1871 	sal_Char* pLine;
1872 	sal_Char* bWasAdded = NULL;
1873 
1874     pProfile->m_NoLines    = 0;
1875     pProfile->m_NoSections = 0;
1876 
1877 	if ( pFile == NULL )
1878 	{
1879 		return sal_False;
1880 	}
1881 
1882 	if ( pProfile == NULL )
1883 	{
1884 		return sal_False;
1885 	}
1886 
1887 	OSL_VERIFY(OslProfile_rewindFile(pFile, sal_False));
1888 
1889     while ( ( pLine=OslProfile_getLine(pFile) ) != NULL )
1890     {
1891 		bWasAdded = addLine( pProfile, pLine );
1892 		rtl_freeMemory( pLine );
1893         OSL_ASSERT(bWasAdded);
1894         if ( ! bWasAdded )
1895 			return (sal_False);
1896     }
1897 
1898     for (i = 0; i < pProfile->m_NoLines; i++)
1899     {
1900         pStr = (sal_Char *)stripBlanks(pProfile->m_Lines[i], NULL);
1901 
1902         if ((*pStr == '\0') || (*pStr == ';'))
1903             continue;
1904 
1905         if ((*pStr != '[') || ((pChar = strrchr(pStr, ']')) == NULL) ||
1906             ((pChar - pStr) <= 2))
1907         {
1908             /* insert entry */
1909 
1910             if (pProfile->m_NoSections < 1)
1911                 continue;
1912 
1913             if ((pChar = strchr(pStr, '=')) == NULL)
1914                 pChar = pStr + strlen(pStr);
1915 
1916             if (! addEntry(pProfile, &pProfile->m_Sections[pProfile->m_NoSections - 1],
1917 				           i, pStr, pChar - pStr))
1918             {
1919                 OSL_ASSERT(0);
1920                 continue;
1921             }
1922 
1923         }
1924         else
1925         {
1926             /* new section */
1927 
1928             if (! addSection(pProfile, i, pStr + 1, pChar - pStr - 1))
1929             {
1930                 OSL_ASSERT(0);
1931                 continue;
1932             }
1933 
1934         }
1935     }
1936 
1937     return (sal_True);
1938 }
1939 
storeProfile(osl_TProfileImpl * pProfile,sal_Bool bCleanup)1940 static sal_Bool storeProfile(osl_TProfileImpl* pProfile, sal_Bool bCleanup)
1941 {
1942 #ifdef TRACE_OSL_PROFILE
1943     OSL_TRACE("In  storeProfile\n");
1944 #endif
1945 
1946 	if (pProfile->m_Lines != NULL)
1947     {
1948         if (pProfile->m_Flags & FLG_MODIFIED)
1949         {
1950 		    sal_uInt32 i;
1951 
1952 			osl_TFile* pTmpFile = osl_openTmpProfileImpl(pProfile);
1953 
1954 			if ( pTmpFile == NULL )
1955 			{
1956 				return sal_False;
1957 			}
1958 
1959 			OSL_VERIFY(OslProfile_rewindFile(pTmpFile, sal_True));
1960 
1961 			for ( i = 0 ; i < pProfile->m_NoLines ; i++ )
1962             {
1963 				OSL_VERIFY(OslProfile_putLine(pTmpFile, pProfile->m_Lines[i]));
1964             }
1965 
1966 			if ( ! writeProfileImpl(pTmpFile) )
1967             {
1968 				if ( pTmpFile->m_pWriteBuf != NULL )
1969 				{
1970 					free(pTmpFile->m_pWriteBuf);
1971 				}
1972 
1973 				pTmpFile->m_pWriteBuf=NULL;
1974 				pTmpFile->m_nWriteBufLen=0;
1975 				pTmpFile->m_nWriteBufFree=0;
1976 
1977 #ifdef TRACE_OSL_PROFILE
1978                 OSL_TRACE("Out storeProfile [not flushed]\n");
1979 #endif
1980 				closeFileImpl(pTmpFile,pProfile->m_Flags);
1981 
1982                 return sal_False;
1983             }
1984 
1985 	        pProfile->m_Flags &= ~FLG_MODIFIED;
1986 
1987             closeFileImpl(pProfile->m_pFile,pProfile->m_Flags);
1988 			closeFileImpl(pTmpFile,pProfile->m_Flags);
1989 
1990 			osl_ProfileSwapProfileNames(pProfile);
1991 
1992 			pProfile->m_pFile = openFileImpl(pProfile->m_FileName,pProfile->m_Flags);
1993 
1994         }
1995 
1996 		if (bCleanup)
1997 		{
1998 	        while (pProfile->m_NoLines > 0)
1999 	            removeLine(pProfile, pProfile->m_NoLines - 1);
2000 
2001 	        free(pProfile->m_Lines);
2002 	        pProfile->m_Lines = NULL;
2003             pProfile->m_NoLines = 0;
2004 	        pProfile->m_MaxLines = 0;
2005 
2006 	        while (pProfile->m_NoSections > 0)
2007 	            removeSection(pProfile, &pProfile->m_Sections[pProfile->m_NoSections - 1]);
2008 
2009 	        free(pProfile->m_Sections);
2010 	        pProfile->m_Sections = NULL;
2011             pProfile->m_NoSections = 0;
2012 	        pProfile->m_MaxSections = 0;
2013 		}
2014     }
2015 
2016 #ifdef TRACE_OSL_PROFILE
2017     OSL_TRACE("Out storeProfile [ok]\n");
2018 #endif
2019     return (sal_True);
2020 }
2021 
2022 
osl_openTmpProfileImpl(osl_TProfileImpl * pProfile)2023 static osl_TFile* osl_openTmpProfileImpl(osl_TProfileImpl* pProfile)
2024 {
2025 	osl_TFile* pFile=NULL;
2026 	sal_Char* pszExtension = "tmp";
2027 	sal_Char pszTmpName[PATH_MAX];
2028 	oslProfileOption PFlags=0;
2029 
2030     pszTmpName[0] = '\0';
2031 
2032 	/* generate tmp profilename */
2033 	osl_ProfileGenerateExtension(pProfile->m_FileName,pszExtension,pszTmpName);
2034 
2035     if ( pszTmpName[0] == 0 )
2036 	{
2037 		return 0;
2038 	}
2039 
2040 	if ( ! ( pProfile->m_Flags & osl_Profile_READLOCK ) )
2041 	{
2042 		PFlags |= osl_Profile_WRITELOCK;
2043 	}
2044 
2045 	/* open this file */
2046 	pFile = openFileImpl(pszTmpName,pProfile->m_Flags | PFlags);
2047 
2048 
2049 	/* return new pFile */
2050 	return pFile;
2051 }
2052 
osl_ProfileSwapProfileNames(osl_TProfileImpl * pProfile)2053 static sal_Bool osl_ProfileSwapProfileNames(osl_TProfileImpl* pProfile)
2054 {
2055   	sal_Bool bRet = sal_False;
2056 
2057   	sal_Char pszBakFile[PATH_MAX];
2058   	sal_Char pszTmpFile[PATH_MAX];
2059   	sal_Char pszIniFile[PATH_MAX];
2060 
2061     pszBakFile[0] = '\0';
2062     pszTmpFile[0] = '\0';
2063     pszIniFile[0] = '\0';
2064 
2065   	osl_ProfileGenerateExtension(pProfile->m_FileName,"bak",pszBakFile);
2066 
2067     strncpy(pszIniFile,pProfile->m_FileName,PATH_MAX);
2068     pszIniFile[PATH_MAX-1] = '\0';
2069 
2070     osl_ProfileGenerateExtension(pProfile->m_FileName,"tmp",pszTmpFile);
2071 
2072   	/* unlink bak */
2073   	unlink( pszBakFile );
2074 
2075   	/* rename ini bak */
2076   	rename( pszIniFile, pszBakFile );
2077 
2078   	/* rename tmp ini */
2079   	rename( pszTmpFile, pszIniFile );
2080 
2081 	return bRet;
2082 }
2083 
2084 
osl_ProfileGenerateExtension(sal_Char * pszFileName,sal_Char * pszExtension,sal_Char * pszTmpName)2085 static void osl_ProfileGenerateExtension(sal_Char* pszFileName, sal_Char* pszExtension, sal_Char* pszTmpName)
2086 {
2087 
2088     strcpy(pszTmpName,pszFileName);
2089     strcat(pszTmpName,".");
2090     strcat(pszTmpName,pszExtension);
2091 
2092 	return;
2093 }
2094 
2095 
acquireProfile(oslProfile Profile,sal_Bool bWriteable)2096 static osl_TProfileImpl* acquireProfile(oslProfile Profile, sal_Bool bWriteable)
2097 {
2098 	osl_TProfileImpl* pProfile = (osl_TProfileImpl*)Profile;
2099     oslProfileOption PFlags=0;
2100     sal_Bool bRet=sal_False;
2101 
2102     if ( bWriteable )
2103     {
2104         PFlags = osl_Profile_DEFAULT | osl_Profile_WRITELOCK;
2105     }
2106     else
2107     {
2108         PFlags = osl_Profile_DEFAULT;
2109     }
2110 
2111 
2112 	if (pProfile == NULL)
2113 	{
2114 #ifdef DEBUG_OSL_PROFILE
2115         OSL_TRACE("AUTOOPEN MODE\n");
2116 #endif
2117 
2118 		if ( ( pProfile = (osl_TProfileImpl*) osl_openProfile(0, PFlags ) ) != NULL )
2119         {
2120 			pProfile->m_Flags |= FLG_AUTOOPEN;
2121         }
2122 	}
2123 	else
2124 	{
2125 #ifdef DEBUG_OSL_PROFILE
2126         OSL_TRACE("try to acquire\n");
2127 #endif
2128 
2129 		if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
2130 		{
2131             if (! (pProfile->m_Flags & (osl_Profile_READLOCK | osl_Profile_WRITELOCK | osl_Profile_FLUSHWRITE )))
2132             {
2133                 osl_TStamp Stamp;
2134 
2135 #ifdef DEBUG_OSL_PROFILE
2136                 OSL_TRACE("Profile acquire DEFAULT MODE\n");
2137 #endif
2138                 if (! (pProfile->m_pFile = openFileImpl(pProfile->m_FileName, pProfile->m_Flags | PFlags )))
2139                     return NULL;
2140 
2141                 Stamp = OslProfile_getFileStamp(pProfile->m_pFile);
2142 
2143                 if (memcmp(&Stamp, &(pProfile->m_Stamp), sizeof(osl_TStamp)))
2144                 {
2145                     pProfile->m_Stamp = Stamp;
2146 
2147                     bRet=loadProfile(pProfile->m_pFile, pProfile);
2148                     OSL_ASSERT(bRet);
2149                 }
2150             }
2151             else
2152             {
2153 #ifdef DEBUG_OSL_PROFILE
2154                 OSL_TRACE("Profile acquire READ/WRITELOCK MODE\n");
2155 #endif
2156                 /* A readlock file could not be written */
2157                 if ((pProfile->m_Flags & osl_Profile_READLOCK) && bWriteable)
2158                 {
2159                     return (NULL);
2160                 }
2161             }
2162         }
2163 	}
2164 
2165 	return (pProfile);
2166 }
2167 
releaseProfile(osl_TProfileImpl * pProfile)2168 static sal_Bool releaseProfile(osl_TProfileImpl* pProfile)
2169 {
2170     sal_Bool bRet=sal_False;
2171 
2172 #ifdef TRACE_OSL_PROFILE
2173     OSL_TRACE("In  releaseProfile\n");
2174 #endif
2175 
2176     if ( pProfile == NULL )
2177     {
2178 #ifdef TRACE_OSL_PROFILE
2179         OSL_TRACE("Out releaseProfile [profile==0]\n");
2180 #endif
2181         return sal_False;
2182     }
2183 
2184 	if (pProfile->m_Flags & FLG_AUTOOPEN)
2185     {
2186 #ifdef TRACE_OSL_PROFILE
2187         OSL_TRACE("Out releaseProfile [AUTOOPEN]\n");
2188 #endif
2189 		return (osl_closeProfile((oslProfile)pProfile));
2190     }
2191 	else
2192 	{
2193 #ifdef DEBUG_OSL_PROFILE
2194         OSL_TRACE("DEFAULT MODE\n");
2195 #endif
2196 		if (! (pProfile->m_Flags & (osl_Profile_READLOCK | osl_Profile_WRITELOCK | osl_Profile_FLUSHWRITE )))
2197 		{
2198 			if (pProfile->m_Flags & FLG_MODIFIED)
2199             {
2200 				bRet=storeProfile(pProfile, sal_False);
2201                 OSL_ASSERT(bRet);
2202             }
2203 
2204 
2205 			closeFileImpl(pProfile->m_pFile,pProfile->m_Flags);
2206 			pProfile->m_pFile = NULL;
2207 		}
2208 	}
2209 
2210 #ifdef TRACE_OSL_PROFILE
2211     OSL_TRACE("Out releaseProfile [ok]\n");
2212 #endif
2213 	return (sal_True);
2214 }
2215