Mercurial > pidgin
annotate src/protocols/rendezvous/rendezvous.c @ 8804:ef1e60f82be0
[gaim-migrate @ 9566]
nosnilmot GOT HIS FREAK ON and made smileys show up as smileys
in the create away message dialog (instead of the envelope thing).
"Someone should make URLs clickable in editable imhtmls"
committer: Tailor Script <tailor@pidgin.im>
| author | Mark Doliner <mark@kingant.net> |
|---|---|
| date | Sat, 24 Apr 2004 20:44:41 +0000 |
| parents | d7b8eb1f0a18 |
| children | 8212661dc3cc |
| 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 { | |
|
8749
d7b8eb1f0a18
[gaim-migrate @ 9504]
Christian Hammond <chipx86@chipx86.com>
parents:
8735
diff
changeset
|
569 GAIM_PRPL_API_VERSION, |
| 8636 | 570 OPT_PROTO_NO_PASSWORD | OPT_PROTO_BUDDY_ICON, |
| 8487 | 571 NULL, |
| 572 NULL, | |
| 573 rendezvous_prpl_list_icon, | |
| 574 rendezvous_prpl_list_emblems, | |
| 575 rendezvous_prpl_status_text, | |
| 576 rendezvous_prpl_tooltip_text, | |
| 577 NULL, | |
| 578 NULL, | |
| 579 NULL, | |
| 580 NULL, | |
| 581 rendezvous_prpl_login, | |
| 582 rendezvous_prpl_close, | |
| 583 rendezvous_prpl_send_im, | |
| 584 NULL, | |
| 585 NULL, | |
| 586 NULL, | |
| 8589 | 587 rendezvous_prpl_set_away, |
| 8487 | 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, | |
| 617 NULL, | |
| 8586 | 618 NULL, |
| 8589 | 619 NULL |
| 8487 | 620 }; |
| 621 | |
| 622 static GaimPluginInfo info = | |
| 623 { | |
|
8749
d7b8eb1f0a18
[gaim-migrate @ 9504]
Christian Hammond <chipx86@chipx86.com>
parents:
8735
diff
changeset
|
624 GAIM_PLUGIN_API_VERSION, /**< api_version */ |
| 8487 | 625 GAIM_PLUGIN_PROTOCOL, /**< type */ |
| 626 NULL, /**< ui_requirement */ | |
| 627 0, /**< flags */ | |
| 628 NULL, /**< dependencies */ | |
| 629 GAIM_PRIORITY_DEFAULT, /**< priority */ | |
| 630 | |
| 631 "prpl-rendezvous", /**< id */ | |
| 632 "Rendezvous", /**< name */ | |
| 633 VERSION, /**< version */ | |
| 634 /** summary */ | |
| 635 N_("Rendezvous Protocol Plugin"), | |
| 636 /** description */ | |
| 637 N_("Rendezvous Protocol Plugin"), | |
| 638 NULL, /**< author */ | |
| 639 GAIM_WEBSITE, /**< homepage */ | |
| 640 | |
| 641 NULL, /**< load */ | |
| 642 NULL, /**< unload */ | |
| 643 NULL, /**< destroy */ | |
| 644 | |
| 645 NULL, /**< ui_info */ | |
| 646 &prpl_info /**< extra_info */ | |
| 647 }; | |
| 648 | |
| 649 static void init_plugin(GaimPlugin *plugin) | |
| 650 { | |
| 651 GaimAccountUserSplit *split; | |
| 652 GaimAccountOption *option; | |
| 8631 | 653 char hostname[255]; |
| 654 | |
| 655 if (gethostname(hostname, 255) != 0) { | |
| 656 gaim_debug_warning("rendezvous", "Error %d when getting host name. Using \"localhost.\"\n", errno); | |
| 657 strcpy(hostname, "localhost"); | |
| 658 } | |
| 8487 | 659 |
| 660 /* Try to avoid making this configurable... */ | |
| 8631 | 661 split = gaim_account_user_split_new(_("Host Name"), hostname, '@'); |
| 8487 | 662 prpl_info.user_splits = g_list_append(prpl_info.user_splits, split); |
| 663 | |
| 664 option = gaim_account_option_string_new(_("First Name"), "first", "Gaim"); | |
| 665 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, | |
| 666 option); | |
| 667 | |
| 668 option = gaim_account_option_string_new(_("Last Name"), "last", _("User")); | |
| 669 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, | |
| 670 option); | |
| 671 | |
| 8631 | 672 option = gaim_account_option_bool_new(_("Share AIM screen name"), "shareaim", FALSE); |
| 8487 | 673 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, |
| 674 option); | |
| 675 | |
| 676 my_protocol = plugin; | |
| 677 } | |
| 678 | |
| 679 GAIM_INIT_PLUGIN(rendezvous, init_plugin, info); |
