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 --- |