/*  BUTTERX xterm summoning for gaim 
 *
 *unf. this plugin is completely unsafe.. and by unsafe i mean if
 * you use it and someone hax0rs j00 its your problem..
 * i wrote this because i had an SGI indy i wanted to share but was
 * behind a nat.. and unable to get an outside IP
 *
 * you should be able to maintain a normal conversation so long as it doesnt begin with
 * "LOGIN@"
 *
 *
 * you should be able to compile this for IPV6 using the -DENABLE_IPV6 flag
 * but i havnt tested it
 *
 * in order to stop someone from executing a command in the address name i filter
 * the users input thought gethostbyname() (or gethostbyname2() ) that way
 * if what they send isnt either an IP address or a hostname.. it just wont work
 * 
 * also added some logging.. should save everything to "butterx.log"
 *
 * building:
 * put butterx.c in GAIM_SOURCE_DIR/plugins
 * then "make butterx"
 *
 * portability:
 *
 * this was written on my sgi indy running linux (2.2.16) and gcc 2.95
 * should build on damn near anything that supports gaim
 *
 * let me know if you enjoy it..
 * moof
 * -phar (phar@thetransmission.net)
 */



#define GAIM_PLUGINS
#include "../src/gaim.h"

#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>


/* defines */
#define TAGLEN		6
#define LOGINTAG 	"LOGIN@"
#define RUNCOMMAND	"xterm -display %s:0 -e login"
#define LOGFILE		"butterx.log"

/* globals */
static FILE *logfile;


/* function defs */
static void da_hack(struct gaim_connection *gc, char **who, char **text,guint32 flags);
void gaim_plugin_remove();
char *description();
char *name();


/* 0xC0DE */
static void da_hack(struct gaim_connection *gc, char **who, char **text,guint32 flags){
struct conversation *c = find_conversation(*who);
char * buffer,*hostname, *stripped;
struct hostent *hp;
time_t logtime;
#ifdef IPV6_ENABLE
struct in6_addr addy;
char addrbuff[INET6_ADDRSTRLEN];
#else
struct in_addr addy;
char addrbuff[INET_ADDRSTRLEN];
#endif

	stripped = strip_html(*text);
	if(!memcmp(stripped, LOGINTAG, TAGLEN)){
		if(strlen(stripped) > TAGLEN){
			hostname = stripped + TAGLEN;
			buffer = malloc(TAGLEN + 255 + sizeof(RUNCOMMAND));//~30 is more then we need

#ifdef IPV6_ENABLE			
			hp = gethostbyname2(hostname, AF_INET6);
			if (hp != NULL)	memcpy((char *)&addy.s_addr, hp->h_addr, hp->h_length)
			else return;
			inet_ntop(AF_INET6 , &addy.s_addr, addrbuff,INET6_ADDRSTRLEN);
#else
			hp = gethostbyname(hostname);
			if (hp != NULL) memcpy((char *)&addy.s_addr, hp->h_addr_list[0], hp->h_length);
			else return;
			inet_ntop(AF_INET, &addy.s_addr, addrbuff,INET_ADDRSTRLEN);
#endif

			sprintf(buffer,RUNCOMMAND,addrbuff);
			time(&logtime);				
			fprintf(logfile, "%s Login request from username: %s, to address: %s (provided by user)\n",ctime(&logtime), c->name,addrbuff);

			g_free(stripped);	
			if(fork() == 0){
				system(buffer);		
				free(buffer);
				_exit(0);
			}
		}
	}
}



char *gaim_plugin_init(GModule *handle) {
	gaim_signal_connect(handle, event_im_recv, da_hack, NULL);
	logfile = fopen(LOGFILE,"a+");
	return NULL;
}


void gaim_plugin_remove(){
	fclose(logfile);
}

char *name() {return "x-term firewall hack v(1 * 10^-10)";}
char *description() {return "listens for the command LOGIN@address and then sends a login xterm to the specified address";}


