Fri, 21 May 2004 14:33:32 +0000
[gaim-migrate @ 9774]
" This patch renames the existing received-*-msg signals
to receiving-*msg to fit the naming of other signals
where a pointer to the message is passed (writing,
sending, displaying)
It adds new received-*-msg signals which are emitted
after the receiving signals, in line with the other
conversation signals (wrote, sent, displayed)
This is necessary to allow plugins which depend on the
final received message to work alongside plugins which
may modify the message.
One known example of this is festival-gaim alongside
gaim-encryption - festival-gaim would try to "speak"
the encrypted text:
http://sf.net/tracker/?func=detail&aid=943216&group_id=89763&atid=591320
I've tested this with gaim-encryption and festival-gaim
(locally modified so gaim-encryption uses the receiving
signal and festival uses the received signal)
All in-tree users of received-*-msg are updated to use
receiving-*-msg if they do modify the message, the
conversation-signals documentation is updated, the
signals-test.c & signal-test.tcl plugins are also updated." --Stu Tomlinson
committer: Luke Schierer <lschiere@pidgin.im>
| 8849 | 1 | /* |
| 2 | ||
| 3 | silcgaim.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" | |
| 23 | ||
| 24 | extern SilcClientOperations ops; | |
| 25 | static GaimPlugin *silc_plugin = NULL; | |
| 26 | ||
| 27 | static const char * | |
| 28 | silcgaim_list_icon(GaimAccount *a, GaimBuddy *b) | |
| 29 | { | |
| 30 | return (const char *)"silc"; | |
| 31 | } | |
| 32 | ||
| 33 | static void | |
| 34 | silcgaim_list_emblems(GaimBuddy *b, char **se, char **sw, | |
| 35 | char **nw, char **ne) | |
| 36 | { | |
| 37 | } | |
| 38 | ||
| 39 | static GList * | |
| 40 | silcgaim_away_states(GaimConnection *gc) | |
| 41 | { | |
| 42 | GList *st = NULL; | |
| 43 | ||
| 44 | st = g_list_append(st, _("Online")); | |
| 45 | st = g_list_append(st, _("Hyper Active")); | |
| 46 | st = g_list_append(st, _("Away")); | |
| 47 | st = g_list_append(st, _("Busy")); | |
| 48 | st = g_list_append(st, _("Indisposed")); | |
| 49 | st = g_list_append(st, _("Wake Me Up")); | |
| 50 | ||
| 51 | return st; | |
| 52 | } | |
| 53 | ||
| 54 | static void | |
| 55 | silcgaim_set_away(GaimConnection *gc, const char *state, const char *msg) | |
| 56 | { | |
| 57 | SilcGaim sg = gc->proto_data; | |
| 58 | SilcUInt32 mode; | |
| 59 | SilcBuffer idp; | |
| 60 | unsigned char mb[4]; | |
| 61 | ||
| 62 | if (!state) | |
| 63 | return; | |
| 64 | if (!sg->conn) | |
| 65 | return; | |
| 66 | ||
| 67 | mode = sg->conn->local_entry->mode; | |
| 68 | mode &= ~(SILC_UMODE_GONE | | |
| 69 | SILC_UMODE_HYPER | | |
| 70 | SILC_UMODE_BUSY | | |
| 71 | SILC_UMODE_INDISPOSED | | |
| 72 | SILC_UMODE_PAGE); | |
| 73 | ||
| 74 | if (!strcmp(state, _("Hyper Active"))) | |
| 75 | mode |= SILC_UMODE_HYPER; | |
| 76 | else if (!strcmp(state, _("Away"))) | |
| 77 | mode |= SILC_UMODE_GONE; | |
| 78 | else if (!strcmp(state, _("Busy"))) | |
| 79 | mode |= SILC_UMODE_BUSY; | |
| 80 | else if (!strcmp(state, _("Indisposed"))) | |
| 81 | mode |= SILC_UMODE_INDISPOSED; | |
| 82 | else if (!strcmp(state, _("Wake Me Up"))) | |
| 83 | mode |= SILC_UMODE_PAGE; | |
| 84 | ||
| 85 | /* Send UMODE */ | |
| 86 | idp = silc_id_payload_encode(sg->conn->local_id, SILC_ID_CLIENT); | |
| 87 | SILC_PUT32_MSB(mode, mb); | |
| 88 | silc_client_command_send(sg->client, sg->conn, SILC_COMMAND_UMODE, | |
| 89 | ++sg->conn->cmd_ident, 2, | |
| 90 | 1, idp->data, idp->len, | |
| 91 | 2, mb, sizeof(mb)); | |
| 92 | silc_buffer_free(idp); | |
| 93 | } | |
| 94 | ||
| 95 | ||
| 96 | /*************************** Connection Routines *****************************/ | |
| 97 | ||
| 98 | static void | |
| 99 | silcgaim_keepalive(GaimConnection *gc) | |
| 100 | { | |
| 101 | SilcGaim sg = gc->proto_data; | |
| 102 | silc_client_send_packet(sg->client, sg->conn, SILC_PACKET_HEARTBEAT, | |
| 103 | NULL, 0); | |
| 104 | } | |
| 105 | ||
| 106 | static int | |
| 107 | silcgaim_scheduler(gpointer *context) | |
| 108 | { | |
| 109 | SilcGaim sg = (SilcGaim)context; | |
| 110 | silc_client_run_one(sg->client); | |
| 111 | return 1; | |
| 112 | } | |
| 113 | ||
| 114 | static void | |
| 115 | silcgaim_nickname_parse(const char *nickname, | |
| 116 | char **ret_nickname) | |
| 117 | { | |
| 118 | silc_parse_userfqdn(nickname, ret_nickname, NULL); | |
| 119 | } | |
| 120 | ||
| 121 | static void | |
| 122 | silcgaim_login_connected(gpointer data, gint source, GaimInputCondition cond) | |
| 123 | { | |
| 124 | GaimConnection *gc = data; | |
| 125 | SilcGaim sg = gc->proto_data; | |
| 126 | SilcClient client = sg->client; | |
| 127 | SilcClientConnection conn; | |
| 128 | GaimAccount *account = sg->account; | |
| 129 | SilcClientConnectionParams params; | |
| 130 | const char *dfile; | |
| 131 | ||
| 132 | if (source < 0) { | |
| 133 | gaim_connection_error(gc, _("Connection failed")); | |
| 134 | return; | |
| 135 | } | |
| 136 | if (!g_list_find(gaim_connections_get_all(), gc)) { | |
| 137 | close(source); | |
| 138 | g_source_remove(sg->scheduler); | |
| 139 | silc_client_stop(sg->client); | |
| 140 | silc_client_free(sg->client); | |
| 141 | silc_free(sg); | |
| 142 | return; | |
| 143 | } | |
| 144 | ||
| 145 | /* Get session detachment data, if available */ | |
| 146 | memset(¶ms, 0, sizeof(params)); | |
| 147 | dfile = silcgaim_session_file(gaim_account_get_username(sg->account)); | |
| 148 | params.detach_data = silc_file_readfile(dfile, ¶ms.detach_data_len); | |
| 149 | if (params.detach_data) | |
| 150 | params.detach_data[params.detach_data_len] = 0; | |
| 151 | ||
| 152 | /* Add connection to SILC client library */ | |
| 153 | conn = silc_client_add_connection( | |
| 154 | sg->client, ¶ms, | |
| 155 | (char *)gaim_account_get_string(account, "server", | |
| 156 | "silc.silcnet.org"), | |
| 157 | gaim_account_get_int(account, "port", 706), sg); | |
| 158 | if (!conn) { | |
| 159 | gaim_connection_error(gc, _("Cannot initialize SILC Client connection")); | |
| 160 | gc->proto_data = NULL; | |
| 161 | return; | |
| 162 | } | |
| 163 | sg->conn = conn; | |
| 164 | ||
| 165 | /* Progress */ | |
| 166 | if (params.detach_data) { | |
| 167 | gaim_connection_update_progress(gc, _("Resuming session"), 2, 5); | |
| 168 | sg->resuming = TRUE; | |
| 169 | } else { | |
| 170 | gaim_connection_update_progress(gc, _("Performing key exchange"), 2, 5); | |
| 171 | } | |
| 172 | ||
| 173 | /* Perform SILC Key Exchange. The "silc_connected" will be called | |
| 174 | eventually. */ | |
| 175 | silc_client_start_key_exchange(sg->client, sg->conn, source); | |
| 176 | ||
| 177 | /* Set default attributes */ | |
| 178 | if (!gaim_account_get_bool(account, "reject-attrs", FALSE)) { | |
| 179 | SilcUInt32 mask; | |
| 180 | const char *tmp; | |
| 181 | #ifdef HAVE_SYS_UTSNAME_H | |
| 182 | struct utsname u; | |
| 183 | #endif | |
| 184 | ||
| 185 | mask = SILC_ATTRIBUTE_MOOD_NORMAL; | |
| 186 | silc_client_attribute_add(client, conn, | |
| 187 | SILC_ATTRIBUTE_STATUS_MOOD, | |
| 188 | SILC_32_TO_PTR(mask), | |
| 189 | sizeof(SilcUInt32)); | |
| 190 | mask = SILC_ATTRIBUTE_CONTACT_CHAT; | |
| 191 | silc_client_attribute_add(client, conn, | |
| 192 | SILC_ATTRIBUTE_PREFERRED_CONTACT, | |
| 193 | SILC_32_TO_PTR(mask), | |
| 194 | sizeof(SilcUInt32)); | |
| 195 | #ifdef HAVE_SYS_UTSNAME_H | |
| 196 | if (!uname(&u)) { | |
| 197 | SilcAttributeObjDevice dev; | |
| 198 | memset(&dev, 0, sizeof(dev)); | |
| 199 | dev.type = SILC_ATTRIBUTE_DEVICE_COMPUTER; | |
| 200 | dev.version = u.release; | |
| 201 | dev.model = u.sysname; | |
| 202 | silc_client_attribute_add(client, conn, | |
| 203 | SILC_ATTRIBUTE_DEVICE_INFO, | |
| 204 | (void *)&dev, sizeof(dev)); | |
| 205 | } | |
| 206 | #endif | |
| 207 | #ifdef _WIN32 | |
| 208 | tmp = _tzname[0]; | |
| 209 | #else | |
| 210 | tmp = tzname[0]; | |
| 211 | #endif | |
| 212 | silc_client_attribute_add(client, conn, | |
| 213 | SILC_ATTRIBUTE_TIMEZONE, | |
| 214 | (void *)tmp, strlen(tmp)); | |
| 215 | } | |
| 216 | ||
| 217 | silc_free(params.detach_data); | |
| 218 | } | |
| 219 | ||
| 220 | static void | |
| 221 | silcgaim_login(GaimAccount *account) | |
| 222 | { | |
| 223 | SilcGaim sg; | |
| 224 | SilcClient client; | |
| 225 | SilcClientParams params; | |
| 226 | GaimConnection *gc; | |
| 227 | ||
| 228 | gc = account->gc; | |
| 229 | if (!gc) | |
| 230 | return; | |
| 231 | gc->proto_data = NULL; | |
| 232 | ||
| 233 | memset(¶ms, 0, sizeof(params)); | |
| 234 | strcat(params.nickname_format, "%n@%h%a"); | |
| 235 | params.nickname_parse = silcgaim_nickname_parse; | |
| 236 | params.ignore_requested_attributes = | |
| 237 | gaim_account_get_bool(account, "reject-attrs", FALSE); | |
| 238 | ||
| 239 | /* Allocate SILC client */ | |
| 240 | client = silc_client_alloc(&ops, ¶ms, gc, NULL); | |
| 241 | if (!client) { | |
| 242 | gaim_connection_error(gc, _("Out of memory")); | |
| 243 | return; | |
| 244 | } | |
| 245 | ||
| 246 | /* Get username, real name and local hostname for SILC library */ | |
| 247 | if (gaim_account_get_username(account)) { | |
| 248 | client->username = strdup(gaim_account_get_username(account)); | |
| 249 | } else { | |
| 250 | client->username = silc_get_username(); | |
| 251 | gaim_account_set_username(account, client->username); | |
| 252 | } | |
| 253 | if (gaim_account_get_user_info(account)) { | |
| 254 | client->realname = strdup(gaim_account_get_user_info(account)); | |
| 255 | } else { | |
| 256 | client->realname = silc_get_real_name(); | |
| 257 | gaim_account_set_user_info(account, client->realname); | |
| 258 | } | |
| 259 | client->hostname = silc_net_localhost(); | |
| 260 | ||
| 261 | gaim_connection_set_display_name(gc, client->username); | |
| 262 | ||
| 263 | /* Init SILC client */ | |
| 264 | if (!silc_client_init(client)) { | |
| 265 | gaim_connection_error(gc, ("Cannot initialize SILC protocol")); | |
| 266 | return; | |
| 267 | } | |
| 268 | ||
| 269 | /* Check the ~/.silc dir and create it, and new key pair if necessary. */ | |
| 270 | if (!silcgaim_check_silc_dir(gc)) { | |
| 271 | gaim_connection_error(gc, ("Cannot find/access ~/.silc directory")); | |
| 272 | return; | |
| 273 | } | |
| 274 | ||
| 275 | /* Progress */ | |
| 276 | gaim_connection_update_progress(gc, _("Connecting to SILC Server"), 1, 5); | |
| 277 | ||
| 278 | /* Load SILC key pair */ | |
| 279 | if (!silc_load_key_pair(gaim_prefs_get_string("/plugins/prpl/silc/pubkey"), | |
| 280 | gaim_prefs_get_string("/plugins/prpl/silc/privkey"), | |
| 281 | "", &client->pkcs, &client->public_key, | |
| 282 | &client->private_key)) { | |
| 283 | gaim_connection_error(gc, ("Could not load SILC key pair")); | |
| 284 | return; | |
| 285 | } | |
| 286 | ||
| 287 | sg = silc_calloc(1, sizeof(*sg)); | |
| 288 | if (!sg) | |
| 289 | return; | |
| 290 | memset(sg, 0, sizeof(*sg)); | |
| 291 | sg->client = client; | |
| 292 | sg->gc = gc; | |
| 293 | sg->account = account; | |
| 294 | gc->proto_data = sg; | |
| 295 | ||
| 296 | /* Connect to the SILC server */ | |
| 297 | if (gaim_proxy_connect(account, | |
| 298 | gaim_account_get_string(account, "server", | |
| 299 | "silc.silcnet.org"), | |
| 300 | gaim_account_get_int(account, "port", 706), | |
| 301 | silcgaim_login_connected, gc)) { | |
| 302 | gaim_connection_error(gc, ("Unable to create connection")); | |
| 303 | return; | |
| 304 | } | |
| 305 | ||
| 306 | /* Schedule SILC using Glib's event loop */ | |
| 307 | sg->scheduler = g_timeout_add(5, (GSourceFunc)silcgaim_scheduler, sg); | |
| 308 | } | |
| 309 | ||
| 310 | static int | |
| 311 | silcgaim_close_final(gpointer *context) | |
| 312 | { | |
| 313 | SilcGaim sg = (SilcGaim)context; | |
| 314 | silc_client_stop(sg->client); | |
| 315 | silc_client_free(sg->client); | |
| 316 | silc_free(sg); | |
| 317 | return 0; | |
| 318 | } | |
| 319 | ||
| 320 | static void | |
| 321 | silcgaim_close_convos(GaimConversation *convo) | |
| 322 | { | |
| 323 | if (convo) | |
| 324 | gaim_conversation_destroy(convo); | |
| 325 | } | |
| 326 | ||
| 327 | static void | |
| 328 | silcgaim_close(GaimConnection *gc) | |
| 329 | { | |
| 330 | SilcGaim sg = gc->proto_data; | |
| 331 | if (!sg) | |
| 332 | return; | |
| 333 | ||
| 334 | /* Close all conversations */ | |
| 335 | gaim_conversation_foreach(silcgaim_close_convos); | |
| 336 | ||
| 337 | /* Send QUIT */ | |
| 338 | silc_client_command_call(sg->client, sg->conn, NULL, | |
| 339 | "QUIT", "Leaving", NULL); | |
| 340 | ||
| 341 | if (sg->conn) | |
| 342 | silc_client_close_connection(sg->client, sg->conn); | |
| 343 | ||
| 344 | g_source_remove(sg->scheduler); | |
| 345 | g_timeout_add(1, (GSourceFunc)silcgaim_close_final, sg); | |
| 346 | } | |
| 347 | ||
| 348 | ||
| 349 | /****************************** Protocol Actions *****************************/ | |
| 350 | ||
| 351 | static void | |
| 352 | silcgaim_attrs_cancel(GaimConnection *gc, GaimRequestFields *fields) | |
| 353 | { | |
| 354 | /* Nothing */ | |
| 355 | } | |
| 356 | ||
| 357 | static void | |
| 358 | silcgaim_attrs_cb(GaimConnection *gc, GaimRequestFields *fields) | |
| 359 | { | |
| 360 | SilcGaim sg = gc->proto_data; | |
| 361 | SilcClient client = sg->client; | |
| 362 | SilcClientConnection conn = sg->conn; | |
| 363 | GaimRequestField *f; | |
| 364 | char *tmp; | |
| 365 | SilcUInt32 tmp_len, mask; | |
| 366 | SilcAttributeObjService service; | |
| 367 | SilcAttributeObjDevice dev; | |
| 368 | SilcVCardStruct vcard; | |
| 369 | const char *val; | |
| 370 | ||
| 371 | sg = gc->proto_data; | |
| 372 | if (!sg) | |
| 373 | return; | |
| 374 | ||
| 375 | memset(&service, 0, sizeof(service)); | |
| 376 | memset(&dev, 0, sizeof(dev)); | |
| 377 | memset(&vcard, 0, sizeof(vcard)); | |
| 378 | ||
| 379 | silc_client_attribute_del(client, conn, | |
| 380 | SILC_ATTRIBUTE_USER_INFO, NULL); | |
| 381 | silc_client_attribute_del(client, conn, | |
| 382 | SILC_ATTRIBUTE_SERVICE, NULL); | |
| 383 | silc_client_attribute_del(client, conn, | |
| 384 | SILC_ATTRIBUTE_STATUS_MOOD, NULL); | |
| 385 | silc_client_attribute_del(client, conn, | |
| 386 | SILC_ATTRIBUTE_STATUS_FREETEXT, NULL); | |
| 387 | silc_client_attribute_del(client, conn, | |
| 388 | SILC_ATTRIBUTE_STATUS_MESSAGE, NULL); | |
| 389 | silc_client_attribute_del(client, conn, | |
| 390 | SILC_ATTRIBUTE_PREFERRED_LANGUAGE, NULL); | |
| 391 | silc_client_attribute_del(client, conn, | |
| 392 | SILC_ATTRIBUTE_PREFERRED_CONTACT, NULL); | |
| 393 | silc_client_attribute_del(client, conn, | |
| 394 | SILC_ATTRIBUTE_TIMEZONE, NULL); | |
| 395 | silc_client_attribute_del(client, conn, | |
| 396 | SILC_ATTRIBUTE_GEOLOCATION, NULL); | |
| 397 | silc_client_attribute_del(client, conn, | |
| 398 | SILC_ATTRIBUTE_DEVICE_INFO, NULL); | |
| 399 | ||
| 400 | /* Set mood */ | |
| 401 | mask = 0; | |
| 402 | f = gaim_request_fields_get_field(fields, "mood_normal"); | |
| 403 | if (f && gaim_request_field_bool_get_value(f)) | |
| 404 | mask |= SILC_ATTRIBUTE_MOOD_NORMAL; | |
| 405 | f = gaim_request_fields_get_field(fields, "mood_happy"); | |
| 406 | if (f && gaim_request_field_bool_get_value(f)) | |
| 407 | mask |= SILC_ATTRIBUTE_MOOD_HAPPY; | |
| 408 | f = gaim_request_fields_get_field(fields, "mood_sad"); | |
| 409 | if (f && gaim_request_field_bool_get_value(f)) | |
| 410 | mask |= SILC_ATTRIBUTE_MOOD_SAD; | |
| 411 | f = gaim_request_fields_get_field(fields, "mood_angry"); | |
| 412 | if (f && gaim_request_field_bool_get_value(f)) | |
| 413 | mask |= SILC_ATTRIBUTE_MOOD_ANGRY; | |
| 414 | f = gaim_request_fields_get_field(fields, "mood_jealous"); | |
| 415 | if (f && gaim_request_field_bool_get_value(f)) | |
| 416 | mask |= SILC_ATTRIBUTE_MOOD_JEALOUS; | |
| 417 | f = gaim_request_fields_get_field(fields, "mood_ashamed"); | |
| 418 | if (f && gaim_request_field_bool_get_value(f)) | |
| 419 | mask |= SILC_ATTRIBUTE_MOOD_ASHAMED; | |
| 420 | f = gaim_request_fields_get_field(fields, "mood_invincible"); | |
| 421 | if (f && gaim_request_field_bool_get_value(f)) | |
| 422 | mask |= SILC_ATTRIBUTE_MOOD_INVINCIBLE; | |
| 423 | f = gaim_request_fields_get_field(fields, "mood_inlove"); | |
| 424 | if (f && gaim_request_field_bool_get_value(f)) | |
| 425 | mask |= SILC_ATTRIBUTE_MOOD_INLOVE; | |
| 426 | f = gaim_request_fields_get_field(fields, "mood_sleepy"); | |
| 427 | if (f && gaim_request_field_bool_get_value(f)) | |
| 428 | mask |= SILC_ATTRIBUTE_MOOD_SLEEPY; | |
| 429 | f = gaim_request_fields_get_field(fields, "mood_bored"); | |
| 430 | if (f && gaim_request_field_bool_get_value(f)) | |
| 431 | mask |= SILC_ATTRIBUTE_MOOD_BORED; | |
| 432 | f = gaim_request_fields_get_field(fields, "mood_excited"); | |
| 433 | if (f && gaim_request_field_bool_get_value(f)) | |
| 434 | mask |= SILC_ATTRIBUTE_MOOD_EXCITED; | |
| 435 | f = gaim_request_fields_get_field(fields, "mood_anxious"); | |
| 436 | if (f && gaim_request_field_bool_get_value(f)) | |
| 437 | mask |= SILC_ATTRIBUTE_MOOD_ANXIOUS; | |
| 438 | silc_client_attribute_add(client, conn, | |
| 439 | SILC_ATTRIBUTE_STATUS_MOOD, | |
| 440 | SILC_32_TO_PTR(mask), | |
| 441 | sizeof(SilcUInt32)); | |
| 442 | ||
| 443 | /* Set preferred contact */ | |
| 444 | mask = 0; | |
| 445 | f = gaim_request_fields_get_field(fields, "contact_chat"); | |
| 446 | if (f && gaim_request_field_bool_get_value(f)) | |
| 447 | mask |= SILC_ATTRIBUTE_CONTACT_CHAT; | |
| 448 | f = gaim_request_fields_get_field(fields, "contact_email"); | |
| 449 | if (f && gaim_request_field_bool_get_value(f)) | |
| 450 | mask |= SILC_ATTRIBUTE_CONTACT_EMAIL; | |
| 451 | f = gaim_request_fields_get_field(fields, "contact_call"); | |
| 452 | if (f && gaim_request_field_bool_get_value(f)) | |
| 453 | mask |= SILC_ATTRIBUTE_CONTACT_CALL; | |
| 454 | f = gaim_request_fields_get_field(fields, "contact_sms"); | |
| 455 | if (f && gaim_request_field_bool_get_value(f)) | |
| 456 | mask |= SILC_ATTRIBUTE_CONTACT_SMS; | |
| 457 | f = gaim_request_fields_get_field(fields, "contact_mms"); | |
| 458 | if (f && gaim_request_field_bool_get_value(f)) | |
| 459 | mask |= SILC_ATTRIBUTE_CONTACT_MMS; | |
| 460 | f = gaim_request_fields_get_field(fields, "contact_video"); | |
| 461 | if (f && gaim_request_field_bool_get_value(f)) | |
| 462 | mask |= SILC_ATTRIBUTE_CONTACT_VIDEO; | |
| 463 | if (mask) | |
| 464 | silc_client_attribute_add(client, conn, | |
| 465 | SILC_ATTRIBUTE_PREFERRED_CONTACT, | |
| 466 | SILC_32_TO_PTR(mask), | |
| 467 | sizeof(SilcUInt32)); | |
| 468 | ||
| 469 | /* Set status text */ | |
| 470 | val = NULL; | |
| 471 | f = gaim_request_fields_get_field(fields, "status_text"); | |
| 472 | if (f) | |
| 473 | val = gaim_request_field_string_get_value(f); | |
| 474 | if (val && *val) | |
| 475 | silc_client_attribute_add(client, conn, | |
| 476 | SILC_ATTRIBUTE_STATUS_FREETEXT, | |
| 477 | (void *)val, strlen(val)); | |
| 478 | ||
| 479 | /* Set vcard */ | |
| 480 | val = NULL; | |
| 481 | f = gaim_request_fields_get_field(fields, "vcard"); | |
| 482 | if (f) | |
| 483 | val = gaim_request_field_string_get_value(f); | |
| 484 | if (val && *val) { | |
| 485 | gaim_prefs_set_string("/plugins/prpl/silc/vcard", val); | |
| 486 | gaim_prefs_sync(); | |
| 487 | tmp = silc_file_readfile(val, &tmp_len); | |
| 488 | if (tmp) { | |
| 489 | tmp[tmp_len] = 0; | |
| 490 | if (silc_vcard_decode(tmp, tmp_len, &vcard)) | |
| 491 | silc_client_attribute_add(client, conn, | |
| 492 | SILC_ATTRIBUTE_USER_INFO, | |
| 493 | (void *)&vcard, | |
| 494 | sizeof(vcard)); | |
| 495 | } | |
| 496 | silc_vcard_free(&vcard); | |
| 497 | silc_free(tmp); | |
| 498 | } | |
| 499 | ||
| 500 | #ifdef HAVE_SYS_UTSNAME_H | |
| 501 | /* Set device info */ | |
| 502 | f = gaim_request_fields_get_field(fields, "device"); | |
| 503 | if (f && gaim_request_field_bool_get_value(f)) { | |
| 504 | struct utsname u; | |
| 505 | if (!uname(&u)) { | |
| 506 | dev.type = SILC_ATTRIBUTE_DEVICE_COMPUTER; | |
| 507 | dev.version = u.release; | |
| 508 | dev.model = u.sysname; | |
| 509 | silc_client_attribute_add(client, conn, | |
| 510 | SILC_ATTRIBUTE_DEVICE_INFO, | |
| 511 | (void *)&dev, sizeof(dev)); | |
| 512 | } | |
| 513 | } | |
| 514 | #endif | |
| 515 | ||
| 516 | /* Set timezone */ | |
| 517 | val = NULL; | |
| 518 | f = gaim_request_fields_get_field(fields, "timezone"); | |
| 519 | if (f) | |
| 520 | val = gaim_request_field_string_get_value(f); | |
| 521 | if (val && *val) | |
| 522 | silc_client_attribute_add(client, conn, | |
| 523 | SILC_ATTRIBUTE_TIMEZONE, | |
| 524 | (void *)val, strlen(val)); | |
| 525 | } | |
| 526 | ||
| 527 | static void | |
| 528 | silcgaim_attrs(GaimConnection *gc) | |
| 529 | { | |
| 530 | SilcGaim sg = gc->proto_data; | |
| 531 | SilcClient client = sg->client; | |
| 532 | SilcClientConnection conn = sg->conn; | |
| 533 | GaimRequestFields *fields; | |
| 534 | GaimRequestFieldGroup *g; | |
| 535 | GaimRequestField *f; | |
| 536 | SilcHashTable attrs; | |
| 537 | SilcAttributePayload attr; | |
| 538 | gboolean mnormal = TRUE, mhappy = FALSE, msad = FALSE, | |
| 539 | mangry = FALSE, mjealous = FALSE, mashamed = FALSE, | |
| 540 | minvincible = FALSE, minlove = FALSE, msleepy = FALSE, | |
| 541 | mbored = FALSE, mexcited = FALSE, manxious = FALSE; | |
| 542 | gboolean cemail = FALSE, ccall = FALSE, csms = FALSE, | |
| 543 | cmms = FALSE, cchat = TRUE, cvideo = FALSE; | |
| 544 | gboolean device = TRUE; | |
| 545 | char status[1024]; | |
| 546 | ||
| 547 | sg = gc->proto_data; | |
| 548 | if (!sg) | |
| 549 | return; | |
| 550 | ||
| 551 | memset(status, 0, sizeof(status)); | |
| 552 | ||
| 553 | attrs = silc_client_attributes_get(client, conn); | |
| 554 | if (attrs) { | |
| 555 | if (silc_hash_table_find(attrs, | |
| 556 | SILC_32_TO_PTR(SILC_ATTRIBUTE_STATUS_MOOD), | |
| 557 | NULL, (void *)&attr)) { | |
| 558 | SilcUInt32 mood = 0; | |
| 559 | silc_attribute_get_object(attr, &mood, sizeof(mood)); | |
| 560 | mnormal = !mood; | |
| 561 | mhappy = (mood & SILC_ATTRIBUTE_MOOD_HAPPY); | |
| 562 | msad = (mood & SILC_ATTRIBUTE_MOOD_SAD); | |
| 563 | mangry = (mood & SILC_ATTRIBUTE_MOOD_ANGRY); | |
| 564 | mjealous = (mood & SILC_ATTRIBUTE_MOOD_JEALOUS); | |
| 565 | mashamed = (mood & SILC_ATTRIBUTE_MOOD_ASHAMED); | |
| 566 | minvincible = (mood & SILC_ATTRIBUTE_MOOD_INVINCIBLE); | |
| 567 | minlove = (mood & SILC_ATTRIBUTE_MOOD_INLOVE); | |
| 568 | msleepy = (mood & SILC_ATTRIBUTE_MOOD_SLEEPY); | |
| 569 | mbored = (mood & SILC_ATTRIBUTE_MOOD_BORED); | |
| 570 | mexcited = (mood & SILC_ATTRIBUTE_MOOD_EXCITED); | |
| 571 | manxious = (mood & SILC_ATTRIBUTE_MOOD_ANXIOUS); | |
| 572 | } | |
| 573 | ||
| 574 | if (silc_hash_table_find(attrs, | |
| 575 | SILC_32_TO_PTR(SILC_ATTRIBUTE_PREFERRED_CONTACT), | |
| 576 | NULL, (void *)&attr)) { | |
| 577 | SilcUInt32 contact = 0; | |
| 578 | silc_attribute_get_object(attr, &contact, sizeof(contact)); | |
| 579 | cemail = (contact & SILC_ATTRIBUTE_CONTACT_EMAIL); | |
| 580 | ccall = (contact & SILC_ATTRIBUTE_CONTACT_CALL); | |
| 581 | csms = (contact & SILC_ATTRIBUTE_CONTACT_SMS); | |
| 582 | cmms = (contact & SILC_ATTRIBUTE_CONTACT_MMS); | |
| 583 | cchat = (contact & SILC_ATTRIBUTE_CONTACT_CHAT); | |
| 584 | cvideo = (contact & SILC_ATTRIBUTE_CONTACT_VIDEO); | |
| 585 | } | |
| 586 | ||
| 587 | if (silc_hash_table_find(attrs, | |
| 588 | SILC_32_TO_PTR(SILC_ATTRIBUTE_STATUS_FREETEXT), | |
| 589 | NULL, (void *)&attr)) | |
| 590 | silc_attribute_get_object(attr, &status, sizeof(status)); | |
| 591 | ||
| 592 | if (!silc_hash_table_find(attrs, | |
| 593 | SILC_32_TO_PTR(SILC_ATTRIBUTE_DEVICE_INFO), | |
| 594 | NULL, (void *)&attr)) | |
| 595 | device = FALSE; | |
| 596 | } | |
| 597 | ||
| 598 | fields = gaim_request_fields_new(); | |
| 599 | ||
| 600 | g = gaim_request_field_group_new(NULL); | |
| 601 | f = gaim_request_field_label_new("l3", _("Your Current Mood")); | |
| 602 | gaim_request_field_group_add_field(g, f); | |
| 603 | f = gaim_request_field_bool_new("mood_normal", _("Normal"), mnormal); | |
| 604 | gaim_request_field_group_add_field(g, f); | |
| 605 | f = gaim_request_field_bool_new("mood_happy", _("Happy"), mhappy); | |
| 606 | gaim_request_field_group_add_field(g, f); | |
| 607 | f = gaim_request_field_bool_new("mood_sad", _("Sad"), msad); | |
| 608 | gaim_request_field_group_add_field(g, f); | |
| 609 | f = gaim_request_field_bool_new("mood_angry", _("Angry"), mangry); | |
| 610 | gaim_request_field_group_add_field(g, f); | |
| 611 | f = gaim_request_field_bool_new("mood_jealous", _("Jealous"), mjealous); | |
| 612 | gaim_request_field_group_add_field(g, f); | |
| 613 | f = gaim_request_field_bool_new("mood_ashamed", _("Ashamed"), mashamed); | |
| 614 | gaim_request_field_group_add_field(g, f); | |
| 615 | f = gaim_request_field_bool_new("mood_invincible", _("Invincible"), minvincible); | |
| 616 | gaim_request_field_group_add_field(g, f); | |
| 617 | f = gaim_request_field_bool_new("mood_inlove", _("In Love"), minlove); | |
| 618 | gaim_request_field_group_add_field(g, f); | |
| 619 | f = gaim_request_field_bool_new("mood_sleepy", _("Sleepy"), msleepy); | |
| 620 | gaim_request_field_group_add_field(g, f); | |
| 621 | f = gaim_request_field_bool_new("mood_bored", _("Bored"), mbored); | |
| 622 | gaim_request_field_group_add_field(g, f); | |
| 623 | f = gaim_request_field_bool_new("mood_excited", _("Excited"), mexcited); | |
| 624 | gaim_request_field_group_add_field(g, f); | |
| 625 | f = gaim_request_field_bool_new("mood_anxious", _("Anxious"), manxious); | |
| 626 | gaim_request_field_group_add_field(g, f); | |
| 627 | ||
| 628 | f = gaim_request_field_label_new("l4", _("\nYour Preferred Contact Methods")); | |
| 629 | gaim_request_field_group_add_field(g, f); | |
| 630 | f = gaim_request_field_bool_new("contact_chat", _("Chat"), cchat); | |
| 631 | gaim_request_field_group_add_field(g, f); | |
| 632 | f = gaim_request_field_bool_new("contact_email", _("Email"), cemail); | |
| 633 | gaim_request_field_group_add_field(g, f); | |
| 634 | f = gaim_request_field_bool_new("contact_call", _("Phone"), ccall); | |
| 635 | gaim_request_field_group_add_field(g, f); | |
| 636 | f = gaim_request_field_bool_new("contact_sms", _("SMS"), csms); | |
| 637 | gaim_request_field_group_add_field(g, f); | |
| 638 | f = gaim_request_field_bool_new("contact_mms", _("MMS"), cmms); | |
| 639 | gaim_request_field_group_add_field(g, f); | |
| 640 | f = gaim_request_field_bool_new("contact_video", _("Video Conferencing"), cvideo); | |
| 641 | gaim_request_field_group_add_field(g, f); | |
| 642 | gaim_request_fields_add_group(fields, g); | |
| 643 | ||
| 644 | g = gaim_request_field_group_new(NULL); | |
| 645 | f = gaim_request_field_string_new("status_text", _("Your Current Status"), | |
| 646 | status[0] ? status : NULL, TRUE); | |
| 647 | gaim_request_field_group_add_field(g, f); | |
| 648 | gaim_request_fields_add_group(fields, g); | |
| 649 | ||
| 650 | g = gaim_request_field_group_new(NULL); | |
| 651 | #if 0 | |
| 652 | f = gaim_request_field_label_new("l2", _("Online Services")); | |
| 653 | gaim_request_field_group_add_field(g, f); | |
| 654 | f = gaim_request_field_bool_new("services", | |
| 655 | _("Let others see what services you are using"), | |
| 656 | TRUE); | |
| 657 | gaim_request_field_group_add_field(g, f); | |
| 658 | #endif | |
| 659 | #ifdef HAVE_SYS_UTSNAME_H | |
| 660 | f = gaim_request_field_bool_new("device", | |
| 661 | _("Let others see what computer you are using"), | |
| 662 | device); | |
| 663 | gaim_request_field_group_add_field(g, f); | |
| 664 | #endif | |
| 665 | gaim_request_fields_add_group(fields, g); | |
| 666 | ||
| 667 | g = gaim_request_field_group_new(NULL); | |
| 668 | f = gaim_request_field_string_new("vcard", _("Your VCard File"), | |
| 669 | gaim_prefs_get_string("/plugins/prpl/silc/vcard"), | |
| 670 | FALSE); | |
| 671 | gaim_request_field_group_add_field(g, f); | |
| 672 | #ifdef _WIN32 | |
| 673 | f = gaim_request_field_string_new("timezone", _("Timezone"), _tzname[0], FALSE); | |
| 674 | #else | |
| 675 | f = gaim_request_field_string_new("timezone", _("Timezone"), tzname[0], FALSE); | |
| 676 | #endif | |
| 677 | gaim_request_field_group_add_field(g, f); | |
| 678 | gaim_request_fields_add_group(fields, g); | |
| 679 | ||
| 680 | ||
| 681 | gaim_request_fields(NULL, _("User Online Status Attributes"), | |
| 682 | _("User Online Status Attributes"), | |
| 683 | _("You can let other users see your online status information " | |
| 684 | "and your personal information. Please fill the information " | |
| 685 | "you would like other users to see about yourself."), | |
| 686 | fields, | |
| 8906 | 687 | _("OK"), G_CALLBACK(silcgaim_attrs_cb), |
| 688 | _("Cancel"), G_CALLBACK(silcgaim_attrs_cancel), gc); | |
| 8849 | 689 | } |
| 690 | ||
| 691 | static void | |
| 692 | silcgaim_detach(GaimConnection *gc) | |
| 693 | { | |
| 694 | SilcGaim sg; | |
| 695 | ||
| 696 | if (!gc) | |
| 697 | return; | |
| 698 | sg = gc->proto_data; | |
| 699 | if (!sg) | |
| 700 | return; | |
| 701 | ||
| 702 | /* Call DETACH */ | |
| 703 | silc_client_command_call(sg->client, sg->conn, "DETACH"); | |
| 704 | sg->detaching = TRUE; | |
| 705 | } | |
| 706 | ||
| 707 | static void | |
| 708 | silcgaim_view_motd(GaimConnection *gc) | |
| 709 | { | |
| 710 | SilcGaim sg; | |
| 711 | ||
| 712 | if (!gc) | |
| 713 | return; | |
| 714 | sg = gc->proto_data; | |
| 715 | if (!sg) | |
| 716 | return; | |
| 717 | ||
| 718 | if (!sg->motd) { | |
| 719 | gaim_notify_error( | |
| 720 | gc, _("Message of the Day"), _("No Message of the Day available"), | |
| 721 | _("There is no Message of the Day associated with this connection")); | |
| 722 | return; | |
| 723 | } | |
| 724 | ||
| 725 | gaim_notify_formatted(gc, "Message of the Day", "Message of the Day", NULL, | |
| 726 | sg->motd, NULL, NULL); | |
| 727 | } | |
| 728 | ||
| 729 | static GList * | |
| 730 | silcgaim_actions(GaimConnection *gc) | |
| 731 | { | |
| 732 | struct proto_actions_menu *pam; | |
| 733 | GList *list = NULL; | |
| 734 | ||
| 735 | if (!gaim_account_get_bool(gc->account, "reject-attrs", FALSE)) { | |
| 736 | pam = g_new0(struct proto_actions_menu, 1); | |
| 737 | pam->label = _("Online Status"); | |
| 738 | pam->callback = silcgaim_attrs; | |
| 739 | pam->gc = gc; | |
| 740 | list = g_list_append(list, pam); | |
| 741 | } | |
| 742 | ||
| 743 | pam = g_new0(struct proto_actions_menu, 1); | |
| 744 | pam->label = _("Detach From Server"); | |
| 745 | pam->callback = silcgaim_detach; | |
| 746 | pam->gc = gc; | |
| 747 | list = g_list_append(list, pam); | |
| 748 | ||
| 749 | pam = g_new0(struct proto_actions_menu, 1); | |
| 750 | pam->label = _("View Message of the Day"); | |
| 751 | pam->callback = silcgaim_view_motd; | |
| 752 | pam->gc = gc; | |
| 753 | list = g_list_append(list, pam); | |
| 754 | ||
| 755 | return list; | |
| 756 | } | |
| 757 | ||
| 758 | ||
| 759 | /******************************* IM Routines *********************************/ | |
| 760 | ||
| 761 | typedef struct { | |
| 762 | char *nick; | |
| 763 | unsigned char *message; | |
| 764 | SilcUInt32 message_len; | |
| 765 | SilcMessageFlags flags; | |
| 766 | } *SilcGaimIM; | |
| 767 | ||
| 768 | static void | |
| 769 | silcgaim_send_im_resolved(SilcClient client, | |
| 770 | SilcClientConnection conn, | |
| 771 | SilcClientEntry *clients, | |
| 772 | SilcUInt32 clients_count, | |
| 773 | void *context) | |
| 774 | { | |
| 775 | GaimConnection *gc = client->application; | |
| 776 | SilcGaim sg = gc->proto_data; | |
| 777 | SilcGaimIM im = context; | |
| 778 | GaimConversation *convo; | |
| 779 | char tmp[256], *nickname = NULL; | |
| 780 | SilcClientEntry client_entry; | |
| 781 | ||
| 782 | convo = gaim_find_conversation_with_account(im->nick, sg->account); | |
| 783 | if (!convo) | |
| 784 | return; | |
| 785 | ||
| 786 | if (!clients) | |
| 787 | goto err; | |
| 788 | ||
| 789 | if (clients_count > 1) { | |
| 790 | silc_parse_userfqdn(im->nick, &nickname, NULL); | |
| 791 | ||
| 792 | /* Find the correct one. The im->nick might be a formatted nick | |
| 793 | so this will find the correct one. */ | |
| 794 | clients = silc_client_get_clients_local(client, conn, | |
| 795 | nickname, im->nick, | |
| 796 | &clients_count); | |
| 797 | if (!clients) | |
| 798 | goto err; | |
| 799 | client_entry = clients[0]; | |
| 800 | silc_free(clients); | |
| 801 | } else { | |
| 802 | client_entry = clients[0]; | |
| 803 | } | |
| 804 | ||
| 805 | /* Send the message */ | |
| 806 | silc_client_send_private_message(client, conn, client_entry, im->flags, | |
| 807 | im->message, im->message_len, TRUE); | |
| 808 | gaim_conv_im_write(GAIM_CONV_IM(convo), conn->local_entry->nickname, | |
| 809 | im->message, 0, time(NULL)); | |
| 810 | ||
| 811 | goto out; | |
| 812 | ||
| 813 | err: | |
| 814 | g_snprintf(tmp, sizeof(tmp), | |
| 815 | _("User <I>%s</I> is not present in the network"), im->nick); | |
| 816 | gaim_conversation_write(convo, NULL, tmp, GAIM_MESSAGE_SYSTEM, time(NULL)); | |
| 817 | ||
| 818 | out: | |
| 819 | g_free(im->nick); | |
| 820 | g_free(im->message); | |
| 821 | silc_free(im); | |
| 822 | silc_free(nickname); | |
| 823 | } | |
| 824 | ||
| 825 | static int | |
| 826 | silcgaim_send_im(GaimConnection *gc, const char *who, const char *msg, | |
| 827 | GaimConvImFlags flags) | |
| 828 | { | |
| 829 | SilcGaim sg = gc->proto_data; | |
| 830 | SilcClient client = sg->client; | |
| 831 | SilcClientConnection conn = sg->conn; | |
| 832 | SilcClientEntry *clients; | |
| 833 | SilcUInt32 clients_count, mflags; | |
| 834 | char *nickname; | |
| 835 | int ret; | |
| 836 | gboolean sign = gaim_prefs_get_bool("/plugins/prpl/silc/sign_im"); | |
| 837 | ||
| 838 | if (!who || !msg) | |
| 839 | return 0; | |
| 840 | ||
| 841 | /* See if command */ | |
| 842 | if (strlen(msg) > 1 && msg[0] == '/') { | |
| 843 | if (!silc_client_command_call(client, conn, msg + 1)) | |
| 844 | gaim_notify_error(gc, ("Call Command"), _("Cannot call command"), | |
| 845 | _("Unknown command")); | |
| 846 | return 0; | |
| 847 | } | |
| 848 | ||
| 849 | if (!silc_parse_userfqdn(who, &nickname, NULL)) | |
| 850 | return 0; | |
| 851 | ||
| 852 | mflags = SILC_MESSAGE_FLAG_UTF8; | |
| 853 | if (sign) | |
| 854 | mflags |= SILC_MESSAGE_FLAG_SIGNED; | |
| 855 | ||
| 856 | /* Find client entry */ | |
| 857 | clients = silc_client_get_clients_local(client, conn, nickname, who, | |
| 858 | &clients_count); | |
| 859 | if (!clients) { | |
| 860 | /* Resolve unknown user */ | |
| 861 | SilcGaimIM im = silc_calloc(1, sizeof(*im)); | |
| 862 | if (!im) | |
| 863 | return 0; | |
| 864 | im->nick = g_strdup(who); | |
| 865 | im->message = g_strdup(msg); | |
| 866 | im->message_len = strlen(im->message); | |
| 867 | im->flags = mflags; | |
| 868 | silc_client_get_clients(client, conn, nickname, NULL, | |
| 869 | silcgaim_send_im_resolved, im); | |
| 870 | silc_free(nickname); | |
| 871 | return 0; | |
| 872 | } | |
| 873 | ||
| 874 | /* Send private message directly */ | |
| 875 | ret = silc_client_send_private_message(client, conn, clients[0], | |
| 876 | mflags, (char *)msg, | |
| 877 | strlen(msg), TRUE); | |
| 878 | ||
| 879 | silc_free(nickname); | |
| 880 | silc_free(clients); | |
| 881 | return ret; | |
| 882 | } | |
| 883 | ||
| 884 | ||
| 885 | /************************** Plugin Initialization ****************************/ | |
| 886 | ||
| 887 | static GaimPluginPrefFrame * | |
| 888 | silcgaim_pref_frame(GaimPlugin *plugin) | |
| 889 | { | |
| 890 | GaimPluginPrefFrame *frame; | |
| 891 | GaimPluginPref *ppref; | |
| 892 | ||
| 893 | frame = gaim_plugin_pref_frame_new(); | |
| 894 | ||
| 895 | ppref = gaim_plugin_pref_new_with_label(_("Instant Messages")); | |
| 896 | gaim_plugin_pref_frame_add(frame, ppref); | |
| 897 | ||
| 898 | ppref = gaim_plugin_pref_new_with_name_and_label( | |
| 899 | "/plugins/prpl/silc/sign_im", | |
| 900 | _("Digitally sign all IM messages")); | |
| 901 | gaim_plugin_pref_frame_add(frame, ppref); | |
| 902 | ||
| 903 | ppref = gaim_plugin_pref_new_with_name_and_label( | |
| 904 | "/plugins/prpl/silc/verify_im", | |
| 905 | _("Verify all IM message signatures")); | |
| 906 | gaim_plugin_pref_frame_add(frame, ppref); | |
| 907 | ||
| 908 | ppref = gaim_plugin_pref_new_with_label(_("Channel Messages")); | |
| 909 | gaim_plugin_pref_frame_add(frame, ppref); | |
| 910 | ||
| 911 | ppref = gaim_plugin_pref_new_with_name_and_label( | |
| 912 | "/plugins/prpl/silc/sign_chat", | |
| 913 | _("Digitally sign all channel messages")); | |
| 914 | gaim_plugin_pref_frame_add(frame, ppref); | |
| 915 | ||
| 916 | ppref = gaim_plugin_pref_new_with_name_and_label( | |
| 917 | "/plugins/prpl/silc/verify_chat", | |
| 918 | _("Verify all channel message signatures")); | |
| 919 | gaim_plugin_pref_frame_add(frame, ppref); | |
| 920 | ||
| 921 | ppref = gaim_plugin_pref_new_with_label(_("Default SILC Key Pair")); | |
| 922 | gaim_plugin_pref_frame_add(frame, ppref); | |
| 923 | ||
| 924 | ppref = gaim_plugin_pref_new_with_name_and_label( | |
| 925 | "/plugins/prpl/silc/pubkey", | |
| 926 | _("SILC Public Key")); | |
| 927 | gaim_plugin_pref_frame_add(frame, ppref); | |
| 928 | ||
| 929 | ppref = gaim_plugin_pref_new_with_name_and_label( | |
| 930 | "/plugins/prpl/silc/privkey", | |
| 931 | _("SILC Private Key")); | |
| 932 | gaim_plugin_pref_frame_add(frame, ppref); | |
| 933 | ||
| 934 | return frame; | |
| 935 | } | |
| 936 | ||
| 937 | static GaimPluginUiInfo prefs_info = | |
| 938 | { | |
| 939 | silcgaim_pref_frame, | |
| 940 | }; | |
| 941 | ||
| 942 | static GaimPluginProtocolInfo prpl_info = | |
| 943 | { | |
| 944 | GAIM_PRPL_API_VERSION, | |
| 945 | OPT_PROTO_CHAT_TOPIC | OPT_PROTO_UNIQUE_CHATNAME | | |
| 946 | OPT_PROTO_PASSWORD_OPTIONAL, | |
| 947 | NULL, | |
| 948 | NULL, | |
| 949 | silcgaim_list_icon, | |
| 950 | silcgaim_list_emblems, | |
| 951 | silcgaim_status_text, | |
| 952 | silcgaim_tooltip_text, | |
| 953 | silcgaim_away_states, | |
| 954 | silcgaim_actions, | |
| 955 | silcgaim_buddy_menu, | |
| 956 | silcgaim_chat_info, | |
| 957 | silcgaim_login, | |
| 958 | silcgaim_close, | |
| 959 | silcgaim_send_im, | |
| 960 | NULL, | |
| 961 | NULL, | |
| 962 | silcgaim_get_info, | |
| 963 | silcgaim_set_away, | |
| 964 | silcgaim_idle_set, | |
| 965 | NULL, | |
| 966 | silcgaim_add_buddy, | |
| 967 | silcgaim_add_buddies, | |
| 968 | silcgaim_remove_buddy, | |
| 969 | NULL, | |
| 970 | NULL, | |
| 971 | NULL, | |
| 972 | NULL, | |
| 973 | NULL, | |
| 974 | NULL, | |
| 975 | NULL, | |
| 976 | silcgaim_chat_join, | |
| 977 | NULL, | |
| 978 | silcgaim_chat_invite, | |
| 979 | silcgaim_chat_leave, | |
| 980 | NULL, | |
| 981 | silcgaim_chat_send, | |
| 982 | silcgaim_keepalive, | |
| 983 | NULL, | |
| 984 | NULL, | |
| 985 | NULL, | |
| 986 | NULL, | |
| 987 | NULL, | |
| 988 | NULL, | |
| 989 | NULL, | |
| 990 | NULL, | |
| 991 | NULL, | |
| 992 | NULL, | |
| 993 | NULL, | |
| 994 | NULL, | |
| 995 | silcgaim_chat_set_topic, | |
| 996 | NULL, | |
| 997 | silcgaim_roomlist_get_list, | |
| 998 | silcgaim_roomlist_cancel, | |
| 999 | NULL, | |
| 1000 | silcgaim_chat_menu | |
| 1001 | }; | |
| 1002 | ||
| 1003 | static GaimPluginInfo info = | |
| 1004 | { | |
| 1005 | GAIM_PLUGIN_API_VERSION, /**< api_version */ | |
| 1006 | GAIM_PLUGIN_PROTOCOL, /**< type */ | |
| 1007 | NULL, /**< ui_requirement */ | |
| 1008 | 0, /**< flags */ | |
| 1009 | NULL, /**< dependencies */ | |
| 1010 | GAIM_PRIORITY_DEFAULT, /**< priority */ | |
| 1011 | ||
| 1012 | "prpl-silc", /**< id */ | |
| 1013 | "SILC", /**< name */ | |
| 1014 | "1.0", /**< version */ | |
| 1015 | /** summary */ | |
| 1016 | N_("SILC Protocol Plugin"), | |
| 1017 | /** description */ | |
| 1018 | N_("Secure Internet Live Conferencing (SILC) Protocol"), | |
| 8891 | 1019 | "Pekka Riikonen", /**< author */ |
| 1020 | "http://silcnet.org/", /**< homepage */ | |
| 8849 | 1021 | |
| 1022 | NULL, /**< load */ | |
| 1023 | NULL, /**< unload */ | |
| 1024 | NULL, /**< destroy */ | |
| 1025 | ||
| 1026 | NULL, /**< ui_info */ | |
| 1027 | &prpl_info, /**< extra_info */ | |
| 8993 | 1028 | &prefs_info, /**< prefs_info */ |
| 1029 | NULL | |
| 8849 | 1030 | }; |
| 1031 | ||
| 1032 | static void | |
| 1033 | init_plugin(GaimPlugin *plugin) | |
| 1034 | { | |
| 1035 | GaimAccountOption *option; | |
| 1036 | char tmp[256]; | |
| 1037 | ||
| 1038 | silc_plugin = plugin; | |
| 1039 | ||
| 1040 | /* Account options */ | |
| 1041 | option = gaim_account_option_string_new(_("Connect server"), | |
| 1042 | "server", | |
| 1043 | "silc.silcnet.org"); | |
| 1044 | prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); | |
| 1045 | option = gaim_account_option_int_new(_("Port"), "port", 706); | |
| 1046 | prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); | |
| 1047 | ||
| 1048 | option = gaim_account_option_bool_new(_("Public key authentication"), | |
| 1049 | "pubkey-auth", FALSE); | |
| 1050 | prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); | |
| 1051 | #if 0 /* XXX Public key auth interface with explicit key pair is | |
| 1052 | broken in SILC Toolkit */ | |
| 8891 | 1053 | g_snprintf(tmp, sizeof(tmp), "%s/public_key.pub", silcgaim_silcdir()); |
| 8849 | 1054 | option = gaim_account_option_string_new(_("Public Key File"), |
| 1055 | "public-key", tmp); | |
| 1056 | prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); | |
| 8891 | 1057 | g_snprintf(tmp, sizeof(tmp), "%s/private_key.prv", silcgaim_silcdir()); |
| 8849 | 1058 | option = gaim_account_option_string_new(_("Private Key File"), |
| 1059 | "public-key", tmp); | |
| 1060 | prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); | |
| 1061 | #endif | |
| 1062 | ||
| 1063 | option = gaim_account_option_bool_new(_("Reject watching by other users"), | |
| 1064 | "reject-watch", FALSE); | |
| 1065 | prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); | |
| 1066 | option = gaim_account_option_bool_new(_("Block invites"), | |
| 1067 | "block-invites", FALSE); | |
| 1068 | prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); | |
| 1069 | option = gaim_account_option_bool_new(_("Block IMs without Key Exchange"), | |
| 1070 | "block-ims", FALSE); | |
| 1071 | prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); | |
| 1072 | option = gaim_account_option_bool_new(_("Reject online status attribute requests"), | |
| 1073 | "reject-attrs", FALSE); | |
| 1074 | prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); | |
| 1075 | ||
| 1076 | /* Preferences */ | |
| 1077 | gaim_prefs_add_none("/plugins/prpl/silc"); | |
| 1078 | gaim_prefs_add_bool("/plugins/prpl/silc/sign_im", FALSE); | |
| 1079 | gaim_prefs_add_bool("/plugins/prpl/silc/verify_im", FALSE); | |
| 1080 | gaim_prefs_add_bool("/plugins/prpl/silc/sign_chat", FALSE); | |
| 1081 | gaim_prefs_add_bool("/plugins/prpl/silc/verify_chat", FALSE); | |
| 8891 | 1082 | g_snprintf(tmp, sizeof(tmp), "%s/public_key.pub", silcgaim_silcdir()); |
| 8849 | 1083 | gaim_prefs_add_string("/plugins/prpl/silc/pubkey", tmp); |
| 8891 | 1084 | g_snprintf(tmp, sizeof(tmp), "%s/private_key.prv", silcgaim_silcdir()); |
| 8849 | 1085 | gaim_prefs_add_string("/plugins/prpl/silc/privkey", tmp); |
| 1086 | gaim_prefs_add_string("/plugins/prpl/silc/vcard", ""); | |
| 1087 | } | |
| 1088 | ||
| 1089 | GAIM_INIT_PLUGIN(silc, init_plugin, info); |