~ubuntu-branches/ubuntu/gutsy/vnc4/gutsy

« back to all changes in this revision

Viewing changes to unix/xc/programs/xterm/os2main.c

  • Committer: Bazaar Package Importer
  • Author(s): Ola Lundqvist
  • Date: 2006-05-15 20:35:17 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20060515203517-l4lre1ku942mn26k
Tags: 4.1.1+X4.3.0-10
* Correction of critical security issue. Thanks to Martin Kogler
  <e9925248@student.tuwien.ac.at> that informed me about the issue,
  and provided the patch.
  This flaw was originally found by Steve Wiseman of intelliadmin.com.
* Applied patch from Javier Kohen <jkohen@users.sourceforge.net> that
  inform the user that only 8 first characters of the password will
  actually be used when typing more than 8 characters, closes:
  #355619.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* removed all foreign stuff to get the code more clear (hv)
 
2
 * and did some rewrite for the obscure OS/2 environment
 
3
 */
 
4
 
 
5
#ifndef lint
 
6
static char *rid = "$XConsortium: main.c,v 1.227.1.2 95/06/29 18:13:15 kaleb Exp $";
 
7
#endif /* lint */
 
8
/* $XFree86: xc/programs/xterm/os2main.c,v 3.57 2002/12/27 21:05:22 dickey Exp $ */
 
9
 
 
10
/***********************************************************
 
11
 
 
12
Copyright (c) 1987, 1988  X Consortium
 
13
 
 
14
Permission is hereby granted, free of charge, to any person obtaining a copy
 
15
of this software and associated documentation files (the "Software"), to deal
 
16
in the Software without restriction, including without limitation the rights
 
17
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 
18
copies of the Software, and to permit persons to whom the Software is
 
19
furnished to do so, subject to the following conditions:
 
20
 
 
21
The above copyright notice and this permission notice shall be included in
 
22
all copies or substantial portions of the Software.
 
23
 
 
24
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
25
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
26
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
 
27
X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
 
28
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 
29
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
30
 
 
31
Except as contained in this notice, the name of the X Consortium shall not be
 
32
used in advertising or otherwise to promote the sale, use or other dealings
 
33
in this Software without prior written authorization from the X Consortium.
 
34
 
 
35
Copyright 1987, 1988 by Digital Equipment Corporation, Maynard.
 
36
 
 
37
                        All Rights Reserved
 
38
 
 
39
Permission to use, copy, modify, and distribute this software and its
 
40
documentation for any purpose and without fee is hereby granted,
 
41
provided that the above copyright notice appear in all copies and that
 
42
both that copyright notice and this permission notice appear in
 
43
supporting documentation, and that the name of Digital not be used in
 
44
advertising or publicity pertaining to distribution of the software
 
45
without specific, written prior permission.
 
46
 
 
47
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
 
48
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
 
49
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
 
50
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
 
51
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 
52
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
 
53
SOFTWARE.
 
54
 
 
55
******************************************************************/
 
56
 
 
57
/* os2main.c */
 
58
#define INCL_DOSFILEMGR
 
59
#define INCL_DOSDEVIOCTL
 
60
#define INCL_DOSSEMAPHORES
 
61
#define I_NEED_OS2_H
 
62
#include <os2.h>
 
63
#define XTERM_MAIN
 
64
 
 
65
#include <version.h>
 
66
#include <xterm.h>
 
67
 
 
68
#include <X11/cursorfont.h>
 
69
#ifdef I18N
 
70
#include <X11/Xlocale.h>
 
71
#endif
 
72
 
 
73
#if OPT_TOOLBAR
 
74
 
 
75
#if defined(HAVE_LIB_XAW)
 
76
#include <X11/Xaw/Form.h>
 
77
#elif defined(HAVE_LIB_XAW3D)
 
78
#include <X11/Xaw3d/Form.h>
 
79
#elif defined(HAVE_LIB_NEXTAW)
 
80
#include <X11/neXtaw/Form.h>
 
81
#endif
 
82
 
 
83
#endif /* OPT_TOOLBAR */
 
84
 
 
85
#include <pwd.h>
 
86
#include <ctype.h>
 
87
 
 
88
#include <data.h>
 
89
#include <error.h>
 
90
#include <menu.h>
 
91
#include <main.h>
 
92
#include <xstrings.h>
 
93
#include <xterm_io.h>
 
94
 
 
95
#if OPT_WIDE_CHARS
 
96
#include <charclass.h>
 
97
#include <wcwidth.h>
 
98
#endif
 
99
 
 
100
int
 
101
setpgrp(pid_t pid, gid_t pgid)
 
102
{
 
103
    return 0;
 
104
}
 
105
 
 
106
int
 
107
chown(const char *fn, pid_t pid, gid_t gid)
 
108
{
 
109
    return 0;
 
110
}
 
111
 
 
112
char *
 
113
ttyname(int fd)
 
114
{
 
115
    return "/dev/tty";
 
116
}
 
117
 
 
118
#include <sys/stat.h>
 
119
#include <sys/param.h>          /* for NOFILE */
 
120
#include <stdio.h>
 
121
#include <signal.h>
 
122
 
 
123
static SIGNAL_T reapchild(int n);
 
124
static int spawn(void);
 
125
static void get_terminal(void);
 
126
static void resize(TScreen * s, char *oldtc, char *newtc);
 
127
static void set_owner(char *device, int uid, int gid, int mode);
 
128
 
 
129
static Bool added_utmp_entry = False;
 
130
 
 
131
/*
 
132
** Ordinarily it should be okay to omit the assignment in the following
 
133
** statement. Apparently the c89 compiler on AIX 4.1.3 has a bug, or does
 
134
** it? Without the assignment though the compiler will init command_to_exec
 
135
** to 0xffffffff instead of NULL; and subsequent usage, e.g. in spawn() to
 
136
** SEGV.
 
137
*/
 
138
static char **command_to_exec = NULL;
 
139
 
 
140
#if OPT_LUIT_PROG
 
141
static char **command_to_exec_with_luit = NULL;
 
142
#endif
 
143
 
 
144
/* The following structures are initialized in main() in order
 
145
** to eliminate any assumptions about the internal order of their
 
146
** contents.
 
147
*/
 
148
static struct termio d_tio;
 
149
 
 
150
/* allow use of system default characters if defined and reasonable */
 
151
#ifndef CEOF
 
152
#define CEOF     CONTROL('D')
 
153
#endif
 
154
#ifndef CEOL
 
155
#define CEOL 0
 
156
#endif
 
157
#ifndef CFLUSH
 
158
#define CFLUSH   CONTROL('O')
 
159
#endif
 
160
#ifndef CLNEXT
 
161
#define CLNEXT   CONTROL('V')
 
162
#endif
 
163
#ifndef CNUL
 
164
#define CNUL 0
 
165
#endif
 
166
#ifndef CQUIT
 
167
#define CQUIT    CONTROL('\\')
 
168
#endif
 
169
#ifndef CRPRNT
 
170
#define CRPRNT   CONTROL('R')
 
171
#endif
 
172
#ifndef CSTART
 
173
#define CSTART   CONTROL('Q')
 
174
#endif
 
175
#ifndef CSTOP
 
176
#define CSTOP    CONTROL('S')
 
177
#endif
 
178
#ifndef CSUSP
 
179
#define CSUSP    CONTROL('Z')
 
180
#endif
 
181
#ifndef CSWTCH
 
182
#define CSWTCH 0
 
183
#endif
 
184
#ifndef CWERASE
 
185
#define CWERASE  CONTROL('W')
 
186
#endif
 
187
 
 
188
/*
 
189
 * SYSV has the termio.c_cc[V] and ltchars; BSD has tchars and ltchars;
 
190
 * SVR4 has only termio.c_cc, but it includes everything from ltchars.
 
191
 */
 
192
static int override_tty_modes = 0;
 
193
/* *INDENT-OFF* */
 
194
struct _xttymodes {
 
195
    char *name;
 
196
    size_t len;
 
197
    int set;
 
198
    char value;
 
199
} ttymodelist[] = {
 
200
    { "intr",   4, 0, '\0' },   /* tchars.t_intrc ; VINTR */
 
201
#define XTTYMODE_intr 0
 
202
    { "quit",   4, 0, '\0' },   /* tchars.t_quitc ; VQUIT */
 
203
#define XTTYMODE_quit 1
 
204
    { "erase",  5, 0, '\0' },   /* sgttyb.sg_erase ; VERASE */
 
205
#define XTTYMODE_erase 2
 
206
    { "kill",   4, 0, '\0' },   /* sgttyb.sg_kill ; VKILL */
 
207
#define XTTYMODE_kill 3
 
208
    { "eof",    3, 0, '\0' },   /* tchars.t_eofc ; VEOF */
 
209
#define XTTYMODE_eof 4
 
210
    { "eol",    3, 0, '\0' },   /* VEOL */
 
211
#define XTTYMODE_eol 5
 
212
    { "swtch",  5, 0, '\0' },   /* VSWTCH */
 
213
#define XTTYMODE_swtch 6
 
214
    { "start",  5, 0, '\0' },   /* tchars.t_startc */
 
215
#define XTTYMODE_start 7
 
216
    { "stop",   4, 0, '\0' },   /* tchars.t_stopc */
 
217
#define XTTYMODE_stop 8
 
218
    { "brk",    3, 0, '\0' },   /* tchars.t_brkc */
 
219
#define XTTYMODE_brk 9
 
220
    { "susp",   4, 0, '\0' },   /* ltchars.t_suspc ; VSUSP */
 
221
#define XTTYMODE_susp 10
 
222
    { "dsusp",  5, 0, '\0' },   /* ltchars.t_dsuspc ; VDSUSP */
 
223
#define XTTYMODE_dsusp 11
 
224
    { "rprnt",  5, 0, '\0' },   /* ltchars.t_rprntc ; VREPRINT */
 
225
#define XTTYMODE_rprnt 12
 
226
    { "flush",  5, 0, '\0' },   /* ltchars.t_flushc ; VDISCARD */
 
227
#define XTTYMODE_flush 13
 
228
    { "weras",  5, 0, '\0' },   /* ltchars.t_werasc ; VWERASE */
 
229
#define XTTYMODE_weras 14
 
230
    { "lnext",  5, 0, '\0' },   /* ltchars.t_lnextc ; VLNEXT */
 
231
#define XTTYMODE_lnext 15
 
232
    { NULL,     0, 0, '\0' },   /* end of data */
 
233
};
 
234
/* *INDENT-ON* */
 
235
 
 
236
static int parse_tty_modes(char *s, struct _xttymodes *modelist);
 
237
 
 
238
static int inhibit;
 
239
static char passedPty[2];       /* name if pty if slave */
 
240
 
 
241
static int Console;
 
242
#include <X11/Xmu/SysUtil.h>    /* XmuGetHostname */
 
243
#define MIT_CONSOLE_LEN 12
 
244
#define MIT_CONSOLE "MIT_CONSOLE_"
 
245
static char mit_console_name[255 + MIT_CONSOLE_LEN + 1] = MIT_CONSOLE;
 
246
static Atom mit_console;
 
247
 
 
248
static int tslot;
 
249
static jmp_buf env;
 
250
 
 
251
/* used by VT (charproc.c) */
 
252
 
 
253
#define offset(field)   XtOffsetOf(XTERM_RESOURCE, field)
 
254
 
 
255
static XtResource application_resources[] =
 
256
{
 
257
    {"name", "Name", XtRString, sizeof(char *),
 
258
     offset(xterm_name), XtRString, DFT_TERMTYPE},
 
259
    {"iconGeometry", "IconGeometry", XtRString, sizeof(char *),
 
260
     offset(icon_geometry), XtRString, (caddr_t) NULL},
 
261
    {XtNtitle, XtCTitle, XtRString, sizeof(char *),
 
262
     offset(title), XtRString, (caddr_t) NULL},
 
263
    {XtNiconName, XtCIconName, XtRString, sizeof(char *),
 
264
     offset(icon_name), XtRString, (caddr_t) NULL},
 
265
    {"termName", "TermName", XtRString, sizeof(char *),
 
266
     offset(term_name), XtRString, (caddr_t) NULL},
 
267
    {"ttyModes", "TtyModes", XtRString, sizeof(char *),
 
268
     offset(tty_modes), XtRString, (caddr_t) NULL},
 
269
    {"hold", "Hold", XtRBoolean, sizeof(Boolean),
 
270
     offset(hold_screen), XtRString, "false"},
 
271
    {"utmpInhibit", "UtmpInhibit", XtRBoolean, sizeof(Boolean),
 
272
     offset(utmpInhibit), XtRString, "false"},
 
273
    {"messages", "Messages", XtRBoolean, sizeof(Boolean),
 
274
     offset(messages), XtRString, "true"},
 
275
    {"sunFunctionKeys", "SunFunctionKeys", XtRBoolean, sizeof(Boolean),
 
276
     offset(sunFunctionKeys), XtRString, "false"},
 
277
#if OPT_SUNPC_KBD
 
278
    {"sunKeyboard", "SunKeyboard", XtRBoolean, sizeof(Boolean),
 
279
     offset(sunKeyboard), XtRString, "false"},
 
280
#endif
 
281
#if OPT_HP_FUNC_KEYS
 
282
    {"hpFunctionKeys", "HpFunctionKeys", XtRBoolean, sizeof(Boolean),
 
283
     offset(hpFunctionKeys), XtRString, "false"},
 
284
#endif
 
285
    {"waitForMap", "WaitForMap", XtRBoolean, sizeof(Boolean),
 
286
     offset(wait_for_map), XtRString, "false"},
 
287
    {"useInsertMode", "UseInsertMode", XtRBoolean, sizeof(Boolean),
 
288
     offset(useInsertMode), XtRString, "false"},
 
289
#if OPT_ZICONBEEP
 
290
    {"zIconBeep", "ZIconBeep", XtRInt, sizeof(int),
 
291
     offset(zIconBeep), XtRImmediate, 0},
 
292
#endif
 
293
#if OPT_SAME_NAME
 
294
    {"sameName", "SameName", XtRBoolean, sizeof(Boolean),
 
295
     offset(sameName), XtRString, "true"},
 
296
#endif
 
297
#if OPT_SESSION_MGT
 
298
    {"sessionMgt", "SessionMgt", XtRBoolean, sizeof(Boolean),
 
299
     offset(sessionMgt), XtRString, "true"},
 
300
#endif
 
301
};
 
302
#undef offset
 
303
 
 
304
static char *fallback_resources[] =
 
305
{
 
306
    "*SimpleMenu*menuLabel.vertSpace: 100",
 
307
    "*SimpleMenu*HorizontalMargins: 16",
 
308
    "*SimpleMenu*Sme.height: 16",
 
309
    "*SimpleMenu*Cursor: left_ptr",
 
310
    "*mainMenu.Label:  Main Options (no app-defaults)",
 
311
    "*vtMenu.Label:  VT Options (no app-defaults)",
 
312
    "*fontMenu.Label:  VT Fonts (no app-defaults)",
 
313
#if OPT_TEK4014
 
314
    "*tekMenu.Label:  Tek Options (no app-defaults)",
 
315
#endif
 
316
    NULL
 
317
};
 
318
 
 
319
/* Command line options table.  Only resources are entered here...there is a
 
320
   pass over the remaining options after XrmParseCommand is let loose. */
 
321
/* *INDENT-OFF* */
 
322
static XrmOptionDescRec optionDescList[] = {
 
323
{"-geometry",   "*vt100.geometry",XrmoptionSepArg,      (caddr_t) NULL},
 
324
{"-132",        "*c132",        XrmoptionNoArg,         (caddr_t) "on"},
 
325
{"+132",        "*c132",        XrmoptionNoArg,         (caddr_t) "off"},
 
326
{"-ah",         "*alwaysHighlight", XrmoptionNoArg,     (caddr_t) "on"},
 
327
{"+ah",         "*alwaysHighlight", XrmoptionNoArg,     (caddr_t) "off"},
 
328
{"-aw",         "*autoWrap",    XrmoptionNoArg,         (caddr_t) "on"},
 
329
{"+aw",         "*autoWrap",    XrmoptionNoArg,         (caddr_t) "off"},
 
330
#ifndef NO_ACTIVE_ICON
 
331
{"-ai",         "*activeIcon",  XrmoptionNoArg,         (caddr_t) "off"},
 
332
{"+ai",         "*activeIcon",  XrmoptionNoArg,         (caddr_t) "on"},
 
333
#endif /* NO_ACTIVE_ICON */
 
334
{"-b",          "*internalBorder",XrmoptionSepArg,      (caddr_t) NULL},
 
335
{"-bc",         "*cursorBlink", XrmoptionNoArg,         (caddr_t) "on"},
 
336
{"+bc",         "*cursorBlink", XrmoptionNoArg,         (caddr_t) "off"},
 
337
{"-bcf",        "*cursorOffTime",XrmoptionSepArg,       (caddr_t) NULL},
 
338
{"-bcn",        "*cursorOnTime",XrmoptionSepArg,        (caddr_t) NULL},
 
339
{"-bdc",        "*colorBDMode", XrmoptionNoArg,         (caddr_t) "off"},
 
340
{"+bdc",        "*colorBDMode", XrmoptionNoArg,         (caddr_t) "on"},
 
341
{"-cb",         "*cutToBeginningOfLine", XrmoptionNoArg, (caddr_t) "off"},
 
342
{"+cb",         "*cutToBeginningOfLine", XrmoptionNoArg, (caddr_t) "on"},
 
343
{"-cc",         "*charClass",   XrmoptionSepArg,        (caddr_t) NULL},
 
344
{"-cm",         "*colorMode",   XrmoptionNoArg,         (caddr_t) "off"},
 
345
{"+cm",         "*colorMode",   XrmoptionNoArg,         (caddr_t) "on"},
 
346
{"-cn",         "*cutNewline",  XrmoptionNoArg,         (caddr_t) "off"},
 
347
{"+cn",         "*cutNewline",  XrmoptionNoArg,         (caddr_t) "on"},
 
348
{"-cr",         "*cursorColor", XrmoptionSepArg,        (caddr_t) NULL},
 
349
{"-cu",         "*curses",      XrmoptionNoArg,         (caddr_t) "on"},
 
350
{"+cu",         "*curses",      XrmoptionNoArg,         (caddr_t) "off"},
 
351
{"-dc",         "*dynamicColors",XrmoptionNoArg,        (caddr_t) "off"},
 
352
{"+dc",         "*dynamicColors",XrmoptionNoArg,        (caddr_t) "on"},
 
353
{"-fb",         "*boldFont",    XrmoptionSepArg,        (caddr_t) NULL},
 
354
{"-fbb",        "*freeBoldBox", XrmoptionNoArg,         (caddr_t)"off"},
 
355
{"+fbb",        "*freeBoldBox", XrmoptionNoArg,         (caddr_t)"on"},
 
356
{"-fbx",        "*forceBoxChars", XrmoptionNoArg,       (caddr_t)"off"},
 
357
{"+fbx",        "*forceBoxChars", XrmoptionNoArg,       (caddr_t)"on"},
 
358
#ifndef NO_ACTIVE_ICON
 
359
{"-fi",         "*iconFont",    XrmoptionSepArg,        (caddr_t) NULL},
 
360
#endif /* NO_ACTIVE_ICON */
 
361
#ifdef XRENDERFONT
 
362
{"-fa",         "*faceName",    XrmoptionSepArg,        (caddr_t) NULL},
 
363
{"-fs",         "*faceSize",    XrmoptionSepArg,        (caddr_t) NULL},
 
364
#endif
 
365
#if OPT_WIDE_CHARS
 
366
{"-fw",         "*wideFont",    XrmoptionSepArg,        (caddr_t) NULL},
 
367
{"-fwb",        "*wideBoldFont", XrmoptionSepArg,       (caddr_t) NULL},
 
368
#endif
 
369
#if OPT_HIGHLIGHT_COLOR
 
370
{"-hc",         "*highlightColor", XrmoptionSepArg,     (caddr_t) NULL},
 
371
#endif
 
372
#if OPT_HP_FUNC_KEYS
 
373
{"-hf",         "*hpFunctionKeys",XrmoptionNoArg,       (caddr_t) "on"},
 
374
{"+hf",         "*hpFunctionKeys",XrmoptionNoArg,       (caddr_t) "off"},
 
375
#endif
 
376
{"-hold",       "*hold",        XrmoptionNoArg,         (caddr_t) "on"},
 
377
{"+hold",       "*hold",        XrmoptionNoArg,         (caddr_t) "off"},
 
378
{"-j",          "*jumpScroll",  XrmoptionNoArg,         (caddr_t) "on"},
 
379
{"+j",          "*jumpScroll",  XrmoptionNoArg,         (caddr_t) "off"},
 
380
/* parse logging options anyway for compatibility */
 
381
{"-l",          "*logging",     XrmoptionNoArg,         (caddr_t) "on"},
 
382
{"+l",          "*logging",     XrmoptionNoArg,         (caddr_t) "off"},
 
383
{"-lf",         "*logFile",     XrmoptionSepArg,        (caddr_t) NULL},
 
384
{"-ls",         "*loginShell",  XrmoptionNoArg,         (caddr_t) "on"},
 
385
{"+ls",         "*loginShell",  XrmoptionNoArg,         (caddr_t) "off"},
 
386
{"-mb",         "*marginBell",  XrmoptionNoArg,         (caddr_t) "on"},
 
387
{"+mb",         "*marginBell",  XrmoptionNoArg,         (caddr_t) "off"},
 
388
{"-mc",         "*multiClickTime", XrmoptionSepArg,     (caddr_t) NULL},
 
389
{"-mesg",       "*messages",    XrmoptionNoArg,         (caddr_t) "off"},
 
390
{"+mesg",       "*messages",    XrmoptionNoArg,         (caddr_t) "on"},
 
391
{"-ms",         "*pointerColor",XrmoptionSepArg,        (caddr_t) NULL},
 
392
{"-nb",         "*nMarginBell", XrmoptionSepArg,        (caddr_t) NULL},
 
393
{"-nul",        "*underLine",   XrmoptionNoArg,         (caddr_t) "off"},
 
394
{"+nul",        "*underLine",   XrmoptionNoArg,         (caddr_t) "on"},
 
395
{"-pc",         "*boldColors",  XrmoptionNoArg,         (caddr_t) "on"},
 
396
{"+pc",         "*boldColors",  XrmoptionNoArg,         (caddr_t) "off"},
 
397
{"-rw",         "*reverseWrap", XrmoptionNoArg,         (caddr_t) "on"},
 
398
{"+rw",         "*reverseWrap", XrmoptionNoArg,         (caddr_t) "off"},
 
399
{"-s",          "*multiScroll", XrmoptionNoArg,         (caddr_t) "on"},
 
400
{"+s",          "*multiScroll", XrmoptionNoArg,         (caddr_t) "off"},
 
401
{"-sb",         "*scrollBar",   XrmoptionNoArg,         (caddr_t) "on"},
 
402
{"+sb",         "*scrollBar",   XrmoptionNoArg,         (caddr_t) "off"},
 
403
#ifdef SCROLLBAR_RIGHT
 
404
{"-leftbar",    "*rightScrollBar", XrmoptionNoArg,      (caddr_t) "off"},
 
405
{"-rightbar",   "*rightScrollBar", XrmoptionNoArg,      (caddr_t) "on"},
 
406
#endif
 
407
{"-rvc",        "*colorRVMode", XrmoptionNoArg,         (caddr_t) "off"},
 
408
{"+rvc",        "*colorRVMode", XrmoptionNoArg,         (caddr_t) "on"},
 
409
{"-sf",         "*sunFunctionKeys", XrmoptionNoArg,     (caddr_t) "on"},
 
410
{"+sf",         "*sunFunctionKeys", XrmoptionNoArg,     (caddr_t) "off"},
 
411
{"-si",         "*scrollTtyOutput", XrmoptionNoArg,     (caddr_t) "off"},
 
412
{"+si",         "*scrollTtyOutput", XrmoptionNoArg,     (caddr_t) "on"},
 
413
{"-sk",         "*scrollKey",   XrmoptionNoArg,         (caddr_t) "on"},
 
414
{"+sk",         "*scrollKey",   XrmoptionNoArg,         (caddr_t) "off"},
 
415
{"-sl",         "*saveLines",   XrmoptionSepArg,        (caddr_t) NULL},
 
416
#if OPT_SUNPC_KBD
 
417
{"-sp",         "*sunKeyboard", XrmoptionNoArg,         (caddr_t) "on"},
 
418
{"+sp",         "*sunKeyboard", XrmoptionNoArg,         (caddr_t) "off"},
 
419
#endif
 
420
{"-t",          "*tekStartup",  XrmoptionNoArg,         (caddr_t) "on"},
 
421
{"+t",          "*tekStartup",  XrmoptionNoArg,         (caddr_t) "off"},
 
422
{"-ti",         "*decTerminalID",XrmoptionSepArg,       (caddr_t) NULL},
 
423
{"-tm",         "*ttyModes",    XrmoptionSepArg,        (caddr_t) NULL},
 
424
{"-tn",         "*termName",    XrmoptionSepArg,        (caddr_t) NULL},
 
425
#if OPT_WIDE_CHARS
 
426
{"-u8",         "*utf8",        XrmoptionNoArg,         (caddr_t) "2"},
 
427
{"+u8",         "*utf8",        XrmoptionNoArg,         (caddr_t) "0"},
 
428
#endif
 
429
#if OPT_LUIT_PROG
 
430
{"-lc",         "*locale",      XrmoptionNoArg,         (caddr_t) "True"},
 
431
{"+lc",         "*locale",      XrmoptionNoArg,         (caddr_t) "False"},
 
432
{"-lcc",        "*localeFilter",XrmoptionSepArg,        (caddr_t) NULL},
 
433
{"-en",         "*locale",      XrmoptionSepArg,        (caddr_t) NULL},
 
434
#endif
 
435
{"-ulc",        "*colorULMode", XrmoptionNoArg,         (caddr_t) "off"},
 
436
{"+ulc",        "*colorULMode", XrmoptionNoArg,         (caddr_t) "on"},
 
437
{"-ut",         "*utmpInhibit", XrmoptionNoArg,         (caddr_t) "on"},
 
438
{"+ut",         "*utmpInhibit", XrmoptionNoArg,         (caddr_t) "off"},
 
439
{"-im",         "*useInsertMode", XrmoptionNoArg,       (caddr_t) "on"},
 
440
{"+im",         "*useInsertMode", XrmoptionNoArg,       (caddr_t) "off"},
 
441
{"-vb",         "*visualBell",  XrmoptionNoArg,         (caddr_t) "on"},
 
442
{"+vb",         "*visualBell",  XrmoptionNoArg,         (caddr_t) "off"},
 
443
{"-pob",        "*popOnBell",   XrmoptionNoArg,         (caddr_t) "on"},
 
444
{"+pob",        "*popOnBell",   XrmoptionNoArg,         (caddr_t) "off"},
 
445
#if OPT_WIDE_CHARS
 
446
{"-wc",         "*wideChars",   XrmoptionNoArg,         (caddr_t) "on"},
 
447
{"+wc",         "*wideChars",   XrmoptionNoArg,         (caddr_t) "off"},
 
448
{"-cjk_width", "*cjkWidth",     XrmoptionNoArg,         (caddr_t) "on"},
 
449
{"+cjk_width", "*cjkWidth",     XrmoptionNoArg,         (caddr_t) "off"},
 
450
#endif
 
451
{"-wf",         "*waitForMap",  XrmoptionNoArg,         (caddr_t) "on"},
 
452
{"+wf",         "*waitForMap",  XrmoptionNoArg,         (caddr_t) "off"},
 
453
#if OPT_ZICONBEEP
 
454
{"-ziconbeep",  "*zIconBeep",   XrmoptionSepArg,        (caddr_t) NULL},
 
455
#endif
 
456
#if OPT_SAME_NAME
 
457
{"-samename",   "*sameName",    XrmoptionNoArg,         (caddr_t) "on"},
 
458
{"+samename",   "*sameName",    XrmoptionNoArg,         (caddr_t) "off"},
 
459
#endif
 
460
#if OPT_SESSION_MGT
 
461
{"-sm",         "*sessionMgt",  XrmoptionNoArg,         (caddr_t) "on"},
 
462
{"+sm",         "*sessionMgt",  XrmoptionNoArg,         (caddr_t) "off"},
 
463
#endif
 
464
/* options that we process ourselves */
 
465
{"-help",       NULL,           XrmoptionSkipNArgs,     (caddr_t) NULL},
 
466
{"-version",    NULL,           XrmoptionSkipNArgs,     (caddr_t) NULL},
 
467
{"-class",      NULL,           XrmoptionSkipArg,       (caddr_t) NULL},
 
468
{"-e",          NULL,           XrmoptionSkipLine,      (caddr_t) NULL},
 
469
{"-into",       NULL,           XrmoptionSkipArg,       (caddr_t) NULL},
 
470
/* bogus old compatibility stuff for which there are
 
471
   standard XtOpenApplication options now */
 
472
{"%",           "*tekGeometry", XrmoptionStickyArg,     (caddr_t) NULL},
 
473
{"#",           ".iconGeometry",XrmoptionStickyArg,     (caddr_t) NULL},
 
474
{"-T",          ".title",       XrmoptionSepArg,        (caddr_t) NULL},
 
475
{"-n",          "*iconName",    XrmoptionSepArg,        (caddr_t) NULL},
 
476
{"-r",          "*reverseVideo",XrmoptionNoArg,         (caddr_t) "on"},
 
477
{"+r",          "*reverseVideo",XrmoptionNoArg,         (caddr_t) "off"},
 
478
{"-rv",         "*reverseVideo",XrmoptionNoArg,         (caddr_t) "on"},
 
479
{"+rv",         "*reverseVideo",XrmoptionNoArg,         (caddr_t) "off"},
 
480
{"-w",          ".borderWidth", XrmoptionSepArg,        (caddr_t) NULL},
 
481
};
 
482
 
 
483
static OptionHelp xtermOptions[] = {
 
484
{ "-version",              "print the version number" },
 
485
{ "-help",                 "print out this message" },
 
486
{ "-display displayname",  "X server to contact" },
 
487
{ "-geometry geom",        "size (in characters) and position" },
 
488
{ "-/+rv",                 "turn on/off reverse video" },
 
489
{ "-bg color",             "background color" },
 
490
{ "-fg color",             "foreground color" },
 
491
{ "-bd color",             "border color" },
 
492
{ "-bw number",            "border width in pixels" },
 
493
{ "-fn fontname",          "normal text font" },
 
494
{ "-fb fontname",          "bold text font" },
 
495
{ "-/+fbb",                "turn on/off normal/bold font comparison inhibit"},
 
496
{ "-/+fbx",                "turn off/on linedrawing characters"},
 
497
#ifdef XRENDERFONT
 
498
{ "-fa pattern",           "FreeType font-selection pattern" },
 
499
{ "-fs size",              "FreeType font-size" },
 
500
#endif
 
501
#if OPT_WIDE_CHARS
 
502
{ "-fw fontname",          "doublewidth text font" },
 
503
{ "-fwb fontname",         "doublewidth bold text font" },
 
504
#endif
 
505
{ "-iconic",               "start iconic" },
 
506
{ "-name string",          "client instance, icon, and title strings" },
 
507
{ "-class string",         "class string (XTerm)" },
 
508
{ "-title string",         "title string" },
 
509
{ "-xrm resourcestring",   "additional resource specifications" },
 
510
{ "-/+132",                "turn on/off 80/132 column switching" },
 
511
{ "-/+ah",                 "turn on/off always highlight" },
 
512
#ifndef NO_ACTIVE_ICON
 
513
{ "-/+ai",                 "turn off/on active icon" },
 
514
{ "-fi fontname",          "icon font for active icon" },
 
515
#endif /* NO_ACTIVE_ICON */
 
516
{ "-b number",             "internal border in pixels" },
 
517
{ "-/+bc",                 "turn on/off text cursor blinking" },
 
518
{ "-bcf milliseconds",     "time text cursor is off when blinking"},
 
519
{ "-bcn milliseconds",     "time text cursor is on when blinking"},
 
520
{ "-/+bdc",                "turn off/on display of bold as color"},
 
521
{ "-/+cb",                 "turn on/off cut-to-beginning-of-line inhibit" },
 
522
{ "-cc classrange",        "specify additional character classes" },
 
523
{ "-/+cm",                 "turn off/on ANSI color mode" },
 
524
{ "-/+cn",                 "turn on/off cut newline inhibit" },
 
525
{ "-cr color",             "text cursor color" },
 
526
{ "-/+cu",                 "turn on/off curses emulation" },
 
527
{ "-/+dc",                 "turn off/on dynamic color selection" },
 
528
#if OPT_HIGHLIGHT_COLOR
 
529
{ "-hc color",             "selection background color" },
 
530
#endif
 
531
#if OPT_HP_FUNC_KEYS
 
532
{ "-/+hf",                 "turn on/off HP Function Key escape codes" },
 
533
#endif
 
534
{ "-/+hold",               "turn on/off logic that retains window after exit" },
 
535
{ "-/+im",                 "use insert mode for TERMCAP" },
 
536
{ "-/+j",                  "turn on/off jump scroll" },
 
537
#ifdef ALLOWLOGGING
 
538
{ "-/+l",                  "turn on/off logging" },
 
539
{ "-lf filename",          "logging filename" },
 
540
#else
 
541
{ "-/+l",                  "turn on/off logging (not supported)" },
 
542
{ "-lf filename",          "logging filename (not supported)" },
 
543
#endif
 
544
{ "-/+ls",                 "turn on/off login shell" },
 
545
{ "-/+mb",                 "turn on/off margin bell" },
 
546
{ "-mc milliseconds",      "multiclick time in milliseconds" },
 
547
{ "-/+mesg",               "forbid/allow messages" },
 
548
{ "-ms color",             "pointer color" },
 
549
{ "-nb number",            "margin bell in characters from right end" },
 
550
{ "-/+nul",                "turn off/on display of underlining" },
 
551
{ "-/+aw",                 "turn on/off auto wraparound" },
 
552
{ "-/+pc",                 "turn on/off PC-style bold colors" },
 
553
{ "-/+rw",                 "turn on/off reverse wraparound" },
 
554
{ "-/+s",                  "turn on/off multiscroll" },
 
555
{ "-/+sb",                 "turn on/off scrollbar" },
 
556
#ifdef SCROLLBAR_RIGHT
 
557
{ "-rightbar",             "force scrollbar right (default left)" },
 
558
{ "-leftbar",              "force scrollbar left" },
 
559
#endif
 
560
{ "-/+rvc",                "turn off/on display of reverse as color" },
 
561
{ "-/+sf",                 "turn on/off Sun Function Key escape codes" },
 
562
{ "-/+si",                 "turn on/off scroll-on-tty-output inhibit" },
 
563
{ "-/+sk",                 "turn on/off scroll-on-keypress" },
 
564
{ "-sl number",            "number of scrolled lines to save" },
 
565
#if OPT_SUNPC_KBD
 
566
{ "-/+sp",                 "turn on/off Sun/PC Function/Keypad mapping" },
 
567
#endif
 
568
#if OPT_TEK4014
 
569
{ "-/+t",                  "turn on/off Tek emulation window" },
 
570
#endif
 
571
{ "-ti termid",            "terminal identifier" },
 
572
{ "-tm string",            "terminal mode keywords and characters" },
 
573
{ "-tn name",              "TERM environment variable name" },
 
574
#if OPT_WIDE_CHARS
 
575
{ "-/+u8",                 "turn on/off UTF-8 mode (implies wide-characters)" },
 
576
#endif
 
577
#if OPT_LUIT_PROG
 
578
{ "-/+lc",                 "turn on/off locale mode using luit" },
 
579
{ "-lcc path",             "filename of locale converter (" DEFLOCALEFILTER ")" },
 
580
#endif
 
581
{ "-/+ulc",                "turn off/on display of underline as color" },
 
582
{ "-/+ut",                 "turn on/off utmp inhibit (not supported)" },
 
583
{ "-/+vb",                 "turn on/off visual bell" },
 
584
{ "-/+pob",                "turn on/off pop on bell" },
 
585
#if OPT_WIDE_CHARS
 
586
{ "-/+wc",                 "turn on/off wide-character mode" },
 
587
{ "-/+cjk_width",          "turn on/off legacy CJK width convention" },
 
588
#endif
 
589
{ "-/+wf",                 "turn on/off wait for map before command exec" },
 
590
{ "-e command args ...",   "command to execute" },
 
591
#if OPT_TEK4014
 
592
{ "%geom",                 "Tek window geometry" },
 
593
#endif
 
594
{ "#geom",                 "icon window geometry" },
 
595
{ "-T string",             "title name for window" },
 
596
{ "-n string",             "icon name for window" },
 
597
{ "-C",                    "intercept console messages" },
 
598
{ "-Sccn",                 "slave mode on \"ttycc\", file descriptor \"n\"" },
 
599
{ "-into windowId",        "use the window id given to -into as the parent window rather than the default root window" },
 
600
#if OPT_ZICONBEEP
 
601
{ "-ziconbeep percent",    "beep and flag icon of window having hidden output" },
 
602
#endif
 
603
#if OPT_SAME_NAME
 
604
{ "-/+samename",           "turn on/off the no-flicker option for title and icon name" },
 
605
#endif
 
606
#if OPT_SESSION_MGT
 
607
{ "-/+sm",                 "turn on/off the session-management support" },
 
608
#endif
 
609
{ NULL, NULL }};
 
610
/* *INDENT-ON* */
 
611
 
 
612
/*debug FILE *confd;*/
 
613
/*static void opencons()
 
614
{
 
615
        if ((confd=fopen("/dev/console$","w")) < 0) {
 
616
                fputs("!!! Cannot open console device.\n",
 
617
                        stderr);
 
618
                exit(1);
 
619
        }
 
620
}
 
621
 
 
622
static void closecons(void)
 
623
{
 
624
        fclose(confd);
 
625
}
 
626
*/
 
627
static char *message[] =
 
628
{
 
629
    "Fonts should be fixed width and, if both normal and bold are specified, should",
 
630
    "have the same size.  If only a normal font is specified, it will be used for",
 
631
    "both normal and bold text (by doing overstriking).  The -e option, if given,",
 
632
    "must appear at the end of the command line, otherwise the user's default shell",
 
633
    "will be started.  Options that start with a plus sign (+) restore the default.",
 
634
    NULL};
 
635
 
 
636
/*
 
637
 * Decode a key-definition.  This combines the termcap and ttyModes, for
 
638
 * comparison.  Note that octal escapes in ttyModes are done by the normal
 
639
 * resource translation.  Also, ttyModes allows '^-' as a synonym for disabled.
 
640
 */
 
641
static int
 
642
decode_keyvalue(char **ptr, int termcap)
 
643
{
 
644
    char *string = *ptr;
 
645
    int value = -1;
 
646
 
 
647
    TRACE(("...decode '%s'\n", string));
 
648
    if (*string == '^') {
 
649
        switch (*++string) {
 
650
        case '?':
 
651
            value = A2E(127);
 
652
            break;
 
653
        case '-':
 
654
            if (!termcap) {
 
655
                errno = 0;
 
656
#if defined(_POSIX_VDISABLE) && defined(HAVE_UNISTD_H)
 
657
                value = _POSIX_VDISABLE;
 
658
#endif
 
659
#if defined(_PC_VDISABLE)
 
660
                if (value == -1) {
 
661
                    value = fpathconf(0, _PC_VDISABLE);
 
662
                    if (value == -1) {
 
663
                        if (errno != 0)
 
664
                            break;      /* skip this (error) */
 
665
                        value = 0377;
 
666
                    }
 
667
                }
 
668
#elif defined(VDISABLE)
 
669
                if (value == -1)
 
670
                    value = VDISABLE;
 
671
#endif
 
672
                break;
 
673
            }
 
674
            /* FALLTHRU */
 
675
        default:
 
676
            value = CONTROL(*string);
 
677
            break;
 
678
        }
 
679
        ++string;
 
680
    } else if (termcap && (*string == '\\')) {
 
681
        char *d;
 
682
        int temp = strtol(string + 1, &d, 8);
 
683
        if (temp > 0 && d != string) {
 
684
            value = temp;
 
685
            string = d;
 
686
        }
 
687
    } else {
 
688
        value = CharOf(*string);
 
689
        ++string;
 
690
    }
 
691
    *ptr = string;
 
692
    return value;
 
693
}
 
694
 
 
695
/*
 
696
 * If we're linked to terminfo, tgetent() will return an empty buffer.  We
 
697
 * cannot use that to adjust the $TERMCAP variable.
 
698
 */
 
699
static Boolean
 
700
get_termcap(char *name, char *buffer, char *resized)
 
701
{
 
702
    register TScreen *screen = &term->screen;
 
703
 
 
704
    *buffer = 0;                /* initialize, in case we're using terminfo's tgetent */
 
705
 
 
706
    if (name != 0) {
 
707
        if (tgetent(buffer, name) == 1) {
 
708
            TRACE(("get_termcap(%s) succeeded (%s)\n", name,
 
709
                   (*buffer
 
710
                    ? "ok:termcap, we can update $TERMCAP"
 
711
                    : "assuming this is terminfo")));
 
712
            if (*buffer) {
 
713
                if (!TEK4014_ACTIVE(screen)) {
 
714
                    resize(screen, buffer, resized);
 
715
                }
 
716
            }
 
717
            return True;
 
718
        } else {
 
719
            *buffer = 0;        /* just in case */
 
720
        }
 
721
    }
 
722
    return False;
 
723
}
 
724
 
 
725
static int
 
726
abbrev(char *tst, char *cmp, size_t need)
 
727
{
 
728
    size_t len = strlen(tst);
 
729
    return ((len >= need) && (!strncmp(tst, cmp, len)));
 
730
}
 
731
 
 
732
static void
 
733
Syntax(char *badOption)
 
734
{
 
735
    OptionHelp *opt;
 
736
    OptionHelp *list = sortedOpts(xtermOptions, optionDescList, XtNumber(optionDescList));
 
737
    int col;
 
738
 
 
739
    fprintf(stderr, "%s:  bad command line option \"%s\"\r\n\n",
 
740
            ProgramName, badOption);
 
741
 
 
742
    fprintf(stderr, "usage:  %s", ProgramName);
 
743
    col = 8 + strlen(ProgramName);
 
744
    for (opt = list; opt->opt; opt++) {
 
745
        int len = 3 + strlen(opt->opt);         /* space [ string ] */
 
746
        if (col + len > 79) {
 
747
            fprintf(stderr, "\r\n   ");         /* 3 spaces */
 
748
            col = 3;
 
749
        }
 
750
        fprintf(stderr, " [%s]", opt->opt);
 
751
        col += len;
 
752
    }
 
753
 
 
754
    fprintf(stderr, "\r\n\nType %s -help for a full description.\r\n\n",
 
755
            ProgramName);
 
756
    exit(1);
 
757
}
 
758
 
 
759
static void
 
760
Version(void)
 
761
{
 
762
    printf("%s(%d)\n", XFREE86_VERSION, XTERM_PATCH);
 
763
    fflush(stdout);
 
764
}
 
765
 
 
766
static void
 
767
Help(void)
 
768
{
 
769
    OptionHelp *opt;
 
770
    OptionHelp *list = sortedOpts(xtermOptions, optionDescList, XtNumber(optionDescList));
 
771
    char **cpp;
 
772
 
 
773
    fprintf(stderr,
 
774
            "%s(%d) usage:\n    %s [-options ...] [-e command args]\n\n",
 
775
            XFREE86_VERSION, XTERM_PATCH, ProgramName);
 
776
    fprintf(stderr, "where options include:\n");
 
777
    for (opt = list; opt->opt; opt++) {
 
778
        fprintf(stderr, "    %-28s %s\n", opt->opt, opt->desc);
 
779
    }
 
780
 
 
781
    putc('\n', stderr);
 
782
    for (cpp = message; *cpp; cpp++) {
 
783
        fputs(*cpp, stderr);
 
784
        putc('\n', stderr);
 
785
    }
 
786
    putc('\n', stderr);
 
787
    fflush(stderr);
 
788
}
 
789
 
 
790
/* ARGSUSED */
 
791
static Boolean
 
792
ConvertConsoleSelection(Widget w GCC_UNUSED,
 
793
                        Atom * selection GCC_UNUSED,
 
794
                        Atom * target GCC_UNUSED,
 
795
                        Atom * type GCC_UNUSED,
 
796
                        XtPointer * value GCC_UNUSED,
 
797
                        unsigned long *length GCC_UNUSED,
 
798
                        int *format GCC_UNUSED)
 
799
{
 
800
    /* we don't save console output, so can't offer it */
 
801
    return False;
 
802
}
 
803
 
 
804
#if OPT_SESSION_MGT
 
805
static void
 
806
die_callback(Widget w GCC_UNUSED,
 
807
             XtPointer client_data GCC_UNUSED,
 
808
             XtPointer call_data GCC_UNUSED)
 
809
{
 
810
    Cleanup(0);
 
811
}
 
812
 
 
813
static void
 
814
save_callback(Widget w GCC_UNUSED,
 
815
              XtPointer client_data GCC_UNUSED,
 
816
              XtPointer call_data)
 
817
{
 
818
    XtCheckpointToken token = (XtCheckpointToken) call_data;
 
819
    /* we have nothing to save */
 
820
    token->save_success = True;
 
821
}
 
822
#endif /* OPT_SESSION_MGT */
 
823
 
 
824
#if OPT_WIDE_CHARS
 
825
int (*my_wcwidth) (wchar_t);
 
826
#endif
 
827
 
 
828
/*
 
829
 * DeleteWindow(): Action proc to implement ICCCM delete_window.
 
830
 */
 
831
/* ARGSUSED */
 
832
static void
 
833
DeleteWindow(Widget w,
 
834
             XEvent * event GCC_UNUSED,
 
835
             String * params GCC_UNUSED,
 
836
             Cardinal * num_params GCC_UNUSED)
 
837
{
 
838
#if OPT_TEK4014
 
839
    if (w == toplevel) {
 
840
        if (term->screen.Tshow)
 
841
            hide_vt_window();
 
842
        else
 
843
            do_hangup(w, (XtPointer) 0, (XtPointer) 0);
 
844
    } else if (term->screen.Vshow)
 
845
        hide_tek_window();
 
846
    else
 
847
#endif
 
848
        do_hangup(w, (XtPointer) 0, (XtPointer) 0);
 
849
}
 
850
 
 
851
/* ARGSUSED */
 
852
static void
 
853
KeyboardMapping(Widget w GCC_UNUSED,
 
854
                XEvent * event,
 
855
                String * params GCC_UNUSED,
 
856
                Cardinal * num_params GCC_UNUSED)
 
857
{
 
858
    switch (event->type) {
 
859
    case MappingNotify:
 
860
        XRefreshKeyboardMapping(&event->xmapping);
 
861
        break;
 
862
    }
 
863
}
 
864
 
 
865
XtActionsRec actionProcs[] =
 
866
{
 
867
    {"DeleteWindow", DeleteWindow},
 
868
    {"KeyboardMapping", KeyboardMapping},
 
869
};
 
870
 
 
871
char **gblenvp;
 
872
extern char **environ;
 
873
 
 
874
int
 
875
main(int argc, char **argv ENVP_ARG)
 
876
{
 
877
    Widget form_top, menu_top;
 
878
    register TScreen *screen;
 
879
    int mode;
 
880
    char *my_class = DEFCLASS;
 
881
    Window winToEmbedInto = None;
 
882
 
 
883
    /* Do these first, since we may not be able to open the display */
 
884
    ProgramName = argv[0];
 
885
    TRACE_OPTS(xtermOptions, optionDescList, XtNumber(optionDescList));
 
886
    TRACE_ARGV("Before XtOpenApplication", argv);
 
887
    if (argc > 1) {
 
888
        int n;
 
889
        int unique = 2;
 
890
        Boolean quit = True;
 
891
 
 
892
        for (n = 1; n < argc; n++) {
 
893
            TRACE(("parsing %s\n", argv[n]));
 
894
            if (abbrev(argv[n], "-version", unique)) {
 
895
                Version();
 
896
            } else if (abbrev(argv[n], "-help", unique)) {
 
897
                Help();
 
898
            } else if (abbrev(argv[n], "-class", 3)) {
 
899
                if ((my_class = argv[++n]) == 0) {
 
900
                    Help();
 
901
                } else {
 
902
                    quit = False;
 
903
                }
 
904
                unique = 3;
 
905
            } else {
 
906
                quit = False;
 
907
                unique = 3;
 
908
            }
 
909
        }
 
910
        if (quit)
 
911
            exit(0);
 
912
    }
 
913
 
 
914
    /* XXX: for some obscure reason EMX seems to lose the value of
 
915
     * the environ variable, don't understand why, so save it recently
 
916
     */
 
917
    gblenvp = envp;
 
918
 
 
919
#ifdef I18N
 
920
    setlocale(LC_ALL, NULL);
 
921
#endif
 
922
 
 
923
/*debug opencons();*/
 
924
 
 
925
    ttydev = (char *) malloc(PTMS_BUFSZ);
 
926
    ptydev = (char *) malloc(PTMS_BUFSZ);
 
927
    if (!ttydev || !ptydev) {
 
928
        fprintf(stderr,
 
929
                "%s:  unable to allocate memory for ttydev or ptydev\n",
 
930
                ProgramName);
 
931
        exit(1);
 
932
    }
 
933
    strcpy(ttydev, TTYDEV);
 
934
    strcpy(ptydev, PTYDEV);
 
935
 
 
936
    /* Initialization is done here rather than above in order
 
937
     * to prevent any assumptions about the order of the contents
 
938
     * of the various terminal structures (which may change from
 
939
     * implementation to implementation).
 
940
     */
 
941
    d_tio.c_iflag = ICRNL | IXON;
 
942
    d_tio.c_oflag = OPOST | ONLCR | TAB3;
 
943
    d_tio.c_cflag = B38400 | CS8 | CREAD | PARENB | HUPCL;
 
944
    d_tio.c_lflag = ISIG | ICANON | ECHO | ECHOE | ECHOK;
 
945
    d_tio.c_line = 0;
 
946
    d_tio.c_cc[VINTR] = CONTROL('C');   /* '^C' */
 
947
    d_tio.c_cc[VERASE] = 0x7f;  /* DEL  */
 
948
    d_tio.c_cc[VKILL] = CONTROL('U');   /* '^U' */
 
949
    d_tio.c_cc[VQUIT] = CQUIT;  /* '^\' */
 
950
    d_tio.c_cc[VEOF] = CEOF;    /* '^D' */
 
951
    d_tio.c_cc[VEOL] = CEOL;    /* '^@' */
 
952
 
 
953
    /* Init the Toolkit. */
 
954
    XtSetErrorHandler(xt_error);
 
955
#if OPT_SESSION_MGT
 
956
    toplevel = XtOpenApplication(&app_con, my_class,
 
957
                                 optionDescList,
 
958
                                 XtNumber(optionDescList),
 
959
                                 &argc, argv, fallback_resources,
 
960
                                 sessionShellWidgetClass,
 
961
                                 NULL, 0);
 
962
#else
 
963
    toplevel = XtAppInitialize(&app_con, my_class,
 
964
                               optionDescList,
 
965
                               XtNumber(optionDescList),
 
966
                               &argc, argv, fallback_resources,
 
967
                               NULL, 0);
 
968
#endif /* OPT_SESSION_MGT */
 
969
    XtSetErrorHandler((XtErrorHandler) 0);
 
970
 
 
971
    XtGetApplicationResources(toplevel, (XtPointer) & resource,
 
972
                              application_resources,
 
973
                              XtNumber(application_resources), NULL, 0);
 
974
 
 
975
    waiting_for_initial_map = resource.wait_for_map;
 
976
 
 
977
    /*
 
978
     * ICCCM delete_window.
 
979
     */
 
980
    XtAppAddActions(app_con, actionProcs, XtNumber(actionProcs));
 
981
 
 
982
    /*
 
983
     * fill in terminal modes
 
984
     */
 
985
    if (resource.tty_modes) {
 
986
        int n = parse_tty_modes(resource.tty_modes, ttymodelist);
 
987
        if (n < 0) {
 
988
            fprintf(stderr, "%s:  bad tty modes \"%s\"\n",
 
989
                    ProgramName, resource.tty_modes);
 
990
        } else if (n > 0) {
 
991
            override_tty_modes = 1;
 
992
        }
 
993
    }
 
994
#if OPT_ZICONBEEP
 
995
    zIconBeep = resource.zIconBeep;
 
996
    zIconBeep_flagged = False;
 
997
    if (zIconBeep > 100 || zIconBeep < -100) {
 
998
        zIconBeep = 0;          /* was 100, but I prefer to defaulting off. */
 
999
        fprintf(stderr,
 
1000
                "a number between -100 and 100 is required for zIconBeep.  0 used by default\n");
 
1001
    }
 
1002
#endif /* OPT_ZICONBEEP */
 
1003
#if OPT_SAME_NAME
 
1004
    sameName = resource.sameName;
 
1005
#endif
 
1006
    hold_screen = resource.hold_screen ? 1 : 0;
 
1007
    xterm_name = resource.xterm_name;
 
1008
    if (strcmp(xterm_name, "-") == 0)
 
1009
        xterm_name = DFT_TERMTYPE;
 
1010
    if (resource.icon_geometry != NULL) {
 
1011
        int scr, junk;
 
1012
        int ix, iy;
 
1013
        Arg args[2];
 
1014
 
 
1015
        for (scr = 0;           /* yyuucchh */
 
1016
             XtScreen(toplevel) != ScreenOfDisplay(XtDisplay(toplevel), scr);
 
1017
             scr++) ;
 
1018
 
 
1019
        args[0].name = XtNiconX;
 
1020
        args[1].name = XtNiconY;
 
1021
        XGeometry(XtDisplay(toplevel), scr, resource.icon_geometry, "",
 
1022
                  0, 0, 0, 0, 0, &ix, &iy, &junk, &junk);
 
1023
        args[0].value = (XtArgVal) ix;
 
1024
        args[1].value = (XtArgVal) iy;
 
1025
        XtSetValues(toplevel, args, 2);
 
1026
    }
 
1027
 
 
1028
    XtSetValues(toplevel, ourTopLevelShellArgs,
 
1029
                number_ourTopLevelShellArgs);
 
1030
 
 
1031
#if OPT_WIDE_CHARS
 
1032
    /* seems as good a place as any */
 
1033
    init_classtab();
 
1034
#endif
 
1035
 
 
1036
    /* Parse the rest of the command line */
 
1037
    TRACE_ARGV("After XtOpenApplication", argv);
 
1038
    for (argc--, argv++; argc > 0; argc--, argv++) {
 
1039
        if (**argv != '-')
 
1040
            Syntax(*argv);
 
1041
 
 
1042
        TRACE(("parsing %s\n", argv[0]));
 
1043
        switch (argv[0][1]) {
 
1044
        case 'h':               /* -help */
 
1045
            Help();
 
1046
            continue;
 
1047
        case 'v':               /* -version */
 
1048
            Version();
 
1049
            continue;
 
1050
        case 'C':
 
1051
            {
 
1052
                struct stat sbuf;
 
1053
 
 
1054
                /* Must be owner and have read/write permission.
 
1055
                   xdm cooperates to give the console the right user. */
 
1056
                if (!stat("/dev/console", &sbuf) &&
 
1057
                    (sbuf.st_uid == getuid()) &&
 
1058
                    !access("/dev/console", R_OK | W_OK)) {
 
1059
                    Console = TRUE;
 
1060
                } else
 
1061
                    Console = FALSE;
 
1062
            }
 
1063
            continue;
 
1064
        case 'S':
 
1065
            if (sscanf(*argv + 2, "%c%c%d", passedPty, passedPty + 1,
 
1066
                       &am_slave) != 3)
 
1067
                Syntax(*argv);
 
1068
            continue;
 
1069
#ifdef DEBUG
 
1070
        case 'D':
 
1071
            debug = TRUE;
 
1072
            continue;
 
1073
#endif /* DEBUG */
 
1074
        case 'c':               /* -class param */
 
1075
            if (strcmp(argv[0] + 1, "class") == 0)
 
1076
                argc--, argv++;
 
1077
            else
 
1078
                Syntax(*argv);
 
1079
            continue;
 
1080
        case 'e':
 
1081
            if (argc <= 1)
 
1082
                Syntax(*argv);
 
1083
            command_to_exec = ++argv;
 
1084
            break;
 
1085
        case 'i':
 
1086
            if (argc <= 1) {
 
1087
                Syntax(*argv);
 
1088
            } else {
 
1089
                char *endPtr;
 
1090
                --argc;
 
1091
                ++argv;
 
1092
                winToEmbedInto = (Window) strtol(argv[0], &endPtr, 10);
 
1093
            }
 
1094
            break;
 
1095
 
 
1096
        default:
 
1097
            Syntax(*argv);
 
1098
        }
 
1099
        break;
 
1100
    }
 
1101
 
 
1102
    SetupMenus(toplevel, &form_top, &menu_top);
 
1103
 
 
1104
    term = (XtermWidget) XtVaCreateManagedWidget("vt100", xtermWidgetClass,
 
1105
                                                 form_top,
 
1106
#if OPT_TOOLBAR
 
1107
                                                 XtNmenuBar, menu_top,
 
1108
                                                 XtNresizable, True,
 
1109
                                                 XtNfromVert, menu_top,
 
1110
                                                 XtNleft, XawChainLeft,
 
1111
                                                 XtNright, XawChainRight,
 
1112
                                                 XtNbottom, XawChainBottom,
 
1113
#endif
 
1114
                                                 (XtPointer) 0);
 
1115
    /* this causes the initialize method to be called */
 
1116
 
 
1117
#if OPT_HP_FUNC_KEYS
 
1118
    init_keyboard_type(keyboardIsHP, resource.hpFunctionKeys);
 
1119
#endif
 
1120
    init_keyboard_type(keyboardIsSun, resource.sunFunctionKeys);
 
1121
#if OPT_SUNPC_KBD
 
1122
    init_keyboard_type(keyboardIsVT220, resource.sunKeyboard);
 
1123
#endif
 
1124
 
 
1125
    screen = &term->screen;
 
1126
 
 
1127
    inhibit = 0;
 
1128
#ifdef ALLOWLOGGING
 
1129
    if (term->misc.logInhibit)
 
1130
        inhibit |= I_LOG;
 
1131
#endif
 
1132
    if (term->misc.signalInhibit)
 
1133
        inhibit |= I_SIGNAL;
 
1134
#if OPT_TEK4014
 
1135
    if (term->misc.tekInhibit)
 
1136
        inhibit |= I_TEK;
 
1137
#endif
 
1138
 
 
1139
#if OPT_WIDE_CHARS
 
1140
    my_wcwidth = &mk_wcwidth;
 
1141
    if (term->misc.cjk_width)
 
1142
        my_wcwidth = &mk_wcwidth_cjk;
 
1143
#endif
 
1144
 
 
1145
#if OPT_SESSION_MGT
 
1146
    if (resource.sessionMgt) {
 
1147
        TRACE(("Enabling session-management callbacks\n"));
 
1148
        XtAddCallback(toplevel, XtNdieCallback, die_callback, NULL);
 
1149
        XtAddCallback(toplevel, XtNsaveCallback, save_callback, NULL);
 
1150
    }
 
1151
#endif
 
1152
 
 
1153
    /*
 
1154
     * Set title and icon name if not specified
 
1155
     */
 
1156
    if (command_to_exec) {
 
1157
        Arg args[2];
 
1158
 
 
1159
        if (!resource.title) {
 
1160
            if (command_to_exec) {
 
1161
                resource.title = x_basename(command_to_exec[0]);
 
1162
            }                   /* else not reached */
 
1163
        }
 
1164
 
 
1165
        if (!resource.icon_name)
 
1166
            resource.icon_name = resource.title;
 
1167
        XtSetArg(args[0], XtNtitle, resource.title);
 
1168
        XtSetArg(args[1], XtNiconName, resource.icon_name);
 
1169
 
 
1170
        TRACE(("setting:\n\ttitle \"%s\"\n\ticon \"%s\"\n\tbased on command \"%s\"\n",
 
1171
               resource.title,
 
1172
               resource.icon_name,
 
1173
               *command_to_exec));
 
1174
 
 
1175
        XtSetValues(toplevel, args, 2);
 
1176
    }
 
1177
#if OPT_LUIT_PROG
 
1178
    if (term->misc.callfilter) {
 
1179
        int u = (term->misc.use_encoding ? 2 : 0);
 
1180
        if (command_to_exec) {
 
1181
            int n;
 
1182
            char **c;
 
1183
            for (n = 0, c = command_to_exec; *c; n++, c++) ;
 
1184
            c = malloc((n + 3 + u) * sizeof(char *));
 
1185
            if (c == NULL)
 
1186
                SysError(ERROR_LUMALLOC);
 
1187
            memcpy(c + 2 + u, command_to_exec, (n + 1) * sizeof(char *));
 
1188
            c[0] = term->misc.localefilter;
 
1189
            if (u) {
 
1190
                c[1] = "-encoding";
 
1191
                c[2] = term->misc.locale_str;
 
1192
            }
 
1193
            c[1 + u] = "--";
 
1194
            command_to_exec_with_luit = c;
 
1195
        } else {
 
1196
            static char *luit[4];
 
1197
            luit[0] = term->misc.localefilter;
 
1198
            if (u) {
 
1199
                luit[1] = "-encoding";
 
1200
                luit[2] = term->misc.locale_str;
 
1201
                luit[3] = NULL;
 
1202
            } else
 
1203
                luit[1] = NULL;
 
1204
            command_to_exec_with_luit = luit;
 
1205
        }
 
1206
    }
 
1207
#endif
 
1208
#if OPT_TEK4014
 
1209
    if (inhibit & I_TEK)
 
1210
        screen->TekEmu = FALSE;
 
1211
 
 
1212
    if (screen->TekEmu && !TekInit())
 
1213
        exit(ERROR_INIT);
 
1214
#endif
 
1215
 
 
1216
#ifdef DEBUG
 
1217
    {
 
1218
        /* Set up stderr properly.  Opening this log file cannot be
 
1219
           done securely by a privileged xterm process (although we try),
 
1220
           so the debug feature is disabled by default. */
 
1221
        int i = -1;
 
1222
        if (debug) {
 
1223
            creat_as(getuid(), getgid(), True, "xterm.debug.log", 0666);
 
1224
            i = open("xterm.debug.log", O_WRONLY | O_TRUNC);
 
1225
        }
 
1226
        if (i >= 0) {
 
1227
            dup2(i, 2);
 
1228
 
 
1229
            /* mark this file as close on exec */
 
1230
            (void) fcntl(i, F_SETFD, 1);
 
1231
        }
 
1232
    }
 
1233
#endif /* DEBUG */
 
1234
 
 
1235
    /* open a terminal for client */
 
1236
    get_terminal();
 
1237
 
 
1238
    spawn();
 
1239
 
 
1240
    /* Child process is out there, let's catch its termination */
 
1241
    (void) signal(SIGCHLD, reapchild);
 
1242
 
 
1243
    /* Realize procs have now been executed */
 
1244
 
 
1245
    if (am_slave >= 0) {        /* Write window id so master end can read and use */
 
1246
        char buf[80];
 
1247
 
 
1248
        buf[0] = '\0';
 
1249
        sprintf(buf, "%lx\n", XtWindow(XtParent(CURRENT_EMU(screen))));
 
1250
        write(screen->respond, buf, strlen(buf));
 
1251
    }
 
1252
 
 
1253
    screen->inhibit = inhibit;
 
1254
 
 
1255
    if (0 > (mode = fcntl(screen->respond, F_GETFL, 0)))
 
1256
        SysError(ERROR_F_GETFL);
 
1257
    mode |= O_NDELAY;
 
1258
 
 
1259
    if (fcntl(screen->respond, F_SETFL, mode))
 
1260
        SysError(ERROR_F_SETFL);
 
1261
 
 
1262
    FD_ZERO(&pty_mask);
 
1263
    FD_ZERO(&X_mask);
 
1264
    FD_ZERO(&Select_mask);
 
1265
    FD_SET(screen->respond, &pty_mask);
 
1266
    FD_SET(ConnectionNumber(screen->display), &X_mask);
 
1267
    FD_SET(screen->respond, &Select_mask);
 
1268
    FD_SET(ConnectionNumber(screen->display), &Select_mask);
 
1269
    max_plus1 = ((screen->respond < ConnectionNumber(screen->display))
 
1270
                 ? (1 + ConnectionNumber(screen->display))
 
1271
                 : (1 + screen->respond));
 
1272
 
 
1273
#ifdef DEBUG
 
1274
    if (debug)
 
1275
        printf("debugging on\n");
 
1276
#endif /* DEBUG */
 
1277
    XSetErrorHandler(xerror);
 
1278
    XSetIOErrorHandler(xioerror);
 
1279
 
 
1280
#ifdef ALLOWLOGGING
 
1281
    if (term->misc.log_on) {
 
1282
        StartLog(screen);
 
1283
    }
 
1284
#endif
 
1285
 
 
1286
    if (winToEmbedInto != None) {
 
1287
        XtRealizeWidget(toplevel);
 
1288
        /*
 
1289
         * This should probably query the tree or check the attributes of
 
1290
         * winToEmbedInto in order to verify that it exists, but I'm still not
 
1291
         * certain what is the best way to do it -GPS
 
1292
         */
 
1293
        XReparentWindow(XtDisplay(toplevel),
 
1294
                        XtWindow(toplevel),
 
1295
                        winToEmbedInto, 0, 0);
 
1296
    }
 
1297
 
 
1298
    for (;;) {
 
1299
#if OPT_TEK4014
 
1300
        if (screen->TekEmu)
 
1301
            TekRun();
 
1302
        else
 
1303
#endif
 
1304
            VTRun();
 
1305
    }
 
1306
    return 0;
 
1307
}
 
1308
 
 
1309
/*
 
1310
 * Called from get_pty to iterate over likely pseudo terminals
 
1311
 * we might allocate.  Used on those systems that do not have
 
1312
 * a functional interface for allocating a pty.
 
1313
 * Returns 0 if found a pty, 1 if fails.
 
1314
 */
 
1315
static int
 
1316
pty_search(int *pty)
 
1317
{
 
1318
    char namebuf[PTMS_BUFSZ];
 
1319
 
 
1320
    /* ask the PTY manager */
 
1321
    int fd = open("/dev/ptms$", 0);
 
1322
    if (fd && ptioctl(fd, PTMS_GETPTY, namebuf) == 0) {
 
1323
        strcpy(ttydev, namebuf);
 
1324
        strcpy(ptydev, namebuf);
 
1325
        *x_basename(ttydev) = 't';
 
1326
        close(fd);
 
1327
        if ((*pty = open(ptydev, O_RDWR)) >= 0) {
 
1328
#ifdef PTYDEBUG
 
1329
            ptioctl(*pty, XTY_TRACE, 0);
 
1330
#endif
 
1331
            return 0;
 
1332
        }
 
1333
    }
 
1334
    return 1;
 
1335
}
 
1336
 
 
1337
/*
 
1338
 * This function opens up a pty master and stuffs its value into pty.
 
1339
 *
 
1340
 * If it finds one, it returns a value of 0.  If it does not find one,
 
1341
 * it returns a value of !0.  This routine is designed to be re-entrant,
 
1342
 * so that if a pty master is found and later, we find that the slave
 
1343
 * has problems, we can re-enter this function and get another one.
 
1344
 */
 
1345
static int
 
1346
get_pty(int *pty)
 
1347
{
 
1348
    return pty_search(pty);
 
1349
}
 
1350
 
 
1351
/*
 
1352
 * sets up X and initializes the terminal structure except for term.buf.fildes.
 
1353
 */
 
1354
static void
 
1355
get_terminal(void)
 
1356
{
 
1357
    register TScreen *screen = &term->screen;
 
1358
 
 
1359
    screen->arrow = make_colored_cursor(XC_left_ptr,
 
1360
                                        screen->mousecolor,
 
1361
                                        screen->mousecolorback);
 
1362
}
 
1363
 
 
1364
/*
 
1365
 * The only difference in /etc/termcap between 4014 and 4015 is that
 
1366
 * the latter has support for switching character sets.  We support the
 
1367
 * 4015 protocol, but ignore the character switches.  Therefore, we
 
1368
 * choose 4014 over 4015.
 
1369
 *
 
1370
 * Features of the 4014 over the 4012: larger (19") screen, 12-bit
 
1371
 * graphics addressing (compatible with 4012 10-bit addressing),
 
1372
 * special point plot mode, incremental plot mode (not implemented in
 
1373
 * later Tektronix terminals), and 4 character sizes.
 
1374
 * All of these are supported by xterm.
 
1375
 */
 
1376
 
 
1377
#if OPT_TEK4014
 
1378
static char *tekterm[] =
 
1379
{
 
1380
    "tek4014",
 
1381
    "tek4015",                  /* 4014 with APL character set support */
 
1382
    "tek4012",                  /* 4010 with lower case */
 
1383
    "tek4013",                  /* 4012 with APL character set support */
 
1384
    "tek4010",                  /* small screen, upper-case only */
 
1385
    "dumb",
 
1386
    0
 
1387
};
 
1388
#endif
 
1389
 
 
1390
/* The VT102 is a VT100 with the Advanced Video Option included standard.
 
1391
 * It also adds Escape sequences for insert/delete character/line.
 
1392
 * The VT220 adds 8-bit character sets, selective erase.
 
1393
 * The VT320 adds a 25th status line, terminal state interrogation.
 
1394
 * The VT420 has up to 48 lines on the screen.
 
1395
 */
 
1396
 
 
1397
static char *vtterm[] =
 
1398
{
 
1399
#ifdef USE_X11TERM
 
1400
    "x11term",                  /* for people who want special term name */
 
1401
#endif
 
1402
    DFT_TERMTYPE,               /* for people who want special term name */
 
1403
    "xterm",                    /* the prefered name, should be fastest */
 
1404
    "vt102",
 
1405
    "vt100",
 
1406
    "ansi",
 
1407
    "dumb",
 
1408
    0
 
1409
};
 
1410
 
 
1411
/* ARGSUSED */
 
1412
static SIGNAL_T
 
1413
hungtty(int i GCC_UNUSED)
 
1414
{
 
1415
    longjmp(env, 1);
 
1416
    SIGNAL_RETURN;
 
1417
}
 
1418
 
 
1419
struct {
 
1420
    int rows;
 
1421
    int cols;
 
1422
} handshake = {
 
1423
 
 
1424
    -1, -1
 
1425
};
 
1426
 
 
1427
void
 
1428
first_map_occurred(void)
 
1429
{
 
1430
    register TScreen *screen = &term->screen;
 
1431
    handshake.rows = screen->max_row;
 
1432
    handshake.cols = screen->max_col;
 
1433
    waiting_for_initial_map = False;
 
1434
}
 
1435
 
 
1436
static void
 
1437
set_owner(char *device, int uid, int gid, int mode)
 
1438
{
 
1439
    if (chown(device, uid, gid) < 0) {
 
1440
        if (errno != ENOENT
 
1441
            && getuid() == 0) {
 
1442
            fprintf(stderr, "Cannot chown %s to %d,%d: %s\n",
 
1443
                    device, uid, gid, strerror(errno));
 
1444
        }
 
1445
    }
 
1446
    chmod(device, mode);
 
1447
}
 
1448
 
 
1449
#define THE_PARENT 1
 
1450
#define THE_CHILD  2
 
1451
int whoami = -1;
 
1452
 
 
1453
SIGNAL_T
 
1454
killit(int sig)
 
1455
{
 
1456
    switch (whoami) {
 
1457
    case -1:
 
1458
        signal(sig, killit);
 
1459
        kill(-getpid(), sig);
 
1460
        break;
 
1461
    case THE_PARENT:
 
1462
        wait(NULL);
 
1463
        signal(SIGTERM, SIG_DFL);
 
1464
        kill(-getpid(), SIGTERM);
 
1465
        Exit(0);
 
1466
        break;
 
1467
    case THE_CHILD:
 
1468
        signal(SIGTERM, SIG_DFL);
 
1469
        kill(-getppid(), SIGTERM);
 
1470
        Exit(0);
 
1471
        break;
 
1472
    }
 
1473
 
 
1474
    SIGNAL_RETURN;
 
1475
}
 
1476
 
 
1477
static int
 
1478
spawn(void)
 
1479
/*
 
1480
 *  Inits pty and tty and forks a login process.
 
1481
 *  Does not close fd Xsocket.
 
1482
 *  If slave, the pty named in passedPty is already open for use
 
1483
 */
 
1484
{
 
1485
    register TScreen *screen = &term->screen;
 
1486
    int Xsocket = ConnectionNumber(screen->display);
 
1487
 
 
1488
    int tty = -1;
 
1489
    struct termio tio;
 
1490
    int status;
 
1491
 
 
1492
    char termcap[TERMCAP_SIZE], newtc[TERMCAP_SIZE];
 
1493
    char *TermName = NULL;
 
1494
    char *ptr, *shname, buf[64];
 
1495
    int i, no_dev_tty = FALSE, envsize;
 
1496
    char *dev_tty_name = (char *) 0;
 
1497
    struct winsize ws;
 
1498
    int pgrp = getpid();
 
1499
    char numbuf[12], **envnew;
 
1500
 
 
1501
    screen->uid = getuid();
 
1502
    screen->gid = getgid();
 
1503
 
 
1504
    if (am_slave >= 0) {
 
1505
        screen->respond = am_slave;
 
1506
        ptydev[strlen(ptydev) - 2] =
 
1507
            ttydev[strlen(ttydev) - 2] = passedPty[0];
 
1508
        ptydev[strlen(ptydev) - 1] =
 
1509
            ttydev[strlen(ttydev) - 1] = passedPty[1];
 
1510
 
 
1511
        setgid(screen->gid);
 
1512
        setuid(screen->uid);
 
1513
    } else {
 
1514
        Bool tty_got_hung;
 
1515
 
 
1516
        /*
 
1517
         * Sometimes /dev/tty hangs on open (as in the case of a pty
 
1518
         * that has gone away).  Simply make up some reasonable
 
1519
         * defaults.
 
1520
         */
 
1521
 
 
1522
        signal(SIGALRM, hungtty);
 
1523
        alarm(2);               /* alarm(1) might return too soon */
 
1524
        if (!setjmp(env)) {
 
1525
            tty = open("/dev/tty", O_RDWR);
 
1526
            alarm(0);
 
1527
            tty_got_hung = False;
 
1528
        } else {
 
1529
            tty_got_hung = True;
 
1530
            tty = -1;
 
1531
            errno = ENXIO;
 
1532
        }
 
1533
        signal(SIGALRM, SIG_DFL);
 
1534
 
 
1535
        /*
 
1536
         * Check results and ignore current control terminal if
 
1537
         * necessary.  ENXIO is what is normally returned if there is
 
1538
         * no controlling terminal, but some systems (e.g. SunOS 4.0)
 
1539
         * seem to return EIO.  Solaris 2.3 is said to return EINVAL.
 
1540
         */
 
1541
        if (tty < 0) {
 
1542
            if (tty_got_hung || errno == ENXIO || errno == EIO ||
 
1543
                errno == EINVAL || errno == ENOTTY) {
 
1544
                no_dev_tty = TRUE;
 
1545
                tio = d_tio;
 
1546
            } else {
 
1547
                SysError(ERROR_OPDEVTTY);
 
1548
            }
 
1549
        } else {
 
1550
 
 
1551
            /* Get a copy of the current terminal's state,
 
1552
             * if we can.  Some systems (e.g., SVR4 and MacII)
 
1553
             * may not have a controlling terminal at this point
 
1554
             * if started directly from xdm or xinit,
 
1555
             * in which case we just use the defaults as above.
 
1556
             */
 
1557
            if (ioctl(tty, TCGETA, &tio) == -1)
 
1558
                tio = d_tio;
 
1559
 
 
1560
            close(tty);
 
1561
            /* tty is no longer an open fd! */
 
1562
            tty = -1;
 
1563
        }
 
1564
 
 
1565
        if (get_pty(&screen->respond)) {
 
1566
            /*  no ptys! */
 
1567
            exit(ERROR_PTYS);
 
1568
        }
 
1569
    }
 
1570
 
 
1571
    /* avoid double MapWindow requests */
 
1572
    XtSetMappedWhenManaged(XtParent(CURRENT_EMU(screen)), False);
 
1573
 
 
1574
    wm_delete_window = XInternAtom(XtDisplay(toplevel), "WM_DELETE_WINDOW",
 
1575
                                   False);
 
1576
 
 
1577
    if (!TEK4014_ACTIVE(screen))
 
1578
        VTInit();               /* realize now so know window size for tty driver */
 
1579
 
 
1580
    if (Console) {
 
1581
        /*
 
1582
         * Inform any running xconsole program
 
1583
         * that we are going to steal the console.
 
1584
         */
 
1585
        XmuGetHostname(mit_console_name + MIT_CONSOLE_LEN, 255);
 
1586
        mit_console = XInternAtom(screen->display, mit_console_name, False);
 
1587
        /* the user told us to be the console, so we can use CurrentTime */
 
1588
        XtOwnSelection(XtParent(CURRENT_EMU(screen)),
 
1589
                       mit_console, CurrentTime,
 
1590
                       ConvertConsoleSelection, NULL, NULL);
 
1591
    }
 
1592
#if OPT_TEK4014
 
1593
    if (screen->TekEmu) {
 
1594
        envnew = tekterm;
 
1595
        ptr = newtc;
 
1596
    } else
 
1597
#endif
 
1598
    {
 
1599
        envnew = vtterm;
 
1600
        ptr = termcap;
 
1601
    }
 
1602
 
 
1603
    /*
 
1604
     * This used to exit if no termcap entry was found for the specified
 
1605
     * terminal name.  That's a little unfriendly, so instead we'll allow
 
1606
     * the program to proceed (but not to set $TERMCAP) if the termcap
 
1607
     * entry is not found.
 
1608
     */
 
1609
    get_termcap(TermName = resource.term_name, ptr, newtc);
 
1610
 
 
1611
    /*
 
1612
     * This block is invoked only if there was no terminal name specified
 
1613
     * by the command-line option "-tn".
 
1614
     */
 
1615
    if (!TermName) {
 
1616
        TermName = *envnew;
 
1617
        while (*envnew != NULL) {
 
1618
            if (get_termcap(*envnew, ptr, newtc)) {
 
1619
                TermName = *envnew;
 
1620
                break;
 
1621
            }
 
1622
            envnew++;
 
1623
        }
 
1624
    }
 
1625
 
 
1626
    /* tell tty how big window is */
 
1627
#if OPT_TEK4014
 
1628
    if (TEK4014_ACTIVE(screen)) {
 
1629
        ws.ws_row = 38;
 
1630
        ws.ws_col = 81;
 
1631
        ws.ws_xpixel = TFullWidth(screen);
 
1632
        ws.ws_ypixel = TFullHeight(screen);
 
1633
    } else
 
1634
#endif
 
1635
    {
 
1636
        ws.ws_row = screen->max_row + 1;
 
1637
        ws.ws_col = screen->max_col + 1;
 
1638
        ws.ws_xpixel = FullWidth(screen);
 
1639
        ws.ws_ypixel = FullHeight(screen);
 
1640
    }
 
1641
 
 
1642
    if (am_slave < 0) {
 
1643
 
 
1644
        char sema[40];
 
1645
        HEV sev;
 
1646
        /* start a child process
 
1647
         * use an event sema for sync
 
1648
         */
 
1649
        sprintf(sema, "\\SEM32\\xterm%s", &ptydev[8]);
 
1650
        if (DosCreateEventSem(sema, &sev, DC_SEM_SHARED, FALSE))
 
1651
            SysError(ERROR_FORK);
 
1652
 
 
1653
        switch ((screen->pid = fork())) {
 
1654
        case -1:                /* error */
 
1655
            SysError(ERROR_FORK);
 
1656
        default:                /* parent */
 
1657
            whoami = THE_PARENT;
 
1658
            DosWaitEventSem(sev, 1000L);
 
1659
            DosCloseEventSem(sev);
 
1660
            break;
 
1661
        case 0:         /* child */
 
1662
            whoami = THE_CHILD;
 
1663
 
 
1664
/*debug fclose(confd);
 
1665
opencons();*/
 
1666
            /* we don't need the socket, or the pty master anymore */
 
1667
            close(ConnectionNumber(screen->display));
 
1668
            close(screen->respond);
 
1669
 
 
1670
            /* Now is the time to set up our process group and
 
1671
             * open up the pty slave.
 
1672
             */
 
1673
            if ((tty = open(ttydev, O_RDWR)) < 0) {
 
1674
                /* dumm gelaufen */
 
1675
                fprintf(stderr, "Cannot open slave side of PTY\n");
 
1676
                exit(1);
 
1677
            }
 
1678
 
 
1679
            /* use the same tty name that everyone else will use
 
1680
             * (from ttyname)
 
1681
             */
 
1682
#ifdef EMXNOTBOGUS
 
1683
            if ((ptr = ttyname(tty)) != 0) {
 
1684
                /* it may be bigger */
 
1685
                ttydev = realloc(ttydev,
 
1686
                                 (unsigned) (strlen(ptr) + 1));
 
1687
                if (ttydev == NULL) {
 
1688
                    SysError(ERROR_SPREALLOC);
 
1689
                }
 
1690
                (void) strcpy(ttydev, ptr);
 
1691
            }
 
1692
#else
 
1693
            ptr = ttydev;
 
1694
#endif
 
1695
            /* for safety: enable DUPs */
 
1696
            ptioctl(tty, XTY_ENADUP, 0);
 
1697
 
 
1698
            /* change ownership of tty to real group and user id */
 
1699
            set_owner(ttydev, screen->uid, screen->gid,
 
1700
                      (resource.messages ? 0622 : 0600));
 
1701
 
 
1702
            /* for the xf86sup-pty, we set the pty to bypass: OS/2 does
 
1703
             * not have a line discipline structure
 
1704
             */
 
1705
            {
 
1706
                struct termio t, t1;
 
1707
                if (ptioctl(tty, TCGETA, (char *) &t) < 0)
 
1708
                    t = d_tio;
 
1709
 
 
1710
                t.c_iflag = ICRNL;
 
1711
                t.c_oflag = OPOST | ONLCR;
 
1712
                t.c_lflag = ISIG | ICANON | ECHO | ECHOE | ECHOK;
 
1713
 
 
1714
                /* ignore error code, user will see it :-) */
 
1715
                ptioctl(tty, TCSETA, (char *) &t);
 
1716
 
 
1717
                /* set the console mode */
 
1718
                if (Console) {
 
1719
                    int on = 1;
 
1720
                    if (ioctl(tty, TIOCCONS, (char *) &on) == -1)
 
1721
                        fprintf(stderr, "%s: cannot open console\n", xterm_name);
 
1722
                }
 
1723
            }
 
1724
 
 
1725
            signal(SIGCHLD, SIG_DFL);
 
1726
            signal(SIGHUP, SIG_IGN);
 
1727
 
 
1728
            /* restore various signals to their defaults */
 
1729
            signal(SIGINT, SIG_DFL);
 
1730
            signal(SIGQUIT, SIG_DFL);
 
1731
            signal(SIGTERM, SIG_DFL);
 
1732
 
 
1733
            /* copy the environment before Setenving */
 
1734
            for (i = 0; gblenvp[i] != NULL; i++) ;
 
1735
 
 
1736
            /* compute number of xtermSetenv() calls below */
 
1737
            envsize = 1;        /* (NULL terminating entry) */
 
1738
            envsize += 3;       /* TERM, WINDOWID, DISPLAY */
 
1739
            envsize += 2;       /* COLUMNS, LINES */
 
1740
 
 
1741
            envnew = (char **) calloc((unsigned) i + envsize, sizeof(char *));
 
1742
            memmove((char *) envnew, (char *) gblenvp, i * sizeof(char *));
 
1743
            gblenvp = envnew;
 
1744
            xtermSetenv("TERM=", TermName);
 
1745
            if (!TermName)
 
1746
                *newtc = 0;
 
1747
 
 
1748
            sprintf(buf, "%lu",
 
1749
                    ((unsigned long) XtWindow(XtParent(CURRENT_EMU(screen)))));
 
1750
            xtermSetenv("WINDOWID=", buf);
 
1751
 
 
1752
            /* put the display into the environment of the shell */
 
1753
            xtermSetenv("DISPLAY=", XDisplayString(screen->display));
 
1754
 
 
1755
            signal(SIGTERM, SIG_DFL);
 
1756
 
 
1757
            /* this is the time to go and set up stdin, out, and err
 
1758
             */
 
1759
            /* dup the tty */
 
1760
            for (i = 0; i <= 2; i++)
 
1761
                if (i != tty) {
 
1762
                    (void) close(i);
 
1763
                    (void) dup(tty);
 
1764
                }
 
1765
 
 
1766
            /* and close the tty */
 
1767
            if (tty > 2)
 
1768
                (void) close(tty);
 
1769
 
 
1770
            setpgrp(0, pgrp);
 
1771
            setgid(screen->gid);
 
1772
            setuid(screen->uid);
 
1773
 
 
1774
            if (handshake.rows > 0 && handshake.cols > 0) {
 
1775
                screen->max_row = handshake.rows;
 
1776
                screen->max_col = handshake.cols;
 
1777
                ws.ws_row = screen->max_row + 1;
 
1778
                ws.ws_col = screen->max_col + 1;
 
1779
                ws.ws_xpixel = FullWidth(screen);
 
1780
                ws.ws_ypixel = FullHeight(screen);
 
1781
            }
 
1782
 
 
1783
            sprintf(numbuf, "%d", screen->max_col + 1);
 
1784
            xtermSetenv("COLUMNS=", numbuf);
 
1785
            sprintf(numbuf, "%d", screen->max_row + 1);
 
1786
            xtermSetenv("LINES=", numbuf);
 
1787
 
 
1788
            /* reconstruct dead environ variable */
 
1789
            environ = gblenvp;
 
1790
 
 
1791
            /* need to reset after all the ioctl bashing we did above */
 
1792
            ptioctl(0, TIOCSWINSZ, (char *) &ws);
 
1793
 
 
1794
            signal(SIGHUP, SIG_DFL);
 
1795
 
 
1796
            /* okay everything seems right, so tell the parent, we are going */
 
1797
            {
 
1798
                char sema[40];
 
1799
                HEV sev;
 
1800
                sprintf(sema, "\\SEM32\\xterm%s", &ttydev[8]);
 
1801
                DosOpenEventSem(sema, &sev);
 
1802
                DosPostEventSem(sev);
 
1803
                DosCloseEventSem(sev);
 
1804
            }
 
1805
 
 
1806
#if OPT_LUIT_PROG
 
1807
            /*
 
1808
             * Use two copies of command_to_exec, in case luit is not actually
 
1809
             * there, or refuses to run.  In that case we will fall-through to
 
1810
             * to command that the user gave anyway.
 
1811
             */
 
1812
            if (command_to_exec_with_luit) {
 
1813
                TRACE(("spawning command \"%s\"\n", *command_to_exec_with_luit));
 
1814
                execvp(*command_to_exec_with_luit, command_to_exec_with_luit);
 
1815
                /* print error message on screen */
 
1816
                fprintf(stderr, "%s: Can't execvp %s: %s\n",
 
1817
                        xterm_name, *command_to_exec_with_luit, strerror(errno));
 
1818
                fprintf(stderr, "%s: cannot support your locale.\n",
 
1819
                        xterm_name);
 
1820
            }
 
1821
#endif
 
1822
            if (command_to_exec) {
 
1823
                TRACE(("spawning command \"%s\"\n", *command_to_exec));
 
1824
                execvpe(*command_to_exec, command_to_exec, gblenvp);
 
1825
 
 
1826
                /* print error message on screen */
 
1827
                fprintf(stderr, "%s: Can't execvp %s\n",
 
1828
                        xterm_name, *command_to_exec);
 
1829
            }
 
1830
 
 
1831
            /* use a layered mechanism to find a shell */
 
1832
            ptr = getenv("X11SHELL");
 
1833
            if (!ptr)
 
1834
                ptr = getenv("SHELL");
 
1835
            if (!ptr)
 
1836
                ptr = getenv("OS2_SHELL");
 
1837
            if (!ptr)
 
1838
                ptr = "SORRY_NO_SHELL_FOUND";
 
1839
 
 
1840
            shname = x_basename(ptr);
 
1841
            if (command_to_exec) {
 
1842
                char *exargv[10];       /*XXX */
 
1843
 
 
1844
                exargv[0] = ptr;
 
1845
                exargv[1] = "/C";
 
1846
                exargv[2] = command_to_exec[0];
 
1847
                exargv[3] = command_to_exec[1];
 
1848
                exargv[4] = command_to_exec[2];
 
1849
                exargv[5] = command_to_exec[3];
 
1850
                exargv[6] = command_to_exec[4];
 
1851
                exargv[7] = command_to_exec[5];
 
1852
                exargv[8] = command_to_exec[6];
 
1853
                exargv[9] = 0;
 
1854
                execvpe(exargv[0], exargv, gblenvp);
 
1855
/*
 
1856
                execvpe(*command_to_exec, command_to_exec, gblenvp);
 
1857
*/
 
1858
                /* print error message on screen */
 
1859
                fprintf(stderr, "%s: Can't execvp %s\n",
 
1860
                        xterm_name, *command_to_exec);
 
1861
            } else {
 
1862
                execlpe(ptr, shname, 0, gblenvp);
 
1863
 
 
1864
                /* Exec failed. */
 
1865
                fprintf(stderr, "%s: Could not exec %s!\n",
 
1866
                        xterm_name, ptr);
 
1867
            }
 
1868
            sleep(5);
 
1869
 
 
1870
            /* preventively shoot the parent */
 
1871
            kill(-getppid(), SIGTERM);
 
1872
 
 
1873
            exit(ERROR_EXEC);
 
1874
        }                       /* endcase */
 
1875
    }
 
1876
    /* !am_slave */
 
1877
    signal(SIGHUP, SIG_IGN);
 
1878
/*
 
1879
 * Unfortunately, System V seems to have trouble divorcing the child process
 
1880
 * from the process group of xterm.  This is a problem because hitting the
 
1881
 * INTR or QUIT characters on the keyboard will cause xterm to go away if we
 
1882
 * don't ignore the signals.  This is annoying.
 
1883
 */
 
1884
 
 
1885
/*  signal (SIGINT, SIG_IGN);*/
 
1886
    signal(SIGINT, killit);
 
1887
    signal(SIGTERM, killit);
 
1888
 
 
1889
    /* hung shell problem */
 
1890
    signal(SIGQUIT, SIG_IGN);
 
1891
/*  signal (SIGTERM, SIG_IGN);*/
 
1892
    return 0;
 
1893
}                               /* end spawn */
 
1894
 
 
1895
SIGNAL_T
 
1896
Exit(int n)
 
1897
{
 
1898
    register TScreen *screen = &term->screen;
 
1899
    int pty = term->screen.respond;     /* file descriptor of pty */
 
1900
    close(pty);                 /* close explicitly to avoid race with slave side */
 
1901
#ifdef ALLOWLOGGING
 
1902
    if (screen->logging)
 
1903
        CloseLog(screen);
 
1904
#endif
 
1905
    if (am_slave < 0) {
 
1906
        /* restore ownership of tty and pty */
 
1907
        set_owner(ttydev, 0, 0, 0666);
 
1908
        set_owner(ptydev, 0, 0, 0666);
 
1909
    }
 
1910
    exit(n);
 
1911
    SIGNAL_RETURN;
 
1912
}
 
1913
 
 
1914
/* ARGSUSED */
 
1915
static void
 
1916
resize(TScreen * screen, register char *oldtc, char *newtc)
 
1917
{
 
1918
}
 
1919
 
 
1920
/*
 
1921
 * Does a non-blocking wait for a child process.  If the system
 
1922
 * doesn't support non-blocking wait, do nothing.
 
1923
 * Returns the pid of the child, or 0 or -1 if none or error.
 
1924
 */
 
1925
int
 
1926
nonblocking_wait(void)
 
1927
{
 
1928
    pid_t pid;
 
1929
 
 
1930
    pid = waitpid(-1, NULL, WNOHANG);
 
1931
    return pid;
 
1932
}
 
1933
 
 
1934
/* ARGSUSED */
 
1935
static SIGNAL_T
 
1936
reapchild(int n GCC_UNUSED)
 
1937
{
 
1938
    int olderrno = errno;
 
1939
    int pid;
 
1940
 
 
1941
    pid = wait(NULL);
 
1942
 
 
1943
    /* cannot re-enable signal before waiting for child
 
1944
     * because then SVR4 loops.  Sigh.  HP-UX 9.01 too.
 
1945
     */
 
1946
    (void) signal(SIGCHLD, reapchild);
 
1947
 
 
1948
    do {
 
1949
        if (pid == term->screen.pid) {
 
1950
#ifdef DEBUG
 
1951
            if (debug)
 
1952
                fputs("Exiting\n", stderr);
 
1953
#endif
 
1954
            if (!hold_screen)
 
1955
                Cleanup(0);
 
1956
        }
 
1957
    } while ((pid = nonblocking_wait()) > 0);
 
1958
 
 
1959
    errno = olderrno;
 
1960
    SIGNAL_RETURN;
 
1961
}
 
1962
 
 
1963
/*
 
1964
 * parse_tty_modes accepts lines of the following form:
 
1965
 *
 
1966
 *         [SETTING] ...
 
1967
 *
 
1968
 * where setting consists of the words in the modelist followed by a character
 
1969
 * or ^char.
 
1970
 */
 
1971
static int
 
1972
parse_tty_modes(char *s, struct _xttymodes *modelist)
 
1973
{
 
1974
    struct _xttymodes *mp;
 
1975
    int c;
 
1976
    int count = 0;
 
1977
 
 
1978
    TRACE(("parse_tty_modes\n"));
 
1979
    while (1) {
 
1980
        while (*s && isascii(CharOf(*s)) && isspace(CharOf(*s)))
 
1981
            s++;
 
1982
        if (!*s)
 
1983
            return count;
 
1984
 
 
1985
        for (mp = modelist; mp->name; mp++) {
 
1986
            if (strncmp(s, mp->name, mp->len) == 0)
 
1987
                break;
 
1988
        }
 
1989
        if (!mp->name)
 
1990
            return -1;
 
1991
 
 
1992
        s += mp->len;
 
1993
        while (*s && isascii(CharOf(*s)) && isspace(CharOf(*s)))
 
1994
            s++;
 
1995
        if (!*s)
 
1996
            return -1;
 
1997
 
 
1998
        if ((c = decode_keyvalue(&s, False)) != -1) {
 
1999
            mp->value = c;
 
2000
            mp->set = 1;
 
2001
            count++;
 
2002
            TRACE(("...parsed #%d: %s=%#x\n", count, mp->name, c));
 
2003
        }
 
2004
    }
 
2005
}
 
2006
 
 
2007
int
 
2008
GetBytesAvailable(int fd)
 
2009
{
 
2010
    long arg;
 
2011
    ioctl(fd, FIONREAD, (char *) &arg);
 
2012
    return (int) arg;
 
2013
}
 
2014
 
 
2015
/* Utility function to try to hide system differences from
 
2016
   everybody who used to call killpg() */
 
2017
 
 
2018
int
 
2019
kill_process_group(int pid, int sig)
 
2020
{
 
2021
    return kill(-pid, sig);
 
2022
}
 
2023
 
 
2024
int
 
2025
ptioctl(int fd, int func, void *data)
 
2026
{
 
2027
    APIRET rc;
 
2028
    ULONG len;
 
2029
    struct pt_termios pt;
 
2030
    struct termio *t;
 
2031
    int i;
 
2032
 
 
2033
    switch (func) {
 
2034
    case TCGETA:
 
2035
        rc = DosDevIOCtl(fd, XFREE86_PTY, func,
 
2036
                         NULL, 0, NULL,
 
2037
                         (ULONG *) & pt, sizeof(struct pt_termios), &len);
 
2038
        if (rc)
 
2039
            return -1;
 
2040
        t = (struct termio *) data;
 
2041
        t->c_iflag = pt.c_iflag;
 
2042
        t->c_oflag = pt.c_oflag;
 
2043
        t->c_cflag = pt.c_cflag;
 
2044
        t->c_lflag = pt.c_lflag;
 
2045
        for (i = 0; i < NCC; i++)
 
2046
            t->c_cc[i] = pt.c_cc[i];
 
2047
        return 0;
 
2048
    case TCSETA:
 
2049
    case TCSETAW:
 
2050
    case TCSETAF:
 
2051
        t = (struct termio *) data;
 
2052
        pt.c_iflag = t->c_iflag;
 
2053
        pt.c_oflag = t->c_oflag;
 
2054
        pt.c_cflag = t->c_cflag;
 
2055
        pt.c_lflag = t->c_lflag;
 
2056
 
 
2057
        for (i = 0; i < NCC; i++)
 
2058
            pt.c_cc[i] = t->c_cc[i];
 
2059
        if (func == TCSETA)
 
2060
            i = XTY_TIOCSETA;
 
2061
        else if (func == TCSETAW)
 
2062
            i = XTY_TIOCSETAW;
 
2063
        else
 
2064
            i = XTY_TIOCSETAF;
 
2065
        rc = DosDevIOCtl(fd, XFREE86_PTY, i,
 
2066
                         (ULONG *) & pt, sizeof(struct pt_termios), &len,
 
2067
                         NULL, 0, NULL);
 
2068
        return (rc) ? -1 : 0;
 
2069
    case TIOCCONS:
 
2070
        return DosDevIOCtl(fd, XFREE86_PTY, XTY_TIOCCONS,
 
2071
                           (ULONG *) data, sizeof(ULONG), &len,
 
2072
                           NULL, 0, NULL);
 
2073
    case TIOCSWINSZ:
 
2074
        return DosDevIOCtl(fd, XFREE86_PTY, XTY_TIOCSWINSZ,
 
2075
                           (ULONG *) data, sizeof(struct winsize), &len,
 
2076
                           NULL, 0, NULL);
 
2077
    case TIOCGWINSZ:
 
2078
        return DosDevIOCtl(fd, XFREE86_PTY, XTY_TIOCGWINSZ,
 
2079
                           NULL, 0, NULL,
 
2080
                           (ULONG *) data, sizeof(struct winsize), &len);
 
2081
    case XTY_ENADUP:
 
2082
        i = 1;
 
2083
        return DosDevIOCtl(fd, XFREE86_PTY, XTY_ENADUP,
 
2084
                           (ULONG *) & i, sizeof(ULONG), &len,
 
2085
                           NULL, 0, NULL);
 
2086
    case XTY_TRACE:
 
2087
        i = 2;
 
2088
        return DosDevIOCtl(fd, XFREE86_PTY, XTY_TRACE,
 
2089
                           (ULONG *) & i, sizeof(ULONG), &len,
 
2090
                           NULL, 0, NULL);
 
2091
    case PTMS_GETPTY:
 
2092
        i = 1;
 
2093
        return DosDevIOCtl(fd, XFREE86_PTY, PTMS_GETPTY,
 
2094
                           (ULONG *) & i, sizeof(ULONG), &len,
 
2095
                           (UCHAR *) data, 14, &len);
 
2096
    default:
 
2097
        return -1;
 
2098
    }
 
2099
}