📄 ckutio.c
字号:
/* Got the line, now set the desired value for local. */
if (*lcl < 0) *lcl = xlocal;
/* Some special stuff for v7... */
#ifdef V7
if (kmem[TTY] < 0) { /* If open, then skip this. */
qaddr[TTY] = initrawq(ttyfd); /* Init the queue. */
if ((kmem[TTY] = open("/dev/kmem", 0)) < 0) {
fprintf(stderr, "Can't read /dev/kmem in ttopen.\n");
perror("/dev/kmem");
exit(1);
}
}
#endif V7
/* Request exclusive access on systems that allow it. */
#ifndef XENIX
/* Xenix exclusive access prevents open(close(...)) from working... */
#ifdef TIOCEXCL
if (ioctl(ttyfd,TIOCEXCL, NULL) < 0)
fprintf(stderr,"Warning, problem getting exclusive access\n");
#endif
#endif
/* Get tty device settings */
#ifndef UXIII
gtty(ttyfd,&ttold); /* Get sgtty info */
gtty(ttyfd,&ttraw); /* And a copy of it for packets*/
gtty(ttyfd,&tttvt); /* And one for virtual tty service */
#else
ioctl(ttyfd,TCGETA,&ttold); /* Same deal for Sys III, Sys V */
ioctl(ttyfd,TCGETA,&ttraw);
ioctl(ttyfd,TCGETA,&tttvt);
#endif
debug(F101,"ttopen, ttyfd","",ttyfd);
debug(F101," lcl","",*lcl);
debug(F111," lock file",flfnam,lkf);
return(0);
}
/* T T C L O S -- Close the TTY, releasing any lock. */
ttclos() {
if (ttyfd < 0) return(0); /* Wasn't open. */
if (xlocal) {
if (tthang()) /* Hang up phone line */
fprintf(stderr,"Warning, problem hanging up the phone\n");
if (ttunlck()) /* Release uucp-style lock */
fprintf(stderr,"Warning, problem releasing lock\n");
}
ttres(); /* Reset modes. */
/* Relinquish exclusive access if we might have had it... */
#ifndef XENIX
#ifdef TIOCEXCL
#ifdef TIOCNXCL
if (ioctl(ttyfd, TIOCNXCL, NULL) < 0)
fprintf(stderr,"Warning, problem relinquishing exclusive access\n");
#endif
#endif
#endif
close(ttyfd); /* Close it. */
ttyfd = -1; /* Mark it as closed. */
return(0);
}
/* T T H A N G -- Hangup phone line */
tthang() {
#ifdef UXIII
unsigned short ttc_save;
#endif
if (ttyfd < 0) return(0); /* Not open. */
#ifdef ANYBSD
ioctl(ttyfd,TIOCCDTR,0); /* Clear DTR */
msleep(500); /* Let things settle */
ioctl(ttyfd,TIOCSDTR,0); /* Restore DTR */
#endif
#ifdef UXIII
ttc_save = ttraw.c_cflag;
ttraw.c_cflag &= ~CBAUD; /* swa: set baud rate to 0 to hangup */
if (ioctl(ttyfd,TCSETAF,&ttraw) < 0) return(-1); /* do it */
msleep(100); /* let things settle */
ttraw.c_cflag = ttc_save;
#ifndef XENIX /* xenix cannot do close/open when carrier drops */
/* following corrects a PC/IX defficiency */
ttc_save = fcntl(ttyfd,F_GETFL,0);
close(ttyfd); /* close/reopen file descriptor */
if ((ttyfd = open(ttnmsv, ttc_save)) < 0) return(-1);
#endif
if (ioctl(ttyfd,TCSETAF,&ttraw) < 0) return(-1); /* un-do it */
#endif
return (0);
}
/* T T R E S -- Restore terminal to "normal" mode. */
ttres() { /* Restore the tty to normal. */
if (ttyfd < 0) return(-1); /* Not open. */
#ifndef UXIII /* except for sIII, */
sleep(1); /* Wait for pending i/o to finish. */
#endif /* (sIII does wait in ioctls) */
#ifdef KERLD
if (kerld) ioctl(ttyfd,TIOCSETD,&oldld); /* Restore old line discipline. */
#endif
#ifdef UXIII
if (ioctl(ttyfd,TCSETAW,&ttold) < 0) return(-1); /* restore termio stuff */
#else
if (stty(ttyfd,&ttold) < 0) return(-1); /* Restore sgtty stuff */
#endif
#ifdef KERLD
if (kerld) ioctl(ttyfd,TIOCSETC,&oldc); /* Restore old special chars. */
#endif
return(0);
}
/* Exclusive uucp file locking control */
/*
by H. Fischer, creative non-Bell coding !
copyright rights for lock modules assigned to Columbia University
*/
static char *
xxlast(s,c) char *s; char c; { /* Equivalent to strrchr() */
int i;
for (i = strlen(s); i > 0; i--)
if ( s[i-1] == c ) return( s + (i - 1) );
return(NULL);
}
static
look4lk(ttname) char *ttname; {
extern char *strcat(), *strcpy();
char *device, *devname;
char lockfil[50]; /* Max length for lock file name */
#ifdef ISIII
char *lockdir = "/etc/locks";
#else
#ifdef ATT3BX
char *lockdir = "/usr/spool/locks";
#else
char *lockdir = "/usr/spool/uucp";
#endif
#endif
device = ( (devname=xxlast(ttname,'/')) != NULL ? devname+1 : ttname);
#ifdef ISIII
(void) strcpy( lockfil, device );
#else
strcat( strcpy( lockfil, "LCK.." ), device );
#endif
if (access( lockdir, 04 ) < 0) { /* read access denied on lock dir */
fprintf(stderr,"Warning, read access to lock directory denied\n");
return( 1 ); /* cannot check or set lock file */
}
strcat(strcat(strcpy(flfnam,lockdir),"/"), lockfil);
debug(F110,"look4lk",flfnam,0);
if ( ! access( flfnam, 00 ) ) { /* print out lock file entry */
char lckcmd[40] ;
strcat( strcpy(lckcmd, "ls -l ") , flfnam);
system(lckcmd);
if (access(flfnam,02) == 0)
printf("(You may type \"! rm %s\" to remove this file)\n",flfnam);
return( -1 );
}
if ( access( lockdir, 02 ) < 0 ) { /* lock file cannot be written */
fprintf(stderr,"Warning, write access to lock directory denied\n");
return( 1 );
}
return( 0 ); /* okay to go ahead and lock */
}
/* T T L O C K */
static
ttlock(ttyfd) char *ttyfd; { /* lock uucp if possible */
#ifdef ATT3BX
FILE *lck_fild;
#endif
int lck_fil, l4l;
int pid_buf = getpid(); /* pid to save in lock file */
hasLock = 0; /* not locked yet */
l4l = look4lk(ttyfd);
if (l4l < 0) return (-1); /* already locked */
if (l4l == 1) return (0); /* can't read/write lock directory */
lck_fil = creat(flfnam, 0444); /* create lock file ... */
if (lck_fil < 0) return (-1); /* create of lockfile failed */
/* creat leaves file handle open for writing -- hf */
#ifdef ATT3BX
fprintf((lck_fild = fdopen(lck_fil, "w")), "%10d\n", pid_buf);
fflush(lck_fild);
#else
write (lck_fil, &pid_buf, sizeof(pid_buf) ); /* uucp expects int in file */
#endif
close (lck_fil);
hasLock = 1; /* now is locked */
return(0);
}
/* T T U N L O C K */
static
ttunlck() { /* kill uucp lock if possible */
if (hasLock) return( unlink( flfnam ) );
}
/* T T P K T -- Condition the communication line for packets. */
/* or for modem dialing */
#define DIALING 4 /* flags (via flow) for modem handling */
#define CONNECT 5
/* If called with speed > -1, also set the speed. */
/* Returns 0 on success, -1 on failure. */
ttpkt(speed,flow) int speed, flow; {
int s;
if (ttyfd < 0) return(-1); /* Not open. */
#ifdef KERLD
/* Note, KERLD ignores the TANDEM, ECHO, and CRMOD bits */
if (kerld) {
ioctl(ttyfd,TIOCGETD,&oldld); /* Get line discipline */
ioctl(ttyfd,TIOCGETC,&oldc); /* Get special chars */
newc = oldc; /* Copy special chars */
newc.t_brkc = '\r'; /* Set CR to be break character */
if(ioctl(ttyfd,TIOCSETC,&newc) < 0) return(-1);
}
#endif
s = ttsspd(speed); /* Check the speed */
#ifndef UXIII
if (flow == 1) ttraw.sg_flags |= TANDEM; /* Use XON/XOFF if selected */
if (flow == 0) ttraw.sg_flags &= ~TANDEM;
ttraw.sg_flags |= RAW; /* Go into raw mode */
ttraw.sg_flags &= ~(ECHO|CRMOD); /* Use CR for break character */
#ifdef TOWER1
ttraw.sg_flags &= ~ANYP; /* Must tell Tower no parityr */
#endif
if (s > -1) ttraw.sg_ispeed = ttraw.sg_ospeed = s; /* Do the speed */
if (stty(ttyfd,&ttraw) < 0) return(-1); /* Set the new modes. */
#ifdef MYREAD
#ifdef BSD4
/* Try to make reads nonblocking */
if (kerld == 0) {
if (fcntl(ttyfd,F_SETFL,fcntl(ttyfd,F_GETFL,0) & FNDELAY) == -1)
return(-1);
else return(0);
}
#endif
#endif
#endif
#ifdef UXIII
if (flow == 1) ttraw.c_iflag |= (IXON|IXOFF);
if (flow == 0) ttraw.c_iflag &= ~(IXON|IXOFF);
if (flow == DIALING) ttraw.c_cflag |= CLOCAL|HUPCL;
if (flow == CONNECT) ttraw.c_cflag &= ~CLOCAL;
ttraw.c_lflag &= ~(ICANON|ECHO);
ttraw.c_lflag |= ISIG; /* do check for interrupt */
ttraw.c_iflag |= (BRKINT|IGNPAR);
ttraw.c_iflag &= ~(IGNBRK|INLCR|IGNCR|ICRNL|IUCLC|INPCK|ISTRIP|IXANY);
ttraw.c_oflag &= ~OPOST;
ttraw.c_cflag &= ~(CSIZE|PARENB);
ttraw.c_cflag |= (CS8|CREAD);
ttraw.c_cc[4] = 1;
ttraw.c_cc[5] = 0;
if (s > -1) ttraw.c_cflag &= ~CBAUD, ttraw.c_cflag |= s; /* set speed */
if (ioctl(ttyfd,TCSETAW,&ttraw) < 0) return(-1); /* set new modes . */
if (flow == DIALING) {
if (fcntl(ttyfd,F_SETFL, fcntl(ttyfd, F_GETFL, 0) & ~O_NDELAY) < 0 )
return(-1);
close( open(ttnmsv,2) ); /* magic to force mode change!!! */
}
#endif
#ifdef KERLD
if (kerld) {
if (ioctl(ttyfd,TIOCSETD,&ld) < 0)
return(-1); /* Set line discpline. */
}
#endif
ttflui(); /* Flush any pending input */
return(0);
}
/* T T V T -- Condition communication line for use as virtual terminal */
ttvt(speed,flow) int speed, flow; {
int s;
if (ttyfd < 0) return(-1); /* Not open. */
s = ttsspd(speed); /* Check the speed */
#ifndef UXIII
if (flow == 1) tttvt.sg_flags |= TANDEM; /* XON/XOFF if selected */
if (flow == 0) tttvt.sg_flags &= ~TANDEM;
tttvt.sg_flags |= RAW; /* Raw mode */
#ifdef TOWER1
tttvt.sg_flags &= ~(ECHO|ANYP); /* No echo or system III ??? parity */
#else
tttvt.sg_flags &= ~ECHO; /* No echo */
#endif
if (s > -1) tttvt.sg_ispeed = tttvt.sg_ospeed = s; /* Do the speed */
if (stty(ttyfd,&tttvt) < 0) return(-1);
#ifdef MYREAD
#ifdef BSD4
/* Make reads nonblocking */
if (kerld == 0) {
if (fcntl(ttyfd,F_SETFL,fcntl(ttyfd,F_GETFL,0) & FNDELAY) == -1)
return(-1);
else return(0);
}
#endif
#endif
#else
if (flow == 1) tttvt.c_iflag |= (IXON|IXOFF);
if (flow == 0) tttvt.c_iflag &= ~(IXON|IXOFF);
if (flow == DIALING) tttvt.c_cflag |= CLOCAL|HUPCL;
if (flow == CONNECT) tttvt.c_cflag &= ~CLOCAL;
tttvt.c_lflag &= ~(ISIG|ICANON|ECHO);
tttvt.c_iflag |= (IGNBRK|IGNPAR);
tttvt.c_iflag &= ~(INLCR|IGNCR|ICRNL|IUCLC|BRKINT|INPCK|ISTRIP|IXANY);
tttvt.c_oflag &= ~OPOST;
tttvt.c_cflag &= ~(CSIZE|PARENB);
tttvt.c_cflag |= (CS8|CREAD);
tttvt.c_cc[4] = 1;
tttvt.c_cc[5] = 0;
if (s > -1) tttvt.c_cflag &= ~CBAUD, tttvt.c_cflag |= s; /* set speed */
if (ioctl(ttyfd,TCSETAW,&tttvt) < 0) return(-1); /* set new modes . */
if (flow == DIALING) {
if (fcntl(ttyfd,F_SETFL, fcntl(ttyfd, F_GETFL, 0) & ~O_NDELAY) < 0 )
return(-1);
close( open(ttnmsv,2) ); /* magic to force mode change!!! */
}
return(0);
#endif
}
/* T T S S P D -- Return the internal baud rate code for 'speed'. */
ttsspd(speed) {
int s, spdok;
if (speed < 0) return(-1);
spdok = 1; /* Assume arg ok */
switch (speed) {
case 0: s = B0; break; /* Just the common ones. */
case 110: s = B110; break; /* The others from ttydev.h */
case 150: s = B150; break; /* could also be included if */
case 300: s = B300; break; /* necessary... */
case 600: s = B600; break;
case 1200: s = B1200; break;
case 1800: s = B1800; break;
case 2400: s = B2400; break;
case 4800: s = B4800; break;
case 9600: s = B9600; break;
#ifdef PLEXUS
case 19200: s = EXTA; break;
#endif
default:
spdok = 0;
fprintf(stderr,"Unsupported line speed - %d\n",speed);
fprintf(stderr,"Current speed not changed\n");
break;
}
if (spdok) return(s); else return(-1);
}
/* T T F L U I -- Flush tty input buffer */
ttflui() {
#ifndef UXIII
long n;
#endif
if (ttyfd < 0) return(-1); /* Not open. */
ungotn = -1; /* Initialize myread() stuff */
inbufc = 0;
#ifdef UXIII
if (ioctl(ttyfd,TCFLSH,0) < 0) perror("flush failed");
#else
#ifdef TIOCFLUSH
#ifdef ANYBSD
n = FREAD; /* Specify read queue */
if (ioctl(ttyfd,TIOCFLUSH,&n) < 0) perror("flush failed");
#else
if (ioctl(ttyfd,TIOCFLUSH,0) < 0) perror("flush failed");
#endif
#endif
#endif
return(0);
}
/* Interrupt Functions */
/* Timeout handler for communication line input functions */
timerh() {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -