date and time created 83/02/11 15:44:33 by rrh
[unix-history] / usr / src / usr.bin / rlogin / rlogin.c
CommitLineData
5567b76f 1#ifndef lint
4659bf8e 2static char sccsid[] = "@(#)rlogin.c 4.9 83/02/09";
5567b76f
BJ
3#endif
4
5567b76f
BJ
5#include <sys/types.h>
6#include <sys/socket.h>
86a16a64 7
c6c678f1 8#include <netinet/in.h>
86a16a64
SL
9
10#include <stdio.h>
11#include <sgtty.h>
5567b76f
BJ
12#include <errno.h>
13#include <pwd.h>
86a16a64
SL
14#include <signal.h>
15#include <netdb.h>
5567b76f
BJ
16
17/*
86a16a64 18 * rlogin - remote login
5567b76f
BJ
19 */
20char *index(), *rindex(), *malloc(), *getenv();
21struct passwd *getpwuid();
86a16a64 22char *name;
5567b76f
BJ
23int rem;
24char cmdchar = '~';
5567b76f
BJ
25int eight;
26char *speeds[] =
27 { "0", "50", "75", "110", "134", "150", "200", "300",
28 "600", "1200", "1800", "2400", "4800", "9600", "19200", "38400" };
86a16a64
SL
29char term[64] = "network";
30extern int errno;
31int lostpeer();
32
5567b76f
BJ
33main(argc, argv)
34 int argc;
35 char **argv;
36{
86a16a64 37 char *host, *cp;
5567b76f
BJ
38 struct sgttyb ttyb;
39 struct passwd *pwd;
86a16a64 40 struct servent *sp;
b5f23952 41 int uid, options = 0;
5567b76f
BJ
42
43 host = rindex(argv[0], '/');
44 if (host)
45 host++;
46 else
47 host = argv[0];
48 argv++, --argc;
49 if (!strcmp(host, "rlogin"))
50 host = *argv++, --argc;
51another:
4659bf8e 52 if (argc > 0 && !strcmp(*argv, "-d")) {
5567b76f 53 argv++, argc--;
b5f23952 54 options |= SO_DEBUG;
5567b76f
BJ
55 goto another;
56 }
4659bf8e 57 if (argc > 0 && !strcmp(*argv, "-l")) {
5567b76f
BJ
58 argv++, argc--;
59 if (argc == 0)
60 goto usage;
61 name = *argv++; argc--;
62 goto another;
63 }
4659bf8e 64 if (argc > 0 && !strncmp(*argv, "-e", 2)) {
5567b76f
BJ
65 cmdchar = argv[0][2];
66 argv++, argc--;
67 goto another;
68 }
4659bf8e 69 if (argc > 0 && !strcmp(*argv, "-8")) {
5567b76f
BJ
70 eight = 1;
71 argv++, argc--;
72 goto another;
73 }
74 if (host == 0)
75 goto usage;
76 if (argc > 0)
77 goto usage;
78 pwd = getpwuid(getuid());
79 if (pwd == 0) {
80 fprintf(stderr, "Who are you?\n");
81 exit(1);
82 }
86a16a64
SL
83 sp = getservbyname("login", "tcp");
84 if (sp == 0) {
85 fprintf(stderr, "rlogin: login/tcp: unknown service\n");
86 exit(2);
87 }
f91500bc
SL
88 cp = getenv("TERM");
89 if (cp)
90 strcpy(term, cp);
c64cdfb4 91 if (ioctl(0, TIOCGETP, &ttyb)==0) {
5567b76f
BJ
92 strcat(term, "/");
93 strcat(term, speeds[ttyb.sg_ospeed]);
94 }
86a16a64
SL
95 signal(SIGPIPE, lostpeer);
96 rem = rcmd(&host, sp->s_port, pwd->pw_name,
5567b76f
BJ
97 name ? name : pwd->pw_name, term, 0);
98 if (rem < 0)
99 exit(1);
b5f23952
SL
100 if (options & SO_DEBUG &&
101 setsockopt(rem, SOL_SOCKET, SO_DEBUG, 0, 0) < 0)
102 perror("rlogin: setsockopt (SO_DEBUG)");
86a16a64
SL
103 uid = getuid();
104 if (setuid(uid) < 0) {
105 perror("rlogin: setuid");
106 exit(1);
107 }
108 doit();
109 /*NOTREACHED*/
5567b76f
BJ
110usage:
111 fprintf(stderr,
112 "usage: rlogin host [ -ex ] [ -l username ]\n");
113 exit(1);
114}
115
5567b76f 116#define CRLF "\r\n"
5567b76f 117
86a16a64 118int child;
5567b76f
BJ
119int done();
120
c64cdfb4
SL
121int defflags;
122struct ttychars deftc;
123struct ttychars notc = {
124 -1, -1, -1, -1, -1,
125 -1, -1, -1, -1, -1,
126 -1, -1, -1, -1
127};
86a16a64
SL
128
129doit()
5567b76f 130{
5567b76f
BJ
131 int exit();
132
c64cdfb4
SL
133 ioctl(0, TIOCGET, (char *)&defflags);
134 defflags &= ECHO | CRMOD;
135 ioctl(0, TIOCCGET, (char *)&deftc);
136 notc.tc_startc = deftc.tc_startc;
137 notc.tc_stopc = deftc.tc_stopc;
5567b76f
BJ
138 signal(SIGINT, exit);
139 signal(SIGHUP, exit);
140 signal(SIGQUIT, exit);
86a16a64
SL
141 child = fork();
142 if (child == -1) {
143 perror("rlogin: fork");
144 done();
145 }
146 signal(SIGINT, SIG_IGN);
147 if (child == 0) {
86a16a64 148 reader();
5567b76f
BJ
149 prf("\007Lost connection.");
150 exit(3);
151 }
152 signal(SIGCHLD, done);
153 mode(1);
86a16a64 154 writer();
5567b76f
BJ
155 prf("Disconnected.");
156 done();
157}
158
159done()
160{
161
162 mode(0);
86a16a64
SL
163 if (child > 0 && kill(child, SIGKILL) >= 0)
164 wait((int *)0);
5567b76f
BJ
165 exit(0);
166}
167
168/*
86a16a64
SL
169 * writer: write to remote: 0 -> line.
170 * ~. terminate
171 * ~^Z suspend rlogin process.
b5f23952 172 * ~^Y suspend rlogin process, but leave reader alone.
5567b76f 173 */
86a16a64 174writer()
5567b76f 175{
86a16a64
SL
176 char b[600], c;
177 register char *p;
5567b76f 178
86a16a64
SL
179top:
180 p = b;
181 while (read(0, &c, 1) > 0) {
182 int local;
5567b76f 183
86a16a64
SL
184 if (eight == 0)
185 c &= 0177;
186 /*
187 * If we're at the beginning of the line
188 * and recognize a command character, then
189 * we echo locally. Otherwise, characters
190 * are echo'd remotely. If the command
191 * character is doubled, this acts as a
192 * force and local echo is suppressed.
193 */
194 if (p == b)
195 local = (c == cmdchar);
196 if (p == b + 1 && *b == cmdchar)
197 local = (c != cmdchar);
198 if (!local) {
199 if (write(rem, &c, 1) == 0) {
200 prf("line gone");
201 return;
202 }
203 if (eight == 0)
204 c &= 0177;
205 } else {
206 if (c == 0177)
c64cdfb4 207 c = deftc.tc_kill;
86a16a64 208 if (c == '\r' || c == '\n') {
c64cdfb4 209 char cmdc = b[1];
86a16a64 210
c64cdfb4 211 if (cmdc == '.' || cmdc == deftc.tc_eofc) {
86a16a64
SL
212 write(0, CRLF, sizeof(CRLF));
213 return;
c64cdfb4
SL
214 }
215 if (cmdc == deftc.tc_suspc ||
216 cmdc == deftc.tc_dsuspc) {
86a16a64
SL
217 write(0, CRLF, sizeof(CRLF));
218 mode(0);
219 signal(SIGCHLD, SIG_IGN);
c64cdfb4
SL
220 kill(cmdc == deftc.tc_suspc ?
221 0 : getpid(), SIGTSTP);
86a16a64
SL
222 signal(SIGCHLD, done);
223 mode(1);
224 goto top;
5567b76f 225 }
86a16a64
SL
226 *p++ = c;
227 write(rem, b, p - b);
228 goto top;
5567b76f 229 }
86a16a64 230 write(1, &c, 1);
5567b76f 231 }
86a16a64 232 *p++ = c;
c64cdfb4 233 if (c == deftc.tc_erase) {
86a16a64
SL
234 p -= 2;
235 if (p < b)
236 goto top;
5567b76f 237 }
c64cdfb4 238 if (c == deftc.tc_kill || c == 0177 || c == deftc.tc_eofc ||
86a16a64
SL
239 c == '\r' || c == '\n')
240 goto top;
5567b76f 241 }
5567b76f
BJ
242}
243
5567b76f
BJ
244oob()
245{
4659bf8e 246 int out = 1+1, atmark;
86a16a64 247 char waste[BUFSIZ], mark;
5567b76f
BJ
248
249 signal(SIGURG, oob);
86a16a64 250 ioctl(1, TIOCFLUSH, (char *)&out);
5567b76f 251 for (;;) {
4659bf8e 252 if (ioctl(rem, SIOCATMARK, &atmark) < 0) {
5567b76f
BJ
253 perror("ioctl");
254 break;
255 }
4659bf8e 256 if (atmark)
5567b76f 257 break;
86a16a64 258 (void) read(rem, waste, sizeof (waste));
5567b76f 259 }
c6c678f1 260 recv(rem, &mark, 1, SOF_OOB);
5567b76f 261 if (mark & TIOCPKT_NOSTOP) {
c64cdfb4
SL
262 notc.tc_stopc = -1;
263 notc.tc_startc = -1;
264 ioctl(0, TIOCCSET, (char *)&notc);
5567b76f
BJ
265 }
266 if (mark & TIOCPKT_DOSTOP) {
c64cdfb4
SL
267 notc.tc_stopc = deftc.tc_stopc;
268 notc.tc_startc = deftc.tc_startc;
269 ioctl(0, TIOCCSET, (char *)&notc);
5567b76f
BJ
270 }
271}
272
86a16a64
SL
273/*
274 * reader: read from remote: line -> 1
275 */
276reader()
5567b76f 277{
86a16a64
SL
278 char rb[BUFSIZ];
279 register int cnt;
5567b76f 280
86a16a64 281 signal(SIGURG, oob);
5567b76f 282 { int pid = -getpid();
86a16a64 283 ioctl(rem, SIOCSPGRP, (char *)&pid); }
5567b76f 284 for (;;) {
86a16a64 285 cnt = read(rem, rb, sizeof (rb));
5567b76f 286 if (cnt <= 0) {
86a16a64 287 if (errno == EINTR)
5567b76f 288 continue;
5567b76f
BJ
289 break;
290 }
86a16a64 291 write(1, rb, cnt);
5567b76f
BJ
292 }
293}
294
5567b76f
BJ
295mode(f)
296{
c64cdfb4
SL
297 struct ttychars *tc;
298 int flags;
86a16a64 299
c64cdfb4
SL
300 ioctl(0, TIOCGET, (char *)&flags);
301 switch (f) {
302
303 case 0:
304 flags &= ~CBREAK;
305 flags |= defflags;
306 tc = &deftc;
307 break;
308
309 case 1:
310 flags |= CBREAK;
311 flags &= ~defflags;
312 tc = &notc;
313 break;
314
315 default:
316 return;
5567b76f 317 }
c64cdfb4
SL
318 ioctl(0, TIOCSET, (char *)&flags);
319 ioctl(0, TIOCCSET, (char *)tc);
5567b76f
BJ
320}
321
86a16a64 322/*VARARGS*/
5567b76f 323prf(f, a1, a2, a3)
86a16a64 324 char *f;
5567b76f
BJ
325{
326 fprintf(stderr, f, a1, a2, a3);
327 fprintf(stderr, CRLF);
328}
329
86a16a64 330lostpeer()
5567b76f 331{
86a16a64
SL
332 signal(SIGPIPE, SIG_IGN);
333 prf("\007Lost connection");
334 done();
5567b76f 335}