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