/****************************************************************************** * This file is part of a software distribution, which is furnished under the * * terms of a license. Use of this software by any means is subject to this * * license and signifies the acceptance of the licensing terms stated * * therein. Please see the file LICENSE in the top-level directory of this * * software distribution for detailed copyright disclaimers and licensing * * terms. * ****************************************************************************** * Copryight (c) by Andreas S. Wetzel - All rights reserved. * ******************************************************************************/ /* $Id: vd_input.c,v 1.3 2001/03/19 23:17:29 mickey Exp $ */ #include #include #include /*** Globals ***/ ED main_ed; ED *ed = &main_ed; /*** Externals ***/ extern int in_chat_window; extern VP vp; extern VTCAP vtcap; /* * int input_line(char *prompt, size_t maxlen, u_short flags); * * Read input from the users terminal up to maxlen characters (or the * maximum possible length if maxlen is given as 0) and return the number * of bytes actually read into the global ED buffer pointed to by the global * ed variable. Flags should be the bitwise OR of any of the following flags: * * ED_RST_CTX - Reset input context upon startup * ED_NO_ECHO - Suppress terminal echo while reading input * */ int input_line(char *prompt, size_t maxlen, u_short flags) { static char lterm = 0; u_char c; u_char cx; /*** Lock all interrupts during init ***/ vlock(LOCK, (V_IO | V_TIMER)); /*** Disable videosnake ***/ snake_disable(); /**** Buffer init ****/ if(flags & ED_RST_CTX) { /* * Reset input context upon startup */ BZERO(&ed->buffer, EDBUFSIZE+1); ed->endpos = ed->curpos = ed->margin = (char *) &ed->buffer; ed->prompt = NULL; } if(prompt) ed->prompt = prompt; ed->offset = (ed->prompt != NULL) ? real_len(ed->prompt) : 0; ed->maxlen = (maxlen > 0 && maxlen < EDBUFSIZE) ? maxlen : EDBUFSIZE; ed->flags = flags; /***** window init *****/ line_update(); /*** init completed - unlock interrupts ***/ vlock(UNLOCK, (V_IO | V_TIMER)); /*** Wait for user input ***/ for(;;) { /* Get character */ switch(read(0, &c, 1)) { case 1: break; case 0: log(VLOG_ERR, "TELNET connection closed by remote host"); snd_serv(CMD_SIGNOFF, NULL, 0); vquit(NULL); case -1: log(VLOG_ERR, "read error on TELNET connection (%s)", strerror(errno)); snd_serv(CMD_SIGNOFF, NULL, 0); vquit(NULL); default: log(VLOG_ERR, "Oooops!!!"); snd_serv(CMD_SIGNOFF, NULL, 0); vquit("Oooops!!!"); } /* End of line? */ if((c == CR && lterm != LF) || (c == LF && lterm != CR)) { lterm = c; break; } else if(c == CR || c == LF) { continue; } /* Filter for incoming telnet commands */ if(!(cx = tel_filter(c))) continue; vlock(LOCK, (V_IO | V_TIMER)); snake_enable(); if(is_key_sequence(vtcap.key_cursleft, cx)) { curs_left(); } else if(is_key_sequence(vtcap.key_cursright, cx)) { curs_right(); } else if(is_key_sequence(vtcap.key_cursup, cx)) { if((ed->flags & ED_HISTORY) != 0 && vp.history_current != vp.history_start) { snake_disable(); vlock(UNLOCK, (V_IO | V_TIMER)); return(-2); } else { nop(); } } else if(is_key_sequence(vtcap.key_cursdown, cx)) { if((ed->flags & ED_HISTORY) != 0 && vp.history_current != vp.history_next) { snake_disable(); vlock(UNLOCK, (V_IO | V_TIMER)); return(-4); } else { nop(); } } else if(is_key_sequence(vtcap.key_insert, cx)) { ungetc(' ', stdin); } else if(is_key_sequence(vtcap.key_delete, cx)) { delete(); } else if(iscntrl(cx)) { switch(cx) { case DEL: case BS: backspace(); break; case CTL_A: jump_start(); break; case CTL_E: jump_end(); break; case CTL_D: delete(); break; case CTL_K: erase_eol(); break; case CTL_U: erase_line(); break; case CTL_F: word_forward(); break; case CTL_B: word_reverse(); break; case CTL_L: line_update(); break; case HT: tabcomplete(); break; default: break; } } else { if(ed->curpos != ed->endpos) { /* * Insert mode */ insert_char(cx); } else { /* * Append mode */ append_char(cx); } } vlock(UNLOCK, (V_IO | V_TIMER)); } if(ED_USED) { vlock(LOCK, (V_IO | V_TIMER)); mv(1, vtcap.rows); in_chat_window = 0; if(vtcap.clear2eol) tputs(vtcap.clear2eol, 1, (void *)outc); else if(vtcap.clear2eod) tputs(vtcap.clear2eod, 1, (void *)outc); vlock(UNLOCK, (V_IO | V_TIMER)); } return(ED_USED); }