示例#1
0
int
process_input (DESCRIPTOR_DATA * t)
{
  int sofar;
  int thisround;
  int begin;
  int squelch;
  int i;
  int k;
  int flag;
  char tmp[MAX_STRING_LENGTH + 100];
  char buffer[MAX_STRING_LENGTH + 100];

  sofar = 0;
  flag = 0;
  begin = strlen (t->buf);

  /* Read in some stuff */
  do
    {
      if ((thisround = read (t->hSocketFD, t->buf + begin + sofar,
			     MAX_INPUT_LENGTH - (begin + sofar) - 1)) > 0)
	sofar += thisround;
      else if (thisround < 0)
	if (errno != EWOULDBLOCK)
	  {
	    return -1;
	  }
	else
	  break;
      else
	{
	  return -1;
	}
    }
  while (!ISNEWL (*(t->buf + begin + sofar - 1)));

  *(t->buf + begin + sofar) = 0;

  if (!IS_SET (t->edit_mode, MODE_DONE_EDITING))
    {
      ve_process (t, t->buf);	/* Editor subsystem call */
      *t->buf = '\0';		/* This may cause some data to be lost if */
      return (0);		/* chars are typed after @ & before processing */
    }

  /* if no newline is contained in input, return without proc'ing */
  for (i = begin; !ISNEWL (*(t->buf + i)); i++)
    if (!*(t->buf + i))
      return (0);

  /* input contains 1 or more newlines; process the stuff */
  for (i = 0, k = 0; *(t->buf + i);)
    {
      if (!ISNEWL (*(t->buf + i)) && !(flag = (k >= (MAX_INPUT_LENGTH - 2))))
	if (*(t->buf + i) == '\b')	/* backspace */
	  if (k)		/* more than one char ? */
	    {
	      i++;
	    }
	  else
	    i++;		/* no or just one char.. Skip backsp */
	else
	  /* KILLER CDR:  $$ problem here. */
	if (isascii (*(t->buf + i)) && isprint (*(t->buf + i)))
	  {
	    *(tmp + k) = *(t->buf + i);

	    k++;
	    i++;
	  }
	else
	  i++;
      else
	{
	  *(tmp + k) = 0;
	  if (*tmp == '!')
	    strcpy (tmp, t->last_input);
	  else
	    strcpy (t->last_input, tmp);

	  write_to_q (tmp, &t->input);

	  if (t->snoop.snoop_by && t->snoop.snoop_by->desc != NULL
	      && !IS_NPC (t->snoop.snoop_by))
	    {
	      write_to_q ("% ", &t->snoop.snoop_by->desc->output);
	      write_to_q (tmp, &t->snoop.snoop_by->desc->output);
	      write_to_q ("\n\r", &t->snoop.snoop_by->desc->output);
	    }

	  if (flag)
	    {
	      sprintf (buffer, "Line too long. Truncated to:\n\r%s\n\r", tmp);
	      if (write_to_descriptor (t, buffer) < 0)
		return (-1);

	      /* skip the rest of the line */
	      for (; !ISNEWL (*(t->buf + i)); i++);
	    }

	  /* find end of entry */
	  for (; ISNEWL (*(t->buf + i)); i++);

	  /* squelch the entry from the buffer */
	  for (squelch = 0;; squelch++)
	    if ((*(t->buf + squelch) = *(t->buf + i + squelch)) == '\0')
	      break;
	  k = 0;
	  i = 0;
	}
    }

  return (1);
}
示例#2
0
void ident_check(struct descriptor_data *d, int pulse)
{
  fd_set fd, efd;
  int rc, rmt_port, our_port, len;
  char user[256], *p;

  extern struct timeval null_time;
  extern int port;

  /*
   * Each pulse, this checks if the ident is ready to proceed to the
   * next state, by calling select to see if the socket is writeable
   * (connected) or readable (response waiting).  
   */

  switch (STATE(d)) {
    case CON_IDCONING:
      /* waiting for connect() to finish */

      if (d->ident_sock != INVALID_SOCKET) {
        FD_ZERO(&fd);
        FD_ZERO(&efd);
        FD_SET(d->ident_sock, &fd);
        FD_SET(d->ident_sock, &efd);
      }

      if ((rc = select(d->ident_sock + 1, (fd_set *) 0, &fd, &efd, &null_time)) == 0)
        break;

      else if (rc < 0) {
        logerror("ident check select (conning)");
        STATE(d) = CON_ASKNAME;
        break;
      }

      if (FD_ISSET(d->ident_sock, &efd)) {
        /* exception, such as failure to connect */
        STATE(d) = CON_ASKNAME;
        break;
      }

      STATE(d) = CON_IDCONED;
      break;

    case CON_IDCONED:
      /* connected, write request */

      sprintf(buf, "%d, %d\n\r", ntohs(d->peer_port), port);

      len = strlen(buf);
#ifdef CIRCLE_WINDOWS
      if (send(d->ident_sock, buf, len, 0) < 0) {
#else
      if (write(d->ident_sock, buf, len) != len) {
        if (errno != EPIPE) /* read end closed (no remote identd) */
#endif
          logerror("ident check write (conned)");

        STATE(d) = CON_ASKNAME;
        break;
      }

      STATE(d) = CON_IDREADING;
      break;

    case CON_IDREADING:
      /* waiting to read */

      if (d->ident_sock != INVALID_SOCKET) {
        FD_ZERO(&fd);
        FD_ZERO(&efd);
        FD_SET(d->ident_sock, &fd);
        FD_SET(d->ident_sock, &efd);
      }

      if ((rc = select(d->ident_sock + 1, &fd, (fd_set *) 0, &efd, &null_time)) == 0)
        break;

      else if (rc < 0) {
        logerror("ident check select (reading)");
        STATE(d) = CON_ASKNAME;
        break;
      }

      if (FD_ISSET(d->ident_sock, &efd)) {
        STATE(d) = CON_ASKNAME;
        break;
      }

      STATE(d) = CON_IDREAD;
      break;

    case CON_IDREAD:
      /* read ready, get the info */

#ifdef CIRCLE_WINDOWS
      if ((len = recv(d->ident_sock, buf, sizeof(buf) - 1, 0)) < 0)
#else
      if ((len = read(d->ident_sock, buf, sizeof(buf) - 1)) < 0)
#endif
        logerror("ident check read (read)");

      else {
        buf[len] = '\0';
        if (sscanf(buf, "%u , %u : USERID :%*[^:]:%255s", &rmt_port, &our_port, user) != 3) {

          /* check if error or malformed */
          if (sscanf(buf, "%u , %u : ERROR : %255s", &rmt_port, &our_port, user) == 3) {
            sprintf(buf2, "Ident error from %s: \"%s\"", d->hostIP, user);
            stderr_log(buf2);
          } else {
            /* strip off trailing newline */
            for (p = buf + len - 1; p > buf && ISNEWL(*p); p--)
              ;
            p[1] = '\0';

            sprintf(buf2, "Malformed ident response from %s: \"%s\"", d->hostIP, buf);
            stderr_log(buf2);
          }
        } else {

          len = HOST_LENGTH - strlen(d->hostIP);

          if (len > 0) {
            strncpy(buf2, user, len - 1);
            buf2[len - 1] = '\0';
            strcpy(d->username, buf2);
          }

          /* if len <= 0, no space for username */
        }
      }

      STATE(d) = CON_ASKNAME;
      break;

    case CON_ASKNAME:
      /* ident complete, ask for name */

      /* close up the ident socket, if one is opened. */
      if (d->ident_sock != INVALID_SOCKET) {
        close(d->ident_sock);
        d->ident_sock = INVALID_SOCKET;
      }
      d->idle_tics = 0;

      /* extra ban check */
      if ((d->host[0] != '\0' && isbanned(d->host) == BAN_ALL) || isbanned(d->hostIP)) {
        if (d->host[0] != '\0') {
          sprintf(buf, "Connection attempt denied from [%s]", d->host);
        } else {
          sprintf(buf, "Connection attempt denied from [%s]", d->hostIP);
        }
        mudlog(buf, 'S', COM_IMMORT, TRUE);
        close_socket(d);
        return;
      }

      /* SEND_TO_Q("\x1B[2K\n\rBy what name do you wish to be known? ", d); */
      STATE(d) = CON_GET_TERMTYPE;
      return;

    default:
      return;
  }

  /*
   * Print a dot every second so the user knows he hasn't been forgotten.
   * Allow the user to go on anyways after waiting IDENT_TIMEOUT seconds.
   */
  if ((pulse % PASSES_PER_SEC) == 0) {
    SEND_TO_Q(".", d);

    if (d->idle_tics++ >= IDENT_TIMEOUT)
      STATE(d) = CON_ASKNAME;
  }
}

/* returns 1 if waiting for ident to complete, else 0 */
int waiting_for_ident(struct descriptor_data *d)
{
  switch (STATE(d)) {
    case CON_IDCONING:
    case CON_IDCONED:
    case CON_IDREADING:
    case CON_IDREAD:
    case CON_ASKNAME:
      return 1;
  }
  return 0;
}