home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
x
/
volume12
/
kterm
/
part13
< prev
next >
Wrap
Text File
|
1991-05-11
|
52KB
|
1,735 lines
Path: uunet!cs.utexas.edu!sun-barr!newstop!jethro!exodus!NMSU.Edu!mleisher
From: mleisher@NMSU.Edu
Newsgroups: comp.sources.x
Subject: v12i094: kterm - kanji xterm, Part13/18
Message-ID: <13146@exodus.Eng.Sun.COM>
Date: 11 May 91 00:51:20 GMT
References: <csx-12i082:kterm@uunet.UU.NET>
Sender: news@exodus.Eng.Sun.COM
Lines: 1723
Approved: argv@sun.com
Submitted-by: mleisher@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, <c) == -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 *)<c) == -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, <c) == -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 *)<c) == -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@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@uunet.uu.net
argv@ora.com argv@zipcode.com