package org.freertr.pipe; import java.io.RandomAccessFile; import org.freertr.sec.secClient; import org.freertr.serv.servGeneric; import org.freertr.util.bits; import org.freertr.util.logger; /** * terminal emulator * * @author matecsaba */ public class pipeTerm { /** * escape character */ protected final int escChr; /** * stream handler */ protected pipeSide stream; /** * console handler */ protected final pipeSide console; /** * record handler */ protected final RandomAccessFile record; /** * rx thread running */ protected boolean runningRx; /** * tx thread running */ protected boolean runningTx; /** * threads needed */ protected boolean runningNeed; /** * thread time in millisecs */ protected final static int threadTime = 200; /** * thread buffer size */ protected final static int threadBuf = 1024; /** * create one terminal * * @param con console to use * @param strm stream to use * @param rec recording */ public pipeTerm(pipeSide con, pipeSide strm, RandomAccessFile rec) { console = con; stream = strm; record = rec; escChr = con.settingsGet(pipeSetting.escape, 65536); } /** * get escape character name * * @return text */ protected String getEscNam() { return "ascii0x" + bits.toHexB(escChr); } /** * terminal session */ public void doTerm() { if (stream == null) { return; } if (stream.isClosed() != 0) { return; } runningRx = true; runningTx = true; runningNeed = true; console.linePut(""); console.linePut("escape character is " + getEscNam() + "."); console.linePut(""); new Thread(new pipeTermRx(this)).start(); new Thread(new pipeTermTx(this)).start(); for (;;) { bits.sleep(threadTime * 2); if (stream.isClosed() != 0) { break; } if (console.isClosed() != 0) { break; } } console.linePut(""); stream.setClose(); runningNeed = false; for (; runningTx || runningRx;) { bits.sleep(500); } console.linePut("connection closed"); } } class pipeTermRx implements Runnable { private final pipeTerm parent; public pipeTermRx(pipeTerm prnt) { parent = prnt; } public void run() { try { for (;;) { if (!parent.runningNeed) { break; } byte[] buf = new byte[pipeTerm.threadBuf]; int siz = parent.stream.nonBlockGet(buf, 0, buf.length); if (siz < 1) { bits.sleep(pipeTerm.threadTime); continue; } parent.console.blockingPut(buf, 0, siz); if (parent.record == null) { continue; } parent.record.write(buf, 0, siz); } } catch (Exception e) { logger.traceback(e); } parent.runningRx = false; } } class pipeTermTx implements Runnable { private final pipeTerm parent; public pipeTermTx(pipeTerm prnt) { parent = prnt; } public void run() { try { for (;;) { if (!parent.runningNeed) { break; } byte[] buf = new byte[pipeTerm.threadBuf]; int siz = parent.console.nonBlockGet(buf, 0, buf.length); if (siz < 1) { bits.sleep(pipeTerm.threadTime); continue; } if ((siz > 1) || (buf[0] != parent.escChr)) { parent.stream.blockingPut(buf, 0, siz); continue; } siz = parent.console.blockingGet(buf, 0, 1); if (siz != 1) { continue; } switch (buf[0]) { case 104: // h case 72: // H case 63: // ? case 8: // ctrl+h parent.console.linePut(""); parent.console.linePut("^H - show this help message"); parent.console.linePut("^T - start tls client"); parent.console.linePut("^C - send one " + parent.getEscNam() + " character"); parent.console.linePut("^V - send two " + parent.getEscNam() + " characters"); parent.console.linePut("^X - close terminal session"); break; case 116: // t case 84: // T case 20: // ctrl+t parent.console.strPut("tls negotiation"); pipeSide res = secClient.openSec(parent.stream, servGeneric.protoTls, null, "", ""); if (res == null) { parent.console.linePut(" failed!"); } else { parent.console.linePut(" success!"); parent.stream = res; } break; case 99: // c case 67: // C case 3: // ctrl+c buf[0] = 3; parent.stream.blockingPut(buf, 0, 1); break; case 118: // v case 86: // V case 22: // ctrl+v buf[0] = 3; buf[1] = 3; parent.stream.blockingPut(buf, 0, 2); break; case 120: // x case 88: // X case 24: // ctrl+x parent.stream.setClose(); break; default: parent.stream.blockingPut(buf, 0, 1); break; } } } catch (Exception e) { logger.traceback(e); } parent.runningTx = false; } }