61729ad3481820fa979a2321a2d97bb9114c66bf
[loudgame] / lg-echo.c
1 /*
2  * Copyright (C) 2003-2004 Imendio AB
3  * Copyright (C) 2008 Carl Worth
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public License as
7  * published by the Free Software Foundation; either version 2 of the
8  * License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this program; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  *
20  * Authors: Imendio AB
21  *          Carl Worth <cworth@cworth.org>
22  */
23  
24 #include <glib.h>
25 #include <string.h>
26 #include <stdlib.h>
27 #include <loudmouth/loudmouth.h>
28 #ifdef __WIN32__
29 #include <winsock2.h>
30 #endif
31  
32 typedef struct _loudgame {
33     gchar               *server;
34     gchar               *name;
35     gchar               *passwd;
36     LmConnection        *connection;
37     GMainLoop           *main_loop;
38     int                  return_value;
39 } loudgame_t;
40
41 static void
42 loudgame_quit (loudgame_t *lg, int return_value)
43 {
44     GError *error;
45
46     lg->return_value = return_value;
47
48     if (! lm_connection_close (lg->connection, &error))
49         g_print ("An error occurred during lm_connection_close: %s\n",
50                  error->message);
51
52     lm_connection_unref (lg->connection);
53
54     g_main_loop_quit (lg->main_loop);
55 }
56  
57 static void
58 authentication_cb (LmConnection *connection, gboolean result, gpointer closure)
59 {
60     LmMessage *m;
61     loudgame_t *lg = closure;
62
63     if (! result) {
64         g_print ("Authentication for %s failed\n", lg->name);
65         loudgame_quit (lg, 1);
66         return;
67     }
68                  
69     m = lm_message_new_with_sub_type (NULL,
70                                       LM_MESSAGE_TYPE_PRESENCE,
71                                       LM_MESSAGE_SUB_TYPE_AVAILABLE);
72
73     lm_connection_send (connection, m, NULL);
74     lm_message_unref (m);
75 }
76  
77 static void
78 connection_open_cb (LmConnection *connection, gboolean result, loudgame_t *lg)
79 {
80     lm_connection_authenticate (connection,
81                                 lg->name, lg->passwd, "TestLM",
82                                 authentication_cb, lg, FALSE,  NULL);
83 }
84
85 static void
86 send_reply (LmConnection        *connection,
87             const char          *peer,
88             const char          *message,
89             loudgame_t          *lg)
90 {
91     LmMessage *reply;
92     gboolean result;
93     GError *error = NULL;
94
95     reply = lm_message_new (peer, LM_MESSAGE_TYPE_MESSAGE);
96
97     lm_message_node_add_child (reply->node, "body", message);
98
99     result = lm_connection_send (connection, reply, &error);
100     lm_message_unref (reply);
101
102     if (! result) {
103         g_error ("lm_connection_send failed: error->message");
104         loudgame_quit (lg, 1);
105     }
106 }
107
108 static void
109 handle_command (LmConnection    *connection,
110                 const char      *peer,
111                 const char      *command,
112                 loudgame_t      *lg)
113 {
114     char *error;
115
116     if (strcmp (command, "quit") == 0) {
117         loudgame_quit (lg, 0);
118         return;
119     }
120
121     error = g_strdup_printf ("Unknown command: '%s'", command);
122     send_reply (connection, peer, error, lg);
123     free (error);
124 }
125  
126 static LmHandlerResult
127 handle_messages (LmMessageHandler *handler,
128                  LmConnection     *connection,
129                  LmMessage        *m,
130                  gpointer          closure)
131 {
132     loudgame_t *lg = closure;
133     LmMessageNode *body;
134     const char *peer;
135     const char *body_str;
136
137     peer = lm_message_node_get_attribute (m->node, "from");
138
139     body = lm_message_node_get_child (m->node, "body");
140     if (body) {
141         body_str = lm_message_node_get_value (body);
142
143         if (body_str && body_str[0] == '%')
144             handle_command (connection, peer, body_str + 1, lg);
145         else
146             send_reply (connection, peer, body_str, lg);
147     }
148         
149     return LM_HANDLER_RESULT_REMOVE_MESSAGE;
150 }
151
152 static gboolean
153 make_connection (gpointer closure)
154 {
155     loudgame_t       *lg;
156     LmMessageHandler *handler;
157     gchar            *jid;
158     GError           *error;
159
160     lg = closure;
161                                                                                 
162     lg->connection = lm_connection_new (lg->server);
163
164     jid = g_strdup_printf ("%s@%s", lg->name, lg->server);
165     lm_connection_set_jid (lg->connection, jid);
166     g_free (jid);
167
168     handler = lm_message_handler_new (handle_messages, lg, NULL);
169     lm_connection_register_message_handler (lg->connection,
170                                             handler,
171                                             LM_MESSAGE_TYPE_MESSAGE,
172                                             LM_HANDLER_PRIORITY_NORMAL);
173                                                                                 
174     lm_message_handler_unref (handler);
175                                                                                 
176     if (! lm_connection_open (lg->connection,
177                               (LmResultFunction) connection_open_cb,
178                               lg, NULL, &error))
179     {
180         g_print ("Opening connection failed: %s\n", error->message);
181         loudgame_quit (lg, 1);
182     }
183
184     /* Return false to not schedule another call. */
185     return 0;
186 }
187
188 int
189 main (int argc, char **argv)
190 {
191     loudgame_t lg;
192
193     if (argc != 4) {
194         g_print ("Usage: %s <server> <username> <password>\n", argv[0]);
195         return 1;
196     }
197
198     lg.server = argv[1];
199     lg.name = argv[2];
200     lg.passwd = argv[3];
201
202     lg.connection = NULL;
203
204     lg.main_loop = g_main_loop_new (NULL, FALSE);
205
206     g_idle_add (make_connection, &lg);
207
208     g_main_loop_run (lg.main_loop);
209
210     g_main_loop_unref (lg.main_loop);
211                                                                                 
212     return lg.return_value;
213 }