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