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); } }
static char * gaim_log_get_log_dir(GaimLogType type, const char *name, GaimAccount *account) { GaimPlugin *prpl; GaimPluginProtocolInfo *prpl_info; const char *prpl_name; char *acct_name; const char *target; char *dir; prpl = gaim_find_prpl(gaim_account_get_protocol_id(account)); if (!prpl) return NULL; prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(prpl); prpl_name = prpl_info->list_icon(account, NULL); acct_name = g_strdup(gaim_escape_filename(gaim_normalize(account, gaim_account_get_username(account)))); if (type == GAIM_LOG_CHAT) { char *temp = g_strdup_printf("%s.chat", gaim_normalize(account, name)); target = gaim_escape_filename(temp); g_free(temp); } else if(type == GAIM_LOG_SYSTEM) { target = ".system"; } else { target = gaim_escape_filename(gaim_normalize(account, name)); } dir = g_build_filename(gaim_user_dir(), "logs", prpl_name, acct_name, target, NULL); g_free(acct_name); return dir; }
gboolean gaym_unreference_channel_member(struct gaym_conn * gaym, gchar * name) { GaymBuddy *channel_member; channel_member = (GaymBuddy *) g_hash_table_lookup(gaym->channel_members, gaim_normalize(gaym->account,name)); if (!channel_member) return FALSE; else { if (channel_member->ref_count <= 0) gaim_debug_error("gaym", "****Reference counting error with channel members struct.\n"); channel_member->ref_count--; if (channel_member->ref_count == 0) { gaim_debug_misc("gaym", "Removing %s from channel_members\n", name); return g_hash_table_remove(gaym->channel_members, gaim_normalize(gaym->account, name)); } return FALSE; } }
GaimAccount * gaim_accounts_find_ext(const char *name, const char *protocol_id, gboolean (*account_test)(const GaimAccount *account)) { GaimAccount *result = NULL; GList *l; char *who; if (name) who = g_strdup(gaim_normalize(NULL, name)); else who = NULL; for (l = gaim_accounts_get_all(); l != NULL; l = l->next) { GaimAccount *account = (GaimAccount *)l->data; if (who && strcmp(gaim_normalize(NULL, gaim_account_get_username(account)), who)) continue; if (protocol_id && strcmp(account->protocol_id, protocol_id)) continue; if (account_test && !account_test(account)) continue; result = account; break; } g_free(who); return result; }
GaimPounce * gaim_find_pounce(const GaimAccount *pouncer, const char *pouncee, GaimPounceEvent events) { GaimPounce *pounce = NULL; GList *l; char *norm_pouncee; g_return_val_if_fail(pouncer != NULL, NULL); g_return_val_if_fail(pouncee != NULL, NULL); g_return_val_if_fail(events != GAIM_POUNCE_NONE, NULL); norm_pouncee = g_strdup(gaim_normalize(pouncer, pouncee)); for (l = gaim_pounces_get_all(); l != NULL; l = l->next) { pounce = (GaimPounce *)l->data; if ((gaim_pounce_get_events(pounce) & events) && (gaim_pounce_get_pouncer(pounce) == pouncer) && !gaim_utf8_strcasecmp(gaim_normalize(pouncer, gaim_pounce_get_pouncee(pounce)), norm_pouncee)) { break; } pounce = NULL; } g_free(norm_pouncee); return pounce; }
GaymBuddy *gaym_get_channel_member_reference(struct gaym_conn *gaym, const gchar * name) { GaymBuddy *channel_member = (GaymBuddy *) g_hash_table_lookup(gaym->channel_members, name); if (!channel_member) { GaymBuddy *channel_member = g_new0(GaymBuddy, 1); channel_member->ref_count = 1; g_hash_table_insert(gaym->channel_members, g_strdup(gaim_normalize(gaym->account,name)), channel_member); gaim_debug_misc("gaym", "Creating channel_members entry for %s\n", name); return g_hash_table_lookup(gaym->channel_members, gaim_normalize(gaym->account, name)); } else { gaim_debug_misc("gaym", "Adding reference to channel_members entry for %s\n", name); (channel_member->ref_count)++; return channel_member; } }
void gaym_buddy_status(struct gaym_conn *gaym, char *name, gboolean online, char *info) { char *bio = NULL; char *thumbnail = NULL; char *stats = NULL; char *url = NULL; struct gaym_fetch_thumbnail_data *data; if (!gaym || !gaym->account || !gaym->buddies || !name) { return; } if (info) { bio = gaym_bio_strdup(info); if (bio) { bio = g_strstrip(bio); } thumbnail = gaym_thumbnail_strdup(info); if (thumbnail) { thumbnail = g_strstrip(thumbnail); } stats = gaym_stats_strdup(info); if (stats) { stats = g_strstrip(stats); } } GaimConnection *gc = gaim_account_get_connection(gaym->account); if (!gc) { return; } struct gaym_buddy *ib = g_hash_table_lookup(gaym->buddies, name); char *normalized = g_strdup(gaim_normalize(gaym->account, name)); char *im_thumbnail = g_hash_table_lookup(gaym->im_thumbnail_needed, normalized); if (thumbnail) { if ((ib && gaim_utf8_strcasecmp(thumbnail, ib->thumbnail)) || im_thumbnail) { char *hashurl = NULL; hashurl = g_hash_table_lookup(gaym->confighash, "mini-profile-panel.thumbnail-prefix"); g_return_if_fail(hashurl != NULL); data = g_new0(struct gaym_fetch_thumbnail_data, 1); data->gc = gaim_account_get_connection(gaym->account); data->who = g_strdup(name); url = g_strdup_printf("%s%s", hashurl, thumbnail); gaim_url_fetch(url, FALSE, "Mozilla/4.0", FALSE, gaym_fetch_thumbnail_cb, data); g_free(url); } }
GdkPixbuf *lookup_cached_thumbnail(GaimAccount * account, const char *fullname) { GDir *gdir = NULL; GError *err = NULL; GdkPixbuf *pixbuf = NULL; const char *filename = NULL; char *dirname = NULL; char *path = NULL; const char *name = gaim_normalize(account, fullname); dirname = g_build_filename(gaim_user_dir(), "icons", "gaym", name, NULL); if (dirname) { gdir = g_dir_open(dirname, 0, &err); if (gdir) { filename = g_dir_read_name(gdir); // don't free filename: // owned by glib. if (filename) { path = g_build_filename(dirname, filename, NULL); if (path) pixbuf = gdk_pixbuf_new_from_file(path, &err); g_free(path); } g_dir_close(gdir); } g_free(dirname); } return pixbuf; }
static char *gaym_tooltip_text(GaimBuddy * buddy) { struct gaym_conn *gaym = (struct gaym_conn *) buddy->account->gc->proto_data; if (!gaym) { return NULL; } struct gaym_buddy *ib = g_hash_table_lookup(gaym->channel_members, gaim_normalize(gaym->account,buddy->name)); if(!ib) ib=g_hash_table_lookup(gaym->buddies, gaim_normalize(gaym->account,buddy->name)); if (!ib) { return g_strdup("No info found."); } return build_tooltip_text(ib); }
gboolean gaim_privacy_deny_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->deny; l != NULL; l = l->next) { if (!gaim_utf8_strcasecmp(name, gaim_normalize(account, (char *)l->data))) break; } if (l != NULL) { g_free(name); return FALSE; } account->deny = g_slist_append(account->deny, name); if (!local_only && gaim_account_is_connected(account)) serv_add_deny(gaim_account_get_connection(account), who); if (privacy_ops != NULL && privacy_ops->deny_added != NULL) privacy_ops->deny_added(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); } return TRUE; }
GaimLog *gaim_log_new(GaimLogType type, const char *name, GaimAccount *account, time_t time) { GaimLog *log = g_new0(GaimLog, 1); log->name = g_strdup(gaim_normalize(account, name)); log->account = account; log->time = time; log->type = type; log->logger_data = NULL; log->logger = gaim_log_logger_get(); if (log->logger && log->logger->create) log->logger->create(log); return log; }
void gaim_pounce_execute(const GaimAccount *pouncer, const char *pouncee, GaimPounceEvent events) { GaimPounce *pounce; GaimPounceHandler *handler; GList *l, *l_next; char *norm_pouncee; g_return_if_fail(pouncer != NULL); g_return_if_fail(pouncee != NULL); g_return_if_fail(events != GAIM_POUNCE_NONE); norm_pouncee = g_strdup(gaim_normalize(pouncer, pouncee)); for (l = gaim_pounces_get_all(); l != NULL; l = l_next) { pounce = (GaimPounce *)l->data; l_next = l->next; if ((gaim_pounce_get_events(pounce) & events) && (gaim_pounce_get_pouncer(pounce) == pouncer) && !gaim_utf8_strcasecmp(gaim_normalize(pouncer, gaim_pounce_get_pouncee(pounce)), norm_pouncee)) { handler = g_hash_table_lookup(pounce_handlers, pounce->ui_type); if (handler != NULL && handler->cb != NULL) { handler->cb(pounce, events, gaim_pounce_get_data(pounce)); if (!gaim_pounce_get_save(pounce)) gaim_pounce_destroy(pounce); } } } g_free(norm_pouncee); }
static void gaym_get_info(GaimConnection * gc, const char *who) { struct gaym_conn *gaym = gc->proto_data; const char *args[1]; args[0] = who; char *normalized = g_strdup(gaim_normalize(gc->account, who)); /** * We are adding the same char* to both the key and the value. * If this changes, we need to change the corresponding * g_hash_table_new_full() so that things are properly cleaned * up during the remove/destroy phase. */ g_hash_table_insert(gaym->info_window_needed, normalized, normalized); gaym_cmd_whois(gaym, "whois", NULL, args); }
void chaticon_replace(GaimConversation * conv, const char *name, GaimConvChatBuddyFlags flags) { GaimGtkConversation *gtkconv = GAIM_GTK_CONVERSATION(conv); GaimGtkChatPane *gtkchat = gtkconv->u.chat; gboolean valid; GtkTreeIter iter; int row_count = 0; GtkTreeModel *list_store = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkchat->list)); /* Get the first iter in the list */ valid = gtk_tree_model_get_iter_first(list_store, &iter); while (valid) { /* Walk through the list, reading each row */ gchar *str_data; /* Make sure you terminate calls to gtk_tree_model_get() with a '-1' value */ gtk_tree_model_get(list_store, &iter, CHAT_USERS_NAME_COLUMN, &str_data, -1); /* Do something with the data */ g_print("Row %d: (%s)(%s)\n", row_count, str_data, name); if (!strcmp(str_data, name)) { GdkPixbuf *pixbuf = lookup_cached_thumbnail(conv->account, gaim_normalize(conv->account, name)); gaim_debug_misc("chaticon", "Got pixbuf: %x\n"); GtkTreePath *path = gtk_tree_model_get_path(list_store, &iter); gtk_list_store_set(GTK_LIST_STORE(list_store), &iter, 0, pixbuf, -1); gtk_tree_model_row_changed(list_store, path, &iter); // g_free(pixbuf); break; } row_count++; valid = gtk_tree_model_iter_next(list_store, &iter); g_free(str_data); } }
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; }
int gaim_log_get_total_size(GaimLogType type, const char *name, GaimAccount *account) { gpointer ptrsize; int size = 0; GSList *n; struct _gaim_logsize_user *lu; lu = g_new(struct _gaim_logsize_user, 1); lu->name = g_strdup(gaim_normalize(account, name)); lu->account = account; if(g_hash_table_lookup_extended(logsize_users, lu, NULL, &ptrsize)) { size = GPOINTER_TO_INT(ptrsize); g_free(lu->name); g_free(lu); } else { for (n = loggers; n; n = n->next) { GaimLogLogger *logger = n->data; if(logger->total_size){ size += (logger->total_size)(type, name, account); } else if(logger->list) { GList *logs = (logger->list)(type, name, account); int this_size = 0; while (logs) { GList *logs2 = logs->next; GaimLog *log = (GaimLog*)(logs->data); this_size += gaim_log_get_size(log); gaim_log_free(log); g_list_free_1(logs); logs = logs2; } size += this_size; } } g_hash_table_replace(logsize_users, lu, GINT_TO_POINTER(size)); } return size; }
void gaim_log_write(GaimLog *log, GaimMessageFlags type, const char *from, time_t time, const char *message) { struct _gaim_logsize_user *lu; g_return_if_fail(log); g_return_if_fail(log->logger); g_return_if_fail(log->logger->write); (log->logger->write)(log, type, from, time, message); lu = g_new(struct _gaim_logsize_user, 1); lu->name = g_strdup(gaim_normalize(log->account, log->name)); lu->account = log->account; g_hash_table_remove(logsize_users, lu); g_free(lu->name); g_free(lu); }
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; }
void synchronize_deny_list(GaimConnection * gc, GHashTable * confighash) { char *srvdeny = NULL; gchar **srvdenylist = NULL; GSList *list; gint i = 0; gboolean needsync = FALSE; g_return_if_fail(confighash != NULL); srvdeny = g_hash_table_lookup(confighash, "connect-list.ignore.members"); if (!srvdeny) { srvdeny = ""; } srvdenylist = g_strsplit(srvdeny, ",", -1); /** * The nicks come in here as if they came from the IRC server * so they need to be converted to GayM format */ for (i = 0; srvdenylist[i]; i++) { gcom_nick_to_gaym(srvdenylist[i]); } /* Add server deny list from config.txt to local deny list */ for (i = 0; srvdenylist[i]; i++) { needsync = TRUE; for (list = gc->account->deny; list != NULL; list = list->next) { if (!gaim_utf8_strcasecmp (srvdenylist[i], gaim_normalize(gc->account, (char *) list->data))) { needsync = FALSE; break; } } if (needsync) { if (!gaim_privacy_deny_add(gc->account, srvdenylist[i], TRUE)) { gaim_debug_error("gaym", "Failed to add %s to local deny list from server.\n", srvdenylist[i]); } else { gaim_debug_misc("gaym", "Added %s to local deny list from server.\n", srvdenylist[i]); } } } /* Add local deny list not found in config.txt to server deny list */ for (list = gc->account->deny; list != NULL; list = list->next) { needsync = TRUE; for (i = 0; srvdenylist[i]; i++) { if (!gaim_utf8_strcasecmp (srvdenylist[i], gaim_normalize(gc->account, (char *) list->data))) { needsync = FALSE; break; } } if (needsync) { gaym_server_store_deny(gc, (char *) list->data, TRUE); } } g_strfreev(srvdenylist); return; }
void gaym_buddy_status(struct gaym_conn *gaym, char *name, gboolean online, char *info, gboolean fetch_thumbnail) { char *bio = NULL; char *thumbnail = NULL; char *stats = NULL; char *url = NULL; struct gaym_fetch_thumbnail_data *data; gboolean gaymuser = FALSE; if (!gaym || !gaym->account || !gaym->buddies || !name) { return; } if (info) { #ifdef GAYM_TOKEN gaymuser = gaym_stats_find_gaym_token(info); #endif bio = gaym_bio_strdup(info); if (bio) { bio = g_strstrip(bio); } thumbnail = gaym_thumbnail_strdup(info); if (thumbnail) { thumbnail = g_strstrip(thumbnail); } stats = gaym_stats_strdup(info); if (stats) { stats = g_strstrip(stats); } } GaimConnection *gc = gaim_account_get_connection(gaym->account); if (!gc) { return; } struct gaym_buddy *ib = g_hash_table_lookup(gaym->buddies, name); if (!ib) ib = g_hash_table_lookup(gaym->channel_members, name); char *normalized = g_strdup(gaim_normalize(gaym->account, name)); if (thumbnail && fetch_thumbnail) { if (!ib || gaim_utf8_strcasecmp(thumbnail, ib->thumbnail)) { char *hashurl = NULL; hashurl = g_hash_table_lookup(gaym->confighash, "mini-profile-panel.thumbnail-prefix"); g_return_if_fail(hashurl != NULL); data = g_new0(struct gaym_fetch_thumbnail_data, 1); data->gc = gaim_account_get_connection(gaym->account); data->who = g_strdup(gaim_normalize(gaym->account, name)); data->filename = g_strdup(g_strrstr(thumbnail, "/")); gaim_debug_misc("gayminfo", "Found filename: %s\n", data->filename); url = g_strdup_printf("%s%s", hashurl, thumbnail); gaim_util_fetch_url(url, FALSE, "Mozilla/4.0", FALSE, gaym_fetch_thumbnail_cb, data); g_free(url); } }
void gaym_buddy_status(struct gaym_conn *gaym, char *name, gboolean online, char *info) { char *bio = NULL; char *thumbnail = NULL; char *stats = NULL; char *url = NULL; struct gaym_fetch_thumbnail_data *data; gboolean gaymuser=FALSE; if (!gaym || !gaym->account || !gaym->buddies || !name) { return; } if (info) { #ifdef GAYM_TOKEN gaymuser = gaym_stats_find_gaym_token(info); #endif bio = gaym_bio_strdup(info); if (bio) { bio = g_strstrip(bio); } thumbnail = gaym_thumbnail_strdup(info); if (thumbnail) { thumbnail = g_strstrip(thumbnail); } stats = gaym_stats_strdup(info); if (stats) { stats = g_strstrip(stats); } } GaimConnection *gc = gaim_account_get_connection(gaym->account); if (!gc) { return; } struct gaym_buddy *ib = g_hash_table_lookup(gaym->buddies, name); char *normalized = g_strdup(gaim_normalize(gaym->account, name)); if (thumbnail) { gboolean do_fetch = 1; GError *err = NULL; if (!ib || gaim_utf8_strcasecmp(thumbnail, ib->thumbnail)) { char *dirname = g_build_filename(gaim_user_dir(), "icons", "gaym", gaim_normalize(gaym->account, name), NULL); GDir *gdir = g_dir_open(dirname, 0, &err); if (gdir) { const char *filename; while ((filename = g_dir_read_name(gdir))) /* don't free filename: owned by glib.*/ { char *thumbnail_base = g_path_get_basename(thumbnail); gaim_debug_misc("gaym", "compared %s and %s\n", thumbnail_base, filename); if (!gaim_utf8_strcasecmp(thumbnail_base, filename)) { do_fetch = 0; break; } g_free(thumbnail_base); } g_dir_close(gdir); } if (do_fetch) { gaim_debug_misc("gaym", "********************************************\n"); gaim_debug_misc("gaym", "*****************FETCH**********************\n"); gaim_debug_misc("gaym", "********************************************\n"); char *hashurl = NULL; hashurl = g_hash_table_lookup(gaym->confighash, "mini-profile-panel.thumbnail-prefix"); g_return_if_fail(hashurl != NULL); data = g_new0(struct gaym_fetch_thumbnail_data, 1); data->gc = gaim_account_get_connection(gaym->account); data->who = g_strdup(gaim_normalize(gaym->account, name)); data->filename = g_strdup(g_strrstr(thumbnail, "/")); gaim_debug_misc("gayminfo", "Found filename: %s\n", data->filename); url = g_strdup_printf("%s%s", hashurl, thumbnail); gaim_url_fetch(url, FALSE, "Mozilla/4.0", FALSE, gaym_fetch_thumbnail_cb, data); g_free(url); } } }
/** * 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 */ }