+Wed Jan 17 15:14:33 1996 Sam Hartman <hartmans@tertius.mit.edu>
+
+ * krlogin.c ((reader): Use select to find out-of-band data, not signals.
+ (oob): No longer a signal handler; just a function.
+ (writer): get rid of copytochild setup as sigurg no longer needed
+ (main): Don't block SIGURG
+ * configure.in : Include sys/time.h check
+
+Mon Jan 15 16:16:07 1996 Sam Hartman <hartmans@tertius.mit.edu>
+
+ * login.c (main): ttyslot usable here as well
+
+ * krlogind.c (doit): update_utmp can use ttyslot.
+
Thu Jan 11 12:40:08 1996 Ezra Peisach (epeisach@paris)
* krsh.c, krlogin.c: (main): Ultrix cc does not support automatic
AC_FUNC_CHECK(openpty,AC_DEFINE(HAVE_OPENPTY))
AC_FUNC_CHECK(setlogin,AC_DEFINE(HAVE_SETLOGIN))
AC_FUNC_CHECK(logwtmp,AC_DEFINE(HAVE_LOGWTMP))
-AC_CHECK_HEADERS(unistd.h stdlib.h string.h sys/filio.h sys/sockio.h)
-AC_CHECK_HEADERS(sys/label.h sys/tty.h ttyent.h lastlog.h sys/select.h)
-AC_CHECK_HEADERS(sys/ptyvar.h utmp.h utmpx.h stdarg.h)
+AC_CHECK_HEADERS(unistd.h stdlib.h string.h sys/filio.h sys/sockio.h )
+AC_CHECK_HEADERS(sys/label.h sys/tty.h ttyent.h lastlog.h sys/select.h )
+AC_CHECK_HEADERS(sys/ptyvar.h utmp.h utmpx.h stdarg.h sys/time.h)
AC_REPLACE_FUNCS(getdtablesize)
DECLARE_SYS_ERRLIST
KRB5_SIGTYPE
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+#if HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
#ifdef POSIX_TERMIOS
#include <termios.h>
char *host=0; /* external, so it can be
reached from confirm_death() */
-krb5_sigtype sigwinch KRB5_PROTOTYPE((int)), oob KRB5_PROTOTYPE((int));
+krb5_sigtype sigwinch KRB5_PROTOTYPE((int));
+void oob KRB5_PROTOTYPE((void));
krb5_sigtype lostpeer KRB5_PROTOTYPE((int));
#if __STDC__
int setsignal(int sig, krb5_sigtype (*act)());
(void) sigaction(SIGPIPE, &sa, (struct sigaction *)0);
(void) sigemptyset(&urgmask);
- (void) sigaddset(&urgmask, SIGURG);
(void) sigaddset(&urgmask, SIGUSR1);
oldmask = &omask;
(void) sigprocmask(SIG_BLOCK, &urgmask, oldmask);
#else
(void) signal(SIGPIPE, lostpeer);
#ifdef sgi
- oldmask = sigignore(sigmask(SIGURG) | sigmask(SIGUSR1));
+ oldmask = sigignore( sigmask(SIGUSR1));
#else
- oldmask = sigblock(sigmask(SIGURG) | sigmask(SIGUSR1));
+ oldmask = sigblock( sigmask(SIGUSR1));
#endif
#endif /* POSIX_SIGNALS */
if (rem < 0)
exit(1);
- /* we need to do the SETOWN here so that we get the SIGURG
- registered if the URG data come in early, before the reader() gets
- to do this for real (otherwise, the signal is never generated
- by the kernel). We block it above, so when it gets unblocked
- it will get processed by the reader().
- There is a possibility that the signal will get delivered to both
- writer and reader, but that is harmless, since the writer reflects
- it to the reader, and the oob() processing code in the reader will
- work properly even if it is called when no oob() data is present.
- */
-#ifdef hpux
- /* hpux invention */
- {
- int pid = getpid();
- ioctl(rem, FIOSSAIOSTAT, &pid); /* trick: pid is non-zero */
- ioctl(rem, FIOSSAIOOWN, &pid);
- }
-#else
-#ifdef HAVE_SETOWN
- (void) fcntl(rem, F_SETOWN, getpid());
-#endif
-#endif
if (options & SO_DEBUG &&
setsockopt(rem, SOL_SOCKET, SO_DEBUG, (char*)&on, sizeof (on)) < 0)
perror("rlogin: setsockopt (SO_DEBUG)");
int child;
krb5_sigtype catchild KRB5_PROTOTYPE((int));
-krb5_sigtype copytochild KRB5_PROTOTYPE((int)),
- writeroob KRB5_PROTOTYPE((int));
+krb5_sigtype writeroob KRB5_PROTOTYPE((int));
int defflags, tabflag;
int deflflags;
exit(3);
}
- /*
- * We may still own the socket, and may have a pending SIGURG
- * (or might receive one soon) that we really want to send to
- * the reader. Set a trap that simply copies such signals to
- * the child.
- */
#ifdef POSIX_SIGNALS
/* "sa" has already been initialized above. */
- sa.sa_handler = copytochild;
- (void) sigaction(SIGURG, &sa, (struct sigaction *)0);
sa.sa_handler = writeroob;
(void) sigaction(SIGUSR1, &sa, (struct sigaction *)0);
sa.sa_handler = catchild;
(void) sigaction(SIGCHLD, &sa, (struct sigaction *)0);
#else
- (void) signal(SIGURG, copytochild);
(void) signal(SIGUSR1, writeroob);
#ifndef sgi
(void) sigsetmask(oldmask);
-/*
- * Copy SIGURGs to the child process.
- */
-krb5_sigtype
- copytochild(signo)
-int signo;
-{
- (void) kill(child, SIGURG);
-}
int rcvstate;
int ppid;
-#ifdef POSIX_SETJMP
-sigjmp_buf rcvtop;
-#else
-jmp_buf rcvtop;
-#endif
-krb5_sigtype
- oob(signo)
-int signo;
+void oob()
{
#ifndef POSIX_TERMIOS
int out = FWRITE;
struct sgttyb sb;
#endif
#endif
+ mark = 0;
- while (recv(rem, &mark, 1, MSG_OOB) < 0)
- switch (errno) {
-
- case EWOULDBLOCK:
- /*
- * Urgent data not here yet.
- * It may not be possible to send it yet
- * if we are blocked for output
- * and our input buffer is full.
- */
- if (rcvcnt < sizeof(rcvbuf)) {
- n = read(rem, rcvbuf + rcvcnt,
- sizeof(rcvbuf) - rcvcnt);
- if (n <= 0)
- return;
- rcvd += n;
- } else {
- n = read(rem, waste, sizeof(waste));
- if (n <= 0)
- return;
- }
- continue;
-
- default:
- return;
- }
+ recv(rem, &mark, 1, MSG_OOB);
if (mark & TIOCPKT_WINDOW) {
/*
* Let server know about window size changes
n = read(rem, waste, sizeof (waste));
if (n <= 0)
break;
+return;
}
- /*
- * Don't want any pending data to be output,
- * so clear the recv buffer.
- * If we were hanging on a write when interrupted,
- * don't want it to restart. If we were reading,
- * restart anyway.
- */
- rcvcnt = 0;
-#ifdef POSIX_SETJMP
- siglongjmp(rcvtop, 1);
-#else
- longjmp(rcvtop, 1);
-#endif
}
- /*
- * oob does not do FLUSHREAD (alas!)
- */
- /*
- * If we filled the receive buffer while a read was pending,
- * longjmp to the top to restart appropriately. Don't abort
- * a pending write, however, or we won't know how much was written.
- */
-#ifdef POSIX_SETJMP
- if (rcvd && rcvstate == READING)
- siglongjmp(rcvtop, 1);
-#else
- if (rcvd && rcvstate == READING)
- longjmp(rcvtop, 1);
-#endif
}
#else
int pid = -getpid();
#endif
+fd_set readset, excset;
int n, remaining;
char *bufp = rcvbuf;
sa.sa_handler = SIG_IGN;
(void) sigaction(SIGTTOU, &sa, (struct sigaction *)0);
-#ifdef SA_RESTART
- /* Because SIGURG will be coming in during a read,
- * we want to restart the syscall afterwards. */
- sa.sa_flags |= SA_RESTART;
-#endif
- sa.sa_handler = oob;
- (void) sigaction(SIGURG, &sa, (struct sigaction *)0);
#else
(void) signal(SIGTTOU, SIG_IGN);
- (void) signal(SIGURG, oob);
#endif
ppid = getppid();
-#ifdef HAVE_SETOWN
- (void) fcntl(rem, F_SETOWN, pid);
-#endif
-#ifdef POSIX_SETJMP
- (void) sigsetjmp(rcvtop, 1);
-#else
- (void) setjmp(rcvtop);
-#endif
+FD_ZERO(&readset);
+ FD_ZERO(&excset);
#ifdef POSIX_SIGNALS
sigprocmask(SIG_SETMASK, oldmask, (sigset_t*)0);
#else
(void) sigsetmask(oldmask);
#endif
#endif /* POSIX_SIGNALS */
+
for (;;) {
while ((remaining = rcvcnt - (bufp - rcvbuf)) > 0) {
rcvstate = WRITING;
}
bufp = rcvbuf;
rcvcnt = 0;
- rcvstate = READING;
- rcvcnt = des_read(rem, rcvbuf, sizeof (rcvbuf));
+ rcvstate = READING;
+FD_SET(rem,&readset);
+ FD_SET(rem,&excset);
+ if (select(rem+1, &readset, 0, &excset, 0) > 0 ) {
+if (FD_ISSET(rem, &excset))
+ oob();
+if (FD_ISSET(rem, &readset)) {
+ rcvcnt = des_read(rem, rcvbuf, sizeof (rcvbuf));
if (rcvcnt == 0)
return (0);
- if (rcvcnt < 0) {
+ if (rcvcnt < 0)
+ goto error;
+}
+ } else
+ error: {
if (errno == EINTR)
continue;
perror("read");
#ifndef NO_UT_PID
{
- pty_update_utmp(PTY_LOGIN_PROCESS, getpid(), "rlogin", line, ""/*host*/);
+ pty_update_utmp(PTY_LOGIN_PROCESS, getpid(), "rlogin", line,
+ ""/*host*/, PTY_TTYSLOT_USABLE);
}
#endif
struct utmp utmp;
login_time = time(&utmp.ut_time);
- if ( (retval = pty_update_utmp(PTY_USER_PROCESS, getpid(), username, ttyn, hostname)) < 0 )
+ if ( (retval = pty_update_utmp(PTY_USER_PROCESS, getpid(), username, ttyn, hostname, PTY_TTYSLOT_USABLE)) < 0 )
com_err (argv[0], retval, "while updating utmp");
}
+Mon Jan 15 17:35:25 1996 Sam Hartman <hartmans@tertius.mit.edu>
+
+ * sys_term.c: Call pty_update_utmp with PTY_TTYSLOT_USABLE flag.
+
Mon Nov 27 15:55:50 1995 Tom Yu <tlyu@dragons-lair.MIT.EDU>
* state.c: use P properly so it won't break non-ansi compilers.
} else {
- pty_update_utmp (PTY_LOGIN_PROCESS, getpid(), "LOGIN", line, host);
+ pty_update_utmp (PTY_LOGIN_PROCESS, getpid(), "LOGIN", line,
+ host, PTY_TTYSLOT_USABLE);
getptyslave(autologin);
/* Notify our parent we're ready to continue.*/
kadm_deplib=''
kadm_lib=''
+kutil_deplib=''
+kutil_lib=''
+
kdb5_deplib=''
kdb5_lib=''
.cvsignore
ChangeLog
+README
Makefile.in
configure.in
cleanup.c
+Tue Jan 16 13:52:22 1996 Sam Hartman <hartmans@tertius.mit.edu>
+
+ * void_assoc.c (ptyint_void_association): Move setsid call from open_ctty to void_association.
+
+ * logwtmp.c (pty_logwtmp): Pass user argument to update_wtmp.
+
+ * update_utmp.c (update_utmp): Implement PTY_UTMP_USERNAME_VALID flag
+
+Mon Jan 15 15:48:37 1996 Sam Hartman (hartmans@justforfun)
+
+ * cleanup.c: Change to indiciate utmp user name is valid.
+
+ *
+
+Mon Jan 15 15:21:16 1996 Sam Hartman <hartmans@tertius.mit.edu>
+
+ * update_utmp.c (pty_update_utmp): Add flags field; use ttyslot
+ only if reasonable.
+
Fri Jan 12 16:33:37 1996 Sam Hartman <hartmans@infocalypse>
* open_slave.c (pty_open_slave): Don't use fchmod or fchown; they
{
int retval, fd;
- pty_update_utmp(PTY_DEAD_PROCESS,0, "", slave, (char *)0);
+ pty_update_utmp(PTY_DEAD_PROCESS,0, "", slave, (char *)0, PTY_UTMP_USERNAME_VALID);
(void)chmod(slave, 0666);
(void)chown(slave, 0, 0);
#define PTY_USER_PROCESS 1
#define PTY_DEAD_PROCESS 2
+/* flags to update_utmp*/
+#define PTY_TTYSLOT_USABLE (0x1)
+#define PTY_UTMP_USERNAME_VALID (0x2)
#ifdef __STDC__ /* use prototypes */
long pty_init(void);
long pty_open_ctty (const char *slave, int *fd);
long pty_initialize_slave ( int fd);
-long pty_update_utmp (int process_type,int pid, char *user, char *line, char *host);
+long pty_update_utmp (int process_type,int pid, char *user, char *line, char *host, int flags);
long pty_logwtmp (char *tty, char * user, char *host);
int *fd;
{
int testfd, retval;
-#ifdef HAVE_SETSID
- (void) setsid();
-#endif
/* First, dissociate from previous terminal */
if ( (retval = ptyint_void_association()) != 0 )
#ifndef UTMP_FILE
#define UTMP_FILE "/etc/utmp"
#endif
-
-long pty_update_utmp (process_type, pid, username, line, host)
+#ifndef NO_UT_PID
+#define WTMP_REQUIRES_USERNAME
+#endif
+long pty_update_utmp (process_type, pid, username, line, host, flags)
int process_type;
int pid;
char *username, *line, *host;
+ int flags;
{
- struct utmp ent;
-#ifdef HAVE_SETUTENT
- struct utmp ut;
-#else
+ struct utmp ent, ut;
+#ifndef HAVE_SETUTENT
struct stat statb;
int tty;
#endif
char *tmpx;
char utmp_id[5];
#endif
+ char userbuf[32];
int fd;
strncpy(ent.ut_line, line+sizeof("/dev/")-1, sizeof(ent.ut_line));
#else
strncpy(ent.ut_name, username, sizeof(ent.ut_name));
#endif
-
+ if(username[0])
+ strncpy(userbuf, username, sizeof(userbuf));
+ else userbuf[0] = '\0';
+
#ifdef HAVE_SETUTENT
utmpname(UTMP_FILE);
setutent();
- pututline(&ent);
- endutent();
-
-#if 0
- /* XXX -- NOT NEEDED ANYMORE */
-
- if (ent.ut_type == DEAD_PROCESS) {
- if ((fd = open(UTMP_FILE, O_RDWR)) >= 0) {
- int cnt = 0;
- while(read(fd, (char *)&ut, sizeof(ut)) == sizeof(ut)) {
- if (!strncmp(ut.ut_id, ent.ut_id, sizeof(ut.ut_id))) {
- (void) memset(ut.ut_host, 0, sizeof(ut.ut_host));
- (void) memset(ut.ut_user, 0, sizeof(ut.ut_user));
- (void) time(&ut.ut_time);
- ut.ut_exit.e_exit = ut.ut_pid = 0;
- ut.ut_type = EMPTY;
- (void) lseek(fd, -sizeof(ut), SEEK_CUR);
- (void) write(fd, &ut, sizeof(ut));
- }
- cnt++;
- }
- close(fd);
+/* If we need to preserve the user name in the wtmp structure and
+ * Our flags tell us we can obtain it from the utmp and we succeed in
+ * obtaining it, we then save the utmp structure we obtain, write
+ * out the utmp structure and change the username pointer so it is used by
+ * update_wtmp.*/
+#ifdef WTMP_REQUIRES_USERNAME
+ if (( !username[0]) && (flags&PTY_UTMP_USERNAME_VALID)
+ &&line)
+ {
+struct utmp *utptr;
+strncpy(ut.ut_line, line, sizeof(ut.ut_line));
+utptr = getutline(&ut);
+if (utptr)
+ strncpy(userbuf,utptr->ut_user,sizeof(ut.ut_user));
}
- }
#endif
+ pututline(&ent);
+ endutent();
+
#ifdef HAVE_SETUTXENT
setutxent();
getutmpx(&ent, &utx);
#endif /* HAVE_SETUTXENT */
#else /* HAVE_SETUTENT */
-
- tty = ttyslot();
- if (tty > 0 && (fd = open(UTMP_FILE, O_WRONLY, 0)) >= 0) {
+ if (flags&PTY_TTYSLOT_USABLE)
+ tty = ttyslot();
+ else {
+ int lc;
+ tty = -1;
+ if ((fd = open(UTMP_FILE, O_RDWR)) < 0)
+ return errno;
+ for (lc = 0;
+ lseek(fd, (off_t)(lc * sizeof(struct utmp)), SEEK_SET) != -1;
+ lc++) {
+ if (read(fd, (char *) &ut, sizeof(struct utmp)) != sizeof(struct utmp))
+ break;
+ if (strncmp(ut.ut_line, ent.ut_line, sizeof(ut.ut_line)) == 0) {
+ tty = lc;
+#ifdef WTMP_REQUIRES_USERNAME
+ if (!username&&(flags&PTY_UTMP_USERNAME_VALID))
+ strncpy(userbuf, ut.ut_user, sizeof(ut.ut_user));
+#endif
+ break;
+ }
+ }
+close(fd);
+ }
+
+ if (tty > 0 && (fd = open(UTMP_FILE, O_WRONLY, 0)) >= 0) {
(void)lseek(fd, (off_t)(tty * sizeof(struct utmp)), SEEK_SET);
(void)write(fd, (char *)&ent, sizeof(struct utmp));
(void)close(fd);
}
+
#endif /* HAVE_SETUTENT */
- return ptyint_update_wtmp(&ent, host, username);
+ return ptyint_update_wtmp(&ent, host, userbuf);
}
long ptyint_void_association()
{
int con_fd;
+#ifdef HAVE_SETSID
+ (void) setsid();
+#endif
+
/* Void tty association first */
if ((con_fd = open("/dev/tty", O_RDWR)) >= 0) {
ioctl(con_fd, TIOCNOTTY, 0);