/* static char szModuleName__[] = "c:/unix/newer/nradutil.c"; jmh 29 May 2001 */
/* static char szLastVersion[] = "Version 0.10"; jmh 29 May 2001 */
/* static char szLastSave[] = "1994-11-17*10:47"; jmh 29 May 2001 */

/***********************************************************************
Abstract
nradutil.c - handling of utilitys for Nordrad pgm's

Change activity
1997-09-08      ARG  Modified UtlTimeoutHandler
1994-01-21 1.00 BBN  Initial version by Bjorn Brodin, AU-System Communication AB.

Description
        Timer functions 

Program structure:

Return codes:         

**********************************************************************      */

#include "nradutil.h"
#include <ctype.h>
#ifndef  NETDEF
#include "netdef.h"
#endif
#include <time.h>
#include "utl.h"
#define  TIMEOUT       -100
#define  MAX_ERR_CODES 100
struct ErrorDataStruc ErrMsgTab[MAX_ERR_CODES];

/****************************************************************************
*                                       timeout_handler
*   Called at timeout
*****************************************************************************
                                                                            */

void UtlTimeoutHandler(int signal)
{

  /**************************************************************************/
  /* Set to ignore interrupt signal too avoid own parent PID termination    */
  /**************************************************************************/
  /* USE TIMER FUNCTIONS IF NOT IN VAX ENVIRONMENT                          */
  /**************************************************************************/

#ifndef  VMS
#ifndef  NOTIMERS
  bTimeout = TRUE;
#endif   
#endif   
  return;
} 


/****************************************************************************
*                                       start_timeout
*       Start a timer
*****************************************************************************
                                                                            */

INT32 UtlStartTimeout(INT32 timeout)
{

  /**************************************************************************/
  /* Set timeout action (signal SIGALRM)                                    */
  /**************************************************************************/
  /* USE TIMER FUNCTIONS IF NOT IN VAX ENVIRONMENT                          */
  /**************************************************************************/

#ifndef  VMS
#ifndef  NOTIMERS
  struct sigaction dummy_sigpipe_action;

  if (sigaction(SIGALRM, 
                &sigalrm_action, 
                &sigalrm_sav_action) == -1)
    return (NOK);

  /**************************************************************************/
  /* Ignore broken pipe signals                                             */
  /**************************************************************************/

  dummy_sigpipe_action.sa_handler = SIG_IGN;
  sigemptyset(&dummy_sigpipe_action.sa_mask);
  dummy_sigpipe_action.sa_flags = SA_RESTART;
  sigaction(SIGPIPE, 
            &dummy_sigpipe_action, 
            NULL);
  bTimeout = FALSE;

  /**************************************************************************/
  /* Activate interval timer                                                */
  /**************************************************************************/

  alarm(timeout);
#endif
#endif
  return (OK);
} 


/****************************************************************************
*                                       cancel_timeout
*   Cancels a timer
*****************************************************************************
                                                                            */

INT32 UtlCancelTimeout(void)
{
  INT32 rc = OK;

  /**************************************************************************/
  /* Deactivate interval timer                                              */
  /**************************************************************************/
  /* USE TIMER FUNCTIONS IF NOT IN VAX ENVIRONMENT                          */
  /**************************************************************************/

#ifndef  VMS
#ifndef  NOTIMERS
  struct sigaction dummy_sigpipe_action;

  alarm(0);

  /**************************************************************************/
  /* Reset to old action for SIGALRM                                        */
  /**************************************************************************/

  if (sigaction(SIGALRM, 
                &sigalrm_sav_action, 
                NULL) == -1)
    rc = NOK;

  /**************************************************************************/
  /* Revert to default SIGPIPE action                                       */
  /**************************************************************************/

  dummy_sigpipe_action.sa_handler = SIG_DFL;
  sigemptyset(&dummy_sigpipe_action.sa_mask);
  dummy_sigpipe_action.sa_flags = SA_RESTART;
  sigaction(SIGPIPE, 
            &dummy_sigpipe_action, 
            NULL);
#endif
#endif
  return  rc;
} 

void UtlInitTimeoutHandler()
{

/* USE TIMER FUNCTIONS IF NOT IN VAX ENVIRONMENT                            */

#ifndef  VMS
#ifndef  NOTIMERS
  sigalrm_action.sa_handler = UtlTimeoutHandler;
  sigemptyset(&sigalrm_action.sa_mask);
  sigalrm_action.sa_flags = SA_RESTART;
  sigaction(SIGALRM, 
            &sigalrm_action, 
            NULL);
  bTimeout = FALSE;
#endif
#endif
} 


/*----------------------------------------------------------
*  StrToUpper  - Converts a string to uppercase
*     returns  - nothing 
*---------------------------------------------------------                  */

void UtlStrToUpper(char *pStr,INT32 iLen)
{
  INT32 iInd = 0;

  while (iInd < iLen)
    {
      *(pStr+iInd) = toupper(*(pStr+iInd));
      iInd++;
    } 
} 


/*----------------------------------------------------------
*  UtlFileToFixRowLen  - Used primarily in VAX environment 
*                        to convert for format with variable
*                        line length with length int first
*                        on every line.
*     returns  - TRUE if no errors found, FALSE otherwise
*---------------------------------------------------------                  */

INT32 UtlFileToFixRowLen(char *pFileStr,char *pConvFileName)
{
  FILE *fVarLenFile;
  FILE *fFixFile;
  char Line[160];
  INT32 iRc = OK;

  fVarLenFile = fopen(pFileStr, 
                      "r");
  if (fVarLenFile)
    {
      fFixFile = fopen(pConvFileName, 
                       "wb");
      if (fFixFile)
        {
          while ((feof(fVarLenFile) == 0) && (iRc == OK))
            {
              memset(Line, 
                     0, 
                     sizeof(Line));
              if (fgets(Line, 
                        sizeof(Line), 
                        fVarLenFile) == NULL)
                iRc = NOK;
              if (iRc != NOK)
                {
                  if (fwrite(Line, 
                             strlen(Line), 
                             sizeof(char), 
                             fFixFile) == 0 )
                    iRc = NOK;
                } 
            } 
        } 
      else
        {
          fclose(fVarLenFile);
          return  NOK;
        } 
    } 
  else
    return  NOK;

  fclose(fVarLenFile);
  fclose(fFixFile);
  return  OK;
} 

void UtlNradTimeStr(time_t lTime,char *TimeStr)
{
  struct tm *pTmStruc;
  INT16 iCentury,iMonth;

  pTmStruc = localtime(&lTime);
  if (pTmStruc->tm_year > 93)
    iCentury = 1900+pTmStruc->tm_year;
  else
    iCentury = 2000+pTmStruc->tm_year;
  iMonth = pTmStruc->tm_mon+1;
  sprintf(TimeStr, 
          "%4d-%02d-%02d %02d:%02d:%02d.00", 
          iCentury, 
          iMonth, 
          pTmStruc->tm_mday, 
          pTmStruc->tm_hour, 
          pTmStruc->tm_min, 
          pTmStruc->tm_min);
} 

#ifdef TEST_ENVIRONMENT
/*----------------------------------------------------------
*  UtlInsertAdaTypeStr  - Converts a string to Ada format
*     returns  - OK(0) or NOK(!=0)UtlInsertAdaTypeStr if error  
*---------------------------------------------------------                  */

INT32 UtlInsertAdaTypeStr(struct AdaTypeStrStruc *pAdaStr,char *pStr,INT32 
                          iMaxLen,INT32 CheckStrNotEmpty)
{
  INT32 iLen;

  iLen = strlen(pStr);
  if ((CheckStrNotEmpty) && (iLen == 0))
    return  NOK;

  if (iLen > pAdaStr->iMaxLen)
    return  NOK;

  pAdaStr->iMaxLen = iMaxLen;
  pAdaStr->iLen = strlen(pStr);
  strcpy(pAdaStr->Text, 
         pStr);
  return  OK;
} 
#endif  /* #ifdef TEST_ENVIRONMENT */


/*----------------------------------------------------------
*    StripStr  - Removes leading and trailing whitespace 
*     returns  - string length
*---------------------------------------------------------                  */

INT32 UtlStripStr(char *pStr,INT32 iLen,INT32 iCheckNotEmpty,INT32 
                  iSetToUpper)
{
  INT32 iInd = 0;
  INT32 iNewSize = 0;
  char *pNext;

  pNext = pStr;

  /**************************************************************************/
  /* Skip whitespace                                                        */
  /**************************************************************************/

  while (isspace(pNext[iInd]) && (iInd <= iLen))
    {
      iInd++;
    } 
  if (iInd < iLen)                     /* blank string                      */
    {

      /**********************************************************************/
      /* copy rest of string                                                */
      /**********************************************************************/

      while ((iInd < iLen) && (pNext[iInd] != 0))
        {
          if (iSetToUpper)
            pStr[iNewSize] = toupper(pNext[iInd++]);
          else
            pStr[iNewSize] = pNext[iInd++];
          iNewSize++;
        } 
      iNewSize--;

      /**********************************************************************/
      /* find last none space                                               */
      /**********************************************************************/

      iInd = 0;
      while (isspace(pStr[iNewSize]))
        iNewSize--;

      /**********************************************************************/
      /* Set null termination after last none space                         */
      /**********************************************************************/

      iNewSize++;
      pStr[iNewSize] = 0;
    } 
  else
    *pStr = 0;
  if ((iCheckNotEmpty == TRUE) && (strlen(pStr) == 0))
    return  NOK;
  return  iNewSize;
} 


/*----------------------------------------------------------
*  UtlInitErrMsgTab - Read up error data from text file 
*                     to table  
*---------------------------------------------------------                  */

void UtlInitErrMsgTab()
{
  char ErrDataFile[30];
  FILE *ErrDataFilep;
  char Line[200];
  char *pLine;
  char *pErrVal;
  char *pConstName;
  char *pErrMsg;
  /* char *pDummy; */
  INT32 iInd = 0;
  char *pCommStart;
  char *pCommEnd;

  memset(ErrMsgTab, 
         0, 
         sizeof(ErrMsgTab));
  strcpy(ErrDataFile, 
         "nraderr.h");
  ErrDataFilep = fopen(ErrDataFile, 
                       "r");
  if (ErrDataFilep == NULL)
    printf("Missing file %s\n", 
           ErrDataFile);
  else
    fgets(Line, 
          sizeof(Line), 
          ErrDataFilep);
  while ((feof(ErrDataFilep) == 0) && (ErrDataFilep != 0L))
    {
      pLine = Line;
      if (strlen(Line) > 0)
        {
          /*pDummy = */strtok(pLine, 
                          " ,\t\r\f\n");
          pConstName = strtok(NULL, 
                              " ,\t\r\f\n");
          strcpy(ErrMsgTab[iInd].ConstName, 
                 pConstName);
          pErrVal = strtok(NULL, 
                           " ,\t\r\f\n");
          if (strlen(pErrVal) > 0)
            {
              sscanf(pErrVal, 
                     "0x%lx", 
                     &ErrMsgTab[iInd].iValue);
              pErrMsg = strtok(NULL, 
                               "\r\f\n");
              pCommStart = strstr(pErrMsg, 
                                  "/*");
              if (pCommStart == 0L)
                pCommStart = pErrMsg;
              else
                pCommStart += 2;
              pCommEnd = strstr(pErrMsg, 
                                "*/");
              if (pCommEnd != 0L)
                *pCommEnd = 0;
              strncpy(ErrMsgTab[iInd].ErrTxt, 
                      pCommStart, 
                      sizeof(ErrMsgTab[iInd].ErrTxt));
              iInd++;
            } 
        } 
      fgets(Line, 
            sizeof(Line), 
            ErrDataFilep);
    } 
  fclose(ErrDataFilep);
  ErrMsgTab[iInd].iValue = -1;
  strcpy(ErrMsgTab[iInd].ConstName, 
         "NOK");
  strcpy(ErrMsgTab[iInd].ErrTxt, 
         "Unsuccessful operation");
  iInd = MAX_ERR_CODES-1;
  ErrMsgTab[iInd].iValue = -1;
  strcpy(ErrMsgTab[iInd].ConstName, 
         "--------");
  strcpy(ErrMsgTab[iInd].ErrTxt, 
         "No message for this error no");
} 


/*----------------------------------------------------------
*  UtlSearchErrMsgTab - Find error text to given error code
*                       
*---------------------------------------------------------                  */

INT32 UtlSearchErrMsgTab(INT32 iErrNo,char *pConstname,char *pErrTxt)
{
  INT32 iInd = 0;

  while ((iInd < MAX_ERR_CODES) && (ErrMsgTab[iInd].iValue != 0))
    {
      if (ErrMsgTab[iInd].iValue == iErrNo)
        {
          strcpy(pConstname, 
                 ErrMsgTab[iInd].ConstName);
          strcpy(pErrTxt, 
                 ErrMsgTab[iInd].ErrTxt);
          return  iInd;
        } 
      iInd++;
    } 

  return -1;
} 

