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