Mercurial > pidgin
annotate src/protocols/rendezvous/rendezvous.c @ 9165:43ea2b858112
[gaim-migrate @ 9950]
Patch by Felipe Contreras, and modified slightly by me to prevent
disconnects on Switchboard errors in MSN. Now, it just displays the error
dialog for switchboards, but keeps the disconnects for everything else. I
was sure I committed this before 0.78, but something happened. *baffled*
committer: Tailor Script <tailor@pidgin.im>
| author | Christian Hammond <chipx86@chipx86.com> |
|---|---|
| date | Wed, 02 Jun 2004 04:50:31 +0000 |
| parents | 294ae6548d4e |
| children | a2792c5f3ffd |
| rev | line source |
|---|---|
| 8487 | 1 /* |
| 2 * gaim - Rendezvous Protocol Plugin | |
| 3 * | |
| 4 * Gaim is the legal property of its developers, whose names are too numerous | |
| 5 * to list here. Please refer to the COPYRIGHT file distributed with this | |
| 6 * source distribution. | |
| 7 * | |
| 8 * This program is free software; you can redistribute it and/or modify | |
| 9 * it under the terms of the GNU General Public License as published by | |
| 10 * the Free Software Foundation; either version 2 of the License, or | |
| 11 * (at your option) any later version. | |
| 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 * You should have received a copy of the GNU General Public License | |
| 19 * along with this program; if not, write to the Free Software | |
| 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
| 21 */ | |
| 22 #include "internal.h" | |
| 23 | |
| 24 #include "account.h" | |
| 25 #include "accountopt.h" | |
| 26 #include "blist.h" | |
| 27 #include "conversation.h" | |
| 28 #include "debug.h" | |
| 8834 | 29 #include "network.h" |
| 8487 | 30 #include "prpl.h" |
| 31 | |
| 32 #include "mdns.h" | |
| 33 #include "util.h" | |
| 34 | |
| 35 #define RENDEZVOUS_CONNECT_STEPS 2 | |
| 36 | |
| 37 typedef struct _RendezvousData { | |
| 38 int fd; | |
| 39 GHashTable *buddies; | |
| 8629 | 40 GSList *mytxtdata; |
| 8487 | 41 } RendezvousData; |
| 42 | |
| 43 typedef struct _RendezvousBuddy { | |
| 8612 | 44 #if 0 |
| 45 guint ttltimer; | |
| 46 #endif | |
| 8487 | 47 gchar *firstandlast; |
| 48 gchar *aim; | |
| 8834 | 49 int ip[4]; |
| 8487 | 50 int p2pjport; |
| 51 int status; | |
| 52 int idle; | |
| 53 gchar *msg; | |
| 54 } RendezvousBuddy; | |
| 55 | |
| 56 #define UC_IDLE 2 | |
| 57 | |
| 58 /****************************/ | |
| 59 /* Utility Functions */ | |
| 60 /****************************/ | |
| 61 static void rendezvous_buddy_free(gpointer data) | |
| 62 { | |
| 63 RendezvousBuddy *rb = data; | |
| 64 | |
| 65 g_free(rb->firstandlast); | |
| 66 g_free(rb->msg); | |
| 67 g_free(rb); | |
| 68 } | |
| 69 | |
| 8546 | 70 /** |
| 8487 | 71 * Extract the "user@host" name from a full presence domain |
| 72 * of the form "user@host._presence._tcp.local" | |
| 73 * | |
| 74 * @return If the domain is NOT a _presence._tcp.local domain | |
| 75 * then return NULL. Otherwise return a newly allocated | |
| 76 * null-terminated string containing the "user@host" for | |
| 77 * the given domain. This string should be g_free'd | |
| 78 * when no longer needed. | |
| 79 */ | |
| 80 static gchar *rendezvous_extract_name(gchar *domain) | |
| 81 { | |
| 82 gchar *ret, *suffix; | |
| 83 | |
| 84 if (!g_str_has_suffix(domain, "._presence._tcp.local")) | |
| 85 return NULL; | |
| 86 | |
| 87 suffix = strstr(domain, "._presence._tcp.local"); | |
| 88 ret = g_strndup(domain, suffix - domain); | |
| 89 | |
| 90 return ret; | |
| 91 } | |
| 92 | |
| 93 /****************************/ | |
| 94 /* Buddy List Functions */ | |
| 95 /****************************/ | |
| 8612 | 96 |
| 8487 | 97 static void rendezvous_addtolocal(GaimConnection *gc, const char *name, const char *domain) |
| 98 { | |
| 99 GaimAccount *account = gaim_connection_get_account(gc); | |
| 100 GaimBuddy *b; | |
| 101 GaimGroup *g; | |
| 102 | |
| 103 g = gaim_find_group(domain); | |
| 104 if (g == NULL) { | |
| 105 g = gaim_group_new(domain); | |
| 106 gaim_blist_add_group(g, NULL); | |
| 107 } | |
| 108 | |
| 109 b = gaim_find_buddy_in_group(account, name, g); | |
| 110 if (b != NULL) | |
| 111 return; | |
| 112 | |
| 113 b = gaim_buddy_new(account, name, NULL); | |
| 114 gaim_blist_add_buddy(b, NULL, g, NULL); | |
| 115 serv_got_update(gc, b->name, 1, 0, 0, 0, 0); | |
| 8612 | 116 |
| 117 #if 0 | |
| 118 RendezvousBuddy *rb; | |
| 119 rb = g_hash_table_lookup(rd->buddies, name); | |
| 120 if (rb == NULL) { | |
| 121 rb = g_malloc0(sizeof(RendezvousBuddy)); | |
| 122 g_hash_table_insert(rd->buddies, g_strdup(name), rb); | |
| 123 } | |
| 124 rb->ttltimer = gaim_timeout_add(time * 10000, rendezvous_buddy_timeout, gc); | |
| 125 | |
| 126 gaim_timeout_remove(rb->ttltimer); | |
| 127 rb->ttltimer = 0; | |
| 128 #endif | |
| 8487 | 129 } |
| 130 | |
| 131 static void rendezvous_removefromlocal(GaimConnection *gc, const char *name, const char *domain) | |
| 132 { | |
| 133 GaimAccount *account = gaim_connection_get_account(gc); | |
| 134 GaimBuddy *b; | |
| 135 GaimGroup *g; | |
| 136 | |
| 137 g = gaim_find_group(domain); | |
| 138 if (g == NULL) | |
| 139 return; | |
| 140 | |
| 141 b = gaim_find_buddy_in_group(account, name, g); | |
| 142 if (b == NULL) | |
| 143 return; | |
| 144 | |
| 145 serv_got_update(gc, b->name, 0, 0, 0, 0, 0); | |
| 146 gaim_blist_remove_buddy(b); | |
| 8546 | 147 /* XXX - This results in incorrect group counts--needs to be fixed in the core */ |
| 8612 | 148 |
| 149 /* | |
| 150 * XXX - Instead of removing immediately, wait 10 seconds and THEN remove | |
| 151 * them. If you do it immediately you don't see the door close icon. | |
| 152 */ | |
| 8487 | 153 } |
| 154 | |
| 155 static void rendezvous_removeallfromlocal(GaimConnection *gc) | |
| 156 { | |
| 157 GaimAccount *account = gaim_connection_get_account(gc); | |
| 158 GaimBuddyList *blist; | |
| 159 GaimBlistNode *gnode, *cnode, *bnode; | |
| 160 GaimBuddy *b; | |
| 161 | |
| 162 /* Go through and remove all buddies that belong to this account */ | |
| 163 if ((blist = gaim_get_blist()) != NULL) { | |
| 164 for (gnode = blist->root; gnode; gnode = gnode->next) { | |
| 165 if (!GAIM_BLIST_NODE_IS_GROUP(gnode)) | |
| 166 continue; | |
| 167 for (cnode = gnode->child; cnode; cnode = cnode->next) { | |
| 168 if (!GAIM_BLIST_NODE_IS_CONTACT(cnode)) | |
| 169 continue; | |
| 170 for (bnode = cnode->child; bnode; bnode = bnode->next) { | |
| 171 if (!GAIM_BLIST_NODE_IS_BUDDY(bnode)) | |
| 172 continue; | |
| 173 b = (GaimBuddy *)bnode; | |
| 174 if (b->account != account) | |
| 175 continue; | |
| 176 serv_got_update(gc, b->name, 0, 0, 0, 0, 0); | |
| 177 gaim_blist_remove_buddy(b); | |
| 178 } | |
| 179 } | |
| 180 } | |
| 181 } | |
| 182 } | |
| 183 | |
| 8834 | 184 static void rendezvous_handle_rr_a(GaimConnection *gc, ResourceRecord *rr, const gchar *name) |
| 185 { | |
| 186 RendezvousData *rd = gc->proto_data; | |
| 187 RendezvousBuddy *rb; | |
| 188 ResourceRecordRDataSRV *rdata; | |
| 189 | |
| 190 rdata = rr->rdata; | |
| 191 | |
| 192 rb = g_hash_table_lookup(rd->buddies, name); | |
| 193 if (rb == NULL) { | |
| 194 rb = g_malloc0(sizeof(RendezvousBuddy)); | |
| 195 g_hash_table_insert(rd->buddies, g_strdup(name), rb); | |
| 196 } | |
| 197 | |
| 198 memcpy(rb->ip, rdata, 4); | |
| 199 } | |
| 200 | |
| 8487 | 201 static void rendezvous_handle_rr_txt(GaimConnection *gc, ResourceRecord *rr, const gchar *name) |
| 202 { | |
| 203 RendezvousData *rd = gc->proto_data; | |
| 204 RendezvousBuddy *rb; | |
| 8806 | 205 GSList *rdata; |
| 206 ResourceRecordRDataTXTNode *node1, *node2; | |
| 8487 | 207 |
| 8594 | 208 rdata = rr->rdata; |
| 209 | |
| 210 /* Don't do a damn thing if the version is greater than 1 */ | |
| 8806 | 211 node1 = mdns_txt_find(rdata, "version"); |
| 212 if ((node1 == NULL) || (node1->value == NULL) || (strcmp(node1->value, "1"))) | |
| 8594 | 213 return; |
| 214 | |
| 8487 | 215 rb = g_hash_table_lookup(rd->buddies, name); |
| 216 if (rb == NULL) { | |
| 217 rb = g_malloc0(sizeof(RendezvousBuddy)); | |
| 218 g_hash_table_insert(rd->buddies, g_strdup(name), rb); | |
| 219 } | |
| 220 | |
| 8806 | 221 node1 = mdns_txt_find(rdata, "1st"); |
| 222 node2 = mdns_txt_find(rdata, "last"); | |
| 8487 | 223 g_free(rb->firstandlast); |
| 224 rb->firstandlast = g_strdup_printf("%s%s%s", | |
| 8806 | 225 (node1 && node1->value ? node1->value : ""), |
| 226 (node1 && node1->value && node2 && node2->value ? " " : ""), | |
| 227 (node2 && node2->value ? node2->value : "")); | |
| 8487 | 228 serv_got_alias(gc, name, rb->firstandlast); |
| 229 | |
| 8806 | 230 node1 = mdns_txt_find(rdata, "aim"); |
| 231 if ((node1 != NULL) && (node1->value != NULL)) { | |
| 8487 | 232 g_free(rb->aim); |
| 8806 | 233 rb->aim = g_strdup(node1->value); |
| 8487 | 234 } |
| 235 | |
| 8594 | 236 /* |
| 237 * We only want to use this port as a back-up. Ideally the port | |
| 238 * is specified in a separate, SRV resource record. | |
| 239 */ | |
| 240 if (rb->p2pjport == 0) { | |
| 8806 | 241 node1 = mdns_txt_find(rdata, "port.p2pj"); |
| 242 if ((node1 != NULL) && (node1->value)) | |
| 243 rb->p2pjport = atoi(node1->value); | |
| 8594 | 244 } |
| 8487 | 245 |
| 8806 | 246 node1 = mdns_txt_find(rdata, "status");; |
| 247 if ((node1 != NULL) && (node1->value != NULL)) { | |
| 248 if (!strcmp(node1->value, "avail")) { | |
| 8487 | 249 /* Available */ |
| 250 rb->status = 0; | |
| 8806 | 251 } else if (!strcmp(node1->value, "away")) { |
| 8487 | 252 /* Idle */ |
| 8806 | 253 node2 = mdns_txt_find(rdata, "away"); |
| 254 if ((node2 != NULL) && (node2->value)) { | |
| 255 rb->idle = atoi(node2->value); | |
| 256 gaim_debug_error("XXX", "User has been idle since %d\n", rb->idle); | |
| 257 } | |
| 8487 | 258 rb->status = UC_IDLE; |
| 8806 | 259 } else if (!strcmp(node1->value, "dnd")) { |
| 8487 | 260 /* Away */ |
| 261 rb->status = UC_UNAVAILABLE; | |
| 262 } | |
| 263 serv_got_update(gc, name, 1, 0, 0, 0, rb->status); | |
| 264 } | |
| 265 | |
| 8806 | 266 node1 = mdns_txt_find(rdata, "msg"); |
| 267 if ((node1 != NULL) && (node1->value != NULL)) { | |
| 8487 | 268 g_free(rb->msg); |
| 8806 | 269 rb->msg = g_strdup(node1->value); |
| 8487 | 270 } |
| 8594 | 271 } |
| 8546 | 272 |
| 8594 | 273 static void rendezvous_handle_rr_srv(GaimConnection *gc, ResourceRecord *rr, const gchar *name) |
| 274 { | |
| 275 RendezvousData *rd = gc->proto_data; | |
| 276 RendezvousBuddy *rb; | |
| 8806 | 277 ResourceRecordRDataSRV *rdata; |
| 8594 | 278 |
| 279 rdata = rr->rdata; | |
| 280 | |
| 281 rb = g_hash_table_lookup(rd->buddies, name); | |
| 282 if (rb == NULL) { | |
| 283 rb = g_malloc0(sizeof(RendezvousBuddy)); | |
| 284 g_hash_table_insert(rd->buddies, g_strdup(name), rb); | |
| 285 } | |
| 286 | |
| 287 rb->p2pjport = rdata->port; | |
| 8487 | 288 } |
| 289 | |
| 290 /* | |
| 291 * Parse a resource record and do stuff if we need to. | |
| 292 */ | |
| 293 static void rendezvous_handle_rr(GaimConnection *gc, ResourceRecord *rr) | |
| 294 { | |
| 8636 | 295 RendezvousData *rd = gc->proto_data; |
| 8487 | 296 gchar *name; |
| 297 | |
| 8594 | 298 gaim_debug_misc("rendezvous", "Parsing resource record with domain name %s\n", rr->name); |
| 299 | |
| 8834 | 300 switch (rr->type) { |
| 301 case RENDEZVOUS_RRTYPE_A: { | |
| 302 name = rendezvous_extract_name(rr->name); | |
| 303 if (name != NULL) { | |
| 304 rendezvous_handle_rr_a(gc, rr, name); | |
| 305 g_free(name); | |
| 306 } | |
| 307 } break; | |
| 8487 | 308 |
| 309 case RENDEZVOUS_RRTYPE_NULL: { | |
| 8834 | 310 name = rendezvous_extract_name(rr->name); |
| 311 if (name != NULL) { | |
| 8487 | 312 if (rr->rdlength > 0) { |
| 313 /* Data is a buddy icon */ | |
| 314 gaim_buddy_icons_set_for_user(gaim_connection_get_account(gc), name, rr->rdata, rr->rdlength); | |
| 315 } | |
| 316 | |
| 317 g_free(name); | |
| 318 } | |
| 319 } break; | |
| 320 | |
| 321 case RENDEZVOUS_RRTYPE_PTR: { | |
| 322 gchar *rdata = rr->rdata; | |
| 8834 | 323 |
| 324 name = rendezvous_extract_name(rdata); | |
| 325 if (name != NULL) { | |
| 8636 | 326 if (rr->ttl > 0) { |
| 327 /* Add them to our buddy list and request their icon */ | |
| 8487 | 328 rendezvous_addtolocal(gc, name, "Rendezvous"); |
| 8636 | 329 mdns_query(rd->fd, rdata, RENDEZVOUS_RRTYPE_NULL); |
| 330 } else { | |
| 331 /* Remove them from our buddy list */ | |
| 8487 | 332 rendezvous_removefromlocal(gc, name, "Rendezvous"); |
| 8636 | 333 } |
| 8487 | 334 g_free(name); |
| 335 } | |
| 336 } break; | |
| 337 | |
| 338 case RENDEZVOUS_RRTYPE_TXT: { | |
| 8834 | 339 name = rendezvous_extract_name(rr->name); |
| 340 if (name != NULL) { | |
| 8487 | 341 rendezvous_handle_rr_txt(gc, rr, name); |
| 342 g_free(name); | |
| 343 } | |
| 344 } break; | |
| 8594 | 345 |
| 346 case RENDEZVOUS_RRTYPE_SRV: { | |
| 8834 | 347 name = rendezvous_extract_name(rr->name); |
| 348 if (name != NULL) { | |
| 8594 | 349 rendezvous_handle_rr_srv(gc, rr, name); |
| 350 g_free(name); | |
| 351 } | |
| 352 } break; | |
| 8487 | 353 } |
| 354 } | |
| 355 | |
| 356 /****************************/ | |
|
8735
92cbf9713795
[gaim-migrate @ 9490]
Christian Hammond <chipx86@chipx86.com>
parents:
8721
diff
changeset
|
357 /* Icon and Emblem Functions */ |
| 8487 | 358 /****************************/ |
| 359 static const char* rendezvous_prpl_list_icon(GaimAccount *a, GaimBuddy *b) | |
| 360 { | |
| 361 return "rendezvous"; | |
| 362 } | |
| 363 | |
| 364 static void rendezvous_prpl_list_emblems(GaimBuddy *b, char **se, char **sw, char **nw, char **ne) | |
| 365 { | |
| 366 if (GAIM_BUDDY_IS_ONLINE(b)) { | |
| 367 if (b->uc & UC_UNAVAILABLE) | |
| 368 *se = "away"; | |
| 369 } else { | |
| 370 *se = "offline"; | |
| 371 } | |
| 372 } | |
| 373 | |
| 374 static gchar *rendezvous_prpl_status_text(GaimBuddy *b) | |
| 375 { | |
| 376 GaimConnection *gc = b->account->gc; | |
| 377 RendezvousData *rd = gc->proto_data; | |
| 378 RendezvousBuddy *rb; | |
| 379 gchar *ret; | |
| 380 | |
| 381 rb = g_hash_table_lookup(rd->buddies, b->name); | |
| 382 if ((rb == NULL) || (rb->msg == NULL)) | |
| 383 return NULL; | |
| 384 | |
| 385 ret = g_strdup(rb->msg); | |
| 386 | |
| 387 return ret; | |
| 388 } | |
| 389 | |
| 390 static gchar *rendezvous_prpl_tooltip_text(GaimBuddy *b) | |
| 391 { | |
| 392 GaimConnection *gc = b->account->gc; | |
| 393 RendezvousData *rd = gc->proto_data; | |
| 394 RendezvousBuddy *rb; | |
| 395 GString *ret; | |
| 396 | |
| 397 rb = g_hash_table_lookup(rd->buddies, b->name); | |
| 398 if (rb == NULL) | |
| 399 return NULL; | |
| 400 | |
| 401 ret = g_string_new(""); | |
| 402 | |
| 403 if (rb->aim != NULL) | |
| 8591 | 404 g_string_append_printf(ret, "\n<b>%s</b>: %s", _("AIM Screen name"), rb->aim); |
| 8487 | 405 |
| 406 if (rb->msg != NULL) { | |
| 407 if (rb->status == UC_UNAVAILABLE) | |
| 8591 | 408 g_string_append_printf(ret, "\n<b>%s</b>: %s", _("Away"), rb->msg); |
| 8487 | 409 else |
| 8591 | 410 g_string_append_printf(ret, "\n<b>%s</b>: %s", _("Available"), rb->msg); |
| 8487 | 411 } |
| 412 | |
| 413 return g_string_free(ret, FALSE); | |
| 414 } | |
| 415 | |
| 416 /****************************/ | |
|
8735
92cbf9713795
[gaim-migrate @ 9490]
Christian Hammond <chipx86@chipx86.com>
parents:
8721
diff
changeset
|
417 /* Connection Functions */ |
| 8487 | 418 /****************************/ |
| 419 static void rendezvous_callback(gpointer data, gint source, GaimInputCondition condition) | |
| 420 { | |
| 421 GaimConnection *gc = data; | |
| 422 RendezvousData *rd = gc->proto_data; | |
| 423 DNSPacket *dns; | |
| 8806 | 424 GSList *cur; |
| 8487 | 425 |
| 426 gaim_debug_misc("rendezvous", "Received rendezvous datagram\n"); | |
| 427 | |
| 428 dns = mdns_read(rd->fd); | |
| 429 if (dns == NULL) | |
| 430 return; | |
| 431 | |
| 432 /* Handle the DNS packet */ | |
| 8806 | 433 for (cur = dns->answers; cur != NULL; cur = cur->next) |
| 434 rendezvous_handle_rr(gc, cur->data); | |
| 435 for (cur = dns->authority; cur != NULL; cur = cur->next) | |
| 436 rendezvous_handle_rr(gc, cur->data); | |
| 437 for (cur = dns->additional; cur != NULL; cur = cur->next) | |
| 438 rendezvous_handle_rr(gc, cur->data); | |
| 8487 | 439 |
| 440 mdns_free(dns); | |
| 441 } | |
| 442 | |
| 8629 | 443 static void rendezvous_add_to_txt(RendezvousData *rd, const char *name, const char *value) |
| 444 { | |
| 8631 | 445 ResourceRecordRDataTXTNode *node; |
| 446 node = g_malloc(sizeof(ResourceRecordRDataTXTNode)); | |
| 8629 | 447 node->name = g_strdup(name); |
| 448 node->value = value != NULL ? g_strdup(value) : NULL; | |
| 449 rd->mytxtdata = g_slist_append(rd->mytxtdata, node); | |
| 450 } | |
| 451 | |
| 8636 | 452 static void rendezvous_send_icon(GaimConnection *gc) |
| 453 { | |
| 454 RendezvousData *rd = gc->proto_data; | |
| 455 GaimAccount *account = gaim_connection_get_account(gc); | |
| 456 const char *iconfile = gaim_account_get_buddy_icon(account); | |
| 457 struct stat st; | |
| 458 FILE *file; | |
| 459 unsigned char *rdata; | |
| 460 unsigned short rdlength; | |
| 461 gchar *myname; | |
| 462 | |
| 463 if (iconfile == NULL) | |
| 464 return; | |
| 465 | |
| 466 if (stat(iconfile, &st)) | |
| 467 return; | |
| 468 | |
| 469 if (!(file = fopen(iconfile, "rb"))) | |
| 470 return; | |
| 471 | |
| 472 rdlength = st.st_size; | |
| 473 rdata = g_malloc(rdlength); | |
| 474 fread(rdata, 1, rdlength, file); | |
| 475 fclose(file); | |
| 476 | |
| 477 myname = g_strdup_printf("%s._presence._tcp.local", gaim_account_get_username(account)); | |
| 478 mdns_advertise_null(rd->fd, myname, rdata, rdlength); | |
| 479 g_free(myname); | |
| 8695 | 480 |
| 481 g_free(rdata); | |
| 8636 | 482 } |
| 483 | |
| 8629 | 484 static void rendezvous_send_online(GaimConnection *gc) |
| 485 { | |
| 486 RendezvousData *rd = gc->proto_data; | |
| 487 GaimAccount *account = gaim_connection_get_account(gc); | |
| 8636 | 488 const gchar *me; |
| 489 gchar *myname, *mycomp; | |
| 8840 | 490 unsigned char myip[4]; |
| 8629 | 491 |
| 8631 | 492 me = gaim_account_get_username(account); |
| 493 myname = g_strdup_printf("%s._presence._tcp.local", me); | |
| 494 mycomp = g_strdup_printf("%s.local", strchr(me, '@') + 1); | |
| 8840 | 495 /* myip = gaim_network_ip_atoi(gaim_network_get_local_system_ip(-1)); */ |
| 496 myip[0] = 192; | |
| 497 myip[1] = 168; | |
| 498 myip[2] = 1; | |
| 499 myip[3] = 41; | |
| 8631 | 500 |
| 8834 | 501 mdns_advertise_a(rd->fd, mycomp, myip); |
| 8631 | 502 mdns_advertise_ptr(rd->fd, "_presence._tcp.local", myname); |
| 503 mdns_advertise_srv(rd->fd, myname, 5298, mycomp); | |
| 8629 | 504 |
| 505 rendezvous_add_to_txt(rd, "txtvers", "1"); | |
| 506 rendezvous_add_to_txt(rd, "status", "avail"); | |
| 8631 | 507 /* rendezvous_add_to_txt(rd, "vc", "A!"); */ |
| 508 /* rendezvous_add_to_txt(rd, "phsh", "96f15dec163cf4a8cfa0cf08109cc9766f7bd5a0"); */ | |
| 8629 | 509 rendezvous_add_to_txt(rd, "1st", gaim_account_get_string(account, "first", "Gaim")); |
| 8631 | 510 if (gaim_account_get_bool(account, "shareaim", FALSE)) { |
| 511 GList *l; | |
| 512 GaimAccount *cur; | |
| 513 for (l = gaim_accounts_get_all(); l != NULL; l = l->next) { | |
| 514 cur = (GaimAccount *)l->data; | |
| 515 if (!strcmp(gaim_account_get_protocol_id(cur), "prpl-oscar")) { | |
| 8634 | 516 /* XXX - Should the name be normalized? */ |
| 8631 | 517 rendezvous_add_to_txt(rd, "AIM", gaim_account_get_username(cur)); |
| 518 break; | |
| 519 } | |
| 520 } | |
| 521 } | |
| 8629 | 522 rendezvous_add_to_txt(rd, "version", "1"); |
| 8631 | 523 rendezvous_add_to_txt(rd, "msg", "Groovin'"); |
| 8629 | 524 rendezvous_add_to_txt(rd, "port.p2pj", "5298"); |
| 525 rendezvous_add_to_txt(rd, "last", gaim_account_get_string(account, "last", _("User"))); | |
| 8631 | 526 mdns_advertise_txt(rd->fd, myname, rd->mytxtdata); |
| 8629 | 527 |
| 8636 | 528 rendezvous_send_icon(gc); |
| 529 | |
| 8631 | 530 g_free(myname); |
| 531 g_free(mycomp); | |
| 8629 | 532 } |
| 533 | |
| 8487 | 534 static void rendezvous_prpl_login(GaimAccount *account) |
| 535 { | |
| 536 GaimConnection *gc = gaim_account_get_connection(account); | |
| 537 RendezvousData *rd; | |
| 538 | |
| 539 rd = g_new0(RendezvousData, 1); | |
| 540 rd->buddies = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, rendezvous_buddy_free); | |
| 541 gc->proto_data = rd; | |
| 542 | |
| 543 gaim_connection_update_progress(gc, _("Preparing Buddy List"), 0, RENDEZVOUS_CONNECT_STEPS); | |
| 544 rendezvous_removeallfromlocal(gc); | |
| 545 | |
| 546 gaim_connection_update_progress(gc, _("Connecting"), 1, RENDEZVOUS_CONNECT_STEPS); | |
| 8834 | 547 rd->fd = mdns_socket_establish(); |
| 8487 | 548 if (rd->fd == -1) { |
| 549 gaim_connection_error(gc, _("Unable to login to rendezvous")); | |
| 550 return; | |
| 551 } | |
| 552 | |
| 553 gc->inpa = gaim_input_add(rd->fd, GAIM_INPUT_READ, rendezvous_callback, gc); | |
| 554 gaim_connection_set_state(gc, GAIM_CONNECTED); | |
| 555 | |
| 8636 | 556 mdns_query(rd->fd, "_presence._tcp.local", RENDEZVOUS_RRTYPE_ALL); |
| 8629 | 557 rendezvous_send_online(gc); |
| 8487 | 558 } |
| 559 | |
| 560 static void rendezvous_prpl_close(GaimConnection *gc) | |
| 561 { | |
| 562 RendezvousData *rd = (RendezvousData *)gc->proto_data; | |
| 8631 | 563 ResourceRecordRDataTXTNode *node; |
| 8487 | 564 |
| 565 if (gc->inpa) | |
| 566 gaim_input_remove(gc->inpa); | |
| 567 | |
| 568 rendezvous_removeallfromlocal(gc); | |
| 569 | |
| 570 if (!rd) | |
| 571 return; | |
| 572 | |
| 8834 | 573 mdns_socket_close(rd->fd); |
| 8487 | 574 |
| 575 g_hash_table_destroy(rd->buddies); | |
| 576 | |
| 8629 | 577 while (rd->mytxtdata != NULL) { |
| 578 node = rd->mytxtdata->data; | |
| 579 rd->mytxtdata = g_slist_remove(rd->mytxtdata, node); | |
| 580 g_free(node->name); | |
| 581 g_free(node->value); | |
| 582 g_free(node); | |
| 583 } | |
| 584 | |
| 8487 | 585 g_free(rd); |
| 586 } | |
| 587 | |
| 588 static int rendezvous_prpl_send_im(GaimConnection *gc, const char *who, const char *message, GaimConvImFlags flags) | |
| 589 { | |
| 590 gaim_debug_info("rendezvous", "Sending IM\n"); | |
| 591 | |
| 592 return 1; | |
| 593 } | |
| 594 | |
| 8589 | 595 static void rendezvous_prpl_set_away(GaimConnection *gc, const char *state, const char *text) |
| 8487 | 596 { |
| 597 gaim_debug_error("rendezvous", "Set away, state=%s, text=%s\n", state, text); | |
| 598 } | |
| 599 | |
| 600 static GaimPlugin *my_protocol = NULL; | |
| 601 | |
| 8842 | 602 static GaimPluginProtocolInfo prpl_info; |
| 8487 | 603 |
| 604 static GaimPluginInfo info = | |
| 605 { | |
|
8749
d7b8eb1f0a18
[gaim-migrate @ 9504]
Christian Hammond <chipx86@chipx86.com>
parents:
8735
diff
changeset
|
606 GAIM_PLUGIN_API_VERSION, /**< api_version */ |
| 8487 | 607 GAIM_PLUGIN_PROTOCOL, /**< type */ |
| 608 NULL, /**< ui_requirement */ | |
| 609 0, /**< flags */ | |
| 610 NULL, /**< dependencies */ | |
| 611 GAIM_PRIORITY_DEFAULT, /**< priority */ | |
| 612 | |
| 613 "prpl-rendezvous", /**< id */ | |
| 614 "Rendezvous", /**< name */ | |
| 615 VERSION, /**< version */ | |
| 616 /** summary */ | |
| 617 N_("Rendezvous Protocol Plugin"), | |
| 618 /** description */ | |
| 619 N_("Rendezvous Protocol Plugin"), | |
| 620 NULL, /**< author */ | |
| 621 GAIM_WEBSITE, /**< homepage */ | |
| 622 | |
| 623 NULL, /**< load */ | |
| 624 NULL, /**< unload */ | |
| 625 NULL, /**< destroy */ | |
| 626 | |
| 627 NULL, /**< ui_info */ | |
| 8993 | 628 &prpl_info, /**< extra_info */ |
| 629 NULL, | |
| 630 NULL | |
| 8487 | 631 }; |
| 632 | |
| 633 static void init_plugin(GaimPlugin *plugin) | |
| 634 { | |
| 635 GaimAccountUserSplit *split; | |
| 636 GaimAccountOption *option; | |
| 8631 | 637 char hostname[255]; |
| 638 | |
| 8842 | 639 prpl_info.api_version = GAIM_PRPL_API_VERSION; |
| 640 prpl_info.options = OPT_PROTO_NO_PASSWORD | OPT_PROTO_BUDDY_ICON; | |
| 641 prpl_info.list_icon = rendezvous_prpl_list_icon; | |
| 642 prpl_info.list_emblems = rendezvous_prpl_list_emblems; | |
| 643 prpl_info.status_text = rendezvous_prpl_status_text; | |
| 644 prpl_info.tooltip_text = rendezvous_prpl_tooltip_text; | |
| 645 prpl_info.login = rendezvous_prpl_login; | |
| 646 prpl_info.close = rendezvous_prpl_close; | |
| 647 prpl_info.send_im = rendezvous_prpl_send_im; | |
| 648 prpl_info.set_away = rendezvous_prpl_set_away; | |
| 649 | |
| 8631 | 650 if (gethostname(hostname, 255) != 0) { |
| 651 gaim_debug_warning("rendezvous", "Error %d when getting host name. Using \"localhost.\"\n", errno); | |
| 652 strcpy(hostname, "localhost"); | |
| 653 } | |
| 8487 | 654 |
| 655 /* Try to avoid making this configurable... */ | |
| 8842 | 656 split = gaim_account_user_split_new(_("Host name"), hostname, '@'); |
| 8487 | 657 prpl_info.user_splits = g_list_append(prpl_info.user_splits, split); |
| 658 | |
| 8842 | 659 option = gaim_account_option_string_new(_("First name"), "first", "Gaim"); |
| 8487 | 660 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, |
| 661 option); | |
| 662 | |
| 8842 | 663 option = gaim_account_option_string_new(_("Last name"), "last", _("User")); |
| 8487 | 664 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, |
| 665 option); | |
| 666 | |
| 8631 | 667 option = gaim_account_option_bool_new(_("Share AIM screen name"), "shareaim", FALSE); |
| 8487 | 668 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, |
| 669 option); | |
| 670 | |
| 671 my_protocol = plugin; | |
| 672 } | |
| 673 | |
| 674 GAIM_INIT_PLUGIN(rendezvous, init_plugin, info); |
