+
+setproctitle(a, s)
+ char *a;
+ int s;
+{
+ int size;
+ register char *cp;
+ struct sockaddr_in sin;
+ char buf[80];
+
+ cp = Argv[0];
+ size = sizeof(sin);
+ if (getpeername(s, &sin, &size) == 0)
+ sprintf(buf, "-%s [%s]", a, inet_ntoa(sin.sin_addr));
+ else
+ sprintf(buf, "-%s", a);
+ strncpy(cp, buf, LastArg - cp);
+ cp += strlen(cp);
+ while (cp < LastArg)
+ *cp++ = ' ';
+}
+
+/*
+ * Internet services provided internally by inetd:
+ */
+
+/* ARGSUSED */
+echo_stream(s, sep) /* Echo service -- echo data back */
+ int s;
+ struct servtab *sep;
+{
+ char buffer[BUFSIZ];
+ int i;
+
+ setproctitle("echo", s);
+ while ((i = read(s, buffer, sizeof(buffer))) > 0 &&
+ write(s, buffer, i) > 0)
+ ;
+ exit(0);
+}
+
+/* ARGSUSED */
+echo_dg(s, sep) /* Echo service -- echo data back */
+ int s;
+ struct servtab *sep;
+{
+ char buffer[BUFSIZ];
+ int i, size;
+ struct sockaddr sa;
+
+ size = sizeof(sa);
+ if ((i = recvfrom(s, buffer, sizeof(buffer), 0, &sa, &size)) < 0)
+ return;
+ (void) sendto(s, buffer, i, 0, &sa, sizeof(sa));
+}
+
+/* ARGSUSED */
+discard_stream(s, sep) /* Discard service -- ignore data */
+ int s;
+ struct servtab *sep;
+{
+ char buffer[BUFSIZ];
+
+ setproctitle("discard", s);
+ while (1) {
+ while (read(s, buffer, sizeof(buffer)) > 0)
+ ;
+ if (errno != EINTR)
+ break;
+ }
+ exit(0);
+}
+
+/* ARGSUSED */
+discard_dg(s, sep) /* Discard service -- ignore data */
+ int s;
+ struct servtab *sep;
+{
+ char buffer[BUFSIZ];
+
+ (void) read(s, buffer, sizeof(buffer));
+}
+
+#include <ctype.h>
+#define LINESIZ 72
+char ring[128];
+char *endring;
+
+initring()
+{
+ register int i;
+
+ endring = ring;
+
+ for (i = 0; i <= 128; ++i)
+ if (isprint(i))
+ *endring++ = i;
+}
+
+/* ARGSUSED */
+chargen_stream(s, sep) /* Character generator */
+ int s;
+ struct servtab *sep;
+{
+ char text[LINESIZ+2];
+ register int i;
+ register char *rp, *rs, *dp;
+
+ setproctitle("discard", s);
+ if (endring == 0)
+ initring();
+
+ for (rs = ring; ; ++rs) {
+ if (rs >= endring)
+ rs = ring;
+ rp = rs;
+ dp = text;
+ i = MIN(LINESIZ, endring - rp);
+ bcopy(rp, dp, i);
+ dp += i;
+ if ((rp += i) >= endring)
+ rp = ring;
+ if (i < LINESIZ) {
+ i = LINESIZ - i;
+ bcopy(rp, dp, i);
+ dp += i;
+ if ((rp += i) >= endring)
+ rp = ring;
+ }
+ *dp++ = '\r';
+ *dp++ = '\n';
+
+ if (write(s, text, dp - text) != dp - text)
+ break;
+ }
+ exit(0);
+}
+
+/* ARGSUSED */
+chargen_dg(s, sep) /* Character generator */
+ int s;
+ struct servtab *sep;
+{
+ char text[LINESIZ+2];
+ register int i;
+ register char *rp;
+ static char *rs = ring;
+ struct sockaddr sa;
+ int size;
+
+ if (endring == 0)
+ initring();
+
+ size = sizeof(sa);
+ if (recvfrom(s, text, sizeof(text), 0, &sa, &size) < 0)
+ return;
+ rp = rs;
+ if (rs++ >= endring)
+ rs = ring;
+ i = MIN(LINESIZ - 2, endring - rp);
+ bcopy(rp, text, i);
+ if ((rp += i) >= endring)
+ rp = ring;
+ if (i < LINESIZ - 2) {
+ bcopy(rp, text, i);
+ if ((rp += i) >= endring)
+ rp = ring;
+ }
+ text[LINESIZ - 2] = '\r';
+ text[LINESIZ - 1] = '\n';
+
+ (void) sendto(s, text, sizeof(text), 0, &sa, sizeof(sa));
+}
+
+/*
+ * Return a machine readable date and time, in the form of the
+ * number of seconds since midnight, Jan 1, 1900. Since gettimeofday
+ * returns the number of seconds since midnight, Jan 1, 1970,
+ * we must add 2208988800 seconds to this figure to make up for
+ * some seventy years Bell Labs was asleep.
+ */
+
+long
+machtime()
+{
+ struct timeval tv;
+
+ if (gettimeofday(&tv, (struct timezone *)0) < 0) {
+ fprintf(stderr, "Unable to get time of day\n");
+ return (0L);
+ }
+ return (htonl((long)tv.tv_sec + 2208988800));
+}
+
+/* ARGSUSED */
+machtime_stream(s, sep)
+ int s;
+ struct servtab *sep;
+{
+ long result;
+
+ result = machtime();
+ (void) write(s, (char *) &result, sizeof(result));
+}
+
+/* ARGSUSED */
+machtime_dg(s, sep)
+ int s;
+ struct servtab *sep;
+{
+ long result;
+ struct sockaddr sa;
+ int size;
+
+ size = sizeof(sa);
+ if (recvfrom(s, (char *)&result, sizeof(result), 0, &sa, &size) < 0)
+ return;
+ result = machtime();
+ (void) sendto(s, (char *) &result, sizeof(result), 0, &sa, sizeof(sa));
+}
+
+/* ARGSUSED */
+daytime_stream(s, sep) /* Return human-readable time of day */
+ int s;
+ struct servtab *sep;
+{
+ char buffer[256];
+ time_t time(), clock;
+ char *ctime();
+
+ clock = time((time_t *) 0);
+
+ sprintf(buffer, "%s\r", ctime(&clock));
+ (void) write(s, buffer, strlen(buffer));
+}
+
+/* ARGSUSED */
+daytime_dg(s, sep) /* Return human-readable time of day */
+ int s;
+ struct servtab *sep;
+{
+ char buffer[256];
+ time_t time(), clock;
+ struct sockaddr sa;
+ int size;
+ char *ctime();
+
+ clock = time((time_t *) 0);
+
+ size = sizeof(sa);
+ if (recvfrom(s, buffer, sizeof(buffer), 0, &sa, &size) < 0)
+ return;
+ sprintf(buffer, "%s\r", ctime(&clock));
+ (void) sendto(s, buffer, strlen(buffer), 0, &sa, sizeof(sa));
+}
+
+/*
+ * print_service:
+ * Dump relevant information to stderr
+ */
+print_service(action, sep)
+ char *action;
+ struct servtab *sep;
+{
+ fprintf(stderr,
+ "%s: %s proto=%s, wait=%d, user=%s builtin=%x server=%s\n",
+ action, sep->se_service, sep->se_proto,
+ sep->se_wait, sep->se_user, sep->se_bi, sep->se_server);
+}