home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Garbo
/
Garbo.cdr
/
mac
/
unix
/
uw_shar.sit
/
uw-42-part3.shar
< prev
next >
Wrap
Text File
|
1989-09-14
|
61KB
|
2,061 lines
#Date: Wed, 2 Mar 88 10:00:46 PST
#From: rothberg@polya.stanford.edu (Edward Rothberg)
#Subject: UW 4.2 part 3 of 8
: This is a shar archive. Extract with sh, not csh.
if test ! -d doc; then
echo mkdir doc
mkdir doc
fi
if test ! -d h; then
echo mkdir h
mkdir h
fi
if test ! -d server; then
echo mkdir server
mkdir server
fi
echo x - doc/uwterm.l
sed -e 's/^X//' > doc/uwterm.l << '!EOF!doc/uwterm.l!'
X.TH UWTERM 1 "20 September 1986"
X.UC 4
X.SH NAME
Xuwterm \- (possibly remote) terminal emulation for UW
X.SH SYNOPSIS
X.B uwterm
X[
X.BI \-w type
X] [
X.BI \-t title
X] [
X.BI \-n serveraddr
X] [
X.BI \-l loginname
X] [ host ]
X.SH DESCRIPTION
X.I Uwterm
Xis a utility program for use with the
X.I uw
Xmultiple-window interface to UNIX.
XIt creates a window in which a terminal session
Xis conducted.
XIf no arguments are given
Xthe terminal is created on the local machine.
XA hostname may be specified;
Xin this case,
Xthe terminal is created on the remote host.
X.RI ( Uwterm
Xmust be installed on the remote host
Xand permissions for
X.I rsh
Xmust have been set up correctly
Xin order for this to work.)
X.I Uwterm
Xexamines the `SHELL' environment variable
Xand executes the program named there.
XThe `\-l' option
Xcan be used to specify the login name under which
Xthe remote process will be executed
X(the default is the current account).
X.PP
XUnlike
X.IR uwtool ,
X.I uwterm
Xdoes not exit until the window it has created
Xis destroyed;
Xhence,
Xit will usually be desirable to run it in the background.
X.PP
XNormally,
Xthe terminal type of the new window is inherited from
Xthe window in which
X.I uwterm
Xis run.
XIt is possible to override this with the `\-w' option
X(`w' stands for `window emulation type').
XThe window types are the same as those accepted by the
X.I uwtool
Xprogram.
X.PP
XThe title of the newly-created window may be
Xspecified with the `\-t' option.
XIf this option is omitted,
Xthe title will be the host name.
X.PP
XNormally
X.I uwterm
Xwill examine the environment for the variable `UW_INET'
Xand will connect to the
X.I uw
Xserver with that address.
XThe `\-n' flag can be used to specify an alternate
Xserver network address.
XThe address should have the form `xxxxxxxx.ddd'
Xwhere `x' is a hexadecimal digit
Xand `d' is a decimal digit.
XThe hexadecimal number is the host's Internet address
Xand the decimal number is the port on which the
Xserver is listening for connections.
XThe `\-n' flag is used by
X.I uwterm
Xitself:
Xit creates a remote terminal by invoking itself on
Xthe remote machine
X(using
X.IR rsh )
Xand specifying the network address
Xof the local server.
X.SH LIMITATIONS
X.I Uwterm
Xis of no use on unix unless
Xthe server is running and
X.I uw
Xis being run on the Macintosh.
X.br
XIf there is a stream of output in one window there will be lag in
Xrecognizing characters typed in another.
X.br
XThere are so many levels of buffering
Xthat user-entered CTL-S/CTL-Q flow control is
Xpractically useless,
Xeven at relatively low baud rates.
X.SH SEE ALSO
Xrsh(1), uw(L), uwtitle(L), uwtool(L)
X.br
X.I uw
XMacintosh documentation
X(`UW \(em A Multiple-Window Interface to UNIX')
X.br
X`The UW Programmer's Library'
X.SH AUTHOR
XJohn Bruner, Lawrence Livermore National Laboratory, 9/86.
X.SH BUGS
XThere are so many levels of buffering that typing
XXON and XOFF
Xto suspend output within a window
Xis futile.
!EOF!doc/uwterm.l!
echo x - doc/uwtitle.l
sed -e 's/^X//' > doc/uwtitle.l << '!EOF!doc/uwtitle.l!'
X.TH UWTITLE 1 "14 September 1986"
X.UC 4
X.SH NAME
Xuwtitle \- retitle UW window
X.SH SYNOPSIS
X.B uwtitle
X[
X.BI \-i id
X]
Xstring ...
X.SH DESCRIPTION
X.I Uwtitle
Xis a utility program for use with the
X.I uw
Xmultiple-window interface to UNIX.
XIt retitles an existing window.
XThe title is specified as one or more
Xstrings
X(in the same fashion as arguments to the
X.I echo
Xprogram).
XThe `\-i' option can be used to specify
Xthe ID of the window to be retitled;
Xotherwise,
Xthe current window will be affected.
X.SH LIMITATIONS
X.I Uwtitle
Xis of no use on unix unless
Xthe server is running and
X.I uw
Xis being run on the Macintosh.
X.SH SEE ALSO
Xecho(1), uw(L), uwtool(L), uwterm(L)
X.br
X.I uw
XMacintosh documentation (`UW \(em A Multiple-Window Interface to UNIX')
X.br
X`The UW Programmer's Library'
X.SH AUTHOR
XJohn Bruner, Lawrence Livermore National Laboratory 9/86
!EOF!doc/uwtitle.l!
echo x - doc/uwtool.l
sed -e 's/^X//' > doc/uwtool.l << '!EOF!doc/uwtool.l!'
X.TH UWTOOL 1 "14 September 1986"
X.UC 4
X.SH NAME
Xuwtool \- command-in-window utility for UW
X.SH SYNOPSIS
X.B uwtool
X[
X.BI \-w type
X] [
X.BI \-t title
X] [
X.B \-v
X] [ command [ arg1 arg2 ... ] ]
X.SH DESCRIPTION
X.I Uwtool
Xis a utility program for use with the
X.I uw
Xmultiple-window interface to UNIX.
XIf no arguments are given,
Xit creates a new `terminal' running the shell named in the
Xenvironment variable `SHELL'.
XIf a process is named,
Xit will create a new window with that process running in it,
Xand when that process is terminated the window will disappear.
X(i.e. `uwtool vi foo' will create a new window with vi,
Xediting the file foo,
Xbut the window will go away when vi is exited)
XAny arguments after the process name are passed as arguments to that process.
X.I Uwtool
Xexits as soon as the window is created.
X.PP
XNormally,
Xthe terminal type of the new window is inherited from
Xthe window in which
X.I uwtool
Xis run.
XIt is possible to override this with the `\-w' option
X(`w' stands for `window emulation type').
XThe following values are recognized:
X.TP 8n
Xadm31
XLear Siegler ADM-31
X.TP
Xadm3a
XLear Siegler ADM-3a (uses ADM-31)
X.TP
Xtek4010
XTektronix 4010
X.TP
Xtek
XTektronix 4010
X.TP
Xvt52
XDigital Equipment Corporation VT-52
X.TP
Xansi
XANSI-compatible terminal
X.TP
Xaaa-24
X24-line Ann Arbor Ambassador
X(uses ANSI emulation)
X.PP
XIf an unknown type is specified,
Xthe ADM-31 emulation will be used.
X.PP
XThe title of the newly-created window may be
Xspecified with the `\-t' option.
XIf this option is omitted,
Xthe window title will be the command name.
X.PP
XThe `\-v' flag causes
X.I uwtool
Xto print the 32-bit window identifier on
Xthe standard output.
XThis value can be used as an argument to a subsequent
Xcommand,
Xfor example
X.IR uwtitle .
X.SH LIMITATIONS
X.I Uwtool
Xis of no use on unix unless
Xthe server is running and
X.I uw
Xis being run on the Macintosh.
X.br
XIf there is a stream of output in one window there will be lag in
Xrecognizing characters typed in another.
X.SH SEE ALSO
Xuw(L), uwtitle(L), uwterm(L)
X.br
X.I uw
XMacintosh documentation
X(`UW \(em A Multiple-Window Interface to UNIX')
X.br
X`The UW Programmer's Library'
X.SH AUTHOR
XProgram written by John Bruner, Lawrence Livermore Laboratories 7/85,11/85,9/86
X.br
XThis document is based upon a document created by
Xby Chris Borton, UC San Diego 11/13/85,
Xedited 9/86 by John Bruner.
!EOF!doc/uwtool.l!
echo x - h/openpty.h
sed -e 's/^X//' > h/openpty.h << '!EOF!h/openpty.h!'
X/*
X * This file defines the "ptydesc" structure which is returned
X * by the routine "openpty".
X */
X
Xstruct ptydesc {
X int pt_pfd; /* file descriptor of master side */
X int pt_tfd; /* file descriptor of slave side */
X char *pt_pname; /* master device name */
X char *pt_tname; /* slave device name */
X};
!EOF!h/openpty.h!
echo x - h/uw_clk.h
sed -e 's/^X//' > h/uw_clk.h << '!EOF!h/uw_clk.h!'
X/*
X * uw_clk - timer support for UW
X *
X * Copyright 1986 by John D. Bruner. All rights reserved. Permission to
X * copy this program is given provided that the copy is not sold and that
X * this copyright notice is included.
X */
X
X#ifndef UW_CLK
X#define UW_CLK
X
X/*
X * Events which are supposed to occur at a certain time are handled by
X * setting "timeout"s. The list of timeouts is sorted in order of
X * occurrence. The "alarm" mechanism is used to send SIGALRM when the
X * first timeout expires. However, the timeout is not processed
X * immediately. Instead, it will be processed upon exit from the
X * select() in main(). This prevents timeouts from happening at
X * inappropriate times.
X *
X * The resolution of timeouts is in seconds. The server doesn't need
X * any better resolution, and this allows all of the hair associated with
X * (struct timeval) and (struct itimerval) types to be avoided.
X */
X
X#define CLK_HZ 1 /* one tick/second */
X
Xtypedef long toarg_t;
X
Xstruct timeout {
X struct timeout *to_next;
X time_t to_when;
X void (*to_fn)();
X toarg_t to_arg;
X};
X
Xextern int timer_rdy;
X
X#define CLK_CHECK() if (timer_rdy) clk_service(); else
X#endif
!EOF!h/uw_clk.h!
echo x - h/uw_err.h
sed -e 's/^X//' > h/uw_err.h << '!EOF!h/uw_err.h!'
X/*
X * uw error codes
X *
X * Copyright 1986 by John D. Bruner. All rights reserved. Permission to
X * copy this program is given provided that the copy is not sold and that
X * this copyright notice is included.
X */
X
X#ifndef UW_ERR
X#define UW_ERR
X
Xtypedef int uwerr_t;
X
X#define UWE_NONE 0 /* no error */
X#define UWE_ERRNO 1 /* system call error, consult errno */
X#define UWE_NXTYPE 2 /* nonexistent window type */
X#define UWE_DUPID 3 /* window ID duplicated (in use) */
X#define UWE_NOTIMPL 4 /* operation not implemented yet */
X#define UWE_NXSERV 5 /* non-existent server */
X#define UWE_NOMEM 6 /* unable to allocate required memory */
X#define UWE_INVAL 7 /* invalid argument to function */
X#define UWE_NOCTL 8 /* no control file descriptor */
X
X#endif
!EOF!h/uw_err.h!
echo x - h/uw_fd.h
sed -e 's/^X//' > h/uw_fd.h << '!EOF!h/uw_fd.h!'
X/*
X * uw_fd - file-descriptor/select data
X *
X * Copyright 1986 by John D. Bruner. All rights reserved. Permission to
X * copy this program is given provided that the copy is not sold and that
X * this copyright notice is included.
X */
X
X#ifndef UW_FD
X#define UW_FD
X
X#include "uw_param.h"
X
X/*
X * If FD_SET and friends aren't defined in <sys/types.h>, then we
X * provide simple definitions here.
X */
X#ifndef FD_SET
X#define FD_SET(n,p) ((p)->fds_bits[0] |= (1 << (n)))
X#define FD_CLR(n,p) ((p)->fds_bits[0] &= ~(1 << (n)))
X#define FD_ISSET(n,p) ((p)->fds_bits[0] & (1 << (n)))
X#define FD_ZERO(p) ((p)->fds_bits[0] = 0)
X#define FD_SETSIZE (NBBY*sizeof(long))
X#endif
X
X/*
X * We use file descriptors for several different things. "fdmap" associates
X * a file descriptor number with its use.
X */
Xtypedef enum { /* file descriptor type */
X FDT_NONE, /* not in use */
X FDT_DATA, /* data connection for window */
X FDT_CTL, /* control connection for window */
X FDT_MAC, /* tty line which talks to Mac */
X FDT_UDSOCK, /* UNIX-domain datagram socket */
X FDT_ISSOCK, /* Internet-domain stream sock */
X FDT_DEBUG, /* debugging use */
X FDT_OTHER /* other uses */
X} fdtype_t;
X
Xstruct fdmap {
X fdtype_t f_type; /* file descriptor type */
X struct window *f_win; /* associate window (if any) */
X};
X
Xstruct selmask {
X struct fd_set sm_rd;
X struct fd_set sm_wt;
X struct fd_set sm_ex;
X};
X
Xextern struct fdmap fdmap[FD_SETSIZE];
Xextern fildes_t nfds;
Xextern struct selmask selmask[2];
X#endif
!EOF!h/uw_fd.h!
echo x - h/uw_ipc.h
sed -e 's/^X//' > h/uw_ipc.h << '!EOF!h/uw_ipc.h!'
X/*
X * uw IPC definitions
X *
X * Copyright 1986 by John D. Bruner. All rights reserved. Permission to
X * copy this program is given provided that the copy is not sold and that
X * this copyright notice is included.
X */
X
X#ifndef UW_IPC
X#define UW_IPC
X
X/*
X * UW accepts network connections in both the UNIX domain and the
X * Internet domain. UNIX domain datagrams are used by processes on
X * the local machine to create new windows and to change the value
X * of window parameters (window options). TCP (Internet stream)
X * connections are used by local and non-local processes which wish
X * to handle their own host activity (e.g. pseudo-terminal handling).
X *
X * Some of the definitions in this file duplicate definitions in the
X * UW server source code, because this file is also intended for use
X * with the UW library.
X *
X * The code which performs byte-order conversions knows the size of the
X * types defined in this file (since there is no typeof() operator).
X */
X
X#define UIPC_ENV "UW_UIPC" /* Unix-domain port environment var */
X#define INET_ENV "UW_INET" /* Internet-domain port environ var */
X
Xtypedef long uwid_t; /* unique window identifier */
X
Xtypedef short uwcmd_t; /* commands: */
X#define UWC_NEWW 0 /* create new window */
X#define UWC_NEWT 1 /* create new tty window */
X#define UWC_STATUS 2 /* creation status message */
X#define UWC_KILLW 3 /* kill existing window */
X#define UWC_OPTION 4 /* act upon window option */
X
Xtypedef short uwoptcmd_t; /* option subcommands: */
X#define UWOC_SET 0 /* set value of option */
X#define UWOC_ASK 2 /* ask for value of option */
X#define UWOC_DO 4 /* report changes in value */
X#define UWOC_DONT 5 /* don't report changes */
X#define UWOC_WILL 6 /* will report changes */
X#define UWOC_WONT 7 /* won't report changes */
X
Xtypedef short uwtype_t; /* window type (see also uw_win.h): */
X#define UWT_ADM31 0 /* ADM-31 */
X#define UWT_VT52 1 /* VT-52 */
X#define UWT_ANSI 2 /* ANSI */
X#define UWT_TEK4010 3 /* Tektronix 4010 */
X#define UWT_FTP 4 /* file transfer */
X#define UWT_PRINT 5 /* output to Macintosh printer */
X#define UWT_PLOT 6 /* plot window */
X
Xtypedef short uwopt_t; /* window option number: */
X#define UWOP_VIS 1 /* visibility */
X#define UWOP_TYPE 2 /* window type */
X#define UWOP_POS 3 /* window position */
X#define UWOP_TITLE 4 /* window title */
X#define UWOP_WSIZE 5 /* window size (in bits) */
X
X#define UWOP_TSIZE 8 /* terminal size (row,col) */
X#define UWOP_TFONTSZ 9 /* small/large font size */
X#define UWOP_TCLIPB 10 /* clipboard/mouse encoding */
X#define UWOP_TBELL 11 /* audible, visual bell */
X#define UWOP_TCURS 12 /* cursor shape */
X
Xunion uwoptval {
X unsigned char uwov_1bit;
X unsigned char uwov_6bit;
X unsigned short uwov_12bit;
X struct {
X unsigned short v,h;
X } uwov_point;
X char uwov_string[256];
X};
X
X
X/*
X * UWC_NEWW: create a new window
X *
X * This command is only valid when it is sent as the first message on an
X * Internet stream socket. The remote port is the data fd for the window.
X * If a control fd is desired, its port number is contained in "uwnt_ctlport"
X */
Xstruct uwneww {
X uwid_t uwnw_id; /* unique window identifier */
X uwtype_t uwnw_type; /* window type */
X short uwnw_ctlport; /* port number of control fd */
X};
X
X/*
X * UWC_NEWT: create a new tty window
X *
X * This command is only valid when it is sent as a datagram to the Unix-domain
X * socket. It must be accompanied by an access right (file descriptor) for
X * the master side of a pty. The server takes over all responsibilities for
X * this window. "uwnt_pty" is variable-length.
X */
Xstruct uwnewt {
X uwid_t uwnt_id; /* unique window identifier */
X uwtype_t uwnt_type; /* window type */
X char uwnt_pty[1]; /* name of associated pty */
X};
X
X/*
X * UWC_STATUS: status report for UWC_NEWW
X *
X * This type of packet is sent by the server to the data fd in response
X * to a UWC_NEWW. It specifies whether the window was successfully
X * created and what unique ID was assigned.
X */
Xstruct uwstatus {
X uwid_t uwst_id; /* unique window identifier */
X short uwst_err; /* error status */
X short uwst_errno; /* UNIX error code (see <errno.h>) */
X};
X
X/*
X * UWC_KILLW: kill the window
X *
X * This command may be sent to either the Unix-domain socket or the control
X * file descriptor of an external window. In the latter case, "uwkw_id"
X * must match the ID of the window associated with the file descriptor.
X */
Xstruct uwkillw {
X uwid_t uwkw_id; /* unique window identifier */
X};
X
X/*
X * UWC_OPTION: act upon window option
X *
X * This command may be sent to either the Unix-domain socket or the control
X * file descriptor of an external window. In the former case, only the
X * UWOC_SET command is processed.
X */
Xstruct uwoption {
X uwid_t uwop_id; /* unique window identifier */
X uwopt_t uwop_opt; /* option number */
X uwoptcmd_t uwop_cmd; /* option subcommand */
X union uwoptval uwop_val; /* option value (for UWOC_SET) */
X};
X
Xstruct uwipc {
X unsigned short uwip_len; /* length of this message */
X uwcmd_t uwip_cmd; /* command (message type) */
X union {
X struct uwneww uwipu_neww;
X struct uwnewt uwipu_newt;
X struct uwstatus uwipu_status;
X struct uwkillw uwipu_killw;
X struct uwoption uwipu_option;
X } uwip_u;
X#define uwip_neww uwip_u.uwipu_neww
X#define uwip_newt uwip_u.uwipu_newt
X#define uwip_status uwip_u.uwipu_status
X#define uwip_killw uwip_u.uwipu_killw
X#define uwip_option uwip_u.uwipu_option
X};
X
X#endif
!EOF!h/uw_ipc.h!
echo x - h/uw_opt.h
sed -e 's/^X//' > h/uw_opt.h << '!EOF!h/uw_opt.h!'
X/*
X * uw window options
X *
X * Copyright 1986 by John D. Bruner. All rights reserved. Permission to
X * copy this program is given provided that the copy is not sold and that
X * this copyright notice is included.
X *
X * Some protocols support the transmission of window options. A window
X * option is a parameter (or collection of related parameters) which
X * describes the layout, appearance, or other characteristic of a
X * window. Some options are common to all window types, while others
X * are window emulation-specific.
X *
X * Window options may be "set" by one side on its own initiative or in
X * response to an "inquiry" from the other side. In addition, one side
X * may request that the other side "report" changes in options.
X *
X * Options are passed as part of a "new window" command or as part of
X * an "option" command (as defined by the protocol, above). The option
X * format has been chosen to minimize the need for protocol encoding
X * of special or meta characters.
X */
X
X#ifndef UW_OPT
X#define UW_OPT
X
Xtypedef unsigned int woptcmd_t; /* window option command: */
X#define WOC_SET 0 /* request current option value */
X#define WOC_INQUIRE 2 /* report current option value */
X#define WOC_DO 4 /* do report changes to option */
X#define WOC_DONT 5 /* don't report changes */
X#define WOC_WILL 6 /* will report changes */
X#define WOC_WONT 7 /* won't report changes */
X#define WOC_MASK 7 /* mask */
X#define WOC_BADCMD(n) ((n)==1 || (n)==3)
X
X/*
X * Option commands include an option number specifier. If the option
X * number is in the range 1-14 a short-form specifier can be used;
X * otherwise, a long-form specifier must be used. Option (sub)command
X * bytes consist of 7 bits of data. The lower order 3 bits specify the
X * option command. The next higher 4 bits specify the option number.
X * The value zero is reserved (as described below). If the option
X * number is greater than 14, these four bits specify 017 (15) and the
X * option number is specified in a second byte. The value is encoded
X * by adding ' ' to the option number. Multiple options may be specified
X * in one command -- the last option is followed by a reference to
X * "option" 0 (as an endmarker).
X */
X
Xtypedef unsigned int woption_t; /* window option number: */
X#define WONUM_MIN 1 /* minimum option number */
X#define WONUM_GENERIC 7 /* maximum generic option number */
X#define WONUM_SHORT 14 /* maximum short option number */
X#define WONUM_MAX 31 /* maximum option number */
X#define WONUM_MASK (017<<3) /* mask for extraction */
X#define WONUM_USELONG(n) ((unsigned)(n) > WONUM_SHORT)
X#define WONUM_SENCODE(n) (((n)&017)<<3) /* short encoding function */
X#define WONUM_SDECODE(b) (((b)>>3)&017) /* short decoding function */
X#define WONUM_LPREFIX (017<<3) /* long encoding prefix */
X#define WONUM_LENCODE(n) ((n)+' ') /* long encoding function */
X#define WONUM_LDECODE(c) (((c)&0177)-' ') /* long decoding function */
X
X
X/*
X * The following option numbers are generic (recognized for all window
X * types):
X */
X#define WOG_END 0 /* [endmarker] */
X#define WOG_VIS 1 /* 0=invisible, 1=visible */
X#define WOG_TYPE 2 /* window emulation type (see below) */
X#define WOG_POS 3 /* window position on screen */
X#define WOG_TITLE 4 /* window title */
X#define WOG_SIZE 5 /* window size (in bits) */
X#define WOG_6 6 /* unassigned, reserved */
X#define WOG_7 7 /* unassigned, reserved */
X
X/*
X * Option arguments immediately follow option (sub)command bytes. They are
X * encoded to prevent interference with flow-control and IAC recognition.
X * Three types of options are recognized: non-graphic character strings of
X * fixed length, general character strings of variable length, and binary
X * numbers of fixed width.
X *
X * Non-graphic character strings are transmitted directly. They CANNOT
X * include IAC, XON, or XOFF and should not include "meta" characters.
X *
X * General character strings are encoded in the UW protocol fashion: "meta"
X * characters and special characters are escaped. The string is terminated
X * with a null byte. The string may not exceed some predetermined maximum
X * number of characters (which may be less than or equal to 256, including
X * the terminating null byte).
X *
X * Binary numbers are transmitted in 6-bit chunks, least-significant bits
X * first. The number of 6-bit chunks required depends upon the width of
X * the number. The 0100 bit in each byte is always set to prevent
X * collisions with special characters (such as flow control and IAC).
X */
X
X/*
X * Implementation:
X *
X * Arrays of type "woptarg_t" are used to describe the arguments associated
X * with each option. (Note that arguments are associated only with
X * the "set" option subcommand.)
X */
X
Xtypedef unsigned woptarg_t; /* option argument type: */
X#define WOA_END 0 /* endmarker */
X#define WOA_CHARS(n) ((1<<8)|(n)) /* "n" untranslated characters */
X#define WOA_STRING(m) ((2<<8)|(m)) /* string of max length "m" */
X#define WOA_UDATA(b) ((3<<8)|(b)) /* binary number "b" bits wide */
X#define WOA_CMDMASK 0177400 /* command mask */
X
Xtypedef long woptbmask_t; /* option bitmask (>= 32 bits wide) */
X#define WOPT_SET(mask,bit) ((mask) |= (1<<(bit)))
X#define WOPT_CLR(mask,bit) ((mask) &= ~(1<<(bit)))
X#define WOPT_ISSET(mask,bit) ((mask) & (1<<(bit)))
X
Xstruct woptdefn {
X woptbmask_t wod_pending; /* pending notifications to Mac */
X woptbmask_t wod_inquire; /* pending inquiries from Mac */
X woptbmask_t wod_do; /* pending DO commands to Mac */
X woptbmask_t wod_dont; /* pending DONT commands to Mac */
X woptbmask_t wod_askrpt; /* reports (of changes) we ask for */
X struct woptlst {
X woptarg_t *wol_argdefn; /* option argument definition */
X char *(*wol_get)(); /* called to get option value */
X void (*wol_set)(); /* called to set option value */
X void (*wol_ext)(); /* called for external window */
X } wod_optlst[WONUM_MAX+1];
X};
X
X/*
X * The following structure is used by routines that fetch and set option
X * values.
X */
Xunion optvalue {
X unsigned char ov_udata1;
X unsigned char ov_udata2;
X unsigned char ov_udata6;
X unsigned short ov_udata12;
X struct {
X unsigned short v,h;
X } ov_point;
X char ov_string[256];
X};
X
X/*
X * When it is necessary to convert between host byte order and network
X * byte order, opt_netadj() is called. A pointer to the following
X * structure is passed.
X */
Xstruct netadj {
X short (*na_short)();
X long (*na_long)();
X unsigned short (*na_ushort)();
X unsigned long (*na_ulong)();
X};
X
X#endif
!EOF!h/uw_opt.h!
echo x - h/uw_param.h
sed -e 's/^X//' > h/uw_param.h << '!EOF!h/uw_param.h!'
X/*
X * uw parameters
X *
X * Copyright 1986 by John D. Bruner. All rights reserved. Permission to
X * copy this program is given provided that the copy is not sold and that
X * this copyright notice is included.
X */
X
X/*
X * This file exists because #include file definitions aren't in the same
X * place on all machines. Also, it seems pointless to drag in all of
X * <stdio.h> just to define NULL. Finally, a few declarations are
X * sufficiently global that this is the most logical place to put them.
X *
X * This file should be #included after all of the system include files
X * (e.g. <sys/types.h>) but before any other UW include files.
X */
X#ifndef UW_PARAM
X#define UW_PARAM
X
Xtypedef int fildes_t; /* this really should be in <sys/types.h> */
X
X#ifndef NBBY /* this is in <sys/types.h> in 4.3BSD */
X#define NBBY 8 /* (number of bits/byte) */
X#endif
X
X#ifndef NULL
X#define NULL 0
X#endif
X
Xextern char *malloc();
Xextern char *mktemp();
Xextern char *getenv();
Xextern void done();
Xextern void cwait();
X
X#endif
!EOF!h/uw_param.h!
echo x - h/uw_pcl.h
sed -e 's/^X//' > h/uw_pcl.h << '!EOF!h/uw_pcl.h!'
X/*
X * uw protocol
X *
X * Copyright 1985,1986 by John D. Bruner. All rights reserved. Permission to
X * copy this program is given provided that the copy is not sold and that
X * this copyright notice is included.
X */
X
X#ifndef UW_PCL
X#define UW_PCL
X
X#include "uw_win.h"
X
X/* UW may operate over connections which speak one of several protocols.
X * Internally these protocols are assigned numbers starting at zero.
X * Three such protocols are currently defined:
X *
X * 0: no special protocol
X * 1: original UW (v1.6, v2.10) protocol
X * 2: extended protocol (v3.x)
X */
X
X/*
X * Protocol 0:
X *
X * The connection between the Macintosh and the host is simply a serial
X * line. Flow control may be enabled, but no special commands are
X * recognized. Only one active window is supported. This "protocol"
X * does not require the UW server; hence, there is no need to support it.
X */
X
X/*
X * Protocol 1: (original UW protocol)
X *
X * Two types of information are exchanged through the 7-bit serial line:
X * ordinary data and command bytes. Command bytes are preceeded by
X * an IAC byte. IAC bytes and literal XON/XOFF characters (those which
X * are not used for flow control) are sent by a P1_FN_CTLCH command.
X * Characters with the eighth bit set (the "meta" bit) are prefixed with
X * a P1_FN_META function.
X *
X * The next most-significant bit in the byte specifies the sender and
X * recipient of the command. If this bit is clear (0), the command byte
X * was sent from the host computer to the Macintosh; if it is set (1)
X * the command byte was sent from the Macintosh to the host computer.
X * This prevents confusion in the event that the host computer
X * (incorrectly) echos a command back to the Macintosh.
X *
X * The remaining six bits are partitioned into two fields. The low-order
X * three bits specify a window number from 1-7 (window 0 is reserved for
X * other uses) or another type of command-dependent parameter. The next
X * three bits specify the operation to be performed by the recipient of
X * the command byte.
X *
X * Note that the choice of command bytes prevents the ASCII XON (021) and
X * XOFF (023) characters from being sent as commands. P1_FN_ISELW commands
X * are only sent by the Macintosh (and thus are tagged with the P1_DIR_MTOH
X * bit). Since XON and XOFF data characters are handled via P1_FN_CTLCH,
X * this allows them to be used for flow control purposes.
X */
X#define P1_IAC 0001 /* interpret as command */
X#define P1_DIR 0100 /* command direction: */
X#define P1_DIR_HTOM 0000 /* from host to Mac */
X#define P1_DIR_MTOH 0100 /* from Mac to host */
X#define P1_FN 0070 /* function code: */
X#define P1_FN_NEWW 0000 /* new window */
X#define P1_FN_KILLW 0010 /* kill (delete) window */
X#define P1_FN_ISELW 0020 /* select window for input */
X#define P1_FN_OSELW 0030 /* select window for output */
X#define P1_FN_META 0050 /* add meta to next data char */
X#define P1_FN_CTLCH 0060 /* low 3 bits specify char */
X#define P1_FN_MAINT 0070 /* maintenance functions */
X#define P1_WINDOW 0007 /* window number mask */
X#define P1_CC 0007 /* control character specifier: */
X#define P1_CC_IAC 1 /* IAC */
X#define P1_CC_XON 2 /* XON */
X#define P1_CC_XOFF 3 /* XOFF */
X#define P1_MF 0007 /* maintenance functions: */
X#define P1_MF_ENTRY 0 /* beginning execution */
X#define P1_MF_ASKPCL 2 /* request protocol negotiation */
X#define P1_MF_CANPCL 3 /* suggest protocol */
X#define P1_MF_SETPCL 4 /* set current protocol */
X#define P1_MF_EXIT 7 /* execution terminating */
X#define P1_NWINDOW 7 /* maximum number of windows */
X
X/*
X * Protocol 2: (extended UW protocol)
X *
X * Protocol 2 is an extension of protocol 1. The P2_FN_NEWW command and
X * the new command P2_FN_WOPT communicate window options between the host
X * and the Macintosh. (See "uw_opt.h" for details.)
X */
X#define P2_IAC P1_IAC /* interpret as command */
X#define P2_DIR P1_DIR /* command direction: */
X#define P2_DIR_HTOM P1_DIR_HTOM /* from host to Mac */
X#define P2_DIR_MTOH P1_DIR_MTOH /* from Mac to host */
X#define P2_FN P1_FN /* function code: */
X#define P2_FN_NEWW P1_FN_NEWW /* new window */
X#define P2_FN_KILLW P1_FN_KILLW /* kill (delete) window */
X#define P2_FN_ISELW P1_FN_ISELW /* select window for input */
X#define P2_FN_OSELW P1_FN_OSELW /* select window for output */
X#define P2_FN_WOPT 0040 /* communicate window options */
X#define P2_FN_META P1_FN_META /* add meta to next data char */
X#define P2_FN_CTLCH P1_FN_CTLCH /* low 3 bits specify char */
X#define P2_FN_MAINT P1_FN_MAINT /* maintenance functions */
X#define P2_WINDOW P1_WINDOW /* window number mask */
X#define P2_CC P1_CC /* control character specifier: */
X#define P2_CC_IAC P1_CC_IAC /* IAC */
X#define P2_CC_XON P1_CC_XON /* XON */
X#define P2_CC_XOFF P1_CC_XOFF /* XOFF */
X#define P2_MF P1_MF /* maintenance functions: */
X#define P2_MF_ENTRY P1_MF_ENTRY /* beginning execution */
X#define P2_MF_ASKPCL P1_MF_ASKPCL /* request protocol negotiation */
X#define P2_MF_CANPCL P1_MF_CANPCL /* suggest protocol */
X#define P2_MF_SETPCL P1_MF_SETPCL /* set current protocol */
X#define P2_MF_EXIT P1_MF_EXIT /* execution terminating */
X#define P2_NWINDOW P1_NWINDOW /* maximum number of windows */
X
X/*
X * Protocol negotiation
X *
X * The server is not used for protocol 0. For the other protocols, the
X * Macintosh and the server negotiate to select the active protocol. The
X * basic idea is that the Macintosh will express its desire for a protocol
X * and the server will attempt to satisfy that desire. Until negotiations
X * are complete, protocol 1 is used.
X *
X * Protocols are identified by single-character names which are formed by
X * adding the ASCII code for a space (040) to the protocol number minus 1
X * (i.e. protocol 1 is ' ', protocol 2 is '!').
X *
X * P1_FN_CANPCL and P1_FN_SETPCL are three-byte commands: P1_IAC,
X * P1_FN_XXXPCL, protocol-name.
X *
X * Macintosh:
X * If UW v2.10 is used on the Macintosh or if a newer Macintosh program
X * wishes to use protocol 1, it will never initiate protocol negotiation.
X * Hence, all interaction will use protocol 1 by default.
X *
X * If the Macintosh program is capable of supporting protocol 2 and the
X * user requests its use, the Mac will remember this fact but will
X * continue to use protocol 1. The Mac program will assume that no
X * server is present until instructed otherwise by the user or until a
X * P1_FN_ENTRY command is received (e.g. when the server starts up).
X * At this time, the Mac program issues P1_FN_ASKPCL. If the server
X * cannot support protocol 2 (i.e. it is an old server), then it will
X * ignore the P1_FN_ASKPCL. The Macintosh will retry the P1_FN_ASKPCL
X * a couple of times (about five seconds apart) and, if there is no
X * response from the server, will abandon negotiations. Protocol 1
X * will be used for the remainder of the session.
X *
X * If the server recognizes the P1_FN_ASKPCL command it will respond
X * with the name of the most complex protocol it can support (currently
X * '!'). If this is acceptable to the Macintosh, it will instruct the
X * server to use this protocol. If the Macintosh cannot support this
X * protocol it will respond with a P1_FN_CANPCL suggesting a less-complex
X * protocol. If the server agrees to this it will answer establish the
X * protocol; otherwise, it will suggest an even weaker protocol.
X * Eventually someone will suggest protocol 1 (which is universal) and
X * the other side will issue a P1_FN_SETPCL command to establish its use.
X *
X * Host:
X * If the host receives a P1_FN_ASKPCL it will respond with the most
X * complex protocol it can support (using the P1_FN_CANPCL command).
X * Negotiations will proceed as described above until one side
X * establishes a new protocol with P1_FN_SETPCL. At this time, the
X * host will switch to the new protocol.
X *
X * If the host receives a P1_FN_ENTRY (P2_FN_ENTRY) command, it will
X * switch back to protocol 1. Receipt of this command indicates that
X * the Macintosh program was restarted. The Macintosh must initiate
X * protocol negotiations again.
X */
X
X/*
X * Although many of the functions are identical (and the code is shared
X * between them), each protocol is accessed through a (struct protocol)
X * which specifies the functions for various operations.
X *
X * In theory, the main program knows nothing about the protocol in use.
X * In practice, the externally-visible functions are accessed as macros
X * for greater efficiency.
X *
X * The protocol layer is aware of the (struct window) data structures.
X */
X
Xstruct protocol {
X char p_name; /* single-character protocol name */
X nwin_t p_maxwin; /* maximum window number */
X int *p_ctlch; /* control character map table */
X unsigned p_szctlch; /* size (# of entries) in ctlch table */
X void (*p_entry)(); /* start up (ENTRY maintenance fn) */
X void (*p_exit)(); /* shut down (EXIT maintenance fn) */
X void (*p_renew)(); /* renew (re-init) */
X struct window *(*p_neww)(); /* create new window */
X void (*p_killw)(); /* kill window */
X void (*p_xmit)(); /* transmit to specified window */
X void (*p_recv)(); /* receive from Macintosh */
X void (*p_chkopt)(); /* check for pending option output */
X void (*p_sendopt)(); /* send option string to Macintosh */
X void (*p_askpcl)(); /* send an ASKPCL maintenance command */
X void (*p_canpcl)(); /* send a CANPCL maintenance command */
X void (*p_setpcl)(); /* send a SETPCL maintenance command */
X};
X
Xextern struct protocol *protocol;
X
X#define PCL_NEWW(mfd,class,wtype,wnum,wid,dfd,cfd) \
X (*protocol->p_neww)(mfd,class,wtype,wnum,(long)wid,dfd,cfd)
X#define PCL_KILLW(mfd,w) (*protocol->p_killw)(mfd,w)
X#define PCL_RECV(mfd,buf,len) (*protocol->p_recv)(mfd,buf,len)
X#define PCL_XMIT(mfd,w) (*protocol->p_xmit)(mfd,w)
X#define PCL_SENDOPT(mfd,fn,buf,len) \
X (protocol->p_sendopt ? (*protocol->p_sendopt)(mfd,fn,buf,len) : 0)
X#endif
!EOF!h/uw_pcl.h!
echo x - h/uw_win.h
sed -e 's/^X//' > h/uw_win.h << '!EOF!h/uw_win.h!'
X/*
X * uw window data definition
X *
X * Copyright 1986 by John D. Bruner. All rights reserved. Permission to
X * copy this program is given provided that the copy is not sold and that
X * this copyright notice is included.
X */
X
X#ifndef UW_WIN
X#define UW_WIN
X
X#include "uw_opt.h"
X
X/*
X * A "point" is a pair of 16-bit integers. This may specify the horizontal
X * and vertical position or size of a window.
X */
Xtypedef short npixel_t; /* number of pixels */
Xstruct point {
X npixel_t v,h;
X};
X
X/*
X * The type of a window determines how it responds to I/O and which
X * window options it supports. I'd like to declare these with an "enum",
X * but the stupid PCC screams if I use enums as array indices, so they
X * are defined via #define's instead.
X */
Xtypedef unsigned int wtype_t; /* window type: */
X#define WT_ADM31 0 /* ADM-31 terminal emulation */
X#define WT_VT52 1 /* VT52 terminal emulation */
X#define WT_ANSI 2 /* ANSI terminal emulation */
X#define WT_TEK4010 3 /* Tek4010 terminal emulation */
X#define WT_FTP 4 /* file transfer */
X#define WT_PRINT 5 /* output to printer */
X#define WT_PLOT 6 /* plot window */
X#define WT_MAXTYPE 6 /* maximum window type */
X
Xextern wtype_t defwtype; /* default window type */
X
X/*
X * There are two basic classes of windows -- those which are processed
X * directly by the server and those which are processed by outside
X * programs. Directly-handled windows are always terminal emulations.
X * Externally-handled windows may be any window type.
X */
Xtypedef enum { /* window class: */
X WC_INTERNAL, /* processed directly */
X WC_EXTERNAL, /* processed externally */
X} wclass_t;
X
Xstruct window {
X int w_alloc; /* window allocated if nonzero */
X long w_id; /* window unique ID */
X wtype_t w_type; /* window emulation type */
X wclass_t w_class; /* window class */
X fildes_t w_datafd; /* data file descriptor */
X union {
X struct winint {
X char wi_tty[32]; /* terminal name */
X } wu_int;
X struct winext {
X fildes_t we_ctlfd; /* control file descriptor */
X } wu_ext;
X } w_un;
X struct woptdefn w_optdefn; /* window option definitions */
X int w_visible; /* nonzero if window is visible */
X struct point w_position; /* position of window on screen */
X struct point w_size; /* size of window in pixels */
X char w_title[256]; /* window title */
X char *w_private; /* storage private to emulation type */
X};
X#define w_tty w_un.wu_int.wi_tty
X#define w_ctlfd w_un.wu_ext.we_ctlfd
X
Xtypedef int nwin_t; /* window index data type */
X
X/*
X * Some operations upon windows depend upon the window type. For each
X * emulation type there is a "emulation" structure which specifies
X * emulation-specific data.
X */
Xstruct emulation {
X struct woptdefn we_optdefn; /* window option definitions */
X int (*we_start)(); /* emulation setup code */
X void (*we_stop)(); /* emulation shutdown code */
X void (*we_setext)(); /* make changes req'd for extern win */
X};
X
Xextern struct window *win_neww(); /* create new window */
Xextern struct window *win_search(); /* convert window ID to window ptr */
X
X/*
X * The following macros convert between a window number and a pointer to
X * the corresponding window structure (and vice versa).
X *
X * NWINDOW *must* be >= P1_NWINDOW and >= P2_NWINDOW (in "uw_pcl.h").
X */
X#define NWINDOW 7 /* maximum number of windows */
X#define WIN_NUM(wptr) ((wptr)-window+1)
X#define WIN_PTR(wnum) (window+(wnum)-1)
Xextern struct window window[]; /* window data structures */
X#endif
!EOF!h/uw_win.h!
echo x - h/uwlib.h
sed -e 's/^X//' > h/uwlib.h << '!EOF!h/uwlib.h!'
X/*
X * uw library definitions
X *
X * Copyright 1986 by John D. Bruner. All rights reserved. Permission to
X * copy this program is given provided that the copy is not sold and that
X * this copyright notice is included.
X */
X
X#include "uw_err.h"
X#include "uw_ipc.h"
X
X#ifndef NBBY
X#define NBBY 8 /* defined in <sys/types.h> in 4.3BSD */
X#endif
X
X#define UW_NUMOPTS 32 /* number of window options */
X#define UW_NWTYPES 6 /* number of window emulation types */
X
Xtypedef char uwtitle_t[256];
X
Xstruct uwpoint {
X unsigned uwp_v; /* vertical component */
X unsigned uwp_h; /* horizontal component */
X};
X
Xstruct uw_info {
X uwid_t uwi_id; /* unique window ID */
X int uwi_datafd; /* file descriptor for data */
X int uwi_ctlfd; /* file descriptor for control */
X uwerr_t uwi_uwerr; /* last error from UW */
X int uwi_errno; /* last error from system call */
X int uwi_vis; /* visiblility */
X uwtype_t uwi_type; /* window type */
X struct uwpoint uwi_pos; /* window position (in pixels) */
X uwtitle_t uwi_title; /* window title */
X struct uwpoint uwi_wsize; /* window size (in pixels) */
X struct {
X void (*uwi_optfn)(); /* option handler */
X } uwi_options[UW_NUMOPTS];
X int uwi_ipclen; /* length of data in IPC buffer */
X struct uwipc uwi_ipcbuf; /* buffer for IPC messages */
X};
X
X#define UW_DATAFD(uwin) (uwin)->uwi_datafd
X#define UW_ID(uwin) (uwin)->uwi_id
X#define UW_PERROR(uwin, mesg) \
X uw_perror(mesg, (uwin)->uwi_uwerr, (uwin)->uwi_errno)
X
Xtypedef struct uw_info *UWIN;
Xtypedef void (*uwfnptr_t)();
X
Xextern uwid_t uw_cmd();
Xextern UWIN uw_new();
Xextern uw_close(), uw_detach();
Xextern uw_optcmd();
Xextern uw_kill();
Xextern uwfnptr_t uw_optfn();
Xextern uw_rsetopt();
Xextern void uw_perror();
Xextern uwid_t uw_fork(), uw_cmd(), uw_shell();
X
Xextern uw_gvis(), uw_svis();
Xextern uw_gtype(), uw_stype();
Xextern uw_gtitle(), uw_stitle();
Xextern uw_gwsize(), uw_swsize();
Xextern uw_gpos(), uw_spos();
X
Xextern uwerr_t uwerrno;
Xextern char *uwerrlist[];
Xextern unsigned uwnerr;
!EOF!h/uwlib.h!
echo x - server/Makefile_4.2
sed -e 's/^X//' > server/Makefile_4.2 << '!EOF!server/Makefile_4.2!'
X#! /bin/make -f
X#
X# uw makefile (4.2BSD)
X#
X# INCDIR names the directory where the header files are located.
X#
X# OBJECTS names all of the object files required for the server.
X#
X
XINCDIR = ../h
X
XOBJECTS = uw_clk.o uw_env.o uw_fd.o uw_ipc.o uw_main.o uw_opt.o \
X uw_pcl.o uw_tty.o uw_utmp.o uw_win.o openpty.o
X
XSOURCES = `echo $(OBJECTS) | sed -e 's/\\.o/\\.c/g'`
X
XDEFINES = `cat ../DEFINES`
X
XCFLAGS = $(DEFINES) -I$(INCDIR) -O
XLFLAGS =
X
Xuw: $(OBJECTS)
X $(CC) $(LFLAGS) -o uw $(OBJECTS) $(LIBS)
X
Xlint:
X lint -hbx -I$(INCDIR) $(DEFINES) $(SOURCES)
X
Xtags:
X ctags $(SOURCES)
X
Xdepend:
X grep '^#include' $(SOURCES) | \
X sed -e '/</d' \
X -e 's/:[^"]*"\([^"]*\)".*/: ..\/h\/\1/' \
X -e 's,^../[a-zA-Z0-9]*/\([^\.]*\)\.[cs],\1.o \1.L,' | \
X awk ' { if ($$1 != prev) { print rec; rec = $$0; prev = $$1; } \
X else { if (length(rec $$3) > 78) { print rec; rec = $$0; } \
X else rec = rec " " $$3 } } \
X END { print rec } ' > makedep
X echo '/^# DO NOT DELETE THIS LINE/+1,$$d' >eddep
X echo '$$r makedep' >>eddep
X echo 'w' >>eddep
X cp Makefile Makefile.bak
X ex - Makefile < eddep
X rm eddep makedep
X
Xclean:
X rm *.o
X
X# DO NOT DELETE THIS LINE (or the following blank line) -- make depend uses it
X
!EOF!server/Makefile_4.2!
echo x - server/Makefile_4.3
sed -e 's/^X//' > server/Makefile_4.3 << '!EOF!server/Makefile_4.3!'
X#! /bin/make -f
X#
X# uw makefile (4.3BSD)
X#
X# INCDIR names the directory where the header files are located.
X#
X# OBJECTS names all of the object files required for the server.
X#
X
XINCDIR = ../h
X
XOBJECTS = uw_clk.o uw_env.o uw_fd.o uw_ipc.o uw_main.o uw_opt.o \
X uw_pcl.o uw_tty.o uw_utmp.o uw_win.o openpty.o
X
XSOURCES = `echo $(OBJECTS) | sed -e 's/\\.o/\\.c/g'`
X
XDEFINES = `cat ../DEFINES`
X
XCFLAGS = $(DEFINES) -I$(INCDIR) -O
XLFLAGS =
X
Xuw: $(OBJECTS)
X $(CC) $(LFLAGS) -o uw $(OBJECTS) $(LIBS)
X
Xlint:
X lint -hbx -I$(INCDIR) $(DEFINES) $(SOURCES)
X
Xtags:
X ctags $(SOURCES)
X
Xdepend:
X $(CC) -M -I$(INCDIR) $(DEFINES) $(SOURCES) | \
X sed -e ':loop' \
X -e 's/\.\.\/[^ /]*\/\.\./../' \
X -e 't loop' | \
X awk ' { if ($$1 != prev) { print rec; rec = $$0; prev = $$1; } \
X else { if (length(rec $$2) > 78) { print rec; rec = $$0; } \
X else rec = rec " " $$2 } } \
X END { print rec } ' >> makedep
X echo '/^# DO NOT DELETE THIS LINE/+1,$$d' >eddep
X echo '$$r makedep' >>eddep
X echo 'w' >>eddep
X cp Makefile Makefile.bak
X ex - Makefile < eddep
X rm eddep makedep
X
Xclean:
X rm *.o
X
X# DO NOT DELETE THIS LINE (or the following blank line) -- make depend uses it
X
!EOF!server/Makefile_4.3!
echo x - server/openpty.c
sed -e 's/^X//' > server/openpty.c << '!EOF!server/openpty.c!'
X/*
X * openpty - open a pseudo-terminal
X *
X * The first time that the routine is called, the device directory is
X * searched and a list of all candidate pseudo-terminals is compiled.
X * Candidates are defined to be those entries in "/dev" whose names
X * (1) are the same length as PTY_PROTO and (2) start with the
X * initial string PTY_PREFIX. Further, the master and slave sides
X * must both exist.
X *
X * openpty() attempts to find an unused pseudo-terminal from the list
X * of candidates. If one is found, the master and slave sides are
X * opened and the file descriptors and names of these two devices are
X * returned in a "ptydesc" structure. (The address of this structure
X * is supplied by the caller. Zero is returned if openpty() was
X * successful, -1 is returned if no pty could be found.
X */
X
X#include <sys/types.h>
X#include <sys/dir.h>
X#include <fcntl.h>
X#include <strings.h>
X#include "openpty.h"
X
X#define DEV_DIR "/dev" /* directory where devices live */
X#define PT_INDEX (sizeof DEV_DIR) /* location of 'p' in "pty" */
X
X#define PTY_PROTO "ptyp0" /* prototype for pty names */
X#define PTY_PREFIX "pty" /* prefix required for name of pty */
X
Xstruct ptyinfo {
X struct ptyinfo *pi_next;
X char *pi_pty;
X char *pi_tty;
X};
X
Xstatic struct ptyinfo *ptylist;
X
Xextern char *malloc();
X
Xstatic
Xchar *
Xdevname(name)
Xchar *name;
X{
X register char *fullname;
X
X /*
X * Construct the full name of a device in DEV_DIR. Returns
X * NULL if it failed (because malloc() failed).
X */
X
X fullname = malloc((unsigned)(sizeof DEV_DIR + 1 + strlen(name)));
X if (fullname != NULL) {
X (void)strcpy(fullname, DEV_DIR);
X (void)strcat(fullname, "/");
X (void)strcat(fullname, name);
X }
X return(fullname);
X}
X
Xstatic
Xisapty(dp)
Xstruct direct *dp;
X{
X static struct ptyinfo *pi;
X
X /*
X * We don't care about the gory details of the directory entry.
X * Instead, what we really want is an array of pointers to
X * device names (with DEV_DIR prepended). Therefore, we create
X * this array ourselves and tell scandir() to ignore every
X * directory entry.
X *
X * If malloc() fails, the current directory entry is ignored.
X */
X if (pi == NULL) {
X pi = (struct ptyinfo *)malloc((unsigned)sizeof *pi);
X if (pi == NULL)
X return(0);
X }
X
X if (strlen(dp->d_name) == sizeof PTY_PROTO - 1 &&
X strncmp(dp->d_name, PTY_PREFIX, sizeof PTY_PREFIX - 1) == 0) {
X pi->pi_pty = devname(dp->d_name);
X if (pi->pi_pty == NULL)
X return(0);
X pi->pi_tty = malloc((unsigned)(strlen(pi->pi_pty) + 1));
X if (pi->pi_tty == NULL) {
X free(pi->pi_pty);
X return(0);
X }
X (void)strcpy(pi->pi_tty, pi->pi_pty);
X pi->pi_tty[PT_INDEX] = 't';
X if (access(pi->pi_pty, 0) == 0 && access(pi->pi_tty, 0) == 0) {
X pi->pi_next = ptylist;
X ptylist = pi;
X pi = NULL;
X } else {
X free(pi->pi_pty);
X free(pi->pi_tty);
X }
X }
X return(0);
X}
X
Xopenpty(pt)
Xstruct ptydesc *pt;
X{
X register struct ptyinfo *pi;
X static int fail;
X auto struct direct **dirlist;
X extern char *re_comp();
X extern int alphasort();
X
X /*
X * If scandir() fails or no possible pty's are found, then "fail"
X * is set non-zero. If "fail" is non-zero then the routine bombs
X * out immediately. Otherwise, the list of candidates is examined
X * starting with the entry following the last one chosen.
X */
X if (fail)
X return(-1);
X
X if (!ptylist) { /* first time */
X if (scandir(DEV_DIR, &dirlist, isapty, alphasort) < 0 ||
X ptylist == NULL) {
X fail = 1;
X return(-1);
X }
X for (pi=ptylist; pi->pi_next; pi=pi->pi_next)
X ;
X pi->pi_next = ptylist; /* make the list circular */
X }
X
X pi = ptylist;
X do {
X if ((pt->pt_pfd = open(pi->pi_pty, O_RDWR)) >= 0) {
X if ((pt->pt_tfd = open(pi->pi_tty, O_RDWR)) >= 0) {
X ptylist = pi->pi_next;
X pt->pt_pname = pi->pi_pty;
X pt->pt_tname = pi->pi_tty;
X return(0);
X } else
X (void)close(pt->pt_pfd);
X }
X pi = pi->pi_next;
X } while (pi != ptylist);
X return(-1);
X}
!EOF!server/openpty.c!
echo x - server/uw_clk.c
sed -e 's/^X//' > server/uw_clk.c << '!EOF!server/uw_clk.c!'
X/*
X * uw_clk - timer support for UW
X *
X * Copyright 1986 by John D. Bruner. All rights reserved. Permission to
X * copy this program is given provided that the copy is not sold and that
X * this copyright notice is included.
X */
X
X#include <sys/types.h>
X#include <sys/time.h>
X#include <sys/signal.h>
X#include <sys/resource.h>
X
X#include "uw_param.h"
X#include "uw_clk.h"
X
Xstatic struct timeout *pending;
Xstatic struct timeout *freelist;
X
Xint timer_rdy; /* nonzero when some timeout is ready to run */
X
Xclk_timeout(secs, fn, arg)
Xint secs;
Xvoid (*fn)();
Xtoarg_t arg;
X{
X register struct timeout *to, **tol;
X register time_t curtime;
X extern time_t time();
X
X to = freelist;
X if (!to) {
X if (!(to = (struct timeout *)malloc(sizeof *to)))
X return(-1);
X } else
X freelist = to->to_next;
X to->to_fn = fn;
X to->to_arg = arg;
X
X if (secs < 0)
X secs = 0;
X curtime = time((time_t *)0);
X to->to_when = curtime + secs;
X
X tol = &pending;
X while (*tol && to->to_when > (*tol)->to_when)
X tol = &(*tol)->to_next;
X to->to_next = *tol;
X *tol = to;
X
X clk_service();
X return(0);
X}
X
Xclk_service()
X{
X register struct timeout *to;
X register time_t curtime;
X
X curtime = time((time_t *)0);
X while ((to=pending) && to->to_when <= curtime) {
X pending = to->to_next;
X if (to->to_fn) {
X (*to->to_fn)(to->to_arg);
X to->to_next = freelist;
X freelist = to;
X }
X }
X
X timer_rdy = 0;
X if (pending)
X (void)alarm((unsigned)(pending->to_when - curtime));
X}
X
Xvoid
Xclk_alarm()
X{
X /*
X * A SIGALRM has been received.
X */
X timer_rdy = 1;
X}
X
Xclk_init()
X{
X timer_rdy = 0;
X (void)signal(SIGALRM, clk_alarm);
X}
!EOF!server/uw_clk.c!
echo x - server/uw_env.c
sed -e 's/^X//' > server/uw_env.c << '!EOF!server/uw_env.c!'
X/*
X * uw_env - environment manipulation
X *
X * Copyright 1985,1986 by John D. Bruner. All rights reserved. Permission to
X * copy this program is given provided that the copy is not sold and that
X * this copyright notice is included.
X */
X
X#define MAXENV 128 /* maximum number of arguments in environment */
X
Xstatic char *earray[MAXENV+1];
X
Xenv_set(env)
Xchar **env;
X{
X register char **ep1, **ep2, *cp;
X char **ep3;
X extern char **environ;
X
X
X /*
X * Merge the set of environment strings in "env" into the
X * environment.
X */
X
X /*
X * The first time through, copy the environment from its
X * original location to the array "earray". This makes it a
X * little easier to change things.
X */
X
X if (environ != earray) {
X ep1=environ;
X ep2=earray;
X while(*ep1 && ep2 <= earray+MAXENV)
X *ep2++ = *ep1++;
X *ep2++ = (char *)0;
X environ = earray;
X }
X
X
X /*
X * If "env" is non-NULL, it points to a list of new items to
X * be added to the environment. These replace existing items
X * with the same name.
X */
X
X if (env) {
X for (ep1=env; *ep1; ep1++) {
X for (ep2=environ; *ep2; ep2++)
X if (!env_cmp(*ep1, *ep2))
X break;
X if (ep2 < earray+MAXENV) {
X if (!*ep2)
X ep2[1] = (char *)0;
X *ep2 = *ep1;
X }
X }
X }
X
X
X /* Finally, use an insertion sort to put things in order. */
X
X for (ep1=environ+1; cp = *ep1; ep1++) {
X for(ep2=environ; ep2 < ep1; ep2++)
X if (env_cmp(*ep1, *ep2) < 0)
X break;
X ep3 = ep2;
X for(ep2=ep1; ep2 > ep3; ep2--)
X ep2[0] = ep2[-1];
X *ep2 = cp;
X }
X}
X
X
Xstatic
Xenv_cmp(e1, e2)
Xregister char *e1, *e2;
X{
X register d;
X
X do {
X if (d = *e1 - *e2++)
X return(d);
X } while (*e1 && *e1++ != '=');
X return(0);
X}
!EOF!server/uw_env.c!
echo x - server/uw_fd.c
sed -e 's/^X//' > server/uw_fd.c << '!EOF!server/uw_fd.c!'
X/*
X * uw_fd - file-descriptor/select data
X *
X * Copyright 1986 by John D. Bruner. All rights reserved. Permission to
X * copy this program is given provided that the copy is not sold and that
X * this copyright notice is included.
X */
X
X#include <sys/types.h>
X
X#include "uw_param.h"
X#include "uw_fd.h"
X
Xstruct selmask selmask[2];
Xstruct fdmap fdmap[FD_SETSIZE];
Xfildes_t nfds; /* number of file descriptors */
X
Xfd_init()
X{
X register fildes_t fd;
X
X nfds = getdtablesize();
X if (nfds > FD_SETSIZE)
X nfds = FD_SETSIZE;
X fdmap[0].f_type = FDT_MAC;
X fdmap[1].f_type = FDT_MAC;
X fdmap[2].f_type = FDT_DEBUG;
X for (fd=3; fd < FD_SETSIZE; fd++) {
X fdmap[fd].f_type = FDT_NONE;
X (void)close(fd);
X }
X FD_ZERO(&selmask[0].sm_rd);
X FD_ZERO(&selmask[0].sm_wt);
X FD_ZERO(&selmask[0].sm_ex);
X}
X
Xfd_exit()
X{
X register fildes_t fd;
X
X for (fd=3; fd < nfds; fd++)
X (void)close(fd);
X}
!EOF!server/uw_fd.c!
echo x - server/uw_main.c
sed -e 's/^X//' > server/uw_main.c << '!EOF!server/uw_main.c!'
X/*
X * uw - UNIX windows program for the Macintosh (host end)
X *
X * Copyright 1985,1986 by John D. Bruner. All rights reserved. Permission to
X * copy this program is given provided that the copy is not sold and that
X * this copyright notice is included.
X */
X
X#include <sys/types.h>
X#include <sys/file.h>
X#include <sys/wait.h>
X#include <sys/time.h>
X#include <sys/resource.h>
X#include <sys/ioctl.h>
X#include <pwd.h>
X#include <signal.h>
X#include <errno.h>
X#include <strings.h>
X#include <stdio.h>
X
X#include "uw_param.h"
X#include "uw_clk.h"
X#include "uw_opt.h"
X#include "uw_win.h"
X#include "uw_fd.h"
X#include "uw_pcl.h"
X#include "uw_ipc.h"
X#include "openpty.h"
X
Xint nflag; /* no startup file */
Xint sflag; /* "secure" (hee hee) -- no network requests */
Xint errflag; /* argument error */
Xchar *rcfile; /* ".uwrc" file name */
X
Xextern void rc_kludge(); /* horrible hack (see rc_kludge()) */
X
Xmain(argc, argv)
Xchar **argv;
X{
X register int c;
X register fildes_t fd;
X extern int calloptscan;
X extern int errno;
X extern int optind;
X extern char *optarg;
X
X /*
X * Make sure we don't accidentally try to run this inside itself.
X */
X if (getenv(UIPC_ENV)) {
X fprintf(stderr, "%s is already running\n", *argv);
X exit(1);
X }
X
X /*
X * Process command-line arguments.
X */
X while ((c=getopt(argc, argv, "f:ns")) != EOF) {
X switch (c) {
X case 'f':
X if (nflag) {
X fprintf(stderr,
X "Cannot specify both \"-f\" and \"-n\"\n");
X nflag = 0;
X }
X rcfile = optarg;
X break;
X case 'n':
X if (rcfile != (char *)0) {
X fprintf(stderr,
X "Cannot specify both \"-f\" and \"-n\"\n");
X rcfile = (char *)0;
X }
X nflag = 1;
X break;
X case 's':
X sflag = 1;
X break;
X case '?':
X default:
X errflag = 1;
X break;
X }
X }
X if (errflag) {
X fprintf(stderr, "Usage: \"%s [-f file] [-n] [-s]\"\n", *argv);
X exit(1);
X }
X
X /*
X * Initialize the file descriptor table.
X */
X fd_init();
X FD_SET(0, &selmask[0].sm_rd);
X
X /*
X * If we can open the "/etc/utmp" for write, do so.
X * Immediately afterwards, we lose any magic powers that
X * might have allowed us to do this.
X */
X#ifdef UTMP
X fd = open("/etc/utmp", O_WRONLY);
X (void)setgid(getgid());
X (void)setuid(getuid());
X if (fd >= 0)
X fdmap[fd].f_type = FDT_OTHER;
X utmp_init(fd);
X#endif
X
X /*
X * Initialize the window structures.
X */
X win_init();
X
X /*
X * Initialize timeouts.
X */
X clk_init();
X
X
X /*
X * Create a UNIX-domain network address, and put its name into
X * the environment so that descendents can contact us with new
X * window requests. If we want to be "secure", we don't allow
X * any UNIX-domain messages to come in.
X */
X ipc_init(!sflag);
X if (!sflag)
X clk_timeout(5, rc_kludge, (toarg_t)0);
X
X
X /*
X * Ignore interrupts, quits, and terminal stops. Clean up and exit
X * if a hangup or termination is received. Also catch changes in
X * child status (so that we can wait for them). Set up the terminal
X * modes.
X */
X (void)signal(SIGHUP, done);
X (void)signal(SIGINT, SIG_IGN);
X (void)signal(SIGQUIT, SIG_IGN);
X (void)signal(SIGTERM, done);
X (void)signal(SIGTSTP, SIG_IGN);
X (void)signal(SIGCHLD, cwait);
X
X tty_mode(1);
X
X
X /*
X * Tell the Macintosh to initialize.
X */
X pcl_entry(0);
X
X
X /*
X * Create window 1 (to start things off) and wait for input.
X * When input is available, process it.
X */
X if (!nflag)
X finduwrc();
X
X while (1) {
X CLK_CHECK();
X if (calloptscan && protocol->p_chkopt) {
X calloptscan = 0;
X (*protocol->p_chkopt)(0);
X }
X selmask[1] = selmask[0];
X if (select(nfds, &selmask[1].sm_rd, &selmask[1].sm_wt,
X &selmask[1].sm_ex, (struct timeval *)0) < 0) {
X if (errno == EINTR)
X continue;
X perror("select");
X done(1); /* for now -- fix this! */
X }
X for (fd=0; fd < nfds; fd++) {
X if (FD_ISSET(fd, &selmask[1].sm_rd)) {
X switch (fdmap[fd].f_type) {
X case FDT_MAC:
X PCL_RECV(0, (char *)0, 0);
X break;
X case FDT_UDSOCK:
X ipc_udrecv(fd);
X break;
X case FDT_ISSOCK:
X ipc_isrecv(fd);
X break;
X case FDT_DATA:
X PCL_XMIT(0, fdmap[fd].f_win);
X break;
X case FDT_CTL:
X ipc_ctlrecv(0, fd, fdmap[fd].f_win);
X break;
X default:
X /* "can't happen" */
X FD_CLR(fd, &selmask[0].sm_rd);
X break;
X }
X }
X if (FD_ISSET(fd, &selmask[1].sm_wt)) {
X /* "can't happen" */
X FD_CLR(fd, &selmask[0].sm_wt);
X break;
X }
X if (FD_ISSET(fd, &selmask[1].sm_ex)) {
X /* "can't happen" */
X FD_CLR(fd, &selmask[0].sm_ex);
X break;
X }
X }
X }
X}
X
Xfinduwrc()
X{
X register struct passwd *pw;
X register char *homedir;
X
X /*
X * If the global variable "rcfile" is non-NULL, then it specifies
X * the name of the startup file. Otherwise, the name of the startup
X * file is "$HOME/.uwrc". If $HOME is undefined or null, the password
X * file is consulted. The ".uwrc" file is an executable program or
X * "/bin/sh" command file. (For "csh" (ugh) use "#! /bin/csh".)
X *
X * Returns 0 if the ".uwrc" file doesn't exist, 1 if it does. As
X * a side-effect, this routine sets the global variable "rcfile"
X * to the name of the ".uwrc" file.
X */
X if (rcfile == (char *)0) {
X if ((homedir=getenv("HOME")) == NULL || !*homedir) {
X if ((pw = getpwuid(getuid())) != NULL)
X homedir = pw->pw_dir;
X else
X return;
X }
X rcfile = malloc((unsigned)(strlen(homedir) + sizeof "/.uwrc"));
X if (rcfile == (char *)0)
X return;
X (void)strcpy(rcfile, homedir);
X (void)strcat(rcfile, "/.uwrc");
X }
X if (access(rcfile, F_OK) < 0)
X rcfile = (char *)0;
X}
X
Xrunuwrc()
X{
X register int pid;
X register fildes_t fd;
X struct ptydesc pt;
X
X /*
X * We use a real fork (rather than a vfork()) because the parent
X * doesn't wait for the child. The caller knows that the file
X * exists; however, it cannot determine whether or not it is
X * successfully executed.
X *
X * We acquire a pseudo-terminal for rather convoluted reasons.
X * Programs such as "uwtool" expect to be able to inherit tty
X * modes from their controlling terminal. By the time that we
X * reach this point, we've already changed our controlling
X * terminal to use cbreak mode with no special characters except
X * XON/XOFF. Therefore, we obtain a pseudo-terminal and
X * restore our original modes onto it. We double-fork (sigh,
X * another miserable kludge) so that the server does not have
X * to wait for the completion of the ".uwrc" file. (The child
X * waits for the grandchild so that the master side of the pty
X * remains open until the grandchild is finished.)
X */
X if (openpty(&pt) < 0)
X return;
X while ((pid = fork()) < 0)
X sleep(5);
X if (pid > 0) {
X (void)close(pt.pt_pfd);
X (void)close(pt.pt_tfd);
X } else {
X /* child */
X while ((pid = fork()) < 0)
X sleep(5);
X if (pid > 0) {
X while (wait((int *)0) < 0 && errno == EINTR)
X ;
X _exit(1);
X /*NOTREACHED*/
X } else {
X /* grandchild */
X (void)setgid(getgid());
X (void)setuid(getuid());
X (void)close(pt.pt_pfd);
X if (pt.pt_tfd != 0)
X (void)dup2(pt.pt_tfd, 0);
X if (pt.pt_tfd != 1);
X (void)dup2(pt.pt_tfd, 1);
X if (pt.pt_tfd != 2)
X (void)dup2(pt.pt_tfd, 2);
X win_envinit(defwtype, (long)0);
X (void)signal(SIGHUP, SIG_DFL);
X (void)signal(SIGINT, SIG_DFL);
X (void)signal(SIGQUIT, SIG_DFL);
X (void)signal(SIGTERM, SIG_DFL);
X (void)signal(SIGTSTP, SIG_IGN);
X (void)signal(SIGCHLD, SIG_DFL);
X (void)ioctl(open("/dev/tty",O_RDWR),
X (int)TIOCNOTTY, (char *)0);
X (void)open(pt.pt_tname, O_RDONLY);
X for (fd=3; fd < nfds; fd++)
X (void)close(fd);
X tty_mode(0);
X (void)execlp(rcfile, rcfile, (char *)0);
X (void)execl("/bin/sh", "sh", rcfile, (char *)0);
X _exit(1);
X /*NOTREACHED*/
X }
X }
X}
X
Xvoid
Xrc_kludge()
X{
X static int firsttime = 1;
X
X /*
X * A problem which occurs with ".uwrc" file handling is that
X * the "rc" file is interpreted immediately after the server
X * begins, i.e. before it and the Macintosh have (possibly)
X * changed from the default protocol to an extended one.
X *
X * To get around this problem, if a ".uwrc" file exists, it
X * is not executed immediately. Instead, it will be executed
X * when this routine is called, either directly by pcl_newpcl()
X * when the protocol changes, or after an initial timeout.
X *
X * It is most unfortunate that "pcl_newpcl" must call "upwards"
X * into this source file.
X */
X if (firsttime) {
X firsttime = 0;
X if (rcfile != (char *)0)
X runuwrc();
X else
X (void)PCL_NEWW(0, WC_INTERNAL, defwtype, (nwin_t)1, 0L,
X (fildes_t)-1, (fildes_t)-1);
X }
X}
X
Xvoid
Xdone(s)
X{
X /*
X * Clean up and exit. It is overkill to close all of the file
X * descriptors, but it causes no harm.
X */
X pcl_exit(0);
X utmp_exit();
X fd_exit();
X ipc_exit();
X tty_mode(0);
X exit(s);
X}
X
Xvoid
Xcwait()
X{
X register int pid;
X union wait status;
X struct rusage rusage;
X
X /*
X * Collect dead children. Restart any children that have stopped.
X */
X while ((pid=wait3(&status, WNOHANG|WUNTRACED, &rusage)) > 0)
X if (WIFSTOPPED(status))
X (void)kill(pid, SIGCONT);
X}
!EOF!server/uw_main.c!
exit 0
: end of shell archive