/* TTY input line editing * Copyright 1991 Phil Karn, KA9Q */ #include #include "global.h" #include "mbuf.h" #include "session.h" #include "tty.h" #include "socket.h" extern FILE *Rawterm; #define OFF 0 #define ON 1 #define LINESIZE 256 #define CTLU 21 #define CTLR 18 #define CTLZ 26 #define DEL 0x7f /* Accept characters from the incoming tty buffer and process them * (if in cooked mode) or just pass them directly (if in raw mode). * * Echoing (if enabled) is direct to the raw terminal. This requires * recording (if enabled) of locally typed info to be done by the session * itself so that edited output instead of raw input is recorded. */ struct mbuf * ttydriv(sp,c) struct session *sp; char c; { struct mbuf *bp; char *cp,*rp; switch(sp->ttystate.edit){ case OFF: bp = ambufw(1); *bp->data = c; bp->cnt = 1; if(sp->ttystate.echo) putc(c,Rawterm); return bp; case ON: if(sp->ttystate.line == NULLBUF) sp->ttystate.line = ambufw(LINESIZE); bp = sp->ttystate.line; cp = bp->data + bp->cnt; /* Perform cooked-mode line editing */ switch(c & 0x7f){ case '\r': /* CR and LF both terminate the line */ case '\n': if(sp->ttystate.crnl) *cp = '\n'; else *cp = c; if(sp->ttystate.echo) fputs(Eol,Rawterm); bp->cnt += 1; sp->ttystate.line = NULLBUF; return bp; case DEL: case '\b': /* Character delete */ if(bp->cnt != 0){ bp->cnt--; if(sp->ttystate.echo) fputs("\b \b",Rawterm); } break; case CTLR: /* print line buffer */ if(sp->ttystate.echo){ fprintf(Rawterm,"^R%s",Eol) ; rp = bp->data; while (rp < cp) putc(*rp++,Rawterm) ; } break ; case CTLU: /* Line kill */ while(bp->cnt != 0){ bp->cnt--; if(sp->ttystate.echo){ fputs("\b \b",Rawterm); } } break; default: /* Ordinary character */ *cp = c; bp->cnt++; /* ^Z apparently hangs the terminal emulators under * DoubleDos and Desqview. I REALLY HATE having to patch * around other people's bugs like this!!! */ if(sp->ttystate.echo && #ifndef AMIGA c != CTLZ && #endif bp->cnt < LINESIZE-1){ putc(c,Rawterm); } else if(bp->cnt >= LINESIZE-1){ putc('\007',Rawterm); /* Beep */ bp->cnt--; } break; } break; } return NULLBUF; }