🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: mod.mac.sources
Article #17

UW v3.4 (part 4 of 9)

#17
From: John Bruner
Date: Thu, 23 Oct 1986 19:58
1805 lines
49018 bytes
: [UW v3.4 - part 4 of 9]
:
: This is a shar archive.  Extract with sh, not csh.
echo mkdir lib
mkdir lib
echo x - lib/Makefile_4.2
sed -e 's/^X//' > lib/Makefile_4.2 << '!EOF!lib/Makefile_4.2!'
X#! /bin/make -f
X#
X#	uw library makefile (4.2BSD)
X#
X# SETOWN_BUG should be defined if the fcntl(fd, F_SETOWN, pgrp) system
X# call is broken (as it is in 4.2BSD and Sun 3.0 UNIX).  On those
X# machines, the third argument must be negative to specify a process ID
X# and positive to specify a process group.
X#
X# INCDIR names the directory in which header files are located.
X# SERVERDIR names the directory containing the server source.
X# SERVER_OBJS names the object files derived from sources in SERVERDIR.
X# OBJECTS names all of the object files required for the library.
X#
XSETOWN_BUG	=	-DSETOWN_BUG
X
XINCDIR	=	../h
X
XSERVERDIR =	../server
X
XSERVER_OBJS =	$(SERVERDIR)/openpty.o $(SERVERDIR)/uw_env.o
X
XOBJECTS	=	uw_cmd.o uw_close.o uw_detach.o uw_fork.o uw_kill.o \
X		uw_netadj.o uw_new.o uw_optcmd.o uw_optfn.o uw_options.o \
X		uw_perror.o uw_ttype.o \
X		uw_rsetopt.o uw_shell.o \
X		uw_gvis.o uw_gtype.o uw_gtitle.o uw_gwsize.o uw_gpos.o \
X		$(SERVER_OBJS)
X
XCFLAGS	=	-O -I$(INCDIR) $(SETOWN_BUG)
X
XTARGET	=	libuw.a
X
X$(TARGET):	$(OBJECTS)
X	ar cr $(TARGET) `lorder $(OBJECTS) | tsort`
X	ranlib $(TARGET)
X	-if [ ! -f uwlib.a ];then ln -s libuw.a uwlib.a;fi
X
X$(SERVER_OBJS):
X	cd $(SERVERDIR); make `basename $@`
X
Xlint:
X	lint -uhbx -I$(INCDIR) `echo $(OBJECTS) | sed -e 's/\\.o/\\.c/g'`
X
Xtags:
X	ctags `echo $(OBJECTS) | sed -e 's/\\.o/\\.c/g'`
X
Xdepend: 
X	grep '^#include' `echo $(OBJECTS) | sed -e 's/\\.o/\\.c/g'` | \
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 -f *.o
X
X# DO NOT DELETE THIS LINE (or the following blank line) -- make depend uses it
X
!EOF!lib/Makefile_4.2!
echo x - lib/Makefile_4.3
sed -e 's/^X//' > lib/Makefile_4.3 << '!EOF!lib/Makefile_4.3!'
X#! /bin/make -f
X#
X#	uw library makefile (4.3BSD)
X#
X# SETOWN_BUG should be defined if the fcntl(fd, F_SETOWN, pgrp) system
X# call is broken (as it is in 4.2BSD and Sun 3.0 UNIX).  On those
X# machines, the third argument must be negative to specify a process ID
X# and positive to specify a process group.
X#
X# INCDIR names the directory in which header files are located.
X# SERVERDIR names the directory containing the server source.
X# SERVER_OBJS names the object files derived from sources in SERVERDIR.
X# OBJECTS names all of the object files required for the library.
X#
X#SETOWN_BUG	=	-DSETOWN_BUG
X
XINCDIR	=	../h
X
XSERVERDIR =	../server
X
XSERVER_OBJS =	$(SERVERDIR)/openpty.o $(SERVERDIR)/uw_env.o
X
XOBJECTS	=	uw_cmd.o uw_close.o uw_detach.o uw_fork.o uw_kill.o \
X		uw_netadj.o uw_new.o uw_optcmd.o uw_optfn.o uw_options.o \
X		uw_perror.o uw_ttype.o \
X		uw_rsetopt.o uw_shell.o \
X		uw_gvis.o uw_gtype.o uw_gtitle.o uw_gwsize.o uw_gpos.o \
X		$(SERVER_OBJS)
X
XCFLAGS	=	-O -I$(INCDIR) $(SETOWN_BUG)
X
XTARGET	=	libuw.a
X
X$(TARGET):	$(OBJECTS)
X	ar cr $(TARGET) `lorder $(OBJECTS) | tsort`
X	ranlib $(TARGET)
X	-if [ ! -f uwlib.a ];then ln -s libuw.a uwlib.a;fi
X
X$(SERVER_OBJS):
X	cd $(SERVERDIR); make `basename $@`
X
Xlint:
X	lint -uhbx -I$(INCDIR) `echo $(OBJECTS) | sed -e 's/\\.o/\\.c/g'`
X
Xtags:
X	ctags `echo $(OBJECTS) | sed -e 's/\\.o/\\.c/g'`
X
Xdepend: 
X	$(CC) -M -I$(INCDIR) `echo $(OBJECTS) | sed -e 's/\\.o/\\.c/g'` | \
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 -f *.o
X
X# DO NOT DELETE THIS LINE (or the following blank line) -- make depend uses it
X
!EOF!lib/Makefile_4.3!
echo x - lib/uw_close.c
sed -e 's/^X//' > lib/uw_close.c << '!EOF!lib/uw_close.c!'
X/*
X *	uw library - uw_close
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#include "uwlib.h"
X
Xuw_close(uwin)
XUWIN uwin;
X{
X	/*
X	 * Close all connections to an existing window, but do not kill it.
X	 */
X	if (uwin != (UWIN)0) {
X		if (uwin->uwi_ctlfd >= 0)
X			(void)uw_detach(uwin);
X		if (uwin->uwi_datafd >= 0)
X			(void)close(uwin->uwi_datafd);
X		free((char *)uwin);
X		return(0);
X	} else {
X		uwerrno = UWE_INVAL;
X		return(-1);
X	}
X}
!EOF!lib/uw_close.c!
echo x - lib/uw_cmd.c
sed -e 's/^X//' > lib/uw_cmd.c << '!EOF!lib/uw_cmd.c!'
X/*
X *	uw library - uw_cmd
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 "uwlib.h"
X
Xuwid_t
Xuw_cmd(wtype, file, argv)
Xuwtype_t wtype;
Xchar *file;
Xchar **argv;
X{
X	register uwid_t uwid;
X
X	/*
X	 * Create a new window (using uw_fork()) and run the specified
X	 * command in it.  Returns the window ID of the new window
X	 * (or -1 if the window creation failed).  There is no way to
X	 * determine if the executed command failed (e.g. if the
X	 * executable file did not exist).
X	 */
X	if ((uwid = uw_fork(wtype, (int *)0)) == 0) {
X		(void)execvp(file, argv);
X		uwerrno = UWE_ERRNO;
X		perror(file);
X		_exit(1);
X		/*NOTREACHED*/
X	} else
X		return(uwid);
X}
!EOF!lib/uw_cmd.c!
echo x - lib/uw_detach.c
sed -e 's/^X//' > lib/uw_detach.c << '!EOF!lib/uw_detach.c!'
X/*
X *	uw library - uw_detach
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#include "uwlib.h"
X
Xuw_detach(uwin)
XUWIN uwin;
X{
X	/*
X	 * Detach the control file descriptor for a window, while still
X	 * retaining access to the data file descriptor.
X	 */
X	if (uwin != (UWIN)0) {
X		if (uwin->uwi_ctlfd >= 0) {
X			uw_optdone(uwin->uwi_ctlfd);
X			(void)close(uwin->uwi_ctlfd);
X			uwin->uwi_ctlfd = -1;
X			return(0);
X		} else {
X			uwerrno = uwin->uwi_uwerr = UWE_NOCTL;
X			return(-1);
X		}
X	} else {
X		uwerrno = UWE_INVAL;
X		return(-1);
X	}
X}
!EOF!lib/uw_detach.c!
echo x - lib/uw_fork.c
sed -e 's/^X//' > lib/uw_fork.c << '!EOF!lib/uw_fork.c!'
X/*
X *	uw library - uw_fork
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#include <sys/types.h>
X#include <sys/socket.h>
X#include <sys/un.h>
X#include <sys/ioctl.h>
X#include <sys/uio.h>
X#include <sys/file.h>
X#include <strings.h>
X#include <signal.h>
X#include "openpty.h"
X
X#include "uwlib.h"
X
Xextern char *malloc();
Xextern char *getenv();
X
Xuwid_t
Xuw_fork(wtype, pidp)
Xuwtype_t wtype;
Xint *pidp;
X{
X	register int pid;
X	register int sd;
X	register struct uwipc *uwip;
X	register uwid_t wid;
X	auto int fd;
X	char *portal;
X	int lmode, ldisc;
X	struct sgttyb sg;
X	struct tchars tc;
X	struct ltchars ltc;
X	struct iovec iov;
X	struct msghdr msg;
X	struct sockaddr_un sa;
X	struct ptydesc pt;
X	char idstr[20];
X	char *env[2];
X	extern char *ltoa();
X
X	/*
X	 * Create a new window attached to a pseudo-terminal.  This routine
X	 * returns twice -- once in the parent and once in the (new) child.
X	 * The parent receives the window ID of the child (or -1 if the
X	 * window creation failed).  Zero is returned to the child.
X	 * If "pidp" is a non-NULL pointer, the process ID from the fork()
X	 * is stored there.
X	 */
X
X	/*
X	 * Get the terminal configuration for this tty.  For now we
X	 * assume that "/dev/tty" is defined.  Eventually we'll have to
X	 * provide defaults in case it is not.
X	 */
X	if ((fd = open("/dev/tty", O_RDWR)) >= 0) {
X		(void)ioctl(fd, (int)TIOCGETP, (char *)&sg);
X		(void)ioctl(fd, (int)TIOCGETC, (char *)&tc);
X		(void)ioctl(fd, (int)TIOCGLTC, (char *)&ltc);
X		(void)ioctl(fd, (int)TIOCLGET, (char *)&lmode);
X		(void)ioctl(fd, (int)TIOCGETD, (char *)&ldisc);
X		(void)close(fd);
X	} else {
X		/* ... */
X	}
X
X	/*
X	 * Create a UNIX-domain socket.
X	 */
X	if (!(portal=getenv("UW_UIPC"))) {
X		uwerrno = UWE_NXSERV;
X		return(-1);
X	}
X
X	if ((sd=socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) {
X		uwerrno = UWE_ERRNO;
X		return(-1);
X	}
X	sa.sun_family = AF_UNIX;
X	(void)strncpy(sa.sun_path, portal, sizeof sa.sun_path-1);
X	sa.sun_path[sizeof sa.sun_path-1] = '\0';
X
X
X	/*
X	 * Obtain a pseudo-tty and construct the datagram we will send later.
X	 */
X	if (openpty(&pt) < 0) {
X		uwerrno = UWE_ERRNO;
X		return(-1);
X	}
X	uwip = (struct uwipc *)malloc(sizeof(struct uwipc)+strlen(pt.pt_pname));
X	env[0] = malloc(sizeof "UW_ID=" + sizeof idstr);
X	if (uwip == (struct uwipc *)0 || env[0] == (char *)0) {
X		uwerrno = UWE_NOMEM;
X		return(-1);
X	}
X	uwip->uwip_cmd = UWC_NEWT;
X	uwip->uwip_len = (char *)&uwip->uwip_newt - (char *)uwip +
X	    sizeof(struct uwnewt) + strlen(pt.pt_pname);
X	uwip->uwip_newt.uwnt_type = wtype;
X	(void)strcpy(uwip->uwip_newt.uwnt_pty, pt.pt_pname);
X
X
X	/* 
X	 * Fork a child process using this pseudo-tty.  Initialize the
X	 * terminal modes on the pseudo-tty to match those of the parent
X	 * tty.  We really want a fork() here, not a vfork().
X	 */
X	while ((pid=fork()) < 0)
X		sleep(5);
X	if (pidp != (int *)0)
X		*pidp = pid;
X	if (pid) {
X		wid = (long)pid << 16;
X		uwip->uwip_newt.uwnt_id = wid;
X	} else {
X		(void)setgid(getgid());
X		(void)setuid(getuid());
X		wid = (long)getpid() << 16;
X		(void)strcat(strcpy(env[0], "UW_ID="),
X		     ltoa(wid, idstr, sizeof idstr));
X		env[1] = (char *)0;
X		env_set(env);
X		(void)signal(SIGTSTP, SIG_IGN);
X		(void)ioctl(open("/dev/tty", 2), (int)TIOCNOTTY, (char *)0);
X		(void)close(open(pt.pt_tname, 0)); /*set new ctrl tty */
X		(void)dup2(pt.pt_tfd, 0);
X		(void)dup2(0, 1);
X		(void)dup2(0, 2);
X		fd = getdtablesize();
X		while (--fd > 2)
X			(void)close(fd);
X		(void)ioctl(fd, (int)TIOCSETD, (char *)&ldisc);
X		(void)ioctl(0, (int)TIOCSETN, (char *)&sg);
X		(void)ioctl(0, (int)TIOCSETC, (char *)&tc);
X		(void)ioctl(0, (int)TIOCSLTC, (char *)&ltc);
X		(void)ioctl(0, (int)TIOCLSET, (char *)&lmode);
X		uwerrno = UWE_NONE;
X		return(0);
X	}
X
X
X	/*
X	 * Pass the file descriptor to the window server.
X	 */
X	iov.iov_base = (char *)uwip;
X	iov.iov_len = uwip->uwip_len;
X	msg.msg_name = (caddr_t)&sa;
X	msg.msg_namelen = sizeof sa.sun_family + strlen(sa.sun_path);
X	msg.msg_iov = &iov;
X	msg.msg_iovlen = 1;
X	msg.msg_accrights = (caddr_t)&pt.pt_pfd;
X	msg.msg_accrightslen = sizeof pt.pt_pfd;
X	if (sendmsg(sd, &msg, 0) < 0) {
X		free((char *)uwip);
X		uwerrno = UWE_ERRNO;
X		return(-1);
X	}
X	free((char *)uwip);
X	uwerrno = UWE_NONE;
X	return(wid);
X}
X
Xstatic
Xchar *
Xltoa(l, buf, buflen)
Xlong l;
Xchar *buf;
Xint buflen;
X{
X	register char *cp;
X	register unsigned long ul;
X	static char digits[] = "0123456789";
X
X	/*
X	 * This routine replaces a call to sprintf() so that the library
X	 * is independent of stdio.
X	 */
X	cp = buf+buflen;
X	*--cp = '\0';
X	ul = l;
X	if (cp > buf) {
X		do {
X			*--cp = digits[ul%10];
X			ul /= 10;
X		} while (cp > buf && ul != 0);
X	}
X	return(cp);
X}
!EOF!lib/uw_fork.c!
echo x - lib/uw_gpos.c
sed -e 's/^X//' > lib/uw_gpos.c << '!EOF!lib/uw_gpos.c!'
X/*
X *	uw library - uw_gpos, uw_spos
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#include "uwlib.h"
X
Xuw_gpos(uwin, pp)
Xregister UWIN uwin;
Xregister struct uwpoint *pp;
X{
X	/*
X	 * Get the position of window "uwin" and store it in the point
X	 * whose address is "pp".
X	 */
X	if (uwin != (UWIN)0) {
X		if (pp != (struct uwpoint *)0) {
X			*pp = uwin->uwi_pos;
X			if (uwin->uwi_ctlfd > 0) {
X				return(0);
X			} else {
X				uwerrno = uwin->uwi_uwerr = UWE_NOCTL;
X				return(-1);
X			}
X		} else {
X			uwerrno = uwin->uwi_uwerr = UWE_INVAL;
X			return(-1);
X		}
X	} else {
X		uwerrno = UWE_INVAL;
X		return(-1);
X	}
X}
X
Xuw_spos(uwin, pp)
Xregister UWIN uwin;
Xstruct uwpoint *pp;
X{
X	union uwoptval optval;
X
X	/*
X	 * Set the position of window "uwin" to "pp".
X	 */
X	if (uwin != (UWIN)0) {
X		if (pp != (struct uwpoint *)0) {
X			uwin->uwi_pos = *pp;
X			optval.uwov_point.v = pp->uwp_v;
X			optval.uwov_point.h = pp->uwp_h;
X			return(uw_optcmd(uwin, UWOP_POS, UWOC_SET, &optval));
X		} else {
X			uwerrno = uwin->uwi_uwerr = UWE_INVAL;
X			return(-1);
X		}
X	} else {
X		uwerrno = UWE_INVAL;
X		return(-1);
X	}
X}
!EOF!lib/uw_gpos.c!
echo x - lib/uw_gtitle.c
sed -e 's/^X//' > lib/uw_gtitle.c << '!EOF!lib/uw_gtitle.c!'
X/*
X *	uw library - uw_gtitle, uw_stitle
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#include <strings.h>
X#include "uwlib.h"
X
Xuw_gtitle(uwin, ttl)
Xregister UWIN uwin;
Xuwtitle_t ttl;
X{
X	/*
X	 * Get the title of window "uwin" and put it in "ttl".
X	 */
X	if (uwin != (UWIN)0) {
X		(void)strncpy(ttl, uwin->uwi_title, sizeof(uwtitle_t));
X		if (uwin->uwi_ctlfd > 0) {
X			return(0);
X		} else {
X			uwerrno = uwin->uwi_uwerr = UWE_NOCTL;
X			return(-1);
X		}
X	} else {
X		uwerrno = UWE_INVAL;
X		return(-1);
X	}
X}
X
Xuw_stitle(uwin, ttl)
Xregister UWIN uwin;
Xuwtitle_t ttl;
X{
X	union uwoptval optval;
X
X	/*
X	 * Set the title of window "uwin" to "ttl".
X	 */
X	if (uwin != (UWIN)0) {
X		(void)strncpy(uwin->uwi_title, ttl, sizeof uwin->uwi_title);
X		uwin->uwi_title[sizeof uwin->uwi_title - 1] = '\0';
X		(void)strncpy(optval.uwov_string,ttl,sizeof optval.uwov_string);
X		optval.uwov_string[sizeof optval.uwov_string - 1] = '\0';
X		return(uw_optcmd(uwin, UWOP_TITLE, UWOC_SET, &optval));
X	} else {
X		uwerrno = UWE_INVAL;
X		return(-1);
X	}
X}
!EOF!lib/uw_gtitle.c!
echo x - lib/uw_gtype.c
sed -e 's/^X//' > lib/uw_gtype.c << '!EOF!lib/uw_gtype.c!'
X/*
X *	uw library - uw_gtype, uw_stype
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#include "uwlib.h"
X
Xuw_gtype(uwin, tp)
Xregister UWIN uwin;
Xregister uwtype_t *tp;
X{
X	/*
X	 * Get the type of the window "uwin".  The window type is stored
X	 * in the variable whose address is passed in "tp".
X	 */
X	if (uwin != (UWIN)0) {
X		if (tp != (uwtype_t *)0) {
X			*tp = uwin->uwi_type;
X			if (uwin->uwi_ctlfd > 0) {
X				return(0);
X			} else {
X				uwerrno = uwin->uwi_uwerr = UWE_NOCTL;
X				return(-1);
X			}
X		} else {
X			uwerrno = uwin->uwi_uwerr = UWE_INVAL;
X			return(-1);
X		}
X	} else {
X		uwerrno = UWE_INVAL;
X		return(-1);
X	}
X}
X
Xuw_stype(uwin, t)
Xregister UWIN uwin;
Xint t;
X{
X	union uwoptval optval;
X
X	/*
X	 * Set the type of window "uwin" to "t".
X	 */
X
X	if (uwin != (UWIN)0) {
X		if (t < UW_NWTYPES) {
X			uwin->uwi_type = t;
X			optval.uwov_6bit = uwin->uwi_type;
X			return(uw_optcmd(uwin, UWOP_TYPE, UWOC_SET, &optval));
X		} else {
X			uwerrno = uwin->uwi_uwerr = UWE_INVAL;
X			return(-1);
X		}
X	} else {
X		uwerrno = UWE_INVAL;
X		return(-1);
X	}
X}
!EOF!lib/uw_gtype.c!
echo x - lib/uw_gvis.c
sed -e 's/^X//' > lib/uw_gvis.c << '!EOF!lib/uw_gvis.c!'
X/*
X *	uw library - uw_gvis, uw_svis
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#include "uwlib.h"
X
Xuw_gvis(uwin, vp)
Xregister UWIN uwin;
Xregister int *vp;
X{
X	/*
X	 * Get the visibility status of the window "uwin".  "vp" is a
X	 * pointer to the integer where the status is returned.
X	 */
X	if (uwin != (UWIN)0) {
X		if (vp != (int *)0) {
X			*vp = uwin->uwi_vis;
X			if (uwin->uwi_ctlfd > 0) {
X				return(0);
X			} else {
X				uwerrno = uwin->uwi_uwerr = UWE_NOCTL;
X				return(-1);
X			}
X		} else {
X			uwerrno = uwin->uwi_uwerr = UWE_INVAL;
X			return(-1);
X		}
X	} else {
X		uwerrno = UWE_INVAL;
X		return(-1);
X	}
X}
X
Xuw_svis(uwin, v)
Xregister UWIN uwin;
Xint v;
X{
X	union uwoptval optval;
X
X	/*
X	 * Make window "uwin" visible (v != 0) or invisible (v == 0).
X	 */
X	if (uwin != (UWIN)0) {
X		uwin->uwi_vis = (v != 0);
X		optval.uwov_1bit = uwin->uwi_vis;
X		return(uw_optcmd(uwin, UWOP_VIS, UWOC_SET, &optval));
X	} else {
X		uwerrno = UWE_INVAL;
X		return(-1);
X	}
X}
!EOF!lib/uw_gvis.c!
echo x - lib/uw_gwsize.c
sed -e 's/^X//' > lib/uw_gwsize.c << '!EOF!lib/uw_gwsize.c!'
X/*
X *	uw library - uw_gwsize, uw_swsize
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#include "uwlib.h"
X
Xuw_gwsize(uwin, pp)
Xregister UWIN uwin;
Xregister struct uwpoint *pp;
X{
X	/*
X	 * Get the (pixel) size of window "uwin" and store it in the
X	 * point whose address is "pp".
X	 */
X	if (uwin != (UWIN)0) {
X		if (pp != (struct uwpoint *)0) {
X			*pp = uwin->uwi_wsize;
X			if (uwin->uwi_ctlfd > 0) {
X				return(0);
X			} else {
X				uwerrno = uwin->uwi_uwerr = UWE_NOCTL;
X				return(-1);
X			}
X		} else {
X			uwerrno = uwin->uwi_uwerr = UWE_INVAL;
X			return(-1);
X		}
X	} else {
X		uwerrno = UWE_INVAL;
X		return(-1);
X	}
X}
X
Xuw_swsize(uwin, pp)
Xregister UWIN uwin;
Xstruct uwpoint *pp;
X{
X	union uwoptval optval;
X
X	/*
X	 * Set the (pixel) size of window "uwin" to "pp".
X	 */
X	if (uwin != (UWIN)0) {
X		if (pp != (struct uwpoint *)0) {
X			uwin->uwi_wsize = *pp;
X			optval.uwov_point.v = pp->uwp_v;
X			optval.uwov_point.h = pp->uwp_h;
X			return(uw_optcmd(uwin, UWOP_WSIZE, UWOC_SET, &optval));
X		} else {
X			uwerrno = uwin->uwi_uwerr = UWE_INVAL;
X			return(-1);
X		}
X	} else {
X		uwerrno = UWE_INVAL;
X		return(-1);
X	}
X}
!EOF!lib/uw_gwsize.c!
echo x - lib/uw_kill.c
sed -e 's/^X//' > lib/uw_kill.c << '!EOF!lib/uw_kill.c!'
X/*
X *	uw library - uw_kill
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#include <sys/types.h>
X#include <netinet/in.h>
X
X#include "uwlib.h"
X
X#ifndef htons
X/* These should have been defined in <netinet/in.h>, but weren't (in 4.2BSD) */
Xextern unsigned short htons(), ntohs();
Xextern unsigned long htonl(), ntohl();
X#endif
X
Xuw_kill(uwin)
XUWIN uwin;
X{
X	register int len;
X	struct uwipc uwip;
X	extern int errno;
X
X	/*
X	 * Kill the window "uwin".  After putting out the contract,
X	 * destroy the evidence by closing all existing connections
X	 * to the window.
X	 */
X	if (uwin != (UWIN)0) {
X		if (uwin->uwi_ctlfd >= 0) {
X			len = sizeof uwip.uwip_killw +
X			    (char *)&uwip.uwip_killw - (char *)&uwip;
X			uwip.uwip_len = htons(len);
X			uwip.uwip_cmd = htons(UWC_KILLW);
X			uwip.uwip_killw.uwkw_id = htonl(uwin->uwi_id);
X			if (write(uwin->uwi_ctlfd, (char *)&uwip, len) < 0) {
X				uwin->uwi_errno = errno;
X				uwerrno = uwin->uwi_uwerr = UWE_ERRNO;
X			} else
X				uwerrno = uwin->uwi_uwerr = UWE_NONE;
X			(void)uw_detach(uwin);
X		} else
X			uwerrno = uwin->uwi_uwerr = UWE_NOCTL;
X		if (uwin->uwi_uwerr == UWE_NONE)
X			return(0);
X		else
X			return(-1);
X	} else {
X		uwerrno = UWE_INVAL;
X		return(-1);
X	}
X}
!EOF!lib/uw_kill.c!
echo x - lib/uw_netadj.c
sed -e 's/^X//' > lib/uw_netadj.c << '!EOF!lib/uw_netadj.c!'
X/*
X *	uw library - uw_new
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#include <sys/types.h>
X#include <sys/socket.h>
X#include <sys/un.h>
X#include <sys/ioctl.h>
X#include <sys/wait.h>
X#include <sys/time.h>
X#include <sys/resource.h>
X#include <sys/uio.h>
X#include <sys/file.h>
X#include <netinet/in.h>
X#include <strings.h>
X#include <signal.h>
X#include "openpty.h"
X
X#include "uw_opt.h"	/* I had hoped to avoid including this */
X#include "uwlib.h"
X
Xstatic woptarg_t woa_vis[] = { WOA_UDATA(1), WOA_END };
Xstatic woptarg_t woa_type[] = { WOA_UDATA(6), WOA_END };
Xstatic woptarg_t woa_pos[] = { WOA_UDATA(12), WOA_UDATA(12), WOA_END };
Xstatic woptarg_t woa_title[] = { WOA_STRING(255), WOA_END };
Xstatic woptarg_t woa_size[] = { WOA_UDATA(12), WOA_UDATA(12), WOA_END };
Xstatic woptarg_t woa_tsize[] = { WOA_UDATA(12), WOA_UDATA(12), WOA_END };
Xstatic woptarg_t woa_fontsz[] = { WOA_UDATA(6), WOA_END };
Xstatic woptarg_t woa_clipb[] = { WOA_UDATA(1), WOA_END };
Xstatic woptarg_t woa_bell[] = { WOA_UDATA(2), WOA_END };
Xstatic woptarg_t woa_curs[] = { WOA_UDATA(1), WOA_END };
Xstatic woptarg_t woa_chgsz[] = { WOA_UDATA(1), WOA_END };
X
Xstatic woptarg_t *optargs[][WONUM_MAX+1] = {
X	/* window type 0 == adm31 */
X	{
X		0, woa_vis, woa_type, woa_pos, woa_title, woa_size, 0, 0,
X		woa_tsize, woa_fontsz, woa_clipb, woa_bell, woa_curs, woa_chgsz
X	},
X	/* window type 1 == vt52 */
X	{
X		0, woa_vis, woa_type, woa_pos, woa_title, woa_size, 0, 0,
X		woa_tsize, woa_fontsz, woa_clipb, woa_bell, woa_curs, woa_chgsz
X	},
X	/* window type 2 == ansi */
X	{
X		0, woa_vis, woa_type, woa_pos, woa_title, woa_size, 0, 0,
X		woa_tsize, woa_fontsz, woa_clipb, woa_bell, woa_curs, woa_chgsz
X	},
X	/* window type 3 = tek4010 */
X	{
X		0, woa_vis, woa_type, woa_pos, woa_title, woa_size, 0, 0,
X	},
X	/* window type 4 = file transfer */
X	{
X		0, woa_vis, woa_type, woa_pos, woa_title, woa_size, 0, 0,
X	},
X	/* window type 5 = printer */
X	{
X		0, woa_vis, woa_type, woa_pos, woa_title, woa_size, 0, 0,
X	},
X};
X
X#ifdef htons
Xuw_hton(wtype, optnum, data)
Xuwtype_t wtype;
Xuwopt_t optnum;
Xchar *data;
X{
X}
X
Xuw_ntoh(wtype, optnum, data)
Xuwtype_t wtype;
Xuwopt_t optnum;
Xchar *data;
X{
X}
X
X#else
X/* These should have been defined in <netinet/in.h> but weren't (in 4.2BSD) */
Xextern unsigned short htons(), ntohs();
Xextern unsigned long htonl(), ntohl();
X
Xuw_hton(wtype, optnum, data)
Xuwtype_t wtype;
Xuwopt_t optnum;
Xchar *data;
X{
X	static struct netadj na = {
X		(short (*)())htons, (long (*)())htonl, htons, htonl
X	};
X	if (data != (char *)0 && wtype < sizeof optargs / sizeof optargs[0] &&
X	    optnum <= WONUM_MAX && optargs[wtype][optnum] != (woptarg_t *)0) {
X		netadj(optargs[wtype][optnum], data, &na);
X	}
X}
X
Xuw_ntoh(wtype, optnum, data)
Xuwtype_t wtype;
Xuwopt_t optnum;
Xchar *data;
X{
X	static struct netadj na = {
X		(short (*)())ntohs, (long (*)())ntohl, ntohs, ntohl
X	};
X	if (data != (char *)0 && wtype < sizeof optargs / sizeof optargs[0] &&
X	    optnum <= WONUM_MAX && optargs[wtype][optnum] != (woptarg_t *)0) {
X		netadj(optargs[wtype][optnum], data, &na);
X	}
X}
X
Xstatic
Xnetadj(woa, data, na)
Xregister woptarg_t *woa;
Xchar *data;
Xregister struct netadj *na;
X{
X	register char *cp;
X	register int cnt;
X	union {
X		struct {
X			char	c1;
X			short	s;
X		}	cs;
X		struct {
X			char	c2;
X			long	l;
X		}	cl;
X	} u;
X
X	/*
X	 * Convert an option between host byte order and network byte order.
X	 */
X	if (data && na) {
X		for (cp=data; *woa != WOA_END; woa++) {
X			cnt = *woa & ~WOA_CMDMASK;
X			switch (*woa & WOA_CMDMASK) {
X			case WOA_CHARS(0):
X			case WOA_STRING(0):
X				cp += cnt;
X				break;
X			case WOA_UDATA(0):
X				if (cnt <= NBBY) {
X					cp++;
X				} else if (cnt <= sizeof(short)*NBBY) {
X					while ((int)cp & ((char *)&u.cs.s-&u.cs.c1-1))
X						cp++;
X					*(u_short *)cp =
X					    (*na->na_ushort)(*(u_short *)cp);
X					cp += sizeof(short);
X				} else {
X					while ((int)cp & ((char *)&u.cl.l-&u.cl.c2-1))
X						cp++;
X					*(u_short *)cp =
X					    (*na->na_ushort)(*(u_short *)cp);
X					cp += sizeof(long);
X				}
X			}
X		}
X	}
X}
X#endif
!EOF!lib/uw_netadj.c!
echo x - lib/uw_new.c
sed -e 's/^X//' > lib/uw_new.c << '!EOF!lib/uw_new.c!'
X/*
X *	uw library - uw_new
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#include <sys/types.h>
X#include <sys/socket.h>
X#include <netinet/in.h>
X#include <sys/uio.h>
X#include <strings.h>
X#include <signal.h>
X#include <netdb.h>
X#include <ctype.h>
X#include "openpty.h"
X
X#include "uwlib.h"
X
Xextern char *malloc();
Xextern char *getenv();
X
X#ifndef htons
X/* These should have been defined in <netinet/in.h>, but weren't (in 4.2BSD) */
Xextern unsigned short htons(), ntohs();
Xextern unsigned long htonl(), ntohl();
X#endif
X
XUWIN
Xuw_new(uwtype, sin)
Xuwtype_t uwtype;
Xstruct sockaddr_in *sin;
X{
X	register UWIN uwin;
X	register char *cp, c;
X	register int len;
X	register int ctlfd;
X	int rdsz;
X	auto int namelen;
X	auto struct sockaddr_in sa, datasin, ctlsin;
X	auto struct uwipc uwip;
X	extern int errno;
X
X	/*
X	 * If our caller didn't supply an address for us to contact,
X	 * look in the environment to find it.
X	 */
X	if (sin == (struct sockaddr_in *)0) {
X		if ((cp = getenv(INET_ENV)) == (char *)0) {
X			uwerrno = UWE_NXSERV;
X			return((UWIN)0);
X		}
X		sin = &sa;
X		sa.sin_family = AF_INET;
X		sa.sin_addr.s_addr = 0;
X		sa.sin_port = 0;
X		bzero(sa.sin_zero, sizeof sa.sin_zero);
X		for ( ; isxdigit(c = *cp); cp++) {
X			/* Pyramid compiler blows this, must use left shift */
X			/* sa.sin_addr.s_addr *= 16; */
X			sa.sin_addr.s_addr <<= 4;
X			if (isdigit(c))
X				sa.sin_addr.s_addr += c-'0';
X			else if (islower(c))
X				sa.sin_addr.s_addr += c-'a' + 10;
X			else
X				sa.sin_addr.s_addr += c-'A' + 10;
X		}
X		if (c == '.') {
X			for (cp++; isdigit(c = *cp); cp++)
X				sa.sin_port = sa.sin_port*10 + c-'0';
X		}
X		if (sa.sin_addr.s_addr == 0 || sa.sin_port == 0 ||
X		    c != '\0') {
X			/* bad address */
X			uwerrno = UWE_INVAL;
X			return((UWIN)0);
X		}
X		sa.sin_addr.s_addr = htonl(sa.sin_addr.s_addr);
X		sa.sin_port = htons(sa.sin_port);
X	}
X
X	/*
X	 * Allocate space for a new window structure.
X	 */
X	if ((uwin = (UWIN)malloc(sizeof(*uwin))) == (UWIN)0) {
X		uwerrno = UWE_NOMEM;
X		return((UWIN)0);
X	}
X	uwin->uwi_type = uwtype;
X	for (len=0; len < UW_NUMOPTS; len++) /* "len" is a convenient "int" */
X		uwin->uwi_options[len].uwi_optfn = (uwfnptr_t)0;
X	
X	/*
X	 * Create sockets for the data and control file descriptors.
X	 */
X	if ((uwin->uwi_datafd = socket(AF_INET, SOCK_STREAM, 0)) < 0 ||
X	    (uwin->uwi_ctlfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
X		if (uwin->uwi_datafd >= 0)
X			(void)close(uwin->uwi_datafd);
X		return((UWIN)0);
X	}
X
X	/*
X	 * Bind these sockets to a local address.  We figure out the
X	 * local machine's host number and use it if possible; otherwise,
X	 * we fall back to 127.0.0.1 (loopback device).  After binding,
X	 * we determine the port number for the control socket, since we
X	 * must send that to the server.  Connect to the server.
X	 */
X	datasin.sin_family = AF_INET;
X	datasin.sin_port = 0;
X	bzero(datasin.sin_zero, sizeof datasin.sin_zero);
X	getmyaddr(&datasin.sin_addr);
X	ctlsin.sin_family = AF_INET;
X	ctlsin.sin_port = 0;
X	bzero(ctlsin.sin_zero, sizeof ctlsin.sin_zero);
X	getmyaddr(&ctlsin.sin_addr);
X	if (bind(uwin->uwi_datafd, (struct sockaddr *)&datasin, sizeof datasin) < 0 ||
X	    bind(uwin->uwi_ctlfd, (struct sockaddr *)&ctlsin, sizeof ctlsin) < 0 ||
X	    listen(uwin->uwi_ctlfd, 1) < 0) {
X		uwerrno = UWE_ERRNO;
X		goto error;
X	}
X	namelen = sizeof ctlsin;
X	(void)getsockname(uwin->uwi_ctlfd, (char *)&ctlsin, &namelen);
X
X	if (connect(uwin->uwi_datafd, sin, sizeof(struct sockaddr_in)) < 0) {
X		uwerrno = UWE_ERRNO;
X		goto error;
X	}
X
X	/*
X	 * Now we have enough information to build the new-window command
X	 * and send it to the server.  The initial command is sent to the
X	 * data port.  Next, we wait for a connection from the server to
X	 * our data socket.  Finally, we expect the server to send us a
X	 * new window status message on the data fd.
X	 */
X	len = sizeof uwip.uwip_neww + (char *)&uwip.uwip_neww - (char *)&uwip;
X	uwip.uwip_len = htons(len);
X	uwip.uwip_cmd = htons(UWC_NEWW);
X	uwip.uwip_neww.uwnw_id = 0;	/* let server choose this */
X	uwip.uwip_neww.uwnw_type = htons(uwtype);
X	uwip.uwip_neww.uwnw_ctlport = ctlsin.sin_port;/* byte order correct */
X	if (write(uwin->uwi_datafd, (char *)&uwip, len) < 0) {
X		uwerrno = UWE_ERRNO;
X		goto error;
X	}
X	
X	namelen = sizeof ctlsin;
X	if ((ctlfd = accept(uwin->uwi_ctlfd, (struct sockaddr_in *)&ctlsin, &namelen)) < 0) {
X		uwerrno = UWE_ERRNO;
X		goto error;
X	}
X	(void)close(uwin->uwi_ctlfd);
X	uwin->uwi_ctlfd = ctlfd;
X	uw_optinit(ctlfd, uwin);
X
X	cp = (char *)&uwip.uwip_len;
X	rdsz = sizeof uwip.uwip_len;
X	while (rdsz > 0 && (len=read(uwin->uwi_datafd, cp, rdsz)) > 0) {
X		cp += len;
X		rdsz -= len;
X	}
X	if (len > 0) {
X		rdsz = htons(uwip.uwip_len) - sizeof uwip.uwip_len;
X		while (rdsz > 0 && (len=read(uwin->uwi_datafd, cp, rdsz)) > 0) {
X			cp += len;
X			rdsz -= len;
X		}
X	}
X	if (len <= 0) {
X		uwerrno = UWE_ERRNO;
X		goto error;
X	}
X	uwerrno = uwin->uwi_uwerr = ntohs(uwip.uwip_status.uwst_err);
X	errno = uwin->uwi_errno = ntohs(uwip.uwip_status.uwst_errno);
X	if (uwin->uwi_uwerr != UWE_NONE)
X		goto error;
X	uwin->uwi_id = ntohl(uwip.uwip_status.uwst_id);
X	return(uwin);
X
Xerror:
X	(void)close(uwin->uwi_datafd);
X	(void)close(uwin->uwi_ctlfd);
X	free((char *)uwin);
X	return((UWIN)0);
X}
X
Xstatic
Xgetmyaddr(addr)
Xstruct in_addr *addr;
X{
X	register struct hostent *h;
X	char hostname[32];
X	static int once = 1;
X	static struct in_addr myaddr;
X
X	if (once) {
X		if (gethostname(hostname, sizeof hostname) < 0) {
X			(void)strncpy(hostname, "localhost", sizeof hostname-1);
X			hostname[sizeof hostname-1] = '\0';
X		}
X		if ((h = gethostbyname(hostname)) != (struct hostent *)0)
X			myaddr = *(struct in_addr *)h->h_addr;
X		else
X			myaddr.s_addr = htonl(0x7f000001L);
X		once = 0;
X	}
X	*addr = myaddr;
X}
!EOF!lib/uw_new.c!
echo x - lib/uw_optcmd.c
sed -e 's/^X//' > lib/uw_optcmd.c << '!EOF!lib/uw_optcmd.c!'
X/*
X *	uw library - uw_optcmd
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#include <sys/types.h>
X#include <netinet/in.h>
X
X#include "uwlib.h"
X
X#ifndef htons
X/* These should have been defined in <netinet/in.h>, but weren't (in 4.2BSD) */
Xextern unsigned short htons(), ntohs();
Xextern unsigned long htonl(), ntohl();
X#endif
X
Xuw_optcmd(uwin, optnum, optcmd, optval)
XUWIN uwin;
Xuwopt_t optnum;
Xuwoptcmd_t optcmd;
Xunion uwoptval *optval;
X{
X	register int len;
X	struct uwipc uwip;
X	extern int errno;
X
X	/*
X	 * Send an option command string to the server (and eventually
X	 * to the Macintosh).
X	 */
X	if (uwin != (UWIN)0) {
X		if (uwin->uwi_ctlfd >= 0) {
X			if (optnum < UW_NUMOPTS) {
X				len = sizeof uwip;
X				uwip.uwip_len = htons(len);
X				uwip.uwip_cmd = htons(UWC_OPTION);
X				uwip.uwip_option.uwop_id = htonl(uwin->uwi_id);
X				uwip.uwip_option.uwop_opt = htons(optnum);
X				uwip.uwip_option.uwop_cmd = htons(optcmd);
X				switch (optcmd) {
X				case UWOC_SET:
X					if (optval == (union uwoptval *)0) {
X						uwin->uwi_uwerr = UWE_INVAL;
X						break;
X					} 
X					uwip.uwip_option.uwop_val = *optval;
X					uw_hton(uwin->uwi_type, optnum,
X					    (char *)&uwip.uwip_option.uwop_val);
X					/* no break */
X				case UWOC_ASK:
X				case UWOC_DO:
X				case UWOC_DONT:
X				case UWOC_WILL:
X				case UWOC_WONT:
X					if (write(uwin->uwi_ctlfd, (char *)&uwip,
X					    len) < 0) {
X						uwin->uwi_uwerr = UWE_ERRNO;
X						uwin->uwi_errno = errno;
X					} else
X						uwin->uwi_uwerr = UWE_NONE;
X					break;
X				default:
X					uwin->uwi_uwerr = UWE_INVAL;
X					break;
X				}
X			} else
X				uwin->uwi_uwerr = UWE_INVAL;
X		}
X		uwerrno = uwin->uwi_uwerr;
X		if (uwin->uwi_uwerr == UWE_NONE)
X			return(0);
X		else
X			return(-1);
X	} else {
X		uwerrno = UWE_INVAL;
X		return(-1);
X	}
X}
!EOF!lib/uw_optcmd.c!
echo x - lib/uw_optfn.c
sed -e 's/^X//' > lib/uw_optfn.c << '!EOF!lib/uw_optfn.c!'
X/*
X *	uw library - uw_optfn
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#include "uwlib.h"
X
Xuwfnptr_t
Xuw_optfn(uwin, optnum, optfn)
XUWIN uwin;
Xuwopt_t optnum;
Xuwfnptr_t optfn;
X{
X	uwfnptr_t oldfn;
X
X	/*
X	 * Establish an option-processing function (defined by the host).
X	 * The specified function will be called whenever an option message
X	 * is received from the server.  The previous function is returned.
X	 */
X	oldfn = (uwfnptr_t)0;
X	if (uwin != (UWIN)0) {
X		if (optnum < UW_NUMOPTS) {
X			oldfn = uwin->uwi_options[optnum].uwi_optfn;
X			uwin->uwi_options[optnum].uwi_optfn = optfn;
X			uwin->uwi_uwerr = UWE_NONE;
X		} else
X			uwin->uwi_uwerr = UWE_INVAL;
X	}
X	uwerrno = uwin->uwi_uwerr;
X	return(oldfn);
X}
!EOF!lib/uw_optfn.c!
echo x - lib/uw_options.c
sed -e 's/^X//' > lib/uw_options.c << '!EOF!lib/uw_options.c!'
X/*
X *	uw library - uw_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#include <sys/types.h>
X#include <sys/file.h>
X#include <sys/time.h>
X#include <netinet/in.h>
X#include <strings.h>
X#include <signal.h>
X#include <errno.h>
X
X#include "uwlib.h"
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#ifndef sigmask
X#define sigmask(m)	(1 << ((m)-1))
X#endif
X
X#ifndef htons
X/* These should have been defined in <netinet/in.h>, but weren't (in 4.2BSD) */
Xextern unsigned short htons(), ntohs();
Xextern unsigned long htonl(), ntohl();
X#endif
X
Xstatic UWIN *fdmap;
Xstatic int (*oldsigio)();
Xstatic struct fd_set fdmask;
Xstatic int nfds;
X
Xextern char *malloc();
X
Xuw_optinit(fd, uwin)
Xint fd;
XUWIN uwin;
X{
X	register int i, flags;
X	static int first = 1;
X	extern uw_optinput();
X
X	/*
X	 * The first time through, allocate the file descriptor map and
X	 * bitmask, and cause SIGIO traps to be handled by uw_optinput.
X	 */
X	if (first) {
X		first = 0;
X		nfds = getdtablesize();
X		fdmap = (UWIN *)malloc((unsigned)(sizeof(UWIN)*nfds));
X		if (fdmap != (UWIN *)0)
X			for (i = 0; i < nfds; i++)
X				fdmap[i] = (UWIN)0;
X		oldsigio = signal(SIGIO, uw_optinput);
X		FD_ZERO(&fdmask);
X	}
X
X	/*
X	 * Add the new control fd to the map and mask.  Set the owner
X	 * to this process
X	 */
X	if (fd >= 0 && fd < nfds && uwin != (UWIN)0 && fdmap != (UWIN *)0) {
X		fdmap[fd] = uwin;
X		FD_SET(fd, &fdmask);
X#ifdef SETOWN_BUG
X		(void)fcntl(fd, F_SETOWN, -getpid());
X#else
X		(void)fcntl(fd, F_SETOWN, getpid());
X#endif
X		if ((flags = fcntl(fd, F_GETFL, 0)) >= 0)
X			(void)fcntl(fd, F_SETFL, flags|FASYNC|FNDELAY);
X		uwin->uwi_ipclen = 0;
X	}
X}
X
Xuw_optdone(fd)
X{
X	register int flags;
X
X	/*
X	 * Turn off asynchronous I/O notification and remove the
X	 * map and mask information for "fd".  We do not close the
X	 * file descriptor, however -- the caller is expected to
X	 * take care of that.
X	 */
X	if (fd >= 0 && fd < nfds && fdmap != (UWIN *)0) {
X		if ((flags = fcntl(fd, F_GETFL, 0)) >= 0)
X			(void)fcntl(fd, F_SETFL, flags&~FASYNC);
X		else
X			(void)fcntl(fd, F_SETFL, 0);
X		(void)fcntl(fd, F_SETFL, 0);
X		fdmap[fd] = (UWIN)0;
X		FD_CLR(fd, &fdmask);
X	}
X}
X
Xstatic
Xuw_optinput(sig, code, scp)
Xint sig, code;
Xstruct sigcontext *scp;
X{
X	register int k, n, fd;
X	register UWIN uwin;
X	register struct uwoption *uwop;
X	register union uwoptval *uwov;
X	uwopt_t optnum;
X	uwoptcmd_t optcmd;
X	uwfnptr_t userfn;
X	int oldmask;
X	struct timeval timeo;
X	struct fd_set ready;
X	extern int errno;
X
X	/*
X	 * This routine is called when input is waiting on a control
X	 * file descriptor.
X	 */
X	oldmask = sigblock(sigmask(SIGALRM));
X	do {
X		ready = fdmask;
X		timeo.tv_sec = 0;
X		timeo.tv_usec = 0;
X		n = select(nfds, &ready, (struct fd_set *)0,
X			   (struct fd_set *)0, &timeo);
X		if (n < 0 && errno == EBADF) {
X			/*
X			 * One of the file descriptors that we asked for
X			 * is no longer valid.  This isn't supposed to
X			 * happen; however, we try to handle it by testing
X			 * each bit individually and eliminating the bad
X			 * ones.
X			 */
X			for (fd=0; fd < nfds; fd++) {
X				if (FD_ISSET(fd, &fdmask)) {
X					do {
X						ready = fdmask;
X						timeo.tv_sec = 0;
X						timeo.tv_usec = 0;
X						k = select(nfds, &ready,
X						    (struct fd_set *)0,
X						    (struct fd_set *)0, &timeo);
X						if (k < 0 && errno == EBADF) {
X							fdmap[fd] = (UWIN)0;
X							FD_CLR(fd, &fdmask);
X						}
X					} while (n < 0 && errno == EINTR);
X				}
X			}
X		}
X	} while (n < 0 && errno == EINTR);
X
X	for (fd=0; n > 0 && fd < nfds; fd++) {
X		if (FD_ISSET(fd, &ready)) {
X			n--;
X			uwin = fdmap[fd];
X			while ((k = getmesg(fd, uwin)) > 0) {
X				uwin->uwi_ipclen = 0;	/* for next time */
X				if (uwin->uwi_ipcbuf.uwip_cmd == UWC_OPTION) {
X					uwop = &uwin->uwi_ipcbuf.uwip_option;
X					uwov = &uwop->uwop_val;
X					optnum = ntohs(uwop->uwop_opt);
X					optcmd = ntohs(uwop->uwop_cmd);
X					if (optcmd == UWOC_SET)
X						uw_ntoh(uwin->uwi_type, optnum,
X						    (char *)uwov);
X					if (optcmd == UWOC_SET) switch(optnum) {
X					case UWOP_VIS:
X						uwin->uwi_vis = !!uwov->uwov_6bit;
X						break;
X					case UWOP_TYPE:
X						if (uwov->uwov_6bit<UW_NWTYPES)
X							uwin->uwi_type=uwov->uwov_6bit;
X						break;
X					case UWOP_POS:
X						uwin->uwi_pos.uwp_v = uwov->uwov_point.v;
X						uwin->uwi_pos.uwp_h = uwov->uwov_point.h;
X						break;
X					case UWOP_TITLE:
X						(void)strncpy(uwin->uwi_title,
X						    uwov->uwov_string,
X						    sizeof uwin->uwi_title);
X						break;
X					case UWOP_WSIZE:
X						uwin->uwi_wsize.uwp_v = uwov->uwov_point.v;
X						uwin->uwi_wsize.uwp_h = uwov->uwov_point.h;
X						break;
X					}
X					if (optnum == UWOP_TYPE &&
X					    optcmd == UWOC_SET &&
X					    uwov->uwov_6bit < UW_NWTYPES)
X						uwin->uwi_type=uwov->uwov_6bit;
X					userfn = uwin->uwi_options[optnum].uwi_optfn;
X					if (userfn != (uwfnptr_t)0)
X						(*userfn)(uwin, optnum,
X							  optcmd, uwov);
X				}
X			}
X			if (k < 0)
X				(void)uw_detach(uwin);	/* I/O error or EOF */
X		}
X	}
X	(void)sigsetmask(oldmask);
X
X	/*
X	 * Finally, if "oldsigio" is not SIG_DFL, call it.
X	 */
X	if (oldsigio != SIG_DFL)
X		(*oldsigio)(sig, code, scp);
X}
X
Xstatic
Xgetmesg(fd, uwin)
Xregister int fd;
Xregister UWIN uwin;
X{
X	register int len;
X	register char *cp;
X
X	/*
X	 * Read some more bytes from control socket "fd" into the input
X	 * buffer.  Return 1 if the message is now complete, -1 if an
X	 * EOF was reached, or 0 otherwise.  Before returning 1, the byte
X	 * order of the common parameters (command, length) is changed
X	 * from network to host order.
X	 */
X	cp = (char *)&uwin->uwi_ipcbuf + uwin->uwi_ipclen;
X	if (uwin->uwi_ipclen < sizeof(uwin->uwi_ipcbuf.uwip_len)) {
X		len = read(fd, cp, sizeof uwin->uwi_ipcbuf.uwip_len - uwin->uwi_ipclen);
X		if (len == 0 || (len < 0 && errno != EWOULDBLOCK))
X			return(-1);
X		if (len < 0)
X			return(0);
X		if ((uwin->uwi_ipclen +=len) < sizeof uwin->uwi_ipcbuf.uwip_len)
X			return(0);
X		uwin->uwi_ipcbuf.uwip_len = ntohs(uwin->uwi_ipcbuf.uwip_len);
X		if (uwin->uwi_ipcbuf.uwip_len==sizeof uwin->uwi_ipcbuf.uwip_len)
X			return(1);
X		cp += len;
X	}
X	if (uwin->uwi_ipcbuf.uwip_len > sizeof(struct uwipc))
X		uwin->uwi_ipcbuf.uwip_len = sizeof(struct uwipc);
X	len = read(fd, cp, uwin->uwi_ipcbuf.uwip_len - uwin->uwi_ipclen);
X	if (len == 0 || (len < 0 && errno != EWOULDBLOCK))
X		return(-1);
X	if ((uwin->uwi_ipclen += len) == uwin->uwi_ipcbuf.uwip_len) {
X		uwin->uwi_ipcbuf.uwip_cmd = ntohs(uwin->uwi_ipcbuf.uwip_cmd);
X		return(1);
X	} else
X		return(0);
X}
!EOF!lib/uw_options.c!
echo x - lib/uw_perror.c
sed -e 's/^X//' > lib/uw_perror.c << '!EOF!lib/uw_perror.c!'
X/*
X *	uw library - uw_perror
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#include "uwlib.h"
X
Xchar *uwerrlist[] = {
X	"no error",
X	"system call error",
X	"nonexistent window type",
X	"window ID duplicated (in use)",
X	"operation not implemented",
X	"non-existent server",
X	"unable to allocate required memory",
X	"invalid argument to function",
X	"no control file descriptor for window",
X};
Xunsigned uwnerr = sizeof uwerrlist / sizeof uwerrlist[0];
X
Xint uwerrno;
X
X/*ARGSUSED*/
Xvoid
Xuw_perror(mesg, uwerr, errno)
Xchar *mesg;
Xuwerr_t uwerr;
Xint errno;
X{
X	register char *errmsg;
X
X	/*
X	 * Print a UW error message.  We call write() directly to avoid
X	 * making the UW library dependent upon stdio.
X	 */
X	if (uwerr == UWE_ERRNO) {
X		perror(mesg);
X	} else {
X		if (mesg != (char *)0) {
X			(void)write(2, mesg, strlen(mesg));
X			(void)write(2, ": ", 2);
X		}
X		if (uwerr >= uwnerr)
X			errmsg = "unknown UW error";
X		else
X			errmsg = uwerrlist[uwerr];
X		(void)write(2, errmsg, strlen(errmsg));
X		(void)write(2, "\n", 1);
X	}
X}
!EOF!lib/uw_perror.c!
echo x - lib/uw_rsetopt.c
sed -e 's/^X//' > lib/uw_rsetopt.c << '!EOF!lib/uw_rsetopt.c!'
X/*
X *	uw library - uw_rsetopt
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#include <sys/types.h>
X#include <sys/socket.h>
X#include <sys/un.h>
X#include <sys/ioctl.h>
X#include <sys/uio.h>
X#include <sys/file.h>
X#include <strings.h>
X#include <signal.h>
X#include "openpty.h"
X
X#include "uwlib.h"
X
Xextern char *malloc();
Xextern char *getenv();
X
Xuw_rsetopt(uwid, optnum, optval)
Xuwid_t uwid;
Xuwopt_t optnum;
Xunion uwoptval *optval;
X{
X	register int sd;
X	register struct uwipc *uwip;
X	char *portal;
X	struct iovec iov;
X	struct msghdr msg;
X	struct sockaddr_un sa;
X
X	/*
X	 * Set a window option on a remote window (that is, one for which
X	 * we do not have a control fd).
X	 */
X
X	/*
X	 * Create a UNIX-domain socket.
X	 */
X	if (!(portal=getenv("UW_UIPC"))) {
X		uwerrno = UWE_NXSERV;
X		return(-1);
X	}
X
X	if ((sd=socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) {
X		uwerrno = UWE_ERRNO;
X		return(-1);
X	}
X	sa.sun_family = AF_UNIX;
X	(void)strncpy(sa.sun_path, portal, sizeof sa.sun_path-1);
X	sa.sun_path[sizeof sa.sun_path-1] = '\0';
X
X
X	/*
X	 * Construct the datagram we will send later.
X	 */
X	uwip = (struct uwipc *)malloc(sizeof(struct uwipc));
X	if (uwip == (struct uwipc *)0) {
X		uwerrno = UWE_NOMEM;
X		return(-1);
X	}
X	uwip->uwip_cmd = UWC_OPTION;
X	uwip->uwip_len = sizeof(struct uwipc);
X	uwip->uwip_option.uwop_id = uwid;
X	uwip->uwip_option.uwop_cmd = UWOC_SET;
X	uwip->uwip_option.uwop_opt = optnum;
X	uwip->uwip_option.uwop_val = *optval;
X
X	/*
X	 * Pass the file descriptor to the window server.
X	 */
X	iov.iov_base = (char *)uwip;
X	iov.iov_len = uwip->uwip_len;
X	msg.msg_name = (caddr_t)&sa;
X	msg.msg_namelen = sizeof sa.sun_family + strlen(sa.sun_path);
X	msg.msg_iov = &iov;
X	msg.msg_iovlen = 1;
X	msg.msg_accrights = (caddr_t)0;
X	msg.msg_accrightslen = 0;
X	if (sendmsg(sd, &msg, 0) < 0) {
X		free((char *)uwip);
X		uwerrno = UWE_ERRNO;
X		return(-1);
X	}
X	free((char *)uwip);
X	uwerrno = UWE_NONE;
X	return(0);
X}
!EOF!lib/uw_rsetopt.c!
echo x - lib/uw_shell.c
sed -e 's/^X//' > lib/uw_shell.c << '!EOF!lib/uw_shell.c!'
X/*
X *	uw library - uw_shell
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#include "uwlib.h"
X
Xchar *uwshellname = "/bin/sh";	/* can be patched by caller if desired */
X
Xuwid_t
Xuw_shell(wtype, cmd)
Xuwtype_t wtype;
Xchar *cmd;
X{
X	register uwid_t uwid;
X
X	/*
X	 * Create a new window (using uw_fork()) and execute the specified
X	 * shell command in it.  Returns the window ID of the new window
X	 * (or -1 if the window creation failed)  There is no way to
X	 * determine if the executed command failed.
X	 */
X	if ((uwid = uw_fork(wtype, (int *)0)) == 0) {
X		(void)execl(uwshellname, uwshellname, "-c", cmd, (char *)0);
X		_exit(1);	/* we'd better not reach this point */
X		/*NOTREACHED*/
X	} else
X		return(uwid);
X}
!EOF!lib/uw_shell.c!
echo x - lib/uw_ttype.c
sed -e 's/^X//' > lib/uw_ttype.c << '!EOF!lib/uw_ttype.c!'
X/*
X *	uw library - uw_ttype
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#include <strings.h>
X#include "uwlib.h"
X
Xstruct table {
X	char		*tname;
X	uwtype_t	wtype;
X};
X
X/* The following table must be sorted */
Xstatic struct table table[] = {
X	{ "aaa-24", UWT_ANSI },
X	{ "adm3", UWT_ADM31 },
X	{ "adm31", UWT_ADM31 },
X	{ "adm3a", UWT_ADM31 },
X	{ "ansi", UWT_ANSI },
X	{ "tek", UWT_TEK4010 },
X	{ "tek4010", UWT_TEK4010 },
X	{ "tek4012", UWT_TEK4010 },
X	{ "vt52", UWT_VT52 },
X};
X
Xuwtype_t
Xuw_ttype(name)
Xchar *name;
X{
X	register struct table *t, *lo, *hi;
X	register int cmp;
X
X	/*
X	 * Map a terminal name string to a UW window emulation type.
X	 */
X	lo = table;
X	hi = table + sizeof table / sizeof table[0] - 1;
X	while (lo <= hi) {
X		t = lo + (hi-lo) / 2;
X		cmp = strcmp(name, t->tname);
X		if (cmp == 0)
X			return(t->wtype);
X		if (cmp < 0)
X			hi = t-1;
X		else
X			lo = t+1;
X	}
X	return(UWT_ADM31);	/* default if no match */
X}
!EOF!lib/uw_ttype.c!
exit 0
: end of shell archive (part 4 of 9)
Technical Details
Message-ID: <1690@felix.UUCP>
Path: arc1-ca.pugleaf.net!utzoo!decvax!ucbvax!dual!unisoft!lll-lcc!lll-crg!mordor!sri-spam!sri-unix!hplabs!felix!macintosh
References: <1687@felix.UUCP> <1688@felix.UUCP> <1689@felix.UUCP>

Show Full Headers
Complete Article Headers
Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Path: arc1-ca.pugleaf.net!utzoo!decvax!ucbvax!dual!unisoft!lll-lcc!lll-crg!mordor!sri-spam!sri-unix!hplabs!felix!macintosh
From: jdb@mordor.ARPA (John Bruner)
Newsgroups: mod.mac.sources
Subject: UW v3.4 (part 4 of 9)
Message-ID: <1690@felix.UUCP>
Date: Thu, 23-Oct-86 15:58:45 EDT
Article-I.D.: felix.1690
Posted: Thu Oct 23 15:58:45 1986
Date-Received: Sat, 25-Oct-86 02:07:28 EDT
References: <1687@felix.UUCP> <1688@felix.UUCP> <1689@felix.UUCP>
Sender: macintosh@felix.UUCP
Reply-To: macintosh@felix.UUCP (The Moderator)
Organization: FileNet Corp., Costa Mesa, CA
Lines: 1805
Approved: bytebug@felix.UUCP (Roger L. Long)