char *ckxv = "NCR-VRX tty I/O, 4E, 01 June 90"; /* C K V T I O */ /********************************************************************** * * * IVS / MCS-Kermit REL 2 * * source code * * * * Change History: * * * * 1. Modify C-Kermit(4E) source code to * * produce new module for MCS/IVS-Kermit * * ORIGINAL RELEASE * * June 22, 1990 * * * * * ***********************************************************************/ /* C-Kermit interrupt, terminal control & i/o functions for NCR-VRX systems */ /* Author: Frank da Cruz (SY.FDC@CU20B), Columbia University Center for Computing Activities, January 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. */ /* Includes for all NCR-VRXes (conditional includes come later) */ #include /* Types */ #include /* Character types */ #include /* NCR-VRX Standard i/o */ #include /* Interrupts */ #include /* Longjumps */ #include "ckcdeb.h" /* Typedefs, formats for debug() */ #include #include "ckuusr.h" #include /* Clock info (for break generation) */ #ifdef MCS_FLAG #include "mcs.h" #define read mcs_read #define write mcs_write #endif /* DUMMY DEFINES FOR COMPILE */ #define DIRSIZ 10 #define B0 1 #define B110 1 #define B150 1 #define B300 1 #define B600 1 #define B1200 1 #define B1800 1 #define B2400 1 #define B4800 1 #define B9600 1 #define SIGQUIT 1 #define SIGINT 1 #define SIGHUP 1 #define SIGALRM 1 /* Maximum length for the name of a tty device */ #ifndef DEVNAMLEN #define DEVNAMLEN 25 #endif char *ckxsys = " NCR VRX/VE"; /* Features... */ /* Do own buffering, using unbuffered read() calls... */ /* 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. flfnam -- Name of lock file, including its path, e.g., "/usr/spool/uucp/LCK..cul0" or "/etc/locks/tty77" hasLock -- Flag set if this kermit established a uucp lock. inbufc -- number of tty line rawmode unread characters (system III/V unixes) backgrd -- Flag indicating program executing in background ( & on end of shell command). Used to ignore INT and QUIT signals. Functions for assigned communication line (either external or console tty): sysinit() -- System dependent program initialization 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) -- Timed read line from the tty. ttinc(timo) -- Timed read character from tty. myread() -- System 3 raw mode bulk buffer read, gives -- subsequent chars one at a time and simulates -- FIONREAD! myunrd(c) -- Places c back in buffer to be read (one only) ttchk() -- See how many characters in tty input buffer. ttxin(n,buf) -- Read n characters from tty (untimed). ttol(string,length) -- Write a string to the tty. ttoc(c) -- Write a character to the tty. ttflui() -- Flush tty input buffer. ttlock(ttname) -- Lock against uucp collisions (Sys III) ttunlck() -- Unlock " " " look4lk(ttname) -- Check if a lock file exists */ /* Functions for console terminal: congm() -- Get console terminal modes. concb(esc) -- Put the console in single-character wakeup mode with no echo. conbin(esc) -- Put the console in binary (raw) mode. conres() -- Restore the console to mode obtained by congm(). 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. conint() -- Enable terminal interrupts on the console if not background. connoi() -- Disable terminal interrupts on the console if not background. Time functions msleep(m) -- Millisecond sleep ztime(&s) -- Return pointer to date/time string rtimer() -- Reset timer gtimer() -- Get elapsed time since last call to rtimer() */ /* Declarations */ long time(); /* All NCR-VRXes should have this... */ char *dftty = CTTNAM; /* Remote by default, use normal */ int dfloc = 0; /* controlling terminal name. */ extern int errno; /* System call error return */ extern int deblog; /* 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 */ int dfprty = 0; /* Parity (0 = none) */ int dfflow = 1; /* Xon/Xoff flow control */ int backgrd = 0; /* Assume in foreground (no '&' ) */ int ckxech = 0; /* 0 if system normally echoes console characters, else 1 */ /* Declarations of variables global within this module */ static long tcount; /* Elapsed time counter */ static char *brnuls = "\0\0\0\0\0\0\0"; /* A string of nulls */ static jmp_buf sjbuf, jjbuf; /* Longjump buffer */ static int lkf = 0, /* Line lock flag */ conif = 0, /* Console interrupts on/off flag */ cgmf = 0, /* Flag that console modes saved */ xlocal = 0, /* Flag for tty local or remote */ ttyfd = -1; /* TTY file descriptor */ static char escchr; /* Escape or attn character */ /* Special line discipline, 4.2bsd only, and only with kernel mods... */ static int kerld = 0; /* Not selected, no special l.d. */ /* dummy struct for compilw **** */ struct sgttyb { int sg_ispeed; int sg_ospeed; }; static struct sgttyb /* sgtty info... */ ttold, ttraw, tttvt, ttbuf, /* for communication line */ ccold, ccraw, cccbrk; /* and for console */ static char flfnam[80]; /* uucp lock file path name */ static int hasLock = 0; /* =1 if this kermit locked uucp */ static int inbufc = 0; /* stuff for efficient SIII raw line */ static int ungotn = -1; /* pushback to unread character */ static int conesc = 0; /* set to 1 if esc char (^\) typed */ static int ttlock(); /* definition of ttlock subprocedure */ static int ttunlck(); /* and unlock subprocedure */ static char ttnmsv[DEVNAMLEN]; /* copy of open path for tthang */ /* S Y S I N I T -- System-dependent program initialization. */ sysinit() { /* for now, nothing... */ if (deblog) debug(F100, "funct: sysinit ", "", 0); } /* T T Y N A M E -- Set default tty name. */ char * ttyname(x) int x; { char *xx; if (deblog) debug(F100, "funct: ttyname ", "", 0); xx = "/dev/tty"; return(xx); } /* T T O P E N -- Open a tty for exclusive access. */ /* Returns 0 on success, -1 on failure. */ /* If called with lcl < 0, sets value of lcl as follows: 0: the terminal named by ttname is the job's controlling terminal. 1: the terminal named by ttname is not the job's controlling terminal. But watch out: if a line is already open, or if requested line can't be opened, then lcl remains (and is returned as) -1. */ ttopen(ttname, lcl, modem) char *ttname; int *lcl, modem; { char *x; char cname[DEVNAMLEN]; if (deblog) debug(F100, "funct: ttopen ", "", 0); if (ttyfd > -1) return(0); /* If already open, ignore this call */ xlocal = *lcl; /* Make this available to other fns */ ttyfd = open(ttname, O_TTY); /* Try to open for read/write */ if (ttyfd < 0) { /* If couldn't open, fail. */ return(-1); } strncpy(ttnmsv, ttname, DEVNAMLEN); /* Open, keep copy of name locally. */ /* Caller wants us to figure out if line is controlling tty */ if (deblog) debug(F111, "ttopen", ttname, *lcl); if (*lcl == -1) { if (strcmp(ttname, CTTNAM) == 0) { /* "/dev/tty" always remote */ if (deblog) debug(F110, " Same as CTTNAM", ttname, 0); xlocal = 0; } else if (isatty(0)) { /* Else, if stdin not redirected */ x = ttyname(0); /* then compare its device name */ strncpy(cname, x, DEVNAMLEN); /* (copy from internal static buf) */ if (deblog) debug(F110, " ttyname(0)", x, 0); x = ttyname(ttyfd); /* ...with real name of ttname. */ xlocal = (strncmp(x, cname, DEVNAMLEN) == 0) ? 0 : 1; if (deblog) debug(F111, " ttyname", x, xlocal); } else { /* Else, if stdin redirected... */ /* Just assume local, so "set speed" and similar commands will work */ /* If not really local, how could it work anyway?... */ xlocal = 1; if (deblog) debug(F101, " redirected stdin", "", xlocal); } } /* Now check if line is locked -- if so fail, else lock for ourselves */ lkf = 0; /* Check lock */ if (xlocal > 0) { if (ttlock(ttname) < 0) { fprintf(stderr, "Exclusive access to %s denied\n", ttname); close(ttyfd); ttyfd = -1; if (deblog) debug(F110, " Access denied by lock", ttname, 0); return(-1); /* Not if already locked */ } else lkf = 1; } /* Got the line, now set the desired value for local. */ if (*lcl < 0) *lcl = xlocal; /* Some special stuff for v7... */ /* Request exclusive access on systems that allow it. */ /* Get tty device settings */ 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 */ if (deblog) debug(F101, "ttopen, ttyfd", "", ttyfd); if (deblog) debug(F101, " lcl", "", *lcl); if (deblog) debug(F111, " lock file", flfnam, lkf); return(0); } /* T T C L O S -- Close the TTY, releasing any lock. */ ttclos() { if (deblog) debug(F100, "funct: ttclos ", "", 0); 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... */ close(ttyfd); /* Close it. */ ttyfd = -1; /* Mark it as closed. */ return(0); } /* T T H A N G -- Hangup phone line */ tthang() { if (deblog) debug(F100, "funct: tthang ", "", 0); if (ttyfd < 0) return(0); /* Not open. */ return (0); } /* T T R E S -- Restore terminal to "normal" mode. */ ttres() { /* Restore the tty to normal. */ if (deblog) debug(F100, "funct: ttres ", "", 0); if (ttyfd < 0) return(-1); /* Not open. */ sleep(1); /* Wait for pending i/o to finish. */ if (STTY(ttyfd, &ttold) < 0) return(-1); /* Restore sgtty stuff */ 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; if (deblog) debug(F100, "funct: xxlast ", "", 0); 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[DIRSIZ+1]; char *lockdir = "/usr/spool/uucp"; device = ( (devname = xxlast(ttname, '/')) != NULL ? devname + 1 : ttname); strcat( strcpy( lockfil, "LCK.." ), device ); 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); if (deblog) 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) #ifndef MCS_FLAG printf("(Use \"DEL %s\" to remove this file)\n", flfnam); #else mcs_printf("(Use \"DEL %s\" to remove this file)\n", flfnam); #endif 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 */ int lck_fil, l4l; int pid_buf = getpid(); /* pid to save in lock file */ hasLock = 0; /* not locked yet */ l4l = look4lk(ttyfd); if (deblog) debug(F100, "funct: ttlock ", "", 0); 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 */ write (lck_fil, &pid_buf, sizeof(pid_buf) ); /* uucp expects int in file */ 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 (deblog) debug(F100, "funct: ttunlock", "", 0); 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 (deblog) debug(F100, "funct: ttpkt ", "", 0); if (ttyfd < 0) return(-1); /* Not open. */ s = ttsspd(speed); /* Check the speed */ 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 (deblog) debug(F100, "funct: ttvt ", "", 0); if (ttyfd < 0) return(-1); /* Not open. */ s = ttsspd(speed); /* Check the speed */ if (s > -1) tttvt.sg_ispeed = tttvt.sg_ospeed = s; /* Do the speed */ if (STTY(ttyfd, &tttvt) < 0) return(-1); } /* T T S S P D -- Return the internal baud rate code for 'speed'. */ ttsspd(speed) { int s, spdok; if (deblog) debug(F100, "funct: ttsspd ", "", 0); 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; 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() { long n; if (deblog) debug(F100, "funct: ttflui ", "", 0); if (ttyfd < 0) return(-1); /* Not open. */ ungotn = -1; /* Initialize myread() stuff */ inbufc = 0; return(0); } /* Interrupt Functions */ /* Timeout handler for communication line input functions */ timerh() { longjmp(sjbuf, 1); } /* Set up terminal interrupts on console terminal */ /* C O N I N T -- Console Interrupt setter */ conint(f) int (*f)(); { /* Set an interrupt trap. */ if (deblog) debug(F100, "funct: conint ", "", 0); if (backgrd) return; /* must ignore signals in bkgrd */ /* Except for special cases below, ignore keyboard quit signal. ^\ too easily confused with connect escape, and besides, we don't want to leave lock files around. (Frank Prindle) */ SIGNAL(SIGQUIT, SIG_IGN); if (conif) return; /* Nothing to do if already on. */ /* check if invoked in background -- if so signals set to be ignored */ if (SIGNAL(SIGINT, SIG_IGN) == SIG_IGN) { backgrd = 1; /* means running in background */ return; } SIGNAL(SIGINT, f); /* Function to trap to on interrupt. */ SIGNAL(SIGHUP, f); /* Or hangup, so lock file cleared. */ conif = 1; /* Flag console interrupts on. */ } /* C O N N O I -- Reset console terminal interrupts */ connoi() { /* Console-no-interrupts */ if (deblog) debug(F100, "funct: connoi ", "", 0); if (backgrd) return; /* Ignore signals in background */ SIGNAL(SIGINT, SIG_DFL); SIGNAL(SIGHUP, SIG_DFL); SIGNAL(SIGQUIT, SIG_DFL); conif = 0; /* Flag interrupt trapping off */ } /* myread() -- For use by systems that can do nonblocking read() calls */ /* Returns: -1 if no characters available, -2 upon error (such as disconnect), otherwise value of character (0 or greater) */ myread() { static int inbuf_item; static CHAR inbuf[257]; CHAR readit; if (ungotn >= 0) { readit = ungotn; } else { if (inbufc > 0) { readit = inbuf[++inbuf_item]; } else { if ((inbufc = read(0, inbuf, 256)) == 0) { /* end of file */ /* means carrier dropped on modem connection */ errno = 9999; /* magic number for no carrier */ return(-2); /* end of file has no errno */ } if (inbufc < 0) return(-2); readit = inbuf[inbuf_item = 0]; } inbufc--; } ungotn = -1; return(readit); } myunrd(ch) CHAR ch; { /* push back up to one character */ ungotn = ch; } /* T T C H K -- Tell how many characters are waiting in tty input buffer */ ttchk() { int x; long n; if (deblog) debug(F100, "funct: ttchk ", "", 0); return(0); } /* T T X I N -- Get n characters from tty input buffer */ /* Returns number of characters actually gotten, or -1 on failure */ /* Intended for use only when it is known that n characters are actually */ /* Available in the input buffer. */ ttxin(n, buf) int n; char *buf; { int x; CHAR c; if (deblog) debug(F100, "funct: ttxin ", "", 0); if (deblog) debug(F101, "ttxin: n", "", n); x = read(0, buf, n); if (deblog) debug(F101, " x", "", x); if (x > 0) buf[x] = '\0'; if (x < 0) x = -1; return(x); } /* T T O L -- Similar to "ttinl", but for writing. */ ttol(s, n) int n; char *s; { int x; char *str; int nbr; if (deblog) debug(F100, "funct: ttol ", "", 0); if (ttyfd < 0) return(-1); /* Not open. */ if (deblog) debug(F111, "ttol", "string length", n); x = write(1, s, n); if (deblog) debug(F110, "ttol: packet ", s, 0); if (x < 0 && deblog) debug(F101, "ttol failed", "", x); return(x); } /* T T O C -- Output a character to the communication line */ ttoc(c) char c; { if (deblog) debug(F100, "funct: ttoc ", "", 0); if (ttyfd < 0) return(-1); /* Not open. */ return(write(1, &c, 1)); } /* 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" seconds. */ ttinl(dest, max, timo, eol) int max, timo; char *dest; char eol; { int x, y; CHAR c; if (deblog) debug(F101, "funct: ttinl timo ", "", timo); if (ttyfd < 0) return(-1); /* Not open. */ if (timo <= 0) { /* Untimed read... */ x = read(0, dest, max); /* Try to read. */ return(x); /* Return the count. */ } /* Timed read... */ SIGNAL(SIGALRM, timerh); /* Set up timeout action. */ ALARM(timo); /* Set the timer. */ if (setjmp(sjbuf)) /* Do this if timer went off. */ x = -1; else if (kerld) { /* Efficient Kermit line discipline */ x = read(0, dest, max); /* for 4.2bsd only... */ } else { /* Normal case... */ if (deblog) debug(F101, "ttinl, starting for loop, max ", "", max); if (deblog) debug(F101, " eol ", "", eol); for (x = c = y = 0; (x < max) && (c != eol); x++) { while ((y = read(0, &c, 1)) == 0) /* Else call system */ ; /* ...for each character. */ if (deblog) debug(F101, "ttinl, read character ", "", c); if (y < 0) { ALARM(0); /* Error, turn off timer, */ SIGNAL(SIGALRM, SIG_DFL); /* and associated interrupt. */ return(y); /* Return the error indication. */ } dest[x] = c; } x++; } dest[x] = '\0'; /* DRE 041890 - null terminate input line */ ALARM(0); /* Success, turn off timer, */ SIGNAL(SIGALRM, SIG_DFL); /* and associated interrupt. */ return(x); /* Return the count. */ } /* T T I N C -- Read a character from the communication line */ ttinc(timo) int timo; { int n = 0; CHAR ch = 0; if (deblog) debug(F100, "funct: tinc ", "", 0); if (ttyfd < 0) return(-1); /* Not open. */ if (timo <= 0) { /* Untimed. */ while ((n = read(0, &ch, 1)) == 0) ; /* Wait for a character. */ if (n == 46) { /* Break and exit if ':' is typed. */ conoll("BREAK"); doexit(BAD_EXIT); } return( (n > 0) ? (ch & 0377) : n ); } SIGNAL(SIGALRM, timerh); /* Timed, set up timer. */ ALARM(timo); if (setjmp(sjbuf)) { n = -1; } else { n = read(0, &ch, 1); /* Otherwise call the system. */ } ALARM(0); /* Turn off timer, */ SIGNAL(SIGALRM, SIG_DFL); /* and interrupt. */ return( (n > 0) ? (ch & 0377) : n ); /* Return char or -1. */ } /* T T S N D B -- Send a BREAK signals */ ttsndb() { int x; long n; char spd; if (deblog) debug(F100, "funct: ttsndb ", "", 0); if (ttyfd < 0) return(-1); /* Not open. */ } /* M S L E E P -- Millisecond version of sleep(). */ /* Intended only for small intervals. For big ones, just use sleep(). */ msleep(m) int m; { if (deblog) debug(F100, "funct: msleep ", "", 0); } /* R T I M E R -- Reset elapsed time counter */ rtimer() { if (deblog) debug(F100, "funct: rtimer ", "", 0); tcount = time( (long *) 0 ); } /* G T I M E R -- Get current value of elapsed time counter in seconds */ gtimer() { int x; if (deblog) debug(F100, "funct: gtimer ", "", 0); x = (int) (time( (long *) 0 ) - tcount); rtimer(); return( (x < 0) ? 0 : x ); } /* Z T I M E -- Return date/time string */ ztime(s) char **s; { long clk; clk=time((long *) 0); *s=ctime(&clk); } /* C O N G M -- Get console terminal modes. */ /* Saves current console mode, and establishes variables for switching between current (presumably normal) mode and other modes. */ congm() { if (deblog) debug(F100, "funct: congm ", "", 0); GTTY(0, &ccold); /* Structure for restoring */ GTTY(0, &cccbrk); /* For setting CBREAK mode */ GTTY(0, &ccraw); /* For setting RAW mode */ cgmf = 1; /* Flag that we got them. */ } /* C O N C B -- Put console in cbreak mode. */ /* Returns 0 if ok, -1 if not */ concb(esc) char esc; { int x; if (deblog) debug(F100, "funct: concb ", "", 0); if (cgmf == 0) congm(); /* Get modes if necessary. */ escchr = esc; /* Make this available to other fns */ ckxech = 1; /* Program can echo characters */ if (x > -1) setbuf(stdout, NULL); /* Make console unbuffered. */ return(x); } /* C O N B I N -- Put console in binary mode */ /* Returns 0 if ok, -1 if not */ conbin(esc) char esc; { if (cgmf == 0) congm(); /* Get modes if necessary. */ escchr = esc; /* Make this available to other fns */ ckxech = 1; /* Program can echo characters */ } /* C O N R E S -- Restore the console terminal */ conres() { if (deblog) debug(F100, "funct: conres ", "", 0); if (cgmf == 0) return(0); /* Don't do anything if modes */ sleep(1); /* not known! */ ckxech = 0; /* System should echo chars */ return(STTY(0, &ccold)); /* Restore controlling tty */ } /* C O N O C -- Output a character to the console terminal */ conoc(c) char c; { if (deblog) debug(F100, "funct: conoc ", "", 0); write(1, &c, 1); } /* C O N X O -- Write x characters to the console terminal */ conxo(x, s) char *s; int x; { if (deblog) debug(F100, "funct: conxo ", "", 0); 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); if (deblog) debug(F100, "funct: conol ", "", 0); 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; if (deblog) debug(F100, "funct: conola ", "", 0); 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); if (deblog) debug(F100, "funct: conoll ", "", 0); write(1, "\r\n", 2); } /* C O N C H K -- Return how many characters available at console */ conchk() { int x; long n; if (deblog) debug(F100, "funct: conchk ", "", 0); return(0); /* Others can't do. */ } /* C O N I N C -- Get a character from the console */ coninc(timo) int timo; { int n = 0; char ch; if (deblog) debug(F100, "funct: coninc ", "", 0); if (timo <= 0 ) { /* untimed */ n = read(0, &ch, 1); /* Read a character. */ ch &= 0377; if (n > 0) return(ch); /* Return the char if read */ else return(-1); /* Return the char, or -1. */ } SIGNAL(SIGALRM, timerh); /* Timed read, so set up timer */ ALARM(timo); if (setjmp(sjbuf)) n = -2; else { n = read(0, &ch, 1); ch &= 0377; } ALARM(0); /* Stop timing, we got our character */ SIGNAL(SIGALRM, SIG_DFL); if (n > 0) return(ch); else return(-1); } /* A L A R M - this is a dummy alarm() */ ALARM(sec) unsigned sec; { return(1); } /* C H D I R - this is a dummy chdir() */ CHDIR(path) char *path; { return(0); } /* F O R K - this is a dummy fork() */ FORK() { return(1); } /* G T T Y - this is a dummy gtty() */ GTTY(arg1, arg2) int arg1, arg2; { return(0); } /* I O C T L - this is a dummy ioctl() */ IOCTL(fildes, request, arg) int fildes, request, arg; { return(1); } /* K I L L - this is a dummy kill() */ KILL(pid, sig) int pid, sig; { return(0); } /* P A U S E - this is a dummy pause() */ PAUSE() { return(0); } /* S I G N A L - this is a dummy signal() */ SIGNAL(arg1, arg2) int arg1, arg2; { return(0); } /* S T T Y - this is a dummy for stty() */ STTY(arg1, arg2) int arg1, arg2; { return(1); } /* S Y S T E M - this is a dummy for system() */ SYSTEM(cmd) char *cmd; { return(1); } /* W A I T - this is a dummy for wait() */ WAIT(stat_loc) int *stat_loc; { return(1); } /* S Y S C L E A N U P -- System-dependent program cleanup. */ syscleanup() { /* for now, nothing... */ return(0); } /* G E T P W U I D - this is a dummy for getpwuid() */ struct passwd *GETPWUID (uid) int uid; { return ( (struct passwd *) NULL); } /* G E T U I D - this is a dummy for getuid() */ unsigned short GETUID() { return (1); } /* E X E C L - dummy for execl() */ int EXECL (path, arg0, arg1, arg2, arg3, arg4) char *path, *arg0, *arg1, *arg2, *arg3, *arg4; { return (1); }