PageRenderTime 62ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 1ms

/nx-3.5.0/nx-X11/programs/xterm/os2main.c

#
C | 2155 lines | 1651 code | 203 blank | 301 comment | 213 complexity | da865de8fd86b52d3c5d2907fd435ee9 MD5 | raw file
Possible License(s): BSD-3-Clause, GPL-2.0, LGPL-2.0

Large files files are truncated, but you can click here to view the full file

  1. /* $XTermId: os2main.c,v 1.213 2005/11/03 13:17:28 tom Exp $ */
  2. /* removed all foreign stuff to get the code more clear (hv)
  3. * and did some rewrite for the obscure OS/2 environment
  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.81 2005/11/03 13:17:28 dickey Exp $ */
  9. /***********************************************************
  10. Copyright (c) 1987, 1988 X Consortium
  11. Permission is hereby granted, free of charge, to any person obtaining a copy
  12. of this software and associated documentation files (the "Software"), to deal
  13. in the Software without restriction, including without limitation the rights
  14. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  15. copies of the Software, and to permit persons to whom the Software is
  16. furnished to do so, subject to the following conditions:
  17. The above copyright notice and this permission notice shall be included in
  18. all copies or substantial portions of the Software.
  19. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  20. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  22. X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  23. AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  24. CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25. Except as contained in this notice, the name of the X Consortium shall not be
  26. used in advertising or otherwise to promote the sale, use or other dealings
  27. in this Software without prior written authorization from the X Consortium.
  28. Copyright 1987, 1988 by Digital Equipment Corporation, Maynard.
  29. All Rights Reserved
  30. Permission to use, copy, modify, and distribute this software and its
  31. documentation for any purpose and without fee is hereby granted,
  32. provided that the above copyright notice appear in all copies and that
  33. both that copyright notice and this permission notice appear in
  34. supporting documentation, and that the name of Digital not be used in
  35. advertising or publicity pertaining to distribution of the software
  36. without specific, written prior permission.
  37. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  38. ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  39. DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  40. ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  41. WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  42. ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  43. SOFTWARE.
  44. ******************************************************************/
  45. /* os2main.c */
  46. #define INCL_DOSFILEMGR
  47. #define INCL_DOSDEVIOCTL
  48. #define INCL_DOSSEMAPHORES
  49. #ifdef __INNOTEK_LIBC__
  50. #define INCL_DOSDEVICES
  51. #endif
  52. #define I_NEED_OS2_H
  53. #include <os2.h>
  54. #define XTERM_MAIN
  55. #define RES_OFFSET(field) XtOffsetOf(XTERM_RESOURCE, field)
  56. #include <xterm.h>
  57. #include <X11/cursorfont.h>
  58. #ifdef I18N
  59. #include <X11/Xlocale.h>
  60. #endif
  61. #if OPT_TOOLBAR
  62. #if defined(HAVE_LIB_XAW)
  63. #include <X11/Xaw/Form.h>
  64. #elif defined(HAVE_LIB_XAW3D)
  65. #include <X11/Xaw3d/Form.h>
  66. #elif defined(HAVE_LIB_NEXTAW)
  67. #include <X11/neXtaw/Form.h>
  68. #elif defined(HAVE_LIB_XAWPLUS)
  69. #include <X11/XawPlus/Form.h>
  70. #endif
  71. #endif /* OPT_TOOLBAR */
  72. #include <pwd.h>
  73. #include <ctype.h>
  74. #include <data.h>
  75. #include <error.h>
  76. #include <menu.h>
  77. #include <main.h>
  78. #include <xstrings.h>
  79. #include <xterm_io.h>
  80. #if OPT_WIDE_CHARS
  81. #include <charclass.h>
  82. #endif
  83. int
  84. setpgrp(pid_t pid, gid_t pgid)
  85. {
  86. return 0;
  87. }
  88. int
  89. chown(const char *fn, pid_t pid, gid_t gid)
  90. {
  91. return 0;
  92. }
  93. char *
  94. ttyname(int fd)
  95. {
  96. return "/dev/tty";
  97. }
  98. #include <sys/stat.h>
  99. #include <sys/param.h> /* for NOFILE */
  100. #include <stdio.h>
  101. #include <signal.h>
  102. static SIGNAL_T reapchild(int n);
  103. static int spawn(void);
  104. static void get_terminal(void);
  105. static void resize(TScreen * s, char *oldtc, char *newtc);
  106. static void set_owner(char *device, uid_t uid, gid_t gid, mode_t mode);
  107. static Bool added_utmp_entry = False;
  108. /*
  109. ** Ordinarily it should be okay to omit the assignment in the following
  110. ** statement. Apparently the c89 compiler on AIX 4.1.3 has a bug, or does
  111. ** it? Without the assignment though the compiler will init command_to_exec
  112. ** to 0xffffffff instead of NULL; and subsequent usage, e.g. in spawn() to
  113. ** SEGV.
  114. */
  115. static char **command_to_exec = NULL;
  116. #if OPT_LUIT_PROG
  117. static char **command_to_exec_with_luit = NULL;
  118. #endif
  119. /* The following structures are initialized in main() in order
  120. ** to eliminate any assumptions about the internal order of their
  121. ** contents.
  122. */
  123. static struct termio d_tio;
  124. /* allow use of system default characters if defined and reasonable */
  125. #ifndef CEOF
  126. #define CEOF CONTROL('D')
  127. #endif
  128. #ifndef CEOL
  129. #define CEOL 0
  130. #endif
  131. #ifndef CFLUSH
  132. #define CFLUSH CONTROL('O')
  133. #endif
  134. #ifndef CLNEXT
  135. #define CLNEXT CONTROL('V')
  136. #endif
  137. #ifndef CNUL
  138. #define CNUL 0
  139. #endif
  140. #ifndef CQUIT
  141. #define CQUIT CONTROL('\\')
  142. #endif
  143. #ifndef CRPRNT
  144. #define CRPRNT CONTROL('R')
  145. #endif
  146. #ifndef CSTART
  147. #define CSTART CONTROL('Q')
  148. #endif
  149. #ifndef CSTOP
  150. #define CSTOP CONTROL('S')
  151. #endif
  152. #ifndef CSUSP
  153. #define CSUSP CONTROL('Z')
  154. #endif
  155. #ifndef CSWTCH
  156. #define CSWTCH 0
  157. #endif
  158. #ifndef CWERASE
  159. #define CWERASE CONTROL('W')
  160. #endif
  161. /*
  162. * SYSV has the termio.c_cc[V] and ltchars; BSD has tchars and ltchars;
  163. * SVR4 has only termio.c_cc, but it includes everything from ltchars.
  164. * POSIX termios has termios.c_cc, which is similar to SVR4.
  165. */
  166. #define TTYMODE(name) { name, sizeof(name)-1, 0, 0 }
  167. static int override_tty_modes = 0;
  168. /* *INDENT-OFF* */
  169. static struct _xttymodes {
  170. char *name;
  171. size_t len;
  172. int set;
  173. Char value;
  174. } ttymodelist[] = {
  175. TTYMODE("intr"), /* tchars.t_intrc ; VINTR */
  176. #define XTTYMODE_intr 0
  177. TTYMODE("quit"), /* tchars.t_quitc ; VQUIT */
  178. #define XTTYMODE_quit 1
  179. TTYMODE("erase"), /* sgttyb.sg_erase ; VERASE */
  180. #define XTTYMODE_erase 2
  181. TTYMODE("kill"), /* sgttyb.sg_kill ; VKILL */
  182. #define XTTYMODE_kill 3
  183. TTYMODE("eof"), /* tchars.t_eofc ; VEOF */
  184. #define XTTYMODE_eof 4
  185. TTYMODE("eol"), /* VEOL */
  186. #define XTTYMODE_eol 5
  187. TTYMODE("swtch"), /* VSWTCH */
  188. #define XTTYMODE_swtch 6
  189. TTYMODE("start"), /* tchars.t_startc ; VSTART */
  190. #define XTTYMODE_start 7
  191. TTYMODE("stop"), /* tchars.t_stopc ; VSTOP */
  192. #define XTTYMODE_stop 8
  193. TTYMODE("brk"), /* tchars.t_brkc */
  194. #define XTTYMODE_brk 9
  195. TTYMODE("susp"), /* ltchars.t_suspc ; VSUSP */
  196. #define XTTYMODE_susp 10
  197. TTYMODE("dsusp"), /* ltchars.t_dsuspc ; VDSUSP */
  198. #define XTTYMODE_dsusp 11
  199. TTYMODE("rprnt"), /* ltchars.t_rprntc ; VREPRINT */
  200. #define XTTYMODE_rprnt 12
  201. TTYMODE("flush"), /* ltchars.t_flushc ; VDISCARD */
  202. #define XTTYMODE_flush 13
  203. TTYMODE("weras"), /* ltchars.t_werasc ; VWERASE */
  204. #define XTTYMODE_weras 14
  205. TTYMODE("lnext"), /* ltchars.t_lnextc ; VLNEXT */
  206. #define XTTYMODE_lnext 15
  207. { NULL, 0, 0, '\0' }, /* end of data */
  208. };
  209. /* *INDENT-ON* */
  210. #define TMODE(ind,var) if (ttymodelist[ind].set) var = ttymodelist[ind].value
  211. static int parse_tty_modes(char *s, struct _xttymodes *modelist);
  212. static char passedPty[2]; /* name if pty if slave */
  213. static int Console;
  214. #include <X11/Xmu/SysUtil.h> /* XmuGetHostname */
  215. #define MIT_CONSOLE_LEN 12
  216. #define MIT_CONSOLE "MIT_CONSOLE_"
  217. static char mit_console_name[255 + MIT_CONSOLE_LEN + 1] = MIT_CONSOLE;
  218. static Atom mit_console;
  219. static int tslot;
  220. static jmp_buf env;
  221. /* used by VT (charproc.c) */
  222. static XtResource application_resources[] =
  223. {
  224. Sres("name", "Name", xterm_name, DFT_TERMTYPE),
  225. Sres("iconGeometry", "IconGeometry", icon_geometry, NULL),
  226. Sres(XtNtitle, XtCTitle, title, NULL),
  227. Sres(XtNiconName, XtCIconName, icon_name, NULL),
  228. Sres("termName", "TermName", term_name, NULL),
  229. Sres("ttyModes", "TtyModes", tty_modes, NULL),
  230. Bres("hold", "Hold", hold_screen, False),
  231. Bres("utmpInhibit", "UtmpInhibit", utmpInhibit, False),
  232. Bres("utmpDisplayId", "UtmpDisplayId", utmpDisplayId, True),
  233. Bres("messages", "Messages", messages, True),
  234. Ires("minBufSize", "MinBufSize", minBufSize, 4096),
  235. Ires("maxBufSize", "MaxBufSize", maxBufSize, 32768),
  236. Sres("keyboardType", "KeyboardType", keyboardType, "unknown"),
  237. Bres("sunFunctionKeys", "SunFunctionKeys", sunFunctionKeys, False),
  238. #if OPT_SUNPC_KBD
  239. Bres("sunKeyboard", "SunKeyboard", sunKeyboard, False),
  240. #endif
  241. #if OPT_HP_FUNC_KEYS
  242. Bres("hpFunctionKeys", "HpFunctionKeys", hpFunctionKeys, False),
  243. #endif
  244. #if OPT_SCO_FUNC_KEYS
  245. Bres("scoFunctionKeys", "ScoFunctionKeys", scoFunctionKeys, False),
  246. #endif
  247. #if OPT_INITIAL_ERASE
  248. Bres("ptyInitialErase", "PtyInitialErase", ptyInitialErase, DEF_INITIAL_ERASE),
  249. Bres("backarrowKeyIsErase", "BackarrowKeyIsErase", backarrow_is_erase, DEF_BACKARO_ERASE),
  250. #endif
  251. Bres("waitForMap", "WaitForMap", wait_for_map, False),
  252. Bres("useInsertMode", "UseInsertMode", useInsertMode, False),
  253. #if OPT_ZICONBEEP
  254. Ires("zIconBeep", "ZIconBeep", zIconBeep, 0),
  255. #endif
  256. #if OPT_PTY_HANDSHAKE
  257. Bres("ptyHandshake", "PtyHandshake", ptyHandshake, True),
  258. #endif
  259. #if OPT_SAME_NAME
  260. Bres("sameName", "SameName", sameName, True),
  261. #endif
  262. #if OPT_SESSION_MGT
  263. Bres("sessionMgt", "SessionMgt", sessionMgt, True),
  264. #endif
  265. #if OPT_TOOLBAR
  266. Bres(XtNtoolBar, XtCToolBar, toolBar, True),
  267. #endif
  268. };
  269. static char *fallback_resources[] =
  270. {
  271. "*SimpleMenu*menuLabel.vertSpace: 100",
  272. "*SimpleMenu*HorizontalMargins: 16",
  273. "*SimpleMenu*Sme.height: 16",
  274. "*SimpleMenu*Cursor: left_ptr",
  275. "*mainMenu.Label: Main Options (no app-defaults)",
  276. "*vtMenu.Label: VT Options (no app-defaults)",
  277. "*fontMenu.Label: VT Fonts (no app-defaults)",
  278. #if OPT_TEK4014
  279. "*tekMenu.Label: Tek Options (no app-defaults)",
  280. #endif
  281. NULL
  282. };
  283. /* Command line options table. Only resources are entered here...there is a
  284. pass over the remaining options after XrmParseCommand is let loose. */
  285. /* *INDENT-OFF* */
  286. static XrmOptionDescRec optionDescList[] = {
  287. {"-geometry", "*vt100.geometry",XrmoptionSepArg, (caddr_t) NULL},
  288. {"-132", "*c132", XrmoptionNoArg, (caddr_t) "on"},
  289. {"+132", "*c132", XrmoptionNoArg, (caddr_t) "off"},
  290. {"-ah", "*alwaysHighlight", XrmoptionNoArg, (caddr_t) "on"},
  291. {"+ah", "*alwaysHighlight", XrmoptionNoArg, (caddr_t) "off"},
  292. {"-aw", "*autoWrap", XrmoptionNoArg, (caddr_t) "on"},
  293. {"+aw", "*autoWrap", XrmoptionNoArg, (caddr_t) "off"},
  294. #ifndef NO_ACTIVE_ICON
  295. {"-ai", "*activeIcon", XrmoptionNoArg, (caddr_t) "off"},
  296. {"+ai", "*activeIcon", XrmoptionNoArg, (caddr_t) "on"},
  297. #endif /* NO_ACTIVE_ICON */
  298. {"-b", "*internalBorder",XrmoptionSepArg, (caddr_t) NULL},
  299. {"-bc", "*cursorBlink", XrmoptionNoArg, (caddr_t) "on"},
  300. {"+bc", "*cursorBlink", XrmoptionNoArg, (caddr_t) "off"},
  301. {"-bcf", "*cursorOffTime",XrmoptionSepArg, (caddr_t) NULL},
  302. {"-bcn", "*cursorOnTime",XrmoptionSepArg, (caddr_t) NULL},
  303. {"-bdc", "*colorBDMode", XrmoptionNoArg, (caddr_t) "off"},
  304. {"+bdc", "*colorBDMode", XrmoptionNoArg, (caddr_t) "on"},
  305. {"-cb", "*cutToBeginningOfLine", XrmoptionNoArg, (caddr_t) "off"},
  306. {"+cb", "*cutToBeginningOfLine", XrmoptionNoArg, (caddr_t) "on"},
  307. {"-cc", "*charClass", XrmoptionSepArg, (caddr_t) NULL},
  308. {"-cm", "*colorMode", XrmoptionNoArg, (caddr_t) "off"},
  309. {"+cm", "*colorMode", XrmoptionNoArg, (caddr_t) "on"},
  310. {"-cn", "*cutNewline", XrmoptionNoArg, (caddr_t) "off"},
  311. {"+cn", "*cutNewline", XrmoptionNoArg, (caddr_t) "on"},
  312. {"-cr", "*cursorColor", XrmoptionSepArg, (caddr_t) NULL},
  313. {"-cu", "*curses", XrmoptionNoArg, (caddr_t) "on"},
  314. {"+cu", "*curses", XrmoptionNoArg, (caddr_t) "off"},
  315. {"-dc", "*dynamicColors",XrmoptionNoArg, (caddr_t) "off"},
  316. {"+dc", "*dynamicColors",XrmoptionNoArg, (caddr_t) "on"},
  317. {"-fb", "*boldFont", XrmoptionSepArg, (caddr_t) NULL},
  318. {"-fbb", "*freeBoldBox", XrmoptionNoArg, (caddr_t)"off"},
  319. {"+fbb", "*freeBoldBox", XrmoptionNoArg, (caddr_t)"on"},
  320. {"-fbx", "*forceBoxChars", XrmoptionNoArg, (caddr_t)"off"},
  321. {"+fbx", "*forceBoxChars", XrmoptionNoArg, (caddr_t)"on"},
  322. #ifndef NO_ACTIVE_ICON
  323. {"-fi", "*iconFont", XrmoptionSepArg, (caddr_t) NULL},
  324. #endif /* NO_ACTIVE_ICON */
  325. #if OPT_RENDERFONT
  326. {"-fa", "*faceName", XrmoptionSepArg, (caddr_t) NULL},
  327. {"-fd", "*faceNameDoublesize", XrmoptionSepArg, (caddr_t) NULL},
  328. {"-fs", "*faceSize", XrmoptionSepArg, (caddr_t) NULL},
  329. #endif
  330. #if OPT_WIDE_CHARS
  331. {"-fw", "*wideFont", XrmoptionSepArg, (caddr_t) NULL},
  332. {"-fwb", "*wideBoldFont", XrmoptionSepArg, (caddr_t) NULL},
  333. #endif
  334. #if OPT_INPUT_METHOD
  335. {"-fx", "*ximFont", XrmoptionSepArg, (caddr_t) NULL},
  336. #endif
  337. #if OPT_HIGHLIGHT_COLOR
  338. {"-hc", "*highlightColor", XrmoptionSepArg, (caddr_t) NULL},
  339. #endif
  340. #if OPT_HP_FUNC_KEYS
  341. {"-hf", "*hpFunctionKeys",XrmoptionNoArg, (caddr_t) "on"},
  342. {"+hf", "*hpFunctionKeys",XrmoptionNoArg, (caddr_t) "off"},
  343. #endif
  344. {"-hold", "*hold", XrmoptionNoArg, (caddr_t) "on"},
  345. {"+hold", "*hold", XrmoptionNoArg, (caddr_t) "off"},
  346. #if OPT_INITIAL_ERASE
  347. {"-ie", "*ptyInitialErase", XrmoptionNoArg, (caddr_t) "on"},
  348. {"+ie", "*ptyInitialErase", XrmoptionNoArg, (caddr_t) "off"},
  349. #endif
  350. {"-j", "*jumpScroll", XrmoptionNoArg, (caddr_t) "on"},
  351. {"+j", "*jumpScroll", XrmoptionNoArg, (caddr_t) "off"},
  352. #if OPT_C1_PRINT
  353. {"-k8", "*allowC1Printable", XrmoptionNoArg, (caddr_t) "on"},
  354. {"+k8", "*allowC1Printable", XrmoptionNoArg, (caddr_t) "off"},
  355. #endif
  356. {"-kt", "*keyboardType", XrmoptionSepArg, (caddr_t) NULL},
  357. {"+kt", "*keyboardType", XrmoptionSepArg, (caddr_t) NULL},
  358. /* parse logging options anyway for compatibility */
  359. {"-l", "*logging", XrmoptionNoArg, (caddr_t) "on"},
  360. {"+l", "*logging", XrmoptionNoArg, (caddr_t) "off"},
  361. {"-lf", "*logFile", XrmoptionSepArg, (caddr_t) NULL},
  362. {"-ls", "*loginShell", XrmoptionNoArg, (caddr_t) "on"},
  363. {"+ls", "*loginShell", XrmoptionNoArg, (caddr_t) "off"},
  364. {"-mb", "*marginBell", XrmoptionNoArg, (caddr_t) "on"},
  365. {"+mb", "*marginBell", XrmoptionNoArg, (caddr_t) "off"},
  366. {"-mc", "*multiClickTime", XrmoptionSepArg, (caddr_t) NULL},
  367. {"-mesg", "*messages", XrmoptionNoArg, (caddr_t) "off"},
  368. {"+mesg", "*messages", XrmoptionNoArg, (caddr_t) "on"},
  369. {"-ms", "*pointerColor",XrmoptionSepArg, (caddr_t) NULL},
  370. {"-nb", "*nMarginBell", XrmoptionSepArg, (caddr_t) NULL},
  371. {"-nul", "*underLine", XrmoptionNoArg, (caddr_t) "off"},
  372. {"+nul", "*underLine", XrmoptionNoArg, (caddr_t) "on"},
  373. {"-pc", "*boldColors", XrmoptionNoArg, (caddr_t) "on"},
  374. {"+pc", "*boldColors", XrmoptionNoArg, (caddr_t) "off"},
  375. {"-rw", "*reverseWrap", XrmoptionNoArg, (caddr_t) "on"},
  376. {"+rw", "*reverseWrap", XrmoptionNoArg, (caddr_t) "off"},
  377. {"-s", "*multiScroll", XrmoptionNoArg, (caddr_t) "on"},
  378. {"+s", "*multiScroll", XrmoptionNoArg, (caddr_t) "off"},
  379. {"-sb", "*scrollBar", XrmoptionNoArg, (caddr_t) "on"},
  380. {"+sb", "*scrollBar", XrmoptionNoArg, (caddr_t) "off"},
  381. #ifdef SCROLLBAR_RIGHT
  382. {"-leftbar", "*rightScrollBar", XrmoptionNoArg, (caddr_t) "off"},
  383. {"-rightbar", "*rightScrollBar", XrmoptionNoArg, (caddr_t) "on"},
  384. #endif
  385. {"-rvc", "*colorRVMode", XrmoptionNoArg, (caddr_t) "off"},
  386. {"+rvc", "*colorRVMode", XrmoptionNoArg, (caddr_t) "on"},
  387. {"-sf", "*sunFunctionKeys", XrmoptionNoArg, (caddr_t) "on"},
  388. {"+sf", "*sunFunctionKeys", XrmoptionNoArg, (caddr_t) "off"},
  389. {"-si", "*scrollTtyOutput", XrmoptionNoArg, (caddr_t) "off"},
  390. {"+si", "*scrollTtyOutput", XrmoptionNoArg, (caddr_t) "on"},
  391. {"-sk", "*scrollKey", XrmoptionNoArg, (caddr_t) "on"},
  392. {"+sk", "*scrollKey", XrmoptionNoArg, (caddr_t) "off"},
  393. {"-sl", "*saveLines", XrmoptionSepArg, (caddr_t) NULL},
  394. #if OPT_SUNPC_KBD
  395. {"-sp", "*sunKeyboard", XrmoptionNoArg, (caddr_t) "on"},
  396. {"+sp", "*sunKeyboard", XrmoptionNoArg, (caddr_t) "off"},
  397. #endif
  398. #if OPT_TEK4014
  399. {"-t", "*tekStartup", XrmoptionNoArg, (caddr_t) "on"},
  400. {"+t", "*tekStartup", XrmoptionNoArg, (caddr_t) "off"},
  401. #endif
  402. {"-ti", "*decTerminalID",XrmoptionSepArg, (caddr_t) NULL},
  403. {"-tm", "*ttyModes", XrmoptionSepArg, (caddr_t) NULL},
  404. {"-tn", "*termName", XrmoptionSepArg, (caddr_t) NULL},
  405. #if OPT_WIDE_CHARS
  406. {"-u8", "*utf8", XrmoptionNoArg, (caddr_t) "2"},
  407. {"+u8", "*utf8", XrmoptionNoArg, (caddr_t) "0"},
  408. #endif
  409. #if OPT_LUIT_PROG
  410. {"-lc", "*locale", XrmoptionNoArg, (caddr_t) "on"},
  411. {"+lc", "*locale", XrmoptionNoArg, (caddr_t) "off"},
  412. {"-lcc", "*localeFilter",XrmoptionSepArg, (caddr_t) NULL},
  413. {"-en", "*locale", XrmoptionSepArg, (caddr_t) NULL},
  414. #endif
  415. {"-ulc", "*colorULMode", XrmoptionNoArg, (caddr_t) "off"},
  416. {"+ulc", "*colorULMode", XrmoptionNoArg, (caddr_t) "on"},
  417. {"-ulit", "*italicULMode", XrmoptionNoArg, (caddr_t) "off"},
  418. {"+ulit", "*italicULMode", XrmoptionNoArg, (caddr_t) "on"},
  419. {"-ut", "*utmpInhibit", XrmoptionNoArg, (caddr_t) "on"},
  420. {"+ut", "*utmpInhibit", XrmoptionNoArg, (caddr_t) "off"},
  421. {"-im", "*useInsertMode", XrmoptionNoArg, (caddr_t) "on"},
  422. {"+im", "*useInsertMode", XrmoptionNoArg, (caddr_t) "off"},
  423. {"-vb", "*visualBell", XrmoptionNoArg, (caddr_t) "on"},
  424. {"+vb", "*visualBell", XrmoptionNoArg, (caddr_t) "off"},
  425. {"-pob", "*popOnBell", XrmoptionNoArg, (caddr_t) "on"},
  426. {"+pob", "*popOnBell", XrmoptionNoArg, (caddr_t) "off"},
  427. #if OPT_WIDE_CHARS
  428. {"-wc", "*wideChars", XrmoptionNoArg, (caddr_t) "on"},
  429. {"+wc", "*wideChars", XrmoptionNoArg, (caddr_t) "off"},
  430. {"-mk_width", "*mkWidth", XrmoptionNoArg, (caddr_t) "on"},
  431. {"+mk_width", "*mkWidth", XrmoptionNoArg, (caddr_t) "off"},
  432. {"-cjk_width", "*cjkWidth", XrmoptionNoArg, (caddr_t) "on"},
  433. {"+cjk_width", "*cjkWidth", XrmoptionNoArg, (caddr_t) "off"},
  434. #endif
  435. {"-wf", "*waitForMap", XrmoptionNoArg, (caddr_t) "on"},
  436. {"+wf", "*waitForMap", XrmoptionNoArg, (caddr_t) "off"},
  437. #if OPT_ZICONBEEP
  438. {"-ziconbeep", "*zIconBeep", XrmoptionSepArg, (caddr_t) NULL},
  439. #endif
  440. #if OPT_SAME_NAME
  441. {"-samename", "*sameName", XrmoptionNoArg, (caddr_t) "on"},
  442. {"+samename", "*sameName", XrmoptionNoArg, (caddr_t) "off"},
  443. #endif
  444. #if OPT_SESSION_MGT
  445. {"-sm", "*sessionMgt", XrmoptionNoArg, (caddr_t) "on"},
  446. {"+sm", "*sessionMgt", XrmoptionNoArg, (caddr_t) "off"},
  447. #endif
  448. #if OPT_TOOLBAR
  449. {"-tb", "*"XtNtoolBar, XrmoptionNoArg, (caddr_t) "on"},
  450. {"+tb", "*"XtNtoolBar, XrmoptionNoArg, (caddr_t) "off"},
  451. #endif
  452. /* options that we process ourselves */
  453. {"-help", NULL, XrmoptionSkipNArgs, (caddr_t) NULL},
  454. {"-version", NULL, XrmoptionSkipNArgs, (caddr_t) NULL},
  455. {"-class", NULL, XrmoptionSkipArg, (caddr_t) NULL},
  456. {"-e", NULL, XrmoptionSkipLine, (caddr_t) NULL},
  457. {"-into", NULL, XrmoptionSkipArg, (caddr_t) NULL},
  458. /* bogus old compatibility stuff for which there are
  459. standard XtOpenApplication options now */
  460. {"%", "*tekGeometry", XrmoptionStickyArg, (caddr_t) NULL},
  461. {"#", ".iconGeometry",XrmoptionStickyArg, (caddr_t) NULL},
  462. {"-T", ".title", XrmoptionSepArg, (caddr_t) NULL},
  463. {"-n", "*iconName", XrmoptionSepArg, (caddr_t) NULL},
  464. {"-r", "*reverseVideo",XrmoptionNoArg, (caddr_t) "on"},
  465. {"+r", "*reverseVideo",XrmoptionNoArg, (caddr_t) "off"},
  466. {"-rv", "*reverseVideo",XrmoptionNoArg, (caddr_t) "on"},
  467. {"+rv", "*reverseVideo",XrmoptionNoArg, (caddr_t) "off"},
  468. {"-w", ".borderWidth", XrmoptionSepArg, (caddr_t) NULL},
  469. };
  470. static OptionHelp xtermOptions[] = {
  471. { "-version", "print the version number" },
  472. { "-help", "print out this message" },
  473. { "-display displayname", "X server to contact" },
  474. { "-geometry geom", "size (in characters) and position" },
  475. { "-/+rv", "turn on/off reverse video" },
  476. { "-bg color", "background color" },
  477. { "-fg color", "foreground color" },
  478. { "-bd color", "border color" },
  479. { "-bw number", "border width in pixels" },
  480. { "-fn fontname", "normal text font" },
  481. { "-fb fontname", "bold text font" },
  482. { "-/+fbb", "turn on/off normal/bold font comparison inhibit"},
  483. { "-/+fbx", "turn off/on linedrawing characters"},
  484. #if OPT_RENDERFONT
  485. { "-fa pattern", "FreeType font-selection pattern" },
  486. { "-fd pattern", "FreeType Doublesize font-selection pattern" },
  487. { "-fs size", "FreeType font-size" },
  488. #endif
  489. #if OPT_WIDE_CHARS
  490. { "-fw fontname", "doublewidth text font" },
  491. { "-fwb fontname", "doublewidth bold text font" },
  492. #endif
  493. #if OPT_INPUT_METHOD
  494. { "-fx fontname", "XIM fontset" },
  495. #endif
  496. { "-iconic", "start iconic" },
  497. { "-name string", "client instance, icon, and title strings" },
  498. { "-class string", "class string (XTerm)" },
  499. { "-title string", "title string" },
  500. { "-xrm resourcestring", "additional resource specifications" },
  501. { "-/+132", "turn on/off 80/132 column switching" },
  502. { "-/+ah", "turn on/off always highlight" },
  503. #ifndef NO_ACTIVE_ICON
  504. { "-/+ai", "turn off/on active icon" },
  505. { "-fi fontname", "icon font for active icon" },
  506. #endif /* NO_ACTIVE_ICON */
  507. { "-b number", "internal border in pixels" },
  508. { "-/+bc", "turn on/off text cursor blinking" },
  509. { "-bcf milliseconds", "time text cursor is off when blinking"},
  510. { "-bcn milliseconds", "time text cursor is on when blinking"},
  511. { "-/+bdc", "turn off/on display of bold as color"},
  512. { "-/+cb", "turn on/off cut-to-beginning-of-line inhibit" },
  513. { "-cc classrange", "specify additional character classes" },
  514. { "-/+cm", "turn off/on ANSI color mode" },
  515. { "-/+cn", "turn on/off cut newline inhibit" },
  516. { "-cr color", "text cursor color" },
  517. { "-/+cu", "turn on/off curses emulation" },
  518. { "-/+dc", "turn off/on dynamic color selection" },
  519. #if OPT_HIGHLIGHT_COLOR
  520. { "-hc color", "selection background color" },
  521. #endif
  522. #if OPT_HP_FUNC_KEYS
  523. { "-/+hf", "turn on/off HP Function Key escape codes" },
  524. #endif
  525. { "-/+hold", "turn on/off logic that retains window after exit" },
  526. #if OPT_INITIAL_ERASE
  527. { "-/+ie", "turn on/off initialization of 'erase' from pty" },
  528. #endif
  529. { "-/+im", "use insert mode for TERMCAP" },
  530. { "-/+j", "turn on/off jump scroll" },
  531. #if OPT_C1_PRINT
  532. { "-/+k8", "turn on/off C1-printable classification"},
  533. #endif
  534. { "-kt keyboardtype", "set keyboard type:" KEYBOARD_TYPES },
  535. #ifdef ALLOWLOGGING
  536. { "-/+l", "turn on/off logging" },
  537. { "-lf filename", "logging filename" },
  538. #else
  539. { "-/+l", "turn on/off logging (not supported)" },
  540. { "-lf filename", "logging filename (not supported)" },
  541. #endif
  542. { "-/+ls", "turn on/off login shell" },
  543. { "-/+mb", "turn on/off margin bell" },
  544. { "-mc milliseconds", "multiclick time in milliseconds" },
  545. { "-/+mesg", "forbid/allow messages" },
  546. { "-ms color", "pointer color" },
  547. { "-nb number", "margin bell in characters from right end" },
  548. { "-/+nul", "turn off/on display of underlining" },
  549. { "-/+aw", "turn on/off auto wraparound" },
  550. { "-/+pc", "turn on/off PC-style bold colors" },
  551. { "-/+rw", "turn on/off reverse wraparound" },
  552. { "-/+s", "turn on/off multiscroll" },
  553. { "-/+sb", "turn on/off scrollbar" },
  554. #ifdef SCROLLBAR_RIGHT
  555. { "-rightbar", "force scrollbar right (default left)" },
  556. { "-leftbar", "force scrollbar left" },
  557. #endif
  558. { "-/+rvc", "turn off/on display of reverse as color" },
  559. { "-/+sf", "turn on/off Sun Function Key escape codes" },
  560. { "-/+si", "turn on/off scroll-on-tty-output inhibit" },
  561. { "-/+sk", "turn on/off scroll-on-keypress" },
  562. { "-sl number", "number of scrolled lines to save" },
  563. #if OPT_SUNPC_KBD
  564. { "-/+sp", "turn on/off Sun/PC Function/Keypad mapping" },
  565. #endif
  566. #if OPT_TEK4014
  567. { "-/+t", "turn on/off Tek emulation window" },
  568. #endif
  569. #if OPT_TOOLBAR
  570. { "-/+tb", "turn on/off toolbar" },
  571. #endif
  572. { "-ti termid", "terminal identifier" },
  573. { "-tm string", "terminal mode keywords and characters" },
  574. { "-tn name", "TERM environment variable name" },
  575. #if OPT_WIDE_CHARS
  576. { "-/+u8", "turn on/off UTF-8 mode (implies wide-characters)" },
  577. #endif
  578. #if OPT_LUIT_PROG
  579. { "-/+lc", "turn on/off locale mode using luit" },
  580. { "-lcc path", "filename of locale converter (" DEFLOCALEFILTER ")" },
  581. #endif
  582. { "-/+ulc", "turn off/on display of underline as color" },
  583. { "-/+ut", "turn on/off utmp inhibit (not supported)" },
  584. { "-/+ulit", "turn off/on display of underline as italics" },
  585. { "-/+vb", "turn on/off visual bell" },
  586. { "-/+pob", "turn on/off pop on bell" },
  587. #if OPT_WIDE_CHARS
  588. { "-/+wc", "turn on/off wide-character mode" },
  589. { "-/+mk_width", "turn on/off simple width convention" },
  590. { "-/+cjk_width", "turn on/off legacy CJK width convention" },
  591. #endif
  592. { "-/+wf", "turn on/off wait for map before command exec" },
  593. { "-e command args ...", "command to execute" },
  594. #if OPT_TEK4014
  595. { "%geom", "Tek window geometry" },
  596. #endif
  597. { "#geom", "icon window geometry" },
  598. { "-T string", "title name for window" },
  599. { "-n string", "icon name for window" },
  600. { "-C", "intercept console messages" },
  601. { "-Sccn", "slave mode on \"ttycc\", file descriptor \"n\"" },
  602. { "-into windowId", "use the window id given to -into as the parent window rather than the default root window" },
  603. #if OPT_ZICONBEEP
  604. { "-ziconbeep percent", "beep and flag icon of window having hidden output" },
  605. #endif
  606. #if OPT_SAME_NAME
  607. { "-/+samename", "turn on/off the no-flicker option for title and icon name" },
  608. #endif
  609. #if OPT_SESSION_MGT
  610. { "-/+sm", "turn on/off the session-management support" },
  611. #endif
  612. { NULL, NULL }};
  613. /* *INDENT-ON* */
  614. /*debug FILE *confd;*/
  615. /*static void opencons()
  616. {
  617. if ((confd=fopen("/dev/console$","w")) < 0) {
  618. fputs("!!! Cannot open console device.\n",
  619. stderr);
  620. exit(1);
  621. }
  622. }
  623. static void closecons(void)
  624. {
  625. fclose(confd);
  626. }
  627. */
  628. static char *message[] =
  629. {
  630. "Fonts should be fixed width and, if both normal and bold are specified, should",
  631. "have the same size. If only a normal font is specified, it will be used for",
  632. "both normal and bold text (by doing overstriking). The -e option, if given,",
  633. "must appear at the end of the command line, otherwise the user's default shell",
  634. "will be started. Options that start with a plus sign (+) restore the default.",
  635. NULL};
  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. TRACE(("...decode '%s'\n", string));
  647. if (*string == '^') {
  648. switch (*++string) {
  649. case '?':
  650. value = A2E(127);
  651. break;
  652. case '-':
  653. if (!termcap) {
  654. errno = 0;
  655. #if defined(_POSIX_VDISABLE) && defined(HAVE_UNISTD_H)
  656. value = _POSIX_VDISABLE;
  657. #endif
  658. #if defined(_PC_VDISABLE)
  659. if (value == -1) {
  660. value = fpathconf(0, _PC_VDISABLE);
  661. if (value == -1) {
  662. if (errno != 0)
  663. break; /* skip this (error) */
  664. value = 0377;
  665. }
  666. }
  667. #elif defined(VDISABLE)
  668. if (value == -1)
  669. value = VDISABLE;
  670. #endif
  671. break;
  672. }
  673. /* FALLTHRU */
  674. default:
  675. value = CONTROL(*string);
  676. break;
  677. }
  678. ++string;
  679. } else if (termcap && (*string == '\\')) {
  680. char *d;
  681. int temp = strtol(string + 1, &d, 8);
  682. if (temp > 0 && d != string) {
  683. value = temp;
  684. string = d;
  685. }
  686. } else {
  687. value = CharOf(*string);
  688. ++string;
  689. }
  690. *ptr = string;
  691. return value;
  692. }
  693. /*
  694. * If we're linked to terminfo, tgetent() will return an empty buffer. We
  695. * cannot use that to adjust the $TERMCAP variable.
  696. */
  697. static Bool
  698. get_termcap(char *name, char *buffer, char *resized)
  699. {
  700. TScreen *screen = &term->screen;
  701. *buffer = 0; /* initialize, in case we're using terminfo's tgetent */
  702. if (name != 0) {
  703. if (tgetent(buffer, name) == 1) {
  704. TRACE(("get_termcap(%s) succeeded (%s)\n", name,
  705. (*buffer
  706. ? "ok:termcap, we can update $TERMCAP"
  707. : "assuming this is terminfo")));
  708. if (*buffer) {
  709. if (!TEK4014_ACTIVE(screen)) {
  710. resize(screen, buffer, resized);
  711. }
  712. }
  713. return True;
  714. } else {
  715. *buffer = 0; /* just in case */
  716. }
  717. }
  718. return False;
  719. }
  720. static int
  721. abbrev(char *tst, char *cmp, size_t need)
  722. {
  723. size_t len = strlen(tst);
  724. return ((len >= need) && (!strncmp(tst, cmp, len)));
  725. }
  726. static void
  727. Syntax(char *badOption)
  728. {
  729. OptionHelp *opt;
  730. OptionHelp *list = sortedOpts(xtermOptions, optionDescList, XtNumber(optionDescList));
  731. int col;
  732. fprintf(stderr, "%s: bad command line option \"%s\"\r\n\n",
  733. ProgramName, badOption);
  734. fprintf(stderr, "usage: %s", ProgramName);
  735. col = 8 + strlen(ProgramName);
  736. for (opt = list; opt->opt; opt++) {
  737. int len = 3 + strlen(opt->opt); /* space [ string ] */
  738. if (col + len > 79) {
  739. fprintf(stderr, "\r\n "); /* 3 spaces */
  740. col = 3;
  741. }
  742. fprintf(stderr, " [%s]", opt->opt);
  743. col += len;
  744. }
  745. fprintf(stderr, "\r\n\nType %s -help for a full description.\r\n\n",
  746. ProgramName);
  747. exit(1);
  748. }
  749. static void
  750. Version(void)
  751. {
  752. printf("%s\n", xtermVersion());
  753. fflush(stdout);
  754. }
  755. static void
  756. Help(void)
  757. {
  758. OptionHelp *opt;
  759. OptionHelp *list = sortedOpts(xtermOptions, optionDescList, XtNumber(optionDescList));
  760. char **cpp;
  761. printf("%s usage:\n %s [-options ...] [-e command args]\n\n",
  762. xtermVersion(), ProgramName);
  763. printf("where options include:\n");
  764. for (opt = list; opt->opt; opt++) {
  765. printf(" %-28s %s\n", opt->opt, opt->desc);
  766. }
  767. putchar('\n');
  768. for (cpp = message; *cpp; cpp++)
  769. puts(*cpp);
  770. putchar('\n');
  771. fflush(stdout);
  772. }
  773. /* ARGSUSED */
  774. static Boolean
  775. ConvertConsoleSelection(Widget w GCC_UNUSED,
  776. Atom * selection GCC_UNUSED,
  777. Atom * target GCC_UNUSED,
  778. Atom * type GCC_UNUSED,
  779. XtPointer *value GCC_UNUSED,
  780. unsigned long *length GCC_UNUSED,
  781. int *format GCC_UNUSED)
  782. {
  783. /* we don't save console output, so can't offer it */
  784. return False;
  785. }
  786. #if OPT_SESSION_MGT
  787. static void
  788. die_callback(Widget w GCC_UNUSED,
  789. XtPointer client_data GCC_UNUSED,
  790. XtPointer call_data GCC_UNUSED)
  791. {
  792. Cleanup(0);
  793. }
  794. static void
  795. save_callback(Widget w GCC_UNUSED,
  796. XtPointer client_data GCC_UNUSED,
  797. XtPointer call_data)
  798. {
  799. XtCheckpointToken token = (XtCheckpointToken) call_data;
  800. /* we have nothing to save */
  801. token->save_success = True;
  802. }
  803. #endif /* OPT_SESSION_MGT */
  804. /*
  805. * DeleteWindow(): Action proc to implement ICCCM delete_window.
  806. */
  807. /* ARGSUSED */
  808. static void
  809. DeleteWindow(Widget w,
  810. XEvent * event GCC_UNUSED,
  811. String * params GCC_UNUSED,
  812. Cardinal *num_params GCC_UNUSED)
  813. {
  814. #if OPT_TEK4014
  815. if (w == toplevel) {
  816. if (term->screen.Tshow)
  817. hide_vt_window();
  818. else
  819. do_hangup(w, (XtPointer) 0, (XtPointer) 0);
  820. } else if (term->screen.Vshow)
  821. hide_tek_window();
  822. else
  823. #endif
  824. do_hangup(w, (XtPointer) 0, (XtPointer) 0);
  825. }
  826. /* ARGSUSED */
  827. static void
  828. KeyboardMapping(Widget w GCC_UNUSED,
  829. XEvent * event,
  830. String * params GCC_UNUSED,
  831. Cardinal *num_params GCC_UNUSED)
  832. {
  833. switch (event->type) {
  834. case MappingNotify:
  835. XRefreshKeyboardMapping(&event->xmapping);
  836. break;
  837. }
  838. }
  839. static XtActionsRec actionProcs[] =
  840. {
  841. {"DeleteWindow", DeleteWindow},
  842. {"KeyboardMapping", KeyboardMapping},
  843. };
  844. char **gblenvp;
  845. int
  846. main(int argc, char **argv ENVP_ARG)
  847. {
  848. Widget form_top, menu_top;
  849. TScreen *screen;
  850. int mode;
  851. char *my_class = DEFCLASS;
  852. Window winToEmbedInto = None;
  853. /* Do these first, since we may not be able to open the display */
  854. ProgramName = argv[0];
  855. TRACE_OPTS(xtermOptions, optionDescList, XtNumber(optionDescList));
  856. TRACE_ARGV("Before XtOpenApplication", argv);
  857. if (argc > 1) {
  858. int n;
  859. unsigned unique = 2;
  860. Bool quit = True;
  861. for (n = 1; n < argc; n++) {
  862. TRACE(("parsing %s\n", argv[n]));
  863. if (abbrev(argv[n], "-version", unique)) {
  864. Version();
  865. } else if (abbrev(argv[n], "-help", unique)) {
  866. Help();
  867. } else if (abbrev(argv[n], "-class", 3)) {
  868. if ((my_class = argv[++n]) == 0) {
  869. Help();
  870. } else {
  871. quit = False;
  872. }
  873. unique = 3;
  874. } else {
  875. quit = False;
  876. unique = 3;
  877. }
  878. }
  879. if (quit)
  880. exit(0);
  881. }
  882. /* XXX: for some obscure reason EMX seems to lose the value of
  883. * the environ variable, don't understand why, so save it recently
  884. */
  885. gblenvp = envp;
  886. #ifdef I18N
  887. setlocale(LC_ALL, NULL);
  888. #endif
  889. /*debug opencons();*/
  890. ttydev = TypeMallocN(char, PTMS_BUFSZ);
  891. ptydev = TypeMallocN(char, PTMS_BUFSZ);
  892. if (!ttydev || !ptydev) {
  893. fprintf(stderr,
  894. "%s: unable to allocate memory for ttydev or ptydev\n",
  895. ProgramName);
  896. exit(1);
  897. }
  898. strcpy(ttydev, TTYDEV);
  899. strcpy(ptydev, PTYDEV);
  900. /* Initialization is done here rather than above in order
  901. * to prevent any assumptions about the order of the contents
  902. * of the various terminal structures (which may change from
  903. * implementation to implementation).
  904. */
  905. d_tio.c_iflag = ICRNL | IXON;
  906. d_tio.c_oflag = OPOST | ONLCR | TAB3;
  907. d_tio.c_cflag = B38400 | CS8 | CREAD | PARENB | HUPCL;
  908. d_tio.c_lflag = ISIG | ICANON | ECHO | ECHOE | ECHOK;
  909. d_tio.c_line = 0;
  910. d_tio.c_cc[VINTR] = CONTROL('C'); /* '^C' */
  911. d_tio.c_cc[VERASE] = 0x7f; /* DEL */
  912. d_tio.c_cc[VKILL] = CONTROL('U'); /* '^U' */
  913. d_tio.c_cc[VQUIT] = CQUIT; /* '^\' */
  914. d_tio.c_cc[VEOF] = CEOF; /* '^D' */
  915. d_tio.c_cc[VEOL] = CEOL; /* '^@' */
  916. XtSetErrorHandler(xt_error);
  917. #if OPT_SESSION_MGT
  918. toplevel = XtOpenApplication(&app_con, my_class,
  919. optionDescList,
  920. XtNumber(optionDescList),
  921. &argc, argv, fallback_resources,
  922. sessionShellWidgetClass,
  923. NULL, 0);
  924. #else
  925. toplevel = XtAppInitialize(&app_con, my_class,
  926. optionDescList,
  927. XtNumber(optionDescList),
  928. &argc, argv, fallback_resources,
  929. NULL, 0);
  930. #endif /* OPT_SESSION_MGT */
  931. XtSetErrorHandler((XtErrorHandler) 0);
  932. XtGetApplicationResources(toplevel, (XtPointer) &resource,
  933. application_resources,
  934. XtNumber(application_resources), NULL, 0);
  935. TRACE_XRES();
  936. waiting_for_initial_map = resource.wait_for_map;
  937. /*
  938. * ICCCM delete_window.
  939. */
  940. XtAppAddActions(app_con, actionProcs, XtNumber(actionProcs));
  941. /*
  942. * fill in terminal modes
  943. */
  944. if (resource.tty_modes) {
  945. int n = parse_tty_modes(resource.tty_modes, ttymodelist);
  946. if (n < 0) {
  947. fprintf(stderr, "%s: bad tty modes \"%s\"\n",
  948. ProgramName, resource.tty_modes);
  949. } else if (n > 0) {
  950. override_tty_modes = 1;
  951. }
  952. }
  953. #if OPT_ZICONBEEP
  954. zIconBeep = resource.zIconBeep;
  955. zIconBeep_flagged = False;
  956. if (zIconBeep > 100 || zIconBeep < -100) {
  957. zIconBeep = 0; /* was 100, but I prefer to defaulting off. */
  958. fprintf(stderr,
  959. "a number between -100 and 100 is required for zIconBeep. 0 used by default\n");
  960. }
  961. #endif /* OPT_ZICONBEEP */
  962. #if OPT_SAME_NAME
  963. sameName = resource.sameName;
  964. #endif
  965. hold_screen = resource.hold_screen ? 1 : 0;
  966. xterm_name = resource.xterm_name;
  967. if (strcmp(xterm_name, "-") == 0)
  968. xterm_name = DFT_TERMTYPE;
  969. if (resource.icon_geometry != NULL) {
  970. int scr, junk;
  971. int ix, iy;
  972. Arg args[2];
  973. for (scr = 0; /* yyuucchh */
  974. XtScreen(toplevel) != ScreenOfDisplay(XtDisplay(toplevel), scr);
  975. scr++) ;
  976. args[0].name = XtNiconX;
  977. args[1].name = XtNiconY;
  978. XGeometry(XtDisplay(toplevel), scr, resource.icon_geometry, "",
  979. 0, 0, 0, 0, 0, &ix, &iy, &junk, &junk);
  980. args[0].value = (XtArgVal) ix;
  981. args[1].value = (XtArgVal) iy;
  982. XtSetValues(toplevel, args, 2);
  983. }
  984. XtSetValues(toplevel, ourTopLevelShellArgs,
  985. number_ourTopLevelShellArgs);
  986. #if OPT_WIDE_CHARS
  987. /* seems as good a place as any */
  988. init_classtab();
  989. #endif
  990. /* Parse the rest of the command line */
  991. TRACE_ARGV("After XtOpenApplication", argv);
  992. for (argc--, argv++; argc > 0; argc--, argv++) {
  993. if (**argv != '-')
  994. Syntax(*argv);
  995. TRACE(("parsing %s\n", argv[0]));
  996. switch (argv[0][1]) {
  997. case 'h': /* -help */
  998. Help();
  999. continue;
  1000. case 'v': /* -version */
  1001. Version();
  1002. continue;
  1003. case 'C':
  1004. {
  1005. struct stat sbuf;
  1006. /* Must be owner and have read/write permission.
  1007. xdm cooperates to give the console the right user. */
  1008. if (!stat("/dev/console", &sbuf) &&
  1009. (sbuf.st_uid == getuid()) &&
  1010. !access("/dev/console", R_OK | W_OK)) {
  1011. Console = True;
  1012. } else
  1013. Console = False;
  1014. }
  1015. continue;
  1016. case 'S':
  1017. if (sscanf(*argv + 2, "%c%c%d", passedPty, passedPty + 1,
  1018. &am_slave) != 3)
  1019. Syntax(*argv);
  1020. continue;
  1021. #ifdef DEBUG
  1022. case 'D':
  1023. debug = True;
  1024. continue;
  1025. #endif /* DEBUG */
  1026. case 'c': /* -class param */
  1027. if (strcmp(argv[0] + 1, "class") == 0)
  1028. argc--, argv++;
  1029. else
  1030. Syntax(*argv);
  1031. continue;
  1032. case 'e':
  1033. if (argc <= 1)
  1034. Syntax(*argv);
  1035. command_to_exec = ++argv;
  1036. break;
  1037. case 'i':
  1038. if (argc <= 1) {
  1039. Syntax(*argv);
  1040. } else {
  1041. char *endPtr;
  1042. --argc;
  1043. ++argv;
  1044. winToEmbedInto = (Window) strtol(argv[0], &endPtr, 10);
  1045. }
  1046. continue;
  1047. default:
  1048. Syntax(*argv);
  1049. }
  1050. break;
  1051. }
  1052. SetupMenus(toplevel, &form_top, &menu_top);
  1053. term = (XtermWidget) XtVaCreateManagedWidget("vt100", xtermWidgetClass,
  1054. form_top,
  1055. #if OPT_TOOLBAR
  1056. XtNmenuBar, menu_top,
  1057. XtNresizable, True,
  1058. XtNfromVert, menu_top,
  1059. XtNleft, XawChainLeft,
  1060. XtNright, XawChainRight,
  1061. XtNtop, XawChainTop,
  1062. XtNbottom, XawChainBottom,
  1063. #endif
  1064. (XtPointer) 0);
  1065. decode_keyboard_type(&resource);
  1066. screen = &term->screen;
  1067. screen->inhibit = 0;
  1068. #ifdef ALLOWLOGGING
  1069. if (term->misc.logInhibit)
  1070. screen->inhibit |= I_LOG;
  1071. #endif
  1072. if (term->misc.signalInhibit)
  1073. screen->inhibit |= I_SIGNAL;
  1074. #if OPT_TEK4014
  1075. if (term->misc.tekInhibit)
  1076. screen->inhibit |= I_TEK;
  1077. #endif
  1078. /*
  1079. * We might start by showing the tek4014 window.
  1080. */
  1081. #if OPT_TEK4014
  1082. if (screen->inhibit & I_TEK)
  1083. screen->TekEmu = False;
  1084. if (screen->TekEmu && !TekInit())
  1085. exit(ERROR_INIT);
  1086. #endif
  1087. /*
  1088. * Start the toolbar at this point, after the first window has been setup.
  1089. */
  1090. #if OPT_TOOLBAR
  1091. ShowToolbar(resource.toolBar);
  1092. #endif
  1093. #if OPT_SESSION_MGT
  1094. if (resource.sessionMgt) {
  1095. TRACE(("Enabling session-management callbacks\n"));
  1096. XtAddCallback(toplevel, XtNdieCallback, die_callback, NULL);
  1097. XtAddCallback(toplevel, XtNsaveCallback, save_callback, NULL);
  1098. }
  1099. #endif
  1100. /*
  1101. * Set title and icon name if not specified
  1102. */
  1103. if (command_to_exec) {
  1104. Arg args[2];
  1105. if (!resource.title) {
  1106. if (command_to_exec) {
  1107. resource.title = x_basename(command_to_exec[0]);
  1108. } /* else not reached */
  1109. }
  1110. if (!resource.icon_name)
  1111. resource.icon_name = resource.title;
  1112. XtSetArg(args[0], XtNtitle, resource.title);
  1113. XtSetArg(args[1], XtNiconName, resource.icon_name);
  1114. TRACE(("setting:\n\ttitle \"%s\"\n\ticon \"%s\"\n\tbased on command \"%s\"\n",
  1115. resource.title,
  1116. resource.icon_name,
  1117. *command_to_exec));
  1118. XtSetValues(toplevel, args, 2);
  1119. }
  1120. #if OPT_LUIT_PROG
  1121. if (term->misc.callfilter) {
  1122. int u = (term->misc.use_encoding ? 2 : 0);
  1123. if (command_to_exec) {
  1124. int n;
  1125. char **c;
  1126. for (n = 0, c = command_to_exec; *c; n++, c++) ;
  1127. c = TypeMallocN(char *, n + 3 + u);
  1128. if (c == NULL)
  1129. SysError(ERROR_LUMALLOC);
  1130. memcpy(c + 2 + u, command_to_exec, (n + 1) * sizeof(char *));
  1131. c[0] = term->misc.localefilter;
  1132. if (u) {
  1133. c[1] = "-encoding";
  1134. c[2] = term->misc.locale_str;
  1135. }
  1136. c[1 + u] = "--";
  1137. command_to_exec_with_luit = c;
  1138. } else {
  1139. static char *luit[4];
  1140. luit[0] = term->misc.localefilter;
  1141. if (u) {
  1142. luit[1] = "-encoding";
  1143. luit[2] = term->misc.locale_str;
  1144. luit[3] = NULL;
  1145. } else
  1146. luit[1] = NULL;
  1147. command_to_exec_with_luit = luit;
  1148. }
  1149. }
  1150. #endif
  1151. #ifdef DEBUG
  1152. {
  1153. /* Set up stderr properly. Opening this log file cannot be
  1154. done securely by a privileged xterm process (although we try),
  1155. so the debug feature is disabled by default. */
  1156. int i = -1;
  1157. if (debug) {
  1158. creat_as(getuid(), getgid(), True, "xterm.debug.log", 0666);
  1159. i = open("xterm.debug.log", O_WRONLY | O_TRUNC);
  1160. }
  1161. if (i >= 0) {
  1162. dup2(i, 2);
  1163. /* mark this file as close on exec */
  1164. (void) fcntl(i, F_SETFD, 1);
  1165. }
  1166. }
  1167. #endif /* DEBUG */
  1168. /* open a terminal for client */
  1169. get_terminal();
  1170. spawn();
  1171. /* Child process is out there, let's catch its termination */
  1172. (void) signal(SIGCHLD, reapchild);
  1173. /* Realize procs have now been executed */
  1174. if (am_slave >= 0) { /* Write window id so master end can read and use */
  1175. char buf[80];
  1176. buf[0] = '\0';
  1177. sprintf(buf, "%lx\n", XtWindow(SHELL_OF(CURRENT_EMU(screen))));
  1178. write(screen->respond, buf, strlen(buf));
  1179. }
  1180. if (0 > (mode = fcntl(screen->respond, F_GETFL, 0)))
  1181. SysError(ERROR_F_GETFL);
  1182. mode |= O_NDELAY;
  1183. if (fcntl(screen->respond, F_SETFL, mode))
  1184. SysError(ERROR_F_SETFL);
  1185. FD_ZERO(&pty_mask);
  1186. FD_ZERO(&X_mask);
  1187. FD_ZERO(&Select_mask);
  1188. FD_SET(screen->respond, &pty_mask);
  1189. FD_SET(ConnectionNumber(screen->display), &X_mask);
  1190. FD_SET(screen->respond, &Select_mask);
  1191. FD_SET(ConnectionNumber(screen->display), &Select_mask);
  1192. max_plus1 = ((screen->respond < ConnectionNumber(screen->display))
  1193. ? (1 + ConnectionNumber(screen->display))
  1194. : (1 + screen->respond));
  1195. #ifdef DEBUG
  1196. if (debug)
  1197. printf("debugging on\n");
  1198. #endif /* DEBUG */
  1199. XSetErrorHandler(xerror);
  1200. XSetIOErrorHandler(xioerror);
  1201. initPtyData(&VTbuffer);
  1202. #ifdef ALLOWLOGGING
  1203. if (term->misc.log_on) {
  1204. StartLog(screen);
  1205. }
  1206. #endif
  1207. if (winToEmbedInto != None) {
  1208. XtRealizeWidget(toplevel);
  1209. /*
  1210. * This should probably query the tree or check the attributes of
  1211. * winToEmbedInto in order to verify that it exists, but I'm still not
  1212. * certain what is the best way to do it -GPS
  1213. */
  1214. XReparentWindow(XtDisplay(toplevel),
  1215. XtWindow(toplevel),
  1216. winToEmbedInto, 0, 0);
  1217. }
  1218. for (;;) {
  1219. #if OPT_TEK4014
  1220. if (screen->TekEmu)
  1221. TekRun();
  1222. else
  1223. #endif
  1224. VTRun();
  1225. }
  1226. return 0;
  1227. }
  1228. /*
  1229. * Called from get_pty to iterate over likely pseudo terminals
  1230. * we might allocate. Used on those systems that do not have
  1231. * a functional interface for allocating a pty.
  1232. * Returns 0 if found a pty, 1 if fails.
  1233. */
  1234. static int
  1235. pty_search(int *pty)
  1236. {
  1237. char namebuf[PTMS_BUFSZ];
  1238. /* ask the PTY manager */
  1239. int fd = open("/dev/ptms$", 0);
  1240. if (fd && ptioctl(fd, PTMS_GETPTY, namebuf) == 0) {
  1241. strcpy(ttydev, namebuf);
  1242. strcpy(ptydev, namebuf);
  1243. *x_basename(ttydev) = 't';
  1244. close(fd);
  1245. if ((*pty = open(ptydev, O_RDWR)) >= 0) {
  1246. #ifdef PTYDEBUG
  1247. ptioctl(*pty, XTY_TRACE, 0);
  1248. #endif
  1249. return 0;
  1250. } else {
  1251. fprintf(stderr, "Unable to open %s, errno=%d\n", ptydev, errno);
  1252. }
  1253. }
  1254. return 1;
  1255. }
  1256. /*
  1257. * This function opens up a pty master and stuffs its value into pty.
  1258. *
  1259. * If it finds one, it returns a value of 0. If it does not find one,
  1260. * it returns a value of !0. This routine is designed to be re-entrant,
  1261. * so that if a pty master is found and later, we find that the slave
  1262. * has problems, we can re-enter this function and get another one.
  1263. */
  1264. static int
  1265. get_pty(int *pty)
  1266. {
  1267. return pty_search(pty);
  1268. }
  1269. /*
  1270. * sets up X and initializes the terminal structure except for term.buf.fildes.
  1271. */
  1272. static void
  1273. get_terminal(void)
  1274. {
  1275. TScreen *screen = &term->screen;
  1276. screen->arrow = make_colored_cursor(XC_left_ptr,
  1277. T_COLOR(screen, MOUSE_FG),
  1278. T_COLOR(screen, MOUSE_BG));
  1279. }
  1280. /*
  1281. * The only difference in /etc/termcap between 4014 and 4015 is that
  1282. * the latter has support for switching character sets. We support the
  1283. * 4015 protocol, but ignore the character switches. Therefore, we
  1284. * choose 4014 over 4015.
  1285. *
  1286. * Features of the 4014 over the 4012: larger (19") screen, 12-bit
  1287. * graphics addressing (compatible with 4012 10-bit addressing),
  1288. * special point plot mode, incremental plot mode (not implemented in
  1289. * later Tektronix terminals), and 4 character sizes.
  1290. * All of these are supported by xterm.
  1291. */
  1292. #if OPT_TEK4014
  1293. static char *tekterm[] =
  1294. {
  1295. "tek4014",
  1296. "tek4015", /* 4014 with APL character set support */
  1297. "tek4012", /* 4010 with lower case */
  1298. "tek4013", /* 4012 with APL character set support */
  1299. "tek4010", /* small screen, upper-case only */
  1300. "dumb",
  1301. 0
  1302. };
  1303. #endif
  1304. /* The VT102 is a VT100 with the Advanced Video Option included standard.
  1305. * It also adds Escape sequences for insert/delete character/line.
  1306. * The VT220 adds 8-bit character sets, selective erase.
  1307. * The VT320 adds a 25th status line, terminal state interrogation.
  1308. * The VT420 has up to 48 lines on the screen.
  1309. */
  1310. static char *vtterm[] =
  1311. {
  1312. #ifdef USE_X11TERM
  1313. "x11term", /* for people who want special term name */
  1314. #endif
  1315. DFT_TERMTYPE, /* for people who want special term name */
  1316. "xterm", /* the prefered name, should be fastest */
  1317. "vt102",
  1318. "vt100",
  1319. "ansi",
  1320. "dumb",
  1321. 0
  1322. };
  1323. /* ARGSUSED */
  1324. static SIGNAL_T
  1325. hungtty(int i GCC_UNUSED)
  1326. {
  1327. longjmp(env, 1);
  1328. SIGNAL_RETURN;
  1329. }
  1330. struct {
  1331. int rows;
  1332. int cols;
  1333. } handshake = {
  1334. -1, -1
  1335. };
  1336. void
  1337. first_map_occurred(void)
  1338. {
  1339. TScreen *screen = &term->screen;
  1340. handshake.rows = screen->max_row;
  1341. handshake.cols = screen->max_col;
  1342. waiting_for_initial_map = False;
  1343. }
  1344. static void
  1345. set_owner(char *device, uid_t uid, gid_t gid, mode_t mode)
  1346. {
  1347. int why;
  1348. if (chown(device, uid, gid) < 0) {
  1349. why = errno;
  1350. if (why != ENOENT
  1351. && getuid() == 0) {
  1352. fprintf(stderr, "Cannot chown %s to %ld,%ld: %s\n",
  1353. device, (long) uid, (long) gid, strerror(why));
  1354. }
  1355. }
  1356. if (chmod(device, mode) < 0) {
  1357. why = errno;
  1358. if (why != ENOENT) {
  1359. struct stat sb;
  1360. if (stat(device, &sb) < 0) {
  1361. fprintf(stderr, "Cannot chmod %s to %03o: %s\n",
  1362. device, mode, strerror(why));
  1363. } else {
  1364. fprintf(stderr,
  1365. "Cannot chmod %s to %03o currently %03o: %s\n",
  1366. device, mode, (sb.st_mode & S_IFMT), strerror(why));
  1367. }
  1368. }
  1369. }
  1370. }
  1371. #define THE_PARENT 1
  1372. #define THE_CHILD 2
  1373. int whoami = -1;
  1374. SIGNAL_T
  1375. killit(int sig)
  1376. {
  1377. switch (whoami) {
  1378. case -1:
  1379. signal(sig, killit);
  1380. kill(-getpid(), sig);
  1381. break;
  1382. case THE_PARENT:
  1383. wait(NULL);
  1384. signal(SIGTERM, SIG_DFL);
  1385. kill(-getpid(), SIGTERM);
  1386. Exit(0);
  1387. break;
  1388. case THE_CHILD:
  1389. signal(SIGTERM, SIG_DFL);
  1390. kill(-getppid(), SIGTERM);
  1391. Exit(0);
  1392. break;
  1393. }
  1394. SIGNAL_RETURN;
  1395. }
  1396. #define close_fd(fd) close(fd), fd = -1
  1397. static int
  1398. spawn(void)
  1399. /*
  1400. * Inits pty and tty and forks a login process.
  1401. * Does not close fd Xsocket.
  1402. * If slave, the pty named in passedPty is already open for use
  1403. */
  1404. {
  1405. TScreen *screen = &term->screen;
  1406. int Xsocket = ConnectionNumber(screen->display);
  1407. int ttyfd = -1;
  1408. struct termio tio;
  1409. int status;
  1410. char termcap[TERMCAP_SIZE], newtc[TERMCAP_SIZE];
  1411. char *TermName = NULL;
  1412. char *ptr, *shname, buf[64];
  1413. int i, no_dev_tty = False, envsize;
  1414. char *dev_tty_name = (char *) 0;
  1415. TTYSIZE_STRUCT ts;
  1416. int pgrp = getpid();
  1417. char numbuf[12], **envnew;
  1418. screen->uid = getuid();
  1419. screen->gid = getgid();
  1420. if (am_slave >= 0) {
  1421. screen->respond = am_slave;
  1422. ptydev[strlen(ptydev) - 2] =
  1423. ttydev[strlen(ttydev) - 2] = passedPty[0];
  1424. ptydev[strlen(ptydev) - 1] =
  1425. ttydev[strlen(ttydev) - 1] = passedPty[1];
  1426. setgid(screen->gid);
  1427. setuid(screen->uid);
  1428. } else {
  1429. Bool tty_got_hung;
  1430. /*
  1431. * Sometimes /dev/tty hangs on open (as in the case of a pty
  1432. * that has gone away). Simply make up some reasonable
  1433. * defaults.
  1434. */
  1435. signal(SIGALRM, hungtty);
  1436. alarm(2); /* alarm(1) might return too soon */
  1437. if (!setjmp(env)) {
  1438. ttyfd = open("/dev/tty", O_RDWR);
  1439. alarm(0);
  1440. tty_got_hung = False;
  1441. } else {
  1442. tty_got_hung = True;
  1443. ttyfd = -1;
  1444. errno = ENXIO;
  1445. }
  1446. signal(SIGALRM, SIG_DFL);
  1447. /*
  1448. * Check results and ignore current control terminal if
  1449. * necessary. ENXIO is what is normally returned if there is
  1450. * no controlling terminal, but some systems (e.g. SunOS 4.0)
  1451. * seem to return EIO. Solaris 2.3 is said to return EINVAL.
  1452. */
  1453. if (ttyfd < 0) {
  1454. if (tty_got_hung || errno == ENXIO || errno == EIO ||
  1455. errno == EINVAL || errno == ENOTTY) {
  1456. no_dev_tty = True;
  1457. tio = d_tio;
  1458. } else {
  1459. SysError(ERROR_OPDEVTTY);
  1460. }
  1461. } else {
  1462. /* Get a copy of the current terminal's state,
  1463. * if we can. Some systems (e.g., SVR4 and MacII)
  1464. * may not have a controlling terminal at this point
  1465. * if started directly from xdm or xinit,
  1466. * in which case we just use the defaults as above.
  1467. */
  1468. if (ioctl(ttyfd, TCGETA, &tio) == -1)
  1469. tio = d_tio;
  1470. close_fd(ttyfd);
  1471. }
  1472. if (get_pty(&screen->respond)) {
  1473. /* no ptys! */
  1474. exit(ERROR_PTYS);
  1475. }
  1476. }
  1477. /* avoid double MapWindow requests */
  1478. XtSetMappedWhenManaged(XtParent(CURRENT_EMU(screen)), False);
  1479. wm_delete_window = XInternAtom(XtDisplay(toplevel), "WM_DELETE_WINDOW",
  1480. False);
  1481. if (!TEK4014_ACTIVE(screen))
  1482. VTInit(); /* realize now so know window size for tty driver */
  1483. if (Console) {
  1484. /*
  1485. * Inform any running xconsole program
  1486. * that we are going to steal the console.
  1487. */
  1488. XmuGetHostname(mit_console_name + MIT_CONSOLE_LEN, 255);
  1489. mit_console = XInternAtom(screen->display, mit_console_name, False);
  1490. /* the user told us to be the console, so we can use CurrentTime */
  1491. XtOwnSelection(XtParent(CURRENT_EMU(screen)),
  1492. mit_console, CurrentTime,
  1493. ConvertConsoleSelection, NULL, N

Large files files are truncated, but you can click here to view the full file