PDA

View Full Version : Connection Timed Out


Arachno331
11-14-2007, 12:43 AM
After trying to run my game the following error is logged:

Tue Nov 13 23:33:51 2007 [?:90.195.66.251:4122] Socket connection timed out in Do_get_socket_string.

So here is the code for socket.c, please help. :)

/*
* socket.c - routines to handle all socket matters for Phantasia
*/

#include "include.h"

extern void *Do_start_thread(void *c);
extern server_hook;
extern randData;

/************************************************************************
/
/ FUNCTION NAME: Do_initialize_socket(struct server_t *server)
/
/ FUNCTION: To initialize the program's socket
/
/ AUTHOR: Brian Kelly, 4/12/99
/
/ ARGUMENTS:
/ struct server_t *s - address of the server's main data strcture
/
/ RETURN VALUE:
/
/ MODULES CALLED: wmove(), _filbuf(), clearok(), waddstr(), wrefresh(),
/ wclrtoeol()
/
/ DESCRIPTION:
/ Read a string from the keyboard.
/ This routine is specially designed to:
/
/ - strip non-printing characters (unless Wizard)
/ - echo, if desired
/ - redraw the screen if CH_REDRAW is entered
/ - read in only 'mx - 1' characters or less characters
/ - nul-terminate string, and throw away newline
/
/ 'mx' is assumed to be at least 2.
/
*************************************************************************/

int Do_init_server_socket()
{
struct sockaddr_in bind_address;
char error_msg[SZ_ERROR_MESSAGE];
int the_socket, error, on=1;

/* create a socket */
errno = 0;
if ((the_socket=socket(AF_INET, SOCK_STREAM, 0)) == -1) {

sprintf(error_msg,
"[0.0.0.0:?] Socket creation failed in Do_init_server_socket: %s\n",
strerror(errno));

Do_log_error(error_msg);
exit(SOCKET_CREATE_ERROR);
}

error = setsockopt(the_socket, SOL_SOCKET, SO_REUSEADDR,
(char *) &on, sizeof(on));

if (error != 0) {

sprintf(error_msg, "[0.0.0.0:?] setsockopt failed with error code of %d in Do_init_server_socket.\n", error);

Do_log_error(error_msg);
exit(SOCKET_CREATE_ERROR);
}

/* set up the bind address */
bind_address.sin_family = AF_INET;
bind_address.sin_addr.s_addr = INADDR_ANY;
bind_address.sin_port = PHANTASIA_PORT;

/* bind to that socket */
error = bind(the_socket, (struct sockaddr *) &bind_address,
sizeof(bind_address));

if (error != 0) {

sprintf(error_msg, "[0.0.0.0:?] bind to socket failed with error code of %d in Do_init_server_socket.\n", error);

Do_log_error(error_msg);
exit(SOCKET_BIND_ERROR);
}

/* start listening on the socket */
error = listen(the_socket, SOMAXCONN);
if (error != 0) {

sprintf(error_msg, "[0.0.0.0:?] listen command failed with error code of %d in Do_init_server_socket\n", error);

Do_log_error(error_msg);
exit(SOCKET_LISTEN_ERROR);
}

if (error = fcntl(the_socket, F_SETOWN, getpid()) < 0) {

sprintf(error_msg, "[0.0.0.0:?] fcntl F_SETOWN failed with error code of %d in Do_init_server_socket.\n", error);

Do_log_error(error_msg);
exit(SOCKET_BIND_ERROR);
}

if (error = fcntl(the_socket, F_SETFL, O_ASYNC) < 0) {

sprintf(error_msg, "[0.0.0.0:?] fcntl F_SETFL failed with error code of %d in Do_init_server_socket.\n", error);

Do_log_error(error_msg);
exit(SOCKET_BIND_ERROR);
}

return the_socket; /* no problems */
}


/************************************************************************
/
/ FUNCTION NAME: Do_accept_connections(struct server_t *s)
/
/ FUNCTION: Create new games for new connections on the socket
/
/ AUTHOR: Brian Kelly, 4/12/99
/
/ ARGUMENTS:
/ struct server_t *s - address of the server's main data strcture
/
/ RETURN VALUE: int error
/
/ MODULES CALLED: wmove(), _filbuf(), clearok(), waddstr(), wrefresh(),
/ wclrtoeol()
/
/ DESCRIPTION:
/ Read a string from the keyboard.
/ This routine is specially designed to:
/
/ - strip non-printing characters (unless Wizard)
/ - echo, if desired
/ - redraw the screen if CH_REDRAW is entered
/ - read in only 'mx - 1' characters or less characters
/ - nul-terminate string, and throw away newline
/
/ 'mx' is assumed to be at least 2.
/
*************************************************************************/

int Do_accept_connections(struct server_t *s)
{
struct game_t *game_ptr;
struct client_t *client_ptr;
pthread_attr_t thread_attr;
size_t addrlen;
char error_msg[SZ_ERROR_MESSAGE];
int theError, on=1, terms, itemp;
char gethost_buffer[16384], *string_ptr, *string_ptr_two;
struct hostent *host_info, host_buffer;
struct in_addr theNetwork;

while (Do_check_socket(s->the_socket)) {

/* on a new connection, seed the random number generator */
srandom_r (time(NULL), (struct random_data *)&randData);

/* create a structure for the thread information */
client_ptr = (struct client_t *) Do_malloc(SZ_CLIENT);

/* accept the new connection */
addrlen = sizeof(client_ptr->address);

errno = 0;
client_ptr->socket = accept(s->the_socket,
(struct sockaddr *)&client_ptr->address, &addrlen);

if (client_ptr->socket == -1) {

sprintf(error_msg,
"[0.0.0.0:%d] accept socket failed in Do_accept_connections: %s.\n",
s->realm.serverPid, strerror(errno));

Do_log_error(error_msg);
free((void *)client_ptr);
return SOCKET_ACCEPT_ERROR;
}

/* log the connection */
sprintf(error_msg, "New connection on socket %d.\n",
client_ptr->socket);

Do_log(SERVER_LOG, error_msg);

/* set the socket variables */
client_ptr->socket_up = TRUE;
client_ptr->out_buffer_size = 0;
client_ptr->in_buffer_size = 0;
client_ptr->date_connected = time(NULL);
client_ptr->run_level = SIGNING_IN;
client_ptr->machineID = 0;
client_ptr->events = NULL;
client_ptr->channel = 1;
client_ptr->timeout = 120;
client_ptr->timeoutFlag = 0;
client_ptr->broadcast = FALSE;
client_ptr->stuck = FALSE;
client_ptr->knightEnergy = 0;
client_ptr->knightQuickness = 0;
client_ptr->ageCount = 0;
client_ptr->morgothCount = 0;
client_ptr->suspended = FALSE;
client_ptr->accountLoaded = FALSE;
client_ptr->characterLoaded = FALSE;
client_ptr->characterAnnounced = FALSE;
client_ptr->muteUntil = 0;
client_ptr->tagUntil = 0;
client_ptr->hearBroadcasts = TRUE;
client_ptr->swearCount = 0;
client_ptr->battle.rounds = 0;
client_ptr->battle.timeouts = 0;
client_ptr->previousName[0] = '\0';
client_ptr->wizaccount[0] = '\0';
client_ptr->wizIP[0] = '\0';

for (terms = 0; terms < 10; terms++) {
client_ptr->chatTimes[terms] = 0;
client_ptr->chatLength[terms] = 0;
}


/* set the from and name fields */
/* determine the dns entry of this connection */
/* I've had major problems getting the reentrant fuction
working with linux as it is not standard. I hope the normal
function run in main process is okay */
host_info = NULL;
theError = 0;
/*
gethostbyaddr_r((char *)&client_ptr->address.sin_addr,
sizeof(client_ptr->address.sin_addr), AF_INET, &host_buffer,
gethost_buffer, 16384, &host_info, &theError);
*/

/*
errno = 0;
host_info = gethostbyaddr((char *)&client_ptr->address.sin_addr,
sizeof(client_ptr->address.sin_addr), AF_INET);
theError = errno;
*/

/* if we received host information */
if (host_info != NULL) {

/* copy over the hostname */
strncpy(&client_ptr->IP, host_info->h_name, SZ_FROM - 1);
client_ptr->IP[SZ_FROM - 1] = '\0';

/* determine the network address of this connection */
string_ptr = client_ptr->IP;

/* skip the first term (assume host name) */
while (*string_ptr != '\0' && *string_ptr++ != '.') {}

/* if we found a null, there is no network (local machine) */
if (*string_ptr == '\0') {
strncpy(client_ptr->network, client_ptr->IP, SZ_FROM - 1);
client_ptr->network[SZ_FROM - 1] = '\0';
client_ptr->addressResolved = FALSE;
}
else {
/* count the number or remaining terms */
terms = 1;
string_ptr_two = string_ptr;
while (*string_ptr_two != '\0') {

if (*string_ptr_two++ == '.')
++terms;
}

/* remove terms until we find one without numbers or hex or
we have only two terms left */

string_ptr_two = string_ptr;
while (*string_ptr != '\0' || terms > 2) {

if (isxdigit(*string_ptr)) {
++string_ptr;
}
else if (*string_ptr == '.') {
string_ptr_two = ++string_ptr;
}
else {
break;
}
}

/* put this shortened hostname into place */
strncpy(client_ptr->network, string_ptr_two, SZ_FROM - 1);
client_ptr->network[SZ_FROM - 1];
client_ptr->addressResolved = TRUE;
}
}
else {
/* use the IP address */
string_ptr = (char *) inet_ntoa(client_ptr->address.sin_addr);
strncpy(client_ptr->IP, string_ptr, SZ_FROM - 1);
client_ptr->IP[SZ_FROM - 1] = '\0';

/* get the class C network address */
theNetwork.s_addr = client_ptr->address.sin_addr.s_addr &
0x00FFFFFF;

client_ptr->addressResolved = FALSE;

string_ptr = (char *) inet_ntoa(theNetwork);
strncpy(client_ptr->network, string_ptr, SZ_FROM - 1);
client_ptr->network[SZ_FROM - 1] = '\0';

/* stop logging this an an error - too common */
/*
sprintf(error_msg,
"[%s:?] gethostbyaddress returned error %d in Do_accept_connections.\n",
client_ptr->IP, theError);

Do_log_error(error_msg);
*/
}

sprintf(error_msg, "Connection, IP=%s, Network=%s.\n", client_ptr->IP, client_ptr->network);

Do_log(DEBUG_LOG, error_msg);

/* create a new game object */
game_ptr = (struct game_t *) Do_malloc(SZ_GAME);

/* set up the game variables */
game_ptr->cleanup_thread = FALSE;
game_ptr->virtual = FALSE;
game_ptr->hearAllChannels = HEAR_SELF;
game_ptr->chatFilter = TRUE;
game_ptr->sendEvents = FALSE;
game_ptr->the_socket = client_ptr->socket;
game_ptr->description = NULL;
game_ptr->it_combat = NULL;
game_ptr->events_in = NULL;
game_ptr->account[0] = '\0';
strcpy(game_ptr->IP, client_ptr->IP);
strcpy(game_ptr->network, client_ptr->network);
game_ptr->machineID = 0;

/* initialize the event queue locks */
Do_init_mutex(&game_ptr->events_in_lock);

/* lock the game list */
Do_lock_mutex(&s->realm.realm_lock);

/* put the temp game into the list of games */
game_ptr->next_game = s->realm.games;
s->realm.games = game_ptr;

/* unlock the game list */
Do_unlock_mutex(&s->realm.realm_lock);

/* init the pthread_att strcture */
theError = pthread_attr_init(&thread_attr);
if (theError) {

sprintf(error_msg, "[0.0.0.0:%d] init of pthread_attr_t failed with error code of %d in Do_accept_connections.\n", s->realm.serverPid, theError);

Do_log_error(error_msg);
free((void *)client_ptr);
return PTHREAD_ATTR_ERROR;
}
/*
pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED);
pthread_attr_setstacksize(&thread_attr, 0xfffffff);
*/

/* set up all information to be passed to the thread */
client_ptr->realm = &s->realm;
client_ptr->game = game_ptr;

/* create the new thread */
theError = pthread_create(&game_ptr->the_thread, NULL,
Do_start_thread, (void *)client_ptr);

if (theError) {

sprintf(error_msg, "[0.0.0.0:%d] thread creation failed with an error code of %d in Do_accept_connections.\n", s->realm.serverPid, theError);

Do_log_error(error_msg);
free((void *)client_ptr);
return PTHREAD_CREATE_ERROR;
}

++s->num_games;
}

return 0;
}


/************************************************************************
/
/ FUNCTION NAME: Do_check_socket(int the_socket)
/
/ FUNCTION: Checks for data waiting on the socket
/
/ AUTHOR: Brian Kelly, 4/23/99
/
/ ARGUMENTS:
/ int the_socket - the socket to check for data
/
/ RETURN VALUE:
/ bool - true if there is data waiting on the socket
/
/ MODULES CALLED: wmove(), _filbuf(), clearok(), waddstr(), wrefresh(),
/ wclrtoeol()
/
/ DESCRIPTION:
/ Read a string from the keyboard.
/ This routine is specially designed to:
/
*************************************************************************/

int Do_check_socket(int the_socket)
{
fd_set rmask;
static struct timeval timeout = { 0, 0 }; /* no timeout */
char error_msg[SZ_ERROR_MESSAGE];
int error;

/* set rmask to check our socket */
FD_ZERO(&rmask);
FD_SET(the_socket, &rmask);

/* check for connections to be accepted */
error = select(the_socket + 1, &rmask, 0, 0, &timeout);
if (error < 0) {

sprintf(error_msg, "[0.0.0.0:?] select on socket failed with error code of %d in Do_check_socket\n", error);

Do_log_error(error_msg);
exit(SOCKET_SELECT_ERROR);
}

/* if select found no matches, return */
if (error == 0) {
return FALSE;
}

/* if our socket flag is not set, something is wrong */
if (!FD_ISSET(the_socket, &rmask)) {

sprintf(error_msg, "[0.0.0.0:?] select returned %d, but socket flag is off in Do_check_socket.\n", error);

Do_log_error(error_msg);
exit (SOCKET_SELECT_ERROR);
}
return TRUE;
}


/************************************************************************
/
/ FUNCTION NAME: Do_send_buffer(int the_socket)
/
/ FUNCTION: Send data over the socket to the player
/
/ AUTHOR: Brian Kelly, 4/23/99
/
/ ARGUMENTS:
/ int the_socket - the socket to send the information on
/ size_t the_size - the number of byest to send
/ void *the_data - a pointer to the data to be sent
/
/ RETURN VALUE: none
/
/ MODULES CALLED: wmove(), _filbuf(), clearok(), waddstr(), wrefresh(),
/ wclrtoeol()
/
/ DESCRIPTION:
/ Read a string from the keyboard.
/ This routine is specially designed to:
/
*************************************************************************/

Do_send_buffer(struct client_t *c)
{
/*
char error_msg[SZ_ERROR_MESSAGE];
*/
char error_msg[2048];
int bytes_sent;

if (c->socket_up && c->out_buffer_size > 0) {

/* send off the data */
errno = 0;
c->out_buffer[c->out_buffer_size] = '\0';

#ifdef SEND_DEBUG
sprintf(error_msg, "[%s] sending %d bytes\n", c->connection_id,
c->out_buffer_size);

Do_log(DEBUG_LOG, error_msg);
#endif

#ifdef SEND_PACKET_DEBUG
sprintf(error_msg, "[%s] (%s)\n", c->connection_id, c->out_buffer);
Do_log(DEBUG_LOG, error_msg);
#endif


bytes_sent = send(c->socket, c->out_buffer, c->out_buffer_size, 0);

if (bytes_sent != c->out_buffer_size) {

sprintf(error_msg,
"[%s] send on socket sent %d out of %d bytes in Do_send_buffer: %s.\n",
c->connection_id, bytes_sent, c->out_buffer_size, strerror(errno));

Do_log_error(error_msg);
c->socket_up = FALSE;

sprintf(error_msg, "[%s] Error on socket while sending.\n",
c->connection_id);

Do_log(CONNECTION_LOG, error_msg);

}
c->out_buffer_size = 0;
}

return;
}


/************************************************************************
/
/ FUNCTION NAME: Do_send_out(struct client_t *c, void *the_data, size_t the_size)
/
/ FUNCTION: Send data over the socket to the player
/
/ AUTHOR: Brian Kelly, 5/6/99
/
/ ARGUMENTS:
/ int the_socket - the socket to send the information on
/ size_t the_size - the number of byest to send
/ void *the_data - a pointer to the data to be sent
/
/ RETURN VALUE: none
/
/ MODULES CALLED: wmove(), _filbuf(), clearok(), waddstr(), wrefresh(),
/ wclrtoeol()
/
/ DESCRIPTION:
/ Read a string from the keyboard.
/ This routine is specially designed to:
/
*************************************************************************/

Do_send_out(struct client_t *c, void *the_data, size_t the_size)
{
char error_msg[SZ_ERROR_MESSAGE];
char string_buffer[SZ_LINE], string_buffer2[SZ_LINE];

if (c->socket_up) {

if (the_size > SZ_OUT_BUFFER) {

sprintf(error_msg,
"[%s] buffer_out overflow with %d bytes in Do_send_out.\n",
c->connection_id, the_size);

Do_log_error(error_msg);
Do_send_error(c, error_msg);
c->socket_up = FALSE;
return;
}

if (the_size + c->out_buffer_size > SZ_OUT_BUFFER) {
Do_send_buffer(c);

if (the_size + c->out_buffer_size > SZ_OUT_BUFFER) {
return;
}
}

#ifdef SEND_QUEUE_DEBUG
memcpy(string_buffer, the_data, the_size);

/* remove the "\n" */
string_buffer[the_size - 1] = '\0';

sprintf(string_buffer2, "[%s] Queued (%s)\n", c->connection_id,
string_buffer);

Do_log(DEBUG_LOG, string_buffer2);
#endif

memcpy(&c->out_buffer[c->out_buffer_size], the_data, the_size);
c->out_buffer_size += the_size;

}

return;
}


/************************************************************************
/
/ FUNCTION NAME: Do_send_string(struct client_t *c, char *theMessage)
/
/ FUNCTION: Send data over the socket to the player
/
/ AUTHOR: Brian Kelly, 8/11/99
/
/ ARGUMENTS:
/ int the_socket - the socket to send the information on
/ size_t the_size - the number of byest to send
/ void *the_data - a pointer to the data to be sent
/
/ RETURN VALUE: none
/
/ MODULES CALLED: wmove(), _filbuf(), clearok(), waddstr(), wrefresh(),
/ wclrtoeol()
/
/ DESCRIPTION:
/ Read a string from the keyboard.
/ This routine is specially designed to:
/
*************************************************************************/

Do_send_string(struct client_t *c, char *theMessage)
{
int theSize;

/* determine the string size */
theSize = strlen(theMessage);

/* send the data */
Do_send_out(c, theMessage, theSize);

return;
}


/************************************************************************
/
/ FUNCTION NAME: Do_send_double(struct client_t *c, double theDouble)
/
/ FUNCTION: Send data over the socket to the player
/
/ AUTHOR: Brian Kelly, 8/13/99
/
/ ARGUMENTS:
/ int the_socket - the socket to send the information on
/ size_t the_size - the number of byest to send
/ void *the_data - a pointer to the data to be sent
/
/ RETURN VALUE: none
/
/ MODULES CALLED: wmove(), _filbuf(), clearok(), waddstr(), wrefresh(),
/ wclrtoeol()
/
/ DESCRIPTION:
/ Read a string from the keyboard.
/ This routine is specially designed to:
/
*************************************************************************/

Do_send_double(struct client_t *c, double theDouble)
{
char tmpDouble[SZ_NUMBER];

/* determine the string size */
sprintf(tmpDouble, "%0.lf\n", theDouble);

/* send the data */
Do_send_string(c, tmpDouble);

return;
}

Arachno331
11-14-2007, 12:45 AM
/************************************************************************
/
/ FUNCTION NAME: Do_send_float(struct client_t *c, float theFloat)
/
/ FUNCTION: Send data over the socket to the player
/
/ AUTHOR: Brian Kelly, 8/13/99
/
/ ARGUMENTS:
/ int the_socket - the socket to send the information on
/ size_t the_size - the number of byest to send
/ void *the_data - a pointer to the data to be sent
/
/ RETURN VALUE: none
/
/ MODULES CALLED: wmove(), _filbuf(), clearok(), waddstr(), wrefresh(),
/ wclrtoeol()
/
/ DESCRIPTION:
/ Read a string from the keyboard.
/ This routine is specially designed to:
/
*************************************************************************/

Do_send_float(struct client_t *c, double theFloat)
{
char tmpFloat[SZ_NUMBER];

/* determine the string size */
sprintf(tmpFloat, "%0.lf\n", theFloat);

/* send the data */
Do_send_string(c, tmpFloat);

return;
}


/************************************************************************
/
/ FUNCTION NAME: Do_send_fpfloat(struct client_t *c, float theFloat)
/
/ FUNCTION: Send a full-precision float to the client
/
/ AUTHOR: Brian Kelly, 8/25/99
/
/ ARGUMENTS:
/ int the_socket - the socket to send the information on
/ size_t the_size - the number of byest to send
/ void *the_data - a pointer to the data to be sent
/
/ RETURN VALUE: none
/
/ MODULES CALLED: wmove(), _filbuf(), clearok(), waddstr(), wrefresh(),
/ wclrtoeol()
/
/ DESCRIPTION:
/ Read a string from the keyboard.
/ This routine is specially designed to:
/
*************************************************************************/

Do_send_fpfloat(struct client_t *c, double theFloat)
{
char tmpFloat[SZ_NUMBER];

/* determine the string size */
sprintf(tmpFloat, "%.4lf\n", theFloat);

/* send the data */
Do_send_string(c, tmpFloat);

return;
}


/************************************************************************
/
/ FUNCTION NAME: Do_send_int(struct client_t *c, int theInt)
/
/ FUNCTION: Send data over the socket to the player
/
/ AUTHOR: Brian Kelly, 8/13/99
/
/ ARGUMENTS:
/ int the_socket - the socket to send the information on
/ size_t the_size - the number of byest to send
/ void *the_data - a pointer to the data to be sent
/
/ RETURN VALUE: none
/
/ MODULES CALLED: wmove(), _filbuf(), clearok(), waddstr(), wrefresh(),
/ wclrtoeol()
/
/ DESCRIPTION:
/ Read a string from the keyboard.
/ This routine is specially designed to:
/
*************************************************************************/

Do_send_int(struct client_t *c, int theInt)
{
char tmpInt[SZ_NUMBER];

/* determine the string size */
sprintf(tmpInt, "%d\n", theInt);

/* send the data */
Do_send_string(c, tmpInt);

return;
}


/************************************************************************
/
/ FUNCTION NAME: Do_send_short(struct client_t *c, short theShort)
/
/ FUNCTION: Send data over the socket to the player
/
/ AUTHOR: Brian Kelly, 8/13/99
/
/ ARGUMENTS:
/ int the_socket - the socket to send the information on
/ size_t the_size - the number of byest to send
/ void *the_data - a pointer to the data to be sent
/
/ RETURN VALUE: none
/
/ MODULES CALLED: wmove(), _filbuf(), clearok(), waddstr(), wrefresh(),
/ wclrtoeol()
/
/ DESCRIPTION:
/ Read a string from the keyboard.
/ This routine is specially designed to:
/
*************************************************************************/

Do_send_short(struct client_t *c, short theShort)
{
char tmpShort[SZ_NUMBER];

/* determine the string size */
sprintf(tmpShort, "%hd\n", theShort);

/* send the data */
Do_send_string(c, tmpShort);

return;
}


/************************************************************************
/
/ FUNCTION NAME: Do_send_bool(struct client_t *c, bool theBool)
/
/ FUNCTION: Send data over the socket to the player
/
/ AUTHOR: Brian Kelly, 8/13/99
/
/ ARGUMENTS:
/ int the_socket - the socket to send the information on
/ size_t the_size - the number of byest to send
/ void *the_data - a pointer to the data to be sent
/
/ RETURN VALUE: none
/
/ MODULES CALLED: wmove(), _filbuf(), clearok(), waddstr(), wrefresh(),
/ wclrtoeol()
/
/ DESCRIPTION:
/ Read a string from the keyboard.
/ This routine is specially designed to:
/
*************************************************************************/

Do_send_bool(struct client_t *c, short theBool)
{
if (theBool == FALSE)

/* send the data */
Do_send_string(c, "No\n");
else

/* send the data */
Do_send_string(c, "Yes\n");

return;
}


/************************************************************************
/
/ FUNCTION NAME: Do_send_error(struct client_t *c, char *theError)
/
/ FUNCTION: Send data over the socket to the player
/
/ AUTHOR: Brian Kelly, 10/2/99
/
/ ARGUMENTS:
/ int the_socket - the socket to send the information on
/ size_t the_size - the number of byest to send
/ void *the_data - a pointer to the data to be sent
/
/ RETURN VALUE: none
/
/ MODULES CALLED: wmove(), _filbuf(), clearok(), waddstr(), wrefresh(),
/ wclrtoeol()
/
/ DESCRIPTION:
/ Read a string from the keyboard.
/ This routine is specially designed to:
/
*************************************************************************/

Do_send_error(struct client_t *c, char *theError)
{
Do_send_int(c, ERROR_PACKET);
Do_send_string(c, theError);
Do_send_buffer(c);
return;
}


/************************************************************************
/
/ FUNCTION NAME: Do_read_socket(struct client_t *c)
/
/ FUNCTION: Send data over the socket to the player
/
/ AUTHOR: Brian Kelly, 4/24/99
/
/ ARGUMENTS:
/ int the_socket - the socket to read data from
/ size_t the_size - the number of bytes to read from the socket
/ void *the_data - a pointer to the data to be read
/
/ RETURN VALUE: none
/
/ MODULES CALLED: wmove(), _filbuf(), clearok(), waddstr(), wrefresh(),
/ wclrtoeol()
/
/ DESCRIPTION:
/ Read a string from the keyboard.
/ This routine is specially designed to:
/
*************************************************************************/

Do_read_socket(struct client_t *c)
{
char error_msg[SZ_ERROR_MESSAGE];
int bytes_read;
struct event_t *event_ptr;

errno = 0;

/* read the data from the socket */
bytes_read = recv(c->socket, &c->in_buffer[c->in_buffer_size],
(SZ_IN_BUFFER - c->in_buffer_size), 0);

if (bytes_read <= 0) {

/* the socket is no longer any good */
c->socket_up = FALSE;

/* if client closed abruptly, the connection will be reset */
if (errno = ECONNRESET) {

/* Error too common for the error log */
/*
sprintf(error_msg,
"[%s] Received a ECONNRESET on socket in Do_read_socket.\n",
c->connection_id);

Do_log_error(error_msg);
*/
}
else {

sprintf(error_msg,
"[%s] read on socket returned %d bytes in Do_read_socket: %s\n",
c->connection_id, bytes_read, strerror(errno));

Do_log_error(error_msg);
}

sprintf(error_msg, "[%s] Received an error on the socket.\n",
c->connection_id);

Do_log(CONNECTION_LOG, error_msg);
}

else if (bytes_read + c->in_buffer_size > SZ_IN_BUFFER) {

/* the socket is no longer any good */
c->socket_up = FALSE;

/* log an error */
sprintf(error_msg, "[%s] added %d to %d bytes for in_buffer overvlow in Do_read_socket.\n", c->connection_id, bytes_read, c->in_buffer_size);

Do_log_error(error_msg);
}

else {
c->in_buffer_size += bytes_read;
}

return;
}
/************************************************************************
/
/ FUNCTION NAME: Do_get_socket_string(struct client_t *c, void *the_data, size_t the_size)
/
/ FUNCTION: reads the next packet type off the socket
/
/ AUTHOR: Brian Kelly, 4/23/99
/
/ ARGUMENTS:
/ int the_socket - the socket to read the packet type
/
/ RETURN VALUE:
/ int - the type of packet next on the socket
/
/ MODULES CALLED: wmove(), _filbuf(), clearok(), waddstr(), wrefresh(),
/ wclrtoeol()
/
/ DESCRIPTION:
/ Read a string from the keyboard.
/
/************************************************************************/

int Do_get_socket_string(struct client_t *c, char *theString, size_t theSize)
{
size_t theLength;
char string_buffer[SZ_LINE], error_msg[SZ_ERROR_MESSAGE + SZ_OUT_BUFFER];
sigset_t sigMask;
int theSignal;

/* prepare to unblock SIGIO */
sigemptyset(&sigMask);
sigaddset(&sigMask, SIGIO);
sigaddset(&sigMask, SIGALRM);

for (;;) {

/* if the socket is down, return an error */
if (!c->socket_up) {
return S_ERROR;
}

/* if we have information in the buffer */
if (c->in_buffer_size) {

/* see if the entire string has been downloaded */
theLength = strlen(c->in_buffer);

if (theLength < c->in_buffer_size) {

/* check that the passed pointer can handle the size */
if (theSize - 1 < theLength) {

/* log the error */
sprintf(error_msg, "[%s] Client returned a string of %d bytes, %d max in Do_get_socket_string.\n", c->connection_id, theLength, theSize);

Do_log_error(error_msg);

/* get as much of the string as we can */
strncpy(theString, c->in_buffer, theSize - 1);
theString[theSize - 1] = '\0';
}
else {
strcpy(theString, c->in_buffer);
}

/* add the terminating null to the string */
++theLength;

/* move up information in the buffer */
if (theLength < c->in_buffer_size) {
c->in_buffer_size -= theLength;
memmove(c->in_buffer, &c->in_buffer[theLength],
c->in_buffer_size);
}
else {
c->in_buffer_size = 0;
}

#ifdef RECEIVE_DEBUG
sprintf(error_msg, "[%s] received %d bytes\n",
c->connection_id, theLength);

Do_log(DEBUG_LOG, error_msg);
#endif

#ifdef RECEIVE_PACKET_DEBUG
sprintf(error_msg, "[%s] (%s)\n", c->connection_id, theString);
Do_log(DEBUG_LOG, error_msg);
#endif

return S_NORM;
}

/* the the buffer is maxed and we're here,
the string is too large for the buffer */

if (c->in_buffer_size == SZ_IN_BUFFER) {

sprintf(error_msg, "[%s] Request for a string, %d bytes, larger than buffer in Do_get_socket_string.\n", c->connection_id, theLength);

Do_log_error(error_msg);

c->socket_up = FALSE;
return S_ERROR;
}
}

/* We need to wait for information, so pause */
if (c->socket_up) {

#ifdef SUSPEND_DEBUG
sprintf(error_msg,
"[%s] now sleeping with alarm set for %d seconds.\n",
c->connection_id, c->timeout);

Do_log(DEBUG_LOG, error_msg);
#endif
sigwait(&sigMask, &theSignal);

#ifdef SUSPEND_DEBUG
sprintf(error_msg, "[%s] awoken on signal %d.\n",
c->connection_id, theSignal);

Do_log(DEBUG_LOG, error_msg);
#endif
/*
sleep(.1);
*/

}
else {
theSignal = SIGIO;
}

/* check events and the socket on a SIGIO */
if (theSignal == SIGIO) {

/* if the socket is up, we have room in the buffer and
there is info waiting */

if (c->socket_up && c->in_buffer_size < SZ_IN_BUFFER &&
Do_check_socket(c->socket)) {

Do_read_socket(c);
}

/* see if any other threads have sent us an event */
Do_check_events_in(c);
}

/* see if the tread alarm went off */
else if (theSignal == SIGALRM) {
/*
if (time(NULL) > c->timeoutAt) {
*/

switch(++c->timeoutFlag) {

/* alarm has gone off once */
case 1:
Do_send_int(c, PING_PACKET);
Do_send_buffer(c);

/* give the client 15 seconds to respond */
alarm(15);
c->timeoutAt = time(NULL) + 15;
break;

/* gone off twice */
case 2:

sprintf(error_msg, "[%s] Socket connection timed out.\n",
c->connection_id);

Do_log(CONNECTION_LOG, error_msg);
Do_send_error(c, "The socket connection timed out.\n");
Do_send_buffer(c);

/* assume the network connection is down */
sprintf(error_msg,
"[%s] Socket connection timed out in Do_get_socket_string.\n",
c->connection_id);

Do_log_error(error_msg);
c->socket_up = FALSE;
return S_ERROR;
}
}

/* unknown signal */
else {
sprintf(error_msg, "[%s] Received unknown signal %d.\n",
c->connection_id, theSignal);

Do_log_error(error_msg);
}
}
}


/************************************************************************
/
/ FUNCTION NAME: Do_get_string(struct client_t *c, char *theString,
/ int maxSize);
/
/ FUNCTION: Wait until char is returned from player
/
/ AUTHOR: Brian Kelly, 8/11/99
/
/ ARGUMENTS:
/ client_t c - the client data strcture
/ size_t the_size - the number of bytes fo data expected
/ void *the_data - a pointer to where the data should be written
/ bool exact - Does there need to be exactly the_size bytes?
/
/ RETURN VALUE:
/ bool - Was the data or a timeout registered
/
/ MODULES CALLED: wmove(), _filbuf(), clearok(), waddstr(), wrefresh(),
/ wclrtoeol()
/
/ DESCRIPTION:
/ Read a string from the keyboard.
/
/************************************************************************/

int Do_get_string(struct client_t *c, char *theString, int maxSize)
{
char packetTmp[SZ_PACKET_TYPE], error_msg[SZ_ERROR_MESSAGE];
int packetType;
int returnCode;

Do_send_buffer(c);

c->timeoutFlag = 0;
alarm(c->timeout);
c->timeoutAt = time(NULL) + c->timeout;

for(;;) {

/* get the header of the next packet */
errno = 0;
if (Do_get_socket_string(c, packetTmp, SZ_PACKET_TYPE) == S_ERROR) {
alarm(0);
return S_ERROR;
}

/* convert the string to an integer */
packetType = strtol(packetTmp, NULL, 10);

switch(packetType) {

/* if the packet type is returning an answer */
case C_RESPONSE_PACKET:

/* read the string */
returnCode = Do_get_socket_string(c, theString, maxSize);
alarm(0);
return returnCode;

case C_CANCEL_PACKET:

alarm(0);
return S_CANCEL;

case C_PING_PACKET:

if (c->timeoutFlag == 1) {

alarm(0);
return S_TIMEOUT;
}
else {
sprintf(error_msg, "[%s] Received unexpected ping packet.\n",
c->connection_id);

Do_log_error(error_msg);
}
break;

default:

if (Do_packet(c, packetType) == S_ERROR) {
alarm(0);
return S_ERROR;
}
}
}
}


/************************************************************************
/
/ FUNCTION NAME: Do_get_double(struct client_t *c, double *theDouble);
/
/ FUNCTION: Wait until char is returned from player
/
/ AUTHOR: Brian Kelly, 8/11/99
/
/ ARGUMENTS:
/ client_t c - the client data strcture
/ size_t the_size - the number of bytes fo data expected
/ void *the_data - a pointer to where the data should be written
/ bool exact - Does there need to be exactly the_size bytes?
/
/ RETURN VALUE:
/ bool - Was the data or a timeout registered
/
/ MODULES CALLED: wmove(), _filbuf(), clearok(), waddstr(), wrefresh(),
/ wclrtoeol()
/
/ DESCRIPTION:
/ Read a string from the keyboard.
/
/************************************************************************/

int Do_get_double(struct client_t *c, double *theDouble)
{
char tmpDouble[SZ_NUMBER];
int rc;

if (rc = Do_get_string(c, tmpDouble, SZ_NUMBER) != S_NORM) {
return rc;
}

*theDouble = floor(strtod(tmpDouble, NULL));

/* insure that the number is finite */
if (!finite(*theDouble)) {

/* fix the number */
*theDouble = 0;
}

return S_NORM;
}


/************************************************************************
/
/ FUNCTION NAME: Do_get_long(struct client_t *c, long *theLong);
/
/ FUNCTION: Wait until char is returned from player
/
/ AUTHOR: Brian Kelly, 10/2/99
/
/ ARGUMENTS:
/ client_t c - the client data strcture
/ size_t the_size - the number of bytes fo data expected
/ void *the_data - a pointer to where the data should be written
/ bool exact - Does there need to be exactly the_size bytes?
/
/ RETURN VALUE:
/ bool - Was the data or a timeout registered
/
/ MODULES CALLED: wmove(), _filbuf(), clearok(), waddstr(), wrefresh(),
/ wclrtoeol()
/
/ DESCRIPTION:
/ Read a string from the keyboard.
/
/************************************************************************/

int Do_get_long(struct client_t *c, long *theLong)
{
char tmpLong[SZ_NUMBER];
int returnCode;

returnCode = Do_get_string(c, tmpLong, SZ_NUMBER);

if (returnCode != S_NORM) {
return returnCode;
}

*theLong = strtol(tmpLong, NULL, 10);

return S_NORM;
}


/************************************************************************
/
/ FUNCTION NAME: Do_get_nothing(struct client_t *c);
/
/ FUNCTION: Wait until char is returned from player
/
/ AUTHOR: Brian Kelly, 11/3/99
/
/ ARGUMENTS:
/ client_t c - the client data strcture
/ size_t the_size - the number of bytes fo data expected
/ void *the_data - a pointer to where the data should be written
/ bool exact - Does there need to be exactly the_size bytes?
/
/ RETURN VALUE:
/ bool - Was the data or a timeout registered
/
/ MODULES CALLED: wmove(), _filbuf(), clearok(), waddstr(), wrefresh(),
/ wclrtoeol()
/
/ DESCRIPTION:
/ Read a string from the keyboard.
/

Arachno331
11-14-2007, 12:46 AM
/************************************************************************/

int Do_get_nothing(struct client_t *c)
{
char packetTmp[SZ_PACKET_TYPE];
char error_msg[SZ_ERROR_MESSAGE];
int packetType;

for(;;) {

/* if the socket is up, we have room in the buffer and
there is info waiting */

if (c->socket_up && c->in_buffer_size < SZ_IN_BUFFER &&
Do_check_socket(c->socket)) {

Do_read_socket(c);
}

/* if the socket is up, and the buffer has data */
if (c->socket_up && c->in_buffer_size) {

c->timeoutAt = time(NULL) + c->timeout;

/* get the header of the next packet */
if (Do_get_socket_string(c, packetTmp, SZ_PACKET_TYPE) == S_ERROR)
return S_ERROR;

/* convert the string to an integer */
packetType = strtol(packetTmp, NULL, 10);

switch(packetType) {

/* we're not expecting an answer */
case C_RESPONSE_PACKET:
case C_CANCEL_PACKET:
case C_PING_PACKET:

/* print an error message */
sprintf(error_msg,
"[%s] Unexpected packet type %d returned in Do_get_nothing.\n",
c->connection_id, packetType);

Do_log_error(error_msg);
Do_send_error(c, error_msg);
c->socket_up = FALSE;

return S_ERROR;

default:

if (Do_packet(c, packetType) == S_ERROR) {
return S_ERROR;
}
}
}
else {
return S_NORM;
}
}
}


/************************************************************************
/
/ FUNCTION NAME: int Do_packet(client_t *c, char packetType);
/
/ FUNCTION: Wait until char is returned from player
/
/ AUTHOR: Brian Kelly, 8/11/99
/
/ ARGUMENTS:
/ client_t c - the client data strcture
/ size_t the_size - the number of bytes fo data expected
/ void *the_data - a pointer to where the data should be written
/ bool exact - Does there need to be exactly the_size bytes?
/
/ RETURN VALUE:
/ bool - Was the data or a timeout registered
/
/ MODULES CALLED: wmove(), _filbuf(), clearok(), waddstr(), wrefresh(),
/ wclrtoeol()
/
/ DESCRIPTION:
/ Read a string from the keyboard.
/
/************************************************************************/

int Do_packet(struct client_t *c, int thePacket)
{
char numChars;
time_t timeNow;
struct event_t *event_ptr;
char error_msg[SZ_ERROR_MESSAGE];
char player_name[SZ_NAME];
char string_buffer[SZ_CHAT - 20];
long theLong;

/* switch on the type of event */
switch(thePacket) {

case C_CHAT_PACKET:

/* get the string to be sent and quit on error*/
if (Do_get_socket_string(c, string_buffer, SZ_CHAT - 20) == S_ERROR)
return S_ERROR;

/* mute null chat messages */
if (strlen(string_buffer) > 0) {

/* if the player is muted */
if (c->muteUntil < time(NULL)) {

/* send the chat message */
Do_chat(c, string_buffer);
}
}

/* get rid of old tags */
if(c->tagUntil < time(NULL))
{
Do_remove_prefix_suffix(c);
/* if(c->characterLoaded)
{
strcpy(string_buffer, c->player.name);
if(c->characterAnnounced)
{
Do_send_specification(c, REMOVE_PLAYER_EVENT);
}
strncpy(c->modifiedName, string_buffer, SZ_NAME - 1);
if(c->characterAnnounced)
{
Do_send_specification(c, ADD_PLAYER_EVENT);
Do_name(c);
}
} */
}

/* finished */
return S_NORM;

case C_EXAMINE_PACKET:

/* read player name and quit if there's an error */
if (Do_get_socket_string(c, player_name, SZ_NAME) == S_ERROR)
return S_ERROR;

/* request the info from the player */
event_ptr = (struct event_t *) Do_create_event();
event_ptr->type = REQUEST_RECORD_EVENT;
event_ptr->from = c->game;

if (!Do_send_character_event(c, event_ptr, player_name)) {
free((void *)event_ptr);
}

/* finished */
return S_NORM;

case C_SCOREBOARD_PACKET:

/* read starting record and quit if there's an error */
if (Do_get_socket_string(c, string_buffer, SZ_NAME) == S_ERROR)
return S_ERROR;

theLong = strtol(string_buffer, NULL, 10);
/* convert the string to an int */
Do_scoreboard(c, (int) theLong, TRUE);

/* finished */
return S_NORM;

case C_ERROR_PACKET:

/* see if the client included a message */
if (Do_get_socket_string(c, error_msg, SZ_ERROR_MESSAGE) !=
S_NORM) {

error_msg[0] = '\0';
}

/* log the error */
sprintf(string_buffer,
"[%s] Client returned an error packet in Do_packet: %s.\n",
c->connection_id, error_msg);

Do_log_error(string_buffer);

c->socket_up = FALSE;
return S_ERROR;

default:

/* print an error message */
sprintf(error_msg,
"[%s] Received unknown packet type %d in Do_packet.\n",
c->connection_id, thePacket);

Do_log_error(error_msg);
Do_send_error(c, error_msg);
c->socket_up = FALSE;

/* exit gracefully */
return S_ERROR;
}
}
/************************************************************************
/
/ FUNCTION NAME: int Do_get_network_address(client_t *c, int hostAddress, int subnetMask);
/
/ FUNCTION: Wait until char is returned from player
/
/ AUTHOR: Brian Kelly, 6/8/00
/
/ ARGUMENTS:
/ client_t c - the client data strcture
/ size_t the_size - the number of bytes fo data expected
/ void *the_data - a pointer to where the data should be written
/ bool exact - Does there need to be exactly the_size bytes?
/
/ RETURN VALUE:
/ bool - Was the data or a timeout registered
/
/ MODULES CALLED: wmove(), _filbuf(), clearok(), waddstr(), wrefresh(),
/ wclrtoeol()
/
/ DESCRIPTION:
/ Read a string from the keyboard.
/
/************************************************************************/

Do_get_network_address(struct in_addr *hostAddress, int subnetMask)
{
unsigned int bitMask;

/* create a bitmask. Ex: 8 mask = 0xffffff00 */
bitMask = pow(2, subnetMask) - 1;
bitMask = (unsigned int) 0xffffffff ^ bitMask;

/* return only the network portion of the hostAddress */
hostAddress->s_addr = bitMask & htonl(hostAddress->s_addr);
hostAddress->s_addr = ntohl(hostAddress->s_addr);
return;
}


/************************************************************************
/
/ FUNCTION NAME: int Do_check_host_address(int hostAddress, int networkAddress, int subnetMask);
/
/ FUNCTION: Wait until char is returned from player
/
/ AUTHOR: Brian Kelly, 6/8/00
/
/ ARGUMENTS:
/ client_t c - the client data strcture
/ size_t the_size - the number of bytes fo data expected
/ void *the_data - a pointer to where the data should be written
/ bool exact - Does there need to be exactly the_size bytes?
/
/ RETURN VALUE:
/ bool - Was the data or a timeout registered
/
/ MODULES CALLED: wmove(), _filbuf(), clearok(), waddstr(), wrefresh(),
/ wclrtoeol()
/
/ DESCRIPTION:
/ Read a string from the keyboard.
/
/************************************************************************/

int Do_check_host_address(struct in_addr *hostAddress, struct in_addr *networkAddress, int subnetMask)
{
struct in_addr checkAddress;

if (subnetMask < 0 || subnetMask > 24) {
return FALSE;
}

checkAddress.s_addr = hostAddress->s_addr;

Do_get_network_address(&checkAddress, subnetMask);

if (networkAddress->s_addr == checkAddress.s_addr) {
return TRUE;
}

return FALSE;
}

Arachno331
11-14-2007, 06:46 PM
socket.c: In function ‘Do_accept_connections’:
socket.c:252: warning: passing argument 1 of ‘strncpy’ from incompatible pointer type

This is line 252:

/*
errno = 0;
host_info = gethostbyaddr((char *)&client_ptr->address.sin_addr,
sizeof(client_ptr->address.sin_addr), AF_INET);
theError = errno;
*/