doc@s.cc.purdue.edu (Craig Norborg) (10/03/87)
# This is a shell archive.
# Remove everything above and including the cut line.
# Then run the rest of the file through sh.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# Xshar: Extended Shell Archiver.
# This is part 3 out of 3.
# This archive created: Sat Oct 3 01:36:26 1987
# By: Craig Norborg (Purdue University Computing Center)
# Run the following text with /bin/sh to create:
# script.c
# vt100.c
# vt100.h
# xmodem.c
cat << \SHAR_EOF > script.c
/*************************************************************
* vt100 terminal emulator - Script file support
*
* v2.7 870825 ACS - Wait for the reply from AbortIO().
* Use the *InfoMsg*() routines in window.c. Provide
* for multiple script files on command line
* (companion to the changes in init.c). Add the
* ability to set shortcuts from init file.
* v2.6 870227 DBW - bug fixes for all the stuff in v2.5
* v2.5 870214 DBW - more additions (see readme file)
* v2.4 861214 DBW - lots of fixes/additions (see readme file)
* v2.3 861101 DBW - minor bug fixes
* v2.2 861012 DBW - more of the same
* v2.1 860915 DBW - new features (see README)
* 860901 ACS - Added BAUD, PARITY and WORD commands & handling
* 860823 DBW - Integrated and rewrote lots of code
* 860815 Steve Drew: Initial version written of SCRIPT.C
* v2.0 860809 DBW - Major rewrite
* v1.1 860720 DBW - Switches, 80 cols, colors, bug fixes
* v1.0 860712 DBW - First version released
*
*************************************************************/
#include "vt100.h"
struct COMMAND {
void (*func)();
char *cname;
};
struct LABEL {
struct LABEL *next;
char *name;
long pos;
};
extern long atol();
struct SHORT_CUTS {
char *cname;
char *pos;
};
/* Following variables are set up in init.c's InitDefaults. They tell
** us if there are any other script files listed on the command line so
** that we can execute them when a prior script is done. */
extern int script_files_todo;
extern char **script_files;
/**************** globals needed ******************/
char on_string[20]; /* string to match on for on cmd */
char wait_string[20]; /* string to match of for wait cmd */
char golabel[20]; /* label we are looking for in goto */
char on_cmd[20]; /* command to execute when on matchs*/
int onsize; /* size of on_string */
int waitsize; /* size of wait_string */
int onpos; /* position in on string for search */
int waitpos; /* pos in wait_string for search */
int on_match; /* flag set while doing on_cmd */
FILE *sf; /* file pointer for script file */
struct LABEL *lbase = NULL; /* will point to first label */
struct LABEL *labels; /* current label pointer */
void cmd_short();
/********************** command tables *******************************/
static struct COMMAND inicmds[] = { /* initialization commands */
cmd_bkg, "bac", /* set background color */
cmd_bold, "bol", /* set bold color */
cmd_buf, "buf", /* set buffer size */
cmd_cursor, "cur", /* set cursor color */
cmd_depth, "dep", /* set screen depth */
cmd_fore, "for", /* set foreground color */
cmd_inter, "int", /* interlace ON/OFF */
cmd_lines, "lin", /* num lines */
cmd_screen, "scr", /* Screen WB/CUST */
cmd_volume, "vol", /* set volume */
cmd_wb, "wb", /* use WB colors */
cmd_short, "sho", /* Set shortcuts */
cmd_null, NULL /* mark the end of the list */
};
static struct COMMAND scrcmds[] = { /* script only commands */
cmd_as, "asc", /* ascii send */
cmd_beep, "bee", /* Beep */
cmd_cap, "cap", /* ascii capture on/off */
cmd_cd, "cd", /* change directory */
cmd_delay, "del", /* delay amount of seconds */
cmd_goto, "got", /* goto label */
cmd_kb, "kb", /* kermit bye (for server) */
cmd_kg, "kg", /* kermit get file */
cmd_kr, "kr", /* kermit receive file */
cmd_ks, "ks", /* kermit send file */
cmd_on, "on", /* on a 'string' do a cmd */
cmd_sb, "sb", /* Send a break */
cmd_send, "send", /* send string to host */
cmd_wait, "wait", /* wait for a host string */
cmd_xr, "xr", /* xmodem receive file */
cmd_xs, "xs", /* xmodem send file */
cmd_null, NULL /* mark the end of the list */
};
static struct COMMAND commands[]= { /* generally available commands */
cmd_appcur, "app", /* turn app. cursor on/off */
cmd_baud, "bau", /* Set Baud Rate */
cmd_bt, "bre", /* Set Break Time */
cmd_conv, "con", /* convert fn to lowercase */
cmd_echo, "ech", /* turn echo on or off */
cmd_exit, "exi", /* exit script file */
cmd_fnc, "f", /* define function key */
cmd_key, "key", /* keyscript character */
cmd_mode, "mod", /* KERMIT transfer mode */
cmd_numkey, "numkey", /* turn numeric kpad on/off */
cmd_parity, "parity", /* Set Parity */
cmd_swap, "swap", /* Swap BS and DEL */
cmd_wrap, "wrap", /* turn wrap on or off */
cmd_null, NULL /* mark the end of the list */
};
/* NB: The structures referenced in the structure may be found in
** init.c */
struct filecmd {
char ac; /* ASCII Capture */
char as; /* ASCII Send */
char xs; /* Xmodem Send */
char xr; /* Xmodem Receive */
char kg; /* Kermit Get */
char kr; /* Kermit Receive */
char ks; /* Kermit Send */
char kb; /* Kermit Bye */
char nl;
} filecmd_chars;
struct baducmd {
char b03; /* 0300 */
char b12; /* 1200 */
char b24; /* 2400 */
char b48; /* 4800 */
char b96; /* 9600 */
char bnl;
} baudcmd_chars;
struct parcmd {
char no; /* NOne */
char ma; /* MArk */
char sp; /* SPace */
char ev; /* EVen */
char od; /* ODd */
char nl;
} parcmd_chars;
struct modcmd {
char im; /* IMage */
char tx; /* TeXt */
char cn; /* CoNvert */
char nl;
} modcmd_chars;
extern struct scrcmd {
char em; /* Execute Macro */
char ab; /* Abort Macro */
char nl;
} scrcmd_chars;
extern struct {
char sb; /* Send Break */
char hu; /* Hang Up */
char cd; /* Change Dir */
char cs; /* Clear Screen */
char ec; /* ECho */
char wr; /* WRap */
char nk; /* Num Key */
char ac; /* App Cur */
char bs; /* BS<->DEL */
char nl;
} utilcmd_chars;
static struct SHORT_CUTS shortkeys[] = { /* Short-cut keys */
/* File items: */
"cap", &(filecmd_chars.ac), /* ascii capture on/off */
"asc", &(filecmd_chars.as), /* ascii send */
"xr", &(filecmd_chars.xs), /* xmodem receive file */
"xs", &(filecmd_chars.xr), /* xmodem send file */
"kg", &(filecmd_chars.kg), /* kermit get file */
"kr", &(filecmd_chars.kr), /* kermit receive file */
"ks", &(filecmd_chars.ks), /* kermit send file */
"kb", &(filecmd_chars.kb), /* kermit bye (for server) */
/* Comm items: */
"300", &(baudcmd_chars.b03), /* Set Baud Rate */
"1200", &(baudcmd_chars.b12), /* Set Baud Rate */
"2400", &(baudcmd_chars.b24), /* Set Baud Rate */
"4800", &(baudcmd_chars.b48), /* Set Baud Rate */
"9600", &(baudcmd_chars.b96), /* Set Baud Rate */
"none", &(parcmd_chars.no), /* Set Parity */
"mark", &(parcmd_chars.ma), /* Set Parity */
"space", &(parcmd_chars.sp), /* Set Parity */
"even", &(parcmd_chars.ev), /* Set Parity */
"odd", &(parcmd_chars.od), /* Set Parity */
"image", &(modcmd_chars.im), /* KERMIT transfer mode */
"text", &(modcmd_chars.tx), /* KERMIT transfer mode */
"convert", &(modcmd_chars.cn), /* KERMIT transfer mode */
/* Script items: */
"execute", &(scrcmd_chars.em), /* execute macro */
"abort", &(scrcmd_chars.ab), /* abort macro */
/* Util items: */
"sb", &(utilcmd_chars.sb), /* send break */
"hang", &(utilcmd_chars.hu), /* hang up */
"cd", &(utilcmd_chars.cd), /* change directory */
"clear", &(utilcmd_chars.cs), /* clear screen */
"ech", &(utilcmd_chars.ec), /* turn echo on or off */
"wrap", &(utilcmd_chars.wr), /* turn wrap on or off */
"numkey", &(utilcmd_chars.nk), /* turn numeric kpad on/off */
"app", &(utilcmd_chars.ac), /* turn app. cursor on/off */
"con", &(utilcmd_chars.bs), /* convert bs to del */
"swap", &(utilcmd_chars.bs), /* Swap BS and DEL */
NULL, NULL
};
/********************************************************************/
/* checks char to see if match with on string or wait_string */
/* if on string match oncmd gets executed imediately, */
/* if wait_string match script_wait is set. */
/********************************************************************/
chk_script(c)
char c;
{
if (on_string[0] != '\0') {
if (on_string[onpos] == c) {
onpos++;
if (onpos == onsize) {
on_match = TRUE;
do_script_cmd(ONCOMMAND);
on_match = FALSE;
return(0);
}
}
else onpos = 0;
}
if (wait_string[0] != '\0') {
if (wait_string[waitpos] != c) {
waitpos = 0;
return(0);
}
waitpos++;
if (waitpos != waitsize) return(0);
wait_string[0] = '\0';
script_wait = FALSE;
}
}
script_start(file)
char *file;
{
char *sfile = NULL;
if (strlen(file) == 0 || *file == '#') return(0);
if ((sf = fopen(file, "r")) == NULL) {
sfile = AllocMem((LONG)(strlen(file)+3), MEMF_PUBLIC|MEMF_CLEAR);
strcpy(sfile, "S:");
strcat(sfile, file);
if((sf = fopen(sfile, "r")) == NULL) {
InfoMsg2Line("Can't open script file",file);
return(0);
}
}
script_on = TRUE;
script_wait = FALSE;
wait_string[0] = '\0';
on_string[0] = '\0';
on_match = FALSE;
lbase = NULL;
if(sfile)
FreeMem(sfile, (LONG)strlen(file)+3);
}
/* return pointer to next word. set l to size of the word */
char *next_wrd(s,l)
char *s;
int *l;
{
char *p;
while(*s && (*s == ' ' || *s == '\t')) s++;
p = s;
while(*s && (*s != ' ' && *s != '\t')) s++;
*l = s-p;
return(p);
}
exe_cmd(p,l)
char *p;
int l;
{
int i,l2;
/* downcase the command */
for (i=0; i<l; i++) p[i] |= ' ';
/* now search for it (first in the init command list) */
if (doing_init)
for (i=0; inicmds[i].func != cmd_null; ++i) {
l2 = strlen(inicmds[i].cname);
if (l >= l2 && strncmp(p, inicmds[i].cname, l2) == 0) {
(*inicmds[i].func)(next_wrd(p+l, &l));
return(TRUE);
}
}
/* or the script command list */
else
for (i=0; scrcmds[i].func != cmd_null; ++i) {
l2 = strlen(scrcmds[i].cname);
if (l >= l2 && strncmp(p, scrcmds[i].cname, l2) == 0) {
(*scrcmds[i].func)(next_wrd(p+l, &l));
return(TRUE);
}
}
/* now search for it (in the standard command list) */
for (i=0; commands[i].func != cmd_null; ++i) {
l2 = strlen(commands[i].cname);
if (l >= l2 && strncmp(p, commands[i].cname, l2) == 0) {
(*commands[i].func)(next_wrd(p+l, &l));
return(TRUE);
}
}
if (doing_init) {
puts("INIT - unknown command:");
puts(p);
}
else InfoMsg2Line("Script - unknown command:",p);
return(FALSE);
}
struct LABEL *find_label(lname)
char *lname;
{
struct LABEL *label;
label = lbase;
while(label != NULL) {
if (strcmp(label->name, lname) == 0) return (label);
label = label->next;
}
return(NULL);
}
do_script_cmd(stat)
int stat;
{
int len,l;
char line[256];
char *p;
/* if ON command is matched and we were */
/* doing a DELAY then abort the delay timer,*/
/* except if on_cmd was just a SEND. */
if (stat == ONCOMMAND) {
strcpy(line,on_cmd);
p = next_wrd(line,&l);
if (*p != 's' && script_wait == WAIT_TIMER) {
AbortIO((char *) &Script_Timer);
Wait (1L << Script_Timer_Port->mp_SigBit);
WaitIO(Script_Timer);
/* script will proceed after on command */
script_wait = FALSE;
}
exe_cmd(p,l);
return(0);
}
script_wait = FALSE;
while(fgets(line,256,sf) != NULL) {
len = strlen(line);
line[--len] = '\0';
p = next_wrd(&line[0], &l);
if (*(p + l - 1) == ':') { /* its a label */
*(p + l - 1) = '\0';
if (find_label(p) == NULL) { /* it's a new label */
if (lbase == NULL) { /* it's the first label */
labels = lbase = (struct LABEL *)
malloc(sizeof (struct LABEL));
}
else {
labels->next = (struct LABEL *)
malloc(sizeof (struct LABEL));
labels = labels->next;
}
labels->pos = ftell(sf);
labels->name = malloc(l);
labels->next = NULL;
strcpy(labels->name, p);
if (stat == GOTOLABEL && strcmp(p, golabel) == 0)
stat = NEXTCOMMAND;
}
p = next_wrd(p+l+1, &l);
} /* end of it's a label */
if (stat == GOTOLABEL || *p == '#') continue;
if (*p) exe_cmd(p,l);
return(0);
} /* end of while */
if (stat == GOTOLABEL) InfoMsg2Line("Script - label not found:",golabel);
exit_script();
if(script_files_todo > 0) {
script_files_todo--;
script_start(*(script_files++));
}
}
exit_script()
{
if (script_wait == WAIT_TIMER) { /* timer not done yet */
AbortIO((char *) &Script_Timer); /* so abort it */
Wait (1L << Script_Timer_Port->mp_SigBit); /* Wait for the sig */
WaitIO(Script_Timer); /* Get my reply back */
}
InfoMsg1Line("Script - terminated");
script_on = FALSE;
script_wait = TRUE;
fclose(sf);
}
/* remove quotes terminate string & return pointer to start */
char *tostring(ptr)
char *ptr;
{
char *s1,*s2;
s1 = ptr;
if (*ptr == '"') {
while(*ptr++ && *ptr != '"') ;
if (*ptr == '"') {
*ptr = '\0';
ptr = s2 = ++s1;
while(*s2) {
if (*s2 != '^') *s1++ = *s2;
else if (*(s2+1) == '^') *s1++ = *s2++;
else *s1++ = ((*++s2)|' ')-96;
s2++;
}
*s1 = '\0';
return(ptr);
}
}
if (*s1 == '^') {
*s1 = (*(s1+1)|' ')-96;
*(s1+1) = '\0';
return(s1);
}
*(s1+1) = '\0';
return(s1);
}
/***************************** SCRIPT COMMANDS ********************/
void cmd_goto(lname)
char *lname;
{
struct LABEL *label;
/* if on_cmd was a goto kill wait state */
if (on_match) { wait_string[0] = '\0'; script_wait = FALSE; }
if ((label = find_label(lname)) == NULL) { /* is it forward */
strcpy(golabel,lname);
do_script_cmd(GOTOLABEL);
}
else {
fseek(sf,(long)(label->pos),0);
}
}
void cmd_send(str)
char *str;
{
sendstring(tostring(str));
}
void cmd_wait(str)
char *str;
{
str = tostring(str);
*(str+20) = '\0'; /* 20 characters max */
strcpy(wait_string, str);
waitsize = strlen(str);
script_wait = WAIT_STRING;
}
void cmd_on(str)
char *str;
{
char *p;
p = tostring(str);
strcpy(on_string, p);
onsize = strlen(p);
*(p+onsize+2+20) = '\0'; /* 20 characters max */
strcpy(on_cmd,p+onsize+2);
}
void cmd_delay(seconds)
char *seconds;
{
script_wait = WAIT_TIMER;
Script_Timer.tr_time.tv_secs = atoi(seconds);
Script_Timer.tr_time.tv_micro = 0;
SendIO((char *) &Script_Timer.tr_node);
}
void cmd_exit(option)
char *option;
{
char *p;
int l;
if (doing_init) return;
if (*option) {
p = next_wrd(option,&l);
*(p+l) = '\000';
if (strcmp(p,"vt100") == 0 || strcmp(p,"VT100") == 0)
cleanup("Exit vt100 from script",0);
exit_script();
script_start(p);
}
else {
exit_script();
if(script_files_todo > 0) {
script_files_todo--;
script_start(*(script_files++));
}
}
}
void cmd_ks(file)
char *file;
{
multi_xfer(file, doksend, 1);
}
void cmd_kr(file)
char *file;
{
multi_xfer(file, dokreceive, 0);
}
void cmd_kg(file)
char *file;
{
server = TRUE;
multi_xfer(file, dokreceive, 0);
}
void cmd_kb()
{
saybye();
}
void cmd_xs(file)
char *file;
{
multi_xfer(file, XMODEM_Send_File, 1);
}
void cmd_xr(file)
char *file;
{
multi_xfer(file, XMODEM_Read_File, 1);
}
void cmd_cap(file)
char *file;
{
do_capture(file);
}
void cmd_as(file)
char *file;
{
do_send(file);
}
void cmd_cd(name)
char *name;
{
set_dir(name);
}
void cmd_sb(str)
char *str;
{
sendbreak();
}
void cmd_baud(rate)
char *rate;
{
int i = atoi(rate);
switch( i ) {
case 300:
case 1200:
case 2400:
case 4800:
case 9600:
if (doing_init) p_baud = i;
else setserbaud(i, TRUE);
break;
default:
if (doing_init) {
puts("INIT - invalid baud rate:");
puts(rate);
}
else InfoMsg2Line("Script - invalid baud rate: ",rate);
break;
}
}
void cmd_parity(par)
char *par;
{
int i;
switch( *par|' ' ) {
case 'n': i = 0; break;
case 'm': i = 1; break;
case 's': i = 2; break;
case 'e': i = 3; break;
case 'o': i = 4; break;
default:
if (doing_init) {
puts("INIT - invalid parity:");
puts(par);
}
else InfoMsg2Line("Script - invalid parity: ",par);
return;
}
p_parity = i;
if (doing_init) return;
ClearMenuStrip( mywindow ); /* Remove old menu */
InitCommItems(); /* Re-do comm menu */
SetMenuStrip(mywindow,&menu[0]); /* Re-display the menu */
}
void cmd_bt(breaklength)
char *breaklength;
{
p_break = atol(breaklength);
if (doing_init) return;
AbortIO(Read_Request);
Wait(1L << Read_Request->IOSer.io_Message.mn_ReplyPort->mp_SigBit);
WaitIO(Read_Request);
Read_Request->io_BrkTime = Write_Request->io_BrkTime = p_break;
setparams();
}
void cmd_mode(tmode)
char *tmode;
{
switch (*tmode|' ') {
case 'i':
p_mode = 0;
break;
case 'c':
p_mode = 1;
break;
default:
if (doing_init) {
puts("INIT - invalid transfer mode: ");
puts(tmode);
}
else InfoMsg2Line("Script - invalid transfer mode: ",tmode);
return;
}
if (doing_init) return;
ClearMenuStrip(mywindow);
InitCommItems(); /* Re-do comm menu */
SetMenuStrip(mywindow,&menu[0]);
}
void cmd_beep(dummy)
char *dummy;
{
if (p_volume == 0) DisplayBeep(NULL);
else {
BeginIO(&Audio_Request);
WaitIO(&Audio_Request);
}
}
void setvar(par,typ,var)
char *par;
int typ,*var;
{
int i;
switch (typ) {
case 0: /* ON/OFF or YES/NO */
case 1: /* not case */
if ((par[1]|' ') == 'n' || (par[0]|' ') == 'y') *var = 1-typ;
else *var = typ;
break;
case 2: /* read hex number */
if (sscanf(par,"%x",&i) == 1) *var = i;
break;
case 3: /* read decimal number */
if (sscanf(par,"%d",&i) == 1) *var = i;
break;
}
}
void cmd_echo(par)
char *par;
{
setvar(par,0,&p_echo);
if (doing_init == 0) redoutil();
}
void cmd_wrap(par)
char *par;
{
setvar(par,0,&p_wrap);
if (doing_init == 0) redoutil();
}
void cmd_numkey(par)
char *par;
{
setvar(par,1,&p_keyapp);
if (doing_init == 0) redoutil();
}
void cmd_appcur(par)
char *par;
{
setvar(par,0,&p_curapp);
if (doing_init == 0) redoutil();
}
void cmd_swap(par)
char *par;
{
setvar(par,0,&p_bs_del);
if (doing_init == 0) redoutil();
}
void cmd_bkg(par)
char *par;
{
setvar(par,2,&p_background);
}
void cmd_bold(par)
char *par;
{
setvar(par,2,&p_bold);
}
void cmd_buf(par)
char *par;
{
setvar(par,3,&p_buffer);
}
void cmd_cursor(par)
char *par;
{
setvar(par,2,&p_cursor);
}
void cmd_depth(par)
char *par;
{
setvar(par,3,&p_depth);
}
void cmd_fore(par)
char *par;
{
setvar(par,2,&p_foreground);
}
void cmd_inter(par)
char *par;
{
setvar(par,0,&p_interlace);
}
void cmd_lines(par)
char *par;
{
setvar(par,3,&p_lines);
}
void cmd_screen(par)
char *par;
{
if ((par[0]|' ') == 'w') p_screen = 0;
else p_screen = 1;
}
void cmd_wb(par)
char *par;
{
setvar(par,0,&p_wbcolors);
}
void cmd_short(par) /* Set keyboard shortcuts */
char *par;
{
int i, l, l2;
register char *p = par;
/* downcase the next word */
for (i=0; p[i] && (p[i] != ' '); i++) p[i] |= ' ';
l = i;
/* Find the command name. If found set the shortcut key to the
** user's value. If no value then set the key to ' ' to indicate no
** shortcur available. */
for(i = 0; shortkeys[i].cname != NULL; i++) {
l2 = strlen(shortkeys[i].cname);
if (l >= l2 && strncmp(p, shortkeys[i].cname, l2) == 0) {
for( ; p[l] && (p[l] == ' '); l++) ;
if(p[l])
*(shortkeys[i].pos) = p[l];
else
*(shortkeys[i].pos) = ' ';
}
}
}
void cmd_key(par)
char *par;
{
int i;
if (sscanf(par,"%x",&i) == 1) p_keyscript = (char)(i & 0x7f);
}
void cmd_volume(par)
char *par;
{
setvar(par,3,&p_volume);
}
void cmd_conv(par)
char *par;
{
setvar(par,0,&p_convert);
if (doing_init == 0) redoutil();
}
void cmd_fnc(par)
char *par;
{
char *s;
int l;
int i = atoi(par);
s = par;
if (*s) s = next_wrd(s,&l); /* skip key number */
if (*s) s = next_wrd(s+l+1,&l); /* point at desired string */
if (*s) s = tostring(s); /* convert the string */
if (*s && i > 0 && i < 21) {
if (i > 10) {
p_F[i-11] = malloc(strlen(s)+1);
strcpy(p_F[i-11],s);
}
else {
p_f[i-1] = malloc(strlen(s)+1);
strcpy(p_f[i-1],s);
}
}
}
void cmd_null(dummy)
char *dummy;
{ }
SHAR_EOF
cat << \SHAR_EOF > vt100.c
/********************************************************************
* vt100 terminal emulator with xmodem transfer capability
*
* v2.7 870825 ACS - Provide handling of the msgs from the
* info/status window.
* v2.6 870227 DBW - bug fixes for all the stuff in v2.5
* v2.5 870214 DBW - more additions (see readme file)
* v2.4 861214 DBW - lots of fixes/additions (see readme file)
* v2.3 861101 DBW - minor bug fixes
* v2.2 861012 DBW - more of the same
* v2.1 860915 DBW - new features (see README)
* 860901 ACS - Added Parity and Word Length and support code
* 860823 DBW - Integrated and rewrote lots of code
* v2.0 860809 DBW - Major rewrite
* v1.1 860720 DBW - Switches, 80 cols, colors, bug fixes
* v1.0 860712 DBW - First version released
*
* use <esc> to abort xmodem or kermit transfers
*
* written by Michael Mounier
* new version by Dave Wecker
*******************************************************************/
/* all includes defines and globals */
#include "vt100.h"
/**************************************************************/
/* here are all the global definitions that appear in vt100.h */
/**************************************************************/
char bufr[BufSize];
int fd, timeout = FALSE, ttime;
int multi = FALSE, server;
long bytes_xferred;
char MyDir[60];
struct FileLock *MyDirLock = NULL;
struct FileLock *StartLock = NULL;
struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
struct TextAttr myattr = {
(STRPTR) "topaz.font",
8,
0,
0};
struct TextFont *myfont = NULL;
struct NewScreen NewScreen = {
0,0,640,200,1, /* left, top, width, height, depth */
0,1,HIRES, /* DetailPen, BlockPen, ViewModes */
CUSTOMSCREEN,&myattr, /* Type, Font */
(UBYTE *)"VT100", /* Title */
NULL,NULL }; /* Gadgets, Bitmap */
struct NewWindow NewWindow = {
0,0,640,200, /* left, top, width, height */
0,1, /* detailpen, blockpen */
MENUPICK|CLOSEWINDOW|RAWKEY|ACTIVEWINDOW|INACTIVEWINDOW,
SMART_REFRESH|ACTIVATE|BORDERLESS|WINDOWCLOSE|WINDOWDEPTH|WINDOWDRAG,
NULL,NULL, /* FirstGadget, CheckMark */
(UBYTE *)NULL,
NULL, /* set screen after open screen */
NULL, /* bitmap */
640, 200, 640, 200, /* minw, minh, maxw, maxh */
CUSTOMSCREEN /* Type */
};
struct NewWindow NewReqWindow = {
10, 15, ((54*8)+4+18), ((4*8)+11+2), /* left, top, width, height */
0, 1, /* detailpen, blockpen */
/* IDCMP Flags... */
CLOSEWINDOW | ACTIVEWINDOW | REQCLEAR | REQSET | NEWSIZE,
/* Flags... */
SMART_REFRESH | NOCAREREFRESH | ACTIVATE | WINDOWSIZING | SIZEBRIGHT |
WINDOWCLOSE | WINDOWDEPTH | WINDOWDRAG,
NULL, /* First gadget */
NULL, /* CheckMark */
(UBYTE *)"VT100 Info & Xfer Status", /* Title */
NULL, /* set screen after open screen */
NULL, /* bitmap */
((5*8)+4+18), ((1*8)+11+2), 640, 200, /* minw, minh, maxw, maxh */
CUSTOMSCREEN /* Type */
};
struct IntuiText MyTitle = {
0,1,JAM2,26,0, /* front pen, back pen, mode, left, top */
&myattr, /* font */
(UBYTE *)VERSION, /* title */
NULL}; /* next text */
struct Screen *myscreen = NULL; /* ptr to applications screen */
struct Window *mywindow = NULL; /* ptr to applications window */
struct Window *reqwindow = NULL; /* ptr to requester's window */
struct ViewPort *myviewport;
struct RastPort *myrastport;
struct IntuiMessage *NewMessage; /* msg structure for GetMsg() */
struct Preferences *Prefs; /* preferences from GetPrefs() */
/**** String requester support ******/
char InpBuf[80],UndoBuf[80],Prompt[80];
struct IntuiText donetxt = {
1,0,JAM2,0,0, /* front pen, back pen, mode, left, top */
&myattr, /* font */
(UBYTE *)"DONE", /* question to ask */
NULL}; /* next text */
struct Gadget mydonegad = {
&mystrgad,290,2,40,10, /* next,left,top,width,height */
GADGHCOMP|REQGADGET, /* flags */
RELVERIFY|ENDGADGET, /* activation */
BOOLGADGET, /* gadget type */
NULL,NULL,&donetxt, /* gad render, sel render, gad text */
0L,NULL,2,NULL}; /* mutual exclude, special, ID, user data */
struct StringInfo mystrinfo = {
(UBYTE *)InpBuf,
(UBYTE *)UndoBuf,
0,80,0,0,0,0, /* initial, max, disp, undo, #chrs, dsp chrs */
0,0,NULL,0L,NULL}; /* left,top,layer,longint,keymap */
struct Gadget mystrgad = {
NULL,10,12,320,10, /* next,left,top,width,height */
GADGHCOMP|REQGADGET,/* flags */
ENDGADGET,STRGADGET,/* activation, type */
NULL,NULL,NULL, /* gad render, sel render, gad text */
0L, /* mutual exclude */
(APTR)&mystrinfo, /* special info */
1,NULL}; /* gadget ID, user data */
struct IntuiText mystrtxt = {
0,1,JAM2,10,2, /* front pen, back pen, mode, left, top */
&myattr, /* font */
(UBYTE *)Prompt, /* question to ask */
NULL}; /* next text */
struct Requester myrequest = {
NULL,0,10,340,22, /* older requester, left, top, width, height */
0,0,&mydonegad, /* relleft reltop, gadgets */
NULL, /* border */
&mystrtxt, /* text */
NULL,1,NULL, /* flags, back fill pen, layer */
{0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0}, /* pad1 */
NULL,NULL, /* image bit map, rquest window */
{0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0} /* pad2 */
};
int numreqs = 0; /* number of outstanding requestors */
int reqwinup = 0; /* Requester window is NOT displayed */
extern int reqmaxx, reqmaxy, reqmaxlen; /* Defined in window.c */
extern void ReqNewSize(); /* New req window size -- window.c */
extern void KillReq(); /* Kill requester window in window.c */
/***** menu structures *****/
struct MenuItem FileItem[FILEMAX];
struct IntuiText FileText[FILEMAX];
struct MenuItem CommItem[COMMAX];
struct IntuiText CommText[COMMAX];
struct MenuItem RSItem[RSMAX];
struct IntuiText RSText[RSMAX];
struct MenuItem ParItem[PARMAX];
struct IntuiText ParText[PARMAX];
struct MenuItem XFItem[XFMAX];
struct IntuiText XFText[XFMAX];
struct MenuItem ScriptItem[SCRIPTMAX];
struct IntuiText ScriptText[SCRIPTMAX];
struct MenuItem UtilItem[UTILMAX];
struct IntuiText UtilText[UTILMAX];
struct Menu menu[MAXMENU];
struct IOExtSer *Read_Request;
char *rs_in;
struct IOExtSer *Write_Request;
char rs_out[2];
struct timerequest Timer;
struct MsgPort *Timer_Port = NULL;
struct timerequest Script_Timer;
struct MsgPort *Script_Timer_Port = NULL;
struct IOAudio Audio_Request;
struct MsgPort *Audio_Port = NULL;
UBYTE *BeepWave;
UBYTE Audio_AllocMap[4] = { 1, 8, 2, 4 };
int x,y,curmode;
int MINX = 0;
int MAXX = 632;
int MINY = 14;
int MAXY = 198;
int top = 14;
int bot = 198;
int savx = 0;
int savy = 14;
int savmode = 0;
int nlmode = 0;
int alt = 0;
int savalt = 0;
int a[2] = { 0, 0 };
int sa[2] = { 0, 0 };
int inesc = -1;
int inctrl = -1;
int private = 0;
int badseq = 0;
int maxcol = 79;
/*************************** defaults *******************************/
int p_baud = 1200; /* baud rate */
int p_screen = 0; /* 0 = WORKBENCH, 1 = CUSTOM */
int p_wbcolors = 1; /* 0 = Custom, 1 = Workbench colors */
int p_interlace = 0; /* 0 = no interlace, 1 = interlace */
int p_depth = 2; /* number of bit planes (1 or 2) */
int p_foreground = 0x840; /* default foreground RGB color */
int p_background = 0x000; /* default background RGB color */
int p_bold = 0x000; /* default BOLD RGB color */
int p_cursor = 0x00d; /* default Cursor RGB color */
int p_lines = 24; /* number of lines on the screen */
int p_mode = 0; /* 0 = image, 1 = CRLF (for kermit) */
int p_buffer = 512; /* read buffer size (>= 512 bytes) */
int p_parity = 0; /* 0=none,1=mark,2=space,3=even,4=odd */
long p_break = 750000; /* break time (in micro seconds) */
int p_volume = 64; /* beep volume (0 = DisplayBeep) */
int p_wrap = 1; /* 0 = truncate, 1 = wrap long lines */
int p_keyapp = 0; /* 0 = numeric, 1 = application keypad */
int p_curapp = 0; /* 0 = cursor, 1 = application cursor */
int p_echo = 0; /* 0 = full duplex, 1 = half duplex */
int p_bs_del = 0; /* 0 = normal, 1 = swap bs and delete */
int p_convert = 0; /* 1 = convert filenames to lower case */
char p_keyscript = 0x7E; /* function key script introducer = ~ */
char *p_f[10] = { /* function key defaults */
"\033OP","\033OQ","\033OR","\033OS",
"f5","f6","f7","f8","f9","f10" };
char *p_F[10] = { /* shifted function key defaults */
"F1","F2","F3","F4","F5",
"F6","F7","F8","F9","F10"};
/* for script file */
int script_on;
int script_wait;
int doing_init = 0;
/******************************************************/
/* Main Program */
/* */
/* This is the main body of the program. */
/******************************************************/
char lookahead[80];
FILE *tranr = NULL;
FILE *trans = NULL;
int capture,send;
char name[80];
struct MsgPort *mySerPort;
main(argc,argv)
int argc;
char **argv;
{
ULONG class, waitmask;
unsigned int code, qual;
int KeepGoing,i,la,dola,actual;
char c,*ptr;
ptr = InitDefaults(argc,argv);
InitDevs();
InitFileItems();
InitCommItems();
InitScriptItems();
InitUtilItems();
InitMenu();
SetMenuStrip(mywindow,&menu[0]);
PrintIText(mywindow->RPort,&MyTitle,0L,0L);
MyDir[0] = '\000';
StartLock = (struct FileLock *)((ULONG)((struct Process *)
(FindTask(NULL)))->pr_CurrentDir);
MyDirLock = (struct FileLock *)DupLock(StartLock);
KeepGoing = TRUE;
capture = FALSE;
send = FALSE;
maxcol = MAXX / 8;
la = 0;
x = MINX ;
y = MINY;
curmode = FS_NORMAL;
script_on = FALSE;
script_wait= TRUE;
SetAPen(mywindow->RPort,1L);
cursorflip();
cursorflip();
emit(12);
mySerPort = Read_Request->IOSer.io_Message.mn_ReplyPort;
SendIO(Read_Request);
/* see if we had a startup script */
if (ptr != NULL) script_start(ptr);
reqwinup = 0;
while( KeepGoing )
{
/* wait for window message or serial port message */
cursorflip();
if(reqwinup)
waitmask = (1L << mySerPort->mp_SigBit) |
(1L << mywindow->UserPort->mp_SigBit) |
(1L << Script_Timer_Port->mp_SigBit) |
(1L << reqwindow->UserPort->mp_SigBit);
else
waitmask = (1L << mySerPort->mp_SigBit) |
(1L << mywindow->UserPort->mp_SigBit) |
(1L << Script_Timer_Port->mp_SigBit);
if (script_wait) /* if script ready dont wait here */
Wait(waitmask);
cursorflip();
/* do ascii file send */
if (send)
{
if ((c=getc(trans)) != EOF) {
if (c == '\n') c = '\r';
sendchar(c);
}
else {
fclose(trans);
InfoMsg1Line("File Sent");
send=FALSE;
}
}
/* see if there are any characters from the host */
if (CheckIO(Read_Request)) {
WaitIO(Read_Request);
c = rs_in[0] & 0x7F;
doremote(c);
if (script_on) chk_script(c);
if (capture && c != 10) {
if (c == 13) c = 10;
putc(c , tranr);
}
Read_Request->IOSer.io_Command = SDCMD_QUERY;
DoIO(Read_Request);
Read_Request->IOSer.io_Command = CMD_READ;
actual = (int)Read_Request->IOSer.io_Actual;
if (actual > 0) {
if (inesc < 0 &&
inctrl < 0 &&
a[alt] == 0 &&
capture == FALSE) dola = 1;
else dola = 0;
Read_Request->IOSer.io_Length =
Read_Request->IOSer.io_Actual;
DoIO(Read_Request);
Read_Request->IOSer.io_Length = 1;
for (i = 0; i < actual; i++) {
c=rs_in[i] & 0x7f;
if (script_on) chk_script(c);
if (dola == 1) {
if (c >= ' ' && c <= '~' && la < 80)
lookahead[la++] = c;
else {
if (la > 0) {
emitbatch(la,lookahead);
la = 0;
}
doremote(c);
dola = 0;
}
}
else {
doremote(c);
if (inesc < 0 &&
inctrl < 0 &&
a[alt] == 0 &&
capture == FALSE) dola = 1;
if (capture && c != 10) {
if (c == 13) c = 10;
putc(c , tranr);
}
}
}
/* dump anything left in the lookahead buffer */
if (la > 0) {
emitbatch(la,lookahead);
la = 0;
}
}
SendIO(Read_Request);
}
while((NewMessage =
(struct IntuiMessage *)GetMsg(mywindow->UserPort))
!= FALSE) {
class = NewMessage->Class;
code = NewMessage->Code;
qual = NewMessage->Qualifier;
ReplyMsg( NewMessage );
switch( class )
{
case CLOSEWINDOW:
KeepGoing = FALSE;
break;
case RAWKEY:
c = toasc(code,qual,0);
if (p_echo) doremote(c);
break;
case NEWSIZE:
emit(12);
break;
case MENUPICK:
handle_menupick(class,code);
break;
default:
PrintIText(mywindow->RPort,&MyTitle,0L,0L);
break;
} /* end of switch (class) */
} /* end of while ( newmessage )*/
if (!script_wait ||
(CheckIO(&Script_Timer) &&
script_wait == WAIT_TIMER))
do_script_cmd(NEXTCOMMAND);
while( reqwinup &&
((NewMessage = (struct IntuiMessage *)
GetMsg(reqwindow->UserPort)) != FALSE)
) {
class = NewMessage->Class;
ReplyMsg( NewMessage );
switch( class ) {
case REQCLEAR:
numreqs = 0;
break;
case CLOSEWINDOW:
KillReq(); /* Kills requester window, set reqwinup = 0 */
break;
case NEWSIZE:
ReqNewSize(reqwindow->Height, reqwindow->Width);
break;
} /* end of switch (class) */
} /* end while */
} /* end while ( keepgoing ) */
/* It must be time to quit, so we have to clean
* up and exit.
*/
cleanup("",0);
} /* end of main */
/* cleanup code */
cleanup(reason, fault)
char *reason;
int fault;
{
switch(fault) {
case 0: /* quitting close everything */
KillReq(); /* Kill the requester and its window */
ClearMenuStrip( mywindow );
CloseDevice(&Audio_Request);
if (MyDirLock != NULL) UnLock(MyDirLock);
case 8: /* error opening audio */
DeletePort(Audio_Port);
FreeMem(BeepWave,BEEPSIZE);
CloseDevice(&Timer);
case 7: /* error opening timer */
DeletePort(Timer_Port);
CloseDevice(&Script_Timer);
DeletePort(Script_Timer_Port);
case 6: /* error opening write device */
DeletePort(Write_Request->IOSer.io_Message.mn_ReplyPort);
FreeMem(Write_Request,(long)sizeof(*Write_Request));
CloseDevice(Read_Request);
case 5: /* error opening read device */
DeletePort(Read_Request->IOSer.io_Message.mn_ReplyPort);
FreeMem(Read_Request,(long)sizeof(*Read_Request));
case 4: /* error opening window */
if (myfont != NULL) CloseFont( myfont );
if (mywindow != NULL) CloseWindow( mywindow );
if (p_screen != 0) CloseScreen( myscreen );
case 3: /* error opening screen */
case 2: /* error opening graphics library */
case 1: /* error opening intuition */
default:
if (*reason) puts (reason);
}
exit(fault);
}
do_capture(file)
char *file;
{
if (capture == TRUE)
{
capture=FALSE;
fclose(tranr);
InfoMsg1Line("End File Capture");
}
else
{
if (file == NULL) {
name[0] = '\000';
req("Ascii Capture:",name,1);
}
else strcpy(name, file);
if ((tranr=fopen(name,"w")) == 0) {
capture=FALSE;
InfoMsg1Line("Error Opening File");
return(FALSE);
}
capture=TRUE;
}
}
do_send(file)
char *file;
{
if (send == TRUE)
{
send=FALSE;
fclose(trans);
InfoMsg1Line("File Send Cancelled");
}
else
{
if (file == NULL) {
name[0] = '\000';
req("Ascii Send:",name,1);
}
else strcpy(name, file);
if ((trans=fopen(name,"r")) == 0) {
send=FALSE;
InfoMsg1Line("Error Opening File");
return(FALSE);
}
send=TRUE;
}
}
void setparams()
{
Read_Request->IOSer.io_Command =
Write_Request->IOSer.io_Command =
SDCMD_SETPARAMS;
DoIO(Read_Request); DoIO(Write_Request);
Read_Request->IOSer.io_Command = CMD_READ;
SendIO(Read_Request);
Write_Request->IOSer.io_Command = CMD_WRITE;
}
void hangup ()
{
AbortIO(Read_Request);
CloseDevice (Read_Request);
Timer.tr_time.tv_secs=0L;
Timer.tr_time.tv_micro=750000L;
DoIO((char *) &Timer.tr_node);
OpenDevice (SERIALNAME,NULL,Read_Request,NULL);
setparams();
}
void redocomm() {
ClearMenuStrip( mywindow ); /* Remove old menu */
InitCommItems(); /* Re-do comm menu */
SetMenuStrip(mywindow,&menu[0]); /* Re-display the menu */
}
void setserbaud(baud, redomenu)
int baud;
LONG redomenu;
{
AbortIO(Read_Request);
Write_Request->io_Baud = Read_Request->io_Baud = baud;
setparams();
p_baud = baud;
if (redomenu) redocomm();
}
void redoutil() {
ClearMenuStrip(mywindow);
InitUtilItems();
SetMenuStrip(mywindow,&menu[0]);
}
void handle_menupick(class, code)
ULONG class;
unsigned int code;
{
unsigned int menunum, itemnum, subnum;
if (code == MENUNULL) return;
menunum = MENUNUM( code );
itemnum = ITEMNUM( code );
subnum = SUBNUM( code );
switch( menunum ) {
case 0:
switch( itemnum ) {
case 0:
do_capture(NULL);
break;
case 1:
do_send(NULL);
break;
case 2:
if (p_parity > 0) {
InfoMsg1Line("Parity setting prevents this");
break;
}
name[0] = '\000';
req("Xmodem Receive:",name,1);
multi_xfer(name,XMODEM_Read_File,0);
break;
case 3:
if (p_parity > 0) {
InfoMsg1Line("Parity setting prevents this");
break;
}
name[0] = '\000';
req("Xmodem Send:",name,1);
multi_xfer(name,XMODEM_Send_File,1);
break;
case 4:
server = TRUE;
name[0] = '\000';
req("Kermit GET remote file(s):",name,1);
multi_xfer(name,dokreceive,0);
break;
case 5:
multi_xfer("",dokreceive,0);
break;
case 6:
server = TRUE;
name[0] = '\000';
req("Kermit Send local name:",name,1);
multi_xfer(name,doksend,1);
break;
case 7:
saybye();
break;
}
break;
case 1:
switch( itemnum ) {
case 0:
switch( subnum ) {
case 0:
setserbaud(300, FALSE);
break;
case 1:
setserbaud(1200, FALSE);
break;
case 2:
setserbaud(2400, FALSE);
break;
case 3:
setserbaud(4800, FALSE);
break;
case 4:
setserbaud(9600, FALSE);
break;
}
break;
case 1:
/* Set Parity */
p_parity = subnum;
break;
case 2:
/* set transfer mode */
if (subnum < 2) p_mode = subnum;
else {
if (p_convert) p_convert = 0;
else p_convert = 1;
redocomm();
}
break;
}
break;
case 2:
if (!itemnum && !script_on) {
name[0] = '\000';
req("Script file name:",name,1);
script_start(name);
}
if (itemnum && script_on) exit_script();
break;
case 3:
switch( itemnum ) {
case 0:
sendbreak();
break;
case 1:
hangup();
break;
case 2:
strcpy(name,MyDir);
req("Directory:",name,1);
set_dir(name);
break;
case 3:
top = MINY; bot = MAXY; savx = MINX; savy = MINY;
curmode = FS_NORMAL; inesc = -1;
a[0] = 0; a[1] = 0; sa[0] = 0; sa[1] = 0;
redoutil();
emit(12);
break;
case 4:
if (p_echo) p_echo = 0;
else p_echo = 1;
redoutil();
break;
case 5:
if (p_wrap) p_wrap = 0;
else p_wrap = 1;
redoutil();
break;
case 6:
if (p_keyapp) p_keyapp = 0;
else p_keyapp = 1;
redoutil();
break;
case 7:
if (p_curapp) p_curapp = 0;
else p_curapp = 1;
redoutil();
break;
case 8:
swap_bs_del();
redoutil();
break;
}
break;
} /* end of switch ( menunum ) */
}
SHAR_EOF
cat << \SHAR_EOF > vt100.h
/*********************************************************************
* a terminal program that has ascii and xmodem transfer capability
*
* v2.7 870825 ACS - See README.
* v2.6 870227 DBW - bug fixes for all the stuff in v2.5
* v2.5 870214 DBW - more additions (see readme file)
* v2.4 861214 DBW - lots of fixes/additions (see readme file)
* v2.3 861101 DBW - minor bug fixes
* v2.2 861012 DBW - more of the same
* v2.1 860915 DBW - new features (see README)
* 860823 DBW - Integrated and rewrote lots of code
* v2.0 860809 DBW - Major release.. LOTS of changes
* v1.1 860720 DBW - Switches, 80 cols, colors, bug fixes
* v1.0 860712 DBW - First version released
*
* use esc to abort xmodem transfer
*
* written by Michael Mounier
* new version by Dave Wecker 860621
********************************************************************/
/********* major version (used for title of terminal window) *********/
#define VERSION "VT100 (V2.7 ACS 870825) Terminal Window"
/*********** ######## define the compiler type here ######## ********/
#define LATTICE 0
#define MANX 1
/* compiler directives to fetch the necessary header files */
#include <exec/types.h>
#include <exec/exec.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include <graphics/gfxbase.h>
#include <graphics/gfx.h>
#include <graphics/text.h>
#include <graphics/regions.h>
#include <graphics/copper.h>
#include <graphics/gels.h>
#include <devices/serial.h>
#include <devices/keymap.h>
#include <devices/inputevent.h>
#include <devices/audio.h>
#include <hardware/blit.h>
/* for Lattice you may have to change these with: */
#include <stdio.h> /* #include <lattice/stdio.h> and */
#include <ctype.h> /* #include <lattice/ctype.h> */
#include <libraries/dos.h>
#include <libraries/dosextens.h>
#include <devices/timer.h>
#if MANX
#include <functions.h>
#undef NULL
#define NULL ((void *)0)
#endif
#define INTUITION_REV 1L
#define GRAPHICS_REV 1L
/* things for xmodem send and recieve */
#define GOODREAD 0
#define TIMEOUT 1
#define USERABORT 2
#define SECSIZ 0x80
#define TTIME_SHORT 5 /* number of seconds for short timeout */
#define TTIME_LONG 50 /* number of seconds for long timeout */
#define TTIME_KERMIT 10 /* number of seconds for KERMIT timeout*/
#define BufSize 0x200 /* Text buffer for XMODEM */
#define ERRORMAX 10 /* Max errors before abort */
#define RETRYMAX 10 /* Maximum retrys before abort */
#define SOH 1 /* Start of sector char */
#define EOT 4 /* end of transmission char */
#define ACK 6 /* acknowledge sector transmission */
#define NAK 21 /* error in transmission detected */
#define FILEMAX 8 /* number of file menu items */
#define COMMAX 3 /* number of communication sub menus */
#define RSMAX 5 /* speed menu items */
#define PARMAX 5 /* parity items */
#define XFMAX 3 /* transfer mode items */
#define SCRIPTMAX 2 /* script menu items */
#define UTILMAX 9 /* utility menu */
#define MAXMENU 4 /* total number of menu entries */
#define MAXGADSTR 80 /* Max size of prompts and inputs */
#define FSF_REVERSE 256 /* fake font style to flag INVERSVID mode */
/* things for script support */
#define GOTOLABEL 1
#define NEXTCOMMAND 0
#define ONCOMMAND 2
#define WAIT_TIMER 2
#define WAIT_STRING 1
/* things for 'beep' support */
#define BEEPSIZE 10L
#define BEEPFREQ 1000L
#define COLORCLOCK 3579545L
extern struct MsgPort *CreatePort();
extern char *malloc(),*strcpy(),*fgets();
extern long ftell();
extern int multi; /* flags multi file transfers */
extern int server;
extern char bufr[BufSize];
extern int fd, timeout, ttime;
extern long bytes_xferred;
extern char MyDir[60];
extern struct FileLock *MyDirLock;
extern struct FileLock *StartLock;
extern struct IntuitionBase *IntuitionBase;
extern struct GfxBase *GfxBase;
extern struct TextAttr myattr;
extern struct TextFont *myfont;
extern struct NewScreen NewScreen;
extern struct NewWindow NewWindow;
extern struct NewWindow NewReqWindow;
extern struct Screen *myscreen;
extern struct Window *mywindow;
extern struct Window *reqwindow;
extern struct ViewPort *myviewport;
extern struct RastPort *myrastport;
extern struct IntuiMessage *NewMessage;
extern struct Preferences *Prefs;
extern char InpBuf[80],UndoBuf[80],Prompt[80];
extern struct StringInfo mystrinfo;
extern struct Gadget mystrgad;
extern struct IntuiText donetxt;
extern struct Gadget mydonegad;
extern struct IntuiText mystrtxt;
extern struct Requester myrequest;
extern int numreqs;
extern int reqwinup;
extern struct MenuItem FileItem[FILEMAX];
extern struct IntuiText FileText[FILEMAX];
extern struct MenuItem CommItem[COMMAX];
extern struct IntuiText CommText[COMMAX];
extern struct MenuItem RSItem[RSMAX];
extern struct IntuiText RSText[RSMAX];
extern struct MenuItem ParItem[PARMAX];
extern struct IntuiText ParText[PARMAX];
extern struct MenuItem XFItem[XFMAX];
extern struct IntuiText XFText[XFMAX];
extern struct MenuItem ScriptItem[SCRIPTMAX];
extern struct IntuiText ScriptText[SCRIPTMAX];
extern struct MenuItem UtilItem[UTILMAX];
extern struct IntuiText UtilText[UTILMAX];
extern struct Menu menu[MAXMENU];
extern struct timerequest Timer, Script_Timer;
extern struct MsgPort *Timer_Port, *Script_Timer_Port;
extern struct IOExtSer *Read_Request;
extern char *rs_in;
extern struct IOExtSer *Write_Request;
extern char rs_out[2];
extern int x,y,curmode;
extern int MINX,MAXX,MINY,MAXY,top,bot,savx,savy;
extern int savmode,nlmode,alt,savalt,a[2],sa[2];
extern int inesc,inctrl,private,badseq,maxcol;
extern struct IOAudio Audio_Request;
extern struct MsgPort *Audio_Port;
extern UBYTE *BeepWave;
extern UBYTE Audio_AllocMap[4];
extern int p_baud,p_screen,p_interlace,p_depth,p_buffer,p_wbcolors;
extern int p_foreground,p_background,p_bold,p_cursor,p_lines,p_mode;
extern int p_parity,p_volume,p_wrap,p_echo,p_keyapp,p_curapp,p_bs_del;
extern int p_convert;
extern char p_keyscript;
extern long p_break;
extern char *p_f[10],*p_F[10];
extern int script_on;
extern int script_wait;
extern int doing_init;
/* vt100.c */
extern int do_send(),do_capture(),cleanup();
extern void setserpar(), setserbaud(), setparams(), redoutil(), redocomm(),
handle_menupick();
/* init.c */
extern void InitDevs(),InitFileItems(),InitCommItems(),
InitScriptItems(),InitUtilItems(),InitMenu();
extern char *InitDefaults();
/* window.c */
extern void swap_bs_del(),req(),emits(),emit(),emitbatch(),cursorflip();
extern int toasc();
extern void ScrollInfoMsg(), InfoMsgNoScroll(), InfoMsg1Line(),
InfoMsg2Line();
/* xmodem.c */
extern void sendchar(),sendstring(),sendbreak(),multi_xfer(),
No_XON(),Do_XON();
extern int readchar(),XMODEM_Read_File(),XMODEM_Send_File();
/* remote.c */
extern void doremote(),doindex(),doctrl(),doesc(),doerase();
/* kermit.c */
extern int doksend(), dokreceive(), saybye();
extern void encode(), decode(), rpar(), spar();
/* script.c */
extern int script_start(), chk_script(), exit_script(),
do_script_cmd();
extern char *next_wrd(), *tostring();
/* init commands */
extern void cmd_bkg(), cmd_bold(), cmd_buf(), cmd_cursor(), cmd_depth(),
cmd_fore(), cmd_inter(), cmd_lines(), cmd_screen(),
cmd_volume(), cmd_wb(), cmd_null(),
/* script commands */
cmd_as(), cmd_beep(), cmd_cap(), cmd_cd(), cmd_delay(),
cmd_goto(), cmd_goto(), cmd_kb(), cmd_kg(), cmd_kr(),
cmd_ks(), cmd_on(), cmd_sb(), cmd_send(), cmd_wait(),
cmd_xr(), cmd_xs(),
/* init and script commands */
cmd_appcur(), cmd_baud(), cmd_bt(), cmd_conv(), cmd_echo(),
cmd_exit(), cmd_fnc(), cmd_key(), cmd_mode(), cmd_numkey(),
cmd_parity(), cmd_swap(), cmd_wrap();
/* expand.c */
extern char **expand();
extern int set_dir(), free_expand();
SHAR_EOF
cat << \SHAR_EOF > xmodem.c
/*************************************************************
* vt100 terminal emulator - XMODEM protocol support
*
* v2.7 870825 ACS - Make multi_xfer() non-recursive; on non-ESC in
* readchar() re-do the main window's title.
* v2.6 870227 DBW - bug fixes for all the stuff in v2.5
* v2.5 870214 DBW - more additions (see readme file)
* v2.4 861214 DBW - lots of fixes/additions (see readme file)
* v2.3 861101 DBW - minor bug fixes
* v2.2 861012 DBW - more of the same
* v2.1 860915 DBW - new features (see README)
* 860901 ACS - Added Parity and Word Length and support code
* 860823 DBW - Integrated and rewrote lots of code
* 860815 Steve Drew: readchar inproved with real timeouts
* v2.0 860809 DBW - Major rewrite
* v1.1 860720 DBW - Switches, 80 cols, colors, bug fixes
* v1.0 860712 DBW - First version released
*
*************************************************************/
#include "vt100.h"
int enablexon = TRUE;
extern struct IntuiText MyTitle;
static unsigned long parity_settings[4] = {
0x96696996,
0x69969669,
0x69969669,
0x96696996 };
/************************************************************
* Send a string (using sendchar below)
************************************************************/
void sendstring(s)
char *s;
{
char c;
while ((c = *s++) != '\000') sendchar(c);
}
/**************************************************************/
/* send char and read char functions for the xmodem function */
/************************************************************/
void sendchar(ch)
int ch;
{
int doxon,i,j,k;
doxon = enablexon;
if (doxon) No_XON();
switch (p_parity) {
case 0: /* no parity */
rs_out[0] = ch & 0xFF;
break;
case 1: /* mark */
rs_out[0] = (ch & 0x7F) | 0x80;
break;
case 2: /* space */
rs_out[0] = ch & 0x7F;
break;
case 3: /* even */
case 4: /* odd */
i = (ch >> 5) & 0x3;
j = ch & 0x1F;
k = ((parity_settings[i] >> j) & 0x1) << 7;
if (p_parity == 3) /* even parity */
rs_out[0] = (ch & 0x7F) | k;
else /* odd parity */
rs_out[0] = (ch & 0x7F) | (k ^ 0x80);
}
do {
DoIO(Write_Request);
} while(Write_Request->IOSer.io_Error != 0);
if (doxon) Do_XON();
}
/* send a break to the host */
void sendbreak() {
AbortIO(Read_Request);
Wait(1L << Read_Request->IOSer.io_Message.mn_ReplyPort->mp_SigBit);
WaitIO(Read_Request);
Read_Request->IOSer.io_Command = SDCMD_BREAK;
DoIO(Read_Request);
Read_Request->IOSer.io_Command = CMD_READ;
SendIO(Read_Request);
}
int readchar()
{
int rd,ch;
ULONG class, waitmask;
USHORT code;
Timer.tr_time.tv_secs = ttime;
Timer.tr_time.tv_micro = 0;
SendIO((char *) &Timer.tr_node);
rd = FALSE;
waitmask = ((1L << Read_Request->IOSer.io_Message.mn_ReplyPort->mp_SigBit) |
( 1L << mywindow->UserPort->mp_SigBit) |
( 1L << Timer_Port->mp_SigBit));
if(reqwinup)
waitmask |= (1L << reqwindow->UserPort->mp_SigBit);
while (rd == FALSE) {
Wait(waitmask);
if (CheckIO(Read_Request)) {
WaitIO(Read_Request);
ch=rs_in[0];
rd = TRUE;
SendIO(Read_Request);
}
if(reqwinup &&
(NewMessage=(struct IntuiMessage *)GetMsg(reqwindow->UserPort))) {
class = NewMessage->Class;
ReplyMsg(NewMessage);
if(class == NEWSIZE)
ReqNewSize(reqwindow->Height, reqwindow->Width);
}
if (NewMessage=(struct IntuiMessage *)GetMsg(mywindow->UserPort)) {
class = NewMessage->Class;
code = NewMessage->Code;
ReplyMsg(NewMessage);
if ((class == RAWKEY) && (code == 69)) {
AbortIO((char *) &Timer);
Wait (1L << Timer_Port->mp_SigBit);
WaitIO((char *) &Timer.tr_node);
InfoMsg1Line("ERROR: User aborted transfer");
timeout = USERABORT;
return('\0');
}
PrintIText(mywindow->RPort, &MyTitle, 0L, 0L);
continue;
}
if (rd == FALSE && CheckIO(&Timer)) {
InfoMsg1Line("ERROR: Timeout waiting for character");
timeout = TIMEOUT;
return('\0');
}
} /* end while */
AbortIO((char *) &Timer);
Wait (1L << Timer_Port->mp_SigBit);
WaitIO((char *) &Timer.tr_node);
timeout = GOODREAD;
return(ch & (p_parity == 0 ? 0xFF : 0x7F));
}
void No_XON() {
/* turn off XON/XOFF processing */
enablexon = FALSE;
Write_Request->io_SerFlags |= SERF_XDISABLED;
Write_Request->IOSer.io_Command = SDCMD_SETPARAMS;
DoIO(Write_Request);
Write_Request->IOSer.io_Command = CMD_WRITE;
}
void Do_XON() {
/* turn on XON/XOFF processing */
enablexon = TRUE;
Write_Request->io_SerFlags &= ~SERF_XDISABLED;
Write_Request->IOSer.io_Command = SDCMD_SETPARAMS;
DoIO(Write_Request);
Write_Request->IOSer.io_Command = CMD_WRITE;
}
/**************************************/
/* xmodem send and recieve functions */
/************************************/
int XMODEM_Read_File(file)
char *file;
{
int firstchar, sectnum, sectcurr, sectcomp, errors, errorflag;
unsigned int checksum, j, bufptr;
char scrstr2[40];
bytes_xferred = 0L;
ttime = TTIME_SHORT;
if ((fd = creat(file, 0)) < 0)
{
InfoMsg2Line("XMODEM Can't Open File:",file);
return FALSE;
}
else
InfoMsg1Line("XMODEM Receive, <esc> in VT100 window to abort");
sectnum = errors = bufptr = 0;
sendchar(NAK);
firstchar = 0;
No_XON();
while (firstchar != EOT && errors != ERRORMAX)
{
errorflag = FALSE;
do { /* get sync char */
firstchar = readchar();
if (timeout != GOODREAD) {
if (timeout == USERABORT || errors++ == ERRORMAX)
Do_XON();
return FALSE;
}
} while (firstchar != SOH && firstchar != EOT);
if (firstchar == SOH)
{
sprintf(scrstr2,"Getting Block %4d...",sectnum);
InfoMsgNoScroll(scrstr2);
sectcurr = readchar();
if (timeout != GOODREAD) { Do_XON(); return FALSE; }
sectcomp = readchar();
if (timeout != GOODREAD) { Do_XON(); return FALSE; }
if ((sectcurr + sectcomp) == 255)
{
if (sectcurr == ((sectnum + 1) & 0xff))
{
checksum = 0;
for (j = bufptr; j < (bufptr + SECSIZ); j++)
{
bufr[j] = readchar();
if (timeout != GOODREAD) { Do_XON(); return FALSE; }
checksum = (checksum + bufr[j]) & 0xff;
}
if (checksum == readchar() && timeout == GOODREAD)
{
errors = 0;
sprintf(scrstr2,"Block %4d verified",sectnum);
sectnum++;
bufptr += SECSIZ;
bytes_xferred += SECSIZ;
InfoMsgNoScroll(scrstr2);
if (bufptr == BufSize)
{
if (write(fd, bufr, BufSize-128) == EOF)
{
InfoMsg1Line("XMODEM: Error Writing File");
Do_XON();
return FALSE;
}
bufptr = 128;
for (j = 0; j < 128; j++)
bufr[j] = bufr[(BufSize-128)+j];
}
sendchar(ACK);
}
else
{
errorflag = TRUE;
if (timeout == USERABORT) { Do_XON(); return FALSE; }
}
}
else
{
/* got a duplicate sector */
if (sectcurr == (sectnum & 0xff))
{
/* wait until we time out for 5secs */
do {
readchar();
} while (timeout == GOODREAD);
if (timeout == USERABORT) {
Do_XON();
return FALSE;
}
InfoMsg1Line("XMODEM: Received Duplicate Sector");
sendchar(ACK);
}
else errorflag = TRUE;
}
}
else errorflag = TRUE;
}
if (errorflag == TRUE)
{
errors++;
InfoMsg1Line("XMODEM: Error");
sendchar(NAK);
}
} /* end while */
if ((firstchar == EOT) && (errors < ERRORMAX))
{
sendchar(ACK);
while (bufptr > 0 && (bufr[--bufptr] == 0x00 ||
bufr[bufptr] == 0x1A)) ;
write(fd, bufr, ++bufptr);
close(fd);
Do_XON();
ScrollInfoMsg(1);
return TRUE;
}
Do_XON();
return FALSE;
}
int XMODEM_Send_File(file)
char *file;
{
int sectnum, bytes_to_send, size, attempts, c;
unsigned checksum, j, bufptr;
char scrstr2[40];
bytes_xferred = 0;
ttime = TTIME_LONG;
if ((fd = open(file, 0)) < 0) {
InfoMsg1Line("XMODEM: Cannot Open Send File");
return FALSE;
}
else
InfoMsg1Line("XMODEM Send, <esc> from VT100 window to abort");
attempts = 0;
sectnum = 1;
No_XON();
/* wait for sync char */
j=1;
while (((c = readchar()) != NAK) && (j++ < ERRORMAX))
if (timeout == USERABORT) { Do_XON(); return(FALSE); }
if (j >= (ERRORMAX))
{
InfoMsg1Line("XMODEM: Receiver not sending NAKs");
Do_XON();
return FALSE;
}
while ((bytes_to_send = read(fd, bufr, BufSize)) &&
attempts != RETRYMAX)
{
if (bytes_to_send == EOF)
{
InfoMsg1Line("XMODEM: Error Reading File");
Do_XON();
return FALSE;
}
bufptr = 0;
while (bytes_to_send > 0 && attempts != RETRYMAX)
{
attempts = 0;
sprintf(scrstr2,"Sending block %4d",sectnum);
do {
InfoMsgNoScroll(scrstr2);
sendchar(SOH);
sendchar(sectnum);
sendchar(~sectnum);
checksum = 0;
size = SECSIZ <= bytes_to_send ? SECSIZ : bytes_to_send;
bytes_to_send -= size;
for (j = bufptr; j < (bufptr + SECSIZ); j++)
if (j < (bufptr + size)) {
sendchar(bufr[j]);
checksum += bufr[j];
}
else sendchar(0);
sendchar(checksum);
attempts++;
c = readchar();
if (timeout == USERABORT) {
InfoMsg1Line("XMODEM: ABORTED");
Do_XON();
return FALSE;
}
} while ((c != ACK) && (attempts != RETRYMAX));
bufptr += size;
bytes_xferred += size;
sprintf(scrstr2,"Sent block %4d",sectnum);
InfoMsgNoScroll(scrstr2);
sectnum++;
}
}
close(fd);
if (attempts == RETRYMAX)
{
InfoMsg1Line("XMODEM: No Acknowledgment, ABORTING");
Do_XON();
return FALSE;
}
else
{
attempts = 0;
do {
sendchar(EOT);
attempts++;
} while ((readchar() != ACK) &&
(attempts != RETRYMAX) &&
(timeout != USERABORT)) ;
if (attempts == RETRYMAX)
InfoMsg1Line("XMODEM: No end of file");
}
Do_XON();
ScrollInfoMsg(1);
return TRUE;
}
/* allow for multi file xfers separated by commas under
kermit and XMODEM */
void multi_xfer(name,mode,do_send)
char *name;
int (*mode)();
int do_send;
{
int done = 0;
int status;
char *p, *name_start;
timeout = USERABORT - 1;
for(p=name_start=name; !done && timeout != USERABORT; name_start=++p)
{
if (*(name_start) == '$' && *(name_start+1) == '\0') {
saybye();
return;
}
while(*p == ' ') p++;
while(*p && *p != ',' && *p != ' ') p++;
if (*p == '\0') {
done = TRUE;
multi = 0;
}
else
multi = 1;
*p = '\0';
status = ((*mode)(name_start, multi));
if (status == FALSE) close(fd);
}
server = 0;
multi = 0;
}
SHAR_EOF