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