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