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); }
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; }