Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!usc!elroy.jpl.nasa.gov!zardoz.cpd.com!dhw68k!macintosh From: werner@rascal.ics.utexas.edu (Werner Uhrig) Newsgroups: comp.sources.mac Subject: MacLayers 1.00 (part 2 of 6) Message-ID: <1990Jun1.190100.8893@dhw68k.cts.com> Date: 1 Jun 90 19:00:09 GMT References: <1990Jun1.070105.1489@dhw68k.cts.com> Reply-To: layers@rascal.ics.utexas.edu Organization: U. Texas CS Dept., Austin, Texas Lines: 1814 Approved: bytebug@dhw68k.cts.com (Roger L. Long) [MacLayers 1.00 - part 2 of 6] --- #! /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 X#include X#include 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 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 X#include X#include X#ifdef SYSV X#include X#else X#include X#endif X#include X#include 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 X#include X#include 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 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 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 ---