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

  1. Newsgroups: comp.sources.unix
  2. From: mlschroe@immd4.informatik.uni-erlangen.de (Michael Schroeder)
  3. Subject: v26i303: screen-3.5 - screen manager with VT100/ANSI terminal emulation, V3.5, Part04/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 303
  9. Archive-Name: screen-3.5/part04
  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 4 (of 10)."
  18. # Contents:  configure.in mark.c tty.c.dist tty.sh window.c
  19. # Wrapped by vixie@gw.home.vix.com on Sun Jul 25 12:57:18 1993
  20. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  21. if test -f 'configure.in' -a "${1}" != "-c" ; then 
  22.   echo shar: Will not clobber existing file \"'configure.in'\"
  23. else
  24. echo shar: Extracting \"'configure.in'\" \(20123 characters\)
  25. sed "s/^X//" >'configure.in' <<'END_OF_FILE'
  26. Xdnl Process this file with autoconf to produce a configure script.
  27. Xdnl
  28. Xdnl $Id: configure.in,v 1.4 1993/07/21 15:42:59 mlschroe Exp $ FAU
  29. Xdnl
  30. Xdnl Many thanks to David McKenzie for writing autoconf and
  31. Xdnl providing a sample configure.in file for screen.
  32. Xdnl
  33. XAC_INIT(screen.c)
  34. XAC_CONFIG_HEADER(config.h)
  35. X
  36. Xdnl
  37. Xdnl Define some useful macros
  38. Xdnl
  39. Xdefine(AC_PROGRAM_SOURCE,
  40. X[AC_REQUIRE([AC_PROG_CPP])AC_PROVIDE([$0])cat > conftest.c <<EOF
  41. X[$1]
  42. X_CUT_HERE_
  43. X[$2]
  44. XEOF
  45. Xeval "$CPP $DEFS conftest.c 2>/dev/null | sed -e '1,/_CUT_HERE_/d' > conftest.out"
  46. X. ./conftest.out
  47. Xrm -f conftest*
  48. X])dnl
  49. X
  50. Xrev=`sed < patchlevel.h -n -e '/#define REV/s/#define REV  *//p'`
  51. Xvers=`sed < patchlevel.h -n -e '/#define VERS/s/#define VERS  *//p'`
  52. Xpat=`sed < patchlevel.h -n -e '/#define PATCHLEVEL/s/#define PATCHLEVEL  *//p'`
  53. XVERSION="$rev.$vers.$pat"
  54. Xecho "this is screen version $VERSION"
  55. XAC_SUBST(VERSION)
  56. X
  57. XAC_PROG_CC
  58. XAC_PROG_CPP
  59. XAC_GCC_TRADITIONAL
  60. XAC_ISC_POSIX
  61. X
  62. X
  63. XAC_TEST_PROGRAM(main(){exit(0);},,echo "Can't run the compiler - sorry";exit)
  64. XAC_PROG_AWK
  65. X
  66. XAC_PROG_INSTALL
  67. X
  68. Xdnl
  69. Xdnl    ****  special unix variants  ****
  70. Xdnl
  71. Xif test -n "$ISC"; then
  72. X  AC_DEFINE(ISC) LIBS="$LIBS -linet"
  73. Xfi
  74. X
  75. Xecho checking for MIPS
  76. Xif test -f /lib/libmld.a || test -f /usr/lib/libmld.a || test -f /usr/lib/cmplrs/cc/libmld.a; then
  77. XAC_DEFINE(MIPS) LIBS="$LIBS -lmld" # for nlist.
  78. XAC_COMPILE_CHECK(wait3, , [wait3();], ,
  79. XAC_COMPILE_CHECK(wait2, , [wait2();],
  80. Xdnl John Rouillard (rouilj@sni-usa.com):
  81. Xdnl need -I/usr/include/bsd in RISCOS otherwise sockets are broken, no
  82. Xdnl job control etc.
  83. Xdnl Detect RISCOS if wait2 is present, but not wait3.
  84. XAC_DEFINE(USE_WAIT2) LIBS="$LIBS -lbsd" ; CC="$CC -I/usr/include/bsd"
  85. X))
  86. Xfi
  87. X
  88. Xecho checking for Ultrix
  89. XAC_PROGRAM_EGREP(yes,
  90. X[#if defined(ultrix) || defined(__ultrix)
  91. X  yes
  92. X#endif
  93. X], ULTRIX=1)
  94. X
  95. Xif test -n "$ULTRIX"; then
  96. X  test -z "$GCC" && CC="$CC -YBSD"
  97. Xelse
  98. X  # POSIX termios is broken on Ultrix so don't look for it.
  99. Xecho checking for POSIX.1
  100. XAC_PROGRAM_EGREP(yes,
  101. X[#include <sys/types.h>
  102. X#include <unistd.h>
  103. Xmain () {
  104. X#ifdef _POSIX_VERSION
  105. X  yes
  106. X#endif
  107. X], echo "- you have a POSIX system";AC_DEFINE(POSIX))
  108. Xfi
  109. X
  110. XAC_COMPILE_CHECK([System V],
  111. X[#include <sys/types.h>
  112. X#include <signal.h>
  113. X#include <fcntl.h>], [int x = SIGCHLD | FNDELAY;], , AC_DEFINE(SYSV))
  114. X
  115. Xecho checking for sequent/ptx
  116. XAC_PROGRAM_EGREP(yes,
  117. X[#ifdef _SEQUENT_
  118. X  yes
  119. X#endif
  120. X], LIBS="$LIBS -lsocket -linet";seqptx=1)
  121. X
  122. Xoldlibs="$LIBS"
  123. XLIBS="$LIBS -lelf"
  124. XAC_COMPILE_CHECK(SVR4,,,
  125. XAC_HEADER_CHECK(dwarf.h, AC_DEFINE(SVR4) ; AC_DEFINE(BUGGYGETLOGIN) ; LIBS="$LIBS -lelf",
  126. XAC_HEADER_CHECK(elf.h, AC_DEFINE(SVR4) ; AC_DEFINE(BUGGYGETLOGIN) ; LIBS="$LIBS -lelf"))
  127. X,LIBS="$oldlibs")
  128. X
  129. X
  130. Xdnl
  131. Xdnl    ****  typedefs / declarations  ****
  132. Xdnl
  133. X
  134. Xecho checking for putenv declaration
  135. XAC_PROGRAM_EGREP([putenv( |    |\()],[#include <sys/types.h>
  136. X#include <unistd.h>
  137. X#include <stdlib.h>
  138. X],AC_DEFINE(PUTENV_DECLARED))
  139. X
  140. Xecho checking for getdtablesize declaration
  141. XAC_PROGRAM_EGREP([getdtablesize( |    |\()],[#include <sys/types.h>
  142. X#include <unistd.h>
  143. X],AC_DEFINE(GETDTABLESIZE_DECLARED))
  144. X
  145. Xecho checking for select declaration
  146. XAC_PROGRAM_EGREP([select( |    |\()],[#include <sys/types.h>
  147. X#include <sys/time.h>
  148. X#include <unistd.h>
  149. X],AC_DEFINE(SELECT_DECLARED))
  150. X
  151. Xecho checking for vsprintf declaration
  152. XAC_PROGRAM_EGREP([vsprintf( |    |\()],[#include <sys/types.h>
  153. X#include <stdio.h>
  154. X#ifdef __STDC__
  155. X#include <stdarg.h>
  156. X#else
  157. X#include <varargs.h>
  158. X#endif
  159. X],AC_DEFINE(VPRNT_DECLARED))
  160. X
  161. Xecho checking for setreuid declaration
  162. XAC_PROGRAM_EGREP([setres?uid( |    |\()],[#include <sys/types.h>
  163. X#include <unistd.h>
  164. X],AC_DEFINE(REUID_DECLARED))
  165. X
  166. Xecho checking for wait declaration
  167. XAC_PROGRAM_EGREP([wait( |    |\()],[#include <sys/types.h>
  168. X#include <signal.h>
  169. X#include <sys/wait.h>
  170. X],AC_DEFINE(WAITSTUFF_DECLARED))
  171. X
  172. Xecho checking for memfuncs declaration
  173. XAC_PROGRAM_EGREP([(memcpy|memmove|bcopy)( |    |\()],[#include <sys/types.h>
  174. X#include <unistd.h>
  175. X#include <string.h>
  176. X#include <strings.h>
  177. X],AC_DEFINE(MEMFUNCS_DECLARED))
  178. X
  179. Xecho checking for [index] declaration
  180. XAC_PROGRAM_EGREP([[index( |    |\()]],[#include <sys/types.h>
  181. X#include <strings.h>
  182. X],AC_DEFINE(INDEX_DECLARED))
  183. X
  184. Xecho checking for crypt declaration
  185. XAC_PROGRAM_EGREP([crypt( |    |\()],[#include <sys/types.h>
  186. X#include <unistd.h>
  187. X],AC_DEFINE(CRYPT_DECLARED))
  188. X
  189. Xecho checking for mknod declaration
  190. XAC_PROGRAM_EGREP([mknod( |    |\()],[#include <sys/types.h>
  191. X#include <sys/stat.h>
  192. X],AC_DEFINE(MKNOD_DECLARED))
  193. X
  194. Xecho checking for setpgid declaration
  195. XAC_PROGRAM_EGREP([setpgid( |    |\()],[#include <sys/types.h>
  196. X#include <unistd.h>
  197. X],AC_DEFINE(SETPGID_DECLARED))
  198. X
  199. Xecho checking for kill declaration
  200. XAC_PROGRAM_EGREP([kill( |    |\()],[#include <sys/types.h>
  201. X#include <unistd.h>
  202. X#include <signal.h>
  203. X],AC_DEFINE(KILLSTUFF_DECLARED))
  204. X
  205. Xecho checking for gethostname declaration
  206. XAC_PROGRAM_EGREP([gethostname( |    |\()],[#include <sys/types.h>
  207. X#include <unistd.h>
  208. X],AC_DEFINE(GETHOSTNAME_DECLARED))
  209. X
  210. Xecho checking for pid_t
  211. XAC_PROGRAM_EGREP(pid_t,[#include <sys/types.h>
  212. X],AC_DEFINE(PID_T_DEFINED))
  213. X
  214. Xecho checking for sig_t
  215. XAC_PROGRAM_EGREP(sig_t,[#include <sys/types.h>
  216. X#include <signal.h>
  217. X],AC_DEFINE(SIG_T_DEFINED))
  218. X
  219. Xecho checking for uid_t
  220. XAC_PROGRAM_EGREP(uid_t,[#include <sys/types.h>
  221. X],AC_DEFINE(UID_T_DEFINED))
  222. X
  223. Xdnl
  224. Xdnl   ****     Job control     ****
  225. Xdnl
  226. X
  227. XAC_COMPILE_CHECK([BSD job control], 
  228. X[#include <sys/types.h>
  229. X#include <sys/ioctl.h>
  230. X], [
  231. X#ifdef POSIX
  232. Xtcsetpgrp(0, 0);
  233. X#else
  234. Xint x = TIOCSPGRP;
  235. X#ifdef SYSV
  236. Xsetpgrp();
  237. X#else
  238. Xint y = TIOCNOTTY;
  239. X#endif
  240. X#endif
  241. X], echo "- you have jobcontrol";AC_DEFINE(BSDJOBS), echo "- you don't have jobcontrol")
  242. X
  243. Xdnl
  244. Xdnl    ****  setreuid()  ****
  245. Xdnl
  246. XAC_COMPILE_CHECK(setreuid, , 
  247. X[
  248. X#ifdef hpux
  249. Xsetresuid(0, 0, 0);
  250. X#else
  251. Xsetreuid(0, 0);
  252. X#endif
  253. X], , AC_DEFINE(NOREUID))
  254. X
  255. X
  256. Xdnl    ****  select()  ****
  257. Xdnl
  258. X
  259. XAC_COMPILE_CHECK(select,,[select(0, 0, 0, 0, 0);],, 
  260. XLIBS="$LIBS -lnet -lnsl"
  261. XAC_COMPILE_CHECK(select with $LIBS,,[select(0, 0, 0, 0, 0);],, 
  262. Xecho '!!! no select - no screen';exit)
  263. X)
  264. Xdnl
  265. Xdnl    ****  FIFO tests  ****
  266. Xdnl
  267. X
  268. Xecho checking fifos
  269. XAC_TEST_PROGRAM([
  270. X#include <sys/types.h>
  271. X#include <sys/stat.h>
  272. X#include <fcntl.h>
  273. X
  274. X#ifndef O_NDELAY
  275. X#define O_NDELAY O_NONBLOCK
  276. X#endif
  277. X#ifndef S_IFIFO
  278. X#define S_IFIFO 0010000
  279. X#endif
  280. X
  281. Xchar *fin = "/tmp/conftest$$";
  282. X
  283. Xmain()
  284. X{
  285. X  struct stat stb;
  286. X  int f;
  287. X
  288. X  (void)alarm(5);
  289. X  if (mknod(fin, S_IFIFO|0777, 0))
  290. X    exit(1);
  291. X  if (stat(fin, &stb) || (stb.st_mode & S_IFIFO) != S_IFIFO)
  292. X    exit(1);
  293. X  close(0);
  294. X  if (open(fin, O_RDWR | O_NDELAY))
  295. X    exit(1);
  296. X  if (write(0, "TEST", 4) == -1)
  297. X    exit(1);
  298. X  f = 1;
  299. X  if (select(1, &f, 0, 0, 0) == -1)
  300. X    exit(1);
  301. X  exit(0);
  302. X}
  303. X], echo "- your fifos are usable"; fifo=1, echo "- your fifos are not usable")
  304. Xrm -f /tmp/conftest*
  305. X
  306. Xif test -n "$fifo"; then
  307. Xecho "checking for broken fifo implementation"
  308. XAC_TEST_PROGRAM([
  309. X#include <sys/types.h>
  310. X#include <fcntl.h>
  311. X#include <sys/time.h>
  312. X#include <sys/stat.h>
  313. X
  314. X#ifndef O_NDELAY
  315. X#define O_NDELAY O_NONBLOCK
  316. X#endif
  317. X#ifndef S_IFIFO
  318. X#define S_IFIFO 0010000
  319. X#endif
  320. X
  321. Xchar *fin = "/tmp/conftest$$";
  322. X
  323. Xmain()
  324. X{
  325. X  struct timeval tv;
  326. X  int r, x;
  327. X
  328. X  if (mknod(fin, S_IFIFO|0600))
  329. X    exit(1);
  330. X  close(0);
  331. X  if (open(fin, O_RDONLY|O_NDELAY))
  332. X    exit(1);
  333. X  r = 1;
  334. X  tv.tv_sec = 1;
  335. X  tv.tv_usec = 0;
  336. X  if (select(1, &r, 0, 0, &tv))
  337. X    exit(1);
  338. X  exit(0);
  339. X}
  340. X], echo "- your implementation is ok", echo "- you have a broken implementation";AC_DEFINE(BROKEN_PIPE);fifobr=1)
  341. Xrm -f /tmp/conftest*
  342. Xfi
  343. X
  344. Xdnl
  345. Xdnl    ****  SOCKET tests  ****
  346. Xdnl
  347. X
  348. Xecho checking sockets
  349. XAC_TEST_PROGRAM([
  350. X#include <sys/types.h>
  351. X#include <sys/socket.h>
  352. X#include <sys/un.h>
  353. X#include <fcntl.h>
  354. X
  355. X#ifndef O_NDELAY
  356. X#define O_NDELAY O_NONBLOCK
  357. X#endif
  358. X#ifndef FNDELAY
  359. X#define FNDELAY O_NDELAY
  360. X#endif
  361. X
  362. Xchar *son = "/tmp/conftest$$";
  363. X
  364. Xmain()
  365. X{
  366. X  int s1, s2, s3, l;
  367. X  struct sockaddr_un a;
  368. X
  369. X  (void)alarm(5);
  370. X  if ((s1 = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
  371. X    exit(1);
  372. X  a.sun_family = AF_UNIX;
  373. X  strcpy(a.sun_path, son);
  374. X  (void) unlink(son);
  375. X  if (bind(s1, (struct sockaddr *) &a, strlen(son)+2) == -1)
  376. X    exit(1);
  377. X  if (listen(s1, 2))
  378. X    exit(1);
  379. X  if (fork() == 0)
  380. X    {
  381. X      if ((s2 = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
  382. X    kill(getppid(), 3);
  383. X      (void)connect(s2, &a, strlen(son) + 2);
  384. X      if (write(s2, "HELLO", 5) == -1)
  385. X    kill(getppid(), 3);
  386. X      exit(0);
  387. X    }
  388. X  l = sizeof(a);
  389. X  close(0);
  390. X  if (accept(s1, &a, &l))
  391. X    exit(1);
  392. X  l = 1;
  393. X  if (select(1, &l, 0, 0, 0) == -1)
  394. X    exit(1);
  395. X  exit(0);
  396. X}
  397. X], echo "- your sockets are usable"; sock=1, echo "- your sockets are not usable")
  398. Xrm -f /tmp/conftest*
  399. X
  400. Xif test -n "$sock"; then
  401. Xecho "checking socket implementation"
  402. XAC_TEST_PROGRAM([
  403. X#include <sys/types.h>
  404. X#include <sys/stat.h>
  405. X#include <sys/socket.h>
  406. X#include <sys/un.h>
  407. X
  408. Xchar *son = "/tmp/conftest$$";
  409. X
  410. Xmain()
  411. X{
  412. X  int s;
  413. X  struct stat stb;
  414. X  struct sockaddr_un a;
  415. X  if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
  416. X    exit(0);
  417. X  a.sun_family = AF_UNIX;
  418. X  strcpy(a.sun_path, son);
  419. X  (void) unlink(son);
  420. X  if (bind(s, (struct sockaddr *) &a, strlen(son)+2) == -1)
  421. X    exit(0);
  422. X  if (stat(son, &stb))
  423. X    exit(1);
  424. X  close(s);
  425. X  exit(0);
  426. X}
  427. X],echo "- you are normal",echo "- unix domain sockets are not kept in the filesystem";AC_DEFINE(SOCK_NOT_IN_FS);socknofs=1)
  428. Xrm -f /tmp/conftest*
  429. Xfi
  430. X
  431. X
  432. Xdnl
  433. Xdnl    ****  choose sockets or fifos  ****
  434. Xdnl
  435. Xif test -n "$fifo"; then
  436. X  if test -n "$sock"; then
  437. X    if test -n "$nore"; then
  438. X      echo "- hmmm... better take the fifos"
  439. X      AC_DEFINE(NAMEDPIPE)
  440. X    elif test -n "$fifobr"; then
  441. X      echo "- as your fifos are broken lets use the sockets."
  442. X    else
  443. X      echo "- both sockets and fifos usable. let's take fifos."
  444. X      AC_DEFINE(NAMEDPIPE)
  445. X    fi
  446. X  else
  447. X    echo "- using named pipes, of course"
  448. X    AC_DEFINE(NAMEDPIPE)
  449. X  fi
  450. Xelif test -n "$sock"; then
  451. X  echo "- using unix-domain sockets, of course"
  452. Xelse
  453. X  echo "!!! you have neither usable sockets nor usable pipes -> no screen"
  454. X  exit
  455. Xfi
  456. X
  457. Xdnl
  458. Xdnl    ****  check the select implementation ****
  459. Xdnl
  460. X
  461. Xecho "checking select return value"
  462. XAC_TEST_PROGRAM([
  463. X#include <sys/types.h>
  464. X#include <sys/stat.h>
  465. X#include <fcntl.h>
  466. X
  467. Xchar *nam = "/tmp/conftest$$";
  468. X
  469. X#ifdef NAMEDPIPE
  470. X
  471. X#ifndef O_NDELAY
  472. X#define O_NDELAY O_NONBLOCK
  473. X#endif
  474. X#ifndef S_IFIFO
  475. X#define S_IFIFO 0010000
  476. X#endif
  477. X
  478. X
  479. Xmain()
  480. X{
  481. X  int l;
  482. X
  483. X  (void)alarm(5);
  484. X  if (mknod(nam, S_IFIFO|0777, 0))
  485. X    exit(1);
  486. X  close(0);
  487. X  if (open(nam, O_RDWR | O_NDELAY))
  488. X    exit(1);
  489. X  if (write(0, "TEST", 4) == -1)
  490. X    exit(1);
  491. X
  492. X#else
  493. X
  494. X#include <sys/types.h>
  495. X#include <sys/socket.h>
  496. X#include <sys/un.h>
  497. X
  498. Xmain()
  499. X{
  500. X  int s1, s2, s3, l;
  501. X  struct sockaddr_un a;
  502. X
  503. X  (void)alarm(5);
  504. X  if ((s1 = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
  505. X    exit(1);
  506. X  a.sun_family = AF_UNIX;
  507. X  strcpy(a.sun_path, nam);
  508. X  (void) unlink(nam);
  509. X  if (bind(s1, (struct sockaddr *) &a, strlen(nam)+2) == -1)
  510. X    exit(1);
  511. X  if (listen(s1, 2))
  512. X    exit(1);
  513. X  if (fork() == 0)
  514. X    {
  515. X      if ((s2 = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
  516. X    kill(getppid(), 3);
  517. X      (void)connect(s2, &a, strlen(nam) + 2);
  518. X      if (write(s2, "HELLO", 5) == -1)
  519. X    kill(getppid(), 3);
  520. X      exit(0);
  521. X    }
  522. X  l = sizeof(a);
  523. X  close(0);
  524. X  if (accept(s1, &a, &l))
  525. X    exit(1);
  526. X#endif
  527. X
  528. X
  529. X  l = 1;
  530. X  if (select(1, &l, 0, 0, 0) == -1)
  531. X    exit(1);
  532. X  if (select(1, &l, &l, 0, 0) != 2)
  533. X    exit(1);
  534. X  exit(0);
  535. X}
  536. X],echo "- select is ok",echo "- it is not usable";AC_DEFINE(SELECT_BROKEN))
  537. X
  538. Xdnl
  539. Xdnl    ****  termcap or terminfo  ****
  540. Xdnl
  541. Xecho searching for tgetent
  542. Xolibs="$LIBS"
  543. XLIBS="-ltermcap $LIBS"
  544. XAC_COMPILE_CHECK(libtermcap,,tgetent((char *)0, (char *)0);,,
  545. XLIBS="-lcurses $olibs"
  546. XAC_COMPILE_CHECK(libcurses,,tgetent((char *)0, (char *)0);,,
  547. Xecho "!!! no tgetent - no screen";exit)
  548. X)
  549. XTERMCAP="xx|scrdumm:xx:"
  550. XTERM=scrdumm
  551. Xexport TERMCAP
  552. Xexport TERM
  553. XAC_TEST_PROGRAM([
  554. Xmain()
  555. X{
  556. X  char buf[1024];
  557. X  if (tgetent(buf, "scrdumm") != 1)
  558. X    exit(1);
  559. X  exit(0);
  560. X}], echo "- you use the termcap database", echo "- you use the terminfo database";AC_DEFINE(TERMINFO))
  561. XAC_COMPILE_CHECK(ospeed,extern short ospeed;,ospeed=5;,,AC_DEFINE(NEED_OSPEED))
  562. X
  563. Xdnl
  564. Xdnl    ****  PTY ranges  ****
  565. Xdnl
  566. Xecho checking for ptyranges
  567. Xif test -d /dev/ptym ; then
  568. Xpdir='/dev/ptym'
  569. Xelse
  570. Xpdir='/dev'
  571. Xfi
  572. Xptys=`echo $pdir/pty??`
  573. Xif test "$ptys" != "$pdir/pty??" ; then
  574. Xp0=`echo $ptys | tr ' ' '\012' | sed -e 's/^.*\(.\).$/\1/g' | tr ' ' '\012' | sort -u | sed -n -e H -e g -e 's/\n//g' -e '$p'`
  575. Xp1=`echo $ptys | tr ' ' '\012' | sed -e 's/^.*\(.\)$/\1/g' | tr ' ' '\012' | sort -u | sed -n -e H -e g -e 's/\n//g' -e '$p'`
  576. XAC_DEFINE(PTYRANGE0,\"$p0\")
  577. XAC_DEFINE(PTYRANGE1,\"$p1\")
  578. Xfi
  579. X
  580. X
  581. Xdnl
  582. Xdnl    ****  utmp handling  ****
  583. Xdnl
  584. Xdnl linux has a void pututline, grrr, gcc will error when evaluating it.
  585. XAC_COMPILE_CHECK(getutent, [#include <time.h> /* to get time_t on SCO */
  586. X#include <sys/types.h>
  587. X#ifdef SVR4
  588. X#include <utmpx.h>
  589. X#else
  590. X#include <utmp.h>
  591. X#endif
  592. X#ifdef hpux
  593. X#define pututline _pututline
  594. X#endif
  595. X],
  596. X[int x = DEAD_PROCESS; struct utmp *y = pututline((struct utmp *)0); getutent();], AC_DEFINE(GETUTENT))
  597. XAC_COMPILE_CHECK(ut_host, [#include <time.h>
  598. X#include <sys/types.h>
  599. X#ifdef SVR4
  600. X#include <utmpx.h>
  601. X#else
  602. X#include <utmp.h>
  603. X#endif
  604. X],[struct utmp u; u.ut_host[0] = 0;], AC_DEFINE(UTHOST))
  605. X
  606. X
  607. Xdnl
  608. Xdnl    ****  loadav  ****
  609. Xdnl
  610. Xecho "checking for libutil(s)"
  611. Xtest -f /usr/lib/libutils.a && LIBS="$LIBS -lutils"
  612. Xtest -f /usr/lib/libutil.a && LIBS="$LIBS -lutil"
  613. X
  614. XAC_COMPILE_CHECK(getloadavg, , [getloadavg((double *)0, 0);],
  615. XAC_DEFINE(LOADAV_GETLOADAVG);load=1)
  616. Xif test -z "$load" ; then
  617. XAC_PROGRAM_EGREP(yes,
  618. X[#if defined(NeXT) || defined(apollo) || defined(linux)
  619. X  yes
  620. X#endif
  621. X], load=1)
  622. Xfi
  623. Xif test -z "$load" ; then
  624. Xecho "searching for kernelfile"
  625. Xfor core in /unix /vmunix /dynix /hp-ux /xelos /386bsd /kernel/unix ; do
  626. X  if test -f $core ; then
  627. X    break
  628. X  fi
  629. Xdone
  630. Xif test ! -f $core ; then
  631. X  echo "- no kernelfile found"
  632. Xelse
  633. X  echo "- using kernelfile '$core'"
  634. X  AC_DEFINE(LOADAV_UNIX,\"$core\")
  635. X  AC_HEADER_CHECK(nlist.h,
  636. X    [AC_DEFINE(NLIST_STRUCT)
  637. X     AC_COMPILE_CHECK(n_un in struct nlist, [#include <nlist.h>],
  638. X       [struct nlist n; n.n_un.n_name = 0;],
  639. X        AC_DEFINE(NLIST_NAME_UNION))])
  640. X
  641. X  echo checking for nlist declaration
  642. X  AC_PROGRAM_EGREP([nlist( |    |\()],[
  643. X#ifdef NLIST_STRUCT
  644. X# include <nlist.h>
  645. X#else
  646. X# include <a.out.h>
  647. X#endif
  648. X],AC_DEFINE(NLIST_DECLARED))
  649. X
  650. X  echo searching for avenrun symbol
  651. X  for av in avenrun _avenrun _Loadavg ; do
  652. X  AC_TEST_PROGRAM([
  653. X#include <sys/types.h>
  654. X#ifdef NLIST_STRUCT
  655. X#include <nlist.h>
  656. X#else
  657. X#include <a.out.h>
  658. X#endif
  659. X
  660. Xstruct nlist nl[2];
  661. X
  662. Xmain()
  663. X{
  664. X#ifdef NLIST_NAME_UNION
  665. X  nl[0].n_un.n_name = "$av";
  666. X#else
  667. X  nl[0].n_name = "$av";
  668. X#endif
  669. X  nlist(LOADAV_UNIX, nl);
  670. X  if (nl[0].n_value == 0)
  671. X    exit(1);
  672. X  exit(0);
  673. X}
  674. X  ],avensym=$av;break)
  675. X  done
  676. X  if test -z "$avensym" ; then
  677. X    echo "- no avenrun symbol found"
  678. X  else
  679. X    echo "- using avenrun symbol '$avensym'"
  680. X    AC_DEFINE(LOADAV_AVENRUN,\"$avensym\");
  681. X    load=1
  682. X  fi
  683. Xfi
  684. Xfi
  685. X
  686. XAC_PROGRAM_SOURCE([
  687. X#include <sys/types.h>
  688. X#include <sys/param.h>
  689. X],[
  690. X#if ((defined(hp300) && !defined(hpux)) || defined(sun) || (defined(ultrix) && defined(mips)) || defined(_SEQUENT_) || defined(sgi) || defined(SVR4) || defined(sony_news))
  691. Xloadtype=long
  692. X# ifdef apollo
  693. Xloadscale=65536
  694. X# else
  695. X#  ifdef FSCALE
  696. X#   undef FSCALE
  697. Xloadscale=FSCALE
  698. X#  else
  699. X#   ifdef sgi
  700. Xloadscale=1024
  701. X#   else
  702. X#    if defined(MIPS) || defined(SVR4)
  703. Xloadscale=256
  704. X#    else /* not MIPS */
  705. Xloadscale=1000     /* our default value */
  706. X#    endif /* MIPS */
  707. X#   endif /* sgi */
  708. X#  endif /* not FSCALE */
  709. X# endif /* not apollo */
  710. X#else
  711. Xloadtype=double
  712. Xloadscale=1
  713. X#endif
  714. X#ifdef alliant
  715. Xloadnum=4
  716. X#else
  717. Xloadnum=3
  718. X#endif
  719. X])
  720. X
  721. Xif test -n "$load" ; then AC_DEFINE(LOADAV) ; fi
  722. Xif test -n "$loadtype" ; then AC_DEFINE(LOADAV_TYPE,$loadtype) ; fi
  723. Xif test -n "$loadnum" ; then AC_DEFINE(LOADAV_NUM,$loadnum) ; fi
  724. Xif test -n "$loadscale" ; then AC_DEFINE(LOADAV_SCALE,$loadscale) ; fi
  725. X
  726. X
  727. Xdnl
  728. Xdnl    ****  signal handling  ****
  729. Xdnl
  730. XAC_HEADER_EGREP([(void|sighandler_t).*signal], signal.h, 
  731. X  AC_DEFINE(SIGVOID))
  732. XAC_COMPILE_CHECK(sigset, [
  733. X#include <sys/types.h>
  734. X#include <signal.h>
  735. X], [
  736. X#ifdef SIGVOID
  737. Xsigset(0, (void (*)())0);
  738. X#else
  739. Xsigset(0, (int (*)())0);
  740. X#endif
  741. X], AC_DEFINE(USESIGSET))
  742. Xecho checking signal implementation
  743. XAC_TEST_PROGRAM([
  744. X#include <sys/types.h>
  745. X#include <signal.h>
  746. X
  747. X#ifndef SIGCHLD
  748. X#define SIGCHLD SIGCLD
  749. X#endif
  750. X#ifdef USESIGSET
  751. X#define signal sigset
  752. X#endif
  753. X
  754. Xint got;
  755. X
  756. X#ifdef SIGVOID
  757. Xvoid
  758. X#endif
  759. Xhand()
  760. X{
  761. X  got++;
  762. X}
  763. X
  764. Xmain()
  765. X{
  766. X  (void)signal(SIGCHLD, hand);
  767. X  kill(getpid(), SIGCHLD);
  768. X  kill(getpid(), SIGCHLD);
  769. X  if (got < 2)
  770. X    exit(1);
  771. X  exit(0);
  772. X}
  773. X],,AC_DEFINE(SYSVSIGS))
  774. X
  775. Xdnl
  776. Xdnl    ****  libraries  ****
  777. Xdnl
  778. X
  779. Xecho checking for crypt and sec libraries
  780. Xtest -f /lib/libcrypt_d.a || test -f /usr/lib/libcrypt_d.a && LIBS="$LIBS -lcrypt_d"
  781. Xtest -f /lib/libcrypt.a || test -f /usr/lib/libcrypt.a && LIBS="$LIBS -lcrypt"
  782. Xtest -f /lib/libsec.a || test -f /usr/lib/libsec.a && LIBS="$LIBS -lsec"
  783. X
  784. Xoldlibs="$LIBS"
  785. XLIBS="$LIBS -lsun"
  786. XAC_COMPILE_CHECK(IRIX sun library,,,,LIBS="$oldlibs")
  787. X
  788. X
  789. Xdnl
  790. Xdnl    ****  misc things  ****
  791. Xdnl
  792. XAC_COMPILE_CHECK(wait union,[#include <sys/types.h>
  793. X#include <sys/wait.h>
  794. X],[
  795. X  union wait x;
  796. X  int y;
  797. X#ifdef WEXITSTATUS
  798. X  y = WEXITSTATUS(x);
  799. X#endif
  800. X],AC_DEFINE(BSDWAIT))
  801. X
  802. Xecho checking for termio or termios
  803. XAC_TEST_CPP([#include <termios.h>], AC_DEFINE(TERMIO),
  804. X            AC_TEST_CPP([#include <termio.h>], AC_DEFINE(TERMIO)))
  805. X
  806. Xdnl AC_HEADER_CHECK(shadow.h, AC_DEFINE(SHADOWPW))
  807. XAC_COMPILE_CHECK(getspnam, [#include <shadow.h>], [getspnam();],
  808. X         AC_DEFINE(SHADOWPW))
  809. X
  810. XAC_COMPILE_CHECK(getttyent, , [getttyent();], AC_DEFINE(GETTTYENT))
  811. X
  812. Xecho checking whether memcpy/memmove/bcopy handles overlapping arguments
  813. XAC_TEST_PROGRAM([
  814. Xmain() {
  815. X  char buf[10];
  816. X  strcpy(buf, "abcdefghi");
  817. X  bcopy(buf, buf + 2, 3);
  818. X  if (strncmp(buf, "ababcf", 6))
  819. X    exit(1);
  820. X  strcpy(buf, "abcdefghi");
  821. X  bcopy(buf + 2, buf, 3);
  822. X  if (strncmp(buf, "cdedef", 6))
  823. X    exit(1);
  824. X  exit(0); /* libc version works properly.  */
  825. X}], AC_DEFINE(USEBCOPY))
  826. X
  827. XAC_TEST_PROGRAM([
  828. X#define bcopy(s,d,l) memmove(d,s,l)
  829. Xmain() {
  830. X  char buf[10];
  831. X  strcpy(buf, "abcdefghi");
  832. X  bcopy(buf, buf + 2, 3);
  833. X  if (strncmp(buf, "ababcf", 6))
  834. X    exit(1);
  835. X  strcpy(buf, "abcdefghi");
  836. X  bcopy(buf + 2, buf, 3);
  837. X  if (strncmp(buf, "cdedef", 6))
  838. X    exit(1);
  839. X  exit(0); /* libc version works properly.  */
  840. X}], AC_DEFINE(USEMEMMOVE))
  841. X
  842. X
  843. XAC_TEST_PROGRAM([
  844. X#define bcopy(s,d,l) memcpy(d,s,l)
  845. Xmain() {
  846. X  char buf[10];
  847. X  strcpy(buf, "abcdefghi");
  848. X  bcopy(buf, buf + 2, 3);
  849. X  if (strncmp(buf, "ababcf", 6))
  850. X    exit(1);
  851. X  strcpy(buf, "abcdefghi");
  852. X  bcopy(buf + 2, buf, 3);
  853. X  if (strncmp(buf, "cdedef", 6))
  854. X    exit(1);
  855. X  exit(0); /* libc version works properly.  */
  856. X}], AC_DEFINE(USEMEMCPY))
  857. X
  858. Xecho checking for long file names
  859. X(echo 1 > /tmp/conftest9012345) 2>/dev/null
  860. X(echo 2 > /tmp/conftest9012346) 2>/dev/null
  861. Xval=`cat /tmp/conftest9012345 2>/dev/null`
  862. Xif test -f /tmp/conftest9012345 && test "$val" = 1; then :
  863. Xelse AC_DEFINE(NAME_MAX, 14)
  864. Xfi
  865. Xrm -f /tmp/conftest*
  866. X
  867. XAC_COMPILE_CHECK(vsprintf, [#include <varargs.h>
  868. X#include <stdio.h>], [vsprintf();], AC_DEFINE(USEVARARGS))
  869. X
  870. XAC_DIR_HEADER
  871. XAC_XENIX_DIR
  872. X
  873. XAC_COMPILE_CHECK(setenv, , [setenv((char *)0,(char *)0);unsetenv((char *)0);], AC_DEFINE(USESETENV),
  874. XAC_COMPILE_CHECK(putenv, , [putenv((char *)0);unsetenv((char *)0);], ,
  875. XAC_DEFINE(NEEDPUTENV)
  876. X))
  877. X
  878. Xdnl
  879. Xdnl    ****  the end  ****
  880. Xdnl
  881. Xdnl Ptx bug workaround -- insert -lc after -ltermcap
  882. Xtest -n "$seqptx" && LIBS="-ltermcap -lc -lsocket -linet -lsec -lseq"
  883. X
  884. XAC_TEST_PROGRAM(main(){exit(0);},,echo "Can't run the compiler - internal error. Sorry.";exit)
  885. XAC_OUTPUT(Makefile)
  886. X
  887. X# a hook for preserving undef directive in config.h
  888. Xif test -z "$no_create" ; then
  889. Xmv config.h conftest
  890. Xsed -e 's@^\(.*\)defin.\( .*\) .*/\*\(.*KEEP_UNDEF_HERE\)@\1undef\2    /\*\3@' < conftest > config.h
  891. Xrm -f conftest
  892. Xfi
  893. Xcat >> config.status << EOF
  894. Xmv config.h conftest
  895. Xsed -e 's@^\(.*\)defin.\( .*\) .*/\*\(.*KEEP_UNDEF_HERE\)@\1undef\2    /\*\3@' < conftest > config.h
  896. Xrm -f conftest
  897. XEOF
  898. X
  899. Xecho ""
  900. Xif test -z "$AWK"; then
  901. Xecho "!!! Since you have no awk you must copy the files 'comm.h.dist'"
  902. Xecho "!!! and 'term.h.dist' to 'comm.h' and 'term.h'."
  903. Xecho "!!! Do _not_ change the user configuration section in config.h!"
  904. Xecho "Please check the pathnames in the Makefile."
  905. Xelse
  906. Xecho "Now please check the pathnames in the Makefile and the user"
  907. Xecho "configuration section in config.h."
  908. Xfi
  909. Xecho "Then type 'make' to make screen. Good luck."
  910. Xecho ""
  911. END_OF_FILE
  912. if test 20123 -ne `wc -c <'configure.in'`; then
  913.     echo shar: \"'configure.in'\" unpacked with wrong size!
  914. fi
  915. # end of 'configure.in'
  916. fi
  917. if test -f 'mark.c' -a "${1}" != "-c" ; then 
  918.   echo shar: Will not clobber existing file \"'mark.c'\"
  919. else
  920. echo shar: Extracting \"'mark.c'\" \(25607 characters\)
  921. sed "s/^X//" >'mark.c' <<'END_OF_FILE'
  922. X/* Copyright (c) 1993
  923. X *      Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
  924. X *      Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
  925. X * Copyright (c) 1987 Oliver Laumann
  926. X *
  927. X * This program is free software; you can redistribute it and/or modify
  928. X * it under the terms of the GNU General Public License as published by
  929. X * the Free Software Foundation; either version 2, or (at your option)
  930. X * any later version.
  931. X *
  932. X * This program is distributed in the hope that it will be useful,
  933. X * but WITHOUT ANY WARRANTY; without even the implied warranty of
  934. X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  935. X * GNU General Public License for more details.
  936. X *
  937. X * You should have received a copy of the GNU General Public License
  938. X * along with this program (see the file COPYING); if not, write to the
  939. X * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  940. X *
  941. X ****************************************************************
  942. X */
  943. X
  944. X#include "rcs.h"
  945. XRCS_ID("$Id: mark.c,v 1.2 1993/07/21 15:43:11 mlschroe Exp $ FAU")
  946. X
  947. X#include <sys/types.h>
  948. X
  949. X#include "config.h"
  950. X#include "screen.h"
  951. X#include "mark.h"
  952. X#include "extern.h"
  953. X
  954. X#ifdef COPY_PASTE
  955. X
  956. Xstatic int  is_letter __P((int));
  957. Xstatic void nextword __P((int *, int *, int, int));
  958. Xstatic int  linestart __P((int));
  959. Xstatic int  lineend __P((int));
  960. Xstatic int  rem __P((int, int , int , int , int , char *, int));
  961. Xstatic int  eq __P((int, int ));
  962. Xstatic int  MarkScrollDownDisplay __P((int));
  963. Xstatic int  MarkScrollUpDisplay __P((int));
  964. X
  965. Xstatic void MarkProcess __P((char **, int *));
  966. Xstatic void MarkAbort __P((void));
  967. Xstatic void MarkRedisplayLine __P((int, int, int, int));
  968. Xstatic int  MarkRewrite __P((int, int, int, int));
  969. Xstatic void MarkSetCursor __P((void));
  970. X
  971. Xextern struct win *fore;
  972. Xextern struct display *display;
  973. Xextern char *null, *blank;
  974. Xextern char Esc, MetaEsc;
  975. X
  976. X#ifdef NETHACK
  977. Xextern nethackflag;
  978. X#endif
  979. X
  980. Xstatic struct LayFuncs MarkLf =
  981. X{
  982. X  MarkProcess,
  983. X  MarkAbort,
  984. X  MarkRedisplayLine,
  985. X  DefClearLine,
  986. X  MarkRewrite,
  987. X  MarkSetCursor,
  988. X  DefResize,
  989. X  DefRestore
  990. X};
  991. X
  992. Xint join_with_cr =  0;
  993. Xchar mark_key_tab[256]; /* this array must be initialised first! */
  994. X
  995. Xstatic struct markdata *markdata;
  996. X
  997. X
  998. X/*
  999. X * VI like is_letter: 0 - whitespace
  1000. X *                    1 - letter
  1001. X *              2 - other
  1002. X */
  1003. Xstatic int is_letter(c)
  1004. Xchar c;
  1005. X{
  1006. X  if ((c >= 'a' && c <= 'z') ||
  1007. X      (c >= 'A' && c <= 'Z') ||
  1008. X      (c >= '0' && c <= '9') ||
  1009. X      c == '_' || c == '.' ||
  1010. X      c == '@' || c == ':' ||
  1011. X      c == '%' || c == '!' ||
  1012. X      c == '-' || c == '+')
  1013. X    /* thus we can catch email-addresses as a word :-) */
  1014. X    return 1;
  1015. X  else if (c != ' ')
  1016. X    return 2;
  1017. X  return 0;
  1018. X}
  1019. X
  1020. Xstatic int
  1021. Xlinestart(y)
  1022. Xint y;
  1023. X{
  1024. X  register int x;
  1025. X  register char *i;
  1026. X
  1027. X  for (x = markdata->left_mar, i = iWIN(y) + x; x < d_width - 1; x++)
  1028. X    if (*i++ != ' ')
  1029. X      break;
  1030. X  if (x == d_width - 1)
  1031. X    x = markdata->left_mar;
  1032. X  return(x);
  1033. X}
  1034. X
  1035. Xstatic int
  1036. Xlineend(y)
  1037. Xint y;
  1038. X{
  1039. X  register int x;
  1040. X  register char *i;
  1041. X
  1042. X  for (x = markdata->right_mar, i = iWIN(y) + x; x >= 0; x--)
  1043. X    if (*i-- != ' ')
  1044. X      break;
  1045. X  if (x < 0)
  1046. X    x = markdata->left_mar;
  1047. X  return(x);
  1048. X}
  1049. X
  1050. X
  1051. X/*
  1052. X *  nextword calculates the cursor position of the num'th word.
  1053. X *  If the cursor is on a word, it counts as the first.
  1054. X *  NW_BACK:        search backward
  1055. X *  NW_ENDOFWORD:    find the end of the word
  1056. X *  NW_MUSTMOVE:    move at least one char
  1057. X */
  1058. X
  1059. X#define NW_BACK        (1<<0)
  1060. X#define NW_ENDOFWORD    (1<<1)
  1061. X#define NW_MUSTMOVE    (1<<2)
  1062. X
  1063. Xstatic void
  1064. Xnextword(xp, yp, flags, num)
  1065. Xint *xp, *yp, flags, num;
  1066. X{
  1067. X  int xx = d_width, yy = fore->w_histheight + d_height;
  1068. X  register int sx, oq, q, x, y;
  1069. X
  1070. X  x = *xp;
  1071. X  y = *yp;
  1072. X  sx = (flags & NW_BACK) ? -1 : 1;
  1073. X  if ((flags & NW_ENDOFWORD) && (flags & NW_MUSTMOVE))
  1074. X    x += sx;
  1075. X  for (oq = -1; ; x += sx, oq = q)
  1076. X    {
  1077. X      if (x >= xx || x < 0)
  1078. X    q = 0;
  1079. X      else
  1080. X        q = is_letter(iWIN(y)[x]);
  1081. X      if (oq >= 0 && oq != q)
  1082. X    {
  1083. X      if (oq == 0 || !(flags & NW_ENDOFWORD))
  1084. X        *xp = x;
  1085. X      else
  1086. X        *xp = x-sx;
  1087. X      *yp = y;
  1088. X      if ((!(flags & NW_ENDOFWORD) && q) ||
  1089. X          ((flags & NW_ENDOFWORD) && oq))
  1090. X        {
  1091. X          if (--num <= 0)
  1092. X            return;
  1093. X        }
  1094. X    }
  1095. X      if (x == xx)
  1096. X    {
  1097. X      x = -1;
  1098. X      if (++y >= yy)
  1099. X        return;
  1100. X    }
  1101. X      else if (x < 0)
  1102. X    {
  1103. X      x = xx;
  1104. X      if (--y < 0)
  1105. X        return;
  1106. X    }
  1107. X    }
  1108. X}
  1109. X
  1110. X
  1111. X/*
  1112. X * y1, y2 are WIN coordinates
  1113. X *
  1114. X * redisplay:    0  -  just copy
  1115. X *         1  -  redisplay + copy
  1116. X *        2  -  count + copy, don't redisplay
  1117. X */
  1118. X
  1119. Xstatic int
  1120. Xrem(x1, y1, x2, y2, redisplay, pt, yend)
  1121. Xint x1, y1, x2, y2, redisplay, yend;
  1122. Xchar *pt;
  1123. X{
  1124. X  int i, j, from, to, ry;
  1125. X  int l = 0;
  1126. X  char *im;
  1127. X
  1128. X  markdata->second = 0;
  1129. X  if (y2 < y1 || ((y2 == y1) && (x2 < x1)))
  1130. X    {
  1131. X      i = y2;
  1132. X      y2 = y1;
  1133. X      y1 = i;
  1134. X      i = x2;
  1135. X      x2 = x1;
  1136. X      x1 = i;
  1137. X    }
  1138. X  ry = y1 - markdata->hist_offset;
  1139. X  
  1140. X  i = y1;
  1141. X  if (redisplay != 2 && pt == 0 && ry <0)
  1142. X    {
  1143. X      i -= ry;
  1144. X      ry = 0;
  1145. X    }
  1146. X  for (; i <= y2; i++, ry++)
  1147. X    {
  1148. X      if (redisplay != 2 && pt == 0 && ry > yend)
  1149. X    break;
  1150. X      from = (i == y1) ? x1 : 0;
  1151. X      if (from < markdata->left_mar)
  1152. X    from = markdata->left_mar;
  1153. X      for (to = d_width, im = iWIN(i) + to; to >= 0; to--)
  1154. X        if (*im-- != ' ')
  1155. X      break;
  1156. X      if (i == y2 && x2 < to)
  1157. X    to = x2;
  1158. X      if (to > markdata->right_mar)
  1159. X    to = markdata->right_mar;
  1160. X      if (redisplay == 1 && from <= to && ry >=0 && ry <= yend)
  1161. X    MarkRedisplayLine(ry, from, to, 0);
  1162. X      if (redisplay != 2 && pt == 0)    /* don't count/copy */
  1163. X    continue;
  1164. X      for (j = from, im = iWIN(i)+from; j <= to; j++)
  1165. X    {
  1166. X      if (pt)
  1167. X        *pt++ = *im++;
  1168. X      l++;
  1169. X    }
  1170. X      if (i != y2 && (to != d_width - 1 || iWIN(i)[to + 1] == ' '))
  1171. X    {
  1172. X      /* 
  1173. X       * this code defines, what glues lines together
  1174. X       */
  1175. X      switch (markdata->nonl)
  1176. X        {
  1177. X        case 0:        /* lines separated by newlines */
  1178. X          if (join_with_cr)
  1179. X        {
  1180. X          if (pt)
  1181. X            *pt++ = '\r';
  1182. X          l++;
  1183. X        }
  1184. X          if (pt)
  1185. X        *pt++ = '\n';
  1186. X          l++;
  1187. X          break;
  1188. X        case 1:        /* nothing to separate lines */
  1189. X          break;
  1190. X        case 2:        /* lines separated by blanks */
  1191. X          if (pt)
  1192. X        *pt++ = ' ';
  1193. X          l++;
  1194. X          break;
  1195. X        }
  1196. X    }
  1197. X    }
  1198. X  return(l);
  1199. X}
  1200. X
  1201. X/* Check if two chars are identical. All digits are treatened
  1202. X * as same. Used for GetHistory()
  1203. X */
  1204. X
  1205. Xstatic int
  1206. Xeq(a, b)
  1207. Xint a, b;
  1208. X{
  1209. X  if (a == b)
  1210. X    return 1;
  1211. X  if (a == 0 || b == 0)
  1212. X    return 1;
  1213. X  if (a <= '9' && a >= '0' && b <= '9' && b >= '0')
  1214. X    return 1;
  1215. X  return 0;
  1216. X}
  1217. X
  1218. X
  1219. Xint
  1220. XGetHistory()    /* return value 1 if d_copybuffer changed */
  1221. X{
  1222. X  int i = 0, q = 0, xx, yy, x, y;
  1223. X  char *linep;
  1224. X
  1225. X  x = fore->w_x;
  1226. X  if (x >= d_width)
  1227. X    x = d_width - 1;
  1228. X  y = fore->w_y + fore->w_histheight;
  1229. X  debug2("cursor is at x=%d, y=%d\n", x, y);
  1230. X  for (xx = x - 1, linep = iWIN(y) + xx; xx >= 0; xx--)
  1231. X    if ((q = *linep--) != ' ' )
  1232. X      break;
  1233. X  debug3("%c at (%d,%d)\n", q, xx, y);
  1234. X  for (yy = y - 1; yy >= 0; yy--)
  1235. X    {
  1236. X      linep = iWIN(yy);
  1237. X      if (xx < 0 || eq(linep[xx], q))
  1238. X    {        /* line is matching... */
  1239. X      for (i = d_width - 1, linep += i; i >= x; i--)
  1240. X        if (*linep-- != ' ')
  1241. X          break;
  1242. X      if (i >= x)
  1243. X        break;
  1244. X    }
  1245. X    }
  1246. X  if (yy < 0)
  1247. X    return 0;
  1248. X  if (d_copybuffer != NULL)
  1249. X    free(d_copybuffer);
  1250. X  if ((d_copybuffer = malloc((unsigned) (i - x + 2))) == NULL)
  1251. X    {
  1252. X      Msg(0, "Not enough memory... Sorry.");
  1253. X      return 0;
  1254. X    }
  1255. X  bcopy(linep - i + x + 1, d_copybuffer, i - x + 1);
  1256. X  d_copylen = i - x + 1;
  1257. X  return 1;
  1258. X}
  1259. X
  1260. Xvoid
  1261. XMarkRoutine()
  1262. X{
  1263. X  int x, y;
  1264. X  ASSERT(fore->w_active);
  1265. X  if (InitOverlayPage(sizeof(*markdata), &MarkLf, 1))
  1266. X    return;
  1267. X  markdata = (struct markdata *)d_lay->l_data;
  1268. X  markdata->second = 0;
  1269. X  markdata->rep_cnt = 0;
  1270. X  markdata->append_mode = 0;
  1271. X  markdata->write_buffer = 0;
  1272. X  markdata->nonl = 0;
  1273. X  markdata->left_mar  = 0;
  1274. X  markdata->right_mar = d_width - 1;
  1275. X  markdata->hist_offset = fore->w_histheight;
  1276. X  x = fore->w_x;
  1277. X  y = D2W(fore->w_y);
  1278. X  if (x >= d_width)
  1279. X    x = d_width - 1;
  1280. X
  1281. X  GotoPos(x, W2D(y));
  1282. X#ifdef NETHACK
  1283. X  if (nethackflag)
  1284. X    Msg(0, "Welcome to hacker's treasure zoo - Column %d Line %d(+%d) (%d,%d)",
  1285. X    x + 1, W2D(y + 1), fore->w_histheight, d_width, d_height);
  1286. X  else
  1287. X#endif
  1288. X  Msg(0, "Copy mode - Column %d Line %d(+%d) (%d,%d)",
  1289. X      x + 1, W2D(y + 1), fore->w_histheight, d_width, d_height);
  1290. X  markdata->cx = markdata->x1 = x;
  1291. X  markdata->cy = markdata->y1 = y;
  1292. X}
  1293. X
  1294. Xstatic void
  1295. XMarkSetCursor()
  1296. X{
  1297. X  markdata = (struct markdata *)d_lay->l_data;
  1298. X  fore = d_fore;
  1299. X  GotoPos(markdata->cx, W2D(markdata->cy));
  1300. X}
  1301. X
  1302. Xstatic void
  1303. XMarkProcess(inbufp,inlenp)
  1304. Xchar **inbufp;
  1305. Xint *inlenp;
  1306. X{
  1307. X  char *inbuf, *pt;
  1308. X  int inlen;
  1309. X  int cx, cy, x2, y2, j, yend;
  1310. X  int newcopylen = 0, od;
  1311. X  int in_mark;
  1312. X  int rep_cnt;
  1313. X/*
  1314. X  char *extrap = 0, extrabuf[100];
  1315. X*/
  1316. X      
  1317. X  markdata = (struct markdata *)d_lay->l_data;
  1318. X  fore = d_fore;
  1319. X  if (inbufp == 0)
  1320. X    {
  1321. X      MarkAbort();
  1322. X      return;
  1323. X    }
  1324. X  GotoPos(markdata->cx, W2D(markdata->cy));
  1325. X  inbuf= *inbufp;
  1326. X  inlen= *inlenp;
  1327. X  pt = inbuf;
  1328. X  in_mark = 1;
  1329. X  while (in_mark && (inlen /* || extrap */))
  1330. X    {
  1331. X/*
  1332. X      if (extrap)
  1333. X    {
  1334. X      od = *extrap++;
  1335. X      if (*extrap == 0)
  1336. X        extrap = 0;
  1337. X    }
  1338. X      else
  1339. X*/
  1340. X    {
  1341. X          od = mark_key_tab[(unsigned int)*pt++];
  1342. X          inlen--;
  1343. X    }
  1344. X      rep_cnt = markdata->rep_cnt;
  1345. X      if (od >= '0' && od <= '9')
  1346. X        {
  1347. X      if (rep_cnt < 1001 && (od != '0' || rep_cnt != 0))
  1348. X        {
  1349. X          markdata->rep_cnt = 10 * rep_cnt + od - '0';
  1350. X          continue;
  1351. X           /*
  1352. X           * Now what is that 1001 here? Well, we have a screen with
  1353. X           * 25 * 80 = 2000 characters. Movement is at most across the full
  1354. X           * screen. This we do with word by word movement, as character by
  1355. X           * character movement never steps over line boundaries. The most words
  1356. X           * we can place on the screen are 1000 single letter words. Thus 1001
  1357. X           * is sufficient. Users with bigger screens never write in single letter
  1358. X           * words, as they should be more advanced. jw.
  1359. X           * Oh, wrong. We still give even the experienced user a factor of ten.
  1360. X           */
  1361. X        }
  1362. X    }
  1363. X      cx = markdata->cx;
  1364. X      cy = markdata->cy;
  1365. X      switch (od)
  1366. X    {
  1367. X    case '\014':    /* CTRL-L Redisplay */
  1368. X      Redisplay(0);
  1369. X      GotoPos(cx, W2D(cy));
  1370. X      break;
  1371. X    case '\010':    /* CTRL-H Backspace */
  1372. X    case 'h':
  1373. X      if (rep_cnt == 0)
  1374. X        rep_cnt = 1;
  1375. X      revto(cx - rep_cnt, cy);
  1376. X      break;
  1377. X    case '\016':    /* CTRL-N */
  1378. X    case 'j':
  1379. X      if (rep_cnt == 0)
  1380. X        rep_cnt = 1;
  1381. X      revto(cx, cy + rep_cnt);
  1382. X      break;
  1383. X    case '+':
  1384. X      if (rep_cnt == 0)
  1385. X        rep_cnt = 1;
  1386. X      j = cy + rep_cnt;
  1387. X      if (j > fore->w_histheight + d_height - 1)
  1388. X        j = fore->w_histheight + d_height - 1;
  1389. X      revto(linestart(j), j);
  1390. X      break;
  1391. X    case '-':
  1392. X      if (rep_cnt == 0)
  1393. X        rep_cnt = 1;
  1394. X      cy -= rep_cnt;
  1395. X      if (cy < 0)
  1396. X        cy = 0;
  1397. X      revto(linestart(cy), cy);
  1398. X      break;
  1399. X    case '^':
  1400. X      revto(linestart(cy), cy);
  1401. X      break;
  1402. X    case '\n':
  1403. X      revto(markdata->left_mar, cy + 1);
  1404. X      break;
  1405. X    case 'k':
  1406. X    case '\020':    /* CTRL-P */
  1407. X      if (rep_cnt == 0)
  1408. X        rep_cnt = 1;
  1409. X      revto(cx, cy - rep_cnt);
  1410. X      break;
  1411. X    case 'l':
  1412. X      if (rep_cnt == 0)
  1413. X        rep_cnt = 1;
  1414. X      revto(cx + rep_cnt, cy);
  1415. X      break;
  1416. X    case '\001':    /* CTRL-A from tcsh/emacs */
  1417. X    case '0':
  1418. X      revto(markdata->left_mar, cy);
  1419. X      break;
  1420. X    case '\004':    /* CTRL-D down half screen */
  1421. X      if (rep_cnt == 0)
  1422. X        rep_cnt = (d_height + 1) >> 1;
  1423. X      revto_line(cx, cy + rep_cnt, W2D(cy));
  1424. X      break;
  1425. X    case '$':
  1426. X      revto(lineend(cy), cy);
  1427. X      break;
  1428. X        case '\022':    /* CTRL-R emacs style backwards search */
  1429. X      ISearch(-1);
  1430. X      in_mark = 0;
  1431. X      break;
  1432. X        case '\023':    /* CTRL-S emacs style search */
  1433. X      ISearch(1);
  1434. X      in_mark = 0;
  1435. X      break;
  1436. X    case '\025':    /* CTRL-U up half screen */
  1437. X      if (rep_cnt == 0)
  1438. X        rep_cnt = (d_height + 1) >> 1;
  1439. X      revto_line(cx, cy - rep_cnt, W2D(cy));
  1440. X      break;
  1441. X    case '\007':    /* CTRL-G show cursorpos */
  1442. X      if (markdata->left_mar == 0 && markdata->right_mar == d_width - 1)
  1443. X        Msg(0, "Column %d Line %d(+%d)", cx+1, W2D(cy)+1,
  1444. X        markdata->hist_offset);
  1445. X      else
  1446. X        Msg(0, "Column %d(%d..%d) Line %d(+%d)", cx+1,
  1447. X        markdata->left_mar+1, markdata->right_mar+1, W2D(cy)+1, markdata->hist_offset);
  1448. X      break;
  1449. X    case '\002':    /* CTRL-B  back one page */
  1450. X      if (rep_cnt == 0)
  1451. X        rep_cnt = 1;
  1452. X      rep_cnt *= d_height; 
  1453. X      revto(cx, cy - rep_cnt);
  1454. X      break;
  1455. X    case '\006':    /* CTRL-F  forward one page */
  1456. X      if (rep_cnt == 0)
  1457. X        rep_cnt = 1;
  1458. X      rep_cnt *= d_height;
  1459. X      revto(cx, cy + rep_cnt);
  1460. X      break;
  1461. X    case '\005':    /* CTRL-E  scroll up */
  1462. X      if (rep_cnt == 0)
  1463. X        rep_cnt = 1;
  1464. X      rep_cnt = MarkScrollUpDisplay(rep_cnt);
  1465. X      if (cy < D2W(0))
  1466. X            revto(cx, D2W(0));
  1467. X      else
  1468. X            GotoPos(cx, W2D(cy));
  1469. X      break;
  1470. X    case '\031': /* CTRL-Y  scroll down */
  1471. X      if (rep_cnt == 0)
  1472. X        rep_cnt = 1;
  1473. X      rep_cnt = MarkScrollDownDisplay(rep_cnt);
  1474. X      if (cy > D2W(d_height-1))
  1475. X            revto(cx, D2W(d_height-1));
  1476. X      else
  1477. X            GotoPos(cx, W2D(cy));
  1478. X      break;
  1479. X    case '@':
  1480. X      /* it may be usefull to have a key that does nothing */
  1481. X      break;
  1482. X    case '%':
  1483. X      rep_cnt--;
  1484. X      /* rep_cnt is a percentage for the history buffer */
  1485. X      if (rep_cnt < 0)
  1486. X        rep_cnt = 0;
  1487. X      if (rep_cnt > 100)
  1488. X        rep_cnt = 100;
  1489. X      revto_line(markdata->left_mar, (rep_cnt * (fore->w_histheight + d_height)) / 100, (d_height - 1) / 2);
  1490. X      break;
  1491. X    case 'g':
  1492. X      rep_cnt = 1;
  1493. X      /* FALLTHROUGH */
  1494. X    case 'G':
  1495. X      /* rep_cnt is here the WIN line number */
  1496. X      if (rep_cnt == 0)
  1497. X        rep_cnt = fore->w_histheight + d_height;
  1498. X      revto_line(markdata->left_mar, --rep_cnt, (d_height - 1) / 2);
  1499. X      break;
  1500. X    case 'H':
  1501. X      revto(markdata->left_mar, D2W(0));
  1502. X      break;
  1503. X    case 'M':
  1504. X      revto(markdata->left_mar, D2W((d_height - 1) / 2));
  1505. X      break;
  1506. X    case 'L':
  1507. X      revto(markdata->left_mar, D2W(d_height - 1));
  1508. X      break;
  1509. X    case '|':
  1510. X      revto(--rep_cnt, cy);
  1511. X      break;
  1512. X    case 'w':
  1513. X      if (rep_cnt == 0)
  1514. X        rep_cnt = 1;
  1515. X      nextword(&cx, &cy, NW_MUSTMOVE, rep_cnt);
  1516. X      revto(cx, cy);
  1517. X      break;
  1518. X    case 'e':
  1519. X      if (rep_cnt == 0)
  1520. X        rep_cnt = 1;
  1521. X      nextword(&cx, &cy, NW_ENDOFWORD|NW_MUSTMOVE, rep_cnt);
  1522. X      revto(cx, cy);
  1523. X      break;
  1524. X    case 'b':
  1525. X      if (rep_cnt == 0)
  1526. X        rep_cnt = 1;
  1527. X      nextword(&cx, &cy, NW_BACK|NW_ENDOFWORD|NW_MUSTMOVE, rep_cnt);
  1528. X      revto(cx, cy);
  1529. X      break;
  1530. X    case 'a':
  1531. X      markdata->append_mode = 1 - markdata->append_mode;
  1532. X      debug1("append mode %d--\n", markdata->append_mode);
  1533. X      Msg(0, (markdata->append_mode) ? ":set append" : ":set noappend");
  1534. X      break;
  1535. X    case 'v':
  1536. X    case 'V':
  1537. X      /* this sets start column to column 9 for VI :set nu users */
  1538. X      if (markdata->left_mar == 8)
  1539. X        rep_cnt = 1;
  1540. X      else
  1541. X        rep_cnt = 9;
  1542. X      /* FALLTHROUGH */
  1543. X    case 'c':
  1544. X    case 'C':
  1545. X      /* set start column (c) and end column (C) */
  1546. X      if (markdata->second)
  1547. X        {
  1548. X          rem(markdata->x1, markdata->y1, cx, cy, 1, (char *)0, d_height-1); /* Hack */
  1549. X          markdata->second = 1;    /* rem turns off second */
  1550. X        }
  1551. X      rep_cnt--;
  1552. X      if (rep_cnt < 0)
  1553. X        rep_cnt = cx;
  1554. X      if (od != 'C')
  1555. X        {
  1556. X          markdata->left_mar = rep_cnt;
  1557. X          if (markdata->left_mar > markdata->right_mar)
  1558. X        markdata->left_mar = markdata->right_mar;
  1559. X        }
  1560. X      else
  1561. X        {
  1562. X          markdata->right_mar = rep_cnt;
  1563. X          if (markdata->left_mar > markdata->right_mar)
  1564. X        markdata->right_mar = markdata->left_mar;
  1565. X        }
  1566. X      if (markdata->second)
  1567. X        {
  1568. X          markdata->cx = markdata->x1; markdata->cy = markdata->y1;
  1569. X          revto(cx, cy);
  1570. X        }
  1571. X      if (od == 'v' || od == 'V')
  1572. X        Msg(0, (markdata->left_mar != 8) ? ":set nonu" : ":set nu");
  1573. X      break;
  1574. X    case 'J':
  1575. X      /* how do you join lines in VI ? */
  1576. X      markdata->nonl = (markdata->nonl + 1) % 3;
  1577. X      switch (markdata->nonl)
  1578. X        {
  1579. X        case 0:
  1580. X          if (join_with_cr)
  1581. X        Msg(0, "Multiple lines (CR/LF)");
  1582. X          else
  1583. X        Msg(0, "Multiple lines (LF)");
  1584. X          break;
  1585. X        case 1:
  1586. X          Msg(0, "Lines joined");
  1587. X          break;
  1588. X        case 2:
  1589. X          Msg(0, "Lines joined with blanks");
  1590. X          break;
  1591. X        }
  1592. X      break;
  1593. X    case '/':
  1594. X      Search(1);
  1595. X      in_mark = 0;
  1596. X      break;
  1597. X    case '?':
  1598. X      Search(-1);
  1599. X      in_mark = 0;
  1600. X      break;
  1601. X    case 'n':
  1602. X      Search(0);
  1603. X      break;
  1604. X    case 'y':
  1605. X    case 'Y':
  1606. X      if (markdata->second == 0)
  1607. X        {
  1608. X          revto(linestart(cy), cy);
  1609. X          markdata->second++;
  1610. X          cx = markdata->x1 = markdata->cx;
  1611. X          cy = markdata->y1 = markdata->cy;
  1612. X        }
  1613. X      if (--rep_cnt > 0)
  1614. X        revto(cx, cy + rep_cnt);
  1615. X      revto(lineend(markdata->cy), markdata->cy);
  1616. X      if (od == 'y')
  1617. X        break;
  1618. X      /* FALLTHROUGH */
  1619. X    case 'W':
  1620. X      if (od == 'W')
  1621. X        {
  1622. X          if (rep_cnt == 0)
  1623. X        rep_cnt = 1;
  1624. X          if (!markdata->second)
  1625. X        {
  1626. X          nextword(&cx, &cy, NW_BACK|NW_ENDOFWORD, 1);
  1627. X          revto(cx, cy);
  1628. X          markdata->second++;
  1629. X          cx = markdata->x1 = markdata->cx;
  1630. X          cy = markdata->y1 = markdata->cy;
  1631. X        }
  1632. X          nextword(&cx, &cy, NW_ENDOFWORD, rep_cnt);
  1633. X          revto(cx, cy);
  1634. X        }
  1635. X      cx = markdata->cx;
  1636. X      cy = markdata->cy;
  1637. X      /* FALLTHROUGH */
  1638. X    case 'A':
  1639. X      if (od == 'A')
  1640. X        markdata->append_mode = 1;
  1641. X      /* FALLTHROUGH */
  1642. X    case '>':
  1643. X      if (od == '>')
  1644. X        markdata->write_buffer = 1;
  1645. X      /* FALLTHROUGH */
  1646. X    case ' ':
  1647. X    case '\r':
  1648. X      if (!markdata->second)
  1649. X        {
  1650. X          markdata->second++;
  1651. X          markdata->x1 = cx;
  1652. X          markdata->y1 = cy;
  1653. X          revto(cx, cy);
  1654. X#ifdef NETHACK
  1655. X          if (nethackflag)
  1656. X        Msg(0, "You drop a magic marker - Column %d Line %d",
  1657. X                cx+1, W2D(cy)+1);
  1658. X          else
  1659. X#endif
  1660. X          Msg(0, "First mark set - Column %d Line %d", cx+1, W2D(cy)+1);
  1661. X          break;
  1662. X        }
  1663. X      else
  1664. X        {
  1665. X          int append_mode = markdata->append_mode;
  1666. X          int write_buffer = markdata->write_buffer;
  1667. X
  1668. X          x2 = cx;
  1669. X          y2 = cy;
  1670. X          newcopylen = rem(markdata->x1, markdata->y1, x2, y2, 2, (char *)0, 0); /* count */
  1671. X          if (d_copybuffer != NULL && !append_mode)
  1672. X        {
  1673. X          d_copylen = 0;
  1674. X          free(d_copybuffer);
  1675. X          d_copybuffer = NULL;
  1676. X        }
  1677. X          if (newcopylen > 0)
  1678. X        {
  1679. X          /* the +3 below is for : cr + lf + \0 */
  1680. X          if (d_copybuffer != NULL)
  1681. X            d_copybuffer = realloc(d_copybuffer,
  1682. X            (unsigned) (d_copylen + newcopylen + 3));
  1683. X          else
  1684. X            {
  1685. X            d_copylen = 0;
  1686. X            d_copybuffer = malloc((unsigned) (newcopylen + 3));
  1687. X            }
  1688. X          if (d_copybuffer == NULL)
  1689. X            {
  1690. X              MarkAbort();
  1691. X              in_mark = 0;
  1692. X              Msg(0, "Not enough memory... Sorry.");
  1693. X              d_copylen = 0;
  1694. X              d_copybuffer = NULL;
  1695. X              break;
  1696. X            }
  1697. X          if (append_mode)
  1698. X            {
  1699. X              switch (markdata->nonl)
  1700. X            {
  1701. X            /* 
  1702. X             * this code defines, what glues lines together
  1703. X             */
  1704. X            case 0:
  1705. X              if (join_with_cr)
  1706. X                {
  1707. X                  d_copybuffer[d_copylen] = '\r';
  1708. X                  d_copylen++;
  1709. X                }
  1710. X              d_copybuffer[d_copylen] = '\n';
  1711. X              d_copylen++;
  1712. X              break;
  1713. X            case 1:
  1714. X              break;
  1715. X            case 2:
  1716. X              d_copybuffer[d_copylen] = ' ';
  1717. X              d_copylen++;
  1718. X              break;
  1719. X            }
  1720. X            }
  1721. X          yend = d_height - 1;
  1722. X          if (fore->w_histheight - markdata->hist_offset < d_height)
  1723. X            {
  1724. X              markdata->second = 0;
  1725. X              yend -= MarkScrollUpDisplay(fore->w_histheight - markdata->hist_offset);
  1726. X            }
  1727. X          d_copylen += rem(markdata->x1, markdata->y1, x2, y2, markdata->hist_offset == fore->w_histheight, d_copybuffer + d_copylen, yend);
  1728. X        }
  1729. X          if (markdata->hist_offset != fore->w_histheight)
  1730. X        LAY_CALL_UP(Activate(0));
  1731. X          ExitOverlayPage();
  1732. X          if (append_mode)
  1733. X        Msg(0, "Appended %d characters to buffer",
  1734. X            newcopylen);
  1735. X          else
  1736. X        Msg(0, "Copied %d characters into buffer", d_copylen);
  1737. X          if (write_buffer)
  1738. X        WriteFile(DUMP_EXCHANGE);
  1739. X          in_mark = 0;
  1740. X          break;
  1741. X        }
  1742. X    default:
  1743. X      MarkAbort();
  1744. X#ifdef NETHACK
  1745. X      if (nethackflag)
  1746. X        Msg(0, "You escaped the dungeon.");
  1747. X      else
  1748. X#endif
  1749. X      Msg(0, "Copy mode aborted");
  1750. X      in_mark = 0;
  1751. X      break;
  1752. X    }
  1753. X      if (in_mark)    /* markdata may be freed */
  1754. X        markdata->rep_cnt = 0;
  1755. X    }
  1756. X  *inbufp = pt;
  1757. X  *inlenp = inlen;
  1758. X}
  1759. X
  1760. Xvoid revto(tx, ty)
  1761. Xint tx, ty;
  1762. X{
  1763. X  revto_line(tx, ty, -1);
  1764. X}
  1765. X
  1766. X/* tx, ty: WINDOW,  line: DISPLAY */
  1767. Xvoid revto_line(tx, ty, line)
  1768. Xint tx, ty, line;
  1769. X{
  1770. X  int fx, fy;
  1771. X  int x, y, t, revst, reven, qq, ff, tt, st, en, ce = 0;
  1772. X  int ystart = 0, yend = d_height-1;
  1773. X  int i, ry;
  1774. X  if (tx < 0)
  1775. X    tx = 0;
  1776. X  else if (tx > d_width - 1)
  1777. X    tx = d_width -1;
  1778. X  if (ty < 0)
  1779. X    ty = 0;
  1780. X  else if (ty > fore->w_histheight + d_height - 1)
  1781. X    ty = fore->w_histheight + d_height - 1;
  1782. X  
  1783. X  fx = markdata->cx; fy = markdata->cy;
  1784. X  markdata->cx = tx; markdata->cy = ty;
  1785. X  /*
  1786. X   * if we go to a position that is currently offscreen 
  1787. X   * then scroll the screen
  1788. X   */
  1789. X  i = 0;
  1790. X  if (line >= 0 && line < d_height)
  1791. X    i = W2D(ty) - line;
  1792. X  else if (ty < markdata->hist_offset)
  1793. X    i = ty - markdata->hist_offset;
  1794. X  else if (ty > markdata->hist_offset + (d_height-1))
  1795. X    i = ty-markdata->hist_offset-(d_height-1);
  1796. X  if (i > 0)
  1797. X    yend -= MarkScrollUpDisplay(i);
  1798. X  else if (i < 0)
  1799. X    ystart += MarkScrollDownDisplay(-i);
  1800. X
  1801. X  if (markdata->second == 0)
  1802. X    {
  1803. X      GotoPos(tx, W2D(ty));
  1804. X      return;
  1805. X    }
  1806. X  
  1807. X  qq = markdata->x1 + markdata->y1 * d_width;
  1808. X  ff = fx + fy * d_width; /* "from" offset in WIN coords */
  1809. X  tt = tx + ty * d_width; /* "to" offset  in WIN coords*/
  1810. X  if (ff > tt)
  1811. X    {
  1812. X      st = tt; en = ff;
  1813. X      x = tx; y = ty;
  1814. X    }
  1815. X  else
  1816. X    {
  1817. X      st = ff; en = tt;
  1818. X      x = fx; y = fy;
  1819. X    }
  1820. X  if (st > qq)
  1821. X    {
  1822. X      st++;
  1823. X      x++;
  1824. X    }
  1825. X  if (en < qq)
  1826. X    en--;
  1827. X  if (tt > qq)
  1828. X    {
  1829. X      revst = qq; reven = tt;
  1830. X    }
  1831. X  else
  1832. X    {
  1833. X      revst = tt; reven = qq;
  1834. X    }
  1835. X  ry = y - markdata->hist_offset;
  1836. X  if (ry < ystart)
  1837. X    {
  1838. X      y += (ystart - ry);
  1839. X      x = 0;
  1840. X      st = y * d_width;
  1841. X      ry = ystart;
  1842. X    }
  1843. X  for (t = st; t <= en; t++, x++)
  1844. X    {
  1845. X      if (x >= d_width)
  1846. X    {
  1847. X      x = 0;
  1848. X      y++, ry++;
  1849. X    }
  1850. X      if (ry > yend)
  1851. X    break;
  1852. X      if (t == st || x == 0)
  1853. X    {
  1854. X      for (ce = d_width; ce >= 0; ce--)
  1855. X        if (iWIN(y)[ce] != ' ')
  1856. X          break;
  1857. X    }
  1858. X      if (x <= ce && x >= markdata->left_mar && x <= markdata->right_mar
  1859. X          && (CLP || x < d_width-1 || ry < d_bot))
  1860. X    {
  1861. X      GotoPos(x, W2D(y));
  1862. X      if (t >= revst && t <= reven)
  1863. X        SetAttrFont(A_SO, ASCII);
  1864. X      else
  1865. X        SetAttrFont(aWIN(y)[x], fWIN(y)[x]);
  1866. X      PUTCHARLP(iWIN(y)[x]);
  1867. X    }
  1868. X    }
  1869. X  GotoPos(tx, W2D(ty));
  1870. X}
  1871. X
  1872. Xstatic void
  1873. XMarkAbort()
  1874. X{
  1875. X  int yend, redisp;
  1876. X
  1877. X  debug("MarkAbort\n");
  1878. X  markdata = (struct markdata *)d_lay->l_data;
  1879. X  fore = d_fore;
  1880. X  yend = d_height - 1;
  1881. X  redisp = markdata->second;
  1882. X  if (fore->w_histheight - markdata->hist_offset < d_height)
  1883. X    {
  1884. X      markdata->second = 0;
  1885. X      yend -= MarkScrollUpDisplay(fore->w_histheight - markdata->hist_offset);
  1886. X    }
  1887. X  if (markdata->hist_offset != fore->w_histheight)
  1888. X    {
  1889. X      LAY_CALL_UP(Activate(0));
  1890. X    }
  1891. X  else
  1892. X    {
  1893. X      rem(markdata->x1, markdata->y1, markdata->cx, markdata->cy, redisp, (char *)0, yend);
  1894. X    }
  1895. X  ExitOverlayPage();
  1896. X}
  1897. X
  1898. X
  1899. Xstatic void
  1900. XMarkRedisplayLine(y, xs, xe, isblank)
  1901. Xint y;    /* NOTE: y is in DISPLAY coords system! */
  1902. Xint xs, xe;
  1903. Xint isblank;
  1904. X{
  1905. X  int x, i, rm;
  1906. X  int sta, sto, cp;    /* NOTE: these 3 are in WINDOW coords system */
  1907. X  char *wi, *wa, *wf, *oldi;
  1908. X
  1909. X  if (y < 0)    /* No special full page handling */
  1910. X    return;
  1911. X
  1912. X  markdata = (struct markdata *)d_lay->l_data;
  1913. X  fore = d_fore;
  1914. X
  1915. X  wi = iWIN(D2W(y));
  1916. X  wa = aWIN(D2W(y));
  1917. X  wf = fWIN(D2W(y));
  1918. X  oldi = isblank ? blank : null;
  1919. X  if (markdata->second == 0)
  1920. X    {
  1921. X      DisplayLine(oldi, null, null, wi, wa, wf, y, xs, xe);
  1922. X      return;
  1923. X    }
  1924. X  sta = markdata->y1 * d_width + markdata->x1;
  1925. X  sto = markdata->cy * d_width + markdata->cx;
  1926. X  if (sta > sto)
  1927. X    {
  1928. X      i=sta; sta=sto; sto=i;
  1929. X    }
  1930. X  cp = D2W(y) * d_width + xs;
  1931. X  rm = markdata->right_mar;
  1932. X  for (x = d_width; x >= 0; x--)
  1933. X    if (wi[x] != ' ')
  1934. X      break;
  1935. X  if (x < rm)
  1936. X    rm = x;
  1937. X  for (x = xs; x <= xe; x++, cp++)
  1938. X    if (cp >= sta && x >= markdata->left_mar)
  1939. X      break;
  1940. X  if (x > xs)
  1941. X    DisplayLine(oldi, null, null, wi, wa, wf, y, xs, x-1);
  1942. X  for (; x <= xe; x++, cp++)
  1943. X    {
  1944. X      if (cp > sto || x > rm || (!CLP && x >= d_width-1 && y == d_bot))
  1945. X    break;
  1946. X      GotoPos(x, y);
  1947. X      SetAttrFont(A_SO, ASCII);
  1948. X      PUTCHARLP(wi[x]);
  1949. X    }
  1950. X  if (x <= xe)
  1951. X    DisplayLine(oldi, null, null, wi, wa, wf, y, x, xe);
  1952. X}
  1953. X
  1954. X
  1955. X/*
  1956. X * This ugly routine is to speed up GotoPos()
  1957. X */
  1958. Xstatic int
  1959. XMarkRewrite(ry, xs, xe, doit)
  1960. Xint ry, xs, xe, doit;
  1961. X{
  1962. X  int dx, x, y, st, en, t, rm;
  1963. X  char *a, *f, *i;
  1964. X
  1965. X  markdata = (struct markdata *)d_lay->l_data;
  1966. X  fore = d_fore;
  1967. X  y = D2W(ry);
  1968. X  dx = xe - xs;
  1969. X  if (doit)
  1970. X    {
  1971. X      i = iWIN(y) + xs;
  1972. X      while (dx--)
  1973. X        PUTCHARLP(*i++);
  1974. X      return(0);
  1975. X    }
  1976. X  
  1977. X  a = aWIN(y) + xs,
  1978. X  f = fWIN(y) + xs;
  1979. X  if (markdata->second == 0)
  1980. X    st = en = -1;
  1981. X  else
  1982. X    {
  1983. X      st = markdata->y1 * d_width + markdata->x1;
  1984. X      en = markdata->cy * d_width + markdata->cx;
  1985. X      if (st > en)
  1986. X        {
  1987. X          t = st; st = en; en = t;
  1988. X        }
  1989. X    }
  1990. X  t = y * d_width + xs;
  1991. X  for (rm=d_width, i=iWIN(y) + d_width; rm>=0; rm--)
  1992. X    if (*i-- != ' ')
  1993. X      break;
  1994. X  if (rm > markdata->right_mar)
  1995. X    rm = markdata->right_mar;
  1996. X  x = xs;
  1997. X  while (dx--)
  1998. X    {
  1999. X      if (t >= st && t <= en && x >= markdata->left_mar && x <= rm)
  2000. X        {
  2001. X      if (d_attr != A_SO || d_font != ASCII)
  2002. X        return(EXPENSIVE);
  2003. X        }
  2004. X      else
  2005. X        {
  2006. X      if (d_attr != *a || d_font != *f)
  2007. X        return(EXPENSIVE);
  2008. X        }
  2009. X      a++, f++, t++, x++;
  2010. X    }
  2011. X  return(xe - xs);
  2012. X}
  2013. X
  2014. X
  2015. X/*
  2016. X * scroll the screen contents up/down.
  2017. X */
  2018. Xstatic int MarkScrollUpDisplay(n)
  2019. Xint n;
  2020. X{
  2021. X  int i;
  2022. X
  2023. X  debug1("MarkScrollUpDisplay(%d)\n", n);
  2024. X  if (n <= 0)
  2025. X    return 0;
  2026. X  if (n > fore->w_histheight - markdata->hist_offset)
  2027. X    n = fore->w_histheight - markdata->hist_offset;
  2028. X  i = (n < d_height) ? n : (d_height);
  2029. X  ScrollRegion(0, d_height - 1, i);
  2030. X  markdata->hist_offset += n;
  2031. X  while (i-- > 0)
  2032. X    MarkRedisplayLine(d_height - i - 1, 0, d_width - 1, 1);
  2033. X  return n;
  2034. X}
  2035. X
  2036. Xstatic int MarkScrollDownDisplay(n)
  2037. Xint n;
  2038. X{
  2039. X  int i;
  2040. X
  2041. X  debug1("MarkScrollDownDisplay(%d)\n", n);
  2042. X  if (n <= 0)
  2043. X    return 0;
  2044. X  if (n > markdata->hist_offset)
  2045. X    n = markdata->hist_offset;
  2046. X  i = (n < d_height) ? n : (d_height);
  2047. X  ScrollRegion(0, d_height - 1, -i);
  2048. X  markdata->hist_offset -= n;
  2049. X  while (i-- > 0)
  2050. X    MarkRedisplayLine(i, 0, d_width - 1, 1);
  2051. X  return n;
  2052. X}
  2053. X
  2054. X#endif /* COPY_PASTE */
  2055. END_OF_FILE
  2056. if test 25607 -ne `wc -c <'mark.c'`; then
  2057.     echo shar: \"'mark.c'\" unpacked with wrong size!
  2058. fi
  2059. # end of 'mark.c'
  2060. fi
  2061. if test -f 'tty.c.dist' -a "${1}" != "-c" ; then 
  2062.   echo shar: Will not clobber existing file \"'tty.c.dist'\"
  2063. else
  2064. echo shar: Extracting \"'tty.c.dist'\" \(21390 characters\)
  2065. sed "s/^X//" >'tty.c.dist' <<'END_OF_FILE'
  2066. X/* Copyright (c) 1993
  2067. X *      Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
  2068. X *      Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
  2069. X * Copyright (c) 1987 Oliver Laumann
  2070. X *
  2071. X * This program is free software; you can redistribute it and/or modify
  2072. X * it under the terms of the GNU General Public License as published by
  2073. X * the Free Software Foundation; either version 2, or (at your option)
  2074. X * any later version.
  2075. X *  
  2076. X * This program is distributed in the hope that it will be useful,
  2077. X * but WITHOUT ANY WARRANTY; without even the implied warranty of
  2078. X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  2079. X * GNU General Public License for more details.
  2080. X *
  2081. X * You should have received a copy of the GNU General Public License
  2082. X * along with this program (see the file COPYING); if not, write to the
  2083. X * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  2084. X *
  2085. X ****************************************************************
  2086. X */
  2087. X
  2088. X/*
  2089. X * NOTICE: tty.c is automatically generated from tty.sh
  2090. X * Do not change anything here. If you then change tty.sh.
  2091. X */
  2092. X
  2093. X#include "rcs.h"
  2094. XRCS_ID("$Id: tty.sh,v 1.2 1993/06/17 17:32:23 mlschroe Exp $ FAU")
  2095. X
  2096. X#include <stdio.h>
  2097. X#include <sys/types.h>
  2098. X#include <signal.h>
  2099. X#include <fcntl.h>
  2100. X#ifndef sun
  2101. X# include <sys/ioctl.h> /* collosions with termios.h */
  2102. X#else
  2103. X# include <sys/ttold.h>    /* needed for TIOCEXCL */
  2104. X#endif
  2105. X
  2106. X#ifdef ISC
  2107. X# include <sys/tty.h>
  2108. X# include <sys/sioctl.h>
  2109. X# include <sys/pty.h>
  2110. X#endif
  2111. X
  2112. X#include "config.h"
  2113. X#include "screen.h"
  2114. X#include "extern.h"
  2115. X
  2116. Xextern struct display *display, *displays;
  2117. Xextern int iflag;
  2118. X
  2119. X
  2120. X/*
  2121. X *  Carefully open a charcter device. Not used to open ttys.
  2122. X */
  2123. X
  2124. Xint
  2125. XOpenTTY(line)
  2126. Xchar *line;
  2127. X{
  2128. X  int f;
  2129. X  sig_t (*sigalrm)__P(SIGPROTOARG);
  2130. X
  2131. X  sigalrm = signal(SIGALRM, SIG_IGN);
  2132. X  alarm(2);
  2133. X  /* this open only succeeds, if real uid is allowed */
  2134. X  if ((f = secopen(line, O_RDWR | O_NDELAY, 0)) == -1)
  2135. X    {
  2136. X      Msg(errno, "Cannot open line '%s' for R/W", line);
  2137. X      alarm(0);
  2138. X      signal(SIGALRM, sigalrm);
  2139. X      return -1;
  2140. X    }
  2141. X#ifdef I_POP
  2142. X  debug("OpenTTY I_POP\n");
  2143. X  while (ioctl(f, I_POP) >= 0)
  2144. X    ;
  2145. X#endif
  2146. X  /*
  2147. X   * We come here exclusively. This is to stop all kermit and cu type things
  2148. X   * accessing the same tty line.
  2149. X   * Perhaps we should better create a lock in some /usr/spool/locks directory?
  2150. X   */
  2151. X#ifdef TIOCEXCL
  2152. X errno = 0;
  2153. X ioctl(f, TIOCEXCL, (char *) 0);
  2154. X debug3("%d %d %d\n", getuid(), geteuid(), getpid());
  2155. X debug2("%s TIOCEXCL errno %d\n", line, errno);
  2156. X#endif  /* TIOCEXCL */
  2157. X  /*
  2158. X   * We create a sane tty mode. We do not copy things from the display tty
  2159. X   */
  2160. X#if WE_REALLY_WANT_TO_COPY_THE_TTY_MODE
  2161. X  if (display)
  2162. X    {
  2163. X      debug1("OpenTTY: using mode of display for %s\n", line);
  2164. X      SetTTY(f, &d_NewMode);
  2165. X#ifdef DEBUG
  2166. X      DebugTTY(&d_NewMode);
  2167. X#endif
  2168. X    }
  2169. X  else
  2170. X#endif 
  2171. X    {
  2172. X      struct mode Mode;
  2173. X
  2174. X      InitTTY(&Mode, TTY_FLAG_PLAIN);
  2175. X#ifdef DEBUG
  2176. X      DebugTTY(&Mode);
  2177. X#endif
  2178. X      SetTTY(f, &Mode);
  2179. X    }
  2180. X  brktty(f);
  2181. X  alarm(0);
  2182. X  signal(SIGALRM, sigalrm);
  2183. X  debug2("'%s' CONNECT fd=%d.\n", line, f);
  2184. X  return f;
  2185. X}
  2186. X
  2187. X
  2188. X/*
  2189. X *  Tty mode handling
  2190. X */
  2191. X
  2192. X#if defined(TERMIO) || defined(POSIX)
  2193. Xint intrc, origintrc = VDISABLE;        /* display? */
  2194. X#else
  2195. Xint intrc, origintrc = -1;        /* display? */
  2196. X#endif
  2197. Xstatic startc, stopc;                   /* display? */
  2198. X
  2199. X
  2200. Xvoid
  2201. XInitTTY(m, ttyflag)
  2202. Xstruct mode *m;
  2203. Xint ttyflag;
  2204. X{
  2205. X  bzero((char *)m, sizeof(*m));
  2206. X#ifdef POSIX
  2207. X  /* struct termios tio 
  2208. X   * defaults, as seen on SunOS 4.1.3
  2209. X   */
  2210. X  debug1("InitTTY: POSIX: termios defaults a la SunOS 4.1.3 (%d)\n", ttyflag);
  2211. X#if defined(BRKINT)
  2212. X      m->tio.c_iflag |= BRKINT;
  2213. X#endif /* BRKINT */
  2214. X#if defined(IGNPAR)
  2215. X      m->tio.c_iflag |= IGNPAR;
  2216. X#endif /* IGNPAR */
  2217. X#if defined(ISTRIP)
  2218. X      m->tio.c_iflag |= ISTRIP;
  2219. X#endif /* ISTRIP */
  2220. X#if defined(IXON)
  2221. X      m->tio.c_iflag |= IXON;
  2222. X#endif /* IXON */
  2223. X#if defined(IMAXBEL)
  2224. X      m->tio.c_iflag |= IMAXBEL; 
  2225. X#endif /* IMAXBEL */
  2226. X
  2227. X  if (!ttyflag)    /* may not even be good for ptys.. */
  2228. X    {
  2229. X#if defined(ICRNL)
  2230. X      m->tio.c_iflag |= ICRNL;
  2231. X#endif /* ICRNL */
  2232. X#if defined(ONLCR)
  2233. X      m->tio.c_oflag |= ONLCR; 
  2234. X#endif /* ONLCR */
  2235. X#if defined(TAB3)
  2236. X      m->tio.c_oflag |= TAB3; 
  2237. X#endif /* TAB3 */
  2238. X#if defined(PARENB)
  2239. X      m->tio.c_cflag |= PARENB;
  2240. X#endif /* PARENB */
  2241. X    }
  2242. X
  2243. X#if defined(OPOST)
  2244. X      m->tio.c_oflag |= OPOST;
  2245. X#endif /* OPOST */
  2246. X
  2247. X#if defined(B9600)
  2248. X      m->tio.c_cflag |= B9600;
  2249. X#endif /* B9600 */
  2250. X#if defined(CS8)
  2251. X       m->tio.c_cflag |= CS8;
  2252. X#endif /* CS8 */
  2253. X#if defined(CREAD)
  2254. X      m->tio.c_cflag |= CREAD;
  2255. X#endif /* CREAD */
  2256. X#if defined(IBSHIFT) && defined(B9600)
  2257. X      m->tio.c_cflag |= B9600 << IBSHIFT;
  2258. X#endif /* IBSHIFT) && defined(B9600 */
  2259. X/* IF{CLOCAL}    m->tio.c_cflag |= CLOCAL; */
  2260. X
  2261. X#if defined(ECHOCTL)
  2262. X      m->tio.c_lflag |= ECHOCTL;
  2263. X#endif /* ECHOCTL */
  2264. X#if defined(ECHOKE)
  2265. X      m->tio.c_lflag |= ECHOKE;
  2266. X#endif /* ECHOKE */
  2267. X
  2268. X  if (!ttyflag)
  2269. X    {
  2270. X#if defined(ISIG)
  2271. X      m->tio.c_lflag |= ISIG;
  2272. X#endif /* ISIG */
  2273. X#if defined(ICANON)
  2274. X      m->tio.c_lflag |= ICANON;
  2275. X#endif /* ICANON */
  2276. X#if defined(ECHO)
  2277. X      m->tio.c_lflag |= ECHO;
  2278. X#endif /* ECHO */
  2279. X    }
  2280. X#if defined(ECHOE)
  2281. X      m->tio.c_lflag |= ECHOE;
  2282. X#endif /* ECHOE */
  2283. X#if defined(ECHOK)
  2284. X      m->tio.c_lflag |= ECHOK;
  2285. X#endif /* ECHOK */
  2286. X#if defined(IEXTEN)
  2287. X      m->tio.c_lflag |= IEXTEN;
  2288. X#endif /* IEXTEN */
  2289. X
  2290. X#if defined(VINTR)
  2291. X      m->tio.c_cc[VINTR]    = Ctrl('C');
  2292. X#endif /* VINTR */
  2293. X#if defined(VQUIT)
  2294. X      m->tio.c_cc[VQUIT]    = Ctrl('\\');
  2295. X#endif /* VQUIT */
  2296. X#if defined(VERASE)
  2297. X      m->tio.c_cc[VERASE]   = 0x7f; /* DEL */
  2298. X#endif /* VERASE */
  2299. X#if defined(VKILL)
  2300. X      m->tio.c_cc[VKILL]    = Ctrl('H');
  2301. X#endif /* VKILL */
  2302. X#if defined(VEOF)
  2303. X      m->tio.c_cc[VEOF]     = Ctrl('D');
  2304. X#endif /* VEOF */
  2305. X#if defined(VEOL)
  2306. X      m->tio.c_cc[VEOL]     = 0000;
  2307. X#endif /* VEOL */
  2308. X#if defined(VEOL2)
  2309. X      m->tio.c_cc[VEOL2]    = 0000;
  2310. X#endif /* VEOL2 */
  2311. X#if defined(VSWTCH)
  2312. X      m->tio.c_cc[VSWTCH]   = 0000;
  2313. X#endif /* VSWTCH */
  2314. X#if defined(VSTART)
  2315. X      m->tio.c_cc[VSTART]   = Ctrl('Q');
  2316. X#endif /* VSTART */
  2317. X#if defined(VSTOP)
  2318. X      m->tio.c_cc[VSTOP]    = Ctrl('S');
  2319. X#endif /* VSTOP */
  2320. X#if defined(VSUSP)
  2321. X      m->tio.c_cc[VSUSP]    = Ctrl('Z');
  2322. X#endif /* VSUSP */
  2323. X#if defined(VDSUSP)
  2324. X      m->tio.c_cc[VDSUSP]   = Ctrl('Y');
  2325. X#endif /* VDSUSP */
  2326. X#if defined(VREPRINT)
  2327. X      m->tio.c_cc[VREPRINT] = Ctrl('R');
  2328. X#endif /* VREPRINT */
  2329. X#if defined(VDISCARD)
  2330. X      m->tio.c_cc[VDISCARD] = Ctrl('O');
  2331. X#endif /* VDISCARD */
  2332. X#if defined(VWERASE)
  2333. X      m->tio.c_cc[VWERASE]  = Ctrl('W');
  2334. X#endif /* VWERASE */
  2335. X#if defined(VLNEXT)
  2336. X      m->tio.c_cc[VLNEXT]   = Ctrl('V');
  2337. X#endif /* VLNEXT */
  2338. X#if defined(VSTATUS)
  2339. X      m->tio.c_cc[VSTATUS]  = Ctrl('T');
  2340. X#endif /* VSTATUS */
  2341. X
  2342. X# ifdef hpux
  2343. X  m->m_ltchars.t_suspc =  Ctrl('Z');
  2344. X  m->m_ltchars.t_dsuspc = Ctrl('Y');
  2345. X  m->m_ltchars.t_rprntc = Ctrl('R');
  2346. X  m->m_ltchars.t_flushc = Ctrl('O');
  2347. X  m->m_ltchars.t_werasc = Ctrl('W');
  2348. X  m->m_ltchars.t_lnextc = Ctrl('V');
  2349. X# endif /* hpux */
  2350. X
  2351. X#else /* POSIX */
  2352. X
  2353. X# ifdef TERMIO
  2354. X  debug1("InitTTY: nonPOSIX, struct termio a la Motorola SYSV68 (%d)\n", ttyflag);
  2355. X  /* struct termio tio 
  2356. X   * defaults, as seen on Mototola SYSV68:
  2357. X   * input: 7bit, CR->NL, ^S/^Q flow control 
  2358. X   * output: POSTprocessing: NL->NL-CR, Tabs to spaces
  2359. X   * control: 9600baud, 8bit CSIZE, enable input
  2360. X   * local: enable signals, erase/kill processing, echo on.
  2361. X   */
  2362. X#if defined(ISTRIP)
  2363. X      m->tio.c_iflag |= ISTRIP;
  2364. X#endif /* ISTRIP */
  2365. X#if defined(IXON)
  2366. X      m->tio.c_iflag |= IXON;
  2367. X#endif /* IXON */
  2368. X
  2369. X#if defined(OPOST)
  2370. X      m->tio.c_oflag |= OPOST;
  2371. X#endif /* OPOST */
  2372. X
  2373. X  if (!ttyflag)    /* may not even be good for ptys.. */
  2374. X    {
  2375. X#if defined(ICRNL)
  2376. X      m->tio.c_iflag |= ICRNL;
  2377. X#endif /* ICRNL */
  2378. X#if defined(ONLCR)
  2379. X      m->tio.c_oflag |= ONLCR;
  2380. X#endif /* ONLCR */
  2381. X#if defined(TAB3)
  2382. X      m->tio.c_oflag |= TAB3;
  2383. X#endif /* TAB3 */
  2384. X    }
  2385. X
  2386. X#if defined(B9600)
  2387. X      m->tio.c_cflag  = B9600;
  2388. X#endif /* B9600 */
  2389. X#if defined(CS8)
  2390. X       m->tio.c_cflag |= CS8;
  2391. X#endif /* CS8 */
  2392. X#if defined(CREAD)
  2393. X      m->tio.c_cflag |= CREAD;
  2394. X#endif /* CREAD */
  2395. X
  2396. X  if (!ttyflag)
  2397. X    {
  2398. X#if defined(ISIG)
  2399. X      m->tio.c_lflag |= ISIG;
  2400. X#endif /* ISIG */
  2401. X#if defined(ICANON)
  2402. X      m->tio.c_lflag |= ICANON;
  2403. X#endif /* ICANON */
  2404. X#if defined(ECHO)
  2405. X      m->tio.c_lflag |= ECHO;
  2406. X#endif /* ECHO */
  2407. X    }
  2408. X#if defined(ECHOE)
  2409. X      m->tio.c_lflag |= ECHOE;
  2410. X#endif /* ECHOE */
  2411. X#if defined(ECHOK)
  2412. X      m->tio.c_lflag |= ECHOK;
  2413. X#endif /* ECHOK */
  2414. X
  2415. X#if defined(VINTR)
  2416. X      m->tio.c_cc[VINTR]  = Ctrl('C');
  2417. X#endif /* VINTR */
  2418. X#if defined(VQUIT)
  2419. X      m->tio.c_cc[VQUIT]  = Ctrl('\\');
  2420. X#endif /* VQUIT */
  2421. X#if defined(VERASE)
  2422. X      m->tio.c_cc[VERASE] = 0177; /* DEL */
  2423. X#endif /* VERASE */
  2424. X#if defined(VKILL)
  2425. X      m->tio.c_cc[VKILL]  = Ctrl('H');
  2426. X#endif /* VKILL */
  2427. X#if defined(VEOF)
  2428. X      m->tio.c_cc[VEOF]   = Ctrl('D');
  2429. X#endif /* VEOF */
  2430. X#if defined(VEOL)
  2431. X      m->tio.c_cc[VEOL]   = 0377;
  2432. X#endif /* VEOL */
  2433. X#if defined(VEOL2)
  2434. X      m->tio.c_cc[VEOL2]  = 0377;
  2435. X#endif /* VEOL2 */
  2436. X#if defined(VSWTCH)
  2437. X      m->tio.c_cc[VSWTCH] = 0000;
  2438. X#endif /* VSWTCH */
  2439. X# else /* TERMIO */
  2440. X  debug1("InitTTY: BSD: defaults a la SunOS 4.1.3 (%d)\n", ttyflag);
  2441. X  m->m_ttyb.sg_ispeed = B9600;
  2442. X  m->m_ttyb.sg_ospeed = B9600;
  2443. X  m->m_ttyb.sg_erase  = 0177; /*DEL */
  2444. X  m->m_ttyb.sg_kill   = Ctrl('H');
  2445. X  if (!ttyflag)
  2446. X    m->m_ttyb.sg_flags = CRMOD | ECHO
  2447. X#if defined(ANYP)
  2448. X      | ANYP
  2449. X#endif /* ANYP */
  2450. X    ;
  2451. X  else
  2452. X    m->m_ttyb.sg_flags = CBREAK
  2453. X#if defined(ANYP)
  2454. X      | ANYP
  2455. X#endif /* ANYP */
  2456. X    ;
  2457. X
  2458. X  m->m_tchars.t_intrc   = Ctrl('C');
  2459. X  m->m_tchars.t_quitc   = Ctrl('\\');
  2460. X  m->m_tchars.t_startc  = Ctrl('Q');
  2461. X  m->m_tchars.t_stopc   = Ctrl('S');
  2462. X  m->m_tchars.t_eofc    = Ctrl('D');
  2463. X  m->m_tchars.t_brkc    = -1;
  2464. X
  2465. X  m->m_ltchars.t_suspc  = Ctrl('Z');
  2466. X  m->m_ltchars.t_dsuspc = Ctrl('Y');
  2467. X  m->m_ltchars.t_rprntc = Ctrl('R');
  2468. X  m->m_ltchars.t_flushc = Ctrl('O');
  2469. X  m->m_ltchars.t_werasc = Ctrl('W');
  2470. X  m->m_ltchars.t_lnextc = Ctrl('V');
  2471. X
  2472. X#if defined(NTTYDISC)
  2473. X      m->m_ldisc = NTTYDISC;
  2474. X#endif /* NTTYDISC */
  2475. X
  2476. X  m->m_lmode = 0
  2477. X#if defined(LDECCTQ)
  2478. X      | LDECCTQ
  2479. X#endif /* LDECCTQ */
  2480. X#if defined(LCTLECH)
  2481. X      | LCTLECH
  2482. X#endif /* LCTLECH */
  2483. X#if defined(LPASS8)
  2484. X      | LPASS8
  2485. X#endif /* LPASS8 */
  2486. X#if defined(LCRTKIL)
  2487. X      | LCRTKIL
  2488. X#endif /* LCRTKIL */
  2489. X#if defined(LCRTERA)
  2490. X      | LCRTERA
  2491. X#endif /* LCRTERA */
  2492. X#if defined(LCRTBS)
  2493. X      | LCRTBS
  2494. X#endif /* LCRTBS */
  2495. X;
  2496. X# endif /* TERMIO */
  2497. X#endif /* POSIX */
  2498. X}
  2499. X
  2500. Xvoid 
  2501. XSetTTY(fd, mp)
  2502. Xint fd;
  2503. Xstruct mode *mp;
  2504. X{
  2505. X  errno = 0;
  2506. X#ifdef POSIX
  2507. X  tcsetattr(fd, TCSADRAIN, &mp->tio);
  2508. X# ifdef hpux
  2509. X  ioctl(fd, TIOCSLTC, &mp->m_ltchars);
  2510. X# endif
  2511. X#else
  2512. X# ifdef TERMIO
  2513. X  ioctl(fd, TCSETAW, &mp->tio);
  2514. X# else
  2515. X  /* ioctl(fd, TIOCSETP, &mp->m_ttyb); */
  2516. X  ioctl(fd, TIOCSETC, &mp->m_tchars);
  2517. X  ioctl(fd, TIOCLSET, &mp->m_lmode);
  2518. X  ioctl(fd, TIOCSETD, &mp->m_ldisc);
  2519. X  ioctl(fd, TIOCSETP, &mp->m_ttyb);
  2520. X  ioctl(fd, TIOCSLTC, &mp->m_ltchars); /* moved here for apollo. jw */
  2521. X# endif
  2522. X#endif
  2523. X  if (errno)
  2524. X    Msg(errno, "SetTTY (fd %d): ioctl failed", fd);
  2525. X}
  2526. X
  2527. Xvoid
  2528. XGetTTY(fd, mp)
  2529. Xint fd;
  2530. Xstruct mode *mp;
  2531. X{
  2532. X  errno = 0;
  2533. X#ifdef POSIX
  2534. X  tcgetattr(fd, &mp->tio);
  2535. X# ifdef hpux
  2536. X  ioctl(fd, TIOCGLTC, &mp->m_ltchars);
  2537. X# endif
  2538. X#else
  2539. X# ifdef TERMIO
  2540. X  ioctl(fd, TCGETA, &mp->tio);
  2541. X# else
  2542. X  ioctl(fd, TIOCGETP, &mp->m_ttyb);
  2543. X  ioctl(fd, TIOCGETC, &mp->m_tchars);
  2544. X  ioctl(fd, TIOCGLTC, &mp->m_ltchars);
  2545. X  ioctl(fd, TIOCLGET, &mp->m_lmode);
  2546. X  ioctl(fd, TIOCGETD, &mp->m_ldisc);
  2547. X# endif
  2548. X#endif
  2549. X  if (errno)
  2550. X    Msg(errno, "GetTTY (fd %d): ioctl failed", fd);
  2551. X}
  2552. X
  2553. Xvoid
  2554. XSetMode(op, np)
  2555. Xstruct mode *op, *np;
  2556. X{
  2557. X  *np = *op;
  2558. X
  2559. X#if defined(TERMIO) || defined(POSIX)
  2560. X  np->tio.c_iflag &= ~ICRNL;
  2561. X# ifdef ONLCR
  2562. X  np->tio.c_oflag &= ~ONLCR;
  2563. X# endif
  2564. X  np->tio.c_lflag &= ~(ICANON | ECHO);
  2565. X
  2566. X  /*
  2567. X   * Unfortunately, the master process never will get SIGINT if the real
  2568. X   * terminal is different from the one on which it was originaly started
  2569. X   * (process group membership has not been restored or the new tty could not
  2570. X   * be made controlling again). In my solution, it is the attacher who
  2571. X   * receives SIGINT (because it is always correctly associated with the real
  2572. X   * tty) and forwards it to the master [kill(MasterPid, SIGINT)]. 
  2573. X   * Marc Boucher (marc@CAM.ORG)
  2574. X   */
  2575. X  if (iflag)
  2576. X    np->tio.c_lflag |= ISIG;
  2577. X  else
  2578. X    np->tio.c_lflag &= ~ISIG;
  2579. X  /* 
  2580. X   * careful, careful catche monkey..
  2581. X   * never set VMIN and VTIME to zero, if you want blocking io.
  2582. X   */
  2583. X  np->tio.c_cc[VMIN] = 1;
  2584. X  np->tio.c_cc[VTIME] = 0;
  2585. X#if defined(VSTART)
  2586. X      startc = op->tio.c_cc[VSTART];
  2587. X#endif /* VSTART */
  2588. X#if defined(VSTOP)
  2589. X      stopc = op->tio.c_cc[VSTOP];
  2590. X#endif /* VSTOP */
  2591. X  if (iflag)
  2592. X    origintrc = intrc = op->tio.c_cc[VINTR];
  2593. X  else
  2594. X    {
  2595. X      origintrc = op->tio.c_cc[VINTR];
  2596. X      intrc = np->tio.c_cc[VINTR] = VDISABLE;
  2597. X    }
  2598. X  np->tio.c_cc[VQUIT] = VDISABLE;
  2599. X  if (d_flow == 0)
  2600. X    {
  2601. X      np->tio.c_cc[VINTR] = VDISABLE;
  2602. X#if defined(VSTART)
  2603. X      np->tio.c_cc[VSTART] = VDISABLE;
  2604. X#endif /* VSTART */
  2605. X#if defined(VSTOP)
  2606. X      np->tio.c_cc[VSTOP] = VDISABLE;
  2607. X#endif /* VSTOP */
  2608. X      np->tio.c_iflag &= ~IXON;
  2609. X    }
  2610. X#if defined(VDISCARD)
  2611. X      np->tio.c_cc[VDISCARD] = VDISABLE;
  2612. X#endif /* VDISCARD */
  2613. X#if defined(VSUSP)
  2614. X      np->tio.c_cc[VSUSP] = VDISABLE;
  2615. X#endif /* VSUSP */
  2616. X# ifdef hpux
  2617. X  np->m_ltchars.t_suspc  = VDISABLE;
  2618. X  np->m_ltchars.t_dsuspc = VDISABLE;
  2619. X  np->m_ltchars.t_rprntc = VDISABLE;
  2620. X  np->m_ltchars.t_flushc = VDISABLE;
  2621. X  np->m_ltchars.t_werasc = VDISABLE;
  2622. X  np->m_ltchars.t_lnextc = VDISABLE;
  2623. X# else /* hpux */
  2624. X#if defined(VDSUSP)
  2625. X      np->tio.c_cc[VDSUSP] = VDISABLE;
  2626. X#endif /* VDSUSP */
  2627. X# endif /* hpux */
  2628. X#else /* TERMIO || POSIX */
  2629. X  startc = op->m_tchars.t_startc;
  2630. X  stopc = op->m_tchars.t_stopc;
  2631. X  if (iflag)
  2632. X    origintrc = intrc = op->m_tchars.t_intrc;
  2633. X  else
  2634. X    {
  2635. X      origintrc = op->m_tchars.t_intrc;
  2636. X      intrc = np->m_tchars.t_intrc = -1;
  2637. X    }
  2638. X  np->m_ttyb.sg_flags &= ~(CRMOD | ECHO);
  2639. X  np->m_ttyb.sg_flags |= CBREAK;
  2640. X  np->m_tchars.t_quitc = -1;
  2641. X  if (d_flow == 0)
  2642. X    {
  2643. X      np->m_tchars.t_intrc = -1;
  2644. X      np->m_tchars.t_startc = -1;
  2645. X      np->m_tchars.t_stopc = -1;
  2646. X    }
  2647. X  np->m_ltchars.t_suspc = -1;
  2648. X  np->m_ltchars.t_dsuspc = -1;
  2649. X  np->m_ltchars.t_flushc = -1;
  2650. X  np->m_ltchars.t_lnextc = -1;
  2651. X#endif /* defined(TERMIO) || defined(POSIX) */
  2652. X}
  2653. X
  2654. Xvoid
  2655. XSetFlow(on)
  2656. Xint on;
  2657. X{
  2658. X  ASSERT(display);
  2659. X  if (d_flow == on)
  2660. X    return;
  2661. X#if defined(TERMIO) || defined(POSIX)
  2662. X  if (on)
  2663. X    {
  2664. X      d_NewMode.tio.c_cc[VINTR] = intrc;
  2665. X#if defined(VSTART)
  2666. X      d_NewMode.tio.c_cc[VSTART] = startc;
  2667. X#endif /* VSTART */
  2668. X#if defined(VSTOP)
  2669. X      d_NewMode.tio.c_cc[VSTOP] = stopc;
  2670. X#endif /* VSTOP */
  2671. X      d_NewMode.tio.c_iflag |= IXON;
  2672. X    }
  2673. X  else
  2674. X    {
  2675. X      d_NewMode.tio.c_cc[VINTR] = VDISABLE;
  2676. X#if defined(VSTART)
  2677. X      d_NewMode.tio.c_cc[VSTART] = VDISABLE;
  2678. X#endif /* VSTART */
  2679. X#if defined(VSTOP)
  2680. X      d_NewMode.tio.c_cc[VSTOP] = VDISABLE;
  2681. X#endif /* VSTOP */
  2682. X      d_NewMode.tio.c_iflag &= ~IXON;
  2683. X    }
  2684. X# ifdef POSIX
  2685. X  if (tcsetattr(d_userfd, TCSANOW, &d_NewMode.tio))
  2686. X# else
  2687. X  if (ioctl(d_userfd, TCSETAW, &d_NewMode.tio) != 0)
  2688. X# endif
  2689. X    debug1("SetFlow: ioctl errno %d\n", errno);
  2690. X#else /* POSIX || TERMIO */
  2691. X  if (on)
  2692. X    {
  2693. X      d_NewMode.m_tchars.t_intrc = intrc;
  2694. X      d_NewMode.m_tchars.t_startc = startc;
  2695. X      d_NewMode.m_tchars.t_stopc = stopc;
  2696. X    }
  2697. X  else
  2698. X    {
  2699. X      d_NewMode.m_tchars.t_intrc = -1;
  2700. X      d_NewMode.m_tchars.t_startc = -1;
  2701. X      d_NewMode.m_tchars.t_stopc = -1;
  2702. X    }
  2703. X  if (ioctl(d_userfd, TIOCSETC, &d_NewMode.m_tchars) != 0)
  2704. X    debug1("SetFlow: ioctl errno %d\n", errno);
  2705. X#endif /* POSIX || TERMIO */
  2706. X  d_flow = on;
  2707. X}
  2708. X
  2709. X
  2710. X/*
  2711. X *  Job control handling
  2712. X */
  2713. X
  2714. X/*ARGSUSED*/
  2715. Xvoid
  2716. Xbrktty(fd)
  2717. Xint fd;
  2718. X{
  2719. X#ifdef POSIX
  2720. X  setsid();        /* will break terminal affiliation */
  2721. X# ifdef BSD
  2722. X  ioctl(fd, TIOCSCTTY, 0);
  2723. X# endif /* BSD */
  2724. X#else /* POSIX */
  2725. X# ifdef SYSV
  2726. X  setpgrp();        /* will break terminal affiliation */
  2727. X# else /* SYSV */
  2728. X#  ifdef BSDJOBS
  2729. X  int devtty;
  2730. X
  2731. X  if ((devtty = open("/dev/tty", O_RDWR | O_NDELAY)) >= 0)
  2732. X    {
  2733. X      if (ioctl(devtty, TIOCNOTTY, (char *)0))
  2734. X        debug2("brktty: ioctl(devtty=%d, TIOCNOTTY, 0) = %d\n", devtty, errno);
  2735. X      close(devtty);
  2736. X    }
  2737. X#  endif /* BSDJOBS */
  2738. X# endif /* SYSV */
  2739. X#endif /* POSIX */
  2740. X}
  2741. X
  2742. Xint
  2743. Xfgtty(fd)
  2744. Xint fd;
  2745. X{
  2746. X#ifdef BSDJOBS
  2747. X  int mypid;
  2748. X
  2749. X  mypid = getpid();
  2750. X
  2751. X# if defined(BSDI) || defined(__386BSD__) || defined(__osf__)
  2752. X  setsid();    /* should be already done */
  2753. X  ioctl(fd, TIOCSCTTY, 0);
  2754. X# endif /* BSDI || __386BSD__ */
  2755. X
  2756. X# ifdef POSIX
  2757. X  if (tcsetpgrp(fd, mypid))
  2758. X    {
  2759. X      debug1("fgtty: tcsetpgrp: %d\n", errno);
  2760. X      return -1;
  2761. X    }
  2762. X# else /* POSIX */
  2763. X  if (ioctl(fd, TIOCSPGRP, &mypid) != 0)
  2764. X    debug1("fgtty: TIOSETPGRP: %d\n", errno);
  2765. X#  ifndef SYSV    /* Already done in brktty():setpgrp() */
  2766. X  if (setpgrp(fd, mypid))
  2767. X    debug1("fgtty: setpgrp: %d\n", errno);
  2768. X#  endif
  2769. X# endif /* POSIX */
  2770. X#endif /* BSDJOBS */
  2771. X  return 0;
  2772. X}
  2773. X
  2774. X
  2775. X/* 
  2776. X * Send a break for n * 0.25 seconds. Tty must be PLAIN.
  2777. X */
  2778. X
  2779. Xvoid SendBreak(wp, n, closeopen)
  2780. Xstruct win *wp;
  2781. Xint n, closeopen;
  2782. X{
  2783. X  if ((wp->w_t.flags & TTY_FLAG_PLAIN) == 0)
  2784. X    return;
  2785. X
  2786. X  debug3("break(%d, %d) fd %d\n", n, closeopen, wp->w_ptyfd);
  2787. X#ifdef POSIX
  2788. X  (void) tcflush(wp->w_ptyfd, TCIOFLUSH);
  2789. X#else
  2790. X# ifdef TIOCFLUSH
  2791. X  (void) ioctl(wp->w_ptyfd, TIOCFLUSH, (char *)0);
  2792. X# endif /* TIOCFLUSH */
  2793. X#endif /* POSIX */
  2794. X  if (closeopen)
  2795. X    {
  2796. X      close(wp->w_ptyfd);
  2797. X      sleep((n + 3) / 4);
  2798. X      if ((wp->w_ptyfd = OpenTTY(wp->w_tty)) < 1)
  2799. X    {
  2800. X      Msg(0, "Ouch, cannot reopen line %s, please try harder", wp->w_tty);
  2801. X      return;
  2802. X    }
  2803. X    }
  2804. X  else
  2805. X    {
  2806. X#ifdef POSIX 
  2807. X      debug("tcsendbreak\n");
  2808. X      if (tcsendbreak(wp->w_ptyfd, n) < 0)
  2809. X    {
  2810. X      Msg(errno, "cannot send BREAK");
  2811. X      return;
  2812. X    }
  2813. X#else
  2814. X      if (!n)
  2815. X    n++;
  2816. X# ifdef TCSBRK
  2817. X      debug("TCSBRK\n");
  2818. X    {
  2819. X      int i;
  2820. X      for (i = 0; i < n; i++)
  2821. X        if (ioctl(wp->w_ptyfd, TCSBRK, (char *)0) < 0)
  2822. X          {
  2823. X        Msg(errno, "Cannot send BREAK");
  2824. X        return;
  2825. X          }
  2826. X    }
  2827. X# else /* TCSBRK */
  2828. X#  if defined(TIOCSBRK) && defined(TIOCCBRK)
  2829. X      debug("TIOCSBRK TIOCCBRK\n");
  2830. X      if (ioctl(wp->w_ptyfd, TIOCSBRK, (char *)0) < 0)
  2831. X    {
  2832. X      Msg(errno, "Can't send BREAK");
  2833. X      return;
  2834. X    }
  2835. X      sleep((n + 3) / 4);
  2836. X      if (ioctl(wp->w_ptyfd, TIOCCBRK, (char *)0) < 0)
  2837. X    {
  2838. X      Msg(errno, "BREAK stuck!!! -- HELP!");
  2839. X      return;
  2840. X    }
  2841. X#  else /* TIOCSBRK && TIOCCBRK */
  2842. X      Msg(0, "Break not simulated yet"); 
  2843. X      return;
  2844. X#  endif /* TIOCSBRK && TIOCCBRK */
  2845. X# endif /* TCSBRK */
  2846. X#endif /* POSIX */
  2847. X      debug("            broken\n");
  2848. X    }
  2849. X}
  2850. X
  2851. X
  2852. X/*
  2853. X *  Console grabbing
  2854. X */
  2855. X
  2856. X/*ARGSUSED*/
  2857. Xint
  2858. XTtyGrabConsole(fd, on, rc_name)
  2859. Xint fd, on;
  2860. Xchar *rc_name;
  2861. X{
  2862. X#ifdef TIOCCONS
  2863. X  char *slave;
  2864. X  int sfd = -1, ret = 0;
  2865. X  struct display *d;
  2866. X
  2867. X  if (!on)
  2868. X    {
  2869. X      if ((fd = OpenPTY(&slave)) < 0)
  2870. X    {
  2871. X      Msg(errno, "%s: could not open detach pty master", rc_name);
  2872. X      return -1;
  2873. X    }
  2874. X      if ((sfd = open(slave, O_RDWR)) < 0)
  2875. X    {
  2876. X      Msg(errno, "%s: could not open detach pty slave", rc_name);
  2877. X      close(fd);
  2878. X      return -1;
  2879. X    }
  2880. X    }
  2881. X  else
  2882. X    {
  2883. X      if (displays == 0)
  2884. X    {
  2885. X      Msg(0, "I need a display");
  2886. X      return -1;
  2887. X    }
  2888. X      for (d = displays; d; d = d->_d_next)
  2889. X    if (strcmp(d->_d_usertty, "/dev/console") == 0)
  2890. X      break;
  2891. X      if (d)
  2892. X    {
  2893. X      Msg(0, "too dangerous - screen is running on /dev/console");
  2894. X      return -1;
  2895. X    }
  2896. X    }
  2897. X  if (UserContext() == 1)
  2898. X    UserReturn(ioctl(fd, TIOCCONS, &on));
  2899. X  ret = UserStatus();
  2900. X  if (ret)
  2901. X    Msg(errno, "%s: ioctl TIOCCONS failed", rc_name);
  2902. X  if (!on)
  2903. X    {
  2904. X      close(sfd);
  2905. X      close(fd);
  2906. X    }
  2907. X  return ret;
  2908. X#else /* TIOCCONS */
  2909. X  Msg(0, "%s: no TIOCCONS on this machine", rc_name);
  2910. X  return -1;
  2911. X#endif /* TIOCCONS */
  2912. X}
  2913. X
  2914. X
  2915. X/*
  2916. X *  Write out the mode struct in a readable form
  2917. X */
  2918. X
  2919. X#ifdef DEBUG
  2920. Xvoid
  2921. XDebugTTY(m)
  2922. Xstruct mode *m;
  2923. X{
  2924. X  int i;
  2925. X
  2926. X#ifdef POSIX
  2927. X  debug("struct termios tio:\n");
  2928. X  debug1("c_iflag = %#x\n", m->tio.c_iflag);
  2929. X  debug1("c_oflag = %#x\n", m->tio.c_oflag);
  2930. X  debug1("c_cflag = %#x\n", m->tio.c_cflag);
  2931. X  debug1("c_lflag = %#x\n", m->tio.c_lflag);
  2932. X  for (i = 0; i < NCCS; i++)
  2933. X    {
  2934. X      debug2("c_cc[%d] = %#x\n", i, m->tio.c_cc[i]);
  2935. X    }
  2936. X# ifdef hpux
  2937. X  debug1("suspc     = %#02x\n", m->m_ltchars.t_suspc);
  2938. X  debug1("dsuspc    = %#02x\n", m->m_ltchars.t_dsuspc);
  2939. X  debug1("rprntc    = %#02x\n", m->m_ltchars.t_rprntc);
  2940. X  debug1("flushc    = %#02x\n", m->m_ltchars.t_flushc);
  2941. X  debug1("werasc    = %#02x\n", m->m_ltchars.t_werasc);
  2942. X  debug1("lnextc    = %#02x\n", m->m_ltchars.t_lnextc);
  2943. X# endif /* hpux */
  2944. X#else /* POSIX */
  2945. X# ifdef TERMIO
  2946. X  debug("struct termio tio:\n");
  2947. X  debug1("c_iflag = %04o\n", m->tio.c_iflag);
  2948. X  debug1("c_oflag = %04o\n", m->tio.c_oflag);
  2949. X  debug1("c_cflag = %04o\n", m->tio.c_cflag);
  2950. X  debug1("c_lflag = %04o\n", m->tio.c_lflag);
  2951. X  for (i = 0; i < NCC; i++)
  2952. X    {
  2953. X      debug2("c_cc[%d] = %04o\n", i, m->tio.c_cc[i]);
  2954. X    }
  2955. X# else /* TERMIO */
  2956. X  debug1("sg_ispeed = %d\n",    m->m_ttyb.sg_ispeed);
  2957. X  debug1("sg_ospeed = %d\n",    m->m_ttyb.sg_ospeed);
  2958. X  debug1("sg_erase  = %#02x\n", m->m_ttyb.sg_erase);
  2959. X  debug1("sg_kill   = %#02x\n", m->m_ttyb.sg_kill);
  2960. X  debug1("sg_flags  = %#04x\n", (unsigned short)m->m_ttyb.sg_flags);
  2961. X  debug1("intrc     = %#02x\n", m->m_tchars.t_intrc);
  2962. X  debug1("quitc     = %#02x\n", m->m_tchars.t_quitc);
  2963. X  debug1("startc    = %#02x\n", m->m_tchars.t_startc);
  2964. X  debug1("stopc     = %#02x\n", m->m_tchars.t_stopc);
  2965. X  debug1("eofc      = %#02x\n", m->m_tchars.t_eofc);
  2966. X  debug1("brkc      = %#02x\n", m->m_tchars.t_brkc);
  2967. X  debug1("suspc     = %#02x\n", m->m_ltchars.t_suspc);
  2968. X  debug1("dsuspc    = %#02x\n", m->m_ltchars.t_dsuspc);
  2969. X  debug1("rprntc    = %#02x\n", m->m_ltchars.t_rprntc);
  2970. X  debug1("flushc    = %#02x\n", m->m_ltchars.t_flushc);
  2971. X  debug1("werasc    = %#02x\n", m->m_ltchars.t_werasc);
  2972. X  debug1("lnextc    = %#02x\n", m->m_ltchars.t_lnextc);
  2973. X  debug1("ldisc     = %d\n",    m->m_ldisc);
  2974. X  debug1("lmode     = %#x\n",   m->m_lmode);
  2975. X# endif /* TERMIO */
  2976. X#endif /* POSIX */
  2977. X}
  2978. X#endif /* DEBUG */
  2979. END_OF_FILE
  2980. if test 21390 -ne `wc -c <'tty.c.dist'`; then
  2981.     echo shar: \"'tty.c.dist'\" unpacked with wrong size!
  2982. fi
  2983. # end of 'tty.c.dist'
  2984. fi
  2985. if test -f 'tty.sh' -a "${1}" != "-c" ; then 
  2986.   echo shar: Will not clobber existing file \"'tty.sh'\"
  2987. else
  2988. echo shar: Extracting \"'tty.sh'\" \(19054 characters\)
  2989. sed "s/^X//" >'tty.sh' <<'END_OF_FILE'
  2990. X#!/bin/sh
  2991. X# sh tty.sh tty.c
  2992. X# This inserts all the needed #ifdefs for IF{} statements
  2993. X# and generates tty.c
  2994. X
  2995. Xrm -f $1
  2996. Xsed -e '1,12d' -e 's%^IF{\(.*\)}\(.*\)%#if defined(\1)\
  2997. X  \2\
  2998. X#endif /* \1 */%' < $0 > $1
  2999. Xchmod -w $1
  3000. Xexit 0
  3001. X
  3002. X/* Copyright (c) 1993
  3003. X *      Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
  3004. X *      Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
  3005. X * Copyright (c) 1987 Oliver Laumann
  3006. X *
  3007. X * This program is free software; you can redistribute it and/or modify
  3008. X * it under the terms of the GNU General Public License as published by
  3009. X * the Free Software Foundation; either version 2, or (at your option)
  3010. X * any later version.
  3011. X *  
  3012. X * This program is distributed in the hope that it will be useful,
  3013. X * but WITHOUT ANY WARRANTY; without even the implied warranty of
  3014. X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  3015. X * GNU General Public License for more details.
  3016. X *
  3017. X * You should have received a copy of the GNU General Public License
  3018. X * along with this program (see the file COPYING); if not, write to the
  3019. X * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  3020. X *
  3021. X ****************************************************************
  3022. X */
  3023. X
  3024. X/*
  3025. X * NOTICE: tty.c is automatically generated from tty.sh
  3026. X * Do not change anything here. If you then change tty.sh.
  3027. X */
  3028. X
  3029. X#include "rcs.h"
  3030. XRCS_ID("$Id: tty.sh,v 1.2 1993/06/17 17:32:23 mlschroe Exp $ FAU")
  3031. X
  3032. X#include <stdio.h>
  3033. X#include <sys/types.h>
  3034. X#include <signal.h>
  3035. X#include <fcntl.h>
  3036. X#ifndef sun
  3037. X# include <sys/ioctl.h> /* collosions with termios.h */
  3038. X#else
  3039. X# include <sys/ttold.h>    /* needed for TIOCEXCL */
  3040. X#endif
  3041. X
  3042. X#ifdef ISC
  3043. X# include <sys/tty.h>
  3044. X# include <sys/sioctl.h>
  3045. X# include <sys/pty.h>
  3046. X#endif
  3047. X
  3048. X#include "config.h"
  3049. X#include "screen.h"
  3050. X#include "extern.h"
  3051. X
  3052. Xextern struct display *display, *displays;
  3053. Xextern int iflag;
  3054. X
  3055. X
  3056. X/*
  3057. X *  Carefully open a charcter device. Not used to open ttys.
  3058. X */
  3059. X
  3060. Xint
  3061. XOpenTTY(line)
  3062. Xchar *line;
  3063. X{
  3064. X  int f;
  3065. X  sig_t (*sigalrm)__P(SIGPROTOARG);
  3066. X
  3067. X  sigalrm = signal(SIGALRM, SIG_IGN);
  3068. X  alarm(2);
  3069. X  /* this open only succeeds, if real uid is allowed */
  3070. X  if ((f = secopen(line, O_RDWR | O_NDELAY, 0)) == -1)
  3071. X    {
  3072. X      Msg(errno, "Cannot open line '%s' for R/W", line);
  3073. X      alarm(0);
  3074. X      signal(SIGALRM, sigalrm);
  3075. X      return -1;
  3076. X    }
  3077. X#ifdef I_POP
  3078. X  debug("OpenTTY I_POP\n");
  3079. X  while (ioctl(f, I_POP) >= 0)
  3080. X    ;
  3081. X#endif
  3082. X  /*
  3083. X   * We come here exclusively. This is to stop all kermit and cu type things
  3084. X   * accessing the same tty line.
  3085. X   * Perhaps we should better create a lock in some /usr/spool/locks directory?
  3086. X   */
  3087. X#ifdef TIOCEXCL
  3088. X errno = 0;
  3089. X ioctl(f, TIOCEXCL, (char *) 0);
  3090. X debug3("%d %d %d\n", getuid(), geteuid(), getpid());
  3091. X debug2("%s TIOCEXCL errno %d\n", line, errno);
  3092. X#endif  /* TIOCEXCL */
  3093. X  /*
  3094. X   * We create a sane tty mode. We do not copy things from the display tty
  3095. X   */
  3096. X#if WE_REALLY_WANT_TO_COPY_THE_TTY_MODE
  3097. X  if (display)
  3098. X    {
  3099. X      debug1("OpenTTY: using mode of display for %s\n", line);
  3100. X      SetTTY(f, &d_NewMode);
  3101. X#ifdef DEBUG
  3102. X      DebugTTY(&d_NewMode);
  3103. X#endif
  3104. X    }
  3105. X  else
  3106. X#endif 
  3107. X    {
  3108. X      struct mode Mode;
  3109. X
  3110. X      InitTTY(&Mode, TTY_FLAG_PLAIN);
  3111. X#ifdef DEBUG
  3112. X      DebugTTY(&Mode);
  3113. X#endif
  3114. X      SetTTY(f, &Mode);
  3115. X    }
  3116. X  brktty(f);
  3117. X  alarm(0);
  3118. X  signal(SIGALRM, sigalrm);
  3119. X  debug2("'%s' CONNECT fd=%d.\n", line, f);
  3120. X  return f;
  3121. X}
  3122. X
  3123. X
  3124. X/*
  3125. X *  Tty mode handling
  3126. X */
  3127. X
  3128. X#if defined(TERMIO) || defined(POSIX)
  3129. Xint intrc, origintrc = VDISABLE;        /* display? */
  3130. X#else
  3131. Xint intrc, origintrc = -1;        /* display? */
  3132. X#endif
  3133. Xstatic startc, stopc;                   /* display? */
  3134. X
  3135. X
  3136. Xvoid
  3137. XInitTTY(m, ttyflag)
  3138. Xstruct mode *m;
  3139. Xint ttyflag;
  3140. X{
  3141. X  bzero((char *)m, sizeof(*m));
  3142. X#ifdef POSIX
  3143. X  /* struct termios tio 
  3144. X   * defaults, as seen on SunOS 4.1.3
  3145. X   */
  3146. X  debug1("InitTTY: POSIX: termios defaults a la SunOS 4.1.3 (%d)\n", ttyflag);
  3147. XIF{BRKINT}    m->tio.c_iflag |= BRKINT;
  3148. XIF{IGNPAR}    m->tio.c_iflag |= IGNPAR;
  3149. XIF{ISTRIP}    m->tio.c_iflag |= ISTRIP;
  3150. XIF{IXON}    m->tio.c_iflag |= IXON;
  3151. XIF{IMAXBEL}    m->tio.c_iflag |= IMAXBEL; 
  3152. X
  3153. X  if (!ttyflag)    /* may not even be good for ptys.. */
  3154. X    {
  3155. XIF{ICRNL}    m->tio.c_iflag |= ICRNL;
  3156. XIF{ONLCR}    m->tio.c_oflag |= ONLCR; 
  3157. XIF{TAB3}    m->tio.c_oflag |= TAB3; 
  3158. XIF{PARENB}    m->tio.c_cflag |= PARENB;
  3159. X    }
  3160. X
  3161. XIF{OPOST}    m->tio.c_oflag |= OPOST;
  3162. X
  3163. XIF{B9600}    m->tio.c_cflag |= B9600;
  3164. XIF{CS8}     m->tio.c_cflag |= CS8;
  3165. XIF{CREAD}    m->tio.c_cflag |= CREAD;
  3166. XIF{IBSHIFT) && defined(B9600}    m->tio.c_cflag |= B9600 << IBSHIFT;
  3167. X/* IF{CLOCAL}    m->tio.c_cflag |= CLOCAL; */
  3168. X
  3169. XIF{ECHOCTL}    m->tio.c_lflag |= ECHOCTL;
  3170. XIF{ECHOKE}    m->tio.c_lflag |= ECHOKE;
  3171. X
  3172. X  if (!ttyflag)
  3173. X    {
  3174. XIF{ISIG}    m->tio.c_lflag |= ISIG;
  3175. XIF{ICANON}    m->tio.c_lflag |= ICANON;
  3176. XIF{ECHO}    m->tio.c_lflag |= ECHO;
  3177. X    }
  3178. XIF{ECHOE}    m->tio.c_lflag |= ECHOE;
  3179. XIF{ECHOK}    m->tio.c_lflag |= ECHOK;
  3180. XIF{IEXTEN}    m->tio.c_lflag |= IEXTEN;
  3181. X
  3182. XIF{VINTR}    m->tio.c_cc[VINTR]    = Ctrl('C');
  3183. XIF{VQUIT}    m->tio.c_cc[VQUIT]    = Ctrl('\\');
  3184. XIF{VERASE}    m->tio.c_cc[VERASE]   = 0x7f; /* DEL */
  3185. XIF{VKILL}    m->tio.c_cc[VKILL]    = Ctrl('H');
  3186. XIF{VEOF}    m->tio.c_cc[VEOF]     = Ctrl('D');
  3187. XIF{VEOL}    m->tio.c_cc[VEOL]     = 0000;
  3188. XIF{VEOL2}    m->tio.c_cc[VEOL2]    = 0000;
  3189. XIF{VSWTCH}    m->tio.c_cc[VSWTCH]   = 0000;
  3190. XIF{VSTART}    m->tio.c_cc[VSTART]   = Ctrl('Q');
  3191. XIF{VSTOP}    m->tio.c_cc[VSTOP]    = Ctrl('S');
  3192. XIF{VSUSP}    m->tio.c_cc[VSUSP]    = Ctrl('Z');
  3193. XIF{VDSUSP}    m->tio.c_cc[VDSUSP]   = Ctrl('Y');
  3194. XIF{VREPRINT}    m->tio.c_cc[VREPRINT] = Ctrl('R');
  3195. XIF{VDISCARD}    m->tio.c_cc[VDISCARD] = Ctrl('O');
  3196. XIF{VWERASE}    m->tio.c_cc[VWERASE]  = Ctrl('W');
  3197. XIF{VLNEXT}    m->tio.c_cc[VLNEXT]   = Ctrl('V');
  3198. XIF{VSTATUS}    m->tio.c_cc[VSTATUS]  = Ctrl('T');
  3199. X
  3200. X# ifdef hpux
  3201. X  m->m_ltchars.t_suspc =  Ctrl('Z');
  3202. X  m->m_ltchars.t_dsuspc = Ctrl('Y');
  3203. X  m->m_ltchars.t_rprntc = Ctrl('R');
  3204. X  m->m_ltchars.t_flushc = Ctrl('O');
  3205. X  m->m_ltchars.t_werasc = Ctrl('W');
  3206. X  m->m_ltchars.t_lnextc = Ctrl('V');
  3207. X# endif /* hpux */
  3208. X
  3209. X#else /* POSIX */
  3210. X
  3211. X# ifdef TERMIO
  3212. X  debug1("InitTTY: nonPOSIX, struct termio a la Motorola SYSV68 (%d)\n", ttyflag);
  3213. X  /* struct termio tio 
  3214. X   * defaults, as seen on Mototola SYSV68:
  3215. X   * input: 7bit, CR->NL, ^S/^Q flow control 
  3216. X   * output: POSTprocessing: NL->NL-CR, Tabs to spaces
  3217. X   * control: 9600baud, 8bit CSIZE, enable input
  3218. X   * local: enable signals, erase/kill processing, echo on.
  3219. X   */
  3220. XIF{ISTRIP}    m->tio.c_iflag |= ISTRIP;
  3221. XIF{IXON}    m->tio.c_iflag |= IXON;
  3222. X
  3223. XIF{OPOST}    m->tio.c_oflag |= OPOST;
  3224. X
  3225. X  if (!ttyflag)    /* may not even be good for ptys.. */
  3226. X    {
  3227. XIF{ICRNL}    m->tio.c_iflag |= ICRNL;
  3228. XIF{ONLCR}    m->tio.c_oflag |= ONLCR;
  3229. XIF{TAB3}    m->tio.c_oflag |= TAB3;
  3230. X    }
  3231. X
  3232. XIF{B9600}    m->tio.c_cflag  = B9600;
  3233. XIF{CS8}     m->tio.c_cflag |= CS8;
  3234. XIF{CREAD}    m->tio.c_cflag |= CREAD;
  3235. X
  3236. X  if (!ttyflag)
  3237. X    {
  3238. XIF{ISIG}    m->tio.c_lflag |= ISIG;
  3239. XIF{ICANON}    m->tio.c_lflag |= ICANON;
  3240. XIF{ECHO}    m->tio.c_lflag |= ECHO;
  3241. X    }
  3242. XIF{ECHOE}    m->tio.c_lflag |= ECHOE;
  3243. XIF{ECHOK}    m->tio.c_lflag |= ECHOK;
  3244. X
  3245. XIF{VINTR}    m->tio.c_cc[VINTR]  = Ctrl('C');
  3246. XIF{VQUIT}    m->tio.c_cc[VQUIT]  = Ctrl('\\');
  3247. XIF{VERASE}    m->tio.c_cc[VERASE] = 0177; /* DEL */
  3248. XIF{VKILL}    m->tio.c_cc[VKILL]  = Ctrl('H');
  3249. XIF{VEOF}    m->tio.c_cc[VEOF]   = Ctrl('D');
  3250. XIF{VEOL}    m->tio.c_cc[VEOL]   = 0377;
  3251. XIF{VEOL2}    m->tio.c_cc[VEOL2]  = 0377;
  3252. XIF{VSWTCH}    m->tio.c_cc[VSWTCH] = 0000;
  3253. X# else /* TERMIO */
  3254. X  debug1("InitTTY: BSD: defaults a la SunOS 4.1.3 (%d)\n", ttyflag);
  3255. X  m->m_ttyb.sg_ispeed = B9600;
  3256. X  m->m_ttyb.sg_ospeed = B9600;
  3257. X  m->m_ttyb.sg_erase  = 0177; /*DEL */
  3258. X  m->m_ttyb.sg_kill   = Ctrl('H');
  3259. X  if (!ttyflag)
  3260. X    m->m_ttyb.sg_flags = CRMOD | ECHO
  3261. XIF{ANYP}    | ANYP
  3262. X    ;
  3263. X  else
  3264. X    m->m_ttyb.sg_flags = CBREAK
  3265. XIF{ANYP}    | ANYP
  3266. X    ;
  3267. X
  3268. X  m->m_tchars.t_intrc   = Ctrl('C');
  3269. X  m->m_tchars.t_quitc   = Ctrl('\\');
  3270. X  m->m_tchars.t_startc  = Ctrl('Q');
  3271. X  m->m_tchars.t_stopc   = Ctrl('S');
  3272. X  m->m_tchars.t_eofc    = Ctrl('D');
  3273. X  m->m_tchars.t_brkc    = -1;
  3274. X
  3275. X  m->m_ltchars.t_suspc  = Ctrl('Z');
  3276. X  m->m_ltchars.t_dsuspc = Ctrl('Y');
  3277. X  m->m_ltchars.t_rprntc = Ctrl('R');
  3278. X  m->m_ltchars.t_flushc = Ctrl('O');
  3279. X  m->m_ltchars.t_werasc = Ctrl('W');
  3280. X  m->m_ltchars.t_lnextc = Ctrl('V');
  3281. X
  3282. XIF{NTTYDISC}    m->m_ldisc = NTTYDISC;
  3283. X
  3284. X  m->m_lmode = 0
  3285. XIF{LDECCTQ}    | LDECCTQ
  3286. XIF{LCTLECH}    | LCTLECH
  3287. XIF{LPASS8}    | LPASS8
  3288. XIF{LCRTKIL}    | LCRTKIL
  3289. XIF{LCRTERA}    | LCRTERA
  3290. XIF{LCRTBS}    | LCRTBS
  3291. X;
  3292. X# endif /* TERMIO */
  3293. X#endif /* POSIX */
  3294. X}
  3295. X
  3296. Xvoid 
  3297. XSetTTY(fd, mp)
  3298. Xint fd;
  3299. Xstruct mode *mp;
  3300. X{
  3301. X  errno = 0;
  3302. X#ifdef POSIX
  3303. X  tcsetattr(fd, TCSADRAIN, &mp->tio);
  3304. X# ifdef hpux
  3305. X  ioctl(fd, TIOCSLTC, &mp->m_ltchars);
  3306. X# endif
  3307. X#else
  3308. X# ifdef TERMIO
  3309. X  ioctl(fd, TCSETAW, &mp->tio);
  3310. X# else
  3311. X  /* ioctl(fd, TIOCSETP, &mp->m_ttyb); */
  3312. X  ioctl(fd, TIOCSETC, &mp->m_tchars);
  3313. X  ioctl(fd, TIOCLSET, &mp->m_lmode);
  3314. X  ioctl(fd, TIOCSETD, &mp->m_ldisc);
  3315. X  ioctl(fd, TIOCSETP, &mp->m_ttyb);
  3316. X  ioctl(fd, TIOCSLTC, &mp->m_ltchars); /* moved here for apollo. jw */
  3317. X# endif
  3318. X#endif
  3319. X  if (errno)
  3320. X    Msg(errno, "SetTTY (fd %d): ioctl failed", fd);
  3321. X}
  3322. X
  3323. Xvoid
  3324. XGetTTY(fd, mp)
  3325. Xint fd;
  3326. Xstruct mode *mp;
  3327. X{
  3328. X  errno = 0;
  3329. X#ifdef POSIX
  3330. X  tcgetattr(fd, &mp->tio);
  3331. X# ifdef hpux
  3332. X  ioctl(fd, TIOCGLTC, &mp->m_ltchars);
  3333. X# endif
  3334. X#else
  3335. X# ifdef TERMIO
  3336. X  ioctl(fd, TCGETA, &mp->tio);
  3337. X# else
  3338. X  ioctl(fd, TIOCGETP, &mp->m_ttyb);
  3339. X  ioctl(fd, TIOCGETC, &mp->m_tchars);
  3340. X  ioctl(fd, TIOCGLTC, &mp->m_ltchars);
  3341. X  ioctl(fd, TIOCLGET, &mp->m_lmode);
  3342. X  ioctl(fd, TIOCGETD, &mp->m_ldisc);
  3343. X# endif
  3344. X#endif
  3345. X  if (errno)
  3346. X    Msg(errno, "GetTTY (fd %d): ioctl failed", fd);
  3347. X}
  3348. X
  3349. Xvoid
  3350. XSetMode(op, np)
  3351. Xstruct mode *op, *np;
  3352. X{
  3353. X  *np = *op;
  3354. X
  3355. X#if defined(TERMIO) || defined(POSIX)
  3356. X  np->tio.c_iflag &= ~ICRNL;
  3357. X# ifdef ONLCR
  3358. X  np->tio.c_oflag &= ~ONLCR;
  3359. X# endif
  3360. X  np->tio.c_lflag &= ~(ICANON | ECHO);
  3361. X
  3362. X  /*
  3363. X   * Unfortunately, the master process never will get SIGINT if the real
  3364. X   * terminal is different from the one on which it was originaly started
  3365. X   * (process group membership has not been restored or the new tty could not
  3366. X   * be made controlling again). In my solution, it is the attacher who
  3367. X   * receives SIGINT (because it is always correctly associated with the real
  3368. X   * tty) and forwards it to the master [kill(MasterPid, SIGINT)]. 
  3369. X   * Marc Boucher (marc@CAM.ORG)
  3370. X   */
  3371. X  if (iflag)
  3372. X    np->tio.c_lflag |= ISIG;
  3373. X  else
  3374. X    np->tio.c_lflag &= ~ISIG;
  3375. X  /* 
  3376. X   * careful, careful catche monkey..
  3377. X   * never set VMIN and VTIME to zero, if you want blocking io.
  3378. X   */
  3379. X  np->tio.c_cc[VMIN] = 1;
  3380. X  np->tio.c_cc[VTIME] = 0;
  3381. XIF{VSTART}    startc = op->tio.c_cc[VSTART];
  3382. XIF{VSTOP}    stopc = op->tio.c_cc[VSTOP];
  3383. X  if (iflag)
  3384. X    origintrc = intrc = op->tio.c_cc[VINTR];
  3385. X  else
  3386. X    {
  3387. X      origintrc = op->tio.c_cc[VINTR];
  3388. X      intrc = np->tio.c_cc[VINTR] = VDISABLE;
  3389. X    }
  3390. X  np->tio.c_cc[VQUIT] = VDISABLE;
  3391. X  if (d_flow == 0)
  3392. X    {
  3393. X      np->tio.c_cc[VINTR] = VDISABLE;
  3394. XIF{VSTART}    np->tio.c_cc[VSTART] = VDISABLE;
  3395. XIF{VSTOP}    np->tio.c_cc[VSTOP] = VDISABLE;
  3396. X      np->tio.c_iflag &= ~IXON;
  3397. X    }
  3398. XIF{VDISCARD}    np->tio.c_cc[VDISCARD] = VDISABLE;
  3399. XIF{VSUSP}    np->tio.c_cc[VSUSP] = VDISABLE;
  3400. X# ifdef hpux
  3401. X  np->m_ltchars.t_suspc  = VDISABLE;
  3402. X  np->m_ltchars.t_dsuspc = VDISABLE;
  3403. X  np->m_ltchars.t_rprntc = VDISABLE;
  3404. X  np->m_ltchars.t_flushc = VDISABLE;
  3405. X  np->m_ltchars.t_werasc = VDISABLE;
  3406. X  np->m_ltchars.t_lnextc = VDISABLE;
  3407. X# else /* hpux */
  3408. XIF{VDSUSP}    np->tio.c_cc[VDSUSP] = VDISABLE;
  3409. X# endif /* hpux */
  3410. X#else /* TERMIO || POSIX */
  3411. X  startc = op->m_tchars.t_startc;
  3412. X  stopc = op->m_tchars.t_stopc;
  3413. X  if (iflag)
  3414. X    origintrc = intrc = op->m_tchars.t_intrc;
  3415. X  else
  3416. X    {
  3417. X      origintrc = op->m_tchars.t_intrc;
  3418. X      intrc = np->m_tchars.t_intrc = -1;
  3419. X    }
  3420. X  np->m_ttyb.sg_flags &= ~(CRMOD | ECHO);
  3421. X  np->m_ttyb.sg_flags |= CBREAK;
  3422. X  np->m_tchars.t_quitc = -1;
  3423. X  if (d_flow == 0)
  3424. X    {
  3425. X      np->m_tchars.t_intrc = -1;
  3426. X      np->m_tchars.t_startc = -1;
  3427. X      np->m_tchars.t_stopc = -1;
  3428. X    }
  3429. X  np->m_ltchars.t_suspc = -1;
  3430. X  np->m_ltchars.t_dsuspc = -1;
  3431. X  np->m_ltchars.t_flushc = -1;
  3432. X  np->m_ltchars.t_lnextc = -1;
  3433. X#endif /* defined(TERMIO) || defined(POSIX) */
  3434. X}
  3435. X
  3436. Xvoid
  3437. XSetFlow(on)
  3438. Xint on;
  3439. X{
  3440. X  ASSERT(display);
  3441. X  if (d_flow == on)
  3442. X    return;
  3443. X#if defined(TERMIO) || defined(POSIX)
  3444. X  if (on)
  3445. X    {
  3446. X      d_NewMode.tio.c_cc[VINTR] = intrc;
  3447. XIF{VSTART}    d_NewMode.tio.c_cc[VSTART] = startc;
  3448. XIF{VSTOP}    d_NewMode.tio.c_cc[VSTOP] = stopc;
  3449. X      d_NewMode.tio.c_iflag |= IXON;
  3450. X    }
  3451. X  else
  3452. X    {
  3453. X      d_NewMode.tio.c_cc[VINTR] = VDISABLE;
  3454. XIF{VSTART}    d_NewMode.tio.c_cc[VSTART] = VDISABLE;
  3455. XIF{VSTOP}    d_NewMode.tio.c_cc[VSTOP] = VDISABLE;
  3456. X      d_NewMode.tio.c_iflag &= ~IXON;
  3457. X    }
  3458. X# ifdef POSIX
  3459. X  if (tcsetattr(d_userfd, TCSANOW, &d_NewMode.tio))
  3460. X# else
  3461. X  if (ioctl(d_userfd, TCSETAW, &d_NewMode.tio) != 0)
  3462. X# endif
  3463. X    debug1("SetFlow: ioctl errno %d\n", errno);
  3464. X#else /* POSIX || TERMIO */
  3465. X  if (on)
  3466. X    {
  3467. X      d_NewMode.m_tchars.t_intrc = intrc;
  3468. X      d_NewMode.m_tchars.t_startc = startc;
  3469. X      d_NewMode.m_tchars.t_stopc = stopc;
  3470. X    }
  3471. X  else
  3472. X    {
  3473. X      d_NewMode.m_tchars.t_intrc = -1;
  3474. X      d_NewMode.m_tchars.t_startc = -1;
  3475. X      d_NewMode.m_tchars.t_stopc = -1;
  3476. X    }
  3477. X  if (ioctl(d_userfd, TIOCSETC, &d_NewMode.m_tchars) != 0)
  3478. X    debug1("SetFlow: ioctl errno %d\n", errno);
  3479. X#endif /* POSIX || TERMIO */
  3480. X  d_flow = on;
  3481. X}
  3482. X
  3483. X
  3484. X/*
  3485. X *  Job control handling
  3486. X */
  3487. X
  3488. X/*ARGSUSED*/
  3489. Xvoid
  3490. Xbrktty(fd)
  3491. Xint fd;
  3492. X{
  3493. X#ifdef POSIX
  3494. X  setsid();        /* will break terminal affiliation */
  3495. X# ifdef BSD
  3496. X  ioctl(fd, TIOCSCTTY, 0);
  3497. X# endif /* BSD */
  3498. X#else /* POSIX */
  3499. X# ifdef SYSV
  3500. X  setpgrp();        /* will break terminal affiliation */
  3501. X# else /* SYSV */
  3502. X#  ifdef BSDJOBS
  3503. X  int devtty;
  3504. X
  3505. X  if ((devtty = open("/dev/tty", O_RDWR | O_NDELAY)) >= 0)
  3506. X    {
  3507. X      if (ioctl(devtty, TIOCNOTTY, (char *)0))
  3508. X        debug2("brktty: ioctl(devtty=%d, TIOCNOTTY, 0) = %d\n", devtty, errno);
  3509. X      close(devtty);
  3510. X    }
  3511. X#  endif /* BSDJOBS */
  3512. X# endif /* SYSV */
  3513. X#endif /* POSIX */
  3514. X}
  3515. X
  3516. Xint
  3517. Xfgtty(fd)
  3518. Xint fd;
  3519. X{
  3520. X#ifdef BSDJOBS
  3521. X  int mypid;
  3522. X
  3523. X  mypid = getpid();
  3524. X
  3525. X# if defined(BSDI) || defined(__386BSD__) || defined(__osf__)
  3526. X  setsid();    /* should be already done */
  3527. X  ioctl(fd, TIOCSCTTY, 0);
  3528. X# endif /* BSDI || __386BSD__ */
  3529. X
  3530. X# ifdef POSIX
  3531. X  if (tcsetpgrp(fd, mypid))
  3532. X    {
  3533. X      debug1("fgtty: tcsetpgrp: %d\n", errno);
  3534. X      return -1;
  3535. X    }
  3536. X# else /* POSIX */
  3537. X  if (ioctl(fd, TIOCSPGRP, &mypid) != 0)
  3538. X    debug1("fgtty: TIOSETPGRP: %d\n", errno);
  3539. X#  ifndef SYSV    /* Already done in brktty():setpgrp() */
  3540. X  if (setpgrp(fd, mypid))
  3541. X    debug1("fgtty: setpgrp: %d\n", errno);
  3542. X#  endif
  3543. X# endif /* POSIX */
  3544. X#endif /* BSDJOBS */
  3545. X  return 0;
  3546. X}
  3547. X
  3548. X
  3549. X/* 
  3550. X * Send a break for n * 0.25 seconds. Tty must be PLAIN.
  3551. X */
  3552. X
  3553. Xvoid SendBreak(wp, n, closeopen)
  3554. Xstruct win *wp;
  3555. Xint n, closeopen;
  3556. X{
  3557. X  if ((wp->w_t.flags & TTY_FLAG_PLAIN) == 0)
  3558. X    return;
  3559. X
  3560. X  debug3("break(%d, %d) fd %d\n", n, closeopen, wp->w_ptyfd);
  3561. X#ifdef POSIX
  3562. X  (void) tcflush(wp->w_ptyfd, TCIOFLUSH);
  3563. X#else
  3564. X# ifdef TIOCFLUSH
  3565. X  (void) ioctl(wp->w_ptyfd, TIOCFLUSH, (char *)0);
  3566. X# endif /* TIOCFLUSH */
  3567. X#endif /* POSIX */
  3568. X  if (closeopen)
  3569. X    {
  3570. X      close(wp->w_ptyfd);
  3571. X      sleep((n + 3) / 4);
  3572. X      if ((wp->w_ptyfd = OpenTTY(wp->w_tty)) < 1)
  3573. X    {
  3574. X      Msg(0, "Ouch, cannot reopen line %s, please try harder", wp->w_tty);
  3575. X      return;
  3576. X    }
  3577. X    }
  3578. X  else
  3579. X    {
  3580. X#ifdef POSIX 
  3581. X      debug("tcsendbreak\n");
  3582. X      if (tcsendbreak(wp->w_ptyfd, n) < 0)
  3583. X    {
  3584. X      Msg(errno, "cannot send BREAK");
  3585. X      return;
  3586. X    }
  3587. X#else
  3588. X      if (!n)
  3589. X    n++;
  3590. X# ifdef TCSBRK
  3591. X      debug("TCSBRK\n");
  3592. X    {
  3593. X      int i;
  3594. X      for (i = 0; i < n; i++)
  3595. X        if (ioctl(wp->w_ptyfd, TCSBRK, (char *)0) < 0)
  3596. X          {
  3597. X        Msg(errno, "Cannot send BREAK");
  3598. X        return;
  3599. X          }
  3600. X    }
  3601. X# else /* TCSBRK */
  3602. X#  if defined(TIOCSBRK) && defined(TIOCCBRK)
  3603. X      debug("TIOCSBRK TIOCCBRK\n");
  3604. X      if (ioctl(wp->w_ptyfd, TIOCSBRK, (char *)0) < 0)
  3605. X    {
  3606. X      Msg(errno, "Can't send BREAK");
  3607. X      return;
  3608. X    }
  3609. X      sleep((n + 3) / 4);
  3610. X      if (ioctl(wp->w_ptyfd, TIOCCBRK, (char *)0) < 0)
  3611. X    {
  3612. X      Msg(errno, "BREAK stuck!!! -- HELP!");
  3613. X      return;
  3614. X    }
  3615. X#  else /* TIOCSBRK && TIOCCBRK */
  3616. X      Msg(0, "Break not simulated yet"); 
  3617. X      return;
  3618. X#  endif /* TIOCSBRK && TIOCCBRK */
  3619. X# endif /* TCSBRK */
  3620. X#endif /* POSIX */
  3621. X      debug("            broken\n");
  3622. X    }
  3623. X}
  3624. X
  3625. X
  3626. X/*
  3627. X *  Console grabbing
  3628. X */
  3629. X
  3630. X/*ARGSUSED*/
  3631. Xint
  3632. XTtyGrabConsole(fd, on, rc_name)
  3633. Xint fd, on;
  3634. Xchar *rc_name;
  3635. X{
  3636. X#ifdef TIOCCONS
  3637. X  char *slave;
  3638. X  int sfd = -1, ret = 0;
  3639. X  struct display *d;
  3640. X
  3641. X  if (!on)
  3642. X    {
  3643. X      if ((fd = OpenPTY(&slave)) < 0)
  3644. X    {
  3645. X      Msg(errno, "%s: could not open detach pty master", rc_name);
  3646. X      return -1;
  3647. X    }
  3648. X      if ((sfd = open(slave, O_RDWR)) < 0)
  3649. X    {
  3650. X      Msg(errno, "%s: could not open detach pty slave", rc_name);
  3651. X      close(fd);
  3652. X      return -1;
  3653. X    }
  3654. X    }
  3655. X  else
  3656. X    {
  3657. X      if (displays == 0)
  3658. X    {
  3659. X      Msg(0, "I need a display");
  3660. X      return -1;
  3661. X    }
  3662. X      for (d = displays; d; d = d->_d_next)
  3663. X    if (strcmp(d->_d_usertty, "/dev/console") == 0)
  3664. X      break;
  3665. X      if (d)
  3666. X    {
  3667. X      Msg(0, "too dangerous - screen is running on /dev/console");
  3668. X      return -1;
  3669. X    }
  3670. X    }
  3671. X  if (UserContext() == 1)
  3672. X    UserReturn(ioctl(fd, TIOCCONS, &on));
  3673. X  ret = UserStatus();
  3674. X  if (ret)
  3675. X    Msg(errno, "%s: ioctl TIOCCONS failed", rc_name);
  3676. X  if (!on)
  3677. X    {
  3678. X      close(sfd);
  3679. X      close(fd);
  3680. X    }
  3681. X  return ret;
  3682. X#else /* TIOCCONS */
  3683. X  Msg(0, "%s: no TIOCCONS on this machine", rc_name);
  3684. X  return -1;
  3685. X#endif /* TIOCCONS */
  3686. X}
  3687. X
  3688. X
  3689. X/*
  3690. X *  Write out the mode struct in a readable form
  3691. X */
  3692. X
  3693. X#ifdef DEBUG
  3694. Xvoid
  3695. XDebugTTY(m)
  3696. Xstruct mode *m;
  3697. X{
  3698. X  int i;
  3699. X
  3700. X#ifdef POSIX
  3701. X  debug("struct termios tio:\n");
  3702. X  debug1("c_iflag = %#x\n", m->tio.c_iflag);
  3703. X  debug1("c_oflag = %#x\n", m->tio.c_oflag);
  3704. X  debug1("c_cflag = %#x\n", m->tio.c_cflag);
  3705. X  debug1("c_lflag = %#x\n", m->tio.c_lflag);
  3706. X  for (i = 0; i < NCCS; i++)
  3707. X    {
  3708. X      debug2("c_cc[%d] = %#x\n", i, m->tio.c_cc[i]);
  3709. X    }
  3710. X# ifdef hpux
  3711. X  debug1("suspc     = %#02x\n", m->m_ltchars.t_suspc);
  3712. X  debug1("dsuspc    = %#02x\n", m->m_ltchars.t_dsuspc);
  3713. X  debug1("rprntc    = %#02x\n", m->m_ltchars.t_rprntc);
  3714. X  debug1("flushc    = %#02x\n", m->m_ltchars.t_flushc);
  3715. X  debug1("werasc    = %#02x\n", m->m_ltchars.t_werasc);
  3716. X  debug1("lnextc    = %#02x\n", m->m_ltchars.t_lnextc);
  3717. X# endif /* hpux */
  3718. X#else /* POSIX */
  3719. X# ifdef TERMIO
  3720. X  debug("struct termio tio:\n");
  3721. X  debug1("c_iflag = %04o\n", m->tio.c_iflag);
  3722. X  debug1("c_oflag = %04o\n", m->tio.c_oflag);
  3723. X  debug1("c_cflag = %04o\n", m->tio.c_cflag);
  3724. X  debug1("c_lflag = %04o\n", m->tio.c_lflag);
  3725. X  for (i = 0; i < NCC; i++)
  3726. X    {
  3727. X      debug2("c_cc[%d] = %04o\n", i, m->tio.c_cc[i]);
  3728. X    }
  3729. X# else /* TERMIO */
  3730. X  debug1("sg_ispeed = %d\n",    m->m_ttyb.sg_ispeed);
  3731. X  debug1("sg_ospeed = %d\n",    m->m_ttyb.sg_ospeed);
  3732. X  debug1("sg_erase  = %#02x\n", m->m_ttyb.sg_erase);
  3733. X  debug1("sg_kill   = %#02x\n", m->m_ttyb.sg_kill);
  3734. X  debug1("sg_flags  = %#04x\n", (unsigned short)m->m_ttyb.sg_flags);
  3735. X  debug1("intrc     = %#02x\n", m->m_tchars.t_intrc);
  3736. X  debug1("quitc     = %#02x\n", m->m_tchars.t_quitc);
  3737. X  debug1("startc    = %#02x\n", m->m_tchars.t_startc);
  3738. X  debug1("stopc     = %#02x\n", m->m_tchars.t_stopc);
  3739. X  debug1("eofc      = %#02x\n", m->m_tchars.t_eofc);
  3740. X  debug1("brkc      = %#02x\n", m->m_tchars.t_brkc);
  3741. X  debug1("suspc     = %#02x\n", m->m_ltchars.t_suspc);
  3742. X  debug1("dsuspc    = %#02x\n", m->m_ltchars.t_dsuspc);
  3743. X  debug1("rprntc    = %#02x\n", m->m_ltchars.t_rprntc);
  3744. X  debug1("flushc    = %#02x\n", m->m_ltchars.t_flushc);
  3745. X  debug1("werasc    = %#02x\n", m->m_ltchars.t_werasc);
  3746. X  debug1("lnextc    = %#02x\n", m->m_ltchars.t_lnextc);
  3747. X  debug1("ldisc     = %d\n",    m->m_ldisc);
  3748. X  debug1("lmode     = %#x\n",   m->m_lmode);
  3749. X# endif /* TERMIO */
  3750. X#endif /* POSIX */
  3751. X}
  3752. X#endif /* DEBUG */
  3753. END_OF_FILE
  3754. if test 19054 -ne `wc -c <'tty.sh'`; then
  3755.     echo shar: \"'tty.sh'\" unpacked with wrong size!
  3756. fi
  3757. # end of 'tty.sh'
  3758. fi
  3759. if test -f 'window.c' -a "${1}" != "-c" ; then 
  3760.   echo shar: Will not clobber existing file \"'window.c'\"
  3761. else
  3762. echo shar: Extracting \"'window.c'\" \(20351 characters\)
  3763. sed "s/^X//" >'window.c' <<'END_OF_FILE'
  3764. X/* Copyright (c) 1993
  3765. X *      Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
  3766. X *      Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
  3767. X * Copyright (c) 1987 Oliver Laumann
  3768. X *
  3769. X * This program is free software; you can redistribute it and/or modify
  3770. X * it under the terms of the GNU General Public License as published by
  3771. X * the Free Software Foundation; either version 2, or (at your option)
  3772. X * any later version.
  3773. X *
  3774. X * This program is distributed in the hope that it will be useful,
  3775. X * but WITHOUT ANY WARRANTY; without even the implied warranty of
  3776. X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  3777. X * GNU General Public License for more details.
  3778. X *
  3779. X * You should have received a copy of the GNU General Public License
  3780. X * along with this program (see the file COPYING); if not, write to the
  3781. X * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  3782. X *
  3783. X ****************************************************************
  3784. X */
  3785. X
  3786. X#include "rcs.h"
  3787. XRCS_ID("$Id: window.c,v 1.9 1993/07/21 15:43:41 mlschroe Exp $ FAU")
  3788. X
  3789. X#include <sys/types.h>
  3790. X#include <sys/stat.h>
  3791. X#include <signal.h>
  3792. X#include <fcntl.h>
  3793. X#ifndef sun
  3794. X#include <sys/ioctl.h>
  3795. X#endif
  3796. X
  3797. X#include "config.h"
  3798. X#include "screen.h"
  3799. X#include "extern.h"
  3800. X
  3801. X#ifdef SVR4    /* for solaris 2.1 */
  3802. X# include <sys/stropts.h>
  3803. X#endif
  3804. X
  3805. Xextern struct display *displays, *display;
  3806. Xextern struct win *windows, *fore, *wtab[], *console_window;
  3807. Xextern char *ShellArgs[];
  3808. Xextern char screenterm[];
  3809. Xextern char HostName[];
  3810. Xextern int default_monitor, TtyMode;
  3811. Xextern struct LayFuncs WinLf;
  3812. Xextern int real_uid, real_gid;
  3813. Xextern char Termcap[];
  3814. Xextern char **NewEnv;
  3815. X
  3816. X#if defined(TIOCSWINSZ) || defined(TIOCGWINSZ)
  3817. Xextern struct winsize glwz;
  3818. X#endif
  3819. X
  3820. X
  3821. Xstatic int OpenDevice __P((char *, int, int *, char **));
  3822. Xstatic int ForkWindow __P((char **, char *, char *, char *, struct win *));
  3823. Xstatic void execvpe __P((char *, char **, char **));
  3824. X
  3825. X
  3826. Xchar DefaultShell[] = "/bin/sh";
  3827. Xstatic char DefaultPath[] = ":/usr/ucb:/bin:/usr/bin";
  3828. X
  3829. X
  3830. Xstruct NewWindow nwin_undef   = 
  3831. X{
  3832. X  -1, (char *)0, (char **)0, (char *)0, (char *)0, -1, -1, 
  3833. X  -1, -1, -1
  3834. X};
  3835. X
  3836. Xstruct NewWindow nwin_default = 
  3837. X{ 
  3838. X  0, 0, ShellArgs, 0, screenterm, 0, 1*FLOW_NOW, 
  3839. X  LOGINDEFAULT, DEFAULTHISTHEIGHT, -1
  3840. X};
  3841. X
  3842. Xstruct NewWindow nwin_options;
  3843. X
  3844. Xvoid
  3845. Xnwin_compose(def, new, res)
  3846. Xstruct NewWindow *def, *new, *res;
  3847. X{
  3848. X  res->StartAt = new->StartAt != nwin_undef.StartAt ? new->StartAt : def->StartAt;
  3849. X  res->aka = new->aka != nwin_undef.aka ? new->aka : def->aka;
  3850. X  res->args = new->args != nwin_undef.args ? new->args : def->args;
  3851. X  res->dir = new->dir != nwin_undef.dir ? new->dir : def->dir;
  3852. X  res->term = new->term != nwin_undef.term ? new->term : def->term;
  3853. X  res->aflag = new->aflag != nwin_undef.aflag ? new->aflag : def->aflag;
  3854. X  res->flowflag = new->flowflag != nwin_undef.flowflag ? new->flowflag : def->flowflag;
  3855. X  res->lflag = new->lflag != nwin_undef.lflag ? new->lflag : def->lflag;
  3856. X  res->histheight = new->histheight != nwin_undef.histheight ? new->histheight : def->histheight;
  3857. X  res->monitor = new->monitor != nwin_undef.monitor ? new->monitor : def->monitor;
  3858. X}
  3859. X
  3860. Xint
  3861. XMakeWindow(newwin)
  3862. Xstruct NewWindow *newwin;
  3863. X{
  3864. X  register struct win **pp, *p;
  3865. X  register int n;
  3866. X  int f = -1;
  3867. X  struct NewWindow nwin;
  3868. X  int ttyflag;
  3869. X  char *TtyName;
  3870. X
  3871. X  debug1("NewWindow: StartAt %d\n", newwin->StartAt);
  3872. X  debug1("NewWindow: aka     %s\n", newwin->aka?newwin->aka:"NULL");
  3873. X  debug1("NewWindow: dir     %s\n", newwin->dir?newwin->dir:"NULL");
  3874. X  debug1("NewWindow: term    %s\n", newwin->term?newwin->term:"NULL");
  3875. X  nwin_compose(&nwin_default, newwin, &nwin);
  3876. X  debug1("NWin: aka     %s\n", nwin.aka ? nwin.aka : "NULL");
  3877. X  pp = wtab + nwin.StartAt;
  3878. X
  3879. X  do
  3880. X    {
  3881. X      if (*pp == 0)
  3882. X    break;
  3883. X      if (++pp == wtab + MAXWIN)
  3884. X    pp = wtab;
  3885. X    }
  3886. X  while (pp != wtab + nwin.StartAt);
  3887. X  if (*pp)
  3888. X    {
  3889. X      Msg(0, "No more windows.");
  3890. X      return -1;
  3891. X    }
  3892. X
  3893. X#if defined(USRLIMIT) && defined(UTMPOK)
  3894. X  /*
  3895. X   * Count current number of users, if logging windows in.
  3896. X   */
  3897. X  if (nwin.lflag && CountUsers() >= USRLIMIT)
  3898. X    {
  3899. X      Msg(0, "User limit reached.  Window will not be logged in.");
  3900. X      nwin.lflag = 0;
  3901. X    }
  3902. X#endif
  3903. X  n = pp - wtab;
  3904. X  debug1("Makewin creating %d\n", n);
  3905. X
  3906. X  if ((f = OpenDevice(nwin.args[0], nwin.lflag, &ttyflag, &TtyName)) < 0)
  3907. X    return -1;
  3908. X
  3909. X  if ((p = (struct win *) malloc(sizeof(struct win))) == 0)
  3910. X    {
  3911. X      close(f);
  3912. X      Msg(0, strnomem);
  3913. X      return -1;
  3914. X    }
  3915. X  bzero((char *) p, (int) sizeof(struct win));
  3916. X#ifdef MULTIUSER
  3917. X  if (NewWindowAcl(p))
  3918. X    {
  3919. X      free(p);
  3920. X      close(f);
  3921. X      Msg(0, strnomem);
  3922. X      return -1;
  3923. X    }
  3924. X#endif
  3925. X  p->w_wlock = WLOCK_AUTO;
  3926. X  p->w_dupto = -1;
  3927. X  p->w_winlay.l_next = 0;
  3928. X  p->w_winlay.l_layfn = &WinLf;
  3929. X  p->w_winlay.l_data = (char *)p;
  3930. X  p->w_lay = &p->w_winlay;
  3931. X  p->w_display = display;
  3932. X  if (display)
  3933. X    p->w_wlockuser = d_user;
  3934. X  p->w_number = n;
  3935. X  p->w_ptyfd = f;
  3936. X  p->w_aflag = nwin.aflag;
  3937. X  p->w_flow = nwin.flowflag | ((nwin.flowflag & FLOW_AUTOFLAG) ? (FLOW_AUTO|FLOW_NOW) : FLOW_AUTO);
  3938. X  if (!nwin.aka)
  3939. X    nwin.aka = Filename(nwin.args[0]);
  3940. X  strncpy(p->w_akabuf, nwin.aka, MAXSTR - 1);
  3941. X  if ((nwin.aka = rindex(p->w_akabuf, '|')) != NULL)
  3942. X    {
  3943. X      p->w_autoaka = 0;
  3944. X      *nwin.aka++ = 0;
  3945. X      p->w_aka = nwin.aka;
  3946. X      p->w_akachange = nwin.aka + strlen(nwin.aka);
  3947. X    }
  3948. X  else
  3949. X    p->w_aka = p->w_akachange = p->w_akabuf;
  3950. X  if ((p->w_monitor = nwin.monitor) == -1)
  3951. X    p->w_monitor = default_monitor;
  3952. X  p->w_norefresh = 0;
  3953. X  strncpy(p->w_tty, TtyName, MAXSTR - 1);
  3954. X
  3955. X  if (ChangeWindowSize(p, display ? d_defwidth : 80, display ? d_defheight : 24))
  3956. X    {
  3957. X      FreeWindow(p);
  3958. X      return -1;
  3959. X    }
  3960. X#ifdef COPY_PASTE
  3961. X  ChangeScrollback(p, nwin.histheight, p->w_width);
  3962. X#endif
  3963. X  ResetWindow(p);    /* sets p->w_wrap */
  3964. X
  3965. X  if (ttyflag == TTY_FLAG_PLAIN)
  3966. X    {
  3967. X      p->w_t.flags |= TTY_FLAG_PLAIN;
  3968. X      p->w_pid = 0;
  3969. X    }
  3970. X  else
  3971. X    {
  3972. X      debug("forking...\n");
  3973. X#ifdef PSEUDOS
  3974. X      p->w_pwin = NULL;
  3975. X#endif
  3976. X      p->w_pid = ForkWindow(nwin.args, nwin.dir, nwin.term, TtyName, p);
  3977. X      if (p->w_pid < 0)
  3978. X    {
  3979. X      FreeWindow(p);
  3980. X      return -1;
  3981. X    }
  3982. X    }
  3983. X  /*
  3984. X   * Place the newly created window at the head of the most-recently-used list.
  3985. X   */
  3986. X  if (display && d_fore)
  3987. X    d_other = d_fore;
  3988. X  *pp = p;
  3989. X  p->w_next = windows;
  3990. X  windows = p;
  3991. X#ifdef UTMPOK
  3992. X  debug1("MakeWindow will %slog in.\n", nwin.lflag?"":"not ");
  3993. X  if (nwin.lflag == 1)
  3994. X    {
  3995. X      if (display)
  3996. X        SetUtmp(p);
  3997. X      else
  3998. X    p->w_slot = (slot_t) 0;
  3999. X    }
  4000. X  else
  4001. X    p->w_slot = (slot_t) -1;
  4002. X#endif
  4003. X  SetForeWindow(p);
  4004. X  Activate(p->w_norefresh);
  4005. X  return n;
  4006. X}
  4007. X
  4008. Xvoid
  4009. XFreeWindow(wp)
  4010. Xstruct win *wp;
  4011. X{
  4012. X  struct display *d;
  4013. X
  4014. X#ifdef PSEUDOS
  4015. X  if (wp->w_pwin)
  4016. X    FreePseudowin(wp);
  4017. X#endif
  4018. X#ifdef UTMPOK
  4019. X  RemoveUtmp(wp);
  4020. X#endif
  4021. X  (void) chmod(wp->w_tty, 0666);
  4022. X  (void) chown(wp->w_tty, 0, 0);
  4023. X  close(wp->w_ptyfd);
  4024. X  if (wp == console_window)
  4025. X    console_window = 0;
  4026. X  if (wp->w_logfp != NULL)
  4027. X    fclose(wp->w_logfp);
  4028. X  ChangeWindowSize(wp, 0, 0);
  4029. X  for (d = displays; d; d = d->_d_next)
  4030. X    if (d->_d_other == wp)
  4031. X      d->_d_other = 0;
  4032. X  free(wp);
  4033. X}
  4034. X
  4035. Xstatic int
  4036. XOpenDevice(arg, lflag, typep, namep)
  4037. Xchar *arg;
  4038. Xint lflag;
  4039. Xint *typep;
  4040. Xchar **namep;
  4041. X{
  4042. X  struct stat st;
  4043. X  int f;
  4044. X
  4045. X  if ((stat(arg, &st)) == 0 && (st.st_mode & S_IFCHR))
  4046. X    {
  4047. X      if (access(arg, R_OK | W_OK) == -1)
  4048. X    {
  4049. X      Msg(errno, "Cannot access line '%s' for R/W", arg); 
  4050. X      return -1;
  4051. X    }
  4052. X      debug("OpenDevice: OpenTTY\n");
  4053. X      if ((f = OpenTTY(arg)) < 0)
  4054. X    return -1;
  4055. X      *typep = TTY_FLAG_PLAIN;
  4056. X      *namep = arg;
  4057. X    }
  4058. X  else
  4059. X    {
  4060. X      *typep = 0;    /* for now we hope it is a program */
  4061. X      f = OpenPTY(namep);
  4062. X      if (f == -1)
  4063. X    {
  4064. X      Msg(0, "No more PTYs.");
  4065. X      return -1;
  4066. X    }
  4067. X#ifdef TIOCPKT
  4068. X      {
  4069. X    int flag = 1;
  4070. X
  4071. X    if (ioctl(f, TIOCPKT, &flag))
  4072. X      {
  4073. X        Msg(errno, "TIOCPKT ioctl");
  4074. X        close(f);
  4075. X        return -1;
  4076. X      }
  4077. X      }
  4078. X#endif /* TIOCPKT */
  4079. X    }
  4080. X  (void) fcntl(f, F_SETFL, FNDELAY);
  4081. X#ifdef PTYGROUP
  4082. X  (void) chown(*namep, real_uid, PTYGROUP);
  4083. X#else
  4084. X  (void) chown(*namep, real_uid, real_gid);
  4085. X#endif
  4086. X#ifdef UTMPOK
  4087. X  (void) chmod(*namep, lflag ? TtyMode : (TtyMode & ~022));
  4088. X#else
  4089. X  (void) chmod(*namep, TtyMode);
  4090. X#endif
  4091. X  return f;
  4092. X}
  4093. X
  4094. X/*
  4095. X * Fields w_width, w_height, aflag, number (and w_tty)
  4096. X * are read from struct win *win. No fields written.
  4097. X * If pwin is nonzero, filedescriptors are distributed 
  4098. X * between win->w_tty and open(ttyn)
  4099. X *
  4100. X */
  4101. Xstatic int 
  4102. XForkWindow(args, dir, term, ttyn, win)
  4103. Xchar **args, *dir, *term, *ttyn;
  4104. Xstruct win *win;
  4105. X{
  4106. X  int pid;
  4107. X  char tebuf[25];
  4108. X  char ebuf[10];
  4109. X  char shellbuf[7 + MAXPATHLEN];
  4110. X  char *proc;
  4111. X#ifndef TIOCSWINSZ
  4112. X  char libuf[20], cobuf[20];
  4113. X#endif
  4114. X  int newfd;
  4115. X  int w = win->w_width;
  4116. X  int h = win->w_height;
  4117. X#ifdef PSEUDOS
  4118. X  int i, pat, wfdused;
  4119. X  struct pseudowin *pwin = win->w_pwin;
  4120. X#endif
  4121. X
  4122. X  switch (pid = fork())
  4123. X    {
  4124. X    case -1:
  4125. X      Msg(errno, "fork");
  4126. X      return -1;
  4127. X    case 0:
  4128. X      signal(SIGHUP, SIG_DFL);
  4129. X      signal(SIGINT, SIG_DFL);
  4130. X      signal(SIGQUIT, SIG_DFL);
  4131. X      signal(SIGTERM, SIG_DFL);
  4132. X#ifdef BSDJOBS
  4133. X      signal(SIGTTIN, SIG_DFL);
  4134. X      signal(SIGTTOU, SIG_DFL);
  4135. X#endif
  4136. X      if (setuid(real_uid) || setgid(real_gid))
  4137. X    {
  4138. X      SendErrorMsg("Setuid/gid: %s", sys_errlist[errno]);
  4139. X      eexit(1);
  4140. X    }
  4141. X      if (dir && *dir && chdir(dir) == -1)
  4142. X    {
  4143. X      SendErrorMsg("Cannot chdir to %s: %s", dir, sys_errlist[errno]);
  4144. X      eexit(1);
  4145. X    }
  4146. X
  4147. X      if (display)
  4148. X    {
  4149. X      brktty(d_userfd);
  4150. X      freetty();
  4151. X    }
  4152. X      else
  4153. X    brktty(-1);
  4154. X#ifdef DEBUG
  4155. X      if (dfp != stderr)
  4156. X    fclose(dfp);
  4157. X#endif
  4158. X      closeallfiles(win->w_ptyfd);
  4159. X#ifdef DEBUG
  4160. X      if ((dfp = fopen("/tmp/debug/screen.child", "a")) == 0)
  4161. X    dfp = stderr;
  4162. X      else
  4163. X    (void) chmod("/tmp/debug/screen.child", 0666);
  4164. X      debug1("=== ForkWindow: pid %d\n", getpid());
  4165. X#endif
  4166. X      /* Close the three /dev/null descriptors */
  4167. X      close(0);
  4168. X      close(1);
  4169. X      close(2);
  4170. X      newfd = -1;
  4171. X      /* 
  4172. X       * distribute filedescriptors between the ttys
  4173. X       */
  4174. X#ifdef PSEUDOS
  4175. X      pat = pwin ? pwin->fdpat : 
  4176. X           ((F_PFRONT<<(F_PSHIFT*2)) | (F_PFRONT<<F_PSHIFT) | F_PFRONT);
  4177. X      wfdused = 0;
  4178. X      for(i = 0; i < 3; i++)
  4179. X    {
  4180. X      if (pat & F_PFRONT << F_PSHIFT * i)
  4181. X        {
  4182. X          if (newfd < 0)
  4183. X        {
  4184. X          if ((newfd = open(ttyn, O_RDWR)) < 0)
  4185. X            {
  4186. X              SendErrorMsg("Cannot open %s: %s",
  4187. X                   ttyn, sys_errlist[errno]);
  4188. X              eexit(1);
  4189. X            }
  4190. X        }
  4191. X          else
  4192. X        dup(newfd);
  4193. X        }
  4194. X      else
  4195. X        {
  4196. X          dup(win->w_ptyfd);
  4197. X          wfdused = 1;
  4198. X        }
  4199. X    }
  4200. X      if (wfdused)
  4201. X    {
  4202. X        /* 
  4203. X         * the pseudo window process should not be surprised with a 
  4204. X         * nonblocking filedescriptor. Poor Backend!
  4205. X         */
  4206. X        debug1("Clearing NDELAY on window-fd(%d)\n", win->w_ptyfd);
  4207. X        if (fcntl(win->w_ptyfd, F_SETFL, 0))
  4208. X          SendErrorMsg("Warning: ForkWindow clear NDELAY fcntl failed, %d", errno);
  4209. X    }
  4210. X#else /* PSEUDOS */
  4211. X      if ((newfd = open(ttyn, O_RDWR)) != 0)
  4212. X    {
  4213. X      SendErrorMsg("Cannot open %s: %s", ttyn, sys_errlist[errno]);
  4214. X      eexit(1);
  4215. X    }
  4216. X      dup(0);
  4217. X      dup(0);
  4218. X#endif /* PSEUDOS */
  4219. X      close(win->w_ptyfd);
  4220. X
  4221. X      if (newfd >= 0)
  4222. X    {
  4223. X      struct mode fakemode, *modep;
  4224. X#ifdef SVR4
  4225. X      if (ioctl(newfd, I_PUSH, "ptem"))
  4226. X        {
  4227. X          SendErrorMsg("Cannot I_PUSH ptem %s %s", ttyn, sys_errlist[errno]);
  4228. X          eexit(1);
  4229. X        }
  4230. X      if (ioctl(newfd, I_PUSH, "ldterm"))
  4231. X        {
  4232. X          SendErrorMsg("Cannot I_PUSH ldterm %s %s", ttyn, sys_errlist[errno]);
  4233. X          eexit(1);
  4234. X        }
  4235. X      if (ioctl(newfd, I_PUSH, "ttcompat"))
  4236. X        {
  4237. X          SendErrorMsg("Cannot I_PUSH ttcompat %s %s", ttyn, sys_errlist[errno]);
  4238. X          eexit(1);
  4239. X        }
  4240. X#endif
  4241. X      if (fgtty(newfd))
  4242. X        SendErrorMsg("fgtty: %s (%d)", sys_errlist[errno], errno);
  4243. X      if (display)
  4244. X        {
  4245. X          debug("ForkWindow: using display tty mode for new child.\n");
  4246. X          modep = &d_OldMode;
  4247. X        }
  4248. X      else
  4249. X        {
  4250. X          debug("No display - creating tty setting\n");
  4251. X          modep = &fakemode;
  4252. X          InitTTY(modep, 0);
  4253. X#ifdef DEBUG
  4254. X          DebugTTY(modep);
  4255. X#endif
  4256. X        }
  4257. X      /* We only want echo if the users input goes to the pseudo
  4258. X       * and the pseudo's stdout is not send to the window.
  4259. X       */
  4260. X#ifdef PSEUDOS
  4261. X      if (pwin && (!(pat & F_UWP) || (pat & F_PBACK << F_PSHIFT)))
  4262. X        {
  4263. X          debug1("clearing echo on pseudywin fd (pat %x)\n", pat);
  4264. X# if defined(POSIX) || defined(TERMIO)
  4265. X          modep->tio.c_lflag &= ~ECHO;
  4266. X          modep->tio.c_iflag &= ~ICRNL;
  4267. X# else
  4268. X          modep->m_ttyb.sg_flags &= ~ECHO;
  4269. X# endif
  4270. X        }
  4271. X#endif
  4272. X      SetTTY(newfd, modep);
  4273. X#ifdef TIOCSWINSZ
  4274. X      glwz.ws_col = w;
  4275. X      glwz.ws_row = h;
  4276. X      (void) ioctl(newfd, TIOCSWINSZ, &glwz);
  4277. X#endif
  4278. X    }
  4279. X#ifndef TIOCSWINSZ
  4280. X      sprintf(libuf, "LINES=%d", h);
  4281. X      sprintf(cobuf, "COLUMNS=%d", w);
  4282. X      NewEnv[5] = libuf;
  4283. X      NewEnv[6] = cobuf;
  4284. X#endif
  4285. X      if (win->w_aflag)
  4286. X    NewEnv[2] = MakeTermcap(1);
  4287. X      else
  4288. X    NewEnv[2] = Termcap;
  4289. X      proc = *args;
  4290. X      if (*proc == '-')
  4291. X    proc++;
  4292. X      strcpy(shellbuf, "SHELL=");
  4293. X      strncpy(shellbuf + 6, proc, MAXPATHLEN);
  4294. X      shellbuf[MAXPATHLEN + 6] = 0;
  4295. X      NewEnv[4] = shellbuf;
  4296. X      if (term && *term && strcmp(screenterm, term) &&
  4297. X      (strlen(term) < 20))
  4298. X    {
  4299. X      char *s1, *s2, tl;
  4300. X
  4301. X      sprintf(tebuf, "TERM=%s", term);
  4302. X      debug2("Makewindow %d with %s\n", win->w_number, tebuf);
  4303. X      tl = strlen(term);
  4304. X      NewEnv[1] = tebuf;
  4305. X      if ((s1 = index(Termcap, '|')))
  4306. X        {
  4307. X          if ((s2 = index(++s1, '|')))
  4308. X        {
  4309. X          if (strlen(Termcap) - (s2 - s1) + tl < 1024)
  4310. X            {
  4311. X              bcopy(s2, s1 + tl, strlen(s2) + 1);
  4312. X              bcopy(term, s1, tl);
  4313. X            }
  4314. X        }
  4315. X        }
  4316. X    }
  4317. X      sprintf(ebuf, "WINDOW=%d", win->w_number);
  4318. X      NewEnv[3] = ebuf;
  4319. X
  4320. X      debug1("calling execvpe %s\n", proc);
  4321. X      execvpe(proc, args, NewEnv);
  4322. X      debug1("exec error: %d\n", errno);
  4323. X      SendErrorMsg("Cannot exec %s: %s", proc, sys_errlist[errno]);
  4324. X      exit(1);
  4325. X    default:
  4326. X      return pid;
  4327. X    } /* end fork switch */
  4328. X  /* NOTREACHED */
  4329. X}
  4330. X
  4331. Xstatic void
  4332. Xexecvpe(prog, args, env)
  4333. Xchar *prog, **args, **env;
  4334. X{
  4335. X  register char *path = NULL, *p;
  4336. X  char buf[1024];
  4337. X  char *shargs[MAXARGS + 1];
  4338. X  register int i, eaccess = 0;
  4339. X
  4340. X  for (i = 0; i < 3; i++)
  4341. X    if (!strncmp("../" + i, prog, 3 - i))
  4342. X      path = "";
  4343. X  if (!path && !(path = getenv("PATH")))
  4344. X    path = DefaultPath;
  4345. X  do
  4346. X    {
  4347. X      p = buf;
  4348. X      while (*path && *path != ':')
  4349. X    *p++ = *path++;
  4350. X      if (p > buf)
  4351. X    *p++ = '/';
  4352. X      strcpy(p, prog);
  4353. X      execve(buf, args, env);
  4354. X      switch (errno)
  4355. X    {
  4356. X    case ENOEXEC:
  4357. X      shargs[0] = DefaultShell;
  4358. X      shargs[1] = buf;
  4359. X      for (i = 1; (shargs[i + 1] = args[i]) != NULL; ++i)
  4360. X        ;
  4361. X      execve(DefaultShell, shargs, env);
  4362. X      return;
  4363. X    case EACCES:
  4364. X      eaccess = 1;
  4365. X      break;
  4366. X    case ENOMEM:
  4367. X    case E2BIG:
  4368. X    case ETXTBSY:
  4369. X      return;
  4370. X    }
  4371. X    } while (*path++);
  4372. X  if (eaccess)
  4373. X    errno = EACCES;
  4374. X}
  4375. X
  4376. X#ifdef PSEUDOS
  4377. X
  4378. Xint
  4379. Xwinexec(av)
  4380. Xchar **av;
  4381. X{
  4382. X  char **pp;
  4383. X  char *p, *s, *t;
  4384. X  int i, r = 0, l = 0;
  4385. X  struct win *w;
  4386. X  extern struct display *display;
  4387. X  extern struct win *windows;
  4388. X  struct pseudowin *pwin;
  4389. X  
  4390. X  if ((w = display ? fore : windows) == NULL)
  4391. X    return -1;
  4392. X  if (!*av || w->w_pwin)
  4393. X    {
  4394. X      Msg(0, "Filter running: %s", w->w_pwin ? w->w_pwin->p_cmd : "(none)");
  4395. X      return -1;
  4396. X    }
  4397. X  if (!(pwin = (struct pseudowin *)malloc(sizeof(struct pseudowin))))
  4398. X    {
  4399. X      Msg(0, strnomem);
  4400. X      return -1;
  4401. X    }
  4402. X  bzero((char *)pwin, (int)sizeof(*pwin));
  4403. X
  4404. X  /* allow ^a:!!./ttytest as a short form for ^a:exec !.. ./ttytest */
  4405. X  for (s = *av; *s == ' '; s++)
  4406. X    ;
  4407. X  for (p = s; *p == ':' || *p == '.' || *p == '!'; p++)
  4408. X    ;
  4409. X  if (*p != '|')
  4410. X    while (*p && p > s && p[-1] == '.')
  4411. X      p--;
  4412. X  if (*p == '|')
  4413. X    {
  4414. X      l = F_UWP;
  4415. X      p++;
  4416. X    }
  4417. X  if (*p) 
  4418. X    av[0] = p;
  4419. X  else
  4420. X    av++;
  4421. X
  4422. X  t = pwin->p_cmd;
  4423. X  for (i = 0; i < 3; i++)
  4424. X    {
  4425. X      *t = (s < p) ? *s++ : '.';
  4426. X      switch (*t++)
  4427. X    {
  4428. X    case '.':
  4429. X    case '|':
  4430. X      l |= F_PFRONT << (i * F_PSHIFT);
  4431. X      break;
  4432. X    case '!':
  4433. X      l |= F_PBACK << (i * F_PSHIFT);
  4434. X      break;
  4435. X    case ':':
  4436. X      l |= F_PBOTH << (i * F_PSHIFT);
  4437. X      break;
  4438. X    }
  4439. X    }
  4440. X  
  4441. X  if (l & F_UWP)
  4442. X    {
  4443. X      *t++ = '|';
  4444. X      if ((l & F_PMASK) == F_PFRONT)
  4445. X    {
  4446. X      *pwin->p_cmd = '!';
  4447. X      l ^= F_PFRONT | F_PBACK;
  4448. X    }
  4449. X    }
  4450. X  if (!(l & F_PBACK))
  4451. X    l |= F_UWP;
  4452. X  *t++ = ' ';
  4453. X  pwin->fdpat = l;
  4454. X  debug1("winexec: '%#x'\n", pwin->fdpat);
  4455. X  
  4456. X  l = MAXSTR - 4;
  4457. X  for (pp = av; *pp; pp++)
  4458. X    {
  4459. X      p = *pp;
  4460. X      while (*p && l-- > 0)
  4461. X        *t++ = *p++;
  4462. X      if (l <= 0)
  4463. X    break;
  4464. X      *t++ = ' ';
  4465. X    }
  4466. X  *--t = '\0';
  4467. X  debug1("%s\n", pwin->p_cmd);
  4468. X  
  4469. X  if ((pwin->p_ptyfd = OpenDevice(av[0], 0, &l, &t)) < 0)
  4470. X    {
  4471. X      free(pwin);
  4472. X      return -1;
  4473. X    }
  4474. X  strncpy(pwin->p_tty, t, MAXSTR - 1);
  4475. X  w->w_pwin = pwin;
  4476. X  if (l == TTY_FLAG_PLAIN)
  4477. X    {
  4478. X      FreePseudowin(w);
  4479. X      Msg(0, "Cannot handle a TTY as a pseudo win.");
  4480. X      return -1;
  4481. X    }
  4482. X#ifdef TIOCPKT
  4483. X  {
  4484. X    int flag = 0;
  4485. X
  4486. X    if (ioctl(pwin->p_ptyfd, TIOCPKT, &flag))
  4487. X      {
  4488. X    Msg(errno, "TIOCPKT ioctl");
  4489. X    FreePseudowin(w);
  4490. X    return -1;
  4491. X      }
  4492. X  }
  4493. X#endif /* TIOCPKT */
  4494. X  pwin->p_pid = ForkWindow(av, NULL, NULL, t, w);
  4495. X  if ((r = pwin->p_pid) < 0)
  4496. X    FreePseudowin(w);
  4497. X  return r;
  4498. X}
  4499. X
  4500. Xvoid
  4501. XFreePseudowin(w)
  4502. Xstruct win *w;
  4503. X{
  4504. X  struct pseudowin *pwin = w->w_pwin;
  4505. X
  4506. X  ASSERT(pwin);
  4507. X  if (fcntl(w->w_ptyfd, F_SETFL, FNDELAY))
  4508. X    Msg(errno, "Warning: FreePseudowin: NDELAY fcntl failed");
  4509. X  (void) chmod(pwin->p_tty, 0666);
  4510. X  (void) chown(pwin->p_tty, 0, 0);
  4511. X  if (pwin->p_ptyfd >= 0)
  4512. X    close(pwin->p_ptyfd);
  4513. X  free(pwin);
  4514. X  w->w_pwin = NULL;
  4515. X}
  4516. X
  4517. X#endif /* PSEUDOS */
  4518. X
  4519. X
  4520. X#ifdef MULTI
  4521. X
  4522. Xstatic void CloneTermcap __P((struct display *));
  4523. Xextern char **environ;
  4524. X
  4525. Xint
  4526. Xexecclone(av)
  4527. Xchar **av;
  4528. X{
  4529. X  int f, sf;
  4530. X  char specialbuf[6];
  4531. X  struct display *old = display;
  4532. X  char **avp, *namep;
  4533. X
  4534. X  sf = OpenPTY(&namep);
  4535. X  if (sf == -1)
  4536. X    {
  4537. X      Msg(0, "No more PTYs.");
  4538. X      return -1;
  4539. X    }
  4540. X  f = open(namep, O_RDWR);
  4541. X  if (f == -1)
  4542. X    {
  4543. X      close(sf);
  4544. X      Msg(errno, "Cannot open slave");
  4545. X      return -1;
  4546. X    }
  4547. X  brktty(f);
  4548. X  signal(SIGHUP, SIG_IGN);    /* No hangups, please */
  4549. X  if (MakeDisplay(d_username, namep, d_termname, f, -1, &d_OldMode) == 0)
  4550. X    {
  4551. X      display = old;
  4552. X      Msg(0, "Could not make display.");
  4553. X      close(f);
  4554. X      return -1;
  4555. X    }
  4556. X  SetMode(&d_OldMode, &d_NewMode);
  4557. X  SetTTY(f, &d_NewMode);
  4558. X  switch (fork())
  4559. X    {
  4560. X    case -1:
  4561. X      FreeDisplay();
  4562. X      display = old;
  4563. X      Msg(errno, "fork");
  4564. X      return -1;
  4565. X    case 0:
  4566. X      setuid(real_uid);
  4567. X      setgid(real_gid);
  4568. X      d_usertty[0] = 0;
  4569. X      closeallfiles(sf);
  4570. X      close(1);
  4571. X      dup(sf);
  4572. X      close(sf);
  4573. X#ifdef DEBUG
  4574. X      if ((dfp = fopen("/tmp/debug/screen.child", "a")) == 0)
  4575. X    dfp = stderr;
  4576. X      else
  4577. X    (void) chmod("/tmp/debug/screen.child", 0666);
  4578. X      debug1("=== Clone: pid %d\n", getpid());
  4579. X#endif
  4580. X      for (avp = av; *avp; avp++)
  4581. X        {
  4582. X          if (strcmp(*avp, "%p") == 0)
  4583. X            *avp = namep;
  4584. X          if (strcmp(*avp, "%X") == 0)
  4585. X            *avp = specialbuf;
  4586. X        }
  4587. X      sprintf(specialbuf, "-SXX1");
  4588. X      namep += strlen(namep);
  4589. X      specialbuf[3] = *--namep;
  4590. X      specialbuf[2] = *--namep;
  4591. X#ifdef DEBUG
  4592. X      debug("Calling:");
  4593. X      for (avp = av; *avp; avp++)
  4594. X        debug1(" %s", *avp);
  4595. X      debug("\n");
  4596. X#endif
  4597. X      execvpe(*av, av, environ);
  4598. X      SendErrorMsg("Cannot exec %s: %s", *av, sys_errlist[errno]);
  4599. X      exit(1);
  4600. X    default:
  4601. X      break;
  4602. X    }
  4603. X  close(sf);
  4604. X  CloneTermcap(old);
  4605. X  InitTerm(0);
  4606. X  Activate(0);
  4607. X  if (d_fore == 0)
  4608. X    ShowWindows();
  4609. X  return 0;
  4610. X}
  4611. X
  4612. Xextern struct term term[];      /* terminal capabilities */
  4613. X
  4614. Xstatic void
  4615. XCloneTermcap(old)
  4616. Xstruct display *old;
  4617. X{
  4618. X  char *tp;
  4619. X  int i;
  4620. X
  4621. X  tp = d_tentry;
  4622. X  for (i = 0; i < T_N; i++)
  4623. X    {
  4624. X      switch(term[i].type)
  4625. X        {
  4626. X        case T_FLG:
  4627. X          d_tcs[i].flg = old->_d_tcs[i].flg;
  4628. X          break;
  4629. X        case T_NUM:
  4630. X          d_tcs[i].num = old->_d_tcs[i].num;
  4631. X          break;
  4632. X        case T_STR:
  4633. X          d_tcs[i].str = old->_d_tcs[i].str;
  4634. X          if (d_tcs[i].str)
  4635. X            {
  4636. X              strcpy(tp, d_tcs[i].str);
  4637. X              d_tcs[i].str = tp;
  4638. X              tp += strlen(tp) + 1;
  4639. X            }
  4640. X      break;
  4641. X        default:
  4642. X          Panic(0, "Illegal tc type in entry #%d", i);
  4643. X        }
  4644. X    }
  4645. X  CheckScreenSize(0);
  4646. X  for (i = 0; i < NATTR; i++)
  4647. X    d_attrtab[i] = old->_d_attrtab[i];
  4648. X  for (i = 0; i < 256; i++)
  4649. X    d_c0_tab[i] = old->_d_c0_tab[i];
  4650. X  d_UPcost = old->_d_UPcost;
  4651. X  d_DOcost = old->_d_DOcost;
  4652. X  d_NLcost = old->_d_NLcost;
  4653. X  d_LEcost = old->_d_LEcost;
  4654. X  d_NDcost = old->_d_NDcost;
  4655. X  d_CRcost = old->_d_CRcost;
  4656. X  d_IMcost = old->_d_IMcost;
  4657. X  d_EIcost = old->_d_EIcost;
  4658. X#ifdef AUTO_NUKE
  4659. X  d_auto_nuke = old->_d_auto_nuke;
  4660. X#endif
  4661. X  d_tcinited = 1;
  4662. X}
  4663. X
  4664. X#endif
  4665. X
  4666. END_OF_FILE
  4667. if test 20351 -ne `wc -c <'window.c'`; then
  4668.     echo shar: \"'window.c'\" unpacked with wrong size!
  4669. fi
  4670. # end of 'window.c'
  4671. fi
  4672. echo shar: End of archive 4 \(of 10\).
  4673. cp /dev/null ark4isdone
  4674. MISSING=""
  4675. for I in 1 2 3 4 5 6 7 8 9 10 ; do
  4676.     if test ! -f ark${I}isdone ; then
  4677.     MISSING="${MISSING} ${I}"
  4678.     fi
  4679. done
  4680. if test "${MISSING}" = "" ; then
  4681.     echo You have unpacked all 10 archives.
  4682.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  4683. else
  4684.     echo You still need to unpack the following archives:
  4685.     echo "        " ${MISSING}
  4686. fi
  4687. ##  End of shell archive.
  4688. exit 0
  4689.