28 * An example of how to use Loudmouth with the synchronous API. |
28 * An example of how to use Loudmouth with the synchronous API. |
29 * <informalexample><programlisting> |
29 * <informalexample><programlisting> |
30 * int |
30 * int |
31 * main (int argc, char **argv) |
31 * main (int argc, char **argv) |
32 * { |
32 * { |
33 * LmConnection *connection; |
33 * LmConnection *connection; |
34 * GError *error = NULL; |
34 * GError *error = NULL; |
35 * gint i; |
35 * gint i; |
36 * LmMessage *m; |
36 * LmMessage *m; |
37 * |
37 * |
38 * connection = lm_connection_new ("myserver"); |
38 * connection = lm_connection_new ("myserver"); |
39 * |
39 * |
40 * if (!lm_connection_open_and_block (connection, &error)) { |
40 * if (!lm_connection_open_and_block (connection, &error)) { |
41 * g_error ("Failed to open: %s\n", error->message); |
41 * g_error ("Failed to open: %s\n", error->message); |
42 * } |
42 * } |
43 * |
43 * |
44 * if (!lm_connection_authenticate_and_block (connection, |
44 * if (!lm_connection_authenticate_and_block (connection, |
45 * "username", "password", |
45 * "username", "password", |
46 * "resource", |
46 * "resource", |
47 * &error)) { |
47 * &error)) { |
48 * g_error ("Failed to authenticate: %s\n", error->message); |
48 * g_error ("Failed to authenticate: %s\n", error->message); |
49 * } |
49 * } |
50 * |
50 * |
51 * m = lm_message_new ("recipient", LM_MESSAGE_TYPE_MESSAGE); |
51 * m = lm_message_new ("recipient", LM_MESSAGE_TYPE_MESSAGE); |
52 * lm_message_node_add_child (m->node, "body", "message"); |
52 * lm_message_node_add_child (m->node, "body", "message"); |
53 * |
53 * |
54 * if (!lm_connection_send (connection, m, &error)) { |
54 * if (!lm_connection_send (connection, m, &error)) { |
55 * g_error ("Send failed: %s\n", error->message); |
55 * g_error ("Send failed: %s\n", error->message); |
56 * } |
56 * } |
57 * |
57 * |
58 * lm_message_unref (m); |
58 * lm_message_unref (m); |
59 * |
59 * |
60 * lm_connection_close (connection, NULL); |
60 * lm_connection_close (connection, NULL); |
61 * lm_connection_unref (connection); |
61 * lm_connection_unref (connection); |
62 * |
62 * |
63 * return 0; |
63 * return 0; |
64 * } |
64 * } |
65 * </programlisting></informalexample> |
65 * </programlisting></informalexample> |
66 */ |
66 */ |
67 |
67 |
68 #include <config.h> |
68 #include <config.h> |
102 LmMessageHandler *handler; |
102 LmMessageHandler *handler; |
103 } HandlerData; |
103 } HandlerData; |
104 |
104 |
105 struct _LmConnection { |
105 struct _LmConnection { |
106 /* Parameters */ |
106 /* Parameters */ |
107 GMainContext *context; |
107 GMainContext *context; |
108 gchar *server; |
108 gchar *server; |
109 gchar *jid; |
109 gchar *jid; |
110 gchar *effective_jid; |
110 gchar *effective_jid; |
111 guint port; |
111 guint port; |
112 gboolean use_srv; |
112 gboolean use_srv; |
113 |
113 |
114 LmOldSocket *socket; |
114 LmOldSocket *socket; |
115 LmSSL *ssl; |
115 LmSSL *ssl; |
116 LmProxy *proxy; |
116 LmProxy *proxy; |
117 LmParser *parser; |
117 LmParser *parser; |
118 |
118 |
119 gchar *stream_id; |
119 gchar *stream_id; |
120 |
120 |
121 GHashTable *id_handlers; |
121 GHashTable *id_handlers; |
122 GSList *handlers[LM_MESSAGE_TYPE_UNKNOWN]; |
122 GSList *handlers[LM_MESSAGE_TYPE_UNKNOWN]; |
123 |
123 |
124 /* XMPP1.0 stuff (SASL, resource binding, StartTLS) */ |
124 /* XMPP1.0 stuff (SASL, resource binding, StartTLS) */ |
125 gboolean use_sasl; |
125 gboolean use_sasl; |
126 LmSASL *sasl; |
126 LmSASL *sasl; |
127 gchar *resource; |
127 gchar *resource; |
128 LmMessageHandler *features_cb; |
128 LmMessageHandler *features_cb; |
129 LmMessageHandler *starttls_cb; |
129 LmMessageHandler *starttls_cb; |
130 gboolean tls_started; |
130 gboolean tls_started; |
131 |
131 |
132 /* Communication */ |
132 /* Communication */ |
133 guint open_id; |
133 guint open_id; |
134 LmCallback *open_cb; |
134 LmCallback *open_cb; |
135 |
135 |
136 gboolean async_connect_waiting; |
136 gboolean async_connect_waiting; |
137 gboolean blocking; |
137 gboolean blocking; |
138 |
138 |
139 gboolean cancel_open; |
139 gboolean cancel_open; |
140 LmCallback *auth_cb; |
140 LmCallback *auth_cb; |
141 |
141 |
142 LmCallback *disconnect_cb; |
142 LmCallback *disconnect_cb; |
143 |
143 |
144 LmMessageQueue *queue; |
144 LmMessageQueue *queue; |
145 |
145 |
146 LmConnectionState state; |
146 LmConnectionState state; |
147 |
147 |
148 guint keep_alive_rate; |
148 guint keep_alive_rate; |
149 LmFeaturePing *feature_ping; |
149 LmFeaturePing *feature_ping; |
150 |
150 |
151 gint ref_count; |
151 gint ref_count; |
152 }; |
152 }; |
153 |
153 |
154 typedef enum { |
154 typedef enum { |
155 AUTH_TYPE_PLAIN = 1, |
155 AUTH_TYPE_PLAIN = 1, |
156 AUTH_TYPE_DIGEST = 2, |
156 AUTH_TYPE_DIGEST = 2, |
205 static void connection_message_queue_cb (LmMessageQueue *queue, |
205 static void connection_message_queue_cb (LmMessageQueue *queue, |
206 LmConnection *connection); |
206 LmConnection *connection); |
207 static void |
207 static void |
208 connection_signal_disconnect (LmConnection *connection, |
208 connection_signal_disconnect (LmConnection *connection, |
209 LmDisconnectReason reason); |
209 LmDisconnectReason reason); |
210 static void connection_incoming_data (LmOldSocket *socket, |
210 static void connection_incoming_data (LmOldSocket *socket, |
211 const gchar *buf, |
211 const gchar *buf, |
212 LmConnection *connection); |
212 LmConnection *connection); |
213 static void connection_socket_closed_cb (LmOldSocket *socket, |
213 static void connection_socket_closed_cb (LmOldSocket *socket, |
214 LmDisconnectReason reason, |
214 LmDisconnectReason reason, |
215 LmConnection *connection); |
215 LmConnection *connection); |
216 static void |
216 static void |
217 connection_socket_connect_cb (LmOldSocket *socket, |
217 connection_socket_connect_cb (LmOldSocket *socket, |
218 gboolean result, |
218 gboolean result, |
219 LmConnection *connection); |
219 LmConnection *connection); |
220 static gboolean |
220 static gboolean |
221 connection_get_server_from_jid (const gchar *jid, |
221 connection_get_server_from_jid (const gchar *jid, |
222 gchar **server); |
222 gchar **server); |
223 static void |
223 static void |
224 connection_send_stream_header (LmConnection *connection); |
224 connection_send_stream_header (LmConnection *connection); |
225 static LmHandlerResult |
225 static LmHandlerResult |
226 connection_features_cb (LmMessageHandler *handler, |
226 connection_features_cb (LmMessageHandler *handler, |
227 LmConnection *connection, |
227 LmConnection *connection, |
228 LmMessage *message, |
228 LmMessage *message, |
229 gpointer user_data); |
229 gpointer user_data); |
230 static gboolean connection_old_auth (LmConnection *connection, |
230 static gboolean connection_old_auth (LmConnection *connection, |
231 const gchar *username, |
231 const gchar *username, |
232 const gchar *password, |
232 const gchar *password, |
233 const gchar *resource, |
233 const gchar *resource, |
234 GError **errror); |
234 GError **errror); |
235 |
235 |
236 static void |
236 static void |
237 connection_free_handlers (LmConnection *connection) |
237 connection_free_handlers (LmConnection *connection) |
238 { |
238 { |
239 int i; |
239 int i; |
387 |
387 |
388 lm_message_queue_push_tail (connection->queue, m); |
388 lm_message_queue_push_tail (connection->queue, m); |
389 } |
389 } |
390 |
390 |
391 static void |
391 static void |
392 connection_ping_timed_out (LmFeaturePing *fp, |
392 connection_ping_timed_out (LmFeaturePing *fp, LmConnection *connection) |
393 LmConnection *connection) |
|
394 { |
393 { |
395 connection_do_close (connection); |
394 connection_do_close (connection); |
396 connection_signal_disconnect (connection, |
395 connection_signal_disconnect (connection, |
397 LM_DISCONNECT_REASON_PING_TIME_OUT); |
396 LM_DISCONNECT_REASON_PING_TIME_OUT); |
398 } |
397 } |
753 } |
752 } |
754 |
753 |
755 |
754 |
756 static LmHandlerResult |
755 static LmHandlerResult |
757 _lm_connection_starttls_cb (LmMessageHandler *handler, |
756 _lm_connection_starttls_cb (LmMessageHandler *handler, |
758 LmConnection *connection, |
757 LmConnection *connection, |
759 LmMessage *message, |
758 LmMessage *message, |
760 gpointer user_data) |
759 gpointer user_data) |
761 { |
760 { |
762 if (lm_old_socket_starttls (connection->socket)) { |
761 if (lm_old_socket_starttls (connection->socket)) { |
763 connection->tls_started = TRUE; |
762 connection->tls_started = TRUE; |
764 connection_send_stream_header (connection); |
763 connection_send_stream_header (connection); |
765 } else { |
764 } else { |
797 |
796 |
798 g_return_if_fail (connection != NULL); |
797 g_return_if_fail (connection != NULL); |
799 g_return_if_fail (m != NULL); |
798 g_return_if_fail (m != NULL); |
800 |
799 |
801 connection->stream_id = g_strdup (lm_message_node_get_attribute (m->node, |
800 connection->stream_id = g_strdup (lm_message_node_get_attribute (m->node, |
802 "id"));; |
801 "id")); |
803 |
802 |
804 xmpp_version = lm_message_node_get_attribute (m->node, "version"); |
803 xmpp_version = lm_message_node_get_attribute (m->node, "version"); |
805 if (xmpp_version && strcmp (xmpp_version, "1.0") == 0) { |
804 if (xmpp_version && strcmp (xmpp_version, "1.0") == 0) { |
806 lm_verbose ("XMPP 1.0 stream received: %s\n", |
805 lm_verbose ("XMPP 1.0 stream received: %s\n", |
807 connection->stream_id); |
806 connection->stream_id); |
870 } |
869 } |
871 |
870 |
872 lm_verbose ("Stream error: Unrecognised error\n"); |
871 lm_verbose ("Stream error: Unrecognised error\n"); |
873 reason = LM_DISCONNECT_REASON_ERROR; |
872 reason = LM_DISCONNECT_REASON_ERROR; |
874 connection->stream_id = g_strdup (lm_message_node_get_attribute (m->node, |
873 connection->stream_id = g_strdup (lm_message_node_get_attribute (m->node, |
875 "id"));; |
874 "id")); |
876 connection_do_close (connection); |
875 connection_do_close (connection); |
877 connection_signal_disconnect (connection, reason); |
876 connection_signal_disconnect (connection, reason); |
878 } |
877 } |
879 |
878 |
880 static gint |
879 static gint |
914 connection_do_close (connection); |
913 connection_do_close (connection); |
915 connection_signal_disconnect (connection, reason); |
914 connection_signal_disconnect (connection, reason); |
916 } |
915 } |
917 |
916 |
918 static void |
917 static void |
919 connection_socket_connect_cb (LmOldSocket *socket, |
918 connection_socket_connect_cb (LmOldSocket *socket, |
920 gboolean result, |
919 gboolean result, |
921 LmConnection *connection) |
920 LmConnection *connection) |
922 { |
921 { |
923 if (result == FALSE) { |
922 if (result == FALSE) { |
924 connection_do_close (connection); |
923 connection_do_close (connection); |
925 |
924 |
926 if (connection->open_cb) { |
925 if (connection->open_cb) { |
1418 * A synchronous call to close the connection. When returning the connection is considered to be closed and can be opened again with lm_connection_open(). |
1416 * A synchronous call to close the connection. When returning the connection is considered to be closed and can be opened again with lm_connection_open(). |
1419 * |
1417 * |
1420 * Return value: Returns #TRUE if no errors where detected, otherwise #FALSE. |
1418 * Return value: Returns #TRUE if no errors where detected, otherwise #FALSE. |
1421 **/ |
1419 **/ |
1422 gboolean |
1420 gboolean |
1423 lm_connection_close (LmConnection *connection, |
1421 lm_connection_close (LmConnection *connection, GError **error) |
1424 GError **error) |
|
1425 { |
1422 { |
1426 gboolean no_errors = TRUE; |
1423 gboolean no_errors = TRUE; |
1427 |
1424 |
1428 g_return_val_if_fail (connection != NULL, FALSE); |
1425 g_return_val_if_fail (connection != NULL, FALSE); |
1429 |
1426 |
1455 |
1452 |
1456 return no_errors; |
1453 return no_errors; |
1457 } |
1454 } |
1458 |
1455 |
1459 static void |
1456 static void |
1460 connection_sasl_auth_finished (LmSASL *sasl, |
1457 connection_sasl_auth_finished (LmSASL *sasl, |
1461 LmConnection *connection, |
1458 LmConnection *connection, |
1462 gboolean success, |
1459 gboolean success, |
1463 const gchar *reason) |
1460 const gchar *reason) |
1464 { |
1461 { |
1465 if (!success) { |
1462 if (!success) { |
1466 lm_verbose ("SASL authentication failed, closing connection\n"); |
1463 lm_verbose ("SASL authentication failed, closing connection\n"); |
1467 connection_call_auth_cb (connection, FALSE); |
1464 connection_call_auth_cb (connection, FALSE); |
1468 return; |
1465 return; |
2066 * |
2063 * |
2067 * Registers a #LmMessageHandler to handle incoming messages of a certain type. |
2064 * Registers a #LmMessageHandler to handle incoming messages of a certain type. |
2068 * To unregister the handler call lm_connection_unregister_message_handler(). |
2065 * To unregister the handler call lm_connection_unregister_message_handler(). |
2069 **/ |
2066 **/ |
2070 void |
2067 void |
2071 lm_connection_register_message_handler (LmConnection *connection, |
2068 lm_connection_register_message_handler (LmConnection *connection, |
2072 LmMessageHandler *handler, |
2069 LmMessageHandler *handler, |
2073 LmMessageType type, |
2070 LmMessageType type, |
2074 LmHandlerPriority priority) |
2071 LmHandlerPriority priority) |
2075 { |
2072 { |
2076 HandlerData *hd; |
2073 HandlerData *hd; |
2077 |
2074 |
2078 g_return_if_fail (connection != NULL); |
2075 g_return_if_fail (connection != NULL); |
2079 g_return_if_fail (handler != NULL); |
2076 g_return_if_fail (handler != NULL); |
2096 * |
2093 * |
2097 * Unregisters a handler for @connection. @handler will no longer be called |
2094 * Unregisters a handler for @connection. @handler will no longer be called |
2098 * when incoming messages of @type arrive. |
2095 * when incoming messages of @type arrive. |
2099 **/ |
2096 **/ |
2100 void |
2097 void |
2101 lm_connection_unregister_message_handler (LmConnection *connection, |
2098 lm_connection_unregister_message_handler (LmConnection *connection, |
2102 LmMessageHandler *handler, |
2099 LmMessageHandler *handler, |
2103 LmMessageType type) |
2100 LmMessageType type) |
2104 { |
2101 { |
2105 GSList *l; |
2102 GSList *l; |
2106 |
2103 |
2107 g_return_if_fail (connection != NULL); |
2104 g_return_if_fail (connection != NULL); |
2108 g_return_if_fail (handler != NULL); |
2105 g_return_if_fail (handler != NULL); |