Mercurial > hg
annotate mcabber/src/xmpp.c @ 1610:6db9f403f707
Replace 'username' with 'jid' in the configuration file
The previous behaviour doesn't make much sense anymore.
MCabber does DNS SRV lookups so providing the server name
is usually not needed.
author | Mikael Berthe <mikael@lilotux.net> |
---|---|
date | Sun, 11 Oct 2009 20:06:47 +0200 |
parents | 351427ef0b4b |
children | f9bf561e54d0 |
rev | line source |
---|---|
29 | 1 /* |
1599 | 2 * xmpp.c -- Jabber protocol handling |
393 | 3 * |
1599 | 4 * Copyright (C) 2008-2009 Frank Zschockelt <mcabber@freakysoft.de> |
5 * Copyright (C) 2005-2009 Mikael Berthe <mikael@lilotux.net> | |
29 | 6 * Parts come from the centericq project: |
7 * Copyright (C) 2002-2005 by Konstantin Klyagin <konst@konst.org.ua> | |
8 * | |
9 * This program is free software; you can redistribute it and/or modify | |
10 * it under the terms of the GNU General Public License as published by | |
11 * the Free Software Foundation; either version 2 of the License, or (at | |
12 * your option) any later version. | |
13 * | |
14 * This program is distributed in the hope that it will be useful, but | |
15 * WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
17 * General Public License for more details. | |
18 * | |
19 * You should have received a copy of the GNU General Public License | |
20 * along with this program; if not, write to the Free Software | |
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 | |
22 * USA | |
23 */ | |
1598 | 24 #include <stdlib.h> |
25 #include <string.h> | |
29 | 26 |
1604
351427ef0b4b
Remove #include's of C files
Mikael Berthe <mikael@lilotux.net>
parents:
1602
diff
changeset
|
27 #include "xmpp.h" |
351427ef0b4b
Remove #include's of C files
Mikael Berthe <mikael@lilotux.net>
parents:
1602
diff
changeset
|
28 #include "xmpp_helper.h" |
351427ef0b4b
Remove #include's of C files
Mikael Berthe <mikael@lilotux.net>
parents:
1602
diff
changeset
|
29 #include "xmpp_iq.h" |
351427ef0b4b
Remove #include's of C files
Mikael Berthe <mikael@lilotux.net>
parents:
1602
diff
changeset
|
30 #include "xmpp_iqrequest.h" |
351427ef0b4b
Remove #include's of C files
Mikael Berthe <mikael@lilotux.net>
parents:
1602
diff
changeset
|
31 #include "xmpp_muc.h" |
351427ef0b4b
Remove #include's of C files
Mikael Berthe <mikael@lilotux.net>
parents:
1602
diff
changeset
|
32 #include "xmpp_s10n.h" |
1600 | 33 #include "caps.h" |
1598 | 34 #include "events.h" |
35 #include "histolog.h" | |
36 #include "hooks.h" | |
37 #include "otr.h" | |
81 | 38 #include "roster.h" |
29 | 39 #include "screen.h" |
1598 | 40 #include "settings.h" |
29 | 41 #include "utils.h" |
42 | |
1001
dff25377c11f
Auto-reconnect after a network/server failure
Mikael Berthe <mikael@lilotux.net>
parents:
999
diff
changeset
|
43 #define RECONNECTION_TIMEOUT 60L |
dff25377c11f
Auto-reconnect after a network/server failure
Mikael Berthe <mikael@lilotux.net>
parents:
999
diff
changeset
|
44 |
1598 | 45 LmConnection* lconnection; |
46 static guint AutoConnection; | |
47 | |
48 inline void update_last_use(void); | |
49 inline gboolean xmpp_reconnect(); | |
50 | |
1604
351427ef0b4b
Remove #include's of C files
Mikael Berthe <mikael@lilotux.net>
parents:
1602
diff
changeset
|
51 enum imstatus mystatus = offline; |
1598 | 52 static enum imstatus mywantedstatus = available; |
1604
351427ef0b4b
Remove #include's of C files
Mikael Berthe <mikael@lilotux.net>
parents:
1602
diff
changeset
|
53 gchar *mystatusmsg; |
29 | 54 |
353
3fe43f6daa5a
Make imstatus2char a null-terminated string
Mikael Berthe <mikael@lilotux.net>
parents:
325
diff
changeset
|
55 char imstatus2char[imstatus_size+1] = { |
1311
0dda8238af21
Implement "/roster display"
Mikael Berthe <mikael@lilotux.net>
parents:
1310
diff
changeset
|
56 '_', 'o', 'f', 'd', 'n', 'a', 'i', '\0' |
46 | 57 }; |
58 | |
1604
351427ef0b4b
Remove #include's of C files
Mikael Berthe <mikael@lilotux.net>
parents:
1602
diff
changeset
|
59 char *imstatus_showmap[] = { |
1378 | 60 "", |
61 "", | |
62 "chat", | |
63 "dnd", | |
64 "xa", | |
65 "away", | |
66 "" | |
67 }; | |
68 | |
1604
351427ef0b4b
Remove #include's of C files
Mikael Berthe <mikael@lilotux.net>
parents:
1602
diff
changeset
|
69 LmMessageNode *bookmarks = NULL; |
351427ef0b4b
Remove #include's of C files
Mikael Berthe <mikael@lilotux.net>
parents:
1602
diff
changeset
|
70 LmMessageNode *rosternotes = NULL; |
29 | 71 |
1598 | 72 static struct IqHandlers |
116 | 73 { |
1598 | 74 const gchar *xmlns; |
75 LmHandleMessageFunction handler; | |
76 } iq_handlers[] = { | |
77 {NS_PING, &handle_iq_ping}, | |
78 {NS_VERSION, &handle_iq_version}, | |
79 {NS_TIME, &handle_iq_time}, | |
80 {NS_ROSTER, &handle_iq_roster}, | |
81 {NS_XMPP_TIME, &handle_iq_time202}, | |
82 {NS_LAST, &handle_iq_last}, | |
83 {NS_DISCO_INFO, &handle_iq_disco_info}, | |
84 {NS_DISCO_ITEMS,&handle_iq_disco_items}, | |
85 {NS_COMMANDS, &handle_iq_commands}, | |
86 {NULL, NULL} | |
87 }; | |
519
5c338d31de56
Show current global status message in "/status"
Mikael Berthe <mikael@lilotux.net>
parents:
513
diff
changeset
|
88 |
1558
3df441efb7c2
Fix gcc warnings related to inline/static uses
Mikael Berthe <mikael@lilotux.net>
parents:
1546
diff
changeset
|
89 void update_last_use(void) |
1254
401639413340
More jabber:iq:last support... (misc)
Mikael Berthe <mikael@lilotux.net>
parents:
1244
diff
changeset
|
90 { |
401639413340
More jabber:iq:last support... (misc)
Mikael Berthe <mikael@lilotux.net>
parents:
1244
diff
changeset
|
91 iqlast = time(NULL); |
401639413340
More jabber:iq:last support... (misc)
Mikael Berthe <mikael@lilotux.net>
parents:
1244
diff
changeset
|
92 } |
401639413340
More jabber:iq:last support... (misc)
Mikael Berthe <mikael@lilotux.net>
parents:
1244
diff
changeset
|
93 |
1598 | 94 // Note: the caller should check the jid is correct |
95 void xmpp_addbuddy(const char *bjid, const char *name, const char *group) | |
1215
80c095886fb5
Entity Capabilities support (XEP-0115)
Mikael Berthe <mikael@lilotux.net>
parents:
1213
diff
changeset
|
96 { |
1598 | 97 LmMessageNode *query, *y; |
98 LmMessage *iq; | |
99 char *cleanjid; | |
1255
ceada40bbe20
Update Entity Capabilities (add iq:last)
Mikael Berthe <mikael@lilotux.net>
parents:
1254
diff
changeset
|
100 |
1598 | 101 if (!lm_connection_is_authenticated(lconnection)) return; |
102 | |
103 cleanjid = jidtodisp(bjid); // Stripping resource, just in case... | |
104 | |
105 // We don't check if the jabber user already exists in the roster, | |
106 // because it allows to re-ask for notification. | |
1215
80c095886fb5
Entity Capabilities support (XEP-0115)
Mikael Berthe <mikael@lilotux.net>
parents:
1213
diff
changeset
|
107 |
1598 | 108 iq = lm_message_new_with_sub_type(NULL, LM_MESSAGE_TYPE_IQ, |
109 LM_MESSAGE_SUB_TYPE_SET); | |
110 query = lm_message_node_add_child(iq->node, "query", NULL); | |
111 lm_message_node_set_attribute(query, "xmlns", NS_ROSTER); | |
112 y = lm_message_node_add_child(query, "item", NULL); | |
113 lm_message_node_set_attribute(y, "jid", cleanjid); | |
114 | |
115 if (name) | |
116 lm_message_node_set_attribute(y, "name", name); | |
1215
80c095886fb5
Entity Capabilities support (XEP-0115)
Mikael Berthe <mikael@lilotux.net>
parents:
1213
diff
changeset
|
117 |
1598 | 118 if (group) |
119 lm_message_node_add_child(y, "group", group); | |
120 | |
121 lm_connection_send(lconnection, iq, NULL); | |
122 lm_message_unref(iq); | |
532
2ac8d8e49e81
Send status changes to chatrooms
Mikael Berthe <mikael@lilotux.net>
parents:
531
diff
changeset
|
123 |
1598 | 124 xmpp_send_s10n(cleanjid, LM_MESSAGE_SUB_TYPE_SUBSCRIBE); |
532
2ac8d8e49e81
Send status changes to chatrooms
Mikael Berthe <mikael@lilotux.net>
parents:
531
diff
changeset
|
125 |
1598 | 126 roster_add_user(cleanjid, name, group, ROSTER_TYPE_USER, sub_pending, -1); |
127 g_free(cleanjid); | |
128 buddylist_build(); | |
532
2ac8d8e49e81
Send status changes to chatrooms
Mikael Berthe <mikael@lilotux.net>
parents:
531
diff
changeset
|
129 |
1598 | 130 update_roster = TRUE; |
532
2ac8d8e49e81
Send status changes to chatrooms
Mikael Berthe <mikael@lilotux.net>
parents:
531
diff
changeset
|
131 } |
2ac8d8e49e81
Send status changes to chatrooms
Mikael Berthe <mikael@lilotux.net>
parents:
531
diff
changeset
|
132 |
1598 | 133 void xmpp_updatebuddy(const char *bjid, const char *name, const char *group) |
29 | 134 { |
1598 | 135 LmMessage *iq; |
136 LmMessageNode *x; | |
137 char *cleanjid; | |
29 | 138 |
1598 | 139 if (!lm_connection_is_authenticated(lconnection)) return; |
444 | 140 |
1598 | 141 // XXX We should check name's and group's correctness |
142 | |
143 cleanjid = jidtodisp(bjid); // Stripping resource, just in case... | |
29 | 144 |
1598 | 145 iq = lm_message_new_with_sub_type(NULL, LM_MESSAGE_TYPE_IQ, |
146 LM_MESSAGE_SUB_TYPE_SET); | |
147 x = lm_message_node_add_child(iq->node, "query", NULL); | |
148 lm_message_node_set_attribute(x, "xmlns", NS_ROSTER); | |
149 x = lm_message_node_add_child(x, "item", NULL); | |
150 lm_message_node_set_attributes(x, | |
151 "jid", cleanjid, | |
152 "name", name, | |
153 NULL); | |
29 | 154 |
1598 | 155 if (group) |
156 lm_message_node_add_child(x, "group", group); | |
1419
fb438482b28e
New option to customize the away/notavail priority (Michael Gehring)
Mikael Berthe <mikael@lilotux.net>
parents:
1415
diff
changeset
|
157 |
1598 | 158 lm_connection_send(lconnection, iq, NULL); |
159 lm_message_unref(iq); | |
160 g_free(cleanjid); | |
534 | 161 } |
162 | |
1598 | 163 void xmpp_delbuddy(const char *bjid) |
534 | 164 { |
1598 | 165 LmMessageNode *y, *z; |
166 LmMessage *iq; | |
167 char *cleanjid; | |
168 | |
169 if (!lm_connection_is_authenticated(lconnection)) return; | |
170 | |
171 cleanjid = jidtodisp(bjid); // Stripping resource, just in case... | |
534 | 172 |
1598 | 173 // If the current buddy is an agent, unsubscribe from it |
174 if (roster_gettype(cleanjid) == ROSTER_TYPE_AGENT) { | |
175 scr_LogPrint(LPRINT_LOGNORM, "Unregistering from the %s agent", cleanjid); | |
29 | 176 |
1598 | 177 iq = lm_message_new_with_sub_type(cleanjid, LM_MESSAGE_TYPE_IQ, |
178 LM_MESSAGE_SUB_TYPE_SET); | |
179 y = lm_message_node_add_child(iq->node, "query", NULL); | |
180 lm_message_node_set_attribute(y, "xmlns", NS_REGISTER); | |
181 lm_message_node_add_child(y, "remove", NULL); | |
182 lm_connection_send(lconnection, iq, NULL); | |
183 lm_message_unref(iq); | |
1014
99c5278bf6b8
Keep the status and status messages when we're disconnected
Mikael Berthe <mikael@lilotux.net>
parents:
1013
diff
changeset
|
184 } |
29 | 185 |
1598 | 186 // Cancel the subscriptions |
187 xmpp_send_s10n(cleanjid, LM_MESSAGE_SUB_TYPE_UNSUBSCRIBED); //cancel "from" | |
188 xmpp_send_s10n(cleanjid, LM_MESSAGE_SUB_TYPE_UNSUBSCRIBE); //cancel "to" | |
189 | |
190 // Ask for removal from roster | |
191 iq = lm_message_new_with_sub_type(NULL, LM_MESSAGE_TYPE_IQ, | |
192 LM_MESSAGE_SUB_TYPE_SET); | |
444 | 193 |
1598 | 194 y = lm_message_node_add_child(iq->node, "query", NULL); |
195 lm_message_node_set_attribute(y, "xmlns", NS_ROSTER); | |
196 z = lm_message_node_add_child(y, "item", NULL); | |
197 lm_message_node_set_attributes(z, | |
198 "jid", cleanjid, | |
199 "subscription", "remove", | |
200 NULL); | |
201 lm_connection_send(lconnection, iq, NULL); | |
202 lm_message_unref(iq); | |
203 | |
204 roster_del_user(cleanjid); | |
205 g_free(cleanjid); | |
206 buddylist_build(); | |
207 | |
208 update_roster = TRUE; | |
209 } | |
1365 | 210 |
1598 | 211 void xmpp_request(const char *fjid, enum iqreq_type reqtype) |
212 { | |
213 GSList *resources, *p_res; | |
214 GSList *roster_elt; | |
215 const char *strreqtype, *xmlns; | |
1365 | 216 |
1598 | 217 if (reqtype == iqreq_version) { |
218 xmlns = NS_VERSION; | |
219 strreqtype = "version"; | |
220 } else if (reqtype == iqreq_time) { | |
221 xmlns = NS_TIME; | |
222 strreqtype = "time"; | |
223 } else if (reqtype == iqreq_last) { | |
224 xmlns = NS_LAST; | |
225 strreqtype = "last"; | |
226 } else if (reqtype == iqreq_vcard) { | |
227 xmlns = NS_VCARD; | |
228 strreqtype = "vCard"; | |
229 // Special case | |
230 } else | |
231 return; | |
1365 | 232 |
1598 | 233 if (strchr(fjid, JID_RESOURCE_SEPARATOR)) { |
234 // This is a full JID | |
235 xmpp_iq_request(fjid, xmlns); | |
236 scr_LogPrint(LPRINT_NORMAL, "Sent %s request to <%s>", strreqtype, fjid); | |
237 return; | |
521 | 238 } |
713 | 239 |
1598 | 240 // The resource has not been specified |
241 roster_elt = roster_find(fjid, jidsearch, ROSTER_TYPE_USER|ROSTER_TYPE_ROOM); | |
242 if (!roster_elt) { | |
243 scr_LogPrint(LPRINT_NORMAL, "No known resource for <%s>...", fjid); | |
244 xmpp_iq_request(fjid, xmlns); // Let's send a request anyway... | |
245 scr_LogPrint(LPRINT_NORMAL, "Sent %s request to <%s>", strreqtype, fjid); | |
246 return; | |
247 } | |
1254
401639413340
More jabber:iq:last support... (misc)
Mikael Berthe <mikael@lilotux.net>
parents:
1244
diff
changeset
|
248 |
1598 | 249 // Send a request to each resource |
250 resources = buddy_getresources(roster_elt->data); | |
251 if (!resources) { | |
252 scr_LogPrint(LPRINT_NORMAL, "No known resource for <%s>...", fjid); | |
253 xmpp_iq_request(fjid, xmlns); // Let's send a request anyway... | |
254 scr_LogPrint(LPRINT_NORMAL, "Sent %s request to <%s>", strreqtype, fjid); | |
255 } | |
256 for (p_res = resources ; p_res ; p_res = g_slist_next(p_res)) { | |
257 gchar *fulljid; | |
258 fulljid = g_strdup_printf("%s/%s", fjid, (char*)p_res->data); | |
259 xmpp_iq_request(fulljid, xmlns); | |
260 scr_LogPrint(LPRINT_NORMAL, "Sent %s request to <%s>", strreqtype, fulljid); | |
261 g_free(fulljid); | |
262 g_free(p_res->data); | |
263 } | |
264 g_slist_free(resources); | |
1014
99c5278bf6b8
Keep the status and status messages when we're disconnected
Mikael Berthe <mikael@lilotux.net>
parents:
1013
diff
changeset
|
265 } |
99c5278bf6b8
Keep the status and status messages when we're disconnected
Mikael Berthe <mikael@lilotux.net>
parents:
1013
diff
changeset
|
266 |
1602 | 267 static LmHandlerResult cb_xep184(LmMessageHandler *h, LmConnection *c, |
268 LmMessage *m, gpointer user_data) | |
269 { | |
270 char *from = jidtodisp(lm_message_get_from(m)); | |
271 scr_RemoveReceiptFlag(from, h); | |
272 g_free(from); | |
273 return LM_HANDLER_RESULT_REMOVE_MESSAGE; | |
274 } | |
275 | |
1598 | 276 // xmpp_send_msg(jid, text, type, subject, |
277 // otrinject, *encrypted, type_overwrite) | |
1197 | 278 // When encrypted is not NULL, the function set *encrypted to 1 if the |
279 // message has been PGP-encrypted. If encryption enforcement is set and | |
280 // encryption fails, *encrypted is set to -1. | |
1598 | 281 void xmpp_send_msg(const char *fjid, const char *text, int type, |
282 const char *subject, gboolean otrinject, gint *encrypted, | |
1602 | 283 LmMessageSubType type_overwrite, gpointer *xep184) |
35 | 284 { |
1598 | 285 LmMessage *x; |
286 LmMessageSubType subtype; | |
1304 | 287 #ifdef HAVE_LIBOTR |
1299
3b338a5c01fc
OTR support
Frank Zschockelt <mcabber_otr[at]freakysoft.de>
parents:
1290
diff
changeset
|
288 int otr_msg = 0; |
1304 | 289 #endif |
1044
52cfe9bf9840
Encryption support for outgoing messages
Mikael Berthe <mikael@lilotux.net>
parents:
1043
diff
changeset
|
290 #if defined HAVE_GPGME || defined JEP0022 || defined JEP0085 |
52cfe9bf9840
Encryption support for outgoing messages
Mikael Berthe <mikael@lilotux.net>
parents:
1043
diff
changeset
|
291 char *rname, *barejid; |
52cfe9bf9840
Encryption support for outgoing messages
Mikael Berthe <mikael@lilotux.net>
parents:
1043
diff
changeset
|
292 GSList *sl_buddy; |
52cfe9bf9840
Encryption support for outgoing messages
Mikael Berthe <mikael@lilotux.net>
parents:
1043
diff
changeset
|
293 #endif |
987
f47e312560af
Improve JEP22 + JEP85 support
Mikael Berthe <mikael@lilotux.net>
parents:
986
diff
changeset
|
294 #if defined JEP0022 || defined JEP0085 |
1598 | 295 LmMessageNode *event; |
997 | 296 guint use_jep85 = 0; |
987
f47e312560af
Improve JEP22 + JEP85 support
Mikael Berthe <mikael@lilotux.net>
parents:
986
diff
changeset
|
297 struct jep0085 *jep85 = NULL; |
f47e312560af
Improve JEP22 + JEP85 support
Mikael Berthe <mikael@lilotux.net>
parents:
986
diff
changeset
|
298 #endif |
1044
52cfe9bf9840
Encryption support for outgoing messages
Mikael Berthe <mikael@lilotux.net>
parents:
1043
diff
changeset
|
299 gchar *enc = NULL; |
447
03bb57383cea
Initial Multi-User Chat support
Mikael Berthe <mikael@lilotux.net>
parents:
444
diff
changeset
|
300 |
1055
6eb1efea75d0
PGP: Visual encryption flag
Mikael Berthe <mikael@lilotux.net>
parents:
1053
diff
changeset
|
301 if (encrypted) |
1197 | 302 *encrypted = 0; |
1055
6eb1efea75d0
PGP: Visual encryption flag
Mikael Berthe <mikael@lilotux.net>
parents:
1053
diff
changeset
|
303 |
1598 | 304 if (!lm_connection_is_authenticated(lconnection)) |
1435
9bf7f3ddff10
Do not send a groupchat-style message when changing a MUC room topic
Mikael Berthe <mikael@lilotux.net>
parents:
1426
diff
changeset
|
305 return; |
9bf7f3ddff10
Do not send a groupchat-style message when changing a MUC room topic
Mikael Berthe <mikael@lilotux.net>
parents:
1426
diff
changeset
|
306 |
9bf7f3ddff10
Do not send a groupchat-style message when changing a MUC room topic
Mikael Berthe <mikael@lilotux.net>
parents:
1426
diff
changeset
|
307 if (!text && type == ROSTER_TYPE_USER) |
9bf7f3ddff10
Do not send a groupchat-style message when changing a MUC room topic
Mikael Berthe <mikael@lilotux.net>
parents:
1426
diff
changeset
|
308 return; |
472
75442262c082
Disable some commands when not connected
Mikael Berthe <mikael@lilotux.net>
parents:
470
diff
changeset
|
309 |
1598 | 310 if (type_overwrite != LM_MESSAGE_SUB_TYPE_NOT_SET) |
311 subtype = type_overwrite; | |
1305
9bc68473f8a3
-n and -f flags to message-sending commands
Michal 'vorner' Vaner <vorner@ucw.cz>
parents:
1304
diff
changeset
|
312 else { |
9bc68473f8a3
-n and -f flags to message-sending commands
Michal 'vorner' Vaner <vorner@ucw.cz>
parents:
1304
diff
changeset
|
313 if (type == ROSTER_TYPE_ROOM) |
1598 | 314 subtype = LM_MESSAGE_SUB_TYPE_GROUPCHAT; |
1305
9bc68473f8a3
-n and -f flags to message-sending commands
Michal 'vorner' Vaner <vorner@ucw.cz>
parents:
1304
diff
changeset
|
315 else |
1598 | 316 subtype = LM_MESSAGE_SUB_TYPE_CHAT; |
1305
9bc68473f8a3
-n and -f flags to message-sending commands
Michal 'vorner' Vaner <vorner@ucw.cz>
parents:
1304
diff
changeset
|
317 } |
447
03bb57383cea
Initial Multi-User Chat support
Mikael Berthe <mikael@lilotux.net>
parents:
444
diff
changeset
|
318 |
1598 | 319 #if defined HAVE_GPGME || defined HAVE_LIBOTR || \ |
320 defined JEP0022 || defined JEP0085 | |
1058 | 321 rname = strchr(fjid, JID_RESOURCE_SEPARATOR); |
322 barejid = jidtodisp(fjid); | |
987
f47e312560af
Improve JEP22 + JEP85 support
Mikael Berthe <mikael@lilotux.net>
parents:
986
diff
changeset
|
323 sl_buddy = roster_find(barejid, jidsearch, ROSTER_TYPE_USER); |
f47e312560af
Improve JEP22 + JEP85 support
Mikael Berthe <mikael@lilotux.net>
parents:
986
diff
changeset
|
324 |
f47e312560af
Improve JEP22 + JEP85 support
Mikael Berthe <mikael@lilotux.net>
parents:
986
diff
changeset
|
325 // If we can get a resource name, we use it. Else we use NULL, |
f47e312560af
Improve JEP22 + JEP85 support
Mikael Berthe <mikael@lilotux.net>
parents:
986
diff
changeset
|
326 // which hopefully will give us the most likely resource. |
f47e312560af
Improve JEP22 + JEP85 support
Mikael Berthe <mikael@lilotux.net>
parents:
986
diff
changeset
|
327 if (rname) |
f47e312560af
Improve JEP22 + JEP85 support
Mikael Berthe <mikael@lilotux.net>
parents:
986
diff
changeset
|
328 rname++; |
1044
52cfe9bf9840
Encryption support for outgoing messages
Mikael Berthe <mikael@lilotux.net>
parents:
1043
diff
changeset
|
329 |
1299
3b338a5c01fc
OTR support
Frank Zschockelt <mcabber_otr[at]freakysoft.de>
parents:
1290
diff
changeset
|
330 #ifdef HAVE_LIBOTR |
1598 | 331 if (otr_enabled() && !otrinject) { |
332 if (type == ROSTER_TYPE_USER) { | |
1347
07816313073b
Add an option 'otr' to enable OTR support in the configuration file
Mikael Berthe <mikael@lilotux.net>
parents:
1344
diff
changeset
|
333 otr_msg = otr_send((char **)&text, barejid); |
07816313073b
Add an option 'otr' to enable OTR support in the configuration file
Mikael Berthe <mikael@lilotux.net>
parents:
1344
diff
changeset
|
334 if (!text) { |
07816313073b
Add an option 'otr' to enable OTR support in the configuration file
Mikael Berthe <mikael@lilotux.net>
parents:
1344
diff
changeset
|
335 g_free(barejid); |
07816313073b
Add an option 'otr' to enable OTR support in the configuration file
Mikael Berthe <mikael@lilotux.net>
parents:
1344
diff
changeset
|
336 if (encrypted) |
07816313073b
Add an option 'otr' to enable OTR support in the configuration file
Mikael Berthe <mikael@lilotux.net>
parents:
1344
diff
changeset
|
337 *encrypted = -1; |
07816313073b
Add an option 'otr' to enable OTR support in the configuration file
Mikael Berthe <mikael@lilotux.net>
parents:
1344
diff
changeset
|
338 return; |
07816313073b
Add an option 'otr' to enable OTR support in the configuration file
Mikael Berthe <mikael@lilotux.net>
parents:
1344
diff
changeset
|
339 } |
1299
3b338a5c01fc
OTR support
Frank Zschockelt <mcabber_otr[at]freakysoft.de>
parents:
1290
diff
changeset
|
340 } |
1484
7b36b91a4388
New UI message flag (O) when OTR is used
Mikael Berthe <mikael@lilotux.net>
parents:
1476
diff
changeset
|
341 if (otr_msg && encrypted) |
7b36b91a4388
New UI message flag (O) when OTR is used
Mikael Berthe <mikael@lilotux.net>
parents:
1476
diff
changeset
|
342 *encrypted = ENCRYPTED_OTR; |
1299
3b338a5c01fc
OTR support
Frank Zschockelt <mcabber_otr[at]freakysoft.de>
parents:
1290
diff
changeset
|
343 } |
3b338a5c01fc
OTR support
Frank Zschockelt <mcabber_otr[at]freakysoft.de>
parents:
1290
diff
changeset
|
344 #endif |
3b338a5c01fc
OTR support
Frank Zschockelt <mcabber_otr[at]freakysoft.de>
parents:
1290
diff
changeset
|
345 |
1044
52cfe9bf9840
Encryption support for outgoing messages
Mikael Berthe <mikael@lilotux.net>
parents:
1043
diff
changeset
|
346 #ifdef HAVE_GPGME |
52cfe9bf9840
Encryption support for outgoing messages
Mikael Berthe <mikael@lilotux.net>
parents:
1043
diff
changeset
|
347 if (type == ROSTER_TYPE_USER && sl_buddy && gpg_enabled()) { |
1197 | 348 if (!settings_pgp_getdisabled(barejid)) { // not disabled for this contact? |
349 guint force; | |
1065
230dca34dbea
Extand pgp_data structure
Mikael Berthe <mikael@lilotux.net>
parents:
1058
diff
changeset
|
350 struct pgp_data *res_pgpdata; |
1197 | 351 force = settings_pgp_getforce(barejid); |
1065
230dca34dbea
Extand pgp_data structure
Mikael Berthe <mikael@lilotux.net>
parents:
1058
diff
changeset
|
352 res_pgpdata = buddy_resource_pgp(sl_buddy->data, rname); |
1197 | 353 if (force || (res_pgpdata && res_pgpdata->sign_keyid)) { |
354 /* Remote client has PGP support (we have a signature) | |
355 * OR encryption is enforced (force = TRUE). | |
1067
a5dc85fdebde
Add key comparison for signatures & use user-provided PGP keys for encryption
Mikael Berthe <mikael@lilotux.net>
parents:
1065
diff
changeset
|
356 * If the contact has a specific KeyId, we'll use it; |
a5dc85fdebde
Add key comparison for signatures & use user-provided PGP keys for encryption
Mikael Berthe <mikael@lilotux.net>
parents:
1065
diff
changeset
|
357 * if not, we'll use the key used for the signature. |
a5dc85fdebde
Add key comparison for signatures & use user-provided PGP keys for encryption
Mikael Berthe <mikael@lilotux.net>
parents:
1065
diff
changeset
|
358 * Both keys should match, in theory (cf. XEP-0027). */ |
a5dc85fdebde
Add key comparison for signatures & use user-provided PGP keys for encryption
Mikael Berthe <mikael@lilotux.net>
parents:
1065
diff
changeset
|
359 const char *key; |
a5dc85fdebde
Add key comparison for signatures & use user-provided PGP keys for encryption
Mikael Berthe <mikael@lilotux.net>
parents:
1065
diff
changeset
|
360 key = settings_pgp_getkeyid(barejid); |
1197 | 361 if (!key && res_pgpdata) |
1067
a5dc85fdebde
Add key comparison for signatures & use user-provided PGP keys for encryption
Mikael Berthe <mikael@lilotux.net>
parents:
1065
diff
changeset
|
362 key = res_pgpdata->sign_keyid; |
1197 | 363 if (key) |
364 enc = gpg_encrypt(text, key); | |
365 if (!enc && force) { | |
366 if (encrypted) | |
367 *encrypted = -1; | |
368 g_free(barejid); | |
369 return; | |
370 } | |
1067
a5dc85fdebde
Add key comparison for signatures & use user-provided PGP keys for encryption
Mikael Berthe <mikael@lilotux.net>
parents:
1065
diff
changeset
|
371 } |
1065
230dca34dbea
Extand pgp_data structure
Mikael Berthe <mikael@lilotux.net>
parents:
1058
diff
changeset
|
372 } |
1044
52cfe9bf9840
Encryption support for outgoing messages
Mikael Berthe <mikael@lilotux.net>
parents:
1043
diff
changeset
|
373 } |
1067
a5dc85fdebde
Add key comparison for signatures & use user-provided PGP keys for encryption
Mikael Berthe <mikael@lilotux.net>
parents:
1065
diff
changeset
|
374 #endif // HAVE_GPGME |
a5dc85fdebde
Add key comparison for signatures & use user-provided PGP keys for encryption
Mikael Berthe <mikael@lilotux.net>
parents:
1065
diff
changeset
|
375 |
1065
230dca34dbea
Extand pgp_data structure
Mikael Berthe <mikael@lilotux.net>
parents:
1058
diff
changeset
|
376 g_free(barejid); |
1067
a5dc85fdebde
Add key comparison for signatures & use user-provided PGP keys for encryption
Mikael Berthe <mikael@lilotux.net>
parents:
1065
diff
changeset
|
377 #endif // HAVE_GPGME || defined JEP0022 || defined JEP0085 |
1044
52cfe9bf9840
Encryption support for outgoing messages
Mikael Berthe <mikael@lilotux.net>
parents:
1043
diff
changeset
|
378 |
1598 | 379 x = lm_message_new_with_sub_type(fjid, LM_MESSAGE_TYPE_MESSAGE, subtype); |
380 lm_message_node_add_child(x->node, "body", | |
381 enc ? "This message is PGP-encrypted." : text); | |
382 | |
383 if (subject) | |
384 lm_message_node_add_child(x->node, "subject", subject); | |
385 | |
1044
52cfe9bf9840
Encryption support for outgoing messages
Mikael Berthe <mikael@lilotux.net>
parents:
1043
diff
changeset
|
386 if (enc) { |
1598 | 387 LmMessageNode *y; |
388 y = lm_message_node_add_child(x->node, "x", enc); | |
389 lm_message_node_set_attribute(y, "xmlns", NS_ENCRYPTED); | |
1055
6eb1efea75d0
PGP: Visual encryption flag
Mikael Berthe <mikael@lilotux.net>
parents:
1053
diff
changeset
|
390 if (encrypted) |
1484
7b36b91a4388
New UI message flag (O) when OTR is used
Mikael Berthe <mikael@lilotux.net>
parents:
1476
diff
changeset
|
391 *encrypted = ENCRYPTED_PGP; |
1044
52cfe9bf9840
Encryption support for outgoing messages
Mikael Berthe <mikael@lilotux.net>
parents:
1043
diff
changeset
|
392 g_free(enc); |
52cfe9bf9840
Encryption support for outgoing messages
Mikael Berthe <mikael@lilotux.net>
parents:
1043
diff
changeset
|
393 } |
52cfe9bf9840
Encryption support for outgoing messages
Mikael Berthe <mikael@lilotux.net>
parents:
1043
diff
changeset
|
394 |
1602 | 395 //XEP-0184: Message Receipts |
396 if (sl_buddy && rname && xep184 && | |
397 caps_has_feature(buddy_resource_getcaps(sl_buddy->data, rname), | |
398 NS_RECEIPTS)) { | |
399 lm_message_node_set_attribute | |
400 (lm_message_node_add_child(x->node, "request", NULL), | |
401 "xmlns", NS_RECEIPTS); | |
402 *xep184 = lm_message_handler_new(cb_xep184, NULL, NULL); | |
403 } | |
404 | |
1044
52cfe9bf9840
Encryption support for outgoing messages
Mikael Berthe <mikael@lilotux.net>
parents:
1043
diff
changeset
|
405 #if defined JEP0022 || defined JEP0085 |
52cfe9bf9840
Encryption support for outgoing messages
Mikael Berthe <mikael@lilotux.net>
parents:
1043
diff
changeset
|
406 // If typing notifications are disabled, we can skip all this stuff... |
52cfe9bf9840
Encryption support for outgoing messages
Mikael Berthe <mikael@lilotux.net>
parents:
1043
diff
changeset
|
407 if (chatstates_disabled || type == ROSTER_TYPE_ROOM) |
1598 | 408 goto xmpp_send_msg_no_chatstates; |
1044
52cfe9bf9840
Encryption support for outgoing messages
Mikael Berthe <mikael@lilotux.net>
parents:
1043
diff
changeset
|
409 |
987
f47e312560af
Improve JEP22 + JEP85 support
Mikael Berthe <mikael@lilotux.net>
parents:
986
diff
changeset
|
410 if (sl_buddy) |
f47e312560af
Improve JEP22 + JEP85 support
Mikael Berthe <mikael@lilotux.net>
parents:
986
diff
changeset
|
411 jep85 = buddy_resource_jep85(sl_buddy->data, rname); |
986
ed697234bd39
Chat states receival (Alexis Hildebrandt)
Mikael Berthe <mikael@lilotux.net>
parents:
977
diff
changeset
|
412 #endif |
ed697234bd39
Chat states receival (Alexis Hildebrandt)
Mikael Berthe <mikael@lilotux.net>
parents:
977
diff
changeset
|
413 |
987
f47e312560af
Improve JEP22 + JEP85 support
Mikael Berthe <mikael@lilotux.net>
parents:
986
diff
changeset
|
414 #ifdef JEP0085 |
f47e312560af
Improve JEP22 + JEP85 support
Mikael Berthe <mikael@lilotux.net>
parents:
986
diff
changeset
|
415 /* JEP-0085 5.1 |
f47e312560af
Improve JEP22 + JEP85 support
Mikael Berthe <mikael@lilotux.net>
parents:
986
diff
changeset
|
416 * "Until receiving a reply to the initial content message (or a standalone |
f47e312560af
Improve JEP22 + JEP85 support
Mikael Berthe <mikael@lilotux.net>
parents:
986
diff
changeset
|
417 * notification) from the Contact, the User MUST NOT send subsequent chat |
f47e312560af
Improve JEP22 + JEP85 support
Mikael Berthe <mikael@lilotux.net>
parents:
986
diff
changeset
|
418 * state notifications to the Contact." |
1378 | 419 * In our implementation support is initially "unknown", then it's "probed" |
987
f47e312560af
Improve JEP22 + JEP85 support
Mikael Berthe <mikael@lilotux.net>
parents:
986
diff
changeset
|
420 * and can become "ok". |
f47e312560af
Improve JEP22 + JEP85 support
Mikael Berthe <mikael@lilotux.net>
parents:
986
diff
changeset
|
421 */ |
f47e312560af
Improve JEP22 + JEP85 support
Mikael Berthe <mikael@lilotux.net>
parents:
986
diff
changeset
|
422 if (jep85 && (jep85->support == CHATSTATES_SUPPORT_OK || |
f47e312560af
Improve JEP22 + JEP85 support
Mikael Berthe <mikael@lilotux.net>
parents:
986
diff
changeset
|
423 jep85->support == CHATSTATES_SUPPORT_UNKNOWN)) { |
1598 | 424 event = lm_message_node_add_child(x->node, "active", NULL); |
425 lm_message_node_set_attribute(event, "xmlns", NS_CHATSTATES); | |
987
f47e312560af
Improve JEP22 + JEP85 support
Mikael Berthe <mikael@lilotux.net>
parents:
986
diff
changeset
|
426 if (jep85->support == CHATSTATES_SUPPORT_UNKNOWN) |
f47e312560af
Improve JEP22 + JEP85 support
Mikael Berthe <mikael@lilotux.net>
parents:
986
diff
changeset
|
427 jep85->support = CHATSTATES_SUPPORT_PROBED; |
f47e312560af
Improve JEP22 + JEP85 support
Mikael Berthe <mikael@lilotux.net>
parents:
986
diff
changeset
|
428 else |
997 | 429 use_jep85 = 1; |
990
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
430 jep85->last_state_sent = ROSTER_EVENT_ACTIVE; |
987
f47e312560af
Improve JEP22 + JEP85 support
Mikael Berthe <mikael@lilotux.net>
parents:
986
diff
changeset
|
431 } |
f47e312560af
Improve JEP22 + JEP85 support
Mikael Berthe <mikael@lilotux.net>
parents:
986
diff
changeset
|
432 #endif |
f47e312560af
Improve JEP22 + JEP85 support
Mikael Berthe <mikael@lilotux.net>
parents:
986
diff
changeset
|
433 #ifdef JEP0022 |
f47e312560af
Improve JEP22 + JEP85 support
Mikael Berthe <mikael@lilotux.net>
parents:
986
diff
changeset
|
434 /* JEP-22 |
f47e312560af
Improve JEP22 + JEP85 support
Mikael Berthe <mikael@lilotux.net>
parents:
986
diff
changeset
|
435 * If the Contact supports JEP-0085, we do not use JEP-0022. |
f47e312560af
Improve JEP22 + JEP85 support
Mikael Berthe <mikael@lilotux.net>
parents:
986
diff
changeset
|
436 * If not, we try to fall back to JEP-0022. |
f47e312560af
Improve JEP22 + JEP85 support
Mikael Berthe <mikael@lilotux.net>
parents:
986
diff
changeset
|
437 */ |
997 | 438 if (!use_jep85) { |
990
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
439 struct jep0022 *jep22 = NULL; |
1598 | 440 event = lm_message_node_add_child(x->node, "x", NULL); |
441 lm_message_node_set_attribute(event, "xmlns", NS_EVENT); | |
442 lm_message_node_add_child(event, "composing", NULL); | |
988
6e2bfd1ffded
Add ids to message stanzas if needed
Mikael Berthe <mikael@lilotux.net>
parents:
987
diff
changeset
|
443 |
990
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
444 if (sl_buddy) |
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
445 jep22 = buddy_resource_jep22(sl_buddy->data, rname); |
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
446 if (jep22) |
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
447 jep22->last_state_sent = ROSTER_EVENT_ACTIVE; |
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
448 |
988
6e2bfd1ffded
Add ids to message stanzas if needed
Mikael Berthe <mikael@lilotux.net>
parents:
987
diff
changeset
|
449 // An id is mandatory when using JEP-0022. |
1598 | 450 if (text || subject) { |
451 const gchar *msgid = lm_message_get_id(x); | |
989
859ab76e5093
Send JEP-22 delivered messages
Mikael Berthe <mikael@lilotux.net>
parents:
988
diff
changeset
|
452 // Let's update last_msgid_sent |
859ab76e5093
Send JEP-22 delivered messages
Mikael Berthe <mikael@lilotux.net>
parents:
988
diff
changeset
|
453 if (jep22) { |
859ab76e5093
Send JEP-22 delivered messages
Mikael Berthe <mikael@lilotux.net>
parents:
988
diff
changeset
|
454 g_free(jep22->last_msgid_sent); |
859ab76e5093
Send JEP-22 delivered messages
Mikael Berthe <mikael@lilotux.net>
parents:
988
diff
changeset
|
455 jep22->last_msgid_sent = g_strdup(msgid); |
859ab76e5093
Send JEP-22 delivered messages
Mikael Berthe <mikael@lilotux.net>
parents:
988
diff
changeset
|
456 } |
988
6e2bfd1ffded
Add ids to message stanzas if needed
Mikael Berthe <mikael@lilotux.net>
parents:
987
diff
changeset
|
457 } |
987
f47e312560af
Improve JEP22 + JEP85 support
Mikael Berthe <mikael@lilotux.net>
parents:
986
diff
changeset
|
458 } |
f47e312560af
Improve JEP22 + JEP85 support
Mikael Berthe <mikael@lilotux.net>
parents:
986
diff
changeset
|
459 #endif |
986
ed697234bd39
Chat states receival (Alexis Hildebrandt)
Mikael Berthe <mikael@lilotux.net>
parents:
977
diff
changeset
|
460 |
1598 | 461 xmpp_send_msg_no_chatstates: |
1254
401639413340
More jabber:iq:last support... (misc)
Mikael Berthe <mikael@lilotux.net>
parents:
1244
diff
changeset
|
462 if (mystatus != invisible) |
401639413340
More jabber:iq:last support... (misc)
Mikael Berthe <mikael@lilotux.net>
parents:
1244
diff
changeset
|
463 update_last_use(); |
1602 | 464 if (xep184 && *xep184) { |
465 lm_connection_send_with_reply(lconnection, x, *xep184, NULL); | |
466 lm_message_handler_unref(*xep184); | |
467 } else | |
468 lm_connection_send(lconnection, x, NULL); | |
1598 | 469 lm_message_unref(x); |
35 | 470 } |
471 | |
990
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
472 #ifdef JEP0085 |
1598 | 473 // xmpp_send_jep85_chatstate() |
990
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
474 // Send a JEP-85 chatstate. |
1598 | 475 static void xmpp_send_jep85_chatstate(const char *bjid, const char *resname, |
476 guint state) | |
990
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
477 { |
1598 | 478 LmMessage *m; |
479 LmMessageNode *event; | |
990
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
480 GSList *sl_buddy; |
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
481 const char *chattag; |
1091
10f9d6fcfeab
JEP85: Reset composing/paused state when a resource with higher prio comes up
Mikael Berthe <mikael@lilotux.net>
parents:
1072
diff
changeset
|
482 char *rjid, *fjid = NULL; |
990
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
483 struct jep0085 *jep85 = NULL; |
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
484 |
1598 | 485 if (!lm_connection_is_authenticated(lconnection)) return; |
990
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
486 |
1091
10f9d6fcfeab
JEP85: Reset composing/paused state when a resource with higher prio comes up
Mikael Berthe <mikael@lilotux.net>
parents:
1072
diff
changeset
|
487 sl_buddy = roster_find(bjid, jidsearch, ROSTER_TYPE_USER); |
990
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
488 |
1091
10f9d6fcfeab
JEP85: Reset composing/paused state when a resource with higher prio comes up
Mikael Berthe <mikael@lilotux.net>
parents:
1072
diff
changeset
|
489 // If we have a resource name, we use it. Else we use NULL, |
990
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
490 // which hopefully will give us the most likely resource. |
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
491 if (sl_buddy) |
1091
10f9d6fcfeab
JEP85: Reset composing/paused state when a resource with higher prio comes up
Mikael Berthe <mikael@lilotux.net>
parents:
1072
diff
changeset
|
492 jep85 = buddy_resource_jep85(sl_buddy->data, resname); |
990
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
493 |
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
494 if (!jep85 || (jep85->support != CHATSTATES_SUPPORT_OK)) |
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
495 return; |
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
496 |
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
497 if (state == jep85->last_state_sent) |
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
498 return; |
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
499 |
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
500 if (state == ROSTER_EVENT_ACTIVE) |
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
501 chattag = "active"; |
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
502 else if (state == ROSTER_EVENT_COMPOSING) |
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
503 chattag = "composing"; |
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
504 else if (state == ROSTER_EVENT_PAUSED) |
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
505 chattag = "paused"; |
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
506 else { |
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
507 scr_LogPrint(LPRINT_LOGNORM, "Error: unsupported JEP-85 state (%d)", state); |
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
508 return; |
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
509 } |
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
510 |
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
511 jep85->last_state_sent = state; |
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
512 |
1091
10f9d6fcfeab
JEP85: Reset composing/paused state when a resource with higher prio comes up
Mikael Berthe <mikael@lilotux.net>
parents:
1072
diff
changeset
|
513 if (resname) |
10f9d6fcfeab
JEP85: Reset composing/paused state when a resource with higher prio comes up
Mikael Berthe <mikael@lilotux.net>
parents:
1072
diff
changeset
|
514 fjid = g_strdup_printf("%s/%s", bjid, resname); |
10f9d6fcfeab
JEP85: Reset composing/paused state when a resource with higher prio comes up
Mikael Berthe <mikael@lilotux.net>
parents:
1072
diff
changeset
|
515 |
10f9d6fcfeab
JEP85: Reset composing/paused state when a resource with higher prio comes up
Mikael Berthe <mikael@lilotux.net>
parents:
1072
diff
changeset
|
516 rjid = resname ? fjid : (char*)bjid; |
1598 | 517 m = lm_message_new_with_sub_type(rjid, LM_MESSAGE_TYPE_MESSAGE, |
518 LM_MESSAGE_SUB_TYPE_CHAT); | |
990
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
519 |
1598 | 520 event = lm_message_node_add_child(m->node, chattag, NULL); |
521 lm_message_node_set_attribute(event, "xmlns", NS_CHATSTATES); | |
990
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
522 |
1598 | 523 lm_connection_send(lconnection, m, NULL); |
524 lm_message_unref(m); | |
990
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
525 |
1091
10f9d6fcfeab
JEP85: Reset composing/paused state when a resource with higher prio comes up
Mikael Berthe <mikael@lilotux.net>
parents:
1072
diff
changeset
|
526 g_free(fjid); |
990
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
527 } |
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
528 #endif |
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
529 |
989
859ab76e5093
Send JEP-22 delivered messages
Mikael Berthe <mikael@lilotux.net>
parents:
988
diff
changeset
|
530 #ifdef JEP0022 |
1598 | 531 // xmpp_send_jep22_event() |
989
859ab76e5093
Send JEP-22 delivered messages
Mikael Berthe <mikael@lilotux.net>
parents:
988
diff
changeset
|
532 // Send a JEP-22 message event (delivered, composing...). |
1598 | 533 static void xmpp_send_jep22_event(const char *fjid, guint type) |
989
859ab76e5093
Send JEP-22 delivered messages
Mikael Berthe <mikael@lilotux.net>
parents:
988
diff
changeset
|
534 { |
1598 | 535 LmMessage *x; |
536 LmMessageNode *event; | |
989
859ab76e5093
Send JEP-22 delivered messages
Mikael Berthe <mikael@lilotux.net>
parents:
988
diff
changeset
|
537 const char *msgid; |
859ab76e5093
Send JEP-22 delivered messages
Mikael Berthe <mikael@lilotux.net>
parents:
988
diff
changeset
|
538 char *rname, *barejid; |
859ab76e5093
Send JEP-22 delivered messages
Mikael Berthe <mikael@lilotux.net>
parents:
988
diff
changeset
|
539 GSList *sl_buddy; |
859ab76e5093
Send JEP-22 delivered messages
Mikael Berthe <mikael@lilotux.net>
parents:
988
diff
changeset
|
540 struct jep0022 *jep22 = NULL; |
990
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
541 guint jep22_state; |
989
859ab76e5093
Send JEP-22 delivered messages
Mikael Berthe <mikael@lilotux.net>
parents:
988
diff
changeset
|
542 |
1598 | 543 if (!lm_connection_is_authenticated(lconnection)) return; |
989
859ab76e5093
Send JEP-22 delivered messages
Mikael Berthe <mikael@lilotux.net>
parents:
988
diff
changeset
|
544 |
1058 | 545 rname = strchr(fjid, JID_RESOURCE_SEPARATOR); |
546 barejid = jidtodisp(fjid); | |
989
859ab76e5093
Send JEP-22 delivered messages
Mikael Berthe <mikael@lilotux.net>
parents:
988
diff
changeset
|
547 sl_buddy = roster_find(barejid, jidsearch, ROSTER_TYPE_USER); |
859ab76e5093
Send JEP-22 delivered messages
Mikael Berthe <mikael@lilotux.net>
parents:
988
diff
changeset
|
548 g_free(barejid); |
859ab76e5093
Send JEP-22 delivered messages
Mikael Berthe <mikael@lilotux.net>
parents:
988
diff
changeset
|
549 |
859ab76e5093
Send JEP-22 delivered messages
Mikael Berthe <mikael@lilotux.net>
parents:
988
diff
changeset
|
550 // If we can get a resource name, we use it. Else we use NULL, |
859ab76e5093
Send JEP-22 delivered messages
Mikael Berthe <mikael@lilotux.net>
parents:
988
diff
changeset
|
551 // which hopefully will give us the most likely resource. |
859ab76e5093
Send JEP-22 delivered messages
Mikael Berthe <mikael@lilotux.net>
parents:
988
diff
changeset
|
552 if (rname) |
859ab76e5093
Send JEP-22 delivered messages
Mikael Berthe <mikael@lilotux.net>
parents:
988
diff
changeset
|
553 rname++; |
859ab76e5093
Send JEP-22 delivered messages
Mikael Berthe <mikael@lilotux.net>
parents:
988
diff
changeset
|
554 if (sl_buddy) |
859ab76e5093
Send JEP-22 delivered messages
Mikael Berthe <mikael@lilotux.net>
parents:
988
diff
changeset
|
555 jep22 = buddy_resource_jep22(sl_buddy->data, rname); |
859ab76e5093
Send JEP-22 delivered messages
Mikael Berthe <mikael@lilotux.net>
parents:
988
diff
changeset
|
556 |
990
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
557 if (!jep22) |
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
558 return; // XXX Maybe we could try harder (other resources?) |
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
559 |
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
560 msgid = jep22->last_msgid_rcvd; |
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
561 |
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
562 // For composing events (composing, active, inactive, paused...), |
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
563 // JEP22 only has 2 states; we'll use composing and active. |
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
564 if (type == ROSTER_EVENT_COMPOSING) |
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
565 jep22_state = ROSTER_EVENT_COMPOSING; |
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
566 else if (type == ROSTER_EVENT_ACTIVE || |
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
567 type == ROSTER_EVENT_PAUSED) |
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
568 jep22_state = ROSTER_EVENT_ACTIVE; |
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
569 else |
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
570 jep22_state = 0; // ROSTER_EVENT_NONE |
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
571 |
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
572 if (jep22_state) { |
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
573 // Do not re-send a same event |
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
574 if (jep22_state == jep22->last_state_sent) |
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
575 return; |
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
576 jep22->last_state_sent = jep22_state; |
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
577 } |
989
859ab76e5093
Send JEP-22 delivered messages
Mikael Berthe <mikael@lilotux.net>
parents:
988
diff
changeset
|
578 |
1598 | 579 x = lm_message_new_with_sub_type(fjid, LM_MESSAGE_TYPE_MESSAGE, |
580 LM_MESSAGE_SUB_TYPE_CHAT); | |
989
859ab76e5093
Send JEP-22 delivered messages
Mikael Berthe <mikael@lilotux.net>
parents:
988
diff
changeset
|
581 |
1598 | 582 event = lm_message_node_add_child(x->node, "x", NULL); |
583 lm_message_node_set_attribute(event, "xmlns", NS_EVENT); | |
989
859ab76e5093
Send JEP-22 delivered messages
Mikael Berthe <mikael@lilotux.net>
parents:
988
diff
changeset
|
584 if (type == ROSTER_EVENT_DELIVERED) |
1598 | 585 lm_message_node_add_child(event, "delivered", NULL); |
989
859ab76e5093
Send JEP-22 delivered messages
Mikael Berthe <mikael@lilotux.net>
parents:
988
diff
changeset
|
586 else if (type == ROSTER_EVENT_COMPOSING) |
1598 | 587 lm_message_node_add_child(event, "composing", NULL); |
588 lm_message_node_add_child(event, "id", msgid); | |
989
859ab76e5093
Send JEP-22 delivered messages
Mikael Berthe <mikael@lilotux.net>
parents:
988
diff
changeset
|
589 |
1598 | 590 lm_connection_send(lconnection, x, NULL); |
591 lm_message_unref(x); | |
989
859ab76e5093
Send JEP-22 delivered messages
Mikael Berthe <mikael@lilotux.net>
parents:
988
diff
changeset
|
592 } |
859ab76e5093
Send JEP-22 delivered messages
Mikael Berthe <mikael@lilotux.net>
parents:
988
diff
changeset
|
593 #endif |
859ab76e5093
Send JEP-22 delivered messages
Mikael Berthe <mikael@lilotux.net>
parents:
988
diff
changeset
|
594 |
1598 | 595 // xmpp_send_chatstate(buddy, state) |
997 | 596 // Send a chatstate or event (JEP-22/85) according to the buddy's capabilities. |
597 // The message is sent to one of the resources with the highest priority. | |
990
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
598 #if defined JEP0022 || defined JEP0085 |
1598 | 599 void xmpp_send_chatstate(gpointer buddy, guint chatstate) |
990
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
600 { |
1058 | 601 const char *bjid; |
1091
10f9d6fcfeab
JEP85: Reset composing/paused state when a resource with higher prio comes up
Mikael Berthe <mikael@lilotux.net>
parents:
1072
diff
changeset
|
602 #ifdef JEP0085 |
10f9d6fcfeab
JEP85: Reset composing/paused state when a resource with higher prio comes up
Mikael Berthe <mikael@lilotux.net>
parents:
1072
diff
changeset
|
603 GSList *resources, *p_res, *p_next; |
1476
77afd831f8f7
Avoid mixed declarations and code
Mikael Berthe <mikael@lilotux.net>
parents:
1448
diff
changeset
|
604 struct jep0085 *jep85 = NULL; |
1091
10f9d6fcfeab
JEP85: Reset composing/paused state when a resource with higher prio comes up
Mikael Berthe <mikael@lilotux.net>
parents:
1072
diff
changeset
|
605 #endif |
10f9d6fcfeab
JEP85: Reset composing/paused state when a resource with higher prio comes up
Mikael Berthe <mikael@lilotux.net>
parents:
1072
diff
changeset
|
606 #ifdef JEP0022 |
10f9d6fcfeab
JEP85: Reset composing/paused state when a resource with higher prio comes up
Mikael Berthe <mikael@lilotux.net>
parents:
1072
diff
changeset
|
607 struct jep0022 *jep22; |
10f9d6fcfeab
JEP85: Reset composing/paused state when a resource with higher prio comes up
Mikael Berthe <mikael@lilotux.net>
parents:
1072
diff
changeset
|
608 #endif |
990
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
609 |
1058 | 610 bjid = buddy_getjid(buddy); |
611 if (!bjid) return; | |
990
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
612 |
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
613 #ifdef JEP0085 |
1091
10f9d6fcfeab
JEP85: Reset composing/paused state when a resource with higher prio comes up
Mikael Berthe <mikael@lilotux.net>
parents:
1072
diff
changeset
|
614 /* Send the chatstate to the last resource (which should have the highest |
10f9d6fcfeab
JEP85: Reset composing/paused state when a resource with higher prio comes up
Mikael Berthe <mikael@lilotux.net>
parents:
1072
diff
changeset
|
615 priority). |
10f9d6fcfeab
JEP85: Reset composing/paused state when a resource with higher prio comes up
Mikael Berthe <mikael@lilotux.net>
parents:
1072
diff
changeset
|
616 If chatstate is "active", send an "active" state to all resources |
10f9d6fcfeab
JEP85: Reset composing/paused state when a resource with higher prio comes up
Mikael Berthe <mikael@lilotux.net>
parents:
1072
diff
changeset
|
617 which do not curently have this state. |
10f9d6fcfeab
JEP85: Reset composing/paused state when a resource with higher prio comes up
Mikael Berthe <mikael@lilotux.net>
parents:
1072
diff
changeset
|
618 */ |
10f9d6fcfeab
JEP85: Reset composing/paused state when a resource with higher prio comes up
Mikael Berthe <mikael@lilotux.net>
parents:
1072
diff
changeset
|
619 resources = buddy_getresources(buddy); |
10f9d6fcfeab
JEP85: Reset composing/paused state when a resource with higher prio comes up
Mikael Berthe <mikael@lilotux.net>
parents:
1072
diff
changeset
|
620 for (p_res = resources ; p_res ; p_res = p_next) { |
10f9d6fcfeab
JEP85: Reset composing/paused state when a resource with higher prio comes up
Mikael Berthe <mikael@lilotux.net>
parents:
1072
diff
changeset
|
621 p_next = g_slist_next(p_res); |
10f9d6fcfeab
JEP85: Reset composing/paused state when a resource with higher prio comes up
Mikael Berthe <mikael@lilotux.net>
parents:
1072
diff
changeset
|
622 jep85 = buddy_resource_jep85(buddy, p_res->data); |
10f9d6fcfeab
JEP85: Reset composing/paused state when a resource with higher prio comes up
Mikael Berthe <mikael@lilotux.net>
parents:
1072
diff
changeset
|
623 if (jep85 && jep85->support == CHATSTATES_SUPPORT_OK) { |
10f9d6fcfeab
JEP85: Reset composing/paused state when a resource with higher prio comes up
Mikael Berthe <mikael@lilotux.net>
parents:
1072
diff
changeset
|
624 // If p_next is NULL, this is the highest (prio) resource, i.e. |
10f9d6fcfeab
JEP85: Reset composing/paused state when a resource with higher prio comes up
Mikael Berthe <mikael@lilotux.net>
parents:
1072
diff
changeset
|
625 // the one we are probably writing to. |
10f9d6fcfeab
JEP85: Reset composing/paused state when a resource with higher prio comes up
Mikael Berthe <mikael@lilotux.net>
parents:
1072
diff
changeset
|
626 if (!p_next || (jep85->last_state_sent != ROSTER_EVENT_ACTIVE && |
10f9d6fcfeab
JEP85: Reset composing/paused state when a resource with higher prio comes up
Mikael Berthe <mikael@lilotux.net>
parents:
1072
diff
changeset
|
627 chatstate == ROSTER_EVENT_ACTIVE)) |
1598 | 628 xmpp_send_jep85_chatstate(bjid, p_res->data, chatstate); |
1091
10f9d6fcfeab
JEP85: Reset composing/paused state when a resource with higher prio comes up
Mikael Berthe <mikael@lilotux.net>
parents:
1072
diff
changeset
|
629 } |
10f9d6fcfeab
JEP85: Reset composing/paused state when a resource with higher prio comes up
Mikael Berthe <mikael@lilotux.net>
parents:
1072
diff
changeset
|
630 g_free(p_res->data); |
990
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
631 } |
1091
10f9d6fcfeab
JEP85: Reset composing/paused state when a resource with higher prio comes up
Mikael Berthe <mikael@lilotux.net>
parents:
1072
diff
changeset
|
632 g_slist_free(resources); |
1099
7804dbac3875
Fix a potential JEP22/85 issue introduced by changeset 10f9d6fcfeab
Mikael Berthe <mikael@lilotux.net>
parents:
1091
diff
changeset
|
633 // If the last resource had chatstates support when can return now, |
7804dbac3875
Fix a potential JEP22/85 issue introduced by changeset 10f9d6fcfeab
Mikael Berthe <mikael@lilotux.net>
parents:
1091
diff
changeset
|
634 // we don't want to send a JEP22 event. |
7804dbac3875
Fix a potential JEP22/85 issue introduced by changeset 10f9d6fcfeab
Mikael Berthe <mikael@lilotux.net>
parents:
1091
diff
changeset
|
635 if (jep85 && jep85->support == CHATSTATES_SUPPORT_OK) |
7804dbac3875
Fix a potential JEP22/85 issue introduced by changeset 10f9d6fcfeab
Mikael Berthe <mikael@lilotux.net>
parents:
1091
diff
changeset
|
636 return; |
990
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
637 #endif |
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
638 #ifdef JEP0022 |
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
639 jep22 = buddy_resource_jep22(buddy, NULL); |
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
640 if (jep22 && jep22->support == CHATSTATES_SUPPORT_OK) { |
1598 | 641 xmpp_send_jep22_event(bjid, chatstate); |
990
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
642 } |
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
643 #endif |
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
644 } |
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
645 #endif |
35e7913affb7
Send events/chatstates notifications (JEP-22/JEP-85)
Mikael Berthe <mikael@lilotux.net>
parents:
989
diff
changeset
|
646 |
1598 | 647 |
999
9687ecc59303
Redo chat states detection if we receive a message error packet from a contact
Mikael Berthe <mikael@lilotux.net>
parents:
998
diff
changeset
|
648 // chatstates_reset_probed(fulljid) |
9687ecc59303
Redo chat states detection if we receive a message error packet from a contact
Mikael Berthe <mikael@lilotux.net>
parents:
998
diff
changeset
|
649 // If the JEP has been probed for this contact, set it back to unknown so |
9687ecc59303
Redo chat states detection if we receive a message error packet from a contact
Mikael Berthe <mikael@lilotux.net>
parents:
998
diff
changeset
|
650 // that we probe it again. The parameter must be a full jid (w/ resource). |
9687ecc59303
Redo chat states detection if we receive a message error packet from a contact
Mikael Berthe <mikael@lilotux.net>
parents:
998
diff
changeset
|
651 #if defined JEP0022 || defined JEP0085 |
9687ecc59303
Redo chat states detection if we receive a message error packet from a contact
Mikael Berthe <mikael@lilotux.net>
parents:
998
diff
changeset
|
652 static void chatstates_reset_probed(const char *fulljid) |
9687ecc59303
Redo chat states detection if we receive a message error packet from a contact
Mikael Berthe <mikael@lilotux.net>
parents:
998
diff
changeset
|
653 { |
9687ecc59303
Redo chat states detection if we receive a message error packet from a contact
Mikael Berthe <mikael@lilotux.net>
parents:
998
diff
changeset
|
654 char *rname, *barejid; |
9687ecc59303
Redo chat states detection if we receive a message error packet from a contact
Mikael Berthe <mikael@lilotux.net>
parents:
998
diff
changeset
|
655 GSList *sl_buddy; |
9687ecc59303
Redo chat states detection if we receive a message error packet from a contact
Mikael Berthe <mikael@lilotux.net>
parents:
998
diff
changeset
|
656 struct jep0085 *jep85; |
9687ecc59303
Redo chat states detection if we receive a message error packet from a contact
Mikael Berthe <mikael@lilotux.net>
parents:
998
diff
changeset
|
657 struct jep0022 *jep22; |
9687ecc59303
Redo chat states detection if we receive a message error packet from a contact
Mikael Berthe <mikael@lilotux.net>
parents:
998
diff
changeset
|
658 |
9687ecc59303
Redo chat states detection if we receive a message error packet from a contact
Mikael Berthe <mikael@lilotux.net>
parents:
998
diff
changeset
|
659 rname = strchr(fulljid, JID_RESOURCE_SEPARATOR); |
9687ecc59303
Redo chat states detection if we receive a message error packet from a contact
Mikael Berthe <mikael@lilotux.net>
parents:
998
diff
changeset
|
660 if (!rname++) |
9687ecc59303
Redo chat states detection if we receive a message error packet from a contact
Mikael Berthe <mikael@lilotux.net>
parents:
998
diff
changeset
|
661 return; |
9687ecc59303
Redo chat states detection if we receive a message error packet from a contact
Mikael Berthe <mikael@lilotux.net>
parents:
998
diff
changeset
|
662 |
9687ecc59303
Redo chat states detection if we receive a message error packet from a contact
Mikael Berthe <mikael@lilotux.net>
parents:
998
diff
changeset
|
663 barejid = jidtodisp(fulljid); |
9687ecc59303
Redo chat states detection if we receive a message error packet from a contact
Mikael Berthe <mikael@lilotux.net>
parents:
998
diff
changeset
|
664 sl_buddy = roster_find(barejid, jidsearch, ROSTER_TYPE_USER); |
9687ecc59303
Redo chat states detection if we receive a message error packet from a contact
Mikael Berthe <mikael@lilotux.net>
parents:
998
diff
changeset
|
665 g_free(barejid); |
9687ecc59303
Redo chat states detection if we receive a message error packet from a contact
Mikael Berthe <mikael@lilotux.net>
parents:
998
diff
changeset
|
666 |
9687ecc59303
Redo chat states detection if we receive a message error packet from a contact
Mikael Berthe <mikael@lilotux.net>
parents:
998
diff
changeset
|
667 if (!sl_buddy) |
9687ecc59303
Redo chat states detection if we receive a message error packet from a contact
Mikael Berthe <mikael@lilotux.net>
parents:
998
diff
changeset
|
668 return; |
9687ecc59303
Redo chat states detection if we receive a message error packet from a contact
Mikael Berthe <mikael@lilotux.net>
parents:
998
diff
changeset
|
669 |
9687ecc59303
Redo chat states detection if we receive a message error packet from a contact
Mikael Berthe <mikael@lilotux.net>
parents:
998
diff
changeset
|
670 jep85 = buddy_resource_jep85(sl_buddy->data, rname); |
9687ecc59303
Redo chat states detection if we receive a message error packet from a contact
Mikael Berthe <mikael@lilotux.net>
parents:
998
diff
changeset
|
671 jep22 = buddy_resource_jep22(sl_buddy->data, rname); |
9687ecc59303
Redo chat states detection if we receive a message error packet from a contact
Mikael Berthe <mikael@lilotux.net>
parents:
998
diff
changeset
|
672 |
9687ecc59303
Redo chat states detection if we receive a message error packet from a contact
Mikael Berthe <mikael@lilotux.net>
parents:
998
diff
changeset
|
673 if (jep85 && jep85->support == CHATSTATES_SUPPORT_PROBED) |
9687ecc59303
Redo chat states detection if we receive a message error packet from a contact
Mikael Berthe <mikael@lilotux.net>
parents:
998
diff
changeset
|
674 jep85->support = CHATSTATES_SUPPORT_UNKNOWN; |
9687ecc59303
Redo chat states detection if we receive a message error packet from a contact
Mikael Berthe <mikael@lilotux.net>
parents:
998
diff
changeset
|
675 if (jep22 && jep22->support == CHATSTATES_SUPPORT_PROBED) |
9687ecc59303
Redo chat states detection if we receive a message error packet from a contact
Mikael Berthe <mikael@lilotux.net>
parents:
998
diff
changeset
|
676 jep22->support = CHATSTATES_SUPPORT_UNKNOWN; |
9687ecc59303
Redo chat states detection if we receive a message error packet from a contact
Mikael Berthe <mikael@lilotux.net>
parents:
998
diff
changeset
|
677 } |
9687ecc59303
Redo chat states detection if we receive a message error packet from a contact
Mikael Berthe <mikael@lilotux.net>
parents:
998
diff
changeset
|
678 #endif |
9687ecc59303
Redo chat states detection if we receive a message error packet from a contact
Mikael Berthe <mikael@lilotux.net>
parents:
998
diff
changeset
|
679 |
1194
03d8fafe8104
Remove a warning when gpgme is disabled
Mikael Berthe <mikael@lilotux.net>
parents:
1166
diff
changeset
|
680 #ifdef HAVE_GPGME |
1104
382972712208
Allow short key format in check_signature()
Mikael Berthe <mikael@lilotux.net>
parents:
1099
diff
changeset
|
681 // keys_mismatch(key, expectedkey) |
382972712208
Allow short key format in check_signature()
Mikael Berthe <mikael@lilotux.net>
parents:
1099
diff
changeset
|
682 // Return TRUE if both keys are non-null and "expectedkey" doesn't match |
382972712208
Allow short key format in check_signature()
Mikael Berthe <mikael@lilotux.net>
parents:
1099
diff
changeset
|
683 // the end of "key". |
382972712208
Allow short key format in check_signature()
Mikael Berthe <mikael@lilotux.net>
parents:
1099
diff
changeset
|
684 // If one of the keys is null, return FALSE. |
382972712208
Allow short key format in check_signature()
Mikael Berthe <mikael@lilotux.net>
parents:
1099
diff
changeset
|
685 // If expectedkey is less than 8 bytes long, return TRUE. |
382972712208
Allow short key format in check_signature()
Mikael Berthe <mikael@lilotux.net>
parents:
1099
diff
changeset
|
686 // |
382972712208
Allow short key format in check_signature()
Mikael Berthe <mikael@lilotux.net>
parents:
1099
diff
changeset
|
687 // Example: keys_mismatch("C9940A9BB0B92210", "B0B92210") will return FALSE. |
382972712208
Allow short key format in check_signature()
Mikael Berthe <mikael@lilotux.net>
parents:
1099
diff
changeset
|
688 static bool keys_mismatch(const char *key, const char *expectedkey) |
382972712208
Allow short key format in check_signature()
Mikael Berthe <mikael@lilotux.net>
parents:
1099
diff
changeset
|
689 { |
382972712208
Allow short key format in check_signature()
Mikael Berthe <mikael@lilotux.net>
parents:
1099
diff
changeset
|
690 int lk, lek; |
382972712208
Allow short key format in check_signature()
Mikael Berthe <mikael@lilotux.net>
parents:
1099
diff
changeset
|
691 |
382972712208
Allow short key format in check_signature()
Mikael Berthe <mikael@lilotux.net>
parents:
1099
diff
changeset
|
692 if (!expectedkey || !key) |
382972712208
Allow short key format in check_signature()
Mikael Berthe <mikael@lilotux.net>
parents:
1099
diff
changeset
|
693 return FALSE; |
382972712208
Allow short key format in check_signature()
Mikael Berthe <mikael@lilotux.net>
parents:
1099
diff
changeset
|
694 |
382972712208
Allow short key format in check_signature()
Mikael Berthe <mikael@lilotux.net>
parents:
1099
diff
changeset
|
695 lk = strlen(key); |
382972712208
Allow short key format in check_signature()
Mikael Berthe <mikael@lilotux.net>
parents:
1099
diff
changeset
|
696 lek = strlen(expectedkey); |
382972712208
Allow short key format in check_signature()
Mikael Berthe <mikael@lilotux.net>
parents:
1099
diff
changeset
|
697 |
382972712208
Allow short key format in check_signature()
Mikael Berthe <mikael@lilotux.net>
parents:
1099
diff
changeset
|
698 // If the expectedkey is less than 8 bytes long, this is probably a |
382972712208
Allow short key format in check_signature()
Mikael Berthe <mikael@lilotux.net>
parents:
1099
diff
changeset
|
699 // user mistake so we consider it's a mismatch. |
382972712208
Allow short key format in check_signature()
Mikael Berthe <mikael@lilotux.net>
parents:
1099
diff
changeset
|
700 if (lek < 8) |
382972712208
Allow short key format in check_signature()
Mikael Berthe <mikael@lilotux.net>
parents:
1099
diff
changeset
|
701 return TRUE; |
382972712208
Allow short key format in check_signature()
Mikael Berthe <mikael@lilotux.net>
parents:
1099
diff
changeset
|
702 |
382972712208
Allow short key format in check_signature()
Mikael Berthe <mikael@lilotux.net>
parents:
1099
diff
changeset
|
703 if (lek < lk) |
382972712208
Allow short key format in check_signature()
Mikael Berthe <mikael@lilotux.net>
parents:
1099
diff
changeset
|
704 key += lk - lek; |
382972712208
Allow short key format in check_signature()
Mikael Berthe <mikael@lilotux.net>
parents:
1099
diff
changeset
|
705 |
382972712208
Allow short key format in check_signature()
Mikael Berthe <mikael@lilotux.net>
parents:
1099
diff
changeset
|
706 return strcasecmp(key, expectedkey); |
382972712208
Allow short key format in check_signature()
Mikael Berthe <mikael@lilotux.net>
parents:
1099
diff
changeset
|
707 } |
1194
03d8fafe8104
Remove a warning when gpgme is disabled
Mikael Berthe <mikael@lilotux.net>
parents:
1166
diff
changeset
|
708 #endif |
1104
382972712208
Allow short key format in check_signature()
Mikael Berthe <mikael@lilotux.net>
parents:
1099
diff
changeset
|
709 |
1043
ebbde723614b
Store contacts PGP keys
Mikael Berthe <mikael@lilotux.net>
parents:
1042
diff
changeset
|
710 // check_signature(barejid, resourcename, xmldata, text) |
ebbde723614b
Store contacts PGP keys
Mikael Berthe <mikael@lilotux.net>
parents:
1042
diff
changeset
|
711 // Verify the signature (in xmldata) of "text" for the contact |
ebbde723614b
Store contacts PGP keys
Mikael Berthe <mikael@lilotux.net>
parents:
1042
diff
changeset
|
712 // barejid/resourcename. |
ebbde723614b
Store contacts PGP keys
Mikael Berthe <mikael@lilotux.net>
parents:
1042
diff
changeset
|
713 // xmldata is the 'jabber:x:signed' stanza. |
ebbde723614b
Store contacts PGP keys
Mikael Berthe <mikael@lilotux.net>
parents:
1042
diff
changeset
|
714 // If the key id is found, the contact's PGP data are updated. |
ebbde723614b
Store contacts PGP keys
Mikael Berthe <mikael@lilotux.net>
parents:
1042
diff
changeset
|
715 static void check_signature(const char *barejid, const char *rname, |
1598 | 716 LmMessageNode *node, const char *text) |
1043
ebbde723614b
Store contacts PGP keys
Mikael Berthe <mikael@lilotux.net>
parents:
1042
diff
changeset
|
717 { |
ebbde723614b
Store contacts PGP keys
Mikael Berthe <mikael@lilotux.net>
parents:
1042
diff
changeset
|
718 #ifdef HAVE_GPGME |
1598 | 719 const char *p, *key; |
1043
ebbde723614b
Store contacts PGP keys
Mikael Berthe <mikael@lilotux.net>
parents:
1042
diff
changeset
|
720 GSList *sl_buddy; |
ebbde723614b
Store contacts PGP keys
Mikael Berthe <mikael@lilotux.net>
parents:
1042
diff
changeset
|
721 struct pgp_data *res_pgpdata; |
ebbde723614b
Store contacts PGP keys
Mikael Berthe <mikael@lilotux.net>
parents:
1042
diff
changeset
|
722 gpgme_sigsum_t sigsum; |
ebbde723614b
Store contacts PGP keys
Mikael Berthe <mikael@lilotux.net>
parents:
1042
diff
changeset
|
723 |
ebbde723614b
Store contacts PGP keys
Mikael Berthe <mikael@lilotux.net>
parents:
1042
diff
changeset
|
724 // All parameters must be valid |
1598 | 725 if (!(node && barejid && rname && text)) |
1043
ebbde723614b
Store contacts PGP keys
Mikael Berthe <mikael@lilotux.net>
parents:
1042
diff
changeset
|
726 return; |
ebbde723614b
Store contacts PGP keys
Mikael Berthe <mikael@lilotux.net>
parents:
1042
diff
changeset
|
727 |
ebbde723614b
Store contacts PGP keys
Mikael Berthe <mikael@lilotux.net>
parents:
1042
diff
changeset
|
728 if (!gpg_enabled()) |
ebbde723614b
Store contacts PGP keys
Mikael Berthe <mikael@lilotux.net>
parents:
1042
diff
changeset
|
729 return; |
ebbde723614b
Store contacts PGP keys
Mikael Berthe <mikael@lilotux.net>
parents:
1042
diff
changeset
|
730 |
ebbde723614b
Store contacts PGP keys
Mikael Berthe <mikael@lilotux.net>
parents:
1042
diff
changeset
|
731 // Get the resource PGP data structure |
ebbde723614b
Store contacts PGP keys
Mikael Berthe <mikael@lilotux.net>
parents:
1042
diff
changeset
|
732 sl_buddy = roster_find(barejid, jidsearch, ROSTER_TYPE_USER); |
ebbde723614b
Store contacts PGP keys
Mikael Berthe <mikael@lilotux.net>
parents:
1042
diff
changeset
|
733 if (!sl_buddy) |
ebbde723614b
Store contacts PGP keys
Mikael Berthe <mikael@lilotux.net>
parents:
1042
diff
changeset
|
734 return; |
ebbde723614b
Store contacts PGP keys
Mikael Berthe <mikael@lilotux.net>
parents:
1042
diff
changeset
|
735 res_pgpdata = buddy_resource_pgp(sl_buddy->data, rname); |
ebbde723614b
Store contacts PGP keys
Mikael Berthe <mikael@lilotux.net>
parents:
1042
diff
changeset
|
736 if (!res_pgpdata) |
ebbde723614b
Store contacts PGP keys
Mikael Berthe <mikael@lilotux.net>
parents:
1042
diff
changeset
|
737 return; |
ebbde723614b
Store contacts PGP keys
Mikael Berthe <mikael@lilotux.net>
parents:
1042
diff
changeset
|
738 |
1598 | 739 if (!node->name || strcmp(node->name, "x")) //XXX: probably useless |
1043
ebbde723614b
Store contacts PGP keys
Mikael Berthe <mikael@lilotux.net>
parents:
1042
diff
changeset
|
740 return; // We expect "<x xmlns='jabber:x:signed'>" |
ebbde723614b
Store contacts PGP keys
Mikael Berthe <mikael@lilotux.net>
parents:
1042
diff
changeset
|
741 |
ebbde723614b
Store contacts PGP keys
Mikael Berthe <mikael@lilotux.net>
parents:
1042
diff
changeset
|
742 // Get signature |
1598 | 743 p = lm_message_node_get_value(node); |
1043
ebbde723614b
Store contacts PGP keys
Mikael Berthe <mikael@lilotux.net>
parents:
1042
diff
changeset
|
744 if (!p) |
ebbde723614b
Store contacts PGP keys
Mikael Berthe <mikael@lilotux.net>
parents:
1042
diff
changeset
|
745 return; |
ebbde723614b
Store contacts PGP keys
Mikael Berthe <mikael@lilotux.net>
parents:
1042
diff
changeset
|
746 |
ebbde723614b
Store contacts PGP keys
Mikael Berthe <mikael@lilotux.net>
parents:
1042
diff
changeset
|
747 key = gpg_verify(p, text, &sigsum); |
ebbde723614b
Store contacts PGP keys
Mikael Berthe <mikael@lilotux.net>
parents:
1042
diff
changeset
|
748 if (key) { |
1067
a5dc85fdebde
Add key comparison for signatures & use user-provided PGP keys for encryption
Mikael Berthe <mikael@lilotux.net>
parents:
1065
diff
changeset
|
749 const char *expectedkey; |
a5dc85fdebde
Add key comparison for signatures & use user-provided PGP keys for encryption
Mikael Berthe <mikael@lilotux.net>
parents:
1065
diff
changeset
|
750 char *buf; |
1043
ebbde723614b
Store contacts PGP keys
Mikael Berthe <mikael@lilotux.net>
parents:
1042
diff
changeset
|
751 g_free(res_pgpdata->sign_keyid); |
1598 | 752 res_pgpdata->sign_keyid = (char *)key; |
1043
ebbde723614b
Store contacts PGP keys
Mikael Berthe <mikael@lilotux.net>
parents:
1042
diff
changeset
|
753 res_pgpdata->last_sigsum = sigsum; |
1046
a3748bd3d010
Tell the user when a signature is bad
Mikael Berthe <mikael@lilotux.net>
parents:
1045
diff
changeset
|
754 if (sigsum & GPGME_SIGSUM_RED) { |
1067
a5dc85fdebde
Add key comparison for signatures & use user-provided PGP keys for encryption
Mikael Berthe <mikael@lilotux.net>
parents:
1065
diff
changeset
|
755 buf = g_strdup_printf("Bad signature from <%s/%s>", barejid, rname); |
1290
e42f48103609
Drawing the MUC nicks by a different color
Michal 'vorner' Vaner <vorner@ucw.cz>
parents:
1282
diff
changeset
|
756 scr_WriteIncomingMessage(barejid, buf, 0, HBB_PREFIX_INFO, 0); |
1067
a5dc85fdebde
Add key comparison for signatures & use user-provided PGP keys for encryption
Mikael Berthe <mikael@lilotux.net>
parents:
1065
diff
changeset
|
757 scr_LogPrint(LPRINT_LOGNORM, "%s", buf); |
a5dc85fdebde
Add key comparison for signatures & use user-provided PGP keys for encryption
Mikael Berthe <mikael@lilotux.net>
parents:
1065
diff
changeset
|
758 g_free(buf); |
a5dc85fdebde
Add key comparison for signatures & use user-provided PGP keys for encryption
Mikael Berthe <mikael@lilotux.net>
parents:
1065
diff
changeset
|
759 } |
a5dc85fdebde
Add key comparison for signatures & use user-provided PGP keys for encryption
Mikael Berthe <mikael@lilotux.net>
parents:
1065
diff
changeset
|
760 // Verify that the key id is the one we expect. |
a5dc85fdebde
Add key comparison for signatures & use user-provided PGP keys for encryption
Mikael Berthe <mikael@lilotux.net>
parents:
1065
diff
changeset
|
761 expectedkey = settings_pgp_getkeyid(barejid); |
1104
382972712208
Allow short key format in check_signature()
Mikael Berthe <mikael@lilotux.net>
parents:
1099
diff
changeset
|
762 if (keys_mismatch(key, expectedkey)) { |
1067
a5dc85fdebde
Add key comparison for signatures & use user-provided PGP keys for encryption
Mikael Berthe <mikael@lilotux.net>
parents:
1065
diff
changeset
|
763 buf = g_strdup_printf("Warning: The KeyId from <%s/%s> doesn't match " |
a5dc85fdebde
Add key comparison for signatures & use user-provided PGP keys for encryption
Mikael Berthe <mikael@lilotux.net>
parents:
1065
diff
changeset
|
764 "the key you set up", barejid, rname); |
1290
e42f48103609
Drawing the MUC nicks by a different color
Michal 'vorner' Vaner <vorner@ucw.cz>
parents:
1282
diff
changeset
|
765 scr_WriteIncomingMessage(barejid, buf, 0, HBB_PREFIX_INFO, 0); |
1046
a3748bd3d010
Tell the user when a signature is bad
Mikael Berthe <mikael@lilotux.net>
parents:
1045
diff
changeset
|
766 scr_LogPrint(LPRINT_LOGNORM, "%s", buf); |
a3748bd3d010
Tell the user when a signature is bad
Mikael Berthe <mikael@lilotux.net>
parents:
1045
diff
changeset
|
767 g_free(buf); |
a3748bd3d010
Tell the user when a signature is bad
Mikael Berthe <mikael@lilotux.net>
parents:
1045
diff
changeset
|
768 } |
1043
ebbde723614b
Store contacts PGP keys
Mikael Berthe <mikael@lilotux.net>
parents:
1042
diff
changeset
|
769 } |
ebbde723614b
Store contacts PGP keys
Mikael Berthe <mikael@lilotux.net>
parents:
1042
diff
changeset
|
770 #endif |
ebbde723614b
Store contacts PGP keys
Mikael Berthe <mikael@lilotux.net>
parents:
1042
diff
changeset
|
771 } |
ebbde723614b
Store contacts PGP keys
Mikael Berthe <mikael@lilotux.net>
parents:
1042
diff
changeset
|
772 |
1598 | 773 static LmSSLResponse ssl_cb(LmSSL *ssl, LmSSLStatus status, gpointer ud) |
774 { | |
775 scr_LogPrint(LPRINT_LOGNORM, "SSL status:%d", status); | |
776 | |
777 switch (status) { | |
778 case LM_SSL_STATUS_NO_CERT_FOUND: | |
779 scr_LogPrint(LPRINT_LOGNORM, "No certificate found!"); | |
780 break; | |
781 case LM_SSL_STATUS_UNTRUSTED_CERT: | |
782 scr_LogPrint(LPRINT_LOGNORM, "Certificate is not trusted!"); | |
783 break; | |
784 case LM_SSL_STATUS_CERT_EXPIRED: | |
785 scr_LogPrint(LPRINT_LOGNORM, "Certificate has expired!"); | |
786 break; | |
787 case LM_SSL_STATUS_CERT_NOT_ACTIVATED: | |
788 scr_LogPrint(LPRINT_LOGNORM, "Certificate has not been activated!"); | |
789 break; | |
790 case LM_SSL_STATUS_CERT_HOSTNAME_MISMATCH: | |
791 scr_LogPrint(LPRINT_LOGNORM, | |
792 "Certificate hostname does not match expected hostname!"); | |
793 break; | |
794 case LM_SSL_STATUS_CERT_FINGERPRINT_MISMATCH: { | |
795 char fpr[49]; | |
796 fingerprint_to_hex((const unsigned char*)lm_ssl_get_fingerprint(ssl), | |
797 fpr); | |
798 scr_LogPrint(LPRINT_LOGNORM, | |
799 "Certificate fingerprint does not match expected fingerprint!"); | |
800 scr_LogPrint(LPRINT_LOGNORM, "Remote fingerprint: %s", fpr); | |
801 | |
802 scr_LogPrint(LPRINT_LOGNORM, "Expected fingerprint: %s", | |
803 settings_opt_get("ssl_fingerprint")); | |
804 | |
805 return LM_SSL_RESPONSE_STOP; | |
806 break; | |
807 } | |
808 case LM_SSL_STATUS_GENERIC_ERROR: | |
809 scr_LogPrint(LPRINT_LOGNORM, "Generic SSL error!"); | |
810 break; | |
811 } | |
812 | |
813 if (!settings_opt_get_int("ssl_ignore_checks")) | |
814 return LM_SSL_RESPONSE_CONTINUE; | |
815 return LM_SSL_RESPONSE_STOP; | |
816 } | |
817 | |
818 static void connection_auth_cb(LmConnection *connection, gboolean success, | |
819 gpointer user_data) | |
820 { | |
821 if (success) { | |
822 LmMessage *m; | |
823 | |
824 m = lm_message_new_with_sub_type(NULL, LM_MESSAGE_TYPE_PRESENCE, | |
825 LM_MESSAGE_SUB_TYPE_AVAILABLE); | |
826 lm_connection_send(connection, m, NULL); | |
827 | |
828 lm_message_unref(m); | |
829 xmpp_setprevstatus(); | |
830 xmpp_iq_request(NULL, NS_ROSTER); | |
831 xmpp_request_storage("storage:bookmarks"); | |
832 xmpp_request_storage("storage:rosternotes"); | |
833 | |
834 AutoConnection = TRUE; | |
835 } else | |
836 scr_LogPrint(LPRINT_LOGNORM, "Authentication failed"); | |
837 } | |
838 | |
839 gboolean xmpp_reconnect() | |
840 { | |
841 if (!lm_connection_is_authenticated(lconnection)) | |
842 xmpp_connect(); | |
843 return FALSE; | |
844 } | |
845 | |
846 static void _try_to_reconnect(void) | |
847 { | |
848 if (AutoConnection) | |
849 g_timeout_add_seconds(RECONNECTION_TIMEOUT, xmpp_reconnect, NULL); | |
850 } | |
851 | |
852 static void connection_open_cb(LmConnection *connection, gboolean success, | |
853 gpointer user_data) | |
854 { | |
1610
6db9f403f707
Replace 'username' with 'jid' in the configuration file
Mikael Berthe <mikael@lilotux.net>
parents:
1604
diff
changeset
|
855 const char *userjid, *password, *resource, *servername; |
1598 | 856 GError *error; |
857 | |
858 if (success) { | |
859 servername = settings_opt_get("server"); | |
1610
6db9f403f707
Replace 'username' with 'jid' in the configuration file
Mikael Berthe <mikael@lilotux.net>
parents:
1604
diff
changeset
|
860 userjid = settings_opt_get("jid"); |
1598 | 861 password = settings_opt_get("password"); |
862 resource = strchr(lm_connection_get_jid(connection), | |
863 JID_RESOURCE_SEPARATOR); | |
864 if (resource) | |
865 resource++; | |
866 | |
1610
6db9f403f707
Replace 'username' with 'jid' in the configuration file
Mikael Berthe <mikael@lilotux.net>
parents:
1604
diff
changeset
|
867 if (!lm_connection_authenticate(lconnection, userjid, password, resource, |
1598 | 868 connection_auth_cb, NULL, FALSE, &error)) { |
869 scr_LogPrint(LPRINT_LOGNORM, "Failed to authenticate: %s\n", | |
870 error->message); | |
871 _try_to_reconnect(); | |
872 } | |
873 } else { | |
874 scr_LogPrint(LPRINT_LOGNORM, "There was an error while connecting."); | |
875 _try_to_reconnect(); | |
876 } | |
877 } | |
878 | |
879 static void connection_close_cb(LmConnection *connection, | |
880 LmDisconnectReason reason, | |
881 gpointer user_data) | |
882 { | |
883 const char *str; | |
884 | |
885 switch (reason) { | |
886 case LM_DISCONNECT_REASON_OK: | |
887 str = "LM_DISCONNECT_REASON_OK"; | |
888 break; | |
889 case LM_DISCONNECT_REASON_PING_TIME_OUT: | |
890 str = "LM_DISCONNECT_REASON_PING_TIME_OUT"; | |
891 break; | |
892 case LM_DISCONNECT_REASON_HUP: | |
893 str = "LM_DISCONNECT_REASON_HUP"; | |
894 break; | |
895 case LM_DISCONNECT_REASON_ERROR: | |
896 str = "LM_DISCONNECT_REASON_ERROR"; | |
897 break; | |
898 case LM_DISCONNECT_REASON_UNKNOWN: | |
899 default: | |
900 str = "LM_DISCONNECT_REASON_UNKNOWN"; | |
901 break; | |
902 } | |
903 | |
904 if (reason != LM_DISCONNECT_REASON_OK) | |
905 _try_to_reconnect(); | |
906 | |
907 // Free bookmarks | |
908 if (bookmarks) | |
909 lm_message_node_unref(bookmarks); | |
910 bookmarks = NULL; | |
911 // Free roster | |
912 roster_free(); | |
913 if (rosternotes) | |
914 lm_message_node_unref(rosternotes); | |
915 rosternotes = NULL; | |
916 // Update display | |
917 update_roster = TRUE; | |
918 scr_UpdateBuddyWindow(); | |
919 | |
920 scr_LogPrint(LPRINT_NORMAL, "Disconnected, reason:%d->'%s'\n", reason, str); | |
921 } | |
922 | |
923 static void handle_state_events(const char *from, LmMessageNode *node) | |
924 { | |
925 #if defined JEP0022 || defined JEP0085 | |
926 LmMessageNode *state_ns = NULL; | |
927 const char *body; | |
928 char *rname, *bjid; | |
929 GSList *sl_buddy; | |
930 guint events; | |
931 struct jep0022 *jep22 = NULL; | |
932 struct jep0085 *jep85 = NULL; | |
933 enum { | |
934 JEP_none, | |
935 JEP_85, | |
936 JEP_22 | |
937 } which_jep = JEP_none; | |
938 | |
939 rname = strchr(from, JID_RESOURCE_SEPARATOR); | |
940 if (rname) | |
941 ++rname; | |
942 else | |
943 rname = (char *)from + strlen(from); | |
944 bjid = jidtodisp(from); | |
945 sl_buddy = roster_find(bjid, jidsearch, ROSTER_TYPE_USER); | |
946 g_free(bjid); | |
947 | |
948 /* XXX Actually that's wrong, since it filters out server "offline" | |
949 messages (for JEP-0022). This JEP is (almost) deprecated so | |
950 we don't really care. */ | |
951 if (!sl_buddy) { | |
952 return; | |
953 } | |
954 | |
955 /* Let's see chich JEP the contact uses. If possible, we'll use | |
956 JEP-85, if not we'll look for JEP-22 support. */ | |
957 events = buddy_resource_getevents(sl_buddy->data, rname); | |
958 | |
959 jep85 = buddy_resource_jep85(sl_buddy->data, rname); | |
960 if (jep85) { | |
961 state_ns = lm_message_node_find_xmlns(node, NS_CHATSTATES); | |
962 if (state_ns) | |
963 which_jep = JEP_85; | |
964 } | |
965 | |
966 if (which_jep != JEP_85) { /* Fall back to JEP-0022 */ | |
967 jep22 = buddy_resource_jep22(sl_buddy->data, rname); | |
968 if (jep22) { | |
969 state_ns = lm_message_node_find_xmlns(node, NS_EVENT); | |
970 if (state_ns) | |
971 which_jep = JEP_22; | |
972 } | |
973 } | |
974 | |
975 if (!which_jep) { /* Sender does not use chat states */ | |
976 return; | |
977 } | |
978 | |
979 body = lm_message_node_get_child_value(node, "body"); | |
980 | |
981 if (which_jep == JEP_85) { /* JEP-0085 */ | |
982 jep85->support = CHATSTATES_SUPPORT_OK; | |
983 | |
984 if (!strcmp(state_ns->name, "composing")) { | |
985 jep85->last_state_rcvd = ROSTER_EVENT_COMPOSING; | |
986 } else if (!strcmp(state_ns->name, "active")) { | |
987 jep85->last_state_rcvd = ROSTER_EVENT_ACTIVE; | |
988 } else if (!strcmp(state_ns->name, "paused")) { | |
989 jep85->last_state_rcvd = ROSTER_EVENT_PAUSED; | |
990 } else if (!strcmp(state_ns->name, "inactive")) { | |
991 jep85->last_state_rcvd = ROSTER_EVENT_INACTIVE; | |
992 } else if (!strcmp(state_ns->name, "gone")) { | |
993 jep85->last_state_rcvd = ROSTER_EVENT_GONE; | |
994 } | |
995 events = jep85->last_state_rcvd; | |
996 } else { /* JEP-0022 */ | |
997 #ifdef JEP0022 | |
998 const char *msgid; | |
999 jep22->support = CHATSTATES_SUPPORT_OK; | |
1000 jep22->last_state_rcvd = ROSTER_EVENT_NONE; | |
1001 | |
1002 msgid = lm_message_node_get_attribute(node, "id"); | |
1003 | |
1004 if (lm_message_node_get_child(state_ns, "composing")) { | |
1005 // Clear composing if the message contains a body | |
1006 if (body) | |
1007 events &= ~ROSTER_EVENT_COMPOSING; | |
1008 else | |
1009 events |= ROSTER_EVENT_COMPOSING; | |
1010 jep22->last_state_rcvd |= ROSTER_EVENT_COMPOSING; | |
1011 | |
1012 } else { | |
1013 events &= ~ROSTER_EVENT_COMPOSING; | |
1014 } | |
1015 | |
1016 // Cache the message id | |
1017 g_free(jep22->last_msgid_rcvd); | |
1018 if (msgid) | |
1019 jep22->last_msgid_rcvd = g_strdup(msgid); | |
1020 else | |
1021 jep22->last_msgid_rcvd = NULL; | |
1022 | |
1023 if (lm_message_node_get_child(state_ns, "delivered")) { | |
1024 jep22->last_state_rcvd |= ROSTER_EVENT_DELIVERED; | |
1025 | |
1026 // Do we have to send back an ACK? | |
1027 if (body) | |
1028 xmpp_send_jep22_event(from, ROSTER_EVENT_DELIVERED); | |
1029 } | |
1030 #endif | |
1031 } | |
1032 | |
1033 buddy_resource_setevents(sl_buddy->data, rname, events); | |
1034 | |
1035 update_roster = TRUE; | |
1036 #endif | |
1037 } | |
1038 | |
1039 static void gotmessage(LmMessageSubType type, const char *from, | |
1040 const char *body, const char *enc, const char *subject, | |
1041 time_t timestamp, LmMessageNode *node_signed) | |
29 | 1042 { |
1058 | 1043 char *bjid; |
956
819396bebdf5
Do not block system messages when block_unsubscribed is set
Mikael Berthe <mikael@lilotux.net>
parents:
940
diff
changeset
|
1044 const char *rname, *s; |
1347
07816313073b
Add an option 'otr' to enable OTR support in the configuration file
Mikael Berthe <mikael@lilotux.net>
parents:
1344
diff
changeset
|
1045 char *decrypted_pgp = NULL; |
07816313073b
Add an option 'otr' to enable OTR support in the configuration file
Mikael Berthe <mikael@lilotux.net>
parents:
1344
diff
changeset
|
1046 char *decrypted_otr = NULL; |
1299
3b338a5c01fc
OTR support
Frank Zschockelt <mcabber_otr[at]freakysoft.de>
parents:
1290
diff
changeset
|
1047 int otr_msg = 0, free_msg = 0; |
29 | 1048 |
1058 | 1049 bjid = jidtodisp(from); |
441
51b8f10cfeb8
Handle g_locale_from_utf8() failures
Mikael Berthe <mikael@lilotux.net>
parents:
438
diff
changeset
|
1050 |
977
5b01de4ac5e1
Cosmetic changes
Alexis Hildebrandt <afh [at] 2drop [dot] net>
parents:
960
diff
changeset
|
1051 rname = strchr(from, JID_RESOURCE_SEPARATOR); |
447
03bb57383cea
Initial Multi-User Chat support
Mikael Berthe <mikael@lilotux.net>
parents:
444
diff
changeset
|
1052 if (rname) rname++; |
819
c2d7d9dd4193
New option 'block_unsubscribed'
Mikael Berthe <mikael@lilotux.net>
parents:
818
diff
changeset
|
1053 |
1042
8a395c2cafc4
Initial PGP support (decrypt)
Mikael Berthe <mikael@lilotux.net>
parents:
1023
diff
changeset
|
1054 #ifdef HAVE_GPGME |
8a395c2cafc4
Initial PGP support (decrypt)
Mikael Berthe <mikael@lilotux.net>
parents:
1023
diff
changeset
|
1055 if (enc && gpg_enabled()) { |
1347
07816313073b
Add an option 'otr' to enable OTR support in the configuration file
Mikael Berthe <mikael@lilotux.net>
parents:
1344
diff
changeset
|
1056 decrypted_pgp = gpg_decrypt(enc); |
07816313073b
Add an option 'otr' to enable OTR support in the configuration file
Mikael Berthe <mikael@lilotux.net>
parents:
1344
diff
changeset
|
1057 if (decrypted_pgp) { |
07816313073b
Add an option 'otr' to enable OTR support in the configuration file
Mikael Berthe <mikael@lilotux.net>
parents:
1344
diff
changeset
|
1058 body = decrypted_pgp; |
1043
ebbde723614b
Store contacts PGP keys
Mikael Berthe <mikael@lilotux.net>
parents:
1042
diff
changeset
|
1059 } |
1042
8a395c2cafc4
Initial PGP support (decrypt)
Mikael Berthe <mikael@lilotux.net>
parents:
1023
diff
changeset
|
1060 } |
1043
ebbde723614b
Store contacts PGP keys
Mikael Berthe <mikael@lilotux.net>
parents:
1042
diff
changeset
|
1061 // Check signature of an unencrypted message |
1598 | 1062 if (node_signed && gpg_enabled()) |
1063 check_signature(bjid, rname, node_signed, decrypted_pgp); | |
1042
8a395c2cafc4
Initial PGP support (decrypt)
Mikael Berthe <mikael@lilotux.net>
parents:
1023
diff
changeset
|
1064 #endif |
8a395c2cafc4
Initial PGP support (decrypt)
Mikael Berthe <mikael@lilotux.net>
parents:
1023
diff
changeset
|
1065 |
1299
3b338a5c01fc
OTR support
Frank Zschockelt <mcabber_otr[at]freakysoft.de>
parents:
1290
diff
changeset
|
1066 #ifdef HAVE_LIBOTR |
1347
07816313073b
Add an option 'otr' to enable OTR support in the configuration file
Mikael Berthe <mikael@lilotux.net>
parents:
1344
diff
changeset
|
1067 if (otr_enabled()) { |
07816313073b
Add an option 'otr' to enable OTR support in the configuration file
Mikael Berthe <mikael@lilotux.net>
parents:
1344
diff
changeset
|
1068 decrypted_otr = (char*)body; |
07816313073b
Add an option 'otr' to enable OTR support in the configuration file
Mikael Berthe <mikael@lilotux.net>
parents:
1344
diff
changeset
|
1069 otr_msg = otr_receive(&decrypted_otr, bjid, &free_msg); |
07816313073b
Add an option 'otr' to enable OTR support in the configuration file
Mikael Berthe <mikael@lilotux.net>
parents:
1344
diff
changeset
|
1070 if (!decrypted_otr) { |
07816313073b
Add an option 'otr' to enable OTR support in the configuration file
Mikael Berthe <mikael@lilotux.net>
parents:
1344
diff
changeset
|
1071 goto gotmessage_return; |
07816313073b
Add an option 'otr' to enable OTR support in the configuration file
Mikael Berthe <mikael@lilotux.net>
parents:
1344
diff
changeset
|
1072 } |
07816313073b
Add an option 'otr' to enable OTR support in the configuration file
Mikael Berthe <mikael@lilotux.net>
parents:
1344
diff
changeset
|
1073 body = decrypted_otr; |
1299
3b338a5c01fc
OTR support
Frank Zschockelt <mcabber_otr[at]freakysoft.de>
parents:
1290
diff
changeset
|
1074 } |
3b338a5c01fc
OTR support
Frank Zschockelt <mcabber_otr[at]freakysoft.de>
parents:
1290
diff
changeset
|
1075 #endif |
3b338a5c01fc
OTR support
Frank Zschockelt <mcabber_otr[at]freakysoft.de>
parents:
1290
diff
changeset
|
1076 |
864
a7b3409df6bc
MUC: Work around user server restart
Mikael Berthe <mikael@lilotux.net>
parents:
862
diff
changeset
|
1077 // Check for unexpected groupchat messages |
a7b3409df6bc
MUC: Work around user server restart
Mikael Berthe <mikael@lilotux.net>
parents:
862
diff
changeset
|
1078 // If we receive a groupchat message from a room we're not a member of, |
a7b3409df6bc
MUC: Work around user server restart
Mikael Berthe <mikael@lilotux.net>
parents:
862
diff
changeset
|
1079 // this is probably a server issue and the best we can do is to send |
a7b3409df6bc
MUC: Work around user server restart
Mikael Berthe <mikael@lilotux.net>
parents:
862
diff
changeset
|
1080 // a type unavailable. |
1598 | 1081 if (type == LM_MESSAGE_SUB_TYPE_GROUPCHAT && !roster_getnickname(bjid)) { |
864
a7b3409df6bc
MUC: Work around user server restart
Mikael Berthe <mikael@lilotux.net>
parents:
862
diff
changeset
|
1082 // It shouldn't happen, probably a server issue |
a7b3409df6bc
MUC: Work around user server restart
Mikael Berthe <mikael@lilotux.net>
parents:
862
diff
changeset
|
1083 GSList *room_elt; |
a7b3409df6bc
MUC: Work around user server restart
Mikael Berthe <mikael@lilotux.net>
parents:
862
diff
changeset
|
1084 char *mbuf; |
a7b3409df6bc
MUC: Work around user server restart
Mikael Berthe <mikael@lilotux.net>
parents:
862
diff
changeset
|
1085 |
a7b3409df6bc
MUC: Work around user server restart
Mikael Berthe <mikael@lilotux.net>
parents:
862
diff
changeset
|
1086 mbuf = g_strdup_printf("Unexpected groupchat packet!"); |
a7b3409df6bc
MUC: Work around user server restart
Mikael Berthe <mikael@lilotux.net>
parents:
862
diff
changeset
|
1087 scr_LogPrint(LPRINT_LOGNORM, "%s", mbuf); |
1290
e42f48103609
Drawing the MUC nicks by a different color
Michal 'vorner' Vaner <vorner@ucw.cz>
parents:
1282
diff
changeset
|
1088 scr_WriteIncomingMessage(bjid, mbuf, 0, HBB_PREFIX_INFO, 0); |
864
a7b3409df6bc
MUC: Work around user server restart
Mikael Berthe <mikael@lilotux.net>
parents:
862
diff
changeset
|
1089 g_free(mbuf); |
a7b3409df6bc
MUC: Work around user server restart
Mikael Berthe <mikael@lilotux.net>
parents:
862
diff
changeset
|
1090 |
a7b3409df6bc
MUC: Work around user server restart
Mikael Berthe <mikael@lilotux.net>
parents:
862
diff
changeset
|
1091 // Send back an unavailable packet |
1598 | 1092 xmpp_setstatus(offline, bjid, "", TRUE); |
864
a7b3409df6bc
MUC: Work around user server restart
Mikael Berthe <mikael@lilotux.net>
parents:
862
diff
changeset
|
1093 |
a7b3409df6bc
MUC: Work around user server restart
Mikael Berthe <mikael@lilotux.net>
parents:
862
diff
changeset
|
1094 // MUC |
a7b3409df6bc
MUC: Work around user server restart
Mikael Berthe <mikael@lilotux.net>
parents:
862
diff
changeset
|
1095 // Make sure this is a room (it can be a conversion user->room) |
1058 | 1096 room_elt = roster_find(bjid, jidsearch, 0); |
864
a7b3409df6bc
MUC: Work around user server restart
Mikael Berthe <mikael@lilotux.net>
parents:
862
diff
changeset
|
1097 if (!room_elt) { |
1355 | 1098 room_elt = roster_add_user(bjid, NULL, NULL, ROSTER_TYPE_ROOM, |
1099 sub_none, -1); | |
864
a7b3409df6bc
MUC: Work around user server restart
Mikael Berthe <mikael@lilotux.net>
parents:
862
diff
changeset
|
1100 } else { |
a7b3409df6bc
MUC: Work around user server restart
Mikael Berthe <mikael@lilotux.net>
parents:
862
diff
changeset
|
1101 buddy_settype(room_elt->data, ROSTER_TYPE_ROOM); |
a7b3409df6bc
MUC: Work around user server restart
Mikael Berthe <mikael@lilotux.net>
parents:
862
diff
changeset
|
1102 } |
a7b3409df6bc
MUC: Work around user server restart
Mikael Berthe <mikael@lilotux.net>
parents:
862
diff
changeset
|
1103 |
a7b3409df6bc
MUC: Work around user server restart
Mikael Berthe <mikael@lilotux.net>
parents:
862
diff
changeset
|
1104 buddylist_build(); |
a7b3409df6bc
MUC: Work around user server restart
Mikael Berthe <mikael@lilotux.net>
parents:
862
diff
changeset
|
1105 scr_DrawRoster(); |
1347
07816313073b
Add an option 'otr' to enable OTR support in the configuration file
Mikael Berthe <mikael@lilotux.net>
parents:
1344
diff
changeset
|
1106 goto gotmessage_return; |
864
a7b3409df6bc
MUC: Work around user server restart
Mikael Berthe <mikael@lilotux.net>
parents:
862
diff
changeset
|
1107 } |
a7b3409df6bc
MUC: Work around user server restart
Mikael Berthe <mikael@lilotux.net>
parents:
862
diff
changeset
|
1108 |
819
c2d7d9dd4193
New option 'block_unsubscribed'
Mikael Berthe <mikael@lilotux.net>
parents:
818
diff
changeset
|
1109 // We don't call the message_in hook if 'block_unsubscribed' is true and |
c2d7d9dd4193
New option 'block_unsubscribed'
Mikael Berthe <mikael@lilotux.net>
parents:
818
diff
changeset
|
1110 // this is a regular message from an unsubscribed user. |
956
819396bebdf5
Do not block system messages when block_unsubscribed is set
Mikael Berthe <mikael@lilotux.net>
parents:
940
diff
changeset
|
1111 // System messages (from our server) are allowed. |
1598 | 1112 if ((!settings_opt_get_int("block_unsubscribed") || |
1113 (roster_getsubscription(bjid) & sub_from) || | |
1114 (type == LM_MESSAGE_SUB_TYPE_CHAT)) || | |
1058 | 1115 ((s = settings_opt_get("server")) != NULL && !strcasecmp(bjid, s))) { |
1399
187985455020
Correctly display PGP-encoded messages with a subject
Mikael Berthe <mikael@lilotux.net>
parents:
1397
diff
changeset
|
1116 gchar *fullbody = NULL; |
1484
7b36b91a4388
New UI message flag (O) when OTR is used
Mikael Berthe <mikael@lilotux.net>
parents:
1476
diff
changeset
|
1117 guint encrypted; |
7b36b91a4388
New UI message flag (O) when OTR is used
Mikael Berthe <mikael@lilotux.net>
parents:
1476
diff
changeset
|
1118 |
7b36b91a4388
New UI message flag (O) when OTR is used
Mikael Berthe <mikael@lilotux.net>
parents:
1476
diff
changeset
|
1119 if (decrypted_pgp) |
7b36b91a4388
New UI message flag (O) when OTR is used
Mikael Berthe <mikael@lilotux.net>
parents:
1476
diff
changeset
|
1120 encrypted = ENCRYPTED_PGP; |
7b36b91a4388
New UI message flag (O) when OTR is used
Mikael Berthe <mikael@lilotux.net>
parents:
1476
diff
changeset
|
1121 else if (otr_msg) |
7b36b91a4388
New UI message flag (O) when OTR is used
Mikael Berthe <mikael@lilotux.net>
parents:
1476
diff
changeset
|
1122 encrypted = ENCRYPTED_OTR; |
7b36b91a4388
New UI message flag (O) when OTR is used
Mikael Berthe <mikael@lilotux.net>
parents:
1476
diff
changeset
|
1123 else |
7b36b91a4388
New UI message flag (O) when OTR is used
Mikael Berthe <mikael@lilotux.net>
parents:
1476
diff
changeset
|
1124 encrypted = 0; |
7b36b91a4388
New UI message flag (O) when OTR is used
Mikael Berthe <mikael@lilotux.net>
parents:
1476
diff
changeset
|
1125 |
1399
187985455020
Correctly display PGP-encoded messages with a subject
Mikael Berthe <mikael@lilotux.net>
parents:
1397
diff
changeset
|
1126 if (subject) { |
187985455020
Correctly display PGP-encoded messages with a subject
Mikael Berthe <mikael@lilotux.net>
parents:
1397
diff
changeset
|
1127 if (body) |
187985455020
Correctly display PGP-encoded messages with a subject
Mikael Berthe <mikael@lilotux.net>
parents:
1397
diff
changeset
|
1128 fullbody = g_strdup_printf("[%s]\n%s", subject, body); |
187985455020
Correctly display PGP-encoded messages with a subject
Mikael Berthe <mikael@lilotux.net>
parents:
1397
diff
changeset
|
1129 else |
187985455020
Correctly display PGP-encoded messages with a subject
Mikael Berthe <mikael@lilotux.net>
parents:
1397
diff
changeset
|
1130 fullbody = g_strdup_printf("[%s]\n", subject); |
187985455020
Correctly display PGP-encoded messages with a subject
Mikael Berthe <mikael@lilotux.net>
parents:
1397
diff
changeset
|
1131 body = fullbody; |
187985455020
Correctly display PGP-encoded messages with a subject
Mikael Berthe <mikael@lilotux.net>
parents:
1397
diff
changeset
|
1132 } |
1484
7b36b91a4388
New UI message flag (O) when OTR is used
Mikael Berthe <mikael@lilotux.net>
parents:
1476
diff
changeset
|
1133 hk_message_in(bjid, rname, timestamp, body, type, encrypted); |
1399
187985455020
Correctly display PGP-encoded messages with a subject
Mikael Berthe <mikael@lilotux.net>
parents:
1397
diff
changeset
|
1134 g_free(fullbody); |
819
c2d7d9dd4193
New option 'block_unsubscribed'
Mikael Berthe <mikael@lilotux.net>
parents:
818
diff
changeset
|
1135 } else { |
1058 | 1136 scr_LogPrint(LPRINT_LOGNORM, "Blocked a message from <%s>", bjid); |
819
c2d7d9dd4193
New option 'block_unsubscribed'
Mikael Berthe <mikael@lilotux.net>
parents:
818
diff
changeset
|
1137 } |
1347
07816313073b
Add an option 'otr' to enable OTR support in the configuration file
Mikael Berthe <mikael@lilotux.net>
parents:
1344
diff
changeset
|
1138 |
07816313073b
Add an option 'otr' to enable OTR support in the configuration file
Mikael Berthe <mikael@lilotux.net>
parents:
1344
diff
changeset
|
1139 gotmessage_return: |
07816313073b
Add an option 'otr' to enable OTR support in the configuration file
Mikael Berthe <mikael@lilotux.net>
parents:
1344
diff
changeset
|
1140 // Clean up and exit |
1058 | 1141 g_free(bjid); |
1347
07816313073b
Add an option 'otr' to enable OTR support in the configuration file
Mikael Berthe <mikael@lilotux.net>
parents:
1344
diff
changeset
|
1142 g_free(decrypted_pgp); |
1333
e30a9d907105
Minor coding style adjustments
Mikael Berthe <mikael@lilotux.net>
parents:
1330
diff
changeset
|
1143 if (free_msg) |
1347
07816313073b
Add an option 'otr' to enable OTR support in the configuration file
Mikael Berthe <mikael@lilotux.net>
parents:
1344
diff
changeset
|
1144 g_free(decrypted_otr); |
29 | 1145 } |
1146 | |
420
04a0b450380b
Display error code/message when receiving a message packet with "error" type
Mikael Berthe <mikael@lilotux.net>
parents:
419
diff
changeset
|
1147 |
1598 | 1148 static LmHandlerResult handle_messages(LmMessageHandler *handler, |
1149 LmConnection *connection, | |
1150 LmMessage *m, gpointer user_data) | |
579
0c67755e0fa7
Introduce a handle_presence_muc() function
Mikael Berthe <mikael@lilotux.net>
parents:
578
diff
changeset
|
1151 { |
1598 | 1152 const char *p, *from=lm_message_get_from(m); |
1153 char *r, *s; | |
1154 LmMessageNode *x; | |
1155 const char *body = NULL; | |
1156 const char *enc = NULL; | |
1157 const char *subject = NULL; | |
1001
dff25377c11f
Auto-reconnect after a network/server failure
Mikael Berthe <mikael@lilotux.net>
parents:
999
diff
changeset
|
1158 time_t timestamp = 0L; |
547
1df26ff0ed8c
Break packethandler() out
Mikael Berthe <mikael@lilotux.net>
parents:
539
diff
changeset
|
1159 |
1598 | 1160 body = lm_message_node_get_child_value(m->node, "body"); |
547
1df26ff0ed8c
Break packethandler() out
Mikael Berthe <mikael@lilotux.net>
parents:
539
diff
changeset
|
1161 |
1598 | 1162 x = lm_message_node_find_xmlns(m->node, NS_ENCRYPTED); |
1163 if (x && (p = lm_message_node_get_value(x)) != NULL) | |
1399
187985455020
Correctly display PGP-encoded messages with a subject
Mikael Berthe <mikael@lilotux.net>
parents:
1397
diff
changeset
|
1164 enc = p; |
187985455020
Correctly display PGP-encoded messages with a subject
Mikael Berthe <mikael@lilotux.net>
parents:
1397
diff
changeset
|
1165 |
1598 | 1166 p = lm_message_node_get_child_value(m->node, "subject"); |
1167 if (p != NULL) { | |
1168 if (lm_message_get_sub_type(m) != LM_MESSAGE_SUB_TYPE_GROUPCHAT) { | |
1169 // Chat message | |
1399
187985455020
Correctly display PGP-encoded messages with a subject
Mikael Berthe <mikael@lilotux.net>
parents:
1397
diff
changeset
|
1170 subject = p; |
187985455020
Correctly display PGP-encoded messages with a subject
Mikael Berthe <mikael@lilotux.net>
parents:
1397
diff
changeset
|
1171 } else { // Room topic |
549
448e299e45da
MUC: "/room topic" shows the current room topic
Mikael Berthe <mikael@lilotux.net>
parents:
547
diff
changeset
|
1172 GSList *roombuddy; |
1598 | 1173 gchar *mbuf; |
1174 const gchar *subj = p; | |
547
1df26ff0ed8c
Break packethandler() out
Mikael Berthe <mikael@lilotux.net>
parents:
539
diff
changeset
|
1175 // Get the room (s) and the nickname (r) |
1598 | 1176 s = g_strdup(lm_message_get_from(m)); |
977
5b01de4ac5e1
Cosmetic changes
Alexis Hildebrandt <afh [at] 2drop [dot] net>
parents:
960
diff
changeset
|
1177 r = strchr(s, JID_RESOURCE_SEPARATOR); |
547
1df26ff0ed8c
Break packethandler() out
Mikael Berthe <mikael@lilotux.net>
parents:
539
diff
changeset
|
1178 if (r) *r++ = 0; |
1df26ff0ed8c
Break packethandler() out
Mikael Berthe <mikael@lilotux.net>
parents:
539
diff
changeset
|
1179 else r = s; |
549
448e299e45da
MUC: "/room topic" shows the current room topic
Mikael Berthe <mikael@lilotux.net>
parents:
547
diff
changeset
|
1180 // Set the new topic |
448e299e45da
MUC: "/room topic" shows the current room topic
Mikael Berthe <mikael@lilotux.net>
parents:
547
diff
changeset
|
1181 roombuddy = roster_find(s, jidsearch, 0); |
448e299e45da
MUC: "/room topic" shows the current room topic
Mikael Berthe <mikael@lilotux.net>
parents:
547
diff
changeset
|
1182 if (roombuddy) |
772
464be13343a9
Store most data in UTF-8 internally
Mikael Berthe <mikael@lilotux.net>
parents:
756
diff
changeset
|
1183 buddy_settopic(roombuddy->data, subj); |
547
1df26ff0ed8c
Break packethandler() out
Mikael Berthe <mikael@lilotux.net>
parents:
539
diff
changeset
|
1184 // Display inside the room window |
560
64cb4de94972
Better topic attribution
Mikael Berthe <mikael@lilotux.net>
parents:
549
diff
changeset
|
1185 if (r == s) { |
64cb4de94972
Better topic attribution
Mikael Berthe <mikael@lilotux.net>
parents:
549
diff
changeset
|
1186 // No specific resource (this is certainly history) |
1598 | 1187 mbuf = g_strdup_printf("The topic has been set to: %s", subj); |
560
64cb4de94972
Better topic attribution
Mikael Berthe <mikael@lilotux.net>
parents:
549
diff
changeset
|
1188 } else { |
1598 | 1189 mbuf = g_strdup_printf("%s has set the topic to: %s", r, subj); |
560
64cb4de94972
Better topic attribution
Mikael Berthe <mikael@lilotux.net>
parents:
549
diff
changeset
|
1190 } |
1598 | 1191 scr_WriteIncomingMessage(s, mbuf, 0, |
1192 HBB_PREFIX_INFO|HBB_PREFIX_NOFLAG, 0); | |
1193 if (settings_opt_get_int("log_muc_conf")) | |
1194 hlog_write_message(s, 0, -1, mbuf); | |
547
1df26ff0ed8c
Break packethandler() out
Mikael Berthe <mikael@lilotux.net>
parents:
539
diff
changeset
|
1195 g_free(s); |
1598 | 1196 g_free(mbuf); |
732
ab623c2df964
MUC: Update the chat status line when the topic is updated
Mikael Berthe <mikael@lilotux.net>
parents:
724
diff
changeset
|
1197 // The topic is displayed in the chat status line, so refresh now. |
ab623c2df964
MUC: Update the chat status line when the topic is updated
Mikael Berthe <mikael@lilotux.net>
parents:
724
diff
changeset
|
1198 scr_UpdateChatStatus(TRUE); |
547
1df26ff0ed8c
Break packethandler() out
Mikael Berthe <mikael@lilotux.net>
parents:
539
diff
changeset
|
1199 } |
1df26ff0ed8c
Break packethandler() out
Mikael Berthe <mikael@lilotux.net>
parents:
539
diff
changeset
|
1200 } |
1df26ff0ed8c
Break packethandler() out
Mikael Berthe <mikael@lilotux.net>
parents:
539
diff
changeset
|
1201 |
1df26ff0ed8c
Break packethandler() out
Mikael Berthe <mikael@lilotux.net>
parents:
539
diff
changeset
|
1202 // Timestamp? |
1598 | 1203 timestamp = lm_message_node_get_timestamp(m->node); |
547
1df26ff0ed8c
Break packethandler() out
Mikael Berthe <mikael@lilotux.net>
parents:
539
diff
changeset
|
1204 |
1598 | 1205 if (lm_message_get_sub_type(m) == LM_MESSAGE_SUB_TYPE_ERROR) { |
1206 x = lm_message_node_get_child(m->node, "error"); | |
1213
4a7db2870685
Improve Private Storage detection.
Mikael Berthe <mikael@lilotux.net>
parents:
1212
diff
changeset
|
1207 display_server_error(x); |
999
9687ecc59303
Redo chat states detection if we receive a message error packet from a contact
Mikael Berthe <mikael@lilotux.net>
parents:
998
diff
changeset
|
1208 #if defined JEP0022 || defined JEP0085 |
9687ecc59303
Redo chat states detection if we receive a message error packet from a contact
Mikael Berthe <mikael@lilotux.net>
parents:
998
diff
changeset
|
1209 // If the JEP85/22 support is probed, set it back to unknown so that |
9687ecc59303
Redo chat states detection if we receive a message error packet from a contact
Mikael Berthe <mikael@lilotux.net>
parents:
998
diff
changeset
|
1210 // we probe it again. |
9687ecc59303
Redo chat states detection if we receive a message error packet from a contact
Mikael Berthe <mikael@lilotux.net>
parents:
998
diff
changeset
|
1211 chatstates_reset_probed(from); |
9687ecc59303
Redo chat states detection if we receive a message error packet from a contact
Mikael Berthe <mikael@lilotux.net>
parents:
998
diff
changeset
|
1212 #endif |
1132
1650056b96fc
Do not use chat states of error messages :)
Mikael Berthe <mikael@lilotux.net>
parents:
1128
diff
changeset
|
1213 } else { |
1598 | 1214 handle_state_events(from, m->node); |
547
1df26ff0ed8c
Break packethandler() out
Mikael Berthe <mikael@lilotux.net>
parents:
539
diff
changeset
|
1215 } |
1399
187985455020
Correctly display PGP-encoded messages with a subject
Mikael Berthe <mikael@lilotux.net>
parents:
1397
diff
changeset
|
1216 if (from && (body || subject)) |
1598 | 1217 gotmessage(lm_message_get_sub_type(m), from, body, enc, subject, timestamp, |
1218 lm_message_node_find_xmlns(m->node, NS_SIGNED)); | |
1602 | 1219 //report received message if message receipt was requested |
1220 if (lm_message_node_get_child(m->node, "request")) { | |
1221 LmMessage *rcvd = lm_message_new(from, LM_MESSAGE_TYPE_MESSAGE); | |
1222 lm_message_node_set_attribute(rcvd->node, "id", lm_message_get_id(m)); | |
1223 lm_message_node_set_attribute | |
1224 (lm_message_node_add_child(rcvd->node, "received", NULL), | |
1225 "xmlns", NS_RECEIPTS); | |
1226 lm_connection_send(connection, rcvd, NULL); | |
1227 lm_message_unref(rcvd); | |
1228 } | |
1128 | 1229 |
1230 if (from) { | |
1598 | 1231 x = lm_message_node_find_xmlns(m->node, |
1232 "http://jabber.org/protocol/muc#user"); | |
1233 if (x && !strcmp(x->name, "x")) | |
1128 | 1234 got_muc_message(from, x); |
1235 } | |
1598 | 1236 |
1237 return LM_HANDLER_RESULT_REMOVE_MESSAGE; | |
547
1df26ff0ed8c
Break packethandler() out
Mikael Berthe <mikael@lilotux.net>
parents:
539
diff
changeset
|
1238 } |
1df26ff0ed8c
Break packethandler() out
Mikael Berthe <mikael@lilotux.net>
parents:
539
diff
changeset
|
1239 |
1600 | 1240 static LmHandlerResult cb_caps(LmMessageHandler *h, LmConnection *c, |
1241 LmMessage *m, gpointer user_data) | |
1242 { | |
1243 char *ver = user_data; | |
1244 | |
1245 if (lm_message_get_sub_type(m) == LM_MESSAGE_SUB_TYPE_ERROR) { | |
1246 display_server_error(lm_message_node_get_child(m->node, "error")); | |
1247 } else if (lm_message_get_sub_type(m) == LM_MESSAGE_SUB_TYPE_RESULT) { | |
1248 LmMessageNode *info; | |
1249 LmMessageNode *query = lm_message_node_get_child(m->node, "query"); | |
1250 | |
1251 caps_add(ver); | |
1252 info = lm_message_node_get_child(query, "identity"); | |
1253 if (info) | |
1254 caps_set_identity(ver, lm_message_node_get_attribute(info, "category"), | |
1255 lm_message_node_get_attribute(info, "name"), | |
1256 lm_message_node_get_attribute(info, "type")); | |
1257 info = lm_message_node_get_child(query, "feature"); | |
1258 while (info) { | |
1259 if (!g_strcmp0(info->name, "feature")) | |
1260 caps_add_feature(ver, lm_message_node_get_attribute(info, "var")); | |
1261 info = info->next; | |
1262 } | |
1263 } | |
1264 g_free(ver); | |
1265 return LM_HANDLER_RESULT_REMOVE_MESSAGE; | |
1266 } | |
1267 | |
1598 | 1268 static LmHandlerResult handle_presence(LmMessageHandler *handler, |
1269 LmConnection *connection, | |
1270 LmMessage *m, gpointer user_data) | |
986
ed697234bd39
Chat states receival (Alexis Hildebrandt)
Mikael Berthe <mikael@lilotux.net>
parents:
977
diff
changeset
|
1271 { |
1598 | 1272 char *r; |
1273 const char *from, *rname, *p=NULL, *ustmsg=NULL; | |
1274 enum imstatus ust; | |
1275 char bpprio; | |
1276 time_t timestamp = 0L; | |
1600 | 1277 LmMessageNode *muc_packet, *caps; |
1598 | 1278 |
1279 //Check for MUC presence packet | |
1280 muc_packet = lm_message_node_find_xmlns | |
1281 (m->node, "http://jabber.org/protocol/muc#user"); | |
1282 | |
1283 from = lm_message_get_from(m); | |
987
f47e312560af
Improve JEP22 + JEP85 support
Mikael Berthe <mikael@lilotux.net>
parents:
986
diff
changeset
|
1284 |
f47e312560af
Improve JEP22 + JEP85 support
Mikael Berthe <mikael@lilotux.net>
parents:
986
diff
changeset
|
1285 rname = strchr(from, JID_RESOURCE_SEPARATOR); |
1598 | 1286 if (rname) rname++; |
986
ed697234bd39
Chat states receival (Alexis Hildebrandt)
Mikael Berthe <mikael@lilotux.net>
parents:
977
diff
changeset
|
1287 |
1598 | 1288 if (settings_opt_get_int("ignore_self_presence")) { |
1289 const char *self_fjid = lm_connection_get_jid(connection); | |
1290 if (self_fjid && !strcasecmp(self_fjid, from)) { | |
1291 return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS; // Ignoring self presence | |
987
f47e312560af
Improve JEP22 + JEP85 support
Mikael Berthe <mikael@lilotux.net>
parents:
986
diff
changeset
|
1292 } |
f47e312560af
Improve JEP22 + JEP85 support
Mikael Berthe <mikael@lilotux.net>
parents:
986
diff
changeset
|
1293 } |
f47e312560af
Improve JEP22 + JEP85 support
Mikael Berthe <mikael@lilotux.net>
parents:
986
diff
changeset
|
1294 |
1598 | 1295 r = jidtodisp(from); |
987
f47e312560af
Improve JEP22 + JEP85 support
Mikael Berthe <mikael@lilotux.net>
parents:
986
diff
changeset
|
1296 |
1598 | 1297 if (lm_message_get_sub_type(m) == LM_MESSAGE_SUB_TYPE_ERROR) { |
1298 LmMessageNode *x; | |
1299 scr_LogPrint(LPRINT_LOGNORM, "Error presence packet from <%s>", r); | |
1300 x = lm_message_node_find_child(m->node, "error"); | |
1301 display_server_error(x); | |
1302 // Let's check it isn't a nickname conflict. | |
1303 // XXX Note: We should handle the <conflict/> string condition. | |
1304 if ((p = lm_message_node_get_attribute(x, "code")) != NULL) { | |
1305 if (atoi(p) == 409) { | |
1306 // 409 = conflict (nickname is in use or registered by another user) | |
1307 // If we are not inside this room, we should reset the nickname | |
1308 GSList *room_elt = roster_find(r, jidsearch, 0); | |
1309 if (room_elt && !buddy_getinsideroom(room_elt->data)) | |
1310 buddy_setnickname(room_elt->data, NULL); | |
1311 } | |
987
f47e312560af
Improve JEP22 + JEP85 support
Mikael Berthe <mikael@lilotux.net>
parents:
986
diff
changeset
|
1312 } |
f47e312560af
Improve JEP22 + JEP85 support
Mikael Berthe <mikael@lilotux.net>
parents:
986
diff
changeset
|
1313 |
1598 | 1314 g_free(r); |
1315 return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS; | |
986
ed697234bd39
Chat states receival (Alexis Hildebrandt)
Mikael Berthe <mikael@lilotux.net>
parents:
977
diff
changeset
|
1316 } |
ed697234bd39
Chat states receival (Alexis Hildebrandt)
Mikael Berthe <mikael@lilotux.net>
parents:
977
diff
changeset
|
1317 |
1598 | 1318 p = lm_message_node_get_child_value(m->node, "priority"); |
1319 if (p && *p) bpprio = (gchar)atoi(p); | |
1320 else bpprio = 0; | |
986
ed697234bd39
Chat states receival (Alexis Hildebrandt)
Mikael Berthe <mikael@lilotux.net>
parents:
977
diff
changeset
|
1321 |
1598 | 1322 ust = available; |
749
6c633adaae10
Use events system for subscription requests
Mikael Berthe <mikael@lilotux.net>
parents:
745
diff
changeset
|
1323 |
1598 | 1324 p = lm_message_node_get_child_value(m->node, "show"); |
1325 if (p) { | |
1326 if (!strcmp(p, "away")) ust = away; | |
1327 else if (!strcmp(p, "dnd")) ust = dontdisturb; | |
1328 else if (!strcmp(p, "xa")) ust = notavail; | |
1329 else if (!strcmp(p, "chat")) ust = freeforchat; | |
749
6c633adaae10
Use events system for subscription requests
Mikael Berthe <mikael@lilotux.net>
parents:
745
diff
changeset
|
1330 } |
6c633adaae10
Use events system for subscription requests
Mikael Berthe <mikael@lilotux.net>
parents:
745
diff
changeset
|
1331 |
1598 | 1332 if (lm_message_get_sub_type(m) == LM_MESSAGE_SUB_TYPE_UNAVAILABLE) |
1333 ust = offline; | |
749
6c633adaae10
Use events system for subscription requests
Mikael Berthe <mikael@lilotux.net>
parents:
745
diff
changeset
|
1334 |
1598 | 1335 ustmsg = lm_message_node_get_child_value(m->node, "status"); |
749
6c633adaae10
Use events system for subscription requests
Mikael Berthe <mikael@lilotux.net>
parents:
745
diff
changeset
|
1336 |
1598 | 1337 // Timestamp? |
1338 timestamp = lm_message_node_get_timestamp(m->node); | |
1339 | |
1340 if (muc_packet) { | |
1341 // This is a MUC presence message | |
1342 handle_muc_presence(from, muc_packet, r, rname, | |
1343 ust, ustmsg, timestamp, bpprio); | |
749
6c633adaae10
Use events system for subscription requests
Mikael Berthe <mikael@lilotux.net>
parents:
745
diff
changeset
|
1344 } else { |
1598 | 1345 // Not a MUC message, so this is a regular buddy... |
1346 // Call hk_statuschange() if status has changed or if the | |
1347 // status message is different | |
1348 const char *msg; | |
1349 msg = roster_getstatusmsg(r, rname); | |
1350 if ((ust != roster_getstatus(r, rname)) || | |
1351 (!ustmsg && msg && msg[0]) || (ustmsg && (!msg || strcmp(ustmsg, msg)))) | |
1352 hk_statuschange(r, rname, bpprio, timestamp, ust, ustmsg); | |
1353 // Presence signature processing | |
1354 if (!ustmsg) | |
1355 ustmsg = ""; // Some clients omit the <status/> element :-( | |
1356 check_signature(r, rname, lm_message_node_find_xmlns(m->node, NS_SIGNED), | |
1357 ustmsg); | |
1128 | 1358 } |
1359 | |
1600 | 1360 //XEP-0115 Entity Capabilities |
1361 caps = lm_message_node_find_xmlns(m->node, NS_CAPS); | |
1362 if (caps) { | |
1363 const char *ver = lm_message_node_get_attribute(caps, "ver"); | |
1364 GSList *sl_buddy = NULL; | |
1365 if (rname) | |
1366 sl_buddy = roster_find(r, jidsearch, ROSTER_TYPE_USER); | |
1367 //only cache the caps if the user is on the roster | |
1368 if (sl_buddy && buddy_getonserverflag(sl_buddy->data)) { | |
1369 buddy_resource_setcaps(sl_buddy->data, rname, ver); | |
1370 | |
1371 if (!caps_has_hash(ver)) { | |
1372 char *node; | |
1373 LmMessageHandler *handler; | |
1374 LmMessage *iq = lm_message_new_with_sub_type(from, LM_MESSAGE_TYPE_IQ, | |
1375 LM_MESSAGE_SUB_TYPE_GET); | |
1376 node = g_strdup_printf("%s#%s", | |
1377 lm_message_node_get_attribute(caps, "node"), | |
1378 ver); | |
1379 lm_message_node_set_attributes | |
1380 (lm_message_node_add_child(iq->node, "query", NULL), | |
1381 "xmlns", NS_DISCO_INFO, | |
1382 "node", node, | |
1383 NULL); | |
1384 g_free(node); | |
1385 handler = lm_message_handler_new(cb_caps, g_strdup(ver), NULL); | |
1386 lm_connection_send_with_reply(connection, iq, handler, NULL); | |
1387 lm_message_unref(iq); | |
1388 lm_message_handler_unref(handler); | |
1389 } | |
1390 } | |
1391 } | |
1392 | |
1598 | 1393 g_free(r); |
1394 return LM_HANDLER_RESULT_REMOVE_MESSAGE; | |
1128 | 1395 } |
1396 | |
1397 | |
1598 | 1398 static LmHandlerResult handle_iq(LmMessageHandler *handler, |
1399 LmConnection *connection, | |
1400 LmMessage *m, gpointer user_data) | |
1401 { | |
1402 int i; | |
1403 const char *xmlns = NULL; | |
1404 LmMessageNode *x; | |
1405 | |
1406 for (x = m->node->children; x; x=x->next) { | |
1407 xmlns = lm_message_node_get_attribute(x, "xmlns"); | |
1408 if (xmlns) | |
1409 for (i=0; iq_handlers[i].xmlns; ++i) | |
1410 if (!strcmp(iq_handlers[i].xmlns, xmlns)) | |
1411 return iq_handlers[i].handler(NULL, connection, m, user_data); | |
1412 xmlns = NULL; | |
1128 | 1413 } |
1414 | |
1598 | 1415 if (lm_message_get_sub_type(m) == LM_MESSAGE_SUB_TYPE_ERROR) { |
1416 display_server_error(lm_message_node_get_child(m->node, "error")); | |
1417 return LM_HANDLER_RESULT_REMOVE_MESSAGE; | |
1128 | 1418 } |
1419 | |
1598 | 1420 if ((lm_message_get_sub_type(m) == LM_MESSAGE_SUB_TYPE_SET) || |
1421 (lm_message_get_sub_type(m) == LM_MESSAGE_SUB_TYPE_GET)) | |
1422 send_iq_error(connection, m, XMPP_ERROR_NOT_IMPLEMENTED); | |
1423 | |
1424 scr_LogPrint(LPRINT_NORMAL|LPRINT_DEBUG, "Unhandled IQ: %s", | |
1425 lm_message_node_to_string(m->node)); | |
1426 return LM_HANDLER_RESULT_REMOVE_MESSAGE; | |
1128 | 1427 } |
1428 | |
1598 | 1429 static LmHandlerResult handle_s10n(LmMessageHandler *handler, |
1430 LmConnection *connection, | |
1431 LmMessage *m, gpointer user_data) | |
547
1df26ff0ed8c
Break packethandler() out
Mikael Berthe <mikael@lilotux.net>
parents:
539
diff
changeset
|
1432 { |
611
ad737139a144
Improve subscription management
Mikael Berthe <mikael@lilotux.net>
parents:
610
diff
changeset
|
1433 char *r; |
ad737139a144
Improve subscription management
Mikael Berthe <mikael@lilotux.net>
parents:
610
diff
changeset
|
1434 char *buf; |
818
55cd45481a07
Fix a buddylist bug when receiving a subscription request
Mikael Berthe <mikael@lilotux.net>
parents:
793
diff
changeset
|
1435 int newbuddy; |
1598 | 1436 const char *from = lm_message_get_from(m); |
611
ad737139a144
Improve subscription management
Mikael Berthe <mikael@lilotux.net>
parents:
610
diff
changeset
|
1437 |
ad737139a144
Improve subscription management
Mikael Berthe <mikael@lilotux.net>
parents:
610
diff
changeset
|
1438 r = jidtodisp(from); |
547
1df26ff0ed8c
Break packethandler() out
Mikael Berthe <mikael@lilotux.net>
parents:
539
diff
changeset
|
1439 |
818
55cd45481a07
Fix a buddylist bug when receiving a subscription request
Mikael Berthe <mikael@lilotux.net>
parents:
793
diff
changeset
|
1440 newbuddy = !roster_find(r, jidsearch, 0); |
55cd45481a07
Fix a buddylist bug when receiving a subscription request
Mikael Berthe <mikael@lilotux.net>
parents:
793
diff
changeset
|
1441 |
1598 | 1442 if (lm_message_get_sub_type(m) == LM_MESSAGE_SUB_TYPE_SUBSCRIBE) { |
611
ad737139a144
Improve subscription management
Mikael Berthe <mikael@lilotux.net>
parents:
610
diff
changeset
|
1443 /* The sender wishes to subscribe to our presence */ |
1598 | 1444 const char *msg; |
547
1df26ff0ed8c
Break packethandler() out
Mikael Berthe <mikael@lilotux.net>
parents:
539
diff
changeset
|
1445 int isagent; |
749
6c633adaae10
Use events system for subscription requests
Mikael Berthe <mikael@lilotux.net>
parents:
745
diff
changeset
|
1446 eviqs *evn; |
611
ad737139a144
Improve subscription management
Mikael Berthe <mikael@lilotux.net>
parents:
610
diff
changeset
|
1447 |
547
1df26ff0ed8c
Break packethandler() out
Mikael Berthe <mikael@lilotux.net>
parents:
539
diff
changeset
|
1448 isagent = (roster_gettype(r) & ROSTER_TYPE_AGENT) != 0; |
1598 | 1449 msg = lm_message_node_get_child_value(m->node, "status"); |
611
ad737139a144
Improve subscription management
Mikael Berthe <mikael@lilotux.net>
parents:
610
diff
changeset
|
1450 |
617
d3a8b43bf9e7
Add "/authorization" command
Mikael Berthe <mikael@lilotux.net>
parents:
616
diff
changeset
|
1451 buf = g_strdup_printf("<%s> wants to subscribe to your presence updates", |
d3a8b43bf9e7
Add "/authorization" command
Mikael Berthe <mikael@lilotux.net>
parents:
616
diff
changeset
|
1452 from); |
1290
e42f48103609
Drawing the MUC nicks by a different color
Michal 'vorner' Vaner <vorner@ucw.cz>
parents:
1282
diff
changeset
|
1453 scr_WriteIncomingMessage(r, buf, 0, HBB_PREFIX_INFO, 0); |
617
d3a8b43bf9e7
Add "/authorization" command
Mikael Berthe <mikael@lilotux.net>
parents:
616
diff
changeset
|
1454 scr_LogPrint(LPRINT_LOGNORM, "%s", buf); |
d3a8b43bf9e7
Add "/authorization" command
Mikael Berthe <mikael@lilotux.net>
parents:
616
diff
changeset
|
1455 g_free(buf); |
d3a8b43bf9e7
Add "/authorization" command
Mikael Berthe <mikael@lilotux.net>
parents:
616
diff
changeset
|
1456 |
611
ad737139a144
Improve subscription management
Mikael Berthe <mikael@lilotux.net>
parents:
610
diff
changeset
|
1457 if (msg) { |
772
464be13343a9
Store most data in UTF-8 internally
Mikael Berthe <mikael@lilotux.net>
parents:
756
diff
changeset
|
1458 buf = g_strdup_printf("<%s> said: %s", from, msg); |
1290
e42f48103609
Drawing the MUC nicks by a different color
Michal 'vorner' Vaner <vorner@ucw.cz>
parents:
1282
diff
changeset
|
1459 scr_WriteIncomingMessage(r, buf, 0, HBB_PREFIX_INFO, 0); |
772
464be13343a9
Store most data in UTF-8 internally
Mikael Berthe <mikael@lilotux.net>
parents:
756
diff
changeset
|
1460 replace_nl_with_dots(buf); |
464be13343a9
Store most data in UTF-8 internally
Mikael Berthe <mikael@lilotux.net>
parents:
756
diff
changeset
|
1461 scr_LogPrint(LPRINT_LOGNORM, "%s", buf); |
464be13343a9
Store most data in UTF-8 internally
Mikael Berthe <mikael@lilotux.net>
parents:
756
diff
changeset
|
1462 g_free(buf); |
547
1df26ff0ed8c
Break packethandler() out
Mikael Berthe <mikael@lilotux.net>
parents:
539
diff
changeset
|
1463 } |
611
ad737139a144
Improve subscription management
Mikael Berthe <mikael@lilotux.net>
parents:
610
diff
changeset
|
1464 |
749
6c633adaae10
Use events system for subscription requests
Mikael Berthe <mikael@lilotux.net>
parents:
745
diff
changeset
|
1465 // Create a new event item |
6c633adaae10
Use events system for subscription requests
Mikael Berthe <mikael@lilotux.net>
parents:
745
diff
changeset
|
1466 evn = evs_new(EVS_TYPE_SUBSCRIPTION, EVS_MAX_TIMEOUT); |
751
4a7271e69694
Avoid reusing events ids
Mikael Berthe <mikael@lilotux.net>
parents:
749
diff
changeset
|
1467 if (evn) { |
752 | 1468 evn->callback = &evscallback_subscription; |
751
4a7271e69694
Avoid reusing events ids
Mikael Berthe <mikael@lilotux.net>
parents:
749
diff
changeset
|
1469 evn->data = g_strdup(r); |
754
5b962b978573
Add event description when receiving a subscription request
Mikael Berthe <mikael@lilotux.net>
parents:
752
diff
changeset
|
1470 evn->desc = g_strdup_printf("<%s> wants to subscribe to your " |
5b962b978573
Add event description when receiving a subscription request
Mikael Berthe <mikael@lilotux.net>
parents:
752
diff
changeset
|
1471 "presence updates", r); |
751
4a7271e69694
Avoid reusing events ids
Mikael Berthe <mikael@lilotux.net>
parents:
749
diff
changeset
|
1472 buf = g_strdup_printf("Please use /event %s accept|reject", evn->id); |
4a7271e69694
Avoid reusing events ids
Mikael Berthe <mikael@lilotux.net>
parents:
749
diff
changeset
|
1473 } else { |
4a7271e69694
Avoid reusing events ids
Mikael Berthe <mikael@lilotux.net>
parents:
749
diff
changeset
|
1474 buf = g_strdup_printf("Unable to create a new event!"); |
4a7271e69694
Avoid reusing events ids
Mikael Berthe <mikael@lilotux.net>
parents:
749
diff
changeset
|
1475 } |
1290
e42f48103609
Drawing the MUC nicks by a different color
Michal 'vorner' Vaner <vorner@ucw.cz>
parents:
1282
diff
changeset
|
1476 scr_WriteIncomingMessage(r, buf, 0, HBB_PREFIX_INFO, 0); |
617
d3a8b43bf9e7
Add "/authorization" command
Mikael Berthe <mikael@lilotux.net>
parents:
616
diff
changeset
|
1477 scr_LogPrint(LPRINT_LOGNORM, "%s", buf); |
611
ad737139a144
Improve subscription management
Mikael Berthe <mikael@lilotux.net>
parents:
610
diff
changeset
|
1478 g_free(buf); |
1598 | 1479 } else if (lm_message_get_sub_type(m) == LM_MESSAGE_SUB_TYPE_UNSUBSCRIBE) { |
611
ad737139a144
Improve subscription management
Mikael Berthe <mikael@lilotux.net>
parents:
610
diff
changeset
|
1480 /* The sender is unsubscribing from our presence */ |
1598 | 1481 xmpp_send_s10n(from, LM_MESSAGE_SUB_TYPE_UNSUBSCRIBED); |
611
ad737139a144
Improve subscription management
Mikael Berthe <mikael@lilotux.net>
parents:
610
diff
changeset
|
1482 buf = g_strdup_printf("<%s> is unsubscribing from your " |
ad737139a144
Improve subscription management
Mikael Berthe <mikael@lilotux.net>
parents:
610
diff
changeset
|
1483 "presence updates", from); |
1290
e42f48103609
Drawing the MUC nicks by a different color
Michal 'vorner' Vaner <vorner@ucw.cz>
parents:
1282
diff
changeset
|
1484 scr_WriteIncomingMessage(r, buf, 0, HBB_PREFIX_INFO, 0); |
611
ad737139a144
Improve subscription management
Mikael Berthe <mikael@lilotux.net>
parents:
610
diff
changeset
|
1485 scr_LogPrint(LPRINT_LOGNORM, "%s", buf); |
ad737139a144
Improve subscription management
Mikael Berthe <mikael@lilotux.net>
parents:
610
diff
changeset
|
1486 g_free(buf); |
1598 | 1487 } else if (lm_message_get_sub_type(m) == LM_MESSAGE_SUB_TYPE_SUBSCRIBED) { |
611
ad737139a144
Improve subscription management
Mikael Berthe <mikael@lilotux.net>
parents:
610
diff
changeset
|
1488 /* The sender has allowed us to receive their presence */ |
ad737139a144
Improve subscription management
Mikael Berthe <mikael@lilotux.net>
parents:
610
diff
changeset
|
1489 buf = g_strdup_printf("<%s> has allowed you to receive their " |
ad737139a144
Improve subscription management
Mikael Berthe <mikael@lilotux.net>
parents:
610
diff
changeset
|
1490 "presence updates", from); |
1290
e42f48103609
Drawing the MUC nicks by a different color
Michal 'vorner' Vaner <vorner@ucw.cz>
parents:
1282
diff
changeset
|
1491 scr_WriteIncomingMessage(r, buf, 0, HBB_PREFIX_INFO, 0); |
611
ad737139a144
Improve subscription management
Mikael Berthe <mikael@lilotux.net>
parents:
610
diff
changeset
|
1492 scr_LogPrint(LPRINT_LOGNORM, "%s", buf); |
ad737139a144
Improve subscription management
Mikael Berthe <mikael@lilotux.net>
parents:
610
diff
changeset
|
1493 g_free(buf); |
1598 | 1494 } else if (lm_message_get_sub_type(m) == LM_MESSAGE_SUB_TYPE_UNSUBSCRIBED) { |
611
ad737139a144
Improve subscription management
Mikael Berthe <mikael@lilotux.net>
parents:
610
diff
changeset
|
1495 /* The subscription request has been denied or a previously-granted |
ad737139a144
Improve subscription management
Mikael Berthe <mikael@lilotux.net>
parents:
610
diff
changeset
|
1496 subscription has been cancelled */ |
610
0e8247cf2bd1
Consider buddies as offline when they have cancelled our subscription
Mikael Berthe <mikael@lilotux.net>
parents:
609
diff
changeset
|
1497 roster_unsubscribed(from); |
859
cb2a3a1d985f
Make sure we update the roster when a subscription is cancelled
Mikael Berthe <mikael@lilotux.net>
parents:
845
diff
changeset
|
1498 update_roster = TRUE; |
611
ad737139a144
Improve subscription management
Mikael Berthe <mikael@lilotux.net>
parents:
610
diff
changeset
|
1499 buf = g_strdup_printf("<%s> has cancelled your subscription to " |
ad737139a144
Improve subscription management
Mikael Berthe <mikael@lilotux.net>
parents:
610
diff
changeset
|
1500 "their presence updates", from); |
1290
e42f48103609
Drawing the MUC nicks by a different color
Michal 'vorner' Vaner <vorner@ucw.cz>
parents:
1282
diff
changeset
|
1501 scr_WriteIncomingMessage(r, buf, 0, HBB_PREFIX_INFO, 0); |
611
ad737139a144
Improve subscription management
Mikael Berthe <mikael@lilotux.net>
parents:
610
diff
changeset
|
1502 scr_LogPrint(LPRINT_LOGNORM, "%s", buf); |
ad737139a144
Improve subscription management
Mikael Berthe <mikael@lilotux.net>
parents:
610
diff
changeset
|
1503 g_free(buf); |
603 | 1504 } else { |
1598 | 1505 return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS; |
818
55cd45481a07
Fix a buddylist bug when receiving a subscription request
Mikael Berthe <mikael@lilotux.net>
parents:
793
diff
changeset
|
1506 } |
55cd45481a07
Fix a buddylist bug when receiving a subscription request
Mikael Berthe <mikael@lilotux.net>
parents:
793
diff
changeset
|
1507 |
1010
54405d09b15a
Add a call to buddylist_build()
Mikael Berthe <mikael@lilotux.net>
parents:
1008
diff
changeset
|
1508 if (newbuddy) |
818
55cd45481a07
Fix a buddylist bug when receiving a subscription request
Mikael Berthe <mikael@lilotux.net>
parents:
793
diff
changeset
|
1509 update_roster = TRUE; |
611
ad737139a144
Improve subscription management
Mikael Berthe <mikael@lilotux.net>
parents:
610
diff
changeset
|
1510 g_free(r); |
1598 | 1511 return LM_HANDLER_RESULT_REMOVE_MESSAGE; |
1512 } | |
1513 | |
1514 //TODO: Use the enum of loudmouth, when it's included in the header... | |
1515 typedef enum { | |
1516 LM_LOG_LEVEL_VERBOSE = 1 << (G_LOG_LEVEL_USER_SHIFT), | |
1517 LM_LOG_LEVEL_NET = 1 << (G_LOG_LEVEL_USER_SHIFT + 1), | |
1518 LM_LOG_LEVEL_PARSER = 1 << (G_LOG_LEVEL_USER_SHIFT + 2), | |
1519 LM_LOG_LEVEL_SSL = 1 << (G_LOG_LEVEL_USER_SHIFT + 3), | |
1520 LM_LOG_LEVEL_SASL = 1 << (G_LOG_LEVEL_USER_SHIFT + 4), | |
1521 LM_LOG_LEVEL_ALL = (LM_LOG_LEVEL_NET | | |
1522 LM_LOG_LEVEL_VERBOSE | | |
1523 LM_LOG_LEVEL_PARSER | | |
1524 LM_LOG_LEVEL_SSL | | |
1525 LM_LOG_LEVEL_SASL) | |
1526 } LmLogLevelFlags; | |
1527 | |
1528 static void lm_debug_handler (const gchar *log_domain, | |
1529 GLogLevelFlags log_level, | |
1530 const gchar *message, | |
1531 gpointer user_data) | |
1532 { | |
1533 if (settings_opt_get_int("tracelog_level") != 2) | |
1534 return; | |
1535 if (message) { | |
1536 char *msg; | |
1537 if (message[0] == '\n') | |
1538 msg = g_strdup(&message[1]); | |
1539 else | |
1540 msg = g_strdup(message); | |
1541 if (msg[strlen(msg)-1] == '\n') msg[strlen(msg)-1] = '\0'; | |
1542 | |
1543 if (log_level & LM_LOG_LEVEL_VERBOSE) { | |
1544 scr_LogPrint(LPRINT_DEBUG, "LM-VERBOSE: %s", msg); | |
1545 } | |
1546 if ((LmLogLevelFlags)log_level & LM_LOG_LEVEL_NET) { | |
1547 scr_LogPrint(LPRINT_DEBUG, "LM-NET: %s", msg); | |
1548 } | |
1549 else if (log_level & LM_LOG_LEVEL_PARSER) { | |
1550 scr_LogPrint(LPRINT_DEBUG, "LM-PARSER: %s", msg); | |
1551 } | |
1552 else if (log_level & LM_LOG_LEVEL_SASL) { | |
1553 scr_LogPrint(LPRINT_DEBUG, "LM-SASL: %s", msg); | |
1554 } | |
1555 else if (log_level & LM_LOG_LEVEL_SSL) { | |
1556 scr_LogPrint(LPRINT_DEBUG, "LM-SSL: %s", msg); | |
1557 } | |
1558 g_free(msg); | |
1559 } | |
547
1df26ff0ed8c
Break packethandler() out
Mikael Berthe <mikael@lilotux.net>
parents:
539
diff
changeset
|
1560 } |
1df26ff0ed8c
Break packethandler() out
Mikael Berthe <mikael@lilotux.net>
parents:
539
diff
changeset
|
1561 |
1598 | 1562 |
1563 void xmpp_connect(void) | |
31 | 1564 { |
1610
6db9f403f707
Replace 'username' with 'jid' in the configuration file
Mikael Berthe <mikael@lilotux.net>
parents:
1604
diff
changeset
|
1565 const char *userjid, *password, *resource, *servername, *ssl_fpr; |
1598 | 1566 char *dynresource = NULL; |
1567 char fpr[16]; | |
1568 const char *proxy_host; | |
1569 const char *resource_prefix = PACKAGE_NAME; | |
1570 char *fjid; | |
1571 int ssl, tls; | |
1572 LmSSL *lssl; | |
1573 unsigned int port; | |
1574 unsigned int ping; | |
1575 LmMessageHandler *handler; | |
1576 GError *error = NULL; | |
1577 | |
1578 if (lconnection && lm_connection_is_open(lconnection)) | |
1579 xmpp_disconnect(); | |
1580 | |
1581 servername = settings_opt_get("server"); | |
1610
6db9f403f707
Replace 'username' with 'jid' in the configuration file
Mikael Berthe <mikael@lilotux.net>
parents:
1604
diff
changeset
|
1582 userjid = settings_opt_get("jid"); |
1598 | 1583 password = settings_opt_get("password"); |
1584 resource = settings_opt_get("resource"); | |
1585 proxy_host = settings_opt_get("proxy_host"); | |
1586 ssl_fpr = settings_opt_get("ssl_fingerprint"); | |
1587 | |
1610
6db9f403f707
Replace 'username' with 'jid' in the configuration file
Mikael Berthe <mikael@lilotux.net>
parents:
1604
diff
changeset
|
1588 if (!userjid) { |
6db9f403f707
Replace 'username' with 'jid' in the configuration file
Mikael Berthe <mikael@lilotux.net>
parents:
1604
diff
changeset
|
1589 scr_LogPrint(LPRINT_LOGNORM, "Your JID has not been specified!"); |
1598 | 1590 return; |
1591 } | |
1592 if (!password) { | |
1610
6db9f403f707
Replace 'username' with 'jid' in the configuration file
Mikael Berthe <mikael@lilotux.net>
parents:
1604
diff
changeset
|
1593 scr_LogPrint(LPRINT_LOGNORM, "Your password has not been specified!"); |
1598 | 1594 return; |
1595 } | |
1596 | |
1597 lconnection = lm_connection_new_with_context | |
1598 (NULL, g_main_loop_get_context(main_loop)); | |
1599 | |
1600 g_log_set_handler("LM", LM_LOG_LEVEL_ALL, lm_debug_handler, NULL); | |
1601 | |
1602 ping = 40; | |
1603 if (settings_opt_get("pinginterval")) | |
1604 ping = (unsigned int) settings_opt_get_int("pinginterval"); | |
1605 lm_connection_set_keep_alive_rate(lconnection, ping); | |
1606 scr_LogPrint(LPRINT_DEBUG, "Ping interval established: %d secs", ping); | |
1607 | |
1608 lm_connection_set_disconnect_function(lconnection, connection_close_cb, | |
1609 NULL, NULL); | |
1610 | |
1611 handler = lm_message_handler_new(handle_messages, NULL, NULL); | |
1612 lm_connection_register_message_handler(lconnection, handler, | |
1613 LM_MESSAGE_TYPE_MESSAGE, | |
1614 LM_HANDLER_PRIORITY_NORMAL); | |
1615 lm_message_handler_unref(handler); | |
1616 | |
1617 handler = lm_message_handler_new(handle_iq, NULL, NULL); | |
1618 lm_connection_register_message_handler(lconnection, handler, | |
1619 LM_MESSAGE_TYPE_IQ, | |
1620 LM_HANDLER_PRIORITY_NORMAL); | |
1621 lm_message_handler_unref(handler); | |
1622 | |
1623 handler = lm_message_handler_new(handle_presence, NULL, NULL); | |
1624 lm_connection_register_message_handler(lconnection, handler, | |
1625 LM_MESSAGE_TYPE_PRESENCE, | |
1626 LM_HANDLER_PRIORITY_LAST); | |
1627 lm_message_handler_unref(handler); | |
1628 | |
1629 handler = lm_message_handler_new(handle_s10n, NULL, NULL); | |
1630 lm_connection_register_message_handler(lconnection, handler, | |
1631 LM_MESSAGE_TYPE_PRESENCE, | |
1632 LM_HANDLER_PRIORITY_NORMAL); | |
1633 lm_message_handler_unref(handler); | |
1634 | |
1635 /* Connect to server */ | |
1636 scr_LogPrint(LPRINT_NORMAL|LPRINT_DEBUG, "Connecting to server: %s", | |
1637 servername); | |
1638 if (!resource) | |
1639 resource = resource_prefix; | |
31 | 1640 |
1598 | 1641 if (!settings_opt_get("disable_random_resource")) { |
1642 #if HAVE_ARC4RANDOM | |
1643 dynresource = g_strdup_printf("%s.%08x", resource, arc4random()); | |
1644 #else | |
1645 unsigned int tab[2]; | |
1646 srand(time(NULL)); | |
1647 tab[0] = (unsigned int) (0xffff * (rand() / (RAND_MAX + 1.0))); | |
1648 tab[1] = (unsigned int) (0xffff * (rand() / (RAND_MAX + 1.0))); | |
1649 dynresource = g_strdup_printf("%s.%04x%04x", resource, tab[0], tab[1]); | |
1650 #endif | |
1651 resource = dynresource; | |
1652 } | |
1653 | |
1654 port = (unsigned int) settings_opt_get_int("port"); | |
1655 | |
1656 if (port) | |
1657 scr_LogPrint(LPRINT_NORMAL|LPRINT_DEBUG, " using port %d", port); | |
1658 scr_LogPrint(LPRINT_NORMAL|LPRINT_DEBUG, " resource %s", resource); | |
1659 | |
1660 if (proxy_host) { | |
1661 int proxy_port = settings_opt_get_int("proxy_port"); | |
1662 if (proxy_port <= 0 || proxy_port > 65535) { | |
1663 scr_LogPrint(LPRINT_NORMAL|LPRINT_DEBUG, "Invalid proxy port: %d", | |
1664 proxy_port); | |
1665 } else { | |
1666 const char *proxy_user, *proxy_pass; | |
1667 LmProxy *lproxy; | |
1668 proxy_user = settings_opt_get("proxy_user"); | |
1669 proxy_pass = settings_opt_get("proxy_pass"); | |
1670 // Proxy initialization | |
1671 lproxy = lm_proxy_new_with_server(LM_PROXY_TYPE_HTTP, | |
1672 proxy_host, proxy_port); | |
1673 lm_proxy_set_username(lproxy, proxy_user); | |
1674 lm_proxy_set_password(lproxy, proxy_pass); | |
1675 lm_connection_set_proxy(lconnection, lproxy); | |
1676 lm_proxy_unref(lproxy); | |
1677 scr_LogPrint(LPRINT_NORMAL|LPRINT_DEBUG, " using proxy %s:%d", | |
1678 proxy_host, proxy_port); | |
1679 } | |
1680 } | |
31 | 1681 |
1610
6db9f403f707
Replace 'username' with 'jid' in the configuration file
Mikael Berthe <mikael@lilotux.net>
parents:
1604
diff
changeset
|
1682 fjid = compose_jid(userjid, servername, resource); |
1598 | 1683 lm_connection_set_jid(lconnection, fjid); |
1610
6db9f403f707
Replace 'username' with 'jid' in the configuration file
Mikael Berthe <mikael@lilotux.net>
parents:
1604
diff
changeset
|
1684 if (servername) |
6db9f403f707
Replace 'username' with 'jid' in the configuration file
Mikael Berthe <mikael@lilotux.net>
parents:
1604
diff
changeset
|
1685 lm_connection_set_server(lconnection, servername); |
1598 | 1686 #if defined(HAVE_LIBOTR) |
1687 otr_init(fjid); | |
1688 #endif | |
1689 g_free(fjid); | |
1690 g_free(dynresource); | |
1691 | |
1692 ssl = settings_opt_get_int("ssl"); | |
1693 tls = settings_opt_get_int("tls"); | |
1694 | |
1695 if (!lm_ssl_is_supported()) { | |
1696 if (ssl || tls) { | |
1697 scr_LogPrint(LPRINT_LOGNORM, "** Error: SSL is NOT available, " | |
1698 "please recompile loudmouth with SSL enabled."); | |
1699 return; | |
1700 } | |
1701 } | |
1702 | |
1703 if (ssl && tls) { | |
1704 scr_LogPrint(LPRINT_LOGNORM, "You can only set ssl or tls, not both."); | |
1705 return; | |
1706 } | |
1707 | |
1708 if (!port) | |
1709 port = (ssl ? LM_CONNECTION_DEFAULT_PORT_SSL : LM_CONNECTION_DEFAULT_PORT); | |
1710 lm_connection_set_port(lconnection, port); | |
1711 scr_LogPrint(LPRINT_LOGNORM, "Port: %i\n", port); | |
1712 | |
1713 if (ssl_fpr && (!hex_to_fingerprint(ssl_fpr, fpr))) { | |
1714 scr_LogPrint(LPRINT_LOGNORM, "** Plese set the fingerprint in the format " | |
1715 "97:5C:00:3F:1D:77:45:25:E2:C5:70:EC:83:C8:87:EE"); | |
1716 return; | |
1717 } | |
1718 | |
1719 lssl = lm_ssl_new((ssl_fpr ? fpr : NULL), ssl_cb, NULL, NULL); | |
1720 if (lssl) { | |
1721 lm_ssl_use_starttls(lssl, !ssl, tls); | |
1722 lm_connection_set_ssl(lconnection, lssl); | |
1723 lm_ssl_unref(lssl); | |
1724 } else if (ssl || tls) { | |
1725 scr_LogPrint(LPRINT_LOGNORM, "** Error: Couldn't create SSL struct."); | |
671
c5da36fd437a
Do not process packet if type = 0
Mikael Berthe <mikael@lilotux.net>
parents:
668
diff
changeset
|
1726 return; |
c5da36fd437a
Do not process packet if type = 0
Mikael Berthe <mikael@lilotux.net>
parents:
668
diff
changeset
|
1727 } |
c5da36fd437a
Do not process packet if type = 0
Mikael Berthe <mikael@lilotux.net>
parents:
668
diff
changeset
|
1728 |
1598 | 1729 if (!lm_connection_open(lconnection, connection_open_cb, |
1730 NULL, FALSE, &error)) { | |
1731 _try_to_reconnect(); | |
1732 scr_LogPrint(LPRINT_LOGNORM, "Failed to open: %s\n", error->message); | |
1733 } | |
1734 } | |
1735 | |
1736 // insert_entity_capabilities(presence_stanza) | |
1737 // Entity Capabilities (XEP-0115) | |
1600 | 1738 static void insert_entity_capabilities(LmMessageNode *x, enum imstatus status) |
1598 | 1739 { |
1740 LmMessageNode *y; | |
1600 | 1741 const char *ver = entity_version(status); |
1598 | 1742 |
1743 y = lm_message_node_add_child(x, "c", NULL); | |
1744 lm_message_node_set_attribute(y, "xmlns", NS_CAPS); | |
1600 | 1745 lm_message_node_set_attribute(y, "hash", "sha-1"); |
1598 | 1746 lm_message_node_set_attribute(y, "node", MCABBER_CAPS_NODE); |
1747 lm_message_node_set_attribute(y, "ver", ver); | |
1748 } | |
1749 | |
1750 void xmpp_disconnect(void) | |
1751 { | |
1752 if (!lconnection || !lm_connection_is_authenticated(lconnection)) | |
1753 return; | |
1754 | |
1755 // Launch pre-disconnect internal hook | |
1756 hook_execute_internal("hook-pre-disconnect"); | |
1757 // Announce it to everyone else | |
1758 xmpp_setstatus(offline, NULL, "", FALSE); | |
1759 lm_connection_close(lconnection, NULL); | |
1760 } | |
1761 | |
1762 void xmpp_setstatus(enum imstatus st, const char *recipient, const char *msg, | |
1763 int do_not_sign) | |
1764 { | |
1765 LmMessage *m; | |
1766 | |
1767 if (msg) { | |
1768 // The status message has been specified. We'll use it, unless it is | |
1769 // "-" which is a special case (option meaning "no status message"). | |
1770 if (!strcmp(msg, "-")) | |
1771 msg = ""; | |
1772 } else { | |
1773 // No status message specified; we'll use: | |
1774 // a) the default status message (if provided by the user); | |
1775 // b) the current status message; | |
1776 // c) no status message (i.e. an empty one). | |
1777 msg = settings_get_status_msg(st); | |
1778 if (!msg) { | |
1779 if (mystatusmsg) | |
1780 msg = mystatusmsg; | |
1781 else | |
1782 msg = ""; | |
1783 } | |
1784 } | |
1785 | |
1786 // Only send the packet if we're online. | |
1787 // (But we want to update internal status even when disconnected, | |
1788 // in order to avoid some problems during network failures) | |
1789 if (lm_connection_is_authenticated(lconnection)) { | |
1790 const char *s_msg = (st != invisible ? msg : NULL); | |
1791 m = lm_message_new_presence(st, recipient, s_msg); | |
1600 | 1792 insert_entity_capabilities(m->node, st); // Entity Capabilities (XEP-0115) |
1598 | 1793 #ifdef HAVE_GPGME |
1794 if (!do_not_sign && gpg_enabled()) { | |
1795 char *signature; | |
1796 signature = gpg_sign(s_msg ? s_msg : ""); | |
1797 if (signature) { | |
1798 LmMessageNode *y; | |
1799 y = lm_message_node_add_child(m->node, "x", signature); | |
1800 lm_message_node_set_attribute(y, "xmlns", NS_SIGNED); | |
1801 g_free(signature); | |
1802 } | |
1803 } | |
1804 #endif | |
1805 lm_connection_send(lconnection, m, NULL); | |
1806 lm_message_unref(m); | |
1807 } | |
1808 | |
1809 // If we didn't change our _global_ status, we are done | |
1810 if (recipient) return; | |
1811 | |
1812 if (lm_connection_is_authenticated(lconnection)) { | |
1813 // Send presence to chatrooms | |
1814 if (st != invisible) { | |
1815 struct T_presence room_presence; | |
1816 room_presence.st = st; | |
1817 room_presence.msg = msg; | |
1818 foreach_buddy(ROSTER_TYPE_ROOM, &roompresence, &room_presence); | |
1819 } | |
1820 | |
1821 // We'll have to update the roster if we switch to/from offline because | |
1822 // we don't know the presences of buddies when offline... | |
1823 if (mystatus == offline || st == offline) | |
1824 update_roster = TRUE; | |
1825 | |
1826 hk_mystatuschange(0, mystatus, st, (st != invisible ? msg : "")); | |
1827 mystatus = st; | |
1828 } | |
1829 | |
1830 if (st) | |
1831 mywantedstatus = st; | |
1832 | |
1833 if (msg != mystatusmsg) { | |
1834 g_free(mystatusmsg); | |
1835 if (*msg) | |
1836 mystatusmsg = g_strdup(msg); | |
1837 else | |
1838 mystatusmsg = NULL; | |
1839 } | |
1840 | |
1841 if (!Autoaway) | |
1842 update_last_use(); | |
1843 | |
1844 // Update status line | |
1845 scr_UpdateMainStatus(TRUE); | |
1846 } | |
1847 | |
547
1df26ff0ed8c
Break packethandler() out
Mikael Berthe <mikael@lilotux.net>
parents:
539
diff
changeset
|
1848 |
1598 | 1849 enum imstatus xmpp_getstatus(void) |
1850 { | |
1851 return mystatus; | |
1852 } | |
1853 | |
1854 const char *xmpp_getstatusmsg(void) | |
1855 { | |
1856 return mystatusmsg; | |
1857 } | |
1858 | |
1859 // xmpp_setprevstatus() | |
1860 // Set previous status. This wrapper function is used after a disconnection. | |
1861 void xmpp_setprevstatus(void) | |
1862 { | |
1863 xmpp_setstatus(mywantedstatus, NULL, mystatusmsg, FALSE); | |
1864 } | |
1865 | |
1866 // send_storage(store) | |
1867 // Send the node "store" to update the server. | |
1868 // Note: the sender should check we're online. | |
1869 void send_storage(LmMessageNode *store) | |
1870 { | |
1871 LmMessage *iq; | |
1872 LmMessageNode *query; | |
1873 | |
1874 if (!rosternotes) return; | |
1875 | |
1876 iq = lm_message_new_with_sub_type(NULL, LM_MESSAGE_TYPE_IQ, | |
1877 LM_MESSAGE_SUB_TYPE_SET); | |
1878 query = lm_message_node_add_child(iq->node, "query", NULL); | |
1879 lm_message_node_set_attribute(query, "xmlns", NS_PRIVATE); | |
1880 lm_message_node_insert_childnode(query, store); | |
1881 | |
1882 lm_connection_send(lconnection, iq, NULL); | |
1883 lm_message_unref(iq); | |
1884 } | |
1885 | |
1886 | |
1887 // xmpp_is_bookmarked(roomjid) | |
1888 // Return TRUE if there's a bookmark for the given jid. | |
1889 guint xmpp_is_bookmarked(const char *bjid) | |
1890 { | |
1891 LmMessageNode *x; | |
1892 | |
1893 if (!bookmarks) | |
1894 return FALSE; | |
1895 | |
1896 // Walk through the storage bookmark tags | |
1897 for (x = bookmarks->children ; x; x = x->next) { | |
1898 // If the node is a conference item, check the jid. | |
1899 if (x->name && !strcmp(x->name, "conference")) { | |
1900 const char *fjid = lm_message_node_get_attribute(x, "jid"); | |
1901 if (fjid && !strcasecmp(bjid, fjid)) | |
1902 return TRUE; | |
1903 } | |
1904 } | |
1905 return FALSE; | |
1906 } | |
1907 | |
1908 // xmpp_get_bookmark_nick(roomjid) | |
1909 // Return the room nickname if it is present in a bookmark. | |
1910 const char *xmpp_get_bookmark_nick(const char *bjid) | |
1911 { | |
1912 LmMessageNode *x; | |
1913 | |
1914 if (!bookmarks || !bjid) | |
1915 return NULL; | |
469
a926523d2392
Use UTF8 to handle resources and room nicknames
Mikael Berthe <mikael@lilotux.net>
parents:
468
diff
changeset
|
1916 |
1598 | 1917 // Walk through the storage bookmark tags |
1918 for (x = bookmarks->children ; x; x = x->next) { | |
1919 // If the node is a conference item, check the jid. | |
1920 if (x->name && !strcmp(x->name, "conference")) { | |
1921 const char *fjid = lm_message_node_get_attribute(x, "jid"); | |
1922 if (fjid && !strcasecmp(bjid, fjid)) | |
1923 return lm_message_node_get_child_value(x, "nick"); | |
1924 } | |
1925 } | |
1926 return NULL; | |
1927 } | |
1928 | |
1929 | |
1930 // xmpp_get_all_storage_bookmarks() | |
1931 // Return a GSList with all storage bookmarks. | |
1932 // The caller should g_free the list (not the MUC jids). | |
1933 GSList *xmpp_get_all_storage_bookmarks(void) | |
1934 { | |
1935 LmMessageNode *x; | |
1936 GSList *sl_bookmarks = NULL; | |
1937 | |
1938 // If we have no bookmarks, probably the server doesn't support them. | |
1939 if (!bookmarks) | |
1940 return NULL; | |
1941 | |
1942 // Walk through the storage bookmark tags | |
1943 for (x = bookmarks->children ; x; x = x->next) { | |
1944 // If the node is a conference item, let's add the note to our list. | |
1945 if (x->name && !strcmp(x->name, "conference")) { | |
1946 struct bookmark *bm_elt; | |
1947 const char *autojoin, *name, *nick; | |
1948 const char *fjid = lm_message_node_get_attribute(x, "jid"); | |
1949 if (!fjid) | |
1950 continue; | |
1951 bm_elt = g_new0(struct bookmark, 1); | |
1952 bm_elt->roomjid = g_strdup(fjid); | |
1953 autojoin = lm_message_node_get_attribute(x, "autojoin"); | |
1954 nick = lm_message_node_get_attribute(x, "nick"); | |
1955 name = lm_message_node_get_attribute(x, "name"); | |
1956 if (autojoin && !strcmp(autojoin, "1")) | |
1957 bm_elt->autojoin = 1; | |
1958 if (nick) | |
1959 bm_elt->nick = g_strdup(nick); | |
1960 if (name) | |
1961 bm_elt->name = g_strdup(name); | |
1962 sl_bookmarks = g_slist_append(sl_bookmarks, bm_elt); | |
1963 } | |
1964 } | |
1965 return sl_bookmarks; | |
1966 } | |
1967 | |
1968 // xmpp_set_storage_bookmark(roomid, name, nick, passwd, autojoin, | |
1969 // printstatus, autowhois) | |
1970 // Update the private storage bookmarks: add a conference room. | |
1971 // If name is nil, we remove the bookmark. | |
1972 void xmpp_set_storage_bookmark(const char *roomid, const char *name, | |
1973 const char *nick, const char *passwd, | |
1974 int autojoin, enum room_printstatus pstatus, | |
1975 enum room_autowhois awhois) | |
1976 { | |
1977 LmMessageNode *x; | |
1978 bool changed = FALSE; | |
1979 | |
1980 if (!roomid) | |
1981 return; | |
1982 | |
1983 // If we have no bookmarks, probably the server doesn't support them. | |
1984 if (!bookmarks) { | |
1985 scr_LogPrint(LPRINT_NORMAL, | |
1986 "Sorry, your server doesn't seem to support private storage."); | |
469
a926523d2392
Use UTF8 to handle resources and room nicknames
Mikael Berthe <mikael@lilotux.net>
parents:
468
diff
changeset
|
1987 return; |
a926523d2392
Use UTF8 to handle resources and room nicknames
Mikael Berthe <mikael@lilotux.net>
parents:
468
diff
changeset
|
1988 } |
31 | 1989 |
1598 | 1990 // Walk through the storage tags |
1991 for (x = bookmarks->children ; x; x = x->next) { | |
1992 // If the current node is a conference item, see if we have to replace it. | |
1993 if (x->name && !strcmp(x->name, "conference")) { | |
1994 const char *fjid = lm_message_node_get_attribute(x, "jid"); | |
1995 if (!fjid) | |
1996 continue; | |
1997 if (!strcmp(fjid, roomid)) { | |
1998 // We've found a bookmark for this room. Let's hide it and we'll | |
1999 // create a new one. | |
2000 lm_message_node_hide(x); | |
2001 changed = TRUE; | |
2002 if (!name) | |
2003 scr_LogPrint(LPRINT_LOGNORM, "Deleting bookmark..."); | |
2004 } | |
2005 } | |
2006 } | |
31 | 2007 |
1598 | 2008 // Let's create a node/bookmark for this roomid, if the name is not NULL. |
2009 if (name) { | |
2010 x = lm_message_node_add_child(bookmarks, "conference", NULL); | |
2011 lm_message_node_set_attributes(x, | |
2012 "jid", roomid, | |
2013 "name", name, | |
2014 "autojoin", autojoin ? "1" : "0", | |
2015 NULL); | |
2016 if (nick) | |
2017 lm_message_node_add_child(x, "nick", nick); | |
2018 if (passwd) | |
2019 lm_message_node_add_child(x, "password", passwd); | |
2020 if (pstatus) | |
2021 lm_message_node_add_child(x, "print_status", strprintstatus[pstatus]); | |
2022 if (awhois) | |
2023 lm_message_node_add_child(x, "autowhois", | |
2024 (awhois == autowhois_on) ? "1" : "0"); | |
2025 changed = TRUE; | |
2026 scr_LogPrint(LPRINT_LOGNORM, "Updating bookmarks..."); | |
2027 } | |
2028 | |
2029 if (!changed) | |
2030 return; | |
31 | 2031 |
1598 | 2032 if (lm_connection_is_authenticated(lconnection)) |
2033 send_storage(bookmarks); | |
2034 else | |
2035 scr_LogPrint(LPRINT_LOGNORM, | |
2036 "Warning: you're not connected to the server."); | |
2037 } | |
2038 | |
2039 static struct annotation *parse_storage_rosternote(LmMessageNode *notenode) | |
2040 { | |
2041 const char *p; | |
2042 struct annotation *note = g_new0(struct annotation, 1); | |
2043 p = lm_message_node_get_attribute(notenode, "cdate"); | |
2044 if (p) | |
2045 note->cdate = from_iso8601(p, 1); | |
2046 p = lm_message_node_get_attribute(notenode, "mdate"); | |
2047 if (p) | |
2048 note->mdate = from_iso8601(p, 1); | |
2049 note->text = g_strdup(lm_message_node_get_value(notenode)); | |
2050 note->jid = g_strdup(lm_message_node_get_attribute(notenode, "jid")); | |
2051 return note; | |
2052 } | |
31 | 2053 |
1598 | 2054 // xmpp_get_all_storage_rosternotes() |
2055 // Return a GSList with all storage annotations. | |
2056 // The caller should g_free the list and its contents. | |
2057 GSList *xmpp_get_all_storage_rosternotes(void) | |
2058 { | |
2059 LmMessageNode *x; | |
2060 GSList *sl_notes = NULL; | |
2061 | |
2062 // If we have no rosternotes, probably the server doesn't support them. | |
2063 if (!rosternotes) | |
2064 return NULL; | |
31 | 2065 |
1598 | 2066 // Walk through the storage rosternotes tags |
2067 for (x = rosternotes->children ; x; x = x->next) { | |
2068 struct annotation *note; | |
2069 | |
2070 // We want a note item | |
2071 if (!x->name || strcmp(x->name, "note")) | |
2072 continue; | |
2073 // Just in case, check the jid... | |
2074 if (!lm_message_node_get_attribute(x, "jid")) | |
2075 continue; | |
2076 // Ok, let's add the note to our list | |
2077 note = parse_storage_rosternote(x); | |
2078 sl_notes = g_slist_append(sl_notes, note); | |
31 | 2079 } |
1598 | 2080 return sl_notes; |
31 | 2081 } |
2082 | |
1598 | 2083 // xmpp_get_storage_rosternotes(barejid, silent) |
2084 // Return the annotation associated with this jid. | |
2085 // If silent is TRUE, no warning is displayed when rosternotes is disabled | |
2086 // The caller should g_free the string and structure after use. | |
2087 struct annotation *xmpp_get_storage_rosternotes(const char *barejid, int silent) | |
2088 { | |
2089 LmMessageNode *x; | |
2090 | |
2091 if (!barejid) | |
2092 return NULL; | |
2093 | |
2094 // If we have no rosternotes, probably the server doesn't support them. | |
2095 if (!rosternotes) { | |
2096 if (!silent) | |
2097 scr_LogPrint(LPRINT_NORMAL, "Sorry, " | |
2098 "your server doesn't seem to support private storage."); | |
2099 return NULL; | |
2100 } | |
2101 | |
2102 // Walk through the storage rosternotes tags | |
2103 for (x = rosternotes->children ; x; x = x->next) { | |
2104 const char *fjid; | |
2105 // We want a note item | |
2106 if (!x->name || strcmp(x->name, "note")) | |
2107 continue; | |
2108 // Just in case, check the jid... | |
2109 fjid = lm_message_node_get_attribute(x, "jid"); | |
2110 if (fjid && !strcmp(fjid, barejid)) // We've found a note for this contact. | |
2111 return parse_storage_rosternote(x); | |
2112 } | |
2113 return NULL; // No note found | |
2114 } | |
2115 | |
2116 // xmpp_set_storage_rosternotes(barejid, note) | |
2117 // Update the private storage rosternotes: add/delete a note. | |
2118 // If note is nil, we remove the existing note. | |
2119 void xmpp_set_storage_rosternotes(const char *barejid, const char *note) | |
2120 { | |
2121 LmMessageNode *x; | |
2122 bool changed = FALSE; | |
2123 const char *cdate = NULL; | |
2124 | |
2125 if (!barejid) | |
2126 return; | |
2127 | |
2128 // If we have no rosternotes, probably the server doesn't support them. | |
2129 if (!rosternotes) { | |
2130 scr_LogPrint(LPRINT_NORMAL, | |
2131 "Sorry, your server doesn't seem to support private storage."); | |
2132 return; | |
2133 } | |
2134 | |
2135 // Walk through the storage tags | |
2136 for (x = rosternotes->children ; x; x = x->next) { | |
2137 // If the current node is a conference item, see if we have to replace it. | |
2138 if (x->name && !strcmp(x->name, "note")) { | |
2139 const char *fjid = lm_message_node_get_attribute(x, "jid"); | |
2140 if (!fjid) | |
2141 continue; | |
2142 if (!strcmp(fjid, barejid)) { | |
2143 // We've found a note for this jid. Let's hide it and we'll | |
2144 // create a new one. | |
2145 cdate = lm_message_node_get_attribute(x, "cdate"); | |
2146 lm_message_node_hide(x); | |
2147 changed = TRUE; | |
2148 break; | |
2149 } | |
2150 } | |
2151 } | |
2152 | |
2153 // Let's create a node for this jid, if the note is not NULL. | |
2154 if (note) { | |
2155 char mdate[20]; | |
2156 time_t now; | |
2157 time(&now); | |
2158 to_iso8601(mdate, now); | |
2159 if (!cdate) | |
2160 cdate = mdate; | |
2161 x = lm_message_node_add_child(rosternotes, "note", note); | |
2162 lm_message_node_set_attributes(x, | |
2163 "jid", barejid, | |
2164 "cdate", cdate, | |
2165 "mdate", mdate, | |
2166 NULL); | |
2167 changed = TRUE; | |
2168 } | |
2169 | |
2170 if (!changed) | |
2171 return; | |
2172 | |
2173 if (lm_connection_is_authenticated(lconnection)) | |
2174 send_storage(rosternotes); | |
2175 else | |
2176 scr_LogPrint(LPRINT_LOGNORM, | |
2177 "Warning: you're not connected to the server."); | |
2178 } | |
1599 | 2179 |
2180 /* vim: set expandtab cindent cinoptions=>2\:2(0: For Vim users... */ |