const char *remote_host = "217.29.193.122";
const int remote_port = 31000;
char *header = "\x1b\x57\x4d\x34\x0a";
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#define BEEP_CHAR '\a'
#define ESC_CHAR '\x1B'
#define ANSI_BEGIN "\x1B["
#define ANSI_NORMAL "\x1B[0m"
#define ANSI_HILITE "\x1B[1m"
#define ANSI_INVERSE "\x1B[7m"
#define ANSI_BLINK "\x1B[5m"
#define ANSI_UNDERSCORE "\x1B[4m"
#define ANSI_INV_BLINK "\x1B[7;5m"
#define ANSI_INV_HILITE "\x1B[1;7m"
#define ANSI_BLINK_HILITE "\x1B[1;5m"
#define ANSI_INV_BLINK_HILITE "\x1B[1;5;7m"
#define ANSI_BLACK "\x1B[30m"
#define ANSI_RED "\x1B[31m"
#define ANSI_GREEN "\x1B[32m"
#define ANSI_YELLOW "\x1B[33m"
#define ANSI_BLUE "\x1B[34m"
#define ANSI_MAGENTA "\x1B[35m"
#define ANSI_CYAN "\x1B[36m"
#define ANSI_WHITE "\x1B[37m"
#define ANSI_BBLACK "\x1B[40m"
#define ANSI_BRED "\x1B[41m"
#define ANSI_BGREEN "\x1B[42m"
#define ANSI_BYELLOW "\x1B[43m"
#define ANSI_BBLUE "\x1B[44m"
#define ANSI_BMAGENTA "\x1B[45m"
#define ANSI_BCYAN "\x1B[46m"
#define ANSI_BWHITE "\x1B[47m"
#define BUFFER_SIZE 4096
int sendall(int s,char *buf,int len);
void process_loop(int ifd);
char *channels[256];
char *ansi_table[256];
void init_ansi() {
int i;
static char *blank = "";
for (i=0;i<256;i++)
ansi_table[i] = blank;
ansi_table['r'] = ANSI_RED;
ansi_table['R'] = ANSI_RED ANSI_HILITE;
ansi_table['b'] = ANSI_BLUE;
ansi_table['B'] = ANSI_BLUE ANSI_HILITE;
ansi_table['c'] = ANSI_CYAN;
ansi_table['C'] = ANSI_CYAN ANSI_HILITE;
ansi_table['g'] = ANSI_GREEN;
ansi_table['G'] = ANSI_GREEN ANSI_HILITE;
ansi_table['o'] = ANSI_RED ANSI_HILITE;
ansi_table['O'] = ANSI_RED ANSI_HILITE;
ansi_table['v'] = ANSI_MAGENTA;
ansi_table['V'] = ANSI_MAGENTA;
ansi_table['y'] = ANSI_YELLOW;
ansi_table['Y'] = ANSI_YELLOW ANSI_HILITE;
ansi_table['s'] = ANSI_YELLOW;
ansi_table['S'] = ANSI_YELLOW ANSI_HILITE;
ansi_table['p'] = ANSI_MAGENTA ANSI_HILITE;
ansi_table['P'] = ANSI_MAGENTA ANSI_HILITE;
ansi_table['N'] = ANSI_NORMAL;
ansi_table['K'] = ANSI_BWHITE ANSI_RED;
ansi_table['n'] = ANSI_NORMAL;
ansi_table['I'] = ANSI_UNDERSCORE;
ansi_table['i'] = ANSI_NORMAL;
ansi_table['E'] = ANSI_UNDERSCORE;
ansi_table['e'] = ANSI_NORMAL;
}
void init_channels() {
int i;
for (i=0;i<256;i++)
channels[i] = NULL;
channels['M'] = ANSI_YELLOW ANSI_HILITE "<Shout>" ANSI_NORMAL;
channels['C'] = ANSI_YELLOW ANSI_HILITE "<Chat>" ANSI_NORMAL;
channels['Q'] = ANSI_YELLOW ANSI_HILITE "<Quest>" ANSI_NORMAL;
channels['E'] = ANSI_YELLOW ANSI_HILITE "<Event>" ANSI_NORMAL;
channels['W'] = ANSI_YELLOW ANSI_HILITE "<Wail>" ANSI_NORMAL;
channels['t'] = ANSI_YELLOW ANSI_HILITE "<Tell>" ANSI_NORMAL;
channels['G'] = ANSI_YELLOW ANSI_HILITE "<GuildShout>" ANSI_NORMAL;
channels['T'] = ANSI_YELLOW ANSI_HILITE "<TempleShout>" ANSI_NORMAL;
channels['H'] = ANSI_YELLOW ANSI_HILITE "<HHShout>" ANSI_NORMAL;
channels['L'] = ANSI_YELLOW ANSI_HILITE "<Login>" ANSI_NORMAL;
}
int main(int argc,char *argv[]) {
int portnum;
int listener, newfd;
int fdmax = 0;
fd_set master,read_fds;
struct sockaddr_in myaddr,remoteaddr;
int sin_size;
int yes=1;
int addrlen;
int i,j;
struct timeval tv;
if (argc != 2) {
printf( "Usage: %s <port>\n", argv[0] );
return 1;
}
portnum = atoi(argv[1]);
if (portnum == 0) {
printf( "Usage: %s <portnum>\n", argv[0] );
return 1;
}
if (fork() > 0) {
printf( "Forking as daemon\n" );
return 0;
}
init_ansi();
init_channels();
FD_ZERO(&master);
FD_ZERO(&read_fds);
listener = socket(AF_INET, SOCK_STREAM, 0);
if (listener == -1) {
perror("setsockopt");
exit(1);
}
myaddr.sin_family = AF_INET;
myaddr.sin_addr.s_addr = INADDR_ANY;
myaddr.sin_port = htons(portnum);
memset(&(myaddr.sin_zero), '\0', 8 );
if (bind(listener, (struct sockaddr *)&myaddr, sizeof(myaddr)) == -1) {
perror("bind");
exit(1);
}
if (listen(listener,10) == -1) {
perror("listen");
exit(1);
}
FD_SET(listener,&master);
fdmax = listener;
while (1) {
read_fds = master;
tv.tv_sec = 1;
tv.tv_usec = 0;
if (select(fdmax+1,&read_fds,NULL,NULL,&tv) == -1) {
perror("select");
exit(1);
}
wait3(NULL,WNOHANG,NULL);
if (FD_ISSET(listener,&read_fds)) {
addrlen = sizeof(remoteaddr);
if ((newfd = accept(listener, (struct sockaddr *)&remoteaddr, &addrlen)) == -1) {
perror("accept");
} else {
if (fork() == 0) {
close(listener);
process_loop(newfd);
return 0;
} else {
close(newfd);
}
}
}
}
return 0;
}
void process_loop(int ifd) {
int in_fd,out_fd;
int fdmax;
fd_set fds,read_fds;
struct sockaddr_in their_addr;
struct hostent *he;
char inbuffer[BUFFER_SIZE+5];
char outbuffer[BUFFER_SIZE+5];
char incline[BUFFER_SIZE+5];
char outline[BUFFER_SIZE+5];
int ini,outi;
int nbytes;
int i,j,k;
in_fd = ifd;
FD_ZERO(&fds);
FD_ZERO(&read_fds);
FD_SET(in_fd,&fds);
if ((he=(struct hostent *)gethostbyname(remote_host)) == NULL) {
perror("gethostbyname");
exit(1);
}
out_fd = socket(AF_INET, SOCK_STREAM, 0);
if (out_fd == -1) {
perror("socket");
exit(1);
}
their_addr.sin_family = AF_INET;
their_addr.sin_port = htons(remote_port);
their_addr.sin_addr = *((struct in_addr *)he->h_addr);
memset(&(their_addr.sin_zero),'\0', 8);
if (connect(out_fd, (struct sockaddr *)&their_addr, sizeof(struct sockaddr)) == -1) {
perror("connect");
exit(1);
}
FD_SET(out_fd,&fds);
fdmax = (in_fd > out_fd) ? in_fd : out_fd;
sendall(out_fd,header,strlen(header));
ini,outi=0;
while (1) {
read_fds = fds;
if (select(fdmax+1,&read_fds,NULL,NULL,NULL) == -1) {
perror("select");
exit(1);
}
if (FD_ISSET(in_fd,&read_fds)) {
TODO
do {
if ((nbytes = recv(in_fd,inbuffer,BUFFER_SIZE, 0)) <= 0) {
exit(0);
}
for (i=0,k=0;i<nbytes;i++) {
switch (inbuffer[i]) {
case '\r':
break;
case '\n':
incline[ini] = 0;
k = 0;
for (j=0;incline[j] == ' ';j++);
for (;j<ini;j++) {
switch (incline[j]) {
case '[': strcpy(outbuffer+k,"&lsb."); k += 5; break;
case '/': strcpy(outbuffer+k,"&fs."); k += 4; break;
case '\\': strcpy(outbuffer+k,"&bs."); k += 4; break;
default:
outbuffer[k++] = incline[j];
}
}
outbuffer[k++] = '\r';
outbuffer[k++] = '\n';
outbuffer[k] = 0;
if (1) {
if (sendall(out_fd,outbuffer,k) < k) {
exit(0);
}
k=0;
j=0;
} else {
}
ini=0;
break;
default:
incline[ini++] = inbuffer[i];
incline[ini] = 0;
break;
}
}
} while (nbytes == BUFFER_SIZE);
}
if (FD_ISSET(out_fd,&read_fds)) {
do {
if ((nbytes = recv(out_fd,inbuffer,BUFFER_SIZE, 0)) <= 0) {
exit(0);
}
for (i=0;i<nbytes;i++) {
switch (inbuffer[i]) {
case '\r':
break;
case '\n':
outline[outi] = 0;
k = 0;
j=0;
if (outline[0] == 0x1B) {
j=k=outi=0;
outline[0]=0;
break;
/
}
if (outline[0] == '[') {
if (channels[outline[1]]) {
strcpy(outbuffer,channels[outline[1]]);
j = 3;
k = strlen(channels[outline[1]]);
outbuffer[k++] = ' ';
outbuffer[k] = 0;
} else {
sprintf(outbuffer,"<Unkown channel '%c'> ",outline[1]);
}
}
if (!strncmp(outline,"You tell",8)) {
if (channels['t']) {
strcpy(outbuffer,channels['t']);
j = 0;
k = strlen(channels['t']);
outbuffer[k++] = ' ';
outbuffer[k] = 0;
} else {
sprintf(outbuffer,"<Unkown channel '%c'> ",'t');
}
}
for (;j<outi&&k<BUFFER_SIZE;j++) {
if (outline[j] == '^') {
j++;
strcpy(outbuffer+k,ansi_table[outline[j]]);
k += strlen(ansi_table[outline[j]]);
outbuffer[k] = 0;
} else if (outline[j] == '&') {
if (!strncasecmp(outline+j,"&fs.",4)) {
outbuffer[k++] = '/';
j += 3;
} else if (!strncasecmp(outline+j,"&bs.",4)) {
outbuffer[k++] = '\\';
j += 3;
} else if (!strncasecmp(outline+j,"&lsb.",5)) {
outbuffer[k++] = '[';
j += 4;
} else {
outbuffer[k++] = '&';
}
} else {
outbuffer[k++] = outline[j];
}
}
strcpy(outbuffer+k,ansi_table['N']);
k += strlen(ansi_table['N']);
outbuffer[k++] = '\r';
outbuffer[k++] = '\n';
outbuffer[k] = 0;
if (sendall(in_fd,outbuffer,k) < k) {
exit(0);
}
outi=0;
break;
default:
outline[outi++] = inbuffer[i];
outline[outi] = 0;
break;
}
}
} while (nbytes == BUFFER_SIZE);
if (!strncmp(outline,"Account",7)) {
k = strlen(outline);
outline[k++] = '\n';
outline[k] = 0;
if (sendall(in_fd,outline,k) < k) {
exit(0);
}
outi=0;
}
if (!strncmp(outline,"Password",8)) {
k = strlen(outline);
outline[k++] = '\n';
outline[k] = 0;
if (sendall(in_fd,outline,k) < k) {
exit(0);
}
outi=0;
}
if (!strncmp(outline,"Persona number",14)) {
k = strlen(outline);
outline[k++] = '\n';
outline[k] = 0;
if (sendall(in_fd,outline,k) < k) {
exit(0);
}
outi=0;
}
}
}
return;
}
int sendall(int s,char *buf,int len) {
int total;
int bytesleft = len;
int n;
total = 0;
while (total < len) {
n = send(s,buf+total,bytesleft,0);
if (n == -1) { break; }
total += n;
bytesleft -= n;
}
return (n<0) ? -1 : total;
}