2 * Copyright (c) 1983 Regents of the University of California.
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
8 * rlogin - remote login
10 #include <afsconfig.h>
11 #include <afs/param.h>
15 #if !defined(AFS_HPUX_ENV) && !defined(AFS_SUN5_ENV) && !defined(AFS_SGI_ENV) && !defined(AFS_LINUX20_ENV)
16 #include <sys/param.h>
17 #include <sys/types.h>
19 #include <sys/socket.h>
22 #include <netinet/in.h>
31 # ifndef TIOCPKT_WINDOW
32 # define TIOCPKT_WINDOW 0x80
33 # endif /* TIOCPKT_WINDOW */
35 char *malloc(), *getenv();
36 struct passwd *getpwuid();
43 { "0", "50", "75", "110", "134", "150", "200", "300",
44 "600", "1200", "1800", "2400", "4800", "9600", "19200", "38400" };
45 char term[256] = "network";
51 struct winsize winsize;
52 int sigwinch(), oob();
54 #define sigmask(s) (1 << (s-1))
59 #if defined(NLS) || defined(KJI)
64 #include "AFS_component_version_number.c"
74 int uid, options = 0, oldmask;
77 #if defined(AFS_AIX32_ENV) && (defined(NLS) || defined(KJI))
81 host = strrchr(argv[0], '/');
87 if (!strcmp(host, "rlogin"))
88 host = *argv++, --argc;
90 if (argc > 0 && !strcmp(*argv, "-d")) {
95 if (argc > 0 && !strcmp(*argv, "-l")) {
99 name = *argv++; argc--;
102 if (argc > 0 && !strncmp(*argv, "-e", 2)) {
103 cmdchar = argv[0][2];
107 if (argc > 0 && !strcmp(*argv, "-8")) {
112 if (argc > 0 && !strcmp(*argv, "-L")) {
118 if (argc > 0 && !strcmp(*argv, "-w")) {
128 pwd = getpwuid(getuid());
130 fprintf(stderr, "Who are you?\n");
133 sp = getservbyname("login", "tcp");
135 fprintf(stderr, "rlogin: login/tcp: unknown service\n");
141 if (ioctl(0, TIOCGETP, &ttyb) == 0) {
143 strcat(term, speeds[ttyb.sg_ospeed]);
147 (void) ioctl(0, TIOCGWINSZ, &winsize);
149 (void) ioctl(0, TIOCGSIZE, &winsize);
152 signal(SIGPIPE, lostpeer);
154 oldmask = sigblock(sigmask(SIGURG));
155 rem = rcmd(&host, sp->s_port, pwd->pw_name,
157 name ? name : pwd->pw_name, term, 0, 0);
159 name ? name : pwd->pw_name, term, 0);
163 if (options & SO_DEBUG &&
164 setsockopt(rem, SOL_SOCKET, SO_DEBUG, &on, sizeof (on)) < 0)
165 perror("rlogin: setsockopt (SO_DEBUG)");
167 if (setuid(uid) < 0) {
168 perror("rlogin: setuid");
175 "usage: rlogin host [ -ex ] [ -l username ] [ -8 ] [ -L ] [ -w ]\n");
185 int defflags, tabflag;
187 char deferase, defkill;
189 struct ltchars defltc;
190 struct tchars notc = { -1, -1, -1, -1, -1, -1 };
191 struct ltchars noltc = { -1, -1, -1, -1, -1, -1 };
198 ioctl(0, TIOCGETP, (char *)&sb);
199 defflags = sb.sg_flags;
200 tabflag = defflags & TBDELAY;
201 defflags &= ECHO | CRMOD;
202 deferase = sb.sg_erase;
203 defkill = sb.sg_kill;
204 ioctl(0, TIOCLGET, (char *)&deflflags);
205 ioctl(0, TIOCGETC, (char *)&deftc);
206 notc.t_startc = deftc.t_startc;
207 notc.t_stopc = deftc.t_stopc;
208 ioctl(0, TIOCGLTC, (char *)&defltc);
209 signal(SIGINT, SIG_IGN);
210 signal(SIGHUP, exit);
211 signal(SIGQUIT, exit);
214 perror("rlogin: fork");
222 prf("\007Connection closed.");
226 signal(SIGURG, writeroob);
229 signal(SIGCHLD, catchild);
232 signal(SIGWINCH, sigwinch);
235 prf("Closed connection.");
243 if (child > 0 && kill(child, SIGKILL) >= 0)
249 * This is called when the reader process gets the out-of-band (urgent)
250 * request to turn on the window-changing protocol.
266 pid = wait3(&status, WNOHANG|WUNTRACED, 0);
270 * if the child (reader) dies, just quit
272 if (pid < 0 || pid == child && !WIFSTOPPED(status))
278 * writer: write to remote: 0 -> line.
280 * ~^Z suspend rlogin process.
281 * ~^Y suspend rlogin process, but leave reader alone.
287 register bol = 1; /* beginning of line */
293 if (n < 0 && errno == EINTR)
298 * If we're at the beginning of the line
299 * and recognize a command character, then
300 * we echo locally. Otherwise, characters
301 * are echo'd remotely. If the command
302 * character is doubled, this acts as a
303 * force and local echo is suppressed.
314 if (c == '.' || c == deftc.t_eofc) {
318 if (c == defltc.t_suspc || c == defltc.t_dsuspc) {
325 write(rem, &cmdchar, 1);
327 if (write(rem, &c, 1) == 0) {
331 bol = c == defkill || c == deftc.t_eofc ||
332 c == '\r' || c == '\n';
340 register char *p = buf;
347 } else if (c == 0177) {
354 write(1, buf, p - buf);
361 signal(SIGCHLD, SIG_IGN);
362 kill(cmdc == defltc.t_suspc ? 0 : getpid(), SIGTSTP);
363 signal(SIGCHLD, catchild);
366 sigwinch(); /* check for size changes */
374 if (dosigwinch && !nosigwin && ioctl(0, TIOCGWINSZ, &ws) == 0 &&
375 memcmp(&ws, &winsize, sizeof (ws))) {
382 * Send the window size to the server via the magic escape
386 char obuf[4 + sizeof (struct winsize)];
387 struct winsize *wp = (struct winsize *)(obuf+4);
393 wp->ws_row = htons(winsize.ws_row);
394 wp->ws_col = htons(winsize.ws_col);
395 wp->ws_xpixel = htons(winsize.ws_xpixel);
396 wp->ws_ypixel = htons(winsize.ws_ypixel);
397 (void) write(rem, obuf, sizeof(obuf));
402 int out = 1+1, atmark;
403 char waste[BUFSIZ], mark;
405 static int didnotify = 0;
407 ioctl(1, TIOCFLUSH, (char *)&out);
410 if (ioctl(rem, SIOCATMARK, &atmark) < 0) {
416 rv = read(rem, waste, sizeof (waste));
420 recv(rem, &mark, 1, MSG_OOB);
421 if (didnotify == 0 && (mark & TIOCPKT_WINDOW)) {
423 * Let server know about window size changes
425 kill(getppid(), SIGURG);
430 if (mark & TIOCPKT_NOSTOP) {
431 ioctl(0, TIOCGETP, (char *)&sb);
432 sb.sg_flags &= ~CBREAK;
434 ioctl(0, TIOCSETN, (char *)&sb);
437 ioctl(0, TIOCSETC, (char *)¬c);
439 if (mark & TIOCPKT_DOSTOP) {
440 ioctl(0, TIOCGETP, (char *)&sb);
442 sb.sg_flags |= CBREAK;
443 ioctl(0, TIOCSETN, (char *)&sb);
444 notc.t_stopc = deftc.t_stopc;
445 notc.t_startc = deftc.t_startc;
446 ioctl(0, TIOCSETC, (char *)¬c);
451 * reader: read from remote: line -> 1
458 signal(SIGTTOU, SIG_IGN);
459 { int pid = getpid();
460 fcntl(rem, F_SETOWN, pid); }
462 cnt = read(rem, rb, sizeof (rb));
481 ioctl(0, TIOCGETP, (char *)&sb);
482 ioctl(0, TIOCLGET, (char *)&lflags);
486 sb.sg_flags &= ~(CBREAK|RAW|TBDELAY);
487 sb.sg_flags |= defflags|tabflag;
490 sb.sg_kill = defkill;
491 sb.sg_erase = deferase;
496 sb.sg_flags |= (eight ? RAW : CBREAK);
497 sb.sg_flags &= ~defflags;
498 /* preserve tab delays, but turn off XTABS */
499 if ((sb.sg_flags & TBDELAY) == XTABS)
500 sb.sg_flags &= ~TBDELAY;
503 sb.sg_kill = sb.sg_erase = -1;
511 ioctl(0, TIOCSLTC, (char *)ltc);
512 ioctl(0, TIOCSETC, (char *)tc);
513 ioctl(0, TIOCSETN, (char *)&sb);
514 ioctl(0, TIOCLSET, (char *)&lflags);
518 prf(f, a1, a2, a3, a4, a5)
521 fprintf(stderr, f, a1, a2, a3, a4, a5);
522 fprintf(stderr, CRLF);
527 signal(SIGPIPE, SIG_IGN);
528 prf("\007Connection closed.");
533 #include "AFS_component_version_number.c"
539 printf("afs rlogin: Not supported for this system ...\n");
541 #endif /* !defined(AFS_HPUX_ENV) */