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