Deleted Added
full compact
inetd.c (48962) inetd.c (48981)
1/*
2 * Copyright (c) 1983, 1991, 1993, 1994
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 28 unchanged lines hidden (view full) ---

37 The Regents of the University of California. All rights reserved.\n";
38#endif /* not lint */
39
40#ifndef lint
41#if 0
42static char sccsid[] = "@(#)from: inetd.c 8.4 (Berkeley) 4/13/94";
43#endif
44static const char rcsid[] =
1/*
2 * Copyright (c) 1983, 1991, 1993, 1994
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 28 unchanged lines hidden (view full) ---

37 The Regents of the University of California. All rights reserved.\n";
38#endif /* not lint */
39
40#ifndef lint
41#if 0
42static char sccsid[] = "@(#)from: inetd.c 8.4 (Berkeley) 4/13/94";
43#endif
44static const char rcsid[] =
45 "$Id: inetd.c,v 1.62 1999/07/21 12:19:24 sheldonh Exp $";
45 "$Id: inetd.c,v 1.63 1999/07/21 16:09:45 sheldonh Exp $";
46#endif /* not lint */
47
48/*
49 * Inetd - Internet super-server
50 *
51 * This program invokes all internet services as needed. Connection-oriented
52 * services are invoked each time a connection is made, by creating a process.
53 * This process is passed the connection as file descriptor 0 and is expected

--- 45 unchanged lines hidden (view full) ---

99 * wait/nowait single-threaded/multi-threaded
100 * user user to run daemon as
101 * server program full path name
102 * server program arguments maximum of MAXARGS
103 *
104 * Comment lines are indicated by a `#' in column 1.
105 */
106#include <sys/param.h>
46#endif /* not lint */
47
48/*
49 * Inetd - Internet super-server
50 *
51 * This program invokes all internet services as needed. Connection-oriented
52 * services are invoked each time a connection is made, by creating a process.
53 * This process is passed the connection as file descriptor 0 and is expected

--- 45 unchanged lines hidden (view full) ---

99 * wait/nowait single-threaded/multi-threaded
100 * user user to run daemon as
101 * server program full path name
102 * server program arguments maximum of MAXARGS
103 *
104 * Comment lines are indicated by a `#' in column 1.
105 */
106#include <sys/param.h>
107#include <sys/stat.h>
108#include <sys/ioctl.h>
107#include <sys/ioctl.h>
109#include <sys/socket.h>
110#include <sys/wait.h>
111#include <sys/time.h>
112#include <sys/resource.h>
108#include <sys/wait.h>
109#include <sys/time.h>
110#include <sys/resource.h>
113#include <sys/sysctl.h>
114#include <sys/ucred.h>
115
116#include <netinet/in.h>
117#include <netinet/tcp.h>
118#include <arpa/inet.h>
119#include <rpc/rpc.h>
120#include <rpc/pmap_clnt.h>
121
111
112#include <netinet/in.h>
113#include <netinet/tcp.h>
114#include <arpa/inet.h>
115#include <rpc/rpc.h>
116#include <rpc/pmap_clnt.h>
117
122#include <ctype.h>
123#include <errno.h>
124#include <err.h>
125#include <fcntl.h>
126#include <grp.h>
127#include <netdb.h>
128#include <pwd.h>
129#include <signal.h>
130#include <stdio.h>
131#include <stdlib.h>
132#include <string.h>
133#include <syslog.h>
134#include <tcpd.h>
135#include <unistd.h>
136#include <libutil.h>
137#include <sysexits.h>
138
118#include <errno.h>
119#include <err.h>
120#include <fcntl.h>
121#include <grp.h>
122#include <netdb.h>
123#include <pwd.h>
124#include <signal.h>
125#include <stdio.h>
126#include <stdlib.h>
127#include <string.h>
128#include <syslog.h>
129#include <tcpd.h>
130#include <unistd.h>
131#include <libutil.h>
132#include <sysexits.h>
133
134#include "inetd.h"
135#include "pathnames.h"
136
139#ifndef LIBWRAP_ALLOW_FACILITY
140# define LIBWRAP_ALLOW_FACILITY LOG_AUTH
141#endif
142#ifndef LIBWRAP_ALLOW_SEVERITY
143# define LIBWRAP_ALLOW_SEVERITY LOG_INFO
144#endif
145#ifndef LIBWRAP_DENY_FACILITY
146# define LIBWRAP_DENY_FACILITY LOG_AUTH

--- 10 unchanged lines hidden (view full) ---

157#ifdef LOGIN_CAP
158#include <login_cap.h>
159
160/* see init.c */
161#define RESOURCE_RC "daemon"
162
163#endif
164
137#ifndef LIBWRAP_ALLOW_FACILITY
138# define LIBWRAP_ALLOW_FACILITY LOG_AUTH
139#endif
140#ifndef LIBWRAP_ALLOW_SEVERITY
141# define LIBWRAP_ALLOW_SEVERITY LOG_INFO
142#endif
143#ifndef LIBWRAP_DENY_FACILITY
144# define LIBWRAP_DENY_FACILITY LOG_AUTH

--- 10 unchanged lines hidden (view full) ---

155#ifdef LOGIN_CAP
156#include <login_cap.h>
157
158/* see init.c */
159#define RESOURCE_RC "daemon"
160
161#endif
162
165#include "pathnames.h"
166
167#ifndef MAXCHILD
168#define MAXCHILD -1 /* maximum number of this service
169 < 0 = no limit */
170#endif
171
172#ifndef MAXCPM
173#define MAXCPM -1 /* rate limit invocations from a
174 single remote address,

--- 20 unchanged lines hidden (view full) ---

195int toomany = TOOMANY;
196int maxchild = MAXCHILD;
197int maxcpm = MAXCPM;
198struct servent *sp;
199struct rpcent *rpc;
200struct in_addr bind_address;
201int signalpipe[2];
202
163#ifndef MAXCHILD
164#define MAXCHILD -1 /* maximum number of this service
165 < 0 = no limit */
166#endif
167
168#ifndef MAXCPM
169#define MAXCPM -1 /* rate limit invocations from a
170 single remote address,

--- 20 unchanged lines hidden (view full) ---

191int toomany = TOOMANY;
192int maxchild = MAXCHILD;
193int maxcpm = MAXCPM;
194struct servent *sp;
195struct rpcent *rpc;
196struct in_addr bind_address;
197int signalpipe[2];
198
203struct servtab {
204 char *se_service; /* name of service */
205 int se_socktype; /* type of socket to use */
206 char *se_proto; /* protocol used */
207 int se_maxchild; /* max number of children */
208 int se_maxcpm; /* max connects per IP per minute */
209 int se_numchild; /* current number of children */
210 pid_t *se_pids; /* array of child pids */
211 char *se_user; /* user name to run as */
212 char *se_group; /* group name to run as */
213#ifdef LOGIN_CAP
214 char *se_class; /* login class name to run with */
215#endif
216 struct biltin *se_bi; /* if built-in, description */
217 char *se_server; /* server program */
218 char *se_server_name; /* server program without path */
219#define MAXARGV 20
220 char *se_argv[MAXARGV+1]; /* program arguments */
221 int se_fd; /* open descriptor */
222 struct sockaddr_in se_ctrladdr;/* bound address */
223 u_char se_type; /* type: normal, mux, or mux+ */
224 u_char se_checked; /* looked at during merge */
225 u_char se_accept; /* i.e., wait/nowait mode */
226 u_char se_rpc; /* ==1 if RPC service */
227 int se_rpc_prog; /* RPC program number */
228 u_int se_rpc_lowvers; /* RPC low version */
229 u_int se_rpc_highvers; /* RPC high version */
230 int se_count; /* number started since se_time */
231 struct timeval se_time; /* start of se_count */
232 struct servtab *se_next;
233} *servtab;
199struct servtab *servtab;
234
200
235#define NORM_TYPE 0
236#define MUX_TYPE 1
237#define MUXPLUS_TYPE 2
238#define TTCP_TYPE 3
239#define ISMUX(sep) (((sep)->se_type == MUX_TYPE) || \
240 ((sep)->se_type == MUXPLUS_TYPE))
241#define ISMUXPLUS(sep) ((sep)->se_type == MUXPLUS_TYPE)
242#define ISTTCP(sep) ((sep)->se_type == TTCP_TYPE)
201extern struct biltin biltins[];
243
202
244
245void chargen_dg __P((int, struct servtab *));
246void chargen_stream __P((int, struct servtab *));
247void close_sep __P((struct servtab *));
248void flag_signal __P((char));
249void flag_config __P((int));
250void config __P((void));
251void daytime_dg __P((int, struct servtab *));
252void daytime_stream __P((int, struct servtab *));
253void discard_dg __P((int, struct servtab *));
254void discard_stream __P((int, struct servtab *));
255void echo_dg __P((int, struct servtab *));
256void echo_stream __P((int, struct servtab *));
257void endconfig __P((void));
258struct servtab *enter __P((struct servtab *));
259void freeconfig __P((struct servtab *));
260struct servtab *getconfigent __P((void));
261void iderror __P((int, int, FILE *, int));
262void ident_stream __P((int, struct servtab *));
263void machtime_dg __P((int, struct servtab *));
264void machtime_stream __P((int, struct servtab *));
265int matchservent __P((char *, char *, char *));
266char *newstr __P((char *));
267char *nextline __P((FILE *));
268void print_service __P((char *, struct servtab *));
269void addchild __P((struct servtab *, int));
270void flag_reapchild __P((int));
271void reapchild __P((void));
272void enable __P((struct servtab *));
273void disable __P((struct servtab *));
274void flag_retry __P((int));
275void retry __P((void));
276int setconfig __P((void));
277void setup __P((struct servtab *));
278char *sskip __P((char **));
279char *skip __P((char **));
280struct servtab *tcpmux __P((int));
281int cpmip __P((struct servtab *, int));
282void inetd_setproctitle __P((char *, int));
283
284void unregisterrpc __P((register struct servtab *sep));
285
286struct biltin {
287 char *bi_service; /* internally provided service name */
288 int bi_socktype; /* type of socket supported */
289 short bi_fork; /* 1 if should fork before call */
290 int bi_maxchild; /* max number of children (-1=default) */
291 void (*bi_fn)(); /* function which performs it */
292} biltins[] = {
293 /* Echo received data */
294 { "echo", SOCK_STREAM, 1, -1, echo_stream },
295 { "echo", SOCK_DGRAM, 0, 1, echo_dg },
296
297 /* Internet /dev/null */
298 { "discard", SOCK_STREAM, 1, -1, discard_stream },
299 { "discard", SOCK_DGRAM, 0, 1, discard_dg },
300
301 /* Return 32 bit time since 1970 */
302 { "time", SOCK_STREAM, 0, -1, machtime_stream },
303 { "time", SOCK_DGRAM, 0, 1, machtime_dg },
304
305 /* Return human-readable time */
306 { "daytime", SOCK_STREAM, 0, -1, daytime_stream },
307 { "daytime", SOCK_DGRAM, 0, 1, daytime_dg },
308
309 /* Familiar character generator */
310 { "chargen", SOCK_STREAM, 1, -1, chargen_stream },
311 { "chargen", SOCK_DGRAM, 0, 1, chargen_dg },
312
313 { "tcpmux", SOCK_STREAM, 1, -1, (void (*)())tcpmux },
314
315 { "auth", SOCK_STREAM, 1, -1, ident_stream },
316
317 { NULL }
318};
319
320#define NUMINT (sizeof(intab) / sizeof(struct inent))
321char *CONFIG = _PATH_INETDCONF;
322char *pid_file = _PATH_INETDPID;
323
324#ifdef OLD_SETPROCTITLE
325char **Argv;
326char *LastArg;
327#endif

--- 1293 unchanged lines hidden (view full) ---

1621 setproctitle("%s", buf);
1622}
1623#endif
1624
1625
1626/*
1627 * Internet services provided internally by inetd:
1628 */
203#define NUMINT (sizeof(intab) / sizeof(struct inent))
204char *CONFIG = _PATH_INETDCONF;
205char *pid_file = _PATH_INETDPID;
206
207#ifdef OLD_SETPROCTITLE
208char **Argv;
209char *LastArg;
210#endif

--- 1293 unchanged lines hidden (view full) ---

1504 setproctitle("%s", buf);
1505}
1506#endif
1507
1508
1509/*
1510 * Internet services provided internally by inetd:
1511 */
1629#define BUFSIZE 8192
1630
1512
1631/* ARGSUSED */
1632void
1633iderror(lport, fport, fp, er)
1634 int lport, fport, er;
1635 FILE *fp;
1636{
1637 fprintf(fp, "%d , %d : ERROR : %s\r\n", lport, fport,
1638 er == -1 ? "HIDDEN-USER" : er ? strerror(er) : "UNKNOWN-ERROR");
1639 fflush(fp);
1640 fclose(fp);
1641
1642 exit(0);
1643}
1644
1645/* ARGSUSED */
1646void
1647ident_stream(s, sep) /* Ident service */
1648 int s;
1649 struct servtab *sep;
1650{
1651 struct sockaddr_in sin[2];
1652 struct ucred uc;
1653 struct passwd *pw;
1654 FILE *fp;
1655 char buf[BUFSIZE], *cp, **av;
1656 int len, c, rflag = 0, fflag = 0, argc = 0;
1657 u_short lport, fport;
1658
1659 inetd_setproctitle(sep->se_service, s);
1660 optind = 1;
1661 optreset = 1;
1662 for (av = sep->se_argv; *av; av++)
1663 argc++;
1664 if (argc) {
1665 while ((c = getopt(argc, sep->se_argv, "fr")) != -1)
1666 switch (c) {
1667 case 'f':
1668 fflag = 1;
1669 break;
1670 case 'r':
1671 rflag = 1;
1672 break;
1673 default:
1674 break;
1675 }
1676 }
1677 fp = fdopen(s, "r+");
1678 len = sizeof(sin[0]);
1679 if (getsockname(s, (struct sockaddr *)&sin[0], &len) == -1)
1680 iderror(0, 0, fp, errno);
1681 len = sizeof(sin[1]);
1682 if (getpeername(s, (struct sockaddr *)&sin[1], &len) == -1)
1683 iderror(0, 0, fp, errno);
1684 errno = 0;
1685 if (fgets(buf, sizeof(buf), fp) == NULL)
1686 iderror(0, 0, fp, errno);
1687 buf[BUFSIZE - 1] = '\0';
1688 strtok(buf, "\r\n");
1689 cp = strtok(buf, ",");
1690 if (cp == NULL || sscanf(cp, "%hu", &lport) != 1)
1691 iderror(0, 0, fp, 0);
1692 cp = strtok(NULL, ",");
1693 if (cp == NULL || sscanf(cp, "%hu", &fport) != 1)
1694 iderror(0, 0, fp, 0);
1695 if (!rflag)
1696 iderror(lport, fport, fp, -1);
1697 sin[0].sin_port = htons(lport);
1698 sin[1].sin_port = htons(fport);
1699 len = sizeof(uc);
1700 if (sysctlbyname("net.inet.tcp.getcred", &uc, &len, sin,
1701 sizeof(sin)) == -1)
1702 iderror(lport, fport, fp, errno);
1703 pw = getpwuid(uc.cr_uid);
1704 if (pw == NULL)
1705 iderror(lport, fport, fp, errno);
1706 if (fflag) {
1707 FILE *fakeid = NULL;
1708 char fakeid_path[PATH_MAX];
1709 struct stat sb;
1710 seteuid(pw->pw_uid);
1711 setegid(pw->pw_gid);
1712 snprintf(fakeid_path, sizeof(fakeid_path), "%s/.fakeid",
1713 pw->pw_dir);
1714 if ((fakeid = fopen(fakeid_path, "r")) != NULL &&
1715 fstat(fileno(fakeid), &sb) != -1 && S_ISREG(sb.st_mode)) {
1716 buf[sizeof(buf) - 1] = '\0';
1717 if (fgets(buf, sizeof(buf), fakeid) == NULL) {
1718 cp = pw->pw_name;
1719 fclose(fakeid);
1720 goto printit;
1721 }
1722 fclose(fakeid);
1723 strtok(buf, "\r\n");
1724 if (strlen(buf) > 16)
1725 buf[16] = '\0';
1726 cp = buf;
1727 while (isspace(*cp))
1728 cp++;
1729 strtok(cp, " \t");
1730 if (!*cp || getpwnam(cp))
1731 cp = getpwuid(uc.cr_uid)->pw_name;
1732 } else
1733 cp = pw->pw_name;
1734 } else
1735 cp = pw->pw_name;
1736printit:
1737 fprintf(fp, "%d , %d : USERID : FreeBSD :%s\r\n", lport, fport,
1738 cp);
1739 fflush(fp);
1740 fclose(fp);
1741
1742 exit(0);
1743}
1744
1745/* ARGSUSED */
1746void
1747echo_stream(s, sep) /* Echo service -- echo data back */
1748 int s;
1749 struct servtab *sep;
1750{
1751 char buffer[BUFSIZE];
1752 int i;
1753
1754 inetd_setproctitle(sep->se_service, s);
1755 while ((i = read(s, buffer, sizeof(buffer))) > 0 &&
1756 write(s, buffer, i) > 0)
1757 ;
1758 exit(0);
1759}
1760
1761int check_loop(sin, sep)
1762 struct sockaddr_in *sin;
1763 struct servtab *sep;
1764{
1765 struct servtab *se2;
1766
1767 for (se2 = servtab; se2; se2 = se2->se_next) {
1768 if (!se2->se_bi || se2->se_socktype != SOCK_DGRAM)

--- 6 unchanged lines hidden (view full) ---

1775 se2->se_service, se2->se_proto,
1776 inet_ntoa(sin->sin_addr));
1777 return 1;
1778 }
1779 }
1780 return 0;
1781}
1782
1513int check_loop(sin, sep)
1514 struct sockaddr_in *sin;
1515 struct servtab *sep;
1516{
1517 struct servtab *se2;
1518
1519 for (se2 = servtab; se2; se2 = se2->se_next) {
1520 if (!se2->se_bi || se2->se_socktype != SOCK_DGRAM)

--- 6 unchanged lines hidden (view full) ---

1527 se2->se_service, se2->se_proto,
1528 inet_ntoa(sin->sin_addr));
1529 return 1;
1530 }
1531 }
1532 return 0;
1533}
1534
1783/* ARGSUSED */
1784void
1785echo_dg(s, sep) /* Echo service -- echo data back */
1786 int s;
1787 struct servtab *sep;
1788{
1789 char buffer[BUFSIZE];
1790 int i, size;
1791 struct sockaddr_in sin;
1792
1793 size = sizeof(sin);
1794 if ((i = recvfrom(s, buffer, sizeof(buffer), 0,
1795 (struct sockaddr *)&sin, &size)) < 0)
1796 return;
1797
1798 if (check_loop(&sin, sep))
1799 return;
1800
1801 (void) sendto(s, buffer, i, 0, (struct sockaddr *)&sin,
1802 sizeof(sin));
1803}
1804
1805/* ARGSUSED */
1806void
1807discard_stream(s, sep) /* Discard service -- ignore data */
1808 int s;
1809 struct servtab *sep;
1810{
1811 int ret;
1812 char buffer[BUFSIZE];
1813
1814 inetd_setproctitle(sep->se_service, s);
1815 while (1) {
1816 while ((ret = read(s, buffer, sizeof(buffer))) > 0)
1817 ;
1818 if (ret == 0 || errno != EINTR)
1819 break;
1820 }
1821 exit(0);
1822}
1823
1824/* ARGSUSED */
1825void
1826discard_dg(s, sep) /* Discard service -- ignore data */
1827 int s;
1828 struct servtab *sep;
1829{
1830 char buffer[BUFSIZE];
1831
1832 (void) read(s, buffer, sizeof(buffer));
1833}
1834
1835#include <ctype.h>
1836#define LINESIZ 72
1837char ring[128];
1838char *endring;
1839
1840void
1841initring()
1842{
1843 int i;
1844
1845 endring = ring;
1846
1847 for (i = 0; i <= 128; ++i)
1848 if (isprint(i))
1849 *endring++ = i;
1850}
1851
1852/* ARGSUSED */
1853void
1854chargen_stream(s, sep) /* Character generator */
1855 int s;
1856 struct servtab *sep;
1857{
1858 int len;
1859 char *rs, text[LINESIZ+2];
1860
1861 inetd_setproctitle(sep->se_service, s);
1862
1863 if (!endring) {
1864 initring();
1865 rs = ring;
1866 }
1867
1868 text[LINESIZ] = '\r';
1869 text[LINESIZ + 1] = '\n';
1870 for (rs = ring;;) {
1871 if ((len = endring - rs) >= LINESIZ)
1872 memmove(text, rs, LINESIZ);
1873 else {
1874 memmove(text, rs, len);
1875 memmove(text + len, ring, LINESIZ - len);
1876 }
1877 if (++rs == endring)
1878 rs = ring;
1879 if (write(s, text, sizeof(text)) != sizeof(text))
1880 break;
1881 }
1882 exit(0);
1883}
1884
1885/* ARGSUSED */
1886void
1887chargen_dg(s, sep) /* Character generator */
1888 int s;
1889 struct servtab *sep;
1890{
1891 struct sockaddr_in sin;
1892 static char *rs;
1893 int len, size;
1894 char text[LINESIZ+2];
1895
1896 if (endring == 0) {
1897 initring();
1898 rs = ring;
1899 }
1900
1901 size = sizeof(sin);
1902 if (recvfrom(s, text, sizeof(text), 0,
1903 (struct sockaddr *)&sin, &size) < 0)
1904 return;
1905
1906 if (check_loop(&sin, sep))
1907 return;
1908
1909 if ((len = endring - rs) >= LINESIZ)
1910 memmove(text, rs, LINESIZ);
1911 else {
1912 memmove(text, rs, len);
1913 memmove(text + len, ring, LINESIZ - len);
1914 }
1915 if (++rs == endring)
1916 rs = ring;
1917 text[LINESIZ] = '\r';
1918 text[LINESIZ + 1] = '\n';
1919 (void) sendto(s, text, sizeof(text), 0,
1920 (struct sockaddr *)&sin, sizeof(sin));
1921}
1922
1923/*
1535/*
1924 * Return a machine readable date and time, in the form of the
1925 * number of seconds since midnight, Jan 1, 1900. Since gettimeofday
1926 * returns the number of seconds since midnight, Jan 1, 1970,
1927 * we must add 2208988800 seconds to this figure to make up for
1928 * some seventy years Bell Labs was asleep.
1929 */
1930
1931unsigned long
1932machtime()
1933{
1934 struct timeval tv;
1935
1936 if (gettimeofday(&tv, (struct timezone *)NULL) < 0) {
1937 if (debug)
1938 warnx("unable to get time of day");
1939 return (0L);
1940 }
1941#define OFFSET ((u_long)25567 * 24*60*60)
1942 return (htonl((long)(tv.tv_sec + OFFSET)));
1943#undef OFFSET
1944}
1945
1946/* ARGSUSED */
1947void
1948machtime_stream(s, sep)
1949 int s;
1950 struct servtab *sep;
1951{
1952 unsigned long result;
1953
1954 result = machtime();
1955 (void) write(s, (char *) &result, sizeof(result));
1956}
1957
1958/* ARGSUSED */
1959void
1960machtime_dg(s, sep)
1961 int s;
1962 struct servtab *sep;
1963{
1964 unsigned long result;
1965 struct sockaddr_in sin;
1966 int size;
1967
1968 size = sizeof(sin);
1969 if (recvfrom(s, (char *)&result, sizeof(result), 0,
1970 (struct sockaddr *)&sin, &size) < 0)
1971 return;
1972
1973 if (check_loop(&sin, sep))
1974 return;
1975
1976 result = machtime();
1977 (void) sendto(s, (char *) &result, sizeof(result), 0,
1978 (struct sockaddr *)&sin, sizeof(sin));
1979}
1980
1981/* ARGSUSED */
1982void
1983daytime_stream(s, sep) /* Return human-readable time of day */
1984 int s;
1985 struct servtab *sep;
1986{
1987 char buffer[256];
1988 time_t clock;
1989
1990 clock = time((time_t *) 0);
1991
1992 (void) sprintf(buffer, "%.24s\r\n", ctime(&clock));
1993 (void) write(s, buffer, strlen(buffer));
1994}
1995
1996/* ARGSUSED */
1997void
1998daytime_dg(s, sep) /* Return human-readable time of day */
1999 int s;
2000 struct servtab *sep;
2001{
2002 char buffer[256];
2003 time_t clock;
2004 struct sockaddr_in sin;
2005 int size;
2006
2007 clock = time((time_t *) 0);
2008
2009 size = sizeof(sin);
2010 if (recvfrom(s, buffer, sizeof(buffer), 0,
2011 (struct sockaddr *)&sin, &size) < 0)
2012 return;
2013
2014 if (check_loop(&sin, sep))
2015 return;
2016
2017 (void) sprintf(buffer, "%.24s\r\n", ctime(&clock));
2018 (void) sendto(s, buffer, strlen(buffer), 0,
2019 (struct sockaddr *)&sin, sizeof(sin));
2020}
2021
2022/*
2023 * print_service:
2024 * Dump relevant information to stderr
2025 */
2026void
2027print_service(action, sep)
2028 char *action;
2029 struct servtab *sep;
2030{

--- 6 unchanged lines hidden (view full) ---

2037 action, sep->se_service, sep->se_proto,
2038 sep->se_accept, sep->se_maxchild, sep->se_user, sep->se_group,
2039#ifdef LOGIN_CAP
2040 sep->se_class,
2041#endif
2042 (void *) sep->se_bi, sep->se_server);
2043}
2044
1536 * print_service:
1537 * Dump relevant information to stderr
1538 */
1539void
1540print_service(action, sep)
1541 char *action;
1542 struct servtab *sep;
1543{

--- 6 unchanged lines hidden (view full) ---

1550 action, sep->se_service, sep->se_proto,
1551 sep->se_accept, sep->se_maxchild, sep->se_user, sep->se_group,
1552#ifdef LOGIN_CAP
1553 sep->se_class,
1554#endif
1555 (void *) sep->se_bi, sep->se_server);
1556}
1557
2045/*
2046 * Based on TCPMUX.C by Mark K. Lottor November 1988
2047 * sri-nic::ps:<mkl>tcpmux.c
2048 */
2049
2050
2051static int /* # of characters upto \r,\n or \0 */
2052getline(fd, buf, len)
2053 int fd;
2054 char *buf;
2055 int len;
2056{
2057 int count = 0, n;
2058 struct sigaction sa;
2059
2060 sa.sa_flags = 0;
2061 sigemptyset(&sa.sa_mask);
2062 sa.sa_handler = SIG_DFL;
2063 sigaction(SIGALRM, &sa, (struct sigaction *)0);
2064 do {
2065 alarm(10);
2066 n = read(fd, buf, len-count);
2067 alarm(0);
2068 if (n == 0)
2069 return (count);
2070 if (n < 0)
2071 return (-1);
2072 while (--n >= 0) {
2073 if (*buf == '\r' || *buf == '\n' || *buf == '\0')
2074 return (count);
2075 count++;
2076 buf++;
2077 }
2078 } while (count < len);
2079 return (count);
2080}
2081
2082#define MAX_SERV_LEN (256+2) /* 2 bytes for \r\n */
2083
2084#define strwrite(fd, buf) (void) write(fd, buf, sizeof(buf)-1)
2085
2086struct servtab *
2087tcpmux(s)
2088 int s;
2089{
2090 struct servtab *sep;
2091 char service[MAX_SERV_LEN+1];
2092 int len;
2093
2094 /* Get requested service name */
2095 if ((len = getline(s, service, MAX_SERV_LEN)) < 0) {
2096 strwrite(s, "-Error reading service name\r\n");
2097 return (NULL);
2098 }
2099 service[len] = '\0';
2100
2101 if (debug)
2102 warnx("tcpmux: someone wants %s", service);
2103
2104 /*
2105 * Help is a required command, and lists available services,
2106 * one per line.
2107 */
2108 if (!strcasecmp(service, "help")) {
2109 for (sep = servtab; sep; sep = sep->se_next) {
2110 if (!ISMUX(sep))
2111 continue;
2112 (void)write(s,sep->se_service,strlen(sep->se_service));
2113 strwrite(s, "\r\n");
2114 }
2115 return (NULL);
2116 }
2117
2118 /* Try matching a service in inetd.conf with the request */
2119 for (sep = servtab; sep; sep = sep->se_next) {
2120 if (!ISMUX(sep))
2121 continue;
2122 if (!strcasecmp(service, sep->se_service)) {
2123 if (ISMUXPLUS(sep)) {
2124 strwrite(s, "+Go\r\n");
2125 }
2126 return (sep);
2127 }
2128 }
2129 strwrite(s, "-Service not available\r\n");
2130 return (NULL);
2131}
2132
2133#define CPMHSIZE 256
2134#define CPMHMASK (CPMHSIZE-1)
2135#define CHTGRAN 10
2136#define CHTSIZE 6
2137
2138typedef struct CTime {
2139 unsigned long ct_Ticks;
2140 int ct_Count;

--- 94 unchanged lines hidden ---
1558#define CPMHSIZE 256
1559#define CPMHMASK (CPMHSIZE-1)
1560#define CHTGRAN 10
1561#define CHTSIZE 6
1562
1563typedef struct CTime {
1564 unsigned long ct_Ticks;
1565 int ct_Count;

--- 94 unchanged lines hidden ---