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