page%swap@Sun.COM (Bob Page) (10/20/89)
Submitted-by: acs@pccuts.pcc.amdahl.com (Tony Sumrall)
Posting-number: Volume 89, Issue 186
Archive-name: comm/vt100r29.9
# 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:
# vt100.h
# vt100.init
# window.c
# xmodem.c
# This is archive 9 of a 9-part kit.
# This archive created: Thu Oct 19 22:30:35 1989
echo "extracting vt100.h"
sed 's/^X//' << \SHAR_EOF > vt100.h
X/*********************************************************************
X * a terminal program that has ascii and xmodem transfer capability
X * :ts=8
X *
X * v2.9 ACS - See change summary.
X * v2.8a 880331 ACS - Update title to 2.8A.
X * v2.7 870825 ACS - See README.
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 * 860823 DBW - Integrated and rewrote lots of code
X * v2.0 860809 DBW - Major release.. LOTS of changes
X * v1.1 860720 DBW - Switches, 80 cols, colors, bug fixes
X * v1.0 860712 DBW - First version released
X *
X * use esc to abort xmodem transfer
X *
X * written by Michael Mounier
X * new version by Dave Wecker 860621
X ********************************************************************/
X
X/********* major version (used for title of terminal window) *********/
X#define VERSION "VT100 (V2.9 ACS 891003) Terminal Window"
X
X/*********** ######## define the compiler type here ######## ********/
X#define LATTICE 0
X#define MANX 1
X
X/* compiler directives to fetch the necessary header files */
X#include <exec/types.h>
X#include <exec/exec.h>
X#include <intuition/intuition.h>
X#include <intuition/intuitionbase.h>
X#include <graphics/gfxbase.h>
X#include <graphics/gfx.h>
X#include <graphics/text.h>
X#include <graphics/regions.h>
X#include <graphics/copper.h>
X#include <graphics/gels.h>
X#include <devices/serial.h>
X#include <devices/keymap.h>
X#include <devices/inputevent.h>
X#include <devices/audio.h>
X#include <hardware/blit.h>
X
X /* for Lattice you may have to change these with: */
X#include <stdio.h> /* #include <lattice/stdio.h> and */
X#include <ctype.h> /* #include <lattice/ctype.h> */
X
X#include <libraries/dos.h>
X#include <libraries/dosextens.h>
X#include <devices/timer.h>
X
X#if LATTICE
X#include <stdlib.h>
X#include <string.h>
X#include <proto/exec.h>
X#include <proto/graphics.h>
X#include <proto/intuition.h>
X#include <proto/dos.h>
X#include <proto/timer.h>
X#endif
X
X#if AREXX
X#include <rexx/rxslib.h>
X#include <rexx/storage.h>
X#endif /* AREXX */
X
X#if MANX
X#include <functions.h>
X#undef NULL
X#define NULL ((void *)0)
X#endif /* MANX */
X
X#define INTUITION_REV 1L
X#define GRAPHICS_REV 1L
X
X/* things for xmodem send and recieve */
X#define GOODREAD 0
X#define TIMEOUT 1
X#define USERABORT 2
X#define SECSIZ 0x80
X#define TTIME_SHORT 5 /* number of seconds for short timeout */
X#define TTIME_LONG 50 /* number of seconds for long timeout */
X#define TTIME_KERMIT 10 /* number of seconds for KERMIT timeout*/
X#define MAXLONGPKS 1000 /* Maximum long msgpkt size */
X#define BufSize 0x1080 /* Text buffer for XMODEM */
X#define ERRORMAX 10 /* Max errors before abort */
X#define RETRYMAX 10 /* Maximum retrys before abort */
X#define SOH 1 /* Start of sector char */
X#define EOT 4 /* end of transmission char */
X#define ACK 6 /* acknowledge sector transmission */
X#define NAK 21 /* error in transmission detected */
X
X#define FILEMAX 6 /* number of file menu items */
X#define MODEMAX 4 /* number of mode menu items */
X#define EXTMAX 10 /* number of external xfer pgms allowed */
X#define COMMAX 4 /* number of communication sub menus */
X#define RSMAX 5 /* speed menu items */
X#define PARMAX 5 /* parity items */
X#define XFMAX 4 /* transfer mode items */
X#define SCRIPTMAX 3 /* script menu items */
X#define UTILMAX 12 /* utility menu */
X#define MAXMENU 4 /* total number of menu entries */
X
X#define MAXGADSTR 80 /* Max size of prompts and inputs */
X
X#define FSF_REVERSE 256 /* fake font style to flag INVERSVID mode */
X
X#define FONTNAMESIZE 40
X#define FONTSUFFIX ".font"
X#define MAXFONTVARLEN 34 /* 40 minus sizeof(".font") */
X
Xextern char myfontname[];
X
X#define SERNAMESIZE 80
X
Xextern char mysername[];
X
X
X/* Structure to hold the external xfer program names and command strings */
Xstruct ExternalXfer {
X char *dispname; /* Display name - shown on menu */
X char *downname; /* downcased name for cmd_short() */
X char *send; /* Command string to use for send */
X char *receive; /* Command string to use for receive */
X char cmdkey; /* Command key equivalent */
X};
X
Xextern struct ExternalXfer *(ExtXfer[EXTMAX]); /* Defined in vt100.c */
Xextern int NumExts; /* Number of ExtXfers */
X
X/* things for script support */
X
X#define GOTOLABEL 1
X#define NEXTCOMMAND 0
X#define ONCOMMAND 2
X
X#define WAIT_TIMER 2
X#define WAIT_STRING 1
X
X/* exe_cmd return values */
X#define CMDOK 0 /* Command OK */
X#define CMDWARN 5 /* Command issued WARNING msg */
X#define CMDNF 10 /* Command Not Found */
X#define CMDBS 11 /* Bad State (e.g. INIT only) */
X#define CMDFAIL 13 /* Command failed */
X
X/* things for 'beep' support */
X#define BEEPSIZE 10L
X#define BEEPFREQ 1000L
X#define COLORCLOCK 3579545L
X
X/* things for MENUPICK support */
X#define REDOFILE 1
X#define REDOCOMM 2
X#define REDOUTIL 4
X
Xextern struct MsgPort *CreatePort();
X
Xextern int CmdFromRexx; /* Command came from the AREXX port */
X
X#if AREXX
Xextern struct RexxMsg *CreateRexxMsg();
Xextern STRPTR *CreateArgstring();
Xextern struct MsgPort *FromRexxPort; /* Port we receive AREXX msgs on */
X
X#define HOSTNAMEROOT "VT100-"
X
X/* Indices into rexxerrmsgs[] in init.c */
X
X#define NORXLIB 1 /* No AREXX library */
X#define NORXPORT 2 /* No AREXX port */
X#define NORXMSG 3 /* Can't create AREXX message */
X#define NOHOSTMEM 4 /* Can't get memory for HostName*/
X#define HAVEVT100PORT 5 /* VT100 port already exists */
X#define NOPORTMEM 6 /* Can't get mem for a port */
X
Xextern char *rexxerrmsgs[]; /* in init.c */
Xextern int makerexxport(); /* in init.c */
X
Xextern char *HostName; /* Our host port name for AREXX */
Xextern char *ForwardPortName; /* Port to which to forward data */
Xextern int forwarding; /* Flag to indicate if we should fwd */
X#endif /* AREXX */
X
X#if MANX
Xextern char *malloc(),*strcpy(),*fgets();
X#endif /* MANX */
X
Xextern long ftell();
X
Xextern int multi; /* flags multi file transfers */
Xextern int server;
Xextern char *bufr; /* Buffer that XMODEM uses */
Xextern int fd, timeout, ttime;
Xextern long bytes_xferred;
Xextern char MyDir[60];
Xextern BPTR StartLock;
Xextern struct IntuitionBase *IntuitionBase;
Xextern struct GfxBase *GfxBase;
Xextern struct Library *DiskfontBase;
X
X#if AREXX
Xextern struct RxsLib *RexxSysBase;
X#endif /* AREXX */
X
Xextern struct TextAttr myattr;
Xextern struct TextFont *myfont;
Xextern struct NewScreen NewScreen;
Xextern struct NewWindow NewWindow;
Xextern struct NewWindow NewReqWindow;
Xextern struct Screen *myscreen;
Xextern struct Window *mywindow;
Xextern struct Window *reqwindow;
Xextern struct ViewPort *myviewport;
Xextern struct RastPort *myrastport;
Xextern struct IntuiMessage *NewMessage;
Xextern struct Preferences *Prefs;
Xextern char InpBuf[80],UndoBuf[80],Prompt[80];
Xextern struct StringInfo mystrinfo;
Xextern struct Gadget mystrgad;
Xextern struct IntuiText donetxt;
Xextern struct Gadget mydonegad;
Xextern struct IntuiText mystrtxt;
Xextern struct Requester myrequest;
Xextern int numreqs;
Xextern int reqwinup;
Xextern struct MenuItem FileItem[FILEMAX];
Xextern struct IntuiText FileText[FILEMAX];
Xextern struct MenuItem ModeItem[MODEMAX+EXTMAX];
Xextern struct IntuiText ModeText[MODEMAX+EXTMAX];
Xextern struct MenuItem CommItem[COMMAX];
Xextern struct IntuiText CommText[COMMAX];
Xextern struct MenuItem RSItem[RSMAX];
Xextern struct IntuiText RSText[RSMAX];
Xextern struct MenuItem ParItem[PARMAX];
Xextern struct IntuiText ParText[PARMAX];
Xextern struct MenuItem XFItem[XFMAX];
Xextern struct IntuiText XFText[XFMAX];
Xextern struct MenuItem ScriptItem[SCRIPTMAX];
Xextern struct IntuiText ScriptText[SCRIPTMAX];
Xextern struct MenuItem UtilItem[UTILMAX];
Xextern struct IntuiText UtilText[UTILMAX];
Xextern struct Menu menu[MAXMENU];
Xextern struct timerequest Timer, Script_Timer;
Xextern struct MsgPort *Timer_Port, *Script_Timer_Port;
Xextern struct IOExtSer *Read_Request;
Xextern char *rs_in;
Xextern struct IOExtSer *Write_Request;
Xextern char rs_out[2];
Xextern int x,y,curmode;
Xextern int Xsize, MINX,MAXX,Ysize,MINY,MAXY,BaseLine,top,bot,savx,savy;
Xextern int savmode,nlmode,alt,savalt,a[2],sa[2];
Xextern int inesc,inctrl,private,badseq,maxcol;
Xextern struct IOAudio Audio_Request;
Xextern struct MsgPort *Audio_Port;
Xextern UBYTE *BeepWave;
Xextern UBYTE Audio_AllocMap[4];
Xextern int p_baud,p_screen,p_interlace,p_depth,p_buffer,p_wbcolors;
Xextern int p_foreground,p_background,p_bold,p_cursor,p_lines,p_mode;
Xextern int p_parity,p_volume,p_wrap,p_echo,p_keyapp,p_curapp,p_bs_del;
Xextern int p_xbeep, p_xproto, p_convert,p_autochop, p_kmaxpack, p_unit;
Xextern int p_fontsize, p_shared, p_mouse_up, p_mouse_down;
Xextern char p_keyscript;
Xextern long p_break;
Xextern char *p_font, *p_device, *p_f[11],*p_F[10];
Xextern int script_on;
Xextern int script_wait;
Xextern int doing_init;
X
X/* vt100.c */
Xextern int do_send(),do_capture();
Xextern void cleanup();
Xextern ULONG handle_menupick();
Xextern void setserpar(), setserbaud(), setparams(), redoutil(), redofile(),
X redocomm();
X
X/* init.c */
Xextern void InitDevs(),InitFileItems(),InitCommItems(),
X InitScriptItems(),InitUtilItems(),InitMenu();
Xextern char *InitDefaults();
Xextern int maxrows; /* number of scan lines available */
X
X/* window.c */
Xextern void swap_bs_del(),req(),emits(),emit(),emitbatch(),cursorflip();
Xextern int toasc();
Xextern void ScrollInfoMsg(), InfoMsgNoScroll(), InfoMsg1Line(),
X InfoMsg2Line();
X
X/* xmodem.c */
Xextern void sendchar(),sendstring(),sendbreak(),multi_xfer(),
X No_XON(),Do_XON();
Xextern int readchar(),XMODEM_Read_File(),XMODEM_Send_File();
X
X/* remote.c */
Xextern void doremote(),doindex(),doctrl(),doesc(),doerase();
X
X/* kermit.c */
Xextern int doksend(), dokreceive();
Xextern void encode(), decode(), rpar(), spar(), saybye();
X
X/* script.c */
Xextern int script_start(), chk_script(),
X do_script_cmd();
Xextern char *next_wrd(), *tostring();
Xextern int exit_script(), do_ext();
X
X /* init commands */
Xextern int cmd_bkg(), cmd_bold(), cmd_buf(), cmd_cursor(), cmd_depth(),
X cmd_device(), cmd_display(), cmd_fore(), cmd_font(),
X cmd_fonts(), cmd_inter(), cmd_lines(), cmd_screen(),
X cmd_unit(), cmd_volume(), cmd_wb(), cmd_null(),
X
X /* script commands */
X cmd_as(), cmd_beep(), cmd_cap(), cmd_cd(), cmd_delay(),
X cmd_goto(), cmd_goto(), cmd_kb(), cmd_kg(), cmd_kr(),
X cmd_ks(), cmd_msg(), cmd_on(), cmd_recf(), cmd_sb(),
X cmd_send(), cmd_sendf(), cmd_wait(), cmd_xr(), cmd_xs(),
X
X /* init and script commands */
X cmd_ac(), cmd_appcur(), cmd_baud(), cmd_bt(), cmd_conv(),
X cmd_echo(), cmd_exit(), cmd_ext(), cmd_fnc(), cmd_key(),
X cmd_kmode(), cmd_kmaxpk(), cmd_mode(), cmd_mouse(),
X cmd_numkey(), cmd_parity(), cmd_share(), cmd_short(),
X cmd_swap(), cmd_wrap(), cmd_xbeep(), cmd_xproto();
X
X /* rexx-only commands */
Xextern int cmd_rx(), cmd_fwd();
X
X/* expand.c */
Xextern char **expand();
Xextern void set_dir(), free_expand();
SHAR_EOF
echo "extracting vt100.init"
sed 's/^X//' << \SHAR_EOF > vt100.init
X# Setup 2 external protocols:
X# Zmodem with -Q (quit without waiting for a click in the close box) and
X# -I (take serial parameters from zmodem.init)
X EXTERNAL Zmodem "sz -QI @LOCAL" "rz -QI"
X# Ymodem with -B (use Ymodem instead of Zmodem), -Q and -I as above.
X EXTERNAL Ymodem "sz -BQI @LOCAL" "rz -BQI"
X# Select Zmodem as the default protocol.
X XPROTO Zmodem
SHAR_EOF
echo "extracting window.c"
sed 's/^X//' << \SHAR_EOF > window.c
X/****************************************************
X * vt100 emulator - window/keyboard support
X * :ts=8
X *
X * v2.9 ACS - See change summary.
X * v2.7 870825 ACS - Provide an info/status window rather than using
X * req(). Better error handling.
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 * 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
Xstatic char *infkey[] = { /* F-keys resulting from RawKeyConvert() */
X "0~", "1~", "2~", "3~", "4~", "5~", "6~", "7~", "8~", "9~",
X "10~", "11~", "12~", "13~", "14~", "15~", "16~", "17~", "18~", "19~",
X NULL};
X
X/* Cursor keys resulting from RawKeyConvert() and their output values */
Xstatic struct {
X char *in; /* in sequence */
X char *out_curapp; /* out sequence in p_curapp */
X char *out; /* out sequence !in p_curapp */
X} ckeys[] = {
X "A", "OA", "[A",
X "T", "OA", "[A",
X "B", "OB", "[B",
X "S", "OB", "[B",
X "C", "OC", "[C",
X " A~", "OC", "[C",
X "D", "OD", "[D",
X " @~", "OD", "[D",
X NULL, NULL, NULL };
X
X/* Numeric keypad for A2000 and A500 have keys that the A1000 doesn't have.
X** Use them for the VT100 F-keys. */
Xstatic char npfkey[] = {
X '(', 'P', ')', 'Q', '*', 'R', '/', 'S', 0, 0};
X
X/* Numeric keypad return values excluding HELP, '-' and ENTER */
Xstatic char keypad[] = {
X 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', '\0'};
X/* Numeric keypad return values for HELP, - and ENTER */
Xstatic char speckeypad[] = {
X '-', 'l', '-',
X '.', 'n', '.',
X '\015', 'M', '\015',
X '\0', '\0', '\0' };
X
X/* For InfoMsg...may be changed by a NEWSIZE msg in vt100.c */
Xint reqminx, /* Min value for x in reqwindow (pixels) */
X reqmaxx, /* Max value for x in reqwindow (pixels) */
X reqmaxlen, /* Max # chars in reqwindow */
X reqminy, /* Min value for y in reqwindow (scan lines) */
X reqmaxy, /* Max value for y in reqwindow (scan lines) */
X reqfudge; /* Clear space between border and start of 1st char */
Xint reqy; /* Current pixel location in reqwindow */
X
Xvoid ReqNewSize(), OpenReqWindow();
X
X/***************************************************
X * function to swap the use of backspace and delete
X ***************************************************/
X
Xvoid swap_bs_del()
X{
X if (p_bs_del) p_bs_del = 0;
X else p_bs_del = 1;
X}
X
X/*************************************************
X * function to get file name (via a requestor)
X *************************************************/
Xvoid req(prmpt,name,getinp)
Xchar *prmpt,*name;
Xint getinp;
X {
X ULONG class;
X#if MANX
X USHORT RemoveGadget();
X#endif /* MANX */
X int lprmpt, lname;
X struct IntuiMessage *Msg;
X
X if(reqwinup == 0)
X OpenReqWindow();
X
X if(!getinp) {
X InfoMsg2Line(prmpt, name);
X return;
X }
X
X lprmpt = strlen(prmpt);
X lname = strlen(name);
X
X /* Don't use strings longer than what we've provided space for. */
X if(lprmpt > (MAXGADSTR-1)) {
X emits("Prompt too long - truncated.\n");
X lprmpt = MAXGADSTR-1;
X }
X if(lname > (MAXGADSTR-1)) {
X emits("Name too long - truncated.\n");
X lname = MAXGADSTR-1;
X }
X
X if (Msg = (struct IntuiMessage *)GetMsg(reqwindow->UserPort)) {
X class = Msg->Class;
X ReplyMsg((struct Message *)Msg);
X if(class == REQCLEAR)
X numreqs = 0;
X if(class == NEWSIZE)
X ReqNewSize(reqwindow->Height, reqwindow->Width);
X }
X
X /* Make sure the prompt gets updated */
X if (numreqs == 1 && strcmp(Prompt,prmpt) != 0) {
X EndRequest(&myrequest,reqwindow);
X do {
X Wait(1L << reqwindow->UserPort->mp_SigBit);
X while (Msg = (struct IntuiMessage *)GetMsg(reqwindow->UserPort)) {
X class = Msg->Class;
X ReplyMsg((struct Message *)Msg);
X if(class == NEWSIZE)
X ReqNewSize(reqwindow->Height, reqwindow->Width);
X }
X } while (class != REQCLEAR);
X numreqs = 0;
X }
X
X /* copy in a prompt and a default */
X strncpy(Prompt,prmpt,lprmpt); Prompt[lprmpt] = '\0';
X strncpy(InpBuf,name,lname); InpBuf[lname] = '\0';
X mystrinfo.BufferPos = lname;
X
X if (numreqs == 1) { /* If there is a requester... reuse it */
X RefreshGadgets(&mystrgad, reqwindow, &myrequest);
X Delay(2L);
X }
X else { /* otherwise create it */
X while(numreqs != 1) {
X if (Request(&myrequest, reqwindow) == 0) {
X emits("ERROR - CAN'T CREATE REQUESTOR FOR:\n");
X emits(Prompt); emit('\n'); emits(InpBuf); emit('\n');
X return;
X }
X else numreqs = 1;
X
X do {
X Wait(1L << reqwindow->UserPort->mp_SigBit);
X while (Msg = (struct IntuiMessage *)GetMsg(reqwindow->UserPort)) {
X class = Msg->Class;
X ReplyMsg((struct Message *)Msg);
X if(class == REQCLEAR)
X numreqs = 0;
X if(class == NEWSIZE)
X ReqNewSize(reqwindow->Height, reqwindow->Width);
X }
X } while (class != REQSET);
X } /* end while numreqs != 0 */
X } /* end else */
X
X /* if we don't want input, we're done */
X if (getinp == 0 || numreqs == 0) return;
X
X if((reqwindow->Flags & WINDOWACTIVE) != WINDOWACTIVE) {
X WindowToFront(reqwindow);
X ActivateWindow(reqwindow);
X do {
X Wait(1L << reqwindow->UserPort->mp_SigBit);
X while(Msg = (struct IntuiMessage *)GetMsg(reqwindow->UserPort)) {
X class = Msg->Class;
X ReplyMsg((struct Message *)Msg);
X if(class == NEWSIZE)
X ReqNewSize(reqwindow->Height, reqwindow->Width);
X }
X } while (class != ACTIVEWINDOW);
X }
X
X /* here is where we pre-select the gadget */
X if (!ActivateGadget(&mystrgad,reqwindow,&myrequest)) {
X
X /* wait for his/her hands to get off the keyboard (Amiga-key) */
X Delay(20L);
X while (Msg = (struct IntuiMessage *)GetMsg(reqwindow->UserPort)) {
X ReplyMsg((struct Message *)Msg);
X if(class == NEWSIZE)
X ReqNewSize(reqwindow->Height, reqwindow->Width);
X }
X
X /* try once more before giving up... */
X ActivateGadget(&mystrgad,reqwindow,&myrequest);
X }
X
X /* wait for input to show up */
X while (1) {
X if ((NewMessage = (struct IntuiMessage *)
X GetMsg(reqwindow->UserPort)) == FALSE) {
X Wait(1L<<reqwindow->UserPort->mp_SigBit);
X continue;
X }
X class = NewMessage->Class;
X ReplyMsg((struct Message *)NewMessage);
X
X /* the requestor got terminated... yea!! */
X if (class == REQCLEAR) break;
X
X if(class == NEWSIZE)
X ReqNewSize(reqwindow->Height, reqwindow->Width);
X
X /* maybe this is a menu item to handle */
X/* if (class == MENUPICK) handle_menupick(class,code); */
X }
X
X /* all done, so return the result */
X numreqs = 0;
X strcpy(name,InpBuf);
X if (reqwinup && ((reqwindow->Flags) & WINDOWACTIVE))
X ActivateWindow(mywindow);
X }
X
X/*************************************************
X* function to print a string
X*************************************************/
Xvoid emits(string)
Xchar string[];
X {
X int i;
X char c;
X
X i=0;
X while (string[i] != 0)
X {
X c=string[i];
X if (c == 10) emit(13);
X emit(c);
X i += 1;
X }
X }
X
X/*************************************************
X* function to output ascii chars to window
X*************************************************/
Xvoid emit(c)
Xchar c;
X {
X static char wrap_flag = 0; /* are we at column 80? */
X
X c &= 0x7F;
X switch( c )
X {
X case '\t':
X x += (Ysize * 8) - ((x-MINX) % (Ysize * 8));
X break;
X
X case 10: /* lf */
X doindex('D');
X break;
X
X case 13: /* cr */
X x = MINX;
X break;
X
X case 8: /* backspace */
X x -= Xsize;
X if (x < MINX) x = MINX;
X break;
X
X case 12: /* page */
X x = MINX;
X y = MINY;
X SetAPen(mywindow->RPort,0L);
X RectFill(mywindow->RPort,(long)MINX,
X (long)(MINY-BaseLine),(long)(MAXX+(Xsize-1)),(long)(MAXY+1));
X SetAPen(mywindow->RPort,1L);
X break;
X
X case 7: /* bell */
X cmd_beep(0L);
X break;
X
X default:
X if (c < ' ' || c > '~') break;
X if (p_wrap && wrap_flag && x >= MAXX) {
X x = MINX;
X doindex('D');
X if (y > MAXY) {
X y = MAXY;
X ScrollRaster(mywindow->RPort,0L,(long)Ysize,(long)MINX,
X (long)(MINY-(BaseLine+1)),(long)(MAXX+(Xsize - 1)),
X (long)(MAXY+1));
X }
X }
X Move(mywindow->RPort,(long)x,(long)y);
X
X if (curmode&FSF_BOLD) {
X if (p_depth > 1) {
X SetAPen(mywindow->RPort,(long)(2+(1^p_screen)));
X SetSoftStyle(mywindow->RPort,(long)curmode,253L);
X }
X else SetSoftStyle(mywindow->RPort,(long)curmode,255L);
X }
X else SetSoftStyle(mywindow->RPort,(long)curmode,255L);
X
X if (curmode&FSF_REVERSE) {
X SetDrMd(mywindow->RPort,(long)(JAM2+INVERSVID));
X Text(mywindow->RPort,&c,1L);
X SetDrMd(mywindow->RPort,(long)JAM2);
X }
X else Text(mywindow->RPort,&c,1L);
X
X if (curmode&FSF_BOLD) SetAPen(mywindow->RPort,1L);
X x += Xsize;
X } /* end of switch */
X
X if (y > MAXY) {
X y = MAXY;
X x = MINX;
X ScrollRaster(mywindow->RPort,0L,(long)Ysize,(long)MINX,
X (long)(MINY-(BaseLine+1)),(long)(MAXX+(Xsize - 1)),
X (long)(MAXY+1));
X }
X if (x > MAXX) {
X wrap_flag = 1;
X x = MAXX;
X }
X else wrap_flag = 0;
X }
X
X/*************************************************
X* function to output ascii chars to window (batched)
X*************************************************/
Xvoid emitbatch(la,lookahead)
Xint la;
Xchar *lookahead;
X {
X int i;
X
X Move(mywindow->RPort,(long)x,(long)y);
X i = x / Xsize;
X if (i+la >= maxcol) {
X if (p_wrap == 0) la = maxcol - i;
X else {
X lookahead[la] = 0;
X emits(lookahead);
X return;
X }
X }
X if (curmode&FSF_BOLD) {
X if (p_depth > 1) {
X SetAPen(mywindow->RPort,(long)(2+(1^p_screen)));
X SetSoftStyle(mywindow->RPort,(long)curmode,253L);
X }
X else SetSoftStyle(mywindow->RPort,(long)curmode,255L);
X }
X else SetSoftStyle(mywindow->RPort,(long)curmode,255L);
X
X if (curmode&FSF_REVERSE) {
X SetDrMd(mywindow->RPort,(long)(JAM2+INVERSVID));
X Text(mywindow->RPort,lookahead,(long)la);
X SetDrMd(mywindow->RPort,(long)JAM2);
X }
X else Text(mywindow->RPort,lookahead,(long)la);
X if (curmode&FSF_BOLD) SetAPen(mywindow->RPort,1L);
X x += (Xsize * la);
X }
X
X/******************************
X* Manipulate cursor
X******************************/
Xvoid cursorflip()
X {
X SetDrMd(mywindow->RPort,(long)COMPLEMENT);
X SetAPen(mywindow->RPort,3L);
X RectFill(mywindow->RPort, (long)(x), (long)(y-BaseLine),
X (long)(x+Xsize-1), (long)(y+(Ysize-BaseLine-1)));
X SetAPen(mywindow->RPort,1L);
X SetDrMd(mywindow->RPort,(long)JAM2);
X }
X
X/************************************************
X* function to take raw key data and convert it
X* into ascii chars
X**************************************************/
Xint toasc(retstr, code, qual, maxlen, ia, local)
Xunsigned char *retstr;
Xunsigned int code,qual;
Xint local, maxlen;
XAPTR ia;
X{
X unsigned int ctrl, alt, npad;
X int i,
X cmatch,
X length = 0; /* length of returned string */
X unsigned char *p = retstr;
X static struct InputEvent ievent = {NULL, IECLASS_RAWKEY,0,0,0};
X
X *p = '\0';
X
X if(code >= 0x5a && code <= 0x5d) {
X /* Appears to be one of the keys (, ), /, * on the newer keypads.
X ** Convert them to VT100 F1-F4 */
X char t, *convert = "()*/";
X
X t = convert[code - 0x5a];
X for(i = 0; npfkey[i]; i++)
X if(t == npfkey[i]) {
X strcpy(p, "\033O");
X *(p+2) = npfkey[i+1];
X *(p+3) = '\0';
X length = 3;
X break;
X }
X if(*p) {
X sendstring(p);
X return length;
X }
X }
X
X ctrl = qual & IEQUALIFIER_CONTROL;
X alt = qual & (IEQUALIFIER_LALT | IEQUALIFIER_RALT);
X npad = qual & IEQUALIFIER_NUMERICPAD;
X
X ievent.ie_Qualifier = qual;
X
X ievent.ie_Code = code;
X /* get previous codes from location pointed to by IAddress
X * this "magic" pointer is valid intil the IntiiMessage is
X * replied
X */
X ievent.ie_position.ie_addr = ia;
X length = RawKeyConvert(&ievent, retstr, (LONG)maxlen, NULL);
X if(length == 0)
X return length;
X
X *(p+length) = '\0'; /* Null terminate the value */
X
X if(npad && length == 1) { /* keypad (excluding HELP key)? */
X register char t = *p;
X
X if(t == '(' || t == ')' || t == '*' || t == '/') {
X for(i = 0; npfkey[i]; i++)
X if(t == npfkey[i]) {
X strcpy(p, "\033O");
X *(p+2) = npfkey[i+1];
X *(p+3) = '\0';
X length = 3;
X break;
X }
X } else if((t >= '0') && (t <= '9')) {
X if(p_keyapp) {
X strcpy(p, "\033O");
X *(p+2) = keypad[t-'0'];
X *(p+3) = '\0';
X length = 3;
X } /* else *p is correct */
X } else for(i = 0; speckeypad[i]; i += 3)
X if(speckeypad[i] == t) {
X if(p_keyapp) {
X strcpy(p, "\033O");
X *(p+2) = speckeypad[i+1];
X length = 3;
X } else
X *p = speckeypad[i+2];
X break;
X }
X } else if((length == 3) && (strcmp(p, "\233?~") == 0)) {
X /* HELP key -- only gen something if in app keypad mode */
X if(p_keyapp) {
X strcpy(p, "\033Om");
X length = 3;
X } else {
X *p = '\0';
X length = 0;
X }
X } else if(length > 1 && retstr[0] == 0x9b) { /* cursor or F-keys? */
X cmatch = 0;
X for(i = 0; ckeys[i].in && !cmatch; i++) {
X if(p_curapp
X && strcmp((p+1), ckeys[i].in) == 0) {
X strcpy((p+1), ckeys[i].out_curapp);
X *p = 0x1b;
X length = strlen(ckeys[i].out_curapp)+1;
X cmatch = 1;
X } else if(strcmp((p+1), ckeys[i].in) == 0) {
X strcpy((p+1), ckeys[i].out);
X *p = 0x1b;
X length = strlen(ckeys[i].out)+1;
X cmatch = 1;
X }
X }
X if(!cmatch) { /* Not cursor, try F-keys */
X for(i = 0; infkey[i]; i++) {
X if(strcmp((p+1), infkey[i]) == 0) {
X if(i > 9)
X strcpy(p, p_F[i-10]);
X else strcpy(p, p_f[i]);
X if(!script_on && *p == p_keyscript) {
X script_start(p+1);
X *p = '\0';
X length = 0;
X }
X length = strlen(p);
X break;
X }
X }
X }
X } else if(ctrl && (length == 1)) {
X /* Control key shortcuts? */
X switch(*p) {
X case '6':
X *p = 30;
X break;
X case '2':
X case ' ': /* @ done by RawKeyConvert? */
X if(!local)
X *p = (alt ? 128 : 0);
X break;
X case '-':
X case '?':
X *p = 31;
X break;
X }
X } else if(alt && !local && length == 1)
X *p |= 0x80; /* Add hi bit if ALT is the only modifier */
X else if(p_bs_del && *p == 8 && length == 1)
X *p = 0x7f;
X else if(p_bs_del && *p == 0x7f && length == 1)
X *p = 8;
X
X/* if (ctrl) { Are all of these taken care of?
X if (c > '`' && c <= 127) c -= 96;
X else if (c > '@' && c <= '_') c -= 64;
X else if (c == '6') c = 30;
X else if (c == '-' || c == '?') c = 31;
X } */
X for(i = 0; i < length; i++)
X sendchar(*(p++));
X return(length);
X}
X
Xvoid
XKillReq()
X{
X struct IntuiMessage *Msg;
X ULONG class;
X
X if(numreqs != 0) {
X EndRequest(&myrequest,reqwindow);
X do {
X Wait(1L << reqwindow->UserPort->mp_SigBit);
X while (Msg = (struct IntuiMessage *)GetMsg(reqwindow->UserPort)) {
X class = Msg->Class;
X ReplyMsg((struct Message *)Msg);
X }
X } while (class != REQCLEAR);
X numreqs = 0;
X }
X
X if(reqwinup) {
X /* First, clear out all pending messages */
X while (Msg = (struct IntuiMessage *)GetMsg(reqwindow->UserPort)) {
X class = Msg->Class;
X ReplyMsg((struct Message *)Msg);
X }
X NewReqWindow.LeftEdge = reqwindow->LeftEdge; /* Remember ... */
X NewReqWindow.TopEdge = reqwindow->TopEdge; /* ...where... */
X NewReqWindow.Width = reqwindow->Width; /* ...the user... */
X NewReqWindow.Height = reqwindow->Height; /* ...put it. */
X CloseWindow(reqwindow); /* Now we can close the window */
X reqwinup = 0;
X }
X}
X
Xvoid
XInfoMsg2Line(header, msg)
Xchar *header, *msg;
X{
X ScrollInfoMsg(1);
X InfoMsgNoScroll(header);
X ScrollInfoMsg(1);
X InfoMsgNoScroll(msg);
X ScrollInfoMsg(1);
X}
X
Xvoid
XInfoMsg1Line(msg)
Xchar *msg;
X{
X ScrollInfoMsg(1);
X InfoMsgNoScroll(msg);
X ScrollInfoMsg(1);
X}
X
X/* Output the specified data to the "info" window */
Xvoid
XScrollInfoMsg(lines)
Xint lines;
X{
X/* ULONG class;
X struct IntuiMessage *Msg; */
X int pixels = lines * Ysize;
X
X if(!reqwinup)
X OpenReqWindow();
X
X/* if(Msg=(struct IntuiMessage *)GetMsg(reqwindow->UserPort)) {
X class = Msg->Class;
X ReplyMsg(Msg);
X if(class == NEWSIZE)
X ReqNewSize(reqwindow->Height, reqwindow->Width);
X } */
X
X if ( (reqy += pixels) > reqmaxy) {
X reqy = reqmaxy;
X if(pixels > 0)
X ScrollRaster(reqwindow->RPort, 0L, (LONG)pixels,
X (LONG)reqminx,
X (LONG)reqminy,
X (LONG)(reqmaxx+(Xsize - 1)),
X (LONG)(reqmaxy+(Ysize - 1)));
X/* Was: (LONG)(wp->Width - wp->BorderRight),
X (LONG)(wp->Height - wp->BorderBottom)); */
X }
X}
X
Xvoid
XInfoMsgNoScroll(msg)
Xchar *msg;
X{
X LONG msglen = strlen(msg);
X
X ScrollInfoMsg(0); /* Ensure that the msg will be visible */
X
X if(msglen > reqmaxlen)
X msglen = reqmaxlen;
X
X /* Position the pen at the baseline of the character (BaseLine scan
X ** lines into it). */
X Move(reqwindow->RPort, (LONG)reqminx, (LONG)(reqy+BaseLine));
X Text(reqwindow->RPort, msg, msglen);
X}
X
Xvoid
XReqNewSize(height, width)
XSHORT height, width;
X{
X register struct Window *wp = reqwindow;
X int oldmaxy;
X
X /* Compute min and max for x and y coordinates. Note that for y the
X ** value is for the *top* of the character, not the baseline. Text()
X ** uses a baseline value and so it must be adjusted prior to the call.
X ** When computing the max values, calculate them so that we will have
X ** sufficient room for an entire character. */
X oldmaxy = reqmaxy;
X reqminy = wp->BorderTop + reqfudge;
X reqmaxy = (((height - reqminy - wp->BorderBottom) / Ysize) * Ysize)
X + (reqminy-Ysize);
X reqminx = wp->BorderLeft + reqfudge;
X reqmaxx = (((width - reqminx - wp->BorderRight) / Xsize) * Xsize)
X + (reqminx-Xsize);
X reqmaxlen = (reqmaxx+(Xsize-1)) / Xsize;
X if(oldmaxy > reqmaxy) { /* Clean up the bottom of the window */
X int temp = height - wp->BorderBottom - reqmaxy;
X
X ScrollRaster(wp->RPort, 0L, (LONG)temp,
X (LONG)reqminx,
X (LONG)reqmaxy,
X (LONG)(width - wp->BorderRight),
X (LONG)(height - wp->BorderBottom));
X }
X}
X
Xvoid
XOpenReqWindow()
X{
X struct IntuiMessage *Msg;
X ULONG class;
X void ReqNewSize();
X static init = 1;
X
X if(init) {
X myrequest.LeftEdge = (myrequest.LeftEdge * Xsize) + 5;
X myrequest.TopEdge = (myrequest.TopEdge * Ysize) + 2;
X myrequest.Width = (myrequest.Width * Ysize) + 4;
X myrequest.Height = (myrequest.Height * Xsize) + 6;
X
X mydonegad.LeftEdge = (mydonegad.LeftEdge * Xsize) + 2;
X mydonegad.TopEdge = (mydonegad.TopEdge * Ysize) + 2;
X mydonegad.Width = ((strlen(donetxt.IText) + 1) * Xsize) + 0;
X mydonegad.Height = (mydonegad.Height * Ysize) + 2;
X
X mystrgad.LeftEdge = (mystrgad.LeftEdge * Xsize) + 2;
X mystrgad.TopEdge = (mystrgad.TopEdge * Ysize) + 4;
X mystrgad.Width = (mystrgad.Width * Ysize) + 0;
X mystrgad.Height = (mystrgad.Height * Xsize) + 2;
X
X donetxt.LeftEdge = (donetxt.LeftEdge * Xsize) + 0;
X donetxt.TopEdge = (donetxt.TopEdge * Ysize) + 0;
X
X mystrtxt.LeftEdge = (mystrtxt.LeftEdge * Xsize) + 2;
X mystrtxt.TopEdge = (mystrtxt.TopEdge * Ysize) + 2;
X
X NewReqWindow.Width = (NewReqWindow.Width * Xsize) + 4 + 18;
X NewReqWindow.LeftEdge = (NewReqWindow.LeftEdge * Xsize) + 2;
X NewReqWindow.LeftEdge = NewWindow.LeftEdge + NewWindow.Width
X - NewReqWindow.Width;
X
X NewReqWindow.TopEdge = (NewReqWindow.TopEdge * Ysize) + 7;
X NewReqWindow.Height = (NewReqWindow.Height * Ysize) + 11 + 2;
X
X init = 0;
X }
X
X reqwindow = OpenWindow(&NewReqWindow);
X do {
X Wait(1L << reqwindow->UserPort->mp_SigBit);
X while(Msg = (struct IntuiMessage *)GetMsg(reqwindow->UserPort)) {
X class = Msg->Class;
X ReplyMsg((struct Message *)Msg);
X }
X } while (class != ACTIVEWINDOW);
X reqfudge = 0; /* Leave 0 pixels/scan lines between border and char */
X ReqNewSize(reqwindow->Height, reqwindow->Width);
X reqy = reqminy; /* Top of character set by ReqNewSize() */
X reqwinup = 1;
X if (reqwinup && ((reqwindow->Flags) & WINDOWACTIVE))
X ActivateWindow(mywindow);
X}
SHAR_EOF
echo "extracting xmodem.c"
sed 's/^X//' << \SHAR_EOF > xmodem.c
X/*************************************************************
X * vt100 terminal emulator - XMODEM protocol support
X * :ts=8
X *
X * v2.9 ACS - multi_xfer() no longer looks for $ -- kermit does,
X * readchar() now infers ttime of 100,000 micros if ttime == 0
X * (for newkermit); readchar() doesn't output a TIMED OUT msg
X * (because of newkermit); speed up sendstring().
X * v2.7 870825 ACS - Make multi_xfer() non-recursive; on non-ESC in
X * readchar() re-do the main window's title.
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 * 860815 Steve Drew: readchar inproved with real timeouts
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
Xint enablexon = TRUE;
X
Xextern struct IntuiText MyTitle;
X
Xstatic unsigned long parity_settings[4] = {
X 0x96696996,
X 0x69969669,
X 0x69969669,
X 0x96696996 };
X
X/* crctab calculated by Mark G. Mendel, Network Systems Corporation */
Xstatic unsigned short crctab[256] = {
X 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
X 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
X 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
X 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
X 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
X 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
X 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
X 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
X 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
X 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
X 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
X 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
X 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
X 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
X 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
X 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
X 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
X 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
X 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
X 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
X 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
X 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
X 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
X 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
X 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
X 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
X 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
X 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
X 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
X 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
X 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
X 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
X};
X
X/*
X * updcrc macro derived from article Copyright (C) 1986 Stephen Satchell.
X * NOTE: First srgument must be in range 0 to 255.
X * Second argument is referenced twice.
X *
X * Programmers may incorporate any or all code into their programs,
X * giving proper credit within the source. Publication of the
X * source routines is permitted so long as proper credit is given
X * to Stephen Satchell, Satchell Evaluations and Chuck Forsberg,
X * Omen Technology.
X */
X
X#define updcrc(cp, crc) ( crctab[((crc >> 8) & 255)] ^ (crc << 8) ^ cp)
X
X/************************************************************
X* Send a string (using sendchar below)
X************************************************************/
X
Xvoid sendstring(s)
Xregister char *s;
X{
X char data[20];
X register char *cp = data;
X int i;
X LONG oldlength = Write_Request->IOSer.io_Length;
X APTR saveaddr = Write_Request->IOSer.io_Data;
X
X Write_Request->IOSer.io_Length = sizeof(data)-1;
X Write_Request->IOSer.io_Data = (APTR) &(data[0]);
X
X if (enablexon)
X No_XON();
X
X while(i = *(s++)) {
X *(cp++) = addparity(i);
X if( (cp - data) == sizeof(data)-1) {
X *cp = '\0';
X do
X DoIO((struct IORequest *)Write_Request);
X while(Write_Request->IOSer.io_Error != 0);
X cp = data;
X }
X }
X if(cp > data) {
X *(cp++) = '\0';
X Write_Request->IOSer.io_Length = strlen(data);
X do
X DoIO((struct IORequest *)Write_Request);
X while(Write_Request->IOSer.io_Error != 0);
X }
X
X Write_Request->IOSer.io_Length = oldlength;
X Write_Request->IOSer.io_Data = saveaddr;
X
X if (enablexon)
X No_XON();
X}
X
X/**************************************************************/
X/* send char and read char functions for the xmodem function */
X/************************************************************/
Xvoid sendchar(ch)
Xint ch;
X{
X if (enablexon)
X No_XON();
X
X rs_out[0] = addparity(ch);
X
X do {
X DoIO((struct IORequest *)Write_Request);
X } while(Write_Request->IOSer.io_Error != 0);
X
X if (enablexon)
X Do_XON();
X}
X
Xstatic int
Xaddparity(ch)
Xregister int ch;
X{
X int i, j, k;
X
X if(p_parity > 0)
X switch (p_parity) {
X case 1: /* mark */
X ch = (ch & 0x7F) | 0x80;
X break;
X
X case 2: /* space */
X ch &= 0x7F;
X break;
X
X case 3: /* even */
X case 4: /* odd */
X i = (ch >> 5) & 0x3;
X j = ch & 0x1F;
X k = ((parity_settings[i] >> j) & 0x1) << 7;
X if (p_parity == 3) /* even parity */
X ch = (ch & 0x7F) | k;
X else /* odd parity */
X ch = (ch & 0x7F) | (k ^ 0x80);
X }
X return(ch & 0xFF);
X}
X
X/* send a break to the host */
Xvoid sendbreak()
X{
X AbortIO((struct IORequest *)Read_Request);
X Wait(1L << Read_Request->IOSer.io_Message.mn_ReplyPort->mp_SigBit);
X WaitIO((struct IORequest *)Read_Request);
X Read_Request->IOSer.io_Command = SDCMD_BREAK;
X DoIO((struct IORequest *)Read_Request);
X Read_Request->IOSer.io_Command = CMD_READ;
X SendIO((struct IORequest *)Read_Request);
X}
X
Xint readchar()
X{
X int rd,ch;
X ULONG class, waitmask;
X USHORT code;
X
X if(ttime == 0)
X Timer.tr_time.tv_micro = 100000;
X else
X Timer.tr_time.tv_micro = 0;
X Timer.tr_time.tv_secs = ttime;
X SendIO((struct IORequest *)&Timer.tr_node);
X
X rd = FALSE;
X waitmask = ((1L << Read_Request->IOSer.io_Message.mn_ReplyPort->mp_SigBit) |
X ( 1L << mywindow->UserPort->mp_SigBit) |
X ( 1L << Timer_Port->mp_SigBit));
X if(reqwinup)
X waitmask |= (1L << reqwindow->UserPort->mp_SigBit);
X while (rd == FALSE) {
X Wait(waitmask);
X if (CheckIO((struct IORequest *)Read_Request)) {
X WaitIO((struct IORequest *)Read_Request);
X ch=rs_in[0];
X rd = TRUE;
X SendIO((struct IORequest *)Read_Request);
X }
X if(reqwinup &&
X (NewMessage=(struct IntuiMessage *)GetMsg(reqwindow->UserPort))) {
X class = NewMessage->Class;
X ReplyMsg((struct Message *)NewMessage);
X if(class == NEWSIZE)
X ReqNewSize(reqwindow->Height, reqwindow->Width);
X }
X if (NewMessage=(struct IntuiMessage *)GetMsg(mywindow->UserPort)) {
X class = NewMessage->Class;
X code = NewMessage->Code;
X ReplyMsg((struct Message *)NewMessage);
X if ((class == RAWKEY) && (code == 69)) {
X if(!CheckIO((struct IORequest *)&Timer))
X AbortIO((struct IORequest *)&Timer);
X Wait (1L << Timer_Port->mp_SigBit);
X WaitIO((struct IORequest *)&Timer.tr_node);
X InfoMsg1Line("ERROR: User aborted transfer");
X timeout = USERABORT;
X return('\0');
X }
X PrintIText(mywindow->RPort, &MyTitle, 0L, 0L);
X }
X
X if (rd == FALSE && CheckIO((struct IORequest *)&Timer)) {
X/* InfoMsg1Line("ERROR: Timeout waiting for character"); */
X timeout = TIMEOUT;
X return('\0');
X }
X } /* end while */
X if(!CheckIO((struct IORequest *)&Timer))
X AbortIO((struct IORequest *)&Timer);
X Wait (1L << Timer_Port->mp_SigBit);
X WaitIO((struct IORequest *)&Timer.tr_node);
X timeout = GOODREAD;
X return(ch & (p_parity == 0 ? 0xFF : 0x7F));
X}
X
Xvoid No_XON()
X{
X
X /* turn off XON/XOFF processing */
X enablexon = FALSE;
X Write_Request->io_SerFlags |= SERF_XDISABLED;
X Write_Request->IOSer.io_Command = SDCMD_SETPARAMS;
X DoIO((struct IORequest *)Write_Request);
X Write_Request->IOSer.io_Command = CMD_WRITE;
X}
X
Xvoid Do_XON()
X{
X /* turn on XON/XOFF processing */
X enablexon = TRUE;
X Write_Request->io_SerFlags &= ~SERF_XDISABLED;
X Write_Request->IOSer.io_Command = SDCMD_SETPARAMS;
X DoIO((struct IORequest *)Write_Request);
X Write_Request->IOSer.io_Command = CMD_WRITE;
X}
X
X/**************************************/
X/* xmodem send and recieve functions */
X/************************************/
X
Xint XMODEM_Read_File(file)
Xchar *file;
X{
X int firstchar, sectnum, sectcurr, sectcomp, errors, errorflag,
X c, good_sect, nak_char, retval = FALSE;
X unsigned int checksum, j, bufptr;
X unsigned short crc;
X char scrstr2[40];
X
X bytes_xferred = 0L;
X ttime = TTIME_SHORT;
X
X if( (bufr = AllocMem((long)BufSize, MEMF_PUBLIC|MEMF_CLEAR)) == NULL) {
X InfoMsg1Line("XMODEM: Can't get a buffer.");
X return FALSE;
X }
X
X if ((fd = creat(file, 0)) < 0) {
X InfoMsg2Line("XMODEM Can't Open File:",file);
X goto exit;
X } else
X InfoMsg1Line("XMODEM Receive, <esc> in VT100 window to abort");
X
X sectnum = errors = bufptr = firstchar = 0;
X if(p_xproto == 2)
X nak_char = 'C';
X else
X nak_char = NAK;
X No_XON();
X sendchar(nak_char);
X while (firstchar != EOT && errors != ERRORMAX) {
X errorflag = FALSE;
X
X while( (firstchar = readchar()) != SOH && firstchar != EOT) {
X if (timeout != GOODREAD) {
X if (timeout == USERABORT || errors++ == ERRORMAX)
X goto exit;
X }
X sendchar(nak_char);
X }
X
X if (firstchar == SOH) {
X sprintf(scrstr2,"%s: Block: %4d Bytes: %d",
X p_xproto==2?"XmodemCRC":"Xmodem", sectnum, sectnum*SECSIZ);
X InfoMsgNoScroll(scrstr2);
X sectcurr = readchar();
X if (timeout != GOODREAD)
X goto exit;
X sectcomp = readchar();
X if (timeout != GOODREAD)
X goto exit;
X if ((sectcurr + sectcomp) == 255) {
X if (sectcurr == ((sectnum + 1) & 0xff)) {
X checksum = 0; crc = 0;
X for (j = bufptr; j < (bufptr + SECSIZ); j++) {
X bufr[j] = readchar();
X if (timeout != GOODREAD)
X goto exit;
X checksum = (checksum + bufr[j]) & 0xff;
X crc = updcrc(((unsigned int)bufr[j] & 0xff), crc);
X }
X c = readchar();
X if(timeout != GOODREAD) {
X errorflag = TRUE;
X if(timeout == USERABORT)
X goto exit;
X }
X if(p_xproto == 2) {
X crc = updcrc(((unsigned int)c & 0xff), crc);
X c = readchar();
X if(timeout != GOODREAD) {
X errorflag = TRUE;
X if(timeout == USERABORT)
X goto exit;
X }
X crc = updcrc(((unsigned int)c & 0xff), crc);
X good_sect = (crc == 0);
X } else
X good_sect = (checksum == c);
X if (!good_sect) {
X errorflag = TRUE;
X if(timeout == USERABORT)
X goto exit;
X } else {
X errors = 0;
X/* sprintf(scrstr2,"Block %4d verified",sectnum); */
X sectnum++;
X bufptr += SECSIZ;
X bytes_xferred += SECSIZ;
X/* InfoMsgNoScroll(scrstr2); */
X if (bufptr == BufSize) {
X if (write(fd, bufr, BufSize-SECSIZ) == EOF) {
X InfoMsg1Line("XMODEM: Error Writing File");
X goto exit;
X }
X bufptr = SECSIZ;
X for (j = 0; j < SECSIZ; j++)
X bufr[j] = bufr[(BufSize-SECSIZ)+j];
X }
X sendchar(ACK);
X }
X } else {
X /* got a duplicate sector */
X if (sectcurr == (sectnum & 0xff)) {
X /* wait until we time out for 5secs */
X do {
X readchar();
X } while (timeout == GOODREAD);
X if (timeout == USERABORT)
X goto exit;
X InfoMsg1Line("XMODEM: Received Duplicate Sector");
X sendchar(ACK);
X }
X else errorflag = TRUE;
X }
X } else errorflag = TRUE;
X }
X if (errorflag == TRUE) {
X errors++;
X InfoMsg1Line("XMODEM: Error");
X sendchar(nak_char);
X }
X } /* end while */
X if ((firstchar == EOT) && (errors < ERRORMAX)) {
X sendchar(ACK);
X if (bufptr) {
X if(p_autochop) {
X /* use firstchar to remember the last char for chopping */
X if((firstchar = bufr[--bufptr]) == 0 || firstchar == 0x1A)
X while (bufptr && bufr[--bufptr] == firstchar)
X ;
X bufptr++;
X }
X write(fd, bufr, bufptr);
X }
X close(fd);
X ScrollInfoMsg(1);
X retval = TRUE;
X }
Xexit:
X Do_XON();
X FreeMem(bufr, (long)BufSize);
X bufr = NULL;
X return retval;
X}
X
Xint XMODEM_Send_File(file)
Xchar *file;
X{
X int sectnum, bytes_to_send, size, attempts, c, use_crc = 0,
X retval = FALSE;
X unsigned checksum, j, bufptr;
X unsigned short crc;
X char scrstr2[40];
X
X bytes_xferred = 0;
X ttime = TTIME_LONG;
X
X if( (bufr = AllocMem((long)BufSize, MEMF_PUBLIC|MEMF_CLEAR)) == NULL) {
X InfoMsg1Line("XMODEM: Can't get a buffer.");
X return FALSE;
X }
X
X if ((fd = open(file, 0)) < 0) {
X InfoMsg1Line("XMODEM: Cannot Open Send File");
X FreeMem(bufr, (long)BufSize);
X bufr = NULL;
X return FALSE;
X } else
X InfoMsg1Line("XMODEM Send, <esc> from VT100 window to abort");
X attempts = 0;
X sectnum = 1;
X No_XON();
X /* wait for sync char */
X j=1;
X while (((c = readchar()) != NAK) && (c != 'C') && (j++ < ERRORMAX))
X if (timeout == USERABORT)
X goto bad_exit;
X
X if (j >= (ERRORMAX)) {
X InfoMsg1Line("XMODEM: Receiver not sending");
X goto bad_exit;
X }
X
X if(c == 'C')
X use_crc = 1;
X while ((bytes_to_send = read(fd, bufr, BufSize)) &&
X attempts != RETRYMAX) {
X if (bytes_to_send == EOF) {
X InfoMsg1Line("XMODEM: Error Reading File");
X goto bad_exit;
X }
X
X bufptr = 0;
X while (bytes_to_send > 0 && attempts != RETRYMAX) {
X attempts = 0;
X sprintf(scrstr2,"%s: Sending Block: %4d Bytes: %d",
X use_crc?"XmodemCRC":"Xmodem", sectnum, sectnum*SECSIZ);
X size = SECSIZ <= bytes_to_send ? SECSIZ : bytes_to_send;
X bytes_to_send -= size;
X do {
X InfoMsgNoScroll(scrstr2);
X sendchar(SOH);
X sendchar(sectnum);
X sendchar(~sectnum);
X checksum = 0; crc = 0;
X for (j = bufptr; j < bufptr + size; j++) {
X sendchar(bufr[j]); /* send buffer data */
X checksum += bufr[j];
X crc = updcrc(((unsigned int)bufr[j] & 0xff), crc);
X }
X if( size < SECSIZ ) { /* check if we need to pad */
X c = bufr[j-1] ? 0 : 0x1A; /* choose correct padding */
X j = SECSIZ - size;
X checksum += j * c;
X while ( j-- ) {
X if(use_crc)
X crc = updcrc(c, crc);
X sendchar(c); /* send padding */
X }
X }
X if(use_crc) {
X crc = updcrc(0, updcrc(0, crc));
X sendchar(crc >> 8);
X sendchar(crc & 0xff);
X } else
X sendchar(checksum);
X attempts++;
X c = readchar();
X if (timeout == USERABORT) {
X InfoMsg1Line("XMODEM: ABORTED");
X goto bad_exit;
X }
X } while ((c != ACK) && (attempts != RETRYMAX));
X bufptr += size;
X bytes_xferred += size;
X/* sprintf(scrstr2,"Sent block %4d",sectnum);
X InfoMsgNoScroll(scrstr2); */
X sectnum++;
X }
X }
X close(fd);
X if (attempts == RETRYMAX) {
X InfoMsg1Line("XMODEM: No Acknowledgment, ABORTING");
X goto bad_exit;
X } else {
X attempts = 0;
X do {
X sendchar(EOT);
X attempts++;
X } while ((readchar() != ACK) &&
X (attempts != RETRYMAX) &&
X (timeout != USERABORT)) ;
X if (attempts == RETRYMAX)
X InfoMsg1Line("XMODEM: No end of file");
X }
X ScrollInfoMsg(1);
X retval = TRUE;
X
Xbad_exit:
X Do_XON();
X FreeMem(bufr, (long)BufSize);
X bufr = NULL;
X return retval;
X}
X
X/* allow for multi file xfers separated by commas under
X kermit and XMODEM */
X
Xvoid multi_xfer(name,mode,do_send)
Xchar *name;
Xint (*mode)();
Xint do_send;
X {
X int done = 0;
X int status;
X char *p, *name_start;
X
X timeout = USERABORT - 1;
X for(p=name_start=name; !done && timeout != USERABORT; name_start=++p)
X {
X if (*(name_start+1) == '\0')
X return;
X
X while(*p == ' ') p++;
X while(*p && *p != ',' && *p != ' ') p++;
X if (*p == '\0') {
X done = TRUE;
X multi = 0;
X }
X else
X multi = 1;
X *p = '\0';
X
X status = ((*mode)(name_start, multi));
X if (status == FALSE) close(fd);
X }
X server = 0;
X multi = 0;
X if(p_xbeep)
X cmd_beep(0L);
X }
X
SHAR_EOF
echo "End of archive 9 (of 9)"
# if you want to concatenate archives, remove anything after this line
exit