#include #include #include #include #include #include #include #include #include #include #include #include char output[1048576]; static int _connect (const char *host, const char *port) { struct addrinfo hints = { .ai_family = AF_INET, .ai_socktype = SOCK_STREAM }, *result; int gai_errno = 0; if ((gai_errno = getaddrinfo (host, port, &hints, &result))) { fprintf (stderr, "_connect: getaddrinfo failed: %s\n", gai_strerror (gai_errno)); return -1; } int sock = -1; if ((sock = socket (result->ai_family, result->ai_socktype, result->ai_protocol)) < 0) { fprintf (stderr, "_connect: socket failed: %s\n", strerror (errno)); } else if (connect (sock, result->ai_addr, result->ai_addrlen) < 0) { fprintf (stderr, "_connect: connect failed: %s\n", strerror (errno)); close (sock); sock = -1; } freeaddrinfo (result); if (sock != -1) { fprintf (stderr, "_connect: connected to %s:%s.\n", host, port); int flags; if ((flags = fcntl (sock, F_GETFL, 0)) == -1) fprintf (stderr, "_connect: fcntl (F_GETFL) failed: %s\n", strerror (errno)); else if (fcntl (sock, F_SETFL, flags | O_NONBLOCK) == -1) fprintf (stderr, "_connect: fcntl (F_SETFL) failed: %s\n", strerror (errno)); else return sock; close (sock); } exit (EXIT_FAILURE); } static void _select (int sock) { fd_set wfds; FD_ZERO (&wfds); FD_SET (sock, &wfds); int rv; if ((rv = select (sock + 1, NULL, &wfds, NULL, &(struct timeval) { .tv_sec = 1 })) < 0) { fprintf (stderr, "_select: select failed: %s\n", strerror (errno)); exit (EXIT_FAILURE); } fprintf (stderr, "_select: select = %d, FD_ISSET (%d, &wfds) == %d.\n", rv, sock, FD_ISSET (sock, &wfds)); } static void _send (int sock) { struct iovec vec = { .iov_base = output, .iov_len = sizeof output }; struct msghdr mhdr = { .msg_iov = &vec, .msg_iovlen = 1 }; for (int i = 0; ; ++i) { ssize_t rv; if ((rv = sendmsg (sock, &mhdr, 0)) < 0) { fprintf (stderr, "_send: sendmsg %d failed: %s\n", i, strerror (errno)); break; } else fprintf (stderr, "_send: sendmsg %d returned: %zd\n", i, rv); } } static void _system (const char *fmt, ...) { char cmdbuf[64]; va_list ap; va_start (ap, fmt); vsprintf (cmdbuf, fmt, ap); va_end (ap); fprintf (stderr, "_system: %s\n", cmdbuf); system (cmdbuf); } int main (int argc, char **argv) { if (argc != 4) exit (EXIT_FAILURE); const char *host = argv[1], *port = argv[2], *netcat = argv[3]; _system ("%s -l %s & sleep 1", netcat, port); signal (SIGPIPE, SIG_IGN); int sock = _connect (host, port); _select (sock); _system ("pkill -x %s; sleep 1", netcat); _select (sock); _send (sock); _select (sock); exit (EXIT_SUCCESS); }