Tue, 13 Jan 2009 19:23:07 +0000
Change error message shown when trying to buzz a buddy who doesn't announce
support to reflect the fact that disabling "attention" also implies the client
should not advertize support, or as we do in libpurple, don't announce support
when the status is set to "Busy".
| 7014 | 1 | /* |
| 15884 | 2 | * purple - Jabber Protocol Plugin |
| 3127 | 3 | * |
| 7014 | 4 | * Copyright (C) 2003, Nathan Walp <faceprint@faceprint.com> |
| 3127 | 5 | * |
| 7014 | 6 | * This program is free software; you can redistribute it and/or modify |
| 7 | * it under the terms of the GNU General Public License as published by | |
| 8 | * the Free Software Foundation; either version 2 of the License, or | |
| 9 | * (at your option) any later version. | |
| 3127 | 10 | * |
| 7014 | 11 | * This program is distributed in the hope that it will be useful, |
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 14 | * GNU General Public License for more details. | |
| 15 | * | |
| 16 | * You should have received a copy of the GNU General Public License | |
| 17 | * along with this program; if not, write to the Free Software | |
|
19859
71d37b57eff2
The FSF changed its address a while ago; our files were out of date.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
15952
diff
changeset
|
18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA |
| 3127 | 19 | * |
| 7014 | 20 | */ |
| 21 | #include "internal.h" | |
|
15952
c087855dc551
Re-arrange #includes so 'make check' stands a chance of passing during
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
15884
diff
changeset
|
22 | #include "account.h" |
|
25110
40b3fffdb00b
Fix up the XMPP User Avatar SHA1 hashing so that we don't mess up the checksum
Paul Aurich <darkrain42@pidgin.im>
parents:
19859
diff
changeset
|
23 | #include "cipher.h" |
|
15952
c087855dc551
Re-arrange #includes so 'make check' stands a chance of passing during
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
15884
diff
changeset
|
24 | #include "conversation.h" |
|
25110
40b3fffdb00b
Fix up the XMPP User Avatar SHA1 hashing so that we don't mess up the checksum
Paul Aurich <darkrain42@pidgin.im>
parents:
19859
diff
changeset
|
25 | #include "debug.h" |
| 7014 | 26 | #include "server.h" |
| 8043 | 27 | #include "util.h" |
|
15952
c087855dc551
Re-arrange #includes so 'make check' stands a chance of passing during
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
15884
diff
changeset
|
28 | #include "xmlnode.h" |
| 7014 | 29 | |
| 7322 | 30 | #include "chat.h" |
| 7014 | 31 | #include "presence.h" |
| 32 | #include "jutil.h" | |
| 3127 | 33 | |
| 7310 | 34 | gboolean jabber_nodeprep_validate(const char *str) |
| 35 | { | |
| 36 | const char *c; | |
| 37 | ||
| 38 | if(!str) | |
| 39 | return TRUE; | |
| 40 | ||
| 41 | if(strlen(str) > 1023) | |
| 42 | return FALSE; | |
| 43 | ||
| 44 | c = str; | |
| 45 | while(c && *c) { | |
| 46 | gunichar ch = g_utf8_get_char(c); | |
| 47 | if(ch == '\"' || ch == '&' || ch == '\'' || ch == '/' || ch == ':' || | |
| 48 | ch == '<' || ch == '>' || ch == '@' || !g_unichar_isgraph(ch)) { | |
| 49 | return FALSE; | |
| 50 | } | |
| 51 | c = g_utf8_next_char(c); | |
| 52 | } | |
| 53 | ||
| 54 | return TRUE; | |
| 55 | } | |
| 56 | ||
| 57 | gboolean jabber_nameprep_validate(const char *str) | |
| 58 | { | |
| 59 | const char *c; | |
| 60 | ||
| 61 | if(!str) | |
| 62 | return TRUE; | |
| 63 | ||
| 64 | if(strlen(str) > 1023) | |
| 65 | return FALSE; | |
| 66 | ||
| 67 | c = str; | |
| 68 | while(c && *c) { | |
| 69 | gunichar ch = g_utf8_get_char(c); | |
| 70 | if(!g_unichar_isgraph(ch)) | |
| 71 | return FALSE; | |
| 72 | ||
| 73 | c = g_utf8_next_char(c); | |
| 74 | } | |
| 75 | ||
| 76 | ||
| 77 | return TRUE; | |
| 78 | } | |
| 79 | ||
| 80 | gboolean jabber_resourceprep_validate(const char *str) | |
| 81 | { | |
| 82 | const char *c; | |
| 83 | ||
| 84 | if(!str) | |
| 85 | return TRUE; | |
| 86 | ||
| 87 | if(strlen(str) > 1023) | |
| 88 | return FALSE; | |
| 89 | ||
| 90 | c = str; | |
| 91 | while(c && *c) { | |
| 92 | gunichar ch = g_utf8_get_char(c); | |
| 7419 | 93 | if(!g_unichar_isgraph(ch) && ch != ' ') |
| 7310 | 94 | return FALSE; |
| 95 | ||
| 96 | c = g_utf8_next_char(c); | |
| 97 | } | |
| 98 | ||
| 99 | return TRUE; | |
| 100 | } | |
| 101 | ||
| 102 | ||
| 7014 | 103 | JabberID* |
| 104 | jabber_id_new(const char *str) | |
| 2086 | 105 | { |
| 7014 | 106 | char *at; |
| 107 | char *slash; | |
| 108 | JabberID *jid; | |
| 2086 | 109 | |
| 7306 | 110 | if(!str || !g_utf8_validate(str, -1, NULL)) |
| 7014 | 111 | return NULL; |
| 2086 | 112 | |
| 7014 | 113 | jid = g_new0(JabberID, 1); |
| 114 | ||
| 7306 | 115 | at = g_utf8_strchr(str, -1, '@'); |
| 116 | slash = g_utf8_strchr(str, -1, '/'); | |
| 2086 | 117 | |
| 7014 | 118 | if(at) { |
| 7306 | 119 | jid->node = g_utf8_normalize(str, at-str, G_NORMALIZE_NFKC); |
| 7014 | 120 | if(slash) { |
| 7306 | 121 | jid->domain = g_utf8_normalize(at+1, slash-(at+1), G_NORMALIZE_NFKC); |
| 122 | jid->resource = g_utf8_normalize(slash+1, -1, G_NORMALIZE_NFKC); | |
| 7014 | 123 | } else { |
| 7306 | 124 | jid->domain = g_utf8_normalize(at+1, -1, G_NORMALIZE_NFKC); |
| 7014 | 125 | } |
| 126 | } else { | |
| 127 | if(slash) { | |
| 7306 | 128 | jid->domain = g_utf8_normalize(str, slash-str, G_NORMALIZE_NFKC); |
| 129 | jid->resource = g_utf8_normalize(slash+1, -1, G_NORMALIZE_NFKC); | |
| 7014 | 130 | } else { |
| 7306 | 131 | jid->domain = g_utf8_normalize(str, -1, G_NORMALIZE_NFKC); |
| 132 | } | |
| 133 | } | |
| 134 | ||
| 135 | ||
| 7310 | 136 | if(!jabber_nodeprep_validate(jid->node) || |
| 137 | !jabber_nameprep_validate(jid->domain) || | |
| 138 | !jabber_resourceprep_validate(jid->resource)) { | |
| 7306 | 139 | jabber_id_free(jid); |
| 140 | return NULL; | |
| 141 | } | |
| 142 | ||
| 7014 | 143 | return jid; |
| 2086 | 144 | } |
| 145 | ||
| 7014 | 146 | void |
| 147 | jabber_id_free(JabberID *jid) | |
| 2086 | 148 | { |
| 7014 | 149 | if(jid) { |
| 150 | if(jid->node) | |
| 151 | g_free(jid->node); | |
| 152 | if(jid->domain) | |
| 153 | g_free(jid->domain); | |
| 154 | if(jid->resource) | |
| 155 | g_free(jid->resource); | |
| 156 | g_free(jid); | |
| 157 | } | |
| 2086 | 158 | } |
| 159 | ||
| 7014 | 160 | |
| 7306 | 161 | char *jabber_get_resource(const char *in) |
| 7014 | 162 | { |
| 7306 | 163 | JabberID *jid = jabber_id_new(in); |
| 164 | char *out; | |
| 7014 | 165 | |
| 7306 | 166 | if(!jid) |
| 7014 | 167 | return NULL; |
| 7306 | 168 | |
| 169 | out = g_strdup(jid->resource); | |
| 170 | jabber_id_free(jid); | |
| 171 | ||
| 172 | return out; | |
| 7014 | 173 | } |
| 174 | ||
| 7306 | 175 | char *jabber_get_bare_jid(const char *in) |
| 7014 | 176 | { |
| 7306 | 177 | JabberID *jid = jabber_id_new(in); |
| 178 | char *out; | |
| 7014 | 179 | |
| 7306 | 180 | if(!jid) |
| 181 | return NULL; | |
| 182 | ||
| 7322 | 183 | out = g_strdup_printf("%s%s%s", jid->node ? jid->node : "", |
| 184 | jid->node ? "@" : "", jid->domain); | |
| 7306 | 185 | jabber_id_free(jid); |
| 186 | ||
| 187 | return out; | |
| 7014 | 188 | } |
| 7261 | 189 | |
| 15884 | 190 | const char *jabber_normalize(const PurpleAccount *account, const char *in) |
| 7261 | 191 | { |
| 15884 | 192 | PurpleConnection *gc = account ? account->gc : NULL; |
| 7322 | 193 | JabberStream *js = gc ? gc->proto_data : NULL; |
| 194 | static char buf[3072]; /* maximum legal length of a jabber jid */ | |
| 195 | JabberID *jid; | |
| 7445 | 196 | char *node, *domain; |
| 7261 | 197 | |
| 7322 | 198 | jid = jabber_id_new(in); |
| 7310 | 199 | |
| 7322 | 200 | if(!jid) |
| 7310 | 201 | return NULL; |
| 202 | ||
| 7445 | 203 | node = jid->node ? g_utf8_strdown(jid->node, -1) : NULL; |
| 204 | domain = g_utf8_strdown(jid->domain, -1); | |
| 205 | ||
| 206 | ||
| 207 | if(js && node && jid->resource && | |
| 208 | jabber_chat_find(js, node, domain)) | |
| 209 | g_snprintf(buf, sizeof(buf), "%s@%s/%s", node, domain, | |
| 7322 | 210 | jid->resource); |
| 211 | else | |
| 7445 | 212 | g_snprintf(buf, sizeof(buf), "%s%s%s", node ? node : "", |
| 213 | node ? "@" : "", domain); | |
| 7322 | 214 | |
| 7429 | 215 | jabber_id_free(jid); |
| 7445 | 216 | g_free(node); |
| 217 | g_free(domain); | |
| 7429 | 218 | |
| 7261 | 219 | return buf; |
| 220 | } | |
| 7306 | 221 | |
| 15884 | 222 | PurpleConversation * |
| 223 | jabber_find_unnormalized_conv(const char *name, PurpleAccount *account) | |
| 8043 | 224 | { |
| 15884 | 225 | PurpleConversation *c = NULL; |
| 8043 | 226 | GList *cnv; |
| 227 | ||
| 228 | g_return_val_if_fail(name != NULL, NULL); | |
| 229 | ||
| 15884 | 230 | for(cnv = purple_get_conversations(); cnv; cnv = cnv->next) { |
| 231 | c = (PurpleConversation*)cnv->data; | |
| 232 | if(purple_conversation_get_type(c) == PURPLE_CONV_TYPE_IM && | |
| 233 | !purple_utf8_strcasecmp(name, purple_conversation_get_name(c)) && | |
| 234 | account == purple_conversation_get_account(c)) | |
| 8043 | 235 | return c; |
| 236 | } | |
| 237 | ||
| 238 | return NULL; | |
| 239 | } | |
| 8401 | 240 | |
|
25110
40b3fffdb00b
Fix up the XMPP User Avatar SHA1 hashing so that we don't mess up the checksum
Paul Aurich <darkrain42@pidgin.im>
parents:
19859
diff
changeset
|
241 | /* The same as purple_util_get_image_checksum, but guaranteed to remain SHA1 */ |
|
40b3fffdb00b
Fix up the XMPP User Avatar SHA1 hashing so that we don't mess up the checksum
Paul Aurich <darkrain42@pidgin.im>
parents:
19859
diff
changeset
|
242 | char * |
|
40b3fffdb00b
Fix up the XMPP User Avatar SHA1 hashing so that we don't mess up the checksum
Paul Aurich <darkrain42@pidgin.im>
parents:
19859
diff
changeset
|
243 | jabber_calculate_data_sha1sum(gconstpointer data, size_t len) |
|
40b3fffdb00b
Fix up the XMPP User Avatar SHA1 hashing so that we don't mess up the checksum
Paul Aurich <darkrain42@pidgin.im>
parents:
19859
diff
changeset
|
244 | { |
|
40b3fffdb00b
Fix up the XMPP User Avatar SHA1 hashing so that we don't mess up the checksum
Paul Aurich <darkrain42@pidgin.im>
parents:
19859
diff
changeset
|
245 | PurpleCipherContext *context; |
|
40b3fffdb00b
Fix up the XMPP User Avatar SHA1 hashing so that we don't mess up the checksum
Paul Aurich <darkrain42@pidgin.im>
parents:
19859
diff
changeset
|
246 | static gchar digest[41]; |
|
40b3fffdb00b
Fix up the XMPP User Avatar SHA1 hashing so that we don't mess up the checksum
Paul Aurich <darkrain42@pidgin.im>
parents:
19859
diff
changeset
|
247 | |
|
40b3fffdb00b
Fix up the XMPP User Avatar SHA1 hashing so that we don't mess up the checksum
Paul Aurich <darkrain42@pidgin.im>
parents:
19859
diff
changeset
|
248 | context = purple_cipher_context_new_by_name("sha1", NULL); |
|
40b3fffdb00b
Fix up the XMPP User Avatar SHA1 hashing so that we don't mess up the checksum
Paul Aurich <darkrain42@pidgin.im>
parents:
19859
diff
changeset
|
249 | if (context == NULL) |
|
40b3fffdb00b
Fix up the XMPP User Avatar SHA1 hashing so that we don't mess up the checksum
Paul Aurich <darkrain42@pidgin.im>
parents:
19859
diff
changeset
|
250 | { |
|
40b3fffdb00b
Fix up the XMPP User Avatar SHA1 hashing so that we don't mess up the checksum
Paul Aurich <darkrain42@pidgin.im>
parents:
19859
diff
changeset
|
251 | purple_debug_error("jabber", "Could not find sha1 cipher\n"); |
|
40b3fffdb00b
Fix up the XMPP User Avatar SHA1 hashing so that we don't mess up the checksum
Paul Aurich <darkrain42@pidgin.im>
parents:
19859
diff
changeset
|
252 | g_return_val_if_reached(NULL); |
|
40b3fffdb00b
Fix up the XMPP User Avatar SHA1 hashing so that we don't mess up the checksum
Paul Aurich <darkrain42@pidgin.im>
parents:
19859
diff
changeset
|
253 | } |
|
40b3fffdb00b
Fix up the XMPP User Avatar SHA1 hashing so that we don't mess up the checksum
Paul Aurich <darkrain42@pidgin.im>
parents:
19859
diff
changeset
|
254 | |
|
40b3fffdb00b
Fix up the XMPP User Avatar SHA1 hashing so that we don't mess up the checksum
Paul Aurich <darkrain42@pidgin.im>
parents:
19859
diff
changeset
|
255 | /* Hash the data */ |
|
40b3fffdb00b
Fix up the XMPP User Avatar SHA1 hashing so that we don't mess up the checksum
Paul Aurich <darkrain42@pidgin.im>
parents:
19859
diff
changeset
|
256 | purple_cipher_context_append(context, data, len); |
|
40b3fffdb00b
Fix up the XMPP User Avatar SHA1 hashing so that we don't mess up the checksum
Paul Aurich <darkrain42@pidgin.im>
parents:
19859
diff
changeset
|
257 | if (!purple_cipher_context_digest_to_str(context, sizeof(digest), digest, NULL)) |
|
40b3fffdb00b
Fix up the XMPP User Avatar SHA1 hashing so that we don't mess up the checksum
Paul Aurich <darkrain42@pidgin.im>
parents:
19859
diff
changeset
|
258 | { |
|
40b3fffdb00b
Fix up the XMPP User Avatar SHA1 hashing so that we don't mess up the checksum
Paul Aurich <darkrain42@pidgin.im>
parents:
19859
diff
changeset
|
259 | purple_debug_error("jabber", "Failed to get SHA-1 digest.\n"); |
|
40b3fffdb00b
Fix up the XMPP User Avatar SHA1 hashing so that we don't mess up the checksum
Paul Aurich <darkrain42@pidgin.im>
parents:
19859
diff
changeset
|
260 | g_return_val_if_reached(NULL); |
|
40b3fffdb00b
Fix up the XMPP User Avatar SHA1 hashing so that we don't mess up the checksum
Paul Aurich <darkrain42@pidgin.im>
parents:
19859
diff
changeset
|
261 | } |
|
40b3fffdb00b
Fix up the XMPP User Avatar SHA1 hashing so that we don't mess up the checksum
Paul Aurich <darkrain42@pidgin.im>
parents:
19859
diff
changeset
|
262 | purple_cipher_context_destroy(context); |
|
40b3fffdb00b
Fix up the XMPP User Avatar SHA1 hashing so that we don't mess up the checksum
Paul Aurich <darkrain42@pidgin.im>
parents:
19859
diff
changeset
|
263 | |
|
40b3fffdb00b
Fix up the XMPP User Avatar SHA1 hashing so that we don't mess up the checksum
Paul Aurich <darkrain42@pidgin.im>
parents:
19859
diff
changeset
|
264 | return g_strdup(digest); |
|
40b3fffdb00b
Fix up the XMPP User Avatar SHA1 hashing so that we don't mess up the checksum
Paul Aurich <darkrain42@pidgin.im>
parents:
19859
diff
changeset
|
265 | } |
|
40b3fffdb00b
Fix up the XMPP User Avatar SHA1 hashing so that we don't mess up the checksum
Paul Aurich <darkrain42@pidgin.im>
parents:
19859
diff
changeset
|
266 |