Re: [PATCH] move socket-related client parts into separate file

Derek Robert Price <[email protected]>
Newsgroups gmane.comp.version-control.cvs.bugs
Organization Ximbiot <http://ximbiot.com>
Message-ID <[email protected]>
Have you tried compiling this on Windows?  Windows and OS2 are the only 
platforms that define NO_SOCKET_TO_FD that I know of and this will break 
there.  At the very least, cvsnt.mak will need to be modified to find 
the new source file, but it is possible that this code needs some 
includes from cvs.h and client.h.  Don't worry about OS2 so much, but we 
still try and keep support on Windows up to date.

Okay, I just defined NO_SOCKET_TO_FD by hand on UNIX and attempted to 
compile and discovered that, at the least, socket-client.c needs some 
function prototypes from cvs.h.  I also got some "dereferencing pointer 
to incomplete type" errors I didn't bother to track down.

I'm cc'ing bug-cvs in the interest of additional input.

Derek

Alexey Mahotkin wrote:

>Derek,
>
>are you interested in a series of patches which extract various parts out
>of the (messy) client.c and server.c?
>
>Goals are: reduce those two beasts; move similar stuff together; help me
>keep cvs-nserver merges manageable.  Not a rocket science, but my
>experience w/cvs-nserver shows that some parts are really becoming clearer
>that way.
>
>
>
>2003-04-24  Alexey Mahotkin  <[email protected]>
>
>Moved most of the socket stuff to separate socket-client.[ch];
>in particular, GSSAPI split depends on this
>
>
> src/Makefile.am     |    1 
> src/Makefile.in     |   20 ++-
> src/client.c        |  264 ----------------------------------------------------
> src/socket-client.c |  246 ++++++++++++++++++++++++++++++++++++++++++++++++
> src/socket-client.h |   55 ++++++++++
> 5 files changed, 315 insertions(+), 271 deletions(-)
>
>--- ccvs/src/client.c~socket-client	Thu Apr 24 02:07:42 2003
>+++ ccvs-alexm/src/client.c	Thu Apr 24 02:18:47 2003
>@@ -26,39 +26,7 @@
> 
> # include "md5.h"
> 
>-# if defined(AUTH_CLIENT_SUPPORT) || defined(HAVE_KERBEROS) || defined(HAVE_GSSAPI) || defined(SOCK_ERRNO) || defined(SOCK_STRERROR)
>-#   ifdef HAVE_WINSOCK_H
>-#     include <winsock.h>
>-#   else /* No winsock.h */
>-#     include <sys/socket.h>
>-#     include <netinet/in.h>
>-#     include <arpa/inet.h>
>-#     include <netdb.h>
>-#   endif /* No winsock.h */
>-# endif
>-
>-/* If SOCK_ERRNO is defined, then send()/recv() and other socket calls
>-   do not set errno, but that this macro should be used to obtain an
>-   error code.  This probably doesn't make sense unless
>-   NO_SOCKET_TO_FD is also defined. */
>-# ifndef SOCK_ERRNO
>-#   define SOCK_ERRNO errno
>-# endif
>-
>-/* If SOCK_STRERROR is defined, then the error codes returned by
>-   socket operations are not known to strerror, and this macro must be
>-   used instead to convert those error codes to strings. */
>-# ifndef SOCK_STRERROR
>-#   define SOCK_STRERROR strerror
>-
>-#   if STDC_HEADERS
>-#     include <string.h>
>-#   endif
>-
>-#   ifndef strerror
>-extern char *strerror ();
>-#   endif
>-# endif /* ! SOCK_STRERROR */
>+#include "socket-client.h"
> 
> # if HAVE_KERBEROS
> 
>@@ -602,236 +570,6 @@ log_buffer_shutdown (buf)
> 	error (0, errno, "closing log file");
>     return retval;
> }
>-
>-#ifdef NO_SOCKET_TO_FD
>-
>-/* Under certain circumstances, we must communicate with the server
>-   via a socket using send() and recv().  This is because under some
>-   operating systems (OS/2 and Windows 95 come to mind), a socket
>-   cannot be converted to a file descriptor -- it must be treated as a
>-   socket and nothing else.
>-   
>-   We may also need to deal with socket routine error codes differently
>-   in these cases.  This is handled through the SOCK_ERRNO and
>-   SOCK_STRERROR macros. */
>-
>-/* These routines implement a buffer structure which uses send and
>-   recv.  The buffer is always in blocking mode so we don't implement
>-   the block routine.  */
>-
>-/* Note that it is important that these routines always handle errors
>-   internally and never return a positive errno code, since it would in
>-   general be impossible for the caller to know in general whether any
>-   error code came from a socket routine (to decide whether to use
>-   SOCK_STRERROR or simply strerror to print an error message). */
>-
>-/* We use an instance of this structure as the closure field.  */
>-
>-struct socket_buffer
>-{
>-    /* The socket number.  */
>-    int socket;
>-};
>-
>-static struct buffer *socket_buffer_initialize
>-  PROTO ((int, int, void (*) (struct buffer *)));
>-static int socket_buffer_input PROTO((void *, char *, int, int, int *));
>-static int socket_buffer_output PROTO((void *, const char *, int, int *));
>-static int socket_buffer_flush PROTO((void *));
>-static int socket_buffer_shutdown PROTO((struct buffer *));
>-
>-
>-
>-/* Create a buffer based on a socket.  */
>-
>-static struct buffer *
>-socket_buffer_initialize (socket, input, memory)
>-    int socket;
>-    int input;
>-    void (*memory) PROTO((struct buffer *));
>-{
>-    struct socket_buffer *n;
>-
>-    n = (struct socket_buffer *) xmalloc (sizeof *n);
>-    n->socket = socket;
>-    return buf_initialize (input ? socket_buffer_input : NULL,
>-			   input ? NULL : socket_buffer_output,
>-			   input ? NULL : socket_buffer_flush,
>-			   (int (*) PROTO((void *, int))) NULL,
>-			   socket_buffer_shutdown,
>-			   memory,
>-			   n);
>-}
>-
>-
>-
>-/* The buffer input function for a buffer built on a socket.  */
>-
>-static int
>-socket_buffer_input (closure, data, need, size, got)
>-     void *closure;
>-     char *data;
>-     int need;
>-     int size;
>-     int *got;
>-{
>-    struct socket_buffer *sb = (struct socket_buffer *) closure;
>-    int nbytes;
>-
>-    /* I believe that the recv function gives us exactly the semantics
>-       we want.  If there is a message, it returns immediately with
>-       whatever it could get.  If there is no message, it waits until
>-       one comes in.  In other words, it is not like read, which in
>-       blocking mode normally waits until all the requested data is
>-       available.  */
>-
>-    *got = 0;
>-
>-    do
>-    {
>-
>-	/* Note that for certain (broken?) networking stacks, like
>-	   VMS's UCX (not sure what version, problem reported with
>-	   recv() in 1997), and (according to windows-NT/config.h)
>-	   Windows NT 3.51, we must call recv or send with a
>-	   moderately sized buffer (say, less than 200K or something),
>-	   or else there may be network errors (somewhat hard to
>-	   produce, e.g. WAN not LAN or some such).  buf_read_data
>-	   makes sure that we only recv() BUFFER_DATA_SIZE bytes at
>-	   a time.  */
>-
>-	nbytes = recv (sb->socket, data, size, 0);
>-	if (nbytes < 0)
>-	    error (1, 0, "reading from server: %s", SOCK_STRERROR (SOCK_ERRNO));
>-	if (nbytes == 0)
>-	{
>-	    /* End of file (for example, the server has closed
>-	       the connection).  If we've already read something, we
>-	       just tell the caller about the data, not about the end of
>-	       file.  If we've read nothing, we return end of file.  */
>-	    if (*got == 0)
>-		return -1;
>-	    else
>-		return 0;
>-	}
>-	need -= nbytes;
>-	size -= nbytes;
>-	data += nbytes;
>-	*got += nbytes;
>-    }
>-    while (need > 0);
>-
>-    return 0;
>-}
>-
>-
>-
>-/* The buffer output function for a buffer built on a socket.  */
>-
>-static int
>-socket_buffer_output (closure, data, have, wrote)
>-     void *closure;
>-     const char *data;
>-     int have;
>-     int *wrote;
>-{
>-    struct socket_buffer *sb = (struct socket_buffer *) closure;
>-
>-    *wrote = have;
>-
>-    /* See comment in socket_buffer_input regarding buffer size we pass
>-       to send and recv.  */
>-
>-#ifdef SEND_NEVER_PARTIAL
>-    /* If send() never will produce a partial write, then just do it.  This
>-       is needed for systems where its return value is something other than
>-       the number of bytes written.  */
>-    if (send (sb->socket, data, have, 0) < 0)
>-	error (1, 0, "writing to server socket: %s", SOCK_STRERROR (SOCK_ERRNO));
>-#else
>-    while (have > 0)
>-    {
>-	int nbytes;
>-
>-	nbytes = send (sb->socket, data, have, 0);
>-	if (nbytes < 0)
>-	    error (1, 0, "writing to server socket: %s", SOCK_STRERROR (SOCK_ERRNO));
>-
>-	have -= nbytes;
>-	data += nbytes;
>-    }
>-#endif
>-
>-    return 0;
>-}
>-
>-
>-
>-/* The buffer flush function for a buffer built on a socket.  */
>-
>-/*ARGSUSED*/
>-static int
>-socket_buffer_flush (closure)
>-     void *closure;
>-{
>-    /* Nothing to do.  Sockets are always flushed.  */
>-    return 0;
>-}
>-
>-
>-
>-static int
>-socket_buffer_shutdown (buf)
>-    struct buffer *buf;
>-{
>-    struct socket_buffer *n = (struct socket_buffer *) buf->closure;
>-    char tmp;
>-
>-    /* no need to flush children of an endpoint buffer here */
>-
>-    if (buf->input)
>-    {
>-	int err = 0;
>-	if (! buf_empty_p (buf)
>-	    || (err = recv (n->socket, &tmp, 1, 0)) > 0)
>-	    error (0, 0, "dying gasps from %s unexpected", current_parsed_root->hostname);
>-	else if (err == -1)
>-	    error (0, 0, "reading from %s: %s", current_parsed_root->hostname, SOCK_STRERROR (SOCK_ERRNO));
>-
>-	/* shutdown() socket */
>-# ifdef SHUTDOWN_SERVER
>-	if (current_parsed_root->method != server_method)
>-# endif
>-	if (shutdown (n->socket, 0) < 0)
>-	{
>-	    error (1, 0, "shutting down server socket: %s", SOCK_STRERROR (SOCK_ERRNO));
>-	}
>-
>-	buf->input = NULL;
>-    }
>-    else if (buf->output)
>-    {
>-	/* shutdown() socket */
>-# ifdef SHUTDOWN_SERVER
>-	/* FIXME:  Should have a SHUTDOWN_SERVER_INPUT &
>-	 * SHUTDOWN_SERVER_OUTPUT
>-	 */
>-	if (current_parsed_root->method == server_method)
>-	    SHUTDOWN_SERVER (n->socket);
>-	else
>-# endif
>-	if (shutdown (n->socket, 1) < 0)
>-	{
>-	    error (1, 0, "shutting down server socket: %s", SOCK_STRERROR (SOCK_ERRNO));
>-	}
>-
>-	buf->output = NULL;
>-    }
>-
>-    return 0;
>-}
>-
>-#endif /* NO_SOCKET_TO_FD */
> 
> /*
>  * Read a line from the server.  Result does not include the terminating \n.
>--- ccvs/src/Makefile.am~socket-client	Thu Apr 24 02:07:42 2003
>+++ ccvs-alexm/src/Makefile.am	Thu Apr 24 02:17:24 2003
>@@ -73,6 +73,7 @@ cvs_SOURCES = \
> 	run.c \
> 	scramble.c \
> 	server.c \
>+	socket-client.c socket-client.h \
> 	status.c \
> 	subr.c \
> 	tag.c \
>--- ccvs/src/Makefile.in~socket-client	Thu Apr 24 02:07:42 2003
>+++ ccvs-alexm/src/Makefile.in	Thu Apr 24 02:17:24 2003
>@@ -164,6 +164,7 @@ cvs_SOURCES = \
> 	run.c \
> 	scramble.c \
> 	server.c \
>+	socket-client.c socket-client.h \
> 	status.c \
> 	subr.c \
> 	tag.c \
>@@ -226,9 +227,10 @@ am_cvs_OBJECTS = add.$(OBJEXT) admin.$(O
> 	patch.$(OBJEXT) rcs.$(OBJEXT) rcscmds.$(OBJEXT) \
> 	recurse.$(OBJEXT) release.$(OBJEXT) remove.$(OBJEXT) \
> 	repos.$(OBJEXT) root.$(OBJEXT) run.$(OBJEXT) scramble.$(OBJEXT) \
>-	server.$(OBJEXT) status.$(OBJEXT) subr.$(OBJEXT) tag.$(OBJEXT) \
>-	update.$(OBJEXT) version.$(OBJEXT) vers_ts.$(OBJEXT) \
>-	watch.$(OBJEXT) wrapper.$(OBJEXT) zlib.$(OBJEXT)
>+	server.$(OBJEXT) socket-client.$(OBJEXT) status.$(OBJEXT) \
>+	subr.$(OBJEXT) tag.$(OBJEXT) update.$(OBJEXT) version.$(OBJEXT) \
>+	vers_ts.$(OBJEXT) watch.$(OBJEXT) wrapper.$(OBJEXT) \
>+	zlib.$(OBJEXT)
> cvs_OBJECTS = $(am_cvs_OBJECTS)
> cvs_DEPENDENCIES = ../diff/libdiff.a ../lib/libcvs.a ../zlib/libz.a
> cvs_LDFLAGS =
>@@ -264,11 +266,12 @@ am__depfiles_maybe = depfiles
> @AMDEP_TRUE@	./$(DEPDIR)/release.Po ./$(DEPDIR)/remove.Po \
> @AMDEP_TRUE@	./$(DEPDIR)/repos.Po ./$(DEPDIR)/root.Po \
> @AMDEP_TRUE@	./$(DEPDIR)/run.Po ./$(DEPDIR)/scramble.Po \
>-@AMDEP_TRUE@	./$(DEPDIR)/server.Po ./$(DEPDIR)/status.Po \
>-@AMDEP_TRUE@	./$(DEPDIR)/subr.Po ./$(DEPDIR)/tag.Po \
>-@AMDEP_TRUE@	./$(DEPDIR)/update.Po ./$(DEPDIR)/vers_ts.Po \
>-@AMDEP_TRUE@	./$(DEPDIR)/version.Po ./$(DEPDIR)/watch.Po \
>-@AMDEP_TRUE@	./$(DEPDIR)/wrapper.Po ./$(DEPDIR)/zlib.Po
>+@AMDEP_TRUE@	./$(DEPDIR)/server.Po ./$(DEPDIR)/socket-client.Po \
>+@AMDEP_TRUE@	./$(DEPDIR)/status.Po ./$(DEPDIR)/subr.Po \
>+@AMDEP_TRUE@	./$(DEPDIR)/tag.Po ./$(DEPDIR)/update.Po \
>+@AMDEP_TRUE@	./$(DEPDIR)/vers_ts.Po ./$(DEPDIR)/version.Po \
>+@AMDEP_TRUE@	./$(DEPDIR)/watch.Po ./$(DEPDIR)/wrapper.Po \
>+@AMDEP_TRUE@	./$(DEPDIR)/zlib.Po
> COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
> 	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
> CCLD = $(CC)
>@@ -391,6 +394,7 @@ distclean-compile:
> @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run.Po@am__quote@
> @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scramble.Po@am__quote@
> @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/server.Po@am__quote@
>+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/socket-client.Po@am__quote@
> @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/status.Po@am__quote@
> @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/subr.Po@am__quote@
> @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tag.Po@am__quote@
>--- /dev/null	Wed Jan  1 02:48:46 2003
>+++ ccvs-alexm/src/socket-client.c	Thu Apr 24 02:07:42 2003
>@@ -0,0 +1,246 @@
>+/* CVS socket client stuff.
>+
>+   This program is free software; you can redistribute it and/or modify
>+   it under the terms of the GNU General Public License as published by
>+   the Free Software Foundation; either version 2, or (at your option)
>+   any later version.
>+
>+   This program is distributed in the hope that it will be useful,
>+   but WITHOUT ANY WARRANTY; without even the implied warranty of
>+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>+   GNU General Public License for more details.  */
>+
>+#include <config.h>
>+
>+#include "cvs.h"
>+
>+#include "socket-client.h"
>+
>+#ifdef NO_SOCKET_TO_FD
>+
>+/* Under certain circumstances, we must communicate with the server
>+   via a socket using send() and recv().  This is because under some
>+   operating systems (OS/2 and Windows 95 come to mind), a socket
>+   cannot be converted to a file descriptor -- it must be treated as a
>+   socket and nothing else.
>+   
>+   We may also need to deal with socket routine error codes differently
>+   in these cases.  This is handled through the SOCK_ERRNO and
>+   SOCK_STRERROR macros. */
>+
>+/* These routines implement a buffer structure which uses send and
>+   recv.  The buffer is always in blocking mode so we don't implement
>+   the block routine.  */
>+
>+/* Note that it is important that these routines always handle errors
>+   internally and never return a positive errno code, since it would in
>+   general be impossible for the caller to know in general whether any
>+   error code came from a socket routine (to decide whether to use
>+   SOCK_STRERROR or simply strerror to print an error message). */
>+
>+/* We use an instance of this structure as the closure field.  */
>+
>+struct socket_buffer
>+{
>+    /* The socket number.  */
>+    int socket;
>+};
>+
>+static int socket_buffer_input PROTO((void *, char *, int, int, int *));
>+static int socket_buffer_output PROTO((void *, const char *, int, int *));
>+static int socket_buffer_flush PROTO((void *));
>+static int socket_buffer_shutdown PROTO((struct buffer *));
>+
>+
>+
>+/* Create a buffer based on a socket.  */
>+
>+static struct buffer *
>+socket_buffer_initialize (socket, input, memory)
>+    int socket;
>+    int input;
>+    void (*memory) PROTO((struct buffer *));
>+{
>+    struct socket_buffer *n;
>+
>+    n = (struct socket_buffer *) xmalloc (sizeof *n);
>+    n->socket = socket;
>+    return buf_initialize (input ? socket_buffer_input : NULL,
>+			   input ? NULL : socket_buffer_output,
>+			   input ? NULL : socket_buffer_flush,
>+			   (int (*) PROTO((void *, int))) NULL,
>+			   socket_buffer_shutdown,
>+			   memory,
>+			   n);
>+}
>+
>+
>+
>+/* The buffer input function for a buffer built on a socket.  */
>+
>+static int
>+socket_buffer_input (closure, data, need, size, got)
>+     void *closure;
>+     char *data;
>+     int need;
>+     int size;
>+     int *got;
>+{
>+    struct socket_buffer *sb = (struct socket_buffer *) closure;
>+    int nbytes;
>+
>+    /* I believe that the recv function gives us exactly the semantics
>+       we want.  If there is a message, it returns immediately with
>+       whatever it could get.  If there is no message, it waits until
>+       one comes in.  In other words, it is not like read, which in
>+       blocking mode normally waits until all the requested data is
>+       available.  */
>+
>+    *got = 0;
>+
>+    do
>+    {
>+
>+	/* Note that for certain (broken?) networking stacks, like
>+	   VMS's UCX (not sure what version, problem reported with
>+	   recv() in 1997), and (according to windows-NT/config.h)
>+	   Windows NT 3.51, we must call recv or send with a
>+	   moderately sized buffer (say, less than 200K or something),
>+	   or else there may be network errors (somewhat hard to
>+	   produce, e.g. WAN not LAN or some such).  buf_read_data
>+	   makes sure that we only recv() BUFFER_DATA_SIZE bytes at
>+	   a time.  */
>+
>+	nbytes = recv (sb->socket, data, size, 0);
>+	if (nbytes < 0)
>+	    error (1, 0, "reading from server: %s", SOCK_STRERROR (SOCK_ERRNO));
>+	if (nbytes == 0)
>+	{
>+	    /* End of file (for example, the server has closed
>+	       the connection).  If we've already read something, we
>+	       just tell the caller about the data, not about the end of
>+	       file.  If we've read nothing, we return end of file.  */
>+	    if (*got == 0)
>+		return -1;
>+	    else
>+		return 0;
>+	}
>+	need -= nbytes;
>+	size -= nbytes;
>+	data += nbytes;
>+	*got += nbytes;
>+    }
>+    while (need > 0);
>+
>+    return 0;
>+}
>+
>+
>+
>+/* The buffer output function for a buffer built on a socket.  */
>+
>+static int
>+socket_buffer_output (closure, data, have, wrote)
>+     void *closure;
>+     const char *data;
>+     int have;
>+     int *wrote;
>+{
>+    struct socket_buffer *sb = (struct socket_buffer *) closure;
>+
>+    *wrote = have;
>+
>+    /* See comment in socket_buffer_input regarding buffer size we pass
>+       to send and recv.  */
>+
>+#ifdef SEND_NEVER_PARTIAL
>+    /* If send() never will produce a partial write, then just do it.  This
>+       is needed for systems where its return value is something other than
>+       the number of bytes written.  */
>+    if (send (sb->socket, data, have, 0) < 0)
>+	error (1, 0, "writing to server socket: %s", SOCK_STRERROR (SOCK_ERRNO));
>+#else
>+    while (have > 0)
>+    {
>+	int nbytes;
>+
>+	nbytes = send (sb->socket, data, have, 0);
>+	if (nbytes < 0)
>+	    error (1, 0, "writing to server socket: %s", SOCK_STRERROR (SOCK_ERRNO));
>+
>+	have -= nbytes;
>+	data += nbytes;
>+    }
>+#endif
>+
>+    return 0;
>+}
>+
>+
>+
>+/* The buffer flush function for a buffer built on a socket.  */
>+
>+/*ARGSUSED*/
>+static int
>+socket_buffer_flush (closure)
>+     void *closure;
>+{
>+    /* Nothing to do.  Sockets are always flushed.  */
>+    return 0;
>+}
>+
>+
>+
>+static int
>+socket_buffer_shutdown (buf)
>+    struct buffer *buf;
>+{
>+    struct socket_buffer *n = (struct socket_buffer *) buf->closure;
>+    char tmp;
>+
>+    /* no need to flush children of an endpoint buffer here */
>+
>+    if (buf->input)
>+    {
>+	int err = 0;
>+	if (! buf_empty_p (buf)
>+	    || (err = recv (n->socket, &tmp, 1, 0)) > 0)
>+	    error (0, 0, "dying gasps from %s unexpected", current_parsed_root->hostname);
>+	else if (err == -1)
>+	    error (0, 0, "reading from %s: %s", current_parsed_root->hostname, SOCK_STRERROR (SOCK_ERRNO));
>+
>+	/* shutdown() socket */
>+# ifdef SHUTDOWN_SERVER
>+	if (current_parsed_root->method != server_method)
>+# endif
>+	if (shutdown (n->socket, 0) < 0)
>+	{
>+	    error (1, 0, "shutting down server socket: %s", SOCK_STRERROR (SOCK_ERRNO));
>+	}
>+
>+	buf->input = NULL;
>+    }
>+    else if (buf->output)
>+    {
>+	/* shutdown() socket */
>+# ifdef SHUTDOWN_SERVER
>+	/* FIXME:  Should have a SHUTDOWN_SERVER_INPUT &
>+	 * SHUTDOWN_SERVER_OUTPUT
>+	 */
>+	if (current_parsed_root->method == server_method)
>+	    SHUTDOWN_SERVER (n->socket);
>+	else
>+# endif
>+	if (shutdown (n->socket, 1) < 0)
>+	{
>+	    error (1, 0, "shutting down server socket: %s", SOCK_STRERROR (SOCK_ERRNO));
>+	}
>+
>+	buf->output = NULL;
>+    }
>+
>+    return 0;
>+}
>+
>+#endif /* NO_SOCKET_TO_FD */
>+
>--- /dev/null	Wed Jan  1 02:48:46 2003
>+++ ccvs-alexm/src/socket-client.h	Thu Apr 24 02:18:54 2003
>@@ -0,0 +1,55 @@
>+/* CVS socket client stuff.
>+
>+   This program is free software; you can redistribute it and/or modify
>+   it under the terms of the GNU General Public License as published by
>+   the Free Software Foundation; either version 2, or (at your option)
>+   any later version.
>+
>+   This program is distributed in the hope that it will be useful,
>+   but WITHOUT ANY WARRANTY; without even the implied warranty of
>+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>+   GNU General Public License for more details.  */
>+
>+#ifndef SOCKET_CLIENT_H__
>+#define SOCKET_CLIENT_H__ 1
>+
>+#include <config.h>
>+
>+struct buffer *socket_buffer_initialize
>+  PROTO ((int, int, void (*) (struct buffer *)));
>+
>+# if defined(AUTH_CLIENT_SUPPORT) || defined(HAVE_KERBEROS) || defined(HAVE_GSSAPI) || defined(SOCK_ERRNO) || defined(SOCK_STRERROR)
>+#   ifdef HAVE_WINSOCK_H
>+#     include <winsock.h>
>+#   else /* No winsock.h */
>+#     include <sys/socket.h>
>+#     include <netinet/in.h>
>+#     include <arpa/inet.h>
>+#     include <netdb.h>
>+#   endif /* No winsock.h */
>+# endif
>+
>+/* If SOCK_ERRNO is defined, then send()/recv() and other socket calls
>+   do not set errno, but that this macro should be used to obtain an
>+   error code.  This probably doesn't make sense unless
>+   NO_SOCKET_TO_FD is also defined. */
>+# ifndef SOCK_ERRNO
>+#   define SOCK_ERRNO errno
>+# endif
>+
>+/* If SOCK_STRERROR is defined, then the error codes returned by
>+   socket operations are not known to strerror, and this macro must be
>+   used instead to convert those error codes to strings. */
>+# ifndef SOCK_STRERROR
>+#   define SOCK_STRERROR strerror
>+
>+#   if STDC_HEADERS
>+#     include <string.h>
>+#   endif
>+
>+#   ifndef strerror
>+extern char *strerror ();
>+#   endif
>+# endif /* ! SOCK_STRERROR */
>+
>+#endif SOCKET_CLIENT_H__
>
>_
>
>
>--alexm
>
>  
>

-- 
                *8^)

Email: [email protected]

Get CVS support at <http://ximbiot.com>!
-- 
Tis better to be thought a fool, than to open your mouth and
remove all doubt.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.