home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Garbo
/
Garbo.cdr
/
mac
/
unix
/
uw_shar.sit
/
uw-42-part5.shar
< prev
next >
Wrap
Text File
|
1989-09-14
|
62KB
|
2,451 lines
#Date: Wed, 2 Mar 88 10:01:20 PST
#From: rothberg@polya.stanford.edu (Edward Rothberg)
#Subject: UW 4.2 part 5 of 8
: This is a shar archive. Extract with sh, not csh.
if test ! -d lib; then
echo mkdir lib
mkdir lib
fi
if test ! -d server; then
echo mkdir server
mkdir server
fi
echo x - server/uw_utmp.c
sed -e 's/^X//' > server/uw_utmp.c << '!EOF!server/uw_utmp.c!'
X/*
X * uw_utmp - /etc/utmp handling
X *
X * Copyright 1985,1986 by John D. Bruner. All rights reserved. Permission to
X * copy this program is given provided that the copy is not sold and that
X * this copyright notice is included.
X */
X
X#ifdef UTMP
X
X#include <sys/types.h>
X#include <sys/file.h>
X#include <sys/time.h>
X#include <pwd.h>
X#include <utmp.h>
X#include <strings.h>
X#include <ctype.h>
X#include <stdio.h>
X
X#include "uw_param.h"
X
Xstruct utinfo {
X struct utinfo *ui_next;
X struct utinfo *ui_chain;
X char *ui_line;
X int ui_slot;
X int ui_inuse;
X};
X
Xstatic struct utinfo *hash[31];
Xstatic struct utinfo *head;
X
Xstatic char *myname;
Xstatic fildes_t utmpfd;
X
Xextern time_t time();
X
Xutmp_init(fd)
Xfildes_t fd;
X{
X register char *cp, *cq;
X register struct utinfo *ui;
X register int hashidx, slot;
X struct passwd *pw;
X FILE *fp;
X char line[256];
X
X if ((utmpfd = fd) >= 0 && (fp = fopen("/etc/ttys", "r")) == NULL) {
X (void)close(utmpfd);
X utmpfd = -1;
X }
X if (utmpfd >= 0) {
X slot = 0;
X while (fgets(line, sizeof line, fp) != NULL) {
X#ifdef V7TTYS
X if (!line[0] || !line[1]) { /* malformed line */
X slot++;
X continue;
X }
X cp = line+2; /* skip flag and speed index */
X#else
X for (cp=line; *cp && isspace(*cp); cp++)
X ;
X if (*cp == '#')
X continue;
X#endif
X slot++;
X if ((ui=(struct utinfo *)malloc(sizeof *ui)) != NULL) {
X for (cq=cp; *cq && !isspace(*cq); cq++)
X ;
X if ((ui->ui_line=malloc(cq-cp+1)) != NULL) {
X (void)strncpy(ui->ui_line, cp, cq-cp);
X ui->ui_line[cq-cp] = '\0';
X } else {
X free((char *)ui);
X ui = (struct utinfo *)0;
X }
X }
X if (ui != NULL) {
X ui->ui_slot = slot;
X ui->ui_inuse = 0;
X ui->ui_chain = head;
X head = ui;
X hashidx = utmp_hash(ui->ui_line);
X ui->ui_next = hash[hashidx];
X hash[hashidx] = ui;
X }
X }
X (void)fclose(fp);
X }
X if ((pw = getpwuid(getuid())) != NULL &&
X (myname=malloc(1+strlen(pw->pw_name))) != NULL)
X (void)strcpy(myname, pw->pw_name);
X}
X
Xstatic
Xstruct utinfo *
Xutmp_find(tty)
Xchar *tty;
X{
X register char *cp;
X register struct utinfo *ui;
X
X if ((cp = rindex(tty, '/')) != NULL)
X cp++;
X else
X cp = tty;
X ui = hash[utmp_hash(cp)];
X while (ui != NULL && strcmp(ui->ui_line, cp) != 0)
X ui = ui->ui_next;
X return(ui);
X}
X
Xutmp_add(tty)
Xchar *tty;
X{
X register struct utinfo *ui;
X struct utmp ut;
X
X if ((ui = utmp_find(tty)) != NULL) {
X (void)strncpy(ut.ut_line, ui->ui_line, sizeof ut.ut_line);
X (void)strncpy(ut.ut_name, myname, sizeof ut.ut_name);
X (void)strncpy(ut.ut_host, "", sizeof ut.ut_host);
X ut.ut_time = (long)time((time_t)0);
X ui->ui_inuse = 1;
X utmp_write(ui->ui_slot, &ut);
X }
X}
X
X
Xutmp_rm(tty)
Xchar *tty;
X{
X register struct utinfo *ui;
X struct utmp ut;
X
X if ((ui = utmp_find(tty)) != NULL) {
X (void)strncpy(ut.ut_line, ui->ui_line, sizeof ut.ut_line);
X (void)strncpy(ut.ut_name, "", sizeof ut.ut_name);
X (void)strncpy(ut.ut_host, "", sizeof ut.ut_host);
X ut.ut_time = (long)time((time_t)0);
X ui->ui_inuse = 0;
X utmp_write(ui->ui_slot, &ut);
X }
X}
X
Xutmp_exit()
X{
X register struct utinfo *ui;
X struct utmp ut;
X
X for (ui=head; ui; ui=ui->ui_chain) {
X if (ui->ui_inuse) {
X (void)strncpy(ut.ut_line,ui->ui_line,sizeof ut.ut_line);
X (void)strncpy(ut.ut_name, "", sizeof ut.ut_name);
X (void)strncpy(ut.ut_host, "", sizeof ut.ut_host);
X ut.ut_time = (long)time((time_t)0);
X ui->ui_inuse = 0;
X utmp_write(ui->ui_slot, &ut);
X }
X }
X}
X
Xutmp_write(slot, ut)
Xregister int slot;
Xstruct utmp *ut;
X{
X extern off_t lseek();
X
X if (utmpfd >= 0 &&
X lseek(utmpfd, slot*sizeof(*ut), L_SET) == (off_t)(slot*sizeof(*ut)))
X (void)write(utmpfd, (char *)ut, sizeof *ut);
X}
X
Xstatic
Xutmp_hash(s)
Xregister char *s;
X{
X register short h;
X
X for (h=0; *s; s++)
X h = (h << ((*s)&7)) | (h >> (sizeof h - ((*s)&7))) + *s;
X return(h % sizeof hash / sizeof hash[0]);
X}
X#else
Xutmp_add(tty)
Xchar *tty;
X{
X}
X
Xutmp_rm(tty)
Xchar *tty;
X{
X}
X
Xutmp_exit()
X{
X}
X#endif
!EOF!server/uw_utmp.c!
echo x - server/uw_win.c
sed -e 's/^X//' > server/uw_win.c << '!EOF!server/uw_win.c!'
X/*
X * uw_win - window handling for UW
X *
X * Copyright 1986 by John D. Bruner. All rights reserved. Permission to
X * copy this program is given provided that the copy is not sold and that
X * this copyright notice is included.
X */
X
X#include <sys/types.h>
X#include <sys/file.h>
X#include <sys/ioctl.h>
X#include <signal.h>
X#include <strings.h>
X#include <stdio.h>
X
X#include "openpty.h"
X#include "uw_param.h"
X#include "uw_opt.h"
X#include "uw_win.h"
X#include "uw_fd.h"
X
X/*
X * "defwtype" specifies the default window type. This type is used when
X * more specific information is not available.
X */
Xwtype_t defwtype = WT_ADM31;
X
X/*
X * "window" is declared in "uw_win.h" Here we define it.
X */
Xstruct window window[NWINDOW]; /* window data structures */
X
X/*
X * "emulation" describes window emulation-specific data. "generic_emul"
X * describes emulations which do not require special server attention
X * (e.g. file transfer, all of whose real work is done by a separate process).
X */
Xextern struct emulation adm31_emul, vt52_emul, ansi_emul, tek_emul;
Xstatic struct emulation generic_emul;
Xstatic struct emulation *emulation[WT_MAXTYPE+1] = {
X &adm31_emul,
X &vt52_emul,
X &ansi_emul,
X &tek_emul,
X &generic_emul,
X &generic_emul,
X &generic_emul,
X};
X
Xextern char *win_getopt();
Xextern void win_setopt();
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 };
X
Xstatic struct woptdefn genwinopt = {
X (1<<WOG_VIS), 0, 0, 0,
X (1<<WOG_VIS)|(1<<WOG_TYPE)|(1<<WOG_POS)|(1<<WOG_TITLE)|(1<<WOG_SIZE),
X {
X/* WOG_END */ { NULL, NULL, NULL },
X/* WOG_VIS */ { woa_vis, win_getopt, win_setopt },
X/* WOG_TYPE */ { woa_type, win_getopt, win_setopt },
X/* WOG_POS */ { woa_pos, win_getopt, win_setopt },
X/* WOG_TITLE */ { woa_title, win_getopt, win_setopt },
X/* WOG_SIZE */ { woa_size, win_getopt, win_setopt },
X/* WOG_6 */ { NULL, NULL, NULL },
X/* WOG_7 */ { NULL, NULL, NULL }
X }
X};
X
X/*
X * This is a violation of the level structure, but it is expedient.
X */
Xextern void ipc_optmsg();
X
Xwin_init()
X{
X register struct window *w;
X
X /*
X * Initialize. Mark all windows unallocated.
X */
X for (w=window; w < window+NWINDOW; w++)
X w->w_alloc = 0;
X}
X
Xlong
Xwin_mkid()
X{
X static unsigned short i = 0;
X static long pid = -1;
X
X if (pid == -1)
X pid = getpid();
X return((pid << (NBBY*(sizeof(long)/sizeof(short)))) | i++);
X}
X
Xstruct window *
Xwin_search(wid, maxwin)
Xlong wid;
Xnwin_t maxwin;
X{
X register struct window *w;
X
X for (w=window; w < window+maxwin; w++)
X if (w->w_alloc && w->w_id == wid)
X return(w);
X return((struct window *)0);
X}
X
Xstruct window *
Xwin_neww(wclass, wtype, wnum, maxwin, wid, datafd, ctlfd, options)
Xwclass_t wclass;
Xwtype_t wtype;
Xnwin_t wnum;
Xnwin_t maxwin;
Xlong wid;
Xfildes_t datafd;
Xfildes_t ctlfd;
Xstruct woptdefn *options;
X{
X fildes_t fd;
X int pid;
X struct window *w;
X char *tty, *shell;
X auto struct ptydesc pt;
X extern char *getenv();
X
X /*
X * Create a new window. "wclass" specifies the window wclass.
X * If "wnum" is negative, choose a window number; otherwise,
X * "wnum" is the window number. "datafd" and "ctlfd" are the
X * data and control file descriptors to be associated with
X * this window. If "datafd" is negative and "wclass" is
X * WC_INTERNAL, allocate a pseudo-terminal.
X *
X * If "options" is non-NULL it specifies the address of an
X * option definition structure; otherwise, a new one is constructed
X * from the generic and emulation-specific prototype structures.
X *
X * If "wid" is nonzero it is a proposed window ID. It must be
X * unique (not in use). If "wid" is zero, a new ID is assigned.
X *
X * The window type "wtype" will always be a terminal emulation
X * if the wclass is WC_INTERNAL.
X *
X * Internal-class windows are visible by default, while external
X * ones are initially invisible.
X *
X * Return the address of the window structure or NULL if
X * none could be created.
X */
X tty = (char *)0;
X if (wtype > WT_MAXTYPE)
X return((struct window *)0);
X if (wid == 0) {
X while (win_search(wid=win_mkid(), maxwin) != NULL)
X ;
X } else if (win_search(wid, maxwin) != NULL)
X return((struct window *)0);
X if (datafd < 0 && wclass == WC_INTERNAL) {
X if (!openpty(&pt)) {
X datafd = pt.pt_pfd;
X tty = pt.pt_tname;
X while ((pid = fork()) < 0)
X sleep(5);
X if (!pid) {
X win_envinit(wtype, wid);
X (void)signal(SIGHUP, SIG_DFL);
X (void)signal(SIGINT, SIG_DFL);
X (void)signal(SIGQUIT, SIG_DFL);
X (void)signal(SIGTERM, SIG_DFL);
X (void)signal(SIGTSTP, SIG_IGN);
X (void)signal(SIGCHLD, SIG_DFL);
X (void)ioctl(open("/dev/tty",O_RDWR),
X (int)TIOCNOTTY, (char *)0);
X (void)close(open(pt.pt_tname, O_RDONLY));
X (void)setuid(getuid());
X if (!(shell = getenv("SHELL")))
X shell = "/bin/sh";
X if (pt.pt_tfd != 0)
X (void)dup2(pt.pt_tfd, 0);
X if (pt.pt_tfd != 1);
X (void)dup2(pt.pt_tfd, 1);
X if (pt.pt_tfd != 2)
X (void)dup2(pt.pt_tfd, 2);
X for (fd=3; fd < nfds; fd++)
X (void)close(fd);
X tty_mode(0); /* HACK! */
X execl(shell, shell, (char *)0);
X _exit(1);
X } else {
X utmp_add(tty);
X (void)close(pt.pt_tfd);
X }
X }
X }
X
X if (datafd >= 0) {
X if (wnum > 0) {
X w = WIN_PTR(wnum);
X if (w->w_alloc)
X w = (struct window *)0;
X } else {
X for (w=window; w < window+maxwin && w->w_alloc; w++)
X ;
X if (w >= window+maxwin)
X w = (struct window *)0;
X }
X } else
X w = (struct window *)0;
X
X if (w) {
X w->w_alloc = 1;
X w->w_id = wid;
X w->w_class = wclass;
X w->w_type = wtype;
X w->w_visible = (w->w_class == WC_INTERNAL);
X w->w_position.h = w->w_position.v = 0;
X w->w_size.h = w->w_size.v = 0;
X w->w_title[0] = '\0';
X if (emulation[wtype]->we_start &&
X !(*emulation[wtype]->we_start)(w)) {
X if (options)
X w->w_optdefn = *options;
X else
X opt_new(&w->w_optdefn, &genwinopt,
X (struct woptdefn *)0);
X } else {
X if (options)
X w->w_optdefn = *options;
X else
X opt_new(&w->w_optdefn, &genwinopt,
X &emulation[wtype]->we_optdefn);
X }
X w->w_datafd = datafd;
X (void)fcntl(datafd, F_SETFL, FNDELAY);
X FD_SET(datafd, &selmask[0].sm_rd);
X fdmap[datafd].f_type = FDT_DATA;
X fdmap[datafd].f_win = w;
X if (w->w_class == WC_INTERNAL) {
X if (tty)
X (void)strncpy(w->w_tty, tty, sizeof w->w_tty);
X } else {
X w->w_ctlfd = ctlfd;
X if (ctlfd >= 0) {
X (void)fcntl(ctlfd, F_SETFL, FNDELAY);
X FD_SET(ctlfd, &selmask[0].sm_rd);
X fdmap[ctlfd].f_type = FDT_CTL;
X fdmap[ctlfd].f_win = w;
X if (emulation[wtype]->we_setext)
X (*emulation[wtype]->we_setext)(&w->w_optdefn);
X opt_setext(&w->w_optdefn, ipc_optmsg);
X }
X }
X }
X
X return(w);
X}
X
Xwin_killw(w)
Xregister struct window *w;
X{
X /*
X * Kill the window "w". This is pretty simple; we just close
X * the data and control file descriptors and mark the structure
X * inactive.
X */
X if (w && w->w_alloc) {
X if (w->w_datafd >= 0) {
X if (w->w_class == WC_INTERNAL)
X utmp_rm(w->w_tty);
X FD_CLR(w->w_datafd, &selmask[0].sm_rd);
X FD_CLR(w->w_datafd, &selmask[0].sm_wt);
X FD_CLR(w->w_datafd, &selmask[0].sm_ex);
X fdmap[w->w_datafd].f_type = FDT_NONE;
X (void)close(w->w_datafd);
X }
X if (w->w_class == WC_EXTERNAL && w->w_ctlfd >= 0) {
X FD_CLR(w->w_ctlfd, &selmask[0].sm_rd);
X FD_CLR(w->w_ctlfd, &selmask[0].sm_wt);
X FD_CLR(w->w_ctlfd, &selmask[0].sm_ex);
X fdmap[w->w_ctlfd].f_type = FDT_NONE;
X (void)close(w->w_ctlfd);
X }
X w->w_alloc = 0;
X }
X}
X
Xwin_renew(w, report)
Xstruct window *w;
Xint report;
X{
X /*
X * Reinitialize (re-NEW) the window "w". Report the state of the
X * window to the Mac if "report" is nonzero.
X */
X opt_renew(&w->w_optdefn, report);
X}
X
Xwin_newtype(w, wtype)
Xregister struct window *w;
Xregister wtype_t wtype;
X{
X /*
X * Change the window emulation type to "wtype".
X */
X if (wtype <= WT_MAXTYPE && wtype != w->w_type) {
X if (emulation[w->w_type]->we_stop)
X (*emulation[w->w_type]->we_stop)(w);
X w->w_type = wtype;
X if (emulation[wtype]->we_start &&
X !(*emulation[wtype]->we_start)(w)) {
X opt_newtype(&w->w_optdefn, &genwinopt,
X (struct woptdefn *)0);
X } else {
X opt_newtype(&w->w_optdefn, &genwinopt,
X &emulation[wtype]->we_optdefn);
X }
X if (w->w_class == WC_EXTERNAL && w->w_ctlfd >= 0) {
X if (emulation[wtype]->we_setext)
X (*emulation[wtype]->we_setext)(&w->w_optdefn);
X opt_setext(&w->w_optdefn, ipc_optmsg);
X }
X }
X}
X
Xwin_envinit(wtype, wid)
Xregister wtype_t wtype;
Xlong wid;
X{
X register char *widstr;
X auto char *env[2];
X
X /*
X * Set up the environment according to the new window type and
X * window ID.
X *
X * A 64-bit integer will fit in 20 digits. If a "long" is wider
X * than this, then this code will have to be adjusted.
X */
X if (wtype <= WT_TEK4010)
X tty_envinit(wtype);
X if ((widstr = malloc(sizeof "UW_ID=" + 20)) != NULL) {
X sprintf(widstr, "UW_ID=%ld", wid);
X env[0] = widstr;
X env[1] = (char *)0;
X env_set(env);
X }
X}
X
Xstatic
Xchar *
Xwin_getopt(win, num)
Xcaddr_t win;
Xwoption_t num;
X{
X register struct window *w;
X static union optvalue ov;
X
X /*
X * Get the value of window option "num". It is arguably wrong to
X * always return the address of "ov" (even if the window isn't
X * allocated or an unknown option type was requested); however,
X * we're already in trouble and there is no good way to recover
X * at this point.
X */
X if ((w = (struct window *)win) != NULL && w->w_alloc) {
X switch (num) {
X case WOG_VIS:
X ov.ov_udata1 = w->w_visible;
X break;
X case WOG_TYPE:
X ov.ov_udata6 = w->w_type;
X break;
X case WOG_POS:
X ov.ov_point.h = w->w_position.h;
X ov.ov_point.v = w->w_position.v;
X break;
X case WOG_TITLE:
X (void)strncpy(ov.ov_string, w->w_title,
X sizeof ov.ov_string);
X ov.ov_string[sizeof ov.ov_string-1] = '\0';
X break;
X case WOG_SIZE:
X ov.ov_point.h = w->w_size.h;
X ov.ov_point.v = w->w_size.v;
X break;
X }
X }
X return((char *)&ov);
X}
X
Xstatic
Xvoid
Xwin_setopt(win, num, value)
Xcaddr_t win;
Xwoption_t num;
Xchar *value;
X{
X register struct window *w;
X register union optvalue *ov;
X
X /*
X * Set window option "num" to "value"
X */
X if ((w = (struct window *)win) != NULL && w->w_alloc &&
X (ov = (union optvalue *)value) != NULL) {
X switch (num) {
X case WOG_VIS:
X w->w_visible = ov->ov_udata1;
X break;
X case WOG_TYPE:
X win_newtype(w, (wtype_t)ov->ov_udata6);
X break;
X case WOG_POS:
X w->w_position.h = ov->ov_point.h;
X w->w_position.v = ov->ov_point.v;
X break;
X case WOG_TITLE:
X (void)strncpy(w->w_title, ov->ov_string,
X sizeof w->w_title);
X w->w_title[sizeof w->w_title-1] = '\0';
X break;
X case WOG_SIZE:
X w->w_size.h = ov->ov_point.h;
X w->w_size.v = ov->ov_point.v;
X break;
X }
X }
X}
!EOF!server/uw_win.c!
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# 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#
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
XSOURCES = `echo $(OBJECTS) | sed -e 's/\\.o/\\.c/g'`
X
XDEFINES = `cat ../DEFINES`
X
XCFLAGS = -O -I$(INCDIR) $(DEFINES)
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) $(DEFINES) $(SOURCES)
X
Xtags:
X ctags $(SOURCES)
X
Xdepend:
X grep '^#include' $(SOURCES) | \
X sed -e '/</d' \
X -e 's/:[^"]*"\([^"]*\)".*/: ..\/h\/\1/' \
X -e 's,^../[a-zA-Z0-9]*/\([^\.]*\)\.[cs],\1.o \1.L,' | \
X awk ' { if ($$1 != prev) { print rec; rec = $$0; prev = $$1; } \
X else { if (length(rec $$3) > 78) { print rec; rec = $$0; } \
X else rec = rec " " $$3 } } \
X END { print rec } ' > makedep
X echo '/^# DO NOT DELETE THIS LINE/+1,$$d' >eddep
X echo '$$r makedep' >>eddep
X echo 'w' >>eddep
X cp Makefile Makefile.bak
X ex - Makefile < eddep
X rm eddep makedep
X
Xclean:
X -rm *.o
X
X# DO NOT DELETE THIS LINE (or the following blank line) -- make depend uses it
X
!EOF!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# 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
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
XSOURCES = `echo $(OBJECTS) | sed -e 's/\\.o/\\.c/g'`
X
XDEFINES = `cat ../DEFINES`
X
XCFLAGS = -O -I$(INCDIR) $(DEFINES)
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) $(DEFINES) $(SOURCES)
X
Xtags:
X ctags $(SOURCES)
X
Xdepend:
X $(CC) -M -I$(INCDIR) $(DEFINES) $(SOURCES) | \
X sed -e ':loop' \
X -e 's/\.\.\/[^ /]*\/\.\./../' \
X -e 't loop' | \
X awk ' { if ($$1 != prev) { print rec; rec = $$0; prev = $$1; } \
X else { if (length(rec $$2) > 78) { print rec; rec = $$0; } \
X else rec = rec " " $$2 } } \
X END { print rec } ' >> makedep
X echo '/^# DO NOT DELETE THIS LINE/+1,$$d' >eddep
X echo '$$r makedep' >>eddep
X echo 'w' >>eddep
X cp Makefile Makefile.bak
X ex - Makefile < eddep
X rm eddep makedep
X
Xclean:
X -rm *.o
X
X# DO NOT DELETE THIS LINE (or the following blank line) -- make depend uses it
X
!EOF!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 *)<c);
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 *)<c);
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_netadj
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 /* window type 6 = plot */
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