From 062412a066cc62635c1d1eb99999ee774775ca6f Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 8 Jun 2001 00:32:52 +0000 Subject: Import xscope bits into keithp.com CVS --- scope.c | 969 ++++++++++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 736 insertions(+), 233 deletions(-) (limited to 'scope.c') 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 /* needed by sys/socket.h and netinet/in.h */ #include /* for struct iovec, used by socket.h */ #include /* for AF_INET, SOCK_STREAM, ... */ #include /* for FIONCLEX, FIONBIO, ... */ +#ifdef SVR4 +#include +#endif +#include #include /* struct sockaddr_in */ +#include #include /* struct servent * and struct hostent * */ #include /* 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]\n"); fprintf(stderr, " [-d]\n"); fprintf(stderr, " [-v] -- verbose output\n"); + fprintf(stderr, " [-a] -- audio verbose output\n"); fprintf(stderr, " [-q] -- quiet output\n"); fprintf(stderr, " [-D]\n"); + fprintf(stderr, " [-S] -- 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,83 +1103,22 @@ 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); -- cgit v1.2.1