--- main.c.orig	Fri May 31 22:15:05 2013
+++ main.c	Fri May 31 22:25:10 2013
@@ -142,9 +142,16 @@ static Bool IsPts = False;
 #define WTMP
 #endif
 
+#ifdef CSRG_BASED
+#define USE_POSIX_TERMIOS
+#endif
+
 #include <sys/ioctl.h>
 #include <sys/stat.h>
 
+#ifdef USE_POSIX_TERMIOS
+#include <termios.h>
+#else
 #ifdef USE_TERMIOS
 #include <termios.h>
 /* this hacked termios support only works on SYSV */
@@ -159,10 +166,12 @@ static Bool IsPts = False;
 #include <sys/termio.h>
 #endif /* SYSV */
 #endif /* USE_TERMIOS else */
+#endif /* USE_POSIX_TERMIOS */
 
 #ifdef SVR4
 #undef TIOCSLTC				/* defined, but not useable */
 #endif
+#define USE_TERMCAP_ENVVARS	/* every one uses this except SYSV maybe */
 
 #if defined(__sgi) && OSMAJORVERSION >= 5
 #undef TIOCLSET				/* defined, but not useable */
@@ -225,7 +234,9 @@ static Bool IsPts = False;
 #endif
 #else /* } !SYSV { */			/* BSD systems */
 #ifndef linux
+#ifndef USE_POSIX_TERMIOS
 #include <sgtty.h>
+#endif /* USE_POSIX_TERMIOS */
 #endif
 #include <sys/resource.h>
 #define HAS_UTMP_UT_HOST
@@ -251,6 +262,8 @@ static Bool IsPts = False;
 
 #if (BSD >= 199103)
 #define USE_POSIX_WAIT
+#define LASTLOG
+#define WTMP
 #define HAS_POSIX_SAVED_IDS
 #endif
 
@@ -301,6 +314,10 @@ extern struct utmp *getutid __((struct utmp *_Id));
 int	Ptyfd;
 #endif /* PUCC_PTYD */
 
+#ifdef __OpenBSD__
+#include <util.h>
+#endif
+
 #ifdef sequent
 #define USE_GET_PSEUDOTTY
 #endif
@@ -407,6 +424,10 @@ static Bool added_utmp_entry = False;
 
 static Bool xterm_exiting = False;
 
+#ifdef __OpenBSD__
+static gid_t utmpGid = -1;
+#endif
+
 /*
 ** Ordinarily it should be okay to omit the assignment in the following
 ** statement. Apparently the c89 compiler on AIX 4.1.3 has a bug, or does
@@ -434,6 +455,9 @@ static struct ltchars d_ltc;
 static unsigned int d_lmode;
 #endif	/* TIOCLSET */
 #else /* not USE_SYSV_TERMIO */
+#ifdef USE_POSIX_TERMIOS
+static struct termios d_tio;
+#else /* not USE_POSIX_TERMIOS */
 static struct  sgttyb d_sg = {
         0, 0, 0177, CKILL, EVENP|ODDP|ECHO|XTABS|CRMOD
 };
@@ -457,6 +481,7 @@ static struct jtchars d_jtc = {
 	'J', 'B'
 };
 #endif /* sony */
+#endif /* USE_POSIX_TERMIOS */
 #endif /* USE_SYSV_TERMIO */
 
 /* allow use of system default characters if defined and reasonable */
@@ -1107,21 +1132,19 @@ char **argv;
 	char *base_name();
 	int xerror(), xioerror();
 
-	XtSetLanguageProc (NULL, NULL, NULL);
-
 	ProgramName = argv[0];
 
 	/* +2 in case longer tty name like /dev/ttyq255 */
-	ttydev = (char *) malloc (sizeof(TTYDEV) + 2);
+	ttydev = (char *) malloc (sizeof(TTYDEV) + 80);
 #ifndef __osf__
-	ptydev = (char *) malloc (sizeof(PTYDEV) + 2);
+	ptydev = (char *) malloc (sizeof(PTYDEV) + 80);
 	if (!ttydev || !ptydev)
 #else
 	if (!ttydev)
 #endif
 	{
 	    fprintf (stderr, 
-	    	     "%s:  unable to allocate memory for ttydev or ptydev\n",
+	    	     "%s: unable to allocate memory for ttydev or ptydev\n",
 		     ProgramName);
 	    exit (1);
 	}
@@ -1130,14 +1153,20 @@ char **argv;
 	strcpy (ptydev, PTYDEV);
 #endif
 
-#ifdef USE_SYSV_TERMIO /* { */
+	XtSetLanguageProc (NULL, NULL, NULL);
+
+#if defined(USE_SYSV_TERMIO) || defined(USE_POSIX_TERMIOS) /* { */
 	/* Initialization is done here rather than above in order
 	** to prevent any assumptions about the order of the contents
 	** of the various terminal structures (which may change from
 	** implementation to implementation).
 	*/
 	d_tio.c_iflag = ICRNL|IXON;
+#ifdef TAB3
 	d_tio.c_oflag = OPOST|ONLCR|TAB3;
+#else
+	d_tio.c_oflag = OPOST|ONLCR;
+#endif
 #if defined(macII) || defined(ATT) || defined(CRAY) /* { */
     	d_tio.c_cflag = B9600|CS8|CREAD|PARENB|HUPCL;
     	d_tio.c_lflag = ISIG|ICANON|ECHO|ECHOE|ECHOK;
@@ -1161,9 +1190,11 @@ char **argv;
 	d_tio.c_cc[VEOL2] = CNUL;
 	d_tio.c_cc[VSWTCH] = CNUL;
 
-#ifdef USE_TERMIOS /* { */
+#if defined(USE_TERMIOS) || defined(USE_POSIX_TERMIOS) /* { */
 	d_tio.c_cc[VSUSP] = CSUSP;
+#ifdef VDSUSP
 	d_tio.c_cc[VDSUSP] = CDSUSP;
+#endif
 	d_tio.c_cc[VREPRINT] = CRPRNT;
 	d_tio.c_cc[VDISCARD] = CFLUSH;
 	d_tio.c_cc[VWERASE] = CWERASE;
@@ -1181,11 +1212,17 @@ char **argv;
 	d_lmode = 0;
 #endif /* } TIOCLSET */
 #else  /* }{ else !macII, ATT, CRAY */
+#ifndef USE_POSIX_TERMIOS
 #ifdef BAUD_0 /* { */
     	d_tio.c_cflag = CS8|CREAD|PARENB|HUPCL;
 #else	/* }{ !BAUD_0 */
     	d_tio.c_cflag = B9600|CS8|CREAD|PARENB|HUPCL;
 #endif	/* } !BAUD_0 */
+#else /* USE_POSIX_TERMIOS */
+	d_tio.c_cflag = CS8|CREAD|PARENB|HUPCL;
+	cfsetispeed(&d_tio, B9600);
+	cfsetospeed(&d_tio, B9600);
+#endif
     	d_tio.c_lflag = ISIG|ICANON|ECHO|ECHOE|ECHOK;
 #ifdef ECHOKE
 	d_tio.c_lflag |= ECHOKE|IEXTEN;
@@ -1193,11 +1230,13 @@ char **argv;
 #ifdef ECHOCTL
 	d_tio.c_lflag |= ECHOCTL|IEXTEN;
 #endif
+#ifndef USE_POSIX_TERMIOS
 #ifdef NTTYDISC
         d_tio.c_line = NTTYDISC;
 #else
 	d_tio.c_line = 0;
 #endif	
+#endif /* USE_POSIX_TERMIOS */
 #ifdef __sgi
         d_tio.c_cflag &= ~(HUPCL|PARENB);
         d_tio.c_iflag |= BRKINT|ISTRIP|IGNPAR;
@@ -1246,8 +1285,14 @@ char **argv;
 	    int i;
 
 	    for (i = 0; i <= 2; i++) {
+#ifndef USE_POSIX_TERMIOS
 		struct termio deftio;
-		if (ioctl (i, TCGETA, &deftio) == 0) {
+		if (ioctl (i, TCGETA, &deftio) == 0)
+#else
+		struct termios deftio;
+		if (tcgetattr(i, &deftio) == 0)
+#endif
+		{
 		    d_tio.c_cc[VINTR] = deftio.c_cc[VINTR];
 		    d_tio.c_cc[VQUIT] = deftio.c_cc[VQUIT];
 		    d_tio.c_cc[VERASE] = deftio.c_cc[VERASE];
@@ -1302,9 +1347,11 @@ char **argv;
         d_ltc.t_werasc = '\377';
         d_ltc.t_lnextc = '\377';
 #endif	/* } TIOCSLTC */
-#ifdef USE_TERMIOS /* { */
+#if defined(USE_TERMIOS) || defined(USE_POSIX_TERMIOS) /* { */
 	d_tio.c_cc[VSUSP] = CSUSP;
+#ifdef VDSUSP
 	d_tio.c_cc[VDSUSP] = '\000';
+#endif
 	d_tio.c_cc[VREPRINT] = '\377';
 	d_tio.c_cc[VDISCARD] = '\377';
 	d_tio.c_cc[VWERASE] = '\377';
@@ -1361,7 +1408,15 @@ char **argv;
 		(void) fprintf(stderr, "setegid(%d): %s\n",
 			       (int) egid, strerror(errno));
 #endif
+
+#ifdef __OpenBSD__
+	if (resource.utmpInhibit) {
+		/* Can totally revoke group privs */
+		setegid(getgid());
+		setgid(getgid());
 	}
+#endif
+	}
 
 	waiting_for_initial_map = resource.wait_for_map;
 
@@ -1719,7 +1774,7 @@ char *name;
 get_pty (pty)
     int *pty;
 {
-#ifdef __osf__
+#if defined(__osf__) || defined(__OpenBSD__)
     int tty;
     return (openpty(pty, &tty, ttydev, NULL, NULL));
 #endif
@@ -2065,6 +2120,9 @@ spawn ()
 	int zero = 0;
 	int status;
 #else	/* else not USE_SYSV_TERMIO */
+#ifdef USE_POSIX_TERMIOS
+	struct termios tio;
+#else /* else not USE_POSIX_TERMIOS */
 	unsigned lmode;
 	struct tchars tc;
 	struct ltchars ltc;
@@ -2073,6 +2131,7 @@ spawn ()
 	int jmode;
 	struct jtchars jtc;
 #endif /* sony */
+#endif  /* USE_POSIX_TERMIOS */
 #endif	/* USE_SYSV_TERMIO */
 
 	char termcap [1024];
@@ -2168,9 +2227,9 @@ spawn ()
 #ifdef TIOCLSET
 				lmode = d_lmode;
 #endif	/* TIOCLSET */
-#ifdef USE_SYSV_TERMIO
+#if defined(USE_SYSV_TERMIO) || defined(USE_POSIX_TERMIOS)
 				tio = d_tio;
-#else	/* not USE_SYSV_TERMIO */
+#else	/* not USE_SYSV_TERMIO and not USE_POSIX_TERMIOS */
 				sg = d_sg;
 				tc = d_tc;
 				discipline = d_disipline;
@@ -2178,7 +2237,7 @@ spawn ()
 				jmode = d_jmode;
 				jtc = d_jtc;
 #endif /* sony */
-#endif	/* USE_SYSV_TERMIO */
+#endif	/* USE_SYSV_TERMIO or USE_POSIX_TERMIOS */
 			} else {
 			    SysError(ERROR_OPDEVTTY);
 			}
@@ -2202,6 +2261,10 @@ spawn ()
 			        tio = d_tio;
 
 #else	/* not USE_SYSV_TERMIO */
+#ifdef USE_POSIX_TERMIOS
+			if (tcgetattr(tty, &tio) == -1) 
+			        tio = d_tio;
+#else   /* not USE_POSIX_TERMIOS */
 			if(ioctl(tty, TIOCGETP, (char *)&sg) == -1)
 			        sg = d_sg;
 			if(ioctl(tty, TIOCGETC, (char *)&tc) == -1)
@@ -2214,6 +2277,7 @@ spawn ()
 			if(ioctl(tty, TIOCKGETC, (char *)&jtc) == -1)
 				jtc = d_jtc;
 #endif /* sony */
+#endif  /* USE_POSIX_TERMIOS */
 #endif	/* USE_SYSV_TERMIO */
 			close (tty);
 			/* tty is no longer an open fd! */
@@ -2507,6 +2571,7 @@ spawn ()
 				break;
 #endif	/* USE_SYSV_PGRP */
 			}
+			perror("open ttydev");
 
 #ifdef TIOCSCTTY
 			ioctl(tty, TIOCSCTTY, 0);
@@ -2581,7 +2646,7 @@ spawn ()
 		 * set up the tty modes
 		 */
 		{
-#ifdef USE_SYSV_TERMIO
+#if defined(USE_SYSV_TERMIO) || defined(USE_POSIX_TERMIOS)
 #if defined(umips) || defined(CRAY) || defined(linux)
 		    /* If the control tty had its modes screwed around with,
 		       eg. by lineedit in the shell, or emacs, etc. then tio
@@ -2598,12 +2663,15 @@ spawn ()
 		    tio.c_iflag &= ~(INLCR|IGNCR);
 		    tio.c_iflag |= ICRNL;
 		    /* ouput: cr->cr, nl is not return, no delays, ln->cr/nl */
+#ifndef USE_POSIX_TERMIOS
 		    tio.c_oflag &=
 		     ~(OCRNL|ONLRET|NLDLY|CRDLY|TABDLY|BSDLY|VTDLY|FFDLY);
+#endif /* USE_POSIX_TERMIOS */
 		    tio.c_oflag |= ONLCR;
 #ifdef OPOST
 		    tio.c_oflag |= OPOST;
 #endif /* OPOST */		    
+#ifndef USE_POSIX_TERMIOS
 #ifdef BAUD_0
 		    /* baud rate is 0 (don't care) */
 		    tio.c_cflag &= ~(CBAUD);
@@ -2612,6 +2680,13 @@ spawn ()
 		    tio.c_cflag &= ~(CBAUD);
 		    tio.c_cflag |= B9600;
 #endif	/* !BAUD_0 */
+#else /* USE_POSIX_TERMIOS */
+		    cfsetispeed(&tio, B9600);
+		    cfsetospeed(&tio, B9600);
+		    /* Clear CLOCAL so that SIGHUP is sent to us 
+		       when the xterm ends */
+		    tio.c_cflag &= ~CLOCAL;
+#endif /* USE_POSIX_TERMIOS */
 		    tio.c_cflag &= ~CSIZE;
 		    if (screen->input_eight_bits)
 			tio.c_cflag |= CS8;
@@ -2723,9 +2798,14 @@ spawn ()
 		    if (ioctl (tty, TIOCLSET, (char *)&lmode) == -1)
 			    HsSysError(cp_pipe[1], ERROR_TIOCLSET);
 #endif	/* TIOCLSET */
+#ifndef USE_POSIX_TERMIOS
 		    if (ioctl (tty, TCSETA, &tio) == -1)
 			    HsSysError(cp_pipe[1], ERROR_TIOCSETP);
-#else	/* USE_SYSV_TERMIO */
+#else   /* USE_POSIX_TERMIOS */
+		    if (tcsetattr (tty, TCSANOW, &tio) == -1)
+			    HsSysError(cp_pipe[1], ERROR_TIOCSETP);
+#endif  /* USE_POSIX_TERMIOS */
+#else	/* USE_SYSV_TERMIO or USE_POSIX_TERMIOS */
 #ifdef KTERM
 		    sg.sg_flags &= ~(ALLDELAY | XTABS | CBREAK | RAW
 						| EVENP | ODDP);
@@ -3100,6 +3180,14 @@ spawn ()
 				    close(i);
 				}
 #endif /* LASTLOG */
+
+#ifdef __OpenBSD__
+				/* Switch to real gid after writing utmp entry */
+				if (getgid() != getegid()) {
+					utmpGid = getegid();
+					setegid(getgid());
+				}
+#endif
 			} else
 				tslot = -tslot;
 		}
@@ -3272,11 +3360,11 @@ spawn ()
 		shname_minus = malloc(strlen(shname) + 2);
 		(void) strcpy(shname_minus, "-");
 		(void) strcat(shname_minus, shname);
-#ifndef USE_SYSV_TERMIO
+#if !defined(USE_SYSV_TERMIO) && !defined(USE_POSIX_TERMIOS)
 		ldisc = XStrCmp("csh", shname + strlen(shname) - 3) == 0 ?
 		 NTTYDISC : 0;
 		ioctl(0, TIOCSETD, (char *)&ldisc);
-#endif	/* !USE_SYSV_TERMIO */
+#endif	/* !USE_SYSV_TERMIO && !USE_POSIX_TERMIOS */
 
 #ifdef USE_LOGIN_DASH_P
 		if (term->misc.login_shell && pw && added_utmp_entry)
@@ -3459,6 +3547,12 @@ Exit(n)
 	    && added_utmp_entry
 #endif /* USE_HANDSHAKE */
 	    ) {
+#ifdef __OpenBSD__
+		if (utmpGid != -1) {
+			/* Switch back to group utmp */
+			setegid(utmpGid);
+		}
+#endif
 	    ptyname = ttydev;
 	    utmp.ut_type = USER_PROCESS;
 	    if (PTYCHARLEN >= (int)strlen(ptyname))
