示例#1
0
文件: socket.c 项目: KaSt/nereamud
void do_copyover(void) {
  LIST_ITERATOR *sock_i = newListIterator(socket_list);
  SOCKET_DATA     *sock = NULL;
  FILE *fp;
  char buf[100];
  char control_buf[20];
  char port_buf[20];

  if ((fp = fopen(COPYOVER_FILE, "w+")) == NULL)
    return;

  sprintf(buf, "\n\r <*>            The world starts spinning             <*>\n\r");

  // For each playing descriptor, save its character and account
  ITERATE_LIST(sock, sock_i) {
    compressEnd(sock, sock->compressing, FALSE);
    // kick off anyone who hasn't yet logged in a character
    if (!socketGetChar(sock) || !socketGetAccount(sock) || 
	!charGetRoom(socketGetChar(sock))) {
      text_to_socket(sock, "\r\nSorry, we are rebooting. Come back in a few minutes.\r\n");
      close_socket(sock, FALSE);
    }
    // save account and player info to file
    else {
      fprintf(fp, "%d %s %s %s\n",
	      sock->control, accountGetName(sock->account), 
	      charGetName(sock->player), sock->hostname);
      // save the player
      save_player(sock->player);
      save_account(sock->account);
      text_to_socket(sock, buf);
    }
  } deleteListIterator(sock_i);
示例#2
0
文件: socket.c 项目: KaSt/nereamud
/*
 * Close_socket()
 *
 * Will close one socket directly, freeing all
 * resources and making the socket availably on
 * the socket free_list.
 */
void close_socket(SOCKET_DATA *dsock, bool reconnect)
{
  if (dsock->lookup_status > TSTATE_DONE) return;
  dsock->lookup_status += 2;

  /* remove the socket from the polling list */
  FD_CLR(dsock->control, &fSet);

  /* remove ourself from the list */
  //
  // NO! We don't want to remove ourself from the list just yet.
  // We will do that the next time we show up in the game_loop.
  // removing now will not close the socket completely. Why, I'm not
  // entirely sure... but it doesn't ;)
  //   - Geoff, Dec26/04
  //
  //  listRemove(socket_list, dsock);
  //

  // we have a character, and it's one that's
  // not in the process of being created
  if (dsock->player && charGetUID(dsock->player) != NOBODY) {
    if (reconnect)
      text_to_socket(dsock, "This connection has been taken over.\r\n");
    else {
      charSetSocket(dsock->player, NULL);
      log_string("Closing link to %s", charGetName(dsock->player));
    }
  }
  else if(dsock->player) {
    charSetSocket(dsock->player, NULL);
    extract_mobile(dsock->player);
  }
  
  if(dsock->account) {
    if(account_exists(accountGetName(dsock->account)))
      unreference_account(dsock->account);
    else
      deleteAccount(dsock->account);
  }

  /* set the closed state */
  dsock->closed = TRUE;
  //  dsock->state = STATE_CLOSED;
}
示例#3
0
文件: socket.c 项目: KaSt/nereamud
/* 
 * Read_from_socket()
 *
 * Reads one line from the socket, storing it
 * in a buffer for later use. Will also close
 * the socket if it tries a buffer overflow.
 */
bool read_from_socket(SOCKET_DATA *dsock)
{
  int size;
  extern int errno;

  /* check for buffer overflows, and drop connection in that case */
  size = strlen(dsock->inbuf);
  if (size >= sizeof(dsock->inbuf) - 2)
  {
    text_to_socket(dsock, "\n\r!!!! Input Overflow !!!!\n\r");
    return FALSE;
  }

  /* start reading from the socket */
  for (;;)
  {
    int sInput;
    int wanted = sizeof(dsock->inbuf) - 2 - size;

    sInput = read(dsock->control, dsock->inbuf + size, wanted);

    if (sInput > 0)
    {
      size += sInput;

      if (dsock->inbuf[size-1] == '\n' || dsock->inbuf[size-1] == '\r')
        break;
    }
    else if (sInput == 0)
    {
      log_string("Read_from_socket: EOF");
      return FALSE;
    }
    else if (errno == EAGAIN || sInput == wanted)
      break;
    else
    {
      perror("Read_from_socket");
      return FALSE;
    }
  }
  dsock->inbuf[size] = '\0';
  return TRUE;
}
示例#4
0
文件: socket.c 项目: KaSt/nereamud
bool flush_output(SOCKET_DATA *dsock) {
  bool  success = TRUE;
  BUFFER   *buf = NULL;

  // run any hooks prior to flushing our text
  hookRun("flush", hookBuildInfo("sk", dsock));

  // quit if we have no output and don't need/can't have a prompt
  if(bufferLength(dsock->outbuf) <= 0 && 
     (!dsock->bust_prompt || !socketHasPrompt(dsock)))
    return success;

  buf = newBuffer(1);

  // send our outbound text
  if(bufferLength(dsock->outbuf) > 0) {
    hookRun("process_outbound_text",  hookBuildInfo("sk", dsock));
    hookRun("finalize_outbound_text", hookBuildInfo("sk", dsock));
    //success = text_to_socket(dsock, bufferString(dsock->outbuf));
    bufferCat(buf, bufferString(dsock->outbuf));
    bufferClear(dsock->outbuf);
  }

  // send our prompt
  if(dsock->bust_prompt && success) {
    socketShowPrompt(dsock);
    hookRun("process_outbound_prompt",  hookBuildInfo("sk", dsock));
    hookRun("finalize_outbound_prompt", hookBuildInfo("sk", dsock));
    //success = text_to_socket(dsock, bufferString(dsock->outbuf));
    bufferCat(buf, bufferString(dsock->outbuf));
    bufferClear(dsock->outbuf);
    dsock->bust_prompt = FALSE;
  }

  success = text_to_socket(dsock, bufferString(buf));
  deleteBuffer(buf);

  // return our success
  return success;
}
bool event_socket_idle(EVENT_DATA *event)
{
  D_SOCKET *dSock;

  /* Check to see if there is an owner of this event.
   * If there is no owner, we return TRUE, because
   * it's the safest - and post a bug message.
   */
  if ((dSock = event->owner.dSock) == NULL)
  {
    bug("event_socket_idle: no owner.");
    return TRUE;
  }

  /* tell the socket that it has idled out, and close it */
  text_to_socket(dSock, "You have idled out...\n\n\r");
  close_socket(dSock, FALSE);

  /* since we closed the socket, all events owned
   * by that socket has been dequeued, and we need
   * to return TRUE, so the caller knows this.
   */
  return TRUE;
}
示例#6
0
文件: socket.c 项目: KaSt/nereamud
/* Recover from a copyover - load players */
void copyover_recover() {     
  CHAR_DATA    *dMob;
  ACCOUNT_DATA *account;
  SOCKET_DATA  *dsock;
  FILE *fp;
  char acct[100];
  char name[100];
  char host[MAX_BUFFER];
  int desc;
      
  log_string("Copyover recovery initiated");

  if ((fp = fopen(COPYOVER_FILE, "r")) == NULL) {  
    log_string("Copyover file not found. Exitting.");
    exit (1);
  }
      
  /* In case something crashes - doesn't prevent reading */
  unlink(COPYOVER_FILE);

  for (;;) {  
    fscanf(fp, "%d %s %s %s\n", &desc, acct, name, host);
    if (desc == -1)
      break;

    // Many thanks to Rhaelar for the help in finding this bug; clear_socket
    // does not like receiving freshly malloc'd data. We have to make sure
    // everything is zeroed before we pass it to clear_socket
    //    dsock = malloc(sizeof(*dsock));
    dsock = calloc(1, sizeof(*dsock));
    clear_socket(dsock, desc);

    dsock->hostname = strdup(host);
    listPut(socket_list, dsock);
    propertyTablePut(sock_table, dsock);

    // load account data
    if((account = get_account(acct)) != NULL)
      socketSetAccount(dsock, account);
    // no luck!
    else {
      close_socket(dsock, FALSE);
      continue;
    }

    // load player data
    if ((dMob = get_player(name)) != NULL) {
      // attach to socket
      charSetSocket(dMob, dsock);
      socketSetChar(dsock, dMob);

      // try putting the character into the game
      // close the socket if we fail.
      if(!try_enter_game(dMob)) {
	// do not bother extracting, since we haven't entered the game yet
	unreference_player(socketGetChar(dsock));
	socketSetChar(dsock, NULL);
	close_socket(dsock, FALSE);
	continue;
      }
    }
    // no luck
    else {
      close_socket(dsock, FALSE);
      continue;
    }
   
    // Write something, and check if it goes error-free
    if (!text_to_socket(dsock, "\n\r <*>  And before you know it, everything has changed  <*>\n\r")) { 
      close_socket(dsock, FALSE);
      continue;
    }
  
    // make sure the socket can be used
    dsock->bust_prompt    =  TRUE;
    dsock->lookup_status  =  TSTATE_DONE;

    // let our modules know we've finished copying over a socket
    hookRun("copyover_complete", hookBuildInfo("sk", dsock));

    // negotiate compression
    text_to_buffer(dsock, (char *) compress_will2);
    text_to_buffer(dsock, (char *) compress_will);
  }
  fclose(fp);

  // now, set all of the sockets' control to the new fSet
  reconnect_copyover_sockets();
}