/* * Read data from the Telnet session to the raw input queue. */ static void telnet_read(ndesc_t *nd, telnet_t *tp) { int cc; if (!nq_full(tp->t_rawq)) { if (tp->t_flags & TF_URGENT) { if (at_mark(nd_fd(nd))) { tp->t_flags &= ~TF_URGENT; nd_enable(nd, ND_X); } } cc = nq_recv(tp->t_rawq, nd_fd(nd), &tp->t_rblen); if (cc == -1) { switch (errno) { case EWOULDBLOCK: case EINTR: case EPROTO: break; default: telnet_disconnect(tp); return; } } if (cc == 0) { telnet_disconnect(tp); return; } if ((tp->t_flags & TF_FLOWC) == 0) nd_enable(nd, ND_C); telnet_enabr(tp); if (!nq_full(tp->t_rawq)) return; } tp->t_flags |= TF_ENABR; nd_disable(nd, ND_R); }
/* * Send a UDP datagram. */ int udpsvc_send(udpsvc_t *svc, char *dest, int port, char *cp) { struct sockaddr_in addr; int cc; if (udpsvc_nd == NULL || port < 0) return 0; memset(&addr, 0, sizeof (addr)); addr.sin_family = AF_INET; addr.sin_port = htons((u_short)port); addr.sin_addr.s_addr = inet_addr(dest); if (addr.sin_addr.s_addr == INADDR_NONE) { #ifdef UDP_SEND_HOSTNAME struct hostent *hp; hp = gethostbyname(addr); if (hp == NULL) return 0; memcpy(&addr.sin_addr, hp->h_addr, hp->h_length); #else return 0; #endif } cc = sendto(nd_fd(svc->nd), cp, strlen(cp), 0, (struct sockaddr *)&addr, sizeof (addr)); return cc != -1; }
/* * Close the UDP Manager session and free the associated resources. */ static void udpsvc_shutdown(ndesc_t *nd, udpsvc_t *svc) { (void)close(nd_fd(nd)); nq_free(svc->nq); nd_detach(nd); free(svc); }
/* * Close the UDP Manager session and free the associated resources. */ static void udpsvc_shutdown(ndesc_t *nd, nqueue_t *nq) { (void)close(nd_fd(nd)); nq_free(nq); nd_detach(nd); udpsvc_nd = NULL; }
/* * Close a Telnet session and free the associated resources. */ static void telnet_shutdown(ndesc_t *nd, telnet_t *tp) { if (tp != NULL) { telnet_flush(tp); telnet_free(tp); } (void)close(nd_fd(nd)); nd_detach(nd); }
/* * Accept a new Telnet connection. */ static void telnet_accept(void *vp) { ndesc_t *nd = vp; int addrlen, s; struct sockaddr_in addr; telnet_t *tp; void *ip; nd_enable(nd, ND_R); addrlen = sizeof (addr); s = accept(nd_fd(nd), (struct sockaddr *)&addr, &addrlen); if (s == -1) { switch (errno) { default: warning("telnet_accept: accept() errno = %d. ip: %s\n", errno, inet_ntoa(addr.sin_addr)); case EWOULDBLOCK: case EINTR: case EPROTO: return; } } enable_nbio(s); enable_oobinline(s); enable_nodelay(s); enable_lowdelay(s); enable_keepalive(s); set_rcvsize(s, TELNET_RCVBUF_SIZE); set_sndsize(s, TELNET_SNDBUF_SIZE); tp = telnet_alloc(); tp->t_nd = nd_attach(s, telnet_read, telnet_write, telnet_exception, NULL, telnet_shutdown, tp); ip = (void *)new_player(tp, &addr, addrlen); if (ip == NULL) { telnet_shutdown(tp->t_nd, tp); } else { telnet_attach(tp, ip); nd_enable(tp->t_nd, ND_R | ND_X); } }
/* * Write data from the output queue to the Telnet session. */ static void telnet_write(ndesc_t *nd, telnet_t *tp) { if (!nq_empty(tp->t_outq)) { if (nq_send(tp->t_outq, nd_fd(nd), &tp->t_sblen) == -1) { switch (errno) { case EWOULDBLOCK: case EINTR: case EPROTO: break; default: telnet_disconnect(tp); return; } } } if (tp->t_flags & TF_OVFLOUTQ) { if (nq_len(tp->t_outq) < TELNET_OUTQ_LOWAT) { tp->t_flags &= ~TF_OVFLOUTQ; nq_puts(tp->t_outq, (u_char *)"*** Truncated. ***\r\n"); } } if (tp->t_flags & TF_FLOWC) { if (nq_len(tp->t_outq) < TELNET_OUTQ_HIWAT) { tp->t_flags &= ~TF_FLOWC; nd_enable(nd, ND_C); } } if (!nq_empty(tp->t_outq)) return; nq_init(tp->t_outq); tp->t_flags |= TF_ENABW; nd_disable(nd, ND_W); }
static int read_datagram(udpsvc_t *svc) { int addrlen, cc; struct sockaddr_in addr; /* Get another datagram */ cc = recvfrom(nd_fd(svc->nd), nq_wptr(svc->nq), nq_size(svc->nq) - 1, 0, (struct sockaddr *)&addr, &addrlen); if (cc == -1) { return 0; } nq_wptr(svc->nq)[cc] = '\0'; return 1; }
/* * Read and process a UDP datagram. */ static void udpsvc_read(ndesc_t *nd, nqueue_t *nq) { int addrlen, cc; struct sockaddr_in addr; addrlen = sizeof (addr); cc = recvfrom(nd_fd(nd), nq_wptr(nq), nq_size(nq) - 1, 0, (struct sockaddr *)&addr, &addrlen); if (cc == -1) return; nq_wptr(nq)[cc] = '\0'; /* XXX We need a safe master apply XXX */ push_string(inet_ntoa(addr.sin_addr), STRING_MSTRING); push_string((char *)nq_rptr(nq), STRING_MSTRING); (void)apply_master_ob(M_INCOMING_UDP, 2); }
/* * Write data from the output queue to the Telnet session. */ static void telnet_write(ndesc_t *nd, telnet_t *tp) { if (!nq_empty(tp->t_outq)) { if (nq_send(tp->t_outq, nd_fd(nd), &tp->t_sblen) == -1) { switch (errno) { case EWOULDBLOCK: case EINTR: case EPROTO: break; default: telnet_disconnect(tp); return; } } } if (tp->t_flags & TF_OVFLOUTQ) { if (nq_len(tp->t_outq) < TELNET_OUTQ_LOWAT) { tp->t_flags &= ~TF_OVFLOUTQ; if (tp->t_flags & (TF_INPUT|TF_DISCONNECT) && !tp->task) /* Reenable command processing */ tp->task = create_task(telnet_interactive, tp); } } if (!nq_empty(tp->t_outq)) return; nq_init(tp->t_outq); nd_disable(nd, ND_W); }
/* * Flush the output queue. */ static void telnet_flush(telnet_t *tp) { if (!nq_empty(tp->t_outq)) nq_send(tp->t_outq, nd_fd(tp->t_nd), &tp->t_sblen); }