1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 * Authors: Jeffrey Stedfast <fejj@novell.com>
5 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
34 #include <sys/types.h>
37 #include <glib/gi18n-lib.h>
38 #include <glib/gstdio.h>
40 #include "camel-data-cache.h"
41 #include "camel-file-utils.h"
42 #include "camel-folder-summary.h"
43 #include "camel-folder.h"
44 #include "camel-offline-journal.h"
45 #include "camel-private.h"
49 static void camel_offline_journal_class_init (CamelOfflineJournalClass *klass);
50 static void camel_offline_journal_init (CamelOfflineJournal *journal, CamelOfflineJournalClass *klass);
51 static void camel_offline_journal_finalize (CamelObject *object);
53 static CamelObjectClass *parent_class = NULL;
56 camel_offline_journal_get_type (void)
58 static CamelType type = NULL;
61 type = camel_type_register (camel_object_get_type (),
62 "CamelOfflineJournal",
63 sizeof (CamelOfflineJournal),
64 sizeof (CamelOfflineJournalClass),
65 (CamelObjectClassInitFunc) camel_offline_journal_class_init,
67 (CamelObjectInitFunc) camel_offline_journal_init,
68 (CamelObjectFinalizeFunc) camel_offline_journal_finalize);
75 camel_offline_journal_class_init (CamelOfflineJournalClass *klass)
77 parent_class = camel_type_get_global_classfuncs (CAMEL_OBJECT_TYPE);
81 camel_offline_journal_init (CamelOfflineJournal *journal, CamelOfflineJournalClass *klass)
83 journal->folder = NULL;
84 journal->filename = NULL;
85 camel_dlist_init (&journal->queue);
89 camel_offline_journal_finalize (CamelObject *object)
91 CamelOfflineJournal *journal = (CamelOfflineJournal *) object;
92 CamelDListNode *entry;
94 g_free (journal->filename);
96 while ((entry = camel_dlist_remhead (&journal->queue)))
97 CAMEL_OFFLINE_JOURNAL_GET_CLASS (journal)->entry_free (journal, entry);
101 * camel_offline_journal_construct:
102 * @journal: a #CamelOfflineJournal object
103 * @folder: a #CamelFolder object
104 * @filename: a filename to save/load the journal
106 * Constructs a journal object.
109 camel_offline_journal_construct (CamelOfflineJournal *journal, CamelFolder *folder, const gchar *filename)
111 CamelDListNode *entry;
114 journal->filename = g_strdup (filename);
115 journal->folder = folder;
117 if ((fp = g_fopen (filename, "rb"))) {
118 while ((entry = CAMEL_OFFLINE_JOURNAL_GET_CLASS (journal)->entry_load (journal, fp)))
119 camel_dlist_addtail (&journal->queue, entry);
126 * camel_offline_journal_set_filename:
127 * @journal: a #CamelOfflineJournal object
128 * @filename: a filename to load/save the journal to
130 * Set the filename where the journal should load/save from.
133 camel_offline_journal_set_filename (CamelOfflineJournal *journal, const gchar *filename)
135 g_return_if_fail (CAMEL_IS_OFFLINE_JOURNAL (journal));
137 g_free (journal->filename);
138 journal->filename = g_strdup (filename);
142 * camel_offline_journal_write:
143 * @journal: a #CamelOfflineJournal object
144 * @ex: a #CamelException
146 * Save the journal to disk.
148 * Returns: %0 on success or %-1 on fail
151 camel_offline_journal_write (CamelOfflineJournal *journal, CamelException *ex)
153 CamelDListNode *entry;
157 if ((fd = g_open (journal->filename, O_CREAT | O_TRUNC | O_WRONLY | O_BINARY, 0666)) == -1) {
158 camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
159 _("Cannot write offline journal for folder '%s': %s"),
160 journal->folder->full_name, g_strerror (errno));
164 fp = fdopen (fd, "w");
165 entry = journal->queue.head;
166 while (entry->next) {
167 if (CAMEL_OFFLINE_JOURNAL_GET_CLASS (journal)->entry_write (journal, entry, fp) == -1)
172 if (fsync (fd) == -1)
181 camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
182 _("Cannot write offline journal for folder '%s': %s"),
183 journal->folder->full_name, g_strerror (errno));
191 * camel_offline_journal_replay:
192 * @journal: a #CamelOfflineJournal object
193 * @ex: a #CamelException
195 * Replay all entries in the journal.
197 * Returns: %0 on success (no entry failed to replay) or %-1 on fail
200 camel_offline_journal_replay (CamelOfflineJournal *journal, CamelException *ex)
202 CamelDListNode *entry, *next;
206 camel_exception_init (&lex);
208 entry = journal->queue.head;
209 while (entry->next) {
211 if (CAMEL_OFFLINE_JOURNAL_GET_CLASS (journal)->entry_play (journal, entry, &lex) == -1) {
213 camel_exception_xfer (ex, &lex);
214 camel_exception_clear (&lex);
217 camel_dlist_remove (entry);