Commit 69ad872f 69ad872fb22c0f05fe2ca06610dfc69711a97c08 by Sergey Poznyakoff

Accept up to two arguments: hostname to connect to and URL of the page to get.

1 parent b16da1bd
......@@ -28,67 +28,139 @@
#include <mailutils/mailutils.h>
const char *wbuf = "GET / HTTP/1.0\r\n\r\n";
char wbuf[1024];
char rbuf[1024];
size_t io_timeout = 3;
size_t io_attempts = 3;
int
main (void)
http_stream_wait (stream_t stream, int flags, size_t *attempt)
{
int rc;
int oflags = flags;
struct timeval tv;
while (*attempt < io_attempts)
{
tv.tv_sec = io_timeout;
tv.tv_usec = 0;
rc = stream_wait (stream, &oflags, &tv);
switch (rc) {
case 0:
if (flags & oflags)
return 0;
/* FALLTHROUGH */
case EAGAIN:
case EINPROGRESS:
++*attempt;
continue;
default:
return rc;
}
}
return ETIMEDOUT;
}
int
main (int argc, char **argv)
{
int ret, off = 0;
stream_t stream;
size_t nb;
size_t nb, size;
size_t attempt;
char *url = "www.gnu.org";
ret = tcp_stream_create (&stream, "www.gnu.org", 80, MU_STREAM_NONBLOCK);
if (argc > 3)
{
fprintf (stderr, "usage: %s [hostname [url]]\n", argv[0]);
exit (1);
}
if (argc > 1)
url = argv[1];
snprintf (wbuf, sizeof wbuf, "GET %s HTTP/1.0\r\n\r\n",
argc == 3 ? argv[2] : "/");
ret = tcp_stream_create (&stream, url, 80, MU_STREAM_NONBLOCK);
if (ret != 0)
{
mu_error ("tcp_stream_create: %s", mu_strerror (ret));
exit (EXIT_FAILURE);
}
connect_again:
ret = stream_open (stream);
if (ret != 0)
for (attempt = 0; (ret = stream_open (stream)); )
{
if (ret == EAGAIN)
if ((ret == EAGAIN || ret == EINPROGRESS) && attempt < io_attempts)
{
int wflags = MU_STREAM_READY_WR;
stream_wait (stream, &wflags, NULL);
goto connect_again;
ret = http_stream_wait(stream, MU_STREAM_READY_WR, &attempt);
if (ret == 0)
continue;
}
mu_error ("stream_open: %s", mu_strerror (ret));
exit (EXIT_FAILURE);
}
write_again:
for (attempt = 0, size = strlen (wbuf); size > 0; )
{
ret = stream_write (stream, wbuf + off, strlen (wbuf), 0, &nb);
if (ret != 0)
if (ret == 0)
{
if (ret == EAGAIN)
if (nb == 0)
{
int wflags = MU_STREAM_READY_WR;
stream_wait (stream, &wflags, NULL);
mu_error("stream_write: wrote 0 bytes");
exit (EXIT_FAILURE);
}
off += nb;
goto write_again;
size -= nb;
}
mu_error ("stream_write: %s", mu_strerror (ret));
else if (ret == EAGAIN)
{
if (attempt < io_attempts)
{
ret = http_stream_wait (stream, MU_STREAM_READY_WR, &attempt);
if (ret)
{
mu_error ("http_wait failed: %s", mu_strerror (ret));
return -1;
}
continue;
}
else
{
mu_error ("stream_write timed out");
exit (EXIT_FAILURE);
}
if (nb != strlen (wbuf))
}
else
{
mu_error ("stream_write: %s", "nb != wbuf length");
mu_error ("stream_write: %s", mu_strerror (ret));
exit (EXIT_FAILURE);
}
}
do
attempt = 0;
for (;;)
{
ret = stream_read (stream, rbuf, sizeof (rbuf), 0, &nb);
if (ret != 0)
if (ret == 0)
{
if (nb == 0)
break;
write (1, rbuf, nb);
}
else if (ret == EAGAIN)
{
if (attempt < io_attempts)
{
if (ret == EAGAIN)
ret = http_stream_wait (stream, MU_STREAM_READY_RD, &attempt);
if (ret)
{
int wflags = MU_STREAM_READY_RD;
stream_wait (stream, &wflags, NULL);
mu_error ("http_stream_wait failed: %s", mu_strerror (ret));
exit (EXIT_FAILURE);
}
}
else
{
......@@ -96,9 +168,7 @@ write_again:
exit (EXIT_FAILURE);
}
}
write (1, rbuf, nb);
}
while (nb || ret == EAGAIN);
ret = stream_close (stream);
if (ret != 0)
......