Mercurial > hg > Applications > mh
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 */ |