home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.sources.x
- From: rr2b+@andrew.cmu.edu (Robert Andrew Ryan)
- Subject: v21i012: sxpc - Silly X Protocol Compressor, Part01/01
- Message-ID: <1993Oct10.155202.14791@sparky.sterling.com>
- X-Md4-Signature: 28690f5dd607092e7117cea564a05db8
- Sender: chris@sparky.sterling.com (Chris Olson)
- Organization: Sterling Software
- Date: Sun, 10 Oct 1993 15:52:02 GMT
- Approved: chris@sterling.com
-
- Submitted-by: rr2b+@andrew.cmu.edu (Robert Andrew Ryan)
- Posting-number: Volume 21, Issue 12
- Archive-name: sxpc/part01
- Environment: X11, ANSI
-
- [ This compiles, I didn't run any other tests on it... ]
- [ -- chris ]
-
- The Silly X protocol compressor gateway. (A Really Gross Hack)
-
- This program provides upto 75% compression of the X protocol stream.
- It is intended to be used to improve the performance of X applications
- over a slow internet connection. (e.g. slip,cslip. or term) It assumes
- a Unix operating system at both ends of the link.
-
- WARNING WARNING DANGER DANGER
- If you use this program use xauth to provide SECURITY, since
- host-based security will be BYPASSED.
-
- #!/bin/sh
- echo x - Imakefile
- sed -e 's/^X//' > Imakefile << '!Funky!Stuff!'
- X#ifndef XCOMM
- X#define XCOMM #
- X#endif
- XXCOMM The Silly X Protocol Compressor
- XXCOMM robr@cmu.edu
- XDEPLIBS=
- XSimpleProgramTarget(sxpc)
- !Funky!Stuff!
- echo x - Makefile
- sed -e 's/^X//' > Makefile << '!Funky!Stuff!'
- X# Makefile for the Silly X Protocol Compressor
- X# Rob Ryan (robr@cmu.edu)
- X# this assumes that cc can handle simple prototypes.
- X# if your compiler can't edit the sxpc.c to put
- X# all the function definitions in the old style.
- X# For generic BSD systems (IBM RT, Decstation)
- Xsxpc:
- X $(CC) -o sxpc sxpc.c
- X
- X# for RS/6000
- X#sxpc:
- X# cc -D_BSD -o sxpc sxpc.c -lbsd
- X
- X# for HP
- X#sxpc:
- X# c89 -D_INCLUDE_POSIX_SOURCE -D_INCLUDE_ANSI_SOURCE
- -D_INCLUDE_HPUX_SOURCE -D_INCLUDE_AES_SOURCE -DPOSIX -o sxpc sxpc.c
- !Funky!Stuff!
- echo x - README
- sed -e 's/^X//' > README << '!Funky!Stuff!'
- XThe Silly X protocol compressor gateway. (A Really Gross Hack)
- X
- XThis program provides upto 75% compression of the X protocol stream.
- XIt is intended to be used to improve the performance of X applications
- Xover a slow internet connection. (e.g. slip,cslip. or term) It assumes
- Xa Unix operating system at both ends of the link.
- X
- X WARNING WARNING DANGER DANGER
- X If you use this program use xauth to provide SECURITY, since
- X host-based security will be BYPASSED.
- X
- XCompilation:
- Xxmkmf
- Xmake
- XIf this doesn't work you may have to compile it manually, if your compiler
- Xclaims to be ANSI, but you don't have stdlib.h use -DNOSTDLIBPLEASE, if
- Xyour system is POSIX try -D_POSIX_SOURCE. If your system is vanilla BSD
- Xcc -o sxpc sxpc.c should just work.
- X
- XUsage:
- X
- XOn X server host:
- Xsxpc local $DISPLAY
- X
- XOn X clients' host:
- XFor csh based shells:
- Xsetenv DISPLAY `sxpc remote $DISPLAY `
- X
- XFor sh based shells:
- XDISPLAY=`sxpc remote $DISPLAY`
- Xexport DISPLAY
- X(where $DISPLAY is the display setting you would normally use
- Xto connect to the X server from the clients' host.)
- X
- X-Rob Ryan
- Xrobr@cmu.edu
- X/*
- XCopyright Rob Ryan and Carnegie Mellon University 1993 - All Rights Reserved
- X
- XPermission to use, copy, modify, and distribute this software and its
- Xdocumentation for any purpose is hereby granted without fee, provided
- Xthat the above copyright notice appear in all copies and that both that
- Xcopyright notice, this permission notice, and the following disclaimer
- Xappear in supporting documentation, and that the name Carnegie Mellon
- XUniversity, not be used in advertising or publicity pertaining to
- Xdistribution of the software without specific, written prior permission.
- X
- XCARNEGIE MELLON UNIVERSITY AND ROB RYAN
- XDISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- XINCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- XAND FITNESS FOR ANY PARTICULAR PURPOSE.
- XIN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY, OR
- XROB RYAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- XCONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
- XRESULTING FROM LOSS OF USE, DATA, OR PROFITS,
- XWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE, OR
- XOTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- XCONNECTION WITH THE USE OR PERFORMANCE OF THIS
- XSOFTWARE.
- X*/
- !Funky!Stuff!
- echo x - patchlevel.h
- sed -e 's/^X//' > patchlevel.h << '!Funky!Stuff!'
- X#define VersionString "Version 0.9"
- !Funky!Stuff!
- echo x - sxpc.1
- sed -e 's/^X//' > sxpc.1 << '!Funky!Stuff!'
- X.TH sxpc 1 "09sep1993" "X" "X"
- X.SH NAME
- XThe Silly X protocol compressor gateway. (A Really Gross Hack)
- X.SH SYNOPSIS
- XThis program provides upto 75% compression of the X protocol stream. It
- is intended to be used to improve the performance of X applications over
- a slow internet connection. (e.g. slip, cslip, or term) It assumes a
- Unix operating system at both ends of the link.
- X
- X
- XWARNING WARNING DANGER DANGER
- X
- XIf you use this program, use xauth to provide SECURITY, since
- host-based security will be BYPASSED. (If somebody knows you are
- running sxpc they will be able to connect to your server and watch what
- you type, what shows up on your screen, or type for you... A BAD THING
- :-()
- X
- X.SH DESCRIPTION
- XOn the X clients' host:
- X.PP
- XFor csh based shells:
- X.PP
- Xsetenv DISPLAY `sxpc remote $DISPLAY `
- X
- XFor sh based shells:
- X.PP
- XDISPLAY=`sxpc remote $DISPLAY`
- X.PP
- Xexport DISPLAY
- X.PP
- X(where $DISPLAY is the display setting you would normally use to
- connect to the X server from the clients' host.)
- X
- XOn the X server host:
- X sxpc local $DISPLAY
- X
- X.SH ENVIRONMENT VARIABLES
- X.PP
- XXCLIENTGATEPORT
- X.PP
- XSets the base port on which clients will connect to the X server.
- This will be added to the display number to get the final port number.
- The default is 6008 so that by default the DISPLAY setting to connect to
- sxpc will be localhost:DisplayNumber+8:0.0
- X
- XXCOMPGATEPORT
- X.PP
- XSets the base port on which the sxpc running on the X server host will
- listen for connections. This will be added to the display number to get
- the final port number. The default is 4000 so that the sxpc on the X
- server host will listen on port 4000 (if it is directed to display on
- display 0.)
- X
- X.SH AUTHOR
- XRob Ryan (robr@cmu.edu)
- !Funky!Stuff!
- echo x - sxpc.c
- sed -e 's/^X//' > sxpc.c << '!Funky!Stuff!'
- X/*
- XCopyright Rob Ryan and Carnegie Mellon University 1993 - All Rights Reserved
- X
- XPermission to use, copy, modify, and distribute this software and its
- Xdocumentation for any purpose is hereby granted without fee, provided
- Xthat the above copyright notice appear in all copies and that both that
- Xcopyright notice, this permission notice, and the following disclaimer
- Xappear in supporting documentation, and that the name Carnegie Mellon
- XUniversity, not be used in advertising or publicity pertaining to
- Xdistribution of the software without specific, written prior permission.
- X
- XCARNEGIE MELLON UNIVERSITY AND ROB RYAN
- XDISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- XINCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- XAND FITNESS FOR ANY PARTICULAR PURPOSE.
- XIN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY, OR
- XROB RYAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- XCONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
- XRESULTING FROM LOSS OF USE, DATA, OR PROFITS,
- XWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE, OR
- XOTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- XCONNECTION WITH THE USE OR PERFORMANCE OF THIS
- XSOFTWARE.
- X*/
- X
- X/* The Silly X protocol compressor gateway. (A Really Gross Hack)
- X
- X TODO:
- XThis program compresses the X protocol by replacing repeated occurrences
- Xof 4 byte values with a one or two byte index into the most recent values
- Xsent. The lookup for recent values is a simple linear search, this limits
- Xthe amount of history which can be kept without making computation the
- Xdominating time factor. A possible solution for this is to switch to a
- Xcircular history buffer, with a hash table of the longs which contains
- Xthe index of each long in the history list (This proposal also calls
- Xfor bringing old values to the most recent position without copying all
- Xthe values which WERE more recent than the old value down. Thus a gap
- Xwill be left, making values older than that age more quickly. Thus it
- Xwill require twice as much history space to ensure the same number of
- Xhistoric values are available.)
- X
- X Find and use a real compression algorithm.
- X
- X Allow for different blocking factors. (Otherwise there is a pause before
- X a redraw while most or all of the data is sent over.) ~250 is probably
- X good for cslip.
- X
- X -Rob Ryan (robr@cmu.edu)
- X Sept, 1993.
- X */
- X
- X/* use -DMAXPACKET=1022 or whatever if you want a larger or smaller
- X packet size over the slow link. Note that a 2 byte header will be sent in
- X addition to upto MAXPACKET bytes of data. */
- X#ifndef MAXPACKET
- X#define MAXPACKET 254
- X#endif
- X
- X#include "patchlevel.h"
- X
- X#include <X11/Xos.h>
- X
- X#if defined(__STDC__) && !defined(ibm032) && !defined(NOSTDLIBPLEASE)
- X#include <stdlib.h>
- X#else
- X#ifdef _POSIX_SOURCE
- X#include <unistd.h>
- X#else
- Xextern char *getenv();
- X#endif
- X#endif
- X
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <sys/socket.h>
- X#include <netinet/in.h>
- X#include <sys/file.h>
- X#include <netdb.h>
- X#if defined(_IBMR2) || defined(AIXV3)
- X#include <sys/select.h>
- X#endif
- X#include <errno.h>
- X#include <string.h>
- X#include <signal.h>
- X#include <sys/resource.h>
- X#include <sys/wait.h>
- X#include <ctype.h>
- X
- Xint compression=0; /* -1 uncompress, 0 no compression, 1 compress */
- Xstruct sockaddr_in servaddr;
- Xextern int errno;
- X
- X
- X#if defined(__hpux) || defined(hpux)
- Xint getdtablesize() {
- X return 32; /* should do the right thing here, but I don't have the
- POSIX book handy */
- X}
- X#endif
- X
- X
- Xint client()
- X{
- X int sock;
- X unsigned char *iaddr=(unsigned char *)&servaddr.sin_addr;
- X if ((sock = socket(AF_INET, SOCK_STREAM, PF_UNSPEC)) == -1) {
- X perror("socket");
- X return -1;
- X }
- X
- X if (connect(sock, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1) {
- X fprintf(stderr, "port:%d\n",ntohs(servaddr.sin_port));
- X fprintf(stderr, "addr:%d.%d.%d.%d\n", iaddr[0], iaddr[1], iaddr[2],
- iaddr[3]);
- X perror("connect");
- X return -1;
- X }
- X
- X return sock;
- X}
- X
- X#define MAXTRANBUF 65536
- X
- Xint reallywrite(fd, buf, len)
- Xint fd;
- Xunsigned char *buf;
- Xint len;
- X{
- X int r;
- X while(len>0) {
- X r=write(fd, buf, len);
- X if(r<0) {
- X perror("write");
- X exit(-1);
- X }
- X buf+=r;
- X len-=r;
- X }
- X}
- X
- Xtypedef unsigned long thet;
- X#define NTOH(x) ntohl(x)
- X#define HTON(x) htonl(x)
- X#define WRITE(x) OUTBYTE((x)&0xff);OUTBYTE((x)>>8);OUTBYTE((x)>>16);OUTBYTE((x)>>24);
- X#define READ(w,x,y,z) (((thet)w)|(((thet)x)<<8)|(((thet)y)<<16)|(((thet)z)<<24))
- X
- X#define HISTORY 2048
- X#define SCOUNTMAX 128
- X#define COUNTBASE 192
- Xstatic thet chistory[HISTORY];
- Xstatic int cnext=0;
- Xstatic thet uhistory[HISTORY];
- Xstatic int unext=0;
- X
- X#define OUTBYTE(blah) do { *out++=((blah)&0xff); csize--, size++;} while (0)
- Xint scompress(cbuf, csize, buf, len)
- Xunsigned char *cbuf;
- Xint csize;
- Xunsigned char **buf;
- Xint *len;
- X{
- X thet *p=(thet *)*buf;
- X unsigned char *out=cbuf;
- X unsigned char *prev=NULL;
- X int i;
- X int scan=0;
- X int size=0;
- X if(*len&1) {
- X fprintf(stderr, "WARNING WARNING WARNING, odd packet size...\n");
- X exit(-1);
- X }
- X#ifdef LOGDATA
- X fprintf(stderr,"sending: ");
- X for(i=0;i<len;i++) fprintf(stderr, "%x ",*buf[i]);
- X fprintf(stderr,"\n");
- X#endif
- X
- X while(*len>0 && csize>0) {
- X thet sh=HTON(*p);
- X for(scan=cnext-1;scan>=0;scan--) {
- X if(sh==chistory[scan]) {
- X int scanx=cnext-1-scan;
- X prev=NULL;
- X if(scanx>=SCOUNTMAX) {
- X if(csize<2) return size;
- X OUTBYTE(((scanx>>8)&0x7)+SCOUNTMAX);
- X OUTBYTE(scanx&0xff);
- X } else OUTBYTE(scanx);
- X for(i=scan+1;i<cnext;i++) {
- X chistory[i-1]=chistory[i];
- X }
- X chistory[cnext-1]=sh;
- X p++;
- X *len-=sizeof(thet);
- X *buf+=sizeof(thet);
- X break;
- X }
- X }
- X if(scan>=0) continue;
- X if(csize<sizeof(thet)) return size;
- X if(prev && *prev<0xff) {
- X (*prev)++;
- X } else {
- X if(csize<sizeof(thet)+1) return size;
- X prev=out;
- X OUTBYTE(COUNTBASE);
- X }
- X WRITE(sh);
- X p++;
- X *len-=sizeof(thet);
- X *buf+=sizeof(thet);
- X if(cnext<HISTORY) {
- X chistory[cnext]=sh;
- X cnext++;
- X
- X } else {
- X bcopy(&chistory[1], &chistory[0], sizeof(chistory)-sizeof(chistory[0]));
- X chistory[cnext-1]=sh;
- X }
- X }
- X return size;
- X}
- X
- Xstatic unsigned char c2buf[65538];
- Xstatic unsigned char c3buf[65538];
- X
- Xint unscompress(src, len, dest)
- Xunsigned char *src;
- Xint len;
- Xunsigned char *dest;
- X{
- X int ulen=0;
- X int i;
- X#ifdef LOGDATA
- X unsigned char *odest=dest;
- X fprintf(stderr, "uncompressing: ");
- X for(i=0;i<len;i++) {
- X fprintf(stderr, "%x ", src[i]);
- X }
- X fprintf(stderr, "\n");
- X#endif
- X while(len>0) {
- X thet sh=0;
- X if(*src>=COUNTBASE) {
- X int shorts=(*src-(COUNTBASE-1));
- X
- X len--;
- X src++;
- X
- X while(shorts>0) {
- X
- X sh=READ(src[0], src[1], src[2], src[3]);
- X sh=NTOH(sh);
- X if(unext<HISTORY) {
- X uhistory[unext]=sh;
- X unext++;
- X } else {
- X bcopy(&uhistory[1], &uhistory[0], sizeof(uhistory)-sizeof(uhistory[0]));
- X uhistory[unext-1]=sh;
- X }
- X *((thet *)dest)=(sh);
- X ulen+=sizeof(thet);
- X dest+=sizeof(thet);
- X src+=sizeof(thet);
- X len-=sizeof(thet);
- X shorts--;
- X }
- X } else if(*src<SCOUNTMAX+8) {
- X int scanx;
- X if(*src>=SCOUNTMAX) {
- X scanx=(((src[0])-SCOUNTMAX)<<8)+src[1];
- X len--;
- X src++;
- X } else scanx=(*src);
- X scanx=unext-1-scanx;
- X sh=(uhistory[scanx]);
- X *((thet *)dest)=sh;
- X for(i=scanx+1;i<unext;i++) {
- X uhistory[i-1]=uhistory[i];
- X }
- X uhistory[unext-1]=sh;
- X ulen+=sizeof(thet);
- X dest+=sizeof(thet);
- X len--;
- X src++;
- X } else {
- X fprintf(stderr, "Bad data!!! %d\n", *src);
- X }
- X }
- X
- X#ifdef LOGDATA
- X fprintf(stderr, "received: ");
- X for(i=0;i<ulen;i++) fprintf(stderr, "%x ", odest[i]);
- X fprintf(stderr, "\n");
- X#endif
- X return ulen;
- X}
- X
- Xstatic unsigned char mbuf[MAXTRANBUF];
- X#undef MAX
- X#define MAX(x,y) ((x<y)?(y):(x))
- X
- Xint dosstuff(fd)
- Xint fd;
- X{
- X fd_set rfs;
- X int xfd;
- X xfd=client();
- X if(xfd<0) {
- X perror("client");
- X exit(-1);
- X }
- X while(1) {
- X int nfds;
- X FD_ZERO(&rfs);
- X FD_SET(fd, &rfs);
- X FD_SET(xfd, &rfs);
- X#if defined(__hpux) || defined(hpux)
- X#define CASTREADMASK(x) ((int *)(x))
- X#else
- X#define CASTREADMASK(x) (x)
- X#endif
- X
- X nfds=select(MAX(fd, xfd)+1, CASTREADMASK(&rfs), NULL, NULL, NULL);
- X if(nfds==0) continue;
- X if(nfds<0) {
- X if(errno==EINTR) continue;
- X perror("select");
- X continue;
- X }
- X if(FD_ISSET(fd, &rfs)) {
- X if(compression==-1) {
- X unsigned short readlen;
- X int len=0;
- X while(len<2) {
- X int r=read(fd, ((char *)&readlen)+len, 2-len);
- X if(r<=0) {
- X exit(-1);
- X }
- X len+=r;
- X }
- X len=0;
- X readlen=ntohs(readlen);
- X while(len<readlen) {
- X int r=read(fd, mbuf+len, readlen-len);
- X if(r<=0) {
- X exit(-1);
- X }
- X len+=r;
- X }
- X len=unscompress(mbuf, len, c2buf);
- X reallywrite(xfd, c2buf, len);
- X
- X } else if(compression==1) {
- X unsigned char *ptr=mbuf;
- X int len=read(fd, mbuf, sizeof(mbuf));
- X int j;
- X if(len<=0) {
- X exit(-1);
- X }
- X while(len>0) {
- X int oldlen=len;
- X j=scompress(c3buf+2, MAXPACKET, &ptr, &len);
- X /* printf("compressed %d to %d\n", oldlen-len, j+2); */
- X *((unsigned short *)c3buf)=htons(j);
- X reallywrite(xfd, c3buf, j+2);
- X }
- X }
- X }
- X if(FD_ISSET(xfd, &rfs)) {
- X if(compression==1) {
- X unsigned short readlen;
- X int len=0;
- X while(len<2) {
- X int r=read(xfd, ((char *)&readlen)+len, 2-len);
- X if(r<=0) {
- X exit(-1);
- X }
- X len+=r;
- X }
- X len=0;
- X readlen=ntohs(readlen);
- X while(len<readlen) {
- X int r=read(xfd, mbuf+len, readlen-len);
- X if(r<=0) {
- X exit(-1);
- X }
- X len+=r;
- X }
- X len=unscompress(mbuf, len, c2buf);
- X reallywrite(fd, c2buf, len);
- X } else if(compression==-1) {
- X unsigned char *ptr=mbuf;
- X int len=read(xfd, mbuf, sizeof(mbuf));
- X int j;
- X if(len<=0) {
- X exit(-1);
- X }
- X while(len>0) {
- X int oldlen=len;
- X j=scompress(c3buf+2, MAXPACKET, &ptr, &len);
- X /* printf("compressed %d to %d\n", oldlen-len, j+2); */
- X *((unsigned short *)c3buf)=htons(j);
- X reallywrite(fd, c3buf, j+2);
- X }
- X }
- X
- X }
- X }
- X}
- X
- X#ifdef SO_LINGER
- Xstruct linger blah={
- X 0,
- X 0
- X};
- X#endif
- X
- Xint server(portnum)
- Xshort portnum;
- X{
- X int one=1;
- X int servsock, clientsock;
- X struct sockaddr_in servsockaddr, clientsockaddr;
- X int clientsockaddrlen;
- X int pid;
- X
- X if ((servsock = socket(AF_INET, SOCK_STREAM, PF_UNSPEC)) == -1) {
- X perror("socket");
- X return -1;
- X }
- X
- X#ifdef SO_REUSEADDR
- X setsockopt(servsock,SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
- X#endif
- X
- X#ifdef SO_LINGER
- X setsockopt(servsock, SOL_SOCKET, SO_LINGER, &blah, sizeof(blah));
- X#endif
- X
- X servsockaddr.sin_family = AF_INET;
- X servsockaddr.sin_port = htons(portnum);
- X servsockaddr.sin_addr.s_addr = 0;
- X
- X if (bind(servsock, (struct sockaddr *)&servsockaddr,
- sizeof(servsockaddr)) == -1) {
- X perror("bind");
- X return -1;
- X }
- X
- X if (listen(servsock, 5) == -1) {
- X perror("listen");
- X return -1;
- X }
- X
- X if(pid=fork()) {
- X if(pid<0) perror("fork");
- X else exit(0);
- X }
- X close(1);
- X close(0);
- X dup2(2, 1);
- X for (;;) {
- X clientsockaddrlen = sizeof(clientsockaddr);
- X clientsock = accept(servsock, &clientsockaddr, &clientsockaddrlen);
- X if (clientsock == -1) {
- X if(errno!=EINTR) perror("accept");
- X continue;
- X }
- X if(fork()==0) {
- X int i;
- X int count=getdtablesize();
- X for(i=3;i<count;i++) {
- X if(i!=clientsock) close(i);
- X }
- X dosstuff(clientsock);
- X } else close(clientsock);
- X }
- X}
- X
- Xstatic int GetXServAddr(dname)
- Xchar *dname;
- X{
- X struct hostent *hp;
- X char *hostname;
- X char *p;
- X unsigned char inetaddr[4];
- X int dnum=0;
- X int count=0;
- X
- X p=strchr(dname, ':');
- X if(p==NULL || !(isascii(*(p+1)) && isdigit(*(p+1)))) {
- X fprintf(stderr, "DISPLAY must be of the form:
- [HostnameOrUnix]:DisplayNumber[.ScreenNumber]\n");
- X exit(-1);
- X }
- X *p='\0';
- X dnum=atoi(p+1);
- X
- X if(dname[0]=='\0' || strcmp(dname, "unix")==0) hostname="localhost";
- X else hostname=dname;
- X if(isascii(hostname[0]) && isdigit(hostname[0])) {
- X inetaddr[0]=atoi(hostname);
- X count++;
- X p=strchr(hostname, '.');
- X if(p) {
- X inetaddr[1]=atoi(p+1);
- X count++;
- X p=strchr(p+1, '.');
- X if(p) {
- X inetaddr[2]=atoi(p+1);
- X count++;
- X p=strchr(p+1, '.');
- X if(p) {
- X inetaddr[3]=atoi(p+1);
- X count++;
- X }
- X }
- X }
- X if(count!=4) {
- X fprintf(stderr, "Badly formed IP address %s\n", hostname);
- X exit(-1);
- X }
- X bcopy(inetaddr, (char *)&servaddr.sin_addr, sizeof(servaddr.sin_addr));
- X } else {
- X hp = gethostbyname(hostname);
- X if (hp == NULL) {
- X fprintf(stderr, "Can't find address for host %s\n", hostname);
- X exit(-1);
- X }
- X bcopy(hp->h_addr, (char *)&servaddr.sin_addr, sizeof(servaddr.sin_addr));
- X }
- X
- X servaddr.sin_family = AF_INET;
- X servaddr.sin_port = htons(6000 + dnum);
- X return dnum;
- X}
- X
- Xstatic int GetGatewayServAddr(dname, clientbase, serverbase)
- Xchar *dname;
- Xint clientbase;
- Xint serverbase;
- X{
- X struct hostent *hp;
- X char *hostname;
- X char *p;
- X unsigned char inetaddr[4];
- X int dnum=0;
- X int count=0;
- X int snum=0;
- X
- X p=strchr(dname, ':');
- X if(p==NULL || !(isascii(*(p+1)) && isdigit(*(p+1)))) {
- X fprintf(stderr, "DISPLAY must be of the form:
- [HostnameOrUnix]:DisplayNumber[.ScreenNumber]\n");
- X exit(-1);
- X }
- X *p='\0';
- X dnum=atoi(p+1);
- X p=strchr(p+1, '.');
- X if(p) snum=atoi(p+1);
- X
- X if(dname[0]=='\0' || strcmp(dname, "unix")==0) hostname="localhost";
- X else hostname=dname;
- X if(isascii(hostname[0]) && isdigit(hostname[0])) {
- X inetaddr[0]=atoi(hostname);
- X count++;
- X p=strchr(hostname, '.');
- X if(p) {
- X inetaddr[1]=atoi(p+1);
- X count++;
- X p=strchr(p+1, '.');
- X if(p) {
- X inetaddr[2]=atoi(p+1);
- X count++;
- X p=strchr(p+1, '.');
- X if(p) {
- X inetaddr[3]=atoi(p+1);
- X count++;
- X }
- X }
- X }
- X if(count!=4) {
- X fprintf(stderr, "Badly formed IP address %s\n", hostname);
- X exit(-1);
- X }
- X bcopy(inetaddr, (char *)&servaddr.sin_addr, sizeof(servaddr.sin_addr));
- X } else {
- X hp = gethostbyname(hostname);
- X if (hp == NULL) {
- X fprintf(stderr, "Can't find address for host %s\n", hostname);
- X exit(-1);
- X }
- X bcopy(hp->h_addr, (char *)&servaddr.sin_addr, sizeof(servaddr.sin_addr));
- X }
- X printf("localhost:%d.%d\n",clientbase-6000+dnum, snum);
- X servaddr.sin_family = AF_INET;
- X servaddr.sin_port = htons(serverbase + dnum);
- X return dnum;
- X}
- X
- X#if defined(_POSIX_SOURCE) || defined(SYSV)
- Xvoid Reaper(n)
- Xint n;
- X{
- X while(waitpid(-1, NULL, WNOHANG)>0);
- X#ifdef SYSV
- X signal(SIGCHLD, Reaper);
- X#endif
- X}
- X#else
- Xint Reaper(n)
- Xint n;
- X{
- X union wait status;
- X while(wait3(&status, WNOHANG, NULL)>0);
- X return 0;
- X}
- X#endif
- X
- Xint main(argc, argv)
- Xint argc;
- Xchar **argv;
- X{
- X char *p=getenv("XCOMPGATEPORT");
- X char *q=getenv("XCLIENTGATEPORT");
- X int clientbase=6008;
- X int serverbase=4000;
- X
- X if(p) serverbase=atoi(p);
- X if(serverbase==0) serverbase=4000;
- X
- X if(q) clientbase=atoi(q);
- X if(clientbase==0) clientbase=6008;
- X
- X signal(SIGCHLD, Reaper);
- X
- X if(argc<3) {
- X fprintf(stderr, "%s\n", VersionString);
- X fprintf(stderr, "On the X server host:\n\tsxpc local $DISPLAY\nOn the
- X clients' host:\n\tsetenv DISPLAY `sxpc remote $REMOTEDISPLAY`\n(Where
- $REMOTEDISPLAY is the DISPLAY variable setting which would otherwise be
- used.)\n");
- X exit(-1);
- X }
- X
- X compression=(argv[1][0]=='l')?-1:1;
- X if(compression==-1) {
- X server(GetXServAddr(argv[2])+serverbase);
- X } else {
- X server(clientbase+GetGatewayServAddr(argv[2], clientbase, serverbase));
- X }
- X}
- X
- !Funky!Stuff!
- exit
-
- exit 0 # Just in case...
- --
- // chris@Sterling.COM | Send comp.sources.x submissions to:
- \X/ Amiga - The only way to fly! | sources-x@sterling.com
- "It's intuitively obvious to the |
- most casual observer..." | GCS d+/-- p+ c++ l+ m+ s++/+ g+ w+ t+ r+ x+
-