diff --git a/apps/discard.c b/apps/discard.c index 288d210..bfd63e3 100644 --- a/apps/discard.c +++ b/apps/discard.c @@ -13,6 +13,8 @@ static void discard_server (int sock) int host, connection, size; char buffer[1000]; + fprintf (stderr, "Listening to socket %d.\n", sock); + size = 8; if (ncp_listen (sock, &size, &host, &connection) == -1) { fprintf (stderr, "NCP listen error.\n"); @@ -22,12 +24,21 @@ static void discard_server (int sock) for (;;) { size = sizeof buffer; - if (ncp_read (connection, buffer, &size) == -1) + if (ncp_read (connection, buffer, &size) == -1) { fprintf (stderr, "NCP read error.\n"); - if (size <= 0) - return; + if (ncp_close (connection) == -1) + fprintf (stderr, "NCP close error.\n"); + break; + } + if (size == 0) + break; fprintf (stderr, "Read %d octets.\n", size); } + + if (ncp_unlisten (sock) == -1) { + fprintf (stderr, "NCP unlisten error.\n"); + exit (1); + } } static void usage (const char *argv0) diff --git a/apps/echo.c b/apps/echo.c index 1428da0..04cd7da 100644 --- a/apps/echo.c +++ b/apps/echo.c @@ -29,37 +29,45 @@ static void echo_client (int host, int sock) for (;;) { size = read (0, buffer, sizeof buffer); - if (size == -1) + if (size < 0) fprintf (stderr, "Read error.\n"); - if (size <= 0) - goto end; + if (size <= 0) { + if (ncp_close (connection) == -1) + fprintf (stderr, "NCP close error.\n"); + return; + } for (ptr = buffer; size > 0; ptr += n, size -= n) { n = size; - if (ncp_write (connection, ptr, &n) == -1) + if (ncp_write (connection, ptr, &n) == -1) { fprintf (stderr, "NCP read error.\n"); - if (n <= 0) - goto end; + if (ncp_close (connection) == -1) + fprintf (stderr, "NCP close error.\n"); + return; + } + if (n == 0) + return; } n = sizeof buffer; - if (ncp_read (connection, buffer, &n) == -1) + if (ncp_read (connection, buffer, &n) == -1) { fprintf (stderr, "NCP read error.\n"); - if (n <= 0) - goto end; + if (ncp_close (connection) == -1) + fprintf (stderr, "NCP close error.\n"); + return; + } + if (n == 0) + return; for (ptr = buffer; n > 0; n -= size) { size = write (1, ptr, n); - if (size < 0) + if (size < 0) { fprintf (stderr, "Write error.\n"); + if (ncp_close (connection) == -1) + fprintf (stderr, "NCP close error.\n"); + } if (size <= 0) - goto end; + return; } } - - end: - if (ncp_close (connection) == -1) { - fprintf (stderr, "NCP close error.\n"); - exit (1); - } } static void echo_server (int sock) @@ -67,6 +75,8 @@ static void echo_server (int sock) int host, connection, size, n; char buffer[1000], *ptr; + fprintf (stderr, "Listening to socket %d.\n", sock); + size = 8; if (ncp_listen (sock, &size, &host, &connection) == -1) { fprintf (stderr, "NCP listen error.\n"); @@ -76,18 +86,32 @@ static void echo_server (int sock) for (;;) { size = sizeof buffer; - if (ncp_read (connection, buffer, &size) == -1) + if (ncp_read (connection, buffer, &size) == -1) { fprintf (stderr, "NCP read error.\n"); - if (size <= 0) - return; + if (ncp_close (connection) == -1) + fprintf (stderr, "NCP close error.\n"); + goto end; + } + if (size == 0) + goto end; for (ptr = buffer; size > 0; ptr += n, size -= n) { n = size; - if (ncp_write (connection, ptr, &n) == -1) + if (ncp_write (connection, ptr, &n) == -1) { fprintf (stderr, "NCP read error.\n"); - if (n <= 0) - return; + if (ncp_close (connection) == -1) + fprintf (stderr, "NCP close error.\n"); + goto end; + } + if (n == 0) + goto end; } } + + end: + if (ncp_unlisten (sock) == -1) { + fprintf (stderr, "NCP unlisten error.\n"); + exit (1); + } } static void usage (const char *argv0) diff --git a/apps/finger.c b/apps/finger.c index cfcd607..a745b1c 100644 --- a/apps/finger.c +++ b/apps/finger.c @@ -46,14 +46,24 @@ int main (int argc, char **argv) argc == 3 ? argv[2] : ""); if (ncp_write (connection, command, &size) == -1) { fprintf (stderr, "NCP write error.\n"); + if (ncp_close (connection) == -1) + fprintf (stderr, "NCP close error.\n"); + exit (1); + } + if (size == 0) { + fprintf (stderr, "Connection closed.\n"); exit (1); } size = sizeof reply; if (ncp_read (connection, reply, &size) == -1) { fprintf (stderr, "NCP read error.\n"); + if (ncp_close (connection) == -1) + fprintf (stderr, "NCP close error.\n"); exit (1); } + if (size == 0) + exit (0); write (1, reply, size); diff --git a/apps/finser.c b/apps/finser.c index 4267a47..386b79b 100644 --- a/apps/finser.c +++ b/apps/finser.c @@ -5,6 +5,8 @@ #include #include "ncp.h" +#define SOCKET 0117 + int main (int argc, char **argv) { char command[1000]; @@ -25,16 +27,25 @@ int main (int argc, char **argv) exit (1); } + fprintf (stderr, "Listening to socket %d.\n", SOCKET); + size = 8; - if (ncp_listen (0117, &size, &host, &connection) == -1) { + if (ncp_listen (SOCKET, &size, &host, &connection) == -1) { fprintf (stderr, "NCP listen error.\n"); exit (1); } + fprintf (stderr, "Connection from host %03o.\n", host); size = sizeof command; if (ncp_read (connection, command, &size) == -1) { fprintf (stderr, "NCP read error.\n"); - exit (1); + if (ncp_close (connection) == -1) + fprintf (stderr, "NCP close error.\n"); + goto unlisten; + } + if (size == 0) { + fprintf (stderr, "Connection closed.\n"); + goto unlisten; } command[size] = 0; @@ -42,14 +53,17 @@ int main (int argc, char **argv) "Sample response from Finger server.\r\n" "Data from client was: \"%s\".\r\n", command); size = strlen (reply); - if (ncp_write (connection, reply, &size) == -1) { + if (ncp_write (connection, reply, &size) == -1) fprintf (stderr, "NCP write error.\n"); - exit (1); - } - if (ncp_close (connection) == -1) { + if (size != 0 && ncp_close (connection) == -1) fprintf (stderr, "NCP close error.\n"); + + unlisten: + if (ncp_unlisten (SOCKET) == -1) { + fprintf (stderr, "NCP unlisten error.\n"); exit (1); } + return 0; } diff --git a/apps/gateway.c b/apps/gateway.c index 1233fc4..33f8a61 100644 --- a/apps/gateway.c +++ b/apps/gateway.c @@ -140,6 +140,8 @@ static void tcp_to_ncp (const char *port, const char *host, const char *sock) int connection, foreign_port; int fd, s, size; + fprintf (stderr, "Listening to port %s.\n", port); + s = inet_server (port); fd = inet_accept (s, &foreign_host, &foreign_port); fprintf (stderr, "Connection from host %s on port %d.\n", @@ -161,6 +163,7 @@ static void tcp_to_ncp (const char *port, const char *host, const char *sock) exit (1); } + fprintf (stderr, "Forwarding to host %d socket %d.\n", ncp_host, ncp_sock); transport (fd, connection); if (ncp_close (connection) == -1) { @@ -173,6 +176,8 @@ static void ncp_to_tcp (int sock, const char *host, const char *port) { int fd, ncp_host, connection, size; + fprintf (stderr, "Listening to socket %d.\n", sock); + size = 8; if (ncp_listen (sock, &size, &ncp_host, &connection) == -1) { fprintf (stderr, "NCP listen error.\n"); @@ -181,10 +186,14 @@ static void ncp_to_tcp (int sock, const char *host, const char *port) fprintf (stderr, "Connection from host %03o on socket %d.\n", ncp_host, sock); fd = inet_connect (host, port); + fprintf (stderr, "Forwarding to host %s port %s.\n", host, port); transport (fd, connection); - if (ncp_close (connection) == -1) { + if (ncp_close (connection) == -1) fprintf (stderr, "NCP close error.\n"); + + if (ncp_unlisten (sock) == -1) { + fprintf (stderr, "NCP unlisten error.\n"); exit (1); } } diff --git a/apps/telnet.c b/apps/telnet.c index 7f3fad8..b2fc216 100644 --- a/apps/telnet.c +++ b/apps/telnet.c @@ -400,6 +400,7 @@ static void telnet_server (int host, int sock, fprintf (stderr, "NCP listen error.\n"); exit (1); } + fprintf (stderr, "Connection from host %03o.\n", host); reader_fd = reader (connection); writer_fd = writer (connection); @@ -456,8 +457,11 @@ static void telnet_server (int host, int sock, kill (reader_pid, SIGTERM); kill (writer_pid, SIGTERM); - if (ncp_close (connection) == -1) { + if (ncp_close (connection) == -1) fprintf (stderr, "NCP close error.\n"); + + if (ncp_unlisten (sock) == -1) { + fprintf (stderr, "NCP unlisten error.\n"); exit (1); } } diff --git a/src/libncp.c b/src/libncp.c index a3cdca1..68c3fb5 100644 --- a/src/libncp.c +++ b/src/libncp.c @@ -208,3 +208,20 @@ int ncp_close (int connection) return -1; return 0; } + +int ncp_unlisten (unsigned socket) +{ + type (WIRE_UNLISTEN); + add (socket >> 24); + add (socket >> 16); + add (socket >> 8); + add (socket); + if (transact () == -1) + return -1; + if (u32 (message + 1) != socket) + return -1; + if (message[5] == 0) + return 0; + else + return -1; +} diff --git a/src/ncp.c b/src/ncp.c index d13c6d0..7851ca9 100644 --- a/src/ncp.c +++ b/src/ncp.c @@ -638,6 +638,22 @@ static void reply_close (uint8_t i) client.sun_path, strerror (errno)); } +static void reply_unlisten (uint32_t socket, uint8_t e) +{ + uint8_t reply[6]; + fprintf (stderr, "NCP: Application unlisten reply socket %u: %u\n", + socket, e); + reply[0] = WIRE_UNLISTEN+1; + reply[1] = socket >> 24; + reply[2] = socket >> 16; + reply[3] = socket >> 8; + reply[4] = socket; + reply[5] = e; + if (sendto (fd, reply, sizeof reply, 0, (struct sockaddr *)&client, len) == -1) + fprintf (stderr, "NCP: sendto %s error: %s.\n", + client.sun_path, strerror (errno)); +} + static void maybe_reply (int i) { if ((connection[i].flags & CONN_GOT_BOTH) == CONN_GOT_BOTH) { @@ -1697,6 +1713,22 @@ static void app_close (void) unless_cls (i, cls_timeout); } +static void app_unlisten (void) +{ + uint32_t socket; + int i; + + socket = app[1] << 24 | app[2] << 16 | app[3] << 8 | app[4]; + fprintf (stderr, "NCP: Application unlisten to socket %u\n", socket); + if ((i = find_listen (socket)) != -1) { + listening[i].sock = 0; + reply_unlisten (socket, 0); + } else { + fprintf (stderr, "NCP: Not listening to %u.\n", socket); + reply_unlisten (socket, 1); + } +} + static void application (void) { ssize_t n; @@ -1724,6 +1756,7 @@ static void application (void) case WIRE_WRITE: app_write (n - 2); break; case WIRE_INTERRUPT: app_interrupt (); break; case WIRE_CLOSE: app_close (); break; + case WIRE_UNLISTEN: app_unlisten (); break; default: fprintf (stderr, "NCP: bad application request.\n"); break; } } diff --git a/src/ncp.h b/src/ncp.h index 7027eb4..c4775c9 100644 --- a/src/ncp.h +++ b/src/ncp.h @@ -8,3 +8,4 @@ extern int ncp_read (int connection, void *data, int *length); extern int ncp_write (int connection, void *data, int *length); extern int ncp_interrupt (int connection); extern int ncp_close (int connection); +extern int ncp_unlisten (unsigned socket); diff --git a/src/wire.h b/src/wire.h index 45c526f..5109c3b 100644 --- a/src/wire.h +++ b/src/wire.h @@ -7,6 +7,7 @@ #define WIRE_WRITE 9 #define WIRE_INTERRUPT 11 #define WIRE_CLOSE 13 +#define WIRE_UNLISTEN 15 static int wire_check (int type, int size) { @@ -25,6 +26,8 @@ static int wire_check (int type, int size) case WIRE_INTERRUPT+1: return size == 2; case WIRE_CLOSE: return size == 2; case WIRE_CLOSE+1: return size == 2; + case WIRE_UNLISTEN: return size == 5; + case WIRE_UNLISTEN+1: return size == 6; default: return 0; } }