Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 23 Jun 2007 02:52:33 GMT
From:      Andrew Turner <andrew@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 122177 for review
Message-ID:  <200706230252.l5N2qXgL097104@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=122177

Change 122177 by andrew@andrew_hermies on 2007/06/23 02:51:39

	Add facund_server_add_call to register a call handler function in a hash table
	Use trhe hash table to lookup the call handler then execute it
	Add a ping handler to the backend

Affected files ...

.. //depot/projects/soc2007/andrew-update/backend/facund-be.c#8 edit
.. //depot/projects/soc2007/andrew-update/lib/facund_connection.h#3 edit
.. //depot/projects/soc2007/andrew-update/lib/facund_server.c#8 edit

Differences ...

==== //depot/projects/soc2007/andrew-update/backend/facund-be.c#8 (text+ko) ====

@@ -46,6 +46,7 @@
 #include <unistd.h>
 
 #include <facund_connection.h>
+#include <facund_object.h>
 
 /* Check if there are updates every 30min  */
 static const time_t default_check_period = 30 * 60;
@@ -58,6 +59,9 @@
 static char	**get_base_dirs(char *);
 static void	 *do_communication(void *);
 
+static struct facund_response *facund_call_ping(const char *,
+    struct facund_object *);
+
 /*
  * Looks for updates on the system with a root of basedir
  */
@@ -258,6 +262,15 @@
 	return NULL;
 }
 
+static struct facund_response *
+facund_call_ping(const char *id, struct facund_object *obj)
+{
+	printf("CALL: ping\nID: %s\nArgs:\n", id);
+	facund_object_print(obj);
+	putchar('\n');
+	return NULL;
+}
+
 int
 main(int argc __unused, char *argv[] __unused)
 {
@@ -322,6 +335,9 @@
 		errx(1, "Could not open a socket: %s\n", strerror(errno));
 	}
 
+	/* Add the callbacks for each call */
+	facund_server_add_call("ping", facund_call_ping);
+
 	pthread_create(&update_thread, NULL, look_for_updates, base_dirs);
 	pthread_create(&comms_thread, NULL, do_communication, conn);
 

==== //depot/projects/soc2007/andrew-update/lib/facund_connection.h#3 (text+ko) ====

@@ -31,6 +31,7 @@
 #include <sys/types.h>
 
 struct facund_conn;
+struct facund_response;
 
 struct facund_conn	*facund_connect_server(const char *);
 struct facund_conn	*facund_connect_client(const char *);
@@ -45,4 +46,10 @@
 int			 facund_server_finish(struct facund_conn *);
 int			 facund_server_get_request(struct facund_conn *);
 
+/* This is the call handler. The data passed in is the call id and argument */
+typedef struct facund_response *facund_call_cb(const char *, 
+    struct facund_object *);
+
+int	facund_server_add_call(const char *call, facund_call_cb *);
+
 #endif /* FACUND_CONNECT_H */

==== //depot/projects/soc2007/andrew-update/lib/facund_server.c#8 (text+ko) ====

@@ -25,7 +25,12 @@
  *
  */
 
+#include <sys/types.h>
+
 #include <assert.h>
+#include <db.h>
+#include <fcntl.h>
+#include <limits.h>
 #include <stdio.h>
 #include <string.h>
 #include <unistd.h>
@@ -42,6 +47,8 @@
 static void facund_server_end_tag(void *, const XML_Char *);
 static void facund_server_text(void *, const XML_Char *, int);
 
+static DB *call_db = NULL;
+
 /*
  * Waits for a client to connect and send the start message
  * next it replys with the server start and returns
@@ -113,19 +120,62 @@
 	return 0;
 }
 
+/*
+ * Calls the correct function for the given call
+ */
 static void
 facund_server_call(struct facund_conn *conn, const char *name, const char *id,
     struct facund_object *arg)
 {
+	facund_call_cb *cb;
+	DBT key, data;
+	int ret;
+
+	/* Find the callback and execute it if it exists */
+	key.data = __DECONST(void *, name);
+	key.size = (strlen(name) + 1) * sizeof(char);
+	ret = call_db->get(call_db, &key, &data, 0);
+	if (ret == 0) {
+		/* Get the callback and execute it */
+		cb = *(facund_call_cb **)data.data;
+		assert(cb != NULL);
+		cb(id, arg);
+	} else {
+		/* TODO: send a bad request response */
+	}
+
 	/* This is not really a valid command. It is just used for testing */
 	if (strcmp(name, "ping") == 0) {
 		const char *msg = "<pong/>";
 		facund_send(conn, msg, strlen(msg));
 		return;
 	}
-	printf("Call: %s\nID: %s\nArg:\n", name, id);
-	facund_object_print(arg);
-	putchar('\n');
+}
+
+/*
+ * Registers a callback to the system for when a remote call is made
+ */
+int
+facund_server_add_call(const char *call, facund_call_cb *cb)
+{
+	DBT key, data;
+	int ret;
+
+	if (call == NULL || cb == NULL)
+		return -1;
+
+	if (call_db == NULL) {
+		call_db = dbopen(NULL, O_CREAT|O_RDWR, 0, DB_HASH, NULL);
+	}
+
+	/* Store a pointer to the callback for this function */
+	key.data = __DECONST(void *, call);
+	key.size = (strlen(call) + 1) * sizeof(char);
+	data.data = &cb;
+	data.size = sizeof(facund_call_cb *);
+	ret = call_db->put(call_db, &key, &data, R_NOOVERWRITE);
+
+	return ((ret == 0) ? 0 : -1);
 }
 
 static void



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200706230252.l5N2qXgL097104>