Mercurial > pidgin
annotate src/protocols/silc/ops.c @ 13545:cfc2f7fcb3dd
[gaim-migrate @ 15922]
Way more changes that I initially thought I was going to make. I apologize
for the commit message spam. These changes bring a lot of consistency to
our capitalization and punctuation, especially of words like "e-mail".
For reference, I've used these rules (after discussing in #gaim):
e-mail, a case of two words joined:
"e-mail" - in the middle of a sentence caps context
"E-mail" - start of text in a sentence caps context
"E-Mail" - in a header (title) caps context
re-enable, a single word, would be:
"re-enable", "Re-enable", and "Re-enable" (respectively)
The reason this changeset exploded is that, as I went through and verified
these changes, I realized we were using improper capitalization (e.g. header
instead of sentence) in a number of dialogs. I fixed a number of these
cases before, and this corrects another pile.
This looks like I've made a LOT of work for the translators, but the impact
is significantly mitigated by three factors: 1) Many of these changes use
strings that already exist, or change one string in many places. 2) I've
used sed to correct the .po files where possible. 3) The actual changes
are extremely trivial.
committer: Tailor Script <tailor@pidgin.im>
| author | Richard Laager <rlaager@wiktel.com> |
|---|---|
| date | Tue, 21 Mar 2006 04:32:45 +0000 |
| parents | 1118b6fc3206 |
| children |
| rev | line source |
|---|---|
| 8849 | 1 /* |
| 2 | |
| 3 silcgaim_ops.c | |
| 4 | |
| 5 Author: Pekka Riikonen <priikone@silcnet.org> | |
| 6 | |
| 7 Copyright (C) 2004 Pekka Riikonen | |
| 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; version 2 of the License. | |
| 12 | |
| 13 This program is distributed in the hope that it will be useful, | |
| 14 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 16 GNU General Public License for more details. | |
| 17 | |
| 18 */ | |
| 19 | |
| 20 #include "silcincludes.h" | |
| 21 #include "silcclient.h" | |
| 22 #include "silcgaim.h" | |
| 12217 | 23 #include "imgstore.h" |
| 12058 | 24 #include "wb.h" |
| 8849 | 25 |
| 12217 | 26 static void |
| 27 silc_channel_message(SilcClient client, SilcClientConnection conn, | |
| 28 SilcClientEntry sender, SilcChannelEntry channel, | |
| 29 SilcMessagePayload payload, SilcChannelPrivateKey key, | |
| 30 SilcMessageFlags flags, const unsigned char *message, | |
| 31 SilcUInt32 message_len); | |
| 32 static void | |
| 33 silc_private_message(SilcClient client, SilcClientConnection conn, | |
| 34 SilcClientEntry sender, SilcMessagePayload payload, | |
| 35 SilcMessageFlags flags, const unsigned char *message, | |
| 36 SilcUInt32 message_len); | |
| 37 | |
| 8849 | 38 /* Message sent to the application by library. `conn' associates the |
| 39 message to a specific connection. `conn', however, may be NULL. | |
| 40 The `type' indicates the type of the message sent by the library. | |
| 41 The application can for example filter the message according the | |
| 42 type. */ | |
| 43 | |
| 44 static void | |
| 45 silc_say(SilcClient client, SilcClientConnection conn, | |
| 46 SilcClientMessageType type, char *msg, ...) | |
| 47 { | |
| 48 /* Nothing */ | |
| 49 } | |
| 50 | |
| 12217 | 51 #ifdef HAVE_SILCMIME_H |
| 52 /* Processes incoming MIME message. Can be private message or channel | |
| 53 message. */ | |
| 54 | |
| 55 static void | |
| 56 silcgaim_mime_message(SilcClient client, SilcClientConnection conn, | |
| 57 SilcClientEntry sender, SilcChannelEntry channel, | |
| 58 SilcMessagePayload payload, SilcChannelPrivateKey key, | |
| 59 SilcMessageFlags flags, SilcMime mime, | |
| 60 gboolean recursive) | |
| 61 { | |
| 62 GaimConnection *gc = client->application; | |
| 63 SilcGaim sg = gc->proto_data; | |
| 64 const char *type; | |
| 65 const unsigned char *data; | |
| 66 SilcUInt32 data_len; | |
| 67 GaimMessageFlags cflags = 0; | |
| 68 GaimConversation *convo = NULL; | |
| 69 | |
| 70 if (!mime) | |
| 71 return; | |
| 72 | |
| 73 /* Check for fragmented MIME message */ | |
| 74 if (silc_mime_is_partial(mime)) { | |
| 75 if (!sg->mimeass) | |
| 76 sg->mimeass = silc_mime_assembler_alloc(); | |
| 77 | |
| 78 /* Defragment */ | |
| 79 mime = silc_mime_assemble(sg->mimeass, mime); | |
| 80 if (!mime) | |
| 81 /* More fragments to come */ | |
| 82 return; | |
| 83 | |
| 84 /* Process the complete message */ | |
| 85 silcgaim_mime_message(client, conn, sender, channel, | |
| 86 payload, key, flags, mime, FALSE); | |
| 87 return; | |
| 88 } | |
| 89 | |
| 90 /* Check for multipart message */ | |
| 91 if (silc_mime_is_multipart(mime)) { | |
| 92 SilcMime p; | |
| 93 const char *mtype; | |
| 94 SilcDList parts = silc_mime_get_multiparts(mime, &mtype); | |
| 95 | |
| 96 /* Only "mixed" type supported */ | |
| 97 if (strcmp(mtype, "mixed")) | |
| 98 goto out; | |
| 99 | |
| 100 silc_dlist_start(parts); | |
| 101 while ((p = silc_dlist_get(parts)) != SILC_LIST_END) { | |
| 102 /* Recursively process parts */ | |
| 103 silcgaim_mime_message(client, conn, sender, channel, | |
| 104 payload, key, flags, p, TRUE); | |
| 105 } | |
| 106 goto out; | |
| 107 } | |
| 108 | |
| 109 /* Get content type and MIME data */ | |
| 110 type = silc_mime_get_field(mime, "Content-Type"); | |
| 111 if (!type) | |
| 112 goto out; | |
| 113 data = silc_mime_get_data(mime, &data_len); | |
| 114 if (!data) | |
| 115 goto out; | |
| 116 | |
| 117 /* Process according to content type */ | |
| 118 | |
| 119 /* Plain text */ | |
| 120 if (strstr(type, "text/plain")) { | |
| 121 /* Default is UTF-8, don't check for other charsets */ | |
| 122 if (!strstr(type, "utf-8")) | |
| 123 goto out; | |
| 124 | |
| 125 if (channel) | |
| 126 silc_channel_message(client, conn, sender, channel, | |
| 127 payload, key, | |
| 128 SILC_MESSAGE_FLAG_UTF8, data, | |
| 129 data_len); | |
| 130 else | |
| 131 silc_private_message(client, conn, sender, payload, | |
| 132 SILC_MESSAGE_FLAG_UTF8, data, | |
| 133 data_len); | |
| 134 goto out; | |
| 135 } | |
| 136 | |
| 137 /* Image */ | |
| 138 if (strstr(type, "image/png") || | |
| 139 strstr(type, "image/jpeg") || | |
| 140 strstr(type, "image/gif") || | |
| 141 strstr(type, "image/tiff")) { | |
| 142 char tmp[32]; | |
| 143 int imgid; | |
| 144 | |
| 145 /* Get channel convo (if message is for channel) */ | |
| 146 if (key && channel) { | |
| 147 GList *l; | |
| 148 SilcGaimPrvgrp prv; | |
| 149 | |
| 150 for (l = sg->grps; l; l = l->next) | |
| 151 if (((SilcGaimPrvgrp)l->data)->key == key) { | |
| 152 prv = l->data; | |
| 153 convo = gaim_find_conversation_with_account(GAIM_CONV_TYPE_CHAT, | |
| 154 prv->channel, sg->account); | |
| 155 break; | |
| 156 } | |
| 157 } | |
| 158 if (channel && !convo) | |
| 159 convo = gaim_find_conversation_with_account(GAIM_CONV_TYPE_CHAT, | |
| 160 channel->channel_name, sg->account); | |
| 161 if (channel && !convo) | |
| 162 goto out; | |
| 163 | |
| 164 imgid = gaim_imgstore_add(data, data_len, ""); | |
| 165 if (imgid) { | |
| 166 cflags |= GAIM_MESSAGE_IMAGES | GAIM_MESSAGE_RECV; | |
| 167 g_snprintf(tmp, sizeof(tmp), "<IMG ID=\"%d\">", imgid); | |
| 168 | |
| 169 if (channel) | |
| 170 serv_got_chat_in(gc, gaim_conv_chat_get_id(GAIM_CONV_CHAT(convo)), | |
| 171 sender->nickname ? | |
| 172 sender->nickname : | |
| 173 "<unknown>", cflags, | |
| 174 tmp, time(NULL)); | |
| 175 else | |
| 176 serv_got_im(gc, sender->nickname ? | |
| 177 sender->nickname : "<unknown>", | |
| 178 tmp, cflags, time(NULL)); | |
| 179 | |
| 180 gaim_imgstore_unref(imgid); | |
| 181 cflags = 0; | |
| 182 } | |
| 183 goto out; | |
| 184 } | |
| 185 | |
| 186 /* Whiteboard message */ | |
| 187 if (strstr(type, "application/x-wb") && | |
| 188 !gaim_account_get_bool(sg->account, "block-wb", FALSE)) { | |
| 189 if (channel) | |
| 190 silcgaim_wb_receive_ch(client, conn, sender, channel, | |
| 191 payload, flags, data, data_len); | |
| 192 else | |
| 193 silcgaim_wb_receive(client, conn, sender, payload, | |
| 194 flags, data, data_len); | |
| 195 goto out; | |
| 196 } | |
| 197 | |
| 198 out: | |
| 199 if (!recursive) | |
| 200 silc_mime_free(mime); | |
| 201 } | |
| 202 #endif /* HAVE_SILCMIME_H */ | |
| 8849 | 203 |
| 204 /* Message for a channel. The `sender' is the sender of the message | |
| 205 The `channel' is the channel. The `message' is the message. Note | |
| 206 that `message' maybe NULL. The `flags' indicates message flags | |
| 207 and it is used to determine how the message can be interpreted | |
| 208 (like it may tell the message is multimedia message). */ | |
| 209 | |
| 210 static void | |
| 211 silc_channel_message(SilcClient client, SilcClientConnection conn, | |
| 212 SilcClientEntry sender, SilcChannelEntry channel, | |
| 213 SilcMessagePayload payload, SilcChannelPrivateKey key, | |
| 214 SilcMessageFlags flags, const unsigned char *message, | |
| 215 SilcUInt32 message_len) | |
| 216 { | |
| 217 GaimConnection *gc = client->application; | |
| 218 SilcGaim sg = gc->proto_data; | |
| 219 GaimConversation *convo = NULL; | |
| 9359 | 220 char *msg, *tmp; |
| 8849 | 221 |
| 222 if (!message) | |
| 223 return; | |
| 224 | |
| 225 if (key) { | |
| 226 GList *l; | |
| 227 SilcGaimPrvgrp prv; | |
| 228 | |
| 229 for (l = sg->grps; l; l = l->next) | |
| 230 if (((SilcGaimPrvgrp)l->data)->key == key) { | |
| 231 prv = l->data; | |
| 11338 | 232 convo = gaim_find_conversation_with_account(GAIM_CONV_TYPE_CHAT, |
| 10246 | 233 prv->channel, sg->account); |
| 8849 | 234 break; |
| 235 } | |
| 236 } | |
| 237 if (!convo) | |
| 11338 | 238 convo = gaim_find_conversation_with_account(GAIM_CONV_TYPE_CHAT, |
| 10246 | 239 channel->channel_name, sg->account); |
| 8849 | 240 if (!convo) |
| 241 return; | |
| 242 | |
| 243 if (flags & SILC_MESSAGE_FLAG_SIGNED && | |
| 12167 | 244 gaim_account_get_bool(sg->account, "sign-verify", FALSE)) { |
| 8849 | 245 /* XXX */ |
| 246 } | |
| 247 | |
| 248 if (flags & SILC_MESSAGE_FLAG_DATA) { | |
| 12217 | 249 /* Process MIME message */ |
| 250 #ifdef HAVE_SILCMIME_H | |
| 251 SilcMime mime; | |
| 252 mime = silc_mime_decode(message, message_len); | |
| 253 silcgaim_mime_message(client, conn, sender, channel, payload, | |
| 254 key, flags, mime, FALSE); | |
| 255 #else | |
| 12058 | 256 char type[128], enc[128]; |
| 257 unsigned char *data; | |
| 258 SilcUInt32 data_len; | |
| 259 | |
| 260 memset(type, 0, sizeof(type)); | |
| 261 memset(enc, 0, sizeof(enc)); | |
| 262 | |
| 263 if (!silc_mime_parse(message, message_len, NULL, 0, | |
| 12217 | 264 type, sizeof(type) - 1, enc, sizeof(enc) - 1, &data, |
| 12058 | 265 &data_len)) |
| 266 return; | |
| 267 | |
| 268 if (!strcmp(type, "application/x-wb") && | |
| 12167 | 269 !strcmp(enc, "binary") && |
| 270 !gaim_account_get_bool(sg->account, "block-wb", FALSE)) | |
| 12058 | 271 silcgaim_wb_receive_ch(client, conn, sender, channel, |
| 272 payload, flags, data, data_len); | |
| 12217 | 273 #endif |
| 8849 | 274 return; |
| 275 } | |
| 276 | |
| 277 if (flags & SILC_MESSAGE_FLAG_ACTION) { | |
| 9353 | 278 msg = g_strdup_printf("/me %s", |
| 8849 | 279 (const char *)message); |
| 280 if (!msg) | |
| 281 return; | |
| 282 | |
|
10732
c4cb90065e1d
[gaim-migrate @ 12334]
Luke Schierer <lschiere@pidgin.im>
parents:
10589
diff
changeset
|
283 tmp = g_markup_escape_text(msg, -1); |
| 8849 | 284 /* Send to Gaim */ |
| 9353 | 285 serv_got_chat_in(gc, gaim_conv_chat_get_id(GAIM_CONV_CHAT(convo)), |
| 286 sender->nickname ? | |
| 287 sender->nickname : "<unknown>", 0, | |
| 9359 | 288 tmp, time(NULL)); |
| 289 g_free(tmp); | |
| 8849 | 290 g_free(msg); |
| 291 return; | |
| 292 } | |
| 293 | |
| 294 if (flags & SILC_MESSAGE_FLAG_NOTICE) { | |
| 295 msg = g_strdup_printf("(notice) <I>%s</I> %s", | |
| 296 sender->nickname ? | |
| 297 sender->nickname : "<unknown>", | |
| 298 (const char *)message); | |
| 299 if (!msg) | |
| 300 return; | |
| 301 | |
| 302 /* Send to Gaim */ | |
| 303 gaim_conversation_write(convo, NULL, (const char *)msg, | |
| 304 GAIM_MESSAGE_SYSTEM, time(NULL)); | |
| 305 g_free(msg); | |
| 306 return; | |
| 307 } | |
| 308 | |
| 9359 | 309 if (flags & SILC_MESSAGE_FLAG_UTF8) { |
|
10732
c4cb90065e1d
[gaim-migrate @ 12334]
Luke Schierer <lschiere@pidgin.im>
parents:
10589
diff
changeset
|
310 tmp = g_markup_escape_text((const char *)message, -1); |
| 8849 | 311 /* Send to Gaim */ |
| 312 serv_got_chat_in(gc, gaim_conv_chat_get_id(GAIM_CONV_CHAT(convo)), | |
| 313 sender->nickname ? | |
| 314 sender->nickname : "<unknown>", 0, | |
| 9359 | 315 tmp, time(NULL)); |
| 316 g_free(tmp); | |
| 317 } | |
| 8849 | 318 } |
| 319 | |
| 320 | |
| 321 /* Private message to the client. The `sender' is the sender of the | |
| 322 message. The message is `message'and maybe NULL. The `flags' | |
| 323 indicates message flags and it is used to determine how the message | |
| 324 can be interpreted (like it may tell the message is multimedia | |
| 325 message). */ | |
| 326 | |
| 327 static void | |
| 328 silc_private_message(SilcClient client, SilcClientConnection conn, | |
| 329 SilcClientEntry sender, SilcMessagePayload payload, | |
| 330 SilcMessageFlags flags, const unsigned char *message, | |
| 331 SilcUInt32 message_len) | |
| 332 { | |
| 333 GaimConnection *gc = client->application; | |
| 334 SilcGaim sg = gc->proto_data; | |
| 335 GaimConversation *convo = NULL; | |
| 9359 | 336 char *msg, *tmp; |
| 8849 | 337 |
| 338 if (!message) | |
| 339 return; | |
| 340 | |
| 341 if (sender->nickname) | |
| 11338 | 342 /* XXX - Should this be GAIM_CONV_TYPE_IM? */ |
| 343 convo = gaim_find_conversation_with_account(GAIM_CONV_TYPE_ANY, | |
| 10246 | 344 sender->nickname, sg->account); |
| 8849 | 345 |
| 346 if (flags & SILC_MESSAGE_FLAG_SIGNED && | |
| 12167 | 347 gaim_account_get_bool(sg->account, "sign-verify", FALSE)) { |
| 8849 | 348 /* XXX */ |
| 349 } | |
| 350 | |
| 351 if (flags & SILC_MESSAGE_FLAG_DATA) { | |
| 12217 | 352 #ifdef HAVE_SILCMIME_H |
| 353 /* Process MIME message */ | |
| 354 SilcMime mime; | |
| 355 mime = silc_mime_decode(message, message_len); | |
| 356 silcgaim_mime_message(client, conn, sender, NULL, payload, | |
| 357 NULL, flags, mime, FALSE); | |
| 358 #else | |
| 12058 | 359 char type[128], enc[128]; |
| 360 unsigned char *data; | |
| 361 SilcUInt32 data_len; | |
| 362 | |
| 363 memset(type, 0, sizeof(type)); | |
| 364 memset(enc, 0, sizeof(enc)); | |
| 365 | |
| 366 if (!silc_mime_parse(message, message_len, NULL, 0, | |
| 367 type, sizeof(type) - 1, enc, sizeof(enc) - 1, &data, | |
| 368 &data_len)) | |
| 369 return; | |
| 370 | |
| 371 if (!strcmp(type, "application/x-wb") && | |
| 12167 | 372 !strcmp(enc, "binary") && |
| 373 !gaim_account_get_bool(sg->account, "block-wb", FALSE)) | |
| 12058 | 374 silcgaim_wb_receive(client, conn, sender, payload, |
| 375 flags, data, data_len); | |
| 12217 | 376 #endif |
| 8849 | 377 return; |
| 378 } | |
| 379 | |
| 380 if (flags & SILC_MESSAGE_FLAG_ACTION && convo) { | |
| 9353 | 381 msg = g_strdup_printf("/me %s", |
| 8849 | 382 (const char *)message); |
| 383 if (!msg) | |
| 384 return; | |
| 385 | |
|
10732
c4cb90065e1d
[gaim-migrate @ 12334]
Luke Schierer <lschiere@pidgin.im>
parents:
10589
diff
changeset
|
386 tmp = g_markup_escape_text(msg, -1); |
| 8849 | 387 /* Send to Gaim */ |
| 9353 | 388 serv_got_im(gc, sender->nickname ? |
| 389 sender->nickname : "<unknown>", | |
| 9359 | 390 tmp, 0, time(NULL)); |
| 8849 | 391 g_free(msg); |
| 9359 | 392 g_free(tmp); |
| 8849 | 393 return; |
| 394 } | |
| 395 | |
| 396 if (flags & SILC_MESSAGE_FLAG_NOTICE && convo) { | |
| 397 msg = g_strdup_printf("(notice) <I>%s</I> %s", | |
| 398 sender->nickname ? | |
| 399 sender->nickname : "<unknown>", | |
| 400 (const char *)message); | |
| 401 if (!msg) | |
| 402 return; | |
| 403 | |
| 404 /* Send to Gaim */ | |
| 405 gaim_conversation_write(convo, NULL, (const char *)msg, | |
| 406 GAIM_MESSAGE_SYSTEM, time(NULL)); | |
| 407 g_free(msg); | |
| 408 return; | |
| 409 } | |
| 410 | |
| 9359 | 411 if (flags & SILC_MESSAGE_FLAG_UTF8) { |
|
10732
c4cb90065e1d
[gaim-migrate @ 12334]
Luke Schierer <lschiere@pidgin.im>
parents:
10589
diff
changeset
|
412 tmp = g_markup_escape_text((const char *)message, -1); |
| 8849 | 413 /* Send to Gaim */ |
| 414 serv_got_im(gc, sender->nickname ? | |
| 415 sender->nickname : "<unknown>", | |
| 9359 | 416 tmp, 0, time(NULL)); |
| 417 g_free(tmp); | |
| 418 } | |
| 8849 | 419 } |
| 420 | |
| 421 | |
| 422 /* Notify message to the client. The notify arguments are sent in the | |
| 423 same order as servers sends them. The arguments are same as received | |
| 424 from the server except for ID's. If ID is received application receives | |
| 425 the corresponding entry to the ID. For example, if Client ID is received | |
| 426 application receives SilcClientEntry. Also, if the notify type is | |
| 427 for channel the channel entry is sent to application (even if server | |
| 428 does not send it because client library gets the channel entry from | |
| 429 the Channel ID in the packet's header). */ | |
| 430 | |
| 431 static void | |
| 432 silc_notify(SilcClient client, SilcClientConnection conn, | |
| 433 SilcNotifyType type, ...) | |
| 434 { | |
| 435 va_list va; | |
| 436 GaimConnection *gc = client->application; | |
| 437 SilcGaim sg = gc->proto_data; | |
| 438 GaimConversation *convo; | |
| 439 SilcClientEntry client_entry, client_entry2; | |
| 440 SilcChannelEntry channel; | |
| 441 SilcServerEntry server_entry; | |
| 442 SilcIdType idtype; | |
| 443 void *entry; | |
| 444 SilcUInt32 mode; | |
| 445 SilcHashTableList htl; | |
| 446 SilcChannelUser chu; | |
| 447 char buf[512], buf2[512], *tmp, *name; | |
| 448 SilcBuffer buffer; | |
| 449 SilcNotifyType notify; | |
| 450 GaimBuddy *b; | |
| 451 int i; | |
| 452 | |
| 453 va_start(va, type); | |
| 454 memset(buf, 0, sizeof(buf)); | |
| 455 | |
| 456 switch (type) { | |
| 457 | |
| 458 case SILC_NOTIFY_TYPE_NONE: | |
| 459 break; | |
| 460 | |
| 461 case SILC_NOTIFY_TYPE_INVITE: | |
| 462 { | |
| 463 GHashTable *components; | |
| 464 channel = va_arg(va, SilcChannelEntry); | |
| 465 name = va_arg(va, char *); | |
| 466 client_entry = va_arg(va, SilcClientEntry); | |
| 467 | |
| 468 components = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); | |
| 9353 | 469 g_hash_table_insert(components, strdup("channel"), strdup(name)); |
| 470 serv_got_chat_invite(gc, name, client_entry->nickname, NULL, components); | |
| 8849 | 471 } |
| 472 break; | |
| 473 | |
| 474 case SILC_NOTIFY_TYPE_JOIN: | |
| 475 client_entry = va_arg(va, SilcClientEntry); | |
| 476 channel = va_arg(va, SilcChannelEntry); | |
| 477 | |
| 478 /* If we joined channel, do nothing */ | |
| 479 if (client_entry == conn->local_entry) | |
| 480 break; | |
| 481 | |
| 11338 | 482 convo = gaim_find_conversation_with_account(GAIM_CONV_TYPE_CHAT, |
| 10246 | 483 channel->channel_name, sg->account); |
| 8849 | 484 if (!convo) |
| 485 break; | |
| 486 | |
| 487 /* Join user to channel */ | |
| 8891 | 488 g_snprintf(buf, sizeof(buf), "%s@%s", |
| 8849 | 489 client_entry->username, client_entry->hostname); |
| 490 gaim_conv_chat_add_user(GAIM_CONV_CHAT(convo), | |
| 9846 | 491 g_strdup(client_entry->nickname), buf, GAIM_CBFLAGS_NONE, TRUE); |
| 8849 | 492 |
| 493 break; | |
| 494 | |
| 495 case SILC_NOTIFY_TYPE_LEAVE: | |
| 496 client_entry = va_arg(va, SilcClientEntry); | |
| 497 channel = va_arg(va, SilcChannelEntry); | |
| 498 | |
| 11338 | 499 convo = gaim_find_conversation_with_account(GAIM_CONV_TYPE_CHAT, |
| 10246 | 500 channel->channel_name, sg->account); |
| 8849 | 501 if (!convo) |
| 502 break; | |
| 503 | |
| 504 /* Remove user from channel */ | |
| 505 gaim_conv_chat_remove_user(GAIM_CONV_CHAT(convo), | |
| 506 client_entry->nickname, NULL); | |
| 507 | |
| 508 break; | |
| 509 | |
| 510 case SILC_NOTIFY_TYPE_SIGNOFF: | |
| 511 client_entry = va_arg(va, SilcClientEntry); | |
| 512 tmp = va_arg(va, char *); | |
| 513 | |
| 514 if (!client_entry->nickname) | |
| 515 break; | |
| 516 | |
| 517 /* Remove from all channels */ | |
| 518 silc_hash_table_list(client_entry->channels, &htl); | |
| 519 while (silc_hash_table_get(&htl, NULL, (void *)&chu)) { | |
| 11338 | 520 convo = gaim_find_conversation_with_account(GAIM_CONV_TYPE_CHAT, |
| 10246 | 521 chu->channel->channel_name, sg->account); |
| 8849 | 522 if (!convo) |
| 523 continue; | |
| 524 gaim_conv_chat_remove_user(GAIM_CONV_CHAT(convo), | |
| 525 client_entry->nickname, | |
| 526 tmp); | |
| 527 } | |
| 528 silc_hash_table_list_reset(&htl); | |
| 529 | |
| 530 break; | |
| 531 | |
| 532 case SILC_NOTIFY_TYPE_TOPIC_SET: | |
| 9762 | 533 { |
| 534 char *esc, *tmp2; | |
| 535 idtype = va_arg(va, int); | |
| 536 entry = va_arg(va, void *); | |
| 537 tmp = va_arg(va, char *); | |
| 538 channel = va_arg(va, SilcChannelEntry); | |
| 539 | |
| 11338 | 540 convo = gaim_find_conversation_with_account(GAIM_CONV_TYPE_CHAT, |
| 10246 | 541 channel->channel_name, sg->account); |
| 9762 | 542 if (!convo) |
| 543 break; | |
| 544 | |
| 545 if (!tmp) | |
| 546 break; | |
| 547 | |
|
10732
c4cb90065e1d
[gaim-migrate @ 12334]
Luke Schierer <lschiere@pidgin.im>
parents:
10589
diff
changeset
|
548 esc = g_markup_escape_text(tmp, -1); |
| 9762 | 549 tmp2 = gaim_markup_linkify(esc); |
| 550 g_free(esc); | |
| 8849 | 551 |
| 9762 | 552 if (idtype == SILC_ID_CLIENT) { |
| 553 client_entry = (SilcClientEntry)entry; | |
| 554 g_snprintf(buf, sizeof(buf), | |
| 555 _("%s has changed the topic of <I>%s</I> to: %s"), | |
| 556 client_entry->nickname, channel->channel_name, tmp2); | |
| 557 gaim_conv_chat_write(GAIM_CONV_CHAT(convo), client_entry->nickname, | |
| 558 buf, GAIM_MESSAGE_SYSTEM, time(NULL)); | |
| 559 gaim_conv_chat_set_topic(GAIM_CONV_CHAT(convo), | |
| 560 client_entry->nickname, tmp); | |
| 561 } else if (idtype == SILC_ID_SERVER) { | |
| 562 server_entry = (SilcServerEntry)entry; | |
| 563 g_snprintf(buf, sizeof(buf), | |
| 564 _("%s has changed the topic of <I>%s</I> to: %s"), | |
| 565 server_entry->server_name, channel->channel_name, tmp2); | |
| 566 gaim_conv_chat_write(GAIM_CONV_CHAT(convo), server_entry->server_name, | |
| 567 buf, GAIM_MESSAGE_SYSTEM, time(NULL)); | |
| 568 gaim_conv_chat_set_topic(GAIM_CONV_CHAT(convo), | |
| 569 server_entry->server_name, tmp); | |
| 570 } else if (idtype == SILC_ID_CHANNEL) { | |
| 571 channel = (SilcChannelEntry)entry; | |
| 572 g_snprintf(buf, sizeof(buf), | |
| 573 _("%s has changed the topic of <I>%s</I> to: %s"), | |
| 574 channel->channel_name, channel->channel_name, tmp2); | |
| 575 gaim_conv_chat_write(GAIM_CONV_CHAT(convo), channel->channel_name, | |
| 576 buf, GAIM_MESSAGE_SYSTEM, time(NULL)); | |
| 577 gaim_conv_chat_set_topic(GAIM_CONV_CHAT(convo), | |
| 578 channel->channel_name, tmp); | |
| 579 } else { | |
| 580 gaim_conv_chat_set_topic(GAIM_CONV_CHAT(convo), NULL, tmp); | |
| 581 } | |
| 8849 | 582 |
| 9762 | 583 g_free(tmp2); |
| 584 | |
| 8849 | 585 break; |
| 586 | |
| 587 } | |
| 588 case SILC_NOTIFY_TYPE_NICK_CHANGE: | |
| 589 client_entry = va_arg(va, SilcClientEntry); | |
| 590 client_entry2 = va_arg(va, SilcClientEntry); | |
| 591 | |
| 592 if (!strcmp(client_entry->nickname, client_entry2->nickname)) | |
| 593 break; | |
| 594 | |
| 595 /* Change nick on all channels */ | |
| 596 silc_hash_table_list(client_entry2->channels, &htl); | |
| 597 while (silc_hash_table_get(&htl, NULL, (void *)&chu)) { | |
| 11338 | 598 convo = gaim_find_conversation_with_account(GAIM_CONV_TYPE_CHAT, |
| 10246 | 599 chu->channel->channel_name, sg->account); |
| 8849 | 600 if (!convo) |
| 601 continue; | |
| 9628 | 602 if (gaim_conv_chat_find_user(GAIM_CONV_CHAT(convo), client_entry->nickname)) |
| 603 gaim_conv_chat_rename_user(GAIM_CONV_CHAT(convo), | |
| 604 client_entry->nickname, | |
| 605 client_entry2->nickname); | |
| 8849 | 606 } |
| 607 silc_hash_table_list_reset(&htl); | |
| 608 | |
| 609 break; | |
| 610 | |
| 611 case SILC_NOTIFY_TYPE_CMODE_CHANGE: | |
| 612 idtype = va_arg(va, int); | |
| 613 entry = va_arg(va, void *); | |
| 614 mode = va_arg(va, SilcUInt32); | |
| 615 (void)va_arg(va, char *); | |
| 616 (void)va_arg(va, char *); | |
| 617 (void)va_arg(va, char *); | |
| 618 (void)va_arg(va, SilcPublicKey); | |
| 619 buffer = va_arg(va, SilcBuffer); | |
| 620 channel = va_arg(va, SilcChannelEntry); | |
| 621 | |
| 11338 | 622 convo = gaim_find_conversation_with_account(GAIM_CONV_TYPE_CHAT, |
| 10246 | 623 channel->channel_name, sg->account); |
| 8849 | 624 if (!convo) |
| 625 break; | |
| 626 | |
| 627 if (idtype == SILC_ID_CLIENT) | |
| 628 name = ((SilcClientEntry)entry)->nickname; | |
| 629 else if (idtype == SILC_ID_SERVER) | |
| 630 name = ((SilcServerEntry)entry)->server_name; | |
| 631 else | |
| 632 name = ((SilcChannelEntry)entry)->channel_name; | |
| 633 if (!name) | |
| 634 break; | |
| 635 | |
| 636 if (mode) { | |
| 637 silcgaim_get_chmode_string(mode, buf2, sizeof(buf2)); | |
| 638 g_snprintf(buf, sizeof(buf), | |
| 639 _("<I>%s</I> set channel <I>%s</I> modes to: %s"), name, | |
| 640 channel->channel_name, buf2); | |
| 641 } else { | |
| 642 g_snprintf(buf, sizeof(buf), | |
| 643 _("<I>%s</I> removed all channel <I>%s</I> modes"), name, | |
| 644 channel->channel_name); | |
| 645 } | |
| 646 gaim_conv_chat_write(GAIM_CONV_CHAT(convo), channel->channel_name, | |
| 647 buf, GAIM_MESSAGE_SYSTEM, time(NULL)); | |
| 648 break; | |
| 649 | |
| 650 case SILC_NOTIFY_TYPE_CUMODE_CHANGE: | |
| 9554 | 651 { |
| 652 GaimConvChatBuddyFlags flags = GAIM_CBFLAGS_NONE; | |
| 653 idtype = va_arg(va, int); | |
| 654 entry = va_arg(va, void *); | |
| 655 mode = va_arg(va, SilcUInt32); | |
| 656 client_entry2 = va_arg(va, SilcClientEntry); | |
| 657 channel = va_arg(va, SilcChannelEntry); | |
| 8849 | 658 |
| 11338 | 659 convo = gaim_find_conversation_with_account(GAIM_CONV_TYPE_CHAT, |
| 10246 | 660 channel->channel_name, sg->account); |
| 9554 | 661 if (!convo) |
| 662 break; | |
| 8849 | 663 |
| 9554 | 664 if (idtype == SILC_ID_CLIENT) |
| 665 name = ((SilcClientEntry)entry)->nickname; | |
| 666 else if (idtype == SILC_ID_SERVER) | |
| 667 name = ((SilcServerEntry)entry)->server_name; | |
| 668 else | |
| 669 name = ((SilcChannelEntry)entry)->channel_name; | |
| 670 if (!name) | |
| 671 break; | |
| 8849 | 672 |
| 9554 | 673 if (mode) { |
| 674 silcgaim_get_chumode_string(mode, buf2, sizeof(buf2)); | |
| 675 g_snprintf(buf, sizeof(buf), | |
| 676 _("<I>%s</I> set <I>%s's</I> modes to: %s"), name, | |
| 677 client_entry2->nickname, buf2); | |
| 678 if (mode & SILC_CHANNEL_UMODE_CHANFO) | |
| 679 flags |= GAIM_CBFLAGS_FOUNDER; | |
| 680 if (mode & SILC_CHANNEL_UMODE_CHANOP) | |
| 681 flags |= GAIM_CBFLAGS_OP; | |
| 682 } else { | |
| 683 g_snprintf(buf, sizeof(buf), | |
| 684 _("<I>%s</I> removed all <I>%s's</I> modes"), name, | |
| 685 client_entry2->nickname); | |
| 686 } | |
| 687 gaim_conv_chat_write(GAIM_CONV_CHAT(convo), channel->channel_name, | |
| 688 buf, GAIM_MESSAGE_SYSTEM, time(NULL)); | |
| 689 gaim_conv_chat_user_set_flags(GAIM_CONV_CHAT(convo), client_entry2->nickname, flags); | |
| 690 break; | |
| 8849 | 691 } |
| 692 | |
| 693 case SILC_NOTIFY_TYPE_MOTD: | |
| 694 tmp = va_arg(va, char *); | |
| 695 silc_free(sg->motd); | |
| 696 sg->motd = silc_memdup(tmp, strlen(tmp)); | |
| 697 break; | |
| 698 | |
| 699 case SILC_NOTIFY_TYPE_KICKED: | |
| 700 client_entry = va_arg(va, SilcClientEntry); | |
| 701 tmp = va_arg(va, char *); | |
| 702 client_entry2 = va_arg(va, SilcClientEntry); | |
| 703 channel = va_arg(va, SilcChannelEntry); | |
| 704 | |
| 11338 | 705 convo = gaim_find_conversation_with_account(GAIM_CONV_TYPE_CHAT, |
| 10246 | 706 channel->channel_name, sg->account); |
| 8849 | 707 if (!convo) |
| 708 break; | |
| 709 | |
| 710 if (client_entry == conn->local_entry) { | |
| 711 /* Remove us from channel */ | |
| 712 g_snprintf(buf, sizeof(buf), | |
| 713 _("You have been kicked off <I>%s</I> by <I>%s</I> (%s)"), | |
| 714 channel->channel_name, client_entry2->nickname, | |
| 715 tmp ? tmp : ""); | |
| 716 gaim_conv_chat_write(GAIM_CONV_CHAT(convo), client_entry->nickname, | |
| 717 buf, GAIM_MESSAGE_SYSTEM, time(NULL)); | |
| 718 serv_got_chat_left(gc, gaim_conv_chat_get_id(GAIM_CONV_CHAT(convo))); | |
| 719 } else { | |
| 720 /* Remove user from channel */ | |
| 12885 | 721 g_snprintf(buf, sizeof(buf), _("Kicked by %s (%s)"), |
| 8849 | 722 client_entry2->nickname, tmp ? tmp : ""); |
| 9353 | 723 gaim_conv_chat_remove_user(GAIM_CONV_CHAT(convo), |
| 8849 | 724 client_entry->nickname, |
| 725 buf); | |
| 726 } | |
| 727 | |
| 728 break; | |
| 729 | |
| 730 case SILC_NOTIFY_TYPE_KILLED: | |
| 731 client_entry = va_arg(va, SilcClientEntry); | |
| 732 tmp = va_arg(va, char *); | |
| 733 idtype = va_arg(va, int); | |
| 734 entry = va_arg(va, SilcClientEntry); | |
| 735 | |
| 736 if (!client_entry->nickname) | |
| 737 break; | |
| 738 | |
| 739 if (client_entry == conn->local_entry) { | |
| 740 if (idtype == SILC_ID_CLIENT) { | |
| 741 client_entry2 = (SilcClientEntry)entry; | |
| 742 g_snprintf(buf, sizeof(buf), | |
| 743 _("You have been killed by %s (%s)"), | |
| 744 client_entry2->nickname, tmp ? tmp : ""); | |
| 745 } else if (idtype == SILC_ID_SERVER) { | |
| 746 server_entry = (SilcServerEntry)entry; | |
| 747 g_snprintf(buf, sizeof(buf), | |
| 748 _("You have been killed by %s (%s)"), | |
| 749 server_entry->server_name, tmp ? tmp : ""); | |
| 750 } else if (idtype == SILC_ID_CHANNEL) { | |
| 751 channel = (SilcChannelEntry)entry; | |
| 752 g_snprintf(buf, sizeof(buf), | |
| 753 _("You have been killed by %s (%s)"), | |
| 754 channel->channel_name, tmp ? tmp : ""); | |
| 755 } | |
| 756 | |
| 757 /* Remove us from all channels */ | |
| 758 silc_hash_table_list(client_entry->channels, &htl); | |
| 759 while (silc_hash_table_get(&htl, NULL, (void *)&chu)) { | |
| 11338 | 760 convo = gaim_find_conversation_with_account(GAIM_CONV_TYPE_CHAT, |
| 10246 | 761 chu->channel->channel_name, sg->account); |
| 8849 | 762 if (!convo) |
| 763 continue; | |
| 764 gaim_conv_chat_write(GAIM_CONV_CHAT(convo), client_entry->nickname, | |
| 765 buf, GAIM_MESSAGE_SYSTEM, time(NULL)); | |
| 766 serv_got_chat_left(gc, gaim_conv_chat_get_id(GAIM_CONV_CHAT(convo))); | |
| 767 } | |
| 768 silc_hash_table_list_reset(&htl); | |
| 769 | |
| 770 } else { | |
| 771 if (idtype == SILC_ID_CLIENT) { | |
| 772 client_entry2 = (SilcClientEntry)entry; | |
| 773 g_snprintf(buf, sizeof(buf), | |
| 774 _("Killed by %s (%s)"), | |
| 775 client_entry2->nickname, tmp ? tmp : ""); | |
| 776 } else if (idtype == SILC_ID_SERVER) { | |
| 777 server_entry = (SilcServerEntry)entry; | |
| 778 g_snprintf(buf, sizeof(buf), | |
| 779 _("Killed by %s (%s)"), | |
| 780 server_entry->server_name, tmp ? tmp : ""); | |
| 781 } else if (idtype == SILC_ID_CHANNEL) { | |
| 782 channel = (SilcChannelEntry)entry; | |
| 783 g_snprintf(buf, sizeof(buf), | |
| 784 _("Killed by %s (%s)"), | |
| 785 channel->channel_name, tmp ? tmp : ""); | |
| 786 } | |
| 787 | |
| 788 /* Remove user from all channels */ | |
| 789 silc_hash_table_list(client_entry->channels, &htl); | |
| 790 while (silc_hash_table_get(&htl, NULL, (void *)&chu)) { | |
| 11338 | 791 convo = gaim_find_conversation_with_account(GAIM_CONV_TYPE_CHAT, |
| 10246 | 792 chu->channel->channel_name, sg->account); |
| 8849 | 793 if (!convo) |
| 794 continue; | |
| 795 gaim_conv_chat_remove_user(GAIM_CONV_CHAT(convo), | |
| 796 client_entry->nickname, tmp); | |
| 797 } | |
| 798 silc_hash_table_list_reset(&htl); | |
| 799 } | |
| 800 | |
| 801 break; | |
| 802 | |
| 803 case SILC_NOTIFY_TYPE_CHANNEL_CHANGE: | |
| 804 break; | |
| 805 | |
| 806 case SILC_NOTIFY_TYPE_SERVER_SIGNOFF: | |
| 807 { | |
| 808 int i; | |
| 809 SilcClientEntry *clients; | |
| 810 SilcUInt32 clients_count; | |
| 811 | |
| 812 (void)va_arg(va, void *); | |
| 813 clients = va_arg(va, SilcClientEntry *); | |
| 814 clients_count = va_arg(va, SilcUInt32); | |
| 815 | |
| 816 for (i = 0; i < clients_count; i++) { | |
| 817 if (!clients[i]->nickname) | |
| 818 break; | |
| 819 | |
| 820 /* Remove from all channels */ | |
| 821 silc_hash_table_list(clients[i]->channels, &htl); | |
| 822 while (silc_hash_table_get(&htl, NULL, (void *)&chu)) { | |
| 823 convo = | |
| 11338 | 824 gaim_find_conversation_with_account(GAIM_CONV_TYPE_CHAT, |
| 10246 | 825 chu->channel->channel_name, sg->account); |
| 8849 | 826 if (!convo) |
| 827 continue; | |
| 828 gaim_conv_chat_remove_user(GAIM_CONV_CHAT(convo), | |
| 829 clients[i]->nickname, | |
| 830 _("Server signoff")); | |
| 831 } | |
| 832 silc_hash_table_list_reset(&htl); | |
| 833 } | |
| 834 } | |
| 835 break; | |
| 836 | |
| 837 case SILC_NOTIFY_TYPE_ERROR: | |
| 838 { | |
| 839 SilcStatus error = va_arg(va, int); | |
| 840 gaim_notify_error(gc, "Error Notify", | |
| 841 silc_get_status_message(error), | |
| 842 NULL); | |
| 843 } | |
| 844 break; | |
| 845 | |
| 846 case SILC_NOTIFY_TYPE_WATCH: | |
| 847 { | |
| 848 SilcPublicKey public_key; | |
| 849 unsigned char *pk; | |
| 850 SilcUInt32 pk_len; | |
| 851 char *fingerprint; | |
| 852 | |
| 853 client_entry = va_arg(va, SilcClientEntry); | |
| 854 (void)va_arg(va, char *); | |
| 855 mode = va_arg(va, SilcUInt32); | |
| 856 notify = va_arg(va, int); | |
| 857 public_key = va_arg(va, SilcPublicKey); | |
| 858 | |
| 859 b = NULL; | |
| 860 if (public_key) { | |
| 861 GaimBlistNode *gnode, *cnode, *bnode; | |
| 862 const char *f; | |
| 863 | |
| 864 pk = silc_pkcs_public_key_encode(public_key, &pk_len); | |
| 865 if (!pk) | |
| 866 break; | |
| 867 fingerprint = silc_hash_fingerprint(NULL, pk, pk_len); | |
| 868 for (i = 0; i < strlen(fingerprint); i++) | |
| 869 if (fingerprint[i] == ' ') | |
| 870 fingerprint[i] = '_'; | |
| 871 g_snprintf(buf, sizeof(buf) - 1, | |
| 872 "%s" G_DIR_SEPARATOR_S "clientkeys" | |
| 873 G_DIR_SEPARATOR_S "clientkey_%s.pub", | |
| 874 silcgaim_silcdir(), fingerprint); | |
| 875 silc_free(fingerprint); | |
| 876 silc_free(pk); | |
| 877 | |
| 878 /* Find buddy by associated public key */ | |
| 879 for (gnode = gaim_get_blist()->root; gnode; | |
| 880 gnode = gnode->next) { | |
| 881 if (!GAIM_BLIST_NODE_IS_GROUP(gnode)) | |
| 882 continue; | |
| 883 for (cnode = gnode->child; cnode; cnode = cnode->next) { | |
| 884 if( !GAIM_BLIST_NODE_IS_CONTACT(cnode)) | |
| 885 continue; | |
| 886 for (bnode = cnode->child; bnode; | |
| 887 bnode = bnode->next) { | |
| 888 if (!GAIM_BLIST_NODE_IS_BUDDY(bnode)) | |
| 889 continue; | |
| 890 b = (GaimBuddy *)bnode; | |
| 891 if (b->account != gc->account) | |
| 892 continue; | |
| 893 f = gaim_blist_node_get_string(bnode, "public-key"); | |
| 894 if (!strcmp(f, buf)) | |
| 895 goto cont; | |
| 896 } | |
| 897 } | |
| 898 } | |
| 899 } | |
| 900 cont: | |
| 901 if (!b) { | |
| 902 /* Find buddy by nickname */ | |
| 903 b = gaim_find_buddy(sg->account, client_entry->nickname); | |
| 904 if (!b) { | |
| 9272 | 905 gaim_debug_warning("silc", "WATCH for %s, unknown buddy", |
| 8849 | 906 client_entry->nickname); |
| 907 break; | |
| 908 } | |
| 909 } | |
| 910 | |
| 911 silc_free(b->proto_data); | |
| 912 b->proto_data = silc_memdup(client_entry->id, | |
| 913 sizeof(*client_entry->id)); | |
| 914 if (notify == SILC_NOTIFY_TYPE_NICK_CHANGE) { | |
| 915 break; | |
| 916 } else if (notify == SILC_NOTIFY_TYPE_UMODE_CHANGE) { | |
| 917 /* See if client was away and is now present */ | |
| 918 if (!(mode & (SILC_UMODE_GONE | SILC_UMODE_INDISPOSED | | |
| 919 SILC_UMODE_BUSY | SILC_UMODE_PAGE | | |
| 920 SILC_UMODE_DETACHED)) && | |
| 921 (client_entry->mode & SILC_UMODE_GONE || | |
| 922 client_entry->mode & SILC_UMODE_INDISPOSED || | |
| 923 client_entry->mode & SILC_UMODE_BUSY || | |
| 924 client_entry->mode & SILC_UMODE_PAGE || | |
| 925 client_entry->mode & SILC_UMODE_DETACHED)) { | |
| 926 client_entry->mode = mode; | |
| 11522 | 927 gaim_prpl_got_user_status(gaim_buddy_get_account(b), gaim_buddy_get_name(b), SILCGAIM_STATUS_ID_AVAILABLE, NULL); |
| 8849 | 928 } |
| 929 else if ((mode & SILC_UMODE_GONE) || | |
| 930 (mode & SILC_UMODE_INDISPOSED) || | |
| 931 (mode & SILC_UMODE_BUSY) || | |
| 932 (mode & SILC_UMODE_PAGE) || | |
| 933 (mode & SILC_UMODE_DETACHED)) { | |
| 934 client_entry->mode = mode; | |
| 10050 | 935 gaim_prpl_got_user_status(gaim_buddy_get_account(b), gaim_buddy_get_name(b), SILCGAIM_STATUS_ID_OFFLINE, NULL); |
| 8849 | 936 } |
| 937 } else if (notify == SILC_NOTIFY_TYPE_SIGNOFF || | |
| 938 notify == SILC_NOTIFY_TYPE_SERVER_SIGNOFF || | |
| 939 notify == SILC_NOTIFY_TYPE_KILLED) { | |
| 940 client_entry->mode = mode; | |
| 10050 | 941 gaim_prpl_got_user_status(gaim_buddy_get_account(b), gaim_buddy_get_name(b), SILCGAIM_STATUS_ID_OFFLINE, NULL); |
| 8849 | 942 } else if (notify == SILC_NOTIFY_TYPE_NONE) { |
| 943 client_entry->mode = mode; | |
| 11522 | 944 gaim_prpl_got_user_status(gaim_buddy_get_account(b), gaim_buddy_get_name(b), SILCGAIM_STATUS_ID_AVAILABLE, NULL); |
| 8849 | 945 } |
| 946 } | |
| 947 break; | |
| 948 | |
| 949 default: | |
| 9353 | 950 gaim_debug_info("silc", "Unhandled notification: %d\n", type); |
| 8849 | 951 break; |
| 952 } | |
| 953 | |
| 954 va_end(va); | |
| 955 } | |
| 956 | |
| 957 | |
| 958 /* Command handler. This function is called always in the command function. | |
| 959 If error occurs it will be called as well. `conn' is the associated | |
| 960 client connection. `cmd_context' is the command context that was | |
| 961 originally sent to the command. `success' is FALSE if error occurred | |
| 962 during command. `command' is the command being processed. It must be | |
| 963 noted that this is not reply from server. This is merely called just | |
| 964 after application has called the command. Just to tell application | |
| 965 that the command really was processed. */ | |
| 966 | |
| 967 static void | |
| 968 silc_command(SilcClient client, SilcClientConnection conn, | |
| 969 SilcClientCommandContext cmd_context, bool success, | |
| 970 SilcCommand command, SilcStatus status) | |
| 971 { | |
| 972 GaimConnection *gc = client->application; | |
| 973 SilcGaim sg = gc->proto_data; | |
| 974 | |
| 975 switch (command) { | |
| 976 | |
| 977 case SILC_COMMAND_CMODE: | |
| 978 if (cmd_context->argc == 3 && | |
| 11488 | 979 !strcmp((char *)cmd_context->argv[2], "+C")) |
| 8849 | 980 sg->chpk = TRUE; |
| 981 else | |
| 982 sg->chpk = FALSE; | |
| 983 break; | |
| 984 | |
| 985 default: | |
| 986 break; | |
| 987 } | |
| 988 } | |
| 989 | |
| 9024 | 990 #if 0 |
| 8849 | 991 static void |
| 992 silcgaim_whois_more(SilcClientEntry client_entry, gint id) | |
| 993 { | |
| 994 SilcAttributePayload attr; | |
| 995 SilcAttribute attribute; | |
| 996 char *buf; | |
| 997 GString *s; | |
| 998 SilcVCardStruct vcard; | |
| 999 int i; | |
| 1000 | |
| 1001 if (id != 0) | |
| 1002 return; | |
| 1003 | |
| 1004 memset(&vcard, 0, sizeof(vcard)); | |
| 1005 | |
| 1006 s = g_string_new(""); | |
| 1007 | |
| 1008 silc_dlist_start(client_entry->attrs); | |
| 1009 while ((attr = silc_dlist_get(client_entry->attrs)) != SILC_LIST_END) { | |
| 1010 attribute = silc_attribute_get_attribute(attr); | |
| 1011 switch (attribute) { | |
| 1012 | |
| 1013 case SILC_ATTRIBUTE_USER_INFO: | |
| 1014 if (!silc_attribute_get_object(attr, (void *)&vcard, | |
| 1015 sizeof(vcard))) | |
| 1016 continue; | |
| 9039 | 1017 g_string_append_printf(s, "%s:\n\n", _("Personal Information")); |
| 8849 | 1018 if (vcard.full_name) |
| 9039 | 1019 g_string_append_printf(s, "%s:\t\t%s\n", |
| 1020 _("Full Name"), | |
| 8849 | 1021 vcard.full_name); |
| 1022 if (vcard.first_name) | |
| 9039 | 1023 g_string_append_printf(s, "%s:\t%s\n", |
| 1024 _("First Name"), | |
| 8849 | 1025 vcard.first_name); |
| 1026 if (vcard.middle_names) | |
| 9039 | 1027 g_string_append_printf(s, "%s:\t%s\n", |
| 1028 _("Middle Name"), | |
| 8849 | 1029 vcard.middle_names); |
| 1030 if (vcard.family_name) | |
| 9039 | 1031 g_string_append_printf(s, "%s:\t%s\n", |
| 1032 _("Family Name"), | |
| 8849 | 1033 vcard.family_name); |
| 1034 if (vcard.nickname) | |
| 9039 | 1035 g_string_append_printf(s, "%s:\t\t%s\n", |
| 1036 _("Nickname"), | |
| 8849 | 1037 vcard.nickname); |
| 1038 if (vcard.bday) | |
| 9039 | 1039 g_string_append_printf(s, "%s:\t\t%s\n", |
| 1040 _("Birth Day"), | |
| 8849 | 1041 vcard.bday); |
| 1042 if (vcard.title) | |
| 9039 | 1043 g_string_append_printf(s, "%s:\t\t%s\n", |
| 1044 _("Job Title"), | |
| 8849 | 1045 vcard.title); |
| 1046 if (vcard.role) | |
| 9039 | 1047 g_string_append_printf(s, "%s:\t\t%s\n", |
| 1048 _("Job Role"), | |
| 8849 | 1049 vcard.role); |
| 1050 if (vcard.org_name) | |
| 9039 | 1051 g_string_append_printf(s, "%s:\t%s\n", |
| 1052 _("Organization"), | |
| 8849 | 1053 vcard.org_name); |
| 1054 if (vcard.org_unit) | |
| 9039 | 1055 g_string_append_printf(s, "%s:\t\t%s\n", |
| 1056 _("Unit"), | |
| 8849 | 1057 vcard.org_unit); |
| 1058 if (vcard.url) | |
| 9039 | 1059 g_string_append_printf(s, "%s:\t%s\n", |
| 1060 _("Homepage"), | |
| 8849 | 1061 vcard.url); |
| 1062 if (vcard.label) | |
| 9039 | 1063 g_string_append_printf(s, "%s:\t%s\n", |
| 1064 _("Address"), | |
| 8849 | 1065 vcard.label); |
| 1066 for (i = 0; i < vcard.num_tels; i++) { | |
| 1067 if (vcard.tels[i].telnum) | |
| 9039 | 1068 g_string_append_printf(s, "%s:\t\t\t%s\n", |
| 1069 _("Phone"), | |
| 8849 | 1070 vcard.tels[i].telnum); |
| 1071 } | |
| 1072 for (i = 0; i < vcard.num_emails; i++) { | |
| 1073 if (vcard.emails[i].address) | |
| 9039 | 1074 g_string_append_printf(s, "%s:\t\t%s\n", |
|
13545
cfc2f7fcb3dd
[gaim-migrate @ 15922]
Richard Laager <rlaager@wiktel.com>
parents:
13446
diff
changeset
|
1075 _("E-Mail"), |
| 8849 | 1076 vcard.emails[i].address); |
| 1077 } | |
| 1078 if (vcard.note) | |
| 9039 | 1079 g_string_append_printf(s, "\n%s:\t\t%s\n", |
| 1080 _("Note"), | |
| 8849 | 1081 vcard.note); |
| 1082 break; | |
| 1083 } | |
| 1084 } | |
| 1085 | |
| 1086 buf = g_string_free(s, FALSE); | |
| 1087 gaim_notify_info(NULL, _("User Information"), _("User Information"), | |
| 1088 buf); | |
| 1089 g_free(buf); | |
| 1090 } | |
| 9024 | 1091 #endif |
| 8849 | 1092 |
| 1093 /* Command reply handler. This function is called always in the command reply | |
| 1094 function. If error occurs it will be called as well. Normal scenario | |
| 1095 is that it will be called after the received command data has been parsed | |
| 1096 and processed. The function is used to pass the received command data to | |
| 1097 the application. | |
| 1098 | |
| 1099 `conn' is the associated client connection. `cmd_payload' is the command | |
| 1100 payload data received from server and it can be ignored. It is provided | |
| 1101 if the application would like to re-parse the received command data, | |
| 1102 however, it must be noted that the data is parsed already by the library | |
| 1103 thus the payload can be ignored. `success' is FALSE if error occurred. | |
| 1104 In this case arguments are not sent to the application. The `status' is | |
| 1105 the command reply status server returned. The `command' is the command | |
| 1106 reply being processed. The function has variable argument list and each | |
| 1107 command defines the number and type of arguments it passes to the | |
| 1108 application (on error they are not sent). */ | |
| 1109 | |
| 1110 static void | |
| 1111 silc_command_reply(SilcClient client, SilcClientConnection conn, | |
| 1112 SilcCommandPayload cmd_payload, bool success, | |
| 1113 SilcCommand command, SilcStatus status, ...) | |
| 1114 { | |
| 1115 GaimConnection *gc = client->application; | |
| 1116 SilcGaim sg = gc->proto_data; | |
| 1117 GaimConversation *convo; | |
| 1118 va_list vp; | |
| 1119 | |
| 1120 va_start(vp, status); | |
| 1121 | |
| 1122 switch (command) { | |
| 1123 case SILC_COMMAND_JOIN: | |
| 1124 { | |
| 1125 SilcChannelEntry channel_entry; | |
| 1126 | |
| 1127 if (!success) { | |
| 1128 gaim_notify_error(gc, _("Join Chat"), _("Cannot join channel"), | |
| 1129 silc_get_status_message(status)); | |
| 1130 return; | |
| 1131 } | |
| 1132 | |
| 1133 (void)va_arg(vp, char *); | |
| 1134 channel_entry = va_arg(vp, SilcChannelEntry); | |
| 1135 | |
| 1136 /* Resolve users on channel */ | |
| 1137 silc_client_get_clients_by_channel(client, conn, channel_entry, | |
| 1138 silcgaim_chat_join_done, | |
| 1139 channel_entry); | |
| 1140 } | |
| 1141 break; | |
| 1142 | |
| 1143 case SILC_COMMAND_LEAVE: | |
| 1144 break; | |
| 1145 | |
| 1146 case SILC_COMMAND_USERS: | |
| 1147 break; | |
| 1148 | |
| 1149 case SILC_COMMAND_WHOIS: | |
| 1150 { | |
| 1151 SilcUInt32 idle, mode; | |
| 1152 SilcBuffer channels, user_modes; | |
| 1153 SilcClientEntry client_entry; | |
|
11531
bf763a1b2454
[gaim-migrate @ 13780]
Luke Schierer <lschiere@pidgin.im>
parents:
11522
diff
changeset
|
1154 char *buf, tmp[1024], *tmp2; |
| 9488 | 1155 char *moodstr, *statusstr, *contactstr, *langstr, *devicestr, *tzstr, *geostr; |
| 8849 | 1156 GString *s; |
| 1157 | |
| 1158 if (!success) { | |
| 1159 gaim_notify_error(gc, _("User Information"), | |
| 9488 | 1160 _("Cannot get user information"), |
| 1161 silc_get_status_message(status)); | |
| 8849 | 1162 break; |
| 1163 } | |
| 1164 | |
| 1165 client_entry = va_arg(vp, SilcClientEntry); | |
| 1166 if (!client_entry->nickname) | |
| 1167 break; | |
| 1168 (void)va_arg(vp, char *); | |
| 1169 (void)va_arg(vp, char *); | |
| 1170 (void)va_arg(vp, char *); | |
| 1171 channels = va_arg(vp, SilcBuffer); | |
| 1172 mode = va_arg(vp, SilcUInt32); | |
| 1173 idle = va_arg(vp, SilcUInt32); | |
| 1174 (void)va_arg(vp, unsigned char *); | |
| 1175 user_modes = va_arg(vp, SilcBuffer); | |
| 1176 | |
| 1177 s = g_string_new(""); | |
|
10732
c4cb90065e1d
[gaim-migrate @ 12334]
Luke Schierer <lschiere@pidgin.im>
parents:
10589
diff
changeset
|
1178 tmp2 = g_markup_escape_text(client_entry->nickname, -1); |
| 9488 | 1179 g_string_append_printf(s, "<b>%s:</b> %s", _("Nickname"), tmp2); |
| 1180 g_free(tmp2); | |
| 1181 if (client_entry->realname) { | |
|
10732
c4cb90065e1d
[gaim-migrate @ 12334]
Luke Schierer <lschiere@pidgin.im>
parents:
10589
diff
changeset
|
1182 tmp2 = g_markup_escape_text(client_entry->realname, -1); |
|
13545
cfc2f7fcb3dd
[gaim-migrate @ 15922]
Richard Laager <rlaager@wiktel.com>
parents:
13446
diff
changeset
|
1183 g_string_append_printf(s, "<br><b>%s:</b> %s", _("Real Name"), tmp2); |
| 9488 | 1184 g_free(tmp2); |
| 1185 } | |
| 1186 if (client_entry->username) { | |
|
10732
c4cb90065e1d
[gaim-migrate @ 12334]
Luke Schierer <lschiere@pidgin.im>
parents:
10589
diff
changeset
|
1187 tmp2 = g_markup_escape_text(client_entry->username, -1); |
| 9488 | 1188 if (client_entry->hostname) |
| 1189 g_string_append_printf(s, "<br><b>%s:</b> %s@%s", _("Username"), tmp2, client_entry->hostname); | |
| 1190 else | |
| 1191 g_string_append_printf(s, "<br><b>%s:</b> %s", _("Username"), tmp2); | |
| 1192 g_free(tmp2); | |
| 1193 } | |
| 1194 | |
| 1195 if (client_entry->mode) { | |
| 1196 g_string_append_printf(s, "<br><b>%s:</b> ", _("User Modes")); | |
| 1197 memset(tmp, 0, sizeof(tmp)); | |
| 1198 silcgaim_get_umode_string(client_entry->mode, | |
| 1199 tmp, sizeof(tmp) - strlen(tmp)); | |
| 1200 g_string_append_printf(s, "%s", tmp); | |
| 1201 } | |
| 1202 | |
| 1203 silcgaim_parse_attrs(client_entry->attrs, &moodstr, &statusstr, &contactstr, &langstr, &devicestr, &tzstr, &geostr); | |
| 1204 if (moodstr) { | |
| 1205 g_string_append_printf(s, "<br><b>%s:</b> %s", _("Mood"), moodstr); | |
| 1206 g_free(moodstr); | |
| 1207 } | |
| 1208 | |
| 1209 if (statusstr) { | |
|
10732
c4cb90065e1d
[gaim-migrate @ 12334]
Luke Schierer <lschiere@pidgin.im>
parents:
10589
diff
changeset
|
1210 tmp2 = g_markup_escape_text(statusstr, -1); |
| 9488 | 1211 g_string_append_printf(s, "<br><b>%s:</b> %s", _("Status Text"), tmp2); |
| 1212 g_free(statusstr); | |
| 1213 g_free(tmp2); | |
| 1214 } | |
| 1215 | |
| 1216 if (contactstr) { | |
| 1217 g_string_append_printf(s, "<br><b>%s:</b> %s", _("Preferred Contact"), contactstr); | |
| 1218 g_free(contactstr); | |
| 1219 } | |
| 1220 | |
| 1221 if (langstr) { | |
| 1222 g_string_append_printf(s, "<br><b>%s:</b> %s", _("Preferred Language"), langstr); | |
| 1223 g_free(langstr); | |
| 1224 } | |
| 1225 | |
| 1226 if (devicestr) { | |
| 1227 g_string_append_printf(s, "<br><b>%s:</b> %s", _("Device"), devicestr); | |
| 1228 g_free(devicestr); | |
| 1229 } | |
| 1230 | |
| 1231 if (tzstr) { | |
| 1232 g_string_append_printf(s, "<br><b>%s:</b> %s", _("Timezone"), tzstr); | |
| 1233 g_free(tzstr); | |
| 1234 } | |
| 1235 | |
| 1236 if (geostr) { | |
| 1237 g_string_append_printf(s, "<br><b>%s:</b> %s", _("Geolocation"), geostr); | |
| 1238 g_free(geostr); | |
| 1239 } | |
| 1240 | |
| 8849 | 1241 if (client_entry->server) |
| 9488 | 1242 g_string_append_printf(s, "<br><b>%s:</b> %s", _("Server"), client_entry->server); |
| 8849 | 1243 |
| 1244 if (channels && user_modes) { | |
| 1245 SilcUInt32 *umodes; | |
| 1246 SilcDList list = | |
| 1247 silc_channel_payload_parse_list(channels->data, | |
| 9488 | 1248 channels->len); |
| 8849 | 1249 if (list && silc_get_mode_list(user_modes, |
| 9488 | 1250 silc_dlist_count(list), |
| 1251 &umodes)) { | |
| 8849 | 1252 SilcChannelPayload entry; |
| 1253 int i = 0; | |
| 1254 | |
| 9488 | 1255 g_string_append_printf(s, "<br><b>%s:</b> ", _("Currently on")); |
| 8849 | 1256 memset(tmp, 0, sizeof(tmp)); |
| 1257 silc_dlist_start(list); | |
| 1258 while ((entry = silc_dlist_get(list)) | |
| 9488 | 1259 != SILC_LIST_END) { |
| 8849 | 1260 SilcUInt32 name_len; |
| 1261 char *m = silc_client_chumode_char(umodes[i++]); | |
| 11488 | 1262 char *name = (char *)silc_channel_get_name(entry, &name_len); |
| 8849 | 1263 if (m) |
| 1264 silc_strncat(tmp, sizeof(tmp) - 1, m, strlen(m)); | |
| 1265 silc_strncat(tmp, sizeof(tmp) - 1, name, name_len); | |
| 1266 silc_strncat(tmp, sizeof(tmp) - 1, " ", 1); | |
| 1267 silc_free(m); | |
| 1268 | |
| 1269 } | |
|
10732
c4cb90065e1d
[gaim-migrate @ 12334]
Luke Schierer <lschiere@pidgin.im>
parents:
10589
diff
changeset
|
1270 tmp2 = g_markup_escape_text(tmp, -1); |
| 9488 | 1271 g_string_append_printf(s, "%s", tmp2); |
| 1272 g_free(tmp2); | |
| 8849 | 1273 silc_free(umodes); |
| 1274 } | |
| 1275 } | |
| 1276 | |
| 1277 if (client_entry->public_key) { | |
| 1278 char *fingerprint, *babbleprint; | |
| 1279 unsigned char *pk; | |
| 1280 SilcUInt32 pk_len; | |
| 1281 pk = silc_pkcs_public_key_encode(client_entry->public_key, &pk_len); | |
| 1282 fingerprint = silc_hash_fingerprint(NULL, pk, pk_len); | |
| 1283 babbleprint = silc_hash_babbleprint(NULL, pk, pk_len); | |
| 9488 | 1284 g_string_append_printf(s, "<br><b>%s:</b><br>%s", _("Public Key Fingerprint"), fingerprint); |
| 1285 g_string_append_printf(s, "<br><b>%s:</b><br>%s", _("Public Key Babbleprint"), babbleprint); | |
| 8849 | 1286 silc_free(fingerprint); |
| 1287 silc_free(babbleprint); | |
| 1288 silc_free(pk); | |
| 1289 } | |
| 1290 | |
| 1291 buf = g_string_free(s, FALSE); | |
| 1292 #if 0 /* XXX for now, let's not show attrs here */ | |
| 1293 if (client_entry->attrs) | |
| 11201 | 1294 gaim_request_action(gc, _("User Information"), |
| 9488 | 1295 _("User Information"), |
| 1296 buf, 1, client_entry, 2, | |
| 1297 _("OK"), G_CALLBACK(silcgaim_whois_more), | |
|
12603
e4e47871c373
[gaim-migrate @ 14938]
Richard Laager <rlaager@wiktel.com>
parents:
12217
diff
changeset
|
1298 _("_More..."), G_CALLBACK(silcgaim_whois_more)); |
| 8849 | 1299 else |
| 1300 #endif | |
|
11533
c9b815aeddc1
[gaim-migrate @ 13782]
Richard Laager <rlaager@wiktel.com>
parents:
11531
diff
changeset
|
1301 gaim_notify_userinfo(gc, client_entry->nickname, buf, NULL, NULL); |
| 9488 | 1302 g_free(buf); |
| 1303 } | |
| 1304 break; | |
| 1305 | |
| 1306 case SILC_COMMAND_WHOWAS: | |
| 1307 { | |
| 1308 SilcClientEntry client_entry; | |
|
11531
bf763a1b2454
[gaim-migrate @ 13780]
Luke Schierer <lschiere@pidgin.im>
parents:
11522
diff
changeset
|
1309 char *buf, *nickname, *realname, *username, *tmp; |
| 9488 | 1310 GString *s; |
| 1311 | |
| 1312 if (!success) { | |
| 1313 gaim_notify_error(gc, _("User Information"), | |
| 1314 _("Cannot get user information"), | |
| 1315 silc_get_status_message(status)); | |
| 1316 break; | |
| 1317 } | |
| 1318 | |
| 1319 client_entry = va_arg(vp, SilcClientEntry); | |
| 1320 nickname = va_arg(vp, char *); | |
| 1321 username = va_arg(vp, char *); | |
| 1322 realname = va_arg(vp, char *); | |
| 1323 if (!nickname) | |
| 1324 break; | |
| 1325 | |
| 1326 s = g_string_new(""); | |
|
10732
c4cb90065e1d
[gaim-migrate @ 12334]
Luke Schierer <lschiere@pidgin.im>
parents:
10589
diff
changeset
|
1327 tmp = g_markup_escape_text(nickname, -1); |
| 9488 | 1328 g_string_append_printf(s, "<b>%s:</b> %s", _("Nickname"), tmp); |
| 1329 g_free(tmp); | |
| 1330 if (realname) { | |
|
10732
c4cb90065e1d
[gaim-migrate @ 12334]
Luke Schierer <lschiere@pidgin.im>
parents:
10589
diff
changeset
|
1331 tmp = g_markup_escape_text(realname, -1); |
|
13545
cfc2f7fcb3dd
[gaim-migrate @ 15922]
Richard Laager <rlaager@wiktel.com>
parents:
13446
diff
changeset
|
1332 g_string_append_printf(s, "<br><b>%s:</b> %s", _("Real Name"), tmp); |
| 9488 | 1333 g_free(tmp); |
| 1334 } | |
| 1335 if (username) { | |
|
10732
c4cb90065e1d
[gaim-migrate @ 12334]
Luke Schierer <lschiere@pidgin.im>
parents:
10589
diff
changeset
|
1336 tmp = g_markup_escape_text(username, -1); |
| 9488 | 1337 if (client_entry && client_entry->hostname) |
| 1338 g_string_append_printf(s, "<br><b>%s:</b> %s@%s", _("Username"), tmp, client_entry->hostname); | |
| 1339 else | |
| 1340 g_string_append_printf(s, "<br><b>%s:</b> %s", _("Username"), tmp); | |
| 1341 g_free(tmp); | |
| 1342 } | |
| 1343 if (client_entry && client_entry->server) | |
| 1344 g_string_append_printf(s, "<br><b>%s:</b> %s", _("Server"), client_entry->server); | |
| 1345 | |
| 1346 | |
| 1347 if (client_entry && client_entry->public_key) { | |
| 1348 char *fingerprint, *babbleprint; | |
| 1349 unsigned char *pk; | |
| 1350 SilcUInt32 pk_len; | |
| 1351 pk = silc_pkcs_public_key_encode(client_entry->public_key, &pk_len); | |
| 1352 fingerprint = silc_hash_fingerprint(NULL, pk, pk_len); | |
| 1353 babbleprint = silc_hash_babbleprint(NULL, pk, pk_len); | |
| 1354 g_string_append_printf(s, "<br><b>%s:</b><br>%s", _("Public Key Fingerprint"), fingerprint); | |
| 1355 g_string_append_printf(s, "<br><b>%s:</b><br>%s", _("Public Key Babbleprint"), babbleprint); | |
| 1356 silc_free(fingerprint); | |
| 1357 silc_free(babbleprint); | |
| 1358 silc_free(pk); | |
| 1359 } | |
| 1360 | |
| 1361 buf = g_string_free(s, FALSE); | |
| 13446 | 1362 gaim_notify_userinfo(gc, nickname, buf, NULL, NULL); |
| 8849 | 1363 g_free(buf); |
| 1364 } | |
| 1365 break; | |
| 1366 | |
| 1367 case SILC_COMMAND_DETACH: | |
| 1368 if (!success) { | |
| 1369 gaim_notify_error(gc, _("Detach From Server"), _("Cannot detach"), | |
| 1370 silc_get_status_message(status)); | |
| 1371 return; | |
| 1372 } | |
| 1373 break; | |
| 1374 | |
| 1375 case SILC_COMMAND_TOPIC: | |
| 1376 { | |
| 1377 SilcChannelEntry channel; | |
| 1378 | |
| 1379 if (!success) { | |
| 1380 gaim_notify_error(gc, _("Topic"), _("Cannot set topic"), | |
| 1381 silc_get_status_message(status)); | |
| 1382 return; | |
| 1383 } | |
| 1384 | |
| 1385 channel = va_arg(vp, SilcChannelEntry); | |
| 1386 | |
| 11338 | 1387 convo = gaim_find_conversation_with_account(GAIM_CONV_TYPE_CHAT, |
| 10246 | 1388 channel->channel_name, sg->account); |
| 9353 | 1389 if (!convo) { |
| 1390 gaim_debug_error("silc", "Got a topic for %s, which doesn't exist\n", | |
| 1391 channel->channel_name); | |
| 8849 | 1392 break; |
| 9353 | 1393 } |
| 1394 | |
| 8849 | 1395 /* Set topic */ |
| 1396 if (channel->topic) | |
| 1397 gaim_conv_chat_set_topic(GAIM_CONV_CHAT(convo), NULL, channel->topic); | |
| 1398 } | |
| 1399 break; | |
| 1400 | |
| 9353 | 1401 case SILC_COMMAND_NICK: |
| 1402 { | |
| 1403 /* I don't think we should need to do this because the server should | |
| 1404 * be sending a SILC_NOTIFY_TYPE_NICK_CHANGE when we change our own | |
| 1405 * nick, but it isn't, so we deal with it here instead. Stu. */ | |
| 1406 SilcClientEntry local_entry; | |
| 1407 SilcHashTableList htl; | |
| 1408 SilcChannelUser chu; | |
| 1409 const char *oldnick; | |
| 1410 | |
| 1411 if (!success) { | |
| 9488 | 1412 gaim_notify_error(gc, _("Nick"), _("Failed to change nickname"), |
| 1413 silc_get_status_message(status)); | |
| 9353 | 1414 return; |
| 1415 } | |
| 1416 | |
| 1417 local_entry = va_arg(vp, SilcClientEntry); | |
| 1418 | |
| 1419 /* Change nick on all channels */ | |
| 1420 silc_hash_table_list(local_entry->channels, &htl); | |
| 1421 while (silc_hash_table_get(&htl, NULL, (void *)&chu)) { | |
| 11338 | 1422 convo = gaim_find_conversation_with_account(GAIM_CONV_TYPE_CHAT, |
| 10246 | 1423 chu->channel->channel_name, sg->account); |
| 1424 if (!convo) | |
| 9353 | 1425 continue; |
| 1426 oldnick = gaim_conv_chat_get_nick(GAIM_CONV_CHAT(convo)); | |
|
11500
9fc7d0153332
[gaim-migrate @ 13745]
Richard Laager <rlaager@wiktel.com>
parents:
11488
diff
changeset
|
1427 if (strcmp(oldnick, gaim_normalize(gaim_conversation_get_account(convo), local_entry->nickname))) { |
| 9353 | 1428 gaim_conv_chat_rename_user(GAIM_CONV_CHAT(convo), |
| 1429 oldnick, local_entry->nickname); | |
| 1430 gaim_conv_chat_set_nick(GAIM_CONV_CHAT(convo), local_entry->nickname); | |
| 1431 } | |
| 1432 } | |
| 1433 silc_hash_table_list_reset(&htl); | |
| 9488 | 1434 |
| 1435 gaim_connection_set_display_name(gc, local_entry->nickname); | |
| 9353 | 1436 } |
| 1437 break; | |
| 1438 | |
| 8849 | 1439 case SILC_COMMAND_LIST: |
| 1440 { | |
| 1441 char *topic, *name; | |
| 1442 int usercount; | |
| 1443 GaimRoomlistRoom *room; | |
| 1444 | |
| 1445 if (sg->roomlist_canceled) | |
| 1446 break; | |
| 1447 | |
| 1448 if (!success) { | |
| 10091 | 1449 gaim_notify_error(gc, _("Error"), _("Error retrieving room list"), |
| 8849 | 1450 silc_get_status_message(status)); |
| 1451 gaim_roomlist_set_in_progress(sg->roomlist, FALSE); | |
| 1452 gaim_roomlist_unref(sg->roomlist); | |
| 1453 sg->roomlist = NULL; | |
| 1454 return; | |
| 1455 } | |
| 1456 | |
| 1457 (void)va_arg(vp, SilcChannelEntry); | |
| 1458 name = va_arg(vp, char *); | |
|
10855
2d3a935462aa
[gaim-migrate @ 12530]
Luke Schierer <lschiere@pidgin.im>
parents:
10774
diff
changeset
|
1459 if (!name) { |
|
2d3a935462aa
[gaim-migrate @ 12530]
Luke Schierer <lschiere@pidgin.im>
parents:
10774
diff
changeset
|
1460 gaim_notify_error(gc, _("Roomlist"), _("Cannot get room list"), |
|
2d3a935462aa
[gaim-migrate @ 12530]
Luke Schierer <lschiere@pidgin.im>
parents:
10774
diff
changeset
|
1461 silc_get_status_message(status)); |
|
2d3a935462aa
[gaim-migrate @ 12530]
Luke Schierer <lschiere@pidgin.im>
parents:
10774
diff
changeset
|
1462 gaim_roomlist_set_in_progress(sg->roomlist, FALSE); |
|
2d3a935462aa
[gaim-migrate @ 12530]
Luke Schierer <lschiere@pidgin.im>
parents:
10774
diff
changeset
|
1463 gaim_roomlist_unref(sg->roomlist); |
|
2d3a935462aa
[gaim-migrate @ 12530]
Luke Schierer <lschiere@pidgin.im>
parents:
10774
diff
changeset
|
1464 sg->roomlist = NULL; |
|
2d3a935462aa
[gaim-migrate @ 12530]
Luke Schierer <lschiere@pidgin.im>
parents:
10774
diff
changeset
|
1465 return; |
|
2d3a935462aa
[gaim-migrate @ 12530]
Luke Schierer <lschiere@pidgin.im>
parents:
10774
diff
changeset
|
1466 } |
| 8849 | 1467 topic = va_arg(vp, char *); |
| 1468 usercount = va_arg(vp, int); | |
| 1469 | |
| 1470 room = gaim_roomlist_room_new(GAIM_ROOMLIST_ROOMTYPE_ROOM, name, NULL); | |
| 1471 gaim_roomlist_room_add_field(sg->roomlist, room, name); | |
| 1472 gaim_roomlist_room_add_field(sg->roomlist, room, | |
| 1473 SILC_32_TO_PTR(usercount)); | |
| 1474 gaim_roomlist_room_add_field(sg->roomlist, room, | |
| 1475 topic ? topic : ""); | |
| 1476 gaim_roomlist_room_add(sg->roomlist, room); | |
| 1477 | |
| 1478 if (status == SILC_STATUS_LIST_END || | |
| 1479 status == SILC_STATUS_OK) { | |
| 1480 gaim_roomlist_set_in_progress(sg->roomlist, FALSE); | |
| 1481 gaim_roomlist_unref(sg->roomlist); | |
| 1482 sg->roomlist = NULL; | |
| 1483 } | |
| 1484 } | |
| 1485 break; | |
| 1486 | |
| 1487 case SILC_COMMAND_GETKEY: | |
| 1488 { | |
| 1489 SilcPublicKey public_key; | |
| 1490 | |
| 1491 if (!success) { | |
| 1492 gaim_notify_error(gc, _("Get Public Key"), | |
| 1493 _("Cannot fetch the public key"), | |
| 1494 silc_get_status_message(status)); | |
| 1495 return; | |
| 1496 } | |
| 1497 | |
| 1498 (void)va_arg(vp, SilcUInt32); | |
| 1499 (void)va_arg(vp, void *); | |
| 1500 public_key = va_arg(vp, SilcPublicKey); | |
| 1501 | |
| 1502 if (!public_key) | |
| 1503 gaim_notify_error(gc, _("Get Public Key"), | |
| 1504 _("Cannot fetch the public key"), | |
| 1505 _("No public key was received")); | |
| 1506 } | |
| 1507 break; | |
| 1508 | |
| 1509 case SILC_COMMAND_INFO: | |
| 1510 { | |
| 1511 | |
| 1512 SilcServerEntry server_entry; | |
| 1513 char *server_name; | |
| 1514 char *server_info; | |
| 10774 | 1515 char tmp[256]; |
| 8849 | 1516 |
| 1517 if (!success) { | |
| 1518 gaim_notify_error(gc, _("Server Information"), | |
| 1519 _("Cannot get server information"), | |
| 1520 silc_get_status_message(status)); | |
| 1521 return; | |
| 1522 } | |
| 1523 | |
| 1524 server_entry = va_arg(vp, SilcServerEntry); | |
| 1525 server_name = va_arg(vp, char *); | |
| 1526 server_info = va_arg(vp, char *); | |
| 1527 | |
| 1528 if (server_name && server_info) { | |
| 1529 g_snprintf(tmp, sizeof(tmp), "Server: %s\n%s", | |
| 1530 server_name, server_info); | |
| 10774 | 1531 gaim_notify_info(gc, NULL, _("Server Information"), tmp); |
| 8849 | 1532 } |
| 1533 } | |
| 1534 break; | |
| 1535 | |
| 9488 | 1536 case SILC_COMMAND_STATS: |
| 1537 { | |
| 1538 SilcUInt32 starttime, uptime, my_clients, my_channels, my_server_ops, | |
| 1539 my_router_ops, cell_clients, cell_channels, cell_servers, | |
| 1540 clients, channels, servers, routers, server_ops, router_ops; | |
| 1541 SilcUInt32 buffer_length; | |
| 1542 SilcBufferStruct buf; | |
| 1543 | |
| 1544 unsigned char *server_stats; | |
| 1545 char *msg; | |
| 1546 | |
| 1547 if (!success) { | |
| 1548 gaim_notify_error(gc, _("Server Statistics"), | |
| 9507 | 1549 _("Cannot get server statistics"), |
| 9488 | 1550 silc_get_status_message(status)); |
| 1551 return; | |
| 1552 } | |
| 1553 | |
| 1554 server_stats = va_arg(vp, unsigned char *); | |
| 1555 buffer_length = va_arg(vp, SilcUInt32); | |
| 1556 if (!server_stats || !buffer_length) { | |
| 1557 gaim_notify_error(gc, _("Server Statistics"), | |
| 9645 | 1558 _("No server statistics available"), NULL); |
| 9488 | 1559 break; |
| 1560 } | |
| 1561 silc_buffer_set(&buf, server_stats, buffer_length); | |
| 1562 silc_buffer_unformat(&buf, | |
| 1563 SILC_STR_UI_INT(&starttime), | |
| 1564 SILC_STR_UI_INT(&uptime), | |
| 1565 SILC_STR_UI_INT(&my_clients), | |
| 1566 SILC_STR_UI_INT(&my_channels), | |
| 1567 SILC_STR_UI_INT(&my_server_ops), | |
| 1568 SILC_STR_UI_INT(&my_router_ops), | |
| 1569 SILC_STR_UI_INT(&cell_clients), | |
| 1570 SILC_STR_UI_INT(&cell_channels), | |
| 1571 SILC_STR_UI_INT(&cell_servers), | |
| 1572 SILC_STR_UI_INT(&clients), | |
| 1573 SILC_STR_UI_INT(&channels), | |
| 1574 SILC_STR_UI_INT(&servers), | |
| 1575 SILC_STR_UI_INT(&routers), | |
| 1576 SILC_STR_UI_INT(&server_ops), | |
| 1577 SILC_STR_UI_INT(&router_ops), | |
| 1578 SILC_STR_END); | |
| 1579 | |
| 1580 msg = g_strdup_printf(_("Local server start time: %s\n" | |
| 1581 "Local server uptime: %s\n" | |
| 1582 "Local server clients: %d\n" | |
| 1583 "Local server channels: %d\n" | |
| 1584 "Local server operators: %d\n" | |
| 1585 "Local router operators: %d\n" | |
| 1586 "Local cell clients: %d\n" | |
| 1587 "Local cell channels: %d\n" | |
| 1588 "Local cell servers: %d\n" | |
| 1589 "Total clients: %d\n" | |
| 1590 "Total channels: %d\n" | |
| 1591 "Total servers: %d\n" | |
| 1592 "Total routers: %d\n" | |
| 1593 "Total server operators: %d\n" | |
| 1594 "Total router operators: %d\n"), | |
| 1595 silc_get_time(starttime), | |
| 1596 gaim_str_seconds_to_string((int)uptime), | |
| 1597 (int)my_clients, (int)my_channels, (int)my_server_ops, (int)my_router_ops, | |
| 1598 (int)cell_clients, (int)cell_channels, (int)cell_servers, | |
| 1599 (int)clients, (int)channels, (int)servers, (int)routers, | |
| 1600 (int)server_ops, (int)router_ops); | |
| 1601 | |
| 1602 gaim_notify_info(gc, NULL, | |
| 1603 _("Network Statistics"), msg); | |
| 1604 g_free(msg); | |
| 1605 } | |
| 1606 break; | |
| 1607 | |
| 1608 case SILC_COMMAND_PING: | |
| 1609 { | |
| 1610 if (!success) { | |
| 1611 gaim_notify_error(gc, _("Ping"), _("Ping failed"), | |
| 1612 silc_get_status_message(status)); | |
| 1613 return; | |
| 1614 } | |
| 1615 | |
| 1616 gaim_notify_info(gc, _("Ping"), _("Ping reply received from server"), | |
| 1617 NULL); | |
| 1618 } | |
| 1619 break; | |
| 1620 | |
| 8849 | 1621 case SILC_COMMAND_KILL: |
| 1622 if (!success) { | |
| 1623 gaim_notify_error(gc, _("Kill User"), | |
| 1624 _("Could not kill user"), | |
| 1625 silc_get_status_message(status)); | |
| 1626 return; | |
| 1627 } | |
| 1628 break; | |
| 1629 | |
| 1630 case SILC_COMMAND_CMODE: | |
| 1631 { | |
| 1632 SilcChannelEntry channel_entry; | |
| 1633 SilcBuffer channel_pubkeys; | |
| 1634 | |
| 1635 if (!success) | |
| 1636 return; | |
| 1637 | |
| 1638 channel_entry = va_arg(vp, SilcChannelEntry); | |
| 1639 (void)va_arg(vp, SilcUInt32); | |
| 1640 (void)va_arg(vp, SilcPublicKey); | |
| 1641 channel_pubkeys = va_arg(vp, SilcBuffer); | |
| 1642 | |
| 1643 if (sg->chpk) | |
| 1644 silcgaim_chat_chauth_show(sg, channel_entry, channel_pubkeys); | |
| 1645 } | |
| 1646 break; | |
| 1647 | |
| 1648 default: | |
| 9353 | 1649 if (success) |
| 1650 gaim_debug_info("silc", "Unhandled command: %d (succeeded)\n", command); | |
| 1651 else | |
| 1652 gaim_debug_info("silc", "Unhandled command: %d (failed: %s)\n", command, | |
| 1653 silc_get_status_message(status)); | |
| 8849 | 1654 break; |
| 1655 } | |
| 1656 | |
| 1657 va_end(vp); | |
| 1658 } | |
| 1659 | |
| 1660 | |
| 1661 /* Called to indicate that connection was either successfully established | |
| 1662 or connecting failed. This is also the first time application receives | |
| 9488 | 1663 the SilcClientConnection object which it should save somewhere. |
| 8849 | 1664 If the `success' is FALSE the application must always call the function |
| 1665 silc_client_close_connection. */ | |
| 1666 | |
| 1667 static void | |
| 1668 silc_connected(SilcClient client, SilcClientConnection conn, | |
| 1669 SilcClientConnectionStatus status) | |
| 1670 { | |
| 1671 GaimConnection *gc = client->application; | |
|
13408
b2efa1432708
[gaim-migrate @ 15783]
Richard Laager <rlaager@wiktel.com>
parents:
12885
diff
changeset
|
1672 SilcGaim sg; |
| 8849 | 1673 gboolean reject_watch, block_invites, block_ims; |
| 1674 | |
|
13408
b2efa1432708
[gaim-migrate @ 15783]
Richard Laager <rlaager@wiktel.com>
parents:
12885
diff
changeset
|
1675 if (gc == NULL) { |
| 8849 | 1676 silc_client_close_connection(client, conn); |
| 1677 return; | |
| 1678 } | |
|
13408
b2efa1432708
[gaim-migrate @ 15783]
Richard Laager <rlaager@wiktel.com>
parents:
12885
diff
changeset
|
1679 sg = gc->proto_data; |
| 8849 | 1680 |
| 1681 switch (status) { | |
| 1682 case SILC_CLIENT_CONN_SUCCESS: | |
| 1683 case SILC_CLIENT_CONN_SUCCESS_RESUME: | |
| 1684 gaim_connection_set_state(gc, GAIM_CONNECTED); | |
| 10869 | 1685 |
| 1686 /* Send the server our buddy list */ | |
| 1687 silcgaim_send_buddylist(gc); | |
| 1688 | |
|
10589
0f7452b1f777
[gaim-migrate @ 11994]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10336
diff
changeset
|
1689 g_unlink(silcgaim_session_file(gaim_account_get_username(sg->account))); |
| 8849 | 1690 |
| 1691 /* Send any UMODEs configured for account */ | |
| 1692 reject_watch = gaim_account_get_bool(sg->account, "reject-watch", FALSE); | |
| 1693 block_invites = gaim_account_get_bool(sg->account, "block-invites", FALSE); | |
| 1694 block_ims = gaim_account_get_bool(sg->account, "block-ims", FALSE); | |
| 1695 if (reject_watch || block_invites || block_ims) { | |
| 1696 char m[5]; | |
| 1697 g_snprintf(m, sizeof(m), "+%s%s%s", | |
| 9488 | 1698 reject_watch ? "w" : "", |
| 1699 block_invites ? "I" : "", | |
| 1700 block_ims ? "P" : ""); | |
| 8849 | 1701 silc_client_command_call(sg->client, sg->conn, NULL, |
| 9488 | 1702 "UMODE", m, NULL); |
| 8849 | 1703 } |
| 1704 | |
| 1705 return; | |
| 1706 break; | |
| 1707 case SILC_CLIENT_CONN_ERROR: | |
| 1708 gaim_connection_error(gc, _("Error during connecting to SILC Server")); | |
|
10589
0f7452b1f777
[gaim-migrate @ 11994]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10336
diff
changeset
|
1709 g_unlink(silcgaim_session_file(gaim_account_get_username(sg->account))); |
| 8849 | 1710 break; |
| 1711 | |
| 1712 case SILC_CLIENT_CONN_ERROR_KE: | |
| 1713 gaim_connection_error(gc, _("Key Exchange failed")); | |
| 1714 break; | |
| 1715 | |
| 1716 case SILC_CLIENT_CONN_ERROR_AUTH: | |
| 1717 gaim_connection_error(gc, _("Authentication failed")); | |
| 1718 break; | |
| 1719 | |
| 1720 case SILC_CLIENT_CONN_ERROR_RESUME: | |
| 1721 gaim_connection_error(gc, | |
| 8910 | 1722 _("Resuming detached session failed. " |
| 8849 | 1723 "Press Reconnect to create new connection.")); |
|
10589
0f7452b1f777
[gaim-migrate @ 11994]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10336
diff
changeset
|
1724 g_unlink(silcgaim_session_file(gaim_account_get_username(sg->account))); |
| 8849 | 1725 break; |
| 1726 | |
| 1727 case SILC_CLIENT_CONN_ERROR_TIMEOUT: | |
| 9039 | 1728 gaim_connection_error(gc, _("Connection Timeout")); |
| 8849 | 1729 break; |
| 1730 } | |
| 1731 | |
| 1732 /* Error */ | |
| 1733 sg->conn = NULL; | |
| 1734 silc_client_close_connection(client, conn); | |
| 1735 } | |
| 1736 | |
| 1737 | |
| 1738 /* Called to indicate that connection was disconnected to the server. | |
| 1739 The `status' may tell the reason of the disconnection, and if the | |
| 1740 `message' is non-NULL it may include the disconnection message | |
| 1741 received from server. */ | |
| 1742 | |
| 1743 static void | |
| 1744 silc_disconnected(SilcClient client, SilcClientConnection conn, | |
| 1745 SilcStatus status, const char *message) | |
| 1746 { | |
| 1747 GaimConnection *gc = client->application; | |
| 1748 SilcGaim sg = gc->proto_data; | |
| 1749 | |
| 1750 if (sg->resuming && !sg->detaching) | |
|
10589
0f7452b1f777
[gaim-migrate @ 11994]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10336
diff
changeset
|
1751 g_unlink(silcgaim_session_file(gaim_account_get_username(sg->account))); |
| 8849 | 1752 |
| 1753 sg->conn = NULL; | |
| 1754 | |
| 1755 /* Close the connection */ | |
| 1756 if (!sg->detaching) | |
| 1757 gaim_connection_error(gc, _("Disconnected by server")); | |
| 1758 else | |
| 10740 | 1759 /* TODO: Does this work correctly? Maybe we need to set wants_to_die? */ |
| 1760 gaim_account_disconnect(gaim_connection_get_account(gc)); | |
| 8849 | 1761 } |
| 1762 | |
| 1763 | |
| 1764 typedef struct { | |
| 1765 SilcGetAuthMeth completion; | |
| 1766 void *context; | |
| 1767 } *SilcGaimGetAuthMethod; | |
| 1768 | |
| 1769 /* Callback called when we've received the authentication method information | |
| 1770 from the server after we've requested it. */ | |
| 1771 | |
| 1772 static void silc_get_auth_method_callback(SilcClient client, | |
| 1773 SilcClientConnection conn, | |
| 1774 SilcAuthMethod auth_meth, | |
| 1775 void *context) | |
| 1776 { | |
| 1777 SilcGaimGetAuthMethod internal = context; | |
| 1778 | |
| 1779 switch (auth_meth) { | |
| 1780 case SILC_AUTH_NONE: | |
| 1781 /* No authentication required. */ | |
| 1782 (*internal->completion)(TRUE, auth_meth, NULL, 0, internal->context); | |
| 1783 break; | |
| 1784 | |
| 1785 case SILC_AUTH_PASSWORD: | |
| 1786 /* By returning NULL here the library will ask the passphrase from us | |
| 1787 by calling the silc_ask_passphrase. */ | |
| 1788 (*internal->completion)(TRUE, auth_meth, NULL, 0, internal->context); | |
| 1789 break; | |
| 1790 | |
| 1791 case SILC_AUTH_PUBLIC_KEY: | |
| 1792 /* Do not get the authentication data now, the library will generate | |
| 1793 it using our default key, if we do not provide it here. */ | |
| 1794 (*internal->completion)(TRUE, auth_meth, NULL, 0, internal->context); | |
| 1795 break; | |
| 1796 } | |
| 1797 | |
| 1798 silc_free(internal); | |
| 1799 } | |
| 1800 | |
| 1801 /* Find authentication method and authentication data by hostname and | |
| 1802 port. The hostname may be IP address as well. When the authentication | |
| 1803 method has been resolved the `completion' callback with the found | |
| 1804 authentication method and authentication data is called. The `conn' | |
| 1805 may be NULL. */ | |
| 1806 | |
| 1807 static void | |
| 1808 silc_get_auth_method(SilcClient client, SilcClientConnection conn, | |
| 1809 char *hostname, SilcUInt16 port, | |
| 1810 SilcGetAuthMeth completion, void *context) | |
| 1811 { | |
| 1812 GaimConnection *gc = client->application; | |
| 1813 SilcGaim sg = gc->proto_data; | |
| 1814 SilcGaimGetAuthMethod internal; | |
| 10751 | 1815 const char *password; |
| 8849 | 1816 |
| 1817 /* Progress */ | |
| 1818 if (sg->resuming) | |
| 1819 gaim_connection_update_progress(gc, _("Resuming session"), 4, 5); | |
| 1820 else | |
| 1821 gaim_connection_update_progress(gc, _("Authenticating connection"), 4, 5); | |
| 1822 | |
| 1823 /* Check configuration if we have this connection configured. If we | |
| 1824 have then return that data immediately, as it's faster way. */ | |
| 10336 | 1825 if (gaim_account_get_bool(sg->account, "pubkey-auth", FALSE)) { |
| 1826 completion(TRUE, SILC_AUTH_PUBLIC_KEY, NULL, 0, context); | |
| 1827 return; | |
| 1828 } | |
| 10751 | 1829 password = gaim_connection_get_password(gc); |
| 1830 if (password && *password) { | |
| 11488 | 1831 completion(TRUE, SILC_AUTH_PASSWORD, (unsigned char *)password, strlen(password), context); |
| 8849 | 1832 return; |
| 1833 } | |
| 1834 | |
| 1835 /* Resolve the authentication method from server, as we may not know it. */ | |
| 1836 internal = silc_calloc(1, sizeof(*internal)); | |
| 1837 if (!internal) | |
| 1838 return; | |
| 1839 internal->completion = completion; | |
| 1840 internal->context = context; | |
| 1841 silc_client_request_authentication_method(client, conn, | |
| 1842 silc_get_auth_method_callback, | |
| 1843 internal); | |
| 1844 } | |
| 1845 | |
| 1846 | |
| 1847 /* Verifies received public key. The `conn_type' indicates which entity | |
| 1848 (server, client etc.) has sent the public key. If user decides to trust | |
| 1849 the application may save the key as trusted public key for later | |
| 1850 use. The `completion' must be called after the public key has been | |
| 1851 verified. */ | |
| 1852 | |
| 1853 static void | |
| 1854 silc_verify_public_key(SilcClient client, SilcClientConnection conn, | |
| 1855 SilcSocketType conn_type, unsigned char *pk, | |
| 1856 SilcUInt32 pk_len, SilcSKEPKType pk_type, | |
| 1857 SilcVerifyPublicKey completion, void *context) | |
| 1858 { | |
| 1859 GaimConnection *gc = client->application; | |
| 1860 SilcGaim sg = gc->proto_data; | |
| 1861 | |
| 1862 if (!sg->conn && (conn_type == SILC_SOCKET_TYPE_SERVER || | |
| 1863 conn_type == SILC_SOCKET_TYPE_ROUTER)) { | |
| 1864 /* Progress */ | |
| 1865 if (sg->resuming) | |
| 1866 gaim_connection_update_progress(gc, _("Resuming session"), 3, 5); | |
| 1867 else | |
| 1868 gaim_connection_update_progress(gc, _("Verifying server public key"), | |
| 1869 3, 5); | |
| 1870 } | |
| 1871 | |
| 1872 /* Verify public key */ | |
| 1873 silcgaim_verify_public_key(client, conn, NULL, conn_type, pk, | |
| 1874 pk_len, pk_type, completion, context); | |
| 1875 } | |
| 1876 | |
| 1877 typedef struct { | |
| 1878 SilcAskPassphrase completion; | |
| 1879 void *context; | |
| 1880 } *SilcGaimAskPassphrase; | |
| 1881 | |
| 1882 static void | |
| 1883 silc_ask_passphrase_cb(SilcGaimAskPassphrase internal, const char *passphrase) | |
| 1884 { | |
| 1885 if (!passphrase || !(*passphrase)) | |
| 1886 internal->completion(NULL, 0, internal->context); | |
| 1887 else | |
| 1888 internal->completion((unsigned char *)passphrase, | |
| 1889 strlen(passphrase), internal->context); | |
| 1890 silc_free(internal); | |
| 1891 } | |
| 1892 | |
| 1893 /* Ask (interact, that is) a passphrase from user. The passphrase is | |
| 1894 returned to the library by calling the `completion' callback with | |
| 1895 the `context'. The returned passphrase SHOULD be in UTF-8 encoded, | |
| 1896 if not then the library will attempt to encode. */ | |
| 1897 | |
| 1898 static void | |
| 1899 silc_ask_passphrase(SilcClient client, SilcClientConnection conn, | |
| 1900 SilcAskPassphrase completion, void *context) | |
| 1901 { | |
| 1902 SilcGaimAskPassphrase internal = silc_calloc(1, sizeof(*internal)); | |
| 1903 | |
| 1904 if (!internal) | |
| 1905 return; | |
| 1906 internal->completion = completion; | |
| 1907 internal->context = context; | |
| 11201 | 1908 gaim_request_input(client->application, _("Passphrase"), NULL, |
| 8849 | 1909 _("Passphrase required"), NULL, FALSE, TRUE, NULL, |
| 1910 _("OK"), G_CALLBACK(silc_ask_passphrase_cb), | |
| 1911 _("Cancel"), G_CALLBACK(silc_ask_passphrase_cb), | |
| 1912 internal); | |
| 1913 } | |
| 1914 | |
| 1915 | |
| 1916 /* Notifies application that failure packet was received. This is called | |
| 1917 if there is some protocol active in the client. The `protocol' is the | |
| 1918 protocol context. The `failure' is opaque pointer to the failure | |
| 1919 indication. Note, that the `failure' is protocol dependant and | |
| 1920 application must explicitly cast it to correct type. Usually `failure' | |
| 1921 is 32 bit failure type (see protocol specs for all protocol failure | |
| 1922 types). */ | |
| 1923 | |
| 1924 static void | |
| 1925 silc_failure(SilcClient client, SilcClientConnection conn, | |
| 1926 SilcProtocol protocol, void *failure) | |
| 1927 { | |
| 1928 GaimConnection *gc = client->application; | |
| 1929 char buf[128]; | |
| 1930 | |
| 1931 memset(buf, 0, sizeof(buf)); | |
| 1932 | |
| 1933 if (protocol->protocol->type == SILC_PROTOCOL_CLIENT_KEY_EXCHANGE) { | |
| 1934 SilcSKEStatus status = (SilcSKEStatus)SILC_PTR_TO_32(failure); | |
| 1935 | |
| 1936 if (status == SILC_SKE_STATUS_BAD_VERSION) | |
| 1937 g_snprintf(buf, sizeof(buf), | |
| 1938 _("Failure: Version mismatch, upgrade your client")); | |
| 1939 if (status == SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY) | |
| 1940 g_snprintf(buf, sizeof(buf), | |
| 1941 _("Failure: Remote does not trust/support your public key")); | |
| 1942 if (status == SILC_SKE_STATUS_UNKNOWN_GROUP) | |
| 1943 g_snprintf(buf, sizeof(buf), | |
| 1944 _("Failure: Remote does not support proposed KE group")); | |
| 1945 if (status == SILC_SKE_STATUS_UNKNOWN_CIPHER) | |
| 1946 g_snprintf(buf, sizeof(buf), | |
| 1947 _("Failure: Remote does not support proposed cipher")); | |
| 1948 if (status == SILC_SKE_STATUS_UNKNOWN_PKCS) | |
| 1949 g_snprintf(buf, sizeof(buf), | |
| 1950 _("Failure: Remote does not support proposed PKCS")); | |
| 1951 if (status == SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION) | |
| 1952 g_snprintf(buf, sizeof(buf), | |
| 1953 _("Failure: Remote does not support proposed hash function")); | |
| 1954 if (status == SILC_SKE_STATUS_UNKNOWN_HMAC) | |
| 1955 g_snprintf(buf, sizeof(buf), | |
| 1956 _("Failure: Remote does not support proposed HMAC")); | |
| 1957 if (status == SILC_SKE_STATUS_INCORRECT_SIGNATURE) | |
| 1958 g_snprintf(buf, sizeof(buf), _("Failure: Incorrect signature")); | |
| 1959 if (status == SILC_SKE_STATUS_INVALID_COOKIE) | |
| 1960 g_snprintf(buf, sizeof(buf), _("Failure: Invalid cookie")); | |
| 1961 | |
| 1962 /* Show the error on the progress bar. A more generic error message | |
| 1963 is going to be showed to user after this in the silc_connected. */ | |
| 1964 gaim_connection_update_progress(gc, buf, 2, 5); | |
| 1965 } | |
| 1966 | |
| 1967 if (protocol->protocol->type == SILC_PROTOCOL_CLIENT_CONNECTION_AUTH) { | |
| 1968 SilcUInt32 err = SILC_PTR_TO_32(failure); | |
| 1969 | |
| 1970 if (err == SILC_AUTH_FAILED) | |
| 1971 g_snprintf(buf, sizeof(buf), _("Failure: Authentication failed")); | |
| 1972 | |
| 1973 /* Show the error on the progress bar. A more generic error message | |
| 1974 is going to be showed to user after this in the silc_connected. */ | |
| 1975 gaim_connection_update_progress(gc, buf, 4, 5); | |
| 1976 } | |
| 1977 } | |
| 1978 | |
| 1979 /* Asks whether the user would like to perform the key agreement protocol. | |
| 1980 This is called after we have received an key agreement packet or an | |
| 1981 reply to our key agreement packet. This returns TRUE if the user wants | |
| 1982 the library to perform the key agreement protocol and FALSE if it is not | |
| 1983 desired (application may start it later by calling the function | |
| 1984 silc_client_perform_key_agreement). If TRUE is returned also the | |
| 1985 `completion' and `context' arguments must be set by the application. */ | |
| 1986 | |
| 1987 static bool | |
| 1988 silc_key_agreement(SilcClient client, SilcClientConnection conn, | |
| 1989 SilcClientEntry client_entry, const char *hostname, | |
| 1990 SilcUInt16 port, SilcKeyAgreementCallback *completion, | |
| 1991 void **context) | |
| 1992 { | |
| 1993 silcgaim_buddy_keyagr_request(client, conn, client_entry, hostname, port); | |
| 1994 *completion = NULL; | |
| 1995 *context = NULL; | |
| 1996 return FALSE; | |
| 1997 } | |
| 1998 | |
| 1999 | |
| 2000 /* Notifies application that file transfer protocol session is being | |
| 2001 requested by the remote client indicated by the `client_entry' from | |
| 2002 the `hostname' and `port'. The `session_id' is the file transfer | |
| 2003 session and it can be used to either accept or reject the file | |
| 2004 transfer request, by calling the silc_client_file_receive or | |
| 2005 silc_client_file_close, respectively. */ | |
| 2006 | |
| 2007 static void | |
| 2008 silc_ftp(SilcClient client, SilcClientConnection conn, | |
| 2009 SilcClientEntry client_entry, SilcUInt32 session_id, | |
| 2010 const char *hostname, SilcUInt16 port) | |
| 2011 { | |
| 2012 silcgaim_ftp_request(client, conn, client_entry, session_id, | |
| 2013 hostname, port); | |
| 2014 } | |
| 2015 | |
| 2016 | |
| 2017 /* Delivers SILC session detachment data indicated by `detach_data' to the | |
| 2018 application. If application has issued SILC_COMMAND_DETACH command | |
| 2019 the client session in the SILC network is not quit. The client remains | |
| 2020 in the network but is detached. The detachment data may be used later | |
| 2021 to resume the session in the SILC Network. The appliation is | |
| 2022 responsible of saving the `detach_data', to for example in a file. | |
| 2023 | |
| 2024 The detachment data can be given as argument to the functions | |
| 2025 silc_client_connect_to_server, or silc_client_add_connection when | |
| 2026 creating connection to remote server, inside SilcClientConnectionParams | |
| 2027 structure. If it is provided the client library will attempt to resume | |
| 2028 the session in the network. After the connection is created | |
| 2029 successfully, the application is responsible of setting the user | |
| 2030 interface for user into the same state it was before detaching (showing | |
| 2031 same channels, channel modes, etc). It can do this by fetching the | |
| 2032 information (like joined channels) from the client library. */ | |
| 2033 | |
| 2034 static void | |
| 2035 silc_detach(SilcClient client, SilcClientConnection conn, | |
| 2036 const unsigned char *detach_data, SilcUInt32 detach_data_len) | |
| 2037 { | |
| 2038 GaimConnection *gc = client->application; | |
| 2039 SilcGaim sg = gc->proto_data; | |
| 2040 const char *file; | |
| 2041 | |
| 2042 /* Save the detachment data to file. */ | |
| 2043 file = silcgaim_session_file(gaim_account_get_username(sg->account)); | |
|
10589
0f7452b1f777
[gaim-migrate @ 11994]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10336
diff
changeset
|
2044 g_unlink(file); |
| 11488 | 2045 silc_file_writefile(file, (char *)detach_data, detach_data_len); |
| 8849 | 2046 } |
| 2047 | |
| 2048 SilcClientOperations ops = { | |
| 2049 silc_say, | |
| 2050 silc_channel_message, | |
| 2051 silc_private_message, | |
| 2052 silc_notify, | |
| 2053 silc_command, | |
| 2054 silc_command_reply, | |
| 2055 silc_connected, | |
| 2056 silc_disconnected, | |
| 2057 silc_get_auth_method, | |
| 2058 silc_verify_public_key, | |
| 2059 silc_ask_passphrase, | |
| 2060 silc_failure, | |
| 2061 silc_key_agreement, | |
| 2062 silc_ftp, | |
| 2063 silc_detach | |
| 2064 }; |
