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