home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
GEMini Atari
/
GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso
/
files
/
telecomm
/
nhclb120
/
bsd_io.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-09-26
|
8KB
|
393 lines
/* OS- and machine-dependent stuff for 4.[23] BSD UNIX */
/*
FILE: UNIX.io.c
Routines:
ioinit()
iostop()
asy_init()
asy_stop()
asy_speed()
asy_output()
asy_recv()
dir()
Written or converted by Mikel Matthews, N9DVG
If you want to use the select code, define SELECT in the makefile or
in this file.
*/
#include <stdio.h>
#include <sys/types.h>
#include <sgtty.h>
#include <signal.h>
#include <sys/file.h>
#include <sys/dir.h>
#include <sys/time.h>
#include <memory.h>
#include <string.h>
#include "global.h"
#include "asy.h"
#include "mbuf.h"
#include "internet.h"
#include "iface.h"
#include "unix.h"
#include "cmdparse.h"
#ifndef B19200
#define B19200 EXTA
#endif
#ifndef B38400
#define B38400 EXTB
#endif
struct asy asy[ASY_MAX];
struct interface *ifaces;
struct sgttyb mysavetty, savecon;
int IORser[ASY_MAX];
/* Called at startup time to set up console I/O, memory heap */
ioinit()
{
struct sgttyb ttybuf;
extern void ioexit();
(void) signal(SIGHUP, ioexit);
(void) signal(SIGINT, ioexit);
(void) signal(SIGQUIT, ioexit);
(void) signal(SIGTERM, ioexit);
ioctl(0,TIOCGETP,&ttybuf);
savecon = ttybuf;
ttybuf.sg_flags &= ~ECHO;
ttybuf.sg_flags |= CBREAK;
ioctl(0,TIOCSETP,&ttybuf);
}
/* Called just before exiting to restore console state */
void
iostop()
{
setbuf(stdout,NULLCHAR);
while(ifaces != NULLIF){
if(ifaces->stop != NULLFP)
(*ifaces->stop)(ifaces->dev);
ifaces = ifaces->next;
}
ioctl(0,TIOCSETP,&savecon);
}
void
ioexit()
{
iostop();
exit(0);
}
/* Initialize asynch port "dev" */
/*ARGSUSED*/
int slipisopen;
/*ARGSUSED*/
int
asy_init(dev,arg1,arg2,bufsize)
int16 dev;
char *arg1,*arg2;
unsigned bufsize;
{
register struct asy *ap;
extern struct interface *ifaces;
struct sgttyb sgttyb;
ap = &asy[dev];
if (ap == NULL || dev >= nasy)
return(-1);
ap->tty = malloc((unsigned)(strlen(arg2)+1));
strcpy(ap->tty, arg2);
printf("asy_init: tty name = %s\n", ap->tty);
if ((IORser[dev] = open (ap->tty, (O_RDWR), 0)) < 0)
{
perror ("Could not open device IORser");
return (-1);
}
/*
* get the stty structure and save it
*/
if (ioctl (IORser[dev], TIOCGETP, &mysavetty) < 0)
{
perror ("ioctl failed on device");
return (-1);
}
/*
* copy over the structure
*/
sgttyb = mysavetty;
sgttyb.sg_flags = (RAW | ANYP | CRMOD);
sgttyb.sg_ispeed = sgttyb.sg_ospeed = B9600;
/*
* now set the modes and flags
*/
if (ioctl (IORser[dev], TIOCSETP, &sgttyb) < 0)
{
perror ("ioctl could not set parameters for IORser");
return (-1);
}
return 0;
}
/*ARGSUSED*/
int
asy_stop(iface)
struct interface *iface;
{
}
/* Set asynch line speed */
int
asy_speed(dev,speed)
int16 dev;
int speed;
{
struct sgttyb sgttyb;
if(speed == 0 || dev >= nasy)
return(-1);
asy[dev].speed = speed;
if (ioctl (IORser[dev], TIOCGETP, &sgttyb) < 0)
{
perror ("ioctl could not get parameters");
return (-1);
}
switch(speed)
{
case 0:
sgttyb.sg_ispeed = sgttyb.sg_ospeed = B0;
break;
case 50:
sgttyb.sg_ispeed = sgttyb.sg_ospeed = B50;
break;
case 75:
sgttyb.sg_ispeed = sgttyb.sg_ospeed = B75;
break;
case 110:
sgttyb.sg_ispeed = sgttyb.sg_ospeed = B110;
break;
case 134:
sgttyb.sg_ispeed = sgttyb.sg_ospeed = B134;
break;
case 150:
sgttyb.sg_ispeed = sgttyb.sg_ospeed = B150;
break;
case 200:
sgttyb.sg_ispeed = sgttyb.sg_ospeed = B200;
break;
case 300:
sgttyb.sg_ispeed = sgttyb.sg_ospeed = B300;
break;
case 600:
sgttyb.sg_ispeed = sgttyb.sg_ospeed = B600;
break;
case 1200:
sgttyb.sg_ispeed = sgttyb.sg_ospeed = B1200;
break;
case 1800:
sgttyb.sg_ispeed = sgttyb.sg_ospeed = B1800;
break;
case 2400:
sgttyb.sg_ispeed = sgttyb.sg_ospeed = B2400;
break;
case 4800:
sgttyb.sg_ispeed = sgttyb.sg_ospeed = B4800;
break;
case 9600:
sgttyb.sg_ispeed = sgttyb.sg_ospeed = B9600;
break;
case 19200:
sgttyb.sg_ispeed = sgttyb.sg_ospeed = B19200;
break;
case 38400:
sgttyb.sg_ispeed = sgttyb.sg_ospeed = B38400;
break;
default:
printf("asy_speed: Unknown speed (%d)\n", speed);
break;
}
if (ioctl (IORser[dev], TIOCSETP, &sgttyb) < 0) {
perror ("ioctl could not set parameters for IORser");
return (-1);
}
return(0);
}
/* Send a buffer to serial transmitter */
asy_output(dev,buf,cnt)
unsigned dev;
char *buf;
unsigned short cnt;
{
if(dev >= nasy)
return(-1);
if ( write(IORser[dev], buf, (int)cnt) < cnt)
{
perror("asy_output");
printf("asy_output: error in writing to device %d\n", dev);
return(-1);
}
return(0);
}
/* Receive characters from asynch line
* Returns count of characters read
*/
unsigned
asy_recv(dev,buf,cnt)
int dev;
char *buf;
unsigned cnt;
{
#define IOBUFLEN 256
unsigned tot;
long amount;
int r;
static struct {
char buf[IOBUFLEN];
char *data;
int cnt;
} IOBUF[ASY_MAX];
#ifdef SELECT
int mask;
int writemask;
int ok;
struct timeval timeout;
timeout.tv_sec = 0;
timeout.tv_usec = 35;
mask = (1<<IORser[dev]);
writemask = (1<<IORser[dev]);
ok = 0;
tot = 0;
ok = select(mask, &mask, 0, 0, &timeout);
if ( mask & (1<<IORser[dev]))
{
tot = read(IORser[dev], buf, cnt);
}
return (tot);
#else
tot = 0;
/* fill the read ahead buffer */
if(IOBUF[dev].cnt == 0) {
IOBUF[dev].data = IOBUF[dev].buf;
amount = 0;
if ((r = ioctl( IORser[dev], FIONREAD, &amount)) != -1) {
if ( amount > 0)
r = read(IORser[dev], buf, (int)cnt);
else
r = 0;
}
r = read(IORser[dev], IOBUF[dev].data, IOBUFLEN);
/* check the read */
if (r == -1) {
IOBUF[dev].cnt = 0; /* bad read */
perror("asy_recv");
printf("asy_recv: error in reading from device %d\n", dev);
return(0);
} else
IOBUF[dev].cnt = r;
}
r = 0; /* return count */
/* fetch what you need with no system call overhead */
if(IOBUF[dev].cnt > 0) {
if(cnt == 1) { /* single byte copy, do it here */
*buf = *IOBUF[dev].data++;
IOBUF[dev].cnt--;
r = 1;
} else { /* multi-byte copy, left memcpy do the work */
unsigned n = min(cnt, IOBUF[dev].cnt);
memcpy(buf, IOBUF[dev].data, n);
IOBUF[dev].cnt -= n;
IOBUF[dev].data += n;
r = n;
}
}
tot = (unsigned int) r;
return (tot);
#endif SELECT
}
/* Generate a directory listing by opening a pipe to /bin/ls.
* If full == 1, give a full listing; else return just a list of names.
*/
FILE *
dir(path,full)
char *path;
int full;
{
FILE *fp;
char cmd[1024];
if (path == NULLCHAR || path[0] == '\0')
path = ".";
if (full)
sprintf(cmd,"ls -l %s", path);
else
sprintf(cmd, "ls %s", path);
if ((fp = popen(cmd,"r")) == NULLFILE) {
perror("popen");
return NULLFILE;
}
return fp;
}
asy_ioctl(interface, argc, argv)
struct interface *interface;
int argc;
char *argv[];
{
if (argc < 1) {
printf("%d\r\n", asy[interface->dev].speed);
return 0;
}
return asy_speed(interface->dev, atoi(argv[0]));
}
int
OpenPty()
{
extern int errno;
int pty;
int letcnt=0, numcnt=0;
static char *letters = "pqrs",
*numbers = "0123456789abcdef";
static char master[] = "/dev/ptyXX";
static int letmax, nummax;
letmax=strlen(letters)-1, nummax=strlen(numbers)-1;
do {
master[strlen("/dev/pty")] = letters[letcnt];
master[strlen("/dev/ptyX")] = numbers[numcnt];
if (letcnt > letmax) {
return -1;
} else if (++numcnt > nummax) {
letcnt++;
numcnt = 0;
}
} while ((pty=open(master, O_RDWR)) < 0);
return(pty);
}