/* highscore-server.c -- The hiscore server using TCP/IP stream. Created on: 2008/12/05 18:56:11 ~yas/dsys/highscore/tcp/highscore-server.c */ #include /* stderr, fprintf() */ #include /* strtol() */ #include /* memcpy() */ #include /* socket() */ #include /* socket() */ #include /* struct sockaddr_in, INADDR_ANY */ #include /* getnameinfo() */ #include "highscore-tcp.h" #include "marshaling-burffer.h" /* From Coins System Program */ extern int tcp_acc_port( int portno ); extern void tcp_peeraddr_print( int com ); extern void sockaddr_print( struct sockaddr *addrp, socklen_t addr_len ); extern int tcp_acc_port( int portno ); /* Hiscore data in memory */ static score_record_t hiscore_records[HIGHSCORE_MAX_RECORDS]; static int hiscore_nelements; static void hiscore_server( int portno ); static void hiscore_request_reply( int com ); static void print_my_host_port( int portno ); static int insert_score( score_record_t records[], int len, int nelement, int score, char *user ); static int find_posision( score_record_t records[], int len, int nelement, int score ); static void usage( char *comname ) { fprintf(stderr,"Usage: %% %s portno\n", comname); exit( 1 ); } main( int argc, char *argv[], char *envp[] ) { int portno; if( argc != 2 ) usage( argv[0] ); portno = strtol( argv[1], 0, 10 ); hiscore_server( portno ); } static void hiscore_server( int portno ) { int acc,com ; acc = tcp_acc_port( portno ); if( acc<0 ) exit( -1 ); print_my_host_port( portno ); printf("(To stop this server, Press ^C)\n"); while( 1 ) { if( (com = accept( acc,0,0 )) < 0 ) { perror("accept"); exit( -1 ); } tcp_peeraddr_print( com ); hiscore_request_reply( com ); } } static void hiscore_request_reply( int com ) { marbuf_t request, reply; int cmd; marbuf_init( &request,HISCORE_PROTO_MAX_MESSAGE_SIZE ); marbuf_init( &reply,HISCORE_PROTO_MAX_MESSAGE_SIZE ); if( marbuf_receive_message( &request, com ) < 0 ) { perror("read"); goto error0; } if( !marbuf_unmarshal_int( &request, &cmd ) ) { perror("request_msg cmd"); goto error0; } switch( cmd ) { case HISCORE_PROTO_PUT_SCORE: { int score ; char name[HIGHSCORE_NAME_LEN]; if( !marbuf_unmarshal_int( &request, &score ) ) goto error1; if( !marbuf_unmarshal_byte_array( &request, name, HIGHSCORE_NAME_LEN ) ) goto error1; hiscore_nelements = insert_score( hiscore_records, HIGHSCORE_MAX_RECORDS, hiscore_nelements, score, name ); if( !marbuf_marshal_int( &reply, HISCORE_PROTO_OK ) ) goto error1; break; } case HISCORE_PROTO_GET_HISCORE: { int len,i,n ; if( !marbuf_unmarshal_int( &request, &len ) ) goto error1; if( len > HIGHSCORE_MAX_RECORDS ) len = HIGHSCORE_MAX_RECORDS; n = len < hiscore_nelements ? len : hiscore_nelements ; /* return n and hiscore_records[0..n-1] to client. */ if( !marbuf_marshal_int( &reply, n ) ) goto error1; for( i=0 ; i