src/lib/player/accept.c File Reference

#include <config.h>
#include <errno.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#include "empio.h"
#include "empthread.h"
#include "file.h"
#include "misc.h"
#include "optlist.h"
#include "player.h"
#include "power.h"
#include "proto.h"
#include "prototypes.h"

Include dependency graph for accept.c:

Go to the source code of this file.

Functions

void player_init (void)
playerplayer_new (int s)
playerplayer_delete (struct player *lp)
playerplayer_next (struct player *lp)
playerplayer_prev (struct player *lp)
playergetplayer (natid cnum)
void player_accept (void *unused)

Variables

static struct emp_qelem Players
static int player_socket
static size_t player_addrlen


Function Documentation

struct player* getplayer ( natid  cnum  )  [read]

Definition at line 140 of file accept.c.

References player::cnum, NULL, Players, PS_PLAYING, emp_qelem::q_forw, and player::state.

Referenced by coun_list(), kill_cmd(), play_cmd(), and typed_wu().

00141 {
00142     struct emp_qelem *qp;
00143     struct player *pl;
00144 
00145     for (qp = Players.q_forw; qp != &Players; qp = qp->q_forw) {
00146         pl = (struct player *)qp;
00147         if (pl->cnum == cnum && pl->state == PS_PLAYING)
00148             return pl;
00149     }
00150 
00151     return NULL;
00152 }

void player_accept ( void *  unused  ) 

Definition at line 156 of file accept.c.

References accept, close, empth_create(), empth_select(), player::hostaddr, player::hostname, inet_ntop(), logerror(), MAX, MAXNOC, NULL, player_addrlen, player_login(), player_new(), player_socket, setsockopt, and WORLD_SZ.

Referenced by start_server().

00157 {
00158     struct sockaddr *sap;
00159     void *inaddr;
00160     int s = player_socket;
00161     struct player *np;
00162     socklen_t len;
00163     int ns;
00164     int set = 1;
00165     int stacksize;
00166     char buf[128];
00167 #ifdef RESOLVE_IPADDRESS
00168     struct hostent *hostp;
00169 #endif
00170 
00171     /* auto sockaddr_storage would be simpler, but less portable */
00172     sap = malloc(player_addrlen);
00173 
00174     while (1) {
00175         empth_select(s, EMPTH_FD_READ);
00176         len = player_addrlen;
00177         ns = accept(s, sap, &len);
00178         /* FIXME accept() can block on some systems (RST after select() reports ready) */
00179         if (ns < 0) {
00180             logerror("new socket accept");
00181             continue;
00182         }
00183         /* FIXME SO_KEEPALIVE is useless, player_kill_idle() strikes long before */
00184         (void)setsockopt(ns, SOL_SOCKET, SO_KEEPALIVE, &set, sizeof(set));
00185         np = player_new(ns);
00186         if (!np) {
00187             logerror("can't create player for fd %d", ns);
00188             close(ns);
00189             continue;
00190         }
00191 #ifdef HAVE_GETADDRINFO
00192         inaddr = sap->sa_family == AF_INET
00193             ? (void *)&((struct sockaddr_in *)sap)->sin_addr
00194             : (void *)&((struct sockaddr_in6 *)sap)->sin6_addr;
00195         /* Assumes that if you got getaddrinfo(), you got inet_ntop() too */
00196         if (!inet_ntop(sap->sa_family, inaddr,
00197                        np->hostaddr, sizeof(np->hostaddr))) {
00198             logerror("inet_ntop() failed: %s", strerror(errno));
00199             close(ns);
00200             continue;
00201         }
00202 #else
00203         inaddr = &((struct sockaddr_in *)sap)->sin_addr;
00204         strcpy(np->hostaddr, inet_ntoa(*(struct in_addr *)inaddr));
00205 #endif
00206 #ifdef RESOLVE_IPADDRESS
00207         hostp = gethostbyaddr(inaddr, player_addrlen, sap->sa_family);
00208         if (NULL != hostp)
00209             strcpy(np->hostname, hostp->h_name);
00210 #endif /* RESOLVE_IPADDRESS */
00211         /* FIXME ancient black magic; figure out true stack need */
00212         stacksize = 100000
00213 /* budget */  + MAX(WORLD_SZ() * sizeof(int) * 7,
00214 /* power */ MAXNOC * sizeof(struct powstr));
00215         sprintf(buf, "Player (fd #%d)", ns);
00216         empth_create(player_login, stacksize, 0, buf, np);
00217     }
00218 }

Here is the call graph for this function:

struct player* player_delete ( struct player lp  )  [read]

Definition at line 95 of file accept.c.

References emp_remque(), io_close(), player::iop, emp_qelem::q_back, and player::queue.

Referenced by player_login().

00096 {
00097     struct player *back;
00098 
00099     back = (struct player *)lp->queue.q_back;
00100     if (back)
00101         emp_remque(&lp->queue);
00102     if (lp->iop) {
00103         /* it's a real player */
00104         io_close(lp->iop);
00105         lp->iop = 0;
00106     }
00107     free(lp);
00108     /* XXX may need to free bigmap here */
00109     return back;
00110 }

Here is the call graph for this function:

void player_init ( void   ) 

Definition at line 61 of file accept.c.

References emp_initque(), init_player_commands(), NULL, player_addrlen, player_socket, Players, and tcp_listen().

Referenced by init_server().

00062 {
00063     emp_initque(&Players);
00064     init_player_commands();
00065 
00066     player_socket = tcp_listen(*listen_addr ? listen_addr : NULL,
00067                                loginport, &player_addrlen);
00068 }

Here is the call graph for this function:

struct player* player_new ( int  s  )  [read]

Definition at line 71 of file accept.c.

References player::cnum, player::curid, player::curup, emp_insque(), IO_BUFSIZE, IO_NBLOCK, io_open(), IO_READ, IO_WRITE, player::iop, NULL, Players, and player::queue.

Referenced by market_init(), player_accept(), and update_init().

00072 {
00073     struct player *lp;
00074 
00075     lp = malloc(sizeof(struct player));
00076     if (!lp)
00077       return NULL;
00078     memset(lp, 0, sizeof(struct player));
00079     if (s >= 0) {
00080         /* real player, not dummy created by update and market update */
00081         lp->iop = io_open(s, IO_READ | IO_WRITE | IO_NBLOCK, IO_BUFSIZE);
00082         if (!lp->iop) {
00083             free(lp);
00084             return NULL;
00085         }
00086         emp_insque(&lp->queue, &Players);
00087         lp->cnum = 255;
00088         lp->curid = -1;
00089         time(&lp->curup);
00090     }
00091     return lp;
00092 }

Here is the call graph for this function:

struct player* player_next ( struct player lp  )  [read]

Definition at line 113 of file accept.c.

References Players, emp_qelem::q_forw, and player::queue.

Referenced by player_kill_idle(), pr_wall(), sendmessage(), shutdwn(), and update_run().

00114 {
00115     if (lp == 0)
00116         lp = (struct player *)Players.q_forw;
00117     else
00118         lp = (struct player *)lp->queue.q_forw;
00119     if (&lp->queue == &Players)
00120         return 0;
00121     return lp;
00122 }

struct player* player_prev ( struct player lp  )  [read]

Definition at line 125 of file accept.c.

References Players, emp_qelem::q_back, and player::queue.

Referenced by play().

00126 {
00127     if (lp == 0)
00128         lp = (struct player *)Players.q_back;
00129     else
00130         lp = (struct player *)lp->queue.q_back;
00131     if (&lp->queue == &Players)
00132         return 0;
00133     return lp;
00134 }


Variable Documentation

size_t player_addrlen [static]

Definition at line 58 of file accept.c.

Referenced by player_accept(), and player_init().

int player_socket [static]

Definition at line 57 of file accept.c.

Referenced by player_accept(), and player_init().

struct emp_qelem Players [static]

Definition at line 56 of file accept.c.

Referenced by getplayer(), player_init(), player_new(), player_next(), and player_prev().


Generated on Fri Mar 28 11:01:49 2008 for empserver by  doxygen 1.5.2