diff options
Diffstat (limited to 'src/piesctl.c')
-rw-r--r-- | src/piesctl.c | 122 |
1 files changed, 10 insertions, 112 deletions
diff --git a/src/piesctl.c b/src/piesctl.c index 2e35aea..aa983ee 100644 --- a/src/piesctl.c +++ b/src/piesctl.c | |||
@@ -415,123 +415,22 @@ static struct shttp_connection * | |||
415 | shttp_connect (struct pies_url *url, struct grecs_sockaddr *source_addr) | 415 | shttp_connect (struct pies_url *url, struct grecs_sockaddr *source_addr) |
416 | { | 416 | { |
417 | int fd; | 417 | int fd; |
418 | union pies_sockaddr_storage addr; | 418 | struct pies_url *conn_url; |
419 | socklen_t socklen; | ||
420 | int flags; | ||
421 | struct shttp_connection *conn; | 419 | struct shttp_connection *conn; |
422 | FILE *fp; | 420 | FILE *fp; |
423 | |||
424 | if (strcmp (url->scheme, "unix") == 0 | ||
425 | || strcmp (url->scheme, "file") == 0 | ||
426 | || strcmp (url->scheme, "socket") == 0) | ||
427 | { | ||
428 | struct stat st; | ||
429 | |||
430 | if (url->port) | ||
431 | { | ||
432 | grecs_error (NULL, 0, _("%s: invalid connection type: " | ||
433 | "port is meaningless for UNIX sockets"), | ||
434 | url->string); | ||
435 | return NULL; | ||
436 | } | ||
437 | |||
438 | if (strlen (url->path) > sizeof addr.s_un.sun_path) | ||
439 | { | ||
440 | errno = EINVAL; | ||
441 | grecs_error (NULL, 0, | ||
442 | _("%s: UNIX socket name too long"), | ||
443 | url->path); | ||
444 | return NULL; | ||
445 | } | ||
446 | |||
447 | addr.s.sa_family = PF_UNIX; | ||
448 | socklen = sizeof (addr.s_un); | ||
449 | strcpy (addr.s_un.sun_path, url->path); | ||
450 | |||
451 | if (stat (url->path, &st)) | ||
452 | { | ||
453 | if (errno != ENOENT) | ||
454 | { | ||
455 | grecs_error (NULL, errno, _("%s: %s failed"), url->path, "stat"); | ||
456 | return NULL; | ||
457 | } | ||
458 | } | ||
459 | else | ||
460 | { | ||
461 | if (!S_ISSOCK (st.st_mode)) | ||
462 | { | ||
463 | grecs_error (NULL, 0, _("%s: not a socket"), url->path); | ||
464 | return NULL; | ||
465 | } | ||
466 | } | ||
467 | } | ||
468 | else if (strcmp (url->scheme, "inet") == 0) | ||
469 | { | ||
470 | short pnum; | ||
471 | struct hostent *hp; | ||
472 | |||
473 | addr.s_in.sin_family = PF_INET; | ||
474 | socklen = sizeof (addr.s_in); | ||
475 | |||
476 | pnum = url->port ? url->port : 8080; | ||
477 | |||
478 | hp = gethostbyname (url->host); | ||
479 | if (!hp) | ||
480 | { | ||
481 | grecs_error (NULL, 0, _("%s: unknown host name"), url->string); | ||
482 | return NULL; | ||
483 | } | ||
484 | |||
485 | addr.s_in.sin_family = hp->h_addrtype; | ||
486 | switch (hp->h_addrtype) | ||
487 | { | ||
488 | case AF_INET: | ||
489 | memmove (&addr.s_in.sin_addr, hp->h_addr, 4); | ||
490 | addr.s_in.sin_port = htons (pnum); | ||
491 | break; | ||
492 | |||
493 | default: | ||
494 | grecs_error (NULL, 0, | ||
495 | _("%s: invalid connection type: " | ||
496 | "unsupported address family"), | ||
497 | url->string); | ||
498 | return NULL; | ||
499 | } | ||
500 | } | ||
501 | else | ||
502 | { | ||
503 | grecs_error (NULL, 0, _("%s: unsupported protocol"), url->string); | ||
504 | return NULL; | ||
505 | } | ||
506 | 421 | ||
507 | fd = socket (addr.s.sa_family, SOCK_STREAM, 0); | 422 | if (pies_url_copy (&conn_url, url)) |
508 | if (fd == -1) | 423 | grecs_alloc_die (); |
509 | { | ||
510 | grecs_error (NULL, errno, _("%s: %s failed"), url->string, "socket"); | ||
511 | return NULL; | ||
512 | } | ||
513 | 424 | ||
514 | if ((flags = fcntl (fd, F_GETFD, 0)) == -1 | 425 | if (conn_url->port == 0 && strcmp (conn_url->scheme, "inet") == 0) |
515 | || fcntl (fd, F_SETFD, flags | FD_CLOEXEC) == -1) | ||
516 | grecs_error (NULL, 0, _("%s: cannot set close-on-exec: %s"), | ||
517 | url->string, strerror (errno)); | ||
518 | |||
519 | if (source_addr) | ||
520 | { | 426 | { |
521 | if (source_addr->sa->sa_family != addr.s.sa_family) | 427 | conn_url->port_s = grecs_strdup ("8080"); |
522 | grecs_error (NULL, 0, | 428 | conn_url->port = 8080; |
523 | _("source and destination address family differ")); | ||
524 | else if (bind (fd, source_addr->sa, source_addr->len) < 0) | ||
525 | { | ||
526 | grecs_error (NULL, errno, _("%s: %s failed"), url->string, "bind"); | ||
527 | exit (EX_UNAVAILABLE); | ||
528 | } | ||
529 | } | 429 | } |
530 | 430 | fd = url_connect (conn_url, source_addr); | |
531 | if (connect (fd, &addr.s, socklen)) | 431 | if (fd == -1) |
532 | { | 432 | { |
533 | grecs_error (NULL, errno, _("%s: %s failed"), url->string, "connect"); | 433 | pies_url_destroy (&conn_url); |
534 | close (fd); | ||
535 | return NULL; | 434 | return NULL; |
536 | } | 435 | } |
537 | 436 | ||
@@ -545,8 +444,7 @@ shttp_connect (struct pies_url *url, struct grecs_sockaddr *source_addr) | |||
545 | 444 | ||
546 | conn = grecs_zalloc (sizeof (*conn)); | 445 | conn = grecs_zalloc (sizeof (*conn)); |
547 | conn->fp = fp; | 446 | conn->fp = fp; |
548 | if (pies_url_copy (&conn->url, url)) | 447 | conn->url = conn_url; |
549 | grecs_alloc_die (); | ||
550 | 448 | ||
551 | if (!no_netrc_option) | 449 | if (!no_netrc_option) |
552 | netrc_scan (conn->url); | 450 | netrc_scan (conn->url); |