215 lines
6.7 KiB
C
215 lines
6.7 KiB
C
/* OpenDoors Online Software Programming Toolkit
|
|
* (C) Copyright 1991 - 1999 by Brian Pirie.
|
|
*
|
|
* 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 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
|
|
*
|
|
*
|
|
* File: ODAuto.c
|
|
*
|
|
* Description: Implements od_autodetect() for automatic detection of
|
|
* terminal emulation supported by remote system.
|
|
*
|
|
* Revisions: Date Ver Who Change
|
|
* ---------------------------------------------------------------
|
|
* Oct 13, 1994 6.00 BP New file header format.
|
|
* Oct 14, 1994 6.00 BP Standardized coding style.
|
|
* Dec 31, 1994 6.00 BP Use new millisecond timer functions.
|
|
* Nov 12, 1995 6.00 BP 32-bit portability.
|
|
* Nov 13, 1995 6.00 BP Fixed non-functioning RIP autodetect.
|
|
* Nov 16, 1995 6.00 BP Removed oddoor.h, added odcore.h.
|
|
* Dec 12, 1995 6.00 BP Added entry, exit and kernel macros.
|
|
* Dec 30, 1995 6.00 BP Added ODCALL for calling convention.
|
|
* Feb 19, 1996 6.00 BP Changed version number to 6.00.
|
|
* Mar 03, 1996 6.10 BP Begin version 6.10.
|
|
* Aug 10, 2003 6.23 SH *nix support
|
|
*/
|
|
|
|
#define BUILDING_OPENDOORS
|
|
|
|
#include <string.h>
|
|
#include <ctype.h>
|
|
|
|
#include "OpenDoor.h"
|
|
#include "ODStr.h"
|
|
#include "ODTypes.h"
|
|
#include "ODGen.h"
|
|
#include "ODPlat.h"
|
|
#include "ODCore.h"
|
|
#include "ODKrnl.h"
|
|
|
|
|
|
/* Private function prototypes. */
|
|
static char ODWaitNoCase(char *pszWaitFor, tODMilliSec WaitTime);
|
|
|
|
|
|
/* Number of attempts and timeout values for testing each terminal emulation */
|
|
/* protocol. */
|
|
#define ANSI_TRIES 1
|
|
#define ANSI_WAIT 660 /* Time in milliseconds. */
|
|
#define RIP_TRIES 1
|
|
#define RIP_WAIT 660 /* Time in milliseconds. */
|
|
|
|
/* Strings to use for autodetection. */
|
|
#define ANSI_QUERY "\x1b[6n\r \r"
|
|
#define ANSI_RESPONSE "\x1b["
|
|
#define RIP_QUERY "\r\x1b[!\r \r"
|
|
#define RIP_RESPONSE "RIP"
|
|
|
|
/* Maximum number of characters to match with _waitnocase(). */
|
|
#define MATCH_LEN 3
|
|
|
|
|
|
/* ----------------------------------------------------------------------------
|
|
* od_autodetect()
|
|
*
|
|
* Determines the terminal emulation capabilities of the remote communications
|
|
* software, when possible. Turns on ANSI and/or RIP modes if they are
|
|
* supported by the remote system.
|
|
*
|
|
* Parameters: nFlags - Currently unused.
|
|
*
|
|
* Return: void
|
|
*/
|
|
ODAPIDEF void ODCALL od_autodetect(INT nFlags)
|
|
{
|
|
INT nCount;
|
|
|
|
/* Log function entry if running in trace mode. */
|
|
TRACE(TRACE_API, "od_autodetect()");
|
|
|
|
/* Initialize OpenDoors if it hasn't aready been done. */
|
|
if(!bODInitialized) od_init();
|
|
|
|
OD_API_ENTRY();
|
|
|
|
/* Temporary code that will be optimized out, which prevents a compiler */
|
|
/* warning from being generated for the currently unused flags parameter. */
|
|
(void)nFlags;
|
|
|
|
/* If operating in local mode, turn on ANSI mode, but not RIP. */
|
|
if(od_control.baud == 0)
|
|
{
|
|
od_control.user_ansi = TRUE;
|
|
OD_API_EXIT();
|
|
return;
|
|
}
|
|
|
|
/* If user_ansi is not set, attempt to determine ANSI capabilities. */
|
|
if(!od_control.user_ansi)
|
|
{
|
|
/* Clear inbound keyboard buffer. */
|
|
od_clear_keybuffer();
|
|
|
|
/* Try twice to test ANSI capabilities. */
|
|
for(nCount = 0; nCount < ANSI_TRIES; ++nCount)
|
|
{
|
|
/* Send a string that an ANSI capable terminal will usually */
|
|
/* respond to. */
|
|
od_disp(ANSI_QUERY, strlen(ANSI_QUERY), FALSE);
|
|
|
|
/* Wait for response expected from an ANSI terminal, for up to */
|
|
/* 12/18.2 second. */
|
|
if(ODWaitNoCase(ANSI_RESPONSE, ANSI_WAIT))
|
|
{
|
|
/* If expected sequence was received, turn on ANSI mode and */
|
|
/* exit the loop. */
|
|
od_control.user_ansi = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
od_clear_keybuffer();
|
|
}
|
|
|
|
/* If user_rip is not set, attempt to determine RIP capabilities. */
|
|
if(!od_control.user_rip)
|
|
{
|
|
/* Clear inbound keyboard buffer. */
|
|
od_clear_keybuffer();
|
|
|
|
/* Try twice to test RIP capabilities. */
|
|
for(nCount = 0; nCount < RIP_TRIES; ++nCount)
|
|
{
|
|
/* Send a string that a RIP capable terminal will usually */
|
|
/* respond to. */
|
|
od_disp(RIP_QUERY, strlen(RIP_QUERY), FALSE);
|
|
|
|
/* Wait for response expected from a RIP terminal. */
|
|
if(ODWaitNoCase(RIP_RESPONSE, RIP_WAIT))
|
|
{
|
|
/* If expected sequence was received, turn on RIP mode and */
|
|
/* exit the loop. */
|
|
od_control.user_rip = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
od_clear_keybuffer();
|
|
}
|
|
|
|
OD_API_EXIT();
|
|
}
|
|
|
|
|
|
/* ----------------------------------------------------------------------------
|
|
* ODWaitNoCase() *** PRIVATE FUNCTION ***
|
|
*
|
|
* Waits up to the specified maximum time for a specified string to be sent
|
|
* from the remote system. String matching is not case sensitive.
|
|
*
|
|
* Parameters: pszWaitFor - String to wait for.
|
|
*
|
|
* WaitTime - Maximum time, in milliseconds, to wait.
|
|
*
|
|
* Return: TRUE on success, FALSE on failure.
|
|
*/
|
|
static char ODWaitNoCase(char *pszWaitFor, tODMilliSec WaitTime)
|
|
{
|
|
tODTimer Timer;
|
|
char szReceived[MATCH_LEN + 1];
|
|
int nCount;
|
|
char chReceived;
|
|
int nMatchChars = MIN(MATCH_LEN, strlen(pszWaitFor));
|
|
|
|
ASSERT(pszWaitFor != NULL);
|
|
ASSERT(strlen(pszWaitFor) != 0);
|
|
ASSERT(WaitTime >= 0);
|
|
|
|
ODTimerStart(&Timer, WaitTime);
|
|
|
|
for(nCount = 0; nCount <= MATCH_LEN; ++nCount)
|
|
{
|
|
szReceived[nCount] = '\0';
|
|
}
|
|
|
|
do
|
|
{
|
|
if((chReceived = od_get_key(FALSE)) != 0)
|
|
{
|
|
for(nCount = 0; nCount < MATCH_LEN - 1; ++ nCount)
|
|
{
|
|
szReceived[nCount] = szReceived[nCount + 1];
|
|
}
|
|
szReceived[MATCH_LEN - 1] = chReceived;
|
|
|
|
if(strnicmp(szReceived + (MATCH_LEN - nMatchChars), pszWaitFor,
|
|
nMatchChars) == 0)
|
|
{
|
|
return(TRUE);
|
|
}
|
|
}
|
|
} while(!ODTimerElapsed(&Timer));
|
|
|
|
return(FALSE);
|
|
}
|