186d7f5d3SJohn Marino /* CVS socket client stuff.
286d7f5d3SJohn Marino
386d7f5d3SJohn Marino This program is free software; you can redistribute it and/or modify
486d7f5d3SJohn Marino it under the terms of the GNU General Public License as published by
586d7f5d3SJohn Marino the Free Software Foundation; either version 2, or (at your option)
686d7f5d3SJohn Marino any later version.
786d7f5d3SJohn Marino
886d7f5d3SJohn Marino This program is distributed in the hope that it will be useful,
986d7f5d3SJohn Marino but WITHOUT ANY WARRANTY; without even the implied warranty of
1086d7f5d3SJohn Marino MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1186d7f5d3SJohn Marino GNU General Public License for more details. */
1286d7f5d3SJohn Marino
1386d7f5d3SJohn Marino /***
1486d7f5d3SJohn Marino *** THIS FILE SHOULD NEVER BE COMPILED UNLESS NO_SOCKET_TO_FD IS DEFINED.
1586d7f5d3SJohn Marino ***/
1686d7f5d3SJohn Marino
1786d7f5d3SJohn Marino #ifdef HAVE_CONFIG_H
1886d7f5d3SJohn Marino # include <config.h>
1986d7f5d3SJohn Marino #endif
2086d7f5d3SJohn Marino
2186d7f5d3SJohn Marino #ifdef CLIENT_SUPPORT
2286d7f5d3SJohn Marino
2386d7f5d3SJohn Marino #include "cvs.h"
2486d7f5d3SJohn Marino #include "buffer.h"
2586d7f5d3SJohn Marino
2686d7f5d3SJohn Marino #include "socket-client.h"
2786d7f5d3SJohn Marino
2886d7f5d3SJohn Marino
2986d7f5d3SJohn Marino /* Under certain circumstances, we must communicate with the server
3086d7f5d3SJohn Marino via a socket using send() and recv(). This is because under some
3186d7f5d3SJohn Marino operating systems (OS/2 and Windows 95 come to mind), a socket
3286d7f5d3SJohn Marino cannot be converted to a file descriptor -- it must be treated as a
3386d7f5d3SJohn Marino socket and nothing else.
3486d7f5d3SJohn Marino
3586d7f5d3SJohn Marino We may also need to deal with socket routine error codes differently
3686d7f5d3SJohn Marino in these cases. This is handled through the SOCK_ERRNO and
3786d7f5d3SJohn Marino SOCK_STRERROR macros. */
3886d7f5d3SJohn Marino
3986d7f5d3SJohn Marino /* These routines implement a buffer structure which uses send and
4086d7f5d3SJohn Marino recv. The buffer is always in blocking mode so we don't implement
4186d7f5d3SJohn Marino the block routine. */
4286d7f5d3SJohn Marino
4386d7f5d3SJohn Marino /* Note that it is important that these routines always handle errors
4486d7f5d3SJohn Marino internally and never return a positive errno code, since it would in
4586d7f5d3SJohn Marino general be impossible for the caller to know in general whether any
4686d7f5d3SJohn Marino error code came from a socket routine (to decide whether to use
4786d7f5d3SJohn Marino SOCK_STRERROR or simply strerror to print an error message). */
4886d7f5d3SJohn Marino
4986d7f5d3SJohn Marino /* We use an instance of this structure as the closure field. */
5086d7f5d3SJohn Marino
5186d7f5d3SJohn Marino struct socket_buffer
5286d7f5d3SJohn Marino {
5386d7f5d3SJohn Marino /* The socket number. */
5486d7f5d3SJohn Marino int socket;
5586d7f5d3SJohn Marino };
5686d7f5d3SJohn Marino
5786d7f5d3SJohn Marino
5886d7f5d3SJohn Marino
5986d7f5d3SJohn Marino /* The buffer input function for a buffer built on a socket. */
6086d7f5d3SJohn Marino
6186d7f5d3SJohn Marino static int
socket_buffer_input(void * closure,char * data,size_t need,size_t size,size_t * got)6286d7f5d3SJohn Marino socket_buffer_input (void *closure, char *data, size_t need, size_t size,
6386d7f5d3SJohn Marino size_t *got)
6486d7f5d3SJohn Marino {
6586d7f5d3SJohn Marino struct socket_buffer *sb = closure;
6686d7f5d3SJohn Marino int nbytes;
6786d7f5d3SJohn Marino
6886d7f5d3SJohn Marino /* I believe that the recv function gives us exactly the semantics
6986d7f5d3SJohn Marino we want. If there is a message, it returns immediately with
7086d7f5d3SJohn Marino whatever it could get. If there is no message, it waits until
7186d7f5d3SJohn Marino one comes in. In other words, it is not like read, which in
7286d7f5d3SJohn Marino blocking mode normally waits until all the requested data is
7386d7f5d3SJohn Marino available. */
7486d7f5d3SJohn Marino
7586d7f5d3SJohn Marino assert (size >= need);
7686d7f5d3SJohn Marino
7786d7f5d3SJohn Marino *got = 0;
7886d7f5d3SJohn Marino
7986d7f5d3SJohn Marino do
8086d7f5d3SJohn Marino {
8186d7f5d3SJohn Marino
8286d7f5d3SJohn Marino /* Note that for certain (broken?) networking stacks, like
8386d7f5d3SJohn Marino VMS's UCX (not sure what version, problem reported with
8486d7f5d3SJohn Marino recv() in 1997), and (according to windows-NT/config.h)
8586d7f5d3SJohn Marino Windows NT 3.51, we must call recv or send with a
8686d7f5d3SJohn Marino moderately sized buffer (say, less than 200K or something),
8786d7f5d3SJohn Marino or else there may be network errors (somewhat hard to
8886d7f5d3SJohn Marino produce, e.g. WAN not LAN or some such). buf_read_data
8986d7f5d3SJohn Marino makes sure that we only recv() BUFFER_DATA_SIZE bytes at
9086d7f5d3SJohn Marino a time. */
9186d7f5d3SJohn Marino
9286d7f5d3SJohn Marino nbytes = recv (sb->socket, data + *got, size - *got, 0);
9386d7f5d3SJohn Marino if (nbytes < 0)
9486d7f5d3SJohn Marino error (1, 0, "reading from server: %s",
9586d7f5d3SJohn Marino SOCK_STRERROR (SOCK_ERRNO));
9686d7f5d3SJohn Marino if (nbytes == 0)
9786d7f5d3SJohn Marino {
9886d7f5d3SJohn Marino /* End of file (for example, the server has closed
9986d7f5d3SJohn Marino the connection). If we've already read something, we
10086d7f5d3SJohn Marino just tell the caller about the data, not about the end of
10186d7f5d3SJohn Marino file. If we've read nothing, we return end of file. */
10286d7f5d3SJohn Marino if (*got == 0)
10386d7f5d3SJohn Marino return -1;
10486d7f5d3SJohn Marino else
10586d7f5d3SJohn Marino return 0;
10686d7f5d3SJohn Marino }
10786d7f5d3SJohn Marino *got += nbytes;
10886d7f5d3SJohn Marino }
10986d7f5d3SJohn Marino while (*got < need);
11086d7f5d3SJohn Marino
11186d7f5d3SJohn Marino return 0;
11286d7f5d3SJohn Marino }
11386d7f5d3SJohn Marino
11486d7f5d3SJohn Marino
11586d7f5d3SJohn Marino
11686d7f5d3SJohn Marino /* The buffer output function for a buffer built on a socket. */
11786d7f5d3SJohn Marino
11886d7f5d3SJohn Marino static int
socket_buffer_output(void * closure,const char * data,size_t have,size_t * wrote)11986d7f5d3SJohn Marino socket_buffer_output (void *closure, const char *data, size_t have,
12086d7f5d3SJohn Marino size_t *wrote)
12186d7f5d3SJohn Marino {
12286d7f5d3SJohn Marino struct socket_buffer *sb = closure;
12386d7f5d3SJohn Marino
12486d7f5d3SJohn Marino *wrote = have;
12586d7f5d3SJohn Marino
12686d7f5d3SJohn Marino /* See comment in socket_buffer_input regarding buffer size we pass
12786d7f5d3SJohn Marino to send and recv. */
12886d7f5d3SJohn Marino
12986d7f5d3SJohn Marino # ifdef SEND_NEVER_PARTIAL
13086d7f5d3SJohn Marino /* If send() never will produce a partial write, then just do it. This
13186d7f5d3SJohn Marino is needed for systems where its return value is something other than
13286d7f5d3SJohn Marino the number of bytes written. */
13386d7f5d3SJohn Marino if (send (sb->socket, data, have, 0) < 0)
13486d7f5d3SJohn Marino error (1, 0, "writing to server socket: %s",
13586d7f5d3SJohn Marino SOCK_STRERROR (SOCK_ERRNO));
13686d7f5d3SJohn Marino # else
13786d7f5d3SJohn Marino while (have > 0)
13886d7f5d3SJohn Marino {
13986d7f5d3SJohn Marino int nbytes;
14086d7f5d3SJohn Marino
14186d7f5d3SJohn Marino nbytes = send (sb->socket, data, have, 0);
14286d7f5d3SJohn Marino if (nbytes < 0)
14386d7f5d3SJohn Marino error (1, 0, "writing to server socket: %s",
14486d7f5d3SJohn Marino SOCK_STRERROR (SOCK_ERRNO));
14586d7f5d3SJohn Marino
14686d7f5d3SJohn Marino have -= nbytes;
14786d7f5d3SJohn Marino data += nbytes;
14886d7f5d3SJohn Marino }
14986d7f5d3SJohn Marino # endif
15086d7f5d3SJohn Marino
15186d7f5d3SJohn Marino return 0;
15286d7f5d3SJohn Marino }
15386d7f5d3SJohn Marino
15486d7f5d3SJohn Marino
15586d7f5d3SJohn Marino
15686d7f5d3SJohn Marino /* The buffer flush function for a buffer built on a socket. */
15786d7f5d3SJohn Marino
15886d7f5d3SJohn Marino /*ARGSUSED*/
15986d7f5d3SJohn Marino static int
socket_buffer_flush(void * closure)16086d7f5d3SJohn Marino socket_buffer_flush (void *closure)
16186d7f5d3SJohn Marino {
16286d7f5d3SJohn Marino /* Nothing to do. Sockets are always flushed. */
16386d7f5d3SJohn Marino return 0;
16486d7f5d3SJohn Marino }
16586d7f5d3SJohn Marino
16686d7f5d3SJohn Marino
16786d7f5d3SJohn Marino
16886d7f5d3SJohn Marino static int
socket_buffer_shutdown(struct buffer * buf)16986d7f5d3SJohn Marino socket_buffer_shutdown (struct buffer *buf)
17086d7f5d3SJohn Marino {
17186d7f5d3SJohn Marino struct socket_buffer *n = buf->closure;
17286d7f5d3SJohn Marino char tmp;
17386d7f5d3SJohn Marino
17486d7f5d3SJohn Marino /* no need to flush children of an endpoint buffer here */
17586d7f5d3SJohn Marino
17686d7f5d3SJohn Marino if (buf->input)
17786d7f5d3SJohn Marino {
17886d7f5d3SJohn Marino int err = 0;
17986d7f5d3SJohn Marino if (! buf_empty_p (buf)
18086d7f5d3SJohn Marino || (err = recv (n->socket, &tmp, 1, 0)) > 0)
18186d7f5d3SJohn Marino error (0, 0, "dying gasps from %s unexpected",
18286d7f5d3SJohn Marino current_parsed_root->hostname);
18386d7f5d3SJohn Marino else if (err == -1)
18486d7f5d3SJohn Marino error (0, 0, "reading from %s: %s", current_parsed_root->hostname,
18586d7f5d3SJohn Marino SOCK_STRERROR (SOCK_ERRNO));
18686d7f5d3SJohn Marino
18786d7f5d3SJohn Marino /* shutdown() socket */
18886d7f5d3SJohn Marino # ifdef SHUTDOWN_SERVER
18986d7f5d3SJohn Marino if (current_parsed_root->method != server_method)
19086d7f5d3SJohn Marino # endif
19186d7f5d3SJohn Marino if (shutdown (n->socket, 0) < 0)
19286d7f5d3SJohn Marino {
19386d7f5d3SJohn Marino error (1, 0, "shutting down server socket: %s",
19486d7f5d3SJohn Marino SOCK_STRERROR (SOCK_ERRNO));
19586d7f5d3SJohn Marino }
19686d7f5d3SJohn Marino
19786d7f5d3SJohn Marino buf->input = NULL;
19886d7f5d3SJohn Marino }
19986d7f5d3SJohn Marino else if (buf->output)
20086d7f5d3SJohn Marino {
20186d7f5d3SJohn Marino /* shutdown() socket */
20286d7f5d3SJohn Marino # ifdef SHUTDOWN_SERVER
20386d7f5d3SJohn Marino /* FIXME: Should have a SHUTDOWN_SERVER_INPUT &
20486d7f5d3SJohn Marino * SHUTDOWN_SERVER_OUTPUT
20586d7f5d3SJohn Marino */
20686d7f5d3SJohn Marino if (current_parsed_root->method == server_method)
20786d7f5d3SJohn Marino SHUTDOWN_SERVER (n->socket);
20886d7f5d3SJohn Marino else
20986d7f5d3SJohn Marino # endif
21086d7f5d3SJohn Marino if (shutdown (n->socket, 1) < 0)
21186d7f5d3SJohn Marino {
21286d7f5d3SJohn Marino error (1, 0, "shutting down server socket: %s",
21386d7f5d3SJohn Marino SOCK_STRERROR (SOCK_ERRNO));
21486d7f5d3SJohn Marino }
21586d7f5d3SJohn Marino
21686d7f5d3SJohn Marino buf->output = NULL;
21786d7f5d3SJohn Marino }
21886d7f5d3SJohn Marino
21986d7f5d3SJohn Marino return 0;
22086d7f5d3SJohn Marino }
22186d7f5d3SJohn Marino
22286d7f5d3SJohn Marino
22386d7f5d3SJohn Marino
22486d7f5d3SJohn Marino /* Create a buffer based on a socket. */
22586d7f5d3SJohn Marino
22686d7f5d3SJohn Marino struct buffer *
socket_buffer_initialize(int socket,int input,void (* memory)(struct buffer *))22786d7f5d3SJohn Marino socket_buffer_initialize (int socket, int input,
22886d7f5d3SJohn Marino void (*memory) (struct buffer *))
22986d7f5d3SJohn Marino {
23086d7f5d3SJohn Marino struct socket_buffer *sbuf = xmalloc (sizeof *sbuf);
23186d7f5d3SJohn Marino sbuf->socket = socket;
23286d7f5d3SJohn Marino return buf_initialize (input ? socket_buffer_input : NULL,
23386d7f5d3SJohn Marino input ? NULL : socket_buffer_output,
23486d7f5d3SJohn Marino input ? NULL : socket_buffer_flush,
23586d7f5d3SJohn Marino NULL, NULL,
23686d7f5d3SJohn Marino socket_buffer_shutdown,
23786d7f5d3SJohn Marino memory,
23886d7f5d3SJohn Marino sbuf);
23986d7f5d3SJohn Marino }
24086d7f5d3SJohn Marino
24186d7f5d3SJohn Marino #endif /* CLIENT_SUPPORT */
242