home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / unix / volume26 / screen35 / part05 < prev    next >
Encoding:
Text File  |  1993-07-25  |  98.3 KB  |  3,339 lines

  1. Newsgroups: comp.sources.unix
  2. From: mlschroe@immd4.informatik.uni-erlangen.de (Michael Schroeder)
  3. Subject: v26i304: screen-3.5 - screen manager with VT100/ANSI terminal emulation, V3.5, Part05/10
  4. Sender: unix-sources-moderator@gw.home.vix.com
  5. Approved: vixie@gw.home.vix.com
  6.  
  7. Submitted-By: mlschroe@immd4.informatik.uni-erlangen.de (Michael Schroeder)
  8. Posting-Number: Volume 26, Issue 304
  9. Archive-Name: screen-3.5/part05
  10.  
  11. #! /bin/sh
  12. # This is a shell archive.  Remove anything before this line, then unpack
  13. # it by saving it into a file and typing "sh file".  To overwrite existing
  14. # files, type "sh file -c".  You can also feed this as standard input via
  15. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  16. # will see the following message at the end:
  17. #        "End of archive 5 (of 10)."
  18. # Contents:  display.c socket.c terminfo/test.txt
  19. # Wrapped by vixie@gw.home.vix.com on Sun Jul 25 12:57:19 1993
  20. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  21. if test -f 'display.c' -a "${1}" != "-c" ; then 
  22.   echo shar: Will not clobber existing file \"'display.c'\"
  23. else
  24. echo shar: Extracting \"'display.c'\" \(27002 characters\)
  25. sed "s/^X//" >'display.c' <<'END_OF_FILE'
  26. X/* Copyright (c) 1993
  27. X *      Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
  28. X *      Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
  29. X * Copyright (c) 1987 Oliver Laumann
  30. X *
  31. X * This program is free software; you can redistribute it and/or modify
  32. X * it under the terms of the GNU General Public License as published by
  33. X * the Free Software Foundation; either version 2, or (at your option)
  34. X * any later version.
  35. X *
  36. X * This program is distributed in the hope that it will be useful,
  37. X * but WITHOUT ANY WARRANTY; without even the implied warranty of
  38. X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  39. X * GNU General Public License for more details.
  40. X *
  41. X * You should have received a copy of the GNU General Public License
  42. X * along with this program (see the file COPYING); if not, write to the
  43. X * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  44. X *
  45. X ****************************************************************
  46. X */
  47. X
  48. X#include "rcs.h"
  49. XRCS_ID("$Id: display.c,v 1.8 1993/07/21 15:43:02 mlschroe Exp $ FAU")
  50. X
  51. X
  52. X#include <sys/types.h>
  53. X#include <fcntl.h>
  54. X
  55. X#include "config.h"
  56. X#include "screen.h"
  57. X#include "extern.h"
  58. X
  59. Xstatic void CountChars __P((int));
  60. Xstatic void PutChar __P((int));
  61. Xstatic int  BlankResize __P((int, int));
  62. X
  63. X
  64. Xextern char *tgoto __P((char *, int, int));
  65. X
  66. Xextern struct win *windows;
  67. X
  68. Xextern int  use_hardstatus;
  69. Xextern int  MsgMinWait;
  70. Xextern int  Z0width, Z1width;
  71. Xextern char *blank, *null;
  72. X
  73. X/*
  74. X * tputs needs this to calculate the padding
  75. X */
  76. X#ifndef NEED_OSPEED
  77. Xextern
  78. X#endif /* NEED_OSPEED */
  79. Xshort ospeed;
  80. X
  81. X
  82. Xstruct display *display, *displays;
  83. X
  84. X#ifndef MULTI
  85. Xstruct display TheDisplay;
  86. X#endif
  87. X
  88. X
  89. X/*
  90. X *  The default values
  91. X */
  92. Xint defobuflimit = OBUF_MAX;
  93. X#ifdef AUTO_NUKE
  94. Xint defautonuke = 0;
  95. X#endif
  96. X
  97. X/*
  98. X *  Default layer management
  99. X */
  100. X
  101. Xvoid
  102. XDefProcess(bufp, lenp)
  103. Xchar **bufp;
  104. Xint *lenp;
  105. X{
  106. X  *bufp += *lenp;
  107. X  *lenp = 0;
  108. X}
  109. X
  110. Xvoid
  111. XDefRedisplayLine(y, xs, xe, isblank)
  112. Xint y, xs, xe, isblank;
  113. X{
  114. X  if (isblank == 0 && y >= 0)
  115. X    DefClearLine(y, xs, xe);
  116. X}
  117. X
  118. Xvoid
  119. XDefClearLine(y, xs, xe)
  120. Xint y, xs, xe;
  121. X{
  122. X  DisplayLine(null, null, null, blank, null, null, y, xs, xe);
  123. X}
  124. X
  125. X/*ARGSUSED*/
  126. Xint
  127. XDefRewrite(y, xs, xe, doit)
  128. Xint y, xs, xe, doit;
  129. X{
  130. X  return EXPENSIVE;
  131. X}
  132. X
  133. Xvoid
  134. XDefSetCursor()
  135. X{
  136. X  GotoPos(0, 0);
  137. X}
  138. X
  139. X/*ARGSUSED*/
  140. Xint
  141. XDefResize(wi, he)
  142. Xint wi, he;
  143. X{
  144. X  return -1;
  145. X}
  146. X
  147. Xvoid
  148. XDefRestore()
  149. X{
  150. X  InsertMode(0);
  151. X  ChangeScrollRegion(0, d_height - 1);
  152. X  KeypadMode(0);
  153. X  CursorkeysMode(0);
  154. X  SetAttrFont(0, ASCII);
  155. X  SetFlow(FLOW_NOW);
  156. X}
  157. X
  158. X/*
  159. X *  Blank layer management
  160. X */
  161. X
  162. Xstruct LayFuncs BlankLf =
  163. X{
  164. X  DefProcess,
  165. X  0,
  166. X  DefRedisplayLine,
  167. X  DefClearLine,
  168. X  DefRewrite,
  169. X  DefSetCursor,
  170. X  BlankResize,
  171. X  DefRestore
  172. X};
  173. X
  174. Xstruct layer BlankLayer =
  175. X{
  176. X  0,
  177. X  0,
  178. X  &BlankLf,
  179. X  0
  180. X};
  181. X
  182. X/*ARGSUSED*/
  183. Xstatic int
  184. XBlankResize(wi, he)
  185. Xint wi, he;
  186. X{
  187. X  return 0;
  188. X}
  189. X
  190. X
  191. X/*
  192. X *  Generate new display
  193. X */
  194. X
  195. Xstruct display *
  196. XMakeDisplay(uname, utty, term, fd, pid, Mode)
  197. Xchar *uname, *utty, *term;
  198. Xint fd, pid;
  199. Xstruct mode *Mode;
  200. X{
  201. X  struct user **u;
  202. X
  203. X#ifdef MULTI
  204. X  if ((display = (struct display *)malloc(sizeof(*display))) == 0)
  205. X    return 0;
  206. X  bzero((char *) display, sizeof(*display));
  207. X#else
  208. X  if (displays)
  209. X    return 0;
  210. X  display = &TheDisplay;
  211. X#endif
  212. X  display->_d_next = displays;
  213. X  displays = display;
  214. X  d_flow = 1;
  215. X  d_userfd = fd;
  216. X  d_OldMode = *Mode;
  217. X  Resize_obuf();  /* Allocate memory for buffer */
  218. X  d_obufmax = defobuflimit;
  219. X#ifdef AUTO_NUKE
  220. X  d_auto_nuke = defautonuke;
  221. X#endif
  222. X  d_obufp = d_obuf;
  223. X  d_userpid = pid;
  224. X#ifdef POSIX
  225. X  d_dospeed = (short) cfgetospeed(&d_OldMode.tio);
  226. X#else
  227. X# ifndef TERMIO
  228. X  d_dospeed = (short) d_OldMode.m_ttyb.sg_ospeed;
  229. X# endif
  230. X#endif
  231. X  debug1("New displays ospeed = %d\n", d_dospeed);
  232. X  strcpy(d_usertty, utty);
  233. X  strcpy(d_termname, term);
  234. X
  235. X  if (!*(u = FindUserPtr(uname)) && UserAdd(uname, NULL, u))
  236. X    {
  237. X      FreeDisplay();
  238. X      return NULL;    /* could not find or add user */
  239. X    }
  240. X  d_user = *u;
  241. X  d_lay = &BlankLayer;
  242. X  d_layfn = BlankLayer.l_layfn;
  243. X  return display;
  244. X}
  245. X
  246. Xvoid
  247. XFreeDisplay()
  248. X{
  249. X#ifdef MULTI
  250. X  struct display *d, **dp;
  251. X
  252. X  for (dp = &displays; (d = *dp) ; dp = &d->_d_next)
  253. X    if (d == display)
  254. X      break;
  255. X  ASSERT(d);
  256. X  if (d_status_lastmsg)
  257. X    free(d_status_lastmsg);
  258. X# ifdef COPY_PASTE
  259. X  if (d_copybuffer)
  260. X    free(d_copybuffer);
  261. X# endif
  262. X  if (d_obuf)
  263. X    free(d_obuf);
  264. X  *dp = display->_d_next;
  265. X  free(display);
  266. X#else /* MULTI */
  267. X  ASSERT(display == displays);
  268. X  ASSERT(display == &TheDisplay);
  269. X  displays = 0;
  270. X#endif /* MULTI */
  271. X  display = 0;
  272. X}
  273. X
  274. X/*
  275. X * if the adaptflag is on, we keep the size of this display, else
  276. X * we may try to restore our old window sizes.
  277. X */
  278. Xvoid
  279. XInitTerm(adapt)
  280. Xint adapt;
  281. X{
  282. X  ASSERT(display);
  283. X  d_top = d_bot = -1;
  284. X  PutStr(TI);
  285. X  PutStr(IS);
  286. X  /* Check for toggle */
  287. X  if (IM && strcmp(IM, EI))
  288. X    PutStr(EI);
  289. X  d_insert = 0;
  290. X  /* Check for toggle */
  291. X  if (KS && strcmp(KS, KE))
  292. X    PutStr(KE);
  293. X  d_keypad = 0;
  294. X  if (CCS && strcmp(CCS, CCE))
  295. X    PutStr(CCE);
  296. X  d_cursorkeys = 0;
  297. X  PutStr(CE0);
  298. X  d_font = ASCII;
  299. X  if (adapt == 0)
  300. X    ResizeDisplay(d_defwidth, d_defheight);
  301. X  ChangeScrollRegion(0, d_height - 1);
  302. X  d_x = d_y = 0;
  303. X  Flush();
  304. X  ClearDisplay();
  305. X  debug1("we %swant to adapt all our windows to the display\n", 
  306. X     (adapt) ? "" : "don't ");
  307. X  /* In case the size was changed by a init sequence */
  308. X  CheckScreenSize((adapt) ? 2 : 0);
  309. X}
  310. X
  311. Xvoid
  312. XFinitTerm()
  313. X{
  314. X  ASSERT(display);
  315. X  ResizeDisplay(d_defwidth, d_defheight);
  316. X  DefRestore();
  317. X  SetAttrFont(0, ASCII);
  318. X  d_x = d_y = -1;
  319. X  GotoPos(0, d_height - 1);
  320. X  AddChar('\n');
  321. X  PutStr(TE);
  322. X  Flush();
  323. X}
  324. X
  325. X
  326. Xvoid
  327. XINSERTCHAR(c)
  328. Xint c;
  329. X{
  330. X  ASSERT(display);
  331. X  if (!d_insert && d_x < d_width - 1)
  332. X    {
  333. X      if (IC || CIC)
  334. X    {
  335. X      if (IC)
  336. X        PutStr(IC);
  337. X      else
  338. X        CPutStr(CIC, 1);
  339. X      RAW_PUTCHAR(c);
  340. X      return;
  341. X    }
  342. X      InsertMode(1);
  343. X      if (!d_insert)
  344. X    {
  345. X          RefreshLine(d_y, d_x, d_width-1, 0);
  346. X      return;
  347. X    }
  348. X    }
  349. X  RAW_PUTCHAR(c);
  350. X}
  351. X
  352. Xvoid
  353. XPUTCHAR(c)
  354. Xint c;
  355. X{
  356. X  ASSERT(display);
  357. X  if (d_insert && d_x < d_width - 1)
  358. X    InsertMode(0);
  359. X  RAW_PUTCHAR(c);
  360. X}
  361. X
  362. Xvoid
  363. XPUTCHARLP(c)
  364. Xint c;
  365. X{
  366. X  if (d_x < d_width - 1)
  367. X    {
  368. X      if (d_insert)
  369. X    InsertMode(0);
  370. X      RAW_PUTCHAR(c);
  371. X      return;
  372. X    }
  373. X  if (CLP || d_y != d_bot)
  374. X    {
  375. X      RAW_PUTCHAR(c);
  376. X      return;
  377. X    }
  378. X  d_lp_missing = 1;
  379. X  d_lp_image = c;
  380. X  d_lp_attr = d_attr;
  381. X  d_lp_font = d_font;
  382. X}
  383. X
  384. X/*
  385. X * RAW_PUTCHAR() is for all text that will be displayed.
  386. X * NOTE: charset Nr. 0 has a conversion table, but c1, c2, ... don't.
  387. X */
  388. X
  389. Xvoid
  390. XRAW_PUTCHAR(c)
  391. Xint c;
  392. X{
  393. X  ASSERT(display);
  394. X  if (d_font == '0')
  395. X    {
  396. X      AddChar(d_c0_tab[c]);
  397. X    }
  398. X  else
  399. X    AddChar(c);
  400. X  if (++d_x >= d_width)
  401. X    {
  402. X      if ((AM && !CLP) || d_x > d_width)
  403. X    {
  404. X      d_x -= d_width;
  405. X      if (d_y < d_height-1 && d_y != d_bot)
  406. X        d_y++;
  407. X    }
  408. X    }
  409. X}
  410. X
  411. Xstatic void
  412. XPutChar(c)
  413. Xint c;
  414. X{
  415. X  /* this PutChar for ESC-sequences only (AddChar is a macro) */
  416. X  AddChar(c);
  417. X}
  418. X
  419. Xvoid
  420. XPutStr(s)
  421. Xchar *s;
  422. X{
  423. X  if (display && s)
  424. X    {
  425. X      ospeed = d_dospeed;
  426. X      tputs(s, 1, PutChar);
  427. X    }
  428. X}
  429. X
  430. Xvoid
  431. XCPutStr(s, c)
  432. Xchar *s;
  433. Xint c;
  434. X{
  435. X  if (display && s)
  436. X    {
  437. X      ospeed = d_dospeed;
  438. X      tputs(tgoto(s, 0, c), 1, PutChar);
  439. X    }
  440. X}
  441. X
  442. X
  443. X/* Insert mode is a toggle on some terminals, so we need this hack:
  444. X */
  445. Xvoid
  446. XInsertMode(on)
  447. Xint on;
  448. X{
  449. X  if (display && on != d_insert && IM)
  450. X    {
  451. X      d_insert = on;
  452. X      if (d_insert)
  453. X    PutStr(IM);
  454. X      else
  455. X    PutStr(EI);
  456. X    }
  457. X}
  458. X
  459. X/* ...and maybe d_keypad application mode is a toggle, too:
  460. X */
  461. Xvoid
  462. XKeypadMode(on)
  463. Xint on;
  464. X{
  465. X  if (display && d_keypad != on && KS)
  466. X    {
  467. X      d_keypad = on;
  468. X      if (d_keypad)
  469. X    PutStr(KS);
  470. X      else
  471. X    PutStr(KE);
  472. X    }
  473. X}
  474. X
  475. Xvoid
  476. XCursorkeysMode(on)
  477. Xint on;
  478. X{
  479. X  if (display && d_cursorkeys != on && CCS)
  480. X    {
  481. X      d_cursorkeys = on;
  482. X      if (d_cursorkeys)
  483. X    PutStr(CCS);
  484. X      else
  485. X    PutStr(CCE);
  486. X    }
  487. X}
  488. X
  489. Xstatic int StrCost;
  490. X
  491. X/* ARGSUSED */
  492. Xstatic void
  493. XCountChars(c)
  494. Xint c;
  495. X{
  496. X  StrCost++;
  497. X}
  498. X
  499. Xint
  500. XCalcCost(s)
  501. Xregister char *s;
  502. X{
  503. X  ASSERT(display);
  504. X  if (s)
  505. X    {
  506. X      StrCost = 0;
  507. X      ospeed = d_dospeed;
  508. X      tputs(s, 1, CountChars);
  509. X      return StrCost;
  510. X    }
  511. X  else
  512. X    return EXPENSIVE;
  513. X}
  514. X
  515. Xvoid
  516. XGotoPos(x2, y2)
  517. Xint x2, y2;
  518. X{
  519. X  register int dy, dx, x1, y1;
  520. X  register int costx, costy;
  521. X  register int m;
  522. X  register char *s;
  523. X  int CMcost;
  524. X  enum move_t xm = M_NONE, ym = M_NONE;
  525. X
  526. X  if (!display)
  527. X    return;
  528. X
  529. X  x1 = d_x;
  530. X  y1 = d_y;
  531. X
  532. X  if (x1 == d_width)
  533. X    if (CLP && AM)
  534. X      x1 = -1;        /* don't know how the terminal treats this */
  535. X    else
  536. X      x1--;
  537. X  if (x2 == d_width)
  538. X    x2--;
  539. X  dx = x2 - x1;
  540. X  dy = y2 - y1;
  541. X  if (dy == 0 && dx == 0)
  542. X    {
  543. X      return;
  544. X    }
  545. X  if (!MS && d_attr)    /* Safe to move in SO mode ? */
  546. X    SetAttr(0);
  547. X  if (y1 < 0            /* don't know the y position */
  548. X      || (y2 > d_bot && y1 <= d_bot)    /* have to cross border */
  549. X      || (y2 < d_top && y1 >= d_top))    /* of scrollregion ?    */
  550. X    {
  551. X    DoCM:
  552. X      if (HO && !x2 && !y2)
  553. X        PutStr(HO);
  554. X      else
  555. X        PutStr(tgoto(CM, x2, y2));
  556. X      d_x = x2;
  557. X      d_y = y2;
  558. X      return;
  559. X    }
  560. X  /* Calculate CMcost */
  561. X  if (HO && !x2 && !y2)
  562. X    s = HO;
  563. X  else
  564. X    s = tgoto(CM, x2, y2);
  565. X  CMcost = CalcCost(s);
  566. X
  567. X  /* Calculate the cost to move the cursor to the right x position */
  568. X  costx = EXPENSIVE;
  569. X  if (x1 >= 0)    /* relativ x positioning only if we know where we are */
  570. X    {
  571. X      if (dx > 0)
  572. X    {
  573. X      if (CRI && (dx > 1 || !ND))
  574. X        {
  575. X          costx = CalcCost(tgoto(CRI, 0, dx));
  576. X          xm = M_CRI;
  577. X        }
  578. X      if ((m = d_NDcost * dx) < costx)
  579. X        {
  580. X          costx = m;
  581. X          xm = M_RI;
  582. X        }
  583. X      /* Speedup: dx <= Rewrite() */
  584. X      if (dx < costx && (m = Rewrite(y1, x1, x2, 0)) < costx)
  585. X        {
  586. X          costx = m;
  587. X          xm = M_RW;
  588. X        }
  589. X    }
  590. X      else if (dx < 0)
  591. X    {
  592. X      if (CLE && (dx < -1 || !BC))
  593. X        {
  594. X          costx = CalcCost(tgoto(CLE, 0, -dx));
  595. X          xm = M_CLE;
  596. X        }
  597. X      if ((m = -dx * d_LEcost) < costx)
  598. X        {
  599. X          costx = m;
  600. X          xm = M_LE;
  601. X        }
  602. X    }
  603. X      else
  604. X    costx = 0;
  605. X    }
  606. X  /* Speedup: Rewrite() >= x2 */
  607. X  if (x2 + d_CRcost < costx && (m = (x2 ? Rewrite(y1, 0, x2, 0) : 0) + d_CRcost) < costx)
  608. X    {
  609. X      costx = m;
  610. X      xm = M_CR;
  611. X    }
  612. X
  613. X  /* Check if it is already cheaper to do CM */
  614. X  if (costx >= CMcost)
  615. X    goto DoCM;
  616. X
  617. X  /* Calculate the cost to move the cursor to the right y position */
  618. X  costy = EXPENSIVE;
  619. X  if (dy > 0)
  620. X    {
  621. X      if (CDO && dy > 1)    /* DO & NL are always != 0 */
  622. X    {
  623. X      costy = CalcCost(tgoto(CDO, 0, dy));
  624. X      ym = M_CDO;
  625. X    }
  626. X      if ((m = dy * ((x2 == 0) ? d_NLcost : d_DOcost)) < costy)
  627. X    {
  628. X      costy = m;
  629. X      ym = M_DO;
  630. X    }
  631. X    }
  632. X  else if (dy < 0)
  633. X    {
  634. X      if (CUP && (dy < -1 || !UP))
  635. X    {
  636. X      costy = CalcCost(tgoto(CUP, 0, -dy));
  637. X      ym = M_CUP;
  638. X    }
  639. X      if ((m = -dy * d_UPcost) < costy)
  640. X    {
  641. X      costy = m;
  642. X      ym = M_UP;
  643. X    }
  644. X    }
  645. X  else
  646. X    costy = 0;
  647. X
  648. X  /* Finally check if it is cheaper to do CM */
  649. X  if (costx + costy >= CMcost)
  650. X    goto DoCM;
  651. X
  652. X  switch (xm)
  653. X    {
  654. X    case M_LE:
  655. X      while (dx++ < 0)
  656. X    PutStr(BC);
  657. X      break;
  658. X    case M_CLE:
  659. X      CPutStr(CLE, -dx);
  660. X      break;
  661. X    case M_RI:
  662. X      while (dx-- > 0)
  663. X    PutStr(ND);
  664. X      break;
  665. X    case M_CRI:
  666. X      CPutStr(CRI, dx);
  667. X      break;
  668. X    case M_CR:
  669. X      PutStr(CR);
  670. X      d_x = 0;
  671. X      x1 = 0;
  672. X      /* FALLTHROUGH */
  673. X    case M_RW:
  674. X      if (x1 < x2)
  675. X    (void) Rewrite(y1, x1, x2, 1);
  676. X      break;
  677. X    default:
  678. X      break;
  679. X    }
  680. X
  681. X  switch (ym)
  682. X    {
  683. X    case M_UP:
  684. X      while (dy++ < 0)
  685. X    PutStr(UP);
  686. X      break;
  687. X    case M_CUP:
  688. X      CPutStr(CUP, -dy);
  689. X      break;
  690. X    case M_DO:
  691. X      s =  (x2 == 0) ? NL : DO;
  692. X      while (dy-- > 0)
  693. X    PutStr(s);
  694. X      break;
  695. X    case M_CDO:
  696. X      CPutStr(CDO, dy);
  697. X      break;
  698. X    default:
  699. X      break;
  700. X    }
  701. X  d_x = x2;
  702. X  d_y = y2;
  703. X}
  704. X
  705. Xvoid
  706. XClearDisplay()
  707. X{
  708. X  ASSERT(display);
  709. X  Clear(0, 0, d_width - 1, d_height - 1);
  710. X}
  711. X
  712. Xvoid
  713. XClear(xs, ys, xe, ye)
  714. Xint xs, ys, xe, ye;
  715. X{
  716. X  int y, xxe;
  717. X
  718. X  ASSERT(display);
  719. X  if (xs == d_width)
  720. X    xs--;
  721. X  if (xe == d_width)
  722. X    xe--;
  723. X  if (d_lp_missing && ys <= d_bot)
  724. X    {
  725. X      if (ye > d_bot || (ye == d_bot && xe == d_width - 1))
  726. X    d_lp_missing = 0;
  727. X    }
  728. X  if (xe == d_width - 1 && ye == d_height - 1)
  729. X    {
  730. X#ifdef AUTO_NUKE
  731. X      if (xs == 0 && ys == 0 && d_auto_nuke)
  732. X    NukePending();
  733. X#endif
  734. X      if (xs == 0 && ys == 0 && CL)
  735. X    {
  736. X      PutStr(CL);
  737. X      d_y = d_x = 0;
  738. X      return;
  739. X    }
  740. X      /* 
  741. X       * Workaround a hp700/22 terminal bug. Do not use CD where CE
  742. X       * is also appropriate.
  743. X       */
  744. X      if (CD && (ys < ye || !CE))
  745. X    {
  746. X      GotoPos(xs, ys);
  747. X      PutStr(CD);
  748. X      return;
  749. X    }
  750. X    }
  751. X  xxe = d_width - 1;
  752. X  for (y = ys; y <= ye; y++, xs = 0)
  753. X    {
  754. X      if (y == ye)
  755. X    xxe = xe;
  756. X      if (xs == 0 && CB && (xxe != d_width - 1 || (d_x == xxe && d_y == y)))
  757. X    {
  758. X      GotoPos(xxe, y);
  759. X      PutStr(CB);
  760. X      continue;
  761. X    }
  762. X      if (xxe == d_width - 1 && CE)
  763. X    {
  764. X      GotoPos(xs, y);
  765. X      PutStr(CE);
  766. X      continue;
  767. X    }
  768. X      ClearLine(y, xs, xxe);
  769. X    }
  770. X}
  771. X
  772. X
  773. X/*
  774. X * if cur_only > 0, we only redisplay current line, as a full refresh is
  775. X * too expensive over a low baud line.
  776. X */
  777. Xvoid
  778. XRedisplay(cur_only)
  779. Xint cur_only;
  780. X{
  781. X  register int i, stop;
  782. X
  783. X  ASSERT(display);
  784. X  DefRestore();
  785. X  ClearDisplay();
  786. X  stop = d_height;
  787. X  i = 0;
  788. X  if (cur_only > 0 && d_fore)
  789. X    {
  790. X      i = stop = d_fore->w_y;
  791. X      stop++;
  792. X    }
  793. X  else RedisplayLine(-1, 0, d_width - 1, 1);
  794. X  for (; i < stop; i++)
  795. X    RedisplayLine(i, 0, d_width - 1, 1);
  796. X  Restore();
  797. X  SetCursor();
  798. X}
  799. X
  800. X
  801. Xvoid
  802. XScrollRegion(ys, ye, n)
  803. Xint ys, ye, n;
  804. X{
  805. X  int i;
  806. X  int up;
  807. X  int oldtop, oldbot;
  808. X  int alok, dlok, aldlfaster;
  809. X  int missy = 0;
  810. X
  811. X  ASSERT(display);
  812. X  if (n == 0)
  813. X    return;
  814. X  if (ys == 0 && ye == d_height - 1 && 
  815. X      (n >= d_height || -n >= d_height))
  816. X    {
  817. X      ClearDisplay();
  818. X      return;
  819. X    }
  820. X
  821. X  if (d_lp_missing)
  822. X    {
  823. X      if (d_bot > ye || d_bot < ys)
  824. X    missy = d_bot;
  825. X      else
  826. X    {
  827. X      missy = d_bot - n;
  828. X          if (missy>ye || missy<ys)
  829. X        d_lp_missing = 0;
  830. X    }
  831. X    }
  832. X
  833. X  up = 1;
  834. X  if (n < 0)
  835. X    {
  836. X      up = 0;
  837. X      n = -n;
  838. X    }
  839. X  if (n >= ye-ys+1)
  840. X    n = ye-ys+1;
  841. X
  842. X  oldtop = d_top;
  843. X  oldbot = d_bot;
  844. X  if (d_bot != ye)
  845. X    ChangeScrollRegion(ys, ye);
  846. X  alok = (AL || CAL || (ye == d_bot &&  up));
  847. X  dlok = (DL || CDL || (ye == d_bot && !up));
  848. X  if (d_top != ys && !(alok && dlok))
  849. X    ChangeScrollRegion(ys, ye);
  850. X
  851. X  if (d_lp_missing && 
  852. X      (oldbot != d_bot ||
  853. X       (oldbot == d_bot && up && d_top == ys && d_bot == ye)))
  854. X    {
  855. X      FixLP(d_width - 1, oldbot);
  856. X      if (oldbot == d_bot)        /* have scrolled */
  857. X    {
  858. X      if (--n == 0)
  859. X        {
  860. X          ChangeScrollRegion(oldtop, oldbot);
  861. X          return;
  862. X        }
  863. X    }
  864. X    }
  865. X
  866. X  aldlfaster = (n > 1 && ye == d_bot && ((up && CDL) || (!up && CAL)));
  867. X
  868. X  if ((up || SR) && d_top == ys && d_bot == ye && !aldlfaster)
  869. X    {
  870. X      if (up)
  871. X    {
  872. X      GotoPos(0, ye);
  873. X      while (n-- > 0)
  874. X        PutStr(NL);        /* was SF, I think NL is faster */
  875. X    }
  876. X      else
  877. X    {
  878. X      GotoPos(0, ys);
  879. X      while (n-- > 0)
  880. X        PutStr(SR);
  881. X    }
  882. X    }
  883. X  else if (alok && dlok)
  884. X    {
  885. X      if (up || ye != d_bot)
  886. X    {
  887. X          GotoPos(0, up ? ys : ye+1-n);
  888. X          if (CDL && !(n == 1 && DL))
  889. X        CPutStr(CDL, n);
  890. X      else
  891. X        for(i = n; i--; )
  892. X          PutStr(DL);
  893. X    }
  894. X      if (!up || ye != d_bot)
  895. X    {
  896. X          GotoPos(0, up ? ye+1-n : ys);
  897. X          if (CAL && !(n == 1 && AL))
  898. X        CPutStr(CAL, n);
  899. X      else
  900. X        for(i = n; i--; )
  901. X          PutStr(AL);
  902. X    }
  903. X    }
  904. X  else
  905. X    {
  906. X      Redisplay(0);
  907. X      return;
  908. X    }
  909. X  if (d_lp_missing && missy != d_bot)
  910. X    FixLP(d_width - 1, missy);
  911. X  ChangeScrollRegion(oldtop, oldbot);
  912. X  if (d_lp_missing && missy != d_bot)
  913. X    FixLP(d_width - 1, missy);
  914. X}
  915. X
  916. Xvoid
  917. XSetAttr(new)
  918. Xregister int new;
  919. X{
  920. X  register int i, old;
  921. X
  922. X  if (!display || (old = d_attr) == new)
  923. X    return;
  924. X  d_attr = new;
  925. X  for (i = 1; i <= A_MAX; i <<= 1)
  926. X    {
  927. X      if ((old & i) && !(new & i))
  928. X    {
  929. X      PutStr(UE);
  930. X      PutStr(SE);
  931. X      PutStr(ME);
  932. X      if (new & A_DI)
  933. X        PutStr(d_attrtab[ATTR_DI]);
  934. X      if (new & A_US)
  935. X        PutStr(d_attrtab[ATTR_US]);
  936. X      if (new & A_BD)
  937. X        PutStr(d_attrtab[ATTR_BD]);
  938. X      if (new & A_RV)
  939. X        PutStr(d_attrtab[ATTR_RV]);
  940. X      if (new & A_SO)
  941. X        PutStr(d_attrtab[ATTR_SO]);
  942. X      if (new & A_BL)
  943. X        PutStr(d_attrtab[ATTR_BL]);
  944. X      return;
  945. X    }
  946. X    }
  947. X  if ((new & A_DI) && !(old & A_DI))
  948. X    PutStr(d_attrtab[ATTR_DI]);
  949. X  if ((new & A_US) && !(old & A_US))
  950. X    PutStr(d_attrtab[ATTR_US]);
  951. X  if ((new & A_BD) && !(old & A_BD))
  952. X    PutStr(d_attrtab[ATTR_BD]);
  953. X  if ((new & A_RV) && !(old & A_RV))
  954. X    PutStr(d_attrtab[ATTR_RV]);
  955. X  if ((new & A_SO) && !(old & A_SO))
  956. X    PutStr(d_attrtab[ATTR_SO]);
  957. X  if ((new & A_BL) && !(old & A_BL))
  958. X    PutStr(d_attrtab[ATTR_BL]);
  959. X}
  960. X
  961. Xvoid
  962. XSetFont(new)
  963. Xint new;
  964. X{
  965. X  if (!display || d_font == new)
  966. X    return;
  967. X  d_font = new;
  968. X  if (new == ASCII)
  969. X    PutStr(CE0);
  970. X  else
  971. X    CPutStr(CS0, new);
  972. X}
  973. X
  974. Xvoid
  975. XSetAttrFont(newattr, newcharset)
  976. Xint newattr, newcharset;
  977. X{
  978. X  SetAttr(newattr);
  979. X  SetFont(newcharset);
  980. X}
  981. X
  982. Xvoid
  983. XMakeStatus(msg)
  984. Xchar *msg;
  985. X{
  986. X  register char *s, *t;
  987. X  register int max, ti;
  988. X
  989. X  if (!display)
  990. X    return;
  991. X  
  992. X  if (!d_tcinited)
  993. X    {
  994. X      debug("tc not inited, just writing msg\n");
  995. X      AddStr(msg);
  996. X      AddStr("\r\n");
  997. X      Flush();
  998. X      return;
  999. X    }
  1000. X  if (!use_hardstatus || !HS)
  1001. X    {
  1002. X      max = d_width;
  1003. X      if (CLP == 0)
  1004. X    max--;
  1005. X    }
  1006. X  else
  1007. X    max = WS;
  1008. X  if (d_status)
  1009. X    {
  1010. X      if (!d_status_bell)
  1011. X    {
  1012. X      ti = time((time_t *) 0) - d_status_time;
  1013. X      if (ti < MsgMinWait)
  1014. X        sleep(MsgMinWait - ti);
  1015. X    }
  1016. X      RemoveStatus();
  1017. X    }
  1018. X  for (s = t = msg; *s && t - msg < max; ++s)
  1019. X    if (*s == BELL)
  1020. X      PutStr(BL);
  1021. X    else if ((unsigned char)*s >= ' ' && *s != 0177)
  1022. X      *t++ = *s;
  1023. X  *t = '\0';
  1024. X  if (t > msg)
  1025. X    {
  1026. X      if (t - msg >= d_status_buflen)
  1027. X        {
  1028. X          char *buf;
  1029. X          if (d_status_lastmsg)
  1030. X        buf = realloc(d_status_lastmsg, t - msg + 1);
  1031. X      else
  1032. X        buf = malloc(t - msg + 1);
  1033. X      if (buf)
  1034. X        {
  1035. X              d_status_lastmsg = buf;
  1036. X              d_status_buflen = t - msg + 1;
  1037. X            }
  1038. X        }
  1039. X      if (t - msg < d_status_buflen)
  1040. X        strcpy(d_status_lastmsg, msg);
  1041. X      d_status = 1;
  1042. X      d_status_len = t - msg;
  1043. X      d_status_lastx = d_x;
  1044. X      d_status_lasty = d_y;
  1045. X      if (!use_hardstatus || !HS)
  1046. X    {
  1047. X      debug1("using STATLINE %d\n", STATLINE);
  1048. X      GotoPos(0, STATLINE);
  1049. X          SetAttrFont(A_SO, ASCII);
  1050. X      InsertMode(0);
  1051. X      AddStr(msg);
  1052. X          d_x = -1;
  1053. X    }
  1054. X      else
  1055. X    {
  1056. X      debug("using HS\n");
  1057. X          SetAttrFont(0, ASCII);
  1058. X      InsertMode(0);
  1059. X      CPutStr(TS, 0);
  1060. X      AddStr(msg);
  1061. X      PutStr(FS);
  1062. X    }
  1063. X      Flush();
  1064. X      (void) time(&d_status_time);
  1065. X    }
  1066. X}
  1067. X
  1068. Xvoid
  1069. XRemoveStatus()
  1070. X{
  1071. X  struct win *p;
  1072. X
  1073. X  if (!display)
  1074. X    return;
  1075. X  if (!d_status)
  1076. X    return;
  1077. X  
  1078. X  /*
  1079. X   * UGLY HACK ALERT - this should NOT be in display.c
  1080. X   * We need to find the window that caused an activity or bell
  1081. X   * message, to reenable this function there.
  1082. X   */
  1083. X  for (p = windows; p; p = p->w_next)
  1084. X    { 
  1085. X      if (p->w_display != display)
  1086. X    continue;
  1087. X      if (p->w_monitor == MON_MSG)
  1088. X    {
  1089. X      debug1("RemoveStatus clearing monitor win %d\n", p->w_number);
  1090. X      p->w_monitor = MON_DONE;
  1091. X    }
  1092. X      if (p->w_bell == BELL_MSG)
  1093. X    {
  1094. X      debug1("RemoveStatus clearing bell win %d\n", p->w_number);
  1095. X      p->w_bell = BELL_DONE;
  1096. X    }
  1097. X    }
  1098. X  d_status = 0;
  1099. X  d_status_bell = 0;
  1100. X  if (!use_hardstatus || !HS)
  1101. X    {
  1102. X      GotoPos(0, STATLINE);
  1103. X      RefreshLine(STATLINE, 0, d_status_len - 1, 0);
  1104. X      GotoPos(d_status_lastx, d_status_lasty);
  1105. X    }
  1106. X  else
  1107. X    {
  1108. X      SetAttrFont(0, ASCII);
  1109. X      PutStr(DS);
  1110. X    }
  1111. X  SetCursor();
  1112. X}
  1113. X
  1114. Xvoid
  1115. XRefreshLine(y, from, to, isblank)
  1116. Xint y, from, to, isblank;
  1117. X{
  1118. X  ASSERT(display);
  1119. X  debug2("RefreshLine %d %d", y, from);
  1120. X  debug2(" %d %d\n", to, isblank);
  1121. X  if (isblank == 0 && CE && to == d_width - 1)
  1122. X    {
  1123. X      GotoPos(from, y);
  1124. X      PutStr(CE);
  1125. X      isblank = 1;
  1126. X    }
  1127. X  RedisplayLine(y, from, to, isblank);
  1128. X}
  1129. X
  1130. Xvoid
  1131. XFixLP(x2, y2)
  1132. Xregister int x2, y2;
  1133. X{
  1134. X  int oldattr = d_attr, oldfont = d_font;
  1135. X
  1136. X  ASSERT(display);
  1137. X  GotoPos(x2, y2);
  1138. X  SetAttrFont(d_lp_attr, d_lp_font);
  1139. X  PUTCHAR(d_lp_image);
  1140. X  d_lp_missing = 0;
  1141. X  SetAttrFont(oldattr, oldfont);
  1142. X}
  1143. X
  1144. Xvoid
  1145. XDisplayLine(os, oa, of, s, as, fs, y, from, to)
  1146. Xint from, to, y;
  1147. Xregister char *os, *oa, *of, *s, *as, *fs;
  1148. X{
  1149. X  register int x;
  1150. X  int last2flag = 0, delete_lp = 0;
  1151. X
  1152. X  ASSERT(display);
  1153. X  ASSERT(y >= 0 && y < d_height);
  1154. X  ASSERT(from >= 0 && from < d_width);
  1155. X  ASSERT(to >= 0 && to < d_width);
  1156. X  if (!CLP && y == d_bot && to == d_width - 1)
  1157. X    if (d_lp_missing
  1158. X    || s[to] != os[to] || as[to] != oa[to] || of[to] != fs[to])
  1159. X      {
  1160. X    if ((IC || IM) && from < to)
  1161. X      {
  1162. X        to -= 2;
  1163. X        last2flag = 1;
  1164. X        d_lp_missing = 0;
  1165. X      }
  1166. X    else
  1167. X      {
  1168. X        to--;
  1169. X        delete_lp = (CE || DC || CDC);
  1170. X        d_lp_missing = (s[to] != ' ' || as[to] || fs[to]);
  1171. X        d_lp_image = s[to];
  1172. X        d_lp_attr = as[to];
  1173. X        d_lp_font = fs[to];
  1174. X      }
  1175. X      }
  1176. X    else
  1177. X      to--;
  1178. X  for (x = from; x <= to; ++x)
  1179. X    {
  1180. X      if (x || d_x != d_width || d_y != y - 1)
  1181. X        {
  1182. X      if (x < to || x != d_width - 1 || s[x + 1] == ' ')
  1183. X        if (s[x] == os[x] && as[x] == oa[x] && of[x] == fs[x])
  1184. X          continue;
  1185. X      GotoPos(x, y);
  1186. X        }
  1187. X      SetAttr(as[x]);
  1188. X      SetFont(fs[x]);
  1189. X      PUTCHAR(s[x]);
  1190. X    }
  1191. X  if (to == d_width - 1 && y < d_height - 1 && s[to + 1] == ' ')
  1192. X    GotoPos(0, y + 1);
  1193. X  if (last2flag)
  1194. X    {
  1195. X      GotoPos(x, y);
  1196. X      SetAttr(as[x + 1]);
  1197. X      SetFont(fs[x + 1]);
  1198. X      PUTCHAR(s[x + 1]);
  1199. X      GotoPos(x, y);
  1200. X      SetAttr(as[x]);
  1201. X      SetFont(fs[x]);
  1202. X      INSERTCHAR(s[x]);
  1203. X    }
  1204. X  else if (delete_lp)
  1205. X    {
  1206. X      if (DC)
  1207. X    PutStr(DC);
  1208. X      else if (CDC)
  1209. X    CPutStr(CDC, 1);
  1210. X      else if (CE)
  1211. X    PutStr(CE);
  1212. X    }
  1213. X}
  1214. X
  1215. Xvoid
  1216. XSetLastPos(x,y)
  1217. Xint x,y;
  1218. X{
  1219. X  ASSERT(display);
  1220. X  d_x = x;
  1221. X  d_y = y;
  1222. X}
  1223. X
  1224. Xint
  1225. XResizeDisplay(wi, he)
  1226. Xint wi, he;
  1227. X{
  1228. X  ASSERT(display);
  1229. X  debug2("ResizeDisplay: to (%d,%d).\n", wi, he);
  1230. X  if (d_width == wi && d_height == he)
  1231. X    {
  1232. X      debug("ResizeDisplay: No change\n");
  1233. X      return 0;
  1234. X    }
  1235. X  if (CWS)
  1236. X    {
  1237. X      debug("ResizeDisplay: using WS\n");
  1238. X      PutStr(tgoto(CWS, wi, he));
  1239. X      ChangeScreenSize(wi, he, 0);
  1240. X      return 0;
  1241. X    }
  1242. X  else if (CZ0 && (wi == Z0width || wi == Z1width))
  1243. X    {
  1244. X      debug("ResizeDisplay: using Z0/Z1\n");
  1245. X      PutStr(wi == Z0width ? CZ0 : CZ1);
  1246. X      ChangeScreenSize(wi, d_height, 0);
  1247. X      return (he == d_height) ? 0 : -1;
  1248. X    }
  1249. X  return -1;
  1250. X}
  1251. X
  1252. Xvoid
  1253. XChangeScrollRegion(newtop, newbot)
  1254. Xint newtop, newbot;
  1255. X{
  1256. X  if (display == 0)
  1257. X    return;
  1258. X  if (CS == 0)
  1259. X    {
  1260. X      d_top = 0;
  1261. X      d_bot = d_height - 1;
  1262. X      return;
  1263. X    }
  1264. X  if (d_top == newtop && d_bot == newbot)
  1265. X    return;
  1266. X  debug2("ChangeScrollRegion: (%d - %d)\n", newtop, newbot);
  1267. X  PutStr(tgoto(CS, newbot, newtop));
  1268. X  d_top = newtop;
  1269. X  d_bot = newbot;
  1270. X  d_y = d_x = -1;        /* Just in case... */
  1271. X}
  1272. X
  1273. X
  1274. X/*
  1275. X *  Layer creation / removal
  1276. X */
  1277. X
  1278. Xint
  1279. XInitOverlayPage(datasize, lf, block)
  1280. Xint datasize;
  1281. Xstruct LayFuncs *lf;
  1282. Xint block;
  1283. X{
  1284. X  char *data;
  1285. X  struct layer *newlay;
  1286. X
  1287. X  RemoveStatus();
  1288. X  debug3("Entering new layer  display %#x  d_fore %#x  oldlay %#x\n", 
  1289. X       (unsigned int)display, (unsigned int)d_fore, (unsigned int)d_lay);
  1290. X  if ((newlay = (struct layer *)malloc(sizeof(struct layer))) == 0)
  1291. X    {
  1292. X      Msg(0, "No memory for layer struct");
  1293. X      return(-1);
  1294. X    }
  1295. X  data = 0;
  1296. X  if (datasize)
  1297. X    {
  1298. X      if ((data = malloc(datasize)) == 0)
  1299. X    {
  1300. X      free(newlay);
  1301. X      Msg(0, "No memory for layer data");
  1302. X      return(-1);
  1303. X    }
  1304. X      bzero(data, datasize);
  1305. X    }
  1306. X  newlay->l_layfn = lf;
  1307. X  newlay->l_block = block | d_lay->l_block;
  1308. X  newlay->l_data = data;
  1309. X  newlay->l_next = d_lay;
  1310. X  if (d_fore)
  1311. X    {
  1312. X      d_fore->w_lay = newlay;    /* XXX: CHECK */
  1313. X      d_fore->w_active = 0;    /* XXX: CHECK */
  1314. X    }
  1315. X  d_lay = newlay;
  1316. X  d_layfn = newlay->l_layfn;
  1317. X  Restore();
  1318. X  return(0);
  1319. X}
  1320. X
  1321. Xvoid
  1322. XExitOverlayPage()
  1323. X{
  1324. X  struct layer *oldlay;
  1325. X
  1326. X  debug3("Exiting layer  display %#x  fore %#x  d_lay %#x\n", 
  1327. X         (unsigned int)display, (unsigned int)d_fore, (unsigned int)d_lay);
  1328. X  oldlay = d_lay;
  1329. X  if (oldlay->l_data)
  1330. X    free(oldlay->l_data);
  1331. X  d_lay = oldlay->l_next;
  1332. X  d_layfn = d_lay->l_layfn;
  1333. X  free(oldlay);
  1334. X  if (d_fore)
  1335. X    d_fore->w_lay = d_lay;    /* XXX: Is this necessary ? */
  1336. X  Restore();
  1337. X  SetCursor();
  1338. X}
  1339. X
  1340. X
  1341. X/*
  1342. X *  Output buffering routines
  1343. X */
  1344. X
  1345. Xvoid
  1346. XAddStr(str)
  1347. Xchar *str;
  1348. X{
  1349. X  register char c;
  1350. X
  1351. X  ASSERT(display);
  1352. X  while ((c = *str++))
  1353. X    AddChar(c);
  1354. X}
  1355. X
  1356. Xvoid
  1357. XAddStrn(str, n)
  1358. Xchar *str;
  1359. Xint n;
  1360. X{
  1361. X  register char c;
  1362. X
  1363. X  ASSERT(display);
  1364. X  while ((c = *str++) && n-- > 0)
  1365. X    AddChar(c);
  1366. X  while (n-- > 0)
  1367. X    AddChar(' ');
  1368. X}
  1369. X
  1370. Xvoid
  1371. XFlush()
  1372. X{
  1373. X  register int l;
  1374. X  register char *p;
  1375. X
  1376. X  ASSERT(display);
  1377. X  l = d_obufp - d_obuf;
  1378. X  debug1("Flush(): %d\n", l);
  1379. X  ASSERT(l + d_obuffree == d_obuflen);
  1380. X  if (l == 0)
  1381. X    return;
  1382. X  if (d_userfd < 0)
  1383. X    {
  1384. X      d_obuffree += l;
  1385. X      d_obufp = d_obuf;
  1386. X      return;
  1387. X    }
  1388. X  p = d_obuf;
  1389. X  if (fcntl(d_userfd, F_SETFL, 0))
  1390. X    debug1("Warning: DELAY fcntl failed: %d\n", errno);
  1391. X  while (l)
  1392. X    {
  1393. X      register int wr;
  1394. X      wr = write(d_userfd, p, l);
  1395. X      if (wr <= 0) 
  1396. X    {
  1397. X      if (errno == EINTR) 
  1398. X        continue;
  1399. X      debug1("Writing to display: %d\n", errno);
  1400. X      wr = l;
  1401. X    }
  1402. X      d_obuffree += wr;
  1403. X      p += wr;
  1404. X      l -= wr;
  1405. X    }
  1406. X  d_obuffree += l;
  1407. X  d_obufp = d_obuf;
  1408. X  if (fcntl(d_userfd, F_SETFL, FNDELAY))
  1409. X    debug1("Warning: NDELAY fcntl failed: %d\n", errno);
  1410. X}
  1411. X
  1412. Xvoid
  1413. Xfreetty()
  1414. X{
  1415. X  if (d_userfd >= 0)
  1416. X    close(d_userfd);
  1417. X  debug1("did freetty %d\n", d_userfd);
  1418. X  d_userfd = -1;
  1419. X  d_obufp = 0;
  1420. X  d_obuffree = 0;
  1421. X  if (d_obuf)
  1422. X    free(d_obuf);
  1423. X  d_obuf = 0;
  1424. X  d_obuflen = 0;
  1425. X}
  1426. X
  1427. X/*
  1428. X *  Asynchronous output routines by
  1429. X *  Tim MacKenzie (tym@dibbler.cs.monash.edu.au)
  1430. X */
  1431. X
  1432. Xvoid
  1433. XResize_obuf()
  1434. X{
  1435. X  register int ind;
  1436. X
  1437. X  ASSERT(display);
  1438. X  if (d_obuflen && d_obuf)
  1439. X    {
  1440. X      ind  = d_obufp - d_obuf;
  1441. X      d_obuflen += GRAIN;
  1442. X      d_obuffree += GRAIN;
  1443. X      d_obuf = realloc(d_obuf, d_obuflen);
  1444. X    }
  1445. X  else
  1446. X    {
  1447. X      ind  = 0;
  1448. X      d_obuflen = GRAIN;
  1449. X      d_obuffree = GRAIN;
  1450. X      d_obuf = malloc(d_obuflen);
  1451. X    }
  1452. X  if (!d_obuf)
  1453. X    Panic(0, "Out of memory");
  1454. X  d_obufp = d_obuf + ind;
  1455. X  debug1("ResizeObuf: resized to %d\n", d_obuflen);
  1456. X}
  1457. X
  1458. X#ifdef AUTO_NUKE
  1459. Xvoid
  1460. XNukePending()
  1461. X{/* Nuke pending output in current display, clear screen */
  1462. X  register int len;
  1463. X  int oldfont = d_font, oldattr = d_attr, oldtop = d_top, oldbot = d_bot;
  1464. X  int oldkeypad = d_keypad, oldcursorkeys = d_cursorkeys;
  1465. X
  1466. X  len = d_obufp - d_obuf;
  1467. X  debug1("NukePending: nuking %d chars\n", len);
  1468. X  
  1469. X  /* Throw away any output that we can... */
  1470. X# ifdef POSIX
  1471. X  tcflush(d_userfd, TCOFLUSH);
  1472. X# else
  1473. X#  ifdef TCFLSH
  1474. X  (void) ioctl(d_userfd, TCFLSH, (char *) 1);
  1475. X#  endif
  1476. X# endif
  1477. X
  1478. X  d_obufp = d_obuf;
  1479. X  d_obuffree += len;
  1480. X  d_top = d_bot = -1;
  1481. X  PutStr(TI);
  1482. X  PutStr(IS);
  1483. X  /* Turn off all attributes. (Tim MacKenzie) */
  1484. X  if (ME)
  1485. X    PutStr(ME);
  1486. X  else
  1487. X    {
  1488. X      PutStr(SE);
  1489. X      PutStr(UE);
  1490. X    }
  1491. X  /* Check for toggle */
  1492. X  if (IM && strcmp(IM, EI))
  1493. X    PutStr(EI);
  1494. X  d_insert = 0;
  1495. X  /* Check for toggle */
  1496. X  if (KS && strcmp(KS, KE))
  1497. X    PutStr(KE);
  1498. X  d_keypad = 0;
  1499. X  if (CCS && strcmp(CCS, CCE))
  1500. X    PutStr(CCE);
  1501. X  d_cursorkeys = 0;
  1502. X  PutStr(CE0);
  1503. X  d_font = ASCII;
  1504. X  d_attr = 0;
  1505. X  ChangeScrollRegion(oldtop, oldbot);
  1506. X  SetAttrFont(oldattr, oldfont);
  1507. X  KeypadMode(oldkeypad);
  1508. X  CursorkeysMode(oldcursorkeys);
  1509. X  if (CWS)
  1510. X    {
  1511. X      debug("ResizeDisplay: using WS\n");
  1512. X      PutStr(tgoto(CWS, d_width, d_height));
  1513. X    }
  1514. X  else if (CZ0 && (d_width == Z0width || d_width == Z1width))
  1515. X    {
  1516. X      debug("ResizeDisplay: using Z0/Z1\n");
  1517. X      PutStr(d_width == Z0width ? CZ0 : CZ1);
  1518. X    }
  1519. X}
  1520. X#endif /* AUTO_NUKE */
  1521. END_OF_FILE
  1522. if test 27002 -ne `wc -c <'display.c'`; then
  1523.     echo shar: \"'display.c'\" unpacked with wrong size!
  1524. fi
  1525. # end of 'display.c'
  1526. fi
  1527. if test -f 'socket.c' -a "${1}" != "-c" ; then 
  1528.   echo shar: Will not clobber existing file \"'socket.c'\"
  1529. else
  1530. echo shar: Extracting \"'socket.c'\" \(28896 characters\)
  1531. sed "s/^X//" >'socket.c' <<'END_OF_FILE'
  1532. X/* Copyright (c) 1993
  1533. X *      Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
  1534. X *      Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
  1535. X * Copyright (c) 1987 Oliver Laumann
  1536. X *
  1537. X * This program is free software; you can redistribute it and/or modify
  1538. X * it under the terms of the GNU General Public License as published by
  1539. X * the Free Software Foundation; either version 2, or (at your option)
  1540. X * any later version.
  1541. X *
  1542. X * This program is distributed in the hope that it will be useful,
  1543. X * but WITHOUT ANY WARRANTY; without even the implied warranty of
  1544. X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  1545. X * GNU General Public License for more details.
  1546. X *
  1547. X * You should have received a copy of the GNU General Public License
  1548. X * along with this program (see the file COPYING); if not, write to the
  1549. X * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  1550. X *
  1551. X ****************************************************************
  1552. X */
  1553. X
  1554. X#include "rcs.h"
  1555. XRCS_ID("$Id: socket.c,v 1.6 1993/07/21 15:43:26 mlschroe Exp $ FAU")
  1556. X
  1557. X#include "config.h"
  1558. X#include <sys/types.h>
  1559. X#include <sys/stat.h>
  1560. X#ifndef sgi
  1561. X# include <sys/file.h>
  1562. X#endif
  1563. X#ifndef NAMEDPIPE
  1564. X#include <sys/socket.h>
  1565. X#endif
  1566. X#include <fcntl.h>
  1567. X#ifndef NAMEDPIPE
  1568. X#include <sys/un.h>
  1569. X#endif
  1570. X#include <signal.h>
  1571. X#ifndef M_XENIX
  1572. X#include <sys/time.h>
  1573. X#endif /* M_XENIX */
  1574. X#ifdef DIRENT
  1575. X# include <dirent.h>
  1576. X#else
  1577. X# include <sys/dir.h>
  1578. X# define dirent direct
  1579. X#endif
  1580. X
  1581. X#include "screen.h"
  1582. X
  1583. X#ifdef USEVARARGS
  1584. X# if defined(__STDC__)
  1585. X#  include <stdarg.h>
  1586. X# else
  1587. X#  include <varargs.h>
  1588. X# endif
  1589. X#endif
  1590. X
  1591. X#include "extern.h"
  1592. X
  1593. X#if defined(_SEQUENT_) && !defined(NAMEDPIPE)
  1594. X# define connect sconnect    /* _SEQUENT_ has braindamaged connect */
  1595. Xstatic int sconnect __P((int, struct sockaddr *, int));
  1596. X#endif
  1597. X
  1598. Xextern char *RcFileName, *extra_incap, *extra_outcap;
  1599. Xextern int ServerSocket, real_uid, real_gid, eff_uid, eff_gid;
  1600. Xextern int dflag, iflag, rflag, lsflag, quietflag, wipeflag, xflag;
  1601. Xextern char *attach_tty, *LoginName, HostName[];
  1602. Xextern struct display *display, *displays;
  1603. Xextern struct win *fore, *console_window, *windows;
  1604. Xextern struct NewWindow nwin_undef;
  1605. X#ifdef NETHACK
  1606. Xextern nethackflag;
  1607. X#endif
  1608. X#ifdef MULTIUSER
  1609. Xextern char *multi;
  1610. X#endif
  1611. X
  1612. X#ifdef PASSWORD
  1613. Xextern int CheckPassword;
  1614. Xextern char Password[];
  1615. X#endif
  1616. Xextern char *getenv();
  1617. X
  1618. Xchar SockPath[MAXPATHLEN];
  1619. Xchar *SockNamePtr, *SockName;
  1620. X
  1621. X#ifdef MULTIUSER
  1622. X# define SOCKMODE (S_IWRITE | S_IREAD | (displays ? S_IEXEC : 0) | (multi ? 1 : 0))
  1623. X#else
  1624. X# define SOCKMODE (S_IWRITE | S_IREAD | (displays ? S_IEXEC : 0))
  1625. X#endif
  1626. X
  1627. Xint
  1628. XRecoverSocket()
  1629. X{
  1630. X#ifndef NOREUID
  1631. X  setreuid(eff_uid, real_uid);
  1632. X  setregid(eff_gid, real_gid);
  1633. X#endif
  1634. X  (void) unlink(SockPath);
  1635. X#ifndef NOREUID
  1636. X  setreuid(real_uid, eff_uid);
  1637. X  setregid(real_gid, eff_gid);
  1638. X#endif
  1639. X  close(ServerSocket);
  1640. X  if ((ServerSocket = MakeServerSocket()) < 0)
  1641. X    return 0;
  1642. X  return 1;
  1643. X}
  1644. X
  1645. X/*
  1646. X * Socket mode 700 means we are Attached. 600 is detached.
  1647. X * We return how many sockets we found. If it was exactly one, we come
  1648. X * back with a SockPath set to it and open it in a fd pointed to by fdp.
  1649. X * If fdp == 0 we simply produce a list if all sockets.
  1650. X */
  1651. X/* ARGSUSED */
  1652. Xint
  1653. XFindSocket(how, fdp)
  1654. Xint how;
  1655. Xint *fdp;
  1656. X{
  1657. X  register int s, lasts = 0, found = 0, deadcount = 0, wipecount = 0;
  1658. X  register int l = 0;
  1659. X  register DIR *dirp;
  1660. X  register struct dirent *dp;
  1661. X  register char *Name;
  1662. X  struct stat st;
  1663. X  struct foundsock
  1664. X    {
  1665. X      char *name;
  1666. X      int mode;
  1667. X    } foundsock[100];    /* 100 is hopefully enough. */
  1668. X  int foundsockcount = 0;
  1669. X
  1670. X  /* User may or may not give us a (prefix) SockName. We want to search. */
  1671. X  debug("FindSocket:\n");
  1672. X  if (SockName)
  1673. X    {
  1674. X      debug1("We want to match '%s'\n", SockName);
  1675. X      l = strlen(SockName);
  1676. X#ifdef NAME_MAX
  1677. X      if (l > NAME_MAX)
  1678. X    l = NAME_MAX;
  1679. X#endif
  1680. X    }
  1681. X
  1682. X#ifndef NOREUID
  1683. X  setreuid(eff_uid, real_uid);
  1684. X  setregid(eff_gid, real_gid);
  1685. X#endif
  1686. X  debug1("FindSock searching... '%s'\n", SockPath);
  1687. X  /*
  1688. X   * this is a hack: SockName may point to Filename(Sockpath)...
  1689. X   */
  1690. X  found = *SockNamePtr;
  1691. X  *SockNamePtr = '\0';
  1692. X  if ((dirp = opendir(SockPath)) == NULL)
  1693. X    {
  1694. X      Panic(0, "Cannot opendir %s", SockPath);
  1695. X      /* NOTREACHED */
  1696. X    }
  1697. X  *SockNamePtr = found;
  1698. X  found = 0;
  1699. X  while ((dp = readdir(dirp)) != NULL)
  1700. X    {
  1701. X      Name = dp->d_name;
  1702. X      /* 
  1703. X       * there may be a file ".termcap" here. 
  1704. X       * Ignore it just like "." and "..". 
  1705. X       */
  1706. X      if (Name[0] == '.')
  1707. X    continue;
  1708. X      if (SockName && l)
  1709. X    {
  1710. X      register char *n = Name;
  1711. X
  1712. X      debug2("Attach found: '%s', needed '%s'\n", Name, SockName);
  1713. X      /*
  1714. X       * The SockNames "hf", "ttyhf", "1", "12345.tty", "12345.ttyhf.medusa"
  1715. X       * all match the Name "12345.ttyhf.medusa".
  1716. X       */
  1717. X
  1718. X      if ((*SockName <= '0' || *SockName > '9') && (*n > '0' && *n <= '9'))
  1719. X        {
  1720. X          while (*++n)
  1721. X        if (*n == '.')
  1722. X          {
  1723. X            n++;
  1724. X            break;
  1725. X          }
  1726. X          if (strncmp("tty", SockName, 3) && !strncmp("tty", n, 3))
  1727. X        n += 3;
  1728. X        }
  1729. X      if (strncmp(n, SockName, l))
  1730. X        {
  1731. X          debug3("strncmp('%s', '%s', %d)\n", n, SockName, l);
  1732. X          continue;
  1733. X        }
  1734. X    }
  1735. X      /*
  1736. X       * ATTENTION! MakeClientSocket adds SockName to SockPath! 
  1737. X       * Anyway, we need it earlier.
  1738. X       */
  1739. X      strcpy(SockNamePtr, Name);
  1740. X      if (stat(SockPath, &st))
  1741. X    continue;
  1742. X#ifndef SOCK_NOT_IN_FS
  1743. X# ifdef NAMEDPIPE
  1744. X      if (!S_ISFIFO(st.st_mode))
  1745. X    {
  1746. X      debug1("'%s' is not a pipe, ignored\n", SockPath);
  1747. X      continue;
  1748. X    }
  1749. X# else /* NAMEDPIPE */
  1750. X#  ifdef S_ISSOCK
  1751. X      if (!S_ISSOCK(st.st_mode))
  1752. X    {
  1753. X      debug1("'%s' is not a socket, ignored\n", SockPath);
  1754. X      continue;
  1755. X    }
  1756. X#  endif
  1757. X# endif /* NAMEDPIPE */
  1758. X#endif
  1759. X      if (st.st_uid != real_uid)
  1760. X    continue;
  1761. X      s = st.st_mode & 0777;
  1762. X#ifdef MULTIUSER
  1763. X      if (multi && ((s & 0677) == 0600))
  1764. X    continue;
  1765. X#endif
  1766. X      foundsock[foundsockcount].name = SaveStr(Name);
  1767. X#ifdef MULTIUSER
  1768. X      foundsock[foundsockcount].mode = s ^ (multi ? 1 : 0);
  1769. X#else
  1770. X      foundsock[foundsockcount].mode = s;
  1771. X#endif
  1772. X      debug2("FindSocket: %s has mode %04o...\n", Name, s);
  1773. X      {
  1774. X    /* 
  1775. X     * marc parses the socketname again
  1776. X     */
  1777. X    int sockmpid = 0;
  1778. X    char *nam = Name;
  1779. X
  1780. X    while (*nam)
  1781. X      {
  1782. X        if (*nam > '9' || *nam < '0')
  1783. X          break;
  1784. X        sockmpid = 10 * sockmpid + *nam - '0';
  1785. X        nam++;
  1786. X      }
  1787. X    /*
  1788. X     * A socket is counted as dead, when there is no
  1789. X     * process belongin to it. If there is one, and the
  1790. X     * socket mode indicates "single user detached", then
  1791. X     * we should be able to connect.
  1792. X     * If successfull, thats o.k. Otherwise we record that mode as -1.
  1793. X     * MakeClientSocket() must be careful not to block forever.
  1794. X     */
  1795. X    if (((sockmpid > 2) && kill(sockmpid, 0) == -1 && errno == ESRCH) ||
  1796. X        (((s & 0677) == 0600) && (s = MakeClientSocket(0, Name)) == -1))
  1797. X      {
  1798. X        foundsock[foundsockcount].mode = -1;
  1799. X        deadcount++;
  1800. X      }
  1801. X    else
  1802. X      close(s);
  1803. X      }
  1804. X      if (++foundsockcount >= 100)
  1805. X    break;
  1806. X    }
  1807. X  closedir(dirp);
  1808. X
  1809. X  if (wipeflag)
  1810. X    {
  1811. X      for (s = 0; s < foundsockcount; s++)
  1812. X    {
  1813. X      if (foundsock[s].mode == -1)
  1814. X        {
  1815. X              strcpy(SockNamePtr, foundsock[s].name);
  1816. X          debug1("wiping '%s'\n", SockPath);
  1817. X          if (unlink(SockPath) == 0)
  1818. X            {
  1819. X          foundsock[s].mode = -2;
  1820. X              wipecount++;
  1821. X        }
  1822. X        }
  1823. X    }
  1824. X    }
  1825. Xdebug3("found=%d, dflag = %d, xflag = %d\n", found, dflag, xflag);
  1826. X  for (s = 0; s < foundsockcount; s++)
  1827. X    if ((foundsock[s].mode) == (dflag ? 0700 : 0600)
  1828. X        || (xflag && foundsock[s].mode == 0700)) 
  1829. X      {
  1830. X    found++;
  1831. Xdebug2("mode = %d --> found = %d\n", foundsock[s].mode, found);
  1832. X    lasts = s;
  1833. X      }
  1834. X  if (quietflag && (lsflag || (found != 1 && rflag != 2)))
  1835. X    eexit(10 + found);
  1836. X  debug2("attach: found=%d, foundsockcount=%d\n", found, foundsockcount);
  1837. X  if (found == 1 && lsflag == 0)
  1838. X    {
  1839. X      if ((lasts = MakeClientSocket(0, SockName = foundsock[lasts].name)) == -1)
  1840. X        found = 0;
  1841. X    }
  1842. X  else if (!quietflag && foundsockcount > 0)
  1843. X    {
  1844. X      switch (found)
  1845. X        {
  1846. X        case 0:
  1847. X          if (lsflag)
  1848. X        {
  1849. X#ifdef NETHACK
  1850. X              if (nethackflag)
  1851. X            printf("Your inventory:\n");
  1852. X          else
  1853. X#endif
  1854. X          printf((foundsockcount > 1) ?
  1855. X                 "There are screens on:\n" : "There is a screen on:\n");
  1856. X        }
  1857. X          else
  1858. X        {
  1859. X#ifdef NETHACK
  1860. X              if (nethackflag)
  1861. X            printf("Nothing fitting exists in the game:\n");
  1862. X          else
  1863. X#endif
  1864. X          printf((foundsockcount > 1) ?
  1865. X                 "There are screens on:\n" : "There is a screen on:\n");
  1866. X        }
  1867. X          break;
  1868. X        case 1:
  1869. X#ifdef NETHACK
  1870. X          if (nethackflag)
  1871. X            printf((foundsockcount > 1) ?
  1872. X                   "Prove thyself worthy or perish:\n" : 
  1873. X                   "You see here a good looking screen:\n");
  1874. X          else
  1875. X#endif
  1876. X          printf((foundsockcount > 1) ? 
  1877. X                 "There are several screens on:\n" :
  1878. X                 "There is a possible screen on:\n");
  1879. X          break;
  1880. X        default:
  1881. X#ifdef NETHACK
  1882. X          if (nethackflag)
  1883. X            printf((foundsockcount > 1) ? 
  1884. X                   "You may whish for a screen, what do you want?\n" : 
  1885. X                   "You see here a screen:\n");
  1886. X          else
  1887. X#endif
  1888. X          printf((foundsockcount > 1) ?
  1889. X                 "There are several screens on:\n" : "There is a screen on:\n");
  1890. X          break;
  1891. X        }
  1892. X      for (s = 0; s < foundsockcount; s++)
  1893. X    {
  1894. X      switch (foundsock[s].mode)
  1895. X        {
  1896. X        case 0700:
  1897. X          printf("\t%s\t(Attached)\n", foundsock[s].name);
  1898. X          break;
  1899. X        case 0600:
  1900. X          printf("\t%s\t(Detached)\n", foundsock[s].name);
  1901. X          break;
  1902. X#ifdef MULTIUSER
  1903. X        case 0701:
  1904. X          printf("\t%s\t(Multi, attached)\n", foundsock[s].name);
  1905. X          break;
  1906. X        case 0601:
  1907. X          printf("\t%s\t(Multi, detached)\n", foundsock[s].name);
  1908. X          break;
  1909. X#endif
  1910. X        case -1:
  1911. X#if defined(__STDC__) || defined(_AIX) || defined(SVR4)
  1912. X          printf("\t%s\t(Dead ??\?)\n", foundsock[s].name);
  1913. X#else
  1914. X          printf("\t%s\t(Dead ???)\n", foundsock[s].name);
  1915. X#endif
  1916. X          break;
  1917. X        case -2:
  1918. X          printf("\t%s\t(Removed)\n", foundsock[s].name);
  1919. X          break;
  1920. X        default:
  1921. X          printf("\t%s\t(Wrong mode)\n", foundsock[s].name);
  1922. X          break;
  1923. X        }
  1924. X    }
  1925. X    }
  1926. X  if (deadcount && !quietflag)
  1927. X    {
  1928. X      if (wipeflag)
  1929. X        {
  1930. X#ifdef NETHACK
  1931. X          if (nethackflag)
  1932. X            printf("You hear%s distant explosion%s.\n",
  1933. X           (deadcount > 1) ? "" : " a", (deadcount > 1) ? "s" : "");
  1934. X          else
  1935. X#endif
  1936. X          printf("%d Socket%s wiped out.\n", deadcount, (deadcount > 1)?"s":"");
  1937. X    }
  1938. X      else
  1939. X    {
  1940. X#ifdef NETHACK
  1941. X          if (nethackflag)
  1942. X            printf("The dead screen%s touch%s you. Try 'screen -wipe'.\n",
  1943. X           (deadcount > 1) ? "s" : "", (deadcount > 1) ? "" : "es");
  1944. X          else
  1945. X#endif
  1946. X          printf("Remove dead Sockets with 'screen -wipe'.\n");
  1947. X    }
  1948. X    }
  1949. X
  1950. X  for (s = 0; s < foundsockcount; s++)
  1951. X    Free(foundsock[s].name);
  1952. X  if (found == 1 && fdp)
  1953. X    *fdp = lasts;
  1954. X#ifndef NOREUID
  1955. X  setreuid(real_uid, eff_uid);
  1956. X  setregid(real_gid, eff_gid);
  1957. X#endif
  1958. X  if (fdp)
  1959. X    return found;
  1960. X  return foundsockcount - wipecount;
  1961. X}
  1962. X
  1963. X#ifdef NAMEDPIPE
  1964. X
  1965. Xint
  1966. XMakeServerSocket()
  1967. X{
  1968. X  register int s;
  1969. X  struct stat st;
  1970. X
  1971. X  strcpy(SockNamePtr, SockName);
  1972. X# ifdef NAME_MAX
  1973. X  if (strlen(SockNamePtr) > NAME_MAX)
  1974. X    {
  1975. X      debug2("MakeClientSocket: '%s' truncated to %d chars\n",
  1976. X         SockNamePtr, NAME_MAX);
  1977. X      SockNamePtr[NAME_MAX] = '\0';
  1978. X    }
  1979. X# endif /* NAME_MAX */
  1980. X
  1981. X# ifndef NOREUID
  1982. X  setreuid(eff_uid, real_uid);
  1983. X  setregid(eff_gid, real_gid);
  1984. X# endif /* NOREUID */
  1985. X  if ((s = open(SockPath, O_WRONLY | O_NDELAY)) >= 0)
  1986. X    {
  1987. X      debug("huii, my fifo already exists??\n");
  1988. X      if (quietflag)
  1989. X    {
  1990. X      Kill(d_userpid, SIG_BYE);
  1991. X      eexit(11);
  1992. X    }
  1993. X      printf("There is already a screen running on %s.\n",
  1994. X         Filename(SockPath));
  1995. X      if (stat(SockPath, &st) == -1)
  1996. X    Panic(errno, "stat");
  1997. X      if (st.st_uid != real_uid)
  1998. X    Panic(0, "Unfortunatelly you are not its owner.");
  1999. X      if ((st.st_mode & 0700) == 0600)
  2000. X    Panic(0, "To resume it, use \"screen -r\"");
  2001. X      else
  2002. X    Panic(0, "It is not detached.");
  2003. X      /* NOTREACHED */
  2004. X    }
  2005. X# ifndef NOREUID
  2006. X  (void) unlink(SockPath);
  2007. X  if (mknod(SockPath, S_IFIFO | SOCKMODE, 0))
  2008. X    Panic(0, "mknod fifo %s failed", SockPath);
  2009. X#  ifdef BROKEN_PIPE
  2010. X  if ((s = open(SockPath, O_RDWR | O_NDELAY, 0)) < 0)
  2011. X#  else
  2012. X  if ((s = open(SockPath, O_RDONLY | O_NDELAY, 0)) < 0)
  2013. X#  endif
  2014. X    Panic(errno, "open fifo %s", SockPath);
  2015. X  setreuid(real_uid, eff_uid);
  2016. X  setregid(real_gid, eff_gid);
  2017. X  return s;
  2018. X# else /* NOREUID */
  2019. X  if (UserContext() > 0)
  2020. X    {
  2021. X      (void) unlink(SockPath);
  2022. X      if (mknod(SockPath, S_IFIFO | SOCKMODE, 0))
  2023. X    UserReturn(0);
  2024. X      UserReturn(1);
  2025. X    }
  2026. X  if (UserStatus() <= 0)
  2027. X    Panic(0, "mknod fifo %s failed", SockPath);
  2028. X#  ifdef BROKEN_PIPE
  2029. X  if ((s = secopen(SockPath, O_RDWR | O_NDELAY, 0)) < 0)
  2030. X#  else
  2031. X  if ((s = secopen(SockPath, O_RDONLY | O_NDELAY, 0)) < 0)
  2032. X#  endif
  2033. X    Panic(errno, "open fifo %s", SockPath);
  2034. X  return s;
  2035. X# endif /* NOREUID */
  2036. X}
  2037. X
  2038. X
  2039. Xint
  2040. XMakeClientSocket(err, name)
  2041. Xint err;
  2042. Xchar *name;
  2043. X{
  2044. X  register int s = 0;
  2045. X
  2046. X  strcpy(SockNamePtr, name);
  2047. X# ifdef NAME_MAX
  2048. X  if (strlen(SockNamePtr) > NAME_MAX)
  2049. X    {
  2050. X      debug2("MakeClientSocket: '%s' truncated to %d chars\n",
  2051. X         SockNamePtr, NAME_MAX);
  2052. X      SockNamePtr[NAME_MAX] = '\0';
  2053. X    }
  2054. X# endif /* NAME_MAX */
  2055. X  
  2056. X  if ((s = secopen(SockPath, O_WRONLY | O_NDELAY, 0)) >= 0)
  2057. X    {
  2058. X      (void) fcntl(s, F_SETFL, 0);
  2059. X      return s;
  2060. X    }
  2061. X  if (err)
  2062. X    Msg(errno, "open: %s (but continuing...)", SockPath);
  2063. X  debug1("MakeClientSocket() open %s failed\n", SockPath);
  2064. X  return -1;
  2065. X}
  2066. X
  2067. X#else    /* NAMEDPIPE */
  2068. X
  2069. Xint
  2070. XMakeServerSocket()
  2071. X{
  2072. X  register int s;
  2073. X  struct sockaddr_un a;
  2074. X  struct stat st;
  2075. X
  2076. X  if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
  2077. X    Panic(errno, "socket");
  2078. X  a.sun_family = AF_UNIX;
  2079. X  strcpy(SockNamePtr, SockName);
  2080. X# ifdef NAME_MAX
  2081. X  if (strlen(SockNamePtr) > NAME_MAX)
  2082. X    {
  2083. X      debug2("MakeServerSocket: '%s' truncated to %d chars\n",
  2084. X         SockNamePtr, NAME_MAX);
  2085. X      SockNamePtr[NAME_MAX] = '\0';
  2086. X    }
  2087. X# endif /* NAME_MAX */
  2088. X
  2089. X  strcpy(a.sun_path, SockPath);
  2090. X# ifndef NOREUID
  2091. X  setreuid(eff_uid, real_uid);
  2092. X  setregid(eff_gid, real_gid);
  2093. X# endif /* NOREUID */
  2094. X  if (connect(s, (struct sockaddr *) &a, strlen(SockPath) + 2) != -1)
  2095. X    {
  2096. X      debug("oooooh! socket already is alive!\n");
  2097. X      if (quietflag)
  2098. X    { 
  2099. X      Kill(d_userpid, SIG_BYE);
  2100. X      /* 
  2101. X       * oh, well. nobody receives that return code. papa 
  2102. X       * dies by signal.
  2103. X       */
  2104. X      eexit(11);
  2105. X    }
  2106. X      printf("There is already a screen running on %s.\n",
  2107. X         Filename(SockPath));
  2108. X      if (stat(SockPath, &st) == -1)
  2109. X    Panic(errno, "stat");
  2110. X      if (st.st_uid != real_uid)
  2111. X    Panic(0, "Unfortunatelly you are not its owner.");
  2112. X      if ((st.st_mode & 0700) == 0600)
  2113. X    Panic(0, "To resume it, use \"screen -r\"");
  2114. X      else
  2115. X    Panic(0, "It is not detached.");
  2116. X      /* NOTREACHED */
  2117. X    }
  2118. X#if defined(m88k) || defined(m68k)
  2119. X  close(s);    /* we get bind: Invalid argument if this is not done */
  2120. X  if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
  2121. X    Panic(errno, "reopen socket");
  2122. X#endif
  2123. X  (void) unlink(SockPath);
  2124. X  if (bind(s, (struct sockaddr *) & a, strlen(SockPath) + 2) == -1)
  2125. X    Panic(errno, "bind (%s)", SockPath);
  2126. X#ifdef SOCK_NOT_IN_FS
  2127. X    {
  2128. X      int f;
  2129. X      if ((f = secopen(SockPath, O_RDWR | O_CREAT, SOCKMODE)) < 0)
  2130. X        Panic(errno, "shadow socket open");
  2131. X      close(f);
  2132. X    }
  2133. X#else
  2134. X  chmod(SockPath, SOCKMODE);
  2135. X# ifdef NOREUID
  2136. X  chown(SockPath, real_uid, real_gid);
  2137. X# endif /* NOREUID */
  2138. X#endif /* SOCK_NOT_IN_FS */
  2139. X  if (listen(s, 5) == -1)
  2140. X    Panic(errno, "listen");
  2141. X# ifdef F_SETOWN
  2142. X  fcntl(s, F_SETOWN, getpid());
  2143. X  debug1("Serversocket owned by %d\n", fcntl(s, F_GETOWN, 0));
  2144. X# endif /* F_SETOWN */
  2145. X# ifndef NOREUID
  2146. X  setreuid(real_uid, eff_uid);
  2147. X  setregid(real_gid, eff_gid);
  2148. X# endif /* NOREUID */
  2149. X  return s;
  2150. X}
  2151. X
  2152. Xint
  2153. XMakeClientSocket(err, name)
  2154. Xint err;
  2155. Xchar *name;
  2156. X{
  2157. X  register int s;
  2158. X  struct sockaddr_un a;
  2159. X
  2160. X  if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
  2161. X    Panic(errno, "socket");
  2162. X  a.sun_family = AF_UNIX;
  2163. X  strcpy(SockNamePtr, name);
  2164. X# ifdef NAME_MAX
  2165. X  if (strlen(SockNamePtr) > NAME_MAX)
  2166. X    {
  2167. X      debug2("MakeClientSocket: '%s' truncated to %d chars\n",
  2168. X         SockNamePtr, NAME_MAX);
  2169. X      SockNamePtr[NAME_MAX] = '\0';
  2170. X    }
  2171. X# endif /* NAME_MAX */
  2172. X
  2173. X  strcpy(a.sun_path, SockPath);
  2174. X# ifndef NOREUID
  2175. X  setreuid(eff_uid, real_uid);
  2176. X  setregid(eff_gid, real_gid);
  2177. X# else /* NOREUID */
  2178. X  if (access(SockPath, W_OK))
  2179. X    {
  2180. X      if (err)
  2181. X    Msg(errno, "%s", SockPath);
  2182. X      debug2("MakeClientSocket: access(%s): %d.\n", SockPath, errno);
  2183. X      close(s);
  2184. X      return -1;
  2185. X    }
  2186. X# endif /* NOREUID */
  2187. X  if (connect(s, (struct sockaddr *) &a, strlen(SockPath) + 2) == -1)
  2188. X    {
  2189. X      if (err)
  2190. X    Msg(errno, "%s: connect", SockPath);
  2191. X      debug("MakeClientSocket: connect failed.\n");
  2192. X      close(s);
  2193. X      s = -1;
  2194. X    }
  2195. X# ifndef NOREUID
  2196. X  setreuid(real_uid, eff_uid);
  2197. X  setregid(real_gid, eff_gid);
  2198. X# endif /* NOREUID */
  2199. X  return s;
  2200. X}
  2201. X#endif /* NAMEDPIPE */
  2202. X
  2203. X
  2204. Xvoid
  2205. XSendCreateMsg(s, nwin)
  2206. Xint s;
  2207. Xstruct NewWindow *nwin;
  2208. X{
  2209. X  struct msg m;
  2210. X  register char *p;
  2211. X  register int len, n;
  2212. X  char **av = nwin->args;
  2213. X
  2214. X  debug1("SendCreateMsg() to '%s'\n", SockPath);
  2215. X  bzero((char *)&m, sizeof(m));
  2216. X  m.type = MSG_CREATE;
  2217. X  strcpy(m.m_tty, attach_tty);
  2218. X  p = m.m.create.line;
  2219. X  n = 0;
  2220. X  if (nwin->args != nwin_undef.args)
  2221. X    for (av = nwin->args; *av && n < MAXARGS - 1; ++av, ++n)
  2222. X      {
  2223. X        len = strlen(*av) + 1;
  2224. X        if (p + len >= m.m.create.line + MAXPATHLEN - 1)
  2225. X      break;
  2226. X        strcpy(p, *av);
  2227. X        p += len;
  2228. X      }
  2229. X  if (nwin->aka != nwin_undef.aka && p + strlen(nwin->aka) + 1 < m.m.create.line + MAXPATHLEN)
  2230. X    strcpy(p, nwin->aka);
  2231. X  else
  2232. X    *p = '\0';
  2233. X  m.m.create.nargs = n;
  2234. X  m.m.create.aflag = nwin->aflag;
  2235. X  m.m.create.flowflag = nwin->flowflag;
  2236. X  m.m.create.lflag = nwin->lflag;
  2237. X  m.m.create.hheight = nwin->histheight;
  2238. X#ifdef SYSV
  2239. X  if (getcwd(m.m.create.dir, sizeof(m.m.create.dir)) == 0)
  2240. X#else
  2241. X  if (getwd(m.m.create.dir) == 0)
  2242. X#endif
  2243. X    {
  2244. X      Msg(errno, "%s", m.m.create.dir);
  2245. X      return;
  2246. X    }
  2247. X  if (nwin->term != nwin_undef.term)
  2248. X    strncpy(m.m.create.screenterm, nwin->term, 19);
  2249. X  m.m.create.screenterm[19] = '\0';
  2250. X  debug1("SendCreateMsg writing '%s'\n", m.m.create.line);
  2251. X  if (write(s, (char *) &m, sizeof m) != sizeof m)
  2252. X    Msg(errno, "write");
  2253. X}
  2254. X
  2255. Xvoid
  2256. X#ifdef USEVARARGS
  2257. X/*VARARGS1*/
  2258. X# if defined(__STDC__)
  2259. XSendErrorMsg(char *fmt, ...)
  2260. X# else /* __STDC__ */
  2261. XSendErrorMsg(fmt, va_alist)
  2262. Xchar *fmt;
  2263. Xva_dcl
  2264. X# endif /* __STDC__ */
  2265. X{ /* } */
  2266. X  static va_list ap;
  2267. X#else /* USEVARARGS */
  2268. X/*VARARGS1*/
  2269. XSendErrorMsg(fmt, p1, p2, p3, p4, p5, p6)
  2270. Xchar *fmt;
  2271. Xunsigned long p1, p2, p3, p4, p5, p6;
  2272. X{
  2273. X#endif /* USEVARARGS */
  2274. X  register int s;
  2275. X  struct msg m;
  2276. X
  2277. X#ifdef USEVARARGS
  2278. X# if defined(__STDC__)
  2279. X  va_start(ap, fmt);
  2280. X# else /* __STDC__ */
  2281. X  va_start(ap);
  2282. X# endif /* __STDC__ */
  2283. X  (void) vsprintf(m.m.message, fmt, ap);
  2284. X  va_end(ap);
  2285. X#else /* USEVARARGS */
  2286. X  sprintf(m.m.message, fmt, p1, p2, p3, p4, p5, p6);
  2287. X#endif /* USEVARARGS */
  2288. X  debug1("SendErrorMsg: '%s'\n", m.m.message);
  2289. X  if (display == 0)
  2290. X    return;
  2291. X  s = MakeClientSocket(1, SockName);
  2292. X  m.type = MSG_ERROR;
  2293. X  strcpy(m.m_tty, d_usertty);
  2294. X  debug1("SendErrorMsg(): writing to '%s'\n", SockPath);
  2295. X  (void) write(s, (char *) &m, sizeof m);
  2296. X  close(s);
  2297. X  sleep(2);
  2298. X}
  2299. X
  2300. X#ifdef PASSWORD
  2301. Xstatic int
  2302. XCheckPasswd(pwd, pid, utty)
  2303. Xint pid;
  2304. Xchar *pwd, *utty;
  2305. X{
  2306. X  if (CheckPassword && 
  2307. X      strcmp(crypt(pwd, (strlen(Password) > 1) ? Password : "JW"),
  2308. X         Password))
  2309. X    {
  2310. X      if (*pwd)
  2311. X    {
  2312. X# ifdef NETHACK
  2313. X          if (nethackflag)
  2314. X        Msg(0, "'%s' tries to explode in the sky, but fails. (%s)", utty, pwd);
  2315. X          else
  2316. X# endif /* NETHACK */
  2317. X      Msg(0, "Illegal reattach attempt from terminal %s, \"%s\"", utty, pwd);
  2318. X    }
  2319. X      debug1("CheckPass() wrong password kill(%d, SIG_PW_FAIL)\n", pid);
  2320. X      Kill(pid, SIG_PW_FAIL);
  2321. X      return 0;
  2322. X    }
  2323. X  debug1("CheckPass() from %d happy\n", pid);
  2324. X  Kill(pid, SIG_PW_OK);
  2325. X  return 1;
  2326. X}
  2327. X#endif    /* PASSWORD */
  2328. X
  2329. Xstatic void
  2330. XExecCreate(mp)
  2331. Xstruct msg *mp;
  2332. X{
  2333. X  struct NewWindow nwin;
  2334. X  char *args[MAXARGS];
  2335. X  register int n;
  2336. X  register char **pp = args, *p = mp->m.create.line;
  2337. X
  2338. X  nwin = nwin_undef;
  2339. X  for (n = mp->m.create.nargs; n > 0; --n)
  2340. X    {
  2341. X      *pp++ = p;
  2342. X      p += strlen(p) + 1;
  2343. X    }
  2344. X  *pp = 0;
  2345. X  if (*p)
  2346. X    nwin.aka = p;
  2347. X  if (*args)
  2348. X    nwin.args = args;
  2349. X  nwin.aflag = mp->m.create.aflag;
  2350. X  nwin.flowflag = mp->m.create.flowflag;
  2351. X  if (*mp->m.create.dir)
  2352. X    nwin.dir = mp->m.create.dir;
  2353. X  nwin.lflag = mp->m.create.lflag;
  2354. X  nwin.histheight = mp->m.create.hheight;
  2355. X  if (*mp->m.create.screenterm)
  2356. X    nwin.term =  mp->m.create.screenterm;
  2357. X  MakeWindow(&nwin);
  2358. X}
  2359. X
  2360. Xstatic int
  2361. XCheckPid(pid)
  2362. Xint pid;
  2363. X{
  2364. X  debug1("Checking pid %d\n", pid);
  2365. X  if (pid < 2)
  2366. X    return(-1);
  2367. X  if (eff_uid == real_uid)
  2368. X    return kill(pid, 0);
  2369. X  if (UserContext() == 1)
  2370. X    {
  2371. X      UserReturn(kill(pid, 0));
  2372. X    }
  2373. X  return UserStatus();
  2374. X}
  2375. X
  2376. Xvoid
  2377. XReceiveMsg()
  2378. X{
  2379. X  int left, len, i;
  2380. X  static struct msg m;
  2381. X  char *p;
  2382. X  int ns = ServerSocket;
  2383. X  struct mode Mode;
  2384. X#ifdef UTMPOK
  2385. X  struct win *wi;
  2386. X#endif
  2387. X#ifdef REMOTE_DETACH
  2388. X  struct display *next;
  2389. X#endif
  2390. X
  2391. X#ifdef NAMEDPIPE
  2392. X  debug("Ha, there was someone knocking on my fifo??\n");
  2393. X  if (fcntl(ServerSocket, F_SETFL, 0) == -1)
  2394. X    Panic(errno, "DELAY fcntl");
  2395. X#else
  2396. X  struct sockaddr_un a;
  2397. X
  2398. X  len = sizeof(a);
  2399. X  debug("Ha, there was someone knocking on my socket??\n");
  2400. X  if ((ns = accept(ns, (struct sockaddr *) &a, &len)) < 0)
  2401. X    {
  2402. X      Msg(errno, "accept");
  2403. X      return;
  2404. X    }
  2405. X#endif                /* NAMEDPIPE */
  2406. X
  2407. X  p = (char *) &m;
  2408. X  left = sizeof(m);
  2409. X  while (left > 0)
  2410. X    {
  2411. X      len = read(ns, p, left);
  2412. X      if (len < 0 && errno == EINTR)
  2413. X    continue;
  2414. X      if (len <= 0)
  2415. X    break;
  2416. X      p += len;
  2417. X      left -= len;
  2418. X    }
  2419. X
  2420. X#ifdef NAMEDPIPE
  2421. X# ifndef BROKEN_PIPE
  2422. X  /* Reopen pipe to prevent EOFs at the select() call */
  2423. X  close(ServerSocket);
  2424. X  if ((ServerSocket = secopen(SockPath, O_RDONLY | O_NDELAY, 0)) < 0)
  2425. X    Panic(errno, "reopen fifo %s", SockPath);
  2426. X# endif
  2427. X#else
  2428. X  close(ns);
  2429. X#endif
  2430. X
  2431. X  if (len < 0)
  2432. X    {
  2433. X      Msg(errno, "read");
  2434. X      return;
  2435. X    }
  2436. X  if (left > 0)
  2437. X    {
  2438. X      if (left != sizeof(m))
  2439. X        Msg(0, "Message %d of %d bytes too small", left, sizeof(m));
  2440. X      else
  2441. X    debug("No data on socket.\n");
  2442. X      return;
  2443. X    }
  2444. X  debug2("*** RecMsg: type %d tty %s\n", m.type, m.m_tty);
  2445. X  for (display = displays; display; display = display->_d_next)
  2446. X    if (strcmp(d_usertty, m.m_tty) == 0)
  2447. X      break;
  2448. X  debug2("display: %s display %sfound\n", m.m_tty, display ? "" : "not ");
  2449. X  if (!display)
  2450. X    {
  2451. X      struct win *w;
  2452. X
  2453. X      for (w = windows; w; w = w->w_next)
  2454. X        if (!strcmp(m.m_tty, w->w_tty))
  2455. X      {
  2456. X            display = w->w_display;
  2457. X        debug2("but window %s %sfound.\n", m.m_tty, display ? "" : "deatached (ignoring) ");
  2458. X        break;
  2459. X          }
  2460. X    }
  2461. X
  2462. X  /* Remove the status to prevent garbage on the screen */
  2463. X  if (display && d_status)
  2464. X    RemoveStatus();
  2465. X
  2466. X  switch (m.type)
  2467. X    {
  2468. X    case MSG_WINCH:
  2469. X      if (display)
  2470. X        CheckScreenSize(1); /* Change fore */
  2471. X      break;
  2472. X    case MSG_CREATE:
  2473. X      if (display)
  2474. X    ExecCreate(&m);
  2475. X      break;
  2476. X    case MSG_CONT:
  2477. X    if (display && d_userpid != 0 && kill(d_userpid, 0) == 0)
  2478. X      break;        /* Intruder Alert */
  2479. X      debug2("RecMsg: apid=%d,was %d\n", m.m.attach.apid, display ? d_userpid : 0);
  2480. X      /* FALLTHROUGH */
  2481. X    case MSG_ATTACH:
  2482. X      if (CheckPid(m.m.attach.apid))
  2483. X    {
  2484. X      debug1("Attach attempt with bad pid(%d)\n", m.m.attach.apid);
  2485. X      Msg(0, "Attach attempt with bad pid(%d) !", m.m.attach.apid);
  2486. X          break;
  2487. X    }
  2488. X      if ((i = secopen(m.m_tty, O_RDWR | O_NDELAY, 0)) < 0)
  2489. X    {
  2490. X      debug1("ALERT: Cannot open %s!\n", m.m_tty);
  2491. X#ifdef NETHACK
  2492. X          if (nethackflag)
  2493. X        Msg(errno, 
  2494. X            "You can't open (%s). Perhaps there's a Monster behind it",
  2495. X            m.m_tty);
  2496. X          else
  2497. X#endif
  2498. X      Msg(errno, "Attach: Could not open %s", m.m_tty);
  2499. X      Kill(m.m.attach.apid, SIG_BYE);
  2500. X      break;
  2501. X    }
  2502. X#ifdef PASSWORD
  2503. X      if (!CheckPasswd(m.m.attach.password, m.m.attach.apid, m.m_tty))
  2504. X    {
  2505. X      debug3("RcvMsg:Checkpass(%s,%d,%s) failed\n",
  2506. X         m.m.attach.password, m.m.attach.apid, m.m_tty);
  2507. X      close(i);
  2508. X      break;
  2509. X    }
  2510. X#else
  2511. X# ifdef MULTIUSER
  2512. X      Kill(m.m.attach.apid, SIGCONT);
  2513. X# endif
  2514. X#endif                /* PASSWORD */
  2515. X      if (display)
  2516. X    {
  2517. X      debug("RecMsg: hey, why you disturb, we are not detached. hangup!\n");
  2518. X      close(i);
  2519. X      Kill(m.m.attach.apid, SIG_BYE);
  2520. X      Msg(0, "Attach msg ignored: We are not detached.");
  2521. X      break;
  2522. X    }
  2523. X
  2524. X#ifdef MULTIUSER
  2525. X      if (strcmp(m.m.attach.auser, LoginName))
  2526. X        if (*FindUserPtr(m.m.attach.auser) == 0)
  2527. X      {
  2528. X              write(i, "Access to session denied.\n", 26);
  2529. X          close(i);
  2530. X          Kill(m.m.attach.apid, SIG_BYE);
  2531. X          Msg(0, "Attach: access denied for user %s", m.m.attach.auser);
  2532. X          break;
  2533. X      }
  2534. X#endif
  2535. X
  2536. X      errno = 0;
  2537. X      debug2("RecMsg: apid %d is o.k. and we just opened '%s'\n", m.m.attach.apid, m.m_tty);
  2538. X      /* turn off iflag on a multi-attach... */
  2539. X      if (iflag && displays)
  2540. X    {
  2541. X      iflag = 0;
  2542. X      display = displays;
  2543. X#if defined(TERMIO) || defined(POSIX)
  2544. X      d_NewMode.tio.c_cc[VINTR] = VDISABLE;
  2545. X      d_NewMode.tio.c_lflag &= ~ISIG;
  2546. X#else /* TERMIO || POSIX */
  2547. X      d_NewMode.m_tchars.t_intrc = -1;
  2548. X#endif /* TERMIO || POSIX */
  2549. X      SetTTY(d_userfd, &d_NewMode);
  2550. X    }
  2551. X
  2552. X      /* create new display */
  2553. X      GetTTY(i, &Mode);
  2554. X      if (MakeDisplay(m.m.attach.auser, m.m_tty, m.m.attach.envterm, i, m.m.attach.apid, &Mode) == 0)
  2555. X        {
  2556. X      write(i, "Could not make display.\n", 24);
  2557. X      close(i);
  2558. X      Msg(errno, "Attach: could not make display for user %s", m.m.attach.auser);
  2559. X      Kill(m.m.attach.apid, SIG_BYE);
  2560. X      break;
  2561. X        }
  2562. X#ifdef ultrix
  2563. X      brktty(d_userfd);    /* for some strange reason this must be done */
  2564. X#endif
  2565. X#if defined(pyr) || defined(xelos) || defined(sequent)
  2566. X      /*
  2567. X       * Kludge for systems with braindamaged termcap routines,
  2568. X       * which evaluate $TERMCAP, regardless weather it describes
  2569. X       * the correct terminal type or not.
  2570. X       */
  2571. X      debug("unsetenv(TERMCAP) in case of a different terminal");
  2572. X      unsetenv("TERMCAP");
  2573. X#endif
  2574. X    
  2575. X      /*
  2576. X       * We reboot our Terminal Emulator. Forget all we knew about
  2577. X       * the old terminal, reread the termcap entries in .screenrc
  2578. X       * (and nothing more from .screenrc is read. Mainly because
  2579. X       * I did not check, weather a full reinit is save. jw) 
  2580. X       * and /etc/screenrc, and initialise anew.
  2581. X       */
  2582. X      if (extra_outcap)
  2583. X    free(extra_outcap);
  2584. X      if (extra_incap)
  2585. X    free(extra_incap);
  2586. X      extra_incap = extra_outcap = 0;
  2587. X      debug2("Message says size (%dx%d)\n", m.m.attach.columns, m.m.attach.lines);
  2588. X#ifdef ETCSCREENRC
  2589. X      if ((p = getenv("SYSSCREENRC")) == NULL)
  2590. X    StartRc(ETCSCREENRC);
  2591. X      else
  2592. X    StartRc(p);
  2593. X#endif
  2594. X      StartRc(RcFileName);
  2595. X      if (InitTermcap(m.m.attach.columns, m.m.attach.lines))
  2596. X    {
  2597. X      FreeDisplay();
  2598. X      Kill(m.m.attach.apid, SIG_BYE);
  2599. X      break;
  2600. X    }
  2601. X      InitTerm(m.m.attach.adaptflag);
  2602. X      if (displays->_d_next == 0)
  2603. X        (void) chsock();
  2604. X      signal(SIGHUP, SigHup);
  2605. X#ifdef UTMPOK
  2606. X      /*
  2607. X       * we set the Utmp slots again, if we were detached normally
  2608. X       * and if we were detached by ^Z.
  2609. X       */
  2610. X      RemoveLoginSlot();
  2611. X      if (displays->_d_next == 0)
  2612. X        for (wi = windows; wi; wi = wi->w_next)
  2613. X      if (wi->w_slot != (slot_t) -1)
  2614. X        SetUtmp(wi);
  2615. X#endif
  2616. X      SetMode(&d_OldMode, &d_NewMode);
  2617. X      SetTTY(d_userfd, &d_NewMode);
  2618. X      if (fore && fore->w_display == 0)
  2619. X        SetForeWindow(fore);
  2620. X      else
  2621. X        d_fore = 0;
  2622. X      Activate(0);
  2623. X      if (d_fore == 0)
  2624. X    ShowWindows();
  2625. X      if (displays->_d_next == 0 && console_window)
  2626. X    {
  2627. X      if (TtyGrabConsole(console_window->w_ptyfd, 1, "reattach") == 0)
  2628. X        Msg(0, "console %s is on window %d", HostName, console_window->w_number);
  2629. X    }
  2630. X      debug("activated...\n");
  2631. X      break;
  2632. X    case MSG_ERROR:
  2633. X      Msg(0, "%s", m.m.message);
  2634. X      break;
  2635. X    case MSG_HANGUP:
  2636. X      SigHup(SIGARG);
  2637. X      break;
  2638. X#ifdef REMOTE_DETACH
  2639. X    case MSG_DETACH:
  2640. X# ifdef POW_DETACH
  2641. X    case MSG_POW_DETACH:
  2642. X# endif                /* POW_DETACH */
  2643. X      for (display = displays; display; display = next)
  2644. X    {
  2645. X      next = display->_d_next;
  2646. X# ifdef POW_DETACH
  2647. X      if (m.type == MSG_POW_DETACH)
  2648. X        Detach(D_REMOTE_POWER);
  2649. X      else
  2650. X# endif                /* POW_DETACH */
  2651. X      if (m.type == MSG_DETACH)
  2652. X        Detach(D_REMOTE);
  2653. X    }
  2654. X      break;
  2655. X#endif
  2656. X    default:
  2657. X      Msg(0, "Invalid message (type %d).", m.type);
  2658. X    }
  2659. X}
  2660. X
  2661. X#if defined(_SEQUENT_) && !defined(NAMEDPIPE)
  2662. X#undef connect
  2663. X
  2664. X/*
  2665. X *  sequent_ptx socket emulation must have mode 000 on the socket!
  2666. X */
  2667. Xstatic int
  2668. Xsconnect(s, sapp, len)
  2669. Xint s, len;
  2670. Xstruct sockaddr *sapp;
  2671. X{
  2672. X  register struct sockaddr_un *sap;
  2673. X  struct stat st;
  2674. X  int x;
  2675. X
  2676. X  sap = (struct sockaddr_un *)sapp;
  2677. X  if (stat(sap->sun_path, &st))
  2678. X    return -1;
  2679. X  chmod(sap->sun_path, 0);
  2680. X  x = connect(s, (struct sockaddr *) sap, len);
  2681. X  chmod(sap->sun_path, st.st_mode);
  2682. X  return x;
  2683. X}
  2684. X#endif
  2685. X
  2686. Xint
  2687. Xchsock()
  2688. X{
  2689. X  int r, euid = geteuid();
  2690. X  if (euid != real_uid)
  2691. X    {
  2692. X      if (UserContext() <= 0)
  2693. X        return UserStatus();
  2694. X    }
  2695. X  r = chmod(SockPath, SOCKMODE);
  2696. X  if (euid != real_uid)
  2697. X    UserReturn(r);
  2698. X  return r;
  2699. X}
  2700. X
  2701. END_OF_FILE
  2702. if test 28896 -ne `wc -c <'socket.c'`; then
  2703.     echo shar: \"'socket.c'\" unpacked with wrong size!
  2704. fi
  2705. # end of 'socket.c'
  2706. fi
  2707. if test -f 'terminfo/test.txt' -a "${1}" != "-c" ; then 
  2708.   echo shar: Will not clobber existing file \"'terminfo/test.txt'\"
  2709. else
  2710. echo shar: Extracting \"'terminfo/test.txt'\" \(38899 characters\)
  2711. sed "s/^X//" >'terminfo/test.txt' <<'END_OF_FILE'
  2712. X
  2713. X <H(A)0?4h?5l
  2714. X    lqqqqqqqqqwwwqqqqqqqqqk                sssssssssssssssssssssssssssss
  2715. X    xMerry Chrxxxmas * Merx                \                           /
  2716. X    xry Christxxx * Merry x                 pr                       rp
  2717. X    xChristmasxxxMerry Chrx                   oqrs               srqo
  2718. X    xistmas * xxxry Christx                       ooppqqwqwqqppoo
  2719. X    tqqqqqqqqqjxmqqqqqqqqqu                             x x
  2720. X    tqqqqqqqqqq`qqqqqqqqqqu                             x x
  2721. X    tqqqqqqqqqkxlqqqqqqqqqu                             x x
  2722. X    xry Christxxx * Merry x                             x x
  2723. X    xChristmasxxxMerry Chrx                             x x
  2724. X    xistmas * xxxry Christx                             x x
  2725. X    xmas * MerxxxChristmasx                         srqqj mqqrs
  2726. X    mqqqqqqqqqvvvqqqqqqqqqj                     rqpo           opqr 0r
  2727. X9Hl9Hm9Hx9Hx
  2728. X8Hlq8Hmq8Hx 8Hx 
  2729. X7Hlqw7Hmqv7Hx x7Hx x
  2730. X6Hlqwq6Hmqvq6Hx x 6Hx x 
  2731. X5Hlqwq5Hmqvq5Hx x 5Hx x 
  2732. X4Hlqwq4Hmqvq4Hx x 4Hx x 
  2733. X3Hlqwq3Hmqvq3Hx x 3Hx x 
  2734. X2Hlqwq2Hmqvq2Hx x 2Hx x 
  2735. X1Hlqwq1Hmqvq1Hx x 1Hx x 
  2736. X0Hlqwq0Hmqvq0Hx x 0Hx x 
  2737. X9H/9H/
  2738. X9H/8H/ 
  2739. X69H/8H/ 8H /9H 9H/
  2740. X69H/68H/ 8H /8H /8H//
  2741. X69H/68H68H /9H/8H/8H/ 
  2742. X69H/68H/ 68H /69H/8H//8H /9H/
  2743. X68H/ 68H /68H//8H/8H 8H/ 9H/
  2744. X68H /68H/8H 8H/ 8H//9H 
  2745. X68H/68H/68H 8H/  8H//8H 9H/
  2746. X68H/68H/68Hs68H/ 8H//9H 9H 
  2747. X53Hsssssssssss
  2748. X68H/68H 68H68H//9H 8H /8H/ 9H/
  2749. X52Hs64Hs
  2750. X68H 68H/ 68H//69H 8H /8H/ 8H /9H/
  2751. X53Hrrrrrrrrrrr
  2752. X68H/ 69H/69Hs68H /8H/ 8H /9H/
  2753. X54Hqqqqqqqqq
  2754. X68H//69H 68H /68H/ 8H /8H/
  2755. X52Hsrqqqqqqqqqrs
  2756. X69H 68H /68H68H /8H/8H/
  2757. X51Hsr64Hrs
  2758. X69H/68H/ 68H /69H/8H//8H /9H/
  2759. X51Hrrqq62Hqqrr
  2760. X68H/ 68H /68H//8H/8H 8H/ 9H/
  2761. X55Hppppppp
  2762. X68H /68H/8H 8H/ 8H//9H 
  2763. X51Hrrq63Hqrr
  2764. X68H/68H/68H 8H/  8H//8H 9H/
  2765. X51Hrqpp62Hppqr
  2766. X68H/68H/68Hs68H/ 8H//9H 9H 
  2767. X50Hrqpppooooooopppqr
  2768. X68H/68H 68H68H//9H 8H /8H/ 9H/
  2769. X50Hqppoooooooooooppq
  2770. X68H 68H/ 68H//69H 8H /8H/ 8H /9H/
  2771. X55Hsssssss52Hooo       ooo57H. o f
  2772. X68H/ 69H/69Hs68H /8H/ 8H /9H/56H.f    
  2773. X53Hss62Hss53H  .f       
  2774. X68H//69H 68H /68H/ 8H /8H/53H       f
  2775. X48Hssssrrrrqqqqqrrrrssss50Hs               s
  2776. X69H 68H /68H68H /8H/8H/51H.    .      .
  2777. X47Hsssrrrrqqqqqqqqqrrrrsss51Hf    f  .   f
  2778. X69H/68H/ 68H /69H/8H//8H /9H51H        f .  
  2779. X47Hrrrqqqqpppppppppqqqqrss52H.    . o f
  2780. X68H/ 68H /68H//8H/8H 8H/ 9H/52Hf   .f    
  2781. X47Hqqqppppooooooooopppqrss52H   .f       .
  2782. X68Hs/68H/8H 8H/ 8H//9H 55Hf        f
  2783. X54Hsssssssss47Hqppoooo         oopqrss54H.o      .55H          
  2784. X68H/68H/68H 8H/  8H//8H 9H/54Hf       f51H.    .    
  2785. X52Hssrrrrrrrrrs47Hqpooo            opqrss53Hf 51Hf    f  .   f
  2786. X68H/68H/68Hs68H/ 8H//9H 53Hf  o      o51H        f .  
  2787. X46Hssssssrr63Hrrssssss47H     64H      9H 47Hf     o           o  .52H.    . o f
  2788. X68Hs68H68H//9H 8H /9H 47H  .         o o      f52Hf   .f    
  2789. X45Hsrrrrrrqqqqqqqqqqqqqqrrssrq49Hf  o    o     .     52H   .f       .
  2790. X68H/ 68H//69H 8H /9H  mqvqqqqqq0H lqwqqqqqq0H x x0H x x49H .     o      f
  2791. X45Hrqqqqqqppppppppppppppq1H mqvqqqqq1H lqwqqqqq1H x x1H x x50Hf   .o      . o55H          
  2792. X69H/69Hs68H /9H 2H mqvqqqq2H lqwqqqq2H x x2H x x50H    f       f  51
  2793. X45Hqppppppoooooooooooooo3H mqvqqq3H lqwqqq3H x x3H x x53Hf 62H   .51Hf    f  .   f
  2794. X69Hs68H /69H 4H mqvqq4H lqwqq4H x x4H x x47H.   o f  o      o f51H        f 
  2795. X45Hpoooooo             5H mqvq5H lqwq5H x x5H x x49H  o    o      o47Hf     o           o  .
  2796. X44Hrrrrrrrrrrrrrrrrrrrrrrrrrrrrr45H       64H        6H mqv6H lqw6H x x6H x x47Ho   
  2797. X7H mq7H lq7H x 7H x 47H       .    o o      o49Hf  o    o     .     52H   .f       .
  2798. X8H m8H l8H x8H x45H.   o  o f  o        .   .49H .     o      f55Hf        f
  2799. X9H 9H 9H 9H 45Hf          o      o  f . f50Hf   .o      . o55H          
  2800. X5H#3 Cheers! 
  2801. X5H#4 Cheers! 
  2802. X45H  .  o    o    .   o   f  50H    f       f  51H.    .      .
  2803. X47Hf .    o  .  f o     f53Hf 62H   .51Hf    f  .   f
  2804. X47H  f       f  f        47H.   o f  o      o f51H        f .  
  2805. X49H  o    o      o47Hf     o           o  .52H.    . o f
  2806. X47Ho     o           o47H  .         o o      f52Hf   .f    
  2807. X47H       .    o o      o49Hf  o    o     .     52H   .f       .
  2808. X45H.   o  o f  o        .   .49H .     o      f55Hf        f
  2809. X45Hf          o      o  f . f50Hf   .o      . o55H          
  2810. X45H  .  o    o    .   o   f  50H    f       f  51H.    .      .
  2811. X47Hf .    o  .  f o     f53Hf 62H   .51Hf    f  .   f
  2812. X47H  f       f  f        47H.   o f  o      o f51H        f .  
  2813. X49H  o    o      o47Hf     o           o  .52H.    . o f
  2814. X47Ho     o           o47H  .         o o      f52Hf   .f    
  2815. X47H       .    o o      o49Hf  o    o     .     52H   .f       .
  2816. X45H.   o  o f  o        .   .49H .     o      f55Hf        f
  2817. X45Hf          o      o  f . f50Hf   .o      . o55H          
  2818. X45H  .  o    o    .   o   f  50H    f       f  51H.    .      .
  2819. X47Hf .    o  .  f o     f53Hf 62H   .51Hf    f  .   f
  2820. X47H  f       f  f        47H.   o f  o      o f51H        f .  
  2821. X49H  o    o      o47Hf     o           o  .52H.    . o f
  2822. X47Ho     o           o47H  .         o o      f52Hf   .f    
  2823. X47H       .    o o      o49Hf  o    o     .     52H   .f       .
  2824. X45H.   o  o f  o        .   .49H .     o      f55Hf        f
  2825. X45Hf          o      o  f . f50Hf   .o      . o55H          
  2826. X45H  .  o    o    .   o   f  50H    f       f  51H.    .      .
  2827. X47Hf .    o  .  f o     f53Hf 62H   .51Hf    f  .   f
  2828. X47H  f       f  f        47H.   o f  o      o f51H        f .  
  2829. X49H  o    o      o47Hf     o           o  .52H.    . o f
  2830. X47Ho     o           o47H  .         o o      f52Hf   .f    
  2831. X47H       .    o o      o49Hf  o    o     .     52H   .f       .
  2832. X45H.   o  o f  o        .   .49H .     o      f55Hf        f
  2833. X45Hf          o      o  f . f50Hf   .o      . o55H          
  2834. X45H  .  o    o    .   o   f  50H    f       f  51H.    .      .
  2835. X47Hf .    o  .  f o     f53Hf 62H   .51Hf    f  .   f
  2836. X47H  f       f  f        47H.   o f  o      o f51H        f .  
  2837. X49H  o    o      o47Hf     o           o  .52H.    . o f
  2838. X47Ho     o           o47H  .         o o      f52Hf   .f    
  2839. X47H       .    o o      o49Hf  o    o     .     52H   .f       .
  2840. X45H.   o  o f  o        .   .49H .     o      f55Hf        f
  2841. X45Hf          o      o  f . f50Hf   .o      . o55H          
  2842. X45H  .  o    o    .   o   f  50H    f       f  51H.    .      .
  2843. X47Hf .    o  .  f o     f53Hf 62H   .51Hf    f  .   f
  2844. X47H  f       f  f        47H.   o f  o      o f51H        f .  
  2845. X49H  o    o      o47Hf     o           o  .52H.    . o f
  2846. X47Ho     o           o47H  .         o o      f52Hf   .f    
  2847. X47H       .    o o      o49Hf  o    o     .     52H   .f       .
  2848. X45H.   o  o f  o        .   .49H .     o      f55Hf        f
  2849. X45Hf          o      o  f . f50Hf   .o      . o55H          
  2850. X45H  .  o    o    .   o   f  50H    f       f  51H.    .      .
  2851. XH#5
  2852. XH#5
  2853. X47Hf .    o  .  f o     f53Hf 62H   .51Hf    f  .   f
  2854. X47H  f       f  f        47H.   o f  o      o f51H        f .  
  2855. X1H       /ooooooooooooooo\
  2856. X49H  o    o      o47Hf     o           o  .52H.    . o f
  2857. X1H      /   sss     sss   \
  2858. X47Ho     o           o47H  .         o o      f52Hf   .f    
  2859. X1H      x  (sOs)   (sOs)  x
  2860. X47H       .    o o      o49Hf  o    o     .     52H   .f       .
  2861. X1H      x        `        x
  2862. X45H.   o  o f  o        .   .49H .     o      f55Hf        f
  2863. X1H       \  \sssssssss/  /
  2864. X45Hf          o      o  f . f50Hf   .o      . o55H          
  2865. X1H        \             /
  2866. X45H  .  o    o    .   o   f  50H    f       f  51H.    .      .
  2867. X1H         \sssssssssss/
  2868. X47Hf .    o  .  f o     f53Hf 62H   .51Hf    f  .   f
  2869. X1H          ooppqqrrsss
  2870. X47H  f       f  f        47H.   o f  o      o f51H        f .  
  2871. X1H          ooppqqrrsss
  2872. X49H  o    o      o47Hf     o           o  .52H.    . o f
  2873. X1H          ooppqqrrsss
  2874. X47Ho     o           o47H  .         o o      f52Hf   .f    
  2875. X1H          ooppqqrrsss
  2876. X47H       .    o o      o49Hf  o    o     .     52H   .f       .
  2877. X1H          ooppqqrrsss
  2878. X45H.   o  o f  o        .   .49H .     o      f55Hf        f
  2879. X1H          ooppqqrrsss
  2880. X45Hf          o      o  f . f50Hf   .o      . o55H          
  2881. X1H          ooppqqrrsss45H  .  o    o    .   o   f  50H    f       f  51H.    .      .
  2882. XHM      x        `        x
  2883. X47Hf .    o  .  f o     f53Hf 62H   .51Hf    f  .   f
  2884. XHM      x  (sOs)   (sOs)  x
  2885. X47H  f       f  f        47H.   o f  o      o f51H        f .  
  2886. XHM      /   sss     sss   \
  2887. X49H  o    o      o47Hf     o           o  .52H.    . o f
  2888. XHM       /ooooooooooooooo\ 
  2889. X47Ho     o           o47H  .         o o      f52Hf   .f    
  2890. XHM
  2891. X47H       .    o o      o49Hf  o    o     .     52H   .f       .
  2892. XHM
  2893. X45H.   o  o f  o        .   .49H .     o      f55Hf        f
  2894. XHM
  2895. X45Hf          o      o  f . f50Hf   .o      . o55H          
  2896. XHM
  2897. X45H  .  o    o    .   o   f  50H    f       f  51H.    .      .
  2898. X1H        \             /
  2899. X47Hf .    o  .  f o     f53Hf 62H   .51Hf    f  .   f
  2900. X1H         \sssssssssss/
  2901. X47H  f       f  f        47H.   o f  o      o f51H        f .  
  2902. X1H          ooppqqrrsss
  2903. X49H  o    o      o47Hf     o           o  .52H.    . o f
  2904. X1H          ooppqqrrsss
  2905. X47Ho     o           o47H  .         o o      f52Hf   .f    
  2906. X1H          ooppqqrrsss
  2907. X47H       .    o o      o49Hf  o    o     .     52H   .f       .
  2908. X1H          ooppqqrrsss
  2909. X45H.   o  o f  o        .   .49H .     o      f55Hf        f
  2910. X1H          ooppqqrrsss45Hf          o      o  f . f50Hf   .o      . o55H          
  2911. XHM      /   sss     sss   \
  2912. X45H  .  o    o    .   o   f  50H    f       f  51H.    .      .
  2913. XHM       /ooooooooooooooo\ 
  2914. X47Hf .    o  .  f o     f53Hf 62H   .51Hf    f  .   f
  2915. XHM
  2916. X47H  f       f  f        47H.   o f  o      o f51H        f .  
  2917. XHM
  2918. X49H  o    o      o47Hf     o           o  .52H.    . o f
  2919. X1H          ooppqqrrsss
  2920. X47Ho     o           o47H  .         o o      f52Hf   .f    
  2921. X1H          ooppqqrrsss
  2922. X47H       .    o o      o49Hf  o    o     .     52H   .f       .
  2923. X1H          ooppqqrrsss
  2924. X45H.   o  o f  o        .   .49H .     o      f55Hf        f
  2925. X1H          ooppqqrrsss45Hf          o      o  f . f50Hf   .o      . o55H          
  2926. XHM       /ooooooooooooooo\ 
  2927. X45H  .  o    o    .   o   f  50H    f       f  51H.    .      .
  2928. XHM
  2929. X47Hf .    o  .  f o     f53Hf 62H   .51Hf    f  .   f
  2930. XHM
  2931. X47H  f       f  f        47H.   o f  o      o f51H        f .  
  2932. XHM
  2933. X49H  o    o      o47Hf     o           o  .52H.    . o f
  2934. X1H         \sssssssssss/
  2935. X47Ho     o           o47H  .         o o      f52Hf   .f    
  2936. X1H          ooppqqrrsss
  2937. X47H       .    o o      o49Hf  o    o     .     52H   .f       .
  2938. X1H          ooppqqrrsssr
  2939. X45H.   o  o f  o        .   .49H .     o      f55Hf        f
  2940. X45Hf          o      o  f . f50Hf   .o      . o55H          
  2941. X5HJin
  2942. X45H  .  o    o    .   o   f  50H    f       f  51H.    .      .
  2943. X8Hgle
  2944. X47Hf .    o  .  f o     f53Hf 62H   .51Hf    f  .   f
  2945. X47H  f       f  f        47H.   o f  o      o f51H        f .  
  2946. X49H  o    o      o47Hf     o           o  .52H.    . o f
  2947. X47Ho     o           o47H  .         o o      f52Hf   .f    
  2948. X2HBells,
  2949. X47H       .    o o      o49Hf  o    o     .     52H   .f       .
  2950. X45H.   o  o f  o        .   .49H .     o      f55Hf        f
  2951. X45Hf          o      o  f . f50Hf   .o      . o55H          
  2952. X45H  .  o    o    .   o   f  50H    f       f  51H.    .      .
  2953. X47Hf .    o  .  f o     f53Hf 62H   .51Hf    f  .   f
  2954. X47H  f       f  f        47H.   o f  o      o f51H        f .  
  2955. X49H  o    o      o47Hf     o           o  .52H.    . o f
  2956. X47Ho     o           o47H  .         o o      f52Hf   .f    
  2957. X9HJin
  2958. X47H       .    o o      o49Hf  o    o     .     52H   .f       .
  2959. X2Hgle
  2960. X45H.   o  o f  o        .   .49H .     o      f55Hf        f
  2961. X45Hf          o      o  f . f50Hf   .o      . o55H          
  2962. X45H  .  o    o    .   o   f  50H    f       f  51H.    .      .
  2963. X47Hf .    o  .  f o     f53Hf 62H   .51Hf    f  .   f
  2964. X6HBells,
  2965. X47H  f       f  f        47H.   o f  o      o f51H        f .  
  2966. X49H  o    o      o47Hf     o           o  .52H.    . o f
  2967. X47Ho     o           o47H  .         o o      f52Hf   .f    
  2968. X47H       .    o o      o49Hf  o    o     .     52H   .f       .
  2969. X45H.   o  o f  o        .   .49H .     o      f55Hf        f
  2970. X45Hf          o      o  f . f50Hf   .o      . o55H          
  2971. X45H  .  o    o    .   o   f  50H    f       f  51H.    .      .
  2972. X47Hf .    o  .  f o     f53Hf 62H   .51Hf    f  .   f
  2973. X5HJin
  2974. X47H  f       f  f        47H.   o f  o      o f51H        f .  
  2975. X8Hgle
  2976. X49H  o    o      o47Hf     o           o  .52H.    . o f
  2977. X47Ho     o           o47H  .         o o      f52Hf   .f    
  2978. X47H       .    o o      o49Hf  o    o     .     52H   .f       .
  2979. X45H.   o  o f  o        .   .49H .     o      f55Hf        f
  2980. X2Hall
  2981. X45Hf          o      o  f . f50Hf   .o      . o55H          
  2982. X45H  .  o    o    .   o   f  50H    f       f  51H.    .      .
  2983. X47Hf .    o  .  f o     f53Hf 62H   .51Hf    f  .   f
  2984. X47H  f       f  f        47H.   o f  o      o f51H        f .  
  2985. X6Hthe
  2986. X49H  o    o      o47Hf     o           o  .52H.    . o f
  2987. X47Ho     o           o47H  .         o o      f52Hf   .f    
  2988. X47H       .    o o      o49Hf  o    o     .     52H   .f       .
  2989. X45H.   o  o f  o        .   .49H .     o      f55Hf        f
  2990. X0Hway,
  2991. X45Hf          o      o  f . f50Hf   .o      . o55H          
  2992. X45H  .  o    o    .   o   f  50H    f       f  51H.    .      .
  2993. X47Hf .    o  .  f o     f53Hf 62H   .51Hf    f  .   f
  2994. X47H  f       f  f        47H.   o f  o      o f51H        f .  
  2995. X49H  o    o      o47Hf     o           o  .52H.    . o f
  2996. X47Ho     o           o47H  .         o o      f52Hf   .f    
  2997. X47H       .    o o      o49Hf  o    o     .     52H   .f       .
  2998. X45H.   o  o f  o        .   .49H .     o      f55Hf        f
  2999. X5HOh!
  3000. X45Hf          o      o  f . f50Hf   .o      . o55H          
  3001. X45H  .  o    o    .   o   f  50H    f       f  51H.    .      .
  3002. X47Hf .    o  .  f o     f53Hf 62H   .51Hf    f  .   f
  3003. X47H  f       f  f        47H.   o f  o      o f51H        f .  
  3004. X0HWhat
  3005. X49H  o    o      o47Hf     o           o  .52H.    . o f
  3006. X47Ho     o           o47H  .         o o      f52Hf   .f    
  3007. X47H       .    o o      o49Hf  o    o     .     52H   .f       .
  3008. X45H.   o  o f  o        .   .49H .     o      f55Hf        f
  3009. X5Hfun
  3010. X45Hf          o      o  f . f50Hf   .o      . o55H          
  3011. X45H  .  o    o    .   o   f  50H    f       f  51H.    .      .
  3012. X47Hf .    o  .  f o     f53Hf 62H   .51Hf    f  .   f
  3013. X47H  f       f  f        47H.   o f  o      o f51H        f .  
  3014. X9Hit
  3015. X49H  o    o      o47Hf     o           o  .52H.    . o f
  3016. X2His
  3017. X47Ho     o           o47H  .         o o      f52Hf   .f    
  3018. X47H       .    o o      o49Hf  o    o     .     52H   .f       .
  3019. X45H.   o  o f  o        .   .49H .     o      f55Hf        f
  3020. X45Hf          o      o  f . f50Hf   .o      . o55H          
  3021. X5Hto
  3022. X45H  .  o    o    .   o   f  50H    f       f  51H.    .      .
  3023. X47Hf .    o  .  f o     f53Hf 62H   .51Hf    f  .   f
  3024. X47H  f       f  f        47H.   o f  o      o f51H        f .  
  3025. X49H  o    o      o47Hf     o           o  .52H.    . o f
  3026. X8Hride,
  3027. X47Ho     o           o47H  .         o o      f52Hf   .f    
  3028. X47H       .    o o      o49Hf  o    o     .     52H   .f       .
  3029. X45H.   o  o f  o        .   .49H .     o      f55Hf        f
  3030. X45Hf          o      o  f . f50Hf   .o      . o55H          
  3031. X45H  .  o    o    .   o   f  50H    f       f  51H.    .      .
  3032. X47Hf .    o  .  f o     f53Hf 62H   .51Hf    f  .   f
  3033. X47H  f       f  f        47H.   o f  o      o f51H        f .  
  3034. X49H  o    o      o47Hf     o           o  .52H.    . o f
  3035. X5HOn
  3036. X47Ho     o           o47H  .         o o      f52Hf   .f    
  3037. X8Ha
  3038. X47H       .    o o      o49Hf  o    o     .     52H   .f       .
  3039. X45H.   o  o f  o        .   .49H .     o      f55Hf        f
  3040. X45Hf          o      o  f . f50Hf   .o      . o55H          
  3041. X45H  .  o    o    .   o   f  50H    f       f  51H.    .      .
  3042. X0Hone-
  3043. X47Hf .    o  .  f o     f53Hf 62H   .51Hf    f  .   f
  3044. X4Hhorse
  3045. X47H  f       f  f        47H.   o f  o      o f51H        f .  
  3046. X49H  o    o      o47Hf     o           o  .52H.    . o f
  3047. X47Ho     o           o47H  .         o o      f52Hf   .f    
  3048. X47H       .    o o      o49Hf  o    o     .     52H   .f       .
  3049. X45H.   o  o f  o        .   .49H .     o      f55Hf        f
  3050. X45Hf          o      o  f . f50Hf   .o      . o55H          
  3051. X45H  .  o    o    .   o   f  50H    f       f  51H.    .      .
  3052. X47Hf .    o  .  f o     f53Hf 62H   .51Hf    f  .   f
  3053. X0Hop
  3054. X47H  f       f  f        47H.   o f  o      o f51H        f .  
  3055. X2Hen
  3056. X49H  o    o      o47Hf     o           o  .52H.    . o f
  3057. X47Ho     o           o47H  .         o o      f52Hf   .f    
  3058. X47H       .    o o      o49Hf  o    o     .     52H   .f       .
  3059. X45H.   o  o f  o        .   .49H .     o      f55Hf        f
  3060. X45Hf          o      o  f . f50Hf   .o      . o55H          
  3061. X45H  .  o    o    .   o   f  50H    f       f  51H.    .      .
  3062. X47Hf .    o  .  f o     f53Hf 62H   .51Hf    f  .   f
  3063. X47H  f       f  f        47H.   o f  o      o f51H        f .  
  3064. X5Hsleigh.
  3065. X49H  o    o      o47Hf     o           o  .52H.    . o f
  3066. X47Ho     o           o47H  .         o o      f52Hf   .f    
  3067. X47H       .    o o      o49Hf  o    o     .     52H   .f       .
  3068. X45H.   o  o f  o        .   .49H .     o      f55Hf        f
  3069. X45Hf          o      o  f . f50Hf   .o      . o55H          
  3070. X45H  .  o    o    .   o   f  50H    f       f  51H.    .      .
  3071. X47Hf .    o  .  f o     f53Hf 62H   .51Hf    f  .   f
  3072. X47H  f       f  f        47H.   o f  o      o f51H        f .  
  3073. X49H  o    o      o47Hf     o           o  .52H.    . o f
  3074. X47Ho     o           o47H  .         o o      f52Hf   .f    
  3075. X47H       .    o o      o49Hf  o    o     .     52H   .f       .
  3076. X45H.   o  o f  o        .   .49H .     o      f55Hf        f
  3077. X45Hf          o      o  f . f50Hf   .o      . o55H          
  3078. X45H  .  o    o    .   o   f  50H    f       f  51H.    .      .
  3079. X47Hf .    o  .  f o     f53Hf 62H   .51Hf    f  .   f
  3080. X47H  f       f  f        47H.   o f  o      o f51H        f .  
  3081. X49H  o    o      o47Hf     o           o  .52H.    . o f
  3082. X47Ho     o           o47H  .         o o      f52Hf   .f    
  3083. X47H       .    o o      o49Hf  o    o     .     52H   .f       .
  3084. X45H.   o  o f  o        .   .49H .     o      f55Hf        f
  3085. X45Hf          o      o  f . f50Hf   .o      . o55H          
  3086. X45H  .  o    o    .   o   f  50H    f       f  51H.    .      .
  3087. X47Hf .    o  .  f o     f53Hf 62H   .51Hf    f  .   f
  3088. X47H  f       f  f        47H.   o f  o      o f51H        f .  
  3089. X49H  o    o      o47Hf     o           o  .52H.    . o f
  3090. X47Ho     o           o47H  .         o o      f52Hf    f    
  3091. X47H  f       f  f        47H.   o f  o      o f51H        f .  
  3092. X49H  o    o      o47Hf     o           o  .52H.    . o f
  3093. X47Ho     o           o47H  .         o o      f52Hf   .f    
  3094. X47H       .    o o      o49Hf  o    o     .     52H   .f       .
  3095. X45H.   o  o f  o        .   .49H .     o      f55Hf        f
  3096. X45Hf          o      o  f . f50Hf   .o      . o55H          
  3097. X45H  .  o    o    .   o   f  50H    f       f  51H.    .      .
  3098. X47Hf .    o  .  f o     f53Hf 62H   .51Hf    f  .   f
  3099. X47H  f       f  f        47H.   o f  o      o f51H        f .  
  3100. X49H  o    o      o47Hf     o           o  .52H.    . o f
  3101. X47Ho     o           o47H  .         o o      f52Hf   .f    
  3102. X47H       .    o o      o49Hf  o    o     .     52H   .f       .
  3103. X45H.   o  o f  o        .   .49H .     o      f55Hf        f
  3104. X45Hf          o      o  f . f50Hf   .o      . o55H          
  3105. X45H  .  o    o    .   o   f  50H    f       f  51H.    .      .
  3106. X47Hf .    o  .  f o     f53Hf 62H   .51Hf    f  .   f
  3107. X47H  f       f  f        47H.   o f  o      o f51H        f .  
  3108. X49H  o    o      o47Hf     o           o  .52H.    . o f
  3109. X47Ho     o           o47H  .         o o      f52Hf   .f    
  3110. X47H       .    o o      o49Hf  o    o     .     52H   .f       .
  3111. X45H.   o  o f  o        .   .49H .     o      f55Hf        f
  3112. X45Hf          o      o  f . f50Hf   .o      . o55H          
  3113. X45H  .  o    o    .   o   f  50H    f       f  51H.    .      .
  3114. X47Hf .    o  .  f o     f53Hf 62H   .51Hf    f  .   f
  3115. X47H  f       f  f        47H.   o f  o      o f51H        f .  
  3116. X49H  o    o      o47Hf     o           o  .52H.    . o f
  3117. X47Ho     o           o47H  .         o o      f52Hf   .f    
  3118. X47H       .    o o      o49Hf  o    o     .     52H   .f       .
  3119. X45H.   o  o f  o        .   .49H .     o      f55Hf        f
  3120. X45Hf          o      o  f . f50Hf   .o      . o55H          
  3121. X45H  .  o    o    .   o   f  50H    f       f  51H.    .      .
  3122. X47Hf .    o  .  f o     f53Hf 62H   .51Hf    f  .   f
  3123. X47H  f       f  f        47H.   o f  o      o f51H        f .  
  3124. X49H  o    o      o47Hf     o           o  .52H.    . o f
  3125. X47Ho     o           o47H  .         o o      f52Hf   .f    
  3126. X47H       .    o o      o49Hf  o    o     .     52H   .f       .
  3127. X45H.   o  o f  o        .   .49H .     o      f55Hf        f
  3128. X45Hf          o      o  f . f50Hf   .o      . o55H          
  3129. X45H  .  o    o    .   o   f  50H    f       f  51H.    .      .
  3130. X47Hf .    o  .  f o     f53Hf 62H   .51Hf    f  .   f
  3131. X47H  f       f  f        47H.   o f  o      o f51H        f .  
  3132. X49H  o    o      o47Hf     o           o  .52H.    . o f
  3133. X47Ho     o           o47H  .         o o      f52Hf    f    
  3134. X47H            o o      o49Hf  o    o           52H             
  3135. X45H.   o  o    o             49H               55H          
  3136. X45Hf          o      o       50H               55H          
  3137. X45H                   
  3138. X47Ho     o           o47H  .         o o      f52Hf    f    
  3139. X47H  f       f  f        47H.   o f  o      o f51H        f .  
  3140. X49H  o    o      o47Hf     o           o  .52H.    . o f
  3141. X47Ho     o           o47H  .         o o      f52Hf   .f    
  3142. X47H       .    o o      o49Hf  o    o     .     52H   .f       .
  3143. X45H.   o  o f  o        .   .49H .     o      f55Hf        f
  3144. X45Hf          o      o  f . f50Hf   .o      . o55H          
  3145. X45H  .  o    o    .   o   f  50H    f       f  51H.    .      .
  3146. X47Hf .    o  .  f o     f53Hf 62H   .51Hf    f  .   f
  3147. X47H  f       f  f        47H.   o f  o      o f51H        f .  
  3148. X49H  o    o      o47Hf     o           o  .52H.    . o f
  3149. X47Ho     o           o47H  .         o o      f52Hf   .f    
  3150. X47H       .    o o      o49Hf  o    o     .     52H   .f       .
  3151. X45H.   o  o f  o        .   .49H .     o      f55Hf        f
  3152. X45Hf          o      o  f . f50Hf   .o      . o55H          
  3153. X45H  .  o    o    .   o   f  50H    f       f  51H.    .      .
  3154. X47Hf .    o  .  f o     f53Hf 62H   .51Hf    f  .   f
  3155. X47H  f       f  f        47H.   o f  o      o f51H        f .  
  3156. X49H  o    o      o47Hf     o           o  .52H.    . o f
  3157. X47Ho     o           o47H  .         o o      f52Hf   .f    
  3158. X47H       .    o o      o49Hf  o    o     .     52H   .f       .
  3159. X45H.   o  o f  o        .   .49H .     o      f55Hf        f
  3160. X45Hf          o      o  f . f50Hf   .o      . o55H          
  3161. X45H  .  o    o    .   o   f  50H    f       f  51H.    .      .
  3162. X47Hf .    o  .  f o     f53Hf 62H   .51Hf    f  .   f
  3163. X47H  f       f  f        47H.   o f  o      o f51H        f .  
  3164. X49H  o    o      o47Hf     o           o  .52H.    . o f
  3165. X47Ho     o           o47H  .         o o      f52Hf   .f    
  3166. X47H       .    o o      o49Hf  o    o     .     52H   .f       .
  3167. X45H.   o  o f  o        .   .49H .     o      f55Hf        f
  3168. X45Hf          o      o  f . f50Hf   .o      . o55H          
  3169. X45H  .  o    o    .   o   f  50H    f       f  51H.    .      .
  3170. X47Hf .    o  .  f o     f53Hf 62H   .51Hf    f  .   f
  3171. X47H  f       f  f        47H.   o f  o      o f51H        f .  
  3172. X49H  o    o      o47Hf     o           o  .52H.    . o f
  3173. X47Ho     o           o47H  .         o o      f52Hf   .f    
  3174. X47H       .    o o      o49Hf  o    o     .     52H   .f       .
  3175. X45H.   o  o f  o        .   .49H .     o      f55Hf        f
  3176. X45Hf          o      o  f . f50Hf   .o      . o55H          
  3177. X45H  .  o    o    .   o   f  50H    f       f  51H.    .      .
  3178. X47Hf .    o  .  f o     f53Hf 62H   .51Hf    f  .   f
  3179. X47H  f       f  f        47H.   o f  o      o f51H        f .  
  3180. X49H  o    o      o47Hf     o           o  .52H.    . o f
  3181. X47Ho     o           o47H  .         o o      f52Hf    f    
  3182. X47H            o o      o49Hf  o    o           52H             
  3183. X45H.   o  o    o             49H               55H          
  3184. X45Hf          o      o       50H               55H          
  3185. X45H                   
  3186. X5H5HMerry Christmas
  3187. X5H
  3188. X5H0H-
  3189. X5H
  3190. X47Ho     o           o47H  .         o o      f52Hf   .f    
  3191. X47H       .    o o      o49Hf  o    o     .     52H   .f       .
  3192. X45H.   o  o f  o        .   .49H .     o      f55Hf        f
  3193. X45Hf          o      o  f . f50Hf   .o      . o55H          
  3194. X45H  .  o    o    .   o   f  50H    f       f  51H.    .      .
  3195. X47Hf .    o  .  f o     f53Hf 62H   .51Hf    f  .   f
  3196. X47H  f       f  f        47H.   o f  o      o f51H        f .  
  3197. X49H  o    o      o47Hf     o           o  .52H.    . o f
  3198. X47Ho     o           o47H  .         o o      f52Hf   .f    
  3199. X47H       .    o o      o49Hf  o    o     .     52H   .f       .
  3200. X45H.   o  o f  o        .   .49H .     o      f55Hf        f
  3201. X45Hf          o      o  f . f50Hf   .o      . o55H          
  3202. X45H  .  o    o    .   o   f  50H    f       f  51H.    .      .
  3203. X47Hf .    o  .  f o     f53Hf 62H   .51Hf    f  .   f
  3204. X47H  f       f  f        47H.   o f  o      o f51H        f .  
  3205. X49H  o    o      o47Hf     o           o  .52H.    . o f
  3206. X47Ho     o           o47H  .         o o      f52Hf    f    
  3207. X47H            o o      o49Hf  o    o           52H             
  3208. X45H.   o  o    o             49H               55H          
  3209. X45Hf          o      o       50H               55H          
  3210. X45H                   
  3211. X47Ho     o           o47H  .         o o      f52Hf    f    
  3212. X47H  f       f  f        47H.   o f  o      o f51H        f .  
  3213. X49H  o    o      o47Hf     o           o  .52H.    . o f
  3214. X47Ho     o           o47H  .         o o      f52Hf   .f    
  3215. X47H       .    o o      o49Hf  o    o     .     52H   .f       .
  3216. X45H.   o  o f  o        .   .49H .     o      f55Hf        f
  3217. X45Hf          o      o  f . f50Hf   .o      . o55H          
  3218. X45H  .  o    o    .   o   f  50H    f       f  51H.    .      .
  3219. X47Hf .    o  .  f o     f53Hf 62H   .51Hf    f  .   f
  3220. X47H  f       f  f        47H.   o f  o      o f51H        f .  
  3221. X49H  o    o      o47Hf     o           o  .52H.    . o f
  3222. X47Ho     o           o47H  .         o o      f52Hf   .f    
  3223. X47H       .    o o      o49Hf  o    o     .     52H   .f       .
  3224. X45H.   o  o f  o        .   .49H .     o      f55Hf        f
  3225. X45Hf          o      o  f . f50Hf   .o      . o55H          
  3226. X45H  .  o    o    .   o   f  50H    f       f  51H.    .      .
  3227. X47Hf .    o  .  f o     f53Hf 62H   .51Hf    f  .   f
  3228. X47H  f       f  f        47H.   o f  o      o f51H        f .  
  3229. X49H  o    o      o47Hf     o           o  .52H.    . o f
  3230. X47Ho     o           o47H  .         o o      f52Hf   .f    
  3231. X47H       .    o o      o49Hf  o    o     .     52H   .f       .
  3232. X45H.   o  o f  o        .   .49H .     o      f55Hf        f
  3233. X45Hf          o      o  f . f50Hf   .o      . o55H          
  3234. X45H  .  o    o    .   o   f  50H    f       f  51H.    .      .
  3235. X47Hf .    o  .  f o     f53Hf 62H   .51Hf    f  .   f
  3236. X47H  f       f  f        47H.   o f  o      o f51H        f .  
  3237. X49H  o    o      o47Hf     o           o  .52H.    . o f
  3238. X47Ho     o           o47H  .         o o      f52Hf   .f    
  3239. X47H       .    o o      o49Hf  o    o     .     52H   .f       .
  3240. X45H.   o  o f  o        .   .49H .     o      f55Hf        f
  3241. X45Hf          o      o  f . f50Hf   .o      . o55H          
  3242. X45H  .  o    o    .   o   f  50H    f       f  51H.    .      .
  3243. X47Hf .    o  .  f o     f53Hf 62H   .51Hf    f  .   f
  3244. X47H  f       f  f        47H.   o f  o      o f51H        f .  
  3245. X49H  o    o      o47Hf     o           o  .52H.    . o f
  3246. X47Ho     o           o47H  .         o o      f52Hf   .f    
  3247. X47H       .    o o      o49Hf  o    o     .     52H   .f       .
  3248. X45H.   o  o f  o        .   .49H .     o      f55Hf        f
  3249. X45Hf          o      o  f . f50Hf   .o      . o55H          
  3250. X45H  .  o    o    .   o   f  50H    f       f  51H.    .      .
  3251. X47Hf .    o  .  f o     f53Hf 62H   .51Hf    f  .   f
  3252. X47H  f       f  f        47H.   o f  o      o f51H        f .  
  3253. X49H  o    o      o47Hf     o           o  .52H.    . o f
  3254. X47Ho     o           o47H  .         o o      f52Hf    f    
  3255. X47H            o o      o49Hf  o    o           52H             
  3256. X45H.   o  o    o             49H               55H          
  3257. X45Hf          o      o       50H               55H          
  3258. X45H                   
  3259. X1H?4l
  3260. X
  3261. END_OF_FILE
  3262. echo shar: 3589 control characters may be missing from \"'terminfo/test.txt'\"
  3263. if test 38899 -ne `wc -c <'terminfo/test.txt'`; then
  3264.     echo shar: \"'terminfo/test.txt'\" unpacked with wrong size!
  3265. fi
  3266. # end of 'terminfo/test.txt'
  3267. fi
  3268. echo shar: End of archive 5 \(of 10\).
  3269. cp /dev/null ark5isdone
  3270. MISSING=""
  3271. for I in 1 2 3 4 5 6 7 8 9 10 ; do
  3272.     if test ! -f ark${I}isdone ; then
  3273.     MISSING="${MISSING} ${I}"
  3274.     fi
  3275. done
  3276. if test "${MISSING}" = "" ; then
  3277.     echo You have unpacked all 10 archives.
  3278.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  3279. else
  3280.     echo You still need to unpack the following archives:
  3281.     echo "        " ${MISSING}
  3282. fi
  3283. ##  End of shell archive.
  3284. exit 0
  3285.