summaryrefslogtreecommitdiff
path: root/scope.c
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2001-06-08 00:32:52 +0000
committerAlan Coopersmith <alan.coopersmith@sun.com>2009-05-04 18:13:07 -0700
commit062412a066cc62635c1d1eb99999ee774775ca6f (patch)
tree3a72f748e101900c292cf242055862ecce4bccb7 /scope.c
parent306057f2475b216fb73686bcb0003355cf88944a (diff)
downloadxscope-062412a066cc62635c1d1eb99999ee774775ca6f.tar.gz
Import xscope bits into keithp.com CVS
Diffstat (limited to 'scope.c')
-rw-r--r--scope.c969
1 files changed, 736 insertions, 233 deletions
diff --git a/scope.c b/scope.c
index 9511f5a..52eadee 100644
--- a/scope.c
+++ b/scope.c
@@ -27,15 +27,20 @@
#include "scope.h"
-#include <sys/types.h> /* needed by sys/socket.h and netinet/in.h */
#include <sys/uio.h> /* for struct iovec, used by socket.h */
#include <sys/socket.h> /* for AF_INET, SOCK_STREAM, ... */
#include <sys/ioctl.h> /* for FIONCLEX, FIONBIO, ... */
+#ifdef SVR4
+#include <sys/filio.h>
+#endif
+#include <fcntl.h>
#include <netinet/in.h> /* struct sockaddr_in */
+#include <netinet/tcp.h>
#include <netdb.h> /* struct servent * and struct hostent * */
#include <errno.h> /* for EINTR, EADDRINUSE, ... */
extern int errno;
+extern InitializePEX();
/* ********************************************** */
/* */
/* ********************************************** */
@@ -43,11 +48,558 @@ extern int errno;
#define DefaultPort 6000
char ServerHostName[255];
+char AudioServerHostName[255];
long ServerBasePort = DefaultPort;
long ServerInPort = 1;
long ServerOutPort = 0;
long ServerDisplay = 0;
+long TranslateText = 0;
+char ScopeEnabled = 1;
+char HandleSIGUSR1 = 0;
+char DoAudio = 0;
+char TerminateClose = 0;
+int Interrupt = 0;
+
+struct FDDescriptor *FDD = 0;
+short MaxFD = 0;
+short nFDsInUse = 0;
+long ReadDescriptors = 0;
+long WriteDescriptors = 0;
+long BlockedReadDescriptors;
+short HighestFD;
+
+short debuglevel = 0;
+short Verbose = 0;
+short XVerbose = 0;
+short NasVerbose = 0;
+int ScopePort = 0;
+char *ScopeHost = 0;
+
+
+typedef struct _BreakPoint {
+ struct _BreakPoint *next;
+ int number;
+ unsigned char request;
+ Boolean enabled;
+} BP;
+
+typedef enum _CMDResult { CMDProceed, CMDDebug, CMDSyntax, CMDError } CMDResult;
+
+CMDResult CMDStep ();
+CMDResult CMDCont ();
+CMDResult CMDBreak ();
+CMDResult CMDDelete ();
+CMDResult CMDDisable ();
+CMDResult CMDEnable ();
+CMDResult CMDLevel ();
+CMDResult CMDAudio ();
+CMDResult CMDQuit ();
+CMDResult CMDHelp ();
+
+typedef struct _CMDFunc {
+ char *name;
+ char *alias;
+ CMDResult (*func)();
+ char *usage;
+ char *help;
+} CMDFuncRec, *CMDFuncPtr;
+
+CMDFuncRec CMDFuncs[] = {
+ "audio", "a", CMDAudio, "[a]udio",
+ "Set audio output level\n",
+ "break", "b", CMDBreak, "[b]reak",
+ "Create breakpoints\n",
+ "cont", "c", CMDCont, "[c]ont",
+ "Continue scoping\n",
+ "delete", "del", CMDDelete, "[del]ete",
+ "Delete breakpoints\n",
+ "disable","d", CMDDisable, "[d]isable",
+ "Disable breakpoints\n",
+ "enable", "e", CMDEnable, "[e]nable",
+ "Enable breakpoints\n",
+ "help", "?", CMDHelp, "help",
+ "Print this list\n",
+ "level", "l", CMDLevel, "[l]evel",
+ "Set output level\n",
+ "quit", "q", CMDQuit, "[q]uit",
+ "Quit Xscope\n",
+ "step", "s", CMDStep, "[s]tep",
+ "Step trace one request\n",
+};
+
+#define NumCMDFuncs (sizeof CMDFuncs / sizeof CMDFuncs[0])
+
+#ifndef FALSE
+#define FALSE 0
+#define TRUE 1
+#endif
+
+static int
+CMDStringToInt(s, v)
+ char *s;
+ int *v;
+{
+ int sign = 1;
+
+ switch (*s) {
+ case '-':
+ sign = -1;
+ s++;
+ break;
+ case '+':
+ s++;
+ break;
+ }
+
+ if (!strncmp (s, "0x", 2))
+ {
+ sscanf (s + 2, "%x", v);
+ }
+ else if (*s == '0')
+ {
+ sscanf (s, "%o", v);
+ }
+ else if (isdigit (*s))
+ {
+ sscanf (s, "%d", v);
+ }
+ else if (*s == '\'')
+ {
+ s++;
+ if (*s == '\\') {
+ s++;
+ switch (*s) {
+ case 'n':
+ *v = '\n';
+ break;
+ case 't':
+ *v = '\t';
+ break;
+ default:
+ *v = (int) *s;
+ break;
+ }
+ } else
+ *v = (int) *s;
+ s++;
+ if (*s != '\'')
+ return FALSE;
+ }
+ else
+ return FALSE;
+ *v *= sign;
+ return TRUE;
+}
+
+static CMDFuncPtr
+CMDStringToFunc (name)
+ char *name;
+{
+ int i;
+ for (i = 0; i < NumCMDFuncs; i++)
+ {
+ if (!strcmp (name, CMDFuncs[i].name) ||
+ !strcmp (name, CMDFuncs[i].alias))
+ {
+ return &CMDFuncs[i];
+ }
+ }
+ return 0;
+}
+
+static int
+CMDSplitIntoWords(line, argv)
+ char *line;
+ char **argv;
+{
+ char quotechar;
+ int argc;
+
+ argc = 0;
+ while (*line) {
+ while (isspace(*line))
+ line++;
+ if (!*line)
+ break;
+ if (*line == '"')
+ {
+ quotechar = *line++;
+ *argv++ = line;
+ argc++;
+ while (*line && *line != quotechar)
+ line++;
+ if (*line)
+ *line++ = '\0';
+ }
+ else
+ {
+ *argv++ = line;
+ argc++;
+ while (*line && !isspace(*line))
+ line++;
+ if (*line)
+ *line++ = '\0';
+ }
+ }
+ *argv = 0;
+ return argc;
+}
+
+CMDResult
+CMDHelp(argc, argv)
+ int argc;
+ char **argv;
+{
+ int i;
+ CMDFuncPtr func;
+
+ if (argc == 1)
+ {
+ for (i = 0; i < NumCMDFuncs; i++)
+ printf("%-10s%s\n", CMDFuncs[i].name, CMDFuncs[i].usage);
+ }
+ else
+ {
+ for (i = 1; i < argc; i++)
+ {
+ func = CMDStringToFunc (argv[i]);
+ if (!func)
+ {
+ printf ("%-10s unknown command\n", argv[i]);
+ return CMDSyntax;
+ }
+ printf ("%-10s %s\n%s", func->name, func->usage, func->help);
+ }
+ }
+ return CMDDebug;
+}
+
+static void
+CMDSyntaxError(argc, argv)
+ int argc;
+ char **argv;
+{
+ printf("Syntax error in:");
+ while (*argv)
+ printf(" %s", *argv++);
+ printf("\n");
+}
+
+void
+ReadCommands ()
+{
+ int argc;
+ char line[1024];
+ char *argv[20];
+ CMDResult result;
+ CMDFuncPtr func;
+ static int here;
+
+ if (here)
+ return;
+ here = 1;
+ for (;;) {
+ printf ("> ");
+ if (!fgets (line, sizeof line, stdin))
+ break;
+ argc = CMDSplitIntoWords(line, argv);
+ if (argc > 0) {
+ func = CMDStringToFunc (argv[0]);
+ if (!func)
+ CMDSyntaxError (argc, argv);
+ else
+ {
+ result = (*func->func)(argc, argv);
+ switch (result) {
+ case CMDSyntax:
+ CMDSyntaxError(argc, argv);
+ break;
+ case CMDError:
+ printf ("Error\n");
+ break;
+ case CMDProceed:
+ here = 0;
+ return;
+ default:
+ break;
+ }
+ }
+ }
+ }
+ printf("...\n");
+ here = 0;
+}
+
+int SingleStep;
+int BreakPoint;
+BP *breakPoints;
+int breakPointNumber;
+
+void
+TestBreakPoints (buf, n)
+ unsigned char *buf;
+ long n;
+{
+ BP *bp;
+
+ for (bp = breakPoints; bp; bp = bp->next)
+ {
+ if (bp->request == buf[0])
+ {
+ break;
+ }
+ }
+ if (bp)
+ {
+ printf ("Breakpoint on request %d\n", bp->request);
+ ReadCommands ();
+ }
+}
+
+void
+setBreakPoint ()
+{
+ Boolean b = false;
+ BP *bp;
+ FD fd;
+
+ if (SingleStep)
+ b = true;
+ else
+ {
+ for (bp = breakPoints; bp; bp = bp->next)
+ {
+ if (bp->enabled)
+ {
+ b = true;
+ break;
+ }
+ }
+ }
+ if (b != BreakPoint)
+ {
+ BreakPoint = b;
+ for (fd = 0; fd < HighestFD; fd++)
+ {
+ extern DataFromClient();
+
+ if (FDD[fd].Busy && FDD[fd].InputHandler == DataFromClient)
+ {
+ if (BreakPoint)
+ SetBufLimit (fd);
+ else
+ ClearBufLimit (fd);
+ }
+ }
+ }
+}
+CMDResult
+CMDBreak (argc, argv)
+ int argc;
+ char **argv;
+{
+ BP *bp, **prev;
+ int request;
+
+ if (argc == 1)
+ {
+ for (bp = breakPoints; bp; bp = bp->next)
+ {
+ printf ("%3d: %3d %s\n", bp->number, bp->request,
+ bp->enabled ? "enabled" : "disabled");
+ }
+ }
+ else
+ {
+ for (prev = &breakPoints; *prev; prev = &(*prev)->next);
+ while (*++argv) {
+ request = GetXRequestFromName (*argv);
+ if (request < 0 && !CMDStringToInt (*argv, &request))
+ return CMDSyntax;
+ bp = (BP *) malloc (sizeof (BP));
+ bp->request = request;
+ bp->number = ++breakPointNumber;
+ bp->enabled = true;
+ bp->next = 0;
+ *prev = bp;
+ prev = &bp->next;
+ }
+ }
+ setBreakPoint ();
+ return CMDDebug;
+}
+
+CMDResult
+CMDCont (argc, argv)
+ int argc;
+ char **argv;
+{
+ SingleStep = 0;
+ return CMDProceed;
+}
+
+CMDResult
+CMDDisable (argc, argv)
+ int argc;
+ char **argv;
+{
+ BP *bp;
+ int number;
+
+ if (argc == 1)
+ {
+ printf ("Disabling all breakpoints...\n");
+ for (bp = breakPoints; bp; bp = bp->next)
+ bp->enabled = false;
+ }
+ else
+ {
+ while (*++argv) {
+ if (!CMDStringToInt (*argv, &number))
+ return CMDSyntax;
+ for (bp = breakPoints; bp; bp = bp->next)
+ if (bp->number == number)
+ {
+ bp->enabled = false;
+ break;
+ }
+ if (!bp)
+ {
+ printf ("No such breakpoint %s\n", *argv);
+ }
+ }
+ }
+ setBreakPoint ();
+ return CMDDebug;
+}
+
+CMDResult
+CMDDelete (argc, argv)
+ int argc;
+ char **argv;
+{
+ BP *bp, **prev;
+ int number;
+
+ if (argc == 1)
+ {
+ printf ("Deleting all breakpoints...\n");
+ while (bp = breakPoints)
+ {
+ breakPoints = bp->next;
+ free (bp);
+ }
+ }
+ else
+ {
+ while (*++argv) {
+ if (!CMDStringToInt (*argv, &number))
+ return CMDSyntax;
+ for (prev = &breakPoints; bp = *prev; prev = &bp->next)
+ {
+ if (bp->number == number)
+ {
+ *prev = bp->next;
+ free (bp);
+ break;
+ }
+ }
+ if (!bp)
+ {
+ printf ("No such breakpoint %s\n", *argv);
+ }
+ }
+ }
+ setBreakPoint ();
+ return CMDDebug;
+}
+
+CMDResult
+CMDEnable (argc, argv)
+ int argc;
+ char **argv;
+{
+ BP *bp;
+ int number;
+
+ if (argc == 1)
+ {
+ printf ("Enablingg all breakpoints...\n");
+ for (bp = breakPoints; bp; bp = bp->next)
+ bp->enabled = true;
+ }
+ else
+ {
+ while (*++argv) {
+ if (!CMDStringToInt (*argv, &number))
+ return CMDSyntax;
+ for (bp = breakPoints; bp; bp = bp->next)
+ if (bp->number == number)
+ {
+ bp->enabled = true;
+ break;
+ }
+ if (!bp)
+ {
+ printf ("No such breakpoint %s\n", *argv);
+ }
+ }
+ }
+ setBreakPoint ();
+ return CMDDebug;
+}
+
+CMDResult
+CMDStep (argc, argv)
+ int argc;
+ char **argv;
+{
+ SingleStep = 1;
+ setBreakPoint ();
+ return CMDProceed;
+}
+
+CMDResult
+CMDQuit (argc, argv)
+ int argc;
+ char **argv;
+{
+ printf ("exiting...\n");
+ exit (0);
+}
+
+CMDResult
+CMDLevel (argc, argv)
+ int argc;
+ char **argv;
+{
+ int level;
+
+ if (argc == 1)
+ printf ("Level: %d\n", XVerbose);
+ else if (argc == 2 && CMDStringToInt (argv[1], &level))
+ XVerbose = level;
+ else
+ return CMDSyntax;
+ return CMDDebug;
+}
+
+CMDResult
+CMDAudio (argc, argv)
+ int argc;
+ char **argv;
+{
+ int level;
+
+ if (argc == 1)
+ printf ("Audio Level: %d\n", NasVerbose);
+ else if (argc == 2 && CMDStringToInt (argv[1], &level))
+ NasVerbose = level;
+ else
+ return CMDSyntax;
+ return CMDDebug;
+}
/* ********************************************** */
/* */
@@ -88,8 +640,11 @@ Usage()
fprintf(stderr, " [-o<out-port>]\n");
fprintf(stderr, " [-d<display-number>]\n");
fprintf(stderr, " [-v<n>] -- verbose output\n");
+ fprintf(stderr, " [-a<n>] -- audio verbose output\n");
fprintf(stderr, " [-q] -- quiet output\n");
fprintf(stderr, " [-D<debug-level>]\n");
+ fprintf(stderr, " [-S<n>] -- start/stop on SIGUSR1\n");
+ fprintf(stderr, " [-t] -- terminate when all clients close\n");
exit(1);
}
@@ -100,9 +655,8 @@ ScanArgs(argc, argv)
int argc;
char **argv;
{
- NoExtensions = false /* default is to allow extensions */;
- Verbose = 1 /* default verbose-ness level */;
- RequestSync = false /* default is to just copy blocks */;
+ XVerbose = 1 /* default verbose-ness level */;
+ NasVerbose = 1;
/* Scan argument list */
while (--argc > 0)
@@ -124,27 +678,26 @@ ScanArgs(argc, argv)
debuglevel = atoi(++*argv);
if (debuglevel == 0)
debuglevel = 255;
- debuglevel |= 1;
- Verbose = 7;
+ XVerbose = 7;
debug(1,(stderr, "debuglevel = %d\n", debuglevel));
break;
- case 'q': /* quiet mode */
- Verbose = 0;
- debug(1,(stderr, "Verbose = %d\n", Verbose));
+ case 'S':
+ HandleSIGUSR1 = 1;
+ ScopeEnabled = atoi(++*argv);
break;
- case 'v': /* verbose mode */
- Verbose = atoi(++*argv);
- debug(1,(stderr, "Verbose = %d\n", Verbose));
+ case 'q': /* quiet mode */
+ XVerbose = 0;
+ debug(1,(stderr, "Verbose = %d\n", XVerbose));
break;
- case 's': /* synchronous mode */
- RequestSync = true;
- debug(1,(stderr, "RequestSync true\n"));
+ case 'v': /* verbose mode */
+ XVerbose = atoi(++*argv);
+ debug(1,(stderr, "Verbose = %d\n", XVerbose));
break;
- case 'o': /* output port */
+ case 'o':
ServerOutPort = atoi(++*argv);
if (ServerOutPort <= 0)
ServerOutPort = 0;
@@ -171,9 +724,26 @@ ScanArgs(argc, argv)
debug(1,(stderr, "ServerHostName=%s\n", ServerHostName));
break;
- case 'x':
- NoExtensions = true;
- debug(1,(stderr, "NoExtensions\n"));
+ case 'T':
+ TranslateText = 1;
+ break;
+
+ case 'A':
+ DoAudio = 1;
+ break;
+
+ case 'a': /* verbose mode */
+ NasVerbose = atoi(++*argv);
+ debug(1,(stderr, "NasVerbose = %d\n", NasVerbose));
+ break;
+
+ case 'n': /* NAS server host */
+ if (++*argv != NULL && **argv != '\0')
+ (void)strcpy(AudioServerHostName, OfficialName(*argv));
+ debug(1,(stderr, "AudioServerHostName=%s\n", AudioServerHostName));
+ break;
+ case 't':
+ TerminateClose = 1;
break;
default:
@@ -205,6 +775,9 @@ ScanArgs(argc, argv)
/* */
/* ********************************************** */
+int NewConnection ();
+int NewAudio ();
+
main(argc, argv)
int argc;
char **argv;
@@ -212,12 +785,18 @@ main(argc, argv)
ScanArgs(argc, argv);
InitializeFD();
InitializeX11();
+ if (DoAudio)
+ InitializeAudio();
+#ifdef PEX
+ InitializePEX();
+#endif
SetUpStdin();
- SetUpConnectionSocket(GetScopePort());
+ SetUpConnectionSocket(GetScopePort(), NewConnection);
+ if (DoAudio)
+ SetUpConnectionSocket (GetScopePort() + 2000, NewAudio);
SetSignalHandling();
MainLoop();
- exit(0);
}
TimerExpired()
@@ -255,7 +834,7 @@ ReadStdin(fd)
SetUpStdin()
{
enterprocedure("SetUpStdin");
- /* UsingFD(fileno(stdin), ReadStdin); */
+ UsingFD(fileno(stdin), ReadStdin, (int (*)()) NULL);
}
/* ************************************************************ */
@@ -272,14 +851,7 @@ SetUpStdin()
we get input from one, we can write it to the other.
*/
-struct fdinfo
-{
- Boolean Server;
- long ClientNumber;
- FD pair;
-};
-
-static long ClientNumber = 0;
+static long clientNumber = 0;
struct fdinfo FDinfo[StaticMaxFD];
SetUpPair(client, server)
@@ -288,15 +860,21 @@ SetUpPair(client, server)
{
if (client >= 0)
{
- ClientNumber += 1;
+ clientNumber += 1;
FDinfo[client].Server = false;
FDinfo[client].pair = server;
- FDinfo[client].ClientNumber = ClientNumber;
+ FDinfo[client].ClientNumber = clientNumber;
+ FDinfo[client].bufcount = 0;
+ FDinfo[client].buflimit = -1;
+ FDinfo[client].bufdelivered = 0;
if (server >= 0)
{
FDinfo[server].Server = true;
FDinfo[server].pair = client;
FDinfo[server].ClientNumber = FDinfo[client].ClientNumber;
+ FDinfo[server].bufcount = 0;
+ FDinfo[server].buflimit = -1;
+ FDinfo[server].bufdelivered = 0;
}
}
else if (server >= 0)
@@ -307,10 +885,29 @@ SetUpPair(client, server)
}
+ResetPair (client, server)
+ FD client;
+ FD server;
+{
+ if (client >= 0)
+ {
+ FDinfo[client].bufcount = 0;
+ FDinfo[client].buflimit = -1;
+ FDinfo[client].bufdelivered = 0;
+ }
+ if (server >= 0)
+ {
+ FDinfo[server].bufcount = 0;
+ FDinfo[server].buflimit = -1;
+ FDinfo[server].bufdelivered = 0;
+ }
+}
+
CloseConnection(fd)
FD fd;
{
debug(4,(stderr, "close %d and %d\n", fd, FDPair(fd)));
+ ResetPair (ClientHalf(fd), ServerHalf(fd));
StopClientConnection(ServerHalf(fd));
StopServerConnection(ClientHalf(fd));
@@ -318,6 +915,8 @@ CloseConnection(fd)
NotUsingFD(fd);
(void)close(FDPair(fd));
NotUsingFD(FDPair(fd));
+ if (TerminateClose)
+ exit (0);
}
/* ************************************************************ */
@@ -347,19 +946,79 @@ FD ServerHalf(fd)
char *ClientName (fd)
FD fd;
{
- static char name[20];
+ static char name[12];
- (void)sprintf(name, " %s %d",
- (FDinfo[fd].Server ? "Server" : "Client"),
- FDinfo[fd].ClientNumber);
+ (void)sprintf(name, " %d", FDinfo[fd].ClientNumber);
return(name);
}
+int ClientNumber (fd)
+ FD fd;
+{
+ return FDinfo[fd].ClientNumber;
+}
/* ********************************************** */
/* */
/* ********************************************** */
+/*
+ * Write as much of the queued data as the receiver will accept
+ * Block reads from the sender until the receiver gets all of the
+ * data
+ */
+FlushFD (fd)
+ FD fd;
+{
+ long BytesToWrite = FDinfo[fd].bufcount - FDinfo[fd].bufstart;
+ char *p = FDinfo[fd].buffer + FDinfo[fd].bufstart;
+ int PeerFD;
+
+ PeerFD = FDPair (fd);
+ if (FDinfo[fd].buflimit >= 0)
+ {
+ if (FDinfo[fd].bufdelivered + BytesToWrite > FDinfo[fd].buflimit)
+ BytesToWrite = FDinfo[fd].buflimit - FDinfo[fd].bufdelivered;
+ }
+ while (BytesToWrite > 0)
+ {
+ int n1 = write (fd, (char *)p, (int)BytesToWrite);
+ debug(4,(stderr, "write %d bytes\n", n1));
+ if (n1 < 0)
+ {
+ if (errno != EWOULDBLOCK && errno != EAGAIN)
+ {
+ perror("Error on write");
+ if (PeerFD >= 0)
+ CloseConnection(PeerFD);
+ BytesToWrite = 0;
+ }
+ break;
+ }
+ else
+ {
+ FDinfo[fd].bufstart += n1;
+ FDinfo[fd].bufdelivered += n1;
+ BytesToWrite -= n1;
+ p += n1;
+ }
+ }
+ if (FDinfo[fd].bufstart == FDinfo[fd].bufcount)
+ {
+ if (PeerFD >= 0)
+ BlockedReadDescriptors &= ~ (1 << PeerFD);
+ WriteDescriptors &= ~(1 << fd);
+ FDinfo[fd].bufcount = FDinfo[fd].bufstart = 0;
+ }
+ else
+ {
+ if (PeerFD >= 0)
+ BlockedReadDescriptors |= 1 << PeerFD;
+ if (FDinfo[fd].buflimit != FDinfo[fd].bufdelivered)
+ WriteDescriptors |= 1 << fd;
+ }
+}
+
/* when we get data from a client, we read it in, copy it to the
server for this client, then dump it to the client. Note, we don't
have to have a server, if there isn't one. */
@@ -367,13 +1026,25 @@ char *ClientName (fd)
DataFromClient(fd)
FD fd;
{
- unsigned char buf[2048];
long n;
FD ServerFD;
+ Verbose = XVerbose;
enterprocedure("DataFromClient");
- n = read(fd, (char *)buf, 2048);
- debug(4,(stderr, "read %d bytes from %s\n", n, ClientName(fd)));
+ ServerFD = FDPair(fd);
+ if (ServerFD < 0)
+ {
+ ServerFD = ConnectToServer(false);
+ if (ServerFD < 0)
+ {
+ CloseConnection(fd);
+ return;
+ }
+ SetUpPair(fd, ServerFD);
+ }
+
+ n = read(fd, FDinfo[ServerFD].buffer, BUFFER_SIZE);
+ debug(4,(stderr, "read %d bytes from Client%s\n", n, ClientName(fd)));
if (n < 0)
{
PrintTime();
@@ -384,30 +1055,18 @@ DataFromClient(fd)
if (n == 0)
{
PrintTime();
- fprintf(stdout, "%s --> EOF\n", ClientName(fd));
+ if (Verbose >= 0)
+ fprintf(stdout, "Client%s --> EOF\n", ClientName(fd));
CloseConnection(fd);
return;
}
- if (debuglevel > 4)
- {
- fflush(stdout); fflush(stderr);
- DumpHexBuffer(buf, n);
- fprintf(stdout,"\n");
- fflush(stdout); fflush(stderr);
- }
-
- ServerFD = FDPair(fd);
- if (ServerFD < 0)
- {
- ServerFD = ConnectToServer(false);
- SetUpPair(fd, ServerFD);
- }
- /* write bytes from client to server, allow for server to fail */
- if (!RequestSync) WriteBytes(ServerFD, buf, n);
+ FDinfo[ServerFD].bufcount = n;
+ FDinfo[ServerFD].bufstart = 0;
+ FlushFD (ServerFD);
/* also report the bytes to standard out */
- ReportFromClient(fd, buf, n);
+ ReportFromClient(fd, FDinfo[ServerFD].buffer, n);
}
/* ********************************************** */
@@ -420,13 +1079,20 @@ DataFromClient(fd)
DataFromServer(fd)
FD fd;
{
- unsigned char buf[2048];
long n;
FD ClientFD;
+ Verbose = XVerbose;
+ ClientFD = FDPair(fd);
+ if (ClientFD < 0)
+ {
+ CloseConnection(fd);
+ return;
+ }
+
enterprocedure("DataFromServer");
- n = read(fd, (char *)buf, 2048);
- debug(4,(stderr, "read %d bytes from %s\n", n, ClientName(fd)));
+ n = read(fd, (char *)FDinfo[ClientFD].buffer, BUFFER_SIZE);
+ debug(4,(stderr, "read %d bytes from Server%s\n", n, ClientName(fd)));
if (n < 0)
{
PrintTime();
@@ -437,85 +1103,24 @@ DataFromServer(fd)
if (n == 0)
{
PrintTime();
- fprintf(stdout, "EOF <-- %s\n", ClientName(fd));
+ if (Verbose >= 0)
+ fprintf(stdout, "EOF <-- Server%s\n", ClientName(fd));
CloseConnection(fd);
return;
}
- if (debuglevel > 4)
- {
- fflush(stdout); fflush(stderr);
- DumpHexBuffer(buf, n);
- fprintf(stdout,"\n");
- fflush(stdout); fflush(stderr);
- }
- ClientFD = FDPair(fd);
- if (ClientFD < 0)
- {
- CloseConnection(fd);
- return;
- }
-
- if (NoExtensions)
- {
- if (buf[0] == 1) /* reply code */
- {
- short SequenceNumber = IShort (&buf[2]);
- short Request = CheckReplyTable (fd, SequenceNumber);
- if (Request == 98) /* Query Extension */
- if (buf[8] == 1)
- buf[8] = 0;
- }
- }
-
- /* write bytes from server to client, allow for client to fail */
- WriteBytes(ClientFD, buf, n);
+ FDinfo[ClientFD].bufcount = n;
+ FDinfo[ClientFD].bufstart = 0;
+ FlushFD (ClientFD);
/* also report the bytes to standard out */
- ReportFromServer(fd, buf, n);
+ ReportFromServer(fd, FDinfo[ClientFD].buffer, n);
}
/* ************************************************************ */
/* */
-/* */
-/* ************************************************************ */
-
-WriteBytes(fd, buf, n)
-FD fd;
-unsigned char *buf;
-long n;
-{
- long BytesToWrite = n;
- unsigned char *p = buf;
-
- if (fd < 0) return;
- if (!ValidFD(fd)) return;
-
- while (BytesToWrite > 0)
- {
- int n1 = write (fd, (char *)p, (int)BytesToWrite);
- debug(4,(stderr, "write %d bytes to %s\n", n1, ClientName(fd)));
- if (n1 > 0)
- {
- BytesToWrite -= n1;
- p += n1;
- }
- else
- {
- char message[255];
- sprintf(message,"Error on write to %s", ClientName(fd));
- perror(message);
- CloseConnection(fd);
- BytesToWrite = 0;
- }
- }
-}
-
-
-/* ************************************************************ */
-/* */
/* Create New Connection to a client program and to Server */
/* */
/* ************************************************************ */
@@ -540,29 +1145,8 @@ FD ConnectToClient(ConnectionSocket)
FD ConnectionSocket;
{
FD ClientFD;
- struct sockaddr_in from;
- size_t len = sizeof (from);
-
- enterprocedure("ConnectToClient");
-
- ClientFD = accept(ConnectionSocket, (struct sockaddr *)&from, &len);
- debug(4,(stderr, "Connect To Client: FD %d\n", ClientFD));
- if (ClientFD < 0 && errno == EWOULDBLOCK)
- {
- debug(4,(stderr, "Almost blocked accepting FD %d\n", ClientFD));
- panic("Can't connect to Client");
- }
- if (ClientFD < 0)
- {
- debug(4,(stderr, "NewConnection: error %d\n", errno));
- panic("Can't connect to Client");
- }
-
- UsingFD(ClientFD, DataFromClient);
-#ifdef FIOCLEX
- (void)ioctl(ClientFD, FIOCLEX, 0);
-#endif /* #ifdef FIOCLEX */
- (void)ioctl(ClientFD, FIONBIO, &ON);
+ ClientFD = AcceptConnection(ConnectionSocket);
+ UsingFD(ClientFD, DataFromClient, FlushFD);
StartClientConnection(ClientFD);
return(ClientFD);
}
@@ -580,91 +1164,10 @@ FD ConnectToServer(report)
Boolean report;
{
FD ServerFD;
- struct sockaddr_in sin;
- struct hostent *hp;
-#ifndef SO_DONTLINGER
- struct linger linger;
-#endif /* #ifndef SO_DONTLINGER */
-
- enterprocedure("ConnectToServer");
-
- /* establish a socket to the name server for this host */
- bzero((char *)&sin, sizeof(sin));
- ServerFD = socket(AF_INET, SOCK_STREAM, 0);
- if (ServerFD < 0)
- {
- perror("socket() to Server failed");
- debug(1,(stderr, "socket failed\n"));
- panic("Can't open connection to Server");
- }
- (void) setsockopt(ServerFD, SOL_SOCKET, SO_REUSEADDR, (char *) NULL, 0);
-#ifdef SO_USELOOPBACK
- (void) setsockopt(ServerFD, SOL_SOCKET, SO_USELOOPBACK,(char *) NULL, 0);
-#endif /* #ifdef SO_USELOOPBACK */
-#ifdef SO_DONTLINGER
- (void) setsockopt(ServerFD, SOL_SOCKET, SO_DONTLINGER, (char *) NULL, 0);
-#else /* #ifdef SO_DONTLINGER */
- linger.l_onoff = 0;
- linger.l_linger = 0;
- (void) setsockopt(ServerFD, SOL_SOCKET, SO_LINGER, (char *)&linger, sizeof linger);
-#endif /* #ifdef SO_DONTLINGER */
-
- /* determine the host machine for this process */
- if (ServerHostName[0] == '\0')
- (void) gethostname(ServerHostName, sizeof (ServerHostName));
- debug(4,(stderr, "try to connect on %s\n", ServerHostName));
-
- hp = gethostbyname(ServerHostName);
- if (hp == 0)
- {
- perror("gethostbyname failed");
- debug(1,(stderr, "gethostbyname failed for %s\n", ServerHostName));
- panic("Can't open connection to Server");
- }
-
- sin.sin_family = AF_INET;
- bcopy((char *)hp->h_addr, (char *)&sin.sin_addr, hp->h_length);
- sin.sin_port = htons(GetServerport());
-
- if ((sin.sin_port == ScopePort)
- && strcmp(ServerHostName, ScopeHost) == 0)
- {
- char error_message[100];
- (void)sprintf(error_message, "Trying to attach to myself: %s,%d\n",
- ServerHostName, sin.sin_port);
- panic(error_message);
- }
-
- /* ******************************************************** */
- /* try to connect to Server */
-
- if (connect(ServerFD, (struct sockaddr *)&sin, sizeof(sin)) < 0)
- {
- debug(4,(stderr, "connect returns errno of %d\n", errno));
- if (errno != 0)
- if (report)
- perror("connect");
- switch (errno)
- {
- case ECONNREFUSED:
- /* experience says this is because there is no Server
- to connect to */
- (void)close(ServerFD);
- debug(1,(stderr, "No Server\n"));
- if (report)
- warn("Can't open connection to Server");
- return(-1);
-
- default:
- (void)close(ServerFD);
- panic("Can't open connection to Server");
- }
- }
-
- debug(4,(stderr, "Connect To Server: FD %d\n", ServerFD));
+ ServerFD = MakeConnection (ServerHostName, GetServerport (), report);
if (ServerFD >= 0)
{
- UsingFD(ServerFD, DataFromServer);
+ UsingFD(ServerFD, DataFromServer, FlushFD);
StartServerConnection(ServerFD);
}
return(ServerFD);