mirror of
https://github.com/alsa-project/alsa-utils
synced 2024-11-10 00:45:41 +01:00
aseqnet: use getaddrinfo() instead obsolete gethostbyname()
- modernize code (preparation for IPv6) Signed-off-by: Jaroslav Kysela <perex@perex.cz>
This commit is contained in:
parent
f076518254
commit
c8e5762750
1 changed files with 85 additions and 48 deletions
|
@ -21,6 +21,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
#include <alsa/asoundlib.h>
|
#include <alsa/asoundlib.h>
|
||||||
|
@ -38,10 +39,9 @@ static void init_buf(void);
|
||||||
static void init_pollfds(void);
|
static void init_pollfds(void);
|
||||||
static void close_files(void);
|
static void close_files(void);
|
||||||
static void init_seq(char *source, char *dest, char *name);
|
static void init_seq(char *source, char *dest, char *name);
|
||||||
static int get_port(char *service);
|
|
||||||
static void sigterm_exit(int sig);
|
static void sigterm_exit(int sig);
|
||||||
static void init_server(int port);
|
static void init_server(const char *port);
|
||||||
static void init_client(char *server, int port);
|
static void init_client(const char *server, const char *port);
|
||||||
static void do_loop(void);
|
static void do_loop(void);
|
||||||
static int copy_local_to_remote(void);
|
static int copy_local_to_remote(void);
|
||||||
static int copy_remote_to_local(int fd);
|
static int copy_remote_to_local(int fd);
|
||||||
|
@ -49,7 +49,7 @@ static int copy_remote_to_local(int fd);
|
||||||
/*
|
/*
|
||||||
* default TCP port number
|
* default TCP port number
|
||||||
*/
|
*/
|
||||||
#define DEFAULT_PORT 40002
|
#define DEFAULT_PORT "40002"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* local input buffer
|
* local input buffer
|
||||||
|
@ -97,7 +97,7 @@ static const struct option long_option[] = {
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
int port = DEFAULT_PORT;
|
char *port = DEFAULT_PORT;
|
||||||
char *source = NULL, *dest = NULL;
|
char *source = NULL, *dest = NULL;
|
||||||
char *name = 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) {
|
while ((c = getopt_long(argc, argv, "p:s:d:n:,vi", long_option, NULL)) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'p':
|
case 'p':
|
||||||
if (isdigit(*optarg))
|
port = optarg;
|
||||||
port = atoi(optarg);
|
|
||||||
else
|
|
||||||
port = get_port(optarg);
|
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
source = optarg;
|
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){
|
switch (rp->ai_family) {
|
||||||
fprintf(stderr, _("service '%s' is not found in /etc/services\n"), service);
|
case AF_INET:
|
||||||
return -1;
|
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
|
* 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 i;
|
||||||
int curstate = 1;
|
int curstate = 1;
|
||||||
struct sockaddr_in addr;
|
int save_errno = 0;
|
||||||
|
|
||||||
memset(&addr, 0, sizeof(addr));
|
memset(&hints, 0, sizeof(hints));
|
||||||
|
hints.ai_family = AF_INET;
|
||||||
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
|
hints.ai_flags = AI_PASSIVE;
|
||||||
|
|
||||||
addr.sin_family = AF_INET;
|
if (getaddrinfo(NULL, port, &hints, &result) < 0) {
|
||||||
addr.sin_addr.s_addr = INADDR_ANY;
|
fprintf(stderr, _("can't get address\n"));
|
||||||
addr.sin_port = htons(port);
|
|
||||||
|
|
||||||
sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
|
||||||
if (sockfd < 0) {
|
|
||||||
perror("create socket");
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &curstate, sizeof(curstate));
|
for (rp = result; rp != NULL; rp = rp->ai_next) {
|
||||||
/* the return value is ignored.. */
|
if ((sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0){
|
||||||
|
perror("create socket");
|
||||||
if (bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
|
exit(1);
|
||||||
perror("can't bind");
|
}
|
||||||
|
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);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
freeaddrinfo(result);
|
||||||
|
|
||||||
if (listen(sockfd, 5) < 0) {
|
if (listen(sockfd, 5) < 0) {
|
||||||
perror("can't listen");
|
perror("can't listen");
|
||||||
|
@ -402,32 +423,48 @@ static void start_connection(void)
|
||||||
/*
|
/*
|
||||||
* initialize network client
|
* 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 addrinfo hints;
|
||||||
struct hostent *host;
|
struct addrinfo *result, *rp;
|
||||||
|
char buf[100];
|
||||||
int curstate = 1;
|
int curstate = 1;
|
||||||
int fd;
|
int fd;
|
||||||
|
int save_errno = 0;
|
||||||
|
|
||||||
if ((fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0){
|
memset(&hints, 0, sizeof(hints));
|
||||||
perror("create socket");
|
hints.ai_family = AF_INET;
|
||||||
exit(1);
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
}
|
hints.ai_flags = AI_PASSIVE;
|
||||||
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &curstate, sizeof(curstate)) < 0) {
|
|
||||||
perror("setsockopt");
|
if (getaddrinfo(server, port, &hints, &result) < 0) {
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
if ((host = gethostbyname(server)) == NULL){
|
|
||||||
fprintf(stderr, _("can't get address %s\n"), server);
|
fprintf(stderr, _("can't get address %s\n"), server);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
addr.sin_port = htons(port);
|
for (rp = result; rp != NULL; rp = rp->ai_next) {
|
||||||
addr.sin_family = AF_INET;
|
if ((fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0){
|
||||||
memcpy(&addr.sin_addr, host->h_addr, host->h_length);
|
perror("create socket");
|
||||||
if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
|
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");
|
perror("connect");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
freeaddrinfo(result);
|
||||||
if (verbose)
|
if (verbose)
|
||||||
fprintf(stderr, _("ok.. connected\n"));
|
fprintf(stderr, _("ok.. connected\n"));
|
||||||
netfd[0] = fd;
|
netfd[0] = fd;
|
||||||
|
|
Loading…
Reference in a new issue