home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 3 Comm
/
03-Comm.zip
/
STERM.ZIP
/
STERMP.C
< prev
next >
Wrap
Text File
|
1991-01-14
|
15KB
|
675 lines
/* Process an STERM command file */
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#define INCL_SUB
#define INCL_DOS
#include <os2kernl.h>
#define STERMP
#include "sterm.h"
/* working copy of port definition */
static PortDef *wp;
/* ptr to command string */
static char *verb;
/* check for phone number */
static int phoncheck( void )
{
/* value must be numeric, '-', ',' */
char *fp;
fp = strtok( NULL, " ;\n" );
/* just uppercase and copy string */
if ( strlen ( fp ) > PHONEL-2 )
{
emsg( "Phone String too Long." );
return(9);
}
/* set phone string with CR */
strcpy( wp->phone, fp );
strupr( wp->phone );
strcat( wp->phone, "/r" );
return (0);
} /* end phoncheck */
/* ECHO: set halfplex TRUE or FALSE */
static int pecho( void )
{
char *fp;
fp = strtok( NULL, " ;\n" );
fp = strupr( fp );
if ( strcmp( fp, "ON" ) == 0 )
wp->halfplex = TRUE;
else
if ( strcmp( fp, "OFF" ) == 0 )
wp->halfplex = FALSE;
else
{
emsg( "ON or OFF required" );
return ( 2 );
}
return ( 0 );
} /* end pecho */
/* check for port number */
static int portcheck( void )
{
/* value must be 1-3 */
long dv;
char *fp, *ep;
int dval;
fp = strtok( NULL, " ;\n" );
dv = strtoul( fp, &ep, 0 );
if ( *ep != '\0' )
{
emsg( "Non-numeric Port" );
return( 4 );
}
dval = (int) dv;
if ( ( dval < 1 ) || ( dval > 3 ) )
{
emsg( "Invalid Port" );
return( 6 );
}
/* set port string with ascii num */
wp->cport[3] = (char) (dval + '0');
return (0);
} /* end portcheck */
/* verify stopbits and store */
static int stopcheck( void )
{
char * stbl[] =
{ "1", "1.5", "2", "\0" };
int s;
char *fp;
fp = strtok( NULL, " ;\n" );
fp = strupr( fp );
for ( s = 0; *stbl[s]; s++ )
if ( strcmp( stbl[s], fp ) == 0 )
{
wp->ltype.StopBits = (char) s;
return(0);
}
emsg( "Unknown Stop Value" );
return(8);
}
/* verify parity and store */
static int parcheck( void )
{
char * ptbl[] =
{ "NONE", "ODD", "EVEN", "MARK", "SPACE", "\0" };
int p;
char *fp;
fp = strtok( NULL, " ;\n" );
fp = strupr( fp );
for ( p = 0; *ptbl[p]; p++ )
if ( strcmp( ptbl[p], fp ) == 0 )
{
wp->ltype.Parity = (char) p;
return(0);
}
emsg( "Unknown Parity" );
return(7);
} /* end parcheck */
/* verify databits and store */
static int datcheck( void )
{
/* value must be 5-8 */
long dv;
char *fp, *ep;
int dval;
fp = strtok( NULL, " ;\n" );
dv = strtoul( fp, &ep, 0 );
if ( *ep != '\0' )
{
emsg( "Non-numeric Databits" );
return( 4 );
}
dval = (int) dv;
if ( ( dval < 5 ) || ( dval > 8 ) )
{
emsg( "Non-standard Databits" );
return( 6 );
}
wp->ltype.DataBits = (char) dval;
return (0);
} /* end datcheck */
/* verify BaudRate and store */
static int baudcheck( void )
{
unsigned int speed_vals[] =
{ 50, 75, 110, 135, 150, 300, 600, 1200,
1800, 2000, 2400, 3600, 4800, 7200, 9600, 19200,
28800, 0 }; /* zero for anchor */
char *fp, *ep;
long par;
int p;
/* next token should be a speed_val */
fp = strtok( NULL, " ;\n" );
par = strtoul( fp, &ep, 0 );
if ( *ep != '\0' )
{
emsg( "Non-numeric Baud" );
return( 3 );
}
for ( p=0; speed_vals[p] ; p++ )
if ( par == speed_vals[p] )
break;
if ( ! speed_vals[p] )
{
emsg( "Non-standard Baud" );
return( 2 );
}
wp->lspeed.BaudRate = (unsigned) par;
return ( 0 );
} /* end baudcheck */
/* static table for identifier - char mapping */
typedef struct
{
char *ident;
char *idchar;
} identry;
#define NULS ""
#define CR "\x0d\0"
#define LF "\x0a\0"
#define SOH "\x01\0"
#define STX "\x02\0"
#define ETX "\x03\0"
#define XON "\x11\0"
#define NIDS 6
static identry idtbl[NIDS] =
{ { "CR", CR }, { "ETX", ETX }, { "STX", STX },
{ "LF", LF }, { "XON", XON }, { "ANY", NULS } };
/* find quoted string or resolve identifier */
static char *nxtstr( char *vp )
{
char *fp;
int id;
fp = vp;
/* get the next string */
while ( ( *fp != '\n' ) && ( *fp == ' ' ) )
fp++;
if ( *fp == '\n' )
{
emsg( "No SEND data." );
return( NULL );
}
/* if start of quoted string, get that token */
if ( ( *fp == '\"' ) || ( *fp == '\'' ) )
{
fp = strtok( fp, "\"\'" );
if ( !fp )
return ( NULL );
}
else
{ /* fp -> identifier representing ctl char */
fp = strtok( fp, "\n;" );
if ( !fp )
return ( NULL );
fp = strupr( fp );
for ( id = 0; id < NIDS; id++ )
if ( strcmp( fp, idtbl[id].ident ) == 0 )
break;
if ( id >= NIDS )
{
emsg( "Unknown key Identifier" );
return( NULL );
}
fp = idtbl[id].idchar;
}
return ( fp );
} /* end nxtstr */
/* SEND: pass a string to port */
static int psend( void )
{
char *fp;
MsgH portmsg;
USHORT plen;
int clen;
if ( wp->beforex )
{ /* initialize port once */
wp->beforex = FALSE;
if ( setport( wp ) )
errexit( "Unable to Initialize" );
CurP = wp;
}
fp = nxtstr( verb+5 );
if ( !fp )
return ( 2 );
if ( ( clen = strlen( fp ) ) > WSLEN-2 )
return( 3 );
/* pump the string to comoW */
portmsg.mlen = clen;
if ( clen == 1 )
{
portmsg.mtype = immed;
portmsg.imdat = *fp;
}
else
portmsg.mtype = dhead; /* data header */
DosWrite( comoW, (PVOID) &portmsg, sizeof(MsgH), (PUSHORT) &plen );
if ( clen > 1 )
DosWrite( comoW, (PVOID) fp, clen, (PUSHORT) &plen );
return ( 0 );
} /* end psend */
#define NCOLOR 16
typedef struct {
char *colname; /* uppercase color name */
char color; /* color */
} vio_color;
static vio_color colentry[NCOLOR] =
{
{"BLACK", '\x00'},
{"BLUE", '\x01'},
{"GREEN", '\x02'},
{"CYAN", '\x03'},
{"RED", '\x04'},
{"MAGENTA", '\x05'},
{"BROWN", '\x06'},
{"WHITE", '\x07'},
{"GRAY", '\x08'},
{"LITEBLUE", '\x09'},
{"LITEGREEN", '\x0A'},
{"LITECYAN", '\x0B'},
{"LITERED", '\x0C'},
{"LITEMAGENTA", '\x0D'},
{"YELLOW", '\x0E'},
{"BRITE", '\x0F'},
};
/* COLOR: fg ON bg screen colors */
static int pcolor( void )
{
char *fp;
char tcol[33];
USHORT ix;
UCHAR bc, fc;
/* 1st token is foreground */
fp = strtok( NULL, " ;\n" );
strcpy( tcol, fp );
strupr( tcol );
for ( ix = 0; ix < NCOLOR; ix++ )
if ( strcmp( tcol, colentry[ix].colname ) == 0 )
break;
if ( ix >= NCOLOR )
{
emsg( "Unknown Color?!?");
return( NULL );
}
fc = colentry[ix].color;
/* 2nd token is background */
fp = strtok( NULL, " ;\n" );
strcpy( tcol, fp );
strupr( tcol );
if ( strcmp( tcol, "ON" ) == 0 )
{
fp = strtok( NULL, " ;\n" );
strcpy( tcol, fp );
strupr( tcol );
}
for ( ix = 0; ix < NCOLOR; ix++ )
if ( strcmp( tcol, colentry[ix].colname ) == 0 )
break;
if ( ix >= NCOLOR )
{
emsg( "Unknown Color?!?");
return( NULL );
}
bc = colentry[ix].color;
/* now build an attribute byte */
fldcolor = ( ( bc << 4 ) | fc );
clrscrn();
return ( 0 );
} /* end pcolor */
/* DELAY: sleep a specified amount */
static int pdelay( void )
{
char *fp, *ep;
long par;
/* next token should be interval */
fp = strtok( NULL, " ;\n" );
par = strtoul( fp, &ep, 0 );
if ( *ep != '\0' )
{
emsg( "Non-numeric Delay" );
return( 3 );
}
/* value in millisecs */
if ( par < 20 )
{
emsg( "Delay too small." ); return ( 4 );
}
DosSleep( par ); /* do it here */
return ( 0 );
}
/* AWAIT: wait for a string to arrive */
static int pwait( void )
{
char *fp;
USHORT rc; /* return code from WaitSem */
fp = nxtstr( verb+6 ); /* skip AWAIT */
if ( !fp )
return ( 2 );
strcpy( waitstr, fp );
waitsem = 0L;
waitlen = strlen( waitstr ); /* now armed */
if (!waitlen)
waitlen = 1; /* case of ANY */
/* wait 30 sec.? small window from 'waitlen' being set */
waitrc = AWAIT_OK; /* assume fine */
rc = DosSemSetWait( (HSEM) &waitsem, timelim );
if ( rc == 0 )
return( waitrc );
else
return( AWAIT_EOJ );
} /* end pwait */
/* COMLOG: set/reset port log */
static int logcheck( void )
{
char *fp;
char tterm[12];
fp = strtok( NULL, " \n;" );
strcpy( tterm, fp );
strupr( tterm );
if ( strcmp( tterm, "ON" ) == 0 )
ComLog = TRUE;
else
if ( strcmp ( tterm, "OFF" ) == 0 )
ComLog = FALSE;
else
emsg( "Invalid ComLog Option" );
return( 0 );
} /* end termcheck */
/* TIMELIM: set 'await' timeout */
static int ptimelim( void )
{
char *fp, *ep;
LONG tval;
fp = strtok( NULL, " \n;" );
tval = strtol( fp, &ep, 10 );
if ( ( tval < 1000 ) || ( tval > 500000 ) )
{
emsg( "Invalid Timelim Value" );
return( AWAIT_WARN );
}
timelim = tval;
return( 0 );
} /* end termcheck */
/* TERMINAL: set emulation type */
static int termcheck( void )
{
char *fp;
char tterm[12];
fp = strtok( NULL, " \n;" );
strcpy( tterm, fp );
strupr( tterm );
if ( strcmp( tterm, "TTY" ) == 0 )
{
keymode = tty; return ( 0 );
}
else
if ( strcmp ( tterm, "SIMVT" ) == 0 )
{
keymode = SIMVT; return ( 0 );
}
emsg( "Invalid Terminal Emulator" );
return( 8 );
} /* end termcheck */
/* build 3270 key translate tbl */
static int p3270key( void )
{
PUCHAR ntbl, fp;
fp = (PUCHAR) strtok( NULL, " \n;" );
ntbl = prockey( fp );
if ( !ntbl )
errexit( "Key Table Build Error" );
Sim3270 = (PUCHAR *) ntbl;
} /* end p3270key */
/* have the host send a file on the VTSIM interface
'VTSEND fn ft fm' */
static int vtsend( void )
{
/* we must be in SIMVT keymode now */
if ( keymode != SIMVT )
{
emsg( "Must be in SIMVT mode" );
return( 8 );
}
/* obtain a blokchar and link it */
/* obtain a transfil area, plant it in global 'blkp' */
if ( !blkp )
{
blkp = (transfil *) malloc( sizeof(transfil) );
blkp->buf = (blokchar *) malloc( sizeof(blokchar) );
blkp->nextb = NULL;
blkp->bufp = (char *) blkp->buf;
}
/* set xstate to VTSEND */
xstate = VTSEND;
/* send command to host */
/* wait for ACK */
/* if we timed out, or host err, change state to TERM,
give error msg and exit */
return( 0 );
} /* end vtsend */
/* parsing vector table */
typedef struct {
char *verbn; /* uppercase cmd name */
int (*verbf)( void ); /* process function */
} verb_entry;
#define NVERBS 15 /* total cmds */
static verb_entry verb_tbl[NVERBS] =
{ { "PARITY", parcheck },
{ "DATABITS", datcheck },
{ "STOPBITS", stopcheck },
{ "PORT", portcheck },
{ "TERMINAL", termcheck },
{ "TIMELIM", ptimelim },
{ "COMLOG", logcheck },
{ "PHONE", phoncheck },
{ "DELAY", pdelay },
{ "COLOR", pcolor },
{ "ECHO", pecho },
{ "SEND", psend },
{ "3270KEYS", p3270key },
{ "AWAIT", pwait },
{ "SPEED", baudcheck } };
/* search for verb and execute statement
input is command verb string
*/
PREF int verbex( PCHAR instmt )
{
char estr[WSLEN];
int i, rc;
/* isolate the 1st token == verb */
verb = strtok( instmt, " ;\n" );
verb = strupr( verb );
if ( *verb == '*' )
return( AWAIT_OK );
for ( i = 0; i < NVERBS; i++ )
if ( strcmp( verb, verb_tbl[i].verbn ) == 0 )
{ /* call verb function */
#pragma warn(wpnd => off)
rc = (*verb_tbl[i].verbf)( );
#pragma warn(wpnd => err)
if ( rc != AWAIT_OK )
{
sprintf( estr, "\nVerb %s returned %d", verb, rc );
emsg( estr );
if ( strcmp( verb, "AWAIT" ) == 0 )
{
sprintf( estr, " was waiting for %s.", waitstr );
sprintf( estr, " compbuf: %.132s", compbuf );
emsg( estr );
}
}
return( rc );
}
sprintf( estr, "Unknown command verb: %s", verb );
emsg( estr );
return( AWAIT_ENDP - 1 );
} /* end verbex */
/* process definition file
cmds of the form verb obj0 obj1 ...
port: either 1,2,or 3
stopbits: either 1,1.5, or 2
databits: 5-8
parity: even, odd, none, mark, space
Input: definition filespec
Returns: ptr to PortDef
*/
PREF PortDef *defile( PCHAR pfn )
{
FILE *dfhand; /* def file handle */
#define MAXSTMT 140
char iline[MAXSTMT];
char filn[MAXSTMT];
char *fn;
int hiret, rc;
hiret = 0;
/* copy file path to filn, uppercase it
then if no extension given, add .PRM */
strcpy( filn, pfn );
fn = filn;
strupr( fn );
if ( strchr( fn, '.' ) == NULL )
strcat( fn, ".PRM" );
dfhand = fopen( fn, "r" );
if ( dfhand == NULL )
errexit( "Definition file not found." );
/* TBD
Read into memory and
display list of connections in definition
file, then open the .PRM file which
represents that connection
*/
wp = (PortDef *) malloc( sizeof( PortDef ) );
wp->cport = (PSZ) "COM1"; /* set default port */
wp->beforex = TRUE; /* no xmit yet */
wp->halfplex = FALSE; /* no echo */
/* set default line characteristics */
wp->lspeed.BaudRate = 2400;
wp->ltype.DataBits = 7;
wp->ltype.Parity = 2; /* even */
wp->ltype.StopBits = 0; /* 1 */
/* read parm file lines until eof or error */
verb = fgets( iline, MAXSTMT-1, dfhand );
while ( verb )
{
rc = verbex( verb );
if ( rc > hiret )
hiret = rc;
if ( hiret >= AWAIT_ENDP )
break;
verb = fgets( iline, MAXSTMT-1, dfhand );
} /* endwhile */
fclose( dfhand );
if ( hiret > AWAIT_ENDP )
{
free( (void *) wp );
errexit( "Initialization Failed...." );
return( NULL );
}
/* we had successful process of parms, but
if no 'SEND' occurred, the port is useless */
if ( wp->beforex )
{ /* initialize port once */
wp->beforex = FALSE;
if ( setport( wp ) )
errexit( "Unable to Initialize" );
}
return ( wp );
} /* end defile */