Article View: comp.sources.mac
Article #42UW v4.2 (part 9 of 9)
From: John Bruner
Date: Fri, 08 Apr 1988 14:39
Date: Fri, 08 Apr 1988 14:39
1266 lines
33028 bytes
33028 bytes
[UW v4.2 - part 9 of 9]
---
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
# utility/Makefile_4.2
# utility/Makefile_4.3
# utility/uwplot.c
# utility/uwterm.c
# utility/uwtitle.c
# utility/uwtool.c
# This archive created: Mon Apr 4 07:52:15 1988
# By: Roger L. Long (macintosh@dhw68k.cts.com)
export PATH; PATH=/bin:$PATH
if test ! -d utility
then
echo shar: mkdir utility
mkdir utility
fi
echo shar: extracting "'utility/Makefile_4.2'" '(1893 characters)'
if test -f 'utility/Makefile_4.2'
then
echo shar: will not over-write existing file "'utility/Makefile_4.2'"
else
sed 's/^X//' << \SHAR_EOF > 'utility/Makefile_4.2'
X#! /bin/make -f
X#
X# uw utility makefile (4.2BSD)
X#
X# INCDIR should be set to the directory containing header files.
X#
X# LIBUW should be set to the name of the library file (or, if it is
X# installed in a system directory, "-luw").
X#
X# Note: in order for "uwterm" to work on remote machines it is
X# necessary for it to be installed in a directly where "rsh"
X# will find it. The #defined symbol UWTERM in the source can
X# be set to the desired absolute pathname, if necessary.
X#
X
XINCDIR = ../h
X
XLIBUW = ../lib/libuw.a
X
XUWTOOL_OBJS = uwtool.o
XUWTITLE_OBJS = uwtitle.o
XUWTERM_OBJS = uwterm.o
XUWPLOT_OBJS = uwplot.o
X
XOBJECTS = $(UWTOOL_OBJS) $(UWTITLE_OBJS) $(UWTERM_OBJS) $(UWPLOT_OBJS)
X
XSOURCES = `echo $(OBJECTS) | sed -e 's/\\.o/\\.c/g'`
X
XDEFINES = `cat ../DEFINES`
X
XCFLAGS = -O -I$(INCDIR) $(DEFINES)
XLFLAGS =
X
Xall: uwtool uwtitle uwterm uwplot
X
Xuwtool: $(UWTOOL_OBJS)
X $(CC) -o $@ $(LFLAGS) $(UWTOOL_OBJS) $(LIBUW)
X
Xuwtitle: $(UWTITLE_OBJS)
X $(CC) -o $@ $(LFLAGS) $(UWTITLE_OBJS) $(LIBUW)
X
Xuwterm: $(UWTERM_OBJS)
X $(CC) -o $@ $(LFLAGS) $(UWTERM_OBJS) $(LIBUW)
X
Xuwplot: $(UWPLOT_OBJS)
X $(CC) -o $@ $(LFLAGS) $(UWPLOT_OBJS) $(LIBUW)
X
Xlint:
X for src in $(SOURCES); \
X do echo $$src:; lint -hubx -I$(INCDIR) $(DEFINES) $$src; done
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 -f *.o
X
X# DO NOT DELETE THIS LINE (or the following blank line) -- make depend uses it
X
SHAR_EOF
if test 1893 -ne "`wc -c < 'utility/Makefile_4.2'`"
then
echo shar: error transmitting "'utility/Makefile_4.2'" '(should have been 1893 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'utility/Makefile_4.3'" '(1860 characters)'
if test -f 'utility/Makefile_4.3'
then
echo shar: will not over-write existing file "'utility/Makefile_4.3'"
else
sed 's/^X//' << \SHAR_EOF > 'utility/Makefile_4.3'
X#! /bin/make -f
X#
X# uw utility makefile (4.3BSD)
X#
X# INCDIR should be set to the directory containing header files.
X#
X# LIBUW should be set to the name of the library file (or, if it is
X# installed in a system directory, "-luw").
X#
X# Note: in order for "uwterm" to work on remote machines it is
X# necessary for it to be installed in a directly where "rsh"
X# will find it. The #defined symbol UWTERM in the source can
X# be set to the desired absolute pathname, if necessary.
X#
X
XINCDIR = ../h
X
XLIBUW = ../lib/libuw.a
X
XUWTOOL_OBJS = uwtool.o
XUWTITLE_OBJS = uwtitle.o
XUWTERM_OBJS = uwterm.o
XUWPLOT_OBJS = uwplot.o
X
XOBJECTS = $(UWTOOL_OBJS) $(UWTITLE_OBJS) $(UWTERM_OBJS) $(UWPLOT_OBJS)
X
XSOURCES = `echo $(OBJECTS) | sed -e 's/\\.o/\\.c/g'`
X
XDEFINES = `cat ../DEFINES`
X
XCFLAGS = -O -I$(INCDIR) $(DEFINES)
XLFLAGS =
X
Xall: uwtool uwtitle uwterm uwplot
X
Xuwtool: $(UWTOOL_OBJS)
X $(CC) -o $@ $(LFLAGS) $(UWTOOL_OBJS) $(LIBUW)
X
Xuwtitle: $(UWTITLE_OBJS)
X $(CC) -o $@ $(LFLAGS) $(UWTITLE_OBJS) $(LIBUW)
X
Xuwterm: $(UWTERM_OBJS)
X $(CC) -o $@ $(LFLAGS) $(UWTERM_OBJS) $(LIBUW)
X
Xuwplot: $(UWPLOT_OBJS)
X $(CC) -o $@ $(LFLAGS) $(UWPLOT_OBJS) $(LIBUW)
X
Xlint:
X for src in $(SOURCES); \
X do echo $$src:; lint -hubx -I$(INCDIR) $(DEFINES) $$src; done
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 -f *.o
X
X# DO NOT DELETE THIS LINE (or the following blank line) -- make depend uses it
X
SHAR_EOF
if test 1860 -ne "`wc -c < 'utility/Makefile_4.3'`"
then
echo shar: error transmitting "'utility/Makefile_4.3'" '(should have been 1860 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'utility/uwplot.c'" '(2810 characters)'
if test -f 'utility/uwplot.c'
then
echo shar: will not over-write existing file "'utility/uwplot.c'"
else
sed 's/^X//' << \SHAR_EOF > 'utility/uwplot.c'
X/*
X * uwplot
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/socket.h>
X#include <netinet/in.h>
X#include <sys/signal.h>
X#include <sys/errno.h>
X#include <ctype.h>
X#include <stdio.h>
X
X#include "uwlib.h"
X
Xchar *argv0;
XUWIN uwin;
X
Xmain(argc, argv)
Xchar **argv;
X{
X register int c, len;
X register char *cp;
X register char *title;
X register struct sockaddr_in *sin;
X auto struct sockaddr_in sa;
X auto char buf[4096];
X extern char *optarg;
X extern int errno;
X extern onintr();
X
X /*
X * Options which are recognized directly are:
X *
X * -ninet connect to server at address "inet"
X * -ttitle label window with "title" (default is argv[0])
X */
X argv0 = argv[0];
X sin = (struct sockaddr_in *)0;
X title = argv0;
X while ((c = getopt(argc, argv, "n:t:")) != EOF) {
X switch (c) {
X case 'n':
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 (cp=optarg; isxdigit(c = *cp); cp++) {
X /* Pyramid compiler botch */
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 if (sa.sin_addr.s_addr == 0 || sa.sin_port == 0) {
X fprintf(stderr,
X "%s: bad Internet address: %s\n",
X argv0, optarg);
X return(1);
X }
X sa.sin_addr.s_addr = htonl(sa.sin_addr.s_addr);
X sa.sin_port = htons(sa.sin_port);
X sin = &sa;
X break;
X case 't':
X title = optarg;
X break;
X }
X }
X
X /*
X * Catch hangup, interrupt, quit, and termination signals. Kill
X * the window if one of these is received.
X */
X (void)signal(SIGHUP, onintr);
X (void)signal(SIGINT, onintr);
X (void)signal(SIGQUIT, onintr);
X (void)signal(SIGTERM, onintr);
X
X /*
X * Create a new plot window, title it, and make it visible.
X */
X if ((uwin = uw_new(UWT_PLOT, sin)) == (UWIN)0) {
X uw_perror(argv[0], uwerrno, errno);
X return(1);
X }
X (void)uw_stitle(uwin, title);
X (void)uw_svis(uwin, 1);
X
X /*
X * Copy the standard input to the plot window.
X */
X while ((len = read(0, buf, sizeof buf)) > 0 ||
X (len < 0 && errno == EINTR)) {
X if (len > 0)
X (void)write(UW_DATAFD(uwin), buf, len);
X }
X
X /*
X * This is something of a hack. We don't expect to be able to
X * read anything from the window. The read will hang until the
X * window is killed.
X */
X while ((len = read(UW_DATAFD(uwin), buf, sizeof buf)) > 0 ||
X len < 0 && errno == EINTR)
X ;
X return(0);
X}
X
Xonintr()
X{
X uw_kill(uwin);
X exit(0);
X}
SHAR_EOF
if test 2810 -ne "`wc -c < 'utility/uwplot.c'`"
then
echo shar: error transmitting "'utility/uwplot.c'" '(should have been 2810 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'utility/uwterm.c'" '(15896 characters)'
if test -f 'utility/uwterm.c'
then
echo shar: will not over-write existing file "'utility/uwterm.c'"
else
sed 's/^X//' << \SHAR_EOF > 'utility/uwterm.c'
X/*
X * uwterm
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/ioctl.h>
X#include <sys/socket.h>
X#include <sys/time.h>
X#include <sys/resource.h>
X#include <sys/wait.h>
X#include <netinet/in.h>
X#include <signal.h>
X#include <strings.h>
X#include <ctype.h>
X#include <errno.h>
X#include <stdio.h>
X
X#include "openpty.h"
X#include "uwlib.h"
X
X#ifndef UWTERM
X#define UWTERM "uwterm"
X#endif
X
X#define CTL(c) ((c)&037)
X
X#ifndef FD_SET
X/* 4.2 retrofit: better definitions for these are in 4.3BSD's <sys/types.h> */
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
Xextern int optind;
Xextern char *optarg;
Xextern char *getenv();
Xextern char *malloc();
Xextern deadkid();
Xextern int errno;
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
Xchar *argv0;
X
Xmain(argc, argv)
Xint argc;
Xchar **argv;
X{
X register char *cp;
X register int c;
X int wflag;
X uwtype_t wtype;
X char *term, *title, *server, *login;
X struct sockaddr_in sa, *sin;
X char hostname[32];
X
X /*
X * If called with no arguments, create a new window using the
X * current shell according to the SHELL environment variable
X * (or "/bin/sh" if that doesn't exist).
X *
X * Options which are recognized directly are:
X *
X * -ninet connect to server at address "inet"
X * -wtype create window with emulation "type"
X * -ttitle label window with "title"
X * -llogin use login name "login" on remote machine
X *
X * If no explicit title is specified, the command name is used.
X */
X argv0 = argv[0];
X sin = (struct sockaddr_in *)0;
X server = (char *)0;
X login = (char *)0;
X title = (char *)0;
X wflag = 0;
X term = (char *)0;
X while ((c = getopt(argc, argv, "l:n:t:w:")) != EOF) {
X switch (c) {
X case 'l':
X if (optarg[0] == '\0') {
X fprintf(stderr,
X "%s: \"-l\" requires user name\n", argv0);
X } else
X login = optarg;
X break;
X case 'n':
X server = optarg;
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 (cp=optarg; isxdigit(c = *cp); cp++) {
X /* Pyramid compiler botch */
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 if (sa.sin_addr.s_addr == 0 || sa.sin_port == 0) {
X fprintf(stderr,
X "%s: bad Internet address: %s\n",
X argv0, optarg);
X return(1);
X }
X sa.sin_addr.s_addr = htonl(sa.sin_addr.s_addr);
X sa.sin_port = htons(sa.sin_port);
X sin = &sa;
X break;
X case 'w':
X wflag++;
X term = optarg;
X wtype = uw_ttype(optarg);
X break;
X case 't':
X title = optarg;
X break;
X }
X }
X
X gethostname(hostname, sizeof hostname);
X if (title == (char *)0) {
X /*
X * If there was no "-t" argument, then "title" will still
X * be NULL. In this case we use the host name.
X */
X if (optind == argc)
X title = hostname;
X else
X title = argv[optind];
X }
X
X if (!term) {
X /*
X * If there was no "-w" argument, fetch the window
X * type from the environment. If that fails, use
X * a default.
X */
X if ((term=getenv("TERM")) != (char *)0)
X wtype = uw_ttype(term);
X else
X wtype = UWT_ADM31;
X }
X
X if (optind == argc-1) {
X /*
X * The remaining argument is the host name. Fork an "rsh"
X * to execute this on the remote machine.
X */
X return(doremote(argv[optind], server, title, term, login));
X } else if (optind == argc) {
X /*
X * There are no other arguments. Set up the connection
X * to this machine.
X */
X return(dolocal(sin, title, wtype, term));
X } else {
X fprintf(stderr,
X "Usage: \"%s [-ttitle] [-wtype] [-naddr] [-llogin] host\"\n",
X argv0);
X return(1);
X }
X}
X
Xdoremote(host, server, title, term, login)
Xchar *host;
Xchar *server;
Xchar *title;
Xchar *term;
Xchar *login;
X{
X register int fd, i, pid;
X register char *cp;
X char *av[16];
X
X /*
X * Invoke a remote "uwterm" via "rsh".
X */
X i = 0;
X av[i++] = "rsh";
X av[i++] = host;
X av[i++] = "-n";
X if (login != NULL) {
X av[i++] = "-l";
X av[i++] = login;
X }
X av[i++] = UWTERM;
X if (server == (char *)0) {
X if ((server = getenv("UW_INET")) == (char *)0) {
X fprintf(stderr,"%s: Can't find window server\n",argv0);
X return(1);
X }
X }
X if ((cp = malloc(3+strlen(server))) == (char *)0) {
X fprintf(stderr, "%s: out of memory\n", argv0);
X return(1);
X }
X (void)strcat(strcpy(cp, "-n"), server);
X av[i++] = cp;
X
X if (title != (char *)0) {
X if ((cp = malloc(3+strlen(title))) == (char *)0) {
X fprintf(stderr, "%s: out of memory\n", argv0);
X return(1);
X }
X (void)strcat(strcpy(cp, "-t"), title);
X av[i++] = cp;
X }
X
X if (term != (char *)0) {
X if ((cp = malloc(3+strlen(term))) == (char *)0) {
X fprintf(stderr, "%s: out of memory\n", argv0);
X return(1);
X }
X (void)strcat(strcpy(cp, "-w"), term);
X av[i++] = cp;
X }
X
X av[i] = (char *)0;
X
X for (fd=getdtablesize()-1; fd > 2; fd--)
X (void)fcntl(fd, F_SETFD, 1);
X (void)execvp(av[0], av);
X (void)execv("/usr/ucb/rsh", av); /* last-ditch try */
X perror(av[0]);
X return(1);
X}
X
X
Xdolocal(sin, title, wtype, term)
Xstruct sockaddr_in *sin;
Xchar *title;
Xuwtype_t wtype;
Xchar *term;
X{
X register UWIN uwin;
X register int fd;
X register int s;
X struct ptydesc pt;
X
X /*
X * Create and initialize a pseudo-terminal.
X */
X if (openpty(&pt) < 0) {
X fprintf(stderr, "No pseudo-terminals are available\n");
X return(1);
X }
X ttyinit(pt.pt_tfd);
X
X
X /*
X * Make fd's 0 and 1 be "/dev/null". We'd like to force a known
X * definition for fd 2 at this point, but we may need it for
X * uw_perror() if uw_new() fails.
X */
X if ((fd = open("/dev/null", O_RDWR)) >= 0) { /* should be zero */
X if (fd != 0 && pt.pt_tfd != 0 && pt.pt_pfd != 0)
X dup2(fd, 0);
X if (fd != 1 && pt.pt_tfd != 1 && pt.pt_pfd != 1)
X dup2(fd, 1);
X if (fd > 2)
X (void)close(fd);
X }
X
X /*
X * Create and title the window. Make it visible.
X */
X if ((uwin = uw_new(wtype, sin)) == (UWIN)0) {
X uw_perror(argv0, uwerrno, errno);
X return(1);
X }
X (void)uw_stitle(uwin, title);
X (void)uw_svis(uwin, 1);
X
X /*
X * We no longer have use for fd 2, so make it "/dev/null" (the
X * same as fd 0.
X */
X (void)dup2(0, 2);
X
X /*
X * Adjust the environment to contain the correct values of TERM,
X * UW_ID, and UW_INET. These will be inherited by the child
X * we will create next.
X */
X adjenv(term, sin, UW_ID(uwin));
X
X /*
X * Create a process to execute the command connected to the pty.
X */
X runcmd(pt.pt_tfd, pt.pt_tname);
X
X /*
X * Ignore signals that might cause us trouble. We do NOT ignore
X * SIGTSTP so that the user can move us from the foreground into
X * the background if desired.
X */
X signal(SIGINT, SIG_IGN);
X signal(SIGQUIT, SIG_IGN);
X signal(SIGCHLD, deadkid);
X
X#if defined(TIOCSWINSZ) || defined(TIOCSSIZE)
X /*
X * Install an option handling routine to catch window size
X * changes from the Mac and make the appropriate changes to
X * the pseudo-terminal.
X */
X setresize(uwin, pt.pt_pfd);
X#endif
X
X /*
X * Close the slave side of the pty. Copy data between the pty
X * and the window. The return value from copy() is the exit
X * status.
X */
X (void)close(pt.pt_tfd);
X s = copy(pt.pt_pfd, UW_DATAFD(uwin));
X uw_kill(uwin);
X return(s);
X}
X
Xttyinit(ptyfd)
Xregister int ptyfd;
X{
X register int ttyfd;
X struct sgttyb sg;
X struct tchars tc;
X struct ltchars ltc;
X int ldisc;
X int lmode;
X
X /*
X * Initialize the modes of the terminal whose file descriptor
X * is "ptyfd" to the same modes as the current terminal. If there
X * isn't a "current terminal" handy, then use hardcoded defaults.
X */
X for (ttyfd=0; ttyfd < 3 && ioctl(ttyfd, TIOCGETD, &ldisc) < 0; ttyfd++)
X ;
X if (ttyfd < 3) {
X (void)ioctl(ttyfd, TIOCGETP, &sg);
X (void)ioctl(ttyfd, TIOCGETC, &tc);
X (void)ioctl(ttyfd, TIOCGLTC, <c);
X (void)ioctl(ttyfd, TIOCLGET, &lmode);
X } else {
X ldisc = NTTYDISC;
X
X sg.sg_ispeed = sg.sg_ospeed = 13; /* doesn't really matter */
X sg.sg_erase = 0177; /* ugh */
X sg.sg_kill = CTL('u'); /* ugh */
X sg.sg_flags = ECHO|CRMOD|ANYP;
X
X tc.t_intrc = CTL('c'); /* yuck, should be 0177 */
X tc.t_quitc = CTL('\\');
X tc.t_startc = CTL('q');
X tc.t_stopc = CTL('s');
X tc.t_eofc = CTL('d');
X tc.t_brkc = -1;
X
X ltc.t_suspc = CTL('z');
X ltc.t_dsuspc = CTL('y');
X ltc.t_rprntc = CTL('r');
X ltc.t_flushc = CTL('o');
X ltc.t_werasc = CTL('w');
X ltc.t_lnextc = CTL('v');
X
X lmode = LCRTBS|LCRTERA|LCRTKIL|LCTLECH;
X }
X (void)ioctl(ptyfd, TIOCSETD, &ldisc);
X (void)ioctl(ptyfd, TIOCSETP, &sg);
X (void)ioctl(ptyfd, TIOCSETC, &tc);
X (void)ioctl(ptyfd, TIOCSLTC, <c);
X (void)ioctl(ptyfd, TIOCLSET, &lmode);
X}
X
Xadjenv(term, sin, wid)
Xchar *term;
Xstruct sockaddr_in *sin;
Xuwid_t wid;
X{
X char *env[4];
X static char ttype[sizeof "TERM=" + 16];
X static char inet[sizeof INET_ENV + 16];
X static char idstr[sizeof "UW_ID=" + 20];
X
X /*
X * Redefine the environment variable UW_ID. Redefine UW_INET
X * if "sin" is non-NULL. Redefine TERM.
X */
X (void)sprintf(ttype, "TERM=%.15s", term);
X env[0] = ttype;
X
X (void)sprintf(idstr, "UW_ID=%ld", wid);
X env[1] = idstr;
X
X if (sin != NULL) {
X (void)sprintf(inet, "%s=%08lx.%d", INET_ENV,
X ntohl(sin->sin_addr.s_addr), ntohs(sin->sin_port));
X env[2] = inet;
X env[3] = (char *)0;
X } else
X env[2] = (char *)0;
X env_set(env);
X}
X
Xruncmd(fd, tname)
Xint fd;
Xchar *tname;
X{
X register int pid;
X register char *shell;
X
X /*
X * Figure out the name of the user's shell. If unknown,
X * use a default.
X */
X if ((shell = getenv("SHELL")) == (char *)0)
X shell = "/bin/sh";
X
X /*
X * Fork a new process and attach "fd" to fd's 0, 1, and 2 of
X * that new process. Disassociate the current controlling
X * terminal and attach the new one (whose name is "tname").
X */
X while ((pid = fork()) < 0)
X sleep(5);
X if (pid == 0) {
X if (fd != 0)
X dup2(fd, 0);
X if (fd != 1)
X dup2(fd, 1);
X if (fd != 2)
X dup2(fd, 2);
X if ((fd = open("/dev/tty", O_RDWR)) >= 0) {
X (void)ioctl(fd, TIOCNOTTY, (char *)0);
X (void)close(fd);
X } else
X setpgrp(0, 0);
X (void)open(tname, O_RDWR);
X for (fd=getdtablesize()-1; fd > 2; fd--)
X (void)fcntl(fd, F_SETFD, 1);
X execlp(shell, "-", (char *)0);
X execl(shell, "-", (char *)0);
X _exit(1);
X }
X}
X
Xcopy(fd1, fd2)
Xint fd1, fd2;
X{
X struct fdinfo {
X int fi_fd; /* associated file descriptor */
X int fi_size; /* amount of data in buffer */
X char *fi_ptr; /* pointer to data in fi_buf */
X char fi_buf[1024];
X };
X register struct fdinfo *fi, *fo;
X register int n, nfds, len;
X struct fdinfo fdinfo[2];
X struct fd_set rdmask[2], wtmask[2], exmask[2];
X struct timeval tv;
X
X /*
X * Copy data between file descriptors fd1 and fd2. Return when an
X * EOF is read or an I/O error (other than an interrupted system
X * call or non-blocking I/O message) is encountered.
X */
X FD_ZERO(&rdmask[1]);
X FD_ZERO(&wtmask[1]);
X FD_ZERO(&exmask[1]);
X
X fdinfo[0].fi_fd = fd1;
X fdinfo[0].fi_size = 0;
X fdinfo[1].fi_fd = fd2;
X fdinfo[1].fi_size = 0;
X
X FD_SET(fd1, &rdmask[1]);
X FD_SET(fd2, &rdmask[1]);
X
X (void)fcntl(fd1, F_SETFL, FNDELAY);
X (void)fcntl(fd2, F_SETFL, FNDELAY);
X
X nfds = ((fd1 > fd2) ? fd1 : fd2) + 1;
X
X while (1) {
X rdmask[0] = rdmask[1];
X wtmask[0] = wtmask[1];
X exmask[0] = exmask[1];
X errno = 0;
X if (fdinfo[0].fi_size != 0 || fdinfo[1].fi_size != 0) {
X /*
X * Select does not work correctly for writes on
X * some machines, so we must fake it. If a write
X * is pending, we time out after 1/50 second and
X * pretend that select told us that writes could
X * now be performed. The code below will do the
X * correct thing if the write would still block.
X */
X tv.tv_sec = 0;
X tv.tv_usec = 1000000 / 50;
X n = select(nfds, rdmask, wtmask, exmask, &tv);
X wtmask[0] = wtmask[1];
X } else
X n = select(nfds, rdmask, wtmask, exmask, (struct timeval *)0);
X if (n < 0 && errno == EINTR) {
X continue;
X } else if (n <= 0) {
X perror("select");
X return(1);
X }
X for (fi=fdinfo; fi < fdinfo+2; fi++) {
X fo = fdinfo + !(fi - fdinfo);
X if (FD_ISSET(fi->fi_fd, rdmask)) {
X /* data available for reading */
X len = read(fi->fi_fd, fi->fi_buf,
X sizeof fi->fi_buf);
X if (len > 0) {
X fi->fi_size = len;
X fi->fi_ptr = fi->fi_buf;
X FD_CLR(fi->fi_fd, &rdmask[1]);
X FD_SET(fo->fi_fd, &wtmask[1]);
X FD_SET(fo->fi_fd, &wtmask[0]);
X } else if (len == 0) {
X /* EOF, exit */
X return(0);
X } else if (errno != EWOULDBLOCK &&
X errno != EINTR) {
X /* error, exit */
X return(1);
X }
X }
X if (FD_ISSET(fo->fi_fd, wtmask)) {
X /* data ready for writing */
X errno = 0;
X len = write(fo->fi_fd, fi->fi_ptr, fi->fi_size);
X if (len > 0) {
X fi->fi_ptr += len;
X fi->fi_size -= len;
X if (fi->fi_size == 0) {
X FD_SET(fi->fi_fd, &rdmask[1]);
X FD_CLR(fo->fi_fd, &wtmask[1]);
X }
X } else if (errno != EWOULDBLOCK &&
X errno != EINTR) {
X /* error, exit */
X return(1);
X }
X }
X }
X }
X}
X
Xdeadkid()
X{
X register int pid;
X
X /*
X * Collect dead children. Don't bother with their exit status
X * or resource usage.
X */
X while ((pid = wait3((union wait *)0, WNOHANG, (struct rusage *)0)) > 0)
X ;
X}
X
X#if defined(TIOCSWINSZ) || defined(TIOCSSIZE)
Xstatic int ptyfd;
X
X#ifdef TIOCSWINSZ
Xstatic struct winsize winsz;
X
Xvoid
Xdoresize(uwin, optnum, optcmd, uwoptval)
XUWIN uwin;
Xuwopt_t optnum;
Xuwoptcmd_t optcmd;
Xunion uwoptval *uwoptval;
X{
X uwtype_t wtype;
X
X /*
X * 4.3BSD-style window resizing
X */
X if (uw_gtype(uwin, &wtype) < 0)
X wtype = UWT_ADM31; /* probably wrong to do this here */
X if (optcmd == UWOC_SET) {
X switch (optnum) {
X case UWOP_WSIZE:
X winsz.ws_ypixel = uwoptval->uwov_point.v;
X winsz.ws_xpixel = uwoptval->uwov_point.h;
X break;
X case UWOP_TSIZE:
X if (wtype <= UWT_ANSI) {
X winsz.ws_row = uwoptval->uwov_point.v;
X winsz.ws_col = uwoptval->uwov_point.h;
X }
X break;
X }
X if (wtype <= UWT_ANSI &&
X (optnum == UWOP_WSIZE || optnum == UWOP_TSIZE))
X (void)ioctl(ptyfd, TIOCSWINSZ, &winsz);
X }
X}
X
Xsetresize(uwin, fd)
XUWIN uwin;
Xint fd;
X{
X struct uwpoint pt;
X uwtype_t wtype;
X
X /*
X * Set up the option-handling routine "doresize".
X */
X ptyfd = fd;
X uw_optfn(uwin, UWOP_TSIZE, doresize);
X uw_optfn(uwin, UWOP_WSIZE, doresize);
X winsz.ws_row = 24; /* default to standard terminal size */
X winsz.ws_col = 80;
X if (uw_gwsize(uwin, &pt) == 0) {
X winsz.ws_ypixel = pt.uwp_v;
X winsz.ws_xpixel = pt.uwp_h;
X } else {
X /* make up something plausible */
X winsz.ws_ypixel = 8 * winsz.ws_row;
X winsz.ws_xpixel = 8 * winsz.ws_col;
X }
X
X if (uw_gtype(uwin, &wtype) == 0 && wtype <= UWT_ANSI)
X (void)uw_optcmd(uwin, UWOP_TSIZE, UWOC_DO, (union uwoptval *)0);
X}
X
X#else
X#ifdef TIOCSSIZE
Xvoid
Xdoresize(uwin, optnum, optcmd, uwoptval)
XUWIN uwin;
Xuwopt_t optnum;
Xuwoptcmd_t optcmd;
Xunion uwoptval *uwoptval;
X{
X struct ttysize ts;
X uwtype_t wtype;
X
X /*
X * Sun-style window resizing
X */
X if (uw_gtype(uwin, &wtype) < 0)
X wtype = UWT_ADM31; /* probably wrong to do this here */
X if (wtype <= UWT_ANSI && optnum == UWOP_TSIZE && optcmd == UWOC_SET) {
X ts.ts_lines = uwoptval->uwov_point.v;
X ts.ts_cols = uwoptval->uwov_point.h;
X (void)ioctl(ptyfd, TIOCSSIZE, &ts);
X }
X}
X
Xsetresize(uwin, fd)
XUWIN uwin;
Xint fd;
X{
X uwtype_t wtype;
X
X /*
X * Set up the option-handling routine "doresize".
X */
X ptyfd = fd;
X uw_optfn(uwin, UWOP_TSIZE, doresize);
X
X if (uw_gtype(uwin, &wtype) == 0 && wtype <= UWT_ANSI)
X (void)uw_optcmd(uwin, UWOP_TSIZE, UWOC_DO, (union uwoptval *)0);
X}
X#endif
X#endif
X#endif
SHAR_EOF
if test 15896 -ne "`wc -c < 'utility/uwterm.c'`"
then
echo shar: error transmitting "'utility/uwterm.c'" '(should have been 15896 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'utility/uwtitle.c'" '(1860 characters)'
if test -f 'utility/uwtitle.c'
then
echo shar: will not over-write existing file "'utility/uwtitle.c'"
else
sed 's/^X//' << \SHAR_EOF > 'utility/uwtitle.c'
X/*
X * uwtitle
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 <stdio.h>
X
X#include "uwlib.h"
X
Xextern char *optarg;
Xextern int optind;
Xextern int errno;
X
Xextern char *getenv();
Xextern long atol();
X
Xmain(argc, argv)
Xint argc;
Xchar **argv;
X{
X register int c;
X register char *cp, *cq, **av;
X register uwid_t uwid;
X char *argv0;
X char *cqlimit;
X union uwoptval uwoptval;
X
X /*
X * If called with no arguments, print a syntax message. Otherwise,
X * set the title of the current window to argv[1..argc-1]. The
X * window ID is obtained from the environment or the "-i" argument.
X */
X argv0 = argv[0];
X uwid = 0;
X while ((c = getopt(argc, argv, "i:")) != EOF) {
X switch (c) {
X case 'i':
X if ((uwid = atol(optarg)) == 0) {
X fprintf(stderr,
X "%s: malformed \"-i\" argument\n", argv0);
X return(1);
X }
X break;
X }
X }
X if (optind >= argc) {
X fprintf(stderr, "Syntax: \"%s [-iID] title ...\"\n", *argv);
X return(1);
X }
X
X if (uwid == 0) {
X if ((cp = getenv("UW_ID")) == NULL) {
X fprintf(stderr,
X "%s: can't determine window ID\n", argv0);
X return(1);
X }
X
X if ((uwid = (uwid_t)atol(cp)) == 0) {
X fprintf(stderr,
X "%s: garbaged window ID in environment: %s",
X argv0, cp);
X return(1);
X }
X }
X
X /*
X * Copy the argv list into "uwoptval" and change the title.
X */
X av = argv + optind - 1;
X cq = uwoptval.uwov_string;
X cqlimit = uwoptval.uwov_string + sizeof uwoptval.uwov_string;
X while ((cp = *++av) != NULL && cq < cqlimit) {
X while (cq < cqlimit && (*cq++ = *cp++) != '\0')
X ;
X cq[-1] = ' ';
X }
X cq[-1] = '\0';
X
X if (uw_rsetopt(uwid, UWOP_TITLE, &uwoptval) < 0) {
X uw_perror("uw_rsetopt", uwerrno, errno);
X return(1);
X } else
X return(0);
X}
SHAR_EOF
if test 1860 -ne "`wc -c < 'utility/uwtitle.c'`"
then
echo shar: error transmitting "'utility/uwtitle.c'" '(should have been 1860 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'utility/uwtool.c'" '(2550 characters)'
if test -f 'utility/uwtool.c'
then
echo shar: will not over-write existing file "'utility/uwtool.c'"
else
sed 's/^X//' << \SHAR_EOF > 'utility/uwtool.c'
X/*
X * uwtool
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 <stdio.h>
X
X#include "uwlib.h"
X
Xmain(argc, argv)
Xint argc;
Xchar **argv;
X{
X register uwid_t uwid;
X register char *fname, *term;
X register int c;
X register uwtype_t wtype;
X char *argv0;
X char *av[2];
X int vflag;
X int wflag;
X char *title;
X union uwoptval uwoptval;
X extern int errno;
X extern int optind;
X extern char *optarg;
X extern char *getenv();
X
X /*
X * If called with no arguments, create a new window using the
X * current shell according to the SHELL environment variable
X * (or "/bin/sh" if that doesn't exist). If called with
X * arguments, argv[optind] through argv[argc-1] are the arguments
X * to the command.
X *
X * Options which are recognized directly are:
X *
X * -v (verbose) print new window ID on stdout
X * -wtype create window with emulation "type"
X * -ttitle label window with "title"
X *
X * If no explicit title is specified, the command name is used.
X */
X argv0 = argv[0];
X wflag = 0;
X vflag = 0;
X title = (char *)0;
X while ((c = getopt(argc, argv, "vw:t:")) != EOF) {
X switch (c) {
X case 'v':
X vflag++;
X break;
X case 'w':
X wflag++;
X wtype = uw_ttype(optarg);
X break;
X case 't':
X title = optarg;
X break;
X }
X }
X
X if (optind < argc) {
X /*
X * Adjust the "argv" pointer according to the number of
X * arguments we've processed.
X */
X argv += optind;
X fname = *argv;
X } else {
X /*
X * No (non-option) arguments -- use SHELL
X */
X if ((fname = getenv("SHELL")) == (char *)0)
X fname = "/bin/sh";
X av[0] = fname;
X av[1] = (char *)0;
X argv = av;
X }
X
X if (title == (char *)0) {
X /*
X * If there was no "-t" argument, then "title" will still
X * be NULL. In this case we use the command name as
X * the title.
X */
X title = fname;
X }
X
X if (!wflag) {
X /*
X * If there was no "-w" argument, fetch the window
X * type from the environment. If that fails, use
X * a default.
X */
X if ((term=getenv("TERM")) != (char *)0)
X wtype = uw_ttype(term);
X else
X wtype = UWT_ADM31;
X }
X
X if ((uwid = uw_cmd(wtype, fname, argv)) > 0) {
X (void)strncpy(uwoptval.uwov_string, title,
X sizeof uwoptval.uwov_string);
X (void)uw_rsetopt(uwid, UWOP_TITLE, &uwoptval);
X if (vflag)
X printf("%d\n", uwid);
X return(0);
X } else {
X if (uwerrno != UWE_NXSERV)
X uw_perror(fname, uwerrno, errno);
X else
X uw_perror(argv0, uwerrno, errno);
X return(1);
X }
X}
SHAR_EOF
if test 2550 -ne "`wc -c < 'utility/uwtool.c'`"
then
echo shar: error transmitting "'utility/uwtool.c'" '(should have been 2550 characters)'
fi
fi # end of overwriting check
# End of shell archive
exit 0
--- end of part 9 ---
Technical Details
Message-ID:
<6630@dhw68k.cts.com>Path:
arc1-ca.pugleaf.net!utzoo!mnetor!uunet!husc6!bloom-beacon!tut.cis.ohio-state.edu!mailrus!ames!ucsd!sdcsvax!ucsdhub!hp-sdd!hplabs!felix!dhw68k!macintoshReferences:
<6493@dhw68k.cts.com> <6497@dhw68k.cts.com> <6515@dhw68k.cts.com> <6538@dhw68k.cts.com> <6587@dhw68k.cts.com> <6602@dhw68k.cts.com> <6609@dhw68k.cts.com> <6612@dhw68k.cts.com>Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!mnetor!uunet!husc6!bloom-beacon!tut.cis.ohio-state.edu!mailrus!ames!ucsd!sdcsvax!ucsdhub!hp-sdd!hplabs!felix!dhw68k!macintosh From: jdb@mordor.s1.gov (John Bruner) Newsgroups: comp.sources.mac Subject: UW v4.2 (part 9 of 9) Message-ID: <6630@dhw68k.cts.com> Date: 8 Apr 88 14:39:45 GMT References: <6493@dhw68k.cts.com> <6497@dhw68k.cts.com> <6515@dhw68k.cts.com> <6538@dhw68k.cts.com> <6587@dhw68k.cts.com> <6602@dhw68k.cts.com> <6609@dhw68k.cts.com> <6612@dhw68k.cts.com> Sender: macintosh@dhw68k.cts.com Organization: Lawrence Livermore National Laboratory, S-1 Project Lines: 1266 Approved: bytebug@dhw68k.cts.com (Roger L. Long)