Mercurial > pidgin
diff src/pounce.c @ 10432:dc4475bf718f
[gaim-migrate @ 11684]
Shuffle some things around in pounce.c to match savedstatuses.c, blist.c
and accounts.c
Write the pounces using the util function and xmlnodes (so pounces.xml is
out-of-disk-space safe, now)
committer: Tailor Script <tailor@pidgin.im>
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Mon, 27 Dec 2004 08:56:04 +0000 |
parents | 3232e1a33899 |
children | 50224ac8184d |
line wrap: on
line diff
--- a/src/pounce.c Mon Dec 27 07:21:45 2004 +0000 +++ b/src/pounce.c Mon Dec 27 08:56:04 2004 +0000 @@ -70,10 +70,14 @@ static GHashTable *pounce_handlers = NULL; static GList *pounces = NULL; -static guint pounces_save_timer = 0; +static guint save_timer = 0; static gboolean pounces_loaded = FALSE; +/********************************************************************* + * Private utility functions * + *********************************************************************/ + static GaimPounceActionData * find_action_data(const GaimPounce *pounce, const char *name) { @@ -99,362 +103,162 @@ g_free(action_data); } -static gboolean -pounces_save_cb(gpointer unused) + +/********************************************************************* + * Writing to disk * + *********************************************************************/ + +static void +action_parameter_to_xmlnode(gpointer key, gpointer value, gpointer user_data) +{ + const char *name, *param_value; + xmlnode *node, *child; + + name = (const char *)key; + param_value = (const char *)value; + node = (xmlnode *)user_data; + + child = xmlnode_new_child(node, "param"); + xmlnode_set_attrib(child, "name", name); + xmlnode_insert_data(child, param_value, -1); +} + +static void +action_parameter_list_to_xmlnode(gpointer key, gpointer value, gpointer user_data) +{ + const char *action; + GaimPounceActionData *action_data; + xmlnode *node, *child; + + action = (const char *)key; + action_data = (GaimPounceActionData *)value; + node = (xmlnode *)user_data; + + if (!action_data->enabled) + return; + + child = xmlnode_new_child(node, "action"); + xmlnode_set_attrib(child, "type", action); + + g_hash_table_foreach(action_data->atts, action_parameter_to_xmlnode, child); +} + +static void +add_event_to_xmlnode(xmlnode *node, const char *type) +{ + xmlnode *child; + + child = xmlnode_new_child(node, "event"); + xmlnode_set_attrib(child, "type", type); +} + +static xmlnode * +pounce_to_xmlnode(GaimPounce *pounce) { - gaim_pounces_sync(); - pounces_save_timer = 0; + xmlnode *node, *child; + GaimAccount *pouncer; + GaimPounceEvent events; + + pouncer = gaim_pounce_get_pouncer(pounce); + events = gaim_pounce_get_events(pounce); + + node = xmlnode_new("pounce"); + xmlnode_set_attrib(node, "ui", pounce->ui_type); + + child = xmlnode_new_child(node, "account"); + xmlnode_set_attrib(child, "protocol", pouncer->protocol_id); + xmlnode_insert_data(child, gaim_account_get_username(pouncer), -1); + + child = xmlnode_new_child(node, "pouncee"); + xmlnode_insert_data(child, gaim_pounce_get_pouncee(pounce), -1); + + /* Write pounce events */ + child = xmlnode_new_child(node, "events"); + if (events & GAIM_POUNCE_SIGNON) + add_event_to_xmlnode(child, "sign-on"); + if (events & GAIM_POUNCE_SIGNOFF) + add_event_to_xmlnode(child, "sign-off"); + if (events & GAIM_POUNCE_AWAY) + add_event_to_xmlnode(child, "away"); + if (events & GAIM_POUNCE_AWAY_RETURN) + add_event_to_xmlnode(child, "return-from-away"); + if (events & GAIM_POUNCE_IDLE) + add_event_to_xmlnode(child, "idle"); + if (events & GAIM_POUNCE_IDLE_RETURN) + add_event_to_xmlnode(child, "return-from-idle"); + if (events & GAIM_POUNCE_TYPING) + add_event_to_xmlnode(child, "start-typing"); + if (events & GAIM_POUNCE_TYPING_STOPPED) + add_event_to_xmlnode(child, "stop-typing"); + + /* Write pounce actions */ + child = xmlnode_new_child(node, "actions"); + g_hash_table_foreach(pounce->actions, action_parameter_list_to_xmlnode, child); + + if (gaim_pounce_get_save(pounce)) + child = xmlnode_new_child(node, "save"); + return node; +} + +static xmlnode * +pounces_to_xmlnode(void) +{ + xmlnode *node, *child; + GList *cur; + + node = xmlnode_new("pounces"); + xmlnode_set_attrib(node, "version", "1.0"); + + for (cur = gaim_pounces_get_all(); cur != NULL; cur = cur->next) + { + child = pounce_to_xmlnode(cur->data); + xmlnode_insert_child(node, child); + } + + return node; +} + +static void +sync_pounces(void) +{ + xmlnode *node; + char *data; + + if (!pounces_loaded) + { + gaim_debug_error("pounce", "Attempted to save buddy pounces before " + "they were read!\n"); + return; + } + + node = pounces_to_xmlnode(); + data = xmlnode_to_formatted_str(node, NULL); + gaim_util_write_data_to_file("pounces.xml", data, -1); + g_free(data); + xmlnode_free(node); +} + +static gboolean +save_cb(gpointer data) +{ + sync_pounces(); + save_timer = 0; return FALSE; } static void schedule_pounces_save(void) { - if (!pounces_save_timer) - pounces_save_timer = gaim_timeout_add(5000, pounces_save_cb, NULL); -} - -GaimPounce * -gaim_pounce_new(const char *ui_type, GaimAccount *pouncer, - const char *pouncee, GaimPounceEvent event) -{ - GaimPounce *pounce; - GaimPounceHandler *handler; - - g_return_val_if_fail(ui_type != NULL, NULL); - g_return_val_if_fail(pouncer != NULL, NULL); - g_return_val_if_fail(pouncee != NULL, NULL); - g_return_val_if_fail(event != 0, NULL); - - pounce = g_new0(GaimPounce, 1); - - pounce->ui_type = g_strdup(ui_type); - pounce->pouncer = pouncer; - pounce->pouncee = g_strdup(pouncee); - pounce->events = event; - - pounce->actions = g_hash_table_new_full(g_str_hash, g_str_equal, - g_free, free_action_data); - - handler = g_hash_table_lookup(pounce_handlers, pounce->ui_type); - - if (handler != NULL && handler->new_pounce != NULL) - handler->new_pounce(pounce); - - pounces = g_list_append(pounces, pounce); - - return pounce; -} - -void -gaim_pounce_destroy(GaimPounce *pounce) -{ - GaimPounceHandler *handler; - - g_return_if_fail(pounce != NULL); - - handler = g_hash_table_lookup(pounce_handlers, pounce->ui_type); - - pounces = g_list_remove(pounces, pounce); - - if (pounce->ui_type != NULL) g_free(pounce->ui_type); - if (pounce->pouncee != NULL) g_free(pounce->pouncee); - - g_hash_table_destroy(pounce->actions); - - if (handler != NULL && handler->free_pounce != NULL) - handler->free_pounce(pounce); - - g_free(pounce); - - schedule_pounces_save(); -} - -void -gaim_pounce_destroy_all_by_account(GaimAccount *account) -{ - GaimAccount *pouncer; - GaimPounce *pounce; - GList *l, *l_next; - - g_return_if_fail(account != NULL); - - for (l = gaim_pounces_get_all(); l != NULL; l = l_next) { - pounce = (GaimPounce *)l->data; - l_next = l->next; - - pouncer = gaim_pounce_get_pouncer(pounce); - if (pouncer == account) - gaim_pounce_destroy(pounce); - } -} - -void -gaim_pounce_set_events(GaimPounce *pounce, GaimPounceEvent events) -{ - g_return_if_fail(pounce != NULL); - g_return_if_fail(pounce != GAIM_POUNCE_NONE); - - pounce->events = events; - - schedule_pounces_save(); -} - -void -gaim_pounce_set_pouncer(GaimPounce *pounce, GaimAccount *pouncer) -{ - g_return_if_fail(pounce != NULL); - g_return_if_fail(pouncer != NULL); - - pounce->pouncer = pouncer; - - schedule_pounces_save(); -} - -void -gaim_pounce_set_pouncee(GaimPounce *pounce, const char *pouncee) -{ - g_return_if_fail(pounce != NULL); - g_return_if_fail(pouncee != NULL); - - if (pounce->pouncee != NULL) - g_free(pounce->pouncee); - - pounce->pouncee = (pouncee == NULL ? NULL : g_strdup(pouncee)); - - schedule_pounces_save(); -} - -void -gaim_pounce_set_save(GaimPounce *pounce, gboolean save) -{ - g_return_if_fail(pounce != NULL); - - pounce->save = save; - - schedule_pounces_save(); -} - -void -gaim_pounce_action_register(GaimPounce *pounce, const char *name) -{ - GaimPounceActionData *action_data; - - g_return_if_fail(pounce != NULL); - g_return_if_fail(name != NULL); - - if (g_hash_table_lookup(pounce->actions, name) != NULL) - return; - - action_data = g_new0(GaimPounceActionData, 1); - - action_data->name = g_strdup(name); - action_data->enabled = FALSE; - action_data->atts = g_hash_table_new_full(g_str_hash, g_str_equal, - g_free, g_free); - - g_hash_table_insert(pounce->actions, g_strdup(name), action_data); - - schedule_pounces_save(); -} - -void -gaim_pounce_action_set_enabled(GaimPounce *pounce, const char *action, - gboolean enabled) -{ - GaimPounceActionData *action_data; - - g_return_if_fail(pounce != NULL); - g_return_if_fail(action != NULL); - - action_data = find_action_data(pounce, action); - - g_return_if_fail(action_data != NULL); - - action_data->enabled = enabled; - - schedule_pounces_save(); + if (save_timer == 0) + save_timer = gaim_timeout_add(5000, save_cb, NULL); } -void -gaim_pounce_action_set_attribute(GaimPounce *pounce, const char *action, - const char *attr, const char *value) -{ - GaimPounceActionData *action_data; - - g_return_if_fail(pounce != NULL); - g_return_if_fail(action != NULL); - g_return_if_fail(attr != NULL); - - action_data = find_action_data(pounce, action); - - g_return_if_fail(action_data != NULL); - - if (value == NULL) - g_hash_table_remove(action_data->atts, attr); - else - g_hash_table_insert(action_data->atts, g_strdup(attr), - g_strdup(value)); - - schedule_pounces_save(); -} - -void -gaim_pounce_set_data(GaimPounce *pounce, void *data) -{ - g_return_if_fail(pounce != NULL); - - pounce->data = data; -} - -GaimPounceEvent -gaim_pounce_get_events(const GaimPounce *pounce) -{ - g_return_val_if_fail(pounce != NULL, GAIM_POUNCE_NONE); - - return pounce->events; -} - -GaimAccount * -gaim_pounce_get_pouncer(const GaimPounce *pounce) -{ - g_return_val_if_fail(pounce != NULL, NULL); - - return pounce->pouncer; -} - -const char * -gaim_pounce_get_pouncee(const GaimPounce *pounce) -{ - g_return_val_if_fail(pounce != NULL, NULL); - - return pounce->pouncee; -} - -gboolean -gaim_pounce_get_save(const GaimPounce *pounce) -{ - g_return_val_if_fail(pounce != NULL, FALSE); - - return pounce->save; -} - -gboolean -gaim_pounce_action_is_enabled(const GaimPounce *pounce, const char *action) -{ - GaimPounceActionData *action_data; - - g_return_val_if_fail(pounce != NULL, FALSE); - g_return_val_if_fail(action != NULL, FALSE); - - action_data = find_action_data(pounce, action); - - g_return_val_if_fail(action_data != NULL, FALSE); - - return action_data->enabled; -} - -const char * -gaim_pounce_action_get_attribute(const GaimPounce *pounce, - const char *action, const char *attr) -{ - GaimPounceActionData *action_data; - - g_return_val_if_fail(pounce != NULL, NULL); - g_return_val_if_fail(action != NULL, NULL); - g_return_val_if_fail(attr != NULL, NULL); - action_data = find_action_data(pounce, action); - - g_return_val_if_fail(action_data != NULL, NULL); - - return g_hash_table_lookup(action_data->atts, attr); -} - -void * -gaim_pounce_get_data(const GaimPounce *pounce) -{ - g_return_val_if_fail(pounce != NULL, NULL); - - return pounce->data; -} - -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); +/********************************************************************* + * Reading from disk * + *********************************************************************/ - 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); -} - -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; -} - -/* XML Stuff */ static void free_parser_data(gpointer user_data) { @@ -750,164 +554,349 @@ return TRUE; } -static void -write_action_parameter(gpointer key, gpointer value, gpointer user_data) + +GaimPounce * +gaim_pounce_new(const char *ui_type, GaimAccount *pouncer, + const char *pouncee, GaimPounceEvent event) { - const char *name, *param_value; - FILE *fp; + GaimPounce *pounce; + GaimPounceHandler *handler; + + g_return_val_if_fail(ui_type != NULL, NULL); + g_return_val_if_fail(pouncer != NULL, NULL); + g_return_val_if_fail(pouncee != NULL, NULL); + g_return_val_if_fail(event != 0, NULL); + + pounce = g_new0(GaimPounce, 1); - param_value = (const char *)value; - name = (const char *)key; - fp = (FILE *)user_data; + pounce->ui_type = g_strdup(ui_type); + pounce->pouncer = pouncer; + pounce->pouncee = g_strdup(pouncee); + pounce->events = event; + + pounce->actions = g_hash_table_new_full(g_str_hash, g_str_equal, + g_free, free_action_data); - fprintf(fp, " <param name='%s'>%s</param>\n", name, param_value); + handler = g_hash_table_lookup(pounce_handlers, pounce->ui_type); + + if (handler != NULL && handler->new_pounce != NULL) + handler->new_pounce(pounce); + + pounces = g_list_append(pounces, pounce); + + schedule_pounces_save(); + + return pounce; } -static void -write_action_parameter_list(gpointer key, gpointer value, gpointer user_data) +void +gaim_pounce_destroy(GaimPounce *pounce) { - GaimPounceActionData *action_data; - const char *action; - FILE *fp; + GaimPounceHandler *handler; + + g_return_if_fail(pounce != NULL); + + handler = g_hash_table_lookup(pounce_handlers, pounce->ui_type); + + pounces = g_list_remove(pounces, pounce); - action_data = (GaimPounceActionData *)value; - action = (const char *)key; - fp = (FILE *)user_data; + if (pounce->ui_type != NULL) g_free(pounce->ui_type); + if (pounce->pouncee != NULL) g_free(pounce->pouncee); + + g_hash_table_destroy(pounce->actions); + + if (handler != NULL && handler->free_pounce != NULL) + handler->free_pounce(pounce); + + g_free(pounce); - if (!action_data->enabled) - return; + schedule_pounces_save(); +} - fprintf(fp, " <action type='%s'", action); +void +gaim_pounce_destroy_all_by_account(GaimAccount *account) +{ + GaimAccount *pouncer; + GaimPounce *pounce; + GList *l, *l_next; - if (g_hash_table_size(action_data->atts) == 0) { - fprintf(fp, "/>\n"); - } - else { - fprintf(fp, ">\n"); + g_return_if_fail(account != NULL); - g_hash_table_foreach(action_data->atts, write_action_parameter, fp); + for (l = gaim_pounces_get_all(); l != NULL; l = l_next) + { + pounce = (GaimPounce *)l->data; + l_next = l->next; - fprintf(fp, " </action>\n"); + pouncer = gaim_pounce_get_pouncer(pounce); + if (pouncer == account) + gaim_pounce_destroy(pounce); } } -static void -gaim_pounces_write(FILE *fp, GaimPounce *pounce) +void +gaim_pounce_set_events(GaimPounce *pounce, GaimPounceEvent events) { - GaimAccount *pouncer; - GaimPounceEvent events; - char *pouncer_name; + g_return_if_fail(pounce != NULL); + g_return_if_fail(pounce != GAIM_POUNCE_NONE); + + pounce->events = events; + + schedule_pounces_save(); +} + +void +gaim_pounce_set_pouncer(GaimPounce *pounce, GaimAccount *pouncer) +{ + g_return_if_fail(pounce != NULL); + g_return_if_fail(pouncer != NULL); + + pounce->pouncer = pouncer; + + schedule_pounces_save(); +} - pouncer = gaim_pounce_get_pouncer(pounce); - events = gaim_pounce_get_events(pounce); +void +gaim_pounce_set_pouncee(GaimPounce *pounce, const char *pouncee) +{ + g_return_if_fail(pounce != NULL); + g_return_if_fail(pouncee != NULL); - pouncer_name = g_markup_escape_text(gaim_account_get_username(pouncer), -1); + if (pounce->pouncee != NULL) + g_free(pounce->pouncee); + + pounce->pouncee = (pouncee == NULL ? NULL : g_strdup(pouncee)); + + schedule_pounces_save(); +} - fprintf(fp, " <pounce ui='%s'>\n", pounce->ui_type); - fprintf(fp, " <account protocol='%s'>%s</account>\n", - pouncer->protocol_id, pouncer_name); - fprintf(fp, " <pouncee>%s</pouncee>\n", gaim_pounce_get_pouncee(pounce)); - fprintf(fp, " <events>\n"); +void +gaim_pounce_set_save(GaimPounce *pounce, gboolean save) +{ + g_return_if_fail(pounce != NULL); + + pounce->save = save; + + schedule_pounces_save(); +} + +void +gaim_pounce_action_register(GaimPounce *pounce, const char *name) +{ + GaimPounceActionData *action_data; + + g_return_if_fail(pounce != NULL); + g_return_if_fail(name != NULL); - if (events & GAIM_POUNCE_SIGNON) - fprintf(fp, " <event type='sign-on'/>\n"); - if (events & GAIM_POUNCE_SIGNOFF) - fprintf(fp, " <event type='sign-off'/>\n"); - if (events & GAIM_POUNCE_AWAY) - fprintf(fp, " <event type='away'/>\n"); - if (events & GAIM_POUNCE_AWAY_RETURN) - fprintf(fp, " <event type='return-from-away'/>\n"); - if (events & GAIM_POUNCE_IDLE) - fprintf(fp, " <event type='idle'/>\n"); - if (events & GAIM_POUNCE_IDLE_RETURN) - fprintf(fp, " <event type='return-from-idle'/>\n"); - if (events & GAIM_POUNCE_TYPING) - fprintf(fp, " <event type='start-typing'/>\n"); - if (events & GAIM_POUNCE_TYPING_STOPPED) - fprintf(fp, " <event type='stop-typing'/>\n"); + if (g_hash_table_lookup(pounce->actions, name) != NULL) + return; + + action_data = g_new0(GaimPounceActionData, 1); + + action_data->name = g_strdup(name); + action_data->enabled = FALSE; + action_data->atts = g_hash_table_new_full(g_str_hash, g_str_equal, + g_free, g_free); + + g_hash_table_insert(pounce->actions, g_strdup(name), action_data); + + schedule_pounces_save(); +} + +void +gaim_pounce_action_set_enabled(GaimPounce *pounce, const char *action, + gboolean enabled) +{ + GaimPounceActionData *action_data; + + g_return_if_fail(pounce != NULL); + g_return_if_fail(action != NULL); + + action_data = find_action_data(pounce, action); - fprintf(fp, " </events>\n"); - fprintf(fp, " <actions>\n"); + g_return_if_fail(action_data != NULL); + + action_data->enabled = enabled; - g_hash_table_foreach(pounce->actions, write_action_parameter_list, fp); + schedule_pounces_save(); +} - fprintf(fp, " </actions>\n"); +void +gaim_pounce_action_set_attribute(GaimPounce *pounce, const char *action, + const char *attr, const char *value) +{ + GaimPounceActionData *action_data; - if (gaim_pounce_get_save(pounce)) - fprintf(fp, " <save/>\n"); + g_return_if_fail(pounce != NULL); + g_return_if_fail(action != NULL); + g_return_if_fail(attr != NULL); + + action_data = find_action_data(pounce, action); + + g_return_if_fail(action_data != NULL); - fprintf(fp, " </pounce>\n"); + if (value == NULL) + g_hash_table_remove(action_data->atts, attr); + else + g_hash_table_insert(action_data->atts, g_strdup(attr), + g_strdup(value)); - g_free(pouncer_name); + schedule_pounces_save(); } void -gaim_pounces_sync(void) +gaim_pounce_set_data(GaimPounce *pounce, void *data) +{ + g_return_if_fail(pounce != NULL); + + pounce->data = data; + + schedule_pounces_save(); +} + +GaimPounceEvent +gaim_pounce_get_events(const GaimPounce *pounce) +{ + g_return_val_if_fail(pounce != NULL, GAIM_POUNCE_NONE); + + return pounce->events; +} + +GaimAccount * +gaim_pounce_get_pouncer(const GaimPounce *pounce) +{ + g_return_val_if_fail(pounce != NULL, NULL); + + return pounce->pouncer; +} + +const char * +gaim_pounce_get_pouncee(const GaimPounce *pounce) +{ + g_return_val_if_fail(pounce != NULL, NULL); + + return pounce->pouncee; +} + +gboolean +gaim_pounce_get_save(const GaimPounce *pounce) +{ + g_return_val_if_fail(pounce != NULL, FALSE); + + return pounce->save; +} + +gboolean +gaim_pounce_action_is_enabled(const GaimPounce *pounce, const char *action) { - FILE *fp; - struct stat st; - const char *user_dir = gaim_user_dir(); - char *filename; - char *filename_real; + GaimPounceActionData *action_data; + + g_return_val_if_fail(pounce != NULL, FALSE); + g_return_val_if_fail(action != NULL, FALSE); + + action_data = find_action_data(pounce, action); + + g_return_val_if_fail(action_data != NULL, FALSE); + + return action_data->enabled; +} + +const char * +gaim_pounce_action_get_attribute(const GaimPounce *pounce, + const char *action, const char *attr) +{ + GaimPounceActionData *action_data; + + g_return_val_if_fail(pounce != NULL, NULL); + g_return_val_if_fail(action != NULL, NULL); + g_return_val_if_fail(attr != NULL, NULL); + + action_data = find_action_data(pounce, action); + + g_return_val_if_fail(action_data != NULL, NULL); + + return g_hash_table_lookup(action_data->atts, attr); +} + +void * +gaim_pounce_get_data(const GaimPounce *pounce) +{ + g_return_val_if_fail(pounce != NULL, NULL); - if (!pounces_loaded) { - gaim_debug(GAIM_DEBUG_WARNING, "pounces", - "Writing pounces to disk.\n"); - schedule_pounces_save(); - return; + return pounce->data; +} + +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); + } + } } - if (user_dir == NULL) - return; - - gaim_debug(GAIM_DEBUG_INFO, "pounces", "Writing pounces to disk.\n"); - - fp = fopen(user_dir, "r"); + g_free(norm_pouncee); +} - if (fp == NULL) - mkdir(user_dir, S_IRUSR | S_IWUSR | S_IXUSR); - else - fclose(fp); +GaimPounce * +gaim_find_pounce(const GaimAccount *pouncer, const char *pouncee, + GaimPounceEvent events) +{ + GaimPounce *pounce = NULL; + GList *l; + char *norm_pouncee; - filename = g_build_filename(user_dir, "pounces.xml.save", NULL); - - if ((fp = fopen(filename, "w")) != NULL) { - GList *l; + 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); - fprintf(fp, "<?xml version='1.0' encoding='UTF-8' ?>\n\n"); - fprintf(fp, "<pounces version='1.0'>\n"); + norm_pouncee = g_strdup(gaim_normalize(pouncer, pouncee)); - for (l = gaim_pounces_get_all(); l != NULL; l = l->next) - gaim_pounces_write(fp, l->data); - - fprintf(fp, "</pounces>\n"); + for (l = gaim_pounces_get_all(); l != NULL; l = l->next) + { + pounce = (GaimPounce *)l->data; - fclose(fp); - chmod(filename, S_IRUSR | S_IWUSR); - } - else { - gaim_debug(GAIM_DEBUG_ERROR, "pounces", "Unable to write %s\n", - filename); - g_free(filename); - return; + 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; } - if (stat(filename, &st) || (st.st_size == 0)) { - gaim_debug_error("pounces", "Failed to save pounces\n"); - unlink(filename); - g_free(filename); - return; - } + g_free(norm_pouncee); - filename_real = g_build_filename(user_dir, "pounces.xml", NULL); - - if (rename(filename, filename_real) < 0) { - gaim_debug(GAIM_DEBUG_ERROR, "pounces", "Error renaming %s to %s\n", - filename, filename_real); - } - - g_free(filename); - g_free(filename_real); + return pounce; } void @@ -987,9 +976,9 @@ void gaim_pounces_init(void) { + void *handle = gaim_pounces_get_handle(); void *blist_handle = gaim_blist_get_handle(); void *conv_handle = gaim_conversations_get_handle(); - void *handle = gaim_pounces_get_handle(); pounce_handlers = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, free_pounce_handler); @@ -1022,10 +1011,11 @@ void gaim_pounces_uninit() { - if (pounces_save_timer != 0) { - gaim_timeout_remove(pounces_save_timer); - pounces_save_timer = 0; - gaim_pounces_sync(); + if (save_timer != 0) + { + gaim_timeout_remove(save_timer); + save_timer = 0; + sync_pounces(); } gaim_signals_disconnect_by_handle(gaim_pounces_get_handle());