commit 1717fb2cc1e8a41154bc2a337f60d6ed8986ba6a
parent d8db125e35204d8492b3e9b063e2e4e4bbf3dbbb
Author: dsp <dsp@2f30.org>
Date: Tue, 3 Jul 2012 14:45:45 +0300
reintroduce lostd patches.+fixes
Diffstat:
M | nbeng.c | | | 161 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------- |
1 file changed, 111 insertions(+), 50 deletions(-)
diff --git a/nbeng.c b/nbeng.c
@@ -34,6 +34,7 @@ typedef struct concontxt_t {
#define SSLCON 3
unsigned int contype; /* connection type */
int confd; /* net connection fd */
+ int clifd;
int clifds[FD_SETSIZE]; /* for tcp connected clients */
fd_set lset; /* the set that we select() on */
struct addrinfo *clinfo; /* info on where we connect */
@@ -86,14 +87,10 @@ set_blocking(int fd)
* The flag for the connection type lives in the context.
*/
static void
-prepare_socket(concontxt *con, char *host, char *port)
+prepare_socket(concontxt *con, char *host, char *port, int lflag)
{
struct addrinfo cli_hints, *cli_servinfo, srv_hints, *srv_servinfo, *p0;
- int rv, cli_sockfd, optval = 1, i;
-
- /* all client fds are available */
- for (i = 0; i < FD_SETSIZE; i++)
- con->clifds[i] = -1;
+ int rv, cli_sockfd, optval = 1;
if ((con == NULL) || (host == NULL) || (port == NULL))
errx(1, "prepare_socket was passed a null arg");
@@ -126,8 +123,9 @@ prepare_socket(concontxt *con, char *host, char *port)
break;
}
if (!p0)
- errx(1, "failed to create socket");
+ err(1, "socket");
/* the same for our local part */
+ if (lflag) {
for (p0 = srv_servinfo; p0; p0 = p0->ai_next) {
if (bind(cli_sockfd, p0->ai_addr, p0->ai_addrlen) < 0) {
close(cli_sockfd);
@@ -137,9 +135,10 @@ prepare_socket(concontxt *con, char *host, char *port)
break;
}
if (!p0)
- errx(1, "failed to bind socket");
+ err(1, "bind");
+ }
/* if it's a tcp connection we have to listen() */
- if (con->contype != UDPCON)
+ if (con->contype != UDPCON && lflag)
listen(cli_sockfd, 5);
/* all was ok, so we register the socket to the context */
con->confd = cli_sockfd;
@@ -190,35 +189,26 @@ freex:
static void
writesock(concontxt *con)
{
- ssize_t sent;
- int newfd;
- int i;
+ ssize_t n;
/* nothing to do */
if (con->buf == NULL)
return;
if (con->contype == UDPCON) {
- sent = sendto(con->confd, con->buf, con->buflen, 0,
+ n = sendto(con->confd, con->buf, con->buflen, 0,
con->clinfo->ai_addr,
con->clinfo->ai_addrlen);
- if (sent < 0)
+ if (n < 0)
warn("sendto");
} else {
- newfd = connect(con->confd,
- con->clinfo->ai_addr,
- con->clinfo->ai_addrlen);
- printf("newfd=%d\n", newfd);
- if (newfd < 0) {
- warn("connect");
+ n = write(con->clifd, con->buf, con->buflen);
+ if (n < 0) {
+ warn("write");
+ close(con->clifd);
+ con->clifd = -1;
goto freex;
}
- for (i = 0; i < FD_SETSIZE; i++) {
- if (con->clifds[i] == -1) {
- con->clifds[i] = newfd;
- break;
- }
- }
}
freex:
@@ -246,9 +236,27 @@ readsock(concontxt *con)
if (con->contype == UDPCON) {
n = recvfrom(con->confd, buf, sizeof (buf), MSG_DONTWAIT,
(struct sockaddr *)&their_addr, &addr_len);
+ if (n < 0) {
+ warn("recvfrom");
+ goto freex;
+ }
+
+ /* resolv */
+ r = getnameinfo((struct sockaddr *)&their_addr, addr_len,
+ host, sizeof (host), NULL, 0, 0);
+ if (r < 0) {
+ warn("getnameinfo");
+ snprintf(host, sizeof (host), "unknown");
+ }
+ printf("host=%s\n", host);
} else {
- /* code for tcp */
- n = 0;
+ n = read(con->clifd, buf, sizeof (buf));
+ if (n == 0) {
+ qflag = 1;
+ close(con->clifd);
+ con->clifd = -1;
+ goto freex;
+ }
}
buf[n] = '\0';
@@ -259,16 +267,7 @@ readsock(concontxt *con)
}
memcpy(con->buf, buf, n);
con->buflen = n;
-
- if (n > 0) {
- r = getnameinfo((struct sockaddr *)&their_addr, addr_len,
- host, sizeof (host), NULL, 0, 0);
- if (r < 0) {
- warn("getnameinfo");
- snprintf(host, sizeof (host), "unknown");
- }
- }
- printf("host=%s n=%zd buf=%s", host, n, buf);
+ printf("n=%zd buf=%s", n, buf);
return;
freex:
@@ -294,10 +293,51 @@ writestdout(concontxt *con)
return;
}
+static void
+myaccept(concontxt *con)
+{
+ int r;
+ char host[NI_MAXHOST];
+ int newfd;
+ struct sockaddr_storage sa;
+ socklen_t salen = sizeof (sa);
+
+ newfd = accept(con->confd, (struct sockaddr *)&sa, &salen);
+ printf("newfd=%d\n", newfd);
+ if (newfd < 0)
+ err(1, "accept");
+ con->clifd = newfd;
+
+ /* resolv */
+ r = getnameinfo((struct sockaddr *)&sa, salen,
+ host, sizeof (host), NULL, 0, 0);
+ if (r < 0) {
+ warn("getnameinfo");
+ snprintf(host, sizeof (host), "unknown");
+ }
+ printf("host=%s\n", host);
+ return;
+}
+
+static void
+myconnect(concontxt *con)
+{
+ int r;
+
+ r = connect(con->confd,
+ con->clinfo->ai_addr,
+ con->clinfo->ai_addrlen);
+ if (r < 0)
+ warn("connect");
+ con->clifd = con->confd;
+ con->confd = -1;
+ return;
+}
+
int
main(int argc, char *argv[])
{
- int c, i;
+ int c;
int highsock, readsocks;
struct timeval timeout;
char *host, *port;
@@ -325,13 +365,14 @@ main(int argc, char *argv[])
con = (concontxt *) malloc(sizeof (concontxt));
if (con == NULL)
- errx(1,"malloc");
+ err(1, "malloc");
/* defaults */
con->wfd = fileno(stdin);
con->lfd = fileno(stdout);
con->contype = (tflag || sflag) ? TCPCON : UDPCON;
+ con->clifd = -1;
- prepare_socket(con, host, port);
+ prepare_socket(con, host, port, 1);
timeout.tv_sec = 1;
timeout.tv_usec = 0;
@@ -339,18 +380,21 @@ main(int argc, char *argv[])
while (1) {
FD_ZERO(&(con->lset));
FD_SET(con->wfd, &(con->lset));
- FD_SET(con->confd, &(con->lset));
- highsock = con->confd;
- /* add all connected clients */
- for (i = 0; i < FD_SETSIZE && con->clifds[i] != -1; i++) {
- FD_SET(con->clifds[i], &(con->lset));
+ highsock = con->wfd;
+ if (con->confd != -1) {
+ FD_SET(con->confd, &(con->lset));
+ highsock = con->confd;
+ }
+ if (con->clifd != -1) {
+ FD_SET(con->clifd, &(con->lset));
+ highsock = con->clifd;
}
if (qflag)
goto freex;
readsocks = select(highsock + 1, &(con->lset), (fd_set *)0,
(fd_set *)0, &timeout);
if (readsocks < 0) {
- warnx("select error");
+ warn("select");
goto freex;
}
if (readsocks == 0) {
@@ -359,10 +403,26 @@ main(int argc, char *argv[])
fflush(stdout);
} else {
if (FD_ISSET(con->wfd, &(con->lset))) {
- readstdin(con);
- writesock(con);
+ if (con->clifd == -1
+ && con->contype != UDPCON) {
+ close(con->confd);
+ prepare_socket(con, host, port, 0);
+ myconnect(con);
+ }
+ readstdin(con);
+ writesock(con);
+ }
+ if (con->confd != -1 &&
+ FD_ISSET(con->confd, &(con->lset))) {
+ if (con->contype == UDPCON) {
+ readsock(con);
+ writestdout(con);
+ } else {
+ myaccept(con);
+ }
}
- if (FD_ISSET(con->confd, &(con->lset))) {
+ if (con->clifd != -1 &&
+ FD_ISSET(con->clifd, &(con->lset))) {
readsock(con);
writestdout(con);
}
@@ -373,6 +433,7 @@ freex:
printf("exiting\n");
if (con != NULL) {
close(con->confd);
+ close(con->clifd);
free(con);
}
return (0);