]> diplodocus.org Git - nmh/blob - docs/historical/mh-6.8.5/uip/ttyw.c
sbr/mts.c: Delete mmdlm2; use same-valued mmdlm1 instead.
[nmh] / docs / historical / mh-6.8.5 / uip / ttyw.c
1 #ifndef BSD42
2 #undef TTYD
3 #endif
4
5 #ifdef TTYD
6 /* ttyw.c - the writer */
7
8 #include <errno.h>
9 #include <stdio.h>
10 #include <strings.h>
11 #include <sys/types.h>
12 #include <sys/socket.h>
13 #include <netinet/in.h>
14 #include <netdb.h>
15 #ifndef hpux
16 #include <arpa/inet.h>
17 #endif
18 #include "ttyd.h"
19 #include "ttym.c"
20
21 /* \f */
22
23 ttyw (command, host, line, user)
24 char *command,
25 *host,
26 *line,
27 *user;
28 {
29 int privd,
30 sd;
31 unsigned times;
32 char buffer[BUFSIZ];
33 struct hostent *hp;
34 struct servent *sp;
35 struct sockaddr_in tty_socket,
36 *tsock = &tty_socket;
37
38 if (command == NULL) {
39 errno = EINVAL;
40 return NOTOK;
41 }
42
43 if ((sp = getservbyname ("ttyserver", "tcp")) == NULL) {
44 errno = ENETDOWN;
45 return NOTOK;
46 }
47 if (host == NULL)
48 (void) gethostname (host = buffer, sizeof buffer);
49 if ((hp = gethostbyname (host))==NULL) {
50 errno = ENETDOWN;
51 return NOTOK;
52 }
53
54 if (line && strncmp (line, "/dev/", strlen ("/dev/")) == 0)
55 line += strlen ("/dev/");
56
57 privd = *command >= 'A' && *command <= 'Z';/* crude */
58
59 /* \f */
60
61 for (times = 1; times <= 16; times *= 2) {
62 if ((sd = getport (0, privd)) == NOTOK)
63 return NOTOK;
64
65 bzero ((char *) tsock, sizeof *tsock);
66 tsock -> sin_family = hp -> h_addrtype;
67 tsock -> sin_port = sp -> s_port;
68 bcopy (hp -> h_addr, (char *) &tsock -> sin_addr, hp -> h_length);
69
70 if (connect (sd, (struct sockaddr *) tsock, sizeof *tsock) == NOTOK) {
71 (void) close (sd);
72 if (errno == ECONNREFUSED || errno == EINTR) {
73 sleep (times);
74 continue;
75 }
76 break;
77 }
78
79 ttym (sd, command, line, user, NULL);
80 if (ttyv (sd) == NOTOK || ttyv (sd) == NOTOK) {
81 (void) close (sd);
82 errno = EPERM; /* what else??? */
83 return NOTOK;
84 }
85 else
86 return sd;
87 }
88
89 return NOTOK;
90 }
91
92 /* \f */
93
94 static int getport (options, privd)
95 unsigned options;
96 int privd;
97 {
98 int sd,
99 port;
100 struct sockaddr_in unx_socket,
101 *usock = &unx_socket;
102
103 if ((sd = socket (AF_INET, SOCK_STREAM, 0)) == NOTOK)
104 return sd;
105
106 if (options & SO_DEBUG)
107 (void) setsockopt (sd, SOL_SOCKET, SO_DEBUG, NULL, 0);
108 (void) setsockopt (sd, SOL_SOCKET, SO_KEEPALIVE, NULL, 0);
109
110 if (!privd)
111 return sd;
112
113 usock -> sin_family = AF_INET;
114 usock -> sin_addr.s_addr = INADDR_ANY;
115
116 for (port = IPPORT_RESERVED - 1; port > IPPORT_RESERVED / 2; port--) {
117 usock -> sin_port = htons (port);
118
119 switch (bind (sd, (struct sockaddr *) usock, sizeof *usock)) {
120 case NOTOK:
121 if (errno != EADDRINUSE && errno != EADDRNOTAVAIL)
122 return NOTOK;
123 continue;
124
125 default:
126 return sd;
127 }
128 }
129
130 return NOTOK;
131 }
132 #endif TTYD