home *** CD-ROM | disk | FTP | other *** search
- /* TTY input line editing
- * Copyright 1991 Phil Karn, KA9Q
- */
- #include <stdio.h>
- #include <ctype.h>
- /*#include <conio.h>*/
- #include "global.h"
- #include "mbuf.h"
- #include "session.h"
- #include "tty.h"
- #include "socket.h"
-
- #define OFF 0
- #define ON 1
-
- #define LINESIZE 256
-
- #define CTLU 21
- #define CTLR 18
- #define CTLW 23
- #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.
- */
- char *
- ttydriv(sp,c)
- struct session *sp;
- char c;
- {
- char *cp,*rp;
-
- switch(sp->ttystate.edit){
- case OFF:
- rp = cp = mallocw(2);
- *cp++ = c;
- *cp = '\0';
- if(sp->ttystate.echo) {
- fputc(c,Current->output);
- fflush(Current->output);
- }
- return rp;
- case ON:
- if(sp->ttystate.line == NULLCHAR)
- sp->ttystate.lp = sp->ttystate.line = calloc(1,LINESIZE);
-
- cp = sp->ttystate.lp;
- rp = sp->ttystate.line;
- /* 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;
- *cp++ = '\0';
- if(sp->ttystate.echo)
- putc('\n',Current->output);
-
- sp->ttystate.line = NULLCHAR;
- return rp;
- case DEL:
- case '\b': /* Character delete */
- if(sp->ttystate.lp != rp){
- sp->ttystate.lp--;
- if(sp->ttystate.echo)
- fputs("\b \b",Current->output);
- }
- break;
- case CTLR: /* print line buffer */
- if(sp->ttystate.echo){
- fprintf(Current->output,"^R\n");
- fwrite(rp,1,cp-rp,Current->output);
- }
- break;
- case CTLU: /* Line kill */
- while(sp->ttystate.lp != rp){
- sp->ttystate.lp--;
- if(sp->ttystate.echo){
- fputs("\b \b",Current->output);
- }
- }
- break;
- case CTLW: /* Word kill */
- while(cp != rp && isspace(cp[-1])){
- cp--;
- if(sp->ttystate.echo){
- fputs("\b \b",Current->output);
- }
- }
- while(cp != rp && !isspace(cp[-1])){
- cp--;
- if(sp->ttystate.echo){
- fputs("\b \b",Current->output);
- }
- }
- sp->ttystate.lp = cp;
- break;
- default: /* Ordinary character */
- *cp++ = c;
-
- /* ^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
- cp - rp < LINESIZE-1){
- putc(c,Current->output);
-
- } else if(cp - rp >= LINESIZE-1){
- putc('\007',Current->output); /* Beep */
- cp--;
- }
- sp->ttystate.lp = cp;
- break;
- }
- if(sp->ttystate.echo) {
- fflush(Current->output);
- }
- break;
- }
- return NULLCHAR;
- }
-