From 3a7bd2d32c872a31ae00cc073a197bddeab4c5cc Mon Sep 17 00:00:00 2001
From: Tim Niemeyer <reddog@mastersword.de>
Date: Sun, 6 Jul 2008 12:21:01 +0200
Subject: [PATCH] This patch add support for an overriding config file in gypsy.
 If /etc/gypsy.conf is there, all incomming calls for a device a directed
 to the device specified in the config file.
 The config file holds also start programs that are executed when gypsy
 creates the device or when the devices gets started.

Signed-off-by: Tim Niemeyer <reddog@mastersword.de>
---
 packages/gypsy/files/test.patch |  303 +++++++++++++++++++++++++++++++++++++++
 packages/gypsy/gypsy_svn.bb     |    3 +-
 2 files changed, 305 insertions(+), 1 deletions(-)
 create mode 100644 packages/gypsy/files/test.patch

diff --git a/packages/gypsy/files/test.patch b/packages/gypsy/files/test.patch
new file mode 100644
index 0000000..8412343
--- /dev/null
+++ b/packages/gypsy/files/test.patch
@@ -0,0 +1,303 @@
+--- ../moko2-tmp/test/gypsy.org/src/main.c	2008-07-02 16:34:30.000000000 +0200
++++ gypsy-0.6/src/main.c	2008-07-05 12:13:12.000000000 +0200
+@@ -34,9 +34,19 @@
+ char* nmea_log = NULL;
+ 
+ static void
+-gypsy_terminate (GObject *object,
++gypsy_terminate (GypsyServer *object,
+ 		 gpointer userdata)
+ {
++	if( object->conf )
++	{
++		g_debug("freeing config ");
++		g_free( object->conf );
++	}
++	else
++	{
++		g_debug("no need to free config");
++	}
++
+ 	g_main_loop_quit (mainloop);
+ }
+ 
+@@ -83,6 +93,9 @@
+ 	gboolean become_daemon = FALSE;
+ 	char *pidfile = NULL;
+ 	char *user_pidfile = NULL;
++	GKeyFile *keyfile;
++	GKeyFileFlags flags;
++	GypsySettings *conf;
+ 
+ 	GOptionEntry entries[] = {
+ 		{ "nmea-log", 0, 0, G_OPTION_ARG_FILENAME, &nmea_log, "Log NMEA data to FILE.[device]", "FILE" },
+@@ -135,6 +148,23 @@
+ 
+ 	umask (022);
+ 
++	keyfile = g_key_file_new ();
++	flags = G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS;
++
++	if (g_key_file_load_from_file(keyfile, "/etc/gypsy.conf", flags, NULL))
++	{
++		conf = g_new(GypsySettings, 1);
++		conf->device_name = g_key_file_get_string(keyfile, "gypsy", "device_name", NULL);
++		conf->create_start_before = g_key_file_get_string(keyfile, "create", "start_before", NULL);
++		conf->create_start_after  = g_key_file_get_string(keyfile, "create", "start_after", NULL);
++		conf->device_start_before = g_key_file_get_string(keyfile, "device", "start_before", NULL);
++		conf->device_start_after  = g_key_file_get_string(keyfile, "device", "start_after", NULL);
++	}
++	else
++	{
++		conf = NULL;
++	}
++
+ 	g_type_init ();
+ 
+ 	mainloop = g_main_loop_new (NULL, FALSE);
+@@ -163,6 +193,7 @@
+ 	}
+ 
+ 	gypsy = g_object_new (GYPSY_TYPE_SERVER, NULL);
++	gypsy->conf = conf;
+ 	g_signal_connect (G_OBJECT (gypsy), "terminate",
+ 			  G_CALLBACK (gypsy_terminate), NULL);
+ 
+--- ../moko2-tmp/test/gypsy.org/src/gypsy-server.c	2008-07-02 16:34:30.000000000 +0200
++++ gypsy-0.6/src/gypsy-server.c	2008-07-05 18:21:48.000000000 +0200
+@@ -19,6 +19,8 @@
+ #include <dbus/dbus-glib-bindings.h>
+ #include <dbus/dbus-glib-lowlevel.h>
+ 
++#include <unistd.h>
++
+ #include "gypsy-server.h"
+ #include "gypsy-client.h"
+ 
+@@ -86,11 +88,33 @@
+ {
+ 	GypsyServerPrivate *priv;
+ 	GypsyClient *client;
+-	char *path, *device_name, *sender;
++	char *in_device_path, *path, *device_name, *sender;
+ 	GList *list;
+ 
+ 	priv = GET_PRIVATE (gps);
+ 
++	if (gps->conf)
++	{
++		g_debug ("Having config gile, overriding %s with %s", IN_device_path, gps->conf->device_name);
++		in_device_path = g_strdup_printf("%s", gps->conf->device_name);
++		if (gps->conf->create_start_before)
++		{
++			g_warning("Starte \"%s\"", gps->conf->create_start_before);
++			//fork();
++			if (!g_spawn_command_line_async(gps->conf->create_start_before, NULL))
++			//if (execlp(gps->conf->create_start_before, NULL)==-1)
++			{
++				g_warning("Unable to start create_start_before (%s)", 
++						gps->conf->create_start_before);
++			}
++		}
++			
++	}
++	else
++	{
++		in_device_path = g_strdup_printf("%s", IN_device_path);
++	}
++
+ 	/* We might be in the termination timeout when we receive a new
+ 	   create request, so cancel that timeout */
+ 	if (priv->terminate_id > 0) {
+@@ -98,8 +122,8 @@
+ 		priv->terminate_id = 0;
+ 	}
+ 
+-	g_debug ("Creating client for %s", IN_device_path);
+-	device_name = g_path_get_basename (IN_device_path);
++	g_debug ("Creating client for %s", in_device_path);
++	device_name = g_path_get_basename (in_device_path);
+ 	g_debug ("Device name: %s", device_name);
+ 	path = g_strdup_printf ("%s%s", GYPSY_GPS_PATH, 
+ 				g_strdelimit (device_name, ":", '_'));
+@@ -110,8 +134,13 @@
+ 		/* If there isn't already an object registered on that path
+ 		   create and register it */
+ 		client = g_object_new (GYPSY_TYPE_CLIENT, 
+-				       "device_path", IN_device_path,
++				       "device_path", in_device_path,
+ 				       NULL);
++
++		if (gps->conf)
++			client->conf = gps->conf;
++		else
++			client->conf = NULL;
+ 	
+ 		dbus_g_connection_register_g_object (priv->connection, path,
+ 						     G_OBJECT (client));
+@@ -132,6 +161,22 @@
+ 	priv->client_count++;
+ 
+ 	dbus_g_method_return (context, path);
++
++	if (gps->conf)
++	{
++		if (gps->conf->create_start_after)
++		{
++			g_warning("Starte \"%s\"", gps->conf->create_start_after);
++			if (!g_spawn_command_line_async(gps->conf->create_start_after, NULL))
++			{
++				g_warning("Unable to start create_start_after (%s)", 
++						gps->conf->create_start_after);
++			}
++		}
++			
++	}
++
++	g_free (in_device_path);
+ 	g_free (path);
+ }
+ 
+@@ -143,12 +188,17 @@
+ 	GypsyServerPrivate *priv;
+ 	GypsyClient *client;
+ 	GList *list, *owner;
+-	char *path, *device_name, *sender;
++	char *in_device_path, *path, *device_name, *sender;
++	
++	if (IN_device_path[0]=='\0')
++		in_device_path = g_strdup_printf("default");
++	else
++		in_device_path = g_strdup_printf("%s", IN_device_path);
+ 
+ 	priv = GET_PRIVATE (gps);
+ 
+-	g_debug ("Finding client for %s", IN_device_path);
+-	device_name = g_path_get_basename (IN_device_path);
++	g_debug ("Finding client for %s", in_device_path);
++	device_name = g_path_get_basename (in_device_path);
+ 	g_debug ("Device name: %s", device_name);
+ 	path = g_strdup_printf ("%s%s", GYPSY_GPS_PATH, device_name);
+ 	g_free (device_name);
+--- ../moko2-tmp/test/gypsy/src/gypsy-client.c	2008-07-02 17:37:21.000000000 +0200
++++ gypsy-0.6/src/gypsy-client.c	2008-07-05 18:28:19.000000000 +0200
+@@ -324,12 +324,33 @@
+ 		g_debug ("Connection to %s already started", priv->device_path);
+ 		return TRUE;
+ 	}
++	
++	if (client->conf)
++	{
++		if (client->conf->device_start_before)
++			{
++				g_warning("Starte \"%s\"", client->conf->device_start_before);
++				if (!g_spawn_command_line_async(client->conf->device_start_before, NULL))
++				{
++					g_warning("Unable to start device_start_before (%s)", 
++					client->conf->device_start_before);
++				}
++			}
++	}
++
+ 
+ 	/* Open a connection to our device */
+ 	if (priv->device_path[0] == '/') {
+ 		struct termios term;
+ 
+ 		priv->fd = open (priv->device_path, O_RDONLY | O_NOCTTY | O_NONBLOCK);
++
++		if (priv->fd==-1)
++		{
++			g_warning("Error, no such file (%s)!", priv->device_path);
++			g_set_error (error, GYPSY_ERROR, errno, g_strerror (errno));
++			return FALSE;
++		}
+ 		
+ 		if (tcgetattr (priv->fd, &term) < 0) {
+ 			g_warning ("Error getting term");
+@@ -443,6 +464,20 @@
+ 		}
+ 	}
+ #endif
++
++	if (client->conf)
++	{
++		if (client->conf->device_start_after)
++			{
++				g_warning("Starte \"%s\"", client->conf->device_start_after);
++				if (!g_spawn_command_line_async(client->conf->device_start_after, NULL))
++				{
++					g_warning("Unable to start device_start_after (%s)", 
++					client->conf->device_start_after);
++				}
++			}
++	}
++
+ 	return TRUE;
+ }
+ 
+--- ../moko2-tmp/test/gypsy/src/gypsy-client.h	2008-07-02 16:34:45.000000000 +0200
++++ gypsy-0.6/src/gypsy-client.h	2008-07-05 18:47:23.000000000 +0200
+@@ -14,6 +14,9 @@
+ 
+ #include <glib-object.h>
+ 
++#include "gypsy-settings.h"
++
++
+ G_BEGIN_DECLS
+ 
+ #define GYPSY_TYPE_CLIENT (gypsy_client_get_type ())
+@@ -60,6 +63,7 @@
+ 
+ typedef struct _GypsyClient {
+ 	GObject parent_object;
++	GypsySettings *conf;
+ } GypsyClient;
+ 
+ typedef struct _GypsyClientClass {
+--- ../moko2-tmp/test/gypsy/src/gypsy-server.h	2008-07-02 16:34:45.000000000 +0200
++++ gypsy-0.6/src/gypsy-server.h	2008-07-05 18:46:59.000000000 +0200
+@@ -13,6 +13,7 @@
+ #define __GYPSY_SERVER_H__
+ 
+ #include <glib-object.h>
++#include "gypsy-settings.h"
+ 
+ G_BEGIN_DECLS
+ 
+@@ -26,6 +27,7 @@
+ 
+ typedef struct _GypsyServer {
+ 	GObject parent_object;
++	GypsySettings *conf;
+ } GypsyServer;
+ 
+ typedef struct _GypsyServerClass {
+--- /dev/null	2008-07-04 09:52:03.892037460 +0200
++++ gypsy-0.6/src/gypsy-settings.h	2008-07-05 18:46:08.000000000 +0200
+@@ -0,0 +1,24 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++/*
++ * Gypsy
++ *
++ * A simple to use and understand GPSD replacement
++ * that uses D-Bus, GLib and memory allocations
++ *
++ * Author: Iain Holmes <iain@gnome.org>
++ * Copyright (C) 2007
++ */
++
++#ifndef __GYPSY_SETTINGS_H__
++#define __GYPSY_SETTINGS_H__
++
++typedef struct _GypsySettings {
++	char *device_name;
++	char *create_start_before;
++	char *create_start_after;
++	char *device_start_before;
++	char *device_start_after;
++} GypsySettings;
++
++
++#endif
diff --git a/packages/gypsy/gypsy_svn.bb b/packages/gypsy/gypsy_svn.bb
index 0e2be88..89c808b 100644
--- a/packages/gypsy/gypsy_svn.bb
+++ b/packages/gypsy/gypsy_svn.bb
@@ -5,7 +5,8 @@ DEFAULT_PREFERENCE = "-1"
 SRC_URI = "svn://svn.o-hand.com/repos/${PN}/trunk;module=${PN};proto=http \
            file://fixups.patch;patch=1;maxrev=107 \
            file://docs-reference-am.patch;patch=1;minrev=134 \
-	   file://allow-open-files.patch;patch=1"
+	   file://allow-open-files.patch;patch=1 \
+	   file://test.patch;patch=1"
 
 PV = "0.0+svnr${SRCPV}"
 PR = "r2"
-- 
1.5.6

