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