]> git.alsa-project.org Git - alsa-utils.git/commitdiff
aseqnet: use getaddrinfo() instead obsolete gethostbyname()
authorJaroslav Kysela <perex@perex.cz>
Mon, 9 Aug 2021 16:10:56 +0000 (18:10 +0200)
committerJaroslav Kysela <perex@perex.cz>
Mon, 9 Aug 2021 16:11:37 +0000 (18:11 +0200)
- modernize code (preparation for IPv6)

Signed-off-by: Jaroslav Kysela <perex@perex.cz>
seq/aseqnet/aseqnet.c

index e756e82b9200760a13a6201c0d91c9d8c44e441e..d05f52d95ca91db3643d0d2d840abd644e569d8f 100644 (file)
@@ -21,6 +21,7 @@
 #include <string.h>
 #include <netinet/in.h>
 #include <sys/socket.h>
+#include <arpa/inet.h>
 #include <netdb.h>
 #include <locale.h>
 #include <alsa/asoundlib.h>
@@ -38,10 +39,9 @@ static void init_buf(void);
 static void init_pollfds(void);
 static void close_files(void);
 static void init_seq(char *source, char *dest, char *name);
-static int get_port(char *service);
 static void sigterm_exit(int sig);
-static void init_server(int port);
-static void init_client(char *server, int port);
+static void init_server(const char *port);
+static void init_client(const char *server, const char *port);
 static void do_loop(void);
 static int copy_local_to_remote(void);
 static int copy_remote_to_local(int fd);
@@ -49,7 +49,7 @@ static int copy_remote_to_local(int fd);
 /*
  * default TCP port number
  */
-#define DEFAULT_PORT   40002
+#define DEFAULT_PORT   "40002"
 
 /*
  * local input buffer
@@ -97,7 +97,7 @@ static const struct option long_option[] = {
 int main(int argc, char **argv)
 {
        int c;
-       int port = DEFAULT_PORT;
+       char *port = DEFAULT_PORT;
        char *source = NULL, *dest = NULL;
        char *name = NULL;
 
@@ -109,10 +109,7 @@ int main(int argc, char **argv)
        while ((c = getopt_long(argc, argv, "p:s:d:n:,vi", long_option, NULL)) != -1) {
                switch (c) {
                case 'p':
-                       if (isdigit(*optarg))
-                               port = atoi(optarg);
-                       else
-                               port = get_port(optarg);
+                       port = optarg;
                        break;
                case 's':
                        source = optarg;
@@ -307,19 +304,25 @@ static void init_seq(char *source, char *dest, char* name)
        }
 }
 
-
 /*
- * convert from string to TCP port number
+ * translate the binary network address to ASCII
  */
-static int get_port(char *service)
+static void get_net_addr(struct addrinfo *rp, char *buf, size_t buflen)
 {
-       struct servent *sp;
+       void *ptr;
 
-       if ((sp = getservbyname(service, "tcp")) == NULL){
-               fprintf(stderr, _("service '%s' is not found in /etc/services\n"), service);
-               return -1;
+       switch (rp->ai_family) {
+       case AF_INET:
+               ptr = &((struct sockaddr_in *) rp->ai_addr)->sin_addr;
+               break;
+       case AF_INET6:
+               ptr = &((struct sockaddr_in6 *) rp->ai_addr)->sin6_addr;
+               break;
+       default:
+               ptr = NULL;
        }
-       return sp->s_port;
+       buf[buflen-1] = '\0';
+       inet_ntop(rp->ai_family, ptr, buf, buflen-1);
 }
 
 /*
@@ -335,30 +338,48 @@ static void sigterm_exit(int sig)
 /*
  * initialize network server
  */
-static void init_server(int port)
+static void init_server(const char *port)
 {
+       struct addrinfo hints;
+       struct addrinfo *result, *rp;
+       char buf[100];
        int i;
        int curstate = 1;
-       struct sockaddr_in addr;
+       int save_errno = 0;
 
-       memset(&addr, 0, sizeof(addr));
-
-       addr.sin_family = AF_INET;
-       addr.sin_addr.s_addr = INADDR_ANY;
-       addr.sin_port = htons(port);
+       memset(&hints, 0, sizeof(hints));
+       hints.ai_family = AF_INET;
+       hints.ai_socktype = SOCK_STREAM;
+       hints.ai_flags = AI_PASSIVE;
 
-       sockfd = socket(AF_INET, SOCK_STREAM, 0);
-       if (sockfd < 0)  {
-               perror("create socket");
+       if (getaddrinfo(NULL, port, &hints, &result) < 0) {
+               fprintf(stderr, _("can't get address\n"));
                exit(1);
        }
-       setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &curstate, sizeof(curstate));
-       /* the return value is ignored.. */
-
-       if (bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)) < 0)  {
-               perror("can't bind");
+       for (rp = result; rp != NULL; rp = rp->ai_next) {
+               if ((sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0){
+                       perror("create socket");
+                       exit(1);
+               }
+               if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &curstate, sizeof(curstate)) < 0) {
+                       perror("setsockopt");
+                       exit(1);
+               }
+               if (verbose) {
+                       get_net_addr(rp, buf, sizeof(buf));
+                       fprintf(stderr, _("connecting to: %s\n"), buf);
+               }
+               if (bind(sockfd, rp->ai_addr, rp->ai_addrlen) == 0)
+                       break;
+               save_errno = errno;
+               close(sockfd);
+       }
+       if (rp == NULL) {
+               errno = save_errno;
+               perror("bind");
                exit(1);
        }
+       freeaddrinfo(result);
 
        if (listen(sockfd, 5) < 0)  {
                perror("can't listen");
@@ -402,32 +423,48 @@ static void start_connection(void)
 /*
  * initialize network client
  */
-static void init_client(char *server, int port)
+static void init_client(const char *server, const char *port)
 {
-       struct sockaddr_in addr;
-       struct hostent *host;
+       struct addrinfo hints;
+       struct addrinfo *result, *rp;
+       char buf[100];
        int curstate = 1;
        int fd;
+       int save_errno = 0;
 
-       if ((fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0){
-               perror("create socket");
-               exit(1);
-       }
-       if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &curstate, sizeof(curstate)) < 0) {
-               perror("setsockopt");
-               exit(1);
-       }
-       if ((host = gethostbyname(server)) == NULL){
+       memset(&hints, 0, sizeof(hints));
+       hints.ai_family = AF_INET;
+       hints.ai_socktype = SOCK_STREAM;
+       hints.ai_flags = AI_PASSIVE;
+
+       if (getaddrinfo(server, port, &hints, &result) < 0) {
                fprintf(stderr, _("can't get address %s\n"), server);
                exit(1);
        }
-       addr.sin_port = htons(port);
-       addr.sin_family = AF_INET;
-       memcpy(&addr.sin_addr, host->h_addr, host->h_length);
-       if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
+       for (rp = result; rp != NULL; rp = rp->ai_next) {
+               if ((fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0){
+                       perror("create socket");
+                       exit(1);
+               }
+               if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &curstate, sizeof(curstate)) < 0) {
+                       perror("setsockopt");
+                       exit(1);
+               }
+               if (verbose) {
+                       get_net_addr(rp, buf, sizeof(buf));
+                       fprintf(stderr, _("connecting to: %s\n"), buf);
+               }
+               if (connect(fd, rp->ai_addr, rp->ai_addrlen) == 0)
+                       break;
+               save_errno = errno;
+               close(fd);
+       }
+       if (rp == NULL) {
+               errno = save_errno;
                perror("connect");
                exit(1);
        }
+       freeaddrinfo(result);
        if (verbose)
                fprintf(stderr, _("ok.. connected\n"));
        netfd[0] = fd;