Commit | Line | Data |
---|---|---|
1dcc3f26 | 1 | /*- |
a9834437 KB |
2 | * Copyright (c) 1983, 1988, 1989, 1993 |
3 | * The Regents of the University of California. All rights reserved. | |
9c901b93 | 4 | * |
1dcc3f26 | 5 | * %sccs.include.redist.c% |
8c5eec2f DF |
6 | */ |
7 | ||
8 | #ifndef lint | |
a9834437 KB |
9 | static char copyright[] = |
10 | "@(#) Copyright (c) 1983, 1988, 1989, 1993\n\ | |
11 | The Regents of the University of California. All rights reserved.\n"; | |
9c901b93 | 12 | #endif /* not lint */ |
8c5eec2f | 13 | |
a10a364d | 14 | #ifndef lint |
a9834437 | 15 | static char sccsid[] = "@(#)rlogind.c 8.1 (Berkeley) %G%"; |
9c901b93 | 16 | #endif /* not lint */ |
a10a364d | 17 | |
bb933cc2 MK |
18 | /* |
19 | * remote login server: | |
e3fc62b0 | 20 | * \0 |
bb933cc2 MK |
21 | * remuser\0 |
22 | * locuser\0 | |
e3fc62b0 | 23 | * terminal_type/speed\0 |
9d5f81ab | 24 | * data |
dfd00f77 MK |
25 | * |
26 | * Automatic login protocol is done here, using login -f upon success, | |
27 | * unless OLD_LOGIN is defined (then done in login, ala 4.2/4.3BSD). | |
bb933cc2 MK |
28 | */ |
29 | ||
b4839a52 | 30 | #define FD_SETSIZE 16 /* don't need many bits for select */ |
2b08f0dd | 31 | #include <sys/param.h> |
a10a364d | 32 | #include <sys/stat.h> |
95d03f33 | 33 | #include <sys/ioctl.h> |
618a2b86 KB |
34 | #include <signal.h> |
35 | #include <termios.h> | |
c6c678f1 | 36 | |
618a2b86 | 37 | #include <sys/socket.h> |
c6c678f1 | 38 | #include <netinet/in.h> |
6e1cccbc MK |
39 | #include <netinet/in_systm.h> |
40 | #include <netinet/ip.h> | |
618a2b86 KB |
41 | #include <arpa/inet.h> |
42 | #include <netdb.h> | |
c6c678f1 | 43 | |
a10a364d | 44 | #include <pwd.h> |
3f99c0f7 | 45 | #include <syslog.h> |
618a2b86 | 46 | #include <errno.h> |
95d03f33 | 47 | #include <stdio.h> |
27ed11f5 | 48 | #include <unistd.h> |
618a2b86 KB |
49 | #include <stdlib.h> |
50 | #include <string.h> | |
95d03f33 | 51 | #include "pathnames.h" |
9d5f81ab MK |
52 | |
53 | #ifndef TIOCPKT_WINDOW | |
54 | #define TIOCPKT_WINDOW 0x80 | |
55 | #endif | |
e3fc62b0 | 56 | |
9d5f81ab MK |
57 | char *env[2]; |
58 | #define NMAX 30 | |
5a93e98d MK |
59 | char lusername[NMAX+1], rusername[NMAX+1]; |
60 | static char term[64] = "TERM="; | |
61 | #define ENVSIZE (sizeof("TERM=")-1) /* skip null for concatenation */ | |
62 | int keepalive = 1; | |
a6449a97 | 63 | int check_all = 0; |
f295ed5f | 64 | int check_all = 0; |
e3fc62b0 | 65 | |
618a2b86 | 66 | struct passwd *pwd; |
bb933cc2 | 67 | |
e355f53b CL |
68 | void doit __P((int, struct sockaddr_in *)); |
69 | int control __P((int, char *, int)); | |
70 | void protocol __P((int, int)); | |
9d95c77d | 71 | void cleanup __P((int)); |
e355f53b CL |
72 | void fatal __P((int, char *, int)); |
73 | int do_rlogin __P((struct sockaddr_in *)); | |
74 | void getstr __P((char *, int, char *)); | |
75 | void setup_term __P((int)); | |
76 | int do_krb_login __P((struct sockaddr_in *)); | |
77 | void usage __P((void)); | |
78 | int local_domain __P((char *)); | |
79 | char *topdomain __P((char *)); | |
80 | ||
81 | int | |
a10a364d BJ |
82 | main(argc, argv) |
83 | int argc; | |
e355f53b | 84 | char *argv[]; |
a10a364d | 85 | { |
e355f53b | 86 | extern int __check_rhosts_file; |
a10a364d | 87 | struct sockaddr_in from; |
e355f53b | 88 | int ch, fromlen, on; |
a10a364d | 89 | |
20b6f6ce | 90 | openlog("rlogind", LOG_PID | LOG_CONS, LOG_AUTH); |
10869b2d KB |
91 | |
92 | opterr = 0; | |
b3da51a3 | 93 | while ((ch = getopt(argc, argv, ARGSTR)) != EOF) |
5a93e98d | 94 | switch (ch) { |
f295ed5f MK |
95 | case 'a': |
96 | check_all = 1; | |
97 | break; | |
a6449a97 MK |
98 | case 'a': |
99 | check_all = 1; | |
100 | break; | |
10869b2d | 101 | case 'l': |
e355f53b | 102 | __check_rhosts_file = 0; |
10869b2d | 103 | break; |
5a93e98d MK |
104 | case 'n': |
105 | keepalive = 0; | |
106 | break; | |
b3da51a3 KF |
107 | #ifdef KERBEROS |
108 | case 'k': | |
109 | use_kerberos = 1; | |
110 | break; | |
111 | case 'v': | |
112 | vacuous = 1; | |
113 | break; | |
114 | #endif | |
10869b2d KB |
115 | case '?': |
116 | default: | |
b3da51a3 | 117 | usage(); |
10869b2d KB |
118 | break; |
119 | } | |
120 | argc -= optind; | |
121 | argv += optind; | |
122 | ||
b3da51a3 | 123 | #ifdef KERBEROS |
c1e16073 | 124 | if (use_kerberos && vacuous) { |
b3da51a3 | 125 | usage(); |
27ed11f5 | 126 | fatal(STDERR_FILENO, "only one of -k and -v allowed", 0); |
b3da51a3 KF |
127 | } |
128 | #endif | |
bb933cc2 | 129 | fromlen = sizeof (from); |
618a2b86 | 130 | if (getpeername(0, (struct sockaddr *)&from, &fromlen) < 0) { |
2b08f0dd | 131 | syslog(LOG_ERR, "Couldn't get peer name of remote host: %m"); |
f295ed5f | 132 | fatalperror("Can't get peer name of remote host"); |
92e31018 | 133 | } |
e355f53b | 134 | on = 1; |
5a93e98d MK |
135 | if (keepalive && |
136 | setsockopt(0, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof (on)) < 0) | |
3f99c0f7 | 137 | syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m"); |
6e1cccbc MK |
138 | on = IPTOS_LOWDELAY; |
139 | if (setsockopt(0, IPPROTO_IP, IP_TOS, (char *)&on, sizeof(int)) < 0) | |
140 | syslog(LOG_WARNING, "setsockopt (IP_TOS): %m"); | |
bb933cc2 | 141 | doit(0, &from); |
92e31018 SL |
142 | } |
143 | ||
a10a364d | 144 | int child; |
a10a364d | 145 | int netf; |
4361e949 | 146 | char line[MAXPATHLEN]; |
b4839a52 | 147 | int confirmed; |
a10a364d | 148 | |
8210fa73 KM |
149 | struct winsize win = { 0, 0, 0, 0 }; |
150 | ||
66feb14c | 151 | |
e355f53b | 152 | void |
a10a364d BJ |
153 | doit(f, fromp) |
154 | int f; | |
155 | struct sockaddr_in *fromp; | |
156 | { | |
e355f53b CL |
157 | int master, pid, on = 1; |
158 | int authenticated = 0; | |
dfd00f77 | 159 | #endif |
3f5b52bc | 160 | register struct hostent *hp; |
83300655 | 161 | char hostname[2 * MAXHOSTNAMELEN + 1]; |
6632767b | 162 | char c; |
a10a364d BJ |
163 | |
164 | alarm(60); | |
165 | read(f, &c, 1); | |
b4839a52 | 166 | if (c != 0) |
a10a364d | 167 | exit(1); |
32d4627a | 168 | #ifdef KERBEROS |
f295ed5f | 169 | if (vacuous) |
27ed11f5 | 170 | fatal(f, "Remote host requires Kerberos authentication", 0); |
e3fc62b0 | 171 | |
a10a364d | 172 | alarm(0); |
1227078b | 173 | fromp->sin_port = ntohs((u_short)fromp->sin_port); |
618a2b86 | 174 | hp = gethostbyaddr((char *)&fromp->sin_addr, sizeof(struct in_addr), |
e3fc62b0 | 175 | |
c1e16073 | 176 | if (use_kerberos) { |
e355f53b | 177 | retval = do_krb_login(fromp); |
f5bb5ea0 | 178 | if (retval == 0) |
b3da51a3 | 179 | authenticated++; |
c1e16073 | 180 | else if (retval > 0) |
27ed11f5 | 181 | fatal(f, krb_err_txt[retval], 0); |
b4839a52 MK |
182 | write(f, &c, 1); |
183 | confirmed = 1; /* we sent the null! */ | |
b3da51a3 | 184 | } else |
dfd00f77 | 185 | #ifndef OLD_LOGIN |
2771f96c | 186 | { |
e355f53b CL |
187 | if (fromp->sin_family != AF_INET || |
188 | fromp->sin_port >= IPPORT_RESERVED || | |
189 | fromp->sin_port < IPPORT_RESERVED/2) { | |
190 | syslog(LOG_NOTICE, "Connection from %s on illegal port", | |
191 | inet_ntoa(fromp->sin_addr)); | |
192 | fatal(f, "Permission denied", 0); | |
193 | } | |
194 | if (do_rlogin(fromp) == 0) | |
195 | authenticated++; | |
c1e16073 | 196 | } |
b4839a52 MK |
197 | if (confirmed == 0) { |
198 | write(f, "", 1); | |
199 | confirmed = 1; /* we sent the null! */ | |
200 | } | |
201 | #ifdef KERBEROS | |
b4839a52 | 202 | #endif |
4361e949 | 203 | netf = f; |
84e161e6 | 204 | |
4361e949 MT |
205 | pid = forkpty(&master, line, NULL, &win); |
206 | if (pid < 0) { | |
207 | if (errno == ENOENT) | |
208 | fatal(f, "Out of ptys", 0); | |
209 | else | |
210 | fatal(f, "Forkpty", 1); | |
211 | } | |
212 | if (pid == 0) { | |
e355f53b | 213 | if (f > 2) /* f should always be 0, but... */ |
4361e949 MT |
214 | (void) close(f); |
215 | setup_term(0); | |
dfd00f77 MK |
216 | #ifdef OLD_LOGIN |
217 | execl("/bin/login", "login", "-r", hp->h_name, 0); | |
218 | #else /* OLD_LOGIN */ | |
7aac2862 | 219 | if (authenticated) { |
6e1cccbc | 220 | #ifdef KERBEROS |
7aac2862 KF |
221 | if (use_kerberos && (pwd->pw_uid == 0)) |
222 | syslog(LOG_INFO|LOG_AUTH, | |
223 | "ROOT Kerberos login from %s.%s@%s on %s\n", | |
224 | kdata->pname, kdata->pinst, kdata->prealm, | |
e355f53b | 225 | hostname); |
6e1cccbc | 226 | #endif |
7aac2862 | 227 | |
95d03f33 | 228 | execl(_PATH_LOGIN, "login", "-p", |
e355f53b | 229 | "-h", hostname, "-f", lusername, (char *)NULL); |
7aac2862 | 230 | } else |
95d03f33 | 231 | execl(_PATH_LOGIN, "login", "-p", |
e355f53b | 232 | "-h", hostname, lusername, (char *)NULL); |
dfd00f77 | 233 | #endif /* OLD_LOGIN */ |
27ed11f5 | 234 | fatal(STDERR_FILENO, _PATH_LOGIN, 1); |
6632767b SL |
235 | /*NOTREACHED*/ |
236 | } | |
754db9db | 237 | ioctl(f, FIONBIO, &on); |
4361e949 MT |
238 | ioctl(master, FIONBIO, &on); |
239 | ioctl(master, TIOCPKT, &on); | |
6632767b | 240 | signal(SIGCHLD, cleanup); |
4361e949 | 241 | protocol(f, master); |
78c1c171 | 242 | signal(SIGCHLD, SIG_IGN); |
9d95c77d | 243 | cleanup(0); |
6632767b | 244 | } |
82c973f2 | 245 | |
6632767b | 246 | char magic[2] = { 0377, 0377 }; |
87e80234 | 247 | char oobdata[] = {TIOCPKT_WINDOW}; |
6632767b SL |
248 | |
249 | /* | |
250 | * Handle a "control" request (signaled by magic being present) | |
251 | * in the data stream. For now, we are only willing to handle | |
252 | * window size changes. | |
253 | */ | |
e355f53b | 254 | int |
6632767b SL |
255 | control(pty, cp, n) |
256 | int pty; | |
257 | char *cp; | |
258 | int n; | |
259 | { | |
cfafdcf2 | 260 | struct winsize w; |
6632767b | 261 | |
cfafdcf2 | 262 | if (n < 4+sizeof (w) || cp[2] != 's' || cp[3] != 's') |
6632767b | 263 | return (0); |
87e80234 | 264 | oobdata[0] &= ~TIOCPKT_WINDOW; /* we know he heard */ |
cfafdcf2 KM |
265 | bcopy(cp+4, (char *)&w, sizeof(w)); |
266 | w.ws_row = ntohs(w.ws_row); | |
267 | w.ws_col = ntohs(w.ws_col); | |
268 | w.ws_xpixel = ntohs(w.ws_xpixel); | |
269 | w.ws_ypixel = ntohs(w.ws_ypixel); | |
270 | (void)ioctl(pty, TIOCSWINSZ, &w); | |
271 | return (4+sizeof (w)); | |
6632767b SL |
272 | } |
273 | ||
274 | /* | |
275 | * rlogin "protocol" machine. | |
276 | */ | |
e355f53b | 277 | void |
6632767b | 278 | protocol(f, p) |
27ed11f5 | 279 | register int f, p; |
6632767b | 280 | { |
b4839a52 | 281 | char pibuf[1024+1], fibuf[1024], *pbp, *fbp; |
6632767b | 282 | register pcc = 0, fcc = 0; |
27ed11f5 | 283 | int cc, nfd, n; |
2c360ad3 | 284 | char cntl; |
6632767b | 285 | |
ffaf1c0b | 286 | /* |
9ee4d121 SL |
287 | * Must ignore SIGTTOU, otherwise we'll stop |
288 | * when we try and set slave pty's window shape | |
87e80234 | 289 | * (our controlling tty is the master pty). |
ffaf1c0b | 290 | */ |
9ee4d121 | 291 | (void) signal(SIGTTOU, SIG_IGN); |
87e80234 | 292 | send(f, oobdata, 1, MSG_OOB); /* indicate new rlogin */ |
5a93e98d MK |
293 | if (f > p) |
294 | nfd = f + 1; | |
295 | else | |
296 | nfd = p + 1; | |
b4839a52 MK |
297 | if (nfd > FD_SETSIZE) { |
298 | syslog(LOG_ERR, "select mask too small, increase FD_SETSIZE"); | |
299 | fatal(f, "internal error (select mask too small)", 0); | |
300 | } | |
6632767b | 301 | for (;;) { |
b4839a52 | 302 | fd_set ibits, obits, ebits, *omask; |
6632767b | 303 | |
d691a08a | 304 | FD_ZERO(&ebits); |
27ed11f5 KB |
305 | FD_ZERO(&ibits); |
306 | FD_ZERO(&obits); | |
b4839a52 MK |
307 | omask = (fd_set *)NULL; |
308 | if (fcc) { | |
27ed11f5 | 309 | FD_SET(p, &obits); |
b4839a52 MK |
310 | omask = &obits; |
311 | } else | |
27ed11f5 | 312 | FD_SET(f, &ibits); |
6632767b | 313 | if (pcc >= 0) |
b4839a52 | 314 | if (pcc) { |
27ed11f5 | 315 | FD_SET(f, &obits); |
b4839a52 MK |
316 | omask = &obits; |
317 | } else | |
27ed11f5 KB |
318 | FD_SET(p, &ibits); |
319 | FD_SET(p, &ebits); | |
b4839a52 | 320 | if ((n = select(nfd, &ibits, omask, &ebits, 0)) < 0) { |
6632767b | 321 | if (errno == EINTR) |
a10a364d | 322 | continue; |
27ed11f5 | 323 | fatal(f, "select", 1); |
6632767b | 324 | } |
27ed11f5 | 325 | if (n == 0) { |
6632767b SL |
326 | /* shouldn't happen... */ |
327 | sleep(5); | |
328 | continue; | |
329 | } | |
2c360ad3 | 330 | #define pkcontrol(c) ((c)&(TIOCPKT_FLUSHWRITE|TIOCPKT_NOSTOP|TIOCPKT_DOSTOP)) |
27ed11f5 | 331 | if (FD_ISSET(p, &ebits)) { |
2c360ad3 MK |
332 | cc = read(p, &cntl, 1); |
333 | if (cc == 1 && pkcontrol(cntl)) { | |
334 | cntl |= oobdata[0]; | |
335 | send(f, &cntl, 1, MSG_OOB); | |
336 | if (cntl & TIOCPKT_FLUSHWRITE) { | |
337 | pcc = 0; | |
27ed11f5 | 338 | FD_CLR(p, &ibits); |
2c360ad3 MK |
339 | } |
340 | } | |
341 | } | |
754db9db | 342 | fcc = read(f, fibuf, sizeof(fibuf)); |
6632767b SL |
343 | if (fcc < 0 && errno == EWOULDBLOCK) |
344 | fcc = 0; | |
345 | else { | |
346 | register char *cp; | |
347 | int left, n; | |
348 | ||
349 | if (fcc <= 0) | |
1227078b | 350 | break; |
6632767b | 351 | fbp = fibuf; |
66feb14c | 352 | |
6632767b | 353 | top: |
87e80234 | 354 | for (cp = fibuf; cp < fibuf+fcc-1; cp++) |
6632767b SL |
355 | if (cp[0] == magic[0] && |
356 | cp[1] == magic[1]) { | |
357 | left = fcc - (cp-fibuf); | |
358 | n = control(p, cp, left); | |
359 | if (n) { | |
360 | left -= n; | |
361 | if (left > 0) | |
87e80234 | 362 | bcopy(cp+n, cp, left); |
6632767b SL |
363 | fcc -= n; |
364 | goto top; /* n^2 */ | |
87e80234 MK |
365 | } |
366 | } | |
27ed11f5 | 367 | FD_SET(p, &obits); /* try write */ |
87e80234 MK |
368 | } |
369 | } | |
66feb14c | 370 | |
27ed11f5 | 371 | if (FD_ISSET(p, &obits) && fcc > 0) { |
87e80234 | 372 | cc = write(p, fbp, fcc); |
66feb14c KM |
373 | if (cc > 0) { |
374 | fcc -= cc; | |
375 | fbp += cc; | |
a10a364d | 376 | } |
6632767b | 377 | } |
66feb14c | 378 | |
27ed11f5 | 379 | if (FD_ISSET(p, &ibits)) { |
6632767b SL |
380 | pcc = read(p, pibuf, sizeof (pibuf)); |
381 | pbp = pibuf; | |
382 | if (pcc < 0 && errno == EWOULDBLOCK) | |
383 | pcc = 0; | |
384 | else if (pcc <= 0) | |
385 | break; | |
5a93e98d | 386 | else if (pibuf[0] == 0) { |
6632767b | 387 | pbp++, pcc--; |
754db9db | 388 | obits |= fmask; /* try a write */ |
5a93e98d | 389 | } else { |
6632767b | 390 | if (pkcontrol(pibuf[0])) { |
87e80234 | 391 | pibuf[0] |= oobdata[0]; |
6632767b | 392 | send(f, &pibuf[0], 1, MSG_OOB); |
a10a364d | 393 | } |
6632767b | 394 | pcc = 0; |
a10a364d | 395 | } |
6632767b | 396 | } |
754db9db | 397 | cc = write(f, pbp, pcc); |
87e80234 | 398 | if (cc < 0 && errno == EWOULDBLOCK) { |
b4839a52 MK |
399 | /* |
400 | * This happens when we try write after read | |
401 | * from p, but some old kernels balk at large | |
402 | * writes even when select returns true. | |
403 | */ | |
404 | if (!FD_ISSET(p, &ibits)) | |
405 | sleep(5); | |
87e80234 MK |
406 | continue; |
407 | } | |
6632767b SL |
408 | if (cc > 0) { |
409 | pcc -= cc; | |
410 | pbp += cc; | |
411 | } | |
412 | } | |
a10a364d | 413 | } |
a10a364d BJ |
414 | } |
415 | ||
618a2b86 | 416 | void |
9d95c77d KB |
417 | cleanup(signo) |
418 | int signo; | |
a10a364d | 419 | { |
6487d192 KB |
420 | char *p; |
421 | ||
27ed11f5 | 422 | p = line + sizeof(_PATH_DEV) - 1; |
6487d192 KB |
423 | if (logout(p)) |
424 | logwtmp(p, "", ""); | |
69be07b8 | 425 | (void)chmod(line, 0666); |
6487d192 KB |
426 | (void)chown(line, 0, 0); |
427 | *p = 'p'; | |
69be07b8 | 428 | (void)chmod(line, 0666); |
6487d192 | 429 | (void)chown(line, 0, 0); |
ff24c640 | 430 | shutdown(netf, 2); |
a10a364d BJ |
431 | exit(1); |
432 | } | |
433 | ||
e355f53b | 434 | void |
27ed11f5 | 435 | fatal(f, msg, syserr) |
e355f53b | 436 | int f; |
82c973f2 | 437 | char *msg; |
e355f53b | 438 | int syserr; |
82c973f2 | 439 | { |
27ed11f5 | 440 | int len; |
b4839a52 | 441 | char buf[BUFSIZ], *bp = buf; |
82c973f2 | 442 | |
b4839a52 MK |
443 | /* |
444 | * Prepend binary one to message if we haven't sent | |
445 | * the magic null as confirmation. | |
446 | */ | |
447 | if (!confirmed) | |
448 | *bp++ = '\01'; /* error indicator */ | |
27ed11f5 | 449 | if (syserr) |
b4839a52 | 450 | len = sprintf(bp, "rlogind: %s: %s.\r\n", |
27ed11f5 | 451 | msg, strerror(errno)); |
1227078b | 452 | else |
b4839a52 MK |
453 | len = sprintf(bp, "rlogind: %s.\r\n", msg); |
454 | (void) write(f, buf, bp + len - buf); | |
27ed11f5 | 455 | exit(1); |
82c973f2 | 456 | } |
e3fc62b0 | 457 | |
dfd00f77 | 458 | #ifndef OLD_LOGIN |
e355f53b CL |
459 | int |
460 | do_rlogin(dest) | |
461 | struct sockaddr_in *dest; | |
e3fc62b0 | 462 | { |
9d5f81ab MK |
463 | getstr(rusername, sizeof(rusername), "remuser too long"); |
464 | getstr(lusername, sizeof(lusername), "locuser too long"); | |
465 | getstr(term+ENVSIZE, sizeof(term)-ENVSIZE, "Terminal type too long"); | |
466 | ||
e3fc62b0 | 467 | pwd = getpwnam(lusername); |
9d5f81ab | 468 | if (pwd == NULL) |
e355f53b | 469 | return (-1); |
f5bb5ea0 | 470 | if (pwd->pw_uid == 0) |
e355f53b CL |
471 | return (-1); |
472 | /* XXX why don't we syslog() failure? */ | |
473 | return (iruserok(dest->sin_addr.s_addr, 0, rusername, lusername)); | |
e3fc62b0 KF |
474 | } |
475 | ||
e355f53b | 476 | void |
9d5f81ab MK |
477 | getstr(buf, cnt, errmsg) |
478 | char *buf; | |
479 | int cnt; | |
480 | char *errmsg; | |
e3fc62b0 | 481 | { |
9d5f81ab MK |
482 | char c; |
483 | ||
e3fc62b0 | 484 | do { |
9d5f81ab | 485 | if (read(0, &c, 1) != 1) |
e3fc62b0 | 486 | exit(1); |
9d5f81ab | 487 | if (--cnt < 0) |
27ed11f5 | 488 | fatal(STDOUT_FILENO, errmsg, 0); |
e3fc62b0 | 489 | *buf++ = c; |
9d5f81ab | 490 | } while (c != 0); |
e3fc62b0 KF |
491 | } |
492 | ||
9d5f81ab | 493 | extern char **environ; |
e3fc62b0 | 494 | |
e355f53b | 495 | void |
dfd00f77 MK |
496 | char *speeds[] = { |
497 | "0", "50", "75", "110", "134", "150", "200", "300", "600", | |
498 | "1200", "1800", "2400", "4800", "9600", "19200", "38400", | |
499 | }; | |
500 | #define NSPEEDS (sizeof(speeds) / sizeof(speeds[0])) | |
501 | ||
502 | setup_term(fd) | |
503 | int fd; | |
504 | { | |
505 | register char *cp = index(term, '/'), **cpp; | |
dfd00f77 | 506 | char *speed; |
f295ed5f MK |
507 | #if BSD > 43 |
508 | struct termios tt; | |
509 | ||
510 | tcgetattr(fd, &tt); | |
511 | if (cp) { | |
512 | *cp++ = '\0'; | |
513 | speed = cp; | |
514 | cp = index(speed, '/'); | |
515 | if (cp) | |
516 | *cp++ = '\0'; | |
517 | cfsetspeed(&tt, atoi(speed)); | |
518 | } | |
519 | ||
520 | tt.c_iflag = TTYDEF_IFLAG; | |
521 | tt.c_oflag = TTYDEF_OFLAG; | |
522 | tt.c_lflag = TTYDEF_LFLAG; | |
523 | tcsetattr(fd, TCSADFLUSH, &tt); | |
524 | #else | |
525 | struct sgttyb sgttyb; | |
dfd00f77 MK |
526 | |
527 | (void)ioctl(fd, TIOCGETP, &sgttyb); | |
528 | if (cp) { | |
529 | *cp++ = '\0'; | |
530 | speed = cp; | |
531 | cp = index(speed, '/'); | |
532 | if (cp) | |
533 | *cp++ = '\0'; | |
534 | for (cpp = speeds; cpp < &speeds[NSPEEDS]; cpp++) | |
535 | if (strcmp(*cpp, speed) == 0) { | |
536 | sgttyb.sg_ispeed = sgttyb.sg_ospeed = cpp - speeds; | |
537 | break; | |
538 | } | |
539 | } | |
540 | sgttyb.sg_flags = ECHO|CRMOD|ANYP|XTABS; | |
541 | (void)ioctl(fd, TIOCSETP, &sgttyb); | |
f295ed5f | 542 | #endif |
dfd00f77 MK |
543 | |
544 | env[0] = term; | |
545 | env[1] = 0; | |
546 | environ = env; | |
547 | } | |
2b08f0dd MK |
548 | |
549 | /* | |
550 | * Check whether host h is in our local domain, | |
f295ed5f MK |
551 | * defined as sharing the last two components of the domain part, |
552 | * or the entire domain part if the local domain has only one component. | |
2b08f0dd MK |
553 | * If either name is unqualified (contains no '.'), |
554 | * assume that the host is local, as it will be | |
555 | * interpreted as such. | |
556 | */ | |
557 | local_domain(h) | |
558 | char *h; | |
559 | { | |
560 | char localhost[MAXHOSTNAMELEN]; | |
f295ed5f | 561 | char *p1, *p2, *topdomain(); |
2b08f0dd | 562 | |
f295ed5f | 563 | localhost[0] = 0; |
2b08f0dd | 564 | (void) gethostname(localhost, sizeof(localhost)); |
f295ed5f MK |
565 | p1 = topdomain(localhost); |
566 | p2 = topdomain(h); | |
2b08f0dd MK |
567 | if (p1 == NULL || p2 == NULL || !strcasecmp(p1, p2)) |
568 | return(1); | |
569 | return(0); | |
570 | } | |
f295ed5f MK |
571 | |
572 | char * | |
573 | topdomain(h) | |
574 | char *h; | |
575 | { | |
576 | register char *p; | |
577 | char *maybe = NULL; | |
578 | int dots = 0; | |
579 | ||
580 | for (p = h + strlen(h); p >= h; p--) { | |
581 | if (*p == '.') { | |
582 | if (++dots == 2) | |
583 | return (p); | |
584 | maybe = p; | |
585 | } | |
586 | } | |
587 | return (maybe); | |
588 | } | |
dfd00f77 | 589 | #endif /* OLD_LOGIN */ |