home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / mac / unix / uw_shar.sit / uw-42-part3.shar < prev    next >
Text File  |  1989-09-14  |  61KB  |  2,061 lines

  1. #Date: Wed, 2 Mar 88 10:00:46 PST
  2. #From: rothberg@polya.stanford.edu (Edward Rothberg)
  3. #Subject: UW 4.2 part 3 of 8
  4. : This is a shar archive.  Extract with sh, not csh.
  5. if test ! -d doc; then
  6.     echo mkdir doc
  7.     mkdir doc
  8. fi
  9. if test ! -d h; then
  10.     echo mkdir h
  11.     mkdir h
  12. fi
  13. if test ! -d server; then
  14.     echo mkdir server
  15.     mkdir server
  16. fi
  17. echo x - doc/uwterm.l
  18. sed -e 's/^X//' > doc/uwterm.l << '!EOF!doc/uwterm.l!'
  19. X.TH UWTERM 1 "20 September 1986"
  20. X.UC 4
  21. X.SH NAME
  22. Xuwterm \- (possibly remote) terminal emulation for UW
  23. X.SH SYNOPSIS
  24. X.B uwterm
  25. X[
  26. X.BI \-w type
  27. X] [
  28. X.BI \-t title
  29. X] [
  30. X.BI \-n serveraddr
  31. X] [
  32. X.BI \-l loginname
  33. X] [ host ]
  34. X.SH DESCRIPTION
  35. X.I Uwterm
  36. Xis a utility program for use with the
  37. X.I uw
  38. Xmultiple-window interface to UNIX.
  39. XIt creates a window in which a terminal session
  40. Xis conducted.
  41. XIf no arguments are given
  42. Xthe terminal is created on the local machine.
  43. XA hostname may be specified;
  44. Xin this case,
  45. Xthe terminal is created on the remote host.
  46. X.RI ( Uwterm
  47. Xmust be installed on the remote host
  48. Xand permissions for
  49. X.I rsh
  50. Xmust have been set up correctly
  51. Xin order for this to work.)
  52. X.I Uwterm
  53. Xexamines the `SHELL' environment variable
  54. Xand executes the program named there.
  55. XThe `\-l' option
  56. Xcan be used to specify the login name under which
  57. Xthe remote process will be executed
  58. X(the default is the current account).
  59. X.PP
  60. XUnlike
  61. X.IR uwtool ,
  62. X.I uwterm
  63. Xdoes not exit until the window it has created
  64. Xis destroyed;
  65. Xhence,
  66. Xit will usually be desirable to run it in the background.
  67. X.PP
  68. XNormally,
  69. Xthe terminal type of the new window is inherited from
  70. Xthe window in which
  71. X.I uwterm
  72. Xis run.
  73. XIt is possible to override this with the `\-w' option
  74. X(`w' stands for `window emulation type').
  75. XThe window types are the same as those accepted by the
  76. X.I uwtool
  77. Xprogram.
  78. X.PP
  79. XThe title of the newly-created window may be
  80. Xspecified with the `\-t' option.
  81. XIf this option is omitted,
  82. Xthe title will be the host name.
  83. X.PP
  84. XNormally
  85. X.I uwterm
  86. Xwill examine the environment for the variable `UW_INET'
  87. Xand will connect to the
  88. X.I uw
  89. Xserver with that address.
  90. XThe `\-n' flag can be used to specify an alternate
  91. Xserver network address.
  92. XThe address should have the form `xxxxxxxx.ddd'
  93. Xwhere `x' is a hexadecimal digit
  94. Xand `d' is a decimal digit.
  95. XThe hexadecimal number is the host's Internet address
  96. Xand the decimal number is the port on which the
  97. Xserver is listening for connections.
  98. XThe `\-n' flag is used by
  99. X.I uwterm
  100. Xitself:
  101. Xit creates a remote terminal by invoking itself on
  102. Xthe remote machine
  103. X(using
  104. X.IR rsh )
  105. Xand specifying the network address
  106. Xof the local server.
  107. X.SH LIMITATIONS
  108. X.I Uwterm 
  109. Xis of no use on unix unless 
  110. Xthe server is running and
  111. X.I uw
  112. Xis being run on the Macintosh.
  113. X.br
  114. XIf there is a stream of output in one window there will be lag in 
  115. Xrecognizing characters typed in another.
  116. X.br
  117. XThere are so many levels of buffering
  118. Xthat user-entered CTL-S/CTL-Q flow control is
  119. Xpractically useless,
  120. Xeven at relatively low baud rates.
  121. X.SH SEE ALSO
  122. Xrsh(1), uw(L), uwtitle(L), uwtool(L)
  123. X.br
  124. X.I uw
  125. XMacintosh documentation
  126. X(`UW \(em A Multiple-Window Interface to UNIX')
  127. X.br
  128. X`The UW Programmer's Library'
  129. X.SH AUTHOR
  130. XJohn Bruner, Lawrence Livermore National Laboratory, 9/86.
  131. X.SH BUGS
  132. XThere are so many levels of buffering that typing
  133. XXON and XOFF
  134. Xto suspend output within a window
  135. Xis futile.
  136. !EOF!doc/uwterm.l!
  137. echo x - doc/uwtitle.l
  138. sed -e 's/^X//' > doc/uwtitle.l << '!EOF!doc/uwtitle.l!'
  139. X.TH UWTITLE 1 "14 September 1986"
  140. X.UC 4
  141. X.SH NAME
  142. Xuwtitle \- retitle UW window
  143. X.SH SYNOPSIS
  144. X.B uwtitle
  145. X[
  146. X.BI \-i id
  147. X]
  148. Xstring ...
  149. X.SH DESCRIPTION
  150. X.I Uwtitle
  151. Xis a utility program for use with the
  152. X.I uw
  153. Xmultiple-window interface to UNIX.
  154. XIt retitles an existing window.
  155. XThe title is specified as one or more
  156. Xstrings
  157. X(in the same fashion as arguments to the
  158. X.I echo
  159. Xprogram).
  160. XThe `\-i' option can be used to specify
  161. Xthe ID of the window to be retitled;
  162. Xotherwise,
  163. Xthe current window will be affected.
  164. X.SH LIMITATIONS
  165. X.I Uwtitle 
  166. Xis of no use on unix unless 
  167. Xthe server is running and
  168. X.I uw
  169. Xis being run on the Macintosh.
  170. X.SH SEE ALSO
  171. Xecho(1), uw(L), uwtool(L), uwterm(L)
  172. X.br
  173. X.I uw
  174. XMacintosh documentation (`UW \(em A Multiple-Window Interface to UNIX')
  175. X.br
  176. X`The UW Programmer's Library'
  177. X.SH AUTHOR
  178. XJohn Bruner, Lawrence Livermore National Laboratory 9/86
  179. !EOF!doc/uwtitle.l!
  180. echo x - doc/uwtool.l
  181. sed -e 's/^X//' > doc/uwtool.l << '!EOF!doc/uwtool.l!'
  182. X.TH UWTOOL 1 "14 September 1986"
  183. X.UC 4
  184. X.SH NAME
  185. Xuwtool \- command-in-window utility for UW
  186. X.SH SYNOPSIS
  187. X.B uwtool
  188. X[
  189. X.BI \-w type
  190. X] [
  191. X.BI \-t title
  192. X] [
  193. X.B \-v
  194. X] [ command [ arg1 arg2 ...  ] ]
  195. X.SH DESCRIPTION
  196. X.I Uwtool
  197. Xis a utility program for use with the
  198. X.I uw
  199. Xmultiple-window interface to UNIX.
  200. XIf no arguments are given,
  201. Xit creates a new `terminal' running the shell named in the
  202. Xenvironment variable `SHELL'.
  203. XIf a process is named,
  204. Xit will create a new window with that process running in it,
  205. Xand when that process is terminated the window will disappear.
  206. X(i.e. `uwtool vi foo' will create a new window with vi,
  207. Xediting the file foo,
  208. Xbut the window will go away when vi is exited)  
  209. XAny arguments after the process name are passed as arguments to that process.
  210. X.I Uwtool
  211. Xexits as soon as the window is created.
  212. X.PP
  213. XNormally,
  214. Xthe terminal type of the new window is inherited from
  215. Xthe window in which
  216. X.I uwtool
  217. Xis run.
  218. XIt is possible to override this with the `\-w' option
  219. X(`w' stands for `window emulation type').
  220. XThe following values are recognized:
  221. X.TP 8n
  222. Xadm31
  223. XLear Siegler ADM-31
  224. X.TP
  225. Xadm3a
  226. XLear Siegler ADM-3a (uses ADM-31)
  227. X.TP
  228. Xtek4010
  229. XTektronix 4010
  230. X.TP
  231. Xtek
  232. XTektronix 4010
  233. X.TP
  234. Xvt52
  235. XDigital Equipment Corporation VT-52
  236. X.TP
  237. Xansi
  238. XANSI-compatible terminal
  239. X.TP
  240. Xaaa-24
  241. X24-line Ann Arbor Ambassador
  242. X(uses ANSI emulation)
  243. X.PP
  244. XIf an unknown type is specified,
  245. Xthe ADM-31 emulation will be used.
  246. X.PP
  247. XThe title of the newly-created window may be
  248. Xspecified with the `\-t' option.
  249. XIf this option is omitted,
  250. Xthe window title will be the command name.
  251. X.PP
  252. XThe `\-v' flag causes
  253. X.I uwtool
  254. Xto print the 32-bit window identifier on
  255. Xthe standard output.
  256. XThis value can be used as an argument to a subsequent
  257. Xcommand,
  258. Xfor example
  259. X.IR uwtitle .
  260. X.SH LIMITATIONS
  261. X.I Uwtool 
  262. Xis of no use on unix unless 
  263. Xthe server is running and
  264. X.I uw
  265. Xis being run on the Macintosh.
  266. X.br
  267. XIf there is a stream of output in one window there will be lag in 
  268. Xrecognizing characters typed in another.
  269. X.SH SEE ALSO
  270. Xuw(L), uwtitle(L), uwterm(L)
  271. X.br
  272. X.I uw
  273. XMacintosh documentation
  274. X(`UW \(em A Multiple-Window Interface to UNIX')
  275. X.br
  276. X`The UW Programmer's Library'
  277. X.SH AUTHOR
  278. XProgram written by John Bruner, Lawrence Livermore Laboratories 7/85,11/85,9/86
  279. X.br
  280. XThis document is based upon a document created by
  281. Xby Chris Borton, UC San Diego 11/13/85,
  282. Xedited 9/86 by John Bruner.
  283. !EOF!doc/uwtool.l!
  284. echo x - h/openpty.h
  285. sed -e 's/^X//' > h/openpty.h << '!EOF!h/openpty.h!'
  286. X/*
  287. X *    This file defines the "ptydesc" structure which is returned
  288. X *    by the routine "openpty".
  289. X */
  290. X
  291. Xstruct ptydesc {
  292. X    int        pt_pfd;        /* file descriptor of master side */
  293. X    int        pt_tfd;        /* file descriptor of slave side */
  294. X    char        *pt_pname;    /* master device name */
  295. X    char        *pt_tname;    /* slave device name */
  296. X};
  297. !EOF!h/openpty.h!
  298. echo x - h/uw_clk.h
  299. sed -e 's/^X//' > h/uw_clk.h << '!EOF!h/uw_clk.h!'
  300. X/*
  301. X *    uw_clk - timer support for UW
  302. X *
  303. X * Copyright 1986 by John D. Bruner.  All rights reserved.  Permission to
  304. X * copy this program is given provided that the copy is not sold and that
  305. X * this copyright notice is included.
  306. X */
  307. X
  308. X#ifndef UW_CLK
  309. X#define    UW_CLK
  310. X
  311. X/*
  312. X * Events which are supposed to occur at a certain time are handled by
  313. X * setting "timeout"s.  The list of timeouts is sorted in order of
  314. X * occurrence.  The "alarm" mechanism is used to send SIGALRM when the
  315. X * first timeout expires.  However, the timeout is not processed
  316. X * immediately.  Instead, it will be processed upon exit from the
  317. X * select() in main().  This prevents timeouts from happening at
  318. X * inappropriate times.
  319. X *
  320. X * The resolution of timeouts is in seconds.  The server doesn't need
  321. X * any better resolution, and this allows all of the hair associated with
  322. X * (struct timeval) and (struct itimerval) types to be avoided.
  323. X */
  324. X
  325. X#define    CLK_HZ        1        /* one tick/second */
  326. X
  327. Xtypedef long toarg_t;
  328. X
  329. Xstruct timeout {
  330. X    struct timeout    *to_next;
  331. X    time_t        to_when;
  332. X    void        (*to_fn)();
  333. X    toarg_t        to_arg;
  334. X};
  335. X
  336. Xextern int timer_rdy;
  337. X
  338. X#define    CLK_CHECK()    if (timer_rdy) clk_service(); else
  339. X#endif
  340. !EOF!h/uw_clk.h!
  341. echo x - h/uw_err.h
  342. sed -e 's/^X//' > h/uw_err.h << '!EOF!h/uw_err.h!'
  343. X/*
  344. X *    uw error codes
  345. X *
  346. X * Copyright 1986 by John D. Bruner.  All rights reserved.  Permission to
  347. X * copy this program is given provided that the copy is not sold and that
  348. X * this copyright notice is included.
  349. X */
  350. X
  351. X#ifndef UW_ERR
  352. X#define    UW_ERR
  353. X
  354. Xtypedef int uwerr_t;
  355. X
  356. X#define    UWE_NONE    0        /* no error */
  357. X#define    UWE_ERRNO    1        /* system call error, consult errno */
  358. X#define    UWE_NXTYPE    2        /* nonexistent window type */
  359. X#define    UWE_DUPID    3        /* window ID duplicated (in use) */
  360. X#define    UWE_NOTIMPL    4        /* operation not implemented yet */
  361. X#define    UWE_NXSERV    5        /* non-existent server */
  362. X#define    UWE_NOMEM    6        /* unable to allocate required memory */
  363. X#define    UWE_INVAL    7        /* invalid argument to function */
  364. X#define    UWE_NOCTL    8        /* no control file descriptor */
  365. X
  366. X#endif
  367. !EOF!h/uw_err.h!
  368. echo x - h/uw_fd.h
  369. sed -e 's/^X//' > h/uw_fd.h << '!EOF!h/uw_fd.h!'
  370. X/*
  371. X *    uw_fd - file-descriptor/select data
  372. X *
  373. X * Copyright 1986 by John D. Bruner.  All rights reserved.  Permission to
  374. X * copy this program is given provided that the copy is not sold and that
  375. X * this copyright notice is included.
  376. X */
  377. X
  378. X#ifndef UW_FD
  379. X#define    UW_FD
  380. X
  381. X#include "uw_param.h"
  382. X
  383. X/*
  384. X * If FD_SET and friends aren't defined in <sys/types.h>, then we
  385. X * provide simple definitions here.
  386. X */
  387. X#ifndef FD_SET
  388. X#define    FD_SET(n,p)    ((p)->fds_bits[0] |= (1 << (n)))
  389. X#define    FD_CLR(n,p)    ((p)->fds_bits[0] &= ~(1 << (n)))
  390. X#define    FD_ISSET(n,p)    ((p)->fds_bits[0] & (1 << (n)))
  391. X#define    FD_ZERO(p)    ((p)->fds_bits[0] = 0)
  392. X#define    FD_SETSIZE    (NBBY*sizeof(long))
  393. X#endif
  394. X
  395. X/*
  396. X * We use file descriptors for several different things.  "fdmap" associates
  397. X * a file descriptor number with its use.
  398. X */
  399. Xtypedef enum {                /* file descriptor type */
  400. X    FDT_NONE,            /*    not in use */
  401. X    FDT_DATA,            /*    data connection for window */
  402. X    FDT_CTL,            /*    control connection for window */
  403. X    FDT_MAC,            /*    tty line which talks to Mac */
  404. X    FDT_UDSOCK,            /*    UNIX-domain datagram socket */
  405. X    FDT_ISSOCK,            /*    Internet-domain stream sock */
  406. X    FDT_DEBUG,            /*    debugging use */
  407. X    FDT_OTHER            /*    other uses */
  408. X} fdtype_t;
  409. X
  410. Xstruct fdmap {
  411. X    fdtype_t    f_type;        /* file descriptor type */
  412. X    struct window    *f_win;        /* associate window (if any) */
  413. X};
  414. X
  415. Xstruct selmask {
  416. X    struct fd_set    sm_rd;
  417. X    struct fd_set    sm_wt;
  418. X    struct fd_set    sm_ex;
  419. X};
  420. X
  421. Xextern struct fdmap fdmap[FD_SETSIZE];
  422. Xextern fildes_t nfds;
  423. Xextern struct selmask selmask[2];
  424. X#endif
  425. !EOF!h/uw_fd.h!
  426. echo x - h/uw_ipc.h
  427. sed -e 's/^X//' > h/uw_ipc.h << '!EOF!h/uw_ipc.h!'
  428. X/*
  429. X *    uw IPC definitions
  430. X *
  431. X * Copyright 1986 by John D. Bruner.  All rights reserved.  Permission to
  432. X * copy this program is given provided that the copy is not sold and that
  433. X * this copyright notice is included.
  434. X */
  435. X
  436. X#ifndef UW_IPC
  437. X#define    UW_IPC
  438. X
  439. X/*
  440. X * UW accepts network connections in both the UNIX domain and the
  441. X * Internet domain.  UNIX domain datagrams are used by processes on
  442. X * the local machine to create new windows and to change the value
  443. X * of window parameters (window options).  TCP (Internet stream)
  444. X * connections are used by local and non-local processes which wish
  445. X * to handle their own host activity (e.g. pseudo-terminal handling).
  446. X *
  447. X * Some of the definitions in this file duplicate definitions in the
  448. X * UW server source code, because this file is also intended for use
  449. X * with the UW library.
  450. X *
  451. X * The code which performs byte-order conversions knows the size of the
  452. X * types defined in this file (since there is no typeof() operator).
  453. X */
  454. X
  455. X#define    UIPC_ENV    "UW_UIPC"    /* Unix-domain port environment var */
  456. X#define    INET_ENV    "UW_INET"    /* Internet-domain port environ var */
  457. X
  458. Xtypedef long uwid_t;            /* unique window identifier */
  459. X
  460. Xtypedef short uwcmd_t;            /* commands: */
  461. X#define    UWC_NEWW    0        /*    create new window */
  462. X#define    UWC_NEWT    1        /*    create new tty window */
  463. X#define    UWC_STATUS    2        /*    creation status message */
  464. X#define    UWC_KILLW    3        /*    kill existing window */
  465. X#define    UWC_OPTION    4        /*    act upon window option */
  466. X
  467. Xtypedef short uwoptcmd_t;        /* option subcommands: */
  468. X#define    UWOC_SET    0        /*    set value of option */
  469. X#define    UWOC_ASK    2        /*    ask for value of option */
  470. X#define    UWOC_DO        4        /*    report changes in value */
  471. X#define    UWOC_DONT    5        /*    don't report changes */
  472. X#define    UWOC_WILL    6        /*    will report changes */
  473. X#define    UWOC_WONT    7        /*    won't report changes */
  474. X
  475. Xtypedef short uwtype_t;            /* window type (see also uw_win.h): */
  476. X#define    UWT_ADM31    0        /*    ADM-31 */
  477. X#define    UWT_VT52    1        /*    VT-52 */
  478. X#define    UWT_ANSI    2        /*    ANSI */
  479. X#define    UWT_TEK4010    3        /*    Tektronix 4010 */
  480. X#define    UWT_FTP        4        /*    file transfer */
  481. X#define    UWT_PRINT    5        /*    output to Macintosh printer */
  482. X#define    UWT_PLOT    6        /*    plot window */
  483. X
  484. Xtypedef short uwopt_t;            /* window option number: */
  485. X#define    UWOP_VIS    1        /*    visibility */
  486. X#define    UWOP_TYPE    2        /*    window type */
  487. X#define    UWOP_POS    3        /*    window position */
  488. X#define    UWOP_TITLE    4        /*    window title */
  489. X#define    UWOP_WSIZE    5        /*    window size (in bits) */
  490. X
  491. X#define    UWOP_TSIZE    8        /*    terminal size (row,col) */
  492. X#define    UWOP_TFONTSZ    9        /*    small/large font size */
  493. X#define    UWOP_TCLIPB    10        /*    clipboard/mouse encoding */
  494. X#define    UWOP_TBELL    11        /*    audible, visual bell */
  495. X#define    UWOP_TCURS    12        /*    cursor shape */
  496. X
  497. Xunion uwoptval {
  498. X    unsigned char    uwov_1bit;
  499. X    unsigned char    uwov_6bit;
  500. X    unsigned short    uwov_12bit;
  501. X    struct {
  502. X        unsigned short v,h;
  503. X    }        uwov_point;
  504. X    char        uwov_string[256];
  505. X};
  506. X
  507. X
  508. X/*
  509. X * UWC_NEWW: create a new window
  510. X *
  511. X * This command is only valid when it is sent as the first message on an
  512. X * Internet stream socket.  The remote port is the data fd for the window.
  513. X * If a control fd is desired, its port number is contained in "uwnt_ctlport"
  514. X */
  515. Xstruct uwneww {
  516. X    uwid_t        uwnw_id;    /* unique window identifier */
  517. X    uwtype_t    uwnw_type;    /* window type */
  518. X    short        uwnw_ctlport;    /* port number of control fd */
  519. X};
  520. X
  521. X/*
  522. X * UWC_NEWT: create a new tty window
  523. X *
  524. X * This command is only valid when it is sent as a datagram to the Unix-domain
  525. X * socket.  It must be accompanied by an access right (file descriptor) for
  526. X * the master side of a pty.  The server takes over all responsibilities for
  527. X * this window.  "uwnt_pty" is variable-length.
  528. X */
  529. Xstruct uwnewt {
  530. X    uwid_t        uwnt_id;    /* unique window identifier */
  531. X    uwtype_t    uwnt_type;    /* window type */
  532. X    char        uwnt_pty[1];    /* name of associated pty */
  533. X};
  534. X
  535. X/*
  536. X * UWC_STATUS: status report for UWC_NEWW
  537. X *
  538. X * This type of packet is sent by the server to the data fd in response
  539. X * to a UWC_NEWW.  It specifies whether the window was successfully
  540. X * created and what unique ID was assigned.
  541. X */
  542. Xstruct uwstatus {
  543. X    uwid_t        uwst_id;    /* unique window identifier */
  544. X    short        uwst_err;    /* error status */
  545. X    short        uwst_errno;    /* UNIX error code (see <errno.h>) */
  546. X};
  547. X
  548. X/*
  549. X * UWC_KILLW: kill the window
  550. X *
  551. X * This command may be sent to either the Unix-domain socket or the control
  552. X * file descriptor of an external window.  In the latter case, "uwkw_id"
  553. X * must match the ID of the window associated with the file descriptor.
  554. X */
  555. Xstruct uwkillw {
  556. X    uwid_t        uwkw_id;    /* unique window identifier */
  557. X};
  558. X
  559. X/*
  560. X * UWC_OPTION: act upon window option
  561. X *
  562. X * This command may be sent to either the Unix-domain socket or the control
  563. X * file descriptor of an external window.  In the former case, only the
  564. X * UWOC_SET command is processed.
  565. X */
  566. Xstruct uwoption {
  567. X    uwid_t        uwop_id;    /* unique window identifier */
  568. X    uwopt_t        uwop_opt;    /* option number */
  569. X    uwoptcmd_t    uwop_cmd;    /* option subcommand */
  570. X    union uwoptval    uwop_val;    /* option value (for UWOC_SET) */
  571. X};
  572. X
  573. Xstruct uwipc {
  574. X    unsigned short    uwip_len;    /* length of this message */
  575. X    uwcmd_t        uwip_cmd;    /* command (message type) */
  576. X    union {
  577. X        struct uwneww uwipu_neww;
  578. X        struct uwnewt uwipu_newt;
  579. X        struct uwstatus uwipu_status;
  580. X        struct uwkillw uwipu_killw;
  581. X        struct uwoption uwipu_option;
  582. X    }        uwip_u;
  583. X#define    uwip_neww    uwip_u.uwipu_neww
  584. X#define    uwip_newt    uwip_u.uwipu_newt
  585. X#define    uwip_status    uwip_u.uwipu_status
  586. X#define    uwip_killw    uwip_u.uwipu_killw
  587. X#define    uwip_option    uwip_u.uwipu_option
  588. X};
  589. X
  590. X#endif
  591. !EOF!h/uw_ipc.h!
  592. echo x - h/uw_opt.h
  593. sed -e 's/^X//' > h/uw_opt.h << '!EOF!h/uw_opt.h!'
  594. X/*
  595. X *    uw window options
  596. X *
  597. X * Copyright 1986 by John D. Bruner.  All rights reserved.  Permission to
  598. X * copy this program is given provided that the copy is not sold and that
  599. X * this copyright notice is included.
  600. X *
  601. X * Some protocols support the transmission of window options.  A window
  602. X * option is a parameter (or collection of related parameters) which
  603. X * describes the layout, appearance, or other characteristic of a
  604. X * window.  Some options are common to all window types, while others
  605. X * are window emulation-specific.
  606. X *
  607. X * Window options may be "set" by one side on its own initiative or in
  608. X * response to an "inquiry" from the other side.  In addition, one side
  609. X * may request that the other side "report" changes in options.
  610. X *
  611. X * Options are passed as part of a "new window" command or as part of
  612. X * an "option" command (as defined by the protocol, above).  The option
  613. X * format has been chosen to minimize the need for protocol encoding
  614. X * of special or meta characters.
  615. X */
  616. X
  617. X#ifndef    UW_OPT
  618. X#define    UW_OPT
  619. X
  620. Xtypedef unsigned int woptcmd_t;        /* window option command: */
  621. X#define    WOC_SET        0        /*    request current option value */
  622. X#define    WOC_INQUIRE    2        /*    report current option value */
  623. X#define    WOC_DO        4        /*    do report changes to option */
  624. X#define    WOC_DONT    5        /*    don't report changes */
  625. X#define    WOC_WILL    6        /*    will report changes */
  626. X#define    WOC_WONT    7        /*    won't report changes */
  627. X#define    WOC_MASK    7        /*    mask */
  628. X#define    WOC_BADCMD(n)    ((n)==1 || (n)==3)
  629. X
  630. X/*
  631. X * Option commands include an option number specifier.  If the option
  632. X * number is in the range 1-14 a short-form specifier can be used;
  633. X * otherwise, a long-form specifier must be used.  Option (sub)command
  634. X * bytes consist of 7 bits of data.  The lower order 3 bits specify the
  635. X * option command.  The next higher 4 bits specify the option number.
  636. X * The value zero is reserved (as described below).  If the option
  637. X * number is greater than 14, these four bits specify 017 (15) and the
  638. X * option number is specified in a second byte.  The value is encoded
  639. X * by adding ' ' to the option number.  Multiple options may be specified
  640. X * in one command -- the last option is followed by a reference to
  641. X * "option" 0 (as an endmarker).
  642. X */
  643. X
  644. Xtypedef unsigned int woption_t;        /* window option number: */
  645. X#define    WONUM_MIN    1        /*    minimum option number */
  646. X#define    WONUM_GENERIC    7        /*    maximum generic option number */
  647. X#define    WONUM_SHORT    14        /*    maximum short option number */
  648. X#define    WONUM_MAX    31        /*    maximum option number */
  649. X#define    WONUM_MASK    (017<<3)    /*    mask for extraction */
  650. X#define    WONUM_USELONG(n) ((unsigned)(n) > WONUM_SHORT)
  651. X#define    WONUM_SENCODE(n) (((n)&017)<<3)    /*     short encoding function */
  652. X#define    WONUM_SDECODE(b) (((b)>>3)&017)    /*     short decoding function */
  653. X#define    WONUM_LPREFIX    (017<<3)    /*    long encoding prefix */
  654. X#define    WONUM_LENCODE(n) ((n)+' ')    /*     long encoding function */
  655. X#define    WONUM_LDECODE(c) (((c)&0177)-' ') /*     long decoding function */
  656. X
  657. X
  658. X/*
  659. X * The following option numbers are generic (recognized for all window
  660. X * types):
  661. X */
  662. X#define    WOG_END        0        /* [endmarker] */
  663. X#define    WOG_VIS        1        /* 0=invisible, 1=visible */
  664. X#define    WOG_TYPE    2        /* window emulation type (see below) */
  665. X#define    WOG_POS        3        /* window position on screen */
  666. X#define    WOG_TITLE    4        /* window title */
  667. X#define    WOG_SIZE    5        /* window size (in bits) */
  668. X#define    WOG_6        6        /* unassigned, reserved */
  669. X#define    WOG_7        7        /* unassigned, reserved */
  670. X
  671. X/*
  672. X * Option arguments immediately follow option (sub)command bytes.  They are
  673. X * encoded to prevent interference with flow-control and IAC recognition.
  674. X * Three types of options are recognized: non-graphic character strings of
  675. X * fixed length, general character strings of variable length, and binary
  676. X * numbers of fixed width.
  677. X *
  678. X * Non-graphic character strings are transmitted directly.  They CANNOT
  679. X * include IAC, XON, or XOFF and should not include "meta" characters.
  680. X *
  681. X * General character strings are encoded in the UW protocol fashion: "meta"
  682. X * characters and special characters are escaped.  The string is terminated
  683. X * with a null byte.  The string may not exceed some predetermined maximum
  684. X * number of characters (which may be less than or equal to 256, including
  685. X * the terminating null byte).
  686. X *
  687. X * Binary numbers are transmitted in 6-bit chunks, least-significant bits
  688. X * first.  The number of 6-bit chunks required depends upon the width of
  689. X * the number.  The 0100 bit in each byte is always set to prevent
  690. X * collisions with special characters (such as flow control and IAC).
  691. X */
  692. X
  693. X/*
  694. X * Implementation:
  695. X *
  696. X * Arrays of type "woptarg_t" are used to describe the arguments associated
  697. X * with each option.  (Note that arguments are associated only with
  698. X * the "set" option subcommand.)
  699. X */
  700. X
  701. Xtypedef unsigned woptarg_t;        /* option argument type: */
  702. X#define    WOA_END        0        /*    endmarker */
  703. X#define    WOA_CHARS(n)    ((1<<8)|(n))    /*    "n" untranslated characters */
  704. X#define    WOA_STRING(m)    ((2<<8)|(m))    /*    string of max length "m" */
  705. X#define    WOA_UDATA(b)    ((3<<8)|(b))    /*    binary number "b" bits wide */
  706. X#define    WOA_CMDMASK    0177400        /* command mask */
  707. X
  708. Xtypedef long woptbmask_t;        /* option bitmask (>= 32 bits wide) */
  709. X#define    WOPT_SET(mask,bit)    ((mask) |= (1<<(bit)))
  710. X#define    WOPT_CLR(mask,bit)    ((mask) &= ~(1<<(bit)))
  711. X#define    WOPT_ISSET(mask,bit)    ((mask) & (1<<(bit)))
  712. X
  713. Xstruct woptdefn {
  714. X    woptbmask_t    wod_pending;    /* pending notifications to Mac */
  715. X    woptbmask_t    wod_inquire;    /* pending inquiries from Mac */
  716. X    woptbmask_t    wod_do;        /* pending DO commands to Mac */
  717. X    woptbmask_t    wod_dont;    /* pending DONT commands to Mac */
  718. X    woptbmask_t    wod_askrpt;    /* reports (of changes) we ask for */
  719. X    struct woptlst {
  720. X        woptarg_t    *wol_argdefn;    /* option argument definition */
  721. X        char        *(*wol_get)();    /* called to get option value */
  722. X        void        (*wol_set)();    /* called to set option value */
  723. X        void        (*wol_ext)();    /* called for external window */
  724. X    }        wod_optlst[WONUM_MAX+1];
  725. X};
  726. X
  727. X/*
  728. X * The following structure is used by routines that fetch and set option
  729. X * values.
  730. X */
  731. Xunion optvalue {
  732. X    unsigned char    ov_udata1;
  733. X    unsigned char    ov_udata2;
  734. X    unsigned char    ov_udata6;
  735. X    unsigned short    ov_udata12;
  736. X    struct {
  737. X        unsigned short    v,h;
  738. X    }        ov_point;
  739. X    char        ov_string[256];
  740. X};
  741. X
  742. X/*
  743. X * When it is necessary to convert between host byte order and network
  744. X * byte order, opt_netadj() is called.  A pointer to the following
  745. X * structure is passed.
  746. X */
  747. Xstruct netadj {
  748. X    short        (*na_short)();
  749. X    long        (*na_long)();
  750. X    unsigned short    (*na_ushort)();
  751. X    unsigned long    (*na_ulong)();
  752. X};
  753. X
  754. X#endif
  755. !EOF!h/uw_opt.h!
  756. echo x - h/uw_param.h
  757. sed -e 's/^X//' > h/uw_param.h << '!EOF!h/uw_param.h!'
  758. X/*
  759. X *    uw parameters
  760. X *
  761. X * Copyright 1986 by John D. Bruner.  All rights reserved.  Permission to
  762. X * copy this program is given provided that the copy is not sold and that
  763. X * this copyright notice is included.
  764. X */
  765. X
  766. X/*
  767. X * This file exists because #include file definitions aren't in the same
  768. X * place on all machines.  Also, it seems pointless to drag in all of
  769. X * <stdio.h> just to define NULL.  Finally, a few declarations are
  770. X * sufficiently global that this is the most logical place to put them.
  771. X *
  772. X * This file should be #included after all of the system include files
  773. X * (e.g. <sys/types.h>) but before any other UW include files.
  774. X */
  775. X#ifndef UW_PARAM
  776. X#define    UW_PARAM
  777. X
  778. Xtypedef int fildes_t;        /* this really should be in <sys/types.h> */
  779. X
  780. X#ifndef NBBY            /* this is in <sys/types.h> in 4.3BSD */
  781. X#define    NBBY    8        /* (number of bits/byte) */
  782. X#endif
  783. X
  784. X#ifndef NULL
  785. X#define    NULL    0
  786. X#endif
  787. X
  788. Xextern char *malloc();
  789. Xextern char *mktemp();
  790. Xextern char *getenv();
  791. Xextern void done();
  792. Xextern void cwait();
  793. X
  794. X#endif
  795. !EOF!h/uw_param.h!
  796. echo x - h/uw_pcl.h
  797. sed -e 's/^X//' > h/uw_pcl.h << '!EOF!h/uw_pcl.h!'
  798. X/*
  799. X *    uw protocol
  800. X *
  801. X * Copyright 1985,1986 by John D. Bruner.  All rights reserved.  Permission to
  802. X * copy this program is given provided that the copy is not sold and that
  803. X * this copyright notice is included.
  804. X */
  805. X
  806. X#ifndef UW_PCL
  807. X#define    UW_PCL
  808. X
  809. X#include "uw_win.h"
  810. X
  811. X/* UW may operate over connections which speak one of several protocols.
  812. X * Internally these protocols are assigned numbers starting at zero.
  813. X * Three such protocols are currently defined:
  814. X *
  815. X *    0: no special protocol
  816. X *    1: original UW (v1.6, v2.10) protocol
  817. X *    2: extended protocol (v3.x)
  818. X */
  819. X
  820. X/*
  821. X * Protocol 0:
  822. X *
  823. X * The connection between the Macintosh and the host is simply a serial
  824. X * line.  Flow control may be enabled, but no special commands are
  825. X * recognized.  Only one active window is supported.  This "protocol"
  826. X * does not require the UW server; hence, there is no need to support it.
  827. X */
  828. X
  829. X/*
  830. X * Protocol 1: (original UW protocol)
  831. X *
  832. X * Two types of information are exchanged through the 7-bit serial line:
  833. X * ordinary data and command bytes.  Command bytes are preceeded by
  834. X * an IAC byte.  IAC bytes and literal XON/XOFF characters (those which
  835. X * are not used for flow control) are sent by a P1_FN_CTLCH command.
  836. X * Characters with the eighth bit set (the "meta" bit) are prefixed with
  837. X * a P1_FN_META function.
  838. X *
  839. X * The next most-significant bit in the byte specifies the sender and
  840. X * recipient of the command.  If this bit is clear (0), the command byte
  841. X * was sent from the host computer to the Macintosh; if it is set (1)
  842. X * the command byte was sent from the Macintosh to the host computer.
  843. X * This prevents confusion in the event that the host computer
  844. X * (incorrectly) echos a command back to the Macintosh.
  845. X *
  846. X * The remaining six bits are partitioned into two fields.  The low-order
  847. X * three bits specify a window number from 1-7 (window 0 is reserved for
  848. X * other uses) or another type of command-dependent parameter.  The next
  849. X * three bits specify the operation to be performed by the recipient of
  850. X * the command byte.
  851. X *
  852. X * Note that the choice of command bytes prevents the ASCII XON (021) and
  853. X * XOFF (023) characters from being sent as commands.  P1_FN_ISELW commands
  854. X * are only sent by the Macintosh (and thus are tagged with the P1_DIR_MTOH
  855. X * bit).  Since XON and XOFF data characters are handled via P1_FN_CTLCH,
  856. X * this allows them to be used for flow control purposes.
  857. X */
  858. X#define    P1_IAC        0001        /* interpret as command */
  859. X#define    P1_DIR        0100        /* command direction: */
  860. X#define    P1_DIR_HTOM    0000        /*    from host to Mac */
  861. X#define    P1_DIR_MTOH    0100        /*    from Mac to host */
  862. X#define    P1_FN        0070        /* function code: */
  863. X#define    P1_FN_NEWW    0000        /*    new window */
  864. X#define    P1_FN_KILLW    0010        /*    kill (delete) window */
  865. X#define    P1_FN_ISELW    0020        /*    select window for input */
  866. X#define    P1_FN_OSELW    0030        /*    select window for output */
  867. X#define    P1_FN_META    0050        /*    add meta to next data char */
  868. X#define    P1_FN_CTLCH    0060        /*    low 3 bits specify char */
  869. X#define    P1_FN_MAINT    0070        /*    maintenance functions */
  870. X#define    P1_WINDOW    0007        /* window number mask */
  871. X#define    P1_CC        0007        /* control character specifier: */
  872. X#define    P1_CC_IAC    1        /*    IAC */
  873. X#define    P1_CC_XON    2        /*    XON */
  874. X#define    P1_CC_XOFF    3        /*    XOFF */
  875. X#define    P1_MF        0007        /* maintenance functions: */
  876. X#define    P1_MF_ENTRY    0        /*    beginning execution */
  877. X#define    P1_MF_ASKPCL    2        /*    request protocol negotiation */
  878. X#define    P1_MF_CANPCL    3        /*    suggest protocol */
  879. X#define    P1_MF_SETPCL    4        /*    set current protocol */
  880. X#define    P1_MF_EXIT    7        /*    execution terminating */
  881. X#define    P1_NWINDOW    7        /* maximum number of windows */
  882. X
  883. X/*
  884. X * Protocol 2: (extended UW protocol)
  885. X *
  886. X * Protocol 2 is an extension of protocol 1.  The P2_FN_NEWW command and
  887. X * the new command P2_FN_WOPT communicate window options between the host
  888. X * and the Macintosh.  (See "uw_opt.h" for details.)
  889. X */
  890. X#define    P2_IAC        P1_IAC        /* interpret as command */
  891. X#define    P2_DIR        P1_DIR        /* command direction: */
  892. X#define    P2_DIR_HTOM    P1_DIR_HTOM    /*    from host to Mac */
  893. X#define    P2_DIR_MTOH    P1_DIR_MTOH    /*    from Mac to host */
  894. X#define    P2_FN        P1_FN        /* function code: */
  895. X#define    P2_FN_NEWW    P1_FN_NEWW    /*    new window */
  896. X#define    P2_FN_KILLW    P1_FN_KILLW    /*    kill (delete) window */
  897. X#define    P2_FN_ISELW    P1_FN_ISELW    /*    select window for input */
  898. X#define    P2_FN_OSELW    P1_FN_OSELW    /*    select window for output */
  899. X#define    P2_FN_WOPT    0040        /*    communicate window options */
  900. X#define    P2_FN_META    P1_FN_META    /*    add meta to next data char */
  901. X#define    P2_FN_CTLCH    P1_FN_CTLCH    /*    low 3 bits specify char */
  902. X#define    P2_FN_MAINT    P1_FN_MAINT    /*    maintenance functions */
  903. X#define    P2_WINDOW    P1_WINDOW    /* window number mask */
  904. X#define    P2_CC        P1_CC        /* control character specifier: */
  905. X#define    P2_CC_IAC    P1_CC_IAC    /*    IAC */
  906. X#define    P2_CC_XON    P1_CC_XON    /*    XON */
  907. X#define    P2_CC_XOFF    P1_CC_XOFF    /*    XOFF */
  908. X#define    P2_MF        P1_MF        /* maintenance functions: */
  909. X#define    P2_MF_ENTRY    P1_MF_ENTRY    /*    beginning execution */
  910. X#define    P2_MF_ASKPCL    P1_MF_ASKPCL    /*    request protocol negotiation */
  911. X#define    P2_MF_CANPCL    P1_MF_CANPCL    /*    suggest protocol */
  912. X#define    P2_MF_SETPCL    P1_MF_SETPCL    /*    set current protocol */
  913. X#define    P2_MF_EXIT    P1_MF_EXIT    /*    execution terminating */
  914. X#define    P2_NWINDOW    P1_NWINDOW    /* maximum number of windows */
  915. X
  916. X/*
  917. X * Protocol negotiation
  918. X *
  919. X * The server is not used for protocol 0.  For the other protocols, the
  920. X * Macintosh and the server negotiate to select the active protocol.  The
  921. X * basic idea is that the Macintosh will express its desire for a protocol
  922. X * and the server will attempt to satisfy that desire.  Until negotiations
  923. X * are complete, protocol 1 is used.
  924. X *
  925. X * Protocols are identified by single-character names which are formed by
  926. X * adding the ASCII code for a space (040) to the protocol number minus 1
  927. X * (i.e. protocol 1 is ' ', protocol 2 is '!').
  928. X *
  929. X * P1_FN_CANPCL and P1_FN_SETPCL are three-byte commands: P1_IAC,
  930. X * P1_FN_XXXPCL, protocol-name.
  931. X *
  932. X * Macintosh:
  933. X *    If UW v2.10 is used on the Macintosh or if a newer Macintosh program
  934. X *    wishes to use protocol 1, it will never initiate protocol negotiation.
  935. X *    Hence, all interaction will use protocol 1 by default.
  936. X *
  937. X *    If the Macintosh program is capable of supporting protocol 2 and the
  938. X *    user requests its use, the Mac will remember this fact but will
  939. X *    continue to use protocol 1.  The Mac program will assume that no
  940. X *    server is present until instructed otherwise by the user or until a
  941. X *    P1_FN_ENTRY command is received (e.g. when the server starts up).
  942. X *    At this time, the Mac program issues P1_FN_ASKPCL.  If the server
  943. X *    cannot support protocol 2 (i.e. it is an old server), then it will
  944. X *    ignore the P1_FN_ASKPCL.  The Macintosh will retry the P1_FN_ASKPCL
  945. X *    a couple of times (about five seconds apart) and, if there is no
  946. X *    response from the server, will abandon negotiations.  Protocol 1
  947. X *    will be used for the remainder of the session.
  948. X *
  949. X *    If the server recognizes the P1_FN_ASKPCL command it will respond
  950. X *    with the name of the most complex protocol it can support (currently
  951. X *    '!').  If this is acceptable to the Macintosh, it will instruct the
  952. X *    server to use this protocol.  If the Macintosh cannot support this
  953. X *    protocol it will respond with a P1_FN_CANPCL suggesting a less-complex
  954. X *    protocol.  If the server agrees to this it will answer establish the
  955. X *    protocol; otherwise, it will suggest an even weaker protocol.
  956. X *    Eventually someone will suggest protocol 1 (which is universal) and
  957. X *    the other side will issue a P1_FN_SETPCL command to establish its use.
  958. X *
  959. X * Host:
  960. X *    If the host receives a P1_FN_ASKPCL it will respond with the most
  961. X *    complex protocol it can support (using the P1_FN_CANPCL command).
  962. X *    Negotiations will proceed as described above until one side
  963. X *    establishes a new protocol with P1_FN_SETPCL.  At this time, the
  964. X *    host will switch to the new protocol.
  965. X *
  966. X *    If the host receives a P1_FN_ENTRY (P2_FN_ENTRY) command, it will
  967. X *    switch back to protocol 1.  Receipt of this command indicates that
  968. X *    the Macintosh program was restarted.  The Macintosh must initiate
  969. X *    protocol negotiations again.
  970. X */
  971. X
  972. X/*
  973. X * Although many of the functions are identical (and the code is shared
  974. X * between them), each protocol is accessed through a (struct protocol)
  975. X * which specifies the functions for various operations.
  976. X *
  977. X * In theory, the main program knows nothing about the protocol in use.
  978. X * In practice, the externally-visible functions are accessed as macros
  979. X * for greater efficiency.
  980. X *
  981. X * The protocol layer is aware of the (struct window) data structures.
  982. X */
  983. X
  984. Xstruct protocol {
  985. X    char        p_name;        /* single-character protocol name */
  986. X    nwin_t        p_maxwin;    /* maximum window number */
  987. X    int        *p_ctlch;    /* control character map table */
  988. X    unsigned    p_szctlch;    /* size (# of entries) in ctlch table */
  989. X    void        (*p_entry)();    /* start up (ENTRY maintenance fn) */
  990. X    void        (*p_exit)();    /* shut down (EXIT maintenance fn) */
  991. X    void        (*p_renew)();    /* renew (re-init) */
  992. X    struct window    *(*p_neww)();    /* create new window */
  993. X    void        (*p_killw)();    /* kill window */
  994. X    void        (*p_xmit)();    /* transmit to specified window */
  995. X    void        (*p_recv)();    /* receive from Macintosh */
  996. X    void        (*p_chkopt)();    /* check for pending option output */
  997. X    void        (*p_sendopt)();    /* send option string to Macintosh */
  998. X    void        (*p_askpcl)();    /* send an ASKPCL maintenance command */
  999. X    void        (*p_canpcl)();    /* send a CANPCL maintenance command */
  1000. X    void        (*p_setpcl)();    /* send a SETPCL maintenance command */
  1001. X};
  1002. X
  1003. Xextern struct protocol *protocol;
  1004. X
  1005. X#define    PCL_NEWW(mfd,class,wtype,wnum,wid,dfd,cfd) \
  1006. X    (*protocol->p_neww)(mfd,class,wtype,wnum,(long)wid,dfd,cfd)
  1007. X#define    PCL_KILLW(mfd,w)    (*protocol->p_killw)(mfd,w)
  1008. X#define    PCL_RECV(mfd,buf,len)    (*protocol->p_recv)(mfd,buf,len)
  1009. X#define    PCL_XMIT(mfd,w)    (*protocol->p_xmit)(mfd,w)
  1010. X#define    PCL_SENDOPT(mfd,fn,buf,len) \
  1011. X    (protocol->p_sendopt ? (*protocol->p_sendopt)(mfd,fn,buf,len) : 0)
  1012. X#endif
  1013. !EOF!h/uw_pcl.h!
  1014. echo x - h/uw_win.h
  1015. sed -e 's/^X//' > h/uw_win.h << '!EOF!h/uw_win.h!'
  1016. X/*
  1017. X *    uw window data definition
  1018. X *
  1019. X * Copyright 1986 by John D. Bruner.  All rights reserved.  Permission to
  1020. X * copy this program is given provided that the copy is not sold and that
  1021. X * this copyright notice is included.
  1022. X */
  1023. X
  1024. X#ifndef UW_WIN
  1025. X#define    UW_WIN
  1026. X
  1027. X#include "uw_opt.h"
  1028. X
  1029. X/*
  1030. X * A "point" is a pair of 16-bit integers.  This may specify the horizontal
  1031. X * and vertical position or size of a window.
  1032. X */
  1033. Xtypedef short npixel_t;            /* number of pixels */
  1034. Xstruct point {
  1035. X    npixel_t    v,h;
  1036. X};
  1037. X
  1038. X/*
  1039. X * The type of a window determines how it responds to I/O and which
  1040. X * window options it supports.  I'd like to declare these with an "enum",
  1041. X * but the stupid PCC screams if I use enums as array indices, so they
  1042. X * are defined via #define's instead.
  1043. X */
  1044. Xtypedef unsigned int wtype_t;        /* window type: */
  1045. X#define    WT_ADM31    0        /*    ADM-31 terminal emulation */
  1046. X#define    WT_VT52        1        /*    VT52 terminal emulation */
  1047. X#define    WT_ANSI        2        /*    ANSI terminal emulation */
  1048. X#define    WT_TEK4010    3        /*    Tek4010 terminal emulation */
  1049. X#define    WT_FTP        4        /*    file transfer */
  1050. X#define    WT_PRINT    5        /*    output to printer */
  1051. X#define    WT_PLOT        6        /*    plot window */
  1052. X#define    WT_MAXTYPE    6        /* maximum window type */
  1053. X
  1054. Xextern wtype_t defwtype;        /* default window type */
  1055. X
  1056. X/*
  1057. X * There are two basic classes of windows -- those which are processed
  1058. X * directly by the server and those which are processed by outside
  1059. X * programs.  Directly-handled windows are always terminal emulations.
  1060. X * Externally-handled windows may be any window type.
  1061. X */
  1062. Xtypedef enum {                /* window class: */
  1063. X    WC_INTERNAL,            /*    processed directly */
  1064. X    WC_EXTERNAL,            /*    processed externally */
  1065. X} wclass_t;
  1066. X
  1067. Xstruct window {
  1068. X    int        w_alloc;    /* window allocated if nonzero */
  1069. X    long        w_id;        /* window unique ID */
  1070. X    wtype_t        w_type;        /* window emulation type */
  1071. X    wclass_t    w_class;    /* window class */
  1072. X    fildes_t    w_datafd;    /* data file descriptor */
  1073. X    union {
  1074. X        struct winint {
  1075. X            char wi_tty[32];    /* terminal name */
  1076. X        }    wu_int;
  1077. X        struct winext {
  1078. X            fildes_t we_ctlfd;    /* control file descriptor */
  1079. X        }    wu_ext;
  1080. X    }        w_un;
  1081. X    struct woptdefn    w_optdefn;    /* window option definitions */
  1082. X    int        w_visible;    /* nonzero if window is visible */
  1083. X    struct point    w_position;    /* position of window on screen */
  1084. X    struct point    w_size;        /* size of window in pixels */
  1085. X    char        w_title[256];    /* window title */
  1086. X    char        *w_private;    /* storage private to emulation type */
  1087. X};
  1088. X#define    w_tty        w_un.wu_int.wi_tty
  1089. X#define    w_ctlfd        w_un.wu_ext.we_ctlfd
  1090. X
  1091. Xtypedef int nwin_t;            /* window index data type */
  1092. X
  1093. X/*
  1094. X * Some operations upon windows depend upon the window type.  For each
  1095. X * emulation type there is a "emulation" structure which specifies
  1096. X * emulation-specific data.
  1097. X */
  1098. Xstruct emulation {
  1099. X    struct woptdefn    we_optdefn;    /* window option definitions */
  1100. X    int        (*we_start)();    /* emulation setup code */
  1101. X    void        (*we_stop)();    /* emulation shutdown code */
  1102. X    void        (*we_setext)();    /* make changes req'd for extern win */
  1103. X};
  1104. X
  1105. Xextern struct window *win_neww();    /* create new window */
  1106. Xextern struct window *win_search();    /* convert window ID to window ptr */
  1107. X
  1108. X/*
  1109. X * The following macros convert between a window number and a pointer to
  1110. X * the corresponding window structure (and vice versa).
  1111. X *
  1112. X * NWINDOW *must* be >= P1_NWINDOW and >= P2_NWINDOW (in "uw_pcl.h").
  1113. X */
  1114. X#define    NWINDOW        7        /* maximum number of windows */
  1115. X#define    WIN_NUM(wptr)    ((wptr)-window+1)
  1116. X#define    WIN_PTR(wnum)    (window+(wnum)-1)
  1117. Xextern struct window window[];        /* window data structures */
  1118. X#endif
  1119. !EOF!h/uw_win.h!
  1120. echo x - h/uwlib.h
  1121. sed -e 's/^X//' > h/uwlib.h << '!EOF!h/uwlib.h!'
  1122. X/*
  1123. X *    uw library definitions
  1124. X *
  1125. X * Copyright 1986 by John D. Bruner.  All rights reserved.  Permission to
  1126. X * copy this program is given provided that the copy is not sold and that
  1127. X * this copyright notice is included.
  1128. X */
  1129. X
  1130. X#include "uw_err.h"
  1131. X#include "uw_ipc.h"
  1132. X
  1133. X#ifndef NBBY
  1134. X#define    NBBY        8        /* defined in <sys/types.h> in 4.3BSD */
  1135. X#endif
  1136. X
  1137. X#define    UW_NUMOPTS    32        /* number of window options */
  1138. X#define    UW_NWTYPES    6        /* number of window emulation types */
  1139. X
  1140. Xtypedef char uwtitle_t[256];
  1141. X
  1142. Xstruct uwpoint {
  1143. X    unsigned    uwp_v;        /* vertical component */
  1144. X    unsigned    uwp_h;        /* horizontal component */
  1145. X};
  1146. X
  1147. Xstruct uw_info {
  1148. X    uwid_t        uwi_id;        /* unique window ID */
  1149. X    int        uwi_datafd;    /* file descriptor for data */
  1150. X    int        uwi_ctlfd;    /* file descriptor for control */
  1151. X    uwerr_t        uwi_uwerr;    /* last error from UW */
  1152. X    int        uwi_errno;    /* last error from system call */
  1153. X    int        uwi_vis;    /* visiblility */
  1154. X    uwtype_t    uwi_type;    /* window type */
  1155. X    struct uwpoint    uwi_pos;    /* window position (in pixels) */
  1156. X    uwtitle_t    uwi_title;    /* window title */
  1157. X    struct uwpoint    uwi_wsize;    /* window size (in pixels) */
  1158. X    struct {
  1159. X        void    (*uwi_optfn)();    /* option handler */
  1160. X    }        uwi_options[UW_NUMOPTS];
  1161. X    int        uwi_ipclen;    /* length of data in IPC buffer */
  1162. X    struct uwipc    uwi_ipcbuf;    /* buffer for IPC messages */
  1163. X};
  1164. X
  1165. X#define    UW_DATAFD(uwin)        (uwin)->uwi_datafd
  1166. X#define    UW_ID(uwin)        (uwin)->uwi_id
  1167. X#define    UW_PERROR(uwin, mesg)    \
  1168. X    uw_perror(mesg, (uwin)->uwi_uwerr, (uwin)->uwi_errno)
  1169. X
  1170. Xtypedef struct uw_info *UWIN;
  1171. Xtypedef void (*uwfnptr_t)();
  1172. X
  1173. Xextern uwid_t uw_cmd();
  1174. Xextern UWIN uw_new();
  1175. Xextern uw_close(), uw_detach();
  1176. Xextern uw_optcmd();
  1177. Xextern uw_kill();
  1178. Xextern uwfnptr_t uw_optfn();
  1179. Xextern uw_rsetopt();
  1180. Xextern void uw_perror();
  1181. Xextern uwid_t uw_fork(), uw_cmd(), uw_shell();
  1182. X
  1183. Xextern uw_gvis(), uw_svis();
  1184. Xextern uw_gtype(), uw_stype();
  1185. Xextern uw_gtitle(), uw_stitle();
  1186. Xextern uw_gwsize(), uw_swsize();
  1187. Xextern uw_gpos(), uw_spos();
  1188. X
  1189. Xextern uwerr_t uwerrno;
  1190. Xextern char *uwerrlist[];
  1191. Xextern unsigned uwnerr;
  1192. !EOF!h/uwlib.h!
  1193. echo x - server/Makefile_4.2
  1194. sed -e 's/^X//' > server/Makefile_4.2 << '!EOF!server/Makefile_4.2!'
  1195. X#! /bin/make -f
  1196. X#
  1197. X#    uw makefile (4.2BSD)
  1198. X#
  1199. X# INCDIR names the directory where the header files are located.
  1200. X#
  1201. X# OBJECTS names all of the object files required for the server.
  1202. X#
  1203. X
  1204. XINCDIR    =    ../h
  1205. X
  1206. XOBJECTS    =    uw_clk.o uw_env.o uw_fd.o uw_ipc.o uw_main.o uw_opt.o \
  1207. X        uw_pcl.o uw_tty.o uw_utmp.o uw_win.o openpty.o
  1208. X
  1209. XSOURCES    =    `echo $(OBJECTS) | sed -e 's/\\.o/\\.c/g'`
  1210. X
  1211. XDEFINES    =    `cat ../DEFINES`
  1212. X
  1213. XCFLAGS    =    $(DEFINES) -I$(INCDIR) -O
  1214. XLFLAGS    =
  1215. X
  1216. Xuw:        $(OBJECTS)
  1217. X    $(CC) $(LFLAGS) -o uw $(OBJECTS) $(LIBS)
  1218. X
  1219. Xlint:
  1220. X    lint -hbx -I$(INCDIR) $(DEFINES) $(SOURCES)
  1221. X
  1222. Xtags:
  1223. X    ctags $(SOURCES)
  1224. X
  1225. Xdepend: 
  1226. X    grep '^#include' $(SOURCES) | \
  1227. X    sed -e '/</d' \
  1228. X        -e 's/:[^"]*"\([^"]*\)".*/: ..\/h\/\1/' \
  1229. X        -e 's,^../[a-zA-Z0-9]*/\([^\.]*\)\.[cs],\1.o \1.L,' | \
  1230. X    awk ' { if ($$1 != prev) { print rec; rec = $$0; prev = $$1; } \
  1231. X        else { if (length(rec $$3) > 78) { print rec; rec = $$0; } \
  1232. X               else rec = rec " " $$3 } } \
  1233. X          END { print rec } ' > makedep
  1234. X    echo '/^# DO NOT DELETE THIS LINE/+1,$$d' >eddep
  1235. X    echo '$$r makedep' >>eddep
  1236. X    echo 'w' >>eddep
  1237. X    cp Makefile Makefile.bak
  1238. X    ex - Makefile < eddep
  1239. X    rm eddep makedep
  1240. X
  1241. Xclean:
  1242. X    rm *.o
  1243. X
  1244. X# DO NOT DELETE THIS LINE (or the following blank line) -- make depend uses it
  1245. X
  1246. !EOF!server/Makefile_4.2!
  1247. echo x - server/Makefile_4.3
  1248. sed -e 's/^X//' > server/Makefile_4.3 << '!EOF!server/Makefile_4.3!'
  1249. X#! /bin/make -f
  1250. X#
  1251. X#    uw makefile (4.3BSD)
  1252. X#
  1253. X# INCDIR names the directory where the header files are located.
  1254. X#
  1255. X# OBJECTS names all of the object files required for the server.
  1256. X#
  1257. X
  1258. XINCDIR    =    ../h
  1259. X
  1260. XOBJECTS    =    uw_clk.o uw_env.o uw_fd.o uw_ipc.o uw_main.o uw_opt.o \
  1261. X        uw_pcl.o uw_tty.o uw_utmp.o uw_win.o openpty.o
  1262. X
  1263. XSOURCES    =    `echo $(OBJECTS) | sed -e 's/\\.o/\\.c/g'`
  1264. X
  1265. XDEFINES    =    `cat ../DEFINES`
  1266. X
  1267. XCFLAGS    =    $(DEFINES) -I$(INCDIR) -O
  1268. XLFLAGS    =
  1269. X
  1270. Xuw:        $(OBJECTS)
  1271. X    $(CC) $(LFLAGS) -o uw $(OBJECTS) $(LIBS)
  1272. X
  1273. Xlint:
  1274. X    lint -hbx -I$(INCDIR) $(DEFINES) $(SOURCES)
  1275. X
  1276. Xtags:
  1277. X    ctags $(SOURCES)
  1278. X
  1279. Xdepend: 
  1280. X    $(CC) -M -I$(INCDIR) $(DEFINES) $(SOURCES) | \
  1281. X    sed -e ':loop' \
  1282. X        -e 's/\.\.\/[^ /]*\/\.\./../' \
  1283. X        -e 't loop' | \
  1284. X    awk ' { if ($$1 != prev) { print rec; rec = $$0; prev = $$1; } \
  1285. X        else { if (length(rec $$2) > 78) { print rec; rec = $$0; } \
  1286. X               else rec = rec " " $$2 } } \
  1287. X          END { print rec } ' >> makedep
  1288. X    echo '/^# DO NOT DELETE THIS LINE/+1,$$d' >eddep
  1289. X    echo '$$r makedep' >>eddep
  1290. X    echo 'w' >>eddep
  1291. X    cp Makefile Makefile.bak
  1292. X    ex - Makefile < eddep
  1293. X    rm eddep makedep
  1294. X
  1295. Xclean:
  1296. X    rm *.o
  1297. X
  1298. X# DO NOT DELETE THIS LINE (or the following blank line) -- make depend uses it
  1299. X
  1300. !EOF!server/Makefile_4.3!
  1301. echo x - server/openpty.c
  1302. sed -e 's/^X//' > server/openpty.c << '!EOF!server/openpty.c!'
  1303. X/*
  1304. X *    openpty - open a pseudo-terminal
  1305. X *
  1306. X * The first time that the routine is called, the device directory is
  1307. X * searched and a list of all candidate pseudo-terminals is compiled.
  1308. X * Candidates are defined to be those entries in "/dev" whose names
  1309. X * (1) are the same length as PTY_PROTO and (2) start with the
  1310. X * initial string PTY_PREFIX.  Further, the master and slave sides
  1311. X * must both exist.
  1312. X *
  1313. X * openpty() attempts to find an unused pseudo-terminal from the list
  1314. X * of candidates.  If one is found, the master and slave sides are
  1315. X * opened and the file descriptors and names of these two devices are
  1316. X * returned in a "ptydesc" structure.  (The address of this structure
  1317. X * is supplied by the caller.  Zero is returned if openpty() was
  1318. X * successful, -1 is returned if no pty could be found.
  1319. X */
  1320. X
  1321. X#include <sys/types.h>
  1322. X#include <sys/dir.h>
  1323. X#include <fcntl.h>
  1324. X#include <strings.h>
  1325. X#include "openpty.h"
  1326. X
  1327. X#define    DEV_DIR        "/dev"        /* directory where devices live */
  1328. X#define    PT_INDEX    (sizeof DEV_DIR)    /* location of 'p' in "pty" */
  1329. X
  1330. X#define    PTY_PROTO    "ptyp0"        /* prototype for pty names */
  1331. X#define    PTY_PREFIX    "pty"        /* prefix required for name of pty */
  1332. X
  1333. Xstruct ptyinfo {
  1334. X    struct ptyinfo    *pi_next;
  1335. X    char        *pi_pty;
  1336. X    char        *pi_tty;
  1337. X};
  1338. X
  1339. Xstatic struct ptyinfo *ptylist;
  1340. X
  1341. Xextern char *malloc();
  1342. X
  1343. Xstatic
  1344. Xchar *
  1345. Xdevname(name)
  1346. Xchar *name;
  1347. X{
  1348. X    register char *fullname;
  1349. X
  1350. X    /*
  1351. X     * Construct the full name of a device in DEV_DIR.  Returns
  1352. X     * NULL if it failed (because malloc() failed).
  1353. X     */
  1354. X
  1355. X    fullname = malloc((unsigned)(sizeof DEV_DIR + 1 + strlen(name)));
  1356. X    if (fullname != NULL) {
  1357. X        (void)strcpy(fullname, DEV_DIR);
  1358. X        (void)strcat(fullname, "/");
  1359. X        (void)strcat(fullname, name);
  1360. X    }
  1361. X    return(fullname);
  1362. X}
  1363. X
  1364. Xstatic
  1365. Xisapty(dp)
  1366. Xstruct direct *dp;
  1367. X{
  1368. X    static struct ptyinfo *pi;
  1369. X
  1370. X    /*
  1371. X     * We don't care about the gory details of the directory entry.
  1372. X     * Instead, what we really want is an array of pointers to
  1373. X     * device names (with DEV_DIR prepended).  Therefore, we create
  1374. X     * this array ourselves and tell scandir() to ignore every
  1375. X     * directory entry.
  1376. X     *
  1377. X     * If malloc() fails, the current directory entry is ignored.
  1378. X     */
  1379. X    if (pi == NULL) {
  1380. X        pi = (struct ptyinfo *)malloc((unsigned)sizeof *pi);
  1381. X        if (pi == NULL)
  1382. X            return(0);
  1383. X    }
  1384. X
  1385. X    if (strlen(dp->d_name) == sizeof PTY_PROTO - 1 &&
  1386. X        strncmp(dp->d_name, PTY_PREFIX, sizeof PTY_PREFIX - 1) == 0) {
  1387. X        pi->pi_pty = devname(dp->d_name);
  1388. X        if (pi->pi_pty == NULL)
  1389. X            return(0);
  1390. X        pi->pi_tty = malloc((unsigned)(strlen(pi->pi_pty) + 1));
  1391. X        if (pi->pi_tty == NULL) {
  1392. X            free(pi->pi_pty);
  1393. X            return(0);
  1394. X        }
  1395. X        (void)strcpy(pi->pi_tty, pi->pi_pty);
  1396. X        pi->pi_tty[PT_INDEX] = 't';
  1397. X        if (access(pi->pi_pty, 0) == 0 && access(pi->pi_tty, 0) == 0) {
  1398. X            pi->pi_next = ptylist;
  1399. X            ptylist = pi;
  1400. X            pi = NULL;
  1401. X        } else {
  1402. X            free(pi->pi_pty);
  1403. X            free(pi->pi_tty);
  1404. X        }
  1405. X    }
  1406. X    return(0);
  1407. X}
  1408. X
  1409. Xopenpty(pt)
  1410. Xstruct ptydesc *pt;
  1411. X{
  1412. X    register struct ptyinfo *pi;
  1413. X    static int fail;
  1414. X    auto struct direct **dirlist;
  1415. X    extern char *re_comp();
  1416. X    extern int alphasort();
  1417. X
  1418. X    /*
  1419. X     * If scandir() fails or no possible pty's are found, then "fail"
  1420. X     * is set non-zero.  If "fail" is non-zero then the routine bombs
  1421. X     * out immediately.  Otherwise, the list of candidates is examined
  1422. X     * starting with the entry following the last one chosen.
  1423. X     */
  1424. X    if (fail)
  1425. X        return(-1);
  1426. X
  1427. X    if (!ptylist) {        /* first time */
  1428. X        if (scandir(DEV_DIR, &dirlist, isapty, alphasort) < 0 ||
  1429. X            ptylist == NULL) {
  1430. X            fail = 1;
  1431. X            return(-1);
  1432. X        }
  1433. X        for (pi=ptylist; pi->pi_next; pi=pi->pi_next)
  1434. X            ;
  1435. X        pi->pi_next = ptylist;    /* make the list circular */
  1436. X    }
  1437. X
  1438. X    pi = ptylist;
  1439. X    do {
  1440. X        if ((pt->pt_pfd = open(pi->pi_pty, O_RDWR)) >= 0) {
  1441. X            if ((pt->pt_tfd = open(pi->pi_tty, O_RDWR)) >= 0) {
  1442. X                ptylist = pi->pi_next;
  1443. X                pt->pt_pname = pi->pi_pty;
  1444. X                pt->pt_tname = pi->pi_tty;
  1445. X                return(0);
  1446. X            } else
  1447. X                (void)close(pt->pt_pfd);
  1448. X        }
  1449. X        pi = pi->pi_next;
  1450. X    } while (pi != ptylist);
  1451. X    return(-1);
  1452. X}
  1453. !EOF!server/openpty.c!
  1454. echo x - server/uw_clk.c
  1455. sed -e 's/^X//' > server/uw_clk.c << '!EOF!server/uw_clk.c!'
  1456. X/*
  1457. X *    uw_clk - timer support for UW
  1458. X *
  1459. X * Copyright 1986 by John D. Bruner.  All rights reserved.  Permission to
  1460. X * copy this program is given provided that the copy is not sold and that
  1461. X * this copyright notice is included.
  1462. X */
  1463. X
  1464. X#include <sys/types.h>
  1465. X#include <sys/time.h>
  1466. X#include <sys/signal.h>
  1467. X#include <sys/resource.h>
  1468. X
  1469. X#include "uw_param.h"
  1470. X#include "uw_clk.h"
  1471. X
  1472. Xstatic struct timeout *pending;
  1473. Xstatic struct timeout *freelist;
  1474. X
  1475. Xint timer_rdy;            /* nonzero when some timeout is ready to run */
  1476. X
  1477. Xclk_timeout(secs, fn, arg)
  1478. Xint secs;
  1479. Xvoid (*fn)();
  1480. Xtoarg_t arg;
  1481. X{
  1482. X    register struct timeout *to, **tol;
  1483. X    register time_t curtime;
  1484. X    extern time_t time();
  1485. X
  1486. X    to = freelist;
  1487. X    if (!to) {
  1488. X        if (!(to = (struct timeout *)malloc(sizeof *to)))
  1489. X            return(-1);
  1490. X    } else
  1491. X        freelist = to->to_next;
  1492. X    to->to_fn = fn;
  1493. X    to->to_arg = arg;
  1494. X
  1495. X    if (secs < 0)
  1496. X        secs = 0;
  1497. X    curtime = time((time_t *)0);
  1498. X    to->to_when = curtime + secs;
  1499. X
  1500. X    tol = &pending;
  1501. X    while (*tol && to->to_when > (*tol)->to_when)
  1502. X        tol = &(*tol)->to_next;
  1503. X    to->to_next = *tol;
  1504. X    *tol = to;
  1505. X
  1506. X    clk_service();
  1507. X    return(0);
  1508. X}
  1509. X
  1510. Xclk_service()
  1511. X{
  1512. X    register struct timeout *to;
  1513. X    register time_t curtime;
  1514. X
  1515. X    curtime = time((time_t *)0);
  1516. X    while ((to=pending) && to->to_when <= curtime) {
  1517. X        pending = to->to_next;
  1518. X        if (to->to_fn) {
  1519. X            (*to->to_fn)(to->to_arg);
  1520. X            to->to_next = freelist;
  1521. X            freelist = to;
  1522. X        }
  1523. X    }
  1524. X
  1525. X    timer_rdy = 0;
  1526. X    if (pending)
  1527. X        (void)alarm((unsigned)(pending->to_when - curtime));
  1528. X}
  1529. X
  1530. Xvoid
  1531. Xclk_alarm()
  1532. X{
  1533. X    /*
  1534. X     * A SIGALRM has been received.
  1535. X     */
  1536. X    timer_rdy = 1;
  1537. X}
  1538. X
  1539. Xclk_init()
  1540. X{
  1541. X    timer_rdy = 0;
  1542. X    (void)signal(SIGALRM, clk_alarm);
  1543. X}
  1544. !EOF!server/uw_clk.c!
  1545. echo x - server/uw_env.c
  1546. sed -e 's/^X//' > server/uw_env.c << '!EOF!server/uw_env.c!'
  1547. X/*
  1548. X *    uw_env - environment manipulation
  1549. X *
  1550. X * Copyright 1985,1986 by John D. Bruner.  All rights reserved.  Permission to
  1551. X * copy this program is given provided that the copy is not sold and that
  1552. X * this copyright notice is included.
  1553. X */
  1554. X
  1555. X#define    MAXENV    128    /* maximum number of arguments in environment */
  1556. X
  1557. Xstatic char *earray[MAXENV+1];
  1558. X
  1559. Xenv_set(env)
  1560. Xchar **env;
  1561. X{
  1562. X    register char **ep1, **ep2, *cp;
  1563. X    char **ep3;
  1564. X    extern char **environ;
  1565. X
  1566. X
  1567. X    /*
  1568. X     * Merge the set of environment strings in "env" into the
  1569. X     * environment.
  1570. X     */
  1571. X
  1572. X    /*
  1573. X     * The first time through, copy the environment from its
  1574. X     * original location to the array "earray".  This makes it a
  1575. X     * little easier to change things.
  1576. X     */
  1577. X
  1578. X    if (environ != earray) {
  1579. X        ep1=environ;
  1580. X        ep2=earray;
  1581. X        while(*ep1 && ep2 <= earray+MAXENV)
  1582. X            *ep2++ = *ep1++;
  1583. X        *ep2++ = (char *)0;
  1584. X        environ = earray;
  1585. X    }
  1586. X
  1587. X
  1588. X    /*
  1589. X     * If "env" is non-NULL, it points to a list of new items to
  1590. X     * be added to the environment.  These replace existing items
  1591. X     * with the same name.
  1592. X     */
  1593. X
  1594. X    if (env) {
  1595. X        for (ep1=env; *ep1; ep1++) {
  1596. X            for (ep2=environ; *ep2; ep2++)
  1597. X                if (!env_cmp(*ep1, *ep2))
  1598. X                    break;
  1599. X            if (ep2 < earray+MAXENV) {
  1600. X                if (!*ep2)
  1601. X                    ep2[1] = (char *)0;
  1602. X                *ep2 = *ep1;
  1603. X            }
  1604. X        }
  1605. X    }
  1606. X
  1607. X
  1608. X    /* Finally, use an insertion sort to put things in order. */
  1609. X
  1610. X    for (ep1=environ+1; cp = *ep1; ep1++) {
  1611. X        for(ep2=environ; ep2 < ep1; ep2++)
  1612. X            if (env_cmp(*ep1, *ep2) < 0)
  1613. X                break;
  1614. X        ep3 = ep2;
  1615. X        for(ep2=ep1; ep2 > ep3; ep2--)
  1616. X            ep2[0] = ep2[-1];
  1617. X        *ep2 = cp;
  1618. X    }
  1619. X}
  1620. X
  1621. X
  1622. Xstatic
  1623. Xenv_cmp(e1, e2)
  1624. Xregister char *e1, *e2;
  1625. X{
  1626. X    register d;
  1627. X
  1628. X    do {
  1629. X        if (d = *e1 - *e2++)
  1630. X            return(d);
  1631. X    } while (*e1 && *e1++ != '=');
  1632. X    return(0);
  1633. X}
  1634. !EOF!server/uw_env.c!
  1635. echo x - server/uw_fd.c
  1636. sed -e 's/^X//' > server/uw_fd.c << '!EOF!server/uw_fd.c!'
  1637. X/*
  1638. X *    uw_fd - file-descriptor/select data
  1639. X *
  1640. X * Copyright 1986 by John D. Bruner.  All rights reserved.  Permission to
  1641. X * copy this program is given provided that the copy is not sold and that
  1642. X * this copyright notice is included.
  1643. X */
  1644. X
  1645. X#include <sys/types.h>
  1646. X
  1647. X#include "uw_param.h"
  1648. X#include "uw_fd.h"
  1649. X
  1650. Xstruct selmask selmask[2];
  1651. Xstruct fdmap fdmap[FD_SETSIZE];
  1652. Xfildes_t nfds;                /* number of file descriptors */
  1653. X
  1654. Xfd_init()
  1655. X{
  1656. X    register fildes_t fd;
  1657. X
  1658. X    nfds = getdtablesize();
  1659. X    if (nfds > FD_SETSIZE)
  1660. X        nfds = FD_SETSIZE;
  1661. X    fdmap[0].f_type = FDT_MAC;
  1662. X    fdmap[1].f_type = FDT_MAC;
  1663. X    fdmap[2].f_type = FDT_DEBUG;
  1664. X    for (fd=3; fd < FD_SETSIZE; fd++) {
  1665. X        fdmap[fd].f_type = FDT_NONE;
  1666. X        (void)close(fd);
  1667. X    }
  1668. X    FD_ZERO(&selmask[0].sm_rd);
  1669. X    FD_ZERO(&selmask[0].sm_wt);
  1670. X    FD_ZERO(&selmask[0].sm_ex);
  1671. X}
  1672. X
  1673. Xfd_exit()
  1674. X{
  1675. X    register fildes_t fd;
  1676. X
  1677. X    for (fd=3; fd < nfds; fd++)
  1678. X        (void)close(fd);
  1679. X}
  1680. !EOF!server/uw_fd.c!
  1681. echo x - server/uw_main.c
  1682. sed -e 's/^X//' > server/uw_main.c << '!EOF!server/uw_main.c!'
  1683. X/*
  1684. X *    uw - UNIX windows program for the Macintosh (host end)
  1685. X *
  1686. X * Copyright 1985,1986 by John D. Bruner.  All rights reserved.  Permission to
  1687. X * copy this program is given provided that the copy is not sold and that
  1688. X * this copyright notice is included.
  1689. X */
  1690. X
  1691. X#include <sys/types.h>
  1692. X#include <sys/file.h>
  1693. X#include <sys/wait.h>
  1694. X#include <sys/time.h>
  1695. X#include <sys/resource.h>
  1696. X#include <sys/ioctl.h>
  1697. X#include <pwd.h>
  1698. X#include <signal.h>
  1699. X#include <errno.h>
  1700. X#include <strings.h>
  1701. X#include <stdio.h>
  1702. X
  1703. X#include "uw_param.h"
  1704. X#include "uw_clk.h"
  1705. X#include "uw_opt.h"
  1706. X#include "uw_win.h"
  1707. X#include "uw_fd.h"
  1708. X#include "uw_pcl.h"
  1709. X#include "uw_ipc.h"
  1710. X#include "openpty.h"
  1711. X
  1712. Xint nflag;            /* no startup file */
  1713. Xint sflag;            /* "secure" (hee hee) -- no network requests */
  1714. Xint errflag;            /* argument error */
  1715. Xchar *rcfile;            /* ".uwrc" file name */
  1716. X
  1717. Xextern void rc_kludge();    /* horrible hack (see rc_kludge()) */
  1718. X
  1719. Xmain(argc, argv)
  1720. Xchar **argv;
  1721. X{
  1722. X    register int c;
  1723. X    register fildes_t fd;
  1724. X    extern int calloptscan;
  1725. X    extern int errno;
  1726. X    extern int optind;
  1727. X    extern char *optarg;
  1728. X
  1729. X    /*
  1730. X     * Make sure we don't accidentally try to run this inside itself.
  1731. X     */
  1732. X    if (getenv(UIPC_ENV)) {
  1733. X        fprintf(stderr, "%s is already running\n", *argv);
  1734. X        exit(1);
  1735. X    }
  1736. X
  1737. X    /*
  1738. X     * Process command-line arguments.
  1739. X     */
  1740. X    while ((c=getopt(argc, argv, "f:ns")) != EOF) {
  1741. X        switch (c) {
  1742. X        case 'f':
  1743. X            if (nflag) {
  1744. X                fprintf(stderr,
  1745. X                    "Cannot specify both \"-f\" and \"-n\"\n");
  1746. X                nflag = 0;
  1747. X            }
  1748. X            rcfile = optarg;
  1749. X            break;
  1750. X        case 'n':
  1751. X            if (rcfile != (char *)0) {
  1752. X                fprintf(stderr,
  1753. X                    "Cannot specify both \"-f\" and \"-n\"\n");
  1754. X                rcfile = (char *)0;
  1755. X            }
  1756. X            nflag = 1;
  1757. X            break;
  1758. X        case 's':
  1759. X            sflag = 1;
  1760. X            break;
  1761. X        case '?':
  1762. X        default:
  1763. X            errflag = 1;
  1764. X            break;
  1765. X        }
  1766. X    }
  1767. X    if (errflag) {
  1768. X        fprintf(stderr, "Usage: \"%s [-f file] [-n] [-s]\"\n", *argv);
  1769. X        exit(1);
  1770. X    }
  1771. X
  1772. X    /*
  1773. X     * Initialize the file descriptor table.
  1774. X     */
  1775. X    fd_init();
  1776. X    FD_SET(0, &selmask[0].sm_rd);
  1777. X
  1778. X    /*
  1779. X     * If we can open the "/etc/utmp" for write, do so.
  1780. X     * Immediately afterwards, we lose any magic powers that
  1781. X     * might have allowed us to do this.
  1782. X     */
  1783. X#ifdef UTMP
  1784. X    fd = open("/etc/utmp", O_WRONLY);
  1785. X    (void)setgid(getgid());
  1786. X    (void)setuid(getuid());
  1787. X    if (fd >= 0)
  1788. X        fdmap[fd].f_type = FDT_OTHER;
  1789. X    utmp_init(fd);
  1790. X#endif
  1791. X
  1792. X    /*
  1793. X     * Initialize the window structures.
  1794. X     */
  1795. X    win_init();
  1796. X
  1797. X    /*
  1798. X     * Initialize timeouts.
  1799. X     */
  1800. X    clk_init();
  1801. X
  1802. X
  1803. X    /*
  1804. X     * Create a UNIX-domain network address, and put its name into
  1805. X     * the environment so that descendents can contact us with new
  1806. X     * window requests.  If we want to be "secure", we don't allow
  1807. X     * any UNIX-domain messages to come in.
  1808. X     */
  1809. X    ipc_init(!sflag);
  1810. X    if (!sflag)
  1811. X        clk_timeout(5, rc_kludge, (toarg_t)0);
  1812. X
  1813. X
  1814. X    /*
  1815. X     * Ignore interrupts, quits, and terminal stops.  Clean up and exit
  1816. X     * if a hangup or termination is received.  Also catch changes in
  1817. X     * child status (so that we can wait for them).  Set up the terminal
  1818. X     * modes.
  1819. X     */
  1820. X    (void)signal(SIGHUP, done);
  1821. X    (void)signal(SIGINT, SIG_IGN);
  1822. X    (void)signal(SIGQUIT, SIG_IGN);
  1823. X    (void)signal(SIGTERM, done);
  1824. X    (void)signal(SIGTSTP, SIG_IGN);
  1825. X    (void)signal(SIGCHLD, cwait);
  1826. X
  1827. X    tty_mode(1);
  1828. X
  1829. X
  1830. X    /*
  1831. X     * Tell the Macintosh to initialize.
  1832. X     */
  1833. X    pcl_entry(0);
  1834. X
  1835. X    
  1836. X    /*
  1837. X     * Create window 1 (to start things off) and wait for input.
  1838. X     * When input is available, process it.
  1839. X     */
  1840. X    if (!nflag)
  1841. X        finduwrc();
  1842. X
  1843. X    while (1) {
  1844. X        CLK_CHECK();
  1845. X        if (calloptscan && protocol->p_chkopt) {
  1846. X            calloptscan = 0;
  1847. X            (*protocol->p_chkopt)(0);
  1848. X        }
  1849. X        selmask[1] = selmask[0];
  1850. X        if (select(nfds, &selmask[1].sm_rd, &selmask[1].sm_wt,
  1851. X            &selmask[1].sm_ex, (struct timeval *)0) < 0) {
  1852. X            if (errno == EINTR)
  1853. X                continue;
  1854. X            perror("select");
  1855. X            done(1);    /* for now -- fix this! */
  1856. X        }
  1857. X        for (fd=0; fd < nfds; fd++) {
  1858. X            if (FD_ISSET(fd, &selmask[1].sm_rd)) {
  1859. X                switch (fdmap[fd].f_type) {
  1860. X                case FDT_MAC:
  1861. X                    PCL_RECV(0, (char *)0, 0);
  1862. X                    break;
  1863. X                case FDT_UDSOCK:
  1864. X                    ipc_udrecv(fd);
  1865. X                    break;
  1866. X                case FDT_ISSOCK:
  1867. X                    ipc_isrecv(fd);
  1868. X                    break;
  1869. X                case FDT_DATA:
  1870. X                    PCL_XMIT(0, fdmap[fd].f_win);
  1871. X                    break;
  1872. X                case FDT_CTL:
  1873. X                    ipc_ctlrecv(0, fd, fdmap[fd].f_win);
  1874. X                    break;
  1875. X                default:
  1876. X                    /* "can't happen" */
  1877. X                    FD_CLR(fd, &selmask[0].sm_rd);
  1878. X                    break;
  1879. X                }
  1880. X            }
  1881. X            if (FD_ISSET(fd, &selmask[1].sm_wt)) {
  1882. X                /* "can't happen" */
  1883. X                FD_CLR(fd, &selmask[0].sm_wt);
  1884. X                break;
  1885. X            }
  1886. X            if (FD_ISSET(fd, &selmask[1].sm_ex)) {
  1887. X                /* "can't happen" */
  1888. X                FD_CLR(fd, &selmask[0].sm_ex);
  1889. X                break;
  1890. X            }
  1891. X        }
  1892. X    }
  1893. X}
  1894. X
  1895. Xfinduwrc()
  1896. X{
  1897. X    register struct passwd *pw;
  1898. X    register char *homedir;
  1899. X
  1900. X    /*
  1901. X     * If the global variable "rcfile" is non-NULL, then it specifies
  1902. X     * the name of the startup file.  Otherwise, the name of the startup
  1903. X     * file is "$HOME/.uwrc".  If $HOME is undefined or null, the password
  1904. X     * file is consulted.  The ".uwrc" file is an executable program or
  1905. X     * "/bin/sh" command file.  (For "csh" (ugh) use "#! /bin/csh".)
  1906. X     *
  1907. X     * Returns 0 if the ".uwrc" file doesn't exist, 1 if it does.  As
  1908. X     * a side-effect, this routine sets the global variable "rcfile"
  1909. X     * to the name of the ".uwrc" file.
  1910. X     */
  1911. X    if (rcfile == (char *)0) {
  1912. X        if ((homedir=getenv("HOME")) == NULL || !*homedir) {
  1913. X            if ((pw = getpwuid(getuid())) != NULL)
  1914. X                homedir = pw->pw_dir;
  1915. X            else
  1916. X                return;
  1917. X        }
  1918. X        rcfile = malloc((unsigned)(strlen(homedir) + sizeof "/.uwrc"));
  1919. X        if (rcfile == (char *)0)
  1920. X            return;
  1921. X        (void)strcpy(rcfile, homedir);
  1922. X        (void)strcat(rcfile, "/.uwrc");
  1923. X    }
  1924. X    if (access(rcfile, F_OK) < 0)
  1925. X        rcfile = (char *)0;
  1926. X}
  1927. X
  1928. Xrunuwrc()
  1929. X{
  1930. X    register int pid;
  1931. X    register fildes_t fd;
  1932. X    struct ptydesc pt;
  1933. X
  1934. X    /*
  1935. X     * We use a real fork (rather than a vfork()) because the parent
  1936. X     * doesn't wait for the child.  The caller knows that the file
  1937. X     * exists; however, it cannot determine whether or not it is
  1938. X     * successfully executed.
  1939. X     *
  1940. X     * We acquire a pseudo-terminal for rather convoluted reasons.
  1941. X     * Programs such as "uwtool" expect to be able to inherit tty
  1942. X     * modes from their controlling terminal.  By the time that we
  1943. X     * reach this point, we've already changed our controlling
  1944. X     * terminal to use cbreak mode with no special characters except
  1945. X     * XON/XOFF.  Therefore, we obtain a pseudo-terminal and
  1946. X     * restore our original modes onto it.  We double-fork (sigh,
  1947. X     * another miserable kludge) so that the server does not have
  1948. X     * to wait for the completion of the ".uwrc" file.  (The child
  1949. X     * waits for the grandchild so that the master side of the pty
  1950. X     * remains open until the grandchild is finished.)
  1951. X     */
  1952. X    if (openpty(&pt) < 0)
  1953. X        return;
  1954. X    while ((pid = fork()) < 0)
  1955. X        sleep(5);
  1956. X    if (pid > 0) {
  1957. X        (void)close(pt.pt_pfd);
  1958. X        (void)close(pt.pt_tfd);
  1959. X    } else {
  1960. X        /* child */
  1961. X        while ((pid = fork()) < 0)
  1962. X            sleep(5);
  1963. X        if (pid > 0) {
  1964. X            while (wait((int *)0) < 0 && errno == EINTR)
  1965. X                ;
  1966. X            _exit(1);
  1967. X            /*NOTREACHED*/
  1968. X        } else {
  1969. X            /* grandchild */
  1970. X            (void)setgid(getgid());
  1971. X            (void)setuid(getuid());
  1972. X            (void)close(pt.pt_pfd);
  1973. X            if (pt.pt_tfd != 0)
  1974. X                (void)dup2(pt.pt_tfd, 0);
  1975. X            if (pt.pt_tfd != 1);
  1976. X                (void)dup2(pt.pt_tfd, 1);
  1977. X            if (pt.pt_tfd != 2)
  1978. X                (void)dup2(pt.pt_tfd, 2);
  1979. X            win_envinit(defwtype, (long)0);
  1980. X            (void)signal(SIGHUP, SIG_DFL);
  1981. X            (void)signal(SIGINT, SIG_DFL);
  1982. X            (void)signal(SIGQUIT, SIG_DFL);
  1983. X            (void)signal(SIGTERM, SIG_DFL);
  1984. X            (void)signal(SIGTSTP, SIG_IGN);
  1985. X            (void)signal(SIGCHLD, SIG_DFL);
  1986. X            (void)ioctl(open("/dev/tty",O_RDWR),
  1987. X                (int)TIOCNOTTY, (char *)0);
  1988. X            (void)open(pt.pt_tname, O_RDONLY);
  1989. X            for (fd=3; fd < nfds; fd++)
  1990. X                (void)close(fd);
  1991. X            tty_mode(0);
  1992. X            (void)execlp(rcfile, rcfile, (char *)0);
  1993. X            (void)execl("/bin/sh", "sh", rcfile, (char *)0);
  1994. X            _exit(1);
  1995. X            /*NOTREACHED*/
  1996. X        }
  1997. X    }
  1998. X}
  1999. X
  2000. Xvoid
  2001. Xrc_kludge()
  2002. X{
  2003. X    static int firsttime = 1;
  2004. X
  2005. X    /*
  2006. X     * A problem which occurs with ".uwrc" file handling is that
  2007. X     * the "rc" file is interpreted immediately after the server
  2008. X     * begins, i.e. before it and the Macintosh have (possibly)
  2009. X     * changed from the default protocol to an extended one.
  2010. X     *
  2011. X     * To get around this problem, if a ".uwrc" file exists, it
  2012. X     * is not executed immediately.  Instead, it will be executed
  2013. X     * when this routine is called, either directly by pcl_newpcl()
  2014. X     * when the protocol changes, or after an initial timeout.
  2015. X     *
  2016. X     * It is most unfortunate that "pcl_newpcl" must call "upwards"
  2017. X     * into this source file.
  2018. X     */
  2019. X    if (firsttime) {
  2020. X        firsttime = 0;
  2021. X        if (rcfile != (char *)0)
  2022. X            runuwrc();
  2023. X        else
  2024. X            (void)PCL_NEWW(0, WC_INTERNAL, defwtype, (nwin_t)1, 0L,
  2025. X                (fildes_t)-1, (fildes_t)-1);
  2026. X    }
  2027. X}
  2028. X
  2029. Xvoid
  2030. Xdone(s)
  2031. X{
  2032. X    /*
  2033. X     * Clean up and exit.  It is overkill to close all of the file
  2034. X     * descriptors, but it causes no harm.
  2035. X     */
  2036. X    pcl_exit(0);
  2037. X    utmp_exit();
  2038. X    fd_exit();
  2039. X    ipc_exit();
  2040. X    tty_mode(0);
  2041. X    exit(s);
  2042. X}
  2043. X
  2044. Xvoid
  2045. Xcwait()
  2046. X{
  2047. X    register int pid;
  2048. X    union wait status;
  2049. X    struct rusage rusage;
  2050. X
  2051. X    /*
  2052. X     * Collect dead children.  Restart any children that have stopped.
  2053. X     */
  2054. X    while ((pid=wait3(&status, WNOHANG|WUNTRACED, &rusage)) > 0)
  2055. X        if (WIFSTOPPED(status))
  2056. X            (void)kill(pid, SIGCONT);
  2057. X}
  2058. !EOF!server/uw_main.c!
  2059. exit 0
  2060. : end of shell archive
  2061.