[gtk-vnc-devel] PATCH: Portability to compile under MinGW for Windows



This patch addresses the (surprisingly few) portability problems which
prevent compilation of gtk-vnc with MinGW. We had already addressed
the major problem with the  pthreads based coroutine in the past, and
this ties up loose ends. The two issues addressed are a drop in impl
of getaddrinfo from GNULIB, and errno / WSAGetLastError() changes.

For those not aware of what gnulib is / does, here's a little background.
GNULIB provides implementations of many POSIX apis to replace/augment/fix
broken/missing impls from various OS. GNULIB is not a library in the normal
sense - you don't link to it, nor is it installed in /usr/lib. GNULIB
is distributed in source form only. As a developer you declare which APIs
you want help from gnulib on, and it has a bootstrap script which pulls 
the source for these APIs into your source directory.  By convention we
place this in gnulib/lib and gnulib/tests. It also provides some autoconf
macros in gnulib/m4 which you call from configure.ac  When configure runs
gnulib probes for the APIs provided by the OS, and if it finds problems
automatically turns on use of the gnulib replacements.

In this case we merely need the getaddrinfo() replacement, so we add a call
to #include "getaddrinfo.h" in src/gvnc.c, and add ../gnulib/lib/gnulib.la
to the LDADD, and -I../gnulib/lib to the CFLAGS. gnulib.la is a static only
library, so it gets linked straight into libgtkvnc.so 

We have used GNULIB very successfully in libvirt to provide portability
to Windows, MacOS and Solaris, so I don't anticipate any problems with 
GTK-VNC.

For the sake of brevity, the patch I'm attaching does /not/ include all 
the files that GNULIB itself will add. I'm just showing the diffs to
existing files. If you want to see what gnulib adds, then just invoke
the 'bootstrap' script after applying this patch. When I actually commit
this to HG, i'll checkin all the stuff GNULIB adds.

NB, make sure you have 'git' installed when running bootstrap since it
checks stuff out of GNULIB's GIT repo directly.

 .hgignore                |   14 ++---
 Makefile.am              |    6 +-
 autogen.sh               |    2 
 b/bootstrap              |   84 +++++++++++++++++++++++++++++++++
 b/src/socketcompat.h     |   64 +++++++++++++++++++++++++
 b/vc-list-files          |  107 ++++++++++++++++++++++++++++++++++++++++++
 configure.ac             |   16 +++++-
 src/Makefile.am          |    8 +--
 src/continuation.c       |    2 
 src/coroutine_gthread.c  |    2 
 src/coroutine_ucontext.c |    2 
 src/gvnc.c               |  118 ++++++++++++++++++++++++++---------------------
 src/vncdisplay.c         |   27 ++++++++--
 13 files changed, 382 insertions(+), 70 deletions(-)

Daniel
-- 
|: Red Hat, Engineering, London   -o-   http://people.redhat.com/berrange/ :|
|: http://libvirt.org  -o-  http://virt-manager.org  -o-  http://ovirt.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505  -o-  F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|
diff -r f1d5c8fae2e9 .hgignore
--- a/.hgignore	Fri Sep 05 13:32:03 2008 +0100
+++ b/.hgignore	Wed Sep 10 09:09:47 2008 -0400
@@ -24,7 +24,7 @@
 ^build
 ^examples/\.deps/
 ^examples/\.libs/
-^examples/gvncviewer$
+^examples/gvncviewer(\.exe)?$
 ^missing$
 ^INSTALL$
 ^depcomp$
@@ -36,9 +36,9 @@
 ^plugin/gtk-vnc-plugin.la$
 ^plugin/gtk_vnc_plugin_la-.*
 ^plugin/gtk-vnc-plugin.so
-
-syntax: glob
-examples/*.o
-src/*.defs
-src/*.orig
-*.spec
+.gnulib
+examples/.*\.o
+src/.*\.defs
+src/.*\.orig
+.*\.spec
+.*\.tar\.gz$
diff -r f1d5c8fae2e9 Makefile.am
--- a/Makefile.am	Fri Sep 05 13:32:03 2008 +0100
+++ b/Makefile.am	Wed Sep 10 09:09:47 2008 -0400
@@ -1,5 +1,9 @@
 
-SUBDIRS = src examples plugin
+SUBDIRS = gnulib/lib src examples plugin gnulib/tests
+
+ACLOCAL_AMFLAGS = -I gnulib/m4
+
+
 
 pkgconfig_DATA = @PACKAGE -1 0 pc
 pkgconfigdir = $(libdir)/pkgconfig
diff -r f1d5c8fae2e9 autogen.sh
--- a/autogen.sh	Fri Sep 05 13:32:03 2008 +0100
+++ b/autogen.sh	Wed Sep 10 09:09:47 2008 -0400
@@ -45,7 +45,7 @@
 fi
 
 libtoolize --copy --force
-aclocal
+aclocal -I gnulib/m4
 autoheader
 automake --add-missing --copy
 autoconf
diff -r f1d5c8fae2e9 bootstrap
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bootstrap	Wed Sep 10 09:09:47 2008 -0400
@@ -0,0 +1,84 @@
+#!/bin/sh
+# Run this after autogen.sh, to pull in all of the gnulib-related bits.
+# It's important to run *after* autogen.sh, since it updates some of
+# the same files autogen.sh does, yet those from gnulib are newer,
+# and match the tests.  So if a gnulib bug has been fixed since the
+# snapshot taken for whatever gettext release you're using, yet you
+# run "make check" against the wrong version, the corresponding unit
+# test in gl-tests/ may well fail.
+
+usage() {
+  echo >&2 "\
+Usage: $0 [OPTION]...
+Bootstrap this package from the checked-out sources.
+
+Options:
+ --gnulib-srcdir=DIRNAME  Specify the local directory where gnulib
+                          sources reside.  Use this if you already
+                          have gnulib sources on your machine, and
+                          do not want to waste your bandwidth downloading
+                          them again.
+
+If the file bootstrap.conf exists in the current working directory, its
+contents are read as shell variables to configure the bootstrap.
+
+Running without arguments will suffice in most cases.
+"
+}
+
+for option
+do
+  case $option in
+  --help)
+    usage
+    exit;;
+  --gnulib-srcdir=*)
+    GNULIB_SRCDIR=`expr "$option" : '--gnulib-srcdir=\(.*\)'`;;
+  *)
+    echo >&2 "$0: $option: unknown option"
+    exit 1;;
+  esac
+done
+
+cleanup_gnulib() {
+  st=$?
+  rm -fr .gnulib
+  exit $st
+}
+
+case ${GNULIB_SRCDIR--} in
+-)
+  if [ ! -d .gnulib ]; then
+    echo "$0: getting gnulib files..."
+
+    trap cleanup_gnulib 1 2 13 15
+
+    git clone --depth 1 git://git.sv.gnu.org/gnulib .gnulib ||
+      cleanup_gnulib
+
+    trap - 1 2 13 15
+  fi
+  GNULIB_SRCDIR=.gnulib
+esac
+
+gnulib_tool=$GNULIB_SRCDIR/gnulib-tool
+<$gnulib_tool || exit
+
+modules='
+getaddrinfo
+vc-list-files
+'
+
+# Tell gnulib to:
+#   require LGPLv2+
+#   put *.m4 files in new gnulib/m4/ dir
+#   put *.[ch] files in new gnulib/lib/ dir.
+
+$gnulib_tool			\
+  --lgpl=2			\
+  --with-tests			\
+  --m4-base=gnulib/m4		\
+  --source-base=gnulib/lib	\
+  --tests-base=gnulib/tests	\
+  --import $modules
+
diff -r f1d5c8fae2e9 configure.ac
--- a/configure.ac	Fri Sep 05 13:32:03 2008 +0100
+++ b/configure.ac	Wed Sep 10 09:09:47 2008 -0400
@@ -23,14 +23,26 @@
 
 AC_CONFIG_HEADERS([config.h:config.hin])
 
-
 AC_CANONICAL_TARGET
 
 AM_INIT_AUTOMAKE(gtk-vnc, 0.3.7)
 
+
+dnl gl_INIT uses m4_foreach_w, yet that is not defined in autoconf-2.59.
+dnl In order to accommodate developers with such old tools, here's a
+dnl replacement definition.
+m4_ifndef([m4_foreach_w],
+  [m4_define([m4_foreach_w],
+    [m4_foreach([$1], m4_split(m4_normalize([$2]), [ ]), [$3])])])
+
+gl_EARLY
+gl_INIT
+
 AC_PROG_CC_STDC
 AM_PROG_CC_C_O
 AC_PROG_LIBTOOL
+
+AC_CHECK_HEADERS([pwd.h winsock2.h])
 
 AC_ARG_WITH(python,
 [  --with-python           build python bindings],
@@ -234,6 +246,8 @@
 
 AC_CONFIG_FILES(
   Makefile
+  gnulib/lib/Makefile
+  gnulib/tests/Makefile
   src/Makefile
   examples/Makefile
   plugin/Makefile
diff -r f1d5c8fae2e9 src/Makefile.am
--- a/src/Makefile.am	Fri Sep 05 13:32:03 2008 +0100
+++ b/src/Makefile.am	Wed Sep 10 09:09:47 2008 -0400
@@ -4,11 +4,13 @@
 lib_LTLIBRARIES = libgtk-vnc-1.0.la
 
 libgtk_vnc_1_0_la_LIBADD = @GTK_LIBS@ @GTKGLEXT_LIBS@ @GNUTLS_LIBS@ \
-			   @GTHREAD_LIBS@
+			   @GTHREAD_LIBS@ \
+                           ../gnulib/lib/libgnu.la
 libgtk_vnc_1_0_la_CFLAGS = @GTK_CFLAGS@ @GTKGLEXT_CFLAGS@ @GNUTLS_CFLAGS@ \
 			   @GTHREAD_CFLAGS@ @WARNING_CFLAGS@ \
 			   -DSYSCONFDIR=\""$(sysconfdir)"\" \
-                           -DG_LOG_DOMAIN=\"gtk-vnc\"
+                           -DG_LOG_DOMAIN=\"gtk-vnc\" \
+                           -I$(top_srcdir)gnulib/lib -I../gnulib/lib
 libgtk_vnc_1_0_la_LDFLAGS = -Wl, @LD_VERSION_SCRIPT_SUPPORT@ \
                             -version-info 0:1:0
 
@@ -22,7 +24,7 @@
 	vncdisplay.h vncdisplay.c \
         vncmarshal.h vncmarshal.c \
 	x_keymap.h x_keymap.c vnc_keycodes.h \
-	utils.h
+	utils.h socketcompat.h
 
 if WITH_UCONTEXT
 libgtk_vnc_1_0_la_SOURCES += continuation.h continuation.c coroutine_ucontext.c
diff -r f1d5c8fae2e9 src/continuation.c
--- a/src/continuation.c	Fri Sep 05 13:32:03 2008 +0100
+++ b/src/continuation.c	Wed Sep 10 09:09:47 2008 -0400
@@ -7,6 +7,8 @@
  *
  *  GTK VNC Widget
  */
+
+#include <config.h>
 
 #include "continuation.h"
 
diff -r f1d5c8fae2e9 src/coroutine_gthread.c
--- a/src/coroutine_gthread.c	Fri Sep 05 13:32:03 2008 +0100
+++ b/src/coroutine_gthread.c	Wed Sep 10 09:09:47 2008 -0400
@@ -7,6 +7,8 @@
  *
  *  GTK VNC Widget
  */
+
+#include <config.h>
 
 #include "coroutine.h"
 #include <stdio.h>
diff -r f1d5c8fae2e9 src/coroutine_ucontext.c
--- a/src/coroutine_ucontext.c	Fri Sep 05 13:32:03 2008 +0100
+++ b/src/coroutine_ucontext.c	Wed Sep 10 09:09:47 2008 -0400
@@ -7,6 +7,8 @@
  *
  *  GTK VNC Widget
  */
+
+#include <config.h>
 
 #include <sys/types.h>
 #include <sys/mman.h>
diff -r f1d5c8fae2e9 src/gvnc.c
--- a/src/gvnc.c	Fri Sep 05 13:32:03 2008 +0100
+++ b/src/gvnc.c	Wed Sep 10 09:09:47 2008 -0400
@@ -8,13 +8,10 @@
  *  GTK VNC Widget
  */
 
+#include <config.h>
+
 #include "gvnc.h"
 
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-#include <netdb.h>
 #include <string.h>
 #include <unistd.h>
 #include <stdio.h>
@@ -40,6 +37,15 @@
 #include <gdk/gdkkeysyms.h>
 
 #include "vnc_keycodes.h"
+#include "socketcompat.h"
+#include "getaddrinfo.h"
+
+/* AI_ADDRCONFIG is missing on some systems and gnulib won't provide it
+   even if its emulated getaddrinfo() for us . */
+#ifndef AI_ADDRCONFIG
+# define AI_ADDRCONFIG 0
+#endif
+
 
 struct wait_queue
 {
@@ -321,10 +327,8 @@
 
 			/* inflate as much as possible */
 			err = inflate(gvnc->strm, Z_SYNC_FLUSH);
-			if (err != Z_OK) {
-				errno = EIO;
-				return -1;
-			}
+			if (err != Z_OK)
+				return -EIO;
 
 			gvnc->uncompressed_length = (uint8_t *)gvnc->strm->next_out - gvnc->uncompressed_buffer;
 			gvnc->compressed_length -= (uint8_t *)gvnc->strm->next_in - gvnc->compressed_buffer;
@@ -352,10 +356,10 @@
 		 * so we must by-pass it */
 		if (gvnc_use_compression(gvnc)) {
 			int ret = gvnc_zread(gvnc, data + offset, len);
-			if (ret == -1) {
+			if (ret < 0) {
 				GVNC_DEBUG("Closing the connection: gvnc_read() - gvnc_zread() failed\n");
 				gvnc->has_error = TRUE;
-				return -errno;
+				return ret;
 			}
 			offset += ret;
 			continue;
@@ -366,16 +370,18 @@
 				ret = gnutls_read(gvnc->tls_session, gvnc->read_buffer, 4096);
 				if (ret < 0) {
 					if (ret == GNUTLS_E_AGAIN)
-						errno = EAGAIN;
+						ret = -EAGAIN;
 					else
-						errno = EIO;
-					ret = -1;
+						ret = -EIO;
 				}
-			} else
+			} else {
 				ret = read(fd, gvnc->read_buffer, 4096);
+				if (ret < 0)
+					ret = socket_errno() * -1;
+			}
 
-			if (ret == -1) {
-				switch (errno) {
+			if (ret < 0) {
+				switch (ret * -1) {
 				case EAGAIN:
 					if (gvnc->wait_interruptable) {
 						if (!g_io_wait_interruptable(&gvnc->wait,
@@ -388,7 +394,7 @@
 				default:
 					GVNC_DEBUG("Closing the connection: gvnc_read() - ret=-1\n");
 					gvnc->has_error = TRUE;
-					return -errno;
+					return ret;
 				}
 			}
 			if (ret == 0) {
@@ -425,17 +431,19 @@
 					   gvnc->write_offset-offset);
 			if (ret < 0) {
 				if (ret == GNUTLS_E_AGAIN)
-					errno = EAGAIN;
+					ret = -EAGAIN;
 				else
-					errno = EIO;
-				ret = -1;
+					ret = -EIO;
 			}
-		} else
+		} else {
 			ret = write(fd,
 				    gvnc->write_buffer+offset,
 				    gvnc->write_offset-offset);
-		if (ret == -1) {
-			switch (errno) {
+			if (ret < 0)
+				ret = socket_errno() * -1;
+		}
+		if (ret < 0) {
+			switch (ret * -1) {
 			case EAGAIN:
 				g_io_wait(gvnc->channel, G_IO_OUT);
 			case EINTR:
@@ -488,7 +496,7 @@
  retry:
 	ret = write(fd, data, len);
 	if (ret < 0) {
-		if (errno == EINTR)
+		if (socket_errno() == EINTR)
 			goto retry;
 		return -1;
 	}
@@ -506,7 +514,7 @@
  retry:
 	ret = read(fd, data, len);
 	if (ret < 0) {
-		if (errno == EINTR)
+		if (socket_errno() == EINTR)
 			goto retry;
 		return -1;
 	}
@@ -2802,12 +2810,12 @@
 	if (gvnc_has_error(gvnc))
 		return FALSE;
 
-	if (!gvnc->fmt.true_color_flag && gvnc->ops.get_preferred_pixel_format)
+	if (!gvnc->fmt.true_color_flag && gvnc->ops.get_preferred_pixel_format) {
 		if (gvnc->ops.get_preferred_pixel_format(gvnc->ops_data, &gvnc->fmt))
 			gvnc_set_pixel_format(gvnc, &gvnc->fmt);
 		else
 			goto fail;
-
+	}
 	memset(&gvnc->strm, 0, sizeof(gvnc->strm));
 	/* FIXME what level? */
 	for (i = 0; i < 5; i++)
@@ -2822,15 +2830,16 @@
 	return !gvnc_has_error(gvnc);
 }
 
-gboolean gvnc_open_fd(struct gvnc *gvnc, int fd)
+static gboolean gvnc_set_nonblock(int fd)
 {
-	int flags;
-	if (gvnc_is_open(gvnc)) {
-		GVNC_DEBUG ("Error: already connected?\n");
+#ifdef __MINGW32__
+	unsigned long flags = 1;
+	if (ioctlsocket(fd, FIONBIO, &flags) < 0) {
+		GVNC_DEBUG ("Failed to set nonblocking flag\n");
 		return FALSE;
 	}
-
-	GVNC_DEBUG("Connecting to FD %d\n", fd);
+#else
+	int flags;
 	if ((flags = fcntl(fd, F_GETFL)) < 0) {
 		GVNC_DEBUG ("Failed to fcntl()\n");
 		return FALSE;
@@ -2840,6 +2849,21 @@
 		GVNC_DEBUG ("Failed to fcntl()\n");
 		return FALSE;
 	}
+#endif
+	return TRUE;
+}
+
+gboolean gvnc_open_fd(struct gvnc *gvnc, int fd)
+{
+	if (gvnc_is_open(gvnc)) {
+		GVNC_DEBUG ("Error: already connected?\n");
+		return FALSE;
+	}
+
+	GVNC_DEBUG("Connecting to FD %d\n", fd);
+
+	if (!gvnc_set_nonblock(fd))
+		return FALSE;
 
 	if (!(gvnc->channel = g_io_channel_unix_new(fd))) {
 		GVNC_DEBUG ("Failed to g_io_channel_unix_new()\n");
@@ -2873,7 +2897,7 @@
 
         runp = ai;
         while (runp != NULL) {
-                int flags, fd;
+                int fd;
                 GIOChannel *chan;
 
 		if ((fd = socket(runp->ai_family, runp->ai_socktype,
@@ -2883,17 +2907,8 @@
 		}
 
                 GVNC_DEBUG("Trying socket %d\n", fd);
-                if ((flags = fcntl(fd, F_GETFL)) < 0) {
-                        close(fd);
-                        GVNC_DEBUG ("Failed to fcntl()\n");
-                        break;
-                }
-                flags |= O_NONBLOCK;
-                if (fcntl(fd, F_SETFL, flags) < 0) {
-                        close(fd);
-                        GVNC_DEBUG ("Failed to fcntl()\n");
-                        break;
-                }
+		if (!gvnc_set_nonblock(fd))
+			break;
 
                 if (!(chan = g_io_channel_unix_new(fd))) {
                         close(fd);
@@ -2904,21 +2919,22 @@
         reconnect:
                 /* FIXME: Better handle EINPROGRESS/EISCONN return values,
                    as explained in connect(2) man page */
-                if ( (connect(fd, runp->ai_addr, runp->ai_addrlen) == 0) || errno == EISCONN) {
+                if ((connect(fd, runp->ai_addr, runp->ai_addrlen) == 0) ||
+		    socket_errno() == EISCONN) {
                         gvnc->channel = chan;
                         gvnc->fd = fd;
                         freeaddrinfo(ai);
                         return !gvnc_has_error(gvnc);
                 }
 
-                if (errno == EINPROGRESS) {
+                if (socket_errno() == EINPROGRESS) {
                         g_io_wait(chan, G_IO_OUT|G_IO_ERR|G_IO_HUP);
                         goto reconnect;
-                } else if (errno != ECONNREFUSED &&
-                           errno != EHOSTUNREACH) {
+                } else if (socket_errno() != ECONNREFUSED &&
+                           socket_errno() != EHOSTUNREACH) {
                         g_io_channel_unref(chan);
                         close(fd);
-                        GVNC_DEBUG ("Failed with errno = %d\n", errno);
+                        GVNC_DEBUG ("Failed with errno = %d\n", socket_errno());
                         break;
                 }
                 close(fd);
diff -r f1d5c8fae2e9 src/socketcompat.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/socketcompat.h	Wed Sep 10 09:09:47 2008 -0400
@@ -0,0 +1,64 @@
+/*
+ * socketcompat.h: Socket compatibility for Windows, making it slightly
+ * less painful to use.
+ *
+ * Use this header under the following circumstances:
+ * (a) Instead of including any of: <net/if.h>, <netinet/in.h>,
+ *     <sys/socket.h>, <netdb.h>, <netinet/tcp.h>, AND
+ * (b) The file will be part of what is built on Windows (basically
+ *     just remote client stuff).
+ *
+ * You need to use socket_errno() instead of errno to get socket
+ * errors.
+ *
+ * Copyright (C) 2008 Red Hat, Inc.
+ *
+ * See COPYING.LIB for the License of this software
+ *
+ * Richard W.M. Jones <rjones redhat com>
+ */
+
+#ifndef __SOCKETCOMPAT_H__
+#define __SOCKETCOMPAT_H__
+
+#include <config.h>
+
+#include <errno.h>
+
+#ifndef HAVE_WINSOCK2_H		/* Unix & Cygwin. */
+
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+
+static inline int
+socket_errno (void)
+{
+  return errno;
+}
+
+#else                           /* MinGW & Win32 */
+
+#include <winsock2.h>
+
+/* Socket functions in Windows don't set errno.  Instead of using errno
+ * to test for socket errors, call this function to get the errno.
+ */
+static inline int
+socket_errno (void)
+{
+  return WSAGetLastError ();
+}
+
+/* Compatibility. */
+#define EWOULDBLOCK             WSAEWOULDBLOCK
+#define ECONNREFUSED            WSAECONNREFUSED
+#define EINPROGRESS             WSAEINPROGRESS
+#define EHOSTUNREACH            WSAEHOSTUNREACH
+#define EISCONN                 WSAEISCONN
+
+#endif /* HAVE_WINSOCK2_H */
+
+#endif /* __WINSOCKWRAPPER_H__ */
diff -r f1d5c8fae2e9 src/vncdisplay.c
--- a/src/vncdisplay.c	Fri Sep 05 13:32:03 2008 +0100
+++ b/src/vncdisplay.c	Wed Sep 10 09:09:47 2008 -0400
@@ -7,6 +7,8 @@
  *
  *  GTK VNC Widget
  */
+
+#include <config.h>
 
 #include "vncdisplay.h"
 #include "coroutine.h"
@@ -24,7 +26,9 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <unistd.h>
+#ifdef HAVE_PWD_H
 #include <pwd.h>
+#endif
 
 #if WITH_GTKGLEXT
 #include <gtk/gtkgl.h>
@@ -2192,33 +2196,44 @@
 
 static int vnc_display_set_x509_credential(VncDisplay *obj, const char *name)
 {
-	char sysdir[PATH_MAX], userdir[PATH_MAX];
+	char file[PATH_MAX];
+	char sysdir[PATH_MAX];
+#ifndef __MINGW32__
+	char userdir[PATH_MAX];
 	struct passwd *pw;
-	char file[PATH_MAX];
 	char *dirs[] = { sysdir, userdir };
+#else
+	char *dirs[] = { sysdir };
+#endif
 
 	strncpy(sysdir, SYSCONFDIR "/pki", PATH_MAX-1);
 	sysdir[PATH_MAX-1] = '\0';
 
+#ifndef __MINGW32__
 	if (!(pw = getpwuid(getuid())))
 		return TRUE;
 
 	snprintf(userdir, PATH_MAX-1, "%s/.pki", pw->pw_dir);
 	userdir[PATH_MAX-1] = '\0';
+#endif
 
-	if (vnc_display_best_path(file, PATH_MAX, "CA", "cacert.pem", dirs, 2) < 0)
+	if (vnc_display_best_path(file, PATH_MAX, "CA", "cacert.pem",
+				  dirs, sizeof(dirs)/sizeof(dirs[0])) < 0)
 		return TRUE;
 	gvnc_set_credential_x509_cacert(obj->priv->gvnc, file);
 
 	/* Don't mind failures of CRL */
-	if (vnc_display_best_path(file, PATH_MAX, "CA", "cacrl.pem", dirs, 2) == 0)
+	if (vnc_display_best_path(file, PATH_MAX, "CA", "cacrl.pem",
+				  dirs, sizeof(dirs)/sizeof(dirs[0])) == 0)
 		gvnc_set_credential_x509_cacert(obj->priv->gvnc, file);
 
 	/* Set client key & cert if we have them. Server will reject auth
 	 * if it decides it requires them*/
-	if (vnc_display_best_path(file, PATH_MAX, name, "private/clientkey.pem", dirs, 2) == 0)
+	if (vnc_display_best_path(file, PATH_MAX, name, "private/clientkey.pem",
+				  dirs, sizeof(dirs)/sizeof(dirs[0])) == 0)
 		gvnc_set_credential_x509_key(obj->priv->gvnc, file);
-	if (vnc_display_best_path(file, PATH_MAX, name, "clientcert.pem", dirs, 2) == 0)
+	if (vnc_display_best_path(file, PATH_MAX, name, "clientcert.pem",
+				  dirs, sizeof(dirs)/sizeof(dirs[0])) == 0)
 		gvnc_set_credential_x509_cert(obj->priv->gvnc, file);
 
 	return FALSE;
diff -r f1d5c8fae2e9 vc-list-files
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vc-list-files	Wed Sep 10 09:09:47 2008 -0400
@@ -0,0 +1,107 @@
+#!/bin/sh
+# List version-controlled file names.
+
+# Print a version string.
+scriptversion=2008-07-11.19
+
+# Copyright (C) 2006-2008 Free Software Foundation, Inc.
+
+# 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 3 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, see <http://www.gnu.org/licenses/>.
+
+
+# List the specified version-controlled files.
+# With no argument, list them all.  With a single DIRECTORY argument,
+# list the version-controlled files in that directory.
+
+# If there's an argument, it must be a single, "."-relative directory name.
+# cvsu is part of the cvsutils package: http://www.red-bean.com/cvsutils/
+
+postprocess=
+case $1 in
+  --help) cat <<EOF
+Usage: $0 [-C SRCDIR] [DIR]
+
+Output a list of version-controlled files in DIR (default .), relative to
+SRCDIR (default .).  SRCDIR must be the top directory of a checkout.
+
+Options:
+  --help     print this help, then exit
+  --version  print version number, then exit
+  -C SRCDIR  change directory to SRCDIR before generating list
+
+Report bugs and patches to <bug-gnulib gnu org>.
+EOF
+    exit ;;
+
+  --version)
+    year=`echo "$scriptversion" | sed 's/[^0-9].*//'`
+    cat <<EOF
+vc-list-files $scriptversion
+Copyright (C) $year Free Software Foundation, Inc,
+License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
+This is free software: you are free to change and redistribute it.
+There is NO WARRANTY, to the extent permitted by law.
+EOF
+    exit ;;
+
+  -C)
+    test "$2" = . || postprocess="| sed 's|^|$2/|'"
+    cd "$2" || exit 1
+    shift; shift ;;
+esac
+
+dir=
+case $# in
+  0) ;;
+  1) dir=$1 ;;
+  *) echo "$0: too many arguments" 1>&2
+     echo "Usage: $0 [-C srcdir] [DIR]" 1>&2; exit 1;;
+esac
+
+test "x$dir" = x && dir=.
+
+if test -d .git; then
+  eval exec git ls-files '"$dir"' $postprocess
+elif test -d .hg; then
+  eval exec hg locate '"$dir/*"' $postprocess
+elif test -d .bzr; then
+  test "$postprocess" = '' && postprocess="| sed 's|^\./||'"
+  eval exec bzr ls --versioned '"$dir"' $postprocess
+elif test -d CVS; then
+  test "$postprocess" = '' && postprocess="| sed 's|^\./||'"
+  if test -x build-aux/cvsu; then
+    eval build-aux/cvsu --find --types=AFGM '"$dir"' $postprocess
+  elif (cvsu --help) >/dev/null 2>&1; then
+    eval cvsu --find --types=AFGM '"$dir"' $postprocess
+  else
+    eval awk -F/ \''{			\
+	if (!$1 && $3 !~ /^-/) {	\
+	  f=FILENAME;			\
+	  if (f ~ /CVS\/Entries$/)	\
+	    f = substr(f, 0, length(f)-11); \
+	  print f $2;			\
+	}}'\''				\
+      `find "$dir" -name Entries -print` /dev/null' $postprocess
+  fi
+else
+  echo "$0: Failed to determine type of version control used in `pwd`" 1>&2
+  exit 1
+fi
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:


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