Mercurial > ~mikael > mcabber > hg
diff mcabber/src/histolog.c @ 1437:071c8170b7de
Add option 'statefile' to keep track of unread messages across restarts
(Suggested by micressor)
author | Mikael Berthe <mikael@lilotux.net> |
---|---|
date | Mon, 25 Feb 2008 20:27:56 +0100 |
parents | 6fb141142388 |
children | ec55cdf44335 |
line wrap: on
line diff
--- a/mcabber/src/histolog.c Sun Feb 24 17:46:13 2008 +0100 +++ b/mcabber/src/histolog.c Mon Feb 25 20:27:56 2008 +0100 @@ -26,14 +26,16 @@ #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> +#include <unistd.h> #include "histolog.h" #include "hbuf.h" #include "jabglue.h" #include "utils.h" -#include "logprint.h" +#include "screen.h" #include "settings.h" #include "utils.h" +#include "roster.h" static guint UseFileLogging; static guint FileLoadLogs; @@ -391,6 +393,11 @@ } } +guint hlog_is_enabled(void) +{ + return UseFileLogging; +} + inline void hlog_write_message(const char *bjid, time_t timestamp, int sent, const char *msg) { @@ -416,4 +423,115 @@ status_msg); } + +// hlog_save_state() +// If enabled, save the current state of the roster +// (i.e. pending messages) to a temporary file. +void hlog_save_state(void) +{ + gpointer unread_ptr, first_unread; + const char *bjid; + char *statefile_xp; + FILE *fp; + const char *statefile = settings_opt_get("statefile"); + + if (!statefile || !UseFileLogging) + return; + + statefile_xp = expand_filename(statefile); + fp = fopen(statefile_xp, "w"); + if (!fp) { + scr_LogPrint(LPRINT_NORMAL, "Cannot open state file [%s]", + strerror(errno)); + goto hlog_save_state_return; + } + + if (!jb_getonline()) { + // We're not connected. Let's use the unread_jids hash. + GList *unread_jid = unread_jid_get_list(); + unread_ptr = unread_jid; + for ( ; unread_jid ; unread_jid = g_list_next(unread_jid)) + fprintf(fp, "%s\n", (char*)unread_jid->data); + g_list_free(unread_ptr); + goto hlog_save_state_return; + } + + if (!current_buddy) // Safety check -- shouldn't happen. + goto hlog_save_state_return; + + // We're connected. Let's use unread_msg(). + unread_ptr = first_unread = unread_msg(NULL); + if (!first_unread) + goto hlog_save_state_return; + + do { + guint type = buddy_gettype(unread_ptr); + if (type & (ROSTER_TYPE_USER|ROSTER_TYPE_AGENT)) { + bjid = buddy_getjid(unread_ptr); + if (bjid) + fprintf(fp, "%s\n", bjid); + } + unread_ptr = unread_msg(unread_ptr); + } while (unread_ptr && unread_ptr != first_unread); + +hlog_save_state_return: + if (fp) { + long filelen = ftell(fp); + fclose(fp); + if (!filelen) + unlink(statefile_xp); + } + g_free(statefile_xp); +} + +// hlog_load_state() +// If enabled, load the current state of the roster +// (i.e. pending messages) from a temporary file. +// This function adds the JIDs to the unread_jids hash table, +// so it should only be called at startup. +void hlog_load_state(void) +{ + char bjid[1024]; + char *statefile_xp; + FILE *fp; + const char *statefile = settings_opt_get("statefile"); + + if (!statefile || !UseFileLogging) + return; + + statefile_xp = expand_filename(statefile); + fp = fopen(statefile_xp, "r"); + if (fp) { + char *eol; + while (!feof(fp)) { + if (fgets(bjid, sizeof bjid, fp) == NULL) + break; + // Let's remove the trailing newline. + // Also remove whitespace, if the file as been (badly) manually modified. + for (eol = bjid; *eol; eol++) ; + for (eol--; eol >= bjid && (*eol == '\n' || *eol == ' '); *eol-- = 0) ; + // Safety checks... + if (!bjid[0]) + continue; + if (check_jid_syntax(bjid)) { + scr_LogPrint(LPRINT_LOGNORM, + "ERROR: Invalid JID in state file. Corrupted file?"); + break; + } + // Display a warning if there are pending messages but the user + // won't see them because load_log isn't set. + if (!FileLoadLogs) { + scr_LogPrint(LPRINT_LOGNORM, "WARNING: unread message from <%s>.", + bjid); + scr_setmsgflag_if_needed(SPECIAL_BUFFER_STATUS_ID, TRUE); + } + // Add the JID to unread_jids. It will be used when the contact is + // added to the roster. + unread_jid_add(bjid); + } + fclose(fp); + } + g_free(statefile_xp); +} + /* vim: set expandtab cindent cinoptions=>2\:2(0: For Vim users... */