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