sj3/sj3.c
SASANO Takayoshi 9d9d49ea29 fix some 'extern function()' declaration
Signed-off-by: SASANO Takayoshi <uaa@uaa.org.uk>
2023-12-09 23:33:26 +09:00

1350 lines
27 KiB
C

/*
* 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 <signal.h>
#include <errno.h>
#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__bsdi__) || defined(__DragonFly__)
#define USE_OLD_TTY
#if defined(__NetBSD__)
#define LACKOF_SETLOCALE
#endif
#if defined(__FreeBSD__)
#include <sys/ioctl_compat.h>
#endif
#include <curses.h>
#endif
#include "select.h"
#include "common.h"
#ifdef SVR4
#include <sys/fcntl.h>
#include <sys/stropts.h>
#include <netdb.h>
#endif
#include <locale.h>
#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 <termios.h>
#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 <grp.h>
#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);
}