home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
019.lha
/
Aterm
/
aterm.c
< prev
next >
Wrap
C/C++ Source or Header
|
1986-11-10
|
21KB
|
842 lines
/************************************************************************
* a terminal program that has ascii and xmodem transfer capability
*
* originally written by Michael Mounier
*
* See file Aterm.mods for modification history.
*
************************************************************************/
/* compiler directives to fetch the necessary header files */
#include <libraries/dos.h>
#include <devices/serial.h>
#include <fcntl.h>
#include <exec/types.h>
#include <stdio.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include <exec/memory.h>
#include <functions.h>
#include "Options.h"
#include "ConsoleIO.h"
#include "SerialIO.h"
#include "Timer.h"
#define INTUITION_REV 0L /* Use Current Version */
#define GRAPHICS_REV 0L /* Use Current Version */
#define VERSION "Aterm 7.3"
#define CSI '\x9b' /* command sequence introducer */
#define EOS '\0' /* end of string marker */
#define CTRLN ('N'&0x1f)
#define CHATON8 ("\x9b3S\x9b22;1H\x9b1K\x9b21;1H\x9b21t")
#define CHATON9 ("\x9b3S\x9b19;1H\x9b1K\x9b18;1H\x9b18t")
#define CHOFF8 ("\x9b24t")
#define CHOFF9 ("\x9b21t")
#define WIPECH ("\x9b3T\x9b3S")
/* External variables declared here */
#define NUMKEYS 10
#define KEYSIZE 40
#define BUFSIZE KEYSIZE * NUMKEYS
UBYTE *KeyBuf = NULL; /* The Key Buffer */
BOOL chatting = FALSE;
BOOL DoPrefs = TRUE;
BOOL StartClock();
void DeleteClock();
/* Intuition always wants to see these declarations */
struct IntuitionBase *IntuitionBase = NULL;
struct GfxBase *GfxBase = NULL;
/* Global variables local to this module */
static UBYTE name[ 32 ];
static BOOL capture = FALSE;
static BOOL sending = FALSE;
static BOOL waiting = FALSE;
static FILE *tranr, *trans;
static BOOL ClockON = FALSE;
static ULONG waitmask;
static LONG maxcount;
/* Defaults if no "Init.key" file. */
static struct options Options =
{
/* Baud */ 300,
/* Mode */ MODEFULL,
/* AutoChop */ TRUE,
/* Xon */ FALSE,
/* Protocol */ XMODEMCRC,
/* Prompt */ EOS /* None */
} ;
static int baudrate[] = { 300,1200,2400,4800,9600 };
static struct Preferences *Preferences;
static struct IOExtSer *SerialIO = NULL;
static struct IOStdReq *Console = NULL; /* see "ConsoleIO.h" */
static BOOL TimerOpened = FALSE;
/* my window structure */
struct NewWindow NewWindow = {
0,0,640,200, /* left, top, width, height */
0,1, /* detail, block pens */
CLOSEWINDOW | MENUPICK | GADGETUP,
WINDOWCLOSE | SMART_REFRESH | ACTIVATE | WINDOWDEPTH | BORDERLESS,
NULL, /* firstgadget */
NULL, /* checkmark */
(UBYTE *)VERSION, /* title */
0, /* screen */
NULL, /* bitmap */
0,0, /* min x,y */
640, 200, /* max x,y */
WBENCHSCREEN /* type */
};
static struct Window *mywindow = NULL; /* ptr to applications window */
static struct RastPort *rp; /* ptr to RastPort for Chat */
static struct IntuiMessage *NewMessage; /* msg structure for GetMsg() */
static struct Menu *menuStrip = NULL; /* from InitMenu() */
/*--------------------------------------------------------------*/
/* cleanup: all done so close up and prepare to exit */
/*--------------------------------------------------------------*/
static void cleanup()
{
if ( ClockON )
DeleteClock();
if ( KeyBuf != NULL )
FreeMem( KeyBuf, (long)BUFSIZE );
if ( TimerOpened )
CloseTimer();
if ( SerialIO != NULL )
CloseSerialIO();
if ( menuStrip != NULL )
CloseMenu();
if ( mywindow != NULL )
CloseWindow( mywindow );
if ( Console != NULL )
CloseConsoleIO();
if ( GfxBase != NULL )
CloseLibrary( GfxBase );
if ( IntuitionBase != NULL )
CloseLibrary(IntuitionBase);
}
/*--------------------------------------------------------------*/
/* setdefaults: set defaults occording to current options. */
/*--------------------------------------------------------------*/
static void setdefaults()
{
/* set defaults */
if (DoPrefs)
{
switch ( Preferences->BaudRate )
{
case 1:
Options.Baud = 300;
break;
case 2:
Options.Baud = 1200;
break;
case 3:
Options.Baud = 2400;
break;
case 4:
Options.Baud = 4800;
break;
case 5:
Options.Baud = 9600;
break;
default:
Options.Baud = 300;
break;
}
}
SetSerBaud( (int)Options.Baud);
SetSerMode( (int)Options.Mode);
SetXonMode( (BOOL)Options.Xon );
SetMenu( &Options );
DoPrefs = FALSE;
}
/*--------------------------------------------------------------*/
/* init: initialize Aterm - set defaults */
/*--------------------------------------------------------------*/
static void init()
{
extern struct Menu *InitMenu();
static char initkeyname[] = "s:init.key";
char *s;
BOOL initFound;
int j;
static char *credits[] =
{"\x9b8y\xC\x9B33m\x9B5;17HA T E R M V E R S I O N 7.3",
"\x9B7;19HOriginal by Michael Mounier",
"\x9B9;21HMajor Modifications by:",
"\x9B10;26HJeff Lydiatt",
"\x9B11;22HLarry Phillips (ICUG)",
"\x9B12;27HSteve Allen",
"\x9B14;24HSpecial Thanks to",
"\x9B16;14H\x9B3mThe Independent Computer Users Group\x9B0;33m",
"\x9B17;30Hand",
"\x9B18;14H\x9B3mThe Source Telecomputing Corporation\x9B0;33m"
"\x9B20;8HWho Made the Super Kermit Implementation Possible"
"\x9Bm",
NULL};
IntuitionBase = (struct IntuitionBase *)
OpenLibrary("intuition.library", INTUITION_REV);
if( IntuitionBase == NULL )
{
puts("can't open intuition\n");
goto badopen;
}
Preferences = GetPrefs (Preferences, 4L);
GfxBase = (struct GfxBase *)
OpenLibrary("graphics.library", GRAPHICS_REV);
if( GfxBase == NULL )
{
puts("can't open graphics library\n");
goto badopen;
}
if ( (TimerOpened = OpenTimer()) == FALSE )
{
puts( "Can't open the Timer." );
goto badopen;
}
if(( mywindow = OpenWindow(&NewWindow) ) == NULL)
{
puts("Can't open a window.\n");
goto badopen;
}
if(( Console = InitConsoleIO( mywindow ) ) == NULL)
{
puts("Can't open the console.\n");
goto badopen;
}
if(( SerialIO = InitSerialIO() ) == NULL)
{
puts("Can't open the Serial Port.\n");
goto badopen;
}
if (( KeyBuf= AllocMem( (long)BUFSIZE,
(long)MEMF_PUBLIC | MEMF_CLEAR))== NULL)
{
puts("Can't get memory for function keys.\n");
goto badopen;
}
menuStrip = InitMenu( mywindow );
j = 0;
while ( (s = credits[j++]) != NULL )
PutString( s );
CursorXY(1, 1);
if ( (ClockON = StartClock( mywindow )) == TRUE )
PutString( "\x9b33mClock Task Started.\n\x9bm" );
initFound = LoadKeys( initkeyname ); /* did the default f-keys load? */
if ( LoadKeys( &initkeyname[2] ) )
initFound = TRUE;
if ( initFound )
PutString( "\x9b33mFunction Keys Loaded...\n\x9bm" );
else
setdefaults();
rp = mywindow->RPort;
CursorXY(1, 22);
return;
badopen:
cleanup();
exit( 4 );
}
/*--------------------------------------------------------------*/
/* SetOptions: called by LoadKeys to replace all options. */
/*--------------------------------------------------------------*/
void SetOptions( opt, optsize )
register char *opt;
int optsize;
{
register int i;
register char *s;
/* Note future changes can be easily accomplished by testing */
/* for the optsize of the older versions, and making the */
/* appropriate defaults and/or sending an error message. */
if (optsize != sizeof( Options ) )
{
optsize = sizeof( Options );
PutString( "Can't happen: setoptions got a bad option size." );
if ( optsize > sizeof( Options ) )
optsize = sizeof( Options );
}
/* copy the options */
/* The trick here is to pretend Options is an array of chars */
/* for the purpose of copying the options passed by LoadKeys */
s = (char *)&Options.Baud;
for (i = 0; i < optsize; i++)
*s++ = *opt++;
setdefaults();
}
/*--------------------------------------------------------------*/
/* GetOptions: called by SaveKeys to store current options.*/
/*--------------------------------------------------------------*/
int GetOptions( opt, maxsize )
register char *opt;
int maxsize;
{
register int i;
register char *s;
if (maxsize > sizeof( Options ) )
maxsize = sizeof( Options );
/* copy the options */
/* Note the same trick of treating Options as an array of chars*/
/* is used here to copy the current options to a workspace */
/* provided by SaveKeys. */
s = (char *)&Options.Baud;
for (i = 0; i < maxsize; i++)
*opt++ = *s++;
return sizeof( Options );
}
static void GetFunc(s)
char *s;
{
char name[40];
strcpy(name, "s:");
strcat(name,s);
if (LoadKeys(&name[2]))
PutString("\x9b33mLoaded\n\x9bm");
else if (LoadKeys(&name[0]))
PutString("\x9b33mLoaded\n\x9bm");
else
PutString("\x9b33mCouldn't load that file\n\x9bm");
}
/*--------------------------------------------------------------*/
/* doFileMenu: Handle Menu 0 */
/*--------------------------------------------------------------*/
static void doFileMenu( itemnum, subnum )
int itemnum, subnum;
{
UBYTE c;
BOOL status;
switch( itemnum )
{
/*-----------------------------------*/
/* Ascii Receive */
/*-----------------------------------*/
case 0:
if (capture)
{
capture = FALSE;
fclose(tranr);
PutString("\x9b33m\nEnd File Capture\n\x9bm");
}
else
{
if ( !GetLine("\x9b33m\nAscii Capture: ", name))
PutString("\nAborted\n\x9bm");
else
{
if ((tranr=fopen(name,"w")) == 0)
{
capture=FALSE;
PutString("\nCan't Open File\n\x9bm");
break;
}
capture = TRUE;
PutString("\x9bm");
}
}
break;
/*-----------------------------------*/
/* Ascii Send */
/*-----------------------------------*/
case 1:
if (sending)
{
sending = waiting = FALSE;
fclose(trans);
PutString("\n\x9b33mFile Send Cancelled\n\x9bm");
}
else if ( !GetLine("\x9b33m\nAscii Send: ",name) )
PutString("\nAborted\n\x9bm");
else if ( (trans = fopen(name,"r")) == 0)
{
sending = FALSE;
PutString("\nCan't Open File\n\x9bm");
}
else
{
sending = TRUE;
waiting = FALSE;
PutString("\x9bm");
}
break;
/*-----------------------------------*/
/* Binary Receive */
/*-----------------------------------*/
case 2:
if ( !GetLine("\x9b33m\nBinary Receive: ", name))
PutString("\nAborted\n\x9Bm");
else
{
if ( Options.Protocol == KERMIT )
status = KermitGet( name );
else
{
/* disable ^Q/^S trapping */
PushSerState();
SetXonMode( FALSE );
status = XMODEM_Read_File(name,
(BOOL)(Options.Protocol == 1), (BOOL)Options.AutoChop);
PullSerState();
}
if ( status )
PutString("\nFile Received\n\x9bm");
else
PutString("\nBinary Receive Failed\n\x9bm");
DisplayBeep(NULL);
}
break;
/*-----------------------------------*/
/* Binary Send */
/*-----------------------------------*/
case 3:
if ( !GetLine("\x9b33m\nBinary Send: ",name))
PutString("\nAborted\n\x9bm");
else
{
if ( Options.Protocol == KERMIT )
status = KermitPut( name );
else
status = XMODEM_Send_File( name, (int)Options.Baud );
if ( status )
PutString("\nFile Sent\n\x9bm");
else
PutString("\nBinary Send Failed\n\x9bm");
DisplayBeep(NULL);
}
break;
/*-----------------------------------*/
/* Prompt */
/*-----------------------------------*/
case 4:
PutString("\x9b33m\nNew Prompt Character: ");
if ( (c = GetKey()) == '0')
Options.Prompt = EOS;
else
Options.Prompt = c;
keychar( c );
PutString("\n\x9bm");
break;
}
}
/*----------------------------------------------------------*/
/* doMiscMenu: Handle the miscellaneous menus */
/*----------------------------------------------------------*/
static void doMiscMenu( itemnum, subnum )
int itemnum, subnum;
{
switch (itemnum)
{
/*---------------------------------*/
/* FKey Load */
/*---------------------------------*/
case 0: /* FKey load */
if ( !GetLine("\x9b33m\nFunction-Key file name: ",name))
PutString(" aborted.\n\x9bm");
else
{
GetFunc(name);
}
break;
/*---------------------------------*/
/* FKey Save */
/*---------------------------------*/
case 1:
if ( !GetLine("\x9b33m\nFunction-Key Save Filename: ",name))
PutString( "aborted...\n\x9bm" );
else
{
if (SaveFKeys(name))
PutString( "File saved\n\x9bm" );
else
PutString( "Unable to save that file.\n\x9bm" );
}
break;
/*---------------------------------*/
/* define an FKey */
/*---------------------------------*/
case 2:
DefineString();
break;
/*---------------------------------*/
/* Toggle AutoChop */
/*---------------------------------*/
case 3:
Options.AutoChop = (subnum == 0);
break;
/*---------------------------------*/
/* Toggle Xon Mode */
/*---------------------------------*/
case 4:
Options.Xon = (subnum == 0);
SetXonMode( (BOOL)Options.Xon );
break;
/*---------------------------------*/
/* Set Protocol */
/*---------------------------------*/
case 5:
Options.Protocol = subnum;
break;
/*---------------------------------*/
/* CHAT Mode toggle */
/*---------------------------------*/
case 6:
chatting = !chatting;
Chat( chatting );
break;
/*---------------------------------*/
/* Do Phone Book */
/*---------------------------------*/
case 7:
do_phlib( mywindow );
break;
}
}
/*============================================================*/
/*== CHAT functions. Moved here because I couldn't get them ==*/
/*== working in a separate file. ==*/
/*============================================================*/
/*---------------------------------*/
/* Chat - Turns CHAT window on/off */
/*---------------------------------*/
Chat( flag )
BOOL flag;
{
char cursor = '_';
if (flag)
{
if (Preferences->FontHeight == 8)
{
PutString ( CHATON8 );
Move ( rp, 0L, 198L );
RectFill( rp, 0L, 178L, 640L, 181L);
maxcount = 79;
}
if (Preferences->FontHeight == 9)
{
PutString ( CHATON9 );
Move ( rp, 0L, 196L );
RectFill( rp, 0L, 173L, 640L, 176L);
maxcount = 63;
}
Text ( rp, &cursor, 1L );
}
else
{
if (Preferences->FontHeight == 8)
PutString ( CHOFF8 );
if (Preferences->FontHeight == 9)
{
ScrollRaster( rp,0L, -20L,0L,180L,640L,200L );
PutString ( CHOFF9 );
}
PutString( WIPECH );
ChatOut ( 0 );
}
}
/*-----------------------------------------*/
/* ChatOut - Send character to CHAT window */
/* - Send to SerIO if CR/LF */
/*-----------------------------------------*/
ChatOut( c )
UBYTE c;
{
static LONG count = 0;
static UBYTE line[ 81 ] = '_';
int i;
Move ( rp, 0L, 197L );
switch (c)
{
case '\r':
case '\n':
line[count] = '\r';
for ( i = 0; i < count; i++ )
SerIOPut(line[i]);
SerIOPut ('\r');
line[0] = '_';
count = 0;
if (Preferences->FontHeight == 8)
ScrollRaster( rp,0L,(LONG)Preferences->FontHeight,0L,183L,640L,200L );
if (Preferences->FontHeight == 9)
ScrollRaster( rp,0L,(LONG)Preferences->FontHeight,0L,181L,640L,200L );
Text( rp, line, 1L );
break;
case '\x08':
if (count > 0)
{
line [count--] = ' ' ;
line [count] = '_';
Text( rp, line, count+2 );
}
break;
case '\0':
count = 0;
line[0] = '_';
break;
default:
if ( count < maxcount )
{
line[count++] = c;
line[count] = '_';
Text( rp, line, count+1 );
}
else
PutChar('\x07');
break;
}
}
/******************************************************/
/* Main Program */
/* */
/* This is the main body of the program. */
/******************************************************/
main()
{
ULONG class, waitmask;
int code, menunum, itemnum, subnum;
BOOL KeepGoing;
int c, i;
UBYTE character, *KeyOffset;
init();
waitmask = (1L << SerialIO->IOSer.io_Message.mn_ReplyPort->mp_SigBit)
| (1L << mywindow->UserPort->mp_SigBit)
| (1L << Console->io_Message.mn_ReplyPort->mp_SigBit);
KeepGoing = TRUE;
while( KeepGoing )
{
if ( !sending || waiting )
Wait( waitmask );
/* --- Ascii Send Routine interleaved ----------*/
if ( sending && !waiting /* for the Prompt character */ )
{
if ( (c = getc(trans)) == EOF)
{
fclose( trans );
PutString( "\x9b33m\nFile Sent\n\x9bm" );
sending = waiting = FALSE;
}
else if (c == '\n' )
{
SerIOPut('\r'); /* switch in carriage return */
if ( Options.Prompt != EOS )
waiting=TRUE;
}
else SerIOPut(c);
} /* end (if sending) */
/*----- Drain the keyboard buffer--------------*/
while ( c = CheckKey() )
{
if (c != CSI)
{
if (chatting)
ChatOut( c );
else
SerIOPut( c );
}
else
{
character = GetKey();
if ((character < 'A') || (character > 'D'))
while ( GetKey() != '~');
if ( ('0' <= character) && (character <= '9') )
{
KeyOffset = KeyBuf + (KEYSIZE * (character - '0'));
while ( c = *KeyOffset++ )
{
if (CheckKey() == 27)
{
PutString("\x9b33m\nFunction key aborted.\x9bm\n");
break;
}
if ( c > 127 )
{
switch (c)
{
case 128: /* <LOAD> */
GetFunc(KeyOffset);
while (c = *KeyOffset++);
KeyOffset--;
break;
case 129: /* <LOADEX */
c = *KeyOffset++;
GetFunc(KeyOffset);
KeyOffset=KeyBuf + (KEYSIZE * (c - '0' -1));
break;
default:
if (( c > 129 ) && ( c < 140 )) /* <Fn:> */
KeyOffset=KeyBuf+(KEYSIZE*(c - 83 - '0'));
break;
} /* end case (c) */
} /* end if (c>127) */
else
SerIOPut( c );
} /* end while */
} /* end if */
else if (character == '?')
{
PutString( "\x9b33m\n" ); /* in red */
PutString( VERSION );
PutString( "\n\nPrompt character is " );
if ( Options.Prompt == EOS)
PutString( "Inactive" );
else
keychar( Options.Prompt );
PutString("\n\n");
DoContents(); /* display function keys */
PutString("\x9bm"); /* turn off red */
}
} /* end if CSI */
} /* end while CheckKey() */
/*----- Drain the Serial Port Buffer-------------*/
if ( CheckSerIO() )
{
do
{
c = SerIOGet() & 0x7f;
if ((c != '\n') && (c != CTRLN)) /* don't print LF or CTRL N */
PutFormat(c=='\r'?'\n':c); /* convert CR into LF */
if ( (waiting) && (c == Options.Prompt) )
waiting = FALSE;
if (capture)
if ( (' ' <= c && c < '\x7f') || c == '\n' || c== '\t' )
putc( c, tranr ); /* trash them mangy ctl chars */
} while( CheckSerIO() );
PutFormat((UBYTE)'\xff'); /* squirt out all received chars */
}
/* ---------------- Handle all Menu Messages --------------------*/
while( NewMessage=(struct IntuiMessage *)GetMsg(mywindow->UserPort) )
{
class = NewMessage->Class;
code = NewMessage->Code;
ReplyMsg( NewMessage );
switch( class )
{
case CLOSEWINDOW:
KeepGoing = FALSE;
break;
case MENUPICK:
if ( code != MENUNULL )
{
menunum = MENUNUM( code );
itemnum = ITEMNUM( code );
subnum = SUBNUM( code );
switch( menunum )
{
case 0:
doFileMenu( itemnum, subnum );
break;
case 1: /* New Baud Rate */
Options.Baud = baudrate[ itemnum ];
SetSerBaud( (int)Options.Baud );
break;
case 2: /* "Mode" */
Options.Mode = itemnum;
SetSerMode( (int)Options.Mode );
break;
case 3: /* misc. menu selection */
doMiscMenu( itemnum, subnum );
break;
} /* end of switch ( menunum ) */
} /*end of for( not MENUNULL ) */
} /* end of switch (class) */
} /* end of while ( newmessage )*/
} /* end while ( keepgoing ) */
cleanup();
exit( 0 );
} /* end of main */