gboolean gaim_privacy_check(GaimAccount *account, const char *who) { GSList *list; switch (account->perm_deny) { case GAIM_PRIVACY_ALLOW_ALL: return TRUE; case GAIM_PRIVACY_DENY_ALL: return FALSE; case GAIM_PRIVACY_ALLOW_USERS: who = gaim_normalize(account, who); for (list=account->permit; list!=NULL; list=list->next) { if (!gaim_utf8_strcasecmp(who, (char *)list->data)) return TRUE; } return FALSE; case GAIM_PRIVACY_DENY_USERS: who = gaim_normalize(account, who); for (list=account->deny; list!=NULL; list=list->next) { if (!gaim_utf8_strcasecmp(who, (char *)list->data )) return FALSE; } return TRUE; case GAIM_PRIVACY_ALLOW_BUDDYLIST: return (gaim_find_buddy(account, who) != NULL); default: g_return_val_if_reached(TRUE); } }
void msn_user_set_state(MsnUser *user, const char *state) { GaimConnection *gc; int status = 0; int idle = 0; GaimBuddy *b; gc = user->userlist->session->account->gc; if ((b = gaim_find_buddy(gc->account, user->passport)) != NULL) status |= ((((b->uc) >> 1) & 0xF0) << 1); if (!g_ascii_strcasecmp(state, "BSY")) status |= UC_UNAVAILABLE | (MSN_BUSY << 1); else if (!g_ascii_strcasecmp(state, "IDL")) { status |= UC_UNAVAILABLE | (MSN_IDLE << 1); idle = -1; } else if (!g_ascii_strcasecmp(state, "BRB")) status |= UC_UNAVAILABLE | (MSN_BRB << 1); else if (!g_ascii_strcasecmp(state, "AWY")) status |= UC_UNAVAILABLE | (MSN_AWAY << 1); else if (!g_ascii_strcasecmp(state, "PHN")) status |= UC_UNAVAILABLE | (MSN_PHONE << 1); else if (!g_ascii_strcasecmp(state, "LUN")) status |= UC_UNAVAILABLE | (MSN_LUNCH << 1); user->status = status; user->idle = idle; }
static void file_recv_request_cb(GaimXfer *xfer, gpointer handle) { GaimAccount *account; GaimBlistNode *node; const char *pref; char *filename; char *dirname; account = xfer->account; node = (GaimBlistNode *)gaim_find_buddy(account, xfer->who); if (!node) { if (gaim_prefs_get_bool(PREF_STRANGER)) xfer->status = GAIM_XFER_STATUS_CANCEL_LOCAL; return; } node = node->parent; g_return_if_fail(GAIM_BLIST_NODE_IS_CONTACT(node)); pref = gaim_prefs_get_string(PREF_PATH); switch (gaim_blist_node_get_int(node, "autoaccept")) { case FT_ASK: break; case FT_ACCEPT: if (ensure_path_exists(pref)) { dirname = g_build_filename(pref, xfer->who, NULL); if (!ensure_path_exists(dirname)) { g_free(dirname); break; } filename = g_build_filename(dirname, xfer->filename, NULL); gaim_xfer_request_accepted(xfer, filename); g_free(dirname); g_free(filename); } gaim_signal_connect(gaim_xfers_get_handle(), "file-recv-complete", handle, GAIM_CALLBACK(auto_accept_complete_cb), xfer); break; case FT_REJECT: xfer->status = GAIM_XFER_STATUS_CANCEL_LOCAL; break; } }
/*TODO: maybe this should be qq_update_buddy_status() ?*/ void qq_update_buddy_contact(GaimConnection *gc, qq_buddy *q_bud) { gchar *name; GaimBuddy *bud; gchar *status_id; g_return_if_fail(q_bud != NULL); name = uid_to_gaim_name(q_bud->uid); bud = gaim_find_buddy(gc->account, name); g_return_if_fail(bud != NULL); if (bud != NULL) { gaim_blist_server_alias_buddy(bud, q_bud->nickname); /* server */ q_bud->last_refresh = time(NULL); /* gaim supports signon and idle time * but it is not much use for QQ, I do not use them */ /* serv_got_update(gc, name, online, 0, q_bud->signon, q_bud->idle, bud->uc); */ status_id = "available"; switch(q_bud->status) { case QQ_BUDDY_OFFLINE: status_id = "offline"; break; case QQ_BUDDY_ONLINE_NORMAL: status_id = "available"; break; case QQ_BUDDY_ONLINE_OFFLINE: status_id = "offline"; break; case QQ_BUDDY_ONLINE_AWAY: status_id = "away"; break; case QQ_BUDDY_ONLINE_INVISIBLE: status_id = "invisible"; break; default: status_id = "invisible"; gaim_debug(GAIM_DEBUG_ERROR, "QQ", "unknown status: %x\n", q_bud->status); break; } gaim_debug(GAIM_DEBUG_INFO, "QQ", "set buddy %d to %s\n", q_bud->uid, status_id); gaim_prpl_got_user_status(gc->account, name, status_id, NULL); } else { gaim_debug(GAIM_DEBUG_ERROR, "QQ", "unknown buddy: %d\n", q_bud->uid); } gaim_debug(GAIM_DEBUG_INFO, "QQ", "qq_update_buddy_contact, client=%04x\n", q_bud->client_version); g_free(name); }
static void buddy_typing_cb(GaimConversation *conv, void *data) { GaimAccount *account = gaim_conversation_get_account(conv); const char *name = gaim_conversation_get_name(conv); if (gaim_find_buddy(account, name) != NULL) { GaimPounceEvent event; event = (gaim_conv_im_get_typing_state(GAIM_CONV_IM(conv)) == GAIM_TYPING ? GAIM_POUNCE_TYPING : GAIM_POUNCE_TYPING_STOPPED); gaim_pounce_execute(account, name, event); } }
/* Remove the buddy referenced by the MsnAddRemData before the serverside list is changed. * If the buddy will be added, he'll be added back; if he will be removed, he won't be. */ static void msn_complete_sync_issue(MsnAddRemData *data) { GaimBuddy *buddy; GaimGroup *group = NULL; if (data->group != NULL) group = gaim_find_group(data->group); if (group != NULL) buddy = gaim_find_buddy_in_group(gaim_connection_get_account(data->gc), data->who, group); else buddy = gaim_find_buddy(gaim_connection_get_account(data->gc), data->who); if (buddy != NULL) gaim_blist_remove_buddy(buddy); }
void jabber_si_xfer_send(GaimConnection *gc, const char *who, const char *file) { JabberStream *js; GaimXfer *xfer; js = gc->proto_data; if(!gaim_find_buddy(gc->account, who) || !jabber_buddy_find(js, who, FALSE)) return; xfer = jabber_si_new_xfer(gc, who); if (file) gaim_xfer_request_accepted(xfer, file); else gaim_xfer_request(xfer); }
gboolean gaim_privacy_permit_remove(GaimAccount *account, const char *who, gboolean local_only) { GSList *l; const char *name; GaimBuddy *buddy; char *del; g_return_val_if_fail(account != NULL, FALSE); g_return_val_if_fail(who != NULL, FALSE); name = gaim_normalize(account, who); for (l = account->permit; l != NULL; l = l->next) { if (!gaim_utf8_strcasecmp(name, (char *)l->data)) break; } if (l == NULL) return FALSE; /* We should not free l->data just yet. There can be occasions where * l->data == who. In such cases, freeing l->data here can cause crashes * later when who is used. */ del = l->data; account->permit = g_slist_delete_link(account->permit, l); if (!local_only && gaim_account_is_connected(account)) serv_rem_permit(gaim_account_get_connection(account), who); if (privacy_ops != NULL && privacy_ops->permit_removed != NULL) privacy_ops->permit_removed(account, who); gaim_blist_schedule_save(); buddy = gaim_find_buddy(account, name); if (buddy != NULL) { gaim_signal_emit(gaim_blist_get_handle(), "buddy-privacy-changed", buddy); } g_free(del); return TRUE; }
gboolean gaim_privacy_deny_remove(GaimAccount *account, const char *who, gboolean local_only) { GSList *l; const char *normalized; char *name; GaimBuddy *buddy; g_return_val_if_fail(account != NULL, FALSE); g_return_val_if_fail(who != NULL, FALSE); normalized = gaim_normalize(account, who); for (l = account->deny; l != NULL; l = l->next) { if (!gaim_utf8_strcasecmp(normalized, (char *)l->data)) break; } buddy = gaim_find_buddy(account, normalized); if (l == NULL) return FALSE; name = l->data; account->deny = g_slist_delete_link(account->deny, l); if (!local_only && gaim_account_is_connected(account)) serv_rem_deny(gaim_account_get_connection(account), name); if (privacy_ops != NULL && privacy_ops->deny_removed != NULL) privacy_ops->deny_removed(account, who); if (buddy != NULL) { gaim_signal_emit(gaim_blist_get_handle(), "buddy-privacy-changed", buddy); } g_free(name); gaim_blist_schedule_save(); return TRUE; }
/* This makes sure that only all the buddies are in the permit list. */ static void add_buddies_in_permit(GaimAccount *account, gboolean local) { GSList *list, *iter; /* Remove anyone in the permit list who is not in the buddylist */ for (list = account->permit; list != NULL; ) { char *person = list->data; list = list->next; if (!gaim_find_buddy(account, person)) gaim_privacy_permit_remove(account, person, local); } /* Now make sure everyone in the buddylist is in the permit list */ for (iter = list = gaim_find_buddies(account, NULL); iter; iter = iter->next) { GaimBuddy *buddy = iter->data; if (!g_slist_find_custom(account->permit, buddy->name, (GCompareFunc)g_utf8_collate)) gaim_privacy_permit_add(account, buddy->name, local); } g_slist_free(list); }
gboolean gaim_privacy_permit_add(GaimAccount *account, const char *who, gboolean local_only) { GSList *l; char *name; GaimBuddy *buddy; g_return_val_if_fail(account != NULL, FALSE); g_return_val_if_fail(who != NULL, FALSE); name = g_strdup(gaim_normalize(account, who)); for (l = account->permit; l != NULL; l = l->next) { if (!gaim_utf8_strcasecmp(name, (char *)l->data)) break; } if (l != NULL) { g_free(name); return FALSE; } account->permit = g_slist_append(account->permit, name); if (!local_only && gaim_account_is_connected(account)) serv_add_permit(gaim_account_get_connection(account), who); if (privacy_ops != NULL && privacy_ops->permit_added != NULL) privacy_ops->permit_added(account, who); gaim_blist_schedule_save(); /* This lets the UI know a buddy has had its privacy setting changed */ buddy = gaim_find_buddy(account, name); if (buddy != NULL) { gaim_signal_emit(gaim_blist_get_handle(), "buddy-privacy-changed", buddy); } return TRUE; }
void gaim_privacy_deny(GaimAccount *account, const char *who, gboolean local, gboolean restore) { GSList *list; switch (account->perm_deny) { case GAIM_PRIVACY_ALLOW_ALL: if (!restore) { /* Empty the deny-list. */ for (list = account->deny; list != NULL; ) { char *person = list->data; list = list->next; gaim_privacy_deny_remove(account, person, local); } } gaim_privacy_deny_add(account, who, local); account->perm_deny = GAIM_PRIVACY_DENY_USERS; break; case GAIM_PRIVACY_ALLOW_USERS: gaim_privacy_permit_remove(account, who, local); break; case GAIM_PRIVACY_DENY_USERS: gaim_privacy_deny_add(account, who, local); break; case GAIM_PRIVACY_DENY_ALL: break; case GAIM_PRIVACY_ALLOW_BUDDYLIST: if (gaim_find_buddy(account, who)) { add_buddies_in_permit(account, local); gaim_privacy_permit_remove(account, who, local); account->perm_deny = GAIM_PRIVACY_ALLOW_USERS; } break; default: g_return_if_reached(); } }
void jabber_presence_fake_to_self(JabberStream *js, const char *away_state, const char *msg) { char *my_base_jid; if(!js->user) return; my_base_jid = g_strdup_printf("%s@%s", js->user->node, js->user->domain); if(gaim_find_buddy(js->gc->account, my_base_jid)) { JabberBuddy *jb; JabberBuddyResource *jbr; if((jb = jabber_buddy_find(js, my_base_jid, TRUE))) { int state = 0; if(away_state) { if(!strcmp(away_state, _("Away")) || (msg && *msg && !strcmp(away_state, GAIM_AWAY_CUSTOM))) state = JABBER_STATE_AWAY; else if(!strcmp(away_state, _("Chatty"))) state = JABBER_STATE_CHAT; else if(!strcmp(away_state, _("Extended Away"))) state = JABBER_STATE_XA; else if(!strcmp(away_state, _("Do Not Disturb"))) state = JABBER_STATE_DND; } if (away_state && !strcmp(away_state, "unavailable")) { jabber_buddy_remove_resource(jb, js->user->resource); } else { jabber_buddy_track_resource(jb, js->user->resource, 0, state, (msg && *msg) ? msg : NULL); } if((jbr = jabber_buddy_find_resource(jb, NULL))) serv_got_update(js->gc, my_base_jid, TRUE, 0, 0, 0, jbr->state); else serv_got_update(js->gc, my_base_jid, FALSE, 0, 0, 0, 0); } } g_free(my_base_jid); }
static void nudge_msg(MsnCmdProc *cmdproc, MsnMessage *msg) { MsnSwitchBoard *swboard; char *username, *str; GaimAccount *account; GaimBuddy *buddy; const char *user; swboard = cmdproc->data; account = cmdproc->session->account; user = msg->remote_user; if ((buddy = gaim_find_buddy(account, user)) != NULL) username = g_markup_escape_text(gaim_buddy_get_alias(buddy), -1); else username = g_markup_escape_text(user, -1); str = g_strdup_printf(_("%s just sent you a Nudge!"), username); g_free(username); msn_switchboard_report_user(swboard, GAIM_MESSAGE_SYSTEM, str); g_free(str); }
static void authorize_add_cb(struct _jabber_add_permit *jap) { if(g_list_find(gaim_connections_get_all(), jap->gc)) { GaimBuddy *buddy = NULL; jabber_presence_subscription_set(jap->gc->proto_data, jap->who, "subscribed"); buddy = gaim_find_buddy(jap->gc->account, jap->who); if (buddy) { JabberBuddy *jb = NULL; jb = jabber_buddy_find(jap->js, jap->who, TRUE); if ((jb->subscription & JABBER_SUB_TO) == 0) { char *buffer = NULL; struct _jabber_add_permit *jap2 = g_new0(struct _jabber_add_permit, 1); jap2->gc = jap->gc; jap2->who = g_strdup(jap->who); /* XXX: Tidy this up when not in string freeze */ buffer = g_strdup_printf(_("%s%s%s%s has made %s his or her buddy%s%s%s"), jap->who, "", "", "", (gaim_connection_get_display_name(jap->gc) != NULL ? gaim_connection_get_display_name(jap->gc) : gaim_account_get_username(jap->gc->account)), ".", "", _("\n\nDo you wish to add him or her to your buddy list?")); gaim_request_action(NULL, NULL, _("Add buddy to your list?"), buffer, GAIM_DEFAULT_ACTION_NONE, jap2, 2, _("Add"), G_CALLBACK(add_user_cb), _("Cancel"), G_CALLBACK(free_jabber_add_permit)); g_free(buffer); } else
/* process the reply packet for get_buddies_online packet */ void qq_process_get_buddies_online_reply(guint8 *buf, gint buf_len, GaimConnection *gc) { qq_data *qd; gint len, bytes; guint8 *data, *cursor, position; GaimBuddy *b; qq_buddy *q_bud; qq_friends_online_entry *fe; g_return_if_fail(buf != NULL && buf_len != 0); qd = (qq_data *) gc->proto_data; len = buf_len; data = g_newa(guint8, len); cursor = data; gaim_debug(GAIM_DEBUG_INFO, "QQ", "processing get_buddies_online_reply\n"); if (qq_crypt(DECRYPT, buf, buf_len, qd->session_key, data, &len)) { _qq_show_packet("Get buddies online reply packet", data, len); read_packet_b(data, &cursor, len, &position); fe = g_newa(qq_friends_online_entry, 1); fe->s = g_newa(qq_buddy_status, 1); while (cursor < (data + len)) { /* based on one online buddy entry */ bytes = 0; /* 000-030 qq_buddy_status */ bytes += qq_buddy_status_read(data, &cursor, len, fe->s); /* 031-032: unknown4 */ bytes += read_packet_w(data, &cursor, len, &fe->unknown1); /* 033-033: flag1 */ bytes += read_packet_b(data, &cursor, len, &fe->flag1); /* 034-034: comm_flag */ bytes += read_packet_b(data, &cursor, len, &fe->comm_flag); /* 035-036: */ bytes += read_packet_w(data, &cursor, len, &fe->unknown2); /* 037-037: */ bytes += read_packet_b(data, &cursor, len, &fe->ending); /* 0x00 */ if (fe->s->uid == 0 || bytes != QQ_ONLINE_BUDDY_ENTRY_LEN) { gaim_debug(GAIM_DEBUG_ERROR, "QQ", "uid=0 or entry complete len(%d) != %d", bytes, QQ_ONLINE_BUDDY_ENTRY_LEN); g_free(fe->s->ip); g_free(fe->s->unknown_key); continue; } /* check if it is a valid entry */ if (QQ_DEBUG) _qq_buddies_online_reply_dump_unclear(fe); /* update buddy information */ b = gaim_find_buddy(gaim_connection_get_account(gc), uid_to_gaim_name(fe->s->uid)); q_bud = (b == NULL) ? NULL : (qq_buddy *) b->proto_data; if (q_bud != NULL) { /* we find one and update qq_buddy */ if(0 != fe->s->client_version) q_bud->client_version = fe->s->client_version; g_memmove(q_bud->ip, fe->s->ip, 4); q_bud->port = fe->s->port; q_bud->status = fe->s->status; q_bud->flag1 = fe->flag1; q_bud->comm_flag = fe->comm_flag; qq_update_buddy_contact(gc, q_bud); } else { gaim_debug(GAIM_DEBUG_ERROR, "QQ", "Got an online buddy %d, but not in my buddy list\n", fe->s->uid); } g_free(fe->s->ip); g_free(fe->s->unknown_key); } if(cursor > (data + len)) { gaim_debug(GAIM_DEBUG_ERROR, "QQ", "qq_process_get_buddies_online_reply: Dangerous error! maybe protocol changed, notify developers!\n"); } if (position != QQ_FRIENDS_ONLINE_POSITION_END) { gaim_debug(GAIM_DEBUG_INFO, "QQ", "Has more online buddies, position from %d\n", position); qq_send_packet_get_buddies_online(gc, position); } else { qq_send_packet_get_buddies_levels(gc); qq_refresh_all_buddy_status(gc); } } else { gaim_debug(GAIM_DEBUG_ERROR, "QQ", "Error decrypt buddies online"); } }
/** * This is our callback for the receiving-im-msg signal. * * We return TRUE to block the IM, FALSE to accept the IM */ static gboolean receiving_im_msg_cb(GaimAccount * account, char **sender, char **buffer, int *flags, void *data) { gboolean retval = FALSE; /* assume the sender is allowed */ gboolean found = FALSE; gint pos = -1; char *botmsg = NULL; PendingMessage *pending = NULL; GSList *slist = NULL; GSList *search = NULL; GaimConnection *connection = NULL; /* expire any old entries in pending */ expire_pending_list(); connection = gaim_account_get_connection(account); /* not good, but don't do anything */ if (!connection || !sender) { return retval; } /* if there is already an open conversation, allowed it */ if (gaim_find_conversation_with_account(*sender, account)) { return retval; } /* don't make buddies use the challenge/response system */ if (gaim_find_buddy(account, *sender)) { return retval; } /* don't make permit list members use the challenge/response system */ for (slist = account->permit; slist != NULL; slist = slist->next) { if (!gaim_utf8_strcasecmp (*sender, gaim_normalize(account, (char *) slist->data))) { return retval; } } /* if there is no question or no answer, allow the sender */ const char *question = gaim_prefs_get_string("/plugins/core/bot/challenger/question"); const char *answer = gaim_prefs_get_string("/plugins/core/bot/challenger/answer"); if (!question || !answer) { return retval; } /* blank / null message ... can this even happen? */ if (!*buffer) { return retval; } /* search if this sender is already in pending */ for (search = pending_list; search; search = search->next) { pending = search->data; pos = g_slist_position(pending_list, search); if (protocmp(account, pending) && usercmp(account, pending) && sendercmp(*sender, pending)) { found = TRUE; break; } } if (!found) { /** * its the first time through, save the nick/msg to the * queue and ask the question */ GTimeVal *now = NULL; now = g_new0(GTimeVal, 1); g_get_current_time(now); PendingMessage *newpend = NULL; newpend = g_new0(PendingMessage, 1); newpend->tv_sec = now->tv_sec; newpend->protocol = g_strdup(account->protocol_id); newpend->username = g_strdup(account->username); newpend->sender = g_strdup(*sender); newpend->message = g_strdup(*buffer); pending_list = g_slist_append(pending_list, newpend); botmsg = g_strdup_printf(_ ("Bot Challenger engaged: you are now being ignored! Your message will be delivered if you can correctly answer the following question within %i minutes: %s"), BOT_MAX_MINUTES, question); send_auto_reply(account, *sender, botmsg); g_free(now); g_free(botmsg); retval = TRUE; } else { if (gaim_utf8_strcasecmp(*buffer, answer)) { /** * Sorry, thanks for playing, please try again */ retval = TRUE; } else { botmsg = _ ("Bot Challenger accepted your answer and delivered your original message. You may now speak freely."); send_auto_reply(account, *sender, botmsg); if (gaim_prefs_get_bool ("/plugins/core/bot/challenger/auto_add_permit")) { if (!gaim_privacy_permit_add(account, *sender, FALSE)) { gaim_debug_info("bot-challenger", "Unable to add %s/%s/%s to permit list\n", *sender, pending->username, pending->protocol); } } /** * Free what is currently in the buffer (the correct answer) * and replace it with the user's first message that was * queued, pending the correct answer. I think some other * process is supposed to free the buffer after its sent. */ g_free(*buffer); *buffer = pending->message; /* Clean up everything else except pending->message */ free_pending(search, FALSE); retval = FALSE; /* Don't block this message */ } } debug_pending_list(); return retval; /* returning TRUE will block the IM */ }
static void add_error(MsnCmdProc *cmdproc, MsnTransaction *trans, int error) { MsnSession *session; GaimAccount *account; GaimConnection *gc; const char *list, *passport; char *reason = NULL; char *msg = NULL; char **params; session = cmdproc->session; account = session->account; gc = gaim_account_get_connection(account); params = g_strsplit(trans->params, " ", 0); list = params[0]; passport = params[1]; if (!strcmp(list, "FL")) msg = g_strdup_printf(_("Unable to add user on %s (%s)"), gaim_account_get_username(account), gaim_account_get_protocol_name(account)); else if (!strcmp(list, "BL")) msg = g_strdup_printf(_("Unable to block user on %s (%s)"), gaim_account_get_username(account), gaim_account_get_protocol_name(account)); else if (!strcmp(list, "AL")) msg = g_strdup_printf(_("Unable to permit user on %s (%s)"), gaim_account_get_username(account), gaim_account_get_protocol_name(account)); if (!strcmp(list, "FL")) { if (error == 210) { reason = g_strdup_printf(_("%s could not be added because " "your buddy list is full."), passport); } } if (reason == NULL) { if (error == 208) { reason = g_strdup_printf(_("%s is not a valid passport account."), passport); } else if (error == 500) { reason = g_strdup(_("Service Temporarily Unavailable.")); } else { reason = g_strdup(_("Unknown error.")); } } if (msg != NULL) { gaim_notify_error(gc, NULL, msg, reason); g_free(msg); } if (!strcmp(list, "FL")) { GaimBuddy *buddy; buddy = gaim_find_buddy(account, passport); if (buddy != NULL) gaim_blist_remove_buddy(buddy); } g_free(reason); g_strfreev(params); }
static gboolean _parse_data(TrepiaSession *session, char *buf) { GHashTable *info; GaimAccount *account; TrepiaMessageType type = 0; TrepiaProfile *profile = NULL; int ret; char *buffer; GaimBuddy *b; int id = 0; const char *value; char *username; int *int_p; GMainContext *ctx; account = gaim_connection_get_account(session->gc); ret = __parse_message(buf, &type, &info); if (ret == 1) return TRUE; if (info != NULL) { switch (type) { case TREPIA_USER_LIST: gaim_connection_update_progress(session->gc, _("Retrieving buddy list"), 2, TREPIA_CONNECT_STEPS); gaim_connection_set_state(session->gc, GAIM_CONNECTED); serv_finish_login(session->gc); break; case TREPIA_MSG_INCOMING: /* Incoming Message */ id = atoi(g_hash_table_lookup(info, "a")); profile = g_hash_table_lookup(session->user_profiles, &id); serv_got_im(session->gc, trepia_profile_get_login(profile), (char *)g_hash_table_lookup(info, "b"), 0, time(NULL)); break; case TREPIA_MEMBER_UPDATE: profile = trepia_profile_new(); if ((value = g_hash_table_lookup(info, "a")) != NULL) { id = atoi(value); trepia_profile_set_id(profile, id); } if ((value = g_hash_table_lookup(info, "b")) != NULL) trepia_profile_set_login_time(profile, atoi(value)); if ((value = g_hash_table_lookup(info, "c")) != NULL) trepia_profile_set_type(profile, atoi(value)); else trepia_profile_set_type(profile, 2); session->pending_users = g_list_append(session->pending_users, profile); #if 0 if (trepia_profile_get_type(profile) == 1) { buffer = g_strdup_printf( "<D>" "<a>%d</a>" "<b>1</b>" "</D>", id); } else { #endif buffer = g_strdup_printf( "<D>" "<a>%d</a>" "<b>1</b>" "</D>" "<D>" "<a>%d</a>" "<b>2</b>" "</D>", id, id); #if 0 } #endif if (trepia_write(session->fd, buffer, strlen(buffer)) < 0) { gaim_connection_error(session->gc, _("Write error")); g_free(buffer); return 1; } g_free(buffer); break; case TREPIA_MEMBER_PROFILE: if ((value = g_hash_table_lookup(info, "a")) != NULL) { GList *l; id = atoi(value); for (l = session->pending_users; l != NULL; l = l->next) { profile = l->data; if (trepia_profile_get_id(profile) == id) break; profile = NULL; } } else break; if (profile == NULL) { profile = g_hash_table_lookup(session->user_profiles, &id); if (profile == NULL) break; } /* Age */ if ((value = g_hash_table_lookup(info, "m")) != NULL) trepia_profile_set_age(profile, atoi(value)); /* ICQ */ if ((value = g_hash_table_lookup(info, "i")) != NULL) trepia_profile_set_icq(profile, atoi(value)); /* Sex */ if ((value = g_hash_table_lookup(info, "n")) != NULL) trepia_profile_set_sex(profile, *value); /* Location */ if ((value = g_hash_table_lookup(info, "p")) != NULL) trepia_profile_set_location(profile, value); /* First Name */ if ((value = g_hash_table_lookup(info, "g")) != NULL) trepia_profile_set_first_name(profile, value); /* Last Name */ if ((value = g_hash_table_lookup(info, "h")) != NULL) trepia_profile_set_last_name(profile, value); /* Profile */ if ((value = g_hash_table_lookup(info, "o")) != NULL) trepia_profile_set_profile(profile, value); /* E-mail */ if ((value = g_hash_table_lookup(info, "e")) != NULL) trepia_profile_set_email(profile, value); /* AIM */ if ((value = g_hash_table_lookup(info, "j")) != NULL) trepia_profile_set_aim(profile, value); /* MSN */ if ((value = g_hash_table_lookup(info, "k")) != NULL) trepia_profile_set_msn(profile, value); /* Yahoo */ if ((value = g_hash_table_lookup(info, "l")) != NULL) trepia_profile_set_yahoo(profile, value); /* Homepage */ if ((value = g_hash_table_lookup(info, "f")) != NULL) trepia_profile_set_homepage(profile, value); /* Country */ if ((value = g_hash_table_lookup(info, "r")) != NULL) trepia_profile_set_country(profile, value); /* State */ if ((value = g_hash_table_lookup(info, "s")) != NULL) trepia_profile_set_state(profile, value); /* City */ if ((value = g_hash_table_lookup(info, "t")) != NULL) trepia_profile_set_city(profile, value); /* Languages */ if ((value = g_hash_table_lookup(info, "u")) != NULL) trepia_profile_set_languages(profile, value); /* School */ if ((value = g_hash_table_lookup(info, "v")) != NULL) trepia_profile_set_school(profile, value); /* Company */ if ((value = g_hash_table_lookup(info, "w")) != NULL) trepia_profile_set_company(profile, value); /* Login Name */ if ((value = g_hash_table_lookup(info, "d")) != NULL) { trepia_profile_set_login(profile, value); username = g_strdup(value); } else if ((value = trepia_profile_get_login(profile)) != NULL) { username = g_strdup(value); } else { username = g_strdup_printf("%d", id); trepia_profile_set_login(profile, username); } b = gaim_find_buddy(account, username); if (b == NULL) { GaimGroup *g; g = gaim_find_group(_("Local Users")); if (g == NULL) { g = gaim_group_new(_("Local Users")); gaim_blist_add_group(g, NULL); } b = gaim_buddy_new(account, username, NULL); gaim_blist_add_buddy(b, NULL, g, NULL); } profile->buddy = b; b->proto_data = profile; session->pending_users = g_list_remove(session->pending_users, profile); int_p = g_new0(int, 1); *int_p = id; g_hash_table_insert(session->user_profiles, int_p, profile); serv_got_update(session->gc, username, TRUE, 0, trepia_profile_get_login_time(profile), 0, 0); /* Buddy Icon */ if ((value = g_hash_table_lookup(info, "q")) != NULL) { char *icon; int icon_len; gaim_base64_decode(value, &icon, &icon_len); gaim_buddy_icons_set_for_user(session->gc->account, username, icon, icon_len); g_free(icon); serv_got_update(session->gc, username, TRUE, 0, 0, 0, 0); } /* * XXX * This does nothing when using a non-gtk event loop. * What is it supposed to accomplish anyway? */ ctx = g_main_context_default(); while (g_main_context_pending(ctx)) g_main_context_iteration(ctx, FALSE); g_free(username); break; case TREPIA_MEMBER_OFFLINE: if ((value = g_hash_table_lookup(info, "a")) != NULL) id = atoi(value); else break; profile = g_hash_table_lookup(session->user_profiles, &id); if (profile == NULL) break; g_hash_table_remove(session->user_profiles, &id); b = profile->buddy; if (b != NULL) serv_got_update(session->gc, trepia_profile_get_login(profile), FALSE, 0, 0, 0, 0); gaim_blist_remove_buddy(b); break; default: break; } g_hash_table_destroy(info); } else {
gboolean gaym_privacy_check(GaimConnection * gc, const char *nick) { /** * returns TRUE if allowed through, FALSE otherwise */ GSList *list; gboolean permitted = FALSE; switch (gc->account->perm_deny) { case 0: gaim_debug_warning("gaym", "Privacy setting was 0. If you can " "reproduce this, please file a bug report.\n"); permitted = TRUE; break; case GAIM_PRIVACY_ALLOW_ALL: permitted = TRUE; break; case GAIM_PRIVACY_DENY_ALL: gaim_debug_info("gaym", "%s blocked data received from %s (GAIM_PRIVACY_DENY_ALL)\n", gc->account->username, nick); break; case GAIM_PRIVACY_ALLOW_USERS: for (list = gc->account->permit; list != NULL; list = list->next) { if (!gaim_utf8_strcasecmp (nick, gaim_normalize(gc->account, (char *) list->data))) { permitted = TRUE; gaim_debug_info("gaym", "%s allowed data received from %s (GAIM_PRIVACY_ALLOW_USERS)\n", gc->account->username, nick); break; } } break; case GAIM_PRIVACY_DENY_USERS: /* seeing we're letting everyone through, except the deny list */ permitted = TRUE; for (list = gc->account->deny; list != NULL; list = list->next) { if (!gaim_utf8_strcasecmp (nick, gaim_normalize(gc->account, (char *) list->data))) { permitted = FALSE; gaim_debug_info("gaym", "%s blocked data received from %s (GAIM_PRIVACY_DENY_USERS)\n", gc->account->username, nick); break; } } break; case GAIM_PRIVACY_ALLOW_BUDDYLIST: if (gaim_find_buddy(gc->account, nick) != NULL) { permitted = TRUE; } else { gaim_debug_info("gaym", "%s blocked data received from %s (GAIM_PRIVACY_ALLOW_BUDDYLIST)\n", gc->account->username, nick); } break; default: gaim_debug_warning("gaym", "Privacy setting was unknown. If you can " "reproduce this, please file a bug report.\n"); permitted = FALSE; break; } /** * don't block/ignore self */ if (!gaim_utf8_strcasecmp(gc->account->username, nick)) { permitted = TRUE; gaim_debug_info("gaym", "declining to block/ignore self\n"); return permitted; } return permitted; }
/* process reply for get_buddies_list */ void qq_process_get_buddies_list_reply(guint8 *buf, gint buf_len, GaimConnection *gc) { qq_data *qd; qq_buddy *q_bud; gint len, bytes, bytes_expected, i; guint16 position, unknown; guint8 *data, *cursor, pascal_len; gchar *name; GaimBuddy *b; g_return_if_fail(buf != NULL && buf_len != 0); qd = (qq_data *) gc->proto_data; len = buf_len; data = g_newa(guint8, len); cursor = data; if (qq_crypt(DECRYPT, buf, buf_len, qd->session_key, data, &len)) { read_packet_w(data, &cursor, len, &position); /* the following data is buddy list in this packet */ i = 0; while (cursor < (data + len)) { q_bud = g_new0(qq_buddy, 1); bytes = 0; /* 000-003: uid */ bytes += read_packet_dw(data, &cursor, len, &q_bud->uid); /* 004-005: icon index (1-255) */ bytes += read_packet_w(data, &cursor, len, &q_bud->face); /* 006-006: age */ bytes += read_packet_b(data, &cursor, len, &q_bud->age); /* 007-007: gender */ bytes += read_packet_b(data, &cursor, len, &q_bud->gender); pascal_len = convert_as_pascal_string(cursor, &q_bud->nickname, QQ_CHARSET_DEFAULT); cursor += pascal_len; bytes += pascal_len; bytes += read_packet_w(data, &cursor, len, &unknown); /* flag1: (0-7) * bit1 => qq show * comm_flag: (0-7) * bit1 => member * bit4 => TCP mode * bit5 => open mobile QQ * bit6 => bind to mobile * bit7 => whether having a video */ bytes += read_packet_b(data, &cursor, len, &q_bud->flag1); bytes += read_packet_b(data, &cursor, len, &q_bud->comm_flag); bytes_expected = 12 + pascal_len; if (q_bud->uid == 0 || bytes != bytes_expected) { gaim_debug(GAIM_DEBUG_INFO, "QQ", "Buddy entry, expect %d bytes, read %d bytes\n", bytes_expected, bytes); g_free(q_bud->nickname); g_free(q_bud); continue; } else { i++; } if (QQ_DEBUG) { gaim_debug(GAIM_DEBUG_INFO, "QQ", "buddy [%09d]: flag1=0x%02x, comm_flag=0x%02x\n", q_bud->uid, q_bud->flag1, q_bud->comm_flag); } name = uid_to_gaim_name(q_bud->uid); b = gaim_find_buddy(gc->account, name); g_free(name); if (b == NULL) b = qq_add_buddy_by_recv_packet(gc, q_bud->uid, TRUE, FALSE); b->proto_data = q_bud; qd->buddies = g_list_append(qd->buddies, q_bud); qq_update_buddy_contact(gc, q_bud); } if(cursor > (data + len)) { gaim_debug(GAIM_DEBUG_ERROR, "QQ", "qq_process_get_buddies_list_reply: Dangerous error! maybe protocol changed, notify developers!"); } if (position == QQ_FRIENDS_LIST_POSITION_END) { gaim_debug(GAIM_DEBUG_INFO, "QQ", "Get friends list done, %d buddies\n", i); qq_send_packet_get_buddies_online(gc, QQ_FRIENDS_ONLINE_POSITION_START); } else { qq_send_packet_get_buddies_list(gc, position); } } else { gaim_debug(GAIM_DEBUG_ERROR, "QQ", "Error decrypt buddies list"); } }