v12i094: kterm - kanji xterm, Part13/18

mleisher at NMSU.Edu mleisher at NMSU.Edu
Sat May 11 10:51:20 AEST 1991


Submitted-by: mleisher at NMSU.Edu
Posting-number: Volume 12, Issue 94
Archive-name: kterm/part13

#!/bin/sh
# this is kt412.13 (part 13 of kterm-4.1.2)
# do not concatenate these parts, unpack them in order with /bin/sh
# file kterm-4.1.2/main.c continued
#
if test ! -r _shar_seq_.tmp; then
	echo 'Please unpack part 1 first!'
	exit 1
fi
(read Scheck
 if test "$Scheck" != 13; then
	echo Please unpack part "$Scheck" next!
	exit 1
 else
	exit 0
 fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
	echo 'x - still skipping kterm-4.1.2/main.c'
else
echo 'x - continuing file kterm-4.1.2/main.c'
sed 's/^X//' << 'SHAR_EOF' >> 'kterm-4.1.2/main.c' &&
#define XTTYMODE_start 7
{ "stop", 4, 0, '\0' },			/* tchars.t_stopc */
#define XTTYMODE_stop 8
{ "brk", 3, 0, '\0' },			/* tchars.t_brkc */
#define XTTYMODE_brk 9
{ "susp", 4, 0, '\0' },			/* ltchars.t_suspc */
#define XTTYMODE_susp 10
{ "dsusp", 5, 0, '\0' },		/* ltchars.t_dsuspc */
#define XTTYMODE_dsusp 11
{ "rprnt", 5, 0, '\0' },		/* ltchars.t_rprntc */
#define XTTYMODE_rprnt 12
{ "flush", 5, 0, '\0' },		/* ltchars.t_flushc */
#define XTTYMODE_flush 13
{ "weras", 5, 0, '\0' },		/* ltchars.t_werasc */
#define XTTYMODE_weras 14
{ "lnext", 5, 0, '\0' },		/* ltchars.t_lnextc */
#define XTTYMODE_lnext 15
#define NXTTYMODES 16
};
X
#ifdef USE_SYSV_UTMP
extern struct utmp *getutent();
extern struct utmp *getutid();
extern struct utmp *getutline();
extern void pututline();
extern void setutent();
extern void endutent();
extern void utmpname();
X
extern struct passwd *getpwent();
extern struct passwd *getpwuid();
extern struct passwd *getpwnam();
extern void setpwent();
extern void endpwent();
extern struct passwd *fgetpwent();
#else	/* not USE_SYSV_UTMP */
static char etc_utmp[] = UTMP_FILENAME;
#ifdef LASTLOG
static char etc_lastlog[] = LASTLOG_FILENAME;
#endif 
#ifdef WTMP
static char etc_wtmp[] = WTMP_FILENAME;
#endif
#endif	/* USE_SYSV_UTMP */
X
/*
X * Some people with 4.3bsd /bin/login seem to like to use login -p -f user
X * to implement xterm -ls.  They can turn on USE_LOGIN_DASH_P and turn off
X * WTMP and LASTLOG.
X */
#ifdef USE_LOGIN_DASH_P
#ifndef LOGIN_FILENAME
#define LOGIN_FILENAME "/bin/login"
#endif
static char bin_login[] = LOGIN_FILENAME;
#endif
X
static int inhibit;
static char passedPty[2];	/* name if pty if slave */
X
#ifdef TIOCCONS
static int Console;
#endif	/* TIOCCONS */
#ifndef USE_SYSV_UTMP
static int tslot;
#endif	/* USE_SYSV_UTMP */
static jmp_buf env;
X
char *ProgramName;
Boolean sunFunctionKeys;
X
static struct _resource {
X    char *xterm_name;
X    char *icon_geometry;
X    char *title;
X    char *icon_name;
X    char *term_name;
X    char *tty_modes;
X    Boolean utmpInhibit;
X    Boolean sunFunctionKeys;	/* %%% should be widget resource? */
X    Boolean wait_for_map;
#ifdef KEEPALIVE
X    Boolean keepalive;
#endif
} resource;
X
/* used by VT (charproc.c) */
X
#define offset(field)	XtOffset(struct _resource *, field)
X
static XtResource application_resources[] = {
X    {"name", "Name", XtRString, sizeof(char *),
#ifdef KTERM
X	offset(xterm_name), XtRString, "kterm"},
#else /* !KTERM */
X	offset(xterm_name), XtRString, "xterm"},
#endif /* !KTERM */
X    {"iconGeometry", "IconGeometry", XtRString, sizeof(char *),
X	offset(icon_geometry), XtRString, (caddr_t) NULL},
X    {XtNtitle, XtCTitle, XtRString, sizeof(char *),
X	offset(title), XtRString, (caddr_t) NULL},
X    {XtNiconName, XtCIconName, XtRString, sizeof(char *),
X	offset(icon_name), XtRString, (caddr_t) NULL},
X    {"termName", "TermName", XtRString, sizeof(char *),
X	offset(term_name), XtRString, (caddr_t) NULL},
X    {"ttyModes", "TtyModes", XtRString, sizeof(char *),
X	offset(tty_modes), XtRString, (caddr_t) NULL},
X    {"utmpInhibit", "UtmpInhibit", XtRBoolean, sizeof (Boolean),
X	offset(utmpInhibit), XtRString, "false"},
X    {"sunFunctionKeys", "SunFunctionKeys", XtRBoolean, sizeof (Boolean),
X	offset(sunFunctionKeys), XtRString, "false"},
X    {"waitForMap", "WaitForMap", XtRBoolean, sizeof (Boolean),
X        offset(wait_for_map), XtRString, "false"},
#ifdef KEEPALIVE
X    {"keepAlive", "KeepAlive", XtRBoolean, sizeof (Boolean),
X        offset(keepalive), XtRString, "false"},
#endif /* KEEPALIVE */
};
#undef offset
X
/* Command line options table.  Only resources are entered here...there is a
X   pass over the remaining options after XtParseCommand is let loose. */
X
static char *fallback_resources[] = {
#ifdef KTERM
X    "KTerm*SimpleMenu*menuLabel.vertSpace: 100",
X    "KTerm*SimpleMenu*HorizontalMargins: 16",
X    "KTerm*SimpleMenu*Sme.height: 16",
X    "KTerm*SimpleMenu*Cursor: left_ptr",
X    "KTerm*mainMenu.Label:  Main Options (no app-defaults)",
X    "KTerm*vtMenu.Label:  VT Options (no app-defaults)",
X    "KTerm*fontMenu.Label:  VT Fonts (no app-defaults)",
X    "KTerm*tekMenu.Label:  Tek Options (no app-defaults)",
#else /* !KTERM */
X    "XTerm*SimpleMenu*menuLabel.vertSpace: 100",
X    "XTerm*SimpleMenu*HorizontalMargins: 16",
X    "XTerm*SimpleMenu*Sme.height: 16",
X    "XTerm*SimpleMenu*Cursor: left_ptr",
X    "XTerm*mainMenu.Label:  Main Options (no app-defaults)",
X    "XTerm*vtMenu.Label:  VT Options (no app-defaults)",
X    "XTerm*fontMenu.Label:  VT Fonts (no app-defaults)",
X    "XTerm*tekMenu.Label:  Tek Options (no app-defaults)",
#endif /* !KTERM */
X    NULL
};
X
static XrmOptionDescRec optionDescList[] = {
{"-geometry",	"*vt100.geometry",XrmoptionSepArg,	(caddr_t) NULL},
{"-132",	"*c132",	XrmoptionNoArg,		(caddr_t) "on"},
{"+132",	"*c132",	XrmoptionNoArg,		(caddr_t) "off"},
{"-ah",		"*alwaysHighlight", XrmoptionNoArg,	(caddr_t) "on"},
{"+ah",		"*alwaysHighlight", XrmoptionNoArg,	(caddr_t) "off"},
{"-b",		"*internalBorder",XrmoptionSepArg,	(caddr_t) NULL},
{"-cb",		"*cutToBeginningOfLine", XrmoptionNoArg, (caddr_t) "off"},
{"+cb",		"*cutToBeginningOfLine", XrmoptionNoArg, (caddr_t) "on"},
{"-cc",		"*charClass",	XrmoptionSepArg,	(caddr_t) NULL},
{"-cn",		"*cutNewline",	XrmoptionNoArg,		(caddr_t) "off"},
{"+cn",		"*cutNewline",	XrmoptionNoArg,		(caddr_t) "on"},
{"-cr",		"*cursorColor",	XrmoptionSepArg,	(caddr_t) NULL},
{"-cu",		"*curses",	XrmoptionNoArg,		(caddr_t) "on"},
{"+cu",		"*curses",	XrmoptionNoArg,		(caddr_t) "off"},
{"-e",		NULL,		XrmoptionSkipLine,	(caddr_t) NULL},
#ifndef ENBUG /* kagotani */
{"-fn",		"*vt100.font",	XrmoptionSepArg,	(caddr_t) NULL},
#endif
{"-fb",		"*boldFont",	XrmoptionSepArg,	(caddr_t) NULL},
#ifdef KTERM
{"-fl",		"*fontList",	XrmoptionSepArg,	(caddr_t) NULL},
{"-flb",	"*boldFontList", XrmoptionSepArg,	(caddr_t) NULL},
{"-fr",		"*romanKanaFont", XrmoptionSepArg,	(caddr_t) NULL},
{"-frb",	"*romanKanaBoldFont", XrmoptionSepArg,	(caddr_t) NULL},
#ifdef KTERM_KANJI
#ifdef KTERM_HANZI
{"-fhz",	"*hanziFont",	XrmoptionSepArg,	(caddr_t) NULL},
{"-fhzb",	"*hanziBoldFont", XrmoptionSepArg,	(caddr_t) NULL},
{"-hzm",	"*hanziMode",	XrmoptionSepArg,	(caddr_t) NULL},
#endif /* KTERM_HANZI */
#ifdef KTERM_HANGUL
{"-fhg",	"*hangulFont",	XrmoptionSepArg,	(caddr_t) NULL},
{"-fhgb",	"*hangulBoldFont", XrmoptionSepArg,	(caddr_t) NULL},
{"-hgm",	"*hangulMode",	XrmoptionSepArg,	(caddr_t) NULL},
#endif /* KTERM_HANGUL */
{"-fk",		"*kanjiFont",	XrmoptionSepArg,	(caddr_t) NULL},
{"-fkb",	"*kanjiBoldFont", XrmoptionSepArg,	(caddr_t) NULL},
{"-km",		"*kanjiMode",	XrmoptionSepArg,	(caddr_t) NULL},
{"-lang",	"*language",	XrmoptionSepArg,	(caddr_t) NULL},
#endif /* KTERM_KANJI */
{"-lsp",	"*lineSpace",	XrmoptionSepArg,	(caddr_t) NULL},
#endif /* KTERM */
{"-j",		"*jumpScroll",	XrmoptionNoArg,		(caddr_t) "on"},
{"+j",		"*jumpScroll",	XrmoptionNoArg,		(caddr_t) "off"},
#ifdef KEEPALIVE
{"-ka",		"*keepAlive",	XrmoptionNoArg,		(caddr_t) "on"},
{"+ka",		"*keepAlive",	XrmoptionNoArg,		(caddr_t) "off"},
#endif /* KEEPALIVE */
{"-l",		"*logging",	XrmoptionNoArg,		(caddr_t) "on"},
{"+l",		"*logging",	XrmoptionNoArg,		(caddr_t) "off"},
{"-lf",		"*logFile",	XrmoptionSepArg,	(caddr_t) NULL},
{"-ls",		"*loginShell",	XrmoptionNoArg,		(caddr_t) "on"},
{"+ls",		"*loginShell",	XrmoptionNoArg,		(caddr_t) "off"},
{"-mb",		"*marginBell",	XrmoptionNoArg,		(caddr_t) "on"},
{"+mb",		"*marginBell",	XrmoptionNoArg,		(caddr_t) "off"},
{"-mc",		"*multiClickTime", XrmoptionSepArg,	(caddr_t) NULL},
{"-ms",		"*pointerColor",XrmoptionSepArg,	(caddr_t) NULL},
{"-nb",		"*nMarginBell",	XrmoptionSepArg,	(caddr_t) NULL},
{"-rw",		"*reverseWrap",	XrmoptionNoArg,		(caddr_t) "on"},
{"+rw",		"*reverseWrap",	XrmoptionNoArg,		(caddr_t) "off"},
{"-s",		"*multiScroll",	XrmoptionNoArg,		(caddr_t) "on"},
{"+s",		"*multiScroll",	XrmoptionNoArg,		(caddr_t) "off"},
{"-sb",		"*scrollBar",	XrmoptionNoArg,		(caddr_t) "on"},
{"+sb",		"*scrollBar",	XrmoptionNoArg,		(caddr_t) "off"},
{"-sf",		"*sunFunctionKeys", XrmoptionNoArg,	(caddr_t) "on"},
{"+sf",		"*sunFunctionKeys", XrmoptionNoArg,	(caddr_t) "off"},
{"-si",		"*scrollTtyOutput",	XrmoptionNoArg,		(caddr_t) "off"},
{"+si",		"*scrollTtyOutput",	XrmoptionNoArg,		(caddr_t) "on"},
{"-sk",		"*scrollKey",	XrmoptionNoArg,		(caddr_t) "on"},
{"+sk",		"*scrollKey",	XrmoptionNoArg,		(caddr_t) "off"},
#ifdef STATUSLINE
{"-st",		"*statusLine",	XrmoptionNoArg,		(caddr_t) "on"},
{"+st",		"*statusLine",	XrmoptionNoArg,		(caddr_t) "off"},
{"-sn",		"*statusNormal", XrmoptionNoArg,	(caddr_t) "on"},
{"+sn",		"*statusNormal", XrmoptionNoArg,	(caddr_t) "off"},
#endif /* STATUSLINE */
{"-sl",		"*saveLines",	XrmoptionSepArg,	(caddr_t) NULL},
{"-t",		"*tekStartup",	XrmoptionNoArg,		(caddr_t) "on"},
{"+t",		"*tekStartup",	XrmoptionNoArg,		(caddr_t) "off"},
{"-tm",		"*ttyModes",	XrmoptionSepArg,	(caddr_t) NULL},
{"-tn",		"*termName",	XrmoptionSepArg,	(caddr_t) NULL},
{"-ut",		"*utmpInhibit",	XrmoptionNoArg,		(caddr_t) "on"},
{"+ut",		"*utmpInhibit",	XrmoptionNoArg,		(caddr_t) "off"},
{"-vb",		"*visualBell",	XrmoptionNoArg,		(caddr_t) "on"},
{"+vb",		"*visualBell",	XrmoptionNoArg,		(caddr_t) "off"},
{"-wf",		"*waitForMap",	XrmoptionNoArg,		(caddr_t) "on"},
{"+wf",		"*waitForMap",	XrmoptionNoArg,		(caddr_t) "off"},
/* bogus old compatibility stuff for which there are
X   standard XtInitialize options now */
{"%",		"*tekGeometry",	XrmoptionStickyArg,	(caddr_t) NULL},
{"#",		".iconGeometry",XrmoptionStickyArg,	(caddr_t) NULL},
{"-T",		"*title",	XrmoptionSepArg,	(caddr_t) NULL},
{"-n",		"*iconName",	XrmoptionSepArg,	(caddr_t) NULL},
{"-r",		"*reverseVideo",XrmoptionNoArg,		(caddr_t) "on"},
{"+r",		"*reverseVideo",XrmoptionNoArg,		(caddr_t) "off"},
{"-rv",		"*reverseVideo",XrmoptionNoArg,		(caddr_t) "on"},
{"+rv",		"*reverseVideo",XrmoptionNoArg,		(caddr_t) "off"},
{"-w",		".borderWidth", XrmoptionSepArg,	(caddr_t) NULL},
};
X
static struct _options {
X  char *opt;
X  char *desc;
} options[] = {
{ "-help",                 "print out this message" },
#ifdef KTERM
{ "-version",              "print out kterm version info" },
#endif /* KTERM */
{ "-display displayname",  "X server to contact" },
{ "-geometry geom",        "size (in characters) and position" },
{ "-/+rv",                 "turn on/off reverse video" },
{ "-bg color",             "background color" },
{ "-fg color",             "foreground color" },
{ "-bd color",             "border color" },
{ "-bw number",            "border width in pixels" },
{ "-fn fontname",          "normal text font" },
{ "-iconic",               "start iconic" },
{ "-name string",          "client instance, icon, and title strings" },
{ "-title string",         "title string" },
{ "-xrm resourcestring",   "additional resource specifications" },
{ "-/+132",                "turn on/off column switch inhibiting" },
{ "-/+ah",                 "turn on/off always highlight" },
{ "-b number",             "internal border in pixels" },
{ "-/+cb",                 "turn on/off cut-to-beginning-of-line inhibit" },
{ "-cc classrange",        "specify additional character classes" },
{ "-/+cn",                 "turn on/off cut newline inhibit" },
{ "-cr color",             "text cursor color" },
{ "-/+cu",                 "turn on/off curses emulation" },
{ "-fb fontname",          "bold text font" },
#ifdef KTERM
{ "-fl fontlist",          "normal fonts" },
{ "-flb fontlist",         "bold fonts" },
{ "-fr fontname",          "normal kana font" },
{ "-frb fontname",         "bold kana font" },
#ifdef KTERM_KANJI
#ifdef KTERM_HANZI
{ "-fhz fontname",         "normal Hanzi font" },
{ "-fhzb fontname",        "bold Hanzi font" },
{ "-hzm hanzimode",        "input Hanzi code (guobiao|big5|shift-guobiao)" },
#endif /* KTERM_HANZI */
#ifdef KTERM_HANGUL
{ "-fhg fontname",         "normal Hangul font" },
{ "-fhgb fontname",        "bold Hangul font" },
{ "-hgm hangulmode",       "input Hangul code (ks-8bit|n-byte)" },
#endif /* KTERM_HANGUL */
{ "-fk fontname",          "normal Kanji font" },
{ "-fkb fontname",         "bold Kanji font" },
{ "-km kanjimode",         "input Kanji code (jis|euc|sjis)" },
{ "-lang language",        "which language to be displayed (chinese|japanese|korean)" },
#endif /* KTERM_KANJI */
{ "-lsp number",           "number of extra dots between  lines" },
#endif /* KTERM */
{ "-/+j",                  "turn on/off jump scroll" },
#ifdef KEEPALIVE
{ "-/+ka",                 "turn on/off keeping connection alive" },
#endif /* KEEPALIVE */
{ "-/+l",                  "turn on/off logging" },
{ "-lf filename",          "logging filename" },
{ "-/+ls",                 "turn on/off login shell" },
{ "-/+mb",                 "turn on/off margin bell" },
{ "-mc milliseconds",      "multiclick time in milliseconds" },
{ "-ms color",             "pointer color" },
{ "-nb number",            "margin bell in characters from right end" },
{ "-/+rw",                 "turn on/off reverse wraparound" },
{ "-/+s",                  "turn on/off multiscroll" },
{ "-/+sb",                 "turn on/off scrollbar" },
{ "-/+sf",                 "turn on/off Sun Function Key escape codes" },
{ "-/+si",                 "turn on/off scroll-on-tty-output inhibit" },
{ "-/+sk",                 "turn on/off scroll-on-keypress" },
{ "-sl number",            "number of scrolled lines to save" },
#ifdef STATUSLINE
{ "-/+st",                 "turn on/off status line" },
{ "-/+sn",                 "turn on/off status line normal video" },
#endif /* STATUSLINE */
{ "-/+t",                  "turn on/off Tek emulation window" },
{ "-tm string",            "terminal mode keywords and characters" },
{ "-tn name",              "TERM environment variable name" },
{ "-/+ut",                 "turn on/off utmp inhibit" },
{ "-/+vb",                 "turn on/off visual bell" },
{ "-e command args",       "command to execute" },
{ "%geom",                 "Tek window geometry" },
{ "#geom",                 "icon window geometry" },
{ "-T string",             "title name for window" },
{ "-n string",             "icon name for window" },
{ "-C",                    "intercept console messages, if supported" },
{ "-Sxxd",                 "slave mode on \"ttyxx\", file descriptor \"d\"" },
{ NULL, NULL }};
X
static char *message[] = {
"Fonts must be fixed width and, if both normal and bold are specified, must",
"have the same size.  If only a normal font is specified, it will be used for",
"both normal and bold text (by doing overstriking).  The -e option, if given,",
"must be appear at the end of the command line, otherwise the user's default",
"shell will be started.  Options that start with a plus sign (+) restore the",
"default.",
NULL};
X
static void Syntax (badOption)
X    char *badOption;
{
X    struct _options *opt;
X    int col;
X
X    fprintf (stderr, "%s:  bad command line option \"%s\"\r\n\n",
X	     ProgramName, badOption);
X
X    fprintf (stderr, "usage:  %s", ProgramName);
X    col = 8 + strlen(ProgramName);
X    for (opt = options; opt->opt; opt++) {
X	int len = 3 + strlen(opt->opt);	 /* space [ string ] */
X	if (col + len > 79) {
X	    fprintf (stderr, "\r\n   ");  /* 3 spaces */
X	    col = 3;
X	}
X	fprintf (stderr, " [%s]", opt->opt);
X	col += len;
X    }
X
X    fprintf (stderr, "\r\n\nType %s -help for a full description.\r\n\n",
X	     ProgramName);
X    exit (1);
}
X
static void Help ()
{
X    struct _options *opt;
X    char **cpp;
X
X    fprintf (stderr, "usage:\n        %s [-options ...] [-e command args]\n\n",
X	     ProgramName);
X    fprintf (stderr, "where options include:\n");
X    for (opt = options; opt->opt; opt++) {
X	fprintf (stderr, "    %-28s %s\n", opt->opt, opt->desc);
X    }
X
X    putc ('\n', stderr);
X    for (cpp = message; *cpp; cpp++) {
X	fputs (*cpp, stderr);
X	putc ('\n', stderr);
X    }
X    putc ('\n', stderr);
X
X    exit (0);
}
X
#ifdef KTERM
static void Version ()
{
X    fprintf (stderr, "kterm: version %s (patchlevel %d)\n", KTERM_VERSION,
X             patchlevel);
X    fprintf (stderr, "       with");
#ifdef KTERM_KANJI
X    fprintf (stderr, " [KTERM_KANJI]");
# ifdef KTERM_HANZI
X    fprintf(stderr, " [KTERM_HANZI]");
# endif
# ifdef KTERM_HANGUL
X    fprintf(stderr, " [KTERM_HANGUL]");
# endif
# ifdef MB_WSEL
X    fprintf(stderr, " [MB_WSEL]");
# endif
#endif
#ifdef KTERM_KCONV
X    fprintf (stderr, " [KTERM_KCONV]");
#endif
#ifdef KTERM_CTEXT
X    fprintf(stderr, " [KTERM_CTEXT]");
#endif /* KTERM_CTEXT */
#ifdef COLOR_TEXT
X    fprintf(stderr, " [COLOR_TEXT]");
#endif /* COLOR_TEXT */
#ifdef STATUSLINE
X    fprintf (stderr, " [STATUSLINE]");
#endif
#ifdef KEEPALIVE
X    fprintf (stderr, " [KEEPALIVE]");
#endif
X    fprintf (stderr, " options.\n");
X
X    exit (0);
}
#endif /* KTERM */
X
extern WidgetClass xtermWidgetClass;
X
Arg ourTopLevelShellArgs[] = {
X	{ XtNallowShellResize, (XtArgVal) TRUE },	
X	{ XtNinput, (XtArgVal) TRUE },
};
int number_ourTopLevelShellArgs = 2;
X	
XXtAppContext app_con;
Widget toplevel;
Bool waiting_for_initial_map;
X
main (argc, argv)
int argc;
char **argv;
{
X	register TScreen *screen;
X	register int i, pty;
X	int Xsocket, mode;
X	char *basename();
X	int xerror(), xioerror();
X
X	ProgramName = argv[0];
X
X	ttydev = (char *) malloc (strlen (TTYDEV) + 1);
X	ptydev = (char *) malloc (strlen (PTYDEV) + 1);
X	if (!ttydev || !ptydev) {
X	    fprintf (stderr, 
X	    	     "%s:  unable to allocate memory for ttydev or ptydev\n",
X		     ProgramName);
X	    exit (1);
X	}
X	strcpy (ttydev, TTYDEV);
X	strcpy (ptydev, PTYDEV);
X
#ifdef USE_SYSV_TERMIO
X	/* Initialization is done here rather than above in order
X	** to prevent any assumptions about the order of the contents
X	** of the various terminal structures (which may change from
X	** implementation to implementation).
X	*/
#if defined(macII) || defined(att)
X	d_tio.c_iflag = ICRNL|IXON;
X	d_tio.c_oflag = OPOST|ONLCR|TAB3;
X    	d_tio.c_cflag = B9600|CS8|CREAD|PARENB|HUPCL;
X    	d_tio.c_lflag = ISIG|ICANON|ECHO|ECHOE|ECHOK;
X
X	d_tio.c_line = 0;
X
X	d_tio.c_cc[VINTR] = CINTR;
X	d_tio.c_cc[VQUIT] = CQUIT;
X	d_tio.c_cc[VERASE] = CERASE;
X	d_tio.c_cc[VKILL] = CKILL;
X    	d_tio.c_cc[VEOF] = CEOF;
X	d_tio.c_cc[VEOL] = CNUL;
X	d_tio.c_cc[VEOL2] = CNUL;
X	d_tio.c_cc[VSWTCH] = CNUL;
X
#ifdef TIOCSLTC
X        d_ltc.t_suspc = CSUSP;		/* t_suspc */
X        d_ltc.t_dsuspc = CDSUSP;	/* t_dsuspc */
X        d_ltc.t_rprntc = 0;		/* reserved...*/
X        d_ltc.t_flushc = 0;
X        d_ltc.t_werasc = 0;
X        d_ltc.t_lnextc = 0;
#endif /* TIOCSLTC */
#else  /* else !macII */
X	d_tio.c_iflag = ICRNL|IXON;
X	d_tio.c_oflag = OPOST|ONLCR|TAB3;
#ifdef BAUD_0
X    	d_tio.c_cflag = CS8|CREAD|PARENB|HUPCL;
#else	/* !BAUD_0 */
X    	d_tio.c_cflag = B9600|CS8|CREAD|PARENB|HUPCL;
#endif	/* !BAUD_0 */
X    	d_tio.c_lflag = ISIG|ICANON|ECHO|ECHOE|ECHOK;
X	d_tio.c_line = 0;
X	d_tio.c_cc[VINTR] = 0x7f;		/* DEL  */
X	d_tio.c_cc[VQUIT] = '\\' & 0x3f;	/* '^\'	*/
X	d_tio.c_cc[VERASE] = '#';		/* '#'	*/
X	d_tio.c_cc[VKILL] = '@';		/* '@'	*/
X    	d_tio.c_cc[VEOF] = 'D' & 0x3f;		/* '^D'	*/
X	d_tio.c_cc[VEOL] = '@' & 0x3f;		/* '^@'	*/
#ifdef VSWTCH
X	d_tio.c_cc[VSWTCH] = '@' & 0x3f;	/* '^@'	*/
#endif	/* VSWTCH */
X	/* now, try to inherit tty settings */
X	{
X	    int i;
X
X	    for (i = 0; i <= 2; i++) {
X		struct termio deftio;
X		if (ioctl (i, TCGETA, &deftio) == 0) {
X		    d_tio.c_cc[VINTR] = deftio.c_cc[VINTR];
X		    d_tio.c_cc[VQUIT] = deftio.c_cc[VQUIT];
X		    d_tio.c_cc[VERASE] = deftio.c_cc[VERASE];
X		    d_tio.c_cc[VKILL] = deftio.c_cc[VKILL];
X		    d_tio.c_cc[VEOF] = deftio.c_cc[VEOF];
X		    d_tio.c_cc[VEOL] = deftio.c_cc[VEOL];
#ifdef VSWTCH
X		    d_tio.c_cc[VSWTCH] = deftio.c_cc[VSWTCH];
#endif /* VSWTCH */
X		    break;
X		}
X	    }
X	}
#ifdef TIOCSLTC
X        d_ltc.t_suspc = '\000';		/* t_suspc */
X        d_ltc.t_dsuspc = '\000';	/* t_dsuspc */
X        d_ltc.t_rprntc = '\377';	/* reserved...*/
X        d_ltc.t_flushc = '\377';
X        d_ltc.t_werasc = '\377';
X        d_ltc.t_lnextc = '\377';
#endif	/* TIOCSLTC */
#ifdef TIOCLSET
X	d_lmode = 0;
#endif	/* TIOCLSET */
#endif  /* macII */
#endif	/* USE_SYSV_TERMIO */
X
X	/* Init the Toolkit. */
#ifdef KTERM
X	toplevel = XtAppInitialize (&app_con, "KTerm", 
#else /* !KTERM */
X	toplevel = XtAppInitialize (&app_con, "XTerm", 
#endif /* !KTERM */
X				    optionDescList, XtNumber(optionDescList), 
X				    &argc, argv, fallback_resources, 
X				    NULL, 0);
X
X	XtGetApplicationResources( toplevel, &resource, application_resources,
X				   XtNumber(application_resources), NULL, 0 );
X
X	waiting_for_initial_map = resource.wait_for_map;
X
#ifdef KEEPALIVE
X	if (resource.keepalive) {
X		int on = 1;
X		(void)setsockopt(ConnectionNumber(XtDisplay(toplevel)),
X				SOL_SOCKET, SO_KEEPALIVE,
X				(char *)&on, sizeof(on));
X	}
#endif /* KEEPALIVE */
X	/*
X	 * fill in terminal modes
X	 */
X	if (resource.tty_modes) {
X	    int n = parse_tty_modes (resource.tty_modes,
X				     ttymodelist, NXTTYMODES);
X	    if (n < 0) {
X		fprintf (stderr, "%s:  bad tty modes \"%s\"\n",
X			 ProgramName, resource.tty_modes);
X	    } else if (n > 0) {
X		override_tty_modes = 1;
X	    }
X	}
X
X	xterm_name = resource.xterm_name;
X	sunFunctionKeys = resource.sunFunctionKeys;
#ifdef KTERM
X	if (strcmp(xterm_name, "-") == 0) xterm_name = "kterm";
#else /* KTERM */
X	if (strcmp(xterm_name, "-") == 0) xterm_name = "xterm";
#endif /* KTERM */
X	if (resource.icon_geometry != NULL) {
X	    int scr, junk;
X	    int ix, iy;
X	    Arg args[2];
X
X	    for(scr = 0;	/* yyuucchh */
X		XtScreen(toplevel) != ScreenOfDisplay(XtDisplay(toplevel),scr);
X		scr++);
X
X	    args[0].name = XtNiconX;
X	    args[1].name = XtNiconY;
X	    XGeometry(XtDisplay(toplevel), scr, resource.icon_geometry, "",
X		      0, 0, 0, 0, 0, &ix, &iy, &junk, &junk);
X	    args[0].value = (XtArgVal) ix;
X	    args[1].value = (XtArgVal) iy;
X	    XtSetValues( toplevel, args, 2);
X	}
X
X	XtSetValues (toplevel, ourTopLevelShellArgs, 
X		     number_ourTopLevelShellArgs);
X
X
X	/* Parse the rest of the command line */
X	for (argc--, argv++ ; argc > 0 ; argc--, argv++) {
X	    if(**argv != '-') Syntax (*argv);
X
X	    switch(argv[0][1]) {
X	     case 'h':
X		Help ();
X		/* NOTREACHED */
#ifdef KTERM
X	     case 'v':
X		Version ();
X		/* NOTREACHED */
#endif /* KTERM */
X	     case 'C':
#ifdef TIOCCONS
X		Console = TRUE;
#endif	/* TIOCCONS */
X		continue;
X	     case 'S':
X		sscanf(*argv + 2, "%c%c%d", passedPty, passedPty+1,
X		 &am_slave);
X		if (am_slave <= 0) Syntax(*argv);
X		continue;
#ifdef DEBUG
X	     case 'D':
X		debug = TRUE;
X		continue;
#endif	/* DEBUG */
X	     case 'e':
X		if (argc <= 1) Syntax (*argv);
X		command_to_exec = ++argv;
X		break;
X	     default:
X		Syntax (*argv);
X	    }
X	    break;
X	}
X
X	XawSimpleMenuAddGlobalActions (XtWidgetToApplicationContext(toplevel));
X	XtRegisterGrabAction (HandlePopupMenu, True,
X			      (ButtonPressMask|ButtonReleaseMask),
X			      GrabModeAsync, GrabModeAsync);
X
X        term = (XtermWidget) XtCreateManagedWidget(
X	    "vt100", xtermWidgetClass, toplevel, NULL, 0);
X            /* this causes the initialize method to be called */
X
X        screen = &term->screen;
X
X	term->flags = WRAPAROUND;
X	update_autowrap();
X	if (!screen->jumpscroll) {
X	    term->flags |= SMOOTHSCROLL;
X	    update_jumpscroll();
X	}
X	if (term->misc.reverseWrap) {
X	    term->flags |= REVERSEWRAP;
X	    update_reversewrap();
X	}
X	if (term->misc.re_verse) {
X	    term->flags |= REVERSE_VIDEO;
X	    update_reversevideo();
X	}
X
#ifdef KTERM_KANJI
X        if (!term->misc.lang) {
X            XtWarning("Language choice not found.");
X            term->misc.lang = KTERM_DEFAULT_LANG;
X            term->misc.k_m = KTERM_DEFAULT_MODE;
X        }
X
X        switch(term->misc.lang[0]) {
#ifdef KTERM_HANZI
X          case 'c':
X          case 'C':
X            (void)load_hzconv_table(term->misc.hz_gb2big_tbl);
X            (void)load_hzconv_table(term->misc.hz_big2gb_tbl);
X            if (term->misc.hz_m) {
X                switch (term->misc.hz_m[0]) {
X                  case 'g': case 'G':
X                    term->flags |= GUOBIAO_HANZI;
X                    break;
X                  case 'b': case 'B':
X                    term->flags |= BIG5_HANZI;
X                    update_big5mode();
X                    break;
X                  case 's': case 'S':
X                    term->flags |= SGB_HANZI;
X                    update_sgbmode();
X                    break;
X                }
X            }
X            break;
#endif /* KTERM_HANZI */
#ifdef KTERM_HANGUL
X          case 'k':
X          case 'K':
X            load_hgconv_table(term->misc.hg_n2ks_tbl);
X            if (term->misc.hg_m) {
X                switch(term->misc.hg_m[0]) {
X                  case 'k': case 'K':
X                    term->flags |= KS_HANGUL;
X                    update_ksmode();
X                    break;
X                  case 'n': case 'N':
X                    term->flags |= NBYTE_HANGUL;
X                    update_nbmode();
X                    break;
X                }
X            }
X            break;
#endif /* KTERM_HANGUL */
X
/*
X * The default language will be Japanese, so set necessary flags.
X */
X
X          default:
X	    switch (term->misc.k_m[0]) {
X		case 'j': case 'J':
X		    break;
X		case 'e': case 'E': case 'x': case 'X': case 'u': case 'U':
X		    term->flags |= EUC_KANJI;
X		    update_eucmode();
X		    break;
X		case 's': case 'S': case 'm': case 'M':
X		    term->flags |= SJIS_KANJI;
X		    update_sjismode();
X		    break;
X	    }
X	}
#endif /* KTERM_KANJI */
X
X	inhibit = 0;
X	if (term->misc.logInhibit) 	    inhibit |= I_LOG;
X	if (term->misc.signalInhibit)		inhibit |= I_SIGNAL;
X	if (term->misc.tekInhibit)			inhibit |= I_TEK;
X
#ifdef STATUSLINE
X	screen->reversestatus = !term->misc.statusnormal;
#endif /* STATUSLINE */
X
X	term->initflags = term->flags;
X
/*
X * Set title and icon name if not specified
X */
X
X	if (command_to_exec) {
X	    Arg args[2];
X
X	    if (!resource.title) {
X		if (command_to_exec) {
X		    resource.title = basename (command_to_exec[0]);
X		} /* else not reached */
X	    }
X
X	    if (!resource.icon_name) 
X	      resource.icon_name = resource.title;
X	    XtSetArg (args[0], XtNtitle, resource.title);
X	    XtSetArg (args[1], XtNiconName, resource.icon_name);		
X
X	    XtSetValues (toplevel, args, 2);
X	}
X
X
X	if(inhibit & I_TEK)
X		screen->TekEmu = FALSE;
X
X	if(screen->TekEmu && !TekInit())
X		exit(ERROR_INIT);
X
X	/* set up stderr properly */
X	i = -1;
#ifdef DEBUG
X	if(debug)
X		i = open ("xterm.debug.log", O_WRONLY | O_CREAT | O_TRUNC,
X		 0666);
#endif	/* DEBUG */
X	if(i >= 0) {
#ifdef USE_SYSV_TERMIO
X		/* SYSV has another pointer which should be part of the
X		** FILE structure but is actually a seperate array.
X		*/
X		unsigned char *old_bufend;
X
X		old_bufend = (unsigned char *) _bufend(stderr);
X		stderr->_file = i;
X		_bufend(stderr) = old_bufend;
#else	/* USE_SYSV_TERMIO */
X		stderr->_file = i;
#endif	/* USE_SYSV_TERMIO */
X
X		/* mark this file as close on exec */
X		(void) fcntl(i, F_SETFD, 1);
X	}
X
X	/* open a terminal for client */
X	get_terminal ();
X	spawn ();
X	/* Child process is out there, let's catch it's termination */
X	signal (SIGCHLD, reapchild);
X
X	/* Realize procs have now been executed */
X
X	Xsocket = screen->display->fd;
X	pty = screen->respond;
X
X	if (am_slave) { /* Write window id so master end can read and use */
X	    char buf[80];
X
X	    buf[0] = '\0';
X	    sprintf (buf, "%lx\n", 
X	    	     screen->TekEmu ? XtWindow (XtParent (tekWidget)) :
X				      XtWindow (XtParent (term)));
X	    write (pty, buf, strlen (buf));
X	}
X
X	if (term->misc.log_on) {
X		StartLog(screen);
X	}
X	screen->inhibit = inhibit;
X
#ifdef USE_SYSV_TERMIO
X	if (0 > (mode = fcntl(pty, F_GETFL, 0)))
X		Error();
X	mode |= O_NDELAY;
X	if (fcntl(pty, F_SETFL, mode))
X		Error();
#else	/* USE_SYSV_TERMIO */
X	mode = 1;
X	if (ioctl (pty, FIONBIO, (char *)&mode) == -1) SysError (ERROR_FIONBIO);
#endif	/* USE_SYSV_TERMIO */
X	
X	pty_mask = 1 << pty;
X	X_mask = 1 << Xsocket;
X	Select_mask = pty_mask | X_mask;
X	max_plus1 = (pty < Xsocket) ? (1 + Xsocket) : (1 + pty);
X
#ifdef DEBUG
X	if (debug) printf ("debugging on\n");
#endif	/* DEBUG */
X	XSetErrorHandler(xerror);
X	XSetIOErrorHandler(xioerror);
X	for( ; ; ) {
X		if(screen->TekEmu) {
X			TekRun();
X		} else
X			VTRun();
X	}
}
X
char *basename(name)
char *name;
{
X	register char *cp;
X	char *rindex();
X
X	return((cp = rindex(name, '/')) ? cp + 1 : name);
}
X
/* This function opens up a pty master and stuffs it's value into pty.
X * If it finds one, it returns a value of 0.  If it does not find one,
X * it returns a value of !0.  This routine is designed to be re-entrant,
X * so that if a pty master is found and later, we find that the slave
X * has problems, we can re-enter this function and get another one.
X */
X
get_pty (pty)
int *pty;
{
X	static int devindex, letter = 0;
X
#ifdef att
X	if ((*pty = open ("/dev/ptmx", O_RDWR)) < 0) {
X	    return 1;
X	}
X	return 0;
#else /* !att, need lots of code */
X
#if defined(umips) && defined (SYSTYPE_SYSV)
X	struct stat fstat_buf;
X
X	*pty = open ("/dev/ptc", O_RDWR);
X	if (*pty < 0 || (fstat (*pty, &fstat_buf)) < 0) {
X	  return(1);
X	}
X	sprintf (ttydev, "/dev/ttyq%d", minor(fstat_buf.st_rdev));
X	sprintf (ptydev, "/dev/ptyq%d", minor(fstat_buf.st_rdev));
X	if ((*tty = open (ttydev, O_RDWR)) < 0) {
X	  close (*pty);
X	  return(1);
X	}
X	/* got one! */
X	return(0);
#else /* not (umips && SYSTYPE_SYSV) */
#ifdef CRAY
X	for (; devindex < 256; devindex++) {
X	    sprintf (ttydev, "/dev/ttyp%03d", devindex);
X	    sprintf (ptydev, "/dev/pty/%03d", devindex);
X
X	    if ((*pty = open (ptydev, O_RDWR)) >= 0) {
X		/* We need to set things up for our next entry
X		 * into this function!
X		 */
X		(void) devindex++;
X		return(0);
X	    }
X	}
#else /* !CRAY */
X	while (PTYCHAR1[letter]) {
X	    ttydev [strlen(ttydev) - 2]  = ptydev [strlen(ptydev) - 2] =
X		    PTYCHAR1 [letter];
X
X	    while (PTYCHAR2[devindex]) {
X		ttydev [strlen(ttydev) - 1] = ptydev [strlen(ptydev) - 1] =
X			PTYCHAR2 [devindex];
X		if ((*pty = open (ptydev, O_RDWR)) >= 0) {
X			/* We need to set things up for our next entry
X			 * into this function!
X			 */
X			(void) devindex++;
X			return(0);
X		}
X		devindex++;
X	    }
X	    devindex = 0;
X	    (void) letter++;
X	}
#endif /* CRAY else not CRAY */
X	/* We were unable to allocate a pty master!  Return an error
X	 * condition and let our caller terminate cleanly.
X	 */
X	return(1);
#endif /* umips && SYSTYPE_SYSV */
#endif /* att */
}
X
get_terminal ()
/* 
X * sets up X and initializes the terminal structure except for term.buf.fildes.
X */
{
X	register TScreen *screen = &term->screen;
X	
X	screen->arrow = make_colored_cursor (XC_left_ptr, 
X					     screen->mousecolor,
X					     screen->mousecolorback);
}
X
/*
X * The only difference in /etc/termcap between 4014 and 4015 is that 
X * the latter has support for switching character sets.  We support the
X * 4015 protocol, but ignore the character switches.  Therefore, we should
X * probably choose 4014 over 4015.
X */
X
static char *tekterm[] = {
X	"tek4014",
X	"tek4015",		/* has alternate character set switching */
X	"tek4013",
X	"tek4010",
X	"dumb",
X	0
};
X
static char *vtterm[] = {
#ifdef KTERM
X	"kterm",
#endif
#ifdef USE_X11TERM
X	"x11term",		/* for people who want special term name */
#endif
X	"xterm",		/* the prefered name, should be fastest */
X	"vt102",
X	"vt100",
X	"ansi",
X	"dumb",
X	0
};
X
/* ARGSUSED */
SIGNAL_T hungtty(i)
X	int i;
{
X	longjmp(env, 1);
X	SIGNAL_RETURN;
}
X
#ifdef USE_HANDSHAKE
typedef enum {		/* c == child, p == parent                        */
X	PTY_BAD,	/* c->p: can't open pty slave for some reason     */
X	PTY_FATALERROR,	/* c->p: we had a fatal error with the pty        */
X	PTY_GOOD,	/* c->p: we have a good pty, let's go on          */
X	PTY_NEW,	/* p->c: here is a new pty slave, try this        */
X	PTY_NOMORE,	/* p->c; no more pty's, terminate                 */
X	UTMP_ADDED,	/* c->p: utmp entry has been added                */
X	UTMP_TTYSLOT,	/* c->p: here is my ttyslot                       */
X	PTY_EXEC	/* p->c: window has been mapped the first time    */
} status_t;
X
typedef struct {
X	status_t status;
X	int error;
X	int fatal_error;
X	int tty_slot;
X	int rows;
X	int cols;
X	char buffer[1024];
} handshake_t;
X
/* HsSysError()
X *
X * This routine does the equivalent of a SysError but it handshakes
X * over the errno and error exit to the master process so that it can
X * display our error message and exit with our exit code so that the
X * user can see it.
X */
X
void
HsSysError(pf, error)
int pf;
int error;
{
X	handshake_t handshake;
X
X	handshake.status = PTY_FATALERROR;
X	handshake.error = errno;
X	handshake.fatal_error = error;
X	strcpy(handshake.buffer, ttydev);
X	write(pf, &handshake, sizeof(handshake));
X	exit(error);
}
X
static int pc_pipe[2];	/* this pipe is used for parent to child transfer */
static int cp_pipe[2];	/* this pipe is used for child to parent transfer */
X
first_map_occurred ()
{
X    handshake_t handshake;
X    register TScreen *screen = &term->screen;
X
X    if (screen->max_row > 0 && screen->max_col > 0) {
X	handshake.status = PTY_EXEC;
X	handshake.rows = screen->max_row;
X	handshake.cols = screen->max_col;
X	write (pc_pipe[1], (char *) &handshake, sizeof(handshake));
X	close (cp_pipe[0]);
X	close (pc_pipe[1]);
X	waiting_for_initial_map = False;
X    }
}
#else
/*
X * temporary hack to get xterm working on att ptys
X */
first_map_occurred ()
{
X    return;
}
#define HsSysError(a,b)
#endif /* USE_HANDSHAKE else !USE_HANDSHAKE */
X
X
spawn ()
/* 
X *  Inits pty and tty and forks a login process.
X *  Does not close fd Xsocket.
X *  If slave, the pty named in passedPty is already open for use
X */
{
X	extern char *SysErrorMsg();
X	register TScreen *screen = &term->screen;
X	int Xsocket = screen->display->fd;
#ifdef USE_HANDSHAKE
X	handshake_t handshake;
#else
X	int fds[2];
#endif
X	int tty = -1;
X	int discipline;
X	int done;
#ifdef USE_SYSV_TERMIO
X	struct termio tio;
X	struct termio dummy_tio;
#ifdef TIOCLSET
X	unsigned lmode;
#endif	/* TIOCLSET */
#ifdef TIOCSLTC
X	struct ltchars ltc;
#endif	/* TIOCSLTC */
X	int one = 1;
X	int zero = 0;
X	int status;
#else	/* else not USE_SYSV_TERMIO */
X	unsigned lmode;
X	struct tchars tc;
X	struct ltchars ltc;
X	struct sgttyb sg;
#endif	/* USE_SYSV_TERMIO */
X
X	char termcap [1024];
X	char newtc [1024];
X	char *ptr, *shname, *shname_minus;
X	int i, no_dev_tty = FALSE;
#ifdef USE_SYSV_TERMIO
X	char *dev_tty_name = (char *) 0;
X	int fd;			/* for /etc/wtmp */
#endif	/* USE_SYSV_TERMIO */
X	char **envnew;		/* new environment */
X	char buf[32];
X	char *TermName = NULL;
X	int ldisc = 0;
#ifdef sun
#ifdef TIOCSSIZE
X	struct ttysize ts;
#endif	/* TIOCSSIZE */
#else	/* not sun */
#ifdef TIOCSWINSZ
X	struct winsize ws;
#endif	/* TIOCSWINSZ */
#endif	/* sun */
X	struct passwd *pw = NULL;
#ifdef UTMP
X	struct utmp utmp;
#ifdef LASTLOG
X	struct lastlog lastlog;
#endif	/* LASTLOG */
#endif	/* UTMP */
X
X	screen->uid = getuid();
X	screen->gid = getgid();
X
#ifdef SIGTTOU
X	/* so that TIOCSWINSZ || TIOCSIZE doesn't block */
X	signal(SIGTTOU,SIG_IGN);
#endif
X
X	if (am_slave) {
X		screen->respond = am_slave;
X		ptydev[strlen(ptydev) - 2] = ttydev[strlen(ttydev) - 2] =
X			passedPty[0];
X		ptydev[strlen(ptydev) - 1] = ttydev[strlen(ttydev) - 1] =
X			passedPty[1];
X
X		setgid (screen->gid);
X		setuid (screen->uid);
X	} else {
X		Bool tty_got_hung = False;
X
X 		/*
X 		 * Sometimes /dev/tty hangs on open (as in the case of a pty
X 		 * that has gone away).  Simply make up some reasonable
X 		 * defaults.
X 		 */
X 		signal(SIGALRM, hungtty);
X 		alarm(2);		/* alarm(1) might return too soon */
X 		if (! setjmp(env)) {
X 			tty = open ("/dev/tty", O_RDWR, 0);
X 			alarm(0);
X 		} else {
X			tty_got_hung = True;
X 			tty = -1;
X 			errno = ENXIO;
X 		}
X 		signal(SIGALRM, SIG_DFL);
X 
X		/*
X		 * Check results and ignore current control terminal if
X		 * necessary.  ENXIO is what is normally returned if there is
X		 * no controlling terminal, but some systems (e.g. SunOS 4.0)
X		 * seem to return EIO.
X		 */
X 		if (tty < 0) {
X			if (tty_got_hung || errno == ENXIO || errno == EIO) {
X				no_dev_tty = TRUE;
#ifdef USE_SYSV_TERMIO
X				tio = d_tio;
#ifdef TIOCSLTC
X				ltc = d_ltc;
#endif	/* TIOCSLTC */
#ifdef TIOCLSET
X				lmode = d_lmode;
#endif	/* TIOCLSET */
#else	/* not USE_SYSV_TERMIO */
X				sg = d_sg;
X				tc = d_tc;
X				discipline = d_disipline;
X				ltc = d_ltc;
X				lmode = d_lmode;
#endif	/* USE_SYSV_TERMIO */
X			} else {
X			    SysError(ERROR_OPDEVTTY);
X			}
X		} else {
X			/* get a copy of the current terminal's state */
X
#ifdef USE_SYSV_TERMIO
X			if(ioctl(tty, TCGETA, &tio) == -1)
X				SysError(ERROR_TIOCGETP);
#ifdef TIOCSLTC
X			if(ioctl(tty, TIOCGLTC, &ltc) == -1)
X				SysError(ERROR_TIOCGLTC);
#endif	/* TIOCSLTC */
#ifdef TIOCLSET
X			if(ioctl(tty, TIOCLGET, &lmode) == -1)
X				SysError(ERROR_TIOCLGET);
#endif	/* TIOCLSET */
#else	/* not USE_SYSV_TERMIO */
X			if(ioctl(tty, TIOCGETP, (char *)&sg) == -1)
X				SysError (ERROR_TIOCGETP);
X			if(ioctl(tty, TIOCGETC, (char *)&tc) == -1)
X				SysError (ERROR_TIOCGETC);
X			if(ioctl(tty, TIOCGETD, (char *)&discipline) == -1)
X				SysError (ERROR_TIOCGETD);
X			if(ioctl(tty, TIOCGLTC, (char *)&ltc) == -1)
X				SysError (ERROR_TIOCGLTC);
X			if(ioctl(tty, TIOCLGET, (char *)&lmode) == -1)
X				SysError (ERROR_TIOCLGET);
#endif	/* USE_SYSV_TERMIO */
X			close (tty);
X			/* tty is no longer an open fd! */
X			tty = -1;
X		}
X
#ifdef 	PUCC_PTYD
X		if(-1 == (screen->respond = openrpty(ttydev, ptydev,
X				(resource.utmpInhibit ?  OPTY_NOP : OPTY_LOGIN),
X				getuid(), XDisplayString(screen->display)))) {
#else /* not PUCC_PTYD */
X		if (get_pty (&screen->respond)) {
#endif /* PUCC_PTYD */
X			/*  no ptys! */
X			(void) fprintf(stderr, "%s: no available ptys\n",
X				       xterm_name);
X			exit (ERROR_PTYS);
#ifdef PUCC_PTYD
X		}
#else
X		}			/* keep braces balanced for emacs */
#endif
#ifdef PUCC_PTYD
X		  else {
X			/*
X			 *  set the fd of the master in a global var so
X			 *  we can undo all this on exit
X			 *
X			 */
X			Ptyfd = screen->respond;
X		  }
#endif /* PUCC_PTYD */
X	}
X
X	/* avoid double MapWindow requests */
X	XtSetMappedWhenManaged( screen->TekEmu ? XtParent(tekWidget) :
X			        XtParent(term), False );
X        /* Realize the Tek or VT widget, depending on which mode we're in.
X           If VT mode, this calls VTRealize (the widget's Realize proc) */
X        XtRealizeWidget (screen->TekEmu ? XtParent(tekWidget) :
X			 XtParent(term));
X
X	if(screen->TekEmu) {
X		envnew = tekterm;
X		ptr = newtc;
X	} else {
X		envnew = vtterm;
X		ptr = termcap;
X	}
X	TermName = NULL;
X	if (resource.term_name) {
X	    if (tgetent (ptr, resource.term_name) == 1) {
X		TermName = resource.term_name;
X		if (!screen->TekEmu)
X		    resize (screen, TermName, termcap, newtc);
X	    } else {
X		fprintf (stderr, "%s:  invalid termcap entry \"%s\".\n",
X			 ProgramName, resource.term_name);
X	    }
X	}
X	if (!TermName) {
X	    while (*envnew != NULL) {
X		if(tgetent(ptr, *envnew) == 1) {
X			TermName = *envnew;
X			if(!screen->TekEmu)
X			    resize(screen, TermName, termcap, newtc);
X			break;
X		}
X		envnew++;
X	    }
X	    if (TermName == NULL) {
X		fprintf (stderr, "%s:  unable to find usable termcap entry.\n",
X			 ProgramName);
X		Exit (1);
X	    }
X	}
X
#ifdef sun
#ifdef TIOCSSIZE
X	/* tell tty how big window is */
X	if(screen->TekEmu) {
X		ts.ts_lines = 38;
X		ts.ts_cols = 81;
X	} else {
X		ts.ts_lines = screen->max_row + 1;
X		ts.ts_cols = screen->max_col + 1;
X	}
#endif	/* TIOCSSIZE */
#else	/* not sun */
#ifdef TIOCSWINSZ
X	/* tell tty how big window is */
X	if(screen->TekEmu) {
X		ws.ws_row = 38;
X		ws.ws_col = 81;
X		ws.ws_xpixel = TFullWidth(screen);
X		ws.ws_ypixel = TFullHeight(screen);
X	} else {
X		ws.ws_row = screen->max_row + 1;
X		ws.ws_col = screen->max_col + 1;
X		ws.ws_xpixel = FullWidth(screen);
X		ws.ws_ypixel = FullHeight(screen);
X	}
#endif	/* TIOCSWINSZ */
#endif	/* sun */
X
X	if (!am_slave) {
#ifdef USE_HANDSHAKE
X	    if (pipe(pc_pipe) || pipe(cp_pipe))
X		SysError (ERROR_FORK);
#endif
X	    if ((screen->pid = fork ()) == -1)
X		SysError (ERROR_FORK);
X		
X	    if (screen->pid == 0) {
X		/*
X		 * now in child process
X		 */
X		extern char **environ;
X		int pgrp = getpid();
#ifdef USE_SYSV_TERMIO
X		char numbuf[12];
#endif	/* USE_SYSV_TERMIO */
X
#ifndef USE_HANDSHAKE
X		int ptyfd;
X
X		setpgrp();
X		grantpt (screen->respond);
X		unlockpt (screen->respond);
X		if ((ptyfd = open (ptsname(screen->respond), O_RDWR)) < 0) {
X		    SysError (1);
X		}
X		if (ioctl (ptyfd, I_PUSH, "ptem") < 0) {
X		    SysError (2);
X		}
X		if (!getenv("CONSEM") && ioctl (ptyfd, I_PUSH, "consem") < 0) {
X		    SysError (3);
X		}
X		if (ioctl (ptyfd, I_PUSH, "ldterm") < 0) {
X		    SysError (4);
X		}
X		tty = ptyfd;
X		close (screen->respond);
#ifdef TIOCSWINSZ
X                /* tell tty how big window is */
X                if(screen->TekEmu) {
X                        ws.ws_row = 24;
X                        ws.ws_col = 80;
X                        ws.ws_xpixel = TFullWidth(screen);
X                        ws.ws_ypixel = TFullHeight(screen);
X                } else {
X                        ws.ws_row = screen->max_row + 1;
X                        ws.ws_col = screen->max_col + 1;
X                        ws.ws_xpixel = FullWidth(screen);
X                        ws.ws_ypixel = FullHeight(screen);
X                }
#endif
X
X
#else /* USE_HANDSHAKE:  warning, goes for a long ways */
X		/* close parent's sides of the pipes */
X		close (cp_pipe[0]);
X		close (pc_pipe[1]);
X
X		/* Make sure that our sides of the pipes are not in the
X		 * 0, 1, 2 range so that we don't fight with stdin, out
X		 * or err.
X		 */
X		if (cp_pipe[1] <= 2) {
X			if ((i = fcntl(cp_pipe[1], F_DUPFD, 3)) >= 0) {
X				(void) close(cp_pipe[1]);
X				cp_pipe[1] = i;
X			}
X		}
X		if (pc_pipe[0] <= 2) {
X			if ((i = fcntl(pc_pipe[0], F_DUPFD, 3)) >= 0) {
X				(void) close(pc_pipe[0]);
X				pc_pipe[0] = i;
X			}
X		}
X
X		/* we don't need the socket, or the pty master anymore */
X		close (Xsocket);
X		close (screen->respond);
X
X		/* Now is the time to set up our process group and
X		 * open up the pty slave.
X		 */
#ifdef	USE_SYSV_PGRP
X		(void) setpgrp();
#endif	/* USE_SYSV_PGRP */
X		while (1) {
#ifdef TIOCNOTTY
X			if ((tty = open ("/dev/tty", 2)) >= 0) {
X				ioctl (tty, TIOCNOTTY, (char *) NULL);
X				close (tty);
X			}
#endif	/* TIOCNOTTY */
X			if ((tty = open(ttydev, O_RDWR, 0)) >= 0) {
#ifdef	USE_SYSV_PGRP
X				/* We need to make sure that we are acutally
X				 * the process group leader for the pty.  If
X				 * we are, then we should now be able to open
X				 * /dev/tty.
X				 */
X				if ((i = open("/dev/tty", O_RDWR, 0)) >= 0) {
X					/* success! */
X					close(i);
X					break;
X				}
#else	/* USE_SYSV_PGRP */
X				break;
#endif	/* USE_SYSV_PGRP */
X			}
X
#ifdef TIOCSCTTY
X			ioctl(tty, TIOCSCTTY, 0);
#endif
X			/* let our master know that the open failed */
X			handshake.status = PTY_BAD;
X			handshake.error = errno;
X			strcpy(handshake.buffer, ttydev);
X			write(cp_pipe[1], (char *) &handshake,
X			    sizeof(handshake));
X
X			/* get reply from parent */
X			i = read(pc_pipe[0], (char *) &handshake,
X			    sizeof(handshake));
X			if (i <= 0) {
X				/* parent terminated */
X				exit(1);
X			}
X
X			if (handshake.status == PTY_NOMORE) {
X				/* No more ptys, let's shutdown. */
X				exit(1);
X			}
X
X			/* We have a new pty to try */
X			free(ttydev);
X			ttydev = malloc((unsigned)
X			    (strlen(handshake.buffer) + 1));
X			strcpy(ttydev, handshake.buffer);
X		}
X
X		/* use the same tty name that everyone else will use
X		** (from ttyname)
X		*/
X		if (ptr = ttyname(tty))
X		{
X			/* it may be bigger */
X			ttydev = realloc (ttydev, (unsigned) (strlen(ptr) + 1));
X			(void) strcpy(ttydev, ptr);
X		}
X
#endif /* !USE_HANDSHAKE else USE_HANDSHAKE - from near fork */
X
#ifdef USE_TTY_GROUP
X	{ 
#include <grp.h>
X		struct group *ttygrp;
X		if (ttygrp = getgrnam("tty")) {
X			/* change ownership of tty to real uid, "tty" gid */
X			chown (ttydev, screen->uid, ttygrp->gr_gid);
X			chmod (ttydev, 0620);
X		}
X		else {
X			/* change ownership of tty to real group and user id */
X			chown (ttydev, screen->uid, screen->gid);
X			chmod (ttydev, 0622);
X		}
X		endgrent();
X	}
#else /* else !USE_TTY_GROUP */
X		/* change ownership of tty to real group and user id */
X		chown (ttydev, screen->uid, screen->gid);
X
X		/* change protection of tty */
X		chmod (ttydev, 0622);
#endif /* USE_TTY_GROUP */
X
X		/*
X		 * set up the tty modes
X		 */
X		{
#ifdef USE_SYSV_TERMIO
#ifdef umips
X		    /* If the control tty had its modes screwed around with,
X		       eg. by lineedit in the shell, or emacs, etc. then tio
X		       will have bad values.  Let's just get termio from the
X		       new tty and tailor it.  */
X		    if (ioctl (tty, TCGETA, &tio) == -1)
X		      SysError (ERROR_TIOCGETP);
X		    tio.c_lflag |= ECHOE;
#endif /* umips */
X		    /* Now is also the time to change the modes of the
X		     * child pty.
X		     */
X		    /* input: nl->nl, don't ignore cr, cr->nl */
X		    tio.c_iflag &= ~(INLCR|IGNCR);
X		    tio.c_iflag |= ICRNL;
X		    /* ouput: cr->cr, nl is not return, no delays, ln->cr/nl */
X		    tio.c_oflag &=
X		     ~(OCRNL|ONLRET|NLDLY|CRDLY|TABDLY|BSDLY|VTDLY|FFDLY);
X		    tio.c_oflag |= ONLCR;
#ifdef BAUD_0
X		    /* baud rate is 0 (don't care) */
X		    tio.c_cflag &= ~(CBAUD);
#else	/* !BAUD_0 */
X		    /* baud rate is 9600 (nice default) */
X		    tio.c_cflag &= ~(CBAUD);
X		    tio.c_cflag |= B9600;
#endif	/* !BAUD_0 */
X		    /* enable signals, canonical processing (erase, kill, etc),
X		    ** echo
X		    */
X		    tio.c_lflag |= ISIG|ICANON|ECHO;
X		    /* reset EOL to defalult value */
X		    tio.c_cc[VEOL] = '@' & 0x3f;		/* '^@'	*/
X		    /* certain shells (ksh & csh) change EOF as well */
X		    tio.c_cc[VEOF] = 'D' & 0x3f;		/* '^D'	*/
X
#define TMODE(ind,var) if (ttymodelist[ind].set) var = ttymodelist[ind].value;
X		    if (override_tty_modes) {
X			/* sysv-specific */
X			TMODE (XTTYMODE_intr, tio.c_cc[VINTR]);
X			TMODE (XTTYMODE_quit, tio.c_cc[VQUIT]);
X			TMODE (XTTYMODE_erase, tio.c_cc[VERASE]);
X			TMODE (XTTYMODE_kill, tio.c_cc[VKILL]);
X			TMODE (XTTYMODE_eof, tio.c_cc[VEOF]);
X			TMODE (XTTYMODE_eol, tio.c_cc[VEOL]);
#ifdef VSWTCH
X			TMODE (XTTYMODE_swtch, d_tio.c_cc[VSWTCH]);
#endif
#ifdef TIOCSLTC
X			/* both SYSV and BSD have ltchars */
X			TMODE (XTTYMODE_susp, ltc.t_suspc);
X			TMODE (XTTYMODE_dsusp, ltc.t_dsuspc);
X			TMODE (XTTYMODE_rprnt, ltc.t_rprntc);
X			TMODE (XTTYMODE_flush, ltc.t_flushc);
X			TMODE (XTTYMODE_weras, ltc.t_werasc);
X			TMODE (XTTYMODE_lnext, ltc.t_lnextc);
#endif
X		    }
#undef TMODE
X
X		    if (ioctl (tty, TCSETA, &tio) == -1)
X			    HsSysError(cp_pipe[1], ERROR_TIOCSETP);
#ifdef TIOCSLTC
X		    if (ioctl (tty, TIOCSLTC, &ltc) == -1)
X			    HsSysError(cp_pipe[1], ERROR_TIOCSETC);
#endif	/* TIOCSLTC */
#ifdef TIOCLSET
X		    if (ioctl (tty, TIOCLSET, (char *)&lmode) == -1)
X			    HsSysError(cp_pipe[1], ERROR_TIOCLSET);
#endif	/* TIOCLSET */
#ifdef TIOCCONS
X		    if (Console) {
X			    int on = 1;
X			    if (ioctl (tty, TIOCCONS, (char *)&on) == -1)
X				    HsSysError(cp_pipe[1], ERROR_TIOCCONS);
X		    }
#endif	/* TIOCCONS */
#else	/* USE_SYSV_TERMIO */
#ifdef KTERM
X		    sg.sg_flags &= ~(ALLDELAY | XTABS | CBREAK | RAW
X						| EVENP | ODDP);
#else /* !KTERM */
X		    sg.sg_flags &= ~(ALLDELAY | XTABS | CBREAK | RAW);
#endif /* !KTERM */
X		    sg.sg_flags |= ECHO | CRMOD;
X		    /* make sure speed is set on pty so that editors work right*/
X		    sg.sg_ispeed = B9600;
X		    sg.sg_ospeed = B9600;
X		    /* reset t_brkc to default value */
X		    tc.t_brkc = -1;
X
#define TMODE(ind,var) if (ttymodelist[ind].set) var = ttymodelist[ind].value;
X		    if (override_tty_modes) {
X			TMODE (XTTYMODE_intr, tc.t_intrc);
X			TMODE (XTTYMODE_quit, tc.t_quitc);
X			TMODE (XTTYMODE_erase, sg.sg_erase);
X			TMODE (XTTYMODE_kill, sg.sg_kill);
X			TMODE (XTTYMODE_eof, tc.t_eofc);
X			TMODE (XTTYMODE_start, tc.t_startc);
X			TMODE (XTTYMODE_stop, tc.t_stopc);
X			TMODE (XTTYMODE_brk, tc.t_brkc);
X			/* both SYSV and BSD have ltchars */
X			TMODE (XTTYMODE_susp, ltc.t_suspc);
X			TMODE (XTTYMODE_dsusp, ltc.t_dsuspc);
X			TMODE (XTTYMODE_rprnt, ltc.t_rprntc);
X			TMODE (XTTYMODE_flush, ltc.t_flushc);
X			TMODE (XTTYMODE_weras, ltc.t_werasc);
X			TMODE (XTTYMODE_lnext, ltc.t_lnextc);
X		    }
#undef TMODE
X
X		    if (ioctl (tty, TIOCSETP, (char *)&sg) == -1)
X			    HsSysError (cp_pipe[1], ERROR_TIOCSETP);
X		    if (ioctl (tty, TIOCSETC, (char *)&tc) == -1)
X			    HsSysError (cp_pipe[1], ERROR_TIOCSETC);
X		    if (ioctl (tty, TIOCSETD, (char *)&discipline) == -1)
X			    HsSysError (cp_pipe[1], ERROR_TIOCSETD);
X		    if (ioctl (tty, TIOCSLTC, (char *)&ltc) == -1)
X			    HsSysError (cp_pipe[1], ERROR_TIOCSLTC);
X		    if (ioctl (tty, TIOCLSET, (char *)&lmode) == -1)
X			    HsSysError (cp_pipe[1], ERROR_TIOCLSET);
#ifdef TIOCCONS
X		    if (Console) {
X			    int on = 1;
X			    if (ioctl (tty, TIOCCONS, (char *)&on) == -1)
X				    HsSysError(cp_pipe[1], ERROR_TIOCCONS);
X		    }
#endif	/* TIOCCONS */
#endif	/* !USE_SYSV_TERMIO */
X		}
X
X		signal (SIGCHLD, SIG_DFL);
#ifdef att
X		/* watch out for extra shells (I don't understand either) */
X		signal (SIGHUP, SIG_DFL);
#else
X		signal (SIGHUP, SIG_IGN);
#endif
X		/* restore various signals to their defaults */
X		signal (SIGINT, SIG_DFL);
X		signal (SIGQUIT, SIG_DFL);
X		signal (SIGTERM, SIG_DFL);
X
X		/* copy the environment before Setenving */
X		for (i = 0 ; environ [i] != NULL ; i++) ;
X		/*
X		 * The `4' (`5' for SYSV) is the number of Setenv()
X		 * calls which may add a new entry to the environment.
X		 * The `1' is for the NULL terminating entry.
X		 */
#ifdef USE_SYSV_ENVVARS
X		envnew = (char **) calloc ((unsigned) i + (5 + 1), sizeof(char *));
#else
X		envnew = (char **) calloc ((unsigned) i + (4 + 1), sizeof(char *));
#endif /* USE_SYSV_ENVVARS */
SHAR_EOF
true || echo 'restore of kterm-4.1.2/main.c failed'
fi
echo 'End of kterm-4.1.2 part 13'
echo 'File kterm-4.1.2/main.c is continued in part 14'
echo 14 > _shar_seq_.tmp
exit 0


-----------------------------------------------------------------------------
mleisher at nmsu.edu                      "I laughed.
Mark Leisher                                I cried.
Computing Research Lab                          I fell down.
New Mexico State University                        It changed my life."
Las Cruces, NM                     - Rich [Cowboy Feng's Space Bar and Grille]

--
Dan Heller
O'Reilly && Associates       Z-Code Software    Comp-sources-x:
Senior Writer                President          comp-sources.x at uunet.uu.net
argv at ora.com                 argv at zipcode.com



More information about the Comp.sources.x mailing list