From a812ce8bebf9c5a2408537626e1a8bb593fe9879 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Thu, 10 Jan 2008 14:50:11 -0800 Subject: [PATCH] Separate common code into loudgame.c and demonstrate with separate lg-test and lg-echo programs --- .gitignore | 3 + Makefile | 16 +++- lg-echo.c | 176 +++----------------------------------------- lg-test.c | 30 ++++++++ loudgame.c | 210 +++++++++++++++++++++++++++++++++++++++++++++++++++++ loudgame.h | 52 +++++++++++++ 6 files changed, 318 insertions(+), 169 deletions(-) create mode 100644 lg-test.c create mode 100644 loudgame.c create mode 100644 loudgame.h diff --git a/.gitignore b/.gitignore index 63e96f5..1cc3118 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ *~ *.o lg-echo +lg-test +Makefile.dep + diff --git a/Makefile b/Makefile index de7e1d3..6ac3b61 100644 --- a/Makefile +++ b/Makefile @@ -1,11 +1,19 @@ -ALL=lg-echo +ALL=lg-echo lg-test MYCFLAGS=-Wall `pkg-config --cflags loudmouth-1.0` MYLDFLAGS=`pkg-config --libs loudmouth-1.0` all: $(ALL) -%: %.c - $(CC) $(CFLAGS) $(MYCFLAGS) $(LDFLAGS) $(MYLDFLAGS) -o $@ $^ +%.o: %.c + $(CC) $(CFLAGS) $(MYCFLAGS) -c -o $@ -c $< +%: %.o loudgame.o + $(CC) $(LDLAGS) $(MYLDFLAGS) -o $@ $^ + +Makefile.dep: *.c + $(CC) -M $(CPPFLAGS) $(MYCFLAGS) $^ > $@ +-include Makefile.dep + +.PHONY: clean clean: - rm -f $(ALL) *.o + rm -f $(ALL) *.o Makefile.dep diff --git a/lg-echo.c b/lg-echo.c index d10b20f..e60380c 100644 --- a/lg-echo.c +++ b/lg-echo.c @@ -1,5 +1,4 @@ /* - * Copyright (C) 2003-2004 Imendio AB * Copyright (C) 2008 Carl Worth * * This program is free software: you can redistribute it and/or modify @@ -15,76 +14,18 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/ . * - * Authors: Imendio AB - * Carl Worth + * Author: Carl Worth */ - -#include -#include -#include -#include -#ifdef __WIN32__ -#include -#endif - -typedef struct _loudgame { - gchar *server; - gchar *name; - gchar *passwd; - LmConnection *connection; - GMainLoop *main_loop; - int return_value; -} loudgame_t; - -static void -loudgame_quit (loudgame_t *lg, int return_value) -{ - GError *error; - - lg->return_value = return_value; - - if (! lm_connection_close (lg->connection, &error)) - g_print ("An error occurred during lm_connection_close: %s\n", - error->message); - - lm_connection_unref (lg->connection); - - g_main_loop_quit (lg->main_loop); -} - -static void -authentication_cb (LmConnection *connection, gboolean result, gpointer closure) -{ - LmMessage *m; - loudgame_t *lg = closure; - if (! result) { - g_print ("Authentication for %s failed\n", lg->name); - loudgame_quit (lg, 1); - return; - } - - m = lm_message_new_with_sub_type (NULL, - LM_MESSAGE_TYPE_PRESENCE, - LM_MESSAGE_SUB_TYPE_AVAILABLE); +#include "loudgame.h" - lm_connection_send (connection, m, NULL); - lm_message_unref (m); -} - -static void -connection_open_cb (LmConnection *connection, gboolean result, loudgame_t *lg) -{ - lm_connection_authenticate (connection, - lg->name, lg->passwd, "TestLM", - authentication_cb, lg, FALSE, NULL); -} +#include +#include static void -send_reply (LmConnection *connection, - const char *peer, - const char *message, - loudgame_t *lg) +echo_handle_message (loudgame_t *lg, + const char *peer, + const char *message) { LmMessage *reply; gboolean result; @@ -94,7 +35,7 @@ send_reply (LmConnection *connection, lm_message_node_add_child (reply->node, "body", message); - result = lm_connection_send (connection, reply, &error); + result = lm_connection_send (lg->connection, reply, &error); lm_message_unref (reply); if (! result) { @@ -103,109 +44,14 @@ send_reply (LmConnection *connection, } } -static void -handle_command (LmConnection *connection, - const char *peer, - const char *command, - loudgame_t *lg) -{ - char *error; - - if (strcmp (command, "quit") == 0) { - loudgame_quit (lg, 0); - return; - } - - error = g_strdup_printf ("Unknown command: '%s'", command); - send_reply (connection, peer, error, lg); - free (error); -} - -static LmHandlerResult -handle_messages (LmMessageHandler *handler, - LmConnection *connection, - LmMessage *m, - gpointer closure) -{ - loudgame_t *lg = closure; - LmMessageNode *body; - const char *peer; - const char *body_str; - - peer = lm_message_node_get_attribute (m->node, "from"); - - body = lm_message_node_get_child (m->node, "body"); - if (body) { - body_str = lm_message_node_get_value (body); - - if (body_str && body_str[0] == '%') - handle_command (connection, peer, body_str + 1, lg); - else - send_reply (connection, peer, body_str, lg); - } - - return LM_HANDLER_RESULT_REMOVE_MESSAGE; -} - -static gboolean -make_connection (gpointer closure) -{ - loudgame_t *lg; - LmMessageHandler *handler; - gchar *jid; - GError *error; - - lg = closure; - - lg->connection = lm_connection_new (lg->server); - - jid = g_strdup_printf ("%s@%s", lg->name, lg->server); - lm_connection_set_jid (lg->connection, jid); - g_free (jid); - - handler = lm_message_handler_new (handle_messages, lg, NULL); - lm_connection_register_message_handler (lg->connection, - handler, - LM_MESSAGE_TYPE_MESSAGE, - LM_HANDLER_PRIORITY_NORMAL); - - lm_message_handler_unref (handler); - - if (! lm_connection_open (lg->connection, - (LmResultFunction) connection_open_cb, - lg, NULL, &error)) - { - g_print ("Opening connection failed: %s\n", error->message); - loudgame_quit (lg, 1); - } - - /* Return false to not schedule another call. */ - return 0; -} - int main (int argc, char **argv) { loudgame_t lg; - if (argc != 4) { - g_print ("Usage: %s \n", argv[0]); - return 1; - } - - lg.server = argv[1]; - lg.name = argv[2]; - lg.passwd = argv[3]; - - lg.connection = NULL; - - lg.main_loop = g_main_loop_new (NULL, FALSE); - - g_idle_add (make_connection, &lg); + loudgame_init (&lg, argc, argv); - g_main_loop_run (lg.main_loop); + lg.handle_message = echo_handle_message; - g_main_loop_unref (lg.main_loop); - - return lg.return_value; + return loudgame_run (&lg); } diff --git a/lg-test.c b/lg-test.c new file mode 100644 index 0000000..c9b819b --- /dev/null +++ b/lg-test.c @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2008 Carl Worth + * + * 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/ . + * + * Author: Carl Worth + */ + +#include "loudgame.h" + +int +main (int argc, char **argv) +{ + loudgame_t lg; + + loudgame_init (&lg, argc, argv); + + return loudgame_run (&lg); +} diff --git a/loudgame.c b/loudgame.c new file mode 100644 index 0000000..53b392b --- /dev/null +++ b/loudgame.c @@ -0,0 +1,210 @@ +/* + * Copyright (C) 2003-2004 Imendio AB + * Copyright (C) 2008 Carl Worth + * + * 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/ . + * + * Authors: Imendio AB + * Carl Worth + */ + +#include "loudgame.h" + +#include +#include +#include +#include + +void +loudgame_quit (loudgame_t *lg, int return_value) +{ + GError *error = NULL; + + lg->return_value = return_value; + + if (! lm_connection_close (lg->connection, &error)) + g_print ("An error occurred during lm_connection_close: %s\n", + error->message); + + lm_connection_unref (lg->connection); + + g_main_loop_quit (lg->main_loop); +} + +static void +authentication_cb (LmConnection *connection, gboolean result, gpointer closure) +{ + LmMessage *m; + loudgame_t *lg = closure; + + if (! result) { + g_print ("Authentication for %s failed\n", lg->name); + loudgame_quit (lg, 1); + return; + } + + m = lm_message_new_with_sub_type (NULL, + LM_MESSAGE_TYPE_PRESENCE, + LM_MESSAGE_SUB_TYPE_AVAILABLE); + + lm_connection_send (connection, m, NULL); + lm_message_unref (m); +} + +static void +connection_open_cb (LmConnection *connection, gboolean result, loudgame_t *lg) +{ + lm_connection_authenticate (connection, + lg->name, lg->passwd, "TestLM", + authentication_cb, lg, FALSE, NULL); +} + +static void +send_reply (LmConnection *connection, + const char *peer, + const char *message, + loudgame_t *lg) +{ + LmMessage *reply; + gboolean result; + GError *error = NULL; + + reply = lm_message_new (peer, LM_MESSAGE_TYPE_MESSAGE); + + lm_message_node_add_child (reply->node, "body", message); + + result = lm_connection_send (connection, reply, &error); + lm_message_unref (reply); + + if (! result) { + g_error ("lm_connection_send failed: error->message"); + loudgame_quit (lg, 1); + } +} + +static void +handle_command (LmConnection *connection, + const char *peer, + const char *command, + loudgame_t *lg) +{ + char *error; + + if (strcmp (command, "quit") == 0) { + loudgame_quit (lg, 0); + return; + } + + error = g_strdup_printf ("Unknown command: '%s'", command); + send_reply (connection, peer, error, lg); + free (error); +} + +static LmHandlerResult +handle_messages (LmMessageHandler *handler, + LmConnection *connection, + LmMessage *m, + gpointer closure) +{ + loudgame_t *lg = closure; + LmMessageNode *body; + const char *peer; + const char *body_str; + + peer = lm_message_node_get_attribute (m->node, "from"); + + body = lm_message_node_get_child (m->node, "body"); + if (body) { + body_str = lm_message_node_get_value (body); + + if (body_str && body_str[0] == '%') + handle_command (connection, peer, body_str + 1, lg); + else if (lg->handle_message) + (lg->handle_message) (lg, peer, body_str); + } + + return LM_HANDLER_RESULT_REMOVE_MESSAGE; +} + +static gboolean +make_connection (gpointer closure) +{ + loudgame_t *lg; + LmMessageHandler *handler; + gchar *jid; + GError *error = NULL; + + lg = closure; + + lg->connection = lm_connection_new (lg->server); + + jid = g_strdup_printf ("%s@%s", lg->name, lg->server); + lm_connection_set_jid (lg->connection, jid); + g_free (jid); + + handler = lm_message_handler_new (handle_messages, lg, NULL); + lm_connection_register_message_handler (lg->connection, + handler, + LM_MESSAGE_TYPE_MESSAGE, + LM_HANDLER_PRIORITY_NORMAL); + + lm_message_handler_unref (handler); + + if (! lm_connection_open (lg->connection, + (LmResultFunction) connection_open_cb, + lg, NULL, &error)) + { + g_print ("Failed to open connection to %s: %s.\n", + lg->server, error->message); + loudgame_quit (lg, 1); + } + + /* Return false to not schedule another call. */ + return 0; +} + +int +loudgame_init (loudgame_t *lg, int argc, char **argv) +{ + if (argc != 4) { + g_print ("Usage: %s \n", argv[0]); + return 1; + } + + lg->server = argv[1]; + lg->name = argv[2]; + lg->passwd = argv[3]; + + lg->connection = NULL; + + lg->main_loop = g_main_loop_new (NULL, FALSE); + + lg->return_value = 0; + + lg->handle_message = NULL; + + return 0; +} + +int +loudgame_run (loudgame_t *lg) +{ + g_idle_add (make_connection, lg); + + g_main_loop_run (lg->main_loop); + + g_main_loop_unref (lg->main_loop); + + return lg->return_value; +} diff --git a/loudgame.h b/loudgame.h new file mode 100644 index 0000000..726394b --- /dev/null +++ b/loudgame.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2008 Carl Worth + * + * 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/ . + * + * Author: Carl Worth + */ + +#ifndef __LOUDGAME_H__ +#define __LOUDGAME_H__ + +#include + +typedef struct _loudgame loudgame_t; + +typedef void (*handle_message_cb) (loudgame_t *lg, + const char *peer, + const char *message); + +struct _loudgame { + gchar *server; + gchar *name; + gchar *passwd; + LmConnection *connection; + GMainLoop *main_loop; + int return_value; + + /* Callbacks */ + handle_message_cb handle_message; +}; + +int +loudgame_init (loudgame_t *lg, int argc, char **argv); + +int +loudgame_run (loudgame_t *lg); + +void +loudgame_quit (loudgame_t *lg, int return_value); + +#endif /* __LOUDGAME_H__ */ -- 2.43.0