void gaim_privacy_allow(GaimAccount *account, const char *who, gboolean local, gboolean restore) { GSList *list; switch (account->perm_deny) { case GAIM_PRIVACY_ALLOW_ALL: return; case GAIM_PRIVACY_ALLOW_USERS: gaim_privacy_permit_add(account, who, local); break; case GAIM_PRIVACY_DENY_USERS: gaim_privacy_deny_remove(account, who, local); break; case GAIM_PRIVACY_DENY_ALL: if (!restore) { /* Empty the allow-list. */ for (list = account->permit; list != NULL;) { char *who = list->data; list = list->next; gaim_privacy_permit_remove(account, who, local); } } gaim_privacy_permit_add(account, who, local); account->perm_deny = GAIM_PRIVACY_ALLOW_USERS; break; case GAIM_PRIVACY_ALLOW_BUDDYLIST: if (!gaim_find_buddy(account, who)) { add_buddies_in_permit(account, local); gaim_privacy_permit_add(account, who, local); account->perm_deny = GAIM_PRIVACY_ALLOW_USERS; } break; default: g_return_if_reached(); } }
/* 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); }
/** * 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 */ }