/* * Copyright (c) 1994 Sony Corporation * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL SONY CORPORATION BE LIABLE FOR ANY CLAIM, * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * Except as contained in this notice, the name of Sony Corporation * shall not be used in advertising or otherwise to promote the sale, use * or other dealings in this Software without prior written authorization * from Sony Corporation. * */ /* * $SonyRCSfile: sj3.c,v $ * $SonyRevision: 1.7 $ * $SonyDate: 1997/01/23 11:26:30 $ */ #include "sj_sysvdef.h" #include "wchar16.h" #include #include #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__bsdi__) || defined(__DragonFly__) #define USE_OLD_TTY #if defined(__NetBSD__) #define LACKOF_SETLOCALE #endif #if defined(__FreeBSD__) #include #endif #include #endif #include "select.h" #include "common.h" #ifdef SVR4 #include #include #include #endif #include #include "sj3.h" #ifndef _PATH_UTMP #define _PATH_UTMP "/etc/utmp" #endif #ifdef SVR4 #define killpg(pid, sig) kill(-(pid),(sig)) #define signal sigset #endif #ifndef linux #define DEFAULTSHELL "/bin/csh" #else #define DEFAULTSHELL "/bin/sh" #endif #if defined(linux) && defined (__GLIBC__) && (__GLIBC__ >= 2) #include #endif int Lflag = 0; int shell_flag = 0; char progname[LONGLENGTH]; char shellname[LONGLENGTH]; char home[LONGLENGTH]; char user_name[SHORTLENGTH]; char term_name[SHORTLENGTH]; char shellprog[LONGLENGTH]; char tty_name[SHORTLENGTH]; #ifdef SVR4 char *slave_name; #else char slave_name[SHORTLENGTH]; #endif char *shellargs[SHORTLENGTH]; #ifdef SVR4 char *mptname = "/dev/ptmx"; char *ptsname(int); #else static char line[SHORTLENGTH]; #endif char *cur_serv; char my_hname[MAXHOSTNAMELEN]; char **serv_list; extern int vflag; extern char **environ; extern int status_line; #ifdef SYSV_TERMIOS struct winsize Ttysize; #define ts_lines ws_row #define ts_cols ws_col #else int Ttyslot; struct ttysize Ttysize; #endif int master; int slave; #ifdef SYSV_TERMIOS struct termios b; #else struct sgttyb b; struct tchars tc, tc1; struct ltchars lc, lc1; int lb; int l; #endif #ifdef __sony_news int jmode, jmode2; struct jtchars jtc; #endif int erase_char; wchar16_t erase_str[2]; #ifdef SIGTYPE_VOID void (*sigpipe)(); #else int (*sigpipe)(); #endif int Pid_shell; int current_locale; int main (int argc, char** argv) { init (argv); get_ttymode (); init_messages (); parsearg (argc, argv); InitConversion (); checkterm (); getsjrc (); print_version (); getsjrk(erase_char); sjinit (); forkshell (); inputprocess (); done (); } void makecore (void) { chdir ("/tmp"); setgid (getgid ()); setuid (getuid ()); abort (); } void init (char** argv) { char *cp; (void) signal (SIGTERM, (void (*)())done); (void) signal (SIGWINCH, SIG_IGN); (void) signal (SIGQUIT, (void (*)())makecore); (void) signal (SIGBUS, (void (*)())makecore); (void) signal (SIGSEGV, (void (*)())makecore); (void) signal (SIGFPE, (void (*)())makecore); /* * Remove warning. * Patched by Hidekazu Kuroki(hidekazu@cs.titech.ac.jp) 1996/8/10 */ #ifdef SIGTYPE_VOID sigpipe = (void(*)()) signal (SIGPIPE, SIG_IGN); #else sigpipe = (int(*)()) signal (SIGPIPE, SIG_IGN); #endif if (argv [0][0] == '-') Lflag ++; if ((cp = strrchr (argv [0], '/')) == NULL) cp = argv [0]; else cp ++; strcpy (progname, cp); init_env(); } void init_env(void) { char *uname, *hp, *tname; int i; struct passwd *pwd, *getpwnam(), *getpwuid(); char *getlogin(), *getenv(); user_name[0] = '\0'; home[0] = '\0'; shellprog[0] = '\0'; gethostname(my_hname, MAXHOSTNAMELEN); if ((serv_list = (char **)malloc(MAXSERVER * sizeof(char *))) == NULL){ fprintf (stderr, "init_env: can't alloc memory\n\r"); done3(); } for (i = 0; i < MAXSERVER; i++) serv_list[i] = NULL; cur_serv = NULL; uname = getlogin (); hp = getenv("HOME"); setpwent (); if( uname == NULL || *uname == '\0' ) pwd = getpwuid(getuid()); else pwd = getpwnam(uname); if (pwd != NULL) { strcpy(user_name, pwd -> pw_name); if (hp == NULL) hp = pwd->pw_dir; endpwent(); } if (hp != NULL) strcpy(home, hp); if ((tname = getenv("TERM")) == NULL) { aprintf ("Can't getenv TERM\n\r"); perror("getenv"); exit(1); } strcpy(term_name, tname); } void parsearg (int argc, char** argv) { int ap; char c; int sp; char **shella; shella = shellargs; ap = 1; -- argc; while (argc > 0) { if (*argv[ap] == '-') { c = argv[ap][1]; switch (c) { case 'L': Lflag ++; break; case 'E': aprintf ("euc mode\n\r"); set_eucmode (); break; case 'V': vflag = 0; break; case 'v': aprintf ("verbose\n\r"); vflag ++; break; case 'f': if (argv[ap + 1] == (char *) NULL) usage (); strcpy (shellprog, argv[ap+1]); shell_flag ++; break; case 'e': if (argv[ap + 1] == (char *) NULL) usage (); strcpy (shellprog, argv[++ap]); sp = 0; while (argv[ap] != (char *) NULL) shella[sp++] = argv[ap++]; shella[sp] = (char *) NULL; break; #ifdef OKB case 'o': oasys ++; break; #endif case 'H': if (argv[ap + 1] == (char *) NULL) usage(); sp = 0; while (argc > 1 && *argv[ap + 1] != '-') { if (sp >= MAXSERVER) break; serv_list[sp++] = argv[ap + 1]; ap++; argc--; } cur_serv = serv_list[0]; break; case 'h': default: usage (); break; } } argc --; ap ++; } if (cur_serv == NULL || *cur_serv == '\0') setsjserv(getenv("SJ3SERV")); } void usage(void) { aprintf ("Usage: %s [-option ...]\n\r", progname); aprintf ("\t-option\n\r"); aprintf ("\t\t-h \thelp\n\r"); aprintf ("\t\t-L \tlogin shell\n\r"); aprintf ("\t\t-f shellname \texec shell name\n\r"); aprintf ("\t\t-e command... \texec command arguments\n\r"); #ifdef OKB aprintf ("\t\t-o \toyayubi shift keyboard\n\r"); #endif aprintf ("\t\t-H hostname... \tname list of server hosts\n\r"); if (vflag > 2) { aprintf ("\t\t-v \tverbose mode\n\r"); aprintf ("\t\t-E \tEUC mode\n\r"); } exit (1); } void sjinit (void) { getfixtty (); setshellname (); if (cur_serv == NULL) cur_serv = serv_list[0] = my_hname; SJ2_henkan_init (); start_guideline (); } void setshellname (void) { char *s; char *namep; if (shellprog[0] == '\0') { s = getenv ("SHELL"); if ((s == NULL) || (*s == '\0') || Lflag) strcpy (shellprog, DEFAULTSHELL); else strcpy (shellprog, s); } if (Lflag) strcpy (shellname, "-"); #ifndef SVR4 else strcpy (shellname, "J"); #endif if ((namep = strrchr (shellprog, '/')) == NULL) namep = shellprog; else namep ++; strcat (shellname, namep); strcat (shellname, "["); strcat (shellname, user_name); strcat (shellname, " on "); strcat (shellname, progname); strcat (shellname, "]"); } void getfixtty (void) { getmaster (); fixtty (); setdev (); } void get_ttymode (void) { #ifdef SYSV_TERMIOS ioctl (0, TCGETS, (char *)&b); erase_char = b.c_cc[VERASE]; set_bs(erase_char); erase_str[0] = erase_char; erase_str[1] = '\0'; #else ioctl (0, TIOCGETP, (char *)&b); erase_char = b.sg_erase; set_bs(erase_char); erase_str[0] = erase_char; erase_str[1] = '\0'; ioctl (0, TIOCGETC, (char *)&tc); ioctl (0, TIOCGETC, (char *)&tc1); ioctl (0, TIOCGETD, (char *)&l); ioctl (0, TIOCGLTC, (char *)&lc); ioctl (0, TIOCGLTC, (char *)&lc1); ioctl (0, TIOCLGET, (char *)&lb); #endif #ifdef __sony_news ioctl (0, TIOCKGET, (char *)&jmode); jmode2 = set_jmode (jmode); ioctl (0, TIOCKGETC, (char *)&jtc); #else (void) set_jmode(); #endif } void getmaster (void) { #ifdef SVR4 struct stat stb; if ((master = open(mptname, O_RDWR)) < 0) { aprintf ("Out of pty's\n\r"); done3 (); } ioctl(master, I_PUSH, "pckt"); #else /* * Change pseudo-devices. * Because FreeBSD's master pseudo-devices are pty[p-sP-S][0-9a-v]. * Patched by Hidekazu Kuroki(hidekazu@cs.titech.ac.jp) 1996/8/10 */ #if defined(__FreeBSD__) || defined(__DragonFly__) struct stat stb; int h, i, j, k1, k2; #else /* !__FreeBSD__ */ char c; struct stat stb; int i, j, k1, k2; #endif /* __FreeBSD__ */ strcpy(line, "/dev/ptyXX"); k1 = strlen("/dev/pty"); k2 = strlen ("/dev/ptyp"); /* * Change pseudo-devices. * Because FreeBSD's master pseudo-devices are pty[p-sP-S][0-9a-v]. * Patched by Hidekazu Kuroki(hidekazu@cs.titech.ac.jp) 1996/8/10 */ #if defined(__FreeBSD__) || defined(__DragonFly__) for (h = 0; h < 8; h++) { line[k1] = "pqrsPQRS"[h]; line[k2] = '0'; if (stat (line, &stb) < 0) break; for (i = 0; i < 32; i++) { line[k2] = "0123456789abcdefghijklmnopqrstuv"[i]; #else /* !__FreeBSD__ */ for (c = 'p'; c <= 'z'; c ++) { line[k1] = c; line[k2] = '0'; if (stat (line, &stb) < 0) break; for (i = 0; i < 16; i++) { line[k2] = "0123456789abcdef"[i]; #endif /* __FreeBSD__ */ master = open (line, 2); if (master >= 0) { j = 1; ioctl (master, TIOCPKT, &j); return; } } } aprintf ("Out of pty's\n\r"); done3 (); #endif } void #ifdef __sony_news set_jmode (int mode) #else set_jmode (void) #endif { #ifdef __sony_news int term_mode; term_mode = mode & KM_KANJI; if (term_mode == KM_JIS) { aprintf ("error: tty jis terminal mode\n\r"); fflush (stdout); exit (1); } if (term_mode == KM_ASCII) { aprintf ("error: tty ascii terminal mode\n\r"); fflush (stdout); exit (1); } else if (term_mode == KM_EUC) { set_eucmode (); mode &= ~KM_SYSSJIS; mode |= KM_SYSEUC; (void) setlocale(LC_CTYPE, "ja_JP.EUC"); current_locale = LC_CTYPE_EUC; } else if (term_mode == KM_SJIS) { mode &= ~KM_SYSEUC; mode |= KM_SYSSJIS; (void) setlocale(LC_CTYPE, "ja_JP.SJIS"); current_locale = LC_CTYPE_SHIFTJIS; } else { aprintf ("error: unknown tty terminal code\n\r"); fflush (stdout); exit (1); } return (mode); #else char *loc; #ifdef LACKOF_SETLOCALE loc = getenv("LANG"); #else loc = setlocale(LC_CTYPE, ""); #endif if (!loc) { aprintf("error: bad locale\n"); fflush(stdout); exit(1); } if (strcmp(loc, "ja_JP.SJIS") == 0) { current_locale = LC_CTYPE_SHIFTJIS; } else if (strncmp(loc, "ja", 2) == 0 || strncmp(loc, "Ja", 2) == 0) { current_locale = LC_CTYPE_EUC; set_eucmode(); } else { aprintf("error: This locale will not use japanese.\n"); fflush(stdout); exit(1); } #endif /* __sony_news */ } void fixtty (void) { #ifdef SYSV_TERMIOS struct termios sbuf; sbuf = b; sbuf.c_iflag &= ~(INLCR|IGNCR|ICRNL|IUCLC|IXON); sbuf.c_oflag &= ~(ONLCR|OPOST); sbuf.c_lflag &= ~(ICANON|ECHO); sbuf.c_cc[VMIN] = 1; sbuf.c_cc[VTIME] = 0; sbuf.c_cc[VINTR] = 0; sbuf.c_cc[VQUIT] = 0; sbuf.c_cc[VSUSP] = 0; #ifdef VDSUSP sbuf.c_cc[VDSUSP] = 0; #endif /* VDSUSP */ sbuf.c_cc[VREPRINT] = 0; sbuf.c_cc[VDISCARD] = 0; sbuf.c_cc[VWERASE] = 0; sbuf.c_cc[VLNEXT] = 0; (void) ioctl(0, TCSETSW, (char *)&sbuf); #else struct sgttyb sbuf; sbuf = b; sbuf.sg_flags &= ~(EVENP|ODDP|ECHO|CRMOD|RAW|TBDELAY); sbuf.sg_flags |= CBREAK; sbuf.sg_flags |= TANDEM; ioctl (0, TIOCSETN, (char *)&sbuf); tc1.t_intrc = -1; tc1.t_quitc = -1; tc1.t_eofc = -1; ioctl (0, TIOCSETC, (char *)&tc1); lc1.t_suspc = -1; lc1.t_dsuspc = -1; lc1.t_rprntc = -1; lc1.t_flushc = -1; lc1.t_werasc = -1; lc1.t_lnextc = -1; ioctl (0, TIOCSLTC, (char *)&lc1); #endif #ifdef __sony_news ioctl (0, TIOCKSET, (char *)&jmode2); #endif } #ifdef BSD43 #include #endif void setdev (void) { char *cp; #ifdef BSD43 struct group *ttygrp; #endif Conversion *cv; cv = current_conversion; if ((cp = ttyname (2)) != NULL) strcpy (tty_name, cp); else *tty_name = '\0'; #ifndef SVR4 strcpy (slave_name, line); slave_name[strlen ("/dev/")] = 't'; #endif #ifdef BSD43 if ((ttygrp = getgrnam ("tty")) != NULL) chown(slave_name, getuid(), ttygrp->gr_gid); else chown(slave_name, getuid(), getgid()); chmod(slave_name, 0620); #else chown(slave_name, getuid(), getgid()); chmod(slave_name, 0622); #endif #ifndef SYSV_TERMIOS Ttyslot = nmttyslot (slave_name); #endif #ifdef SYSV_TERMIOS if (ioctl(0, TIOCGWINSZ, &Ttysize) == 0) #else if (ioctl(0, TIOCGSIZE, &Ttysize) == 0) #endif { if (!status_line) --Ttysize.ts_lines; if (Ttysize.ts_lines < 1) { aprintf ("not enough lines\n\r"); done3 (); } if (Ttysize.ts_cols < 1) { aprintf ("not enough columns\n\r"); done3 (); } cv->line = Ttysize.ts_lines; cv->column = Ttysize.ts_cols; SetRegion (); } else { if (cv->line < 1) cv->line = 24; if (cv->column < 1) cv->column = 80; Ttysize.ts_lines = cv->line; Ttysize.ts_cols = cv->column; if (ioctl(0, TIOCSWINSZ, &Ttysize) < 0) { aprintf("Warnning: Can't get tty size, use rows(%d) and columns(%d).\n\r", cv->line, cv->column); } if (!status_line) { Ttysize.ts_lines--; cv->line--; } SetRegion (); } if (cv->column < MINCOL) { if (Hlevel > 1) Hlevel = 1; } else if (HHlevel > 1) { Hlevel = 2; } if (vflag > 1) { aprintf ("line %d\n\r", cv->line); aprintf ("column %d\n\r", cv->column); } #ifndef SVR4 /* * Remove warning. * Patched by Hidekazu Kuroki(hidekazu@cs.titech.ac.jp) 1996/8/10 */ (void) signal (SIGCHLD, (void (*)())exitprocess); #endif } static char shellbuf[128]; void forkshell (void) { #ifdef SVR4 struct sigaction action; sigset_t sset; #endif Pid_shell = fork (); if (Pid_shell < 0) { perror ("fork"); done (); } if (Pid_shell == 0) { shellprocess (); } if (vflag > 1) { aprintf ("sj3 pid = %d\n\r", getpid ()); aprintf ("shell pid = %d\n\r", Pid_shell); } (void) signal (SIGHUP, (void (*)())fail); (void) signal (SIGINT, (void (*)())fail); (void) signal (SIGTERM, (void (*)())fail); (void) signal (SIGWINCH, (void (*)())onwinch); #ifdef SVR4 (void) sigemptyset(&sset); (void) sigaddset(&sset, SIGCHLD); action.sa_handler = (void (*)()) exitprocess; action.sa_mask = sset; action.sa_flags = SA_RESTART; (void) sigaction(SIGCHLD, &action, NULL); #endif } void sj3_setenv (char* ename, char* eval, char* buf) { char *cp, *dp; char **ep = environ; while ((dp = *ep++) != NULL) { for (cp = ename; *cp == *dp && *cp; cp++, dp++) continue; if (*cp == 0 && (*dp == '=' || *dp == 0)) { strcat(buf, eval); *--ep = buf; return; } } } void shellprocess (void) { int t, f; #ifdef SYSV_TERMIOS #ifdef SYSV_UTMP struct utmp Utmp; #else struct utmpx Utmp; #endif setsid(); getslave (); memset ((char *) &Utmp, '\0', sizeof (Utmp)); (void) strncpy(Utmp.ut_user, user_name, sizeof(Utmp.ut_user)); (void) strncpy(Utmp.ut_line, &slave_name[sizeof("/dev/")-1], sizeof(Utmp.ut_line)); Utmp.ut_type = USER_PROCESS; #ifdef SYSV_UTMP Utmp.ut_pid = (pid_t)getpid(); strncpy(Utmp.ut_id, &Utmp.ut_line[2], 4); Utmp.ut_id[0] = 't'; Utmp.ut_time = time(0); setutent(); getutid(&Utmp); pututline(&Utmp); endutent(); #else Utmp.ut_pid = (o_pid_t)getpid(); Utmp.ut_id[0] = 's'; Utmp.ut_id[1] = 'j'; Utmp.ut_id[2] = SC_WILDC; Utmp.ut_id[3] = SC_WILDC; Utmp.ut_exit.e_termination = 0; Utmp.ut_exit.e_exit = 0; (void) time (&Utmp.ut_tv.tv_sec); if (makeutx(&Utmp) == NULL) aprintf ("%s:\tmakeutx failed\r\n", progname); #endif /* SYSV_UTMP */ #else /* SYSV_TERMIOS */ struct utmp Utmp; char *p; /* * Remove warning. * Patched by Hidekazu Kuroki(hidekazu@cs.titech.ac.jp) 1996/8/10 */ #define SCPYN(a, b) strncpy(a, b, sizeof(a)) if ((p = ttyname (0)) == NULL) SCPYN(Utmp.ut_host, progname); else { SCPYN(Utmp.ut_host, progname); strcat (Utmp.ut_host, " on "); p = strrchr (p, '/') + 1; strcat (Utmp.ut_host, p); } SCPYN(Utmp.ut_name, user_name); SCPYN(Utmp.ut_line, strrchr (slave_name, '/') + 1); time (&Utmp.ut_time); #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__bsdi__) || defined(__DragonFly__) if (setsid() < 0) perror("setsid()"); #else t = open ("/dev/tty", 2); if (t >= 0) { ioctl (t, TIOCNOTTY, (char *)0); (void) close(t); } #endif getslave (); #endif /* SYSV_TERMIOS */ (void) close (master); dup2 (slave, 0); dup2 (slave, 1); dup2 (slave, 2); (void) close (slave); #ifndef SYSV_TERMIOS if (Ttyslot > 0 && (f = open (_PATH_UTMP, 1)) >= 0) { lseek (f, (long) (Ttyslot * sizeof (Utmp)), 0); write (f, (char *)&Utmp, sizeof (Utmp)); close (f); } #endif /* SYSV_TERMIOS */ setgid (getgid ()); setuid (getuid ()); if (shellargs[0] == (char *) NULL) { shellargs[0] = shellname; shellargs[1] = (char *) 0; } /* * Remove warning. * Patched by Hidekazu Kuroki(hidekazu@cs.titech.ac.jp) 1996/8/10 */ (void) signal (SIGPIPE, (void (*)())sigpipe); if ( *shellprog == '/' ) { if (shell_flag) { strcpy (shellbuf, "SHELL="); sj3_setenv("SHELL", shellprog, shellbuf); } (void) execve (shellprog, shellargs, environ); } else execcmd (shellprog, shellargs); perror (shellprog); exit (1); } void getslave (void) { #ifdef SVR4 grantpt(master); unlockpt(master); slave_name = ptsname(master); slave = open(slave_name, O_RDWR); if (slave < 0) { perror(slave_name); done2(); } ioctl(slave, I_PUSH, "ptem"); ioctl(slave, I_PUSH, "ldterm"); ioctl(slave, I_PUSH, "ttcompat"); (void) ioctl(slave, TCSETSF, (char *)&b); (void) ioctl(slave, TIOCSWINSZ, (char *)&Ttysize); #ifdef __sony_news (void) ioctl(slave, TIOCKSET, (char *)&jmode); (void) ioctl(slave, TIOCKSETC, (char *)&jtc); #endif #else line[strlen ("/dev/")] = 't'; slave = open (line, 2); if (slave < 0) { perror (line); done2 (); } #ifndef SYSV_TERMIOS #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__bsdi__) || defined(__DragonFly__) ioctl(slave, TIOCSCTTY, NULL); #endif ioctl (slave, TIOCSETP, (char *)&b); ioctl (slave, TIOCSETC, (char *)&tc); ioctl (slave, TIOCSLTC, (char *)&lc); ioctl (slave, TIOCLSET, (char *)&lb); ioctl (slave, TIOCSETD, (char *)&l); #ifdef __sony_news ioctl (slave, TIOCKSET, (char *)&jmode); ioctl (slave, TIOCKSETC, (char *)&jtc); #endif ioctl (slave, TIOCSSIZE, &Ttysize); #else /* SYSV_TERMIOS */ (void) ioctl(slave, TCSETSF, (char *)&b); (void) ioctl(slave, TIOCSWINSZ, (char *)&Ttysize); #endif /* SYSV_TERMIOS */ #endif /* SVR4 */ } void execcmd (char* cmd, char** ap) { int c; char *getenv (); char *path, *cp, fullcmd[BUFSIZ]; path = getenv ("PATH"); cp = fullcmd; while ((c = *path++) != 0) { if (c == ':') { *cp++ = '/'; *cp = '\0'; cp = fullcmd; (void) strcat (cp, cmd); if (shell_flag) { strcpy (shellbuf, "SHELL="); sj3_setenv ("SHELL", cp, shellbuf); } (void) execve (cp, ap, environ); cp = fullcmd; } else *cp++ = c; } *cp++ = '/'; *cp = '\0'; cp = fullcmd; (void) strcat (cp, cmd); if (shell_flag) { strcpy (shellbuf, "SHELL="); sj3_setenv ("SHELL", cp, shellbuf); } (void) execve (cp, ap, environ); } void fail (void) { (void) kill (0, SIGTERM); done (); } void done (void) { (void) signal (SIGWINCH, SIG_IGN); clear_guide_line (); end_guideline (); done2 (); } void done2 (void) { chown (slave_name, 0, 0); chmod (slave_name, 0666); #ifdef SYSV_TERMIOS ioctl (0, TCSETSW, (char *)&b); #else /* SYSV_TERMIOS */ ioctl (0, TIOCSETP, (char *)&b); ioctl (0, TIOCSETC, (char *)&tc); ioctl (0, TIOCSLTC, (char *)&lc); #endif /* SYSV_TERMIOS */ #ifdef __sony_news ioctl (0, TIOCKSET, (char *)&jmode); #endif if (!status_line) { ++Ttysize.ts_lines; SetRegion(); } clearutmpentry (); SJ2_henkan_end (); EndConversion (); done3 (); } void done3 (void) { aprintf ("\r\nexit %s.\r\n", progname); exit (0); } void exitprocess (void) { #ifdef SVR4 siginfo_t info; (void) waitid (P_ALL, 0, &info, WNOHANG | WUNTRACED | WEXITED | WTRAPPED | WCONTINUED); if ((info.si_code == CLD_CONTINUED) ||(info.si_code == CLD_TRAPPED)) return; if (info.si_code == CLD_STOPPED) #else int pid, status; /* * Remove warning. * Patched by Hidekazu Kuroki(hidekazu@cs.titech.ac.jp) 1996/8/10 */ pid = wait3 (&status, (WNOHANG|WUNTRACED), 0); if (WIFSTOPPED (status)) #endif suspend(); else done (); } void suspend (void) { #ifdef SIGTYPE_VOID void (*old_sigtstp) (); #else int (*old_sigtstp) (); #endif SELECT_FD ifds; int nc; struct timeval t; clear_guide_line (); do { cont: t.tv_sec = 0; t.tv_usec = UsecWeight (1); FD_ZERO (&ifds); FD_SET (master, &ifds); if (select (master + 1, &ifds, 0, 0, &t) > 0) { if (FD_ISSET (master, &ifds)) output_master (); } else if (errno == EINTR) { errno = 0; goto cont; } if (ioctl (master, TIOCOUTQ, &nc) < 0) #ifdef SVR4 break; #else fail (); #endif } while (nc > 0); #ifdef SYSV_TERMIOS ioctl (0, TCSETSW, (char *)&b); #else /* SYSV_TERMIOS */ ioctl (0, TIOCSETP, (char *)&b); ioctl (0, TIOCSETC, (char *)&tc); ioctl (0, TIOCSLTC, (char *)&lc); #endif /* SYSV_TERMIOS */ #ifdef __sony_news ioctl (0, TIOCKSET, (char *)&jmode); #endif if (!status_line) { ++Ttysize.ts_lines; SetRegion(); } /* * Remove warning. * Patched by Hidekazu Kuroki(hidekazu@cs.titech.ac.jp) 1996/8/10 */ #ifdef SIGTYPE_VOID old_sigtstp = (void(*)()) signal (SIGTSTP, SIG_DFL); #else old_sigtstp = (int(*)()) signal (SIGTSTP, SIG_DFL); #endif kill (0, SIGTSTP); /* * Remove warning. * Patched by Hidekazu Kuroki(hidekazu@cs.titech.ac.jp) 1996/8/10 */ (void) signal (SIGTSTP, (void (*)())old_sigtstp); killpg (Pid_shell, SIGCONT); fixtty (); if (!status_line) { --Ttysize.ts_lines; SetRegion(); } print_guide_line (); } #ifdef SVR4 void clearutmpentry(void) { struct utmpx *up; #ifdef SVR4 struct sigaction action; sigset_t sset; sigemptyset(&sset); sigaddset(&sset, SIGCHLD); action.sa_handler = SIG_IGN; action.sa_mask = sset; action.sa_flags = SA_RESTART; (void) sigaction(SIGCHLD, &action, NULL); #else signal(SIGCHLD, SIG_IGN); #endif setutxent(); while ( (up = getutxent()) ) { if (up->ut_pid != (o_pid_t)Pid_shell) continue; up->ut_type = DEAD_PROCESS; up->ut_exit.e_termination = 0; up->ut_exit.e_exit = 0; (void) time (&up->ut_tv.tv_sec); if (modutx(up) == NULL) aprintf("%s:\tmodutx failed\r\n", progname); break; } endutxent(); #ifdef SVR4 action.sa_handler = (void (*)()) exitprocess; action.sa_mask = sset; action.sa_flags = SA_RESTART; (void) sigaction(SIGCHLD, &action, NULL); #else signal (SIGCHLD, (void (*)())exitprocess); #endif } #else /* SVR4 */ #ifdef SYSV_UTMP void clearutmpentry (void) { struct utmp Utmp; memset ((char *) &Utmp, '\0', sizeof (Utmp)); (void) strncpy(Utmp.ut_user, user_name, sizeof(Utmp.ut_user)); (void) strncpy(Utmp.ut_line, &slave_name[sizeof("/dev/")-1], sizeof(Utmp.ut_line)); Utmp.ut_type = DEAD_PROCESS; Utmp.ut_pid = (pid_t)getpid(); strncpy(Utmp.ut_id, &Utmp.ut_line[2], 4); Utmp.ut_id[0] = 't'; Utmp.ut_time = time(0); setutent(); getutid(&Utmp); pututline(&Utmp); endutent(); } #else /* SYSV_UTMP */ void clearutmpentry (void) { int f; struct utmp Utmp; Utmp.ut_line[0] = '\0'; Utmp.ut_name[0] = '\0'; Utmp.ut_host[0] = '\0'; Utmp.ut_time = 0; if (Ttyslot > 0 && (f = open (_PATH_UTMP, 1)) >= 0) { lseek (f, (long) (Ttyslot * sizeof (Utmp)), 0); write (f, (char *)&Utmp, sizeof (Utmp)); close (f); } } #endif /* SYSV_UTMP */ #endif /* SVR4 */ void onwinch (void) { int ttypgrp; Conversion *cv; cv = current_conversion; (void) signal (SIGWINCH, SIG_IGN); #ifdef SYSV_TERMIOS if (ioctl (0, TIOCGWINSZ, &Ttysize) == 0) #else /* SYSV_TERMIOS */ if (ioctl (0, TIOCGSIZE, &Ttysize) == 0) #endif /* SYSV_TERMIOS */ { if (!status_line) { clear_guide_line (); --Ttysize.ts_lines; } cv->line = Ttysize.ts_lines; cv->column = Ttysize.ts_cols; if (cv->column < MINCOL) { if (Hlevel > 1) Hlevel = 1; } else if (HHlevel > 1) { Hlevel = 2; } SetRegion(); if (!status_line) { print_guide_line (); } killpg (Pid_shell, SIGWINCH); if (ioctl (master, TIOCGPGRP, &ttypgrp) == 0) killpg (ttypgrp, SIGWINCH); } (void) signal (SIGWINCH, (void (*)())onwinch); } void SetRegion (void) { set_tty_size (); if (!status_line) RegionSet (1, Ttysize.ts_lines); } void set_tty_size (void) { #ifdef SYSV_TERMIOS ioctl (master, TIOCSWINSZ, &Ttysize); #else /* SYSV_TERMIOS */ ioctl (master, TIOCSSIZE, &Ttysize); #endif /* SYSV_TERMIOS */ } void setsjserv(char* hname) { char *p; int i; char *sbuf; if (hname == NULL || *hname == '\0') return; if ((sbuf = (char *)malloc(strlen(hname))) == NULL) { fprintf(stderr, "setsjserv: can't alloc memory\n\r"); done3(); } strcpy(sbuf, hname); p = sbuf; for (i = 0; i < MAXSERVER; i++) { serv_list[i] = p; while(*p != '\0' && *p != ' ' && *p != '\t') p++; if (*p == '\0') break; *p++ = '\0'; } cur_serv = serv_list[0]; } char * chmyhname(char* hname) { if (hname != NULL) { if (strcmp(my_hname, hname) == 0 || strcmp("localhost", hname) == 0) hname = NULL; } return(hname); }