home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
GEMini Atari
/
GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso
/
files
/
mint
/
tip
/
tip.c
next >
Wrap
C/C++ Source or Header
|
1990-10-10
|
7KB
|
337 lines
/*
* Stripped down tip clone -- Howard Chu, 10-10-90
*
* This is a very simple terminal program intended for use with MiNT
* (and MGR...). I tried to model it on the BSD 4.3 version of tip,
* but got impatient and thus omitted a number of features. Still,
* this is useful enough and easy enough to use... You may copy and
* distribute this program freely as long as you keep all files intact
* (meaning this source file and the accompanying doc and executable
* file). You are also welcome to modify the program to suit your own
* needs, but leave this notice intact. I would also appreciate it
* if you send me any improvements you may make.
* hyc@math.lsa.umich.edu
*/
#include <osbind.h>
#include <xbios.h>
#define Finstat(a) gemdos(0x105,a)
#define Foutstat(a) gemdos(0x106,a)
#define Fgetchar(a,b) gemdos(0x107,a,b)
#define Fputchar(a,b,c) gemdos(0x108,a,b,c)
/* The previous 4 defines don't actually get used. So it goes...
they're up there because I thought about using them, and I haven't
incorporated them into my MWC library yet. */
#define Pgetpid() gemdos(0x10b)
#define Pkill(a,b) gemdos(0x111,a,b)
char iobuf[8192];
struct iorec *rec, oldirec, oldorec;
char shell[128], esc='~';
int par=0; /* none, odd, even - 0, 1, 2 */
int baud=1; /* see baud table 1=9600 */
int echo=0;
int flow=0; /* none, xon/xoff, rts/cts */
int ucr, rsr, tsr, scr;
char *bauds[]={"19200","9600","4800","3600","2400","2000","1800","1200",
"600","300","200","150","134","110","75","50"};
/* Set up a large I/O buffer for the RS232 port, and set initial
speed, flow control, and parity. */
void rs232init(){
register long m68901reg;
rec=Iorec(0);
oldirec=*rec;
rec->io_buff=iobuf;
rec->io_bufsiz = 4096;
rec->io_head = 0;
rec->io_tail = 0;
rec->io_low = 100;
rec->io_high = 4000;
rec++;
oldorec=*rec;
rec->io_buff=&iobuf[4096];
rec->io_bufsiz = 4096;
rec->io_head=0;
rec->io_tail=0;
rec->io_low=100;
rec->io_high=4000;
m68901reg=Rsconf(baud,0,-1,-1,-1,-1);
scr=m68901reg&0xff;
m68901reg>>=8;
tsr=m68901reg&0xff;
m68901reg>>=8;
rsr=m68901reg&0xff;
m68901reg>>=8;
ucr=m68901reg&0xf8;
Rsconf(-1,-1,ucr,-1,-1,-1); /* turn off parity */
}
int getbaud(rate)
char *rate;
{
register int i;
for (i=0;i<16;i++)
if (!strcmp(rate,bauds[i]))
break;
if (i==16) {
Cconws(rate);
Cconws(": unknown baudrate value\r\n");
i=(-1);
}
return(i);
}
main(argc,argv)
int argc; char *argv[];
{
register int c;
register int cr=0;
register int cmd=0;
char *buf, *getenv();
void docommand();
switch(argc){
case 1:
break;
case 2:
c=getbaud(argv[1]);
if (c>=0)
baud=c;
break;
default:
Cconws("Use: tip [speed]\r\n");
break;
}
rs232init();
buf=getenv("SHELL");
if (buf)
strcpy(shell,buf);
for(;;) {
if (Bconstat(1)) {
c = Bconin(1);
Bconout(2,c);
}
if (Cconis()) {
c = Crawcin();
if (cmd) {
cmd=0;
docommand(c);
cr=1;
continue;
} else if (cr && c == esc) {
cmd = 1;
cr = 0;
continue;
} else if (c == '\r')
cr = 1;
else cr = 0;
if (Bcostat(1))
Bconout(1,c);
if (echo)
Bconout(2,c);
}
}
}
void docommand(c)
int c;
{
int args=0;
void dosetvar(), dobreak();
char *strchr();
if (strchr("!#.?s",c)||(c==4)||(c==26))
Cconout(esc);
switch (c) {
case '!':
if (shell[0]) {
Cconws("\r\n[sh]\r\n");
Pexec(0,shell,&args,0L);
} else {
Cconws("No shell.\r\n");
}
break;
#if 0 /* Not implemented. Too much hassle. */
case '|':
Cconws("Local command? ");
Cconws("List command for remote system? ");
case '$':
/* Pipe local command to remote */
case 'C':
Cconws("Local command? ");
#endif
case '.':
case 4:
Cconws("\r\n[EOT]\r\n");
*rec=oldorec; /* reset to old I/O rec stuff, then exit */
rec--;
*rec=oldirec;
exit(0);
case 26: /* Send a STOP to this process */
{register int i = Pgetpid();
Pkill(i,17);
}
break;
case 's':
dosetvar();
break;
case '#':
dobreak();
break;
case '?':
Cconws("\r\n ~! shell\r\n");
Cconws(" ~. exit from tip\r\n");
Cconws(" ~^D exit from tip\r\n");
Cconws(" ~^Z suspend tip\r\n");
Cconws(" ~s set variable\r\n");
Cconws(" ~# send break\r\n");
Cconws(" ~? get this summary\r\n");
break;
default:
Bconout(1,c);
break;
}
}
void dobreak()
{
#define Fselect(a,b,c,d) gemdos(0x11d,a,b,c,d)
tsr |= 0x08;
Rsconf(-1,-1,-1,-1,tsr,-1);
Fselect(300,0L,0L,0L); /* sleep 300 milliseconds */
tsr &=0xf7;
Rsconf(-1,-1,-1,-1,tsr,-1);
}
char *vars[]={"all","baudrate","flowcontrol","localecho","parity","escape","shell"};
char *flows[]={"none","xon/xoff","rts/cts"};
char *pars[]={"none","odd","even"};
void dosetvar()
{
register int i, j;
char *strpbrk();
unsigned char buf[130];
register char *ptr;
Cconws("[set] ");
buf[0]=128;
Cconrs(buf);
Cconout('\n');
i=buf[1];
if (i==0)
return;
buf[i+2]='\0';
ptr=strpbrk(&buf[2]," = ");
if (ptr)
i=ptr-&buf[2];
else
i=buf[1];
for (j=0;j<7;j++)
if(!strncmp(&buf[2],vars[j],i))
break;
if (j==7) {
Cconws(&buf[2]);
Cconws(": unknown variable\r\n");
return;
}
if (j&&!ptr) {
Cconws("\r\nno value supplied\r\n");
return;
}
ptr++;
switch(j) {
case 0:
Cconws("baudrate=");
Cconws(bauds[baud]);
Cconws("\r\nflowcontrol=");
Cconws(flows[flow]);
Cconws("\r\nlocalecho=");
ptr=echo ? "on":"off";
Cconws(ptr);
Cconws("\r\nparity=");
Cconws(pars[par]);
Cconws("\r\nescape=");
Cconout(esc);
Cconws("\r\nshell=");
Cconws(shell);
Cconws("\r\n");
break;
case 1:
i=getbaud(ptr);
if (i>=0) {
baud=i;
Rsconf(i,-1,-1,-1,-1,-1);
}
break;
case 2:
j=buf[1]-i-1;
for (i=0;i<4;i++)
if (!strncmp(ptr,flows[i],j))
break;
if (i==4) {
Cconws(ptr);
Cconws(": unknown flowcontrol value\r\n");
return;
}
flow=i;
Rsconf(-1,i,-1,-1,-1,-1);
break;
case 3:
echo=strcmp(ptr,"on") ? 0 : 1;
break;
case 4:
j=buf[1]-i-1;
for (i=0;i<3;i++)
if (!strncmp(ptr,pars[i],j))
break;
if (i==3) {
Cconws(ptr);
Cconws(": unknown parity value\r\n");
return;
}
par=i;
ucr &=0x98;
if (i) {
ucr |= i|0x24; /* set 7 bits, parity on */
}
Rsconf(-1,-1,ucr,-1,-1,-1);
break;
case 5:
esc=*ptr;
break;
case 6:
strcpy(shell,ptr);
break;
}
}