23 |
#if defined (AUTH_CLIENT_SUPPORT) || defined (HAVE_KERBEROS) || defined (HAVE_GSSAPI) |
#if defined (AUTH_CLIENT_SUPPORT) || defined (HAVE_KERBEROS) || defined (HAVE_GSSAPI) |
24 |
|
|
25 |
struct hostent * |
struct hostent * |
26 |
init_sockaddr( struct sockaddr_in *name, char *hostname, unsigned int port ) |
init_sockaddr (struct sockaddr_in *name, char *hostname, unsigned int port) |
27 |
{ |
{ |
28 |
struct hostent *hostinfo; |
struct hostent *hostinfo; |
29 |
unsigned short shortport = port; |
unsigned short shortport = port; |
32 |
name->sin_family = AF_INET; |
name->sin_family = AF_INET; |
33 |
name->sin_port = htons (shortport); |
name->sin_port = htons (shortport); |
34 |
hostinfo = gethostbyname (hostname); |
hostinfo = gethostbyname (hostname); |
35 |
if (hostinfo == NULL) |
if (!hostinfo) |
36 |
{ |
{ |
37 |
fprintf (stderr, "Unknown host %s.\n", hostname); |
fprintf (stderr, "Unknown host %s.\n", hostname); |
38 |
exit (EXIT_FAILURE); |
exit (EXIT_FAILURE); |
73 |
int socket; |
int socket; |
74 |
}; |
}; |
75 |
|
|
|
static int socket_buffer_input (void *, char *, size_t, size_t, size_t *); |
|
|
static int socket_buffer_output (void *, const char *, size_t, size_t *); |
|
|
static int socket_buffer_flush (void *); |
|
|
static int socket_buffer_shutdown (struct buffer *); |
|
|
|
|
|
|
|
|
|
|
|
/* Create a buffer based on a socket. */ |
|
|
|
|
|
struct buffer * |
|
|
socket_buffer_initialize( int socket, int input, |
|
|
void (*memory) ( struct buffer * ) ) |
|
|
{ |
|
|
struct socket_buffer *sbuf = xmalloc (sizeof *sbuf); |
|
|
sbuf->socket = socket; |
|
|
return buf_initialize (input ? socket_buffer_input : NULL, |
|
|
input ? NULL : socket_buffer_output, |
|
|
input ? NULL : socket_buffer_flush, |
|
|
NULL, NULL, |
|
|
socket_buffer_shutdown, |
|
|
memory, |
|
|
sbuf); |
|
|
} |
|
|
|
|
76 |
|
|
77 |
|
|
78 |
/* The buffer input function for a buffer built on a socket. */ |
/* The buffer input function for a buffer built on a socket. */ |
79 |
|
|
80 |
static int |
static int |
81 |
socket_buffer_input( void *closure, char *data, size_t need, size_t size, size_t *got ) |
socket_buffer_input (void *closure, char *data, size_t need, size_t size, |
82 |
|
size_t *got) |
83 |
{ |
{ |
84 |
struct socket_buffer *sb = (struct socket_buffer *) closure; |
struct socket_buffer *sb = closure; |
85 |
int nbytes; |
int nbytes; |
86 |
|
|
87 |
/* I believe that the recv function gives us exactly the semantics |
/* I believe that the recv function gives us exactly the semantics |
108 |
|
|
109 |
nbytes = recv (sb->socket, data, size, 0); |
nbytes = recv (sb->socket, data, size, 0); |
110 |
if (nbytes < 0) |
if (nbytes < 0) |
111 |
error (1, 0, "reading from server: %s", SOCK_STRERROR (SOCK_ERRNO)); |
error (1, 0, "reading from server: %s", |
112 |
|
SOCK_STRERROR (SOCK_ERRNO)); |
113 |
if (nbytes == 0) |
if (nbytes == 0) |
114 |
{ |
{ |
115 |
/* End of file (for example, the server has closed |
/* End of file (for example, the server has closed |
136 |
/* The buffer output function for a buffer built on a socket. */ |
/* The buffer output function for a buffer built on a socket. */ |
137 |
|
|
138 |
static int |
static int |
139 |
socket_buffer_output( void *closure, const char *data, size_t have, size_t *wrote ) |
socket_buffer_output (void *closure, const char *data, size_t have, |
140 |
|
size_t *wrote) |
141 |
{ |
{ |
142 |
struct socket_buffer *sb = (struct socket_buffer *) closure; |
struct socket_buffer *sb = closure; |
143 |
|
|
144 |
*wrote = have; |
*wrote = have; |
145 |
|
|
151 |
is needed for systems where its return value is something other than |
is needed for systems where its return value is something other than |
152 |
the number of bytes written. */ |
the number of bytes written. */ |
153 |
if (send (sb->socket, data, have, 0) < 0) |
if (send (sb->socket, data, have, 0) < 0) |
154 |
error (1, 0, "writing to server socket: %s", SOCK_STRERROR (SOCK_ERRNO)); |
error (1, 0, "writing to server socket: %s", |
155 |
|
SOCK_STRERROR (SOCK_ERRNO)); |
156 |
#else |
#else |
157 |
while (have > 0) |
while (have > 0) |
158 |
{ |
{ |
160 |
|
|
161 |
nbytes = send (sb->socket, data, have, 0); |
nbytes = send (sb->socket, data, have, 0); |
162 |
if (nbytes < 0) |
if (nbytes < 0) |
163 |
error (1, 0, "writing to server socket: %s", SOCK_STRERROR (SOCK_ERRNO)); |
error (1, 0, "writing to server socket: %s", |
164 |
|
SOCK_STRERROR (SOCK_ERRNO)); |
165 |
|
|
166 |
have -= nbytes; |
have -= nbytes; |
167 |
data += nbytes; |
data += nbytes; |
177 |
|
|
178 |
/*ARGSUSED*/ |
/*ARGSUSED*/ |
179 |
static int |
static int |
180 |
socket_buffer_flush( void *closure ) |
socket_buffer_flush (void *closure) |
181 |
{ |
{ |
182 |
/* Nothing to do. Sockets are always flushed. */ |
/* Nothing to do. Sockets are always flushed. */ |
183 |
return 0; |
return 0; |
186 |
|
|
187 |
|
|
188 |
static int |
static int |
189 |
socket_buffer_shutdown( struct buffer *buf ) |
socket_buffer_shutdown (struct buffer *buf) |
190 |
{ |
{ |
191 |
struct socket_buffer *n = (struct socket_buffer *) buf->closure; |
struct socket_buffer *n = buf->closure; |
192 |
char tmp; |
char tmp; |
193 |
|
|
194 |
/* no need to flush children of an endpoint buffer here */ |
/* no need to flush children of an endpoint buffer here */ |
198 |
int err = 0; |
int err = 0; |
199 |
if (! buf_empty_p (buf) |
if (! buf_empty_p (buf) |
200 |
|| (err = recv (n->socket, &tmp, 1, 0)) > 0) |
|| (err = recv (n->socket, &tmp, 1, 0)) > 0) |
201 |
error (0, 0, "dying gasps from %s unexpected", current_parsed_root->hostname); |
error (0, 0, "dying gasps from %s unexpected", |
202 |
|
current_parsed_root->hostname); |
203 |
else if (err == -1) |
else if (err == -1) |
204 |
error (0, 0, "reading from %s: %s", current_parsed_root->hostname, SOCK_STRERROR (SOCK_ERRNO)); |
error (0, 0, "reading from %s: %s", current_parsed_root->hostname, |
205 |
|
SOCK_STRERROR (SOCK_ERRNO)); |
206 |
|
|
207 |
/* shutdown() socket */ |
/* shutdown() socket */ |
208 |
# ifdef SHUTDOWN_SERVER |
# ifdef SHUTDOWN_SERVER |
210 |
# endif |
# endif |
211 |
if (shutdown (n->socket, 0) < 0) |
if (shutdown (n->socket, 0) < 0) |
212 |
{ |
{ |
213 |
error (1, 0, "shutting down server socket: %s", SOCK_STRERROR (SOCK_ERRNO)); |
error (1, 0, "shutting down server socket: %s", |
214 |
|
SOCK_STRERROR (SOCK_ERRNO)); |
215 |
} |
} |
216 |
|
|
217 |
buf->input = NULL; |
buf->input = NULL; |
229 |
# endif |
# endif |
230 |
if (shutdown (n->socket, 1) < 0) |
if (shutdown (n->socket, 1) < 0) |
231 |
{ |
{ |
232 |
error (1, 0, "shutting down server socket: %s", SOCK_STRERROR (SOCK_ERRNO)); |
error (1, 0, "shutting down server socket: %s", |
233 |
|
SOCK_STRERROR (SOCK_ERRNO)); |
234 |
} |
} |
235 |
|
|
236 |
buf->output = NULL; |
buf->output = NULL; |
239 |
return 0; |
return 0; |
240 |
} |
} |
241 |
|
|
242 |
|
|
243 |
|
|
244 |
|
/* Create a buffer based on a socket. */ |
245 |
|
|
246 |
|
struct buffer * |
247 |
|
socket_buffer_initialize (int socket, int input, |
248 |
|
void (*memory) (struct buffer *)) |
249 |
|
{ |
250 |
|
struct socket_buffer *sbuf = xmalloc (sizeof *sbuf); |
251 |
|
sbuf->socket = socket; |
252 |
|
return buf_initialize (input ? socket_buffer_input : NULL, |
253 |
|
input ? NULL : socket_buffer_output, |
254 |
|
input ? NULL : socket_buffer_flush, |
255 |
|
NULL, NULL, |
256 |
|
socket_buffer_shutdown, |
257 |
|
memory, |
258 |
|
sbuf); |
259 |
|
} |
260 |
|
|
261 |
#endif /* NO_SOCKET_TO_FD */ |
#endif /* NO_SOCKET_TO_FD */ |
262 |
|
|
263 |
#endif /* CLIENT_SUPPORT */ |
#endif /* CLIENT_SUPPORT */ |