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