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 != 0 && 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 == 0 )
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 != 0 )
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 == 0 )
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 != 0 )
338 {
339 for ( idx = 0 ; idx < pProfile->m_NoLines ; ++idx)
340 {
341 if ( pProfile->m_Lines[idx] != 0 )
342 {
343 free(pProfile->m_Lines[idx]);
344 pProfile->m_Lines[idx]=0;
345 }
346 }
347 free(pProfile->m_Lines);
348 pProfile->m_Lines=0;
349 }
350 if ( pProfile->m_Sections != 0 )
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 != 0 )
356 {
357 free(pProfile->m_Sections[idx].m_Entries);
358 pProfile->m_Sections[idx].m_Entries=0;
359 }
360 }
361 free(pProfile->m_Sections);
362 pProfile->m_Sections=0;
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 == 0 )
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 != 0 && 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 != 0 && pFile->m_Handle >= 0 ) || ( pFile->m_pWriteBuf == 0 ) )
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=0;
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=0;
490 osl_TProfileSection* pSec;
491 osl_TProfileImpl* pProfile=0;
492 osl_TProfileImpl* pTmpProfile=0;
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 == 0 )
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 != 0 )
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 == 0 )
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 = 0;
653 osl_TProfileSection* pSec;
654 osl_TProfileImpl* pProfile = 0;
655 osl_TProfileImpl* pTmpProfile = 0;
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 == 0 )
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!= 0 )
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 = 0;
843 osl_TProfileImpl* pTmpProfile = 0;
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 == 0 )
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 = 0;
929 osl_TProfileImpl* pTmpProfile = 0;
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 == 0 )
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 = 0;
1030 osl_TProfileImpl* pTmpProfile = 0;
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 == 0 )
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 == 0 )
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=0;
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 == 0 )
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 == 0 )
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 == 0 || pFile->m_Handle < 0 )
1458 {
1459 return (sal_False);
1460 }
1461
1462 if ( pFile->m_pWriteBuf == 0 )
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 == 0 )
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 = 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]=0;
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 != 0 && pProfile->m_Lines[pProfile->m_NoLines] != 0 )
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 = 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]=0;
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] = 0;
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 = 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=0;
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 != 0 )
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=0;
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 = 0;
1802 }
1803 else
1804 {
1805 pSection->m_Entries = 0;
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=0;
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 == 0 )
1878 {
1879 return sal_False;
1880 }
1881
1882 if ( pProfile == 0 )
1883 {
1884 return sal_False;
1885 }
1886
1887 OSL_VERIFY(OslProfile_rewindFile(pFile, sal_False));
1888
1889 while ( ( pLine=OslProfile_getLine(pFile) ) != 0 )
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 == 0 )
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 != 0 )
1969 {
1970 free(pTmpFile->m_pWriteBuf);
1971 }
1972
1973 pTmpFile->m_pWriteBuf=0;
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=0;
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 strcpy(pszIniFile,pProfile->m_FileName);
2068
2069 osl_ProfileGenerateExtension(pProfile->m_FileName,"tmp",pszTmpFile);
2070
2071 /* unlink bak */
2072 unlink( pszBakFile );
2073
2074 /* rename ini bak */
2075 rename( pszIniFile, pszBakFile );
2076
2077 /* rename tmp ini */
2078 rename( pszTmpFile, pszIniFile );
2079
2080 return bRet;
2081 }
2082
2083
osl_ProfileGenerateExtension(sal_Char * pszFileName,sal_Char * pszExtension,sal_Char * pszTmpName)2084 static void osl_ProfileGenerateExtension(sal_Char* pszFileName, sal_Char* pszExtension, sal_Char* pszTmpName)
2085 {
2086
2087 strcpy(pszTmpName,pszFileName);
2088 strcat(pszTmpName,".");
2089 strcat(pszTmpName,pszExtension);
2090
2091 return;
2092 }
2093
2094
acquireProfile(oslProfile Profile,sal_Bool bWriteable)2095 static osl_TProfileImpl* acquireProfile(oslProfile Profile, sal_Bool bWriteable)
2096 {
2097 osl_TProfileImpl* pProfile = (osl_TProfileImpl*)Profile;
2098 oslProfileOption PFlags=0;
2099 sal_Bool bRet=sal_False;
2100
2101 if ( bWriteable )
2102 {
2103 PFlags = osl_Profile_DEFAULT | osl_Profile_WRITELOCK;
2104 }
2105 else
2106 {
2107 PFlags = osl_Profile_DEFAULT;
2108 }
2109
2110
2111 if (pProfile == NULL)
2112 {
2113 #ifdef DEBUG_OSL_PROFILE
2114 OSL_TRACE("AUTOOPEN MODE\n");
2115 #endif
2116
2117 if ( ( pProfile = (osl_TProfileImpl*) osl_openProfile(0, PFlags ) ) != NULL )
2118 {
2119 pProfile->m_Flags |= FLG_AUTOOPEN;
2120 }
2121 }
2122 else
2123 {
2124 #ifdef DEBUG_OSL_PROFILE
2125 OSL_TRACE("try to acquire\n");
2126 #endif
2127
2128 if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
2129 {
2130 if (! (pProfile->m_Flags & (osl_Profile_READLOCK | osl_Profile_WRITELOCK | osl_Profile_FLUSHWRITE )))
2131 {
2132 osl_TStamp Stamp;
2133
2134 #ifdef DEBUG_OSL_PROFILE
2135 OSL_TRACE("Profile acquire DEFAULT MODE\n");
2136 #endif
2137 if (! (pProfile->m_pFile = openFileImpl(pProfile->m_FileName, pProfile->m_Flags | PFlags )))
2138 return NULL;
2139
2140 Stamp = OslProfile_getFileStamp(pProfile->m_pFile);
2141
2142 if (memcmp(&Stamp, &(pProfile->m_Stamp), sizeof(osl_TStamp)))
2143 {
2144 pProfile->m_Stamp = Stamp;
2145
2146 bRet=loadProfile(pProfile->m_pFile, pProfile);
2147 OSL_ASSERT(bRet);
2148 }
2149 }
2150 else
2151 {
2152 #ifdef DEBUG_OSL_PROFILE
2153 OSL_TRACE("Profile acquire READ/WRITELOCK MODE\n");
2154 #endif
2155 /* A readlock file could not be written */
2156 if ((pProfile->m_Flags & osl_Profile_READLOCK) && bWriteable)
2157 {
2158 return (NULL);
2159 }
2160 }
2161 }
2162 }
2163
2164 return (pProfile);
2165 }
2166
releaseProfile(osl_TProfileImpl * pProfile)2167 static sal_Bool releaseProfile(osl_TProfileImpl* pProfile)
2168 {
2169 sal_Bool bRet=sal_False;
2170
2171 #ifdef TRACE_OSL_PROFILE
2172 OSL_TRACE("In releaseProfile\n");
2173 #endif
2174
2175 if ( pProfile == 0 )
2176 {
2177 #ifdef TRACE_OSL_PROFILE
2178 OSL_TRACE("Out releaseProfile [profile==0]\n");
2179 #endif
2180 return sal_False;
2181 }
2182
2183 if (pProfile->m_Flags & FLG_AUTOOPEN)
2184 {
2185 #ifdef TRACE_OSL_PROFILE
2186 OSL_TRACE("Out releaseProfile [AUTOOPEN]\n");
2187 #endif
2188 return (osl_closeProfile((oslProfile)pProfile));
2189 }
2190 else
2191 {
2192 #ifdef DEBUG_OSL_PROFILE
2193 OSL_TRACE("DEFAULT MODE\n");
2194 #endif
2195 if (! (pProfile->m_Flags & (osl_Profile_READLOCK | osl_Profile_WRITELOCK | osl_Profile_FLUSHWRITE )))
2196 {
2197 if (pProfile->m_Flags & FLG_MODIFIED)
2198 {
2199 bRet=storeProfile(pProfile, sal_False);
2200 OSL_ASSERT(bRet);
2201 }
2202
2203
2204 closeFileImpl(pProfile->m_pFile,pProfile->m_Flags);
2205 pProfile->m_pFile = NULL;
2206 }
2207 }
2208
2209 #ifdef TRACE_OSL_PROFILE
2210 OSL_TRACE("Out releaseProfile [ok]\n");
2211 #endif
2212 return (sal_True);
2213 }
2214