diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/builtin.at | 77 | ||||
-rw-r--r-- | tests/chargen.c | 11 | ||||
-rw-r--r-- | tests/nt.c | 145 |
3 files changed, 211 insertions, 22 deletions
diff --git a/tests/builtin.at b/tests/builtin.at index 40f65fa..893f213 100644 --- a/tests/builtin.at +++ b/tests/builtin.at @@ -126,6 +126,83 @@ IT_BUILTIN([qotd],[], A quote of the day service simply sends a short message without regard to the input. ]) m4_popdef([IT_BUILTIN]) m4_popdef([IT_SPECIAL]) + +# IT_TCPMUX([KW],[ID],[INPUT],[OUTPUT]) +m4_define([IT_TCPMUX], +[AT_SETUP([tcpmux: $1]) +AT_KEYWORDS([inetd builtin internal tcpmux $1]) +AT_CHECK([ +PIES_XFAIL_CHECK +PIES_CONTROL_INIT +: ${PIES_TEST_INET_SOCKET:=unix://$PWD/in.sock} +m4_if([$3],[],[],[AT_DATA([input],[$3])]) +cat > pies.conf <<_EOT +component master { + socket "$PIES_TEST_INET_SOCKET"; + service tcpmux; + flags internal; +} +component one { + service one; + flags (tcpmuxplus); + tcpmux-master master; + command "$auxdir/in.test $PWD/one.log"; + stderr file "$PWD/one.err"; +} +component two { + service two; + flags (tcpmuxplus); + tcpmux-master master; + command "$auxdir/in.test $PWD/two.log"; + stderr file "$PWD/two.err"; +} +component test { + command "nt -t [$2]m4_if([$3],[],,[ -i $PWD/input]) -o $PWD/test.out '$PIES_TEST_INET_SOCKET'"; + stderr file "$PWD/test.err"; + return-code * { + action disable; + exec "piesctl --no-netrc --url=$PIES_CTLSOCK shutdown"; + } +} +_EOT + +set -e +to 10 \ + pies --foreground --stderr \ + --config-file control.conf --config-file pies.conf --debug 1 2>errlog + +for err in one.err two.err test.err +do + if test -s $err; then + echo "$err:" + cat $err + fi +done >&2 + +if test -f test.out; then + cat test.out | tr -d '\r' +fi +], +[0], +[$4]) +AT_CLEANUP +]) + +IT_TCPMUX([help],[help],[], +[one +two +]) + +IT_TCPMUX([service],[one], +[Test one +quit +], +[OK Test one +]) + +m4_popdef([IT_TCPMUX]) + + diff --git a/tests/chargen.c b/tests/chargen.c index a3b3290..75d096c 100644 --- a/tests/chargen.c +++ b/tests/chargen.c @@ -73,19 +73,26 @@ main (int argc, char **argv) fprintf (stderr, "Tests the character generator protocol\n"); return 64; } if (pies_url_create (&url, argv[1])) { - perror (argv[0]); + perror (argv[1]); return 64; } fd = url_connect (url, NULL); + if (fd == -1) + return 1; fp = fdopen (fd, "r"); - + if (!fp) + { + perror ("fdopen"); + return 1; + } + first = next_char (0); c = first; do { int in = fgetc (fp); if (in == EOF) @@ -133,13 +133,13 @@ netcat_stream_read (netcat_server_t *srv) n = iobuf_fill (&srv->buf[IN], srv->pollfd->fd); if (n == -1) { if (errno == EINTR) return 0; grecs_error (NULL, errno, "%s: read", srv->id); - srv->pollfd->events &= ~POLLIN; + netcat_stream_disconnect (srv, POLLIN); return -1; } if (n == 0 || !peer_is_state (srv, POLLOUT)) { /* No more input is expected || needed */ netcat_stream_disconnect (srv, POLLIN); @@ -182,17 +182,18 @@ netcat_stream_write (netcat_server_t *srv) n = iobuf_flush (&srv->buf[OUT], srv->pollfd->fd); if (n == -1) { if (errno == EINTR) return 0; grecs_error (NULL, errno, "%s: write", srv->id); + netcat_stream_disconnect (srv, POLLOUT); return -1; } if (n == 0) { - // FIXME: eof + netcat_stream_disconnect (srv, POLLOUT); return -1; } return 0; } int @@ -217,14 +218,105 @@ int disconnect_stdout (netcat_server_t *srv) { close (srv->pollfd->fd); exit (0); } +void +fd_write (int fd, char const *str, size_t len) +{ + while (len) + { + ssize_t n = write (fd, str, len); + if (n == -1) + { + perror ("socket write"); + exit (1); + } + if (n == 0) + { + fprintf (stderr, "zero write\n"); + exit (1); + } + len -= n; + str += n; + } +} + +void +fd_writeln (int fd, char const *str) +{ + fd_write (fd, str, strlen (str)); + fd_write (fd, "\r\n", 2); +} + +int +fd_getc (int fd) +{ + char c; + ssize_t n = read (fd, &c, 1); + if (n == -1) + { + perror ("socket read"); + exit (1); + } + if (n == 0) + c = EOF; + return c; +} + +static void +tcpmux_init (int fd, char const *service) +{ + int c; + + fd_writeln (fd, service); + + if (strcmp (service, "help") == 0) + { + while ((c = fd_getc (fd)) != EOF) + { + fputc (c, stdout); + } + close (fd); + exit (0); + } + + c = fd_getc (fd); + if (c == 0) + { + fprintf (stderr, "socket read: unexpected eof\n"); + exit (1); + } + if (c == '+') + { + while ((c = fd_getc (fd)) != '\n') + { + if (c == EOF) + { + fprintf (stderr, "socket read: unexpected eof\n"); + exit (1); + } + } + } + else + { + fprintf (stderr, "service rejected: "); + do + { + if (c != '\r') + fputc (c, stderr); + } + while ((c = fd_getc (fd)) != 0 && c != '\n'); + fputc ('\n', stderr); + exit (1); + } +} + static int -netcat (char const *urlstr) +netcat (char const *urlstr, char const *tcpmux_service) { int fd; struct pies_url *url; struct pollfd pfd[3]; int nfd = sizeof (pfd) / sizeof (pfd[0]); netcat_server_t *srvin, *srvout, *srv; @@ -236,12 +328,15 @@ netcat (char const *urlstr) } fd = url_connect (url, NULL); if (fd == -1) return 1; + if (tcpmux_service) + tcpmux_init (fd, tcpmux_service); + pfd[0].fd = 0; pfd[0].events = 0; srvin = netcat_server_create ("stdin", &pfd[0], POLLIN, disconnect_stdin, NULL); pfd[1].fd = 1; pfd[1].events = 0; @@ -262,31 +357,32 @@ netcat (char const *urlstr) grecs_error (NULL, errno, "poll"); continue; } for (srv = server_head; srv; ) { netcat_server_t *next = srv->next; - int events; - events = (srv->pollfd->events|POLLHUP) - & (srv->pollfd->revents - & (srv->state | ((srv->state & POLLOUT) ? POLLHUP : 0))); - if (events) + if ((srv->pollfd->revents & srv->state) & POLLIN) + netcat_stream_read (srv); + if ((srv->pollfd->revents & srv->state) & POLLOUT) + netcat_stream_write (srv); + if ((srv->state & POLLOUT) && (srv->pollfd->revents & POLLHUP)) { - if (events & POLLIN) - netcat_stream_read (srv); - if (events & POLLOUT) - netcat_stream_write (srv); - if (events & POLLHUP) + //grecs_error (NULL, 0, "HUP on %s", srv->id); + netcat_stream_disconnect (srv, srv->state); + } + if (srv->state == 0 || srv->pollfd->fd == -1) + { + netcat_server_t *peer = srv->peer; + if (peer && peer->pollfd->events == 0) { - //grecs_error (NULL, 0, "HUP on %s", srv->id); - netcat_stream_disconnect (srv, srv->state); + netcat_stream_disconnect (peer, peer->state); + netcat_server_remove (peer); } + netcat_server_remove (srv); } - if (srv->state == 0 || srv->pollfd->fd == -1) - netcat_server_remove (srv); srv = next; } } return 0; } @@ -308,34 +404,43 @@ redirect (int sfd, char const *name) } } static void usage (FILE *fp) { - fprintf (fp, "usage: nt [-i IFILE] [-o OFILE] URL\n"); + fprintf (fp, "usage: nt [-i IFILE] [-o OFILE] [-t SERVICE] URL\n"); fprintf (fp, "Reads data from stdin (or IFILE) and sends them to URL.\n"); fprintf (fp, "Reads replies from URL and sends them to stdout (or OFILE).\n"); + fprintf (fp, "\nOPTIONS\n\n"); + fprintf (fp, " -t SERVICE use TCPMUX service\n"); + fprintf (fp, " -i IFILE read input from IFILE\n"); + fprintf (fp, " -o OFILE write output to OFILE\n"); } int main (int argc, char **argv) { int c; + char const *tcpmux_service = NULL; - while ((c = getopt (argc, argv, "i:o:")) != EOF) + while ((c = getopt (argc, argv, "i:o:t:")) != EOF) { switch (c) { case 'i': redirect (0, optarg); break; case 'o': redirect (1, optarg); break; + case 't': + tcpmux_service = optarg; + break; + default: exit (64); } } argc -= optind; @@ -344,8 +449,8 @@ main (int argc, char **argv) if (argc != 1) { usage (stderr); exit (64); } - return netcat (argv[0]); + return netcat (argv[0], tcpmux_service); } |