Article View: comp.sources.mac
Article #41UW v4.2 (part 8 of 9)
From: John Bruner
Date: Fri, 08 Apr 1988 05:47
Date: Fri, 08 Apr 1988 05:47
1041 lines
27735 bytes
27735 bytes
[UW v4.2 - part 8 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:
# server/uw_tty.c
# server/uw_utmp.c
# server/uw_win.c
# This archive created: Mon Apr 4 07:52:12 1988
# By: Roger L. Long (macintosh@dhw68k.cts.com)
export PATH; PATH=/bin:$PATH
if test ! -d server
then
echo shar: mkdir server
mkdir server
fi
echo shar: extracting "'server/uw_tty.c'" '(8756 characters)'
if test -f 'server/uw_tty.c'
then
echo shar: will not over-write existing file "'server/uw_tty.c'"
else
sed 's/^X//' << \SHAR_EOF > 'server/uw_tty.c'
X/*
X * uw_tty - terminal support for UW
X *
X * Copyright 1985,1986 by John D. Bruner. All rights reserved. Permission to
X * copy this program is given provided that the copy is not sold and that
X * this copyright notice is included.
X */
X
X#include <sys/types.h>
X#include <sys/file.h>
X#include <sys/ioctl.h>
X#include <sys/stat.h>
X
X#include "uw_param.h"
X#include "uw_win.h"
X#include "uw_opt.h"
X
X#define XON 021 /* ASCII XON (ASR-33 paper-tape reader on) */
X#define XOFF 023 /* ASCII XOFF (ASR-33 paper-tape reader off) */
X
Xstatic char *envinfo[][3] = {
X {
X "TERM=adm31",
X "TERMCAP=adm31:cr=^M:do=^J:nl=^J:al=\\EE:am:le=^H:bs:ce=\\ET:cm=\\E=%+ %+ :cl=^Z:cd=\\EY:co#80:dc=\\EW:dl=\\ER:ei=\\Er:ho=^^:im=\\Eq:li#24:mi:nd=^L:up=^K:MT:km:so=\\EG1:se=\\EG0:",
X (char *)0
X },
X {
X "TERM=vt52",
X (char *)0
X },
X {
X "TERM=ansi",
X (char *)0
X },
X {
X "TERM=tek4010",
X (char *)0
X }
X};
X
X/* private (emulation-specific) data */
Xstruct tty {
X struct {
X unsigned short h,v;
X } t_size;
X unsigned t_fontsz;
X unsigned t_clipb;
X unsigned t_bell;
X unsigned t_curs;
X unsigned t_chgsz;
X};
X
X#define WOTTY_SIZE 8 /* terminal size in (row, col) */
X#define WOTTY_FONTSZ 9 /* font size index (0=7pt, 1=9pt) */
X#define WOTTY_CLIPB 10 /* 0=clipboard, 1=encode mouse clicks */
X#define WOTTY_BELL 11 /* bell: bit 0=visible, bit 1=audible */
X#define WOTTY_CURSOR 12 /* cursor type: 0=block, 1=underscore */
X#define WOTTY_CHGSZ 13 /* change actual size (not view size) */
X
Xstatic woptarg_t size_xdr[] = { WOA_UDATA(12), WOA_UDATA(12), WOA_END };
Xstatic woptarg_t fontsz_xdr[] = { WOA_UDATA(6), WOA_END };
Xstatic woptarg_t clipb_xdr[] = { WOA_UDATA(1), WOA_END };
Xstatic woptarg_t bell_xdr[] = { WOA_UDATA(2), WOA_END };
Xstatic woptarg_t curs_xdr[] = { WOA_UDATA(1), WOA_END };
Xstatic woptarg_t chgsz_xdr[] = { WOA_UDATA(1), WOA_END };
X
X/* TIOCSWINSZ is in 4.3BSD, TIOCSSIZE is in Sun UNIX */
X#if defined(TIOCSWINSZ) || defined(TIOCSSIZE)
X#define RPTWINSZ (1<<WOTTY_SIZE)
X#else
X#define RPTWINSZ 0
X#endif
X
X#define TTY_WOPT { \
X 0, 0, 0, 0, \
X RPTWINSZ|(1<<WOTTY_FONTSZ)|(1<<WOTTY_CLIPB)| \
X (1<<WOTTY_BELL)|(1<<WOTTY_CURSOR)|(1<<WOTTY_CHGSZ), \
X { \
X { NULL, NULL, NULL }, \
X { NULL, NULL, NULL }, \
X { NULL, NULL, NULL }, \
X { NULL, NULL, NULL }, \
X { NULL, NULL, NULL }, \
X { NULL, NULL, NULL }, \
X { NULL, NULL, NULL }, \
X { NULL, NULL, NULL }, \
X { size_xdr, tty_getopt, tty_setopt }, \
X { fontsz_xdr, tty_getopt, tty_setopt }, \
X { clipb_xdr, tty_getopt, tty_setopt }, \
X { bell_xdr, tty_getopt, tty_setopt }, \
X { curs_xdr, tty_getopt, tty_setopt }, \
X { chgsz_xdr, tty_getopt, tty_setopt } \
X } \
X}
Xextern int tty_start();
Xextern void tty_stop(), tty_setopt(), tty_setext();
Xextern char *tty_getopt();
X
Xstruct emulation adm31_emul = { TTY_WOPT, tty_start, tty_stop, tty_setext };
Xstruct emulation vt52_emul = { TTY_WOPT, tty_start, tty_stop, tty_setext };
Xstruct emulation ansi_emul = { TTY_WOPT, tty_start, tty_stop, tty_setext };
Xstruct emulation tek_emul = { { 0, 0, 0, 0, 0 }, tty_start, tty_stop };
X
Xtty_mode(f)
Xint f;
X{
X static struct sgttyb ostty, nstty;
X static struct tchars otchars, ntchars;
X static struct ltchars oltchars, nltchars;
X static int olmode, nlmode;
X static int operm;
X static saved;
X static int inout = FREAD|FWRITE;
X struct stat st;
X
X /*
X * This routine either saves the current terminal modes and then
X * sets up the terminal line or resets the terminal modes (depending
X * upon the value of "f"). The terminal line is used in "cbreak"
X * mode with all special characters except XON/XOFF disabled. The
X * hated (by me) LDECCTQ mode is required for the Macintosh to
X * handle flow control properly.
X */
X if (f == 1) {
X if (fstat(0, &st) == 0)
X operm = st.st_mode & 06777;
X else
X operm = -1;
X if (ioctl(0, (int)TIOCGETP, (char *)&ostty) < 0) {
X perror("ioctl((int)TIOCGETP)");
X done(1);
X }
X if (ioctl(0, (int)TIOCGETC, (char *)&otchars) < 0) {
X perror("ioctl((int)TIOCGETC)");
X done(1);
X }
X if (ioctl(0, (int)TIOCGLTC, (char *)&oltchars) < 0) {
X perror("ioctl((int)TIOCGLTC)");
X done(1);
X }
X if (ioctl(0, (int)TIOCLGET, (char *)&olmode) < 0) {
X perror("ioctl((int)TIOCLGET)");
X done(1);
X }
X nstty = ostty;
X nstty.sg_erase = nstty.sg_kill = -1;
X nstty.sg_flags |= CBREAK;
X nstty.sg_flags &= ~(RAW|CRMOD|ECHO|LCASE|XTABS|ALLDELAY);
X ntchars.t_intrc = ntchars.t_quitc = -1;
X ntchars.t_eofc = ntchars.t_brkc = -1;
X ntchars.t_startc = XON;
X ntchars.t_stopc = XOFF;
X nltchars.t_suspc = nltchars.t_dsuspc = -1;
X nltchars.t_rprntc = nltchars.t_flushc = -1;
X nltchars.t_werasc = nltchars.t_lnextc = -1;
X nlmode = olmode | LDECCTQ;
X if (operm != -1 && fchmod(0, S_IREAD|S_IWRITE) < 0)
X operm = -1;
X if (ioctl(0, (int)TIOCSETN, (char *)&nstty) < 0) {
X perror("ioctl((int)TIOCSETN)");
X done(1);
X }
X if (ioctl(0, (int)TIOCSETC, (char *)&ntchars) < 0) {
X perror("ioctl((int)TIOCSETC");
X done(1);
X }
X if (ioctl(0, (int)TIOCSLTC, (char *)&nltchars) < 0) {
X perror("ioctl((int)TIOCSLTC");
X done(1);
X }
X if (ioctl(0, (int)TIOCLSET, (char *)&nlmode) < 0) {
X perror("ioctl((int)TIOCLSET)");
X done(1);
X }
X saved = 1;
X } else if (saved) {
X (void)ioctl(0, (int)TIOCFLUSH, (char *)&inout);
X (void)ioctl(0, (int)TIOCSETP, (char *)&ostty);
X (void)ioctl(0, (int)TIOCSETC, (char *)&otchars);
X (void)ioctl(0, (int)TIOCSLTC, (char *)&oltchars);
X (void)ioctl(0, (int)TIOCLSET, (char *)&olmode);
X if (operm != -1)
X (void)fchmod(0, operm);
X }
X}
X
Xstatic
Xtty_start(w)
Xregister struct window *w;
X{
X register struct tty *t;
X extern char *malloc();
X
X /*
X * Start up a terminal emulation. Establish reasonable defaults
X * for the terminal-specific window options.
X */
X if (w->w_type != WT_TEK4010) {
X if ((w->w_private = malloc(sizeof(struct tty))) != NULL) {
X t = (struct tty *)w->w_private;
X t->t_size.h = 80;
X t->t_size.v = 24;
X t->t_fontsz = 0;
X t->t_clipb = 0;
X t->t_bell = 3;
X t->t_curs = 0;
X t->t_chgsz = 0;
X return(1);
X } else
X return(0);
X } else {
X w->w_private = (char *)0;
X return(1);
X }
X}
X
Xstatic
Xvoid
Xtty_stop(w)
Xregister struct window *w;
X{
X /*
X * Shut down (stop) a terminal emulation.
X */
X free(w->w_private);
X w->w_private = (char *)0;
X}
X
Xstatic
Xvoid
Xtty_setext(wod)
Xregister struct woptdefn *wod;
X{
X /*
X * This routine makes adjustments to the window option definitions
X * for external windows. Basically, we turn off reporting for
X * WOTTY_SIZE. (If the external process wants to handle this, it
X * can turn it back on.)
X */
X WOPT_CLR(wod->wod_do, WOTTY_SIZE);
X WOPT_CLR(wod->wod_askrpt, WOTTY_SIZE);
X}
X
Xtty_envinit(wtype)
Xregister wtype_t wtype;
X{
X /*
X * Set up environment variables corresponding to the window type
X * "wtype".
X */
X env_set(envinfo[wtype]);
X}
X
Xstatic
Xchar *
Xtty_getopt(win, num)
Xcaddr_t win;
Xwoption_t num;
X{
X register struct tty *t;
X static union optvalue ov;
X struct window *w;
X
X if ((w=(struct window *)win) != NULL && w->w_alloc &&
X (t=(struct tty *)w->w_private) != NULL) {
X switch (num) {
X case WOTTY_SIZE:
X ov.ov_point.h = t->t_size.h;
X ov.ov_point.v = t->t_size.v;
X break;
X case WOTTY_FONTSZ:
X ov.ov_udata6 = t->t_fontsz;
X break;
X case WOTTY_CLIPB:
X ov.ov_udata1 = t->t_clipb;
X break;
X case WOTTY_BELL:
X ov.ov_udata2 = t->t_bell;
X break;
X case WOTTY_CURSOR:
X ov.ov_udata1 = t->t_curs;
X break;
X case WOTTY_CHGSZ:
X ov.ov_udata1 = t->t_chgsz;
X break;
X }
X }
X return((char *)&ov);
X}
X
Xstatic
Xvoid
Xtty_setopt(win, num, value)
Xcaddr_t win;
Xwoption_t num;
Xchar *value;
X{
X register struct tty *t;
X register union optvalue *ovp;
X register struct window *w;
X
X if ((w=(struct window *)win) != NULL && w->w_alloc &&
X (t=(struct tty *)w->w_private) != NULL &&
X (ovp = (union optvalue *)value) != NULL) {
X switch (num) {
X case WOTTY_SIZE:
X t->t_size.h = ovp->ov_point.h;
X t->t_size.v = ovp->ov_point.v;
X#ifdef TIOCSWINSZ
X if (w->w_class == WC_INTERNAL) {
X /* set window size on pty (4.3BSD) */
X struct winsize ws;
X ws.ws_row = t->t_size.v;
X ws.ws_col = t->t_size.h;
X ws.ws_xpixel = w->w_size.h;
X ws.ws_ypixel = w->w_size.v;
X (void)ioctl(w->w_datafd, (int)TIOCSWINSZ,
X (char *)&ws);
X }
X#else
X#ifdef TIOCSSIZE
X if (w->w_class == WC_INTERNAL) {
X /* set window size on pty (Sun) */
X struct ttysize ts;
X ts.ts_lines = t->t_size.v;
X ts.ts_cols = t->t_size.h;
X (void)ioctl(w->w_datafd, (int)TIOCSSIZE,
X (char *)&ts);
X }
X#endif
X#endif
X break;
X case WOTTY_FONTSZ:
X t->t_fontsz = ovp->ov_udata6;
X break;
X case WOTTY_CLIPB:
X t->t_clipb = ovp->ov_udata1;
X break;
X case WOTTY_BELL:
X t->t_bell = ovp->ov_udata2;
X break;
X case WOTTY_CURSOR:
X t->t_curs = ovp->ov_udata1;
X break;
X case WOTTY_CHGSZ:
X t->t_chgsz = ovp->ov_udata1;
X break;
X }
X }
X}
SHAR_EOF
if test 8756 -ne "`wc -c < 'server/uw_tty.c'`"
then
echo shar: error transmitting "'server/uw_tty.c'" '(should have been 8756 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'server/uw_utmp.c'" '(3885 characters)'
if test -f 'server/uw_utmp.c'
then
echo shar: will not over-write existing file "'server/uw_utmp.c'"
else
sed 's/^X//' << \SHAR_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
SHAR_EOF
if test 3885 -ne "`wc -c < 'server/uw_utmp.c'`"
then
echo shar: error transmitting "'server/uw_utmp.c'" '(should have been 3885 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'server/uw_win.c'" '(10772 characters)'
if test -f 'server/uw_win.c'
then
echo shar: will not over-write existing file "'server/uw_win.c'"
else
sed 's/^X//' << \SHAR_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}
SHAR_EOF
if test 10772 -ne "`wc -c < 'server/uw_win.c'`"
then
echo shar: error transmitting "'server/uw_win.c'" '(should have been 10772 characters)'
fi
fi # end of overwriting check
# End of shell archive
exit 0
--- end of part 8 ---
Technical Details
Message-ID:
<6612@dhw68k.cts.com>Path:
arc1-ca.pugleaf.net!utzoo!mnetor!uunet!husc6!mailrus!ames!oliveb!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>Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!mnetor!uunet!husc6!mailrus!ames!oliveb!felix!dhw68k!macintosh From: jdb@mordor.s1.gov (John Bruner) Newsgroups: comp.sources.mac Subject: UW v4.2 (part 8 of 9) Message-ID: <6612@dhw68k.cts.com> Date: 8 Apr 88 05:47:50 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> Sender: macintosh@dhw68k.cts.com Organization: Lawrence Livermore National Laboratory, S-1 Project Lines: 1041 Approved: bytebug@dhw68k.cts.com (Roger L. Long)