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