home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume28 / screen32 / part07 < prev    next >
Encoding:
Text File  |  1992-02-08  |  55.0 KB  |  2,416 lines

  1. Newsgroups: comp.sources.misc
  2. From: jnweiger@immd4.informatik.uni-erlangen.de (Juergen Weigert)
  3. Subject:  v28i024:  screen-3.2 - multiple windows on an ASCII terminal, v3.2, Part07/11
  4. Message-ID: <1992Feb9.223729.6800@sparky.imd.sterling.com>
  5. X-Md4-Signature: 0d304e0df855153b444f13c61fdcf891
  6. Date: Sun, 9 Feb 1992 22:37:29 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: jnweiger@immd4.informatik.uni-erlangen.de (Juergen Weigert)
  10. Posting-number: Volume 28, Issue 24
  11. Archive-name: screen-3.2/part07
  12. Environment: UNIX
  13.  
  14. #!/bin/sh
  15. # do not concatenate these parts, unpack them in order with /bin/sh
  16. # file screen3.2/screen.c continued
  17. #
  18. if test ! -r _shar_seq_.tmp; then
  19.     echo 'Please unpack part 1 first!'
  20.     exit 1
  21. fi
  22. (read Scheck
  23.  if test "$Scheck" != 7; then
  24.     echo Please unpack part "$Scheck" next!
  25.     exit 1
  26.  else
  27.     exit 0
  28.  fi
  29. ) < _shar_seq_.tmp || exit 1
  30. if test ! -f _shar_wnt_.tmp; then
  31.     echo 'x - still skipping screen3.2/screen.c'
  32. else
  33. echo 'x - continuing file screen3.2/screen.c'
  34. sed 's/^X//' << 'SHAR_EOF' >> 'screen3.2/screen.c' &&
  35. }
  36. X
  37. void
  38. SetFlow(on)
  39. int on;
  40. {
  41. X  if (flow == on)
  42. X    return;
  43. #if defined(TERMIO) || defined(POSIX)
  44. X  if (on)
  45. X    {
  46. X      NewMode.tio.c_cc[VINTR] = intrc;
  47. #ifdef VSTART
  48. X      NewMode.tio.c_cc[VSTART] = startc;
  49. #endif
  50. #ifdef VSTOP
  51. X      NewMode.tio.c_cc[VSTOP] = stopc;
  52. #endif
  53. X      NewMode.tio.c_iflag |= IXON;
  54. X    }
  55. X  else
  56. X    {
  57. X      NewMode.tio.c_cc[VINTR] = 0377;
  58. #ifdef VSTART
  59. X      NewMode.tio.c_cc[VSTART] = 0377;
  60. #endif
  61. #ifdef VSTOP
  62. X      NewMode.tio.c_cc[VSTOP] = 0377;
  63. #endif
  64. X      NewMode.tio.c_iflag &= ~IXON;
  65. X    }
  66. # ifdef POSIX
  67. X  if (tcsetattr(0, TCSADRAIN, &NewMode.tio))
  68. # else
  69. X  if (ioctl(0, TCSETA, &NewMode.tio) != 0)
  70. # endif
  71. X    debug1("SetFlow: ioctl errno %d\n", errno);
  72. #else
  73. X  if (on)
  74. X    {
  75. X      NewMode.m_tchars.t_intrc = intrc;
  76. X      NewMode.m_tchars.t_startc = startc;
  77. X      NewMode.m_tchars.t_stopc = stopc;
  78. X    }
  79. X  else
  80. X    {
  81. X      NewMode.m_tchars.t_intrc = -1;
  82. X      NewMode.m_tchars.t_startc = -1;
  83. X      NewMode.m_tchars.t_stopc = -1;
  84. X    }
  85. X  if (ioctl(0, TIOCSETC, &NewMode.m_tchars) != 0)
  86. X    debug1("SetFlow: ioctl errno %d\n", errno);
  87. #endif                /* defined(TERMIO) || defined(POSIX) */
  88. X  flow = on;
  89. }
  90. X
  91. /* we return 1 if we could attach one, or 0 if none */
  92. static int Attach(how)
  93. int how;
  94. {
  95. X  int lasts;
  96. X  struct msg m;
  97. X  struct stat st;
  98. X  char *s;
  99. X
  100. X  if (how == MSG_WINCH)
  101. X    {
  102. X      bzero((char *) &m, sizeof(m));
  103. X      m.type = how;
  104. X      if ((lasts = MakeClientSocket(0, SockName)) >= 0)
  105. X    {
  106. X          write(lasts, &m, sizeof(m));
  107. X          close(lasts);
  108. X    }
  109. X      return 0;
  110. X    }
  111. X
  112. X  if (how == MSG_CONT)
  113. X    {
  114. X      if ((lasts = MakeClientSocket(0, SockName)) < 0)
  115. X        {
  116. X          printf("Sorry, cannot contact session \"%s\" again\r\n",
  117. X                 SockName);
  118. X          sleep(2);
  119. X          how = MSG_ATTACH;
  120. X        }
  121. X    }
  122. X    
  123. X  if (how != MSG_CONT)
  124. X    {
  125. X      switch (FindSocket(how, &lasts))
  126. X        {
  127. X        case 0:
  128. X          if (rflag == 2)
  129. X        return 0;
  130. X          if (quietflag)
  131. X        eexit(10);
  132. X          if (SockName && *SockName)
  133. X            Msg(0, "There is no screen to be %sed matching %s.", 
  134. X            dflag ? "detach" : "resum", SockName);
  135. X          else
  136. X            Msg(0, "There is no screen to be %sed.",
  137. X                dflag ? "detach" : "resum");
  138. X          /* NOTREACHED */
  139. X        case 1:
  140. X          break;
  141. X        default:
  142. X          Msg(0, "Type \"screen [-d] -r [pid.]tty.host\" to resume one of them.");
  143. X          /* NOTREACHED */
  144. X        }
  145. X      /*
  146. X       * Go in UserContext. Advantage is, you can kill your attacher
  147. X       * when things go wrong. Any disadvantages? jw.
  148. X       */
  149. X      setuid(real_uid);
  150. X      setgid(real_gid);
  151. X
  152. X      SockName = SockNamePtr;
  153. X      MasterPid = 0;
  154. X      while (*SockName)
  155. X        {
  156. X          if (*SockName > '9' || *SockName < '0')
  157. X        break;
  158. X          MasterPid = 10 * MasterPid + *SockName - '0';
  159. X          SockName++;
  160. X        }
  161. X      SockName = SockNamePtr;
  162. X      debug1("Attach decided, it is '%s'\n", SockPath);
  163. X      debug1("Attach found MasterPid == %d\n", MasterPid);
  164. X      if (stat(SockPath, &st) == -1)
  165. X        Msg(errno, "stat %s", SockPath);
  166. X      if ((st.st_mode & 0700) != (dflag ? 0700 : 0600))
  167. X        Msg(0, "That screen is %sdetached.", dflag ? "already " : "not ");
  168. #ifdef REMOTE_DETACH
  169. X      if (dflag &&
  170. X          (how == MSG_ATTACH || how == MSG_DETACH || how == MSG_POW_DETACH))
  171. X        {
  172. X          strcpy(m.m.detach.tty, attach_tty);
  173. X          debug1("attach_tty is %s\n", attach_tty);
  174. X          m.m.detach.dpid = getpid();
  175. # ifdef POW_DETACH
  176. X          if (dflag == 2)
  177. X        m.type = MSG_POW_DETACH;
  178. X          else
  179. # endif
  180. X        m.type = MSG_DETACH;
  181. X          if (write(lasts, (char *) &m, sizeof(m)) != sizeof(m))
  182. X            Msg(errno, "write");
  183. X          close(lasts);
  184. X          if (how != MSG_ATTACH)
  185. X            return 0;    /* we detached it. jw. */
  186. X          sleep(1);    /* we dont want to overrun our poor backend. jw. */
  187. X          if ((lasts = MakeClientSocket(0, SockName)) == -1)
  188. X            Msg(0, "Cannot contact screen again. Shit.");
  189. X        }
  190. #endif
  191. X    }
  192. X  m.type = how;
  193. X  strcpy(m.m.attach.tty, attach_tty);
  194. X  debug1("attach_tty is %s\n", attach_tty);
  195. X  s = getenv("TERM");
  196. X  if (s)
  197. X    {
  198. X      if (strlen(s) >= MAXPATH - 5)
  199. X    Msg(0, "$TERM too long - sorry.");
  200. X      sprintf(m.m.attach.envterm, "TERM=%s", s);
  201. X    }
  202. X  else
  203. X    *m.m.attach.envterm = '\0';
  204. X  debug1("attach: sending %d bytes... ", sizeof m);
  205. X
  206. X  m.m.attach.apid = getpid();
  207. X  m.m.attach.adaptflag = adaptflag;
  208. X  m.m.attach.lines = m.m.attach.columns = 0;
  209. X  if (s = getenv("LINES"))
  210. X    m.m.attach.lines = atoi(s);
  211. X  if (s = getenv("COLUMNS"))
  212. X    m.m.attach.columns = atoi(s);
  213. X
  214. #ifdef PASSWORD
  215. X  if (how == MSG_ATTACH || how == MSG_CONT)
  216. X    trysend(lasts, &m, m.m.attach.password);
  217. X  else
  218. #endif
  219. X    {
  220. X      if (write(lasts, (char *) &m, sizeof(m)) != sizeof(m))
  221. X    Msg(errno, "write");
  222. X      close(lasts);
  223. X    }
  224. X  debug1("Attach(%d): sent\n", m.type);
  225. X  Suspended = 0;
  226. X  rflag = 0;
  227. X  return 1;
  228. }
  229. X
  230. X
  231. #ifdef PASSWORD
  232. X
  233. static trysendstat;
  234. X
  235. static sig_t trysendok(SIGDEFARG)
  236. {
  237. X  trysendstat = 1;
  238. }
  239. X
  240. static sig_t trysendfail(SIGDEFARG)
  241. {
  242. X  trysendstat = -1;
  243. # ifdef SYSV
  244. X  signal(SIG_PW_FAIL, trysendfail);
  245. # endif /* SYSV */
  246. }
  247. X
  248. static char screenpw[9];
  249. X
  250. static void trysend(fd, m, pwto)
  251. int fd;
  252. struct msg *m;
  253. char *pwto;
  254. {
  255. X  char *npw = NULL;
  256. X  sig_t (*sighup)();
  257. X  sig_t (*sigusr1)();
  258. X  int tries;
  259. X
  260. X  sigusr1 = signal(SIG_PW_OK, trysendok);
  261. X  sighup = signal(SIG_PW_FAIL, trysendfail);
  262. X  for (tries = 0; ; )
  263. X    {
  264. X      strcpy(pwto, screenpw);
  265. X      trysendstat = 0;
  266. X      if (write(fd, (char *) m, sizeof(*m)) != sizeof(*m))
  267. X    Msg(errno, "write");
  268. X      close(fd);
  269. X      while (trysendstat == 0)
  270. X    pause();
  271. X      if (trysendstat > 0)
  272. X    {
  273. X      signal(SIG_PW_OK, sigusr1);
  274. X      signal(SIG_PW_FAIL, sighup);
  275. X      return;
  276. X    }
  277. X      if (++tries > 1 || (npw = getpass("Screen Password:")) == 0 || *npw == 0)
  278. X    Msg(0, "Password incorrect");
  279. X      strncpy(screenpw, npw, 8);
  280. X      if ((fd = MakeClientSocket(0, SockName)) == -1)
  281. X    Msg(0, "Cannot contact screen again. Shit.");
  282. X    }
  283. }
  284. #endif /* PASSWORD */
  285. X
  286. X
  287. /*
  288. X * Unfortunatelly this is also the SIGHUP handler, so we have to
  289. X * check, if the backend is already detached.
  290. X */
  291. X
  292. static sig_t AttacherFinit(SIGDEFARG)
  293. {
  294. X  struct stat statb;
  295. X  struct msg m;
  296. X  int s;
  297. X
  298. X  debug("AttacherFinit();\n");
  299. X  signal(SIGHUP, SIG_IGN);
  300. X  /* Check if signal comes from backend */
  301. X  if (SockName)
  302. X    {
  303. X      strcpy(SockNamePtr, SockName);
  304. X      if (stat(SockPath, &statb) == 0 && (statb.st_mode & 0777) != 0600)
  305. X    {
  306. X      debug("Detaching backend!\n");
  307. X      bzero((char *) &m, sizeof(m));
  308. X      strcpy(m.m.detach.tty, attach_tty);
  309. X          debug1("attach_tty is %s\n", attach_tty);
  310. X      m.m.detach.dpid = getpid();
  311. X      m.type = MSG_HANGUP;
  312. X      if ((s = MakeClientSocket(0, SockName)) >= 0)
  313. X        {
  314. X          write(s, &m, sizeof(m));
  315. X          close(s);
  316. X        }
  317. X    }
  318. X    }
  319. X  exit(0);
  320. #ifndef SIGVOID
  321. X  return((sig_t) 0);
  322. #endif
  323. }
  324. X
  325. #ifdef POW_DETACH
  326. static sig_t AttacherFinitBye(SIGDEFARG)
  327. {
  328. X  int ppid;
  329. X  debug("AttacherFintBye()\n");
  330. X  freetty();
  331. X  setuid(real_uid);
  332. X  setgid(real_gid);
  333. X  /* we don't want to disturb init (even if we were root), eh? jw */
  334. X  if ((ppid = getppid()) > 1)
  335. X    Kill(ppid, SIGHUP);        /* carefully say good bye. jw. */
  336. X  exit(0);
  337. #ifndef SIGVOID
  338. X  return((sig_t) 0);
  339. #endif
  340. }
  341. #endif
  342. X
  343. static SuspendPlease;
  344. X
  345. static sig_t SigStop(SIGDEFARG)
  346. {
  347. X  debug("SigStop()\n");
  348. X  SuspendPlease = 1;
  349. #ifndef SIGVOID
  350. X  return((sig_t) 0);
  351. #endif
  352. }
  353. X
  354. #ifdef LOCK
  355. static LockPlease;
  356. X
  357. static sig_t DoLock(SIGDEFARG)
  358. {
  359. X  debug("DoLock()\n");
  360. X  LockPlease = 1;
  361. # ifdef SYSV
  362. X  signal(SIG_LOCK, DoLock);
  363. # endif
  364. # ifndef SIGVOID
  365. X  return((sig_t) 0);
  366. # endif
  367. }
  368. #endif
  369. X
  370. #if defined(SIGWINCH) && defined(TIOCGWINSZ)
  371. static SigWinchPlease;
  372. X
  373. static sig_t SigAttWinch(SIGDEFARG)
  374. {
  375. X  debug("SigAttWinch()\n");
  376. X  SigWinchPlease = 1;
  377. # ifndef SIGVOID
  378. X  return((sig_t) 0);
  379. # endif
  380. }
  381. #endif
  382. X
  383. static void Attacher()
  384. {
  385. X  /*
  386. X   * permanent in UserContext. Advantage is, you can kill your attacher
  387. X   * when things go wrong. Any disadvantages? jw.
  388. X   */
  389. X  setuid(real_uid);    /* XXX: already done in Attach() */
  390. X  setgid(real_gid);    /* XXX: already done in Attach() */
  391. X
  392. X  signal(SIGHUP, AttacherFinit);
  393. X  signal(SIG_BYE, AttacherFinit);
  394. #ifdef POW_DETACH
  395. X  signal(SIG_POWER_BYE, AttacherFinitBye);
  396. #endif
  397. #ifdef LOCK
  398. X  signal(SIG_LOCK, DoLock);
  399. #endif
  400. X  signal(SIGINT, AttacherSigInt);
  401. #ifdef BSDJOBS
  402. X  signal(SIG_STOP, SigStop);
  403. #endif
  404. #if defined(SIGWINCH) && defined(TIOCGWINSZ)
  405. X  signal(SIGWINCH, SigAttWinch);
  406. #endif
  407. #ifdef DEBUG
  408. # ifdef SYSV
  409. X  signal(SIGCLD, FEChld);
  410. # else
  411. X  signal(SIGCHLD, FEChld);
  412. # endif
  413. #endif
  414. X  debug("attacher: going for a nap.\n");
  415. X  dflag = 0;
  416. X  while (1)
  417. X    {
  418. X      pause();
  419. X      debug("attacher: huh! a signal!\n");
  420. #ifdef DEBUG
  421. X      if (FEpanic)
  422. X        {
  423. X      printf("\n\rSuddenly the Dungeon collapses!! - You die...\n\r");
  424. X      SetTTY(0, &OldMode);
  425. X      eexit(1);
  426. X        }
  427. #endif
  428. #ifdef BSDJOBS
  429. X      if (SuspendPlease)
  430. X    {
  431. X      SuspendPlease = 0;
  432. X      signal(SIGTSTP, SIG_DFL);
  433. X      debug("attacher: killing myself SIGTSTP\n");
  434. X      kill(getpid(), SIGTSTP);
  435. X
  436. X      debug1("attacher: continuing from stop(%d)\n", Suspended);
  437. X      signal(SIG_STOP, SigStop);
  438. X      (void) Attach(MSG_CONT);
  439. X    }
  440. #endif
  441. #ifdef LOCK
  442. X      if (LockPlease)
  443. X    {
  444. X      LockPlease = 0;
  445. X      LockTerminal();
  446. # ifdef SYSV
  447. X      signal(SIG_LOCK, DoLock);
  448. # endif
  449. X      (void) Attach(MSG_CONT);
  450. X    }
  451. #endif    /* LOCK */
  452. #if defined(SIGWINCH) && defined(TIOCGWINSZ)
  453. X      if (SigWinchPlease)
  454. X    {
  455. X      SigWinchPlease = 0;
  456. # ifdef SYSV
  457. X      signal(SIGWINCH, SigAttWinch);
  458. # endif
  459. X      (void) Attach(MSG_WINCH);
  460. X    }
  461. #endif    /* SIGWINCH */
  462. X    }
  463. }
  464. X
  465. #ifdef LOCK
  466. X
  467. /* ADDED by Rainer Pruy 10/15/87 */
  468. /* POLISHED by mls. 03/10/91 */
  469. X
  470. static char LockEnd[] = "Welcome back to screen !!\n";
  471. X
  472. static void LockTerminal()
  473. {
  474. X  char *prg;
  475. X  int sig, pid;
  476. X  sig_t (*sigs[NSIG])__P(SIGPROTOARG);
  477. X
  478. X  for (sig = 1; sig < NSIG; sig++)
  479. X    {
  480. X      sigs[sig] = signal(sig, SIG_IGN);
  481. X    }
  482. X  SetTTY(0, &OldMode);
  483. X  printf("\n");
  484. X
  485. X  prg = getenv("LOCKPRG");
  486. X  if (prg && strcmp(prg, "builtin") && !access(prg, X_OK))
  487. X    {
  488. # ifdef SYSV
  489. X      signal(SIGCLD, SIG_DFL);
  490. # else /* SYSV */
  491. X      signal(SIGCHLD, SIG_DFL);
  492. # endif /* SYSV */
  493. X      debug1("lockterminal: '%s' seems executable, execl it!\n", prg);
  494. X      if ((pid = fork()) == 0)
  495. X        {
  496. X          /* Child */
  497. X          setuid(real_uid);    /* this should be done already */
  498. X          setgid(real_gid);
  499. X          closeallfiles();    /* important: /etc/shadow may be open */
  500. X          execl(prg, "SCREEN-LOCK", NULL);
  501. X          exit(errno);
  502. X        }
  503. X      if (pid == -1)
  504. X        {
  505. #ifdef NETHACK
  506. X          if (nethackflag)
  507. X            Msg(errno, "Cannot fork terminal - lock failed");
  508. X          else
  509. #endif
  510. X          Msg(errno, "Cannot lock terminal - fork failed");
  511. X        }
  512. X      else
  513. X        {
  514. #ifdef BSDWAIT
  515. X          union wait wstat;
  516. #else
  517. X          int wstat;
  518. #endif
  519. X          int wret;
  520. X
  521. #ifdef hpux
  522. X          signal(SIGCLD, SIG_DFL);
  523. #endif
  524. X          errno = 0;
  525. X          while (((wret = wait((int *) &wstat)) != pid) ||
  526. X             ((wret == -1) && (errno == EINTR))
  527. X             )
  528. X        errno = 0;
  529. X    
  530. X          if (errno)
  531. X        {
  532. X          perror("Lock");
  533. X          sleep(2);
  534. X        }
  535. X      else if (WTERMSIG(wstat) != 0)
  536. X        {
  537. X          fprintf(stderr, "Lock: %s: Killed by signal: %d%s\n", prg,
  538. X              WTERMSIG(wstat), WIFCORESIG(wstat) ? " (Core dumped)" : "");
  539. X          sleep(2);
  540. X        }
  541. X      else if (WEXITSTATUS(wstat))
  542. X        {
  543. X          debug2("Lock: %s: return code %d\n", prg, WEXITSTATUS(wstat));
  544. X        }
  545. X          else
  546. X        printf(LockEnd);
  547. X        }
  548. X    }
  549. X  else
  550. X    {
  551. X      if (prg)
  552. X    {
  553. X          debug1("lockterminal: '%s' seems NOT executable, we use our builtin\n", prg);
  554. X    }
  555. X      else
  556. X    {
  557. X      debug("lockterminal: using buitin.\n");
  558. X    }
  559. X      screen_builtin_lck();
  560. X    }
  561. X  /* reset signals */
  562. X  for (sig = 1; sig < NSIG; sig++)
  563. X    {
  564. X      if (sigs[sig] != (sig_t(*) ()) - 1)
  565. X    signal(sig, sigs[sig]);
  566. X    }
  567. }                /* LockTerminal */
  568. X
  569. /* -- original copyright by Luigi Cannelloni 1985 (luigi@faui70.UUCP) -- */
  570. void
  571. screen_builtin_lck()
  572. {
  573. X  char fullname[100], *cp1, message[BUFSIZ];
  574. X  char c, *pass, mypass[9];
  575. #ifdef SHADOWPW
  576. X  struct spwd *sss = NULL;
  577. #endif
  578. X  int t;
  579. X
  580. #ifdef undef
  581. X  /* get password entry */
  582. X  if ((ppp = getpwuid(real_uid)) == NULL)
  583. X    {
  584. X      fprintf(stderr, "screen_builtin_lck: No passwd entry.\007\n");
  585. X      sleep(2);
  586. X      return;
  587. X    }
  588. X  if (!isatty(0))
  589. X    {
  590. X      fprintf(stderr, "screen_builtin_lck: Not a tty.\007\n");
  591. X      sleep(2);
  592. X      return;
  593. X    }
  594. #endif
  595. X  pass = ppp->pw_passwd;
  596. realpw:
  597. X  for (t = 0; t < 13; t++)
  598. X    {
  599. X      c = pass[t];
  600. X      if (!(c == '.' || c == '/' ||
  601. X            (c >= '0' && c <= '9') || 
  602. X            (c >= 'a' && c <= 'z') || 
  603. X            (c >= 'A' && c <= 'Z'))) 
  604. X        break;
  605. X    }
  606. X  if (t < 13)
  607. X    {
  608. X      debug("builtin_lock: ppp->pw_passwd bad, has it a shadow?\n");
  609. #ifdef SHADOWPW
  610. X      setspent(); /* rewind shadow file */
  611. X      if ((sss == NULL) && (sss = getspnam(ppp->pw_name)))
  612. X        {
  613. X          pass = sss->sp_pwdp;
  614. X          goto realpw;
  615. X        }
  616. #endif /* SHADOWPW */
  617. X      if (pass = getpass("Key:   "))
  618. X        {
  619. X          strncpy(mypass, pass, 8);
  620. X          mypass[8] = 0;
  621. X          if (*mypass == 0)
  622. X            return;
  623. X          if (pass = getpass("Again: "))
  624. X            {
  625. X              if (strcmp(mypass, pass))
  626. X                {
  627. X                  fprintf(stderr, "Passwords don't match.\007\n");
  628. X                  sleep(2);
  629. X                  return;
  630. X                }
  631. X            }
  632. X        }
  633. X      if (pass == 0)
  634. X        {
  635. X          fprintf(stderr, "Getpass error.\007\n");
  636. X          sleep(2);
  637. X          return;
  638. X        }
  639. X      pass = 0;
  640. X    }
  641. X
  642. X  debug("screen_builtin_lck looking in gcos field\n");
  643. X  strcpy(fullname, ppp->pw_gecos);
  644. X  if ((cp1 = index(fullname, ',')) != NULL)
  645. X    *cp1 = '\0';
  646. X  if ((cp1 = index(fullname, '&')) != NULL)
  647. X    {
  648. X      sprintf(cp1, "%s", ppp->pw_name);
  649. X      *cp1 = islower(*cp1) ? toupper(*cp1) : *cp1;
  650. X    }
  651. X
  652. X  sprintf(message, "Screen used by %s <%s>.\nPassword:\007",
  653. X          fullname, ppp->pw_name);
  654. X
  655. X  /* loop here to wait for correct password */
  656. X  for (;;)
  657. X    {
  658. X      debug("screen_builtin_lck awaiting password\n");
  659. X      if ((cp1 = getpass(message)) == NULL)
  660. X        {
  661. X          AttacherFinit(SIGARG);
  662. X          /* NOTREACHED */
  663. X        }
  664. X      if (pass)
  665. X        {
  666. X          if (!strcmp(crypt(cp1, pass), pass))
  667. X            break;
  668. X        }
  669. X      else
  670. X        {
  671. X          if (!strcmp(cp1, mypass))
  672. X            break;
  673. X        }
  674. X      debug("screen_builtin_lck: NO!!!!!\n");
  675. X    }
  676. X  debug("password ok.\n");
  677. }
  678. X
  679. #endif    /* LOCK */
  680. X
  681. /*
  682. X * Detach now has the following modes:
  683. X *    D_DETACH    SIG_BYE        detach backend and exit attacher
  684. X *    D_STOP        SIG_STOP    stop attacher (and detach backend)
  685. X *    D_REMOTE    SIG_BYE        remote detach -- reattach to new attacher
  686. X *    D_POWER     SIG_POWER_BYE     power detach -- attacher kills his parent
  687. X *    D_REMOTE_POWER    SIG_POWER_BYE    remote power detach -- both
  688. X *    D_LOCK        SIG_LOCK    lock the attacher
  689. X * (jw)
  690. X * we always remove our utmp slots. (even when "lock" or "stop")
  691. X * Note: Take extra care here, we may be called by unterrupt!
  692. X */
  693. void
  694. Detach(mode)
  695. int mode;
  696. {
  697. X  int sign = 0;
  698. #ifdef UTMPOK
  699. X  register int n;
  700. #endif
  701. X
  702. X  if (Detached)
  703. X    return;
  704. X  debug1("Detach(%d)\n", mode);
  705. X  if (fore && status)
  706. X    RemoveStatus();
  707. X  signal(SIGHUP, SIG_IGN);
  708. X  SetTTY(0, &OldMode);
  709. X  FinitTerm();
  710. X  switch (mode)
  711. X    {
  712. X    case D_DETACH:
  713. X      printf("\n[detached]\n");
  714. X      sign = SIG_BYE;
  715. X      break;
  716. #ifdef BSDJOBS
  717. X    case D_STOP:
  718. X      (void) fflush(stdout);
  719. X      sign = SIG_STOP;
  720. X      break;
  721. #endif
  722. #ifdef REMOTE_DETACH
  723. X    case D_REMOTE:
  724. X      printf("\n[remote detached]\n");
  725. X      sign = SIG_BYE;
  726. X      break;
  727. #endif
  728. #ifdef POW_DETACH
  729. X    case D_POWER:
  730. X      printf("\n[power detached]\n");
  731. X      if (PowDetachString) 
  732. X        printf("%s\n", PowDetachString);
  733. X      sign = SIG_POWER_BYE;
  734. X      break;
  735. #ifdef REMOTE_DETACH
  736. X    case D_REMOTE_POWER:
  737. X      printf("\n[remote power detached]\n");
  738. X      if (PowDetachString) 
  739. X        printf("%s\n", PowDetachString);
  740. X      sign = SIG_POWER_BYE;
  741. X      break;
  742. #endif
  743. #endif
  744. X    case D_LOCK:
  745. X      ClearDisplay();
  746. X      sign = SIG_LOCK;
  747. X      /* tell attacher to lock terminal with a lockprg. */
  748. X      break;
  749. X    }
  750. #ifdef UTMPOK
  751. X  for (n = WinList; n != -1; n = wtab[n]->WinLink)
  752. X    if (wtab[n]->slot != (slot_t) -1)
  753. X      {
  754. X    RemoveUtmp(wtab[n]);
  755. X        /*
  756. X     * Set the slot to 0 to get the window
  757. X         * logged in again.
  758. X     */
  759. X    wtab[n]->slot = (slot_t) 0;
  760. X      }
  761. X  RestoreLoginSlot();
  762. #endif
  763. X  freetty();
  764. X  (void) chmod(SockPath, /* S_IFSOCK | */ 0600); /* Flag detached-ness */
  765. X    /*
  766. X     * tell father to father what to do. We do that after we
  767. X     * freed the tty, thus getty feels more comfortable on hpux
  768. X     * if it was a power detach.
  769. X     */
  770. X  Kill(AttacherPid, sign);
  771. X  debug2("Detach: Signal %d to Attacher(%d)!\n", sign, AttacherPid);
  772. X  if (mode != D_LOCK && mode != D_STOP)
  773. X    AttacherPid = 0;
  774. X
  775. X  Detached = 1;
  776. X  Suspended = (mode == D_STOP) ? 1 : 0;
  777. X  if (fore)
  778. X    fore->active = 0;
  779. X  debug("Detach returns, we are successfully detached.\n");
  780. }
  781. X
  782. void
  783. Kill(pid, sig)
  784. int pid, sig;
  785. {
  786. X  if (pid < 2)
  787. X    return;
  788. X  (void) kill(pid, sig);
  789. }
  790. X
  791. static int IsSymbol(e, s)
  792. register char *e, *s;
  793. {
  794. X  register char *p;
  795. X  register int n;
  796. X
  797. X  for (p = e; *p && *p != '='; ++p)
  798. X    ;
  799. X  if (*p)
  800. X    {
  801. X      *p = '\0';
  802. X      n = strcmp(e, s);
  803. X      *p = '=';
  804. X      return n == 0;
  805. X    }
  806. X  return 0;
  807. }
  808. X
  809. static void MakeNewEnv()
  810. {
  811. X  register char **op, **np;
  812. X  static char buf[MAXSTR];
  813. X
  814. X  for (op = environ; *op; ++op)
  815. X    ;
  816. X  NewEnv = np = (char **) malloc((unsigned) (op - environ + 6 + 1) * sizeof(char **));
  817. X  if (!NewEnv)
  818. X    Msg_nomem;
  819. X  if (strlen(SockName) > MAXSTR - 5)
  820. X    SockName = "?";
  821. X  sprintf(buf, "STY=%s", SockName);
  822. X  *np++ = buf;                    /* NewEnv[0] */
  823. X  *np++ = Term;                    /* NewEnv[1] */
  824. #ifdef TIOCSWINSZ
  825. X  np += 2;    /* room for TERMCAP and WINDOW */
  826. #else
  827. X  np += 4;    /* room for TERMCAP WINDOW LINES COLUMNS */
  828. #endif
  829. X
  830. X  for (op = environ; *op; ++op)
  831. X    {
  832. X      if (!IsSymbol(*op, "TERM") && !IsSymbol(*op, "TERMCAP")
  833. X      && !IsSymbol(*op, "STY") && !IsSymbol(*op, "WINDOW")
  834. X      && !IsSymbol(*op, "SCREENCAP")
  835. #ifndef TIOCGWINSZ
  836. X      && !IsSymbol(*op, "LINES") && !IsSymbol(*op, "COLUMNS")
  837. #endif
  838. X      )
  839. X    *np++ = *op;
  840. X    }
  841. X  *np = 0;
  842. }
  843. X
  844. void
  845. #ifdef USEVARARGS
  846. /*VARARGS2*/
  847. # if defined(__STDC__)
  848. Msg(int err, char *fmt, ...)
  849. # else
  850. Msg(err, fmt, va_alist)
  851. int err;
  852. char *fmt;
  853. va_dcl
  854. # endif
  855. {
  856. X  static va_list ap = 0;
  857. #else
  858. /*VARARGS2*/
  859. Msg(err, fmt, p1, p2, p3, p4, p5, p6)
  860. int err;
  861. char *fmt;
  862. unsigned long p1, p2, p3, p4, p5, p6;
  863. {
  864. #endif
  865. X  char buf[MAXPATH*2];
  866. X  char *p = buf;
  867. X
  868. X  if (Detached)
  869. X    return;
  870. #ifdef USEVARARGS
  871. # if defined(__STDC__)
  872. X  va_start(ap, fmt);
  873. # else
  874. X  va_start(ap);
  875. # endif
  876. X  (void) vsprintf(p, fmt, ap);
  877. X  va_end(ap);
  878. #else
  879. X  sprintf(p, fmt, p1, p2, p3, p4, p5, p6);
  880. #endif
  881. X  if (err)
  882. X    {
  883. X      p += strlen(p);
  884. X      if (err > 0 && err < sys_nerr)
  885. X    sprintf(p, ": %s", sys_errlist[err]);
  886. X      else
  887. X    sprintf(p, ": Error %d", err);
  888. X    }
  889. X  if (HasWindow)
  890. X    {
  891. X      debug1("Msg('%s');\n", p);
  892. X      MakeStatus(buf);
  893. X    }
  894. X  else
  895. X    {
  896. X      printf("%s\r\n", buf);
  897. X      if (DeadlyMsg)
  898. X    {
  899. X          debug1("Msg('%s') screen is not up, exiting..\n", buf);
  900. X          Kill(AttacherPid, SIG_BYE);
  901. X          eexit(1);
  902. X    }
  903. X      else
  904. X    debug1("Harmless; Msg('%s');\n", buf);
  905. X    }
  906. X  DeadlyMsg = 1;
  907. }
  908. X
  909. char *Filename(s)
  910. char *s;
  911. {
  912. X  register char *p;
  913. X
  914. X  if (s == NULL) 
  915. X    return s;
  916. X  p = s + strlen(s) - 1;
  917. X  while (p >= s && *p != '/')
  918. X    --p;
  919. X  return ++p;
  920. }
  921. X
  922. /*
  923. X * '^' is allowed as an escape mechanism for control characters. jw.
  924. X */
  925. static char *MakeWinMsg(s, n)
  926. register char *s;
  927. int n;
  928. {
  929. X  static char buf[MAXSTR];
  930. X  register char *p = buf;
  931. X  register int ctrl;
  932. X
  933. X  ctrl = 0;
  934. X  for (; *s && p < buf + MAXSTR - 1; s++, p++)
  935. X    if (ctrl)
  936. X      {
  937. X        ctrl = 0;
  938. X        if (*s == '^' || *s < 64)
  939. X          *p = *s;
  940. X        else 
  941. X          *p = *s - 64;
  942. X      }
  943. X    else
  944. X      {
  945. X        switch (*s)
  946. X          {
  947. X          case '%':
  948. X            *p = n + '0';
  949. X        break;
  950. X          case '~':
  951. X        *p = BELL;
  952. X        break;
  953. X      case '^':
  954. X        ctrl = 1;
  955. X        *p-- = '^';
  956. X        break;
  957. X          default:
  958. X        *p = *s;
  959. X        break;
  960. X          }
  961. X      }
  962. X  *p = '\0';
  963. X  return buf;
  964. }
  965. X
  966. SHAR_EOF
  967. echo 'File screen3.2/screen.c is complete' &&
  968. chmod 0444 screen3.2/screen.c ||
  969. echo 'restore of screen3.2/screen.c failed'
  970. Wc_c="`wc -c < 'screen3.2/screen.c'`"
  971. test 86700 -eq "$Wc_c" ||
  972.     echo 'screen3.2/screen.c: original size 86700, current size' "$Wc_c"
  973. rm -f _shar_wnt_.tmp
  974. fi
  975. # ============= screen3.2/screen.h ==============
  976. if test -f 'screen3.2/screen.h' -a X"$1" != X"-c"; then
  977.     echo 'x - skipping screen3.2/screen.h (File already exists)'
  978.     rm -f _shar_wnt_.tmp
  979. else
  980. > _shar_wnt_.tmp
  981. echo 'x - extracting screen3.2/screen.h (Text)'
  982. sed 's/^X//' << 'SHAR_EOF' > 'screen3.2/screen.h' &&
  983. /* Copyright (c) 1991
  984. X *      Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
  985. X *      Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
  986. X * Copyright (c) 1987 Oliver Laumann
  987. X *
  988. X * This program is free software; you can redistribute it and/or modify
  989. X * it under the terms of the GNU General Public License as published by
  990. X * the Free Software Foundation; either version 1, or (at your option)
  991. X * any later version.
  992. X *
  993. X * This program is distributed in the hope that it will be useful,
  994. X * but WITHOUT ANY WARRANTY; without even the implied warranty of
  995. X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  996. X * GNU General Public License for more details.
  997. X *
  998. X * You should have received a copy of the GNU General Public License
  999. X * along with this program (see the file COPYING); if not, write to the
  1000. X * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  1001. X *
  1002. X * Noteworthy contributors to screen's design and implementation:
  1003. X *    Wayne Davison (davison@borland.com)
  1004. X *    Patrick Wolfe (pat@kai.com, kailand!pat)
  1005. X *    Bart Schaefer (schaefer@cse.ogi.edu)
  1006. X *    Nathan Glasser (nathan@brokaw.lcs.mit.edu)
  1007. X *    Larry W. Virden (lwv27%cas.BITNET@CUNYVM.CUNY.Edu)
  1008. X *    Howard Chu (hyc@hanauma.jpl.nasa.gov)
  1009. X *    Tim MacKenzie (tym@dibbler.cs.monash.edu.au)
  1010. X *    Markku Jarvinen (mta@{cc,cs,ee}.tut.fi)
  1011. X *    Marc Boucher (marc@CAM.ORG)
  1012. X *
  1013. X ****************************************************************
  1014. X * $Id: screen.h,v 1.2 92/02/03 02:28:13 jnweiger Exp $ FAU
  1015. X */
  1016. X
  1017. /* screen.h now includes enough to satisfy its own references.
  1018. X * only config.h is still needed.
  1019. X */
  1020. X
  1021. #include <stdio.h>
  1022. #include <errno.h>
  1023. X
  1024. #ifdef ISC
  1025. # ifdef ENAMETOOLONG
  1026. #  undef ENAMETOOLONG
  1027. # endif
  1028. # ifdef ENOTEMPTY
  1029. #  undef ENOTEMPTY
  1030. # endif
  1031. # include <net/errno.h>
  1032. #endif
  1033. X
  1034. #if defined(pyr)
  1035. extern int errno;
  1036. #endif
  1037. X
  1038. #ifdef sun
  1039. # define getpgrp __getpgrp
  1040. # define exit __exit
  1041. #endif
  1042. X
  1043. #ifdef POSIX
  1044. #include <unistd.h>
  1045. # if defined(__STDC__)
  1046. #  include <stdlib.h>
  1047. # endif
  1048. #endif
  1049. X
  1050. #ifdef sun
  1051. # undef getpgrp
  1052. # undef exit
  1053. #endif
  1054. X
  1055. #ifdef POSIX
  1056. # include <termios.h>
  1057. # ifdef hpux
  1058. #  include <bsdtty.h>
  1059. # endif
  1060. #else
  1061. # ifdef TERMIO
  1062. #  include <termio.h>
  1063. # else
  1064. #  include <sgtty.h>
  1065. # endif /* TERMIO */
  1066. #endif /* POSIX */
  1067. X
  1068. #if defined(BSD) || defined(sequent) || defined(pyr)
  1069. # include <strings.h>
  1070. #else /* BSD */
  1071. # ifdef SVR4
  1072. #  define strlen ___strlen___
  1073. #  include <string.h>
  1074. #  undef strlen
  1075. X   extern size_t strlen(const char *);
  1076. # else /* SVR4 */
  1077. #  include <string.h>
  1078. # endif /* SVR4 */
  1079. #endif /* BSD */
  1080. X
  1081. #if (defined(TIOCGWINSZ) || defined(TIOCSWINSZ)) && defined(M_UNIX)
  1082. # include <sys/stream.h>
  1083. # include <sys/ptem.h>
  1084. #endif
  1085. X
  1086. #ifdef SUIDROOT
  1087. #  ifdef LOCKPTY
  1088. #     undef LOCKPTY
  1089. #  endif
  1090. #endif
  1091. X
  1092. #ifndef UTMPOK
  1093. #  ifdef USRLIMIT
  1094. #     undef USRLIMIT
  1095. #  endif
  1096. #endif
  1097. X
  1098. #ifndef LOGINDEFAULT
  1099. #  define LOGINDEFAULT 0
  1100. #endif
  1101. X
  1102. #if defined(LOADAV_3DOUBLES) || defined(LOADAV_3LONGS) ||\
  1103. X    defined(LOADAV_4LONGS) || defined(LOADAV_NEXT)
  1104. #  define LOADAV
  1105. #endif
  1106. X
  1107. #ifndef FSCALE
  1108. # if defined(MIPS) || defined(SVR4)
  1109. #  define FSCALE 256            /* MIPS doesn't, and... */
  1110. # else
  1111. #  ifdef sgi
  1112. #   define FSCALE 1024.0
  1113. #  else
  1114. #   define FSCALE 1000.0     /* Sequent doesn't define FSCALE...grrrr */
  1115. #  endif
  1116. # endif    
  1117. #endif
  1118. X
  1119. #ifndef F_OK
  1120. #define F_OK 0
  1121. #endif
  1122. #ifndef X_OK
  1123. #define X_OK 1
  1124. #endif
  1125. #ifndef W_OK
  1126. #define W_OK 2
  1127. #endif
  1128. #ifndef R_OK
  1129. #define R_OK 4
  1130. #endif
  1131. X
  1132. #ifndef MAXPATH
  1133. # define MAXPATH 1024
  1134. #endif
  1135. X
  1136. #ifndef SIG_T_DEFINED
  1137. # ifdef SIGVOID
  1138. #  if defined(ultrix)
  1139. #   define sig_t void
  1140. #  else /* nice compilers: */
  1141. X    typedef void sig_t;
  1142. #  endif
  1143. # else
  1144. X   typedef int sig_t; /* (* sig_t) */
  1145. # endif
  1146. #endif /* SIG_T_DEFINED */
  1147. X
  1148. #if defined(SVR4) || (defined(SYSV) && defined(ISC))
  1149. # define SIGPROTOARG   (int)
  1150. # define SIGDEFARG     int sigsig
  1151. # define SIGARG        0
  1152. #else
  1153. # define SIGPROTOARG   (void)
  1154. # define SIGDEFARG
  1155. # define SIGARG
  1156. #endif
  1157. X
  1158. #if (!defined(SYSV) && !defined(POSIX) && !defined(apollo)) || defined(sysV68) 
  1159. # ifndef PID_T_DEFINED
  1160. typedef int pid_t;
  1161. # endif /* PID_T_DEFINED */
  1162. #endif
  1163. X
  1164. #if defined(M_XENIX)
  1165. typedef int pid_t;
  1166. typedef int gid_t;
  1167. typedef int uid_t;
  1168. #endif
  1169. X
  1170. #if defined(UTMPOK) && defined(_SEQUENT_)
  1171. # define GETUTENT
  1172. #endif
  1173. X
  1174. #ifdef GETUTENT
  1175. X  typedef char *slot_t;
  1176. #else
  1177. X  typedef int slot_t;
  1178. #endif
  1179. X
  1180. #if !defined(BSD) && !defined(sequent) && !defined(NeXT)
  1181. # define index strchr
  1182. # define rindex strrchr
  1183. #endif
  1184. X
  1185. #ifdef SYSV /* jw. */
  1186. # define bzero(poi,len) memset(poi,0,len)
  1187. # define killpg(pgrp,sig) kill( -(pgrp), sig)
  1188. #endif
  1189. X
  1190. #if defined(_POSIX_SOURCE) && defined(ISC)
  1191. # ifndef O_NDELAY
  1192. #  define O_NDELAY O_NONBLOCK
  1193. # endif
  1194. #endif
  1195. X
  1196. /* here comes my own Free: jw. */
  1197. #define Free(a) {if ((a) == 0) abort(); else free((void *)(a)); (a)=0;}
  1198. X
  1199. #define Ctrl(c) ((c)&037)
  1200. X
  1201. /* modes for markroutine 
  1202. X */
  1203. #define PLAIN 0
  1204. #define TRICKY 1
  1205. #define CRAZY 2 /* should rather be TAXY or MAHEM though... */
  1206. X
  1207. /*typedef long off_t; */    /* Someone might need this */
  1208. X
  1209. enum state_t 
  1210. {
  1211. X  LIT,                /* Literal input */
  1212. X  ESC,                /* Start of escape sequence */
  1213. X  ASTR,                /* Start of control string */
  1214. X  STRESC,            /* ESC seen in control string */
  1215. X  CSI,                /* Reading arguments in "CSI Pn ; Pn ; ... ; XXX" */
  1216. X  PRIN,                /* Printer mode */
  1217. X  PRINESC,            /* ESC seen in printer mode */
  1218. X  PRINCSI,            /* CSI seen in printer mode */
  1219. X  PRIN4            /* CSI 4 seen in printer mode */
  1220. };
  1221. X
  1222. enum string_t 
  1223. {
  1224. X  NONE,
  1225. X  DCS,                /* Device control string */
  1226. X  OSC,                /* Operating system command */
  1227. X  APC,                /* Application program command */
  1228. X  PM,                /* Privacy message */
  1229. X  AKA                /* a.k.a. for current screen */
  1230. };
  1231. X
  1232. #define MAXSTR        256
  1233. #define MAXARGS     64
  1234. #define MSGWAIT     5
  1235. #define MSGMINWAIT     1
  1236. X
  1237. /* 
  1238. X * 4 <= IOSIZE <=1000
  1239. X * you may try to vary this value. Use low values if your (VMS) system
  1240. X * tends to choke when pasting. Use high values if you want to test
  1241. X * how many characters your pty's can buffer.
  1242. X */
  1243. #define IOSIZE        80
  1244. X
  1245. /*
  1246. X * if a nasty user really wants to try a history of 2000 lines on all 10
  1247. X * windows, he will allocate 5 MegaBytes of memory, which is quite enough.
  1248. X */
  1249. #define MAXHISTHEIGHT 3000
  1250. #define DEFAULTHISTHEIGHT 100
  1251. X
  1252. struct win 
  1253. {
  1254. X  int wpid; /* process, that is connected to the other end of ptyfd */
  1255. X  int ptyfd;    /* usually the master side of our pty pair */
  1256. X  int ttyflag;    /* 1 if ptyfd is connected to a user specified tty. */
  1257. X  int aflag;
  1258. X  char outbuf[IOSIZE];
  1259. X  int outlen;
  1260. X  int autoaka, akapos;
  1261. X  char cmd[MAXSTR];
  1262. X  char tty[MAXSTR];
  1263. X  int args[MAXARGS];
  1264. X  int NumArgs;
  1265. X  slot_t slot;
  1266. X  char **image;
  1267. X  char **attr;
  1268. X  char **font;
  1269. X  int LocalCharset;
  1270. X  int charsets[4];
  1271. X  int ss;
  1272. X  int active;
  1273. X  int x, y;
  1274. X  char LocalAttr;
  1275. X  int saved;
  1276. X  int Saved_x, Saved_y;
  1277. X  char SavedLocalAttr;
  1278. X  int SavedLocalCharset;
  1279. X  int SavedCharsets[4];
  1280. X  int top, bot;
  1281. X  int wrap;
  1282. X  int origin;
  1283. X  int insert;
  1284. X  int keypad;
  1285. X  int width, height;    /* width AND height, as we have now resized wins. jw.*/
  1286. X  int histheight;       /* all histbases are malloced with width * histheight */
  1287. X  int histidx;          /* 0= < histidx < histheight; where we insert lines */
  1288. X  char **ihist;     /* the history buffer  image */
  1289. X  char **ahist;     /* attributes */
  1290. X  char **fhist;     /* fonts */
  1291. X  enum state_t state;
  1292. X  enum string_t StringType;
  1293. X  char string[MAXSTR];
  1294. X  char *stringp;
  1295. X  char *tabs;
  1296. X  int vbwait;            
  1297. X  int bell;
  1298. X  int flow;
  1299. X  int WinLink;
  1300. X  FILE *logfp;
  1301. X  int monitor;
  1302. X  int cursor_invisible;
  1303. X  int norefresh;    /* we dont redisplay when switching to that win */
  1304. };
  1305. X
  1306. /*
  1307. X * Definitions for flow
  1308. X *   000  -(-)
  1309. X *   001  +(-)
  1310. X *   010  -(+)
  1311. X *   011  +(+)
  1312. X *   100  -(a)
  1313. X *   111  +(a)
  1314. X */
  1315. #define FLOW_NOW    (1<<0)
  1316. #define FLOW_AUTO    (1<<1)
  1317. #define FLOW_AUTOFLAG    (1<<2)
  1318. X
  1319. /*
  1320. X * Parameters for the Detach() routine
  1321. X */
  1322. #define D_DETACH    0
  1323. #define D_STOP        1
  1324. #define D_REMOTE    2
  1325. #define D_POWER     3
  1326. #define D_REMOTE_POWER    4
  1327. #define D_LOCK        5
  1328. X
  1329. /*
  1330. X * Here are the messages the attacher sends to the backend
  1331. X */
  1332. #define MSG_CREATE    0
  1333. #define MSG_ERROR    1
  1334. #define MSG_ATTACH    2
  1335. #define MSG_CONT    3
  1336. #define MSG_DETACH    4
  1337. #define MSG_POW_DETACH    5
  1338. #define MSG_WINCH    6
  1339. #define MSG_HANGUP    7
  1340. X
  1341. struct msg
  1342. {
  1343. X  int type;
  1344. X  union
  1345. X    {
  1346. X      struct
  1347. X    {
  1348. X      int lflag;
  1349. X      int aflag;
  1350. X      int flowflag;
  1351. X      int hheight;  /* size of scrollback buffer */
  1352. X      int nargs;
  1353. X      char line[MAXPATH];
  1354. X      char dir[MAXPATH];
  1355. X      char screenterm[20]; /* is screen really "screen" ? */
  1356. X    }
  1357. X      create;
  1358. X      struct
  1359. X    {
  1360. X      int apid;
  1361. X      int adaptflag; /* do we wish to adapt window size? */
  1362. X      int lines, columns;
  1363. X      char tty[MAXPATH];
  1364. X      char password[20];
  1365. X      char envterm[MAXPATH];
  1366. X    }
  1367. X      attach;
  1368. X      struct 
  1369. X    {
  1370. X      char password[20];
  1371. X      int dpid;
  1372. X      char tty[MAXPATH];
  1373. X    }
  1374. X      detach;
  1375. X      char message[MAXPATH * 2];
  1376. X    } m;
  1377. };
  1378. X
  1379. /*
  1380. X * And the signals the attacher receives from the backend
  1381. X */
  1382. #define SIG_BYE        SIGHUP
  1383. #define SIG_POWER_BYE    SIGUSR1
  1384. #define SIG_LOCK    SIGUSR2
  1385. #define SIG_STOP    SIGTSTP
  1386. #define SIG_PW_OK    SIGUSR1
  1387. #define SIG_PW_FAIL    SIG_BYE
  1388. X
  1389. X
  1390. struct mode
  1391. {
  1392. #ifdef POSIX
  1393. X  struct termios tio;
  1394. # ifdef hpux
  1395. X  struct ltchars m_ltchars;
  1396. # endif
  1397. #else
  1398. # ifdef TERMIO
  1399. X  struct termio tio;
  1400. # else
  1401. X  struct sgttyb m_ttyb;
  1402. X  struct tchars m_tchars;
  1403. X  struct ltchars m_ltchars;
  1404. X  int m_ldisc;
  1405. X  int m_lmode;
  1406. # endif                /* TERMIO */
  1407. #endif                /* POSIX */
  1408. };
  1409. X
  1410. #define BELL        7
  1411. #define VBELLWAIT    1 /* No. of seconds a vbell will be displayed */
  1412. X
  1413. #define BELL_OFF    0 /* No bell has occurred in the window */
  1414. #define BELL_ON     1 /* A bell has occurred, but user not yet notified */
  1415. #define BELL_DONE    2 /* A bell has occured, user has been notified */
  1416. #define BELL_VISUAL     3 /* A bell has occured in fore win, notify him visually */
  1417. X
  1418. #define MON_OFF     0 /* Monitoring is off in the window */
  1419. #define MON_ON        1 /* No activity has occurred in the window */
  1420. #define MON_FOUND    2 /* Activity has occured, but user not yet notified */
  1421. #define MON_DONE    3 /* Activity has occured, user has been notified */
  1422. X
  1423. #define DUMP_TERMCAP    0 /* WriteFile() options */
  1424. #define DUMP_HARDCOPY    1
  1425. #define DUMP_EXCHANGE    2
  1426. X
  1427. #undef MAXWIN20
  1428. X
  1429. #ifdef MAXWIN20
  1430. #define MAXWIN    20
  1431. #else
  1432. #define MAXWIN    10
  1433. #endif
  1434. X
  1435. /* the key definitions are used in screen.c and help.c */
  1436. /* keep this list synchronus with the names given in fileio.c */
  1437. enum keytype
  1438. {
  1439. X  KEY_IGNORE, /* Keep these first 2 at the start */
  1440. X  KEY_SCREEN,
  1441. X  KEY_0,  KEY_1,  KEY_2,  KEY_3,  KEY_4,
  1442. X  KEY_5,  KEY_6,  KEY_7,  KEY_8,  KEY_9,
  1443. #ifdef MAXWIN20
  1444. X  KEY_10, KEY_11, KEY_12, KEY_13, KEY_14,
  1445. X  KEY_15, KEY_16, KEY_17, KEY_18, KEY_19,
  1446. #endif
  1447. X  KEY_AKA,
  1448. X  KEY_CLEAR,
  1449. X  KEY_COLON,
  1450. X  KEY_COPY,
  1451. X  KEY_DETACH,
  1452. X  KEY_FLOW,
  1453. X  KEY_HARDCOPY,
  1454. X  KEY_HELP,
  1455. X  KEY_HISTNEXT,
  1456. X  KEY_HISTORY,
  1457. X  KEY_INFO,
  1458. X  KEY_KILL,
  1459. X  KEY_LASTMSG,
  1460. X  KEY_LICENSE,
  1461. X  KEY_LOCK,
  1462. X  KEY_LOGTOGGLE,
  1463. X  KEY_LOGIN,
  1464. X  KEY_MONITOR,
  1465. X  KEY_NEXT,
  1466. X  KEY_OTHER,
  1467. X  KEY_PASTE,
  1468. X  KEY_POW_DETACH,
  1469. X  KEY_PREV,
  1470. X  KEY_QUIT,
  1471. X  KEY_READ_BUFFER,
  1472. X  KEY_REDISPLAY,
  1473. X  KEY_REMOVE_BUFFERS,
  1474. X  KEY_RESET,
  1475. X  KEY_SET,
  1476. X  KEY_SHELL,
  1477. X  KEY_SUSPEND,
  1478. X  KEY_TERMCAP,
  1479. X  KEY_TIME,
  1480. X  KEY_VBELL,
  1481. X  KEY_VERSION,
  1482. X  KEY_WIDTH,
  1483. X  KEY_WINDOWS,
  1484. X  KEY_WRAP,
  1485. X  KEY_WRITE_BUFFER,
  1486. X  KEY_XOFF,
  1487. X  KEY_XON,
  1488. X  KEY_EXTEND,
  1489. X  KEY_X_WINDOWS,
  1490. X  KEY_BONUSWINDOW,
  1491. X  KEY_CREATE,
  1492. };
  1493. X
  1494. struct key 
  1495. {
  1496. X  enum keytype type;
  1497. X  char **args;
  1498. };
  1499. X
  1500. #ifdef NETHACK
  1501. #    define Msg_nomem Msg(0, "You feel stupid.")
  1502. #else
  1503. #    define Msg_nomem Msg(0, "Out of memory.")
  1504. #endif
  1505. X
  1506. #ifdef DEBUG
  1507. #    define debug(x) {fprintf(dfp,x);fflush(dfp);}
  1508. #    define debug1(x,a) {fprintf(dfp,x,a);fflush(dfp);}
  1509. #    define debug2(x,a,b) {fprintf(dfp,x,a,b);fflush(dfp);}
  1510. #    define debug3(x,a,b,c) {fprintf(dfp,x,a,b,c);fflush(dfp);}
  1511. X    extern FILE *dfp;
  1512. #else
  1513. #    define debug(x) {}
  1514. #    define debug1(x,a) {}
  1515. #    define debug2(x,a,b) {}
  1516. #    define debug3(x,a,b,c) {}
  1517. #endif
  1518. X
  1519. #if defined(__STDC__)
  1520. # ifndef __P
  1521. #  define __P(a) a
  1522. # endif
  1523. #else
  1524. # ifndef __P
  1525. #  define __P(a) ()
  1526. # endif
  1527. # define const
  1528. #endif
  1529. X
  1530. #ifdef hpux
  1531. # define setreuid(ruid, euid) setresuid(ruid, euid, -1)
  1532. # define setregid(rgid, egid) setresgid(rgid, egid, -1)
  1533. #endif
  1534. X
  1535. #ifdef UTMPOK
  1536. # ifdef SVR4
  1537. #  include <utmpx.h>
  1538. #  define UTMPFILE     UTMPX_FILE
  1539. #  define utmp         utmpx
  1540. #  define getutent     getutxent
  1541. #  define getutid      getutxid
  1542. #  define getutline    getutxline
  1543. #  define pututline    pututxline
  1544. #  define setutent     setutxent
  1545. #  define endutent     endutxent
  1546. # else /* SVR4 */
  1547. #  include <utmp.h>
  1548. # endif /* SVR4 */
  1549. #endif
  1550. X
  1551. #ifndef UTMPFILE
  1552. # ifdef UTMP_FILE
  1553. #  define UTMPFILE     UTMP_FILE
  1554. # else
  1555. #  ifdef BSDI
  1556. #   define UTMPFILE    "/var/run/utmp"
  1557. #  else
  1558. #   define UTMPFILE     "/etc/utmp"
  1559. #  endif /* BSDI */
  1560. # endif
  1561. #endif
  1562. X
  1563. #if !defined(SYSV) || defined(sun) || defined(RENO) || defined(xelos)
  1564. # define BSDWAIT
  1565. #endif
  1566. SHAR_EOF
  1567. chmod 0444 screen3.2/screen.h ||
  1568. echo 'restore of screen3.2/screen.h failed'
  1569. Wc_c="`wc -c < 'screen3.2/screen.h'`"
  1570. test 12454 -eq "$Wc_c" ||
  1571.     echo 'screen3.2/screen.h: original size 12454, current size' "$Wc_c"
  1572. rm -f _shar_wnt_.tmp
  1573. fi
  1574. # ============= screen3.2/socket.c ==============
  1575. if test -f 'screen3.2/socket.c' -a X"$1" != X"-c"; then
  1576.     echo 'x - skipping screen3.2/socket.c (File already exists)'
  1577.     rm -f _shar_wnt_.tmp
  1578. else
  1579. > _shar_wnt_.tmp
  1580. echo 'x - extracting screen3.2/socket.c (Text)'
  1581. sed 's/^X//' << 'SHAR_EOF' > 'screen3.2/socket.c' &&
  1582. /* Copyright (c) 1991
  1583. X *      Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
  1584. X *      Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
  1585. X * Copyright (c) 1987 Oliver Laumann
  1586. X *
  1587. X * This program is free software; you can redistribute it and/or modify
  1588. X * it under the terms of the GNU General Public License as published by
  1589. X * the Free Software Foundation; either version 1, or (at your option)
  1590. X * any later version.
  1591. X *
  1592. X * This program is distributed in the hope that it will be useful,
  1593. X * but WITHOUT ANY WARRANTY; without even the implied warranty of
  1594. X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  1595. X * GNU General Public License for more details.
  1596. X *
  1597. X * You should have received a copy of the GNU General Public License
  1598. X * along with this program (see the file COPYING); if not, write to the
  1599. X * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  1600. X *
  1601. X * Noteworthy contributors to screen's design and implementation:
  1602. X *    Wayne Davison (davison@borland.com)
  1603. X *    Patrick Wolfe (pat@kai.com, kailand!pat)
  1604. X *    Bart Schaefer (schaefer@cse.ogi.edu)
  1605. X *    Nathan Glasser (nathan@brokaw.lcs.mit.edu)
  1606. X *    Larry W. Virden (lwv27%cas.BITNET@CUNYVM.CUNY.Edu)
  1607. X *    Howard Chu (hyc@hanauma.jpl.nasa.gov)
  1608. X *    Tim MacKenzie (tym@dibbler.cs.monash.edu.au)
  1609. X *    Markku Jarvinen (mta@{cc,cs,ee}.tut.fi)
  1610. X *    Marc Boucher (marc@CAM.ORG)
  1611. X *
  1612. X ****************************************************************
  1613. X */
  1614. X
  1615. #ifndef lint
  1616. X  static char rcs_id[] = "$Id: socket.c,v 1.2 92/02/03 02:28:17 jnweiger Exp $ FAU";
  1617. #endif
  1618. X
  1619. #include "config.h"
  1620. #if defined(MIPS) || defined(GOULD_NP1) || defined(B43)
  1621. extern int errno;
  1622. #endif
  1623. #include <sys/types.h>
  1624. #include <sys/stat.h>
  1625. #ifndef sgi
  1626. # include <sys/file.h>
  1627. #endif
  1628. #ifndef NAMEDPIPE
  1629. #include <sys/socket.h>
  1630. #endif
  1631. #include <fcntl.h>
  1632. #ifndef NAMEDPIPE
  1633. #include <sys/un.h>
  1634. #endif
  1635. #include <signal.h>
  1636. #ifndef M_XENIX
  1637. #include <sys/time.h>
  1638. #endif /* M_XENIX */
  1639. #ifdef DIRENT
  1640. # include <sys/param.h>
  1641. # include <dirent.h>
  1642. #else
  1643. # include <sys/dir.h>
  1644. # define dirent direct
  1645. #endif
  1646. X
  1647. #include "screen.h"
  1648. X
  1649. #ifdef USEVARARGS
  1650. # if defined(__STDC__)
  1651. #  include <stdarg.h>
  1652. # else
  1653. #  include <varargs.h>
  1654. # endif
  1655. #endif
  1656. X
  1657. #include "extern.h"
  1658. X
  1659. #if defined(_SEQUENT_) && !defined(NAMEDPIPE)
  1660. # define connect sconnect    /* _SEQUENT_ has braindamaged connect */
  1661. #endif
  1662. X
  1663. extern char *RcFileName, *extra_incap, *extra_outcap;
  1664. extern WinList, Detached, ServerSocket, real_uid, real_gid, eff_uid, eff_gid;
  1665. #ifdef BSDJOBS
  1666. extern int Suspended;
  1667. #endif
  1668. extern AttacherPid, dflag, rflag, lsflag, quietflag, wipeflag;
  1669. extern char HostName[];
  1670. extern struct mode OldMode, NewMode;
  1671. extern char display_tty[];
  1672. extern struct win *wtab[], *fore;
  1673. #ifdef NETHACK
  1674. extern nethackflag;
  1675. #endif
  1676. X
  1677. #ifdef PASSWORD
  1678. extern int CheckPassword;
  1679. extern char Password[];
  1680. #endif
  1681. #if defined(BSDJOBS) && !(defined(POSIX) || defined(SYSV))
  1682. extern DevTty;
  1683. #endif
  1684. extern char *getenv();
  1685. X
  1686. char SockPath[MAXPATH];
  1687. char *SockNamePtr, *SockName;
  1688. X
  1689. char *strdup(str)
  1690. const char *str;
  1691. {
  1692. X  char *ret;
  1693. X
  1694. X  if ((ret = (char *) malloc(strlen(str) + 1)) == 0)
  1695. X    {
  1696. X      Msg_nomem;
  1697. X      return (0);
  1698. X    }
  1699. X  (void) strcpy(ret, str);
  1700. X  return (ret);
  1701. }
  1702. X
  1703. int RecoverSocket()
  1704. {
  1705. X  int s = 0, d;
  1706. X
  1707. X  (void) unlink(SockPath);
  1708. X  s = MakeServerSocket();
  1709. X  if (s != ServerSocket)
  1710. X    {
  1711. X      debug2("Oh, Serversocket was %d, now %d, let's dup!\n", ServerSocket, s);
  1712. X      d = dup2(s, ServerSocket);
  1713. X      close(s);
  1714. X      if (d != ServerSocket)
  1715. X    {
  1716. X      debug2("Hmm, dup2() failed, Serversocket was %d, now %d, bye\n",
  1717. X         ServerSocket, d);
  1718. X      return 0;
  1719. X    }
  1720. X    }
  1721. X  if (Detached)
  1722. X    (void) chmod(SockPath, /* S_IFSOCK | */ 0600); /* Flag detached-ness */
  1723. X  return 1;
  1724. }
  1725. X
  1726. /*
  1727. X * Socket mode 700 means we are Attached. 600 is detached.
  1728. X * We return how many sockets we found. If it was exactly one, we come
  1729. X * back with a SockPath set to it and open it in a fd pointed to by fdp.
  1730. X * If fdp == 0 we simply produce a list if all sockets.
  1731. X */
  1732. int FindSocket(how, fdp)
  1733. int how;
  1734. int *fdp;
  1735. {
  1736. X  register int s, lasts = 0, found = 0, deadcount = 0, wipecount = 0;
  1737. X  register int l;
  1738. X  register DIR *dirp;
  1739. X  register struct dirent *dp;
  1740. X  register char *Name;
  1741. X  struct stat st;
  1742. X  struct foundsock
  1743. X    {
  1744. X      char *name;
  1745. X      int mode;
  1746. X    } foundsock[100];    /* 100 is hopefully enough. */
  1747. X  int foundsockcount = 0;
  1748. X
  1749. X  /* User may or may not give us a (prefix) SockName. We want to search. */
  1750. X  debug("FindSocket:\n");
  1751. X  if (SockName)
  1752. X    {
  1753. X      debug1("We want to match '%s'\n", SockName);
  1754. X      l = strlen(SockName);
  1755. #ifdef NAME_MAX
  1756. X      if (l > NAME_MAX)
  1757. X    l = NAME_MAX;
  1758. #endif
  1759. X    }
  1760. X
  1761. #ifdef NFS_HACK
  1762. X  setreuid(eff_uid, real_uid);
  1763. #endif
  1764. X  debug1("FindSock searching... '%s'\n", SockPath);
  1765. X  /*
  1766. X   * this is a hack: SockName may point to Filename(Sockpath)...
  1767. X   */
  1768. X  found = *SockNamePtr;
  1769. X  *SockNamePtr = '\0';
  1770. X  if ((dirp = opendir(SockPath)) == NULL)
  1771. X    {
  1772. X      Msg(0, "Cannot opendir %s", SockPath);
  1773. X      /* NOTREACHED */
  1774. X    }
  1775. X  *SockNamePtr = found;
  1776. X  found = 0;
  1777. X  while ((dp = readdir(dirp)) != NULL)
  1778. X    {
  1779. X      Name = dp->d_name;
  1780. X      /* 
  1781. X       * there may be a file ".termcap" here. 
  1782. X       * Ignore it just like "." and "..". 
  1783. X       */
  1784. X      if (Name[0] == '.')
  1785. X    continue;
  1786. X      debug2("Attach found: '%s', needed '%s'\n", Name, SockName);
  1787. X      if (SockName && l)
  1788. X    {
  1789. X      register char *n = Name;
  1790. X
  1791. X      /*
  1792. X       * The SockNames "hf", "ttyhf", "1", "12345.tty", "12345.ttyhf.medusa"
  1793. X       * all match the Name "12345.ttyhf.medusa".
  1794. X       */
  1795. X
  1796. X      if ((*SockName <= '0' || *SockName > '9') && (*n > '0' && *n <= '9'))
  1797. X        {
  1798. X          while (*++n)
  1799. X        if (*n == '.')
  1800. X          {
  1801. X            n++;
  1802. X            break;
  1803. X          }
  1804. X          if (strncmp("tty", SockName, 3) && !strncmp("tty", n, 3))
  1805. X        n += 3;
  1806. X        }
  1807. X      if (strncmp(n, SockName, l))
  1808. X        {
  1809. X          debug3("strncmp('%s', '%s', %d)\n", n, SockName, l);
  1810. X          continue;
  1811. X        }
  1812. X    }
  1813. X      /*
  1814. X       * ATTENTION! MakeClientSocket adds SockName to SockPath! 
  1815. X       * Anyway, we need it earlier.
  1816. X       */
  1817. X      strcpy(SockNamePtr, Name);
  1818. X      if (stat(SockPath, &st))
  1819. X    continue;
  1820. X      if (st.st_uid != real_uid)
  1821. X    continue;
  1822. X      foundsock[foundsockcount].name = strdup(Name);
  1823. X      foundsock[foundsockcount].mode = s = st.st_mode & 0777;
  1824. X      debug2("FindSocket: %s has mode %04o...\n", Name, s);
  1825. X      if (s == 0700 || s == 0600)
  1826. X    {
  1827. X      /*
  1828. X       * We try to connect through the socket. If successfull, 
  1829. X       * thats o.k. Otherwise we record that mode as -1.
  1830. X       * MakeClientSocket() must be careful not to block forever.
  1831. X       */
  1832. X      if ((s = MakeClientSocket(0, Name)) == -1)
  1833. X        { 
  1834. X          foundsock[foundsockcount].mode = -1;
  1835. X          deadcount++;
  1836. X        }
  1837. X      else
  1838. X        close(s);
  1839. X    }
  1840. X      if (++foundsockcount >= 100)
  1841. X    break;
  1842. X    }
  1843. X  closedir(dirp);
  1844. #ifdef NFS_HACK
  1845. X  setreuid(real_uid, eff_uid);
  1846. #endif
  1847. X
  1848. X  if (wipeflag)
  1849. X    {
  1850. X      for (s = 0; s < foundsockcount; s++)
  1851. X    {
  1852. X      if (foundsock[s].mode == -1)
  1853. X        {
  1854. X              strcpy(SockNamePtr, foundsock[s].name);
  1855. X          debug1("wiping '%d'\n", SockPath);
  1856. X          if (unlink(SockPath) == 0)
  1857. X            {
  1858. X          foundsock[s].mode = -2;
  1859. X              wipecount++;
  1860. X        }
  1861. X        }
  1862. X    }
  1863. X    }
  1864. X  for (s = 0; s < foundsockcount; s++)
  1865. X    if ((foundsock[s].mode) == (dflag ? 0700 : 0600)) 
  1866. X      {
  1867. X    found++;
  1868. X    lasts = s;
  1869. X      }
  1870. X  if (quietflag && (lsflag || (found != 1 && rflag != 2)))
  1871. X    eexit(10 + found);
  1872. X  debug2("attach: found=%d, foundsockcount=%d\n", found, foundsockcount);
  1873. X  if (found == 1 && lsflag == 0)
  1874. X    {
  1875. X      if ((lasts = MakeClientSocket(0, SockName = foundsock[lasts].name)) == -1)
  1876. X        found = 0;
  1877. X    }
  1878. X  else if (!quietflag && foundsockcount > 0)
  1879. X    {
  1880. X      switch (found)
  1881. X        {
  1882. X        case 0:
  1883. X          if (lsflag)
  1884. X        {
  1885. #ifdef NETHACK
  1886. X              if (nethackflag)
  1887. X            printf("Your inventory:\n");
  1888. X          else
  1889. #endif
  1890. X          printf((foundsockcount > 1) ?
  1891. X                 "There are screens on:\n" : "There is a screen on:\n");
  1892. X        }
  1893. X          else
  1894. X        {
  1895. #ifdef NETHACK
  1896. X              if (nethackflag)
  1897. X            printf("Nothing fitting exists in the game:\n");
  1898. X          else
  1899. #endif
  1900. X          printf((foundsockcount > 1) ?
  1901. X                 "There are screens on:\n" : "There is a screen on:\n");
  1902. X        }
  1903. X          break;
  1904. X        case 1:
  1905. #ifdef NETHACK
  1906. X          if (nethackflag)
  1907. X            printf((foundsockcount > 1) ?
  1908. X                   "Prove thyself worthy or perish:\n" : 
  1909. X                   "You see here a good looking screen:\n");
  1910. X          else
  1911. #endif
  1912. X          printf((foundsockcount > 1) ? 
  1913. X                 "There are several screens on:\n" :
  1914. X                 "There is a possible screen on:\n");
  1915. X          break;
  1916. X        default:
  1917. #ifdef NETHACK
  1918. X          if (nethackflag)
  1919. X            printf((foundsockcount > 1) ? 
  1920. X                   "You may whish for a screen, what do you want?\n" : 
  1921. X                   "You see here a screen:\n");
  1922. X          else
  1923. #endif
  1924. X          printf((foundsockcount > 1) ?
  1925. X                 "There are several screens on:\n" : "There is a screen on:\n");
  1926. X          break;
  1927. X        }
  1928. X      for (s = 0; s < foundsockcount; s++)
  1929. X    {
  1930. X      switch (foundsock[s].mode)
  1931. X        {
  1932. X        case 0700:
  1933. X          printf("\t%s\t(Attached)\n", foundsock[s].name);
  1934. X          break;
  1935. X        case 0600:
  1936. X          printf("\t%s\t(Detached)\n", foundsock[s].name);
  1937. X          break;
  1938. X        case -1:
  1939. #if defined(__STDC__) || defined(_AIX)
  1940. X          printf("\t%s\t(Dead ??\?)\n", foundsock[s].name);
  1941. #else
  1942. X          printf("\t%s\t(Dead ???)\n", foundsock[s].name);
  1943. #endif
  1944. X          break;
  1945. X        case -2:
  1946. X          printf("\t%s\t(Removed)\n", foundsock[s].name);
  1947. X          break;
  1948. X        default:
  1949. X          printf("\t%s\t(Wrong mode)\n", foundsock[s].name);
  1950. X          break;
  1951. X        }
  1952. X    }
  1953. X    }
  1954. X  if (deadcount && !quietflag)
  1955. X    {
  1956. X      if (wipeflag)
  1957. X        {
  1958. #ifdef NETHACK
  1959. X          if (nethackflag)
  1960. X            printf("You hear%s distant explosion%s.\n",
  1961. X           (deadcount > 1) ? "" : " a", (deadcount > 1) ? "s" : "");
  1962. X          else
  1963. #endif
  1964. X          printf("%d Socket%s wiped out.\n", deadcount, (deadcount > 1)?"s":"");
  1965. X    }
  1966. X      else
  1967. X    {
  1968. #ifdef NETHACK
  1969. X          if (nethackflag)
  1970. X            printf("The dead screen%s touch%s you. Try 'screen -wipe'.\n",
  1971. X           (deadcount > 1) ? "s" : "", (deadcount > 1) ? "" : "es");
  1972. X          else
  1973. #endif
  1974. X          printf("Remove dead Sockets with 'screen -wipe'.\n");
  1975. X    }
  1976. X    }
  1977. X
  1978. X  for (s = 0; s < foundsockcount; s++)
  1979. X    Free(foundsock[s].name);
  1980. X  if (found == 1 && fdp)
  1981. X    *fdp = lasts;
  1982. X  if (fdp)
  1983. X    return found;
  1984. X  return foundsockcount - wipecount;
  1985. }
  1986. X
  1987. #ifdef NAMEDPIPE
  1988. X
  1989. int
  1990. MakeServerSocket()
  1991. {
  1992. X  register int s;
  1993. X  struct stat st;
  1994. X
  1995. X  strcpy(SockNamePtr, SockName);
  1996. #ifdef NAME_MAX
  1997. X  if (strlen(SockNamePtr) > NAME_MAX)
  1998. X    {
  1999. X      debug2("MakeClientSocket: '%s' truncated to %d chars\n",
  2000. X         SockNamePtr, NAME_MAX);
  2001. X      SockNamePtr[NAME_MAX] = '\0';
  2002. X    }
  2003. #endif
  2004. X
  2005. X  if ((s = open(SockPath, O_WRONLY | O_NDELAY)) >= 0)
  2006. X    {
  2007. X      debug("huii, my fifo already exists??\n");
  2008. X      if (quietflag)
  2009. X    {
  2010. X      Kill(AttacherPid, SIG_BYE);
  2011. X      eexit(11);
  2012. X    }
  2013. X      printf("There is already a screen running on %s.\n",
  2014. X         Filename(SockPath));
  2015. X      if (stat(SockPath, &st) == -1)
  2016. X    Msg(errno, "stat");
  2017. X      if (st.st_uid != real_uid)
  2018. X    Msg(0, "Unfortunatelly you are not its owner.");
  2019. X      if ((st.st_mode & 0700) == 0600)
  2020. X    Msg(0, "To resume it, use \"screen -r\"");
  2021. X      else
  2022. X    Msg(0, "It is not detached.");
  2023. X      /* NOTREACHED */
  2024. X    }
  2025. X  (void) unlink(SockPath);
  2026. X  if (UserContext() > 0)
  2027. X    {
  2028. #if defined(_POSIX_SOURCE) && defined(ISC)
  2029. X      if (mknod(SockPath, 0010700, 0))
  2030. #else
  2031. X      if (mknod(SockPath, S_IFIFO | S_IEXEC | S_IWRITE | S_IREAD, 0))
  2032. #endif
  2033. X    UserReturn(0);
  2034. X      UserReturn(1);
  2035. X    }
  2036. X  if (UserStatus() <= 0)
  2037. X    Msg(0, "mknod fifo %s failed", SockPath);
  2038. X  /*
  2039. X   * MUST be RDWR because otherwise we will get EOF's if
  2040. X   * nobody has opened the pipe for writing
  2041. X   */
  2042. X  if ((s = secopen(SockPath, O_RDWR | O_NDELAY, 0)) < 0)
  2043. X    Msg(errno, "open fifo %s", SockPath);
  2044. X  return s;
  2045. }
  2046. X
  2047. X
  2048. int
  2049. MakeClientSocket(err, name)
  2050. int err;
  2051. char *name;
  2052. {
  2053. X  register int s = 0;
  2054. X
  2055. X  strcpy(SockNamePtr, name);
  2056. #ifdef NAME_MAX
  2057. X  if (strlen(SockNamePtr) > NAME_MAX)
  2058. X    {
  2059. X      debug2("MakeClientSocket: '%s' truncated to %d chars\n",
  2060. X         SockNamePtr, NAME_MAX);
  2061. X      SockNamePtr[NAME_MAX] = '\0';
  2062. X    }
  2063. #endif
  2064. X  
  2065. X  if ((s = secopen(SockPath, O_WRONLY | O_NDELAY, 0)) >= 0)
  2066. X    {
  2067. X      (void) fcntl(s, F_SETFL, 0);
  2068. X      return s;
  2069. X    }
  2070. X  if (err)
  2071. X    {
  2072. X      Msg(errno, "open: %s (but continuing...)", SockPath);
  2073. X      debug1("MakeClientSocket() open %s failed\n", SockPath);
  2074. X    }
  2075. X  else
  2076. X    {
  2077. X      debug1("MakeClientSocket() open %s failed\n", SockPath);
  2078. X    }
  2079. X  return -1;
  2080. }
  2081. X
  2082. #else    /* NAMEDPIPE */
  2083. X
  2084. int
  2085. MakeServerSocket()
  2086. {
  2087. X  register int s;
  2088. X  struct sockaddr_un a;
  2089. X  struct stat st;
  2090. X
  2091. X  if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
  2092. X    Msg(errno, "socket");
  2093. X  a.sun_family = AF_UNIX;
  2094. X  strcpy(SockNamePtr, SockName);
  2095. #ifdef NAME_MAX
  2096. X  if (strlen(SockNamePtr) > NAME_MAX)
  2097. X    {
  2098. X      debug2("MakeServerSocket: '%s' truncated to %d chars\n",
  2099. X         SockNamePtr, NAME_MAX);
  2100. X      SockNamePtr[NAME_MAX] = '\0';
  2101. X    }
  2102. #endif
  2103. X
  2104. X  strcpy(a.sun_path, SockPath);
  2105. X  if (connect(s, (struct sockaddr *) & a, strlen(SockPath) + 2) != -1)
  2106. X    {
  2107. X      debug("oooooh! socket already is alive!\n");
  2108. X      if (quietflag)
  2109. X    { 
  2110. X      Kill(AttacherPid, SIG_BYE);
  2111. X      /* 
  2112. X       * oh, well. nobody receives that return code. papa 
  2113. X       * dies by signal.
  2114. X       */
  2115. X      eexit(11);
  2116. X    }
  2117. X      printf("There is already a screen running on %s.\n",
  2118. X         Filename(SockPath));
  2119. X      if (stat(SockPath, &st) == -1)
  2120. X    Msg(errno, "stat");
  2121. X      if (st.st_uid != real_uid)
  2122. X    Msg(0, "Unfortunatelly you are not its owner.");
  2123. X      if ((st.st_mode & 0700) == 0600)
  2124. X    Msg(0, "To resume it, use \"screen -r\"");
  2125. X      else
  2126. X    Msg(0, "It is not detached.");
  2127. X      /* NOTREACHED */
  2128. X    }
  2129. X  (void) unlink(SockPath);
  2130. #ifndef NOREUID
  2131. X  setreuid(eff_uid, real_uid);
  2132. X  setregid(eff_gid, real_gid);
  2133. #endif
  2134. X  if (bind(s, (struct sockaddr *) & a, strlen(SockPath) + 2) == -1)
  2135. X    Msg(errno, "bind");
  2136. X  (void) chmod(SockPath, /* S_IFSOCK | */ 0700);
  2137. #ifdef NOREUID
  2138. X  chown(SockPath, real_uid, real_gid);
  2139. #else
  2140. X  setreuid(real_uid, eff_uid);
  2141. X  setregid(real_gid, eff_gid);
  2142. #endif
  2143. X  if (listen(s, 5) == -1)
  2144. X    Msg(errno, "listen");
  2145. #ifdef F_SETOWN
  2146. X  fcntl(s, F_SETOWN, getpid());
  2147. X  debug1("Serversocket owned by %d\n", fcntl(s, F_GETOWN, 0));
  2148. #endif /* F_SETOWN */
  2149. X  return s;
  2150. }
  2151. X
  2152. int
  2153. MakeClientSocket(err, name)
  2154. int err;
  2155. char *name;
  2156. {
  2157. X  register int s;
  2158. X  struct sockaddr_un a;
  2159. X
  2160. X  if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
  2161. X    Msg(errno, "socket");
  2162. X  a.sun_family = AF_UNIX;
  2163. X  strcpy(SockNamePtr, name);
  2164. #ifdef NAME_MAX
  2165. X  if (strlen(SockNamePtr) > NAME_MAX)
  2166. X    {
  2167. X      debug2("MakeClientSocket: '%s' truncated to %d chars\n",
  2168. X         SockNamePtr, NAME_MAX);
  2169. X      SockNamePtr[NAME_MAX] = '\0';
  2170. X    }
  2171. #endif
  2172. X
  2173. X  strcpy(a.sun_path, SockPath);
  2174. #ifndef NOREUID
  2175. X  setreuid(eff_uid, real_uid);
  2176. X  setregid(eff_gid, real_gid);
  2177. #else
  2178. X  if (access(SockPath, W_OK))
  2179. X    {
  2180. X      if (err)
  2181. X    Msg(errno, "%s", SockPath);
  2182. X      else
  2183. X    debug2("MakeClientSocket: access(%s): %d.\n", SockPath, errno);
  2184. X      close(s);
  2185. X      return -1;
  2186. X    }
  2187. #endif
  2188. X  if (connect(s, (struct sockaddr *) & a, strlen(SockPath) + 2) == -1)
  2189. X    {
  2190. X      if (err)
  2191. X    Msg(errno, "%s: connect", SockPath);
  2192. X      else
  2193. X    debug("MakeClientSocket: connect failed.\n");
  2194. X      close(s);
  2195. X      s = -1;
  2196. X    }
  2197. #ifndef NOREUID
  2198. X  setreuid(real_uid, eff_uid);
  2199. X  setregid(real_gid, eff_gid);
  2200. #endif
  2201. X  return s;
  2202. }
  2203. #endif
  2204. X
  2205. X
  2206. void
  2207. SendCreateMsg(s, ac, av, aflag, flowflag, lflag, histheight, sterm)
  2208. int s, ac, aflag, flowflag, lflag, histheight;
  2209. char **av;
  2210. char *sterm;
  2211. {
  2212. X  struct msg m;
  2213. X  register char *p;
  2214. X  register int len, n;
  2215. X
  2216. X  debug1("SendCreateMsg() to '%s'\n", SockPath);
  2217. X  m.type = MSG_CREATE;
  2218. X  p = m.m.create.line;
  2219. X  for (n = 0; ac > 0 && n < MAXARGS - 1; ++av, --ac, ++n)
  2220. X    {
  2221. X      len = strlen(*av) + 1;
  2222. X      if (p + len >= m.m.create.line + MAXPATH - 1)
  2223. X    break;
  2224. X      strcpy(p, *av);
  2225. X      p += len;
  2226. X    }
  2227. X  if (!ac && *av && p + strlen(*av) + 1 < m.m.create.line + MAXPATH)
  2228. X    strcpy(p, *av);
  2229. X  else
  2230. X    *p = '\0';
  2231. X  m.m.create.nargs = n;
  2232. X  m.m.create.aflag = aflag;
  2233. X  m.m.create.flowflag = flowflag;
  2234. X  m.m.create.lflag = lflag;
  2235. X  m.m.create.hheight = histheight;
  2236. #ifdef SYSV
  2237. X  if (getcwd(m.m.create.dir, sizeof(m.m.create.dir)) == 0)
  2238. #else
  2239. X    if (getwd(m.m.create.dir) == 0)
  2240. #endif
  2241. X      Msg(0, "%s", m.m.create.dir);
  2242. X  strncpy(m.m.create.screenterm, sterm, 19);
  2243. X  m.m.create.screenterm[19] = '\0';
  2244. X  debug1("SendCreateMsg writing '%s'\n", m.m.create.line);
  2245. X  if (write(s, (char *) &m, sizeof m) != sizeof m)
  2246. X    Msg(errno, "write");
  2247. }
  2248. X
  2249. void
  2250. #ifdef USEVARARGS
  2251. /*VARARGS1*/
  2252. # if defined(__STDC__)
  2253. SendErrorMsg(char *fmt, ...)
  2254. # else
  2255. SendErrorMsg(fmt, va_alist)
  2256. char *fmt;
  2257. va_dcl
  2258. #endif
  2259. { /* } */
  2260. X  static va_list ap = 0;
  2261. #else
  2262. /*VARARGS1*/
  2263. SendErrorMsg(fmt, p1, p2, p3, p4, p5, p6)
  2264. char *fmt;
  2265. unsigned long p1, p2, p3, p4, p5, p6;
  2266. {
  2267. #endif
  2268. X  register int s;
  2269. X  struct msg m;
  2270. X
  2271. X  s = MakeClientSocket(1, SockName);
  2272. X  debug1("SendErrorMsg() to '%s'\n", SockPath);
  2273. X  m.type = MSG_ERROR;
  2274. #ifdef USEVARARGS
  2275. # if defined(__STDC__)
  2276. X  va_start(ap, fmt);
  2277. # else
  2278. X  va_start(ap);
  2279. # endif
  2280. X  (void) vsprintf(m.m.message, fmt, ap);
  2281. X  va_end(ap);
  2282. #else
  2283. X  sprintf(m.m.message, fmt, p1, p2, p3, p4, p5, p6);
  2284. #endif
  2285. X  debug1("SendErrorMsg writing '%s'\n", m.m.message);
  2286. X  (void) write(s, (char *) &m, sizeof m);
  2287. X  close(s);
  2288. X  sleep(2);
  2289. }
  2290. X
  2291. #ifdef PASSWORD
  2292. static int CheckPasswd(pwd, pid, tty)
  2293. int pid;
  2294. char *pwd, *tty;
  2295. {
  2296. X  if (CheckPassword && 
  2297. X      strcmp(crypt(pwd, (strlen(Password) > 1) ? Password : "JW"),
  2298. X         Password))
  2299. X    {
  2300. X      if (*pwd)
  2301. X    {
  2302. #ifdef NETHACK
  2303. X          if (nethackflag)
  2304. X        Msg(0, "'%s' tries to explode in the sky, but fails. (%s)", tty, pwd);
  2305. X          else
  2306. #endif
  2307. X      Msg(0, "Illegal reattach attempt from terminal %s, \"%s\"", tty, pwd);
  2308. X    }
  2309. X      debug1("CheckPass() wrong password kill(%d, SIG_PW_FAIL)\n", pid);
  2310. X      Kill(pid, SIG_PW_FAIL);
  2311. X      return 0;
  2312. X    }
  2313. X  debug1("CheckPass() from %d happy\n", pid);
  2314. X  Kill(pid, SIG_PW_OK);
  2315. X  return 1;
  2316. }
  2317. #endif    /* PASSWORD */
  2318. X
  2319. static void ExecCreate(mp)
  2320. struct msg *mp;
  2321. {
  2322. X  char *args[MAXARGS];
  2323. X  register int n;
  2324. X  register char **pp = args, *p = mp->m.create.line;
  2325. X
  2326. X  for (n = mp->m.create.nargs; n > 0; --n)
  2327. X    {
  2328. X      *pp++ = p;
  2329. X      p += strlen(p) + 1;
  2330. X    }
  2331. X  *pp = 0;
  2332. X  if (!*p)
  2333. X    p = 0;
  2334. X  MakeWindow(p, args, mp->m.create.aflag, mp->m.create.flowflag,
  2335. X              0, mp->m.create.dir, mp->m.create.lflag,
  2336. X              mp->m.create.hheight, mp->m.create.screenterm);
  2337. }
  2338. X
  2339. static int
  2340. CheckPid(pid)
  2341. int pid;
  2342. {
  2343. X  if (pid < 2)
  2344. X    return(-1);
  2345. X  if (eff_uid == real_uid)
  2346. X    return kill(pid, 0);
  2347. X  if (UserContext() == 1)
  2348. X    {
  2349. X      UserReturn(kill(pid, 0));
  2350. X    }
  2351. X  return UserStatus();
  2352. }
  2353. X
  2354. void
  2355. ReceiveMsg(s)
  2356. int s;
  2357. {
  2358. X  int left, len, i;
  2359. X  static struct msg m;
  2360. X  char *p;
  2361. X  static char lbuf[20], cbuf[20]; /* static for later putenv()'s */
  2362. #ifdef NAMEDPIPE
  2363. X  /*
  2364. X   * we may be called if there are no pending messages, so we will have to
  2365. X   * block on first read.
  2366. X   */
  2367. X  debug("Ha, there was someone knocking on my fifo??\n");
  2368. X  if (fcntl(s, F_SETFL, 0) == -1)
  2369. X    {
  2370. X      Msg(errno, "fcntl no O_NDELAY");
  2371. X      exit(1);
  2372. X    }
  2373. X  p = (char *) &m;
  2374. X  left = sizeof(m);
  2375. X  while (left > 0 && (len = read(s, p, left)) > 0)
  2376. X    {
  2377. X      /*        if (p == (char *)&m)
  2378. X       *        {    if (fcntl(s, F_SETFL, O_NDELAY) == -1)
  2379. X       *            {    Msg(errno, "fcntl O_NDELAY !");
  2380. X       *                return;
  2381. X       *            }
  2382. X       *        }
  2383. X       */
  2384. X      p += len;
  2385. X      left -= len;
  2386. X    }
  2387. # ifdef DEBUG
  2388. X  if (len == 0)
  2389. X    debug("ReceiveMsg: Yucc! Got an EOF !!\n");
  2390. # endif
  2391. #else
  2392. X  register int ns;
  2393. X  struct sockaddr_un a;
  2394. X
  2395. X  len = sizeof(struct sockaddr_un);
  2396. X  debug("Ha, there was someone knocking on my socket??\n");
  2397. X  if ((ns = accept(s, (struct sockaddr *) & a, &len)) == -1)
  2398. X    {
  2399. X      Msg(errno, "accept");
  2400. X      return;
  2401. X    }
  2402. X  p = (char *) &m;
  2403. X  left = sizeof m;
  2404. X  while (left > 0 && (len = read(ns, p, left)) > 0)
  2405. X    {
  2406. X      p += len;
  2407. X      left -= len;
  2408. SHAR_EOF
  2409. true || echo 'restore of screen3.2/socket.c failed'
  2410. fi
  2411. echo 'End of  part 7'
  2412. echo 'File screen3.2/socket.c is continued in part 8'
  2413. echo 8 > _shar_seq_.tmp
  2414. exit 0
  2415. exit 0 # Just in case...
  2416.