home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Columbia Kermit
/
kermit.zip
/
pub
/
uniflex
/
ufio.c
< prev
next >
Wrap
C/C++ Source or Header
|
2020-01-01
|
8KB
|
290 lines
#include "ufk.h"
#include <sgtty.h>
#include <signal.h>
#include <setjmp.h>
#include <stat.h>
#include <modes.h>
#define R_CHUNK_SIZE 50 /* Number of characters to read at a time */
char lastchar,
cons_set;
jmp_buf env, popenv;
struct sgttyb old_mode, new_mode,
old_c_mode, new_c_mode;
/*
* Open communication port
*/
open_port(setcons,check_only)
char setcons,
check_only;
{
int opnint();
char tmpprt[20];
struct stat buf;
sprintf(tmpprt,"/dev/tty%02d",ttyslot()); /* Get controlling terminal */
if ((strcmp(tty_descr,"Remote") == 0) ||
(strcmp(tty_descr,tmpprt) == 0))
remote = TRUE;
else
{
remote = FALSE;
strcpy(tmpprt,tty_descr);
}
if (stat(tmpprt,&buf))
return (NULL); /* unable to obtain status */
if ((buf.st_mode & S_IFMT) != S_IFCHR)
return (NULL); /* Not a character device */
if (!check_only) /* Real open */
{
if (!port_open || remote)
{
if (setjmp(popenv))
return (NULL); /* Interrupted during open */
signal(SIGINT,opnint); /* Catch ctrl-C interrupt */
ttyfd = open(tmpprt,2);
if (ttyfd == ERROR)
{
signal(SIGINT,SIG_DFL); /* Default kbd interrupt */
return(NULL);
}
signal(SIGINT,SIG_IGN); /* Ignore kbd interrupt */
gtty(ttyfd,&old_mode); /* Get old characteristics */
gtty(ttyfd,&new_mode); /* Get copy */
new_mode.sg_speed &= ~0x1c; /* Mask old config bits */
new_mode.sg_speed |= (config << 2); /* Set new configuration */
new_mode.sg_flag |= RAW; /* Set raw mode */
new_mode.sg_flag &= ~(ECHO|CRMOD); /* No echo, no auto lf */
stty(ttyfd,&new_mode); /* Set new parameters */
port_open = TRUE; /* Flag it's open now */
}
cons_set = FALSE;
if (!remote)
{
if (call_baud) /* Only the first time ... */
{
baud(tmpprt,speed); /* set baudrate */
call_baud = FALSE; /* Don't set it anymore */
}
if (setcons && !nooutput)
{
cons_set = TRUE; /* Console set as well */
gtty(0,&old_c_mode); /* Get console characteristics */
gtty(0,&new_c_mode); /* Get copy */
new_c_mode.sg_flag |= RAW; /* Set raw mode */
new_c_mode.sg_flag &= ~(ECHO|CRMOD); /* No echo, no auto lf */
stty(0,&new_c_mode); /* Set new console parameters */
}
}
purgeline(ttyfd); /* eat old input */
aborted = FALSE;
port_open = TRUE; /* Mark port open */
}
return (TRUE); /* valid port found */
}
opnint()
{
longjmp(popenv,TRUE); /* timeout during port open */
}
/*
* Close communication port
*/
close_port(scrflag,real_close)
int scrflag,
real_close;
{
if (!remote && cons_set)
stty(0,&old_c_mode);
if ((real_close || remote) && port_open)
{
stty(ttyfd,&old_mode);
close(ttyfd);
signal(SIGINT,SIG_DFL); /* Restore keyboard interrupt */
port_open = FALSE;
}
if (scrflag)
posit(0,23);
curs_on(); /* Re-enable cursor */
}
/*
* read data from port
*/
kread(dev,data,count)
int dev,count;
char *data;
{
int i, n, p, left,
clkint();
i = 0; /* Timeout counter */
if (setjmp(env))
if ((aborted && !(sflg || rflg)) || ((i += 2) >= timint))
/* Return TIMOUT if aborted during inactive period, or after real timeout */
return TIMEOUT; /* Limit reached, timeout */
signal(SIGALRM,clkint); /* Setup timeout catch */
/* Due to the accuracy of the 'alarm' call one second can cause problems */
alarm(2); /* Set two seconds timeout */
read(dev,data,1); /* Try to get first character */
alarm(0); /* Got one character, reset timeout */
if (count > 1) /* If more to do ... */
{
left = count - 1; /* What's left to do */
n = 1; /* Starting offset in data array */
while (left > 0) /* Until all has been done */
{
p = (left > R_CHUNK_SIZE ? R_CHUNK_SIZE : left); /* Read in chunks */
/* of R_CHUNK_SIZE characters or less */
i = timint; /* so we will return at timeout */
alarm(timint); /* Set selected timeout */
read(dev,&data[n],p); /* Try to get the rest of the data */
alarm(0); /* Got the rest, reset timeout */
left -= R_CHUNK_SIZE; /* Count down */
n += R_CHUNK_SIZE; /* Adjust next array index */
}
}
lastchar = data[count-1]; /* get last entered character */
if (rflg || sflg)
chr_rec += count; /* count chars if sending or receiving */
if (!remote && !nooutput)
check_abort(); /* check for abort or toggle debug */
return NULL; /* normal termination */
}
clkint()
{
check_abort(); /* check for user abort after timeout */
longjmp(env,TRUE);
}
/*
* write characters to port
*/
kwrite(dev,data,count)
int dev,count;
char *data;
{
if (count == 0) /* determine count if not given */
count = strlen(data);
write(dev,data,count);
if (rflg || sflg)
chr_sent += count; /* count chars if sending or receiving */
}
/*
* check for user abort
*/
check_abort()
{
char c;
struct sgttyb mode;
if (!cflg) /* only when connect is inactive */
{
gtty(0,&mode);
if (mode.sg_speed & INCHR) /* if character available */
read(0,&c,1);
else
{
if (remote)
c = lastchar; /* Only check typed character */
else /* if remote */
c = 0;
}
c &= 0177; /* strip parity */
lastchar = 0;
if ((c == ABORTX) || (c == ABORTZ))
{ /* and if it's the abort char */
aborted = c; /* flag abort */
return c;
}
else if (c == TOGDBG) /* Toggle debug ? */
{
if (debug)
{
debug = FALSE; /* Switch off debug */
if (dbgfil != ERROR)
{
fclose(dbgfil); /* Close debug output file if open */
dbgfil = ERROR;
}
}
else
debug = TRUE; /* Switch on debug */
set_frame(); /* Make new display frame */
disp_params(); /* With the current parameters */
}
else if (c == PANIC)
{
for (c = 0; c < 3; c++)
beep(); /* Ring the bell three times */
kerm_exit(); /* Get the hell out of here */
}
else if (dstop != NULL && c == dstop) /* Wait.... */
{
do
read(0,&c,1);
while ((c & 0177) != dstart); /* Wait for start */
}
}
return NULL; /* no abort */
}
/*
* purge a line of input data
*/
purgeline(port)
int port;
{
struct sgttyb mode;
char c;
while(TRUE)
{
gtty(port,&mode);
if (mode.sg_speed & INCHR) /* eat characters */
read(port,&c,1);
else
break;
}
}
/*
send break
*/
send_break(port)
int port; /* Not used */
{
do_break(tty_descr); /* Use fixed string descriptor */
}
kdelay(time)
int time;
{
int timdummy();
if (time != 0)
{
signal(SIGALRM,timdummy);
alarm(time);
pause();
}
}
timdummy()
{
}