vino r1042 - in trunk: . capplet server/libvncserver
- From: haltonhuo svn gnome org
- To: svn-commits-list gnome org
- Subject: vino r1042 - in trunk: . capplet server/libvncserver
- Date: Thu, 8 Jan 2009 12:54:12 +0000 (UTC)
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]