diff --git a/src/xpdev/multisock.c b/src/xpdev/multisock.c index a74038cbc0360cfe47501ff0ff542c75d2ac9755..0e85842af7a5dbe10d3ce84854bc9ab7aa220c71 100644 --- a/src/xpdev/multisock.c +++ b/src/xpdev/multisock.c @@ -134,6 +134,40 @@ BOOL xpms_add(struct xpms_set *xpms_set, int domain, int type, return FALSE; } +BOOL xpms_add_list(struct xpms_set *xpms_set, int domain, int type, + int protocol, str_list_t list, uint16_t default_port, const char *prot, + void (*sock_init)(SOCKET, void *), int(*bind_init)(BOOL), void *cbdata) +{ + char **iface; + char *host; + char *p, *p2; + BOOL one_good=FALSE; + + for(iface=list; iface && *iface; iface++) { + host=strdup(*iface); + WORD port=default_port; + + if(xpms_set->lprintf) + xpms_set->lprintf(LOG_INFO, "Adding %s listening socket on %s", prot, host); + p = strrchr(host, ':'); + if(host[0]=='[') { + p2=strrchr(host,']'); + if(p2) + *p2=0; + if(p2 > p) + p=NULL; + } + if(p!=NULL) { + *(p++)=0; + sscanf(p, "%hu", &port); + } + if(xpms_add(xpms_set, PF_UNSPEC, SOCK_STREAM, 0, host, port, prot, sock_init, bind_init, NULL)) + one_good=TRUE; + free(host); + } + return one_good; +} + SOCKET xpms_accept(struct xpms_set *xpms_set, struct sockaddr * addr, socklen_t * addrlen, unsigned int timeout, void **cb_data) { @@ -184,3 +218,4 @@ SOCKET xpms_accept(struct xpms_set *xpms_set, struct sockaddr * addr, return INVALID_SOCKET; } + diff --git a/src/xpdev/multisock.h b/src/xpdev/multisock.h index ea73fa19e4dae01ee97cebdf97f0b7e5487d14fc..782104f38f2ab35327c649912e385856960bdd34 100644 --- a/src/xpdev/multisock.h +++ b/src/xpdev/multisock.h @@ -2,6 +2,7 @@ #define MULTISOCK_H #include <sys/limits.h> +#include <str_list.h> struct xpms_sockdef { @@ -35,6 +36,9 @@ void xpms_destroy(struct xpms_set *xpms_set); BOOL xpms_add(struct xpms_set *xpms_set, int domain, int type, int protocol, const char *addr, uint16_t port, const char *prot, void (*sock_init)(SOCKET, void *), int(*bind_init)(BOOL), void *cbdata); +BOOL xpms_add_list(struct xpms_set *xpms_set, int domain, int type, + int protocol, str_list_t list, uint16_t default_port, const char *prot, + void (*sock_init)(SOCKET, void *), int(*bind_init)(BOOL), void *cbdata); SOCKET xpms_accept(struct xpms_set *, struct sockaddr * addr, socklen_t * addrlen, unsigned int timeout, void **cb_data); diff --git a/src/xpdev/sockwrap.c b/src/xpdev/sockwrap.c index cfb9ac15ba338714108f682562c8dfdd74e32837..eb91b239c4798bb609b465aa7de357ec57e95cd6 100644 --- a/src/xpdev/sockwrap.c +++ b/src/xpdev/sockwrap.c @@ -386,3 +386,27 @@ int nonblocking_connect(SOCKET sock, struct sockaddr* addr, size_t size, unsigne } return result; } + +const char *inet_addrtop(SOCKADDR *in, char *dest, size_t size) +{ + switch(in->sa_family) { + case AF_INET: + return inet_ntop(in->sa_family, &((struct sockaddr_in *)in)->sin_addr, dest, size); + case AF_INET6: + return inet_ntop(in->sa_family, &((struct sockaddr_in6 *)in)->sin6_addr, dest, size); + default: + return NULL; + } +} + +uint16_t inet_addrport(SOCKADDR *in) +{ + switch(in->sa_family) { + case AF_INET: + return ntohs(((struct sockaddr_in *)in)->sin_port); + case AF_INET6: + return ntohs(((struct sockaddr_in6 *)in)->sin6_port); + default: + return 0; + } +} diff --git a/src/xpdev/sockwrap.h b/src/xpdev/sockwrap.h index f94ee97b647aa38b88b238bbca9794822a2eaf47..43412dd10d93f12ea9418f4d3017aaca69da2c0d 100644 --- a/src/xpdev/sockwrap.h +++ b/src/xpdev/sockwrap.h @@ -193,6 +193,8 @@ int retry_bind(SOCKET s, const struct sockaddr *addr, socklen_t addrlen ,uint retries, uint wait_secs, const char* prot ,int (*lprintf)(int level, const char *fmt, ...)); int nonblocking_connect(SOCKET, struct sockaddr*, size_t, unsigned timeout /* seconds */); +const char *inet_addrtop(SOCKADDR *in, char *dest, size_t size); +uint16_t inet_addrport(SOCKADDR *in); #ifdef __cplusplus }