summaryrefslogtreecommitdiff
path: root/seq
diff options
context:
space:
mode:
authorJaroslav Kysela <perex@perex.cz>2021-08-09 18:10:56 +0200
committerJaroslav Kysela <perex@perex.cz>2021-08-09 18:11:37 +0200
commitc8e5762750ae47b15d1b7a447529083af2b7fae6 (patch)
tree54a0114bda1068ca781c70df8f8b1cebe62afed8 /seq
parentf076518254d08b9329bd50b52264c5b1b2cb5b16 (diff)
downloadalsa-utils-c8e5762750ae47b15d1b7a447529083af2b7fae6.tar.gz
aseqnet: use getaddrinfo() instead obsolete gethostbyname()
- modernize code (preparation for IPv6) Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Diffstat (limited to 'seq')
-rw-r--r--seq/aseqnet/aseqnet.c133
1 files changed, 85 insertions, 48 deletions
diff --git a/seq/aseqnet/aseqnet.c b/seq/aseqnet/aseqnet.c
index e756e82..d05f52d 100644
--- a/seq/aseqnet/aseqnet.c
+++ b/seq/aseqnet/aseqnet.c
@@ -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;