vino r1042 - in trunk: . capplet server/libvncserver



Author: haltonhuo
Date: Thu Jan  8 12:54:11 2009
New Revision: 1042
URL: http://svn.gnome.org/viewvc/vino?rev=1042&view=rev

Log:
2009-01-08  Halton Huo <halton huo sun com>

	Use self-implmented getifaddrs() and freeifaddrs() when system like
	Solaris does not have them. Closes #565422
	* capplet/Makefile.am:
	* configure.in:
	* server/libvncserver/Makefile.am:
	* server/libvncserver/getifaddrs.c: (get_lifreq), (nbytes),
	(addrcpy), (populate), (getifaddrs), (freeifaddrs):
	* server/libvncserver/ifaddrs.h:



Added:
   trunk/server/libvncserver/getifaddrs.c
   trunk/server/libvncserver/ifaddrs.h
Modified:
   trunk/ChangeLog
   trunk/capplet/Makefile.am
   trunk/configure.in
   trunk/server/libvncserver/Makefile.am

Modified: trunk/capplet/Makefile.am
==============================================================================
--- trunk/capplet/Makefile.am	(original)
+++ trunk/capplet/Makefile.am	Thu Jan  8 12:54:11 2009
@@ -23,6 +23,11 @@
 	$(X_LIBS) \
 	$(NULL)
 
+if !HAVE_GETIFADDRS
+INCLUDES += -I../server/libvncserver
+vino_preferences_LDADD += ../server/libvncserver/libifaddrs.la
+endif
+
 gladedir   = $(datadir)/vino
 glade_DATA = vino-preferences.glade
 

Modified: trunk/configure.in
==============================================================================
--- trunk/configure.in	(original)
+++ trunk/configure.in	Thu Jan  8 12:54:11 2009
@@ -259,6 +259,16 @@
 
 AC_CHECK_HEADERS([netinet/in.h sys/time.h fcntl.h unistd.h sys/socket.h signal.h ifaddrs.h net/if.h])
 AC_CHECK_FUNCS([gettimeofday])
+AC_CHECK_LIB(resolv, herror)
+
+dnl Check for getifaddrs
+AC_TRY_COMPILE([
+      #include <ifaddrs.h>
+    ],[
+      struct ifaddrs *myaddrs;
+      getifaddrs (&myaddrs);
+    ], have_getifaddrs=yes, have_getifaddrs=no)
+AM_CONDITIONAL(HAVE_GETIFADDRS, [test $"$have_getifaddrs" = "yes"])
 
 dnl
 dnl End of libvncserver stuff

Modified: trunk/server/libvncserver/Makefile.am
==============================================================================
--- trunk/server/libvncserver/Makefile.am	(original)
+++ trunk/server/libvncserver/Makefile.am	Thu Jan  8 12:54:11 2009
@@ -37,6 +37,14 @@
 	$(LIBGCRYPT_LIBS)	\
 	$(NULL)
 
+if !HAVE_GETIFADDRS
+noinst_LTLIBRARIES += libifaddrs.la
+libifaddrs_la_SOURCES = 	\
+	getifaddrs.c 		\
+	ifaddrs.h
+libvncserver_la_LIBADD += ./libifaddrs.la
+endif
+
 EXTRA_DIST =			\
 	tableinit24.c		\
 	tableinittctemplate.c	\

Added: trunk/server/libvncserver/getifaddrs.c
==============================================================================
--- (empty file)
+++ trunk/server/libvncserver/getifaddrs.c	Thu Jan  8 12:54:11 2009
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc.. All rights reserved.
+ * Use is subject to license terms
+ *
+ *  Author: James Carlson, James D Carlson Sun COM
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/sockio.h>
+#include <sys/socket.h>
+#include <net/if.h>
+
+#include "ifaddrs.h"
+
+static int
+get_lifreq(int fd, struct lifreq **ifr_ret)
+{
+	struct lifnum lifn;
+	struct lifconf lifc;
+	struct lifreq *lifrp;
+
+	lifn.lifn_family = AF_UNSPEC;
+	lifn.lifn_flags = 0;
+	if (ioctl(fd, SIOCGLIFNUM, &lifn) == -1)
+		lifn.lifn_count = 16;
+	else
+		lifn.lifn_count += 16;
+
+	for (;;) {
+		lifc.lifc_len = lifn.lifn_count * sizeof (*lifrp);
+		lifrp = malloc(lifc.lifc_len);
+		if (lifrp == NULL)
+			return (-1);
+
+		lifc.lifc_family = AF_UNSPEC;
+		lifc.lifc_flags = 0;
+		lifc.lifc_buf = (char *)lifrp;
+		if (ioctl(fd, SIOCGLIFCONF, &lifc) == -1) {
+			free(lifrp);
+			if (errno == EINVAL) {
+				lifn.lifn_count <<= 1;
+				continue;
+			}
+			(void) close(fd);
+			return (-1);
+		}
+		if (lifc.lifc_len < (lifn.lifn_count - 1) * sizeof (*lifrp))
+			break;
+		free(lifrp);
+		lifn.lifn_count <<= 1;
+	}
+
+	*ifr_ret = lifrp;
+
+	return (lifc.lifc_len / sizeof (*lifrp));
+}
+
+static size_t
+nbytes(const struct lifreq *lifrp, int nlif, size_t socklen)
+{
+	size_t len = 0;
+	size_t slen;
+
+	while (nlif > 0) {
+		slen = strlen(lifrp->lifr_name) + 1;
+		len += sizeof (struct ifaddrs) + ((slen + 3) & ~3);
+		len += 3 * socklen;
+		lifrp++;
+		nlif--;
+	}
+	return (len);
+}
+
+static struct sockaddr *
+addrcpy(struct sockaddr_storage *addr, char **bufp)
+{
+	char *buf = *bufp;
+	size_t len;
+
+	len = addr->ss_family == AF_INET ? sizeof (struct sockaddr_in) :
+	    sizeof (struct sockaddr_in6);
+	(void) memcpy(buf, addr, len);
+	*bufp = buf + len;
+	return ((struct sockaddr *)buf);
+}
+
+static int
+populate(struct ifaddrs *ifa, int fd, struct lifreq *lifrp, int nlif, int af,
+    char **bufp)
+{
+	char *buf = *bufp;
+	size_t slen;
+
+	while (nlif > 0) {
+		ifa->ifa_next = (nlif > 1) ? ifa + 1 : NULL;
+		(void) strcpy(ifa->ifa_name = buf, lifrp->lifr_name);
+		slen = strlen(lifrp->lifr_name) + 1;
+		buf += (slen + 3) & ~3;
+		if (ioctl(fd, SIOCGLIFFLAGS, lifrp) == -1)
+			ifa->ifa_flags = 0;
+		else
+			ifa->ifa_flags = lifrp->lifr_flags;
+		if (ioctl(fd, SIOCGLIFADDR, lifrp) == -1)
+			ifa->ifa_addr = NULL;
+		else
+			ifa->ifa_addr = addrcpy(&lifrp->lifr_addr, &buf);
+		if (ioctl(fd, SIOCGLIFNETMASK, lifrp) == -1)
+			ifa->ifa_netmask = NULL;
+		else
+			ifa->ifa_netmask = addrcpy(&lifrp->lifr_addr, &buf);
+		if (ifa->ifa_flags & IFF_POINTOPOINT) {
+			if (ioctl(fd, SIOCGLIFDSTADDR, lifrp) == -1)
+				ifa->ifa_dstaddr = NULL;
+			else
+				ifa->ifa_dstaddr =
+				    addrcpy(&lifrp->lifr_dstaddr, &buf);
+		} else if (ifa->ifa_flags & IFF_BROADCAST) {
+			if (ioctl(fd, SIOCGLIFBRDADDR, lifrp) == -1)
+				ifa->ifa_broadaddr = NULL;
+			else
+				ifa->ifa_broadaddr =
+				    addrcpy(&lifrp->lifr_broadaddr, &buf);
+		} else {
+			ifa->ifa_dstaddr = NULL;
+		}
+
+		ifa++;
+		nlif--;
+		lifrp++;
+	}
+	*bufp = buf;
+	return (0);
+}
+
+int
+getifaddrs(struct ifaddrs **ifap)
+{
+	int fd4, fd6;
+	int nif4, nif6 = 0;
+	struct lifreq *ifr4 = NULL;
+	struct lifreq *ifr6 = NULL;
+	struct ifaddrs *ifa = NULL;
+	char *buf;
+
+	if ((fd4 = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
+		return (-1);
+	if ((fd6 = socket(AF_INET6, SOCK_DGRAM, 0)) == -1 &&
+	    errno != EAFNOSUPPORT) {
+		(void) close(fd4);
+		return (-1);
+	}
+
+	if ((nif4 = get_lifreq(fd4, &ifr4)) == -1 ||
+	    (fd6 != -1 && (nif6 = get_lifreq(fd6, &ifr6)) == -1))
+		goto failure;
+
+	if (nif4 == 0 && nif6 == 0) {
+		*ifap = NULL;
+		return (0);
+	}
+
+	ifa = malloc(nbytes(ifr4, nif4, sizeof (struct sockaddr_in)) +
+	    nbytes(ifr6, nif6, sizeof (struct sockaddr_in6)));
+	if (ifa == NULL)
+		goto failure;
+
+	buf = (char *)(ifa + nif4 + nif6);
+
+	if (populate(ifa, fd4, ifr4, nif4, AF_INET, &buf) == -1)
+		goto failure;
+	if (nif4 > 0 && nif6 > 0)
+		ifa[nif4 - 1].ifa_next = ifa + nif4;
+	if (populate(ifa + nif4, fd6, ifr6, nif6, AF_INET6, &buf) == -1)
+		goto failure;
+
+	*ifap = ifa;
+	return (0);
+
+failure:
+	free(ifa);
+	(void) close(fd4);
+	if (fd6 != -1)
+		(void) close(fd6);
+	free(ifr4);
+	free(ifr6);
+	return (-1);
+}
+
+void
+freeifaddrs(struct ifaddrs *ifa)
+{
+	free(ifa);
+}

Added: trunk/server/libvncserver/ifaddrs.h
==============================================================================
--- (empty file)
+++ trunk/server/libvncserver/ifaddrs.h	Thu Jan  8 12:54:11 2009
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc.. All rights reserved.
+ * Use is subject to license terms
+ *
+ *  Author: James Carlson, James D Carlson Sun COM
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __IFADDRS_H
+#define __IFADDRS_H
+
+#include <sys/types.h>
+
+#undef ifa_broadaddr
+#undef ifa_dstaddr
+struct ifaddrs {
+	struct ifaddrs	*ifa_next;	/* Pointer to next struct */
+	char		*ifa_name;	/* Interface name */
+	uint64_t	ifa_flags;	/* Interface flags */
+	struct sockaddr	*ifa_addr;	/* Interface address */
+	struct sockaddr	*ifa_netmask;	/* Interface netmask */
+	struct sockaddr	*ifa_dstaddr;	/* P2P interface destination */
+};
+#define	ifa_broadaddr	ifa_dstaddr
+
+extern int getifaddrs(struct ifaddrs **);
+extern void freeifaddrs(struct ifaddrs *);
+#endif



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]