/* A listener port, by Tim of The Eternal Fantasy and TimMUD
 This will accept connections and then display what comes in, doesn't send anything back.

It will looks like this:

LISTENER Got a message of size [35] from fd [3]...
   0 [ 70: F] [111: o] [117: u] [114: r] [ 32:  ] [115: s] [ 99: c] [111: o] 
   8 [114: r] [101: e] [ 32:  ] [ 97: a] [110: n] [100: d] [ 32:  ] [115: s] 
  16 [101: e] [118: v] [101: e] [110: n] [ 32:  ] [121: y] [101: e] [ 97: a] 
  24 [114: r] [115: s] [ 32:  ] [ 97: a] [103: g] [111: o] [ 46: .] [ 46: .] 
  32 [ 46: .] [ 13:\r] [ 10:\n] 

*/

#ifndef STREAM_BINARY
#define STREAM_BINARY 3
#endif
#define PORT_NUMBER 12345
#define DEBUGGER "tim"

static private int listener_socket; // socket that the listener is using

void debug(string str){
	if(find_player(DEBUGGER)) tell_object(find_player(DEBUGGER),"LISTENER "+str);
//	log_file("server",str);
}

static void create(){ 
	seteuid(getuid());
	call_out("setup", 5);
}

static void setup(){
	int i;
	debug("Setting up sniffer at "+ctime(time())+"\n");
	if ((i=(listener_socket = socket_create(STREAM_BINARY, "read_callback", "close_callback"))) < 0){
		debug("setup: Failed to create socket, error:"+i+"\n");
		return;
	}
	debug("setup: created socket\n");
        if ((i=socket_bind(listener_socket, PORT_NUMBER)) < 0) {
                socket_close(listener_socket);
		debug("setup: Failed to bind socket to port, error:"+i+"\n");
		return;
	}
	debug("setup: bound socket, should be ready to connect to now\n");
	if ((i=socket_listen(listener_socket, "listen_callback")) < 0) {
		socket_close(listener_socket);
		debug("setup: Failed to listen to socket, error:"+i+"\n");
	}
}

static void listen_callback(int fd){
        int nfd;
        if ((nfd = socket_accept(fd, "read_callback", "write_callback")) < 0) {
		debug("listen_callback: socket_accept failed.\n");
		return;
	}
	debug("listen_callback: Accepted connection by fd:"+fd+"\n");
}

static void close_callback(int fd){
	debug("close_callback: Closed socket fd:"+fd+"\n");
}

string esc_char(int i){
	switch(i){
		case '\t': return "\\t";
		case '\a': return "\\a";
		case '\r': return "\\r";
		case '\n': return "\\n";
		default: return sprintf("%c",i);
	}
}

static void read_callback(int fd, buffer info){
	int i; string output="";
	output = "Got a message of size ["+sizeof(info)+"] from fd ["+fd+"]...";
		for(i=0;i<sizeof(info);i++){
			if(!(i%8)) output += sprintf("\n%4d ",i);
			output += sprintf("[%3d:%2s] ",info[i],esc_char(info[i]) );
		}
	output += "\n";
	debug(output);
//	socket_write(fd,info); //Uncomment this line if you want an echo server.
	return;
}

int query_prevent_shadow(object ob){ return 1; }