comparison uip/ttyw.c @ 0:bce86c4163a3

Initial revision
author kono
date Mon, 18 Apr 2005 23:46:02 +0900
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:bce86c4163a3
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 */