/* pty_unicos.c - routines to allocate ptys - for CRAY UNICOS 5.1 and 6.0 */
|
/* pty_unicos.c - routines to allocate ptys - for CRAY UNICOS 5.1 and 6.0 */
|
|
|
/*
|
/*
|
|
|
Original by: Don Libes, NIST, 2/6/90
|
Original by: Don Libes, NIST, 2/6/90
|
Hacked for Unicos 5.1 by: Frank Terhaar-Yonkers, US EPA, 1/10/91
|
Hacked for Unicos 5.1 by: Frank Terhaar-Yonkers, US EPA, 1/10/91
|
Hacked for Unicos 6.0 by: Pete TerMaat, pete@willow.cray.com, 3/27/91
|
Hacked for Unicos 6.0 by: Pete TerMaat, pete@willow.cray.com, 3/27/91
|
|
|
Design and implementation of this program was paid for by U.S. tax
|
Design and implementation of this program was paid for by U.S. tax
|
dollars. Therefore it is public domain. However, the author and NIST
|
dollars. Therefore it is public domain. However, the author and NIST
|
would appreciate credit if this program or parts of it are used.
|
would appreciate credit if this program or parts of it are used.
|
|
|
*/
|
*/
|
|
|
#include "expect_cf.h"
|
#include "expect_cf.h"
|
#include <stdio.h>
|
#include <stdio.h>
|
#include <signal.h>
|
#include <signal.h>
|
|
|
#if defined(SIGCLD) && !defined(SIGCHLD)
|
#if defined(SIGCLD) && !defined(SIGCHLD)
|
#define SIGCHLD SIGCLD
|
#define SIGCHLD SIGCLD
|
#endif
|
#endif
|
|
|
#ifdef HAVE_UNISTD_H
|
#ifdef HAVE_UNISTD_H
|
#include <unistd.h>
|
#include <unistd.h>
|
#else
|
#else
|
extern int fork(), execl(), wait();
|
extern int fork(), execl(), wait();
|
#endif
|
#endif
|
#include <errno.h>
|
#include <errno.h>
|
#include <sys/types.h>
|
#include <sys/types.h>
|
#include <sys/stat.h>
|
#include <sys/stat.h>
|
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
#include <sys/file.h>
|
#include <sys/file.h>
|
#ifdef HAVE_SYS_FCNTL_H
|
#ifdef HAVE_SYS_FCNTL_H
|
# include <sys/fcntl.h>
|
# include <sys/fcntl.h>
|
#else
|
#else
|
# include <fcntl.h>
|
# include <fcntl.h>
|
#endif
|
#endif
|
/*#if CRAY>=60*/
|
/*#if CRAY>=60*/
|
#if defined(HAVE_TERMIOS)
|
#if defined(HAVE_TERMIOS)
|
# include <sys/termios.h>
|
# include <sys/termios.h>
|
#else
|
#else
|
# include <sys/termio.h>
|
# include <sys/termio.h>
|
/*#endif /* 60 */*/
|
/*#endif /* 60 */*/
|
#endif /* defined(HAVE_TERMIOS) */
|
#endif /* defined(HAVE_TERMIOS) */
|
#if CRAY>=70 && defined(_CRAY2)
|
#if CRAY>=70 && defined(_CRAY2)
|
#include <sys/session.h>
|
#include <sys/session.h>
|
#endif /* 70 */
|
#endif /* 70 */
|
#include <sys/pty.h>
|
#include <sys/pty.h>
|
#include <pwd.h>
|
#include <pwd.h>
|
#include <utmp.h>
|
#include <utmp.h>
|
#include <signal.h>
|
#include <signal.h>
|
#include "exp_tty_in.h"
|
#include "exp_tty_in.h"
|
#include "exp_rename.h"
|
#include "exp_rename.h"
|
|
|
#ifdef HAVE_SYSCONF_H
|
#ifdef HAVE_SYSCONF_H
|
#include <sys/sysconfig.h>
|
#include <sys/sysconfig.h>
|
#endif
|
#endif
|
|
|
void debuglog();
|
void debuglog();
|
|
|
#ifndef TRUE
|
#ifndef TRUE
|
#define TRUE 1
|
#define TRUE 1
|
#define FALSE 0
|
#define FALSE 0
|
#endif
|
#endif
|
|
|
#ifndef MAXHOSTNAMELEN
|
#ifndef MAXHOSTNAMELEN
|
#define MAXHOSTNAMELEN 64
|
#define MAXHOSTNAMELEN 64
|
#endif /* MAXHOSTNAMELEN */
|
#endif /* MAXHOSTNAMELEN */
|
|
|
static char linep[] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
|
static char linep[] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
|
static char linet[] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
|
static char linet[] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
|
static int lowpty;
|
static int lowpty;
|
static int highpty;
|
static int highpty;
|
static int realuid;
|
static int realuid;
|
static int realgid;
|
static int realgid;
|
static int *ptys;
|
static int *ptys;
|
static char myname[32];
|
static char myname[32];
|
static char hostname[MAXHOSTNAMELEN];
|
static char hostname[MAXHOSTNAMELEN];
|
char *exp_pty_slave_name;
|
char *exp_pty_slave_name;
|
char *exp_pty_error;
|
char *exp_pty_error;
|
|
|
static void
|
static void
|
pty_stty(s,name)
|
pty_stty(s,name)
|
char *s; /* args to stty */
|
char *s; /* args to stty */
|
char *name; /* name of pty */
|
char *name; /* name of pty */
|
{
|
{
|
#define MAX_ARGLIST 10240
|
#define MAX_ARGLIST 10240
|
char buf[MAX_ARGLIST]; /* overkill is easier */
|
char buf[MAX_ARGLIST]; /* overkill is easier */
|
RETSIGTYPE (*old)(); /* save old sigalarm handler */
|
RETSIGTYPE (*old)(); /* save old sigalarm handler */
|
|
|
#ifdef STTY_READS_STDOUT
|
#ifdef STTY_READS_STDOUT
|
sprintf(buf,"/bin/stty %s > %s",s,name);
|
sprintf(buf,"/bin/stty %s > %s",s,name);
|
#else
|
#else
|
sprintf(buf,"/bin/stty %s < %s",s,name);
|
sprintf(buf,"/bin/stty %s < %s",s,name);
|
#endif
|
#endif
|
old = signal(SIGCHLD, SIG_DFL);
|
old = signal(SIGCHLD, SIG_DFL);
|
system(buf);
|
system(buf);
|
signal(SIGCHLD, old); /* restore signal handler */
|
signal(SIGCHLD, old); /* restore signal handler */
|
}
|
}
|
|
|
int exp_dev_tty; /* file descriptor to /dev/tty or -1 if none */
|
int exp_dev_tty; /* file descriptor to /dev/tty or -1 if none */
|
static int knew_dev_tty;/* true if we had our hands on /dev/tty at any time */
|
static int knew_dev_tty;/* true if we had our hands on /dev/tty at any time */
|
|
|
#ifdef TIOCGWINSZ
|
#ifdef TIOCGWINSZ
|
static struct winsize winsize = {0, 0};
|
static struct winsize winsize = {0, 0};
|
#endif
|
#endif
|
#if defined(TIOCGSIZE) && !defined(TIOCGWINSZ)
|
#if defined(TIOCGSIZE) && !defined(TIOCGWINSZ)
|
static struct ttysize winsize = {0, 0};
|
static struct ttysize winsize = {0, 0};
|
#endif
|
#endif
|
|
|
/*struct termio exp_tty_original;*/
|
/*struct termio exp_tty_original;*/
|
exp_tty exp_tty_original;
|
exp_tty exp_tty_original;
|
|
|
#define GET_TTYTYPE 0
|
#define GET_TTYTYPE 0
|
#define SET_TTYTYPE 1
|
#define SET_TTYTYPE 1
|
static void
|
static void
|
ttytype(request,fd,ttycopy,ttyinit,s)
|
ttytype(request,fd,ttycopy,ttyinit,s)
|
int request;
|
int request;
|
int fd;
|
int fd;
|
/* following are used only if request == SET_TTYTYPE */
|
/* following are used only if request == SET_TTYTYPE */
|
int ttycopy; /* true/false, copy from /dev/tty */
|
int ttycopy; /* true/false, copy from /dev/tty */
|
int ttyinit; /* if true, initialize to sane state */
|
int ttyinit; /* if true, initialize to sane state */
|
char *s; /* stty args, used only if request == SET_TTYTYPE */
|
char *s; /* stty args, used only if request == SET_TTYTYPE */
|
{
|
{
|
if (request == GET_TTYTYPE) {
|
if (request == GET_TTYTYPE) {
|
if (-1 == ioctl(fd, TCGETA, (char *)&exp_tty_original)) {
|
if (-1 == ioctl(fd, TCGETA, (char *)&exp_tty_original)) {
|
knew_dev_tty = FALSE;
|
knew_dev_tty = FALSE;
|
exp_dev_tty = -1;
|
exp_dev_tty = -1;
|
}
|
}
|
#ifdef TIOCGWINSZ
|
#ifdef TIOCGWINSZ
|
ioctl(fd,TIOCGWINSZ,&winsize);
|
ioctl(fd,TIOCGWINSZ,&winsize);
|
#endif
|
#endif
|
#if defined(TIOCGSIZE) && !defined(TIOCGWINSZ)
|
#if defined(TIOCGSIZE) && !defined(TIOCGWINSZ)
|
ioctl(fd,TIOCGSIZE,&winsize);
|
ioctl(fd,TIOCGSIZE,&winsize);
|
#endif
|
#endif
|
} else { /* type == SET_TTYTYPE */
|
} else { /* type == SET_TTYTYPE */
|
if (ttycopy && knew_dev_tty) {
|
if (ttycopy && knew_dev_tty) {
|
(void) ioctl(fd, TCSETA, (char *)&exp_tty_current);
|
(void) ioctl(fd, TCSETA, (char *)&exp_tty_current);
|
#ifdef TIOCSWINSZ
|
#ifdef TIOCSWINSZ
|
ioctl(fd,TIOCSWINSZ,&winsize);
|
ioctl(fd,TIOCSWINSZ,&winsize);
|
#endif
|
#endif
|
#if defined(TIOCSSIZE) && !defined(TIOCSWINSZ)
|
#if defined(TIOCSSIZE) && !defined(TIOCSWINSZ)
|
ioctl(fd,TIOCGSIZE,&winsize);
|
ioctl(fd,TIOCGSIZE,&winsize);
|
#endif
|
#endif
|
}
|
}
|
|
|
if (ttyinit) {
|
if (ttyinit) {
|
/* overlay parms originally supplied by Makefile */
|
/* overlay parms originally supplied by Makefile */
|
pty_stty(DFLT_STTY,linet);
|
pty_stty(DFLT_STTY,linet);
|
}
|
}
|
|
|
/* lastly, give user chance to override any terminal parms */
|
/* lastly, give user chance to override any terminal parms */
|
if (s) {
|
if (s) {
|
pty_stty(s,linet);
|
pty_stty(s,linet);
|
}
|
}
|
}
|
}
|
}
|
}
|
|
|
void
|
void
|
exp_init_pty()
|
exp_init_pty()
|
{
|
{
|
int npty;
|
int npty;
|
char *myline;
|
char *myline;
|
|
|
lowpty=0;
|
lowpty=0;
|
#ifdef _SC_CRAY_NPTY
|
#ifdef _SC_CRAY_NPTY
|
highpty=sysconf(_SC_CRAY_NPTY);
|
highpty=sysconf(_SC_CRAY_NPTY);
|
#else
|
#else
|
highpty=128;
|
highpty=128;
|
#endif /* _SC_CRAY_NPTY */
|
#endif /* _SC_CRAY_NPTY */
|
|
|
ptys = (int *) malloc(sizeof(int)*(highpty+1));
|
ptys = (int *) malloc(sizeof(int)*(highpty+1));
|
if (ptys == NULL) {
|
if (ptys == NULL) {
|
fprintf(stderr,"exp_init_pty: couldn't allocate pty array\n");
|
fprintf(stderr,"exp_init_pty: couldn't allocate pty array\n");
|
exit(1);
|
exit(1);
|
}
|
}
|
for (npty = lowpty;npty <= highpty;npty++)
|
for (npty = lowpty;npty <= highpty;npty++)
|
ptys[npty] = 0;
|
ptys[npty] = 0;
|
|
|
realuid=getuid(); /* get REAL uid */
|
realuid=getuid(); /* get REAL uid */
|
realgid=getgid(); /* get REAL uid */
|
realgid=getgid(); /* get REAL uid */
|
|
|
exp_dev_tty = open("/dev/tty",O_RDWR);
|
exp_dev_tty = open("/dev/tty",O_RDWR);
|
knew_dev_tty = (exp_dev_tty != -1);
|
knew_dev_tty = (exp_dev_tty != -1);
|
if (knew_dev_tty) ttytype(GET_TTYTYPE,exp_dev_tty,0,0,(char *)0);
|
if (knew_dev_tty) ttytype(GET_TTYTYPE,exp_dev_tty,0,0,(char *)0);
|
|
|
/*
|
/*
|
* Acquire (as root) current user name and host.
|
* Acquire (as root) current user name and host.
|
*/
|
*/
|
(void) cuserid(myname);
|
(void) cuserid(myname);
|
(void) gethostname(hostname,sizeof(hostname));
|
(void) gethostname(hostname,sizeof(hostname));
|
|
|
/*
|
/*
|
* Set the real and effective userids to root using 'setuid'. Then
|
* Set the real and effective userids to root using 'setuid'. Then
|
* set the real and effective userids to the actual user using
|
* set the real and effective userids to the actual user using
|
* 'setreuid'. This allows using 'seteuid' to go back and forth from
|
* 'setreuid'. This allows using 'seteuid' to go back and forth from
|
* root and the actual userid. Don't ask me why it works.
|
* root and the actual userid. Don't ask me why it works.
|
*/
|
*/
|
setuid(0);
|
setuid(0);
|
setreuid(realuid,realuid);
|
setreuid(realuid,realuid);
|
}
|
}
|
|
|
/* returns fd of master end of pseudotty */
|
/* returns fd of master end of pseudotty */
|
int
|
int
|
getptymaster()
|
getptymaster()
|
{
|
{
|
struct stat sb;
|
struct stat sb;
|
int master;
|
int master;
|
int npty;
|
int npty;
|
|
|
exp_pty_error = 0;
|
exp_pty_error = 0;
|
|
|
debuglog("getptymaster: lowpty=%d highpty=%d\n",lowpty,highpty);
|
debuglog("getptymaster: lowpty=%d highpty=%d\n",lowpty,highpty);
|
for (npty = lowpty; npty <= highpty; npty++) {
|
for (npty = lowpty; npty <= highpty; npty++) {
|
if (seteuid(0) == -1) { /* we need to be root! */
|
if (seteuid(0) == -1) { /* we need to be root! */
|
debuglog("getptymaster: seteuid root errno=%d\n",
|
debuglog("getptymaster: seteuid root errno=%d\n",
|
errno);
|
errno);
|
}
|
}
|
(void) sprintf(linep, "/dev/pty/%03d", npty);
|
(void) sprintf(linep, "/dev/pty/%03d", npty);
|
master = open(linep, O_RDWR);
|
master = open(linep, O_RDWR);
|
|
|
if (master < 0) {
|
if (master < 0) {
|
debuglog("getptymaster: open linep=%s errno=%d\n",
|
debuglog("getptymaster: open linep=%s errno=%d\n",
|
linep,errno);
|
linep,errno);
|
continue;
|
continue;
|
}
|
}
|
|
|
(void) sprintf(linet, "/dev/ttyp%03d", npty);
|
(void) sprintf(linet, "/dev/ttyp%03d", npty);
|
if(stat(linet, &sb) < 0) {
|
if(stat(linet, &sb) < 0) {
|
debuglog("getptymaster: stat linet=%s errno=%d\n",
|
debuglog("getptymaster: stat linet=%s errno=%d\n",
|
linet,errno);
|
linet,errno);
|
(void) close(master);
|
(void) close(master);
|
continue;
|
continue;
|
}
|
}
|
if (sb.st_uid || sb.st_gid || sb.st_mode != 0600) {
|
if (sb.st_uid || sb.st_gid || sb.st_mode != 0600) {
|
if (chown(linet, realuid, realgid) == -1) {
|
if (chown(linet, realuid, realgid) == -1) {
|
debuglog("getptymaster: chown linet=%s errno=%d\n",
|
debuglog("getptymaster: chown linet=%s errno=%d\n",
|
linet,errno);
|
linet,errno);
|
}
|
}
|
if (chmod(linet, 0600) == -1) {
|
if (chmod(linet, 0600) == -1) {
|
debuglog("getptymaster: chmod linet=%s errno=%d\n",
|
debuglog("getptymaster: chmod linet=%s errno=%d\n",
|
linet,errno);
|
linet,errno);
|
}
|
}
|
(void)close(master);
|
(void)close(master);
|
master = open(linep, 2);
|
master = open(linep, 2);
|
if (master < 0) {
|
if (master < 0) {
|
debuglog("getptymaster: reopen linep=%s errno=%d\n",
|
debuglog("getptymaster: reopen linep=%s errno=%d\n",
|
linep,errno);
|
linep,errno);
|
continue;
|
continue;
|
}
|
}
|
}
|
}
|
if (seteuid(realuid) == -1) { /* back to who we are! */
|
if (seteuid(realuid) == -1) { /* back to who we are! */
|
debuglog("getptymaster: seteuid user errno=%d\n",
|
debuglog("getptymaster: seteuid user errno=%d\n",
|
errno);
|
errno);
|
}
|
}
|
if (access(linet, R_OK|W_OK) != 0) {
|
if (access(linet, R_OK|W_OK) != 0) {
|
debuglog("getptymaster: access linet=%s errno=%d\n",
|
debuglog("getptymaster: access linet=%s errno=%d\n",
|
linet,errno);
|
linet,errno);
|
(void) close(master);
|
(void) close(master);
|
continue;
|
continue;
|
}
|
}
|
debuglog("getptymaster: allocated %s\n",linet);
|
debuglog("getptymaster: allocated %s\n",linet);
|
ptys[npty] = -1;
|
ptys[npty] = -1;
|
exp_pty_slave_name = linet;
|
exp_pty_slave_name = linet;
|
return(master);
|
return(master);
|
}
|
}
|
if (seteuid(realuid) == -1) { /* back to who we are! */
|
if (seteuid(realuid) == -1) { /* back to who we are! */
|
debuglog("getptymaster: seteuid user errno=%d\n",errno);
|
debuglog("getptymaster: seteuid user errno=%d\n",errno);
|
}
|
}
|
return(-1);
|
return(-1);
|
}
|
}
|
|
|
/* see comment in pty_termios.c */
|
/* see comment in pty_termios.c */
|
/*ARGSUSED*/
|
/*ARGSUSED*/
|
void
|
void
|
exp_slave_control(master,control)
|
exp_slave_control(master,control)
|
int master;
|
int master;
|
int control;
|
int control;
|
{
|
{
|
}
|
}
|
|
|
int
|
int
|
getptyslave(ttycopy,ttyinit,stty_args)
|
getptyslave(ttycopy,ttyinit,stty_args)
|
int ttycopy;
|
int ttycopy;
|
int ttyinit;
|
int ttyinit;
|
char *stty_args;
|
char *stty_args;
|
{
|
{
|
int slave;
|
int slave;
|
|
|
if (0 > (slave = open(linet, O_RDWR))) {
|
if (0 > (slave = open(linet, O_RDWR))) {
|
debuglog("getptyslave: open linet=%s errno=%d\n",linet,errno);
|
debuglog("getptyslave: open linet=%s errno=%d\n",linet,errno);
|
return(-1);
|
return(-1);
|
}
|
}
|
|
|
/* sanity check - if slave not 0, skip rest of this and return */
|
/* sanity check - if slave not 0, skip rest of this and return */
|
/* to what will later be detected as an error in caller */
|
/* to what will later be detected as an error in caller */
|
if (0 != slave) {
|
if (0 != slave) {
|
debuglog("getptyslave: slave fd not 0\n");
|
debuglog("getptyslave: slave fd not 0\n");
|
return(slave);
|
return(slave);
|
}
|
}
|
|
|
if (0 == slave) {
|
if (0 == slave) {
|
/* if opened in a new process, slave will be 0 (and */
|
/* if opened in a new process, slave will be 0 (and */
|
/* ultimately, 1 and 2 as well) */
|
/* ultimately, 1 and 2 as well) */
|
|
|
/* duplicate 0 onto 1 and 2 to prepare for stty */
|
/* duplicate 0 onto 1 and 2 to prepare for stty */
|
fcntl(0,F_DUPFD,1);
|
fcntl(0,F_DUPFD,1);
|
fcntl(0,F_DUPFD,2);
|
fcntl(0,F_DUPFD,2);
|
}
|
}
|
|
|
ttytype(SET_TTYTYPE,slave,ttycopy,ttyinit,stty_args);
|
ttytype(SET_TTYTYPE,slave,ttycopy,ttyinit,stty_args);
|
return(slave);
|
return(slave);
|
}
|
}
|
|
|
setptyutmp()
|
setptyutmp()
|
{
|
{
|
struct utmp utmp;
|
struct utmp utmp;
|
|
|
if (seteuid(0) == -1) { /* Need to be root */
|
if (seteuid(0) == -1) { /* Need to be root */
|
debuglog("setptyutmp: setuid root errno=%d\n",errno);
|
debuglog("setptyutmp: setuid root errno=%d\n",errno);
|
return(-1);
|
return(-1);
|
}
|
}
|
(void) time(&utmp.ut_time);
|
(void) time(&utmp.ut_time);
|
utmp.ut_type = USER_PROCESS;
|
utmp.ut_type = USER_PROCESS;
|
utmp.ut_pid = getpid();
|
utmp.ut_pid = getpid();
|
strncpy(utmp.ut_user,myname,sizeof(utmp.ut_user));
|
strncpy(utmp.ut_user,myname,sizeof(utmp.ut_user));
|
strncpy(utmp.ut_host,hostname,sizeof(utmp.ut_host));
|
strncpy(utmp.ut_host,hostname,sizeof(utmp.ut_host));
|
strncpy(utmp.ut_line,linet+5,sizeof(utmp.ut_line));
|
strncpy(utmp.ut_line,linet+5,sizeof(utmp.ut_line));
|
strncpy(utmp.ut_id,linet+8,sizeof(utmp.ut_id));
|
strncpy(utmp.ut_id,linet+8,sizeof(utmp.ut_id));
|
if (pututline(&utmp) == NULL) {
|
if (pututline(&utmp) == NULL) {
|
debuglog("setptyutmp: pututline failed\n");
|
debuglog("setptyutmp: pututline failed\n");
|
}
|
}
|
endutent();
|
endutent();
|
if (seteuid(realuid) == -1)
|
if (seteuid(realuid) == -1)
|
debuglog("setptyutmp: seteuid user errno=%d\n",errno);
|
debuglog("setptyutmp: seteuid user errno=%d\n",errno);
|
return(0);
|
return(0);
|
}
|
}
|
|
|
setptypid(pid)
|
setptypid(pid)
|
int pid;
|
int pid;
|
{
|
{
|
int npty;
|
int npty;
|
|
|
for (npty = lowpty; npty <= highpty; npty++) {
|
for (npty = lowpty; npty <= highpty; npty++) {
|
if (ptys[npty] < 0) {
|
if (ptys[npty] < 0) {
|
debuglog("setptypid: ttyp%03d pid=%d\n",npty,pid);
|
debuglog("setptypid: ttyp%03d pid=%d\n",npty,pid);
|
ptys[npty] = pid;
|
ptys[npty] = pid;
|
break;
|
break;
|
}
|
}
|
}
|
}
|
}
|
}
|
|
|
ttyp_reset()
|
ttyp_reset()
|
{
|
{
|
int npty;
|
int npty;
|
|
|
if (seteuid(0) == -1) { /* we need to be root! */
|
if (seteuid(0) == -1) { /* we need to be root! */
|
debuglog("ttyp_reset: seteuid root errno=%d\n",errno);
|
debuglog("ttyp_reset: seteuid root errno=%d\n",errno);
|
}
|
}
|
for (npty = lowpty; npty <= highpty; npty++) {
|
for (npty = lowpty; npty <= highpty; npty++) {
|
if (ptys[npty] <= 0)
|
if (ptys[npty] <= 0)
|
continue;
|
continue;
|
|
|
(void) sprintf(linet, "/dev/ttyp%03d", npty);
|
(void) sprintf(linet, "/dev/ttyp%03d", npty);
|
debuglog("ttyp_reset: resetting %s, killing %d\n",
|
debuglog("ttyp_reset: resetting %s, killing %d\n",
|
linet,ptys[npty]);
|
linet,ptys[npty]);
|
if (chown(linet,0,0) == -1) {
|
if (chown(linet,0,0) == -1) {
|
debuglog("ttyp_reset: chown %s errno=%d\n",linet,errno);
|
debuglog("ttyp_reset: chown %s errno=%d\n",linet,errno);
|
}
|
}
|
if (chmod(linet, 0666) == -1) {
|
if (chmod(linet, 0666) == -1) {
|
debuglog("ttyp_reset: chmod %s errno=%d\n",linet,errno);
|
debuglog("ttyp_reset: chmod %s errno=%d\n",linet,errno);
|
}
|
}
|
resetptyutmp();
|
resetptyutmp();
|
if (kill(ptys[npty],SIGKILL) == -1) {
|
if (kill(ptys[npty],SIGKILL) == -1) {
|
debuglog("ttyp_reset: kill pid=%d errno=%d\n",
|
debuglog("ttyp_reset: kill pid=%d errno=%d\n",
|
ptys[npty],errno);
|
ptys[npty],errno);
|
}
|
}
|
}
|
}
|
if (seteuid(realuid) == -1) { /* Back to who we really are */
|
if (seteuid(realuid) == -1) { /* Back to who we really are */
|
debuglog("ttyp_reset: seteuid user errno=%d\n",errno);
|
debuglog("ttyp_reset: seteuid user errno=%d\n",errno);
|
}
|
}
|
}
|
}
|
|
|
void
|
void
|
exp_pty_exit()
|
exp_pty_exit()
|
{
|
{
|
ttyp_reset();
|
ttyp_reset();
|
}
|
}
|
|
|
resetptyutmp()
|
resetptyutmp()
|
{
|
{
|
struct utmp utmp;
|
struct utmp utmp;
|
|
|
(void) setutent ();
|
(void) setutent ();
|
/* set up entry to search for */
|
/* set up entry to search for */
|
(void) strncpy(utmp.ut_id, linet + strlen(linet) - 4,
|
(void) strncpy(utmp.ut_id, linet + strlen(linet) - 4,
|
sizeof (utmp.ut_id));
|
sizeof (utmp.ut_id));
|
utmp.ut_type = USER_PROCESS;
|
utmp.ut_type = USER_PROCESS;
|
|
|
/* position to entry in utmp file */
|
/* position to entry in utmp file */
|
if(getutid(&utmp) == NULL) {
|
if(getutid(&utmp) == NULL) {
|
debuglog("resetptyutmp: no utmp entry for %s\n",linet);
|
debuglog("resetptyutmp: no utmp entry for %s\n",linet);
|
return(-1); /* no utmp entry for this line ??? */
|
return(-1); /* no utmp entry for this line ??? */
|
}
|
}
|
|
|
/* set up the new entry */
|
/* set up the new entry */
|
strncpy(utmp.ut_name,"",sizeof(utmp.ut_name));
|
strncpy(utmp.ut_name,"",sizeof(utmp.ut_name));
|
strncpy(utmp.ut_host,"",sizeof(utmp.ut_host));
|
strncpy(utmp.ut_host,"",sizeof(utmp.ut_host));
|
time(&utmp.ut_time);
|
time(&utmp.ut_time);
|
utmp.ut_type = DEAD_PROCESS;
|
utmp.ut_type = DEAD_PROCESS;
|
utmp.ut_exit.e_exit = 0;
|
utmp.ut_exit.e_exit = 0;
|
|
|
/* write out the entry */
|
/* write out the entry */
|
pututline(&utmp);
|
pututline(&utmp);
|
|
|
/* close the file */
|
/* close the file */
|
(void) endutent();
|
(void) endutent();
|
return(0);
|
return(0);
|
}
|
}
|
|
|