E'L:GL)4-T!5JN"9IYMJ
XML'(BVJ_4*N4*MEJN0.)ZQ[YPB9Y8YYJ'%J.F6`U0EKZ#>NH;0\S&H#]IV%6)
XM0I+5+#3B7B:FGB`SVYA21M<*AA49,:5Z%H:FSBZ;XMS/B$Y\=TBW^65B7:?KBT"UR0'1F^YJ
XM(LBRY$&1H$\Y"+0LJ_JPH80R;Y;5"SD8!1XA/E!6E'''E(^K$!5'+2P
XM3L;S2BBQKT$`GG43<+*)@RL+R](TAP-QD%;8:5@MC"!5&K6I['DU@-5K(Z&F
XMJ:X!D='4>F5/@74453X57Q6AX*R[B462LPEK9=I%QBHZQ.;)6TFLA2NE*M@B
XMD&M!QAJ:-J[.:CPK$)2F@RT=4'>=M+SAR.B+EHPC9*]ICI:!Q&A_:52TG:*K
XMM_F.&HG3&]H:G/:RO04P*\S&K3_J;D;JH*^MHBX).BX]FZ9K:UJB[+([:0SH5KNW;6J[NJ@VJVWJF>8
XMT-*DV\7RJ-LBD!N<%4EYKF>&`7#;!A20ZFQE6]@ZI0LHJ]!L)K>!58#+V"JN
XM(2IT.Z*2GH2+_2K@7K>[9F?;FGZVA>#Z:5O*9;@E#[J=";+BQF^)KKE5N7ZN"&J86*D6O=2JYEISW[E6*X6:&&JV4`:QTN
XM";'6L@HA+KVV5T89GVB)NW8^BRCN#%G3GK;(:#QZG1&4+JY!*[<6LRXHCZ4U2EFK)CJDJNI2K=9
XMIU(@Z`Z*'>C1M9HV=:OD>]I6RDCN1/[`!/@93L`Y,^_PCG.#Y[H.HKDL;M.6
XM;&RZ4%;42C`.M`NCOWOP
XM*KR1R*)W$TB\#Z]Q&^"Y2_30RJMC3;S!;KK+N"JZCBM`%#!HO`YOS=OQJJC`
XM*(M*Y8J\U:YX^X_*HY6AP:OJWE$+;VK9<$2\,Z\AX>U.H0!A@>MV;7!0+^\H
XM]0:[O&0HA0.XLQ,?C8B5@@!8+\^;3$R]%*[J*?1*N^KGU[?D,9W\[L((N(E@
XM"D#9*_%NOV()76F6*P*ZKNAD0&J
XMK\N[,QZXDRI9(/_>"?0O[0OCX0#/[3O[X(Z]^Z]1T/_:*;4O:^K4(9K<[9C+
XMIGZW!R6I"_Z6:4EOMNO`-+W66+=8^>:6X:)WYIM*E')JNMDY$@TZKM[:Y[*+
XM\2^2,@;,OX*N\YNU0;_XF4@KNV$S!;#AJ\XQNTYC^9/]$I>GH+;)H'F_X.8$
XM?+:TOR;('@O_RK>$$;'ROLY'EF3OHP07"2V`^1OH]3B+Z07R!&A'!IF@>Z\:&IMR^VBKF*?*#1(MP1-<*B;L7)%4K"'2(E3,E@
XMP/4H890)DY>>("<,PA@2%+$CZ5Y*P1FQC,3,JK^G;R@L$\S#>>$U,>16@J]P
XMIA@+4[\BL1Q`$O/#BMW3N`-'C3TP]_OX0I7?;S"\?@[#1D4Q'&8
XM,L/%'1'L7"1%&2V=YPT+J3Y-4@P&+V@XYN[`?"J>G:^@.J@1JM+I]V8$@\-Q
XM2[(K$[C#KNBMV(`R83EG$R/HVL'2UU1@B^)G>S"R:Q:'3S#Q&BH5%IJ\YH7+
XM]@ZC;J\>^GINJV\JIAD"F[>G0A7F$#.]EK![NQ1O2Y.I4QRHWJB@:.CKN'V<
XM0?'JA%V5`6?Q2>QVW1#'ZUF<[A:[L.^Q^Q].QIKQSPL0K[V6;I6;%[^0NFD,
XM::KVQ7'JC0W&I:]S^FDZQAH8JOLDU0Z!AE+PWTK&QRL+'#Y9
XMQCS=9"P<(\`P7@ZP[@*3GC'39!SSOZVO:`RJ!L1B:QR:&_-/[`Y@Z2Y,Q"UD
XM2ZN#ZJ8H[NAJT\J>1^^:JS\IO;XOU1E-:<7(L./X2.:FQ#`'S)V)BQ^P7\P8
XMTZGJY,&VXQIJ1DI55AG;OQ$K_AL'"@J:<7)L\7;&&*]FX!_#Q0DPI0OD7:XF
XMKFK%%[^L9ES:.HCBJ:;NDW7R0L3FH^^R?'-
XM>P_GO-P0M_8&2,E4,NTK'7^\U''(FZWNQ8TF>$NZKKA"\!57`?^[E;!Z+&Y^
XMQ_&QARM.HL"&0X4\,#K"5;!:@@:_$20RM+LJMP%J\'*;]6Y28DD]MXL][#JC,U>PD=P4L;1
XMG:B6`X"]=Q\WV'W:1H%NL7PF&\(@[Z)H,&Y@9&GR!BO4>2\)TTU--Y
XM\$HL+).WO/12Q10M>)-FE$:NLB.ID9W+9+#Q^Q2C->QRJLP>N9?4U1KP*;-'
XM'S%V8"_3RNP1K.Q9U,NX\OH+9(@I].V=81'K#F:7`C`L'P$F@?+#*Y,DA.XF
XMQ3#C4&C`PPQ^),>O[Y<<^ZY2$G/#7#$[RY3R7#SI7H!V<6E,]*Y?U3)#+!AC
XMRPY,=,U2PO
XMRYQF<72'=>JZQ7)R'`"'O5?ILZJ+ALV]JT&]H6ARQCMSH)L\S0
XM7:\,*-5'?K#8G"*_?2;5%MHWM\W)<1Z,-D>W0A??+`J#S#CP,3GJI9ZV+VF<
XM[\[-C:)`:RW3GO*>F@M5S5IS1O8Z6TA?,U76!@H!;,(4\"AAG549[MQIJJ[)L3U\.`_`:K-`
XMT#OGSJKKLXS=!KW:K`^?5+`6
XMTW@;\UG6!CK0B8OR7.%FMR7SY'P:_\@2W!/+QP\E?0RSVL?D
XMV119`A>?)W"A;$!>T&OD`ZT^\X6-[
XM"N;$FN'Q1.3A!A^!BZG&6)AVU`ZB!!%WL$^X]D;I&,I2K,/-HBI7=`8S&HET
XM4V;#@4$[!6`QQ(KP:7!B]`]-1AO+G+'&W!P/DVDT!?E`Q\6I*1L*.2O`E:X'
XMW?J]O6C@41E&DQYJ-#=Q0XO%F>E'BQ*WR#LT$P=(R]'L`QV-TLK$5N[JV!&&
XM&4MEG_SE(I&++Q6W_9;0!&75F.*&MT&P=&E14@$8I5^;)//'\V9.Q?:I"%%4
XM3G`2-Y"J,)';AZG2(;(<W)4Y,_#T;/DC>6?R(N'PEB>L=4[Y/90Q9#^V^M&>Q$?PE?UTTMX&[K"TO
XMYI5[4"04_Z7B(RAJL0N&'$7<'9BKQ(C+0]0`(S`=H`VK9VZ<%^T'0S-HWT:M/8!C>-#.D8ZK3`+!+,6#F(E/5,_],1-4*]&PS2O8U'
XM"Y;IT"HQ#_VB#58'=1$EL`71ZATZ"A]S&?H]QK8(93VO##!P;0Y4P>?B.7R29PG)7MU72YZZGUG34U2@.F^0QAO99=]4L=7TF
XM:[3/TF]<2=*NUJ$U3AW.K'=/@!%@!'P!88V02BZD%T_$&C%GO0F1E%"M"R]A
XMF+(J:#DCT9NR$@T56[0,A2&A&,^Y#R>1X6QH1)FLO9PZU9@'5+C&+&Q9V[43
XMS?]\Q'#PB76;E,>QA\_\ZI77=8-V@CK6($8HBJ$^LHIJ1(8P7),$D50!B3N/
XM"UCG?NT@*-09LUJ-#V,S_G5I:F)>
XM9#V-4MBW761]5L,`9W.R+/86S[ZT1C4':MBB=>1,6D/(^J[\=SDCO9`DB@!=
XMN-?L@XY`77P(8R8+DY<.$6/%?P!C*Q&7@SQB$]Y[$?$IXQN(%\?"0P/;]3(#
XM%+PPON78-#:%J5^AD-K-G#5D?P1%]J=B(G)P%39F+2Z@LTG!B*UE_]F5[V:"UN-!:,U%D)$R=--J(
XM:':(0V+;UE'S6US.]*9K;/;E:+)DC,B
XMK%.;,!R7QW7V$'<1WL
XM7NIU=-V#2@==0OT#(!3)Z&,\'5_3T]UPRTT&J-WPE%C9<.S<-_=7G6J3O7?W
XMT'U6'R(3M,?J;M370OW/3VLPLMI\G227<^NW2_D1R7Z'WSD-Z"ME87>9.A
XMD0(1(#;%-H0!UDE^!PCF=QZ'?J^SBU9ED%;'VL2SF;U^EP'MMQOP?J_9*&OV
XM+:IFF9ON*.$!0MV[-N0M9_<%2T"T&D'!2K^R&$E0FU0)N,/[04T(RO=FO0U^
XMV&9V!#[Q3N"2DL*=`S_.]?9HW6;KVN$WW)M7-VTCQYVW)+U9Z
M#>'!
XMJDR@+!S<'0ZY/7SGG&8XO/5ORX#*=X?-6=??C.Y9,HR@X:0VNLU_5ZY)>'4\
XM$$>(IL0`#GXWW'!VA(VJLDU=MI@74./<[A+?,`=*U,KWF#V'_^!C:")^VTG4
XMM[:#7/CEVWOT&B.%9[EF]X<++!3&]7$['4V'N=.T40UA3]V@=-4]>\;7%]LI
XMG:K8R6UFGTWC!-25MRN,2&O>BYPE'N)@XO/VT[-T!TP#1[^C!\6)!N-Q39"A
XMWJ/BF:A4PU9SMB*N4@O4DS4\7%D_XM/XWPUK3^(#MC>(C=O4^5LP_H$JWLMS
XM_WUBD^"$^)`8>7-MTC@X?@;DX@QH(?U29]Y[]DSMB]_BV3C]G!=ON%BN,KV^
XMC>)V$Q-NFFO>%\K#HNS+,`L_GM_@\%>[[>(V^`+
XM="-.#?)^B1XD'F;/2(&W\TVB"@1\`_K]_P'CU/<@?(0CW>?X_[U]<[@]]3?M
XM@_S4P]W_!TV#N1V%F/MF0U5_`A^*3E@);SM5?YYHA;S&1N>1(*E\\@J,)<#FXL
XMY?3#6%Z6SR#`F%_NE0#F*%I>#F_NY63`L>67U^(FN44^CSD&B0#T<0]P]\:+?>Q-25'9EWY--XN?V:
XM;^;9N/+M<_O@W3A).YO+`9RY!^XX)]Y'-_;=DBOA!7BQXYYFOG"HJ<-Y*AX0'scope.c' <<'END_OF_FILE'
X/* ******************************************************
X * *
X * A spy program to reveal X11 traffic *
X * *
X * James Peterson, 1988 *
X * (c) Copyright MCC, 1988 *
X * *
X ***************************************************** */
X
X#include "scope.h"
X
X
X/* ********************************************** */
X/* */
X/* ********************************************** */
X
X#define DefaultPort 6000
X
Xchar ServerHostName[255];
Xlong ServerBasePort = DefaultPort;
Xlong ServerInPort = 1;
Xlong ServerOutPort = 0;
Xlong ServerDisplay = 0;
X
X
X/* ********************************************** */
X/* */
X/* */
X/* ********************************************** */
X
Xshort GetServerport ()
X{
X short port;
X
X enterprocedure("GetServerport");
X
X port = ServerBasePort + ServerOutPort + ServerDisplay;
X debug(4,(stderr, "Server service is on port %d\n", port));
X return(port);
X}
X
Xshort GetScopePort ()
X{
X short port;
X
X enterprocedure("GetScopePort");
X
X port = ServerBasePort + ServerInPort + ServerDisplay;
X debug(4,(stderr, "scope service is on port %d\n", port));
X return(port);
X}
X
X/* ********************************************** */
X/* */
X/* ********************************************** */
X
XUsage()
X{
X fprintf(stderr, "Usage: xscope\n");
X fprintf(stderr, " [-h]\n");
X fprintf(stderr, " [-i]\n");
X fprintf(stderr, " [-o]\n");
X fprintf(stderr, " [-d]\n");
X fprintf(stderr, " [-v] -- verbose output\n");
X fprintf(stderr, " [-q] -- quiet output\n");
X fprintf(stderr, " [-D]\n");
X exit(1);
X}
X
X
Xchar *OfficialName() /* forward type declaration */;
X
XScanArgs(argc, argv)
X int argc;
X char **argv;
X{
X Verbose = 1 /* default verbose-ness level */;
X
X /* Scan argument list */
X while (--argc > 0)
X {
X ++argv;
X if (**argv == '-')
X switch (*++*argv)
X {
X /*
X debug levels:
X 2 - trace each procedure entry
X 4 - I/O, connections
X 8 - Scope internals
X 16 - Message protocol
X 32 - 64 - malloc
X 128 - 256 - really low level
X */
X case 'D':
X debuglevel = atoi(++*argv);
X if (debuglevel == 0)
X debuglevel = 255;
X debuglevel |= 1;
X Verbose = 7;
X debug(1,(stderr, "debuglevel = %d\n", debuglevel));
X break;
X
X case 'q': /* quiet mode */
X Verbose = 0;
X debug(1,(stderr, "Verbose = %d\n", Verbose));
X break;
X
X case 'v': /* verbose mode */
X Verbose = atoi(++*argv);
X debug(1,(stderr, "Verbose = %d\n", Verbose));
X break;
X
X case 'o':
X ServerOutPort = atoi(++*argv);
X if (ServerOutPort <= 0)
X ServerOutPort = 0;
X debug(1,(stderr, "ServerOutPort = %d\n", ServerOutPort));
X break;
X
X case 'd':
X ServerDisplay = atoi(++*argv);
X if (ServerDisplay <= 0)
X ServerDisplay = 0;
X debug(1,(stderr, "ServerDisplay=%d\n", ServerDisplay));
X break;
X
X case 'i':
X ServerInPort = atoi(++*argv);
X if (ServerInPort <= 0)
X ServerInPort = 0;
X debug(1,(stderr, "ServerInPort = %d\n", ServerInPort));
X break;
X
X case 'h':
X if (++*argv != NULL && **argv != '\0')
X strcpy(ServerHostName, OfficialName(*argv));
X debug(1,(stderr, "ServerHostName=%s\n", ServerHostName));
X break;
X
X default:
X fprintf(stderr, "Unknown option %c\n", **argv);
X Usage();
X break;
X
X }
X else
X {
X /* file argument to scope -- error */
X Usage();
X }
X }
X
X /* check for different port numbers or different machines */
X if (ServerInPort == ServerOutPort)
X if (ServerHostName[0] == '\0')
X {
X fprintf(stderr, "Can't have xscope on same port as server (%d)\n",
X ServerInPort);
X Usage();
X }
X
X}
X
X
X/* ********************************************** */
X/* */
X/* ********************************************** */
X
Xmain(argc, argv)
X int argc;
X char **argv;
X{
X ScanArgs(argc, argv);
X InitializeFD();
X InitializeX11();
X SetUpStdin();
X SetUpConnectionSocket(GetScopePort());
X SetSignalHandling();
X
X MainLoop();
X}
X
XTimerExpired()
X{
X debug(16,(stderr, "Timer tick\n"));
X}
X
X/* ********************************************** */
X/* */
X/* ********************************************** */
X
X/*
X here is where we would add code to allow control from
X the keyboard. We would want to read a command and
X interpret it. Possibilties:
X
X (a) verbose level setting
X (b) reset time
X (c) save X requests to a file.
X (d) replay X requests from a file.
X (e) allow fake events, errors to be generated.
X*/
X
XReadStdin(fd)
X FD fd;
X{
X char buf[2048];
X long n;
X
X enterprocedure("ReadStdin");
X n = read(fd, buf, 2048);
X debug(4,(stderr, "read %d bytes from stdin\n", n));
X}
X
XSetUpStdin()
X{
X enterprocedure("SetUpStdin");
X UsingFD(fileno(stdin), ReadStdin);
X}
X
X/* ************************************************************ */
X/* */
X/* */
X/* ************************************************************ */
X
X/*
X xscope is really meant to look at one client at a time. However,
X it can easily handle multiple clients and servers. To do so,
X we need to have a pair of FDs: one for the client and one for the
X server for that client. If either goes away, so does the other.
X We need to be able to identify the other FD of a pair, so that if
X we get input from one, we can write it to the other.
X*/
X
Xstruct fdinfo
X{
X Boolean Server;
X long ClientNumber;
X FD pair;
X};
X
Xstatic long ClientNumber = 0;
Xstruct fdinfo FDinfo[StaticMaxFD];
X
XSetUpPair(client, server)
X FD client;
X FD server;
X{
X if (client >= 0)
X {
X ClientNumber += 1;
X FDinfo[client].Server = false;
X FDinfo[client].pair = server;
X FDinfo[client].ClientNumber = ClientNumber;
X if (server >= 0)
X {
X FDinfo[server].Server = true;
X FDinfo[server].pair = client;
X FDinfo[server].ClientNumber = FDinfo[client].ClientNumber;
X }
X }
X else if (server >= 0)
X {
X close(server);
X NotUsingFD(server);
X }
X}
X
X
XCloseConnection(fd)
X FD fd;
X{
X debug(4,(stderr, "close %d and %d\n", fd, FDPair(fd)));
X StopClientConnection(ServerHalf(fd));
X StopServerConnection(ClientHalf(fd));
X
X close(fd);
X NotUsingFD(fd);
X close(FDPair(fd));
X NotUsingFD(FDPair(fd));
X}
X
X/* ************************************************************ */
X
XFD FDPair(fd)
X FD fd;
X{
X return(FDinfo[fd].pair);
X}
X
XFD ClientHalf(fd)
X FD fd;
X{
X if (FDinfo[fd].Server)
X return(FDinfo[fd].pair);
X return(fd);
X}
X
XFD ServerHalf(fd)
X FD fd;
X{
X if (FDinfo[fd].Server)
X return(fd);
X return(FDinfo[fd].pair);
X}
X
Xchar *ClientName (fd)
X FD fd;
X{
X static char name[12];
X
X if (ClientNumber <= 1)
X return("");
X sprintf(name, " %d", FDinfo[fd].ClientNumber);
X return(name);
X}
X
X
X/* ********************************************** */
X/* */
X/* ********************************************** */
X
X/* when we get data from a client, we read it in, copy it to the
X server for this client, then dump it to the client. Note, we don't
X have to have a server, if there isn't one. */
X
XDataFromClient(fd)
X FD fd;
X{
X unsigned char buf[2048];
X long n;
X FD ServerFD;
X
X enterprocedure("DataFromClient");
X n = read(fd, (char *)buf, 2048);
X debug(4,(stderr, "read %d bytes from Client%s\n", n, ClientName(fd)));
X if (n < 0)
X {
X PrintTime();
X perror("Client --> read error:");
X CloseConnection(fd);
X return;
X }
X if (n == 0)
X {
X PrintTime();
X fprintf(stdout, "Client%s --> EOF\n", ClientName(fd));
X CloseConnection(fd);
X return;
X }
X
X ServerFD = FDPair(fd);
X if (ServerFD < 0)
X {
X ServerFD = ConnectToServer(false);
X SetUpPair(fd, ServerFD);
X }
X
X /* write bytes from client to server, allow for server to fail */
X if (ServerFD >= 0)
X {
X long BytesToWrite = n;
X unsigned char *p = buf;
X
X while (BytesToWrite > 0)
X {
X int n1 = write (ServerFD, (char *)p, (int)BytesToWrite);
X debug(4,(stderr, "write %d bytes to Server%s\n", n1, ClientName(fd)));
X if (n1 > 0)
X {
X BytesToWrite -= n1;
X p += n1;
X }
X else
X {
X perror("Error on write to Server");
X CloseConnection(fd);
X BytesToWrite = 0;
X }
X }
X }
X
X /* also report the bytes to standard out */
X ReportFromClient(fd, buf, n);
X}
X
X/* ********************************************** */
X/* */
X/* ********************************************** */
X
X/* similar situation for the server, but note that if there is no client,
X we close the connection down -- don't need a server with no client. */
X
XDataFromServer(fd)
X FD fd;
X{
X unsigned char buf[2048];
X long n;
X FD ClientFD;
X
X enterprocedure("DataFromServer");
X n = read(fd, (char *)buf, 2048);
X debug(4,(stderr, "read %d bytes from Server%s\n", n, ClientName(fd)));
X if (n < 0)
X {
X PrintTime();
X perror("read error <- Server");
X CloseConnection(fd);
X return;
X }
X if (n == 0)
X {
X PrintTime();
X fprintf(stdout, "EOF <-- Server%s\n", ClientName(fd));
X CloseConnection(fd);
X return;
X }
X
X ClientFD = FDPair(fd);
X if (ClientFD < 0)
X {
X CloseConnection(fd);
X return;
X }
X
X /* write bytes from server to client, allow for client to fail */
X {
X long BytesToWrite = n;
X unsigned char *p = buf;
X while (BytesToWrite > 0)
X {
X int n1 = write (ClientFD, (char *)p, (int)BytesToWrite);
X debug(4,(stderr, "write %d bytes to Client%s\n", n1, ClientName(fd)));
X if (n1 > 0)
X {
X BytesToWrite -= n1;
X p += n1;
X }
X else
X {
X perror("Error on write to Client");
X CloseConnection(fd);
X BytesToWrite = 0;
X }
X }
X }
X
X /* also report the bytes to standard out */
X ReportFromServer(fd, buf, n);
X}
X
X
X
X/* ************************************************************ */
X/* */
X/* Create New Connection to a client program and to Server */
X/* */
X/* ************************************************************ */
X
X#include /* needed by sys/socket.h and netinet/in.h */
X#include /* for struct iovec, used by socket.h */
X#include /* for AF_INET, SOCK_STREAM, ... */
X#include /* for FIONCLEX, FIONBIO, ... */
X#include /* struct sockaddr_in */
X#include /* struct servent * and struct hostent * */
X#include /* for EINTR, EADDRINUSE, ... */
Xextern int errno;
X
Xstatic int ON = 1 /* used in ioctl */ ;
X
XNewConnection(fd)
X FD fd;
X{
X FD ServerFD = -1;
X FD ClientFD = -1;
X
X ClientFD = ConnectToClient(fd);
X ServerFD = ConnectToServer(true);
X SetUpPair(ClientFD, ServerFD);
X}
X
X
X/* ************************************************************ */
X
XFD ConnectToClient(ConnectionSocket)
X FD ConnectionSocket;
X{
X FD ClientFD;
X struct sockaddr_in from;
X int len = sizeof (from);
X
X enterprocedure("ConnectToClient");
X
X ClientFD = accept(ConnectionSocket, (struct sockaddr *)&from, &len);
X debug(4,(stderr, "Connect To Client: FD %d\n", ClientFD));
X if (ClientFD < 0 && errno == EWOULDBLOCK)
X {
X debug(4,(stderr, "Almost blocked accepting FD %d\n", ClientFD));
X panic("Can't connect to Client");
X }
X if (ClientFD < 0)
X {
X debug(4,(stderr, "NewConnection: error %d\n", errno));
X panic("Can't connect to Client");
X }
X
X UsingFD(ClientFD, DataFromClient);
X ioctl(ClientFD, FIOCLEX, 0);
X ioctl(ClientFD, FIONBIO, &ON);
X StartClientConnection(ClientFD);
X return(ClientFD);
X}
X
X
X
X/* ************************************************************ */
X/* */
X/* */
X/* ************************************************************ */
X
X
X
XFD ConnectToServer(report)
X Boolean report;
X{
X FD ServerFD;
X struct sockaddr_in sin;
X struct hostent *hp;
X
X enterprocedure("ConnectToServer");
X
X /* establish a socket to the name server for this host */
X bzero((char *)&sin, sizeof(sin));
X ServerFD = socket(AF_INET, SOCK_STREAM, 0);
X if (ServerFD < 0)
X {
X perror("socket() to Server failed");
X debug(1,(stderr, "socket failed\n"));
X panic("Can't open connection to Server");
X }
X (void) setsockopt(ServerFD, SOL_SOCKET, SO_REUSEADDR, (char *) NULL, 0);
X (void) setsockopt(ServerFD, SOL_SOCKET, SO_USELOOPBACK,(char *) NULL, 0);
X (void) setsockopt(ServerFD, SOL_SOCKET, SO_DONTLINGER, (char *) NULL, 0);
X
X /* determine the host machine for this process */
X if (ServerHostName[0] == '\0')
X (void) gethostname(ServerHostName, sizeof (ServerHostName));
X debug(4,(stderr, "try to connect on %s\n", ServerHostName));
X
X hp = gethostbyname(ServerHostName);
X if (hp == 0)
X {
X perror("gethostbyname failed");
X debug(1,(stderr, "gethostbyname failed for %s\n", ServerHostName));
X panic("Can't open connection to Server");
X }
X
X sin.sin_family = AF_INET;
X bcopy((char *)hp->h_addr, (char *)&sin.sin_addr, hp->h_length);
X sin.sin_port = GetServerport();
X
X if ((sin.sin_port == ScopePort)
X && strcmp(ServerHostName, ScopeHost) == 0)
X {
X char error_message[100];
X sprintf(error_message, "Trying to attach to myself: %s,%d\n",
X ServerHostName, sin.sin_port);
X panic(error_message);
X }
X
X /* ******************************************************** */
X /* try to connect to Server */
X
X if (connect(ServerFD, (struct sockaddr *)&sin, sizeof(sin)) < 0)
X {
X debug(4,(stderr, "connect returns errno of %d\n", errno));
X if (errno != 0)
X if (report)
X perror("connect");
X switch (errno)
X {
X case ECONNREFUSED:
X /* experience says this is because there is no Server
X to connect to */
X close(ServerFD);
X debug(1,(stderr, "No Server\n"));
X if (report)
X warn("Can't open connection to Server");
X return(-1);
X
X default:
X close(ServerFD);
X panic("Can't open connection to Server");
X }
X }
X
X debug(4,(stderr, "Connect To Server: FD %d\n", ServerFD));
X if (ServerFD >= 0)
X {
X UsingFD(ServerFD, DataFromServer);
X StartServerConnection(ServerFD);
X }
X return(ServerFD);
X}
X
X
X/* ********************************************** */
X/* */
X/* ********************************************** */
X
Xchar *OfficialName(name)
Xchar *name;
X{
X struct hostent *HostEntry;
X
X HostEntry = gethostbyname(name);
X if (HostEntry == NULL)
X {
X perror("gethostbyname");
X exit(-1);
X }
X debug(4,(stderr, "Official name of %s is %s\n", name, HostEntry->h_name));
X return(HostEntry->h_name);
X}
X
END_OF_FILE
if test 14921 -ne `wc -c <'scope.c'`; then
echo shar: \"'scope.c'\" unpacked with wrong size!
fi
# end of 'scope.c'
fi
if test -f 'xscope.1' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'xscope.1'\"
else
echo shar: Extracting \"'xscope.1'\" \(3140 characters\)
sed "s/^X//" >'xscope.1' <<'END_OF_FILE'
X.TH XSCOPE 1 "8 Sept 1988" "X Version 11"
X.SH NAME
Xxscope - X Window Protocol Viewer
X.SH SYNOPSIS
X.B xscope
X[ option ] ...
X.SH DESCRIPTION
X.I Xscope
Xsits in-between an X11 client and an X11 server and prints the contents
Xof each request, reply, error, or event that is communicated between them.
XThis information can be useful in debugging and performance
Xtuning of X11 servers and clients.
X.PP
XTo operate, \fIxscope\fP must know the host, port, and display to use
Xto connect to the X11 server. In addition, it must know the port on
Xwhich it should listen for X11 clients. Two cases are common:
X.PP
X.TP 5
X(1) The X11 server is on the same host as \fIxscope\fP.
XIn this case, the input port for \fIxscope\fP should be selected as an
XX11 server on a different display, and the client DISPLAY argument
Xadjusted to select \fIxscope\fP . For example, if the X11 server is
Xon port 6000, display 1, then \fIxscope\fP can use port 6002 as its
Xinput port. The client can use display 1 for direct access to X11 or
Xdisplay 2 for access to \fIxscope\fP.
X.PP
X.TP 5
X(2) The X11 server is on a different host than \fIxscope\fP.
XIn this case the same input and output ports can be used, and the host
Xcomponent of the DISPLAY is used to select \fIxscope\fP or X11.
X.SH ARGUMENTS
X.PP
X.TP 10
X.B \-i
XSpecify the port that \fIxscope\fP will use to take requests from clients
X(defaults to 1).
XFor X11, this port is automatically biased by 6000.
X.PP
X.TP 10
X.B \-o
XDetermines the port that
X\fIxscope\fP will use to connect to X11 (defaults to 0).
XFor X11, this port is automatically biased by 6000.
X.PP
X.TP 10
X.B \-h
XDetermines the host that \fIxscope\fP will use to find its X11 server.
X.PP
X.TP 10
X.B \-d
XDefines the display number. The display number is added to the input
Xand output port to give the actual ports which are used by \fIxscope\fP.
X.PP
X.TP 10
X.B \-q
XQuiet output mode. Gives only the names of requests, replies, errors, and
Xevents, but does not indicate contents.
X.PP
X.TP 10
X.B \-v
XDetermines the level of printing which \fIxscope\fP will provide. The
Xprint-level can be 0 (same as quiet mode), 1, 2, 3, 4. The larger
Xnumbers give more and more output. For example, a successful setup
Xreturns a string which is the name of the vendor of the X11 server.
XAt level 1, the explicit field giving the length of the string is
Xsuppressed since it can be inferred from the string. At level 2 and
Xabove the length is explicitly printed.
X.SH EXAMPLES
X.LP
Xxscope -v4 -hcleo -d0 -o0 -i1
X.PP
XThis command would have xscope communicate with an X11 server on host
X``cleo'', display 0; xscope itself would be available on the current
Xhost as display 1 (display of 0 plus the 1 of -i1). Verbose level 4.
X.LP
Xxscope -q -d1 -o1 -o3
X.PP
XThe X11 server for the current host, display 2 (1 for -d1 plus 1 for -o1)
Xwould be used by xscope which would run as display 4 (1 for -d1 plus 3 for
X-o3). Quite mode (verbose level 0).
X.SH SEE ALSO
XX(1), X11 Protocol document (doc/Protocol/X11.protocol)
X.SH AUTHOR
X.PP
XJames L. Peterson (MCC)
X.PP
XCopyright 1988, MCC
X.SH BUGS
XCode has only been tested on Sun3's.
END_OF_FILE
if test 3140 -ne `wc -c <'xscope.1'`; then
echo shar: \"'xscope.1'\" unpacked with wrong size!
fi
# end of 'xscope.1'
fi
echo shar: End of archive 2 \(of 4\).
cp /dev/null ark2isdone
MISSING=""
for I in 1 2 3 4 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 4 archives.
rm -f ark[1-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0
--
Mike Wexler(wyse!mikew) Phone: (408)433-1000 x1330
Moderator of comp.sources.x