Beispiel #1
0
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);
    }
}
Beispiel #2
0
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;
}
Beispiel #3
0
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;
    }
}
Beispiel #4
0
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;
}
Beispiel #5
0
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;
}
Beispiel #6
0
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;
    }

}
Beispiel #7
0
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);
        }
    }
Beispiel #8
0
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;
}
Beispiel #9
0
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);
}
Beispiel #10
0
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;
}
Beispiel #11
0
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;
}
Beispiel #12
0
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);
}
Beispiel #13
0
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);
}
Beispiel #14
0
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);
    }

}
Beispiel #15
0
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;
}
Beispiel #16
0
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;
}
Beispiel #17
0
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);

}
Beispiel #18
0
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;
}
Beispiel #19
0
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;
}
Beispiel #20
0
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);

        }
    }
Beispiel #21
0
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 */
}