1*86d7f5d3SJohn Marino /* CVS socket client stuff.
2*86d7f5d3SJohn Marino
3*86d7f5d3SJohn Marino This program is free software; you can redistribute it and/or modify
4*86d7f5d3SJohn Marino it under the terms of the GNU General Public License as published by
5*86d7f5d3SJohn Marino the Free Software Foundation; either version 2, or (at your option)
6*86d7f5d3SJohn Marino any later version.
7*86d7f5d3SJohn Marino
8*86d7f5d3SJohn Marino This program is distributed in the hope that it will be useful,
9*86d7f5d3SJohn Marino but WITHOUT ANY WARRANTY; without even the implied warranty of
10*86d7f5d3SJohn Marino MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11*86d7f5d3SJohn Marino GNU General Public License for more details. */
12*86d7f5d3SJohn Marino
13*86d7f5d3SJohn Marino /***
14*86d7f5d3SJohn Marino *** THIS FILE SHOULD NEVER BE COMPILED UNLESS NO_SOCKET_TO_FD IS DEFINED.
15*86d7f5d3SJohn Marino ***/
16*86d7f5d3SJohn Marino
17*86d7f5d3SJohn Marino #ifdef HAVE_CONFIG_H
18*86d7f5d3SJohn Marino # include <config.h>
19*86d7f5d3SJohn Marino #endif
20*86d7f5d3SJohn Marino
21*86d7f5d3SJohn Marino #ifdef CLIENT_SUPPORT
22*86d7f5d3SJohn Marino
23*86d7f5d3SJohn Marino #include "cvs.h"
24*86d7f5d3SJohn Marino #include "buffer.h"
25*86d7f5d3SJohn Marino
26*86d7f5d3SJohn Marino #include "socket-client.h"
27*86d7f5d3SJohn Marino
28*86d7f5d3SJohn Marino
29*86d7f5d3SJohn Marino /* Under certain circumstances, we must communicate with the server
30*86d7f5d3SJohn Marino via a socket using send() and recv(). This is because under some
31*86d7f5d3SJohn Marino operating systems (OS/2 and Windows 95 come to mind), a socket
32*86d7f5d3SJohn Marino cannot be converted to a file descriptor -- it must be treated as a
33*86d7f5d3SJohn Marino socket and nothing else.
34*86d7f5d3SJohn Marino
35*86d7f5d3SJohn Marino We may also need to deal with socket routine error codes differently
36*86d7f5d3SJohn Marino in these cases. This is handled through the SOCK_ERRNO and
37*86d7f5d3SJohn Marino SOCK_STRERROR macros. */
38*86d7f5d3SJohn Marino
39*86d7f5d3SJohn Marino /* These routines implement a buffer structure which uses send and
40*86d7f5d3SJohn Marino recv. The buffer is always in blocking mode so we don't implement
41*86d7f5d3SJohn Marino the block routine. */
42*86d7f5d3SJohn Marino
43*86d7f5d3SJohn Marino /* Note that it is important that these routines always handle errors
44*86d7f5d3SJohn Marino internally and never return a positive errno code, since it would in
45*86d7f5d3SJohn Marino general be impossible for the caller to know in general whether any
46*86d7f5d3SJohn Marino error code came from a socket routine (to decide whether to use
47*86d7f5d3SJohn Marino SOCK_STRERROR or simply strerror to print an error message). */
48*86d7f5d3SJohn Marino
49*86d7f5d3SJohn Marino /* We use an instance of this structure as the closure field. */
50*86d7f5d3SJohn Marino
51*86d7f5d3SJohn Marino struct socket_buffer
52*86d7f5d3SJohn Marino {
53*86d7f5d3SJohn Marino /* The socket number. */
54*86d7f5d3SJohn Marino int socket;
55*86d7f5d3SJohn Marino };
56*86d7f5d3SJohn Marino
57*86d7f5d3SJohn Marino
58*86d7f5d3SJohn Marino
59*86d7f5d3SJohn Marino /* The buffer input function for a buffer built on a socket. */
60*86d7f5d3SJohn Marino
61*86d7f5d3SJohn Marino static int
socket_buffer_input(void * closure,char * data,size_t need,size_t size,size_t * got)62*86d7f5d3SJohn Marino socket_buffer_input (void *closure, char *data, size_t need, size_t size,
63*86d7f5d3SJohn Marino size_t *got)
64*86d7f5d3SJohn Marino {
65*86d7f5d3SJohn Marino struct socket_buffer *sb = closure;
66*86d7f5d3SJohn Marino int nbytes;
67*86d7f5d3SJohn Marino
68*86d7f5d3SJohn Marino /* I believe that the recv function gives us exactly the semantics
69*86d7f5d3SJohn Marino we want. If there is a message, it returns immediately with
70*86d7f5d3SJohn Marino whatever it could get. If there is no message, it waits until
71*86d7f5d3SJohn Marino one comes in. In other words, it is not like read, which in
72*86d7f5d3SJohn Marino blocking mode normally waits until all the requested data is
73*86d7f5d3SJohn Marino available. */
74*86d7f5d3SJohn Marino
75*86d7f5d3SJohn Marino assert (size >= need);
76*86d7f5d3SJohn Marino
77*86d7f5d3SJohn Marino *got = 0;
78*86d7f5d3SJohn Marino
79*86d7f5d3SJohn Marino do
80*86d7f5d3SJohn Marino {
81*86d7f5d3SJohn Marino
82*86d7f5d3SJohn Marino /* Note that for certain (broken?) networking stacks, like
83*86d7f5d3SJohn Marino VMS's UCX (not sure what version, problem reported with
84*86d7f5d3SJohn Marino recv() in 1997), and (according to windows-NT/config.h)
85*86d7f5d3SJohn Marino Windows NT 3.51, we must call recv or send with a
86*86d7f5d3SJohn Marino moderately sized buffer (say, less than 200K or something),
87*86d7f5d3SJohn Marino or else there may be network errors (somewhat hard to
88*86d7f5d3SJohn Marino produce, e.g. WAN not LAN or some such). buf_read_data
89*86d7f5d3SJohn Marino makes sure that we only recv() BUFFER_DATA_SIZE bytes at
90*86d7f5d3SJohn Marino a time. */
91*86d7f5d3SJohn Marino
92*86d7f5d3SJohn Marino nbytes = recv (sb->socket, data + *got, size - *got, 0);
93*86d7f5d3SJohn Marino if (nbytes < 0)
94*86d7f5d3SJohn Marino error (1, 0, "reading from server: %s",
95*86d7f5d3SJohn Marino SOCK_STRERROR (SOCK_ERRNO));
96*86d7f5d3SJohn Marino if (nbytes == 0)
97*86d7f5d3SJohn Marino {
98*86d7f5d3SJohn Marino /* End of file (for example, the server has closed
99*86d7f5d3SJohn Marino the connection). If we've already read something, we
100*86d7f5d3SJohn Marino just tell the caller about the data, not about the end of
101*86d7f5d3SJohn Marino file. If we've read nothing, we return end of file. */
102*86d7f5d3SJohn Marino if (*got == 0)
103*86d7f5d3SJohn Marino return -1;
104*86d7f5d3SJohn Marino else
105*86d7f5d3SJohn Marino return 0;
106*86d7f5d3SJohn Marino }
107*86d7f5d3SJohn Marino *got += nbytes;
108*86d7f5d3SJohn Marino }
109*86d7f5d3SJohn Marino while (*got < need);
110*86d7f5d3SJohn Marino
111*86d7f5d3SJohn Marino return 0;
112*86d7f5d3SJohn Marino }
113*86d7f5d3SJohn Marino
114*86d7f5d3SJohn Marino
115*86d7f5d3SJohn Marino
116*86d7f5d3SJohn Marino /* The buffer output function for a buffer built on a socket. */
117*86d7f5d3SJohn Marino
118*86d7f5d3SJohn Marino static int
socket_buffer_output(void * closure,const char * data,size_t have,size_t * wrote)119*86d7f5d3SJohn Marino socket_buffer_output (void *closure, const char *data, size_t have,
120*86d7f5d3SJohn Marino size_t *wrote)
121*86d7f5d3SJohn Marino {
122*86d7f5d3SJohn Marino struct socket_buffer *sb = closure;
123*86d7f5d3SJohn Marino
124*86d7f5d3SJohn Marino *wrote = have;
125*86d7f5d3SJohn Marino
126*86d7f5d3SJohn Marino /* See comment in socket_buffer_input regarding buffer size we pass
127*86d7f5d3SJohn Marino to send and recv. */
128*86d7f5d3SJohn Marino
129*86d7f5d3SJohn Marino # ifdef SEND_NEVER_PARTIAL
130*86d7f5d3SJohn Marino /* If send() never will produce a partial write, then just do it. This
131*86d7f5d3SJohn Marino is needed for systems where its return value is something other than
132*86d7f5d3SJohn Marino the number of bytes written. */
133*86d7f5d3SJohn Marino if (send (sb->socket, data, have, 0) < 0)
134*86d7f5d3SJohn Marino error (1, 0, "writing to server socket: %s",
135*86d7f5d3SJohn Marino SOCK_STRERROR (SOCK_ERRNO));
136*86d7f5d3SJohn Marino # else
137*86d7f5d3SJohn Marino while (have > 0)
138*86d7f5d3SJohn Marino {
139*86d7f5d3SJohn Marino int nbytes;
140*86d7f5d3SJohn Marino
141*86d7f5d3SJohn Marino nbytes = send (sb->socket, data, have, 0);
142*86d7f5d3SJohn Marino if (nbytes < 0)
143*86d7f5d3SJohn Marino error (1, 0, "writing to server socket: %s",
144*86d7f5d3SJohn Marino SOCK_STRERROR (SOCK_ERRNO));
145*86d7f5d3SJohn Marino
146*86d7f5d3SJohn Marino have -= nbytes;
147*86d7f5d3SJohn Marino data += nbytes;
148*86d7f5d3SJohn Marino }
149*86d7f5d3SJohn Marino # endif
150*86d7f5d3SJohn Marino
151*86d7f5d3SJohn Marino return 0;
152*86d7f5d3SJohn Marino }
153*86d7f5d3SJohn Marino
154*86d7f5d3SJohn Marino
155*86d7f5d3SJohn Marino
156*86d7f5d3SJohn Marino /* The buffer flush function for a buffer built on a socket. */
157*86d7f5d3SJohn Marino
158*86d7f5d3SJohn Marino /*ARGSUSED*/
159*86d7f5d3SJohn Marino static int
socket_buffer_flush(void * closure)160*86d7f5d3SJohn Marino socket_buffer_flush (void *closure)
161*86d7f5d3SJohn Marino {
162*86d7f5d3SJohn Marino /* Nothing to do. Sockets are always flushed. */
163*86d7f5d3SJohn Marino return 0;
164*86d7f5d3SJohn Marino }
165*86d7f5d3SJohn Marino
166*86d7f5d3SJohn Marino
167*86d7f5d3SJohn Marino
168*86d7f5d3SJohn Marino static int
socket_buffer_shutdown(struct buffer * buf)169*86d7f5d3SJohn Marino socket_buffer_shutdown (struct buffer *buf)
170*86d7f5d3SJohn Marino {
171*86d7f5d3SJohn Marino struct socket_buffer *n = buf->closure;
172*86d7f5d3SJohn Marino char tmp;
173*86d7f5d3SJohn Marino
174*86d7f5d3SJohn Marino /* no need to flush children of an endpoint buffer here */
175*86d7f5d3SJohn Marino
176*86d7f5d3SJohn Marino if (buf->input)
177*86d7f5d3SJohn Marino {
178*86d7f5d3SJohn Marino int err = 0;
179*86d7f5d3SJohn Marino if (! buf_empty_p (buf)
180*86d7f5d3SJohn Marino || (err = recv (n->socket, &tmp, 1, 0)) > 0)
181*86d7f5d3SJohn Marino error (0, 0, "dying gasps from %s unexpected",
182*86d7f5d3SJohn Marino current_parsed_root->hostname);
183*86d7f5d3SJohn Marino else if (err == -1)
184*86d7f5d3SJohn Marino error (0, 0, "reading from %s: %s", current_parsed_root->hostname,
185*86d7f5d3SJohn Marino SOCK_STRERROR (SOCK_ERRNO));
186*86d7f5d3SJohn Marino
187*86d7f5d3SJohn Marino /* shutdown() socket */
188*86d7f5d3SJohn Marino # ifdef SHUTDOWN_SERVER
189*86d7f5d3SJohn Marino if (current_parsed_root->method != server_method)
190*86d7f5d3SJohn Marino # endif
191*86d7f5d3SJohn Marino if (shutdown (n->socket, 0) < 0)
192*86d7f5d3SJohn Marino {
193*86d7f5d3SJohn Marino error (1, 0, "shutting down server socket: %s",
194*86d7f5d3SJohn Marino SOCK_STRERROR (SOCK_ERRNO));
195*86d7f5d3SJohn Marino }
196*86d7f5d3SJohn Marino
197*86d7f5d3SJohn Marino buf->input = NULL;
198*86d7f5d3SJohn Marino }
199*86d7f5d3SJohn Marino else if (buf->output)
200*86d7f5d3SJohn Marino {
201*86d7f5d3SJohn Marino /* shutdown() socket */
202*86d7f5d3SJohn Marino # ifdef SHUTDOWN_SERVER
203*86d7f5d3SJohn Marino /* FIXME: Should have a SHUTDOWN_SERVER_INPUT &
204*86d7f5d3SJohn Marino * SHUTDOWN_SERVER_OUTPUT
205*86d7f5d3SJohn Marino */
206*86d7f5d3SJohn Marino if (current_parsed_root->method == server_method)
207*86d7f5d3SJohn Marino SHUTDOWN_SERVER (n->socket);
208*86d7f5d3SJohn Marino else
209*86d7f5d3SJohn Marino # endif
210*86d7f5d3SJohn Marino if (shutdown (n->socket, 1) < 0)
211*86d7f5d3SJohn Marino {
212*86d7f5d3SJohn Marino error (1, 0, "shutting down server socket: %s",
213*86d7f5d3SJohn Marino SOCK_STRERROR (SOCK_ERRNO));
214*86d7f5d3SJohn Marino }
215*86d7f5d3SJohn Marino
216*86d7f5d3SJohn Marino buf->output = NULL;
217*86d7f5d3SJohn Marino }
218*86d7f5d3SJohn Marino
219*86d7f5d3SJohn Marino return 0;
220*86d7f5d3SJohn Marino }
221*86d7f5d3SJohn Marino
222*86d7f5d3SJohn Marino
223*86d7f5d3SJohn Marino
224*86d7f5d3SJohn Marino /* Create a buffer based on a socket. */
225*86d7f5d3SJohn Marino
226*86d7f5d3SJohn Marino struct buffer *
socket_buffer_initialize(int socket,int input,void (* memory)(struct buffer *))227*86d7f5d3SJohn Marino socket_buffer_initialize (int socket, int input,
228*86d7f5d3SJohn Marino void (*memory) (struct buffer *))
229*86d7f5d3SJohn Marino {
230*86d7f5d3SJohn Marino struct socket_buffer *sbuf = xmalloc (sizeof *sbuf);
231*86d7f5d3SJohn Marino sbuf->socket = socket;
232*86d7f5d3SJohn Marino return buf_initialize (input ? socket_buffer_input : NULL,
233*86d7f5d3SJohn Marino input ? NULL : socket_buffer_output,
234*86d7f5d3SJohn Marino input ? NULL : socket_buffer_flush,
235*86d7f5d3SJohn Marino NULL, NULL,
236*86d7f5d3SJohn Marino socket_buffer_shutdown,
237*86d7f5d3SJohn Marino memory,
238*86d7f5d3SJohn Marino sbuf);
239*86d7f5d3SJohn Marino }
240*86d7f5d3SJohn Marino
241*86d7f5d3SJohn Marino #endif /* CLIENT_SUPPORT */
242