rpms/nut/devel nut-ipv6.patch, NONE, 1.1 .cvsignore, 1.12, 1.13 nut.spec, 1.34, 1.35 sources, 1.12, 1.13

fedora-cvs-commits at redhat.com fedora-cvs-commits at redhat.com
Tue Nov 21 12:38:52 UTC 2006


Author: than

Update of /cvs/dist/rpms/nut/devel
In directory cvs.devel.redhat.com:/tmp/cvs-serv11047

Modified Files:
	.cvsignore nut.spec sources 
Added Files:
	nut-ipv6.patch 
Log Message:
add IPv6 support, thanks to Dan KopeÄek (#198394)


nut-ipv6.patch:
 clients/upsc.c      |    3 
 clients/upsclient.c |  167 ++++++++++++++++++++++++++++++----------------------
 clients/upsclient.h |    2 
 server/access.c     |  149 ++++++++++++++++++++++++++++++++++++++--------
 server/access.h     |    8 +-
 server/ctype.h      |    2 
 server/upsd.c       |  123 +++++++++++++++++++++++++++-----------
 server/user.c       |    6 -
 server/user.h       |    4 -
 9 files changed, 326 insertions(+), 138 deletions(-)

--- NEW FILE nut-ipv6.patch ---
--- nut-2.0.3/server/access.c.ipv6	2006-10-24 11:16:43.000000000 +0200
+++ nut-2.0.3/server/access.c	2006-10-24 11:06:41.000000000 +0200
@@ -25,33 +25,72 @@
 #include "common.h"
 #include "access.h"
 
-	struct 	acl_t	*acl_head = NULL;
-	struct	access_t	*access_head = NULL;
+struct 	acl_t	*acl_head = NULL;
+struct	access_t	*access_head = NULL;
+
+/*
+ *  Stolen from privoxy code :]
+ */
+int mask_cmp (const struct sockaddr_storage* ip_addr, unsigned int prefix, const struct sockaddr_storage* net_addr) {
+	switch (ip_addr->ss_family) {
+	case AF_INET:
+		return((((struct sockaddr_in*)ip_addr)->sin_addr.s_addr & htonl(prefix)) == ((struct sockaddr_in*)net_addr)->sin_addr.s_addr);
+		break;
+	case AF_INET6:
+		if (AF_INET6 == net_addr->ss_family) {
+			struct in6_addr ip, net;
+			register unsigned char i;
+			
+			memcpy (&ip, &((struct sockaddr_in6 *)ip_addr)->sin6_addr, sizeof (struct in6_addr));
+			memcpy (&net, &((struct sockaddr_in6 *)net_addr)->sin6_addr, sizeof (struct in6_addr));
+			
+			i = prefix/8;
+			if (prefix%8)
+				ip.s6_addr[i++] &= 0xff<<(8-(prefix%8));
+			for (; i < sizeof ip.s6_addr; i++)
+				ip.s6_addr[i] = 0;
+			
+			return (memcmp (ip.s6_addr, net.s6_addr, sizeof ip.s6_addr)==0);
+		}
+		else if (AF_INET == net_addr->ss_family) { /* IPv4 mapped IPv6 */
+			struct in6_addr *ip6 = &((struct sockaddr_in6 *)ip_addr)->sin6_addr;
+			struct in_addr *net = &((struct sockaddr_in *)net_addr)->sin_addr;
+			
+			if ((ip6->s6_addr32[3] & (u_int32_t)prefix) == net->s_addr &&
+#if BYTE_ORDER == LITTLE_ENDIAN
+					(ip6->s6_addr32[2] == (u_int32_t)0xffff0000) &&
+#else
+					(ip6->s6_addr32[2] == (u_int32_t)0x0000ffff) &&
+#endif
+					(ip6->s6_addr32[1] == 0) && (ip6->s6_addr32[0] == 0))
+				return(1);
+			else
+				return(0); 
+		}
+	default:
+		fatal ("mask_cmp: Unknown address family");
+		return(0);
+	}
+}
 
 /* see if <addr> matches the acl <aclname> */
-int acl_check(const char *aclname, const struct sockaddr_in *addr)
+int acl_check(const char *aclname, const struct sockaddr_storage *addr)
 {
 	struct	acl_t	*tmp;
-	int	aclchk, addrchk;
 
 	tmp = acl_head;
 	while (tmp != NULL) {
-		if (!strcmp(tmp->name, aclname)) {
-			aclchk = tmp->addr & tmp->mask;
-			addrchk = ntohl(addr->sin_addr.s_addr) & tmp->mask;
-
-			if (aclchk == addrchk) 
-				return 1;	/* match */
-		}
-
+		if (!strcmp(tmp->name, aclname))
+			if (mask_cmp (addr, tmp->mask, &tmp->addr))
+				return 1;
 		tmp = tmp->next;
 	}
-
+	
 	return 0;	/* not found */
 }
 
 /* return ACCEPT/REJECT based on source address */
-int access_check(const struct sockaddr_in *addr)
+int access_check(const struct sockaddr_storage *addr)
 {
 	struct	access_t	*tmp;
 	int	ret;
@@ -108,21 +147,83 @@
 		tmp = tmp->next;
 	}
 
+	//memset (&saddr, 0, sizeof (struct sockaddr_storage));
 	tmp = xmalloc(sizeof(struct acl_t));
+	memset (tmp, 0, sizeof (struct acl_t));
 	tmp->name = xstrdup(aclname);
-	tmp->addr = ntohl(inet_addr(addr));
 	tmp->next = NULL;
 
-	/* must be a /nn CIDR type block */
-	if (strstr(mask, ".") == NULL) { 
-		if (atoi(mask) != 32)
-			tmp->mask = ((unsigned int) ((1 << atoi(mask)) - 1) << 
-					(32 - atoi(mask)));
-		else
-			tmp->mask = 0xffffffff;	/* avoid overflow from 2^32 */
+	if (*addr == '[') { 
+		struct sockaddr_in6 s6;
+		char *stmp;
+
+		stmp = strchr (addr, ']');
+		if (stmp == NULL) {
+			free (tmp);
+			fatal("Expecting \']\' in \"%s\"", addr);
+		}
+
+		*stmp = '\0';
+		addr++;
+		
+		memset (&s6, 0, sizeof (struct sockaddr_in6));
+		s6.sin6_family = AF_INET6;
+
+		if (inet_pton (AF_INET6, addr, &s6.sin6_addr) < 1) {
+			free (tmp);
+			fatal ("Invalid IPv6 address: \"%s\"", addr);
+		}
+
+		/* prefix */
+		tmp->mask = strtol (mask, NULL, 10);
+
+		if (tmp->mask < 0 || tmp->mask > 128) {
+			free (tmp);
+			fatal ("Invalid IPv6 prefix");
+		}
+
+		{ register unsigned char i;
+			i = (tmp->mask)/8;
+			if ((tmp->mask)%8)
+				s6.sin6_addr.s6_addr[i++] &= 0xff<<(8-((tmp->mask)%8));
+			for (; i < sizeof s6.sin6_addr.s6_addr; i++)
+				s6.sin6_addr.s6_addr[i] = 0;
+		}
+
+		memcpy (&(tmp->addr), &s6, sizeof (struct sockaddr_in6));
+		//tmp->addr.ss_len = sizeof (struct sockaddr_in6);
+		tmp->addr.ss_family = AF_INET6;
+	} else {
+		struct sockaddr_in s4;
+
+		/* mask */
+		if (inet_pton (AF_INET, mask, &s4.sin_addr) < 1) {
+			/* must be a /nn CIDR type block */
+			tmp->mask = strtol (mask, NULL, 10);
+
+			if (tmp->mask < 0 || tmp->mask > 32) {
+				free (tmp);
+				fatal ("Invalid CIDR type block: Must be > 0 && < 32");
+			}
+			tmp->mask = 0xffffffff << (32 - tmp->mask);
+		} else {
+			tmp->mask = ntohl (s4.sin_addr.s_addr);
+		}
+
+		memset (&s4, 0, sizeof (struct sockaddr_in));
+		s4.sin_family = AF_INET;
+
+		if (inet_pton (AF_INET, addr, &s4.sin_addr) < 1) {
+			free (tmp);
+			fatal ("Invalid IPv4 address: \"%s\"", addr);
+		}
+
+		s4.sin_addr.s_addr &= htonl (tmp->mask);
+
+		memcpy (&(tmp->addr), &s4, sizeof (struct sockaddr_in));
+		//tmp->addr.ss_len = sizeof (struct sockaddr_in);
+		tmp->addr.ss_family = AF_INET;
 	}
-	else
-		tmp->mask = ntohl(inet_addr(mask));
 
 	if (last == NULL)	/* first */
 		acl_head = tmp;
--- nut-2.0.3/server/user.c.ipv6	2006-10-24 11:16:54.000000000 +0200
+++ nut-2.0.3/server/user.c	2006-10-23 23:15:30.000000000 +0200
@@ -290,7 +290,7 @@
 	users = NULL;
 }	
 
-static int user_matchacl(ulist_t *user, const struct sockaddr_in *addr)
+static int user_matchacl(ulist_t *user, const struct sockaddr_storage *addr)
 {
 	acllist	*tmp;
 
@@ -328,7 +328,7 @@
 	return 0;	/* fail */
 }
 
-int user_checkinstcmd(const struct sockaddr_in *addr, 
+int user_checkinstcmd(const struct sockaddr_storage *addr, 
 	const char *un, const char *pw, const char *cmd)
 {
 	ulist_t	*tmp = users;
@@ -385,7 +385,7 @@
 	return 0;	/* fail */
 }
 
-int user_checkaction(const struct sockaddr_in *addr, 
+int user_checkaction(const struct sockaddr_storage *addr, 
 	const char *un, const char *pw, const char *action)
 {
 	ulist_t	*tmp = users;
--- nut-2.0.3/server/user.h.ipv6	2006-10-24 11:17:17.000000000 +0200
+++ nut-2.0.3/server/user.h	2006-10-23 23:16:10.000000000 +0200
@@ -19,10 +19,10 @@
 
 void user_load(void);
 
-int user_checkinstcmd(const struct sockaddr_in *addr,
+int user_checkinstcmd(const struct sockaddr_storage *addr,
 	const char *un, const char *pw, const char *cmd);
 
-int user_checkaction(const struct sockaddr_in *addr,
+int user_checkaction(const struct sockaddr_storage *addr,
 	const char *un, const char *pw, const char *action);
 
 void user_flush(void);
--- nut-2.0.3/server/ctype.h.ipv6	2006-10-24 11:17:47.000000000 +0200
+++ nut-2.0.3/server/ctype.h	2006-10-22 17:01:30.000000000 +0200
@@ -32,7 +32,7 @@
 	char	*addr;
 	int	fd;
 	int	delete;			/* set after a write fails */
-	struct sockaddr_in sock;
+	struct sockaddr_storage sock;
 	char	rq[SMALLBUF];
 	size_t	rqpos;
 	char	*loginups;
--- nut-2.0.3/server/upsd.c.ipv6	2006-10-24 11:16:32.000000000 +0200
+++ nut-2.0.3/server/upsd.c	2006-10-24 11:26:24.000000000 +0200
@@ -26,6 +26,7 @@
 
 #include <sys/un.h>
 #include <sys/socket.h>
+#include <netdb.h>
 
 #ifdef HAVE_SSL
 #include <openssl/err.h>
@@ -60,7 +61,11 @@
 static	int	listenfd, net_port = PORT;
 
 	/* default is to listen on all local interfaces */
-static	struct	in_addr	listenaddr;
+static	char *listenaddr = NULL;
+
+/* AF_ */
+
+static int opt_af = AF_UNSPEC;
 
 	/* signal handlers */
 static	struct sigaction sa;
@@ -72,6 +77,20 @@
 	/* set by signal handlers */
 static	int	reload_flag = 0, exit_flag = 0;
 
+const char *inet_ntopW (struct sockaddr_storage *s) {
+	static char str[40];
+
+	switch (s->ss_family) {
+	case AF_INET:
+		return inet_ntop (AF_INET, &(((struct sockaddr_in *)s)->sin_addr), str, 16);
+	case AF_INET6:
+		return inet_ntop (AF_INET6, &(((struct sockaddr_in6 *)s)->sin6_addr), str, 40);
+	default:
+		errno = EAFNOSUPPORT;
+		return NULL;
+	}
+}
+
 /* return a pointer to the named ups if possible */
 upstype *get_ups_ptr(const char *name)
 {
@@ -131,35 +150,63 @@
 /* create a listening socket for tcp connections */
 static void setuptcp(void)
 {
-	struct	sockaddr_in	server;
+	struct addrinfo hints, *r, *rtmp;
+	char *service;
 	int	res, one = 1;
 
-	if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
-		fatal("socket");
-
-	res = setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, (void *) &one, 
-		sizeof(one));
-
-	if (res != 0)
-		fatal("setsockopt(SO_REUSEADDR)");
-
-	memset(&server, '\0', sizeof(server));
-	server.sin_addr = listenaddr;
-	server.sin_family = AF_INET;
-	server.sin_port = htons(net_port);
-
-	if (bind(listenfd, (struct sockaddr *) &server, sizeof(server)) == -1)
-		fatal("Can't bind TCP port number %d", net_port);
+	memset (&hints, 0, sizeof (struct addrinfo));
+	hints.ai_family = opt_af;
+	hints.ai_flags = AI_PASSIVE;
+	hints.ai_protocol = IPPROTO_TCP;
+	hints.ai_socktype = SOCK_STREAM;
+	
+	service = malloc (sizeof (char) * 6);
+	if (service == NULL)
+		fatal("malloc");
+
+	if (snprintf (service, 6, "%hu", (unsigned short int)net_port) < 1)
+		fatal("snprintf");
+
+	if (getaddrinfo (listenaddr, service, &hints, &r) != 0) {
+		free (service);
+		fatal("getaddrinfo");
+	}
+	free (service);
+
+	for (rtmp = r; r != NULL; r = r->ai_next) {
+		listenfd = socket(r->ai_family, r->ai_socktype, r->ai_protocol);
+		if (listenfd < 0) {
+			if (r->ai_next == NULL)
+				fatal("socket");
+			continue;
+		}
 
-	if ((res = fcntl(listenfd, F_GETFL, 0)) == -1)
-		fatal("fcntl(get)");
+		res = setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, (void *) &one, sizeof(one));
+		if (res != 0)
+			fatal("setsockopt(SO_REUSEADDR)");
+
+		if (bind (listenfd, r->ai_addr, r->ai_addrlen) == -1) {
+			if (r->ai_next == NULL)
+				fatal("Can't bind TCP port number %u", net_port);
+			close (listenfd);
+			continue;
+		}
 
-	if (fcntl(listenfd, F_SETFL, res | O_NDELAY) == -1)
-		fatal("fcntl(set)");
+		if ((res = fcntl(listenfd, F_GETFL, 0)) == -1)
+			fatal("fcntl(get)");
 
-	if (listen(listenfd, 16))
-		fatal("listen");
+		if (fcntl(listenfd, F_SETFL, res | O_NDELAY) == -1)
+			fatal("fcntl(set)");
 
+		if (listen(listenfd, 16) == -1) {
+			if (r->ai_next == NULL)
+				fatal("listen");
+			close (listenfd);
+			continue;
+		}
+		break;
+	}
+	freeaddrinfo (rtmp);
 	return;
 }
 
@@ -412,7 +459,7 @@
 static void answertcp(void)
 {
 	int	acc;
-	struct	sockaddr_in csock;
+	struct	sockaddr_storage csock;
 	ctype	*tmp, *last;
 	socklen_t	clen;
 
@@ -424,7 +471,7 @@
 
 	if (!access_check(&csock)) {
 		upslogx(LOG_NOTICE, "Rejecting TCP connection from %s", 
-			inet_ntoa(csock.sin_addr));
+			inet_ntopW(&csock));
 		shutdown(acc, shutdown_how);
 		close(acc);
 		return;
@@ -439,10 +486,10 @@
 
 	tmp = xmalloc(sizeof(ctype));
 
-	tmp->addr = xstrdup(inet_ntoa(csock.sin_addr));
+	tmp->addr = xstrdup(inet_ntopW(&csock));
 	tmp->fd = acc;
 	tmp->delete = 0;
-	memcpy(&tmp->sock, &csock, sizeof(struct sockaddr_in));
+	memcpy(&tmp->sock, &csock, sizeof(struct sockaddr_storage));
 
 	tmp->rqpos = 0;
 	memset(tmp->rq, '\0', sizeof(tmp->rq));
@@ -463,7 +510,7 @@
 	else
 		last->next = tmp;
 
-	upslogx(LOG_INFO, "Connection from %s", inet_ntoa(csock.sin_addr));
+	upslogx(LOG_INFO, "Connection from %s", tmp->addr);
 }
 
 /* read tcp messages and handle them */
@@ -668,6 +715,8 @@
 	printf("  -r <dir>	chroots to <dir>\n");
 	printf("  -u <user>	switch to <user> (if started as root)\n");
 	printf("  -V		display the version of this software\n");
+	printf("  -4		IPv4 only\n");
+	printf("  -6		IPv6 only\n");
 
 	exit(EXIT_SUCCESS);
 }
@@ -819,13 +868,11 @@
 	datapath = xstrdup(DATADIR);
 
 	/* set up some things for later */
-
-	listenaddr.s_addr = INADDR_ANY;
 	snprintf(pidfn, sizeof(pidfn), "%s/upsd.pid", altpidpath());
 
 	printf("Network UPS Tools upsd %s\n", UPS_VERSION);
 
-	while ((i = getopt(argc, argv, "+hp:r:i:fu:Vc:D")) != EOF) {
+	while ((i = getopt(argc, argv, "+h46p:r:i:fu:Vc:D")) != EOF) {
 		switch (i) {
 			case 'h':
 				help(progname);
@@ -834,8 +881,7 @@
 				net_port = atoi(optarg);
 				break;
 			case 'i':
-				if (!inet_aton(optarg, &listenaddr))
-					fatal("Invalid IP address");
+				listenaddr = xstrdup (optarg);
 				break;
 			case 'r':
 				chroot_path = optarg;
@@ -866,6 +912,15 @@
 				do_background = 0;
 				nut_debug_level++;
 				break;
+
+		  case '4':
+				opt_af = AF_INET;
+				break;
+
+		  case '6':
+				opt_af = AF_INET6;
+				break;
+
 			default:
 				help(progname);
 				break;
--- nut-2.0.3/server/access.h.ipv6	2006-10-24 11:17:25.000000000 +0200
+++ nut-2.0.3/server/access.h	2006-10-22 20:14:23.000000000 +0200
@@ -26,8 +26,8 @@
 /* ACL structure */
 struct acl_t {
 	char	*name;
-	unsigned int	addr;
-	unsigned int	mask;
+	struct sockaddr_storage	addr;
+	unsigned int	mask; /* prefix - if IPv6 */
 	void	*next;
 };
 
@@ -38,8 +38,8 @@
 	void	*next;
 };
 
-int acl_check(const char *aclname, const struct sockaddr_in *addr);
-int access_check(const struct sockaddr_in *addr);
+int acl_check(const char *aclname, const struct sockaddr_storage *addr);
+int access_check(const struct sockaddr_storage *addr);
 void acl_add(const char *aclname, char *ipblock);
 void access_add(int type, int numargs, const char **arg);
 void acl_free(void);
--- nut-2.0.3/clients/upsclient.h.ipv6	2006-10-24 11:15:38.000000000 +0200
+++ nut-2.0.3/clients/upsclient.h	2006-10-22 01:52:46.000000000 +0200
@@ -148,6 +148,8 @@
 
 #define UPSCLI_CONN_TRYSSL	0x0001	/* try SSL, OK if not supported       */
 #define UPSCLI_CONN_REQSSL	0x0002	/* try SSL, fail if not supported     */
+#define UPSCLI_CONN_INET    0x0004  /* IPv4 only */
+#define UPSCLI_CONN_INET6   0x0008  /* IPv6 only */
 
 #ifdef __cplusplus
 }
--- nut-2.0.3/clients/upsc.c.ipv6	2006-10-24 11:15:20.000000000 +0200
+++ nut-2.0.3/clients/upsc.c	2006-10-22 01:32:39.000000000 +0200
@@ -25,6 +25,9 @@
 
 #include "upsclient.h"
 
+
+static int opt_af = AF_UNSPEC;
+
 static void help(const char *prog)
 {
 	printf("Network UPS Tools upsc %s\n\n", UPS_VERSION);
--- nut-2.0.3/clients/upsclient.c.ipv6	2006-10-24 11:15:44.000000000 +0200
+++ nut-2.0.3/clients/upsclient.c	2006-10-24 10:49:04.000000000 +0200
@@ -38,6 +38,8 @@
 #define shutdown_how 2
 #endif
 
+extern int opt_af;
+
 struct {
 	int	flags;
 	const	char	*str;
@@ -421,8 +423,8 @@
 	
 int upscli_connect(UPSCONN *ups, const char *host, int port, int flags)
 {
-	struct	sockaddr_in	local, server;
-	struct	hostent	*serv;
+	struct addrinfo hints, *r, *rtmp;
+	char *service;
 
 	/* clear out any lingering junk */
 	ups->fd = -1;
@@ -449,78 +451,86 @@
 		return -1;
 	}
 
-	if ((serv = gethostbyname(host)) == (struct hostent *) NULL) {
-
-		ups->upserror = UPSCLI_ERR_NOSUCHHOST;
+	service = malloc (sizeof (char) * 6);
+	if (service == NULL) {
+		ups->upserror = UPSCLI_ERR_NOMEM;
 		return -1;
 	}
 
-	if ((ups->fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
-		ups->upserror = UPSCLI_ERR_SOCKFAILURE;
-		ups->syserrno = errno;
+	if (snprintf (service, 6, "%hu", (unsigned short int)port) < 1) {
 		return -1;
 	}
 
-	memset(&local, '\0', sizeof(struct sockaddr_in));
-	local.sin_family = AF_INET;
-	local.sin_port = htons(INADDR_ANY);
-
-	memset(&server, '\0', sizeof(struct sockaddr_in));
-	server.sin_family = AF_INET;
-	server.sin_port = htons(port);
-
-	memcpy(&server.sin_addr, serv->h_addr, serv->h_length);
-
-	if (bind(ups->fd, (struct sockaddr *) &local, 
-		sizeof(struct sockaddr_in)) == -1) {
-		ups->upserror = UPSCLI_ERR_BINDFAILURE;
-		ups->syserrno = errno;
-		close(ups->fd);
-		ups->fd = -1;
+	memset (&hints, 0, sizeof (struct addrinfo));
+	hints.ai_family = flags & UPSCLI_CONN_INET ? AF_INET : (flags & UPSCLI_CONN_INET6 ? AF_INET6 : AF_UNSPEC);
+	hints.ai_socktype = SOCK_STREAM;
+	hints.ai_protocol = IPPROTO_TCP;
+	hints.ai_flags = AI_ADDRCONFIG;
 
+	if (getaddrinfo (host, service, &hints, &r) != 0) {
+		ups->upserror = UPSCLI_ERR_NOSUCHHOST;
+		free (service);
 		return -1;
 	}
+	free (service);
 
-	if (connect(ups->fd, (struct sockaddr *) &server, 
-		sizeof(struct sockaddr_in)) == -1) {
-		ups->upserror = UPSCLI_ERR_CONNFAILURE;
-		ups->syserrno = errno;
-		close(ups->fd);
-		ups->fd = -1;
+	for (rtmp = r; r != NULL; r = r->ai_next) {
+		ups->fd = socket (r->ai_family, r->ai_socktype, r->ai_protocol);
+		if (ups->fd < 0) {
+			if (r->ai_next == NULL) {
+				ups->upserror = UPSCLI_ERR_SOCKFAILURE;
+				ups->syserrno = errno;
+				break;
+			}
+			continue;
+		}
 
-		return -1;
-	}
+		if (connect (ups->fd, r->ai_addr, r->ai_addrlen) == -1) {
+			close (ups->fd);
+			ups->fd = -1;
+			if (r->ai_next == NULL) {
+				ups->upserror = UPSCLI_ERR_CONNFAILURE;
+				ups->syserrno = errno;
+				break;
+			}
+			continue;
+		}
+		freeaddrinfo (rtmp);
 
-	/* don't use xstrdup for cleaner linking (fewer dependencies) */
-	ups->host = strdup(host);
+		/* don't use xstrdup for cleaner linking (fewer dependencies) */
+		ups->host = strdup(host);
 
-	if (!ups->host) {
-		close(ups->fd);
-		ups->fd = -1;
+		if (!ups->host) {
+			close(ups->fd);
+			ups->fd = -1;
 
-		ups->upserror = UPSCLI_ERR_NOMEM;
-		return -1;
-	}
+			ups->upserror = UPSCLI_ERR_NOMEM;
+			return -1;
+		}
 
-	ups->port = port;
+		ups->port = port;
 
-	if (flags & UPSCLI_CONN_TRYSSL) {
-		upscli_sslinit(ups);
+		if (flags & UPSCLI_CONN_TRYSSL) {
+			upscli_sslinit(ups);
 
-		/* see if something made us die inside sslinit */
-		if (ups->upserror != 0)
-			return -1;
-	}
+			/* see if something made us die inside sslinit */
+			if (ups->upserror != 0)
+				return -1;
+		}
 
-	if (flags & UPSCLI_CONN_REQSSL) {
-		if (upscli_sslinit(ups) != 1) {
-			ups->upserror = UPSCLI_ERR_SSLFAIL;
-			upscli_closefd(ups);
-			return -1;
+		if (flags & UPSCLI_CONN_REQSSL) {
+			if (upscli_sslinit(ups) != 1) {
+				ups->upserror = UPSCLI_ERR_SSLFAIL;
+				upscli_closefd(ups);
+				return -1;
+			}
 		}
+
+		return 0;
 	}
+	freeaddrinfo (rtmp);
 
-	return 0;
+	return -1;
 }
 
 /* map upsd error strings back to upsclient internal numbers */
@@ -861,31 +871,48 @@
 
 	ptr = ap;
 
-	cp = strchr(ptr, ':');
+	if (*ptr != '[') {
+		cp = strchr(ptr, ':');
+		if (cp) {
+			*cp++ = '\0';
+			*hostname = strdup(ptr);
+			
+			if (!*hostname) {
+				fprintf(stderr, "upscli_splitname: strdup failed\n");
+				return -1;
+			}
 
-	if (cp) {
-		*cp++ = '\0';
-		*hostname = strdup(ptr);
+			ptr = cp;
+			
+			*port = strtol(ptr, (char **) NULL, 10);
 
-		if (!*hostname) {
-			fprintf(stderr, "upscli_splitname: strdup failed\n");
-			return -1;
-		}
+		} else {
 
-		ptr = cp;
+			*hostname = strdup(ptr);
 
-		*port = strtol(ptr, (char **) NULL, 10);
+			if (!*hostname) {
+				fprintf(stderr, "upscli_splitname: strdup failed\n");
+				return -1;
+			}
 
+			*port = PORT;
+		}
 	} else {
-
-		*hostname = strdup(ptr);
-
-		if (!*hostname) {
-			fprintf(stderr, "upscli_splitname: strdup failed\n");
+		ptr++;
+		cp = strchr(ptr, ']');
+		if (cp) {
+			*cp = '\0';
+			*hostname = strdup (ptr);
+			ptr = ++cp;
+			cp = strchr (ptr, ':');
+			if (cp != NULL)
+			 *port = strtol (++cp, (char **)NULL, 10);
+			else
+			 *port = PORT;
+		} else {
+			fprintf (stderr, "upscli_splitname: strchr(']') failed\n");
 			return -1;
 		}
-
-		*port = PORT;
 	}
 
 	return 0;


Index: .cvsignore
===================================================================
RCS file: /cvs/dist/rpms/nut/devel/.cvsignore,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- .cvsignore	24 Apr 2006 17:58:48 -0000	1.12
+++ .cvsignore	21 Nov 2006 12:38:49 -0000	1.13
@@ -2,3 +2,4 @@
 nut-2.0.1.tar.gz
 nut-2.0.2.tar.gz
 nut-2.0.3.tar.gz
+nut-2.0.4.tar.gz


Index: nut.spec
===================================================================
RCS file: /cvs/dist/rpms/nut/devel/nut.spec,v
retrieving revision 1.34
retrieving revision 1.35
diff -u -r1.34 -r1.35
--- nut.spec	12 Jul 2006 07:29:56 -0000	1.34
+++ nut.spec	21 Nov 2006 12:38:50 -0000	1.35
@@ -10,8 +10,8 @@
 
 Summary: Network UPS Tools
 Name: nut
-Version: 2.0.3
-Release: 2.1
+Version: 2.0.4
+Release: 1
 Group: Applications/System
 License: GPL
 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
@@ -24,6 +24,7 @@
 Patch1: nut-0.45.0-conffiles.patch
 Patch2: nut-0.45.4-conf.patch
 Patch3: nut-2.0.1-bad.patch
+Patch4: nut-ipv6.patch
 
 Requires: nut-client
 
@@ -90,6 +91,7 @@
 %patch1 -p1 -b .conf
 %patch2 -p1 -b .conf1
 %patch3 -p1 -b .bad
+%patch4 -p1 -b .IPv6
 
 iconv -f iso-8859-1 -t utf-8 < man/newhidups.8 > man/newhidups.8_
 mv man/newhidups.8_ man/newhidups.8
@@ -276,6 +278,9 @@
 %{_mandir}/man8/upsset.cgi.8.gz
 
 %changelog
+* Tue Nov 21 2006 Than Ngo <than at redhat.com> - 2.0.4-1
+- add IPv6 support, thanks to Dan KopeÄek (#198394)
+
 * Wed Jul 12 2006 Jesse Keating <jkeating at redhat.com> - 2.0.3-2.1
 - rebuild
 


Index: sources
===================================================================
RCS file: /cvs/dist/rpms/nut/devel/sources,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- sources	24 Apr 2006 17:58:48 -0000	1.12
+++ sources	21 Nov 2006 12:38:50 -0000	1.13
@@ -1 +1 @@
-ed2d3104d021a6ddb864f23d8cbd1cf6  nut-2.0.3.tar.gz
+59b6f3038a5ef64c584913e72bd850a2  nut-2.0.4.tar.gz




More information about the fedora-cvs-commits mailing list