/* LPC4 has no automagic communication code, this file opens up a socket * and listens for connections from outside. When someone connects, * /secure/logon.c is cloned and given the input. Note that the socket * owernership never leaves this objects, thus, all communication is done * through this object. */ #include <socket.h> #include <arpa/telnet.h> #define PORT 1905 void low_tell_object(int fd,string s); int main_socket; object *players=allocate(256); string *cache=allocate(256); int *write_disallow=allocate(256); int num_players; object *users() { return players-({0}); } static void low_fflush(int fd) { string foo; if(foo=cache[fd]) { cache[fd]=0; low_tell_object(fd,foo); } if(!players[fd] && !cache[fd]) socket_close(fd); } void fflush(int fd) { if(previous_object()==players[fd]) low_fflush(fd); } static void player_close(int fd,string s) { write("Shutting down. ("+fd+")\n"); players[fd]->go_ld(fd); players[fd]=0; num_players--; } int do_exec(int fd,object to) { int foo; if(previous_object() && previous_object()==players[fd]) { players[fd]=to; foo=(int)to->take_a_socket(fd,this_object()); if(!foo) { players[fd]=previous_object(); return 0; } } return 1; } static void low_tell_object(int fd,string s) { int e; if(write_disallow[fd]) { cache[fd]=s; }else{ if((e=socket_write(fd,s))==EECALLBACK) { write_disallow[fd]=1; cache[fd]=""; } } } void tell_object(int fd,string s) { if(previous_object()!=players[fd]) { write("I think someone is trying to tell me something...\n"); write(fd+" "+s+"\n"); return; } if(stringp(cache[fd])) { cache[fd]+=s; return; } low_tell_object(fd,s); } static void player_write_callback(int fd) { write_disallow[fd]=0; low_fflush(fd); } void disconnect(int fd) { if(players[fd]==previous_object()) { players[fd]=0; low_fflush(fd); num_players--; } } static void player_write(int fd,string s) { if(s[0]==255) { write("Telnet junk ignored\n"); return; } sscanf(s,"%s ",s); low_fflush(fd); cache[fd]=""; players[fd]->catch_input(s); low_fflush(fd); } void player_read(int fd) { write("Stop that! ("+fd+")\n"); } void close(int fd) { write("Closing down.\n"); } static void connect(int s) { int err; object foo; if(s!=main_socket) { write("Foo?"); } err=socket_accept(s,player_write,player_write_callback); foo=clone_object("/secure/logon"); num_players++; players[err]=foo; foo->take_a_socket(err,this_object()); low_fflush(err); } void create() { int err; main_socket=socket_create(STREAM | BUFFERED_INPUT | BUFFERED_OUTPUT, player_read,close); if(main_socket<0) { write("Couldn't create socket.\n"); shutdown(); } /* write("Got socket ("+main_socket+")\n"); */ err=socket_bind(main_socket,PORT); if(EESUCCESS!=err) { write("Couldn't bind socket.\n"); write(socket_error(err)+"\n"); shutdown(); } write("Bound socket on port "+PORT+"\n"); err=socket_listen(main_socket,connect); if(EESUCCESS!=err) { write("Couldn't listen to socket.\n"); write(socket_error(err)+"\n"); shutdown(); } }