File:  [Research Unix] / researchv9 / X11 / src / X.V11R1 / clients / xterm / main.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 17:40:10 2018 UTC (8 years, 1 month ago) by root
Branches: belllabs, MAIN
CVS tags: researchv9-SUN3, HEAD
researchv9-SUN3

/*
 *	$Source: /var/lib/cvsd/repos/research/researchv9/X11/src/X.V11R1/clients/xterm/main.c,v $
 *	$Header: /var/lib/cvsd/repos/research/researchv9/X11/src/X.V11R1/clients/xterm/main.c,v 1.1.1.2 2018/04/24 17:40:10 root Exp $
 */

#include <X11/copyright.h>

/*
 * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
 *
 *                         All Rights Reserved
 *
 * Permission to use, copy, modify, and distribute this software and its
 * documentation for any purpose and without fee is hereby granted,
 * provided that the above copyright notice appear in all copies and that
 * both that copyright notice and this permission notice appear in
 * supporting documentation, and that the name of Digital Equipment
 * Corporation not be used in advertising or publicity pertaining to
 * distribution of the software without specific, written prior permission.
 *
 *
 * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
 * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
 * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
 * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
 * SOFTWARE.
 */

/* main.c */

#ifndef lint
static char rcs_id[] = "$Header: /var/lib/cvsd/repos/research/researchv9/X11/src/X.V11R1/clients/xterm/main.c,v 1.1.1.2 2018/04/24 17:40:10 root Exp $";
#endif	lint

#include <pwd.h>
#include <sys/ioctl.h>
#include <sys/ttyld.h>
#include <wait.h>
#include <stdio.h>
#include <errno.h>
#include <signal.h>
#include <strings.h>
#include <setjmp.h>

#ifdef apollo
#include <sys/types.h>
#define ttyslot() 1
#define vhangup() ;
#endif

#include <utmp.h>
#include <sys/param.h>	/* for NOFILE */
#include <X11/Xlib.h>
#include <X11/Xtlib.h>
#include "ptyx.h"
#include "data.h"
#include "error.h"
#include "main.h"

extern Pixmap make_gray();
extern char *malloc();
extern char *calloc();
extern char *ttyname();
extern void exit();
extern void sleep();
extern void bcopy();
extern void vhangup();
extern long lseek();
extern int tty_ld, mesg_ld;

XrmNameList nameList;
XrmClassList classList;

int switchfb[] = {0, 2, 1, 3};

static int reapchild ();

static char **command_to_exec;
static struct  sgttyb d_sg = {
        0, 0, 0177, CKILL, EVENP|ODDP|ECHO|XTABS|CRMOD
};
static struct  tchars d_tc = {
        CINTR, CQUIT, CSTART,
        CSTOP, CEOT, 0377,
};
static char display[256];
static char etc_utmp[] = "/etc/utmp";
static char *get_ty;
static int inhibit;
static int log_on;
static int login_shell;
static char passedPty[2];	/* name if pty if slave */
static int loginpty;
#ifdef TIOCCONS
static int Console;
#endif TIOCCONS
static int tslot;
static jmp_buf env;

#define	XtNxterm		"xterm"
#define	XtNwindowName		"windowName"
#define	XtNboldFont		"boldFont"
#define	XtNc132			"c132"
#define XtNtitle		"title"
#define	XtNcurses		"curses"
#define	XtNcursor		"cursor"
#define	XtNcursorShape		"cursorShape"
#define	XtNgeometry		"geometry"
#define	XtNiconStartup		"iconStartup"
#define	XtNinternalBorder	"internalBorder"
#define	XtNjumpScroll		"jumpScroll"
#define	XtNlogFile		"logFile"
#define	XtNlogging		"logging"
#define	XtNlogInhibit		"logInhibit"
#define	XtNloginShell		"loginShell"
#define	XtNmarginBell		"marginBell"
#define	XtNmouse		"mouse"
#define	XtNmultiScroll		"multiScroll"
#define	XtNnMarginBell		"nMarginBell"
#define	XtNreverseWrap		"reverseWrap"
#define	XtNsaveLines		"saveLines"
#define	XtNscrollBar		"scrollBar"
#define	XtNscrollInput		"scrollInput"
#define	XtNscrollKey		"scrollKey"
#define	XtNsignalInhibit	"signalInhibit"
#define	XtNtekInhibit		"tekInhibit"
#define	XtNtekStartup		"tekStartup"
#define	XtNvisualBell		"visualBell"

#define	XtCApp			"App"
#define	XtCC132			"C132"
#define	XtCCurses		"Curses"
#define	XtCBitmapbits		"Bitmapbits"
#define	XtCGeometry		"Geometry"
#define	XtCIconstartup		"Iconstartup"
#define	XtCJumpscroll		"Jumpscroll"
#define	XtCLogfile		"Logfile"
#define	XtCLogging		"Logging"
#define	XtCLoginhibit		"Loginhibit"
#define	XtCLoginshell		"Loginshell"
#define	XtCMarginbell		"Marginbell"
#define	XtCMultiscroll		"Multiscroll"
#define	XtCColumn		"Column"
#define	XtCReverseVideo		"ReverseVideo"
#define	XtCReverseWrap		"ReverseWrap"
#define	XtCRows			"Rows"
#define	XtCScrollbar		"ScrollBar"
#define	XtCScrollcond		"Scrollcond"
#define	XtCSignalInibit		"SignalInibit"
#define	XtCTekInhibit		"TekInhibit"
#define	XtCTekStartup		"TekStartup"
#define	XtCVisualbell		"Visualbell"


/* Defaults */
static  Boolean	defaultFALSE	   = FALSE;
static  Boolean	defaultTRUE	   = TRUE;
static	char	*defaultNULL	   = NULL;
static	int	defaultBorderWidth = DEFBORDERWIDTH;
static	int	defaultIntBorder   = DEFBORDER;
static  int	defaultSaveLines   = SAVELINES;
static	int	defaultNMarginBell = N_MARGINBELL;
static  char	*defaultFont	   = DEFFONT;
static	char	*defaultBoldFont  = DEFBOLDFONT;

/* term.screen.flags things that don't map directly from option */
static Boolean reverseWrap;
static Boolean logInhibit;
static Boolean signalInhibit;
static Boolean tekInhibit;

/* term.screen.xxx things that don't map directly from option */
static Boolean scrollbar;


/*static*/ Resource resourceList[] = {
{XtNbackground,	XtCColor,	XrmRPixel,	sizeof(Pixel),
	(caddr_t) &term.screen.background,	(caddr_t) &XtDefaultBGPixel},
{XtNforeground,	XtCColor,	XrmRPixel,	sizeof(Pixel),
	(caddr_t) &term.screen.foreground,	(caddr_t) &XtDefaultFGPixel},
{XtNfont,	XtCFont,	XrmRString,	sizeof(char *),
	(caddr_t) &f_n,				(caddr_t) &defaultNULL},
{XtNboldFont,	XtCFont,	XrmRString,	sizeof(char *),
	(caddr_t) &f_b,				(caddr_t) &defaultNULL},
{XtNborder,	XtCColor,	XrmRPixel,	sizeof(Pixel),
	(caddr_t) &term.screen.bordercolor,	(caddr_t) &XtDefaultFGPixel},
{XtNborderWidth,XtCBorderWidth,	XrmRInt,		sizeof(int),
	(caddr_t) &term.screen.borderwidth,	(caddr_t)&defaultBorderWidth},
{XtNc132,	XtCC132,	XrmRBoolean,	sizeof(Boolean),
	(caddr_t) &term.screen.c132,		(caddr_t) &defaultFALSE},
{XtNcurses,	XtCCurses,	XrmRBoolean,	sizeof(Boolean),
	(caddr_t) &term.screen.curses,		(caddr_t) &defaultFALSE},
{XtNcursor,	XtCColor,	XrmRPixel,	sizeof(Pixel),
	(caddr_t) &term.screen.cursorcolor,	
	(caddr_t) &term.screen.foreground},
{XtNcursorShape,XtCCursor,	XrmRString,	sizeof(char *),
	(caddr_t) &curs_shape,			(caddr_t) &defaultNULL},
{XtNgeometry,XtCGeometry,	XrmRString,	sizeof(char *),
	(caddr_t) &geo_metry,			(caddr_t) &defaultNULL},
{XtNiconStartup,XtCIconstartup,	XrmRBoolean,	sizeof(Boolean),
	(caddr_t) &iconstartup,			(caddr_t) &defaultFALSE},
{XtNinternalBorder,XtCBorderWidth,XrmRInt,	sizeof(int),
	(caddr_t) &term.screen.border,		(caddr_t) &defaultIntBorder},
{XtNjumpScroll,	XtCJumpscroll,	XrmRBoolean,	sizeof(Boolean),
	(caddr_t) &term.screen.jumpscroll,	(caddr_t) &defaultTRUE},
{XtNlogFile,	XtCLogfile,	XrmRString,	sizeof(char *),
	(caddr_t) &term.screen.logfile,		(caddr_t) &defaultNULL},
{XtNlogging,	XtCLogging,	XrmRBoolean,	sizeof(Boolean),
	(caddr_t) &log_on,			(caddr_t) &defaultFALSE},
{XtNlogInhibit,	XtCLoginhibit,	XrmRBoolean,	sizeof(Boolean),
	(caddr_t) &logInhibit,			(caddr_t) &defaultFALSE},
{XtNloginShell,	XtCLoginshell,	XrmRBoolean,	sizeof(Boolean),
	(caddr_t) &login_shell,			(caddr_t) &defaultFALSE},
{XtNmarginBell,	XtCMarginbell,	XrmRBoolean,	sizeof(Boolean),
	(caddr_t) &term.screen.marginbell,	(caddr_t) &defaultFALSE},
{XtNmouse,	XtCColor,	XrmRPixel,	sizeof(Pixel),
/*	(caddr_t) &term.screen.mousecolor,	(caddr_t) &XtDefaultFGPixel},
*/
	(caddr_t) &term.screen.mousecolor,	
	(caddr_t) &term.screen.cursorcolor},
{XtNmultiScroll,XtCMultiscroll,	XrmRBoolean,	sizeof(Boolean),
	(caddr_t) &term.screen.multiscroll,	(caddr_t) &defaultFALSE},
{XtNnMarginBell,XtCColumn,	XrmRInt,	sizeof(int),
	(caddr_t) &term.screen.nmarginbell,	(caddr_t) &defaultNMarginBell},
{XtNreverseVideo,XtCReverseVideo,XrmRBoolean,	sizeof(Boolean),
	(caddr_t) &re_verse,			(caddr_t) &defaultFALSE},
{XtNreverseWrap,XtCReverseWrap,	XrmRBoolean,	sizeof(Boolean),
	(caddr_t) &reverseWrap,			(caddr_t) &defaultFALSE},
{XtNsaveLines,	XtCRows,	XrmRInt,	sizeof(int),
	(caddr_t) &save_lines,			(caddr_t) &defaultSaveLines},
{XtNscrollBar,	XtCScrollbar,	XrmRBoolean,	sizeof(Boolean),
	(caddr_t) &scrollbar,			(caddr_t) &defaultFALSE},
{XtNscrollInput,XtCScrollcond,	XrmRBoolean,	sizeof(Boolean),
	(caddr_t) &term.screen.scrollinput,	(caddr_t) &defaultTRUE},
{XtNscrollKey,	XtCScrollcond,	XrmRBoolean,	sizeof(Boolean),
	(caddr_t) &term.screen.scrollkey,	(caddr_t) &defaultFALSE},
{XtNsignalInhibit,XtCSignalInibit,XrmRBoolean,	sizeof(Boolean),
	(caddr_t) &signalInhibit,		(caddr_t) &defaultFALSE},
{XtNtekInhibit,	XtCTekInhibit,	XrmRBoolean,	sizeof(Boolean),
	(caddr_t) &tekInhibit,			(caddr_t) &defaultFALSE},
{XtNtekStartup,	XtCTekStartup,	XrmRBoolean,	sizeof(Boolean),
	(caddr_t) &term.screen.TekEmu,		(caddr_t) &defaultFALSE},
{XtNtitle,	XtCString,	XrmRString,	sizeof(char *),
	(caddr_t) &title_name,			(caddr_t) &defaultNULL},
{XtNvisualBell,XtCVisualbell,	XrmRBoolean,	sizeof(Boolean),
	(caddr_t) &term.screen.visualbell,	(caddr_t) &defaultFALSE},
{XtNwindowName,	XtCString,	XrmRString,	sizeof(char *),
	(caddr_t) &window_name,			(caddr_t) &defaultNULL},

};


/* Command line options table.  Only resources are entered here...there is a
   pass over the remaining options after XtParseCommand is let loose. */

static XrmOptionDescRec optionDescList[] = {
{"=",		XtNgeometry,	XrmoptionIsArg,		(caddr_t) NULL},
{"-132",	XtNc132,	XrmoptionNoArg,		(caddr_t) "on"},
{"+132",	XtNc132,	XrmoptionNoArg,		(caddr_t) "off"},
{"-T",		XtNtitle,	XrmoptionSepArg,	(caddr_t) NULL},
{"-b",		XtNinternalBorder,XrmoptionSepArg,	(caddr_t) NULL},
{"-bd",		XtNborder,	XrmoptionSepArg,	(caddr_t) NULL},
{"-bg",		XtNbackground,	XrmoptionSepArg,	(caddr_t) NULL},
{"-bw",		XtNborderWidth,	XrmoptionSepArg,	(caddr_t) NULL},
{"-cr",		XtNcursor,	XrmoptionSepArg,	(caddr_t) NULL},
{"-cu",		XtNcurses,	XrmoptionNoArg,		(caddr_t) "on"},
{"+cu",		XtNcurses,	XrmoptionNoArg,		(caddr_t) "off"},
{"-e",		NULL,		XrmoptionSkipLine,	(caddr_t) NULL},
{"-fb",		XtNboldFont,	XrmoptionSepArg,	(caddr_t) NULL},
{"-fg",		XtNforeground,	XrmoptionSepArg,	(caddr_t) NULL},
{"-fn",		XtNfont,	XrmoptionSepArg,	(caddr_t) NULL},
{"-i",		XtNiconStartup,	XrmoptionNoArg,		(caddr_t) "on"},
{"-j",		XtNjumpScroll,	XrmoptionNoArg,		(caddr_t) "on"},
{"+j",		XtNjumpScroll,	XrmoptionNoArg,		(caddr_t) "off"},
{"-l",		XtNlogging,	XrmoptionNoArg,		(caddr_t) "on"},
{"+l",		XtNlogging,	XrmoptionNoArg,		(caddr_t) "off"},
{"-lf",		XtNlogFile,	XrmoptionSepArg,	(caddr_t) NULL},
{"-ls",		XtNloginShell,	XrmoptionNoArg,		(caddr_t) "on"},
{"+ls",		XtNloginShell,	XrmoptionNoArg,		(caddr_t) "off"},
{"-mb",		XtNmarginBell,	XrmoptionNoArg,		(caddr_t) "on"},
{"+mb",		XtNmarginBell,	XrmoptionNoArg,		(caddr_t) "off"},
{"-ms",		XtNmouse,	XrmoptionSepArg,	(caddr_t) NULL},
{"-n",		XtNwindowName,	XrmoptionSepArg,	(caddr_t) NULL},
{"-nb",		XtNnMarginBell,	XrmoptionSepArg,	(caddr_t) NULL},
{"-r",		XtNreverseVideo,XrmoptionNoArg,		(caddr_t) "on"},
{"+r",		XtNreverseVideo,XrmoptionNoArg,		(caddr_t) "off"},
{"-rv",		XtNreverseVideo,XrmoptionNoArg,		(caddr_t) "on"},
{"+rv",		XtNreverseVideo,XrmoptionNoArg,		(caddr_t) "off"},
{"-rw",		XtNreverseWrap,	XrmoptionNoArg,		(caddr_t) "on"},
{"+rw",		XtNreverseWrap,	XrmoptionNoArg,		(caddr_t) "off"},
{"-s",		XtNmultiScroll,	XrmoptionNoArg,		(caddr_t) "on"},
{"+s",		XtNmultiScroll,	XrmoptionNoArg,		(caddr_t) "off"},
{"-sb",		XtNscrollBar,	XrmoptionNoArg,		(caddr_t) "on"},
{"+sb",		XtNscrollBar,	XrmoptionNoArg,		(caddr_t) "off"},
{"-si",		XtNscrollInput,	XrmoptionNoArg,		(caddr_t) "off"},
{"+si",		XtNscrollInput,	XrmoptionNoArg,		(caddr_t) "on"},
{"-sk",		XtNscrollKey,	XrmoptionNoArg,		(caddr_t) "on"},
{"+sk",		XtNscrollKey,	XrmoptionNoArg,		(caddr_t) "off"},
{"-sl",		XtNsaveLines,	XrmoptionSepArg,	(caddr_t) NULL},
{"-t",		XtNtekStartup,	XrmoptionNoArg,		(caddr_t) "on"},
{"+t",		XtNtekStartup,	XrmoptionNoArg,		(caddr_t) "off"},
{"-vb",		XtNvisualBell,	XrmoptionNoArg,		(caddr_t) "on"},
{"+vb",		XtNvisualBell,	XrmoptionNoArg,		(caddr_t) "off"},
{"-w",		XtNborderWidth,	XrmoptionSepArg,	(caddr_t) NULL},
};

void XtGetUsersDataBase()
{
	XrmResourceDataBase resources, userResources;
	int uid;
	extern struct passwd *getpwuid();
	struct passwd *pw;
	char filename[1024];
	FILE *f;

	strcpy(filename, LIBDIR);
	strcat(filename, "/Xdefaults" );
	f = fopen(filename, "r");
	if (f) {
	        XrmGetDataBase(f, &resources);
		fclose(f);
	} else
		resources = NULL;

	/* Open .Xdefaults file and merge into existing data base */
	uid = getuid();
	pw = getpwuid(uid);
	if (pw) {
		strcpy(filename, pw->pw_dir);
		strcat(filename, "/.Xdefaults");
		f = fopen(filename, "r");
		if (f) {
			XrmGetDataBase(f, &userResources);
			if (resources)
			    XrmMergeDataBases(userResources, &resources);
			else
			    resources = userResources;
			fclose(f);
		}
		strcpy(filename, pw->pw_dir);
		strcat(filename, "/.X11defaults");
		f = fopen(filename, "r");
		if (f) {
			XrmGetDataBase(f, &userResources);
			if (resources)
			    XrmMergeDataBases(userResources, &resources);
			else
			    resources = userResources;
			fclose(f);
		}
	}
	if (resources) XrmSetCurrentDataBase(resources);
}


OpenDisplay()
{
	register TScreen *screen = &term.screen;
	register int try;
	for (try = 10 ; ; ) {
	    if (screen->display = XOpenDisplay(display))
		break;
	    if (!get_ty) {
		fprintf(stderr, "%s: No such display server %s\n", xterm_name,
		 XDisplayName(display));
		exit(ERROR_NOX);
	    }
	    if (--try <= 0)  {
		fprintf (stderr, "%s: Can't connect to display server %s\n",
		 xterm_name,  XDisplayName(display));
		exit (ERROR_NOX2);
	    }	    
	    sleep (5);
	}

	if (screen->display->fd > 31) {
		fprintf(stderr, 
		 "%s: Display server returned bogus file descriptor %d\n",
		  xterm_name, screen->display->fd);
		exit (ERROR_NOX3);
	};
}

/* ||| */
/* struct timeb startT, initT, endT; */

main (argc, argv)
int argc;
char **argv;
{
	register TScreen *screen = &term.screen;
	register int i, pty;
	int Xsocket, mode;
	char *malloc();
	char *basename();
	int xerror(), xioerror();

	xterm_name = (XStrCmp(*argv, "-") == 0) ? "xterm" : basename(*argv);

/* ||| 
gettimeofday(&startT, &tz);
*/
	/* Init the Toolkit. */
	XtInitialize();
/* ||| 
gettimeofday(&initT, &tz);
*/
	/* Parse the command line for resources */
	XtGetUsersDataBase();
	XrmParseCommand(optionDescList, XtNumber(optionDescList), XtNxterm,
	 &argc, argv);

	/* Parse the rest of the command line */
	display[0] = '\0';
	for (argc--, argv++ ; argc > 0 ; argc--, argv++) {
	    if (**argv == '%') {
		T_geometry = *argv;
		*T_geometry = '=';
		continue;
	    }

	    if (**argv == '#') {
		icon_geom = *argv;
		*icon_geom = '=';
		continue;
	    }

	    if(index(*argv, ':') != NULL) {
		strncpy(display, *argv, sizeof(display));
		continue;
	    }

	    if(!(i = (**argv == '-'))) Syntax (*argv);

	    switch(argv[0][1]) {
#ifdef TIOCCONS
	     case 'C':
		Console = TRUE;
		continue;
#endif TIOCCONS
/*
	     case 'L':
		{
		char tt[32];

		L_flag = 1;
		get_ty = argv[--argc];
		strcpy(tt,"/dev/");
		strcat(tt, get_ty);
		tt[5] = 'p';
		loginpty = open( tt, O_RDWR, 0 );
		dup2( loginpty, 4 );
		close( loginpty );
		loginpty = 4;
		tt[5] = 't';
		chown(tt, 0, 0);
		chmod(tt, 0622);
		if (open(tt, O_RDWR, 0) < 0) {
			consolepr("open(%s) failed\n", tt);
		}
		signal(SIGHUP, SIG_IGN);
		vhangup();
		setpgrp(0,0);
		signal(SIGHUP, SIG_DFL);
		(void) close(0);
		open(tt, O_RDWR, 0);
		dup2(0, 1);
		dup2(0, 2);
		continue;
		}
	     case 'S':
		sscanf(*argv + 2, "%c%c%d", passedPty, passedPty+1,
		 &am_slave);
		if (am_slave <= 0) Syntax(*argv);
		continue;
*/
#ifdef DEBUG
	     case 'D':
		debug = TRUE;
		continue;
#endif DEBUG
	     case 'e':
		if (argc <= 1) Syntax (*argv);
		command_to_exec = ++argv;
		break;
	     default:
		Syntax (*argv);
	    }
	    break;
	}


	/* Initialize the display connection */
	OpenDisplay();
	/* Get initial values from .Xdefaults file */
	XtGetResources(
	    screen->display,
	    resourceList,
	    XtNumber(resourceList), 
	    (ArgList) NULL,
	    0,
	    DefaultRootWindow(screen->display),
	    XtNxterm,
	    XtCApp,
	    &nameList,
	    &classList);

/* ||| 
    gettimeofday(&endT, &tz);
    printf("init: %8.3f,   total: %8.3f\n",
        ((initT.tv_sec*1000000.0+initT.tv_usec)
          - (startT.tv_sec*1000000.0+startT.tv_usec))/1000000.0,
        ((endT.tv_sec*1000000.0+endT.tv_usec)
          - (startT.tv_sec*1000000.0+startT.tv_usec))/1000000.0);
   exit(0);
*/
	/* Do additional processing on complex .Xdefaults stuff */

	if (!f_n) {
		if (f_b)
			f_n = f_b;
		else {
			f_n = defaultFont;
			f_b = defaultBoldFont;
		}
	}

	term.flags = WRAPAROUND | AUTOREPEAT;
	if (!screen->jumpscroll)	term.flags |= SMOOTHSCROLL;
	if (reverseWrap)		term.flags |= REVERSEWRAP;

	inhibit = 0;
	if (logInhibit)			inhibit |= I_LOG;
	if (signalInhibit)		inhibit |= I_SIGNAL;
	if (tekInhibit)			inhibit |= I_TEK;

	if (scrollbar)			screen->scrollbar = SCROLLBARWIDTH;

	screen->color = 0;
	if (screen->foreground != XtDefaultFGPixel)
		screen->color |= C_FOREGROUND;
	if (screen->background != XtDefaultBGPixel) {
		screen->color |= C_BACKGROUND;
	}
	if (screen->cursorcolor != XtDefaultFGPixel)
		screen->color |= C_CURSOR;
	if (screen->mousecolor != XtDefaultFGPixel)
		screen->color |= C_MOUSE;

	term.initflags = term.flags;

	if(!window_name)
		window_name = (get_ty ? "login" : (am_slave ? "xterm slave" :
		 (command_to_exec ? basename(command_to_exec[0]) :
		 xterm_name)));
	if (!title_name)
		title_name = window_name;
	if(inhibit & I_TEK)
		screen->TekEmu = FALSE;

	/* set up stderr properly */
	i = -1;
#ifdef DEBUG
	if(debug)
		i = creat ("xterm.debug", 0666);
	else
#endif DEBUG
	if(get_ty)
		i = open("/dev/console", 1);
	if(i >= 0)
		fileno(stderr) = i;
	if(fileno(stderr) != (NOFILE - 1)) {
		dup2(fileno(stderr), (NOFILE - 1));
		if(fileno(stderr) >= 3)
			close(fileno(stderr));
		fileno(stderr) = (NOFILE - 1);
	}

	signal (SIGCHLD, reapchild);

	/* open a terminal for client */
	get_terminal ();
	spawn ();

	Xsocket = screen->display->fd;
	pty = screen->respond;

	if (am_slave) { /* Write window id so master end can read and use */
	    write(pty, screen->TekEmu ? (char *)&TWindow(screen) :
	     (char *)&VWindow(screen), sizeof(Window));
	    write(pty, "\n", 1);
	}

	if(log_on) {
		log_on = FALSE;
		StartLog(screen);
	}
	screen->inhibit = inhibit;
	mode = 1;
	
	pty_mask = 1 << pty;
	X_mask = 1 << Xsocket;
	Select_mask = pty_mask | X_mask;
	max_plus1 = (pty < Xsocket) ? (1 + Xsocket) : (1 + pty);

#ifdef DEBUG
	if (debug) printf ("debugging on\n");
#endif DEBUG
	XSetErrorHandler(xerror);
	XSetIOErrorHandler(xioerror);
	for( ; ; )
		if(screen->TekEmu)
			TekRun();
		else
			VTRun();
}

char *basename(name)
char *name;
{
	register char *cp;
	char *rindex();

	return((cp = rindex(name, '/')) ? cp + 1 : name);
}

static char *ustring[] = {
"Usage: xterm [-132] [-b inner_border_width] [-bd border_color] \\\n",
#ifdef TIOCCONS
" [-bg backgrnd_color] [-bw border_width] [-C] [-cr cursor_color] [-cu] \\\n",
#else TIOCCONS
" [-bg backgrnd_color] [-bw border_width] [-cr cursor_color] [-cu] \\\n",
#endif TIOCCONS
" [-fb bold_font] [-fg foregrnd_color] [-fn norm_font] \\\n",
" [-i] [-j] [-l] [-lf logfile] [-ls] [-mb] [-ms mouse_color] \\\n",
" [-n name] [-nb bell_margin] [-rv] [-rw] [-s] \\\n",
" [-sb] [-si] [-sk] [-sl save_lines] [-sn] [-st] [-T title] [-t] [-tb] \\\n",
" [-vb] [=[width]x[height][[+-]xoff[[+-]yoff]]] \\\n",
" [%[width]x[height][[+-]xoff[[+-]yoff]]] [#[+-]xoff[[+-]yoff]] \\\n",
" [-e command_to_exec]\n\n",
"Fonts must be of fixed width and of same size;\n",
"If only one font is specified, it will be used for normal and bold text\n",
"The -132 option allows 80 <-> 132 column escape sequences\n",
#ifdef TIOCCONS
"The -C option forces output to /dev/console to appear in this window\n",
#endif TIOCCONS
"The -cu option turns a curses bug fix on\n",
"The -i  option enables iconic startup\n",
"The -j  option enables jump scroll\n",
"The -l  option enables logging\n",
"The -ls option makes the shell a login shell\n",
"The -mb option turns the margin bell on\n",
"The -rv option turns reverse video on\n",
"The -rw option turns reverse wraparound on\n",
"The -s  option enables asynchronous scrolling\n",
"The -sb option enables the scrollbar\n",
"The -si option disables re-positioning the scrollbar at the bottom on input\n",
"The -sk option causes the scrollbar to position at the bottom on a key\n",
"The -t  option starts Tektronix mode\n",
"The -vb option enables visual bell\n",
0
};

Syntax (badOption)
char	*badOption;
{
	register char **us = ustring;

	fprintf(stderr, "Unknown option \"%s\"\n\n", badOption);
	while (*us) fputs(*us++, stderr);
	exit (1);
}

get_pty (pty, tty)
/*
   opens a pty, storing fildes in pty and tty.
 */
int *pty, *tty;
{
	if ((*pty = ptopen (ttydev)) >= 0) {
		if ((*tty = open (ttydev, 2)) >= 0) {
			if(ioctl(*pty, FIOPUSHLD, &mesg_ld) != -1 &&
			   ioctl(*tty, FIOPUSHLD, &tty_ld) != -1)
				return;
			else {
			   close(*tty);
			   close(*pty);
			   fprintf(stderr, "FIOPUSHLD fails, errno=%d\n", errno);
			}
		} else {
			fprintf(stderr, "Can't open slave pty\n");
			close(*pty);
		}
	} else
		fprintf (stderr, "%s: Not enough available pty's\n", xterm_name);
	exit (ERROR_PTYS);
}

get_terminal ()
/* 
 * sets up X and initializes the terminal structure except for term.buf.fildes.
 */
{
	register TScreen *screen = &term.screen;
	char *malloc();
	
	screen->graybordertile = make_gray(screen->bordercolor,
		screen->background,
		DefaultDepth(screen->display, DefaultScreen(screen->display)));

	screen->arrow = make_arrow(screen->mousecolor, screen->background);

	XAutoRepeatOn(screen->display);

	if((screen->iconname = malloc((unsigned) strlen(window_name) + 10)) == NULL)
		Error(ERROR_WINNAME);
	strcpy(screen->iconname, window_name);
	screen->iconnamelen = strlen(screen->iconname);
	if((screen->titlename = malloc((unsigned) strlen(title_name) + 10)) == NULL)
		Error(ERROR_WINNAME);
	strcpy(screen->titlename, title_name);
	screen->titlenamelen = strlen(screen->titlename);

}

static char *tekterm[] = {
	"tek4015",
	"tek4014",
	"tek4013",
	"tek4010",
	"dumb",
	0
};

static char *vtterm[] = {
	"xterm",
	"vt102",
	"vt100",
	"ansi",
	"dumb",
	0
};

hungtty()
{
	longjmp(env, 1);
}

spawn ()
/* 
 *  Inits pty and tty and forks a login process.
 *  Does not close fd Xsocket.
 *  If getty,  execs getty rather than csh and uses std fd's rather
 *  than opening a pty/tty pair.
 *  If slave, the pty named in passedPty is already open for use
 */
{
	register TScreen *screen = &term.screen;
	int Xsocket = screen->display->fd;
	int index1, tty = -1;
	unsigned lmode;
	struct tchars tc;
	struct sgttyb sg;
	struct ttydevb	devmodes;

	char termcap [1024];
	char newtc [1024];
	char *ptr, *shname;
	int i, no_dev_tty = FALSE;
	char **envnew;		/* new environment */
	char buf[32];
	char *TermName = NULL;
	struct passwd *pw = NULL;
#ifdef UTMP
	struct utmp utmp;
#endif UTMP
	extern int Exit();
	char *getenv();
	char *index (), *rindex (), *strindex ();

	screen->uid = getuid();
	screen->gid = getgid();

	if(!(screen->TekEmu ? TekInit() : VTInit()))
		exit(ERROR_INIT);

	if(screen->TekEmu) {
		envnew = tekterm;
		ptr = newtc;
	} else {
		envnew = vtterm;
		ptr = termcap;
	}
	while(*envnew) {
		if(tgetent(ptr, *envnew) == 1) {
			TermName = *envnew;
			if(!screen->TekEmu)
			    resize(screen, TermName, termcap, newtc);
			break;
		}
		envnew++;
	}

	if (get_ty) {
		screen->respond = loginpty;
	} else if (am_slave) {
		setgid (screen->gid);
		setuid (screen->uid);
	} else {
 		/*
 		 * Sometimes /dev/tty hangs on open (as in the case of a pty
 		 * that has gone away).  Simply make up some reasonable
 		 * defaults.
 		 */
 		signal(SIGALRM, hungtty);
 		alarm(1);		
 		if (! setjmp(env)) {
 			tty = open ("/dev/tty", 2);
 			alarm(0);
 		} else {
 			tty = -1;
 			errno = ENXIO;
 		}
 		signal(SIGALRM, SIG_DFL);
 
 		if (tty < 0) {
			if (errno != ENXIO) SysError(ERROR_OPDEVTTY);
			else {
				no_dev_tty = TRUE;
				sg = d_sg;
				tc = d_tc;
			}
		} else {
			/* get a copy of the current terminal's state */

			if(ioctl(tty, TIOCGETP, (char *)&sg) == -1) {
				char filename[256], *p;
				int fd;

				if((p=getenv("HOME")) == 0)
					exit(1);
				strcpy(filename, p);
				strcat(filename, "/.sttymodes");
				if ((fd = open(filename, 0)) < 0)
					exit(1);
				read(fd, &sg, sizeof(struct sgttyb));
				read(fd, &devmodes, sizeof(struct ttydevb));
				read(fd, &tc, sizeof(struct tchars));
				close(fd);
			}
			else {
				if(ioctl(tty, TIOCGETC, (char *)&tc) == -1)
					SysError (ERROR_TIOCGETC);
			}
			close (tty);

			/* close all std file descriptors */
			for (index1 = 0; index1 < 4; index1++)
				close (index1);
		}

		get_pty (&screen->respond, &tty);

		if (screen->respond != Xsocket + 1) {
			dup2 (screen->respond, Xsocket + 1);
			close (screen->respond);
			screen->respond = Xsocket + 1;
		}

		/* change ownership of tty to real group and user id */
		chown (ttydev, screen->uid, screen->gid);

		/* change protection of tty */
		chmod (ttydev, 0622);

		if (tty != Xsocket + 2)	{
			dup2 (tty, Xsocket + 2);
			close (tty);
			tty = Xsocket + 2;
		}

		/* set the new terminal's state to be the old one's 
		   with minor modifications for efficiency */

		sg.sg_flags &= ~(ALLDELAY | XTABS | CBREAK | RAW);
		sg.sg_flags |= ECHO | CRMOD;
		/* make sure speed is set on pty so that editors work right*/
		sg.sg_ispeed = B9600;
		sg.sg_ospeed = B9600;
		/* reset t_brkc to default value */
		tc.t_brkc = -1;

		if (ioctl (tty, TIOCSETP, (char *)&sg) == -1)
			SysError (ERROR_TIOCSETP);
		if (ioctl (tty, TIOCSETC, (char *)&tc) == -1)
			SysError (ERROR_TIOCSETC);
#ifdef TIOCCONS
		if (Console) {
			int on = 1;
			if (ioctl (tty, TIOCCONS, (char *)&on) == -1)
				SysError(ERROR_TIOCCONS);
		}
#endif TIOCCONS
		for (index1 = 0; index1 < 4; index1++)
			dup2 (tty, index1);
#ifdef UTMP
		if((pw = getpwuid(screen->uid)) &&
		 (i = open(etc_utmp, 1)) >= 0) {
			bzero((char *)&utmp, sizeof(struct utmp));
			(void) strcpy(utmp.ut_line, &ttydev[5]);
			(void) strcpy(utmp.ut_name, pw->pw_name);
			time(&utmp.ut_time);
			lseek(i, (long)(tslot * sizeof(struct utmp)), 0);
			write(i, (char *)&utmp, sizeof(struct utmp));
			close(i);
		} else
			tslot = -tslot;
#endif UTMP
	}

	if (!am_slave) {
	    if ((screen->pid = fork ()) == -1)
		SysError (ERROR_FORK);
		
	    if (screen->pid == 0) {
		extern char **environ;
		int pgrp = getpid();

		close (Xsocket);
		close (screen->respond);
		if(fileno(stderr) >= 4)
			close (fileno(stderr));

		if (tty >= 0) close (tty);

		signal (SIGCHLD, SIG_DFL);
		signal (SIGHUP, SIG_IGN);

		/* copy the environment before Setenving */
		for (i = 0 ; environ [i] != NULL ; i++) ;
		/*
		 * The `4' is the number of Setenv() calls which may add
		 * a new entry to the environment.  The `1' is for the
		 * NULL terminating entry.
		 */
		envnew = (char **) calloc ((unsigned) i + (4 + 1), sizeof(char *));
		bcopy((char *)environ, (char *)envnew, i * sizeof(char *));
		environ = envnew;
		Setenv ("TERM=", TermName);
		if(!TermName)
			*newtc = 0;
		Setenv ("TERMCAP=", newtc);
		sprintf(buf, "%d", screen->TekEmu ? (int)TWindow(screen) :
		 (int)VWindow(screen));
		Setenv ("WINDOWID=", buf);
		/* put the display into the environment of the shell*/
		if (display[0] != '\0') 
			Setenv ("DISPLAY=", XDisplayName(display));

		signal(SIGTERM, SIG_DFL);
		ioctl(0, TIOCSPGRP, 0);

		setgid (screen->gid);
		setuid (screen->uid);

		if (command_to_exec) {
			execvp(*command_to_exec, command_to_exec);
			/* print error message on screen */
			fprintf(stderr, "%s: Can't execvp %s\n", xterm_name,
			 *command_to_exec);
		}
		signal(SIGHUP, SIG_IGN);
		if (get_ty) {
			execl ("/etc/getty", "+", "Xwindow", get_ty, 0);
		}
		signal(SIGHUP, SIG_DFL);

#ifdef UTMP
		if(((ptr = getenv("SHELL")) == NULL || *ptr == 0) &&
		 ((pw == NULL && (pw = getpwuid(screen->uid)) == NULL) ||
		 *(ptr = pw->pw_shell) == 0))
#else UTMP
		if(((ptr = getenv("SHELL")) == NULL || *ptr == 0) &&
		 ((pw = getpwuid(screen->uid)) == NULL ||
		 *(ptr = pw->pw_shell) == 0))
#endif UTMP
			ptr = "/bin/sh";
		if(shname = rindex(ptr, '/'))
			shname++;
		else
			shname = ptr;
		execl (ptr, login_shell ? "-" : shname, 0);
		fprintf (stderr, "%s: Could not exec %s!\n", xterm_name, ptr);
		sleep(5);
		exit(ERROR_EXEC);
	    }
	}

	if(tty >= 0) close (tty);
	signal(SIGHUP,SIG_IGN);

	if (!no_dev_tty) {
		if ((tty = open ("/dev/tty", 2)) < 0)
			SysError(ERROR_OPDEVTTY3);
		for (index1 = 0; index1 < 4; index1++)
			dup2 (tty, index1);
		if (tty > 2) close (tty);
	}

	signal(SIGINT, Exit); 
	signal(SIGQUIT, Exit);
	signal(SIGTERM, Exit);
}

Exit(n)
int n;
{
	register TScreen *screen = &term.screen;
        int pty = term.screen.respond;  /* file descriptor of pty */
#ifdef UTMP
	register int i;
	struct utmp utmp;

	if(!am_slave && tslot > 0 && (i = open(etc_utmp, 1)) >= 0) {
		bzero((char *)&utmp, sizeof(struct utmp));
		lseek(i, (long)(tslot * sizeof(struct utmp)), 0);
		write(i, (char *)&utmp, sizeof(struct utmp));
		close(i);
	}
#endif UTMP
        close(pty); /* close explicitly to avoid race with slave side */
	if(screen->logging)
		CloseLog(screen);

	if(!get_ty && !am_slave) {
		/* restore ownership of tty */
		chown (ttydev, 0, 0);

		/* restore modes of tty */
		chmod (ttydev, 0666);
	}
	exit(n);
}

resize(screen, TermName, oldtc, newtc)
TScreen *screen;
char *TermName;
register char *oldtc, *newtc;
{
	register char *ptr1, *ptr2;
	register int i;
	register int li_first = 0;
	register char *temp;
	char *index(), *strindex();

	if ((ptr1 = strindex (oldtc, "co#")) == NULL){
		fprintf(stderr, "%s: Can't find co# in termcap string %s\n",
			xterm_name, TermName);
		exit (ERROR_NOCO);
	}
	if ((ptr2 = strindex (oldtc, "li#")) == NULL){
		fprintf(stderr, "%s: Can't find li# in termcap string %s\n",
			xterm_name, TermName);
		exit (ERROR_NOLI);
	}
	if(ptr1 > ptr2) {
		li_first++;
		temp = ptr1;
		ptr1 = ptr2;
		ptr2 = temp;
	}
	ptr1 += 3;
	ptr2 += 3;
	strncpy (newtc, oldtc, i = ptr1 - oldtc);
	newtc += i;
	sprintf (newtc, "%d", li_first ? screen->max_row + 1 :
	 screen->max_col + 1);
	newtc += strlen(newtc);
	ptr1 = index (ptr1, ':');
	strncpy (newtc, ptr1, i = ptr2 - ptr1);
	newtc += i;
	sprintf (newtc, "%d", li_first ? screen->max_col + 1 :
	 screen->max_row + 1);
	ptr2 = index (ptr2, ':');
	strcat (newtc, ptr2);
}

static reapchild ()
{
	union wait status;
	register int pid;
	
#ifdef DEBUG
	if (debug) fputs ("Exiting\n", stderr);
#endif DEBUG
	pid  = wait3 (&status, WNOHANG, (struct rusage *)NULL);
	if (!pid) return;
	if (pid != term.screen.pid) return;
	
	Cleanup(0);
}

/* VARARGS1 */
consolepr(fmt,x0,x1,x2,x3,x4,x5,x6,x7,x8,x9)
char *fmt;
{
	extern int errno;
	extern char *sys_errlist[];
	int oerrno;
	int f;
 	char buf[ BUFSIZ ];

	oerrno = errno;
 	strcpy(buf, "xterm: ");
 	sprintf(buf+strlen(buf), fmt, x0,x1,x2,x3,x4,x5,x6,x7,x8,x9);
 	strcat(buf, ": ");
 	strcat(buf, sys_errlist[oerrno]);
 	strcat(buf, "\n");	
	f = open("/dev/console",1);
	write(f, buf, strlen(buf));
	close(f);
}

checklogin()
{
	register int ts, i;
	register struct passwd *pw;
	struct utmp utmp;

	ts = tslot > 0 ? tslot : -tslot;
	if((i = open(etc_utmp, 0)) < 0)
		return(FALSE);
	lseek(i, (long)(ts * sizeof(struct utmp)), 0);
	ts = read(i, (char *)&utmp, sizeof(utmp));
	close(i);
	if(ts != sizeof(utmp) || XStrCmp(get_ty, utmp.ut_line) != 0 ||
	 !*utmp.ut_name || (pw = getpwnam(utmp.ut_name)) == NULL)
		return(FALSE);
	chdir(pw->pw_dir);
	setgid(pw->pw_gid);
	setuid(pw->pw_uid);
	L_flag = 0;
	return(TRUE);
}

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.