From 6bf1f36cee90e75e706e54a42c6d9eff5edcc9b0 Mon Sep 17 00:00:00 2001 From: Michiel Broek Date: Sun, 1 Feb 2004 14:38:49 +0000 Subject: [PATCH] Updates for experimental telnet code --- mbcico/Makefile | 9 +-- mbcico/opentcp.c | 175 +++++----------------------------------------- mbcico/opentcp.h | 6 -- mbcico/telnet.c | 176 +++++++++++++++++++++++++++++++++++++++++++++++ mbcico/telnet.h | 22 ++++++ 5 files changed, 220 insertions(+), 168 deletions(-) create mode 100644 mbcico/telnet.c create mode 100644 mbcico/telnet.h diff --git a/mbcico/Makefile b/mbcico/Makefile index 2c6dc878..270667d4 100644 --- a/mbcico/Makefile +++ b/mbcico/Makefile @@ -9,7 +9,7 @@ SRCS = zmmisc.c zmrle.c zmrecv.c zmsend.c binkp.c md5b.c \ answer.c chat.c dial.c dietifna.c emsidat.c filelist.c \ openfile.c openport.c opentcp.c rdoptions.c yoohoo.c \ recvbark.c respfreq.c sendbark.c tcp.c tcpproto.c wazoo.c \ - filetime.c ftsc.c atoul.c portsel.c \ + filetime.c ftsc.c atoul.c portsel.c telnet.c \ ttyio.c lutil.c scanout.c emsi.c ulock.c \ callstat.c session.c call.c mbcico.c \ outstat.c nlinfo.c mbout.c mbtelind.c mbtelout.c @@ -18,7 +18,7 @@ HDRS = zmodem.h binkp.h config.h statetbl.h md5b.h \ answer.h chat.h dial.h dietifna.h emsidat.h filelist.h \ openfile.h openport.h opentcp.h rdoptions.h yoohoo.h \ recvbark.h respfreq.h sendbark.h tcp.h tcpproto.h wazoo.h \ - filetime.h ftsc.h atoul.h portsel.h \ + filetime.h ftsc.h atoul.h portsel.h telnet.h \ ttyio.h lutil.h scanout.h emsi.h ulock.h \ callstat.h session.h call.h mbcico.h \ outstat.h nlinfo.h mbtelind.h mbtelout.h @@ -27,7 +27,7 @@ MBCICO_OBJS = zmmisc.o zmrle.o zmrecv.o zmsend.o binkp.o md5b.o \ answer.o chat.o dial.o dietifna.o emsidat.o filelist.o \ openfile.o openport.o opentcp.o rdoptions.o yoohoo.o \ recvbark.o respfreq.o sendbark.o tcp.o tcpproto.o wazoo.o \ - filetime.o ftsc.o atoul.o portsel.o \ + filetime.o ftsc.o atoul.o portsel.o telnet.o \ ttyio.o lutil.o scanout.o emsi.o ulock.o \ callstat.o session.o call.o mbcico.o MBOUT_OBJS = outstat.o nlinfo.o mbout.o scanout.o callstat.o @@ -115,7 +115,7 @@ emsidat.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/users.h ../lib/reco filelist.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/clcomm.h ../lib/common.h ../lib/nodelist.h config.h session.h filelist.h openfile.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/clcomm.h ../lib/common.h ../lib/users.h ../lib/records.h config.h lutil.h openfile.h openport.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/common.h ../lib/clcomm.h ulock.h ttyio.h mbcico.h openport.h -opentcp.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/clcomm.h ../lib/nodelist.h ../lib/dbnode.h session.h ttyio.h openport.h opentcp.h +opentcp.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/clcomm.h ../lib/nodelist.h ../lib/dbnode.h session.h ttyio.h openport.h telnet.h opentcp.h rdoptions.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/clcomm.h ../lib/nodelist.h ../lib/dbnode.h session.h config.h yoohoo.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/clcomm.h ../lib/common.h ../lib/nodelist.h ../lib/dbnode.h ../lib/mberrors.h statetbl.h ttyio.h session.h config.h emsi.h hydra.h rdoptions.h wazoo.h dietifna.h yoohoo.h inbound.h recvbark.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/common.h ../lib/nodelist.h ../lib/clcomm.h ttyio.h session.h statetbl.h recvbark.h respfreq.h filelist.h @@ -128,6 +128,7 @@ filetime.o: ../config.h ../lib/libs.h filetime.h ftsc.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/nodelist.h ../lib/clcomm.h ../lib/mberrors.h session.h ttyio.h statetbl.h config.h ftsc.h rdoptions.h recvbark.h filelist.h sendbark.h respfreq.h xmrecv.h xmsend.h inbound.h atoul.o: ../config.h ../lib/libs.h atoul.h portsel.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/clcomm.h portsel.h +telnet.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/clcomm.h ../lib/nodelist.h ../lib/dbnode.h telnet.h ttyio.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/clcomm.h ttyio.h lutil.h lutil.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/common.h ../lib/clcomm.h lutil.h scanout.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/clcomm.h ../lib/dbftn.h config.h scanout.h lutil.h diff --git a/mbcico/opentcp.c b/mbcico/opentcp.c index d958fee5..2a6bc081 100644 --- a/mbcico/opentcp.c +++ b/mbcico/opentcp.c @@ -4,7 +4,7 @@ * Purpose ...............: Fidonet mailer * ***************************************************************************** - * Copyright (C) 1997-2003 + * Copyright (C) 1997-2004 * * Michiel Broek FIDO: 2:280/2802 * Beekmansbos 10 @@ -40,6 +40,7 @@ #include "session.h" #include "ttyio.h" #include "openport.h" +#include "telnet.h" #include "opentcp.h" @@ -61,12 +62,6 @@ extern long rcvdbytes; extern int Loaded; static int tcp_is_open = FALSE; -#ifdef USE_EXPERIMENT -void telnet_init(int); -void telnet_answer(int, int, int); -void telout_filter(int [], int); -void telin_filter(int [], int); -#endif /* opentcp() was rewritten by Martin Junius */ @@ -145,15 +140,15 @@ int opentcp(char *name) return -1; } + Syslog('d', "SIGPIPE => sigpipe()"); + signal(SIGPIPE, sigpipe); + Syslog('d', "SIGHUP => linedrop()"); + signal(SIGHUP, linedrop); + #ifdef USE_EXPERIMENT if (tcp_mode == TCPMODE_ITN) { Syslog('s', "Installing telnet filter..."); - Syslog('d', "SIGPIPE => sigpipe()"); - signal(SIGPIPE, sigpipe); - Syslog('d', "SIGHUP => linedrop()"); - signal(SIGHUP, linedrop); - /* * Create TCP socket and open */ @@ -167,6 +162,10 @@ int opentcp(char *name) } Syslog('s', "socket %d", Fdo); + /* + * Close stdin and stdout so that when we create the pipes to + * the telnet filter they get stdin and stdout as file descriptors. + */ fflush(stdin); fflush(stdout); setbuf(stdin,NULL); @@ -175,13 +174,12 @@ int opentcp(char *name) close(1); /* - * Create output pipe + * Create output pipe and start output filter. */ if ((rc = pipe(output_pipe)) == -1) { WriteError("$could not create output_pipe"); return -1; } - fpid = fork(); switch (fpid) { case -1: WriteError("fork for telout_filter failed"); @@ -190,7 +188,7 @@ int opentcp(char *name) WriteError("$error close output_pipe[1]"); return -1; } - telout_filter(output_pipe, Fdo); + telout_filter(output_pipe[0], Fdo); /* NOT REACHED */ } if (close(output_pipe[0] == -1)) { @@ -200,16 +198,12 @@ int opentcp(char *name) Syslog('s', "telout_filter forked with pid %d", fpid); /* - * Create input pipe + * Create input pipe and start input filter */ if ((rc = pipe(input_pipe)) == -1) { WriteError("$could not create input_pipe"); return -1; } - - /* - * Fork input filter - */ fpid = fork(); switch (fpid) { case -1: WriteError("fork for telin_filter failed"); @@ -218,7 +212,7 @@ int opentcp(char *name) WriteError("$error close input_pipe[0]"); return -1; } - telin_filter(input_pipe, Fdo); + telin_filter(input_pipe[1], Fdo); /* NOT REACHED */ } if (close(input_pipe[1]) == -1) { @@ -226,10 +220,11 @@ int opentcp(char *name) return -1; } Syslog('s', "telin_filter forked with pid %d", fpid); + Syslog('s', "stdout = %d", output_pipe[1]); Syslog('s', "stdin = %d", input_pipe[0]); - telnet_init(Fdo); + telnet_init(Fdo); /* Do we need that as originating system? */ f_flags=0; } else { @@ -237,10 +232,6 @@ int opentcp(char *name) /* * Transparant 8 bits connection */ - Syslog('d', "SIGPIPE => sigpipe()"); - signal(SIGPIPE, sigpipe); - Syslog('d', "SIGHUP => linedrop()"); - signal(SIGHUP, linedrop); fflush(stdin); fflush(stdout); setbuf(stdin,NULL); @@ -333,135 +324,3 @@ void closetcp(void) } - -#ifdef USE_EXPERIMENT - - -void telnet_init(int Fd) -{ - Syslog('s', "telnet_init(%d)", Fd); - telnet_answer(DO, TOPT_SUPP, Fd); - telnet_answer(WILL, TOPT_SUPP, Fd); - telnet_answer(DO, TOPT_BIN, Fd); - telnet_answer(WILL, TOPT_BIN, Fd); - telnet_answer(DO, TOPT_ECHO, Fd); - telnet_answer(WILL, TOPT_ECHO, Fd); -} - - - -void telnet_answer(int tag, int opt, int Fd) -{ - char buf[3]; - char *r = (char *)"???"; - - switch (tag) { - case WILL: r = (char *)"WILL"; - break; - case WONT: r = (char *)"WONT"; - break; - case DO: r = (char *)"DO"; - break; - case DONT: r = (char *)"DONT"; - break; - } - Syslog('s', "Telnet: send %s %d", r, opt); - - buf[0] = IAC; - buf[1] = tag; - buf[2] = opt; - if (write (Fd, buf, 3) != 3) - WriteError("$answer cant send"); -} - - - -void telout_filter(int output_pipe[], int Fd) -{ - int rc, c; - char ch; - - Syslog('s', "telout_filter: in=%d out=%d", output_pipe[0], Fd); - - while (read(output_pipe[0], &ch, 1) > 0) { - c = (int)ch & 0xff; -// Syslog('s', "telout_filter: ch=%s", printablec(c)); - if (c == IAC) { - Syslog('s', "telout_filter: got IAC"); - /* - * Escape IAC characters - */ - rc = write(Fd, &ch, 1); - } - /* write translated character back to user_handler. */ - rc = write(Fd, &ch, 1); - if (rc == -1) { /* write failed - notify user and exit. */ - Syslog('s', "$telout_filter: write to Fd failed"); - exit(1); - } - } - Syslog('s', "$telout_filter: read error"); - - exit(0); -} - - -void telin_filter(int input_pipe[], int Fd) -{ - int rc, c, m; - char ch; - - Syslog('s', "telin_filter: in=%d out=%d", Fd, input_pipe[1]); - Syslog('s', "telin_filter: IAC=%s %d", printablec(IAC), IAC); - - while (read(Fd, &ch, 1) > 0) { - c = (int)ch & 0xff; -// Syslog('s', "telin_filter: ch=%s", printablec(c)); - if (c == IAC) { - Syslog('s', "got IAC"); - if ((read(Fd, &ch, 1) < 0)) - break; - m = (int)ch & 0xff; - switch (m) { - case WILL: read(Fd, &ch, 1); - m = (int)ch & 0xff; - Syslog('s', "Telnet: recv WILL %d", m); - if (m != TOPT_BIN && m != TOPT_SUPP && m != TOPT_ECHO) - telnet_answer(DONT, m, input_pipe[1]); - break; - case WONT: read(Fd, &ch, 1); - m = (int)ch & 0xff; - Syslog('s', "Telnet: recv WONT %d", m); - break; - case DO: read(Fd, &ch, 1); - m = (int)ch & 0xff; - Syslog('s', "Telnet: recv DO %d", m); - if (m != TOPT_BIN && m != TOPT_SUPP && m != TOPT_ECHO) - telnet_answer(WONT, m, input_pipe[1]); - break; - case DONT: read(Fd, &ch, 1); - m = (int)ch & 0xff; - Syslog('s', "Telnet: recv DONT %d", m); - break; - case IAC: ch = (char)m & 0xff; - rc = write(input_pipe[1], &ch, 1); - break; - default: Syslog('s', "Telnet: recv IAC %d, not good", m); - break; - } - } else { -// Syslog('s', "Telnet: normal"); - ch = (char)c; - rc = write(input_pipe[1], &ch, 1); - if (rc == -1) { /* write failed - notify user and exit. */ - Syslog('s', "$telin_filter: write to input_pipe[1] failed"); - exit(1); - } - } - } - Syslog('s', "$telin_filter: read error"); - - exit(0); -} - -#endif diff --git a/mbcico/opentcp.h b/mbcico/opentcp.h index ed045d8c..737c6c34 100644 --- a/mbcico/opentcp.h +++ b/mbcico/opentcp.h @@ -3,12 +3,6 @@ #ifndef _OPENTCP_H #define _OPENTCP_H -#define MBT_TIMEOUT 500 -#define MBT_BUFLEN 8192 - -#define TOPT_BIN 0 -#define TOPT_ECHO 1 -#define TOPT_SUPP 3 int opentcp(char *); void closetcp(void); diff --git a/mbcico/telnet.c b/mbcico/telnet.c new file mode 100644 index 00000000..8a83c0d7 --- /dev/null +++ b/mbcico/telnet.c @@ -0,0 +1,176 @@ +/***************************************************************************** + * + * $Id$ + * Purpose ...............: Fidonet mailer + * + ***************************************************************************** + * Copyright (C) 1997-2004 + * + * Michiel Broek FIDO: 2:280/2802 + * Beekmansbos 10 + * 1971 BV IJmuiden + * the Netherlands + * + * This file is part of MBSE BBS. + * + * This BBS is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * MBSE BBS is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with MBSE BBS; see the file COPYING. If not, write to the Free + * Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + *****************************************************************************/ + +#include "../config.h" +#include "../lib/libs.h" +#include "../lib/structs.h" +#include "../lib/users.h" +#include "../lib/records.h" +#include "../lib/common.h" +#include "../lib/clcomm.h" +#include "../lib/nodelist.h" +#include "../lib/dbnode.h" +#include "telnet.h" + + + + +#ifdef USE_EXPERIMENT + + +void telnet_init(int Fd) +{ + Syslog('s', "telnet_init(%d)", Fd); + telnet_answer(DO, TOPT_SUPP, Fd); + telnet_answer(WILL, TOPT_SUPP, Fd); + telnet_answer(DO, TOPT_BIN, Fd); + telnet_answer(WILL, TOPT_BIN, Fd); + telnet_answer(DO, TOPT_ECHO, Fd); + telnet_answer(WILL, TOPT_ECHO, Fd); +} + + + +void telnet_answer(int tag, int opt, int Fd) +{ + char buf[3]; + char *r = (char *)"???"; + + switch (tag) { + case WILL: r = (char *)"WILL"; + break; + case WONT: r = (char *)"WONT"; + break; + case DO: r = (char *)"DO"; + break; + case DONT: r = (char *)"DONT"; + break; + } + Syslog('s', "Telnet: send %s %d", r, opt); + + buf[0] = IAC; + buf[1] = tag; + buf[2] = opt; + if (write (Fd, buf, 3) != 3) + WriteError("$answer cant send"); +} + + + +/* + * Telnet output filter, escape IAC. + */ +void telout_filter(int fdi, int fdo) +{ + int rc, c; + char ch; + + Syslog('s', "telout_filter: in=%d out=%d", fdi, fdo); + + while ((rc = read(fdi, &ch, 1)) > 0) { + c = (int)ch & 0xff; + if (c == IAC) { + Syslog('s', "telout_filter: got IAC"); + /* + * Escape IAC characters by sending it twice. + */ + rc = write(fdo, &ch, 1); + } + if ((rc = write(fdo, &ch, 1)) == -1) { + Syslog('s', "$telout_filter: write failed"); + exit(1); + } + } + + Syslog('s', "$telout_filter: finished rc=%d", rc); + exit(0); +} + + + +/* + * Telnet input filter, interpret telnet commands. + */ +void telin_filter(int fdo, int fdi) +{ + int rc, c, m; + char ch; + + Syslog('s', "telin_filter: in=%d out=%d", fdi, fdo); + + while ((rc = read(fdi, &ch, 1)) > 0) { + c = (int)ch & 0xff; +// Syslog('s', "telin_filter: ch=%s", printablec(c)); + if (c == IAC) { + Syslog('s', "got IAC"); + if ((read(fdi, &ch, 1) < 0)) + break; + m = (int)ch & 0xff; + switch (m) { + case WILL: read(fdi, &ch, 1); + m = (int)ch & 0xff; + Syslog('s', "Telnet: recv WILL %d", m); + if (m != TOPT_BIN && m != TOPT_SUPP && m != TOPT_ECHO) + telnet_answer(DONT, m, fdo); + break; + case WONT: read(fdi, &ch, 1); + m = (int)ch & 0xff; + Syslog('s', "Telnet: recv WONT %d", m); + break; + case DO: read(fdi, &ch, 1); + m = (int)ch & 0xff; + Syslog('s', "Telnet: recv DO %d", m); + if (m != TOPT_BIN && m != TOPT_SUPP && m != TOPT_ECHO) + telnet_answer(WONT, m, fdo); + break; + case DONT: read(fdi, &ch, 1); + m = (int)ch & 0xff; + Syslog('s', "Telnet: recv DONT %d", m); + break; + case IAC: ch = (char)m & 0xff; + rc = write(fdo, &ch, 1); + break; + default: Syslog('s', "Telnet: recv IAC %d, not good", m); + break; + } + } else { + ch = (char)c; + if ((rc = write(fdo, &ch, 1)) == -1) { + Syslog('s', "$telin_filter: write failed"); + exit(1); + } + } + } + + Syslog('s', "telin_filter: finished rc=%d", rc); + exit(0); +} + +#endif diff --git a/mbcico/telnet.h b/mbcico/telnet.h new file mode 100644 index 00000000..2a180417 --- /dev/null +++ b/mbcico/telnet.h @@ -0,0 +1,22 @@ +#ifndef _TELNET_H +#define _TELNET_H + +/* $Id$ */ + +#ifdef USE_EXPERIMENT + +// #define MBT_TIMEOUT 500 +// #define MBT_BUFLEN 8192 + +#define TOPT_BIN 0 +#define TOPT_ECHO 1 +#define TOPT_SUPP 3 + +void telnet_init(int); +void telnet_answer(int, int, int); +void telout_filter(int, int); +void telin_filter(int, int); + +#endif + +#endif