common.c (97856) | common.c (97866) |
---|---|
1/*- 2 * Copyright (c) 1998 Dag-Erling Co�dan Sm�rgrav 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 13 unchanged lines hidden (view full) --- 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 1998 Dag-Erling Co�dan Sm�rgrav 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 13 unchanged lines hidden (view full) --- 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29#include <sys/cdefs.h> |
30__FBSDID("$FreeBSD: head/lib/libfetch/common.c 97856 2002-06-05 10:05:03Z des $"); | 30__FBSDID("$FreeBSD: head/lib/libfetch/common.c 97866 2002-06-05 12:19:08Z des $"); |
31 32#include <sys/param.h> 33#include <sys/socket.h> 34#include <sys/time.h> 35#include <sys/uio.h> 36#include <netinet/in.h> 37 | 31 32#include <sys/param.h> 33#include <sys/socket.h> 34#include <sys/time.h> 35#include <sys/uio.h> 36#include <netinet/in.h> 37 |
38#include <ctype.h> /* XXX */ |
|
38#include <errno.h> 39#include <netdb.h> 40#include <stdarg.h> 41#include <stdlib.h> 42#include <stdio.h> 43#include <string.h> 44#include <unistd.h> 45 --- 145 unchanged lines hidden (view full) --- 191 if (strcasecmp(scheme, SCHEME_FTP) == 0) 192 return (FTP_DEFAULT_PROXY_PORT); 193 if (strcasecmp(scheme, SCHEME_HTTP) == 0) 194 return (HTTP_DEFAULT_PROXY_PORT); 195 return (0); 196} 197 198/* | 39#include <errno.h> 40#include <netdb.h> 41#include <stdarg.h> 42#include <stdlib.h> 43#include <stdio.h> 44#include <string.h> 45#include <unistd.h> 46 --- 145 unchanged lines hidden (view full) --- 192 if (strcasecmp(scheme, SCHEME_FTP) == 0) 193 return (FTP_DEFAULT_PROXY_PORT); 194 if (strcasecmp(scheme, SCHEME_HTTP) == 0) 195 return (HTTP_DEFAULT_PROXY_PORT); 196 return (0); 197} 198 199/* |
200 * Create a connection for an existing descriptor. 201 */ 202conn_t * 203_fetch_reopen(int sd) 204{ 205 conn_t *conn; 206 207 /* allocate and fill connection structure */ 208 if ((conn = calloc(1, sizeof *conn)) == NULL) 209 return (NULL); 210 conn->sd = sd; 211 return (conn); 212} 213 214 215/* |
|
199 * Establish a TCP connection to the specified port on the specified host. 200 */ 201conn_t * 202_fetch_connect(const char *host, int port, int af, int verbose) 203{ 204 conn_t *conn; 205 char pbuf[10]; 206 struct addrinfo hints, *res, *res0; --- 29 unchanged lines hidden (view full) --- 236 sd = -1; 237 } 238 freeaddrinfo(res0); 239 if (sd == -1) { 240 _fetch_syserr(); 241 return (NULL); 242 } 243 | 216 * Establish a TCP connection to the specified port on the specified host. 217 */ 218conn_t * 219_fetch_connect(const char *host, int port, int af, int verbose) 220{ 221 conn_t *conn; 222 char pbuf[10]; 223 struct addrinfo hints, *res, *res0; --- 29 unchanged lines hidden (view full) --- 253 sd = -1; 254 } 255 freeaddrinfo(res0); 256 if (sd == -1) { 257 _fetch_syserr(); 258 return (NULL); 259 } 260 |
244 /* allocate and fill connection structure */ 245 if ((conn = calloc(1, sizeof *conn)) == NULL) { | 261 if ((conn = _fetch_reopen(sd)) == NULL) |
246 close(sd); | 262 close(sd); |
247 return (NULL); 248 } 249 if ((conn->host = strdup(host)) == NULL) { 250 free(conn); 251 close(sd); 252 return (NULL); 253 } 254 conn->port = port; 255 conn->af = af; 256 conn->sd = sd; | |
257 return (conn); 258} 259 260 261/* | 263 return (conn); 264} 265 266 267/* |
262 * Read a line of text from a socket w/ timeout | 268 * Read a character from a connection w/ timeout |
263 */ | 269 */ |
264#define MIN_BUF_SIZE 1024 265 266int 267_fetch_getln(conn_t *conn) | 270ssize_t 271_fetch_read(conn_t *conn, char *buf, size_t len) |
268{ 269 struct timeval now, timeout, wait; 270 fd_set readfds; | 272{ 273 struct timeval now, timeout, wait; 274 fd_set readfds; |
275 ssize_t rlen, total; |
|
271 int r; | 276 int r; |
272 char c; | |
273 | 277 |
274 if (conn->buf == NULL) { 275 if ((conn->buf = malloc(MIN_BUF_SIZE)) == NULL) { 276 errno = ENOMEM; 277 return (-1); 278 } 279 conn->bufsize = MIN_BUF_SIZE; 280 } 281 282 conn->buf[0] = '\0'; 283 conn->buflen = 0; 284 | |
285 if (fetchTimeout) { | 278 if (fetchTimeout) { |
279 FD_ZERO(&readfds); |
|
286 gettimeofday(&timeout, NULL); 287 timeout.tv_sec += fetchTimeout; | 280 gettimeofday(&timeout, NULL); 281 timeout.tv_sec += fetchTimeout; |
288 FD_ZERO(&readfds); | |
289 } 290 | 282 } 283 |
291 do { 292 if (fetchTimeout) { | 284 total = 0; 285 while (len > 0) { 286 while (fetchTimeout && !FD_ISSET(conn->sd, &readfds)) { |
293 FD_SET(conn->sd, &readfds); 294 gettimeofday(&now, NULL); 295 wait.tv_sec = timeout.tv_sec - now.tv_sec; 296 wait.tv_usec = timeout.tv_usec - now.tv_usec; 297 if (wait.tv_usec < 0) { 298 wait.tv_usec += 1000000; 299 wait.tv_sec--; 300 } | 287 FD_SET(conn->sd, &readfds); 288 gettimeofday(&now, NULL); 289 wait.tv_sec = timeout.tv_sec - now.tv_sec; 290 wait.tv_usec = timeout.tv_usec - now.tv_usec; 291 if (wait.tv_usec < 0) { 292 wait.tv_usec += 1000000; 293 wait.tv_sec--; 294 } |
301 if (wait.tv_sec < 0) { 302 errno = ETIMEDOUT; 303 return (-1); 304 } | 295 if (wait.tv_sec < 0) 296 return (rlen); 297 errno = 0; |
305 r = select(conn->sd + 1, &readfds, NULL, NULL, &wait); 306 if (r == -1) { 307 if (errno == EINTR && fetchRestartCalls) 308 continue; | 298 r = select(conn->sd + 1, &readfds, NULL, NULL, &wait); 299 if (r == -1) { 300 if (errno == EINTR && fetchRestartCalls) 301 continue; |
309 /* EBADF or EINVAL: shouldn't happen */ | |
310 return (-1); 311 } | 302 return (-1); 303 } |
312 if (!FD_ISSET(conn->sd, &readfds)) 313 continue; | |
314 } | 304 } |
315 r = read(conn->sd, &c, 1); 316 if (r == 0) | 305 if (conn->ssl != NULL) 306 rlen = SSL_read(conn->ssl, buf, len); 307 else 308 rlen = read(conn->sd, buf, len); 309 if (rlen == 0) |
317 break; | 310 break; |
318 if (r == -1) { | 311 if (rlen < 0) { |
319 if (errno == EINTR && fetchRestartCalls) 320 continue; | 312 if (errno == EINTR && fetchRestartCalls) 313 continue; |
321 /* any other error is bad news */ | |
322 return (-1); 323 } | 314 return (-1); 315 } |
316 len -= rlen; 317 buf += rlen; 318 total += rlen; 319 } 320 return (total); 321} 322 323/* 324 * Read a line of text from a connection w/ timeout 325 */ 326#define MIN_BUF_SIZE 1024 327 328int 329_fetch_getln(conn_t *conn) 330{ 331 char *tmp; 332 size_t tmpsize; 333 char c; 334 335 if (conn->buf == NULL) { 336 if ((conn->buf = malloc(MIN_BUF_SIZE)) == NULL) { 337 errno = ENOMEM; 338 return (-1); 339 } 340 conn->bufsize = MIN_BUF_SIZE; 341 } 342 343 conn->buf[0] = '\0'; 344 conn->buflen = 0; 345 346 do { 347 if (_fetch_read(conn, &c, 1) == -1) 348 return (-1); |
|
324 conn->buf[conn->buflen++] = c; 325 if (conn->buflen == conn->bufsize) { | 349 conn->buf[conn->buflen++] = c; 350 if (conn->buflen == conn->bufsize) { |
326 char *tmp; 327 size_t tmpsize; 328 | |
329 tmp = conn->buf; 330 tmpsize = conn->bufsize * 2 + 1; 331 if ((tmp = realloc(tmp, tmpsize)) == NULL) { 332 errno = ENOMEM; 333 return (-1); 334 } 335 conn->buf = tmp; 336 conn->bufsize = tmpsize; 337 } 338 } while (c != '\n'); 339 340 conn->buf[conn->buflen] = '\0'; 341 DEBUG(fprintf(stderr, "<<< %s", conn->buf)); 342 return (0); 343} 344 345 346/* | 351 tmp = conn->buf; 352 tmpsize = conn->bufsize * 2 + 1; 353 if ((tmp = realloc(tmp, tmpsize)) == NULL) { 354 errno = ENOMEM; 355 return (-1); 356 } 357 conn->buf = tmp; 358 conn->bufsize = tmpsize; 359 } 360 } while (c != '\n'); 361 362 conn->buf[conn->buflen] = '\0'; 363 DEBUG(fprintf(stderr, "<<< %s", conn->buf)); 364 return (0); 365} 366 367 368/* |
347 * Write a line of text to a socket w/ timeout 348 * XXX currently does not enforce timeout | 369 * Write to a connection w/ timeout |
349 */ | 370 */ |
371ssize_t 372_fetch_write(conn_t *conn, const char *buf, size_t len) 373{ 374 struct timeval now, timeout, wait; 375 fd_set writefds; 376 ssize_t wlen, total; 377 int r; 378 379 if (fetchTimeout) { 380 FD_ZERO(&writefds); 381 gettimeofday(&timeout, NULL); 382 timeout.tv_sec += fetchTimeout; 383 } 384 385 while (len > 0) { 386 while (fetchTimeout && !FD_ISSET(conn->sd, &writefds)) { 387 FD_SET(conn->sd, &writefds); 388 gettimeofday(&now, NULL); 389 wait.tv_sec = timeout.tv_sec - now.tv_sec; 390 wait.tv_usec = timeout.tv_usec - now.tv_usec; 391 if (wait.tv_usec < 0) { 392 wait.tv_usec += 1000000; 393 wait.tv_sec--; 394 } 395 if (wait.tv_sec < 0) { 396 errno = ETIMEDOUT; 397 return (-1); 398 } 399 errno = 0; 400 r = select(conn->sd + 1, NULL, &writefds, NULL, &wait); 401 if (r == -1) { 402 if (errno == EINTR && fetchRestartCalls) 403 continue; 404 return (-1); 405 } 406 } 407 errno = 0; 408 if (conn->ssl != NULL) 409 wlen = SSL_write(conn->ssl, buf, len); 410 else 411 wlen = write(conn->sd, buf, len); 412 if (wlen == 0) 413 /* we consider a short write a failure */ 414 return (-1); 415 if (wlen < 0) { 416 if (errno == EINTR && fetchRestartCalls) 417 continue; 418 return (-1); 419 } 420 len -= wlen; 421 buf += wlen; 422 total += wlen; 423 } 424 return (total); 425} 426 427/* 428 * Write a line of text to a connection w/ timeout 429 */ |
|
350int 351_fetch_putln(conn_t *conn, const char *str, size_t len) 352{ | 430int 431_fetch_putln(conn_t *conn, const char *str, size_t len) 432{ |
353 struct iovec iov[2]; 354 ssize_t wlen; 355 356 /* XXX should enforce timeout */ 357 iov[0].iov_base = (char *)str; 358 iov[0].iov_len = len; 359 iov[1].iov_base = (char *)ENDL; 360 iov[1].iov_len = sizeof ENDL; 361 len += sizeof ENDL; 362 wlen = writev(conn->sd, iov, 2); 363 if (wlen < 0 || (size_t)wlen != len) | 433 if (_fetch_write(conn, str, len) == -1 || 434 _fetch_write(conn, ENDL, sizeof ENDL) == -1) |
364 return (-1); | 435 return (-1); |
365 DEBUG(fprintf(stderr, ">>> %.*s\n", (int)len, str)); | |
366 return (0); 367} 368 369 370/* 371 * Close connection 372 */ 373int 374_fetch_close(conn_t *conn) 375{ 376 int ret; 377 378 ret = close(conn->sd); | 436 return (0); 437} 438 439 440/* 441 * Close connection 442 */ 443int 444_fetch_close(conn_t *conn) 445{ 446 int ret; 447 448 ret = close(conn->sd); |
379 free(conn->host); | |
380 free(conn); 381 return (ret); 382} 383 384 385/*** Directory-related utility functions *************************************/ 386 387int --- 30 unchanged lines hidden --- | 449 free(conn); 450 return (ret); 451} 452 453 454/*** Directory-related utility functions *************************************/ 455 456int --- 30 unchanged lines hidden --- |