| 17 |
17 |
| 18 */ |
18 */ |
| 19 |
19 |
| 20 #include "silcincludes.h" |
20 #include "silcincludes.h" |
| 21 #include "silcclient.h" |
21 #include "silcclient.h" |
| 22 #include "silcgaim.h" |
22 #include "silcpurple.h" |
| 23 #include "wb.h" |
23 #include "wb.h" |
| 24 |
24 |
| 25 /***************************** Key Agreement *********************************/ |
25 /***************************** Key Agreement *********************************/ |
| 26 |
26 |
| 27 static void |
27 static void |
| 28 silcgaim_buddy_keyagr(GaimBlistNode *node, gpointer data); |
28 silcpurple_buddy_keyagr(PurpleBlistNode *node, gpointer data); |
| 29 |
29 |
| 30 static void |
30 static void |
| 31 silcgaim_buddy_keyagr_do(GaimConnection *gc, const char *name, |
31 silcpurple_buddy_keyagr_do(PurpleConnection *gc, const char *name, |
| 32 gboolean force_local); |
32 gboolean force_local); |
| 33 |
33 |
| 34 typedef struct { |
34 typedef struct { |
| 35 char *nick; |
35 char *nick; |
| 36 GaimConnection *gc; |
36 PurpleConnection *gc; |
| 37 } *SilcGaimResolve; |
37 } *SilcPurpleResolve; |
| 38 |
38 |
| 39 static void |
39 static void |
| 40 silcgaim_buddy_keyagr_resolved(SilcClient client, |
40 silcpurple_buddy_keyagr_resolved(SilcClient client, |
| 41 SilcClientConnection conn, |
41 SilcClientConnection conn, |
| 42 SilcClientEntry *clients, |
42 SilcClientEntry *clients, |
| 43 SilcUInt32 clients_count, |
43 SilcUInt32 clients_count, |
| 44 void *context) |
44 void *context) |
| 45 { |
45 { |
| 46 GaimConnection *gc = client->application; |
46 PurpleConnection *gc = client->application; |
| 47 SilcGaimResolve r = context; |
47 SilcPurpleResolve r = context; |
| 48 char tmp[256]; |
48 char tmp[256]; |
| 49 |
49 |
| 50 if (!clients) { |
50 if (!clients) { |
| 51 g_snprintf(tmp, sizeof(tmp), |
51 g_snprintf(tmp, sizeof(tmp), |
| 52 _("User %s is not present in the network"), r->nick); |
52 _("User %s is not present in the network"), r->nick); |
| 53 gaim_notify_error(gc, _("Key Agreement"), |
53 purple_notify_error(gc, _("Key Agreement"), |
| 54 _("Cannot perform the key agreement"), tmp); |
54 _("Cannot perform the key agreement"), tmp); |
| 55 silc_free(r->nick); |
55 silc_free(r->nick); |
| 56 silc_free(r); |
56 silc_free(r); |
| 57 return; |
57 return; |
| 58 } |
58 } |
| 59 |
59 |
| 60 silcgaim_buddy_keyagr_do(gc, r->nick, FALSE); |
60 silcpurple_buddy_keyagr_do(gc, r->nick, FALSE); |
| 61 silc_free(r->nick); |
61 silc_free(r->nick); |
| 62 silc_free(r); |
62 silc_free(r); |
| 63 } |
63 } |
| 64 |
64 |
| 65 typedef struct { |
65 typedef struct { |
| 66 gboolean responder; |
66 gboolean responder; |
| 67 } *SilcGaimKeyAgr; |
67 } *SilcPurpleKeyAgr; |
| 68 |
68 |
| 69 static void |
69 static void |
| 70 silcgaim_buddy_keyagr_cb(SilcClient client, |
70 silcpurple_buddy_keyagr_cb(SilcClient client, |
| 71 SilcClientConnection conn, |
71 SilcClientConnection conn, |
| 72 SilcClientEntry client_entry, |
72 SilcClientEntry client_entry, |
| 73 SilcKeyAgreementStatus status, |
73 SilcKeyAgreementStatus status, |
| 74 SilcSKEKeyMaterial *key, |
74 SilcSKEKeyMaterial *key, |
| 75 void *context) |
75 void *context) |
| 76 { |
76 { |
| 77 GaimConnection *gc = client->application; |
77 PurpleConnection *gc = client->application; |
| 78 SilcGaim sg = gc->proto_data; |
78 SilcPurple sg = gc->proto_data; |
| 79 SilcGaimKeyAgr a = context; |
79 SilcPurpleKeyAgr a = context; |
| 80 |
80 |
| 81 if (!sg->conn) |
81 if (!sg->conn) |
| 82 return; |
82 return; |
| 83 |
83 |
| 84 switch (status) { |
84 switch (status) { |
| 85 case SILC_KEY_AGREEMENT_OK: |
85 case SILC_KEY_AGREEMENT_OK: |
| 86 { |
86 { |
| 87 GaimConversation *convo; |
87 PurpleConversation *convo; |
| 88 char tmp[128]; |
88 char tmp[128]; |
| 89 |
89 |
| 90 /* Set the private key for this client */ |
90 /* Set the private key for this client */ |
| 91 silc_client_del_private_message_key(client, conn, client_entry); |
91 silc_client_del_private_message_key(client, conn, client_entry); |
| 92 silc_client_add_private_message_key_ske(client, conn, client_entry, |
92 silc_client_add_private_message_key_ske(client, conn, client_entry, |
| 93 NULL, NULL, key, a->responder); |
93 NULL, NULL, key, a->responder); |
| 94 silc_ske_free_key_material(key); |
94 silc_ske_free_key_material(key); |
| 95 |
95 |
| 96 |
96 |
| 97 /* Open IM window */ |
97 /* Open IM window */ |
| 98 convo = gaim_find_conversation_with_account(GAIM_CONV_TYPE_IM, |
98 convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, |
| 99 client_entry->nickname, sg->account); |
99 client_entry->nickname, sg->account); |
| 100 if (convo) { |
100 if (convo) { |
| 101 /* we don't have windows in the core anymore...but we may want to |
101 /* we don't have windows in the core anymore...but we may want to |
| 102 * provide some method for asking the UI to show the window |
102 * provide some method for asking the UI to show the window |
| 103 gaim_conv_window_show(gaim_conversation_get_window(convo)); |
103 purple_conv_window_show(purple_conversation_get_window(convo)); |
| 104 */ |
104 */ |
| 105 } else { |
105 } else { |
| 106 convo = gaim_conversation_new(GAIM_CONV_TYPE_IM, sg->account, |
106 convo = purple_conversation_new(PURPLE_CONV_TYPE_IM, sg->account, |
| 107 client_entry->nickname); |
107 client_entry->nickname); |
| 108 } |
108 } |
| 109 g_snprintf(tmp, sizeof(tmp), "%s [private key]", client_entry->nickname); |
109 g_snprintf(tmp, sizeof(tmp), "%s [private key]", client_entry->nickname); |
| 110 gaim_conversation_set_title(convo, tmp); |
110 purple_conversation_set_title(convo, tmp); |
| 111 } |
111 } |
| 112 break; |
112 break; |
| 113 |
113 |
| 114 case SILC_KEY_AGREEMENT_ERROR: |
114 case SILC_KEY_AGREEMENT_ERROR: |
| 115 gaim_notify_error(gc, _("Key Agreement"), |
115 purple_notify_error(gc, _("Key Agreement"), |
| 116 _("Error occurred during key agreement"), NULL); |
116 _("Error occurred during key agreement"), NULL); |
| 117 break; |
117 break; |
| 118 |
118 |
| 119 case SILC_KEY_AGREEMENT_FAILURE: |
119 case SILC_KEY_AGREEMENT_FAILURE: |
| 120 gaim_notify_error(gc, _("Key Agreement"), _("Key Agreement failed"), NULL); |
120 purple_notify_error(gc, _("Key Agreement"), _("Key Agreement failed"), NULL); |
| 121 break; |
121 break; |
| 122 |
122 |
| 123 case SILC_KEY_AGREEMENT_TIMEOUT: |
123 case SILC_KEY_AGREEMENT_TIMEOUT: |
| 124 gaim_notify_error(gc, _("Key Agreement"), |
124 purple_notify_error(gc, _("Key Agreement"), |
| 125 _("Timeout during key agreement"), NULL); |
125 _("Timeout during key agreement"), NULL); |
| 126 break; |
126 break; |
| 127 |
127 |
| 128 case SILC_KEY_AGREEMENT_ABORTED: |
128 case SILC_KEY_AGREEMENT_ABORTED: |
| 129 gaim_notify_error(gc, _("Key Agreement"), |
129 purple_notify_error(gc, _("Key Agreement"), |
| 130 _("Key agreement was aborted"), NULL); |
130 _("Key agreement was aborted"), NULL); |
| 131 break; |
131 break; |
| 132 |
132 |
| 133 case SILC_KEY_AGREEMENT_ALREADY_STARTED: |
133 case SILC_KEY_AGREEMENT_ALREADY_STARTED: |
| 134 gaim_notify_error(gc, _("Key Agreement"), |
134 purple_notify_error(gc, _("Key Agreement"), |
| 135 _("Key agreement is already started"), NULL); |
135 _("Key agreement is already started"), NULL); |
| 136 break; |
136 break; |
| 137 |
137 |
| 138 case SILC_KEY_AGREEMENT_SELF_DENIED: |
138 case SILC_KEY_AGREEMENT_SELF_DENIED: |
| 139 gaim_notify_error(gc, _("Key Agreement"), |
139 purple_notify_error(gc, _("Key Agreement"), |
| 140 _("Key agreement cannot be started with yourself"), |
140 _("Key agreement cannot be started with yourself"), |
| 141 NULL); |
141 NULL); |
| 142 break; |
142 break; |
| 143 |
143 |
| 144 default: |
144 default: |
| 267 if (!ai) |
267 if (!ai) |
| 268 goto out; |
268 goto out; |
| 269 ai->responder = FALSE; |
269 ai->responder = FALSE; |
| 270 silc_client_perform_key_agreement(a->client, a->conn, client_entry, |
270 silc_client_perform_key_agreement(a->client, a->conn, client_entry, |
| 271 a->hostname, a->port, |
271 a->hostname, a->port, |
| 272 silcgaim_buddy_keyagr_cb, ai); |
272 silcpurple_buddy_keyagr_cb, ai); |
| 273 } else { |
273 } else { |
| 274 /* Send request. Force us as the point of connection since requestor |
274 /* Send request. Force us as the point of connection since requestor |
| 275 did not provide the point of connection. */ |
275 did not provide the point of connection. */ |
| 276 silcgaim_buddy_keyagr_do(a->client->application, |
276 silcpurple_buddy_keyagr_do(a->client->application, |
| 277 client_entry->nickname, TRUE); |
277 client_entry->nickname, TRUE); |
| 278 } |
278 } |
| 279 |
279 |
| 280 out: |
280 out: |
| 281 silc_free(a->hostname); |
281 silc_free(a->hostname); |
| 282 silc_free(a); |
282 silc_free(a); |
| 283 } |
283 } |
| 284 |
284 |
| 285 void silcgaim_buddy_keyagr_request(SilcClient client, |
285 void silcpurple_buddy_keyagr_request(SilcClient client, |
| 286 SilcClientConnection conn, |
286 SilcClientConnection conn, |
| 287 SilcClientEntry client_entry, |
287 SilcClientEntry client_entry, |
| 288 const char *hostname, SilcUInt16 port) |
288 const char *hostname, SilcUInt16 port) |
| 289 { |
289 { |
| 290 char tmp[128], tmp2[128]; |
290 char tmp[128], tmp2[128]; |
| 291 SilcGaimKeyAgrAsk a; |
291 SilcPurpleKeyAgrAsk a; |
| 292 |
292 |
| 293 g_snprintf(tmp, sizeof(tmp), |
293 g_snprintf(tmp, sizeof(tmp), |
| 294 _("Key agreement request received from %s. Would you like to " |
294 _("Key agreement request received from %s. Would you like to " |
| 295 "perform the key agreement?"), client_entry->nickname); |
295 "perform the key agreement?"), client_entry->nickname); |
| 296 if (hostname) |
296 if (hostname) |
| 306 a->client_id = *client_entry->id; |
306 a->client_id = *client_entry->id; |
| 307 if (hostname) |
307 if (hostname) |
| 308 a->hostname = strdup(hostname); |
308 a->hostname = strdup(hostname); |
| 309 a->port = port; |
309 a->port = port; |
| 310 |
310 |
| 311 gaim_request_action(client->application, _("Key Agreement Request"), tmp, |
311 purple_request_action(client->application, _("Key Agreement Request"), tmp, |
| 312 hostname ? tmp2 : NULL, 1, a, 2, |
312 hostname ? tmp2 : NULL, 1, a, 2, |
| 313 _("Yes"), G_CALLBACK(silcgaim_buddy_keyagr_request_cb), |
313 _("Yes"), G_CALLBACK(silcpurple_buddy_keyagr_request_cb), |
| 314 _("No"), G_CALLBACK(silcgaim_buddy_keyagr_request_cb)); |
314 _("No"), G_CALLBACK(silcpurple_buddy_keyagr_request_cb)); |
| 315 } |
315 } |
| 316 |
316 |
| 317 static void |
317 static void |
| 318 silcgaim_buddy_keyagr(GaimBlistNode *node, gpointer data) |
318 silcpurple_buddy_keyagr(PurpleBlistNode *node, gpointer data) |
| 319 { |
319 { |
| 320 GaimBuddy *buddy; |
320 PurpleBuddy *buddy; |
| 321 |
321 |
| 322 buddy = (GaimBuddy *)node; |
322 buddy = (PurpleBuddy *)node; |
| 323 silcgaim_buddy_keyagr_do(buddy->account->gc, buddy->name, FALSE); |
323 silcpurple_buddy_keyagr_do(buddy->account->gc, buddy->name, FALSE); |
| 324 } |
324 } |
| 325 |
325 |
| 326 |
326 |
| 327 /**************************** Static IM Key **********************************/ |
327 /**************************** Static IM Key **********************************/ |
| 328 |
328 |
| 329 static void |
329 static void |
| 330 silcgaim_buddy_resetkey(GaimBlistNode *node, gpointer data) |
330 silcpurple_buddy_resetkey(PurpleBlistNode *node, gpointer data) |
| 331 { |
331 { |
| 332 GaimBuddy *b; |
332 PurpleBuddy *b; |
| 333 GaimConnection *gc; |
333 PurpleConnection *gc; |
| 334 SilcGaim sg; |
334 SilcPurple sg; |
| 335 char *nickname; |
335 char *nickname; |
| 336 SilcClientEntry *clients; |
336 SilcClientEntry *clients; |
| 337 SilcUInt32 clients_count; |
337 SilcUInt32 clients_count; |
| 338 |
338 |
| 339 g_return_if_fail(GAIM_BLIST_NODE_IS_BUDDY(node)); |
339 g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node)); |
| 340 |
340 |
| 341 b = (GaimBuddy *) node; |
341 b = (PurpleBuddy *) node; |
| 342 gc = gaim_account_get_connection(b->account); |
342 gc = purple_account_get_connection(b->account); |
| 343 sg = gc->proto_data; |
343 sg = gc->proto_data; |
| 344 |
344 |
| 345 if (!silc_parse_userfqdn(b->name, &nickname, NULL)) |
345 if (!silc_parse_userfqdn(b->name, &nickname, NULL)) |
| 346 return; |
346 return; |
| 347 |
347 |
| 459 if (!p) |
459 if (!p) |
| 460 return; |
460 return; |
| 461 p->client = sg->client; |
461 p->client = sg->client; |
| 462 p->conn = sg->conn; |
462 p->conn = sg->conn; |
| 463 p->client_id = *clients[0]->id; |
463 p->client_id = *clients[0]->id; |
| 464 gaim_request_input(gc, _("IM With Password"), NULL, |
464 purple_request_input(gc, _("IM With Password"), NULL, |
| 465 _("Set IM Password"), NULL, FALSE, TRUE, NULL, |
465 _("Set IM Password"), NULL, FALSE, TRUE, NULL, |
| 466 _("OK"), G_CALLBACK(silcgaim_buddy_privkey_cb), |
466 _("OK"), G_CALLBACK(silcpurple_buddy_privkey_cb), |
| 467 _("Cancel"), G_CALLBACK(silcgaim_buddy_privkey_cb), |
467 _("Cancel"), G_CALLBACK(silcpurple_buddy_privkey_cb), |
| 468 p); |
468 p); |
| 469 |
469 |
| 470 silc_free(clients); |
470 silc_free(clients); |
| 471 silc_free(nickname); |
471 silc_free(nickname); |
| 472 } |
472 } |
| 473 |
473 |
| 474 static void |
474 static void |
| 475 silcgaim_buddy_privkey_menu(GaimBlistNode *node, gpointer data) |
475 silcpurple_buddy_privkey_menu(PurpleBlistNode *node, gpointer data) |
| 476 { |
476 { |
| 477 GaimBuddy *buddy; |
477 PurpleBuddy *buddy; |
| 478 GaimConnection *gc; |
478 PurpleConnection *gc; |
| 479 |
479 |
| 480 g_return_if_fail(GAIM_BLIST_NODE_IS_BUDDY(node)); |
480 g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node)); |
| 481 |
481 |
| 482 buddy = (GaimBuddy *) node; |
482 buddy = (PurpleBuddy *) node; |
| 483 gc = gaim_account_get_connection(buddy->account); |
483 gc = purple_account_get_connection(buddy->account); |
| 484 |
484 |
| 485 silcgaim_buddy_privkey(gc, buddy->name); |
485 silcpurple_buddy_privkey(gc, buddy->name); |
| 486 } |
486 } |
| 487 |
487 |
| 488 |
488 |
| 489 /**************************** Get Public Key *********************************/ |
489 /**************************** Get Public Key *********************************/ |
| 490 |
490 |
| 491 typedef struct { |
491 typedef struct { |
| 492 SilcClient client; |
492 SilcClient client; |
| 493 SilcClientConnection conn; |
493 SilcClientConnection conn; |
| 494 SilcClientID client_id; |
494 SilcClientID client_id; |
| 495 } *SilcGaimBuddyGetkey; |
495 } *SilcPurpleBuddyGetkey; |
| 496 |
496 |
| 497 static void |
497 static void |
| 498 silcgaim_buddy_getkey(GaimConnection *gc, const char *name); |
498 silcpurple_buddy_getkey(PurpleConnection *gc, const char *name); |
| 499 |
499 |
| 500 static void |
500 static void |
| 501 silcgaim_buddy_getkey_cb(SilcGaimBuddyGetkey g, |
501 silcpurple_buddy_getkey_cb(SilcPurpleBuddyGetkey g, |
| 502 SilcClientCommandReplyContext cmd) |
502 SilcClientCommandReplyContext cmd) |
| 503 { |
503 { |
| 504 SilcClientEntry client_entry; |
504 SilcClientEntry client_entry; |
| 505 unsigned char *pk; |
505 unsigned char *pk; |
| 506 SilcUInt32 pk_len; |
506 SilcUInt32 pk_len; |
| 507 |
507 |
| 508 /* Get the client entry. */ |
508 /* Get the client entry. */ |
| 509 client_entry = silc_client_get_client_by_id(g->client, g->conn, |
509 client_entry = silc_client_get_client_by_id(g->client, g->conn, |
| 510 &g->client_id); |
510 &g->client_id); |
| 511 if (!client_entry) { |
511 if (!client_entry) { |
| 512 gaim_notify_error(g->client->application, _("Get Public Key"), |
512 purple_notify_error(g->client->application, _("Get Public Key"), |
| 513 _("The remote user is not present in the network any more"), |
513 _("The remote user is not present in the network any more"), |
| 514 NULL); |
514 NULL); |
| 515 silc_free(g); |
515 silc_free(g); |
| 516 return; |
516 return; |
| 517 } |
517 } |
| 591 g->client_id = *clients[0]->id; |
591 g->client_id = *clients[0]->id; |
| 592 silc_client_command_call(client, conn, NULL, "GETKEY", |
592 silc_client_command_call(client, conn, NULL, "GETKEY", |
| 593 clients[0]->nickname, NULL); |
593 clients[0]->nickname, NULL); |
| 594 silc_client_command_pending(conn, SILC_COMMAND_GETKEY, |
594 silc_client_command_pending(conn, SILC_COMMAND_GETKEY, |
| 595 conn->cmd_ident, |
595 conn->cmd_ident, |
| 596 (SilcCommandCb)silcgaim_buddy_getkey_cb, g); |
596 (SilcCommandCb)silcpurple_buddy_getkey_cb, g); |
| 597 silc_free(clients); |
597 silc_free(clients); |
| 598 silc_free(nickname); |
598 silc_free(nickname); |
| 599 } |
599 } |
| 600 |
600 |
| 601 static void |
601 static void |
| 602 silcgaim_buddy_getkey_menu(GaimBlistNode *node, gpointer data) |
602 silcpurple_buddy_getkey_menu(PurpleBlistNode *node, gpointer data) |
| 603 { |
603 { |
| 604 GaimBuddy *buddy; |
604 PurpleBuddy *buddy; |
| 605 GaimConnection *gc; |
605 PurpleConnection *gc; |
| 606 |
606 |
| 607 g_return_if_fail(GAIM_BLIST_NODE_IS_BUDDY(node)); |
607 g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node)); |
| 608 |
608 |
| 609 buddy = (GaimBuddy *) node; |
609 buddy = (PurpleBuddy *) node; |
| 610 gc = gaim_account_get_connection(buddy->account); |
610 gc = purple_account_get_connection(buddy->account); |
| 611 |
611 |
| 612 silcgaim_buddy_getkey(gc, buddy->name); |
612 silcpurple_buddy_getkey(gc, buddy->name); |
| 613 } |
613 } |
| 614 |
614 |
| 615 static void |
615 static void |
| 616 silcgaim_buddy_showkey(GaimBlistNode *node, gpointer data) |
616 silcpurple_buddy_showkey(PurpleBlistNode *node, gpointer data) |
| 617 { |
617 { |
| 618 GaimBuddy *b; |
618 PurpleBuddy *b; |
| 619 GaimConnection *gc; |
619 PurpleConnection *gc; |
| 620 SilcGaim sg; |
620 SilcPurple sg; |
| 621 SilcPublicKey public_key; |
621 SilcPublicKey public_key; |
| 622 const char *pkfile; |
622 const char *pkfile; |
| 623 |
623 |
| 624 g_return_if_fail(GAIM_BLIST_NODE_IS_BUDDY(node)); |
624 g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node)); |
| 625 |
625 |
| 626 b = (GaimBuddy *) node; |
626 b = (PurpleBuddy *) node; |
| 627 gc = gaim_account_get_connection(b->account); |
627 gc = purple_account_get_connection(b->account); |
| 628 sg = gc->proto_data; |
628 sg = gc->proto_data; |
| 629 |
629 |
| 630 pkfile = gaim_blist_node_get_string(node, "public-key"); |
630 pkfile = purple_blist_node_get_string(node, "public-key"); |
| 631 if (!silc_pkcs_load_public_key(pkfile, &public_key, SILC_PKCS_FILE_PEM) && |
631 if (!silc_pkcs_load_public_key(pkfile, &public_key, SILC_PKCS_FILE_PEM) && |
| 632 !silc_pkcs_load_public_key(pkfile, &public_key, SILC_PKCS_FILE_BIN)) { |
632 !silc_pkcs_load_public_key(pkfile, &public_key, SILC_PKCS_FILE_BIN)) { |
| 633 gaim_notify_error(gc, |
633 purple_notify_error(gc, |
| 634 _("Show Public Key"), |
634 _("Show Public Key"), |
| 635 _("Could not load public key"), NULL); |
635 _("Could not load public key"), NULL); |
| 636 return; |
636 return; |
| 637 } |
637 } |
| 638 |
638 |
| 639 silcgaim_show_public_key(sg, b->name, public_key, NULL, NULL); |
639 silcpurple_show_public_key(sg, b->name, public_key, NULL, NULL); |
| 640 silc_pkcs_public_key_free(public_key); |
640 silc_pkcs_public_key_free(public_key); |
| 641 } |
641 } |
| 642 |
642 |
| 643 |
643 |
| 644 /**************************** Buddy routines *********************************/ |
644 /**************************** Buddy routines *********************************/ |
| 647 can be used to search users by their public key. Since nicknames aren't |
647 can be used to search users by their public key. Since nicknames aren't |
| 648 unique in SILC we cannot trust the buddy list using their nickname. We |
648 unique in SILC we cannot trust the buddy list using their nickname. We |
| 649 associate public keys to buddies and use those to search and watch |
649 associate public keys to buddies and use those to search and watch |
| 650 in the network. |
650 in the network. |
| 651 |
651 |
| 652 The problem is that Gaim does not return GaimBuddy contexts to the |
652 The problem is that Purple does not return PurpleBuddy contexts to the |
| 653 callbacks but the buddy names. Naturally, this is not going to work |
653 callbacks but the buddy names. Naturally, this is not going to work |
| 654 with SILC. But, for now, we have to do what we can... */ |
654 with SILC. But, for now, we have to do what we can... */ |
| 655 |
655 |
| 656 typedef struct { |
656 typedef struct { |
| 657 SilcClient client; |
657 SilcClient client; |
| 658 SilcClientConnection conn; |
658 SilcClientConnection conn; |
| 659 SilcClientID client_id; |
659 SilcClientID client_id; |
| 660 GaimBuddy *b; |
660 PurpleBuddy *b; |
| 661 unsigned char *offline_pk; |
661 unsigned char *offline_pk; |
| 662 SilcUInt32 offline_pk_len; |
662 SilcUInt32 offline_pk_len; |
| 663 unsigned int offline : 1; |
663 unsigned int offline : 1; |
| 664 unsigned int pubkey_search : 1; |
664 unsigned int pubkey_search : 1; |
| 665 unsigned int init : 1; |
665 unsigned int init : 1; |
| 666 } *SilcGaimBuddyRes; |
666 } *SilcPurpleBuddyRes; |
| 667 |
667 |
| 668 static void |
668 static void |
| 669 silcgaim_add_buddy_ask_pk_cb(SilcGaimBuddyRes r, gint id); |
669 silcpurple_add_buddy_ask_pk_cb(SilcPurpleBuddyRes r, gint id); |
| 670 static void |
670 static void |
| 671 silcgaim_add_buddy_resolved(SilcClient client, |
671 silcpurple_add_buddy_resolved(SilcClient client, |
| 672 SilcClientConnection conn, |
672 SilcClientConnection conn, |
| 673 SilcClientEntry *clients, |
673 SilcClientEntry *clients, |
| 674 SilcUInt32 clients_count, |
674 SilcUInt32 clients_count, |
| 675 void *context); |
675 void *context); |
| 676 |
676 |
| 677 void silcgaim_get_info(GaimConnection *gc, const char *who) |
677 void silcpurple_get_info(PurpleConnection *gc, const char *who) |
| 678 { |
678 { |
| 679 SilcGaim sg = gc->proto_data; |
679 SilcPurple sg = gc->proto_data; |
| 680 SilcClient client = sg->client; |
680 SilcClient client = sg->client; |
| 681 SilcClientConnection conn = sg->conn; |
681 SilcClientConnection conn = sg->conn; |
| 682 SilcClientEntry client_entry; |
682 SilcClientEntry client_entry; |
| 683 GaimBuddy *b; |
683 PurpleBuddy *b; |
| 684 const char *filename, *nick = who; |
684 const char *filename, *nick = who; |
| 685 char tmp[256]; |
685 char tmp[256]; |
| 686 |
686 |
| 687 if (!who) |
687 if (!who) |
| 688 return; |
688 return; |
| 726 silc_client_command_call(client, conn, NULL, "WHOIS", nick, NULL); |
726 silc_client_command_call(client, conn, NULL, "WHOIS", nick, NULL); |
| 727 } |
727 } |
| 728 } |
728 } |
| 729 |
729 |
| 730 static void |
730 static void |
| 731 silcgaim_add_buddy_pk_no(SilcGaimBuddyRes r) |
731 silcpurple_add_buddy_pk_no(SilcPurpleBuddyRes r) |
| 732 { |
732 { |
| 733 char tmp[512]; |
733 char tmp[512]; |
| 734 g_snprintf(tmp, sizeof(tmp), _("The %s buddy is not trusted"), |
734 g_snprintf(tmp, sizeof(tmp), _("The %s buddy is not trusted"), |
| 735 r->b->name); |
735 r->b->name); |
| 736 gaim_notify_error(r->client->application, _("Add Buddy"), tmp, |
736 purple_notify_error(r->client->application, _("Add Buddy"), tmp, |
| 737 _("You cannot receive buddy notifications until you " |
737 _("You cannot receive buddy notifications until you " |
| 738 "import his/her public key. You can use the Get Public Key " |
738 "import his/her public key. You can use the Get Public Key " |
| 739 "command to get the public key.")); |
739 "command to get the public key.")); |
| 740 gaim_prpl_got_user_status(gaim_buddy_get_account(r->b), gaim_buddy_get_name(r->b), SILCGAIM_STATUS_ID_OFFLINE, NULL); |
740 purple_prpl_got_user_status(purple_buddy_get_account(r->b), purple_buddy_get_name(r->b), SILCPURPLE_STATUS_ID_OFFLINE, NULL); |
| 741 } |
741 } |
| 742 |
742 |
| 743 static void |
743 static void |
| 744 silcgaim_add_buddy_save(bool success, void *context) |
744 silcpurple_add_buddy_save(bool success, void *context) |
| 745 { |
745 { |
| 746 SilcGaimBuddyRes r = context; |
746 SilcPurpleBuddyRes r = context; |
| 747 GaimBuddy *b = r->b; |
747 PurpleBuddy *b = r->b; |
| 748 SilcClient client = r->client; |
748 SilcClient client = r->client; |
| 749 SilcClientEntry client_entry; |
749 SilcClientEntry client_entry; |
| 750 SilcAttributePayload attr; |
750 SilcAttributePayload attr; |
| 751 SilcAttribute attribute; |
751 SilcAttribute attribute; |
| 752 SilcVCardStruct vcard; |
752 SilcVCardStruct vcard; |
| 998 /* Save the public key path to buddy properties, as it is used |
998 /* Save the public key path to buddy properties, as it is used |
| 999 to identify the buddy in the network (and not the nickname). */ |
999 to identify the buddy in the network (and not the nickname). */ |
| 1000 memset(filename, 0, sizeof(filename)); |
1000 memset(filename, 0, sizeof(filename)); |
| 1001 g_snprintf(filename, sizeof(filename) - 1, |
1001 g_snprintf(filename, sizeof(filename) - 1, |
| 1002 "%s" G_DIR_SEPARATOR_S "clientkeys" G_DIR_SEPARATOR_S "clientkey_%s.pub", |
1002 "%s" G_DIR_SEPARATOR_S "clientkeys" G_DIR_SEPARATOR_S "clientkey_%s.pub", |
| 1003 silcgaim_silcdir(), fingerprint); |
1003 silcpurple_silcdir(), fingerprint); |
| 1004 gaim_blist_node_set_string((GaimBlistNode *)b, "public-key", filename); |
1004 purple_blist_node_set_string((PurpleBlistNode *)b, "public-key", filename); |
| 1005 |
1005 |
| 1006 /* Update online status */ |
1006 /* Update online status */ |
| 1007 gaim_prpl_got_user_status(gaim_buddy_get_account(r->b), gaim_buddy_get_name(r->b), SILCGAIM_STATUS_ID_AVAILABLE, NULL); |
1007 purple_prpl_got_user_status(purple_buddy_get_account(r->b), purple_buddy_get_name(r->b), SILCPURPLE_STATUS_ID_AVAILABLE, NULL); |
| 1008 |
1008 |
| 1009 /* Finally, start watching this user so we receive its status |
1009 /* Finally, start watching this user so we receive its status |
| 1010 changes from the server */ |
1010 changes from the server */ |
| 1011 g_snprintf(filename2, sizeof(filename2) - 1, "+%s", filename); |
1011 g_snprintf(filename2, sizeof(filename2) - 1, "+%s", filename); |
| 1012 silc_client_command_call(r->client, r->conn, NULL, "WATCH", "-pubkey", |
1012 silc_client_command_call(r->client, r->conn, NULL, "WATCH", "-pubkey", |
| 1015 silc_free(fingerprint); |
1015 silc_free(fingerprint); |
| 1016 silc_free(r); |
1016 silc_free(r); |
| 1017 } |
1017 } |
| 1018 |
1018 |
| 1019 static void |
1019 static void |
| 1020 silcgaim_add_buddy_ask_import(void *user_data, const char *name) |
1020 silcpurple_add_buddy_ask_import(void *user_data, const char *name) |
| 1021 { |
1021 { |
| 1022 SilcGaimBuddyRes r = (SilcGaimBuddyRes)user_data; |
1022 SilcPurpleBuddyRes r = (SilcPurpleBuddyRes)user_data; |
| 1023 SilcPublicKey public_key; |
1023 SilcPublicKey public_key; |
| 1024 |
1024 |
| 1025 /* Load the public key */ |
1025 /* Load the public key */ |
| 1026 if (!silc_pkcs_load_public_key(name, &public_key, SILC_PKCS_FILE_PEM) && |
1026 if (!silc_pkcs_load_public_key(name, &public_key, SILC_PKCS_FILE_PEM) && |
| 1027 !silc_pkcs_load_public_key(name, &public_key, SILC_PKCS_FILE_BIN)) { |
1027 !silc_pkcs_load_public_key(name, &public_key, SILC_PKCS_FILE_BIN)) { |
| 1028 silcgaim_add_buddy_ask_pk_cb(r, 0); |
1028 silcpurple_add_buddy_ask_pk_cb(r, 0); |
| 1029 gaim_notify_error(r->client->application, |
1029 purple_notify_error(r->client->application, |
| 1030 _("Add Buddy"), _("Could not load public key"), NULL); |
1030 _("Add Buddy"), _("Could not load public key"), NULL); |
| 1031 return; |
1031 return; |
| 1032 } |
1032 } |
| 1033 |
1033 |
| 1034 /* Now verify the public key */ |
1034 /* Now verify the public key */ |
| 1035 r->offline_pk = silc_pkcs_public_key_encode(public_key, &r->offline_pk_len); |
1035 r->offline_pk = silc_pkcs_public_key_encode(public_key, &r->offline_pk_len); |
| 1036 silcgaim_verify_public_key(r->client, r->conn, r->b->name, |
1036 silcpurple_verify_public_key(r->client, r->conn, r->b->name, |
| 1037 SILC_SOCKET_TYPE_CLIENT, |
1037 SILC_SOCKET_TYPE_CLIENT, |
| 1038 r->offline_pk, r->offline_pk_len, |
1038 r->offline_pk, r->offline_pk_len, |
| 1039 SILC_SKE_PK_TYPE_SILC, |
1039 SILC_SKE_PK_TYPE_SILC, |
| 1040 silcgaim_add_buddy_save, r); |
1040 silcpurple_add_buddy_save, r); |
| 1041 } |
1041 } |
| 1042 |
1042 |
| 1043 static void |
1043 static void |
| 1044 silcgaim_add_buddy_ask_pk_cancel(void *user_data, const char *name) |
1044 silcpurple_add_buddy_ask_pk_cancel(void *user_data, const char *name) |
| 1045 { |
1045 { |
| 1046 SilcGaimBuddyRes r = (SilcGaimBuddyRes)user_data; |
1046 SilcPurpleBuddyRes r = (SilcPurpleBuddyRes)user_data; |
| 1047 |
1047 |
| 1048 /* The user did not import public key. The buddy is unusable. */ |
1048 /* The user did not import public key. The buddy is unusable. */ |
| 1049 silcgaim_add_buddy_pk_no(r); |
1049 silcpurple_add_buddy_pk_no(r); |
| 1050 silc_free(r); |
1050 silc_free(r); |
| 1051 } |
1051 } |
| 1052 |
1052 |
| 1053 static void |
1053 static void |
| 1054 silcgaim_add_buddy_ask_pk_cb(SilcGaimBuddyRes r, gint id) |
1054 silcpurple_add_buddy_ask_pk_cb(SilcPurpleBuddyRes r, gint id) |
| 1055 { |
1055 { |
| 1056 if (id != 0) { |
1056 if (id != 0) { |
| 1057 /* The user did not import public key. The buddy is unusable. */ |
1057 /* The user did not import public key. The buddy is unusable. */ |
| 1058 silcgaim_add_buddy_pk_no(r); |
1058 silcpurple_add_buddy_pk_no(r); |
| 1059 silc_free(r); |
1059 silc_free(r); |
| 1060 return; |
1060 return; |
| 1061 } |
1061 } |
| 1062 |
1062 |
| 1063 /* Open file selector to select the public key. */ |
1063 /* Open file selector to select the public key. */ |
| 1064 gaim_request_file(r->client->application, _("Open..."), NULL, FALSE, |
1064 purple_request_file(r->client->application, _("Open..."), NULL, FALSE, |
| 1065 G_CALLBACK(silcgaim_add_buddy_ask_import), |
1065 G_CALLBACK(silcpurple_add_buddy_ask_import), |
| 1066 G_CALLBACK(silcgaim_add_buddy_ask_pk_cancel), r); |
1066 G_CALLBACK(silcpurple_add_buddy_ask_pk_cancel), r); |
| 1067 } |
1067 } |
| 1068 |
1068 |
| 1069 static void |
1069 static void |
| 1070 silcgaim_add_buddy_ask_pk(SilcGaimBuddyRes r) |
1070 silcpurple_add_buddy_ask_pk(SilcPurpleBuddyRes r) |
| 1071 { |
1071 { |
| 1072 char tmp[512]; |
1072 char tmp[512]; |
| 1073 g_snprintf(tmp, sizeof(tmp), _("The %s buddy is not present in the network"), |
1073 g_snprintf(tmp, sizeof(tmp), _("The %s buddy is not present in the network"), |
| 1074 r->b->name); |
1074 r->b->name); |
| 1075 gaim_request_action(r->client->application, _("Add Buddy"), tmp, |
1075 purple_request_action(r->client->application, _("Add Buddy"), tmp, |
| 1076 _("To add the buddy you must import his/her public key. " |
1076 _("To add the buddy you must import his/her public key. " |
| 1077 "Press Import to import a public key."), 0, r, 2, |
1077 "Press Import to import a public key."), 0, r, 2, |
| 1078 _("Cancel"), G_CALLBACK(silcgaim_add_buddy_ask_pk_cb), |
1078 _("Cancel"), G_CALLBACK(silcpurple_add_buddy_ask_pk_cb), |
| 1079 _("_Import..."), G_CALLBACK(silcgaim_add_buddy_ask_pk_cb)); |
1079 _("_Import..."), G_CALLBACK(silcpurple_add_buddy_ask_pk_cb)); |
| 1080 } |
1080 } |
| 1081 |
1081 |
| 1082 static void |
1082 static void |
| 1083 silcgaim_add_buddy_getkey_cb(SilcGaimBuddyRes r, |
1083 silcpurple_add_buddy_getkey_cb(SilcPurpleBuddyRes r, |
| 1084 SilcClientCommandReplyContext cmd) |
1084 SilcClientCommandReplyContext cmd) |
| 1085 { |
1085 { |
| 1086 SilcClientEntry client_entry; |
1086 SilcClientEntry client_entry; |
| 1087 unsigned char *pk; |
1087 unsigned char *pk; |
| 1088 SilcUInt32 pk_len; |
1088 SilcUInt32 pk_len; |
| 1093 if (!client_entry || !client_entry->public_key) { |
1093 if (!client_entry || !client_entry->public_key) { |
| 1094 /* The buddy is offline/nonexistent. We will require user |
1094 /* The buddy is offline/nonexistent. We will require user |
| 1095 to associate a public key with the buddy or the buddy |
1095 to associate a public key with the buddy or the buddy |
| 1096 cannot be added. */ |
1096 cannot be added. */ |
| 1097 r->offline = TRUE; |
1097 r->offline = TRUE; |
| 1098 silcgaim_add_buddy_ask_pk(r); |
1098 silcpurple_add_buddy_ask_pk(r); |
| 1099 return; |
1099 return; |
| 1100 } |
1100 } |
| 1101 |
1101 |
| 1102 /* Now verify the public key */ |
1102 /* Now verify the public key */ |
| 1103 pk = silc_pkcs_public_key_encode(client_entry->public_key, &pk_len); |
1103 pk = silc_pkcs_public_key_encode(client_entry->public_key, &pk_len); |
| 1104 silcgaim_verify_public_key(r->client, r->conn, client_entry->nickname, |
1104 silcpurple_verify_public_key(r->client, r->conn, client_entry->nickname, |
| 1105 SILC_SOCKET_TYPE_CLIENT, |
1105 SILC_SOCKET_TYPE_CLIENT, |
| 1106 pk, pk_len, SILC_SKE_PK_TYPE_SILC, |
1106 pk, pk_len, SILC_SKE_PK_TYPE_SILC, |
| 1107 silcgaim_add_buddy_save, r); |
1107 silcpurple_add_buddy_save, r); |
| 1108 silc_free(pk); |
1108 silc_free(pk); |
| 1109 } |
1109 } |
| 1110 |
1110 |
| 1111 static void |
1111 static void |
| 1112 silcgaim_add_buddy_select_cb(SilcGaimBuddyRes r, GaimRequestFields *fields) |
1112 silcpurple_add_buddy_select_cb(SilcPurpleBuddyRes r, PurpleRequestFields *fields) |
| 1113 { |
1113 { |
| 1114 GaimRequestField *f; |
1114 PurpleRequestField *f; |
| 1115 const GList *list; |
1115 const GList *list; |
| 1116 SilcClientEntry client_entry; |
1116 SilcClientEntry client_entry; |
| 1117 |
1117 |
| 1118 f = gaim_request_fields_get_field(fields, "list"); |
1118 f = purple_request_fields_get_field(fields, "list"); |
| 1119 list = gaim_request_field_list_get_selected(f); |
1119 list = purple_request_field_list_get_selected(f); |
| 1120 if (!list) { |
1120 if (!list) { |
| 1121 /* The user did not select any user. */ |
1121 /* The user did not select any user. */ |
| 1122 silcgaim_add_buddy_pk_no(r); |
1122 silcpurple_add_buddy_pk_no(r); |
| 1123 silc_free(r); |
1123 silc_free(r); |
| 1124 return; |
1124 return; |
| 1125 } |
1125 } |
| 1126 |
1126 |
| 1127 client_entry = gaim_request_field_list_get_data(f, list->data); |
1127 client_entry = purple_request_field_list_get_data(f, list->data); |
| 1128 silcgaim_add_buddy_resolved(r->client, r->conn, &client_entry, 1, r); |
1128 silcpurple_add_buddy_resolved(r->client, r->conn, &client_entry, 1, r); |
| 1129 } |
1129 } |
| 1130 |
1130 |
| 1131 static void |
1131 static void |
| 1132 silcgaim_add_buddy_select_cancel(SilcGaimBuddyRes r, GaimRequestFields *fields) |
1132 silcpurple_add_buddy_select_cancel(SilcPurpleBuddyRes r, PurpleRequestFields *fields) |
| 1133 { |
1133 { |
| 1134 /* The user did not select any user. */ |
1134 /* The user did not select any user. */ |
| 1135 silcgaim_add_buddy_pk_no(r); |
1135 silcpurple_add_buddy_pk_no(r); |
| 1136 silc_free(r); |
1136 silc_free(r); |
| 1137 } |
1137 } |
| 1138 |
1138 |
| 1139 static void |
1139 static void |
| 1140 silcgaim_add_buddy_select(SilcGaimBuddyRes r, |
1140 silcpurple_add_buddy_select(SilcPurpleBuddyRes r, |
| 1141 SilcClientEntry *clients, |
1141 SilcClientEntry *clients, |
| 1142 SilcUInt32 clients_count) |
1142 SilcUInt32 clients_count) |
| 1143 { |
1143 { |
| 1144 GaimRequestFields *fields; |
1144 PurpleRequestFields *fields; |
| 1145 GaimRequestFieldGroup *g; |
1145 PurpleRequestFieldGroup *g; |
| 1146 GaimRequestField *f; |
1146 PurpleRequestField *f; |
| 1147 char tmp[512], tmp2[128]; |
1147 char tmp[512], tmp2[128]; |
| 1148 int i; |
1148 int i; |
| 1149 char *fingerprint; |
1149 char *fingerprint; |
| 1150 |
1150 |
| 1151 fields = gaim_request_fields_new(); |
1151 fields = purple_request_fields_new(); |
| 1152 g = gaim_request_field_group_new(NULL); |
1152 g = purple_request_field_group_new(NULL); |
| 1153 f = gaim_request_field_list_new("list", NULL); |
1153 f = purple_request_field_list_new("list", NULL); |
| 1154 gaim_request_field_group_add_field(g, f); |
1154 purple_request_field_group_add_field(g, f); |
| 1155 gaim_request_field_list_set_multi_select(f, FALSE); |
1155 purple_request_field_list_set_multi_select(f, FALSE); |
| 1156 gaim_request_fields_add_group(fields, g); |
1156 purple_request_fields_add_group(fields, g); |
| 1157 |
1157 |
| 1158 for (i = 0; i < clients_count; i++) { |
1158 for (i = 0; i < clients_count; i++) { |
| 1159 fingerprint = NULL; |
1159 fingerprint = NULL; |
| 1160 if (clients[i]->fingerprint) { |
1160 if (clients[i]->fingerprint) { |
| 1161 fingerprint = silc_fingerprint(clients[i]->fingerprint, |
1161 fingerprint = silc_fingerprint(clients[i]->fingerprint, |
| 1165 g_snprintf(tmp, sizeof(tmp), "%s - %s (%s@%s)%s", |
1165 g_snprintf(tmp, sizeof(tmp), "%s - %s (%s@%s)%s", |
| 1166 clients[i]->realname, clients[i]->nickname, |
1166 clients[i]->realname, clients[i]->nickname, |
| 1167 clients[i]->username, clients[i]->hostname ? |
1167 clients[i]->username, clients[i]->hostname ? |
| 1168 clients[i]->hostname : "", |
1168 clients[i]->hostname : "", |
| 1169 fingerprint ? tmp2 : ""); |
1169 fingerprint ? tmp2 : ""); |
| 1170 gaim_request_field_list_add(f, tmp, clients[i]); |
1170 purple_request_field_list_add(f, tmp, clients[i]); |
| 1171 silc_free(fingerprint); |
1171 silc_free(fingerprint); |
| 1172 } |
1172 } |
| 1173 |
1173 |
| 1174 gaim_request_fields(r->client->application, _("Add Buddy"), |
1174 purple_request_fields(r->client->application, _("Add Buddy"), |
| 1175 _("Select correct user"), |
1175 _("Select correct user"), |
| 1176 r->pubkey_search |
1176 r->pubkey_search |
| 1177 ? _("More than one user was found with the same public key. Select " |
1177 ? _("More than one user was found with the same public key. Select " |
| 1178 "the correct user from the list to add to the buddy list.") |
1178 "the correct user from the list to add to the buddy list.") |
| 1179 : _("More than one user was found with the same name. Select " |
1179 : _("More than one user was found with the same name. Select " |
| 1180 "the correct user from the list to add to the buddy list."), |
1180 "the correct user from the list to add to the buddy list."), |
| 1181 fields, |
1181 fields, |
| 1182 _("OK"), G_CALLBACK(silcgaim_add_buddy_select_cb), |
1182 _("OK"), G_CALLBACK(silcpurple_add_buddy_select_cb), |
| 1183 _("Cancel"), G_CALLBACK(silcgaim_add_buddy_select_cancel), r); |
1183 _("Cancel"), G_CALLBACK(silcpurple_add_buddy_select_cancel), r); |
| 1184 } |
1184 } |
| 1185 |
1185 |
| 1186 static void |
1186 static void |
| 1187 silcgaim_add_buddy_resolved(SilcClient client, |
1187 silcpurple_add_buddy_resolved(SilcClient client, |
| 1188 SilcClientConnection conn, |
1188 SilcClientConnection conn, |
| 1189 SilcClientEntry *clients, |
1189 SilcClientEntry *clients, |
| 1190 SilcUInt32 clients_count, |
1190 SilcUInt32 clients_count, |
| 1191 void *context) |
1191 void *context) |
| 1192 { |
1192 { |
| 1193 SilcGaimBuddyRes r = context; |
1193 SilcPurpleBuddyRes r = context; |
| 1194 GaimBuddy *b = r->b; |
1194 PurpleBuddy *b = r->b; |
| 1195 SilcAttributePayload pub; |
1195 SilcAttributePayload pub; |
| 1196 SilcAttributeObjPk userpk; |
1196 SilcAttributeObjPk userpk; |
| 1197 unsigned char *pk; |
1197 unsigned char *pk; |
| 1198 SilcUInt32 pk_len; |
1198 SilcUInt32 pk_len; |
| 1199 const char *filename; |
1199 const char *filename; |
| 1200 |
1200 |
| 1201 filename = gaim_blist_node_get_string((GaimBlistNode *)b, "public-key"); |
1201 filename = purple_blist_node_get_string((PurpleBlistNode *)b, "public-key"); |
| 1202 |
1202 |
| 1203 /* If the buddy is offline/nonexistent, we will require user |
1203 /* If the buddy is offline/nonexistent, we will require user |
| 1204 to associate a public key with the buddy or the buddy |
1204 to associate a public key with the buddy or the buddy |
| 1205 cannot be added. */ |
1205 cannot be added. */ |
| 1206 if (!clients_count) { |
1206 if (!clients_count) { |
| 1259 r->client_id = *clients[0]->id; |
1259 r->client_id = *clients[0]->id; |
| 1260 |
1260 |
| 1261 /* Get the public key from attributes, if not present then |
1261 /* Get the public key from attributes, if not present then |
| 1262 resolve it with GETKEY unless we have it cached already. */ |
1262 resolve it with GETKEY unless we have it cached already. */ |
| 1263 if (clients[0]->attrs && !clients[0]->public_key) { |
1263 if (clients[0]->attrs && !clients[0]->public_key) { |
| 1264 pub = silcgaim_get_attr(clients[0]->attrs, |
1264 pub = silcpurple_get_attr(clients[0]->attrs, |
| 1265 SILC_ATTRIBUTE_USER_PUBLIC_KEY); |
1265 SILC_ATTRIBUTE_USER_PUBLIC_KEY); |
| 1266 if (!pub || !silc_attribute_get_object(pub, (void *)&userpk, |
1266 if (!pub || !silc_attribute_get_object(pub, (void *)&userpk, |
| 1267 sizeof(userpk))) { |
1267 sizeof(userpk))) { |
| 1268 /* Get public key with GETKEY */ |
1268 /* Get public key with GETKEY */ |
| 1269 silc_client_command_call(client, conn, NULL, |
1269 silc_client_command_call(client, conn, NULL, |
| 1270 "GETKEY", clients[0]->nickname, NULL); |
1270 "GETKEY", clients[0]->nickname, NULL); |
| 1271 silc_client_command_pending(conn, SILC_COMMAND_GETKEY, |
1271 silc_client_command_pending(conn, SILC_COMMAND_GETKEY, |
| 1272 conn->cmd_ident, |
1272 conn->cmd_ident, |
| 1273 (SilcCommandCb)silcgaim_add_buddy_getkey_cb, |
1273 (SilcCommandCb)silcpurple_add_buddy_getkey_cb, |
| 1274 r); |
1274 r); |
| 1275 return; |
1275 return; |
| 1276 } |
1276 } |
| 1277 if (!silc_pkcs_public_key_decode(userpk.data, userpk.data_len, |
1277 if (!silc_pkcs_public_key_decode(userpk.data, userpk.data_len, |
| 1278 &clients[0]->public_key)) |
1278 &clients[0]->public_key)) |
| 1286 /* Get public key with GETKEY */ |
1286 /* Get public key with GETKEY */ |
| 1287 silc_client_command_call(client, conn, NULL, |
1287 silc_client_command_call(client, conn, NULL, |
| 1288 "GETKEY", clients[0]->nickname, NULL); |
1288 "GETKEY", clients[0]->nickname, NULL); |
| 1289 silc_client_command_pending(conn, SILC_COMMAND_GETKEY, |
1289 silc_client_command_pending(conn, SILC_COMMAND_GETKEY, |
| 1290 conn->cmd_ident, |
1290 conn->cmd_ident, |
| 1291 (SilcCommandCb)silcgaim_add_buddy_getkey_cb, |
1291 (SilcCommandCb)silcpurple_add_buddy_getkey_cb, |
| 1292 r); |
1292 r); |
| 1293 return; |
1293 return; |
| 1294 } |
1294 } |
| 1295 } else if (!clients[0]->public_key) { |
1295 } else if (!clients[0]->public_key) { |
| 1296 /* Get public key with GETKEY */ |
1296 /* Get public key with GETKEY */ |
| 1297 silc_client_command_call(client, conn, NULL, |
1297 silc_client_command_call(client, conn, NULL, |
| 1298 "GETKEY", clients[0]->nickname, NULL); |
1298 "GETKEY", clients[0]->nickname, NULL); |
| 1299 silc_client_command_pending(conn, SILC_COMMAND_GETKEY, |
1299 silc_client_command_pending(conn, SILC_COMMAND_GETKEY, |
| 1300 conn->cmd_ident, |
1300 conn->cmd_ident, |
| 1301 (SilcCommandCb)silcgaim_add_buddy_getkey_cb, |
1301 (SilcCommandCb)silcpurple_add_buddy_getkey_cb, |
| 1302 r); |
1302 r); |
| 1303 return; |
1303 return; |
| 1304 } |
1304 } |
| 1305 |
1305 |
| 1306 /* We have the public key, verify it. */ |
1306 /* We have the public key, verify it. */ |
| 1307 pk = silc_pkcs_public_key_encode(clients[0]->public_key, &pk_len); |
1307 pk = silc_pkcs_public_key_encode(clients[0]->public_key, &pk_len); |
| 1308 silcgaim_verify_public_key(client, conn, clients[0]->nickname, |
1308 silcpurple_verify_public_key(client, conn, clients[0]->nickname, |
| 1309 SILC_SOCKET_TYPE_CLIENT, |
1309 SILC_SOCKET_TYPE_CLIENT, |
| 1310 pk, pk_len, SILC_SKE_PK_TYPE_SILC, |
1310 pk, pk_len, SILC_SKE_PK_TYPE_SILC, |
| 1311 silcgaim_add_buddy_save, r); |
1311 silcpurple_add_buddy_save, r); |
| 1312 silc_free(pk); |
1312 silc_free(pk); |
| 1313 } |
1313 } |
| 1314 |
1314 |
| 1315 static void |
1315 static void |
| 1316 silcgaim_add_buddy_i(GaimConnection *gc, GaimBuddy *b, gboolean init) |
1316 silcpurple_add_buddy_i(PurpleConnection *gc, PurpleBuddy *b, gboolean init) |
| 1317 { |
1317 { |
| 1318 SilcGaim sg = gc->proto_data; |
1318 SilcPurple sg = gc->proto_data; |
| 1319 SilcClient client = sg->client; |
1319 SilcClient client = sg->client; |
| 1320 SilcClientConnection conn = sg->conn; |
1320 SilcClientConnection conn = sg->conn; |
| 1321 SilcGaimBuddyRes r; |
1321 SilcPurpleBuddyRes r; |
| 1322 SilcBuffer attrs; |
1322 SilcBuffer attrs; |
| 1323 const char *filename, *name = b->name; |
1323 const char *filename, *name = b->name; |
| 1324 |
1324 |
| 1325 r = silc_calloc(1, sizeof(*r)); |
1325 r = silc_calloc(1, sizeof(*r)); |
| 1326 if (!r) |
1326 if (!r) |
| 1372 attrs = silc_client_attributes_request(0); |
1372 attrs = silc_client_attributes_request(0); |
| 1373 } |
1373 } |
| 1374 |
1374 |
| 1375 /* Resolve */ |
1375 /* Resolve */ |
| 1376 silc_client_get_clients_whois(client, conn, name, NULL, attrs, |
1376 silc_client_get_clients_whois(client, conn, name, NULL, attrs, |
| 1377 silcgaim_add_buddy_resolved, r); |
1377 silcpurple_add_buddy_resolved, r); |
| 1378 silc_buffer_free(attrs); |
1378 silc_buffer_free(attrs); |
| 1379 } |
1379 } |
| 1380 |
1380 |
| 1381 void silcgaim_add_buddy(GaimConnection *gc, GaimBuddy *buddy, GaimGroup *group) |
1381 void silcpurple_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group) |
| 1382 { |
1382 { |
| 1383 silcgaim_add_buddy_i(gc, buddy, FALSE); |
1383 silcpurple_add_buddy_i(gc, buddy, FALSE); |
| 1384 } |
1384 } |
| 1385 |
1385 |
| 1386 void silcgaim_send_buddylist(GaimConnection *gc) |
1386 void silcpurple_send_buddylist(PurpleConnection *gc) |
| 1387 { |
1387 { |
| 1388 GaimBuddyList *blist; |
1388 PurpleBuddyList *blist; |
| 1389 GaimBlistNode *gnode, *cnode, *bnode; |
1389 PurpleBlistNode *gnode, *cnode, *bnode; |
| 1390 GaimBuddy *buddy; |
1390 PurpleBuddy *buddy; |
| 1391 GaimAccount *account; |
1391 PurpleAccount *account; |
| 1392 |
1392 |
| 1393 account = gaim_connection_get_account(gc); |
1393 account = purple_connection_get_account(gc); |
| 1394 |
1394 |
| 1395 if ((blist = gaim_get_blist()) != NULL) |
1395 if ((blist = purple_get_blist()) != NULL) |
| 1396 { |
1396 { |
| 1397 for (gnode = blist->root; gnode != NULL; gnode = gnode->next) |
1397 for (gnode = blist->root; gnode != NULL; gnode = gnode->next) |
| 1398 { |
1398 { |
| 1399 if (!GAIM_BLIST_NODE_IS_GROUP(gnode)) |
1399 if (!PURPLE_BLIST_NODE_IS_GROUP(gnode)) |
| 1400 continue; |
1400 continue; |
| 1401 for (cnode = gnode->child; cnode != NULL; cnode = cnode->next) |
1401 for (cnode = gnode->child; cnode != NULL; cnode = cnode->next) |
| 1402 { |
1402 { |
| 1403 if (!GAIM_BLIST_NODE_IS_CONTACT(cnode)) |
1403 if (!PURPLE_BLIST_NODE_IS_CONTACT(cnode)) |
| 1404 continue; |
1404 continue; |
| 1405 for (bnode = cnode->child; bnode != NULL; bnode = bnode->next) |
1405 for (bnode = cnode->child; bnode != NULL; bnode = bnode->next) |
| 1406 { |
1406 { |
| 1407 if (!GAIM_BLIST_NODE_IS_BUDDY(bnode)) |
1407 if (!PURPLE_BLIST_NODE_IS_BUDDY(bnode)) |
| 1408 continue; |
1408 continue; |
| 1409 buddy = (GaimBuddy *)bnode; |
1409 buddy = (PurpleBuddy *)bnode; |
| 1410 if (gaim_buddy_get_account(buddy) == account) |
1410 if (purple_buddy_get_account(buddy) == account) |
| 1411 silcgaim_add_buddy_i(gc, buddy, TRUE); |
1411 silcpurple_add_buddy_i(gc, buddy, TRUE); |
| 1412 } |
1412 } |
| 1413 } |
1413 } |
| 1414 } |
1414 } |
| 1415 } |
1415 } |
| 1416 } |
1416 } |
| 1417 |
1417 |
| 1418 void silcgaim_remove_buddy(GaimConnection *gc, GaimBuddy *buddy, |
1418 void silcpurple_remove_buddy(PurpleConnection *gc, PurpleBuddy *buddy, |
| 1419 GaimGroup *group) |
1419 PurpleGroup *group) |
| 1420 { |
1420 { |
| 1421 silc_free(buddy->proto_data); |
1421 silc_free(buddy->proto_data); |
| 1422 } |
1422 } |
| 1423 |
1423 |
| 1424 void silcgaim_idle_set(GaimConnection *gc, int idle) |
1424 void silcpurple_idle_set(PurpleConnection *gc, int idle) |
| 1425 |
1425 |
| 1426 { |
1426 { |
| 1427 SilcGaim sg = gc->proto_data; |
1427 SilcPurple sg = gc->proto_data; |
| 1428 SilcClient client = sg->client; |
1428 SilcClient client = sg->client; |
| 1429 SilcClientConnection conn = sg->conn; |
1429 SilcClientConnection conn = sg->conn; |
| 1430 SilcAttributeObjService service; |
1430 SilcAttributeObjService service; |
| 1431 const char *server; |
1431 const char *server; |
| 1432 int port; |
1432 int port; |
| 1433 |
1433 |
| 1434 server = gaim_account_get_string(sg->account, "server", |
1434 server = purple_account_get_string(sg->account, "server", |
| 1435 "silc.silcnet.org"); |
1435 "silc.silcnet.org"); |
| 1436 port = gaim_account_get_int(sg->account, "port", 706), |
1436 port = purple_account_get_int(sg->account, "port", 706), |
| 1437 |
1437 |
| 1438 memset(&service, 0, sizeof(service)); |
1438 memset(&service, 0, sizeof(service)); |
| 1439 silc_client_attribute_del(client, conn, |
1439 silc_client_attribute_del(client, conn, |
| 1440 SILC_ATTRIBUTE_SERVICE, NULL); |
1440 SILC_ATTRIBUTE_SERVICE, NULL); |
| 1441 service.port = port; |
1441 service.port = port; |
| 1523 client_entry = silc_client_get_client_by_id(client, conn, client_id); |
1523 client_entry = silc_client_get_client_by_id(client, conn, client_id); |
| 1524 if (!client_entry) |
1524 if (!client_entry) |
| 1525 return; |
1525 return; |
| 1526 |
1526 |
| 1527 if (client_entry->nickname) |
1527 if (client_entry->nickname) |
| 1528 gaim_notify_user_info_add_pair(user_info, _("Nickname"), |
1528 purple_notify_user_info_add_pair(user_info, _("Nickname"), |
| 1529 client_entry->nickname); |
1529 client_entry->nickname); |
| 1530 if (client_entry->username && client_entry->hostname) { |
1530 if (client_entry->username && client_entry->hostname) { |
| 1531 g_snprintf(tmp, sizeof(tmp), "%s@%s", client_entry->username, client_entry->hostname); |
1531 g_snprintf(tmp, sizeof(tmp), "%s@%s", client_entry->username, client_entry->hostname); |
| 1532 gaim_notify_user_info_add_pair(user_info, _("Username"), tmp); |
1532 purple_notify_user_info_add_pair(user_info, _("Username"), tmp); |
| 1533 } |
1533 } |
| 1534 if (client_entry->mode) { |
1534 if (client_entry->mode) { |
| 1535 memset(tmp, 0, sizeof(tmp)); |
1535 memset(tmp, 0, sizeof(tmp)); |
| 1536 silcgaim_get_umode_string(client_entry->mode, |
1536 silcpurple_get_umode_string(client_entry->mode, |
| 1537 tmp, sizeof(tmp) - strlen(tmp)); |
1537 tmp, sizeof(tmp) - strlen(tmp)); |
| 1538 gaim_notify_user_info_add_pair(user_info, _("User Modes"), tmp); |
1538 purple_notify_user_info_add_pair(user_info, _("User Modes"), tmp); |
| 1539 } |
1539 } |
| 1540 |
1540 |
| 1541 silcgaim_parse_attrs(client_entry->attrs, &moodstr, &statusstr, &contactstr, &langstr, &devicestr, &tzstr, &geostr); |
1541 silcpurple_parse_attrs(client_entry->attrs, &moodstr, &statusstr, &contactstr, &langstr, &devicestr, &tzstr, &geostr); |
| 1542 |
1542 |
| 1543 if (statusstr) { |
1543 if (statusstr) { |
| 1544 gaim_notify_user_info_add_pair(user_info, _("Message"), statusstr); |
1544 purple_notify_user_info_add_pair(user_info, _("Message"), statusstr); |
| 1545 g_free(statusstr); |
1545 g_free(statusstr); |
| 1546 } |
1546 } |
| 1547 |
1547 |
| 1548 if (full) { |
1548 if (full) { |
| 1549 if (moodstr) { |
1549 if (moodstr) { |
| 1550 gaim_notify_user_info_add_pair(user_info, _("Mood"), moodstr); |
1550 purple_notify_user_info_add_pair(user_info, _("Mood"), moodstr); |
| 1551 g_free(moodstr); |
1551 g_free(moodstr); |
| 1552 } |
1552 } |
| 1553 |
1553 |
| 1554 if (contactstr) { |
1554 if (contactstr) { |
| 1555 gaim_notify_user_info_add_pair(user_info, _("Preferred Contact"), contactstr); |
1555 purple_notify_user_info_add_pair(user_info, _("Preferred Contact"), contactstr); |
| 1556 g_free(contactstr); |
1556 g_free(contactstr); |
| 1557 } |
1557 } |
| 1558 |
1558 |
| 1559 if (langstr) { |
1559 if (langstr) { |
| 1560 gaim_notify_user_info_add_pair(user_info, _("Preferred Language"), langstr); |
1560 purple_notify_user_info_add_pair(user_info, _("Preferred Language"), langstr); |
| 1561 g_free(langstr); |
1561 g_free(langstr); |
| 1562 } |
1562 } |
| 1563 |
1563 |
| 1564 if (devicestr) { |
1564 if (devicestr) { |
| 1565 gaim_notify_user_info_add_pair(user_info, _("Device"), devicestr); |
1565 purple_notify_user_info_add_pair(user_info, _("Device"), devicestr); |
| 1566 g_free(devicestr); |
1566 g_free(devicestr); |
| 1567 } |
1567 } |
| 1568 |
1568 |
| 1569 if (tzstr) { |
1569 if (tzstr) { |
| 1570 gaim_notify_user_info_add_pair(user_info, _("Timezone"), tzstr); |
1570 purple_notify_user_info_add_pair(user_info, _("Timezone"), tzstr); |
| 1571 g_free(tzstr); |
1571 g_free(tzstr); |
| 1572 } |
1572 } |
| 1573 |
1573 |
| 1574 if (geostr) { |
1574 if (geostr) { |
| 1575 gaim_notify_user_info_add_pair(user_info, _("Geolocation"), geostr); |
1575 purple_notify_user_info_add_pair(user_info, _("Geolocation"), geostr); |
| 1576 g_free(geostr); |
1576 g_free(geostr); |
| 1577 } |
1577 } |
| 1578 } |
1578 } |
| 1579 } |
1579 } |
| 1580 |
1580 |
| 1581 static void |
1581 static void |
| 1582 silcgaim_buddy_kill(GaimBlistNode *node, gpointer data) |
1582 silcpurple_buddy_kill(PurpleBlistNode *node, gpointer data) |
| 1583 { |
1583 { |
| 1584 GaimBuddy *b; |
1584 PurpleBuddy *b; |
| 1585 GaimConnection *gc; |
1585 PurpleConnection *gc; |
| 1586 SilcGaim sg; |
1586 SilcPurple sg; |
| 1587 |
1587 |
| 1588 g_return_if_fail(GAIM_BLIST_NODE_IS_BUDDY(node)); |
1588 g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node)); |
| 1589 |
1589 |
| 1590 b = (GaimBuddy *) node; |
1590 b = (PurpleBuddy *) node; |
| 1591 gc = gaim_account_get_connection(b->account); |
1591 gc = purple_account_get_connection(b->account); |
| 1592 sg = gc->proto_data; |
1592 sg = gc->proto_data; |
| 1593 |
1593 |
| 1594 /* Call KILL */ |
1594 /* Call KILL */ |
| 1595 silc_client_command_call(sg->client, sg->conn, NULL, "KILL", |
1595 silc_client_command_call(sg->client, sg->conn, NULL, "KILL", |
| 1596 b->name, "Killed by operator", NULL); |
1596 b->name, "Killed by operator", NULL); |
| 1597 } |
1597 } |
| 1598 |
1598 |
| 1599 typedef struct { |
1599 typedef struct { |
| 1600 SilcGaim sg; |
1600 SilcPurple sg; |
| 1601 SilcClientEntry client_entry; |
1601 SilcClientEntry client_entry; |
| 1602 } *SilcGaimBuddyWb; |
1602 } *SilcPurpleBuddyWb; |
| 1603 |
1603 |
| 1604 static void |
1604 static void |
| 1605 silcgaim_buddy_wb(GaimBlistNode *node, gpointer data) |
1605 silcpurple_buddy_wb(PurpleBlistNode *node, gpointer data) |
| 1606 { |
1606 { |
| 1607 SilcGaimBuddyWb wb = data; |
1607 SilcPurpleBuddyWb wb = data; |
| 1608 silcgaim_wb_init(wb->sg, wb->client_entry); |
1608 silcpurple_wb_init(wb->sg, wb->client_entry); |
| 1609 silc_free(wb); |
1609 silc_free(wb); |
| 1610 } |
1610 } |
| 1611 |
1611 |
| 1612 GList *silcgaim_buddy_menu(GaimBuddy *buddy) |
1612 GList *silcpurple_buddy_menu(PurpleBuddy *buddy) |
| 1613 { |
1613 { |
| 1614 GaimConnection *gc = gaim_account_get_connection(buddy->account); |
1614 PurpleConnection *gc = purple_account_get_connection(buddy->account); |
| 1615 SilcGaim sg = gc->proto_data; |
1615 SilcPurple sg = gc->proto_data; |
| 1616 SilcClientConnection conn = sg->conn; |
1616 SilcClientConnection conn = sg->conn; |
| 1617 const char *pkfile = NULL; |
1617 const char *pkfile = NULL; |
| 1618 SilcClientEntry client_entry = NULL; |
1618 SilcClientEntry client_entry = NULL; |
| 1619 GaimMenuAction *act; |
1619 PurpleMenuAction *act; |
| 1620 GList *m = NULL; |
1620 GList *m = NULL; |
| 1621 SilcGaimBuddyWb wb; |
1621 SilcPurpleBuddyWb wb; |
| 1622 |
1622 |
| 1623 pkfile = gaim_blist_node_get_string((GaimBlistNode *) buddy, "public-key"); |
1623 pkfile = purple_blist_node_get_string((PurpleBlistNode *) buddy, "public-key"); |
| 1624 client_entry = silc_client_get_client_by_id(sg->client, |
1624 client_entry = silc_client_get_client_by_id(sg->client, |
| 1625 sg->conn, |
1625 sg->conn, |
| 1626 buddy->proto_data); |
1626 buddy->proto_data); |
| 1627 |
1627 |
| 1628 if (client_entry && client_entry->send_key) { |
1628 if (client_entry && client_entry->send_key) { |
| 1629 act = gaim_menu_action_new(_("Reset IM Key"), |
1629 act = purple_menu_action_new(_("Reset IM Key"), |
| 1630 GAIM_CALLBACK(silcgaim_buddy_resetkey), |
1630 PURPLE_CALLBACK(silcpurple_buddy_resetkey), |
| 1631 NULL, NULL); |
1631 NULL, NULL); |
| 1632 m = g_list_append(m, act); |
1632 m = g_list_append(m, act); |
| 1633 |
1633 |
| 1634 } else { |
1634 } else { |
| 1635 act = gaim_menu_action_new(_("IM with Key Exchange"), |
1635 act = purple_menu_action_new(_("IM with Key Exchange"), |
| 1636 GAIM_CALLBACK(silcgaim_buddy_keyagr), |
1636 PURPLE_CALLBACK(silcpurple_buddy_keyagr), |
| 1637 NULL, NULL); |
1637 NULL, NULL); |
| 1638 m = g_list_append(m, act); |
1638 m = g_list_append(m, act); |
| 1639 |
1639 |
| 1640 act = gaim_menu_action_new(_("IM with Password"), |
1640 act = purple_menu_action_new(_("IM with Password"), |
| 1641 GAIM_CALLBACK(silcgaim_buddy_privkey_menu), |
1641 PURPLE_CALLBACK(silcpurple_buddy_privkey_menu), |
| 1642 NULL, NULL); |
1642 NULL, NULL); |
| 1643 m = g_list_append(m, act); |
1643 m = g_list_append(m, act); |
| 1644 } |
1644 } |
| 1645 |
1645 |
| 1646 if (pkfile) { |
1646 if (pkfile) { |
| 1647 act = gaim_menu_action_new(_("Show Public Key"), |
1647 act = purple_menu_action_new(_("Show Public Key"), |
| 1648 GAIM_CALLBACK(silcgaim_buddy_showkey), |
1648 PURPLE_CALLBACK(silcpurple_buddy_showkey), |
| 1649 NULL, NULL); |
1649 NULL, NULL); |
| 1650 m = g_list_append(m, act); |
1650 m = g_list_append(m, act); |
| 1651 |
1651 |
| 1652 } else { |
1652 } else { |
| 1653 act = gaim_menu_action_new(_("Get Public Key..."), |
1653 act = purple_menu_action_new(_("Get Public Key..."), |
| 1654 GAIM_CALLBACK(silcgaim_buddy_getkey_menu), |
1654 PURPLE_CALLBACK(silcpurple_buddy_getkey_menu), |
| 1655 NULL, NULL); |
1655 NULL, NULL); |
| 1656 m = g_list_append(m, act); |
1656 m = g_list_append(m, act); |
| 1657 } |
1657 } |
| 1658 |
1658 |
| 1659 if (conn && conn->local_entry->mode & SILC_UMODE_ROUTER_OPERATOR) { |
1659 if (conn && conn->local_entry->mode & SILC_UMODE_ROUTER_OPERATOR) { |
| 1660 act = gaim_menu_action_new(_("Kill User"), |
1660 act = purple_menu_action_new(_("Kill User"), |
| 1661 GAIM_CALLBACK(silcgaim_buddy_kill), |
1661 PURPLE_CALLBACK(silcpurple_buddy_kill), |
| 1662 NULL, NULL); |
1662 NULL, NULL); |
| 1663 m = g_list_append(m, act); |
1663 m = g_list_append(m, act); |
| 1664 } |
1664 } |
| 1665 |
1665 |
| 1666 if (client_entry) { |
1666 if (client_entry) { |
| 1667 wb = silc_calloc(1, sizeof(*wb)); |
1667 wb = silc_calloc(1, sizeof(*wb)); |
| 1668 wb->sg = sg; |
1668 wb->sg = sg; |
| 1669 wb->client_entry = client_entry; |
1669 wb->client_entry = client_entry; |
| 1670 act = gaim_menu_action_new(_("Draw On Whiteboard"), |
1670 act = purple_menu_action_new(_("Draw On Whiteboard"), |
| 1671 GAIM_CALLBACK(silcgaim_buddy_wb), |
1671 PURPLE_CALLBACK(silcpurple_buddy_wb), |
| 1672 (void *)wb, NULL); |
1672 (void *)wb, NULL); |
| 1673 m = g_list_append(m, act); |
1673 m = g_list_append(m, act); |
| 1674 } |
1674 } |
| 1675 return m; |
1675 return m; |
| 1676 } |
1676 } |
| 1677 |
1677 |
| 1678 #ifdef SILC_ATTRIBUTE_USER_ICON |
1678 #ifdef SILC_ATTRIBUTE_USER_ICON |
| 1679 void silcgaim_buddy_set_icon(GaimConnection *gc, const char *iconfile) |
1679 void silcpurple_buddy_set_icon(PurpleConnection *gc, const char *iconfile) |
| 1680 { |
1680 { |
| 1681 SilcGaim sg = gc->proto_data; |
1681 SilcPurple sg = gc->proto_data; |
| 1682 SilcClient client = sg->client; |
1682 SilcClient client = sg->client; |
| 1683 SilcClientConnection conn = sg->conn; |
1683 SilcClientConnection conn = sg->conn; |
| 1684 SilcMime mime; |
1684 SilcMime mime; |
| 1685 GaimBuddyIcon ic; |
1685 PurpleBuddyIcon ic; |
| 1686 char type[32]; |
1686 char type[32]; |
| 1687 unsigned char *icon; |
1687 unsigned char *icon; |
| 1688 const char *t; |
1688 const char *t; |
| 1689 struct stat st; |
1689 struct stat st; |
| 1690 FILE *fp; |
1690 FILE *fp; |