Attempt to make outgoing telnet work
This commit is contained in:
parent
bb1105a61f
commit
4c919784a1
@ -3,6 +3,8 @@ $Id$
|
||||
|
||||
v0.39.2 21-Nov-2003
|
||||
|
||||
NOTE: Don't use this version yet, mbtelnetd might be removed again!
|
||||
|
||||
general:
|
||||
With the use of a proxy based on the iftelnetd from the ifmail
|
||||
package incoming telnet sessions are now supported. Outgoing
|
||||
@ -11,9 +13,13 @@ v0.39.2 21-Nov-2003
|
||||
upgrade:
|
||||
See mbtelnetd.html how to install mbtelnetd.
|
||||
|
||||
common.a:
|
||||
A small fix in printable function.
|
||||
|
||||
mbcico:
|
||||
If called by inetd with the -t itn parameters, mbcico aborts
|
||||
and writes a short instruction in the log to install mbtelnetd.
|
||||
Outgoing telnet works almost.
|
||||
|
||||
mbtelnetd:
|
||||
New program, a proxy to handle incoming telnet/vmodem sessions.
|
||||
|
@ -497,7 +497,7 @@ char *printable(char *s, int l)
|
||||
case '\n': *p++='\\'; *p++='n'; break;
|
||||
case '\t': *p++='\\'; *p++='t'; break;
|
||||
case '\b': *p++='\\'; *p++='b'; break;
|
||||
default: sprintf(p,"\\%02x",*s); p+=3; break;
|
||||
default: sprintf(p,"\\%02x", (*s & 0xff)); p+=3; break;
|
||||
}
|
||||
s++;
|
||||
}
|
||||
|
@ -138,6 +138,6 @@ mbcico.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/users.h ../lib/recor
|
||||
outstat.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/dbcfg.h ../lib/dbnode.h ../lib/dbftn.h ../lib/mberrors.h scanout.h callstat.h outstat.h
|
||||
nlinfo.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/common.h ../lib/nodelist.h ../lib/clcomm.h nlinfo.h
|
||||
mbout.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/dbcfg.h ../lib/dbnode.h ../lib/dbftn.h ../lib/mberrors.h outstat.h nlinfo.h
|
||||
mbtelnetd.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/clcomm.h ../lib/dbcfg.h ../lib/mberrors.h telnio.h mbtelnetd.h
|
||||
telnio.o: ../config.h ../lib/libs.h ../lib/clcomm.h telnio.h
|
||||
mbtelnetd.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/clcomm.h ../lib/dbcfg.h ../lib/mberrors.h hydra.h telnio.h mbtelnetd.h
|
||||
telnio.o: ../config.h ../lib/libs.h ../lib/clcomm.h hydra.h telnio.h
|
||||
# End of generated dependencies
|
||||
|
@ -55,34 +55,18 @@
|
||||
#include "../lib/clcomm.h"
|
||||
#include "../lib/dbcfg.h"
|
||||
#include "../lib/mberrors.h"
|
||||
#include "hydra.h"
|
||||
#include "telnio.h"
|
||||
#include "mbtelnetd.h"
|
||||
|
||||
|
||||
#define MBT_BUFSIZ 8192
|
||||
#define MBT_TIMEOUT 3600
|
||||
|
||||
|
||||
void die(int);
|
||||
int init_telnet(void);
|
||||
void answer(int, int);
|
||||
int read0(char *, int);
|
||||
int write1(char *, int);
|
||||
void com_gw(int);
|
||||
|
||||
|
||||
#define WILL 251
|
||||
#define WONT 252
|
||||
#define DO 253
|
||||
#define DONT 254
|
||||
#define IAC 255
|
||||
|
||||
#define TN_TRANSMIT_BINARY 0
|
||||
#define TN_ECHO 1
|
||||
#define TN_SUPPRESS_GA 3
|
||||
|
||||
|
||||
|
||||
static int tellen;
|
||||
char *envptr = NULL;
|
||||
time_t t_start, t_end;
|
||||
|
||||
@ -200,11 +184,11 @@ int main(int ac, char **av)
|
||||
die(MBERR_INIT_ERROR);
|
||||
}
|
||||
|
||||
init_telnet();
|
||||
telnet_init();
|
||||
|
||||
tmp = calloc(81, sizeof(char ));
|
||||
sprintf(tmp, "mbtelnetd v%s\r\n", VERSION);
|
||||
write1(tmp, strlen(tmp));
|
||||
telnet_write(tmp, strlen(tmp));
|
||||
free(tmp);
|
||||
|
||||
com_gw(s);
|
||||
@ -218,139 +202,12 @@ int main(int ac, char **av)
|
||||
|
||||
|
||||
|
||||
/* --- This is an artwork of serge terekhov, 2:5000/13@fidonet :) --- */
|
||||
|
||||
void answer (int tag, int opt)
|
||||
{
|
||||
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 (1, buf, 3) != 3)
|
||||
WriteError("$answer cant send");
|
||||
}
|
||||
|
||||
|
||||
|
||||
int init_telnet(void)
|
||||
{
|
||||
tellen = 0;
|
||||
answer (DO, TN_SUPPRESS_GA);
|
||||
answer (WILL, TN_SUPPRESS_GA);
|
||||
answer (DO, TN_TRANSMIT_BINARY);
|
||||
answer (WILL, TN_TRANSMIT_BINARY);
|
||||
answer (DO, TN_ECHO);
|
||||
answer (WILL, TN_ECHO);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int read0 (char *buf, int len)
|
||||
{
|
||||
int n = 0, m;
|
||||
char *q, *p;
|
||||
static char telbuf[4];
|
||||
|
||||
while ((n == 0) && (n = read (0, buf + tellen, MBT_BUFSIZ - tellen)) > 0) {
|
||||
if (tellen) {
|
||||
memcpy(buf, telbuf, tellen);
|
||||
n += tellen;
|
||||
tellen = 0;
|
||||
}
|
||||
|
||||
if (memchr (buf, IAC, n)) {
|
||||
for (p = q = buf; n--; )
|
||||
if ((m = (unsigned char)*q++) != IAC)
|
||||
*p++ = m;
|
||||
else {
|
||||
if (n < 2) {
|
||||
memcpy (telbuf, q - 1, tellen = n + 1);
|
||||
break;
|
||||
}
|
||||
--n;
|
||||
switch (m = (unsigned char)*q++) {
|
||||
case WILL: m = (unsigned char)*q++; --n;
|
||||
Syslog('s', "TELNET: recv WILL %d", m);
|
||||
if (m != TN_TRANSMIT_BINARY && m != TN_SUPPRESS_GA && m != TN_ECHO)
|
||||
answer (DONT, m);
|
||||
break;
|
||||
case WONT: m = *q++;
|
||||
--n;
|
||||
Syslog('s', "TELNET: recv WONT %d", m);
|
||||
break;
|
||||
case DO: m = (unsigned char)*q++;
|
||||
--n;
|
||||
Syslog('s', "TELNET: recv DO %d", m);
|
||||
if (m != TN_TRANSMIT_BINARY && m != TN_SUPPRESS_GA && m != TN_ECHO)
|
||||
answer (WONT, m);
|
||||
break;
|
||||
case DONT: m = (unsigned char)*q++;
|
||||
--n;
|
||||
Syslog('s', "TELNET: recv DONT %d", m);
|
||||
break;
|
||||
case IAC: *p++ = IAC;
|
||||
break;
|
||||
default: Syslog('s', "TELNET: recv IAC %d", m);
|
||||
break;
|
||||
}
|
||||
}
|
||||
n = p - buf;
|
||||
}
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int write1 (char *buf, int len)
|
||||
{
|
||||
char *q;
|
||||
int k, l;
|
||||
|
||||
l = len;
|
||||
while ((len > 0) && (q = memchr(buf, IAC, len))) {
|
||||
k = (q - buf) + 1;
|
||||
if ((write (1, buf, k) != k) || (write (1, q, 1) != 1)) {
|
||||
return -1;
|
||||
}
|
||||
buf += k;
|
||||
len -= k;
|
||||
}
|
||||
|
||||
if ((len > 0) && write (1, buf, len) != len) {
|
||||
return -1;
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void com_gw(int in)
|
||||
{
|
||||
fd_set fds;
|
||||
int n, fdsbits;
|
||||
static struct timeval tout = { MBT_TIMEOUT, 0 };
|
||||
unsigned char buf[MBT_BUFSIZ];
|
||||
unsigned char buf[H_ZIPBUFLEN];
|
||||
|
||||
alarm(0);
|
||||
fdsbits = in + 1;
|
||||
@ -366,7 +223,7 @@ void com_gw(int in)
|
||||
if ((n = select(fdsbits, &fds, NULL, NULL, &tout)) > 0) {
|
||||
if (FD_ISSET(in, &fds)) {
|
||||
if ((n = read(in, buf, sizeof buf)) > 0) {
|
||||
if (write1(buf, n) < 0) {
|
||||
if (telnet_write(buf, n) < 0) {
|
||||
goto bad;
|
||||
}
|
||||
} else {
|
||||
@ -374,7 +231,7 @@ void com_gw(int in)
|
||||
}
|
||||
}
|
||||
if (FD_ISSET(0, &fds)) {
|
||||
if ((n = read0(buf, sizeof buf)) > 0) {
|
||||
if ((n = telnet_read(buf, sizeof buf)) > 0) {
|
||||
if (write(in, buf, n) < 0) goto bad;
|
||||
} else {
|
||||
goto bad;
|
||||
|
@ -221,42 +221,3 @@ void closetcp(void)
|
||||
}
|
||||
|
||||
|
||||
#ifdef USE_TELNET
|
||||
|
||||
#define WILL 251
|
||||
#define WONT 252
|
||||
#define DO 253
|
||||
#define DONT 254
|
||||
#define IAC 255
|
||||
|
||||
#define TOPT_BIN 0
|
||||
#define TOPT_ECHO 1
|
||||
#define TOPT_SUPP 3
|
||||
|
||||
|
||||
static void telnet_answer(int tag, int opt)
|
||||
{
|
||||
char buf[3];
|
||||
|
||||
Syslog('s', "telnet_answer(%d, %d)", tag, opt);
|
||||
buf[0]=IAC;
|
||||
buf[1]=tag;
|
||||
buf[2]=opt;
|
||||
tty_put(buf, 3);
|
||||
}
|
||||
|
||||
|
||||
void telnet_init(void)
|
||||
{
|
||||
Syslog('s', "telnet_init()");
|
||||
telnet_answer(DO,TOPT_SUPP);
|
||||
telnet_answer(WILL,TOPT_SUPP);
|
||||
telnet_answer(DO,TOPT_BIN);
|
||||
telnet_answer(WILL,TOPT_BIN);
|
||||
telnet_answer(DO,TOPT_ECHO);
|
||||
telnet_answer(WILL,TOPT_ECHO);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -6,8 +6,4 @@
|
||||
int opentcp(char *);
|
||||
void closetcp(void);
|
||||
|
||||
#ifdef USE_TELNET
|
||||
void telnet_init(void);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
249
mbcico/telnio.c
Normal file
249
mbcico/telnio.c
Normal file
@ -0,0 +1,249 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* $id$
|
||||
* Purpose ...............: Telnet IO filter
|
||||
*
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1997-2003
|
||||
*
|
||||
* 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/clcomm.h"
|
||||
#include "hydra.h"
|
||||
#include "telnio.h"
|
||||
|
||||
|
||||
static int tellen;
|
||||
|
||||
|
||||
|
||||
/* --- This is an artwork of serge terekhov, 2:5000/13@fidonet :) --- */
|
||||
|
||||
void telnet_answer(int tag, int opt)
|
||||
{
|
||||
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 (1, buf, 3) != 3)
|
||||
WriteError("$answer cant send");
|
||||
}
|
||||
|
||||
|
||||
|
||||
int telnet_init(void)
|
||||
{
|
||||
Syslog('s', "telnet_init()");
|
||||
tellen = 0;
|
||||
telnet_answer(DO, TOPT_SUPP);
|
||||
telnet_answer(WILL, TOPT_SUPP);
|
||||
telnet_answer(DO, TOPT_BIN);
|
||||
telnet_answer(WILL, TOPT_BIN);
|
||||
telnet_answer(DO, TOPT_ECHO);
|
||||
telnet_answer(WILL, TOPT_ECHO);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Read function for mbtelnetd
|
||||
*/
|
||||
int telnet_read(char *buf, int len)
|
||||
{
|
||||
int n = 0, m;
|
||||
char *q, *p;
|
||||
static char telbuf[4];
|
||||
|
||||
Syslog('s', "telnet_read(buf, %d tellen=%d)", len, tellen);
|
||||
while ((n == 0) && (n = read (0, buf + tellen, H_ZIPBUFLEN - tellen)) > 0) {
|
||||
|
||||
Syslog('s', " n=%d tellen=%d", n, tellen);
|
||||
if (n < 0) {
|
||||
Syslog('s', "telnet_read n=%d", n);
|
||||
return n;
|
||||
}
|
||||
|
||||
if (tellen) {
|
||||
Syslog('s', " memcpy");
|
||||
memcpy(buf, telbuf, tellen);
|
||||
n += tellen;
|
||||
tellen = 0;
|
||||
}
|
||||
|
||||
if (memchr (buf, IAC, n)) {
|
||||
Syslog('s', " IAC detected");
|
||||
for (p = q = buf; n--; )
|
||||
if ((m = (unsigned char)*q++) != IAC)
|
||||
*p++ = m;
|
||||
else {
|
||||
if (n < 2) {
|
||||
memcpy (telbuf, q - 1, tellen = n + 1);
|
||||
break;
|
||||
}
|
||||
--n;
|
||||
switch (m = (unsigned char)*q++) {
|
||||
case WILL: m = (unsigned char)*q++; --n;
|
||||
Syslog('s', "TELNET: recv WILL %d", m);
|
||||
if (m != TOPT_BIN && m != TOPT_SUPP && m != TOPT_ECHO)
|
||||
telnet_answer(DONT, m);
|
||||
break;
|
||||
case WONT: m = *q++;
|
||||
--n;
|
||||
Syslog('s', "TELNET: recv WONT %d", m);
|
||||
break;
|
||||
case DO: m = (unsigned char)*q++;
|
||||
--n;
|
||||
Syslog('s', "TELNET: recv DO %d", m);
|
||||
if (m != TOPT_BIN && m != TOPT_SUPP && m != TOPT_ECHO)
|
||||
telnet_answer(WONT, m);
|
||||
break;
|
||||
case DONT: m = (unsigned char)*q++;
|
||||
--n;
|
||||
Syslog('s', "TELNET: recv DONT %d", m);
|
||||
break;
|
||||
case IAC: Syslog('s', "TELNET: recv 2nd IAC %d", m);
|
||||
*p++ = IAC;
|
||||
break;
|
||||
default: Syslog('s', "TELNET: recv IAC %d", m);
|
||||
break;
|
||||
}
|
||||
}
|
||||
n = p - buf;
|
||||
}
|
||||
}
|
||||
|
||||
Syslog('s', " return n=%d", n);
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Telnet output filter, IAC characters are escaped.
|
||||
*/
|
||||
int telnet_write(char *buf, int len)
|
||||
{
|
||||
char *q;
|
||||
int k, l;
|
||||
|
||||
Syslog('s', "telnet_write(buf, %d)", len);
|
||||
l = len;
|
||||
while ((len > 0) && (q = memchr(buf, IAC, len))) {
|
||||
k = (q - buf) + 1;
|
||||
if ((write(1, buf, k) != k) || (write(1, q, 1) != 1)) {
|
||||
return -1;
|
||||
}
|
||||
buf += k;
|
||||
len -= k;
|
||||
}
|
||||
|
||||
if ((len > 0) && write(1, buf, len) != len) {
|
||||
return -1;
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int telnet_buffer(char *buf, int len)
|
||||
{
|
||||
int i, j, m = 0, rc;
|
||||
|
||||
rc = len;
|
||||
|
||||
if (memchr (buf, IAC, rc)) {
|
||||
Syslog('s', "telnet_buffer: IAC in input stream rc=%d", rc);
|
||||
// Syslogp('s', printable(buf, rc));
|
||||
j = 0;
|
||||
for (i = 0; i < rc; i++) {
|
||||
if ((buf[i] & 0xff) == IAC) {
|
||||
i++;
|
||||
switch (buf[i] & 0xff) {
|
||||
case WILL: i++;
|
||||
m = buf[i] & 0xff;
|
||||
Syslog('s', "Telnet recv WILL %d", m);
|
||||
if (m != TOPT_BIN && m != TOPT_SUPP && m != TOPT_ECHO)
|
||||
telnet_answer(DONT, m);
|
||||
break;
|
||||
case WONT: i++;
|
||||
m = buf[i] & 0xff;
|
||||
Syslog('s', "Telnet recv WONT %d", m);
|
||||
break;
|
||||
case DO: i++;
|
||||
m = buf[i] & 0xff;
|
||||
Syslog('s', "Telnet recv DO %d", m);
|
||||
if (m != TOPT_BIN && m != TOPT_SUPP && m != TOPT_ECHO)
|
||||
telnet_answer(WONT, m);
|
||||
break;
|
||||
case DONT: i++;
|
||||
m = buf[i] & 0xff;
|
||||
Syslog('s', "Telnet recv DONT %d", m);
|
||||
break;
|
||||
case IAC: buf[j] = buf[i];
|
||||
j++;
|
||||
Syslog('s', "Telnet recv escaped IAC");
|
||||
break;
|
||||
default: m = buf[i] & 0xff;
|
||||
Syslog('s', "TELNET: recv IAC %d, this is not good", m);
|
||||
buf[j] = IAC;
|
||||
j++;
|
||||
buf[j] = m;
|
||||
j++;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
buf[j] = buf[i];
|
||||
j++;
|
||||
}
|
||||
}
|
||||
rc = j;
|
||||
// Syslog('s', "new rc=%d", rc);
|
||||
// Syslogp('s', printable(buf, rc));
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
23
mbcico/telnio.h
Normal file
23
mbcico/telnio.h
Normal file
@ -0,0 +1,23 @@
|
||||
#ifndef _TELNIO_H
|
||||
#define _TELNIO_H
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
|
||||
#define MBT_WILL 251
|
||||
#define MBT_WONT 252
|
||||
#define MBT_DO 253
|
||||
#define MBT_DONT 254
|
||||
#define MBT_IAC 255
|
||||
|
||||
#define TOPT_BIN 0
|
||||
#define TOPT_ECHO 1
|
||||
#define TOPT_SUPP 3
|
||||
|
||||
void telnet_answer(int, int);
|
||||
int telnet_init(void);
|
||||
int telnet_read(char *, int);
|
||||
int telnet_write(char *, int);
|
||||
int telnet_buffer(char *, int);
|
||||
|
||||
#endif
|
206
mbcico/ttyio.c
206
mbcico/ttyio.c
@ -38,14 +38,17 @@
|
||||
#include "../lib/records.h"
|
||||
#include "../lib/common.h"
|
||||
#include "../lib/clcomm.h"
|
||||
#include "telnio.h"
|
||||
#include "ttyio.h"
|
||||
#include "lutil.h"
|
||||
|
||||
extern int hanged_up;
|
||||
extern int telnet;
|
||||
extern int master;
|
||||
extern char *inetaddr;
|
||||
|
||||
#define TT_BUFSIZ 1024
|
||||
#define NUMTIMERS 3
|
||||
#define TT_BUFSIZ 1024
|
||||
#define NUMTIMERS 3
|
||||
|
||||
|
||||
int tty_status = 0;
|
||||
@ -241,6 +244,10 @@ static int tty_read(char *buf, int size, int tot)
|
||||
Syslog('!', "tty_read: error flag");
|
||||
}
|
||||
rc=-tty_status;
|
||||
} else {
|
||||
if (master && telnet) {
|
||||
rc = telnet_buffer(buf, rc);
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
@ -253,7 +260,10 @@ int tty_write(char *buf, int size)
|
||||
int result;
|
||||
|
||||
tty_status=0;
|
||||
result = write(1,buf,size);
|
||||
if (telnet && master)
|
||||
result = telnet_write(buf, size);
|
||||
else
|
||||
result = write(1, buf, size);
|
||||
|
||||
if (result != size) {
|
||||
if (hanged_up || (errno == EPIPE) || (errno == ECONNRESET)) {
|
||||
@ -461,135 +471,141 @@ int tty_getc(int tot)
|
||||
|
||||
int tty_get(char *buf, int size, int tot)
|
||||
{
|
||||
int result=0;
|
||||
int result=0;
|
||||
|
||||
if (left >= size) {
|
||||
memcpy(buf,next,size);
|
||||
next += size;
|
||||
left -= size;
|
||||
return 0;
|
||||
}
|
||||
if (left >= size) {
|
||||
memcpy(buf,next,size);
|
||||
next += size;
|
||||
left -= size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (left > 0) {
|
||||
memcpy(buf,next,left);
|
||||
buf += left;
|
||||
next += left;
|
||||
size -= left;
|
||||
left=0;
|
||||
}
|
||||
if (left > 0) {
|
||||
memcpy(buf,next,left);
|
||||
buf += left;
|
||||
next += left;
|
||||
size -= left;
|
||||
left=0;
|
||||
}
|
||||
|
||||
while ((result=tty_read(buf,size,tot)) > 0) {
|
||||
buf += result;
|
||||
size -= result;
|
||||
}
|
||||
while ((result=tty_read(buf,size,tot)) > 0) {
|
||||
buf += result;
|
||||
size -= result;
|
||||
}
|
||||
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int tty_putc(int c)
|
||||
{
|
||||
char buf = c;
|
||||
char buf = c;
|
||||
|
||||
return tty_write(&buf,1);
|
||||
return tty_write(&buf,1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int tty_put(char *buf, int size)
|
||||
{
|
||||
return tty_write(buf,size);
|
||||
return tty_write(buf,size);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int tty_putget(char **obuf, int *osize, char **ibuf, int *isize)
|
||||
{
|
||||
time_t timeout, now;
|
||||
int i, rc;
|
||||
fd_set readfds, writefds, exceptfds;
|
||||
struct timeval seltimer;
|
||||
time_t timeout, now;
|
||||
int i, rc;
|
||||
fd_set readfds, writefds, exceptfds;
|
||||
struct timeval seltimer;
|
||||
|
||||
tty_status = 0;
|
||||
now = time(NULL);
|
||||
timeout = (time_t)300; /* maximum of 5 minutes */
|
||||
tty_status = 0;
|
||||
now = time(NULL);
|
||||
timeout = (time_t)300; /* maximum of 5 minutes */
|
||||
|
||||
for (i = 0; i < NUMTIMERS; i++) {
|
||||
if (timer[i]) {
|
||||
if (now >= timer[i]) {
|
||||
tty_status = STAT_TIMEOUT;
|
||||
WriteError("tty_putget: timer %d already expired, return",i);
|
||||
return -tty_status;
|
||||
} else {
|
||||
if (timeout > (timer[i]-now))
|
||||
timeout=timer[i]-now;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < NUMTIMERS; i++) {
|
||||
if (timer[i]) {
|
||||
if (now >= timer[i]) {
|
||||
tty_status = STAT_TIMEOUT;
|
||||
WriteError("tty_putget: timer %d already expired, return",i);
|
||||
return -tty_status;
|
||||
} else {
|
||||
if (timeout > (timer[i]-now))
|
||||
timeout=timer[i]-now;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Syslog('t', "tty_putget: timeout=%d",timeout);
|
||||
Syslog('t', "tty_putget: timeout=%d",timeout);
|
||||
|
||||
FD_ZERO(&readfds);
|
||||
FD_ZERO(&writefds);
|
||||
FD_ZERO(&exceptfds);
|
||||
FD_SET(0,&readfds);
|
||||
FD_SET(1,&writefds);
|
||||
FD_SET(0,&exceptfds);
|
||||
FD_SET(1,&exceptfds);
|
||||
seltimer.tv_sec=timeout;
|
||||
seltimer.tv_usec=0;
|
||||
FD_ZERO(&readfds);
|
||||
FD_ZERO(&writefds);
|
||||
FD_ZERO(&exceptfds);
|
||||
FD_SET(0,&readfds);
|
||||
FD_SET(1,&writefds);
|
||||
FD_SET(0,&exceptfds);
|
||||
FD_SET(1,&exceptfds);
|
||||
seltimer.tv_sec=timeout;
|
||||
seltimer.tv_usec=0;
|
||||
|
||||
rc=select(2,&readfds,&writefds,&exceptfds,&seltimer);
|
||||
if (rc < 0) {
|
||||
if (hanged_up) {
|
||||
tty_status=STAT_HANGUP;
|
||||
WriteError("tty_putget: hanged_up flag");
|
||||
} else {
|
||||
WriteError("$tty_putget: select failed");
|
||||
tty_status=STAT_ERROR;
|
||||
}
|
||||
} else if (rc == 0) {
|
||||
tty_status=STAT_TIMEOUT;
|
||||
rc=select(2,&readfds,&writefds,&exceptfds,&seltimer);
|
||||
if (rc < 0) {
|
||||
if (hanged_up) {
|
||||
tty_status=STAT_HANGUP;
|
||||
WriteError("tty_putget: hanged_up flag");
|
||||
} else {
|
||||
/* rc > 0 */
|
||||
if ((FD_ISSET(0,&exceptfds)) || (FD_ISSET(1,&exceptfds))) {
|
||||
WriteError("$tty_putget: exeption error");
|
||||
tty_status=STAT_ERROR;
|
||||
}
|
||||
WriteError("$tty_putget: select failed");
|
||||
tty_status=STAT_ERROR;
|
||||
}
|
||||
|
||||
if (tty_status) {
|
||||
Syslog('t', "tty_putget: return after select status %s",ttystat[tty_status]);
|
||||
return -tty_status;
|
||||
} else if (rc == 0) {
|
||||
tty_status=STAT_TIMEOUT;
|
||||
} else {
|
||||
/* rc > 0 */
|
||||
if ((FD_ISSET(0,&exceptfds)) || (FD_ISSET(1,&exceptfds))) {
|
||||
WriteError("$tty_putget: exeption error");
|
||||
tty_status=STAT_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (FD_ISSET(0,&readfds) && *isize) {
|
||||
rc=read(0,*ibuf,*isize);
|
||||
if (rc < 0) {
|
||||
WriteError("$tty_putget: read failed");
|
||||
tty_status=STAT_ERROR;
|
||||
} else {
|
||||
(*ibuf)+=rc;
|
||||
(*isize)-=rc;
|
||||
}
|
||||
if (tty_status) {
|
||||
Syslog('t', "tty_putget: return after select status %s",ttystat[tty_status]);
|
||||
return -tty_status;
|
||||
}
|
||||
|
||||
if (FD_ISSET(0,&readfds) && *isize) {
|
||||
rc = read(0, *ibuf, *isize);
|
||||
if (rc < 0) {
|
||||
WriteError("$tty_putget: read failed");
|
||||
tty_status=STAT_ERROR;
|
||||
} else {
|
||||
if (master && telnet) {
|
||||
rc = telnet_buffer(*ibuf, rc);
|
||||
}
|
||||
(*ibuf)+=rc;
|
||||
(*isize)-=rc;
|
||||
}
|
||||
}
|
||||
|
||||
if (FD_ISSET(1,&writefds) && *osize) {
|
||||
rc=write(1,*obuf,*osize);
|
||||
if (rc < 0) {
|
||||
WriteError("$tty_putget: write failed");
|
||||
tty_status=STAT_ERROR;
|
||||
} else {
|
||||
(*obuf)+=rc;
|
||||
(*osize)-=rc;
|
||||
}
|
||||
if (FD_ISSET(1,&writefds) && *osize) {
|
||||
if (telnet && master)
|
||||
rc = telnet_write(*obuf,*osize);
|
||||
else
|
||||
rc=write(1,*obuf,*osize);
|
||||
if (rc < 0) {
|
||||
WriteError("$tty_putget: write failed");
|
||||
tty_status=STAT_ERROR;
|
||||
} else {
|
||||
(*obuf)+=rc;
|
||||
(*osize)-=rc;
|
||||
}
|
||||
}
|
||||
|
||||
if (tty_status)
|
||||
return -tty_status;
|
||||
else
|
||||
return ((*isize == 0) | ((*osize == 0) << 1));
|
||||
if (tty_status)
|
||||
return -tty_status;
|
||||
else
|
||||
return ((*isize == 0) | ((*osize == 0) << 1));
|
||||
}
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user