From 849e60108f8df449367f4a05eb489017bea35281 Mon Sep 17 00:00:00 2001 From: Sergey Poznyakoff Date: Wed, 25 Nov 2009 10:08:33 +0200 Subject: Implement TCPMUX internal service. * src/pies.h (CF_TCPMUX, CF_TCPMUXPLUS): New flags. (struct component): New member: service. (progman_lookup_service, progman_run_comp) (progman_iterate_comp): New protos. * src/progman.c (progman_iterate_comp) (prog_lookup_by_service) (progman_lookup_service): New functions (prog_start_prologue, prog_execute): New functions, extracted from prog_start. (progman_run_comp): New function. (prog_start): Replace extracted parts of code with calls to prog_start_prologue and prog_execute. * src/inetd-bi.c: Implement TCPMUX * src/inetd.c (inetd_conf_file): Handle tcpmux extries. --- src/inetd-bi.c | 116 ++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 99 insertions(+), 17 deletions(-) (limited to 'src/inetd-bi.c') diff --git a/src/inetd-bi.c b/src/inetd-bi.c index f86f373..60e6fb5 100644 --- a/src/inetd-bi.c +++ b/src/inetd-bi.c @@ -20,7 +20,7 @@ #define INTBUFSIZE 8192 /* Echo protocol, RFC 862 */ -void +static void echo_stream (int fd) { int rc; @@ -31,7 +31,7 @@ echo_stream (int fd) ; } -void +static void echo_dg (int fd) { int rc; @@ -46,7 +46,7 @@ echo_dg (int fd) } /* Discard protocol, RFC 863 */ -void +static void discard_stream (int fd) { int rc; @@ -61,7 +61,7 @@ discard_stream (int fd) } } -void +static void discard_dg (int fd) { char buffer[INTBUFSIZE]; @@ -76,7 +76,7 @@ discard_dg (int fd) #define SEVENTY_YEARS ((unsigned long)25567 * 24 * 60 * 60) -unsigned long +static unsigned long time_since_1900 (void) { struct timeval tv; @@ -89,14 +89,14 @@ time_since_1900 (void) return htonl ((long) (tv.tv_sec + SEVENTY_YEARS)); } -void +static void time_stream (int fd) { unsigned long result = time_since_1900 (); write (fd, (char *) &result, sizeof result); } -void +static void time_dg (int fd) { unsigned long result; @@ -110,7 +110,7 @@ time_dg (int fd) } /* Daytime Protocol, RFC 867 */ -void +static void daytime_stream (int fd) { char buffer[27]; @@ -121,7 +121,7 @@ daytime_stream (int fd) write (fd, buffer, strlen (buffer)); } -void +static void daytime_dg (int fd) { char buffer[27]; @@ -159,7 +159,7 @@ chargen_next_line (char *text) } } -void +static void chargen_stream (int fd) { char text[LINESIZ + 2]; @@ -175,7 +175,7 @@ chargen_stream (int fd) } } -void +static void chargen_dg (int fd) { struct sockaddr sa; @@ -218,7 +218,7 @@ trnl (char *text, size_t size) return size; } -size_t +static size_t qotd_read (char *text) { ssize_t rc; @@ -246,7 +246,7 @@ qotd_read (char *text) return rc; } -void +static void qotd_stream (int fd) { char text[QOTD_MAX]; @@ -254,7 +254,7 @@ qotd_stream (int fd) write (fd, text, len); } -void +static void qotd_dg (int fd) { char text[QOTD_MAX]; @@ -267,7 +267,90 @@ qotd_dg (int fd) sendto (fd, text, len, 0, &sa, sizeof sa); } + +/* TCPMUX service, RFC 1078 */ +#define MAX_SERV_LEN (256+2) + +static int +fd_getline (int fd, char *buf, int len) +{ + int count = 0, n; + + do + { + n = read (fd, buf, len - count); + if (n == 0) + return count; + if (n < 0) + return -1; + while (--n >= 0) + { + if (*buf == '\r' || *buf == '\n' || *buf == '\0') + return count; + count++; + buf++; + } + } + while (count < len); + return count; +} + +static int +fd_write (int fd, const char *text) +{ + return write (fd, text, strlen (text)); +} + +static int +tcpmux_help (struct component *comp, void *data) +{ + int *pfd = data; + + if (comp->flags & (CF_TCPMUXPLUS | CF_TCPMUX)) + { + fd_write (*pfd, comp->service); + fd_write (*pfd, "\r\n"); + } + return 0; +} +static void +tcpmux (int fd) +{ + char service[MAX_SERV_LEN + 1]; + size_t len; + struct component *comp; + + /* Read service name */ + if ((len = fd_getline (fd, service, MAX_SERV_LEN)) < 0) + { + fd_write (fd, "-Error reading service name\r\n"); + return; + } + service[len] = 0; + + debug (2, ("tcpmux: someone wants %s", service)); + + if (!strcasecmp (service, "help")) + { + progman_iterate_comp (tcpmux_help, &fd); + return; + } + + comp = progman_lookup_service (service); + if (!comp) + { + fd_write (fd, "-Service not available\r\n"); + return; + } + + if (comp->flags & CF_TCPMUXPLUS) + fd_write (fd, "+Go\r\n"); + + progman_run_comp (comp, fd); +} + + struct inetd_builtin inetd_builtin_tab[] = { /* Echo received data */ {"echo", SOCK_STREAM, 0, 0, echo_stream}, @@ -287,9 +370,8 @@ struct inetd_builtin inetd_builtin_tab[] = { /* Quote of the Day */ {"qotd", SOCK_STREAM, 0, 0, qotd_stream}, {"qotd", SOCK_DGRAM, 1, 0, qotd_dg}, -#if 0 - {"tcpmux", SOCK_STREAM, 0, 0, tcpmux}, -#endif + /* TCPMUX */ + {"tcpmux", SOCK_STREAM, 0, 0, tcpmux}, {NULL, 0, 0, 0, NULL} }; -- cgit v1.2.1