- Timestamp:
- 2016-09-24T20:14:34Z (8 years ago)
- Children:
- ba52ac5
- Parents:
- 63cad66 (diff), 82cb190 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- protocols
- Files:
-
- 1 added
- 72 edited
Legend:
- Unmodified
- Added
- Removed
-
protocols/account.c
r63cad66 r3fbce97 84 84 strstr(a->user, "@googlemail.com")) { 85 85 strcpy(tag, "gtalk"); 86 } else if (strstr(a->user, "@chat.facebook.com")) {87 strcpy(tag, "fb");88 86 } 89 87 } -
protocols/bee.h
r63cad66 r3fbce97 62 62 BEE_USER_LOCAL = 256, /* Locally-added contacts (not in real contact list) */ 63 63 BEE_USER_SPECIAL = 512, /* Denotes a user as being special */ 64 BEE_USER_NOOTR = 4096, /* Per-user version of OPT_NOOTR */ 64 65 } bee_user_flags_t; 65 66 … … 104 105 gboolean (*user_status)(bee_t *bee, struct bee_user *bu, struct bee_user *old); 105 106 /* On every incoming message. sent_at = 0 means unknown. */ 106 gboolean (*user_msg)(bee_t *bee, bee_user_t *bu, const char *msg, time_t sent_at);107 gboolean (*user_msg)(bee_t *bee, bee_user_t *bu, const char *msg, guint32 flags, time_t sent_at); 107 108 /* Flags currently defined (OPT_TYPING/THINKING) in nogaim.h. */ 108 109 gboolean (*user_typing)(bee_t *bee, bee_user_t *bu, guint32 flags); … … 117 118 /* System messages of any kind. */ 118 119 gboolean (*chat_log)(bee_t *bee, struct groupchat *c, const char *text); 119 gboolean (*chat_msg)(bee_t *bee, struct groupchat *c, bee_user_t *bu, const char *msg, time_t sent_at);120 gboolean (*chat_msg)(bee_t *bee, struct groupchat *c, bee_user_t *bu, const char *msg, guint32 flags, time_t sent_at); 120 121 gboolean (*chat_add_user)(bee_t *bee, struct groupchat *c, bee_user_t *bu); 121 gboolean (*chat_remove_user)(bee_t *bee, struct groupchat *c, bee_user_t *bu );122 gboolean (*chat_remove_user)(bee_t *bee, struct groupchat *c, bee_user_t *bu, const char *reason); 122 123 gboolean (*chat_topic)(bee_t *bee, struct groupchat *c, const char *new_topic, bee_user_t *bu); 123 124 gboolean (*chat_name_hint)(bee_t *bee, struct groupchat *c, const char *name); … … 128 129 void (*ft_close)(struct im_connection *ic, struct file_transfer *ft); 129 130 void (*ft_finished)(struct im_connection *ic, struct file_transfer *ft); 131 132 void (*log)(bee_t *bee, const char *tag, const char *msg); 130 133 } bee_ui_funcs_t; 131 134 -
protocols/bee_chat.c
r63cad66 r3fbce97 95 95 } 96 96 97 void imcb_chat_msg(struct groupchat *c, const char *who, char *msg, uint32_tflags, time_t sent_at)97 void imcb_chat_msg(struct groupchat *c, const char *who, char *msg, guint32 flags, time_t sent_at) 98 98 { 99 99 struct im_connection *ic = c->ic; 100 100 bee_t *bee = ic->bee; 101 101 bee_user_t *bu; 102 gboolean temp ;102 gboolean temp = FALSE; 103 103 char *s; 104 104 105 /* Gaim sends own messages through this too. IRC doesn't want this, so kill them */ 106 if (handle_is_self(ic, who)) { 105 if (handle_is_self(ic, who) && !(flags & OPT_SELFMESSAGE)) { 107 106 return; 108 107 } … … 122 121 123 122 if (bee->ui->chat_msg) { 124 bee->ui->chat_msg(bee, c, bu, msg, sent_at);123 bee->ui->chat_msg(bee, c, bu, msg, flags, sent_at); 125 124 } 126 125 … … 230 229 231 230 if (bee->ui->chat_remove_user && bu) { 232 bee->ui->chat_remove_user(bee, c, bu );231 bee->ui->chat_remove_user(bee, c, bu, reason); 233 232 } 234 233 } -
protocols/bee_user.c
r63cad66 r3fbce97 247 247 } 248 248 249 void imcb_buddy_msg(struct im_connection *ic, const char *handle, const char *msg, uint32_tflags, time_t sent_at)249 void imcb_buddy_msg(struct im_connection *ic, const char *handle, const char *msg, guint32 flags, time_t sent_at) 250 250 { 251 251 bee_t *bee = ic->bee; … … 265 265 266 266 if (bee->ui->user_msg && bu) { 267 bee->ui->user_msg(bee, bu, msg, sent_at);267 bee->ui->user_msg(bee, bu, msg, flags, sent_at); 268 268 } else { 269 269 imcb_log(ic, "Message from unknown handle %s:\n%s", handle, msg); … … 297 297 } 298 298 299 void imcb_buddy_typing(struct im_connection *ic, const char *handle, uint32_tflags)299 void imcb_buddy_typing(struct im_connection *ic, const char *handle, guint32 flags) 300 300 { 301 301 bee_user_t *bu; -
protocols/ft.h
r63cad66 r3fbce97 58 58 * | accept 59 59 * V 60 * /------ /-------------\ /------------------------ \61 * out_of_data | | TRANSFER ING | -----------------> | TRANSFERING | CANCELED |62 * \-----> \-------------/ [canceled,]free \------------------------ /60 * /------ /-------------\ /--------------------------\ 61 * out_of_data | | TRANSFERRING | -----------------> | TRANSFERRING | CANCELED | 62 * \-----> \-------------/ [canceled,]free \--------------------------/ 63 63 * | 64 64 * | finished,free 65 65 * V 66 * /------------------------ \67 * | TRANSFER ING | FINISHED |68 * \------------------------ /66 * /-------------------------\ 67 * | TRANSFERRING | FINISHED | 68 * \-------------------------/ 69 69 */ 70 70 typedef struct file_transfer { … … 115 115 116 116 /* 117 * If set, called after succes ful connection setup.117 * If set, called after successful connection setup. 118 118 */ 119 119 void (*accept)(struct file_transfer *file); -
protocols/jabber/conference.c
r63cad66 r3fbce97 26 26 27 27 static xt_status jabber_chat_join_failed(struct im_connection *ic, struct xt_node *node, struct xt_node *orig); 28 static xt_status jabber_chat_self_message(struct im_connection *ic, struct xt_node *node, struct xt_node *orig); 28 29 29 30 struct groupchat *jabber_chat_join(struct im_connection *ic, const char *room, const char *nick, const char *password) … … 121 122 } 122 123 if (bud) { 123 jabber_chat_free(jabber_chat_by_jid(ic, bud->bare_jid)); 124 struct groupchat *c = jabber_chat_by_jid(ic, bud->bare_jid); 125 if (c) { 126 jabber_chat_free(c); 127 } 124 128 } 125 129 126 130 return XT_HANDLED; 131 } 132 133 static xt_status jabber_chat_self_message(struct im_connection *ic, struct xt_node *node, struct xt_node *orig) 134 { 135 /* This is a self message sent by this bitlbee - just drop it */ 136 return XT_ABORT; 127 137 } 128 138 … … 171 181 node = jabber_make_packet("message", "groupchat", jc->name, node); 172 182 173 if (!jabber_write_packet(ic, node)) { 174 xt_free_node(node); 175 return 0; 176 } 177 xt_free_node(node); 178 179 return 1; 183 jabber_cache_add(ic, node, jabber_chat_self_message); 184 185 return !jabber_write_packet(ic, node); 180 186 } 181 187 … … 299 305 } 300 306 } 301 302 /* Some program-specific restrictions. */303 imcb_clean_handle(ic, bud->ext_jid);304 307 } 305 308 bud->flags |= JBFLAG_IS_ANONYMOUS; … … 331 334 } else if (type) { /* type can only be NULL or "unavailable" in this function */ 332 335 if ((bud->flags & JBFLAG_IS_CHATROOM) && bud->ext_jid) { 336 char *reason = NULL; 337 char *status = NULL; 338 char *status_text = NULL; 339 340 if ((c = xt_find_node_by_attr(node->children, "x", "xmlns", XMLNS_MUC_USER))) { 341 struct xt_node *c2 = c->children; 342 343 while ((c2 = xt_find_node(c2, "status"))) { 344 char *code = xt_find_attr(c2, "code"); 345 if (g_strcmp0(code, "301") == 0) { 346 status = "Banned"; 347 break; 348 } else if (g_strcmp0(code, "303") == 0) { 349 /* This could be handled in a cleverer way, 350 * but let's just show a literal part/join for now */ 351 status = "Changing nicks"; 352 break; 353 } else if (g_strcmp0(code, "307") == 0) { 354 status = "Kicked"; 355 break; 356 } 357 c2 = c2->next; 358 } 359 360 /* Sometimes the status message is in presence/x/item/reason */ 361 if ((c2 = xt_find_path(c, "item/reason")) && c2->text && c2->text_len) { 362 status_text = c2->text; 363 } 364 } 365 366 /* Sometimes the status message is right inside <presence> */ 367 if ((c = xt_find_node(node->children, "status")) && c->text && c->text_len) { 368 status_text = c->text; 369 } 370 371 if (status_text && status) { 372 reason = g_strdup_printf("%s: %s", status, status_text); 373 } else { 374 reason = g_strdup(status_text ? : status); 375 } 376 333 377 s = strchr(bud->ext_jid, '/'); 334 378 if (s) { 335 379 *s = 0; 336 380 } 337 imcb_chat_remove_buddy(chat, bud->ext_jid, NULL);381 imcb_chat_remove_buddy(chat, bud->ext_jid, reason); 338 382 if (bud != jc->me && bud->flags & JBFLAG_IS_ANONYMOUS) { 339 imcb_remove_buddy(ic, bud->ext_jid, NULL);383 imcb_remove_buddy(ic, bud->ext_jid, reason); 340 384 } 341 385 if (s) { 342 386 *s = '/'; 343 387 } 388 389 g_free(reason); 344 390 } 345 391 … … 360 406 char *final_from = NULL; 361 407 char *bare_jid = NULL; 408 guint32 flags = 0; 362 409 363 410 from = (bud) ? bud->full_jid : xt_find_attr(node, "from"); … … 396 443 397 444 if (subject && chat) { 398 char *subject_text = subject->text_len > 0 ? subject->text : NULL;445 char *subject_text = subject->text_len > 0 ? subject->text : ""; 399 446 if (g_strcmp0(chat->topic, subject_text) != 0) { 400 447 bare_jid = (bud) ? jabber_get_bare_jid(bud->ext_jid) : NULL; … … 402 449 jabber_get_timestamp(node)); 403 450 g_free(bare_jid); 451 bare_jid = NULL; 404 452 } 405 453 } … … 422 470 imcb_chat_log(chat, "From conference server: %s", body->text); 423 471 return; 424 } else if (jc && jc->flags & JCFLAG_MESSAGE_SENT && bud == jc->me ) {425 /* exclude self-messages since they would get filtered out426 * but not the ones in the backlog*/472 } else if (jc && jc->flags & JCFLAG_MESSAGE_SENT && bud == jc->me && 473 (jabber_cache_handle_packet(ic, node) == XT_ABORT)) { 474 /* Self message marked by this bitlbee, don't show it */ 427 475 return; 428 476 } 429 477 430 if (bud && jc && bud != jc->me) {478 if (bud) { 431 479 bare_jid = jabber_get_bare_jid(bud->ext_jid ? bud->ext_jid : bud->full_jid); 432 480 final_from = bare_jid; 481 flags = (bud == jc->me) ? OPT_SELFMESSAGE : 0; 433 482 } else { 434 483 final_from = nick; 435 484 } 436 485 437 imcb_chat_msg(chat, final_from, body->text, 0, jabber_get_timestamp(node));486 imcb_chat_msg(chat, final_from, body->text, flags, jabber_get_timestamp(node)); 438 487 439 488 g_free(bare_jid); -
protocols/jabber/hipchat.c
r63cad66 r3fbce97 42 42 *sep = '/'; 43 43 } 44 45 jd->muc_host = g_strdup(xt_find_attr(node, "muc_host")); 44 46 45 47 /* Hipchat's auth doesn't expect a restart here */ … … 92 94 93 95 } 96 97 /* Returns a newly allocated string that tries to match the "slug" part of the JID using an 98 * approximation of the method used by the server. This might fail in some rare conditions 99 * (old JIDs generated a different way, locale settings unicode, etc) */ 100 char *hipchat_make_channel_slug(const char *name) 101 { 102 char *lower; 103 char *new = g_malloc(strlen(name) + 1); 104 int i = 0; 105 106 do { 107 if (*name == ' ') { 108 new[i++] = '_'; 109 } else if (*name && !strchr("\"&'/:<>@", *name)) { 110 new[i++] = *name; 111 } 112 } while (*(name++)); 113 114 new[i] = '\0'; 115 116 lower = g_utf8_strdown(new, -1); 117 g_free(new); 118 119 return lower; 120 } 121 122 char *hipchat_guess_channel_name(struct im_connection *ic, const char *name) 123 { 124 struct jabber_data *jd = ic->proto_data; 125 char *slug, *retval, *underscore; 126 127 if (!(underscore = strchr(jd->username, '_')) || !jd->muc_host) { 128 return NULL; 129 } 130 131 slug = hipchat_make_channel_slug(name); 132 133 /* Get the organization ID from the username, before the underscore */ 134 *underscore = '\0'; 135 136 retval = g_strdup_printf("%s_%s@%s", jd->username, slug, jd->muc_host); 137 138 *underscore = '_'; 139 140 g_free(slug); 141 142 return retval; 143 } -
protocols/jabber/io.c
r63cad66 r3fbce97 147 147 } 148 148 149 static gboolean jabber_read_callback(gpointer data, gint fd, b_input_condition cond) 150 { 151 struct im_connection *ic = data; 152 struct jabber_data *jd = ic->proto_data; 153 char buf[512]; 154 int st; 155 156 if (jd->fd == -1) { 157 return FALSE; 158 } 159 160 if (jd->ssl) { 161 st = ssl_read(jd->ssl, buf, sizeof(buf)); 162 } else { 163 st = read(jd->fd, buf, sizeof(buf)); 164 } 165 166 if (st > 0) { 167 /* Parse. */ 168 if (xt_feed(jd->xt, buf, st) < 0) { 149 static gboolean jabber_feed_input(struct im_connection *ic, char *buf, int size) 150 { 151 struct jabber_data *jd = ic->proto_data; 152 153 /* Allow not passing a size for debugging purposes. 154 * This never happens when reading from the socket */ 155 if (size == -1) { 156 size = strlen(buf); 157 } 158 159 /* Parse. */ 160 if (xt_feed(jd->xt, buf, size) < 0) { 161 imcb_error(ic, "XML stream error"); 162 imc_logout(ic, TRUE); 163 return FALSE; 164 } 165 166 /* Execute all handlers. */ 167 if (!xt_handle(jd->xt, NULL, 1)) { 168 /* Don't do anything, the handlers should have 169 aborted the connection already. */ 170 return FALSE; 171 } 172 173 if (jd->flags & JFLAG_STREAM_RESTART) { 174 jd->flags &= ~JFLAG_STREAM_RESTART; 175 jabber_start_stream(ic); 176 } 177 178 /* Garbage collection. */ 179 xt_cleanup(jd->xt, NULL, 1); 180 181 /* This is a bit hackish, unfortunately. Although xmltree 182 has nifty event handler stuff, it only calls handlers 183 when nodes are complete. Since the server should only 184 send an opening <stream:stream> tag, we have to check 185 this by hand. :-( */ 186 if (!(jd->flags & JFLAG_STREAM_STARTED) && jd->xt && jd->xt->root) { 187 if (g_strcasecmp(jd->xt->root->name, "stream:stream") == 0) { 188 jd->flags |= JFLAG_STREAM_STARTED; 189 190 /* If there's no version attribute, assume 191 this is an old server that can't do SASL 192 authentication. */ 193 if (!set_getbool(&ic->acc->set, "sasl") || !sasl_supported(ic)) { 194 /* If there's no version= tag, we suppose 195 this server does NOT implement: XMPP 1.0, 196 SASL and TLS. */ 197 if (set_getbool(&ic->acc->set, "tls")) { 198 imcb_error(ic, "TLS is turned on for this " 199 "account, but is not supported by this server"); 200 imc_logout(ic, FALSE); 201 return FALSE; 202 } else { 203 if (!jabber_init_iq_auth(ic)) { 204 return FALSE; 205 } 206 } 207 } 208 } else { 169 209 imcb_error(ic, "XML stream error"); 170 210 imc_logout(ic, TRUE); 171 211 return FALSE; 172 212 } 173 174 /* Execute all handlers. */ 175 if (!xt_handle(jd->xt, NULL, 1)) { 176 /* Don't do anything, the handlers should have 177 aborted the connection already. */ 213 } 214 215 return TRUE; 216 } 217 218 219 static gboolean jabber_read_callback(gpointer data, gint fd, b_input_condition cond) 220 { 221 struct im_connection *ic = data; 222 struct jabber_data *jd = ic->proto_data; 223 char buf[512]; 224 int st; 225 226 if (jd->fd == -1) { 227 return FALSE; 228 } 229 230 if (jd->ssl) { 231 st = ssl_read(jd->ssl, buf, sizeof(buf)); 232 } else { 233 st = read(jd->fd, buf, sizeof(buf)); 234 } 235 236 if (st > 0) { 237 if (!jabber_feed_input(ic, buf, st)) { 178 238 return FALSE; 179 }180 181 if (jd->flags & JFLAG_STREAM_RESTART) {182 jd->flags &= ~JFLAG_STREAM_RESTART;183 jabber_start_stream(ic);184 }185 186 /* Garbage collection. */187 xt_cleanup(jd->xt, NULL, 1);188 189 /* This is a bit hackish, unfortunately. Although xmltree190 has nifty event handler stuff, it only calls handlers191 when nodes are complete. Since the server should only192 send an opening <stream:stream> tag, we have to check193 this by hand. :-( */194 if (!(jd->flags & JFLAG_STREAM_STARTED) && jd->xt && jd->xt->root) {195 if (g_strcasecmp(jd->xt->root->name, "stream:stream") == 0) {196 jd->flags |= JFLAG_STREAM_STARTED;197 198 /* If there's no version attribute, assume199 this is an old server that can't do SASL200 authentication. */201 if (!set_getbool(&ic->acc->set, "sasl") || !sasl_supported(ic)) {202 /* If there's no version= tag, we suppose203 this server does NOT implement: XMPP 1.0,204 SASL and TLS. */205 if (set_getbool(&ic->acc->set, "tls")) {206 imcb_error(ic, "TLS is turned on for this "207 "account, but is not supported by this server");208 imc_logout(ic, FALSE);209 return FALSE;210 } else {211 return jabber_init_iq_auth(ic);212 }213 }214 } else {215 imcb_error(ic, "XML stream error");216 imc_logout(ic, TRUE);217 return FALSE;218 }219 239 } 220 240 } else if (st == 0 || (st < 0 && !ssl_sockerr_again(jd->ssl))) { -
protocols/jabber/iq.c
r63cad66 r3fbce97 28 28 static xt_status jabber_iq_display_vcard(struct im_connection *ic, struct xt_node *node, struct xt_node *orig); 29 29 static xt_status jabber_gmail_handle_new(struct im_connection *ic, struct xt_node *node); 30 static xt_status jabber_iq_carbons_response(struct im_connection *ic, struct xt_node *node, struct xt_node *orig); 30 31 31 32 xt_status jabber_pkt_iq(struct xt_node *node, gpointer data) … … 52 53 (c = xt_find_node(node->children, "time"))) || 53 54 !(s = xt_find_attr(c, "xmlns"))) { 54 /* Sigh. Who decided to suddenly invent new elements 55 instead of just sticking with <query/>? */ 56 return XT_HANDLED; 55 56 reply = jabber_make_error_packet(node, "service-unavailable", "cancel", NULL); 57 st = jabber_write_packet(ic, reply); 58 xt_free_node(reply); 59 return st; 57 60 } 58 61 … … 118 121 XMLNS_BYTESTREAMS, 119 122 XMLNS_FILETRANSFER, 123 XMLNS_CARBONS, 120 124 NULL }; 121 125 const char **f; … … 134 138 } else { 135 139 xt_free_node(reply); 136 reply = jabber_make_error_packet(node, " feature-not-implemented", "cancel", NULL);140 reply = jabber_make_error_packet(node, "service-unavailable", "cancel", NULL); 137 141 pack = 0; 138 142 } … … 385 389 struct xt_node *response; 386 390 struct jabber_data *jd = ic->proto_data; 387 388 response = jabber_make_packet("iq", "result", g_strdup_printf("%s@%s", jd->username, jd->server), NULL);391 392 response = jabber_make_packet("iq", "result", jd->me, NULL); 389 393 390 394 jabber_cache_add(ic, response, NULL); … … 1004 1008 { 1005 1009 struct jabber_data *jd = ic->proto_data; 1006 struct xt_node *id; 1007 1008 if ((id = xt_find_path(node, "query/identity"))) { 1010 struct xt_node *query, *id; 1011 1012 if (!(query = xt_find_node(node->children, "query"))) { 1013 return XT_HANDLED; 1014 } 1015 1016 if (xt_find_node_by_attr(query->children, "feature", "var", XMLNS_CARBONS) && 1017 set_getbool(&ic->acc->set, "carbons")) { 1018 1019 struct xt_node *enable, *iq; 1020 1021 enable = xt_new_node("enable", NULL, NULL); 1022 xt_add_attr(enable, "xmlns", XMLNS_CARBONS); 1023 iq = jabber_make_packet("iq", "set", NULL, enable); 1024 1025 jabber_cache_add(ic, iq, jabber_iq_carbons_response); 1026 jabber_write_packet(ic, iq); 1027 } 1028 1029 if ((id = xt_find_node(query->children, "identity"))) { 1009 1030 char *cat, *type, *name; 1010 1031 … … 1023 1044 return XT_HANDLED; 1024 1045 } 1046 1047 static xt_status jabber_iq_carbons_response(struct im_connection *ic, 1048 struct xt_node *node, struct xt_node *orig) 1049 { 1050 struct jabber_error *err; 1051 1052 if ((err = jabber_error_parse(xt_find_node(node->children, "error"), XMLNS_STANZA_ERROR))) { 1053 imcb_error(ic, "Error enabling carbons: %s%s%s", 1054 err->code, err->text ? ": " : "", err->text ? err->text : ""); 1055 jabber_error_free(err); 1056 } else { 1057 imcb_log(ic, "Carbons enabled"); 1058 } 1059 1060 return XT_HANDLED; 1061 } -
protocols/jabber/jabber.c
r63cad66 r3fbce97 114 114 s->flags |= ACC_SET_OFFLINE_ONLY | SET_NULL_OK; 115 115 116 s = set_add(&acc->set, "carbons", "true", set_eval_bool, acc); 117 s->flags |= ACC_SET_OFFLINE_ONLY; 118 116 119 acc->flags |= ACC_FLAG_AWAY_MESSAGE | ACC_FLAG_STATUS_MESSAGE | 117 120 ACC_FLAG_HANDLE_DOMAINS; … … 148 151 } 149 152 153 if (strstr(jd->server, ".facebook.com")) { 154 imcb_error(ic, "Facebook's XMPP service is gone. Try this instead: https://wiki.bitlbee.org/HowtoFacebookMQTT"); 155 imc_logout(ic, FALSE); 156 return; 157 } 158 150 159 if ((s = strchr(jd->server, '/'))) { 151 160 *s = 0; … … 167 176 jd->fd = jd->r_inpa = jd->w_inpa = -1; 168 177 169 if (strstr(jd->server, ".facebook.com")) { 170 jd->oauth2_service = &oauth2_service_facebook; 171 } else { 172 jd->oauth2_service = &oauth2_service_google; 173 } 178 /* There are no other options atm, so assume google for everything 179 Facebook and MSN XMPP used to be here. RIP. */ 180 jd->oauth2_service = &oauth2_service_google; 174 181 175 182 oauth_params_parse(&p_in, ic->acc->pass); … … 197 204 } else { 198 205 jabber_connect(ic); 206 } 207 } 208 209 static void jabber_xmlconsole_enable(struct im_connection *ic) 210 { 211 struct jabber_data *jd = ic->proto_data; 212 const char *handle = JABBER_XMLCONSOLE_HANDLE; 213 bee_user_t *bu; 214 215 jd->flags |= JFLAG_XMLCONSOLE; 216 217 if (!(bu = bee_user_by_handle(ic->bee, ic, handle))) { 218 bu = bee_user_new(ic->bee, ic, handle, 0); 219 bu->flags |= BEE_USER_NOOTR; 199 220 } 200 221 } … … 266 287 267 288 if (set_getbool(&acc->set, "xmlconsole")) { 268 jd->flags |= JFLAG_XMLCONSOLE; 269 /* Shouldn't really do this at this stage already, maybe. But 270 I think this shouldn't break anything. */ 271 imcb_add_buddy(ic, JABBER_XMLCONSOLE_HANDLE, NULL); 289 jabber_xmlconsole_enable(ic); 272 290 } 273 291 … … 334 352 } 335 353 if (jd->fd >= 0) { 336 closesocket(jd->fd);354 proxy_disconnect(jd->fd); 337 355 } 338 356 … … 345 363 } 346 364 347 jabber_buddy_remove_all(ic); 365 if (jd->buddies) { 366 jabber_buddy_remove_all(ic); 367 } 348 368 349 369 xt_free(jd->xt); … … 355 375 g_free(jd->internal_jid); 356 376 g_free(jd->gmail_tid); 377 g_free(jd->muc_host); 357 378 g_free(jd->username); 358 379 g_free(jd->me); … … 413 434 } 414 435 436 /* XEP-0364 suggests we add message processing hints (XEP-0334) to OTR messages, 437 mostly to avoid carbons (XEP-0280) and server-side message archiving. 438 OTR messages are roughly like this: /^\?OTR(.*\?| Error:|:)/ 439 But I'm going to simplify it to messages starting with "?OTR". */ 440 if (g_str_has_prefix(message, "?OTR")) { 441 int i; 442 char *hints[] = { 443 "no-copy", XMLNS_HINTS, 444 "no-permanent-store", XMLNS_HINTS, 445 "private", XMLNS_CARBONS, 446 NULL 447 }; 448 449 for (i = 0; hints[i]; i += 2) { 450 struct xt_node *hint; 451 hint = xt_new_node(hints[i], NULL, NULL); 452 xt_add_attr(hint, "xmlns", hints[i + 1]); 453 xt_add_child(node, hint); 454 } 455 } 456 415 457 st = jabber_write_packet(ic, node); 416 458 xt_free_node(node); … … 472 514 static void jabber_add_buddy(struct im_connection *ic, char *who, char *group) 473 515 { 474 struct jabber_data *jd = ic->proto_data;475 476 516 if (g_strcasecmp(who, JABBER_XMLCONSOLE_HANDLE) == 0) { 477 jd->flags |= JFLAG_XMLCONSOLE; 478 imcb_add_buddy(ic, JABBER_XMLCONSOLE_HANDLE, NULL); 517 jabber_xmlconsole_enable(ic); 479 518 return; 480 519 } … … 520 559 } 521 560 561 if (jd->flags & JFLAG_HIPCHAT && jd->muc_host && !g_str_has_suffix(room, jd->muc_host)) { 562 char *guessed_name = hipchat_guess_channel_name(ic, room); 563 if (guessed_name) { 564 set_setstr(sets, "room", guessed_name); 565 g_free(guessed_name); 566 567 /* call this same function again with the fixed name */ 568 return jabber_chat_join_(ic, set_getstr(sets, "room"), nick, password, sets); 569 } 570 } 571 522 572 if (strchr(room, '@') == NULL) { 523 573 imcb_error(ic, "%s is not a valid Jabber room name. Maybe you mean %s@conference.%s?", … … 526 576 imcb_error(ic, "Already present in chat `%s'", room); 527 577 } else { 578 /* jabber_chat_join without the underscore is the conference.c one */ 528 579 return jabber_chat_join(ic, room, final_nick, set_getstr(sets, "password")); 529 580 } … … 590 641 { 591 642 struct jabber_data *jd = ic->proto_data; 592 struct jabber_buddy *bud ;643 struct jabber_buddy *bud, *bare; 593 644 594 645 /* Enable typing notification related code from now. */ 595 646 jd->flags |= JFLAG_WANT_TYPING; 596 647 597 if ((bud = jabber_buddy_by_jid(ic, who, 0)) == NULL) { 648 if ((bud = jabber_buddy_by_jid(ic, who, 0)) == NULL || 649 (bare = jabber_buddy_by_jid(ic, who, GET_BUDDY_BARE)) == NULL) { 598 650 /* Sending typing notifications to unknown buddies is 599 651 unsupported for now. Shouldn't be a problem, I think. */ … … 601 653 } 602 654 603 if (bud->flags & JBFLAG_DOES_XEP85) { 655 656 if (bud->flags & JBFLAG_DOES_XEP85 || bare->flags & JBFLAG_DOES_XEP85) { 604 657 /* We're only allowed to send this stuff if we know the other 605 side supports it. */ 658 side supports it. If the bare JID has the flag, all other 659 resources get it, too (That is the case in gtalk) */ 606 660 607 661 struct xt_node *node; -
protocols/jabber/jabber.h
r63cad66 r3fbce97 50 50 JFLAG_GTALK = 0x100000, /* Is Google Talk, as confirmed by iq discovery */ 51 51 JFLAG_HIPCHAT = 0x200000, /* Is hipchat, because prpl->name says so */ 52 53 JFLAG_SASL_FB = 0x10000, /* Trying Facebook authentication. */54 52 } jabber_flags_t; 55 53 … … 113 111 GSList *streamhosts; 114 112 int have_streamhosts; 113 114 char *muc_host; 115 115 }; 116 116 … … 228 228 #define XMLNS_XDATA "jabber:x:data" /* XEP-0004 */ 229 229 #define XMLNS_GMAILNOTIFY "google:mail:notify" /* Not a XEP */ 230 #define XMLNS_CARBONS "urn:xmpp:carbons:2" /* XEP-0280 */ 231 #define XMLNS_FORWARDING "urn:xmpp:forward:0" /* XEP-0297 */ 232 #define XMLNS_HINTS "urn:xmpp:hints" /* XEP-0334 */ 230 233 #define XMLNS_CHATSTATES "http://jabber.org/protocol/chatstates" /* XEP-0085 */ 231 234 #define XMLNS_DISCO_INFO "http://jabber.org/protocol/disco#info" /* XEP-0030 */ … … 338 341 339 342 extern const struct oauth2_service oauth2_service_google; 340 extern const struct oauth2_service oauth2_service_facebook;341 343 342 344 /* conference.c */ … … 356 358 xt_status jabber_parse_hipchat_profile(struct im_connection *ic, struct xt_node *node, struct xt_node *orig); 357 359 xt_status hipchat_handle_success(struct im_connection *ic, struct xt_node *node); 360 char *hipchat_make_channel_slug(const char *name); 361 char *hipchat_guess_channel_name(struct im_connection *ic, const char *name); 358 362 359 363 #endif -
protocols/jabber/jabber_util.c
r63cad66 r3fbce97 514 514 } else if (bud->resource && (flags & GET_BUDDY_EXACT)) { 515 515 /* We want an exact match, so in thise case there shouldn't be a /resource. */ 516 return NULL; 516 if (head != bud && head->resource == NULL) { 517 return head; 518 } else { 519 return NULL; 520 } 517 521 } else if (bud->resource == NULL || bud->next == NULL) { 518 522 /* No need for selection if there's only one option. */ -
protocols/jabber/message.c
r63cad66 r3fbce97 24 24 #include "jabber.h" 25 25 26 xt_status jabber_pkt_message(struct xt_node *node, gpointer data)26 static xt_status jabber_pkt_message_normal(struct xt_node *node, gpointer data, gboolean carbons_sent) 27 27 { 28 28 struct im_connection *ic = data; 29 char *from = xt_find_attr(node, "from"); 29 struct jabber_data *jd = ic->proto_data; 30 char *from = xt_find_attr(node, carbons_sent ? "to" : "from"); 30 31 char *type = xt_find_attr(node, "type"); 31 32 char *id = xt_find_attr(node, "id"); … … 37 38 if (!from) { 38 39 return XT_HANDLED; /* Consider this packet corrupted. */ 39 40 } 41 if (request && id) { 40 } 41 42 /* try to detect hipchat's own version of self-messages */ 43 if (jd->flags & JFLAG_HIPCHAT) { 44 struct xt_node *c; 45 46 if ((c = xt_find_node_by_attr(node->children, "delay", "xmlns", XMLNS_DELAY)) && 47 (s = xt_find_attr(c, "from_jid")) && 48 jabber_compare_jid(s, jd->me)) { 49 carbons_sent = TRUE; 50 } 51 } 52 53 if (request && id && g_strcmp0(type, "groupchat") != 0 && !carbons_sent) { 42 54 /* Send a message receipt (XEP-0184), looking like this: 43 * <message 44 * from='kingrichard@royalty.england.lit/throne' 45 * id='bi29sg183b4v' 46 * to='northumberland@shakespeare.lit/westminster'> 55 * <message from='...' id='...' to='...'> 47 56 * <received xmlns='urn:xmpp:receipts' id='richard2-4.1.247'/> 48 * </message> */ 57 * </message> 58 * 59 * MUC messages are excluded, since receipts aren't supposed to be sent over MUCs 60 * (XEP-0184 section 5.3) and replying to those may result in 'forbidden' errors. 61 */ 49 62 struct xt_node *received, *receipt; 50 63 … … 127 140 if (fullmsg->len > 0) { 128 141 imcb_buddy_msg(ic, from, fullmsg->str, 129 0, jabber_get_timestamp(node));142 carbons_sent ? OPT_SELFMESSAGE : 0, jabber_get_timestamp(node)); 130 143 } 131 144 if (room) { … … 136 149 137 150 /* Handling of incoming typing notifications. */ 138 if (bud == NULL) { 139 /* Can't handle these for unknown buddies. */ 151 if (bud == NULL || carbons_sent) { 152 /* Can't handle these for unknown buddies. 153 And ignore them if it's just carbons */ 140 154 } else if (xt_find_node(node->children, "composing")) { 141 155 bud->flags |= JBFLAG_DOES_XEP85; 142 156 imcb_buddy_typing(ic, from, OPT_TYPING); 143 157 } 144 /* No need to send a "stopped typing" signal when there's a message. */ 145 else if (xt_find_node(node->children, "active") && (body == NULL)) { 158 else if (xt_find_node(node->children, "active")) { 146 159 bud->flags |= JBFLAG_DOES_XEP85; 147 imcb_buddy_typing(ic, from, 0); 160 161 /* No need to send a "stopped typing" signal when there's a message. */ 162 if (body == NULL) { 163 imcb_buddy_typing(ic, from, 0); 164 } 148 165 } else if (xt_find_node(node->children, "paused")) { 149 166 bud->flags |= JBFLAG_DOES_XEP85; … … 158 175 return XT_HANDLED; 159 176 } 177 178 static xt_status jabber_carbons_message(struct xt_node *node, gpointer data) 179 { 180 struct im_connection *ic = data; 181 struct xt_node *wrap, *fwd, *msg; 182 gboolean carbons_sent; 183 184 if ((wrap = xt_find_node(node->children, "received"))) { 185 carbons_sent = FALSE; 186 } else if ((wrap = xt_find_node(node->children, "sent"))) { 187 carbons_sent = TRUE; 188 } 189 190 if (wrap == NULL || g_strcmp0(xt_find_attr(wrap, "xmlns"), XMLNS_CARBONS) != 0) { 191 return XT_NEXT; 192 } 193 194 if (!(fwd = xt_find_node(wrap->children, "forwarded")) || 195 (g_strcmp0(xt_find_attr(fwd, "xmlns"), XMLNS_FORWARDING) != 0) || 196 !(msg = xt_find_node(fwd->children, "message"))) { 197 imcb_log(ic, "Error: Invalid carbons message received"); 198 return XT_ABORT; 199 } 200 201 return jabber_pkt_message_normal(msg, data, carbons_sent); 202 } 203 204 xt_status jabber_pkt_message(struct xt_node *node, gpointer data) 205 { 206 struct im_connection *ic = data; 207 struct jabber_data *jd = ic->proto_data; 208 char *from = xt_find_attr(node, "from"); 209 210 if (jabber_compare_jid(jd->me, from)) { /* Probably a Carbons message */ 211 xt_status st = jabber_carbons_message(node, data); 212 if (st == XT_HANDLED || st == XT_ABORT) { 213 return st; 214 } 215 } 216 return jabber_pkt_message_normal(node, data, FALSE); 217 } -
protocols/jabber/presence.c
r63cad66 r3fbce97 186 186 char *prio = set_getstr(&ic->acc->set, "priority"); 187 187 188 if (jd->away_state ->code != NULL) {188 if (jd->away_state && jd->away_state->full_name != NULL) { 189 189 int new_prio = (atoi(prio) - 5); 190 190 if (new_prio < 0) { … … 222 222 cap = xt_new_node("c", NULL, NULL); 223 223 xt_add_attr(cap, "xmlns", XMLNS_CAPS); 224 xt_add_attr(cap, "node", "http://bitlbee.org/xmpp/caps"); 224 225 if (jd->flags & JFLAG_HIPCHAT) { 226 /* hipchat specific node, whitelisted by request to receive self-messages */ 227 xt_add_attr(cap, "node", "http://bitlbee.org/xmpp/caps/hipchat"); 228 } else { 229 xt_add_attr(cap, "node", "http://bitlbee.org/xmpp/caps"); 230 } 225 231 xt_add_attr(cap, "ver", BITLBEE_VERSION); /* The XEP wants this hashed, but nobody's doing that. */ 226 232 xt_add_child(node, cap); -
protocols/jabber/s5bytestream.c
r63cad66 r3fbce97 536 536 * that sends atyp=0 addrlen=0 and only 6 bytes (one less than one would expect). 537 537 * Therefore I removed the wait for more bytes. Since we don't care about what else the proxy 538 * is sending, it should nt matter */538 * is sending, it should not matter */ 539 539 540 540 if (bt->tf->ft->sending) { … … 559 559 * An intelligent sender would probably specify himself as the first streamhost and 560 560 * a proxy as the second (Kopete and PSI are examples here). That way, a (potentially) 561 * slow proxy is only used if nec cessary. This of course also means, that the timeout561 * slow proxy is only used if necessary. This of course also means, that the timeout 562 562 * per streamhost should be kept short. If one or two firewalled adresses are specified, 563 563 * they have to timeout first before a proxy is tried. -
protocols/jabber/sasl.c
r63cad66 r3fbce97 38 38 "6C-Zgf7Tr7gEQTPlBhMUgo7R", 39 39 }; 40 const struct oauth2_service oauth2_service_facebook =41 {42 "https://www.facebook.com/dialog/oauth",43 "https://graph.facebook.com/oauth/access_token",44 "https://www.bitlbee.org/main.php/Facebook/oauth2.html",45 "offline_access,xmpp_login",46 "126828914005625",47 "4b100f0f244d620bf3f15f8b217d4c32",48 };49 40 50 41 xt_status sasl_pkt_mechanisms(struct xt_node *node, gpointer data) … … 54 45 struct xt_node *c, *reply; 55 46 char *s; 56 int sup_plain = 0, sup_digest = 0, sup_gtalk = 0, sup_ fb = 0, sup_anonymous = 0;47 int sup_plain = 0, sup_digest = 0, sup_gtalk = 0, sup_anonymous = 0; 57 48 int want_oauth = FALSE, want_hipchat = FALSE, want_anonymous = FALSE; 58 49 GString *mechs; … … 89 80 } else if (c->text && g_strcasecmp(c->text, "X-OAUTH2") == 0) { 90 81 sup_gtalk = 1; 91 } else if (c->text && g_strcasecmp(c->text, "X-FACEBOOK-PLATFORM") == 0) {92 sup_fb = 1;93 82 } 94 83 … … 101 90 102 91 if (!want_oauth && !sup_plain && !sup_digest) { 103 if (!sup_gtalk && !sup_fb) {92 if (!sup_gtalk) { 104 93 imcb_error(ic, "This server requires OAuth " 105 94 "(supported schemes:%s)", mechs->str); … … 137 126 reply->text_len = strlen(reply->text); 138 127 g_free(s); 139 } else if (sup_fb && want_oauth) {140 xt_add_attr(reply, "mechanism", "X-FACEBOOK-PLATFORM");141 jd->flags |= JFLAG_SASL_FB;142 128 } else if (want_oauth) { 143 129 imcb_error(ic, "OAuth requested, but not supported by server"); … … 154 140 xt_free_node(reply); 155 141 return XT_ABORT; 156 } else if (sup_digest) { 142 } else if (sup_digest && !(jd->ssl && sup_plain)) { 143 /* Only try DIGEST-MD5 if there's no SSL/TLS or if PLAIN isn't supported. 144 * Which in practice means "don't bother with DIGEST-MD5 most of the time". 145 * It's weak, pointless over TLS, and often breaks with some servers (hi openfire) */ 146 157 147 xt_add_attr(reply, "mechanism", "DIGEST-MD5"); 158 148 … … 295 285 dec = frombase64(node->text); 296 286 297 if (jd->flags & JFLAG_SASL_FB) { 298 /* New-style Facebook OAauth2 support. Instead of sending a refresh 299 token, they just send an access token that should never expire. */ 300 GSList *p_in = NULL, *p_out = NULL; 301 char time[33]; 302 303 oauth_params_parse(&p_in, dec); 304 oauth_params_add(&p_out, "nonce", oauth_params_get(&p_in, "nonce")); 305 oauth_params_add(&p_out, "method", oauth_params_get(&p_in, "method")); 306 oauth_params_free(&p_in); 307 308 g_snprintf(time, sizeof(time), "%lld", (long long) (gettime() * 1000)); 309 oauth_params_add(&p_out, "call_id", time); 310 oauth_params_add(&p_out, "api_key", oauth2_service_facebook.consumer_key); 311 oauth_params_add(&p_out, "v", "1.0"); 312 oauth_params_add(&p_out, "format", "XML"); 313 oauth_params_add(&p_out, "access_token", jd->oauth2_access_token); 314 315 reply = oauth_params_string(p_out); 316 oauth_params_free(&p_out); 317 } else if (!(s = sasl_get_part(dec, "rspauth"))) { 287 if (!(s = sasl_get_part(dec, "rspauth"))) { 318 288 /* See RFC 2831 for for information. */ 319 289 md5_state_t A1, A2, H; -
protocols/jabber/si.c
r63cad66 r3fbce97 186 186 jd->filetransfers = g_slist_prepend(jd->filetransfers, tf); 187 187 188 /* query buddy's features and server's streaming proxies if nec cessary */188 /* query buddy's features and server's streaming proxies if necessary */ 189 189 190 190 if (!tf->bud->features) { … … 283 283 284 284 if (requestok) { 285 /* Figure out who the transfer should come from e... */285 /* Figure out who the transfer should come from... */ 286 286 287 287 ext_jid = ini_jid; … … 403 403 * <iq from=... to=... id=...> 404 404 * <si xmlns=si> 405 * [ <file xmlns=ft/> ] <-- not nec cessary405 * [ <file xmlns=ft/> ] <-- not necessary 406 406 * <feature xmlns=feature> 407 407 * <x xmlns=xdata type=submit> -
protocols/msn/gw.c
r63cad66 r3fbce97 22 22 gw->ssl = (GATEWAY_PORT == 443); 23 23 gw->poll_timeout = -1; 24 gw->write_timeout = -1; 24 25 gw->ic = ic; 25 26 gw->md = ic->proto_data; … … 34 35 b_event_remove(gw->poll_timeout); 35 36 } 37 38 if (gw->write_timeout != -1) { 39 b_event_remove(gw->write_timeout); 40 } 41 36 42 g_byte_array_free(gw->in, TRUE); 37 43 g_byte_array_free(gw->out, TRUE); … … 189 195 } 190 196 191 void msn_gw_write(struct msn_gw *gw, char *buf, size_t len) 192 { 193 g_byte_array_append(gw->out, (const guint8 *) buf, len); 197 static gboolean msn_gw_write_cb(gpointer data, gint source, b_input_condition cond) 198 { 199 struct msn_gw *gw; 200 201 if (!(gw = msn_gw_from_ic(data))) { 202 return FALSE; 203 } 204 194 205 if (!gw->open) { 195 206 msn_gw_open(gw); … … 197 208 msn_gw_dorequest(gw, NULL); 198 209 } 199 } 210 211 gw->write_timeout = -1; 212 return FALSE; 213 } 214 215 void msn_gw_write(struct msn_gw *gw, char *buf, size_t len) 216 { 217 g_byte_array_append(gw->out, (const guint8 *) buf, len); 218 219 /* do a bit of buffering here to send several commands with a single request */ 220 if (gw->write_timeout == -1) { 221 gw->write_timeout = b_timeout_add(1, msn_gw_write_cb, gw->ic); 222 } 223 } -
protocols/msn/msn.h
r63cad66 r3fbce97 112 112 113 113 int poll_timeout; 114 int write_timeout; 114 115 115 116 b_event_handler callback; -
protocols/msn/msn_util.c
r63cad66 r3fbce97 41 41 } 42 42 43 return g_markup_printf_escaped("<ml><d n=\"%s\"><c n=\"%s\" l=\"%d\" t=\"1\"/></d></ml>",43 return g_markup_printf_escaped("<ml><d n=\"%s\"><c n=\"%s\" t=\"1\"><s n=\"IM\" l=\"%d\" /></c></d></ml>", 44 44 domain, handle, list); 45 45 } -
protocols/msn/ns.c
r63cad66 r3fbce97 39 39 static void msn_ns_send_adl(struct im_connection *ic); 40 40 static void msn_ns_structured_message(struct msn_data *md, char *msg, int msglen, char **cmd); 41 static void msn_ns_sdg(struct msn_data *md, char *who, char **parts, char *action );41 static void msn_ns_sdg(struct msn_data *md, char *who, char **parts, char *action, gboolean selfmessage); 42 42 static void msn_ns_nfy(struct msn_data *md, char *who, char **parts, char *action, gboolean is_put); 43 43 … … 110 110 struct im_connection *ic = md->ic; 111 111 112 /* this should be taken from XFR, but hardcoding it for now. it also prevents more redirects. */ 113 const char *redir_data = "VmVyc2lvbjogMQ0KWGZyQ291bnQ6IDINCklzR2VvWGZyOiB0cnVlDQo="; 114 112 115 if (source == -1 && !md->is_http) { 113 116 imcb_error(ic, "Could not connect to server"); … … 135 138 } 136 139 137 if (msn_ns_write(ic, source, "VER %d %s CVR0\r\n", ++md->trId, MSNP_VER)) { 140 /* Having to handle potential errors in each write sure makes these ifs awkward...*/ 141 142 if (msn_ns_write(ic, source, "VER %d %s CVR0\r\n", ++md->trId, MSNP_VER) && 143 msn_ns_write(ic, source, "CVR %d 0x0409 mac 10.2.0 ppc macmsgs 3.5.1 macmsgs %s %s\r\n", 144 ++md->trId, ic->acc->user, redir_data) && 145 msn_ns_write(ic, md->fd, "USR %d SSO I %s\r\n", ++md->trId, ic->acc->user)) { 146 138 147 if (!md->is_http) { 139 148 md->inpa = b_input_add(md->fd, B_EV_IO_READ, msn_ns_callback, md); … … 208 217 } 209 218 210 return(msn_ns_write(ic, md->fd, "CVR %d 0x0409 mac 10.2.0 ppc macmsgs 3.5.1 macmsgs %s VmVyc2lvbjogMQ0KWGZyQ291bnQ6IDINClhmclNlbnRVVENUaW1lOiA2MzU2MTQ3OTU5NzgzOTAwMDANCklzR2VvWGZyOiB0cnVlDQo=\r\n",211 ++md->trId, ic->acc->user));212 219 } else if (strcmp(cmd[0], "CVR") == 0) { 213 220 /* We don't give a damn about the information we just received */ 214 return msn_ns_write(ic, md->fd, "USR %d SSO I %s\r\n", ++md->trId, ic->acc->user);215 221 } else if (strcmp(cmd[0], "XFR") == 0) { 216 222 char *server; … … 280 286 md->msglen = atoi(cmd[2]); 281 287 } 288 } else if (strcmp(cmd[0], "RML") == 0) { 289 /* Move along, nothing to see here */ 282 290 } else if (strcmp(cmd[0], "CHL") == 0) { 283 291 char *resp; … … 475 483 } 476 484 485 /* returns newly allocated string */ 486 static char *msn_ns_parse_header_address(struct msn_data *md, char *headers, char *header_name) 487 { 488 char *semicolon = NULL; 489 char *header = NULL; 490 char *address = NULL; 491 492 if (!(header = get_rfc822_header(headers, header_name, 0))) { 493 return NULL; 494 } 495 496 /* either the semicolon or the end of the string */ 497 semicolon = strchr(header, ';') ? : (header + strlen(header)); 498 499 address = g_strndup(header + 2, semicolon - header - 2); 500 501 g_free(header); 502 return address; 503 } 504 477 505 static void msn_ns_structured_message(struct msn_data *md, char *msg, int msglen, char **cmd) 478 506 { 479 507 char **parts = NULL; 480 char *semicolon = NULL;481 508 char *action = NULL; 482 char *from = NULL;483 509 char *who = NULL; 510 gboolean selfmessage = FALSE; 484 511 485 512 parts = g_strsplit(msg, "\r\n\r\n", 4); 486 513 487 if (!( from = get_rfc822_header(parts[0], "From", 0))) {514 if (!(who = msn_ns_parse_header_address(md, parts[0], "From"))) { 488 515 goto cleanup; 489 516 } 490 517 491 /* either the semicolon or the end of the string */ 492 semicolon = strchr(from, ';') ? : (from + strlen(from)); 493 494 who = g_strndup(from + 2, semicolon - from - 2); 518 if (strcmp(who, md->ic->acc->user) == 0) { 519 selfmessage = TRUE; 520 g_free(who); 521 if (!(who = msn_ns_parse_header_address(md, parts[0], "To"))) { 522 goto cleanup; 523 } 524 } 495 525 496 526 if ((strcmp(cmd[0], "SDG") == 0) && (action = get_rfc822_header(parts[2], "Message-Type", 0))) { 497 msn_ns_sdg(md, who, parts, action );527 msn_ns_sdg(md, who, parts, action, selfmessage); 498 528 499 529 } else if ((strcmp(cmd[0], "NFY") == 0) && (action = get_rfc822_header(parts[2], "Uri", 0))) { … … 505 535 g_strfreev(parts); 506 536 g_free(action); 507 g_free(from);508 537 g_free(who); 509 538 } 510 539 511 static void msn_ns_sdg(struct msn_data *md, char *who, char **parts, char *action )540 static void msn_ns_sdg(struct msn_data *md, char *who, char **parts, char *action, gboolean selfmessage) 512 541 { 513 542 struct im_connection *ic = md->ic; 514 543 515 if (strcmp(action, "Control/Typing") == 0 ) {544 if (strcmp(action, "Control/Typing") == 0 && !selfmessage) { 516 545 imcb_buddy_typing(ic, who, OPT_TYPING); 517 546 } else if (strcmp(action, "Text") == 0) { 518 imcb_buddy_msg(ic, who, parts[3], 0, 0);547 imcb_buddy_msg(ic, who, parts[3], selfmessage ? OPT_SELFMESSAGE : 0, 0); 519 548 } 520 549 } … … 595 624 } else { 596 625 imcb_error(ic, "Error during Passport authentication: %s", error); 597 imc_logout(ic, TRUE); 626 627 /* don't reconnect with auth errors */ 628 if (error && g_str_has_prefix(error, "wsse:FailedAuthentication")) { 629 imc_logout(ic, FALSE); 630 } else { 631 imc_logout(ic, TRUE); 632 } 598 633 } 599 634 } -
protocols/msn/soap.c
r63cad66 r3fbce97 270 270 struct im_connection *ic = soap_req->ic; 271 271 struct msn_data *md = ic->proto_data; 272 char pass[MAX_PASSPORT_PWLEN + 1];273 272 274 273 if (sd->redirect) { … … 286 285 } 287 286 288 strncpy(pass, ic->acc->pass, MAX_PASSPORT_PWLEN);289 pass[MAX_PASSPORT_PWLEN] = '\0';290 287 soap_req->payload = g_markup_printf_escaped(SOAP_PASSPORT_SSO_PAYLOAD, 291 ic->acc->user, pass, md->pp_policy);288 ic->acc->user, ic->acc->pass, md->pp_policy); 292 289 293 290 return MSN_SOAP_OK; … … 327 324 struct xt_node *code = xt_find_node(node->children, "faultcode"); 328 325 struct xt_node *string = xt_find_node(node->children, "faultstring"); 326 struct xt_node *reqstatus = xt_find_path(node, "psf:pp/psf:reqstatus"); 329 327 struct xt_node *url; 330 328 … … 335 333 url->text_len > 0) { 336 334 sd->redirect = g_strdup(url->text); 335 } else if (reqstatus && strcmp(reqstatus->text, "0x800488fe") == 0) { 336 char *msg = "Location blocked. Log in to live.com, go to recent activity and click 'this was me'"; 337 sd->error = g_strdup_printf("%s (%s)", code->text, msg); 337 338 } else { 338 339 sd->error = g_strdup_printf("%s (%s)", code->text, string && string->text_len ? … … 346 347 { "wsse:BinarySecurityToken", "wst:RequestedSecurityToken", msn_soap_passport_sso_token }, 347 348 { "S:Fault", "S:Envelope", msn_soap_passport_failure }, 349 { "S:Fault", "wst:RequestSecurityTokenResponse", msn_soap_passport_failure }, 348 350 { NULL, NULL, NULL } 349 351 }; … … 774 776 imcb_log(soap_req->ic, "Warning: %d contacts were in both your " 775 777 "block and your allow list. Assuming they're all " 776 "allowed. Use the official WLM client once to fix " 777 "this.", wtf); 778 "allowed.", wtf); 778 779 } 779 780 -
protocols/msn/soap.h
r63cad66 r3fbce97 61 61 #define SOAP_PASSPORT_SSO_URL "https://login.live.com/RST.srf" 62 62 #define SOAP_PASSPORT_SSO_URL_MSN "https://msnia.login.live.com/pp900/RST.srf" 63 #define MAX_PASSPORT_PWLEN 1664 63 65 64 #define SOAP_PASSPORT_SSO_PAYLOAD \ -
protocols/nogaim.c
r63cad66 r3fbce97 90 90 91 91 GList *protocols = NULL; 92 GList *disabled_protocols = NULL; 92 93 93 94 void register_protocol(struct prpl *p) … … 103 104 104 105 if (refused) { 105 log_message(LOGLVL_WARNING, "Protocol %s disabled\n", p->name);106 disabled_protocols = g_list_append(disabled_protocols, p); 106 107 } else { 107 108 protocols = g_list_append(protocols, p); … … 109 110 } 110 111 112 static int proto_name_cmp(const void *proto_, const void *name) 113 { 114 const struct prpl *proto = proto_; 115 return g_strcasecmp(proto->name, name); 116 } 117 111 118 struct prpl *find_protocol(const char *name) 112 119 { 113 GList *gl; 114 115 for (gl = protocols; gl; gl = gl->next) { 116 struct prpl *proto = gl->data; 117 118 if (g_strcasecmp(proto->name, name) == 0) { 119 return proto; 120 } 121 } 122 123 return NULL; 120 GList *gl = g_list_find_custom(protocols, name, proto_name_cmp); 121 return gl ? gl->data: NULL; 122 } 123 124 gboolean is_protocol_disabled(const char *name) 125 { 126 return g_list_find_custom(disabled_protocols, name, proto_name_cmp) != NULL; 124 127 } 125 128 … … 209 212 account_t *a; 210 213 214 if (!ic->bee->ui->log) { 215 return; 216 } 217 211 218 va_start(params, format); 212 219 text = g_strdup_vprintf(format, params); … … 227 234 /* If we found one, include the screenname in the message. */ 228 235 if (a) { 229 /* FIXME(wilmer): ui_log callback or so */ 230 irc_rootmsg(ic->bee->ui_data, "%s - %s", ic->acc->tag, text); 236 ic->bee->ui->log(ic->bee, ic->acc->tag, text); 231 237 } else { 232 i rc_rootmsg(ic->bee->ui_data, "%s - %s", ic->acc->prpl->name, text);238 ic->bee->ui->log(ic->bee, ic->acc->prpl->name, text); 233 239 } 234 240 … … 662 668 GList *m = ic->acc->prpl->away_states(ic); 663 669 msg = ic->acc->flags & ACC_FLAG_AWAY_MESSAGE ? away : NULL; 664 away = imc_away_state_find(m, away, &msg) ? : m->data; 670 away = imc_away_state_find(m, away, &msg) ? : 671 (imc_away_state_find(m, "away", &msg) ? : m->data); 665 672 } else if (ic->acc->flags & ACC_FLAG_STATUS_MESSAGE) { 666 673 away = NULL; … … 781 788 } 782 789 790 /* Deprecated: using this function resulted in merging several handles accidentally 791 * Also the irc layer handles this decently nowadays */ 783 792 void imcb_clean_handle(struct im_connection *ic, char *handle) 784 793 { 785 /* Accepts a handle and does whatever is necessary to make it 786 BitlBee-friendly. Currently this means removing everything 787 outside 33-127 (ASCII printable excl spaces), @ (only one 788 is allowed) and ! and : */ 789 char out[strlen(handle) + 1]; 790 int s, d; 791 792 s = d = 0; 793 while (handle[s]) { 794 if (handle[s] > ' ' && handle[s] != '!' && handle[s] != ':' && 795 (handle[s] & 0x80) == 0) { 796 if (handle[s] == '@') { 797 /* See if we got an @ already? */ 798 out[d] = 0; 799 if (strchr(out, '@')) { 800 continue; 801 } 802 } 803 804 out[d++] = handle[s]; 805 } 806 s++; 807 } 808 out[d] = handle[s]; 809 810 strcpy(handle, out); 811 } 794 } -
protocols/nogaim.h
r63cad66 r3fbce97 76 76 #define OPT_PONGED 0x00020000 /* Received a keep-alive during last interval */ 77 77 #define OPT_LOCAL_CONTACTS_SENT 0x00040000 /* Protocol already requested local contact list, so don't send it after finishing login. */ 78 #define OPT_SELFMESSAGE 0x00080000 /* A message sent by self from another location */ 78 79 79 80 /* ok. now the fun begins. first we create a connection structure */ … … 280 281 G_MODULE_EXPORT GSList *get_connections(); 281 282 G_MODULE_EXPORT struct prpl *find_protocol(const char *name); 283 G_MODULE_EXPORT gboolean is_protocol_disabled(const char *name); 282 284 /* When registering a new protocol, you should allocate space for a new prpl 283 285 * struct, initialize it (set the function pointers to point to your … … 326 328 G_MODULE_EXPORT void imcb_add_buddy(struct im_connection *ic, const char *handle, const char *group); 327 329 G_MODULE_EXPORT void imcb_remove_buddy(struct im_connection *ic, const char *handle, char *group); 328 G_MODULE_EXPORT struct buddy *imcb_find_buddy(struct im_connection *ic, char *handle);329 330 G_MODULE_EXPORT void imcb_rename_buddy(struct im_connection *ic, const char *handle, const char *realname); 330 331 G_MODULE_EXPORT void imcb_buddy_nick_hint(struct im_connection *ic, const char *handle, const char *nick); … … 332 333 G_MODULE_EXPORT GSList *imcb_get_local_contacts(struct im_connection *ic); 333 334 334 G_MODULE_EXPORT void imcb_buddy_typing(struct im_connection *ic, const char *handle, uint32_tflags);335 G_MODULE_EXPORT void imcb_buddy_typing(struct im_connection *ic, const char *handle, guint32 flags); 335 336 G_MODULE_EXPORT struct bee_user *imcb_buddy_by_handle(struct im_connection *ic, const char *handle); 336 G_MODULE_EXPORT void imcb_clean_handle(struct im_connection *ic, char *handle); 337 338 G_GNUC_DEPRECATED G_MODULE_EXPORT void imcb_clean_handle(struct im_connection *ic, char *handle); 337 339 338 340 /* Actions, or whatever. */ -
protocols/oscar/aim.h
r63cad66 r3fbce97 21 21 22 22 #include "bitlbee.h" 23 24 #ifdef WITH_PURPLE 25 /* For compatibility with builds that include both purple and this oscar module */ 26 #include "aim_prefixes.h" 27 #endif 23 28 24 29 /* XXX adjust these based on autoconf-detected platform */ … … 871 876 * SNAC Family: Internal Messages 872 877 * 873 * This isn't tru ely a SNAC family either, but using878 * This isn't truly a SNAC family either, but using 874 879 * these, we can integrated non-SNAC services into 875 880 * the SNAC-centered libfaim callback structure. -
protocols/oscar/auth.c
r63cad66 r3fbce97 41 41 * meaning you generally never call this. 42 42 * 43 * But there are times when something might want it sep erate. Specifically,43 * But there are times when something might want it separate. Specifically, 44 44 * libfaim sends this internally when doing SNAC login. 45 45 * -
protocols/oscar/conn.c
r63cad66 r3fbce97 15 15 * In OSCAR, every connection has a set of SNAC groups associated 16 16 * with it. These are the groups that you can send over this connection 17 * without being guar enteed a "Not supported" SNAC error.17 * without being guaranteed a "Not supported" SNAC error. 18 18 * 19 19 * The grand theory of things says that these associations transcend … … 36 36 * 37 37 * Here comes the good bit. Without even letting anyone know, particularly 38 * the module that decided to send this SNAC, and definit ly not that twit38 * the module that decided to send this SNAC, and definitely not that twit 39 39 * in Greenland, you send out a service request. In this request, you have 40 40 * marked the need for a connection supporting group 0x000e. A few seconds … … 317 317 318 318 if (deadconn->fd >= 3) { 319 closesocket(deadconn->fd);319 proxy_disconnect(deadconn->fd); 320 320 } 321 321 deadconn->fd = -1; -
protocols/oscar/im.c
r63cad66 r3fbce97 50 50 * encoding for your message. In UNICODE mode, _all_ characters must 51 51 * occupy 16bits, including ones that are not special. (Remember that 52 * the first 128 UNICODE symbols are equiv elent to ASCII7, however they52 * the first 128 UNICODE symbols are equivalent to ASCII7, however they 53 53 * must be prefixed with a zero high order byte.) 54 54 * … … 64 64 * in all of libfaim, it is written with performance in mind. As such, 65 65 * it is not as clear as it could be in respect to how this message is 66 * supposed to be la yed out. Most obviously, tlvlists should be used66 * supposed to be laid out. Most obviously, tlvlists should be used 67 67 * instead of writing out the bytes manually. 68 68 * … … 476 476 * examples of how to do this. 477 477 * 478 * I would definit ly recommend avoiding this feature unless you really478 * I would definitely recommend avoiding this feature unless you really 479 479 * know what you are doing, and/or you have something neat to do with it. 480 480 * … … 638 638 } 639 639 #if 0 640 /* XXX this isn't really neces ary... */640 /* XXX this isn't really necessary... */ 641 641 if (((args.flag1 != 0x0000) && 642 642 (args.flag1 != 0x0002) && … … 1161 1161 * 1162 1162 * Channel 0x0001 is the message channel. There are 1163 * other channels for things called "rende vous"1163 * other channels for things called "rendezvous" 1164 1164 * which represent chat and some of the other new 1165 1165 * features of AIM2/3/3.5. 1166 1166 * 1167 * Channel 0x0002 is the Rende vous channel, which1167 * Channel 0x0002 is the Rendezvous channel, which 1168 1168 * is where Chat Invitiations and various client-client 1169 1169 * connection negotiations come from. … … 1181 1181 * with the TLVs read below, they are two different pieces. The 1182 1182 * userinfo block contains the number of TLVs that contain user 1183 * information, the rest are not even though there is no sep eration.1183 * information, the rest are not even though there is no separation. 1184 1184 * aim_extractuserinfo() returns the number of bytes used by the 1185 1185 * userinfo tlvs, so you can start reading the rest of them right … … 1253 1253 /* 1254 1254 * 1255 * I definit ly recommend sending this. If you don't, you'll be stuck1255 * I definitely recommend sending this. If you don't, you'll be stuck 1256 1256 * with the rather unreasonable defaults. You don't want those. Send this. 1257 1257 * -
protocols/oscar/misc.c
r63cad66 r3fbce97 3 3 * aim_misc.c 4 4 * 5 * TODO: Sep erate a lot of this into an aim_bos.c.5 * TODO: Separate a lot of this into an aim_bos.c. 6 6 * 7 7 * Other things... -
protocols/oscar/msgcookie.c
r63cad66 r3fbce97 142 142 * @cookiep: the address of a pointer to the cookie struct to remove 143 143 * 144 * this function removes the cookie *cookie from t ehlist of cookies144 * this function removes the cookie *cookie from the list of cookies 145 145 * in sess, and then frees all memory associated with it. including 146 146 * its data! if you want to use the private data after calling this, -
protocols/oscar/oscar.c
r63cad66 r3fbce97 1266 1266 } break; 1267 1267 1268 case 2: { /* rende vous */1268 case 2: { /* rendezvous */ 1269 1269 struct aim_incomingim_ch2_args *args; 1270 1270 args = va_arg(ap, struct aim_incomingim_ch2_args *); -
protocols/oscar/rxhandlers.c
r63cad66 r3fbce97 381 381 /* 382 382 * This doesn't have to be called here. It could easily be done 383 * by a sep erate thread or something. It's an administrative operation,383 * by a separate thread or something. It's an administrative operation, 384 384 * and can take a while. Though the less you call it the less memory 385 385 * you'll have :) -
protocols/oscar/rxqueue.c
r63cad66 r3fbce97 361 361 /* 362 362 * Grab a single command sequence off the socket, and enqueue 363 * it in the incoming event queue in a sep erate struct.363 * it in the incoming event queue in a separate struct. 364 364 */ 365 365 int aim_get_command(aim_session_t *sess, aim_conn_t *conn) … … 479 479 480 480 /* 481 * Purge rec ieve queue of all handled commands (->handled==1). Also481 * Purge receive queue of all handled commands (->handled==1). Also 482 482 * allows for selective freeing using ->nofree so that the client can 483 483 * keep the data for various purposes. -
protocols/oscar/service.c
r63cad66 r3fbce97 157 157 158 158 /* 159 * OSCAR defines several 'rate classes'. Each class has sep erate159 * OSCAR defines several 'rate classes'. Each class has separate 160 160 * rate limiting properties (limit level, alert level, disconnect 161 161 * level, etc), and a set of SNAC family/type pairs associated with … … 709 709 * of memory. (I won't put it past them to start requesting data in 710 710 * less static regions -- regions that are initialized at run time, but still 711 * before the client rec ieves this request.)712 * 713 * When the client rec ieves the request, it adds it to the current ds711 * before the client receives this request.) 712 * 713 * When the client receives the request, it adds it to the current ds 714 714 * (0x00400000) and dereferences it, copying the data into a buffer which 715 715 * it then runs directly through the MD5 hasher. The 16 byte output of … … 723 723 * download a FREE, fully featured, and authorized client, here 724 724 * http://www.aol.com/aim/download2.html" 725 * The connection is then closed, rec ieving disconnect code 1, URL725 * The connection is then closed, receiving disconnect code 1, URL 726 726 * http://www.aim.aol.com/errors/USER_LOGGED_OFF_NEW_LOGIN.html. 727 727 * 728 728 * Note, however, that numerous inconsistencies can cause the above error, 729 * not just sending back a bad hash. Do not immediat ly suspect this code729 * not just sending back a bad hash. Do not immediately suspect this code 730 730 * if you get disconnected. AOL and the open/free software community have 731 731 * played this game for a couple years now, generating the above message 732 * on numerous oc assions.732 * on numerous occasions. 733 733 * 734 734 * Anyway, neener. We win again. -
protocols/oscar/tlv.c
r63cad66 r3fbce97 25 25 * bstream references, so that at least the ->value portion of each 26 26 * element doesn't need to be malloc/memcpy'd. This could prove to be 27 * just as eff ecient as the in-place TLV parsing used in a couple places27 * just as efficient as the in-place TLV parsing used in a couple places 28 28 * in libfaim. 29 29 * … … 135 135 /** 136 136 * aim_addtlvtochain_str - Add a string to a TLV chain 137 * @list: Desi nation chain (%NULL pointer if empty)137 * @list: Designation chain (%NULL pointer if empty) 138 138 * @type: TLV type 139 139 * @str: String to add -
protocols/oscar/txqueue.c
r63cad66 r3fbce97 67 67 * The overall purpose here is to enqueue the passed in command struct 68 68 * into the outgoing (tx) queue. Basically... 69 * 1) Make a scope-irrelev ent copy of the struct69 * 1) Make a scope-irrelevant copy of the struct 70 70 * 3) Mark as not-sent-yet 71 71 * 4) Enqueue the struct into the list -
protocols/purple/ft-direct.c
r63cad66 r3fbce97 193 193 PurpleXferUiOps bee_xfer_uiops = 194 194 { 195 prplcb_xfer_new, 196 prplcb_xfer_dbg, 197 prplcb_xfer_dbg, 198 prplcb_xfer_progress, 199 prplcb_xfer_dbg, 200 prplcb_xfer_dbg, 201 prplcb_xfer_write, 202 prplcb_xfer_read, 203 prplcb_xfer_dbg, 195 prplcb_xfer_new, /* new_xfer */ 196 prplcb_xfer_dbg, /* destroy */ 197 prplcb_xfer_dbg, /* add_xfer */ 198 prplcb_xfer_progress, /* update_progress */ 199 prplcb_xfer_dbg, /* cancel_local */ 200 prplcb_xfer_dbg, /* cancel_remote */ 201 prplcb_xfer_write, /* ui_write */ 202 prplcb_xfer_read, /* ui_read */ 203 prplcb_xfer_dbg, /* data_not_sent */ 204 204 }; 205 205 -
protocols/purple/ft.c
r63cad66 r3fbce97 232 232 } 233 233 234 static void prplcb_xfer_dbg(PurpleXfer *xfer)235 {236 fprintf(stderr, "prplcb_xfer_dbg 0x%p\n", xfer);237 }238 239 234 240 235 /* Sending files (UI->IM): */ … … 337 332 PurpleXferUiOps bee_xfer_uiops = 338 333 { 339 prplcb_xfer_new, 340 prplcb_xfer_destroy, 341 NULL, /* prplcb_xfer_add,*/342 prplcb_xfer_progress, 343 prplcb_xfer_dbg,344 prplcb_xfer_cancel_remote, 345 NULL, 346 NULL, 347 prplcb_xfer_dbg,334 prplcb_xfer_new, /* new_xfer */ 335 prplcb_xfer_destroy, /* destroy */ 336 NULL, /* add_xfer */ 337 prplcb_xfer_progress, /* update_progress */ 338 NULL, /* cancel_local */ 339 prplcb_xfer_cancel_remote, /* cancel_remote */ 340 NULL, /* ui_write */ 341 NULL, /* ui_read */ 342 NULL, /* data_not_sent */ 348 343 }; -
protocols/purple/purple.c
r63cad66 r3fbce97 113 113 servers anyway! */ 114 114 if (!dir_fixed) { 115 PurpleCertificatePool *pool; 115 116 irc_t *irc = acc->bee->ui_data; 116 117 char *dir; … … 122 123 purple_blist_load(); 123 124 purple_prefs_load(); 125 126 if (proxytype == PROXY_SOCKS4A) { 127 /* do this here after loading prefs. yes, i know, it sucks */ 128 purple_prefs_set_bool("/purple/proxy/socks4_remotedns", TRUE); 129 } 130 131 /* re-create the certificate cache directory */ 132 pool = purple_certificate_find_pool("x509", "tls_peers"); 133 dir = purple_certificate_pool_mkpath(pool, NULL); 134 purple_build_dir(dir, 0700); 135 g_free(dir); 136 124 137 dir_fixed = TRUE; 125 138 } … … 352 365 if (!pd) { 353 366 return; 367 } 368 369 while (ic->groupchats) { 370 imcb_chat_free(ic->groupchats->data); 354 371 } 355 372 … … 639 656 /* Call the fucker. */ 640 657 callback = (void *) mi->callback; 641 callback(&pb->node, m enu->data);658 callback(&pb->node, mi->data); 642 659 643 660 return NULL; … … 707 724 g_hash_table_replace(chat_hash, "passwd", g_strdup(password)); 708 725 } 709 } 726 727 g_free(pce); 728 } 729 730 g_list_free(info); 710 731 711 732 serv_join_chat(purple_account_get_connection(pd->account), chat_hash); 712 733 713 return NULL; 734 g_hash_table_destroy(chat_hash); 735 736 return imcb_chat_new(ic, room); 714 737 } 715 738 … … 733 756 static PurpleCoreUiOps bee_core_uiops = 734 757 { 735 NULL, 736 NULL, 737 purple_ui_init, 738 NULL, 739 prplcb_ui_info, 758 NULL, /* ui_prefs_init */ 759 NULL, /* debug_ui_init */ 760 purple_ui_init, /* ui_init */ 761 NULL, /* quit */ 762 prplcb_ui_info, /* get_ui_info */ 740 763 }; 741 764 … … 764 787 purple_gg_buddylist_import(gc); 765 788 766 if (gc->flags & PURPLE_CONNECTION_HTML) { 767 ic->flags |= OPT_DOES_HTML; 768 } 789 ic->flags |= OPT_DOES_HTML; 769 790 } 770 791 … … 800 821 static PurpleConnectionUiOps bee_conn_uiops = 801 822 { 802 prplcb_conn_progress, 803 prplcb_conn_connected, 804 prplcb_conn_disconnected, 805 prplcb_conn_notice, 806 NULL, 807 NULL, 808 NULL, 809 prplcb_conn_report_disconnect_reason, 823 prplcb_conn_progress, /* connect_progress */ 824 prplcb_conn_connected, /* connected */ 825 prplcb_conn_disconnected, /* disconnected */ 826 prplcb_conn_notice, /* notice */ 827 NULL, /* report_disconnect */ 828 NULL, /* network_connected */ 829 NULL, /* network_disconnected */ 830 prplcb_conn_report_disconnect_reason, /* report_disconnect_reason */ 810 831 }; 811 832 … … 882 903 static PurpleBlistUiOps bee_blist_uiops = 883 904 { 884 NULL, 885 prplcb_blist_new, 886 NULL, 887 prplcb_blist_update, 888 prplcb_blist_remove, 905 NULL, /* new_list */ 906 prplcb_blist_new, /* new_node */ 907 NULL, /* show */ 908 prplcb_blist_update, /* update */ 909 prplcb_blist_remove, /* remove */ 889 910 }; 890 911 … … 895 916 struct groupchat *gc; 896 917 897 gc = imcb_chat_new(ic, conv->name); 898 if (conv->title != NULL) { 899 imcb_chat_name_hint(gc, conv->title); 918 gc = bee_chat_by_title(ic->bee, ic, conv->name); 919 920 if (!gc) { 921 gc = imcb_chat_new(ic, conv->name); 922 if (conv->title != NULL) { 923 imcb_chat_name_hint(gc, conv->title); 924 } 925 } 926 927 /* don't set the topic if it's just the name */ 928 if (conv->title != NULL && strcmp(conv->name, conv->title) != 0) { 900 929 imcb_chat_topic(gc, NULL, conv->title, 0); 901 930 } … … 940 969 } 941 970 942 void prplcb_conv_chat_msg(PurpleConversation *conv, const char *who, const char *message, PurpleMessageFlags flags, 943 time_t mtime) 944 { 971 /* Generic handler for IM or chat messages, covers write_chat, write_im and write_conv */ 972 static void handle_conv_msg(PurpleConversation *conv, const char *who, const char *message, guint32 bee_flags, time_t mtime) 973 { 974 struct im_connection *ic = purple_ic_by_pa(conv->account); 945 975 struct groupchat *gc = conv->ui_data; 946 976 PurpleBuddy *buddy; 947 948 /* ..._SEND means it's an outgoing message, no need to echo those. */949 if (flags & PURPLE_MESSAGE_SEND) {950 return;951 }952 977 953 978 buddy = purple_find_buddy(conv->account, who); … … 956 981 } 957 982 958 imcb_chat_msg(gc, who, (char *) message, 0, mtime); 959 } 960 961 static void prplcb_conv_im(PurpleConversation *conv, const char *who, const char *message, PurpleMessageFlags flags, 962 time_t mtime) 963 { 964 struct im_connection *ic = purple_ic_by_pa(conv->account); 965 PurpleBuddy *buddy; 966 967 /* ..._SEND means it's an outgoing message, no need to echo those. */ 983 if (conv->type == PURPLE_CONV_TYPE_IM) { 984 imcb_buddy_msg(ic, (char *) who, (char *) message, bee_flags, mtime); 985 } else if (gc) { 986 imcb_chat_msg(gc, who, (char *) message, bee_flags, mtime); 987 } 988 } 989 990 /* Handles write_im and write_chat. Removes echoes of locally sent messages */ 991 static void prplcb_conv_msg(PurpleConversation *conv, const char *who, const char *message, PurpleMessageFlags flags, time_t mtime) 992 { 993 if (!(flags & PURPLE_MESSAGE_SEND)) { 994 handle_conv_msg(conv, who, message, 0, mtime); 995 } 996 } 997 998 /* Handles write_conv. Only passes self messages from other locations through. 999 * That is, only writes of PURPLE_MESSAGE_SEND. 1000 * There are more events which might be handled in the future, but some are tricky. 1001 * (images look like <img id="123">, what do i do with that?) */ 1002 static void prplcb_conv_write(PurpleConversation *conv, const char *who, const char *alias, const char *message, 1003 PurpleMessageFlags flags, time_t mtime) 1004 { 968 1005 if (flags & PURPLE_MESSAGE_SEND) { 969 return; 970 } 971 972 buddy = purple_find_buddy(conv->account, who); 973 if (buddy != NULL) { 974 who = purple_buddy_get_name(buddy); 975 } 976 977 imcb_buddy_msg(ic, (char *) who, (char *) message, 0, mtime); 1006 handle_conv_msg(conv, who, message, OPT_SELFMESSAGE, mtime); 1007 } 978 1008 } 979 1009 … … 1008 1038 prplcb_conv_new, /* create_conversation */ 1009 1039 prplcb_conv_free, /* destroy_conversation */ 1010 prplcb_conv_ chat_msg,/* write_chat */1011 prplcb_conv_ im,/* write_im */1012 NULL,/* write_conv */1040 prplcb_conv_msg, /* write_chat */ 1041 prplcb_conv_msg, /* write_im */ 1042 prplcb_conv_write, /* write_conv */ 1013 1043 prplcb_conv_add_users, /* chat_add_users */ 1014 1044 NULL, /* chat_rename_user */ … … 1175 1205 static PurpleRequestUiOps bee_request_uiops = 1176 1206 { 1177 prplcb_request_input, 1178 NULL, 1179 prplcb_request_action, 1180 NULL, 1181 NULL, 1182 prplcb_close_request, 1183 NULL, 1207 prplcb_request_input, /* request_input */ 1208 NULL, /* request_choice */ 1209 prplcb_request_action, /* request_action */ 1210 NULL, /* request_fields */ 1211 NULL, /* request_file */ 1212 prplcb_close_request, /* close_request */ 1213 NULL, /* request_folder */ 1184 1214 }; 1185 1215 … … 1222 1252 static PurplePrivacyUiOps bee_privacy_uiops = 1223 1253 { 1224 prplcb_privacy_permit_added, 1225 prplcb_privacy_permit_removed, 1226 prplcb_privacy_deny_added, 1227 prplcb_privacy_deny_removed, 1254 prplcb_privacy_permit_added, /* permit_added */ 1255 prplcb_privacy_permit_removed, /* permit_removed */ 1256 prplcb_privacy_deny_added, /* deny_added */ 1257 prplcb_privacy_deny_removed, /* deny_removed */ 1228 1258 }; 1229 1259 … … 1235 1265 static PurpleDebugUiOps bee_debug_uiops = 1236 1266 { 1237 prplcb_debug_print, 1267 prplcb_debug_print, /* print */ 1238 1268 }; 1239 1269 … … 1256 1286 static PurpleEventLoopUiOps glib_eventloops = 1257 1287 { 1258 prplcb_ev_timeout_add, 1259 prplcb_ev_remove, 1260 prplcb_ev_input_add, 1261 prplcb_ev_remove, 1288 prplcb_ev_timeout_add, /* timeout_add */ 1289 prplcb_ev_remove, /* timeout_remove */ 1290 prplcb_ev_input_add, /* input_add */ 1291 prplcb_ev_remove, /* input_remove */ 1262 1292 }; 1293 1294 /* Absolutely no connection context at all. Thanks purple! brb crying */ 1295 static void *prplcb_notify_message(PurpleNotifyMsgType type, const char *title, 1296 const char *primary, const char *secondary) 1297 { 1298 char *text = g_strdup_printf("%s%s - %s%s%s", 1299 (type == PURPLE_NOTIFY_MSG_ERROR) ? "Error: " : "", 1300 title, 1301 primary ?: "", 1302 (primary && secondary) ? " - " : "", 1303 secondary ?: "" 1304 ); 1305 1306 if (local_bee->ui->log) { 1307 local_bee->ui->log(local_bee, "purple", text); 1308 } 1309 1310 g_free(text); 1311 1312 return NULL; 1313 } 1263 1314 1264 1315 static void *prplcb_notify_email(PurpleConnection *gc, const char *subject, const char *from, … … 1322 1373 static PurpleNotifyUiOps bee_notify_uiops = 1323 1374 { 1324 NULL,1325 prplcb_notify_email, 1326 NULL, 1327 NULL, 1328 NULL, 1329 NULL, 1330 prplcb_notify_userinfo, 1375 prplcb_notify_message, /* notify_message */ 1376 prplcb_notify_email, /* notify_email */ 1377 NULL, /* notify_emails */ 1378 NULL, /* notify_formatted */ 1379 NULL, /* notify_searchresults */ 1380 NULL, /* notify_searchresults_new_rows */ 1381 prplcb_notify_userinfo, /* notify_userinfo */ 1331 1382 }; 1332 1383 … … 1355 1406 static PurpleAccountUiOps bee_account_uiops = 1356 1407 { 1357 NULL, 1358 NULL, 1359 NULL, 1360 prplcb_account_request_authorize, 1361 NULL, 1408 NULL, /* notify_added */ 1409 NULL, /* status_changed */ 1410 NULL, /* request_add */ 1411 prplcb_account_request_authorize, /* request_authorize */ 1412 NULL, /* close_account_request */ 1362 1413 }; 1363 1414 … … 1387 1438 char *dir; 1388 1439 1389 if (B_EV_IO_READ != PURPLE_INPUT_READ || 1390 B_EV_IO_WRITE != PURPLE_INPUT_WRITE) { 1391 /* FIXME FIXME FIXME FIXME FIXME :-) */ 1392 exit(1); 1393 } 1440 g_assert((int) B_EV_IO_READ == (int) PURPLE_INPUT_READ); 1441 g_assert((int) B_EV_IO_WRITE == (int) PURPLE_INPUT_WRITE); 1394 1442 1395 1443 dir = g_strdup_printf("%s/purple", global.conf->configdir); … … 1409 1457 PurpleProxyInfo *pi = purple_global_proxy_get_info(); 1410 1458 switch (proxytype) { 1459 case PROXY_SOCKS4A: 1411 1460 case PROXY_SOCKS4: 1412 1461 purple_proxy_info_set_type(pi, PURPLE_PROXY_SOCKS4); -
protocols/skype/README
r63cad66 r3fbce97 203 203 204 204 * `account skype set skypeconsole_receive true` will make the 205 `skypeconsole` account dump all the rec ieved raw traffic for you205 `skypeconsole` account dump all the received raw traffic for you 206 206 207 207 - If you want to automatically join bookmarked groupchats right after -
protocols/skype/skype.c
r63cad66 r3fbce97 21 21 22 22 #define _XOPEN_SOURCE 23 #define _BSD_SOURCE24 23 #include <poll.h> 25 24 #include <stdio.h> … … 188 187 189 188 va_start(args, fmt); 190 vsnprintf(str, IRC_LINE_SIZE, fmt, args);189 g_vsnprintf(str, IRC_LINE_SIZE, fmt, args); 191 190 va_end(args); 192 191 … … 322 321 } 323 322 return NULL; 323 } 324 325 static struct groupchat *skype_chat_get_or_create(struct im_connection *ic, char *id) 326 { 327 struct skype_data *sd = ic->proto_data; 328 struct groupchat *gc = bee_chat_by_title(ic->bee, ic, id); 329 330 if (!gc) { 331 gc = imcb_chat_new(ic, id); 332 imcb_chat_name_hint(gc, id); 333 imcb_chat_add_buddy(gc, sd->username); 334 335 skype_printf(ic, "GET CHAT %s ADDER\n", id); 336 skype_printf(ic, "GET CHAT %s TOPIC\n", id); 337 skype_printf(ic, "GET CHAT %s ACTIVEMEMBERS\n", id); 338 } 339 340 return gc; 324 341 } 325 342 … … 688 705 info += 9; 689 706 if (sd->handle && sd->body && sd->type) { 690 struct groupchat *gc = bee_chat_by_title(ic->bee,ic, info);707 struct groupchat *gc = skype_chat_get_or_create(ic, info); 691 708 int i; 692 709 for (i = 0; i < g_list_length(sd->body); i++) { … … 1026 1043 } 1027 1044 if (!strcmp(info, "STATUS MULTI_SUBSCRIBED")) { 1028 gc = bee_chat_by_title(ic->bee, ic, id); 1029 if (!gc) { 1030 gc = imcb_chat_new(ic, id); 1031 imcb_chat_name_hint(gc, id); 1032 } 1033 skype_printf(ic, "GET CHAT %s ADDER\n", id); 1034 skype_printf(ic, "GET CHAT %s TOPIC\n", id); 1045 skype_chat_get_or_create(ic, id); 1035 1046 } else if (!strcmp(info, "STATUS DIALOG") && sd->groupchat_with) { 1036 gc = imcb_chat_new(ic, id); 1037 imcb_chat_name_hint(gc, id); 1047 gc = skype_chat_get_or_create(ic, id); 1038 1048 /* According to the docs this 1039 1049 * is necessary. However it … … 1046 1056 sd->groupchat_with); 1047 1057 imcb_chat_add_buddy(gc, buf); 1048 imcb_chat_add_buddy(gc, sd->username);1049 1058 g_free(sd->groupchat_with); 1050 1059 sd->groupchat_with = NULL; 1051 skype_printf(ic, "GET CHAT %s ADDER\n", id);1052 skype_printf(ic, "GET CHAT %s TOPIC\n", id);1053 1060 } else if (!strcmp(info, "STATUS UNSUBSCRIBED")) { 1054 1061 gc = bee_chat_by_title(ic->bee, ic, id); … … 1257 1264 } 1258 1265 g_strfreev(lines); 1259 } else if (st == 0 || (st < 0 && !s ockerr_again())) {1266 } else if (st == 0 || (st < 0 && !ssl_sockerr_again(sd->ssl))) { 1260 1267 ssl_disconnect(sd->ssl); 1261 1268 sd->fd = -1; -
protocols/skype/t/add-yes-bitlbee.mock
r63cad66 r3fbce97 1 >> NOTICE AUTH1 >> NOTICE * 2 2 << NICK alice 3 3 << USER alice alice localhost :Alice -
protocols/skype/t/added-no-bitlbee.mock
r63cad66 r3fbce97 1 >> NOTICE AUTH1 >> NOTICE * 2 2 << NICK alice 3 3 << USER alice alice localhost :Alice -
protocols/skype/t/added-yes-bitlbee.mock
r63cad66 r3fbce97 1 >> NOTICE AUTH1 >> NOTICE * 2 2 << NICK alice 3 3 << USER alice alice localhost :Alice -
protocols/skype/t/away-set-bitlbee.mock
r63cad66 r3fbce97 1 >> NOTICE AUTH1 >> NOTICE * 2 2 << NICK alice 3 3 << USER alice alice localhost :Alice -
protocols/skype/t/call-bitlbee.mock
r63cad66 r3fbce97 1 >> NOTICE AUTH1 >> NOTICE * 2 2 << NICK alice 3 3 << USER alice alice localhost :alice -
protocols/skype/t/call-failed-bitlbee.mock
r63cad66 r3fbce97 1 >> NOTICE AUTH1 >> NOTICE * 2 2 << NICK alice 3 3 << USER alice alice localhost :alice -
protocols/skype/t/called-no-bitlbee.mock
r63cad66 r3fbce97 1 >> NOTICE AUTH1 >> NOTICE * 2 2 << NICK alice 3 3 << USER alice alice localhost :Alice -
protocols/skype/t/called-yes-bitlbee.mock
r63cad66 r3fbce97 1 >> NOTICE AUTH1 >> NOTICE * 2 2 << NICK alice 3 3 << USER alice alice localhost :Alice -
protocols/skype/t/ctcp-help-bitlbee.mock
r63cad66 r3fbce97 1 >> NOTICE AUTH1 >> NOTICE * 2 2 << NICK alice 3 3 << USER alice alice localhost :Alice -
protocols/skype/t/filetransfer-bitlbee.mock
r63cad66 r3fbce97 1 >> NOTICE AUTH1 >> NOTICE * 2 2 << NICK alice 3 3 << USER alice alice localhost :Alice -
protocols/skype/t/group-add-bitlbee.mock
r63cad66 r3fbce97 1 >> NOTICE AUTH1 >> NOTICE * 2 2 << NICK alice 3 3 << USER alice alice localhost :Alice -
protocols/skype/t/group-read-bitlbee.mock
r63cad66 r3fbce97 1 >> NOTICE AUTH1 >> NOTICE * 2 2 << NICK alice 3 3 << USER alice alice localhost :Alice -
protocols/skype/t/groupchat-invite-bitlbee.mock
r63cad66 r3fbce97 1 >> NOTICE AUTH1 >> NOTICE * 2 2 << NICK alice 3 3 << USER alice alice localhost :Alice … … 7 7 >> :bob!bob@skype.com JOIN :&bitlbee 8 8 << PRIVMSG &bitlbee :chat with bob 9 >> 353 alice = ##alice/$bob;a7ab206ec78 0 :@alice bob@root10 << INVITE cecil ##alice/$bob;a7ab206ec78 011 >> cecil@skype.com JOIN :##alice/$bob;a7ab206ec78 09 >> 353 alice = ##alice/$bob;a7ab206ec78 :@alice @root 10 << INVITE cecil ##alice/$bob;a7ab206ec78 11 >> cecil@skype.com JOIN :##alice/$bob;a7ab206ec78 -
protocols/skype/t/groupchat-invite-skyped.mock
r63cad66 r3fbce97 26 26 >> GET CHAT #alice/$bob;a7ab206ec78060f1 TOPIC 27 27 << CHAT #alice/$bob;a7ab206ec78060f1 TOPIC 28 >> GET CHAT #alice/$bob;a7ab206ec78060f1 ACTIVEMEMBERS 29 << CHAT #alice/$bob;a7ab206ec78060f1 ACTIVEMEMBERS 28 30 << CHATMESSAGE 206 STATUS SENDING 29 31 << CHAT #alice/$bob;a7ab206ec78060f1 STATUS DIALOG -
protocols/skype/t/groupchat-invited-bitlbee.mock
r63cad66 r3fbce97 1 >> NOTICE AUTH1 >> NOTICE * 2 2 << NICK alice 3 3 << USER alice alice localhost :Alice … … 5 5 << PRIVMSG &bitlbee :account add skype alice foo 6 6 << PRIVMSG &bitlbee :account skype on 7 >> JOIN :##cecil/$bob;4d8cc996579 18 >> 353 alice = ##cecil/$bob;4d8cc996579 1 :@alice bob cecil@root7 >> JOIN :##cecil/$bob;4d8cc996579 8 >> 353 alice = ##cecil/$bob;4d8cc996579 :@alice @root -
protocols/skype/t/groupchat-leave-bitlbee.mock
r63cad66 r3fbce97 1 >> NOTICE AUTH1 >> NOTICE * 2 2 << NICK alice 3 3 << USER alice alice localhost :Alice … … 6 6 << PRIVMSG &bitlbee :account skype set skypeconsole_receive true 7 7 << PRIVMSG &bitlbee :account skype on 8 >> JOIN :##cecil/$bob;4d8cc996579 19 >> 353 alice = ##cecil/$bob;4d8cc996579 1 :@alice bob cecil@root10 << PART ##cecil/$bob;4d8cc996579 18 >> JOIN :##cecil/$bob;4d8cc996579 9 >> 353 alice = ##cecil/$bob;4d8cc996579 :@alice @root 10 << PART ##cecil/$bob;4d8cc996579 11 11 >> PRIVMSG &bitlbee :alice: CHAT #cecil/$bob;4d8cc9965791c6b9 STATUS UNSUBSCRIBED -
protocols/skype/t/groupchat-leave-skyped.mock
r63cad66 r3fbce97 36 36 >> GET CHAT #cecil/$bob;4d8cc9965791c6b9 TOPIC 37 37 << CHAT #cecil/$bob;4d8cc9965791c6b9 TOPIC 38 >> GET CHAT #cecil/$bob;4d8cc9965791c6b9 ADDER 39 << CHAT #cecil/$bob;4d8cc9965791c6b9 ADDER bob 40 >> GET CHAT #cecil/$bob;4d8cc9965791c6b9 TOPIC 41 << CHAT #cecil/$bob;4d8cc9965791c6b9 TOPIC 42 >> GET CHAT #cecil/$bob;4d8cc9965791c6b9 ADDER 43 << CHAT #cecil/$bob;4d8cc9965791c6b9 ADDER bob 44 >> GET CHAT #cecil/$bob;4d8cc9965791c6b9 TOPIC 45 << CHAT #cecil/$bob;4d8cc9965791c6b9 TOPIC 38 >> GET CHAT #cecil/$bob;4d8cc9965791c6b9 ACTIVEMEMBERS 39 << CHAT #cecil/$bob;4d8cc9965791c6b9 ACTIVEMEMBERS 46 40 >> GET CHATMESSAGE 188 FROM_HANDLE 47 41 << CHATMESSAGE 188 FROM_HANDLE bob -
protocols/skype/t/groupchat-msg-bitlbee.mock
r63cad66 r3fbce97 1 >> NOTICE AUTH1 >> NOTICE * 2 2 << NICK alice 3 3 << USER alice alice localhost :Alice … … 6 6 << PRIVMSG &bitlbee :account skype set skypeconsole_receive true 7 7 << PRIVMSG &bitlbee :account skype on 8 >> JOIN :##cecil/$bob;4d8cc996579 19 >> 353 alice = ##cecil/$bob;4d8cc996579 1 :@alice bob cecil@root10 << PRIVMSG ##cecil/$bob;4d8cc996579 1:hello8 >> JOIN :##cecil/$bob;4d8cc996579 9 >> 353 alice = ##cecil/$bob;4d8cc996579 :@alice @root 10 << PRIVMSG ##cecil/$bob;4d8cc996579 :hello 11 11 >> PRIVMSG &bitlbee :alice: CHAT #cecil/$bob;4d8cc9965791c6b9 ACTIVITY_TIMESTAMP -
protocols/skype/t/groupchat-msg-skyped.mock
r63cad66 r3fbce97 36 36 >> GET CHAT #cecil/$bob;4d8cc9965791c6b9 TOPIC 37 37 << CHAT #cecil/$bob;4d8cc9965791c6b9 TOPIC 38 >> GET CHAT #cecil/$bob;4d8cc9965791c6b9 ADDER 39 << CHAT #cecil/$bob;4d8cc9965791c6b9 ADDER bob 40 >> GET CHAT #cecil/$bob;4d8cc9965791c6b9 TOPIC 41 << CHAT #cecil/$bob;4d8cc9965791c6b9 TOPIC 42 >> GET CHAT #cecil/$bob;4d8cc9965791c6b9 ADDER 43 << CHAT #cecil/$bob;4d8cc9965791c6b9 ADDER bob 44 >> GET CHAT #cecil/$bob;4d8cc9965791c6b9 TOPIC 45 << CHAT #cecil/$bob;4d8cc9965791c6b9 TOPIC 38 >> GET CHAT #cecil/$bob;4d8cc9965791c6b9 ACTIVEMEMBERS 39 << CHAT #cecil/$bob;4d8cc9965791c6b9 ACTIVEMEMBERS bob cecil alice 46 40 >> GET CHATMESSAGE 188 FROM_HANDLE 47 41 << CHATMESSAGE 188 FROM_HANDLE bob -
protocols/skype/t/groupchat-topic-bitlbee.mock
r63cad66 r3fbce97 1 >> NOTICE AUTH1 >> NOTICE * 2 2 << NICK alice 3 3 << USER alice alice localhost :Alice … … 5 5 << PRIVMSG &bitlbee :account add skype alice foo 6 6 << PRIVMSG &bitlbee :account skype on 7 >> JOIN :##cecil/$bob;4d8cc996579 18 >> 353 alice = ##cecil/$bob;4d8cc996579 1 :@alice bob cecil@root9 << TOPIC ##cecil/$bob;4d8cc996579 1:topic10 >> TOPIC ##cecil/$bob;4d8cc996579 1:topic7 >> JOIN :##cecil/$bob;4d8cc996579 8 >> 353 alice = ##cecil/$bob;4d8cc996579 :@alice @root 9 << TOPIC ##cecil/$bob;4d8cc996579 :topic 10 >> TOPIC ##cecil/$bob;4d8cc996579 :topic -
protocols/skype/t/info-bitlbee.mock
r63cad66 r3fbce97 1 >> NOTICE AUTH1 >> NOTICE * 2 2 << NICK alice 3 3 << USER alice alice localhost :Alice -
protocols/skype/t/login-bitlbee.mock
r63cad66 r3fbce97 1 >> NOTICE AUTH1 >> NOTICE * 2 2 << NICK alice 3 3 << USER alice alice localhost :Alice -
protocols/skype/t/msg-bitlbee.mock
r63cad66 r3fbce97 1 >> NOTICE AUTH1 >> NOTICE * 2 2 << NICK alice 3 3 << USER alice alice localhost :Alice -
protocols/skype/t/set-mood-text-bitlbee.mock
r63cad66 r3fbce97 1 >> NOTICE AUTH1 >> NOTICE * 2 2 << NICK alice 3 3 << USER alice alice localhost :Alice -
protocols/twitter/twitter.c
r63cad66 r3fbce97 678 678 ic->flags &= ~OPT_LOGGED_IN; 679 679 680 // Remove the main_loop function from the function queue.681 b_event_remove(td->main_loop_id);682 683 if (td->timeline_gc) {684 imcb_chat_free(td->timeline_gc);685 }686 687 680 if (td) { 681 // Remove the main_loop function from the function queue. 682 b_event_remove(td->main_loop_id); 683 684 if (td->timeline_gc) { 685 imcb_chat_free(td->timeline_gc); 686 } 687 688 688 if (td->filter_update_id > 0) { 689 689 b_event_remove(td->filter_update_id); -
protocols/twitter/twitter_http.c
r63cad66 r3fbce97 24 24 /***************************************************************************\ 25 25 * * 26 * Some fun tions within this file have been copied from other files within *26 * Some functions within this file have been copied from other files within * 27 27 * BitlBee. * 28 28 * * … … 53 53 char *tmp; 54 54 GString *request = g_string_new(""); 55 void *ret ;55 void *ret = NULL; 56 56 char *url_arguments; 57 57 url_t *base_url = NULL; … … 72 72 base_url = g_new0(url_t, 1); 73 73 if (!url_set(base_url, url_string)) { 74 g_free(base_url); 75 return NULL; 74 goto error; 76 75 } 77 76 } … … 132 131 } 133 132 133 error: 134 134 g_free(url_arguments); 135 135 g_string_free(request, TRUE); -
protocols/twitter/twitter_lib.c
r63cad66 r3fbce97 314 314 td = ic->proto_data; 315 315 316 // Parse the data. 317 if (!(parsed = twitter_parse_response(ic, req))) { 318 return; 319 } 320 316 321 txl = g_new0(struct twitter_xml_list, 1); 317 322 txl->list = td->follow_ids; 318 319 // Parse the data.320 if (!(parsed = twitter_parse_response(ic, req))) {321 return;322 }323 323 324 324 twitter_xt_get_friends_id_list(parsed, txl); … … 390 390 } 391 391 392 // Get the user list from the parsed xml feed. 393 if (!(parsed = twitter_parse_response(ic, req))) { 394 return; 395 } 396 392 397 txl = g_new0(struct twitter_xml_list, 1); 393 398 txl->list = NULL; 394 399 395 // Get the user list from the parsed xml feed.396 if (!(parsed = twitter_parse_response(ic, req))) {397 return;398 }399 400 twitter_xt_get_users(parsed, txl); 400 401 json_value_free(parsed); … … 1389 1390 td = ic->proto_data; 1390 1391 1391 txl = g_new0(struct twitter_xml_list, 1);1392 txl->list = NULL;1393 1394 1392 // The root <statuses> node should hold the list of statuses <status> 1395 1393 if (!(parsed = twitter_parse_response(ic, req))) { 1396 1394 goto end; 1397 1395 } 1396 1397 txl = g_new0(struct twitter_xml_list, 1); 1398 txl->list = NULL; 1399 1398 1400 twitter_xt_get_status_list(ic, parsed, txl); 1399 1401 json_value_free(parsed); … … 1428 1430 td = ic->proto_data; 1429 1431 1430 txl = g_new0(struct twitter_xml_list, 1);1431 txl->list = NULL;1432 1433 1432 // The root <statuses> node should hold the list of statuses <status> 1434 1433 if (!(parsed = twitter_parse_response(ic, req))) { 1435 1434 goto end; 1436 1435 } 1436 1437 txl = g_new0(struct twitter_xml_list, 1); 1438 txl->list = NULL; 1439 1437 1440 twitter_xt_get_status_list(ic, parsed, txl); 1438 1441 json_value_free(parsed); -
protocols/yahoo/libyahoo2.c
r63cad66 r3fbce97 12 12 * GNU GPL. 13 13 * 14 * This code is deriv itive of Gaim <http://gaim.sourceforge.net>14 * This code is derivative of Gaim <http://gaim.sourceforge.net> 15 15 * copyright (C) 1998-1999, Mark Spencer <markster@marko.net> 16 16 * 1998-1999, Adam Fritzler <afritz@marko.net> … … 1402 1402 1403 1403 /* 1404 * Status updates may be spread ac cross multiple packets and not1404 * Status updates may be spread across multiple packets and not 1405 1405 * even on buddy boundaries, so keeping some state is important. 1406 1406 * So, continue where we left off, and only add a user entry to -
protocols/yahoo/yahoo.c
r63cad66 r3fbce97 440 440 { 441 441 struct byahoo_connect_callback_data *d = data; 442 443 if (!byahoo_get_ic_by_id(d->id)) { 442 struct im_connection *ic; 443 444 if (!(ic = byahoo_get_ic_by_id(d->id))) { 445 g_free(d); 446 return; 447 } 448 449 if (source == -1) { 450 d->callback(NULL, 0, d->data); 451 imcb_error(ic, "Could not connect to server"); 452 imc_logout(ic, TRUE); 444 453 g_free(d); 445 454 return; -
protocols/yahoo/yahoo2_callbacks.h
r63cad66 r3fbce97 685 685 * Name: ext_yahoo_connect_async 686 686 * Connect to a host:port asynchronously. This function should return 687 * immediately retur ing a tag used to identify the connection handler,687 * immediately returning a tag used to identify the connection handler, 688 688 * or a pre-connect error (eg: host name lookup failure). 689 689 * Once the connect completes (successfully or unsuccessfully), callback
Note: See TracChangeset
for help on using the changeset viewer.