From 2d16792fd5607dd55863044d8afc352f3ff8f24a Mon Sep 17 00:00:00 2001 From: Chris Toshok Date: Thu, 11 Jul 2002 00:01:25 +0000 Subject: actually remove the items from the pointer array too, so an error while 2002-07-10 Chris Toshok * backend/pas/pas-backend-summary.c (clear_items): actually remove the items from the pointer array too, so an error while loading doesn't leave the memory summary corrupted. (pas_backend_summary_load_header): bleah, load the num_items and summary_mtime in the right order :) Also, set upgraded to TRUE if we loaded a v1.0 summary. (pas_backend_summary_open): make this return a gboolean, return TRUE if the summary is already open (priv->fp != NULL). return FALSE in error conditions. (pas_backend_summary_load): if summary_open returns FALSE, return FALSE, also set the dirty flag to FALSE after we load, and if the summary was upgraded write it out. (pas_backend_summary_save): update the in memory mtime to that of the file when we save. (summary_flush_func): if we're not dirty, do nothing and return. (pas_backend_summary_is_up_to_date): make sure we've opened the summary. (pas_backend_summary_get_summary_vcard): fix compiler warning. svn path=/trunk/; revision=17416 --- addressbook/backend/pas/pas-backend-summary.c | 64 ++++++++++++++++++++------- 1 file changed, 47 insertions(+), 17 deletions(-) (limited to 'addressbook/backend') diff --git a/addressbook/backend/pas/pas-backend-summary.c b/addressbook/backend/pas/pas-backend-summary.c index 23a24c879e..18e56f61a6 100644 --- a/addressbook/backend/pas/pas-backend-summary.c +++ b/addressbook/backend/pas/pas-backend-summary.c @@ -43,6 +43,7 @@ struct _PASBackendSummaryPrivate { FILE *fp; guint32 file_version; time_t mtime; + gboolean upgraded; gboolean dirty; int flush_timeout_millis; int flush_timeout; @@ -109,8 +110,9 @@ static void clear_items (PASBackendSummary *summary) { int i; - for (i = 0; i < summary->priv->items->len; i++) { - PASBackendSummaryItem *item = g_ptr_array_index (summary->priv->items, i); + int num = summary->priv->items->len; + for (i = 0; i < num; i++) { + PASBackendSummaryItem *item = g_ptr_array_remove_index_fast (summary->priv->items, 0); g_hash_table_remove (summary->priv->id_to_item, item->id); free_summary_item (item); } @@ -244,6 +246,12 @@ pas_backend_summary_load_header (PASBackendSummary *summary, FILE *fp, header->file_version = ntohl (header->file_version); + rv = fread (&header->num_items, sizeof (header->num_items), 1, fp); + if (rv != 1) + return FALSE; + + header->num_items = ntohl (header->num_items); + if (header->file_version == PAS_SUMMARY_FILE_VERSION) { rv = fread (&header->summary_mtime, sizeof (header->summary_mtime), 1, fp); if (rv != 1) @@ -265,6 +273,7 @@ pas_backend_summary_load_header (PASBackendSummary *summary, FILE *fp, header->summary_mtime = 0; } header->summary_mtime = sb.st_mtime; + summary->priv->upgraded = TRUE; } else { /* unknown version */ @@ -272,12 +281,6 @@ pas_backend_summary_load_header (PASBackendSummary *summary, FILE *fp, } } - rv = fread (&header->num_items, sizeof (header->num_items), 1, fp); - if (rv != 1) - return FALSE; - - header->num_items = ntohl (header->num_items); - return TRUE; } @@ -411,13 +414,16 @@ pas_backend_summary_load_item (PASBackendSummary *summary, } /* opens the file and loads the header */ -static void +static gboolean pas_backend_summary_open (PASBackendSummary *summary) { FILE *fp; PASBackendSummaryHeader header; struct stat sb; + if (summary->priv->fp) + return TRUE; + if (stat (summary->priv->summary_path, &sb) == -1) { /* if there's no summary present, look for the .new file and rename it if it's there, and attempt to @@ -426,7 +432,7 @@ pas_backend_summary_open (PASBackendSummary *summary) if (stat (new_filename, &sb) == -1) { g_warning ("no summary present"); g_free (new_filename); - return; + return FALSE; } else { rename (new_filename, summary->priv->summary_path); @@ -437,25 +443,27 @@ pas_backend_summary_open (PASBackendSummary *summary) fp = fopen (summary->priv->summary_path, "r"); if (!fp) { g_warning ("failed to open summary file"); - return; + return FALSE; } if (!pas_backend_summary_check_magic (summary, fp)) { g_warning ("file is not a valid summary file"); fclose (fp); - return; + return FALSE; } if (!pas_backend_summary_load_header (summary, fp, &header)) { g_warning ("failed to read summary header"); fclose (fp); - return; + return FALSE; } summary->priv->num_items = header.num_items; summary->priv->file_version = header.file_version; summary->priv->mtime = header.summary_mtime; summary->priv->fp = fp; + + return TRUE; } gboolean @@ -464,9 +472,7 @@ pas_backend_summary_load (PASBackendSummary *summary) PASBackendSummaryItem *new_item; int i; - pas_backend_summary_open (summary); - - if (!summary->priv->fp) + if (!pas_backend_summary_open (summary)) return FALSE; for (i = 0; i < summary->priv->num_items; i ++) { @@ -475,6 +481,7 @@ pas_backend_summary_load (PASBackendSummary *summary) clear_items (summary); fclose (summary->priv->fp); summary->priv->fp = NULL; + summary->priv->dirty = FALSE; return FALSE; } @@ -482,6 +489,11 @@ pas_backend_summary_load (PASBackendSummary *summary) g_hash_table_insert (summary->priv->id_to_item, new_item->id, new_item); } + if (summary->priv->upgraded) { + pas_backend_summary_save (summary); + } + summary->priv->dirty = FALSE; + return TRUE; } @@ -583,6 +595,7 @@ pas_backend_summary_save_item (PASBackendSummary *summary, FILE *fp, PASBackendS gboolean pas_backend_summary_save (PASBackendSummary *summary) { + struct stat sb; FILE *fp = NULL; char *new_filename = NULL; int i; @@ -630,6 +643,14 @@ pas_backend_summary_save (PASBackendSummary *summary) g_free (new_filename); + /* lastly, update the in memory mtime to that of the file */ + if (stat (summary->priv->summary_path, &sb) == -1) { + g_warning ("error stat'ing saved summary"); + } + else { + summary->priv->mtime = sb.st_mtime; + } + return TRUE; lose: @@ -703,6 +724,11 @@ summary_flush_func (gpointer data) { PASBackendSummary *summary = PAS_BACKEND_SUMMARY (data); + if (!summary->priv->dirty) { + summary->priv->flush_timeout = 0; + return FALSE; + } + if (!pas_backend_summary_save (summary)) { /* this isn't fatal, as we can just either 1) flush out with the next change, or 2) regen the summary @@ -732,7 +758,10 @@ pas_backend_summary_touch (PASBackendSummary *summary) gboolean pas_backend_summary_is_up_to_date (PASBackendSummary *summary, time_t t) { - return summary->priv->mtime >= t; + if (!pas_backend_summary_open (summary)) + return FALSE; + else + return summary->priv->mtime >= t; } @@ -1019,6 +1048,7 @@ pas_backend_summary_get_summary_vcard(PASBackendSummary *summary, const char *id } else { g_warning ("in unable to locate card `%s' in summary", id); + return NULL; } } -- cgit