xconnect.c 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. /* vi: set sw=4 ts=4: */
  2. /*
  3. * Utility routines.
  4. *
  5. * Connect to host at port using address resolution from getaddrinfo
  6. *
  7. */
  8. #include <unistd.h>
  9. #include <string.h>
  10. #include <stdlib.h>
  11. #include <sys/types.h>
  12. #include <sys/socket.h>
  13. #include <errno.h>
  14. #include <netdb.h>
  15. #include <sys/socket.h>
  16. #include <netinet/in.h>
  17. #include <arpa/inet.h>
  18. #include "libbb.h"
  19. /* Return network byte ordered port number for a service.
  20. * If "port" is a number use it as the port.
  21. * If "port" is a name it is looked up in /etc/services, if it isnt found return
  22. * default_port
  23. */
  24. unsigned short bb_lookup_port(const char *port, const char *protocol, unsigned short default_port)
  25. {
  26. unsigned short port_nr = htons(default_port);
  27. if (port) {
  28. char *endptr;
  29. int old_errno;
  30. long port_long;
  31. /* Since this is a lib function, we're not allowed to reset errno to 0.
  32. * Doing so could break an app that is deferring checking of errno. */
  33. old_errno = errno;
  34. errno = 0;
  35. port_long = strtol(port, &endptr, 10);
  36. if (errno != 0 || *endptr!='\0' || endptr==port || port_long < 0 || port_long > 65535) {
  37. struct servent *tserv = getservbyname(port, protocol);
  38. if (tserv) {
  39. port_nr = tserv->s_port;
  40. }
  41. } else {
  42. port_nr = htons(port_long);
  43. }
  44. errno = old_errno;
  45. }
  46. return port_nr;
  47. }
  48. void bb_lookup_host(struct sockaddr_in *s_in, const char *host)
  49. {
  50. struct hostent *he;
  51. memset(s_in, 0, sizeof(struct sockaddr_in));
  52. s_in->sin_family = AF_INET;
  53. he = xgethostbyname(host);
  54. memcpy(&(s_in->sin_addr), he->h_addr_list[0], he->h_length);
  55. }
  56. int xconnect(struct sockaddr_in *s_addr)
  57. {
  58. int s = socket(AF_INET, SOCK_STREAM, 0);
  59. if (connect(s, (struct sockaddr *)s_addr, sizeof(struct sockaddr_in)) < 0)
  60. {
  61. if (ENABLE_FEATURE_CLEAN_UP) close(s);
  62. bb_perror_msg_and_die("Unable to connect to remote host (%s)",
  63. inet_ntoa(s_addr->sin_addr));
  64. }
  65. return s;
  66. }