mirror of
https://github.com/alsa-project/alsa-utils
synced 2024-11-10 00:25:43 +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 <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));
|
||||
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;
|
||||
addr.sin_addr.s_addr = INADDR_ANY;
|
||||
addr.sin_port = htons(port);
|
||||
|
||||
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;
|
||||
|
|
Loading…
Reference in a new issue