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