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