home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Fred Fish Collection 1.5
/
ffcollection-1-5-1992-11.iso
/
ff_disks
/
300-399
/
ff330.lzh
/
Vt100
/
Src.lzh
/
Src
/
script.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-03-01
|
42KB
|
1,815 lines
static char rcsid[] = "$RCSfile: script.c,v $ $Revision: 1.5 $";
/*************************************************************
* vt100 terminal emulator - Script file support
* :ts=8
*
* $Log: script.c,v $
* Revision 1.5 89/12/14 20:32:10 acs
* Wasn't beeping after a transfer using external protocols.
*
* Revision 1.4 89/12/11 20:35:04 acs
* 1) do_script_cmd(): if(CmdFromRexx) should return a value. Thanks to
* William Dimm (wdimm@lehi3b15.csee.Lehigh.EDU).
* 2) cmd_ext(): After successfully deleting an external protocol it should
* return CMDOK. Thanks again, William!
* 3) Displaynames for external protocols no longer need 2 spaces before
* the name.
*
* Revision 1.3 89/11/02 10:27:06 acs
* New command: STRIP which will strip parity from data destined for
* display.
*
* Revision 1.2 89/11/01 15:32:54 acs
* 1) Make cmd_from_script accessible to other source modules.
* 2) Add RCS id and change log.
*
* v2.9 ACS - Add support for font size, external transfer program
* support, new ASIS option to LACE cmd and AREXX support.
* v2.8a 880331 ACS - Allow comments on XPROTO and FONT.
* 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"
#define DNMAXLEN 9
extern struct MsgPort *mySerPort; /* in vt100.c */
struct COMMAND {
int (*func)();
char *cname;
int minlen;
int validfrom;
};
#define INIT 1
#define SCRIPT 2
#define NONREXX 4
#define REXXONLY 8
struct LABEL {
struct LABEL *next;
char *name;
long pos;
};
extern long atol();
#if MANX
extern char *index();
#endif /* MANX */
#if LATTICE
#define index(a,b) stpchr(a,b)
#endif /* LATTICE */
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 = NULL; /* file pointer for script file */
struct LABEL *lbase = NULL; /* will point to first label */
struct LABEL *labels; /* current label pointer */
char errmsg[80]; /* Error msg from routines */
#if AREXX
int implied_rexx; /* cmd_rx() invoked as impled cmd */
#endif /* AREXX */
/************************ command table *********************************/
static struct COMMAND commands[] = {
cmd_appcur, "appcursor", 3, INIT|SCRIPT, /* turn app. cursor on/off */
cmd_as, "ascii", 3, SCRIPT, /* ascii send */
cmd_ac, "autochop", 3, INIT|SCRIPT, /* XMODEM autochop */
cmd_bkg, "background", 3, INIT, /* set background color */
cmd_baud, "baud", 3, INIT|SCRIPT, /* Set Baud Rate */
cmd_beep, "beep", 3, SCRIPT, /* Beep */
cmd_bold, "bold", 3, INIT, /* set bold color */
cmd_bt, "breaktime", 3, INIT|SCRIPT, /* Set Break Time */
cmd_buf, "buffer", 3, INIT, /* set buffer size */
cmd_cap, "capture", 3, SCRIPT, /* ascii capture on/off */
cmd_cd, "cd", 2, SCRIPT, /* change directory */
cmd_conv, "convert", 4, INIT|SCRIPT, /* convert fn to lowercase */
cmd_cursor, "cursor", 3, INIT, /* set cursor color */
cmd_delay, "delay", 3, SCRIPT, /* delay amount of seconds */
cmd_depth, "depth", 3, INIT, /* set screen depth */
cmd_device, "device", 3, INIT, /* set serial device name */
cmd_display, "display", 3, SCRIPT, /* Display data on screen */
cmd_echo, "echo", 3, INIT|SCRIPT, /* turn echo on or off */
cmd_exit, "exit", 3, INIT|SCRIPT|NONREXX, /* exit script file */
cmd_ext, "external", 4, INIT|SCRIPT, /* external xfer pgms */
cmd_fnc, "f", 1, INIT|SCRIPT, /* define function key */
cmd_font, "font", 3, INIT, /* set font */
cmd_fonts, "fontsize", 5, INIT, /* set fontsize */
cmd_fore, "foreground", 3, INIT, /* set foreground color */
#if AREXX
cmd_fwd, "forward", 3, REXXONLY, /* forward data to rexx */
#endif /* AREXX */
cmd_goto, "goto", 3, SCRIPT|NONREXX,/* goto label */
cmd_inter, "interlace", 3, INIT, /* interlace ON/OFF */
cmd_kb, "kb", 2, SCRIPT, /* kermit bye (for server) */
cmd_key, "keyscript", 3, INIT|SCRIPT, /* keyscript character */
cmd_kg, "kg", 2, SCRIPT, /* kermit get file */
cmd_kmaxpk, "kmaxpack", 8, INIT|SCRIPT, /* Kermit maximum packet size */
cmd_kr, "kr", 2, SCRIPT, /* kermit receive file */
cmd_ks, "ks", 2, SCRIPT, /* kermit send file */
cmd_lines, "lines", 3, INIT, /* num lines */
cmd_mode, "mode", 3, INIT|SCRIPT, /* KERMIT transfer mode */
cmd_mouse, "mouse", 3, INIT|SCRIPT, /* Mouse control */
cmd_msg, "msg", 3, SCRIPT, /* Display a message */
cmd_numkey, "numkey", 6, INIT|SCRIPT, /* turn numeric kpad on/off */
cmd_on, "on", 2, SCRIPT, /* on a 'string' do a cmd */
cmd_parity, "parity", 6, INIT|SCRIPT, /* Set Parity */
cmd_recf, "recfile", 4, SCRIPT, /* receive a file from host */
cmd_rx, "rx", 2, INIT|SCRIPT, /* Specific invocation */
cmd_sb, "sb", 2, SCRIPT, /* Send a break */
cmd_screen, "screen", 3, INIT, /* Screen WB/CUST */
cmd_send, "send", 4, SCRIPT, /* send string to host */
cmd_sendf, "sendfile", 5, SCRIPT, /* send a file to host */
cmd_share, "shareserial", 5, INIT|SCRIPT, /* ShareSerial device */
cmd_short, "shortcut", 3, INIT, /* Set shortcuts */
cmd_strip, "strip", 2, INIT|SCRIPT, /* Strip parity for display */
cmd_swap, "swap", 4, INIT|SCRIPT, /* Swap BS and DEL */
cmd_unit, "unit", 4, INIT, /* Unit of serial.device to use */
cmd_volume, "volume", 3, INIT, /* set volume */
cmd_wait, "wait", 4, SCRIPT|NONREXX, /* wait for a host string */
cmd_wb, "wbcolors", 3, INIT, /* use WB colors */
cmd_wrap, "wrap", 4, INIT|SCRIPT, /* turn wrap on or off */
cmd_xbeep, "xbeep", 4, INIT|SCRIPT, /* Beep at end of xfer */
cmd_xproto, "xprotocol", 5, INIT|SCRIPT, /* Xfer Protocol */
cmd_xr, "xr", 2, SCRIPT, /* xmodem receive file */
cmd_xs, "xs", 2, SCRIPT, /* xmodem send file */
cmd_null, NULL, 0, 0 /* mark the end of the list */
};
char *xprotos[] = { /* Order *must* be same as corresponding p_xproto values */
"ascii", "xmodem", "xmodemcrc", "kermit" };
/* NB: The structures referenced in the structure may be found in
** init.c */
extern struct filecmd {
char mo; /* Mode */
char se; /* Send */
char re; /* Receive */
char kg; /* Kermit Get */
char kb; /* Kermit Bye */
char ca; /* Capture or Capturing */
char nl;
} filecmd_chars;
extern struct mode_cmd {
char as; /* ascii mode */
char xm; /* xmodem mode */
char xmc; /* xmodem crc mode */
char ke; /* kermit mode */
char nl;
} modecmd_chars;
extern struct baducmd {
char b03; /* 0300 */
char b12; /* 1200 */
char b24; /* 2400 */
char b48; /* 4800 */
char b96; /* 9600 */
char bnl;
} baudcmd_chars;
extern struct parcmd {
char no; /* NOne */
char ma; /* MArk */
char sp; /* SPace */
char ev; /* EVen */
char od; /* ODd */
char st; /* STrip */
char nl;
} parcmd_chars;
extern struct commcmd {
char nl0; /* Baud Sub-Item */
char nl1; /* Parity Sub-Item */
char nl2; /* Xfer mode Sub-Item */
char sh; /* Shared item */
char nl;
} commcmd_chars;
extern struct modcmd {
char im; /* IMage */
char tx; /* TeXt */
char cn; /* CoNvert */
char ac; /* AutoChop */
char nl;
} modcmd_chars;
extern struct scrcmd {
char em; /* Execute Macro */
char ab; /* Abort Macro */
char rx; /* AREXX 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 xb; /* Beep at end of Xfer */
char mu; /* Mouse up events */
char md; /* Mouse down events */
char nl;
} utilcmd_chars;
static struct SHORT_CUTS shortkeys[] = { /* Short-cut keys */
/* File items: */
"se", &(filecmd_chars.se), /* Send file */
"re", &(filecmd_chars.re), /* Receive file */
"kb", &(filecmd_chars.kb), /* kermit bye (for server) */
"kg", &(filecmd_chars.kg), /* kermit get (for server) */
"cap", &(filecmd_chars.ca), /* Capture */
/* Mode items: */
"asc", &(modecmd_chars.as), /* ascii mode */
"xmc", &(modecmd_chars.xmc), /* xmodemcrc mode */
"xm", &(modecmd_chars.xm), /* xmodem mode */
"ke", &(modecmd_chars.ke), /* kermit mode */
/* Comm items: */
"share", &(commcmd_chars.sh), /* Shared */
"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 */
"strip", &(parcmd_chars.st), /* Strip parity */
"image", &(modcmd_chars.im), /* KERMIT transfer mode */
"text", &(modcmd_chars.tx), /* KERMIT transfer mode */
"convert", &(modcmd_chars.cn), /* KERMIT transfer mode */
"autochop", &(modcmd_chars.ac), /* XMODEM autochop */
/* Script items: */
"execute", &(scrcmd_chars.em), /* execute macro */
"abort", &(scrcmd_chars.ab), /* abort macro */
"rx", &(scrcmd_chars.rx), /* rexx 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 */
"xbeep", &(utilcmd_chars.xb), /* Beep at end of xfer */
"mouseup", &(utilcmd_chars.mu), /* Mouse up events */
"mousedn", &(utilcmd_chars.md), /* Mouse dn events */
NULL, NULL
};
int cmd_from_script; /* != 0 iff cmd from a script */
/********************************************************************/
/* 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;
on_string[0] = '\0';
on_cmd[0] = '\0';
onpos = 0;
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)
register char *p;
int l;
{
int i, l2, cmdrc = CMDOK;
register struct COMMAND *cmd;
/* downcase the command */
for (i=0; i<l; i++) p[i] |= ' ';
errmsg[0] = '\0';
/* now search for it */
for (cmd = commands; cmd->func != cmd_null; cmd++) {
int validfrom = cmd->validfrom;
if(*p != cmd->cname[0])
continue;
l2 = strlen(cmd->cname);
if(l >= cmd->minlen && l <= l2
&& strncmp(p, cmd->cname, l) == 0) {
if( (!doing_init && (validfrom == INIT))
|| (((validfrom & NONREXX) == NONREXX) && CmdFromRexx)
|| (((validfrom & REXXONLY) == REXXONLY) && !CmdFromRexx) )
return(CMDBS);
cmd_from_script = 1;
cmdrc = (*(cmd->func))(next_wrd(p+l, &l));
cmd_from_script = 0;
if(errmsg[0])
if(doing_init) {
puts("Init:");
puts(errmsg);
} else
InfoMsg2Line("Script:", errmsg);
return(cmdrc);
}
}
#if AREXX
if(implied_rexx == 0 && RexxSysBase != NULL) {
implied_rexx = 1;
cmdrc = cmd_rx(p);
implied_rexx = 0;
return(cmdrc);
}
#endif /* AREXX */
if (doing_init) {
puts("Init: unknown command:");
puts(p);
} else
InfoMsg2Line("Script - unknown command:",p);
return(CMDNF);
}
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) {
if(!CheckIO((struct IORequest *)&Script_Timer))
AbortIO((struct IORequest *)&Script_Timer);
Wait (1L << Script_Timer_Port->mp_SigBit);
WaitIO((struct IORequest *)&Script_Timer);
/* script will proceed after on command */
script_wait = FALSE;
}
exe_cmd(p,l);
return(0);
}
script_wait = FALSE;
if(CmdFromRexx)
return 0;
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 */
if(!CheckIO((struct IORequest *)&Script_Timer))
AbortIO((struct IORequest *)&Script_Timer); /* so abort it */
Wait (1L << Script_Timer_Port->mp_SigBit); /* Wait for the sig */
WaitIO((struct IORequest *)&Script_Timer); /* Get my reply back */
}
InfoMsg1Line("Script: terminated");
script_on = FALSE;
script_wait = TRUE;
on_match = FALSE;
wait_string[0] = '\0';
on_string[0] = '\0';
on_cmd[0] = '\0';
fclose(sf);
sf = NULL;
if (reqwinup && ((reqwindow->Flags) & WINDOWACTIVE))
ActivateWindow(mywindow);
return 0;
}
/* remove quotes terminate string & return pointer to start */
char *tostring(ptr)
char *ptr;
{
register char *s1, *s2;
if(*ptr == '\0')
return ptr;
s1 = ptr;
if (*ptr == '"') {
while(*ptr++) {
if(*ptr == '"')
if(*(ptr+1) == '"')
ptr++;
else
break;
}
/* Only 2 ways out: encounter an single " or hit \0. */
if (*ptr == '"')
*ptr = '\0';
ptr = s2 = ++s1;
while(*s2) {
switch(*s2) {
case '"':
if(*(s2+1) == '"')
*s1++ = *s2++;
break;
case '^':
if(*(s2+1) == '^')
*s1++ = *s2++;
else
*s1++ = ((*++s2) | ' ') - 96;
break;
default:
*s1++ = *s2;
break;
}
s2++;
}
*s1 = '\0';
return(ptr);
}
if (*s1 == '^') {
*s1 = (*(s1+1)|' ')-96;
*(s1+1) = '\0';
return(s1);
}
*(s1+1) = '\0';
return(s1);
}
/***************************** SCRIPT COMMANDS ********************/
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);
}
return 0;
}
cmd_send(str)
char *str;
{
register char *p = tostring(str);
int i, len = strlen(p);
if(p_echo)
for(i = 0; i < len; i++) {
doremote(*p);
sendchar(*(p++));
}
else
sendstring(p);
return 0;
}
cmd_wait(str)
char *str;
{
int waitstrsize = sizeof(wait_string) - 1;
str = tostring(str);
strncpy(wait_string, str, waitstrsize);
wait_string[waitstrsize] = '\0';
waitsize = strlen(wait_string);
script_wait = WAIT_STRING;
return 0;
}
cmd_on(str)
char *str;
{
char *p;
p = tostring(str);
if( (onsize = strlen(p)) == 0) {
on_string[0] = '\0';
on_cmd[0] = '\0';
} else {
int onstrsize = sizeof(on_string) - 1,
oncmdsize = sizeof(on_cmd) - 1,
len;
strncpy(on_string, p, onstrsize);
on_string[onstrsize] = '\0';
p = next_wrd(p+onsize+1, &len);
strncpy(on_cmd, p, oncmdsize);
on_cmd[oncmdsize] = '\0';
}
return 0;
}
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((struct IORequest *)&Script_Timer.tr_node);
return 0;
}
cmd_exit(option)
char *option;
{
char *p;
int l;
if (doing_init)
return 0;
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++));
}
}
return 0;
}
cmd_ext(parms)
char *parms;
{
struct ExternalXfer *cexp;
int i, j, len, nxfer, ci_strcmp(), cmdrc = CMDOK;
char *p, temp[80], bound, *send, *dn;
unsigned long mem_type = MEMF_PUBLIC | MEMF_CLEAR;
parms = next_wrd(parms, &len); /* Step to start of display name */
if(len <= 0) { /* No next word...error */
strcpy(errmsg, "No display name for EXT command.");
return CMDFAIL;
}
dn = parms; /* Remember start of display name */
parms += len; /* Step to end of word */
*(parms++) = '\0'; /* Mark end of display name and step beyond it */
if(len > DNMAXLEN) {
*(dn+DNMAXLEN) = '\0';
sprintf(temp, "Display name more than %d chars, 1st %d used in EXT %s",
DNMAXLEN, DNMAXLEN, dn);
if(doing_init) {
puts("Init:");
puts(temp);
} else
InfoMsg2Line("Script:", temp);
cmdrc = CMDWARN;
}
parms = next_wrd(parms, &len); /* Step to start of SEND cmd */
/* Find a matching ExternalXfer structure based on display name */
for(i = 0; i < NumExts; i++) {
if(ci_strcmp(ExtXfer[i]->downname, dn) == 0)
if(len > 0) /* Replace this entry */
break;
else { /* remove this entry from the list */
struct ExternalXfer *p = ExtXfer[i];
FreeMem(p->dispname, (long)(strlen(p->dispname)+1));
FreeMem(p->downname, (long)(strlen(p->downname)+1));
FreeMem(p->send, (long)(strlen(p->send)+1));
FreeMem(p->receive, (long)(strlen(p->receive)+1));
FreeMem(p, (long)sizeof(struct ExternalXfer));
ExtXfer[i] = NULL;
for(j = i+1; j < NumExts; j++)
ExtXfer[j-1] = ExtXfer[j];
NumExts--;
if(!doing_init)
InitFileItems();
return CMDOK;
}
}
nxfer = i; /* Remember index of match or where to put new... */
cexp = ExtXfer[nxfer]; /* ...and its location. */
bound = *(parms++); /* Remember starting quote for SEND command and step over it */
if((p = index(parms, bound)) == NULL) {
sprintf(errmsg, "No ending quote for SEND cmd in EXT %s", dn);
return CMDFAIL;
}
*p = '\0'; /* Replace ending quote with NULL */
send = parms; /* Remember start of SEND cmd... */
parms = ++p; /* ...and step over the NULL */
parms = next_wrd(parms, &len); /* Step to start of RECEIVE cmd */
if(len <= 0) {
sprintf(errmsg, "No RECEIVE command for EXT %s", dn);
return CMDFAIL;
}
bound = *(parms++);
if((p =index(parms, bound)) == NULL) {
sprintf(errmsg, "No ending quote for RECEIVE cmd in EXT %s", dn);
return CMDFAIL;
}
*p = '\0';
if(cexp) { /* changing a current entry */
FreeMem(cexp->dispname, (long)(strlen(cexp->dispname)+1));
FreeMem(cexp->downname, (long)(strlen(cexp->downname)+1));
FreeMem(cexp->send, (long)(strlen(cexp->send)+1));
FreeMem(cexp->receive, (long)(strlen(cexp->receive)+1));
cexp->cmdkey = '\0';
} else if(nxfer >= EXTMAX) {
sprintf(errmsg, "EXT %s would add more than %d external protocols",
dn, EXTMAX);
return CMDFAIL;
} else {
cexp = (struct ExternalXfer *)
AllocMem((long)sizeof(struct ExternalXfer), mem_type);
ExtXfer[nxfer] = cexp;
NumExts++;
}
/* Initialize the new ExternalXfer entry. Leave room in dispname for
** a checkmark (2 character widths). */
len = strlen(dn);
cexp->dispname = (char *)AllocMem((long)len+1, mem_type);
strcpy(cexp->dispname, dn);
cexp->downname = (char *)AllocMem((long)len+1, mem_type);
for(i = 0; i < len; i++)
cexp->downname[i] = dn[i] | ' ';
cexp->send = (char *)AllocMem((long)strlen(send)+1, mem_type);
strcpy(cexp->send, send);
cexp->receive = (char *)AllocMem((long)strlen(parms)+1, mem_type);
strcpy(cexp->receive, parms);
if(!doing_init)
InitFileItems();
return cmdrc;
}
cmd_ks(file)
char *file;
{
char name[MAXGADSTR], *p;
if(file)
strcpy(name, file);
else
name[0] = '\0';
if(file == NULL || *file == '\0' || !cmd_from_script) {
req("Kermit Send:",name,1);
p = name;
if(file && !cmd_from_script)
strcpy(file, name);
} else
p = file;
multi_xfer(p, doksend, 1);
return CMDOK;
}
cmd_kr(file)
char *file;
{
char name[80];
name[0] = '\0';
multi_xfer(name, dokreceive, 0);
return CMDOK;
}
cmd_kg(file)
char *file;
{
char name[MAXGADSTR], *p;
if(file)
strcpy(name, file);
else
name[0] = '\0';
server = TRUE;
if(file == NULL || *file == '\0' || !cmd_from_script) {
req("Kermit GET remote file(s):", name, 1);
p = name;
if(file && !cmd_from_script)
strcpy(file, name);
} else
p = file;
multi_xfer(p, dokreceive, 0);
return CMDOK;
}
cmd_kb()
{
saybye();
return CMDOK;
}
cmd_recf(file)
char *file;
{
int cmdrc = CMDOK;
switch(p_xproto) {
case 0: /* Ascii */
do_capture(file);
break;
case 1: /* Xmodem */
case 2: /* XmodemCRC */
if(p_parity > 0) {
InfoMsg1Line("Parity setting prevents XMODEM receive.");
break;
}
cmd_xr(file);
break;
case 3: /* Kermit */
cmd_kr(file);
break;
default:
if(p_xproto > MODEMAX + NumExts - 1)
cmd_kr(file);
else
cmdrc = do_ext(ExtXfer[p_xproto-MODEMAX],
ExtXfer[p_xproto-MODEMAX]->receive,
file);
}
return cmdrc;
}
cmd_sendf(file)
char *file;
{
int cmdrc = CMDOK;
switch(p_xproto) {
case 0: /* Ascii */
do_send(file);
break;
case 1: /* Xmodem */
case 2: /* XmodemCRC */
if(p_parity > 0) {
InfoMsg1Line("Parity setting prevents XMODEM send.");
cmdrc = CMDFAIL;
break;
}
cmd_xs(file);
break;
case 3: /* Kermit */
cmd_ks(file);
break;
default:
if(p_xproto > MODEMAX + NumExts - 1)
cmd_ks(file);
else
cmdrc = do_ext(ExtXfer[p_xproto-MODEMAX],
ExtXfer[p_xproto-MODEMAX]->send,
file);
}
return cmdrc;
}
cmd_xs(file)
char *file;
{
char name[MAXGADSTR], *p;
if(file)
strcpy(name, file);
else
name[0] = '\0';
if(file == NULL || *file == '\0' || !cmd_from_script) {
req("Xmodem Send:",name,1);
p = name;
if(file && !cmd_from_script)
strcpy(file, name);
} else
p = file;
multi_xfer(p, XMODEM_Send_File, 1);
return CMDOK;
}
cmd_xr(file)
char *file;
{
char name[MAXGADSTR], *p;
if(file)
strcpy(name, file);
else
name[0] = '\0';
if(file == NULL || *file == '\0' || !cmd_from_script) {
req("Xmodem Receive:",name,1);
p = name;
if(file && !cmd_from_script)
strcpy(file, name);
} else
p = file;
multi_xfer(p, XMODEM_Read_File, 1);
return CMDOK;
}
cmd_cd(name)
char *name;
{
set_dir(name);
return CMDOK;
}
cmd_sb(str)
char *str;
{
sendbreak();
return CMDOK;
}
cmd_baud(rate)
char *rate;
{
int i = atoi(rate),
cmdrc = CMDOK;
switch( i ) {
case 300:
case 1200:
case 2400:
case 4800:
case 9600:
if (doing_init) p_baud = i;
else setserbaud(i, TRUE);
break;
default:
strcpy(errmsg, "Invalid baud rate: ");
strcat(errmsg, rate);
cmdrc = CMDFAIL;
break;
}
return cmdrc;
}
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:
strcpy(errmsg, "Init: invalid parity: ");
strcat(errmsg, par);
return CMDFAIL;
}
p_parity = i;
if (doing_init == 0)
redocomm();
return CMDOK;
}
#if AREXX
cmd_rx(cmd)
char *cmd;
{
int cmdrc = CMDOK,
ret = do_rx(cmd, implied_rexx);
char *msg = NULL;
errmsg[0] = '\0';
if(ret) {
cmdrc = CMDFAIL;
if(doing_init)
printf("Init:\n%s\n", rexxerrmsgs[ret]);
else
InfoMsg2Line("Script:", rexxerrmsgs[ret]);
}
return cmdrc;
}
#else
cmd_rx(cmd)
char *cmd;
{
char *msg = "AREXX not compiled into this version.";
if(doing_init)
printf("Init:\n%s\n", msg);
else
InfoMsg2Line("Script:", msg);
return CMDFAIL;
}
#endif
cmd_bt(breaklength)
char *breaklength;
{
p_break = atol(breaklength);
if (doing_init)
return CMDOK;
AbortIO((struct IORequest *)Read_Request);
Wait(1L << Read_Request->IOSer.io_Message.mn_ReplyPort->mp_SigBit);
WaitIO((struct IORequest *)Read_Request);
Read_Request->io_BrkTime = Write_Request->io_BrkTime = p_break;
setparams();
return CMDOK;
}
cmd_kmaxpk(pks)
char *pks;
{
int i = atoi(pks),
cmdrc = CMDOK;
if(i <= MAXLONGPKS)
p_kmaxpack = i;
else {
sprintf(errmsg, "Kermit packet size too big: %d", pks);
cmdrc = CMDFAIL;
}
return cmdrc;
}
cmd_mode(tmode)
char *tmode;
{
switch (*tmode|' ') {
case 'i':
p_mode = 0;
break;
case 'c':
p_mode = 1;
break;
default:
strcpy(errmsg, "Init: invalid transfer mode: ");
strcat(errmsg, tmode);
return CMDFAIL;
}
if (doing_init == 0)
redocomm();
return CMDOK;
}
cmd_as(file)
char *file;
{
do_send(file);
return CMDOK;
}
cmd_cap(file)
char *file;
{
do_capture(file);
return CMDOK;
}
cmd_beep(dummy)
char *dummy;
{
if (p_volume == 0)
DisplayBeep(NULL);
else {
BeginIO((struct IORequest *)&Audio_Request);
WaitIO((struct IORequest *)&Audio_Request);
}
return CMDOK;
}
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;
}
}
cmd_ac(par)
char *par;
{
setvar(par,0,&p_autochop);
if (doing_init == 0)
redoutil();
return CMDOK;
}
cmd_echo(par)
char *par;
{
setvar(par,0,&p_echo);
if (doing_init == 0)
redoutil();
return CMDOK;
}
cmd_wrap(par)
char *par;
{
setvar(par,0,&p_wrap);
if (doing_init == 0)
redoutil();
return CMDOK;
}
cmd_share(parm)
char *parm;
{
int oldval = p_shared;
setvar(parm, 0, &p_shared);
if(Read_Request && (oldval ^ p_shared)) {
/* Port is going from shared->exclusive or vice-versa. Close it and
** re-open */
if(!CheckIO((struct IORequest *)Read_Request))
AbortIO((struct IORequest *)Read_Request);
Wait (1L <<mySerPort->mp_SigBit);
WaitIO((struct IORequest *)Read_Request);
CloseDevice((struct IORequest *)Read_Request);
if(p_shared)
Read_Request->io_SerFlags |= SERF_SHARED;
else
Read_Request->io_SerFlags &= (-1L ^ SERF_SHARED);
if(OpenDevice(mysername,(LONG)p_unit,(struct IORequest *)Read_Request,NULL))
cleanup("Can't re-open Read device",0);
InitCommItems();
setparams();
}
return CMDOK;
}
cmd_xbeep(par)
char *par;
{
setvar(par,0,&p_xbeep);
if (doing_init == 0)
redoutil();
return CMDOK;
}
cmd_xproto(par)
char *par;
{
int i, len, save, cmdrc = CMDOK;
next_wrd(par, &len);
p_xproto = MODEMAX + 1; /* Establish an out of bounds default */
if(len) {
par[len] = '\0';
/* downcase the parameter */
for(i = 0; i < len; i++) par[i] |= ' ';
for(i = 0; i < MODEMAX; i++)
if(strcmp(par, &(*(xprotos[i]))) == 0) {
p_xproto = i;
break;
}
}
if(p_xproto >= MODEMAX) {
/* Not a built-in protocol...check the defined external protocols */
p_xproto = 0;
if(len > DNMAXLEN) {
save = *(par+DNMAXLEN);
*(par+DNMAXLEN) = '\0';
}
for(i = 0; i < NumExts; i++) {
if(strcmp(par, ExtXfer[i]->downname) == 0) {
p_xproto = MODEMAX + i;
break;
}
}
if(p_xproto == 0) {
p_xproto = MODEMAX - 1;
if(len > DNMAXLEN)
*(par+DNMAXLEN) = save;
sprintf(errmsg, "XPROTO beginning \"%.10s\" unknown, %s used",
par, &(*(xprotos[p_xproto])));
cmdrc = CMDFAIL;
}
}
if(!doing_init)
redofile();
return cmdrc;
}
cmd_numkey(par)
char *par;
{
setvar(par,1,&p_keyapp);
if (doing_init == 0)
redoutil();
return CMDOK;
}
cmd_appcur(par)
char *par;
{
setvar(par,0,&p_curapp);
if (doing_init == 0)
redoutil();
return CMDOK;
}
cmd_swap(par)
char *par;
{
setvar(par,0,&p_bs_del);
if (doing_init == 0)
redoutil(); /* Calls InitUtilItems which does swap_bs_del() */
else {
swap_bs_del(); /* Setup keys[] properly... */
swap_bs_del(); /* ...for new mode */
}
return CMDOK;
}
cmd_bkg(par)
char *par;
{
setvar(par,2,&p_background);
return CMDOK;
}
cmd_bold(par)
char *par;
{
setvar(par,2,&p_bold);
return CMDOK;
}
cmd_buf(par)
char *par;
{
setvar(par,3,&p_buffer);
return CMDOK;
}
cmd_cursor(par)
char *par;
{
setvar(par,2,&p_cursor);
return CMDOK;
}
cmd_depth(par)
char *par;
{
setvar(par,3,&p_depth);
return CMDOK;
}
cmd_device(par)
char *par;
{
int len, cmdrc = CMDOK;
char temp[80];
next_wrd(par, &len);
if(len > SERNAMESIZE) {
printf(temp, "Init:\nDevice parm too long, %s used", SERIALNAME);
strcpy(mysername, SERIALNAME);
cmdrc = CMDFAIL;
} else
strcpy(mysername, par);
return cmdrc;
}
cmd_display(str)
char *str;
{
register char *p;
for(p = tostring(str); *p; p++)
doremote(*p);
return CMDOK;
}
cmd_fore(par)
char *par;
{
setvar(par,2,&p_foreground);
return CMDOK;
}
#if AREXX
/* This routine *depends* on the fact that the FORWARD command is only
** valid from AREXX. It then assumes that it can open RXSNAME.
**/
cmd_fwd(par)
char *par;
{
int i;
if(ForwardPortName != NULL) {
FreeMem(ForwardPortName, (LONG)strlen(ForwardPortName) + 1);
ForwardPortName = NULL;
}
forwarding = 0;
if(RexxSysBase == NULL) {
RexxSysBase = (struct RxsLib *)OpenLibrary(RXSNAME, 0L);
if( (i = makerexxport()) != 0) {
strcpy(errmsg, rexxerrmsgs[i]);
return CMDFAIL;
}
}
if(par && *par) {
if(ForwardPortName = AllocMem((LONG)strlen(par)+1,
MEMF_PUBLIC | MEMF_CLEAR)) {
strcpy(ForwardPortName, par);
forwarding = 1;
} else {
strcpy(errmsg, "Can't allocate memory for an AREXX forward port");
return CMDFAIL;
}
}
return CMDOK;
}
#else
cmd_fwd(par)
{
return CMDFAIL;
}
#endif /* AREXX */
cmd_font(par)
char *par;
{
char temp[80];
int len, cmdrc = CMDOK;
next_wrd(par, &len);
temp[0] = '\0';
/* myfontname has been initialized from p_font in InitDefaults() in
** init.c */
if(!len) {
sprintf(temp, "Init:\nNo font specified, \"%s\" used", myfontname);
cmdrc = CMDWARN;
} else {
if(*par && len) {
if(len < MAXFONTVARLEN) {
par[len] = '\0';
strcpy(myfontname, par);
strcat(myfontname,FONTSUFFIX);
} else {
sprintf(temp, "Init:\nFont specification too long, \"%s\" used",
myfontname);
cmdrc = CMDWARN;
}
}
}
myattr.ta_Name = (STRPTR)myfontname;
if(*temp)
puts(temp);
return cmdrc;
}
cmd_fonts(par)
char *par;
{
char temp[80];
int len, size, cmdrc = CMDOK;
next_wrd(par, &len);
temp[0] = '\0';
/* myfontname has been initialized from p_font in InitDefaults() in
** init.c */
if(!len) {
strcpy(temp, "Init:\nNo font size specified, \"8\" used");
cmdrc = CMDWARN;
} else {
if(*par && len) {
size = atoi(par);
if(size > 0)
myattr.ta_YSize = size;
else {
myattr.ta_YSize = 8;
sprintf(temp, "Init:\nFont size \"%s\" invalid, \"8\" used",
par);
cmdrc = CMDWARN;
}
}
}
if(*temp)
puts(temp);
return cmdrc;
}
cmd_inter(par)
char *par;
{
if(strcmp(par, "asis") == 0)
p_interlace = 2;
else
setvar(par,0,&p_interlace);
return CMDOK;
}
cmd_mouse(par)
char *par;
{
switch (par[0]|' ') {
case 'b':
p_mouse_up = p_mouse_down = 1; /* send both */
break;
case 'o':
p_mouse_up = p_mouse_down = 0; /* mouse off */
break;
case 'u':
p_mouse_up = 1; /* up only */
p_mouse_down = 0;
break;
case 'd': /* down only */
p_mouse_down = 1;
p_mouse_up = 0;
break;
default:
return CMDFAIL;
}
return CMDOK;
}
cmd_msg(par)
char *par;
{
register char *p, *s;
int newline = 1; /* Whether we need to scroll */
for(s = p = tostring(par); *p; p++) {
if(*p == '\n') {
*p = '\0';
InfoMsgNoScroll(s);
ScrollInfoMsg(1);
newline = 0;
s = p + 1;
} else if(*p == '\r') {
*p = '\0';
InfoMsgNoScroll(s);
newline = 0;
s = p + 1;
} else
newline = 1;
}
if(*s)
InfoMsgNoScroll(s);
if(newline)
ScrollInfoMsg(1);
return CMDOK;
}
cmd_lines(par)
char *par;
{
setvar(par,3,&p_lines);
return CMDOK;
}
cmd_screen(par)
char *par;
{
if ((par[0]|' ') == 'w') p_screen = 0;
else p_screen = 1;
return CMDOK;
}
cmd_unit(par)
char *par;
{
setvar(par, 3, &p_unit);
return CMDOK;
}
cmd_wb(par)
char *par;
{
setvar(par,0,&p_wbcolors);
return CMDOK;
}
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] != ' ') && (p[i] != '\t'); 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
** shortcut 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] == ' ') || (p[l] == '\t')) ; l++)
;
if(p[l])
*(shortkeys[i].pos) = p[l];
else
*(shortkeys[i].pos) = ' ';
return CMDOK;
}
}
/* Not a "normal" item so try an ExternalXfer item */
p = next_wrd(par, &l);
if(l > 0) {
*(p+l) = '\0';
for(i = 0; i < NumExts; i++)
if(strcmp(p, ExtXfer[i]->downname) == 0) {
p = next_wrd(p+l+1, &l);
if(l <= 0)
break;
ExtXfer[i]->cmdkey = *p;
return CMDOK;
}
}
sprintf(errmsg, "Unknown shortcut: %s", par);
return CMDFAIL;
}
cmd_strip(par)
char *par;
{
setvar(par,0,&p_strip);
return CMDOK;
}
cmd_key(par)
char *par;
{
int i;
if (sscanf(par,"%x",&i) == 1)
p_keyscript = (char)(i & 0x7f);
return CMDOK;
}
cmd_volume(par)
char *par;
{
setvar(par,3,&p_volume);
return CMDOK;
}
cmd_conv(par)
char *par;
{
setvar(par,0,&p_convert);
if (doing_init == 0)
redoutil();
return CMDOK;
}
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(*par == 'm') { /* Mouse prefix */
p_f[10] = malloc(strlen(s) + 1);
strcpy(p_f[10], s);
} else 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);
}
}
return CMDOK;
}
cmd_null(dummy)
char *dummy;
{
return CMDOK;
}
/* Case-insensitive strcmp() */
ci_strcmp(p1, p2)
char *p1, *p2;
{
while( *p1 && ((*p1 | ' ') == (*p2 | ' ')) ) {
++p1;
++p2;
}
return(*p1 != *p2);
}
do_ext(exp, pgmname, file)
struct ExternalXfer *exp;
char *pgmname, *file;
{
char *local = "@LOCAL",
*remote = "@REMOTE",
*command,
localfn[MAXGADSTR],
remotefn[MAXGADSTR],
*p,
*p1;
int len = 0,
locallen = strlen(local),
remotelen = strlen(remote);
if(file)
strcpy(localfn, file);
else
localfn[0] = '\0';
remotefn[0] = '\0';
/* Get the initial length of the command then go through the user's
** command string looking for @LOCAL and @REMOTE. When we encounter one of
** these strings then, if we don't already have the appropriate filename,
** we'll put up a requester asking for it. Whether we put up the requester
** or not we must still account for the length of the replacement filename
** so that when we AllocMem() for the command we'll only get what we need.
*/
len = strlen(pgmname) + 1;
for(p = pgmname; *p; p++) {
if(*p == '@')
if(strncmp(p+1, local+1, locallen-1) == 0) {
if(!cmd_from_script || localfn[0] == '\0')
req("Local file name:", localfn, 1);
if(!localfn[0]) /* No filename specified */
return CMDFAIL;
if(file && !cmd_from_script)
strcpy(file, localfn);
len += strlen(localfn);
len -= locallen;
p += locallen;
} else if(strncmp(p+1, remote+1, remotelen-1) == 0) {
req("Remote file name:", remotefn, 1);
if(!remotefn[0]) /* No filename specified */
return CMDFAIL;
len += strlen(remotefn);
len -= remotelen;
p += remotelen;
}
} /* for p = pgmname */
/* Allocate space for the command and copy the command string to it
** replacing @LOCAL and @REMOTE with localfn and remotefn, respectively */
command = AllocMem((long)len, MEMF_PUBLIC | MEMF_CLEAR);
if(localfn[0] || remotefn[0]) {
for(p = pgmname, p1 = p; *p; p++) {
if(strncmp(p, local, locallen) == 0) {
strncat(command, p1, p - p1);
strcat(command, localfn);
p += locallen;
p1 = p;
} else if(strncmp(p, remote, remotelen) == 0) {
strncat(command, p1, p - p1);
strcat(command, remotefn);
p += remotelen;
p1 = p;
}
}
strcat(command, p1); /* Don't forget the tail of the command! */
} else strcpy(command, pgmname);
/* Close down VT100's use of the serial port */
if(!CheckIO((struct IORequest *)Read_Request))
AbortIO((struct IORequest *)Read_Request);
Wait (1L <<mySerPort->mp_SigBit);
WaitIO((struct IORequest *)Read_Request);
if(!p_shared)
CloseDevice((struct IORequest *)Read_Request);
Execute(command, 0L, 0L); /* Invoke the external xfer pgm */
FreeMem(command, (long)len);
if(!p_shared && OpenDevice(mysername,(LONG)p_unit,(struct IORequest *)Read_Request,NULL))
cleanup("Can't re-open Read device",0);
setparams();
if(p_xbeep)
cmd_beep(0L);
return CMDOK;
}