// Unix finger support for clients.
#include <mudlib.h>
#include <uid.h>
#include <net/socket.h>
#define WHO find_player( "no_one" )
#define TELL(x) if( WHO ) tell_object( WHO, (x) );
#define MYPORT 4343
mapping sockets;
int listen_fd;
void create() {
seteuid( ROOT_UID );
sockets = allocate_mapping( 5 );
}
void write_callback( int fd, string msg ) {
string txt;
int err;
if( sockets[fd]["pending"] ) {
txt = sockets[fd]["outgoing"];
err = socket_write( fd, txt );
if( err < 0 ) {
return;
}
TELL( sprintf( "socket_write( %d, %O )\n", fd, txt + "\n" ) );
sockets[fd]["pending"] = 0;
sockets[fd]["outgoing"] = "";
}
}
void read_callback( int fd, string msg ) {
/*
sockets[fd]["incoming"] += msg;
*/
message( "info", msg, sockets[fd]["object"] );
}
void close_callback( int fd ) {
string txt;
if ( !sockets[fd] ) return;
TELL( sprintf( "Closing socket %d\n", fd ) );
if( strlen( txt = sockets[fd]["incoming"] ) )
message( "info", txt, sockets[fd]["object"] );
map_delete( sockets, fd );
socket_close( fd );
}
int create_listen() {
int err;
listen_fd = socket_create( STREAM, "read_callback", "close_callback" );
if( listen_fd < 0 ) {
TELL( sprintf( "Error %d in socket_create()\n", listen_fd ) );
return 0;
}
err = socket_bind( listen_fd, MYPORT );
if( err < 0 ) {
TELL( sprintf( "Error %d in socket_bind()\n", err ) );
socket_close( listen_fd );
return 0;
}
err = socket_listen( listen_fd, "close_callback" );
if( err < 0 ) {
TELL( sprintf( "Error %d in socket_listen()\n", err ) );
socket_close( listen_fd );
return 0;
}
return listen_fd;
}
varargs
int create_socket( string dest, object ob ) {
int fd, err;
fd = socket_create( STREAM, "read_callback", "close_callback" );
if( fd < 0 ) {
TELL("create_socket: socket_create: " + socket_error(fd) + "\n");
return -1;
}
err = socket_connect( fd, dest, "read_callback", "write_callback" );
if( err != EESUCCESS ) {
socket_close( fd );
TELL("create_socket: socket_connect: " + (err) + "\n");
return -1;
}
sockets[fd] = allocate_mapping( 5 );
sockets[fd]["pending"] = 0;
sockets[fd]["outgoing"] = "";
sockets[fd]["incoming"] = "";
if( !ob ) ob = this_player();
sockets[fd]["object"] = ob;
call_out( "close_callback", 30, fd );
message( "info", "Socket: " + fd + " is ready for writes.\n",
this_player() );
return fd;
}
int write_socket( int fd, string msg ) {
int err;
if( !sockets[fd] ) return -1;
if( sockets[fd]["pending"] ) {
sockets[fd]["outgoing"] += msg;
} else {
err = socket_write( fd, msg + "\n" );
if( err < 0 ) {
TELL( sprintf( "socket_write() err %d\n", err ) );
sockets[fd]["pending"] = 1;
sockets[fd]["outgoing"] += msg;
return 2;
}
}
return 1;
}
void dump() {
printf( "%O\n", sockets );
}