
/* 
  -----------------------------------------------------------------------------
 
  module: vcn51.cpp
 
  -----------------------------------------------------------------------------
 
  responsible:  BerndV
 
  special area: DBMServer Configuration Value Class
   
  description:  DBMServer Configuration Value Class - Implementation

  -----------------------------------------------------------------------------


    ========== licence begin  GPL
    Copyright (c) 2000-2005 SAP AG

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    as published by the Free Software Foundation; either version 2
    of the License, or (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    ========== licence end




*/

/*
  -----------------------------------------------------------------------------
  includes
  -----------------------------------------------------------------------------
 */
#include <stdlib.h>

#include "heo06.h"
#include "hcn42.h"
#include "hcn90.h"
#include "hcn51.h"


/*
  =============================================================================
  class:        tcn51ConfigEntry
  =============================================================================
 */
class tcn51ConfigEntry {
  private:
    _TCHAR             szConfigString[600];
    tcn51ConfigEntry * pNext;

    tcn51ConfigEntry () {szConfigString[0] = CHAR_STRINGTERM_CN90; 
                         pNext             = NULL;}

    friend class cn51DBMConfigValue;
};

/*
  =============================================================================
  class:        cn51DBMConfigValue
  =============================================================================
 */

/*
  -----------------------------------------------------------------------------
  init static members
  -----------------------------------------------------------------------------
 */
tcn51ConfigEntry * cn51DBMConfigValue::m_pAnchor = NULL;
teo200_EventList   cn51DBMConfigValue::m_LastEvent;

/*
  -----------------------------------------------------------------------------
  public function:     cn51DBMConfigValue::cn51DBMConfigValue
  -----------------------------------------------------------------------------
 */
cn51DBMConfigValue::cn51DBMConfigValue ( const tsp00_DbNamec szDbName, 
                                         const tsp00_Namec   szValueName )
{

  m_szName     = szValueName;
  m_szDbName   = szDbName;
  m_szValue.Init();


} // cn51DBMConfigValue::cn51DBMConfigValue 

/*
  -----------------------------------------------------------------------------
  public function:     cn51DBMConfigValue::operator = 
  -----------------------------------------------------------------------------
 */
cn51DBMConfigValue cn51DBMConfigValue::operator = ( const tsp00_Int4 cfgValue )
{
  tsp00_C64c          szCrypt;
  tsp00_Namec         szValue;

  _stprintf(szValue, "%ld", (long) cfgValue);

  cn90ClearStringToCryptString(szValue, szCrypt);

  m_szValue.rawAssign(szCrypt);

  saveValue(m_szDbName, m_szName, m_szValue);

  return *this;

} // cn51DBMConfigValue::operator = 

/*
  -----------------------------------------------------------------------------
  public function:     cn51DBMConfigValue::operator = 
  -----------------------------------------------------------------------------
 */
cn51DBMConfigValue cn51DBMConfigValue::operator = ( const tsp00_Namec cfgValue )
{
  tsp00_C64c          szCrypt;

  cn90ClearStringToCryptString(cfgValue, szCrypt);

  m_szValue.rawAssign(szCrypt);

  saveValue(m_szDbName, m_szName, m_szValue);

  return *this;
} // cn51DBMConfigValue::operator = 

/*
  -----------------------------------------------------------------------------
  public function:     cn51DBMConfigValue::operator = 
  -----------------------------------------------------------------------------
 */
cn51DBMConfigValue cn51DBMConfigValue::operator = ( const tsp00_C512c cfgValue )
{

  m_szValue.rawAssign(cfgValue);

  saveValue(m_szDbName, m_szName, m_szValue);

  return *this;
} // cn51DBMConfigValue::operator = 

/*
  -----------------------------------------------------------------------------
  public function:     cn51DBMConfigValue::operator tsp00_Int4
  -----------------------------------------------------------------------------
 */
cn51DBMConfigValue::operator tsp00_Int4 ( )
{
  tsp00_C64c    szCrypt;
  tsp00_Namec   szValue;

  readValue(m_szDbName, m_szName, m_szValue);

  szCrypt.rawAssign(m_szValue);

  cn90CryptStringToClearString(szCrypt, szValue);

  return atol(szValue);

} // cn51DBMConfigValue::operator tsp00_Int4

/*
  -----------------------------------------------------------------------------
  public function:     cn51DBMConfigValue::operator tsp00_Namec
  -----------------------------------------------------------------------------
 */
cn51DBMConfigValue::operator tsp00_Namec ( )
{
  tsp00_C64c    szCrypt;
  tsp00_Namec   szValue;

  readValue(m_szDbName, m_szName, m_szValue);

  szCrypt.rawAssign(m_szValue);

  cn90CryptStringToClearString(szCrypt, szValue);

  return szValue;

} // cn51DBMConfigValue::operator tsp00_Namec

/*
  -----------------------------------------------------------------------------
  public function:     cn51DBMConfigValue::operator tsp00_C512c
  -----------------------------------------------------------------------------
 */
cn51DBMConfigValue::operator tsp00_C512c ( )
{
  readValue(m_szDbName, m_szName, m_szValue);

  return m_szValue;

} // cn51DBMConfigValue::operator tsp00_C512c

/*
  -----------------------------------------------------------------------------
  private function:     cn51DBMConfigValue::saveValue
  -----------------------------------------------------------------------------
 */
void cn51DBMConfigValue::saveValue ( const tsp00_DbNamec   szDbName,
                                     const tsp00_Namec     szName, 
                                     const tsp00_C512c     szValue ) const
{
  tcn51ConfigEntry  * pAnchor   = m_pAnchor;
  tcn51ConfigEntry  * pEntry    = NULL;
  tcn51ConfigEntry  * pLast     = NULL;
  _TCHAR              szNewConfigString[600];
  _TCHAR              bWritten  = false;

  // prepare config file contents
  if (m_pAnchor == NULL) {
    pAnchor = readFile(szDbName);
  } // end if
    
  // prepare config string
  if (_tcslen(szValue) > 0) {
    _stprintf ( szNewConfigString , _T("%-20s=%s"), (const _TCHAR *) szName,
                                                    (const _TCHAR *) szValue);
  } else {
    szNewConfigString[0] = CHAR_STRINGTERM_CN90;
  } // end if

  // search entry
  pEntry = pAnchor;
  while (pEntry != NULL) {
    if (cn90CheckKeyword(pEntry->szConfigString, szName, false)) {
      // wow match found, replace config string
      _tcscpy(pEntry->szConfigString, szNewConfigString);
      bWritten = true;
    } // end if

    pLast = pEntry;
    pEntry = pEntry->pNext;
  } // end while

  // add new entry if not found
  if (!bWritten) {
    pEntry = new tcn51ConfigEntry;
    if (pEntry != NULL) {
      _tcscpy(pEntry->szConfigString, szNewConfigString);
    } // end if
    if (pLast != NULL) {
      pLast->pNext = pEntry;
    } else {
      pAnchor = pEntry;
    } // end if
  } // end if

  // save file
  if (m_pAnchor == NULL) {
    saveFile(szDbName, pAnchor);
  } // end if

} // cn51DBMConfigValue::saveValue
    
/*
  -----------------------------------------------------------------------------
  private function:     cn51DBMConfigValue::readValue
  -----------------------------------------------------------------------------
 */
void cn51DBMConfigValue::readValue ( const tsp00_DbNamec   szDbName,
                                     const tsp00_Namec     szName, 
                                           tsp00_C512c   & szValue) const
{
  tcn51ConfigEntry  * pAnchor   = m_pAnchor;
  tcn51ConfigEntry  * pEntry    = NULL;
  tcn51ConfigEntry  * pDelete   = NULL;
  _TCHAR            * pData;

  // prepare config file contents
  if (m_pAnchor == NULL) {
    pAnchor = readFile(szDbName);
  } // end if

  // search entry
  pEntry = pAnchor;
  while (pEntry != NULL) {
    if (cn90CheckKeyword(pEntry->szConfigString, szName, false)) {
      pData = _tcschr(pEntry->szConfigString, _T('='));
      if (pData != NULL) {
        pData++;
        cn90StripTrailingChar(pData, _T('\n'));
        cn90StripTrailingChar(pData, _T('\r'));
        _tcscpy(szValue, pData);
      } // end if
    } // end if

    pDelete = pEntry;
    pEntry = pEntry->pNext;
    if (m_pAnchor == NULL) {
      delete pDelete;
    } // end if
    
  } // end while

} // cn51DBMConfigValue::readValue

/*
  -----------------------------------------------------------------------------
  private function:     cn51DBMConfigValue::readFile
  -----------------------------------------------------------------------------
 */
tcn51ConfigEntry * cn51DBMConfigValue::readFile ( const tsp00_DbNamec szDbName)
{
  FUNCTION_DBG_MCN00_1("cn51DBMConfigValue::readFile");

  tsp00_Pathc         szConfigFile;
  tsp00_Pathc         szBackupFile;
  tsp00_Int4     	    hFile;
  tsp05_RteFileError  errFile;
  tsp00_Longint         nOut;
  tcn51ConfigEntry  * pEntry    = NULL;
  tcn51ConfigEntry  * pAnchor   = NULL;

  m_LastEvent.eo200_ClearEventList();

  // prepare config file name
  cn42GetFileName(szDbName, FGET_DBMCFG_CN42, szConfigFile, szBackupFile);

  // init list
  pAnchor = new tcn51ConfigEntry;
  pEntry  = pAnchor;
  // open file for read
  sqlfopenc(szConfigFile, sp5vf_text, sp5vf_read, sp5bk_buffered, &hFile, &errFile );
  if (errFile.sp5fe_result != vf_ok) {
    cn42RestoreFile(szDbName, FGET_DBMCFG_CN42);
    sqlfopenc(szConfigFile, sp5vf_text, sp5vf_read, sp5bk_buffered, &hFile, &errFile );
  }  // end if
  if (errFile.sp5fe_result != vf_ok) {
    // !!!!! FH: szBackupFile instead szConfigFile !!!!! PTS 1103341
    sqlfopenc(szBackupFile, sp5vf_text, sp5vf_read, sp5bk_buffered, &hFile, &errFile );
  }  // end if

  // read file
  if (errFile.sp5fe_result == vf_ok) {
    while (errFile.sp5fe_result == vf_ok && pEntry != NULL) {
      sqlfreadc (hFile, pEntry->szConfigString, sizeof(pEntry->szConfigString), &nOut, &errFile);
      pEntry->pNext = new tcn51ConfigEntry;
      pEntry = pEntry->pNext;
    } // end while

    sqlfclosec(hFile, sp5vf_close_normal, &errFile);
  } else {
    // write error to protocol
    teo200_EventList aRTE(FUNCTION_NAME_MCN00_1, errFile.sp5fe_result, TERR_CN00_1, "DBM", "%.*s", errFile.sp5fe_text.length(), errFile.sp5fe_text.asCharp());
    teo200_EventList aEvent (aRTE, FUNCTION_NAME_MCN00_1, ERR_FILE_CN00_1);
    m_LastEvent = aEvent;
  } // end if

  return pAnchor;
} // end cn51DBMConfigValue::readFile

/*
  -----------------------------------------------------------------------------
  private function:     cn51DBMConfigValue::saveFile
  -----------------------------------------------------------------------------
 */
void cn51DBMConfigValue::saveFile ( const tsp00_DbNamec        szDbName,
                                          tcn51ConfigEntry *   pAnchor )
{
  FUNCTION_DBG_MCN00_1("cn51DBMConfigValue::saveFile");

  tsp00_Pathc         szConfigFile;
  tsp00_Pathc         szBackupFile;
  tsp00_Int4     	    hFile;
  tsp05_RteFileError  errFile;
  tcn51ConfigEntry  * pEntry    = NULL;
  tcn51ConfigEntry  * pDelete   = NULL;

  m_LastEvent.eo200_ClearEventList();

  // prepare config file name
  cn42GetFileName(szDbName, FGET_DBMCFG_CN42, szConfigFile, szBackupFile);

  // open file for write
  sqlfopenc(szConfigFile, sp5vf_text, sp5vf_write, sp5bk_buffered, &hFile, &errFile );
  if (errFile.sp5fe_result != vf_ok) {
    cn42RestoreFile(szDbName, FGET_DBMCFG_CN42);
    sqlfopenc(szConfigFile, sp5vf_text, sp5vf_write, sp5bk_buffered, &hFile, &errFile );
  }  // end if
  if (errFile.sp5fe_result != vf_ok) {
    sqlfopenc(szBackupFile, sp5vf_text, sp5vf_write, sp5bk_buffered, &hFile, &errFile ); 
  }  // end if

  // write file
  if (errFile.sp5fe_result == vf_ok) {
    pEntry = pAnchor;
    while (errFile.sp5fe_result == vf_ok && pEntry != NULL) {
      if (_tcslen(pEntry->szConfigString) > 0) {
        sqlfwritec (hFile, pEntry->szConfigString, -1, &errFile);
      } // end if
      pDelete = pEntry;
      pEntry = pEntry->pNext;
      delete pDelete;
    } // end while
    if (errFile.sp5fe_result != vf_ok) {
      // write error to protocol
      teo200_EventList aRTE(FUNCTION_NAME_MCN00_1, errFile.sp5fe_result, TERR_CN00_1, "DBM", "%.*s", errFile.sp5fe_text.length(), errFile.sp5fe_text.asCharp());
      teo200_EventList aEvent (aRTE, FUNCTION_NAME_MCN00_1, ERR_FILE_CN00_1);
       m_LastEvent = aEvent;

      sqlfclosec(hFile, sp5vf_close_normal, &errFile);
      cn42RestoreFile(szDbName, FGET_DBMCFG_CN42);
    } else {
      sqlfclosec(hFile, sp5vf_close_normal, &errFile);
      if (errFile.sp5fe_result != vf_ok) {
        // write error to protocol
        teo200_EventList aRTE(FUNCTION_NAME_MCN00_1, errFile.sp5fe_result, TERR_CN00_1, "DBM", "%.*s", errFile.sp5fe_text.length(), errFile.sp5fe_text.asCharp());
        teo200_EventList aEvent (aRTE, FUNCTION_NAME_MCN00_1, ERR_FILE_CN00_1);
        m_LastEvent = aEvent;

        cn42RestoreFile(szDbName, FGET_DBMCFG_CN42);
      } else {
        cn42BackupFile(szDbName, FGET_DBMCFG_CN42);
      } // end if
    } // end if
  } else {
    // write error to protocol
    teo200_EventList aRTE(FUNCTION_NAME_MCN00_1, errFile.sp5fe_result, TERR_CN00_1, "DBM", "%.*s", errFile.sp5fe_text.length(), errFile.sp5fe_text.asCharp());
    teo200_EventList aEvent (aRTE, FUNCTION_NAME_MCN00_1, ERR_FILE_CN00_1);
    m_LastEvent = aEvent;
  } // end if

} // end cn51DBMConfigValue::saveFile

/*
  -----------------------------------------------------------------------------
  public function:     cn51DBMConfigValue::startBuffering
  -----------------------------------------------------------------------------
 */
void cn51DBMConfigValue::startBuffering ( const tsp00_DbNamec        szDbName )
{
  if (m_pAnchor == NULL) {
    m_pAnchor = readFile(szDbName);
  } // end if
} // cn51DBMConfigValue::startBuffering

/*
  -----------------------------------------------------------------------------
  public function:     cn51DBMConfigValue::endBuffering
  -----------------------------------------------------------------------------
 */
void cn51DBMConfigValue::endBuffering ( const tsp00_DbNamec        szDbName )
{
  if (m_pAnchor != NULL) {
    saveFile(szDbName, m_pAnchor);
    m_pAnchor = NULL;
  } // end if
} // cn51DBMConfigValue::endBuffering
