/* Autoconf patching by David Hedbor, neotron@lysator.liu.se */
/*********************************************************************/
/* file: net.c - do all the net stuff */
/* TINTIN III */
/* (T)he K(I)cki(N) (T)ickin D(I)kumud Clie(N)t */
/* coded by peter unold 1992 */
/*********************************************************************/
#ifdef HAVE_STRING_H
#include <string.h>
#else
#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif
#endif
#include <ctype.h>
#include <sys/errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <signal.h>
#include "tintin.h"
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#include <arpa/inet.h>
#endif
/* NOTE! Some systems might require a #include <net/errno.h>,
* try adding this if you are really stuck and net.c won't compile.
* Thanks to Brian Ebersole [Harm@GrimneMUD] for this suggestion.
*/
void do_telnet_protecol();
extern int sessionsstarted, ticker_interrupted;
extern struct listnode *common_aliases, *common_actions, *common_subs;
extern struct session *sessionlist, *activesession;
extern int errno;
static void alarm_handler( /* void */ )
{
/* do nothing; the connect will fail, returning -1, with errno = EINTR */
}
/**************************************************/
/* try connect to the mud specified by the args */
/* return fd on success / 0 on failure */
/**************************************************/
int connect_mud(host, port, ses)
char *host;
char *port;
struct session *ses;
{
int sock, connectresult;
struct sockaddr_in sockaddr;
if (isdigit(*host)) /* interprete host part */
sockaddr.sin_addr.s_addr = inet_addr(host);
else {
struct hostent *hp;
if ((hp = gethostbyname(host)) == NULL) {
tintin_puts("#ERROR - UNKNOWN HOST.", ses);
prompt(NULL);
return 0;
}
memcpy((char *) &sockaddr.sin_addr, hp->h_addr, sizeof(sockaddr.sin_addr));
}
if (isdigit(*port))
sockaddr.sin_port = htons(atoi(port)); /* inteprete port part */
else {
tintin_puts("#THE PORT SHOULD BE A NUMBER.", ses);
prompt(NULL);
return 0;
}
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
syserr("socket");
sockaddr.sin_family = AF_INET;
tintin_puts("#Trying to connect..", ses);
/* ignore the alarm: it'll cause the connect to return -1 with errno=EINTR */
if (signal(SIGALRM, alarm_handler) < 0)
syserr("signal SIGALRM");
alarm(30); /* We'll allow connect to hang in 15seconds! NO MORE! */
#ifdef SOCKS
connectresult = Rconnect(sock, (struct sockaddr *) &sockaddr, sizeof(sockaddr));
#else
connectresult = connect(sock, (struct sockaddr *) &sockaddr, sizeof(sockaddr));
#endif
alarm(0);
if (connectresult) {
close(sock);
switch (errno) {
case EINTR:
tintin_puts("#CONNECTION TIMED OUT.", ses);
break;
case ECONNREFUSED:
tintin_puts("#ERROR - CONNECTION REFUSED.", ses);
break;
case ENETUNREACH:
tintin_puts("#ERROR - THE NETWORK IS NOT REACHABLE FROM THIS HOST.", ses);
break;
default:
tintin_puts("#Couldn't connect", ses);
}
prompt(NULL);
return 0;
}
return sock;
}
/************************************************************/
/* write line to the mud ses is connected to - add \n first */
/************************************************************/
void write_line_mud(line, ses)
char *line;
struct session *ses;
{
char outtext[BUFFER_SIZE + 2];
strcpy(outtext, line);
strcat(outtext, "\n\r");
if (write(ses->socket, outtext, strlen(outtext)) == -1)
syserr("write in write_to_mud");
}
/*******************************************************************/
/* read at most BUFFER_SIZE chars from mud - parse protecol stuff */
/*******************************************************************/
int read_buffer_mud(buffer, ses)
char *buffer;
struct session *ses;
{
int i, didget;
char tmpbuf[BUFFER_SIZE], *cpsource, *cpdest;
didget = read(ses->socket, tmpbuf, 512);
ses->old_more_coming = ses->more_coming;
if (didget == 512)
ses->more_coming = 1;
else
ses->more_coming = 0;
if (didget < 0)
return 0; /*syserr("read from socket"); we do this here instead - dunno quite
why, but i got some mysterious connection read by peer on some hps */
else if (didget == 0)
return 0;
else {
cpsource = tmpbuf;
cpdest = buffer;
i = didget;
while (i > 0) {
if (*(unsigned char *) cpsource == 255) {
do_telnet_protecol(*cpsource, *(cpsource + 1), *(cpsource + 2), ses);
i -= 3;
cpsource += 3;
}
else {
*cpdest++ = *cpsource++;
i--;
}
}
}
*cpdest = '\0';
return didget;
}
/*****************************************************************/
/* respond according to the telnet protecol - weeeeelllllll..... */
/*****************************************************************/
void do_telnet_protecol(dat0, dat1, dat2, ses)
int dat0;
int dat1;
int dat2;
struct session *ses;
{
/* we don't do anything here.. why should we? add the stuff yourself if
you feel like being nice..... */
}