Path: 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) [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 '/ 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 X#include X#include X#include X#include X#include X#include 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 X#include X#include X#include X#include X#include X#include X#include X#include X#include X#include X#include X#include 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 */ 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 , 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 X#include 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 X#include 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 ---