[comp.sources.amiga] v89i182: vt100 - terminal emulator v2.9, Part05/09

page%swap@Sun.COM (Bob Page) (10/20/89)

Submitted-by: acs@pccuts.pcc.amdahl.com (Tony Sumrall)
Posting-number: Volume 89, Issue 182
Archive-name: comm/vt100r29.5

# This is a shell archive.
# Remove anything above and including the cut line.
# Then run the rest of the file through 'sh'.
# Unpacked files will be owned by you and have default permissions.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar: SHell ARchive
# Run the following text through 'sh' to create:
#	Zmodem/SerIO.c
#	Zmodem/term.c
#	expand.c
#	init.c
# This is archive 5 of a 9-part kit.
# This archive created: Thu Oct 19 22:30:30 1989
if `test ! -d Zmodem`
then
  mkdir Zmodem
  echo "mkdir Zmodem"
fi
echo "extracting Zmodem/SerIO.c"
sed 's/^X//' << \SHAR_EOF > Zmodem/SerIO.c
X
X#define ERROR (-1)     /* don't change these 2 because they have to */
X#define TIMEOUT (-2)   /* be the same as the #defines in sz.c and rz.c */
X
X#define SERBUFSIZE 1024L
X
X/*
X *   Serial IO functions
X *
X *	based on routines by A.Livshits & J.M.Forgeas
X *
X *   Extensively modified for Amiga zmodem by Frank Harper
X */
X
X#include <stdio.h>
X#include <ctype.h>
X#include <exec/types.h>
X#include <exec/nodes.h>
X#include <exec/memory.h>
X#include <exec/io.h>
X#include <exec/errors.h>
X#include <exec/ports.h>
X#include <devices/timer.h>
X#include <devices/serial.h>
X#include <libraries/dos.h>
X#include "intuition/intuition.h"
X
Xextern int Lleft;			 /* number of chars in input buffer */
Xextern UBYTE  SerOpen;			 /* True if Serial port is open */
Xstatic UBYTE TimeOpen;
Xextern struct IOExtSer *InSer, *OutSer;
Xextern struct MsgPort  *InSerPort, *OutSerPort;
X
Xextern ULONG  InSerSigMask, OutSerSigMask; /* Masks for Wait & WaitIO */
Xextern ULONG  IOTimeSigMask;
X
Xextern struct timerequest *IOTime;
Xextern struct MsgPort *TimerPort;
Xextern struct Window *Win;
Xstruct MsgPort *CreatePort();
Xvoid *CreateExtIO(),*AllocMem();
X
Xstatic UBYTE  RecSerBuf[SERBUFSIZE];	/* Serial input buffer */
Xstatic UBYTE Previous=FALSE;		/* True if asynchronous serial
X					   write is pending */
X
X
Xextern int Enable_Abort = 0;		/* No ^C allowed (Manx) */
X
X /*
X  * Init. serial port
X  *
X  * bps: bits per second (or Baud rate) between 110 and 29,200
X  *	if this parameter is -1 then the device is opened with
X  *	no changes in bps,len, or stop.
X  *
X  * len: lenght of each word sent and received (7 or 8)
X  * stop: number of stop bits 1 or 2
X  * flags: used to set other parameters
X  *
X  * returns pointer to IOExtSer structure, so caller can determine what
X  * the serial parameters in use actually are. In case of failure
X  * return NULL.
X  */
X
Xstruct IOExtSer *SetSer(bps,len,stop,flags)
XULONG bps,len,stop,flags;
X{
X
X   if( bps!=-1 && (bps<110 || bps>29200 || len<7 || len>8 ||
X		    stop<1 || stop>2)) return NULL;
X
X   InSer = (struct IOExtSer *) AllocMem((long)sizeof(*InSer),MEMF_PUBLIC|MEMF_CLEAR);
X   if(InSer==NULL) return NULL;
X
X   OutSer = (struct IOExtSer *) AllocMem((long)sizeof(*OutSer),MEMF_PUBLIC|MEMF_CLEAR);
X   if( OutSer==NULL) return NULL;
X
X   InSerPort = InSer->IOSer.io_Message.mn_ReplyPort = CreatePort(0L,0L);
X   if(InSerPort==NULL) return NULL;
X
X   InSerSigMask = 1 << (InSerPort->mp_SigBit);
X   InSer->io_SerFlags = SERF_SHARED&flags;
X
X   if(OpenDevice(SERIALNAME,NULL,InSer,NULL)) {
X       fprintf(stderr,"Error opening serial device\n");
X       return NULL;
X   }
X   if( bps!=-1 ) {
X     InSer->io_SerFlags = flags;
X     InSer->io_Baud	= bps;
X     InSer->io_ReadLen	= InSer->io_WriteLen = len;
X     InSer->io_StopBits = stop;
X     InSer->io_CtlChar	= 0x11130000L;
X     InSer->io_RBufLen	= SERBUFSIZE;
X     InSer->io_BrkTime	= 250000L;
X     InSer->IOSer.io_Command = SDCMD_SETPARAMS;
X     if( DoIO(InSer)!=0 ) {
X	 fprintf(stderr,"Error setting serial port parameters\n");
X	 return NULL;
X     }
X   }
X   CopyMem(InSer,OutSer,sizeof(struct IOExtSer));
X   OutSerPort = OutSer->IOSer.io_Message.mn_ReplyPort = CreatePort(0L,0L);
X   if(OutSerPort==NULL) return NULL;
X   OutSerSigMask = 1 << (OutSerPort->mp_SigBit);
X   SerOpen=1;
X   return InSer;
X}
X
X /*
X  * Close serial port
X  */
X
Xvoid  CloseSer()
X{
X    if(Previous) {
X	Wait(OutSerSigMask);
X	GetMsg(OutSerPort);
X    }
X    if(SerOpen) {
X	CloseDevice(InSer);
X	SerOpen=0;
X    }
X    if(OutSerPort) {
X	DeletePort(OutSerPort);
X	OutSerPort=NULL;
X    }
X    if(InSerPort)  {
X	DeletePort(InSerPort);
X	InSerPort=NULL;
X    }
X    if(OutSer) {
X	FreeMem(OutSer,(long)sizeof(*OutSer));
X	OutSer=NULL;
X    }
X    if(InSer) {
X	FreeMem(InSer,(long)sizeof(*InSer));
X	InSer=NULL;
X    }
X}
X
X /*
X  * Write asynchronously the len characters (up to SERBUFSIZE) pointed
X  * at by c.
X  */
X
Xint LWriteSer(c,len)
XUBYTE  *c;
Xint len;
X{
X
X   ULONG  IntuiMask,mask;
X   static UBYTE buf[SERBUFSIZE];
X
X    if (len==0) return (0);
X    if (len > SERBUFSIZE || SerOpen==0) return ERROR;
X    if (Previous) {
X	IntuiMask = 1 << (Win->UserPort->mp_SigBit);
X	mask = Wait(OutSerSigMask | IntuiMask);
X	if ((mask & IntuiMask) && CheckQuit()) {
X	    KillIO( (struct IOStdReq *)OutSer,mask);
X	    Previous=FALSE;
X	    bibi(1);
X	}
X	GetMsg(OutSerPort);
X    }
X    Previous = TRUE;
X    CopyMem(c,buf,len);
X    OutSer->IOSer.io_Data = (APTR)buf;
X    OutSer->IOSer.io_Length = (ULONG)len;
X    OutSer->IOSer.io_Command = CMD_WRITE;
X    SendIO(OutSer);
X    return (0);
X}
X
X /*
X  * Send an asynchronous read request for n characters
X  * put result in buf
X  */
X
XSendSer(n,buf)
Xint n;
Xchar *buf;
X{
X    if( SerOpen==0 ) {
X	fprintf(stderr,"Read attempt on closed Serial Port\n");
X	return ERROR;
X    }
X    InSer->IOSer.io_Data = (APTR)buf;
X    InSer->IOSer.io_Length = n;
X    InSer->IOSer.io_Command = CMD_READ;
X    SendIO(InSer);
X    return (0);
X}
X
X /*
X  * Purge any characters waiting in serial port queue
X  *
X  */
X
XPurgeSer()
X{
X    if( SerOpen!=0 ) {
X     InSer->IOSer.io_Command = CMD_CLEAR;
X     if ( DoIO(InSer)!=0) fprintf(stderr,"can't purge serport\n");
X    }
X}
X
X /*
X  * Initialize timer device
X  */
X
Xint SetTimer()
X
X{
X    int err;
X
X    TimerPort =  CreatePort(0,0);
X    if (TimerPort==NULL) return ERROR;
X    IOTimeSigMask = 1 << (TimerPort->mp_SigBit);
X    IOTime   = (struct timerequest *) CreateExtIO(TimerPort,sizeof(struct timerequest));
X    if (IOTime==NULL) return ERROR;
X    if( (err=OpenDevice(TIMERNAME,UNIT_VBLANK,IOTime,0))!=0)
X	 TimeOpen=0;
X    else TimeOpen=1;
X    return err;
X}
X
X /*
X  * Close timer device
X  */
X
Xvoid CloseTimer()
X{
X    if( TimeOpen ) {
X	CloseDevice(IOTime);
X	TimeOpen=0;
X    }
X    if(IOTime) {
X	DeleteExtIO(IOTime,sizeof(struct timerequest));
X	IOTime=NULL;
X    }
X    if(TimerPort) {
X	DeletePort(TimerPort);
X	TimerPort=NULL;
X    }
X}
X
X/* send a break to the host */
X
Xvoid SendBreak()
X{
X    if ( SerOpen ) {
X	InSer->IOSer.io_Command = SDCMD_BREAK;
X	if( DoIO(InSer)!=0) fprintf(stderr,"SendBreak:error sending break\n");
X    }
X}
X
X /*
X  * Read a character from serial port. Timeout is in tenths of seconds.
X  *
X  */
Xint ReadSer(timeout)
Xint timeout;
X{
X    int ch;
X    ULONG mask,IntuiMask;
X    static UBYTE *NextChar;
X    int Quit;
X
X  /*  if(CheckQuit()) bibi(1);*/
X    if( !SerOpen) return ERROR;
X    if( Lleft>0 ) {
X	--Lleft;
X	return (*NextChar++);
X     }
X    IOTime->tr_time.tv_secs = timeout/10;
X    IOTime->tr_time.tv_micro = 100000*(timeout%10);
X    IOTime->tr_node.io_Command = TR_ADDREQUEST;
X    SendIO(IOTime);
X    SendSer(1,RecSerBuf);
X    IntuiMask = 1 << (Win->UserPort->mp_SigBit);
X    mask=Wait( InSerSigMask | IOTimeSigMask | IntuiMask);
X    if (CheckQuit()) {
X	KillIO(IOTime,mask);
X	KillIO( (struct IOStdReq *)InSer,mask);
X	bibi(1);
X    }
X    else if ((mask&InSerSigMask)!=0) {
X	    KillIO(IOTime,mask);
X	    GetMsg(InSerPort);
X	    ch=RecSerBuf[0];
X	    if( (Lleft=CharsWaiting())>0){/* find out how many characters are
X					     waiting */
X		InSer->IOSer.io_Data = (APTR)RecSerBuf;
X		InSer->IOSer.io_Length = Lleft<SERBUFSIZE?Lleft:SERBUFSIZE;
X		InSer->IOSer.io_Command = CMD_READ;
X		DoIO(InSer);
X		NextChar=RecSerBuf;
X	     }
X	    return(ch);
X    }
X    else  { /* it was the timer signal */
X	    KillIO( (struct IOStdReq *)InSer,mask);
X	    WaitIO(IOTime);
X	    return TIMEOUT;
X    }
X}
X
X /*
X  * Determine the number of characters waiting in the serial.device
X  * input buffer
X  *
X  */
X
XCharsWaiting()
X{
X    if( SerOpen ) {
X	    InSer->IOSer.io_Command = SDCMD_QUERY;
X	    if( DoIO(InSer)!=0) fprintf(stderr,"CharsWaiting: IO error\n");
X	    return (int)(InSer->IOSer.io_Actual);
X    }
X}
X
X /*
X  * If IO isn't done Abort it
X  * in any case GetMsg it
X  *
X  */
X
XKillIO(Req,Mask)
Xstruct IOStdReq *Req;
XULONG Mask;
X{
X  ULONG SigMask;
X  struct MsgPort  *SigPort;
X
X    SigPort=Req->io_Message.mn_ReplyPort;
X    SigMask=1 << (SigPort->mp_SigBit);
X    if( (Mask & SigMask)==0 ) {
X	    AbortIO(Req);
X	    Wait(SigMask);
X    }
X    GetMsg(SigPort);
X}
SHAR_EOF
echo "extracting Zmodem/term.c"
sed 's/^X//' << \SHAR_EOF > Zmodem/term.c
X#include "exec/types.h"
X#include "exec/ports.h"
X#include "exec/devices.h"
X#include "exec/io.h"
X#include "exec/memory.h"
X#include "devices/console.h"
X#include "intuition/intuition.h"
Xstruct MsgPort *CreatePort();
Xstruct IOStdReq *CreateStdIO();
Xstruct Window *OpenWindow();
Xvoid *GetMsg();
X
X#define ESC 27
X
X
Xextern struct IOStdReq *ConWriteReq;
Xextern struct IOStdReq *ConReadReq;
Xextern struct Window *Win;
Xextern ULONG InSerSigMask;
Xextern int FullDuplex;
Xextern struct MsgPort  *InSerPort;
Xextern struct IOExtSer *InSer;
Xstatic int ConOpen;
Xextern struct MsgPort  *ConReadPort,*ConWritePort;
X
X/*
X * mini-terminal function
X * exit when user hits close box
X *
X */
Xterm()
X{
X    char ConChar,SerChar;
X    ULONG ConInMask,mask,IntuiMask;
X    struct IntuiMessage *message;
X
X    ConInMask = 1 << (ConReadPort->mp_SigBit);
X    IntuiMask = 1 << (Win->UserPort->mp_SigBit);
X    QueueRead(ConReadReq,&ConChar);
X    SendSer(1,&SerChar);
X    while(1) {
X	mask=Wait(ConInMask|InSerSigMask|IntuiMask);
X	if(CheckQuit()) break;
X	if( mask & ConInMask ) {
X	    GetMsg(ConReadPort);
X	    LWriteSer(&ConChar,1);
X	    if(!FullDuplex) ConPutChar(ConWriteReq,ConChar);
X	    QueueRead(ConReadReq,&ConChar);
X	}
X	if( mask & InSerSigMask ) {
X	    GetMsg(InSerPort);
X	    ConPutChar(ConWriteReq,SerChar&0x7F);
X	    SendSer(1,&SerChar);
X	}
X    }
X    /*if( (mask & InSerSigMask)==0) {
X	AbortIO(InSer);
X	Wait(InSerSigMask);
X    }
X    GetMsg(InSerPort);
X    if( (mask & ConInMask)==0) {
X	AbortIO(ConReadReq);
X	Wait(ConInMask);
X    }
X    GetMsg(ConReadPort);*/
X    KillIO( (struct IOStdReq *)InSer,mask);
X    KillIO(ConReadReq,mask);
X    return 0;
X}
X
X
X/*
X * Open a console device
X *
X */
X      int
XOpenConsole(WriteReq,ReadReq,Win)
X    struct IOStdReq **WriteReq;
X    struct IOStdReq **ReadReq;
X    struct Window *Win;
X{
X    int error;
X
X    ConWritePort = CreatePort(0L,0L);
X    if ( ConWritePort == NULL ) {
X	CloseConsole();
X	return -1;
X    }
X    *WriteReq = CreateStdIO(ConWritePort);
X    if( WriteReq == NULL ) {
X	CloseConsole();
X	return -1;
X    }
X
X    ConReadPort = CreatePort(0L,0L);
X    if ( ConReadPort == NULL ) {
X	CloseConsole();
X	return -1;
X    }
X
X    *ReadReq = CreateStdIO(ConReadPort);
X    if( ReadReq == NULL ) {
X	CloseConsole();
X	return -1;
X    }
X
X    (*WriteReq)->io_Data = (APTR) Win;
X    (*WriteReq)->io_Length = sizeof(*Win);
X    error = OpenDevice("console.device", 0, *WriteReq, 0);
X    (*ReadReq)->io_Device = (*WriteReq)->io_Device;
X    (*ReadReq)->io_Unit   = (*WriteReq)->io_Unit;
X	  /* clone required parts of the request */
X    if( !error ) ConOpen=TRUE;
X    else CloseConsole();
X    return error;
X}
X
XCloseConsole(ReadReq,WriteReq)
Xstruct IOStdReq *WriteReq;
Xstruct IOStdReq *ReadReq;
X{
X    if(ConOpen)       CloseDevice(ReadReq);
X    if( ConReadPort)  DeletePort(ConReadPort);
X    if( ReadReq)      DeleteStdIO(ReadReq);
X    if( ConWritePort) DeletePort(ConWritePort);
X    if( WriteReq)     DeleteStdIO(WriteReq);
X}
X
X/* Output a single character to a specified console */
X
X      int
XConPutChar(request,character)
X      struct IOStdReq *request;
X      char character;
X      {
X	    request->io_Command = CMD_WRITE;
X	    request->io_Data = (APTR)&character;
X	    request->io_Length = 1;
X	    request->io_Flags = IOF_QUICK;
X	    DoIO(request);
X	    return(0);
X      }
X
X/* Output a NULL-terminated string of characters to a console */
X
X      int
XConPutStr(request,string)
X      struct IOStdReq *request;
X      char *string;
X      {
X	    request->io_Command = CMD_WRITE;
X	    request->io_Data = (APTR)string;
X	    request->io_Length = -1;
X	    DoIO(request);
X	    return(0);
X      }
X
X      /* queue up a read request to a console */
X
X      int
XQueueRead(request,whereto)
X      struct IOStdReq *request;
X      char *whereto;
X      {
X	    request->io_Command = CMD_READ;
X	    request->io_Data = (APTR)whereto;
X	    request->io_Length = 1;
X	    SendIO(request);
X	    return(0);
X      }
X
X /*
X  * Check if user has hit close box
X  *
X  */
X
Xint CheckQuit()
X{
X int Quit;
X struct IntuiMessage *message;
X
X    Quit=FALSE;
X    while( ((message = (struct IntuiMessage *)
X			GetMsg(Win->UserPort) ) != NULL)) {
X	if(message->Class==CLOSEWINDOW) Quit=TRUE;
X	ReplyMsg(message);
X    }
X    return Quit;
X}
X
XConGetC(request)
Xstruct IOStdReq *request;
X{
X  char c;
X
X    request->io_Command = CMD_READ;
X    request->io_Data = (APTR)&c;
X    request->io_Length = 1;
X    DoIO(request);
X    return c;
X}
X
SHAR_EOF
echo "extracting expand.c"
sed 's/^X//' << \SHAR_EOF > expand.c
X/*************************************************************
X * vt100 terminal emulator - Wild card and Directory support
X *			:ts=8
X *
X *	v2.9 ACS - See change summary.
X *	v2.7 870825 ACS - Use the *InfoMsg*() routines in window.c rather
X *			  than req().
X *	v2.6 870227 DBW - bug fixes for all the stuff in v2.5
X *	v2.5 870214 DBW - more additions (see readme file)
X *	v2.4 861214 DBW - lots of fixes/additions (see readme file)
X *	v2.3 861101 DBW - minor bug fixes
X *	v2.2 861012 DBW - more of the same
X *	v2.1 860915 DBW	- new features (see README)
X *           860830 Steve Drew Added Wild card support,
X *		    features(expand.c)
X *	v2.0 860809 DBW - Major rewrite
X *	v1.1 860720 DBW	- Switches, 80 cols, colors, bug fixes
X *	v1.0 860712 DBW	- First version released
X *
X *      Much of the code from this module extracted from
X *      Matt Dillons Shell program. (Thanxs Matt.)
X *************************************************************/
X
X#include "vt100.h"
X
Xstruct DPTR {                    /* Format of directory fetch ptr */
X   struct FileLock *lock;        /* lock on directory   */
X   struct FileInfoBlock *fib;    /* mod'd fib for entry */
X};
X
X/*
X * Disk directory routines
X *
X *
X * diropen() returns a struct DPTR, or NULL if the given file does not
X * exist.  stat will be set to 1 if the file is a directory.  If the
X * name is "", then the current directory is openned.
X *
X * dirnext() returns 1 until there are no more entries.  The **name and
X * *stat are set.  *stat = 1 if the file is a directory.
X *
X * dirclose() closes a directory channel.
X *
X */
X
Xstruct DPTR *
Xdiropen(name, stat)
Xchar *name;
Xint *stat;
X{
X   struct DPTR *dp;
X   int namelen, endslash = 0;
X   struct FileLock *MyLock;
X
X   MyLock = (struct FileLock *)( (ULONG) ((struct Process *)
X				 (FindTask(NULL)))->pr_CurrentDir);
X   namelen = strlen(name);
X   if (namelen && name[namelen - 1] == '/') {
X      name[namelen - 1] = '\0';
X      endslash = 1;
X   }
X   *stat = 0;
X   dp = (struct DPTR *)malloc(sizeof(struct DPTR));
X   if (*name == '\0')
X      dp->lock = (struct FileLock *)DupLock (MyLock);
X   else
X      dp->lock = (struct FileLock *)Lock (name, ACCESS_READ);
X   if (endslash)
X      name[namelen - 1] = '/';
X   if (dp->lock == NULL) {
X      free (dp);
X      return (NULL);
X   }
X   dp->fib = (struct FileInfoBlock *)
X	 AllocMem((long)sizeof(struct FileInfoBlock), MEMF_PUBLIC);
X   if (!Examine (dp->lock, dp->fib)) {
X      dirclose (dp);
X      return (NULL);
X   }
X   if (dp->fib->fib_DirEntryType >= 0)
X      *stat = 1;
X   return (dp);
X}
X
Xdirnext(dp, pname, stat)
Xstruct DPTR *dp;
Xchar **pname;
Xint *stat;
X{
X   if (dp == NULL)
X      return (0);
X   if (ExNext (dp->lock, dp->fib)) {
X      *stat = (dp->fib->fib_DirEntryType < 0) ? 0 : 1;
X      *pname = dp->fib->fib_FileName;
X      return (1);
X   }
X   return (0);
X}
X
X
Xdirclose(dp)
Xstruct DPTR *dp;
X{
X   if (dp == NULL)
X      return (1);
X   if (dp->fib)
X      FreeMem (dp->fib, (long)sizeof(*dp->fib));
X   if (dp->lock)
X      UnLock (dp->lock);
X   free (dp);
X   return (1);
X}
X
Xvoid
Xfree_expand(av)
Xchar **av;
X{
X   char **base = av;
X
X   if (av) {
X      while (*av) {
X	 free (*av);
X	 ++av;
X      }
X      free (base);
X   }
X}
X
X/*
X * EXPAND(wild_name, pac)
X *    wild_name      - char * (example: "df0:*.c")
X *    pac            - int  *  will be set to # of arguments.
X *
X */
X
X
Xchar **
Xexpand(base, pac)
Xchar *base;
Xint *pac;
X{
X   char **eav = (char **)malloc (sizeof(char *));
X   int  eleft, eac;
X
X   char *ptr, *name;
X   char *bname, *ename, *tail;
X   int stat, scr;
X   struct DPTR *dp;
X
X   *pac = eleft = eac = 0;
X   base = strcpy(malloc(strlen(base)+1), base);
X   for (ptr = base; *ptr && *ptr != '?' && *ptr != '*'; ++ptr);
X   for (; ptr >= base && !(*ptr == '/' || *ptr == ':'); --ptr);
X   if (ptr < base) {
X      bname = strcpy (malloc(1), "");
X   } else {
X      scr = ptr[1];
X      ptr[1] = '\0';
X      bname = strcpy (malloc(strlen(base)+1), base);
X      ptr[1] = scr;
X   }
X   ename = ptr + 1;
X   for (ptr = ename; *ptr && *ptr != '/'; ++ptr);
X   scr = *ptr;
X   *ptr = '\0';
X   tail = (scr) ? ptr + 1 : NULL;
X
X   if ((dp = diropen (bname, &stat)) == NULL  ||  stat == 0) {
X      free (bname);
X      free (base);
X      free (eav);
X      InfoMsg1Line("Could not open directory");
X      return (NULL);
X   }
X   while (dirnext (dp, &name, &stat)) {
X      if (compare_ok(ename, name)) {
X	 if (tail) {
X	    int alt_ac;
X	    char *search, **alt_av, **scrav;
X	    struct FileLock *lock;
X
X	    if (!stat)      /* expect more dirs, but this not a dir */
X	       continue;
X	    lock = (struct FileLock *)CurrentDir (dp->lock);
X	    search = malloc(strlen(name)+strlen(tail)+2);
X	    strcpy (search, name);
X	    strcat (search, "/");
X	    strcat (search, tail);
X	    scrav = alt_av = expand (search, &alt_ac);
X	    CurrentDir (lock);
X	    if (scrav) {
X	       while (*scrav) {
X		  if (eleft < 2) {
X		     char **scrav = (char **)
X			malloc(sizeof(char *) * (eac + 10));
X		     movmem ((char *)eav, (char *)scrav, sizeof(char *) * (eac + 1));
X		     free (eav);
X		     eav = scrav;
X		     eleft = 10;
X		  }
X		  eav[eac] = malloc(strlen(bname)+strlen(*scrav)+1);
X		  strcpy(eav[eac], bname);
X		  strcat(eav[eac], *scrav);
X		  free (*scrav);
X		  ++scrav;
X		  --eleft, ++eac;
X	       }
X	       free (alt_av);
X	    }
X	 } else {
X	    if (eleft < 2) {
X	       char **scrav = (char **)
X		    malloc(sizeof(char *) * (eac + 10));
X	       movmem ((char *)eav, (char *)scrav, sizeof(char *) * (eac + 1));
X	       free (eav);
X	       eav = scrav;
X	       eleft = 10;
X	    }
X	    eav[eac] = malloc (strlen(bname)+strlen(name)+1);
X	    eav[eac] = strcpy(eav[eac], bname);
X	    strcat(eav[eac], name);
X	    --eleft, ++eac;
X	 }
X      }
X   }
X   dirclose (dp);
X   *pac = eac;
X   eav[eac] = NULL;
X   free (bname);
X   free (base);
X   if (eac)
X      return (eav);
X   free (eav);
X   return (NULL);
X}
X
X/*
X * Compare a wild card name with a normal name
X */
X
X#define MAXB   8
X
Xcompare_ok(wild, name)
Xchar *wild, *name;
X{
X   char *w = wild;
X   char *n = name;
X   char *back[MAXB][2];
X   int  bi = 0;
X
X   while (*n || *w) {
X      switch (*w) {
X      case '*':
X	 if (bi == MAXB) {
X	    InfoMsg1Line("Too many levels of '*'");
X	    return (0);
X	 }
X	 back[bi][0] = w;
X	 back[bi][1] = n;
X	 ++bi;
X	 ++w;
X	 continue;
Xgoback:
X	 --bi;
X	 while (bi >= 0 && *back[bi][1] == '\0')
X	    --bi;
X	 if (bi < 0)
X	    return (0);
X	 w = back[bi][0] + 1;
X	 n = ++back[bi][1];
X	 ++bi;
X	 continue;
X      case '?':
X	 if (!*n) {
X	    if (bi)
X	       goto goback;
X	    return (0);
X	 }
X	 break;
X      default:
X	 if (toupper(*n) != toupper(*w)) {
X	    if (bi)
X	       goto goback;
X	    return (0);
X	 }
X	 break;
X      }
X      if (*n)  ++n;
X      if (*w)  ++w;
X   }
X   return (1);
X}
X
Xvoid
Xset_dir(new)
Xchar *new;
X{
X   register 	char 		*s;
X   int   			i;
X   struct 	FileLock 	*lock;
X   char 			temp[60];
X   struct       FileInfoBlock   *fib;
X
X   if (*new != '\000') {
X      strcpy(temp, MyDir);
X      s = new;
X      if (*s == '/') {
X	 s++;
X	 for (i=strlen(MyDir);
X	      MyDir[i] != '/' && MyDir[i] != ':';
X	      i--);
X	 MyDir[i+1] = '\0';
X	 strcat(MyDir, s);
X	 }
X      else if (exists(s, ':') == 0) {
X	 if (MyDir[strlen(MyDir)-1] != ':')
X	    strcat(MyDir, "/");
X	 strcat(MyDir, s);
X	 }
X      else
X	 strcpy(MyDir, s);
X
X      if ((lock = (struct FileLock *)Lock(MyDir, (long)ACCESS_READ)) == 0) {
X	 InfoMsg2Line("Directory not found:",MyDir);
X	 strcpy(MyDir, temp);
X	 }
X      else {
X	 fib = (struct FileInfoBlock *)AllocMem(
X		(long)sizeof(struct FileInfoBlock), MEMF_PUBLIC);
X	 if (fib) {
X	    if (Examine(lock, fib)) {
X		if (fib->fib_DirEntryType > 0) {
X		    UnLock(CurrentDir(lock));
X		    if (MyDir[strlen(MyDir)-1] == '/')
X			MyDir[strlen(MyDir)-1] = '\000';
X		    }
X		else {
X		    InfoMsg2Line("Not a Directory:",MyDir);
X		    strcpy(MyDir,temp);
X		    }
X		}
X	    FreeMem(fib, (long)sizeof(struct FileInfoBlock));
X	    }
X	else {
X	    InfoMsg1Line("Can't change directory...No free memory!");
X	    strcpy(MyDir,temp);
X	    }
X	}
X    }
X}
X
Xexists(s,c)
Xchar *s,c;
X    {
X    while (*s != '\000')
X	if (*s++ == c) return(1);
X    return(0);
X    }
SHAR_EOF
echo "extracting init.c"
sed 's/^X//' << \SHAR_EOF > init.c
X/***************************************************************
X * vt100 - terminal emulator - initialization
X *				:ts=8
X *
X *	v2.9 ACS - Support new cmds EXT.  Use S and R for Send and Receive menu
X *		   items instead of ^ and V.  AREXX support.
X *	v2.8a 880331 ACS - Allow lines 0 in init file to *really* mean
X *			  "use all available lines".
X *	v2.7 870825 ACS - Allow execution of all script files specified on
X *			  command line (companion to changes in script.c).
X *			  Rolled menu init into one routine (do_menu_init()).
X *	v2.6 870227 DBW - bug fixes for all the stuff in v2.5
X *	v2.5 870214 DBW - more additions (see readme file)
X *	v2.4 861214 DBW - lots of fixes/additions (see readme file)
X *	v2.3 861101 DBW - minor bug fixes
X *	v2.2 861012 DBW - more of the same
X *	v2.1 860915 DBW - new features (see README)
X *	     860901 ACS - Added Parity and Word Length and support code
X *	     860823 DBW - Integrated and rewrote lots of code
X *	v2.0 860809 DBW - Major rewrite
X *	v1.1 860720 DBW - Switches, 80 cols, colors, bug fixes
X *	v1.0 860712 DBW - First version released
X *
X ***************************************************************/
X
X#include "vt100.h"
X
Xstruct Device *ConsoleDevice = NULL;
Xstruct IOStdReq ConReq;
Xextern APTR OrigWindowPtr;
Xextern int capture;		/* in vt100.c */
X
X/*   Used by script.c for script file chaining. */
Xint script_files_todo = 0;
Xchar **script_files = NULL;
X
Xchar line[256];
X
X/* Command key equivalences per menu.  Manipulated by script.c */
X
X/*   Equivalences for the File menu... */
Xstruct filecmd {
X    char mo;	/* Mode			*/
X    char se;	/* Send			*/
X    char re;	/* Receive		*/
X    char kg;	/* Kermit Get		*/
X    char kb;	/* Kermit Bye		*/
X    char ca;	/* Capture or Capturing */
X    char nl;
X} filecmd_chars = { ' ', 'S', 'R', 'G', 'B', ' ', '\0' };
X
X/*   Equivalences for Mode sub-menu... */
Xstruct mode_cmd {
X    char as;	/* ascii mode		*/
X    char xm;	/* xmodem mode		*/
X    char xmc;	/* xmodemcrc mode	*/
X    char ke;	/* kermit mode		*/
X    char nl;
X} modecmd_chars = { ' ', 'X', ' ', 'K', '\0' };
X
X/*   Equivalences for the Comm menu... */
Xstruct commcmd {
X    char nl0;	/* Baud Sub-Item	*/
X    char nl1;	/* Parity Sub-Item	*/
X    char nl2;	/* Xfer mode Sub-Item	*/
X    char sh;	/* Shared item		*/
X    char nl;
X} commcmd_chars = { ' ', ' ', ' ', ' ', '\0' };
X
X/*   Equivalences for the Baud Rate sub-menu... */
Xstruct baudcmd {
X    char b03;	/* 0300			*/
X    char b12;	/* 1200			*/
X    char b24;	/* 2400			*/
X    char b48;	/* 4800			*/
X    char b96;	/* 9600			*/
X    char bnl;
X} baudcmd_chars = { ' ', 'L', 'H', ' ', ' ', '\0' };
X
X/*   Equivalences for the Parity sub-menu... */
Xstruct parcmd {
X    char no;	/* NOne			*/
X    char ma;	/* MArk			*/
X    char sp;	/* SPace		*/
X    char ev;	/* EVen			*/
X    char od;	/* ODd			*/
X    char nl;
X} parcmd_chars = { 'N', ' ', ' ', 'E', 'O', '\0' };
X
X/*   Equivalences for the Xfer Mode sub-menu... */
Xstruct modcmd {
X    char im;	/* IMage		*/
X    char tx;	/* TeXt			*/
X    char cn;	/* CoNvert		*/
X    char ac;	/* AutoChop		*/
X    char nl;
X} modcmd_chars = { 'I', 'T', ' ', ' ', '\0' };
X
X/*   Equivalences for the Script menu... */
Xstruct scrcmd {
X    char em;	/* Execute Macro	*/
X    char ab;	/* Abort Macro		*/
X    char rc;	/* AREXX Macro		*/
X    char nl;
X} scrcmd_chars = { 'M', 'A', ' ', '\0' };
X
X/*   Equivalences for the Utility menu... */
Xstruct utilcmd {
X    char sb;	/* Send Break	*/
X    char hu;	/* Hang Up	*/
X    char cd;	/* Change Dir	*/
X    char cs;	/* Clear Screen	*/
X    char ec;	/* ECho		*/
X    char wr;	/* WRap		*/
X    char nk;	/* Num Key	*/
X    char ac;	/* App Cur	*/
X    char bs;	/* BS<->DEL	*/
X    char xb;	/* Xfer beep	*/
X    char mu;	/* Mouse up events	*/
X    char md;	/* Mouse down events	*/
X    char nl;
X} utilcmd_chars = { '.', ' ', 'D', ' ', ' ', 'W', 'K', 'C', ' ', ' ', ' ', ' ', '\0' };
X
Xstatic char *filetext[] = {
X    "Protocol",
X    "Send",
X    "Receive",
X    "Kermit Get",
X    "Kermit BYE",
X    "Capture"
X};
X
Xstatic char *modetext[] = {
X    "  Ascii",
X    "  Xmodem",
X    "  XmodemCRC",
X    "  Kermit"
X};
X
Xstatic char *commtext[] = {
X    "Baud Rate",
X    "Parity   ",
X    "Xfer Mode",
X    "  Shared ",
X};
X
Xstatic char *baudtext[] = {
X    "   300",
X    "  1200",
X    "  2400",
X    "  4800",
X    "  9600"
X};
X
Xstatic char *partext[] = {
X    "  None ",
X    "  Mark ",
X    "  Space",
X    "  Even ",
X    "  Odd  "
X};
X
Xstatic char *modtext[] = {
X    "  Image  ",
X    "  Text   ",
X    "  Convert",
X    "  AutoChop"
X};
X
Xstatic char *scrtext[] = {
X    "Execute Macro",
X    "Abort Execution",
X    "AREXX Macro"
X};
X
Xstatic char *utiltext[] = {
X    "Send Break",
X    "Hang Up",
X    "Change Dir",
X    "Clear Scrn",
X    "  Echo",
X    "  Wrap",
X    "  Num Key",
X    "  App Cur",
X    "  BS<->DEL",
X    "  Xfer Beep",
X    "  Mouse Up",
X    "  Mouse Dn",
X};
X
Xstruct HowToInit {
X    int LeftEdge;	/* in characters, NOT pixels	*/
X    int Width;		/* 	ditto			*/
X    ULONG Flags;
X    char **text;
X    char *cmdkeys;
X};
X
Xstatic struct HowToInit menu_init[] = {
X	{ 0, 20, ITEMTEXT | ITEMENABLED | HIGHCOMP,
X	     filetext, (char *)(&filecmd_chars) },
X	{10, 17, ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT | MENUTOGGLE,
X	     modetext, (char *)(&modecmd_chars) },
X	{ 0, 11, ITEMTEXT | ITEMENABLED | HIGHCOMP,
X	     commtext, (char *)(&commcmd_chars) },
X	{ 10, 12, ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT | MENUTOGGLE,
X	       baudtext, (char *)(&baudcmd_chars) },
X	{ 10, 12, ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT | MENUTOGGLE,
X	      partext, (char *)(&parcmd_chars) },
X	{ 10, 15, ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT | MENUTOGGLE,
X	      modtext, (char *)(&modcmd_chars) },
X	{ 0, 20, ITEMTEXT | ITEMENABLED | HIGHCOMP,
X	     scrtext, (char *)(&scrcmd_chars) },
X	{ 0, 16, ITEMTEXT | ITEMENABLED | HIGHCOMP,
X	     utiltext, (char *)(&utilcmd_chars) }
X};
X
X#define FILE_INIT_ENTRY	(&(menu_init[0]))
X#define MODE_INIT_ENTRY (&(menu_init[1]))
X#define COMM_INIT_ENTRY	(&(menu_init[2]))
X#define RS_INIT_ENTRY	(&(menu_init[3]))
X#define PAR_INIT_ENTRY	(&(menu_init[4]))
X#define XF_INIT_ENTRY	(&(menu_init[5]))
X#define SCRIPT_INIT_ENTRY	(&(menu_init[6]))
X#define UTIL_INIT_ENTRY	(&(menu_init[7]))
X
Xvoid do_menu_init();
X
X#if AREXX
Xchar *rexxerrmsgs[] = {
X	"",
X	"No AREXX library - AREXX unavailable.",
X	"Can't contact AREXX server - AREXX unavailable.",
X	"Can't create an AREXX msg - AREXX unavailable.",
X	"Can't get memory for hostname.",
X	"VT100 AREXX port already present - another VT100 up?",
X	"Can't get memory for AREXX port."
X};
X#endif /* AREXX */
X
Xchar *InitDefaults(argc,argv)
Xint	argc;
Xchar	**argv;
X    {
X    FILE    *fd = NULL;
X    char    *p = NULL, *ifile, temp[80];
X    int     i, l, dont_init = 0, customfudge, maxrows, maxlines;
X
X    for(l = 0; l < EXTMAX; l++)
X	ExtXfer[l] = NULL;
X
X    doing_init = 1;	/* make sure we only allow INIT script commands */
X    if (argc > 1) {
X	int start_of_script_files = 1;
X
X	if(strcmp(argv[1], "-i") == 0) {	/* No init file */
X	    dont_init = 1;
X	    start_of_script_files = 2;
X	}
X	else if(strcmp(argv[1], "+i") == 0) {	/* Use specified init file */
X	    start_of_script_files = 3;
X    	    if((fd=fopen(argv[2],"r")) == NULL) {
X		ifile = AllocMem((LONG)(strlen(argv[2])+3), MEMF_PUBLIC|MEMF_CLEAR);
X		strcpy(ifile, "S:");
X		strcat(ifile, argv[2]);
X		fd = fopen(ifile, "r");
X		FreeMem(ifile, (LONG)(strlen(argv[2])+3));
X		ifile = NULL;
X	    }
X	}
X	if(start_of_script_files > argc)
X	    script_files_todo = 0;
X	else
X	    script_files_todo = argc - start_of_script_files; /* # of cmdline script files left */
X	script_files = &(argv[start_of_script_files]);	  /* Ptr to first of 'em */
X    }
X
X    if((p_font == NULL) || (p_font[0] == '\0'))
X	strcpy(myfontname, "topaz");
X    else
X	strcpy(myfontname, p_font);	/* Init font name */
X    strcat(myfontname, ".font");
X
X    if((p_device == NULL) || (p_device[0] == '\0'))
X	strcpy(mysername, SERIALNAME);
X    else
X	strcpy(mysername, p_device);
X
X#if AREXX
X    /*   Setup the AREXX interface now so user can use it during init. */
X    if( (RexxSysBase = (struct RxsLib *)OpenLibrary(RXSNAME, 0L))
X       == NULL)
X	puts("Can't open rexxsyslib.library - AREXX unavailable.");
X    else if( (i = makerexxport()) != 0)
X	cleanup(rexxerrmsgs[i], 256);
X#endif /* AREXX */
X
X    if(!dont_init)
X	if((fd == NULL) && ((fd=fopen("vt100.init","r")) == NULL))
X	    fd=fopen("s:vt100.init","r");
X
X    if(fd != NULL) {
X	while (fgets(line,256,fd) != 0) {
X	    if(line[strlen(line)-1] == '\n')
X		line[strlen(line)-1] = '\000';
X	    p = next_wrd(&line[0],&l);
X	    if (*p) {
X		*p |= ' ';
X		if (p[1]) p[1] |= ' ';
X		if (*p == '#') continue;
X		if (strncmp(p, "exi", 3) == 0) break;
X		exe_cmd(p,l);
X		}
X	}
X	fclose(fd);
X    }
X    doing_init = 0;
X
X    IntuitionBase = (struct IntuitionBase *)
X	OpenLibrary("intuition.library", INTUITION_REV);
X    if( IntuitionBase == NULL )
X	cleanup("can't open intuition",1);
X
X    GfxBase = (struct GfxBase *)
X	OpenLibrary("graphics.library",GRAPHICS_REV);
X    if( GfxBase == NULL )
X	cleanup("can't open graphics library",2);
X
X    DiskfontBase = (struct Library *)OpenLibrary("diskfont.library", 0L);
X    if(DiskfontBase == NULL)
X	cleanup("can't open diskfont library", 2);
X
X    if ( (myfont = (struct TextFont *)OpenFont(&myattr)) == NULL
X      && (myfont = (struct TextFont *)OpenDiskFont(&myattr)) == NULL) {
X	sprintf(temp, "Can't open font %s", myfontname);
X	cleanup(temp, 4);
X    }
X
X    Xsize = myfont->tf_XSize;
X    Ysize = myfont->tf_YSize;
X    BaseLine = myfont->tf_Baseline;
X
X    /* Now set up all the screen info as necessary */
X
X    maxrows = GfxBase->NormalDisplayRows;
X
X    /*   If user wants to use the current interlace setting then set p_interlace
X    ** according to what the ViewLord says it is. */
X    if(p_interlace == 2)
X	p_interlace = ((IntuitionBase->ViewLord.Modes & LACE) == LACE) ? 1 : 0;
X    else if((p_screen == 0) && ((IntuitionBase->ViewLord.Modes & LACE) == 0))
X	p_interlace = 0;
X
X    if(p_interlace)
X	maxrows *= 2;
X
X    customfudge = (p_screen == 1) ? 4 : 0;
X
X    /*   See if user wants to use everything available (specified LINES 0).If
X    ** so then set p_lines so we'll leave room for the window title.
X    ** (Ysize + 1) is the size of the window title bar.
X    ** (Ysize + 1 + customfudge) is used to allow us to account for the the 4
X    ** scan-lines we'll allow in CUSTOM screen mode so that the user can pull
X    ** the window down to expose the screen's depth arrangement gadgets.  Note
X    ** that it's OK to overwrite the last 2 lines or so of the window-title bar
X    ** (that's why we take the remainder first).
X    **/
X    if( ((maxrows - (Ysize + 1 - customfudge)) % Ysize) > (Ysize - 2) )
X	maxlines = (maxrows - Ysize + customfudge) / Ysize;
X    else
X	maxlines = (maxrows - (Ysize + 1 + customfudge)) / Ysize;
X    if(p_lines == 0)
X	p_lines = maxlines;
X    else if (p_lines > maxlines)
X	p_lines = maxlines;
X
X    /*   Set MINY.  MINY will be adjusted so we'll overwrite part of the
X    ** window title bar if necessary to get the last line to end at the bottom
X    ** of the window.
X    ** Remember that MINY is the location of the BASELINE of the character. */
X    {
X	int end = (Ysize + 2) + (p_lines * Ysize);
X
X	MINY = Ysize + 2;
X	if(end > maxrows)
X	    MINY -= (end - maxrows);
X	MINY += BaseLine;
X    }
X    if(p_screen == 1 && p_interlace == 1)
X	NewScreen.ViewModes |= LACE;
X
X    MAXY = MINY + ((p_lines - 1) * Ysize);
X    top  = MINY; bot  = MAXY;
X    savx = MINX; savy = MINY;
X
X    NewWindow.Height = MAXY + customfudge + (Ysize - BaseLine);
X    NewWindow.MinHeight = NewWindow.Height;
X    NewWindow.MaxHeight = NewWindow.Height;
X    NewReqWindow.MaxHeight = NewWindow.Height;
X    NewWindow.TopEdge	= 0L;
X
X    if (p_screen == 1) {
X	if (p_depth > 2)
X	    p_depth = 2;
X	else if (p_depth < 1)
X	    p_depth = 1;
X	NewScreen.Depth = (long)p_depth;
X	NewScreen.Height = NewWindow.Height + customfudge;
X	NewScreen.TopEdge = 0;
X    } else {
X	p_depth	= 2L;
X	NewWindow.Screen = NULL;
X	NewReqWindow.Screen = NULL;
X	NewWindow.Type = WBENCHSCREEN;
X	NewReqWindow.Type = WBENCHSCREEN;
X    }
X
X    /* see if we exit with a startup script */
X    if (strncmp(p, "exi", 3) == 0) {
X	p = next_wrd(p+l+1,&l);
X	if (*p) return(p);
X    }
X    if (script_files_todo > 0) {
X    	script_files_todo--;
X    	return(*(script_files++));
X    }
X    return(NULL);
X    }
X
Xvoid InitDevs()
X{
XUSHORT	colors[4];
Xint	i;
XBYTE	*b,*c;
Xstruct Process *mproc;
X
X    if (p_screen == 1) {
X	if ((myscreen = (struct Screen *)OpenScreen(&NewScreen)) == NULL)
X	    cleanup("can't open screen",3);
X	NewWindow.Screen = myscreen;
X	NewReqWindow.Screen = myscreen;
X    }
X
X    if ((mywindow = (struct Window *)OpenWindow(&NewWindow)) == NULL)
X	cleanup("can't open window",4);
X
X    if(OpenDevice("console.device", -1L, &ConReq, 0L))
X	cleanup("can't open console", 4);
X    ConsoleDevice = ConReq.io_Device;
X
X    if(p_screen == 1) {	/* Cause system reqs to come to this screen */
X	mproc = (struct Process *)FindTask(0L);
X	OrigWindowPtr = mproc->pr_WindowPtr;
X	mproc->pr_WindowPtr = (APTR)mywindow;
X    }
X
X    myviewport   = (struct ViewPort *)ViewPortAddress(mywindow);
X    myrastport   = (struct RastPort *)mywindow->RPort;
X
X    SetFont(myrastport,myfont);
X
X    if (p_depth > 1) myrequest.BackFill = 2;
X    if (p_screen != 0 && p_wbcolors == 0) {
X	colors[0] = p_background;
X	colors[1] = p_foreground;
X	colors[2] = p_bold;
X	colors[3] = p_cursor;
X	if (p_depth == 1)
X	    LoadRGB4(myviewport, colors, 2L);
X	else
X	    LoadRGB4(myviewport, colors, 4L);
X    }
X
X    Read_Request = (struct IOExtSer *)
X	AllocMem((long)sizeof(*Read_Request),MEMF_PUBLIC|MEMF_CLEAR);
X    Read_Request->io_SerFlags = (p_shared ? SERF_SHARED : 0);
X    Read_Request->IOSer.io_Message.mn_ReplyPort = CreatePort(0L,0L);
X    if(OpenDevice(mysername, (LONG)p_unit, (struct IORequest *)Read_Request, NULL))
X	cleanup("Can't open Read device",5);
X    rs_in = malloc(p_buffer+1);
X    Read_Request->io_SerFlags = 0L;
X    Read_Request->io_Baud	  = p_baud;
X    Read_Request->io_ReadLen  = 8L;
X    Read_Request->io_WriteLen = 8L;
X    Read_Request->io_CtlChar  = 0x11130000L;
X    Read_Request->io_RBufLen  = p_buffer;
X    Read_Request->io_BrkTime  = p_break;
X    Read_Request->IOSer.io_Command = SDCMD_SETPARAMS;
X    DoIO((struct IORequest *)Read_Request);
X    Read_Request->IOSer.io_Command = CMD_READ;
X    Read_Request->IOSer.io_Length  = 1;
X    Read_Request->IOSer.io_Data    = (APTR) &rs_in[0];
X
X    Write_Request = (struct IOExtSer *)
X	AllocMem((long)sizeof(*Write_Request),MEMF_PUBLIC|MEMF_CLEAR);
X    b = (BYTE *)Read_Request;
X    c = (BYTE *)Write_Request;
X    for (i=0;i<sizeof(struct IOExtSer);i++)
X	*c++ = *b++;
X    Write_Request->IOSer.io_Message.mn_ReplyPort = CreatePort(0L,0L);
X    Write_Request->IOSer.io_Command = CMD_WRITE;
X    Write_Request->IOSer.io_Length = 1;
X    Write_Request->IOSer.io_Data = (APTR) &rs_out[0];
X
X    Timer_Port = CreatePort("Timer Port",0L);
X    Script_Timer_Port = CreatePort("Timer Port",0L);
X
X    if (OpenDevice(TIMERNAME, UNIT_VBLANK, (struct IORequest *)&Timer, NULL) ||
X	OpenDevice(TIMERNAME, UNIT_VBLANK, (struct IORequest *)&Script_Timer, NULL))
X	cleanup("can't open timer device",7);
X
X    Timer.tr_node.io_Message.mn_ReplyPort = Timer_Port;
X    Timer.tr_node.io_Command = TR_ADDREQUEST;
X    Timer.tr_node.io_Flags = 0;
X    Timer.tr_node.io_Error = 0;
X
X    Script_Timer.tr_node.io_Message.mn_ReplyPort = Script_Timer_Port;
X    Script_Timer.tr_node.io_Command = TR_ADDREQUEST;
X    Script_Timer.tr_node.io_Flags = 0;
X    Script_Timer.tr_node.io_Error = 0;
X
X    BeepWave = (UBYTE *)AllocMem(BEEPSIZE,(long)(MEMF_CHIP|MEMF_CLEAR));
X    if (BeepWave != 0)
X	BeepWave[0] = 100;
X
X    Audio_Port = CreatePort("Audio Port",0L);
X
X    Audio_Request.ioa_Request.io_Message.mn_ReplyPort = Audio_Port;
X    Audio_Request.ioa_Request.io_Message.mn_Node.ln_Pri = 85;
X    Audio_Request.ioa_Data = Audio_AllocMap;
X    Audio_Request.ioa_Length = (ULONG) sizeof(Audio_AllocMap);
X
X    if (OpenDevice(AUDIONAME, NULL, (struct IORequest *)&Audio_Request, NULL))
X	cleanup("can't open audio device",8);
X
X    Audio_Request.ioa_Request.io_Command = CMD_WRITE;
X    Audio_Request.ioa_Request.io_Flags = ADIOF_PERVOL;
X    Audio_Request.ioa_Data = BeepWave;
X    Audio_Request.ioa_Length = BEEPSIZE;
X    Audio_Request.ioa_Period = COLORCLOCK / (BEEPSIZE * BEEPFREQ);
X    Audio_Request.ioa_Volume = p_volume;
X    Audio_Request.ioa_Cycles = 100;
X}
X
X/*****************************************************************/
X/*    The following function initializes the structure arrays	 */
X/*   needed to provide the File menu topic.			 */
X/*****************************************************************/
Xvoid InitFileItems()
X{
X    int n, nxfer;
X    struct HowToInit Externs;	/* for the external xfer pgms */
X    char *p, *p1;
X
X    if(capture == TRUE)
X	filetext[FILEMAX-1] = "Capturing";
X    else
X	filetext[FILEMAX-1] = "Capture";
X    do_menu_init(FileItem, FileText, FILE_INIT_ENTRY, FILEMAX);
X    FileItem[0].SubItem = ModeItem;
X    do_menu_init(ModeItem, ModeText, MODE_INIT_ENTRY, MODEMAX);
X
X    p = (char *)&Externs; p1 = (char *)MODE_INIT_ENTRY;
X    for(n = 0; n < sizeof(struct HowToInit); n++)
X	*(p++) = *(p1++);
X
X    nxfer = MODEMAX;
X    for(n = 0; n < NumExts; n++) {
X	struct ExternalXfer *exp = ExtXfer[n];
X
X	nxfer = n + MODEMAX;
X	ModeItem[nxfer-1].NextItem = &ModeItem[nxfer];
X	Externs.text = &exp->dispname;
X	*Externs.cmdkeys = exp->cmdkey;
X	do_menu_init(&ModeItem[nxfer], &ModeText[nxfer], &Externs, 1);
X	ModeItem[nxfer].TopEdge = 10 * nxfer;
X    }
X
X    for(n = 0; n <= nxfer; n++ ) {
X	ModeItem[n].MutualExclude = (~(1 << n));
X    }
X    if(p_xproto > nxfer) {
X	p_xproto = MODEMAX - 1;
X    }
X    ModeItem[p_xproto].Flags |= CHECKED;
X}
X
X/******************************************************************
X**			Main Comm menu
X**		set up for Baud & Parity submenus
X*******************************************************************/
Xvoid InitCommItems()
X{
X    int n;
X
X    do_menu_init(CommItem, CommText, COMM_INIT_ENTRY, COMMAX);
X    CommItem[0].SubItem = RSItem;
X    CommItem[1].SubItem = ParItem;
X    CommItem[2].SubItem = XFItem;
X    CommItem[3].Flags |= CHECKIT | MENUTOGGLE;
X    if(p_shared)
X	CommItem[3].Flags |= CHECKED;
X    else
X	CommItem[3].Flags &= (-1L ^ CHECKED);
X
X/*****************************************************************/
X/*    The following initializes the structure arrays		 */
X/*   needed to provide the BaudRate Submenu topic.		 */
X/*****************************************************************/
X
X    do_menu_init(RSItem, RSText, RS_INIT_ENTRY, RSMAX);
X    for( n=0; n<RSMAX; n++ ) {
X	RSItem[n].MutualExclude = (~(1 << n));
X    }
X
X    /* select baud item chekced */
X    switch (p_baud) {
X	case 300:	n = 0; break;
X	case 1200:	n = 1; break;
X	case 2400:	n = 2; break;
X	case 4800:	n = 3; break;
X	case 9600:	n = 4; break;
X	default:	n = 2; p_baud = 2400;
X    }
X    RSItem[n].Flags |= CHECKED;
X
X/* initialize text for specific menu items */
X
X/*****************************************************************/
X/*    The following initializes the structure arrays		 */
X/*   needed to provide the Parity   Submenu topic.		 */
X/*****************************************************************/
X
X    do_menu_init(ParItem, ParText, PAR_INIT_ENTRY, PARMAX);
X    for( n=0; n<PARMAX; n++ ) {
X	ParItem[n].MutualExclude = (~(1 << n));
X    }
X
X    /* select parity item chekced */
X    ParItem[p_parity].Flags |= CHECKED;
X
X/*****************************************************************/
X/*    The following initializes the structure arrays		 */
X/* initialize text for specific menu items */
X/*    needed to provide the Transfer Mode menu topic.		 */
X/*****************************************************************/
X
X    do_menu_init(XFItem, XFText, XF_INIT_ENTRY, XFMAX);
X    
X    /* initialize each menu item and IntuiText with loop */
X    for(n = 0; n < 2; n++)
X	XFItem[n].MutualExclude = 2 - n;
X
X    /* mode checked */
X    XFItem[p_mode].Flags |= CHECKED;
X    if (p_convert)
X	XFItem[2].Flags |= CHECKED;
X
X    if (p_autochop)
X	XFItem[3].Flags |= CHECKED;
X    
X} /* end of InitCommItems() */
X
X
X/*****************************************************************/
X/*    The following function initializes the structure arrays	 */
X/*   needed to provide the Script menu topic.			 */
X/*****************************************************************/
Xvoid InitScriptItems()
X{
X    do_menu_init(ScriptItem, ScriptText, SCRIPT_INIT_ENTRY, SCRIPTMAX);
X}
X
X/*****************************************************************/
X/*    The following function initializes the structure arrays	 */
X/*   needed to provide the Util menu topic.		       */
X/*****************************************************************/
Xvoid InitUtilItems()
X{
X    int	n;
X
X    do_menu_init(UtilItem, UtilText, UTIL_INIT_ENTRY, UTILMAX);
X    /* initialize each menu item and IntuiText with loop */
X    for( n=0; n<UTILMAX; n++ ) {
X	if (n > 3)
X	    UtilItem[n].Flags |= CHECKIT | MENUTOGGLE;
X    }
X
X    if (p_echo)
X	UtilItem[4].Flags |= CHECKED;
X    if (p_wrap)
X	UtilItem[5].Flags |= CHECKED;
X    if (p_keyapp == 0)
X	UtilItem[6].Flags |= CHECKED;
X    if (p_curapp)
X	UtilItem[7].Flags |= CHECKED;
X    if (p_bs_del)
X	UtilItem[8].Flags |= CHECKED;
X    if (p_xbeep)
X	UtilItem[9].Flags |= CHECKED;
X    if(p_mouse_up)
X	UtilItem[10].Flags |= CHECKED;
X    if(p_mouse_down)
X	UtilItem[11].Flags |= CHECKED;
X
X    swap_bs_del();	/* Setup keys[] properly... */
X    swap_bs_del();	/* ...for mode		    */
X}
X
X/****************************************************************/
X/*   The following function inits the Menu structure array with */
X/*  appropriate values for our simple menu.  Review the manual	*/
X/*  if you need to know what each value means.			*/
X/****************************************************************/
Xvoid InitMenu()
X{
X    menu[0].NextMenu = &menu[1];
X    menu[0].LeftEdge = 5;
X    menu[0].TopEdge = 0;
X    menu[0].Width = 40;
X    menu[0].Height = 10;
X    menu[0].Flags = MENUENABLED;
X    menu[0].MenuName = "File";	  /* text for menu-bar display */
X    menu[0].FirstItem = &FileItem[0]; /* pointer to first item in list */
X
X    menu[1].NextMenu = &menu[2];
X    menu[1].LeftEdge = 55;
X    menu[1].TopEdge = 0;
X    menu[1].Width = 88;
X    menu[1].Height = 10;
X    menu[1].Flags = MENUENABLED;
X    menu[1].MenuName = "Comm Setup";	/* text for menu-bar display */
X    menu[1].FirstItem = &CommItem[0];	/* pointer to first item in list */
X
X    menu[2].NextMenu = &menu[3];
X    menu[2].LeftEdge = 153;
X    menu[2].TopEdge = 0;
X    menu[2].Width = 56;
X    menu[2].Height = 10;
X    menu[2].Flags = MENUENABLED;
X    menu[2].MenuName = "Script";	/* text for menu-bar display */
X    menu[2].FirstItem = &ScriptItem[0];	/* pointer to first item in list*/
X
X    menu[3].NextMenu = NULL;
X    menu[3].LeftEdge = 225;
X    menu[3].TopEdge = 0;
X    menu[3].Width = 64;
X    menu[3].Height = 10;
X    menu[3].Flags = MENUENABLED;
X    menu[3].MenuName = "Utility";	   /* text for menu-bar display */
X    menu[3].FirstItem = &UtilItem[0];  /* pointer to first item in list*/
X}
X
Xvoid do_menu_init(menuitem, menutext, initentry, max)
Xstruct MenuItem menuitem[];
Xstruct IntuiText menutext[];
Xstruct HowToInit *initentry;
Xint max;
X{
X    int n, nplus1;
X    char **temp;
X
X    /* initialize each menu item and IntuiText with loop */
X    for( n=0; n < max; n++ ) {
X	nplus1 = n + 1;
X	temp = initentry->text;
X	menutext[n].IText = (UBYTE *)temp[n];
X	menuitem[n].NextItem = &menuitem[nplus1];
X	menuitem[n].LeftEdge = initentry->LeftEdge * Ysize;
X	menuitem[n].TopEdge = 10 * n;
X	menuitem[n].Width = initentry->Width * Ysize;
X	menuitem[n].Height = 10;
X	menuitem[n].Flags = initentry->Flags;
X	menuitem[n].MutualExclude = 0;
X	menuitem[n].ItemFill = (APTR)&menutext[n];
X	menuitem[n].SelectFill = NULL;
X	if((initentry->cmdkeys != NULL)
X	&& (initentry->cmdkeys[n])
X	&& (initentry->cmdkeys[n] != ' ')) {
X	    menuitem[n].Command  = initentry->cmdkeys[n];
X	    menuitem[n].Flags   |= COMMSEQ;
X	}
X	else menuitem[n].Command = 0;
X	menuitem[n].SubItem = NULL;
X	menuitem[n].NextSelect = 0;
X    
X	menutext[n].FrontPen = 0;
X	menutext[n].BackPen = 1;
X	menutext[n].DrawMode = JAM2;/* render in fore and background */
X	menutext[n].LeftEdge = 0;
X	menutext[n].TopEdge = 1;
X	menutext[n].ITextFont = NULL;
X	menutext[n].NextText = NULL;
X    }
X    menuitem[max-1].NextItem = NULL;
X}
X
X#if AREXX
Xmakerexxport()
X{
X    int i,
X	ret = 0;
X    long hostlen = strlen(HOSTNAMEROOT) + strlen(mysername) + 1 + 2 + 1;
X			/* "VT100-"            name          "-" "xx" \0 */
X
X    if(HostName) {
X	FreeMem(HostName, (ULONG)(strlen(HostName)+1));
X	HostName = NULL;
X    }
X
X    if( (HostName = AllocMem(hostlen, MEMF_PUBLIC | MEMF_CLEAR)) == NULL)
X	return NOHOSTMEM;
X
X    sprintf(HostName, "%s%s-%02d", HOSTNAMEROOT, mysername, p_unit);
X
X    Forbid();
X    
X    if(FindPort(HostName) != NULL)
X	ret = HAVEVT100PORT;
X    else if( (FromRexxPort = (struct MsgPort *)AllocMem((LONG)sizeof(struct MsgPort),
X			     MEMF_PUBLIC | MEMF_CLEAR)) == NULL)
X	ret = NOPORTMEM;
X    else {
X	InitPort(FromRexxPort, HostName);
X	AddPort(FromRexxPort);
X    }
X
X    Permit();
X    if(ret && RexxSysBase) {
X	CloseLibrary((struct Library *)RexxSysBase);
X	RexxSysBase = NULL;
X    }
X    return ret;
X}
X#endif /* AREXX */
SHAR_EOF
echo "End of archive 5 (of 9)"
# if you want to concatenate archives, remove anything after this line
exit