/* L C K T I O module */ char *ckxv = "tty I/O, 4LC (001), 01 Jul 85"; /* C-Kermit interrupt, terminal control & i/o functions for PC-DOS systems */ /* F. da Cruz, Columbia University Center for Computing Activities */ /* Modified for use with PC-DOS by: Jan A. van der Eijk, NUS Corp., July 1985 */ /* Copyright (C) 1985, Trustees of Columbia University in the City of New York. Permission is granted to any individual or institution to use, copy, or redistribute this software so long as it is not sold for profit, provided this copyright notice is retained. */ char *ckxsys = " PC-DOS > 2.0"; /* Variables available to outside world: dftty -- Pointer to default tty name string, like "/dev/tty". dfloc -- 0 if dftty is console, 1 if external line. dfprty -- Default parity dfflow -- Default flow control ckxech -- Flag for who echoes console typein: 1 - The program (system echo is turned off) 0 - The system (or front end, or terminal). functions that want to do their own echoing should check this flag before doing so. Functions for assigned communication line (either external or console tty): ttopen(ttname,local,mdmtyp) -- Open the named tty for exclusive access. ttclos() -- Close & reset the tty, releasing any access lock. ttpkt(speed,flow) -- Put the tty in packet mode and set the speed. ttvt(speed,flow) -- Put the tty in virtual terminal mode. or in DIALING or CONNECTED modem control state. ttinl(dest,max,timo,eol)-- Timed read line from the tty. ttinc(timo) -- Timed read character from tty. ttchk() -- See how many characters in tty input buffer. ttol(string,length) -- Write a string to the tty. ttoc(c) -- Write a character to the tty. ttflui() -- Flush tty input buffer. */ /* Functions for console terminal: conoc(c) -- Unbuffered output, one character to console. conol(s) -- Unbuffered output, null-terminated string to the console. conola(s) -- Unbuffered output, array of strings to the console. conxo(n,s) -- Unbuffered output, n characters to the console. conchk() -- Check if characters available at console (bsd 4.2). Check if escape char (^\) typed at console (System III/V). coninc(timo) -- Timed get a character from the console. Time functions msleep(m) -- Millisecond sleep ztime(&s) -- Return pointer to date/time string */ /* Includes */ #include "stdios.h" /* Unix Standard i/o */ #include #include "lckdeb.h" /* Formats for debug() */ #include "asic.h" /* Greenleaf header */ #include "timedate.h" /* Greenleaf header */ #define XONCODE 0 #define XOFFCODE 1 #define NULCODE 2 struct TIMEDATE *sgettime(); long int strtim; /* Declarations */ /* dftty is the device name of the default device for file transfer */ /* dfloc is 0 if dftty is the user's console terminal, 1 if an external line */ char *dftty = "COM1"; int dfloc = 1; int dfprty = 0; /* Parity (0 = none) */ int dfflow = 1; /* Xon/Xoff flow control */ int ckxech = 0; /* 0 if system normally echoes console characters, else 1 */ /* Declarations of variables global within this module */ static int xlocal = 0, /* Flag for tty local or remote */ ttyfd = -1; /* TTY file descriptor */ static char escchr; /* Escape or attn character */ static int conesc = 0; /* set to 1 if esc char (^\) typed */ char rbuf[4000],tbuf[4000]; /* receive and transmit buffer pointer */ int tlen,rlen; /* length of Xmit & Recv buffers */ /* C O N O C -- Output a character to the console terminal */ conoc(c) char c; { write(1,&c,1); } /* C O N X O -- Write x characters to the console terminal */ conxo(x,s) char *s; int x; { write(1,s,x); } /* C O N O L -- Write a line to the console terminal */ conol(s) char *s; { int len; len = strlen(s); write(1,s,len); } /* C O N O L A -- Write an array of lines to the console terminal */ conola(s) char *s[]; { int i; for (i=0 ; *s[i] ; i++) conol(s[i]); } /* C O N O L L -- Output a string followed by CRLF */ conoll(s) char *s; { conol(s); write(1,"\r\n",2); } /* C O N C H K -- Check to see if user did hit keyboard */ /* Return 1 if keyboard has been hit */ conchk() { if (asikbhit()) return(1); /* Greenleaf function to test keyboard hit */ return(0); } /* C O N I N C -- Get a character from the console */ /* argument; timo = number of seconds to wait for keyboard input */ /* return -1 if no keyboard input */ coninc(timo) int timo; { int n, time; time = 0; while ( !conchk() ) { if ( time++ > (timo*18 )) return(-1); timer(1); /* wait for 1 clock tick */ } /* Greenleaf function timer() */ n = getch(); /* Read a character. */ if (n > 0 ) return(n); /* Return the char if read */ } /* T T O P E N -- Open a tty for exclusive access. */ /* Returns 0 on success, -1 on failure. */ ttopen(ttname,lcl,modem) char *ttname; int lcl, modem; { int status; if (ttyfd > -1) return(0); /* If already open, ignore this call */ xlocal = lcl; /* Make available to other functions */ ttyfd = -1; if (strcmp(ttname,"COM1") == 0) ttyfd = 0; /* Check for valid name */ else if (strcmp(ttname,"COM2") == 0) ttyfd = 1; else return(-1); rlen = 4000; /* Allocate space for interrupt driven */ tlen = 4000; /* RS 232 I/O */ status=asisetup(ttyfd,ASINOUT,BINARYNONE,rbuf,(rlen-2),tbuf,(tlen-2)); if (status < 0) { ttyfd = -1; return(-1); /* Setup buffers, return -1 if error */ } asdtr(ttyfd,1); asrts(ttyfd,1); /* Greenleaf specific function to */ status=asistart(ttyfd,ASINOUT); /* Setup interrupt handlers */ if (status < 0) { ttyfd = -1; return(-1); /* return -1 if any error */ } status= asixrst(ttyfd); if (status < 0) return(-1); status=asiclear(ttyfd,ASIN); if (status < 0) return(-1); return(0); } /* T T C L O S -- Close the TTY */ ttclos() { if (ttyfd < 0) return; /* Wasn't open. */ asiquit(ttyfd); /* Reset modes, turn off interrupts. */ /* Using Greenleaf function */ ttyfd = -1; /* Mark it as closed. */ } /* T T O L -- Similar to "ttinl", but for writing. */ /* returns number of characters writen to Com port */ ttol(s,n) int n; char *s; { int x; if (ttyfd < 0) return(-1); /* Not open, return -1. */ ttflow(); /* check for XON */ if ((x = asiputb(ttyfd,s,n)) >= 0 ) x = n; /* All characters writen ?? */ debug(F111,"ttol",s,n); if (x < 0) debug(F101,"ttol failed","",x); return(x); } /* T T O C -- Output a character to the communication line */ /* Returns -1 if an error occured */ ttoc(c) char c; { if (ttyfd < 0) return(-1); /* Not open. */ ttflow(); return(asiputc(ttyfd,c)); } /* T T I N C -- Read a character from the communication line */ /* return the character if possible otherwise -1 */ /* Argument timo, timout in seconds */ ttinc(timo) int timo; { extern long int strtim; long int totsec(); int n,time; n = -1; time = 0; if (ttyfd < 0) return(-1); /* Not open. */ if (timo <= 0) { /* Untimed. */ while (carrier()) { if( (n = ttin())>= 0) break ; /* Wait for a character. */ } } else { if ((n = ttin()) < 0) { strtim = totsec(); while(carrier()) { if( (n = ttin()) >= 0) break ; /* Wait for a character. */ else if (toolong(timo)) return(-1); /* Timeout return -1 */ } } } return(n); } /* T T I N L -- Read a record (up to break character) from comm line. */ /* If no break character encountered within "max", return "max" characters, with disposition of any remaining characters undefined. Otherwise, return the characters that were read, including the break character, in "dest" and the number of characters read as the value of function, or 0 upon end of file, or -1 if an error occurred. Times out & returns error if not completed within "timo" sconds. */ ttinl(dest,maxnum,timo,eol) int maxnum,timo,eol; char *dest; { extern long int strtim; long int totsec(); int i, y, c; int time; time = 0; if (ttyfd < 0) return(-1); /* Not open. */ if (timo <= 0) { /* Untimed. */ for ( i = c = 0; (i < maxnum) && (c != eol) ; i++) { c = ttin(); if ( c > -1 ) dest[i] = c; /* Try to read. */ else dest[i] = 0; } return(i); } else { strtim = totsec(); /* Intialize timer */ for ( i = c = 0; (i < maxnum) && (c !=eol) ; i++) { while ( (c = ttin()) < 0 ) { /* Try to read */ /* Timed out yet */ if(toolong(timo) || !carrier()) return(i); } dest[i] = c; /* Store the character */ } } return(i); /* Return the count. */ } /* TTPKT -- Condition communication line for packect mode */ /* arguments - speed, communications baud rate flow, flow control used */ ttpkt (speed,flow) int speed, flow; { int ispeed,iflow; ispeed =speed; iflow = flow; return(ttvt(ispeed,iflow)); } /* TTVT -- Condition communication line for use as virtual terminal */ /* Returns -1 if Error */ /* Arguments : speed -- requested communication baud rate flow -- requested flow control */ ttvt (speed,flow) int speed, flow; { extern int parity; int s, status,ipar,dbits; s = ttsspd(speed); /* Check the requested speed */ if (s < 0 ) return(-1); ipar=0; dbits = 8; if (parity ) dbits = 7; /* Set up required parity */ if (parity =='o') ipar =1; else if (parity =='e') ipar =2; else if (parity =='m') ipar =3; else if (parity =='s') ipar =4; status = asiinit(ttyfd,s,ipar,1,dbits); /* Condition comm port using */ /* Greenleaf functions */ if ( status < 0 ) return(-1); if ( flow) { asirchk(ttyfd,XOFFCODE,XOFF,2); asirchk(ttyfd,XONCODE,XON,2); } else { asirchk(ttyfd,XOFFCODE,XOFF,0); asirchk(ttyfd,XONCODE,XON,0); } asirchk(ttyfd,NULCODE,0x00,2); asiignore(ttyfd,1,ON); asiignore(ttyfd,2,ON); return(0); } /* T T S S P D -- check for valid baud rates */ /* return the baud rate if valid otherwise -1 */ ttsspd(speed) { int s; if (speed <0) return(-1); switch (speed) { case 0: s = 0 ; break; case 300: s = 300 ; break; case 1200: s = 1200 ; break; case 2400: s = 2400 ; break; case 4800: s = 4800 ; break; case 9600: s = 9600 ; break; default: fprintf(stderr,"Unsupported line speed - %d\n",speed); fprintf(stderr,"Current speed not changed\n"); s = - 1; break; } return(s); } /* TTFLUI --- Flush tty input buffer */ ttflui() { if ( ttyfd < 0) return(-1); if ( !ttsome()) return(0); while (1) { while(ttsome()) asigetc(ttyfd); /* Greenleaf function */ if (ttinc(1) < 0) break; /* Wait one sec */ } return(0); } /* TTFLUO ---- Flush tty ouput buffer */ ttfluo() { if ( ttyfd > -1 ) asiclear(ttyfd,ASOUT); /* Greenleaf function */ } /* T T I N -- read one character for tty input buffer */ /* return the character if available otherwise -1 */ ttin() { char ch; int n; if ( ttyfd <0 ) return(-1); if (!ttsome()) return(-1); /* Anything there */ n = asigetc(ttyfd); /* Greenleaf function */ if ( n > 0 ) n &= 0377; return(n); } /* T T C H K check if character available in receive buffer */ ttchk() { int n; if ( ttyfd < 0 ) return(0); if ( !ttsome() ) return(0); return (TRUE); } /* T T S O M E * * Routine to return TRUE if receive buffer has character in it * * Returns: Serial port receive character register status */ int ttsome() { int status; ttflow(); /* Check for XOFF if enabled */ /* if receiver is not empty */ if ((asi_parms[ttyfd].flags&2)==0) return(TRUE); /* Greenleaf */ return(FALSE); } int ttflow() { if ( isrchk(ttyfd,XOFFCODE)) { /* check for XOFF */ asihold(ttyfd); /* Hold interrupts */ asiresume(ttyfd,ASIN); /* Resume receiving */ if ( !isrchk(ttyfd,XONCODE)) { strtim = totsec(); /* Intialize timer */ while ( TRUE) { if ( isrchk(ttyfd,XONCODE)) { /* wait for XON */ break; /* go for it again */ } if ( !carrier() || toolong(5)) break; /* don't wait toolong */ } } asihold(ttyfd); /* stop interrupts */ asiresume(ttyfd,ASINOUT); /* resume them */ if ( isrchk(ttyfd,XOFFCODE)) { asirchk(ttyfd,XOFFCODE,XOFF,4); /* Clear XOFF flag */ } if ( isrchk(ttyfd,XONCODE)) { asirchk(ttyfd,XONCODE,XON,4); /* Clear XON flag */ } /* printf("xon/xoff detected \n"); */ } } /* C A R R I E R * * check for existance of modem carrier signal * * carrier() * * Returns: 1 if carrier present; else returns 0 */ int carrier() { extern int cdetect; int status; if ( !cdetect) return(TRUE); /* Carrier not required */ status = asistat(ttyfd); /* Greenleaf function */ if (status & 0x0080) return(TRUE); /* check rec line sig detect */ return(FALSE); /* return FALSE if no carrier */ } /* S L E E P wait for m seconds */ sleep(m) int m; { extern long int strtim, totsec(); strtim = totsec(); while (1) { if ( toolong(m) ) break; } } /* T I C K S -- Returns total number of clock ticks since midnight */ long int ticks() { struct REGS regs; union { int s[2]; long ll;} secs ; regs.ax = 0; secs.ll = 0L; int86(0x1A,®s,®s); secs.s[0] = regs.dx; /* High count */ secs.s[1] = regs.cx; /* Low count */ return(secs.ll); } /* T O T S E C -- Time since midnight in seconds */ long int totsec() { long int ticks(), secnds; secnds = (10l * ticks() ) / 182; return(secnds); } /* T O O L O N G -- Timeout for user input with tout in seconds */ toolong(tout) int tout; { extern long int strtim, totsec(); long int nowtim; nowtim = totsec(); if (nowtim < strtim) nowtim += 86400L; if ( (nowtim - strtim) < tout) return(0); else return(1); } /* Z T I M E -- Return date/time string */ ztime(s) char **s; { struct TIMEDATE *ptd; ptd = sgettime(6); /* get the time from system */ *s= ptd->dateline; /* Using Greenleaf function */ }