.ad 8
.bm 8
.fm 4
.bt $Copyright by   Software AG, 1993$$Page %$
.tm 12
.hm 6
.hs 3
.tt 1 $NME$Project Distributed Database System$vos44c$
.tt 2 $$$
.tt 3 $R.Roedling$miscellaneous device/file functions$1996-03-12$
***********************************************************
.nf


    ========== licence begin LGPL
    Copyright (C) 2002 SAP AG

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

    This library 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
    Lesser General Public License for more details.

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

.fo
.nf
.sp
Module  : miscellaneous device/file functions
=========
.sp
Purpose :
.CM *-END-* purpose -------------------------------------
.sp
.cp 3
Define  :

.CM *-END-* define --------------------------------------
.sp;.cp 3
Use     :

.CM *-END-* use -----------------------------------------
.sp;.cp 3
Synonym :

.CM *-END-* synonym -------------------------------------
.sp;.cp 3
Author  : R. Roedling
.sp
.cp 3
Created : 03.03.93
.sp
.cp 3
Version :
.sp
.cp 3
Release :  6.2 	 Date : 1996-03-12
.br
.sp
***********************************************************
.sp
.cp 10
.fo
.oc _/1
Specification:

.CM *-END-* specification -------------------------------
.sp 2
***********************************************************
.sp
.cp 10
.fo
.oc _/1
Description:

.CM *-END-* description ---------------------------------
.sp 2
***********************************************************
.sp
.cp 10
.nf
.oc _/1
Structure:

.CM *-END-* structure -----------------------------------
.sp 2
**********************************************************
.sp
.cp 10
.nf
.oc _/1
.CM -lll-
Code    :
/*PRETTY*/
/*
 * MODULE - sql44c_subst_log_parts
 */

/*
 * INCLUDE FILES
 */


/*
 *  DEFINES
 */
#define MOD__  "VOS44C : "
#define MF__   MOD__"UNDEFINED"

#if defined(_WIN32)
 #define TAPE_ID_STR          "TAPE"
 #define TAPE_ID_LEN          (sizeof(TAPE_ID_STR) - 1)

 #define CONOUT_ID_STR        "CONOUT$"
 #define CONIN_ID_STR         "CONIN$"
#endif

#define PIPE_ID_STR          "PIPE\\"
#define PIPE_ID_LEN          (sizeof(PIPE_ID_STR) - 1)

#define SKIP_NODE(_out,_in)  {_out = (_in[0] == '\\' && _in[1] == '\\') ?   \
                                        strchr( &_in[2], '\\') : NULL;      \
                              _out = (_out != NULL && _out[0] != '\0' ) ?   \
                                        _out + 1 : NULL; }

#define CON_ID_STR            "CON"
#define CON_ID_LEN            (sizeof(CON_ID_STR) - 1)
#define PRN_ID_STR            "PRN"
#define PRN_ID_LEN            (sizeof(PRN_ID_STR) - 1)
#define COM_ID_STR            "COM"
#define COM_ID_LEN            (sizeof(COM_ID_STR) - 1)
#define LPT_ID_STR            "LPT"
#define LPT_ID_LEN            (sizeof(LPT_ID_STR) - 1)
#define NUL_ID_STR            "NUL"
#define NUL_ID_LEN            (sizeof(NUL_ID_STR) - 1)

#if defined(_WIN32)
  #define FILESIZELOW  InfoBuf.nFileSizeLow
  #define FILESIZEHIGH InfoBuf.nFileSizeHigh
  #define FILEATTR     InfoBuf.dwFileAttributes
#else
  #define FILESIZELOW  InfoBuf.cbFile
  #define FILESIZEHIGH 0
  #define FILEATTR     InfoBuf.attrFile
#endif


/*
 * EXTERNAL VARIABLES
 */


/*
 * LOCAL VARIABLES
 */


/*
 * LOCAL FUNCTION PROTOTYPES
 */


/*
 * ========================== GLOBAL FUNCTIONS ================================
 */

LONG sql44c_get_dev_type_by_filename ( PSZ pszName )
  {
  #undef  MF__
  #define MF__ MOD__"sql44c_get_dev_type_by_filename"
  LONG      DevType   = DT_OTHER;
  PATHNAME  szName;
  CHAR      szNum[5]  = "";
  LONG      lNum;
  PSZ       pszID;
  #if defined(_WIN32)
   CHAR     cAny     = ' ';
  #endif

  DBGPAS;

  // --- Convert diagnostic file name to uppercase
  strncpy (szName, pszName, sizeof (PATHNAME) - 1);
  szName[sizeof(PATHNAME)] = '\0';
  strupr(szName);

  #if defined(_WIN32)
   //
   // --- TAPE
   //
   SKIP_NODE( pszID, szName);  // --- try to skip node name

   if (( pszID != NULL ) &&
       (!strncmp( TAPE_ID_STR, pszID, TAPE_ID_LEN)))
     {
     lNum = sscanf ( pszID + TAPE_ID_LEN,
                     "%4[0123456789]%c", szNum, &cAny );

     if ( lNum == 1 )
       {
       DevType = DT_TAPE;
       DBG3 ((MF__, "DevType:  TAPE"));
       return (DevType);
       }
     }

   //
   // --- DRIVE
   //
   if (( szName[0] == '\\' ) && ( szName[1] == '\\' ) &&
       ( szName[2] == '.'  ) && ( szName[3] == '\\' ) &&
        isalpha( szName[4] ) && ( szName[5] == ':'  ) &&
       ( szName[6] == '\0' ))
     {
     DevType = DT_DRIVE;
     DBG3 ((MF__, "DevType:  DRIVE"));
     return (DevType);
     }

   //
   // --- CONSOLE
   //
   if (!strcmp( CONOUT_ID_STR, szName ))
     {
     DevType = DT_CONOUT;
     DBG3 ((MF__, "DevType:  CONSOLE"));
     return (DevType);
     }

   if (!strcmp( CONIN_ID_STR, szName ))
     {
     DevType = DT_CONIN;
     DBG3 ((MF__, "DevType:  CONSOLE"));
     return (DevType);
     }
  #else
   //
   // --- LOCAL PIPE ( '\PIPE\<pipename>')
   //
   if (!strncmp( "\\"PIPE_ID_STR, szName, PIPE_ID_LEN + 1))
     {
     DevType = DT_PIPE;
     DBG3 ((MF__, "DevType:  PIPE"));
     return (DevType);
     }

   //
   // --- DRIVE
   //
   if ( isalpha( szName[0] ) && ( szName[1] == ':' ) && ( szName[2] == '\0'))
     {
     DevType = DT_DRIVE;
     DBG3 ((MF__, "DevType:  DRIVE"));
     return (DevType);
     }

  #endif

  //
  // --- PIPE ( '\\<nodename>\PIPE\<pipename>' )
  //
  SKIP_NODE( pszID, szName);  // --- try to skip node name

  if (( pszID != NULL ) &&
      (!strncmp( PIPE_ID_STR, pszID, PIPE_ID_LEN)))
    {
    DevType = DT_PIPE;
    DBG3 ((MF__, "DevType:  PIPE"));
    return (DevType);
    }


  //
  // --- CONSOLE
  //
  if (( !strncmp (CON_ID_STR, szName, CON_ID_LEN) ) &&
      ((( szName[CON_ID_LEN] == '.' ) && ( szName[CON_ID_LEN + 1] == '\0')) ||
       (( szName[CON_ID_LEN] == ':' ) && ( szName[CON_ID_LEN + 1] == '\0')) ||
       ( szName[CON_ID_LEN] == '\0' ) ))
    {
    DevType = DT_CON;
    DBG3 ((MF__, "DevType:  CONSOLE"));
    return (DevType);
    }

  //
  // --- PRINTER
  //
  if (( !strncmp (PRN_ID_STR, szName, PRN_ID_LEN) ) &&
      ((( szName[PRN_ID_LEN] == '.' ) && ( szName[PRN_ID_LEN + 1] == '\0')) ||
       (( szName[PRN_ID_LEN] == ':' ) && ( szName[PRN_ID_LEN + 1] == '\0')) ||
       ( szName[PRN_ID_LEN] == '\0' ) ))
    {
    DevType = DT_PRN;
    DBG3 ((MF__, "DevType:  PRN"));
    return (DevType);
    }

  //
  // --- NUL
  //
  if (( !strncmp (NUL_ID_STR, szName, NUL_ID_LEN) ) &&
      (( szName[NUL_ID_LEN] == '.' ) ||
       (( szName[NUL_ID_LEN] == ':' ) && ( szName[NUL_ID_LEN + 1] == '\0')) ||
       ( szName[NUL_ID_LEN] == '\0' ) ))
    {
    DevType = DT_NUL;
    DBG3 ((MF__, "DevType:  NUL"));
    return (DevType);
    }

  //
  // --- COM-Port
  //
  if (!strncmp( COM_ID_STR, szName, COM_ID_LEN ))
    {
    sscanf ( szName + COM_ID_LEN, "%4[0123456789]", szNum );

    lNum = strlen ( szNum );

    if (( lNum > 0 ) &&
        ((( szName[COM_ID_LEN + lNum]   == '.'  ) &&
          ( szName[COM_ID_LEN + lNum + 1] == '\0' )) ||
         (( szName[COM_ID_LEN + lNum]   == ':'  ) &&
          ( szName[COM_ID_LEN + lNum + 1] == '\0' )) ||
         ( szName[COM_ID_LEN + lNum]   == '\0' )))
      {
      DevType = DT_COMx;
      DBG3 ((MF__, "DevType:  DT_COMx"));
      return (DevType);
      }
    }

  //
  // --- LPT-Port
  //
  if (!strncmp( LPT_ID_STR, szName, LPT_ID_LEN ))
    {
    sscanf ( szName + LPT_ID_LEN, "%4[0123456789]", szNum );

    lNum = strlen ( szNum );

    if (( lNum > 0 ) &&
        ((( szName[LPT_ID_LEN + lNum]   == '.'  ) &&
          ( szName[LPT_ID_LEN + lNum + 1] == '\0' )) ||
         (( szName[LPT_ID_LEN + lNum]   == ':'  ) &&
          ( szName[LPT_ID_LEN + lNum + 1] == '\0' )) ||
         ( szName[LPT_ID_LEN + lNum]   == '\0' )))
      {
      DevType = DT_LPTx;
      DBG3 ((MF__, "DevType:  DT_LPTx"));
      return (DevType);
      }
    }

  return (DevType);
  }

/*------------------------------*/

/*
 *
 * sql44c_subst_log_parts
 *
 * Example:
 *    input : %DBROOT%\xpath
 *    output: d:\vdn\usr\xpath
 *
 */

BOOL sql44c_subst_log_parts ( PSZ  pszOutName,
                              PSZ  pszInName )
  {
  #undef  MF__
  #define MF__ MOD__"sql44c_subst_log_parts"

  PATHNAME                               szVarName;
  PSZ                                    pszResult;
  PCHAR                                  pch1stPercent;
  PCHAR                                  pch2ndPercent;
  size_t                                 cbLength;
  INT                                    cbOutLength;

  DBGIN;

  /*
   * Initialization
   */
  cbOutLength   = 0;
  pch2ndPercent = pszInName - 1;
  pch1stPercent = strchr (pszInName, '%');             /* beginning of env.var.*/

  while (pch1stPercent)
    {
    cbLength     = pch1stPercent - pch2ndPercent - 1;
    cbOutLength += cbLength;

    if (cbOutLength > sizeof (PATHNAME))
      {
      strcpy (pszOutName, pszInName);
      return (FALSE);
      }

    strncpy (pszOutName, pch2ndPercent+1, cbLength);
    pszOutName  += cbLength;

    pch2ndPercent  = strchr (pch1stPercent+1, '%');    /* end of env. var.*/

    if (pch2ndPercent)
      {
      /*
       * environment variable found:
       * scan environment for result string
       */
      cbLength = pch2ndPercent - pch1stPercent - 1;
      strncpy (szVarName, pch1stPercent+1, cbLength);
      strupr  (szVarName);
      *(szVarName+cbLength) = '\0';

      GETENV ( szVarName, &pszResult );

      if (pszResult != NULL)
        {
        DBG3 ((MF__, "EnvVar: '%s' = '%s'", szVarName, pszResult));
        /*
         * replace environment variable by result string
         */
        cbLength     = strlen (pszResult);
        cbOutLength += cbLength;

        if (cbOutLength > sizeof(PATHNAME))
          {
          strcpy (pszOutName, pszInName);
          return (FALSE);
          }

        strcpy (pszOutName, pszResult);
        pszOutName  += cbLength;
        }
      else
        {
        DBG3 ((MF__, "Environment variable '%s' no found", szVarName));
        /*
         * environment variable not set:
         * take %....% as part of filename
         */
        cbLength    += 2;
        cbOutLength += cbLength;

        if (cbOutLength > sizeof(PATHNAME))
          {
          strcpy (pszOutName, pszInName);
          return (FALSE);
          }

        strncpy (pszOutName, pch1stPercent, cbLength);
        pszOutName  += cbLength;
        }
        /*
         * search for next environment variable
         */
        pch1stPercent = strchr (pch2ndPercent+1, '%');
      }
    else
      {
      /*
       * % was not matched by another %
       * take %.... as part of filename
       */
      cbOutLength  += strlen (pch1stPercent);

      if (cbOutLength > sizeof(PATHNAME))
        {
        strcpy (pszOutName, pszInName);
        return (FALSE);
        }


      strcpy (pszOutName, pch1stPercent);
      pch1stPercent = 0;
      }
    }
  /*
   * copy remaining characters
   */
  if (pch2ndPercent)
    {
    cbOutLength  += strlen (pch2ndPercent+1);

    if (cbOutLength > sizeof(PATHNAME))
      {
      strcpy (pszOutName, pszInName);
      return (FALSE);
      }

    strcpy (pszOutName, pch2ndPercent+1);
    }

  DBGOUT;

  return (TRUE);
  }

/*------------------------------*/

// --- Gets the filemode of the node specified by fname
LONG sql44c_get_file_info ( PCHAR  pszFName,
                            PLONG  plAtt,
                            ULONG  *pFSizeLow,
                            ULONG  *pFSizeHigh )
  {
  #undef  MF__
  #define MF__  MOD__"sql44_get_file_info"

  #if defined(_WIN32)
   BY_HANDLE_FILE_INFORMATION InfoBuf;
   HANDLE                     FileHandle;
  #else
   ULONG                      InfoLevel;      /* Data required */
   FILESTATUS3                InfoBuf;        /* File info buffer */
   ULONG                      InfoBufSize;    /* Data buffer size */
  #endif
  APIRET                       rc = NO_ERROR;  /* Return code */

  DBGIN;

  *pFSizeLow  = 0;
  *pFSizeHigh = 0;

  #if defined(_WIN32)
   FileHandle = CreateFile(pszFName,
                           GENERIC_READ,
                           FILE_SHARE_READ | FILE_SHARE_WRITE,
                           NULL,
                           OPEN_EXISTING,
                           0,  //... file attributes seem to be ignored
                           NULL);
   if (FileHandle == INVALID_HANDLE_VALUE)
     rc = GetLastError();
   else
     {
     if (!GetFileInformationByHandle(FileHandle, &InfoBuf))
       rc = GetLastError();
     CloseHandle(FileHandle);
     }

   // --- remove some flags
   FILEATTR &= ~FILE_ARCHIVED;

  #else
   InfoLevel   = 1;       /* Indicate that Level 1 information is desired   */
   InfoBufSize = sizeof(FILESTATUS3);

   //
   // On successful return, the Level 1 directory
   // information is in the InfoBuf buffer
   //
   rc = DosQueryPathInfo(pszFName, InfoLevel, &InfoBuf, InfoBufSize);

   // --- remove the archived flag
   FILEATTR &= ~FILE_ARCHIVED;
  #endif


  if (rc == ERROR_FILE_NOT_FOUND)
    {
    *plAtt      = FILE_NORMAL;
    *pFSizeLow  = 0;
    *pFSizeHigh = 0;
    }
  else if (rc != 0)
    {
    *plAtt = UNDEF;
    }
  else if ((FILEATTR & FILE_DIRECTORY) == FILE_DIRECTORY)
    {
    *plAtt = FILE_DIRECTORY;
    *pFSizeLow  = 0;
    *pFSizeHigh = 0;
    }
  else if (((FILEATTR & FILE_SYSTEM)     == FILE_SYSTEM)     ||
           ((FILEATTR & FILE_READONLY)   == FILE_READONLY)   ||
           ((FILEATTR & FILE_HIDDEN)     == FILE_HIDDEN)     ||
           ((FILEATTR & FILE_COMPRESSED) == FILE_COMPRESSED) ||
           ((FILEATTR == FILE_NORMAL) || (FILEATTR == 0)))
    {
    *plAtt      = FILEATTR;
    *pFSizeLow  = ((ULONG) FILESIZELOW);
    *pFSizeHigh = ((ULONG) FILESIZEHIGH);
    }
  else
    {
    *plAtt = UNDEF;
    DBG1 ((MF__, "Unknown attribute: %d", FILEATTR ));
    }

  DBGOUT;
  return ( rc );
  }

/*
 * ========================== LOCAL FUNCTIONS =================================
 */
.CM *-END-* code ----------------------------------------
.SP 2
***********************************************************
