evolution-exchange r1646 - in trunk: . camel



Author: tml
Date: Mon May 12 16:17:28 2008
New Revision: 1646
URL: http://svn.gnome.org/viewvc/evolution-exchange?rev=1646&view=rev

Log:
2008-05-12  Tor Lillqvist  <tml novell com>

	Further outstanding Win32 portability changes.

	* camel/camel-stub.h: Add a separate have_status_thread boolean
	flag to the CamelStub struct. A pthread_t is not necessarily a
	scalar type, it can also be a struct.

	* camel/camel-stub.c: Corresponding changes.

	* camel/camel-stub.c: Include <winsock2.h> on Windows.
	(connect_to_storage): Different implementation on Unix and
	Windows. On Windows, there are no Unix domain sockets, so instead
	we just have the sockaddr_in of a TCP socket bound to the loopback
	interface stored in a plain file. Yes, this is insecure on
	multiple-user machines. Will have to spend more time on this issue
	sometime. Presumably Win32 named pipes are what should be used
	instead.
	(camel_stub_new): Corresponding ifdefs.



Modified:
   trunk/ChangeLog
   trunk/camel/camel-stub.c
   trunk/camel/camel-stub.h

Modified: trunk/camel/camel-stub.c
==============================================================================
--- trunk/camel/camel-stub.c	(original)
+++ trunk/camel/camel-stub.c	Mon May 12 16:17:28 2008
@@ -32,9 +32,14 @@
 
 #include <errno.h>
 #include <string.h>
+
+#ifndef G_OS_WIN32
 #include <sys/socket.h>
 #include <sys/un.h>
 #include <unistd.h>
+#else
+#include <winsock2.h>
+#endif
 
 CamelStub *das_global_camel_stub;
 
@@ -49,6 +54,7 @@
 {
 	stub->read_lock = g_mutex_new ();
 	stub->write_lock = g_mutex_new ();
+	stub->have_status_thread = FALSE;
 }
 
 static void
@@ -57,7 +63,7 @@
 	if (stub->cmd)
 		camel_stub_marshal_free (stub->cmd);
 
-	if (stub->status_thread) {
+	if (stub->have_status_thread) {
 		void *unused;
 
 		/* When we close the command channel, the storage will
@@ -116,6 +122,8 @@
 	CamelStubMarshal *status_channel = stub->status;
 	guint32 retval;
 
+	stub->have_status_thread = TRUE;
+
 	stub->op = camel_operation_new (NULL, NULL);
 	camel_operation_register (stub->op);
 
@@ -138,9 +146,13 @@
 
 	camel_operation_unregister (stub->op);
 
+	stub->have_status_thread = FALSE;
+
 	return NULL;
 }
 
+#ifndef G_OS_WIN32
+
 static int
 connect_to_storage (CamelStub *stub, struct sockaddr_un *sa_un,
 		    CamelException *ex)
@@ -182,6 +194,68 @@
 	return fd;
 }
 
+#else
+
+static int
+connect_to_storage (CamelStub *stub, const char *socket_path,
+		    CamelException *ex)
+{
+	SOCKET fd;
+	struct sockaddr_in *sa_in;
+	gsize contents_length;
+	GError *error = NULL;
+	int rc;
+
+	if (!g_file_get_contents (socket_path, (gchar **) &sa_in,
+				  &contents_length, &error)) {
+		camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
+				      _("Count not read file '%s': %s"),
+				      socket_path, error->message);
+		g_error_free (error);
+		return -1;
+	}
+
+	if (contents_length != sizeof (*sa_in)) {
+		camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
+				      _("Wrong size file '%s'"),
+				      socket_path);
+		g_free (sa_in);
+		return -1;
+	}
+
+	fd = socket (AF_INET, SOCK_STREAM, 0);
+	if (fd == INVALID_SOCKET) {
+		camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
+				      _("Could not create socket: %s"),
+				      g_win32_error_message (WSAGetLastError ()));
+		return -1;
+	}
+	rc = connect (fd, (struct sockaddr *)sa_in, sizeof (*sa_in));
+	g_free (sa_in);
+
+	if (rc == SOCKET_ERROR) {
+		closesocket (fd);
+		if (WSAGetLastError () == WSAECONNREFUSED) {
+			/* The user has an account configured but the
+			 * backend isn't listening, which probably means that
+			 * he doesn't have a license.
+			 */
+			camel_exception_set (ex, CAMEL_EXCEPTION_USER_CANCEL,
+					     "Cancelled");
+		} else {
+			camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
+					      _("Could not connect to %s: %s"),
+					      stub->backend_name,
+					      g_win32_error_message (WSAGetLastError ()));
+		}
+		return -1;
+	}
+	return fd;
+}
+
+#endif
+
+
 /**
  * camel_stub_new:
  * @socket_path: path to the server's UNIX domain socket
@@ -198,9 +272,12 @@
 		CamelException *ex)
 {
 	CamelStub *stub;
+#ifndef G_OS_WIN32
 	struct sockaddr_un sa_un;
+#endif
 	int fd;
 
+#ifndef G_OS_WIN32
 	if (strlen (socket_path) > sizeof (sa_un.sun_path) - 1) {
 		camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
 				      _("Path too long: %s"), socket_path);
@@ -208,18 +285,27 @@
 	}
 	sa_un.sun_family = AF_UNIX;
 	strcpy (sa_un.sun_path, socket_path);
+#endif
 
 	stub = (CamelStub *)camel_object_new (CAMEL_STUB_TYPE);
 	stub->backend_name = g_strdup (backend_name);
 
+#ifndef G_OS_WIN32
 	fd = connect_to_storage (stub, &sa_un, ex);
+#else
+	fd = connect_to_storage (stub, socket_path, ex);
+#endif
 	if (fd == -1) {
 		camel_object_unref (CAMEL_OBJECT (stub));
 		return NULL;
 	}
 	stub->cmd = camel_stub_marshal_new (fd);
 
+#ifndef G_OS_WIN32
 	fd = connect_to_storage (stub, &sa_un, ex);
+#else
+	fd = connect_to_storage (stub, socket_path, ex);
+#endif
 	if (fd == -1) {
 		camel_object_unref (CAMEL_OBJECT (stub));
 		return NULL;

Modified: trunk/camel/camel-stub.h
==============================================================================
--- trunk/camel/camel-stub.h	(original)
+++ trunk/camel/camel-stub.h	Mon May 12 16:17:28 2008
@@ -35,6 +35,7 @@
 
 	CamelOperation *op;      /* for cancelling */
 	pthread_t status_thread;
+	gboolean have_status_thread;
 } CamelStub;
 
 typedef struct {



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