home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Meeting Pearls 3
/
Meeting_Pearls_III.iso
/
Pearls
/
tcp
/
Networking
/
TCP
/
Server
/
telser
/
src
/
tstelnet.c
next >
Wrap
C/C++ Source or Header
|
1995-03-06
|
14KB
|
433 lines
/*****************************************************************************\
* *
* tstelnet.c -- telnet program for telser.device *
* *
* Copyright (c) 1994-1995 by Sam Yee. *
* Source freely distributable in unmodified form. *
* *
* $ Author: Sam Yee (samy@sfu.ca) $ *
* $ Project: telser $ *
* $ Date Started: October 30, 1994 $ *
* $ Version: 1.20 (5.3.95) $ *
* *
* History: *
* Ver. YY/MM/DD Who Modifications *
* --------------------------------------------------------------------------- *
* 1.20 95/03/05 Sam Yee Prompts user for host if not specified on *
* command line *
* three escapes will kill session *
* 1.10 95/01/16 Sam Yee Three breaks will kill session *
* 1.00 95/01/01 Sam Yee Original release *
* *
\*****************************************************************************/
#include <clib/dos_protos.h>
#include <clib/exec_protos.h>
#include <dos/dosasl.h>
#include <devices/serial.h>
#include <pragmas/dos_pragmas.h>
#include <pragmas/exec_pragmas.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define RAWIN_RUNTIME
#include <RawIN.h>
/********************************************************************/
/* imports */
extern struct DOSBase *DOSBase;
extern struct SysBase *SysBase;
/********************************************************************/
/* prototypes */
ULONG ScanSerial(struct IOExtSer *ser_rreq, struct IOExtSer *ser_oreq,
char *buf, ULONG buf_len);
void SendSerReadRequest(struct IOExtSer *req, char *c);
void SendSerWriteRequest(struct IOExtSer *req, char *buf, ULONG buf_len);
void AbortReq(struct IORequest *req);
void sprintf(char *buf, char *fmt,...);
/********************************************************************/
void __regargs __chkabort(void); /* disable SAS/C ^C checking */
void __regargs __chkabort(){}
void __regargs _CXBRK(void);
void __regargs _CXBRK(){}
const char version[] = "\0$VER: tstelnet 1.20 (6.3.95)";
/********************************************************************/
/* where the action starts */
int
main(int argc,
char *argv[])
{
struct Library *RawINBase = NULL; /* std i/o handling library */
struct Line *line = NULL; /* line buffer */
struct IOExtSer *ser_rreq = NULL, /* serial stuff */
*ser_wreq = NULL,
*ser_oreq = NULL;
struct MsgPort *ser_rport = NULL,
*ser_wport = NULL,
*ser_oport = NULL;
char device[64] = "telser.device",
*s,
*prog_name,
buf[256], /* these three buffers must be the same size! */
ser_wbuf[256],
raw_buf[256],
*host = NULL,
host_buf[256],
ser_char; /* for serial reads */
ULONG wait_mask;
int unit = 0,
host_arg_num = 1,
port = 23,
i,
read_len,
error_code = 0,
break_count = 0;
BOOL show_usage = FALSE,
got_stuff,
typed,
ser_wrote = FALSE,
device_specified = FALSE,
typed_ctrl_c,
typed_esc,
broke = FALSE,
ser_opened = FALSE;
prog_name = FilePart(argv[0]);
if ((argc == 2) && (!stricmp(argv[1],"-h") || !strcmp(argv[1],"?")))
show_usage = TRUE;
else if (!strnicmp(argv[host_arg_num],"-d",2))
{
device_specified = TRUE;
s = argv[host_arg_num] + 2;
i = 0;
while (*s && (i < sizeof(device)-1) && (*s != ','))
device[i++] = *s++;
device[i] = '\0';
if (*s)
unit = atol(++s);
host_arg_num++;
}
/* host specified? */
if (host_arg_num < argc)
{
host = argv[host_arg_num];
if (host_arg_num < (argc-1))
port = atol(argv[host_arg_num+1]);
}
if (show_usage)
Printf("Usage: %s [-ddevice,unit] host-name [port]\n",prog_name);
else if (!(ser_rport = CreateMsgPort()) ||
!(ser_wport = CreateMsgPort()) ||
!(ser_oport = CreateMsgPort()))
{
Printf("%s: no memory for message ports\n",prog_name);
error_code = 10;
}
else if (!(ser_rreq = CreateIORequest(ser_rport,sizeof(struct IOExtSer))) ||
!(ser_wreq = CreateIORequest(ser_wport,sizeof(struct IOExtSer))) ||
!(ser_oreq = CreateIORequest(ser_oport,sizeof(struct IOExtSer))))
{
Printf("%s: no memory for io requests\n",prog_name);
error_code = 10;
}
else
{
if (device_specified)
{
if (OpenDevice(device,unit,(struct IORequest *)ser_rreq,0L))
error_code = 10;
}
else
{
ser_rreq->io_SerFlags = 0;
for (i = unit; i < (unit+20);i++)
{
if (CheckSignal(SIGBREAKF_CTRL_C))
{
PrintFault(ERROR_BREAK,FilePart(argv[0]));
error_code = 10;
broke = TRUE;
break;
}
if (!OpenDevice(device,i,(struct IORequest *)ser_rreq,0L))
{
ser_opened = TRUE;
break;
}
}
if (i == (unit+20))
error_code = 10;
unit = i;
}
if (error_code && !broke)
Printf("%s: cannot open device %s, unit %ld\n",prog_name,device,unit);
}
if (!error_code && !show_usage)
{
if (!(RawINBase = OpenLibrary(RAWIN_NAME,0)))
{
Printf("%s: " RAWIN_NAME " not found\n",prog_name);
error_code = 10;
}
}
if (RawINBase)
{
if (!(line = RI_AllocLine(2,2)))
{
Printf("%s: no memory for line buffer\n",prog_name);
error_code = 10;
}
else if (!host)
{
Printf("Telnet Host: "); Flush(Output());
i = RI_Gets(line,host_buf,sizeof(host_buf),0,FALSE,FALSE,TRUE);
Printf("\r\n");
if (i > 1)
{
Printf("Port [%ld]: ",port); Flush(Output());
i = RI_Gets(line,buf,6,0,FALSE,FALSE,TRUE);
Printf("\r\n");
if (i >= 0)
{
Printf("*** Press Esc Esc Esc to exit\r\n\r\n");
if (i)
port = atoi(buf);
host = host_buf;
}
}
}
}
if (line && host)
{
CopyMem(ser_rreq,ser_wreq,sizeof(struct IOExtSer));
CopyMem(ser_rreq,ser_oreq,sizeof(struct IOExtSer));
ser_wreq->IOSer.io_Message.mn_ReplyPort = ser_rport;
ser_oreq->IOSer.io_Message.mn_ReplyPort = ser_oport;
ser_oreq->io_Baud = 19200; /* set the baud rate */
ser_oreq->io_RBufLen = 4096L;
ser_oreq->IOSer.io_Command = SDCMD_SETPARAMS;
DoIO((struct IORequest *)ser_oreq);
SendSerReadRequest(ser_rreq,&ser_char);
sprintf(ser_wbuf,"ATDT %s",host);
if (port)
sprintf(ser_wbuf+strlen(ser_wbuf),",%ld",port);
Printf("Trying %s...\r\n",host); Flush(Output());
strcat(ser_wbuf,"\r");
SendSerWriteRequest(ser_wreq,ser_wbuf,strlen(ser_wbuf));
ser_wrote = TRUE;
typed = TRUE;
RI_SendReadRequest(line);
wait_mask = SIGBREAKF_CTRL_C |
(1L << ser_rport->mp_SigBit) |
(1L << ser_wport->mp_SigBit) |
(1L << line->ReadReplyPort->mp_SigBit);
while (!(line->flags & (LNF_EOF|LNF_BREAKC|LNF_READERROR|LNF_WRITEERROR)))
{
typed_ctrl_c = typed_esc = got_stuff = FALSE;
/* get user input */
if ((read_len = RI_GetBlock(line,FALSE,FALSE,buf,sizeof(buf))) > 0L)
{
got_stuff = TRUE;
if (buf[0] == 0x1b)
{
break_count++;
typed_esc = TRUE;
}
else if (buf[0] == 0x03)
typed_ctrl_c = TRUE;
if (ser_wrote) /* already wrote something? if so, wait! */
WaitIO((struct IORequest *)ser_wreq);
memcpy(ser_wbuf,buf,read_len);
SendSerWriteRequest(ser_wreq,ser_wbuf,read_len);
ser_wrote = TRUE;
if (break_count != 3)
typed = TRUE;
}
if (GetMsg(ser_wport)) /* a write reply? */
ser_wrote = FALSE;
/* read from serial port as much as possible */
if (read_len = ScanSerial(ser_rreq,ser_oreq,buf,sizeof(buf)))
{
got_stuff = TRUE;
RI_WaitWrite(line); /* wait for a write to finish if needed */
memcpy(raw_buf,buf,read_len);
RI_SendWriteRequest(line,raw_buf,read_len);
}
/* if user typed key(s), send next read request */
if (typed)
{
RI_SendReadRequest(line);
typed = FALSE;
}
if (got_stuff)
{
if (!typed_ctrl_c && !typed_esc)
break_count = 0;
continue;
}
if (Wait(wait_mask) & SIGBREAKF_CTRL_C)
break_count++;
if (break_count == 3)
break;
}
AbortReq((struct IORequest *)ser_rreq);
}
if (ser_opened)
CloseDevice((struct IORequest *)ser_rreq);
/* cleanup */
if (ser_rreq)
DeleteIORequest((struct IORequest *)ser_rreq);
if (ser_wreq)
DeleteIORequest((struct IORequest *)ser_wreq);
if (ser_oreq)
DeleteIORequest((struct IORequest *)ser_oreq);
if (ser_rport)
DeleteMsgPort(ser_rport);
if (ser_wport)
DeleteMsgPort(ser_wport);
if (ser_oport)
DeleteMsgPort(ser_oport);
if (line)
RI_FreeLine(line);
if (RawINBase)
CloseLibrary(RawINBase);
return(error_code);
}
/****************************************************************************/
/* grab bytes from serial port if any */
ULONG
ScanSerial(struct IOExtSer *ser_rreq,
struct IOExtSer *ser_oreq,
char *buf,
ULONG buf_len)
{
char *s;
ULONG bytesRead = 0L,
bytesInQ = 0L;
if (!buf_len)
return(0L);
if (CheckIO((struct IORequest *)ser_rreq))
{
WaitIO((struct IORequest *)ser_rreq);
s = (char *)ser_rreq->IOSer.io_Data;
buf[0] = *s;
bytesRead = 1L;
ser_oreq->IOSer.io_Command = SDCMD_QUERY;
if (!DoIO((struct IORequest *)ser_oreq))
{
if (bytesInQ = ser_oreq->IOSer.io_Actual)
{
if (bytesInQ >= buf_len)
bytesInQ = buf_len - 1L;
ser_rreq->IOSer.io_Data = buf+1;
ser_rreq->IOSer.io_Length = bytesInQ;
ser_rreq->IOSer.io_Command = CMD_READ;
DoIO((struct IORequest *)ser_rreq);
bytesRead += bytesInQ;
}
}
SendSerReadRequest(ser_rreq,s);
}
return(bytesRead);
}
/****************************************************************************/
/* send an asynchronous serial read */
void
SendSerReadRequest(struct IOExtSer *req,
char *c)
{
req->IOSer.io_Command = CMD_READ;
req->IOSer.io_Data = c;
req->IOSer.io_Length = 1L;
SendIO((struct IORequest *)req);
}
/****************************************************************************/
/* send an asynchronous serial write */
void
SendSerWriteRequest(struct IOExtSer *req,
char *buf,
ULONG buf_len)
{
req->IOSer.io_Command = CMD_WRITE;
req->IOSer.io_Data = buf;
req->IOSer.io_Length = buf_len;
SendIO((struct IORequest *)req);
}
/****************************************************************************/
void
AbortReq(struct IORequest *req)
{
if (!CheckIO(req))
AbortIO(req);
WaitIO(req);
}
/****************************************************************************/
/* END */