home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / x / volume12 / kterm / part13 < prev    next >
Text File  |  1991-05-11  |  52KB  |  1,735 lines

  1. Path: uunet!cs.utexas.edu!sun-barr!newstop!jethro!exodus!NMSU.Edu!mleisher
  2. From: mleisher@NMSU.Edu
  3. Newsgroups: comp.sources.x
  4. Subject: v12i094: kterm  - kanji xterm, Part13/18
  5. Message-ID: <13146@exodus.Eng.Sun.COM>
  6. Date: 11 May 91 00:51:20 GMT
  7. References: <csx-12i082:kterm@uunet.UU.NET>
  8. Sender: news@exodus.Eng.Sun.COM
  9. Lines: 1723
  10. Approved: argv@sun.com
  11.  
  12. Submitted-by: mleisher@NMSU.Edu
  13. Posting-number: Volume 12, Issue 94
  14. Archive-name: kterm/part13
  15.  
  16. #!/bin/sh
  17. # this is kt412.13 (part 13 of kterm-4.1.2)
  18. # do not concatenate these parts, unpack them in order with /bin/sh
  19. # file kterm-4.1.2/main.c continued
  20. #
  21. if test ! -r _shar_seq_.tmp; then
  22.     echo 'Please unpack part 1 first!'
  23.     exit 1
  24. fi
  25. (read Scheck
  26.  if test "$Scheck" != 13; then
  27.     echo Please unpack part "$Scheck" next!
  28.     exit 1
  29.  else
  30.     exit 0
  31.  fi
  32. ) < _shar_seq_.tmp || exit 1
  33. if test ! -f _shar_wnt_.tmp; then
  34.     echo 'x - still skipping kterm-4.1.2/main.c'
  35. else
  36. echo 'x - continuing file kterm-4.1.2/main.c'
  37. sed 's/^X//' << 'SHAR_EOF' >> 'kterm-4.1.2/main.c' &&
  38. #define XTTYMODE_start 7
  39. { "stop", 4, 0, '\0' },            /* tchars.t_stopc */
  40. #define XTTYMODE_stop 8
  41. { "brk", 3, 0, '\0' },            /* tchars.t_brkc */
  42. #define XTTYMODE_brk 9
  43. { "susp", 4, 0, '\0' },            /* ltchars.t_suspc */
  44. #define XTTYMODE_susp 10
  45. { "dsusp", 5, 0, '\0' },        /* ltchars.t_dsuspc */
  46. #define XTTYMODE_dsusp 11
  47. { "rprnt", 5, 0, '\0' },        /* ltchars.t_rprntc */
  48. #define XTTYMODE_rprnt 12
  49. { "flush", 5, 0, '\0' },        /* ltchars.t_flushc */
  50. #define XTTYMODE_flush 13
  51. { "weras", 5, 0, '\0' },        /* ltchars.t_werasc */
  52. #define XTTYMODE_weras 14
  53. { "lnext", 5, 0, '\0' },        /* ltchars.t_lnextc */
  54. #define XTTYMODE_lnext 15
  55. #define NXTTYMODES 16
  56. };
  57. X
  58. #ifdef USE_SYSV_UTMP
  59. extern struct utmp *getutent();
  60. extern struct utmp *getutid();
  61. extern struct utmp *getutline();
  62. extern void pututline();
  63. extern void setutent();
  64. extern void endutent();
  65. extern void utmpname();
  66. X
  67. extern struct passwd *getpwent();
  68. extern struct passwd *getpwuid();
  69. extern struct passwd *getpwnam();
  70. extern void setpwent();
  71. extern void endpwent();
  72. extern struct passwd *fgetpwent();
  73. #else    /* not USE_SYSV_UTMP */
  74. static char etc_utmp[] = UTMP_FILENAME;
  75. #ifdef LASTLOG
  76. static char etc_lastlog[] = LASTLOG_FILENAME;
  77. #endif 
  78. #ifdef WTMP
  79. static char etc_wtmp[] = WTMP_FILENAME;
  80. #endif
  81. #endif    /* USE_SYSV_UTMP */
  82. X
  83. /*
  84. X * Some people with 4.3bsd /bin/login seem to like to use login -p -f user
  85. X * to implement xterm -ls.  They can turn on USE_LOGIN_DASH_P and turn off
  86. X * WTMP and LASTLOG.
  87. X */
  88. #ifdef USE_LOGIN_DASH_P
  89. #ifndef LOGIN_FILENAME
  90. #define LOGIN_FILENAME "/bin/login"
  91. #endif
  92. static char bin_login[] = LOGIN_FILENAME;
  93. #endif
  94. X
  95. static int inhibit;
  96. static char passedPty[2];    /* name if pty if slave */
  97. X
  98. #ifdef TIOCCONS
  99. static int Console;
  100. #endif    /* TIOCCONS */
  101. #ifndef USE_SYSV_UTMP
  102. static int tslot;
  103. #endif    /* USE_SYSV_UTMP */
  104. static jmp_buf env;
  105. X
  106. char *ProgramName;
  107. Boolean sunFunctionKeys;
  108. X
  109. static struct _resource {
  110. X    char *xterm_name;
  111. X    char *icon_geometry;
  112. X    char *title;
  113. X    char *icon_name;
  114. X    char *term_name;
  115. X    char *tty_modes;
  116. X    Boolean utmpInhibit;
  117. X    Boolean sunFunctionKeys;    /* %%% should be widget resource? */
  118. X    Boolean wait_for_map;
  119. #ifdef KEEPALIVE
  120. X    Boolean keepalive;
  121. #endif
  122. } resource;
  123. X
  124. /* used by VT (charproc.c) */
  125. X
  126. #define offset(field)    XtOffset(struct _resource *, field)
  127. X
  128. static XtResource application_resources[] = {
  129. X    {"name", "Name", XtRString, sizeof(char *),
  130. #ifdef KTERM
  131. X    offset(xterm_name), XtRString, "kterm"},
  132. #else /* !KTERM */
  133. X    offset(xterm_name), XtRString, "xterm"},
  134. #endif /* !KTERM */
  135. X    {"iconGeometry", "IconGeometry", XtRString, sizeof(char *),
  136. X    offset(icon_geometry), XtRString, (caddr_t) NULL},
  137. X    {XtNtitle, XtCTitle, XtRString, sizeof(char *),
  138. X    offset(title), XtRString, (caddr_t) NULL},
  139. X    {XtNiconName, XtCIconName, XtRString, sizeof(char *),
  140. X    offset(icon_name), XtRString, (caddr_t) NULL},
  141. X    {"termName", "TermName", XtRString, sizeof(char *),
  142. X    offset(term_name), XtRString, (caddr_t) NULL},
  143. X    {"ttyModes", "TtyModes", XtRString, sizeof(char *),
  144. X    offset(tty_modes), XtRString, (caddr_t) NULL},
  145. X    {"utmpInhibit", "UtmpInhibit", XtRBoolean, sizeof (Boolean),
  146. X    offset(utmpInhibit), XtRString, "false"},
  147. X    {"sunFunctionKeys", "SunFunctionKeys", XtRBoolean, sizeof (Boolean),
  148. X    offset(sunFunctionKeys), XtRString, "false"},
  149. X    {"waitForMap", "WaitForMap", XtRBoolean, sizeof (Boolean),
  150. X        offset(wait_for_map), XtRString, "false"},
  151. #ifdef KEEPALIVE
  152. X    {"keepAlive", "KeepAlive", XtRBoolean, sizeof (Boolean),
  153. X        offset(keepalive), XtRString, "false"},
  154. #endif /* KEEPALIVE */
  155. };
  156. #undef offset
  157. X
  158. /* Command line options table.  Only resources are entered here...there is a
  159. X   pass over the remaining options after XtParseCommand is let loose. */
  160. X
  161. static char *fallback_resources[] = {
  162. #ifdef KTERM
  163. X    "KTerm*SimpleMenu*menuLabel.vertSpace: 100",
  164. X    "KTerm*SimpleMenu*HorizontalMargins: 16",
  165. X    "KTerm*SimpleMenu*Sme.height: 16",
  166. X    "KTerm*SimpleMenu*Cursor: left_ptr",
  167. X    "KTerm*mainMenu.Label:  Main Options (no app-defaults)",
  168. X    "KTerm*vtMenu.Label:  VT Options (no app-defaults)",
  169. X    "KTerm*fontMenu.Label:  VT Fonts (no app-defaults)",
  170. X    "KTerm*tekMenu.Label:  Tek Options (no app-defaults)",
  171. #else /* !KTERM */
  172. X    "XTerm*SimpleMenu*menuLabel.vertSpace: 100",
  173. X    "XTerm*SimpleMenu*HorizontalMargins: 16",
  174. X    "XTerm*SimpleMenu*Sme.height: 16",
  175. X    "XTerm*SimpleMenu*Cursor: left_ptr",
  176. X    "XTerm*mainMenu.Label:  Main Options (no app-defaults)",
  177. X    "XTerm*vtMenu.Label:  VT Options (no app-defaults)",
  178. X    "XTerm*fontMenu.Label:  VT Fonts (no app-defaults)",
  179. X    "XTerm*tekMenu.Label:  Tek Options (no app-defaults)",
  180. #endif /* !KTERM */
  181. X    NULL
  182. };
  183. X
  184. static XrmOptionDescRec optionDescList[] = {
  185. {"-geometry",    "*vt100.geometry",XrmoptionSepArg,    (caddr_t) NULL},
  186. {"-132",    "*c132",    XrmoptionNoArg,        (caddr_t) "on"},
  187. {"+132",    "*c132",    XrmoptionNoArg,        (caddr_t) "off"},
  188. {"-ah",        "*alwaysHighlight", XrmoptionNoArg,    (caddr_t) "on"},
  189. {"+ah",        "*alwaysHighlight", XrmoptionNoArg,    (caddr_t) "off"},
  190. {"-b",        "*internalBorder",XrmoptionSepArg,    (caddr_t) NULL},
  191. {"-cb",        "*cutToBeginningOfLine", XrmoptionNoArg, (caddr_t) "off"},
  192. {"+cb",        "*cutToBeginningOfLine", XrmoptionNoArg, (caddr_t) "on"},
  193. {"-cc",        "*charClass",    XrmoptionSepArg,    (caddr_t) NULL},
  194. {"-cn",        "*cutNewline",    XrmoptionNoArg,        (caddr_t) "off"},
  195. {"+cn",        "*cutNewline",    XrmoptionNoArg,        (caddr_t) "on"},
  196. {"-cr",        "*cursorColor",    XrmoptionSepArg,    (caddr_t) NULL},
  197. {"-cu",        "*curses",    XrmoptionNoArg,        (caddr_t) "on"},
  198. {"+cu",        "*curses",    XrmoptionNoArg,        (caddr_t) "off"},
  199. {"-e",        NULL,        XrmoptionSkipLine,    (caddr_t) NULL},
  200. #ifndef ENBUG /* kagotani */
  201. {"-fn",        "*vt100.font",    XrmoptionSepArg,    (caddr_t) NULL},
  202. #endif
  203. {"-fb",        "*boldFont",    XrmoptionSepArg,    (caddr_t) NULL},
  204. #ifdef KTERM
  205. {"-fl",        "*fontList",    XrmoptionSepArg,    (caddr_t) NULL},
  206. {"-flb",    "*boldFontList", XrmoptionSepArg,    (caddr_t) NULL},
  207. {"-fr",        "*romanKanaFont", XrmoptionSepArg,    (caddr_t) NULL},
  208. {"-frb",    "*romanKanaBoldFont", XrmoptionSepArg,    (caddr_t) NULL},
  209. #ifdef KTERM_KANJI
  210. #ifdef KTERM_HANZI
  211. {"-fhz",    "*hanziFont",    XrmoptionSepArg,    (caddr_t) NULL},
  212. {"-fhzb",    "*hanziBoldFont", XrmoptionSepArg,    (caddr_t) NULL},
  213. {"-hzm",    "*hanziMode",    XrmoptionSepArg,    (caddr_t) NULL},
  214. #endif /* KTERM_HANZI */
  215. #ifdef KTERM_HANGUL
  216. {"-fhg",    "*hangulFont",    XrmoptionSepArg,    (caddr_t) NULL},
  217. {"-fhgb",    "*hangulBoldFont", XrmoptionSepArg,    (caddr_t) NULL},
  218. {"-hgm",    "*hangulMode",    XrmoptionSepArg,    (caddr_t) NULL},
  219. #endif /* KTERM_HANGUL */
  220. {"-fk",        "*kanjiFont",    XrmoptionSepArg,    (caddr_t) NULL},
  221. {"-fkb",    "*kanjiBoldFont", XrmoptionSepArg,    (caddr_t) NULL},
  222. {"-km",        "*kanjiMode",    XrmoptionSepArg,    (caddr_t) NULL},
  223. {"-lang",    "*language",    XrmoptionSepArg,    (caddr_t) NULL},
  224. #endif /* KTERM_KANJI */
  225. {"-lsp",    "*lineSpace",    XrmoptionSepArg,    (caddr_t) NULL},
  226. #endif /* KTERM */
  227. {"-j",        "*jumpScroll",    XrmoptionNoArg,        (caddr_t) "on"},
  228. {"+j",        "*jumpScroll",    XrmoptionNoArg,        (caddr_t) "off"},
  229. #ifdef KEEPALIVE
  230. {"-ka",        "*keepAlive",    XrmoptionNoArg,        (caddr_t) "on"},
  231. {"+ka",        "*keepAlive",    XrmoptionNoArg,        (caddr_t) "off"},
  232. #endif /* KEEPALIVE */
  233. {"-l",        "*logging",    XrmoptionNoArg,        (caddr_t) "on"},
  234. {"+l",        "*logging",    XrmoptionNoArg,        (caddr_t) "off"},
  235. {"-lf",        "*logFile",    XrmoptionSepArg,    (caddr_t) NULL},
  236. {"-ls",        "*loginShell",    XrmoptionNoArg,        (caddr_t) "on"},
  237. {"+ls",        "*loginShell",    XrmoptionNoArg,        (caddr_t) "off"},
  238. {"-mb",        "*marginBell",    XrmoptionNoArg,        (caddr_t) "on"},
  239. {"+mb",        "*marginBell",    XrmoptionNoArg,        (caddr_t) "off"},
  240. {"-mc",        "*multiClickTime", XrmoptionSepArg,    (caddr_t) NULL},
  241. {"-ms",        "*pointerColor",XrmoptionSepArg,    (caddr_t) NULL},
  242. {"-nb",        "*nMarginBell",    XrmoptionSepArg,    (caddr_t) NULL},
  243. {"-rw",        "*reverseWrap",    XrmoptionNoArg,        (caddr_t) "on"},
  244. {"+rw",        "*reverseWrap",    XrmoptionNoArg,        (caddr_t) "off"},
  245. {"-s",        "*multiScroll",    XrmoptionNoArg,        (caddr_t) "on"},
  246. {"+s",        "*multiScroll",    XrmoptionNoArg,        (caddr_t) "off"},
  247. {"-sb",        "*scrollBar",    XrmoptionNoArg,        (caddr_t) "on"},
  248. {"+sb",        "*scrollBar",    XrmoptionNoArg,        (caddr_t) "off"},
  249. {"-sf",        "*sunFunctionKeys", XrmoptionNoArg,    (caddr_t) "on"},
  250. {"+sf",        "*sunFunctionKeys", XrmoptionNoArg,    (caddr_t) "off"},
  251. {"-si",        "*scrollTtyOutput",    XrmoptionNoArg,        (caddr_t) "off"},
  252. {"+si",        "*scrollTtyOutput",    XrmoptionNoArg,        (caddr_t) "on"},
  253. {"-sk",        "*scrollKey",    XrmoptionNoArg,        (caddr_t) "on"},
  254. {"+sk",        "*scrollKey",    XrmoptionNoArg,        (caddr_t) "off"},
  255. #ifdef STATUSLINE
  256. {"-st",        "*statusLine",    XrmoptionNoArg,        (caddr_t) "on"},
  257. {"+st",        "*statusLine",    XrmoptionNoArg,        (caddr_t) "off"},
  258. {"-sn",        "*statusNormal", XrmoptionNoArg,    (caddr_t) "on"},
  259. {"+sn",        "*statusNormal", XrmoptionNoArg,    (caddr_t) "off"},
  260. #endif /* STATUSLINE */
  261. {"-sl",        "*saveLines",    XrmoptionSepArg,    (caddr_t) NULL},
  262. {"-t",        "*tekStartup",    XrmoptionNoArg,        (caddr_t) "on"},
  263. {"+t",        "*tekStartup",    XrmoptionNoArg,        (caddr_t) "off"},
  264. {"-tm",        "*ttyModes",    XrmoptionSepArg,    (caddr_t) NULL},
  265. {"-tn",        "*termName",    XrmoptionSepArg,    (caddr_t) NULL},
  266. {"-ut",        "*utmpInhibit",    XrmoptionNoArg,        (caddr_t) "on"},
  267. {"+ut",        "*utmpInhibit",    XrmoptionNoArg,        (caddr_t) "off"},
  268. {"-vb",        "*visualBell",    XrmoptionNoArg,        (caddr_t) "on"},
  269. {"+vb",        "*visualBell",    XrmoptionNoArg,        (caddr_t) "off"},
  270. {"-wf",        "*waitForMap",    XrmoptionNoArg,        (caddr_t) "on"},
  271. {"+wf",        "*waitForMap",    XrmoptionNoArg,        (caddr_t) "off"},
  272. /* bogus old compatibility stuff for which there are
  273. X   standard XtInitialize options now */
  274. {"%",        "*tekGeometry",    XrmoptionStickyArg,    (caddr_t) NULL},
  275. {"#",        ".iconGeometry",XrmoptionStickyArg,    (caddr_t) NULL},
  276. {"-T",        "*title",    XrmoptionSepArg,    (caddr_t) NULL},
  277. {"-n",        "*iconName",    XrmoptionSepArg,    (caddr_t) NULL},
  278. {"-r",        "*reverseVideo",XrmoptionNoArg,        (caddr_t) "on"},
  279. {"+r",        "*reverseVideo",XrmoptionNoArg,        (caddr_t) "off"},
  280. {"-rv",        "*reverseVideo",XrmoptionNoArg,        (caddr_t) "on"},
  281. {"+rv",        "*reverseVideo",XrmoptionNoArg,        (caddr_t) "off"},
  282. {"-w",        ".borderWidth", XrmoptionSepArg,    (caddr_t) NULL},
  283. };
  284. X
  285. static struct _options {
  286. X  char *opt;
  287. X  char *desc;
  288. } options[] = {
  289. { "-help",                 "print out this message" },
  290. #ifdef KTERM
  291. { "-version",              "print out kterm version info" },
  292. #endif /* KTERM */
  293. { "-display displayname",  "X server to contact" },
  294. { "-geometry geom",        "size (in characters) and position" },
  295. { "-/+rv",                 "turn on/off reverse video" },
  296. { "-bg color",             "background color" },
  297. { "-fg color",             "foreground color" },
  298. { "-bd color",             "border color" },
  299. { "-bw number",            "border width in pixels" },
  300. { "-fn fontname",          "normal text font" },
  301. { "-iconic",               "start iconic" },
  302. { "-name string",          "client instance, icon, and title strings" },
  303. { "-title string",         "title string" },
  304. { "-xrm resourcestring",   "additional resource specifications" },
  305. { "-/+132",                "turn on/off column switch inhibiting" },
  306. { "-/+ah",                 "turn on/off always highlight" },
  307. { "-b number",             "internal border in pixels" },
  308. { "-/+cb",                 "turn on/off cut-to-beginning-of-line inhibit" },
  309. { "-cc classrange",        "specify additional character classes" },
  310. { "-/+cn",                 "turn on/off cut newline inhibit" },
  311. { "-cr color",             "text cursor color" },
  312. { "-/+cu",                 "turn on/off curses emulation" },
  313. { "-fb fontname",          "bold text font" },
  314. #ifdef KTERM
  315. { "-fl fontlist",          "normal fonts" },
  316. { "-flb fontlist",         "bold fonts" },
  317. { "-fr fontname",          "normal kana font" },
  318. { "-frb fontname",         "bold kana font" },
  319. #ifdef KTERM_KANJI
  320. #ifdef KTERM_HANZI
  321. { "-fhz fontname",         "normal Hanzi font" },
  322. { "-fhzb fontname",        "bold Hanzi font" },
  323. { "-hzm hanzimode",        "input Hanzi code (guobiao|big5|shift-guobiao)" },
  324. #endif /* KTERM_HANZI */
  325. #ifdef KTERM_HANGUL
  326. { "-fhg fontname",         "normal Hangul font" },
  327. { "-fhgb fontname",        "bold Hangul font" },
  328. { "-hgm hangulmode",       "input Hangul code (ks-8bit|n-byte)" },
  329. #endif /* KTERM_HANGUL */
  330. { "-fk fontname",          "normal Kanji font" },
  331. { "-fkb fontname",         "bold Kanji font" },
  332. { "-km kanjimode",         "input Kanji code (jis|euc|sjis)" },
  333. { "-lang language",        "which language to be displayed (chinese|japanese|korean)" },
  334. #endif /* KTERM_KANJI */
  335. { "-lsp number",           "number of extra dots between  lines" },
  336. #endif /* KTERM */
  337. { "-/+j",                  "turn on/off jump scroll" },
  338. #ifdef KEEPALIVE
  339. { "-/+ka",                 "turn on/off keeping connection alive" },
  340. #endif /* KEEPALIVE */
  341. { "-/+l",                  "turn on/off logging" },
  342. { "-lf filename",          "logging filename" },
  343. { "-/+ls",                 "turn on/off login shell" },
  344. { "-/+mb",                 "turn on/off margin bell" },
  345. { "-mc milliseconds",      "multiclick time in milliseconds" },
  346. { "-ms color",             "pointer color" },
  347. { "-nb number",            "margin bell in characters from right end" },
  348. { "-/+rw",                 "turn on/off reverse wraparound" },
  349. { "-/+s",                  "turn on/off multiscroll" },
  350. { "-/+sb",                 "turn on/off scrollbar" },
  351. { "-/+sf",                 "turn on/off Sun Function Key escape codes" },
  352. { "-/+si",                 "turn on/off scroll-on-tty-output inhibit" },
  353. { "-/+sk",                 "turn on/off scroll-on-keypress" },
  354. { "-sl number",            "number of scrolled lines to save" },
  355. #ifdef STATUSLINE
  356. { "-/+st",                 "turn on/off status line" },
  357. { "-/+sn",                 "turn on/off status line normal video" },
  358. #endif /* STATUSLINE */
  359. { "-/+t",                  "turn on/off Tek emulation window" },
  360. { "-tm string",            "terminal mode keywords and characters" },
  361. { "-tn name",              "TERM environment variable name" },
  362. { "-/+ut",                 "turn on/off utmp inhibit" },
  363. { "-/+vb",                 "turn on/off visual bell" },
  364. { "-e command args",       "command to execute" },
  365. { "%geom",                 "Tek window geometry" },
  366. { "#geom",                 "icon window geometry" },
  367. { "-T string",             "title name for window" },
  368. { "-n string",             "icon name for window" },
  369. { "-C",                    "intercept console messages, if supported" },
  370. { "-Sxxd",                 "slave mode on \"ttyxx\", file descriptor \"d\"" },
  371. { NULL, NULL }};
  372. X
  373. static char *message[] = {
  374. "Fonts must be fixed width and, if both normal and bold are specified, must",
  375. "have the same size.  If only a normal font is specified, it will be used for",
  376. "both normal and bold text (by doing overstriking).  The -e option, if given,",
  377. "must be appear at the end of the command line, otherwise the user's default",
  378. "shell will be started.  Options that start with a plus sign (+) restore the",
  379. "default.",
  380. NULL};
  381. X
  382. static void Syntax (badOption)
  383. X    char *badOption;
  384. {
  385. X    struct _options *opt;
  386. X    int col;
  387. X
  388. X    fprintf (stderr, "%s:  bad command line option \"%s\"\r\n\n",
  389. X         ProgramName, badOption);
  390. X
  391. X    fprintf (stderr, "usage:  %s", ProgramName);
  392. X    col = 8 + strlen(ProgramName);
  393. X    for (opt = options; opt->opt; opt++) {
  394. X    int len = 3 + strlen(opt->opt);     /* space [ string ] */
  395. X    if (col + len > 79) {
  396. X        fprintf (stderr, "\r\n   ");  /* 3 spaces */
  397. X        col = 3;
  398. X    }
  399. X    fprintf (stderr, " [%s]", opt->opt);
  400. X    col += len;
  401. X    }
  402. X
  403. X    fprintf (stderr, "\r\n\nType %s -help for a full description.\r\n\n",
  404. X         ProgramName);
  405. X    exit (1);
  406. }
  407. X
  408. static void Help ()
  409. {
  410. X    struct _options *opt;
  411. X    char **cpp;
  412. X
  413. X    fprintf (stderr, "usage:\n        %s [-options ...] [-e command args]\n\n",
  414. X         ProgramName);
  415. X    fprintf (stderr, "where options include:\n");
  416. X    for (opt = options; opt->opt; opt++) {
  417. X    fprintf (stderr, "    %-28s %s\n", opt->opt, opt->desc);
  418. X    }
  419. X
  420. X    putc ('\n', stderr);
  421. X    for (cpp = message; *cpp; cpp++) {
  422. X    fputs (*cpp, stderr);
  423. X    putc ('\n', stderr);
  424. X    }
  425. X    putc ('\n', stderr);
  426. X
  427. X    exit (0);
  428. }
  429. X
  430. #ifdef KTERM
  431. static void Version ()
  432. {
  433. X    fprintf (stderr, "kterm: version %s (patchlevel %d)\n", KTERM_VERSION,
  434. X             patchlevel);
  435. X    fprintf (stderr, "       with");
  436. #ifdef KTERM_KANJI
  437. X    fprintf (stderr, " [KTERM_KANJI]");
  438. # ifdef KTERM_HANZI
  439. X    fprintf(stderr, " [KTERM_HANZI]");
  440. # endif
  441. # ifdef KTERM_HANGUL
  442. X    fprintf(stderr, " [KTERM_HANGUL]");
  443. # endif
  444. # ifdef MB_WSEL
  445. X    fprintf(stderr, " [MB_WSEL]");
  446. # endif
  447. #endif
  448. #ifdef KTERM_KCONV
  449. X    fprintf (stderr, " [KTERM_KCONV]");
  450. #endif
  451. #ifdef KTERM_CTEXT
  452. X    fprintf(stderr, " [KTERM_CTEXT]");
  453. #endif /* KTERM_CTEXT */
  454. #ifdef COLOR_TEXT
  455. X    fprintf(stderr, " [COLOR_TEXT]");
  456. #endif /* COLOR_TEXT */
  457. #ifdef STATUSLINE
  458. X    fprintf (stderr, " [STATUSLINE]");
  459. #endif
  460. #ifdef KEEPALIVE
  461. X    fprintf (stderr, " [KEEPALIVE]");
  462. #endif
  463. X    fprintf (stderr, " options.\n");
  464. X
  465. X    exit (0);
  466. }
  467. #endif /* KTERM */
  468. X
  469. extern WidgetClass xtermWidgetClass;
  470. X
  471. Arg ourTopLevelShellArgs[] = {
  472. X    { XtNallowShellResize, (XtArgVal) TRUE },    
  473. X    { XtNinput, (XtArgVal) TRUE },
  474. };
  475. int number_ourTopLevelShellArgs = 2;
  476. X    
  477. XXtAppContext app_con;
  478. Widget toplevel;
  479. Bool waiting_for_initial_map;
  480. X
  481. main (argc, argv)
  482. int argc;
  483. char **argv;
  484. {
  485. X    register TScreen *screen;
  486. X    register int i, pty;
  487. X    int Xsocket, mode;
  488. X    char *basename();
  489. X    int xerror(), xioerror();
  490. X
  491. X    ProgramName = argv[0];
  492. X
  493. X    ttydev = (char *) malloc (strlen (TTYDEV) + 1);
  494. X    ptydev = (char *) malloc (strlen (PTYDEV) + 1);
  495. X    if (!ttydev || !ptydev) {
  496. X        fprintf (stderr, 
  497. X                 "%s:  unable to allocate memory for ttydev or ptydev\n",
  498. X             ProgramName);
  499. X        exit (1);
  500. X    }
  501. X    strcpy (ttydev, TTYDEV);
  502. X    strcpy (ptydev, PTYDEV);
  503. X
  504. #ifdef USE_SYSV_TERMIO
  505. X    /* Initialization is done here rather than above in order
  506. X    ** to prevent any assumptions about the order of the contents
  507. X    ** of the various terminal structures (which may change from
  508. X    ** implementation to implementation).
  509. X    */
  510. #if defined(macII) || defined(att)
  511. X    d_tio.c_iflag = ICRNL|IXON;
  512. X    d_tio.c_oflag = OPOST|ONLCR|TAB3;
  513. X        d_tio.c_cflag = B9600|CS8|CREAD|PARENB|HUPCL;
  514. X        d_tio.c_lflag = ISIG|ICANON|ECHO|ECHOE|ECHOK;
  515. X
  516. X    d_tio.c_line = 0;
  517. X
  518. X    d_tio.c_cc[VINTR] = CINTR;
  519. X    d_tio.c_cc[VQUIT] = CQUIT;
  520. X    d_tio.c_cc[VERASE] = CERASE;
  521. X    d_tio.c_cc[VKILL] = CKILL;
  522. X        d_tio.c_cc[VEOF] = CEOF;
  523. X    d_tio.c_cc[VEOL] = CNUL;
  524. X    d_tio.c_cc[VEOL2] = CNUL;
  525. X    d_tio.c_cc[VSWTCH] = CNUL;
  526. X
  527. #ifdef TIOCSLTC
  528. X        d_ltc.t_suspc = CSUSP;        /* t_suspc */
  529. X        d_ltc.t_dsuspc = CDSUSP;    /* t_dsuspc */
  530. X        d_ltc.t_rprntc = 0;        /* reserved...*/
  531. X        d_ltc.t_flushc = 0;
  532. X        d_ltc.t_werasc = 0;
  533. X        d_ltc.t_lnextc = 0;
  534. #endif /* TIOCSLTC */
  535. #else  /* else !macII */
  536. X    d_tio.c_iflag = ICRNL|IXON;
  537. X    d_tio.c_oflag = OPOST|ONLCR|TAB3;
  538. #ifdef BAUD_0
  539. X        d_tio.c_cflag = CS8|CREAD|PARENB|HUPCL;
  540. #else    /* !BAUD_0 */
  541. X        d_tio.c_cflag = B9600|CS8|CREAD|PARENB|HUPCL;
  542. #endif    /* !BAUD_0 */
  543. X        d_tio.c_lflag = ISIG|ICANON|ECHO|ECHOE|ECHOK;
  544. X    d_tio.c_line = 0;
  545. X    d_tio.c_cc[VINTR] = 0x7f;        /* DEL  */
  546. X    d_tio.c_cc[VQUIT] = '\\' & 0x3f;    /* '^\'    */
  547. X    d_tio.c_cc[VERASE] = '#';        /* '#'    */
  548. X    d_tio.c_cc[VKILL] = '@';        /* '@'    */
  549. X        d_tio.c_cc[VEOF] = 'D' & 0x3f;        /* '^D'    */
  550. X    d_tio.c_cc[VEOL] = '@' & 0x3f;        /* '^@'    */
  551. #ifdef VSWTCH
  552. X    d_tio.c_cc[VSWTCH] = '@' & 0x3f;    /* '^@'    */
  553. #endif    /* VSWTCH */
  554. X    /* now, try to inherit tty settings */
  555. X    {
  556. X        int i;
  557. X
  558. X        for (i = 0; i <= 2; i++) {
  559. X        struct termio deftio;
  560. X        if (ioctl (i, TCGETA, &deftio) == 0) {
  561. X            d_tio.c_cc[VINTR] = deftio.c_cc[VINTR];
  562. X            d_tio.c_cc[VQUIT] = deftio.c_cc[VQUIT];
  563. X            d_tio.c_cc[VERASE] = deftio.c_cc[VERASE];
  564. X            d_tio.c_cc[VKILL] = deftio.c_cc[VKILL];
  565. X            d_tio.c_cc[VEOF] = deftio.c_cc[VEOF];
  566. X            d_tio.c_cc[VEOL] = deftio.c_cc[VEOL];
  567. #ifdef VSWTCH
  568. X            d_tio.c_cc[VSWTCH] = deftio.c_cc[VSWTCH];
  569. #endif /* VSWTCH */
  570. X            break;
  571. X        }
  572. X        }
  573. X    }
  574. #ifdef TIOCSLTC
  575. X        d_ltc.t_suspc = '\000';        /* t_suspc */
  576. X        d_ltc.t_dsuspc = '\000';    /* t_dsuspc */
  577. X        d_ltc.t_rprntc = '\377';    /* reserved...*/
  578. X        d_ltc.t_flushc = '\377';
  579. X        d_ltc.t_werasc = '\377';
  580. X        d_ltc.t_lnextc = '\377';
  581. #endif    /* TIOCSLTC */
  582. #ifdef TIOCLSET
  583. X    d_lmode = 0;
  584. #endif    /* TIOCLSET */
  585. #endif  /* macII */
  586. #endif    /* USE_SYSV_TERMIO */
  587. X
  588. X    /* Init the Toolkit. */
  589. #ifdef KTERM
  590. X    toplevel = XtAppInitialize (&app_con, "KTerm", 
  591. #else /* !KTERM */
  592. X    toplevel = XtAppInitialize (&app_con, "XTerm", 
  593. #endif /* !KTERM */
  594. X                    optionDescList, XtNumber(optionDescList), 
  595. X                    &argc, argv, fallback_resources, 
  596. X                    NULL, 0);
  597. X
  598. X    XtGetApplicationResources( toplevel, &resource, application_resources,
  599. X                   XtNumber(application_resources), NULL, 0 );
  600. X
  601. X    waiting_for_initial_map = resource.wait_for_map;
  602. X
  603. #ifdef KEEPALIVE
  604. X    if (resource.keepalive) {
  605. X        int on = 1;
  606. X        (void)setsockopt(ConnectionNumber(XtDisplay(toplevel)),
  607. X                SOL_SOCKET, SO_KEEPALIVE,
  608. X                (char *)&on, sizeof(on));
  609. X    }
  610. #endif /* KEEPALIVE */
  611. X    /*
  612. X     * fill in terminal modes
  613. X     */
  614. X    if (resource.tty_modes) {
  615. X        int n = parse_tty_modes (resource.tty_modes,
  616. X                     ttymodelist, NXTTYMODES);
  617. X        if (n < 0) {
  618. X        fprintf (stderr, "%s:  bad tty modes \"%s\"\n",
  619. X             ProgramName, resource.tty_modes);
  620. X        } else if (n > 0) {
  621. X        override_tty_modes = 1;
  622. X        }
  623. X    }
  624. X
  625. X    xterm_name = resource.xterm_name;
  626. X    sunFunctionKeys = resource.sunFunctionKeys;
  627. #ifdef KTERM
  628. X    if (strcmp(xterm_name, "-") == 0) xterm_name = "kterm";
  629. #else /* KTERM */
  630. X    if (strcmp(xterm_name, "-") == 0) xterm_name = "xterm";
  631. #endif /* KTERM */
  632. X    if (resource.icon_geometry != NULL) {
  633. X        int scr, junk;
  634. X        int ix, iy;
  635. X        Arg args[2];
  636. X
  637. X        for(scr = 0;    /* yyuucchh */
  638. X        XtScreen(toplevel) != ScreenOfDisplay(XtDisplay(toplevel),scr);
  639. X        scr++);
  640. X
  641. X        args[0].name = XtNiconX;
  642. X        args[1].name = XtNiconY;
  643. X        XGeometry(XtDisplay(toplevel), scr, resource.icon_geometry, "",
  644. X              0, 0, 0, 0, 0, &ix, &iy, &junk, &junk);
  645. X        args[0].value = (XtArgVal) ix;
  646. X        args[1].value = (XtArgVal) iy;
  647. X        XtSetValues( toplevel, args, 2);
  648. X    }
  649. X
  650. X    XtSetValues (toplevel, ourTopLevelShellArgs, 
  651. X             number_ourTopLevelShellArgs);
  652. X
  653. X
  654. X    /* Parse the rest of the command line */
  655. X    for (argc--, argv++ ; argc > 0 ; argc--, argv++) {
  656. X        if(**argv != '-') Syntax (*argv);
  657. X
  658. X        switch(argv[0][1]) {
  659. X         case 'h':
  660. X        Help ();
  661. X        /* NOTREACHED */
  662. #ifdef KTERM
  663. X         case 'v':
  664. X        Version ();
  665. X        /* NOTREACHED */
  666. #endif /* KTERM */
  667. X         case 'C':
  668. #ifdef TIOCCONS
  669. X        Console = TRUE;
  670. #endif    /* TIOCCONS */
  671. X        continue;
  672. X         case 'S':
  673. X        sscanf(*argv + 2, "%c%c%d", passedPty, passedPty+1,
  674. X         &am_slave);
  675. X        if (am_slave <= 0) Syntax(*argv);
  676. X        continue;
  677. #ifdef DEBUG
  678. X         case 'D':
  679. X        debug = TRUE;
  680. X        continue;
  681. #endif    /* DEBUG */
  682. X         case 'e':
  683. X        if (argc <= 1) Syntax (*argv);
  684. X        command_to_exec = ++argv;
  685. X        break;
  686. X         default:
  687. X        Syntax (*argv);
  688. X        }
  689. X        break;
  690. X    }
  691. X
  692. X    XawSimpleMenuAddGlobalActions (XtWidgetToApplicationContext(toplevel));
  693. X    XtRegisterGrabAction (HandlePopupMenu, True,
  694. X                  (ButtonPressMask|ButtonReleaseMask),
  695. X                  GrabModeAsync, GrabModeAsync);
  696. X
  697. X        term = (XtermWidget) XtCreateManagedWidget(
  698. X        "vt100", xtermWidgetClass, toplevel, NULL, 0);
  699. X            /* this causes the initialize method to be called */
  700. X
  701. X        screen = &term->screen;
  702. X
  703. X    term->flags = WRAPAROUND;
  704. X    update_autowrap();
  705. X    if (!screen->jumpscroll) {
  706. X        term->flags |= SMOOTHSCROLL;
  707. X        update_jumpscroll();
  708. X    }
  709. X    if (term->misc.reverseWrap) {
  710. X        term->flags |= REVERSEWRAP;
  711. X        update_reversewrap();
  712. X    }
  713. X    if (term->misc.re_verse) {
  714. X        term->flags |= REVERSE_VIDEO;
  715. X        update_reversevideo();
  716. X    }
  717. X
  718. #ifdef KTERM_KANJI
  719. X        if (!term->misc.lang) {
  720. X            XtWarning("Language choice not found.");
  721. X            term->misc.lang = KTERM_DEFAULT_LANG;
  722. X            term->misc.k_m = KTERM_DEFAULT_MODE;
  723. X        }
  724. X
  725. X        switch(term->misc.lang[0]) {
  726. #ifdef KTERM_HANZI
  727. X          case 'c':
  728. X          case 'C':
  729. X            (void)load_hzconv_table(term->misc.hz_gb2big_tbl);
  730. X            (void)load_hzconv_table(term->misc.hz_big2gb_tbl);
  731. X            if (term->misc.hz_m) {
  732. X                switch (term->misc.hz_m[0]) {
  733. X                  case 'g': case 'G':
  734. X                    term->flags |= GUOBIAO_HANZI;
  735. X                    break;
  736. X                  case 'b': case 'B':
  737. X                    term->flags |= BIG5_HANZI;
  738. X                    update_big5mode();
  739. X                    break;
  740. X                  case 's': case 'S':
  741. X                    term->flags |= SGB_HANZI;
  742. X                    update_sgbmode();
  743. X                    break;
  744. X                }
  745. X            }
  746. X            break;
  747. #endif /* KTERM_HANZI */
  748. #ifdef KTERM_HANGUL
  749. X          case 'k':
  750. X          case 'K':
  751. X            load_hgconv_table(term->misc.hg_n2ks_tbl);
  752. X            if (term->misc.hg_m) {
  753. X                switch(term->misc.hg_m[0]) {
  754. X                  case 'k': case 'K':
  755. X                    term->flags |= KS_HANGUL;
  756. X                    update_ksmode();
  757. X                    break;
  758. X                  case 'n': case 'N':
  759. X                    term->flags |= NBYTE_HANGUL;
  760. X                    update_nbmode();
  761. X                    break;
  762. X                }
  763. X            }
  764. X            break;
  765. #endif /* KTERM_HANGUL */
  766. X
  767. /*
  768. X * The default language will be Japanese, so set necessary flags.
  769. X */
  770. X
  771. X          default:
  772. X        switch (term->misc.k_m[0]) {
  773. X        case 'j': case 'J':
  774. X            break;
  775. X        case 'e': case 'E': case 'x': case 'X': case 'u': case 'U':
  776. X            term->flags |= EUC_KANJI;
  777. X            update_eucmode();
  778. X            break;
  779. X        case 's': case 'S': case 'm': case 'M':
  780. X            term->flags |= SJIS_KANJI;
  781. X            update_sjismode();
  782. X            break;
  783. X        }
  784. X    }
  785. #endif /* KTERM_KANJI */
  786. X
  787. X    inhibit = 0;
  788. X    if (term->misc.logInhibit)         inhibit |= I_LOG;
  789. X    if (term->misc.signalInhibit)        inhibit |= I_SIGNAL;
  790. X    if (term->misc.tekInhibit)            inhibit |= I_TEK;
  791. X
  792. #ifdef STATUSLINE
  793. X    screen->reversestatus = !term->misc.statusnormal;
  794. #endif /* STATUSLINE */
  795. X
  796. X    term->initflags = term->flags;
  797. X
  798. /*
  799. X * Set title and icon name if not specified
  800. X */
  801. X
  802. X    if (command_to_exec) {
  803. X        Arg args[2];
  804. X
  805. X        if (!resource.title) {
  806. X        if (command_to_exec) {
  807. X            resource.title = basename (command_to_exec[0]);
  808. X        } /* else not reached */
  809. X        }
  810. X
  811. X        if (!resource.icon_name) 
  812. X          resource.icon_name = resource.title;
  813. X        XtSetArg (args[0], XtNtitle, resource.title);
  814. X        XtSetArg (args[1], XtNiconName, resource.icon_name);        
  815. X
  816. X        XtSetValues (toplevel, args, 2);
  817. X    }
  818. X
  819. X
  820. X    if(inhibit & I_TEK)
  821. X        screen->TekEmu = FALSE;
  822. X
  823. X    if(screen->TekEmu && !TekInit())
  824. X        exit(ERROR_INIT);
  825. X
  826. X    /* set up stderr properly */
  827. X    i = -1;
  828. #ifdef DEBUG
  829. X    if(debug)
  830. X        i = open ("xterm.debug.log", O_WRONLY | O_CREAT | O_TRUNC,
  831. X         0666);
  832. #endif    /* DEBUG */
  833. X    if(i >= 0) {
  834. #ifdef USE_SYSV_TERMIO
  835. X        /* SYSV has another pointer which should be part of the
  836. X        ** FILE structure but is actually a seperate array.
  837. X        */
  838. X        unsigned char *old_bufend;
  839. X
  840. X        old_bufend = (unsigned char *) _bufend(stderr);
  841. X        stderr->_file = i;
  842. X        _bufend(stderr) = old_bufend;
  843. #else    /* USE_SYSV_TERMIO */
  844. X        stderr->_file = i;
  845. #endif    /* USE_SYSV_TERMIO */
  846. X
  847. X        /* mark this file as close on exec */
  848. X        (void) fcntl(i, F_SETFD, 1);
  849. X    }
  850. X
  851. X    /* open a terminal for client */
  852. X    get_terminal ();
  853. X    spawn ();
  854. X    /* Child process is out there, let's catch it's termination */
  855. X    signal (SIGCHLD, reapchild);
  856. X
  857. X    /* Realize procs have now been executed */
  858. X
  859. X    Xsocket = screen->display->fd;
  860. X    pty = screen->respond;
  861. X
  862. X    if (am_slave) { /* Write window id so master end can read and use */
  863. X        char buf[80];
  864. X
  865. X        buf[0] = '\0';
  866. X        sprintf (buf, "%lx\n", 
  867. X                 screen->TekEmu ? XtWindow (XtParent (tekWidget)) :
  868. X                      XtWindow (XtParent (term)));
  869. X        write (pty, buf, strlen (buf));
  870. X    }
  871. X
  872. X    if (term->misc.log_on) {
  873. X        StartLog(screen);
  874. X    }
  875. X    screen->inhibit = inhibit;
  876. X
  877. #ifdef USE_SYSV_TERMIO
  878. X    if (0 > (mode = fcntl(pty, F_GETFL, 0)))
  879. X        Error();
  880. X    mode |= O_NDELAY;
  881. X    if (fcntl(pty, F_SETFL, mode))
  882. X        Error();
  883. #else    /* USE_SYSV_TERMIO */
  884. X    mode = 1;
  885. X    if (ioctl (pty, FIONBIO, (char *)&mode) == -1) SysError (ERROR_FIONBIO);
  886. #endif    /* USE_SYSV_TERMIO */
  887. X    
  888. X    pty_mask = 1 << pty;
  889. X    X_mask = 1 << Xsocket;
  890. X    Select_mask = pty_mask | X_mask;
  891. X    max_plus1 = (pty < Xsocket) ? (1 + Xsocket) : (1 + pty);
  892. X
  893. #ifdef DEBUG
  894. X    if (debug) printf ("debugging on\n");
  895. #endif    /* DEBUG */
  896. X    XSetErrorHandler(xerror);
  897. X    XSetIOErrorHandler(xioerror);
  898. X    for( ; ; ) {
  899. X        if(screen->TekEmu) {
  900. X            TekRun();
  901. X        } else
  902. X            VTRun();
  903. X    }
  904. }
  905. X
  906. char *basename(name)
  907. char *name;
  908. {
  909. X    register char *cp;
  910. X    char *rindex();
  911. X
  912. X    return((cp = rindex(name, '/')) ? cp + 1 : name);
  913. }
  914. X
  915. /* This function opens up a pty master and stuffs it's value into pty.
  916. X * If it finds one, it returns a value of 0.  If it does not find one,
  917. X * it returns a value of !0.  This routine is designed to be re-entrant,
  918. X * so that if a pty master is found and later, we find that the slave
  919. X * has problems, we can re-enter this function and get another one.
  920. X */
  921. X
  922. get_pty (pty)
  923. int *pty;
  924. {
  925. X    static int devindex, letter = 0;
  926. X
  927. #ifdef att
  928. X    if ((*pty = open ("/dev/ptmx", O_RDWR)) < 0) {
  929. X        return 1;
  930. X    }
  931. X    return 0;
  932. #else /* !att, need lots of code */
  933. X
  934. #if defined(umips) && defined (SYSTYPE_SYSV)
  935. X    struct stat fstat_buf;
  936. X
  937. X    *pty = open ("/dev/ptc", O_RDWR);
  938. X    if (*pty < 0 || (fstat (*pty, &fstat_buf)) < 0) {
  939. X      return(1);
  940. X    }
  941. X    sprintf (ttydev, "/dev/ttyq%d", minor(fstat_buf.st_rdev));
  942. X    sprintf (ptydev, "/dev/ptyq%d", minor(fstat_buf.st_rdev));
  943. X    if ((*tty = open (ttydev, O_RDWR)) < 0) {
  944. X      close (*pty);
  945. X      return(1);
  946. X    }
  947. X    /* got one! */
  948. X    return(0);
  949. #else /* not (umips && SYSTYPE_SYSV) */
  950. #ifdef CRAY
  951. X    for (; devindex < 256; devindex++) {
  952. X        sprintf (ttydev, "/dev/ttyp%03d", devindex);
  953. X        sprintf (ptydev, "/dev/pty/%03d", devindex);
  954. X
  955. X        if ((*pty = open (ptydev, O_RDWR)) >= 0) {
  956. X        /* We need to set things up for our next entry
  957. X         * into this function!
  958. X         */
  959. X        (void) devindex++;
  960. X        return(0);
  961. X        }
  962. X    }
  963. #else /* !CRAY */
  964. X    while (PTYCHAR1[letter]) {
  965. X        ttydev [strlen(ttydev) - 2]  = ptydev [strlen(ptydev) - 2] =
  966. X            PTYCHAR1 [letter];
  967. X
  968. X        while (PTYCHAR2[devindex]) {
  969. X        ttydev [strlen(ttydev) - 1] = ptydev [strlen(ptydev) - 1] =
  970. X            PTYCHAR2 [devindex];
  971. X        if ((*pty = open (ptydev, O_RDWR)) >= 0) {
  972. X            /* We need to set things up for our next entry
  973. X             * into this function!
  974. X             */
  975. X            (void) devindex++;
  976. X            return(0);
  977. X        }
  978. X        devindex++;
  979. X        }
  980. X        devindex = 0;
  981. X        (void) letter++;
  982. X    }
  983. #endif /* CRAY else not CRAY */
  984. X    /* We were unable to allocate a pty master!  Return an error
  985. X     * condition and let our caller terminate cleanly.
  986. X     */
  987. X    return(1);
  988. #endif /* umips && SYSTYPE_SYSV */
  989. #endif /* att */
  990. }
  991. X
  992. get_terminal ()
  993. /* 
  994. X * sets up X and initializes the terminal structure except for term.buf.fildes.
  995. X */
  996. {
  997. X    register TScreen *screen = &term->screen;
  998. X    
  999. X    screen->arrow = make_colored_cursor (XC_left_ptr, 
  1000. X                         screen->mousecolor,
  1001. X                         screen->mousecolorback);
  1002. }
  1003. X
  1004. /*
  1005. X * The only difference in /etc/termcap between 4014 and 4015 is that 
  1006. X * the latter has support for switching character sets.  We support the
  1007. X * 4015 protocol, but ignore the character switches.  Therefore, we should
  1008. X * probably choose 4014 over 4015.
  1009. X */
  1010. X
  1011. static char *tekterm[] = {
  1012. X    "tek4014",
  1013. X    "tek4015",        /* has alternate character set switching */
  1014. X    "tek4013",
  1015. X    "tek4010",
  1016. X    "dumb",
  1017. X    0
  1018. };
  1019. X
  1020. static char *vtterm[] = {
  1021. #ifdef KTERM
  1022. X    "kterm",
  1023. #endif
  1024. #ifdef USE_X11TERM
  1025. X    "x11term",        /* for people who want special term name */
  1026. #endif
  1027. X    "xterm",        /* the prefered name, should be fastest */
  1028. X    "vt102",
  1029. X    "vt100",
  1030. X    "ansi",
  1031. X    "dumb",
  1032. X    0
  1033. };
  1034. X
  1035. /* ARGSUSED */
  1036. SIGNAL_T hungtty(i)
  1037. X    int i;
  1038. {
  1039. X    longjmp(env, 1);
  1040. X    SIGNAL_RETURN;
  1041. }
  1042. X
  1043. #ifdef USE_HANDSHAKE
  1044. typedef enum {        /* c == child, p == parent                        */
  1045. X    PTY_BAD,    /* c->p: can't open pty slave for some reason     */
  1046. X    PTY_FATALERROR,    /* c->p: we had a fatal error with the pty        */
  1047. X    PTY_GOOD,    /* c->p: we have a good pty, let's go on          */
  1048. X    PTY_NEW,    /* p->c: here is a new pty slave, try this        */
  1049. X    PTY_NOMORE,    /* p->c; no more pty's, terminate                 */
  1050. X    UTMP_ADDED,    /* c->p: utmp entry has been added                */
  1051. X    UTMP_TTYSLOT,    /* c->p: here is my ttyslot                       */
  1052. X    PTY_EXEC    /* p->c: window has been mapped the first time    */
  1053. } status_t;
  1054. X
  1055. typedef struct {
  1056. X    status_t status;
  1057. X    int error;
  1058. X    int fatal_error;
  1059. X    int tty_slot;
  1060. X    int rows;
  1061. X    int cols;
  1062. X    char buffer[1024];
  1063. } handshake_t;
  1064. X
  1065. /* HsSysError()
  1066. X *
  1067. X * This routine does the equivalent of a SysError but it handshakes
  1068. X * over the errno and error exit to the master process so that it can
  1069. X * display our error message and exit with our exit code so that the
  1070. X * user can see it.
  1071. X */
  1072. X
  1073. void
  1074. HsSysError(pf, error)
  1075. int pf;
  1076. int error;
  1077. {
  1078. X    handshake_t handshake;
  1079. X
  1080. X    handshake.status = PTY_FATALERROR;
  1081. X    handshake.error = errno;
  1082. X    handshake.fatal_error = error;
  1083. X    strcpy(handshake.buffer, ttydev);
  1084. X    write(pf, &handshake, sizeof(handshake));
  1085. X    exit(error);
  1086. }
  1087. X
  1088. static int pc_pipe[2];    /* this pipe is used for parent to child transfer */
  1089. static int cp_pipe[2];    /* this pipe is used for child to parent transfer */
  1090. X
  1091. first_map_occurred ()
  1092. {
  1093. X    handshake_t handshake;
  1094. X    register TScreen *screen = &term->screen;
  1095. X
  1096. X    if (screen->max_row > 0 && screen->max_col > 0) {
  1097. X    handshake.status = PTY_EXEC;
  1098. X    handshake.rows = screen->max_row;
  1099. X    handshake.cols = screen->max_col;
  1100. X    write (pc_pipe[1], (char *) &handshake, sizeof(handshake));
  1101. X    close (cp_pipe[0]);
  1102. X    close (pc_pipe[1]);
  1103. X    waiting_for_initial_map = False;
  1104. X    }
  1105. }
  1106. #else
  1107. /*
  1108. X * temporary hack to get xterm working on att ptys
  1109. X */
  1110. first_map_occurred ()
  1111. {
  1112. X    return;
  1113. }
  1114. #define HsSysError(a,b)
  1115. #endif /* USE_HANDSHAKE else !USE_HANDSHAKE */
  1116. X
  1117. X
  1118. spawn ()
  1119. /* 
  1120. X *  Inits pty and tty and forks a login process.
  1121. X *  Does not close fd Xsocket.
  1122. X *  If slave, the pty named in passedPty is already open for use
  1123. X */
  1124. {
  1125. X    extern char *SysErrorMsg();
  1126. X    register TScreen *screen = &term->screen;
  1127. X    int Xsocket = screen->display->fd;
  1128. #ifdef USE_HANDSHAKE
  1129. X    handshake_t handshake;
  1130. #else
  1131. X    int fds[2];
  1132. #endif
  1133. X    int tty = -1;
  1134. X    int discipline;
  1135. X    int done;
  1136. #ifdef USE_SYSV_TERMIO
  1137. X    struct termio tio;
  1138. X    struct termio dummy_tio;
  1139. #ifdef TIOCLSET
  1140. X    unsigned lmode;
  1141. #endif    /* TIOCLSET */
  1142. #ifdef TIOCSLTC
  1143. X    struct ltchars ltc;
  1144. #endif    /* TIOCSLTC */
  1145. X    int one = 1;
  1146. X    int zero = 0;
  1147. X    int status;
  1148. #else    /* else not USE_SYSV_TERMIO */
  1149. X    unsigned lmode;
  1150. X    struct tchars tc;
  1151. X    struct ltchars ltc;
  1152. X    struct sgttyb sg;
  1153. #endif    /* USE_SYSV_TERMIO */
  1154. X
  1155. X    char termcap [1024];
  1156. X    char newtc [1024];
  1157. X    char *ptr, *shname, *shname_minus;
  1158. X    int i, no_dev_tty = FALSE;
  1159. #ifdef USE_SYSV_TERMIO
  1160. X    char *dev_tty_name = (char *) 0;
  1161. X    int fd;            /* for /etc/wtmp */
  1162. #endif    /* USE_SYSV_TERMIO */
  1163. X    char **envnew;        /* new environment */
  1164. X    char buf[32];
  1165. X    char *TermName = NULL;
  1166. X    int ldisc = 0;
  1167. #ifdef sun
  1168. #ifdef TIOCSSIZE
  1169. X    struct ttysize ts;
  1170. #endif    /* TIOCSSIZE */
  1171. #else    /* not sun */
  1172. #ifdef TIOCSWINSZ
  1173. X    struct winsize ws;
  1174. #endif    /* TIOCSWINSZ */
  1175. #endif    /* sun */
  1176. X    struct passwd *pw = NULL;
  1177. #ifdef UTMP
  1178. X    struct utmp utmp;
  1179. #ifdef LASTLOG
  1180. X    struct lastlog lastlog;
  1181. #endif    /* LASTLOG */
  1182. #endif    /* UTMP */
  1183. X
  1184. X    screen->uid = getuid();
  1185. X    screen->gid = getgid();
  1186. X
  1187. #ifdef SIGTTOU
  1188. X    /* so that TIOCSWINSZ || TIOCSIZE doesn't block */
  1189. X    signal(SIGTTOU,SIG_IGN);
  1190. #endif
  1191. X
  1192. X    if (am_slave) {
  1193. X        screen->respond = am_slave;
  1194. X        ptydev[strlen(ptydev) - 2] = ttydev[strlen(ttydev) - 2] =
  1195. X            passedPty[0];
  1196. X        ptydev[strlen(ptydev) - 1] = ttydev[strlen(ttydev) - 1] =
  1197. X            passedPty[1];
  1198. X
  1199. X        setgid (screen->gid);
  1200. X        setuid (screen->uid);
  1201. X    } else {
  1202. X        Bool tty_got_hung = False;
  1203. X
  1204. X         /*
  1205. X          * Sometimes /dev/tty hangs on open (as in the case of a pty
  1206. X          * that has gone away).  Simply make up some reasonable
  1207. X          * defaults.
  1208. X          */
  1209. X         signal(SIGALRM, hungtty);
  1210. X         alarm(2);        /* alarm(1) might return too soon */
  1211. X         if (! setjmp(env)) {
  1212. X             tty = open ("/dev/tty", O_RDWR, 0);
  1213. X             alarm(0);
  1214. X         } else {
  1215. X            tty_got_hung = True;
  1216. X             tty = -1;
  1217. X             errno = ENXIO;
  1218. X         }
  1219. X         signal(SIGALRM, SIG_DFL);
  1220. X        /*
  1221. X         * Check results and ignore current control terminal if
  1222. X         * necessary.  ENXIO is what is normally returned if there is
  1223. X         * no controlling terminal, but some systems (e.g. SunOS 4.0)
  1224. X         * seem to return EIO.
  1225. X         */
  1226. X         if (tty < 0) {
  1227. X            if (tty_got_hung || errno == ENXIO || errno == EIO) {
  1228. X                no_dev_tty = TRUE;
  1229. #ifdef USE_SYSV_TERMIO
  1230. X                tio = d_tio;
  1231. #ifdef TIOCSLTC
  1232. X                ltc = d_ltc;
  1233. #endif    /* TIOCSLTC */
  1234. #ifdef TIOCLSET
  1235. X                lmode = d_lmode;
  1236. #endif    /* TIOCLSET */
  1237. #else    /* not USE_SYSV_TERMIO */
  1238. X                sg = d_sg;
  1239. X                tc = d_tc;
  1240. X                discipline = d_disipline;
  1241. X                ltc = d_ltc;
  1242. X                lmode = d_lmode;
  1243. #endif    /* USE_SYSV_TERMIO */
  1244. X            } else {
  1245. X                SysError(ERROR_OPDEVTTY);
  1246. X            }
  1247. X        } else {
  1248. X            /* get a copy of the current terminal's state */
  1249. X
  1250. #ifdef USE_SYSV_TERMIO
  1251. X            if(ioctl(tty, TCGETA, &tio) == -1)
  1252. X                SysError(ERROR_TIOCGETP);
  1253. #ifdef TIOCSLTC
  1254. X            if(ioctl(tty, TIOCGLTC, <c) == -1)
  1255. X                SysError(ERROR_TIOCGLTC);
  1256. #endif    /* TIOCSLTC */
  1257. #ifdef TIOCLSET
  1258. X            if(ioctl(tty, TIOCLGET, &lmode) == -1)
  1259. X                SysError(ERROR_TIOCLGET);
  1260. #endif    /* TIOCLSET */
  1261. #else    /* not USE_SYSV_TERMIO */
  1262. X            if(ioctl(tty, TIOCGETP, (char *)&sg) == -1)
  1263. X                SysError (ERROR_TIOCGETP);
  1264. X            if(ioctl(tty, TIOCGETC, (char *)&tc) == -1)
  1265. X                SysError (ERROR_TIOCGETC);
  1266. X            if(ioctl(tty, TIOCGETD, (char *)&discipline) == -1)
  1267. X                SysError (ERROR_TIOCGETD);
  1268. X            if(ioctl(tty, TIOCGLTC, (char *)<c) == -1)
  1269. X                SysError (ERROR_TIOCGLTC);
  1270. X            if(ioctl(tty, TIOCLGET, (char *)&lmode) == -1)
  1271. X                SysError (ERROR_TIOCLGET);
  1272. #endif    /* USE_SYSV_TERMIO */
  1273. X            close (tty);
  1274. X            /* tty is no longer an open fd! */
  1275. X            tty = -1;
  1276. X        }
  1277. X
  1278. #ifdef     PUCC_PTYD
  1279. X        if(-1 == (screen->respond = openrpty(ttydev, ptydev,
  1280. X                (resource.utmpInhibit ?  OPTY_NOP : OPTY_LOGIN),
  1281. X                getuid(), XDisplayString(screen->display)))) {
  1282. #else /* not PUCC_PTYD */
  1283. X        if (get_pty (&screen->respond)) {
  1284. #endif /* PUCC_PTYD */
  1285. X            /*  no ptys! */
  1286. X            (void) fprintf(stderr, "%s: no available ptys\n",
  1287. X                       xterm_name);
  1288. X            exit (ERROR_PTYS);
  1289. #ifdef PUCC_PTYD
  1290. X        }
  1291. #else
  1292. X        }            /* keep braces balanced for emacs */
  1293. #endif
  1294. #ifdef PUCC_PTYD
  1295. X          else {
  1296. X            /*
  1297. X             *  set the fd of the master in a global var so
  1298. X             *  we can undo all this on exit
  1299. X             *
  1300. X             */
  1301. X            Ptyfd = screen->respond;
  1302. X          }
  1303. #endif /* PUCC_PTYD */
  1304. X    }
  1305. X
  1306. X    /* avoid double MapWindow requests */
  1307. X    XtSetMappedWhenManaged( screen->TekEmu ? XtParent(tekWidget) :
  1308. X                    XtParent(term), False );
  1309. X        /* Realize the Tek or VT widget, depending on which mode we're in.
  1310. X           If VT mode, this calls VTRealize (the widget's Realize proc) */
  1311. X        XtRealizeWidget (screen->TekEmu ? XtParent(tekWidget) :
  1312. X             XtParent(term));
  1313. X
  1314. X    if(screen->TekEmu) {
  1315. X        envnew = tekterm;
  1316. X        ptr = newtc;
  1317. X    } else {
  1318. X        envnew = vtterm;
  1319. X        ptr = termcap;
  1320. X    }
  1321. X    TermName = NULL;
  1322. X    if (resource.term_name) {
  1323. X        if (tgetent (ptr, resource.term_name) == 1) {
  1324. X        TermName = resource.term_name;
  1325. X        if (!screen->TekEmu)
  1326. X            resize (screen, TermName, termcap, newtc);
  1327. X        } else {
  1328. X        fprintf (stderr, "%s:  invalid termcap entry \"%s\".\n",
  1329. X             ProgramName, resource.term_name);
  1330. X        }
  1331. X    }
  1332. X    if (!TermName) {
  1333. X        while (*envnew != NULL) {
  1334. X        if(tgetent(ptr, *envnew) == 1) {
  1335. X            TermName = *envnew;
  1336. X            if(!screen->TekEmu)
  1337. X                resize(screen, TermName, termcap, newtc);
  1338. X            break;
  1339. X        }
  1340. X        envnew++;
  1341. X        }
  1342. X        if (TermName == NULL) {
  1343. X        fprintf (stderr, "%s:  unable to find usable termcap entry.\n",
  1344. X             ProgramName);
  1345. X        Exit (1);
  1346. X        }
  1347. X    }
  1348. X
  1349. #ifdef sun
  1350. #ifdef TIOCSSIZE
  1351. X    /* tell tty how big window is */
  1352. X    if(screen->TekEmu) {
  1353. X        ts.ts_lines = 38;
  1354. X        ts.ts_cols = 81;
  1355. X    } else {
  1356. X        ts.ts_lines = screen->max_row + 1;
  1357. X        ts.ts_cols = screen->max_col + 1;
  1358. X    }
  1359. #endif    /* TIOCSSIZE */
  1360. #else    /* not sun */
  1361. #ifdef TIOCSWINSZ
  1362. X    /* tell tty how big window is */
  1363. X    if(screen->TekEmu) {
  1364. X        ws.ws_row = 38;
  1365. X        ws.ws_col = 81;
  1366. X        ws.ws_xpixel = TFullWidth(screen);
  1367. X        ws.ws_ypixel = TFullHeight(screen);
  1368. X    } else {
  1369. X        ws.ws_row = screen->max_row + 1;
  1370. X        ws.ws_col = screen->max_col + 1;
  1371. X        ws.ws_xpixel = FullWidth(screen);
  1372. X        ws.ws_ypixel = FullHeight(screen);
  1373. X    }
  1374. #endif    /* TIOCSWINSZ */
  1375. #endif    /* sun */
  1376. X
  1377. X    if (!am_slave) {
  1378. #ifdef USE_HANDSHAKE
  1379. X        if (pipe(pc_pipe) || pipe(cp_pipe))
  1380. X        SysError (ERROR_FORK);
  1381. #endif
  1382. X        if ((screen->pid = fork ()) == -1)
  1383. X        SysError (ERROR_FORK);
  1384. X        
  1385. X        if (screen->pid == 0) {
  1386. X        /*
  1387. X         * now in child process
  1388. X         */
  1389. X        extern char **environ;
  1390. X        int pgrp = getpid();
  1391. #ifdef USE_SYSV_TERMIO
  1392. X        char numbuf[12];
  1393. #endif    /* USE_SYSV_TERMIO */
  1394. X
  1395. #ifndef USE_HANDSHAKE
  1396. X        int ptyfd;
  1397. X
  1398. X        setpgrp();
  1399. X        grantpt (screen->respond);
  1400. X        unlockpt (screen->respond);
  1401. X        if ((ptyfd = open (ptsname(screen->respond), O_RDWR)) < 0) {
  1402. X            SysError (1);
  1403. X        }
  1404. X        if (ioctl (ptyfd, I_PUSH, "ptem") < 0) {
  1405. X            SysError (2);
  1406. X        }
  1407. X        if (!getenv("CONSEM") && ioctl (ptyfd, I_PUSH, "consem") < 0) {
  1408. X            SysError (3);
  1409. X        }
  1410. X        if (ioctl (ptyfd, I_PUSH, "ldterm") < 0) {
  1411. X            SysError (4);
  1412. X        }
  1413. X        tty = ptyfd;
  1414. X        close (screen->respond);
  1415. #ifdef TIOCSWINSZ
  1416. X                /* tell tty how big window is */
  1417. X                if(screen->TekEmu) {
  1418. X                        ws.ws_row = 24;
  1419. X                        ws.ws_col = 80;
  1420. X                        ws.ws_xpixel = TFullWidth(screen);
  1421. X                        ws.ws_ypixel = TFullHeight(screen);
  1422. X                } else {
  1423. X                        ws.ws_row = screen->max_row + 1;
  1424. X                        ws.ws_col = screen->max_col + 1;
  1425. X                        ws.ws_xpixel = FullWidth(screen);
  1426. X                        ws.ws_ypixel = FullHeight(screen);
  1427. X                }
  1428. #endif
  1429. X
  1430. X
  1431. #else /* USE_HANDSHAKE:  warning, goes for a long ways */
  1432. X        /* close parent's sides of the pipes */
  1433. X        close (cp_pipe[0]);
  1434. X        close (pc_pipe[1]);
  1435. X
  1436. X        /* Make sure that our sides of the pipes are not in the
  1437. X         * 0, 1, 2 range so that we don't fight with stdin, out
  1438. X         * or err.
  1439. X         */
  1440. X        if (cp_pipe[1] <= 2) {
  1441. X            if ((i = fcntl(cp_pipe[1], F_DUPFD, 3)) >= 0) {
  1442. X                (void) close(cp_pipe[1]);
  1443. X                cp_pipe[1] = i;
  1444. X            }
  1445. X        }
  1446. X        if (pc_pipe[0] <= 2) {
  1447. X            if ((i = fcntl(pc_pipe[0], F_DUPFD, 3)) >= 0) {
  1448. X                (void) close(pc_pipe[0]);
  1449. X                pc_pipe[0] = i;
  1450. X            }
  1451. X        }
  1452. X
  1453. X        /* we don't need the socket, or the pty master anymore */
  1454. X        close (Xsocket);
  1455. X        close (screen->respond);
  1456. X
  1457. X        /* Now is the time to set up our process group and
  1458. X         * open up the pty slave.
  1459. X         */
  1460. #ifdef    USE_SYSV_PGRP
  1461. X        (void) setpgrp();
  1462. #endif    /* USE_SYSV_PGRP */
  1463. X        while (1) {
  1464. #ifdef TIOCNOTTY
  1465. X            if ((tty = open ("/dev/tty", 2)) >= 0) {
  1466. X                ioctl (tty, TIOCNOTTY, (char *) NULL);
  1467. X                close (tty);
  1468. X            }
  1469. #endif    /* TIOCNOTTY */
  1470. X            if ((tty = open(ttydev, O_RDWR, 0)) >= 0) {
  1471. #ifdef    USE_SYSV_PGRP
  1472. X                /* We need to make sure that we are acutally
  1473. X                 * the process group leader for the pty.  If
  1474. X                 * we are, then we should now be able to open
  1475. X                 * /dev/tty.
  1476. X                 */
  1477. X                if ((i = open("/dev/tty", O_RDWR, 0)) >= 0) {
  1478. X                    /* success! */
  1479. X                    close(i);
  1480. X                    break;
  1481. X                }
  1482. #else    /* USE_SYSV_PGRP */
  1483. X                break;
  1484. #endif    /* USE_SYSV_PGRP */
  1485. X            }
  1486. X
  1487. #ifdef TIOCSCTTY
  1488. X            ioctl(tty, TIOCSCTTY, 0);
  1489. #endif
  1490. X            /* let our master know that the open failed */
  1491. X            handshake.status = PTY_BAD;
  1492. X            handshake.error = errno;
  1493. X            strcpy(handshake.buffer, ttydev);
  1494. X            write(cp_pipe[1], (char *) &handshake,
  1495. X                sizeof(handshake));
  1496. X
  1497. X            /* get reply from parent */
  1498. X            i = read(pc_pipe[0], (char *) &handshake,
  1499. X                sizeof(handshake));
  1500. X            if (i <= 0) {
  1501. X                /* parent terminated */
  1502. X                exit(1);
  1503. X            }
  1504. X
  1505. X            if (handshake.status == PTY_NOMORE) {
  1506. X                /* No more ptys, let's shutdown. */
  1507. X                exit(1);
  1508. X            }
  1509. X
  1510. X            /* We have a new pty to try */
  1511. X            free(ttydev);
  1512. X            ttydev = malloc((unsigned)
  1513. X                (strlen(handshake.buffer) + 1));
  1514. X            strcpy(ttydev, handshake.buffer);
  1515. X        }
  1516. X
  1517. X        /* use the same tty name that everyone else will use
  1518. X        ** (from ttyname)
  1519. X        */
  1520. X        if (ptr = ttyname(tty))
  1521. X        {
  1522. X            /* it may be bigger */
  1523. X            ttydev = realloc (ttydev, (unsigned) (strlen(ptr) + 1));
  1524. X            (void) strcpy(ttydev, ptr);
  1525. X        }
  1526. X
  1527. #endif /* !USE_HANDSHAKE else USE_HANDSHAKE - from near fork */
  1528. X
  1529. #ifdef USE_TTY_GROUP
  1530. X    { 
  1531. #include <grp.h>
  1532. X        struct group *ttygrp;
  1533. X        if (ttygrp = getgrnam("tty")) {
  1534. X            /* change ownership of tty to real uid, "tty" gid */
  1535. X            chown (ttydev, screen->uid, ttygrp->gr_gid);
  1536. X            chmod (ttydev, 0620);
  1537. X        }
  1538. X        else {
  1539. X            /* change ownership of tty to real group and user id */
  1540. X            chown (ttydev, screen->uid, screen->gid);
  1541. X            chmod (ttydev, 0622);
  1542. X        }
  1543. X        endgrent();
  1544. X    }
  1545. #else /* else !USE_TTY_GROUP */
  1546. X        /* change ownership of tty to real group and user id */
  1547. X        chown (ttydev, screen->uid, screen->gid);
  1548. X
  1549. X        /* change protection of tty */
  1550. X        chmod (ttydev, 0622);
  1551. #endif /* USE_TTY_GROUP */
  1552. X
  1553. X        /*
  1554. X         * set up the tty modes
  1555. X         */
  1556. X        {
  1557. #ifdef USE_SYSV_TERMIO
  1558. #ifdef umips
  1559. X            /* If the control tty had its modes screwed around with,
  1560. X               eg. by lineedit in the shell, or emacs, etc. then tio
  1561. X               will have bad values.  Let's just get termio from the
  1562. X               new tty and tailor it.  */
  1563. X            if (ioctl (tty, TCGETA, &tio) == -1)
  1564. X              SysError (ERROR_TIOCGETP);
  1565. X            tio.c_lflag |= ECHOE;
  1566. #endif /* umips */
  1567. X            /* Now is also the time to change the modes of the
  1568. X             * child pty.
  1569. X             */
  1570. X            /* input: nl->nl, don't ignore cr, cr->nl */
  1571. X            tio.c_iflag &= ~(INLCR|IGNCR);
  1572. X            tio.c_iflag |= ICRNL;
  1573. X            /* ouput: cr->cr, nl is not return, no delays, ln->cr/nl */
  1574. X            tio.c_oflag &=
  1575. X             ~(OCRNL|ONLRET|NLDLY|CRDLY|TABDLY|BSDLY|VTDLY|FFDLY);
  1576. X            tio.c_oflag |= ONLCR;
  1577. #ifdef BAUD_0
  1578. X            /* baud rate is 0 (don't care) */
  1579. X            tio.c_cflag &= ~(CBAUD);
  1580. #else    /* !BAUD_0 */
  1581. X            /* baud rate is 9600 (nice default) */
  1582. X            tio.c_cflag &= ~(CBAUD);
  1583. X            tio.c_cflag |= B9600;
  1584. #endif    /* !BAUD_0 */
  1585. X            /* enable signals, canonical processing (erase, kill, etc),
  1586. X            ** echo
  1587. X            */
  1588. X            tio.c_lflag |= ISIG|ICANON|ECHO;
  1589. X            /* reset EOL to defalult value */
  1590. X            tio.c_cc[VEOL] = '@' & 0x3f;        /* '^@'    */
  1591. X            /* certain shells (ksh & csh) change EOF as well */
  1592. X            tio.c_cc[VEOF] = 'D' & 0x3f;        /* '^D'    */
  1593. X
  1594. #define TMODE(ind,var) if (ttymodelist[ind].set) var = ttymodelist[ind].value;
  1595. X            if (override_tty_modes) {
  1596. X            /* sysv-specific */
  1597. X            TMODE (XTTYMODE_intr, tio.c_cc[VINTR]);
  1598. X            TMODE (XTTYMODE_quit, tio.c_cc[VQUIT]);
  1599. X            TMODE (XTTYMODE_erase, tio.c_cc[VERASE]);
  1600. X            TMODE (XTTYMODE_kill, tio.c_cc[VKILL]);
  1601. X            TMODE (XTTYMODE_eof, tio.c_cc[VEOF]);
  1602. X            TMODE (XTTYMODE_eol, tio.c_cc[VEOL]);
  1603. #ifdef VSWTCH
  1604. X            TMODE (XTTYMODE_swtch, d_tio.c_cc[VSWTCH]);
  1605. #endif
  1606. #ifdef TIOCSLTC
  1607. X            /* both SYSV and BSD have ltchars */
  1608. X            TMODE (XTTYMODE_susp, ltc.t_suspc);
  1609. X            TMODE (XTTYMODE_dsusp, ltc.t_dsuspc);
  1610. X            TMODE (XTTYMODE_rprnt, ltc.t_rprntc);
  1611. X            TMODE (XTTYMODE_flush, ltc.t_flushc);
  1612. X            TMODE (XTTYMODE_weras, ltc.t_werasc);
  1613. X            TMODE (XTTYMODE_lnext, ltc.t_lnextc);
  1614. #endif
  1615. X            }
  1616. #undef TMODE
  1617. X
  1618. X            if (ioctl (tty, TCSETA, &tio) == -1)
  1619. X                HsSysError(cp_pipe[1], ERROR_TIOCSETP);
  1620. #ifdef TIOCSLTC
  1621. X            if (ioctl (tty, TIOCSLTC, <c) == -1)
  1622. X                HsSysError(cp_pipe[1], ERROR_TIOCSETC);
  1623. #endif    /* TIOCSLTC */
  1624. #ifdef TIOCLSET
  1625. X            if (ioctl (tty, TIOCLSET, (char *)&lmode) == -1)
  1626. X                HsSysError(cp_pipe[1], ERROR_TIOCLSET);
  1627. #endif    /* TIOCLSET */
  1628. #ifdef TIOCCONS
  1629. X            if (Console) {
  1630. X                int on = 1;
  1631. X                if (ioctl (tty, TIOCCONS, (char *)&on) == -1)
  1632. X                    HsSysError(cp_pipe[1], ERROR_TIOCCONS);
  1633. X            }
  1634. #endif    /* TIOCCONS */
  1635. #else    /* USE_SYSV_TERMIO */
  1636. #ifdef KTERM
  1637. X            sg.sg_flags &= ~(ALLDELAY | XTABS | CBREAK | RAW
  1638. X                        | EVENP | ODDP);
  1639. #else /* !KTERM */
  1640. X            sg.sg_flags &= ~(ALLDELAY | XTABS | CBREAK | RAW);
  1641. #endif /* !KTERM */
  1642. X            sg.sg_flags |= ECHO | CRMOD;
  1643. X            /* make sure speed is set on pty so that editors work right*/
  1644. X            sg.sg_ispeed = B9600;
  1645. X            sg.sg_ospeed = B9600;
  1646. X            /* reset t_brkc to default value */
  1647. X            tc.t_brkc = -1;
  1648. X
  1649. #define TMODE(ind,var) if (ttymodelist[ind].set) var = ttymodelist[ind].value;
  1650. X            if (override_tty_modes) {
  1651. X            TMODE (XTTYMODE_intr, tc.t_intrc);
  1652. X            TMODE (XTTYMODE_quit, tc.t_quitc);
  1653. X            TMODE (XTTYMODE_erase, sg.sg_erase);
  1654. X            TMODE (XTTYMODE_kill, sg.sg_kill);
  1655. X            TMODE (XTTYMODE_eof, tc.t_eofc);
  1656. X            TMODE (XTTYMODE_start, tc.t_startc);
  1657. X            TMODE (XTTYMODE_stop, tc.t_stopc);
  1658. X            TMODE (XTTYMODE_brk, tc.t_brkc);
  1659. X            /* both SYSV and BSD have ltchars */
  1660. X            TMODE (XTTYMODE_susp, ltc.t_suspc);
  1661. X            TMODE (XTTYMODE_dsusp, ltc.t_dsuspc);
  1662. X            TMODE (XTTYMODE_rprnt, ltc.t_rprntc);
  1663. X            TMODE (XTTYMODE_flush, ltc.t_flushc);
  1664. X            TMODE (XTTYMODE_weras, ltc.t_werasc);
  1665. X            TMODE (XTTYMODE_lnext, ltc.t_lnextc);
  1666. X            }
  1667. #undef TMODE
  1668. X
  1669. X            if (ioctl (tty, TIOCSETP, (char *)&sg) == -1)
  1670. X                HsSysError (cp_pipe[1], ERROR_TIOCSETP);
  1671. X            if (ioctl (tty, TIOCSETC, (char *)&tc) == -1)
  1672. X                HsSysError (cp_pipe[1], ERROR_TIOCSETC);
  1673. X            if (ioctl (tty, TIOCSETD, (char *)&discipline) == -1)
  1674. X                HsSysError (cp_pipe[1], ERROR_TIOCSETD);
  1675. X            if (ioctl (tty, TIOCSLTC, (char *)<c) == -1)
  1676. X                HsSysError (cp_pipe[1], ERROR_TIOCSLTC);
  1677. X            if (ioctl (tty, TIOCLSET, (char *)&lmode) == -1)
  1678. X                HsSysError (cp_pipe[1], ERROR_TIOCLSET);
  1679. #ifdef TIOCCONS
  1680. X            if (Console) {
  1681. X                int on = 1;
  1682. X                if (ioctl (tty, TIOCCONS, (char *)&on) == -1)
  1683. X                    HsSysError(cp_pipe[1], ERROR_TIOCCONS);
  1684. X            }
  1685. #endif    /* TIOCCONS */
  1686. #endif    /* !USE_SYSV_TERMIO */
  1687. X        }
  1688. X
  1689. X        signal (SIGCHLD, SIG_DFL);
  1690. #ifdef att
  1691. X        /* watch out for extra shells (I don't understand either) */
  1692. X        signal (SIGHUP, SIG_DFL);
  1693. #else
  1694. X        signal (SIGHUP, SIG_IGN);
  1695. #endif
  1696. X        /* restore various signals to their defaults */
  1697. X        signal (SIGINT, SIG_DFL);
  1698. X        signal (SIGQUIT, SIG_DFL);
  1699. X        signal (SIGTERM, SIG_DFL);
  1700. X
  1701. X        /* copy the environment before Setenving */
  1702. X        for (i = 0 ; environ [i] != NULL ; i++) ;
  1703. X        /*
  1704. X         * The `4' (`5' for SYSV) is the number of Setenv()
  1705. X         * calls which may add a new entry to the environment.
  1706. X         * The `1' is for the NULL terminating entry.
  1707. X         */
  1708. #ifdef USE_SYSV_ENVVARS
  1709. X        envnew = (char **) calloc ((unsigned) i + (5 + 1), sizeof(char *));
  1710. #else
  1711. X        envnew = (char **) calloc ((unsigned) i + (4 + 1), sizeof(char *));
  1712. #endif /* USE_SYSV_ENVVARS */
  1713. SHAR_EOF
  1714. true || echo 'restore of kterm-4.1.2/main.c failed'
  1715. fi
  1716. echo 'End of kterm-4.1.2 part 13'
  1717. echo 'File kterm-4.1.2/main.c is continued in part 14'
  1718. echo 14 > _shar_seq_.tmp
  1719. exit 0
  1720.  
  1721.  
  1722. -----------------------------------------------------------------------------
  1723. mleisher@nmsu.edu                      "I laughed.
  1724. Mark Leisher                                I cried.
  1725. Computing Research Lab                          I fell down.
  1726. New Mexico State University                        It changed my life."
  1727. Las Cruces, NM                     - Rich [Cowboy Feng's Space Bar and Grille]
  1728.  
  1729. --
  1730. Dan Heller
  1731. O'Reilly && Associates       Z-Code Software    Comp-sources-x:
  1732. Senior Writer                President          comp-sources.x@uunet.uu.net
  1733. argv@ora.com                 argv@zipcode.com
  1734.