home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Garbo
/
Garbo.cdr
/
mac
/
source
/
layers.zoo
/
layers.2
< prev
next >
Wrap
Text File
|
1990-06-11
|
48KB
|
1,815 lines
#! /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:
#
# layers.h
# layersize.c
# layertitle.c
# macbput.c
# makefile
# protocol.c
#
# This archive created: Thu May 31 21:58:11 1990
# By: Roger L. Long (macintosh@dhw68k.cts.com)
export PATH; PATH=/bin:$PATH
echo shar: extracting "'layers.h'" '(2049 characters)'
if test -f 'layers.h'
then
echo shar: will not over-write existing file "'layers.h'"
else
sed 's/^X//' << \SHAR_EOF > 'layers.h'
X/* Copyright (C) 1989 by David W. Trissel
X *
X * Not derived from licensed software.
X *
X * Permission is granted to freely use, copy, modify, and redistribute
X * this software, provided that no attempt is made to gain profit from it,
X * the author is not construed to be liable for any results of using the
X * software, alterations are clearly marked as such, and this notice is
X * not modified.
X *
X */
X
X#define MAXPCHAN 7 /* maximum layers supported */
X
X#define MAXSTR 200
X#define MAXARGS 64
X#define MAXLINE 1024
X#define IOSIZE 800 /* data gulp handling size */
X
X/* WARNING - packet sizes must be insured to never match the ESCAPE char */
X#define ESCAPE '}' /* datalink escape character */
X
X#define DO if (Dflag) /* for debugging */
X
X/* miscelaneous common data */
Xextern int Dflag; /* debug dump indicator flag */
X
X/* Shape structure passed between MacLayers and ourselves */
Xstruct Shape
X{ short worigv; /* verical window bit origin */
X short worigh; /* horizontal window bit origin */
X short wlines; /* window height */
X short wchars; /* window width */
X short wfont; /* window font size */
X short wattr; /* window attributes */
X};
X
X#define Wa_shell 0x01 /* window is a shell */
X
X
X /* The following modules define the complete protocol/server interface */
X
X /* layers.c */
X
Xextern void FQuit(/* exitcode */);
Xextern void ReceiveQuit();
Xextern void ReceiveNew(/* chanid, shape */);
Xextern void ReceiveDelete(/* chanid */);
Xextern void ReceiveSignal(/* chanid, signal */);
Xextern void ReceiveData(/* chanid, buff, cnt */);
Xextern void ReceiveReshape(/*chanid, shape */);
Xextern void DEBUG(/* format, arg1, arg2, arg3, arg4 */);
X
X /* protocol.c */
X
Xextern int InitLink();
Xextern int TopChannel();
Xextern int SendNew(/* shape */);
Xextern void SendTitle(/* chan, buff, cnt */);
Xextern void SendDelete(/* chan */);
Xextern void SendQuit();
Xextern void SendReshape(/* chan, shape */);
Xextern void SendData(/* chan, buff, cnt */);
Xextern void ProcessStreamin();
SHAR_EOF
if test 2049 -ne "`wc -c < 'layers.h'`"
then
echo shar: error transmitting "'layers.h'" '(should have been 2049 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'layersize.c'" '(3586 characters)'
if test -f 'layersize.c'
then
echo shar: will not over-write existing file "'layersize.c'"
else
sed 's/^X//' << \SHAR_EOF > 'layersize.c'
X/* Copyright (C) 1989 by David W. Trissel
X *
X * Not derived from licensed software.
X *
X * Permission is granted to freely use, copy, modify, and redistribute
X * this software, provided that no attempt is made to gain profit from it,
X * the author is not construed to be liable for any results of using the
X * software, alterations are clearly marked as such, and this notice is
X * not modified.
X *
X */
X /* All rights reserved. */
X
X /* layersize - update BSD Sun Unix with window size information */
X
X#include <stdio.h>
X#include <errno.h>
X#include <sys/ioctl.h>
X
Xextern int sys_nerr;
Xextern char *sys_errlist[];
X
Xstatic void gotsyserr(/* char * */);
Xstatic void goterr(/* char * */);
Xstatic int getnumber(/* char * */);
X
X
X /* main() - update BSD window size */
X
Xmain(ac, av)
Xint ac; /* argument count */
Xchar **av; /* argument vector */
X{
X struct winsize wsize; /* window size structure for ioctl() */
X char *ap; /* argument scan pointer */
X int lines; /* new lines value */
X int cols; /* new columns value */
X
X if (--ac != 2)
X goterr("Missing lines and column options");
X
X /* get window size (actually do this to set xpixel and ypixel values) */
X if (ioctl(0, TIOCGWINSZ, &wsize) == -1)
X gotsyserr("No window support in host"); /* terminate with message */
X
X /* scan looking for -l and -c line and column numeric sizes */
X lines = cols = 0; /* reset values */
X while (ac > 0)
X { ap = *++av; /* point to next argument string */
X if (ac-- > 0 && *ap == '-') /* if option ... */
X switch (ap[1])
X { case 'l': /* lines */
X lines = getnumber(&ap[2]);
X break;
X
X case 'c': /* columns */
X cols = getnumber(&ap[2]);
X break;
X
X default:
X goterr("Usupported option"); /* unsupported option */
X break;
X
X } /* end '-' argument */
X else
X goterr("Unsupported parameter"); /* unsupported parameter */
X
X } /* end while argument vector scan */
X
X /* must have both lines and columns */
X if (lines == 0 || cols == 0)
X goterr("Must specify both lines and columns");
X
X wsize.ws_col = cols; /* set columns */
X wsize.ws_row = lines; /* set lines */
X /* update the kernel */
X if (ioctl(0, TIOCSWINSZ, &wsize) == -1)
X gotsyserr("Failed to update window size"); /* didn't go */
X
X}
X
X
X /* goterr() - issue error and terminate */
X
Xstatic void
Xgoterr(msg)
Xchar *msg; /* error message string */
X{
X printf("%s\n", msg); /* send error message to user */
X exit(1); /* terminate with error */
X
X} /* goterr() */
X
X
X /* gotsyserror() - system error return */
X
Xstatic void
Xgotsyserr(msg)
Xchar *msg; /* error string */
X{
X if (errno > 0 && errno < sys_nerr)
X printf("%s: %s\n", msg, sys_errlist[errno]);
X else
X printf("%s: Error %d\n", msg, errno);
X
X exit(1); /* exit with failure */
X
X} /* gotsyserr() */
X
X
X /* getnumber() - parse option number */
X
Xstatic int
Xgetnumber(str)
Xchar *str; /* start of option string */
X{
X int n; /* number being built */
X
X if (str == NULL)
X goterr("Invalid numeric in option");
X
X /* skip any leading delimiters */
X while (*str && (*str == ' ' || *str == '\t'))
X str++;
X
X for(n=0; *str && *str >= '0' && *str <= '9'; str++)
X n = n*10 + *str - '0'; /* add next digit in */
X
X /* make sure number terminates legally */
X switch (*str)
X { case '\0':
X case ' ':
X case '\t':
X case '\n':
X if (n <= 0 || n > 200)
X goterr("Number out of range");
X break; /* these are OK */
X
X default:
X goterr("Invalid numeric in option");
X
X } /* end switch */
X
X return ( n ); /* return the number */
X
X} /* getnumber() */
SHAR_EOF
if test 3586 -ne "`wc -c < 'layersize.c'`"
then
echo shar: error transmitting "'layersize.c'" '(should have been 3586 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'layertitle.c'" '(1242 characters)'
if test -f 'layertitle.c'
then
echo shar: will not over-write existing file "'layertitle.c'"
else
sed 's/^X//' << \SHAR_EOF > 'layertitle.c'
X/* Copyright (C) 1989 by David W. Trissel
X *
X * Not derived from licensed software.
X *
X * Permission is granted to freely use, copy, modify, and redistribute
X * this software, provided that no attempt is made to gain profit from it,
X * the author is not construed to be liable for any results of using the
X * software, alterations are clearly marked as such, and this notice is
X * not modified.
X *
X */
X /* All rights reserved. */
X
X /* layertitle - utility to specify window title */
X
X#include <stdio.h>
X
X#define ESC 0x1b
X
X /* main() - send string designating layers window title */
X
Xmain(ac, av)
Xint ac; /* argument count */
Xchar **av; /* argument vector */
X{
X char *ap; /* argument scan pointer */
X
X if (--ac != 1)
X { printf("usage: layertitle \"new window title\"\n");
X exit(1);
X }
X
X ap = *++av; /* point to argument string */
X
X /* Transmit the title string in the ANSI Private Message format
X ** which is
X ** ESC '^' message ESC '\'
X */
X printf("%c%c%s%c%c", ESC, '^', ap, ESC, '\\');
X
X} /* main() */
SHAR_EOF
if test 1242 -ne "`wc -c < 'layertitle.c'`"
then
echo shar: error transmitting "'layertitle.c'" '(should have been 1242 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'macbput.c'" '(9383 characters)'
if test -f 'macbput.c'
then
echo shar: will not over-write existing file "'macbput.c'"
else
sed 's/^X//' << \SHAR_EOF > 'macbput.c'
X/*
X * (originally macput) -- send file to Macintosh using MacBinary XMODEM protocol
X * Dave Johnson, Brown University Computer Science
X *
X * (c) 1984 Brown University
X * may be used but not sold without permission
X *
X */
X
X/* To compile:
X cc -O -o macbput macbput.c
X (Sun 4.2 BSD) cc -O -DSUNBSD42 -o macbput macbput.c
X (System V) cc -O -DSYSV -o macbput macbput.c
X
X Latest modifications 10/20/88 by Trissel -
X
X 1. General cleanup by removal of unused definitions and headers.
X 2. Added #ifdefs to support System V and BSD 4.2 Sun compilation.
X 3. Removed ancient Macterminal Beta 0.5X code.
X 4. Fixed bad bug where XMODEM block count was not bumped up
X after the first fork transfer.
X
X Dave Trissel
X Motorola Inc.
X ut-sally!oakhill!davet
X
X This code is fundamentally from two earlier programmers:
X
X Jon Hueras
X Symantec/THINK Technologies
X singer@endor.harvard.edu
X
X who added 2-Byte CRC capability to code from:
X
X Dave Johnson
X ddj%brown@csnet-relay.arpa
X Brown University Computer Science
X
X who did the initial MacTerminal 1.1 transfer protocol.
X*/
X
X/* If you have System V define the following: */
X /* #define SYSV */
X
X/* Sun BSD 4.2 systems should define the following: */
X /* #define SUNBSD42 */
X
X#include <stdio.h>
X#include <signal.h>
X#include <setjmp.h>
X#ifdef SYSV
X#include <termio.h>
X#else
X#include <sgtty.h>
X#endif
X#include <sys/types.h>
X#include <sys/stat.h>
X
X#ifdef SUNBSD42
X/* RAW is no longer being found on latest Sun system (??) (Trissel) */
X#define RAW 0x20
X#endif
X
X#define RECORDBYTES 132
X#define DATABYTES 128
X#define NAMEBYTES 63
X
X#define RETRIES 10
X#define ACKTIMO 10
X
X#define MAXRECNO 0xff
X#define BYTEMASK 0xff
X
X#define TMO -1
X#define DUP '\000'
X#define SOH '\001'
X#define EOT '\004'
X#define ACK '\006'
X#define NAK '\025'
X#define CAN '\030'
X#define EEF '\032'
X#define ESC '\033'
X
X#define H_NLENOFF 1
X#define H_NAMEOFF 2
X/* 65 <-> 80 is the FInfo structure */
X#define H_TYPEOFF 65
X#define H_AUTHOFF 69
X
X#define H_LOCKOFF 81
X#define H_DLENOFF 83
X#define H_RLENOFF 87
X#define H_CTIMOFF 91
X#define H_MTIMOFF 95
X
X#define H_OLD_DLENOFF 81
X#define H_OLD_RLENOFF 85
X
X#define TEXT 0
X#define DATA 1
X#define RSRC 2
X#define FULL 3
X
Xint mode, txtmode;
X
Xstruct macheader {
X char m_name[NAMEBYTES+1];
X char m_type[4];
X char m_author[4];
X long m_datalen;
X long m_rsrclen;
X long m_createtime;
X long m_modifytime;
X} mh;
X
Xstruct filenames {
X char f_info[256];
X char f_data[256];
X char f_rsrc[256];
X} files;
X
Xint recno, crc;
Xchar buf[DATABYTES];
X
Xchar usage[] =
X "usage: \"macbput [-rdu] [-t type] [-c creator] [-n name] filename\"\n";
X
Xmain(ac, av)
Xchar **av;
X{
X int n;
X char *filename;
X
X if (ac == 1) {
X fprintf(stderr, usage);
X exit(1);
X }
X
X mode = FULL;
X ac--; av++;
X while (ac) {
X if (av[0][0] == '-') {
X switch (av[0][1]) {
X case 'r':
X mode = RSRC;
X strncpy(mh.m_type, "????", 4);
X strncpy(mh.m_author, "????", 4);
X break;
X case 'u':
X mode = TEXT;
X strncpy(mh.m_type, "TEXT", 4);
X strncpy(mh.m_author, "MACA", 4);
X break;
X case 'd':
X mode = DATA;
X strncpy(mh.m_type, "????", 4);
X strncpy(mh.m_author, "????", 4);
X break;
X case 'n':
X if (ac > 1) {
X ac--; av++;
X n = strlen(av[0]);
X if (n > NAMEBYTES) n = NAMEBYTES;
X strncpy(mh.m_name, av[0], n);
X mh.m_name[n] = '\0';
X break;
X }
X else goto bad_usage;
X case 't':
X if (ac > 1) {
X ac--; av++;
X strncpy(mh.m_type, av[0], 4);
X break;
X }
X else goto bad_usage;
X case 'c':
X if (ac > 1) {
X ac--; av++;
X strncpy(mh.m_author, av[0], 4);
X break;
X }
X else goto bad_usage;
X default:
Xbad_usage:
X fprintf(stderr, usage);
X exit(1);
X }
X }
X else {
X filename = av[0];
X }
X ac--; av++;
X }
X
X setup_tty();
X find_files(filename, mode);
X if (mode != FULL)
X forge_info();
X
X if (send_sync()) {
X recno = 1;
X txtmode = 0;
X send_file(files.f_info, 1);
X
X if (mode != FULL)
X unlink(files.f_info);
X
X if (mode == TEXT) txtmode++;
X send_file(files.f_data, 1);
X
X txtmode = 0;
X send_file(files.f_rsrc, 0);
X }
X reset_tty();
X}
X
Xfind_files(filename, mode)
Xchar *filename;
X{
X int n, tdiff;
X struct stat stbuf;
X
X sprintf(files.f_data, "%s.data", filename);
X sprintf(files.f_rsrc, "%s.rsrc", filename);
X
X if (mode == FULL) {
X sprintf(files.f_info, "%s.info", filename);
X if (stat(files.f_info, &stbuf) != 0) {
X perror(files.f_info);
X cleanup(-1);
X }
X return;
X }
X else {
X strcpy(files.f_info, "#machdrXXXXXX");
X mktemp(files.f_info);
X }
X
X if (mode == RSRC) {
X strcpy(files.f_data, "/dev/null");
X if (stat(files.f_rsrc, &stbuf) != 0) {
X strcpy(files.f_rsrc, filename);
X if (stat(files.f_rsrc, &stbuf) != 0) {
X perror(files.f_rsrc);
X cleanup(-1);
X }
X }
X mh.m_datalen = 0;
X mh.m_rsrclen = stbuf.st_size;
X }
X else {
X strcpy(files.f_rsrc, "/dev/null");
X if (stat(files.f_data, &stbuf) != 0) {
X sprintf(files.f_data, "%s.text", filename);
X if (stat(files.f_data, &stbuf) != 0) {
X strcpy(files.f_data, filename);
X if (stat(files.f_data, &stbuf) != 0) {
X perror(files.f_data);
X cleanup(-1);
X }
X }
X }
X mh.m_datalen = stbuf.st_size;
X mh.m_rsrclen = 0;
X }
X
X if (mh.m_name[0] == '\0') {
X n = strlen(filename);
X if (n > NAMEBYTES) n = NAMEBYTES;
X strncpy(mh.m_name, filename, n);
X mh.m_name[n] = '\0';
X }
X}
X
Xforge_info()
X{
X int n;
X char *np;
X FILE *fp;
X
X for (np = mh.m_name; *np; np++)
X if (*np == '_') *np = ' ';
X
X buf[H_NLENOFF] = n = np - mh.m_name;
X strncpy(buf + H_NAMEOFF, mh.m_name, n);
X strncpy(buf + H_TYPEOFF, mh.m_type, 4);
X strncpy(buf + H_AUTHOFF, mh.m_author, 4);
X put4(buf + H_DLENOFF, mh.m_datalen);
X put4(buf + H_RLENOFF, mh.m_rsrclen);
X put4(buf + H_CTIMOFF, mh.m_createtime);
X put4(buf + H_MTIMOFF, mh.m_modifytime);
X fp = fopen(files.f_info, "w");
X if (fp == NULL) {
X perror("temp file");
X cleanup(-1);
X }
X fwrite(buf, 1, DATABYTES, fp);
X fclose(fp);
X}
X
Xsend_sync()
X {
X int c;
X
X tputc(ESC);
X tputc('b');
X
X for (;;) {
X
X if ((c = tgetc(ACKTIMO)) == TMO)
X {
X return(0);
X }
X
X if (c == NAK)
X {
X return(1);
X }
X
X if (c == 'C') {
X crc++;
X return(1);
X }
X }
X }
X
Xsend_file(fname, more)
Xchar *fname;
Xint more;
X{
X register int status, i, n;
X FILE *inf;
X
X inf = fopen(fname, "r");
X if (inf == NULL) {
X perror(fname);
X cleanup(-1);
X }
X for (;;) {
X n = fread(buf, 1, DATABYTES, inf);
X if (n > 0) {
X for (i = 0; i < RETRIES; i++) {
X send_rec(buf, DATABYTES);
X while ((status = tgetc(ACKTIMO)) != ACK && status != NAK && status != CAN);
X if (status != NAK)
X break;
X }
X if (status != ACK) {
X if (status != CAN)
X while ((status = tgetc(ACKTIMO)) != CAN);
X fclose(inf);
X cleanup(-1);
X /* NOTREACHED */
X }
X }
X if (n < DATABYTES) {
X if (!more) {
X tputc(EOT);
X tgetc(ACKTIMO);
X }
X return;
X }
X recno++;
X recno &= MAXRECNO;
X }
X}
X
Xsend_rec(buf, recsize)
Xchar buf[];
Xint recsize;
X{
X int i, cksum;
X char *bp;
X
X if (txtmode || !crc) {
X cksum = 0;
X bp = buf;
X for (i = 0; i < recsize; i++, bp++) {
X if (txtmode && *bp == '\n')
X *bp = '\r';
X cksum += *bp;
X }
X }
X
X if (crc)
X cksum = calcrc(buf, recsize);
X
X tputc(SOH);
X tputc((char) recno);
X tputc((char) (MAXRECNO - recno));
X tputrec(buf, recsize);
X
X if (crc) {
X tputc((char) (cksum >> 8));
X tputc((char) cksum);
X } else
X tputc((char) cksum);
X}
X
Xstatic int ttyfd;
Xstatic FILE *ttyf;
Xstatic jmp_buf timobuf;
X
Xtgetc(timeout)
Xint timeout;
X{
X int c;
X
X if (setjmp(timobuf))
X return TMO;
X
X alarm(timeout);
X c = getc(ttyf);
X alarm(0);
X
X if (c == -1) /* probably hung up or logged off */
X return EOT;
X else
X return c & BYTEMASK;
X}
X
Xtputrec(buf, count)
Xchar *buf;
Xint count;
X{
X write(ttyfd, buf, count);
X}
X
Xtputc(c)
Xchar c;
X{
X write(ttyfd, &c, 1);
X}
X
Xtimedout()
X{
X signal(SIGALRM, timedout); /* for pre-4.2 systems */
X longjmp(timobuf, 1);
X}
X
X#ifdef SYSV
Xstatic struct termio otty, ntty;
X#else
Xstatic struct sgttyb otty, ntty;
X#endif
X
X/* should turn messages off */
X
Xsetup_tty()
X{
X int cleanup();
X int timedout();
X
X ttyf = stdin;
X ttyfd = fileno(stdout);
X#ifdef SYSV
X ioctl(ttyfd, TCGETA, &otty); /* get termio info */
X#else
X ioctl(ttyfd, TIOCGETP, &otty);
X#endif
X signal(SIGHUP, cleanup);
X signal(SIGINT, cleanup);
X signal(SIGQUIT, cleanup);
X signal(SIGTERM, cleanup);
X signal(SIGALRM, timedout);
X ntty = otty;
X#ifdef SYSV
X ntty.c_iflag = BRKINT; /* only interrupt on break */
X ntty.c_oflag = 0; /* no output processing */
X ntty.c_cflag |= CS8; /* 8 bit characters */
X ntty.c_lflag = 0; /* no echoing */
X ntty.c_cc[VEOF] = 1; /* "MIN" minimum chars before input */
X ntty.c_cc[VEOL] = 1; /* "TIME" maximum .1 secs before feed */
X ioctl(ttyfd, TCSETAF, &ntty); /* set mode and flush input */
X#else
X ntty.sg_flags = RAW;
X ioctl(ttyfd, TIOCSETP, &ntty);
X#endif
X}
X
Xreset_tty()
X{
X if (ttyf != NULL) {
X#ifdef SYSV
X ioctl(ttyfd, TCSETAF, &otty); /* reset after output drains */
X#else
X sleep (5); /* wait for output to drain */
X ioctl(ttyfd, TIOCSETP, &otty);
X#endif
X }
X}
X
Xcleanup(sig)
Xint sig;
X{
X reset_tty();
X exit(sig);
X}
X
Xput4(bp, value)
Xchar *bp;
Xlong value;
X{
X register int i, c;
X
X for (i = 0; i < 4; i++) {
X c = (value >> 24) & BYTEMASK;
X value <<= 8;
X *bp++ = c;
X }
X}
X
Xint calcrc(ptr, count)
Xchar *ptr;
Xint count;
X {
X int crc, i;
X
X crc = 0;
X while (--count >= 0) {
X crc ^= ((int) *ptr++) << 8;
X for (i = 0; i < 8; ++i)
X if (crc & 0x8000)
X crc = crc << 1 ^ 0x1021;
X else
X crc <<= 1;
X }
X return (crc & 0xFFFF);
X }
SHAR_EOF
if test 9383 -ne "`wc -c < 'macbput.c'`"
then
echo shar: error transmitting "'macbput.c'" '(should have been 9383 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'makefile'" '(1674 characters)'
if test -f 'makefile'
then
echo shar: will not over-write existing file "'makefile'"
else
sed 's/^X//' << \SHAR_EOF > 'makefile'
X# Makefile for Layers 1.0
X
XBIN = /usr/local
XMANDIR = /usr/local/manl
X
XPGM = layers
XPGM2 = layersize
XPGM3 = layertitle
XPGM4 = macbput
XMS = l
XCFLAGS = -O
XCFILES = layers.c protocol.c
XOFILES = layers.o protocol.o
X
Xall: $(PGM) $(PGM2) $(PGM3) $(PGM4)
X
X$(PGM): $(OFILES)
X $(CC) $(CFLAGS) -o $(PGM) $(OFILES)
X
X# $(CC) $(CFLAGS) -o $(PGM) $(OFILES) -ltermcap
X
Xlayers.o: layers.c layers.h
X $(CC) $(CFLAGS) -c layers.c
X
Xprotocol.o: protocol.c layers.h
X $(CC) $(CFLAGS) -c protocol.c
X
X$(PGM2): layersize.o
X $(CC) $(CFLAGS) -o $(PGM2) layersize.o
X
X$(PGM3): layertitle.o
X $(CC) $(CFLAGS) -o $(PGM3) layertitle.o
X
X$(PGM4): macbput.o
X $(CC) $(CFLAGS) -o $(PGM4) macbput.o
X
Xlayersize.o: layersize.c
X $(CC) $(CFLAGS) -c layersize.c
X
Xlayertitle.o: layertitle.c
X $(CC) $(CFLAGS) -c layertitle.c
X
Xmacbput.o: macbput.c
X $(CC) $(CFLAGS) -c macbput.c
X
Xinstall: $(PGM) $(PGM2) $(PGM3) $(PGM4)
X rm -f $(BIN)/$(PGM)
X install -c -s -o root -g daemon -m 4711 $(PGM) $(BIN)/$(PGM)
X install -c -s $(PGM2) $(BIN)/$(PGM2)
X install -c -s $(PGM3) $(BIN)/$(PGM3)
X# install -c -s $(PGM4) $(BIN)/$(PGM4)
X
Xinstallnopriv: $(PGM) $(PGM2) $(PGM3) $(PGM4)
X rm -f $(BIN)/$(PGM)
X install -c -s $(PGM) $(BIN)/$(PGM)
X install -c -s $(PGM2) $(BIN)/$(PGM2)
X install -c -s $(PGM3) $(BIN)/$(PGM3)
X# install -c -s $(PGM4) $(BIN)/$(PGM4)
X
Xmanpage: layers.1
X rm -f $(MANDIR)/$(PGM).$(MS)
X cp layers.1 $(MANDIR)/$(PGM).$(MS)
X chmod 664 $(MANDIR)/$(PGM).$(MS)
X
Xclean:
X rm -f a.out core $(PGM) $(PGM2) $(PGM3) $(PGM4) *.o
X
Xshar: makefile
X shar README layers.1 makefile layers.h layers.c \
X protocol.c layersize.c layertitle.c MacLayers.sit.Hqx MacLayers.doc \
X macbput.c macbput.1 >layers.shar
SHAR_EOF
if test 1674 -ne "`wc -c < 'makefile'`"
then
echo shar: error transmitting "'makefile'" '(should have been 1674 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'protocol.c'" '(25546 characters)'
if test -f 'protocol.c'
then
echo shar: will not over-write existing file "'protocol.c'"
else
sed 's/^X//' << \SHAR_EOF > 'protocol.c'
X/* Copyright (C) 1989 by David W. Trissel
X *
X * Not derived from licensed software.
X *
X * Permission is granted to freely use, copy, modify, and redistribute
X * this software, provided that no attempt is made to gain profit from it,
X * the author is not construed to be liable for any results of using the
X * software, alterations are clearly marked as such, and this notice is
X * not modified.
X *
X */
X
X#include <stdio.h>
X#include <signal.h>
X#include <errno.h>
X#include "layers.h"
X
X /* protocol.c - BSD MacLayers protocol driver */
X
X/* This module handles all interaction with the Macintosh MacLayers
X** program. Services provided are:
X**
X** InitLink() - initialize link to MacLayers
X**
X** TopChannel() - return highest prority channel
X**
X** SendNew() - request new layer channel of MacLayers
X**
X** SendTitle() - change window title to given string (NOT IMPLENTED YET)
X**
X** SendDelete()- tell MacLayers indicated layer has died
X**
X** SendQuit() - order MacLayers to terminate layers mode
X**
X** SendData() - send output to indicated channel's window
X**
X** SendReshape() - send Shape structure to MacLayers
X**
X** ProcessStreamin() - data is ready to be processed from MacLayers
X**
X*/
X
X#define DUMPALL
X#undef DUMPALL
X
X/* C library calls */
Xunsigned alarm(); /* alarm system call */
X
Xstatic int GetData();
Xstatic void Packet();
Xstatic void Parse();
Xstatic void AwaitInput();
Xstatic void asciishape();
Xstatic void fill4();
Xstatic void fill2();
Xstatic void fill1();
Xstatic int parseshape();
Xstatic unsigned get4();
Xstatic unsigned get2();
Xstatic unsigned get1();
X
Xstatic char inbuff[IOSIZE]; /* input buffer from MacLayers */
Xstatic char *inpos; /* current input position in buffer */
Xstatic int insize = 0; /* characters left to process */
Xstatic int Outstream = -1; /* current output stream channel */
Xstatic int Instream = -1; /* current input stream channel */
X
Xstatic struct Shape SNshape; /* SendNew() shape response */
Xstatic int SNresp = 0; /* SendNew() reponse poll flag */
Xstatic int SNchan = 0; /* SendNew() channel return */
X#define SN_WAITING -1000 /* SendNew() waiting response value */
X
X#define ATTRSIZE 15 /* size of window attribute string */
X
X#define FLUSH fflush(stdout)
X
X
X /* Initlink() - initialize link with MacLayers */
X
X/* Returns:
X** 0 - linkup failed
X** 1 - linkup successful, Maclayers now in protocol mode
X*/
X
Xint
XInitlink()
X{
X int Outstream = -1; /* no default stream yet */
X int Instream = -1; /* no default stream yet */
X int num1, num2, num3; /* scanf item result */
X int err; /* error code */
X
X#define WAITTIME 10 /* second wait response time */
X#define INITTIME 2 /* wait time after succesful startup */
X
X /* we must non-buffer input since all input must be immediate */
X setbuf(stdin, NULL); /* non-buffer all input */
X
X /* send intitial request for terminal type and version number */
X DO DEBUG("write: ESC [ c\n");
X if ((err=printf("\033[c")) < 0)
X {
X DO DEBUG(" printf() error code %d\n", err);
X return ( 0 ); /* problem with stdout */
X }
X FLUSH; /* force output buffer */
X
X /* attempt to read "ESC [ ? 8 ; typedigits ; versiondigits c" */
X num1 = num2 = num3 = -1; /* default to unsupplied values */
X (void) alarm(WAITTIME); /* set timeout */
X DO DEBUG(" doing first scanf\n");
X (void) scanf("\033[?%d;%d;%dc", &num1, &num2, &num3);
X (void) alarm(0); /* cancel alarm */
X DO DEBUG("read ESC [ ? %d ; %d; %d c\n", num1, num2, num3);
X if (num1 != 8 || num2 != 10)
X return ( 0 ); /* not correct response or layers term ID */
X
X /* ask terminal if ENC_ENABLE is to be forced */
X DO DEBUG("write: ESC [ F\n");
X (void) printf("\033[F");
X FLUSH; /* force output buffer */
X (void) alarm(WAITTIME); /* set timeout */
X
X /* attempt to read "ESC [ flag F" (flag indicates ENC_ENABLE status) */
X num1 = -1; /* default to invalid response */
X (void) scanf("\033[%dF", &num1);
X (void) alarm(0); /* cancel alarm */
X DO DEBUG("read ESC [ %d F\n", num1);
X if (num1 != 2 && num1 != 0)
X return ( 0 ); /* something's wrong */
X
X /* now startup packet mode in non ENC_ENABLE processing */
X DO DEBUG("write: ESC [ 2 ; 0 v\n");
X (void) printf("\033[2;0v"); /* "ESC [ 2 ; 0 v" */
X FLUSH; /* force output buffer */
X
X /* we are now in packet mode */
X sleep( INITTIME ); /* let Macintosh keep up with us */
X return ( 1 ); /* return successful startup */
X
X} /* Initlink() */
X
X
X /* TopChannel() - return highest prority channel */
X
Xint
XTopChannel()
X{
X return ( Instream );
X
X} /* TopChannel() */
X
X
X /*
X ** WARNING: Most of the following functions may be recursively called
X ** as control commands are processed from the input stream
X */
X
X
X /* ProcessStreamin() - MacLayers has input to process */
X
Xvoid
XProcessStreamin()
X{
X int c; /* input character being processed */
X
X DO DEBUG("ProcessStreamin()\n");
X
X GetData(0); /* read some and don't timeout */
X
X while (insize > 0) /* while more data to process ... */
X Parse(); /* process next chuck of data */
X
X} /* ProcessStreamin() */
X
X
X /* SendNew() - request new layer channel from MacLayers */
X
X/* This command is unique in that it returns a response from MacLayers.
X** To do this we continue processing the input stream until we get
X** our return. (This leads to recursive conditions.) The variables
X** 'SNresp', 'SNshape' and 'SNchan' are set when our reply is received.
X*/
Xint
XSendNew(shape)
Xstruct Shape *shape; /* shape to use for new window */
X{
X int i; /* attribute count variable */
X char astring[ATTRSIZE]; /* copy of attribute string */
X
X DO DEBUG("SendNew() new layer requested: '~%cA'\n", '1'+ATTRSIZE);
X
X /* check for a recursive call */
X if (SNresp == SN_WAITING)
X { DO DEBUG("return 0 - recursive call\n");
X return ( 0 ); /* return failure */
X }
X
X putchar(ESCAPE); /* send start of control packet char */
X putchar('1' + ATTRSIZE); /* send command size */
X putchar('A'); /* send command */
X asciishape(shape, astring); /* convert shape to string */
X for (i=0; i < ATTRSIZE; i++)
X putchar(astring[i]); /* send next attribute digit */
X FLUSH;
X
X /* now stay here and process the input stream until we see our response */
X/**** THIS SHOULD BE ENHANCED TO TIMEOUT WITH GetData() AND REISSUE REQUEST */
X SNresp = SN_WAITING; /* indicate we are waiting a response */
X while (SNresp == SN_WAITING)
X { DO DEBUG(" while (SNresp %d == %d)\n", SNresp, SN_WAITING);
X AwaitInput(); /* wait till input from MacLayers arrives */
X ProcessStreamin(); /* process available input */
X }
X
X if (SNresp == -1) /* if Maclayers rejected request */
X SNchan = 0; /* return failure channel of zero */
X else
X *shape = SNshape; /* else update shape structure */
X
X DO DEBUG("SendNew() returning channel %d\n", SNchan);
X
X return ( SNchan ); /* return the indicated channel */
X
X} /* SendNew() */
X
X
X /* SendReshape() - send to shape to MacLayers */
X
Xvoid
XSendReshape(chan, shape)
Xint chan; /* channel shape belongs to */
Xstruct Shape *shape; /* shape to use for new window */
X{
X int i; /* attribute count variable */
X char astring[ATTRSIZE]; /* copy of attribute string */
X
X DO DEBUG("SendReshape() reshape: '~%cA'\n", '2'+ATTRSIZE);
X
X if (chan <= 0 || chan > MAXPCHAN)
X { DO DEBUG("BAD CHANNEL!!!\n");
X return; /* ignore request */
X }
X
X putchar(ESCAPE); /* send start of control packet char */
X putchar('2' + ATTRSIZE); /* send command size */
X putchar('R'); /* send command */
X putchar(chan + '0'); /* send channel */
X asciishape(shape, astring); /* convert shape to string */
X DO DEBUG("shape: %.*s\n", ATTRSIZE, astring);
X for (i=0; i < ATTRSIZE; i++)
X putchar(astring[i]); /* send next attribute digit */
X FLUSH;
X
X} /* SendReshape() */
X
X
X /* SendTitle() - set layer's window title */
X
Xvoid
XSendTitle(chan, buff, cnt)
Xint chan; /* layer window ID */
Xchar *buff; /* new title string */
Xint cnt; /* count of title length */
X{
X int i; /* work variable */
X
X DO DEBUG("SendTitle(chan%d, len %d, '%.*s')\n", chan, cnt, cnt, buff);
X
X if (chan <= 0 || chan > MAXPCHAN)
X { DO DEBUG("BAD CHANNEL!!!\n");
X return; /* ignore request */
X }
X
X if (cnt < 0)
X { DO DEBUG("BAD COUNT!!!\n");
X return; /* ignore request */
X }
X
X /* for now chop title size to 29 chars since that's MacLayer's limit */
X if (cnt > 29)
X cnt = 29; /* due to packet size limit */
X
X /* we must guarantee that the size will not appear to be another ESCAPE */
X if ('2' + cnt == ESCAPE)
X cnt--; /* truncate to avoid ESCAPE ESCAPE */
X
X putchar(ESCAPE); /* send start of control packet char */
X putchar('2' + cnt); /* send size of packet */
X putchar('T'); /* send command */
X putchar(chan + '0'); /* send channel ID */
X for (i=0; i<cnt; i++)
X putchar(buff[i]); /* send out title */
X FLUSH;
X
X} /* SendTitle() */
X
X
X /* SendDelete() - tell Maclayers layer died */
X
Xvoid
XSendDelete(chan)
Xint chan; /* dead channel ID */
X{
X DO DEBUG("SendDelete(%d) '~2D%d'\n", chan, chan);
X
X if (chan <= 0 || chan > MAXPCHAN) /* check channel ID */
X { DO DEBUG("BAD CHANNEL!!!\n");
X return; /* ignore request */
X }
X
X putchar(ESCAPE); /* send control packet start char */
X putchar('2'); /* send command size */
X putchar('D'); /* send command character */
X putchar(chan + '0'); /* channel ID in ascii */
X FLUSH;
X
X} /* SendDelete() */
X
X
X /* SendQuit() - order MacLayers to end layers mode */
X
Xvoid
XSendQuit(chan)
Xint chan; /* dead channel ID */
X{
X DO DEBUG("SendQuit() '~1E'\n");
X
X putchar(ESCAPE); /* send control packet start char */
X putchar('1'); /* send command size */
X putchar('E'); /* send command */
X FLUSH;
X
X} /* SendQuit() */
X
X
X /* SendData() - send output to layer's window */
X
Xvoid
XSendData(chan, buff, cnt)
Xint chan; /* layer window ID */
Xunsigned char *buff; /* new title string */
Xint cnt; /* count of title length */
X{
X unsigned c; /* output character being sent */
X
X DO
X { int dcnt;
X
X DEBUG("SendData(chan %d, len %d, '", chan, cnt, cnt, buff);
X for (dcnt=0; dcnt<cnt; dcnt++)
X DEBUG("%c", buff[dcnt]); /* dump each char so null doesn't stop */
X DEBUG("')\n");
X }
X
X if (chan <= 0 || chan > MAXPCHAN)
X { DO DEBUG("BAD CHANNEL!!!\n");
X return; /* ignore request */
X }
X
X /* if new output channel stream then prefix redirect command */
X if (chan != Outstream)
X { DO DEBUG("Redirecting output to %d '~2O%d'\n", chan, chan);
X putchar(ESCAPE); /* start of command sequence */
X putchar('2'); /* send command size */
X putchar('O'); /* send command */
X putchar(chan + '0'); /* put out channel in ASCII */
X Outstream = chan; /* new output stream set */
X }
X
X /* transmit the buffer converting the ESCAPE sequence to double ESCAPE */
X while (cnt--)
X { c = *buff++; /* get next output character */
X#ifdef DUMPALL
X DO DEBUG("outchar %c 0x%x\n", c, c);
X#endif
X if (c == ESCAPE || c == (ESCAPE + 0x80))
X { putchar(c); /* put it out twice */
X#ifdef DUMPALL
X DO DEBUG(" Doubled Escape!\n");
X#endif
X }
X putchar(c); /* write character out */
X }
X
X FLUSH; /* force out queued output characters */
X
X} /* SendData() */
X
X
X /* Parse() - process next chunk of input stream */
X
Xstatic void
XParse()
X{
X#define ST_NULL 0 /* not primed for next state yet */
X#define ST_STREAM 1 /* processing default stream input */
X#define ST_PKT 2 /* processing packet data */
X
X int c; /* input character being processed */
X
X static int state = ST_NULL; /* current input state */
X static int psize = 0; /* packet size */
X static int rempsize = 0; /* remembered packet size */
X static char pdata[MAXSTR]; /* area for packet data */
X static char *ppos; /* packet read insert position */
X static int escapemode = 0; /* processing escape character */
X static int escapechar; /* escape character being processed */
X static pchan = -1; /* packet input stream channel */
X
X while (insize-- > 0) /* while more data */
X { c = *inpos++; /* get next character */
X switch (state) /* process according to state */
X { case ST_NULL: /* prepare for new packet */
X DO DEBUG("ST_NULL\n");
X psize = 0; /* clear packet size */
X ppos = pdata; /* start fill at data position */
X pchan = Instream; /* packet channel is current input stream */
X state = ST_STREAM; /* default is stream processing */
X
X case ST_STREAM:
X /* stream keyboard input for layer */
X /* check for escape char with possible high bit on */
X#ifdef DUMPALL
X DO DEBUG("ST_STREAM %x/%x esc %d insz %d\n",
X c, c & 0x7f, escapemode, insize);
X#endif
X if (c == ESCAPE || c == (ESCAPE | 0x80))
X { if (escapemode && c == escapechar) /* previous was ESCAPE */
X /* this is really a single ESCAPE character */
X escapemode = 0; /* back out of ESCAPE mode */
X else
X /* what do we do with back to back esc esc+0x80 ? */
X { /* flag in escape mode */
X escapemode++;
X escapechar = c; /* remember character used for escape */
X continue; /* and continue scan */
X }
X }
X else
X if (escapemode)
X { /* this is the start of a control packet */
X if (psize) /* if we have previous data packet */
X Packet(pchan, psize, pdata); /* finish up previous pkt */
X /* process packet size */
X psize = (c & 0x7f) - '0'; /* save size byte */
X if (psize <= 0 || psize > MAXSTR)
X { /* bad size */
X DO DEBUG("Bad pkt size %d\n", psize);
X break; /* trash this packet */
X }
X rempsize = psize; /* remember this size for later */
X#if 0
X ptimo = rtimo; /* start receive timeout */
X#endif
X escapemode = 0; /* escape mode now off */
X ppos = pdata; /* initialize data store pointer */
X state = ST_PKT; /* expect packet data next */
X continue; /* continue scan */
X }
X
X /* process standard data output character for current stream */
X
X *ppos++ = c; /* save next data character */
X
X if (++psize >= MAXSTR) /* if packet full ... */
X { Packet(pchan, psize, pdata); /* process this packet */
X break; /* end packet processing */
X }
X continue; /* continue scan */
X
X case ST_PKT:
X /* process next paket data byte */
X *ppos++ = c & 0x7f; /* store next data byte */
X#ifdef DUMPALL
X DO DEBUG("ST_PKT: %x sz %d\n", c & 0x7f, psize);
X#endif
X if (--psize != 0)
X continue;
X#if 0
X if (crc((unsigned char *) &rpkt, rpkt.pkt.HEADER_DSIZE+2))
X STATS(Scrcerr); /* communications error */
X else
X#endif
X Packet(0, rempsize, pdata); /* process it */
X
X } /* end build packet switch */
X
X#if 0
X ptimo = 0; /* no more receive timeout */
X#endif
X state = ST_NULL; /* no more receive packet in progress */
X
X } /* end while (insize) */
X
X if (state == ST_STREAM && psize ) /* if we have some data ... */
X { Packet(Instream, psize, pdata); /* process this data */
X#if 0
X ptimo = 0; /* no more receive timeout */
X#endif
X state = ST_NULL; /* no more receive packet in progress */
X }
X
X} /* Parse() */
X
X
X /* Packet() - prcess next input data string or control packet */
Xstatic void
XPacket(chan, size, buff)
Xint chan; /* channel (0 if control packet) */
Xint size; /* amount of data */
Xchar *buff; /* pointer to packet data */
X{
X static struct Shape shape; /* Shape structure */
X
X DO DEBUG("Packet(chan %d, size %d, '%.*s')\n", chan, size, size, buff);
X
X /* verify channel */
X if (chan < 0 || chan > MAXPCHAN)
X { DO DEBUG("BAD CHANNEL!!\n");
X return; /* ignore bad channel */
X }
X
X /* if data packet (chan>0) feed data to server */
X if (chan > 0)
X { ReceiveData(chan, buff, size);
X return; /* we are through */
X }
X
X /* control packet (channel 0) */
X chan = buff[1] - '0'; /* assume channel specified */
X if (chan < 0 || chan > MAXPCHAN) /* if invalid ... */
X chan = 0; /* set to zero */
X
X switch (buff[0])
X { case 'I': /* redirect stream */
X DO DEBUG("CMD 'I' redirect stream to %c\n", buff[1]);
X if (size != 2) /* verify size */
X break; /* break if bad */
X if (chan == 0) /* verify channel */
X break; /* break if bad */
X Instream = chan; /* new instream channel */
X return; /* we are through */
X
X case 'A': /* returned A_NEWLAYER packet */
X DO DEBUG("CMD 'A' A_NEWLAYER response %c newchan %c SNresp %d\n",
X buff[2], buff[1], SNresp);
X if (size != 3 + ATTRSIZE)
X break; /* break if bad */
X
X /* if SendNew() not waiting for a response this is invalid */
X if (SNresp != SN_WAITING)
X break; /* break if bad */
X
X if (buff[2] == '1') /* if response is "failed" ... */
X SNresp = -1; /* show -1 response */
X else
X if (buff[2] == '0') /* if response is "success" ... */
X { if (chan == 0) /* if invalid channel */
X break; /* break if bad */
X /* build shape structure for SendNew() */
X if (parseshape(&SNshape, &buff[3]) == -1)
X break; /* if invalid data then bad packet */
X SNresp = 0; /* show good response */
X SNchan = chan; /* indicate channel returned */
X }
X else
X break; /* break if bad */
X
X DO DEBUG("SNresp = %d, SNchan = %d\n", SNresp, SNchan);
X return; /* we are through */
X
X case 'N': /* new layer creation */
X DO DEBUG("CMD 'N' new layer creation newchan %c\n", buff[1]);
X if (size != 2 + ATTRSIZE) /* verify size */
X break; /* break if bad */
X if (chan == 0) /* verify channel */
X break; /* break if bad */
X /* build shape structure */
X if (parseshape(&shape, &buff[2]) == -1)
X break; /* if invalid data then bad packet */
X ReceiveNew(chan, &shape); /* pass to server */
X return; /* packet is done */
X
X case 'D': /* deleted layer */
X DO DEBUG("CMD 'D' deleted layer %c\n", buff[1]);
X if (size != 2) /* verify size */
X break; /* break if bad */
X if (chan == 0) /* verify channel */
X break; /* break if bad */
X ReceiveDelete(chan); /* pass on to server */
X return; /* packet is done */
X
X case 'E': /* exit - awaiting shutdown */
X DO DEBUG("CMD 'E' exit MacLayers awaiting shutdown msg\n");
X if (size != 1) /* verify size */
X break; /* break if bad */
X ReceiveQuit(); /* pass to server */
X /* NOT REACHED*/
X return; /* ?? should never reach here */
X
X case 'R': /* reshaped */
X DO DEBUG("CMD 'R' reshape chan %c\n", buff[1]);
X
X if (size != 2 + ATTRSIZE) /* verify size */
X break; /* break if bad */
X
X if (chan == 0) /* verify channel */
X break; /* break if bad */
X
X /* build shape structure */
X if (parseshape(&shape, &buff[2]) == -1)
X break; /* if invalid data then bad packet */
X
X ReceiveReshape(chan, &shape); /* tell server about shape */
X return; /* packet processed */
X
X case 'S': /* signal */
X DO DEBUG("CMD 'S' SIGNAL chan %c sig %c\n", buff[1], buff[2]);
X if (size != 3) /* verify size */
X break; /* break if bad */
X if (chan == 0)
X break; /* break if bad */
X
X if (buff[2] == '0') /* if SIGINT */
X size = SIGINT; /* yes */
X else
X if (buff[2] == '1') /* if SIGHUP */
X size = SIGHUP; /* yes */
X else
X break; /* invalid signal */
X
X ReceiveSignal(chan, size); /* pass to server */
X return; /* packet processed */
X
X default:
X DO DEBUG("ILLEGAL CONTROL PACKET!!!\n");
X return; /* ignore bad packet */
X
X } /* end command packet switch */
X
X /* switch falls out if bad size or channel for given command */
X DO DEBUG("Invalid size or channel!!!\n"); /* dump error */
X return; /* ignore packet */
X
X} /* Packet() */
X
X
X /* GetData() - read next input from MacLayers stream */
X
X/* An input timout parameter can indicate that we return if nothing
X** is read within a certain amount of seconds. The return code is:
X**
X** 0 - timeout occured and no data was read
X**
X** 1 - no timeout occured, data read
X*/
Xstatic int
XGetData(timeout)
Xint timeout; /* timeout in seconds (or zero) */
X{
X int result; /* return from read() */
X
X DO DEBUG("GetData(timout %d)\n", timeout);
X
X /* if buffer still has data simply return (SHOULD NOT OCCUR?) */
X if (insize > 0)
X return ( 1 ); /* act as through data read */
X inpos = inbuff; /* next get will start at beginning */
X insize = 0; /* default insize back to zero */
X
X /* set timeout if we are to do so */
X if (timeout)
X (void) alarm(timeout); /* set timeout in seconds */
X
X /* do the read from stdin */
X result = read(0, inbuff, IOSIZE);
X
X /* if alarm was set cancel it now */
X if (timeout)
X (void) alarm(0); /* cancel alarm */
X
X /* check for timeout or error */
X /* EWOULDBLOCK for no data avail -(but we should not see this) */
X /* EINTR if signal stopped the read -(rare but could happen) */
X if (result <= 0)
X return ( 0 ); /* return nothing read */
X
X /* return with fresh buffer data */
X insize = result;
X DO DEBUG("read %d bytes\n", insize);
X return ( 1 ); /* return OK code */
X
X} /* GetData() */
X
X
X /* AwaitInput() - wait for more input from MacLayers */
X
Xstatic void
XAwaitInput()
X{
X int r; /* read descriptor bits */
X
X DO DEBUG("AwaitInput()\n");
X
X do
X { r = 1<<0; /* wait for read from input device */
X if (select(32, &r, NULL, NULL, NULL) == -1) /* if problem waiting ... */
X { if (errno != EINTR) /* if not simply signal taken ... */
X { /* SHOULD NOT OCCUR - shutdown layers */
X DO DEBUG("AwaitInput: select error %d\n", errno);
X printf("layers: AwaitInput: bad select %d\n", errno);
X FQuit(); /* shutdown layers */
X /* NOT REACHED */
X }
X }
X } while ((r & 1<<0) == 0);
X
X} /* AwaitInput() */
X
X /* asciishape() - convert Shape structure to ASCII */
Xstatic void
Xasciishape(shape, loc)
Xstruct Shape *shape; /* Shape structure for channel */
Xchar *loc; /* location to start filling result */
X{
X char *origloc; /* (for debuggin) */
X
X origloc = loc; /* remember start of string */
X fill4(&loc, shape->worigh); /* origin h */
X fill4(&loc, shape->worigv); /* origin v */
X fill2(&loc, shape->wlines); /* lines high */
X fill2(&loc, shape->wchars); /* chars wide */
X fill1(&loc, shape->wfont); /* font size */
X fill2(&loc, shape->wattr); /* attributes */
X
X DO DEBUG("asciishape(): %.*s\n", ATTRSIZE, origloc);
X
X} /* asciishape() */
X
X
X /* fill4() - convert parameter to ASCII */
X
Xstatic void
Xfill4(loc, valu)
Xchar **loc; /* pointer to fill area pointer */
Xunsigned valu; /* value to use */
X{
X fill2(loc, valu>>8); /* fill high half word */
X fill2(loc, valu & 0xff); /* fill low half word */
X
X} /* fill4() */
X
X
X /* fill2() - convert parameter to ASCII */
X
Xstatic void
Xfill2(loc, valu)
Xchar **loc; /* pointer to fill area pointer */
Xunsigned valu; /* value to use */
X{
X fill1(loc, valu>>4); /* fill high byte */
X fill1(loc, valu & 0xf); /* fill low byte */
X
X} /* fill2() */
X
X
X /* fill1() - convert parameter to ASCII */
X
Xstatic void
Xfill1(loc, valu)
Xchar **loc; /* pointer to fill area pointer */
Xunsigned valu; /* value to use */
X{
X *(*loc)++ = "0123456789ABCDEF"[valu & 0xf]; /* return hex value */
X
X} /* fill1() */
X
X
X /* parseshape() - convert ASCII image to Shape structure */
X
Xstatic int Badconvert; /* indicates bad conversion */
X
Xstatic int
Xparseshape(shape, loc)
Xstruct Shape *shape; /* Shape structure for channel */
Xchar *loc; /* location to start parsing */
X{
X Badconvert = 0; /* clear bad characters indicator */
X shape->worigh = get4(&loc); /* origin h */
X shape->worigv = get4(&loc); /* origin v */
X shape->wlines = get2(&loc); /* lines high */
X shape->wchars = get2(&loc); /* chars wide */
X shape->wfont = get1(&loc); /* font size */
X shape->wattr = get2(&loc); /* attributes */
X
X DO DEBUG("ParseShape(): origv %d, origh %d, lines %d, chars %d\n",
X shape->worigv, shape->worigh, shape->wlines, shape->wchars);
X DO DEBUG(" font %d, attr 0x%x, badconv %d\n",
X shape->wfont, shape->wattr, Badconvert);
X
X return ( Badconvert ? -1 : 0 ); /* return conversion code */
X
X} /* parseshape() */
X
X
X /* get4() - convert ASCII to parameter */
X
Xstatic unsigned
Xget4(loc)
Xchar **loc; /* pointer to fill area pointer */
X{
X unsigned hi; /* high portion */
X unsigned low; /* low portion */
X
X hi = get2(loc); /* get high byte */
X low = get2(loc); /* get low byte */
X
X return ( (hi<<8) + low ); /* return word value */
X
X} /* get4() */
X
X
X /* get2() - convert ASCII to parameter */
X
Xstatic unsigned
Xget2(loc)
Xchar **loc; /* pointer to fill area pointer */
X{
X unsigned hi; /* high portion */
X unsigned low; /* low portion */
X
X hi = get1(loc); /* get high half */
X low = get1(loc); /* get low half */
X
X return ( (hi<<4) + low ); /* return byte value */
X
X} /* get2() */
X
X
X /* get1() - convert ASCII to parameter */
X
X/* This function sets 'Badconvert' if an invalid character is detected */
X
Xstatic unsigned
Xget1(loc)
Xchar **loc; /* pointer to fill area pointer */
X{
X int c; /* character to convert */
X
X c = *(*loc)++; /* fetch character */
X
X if (c >= '0' && c <= '9')
X /* zero through nine */
X return ( c - '0' ); /* return it's binary value */
X
X if (c >= 'a' && c <= 'f')
X /* lower case hex */
X return ( c - 'a' + 10); /* return it's binary value */
X
X if (c >= 'A' && c <= 'F')
X /* upper case hex */
X return ( c - 'A' + 10); /* return it's binary value */
X
X /* invalid digit! */
X Badconvert++; /* set bad character flag */
X return ( 0 ); /* return a zero */
X
X} /* get1() */
SHAR_EOF
if test 25546 -ne "`wc -c < 'protocol.c'`"
then
echo shar: error transmitting "'protocol.c'" '(should have been 25546 characters)'
fi
fi # end of overwriting check
# End of shell archive
exit 0
--- end of part 2 ---