2011-11-28 [pawel] 3.7.10cvs106
[claws.git] / src / addrbook.c
index 3b1dc2dddb0a1ab2bbe1db7e4cffa76eb6584d4c..4350bf2531a9fe14bd13652392b68cef882d21f0 100644 (file)
@@ -1,10 +1,10 @@
 /*
  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 2001-2007 Match Grun and the Claws Mail team
+ * Copyright (C) 2001-2011 Match Grun and the Claws Mail team
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * the Free Software Foundation; either version 3 of the License, or
  * (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful,
@@ -13,8 +13,8 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ * 
  */
 
 /* General functions for accessing address book files */
@@ -76,13 +76,13 @@ AddressBookFile *addrbook_create_book()
  */
 void addrbook_set_name(AddressBookFile *book, const gchar *value)
 {
-       g_return_if_fail(book != NULL);
+       cm_return_if_fail(book != NULL);
        addrcache_set_name(book->addressCache, value);
 }
 
 gchar *addrbook_get_name(AddressBookFile *book)
 {
-       g_return_val_if_fail(book != NULL, NULL);
+       cm_return_val_if_fail(book != NULL, NULL);
        return addrcache_get_name(book->addressCache);
 }
 
@@ -93,7 +93,7 @@ gchar *addrbook_get_name(AddressBookFile *book)
  */
 void addrbook_set_path(AddressBookFile *book, const gchar *value)
 {
-       g_return_if_fail(book != NULL);
+       cm_return_if_fail(book != NULL);
        book->path = mgu_replace_string(book->path, value);
        addrcache_set_dirty(book->addressCache, TRUE);
 }
@@ -105,20 +105,20 @@ void addrbook_set_path(AddressBookFile *book, const gchar *value)
  */
 void addrbook_set_file(AddressBookFile *book, const gchar *value)
 {
-       g_return_if_fail(book != NULL);
+       cm_return_if_fail(book != NULL);
        book->fileName = mgu_replace_string(book->fileName, value);
        addrcache_set_dirty(book->addressCache, TRUE);
 }
 
 gboolean addrbook_get_modified(AddressBookFile *book)
 {
-       g_return_val_if_fail(book != NULL, FALSE);
+       cm_return_val_if_fail(book != NULL, FALSE);
        return book->addressCache->modified;
 }
 
 gboolean addrbook_get_accessed(AddressBookFile *book)
 {
-       g_return_val_if_fail(book != NULL, FALSE);
+       cm_return_val_if_fail(book != NULL, FALSE);
        return book->addressCache->accessFlag;
 }
 
@@ -129,43 +129,43 @@ gboolean addrbook_get_accessed(AddressBookFile *book)
  */
 void addrbook_set_accessed(AddressBookFile *book, const gboolean value)
 {
-       g_return_if_fail(book != NULL);
+       cm_return_if_fail(book != NULL);
        book->addressCache->accessFlag = value;
 }
 
 gboolean addrbook_get_read_flag(AddressBookFile *book)
 {
-       g_return_val_if_fail(book != NULL, FALSE);
+       cm_return_val_if_fail(book != NULL, FALSE);
        return book->addressCache->dataRead;
 }
 
 gint addrbook_get_status(AddressBookFile *book)
 {
-       g_return_val_if_fail(book != NULL, -1);
+       cm_return_val_if_fail(book != NULL, -1);
        return book->retVal;
 }
 
 ItemFolder *addrbook_get_root_folder(AddressBookFile *book)
 {
-       g_return_val_if_fail(book != NULL, NULL);
+       cm_return_val_if_fail(book != NULL, NULL);
        return addrcache_get_root_folder(book->addressCache);
 }
 
 GList *addrbook_get_list_folder(AddressBookFile *book)
 {
-       g_return_val_if_fail(book != NULL, NULL);
+       cm_return_val_if_fail(book != NULL, NULL);
        return addrcache_get_list_folder(book->addressCache);
 }
 
 GList *addrbook_get_list_person(AddressBookFile *book)
 {
-       g_return_val_if_fail(book != NULL, NULL);
+       cm_return_val_if_fail(book != NULL, NULL);
        return addrcache_get_list_person(book->addressCache);
 }
 
 gboolean addrbook_get_dirty(AddressBookFile *book)
 {
-       g_return_val_if_fail(book != NULL, FALSE);
+       cm_return_val_if_fail(book != NULL, FALSE);
        return addrcache_get_dirty(book->addressCache);
 }
 
@@ -176,7 +176,7 @@ gboolean addrbook_get_dirty(AddressBookFile *book)
  */
 void addrbook_set_dirty(AddressBookFile *book, const gboolean value)
 {
-       g_return_if_fail(book != NULL);
+       cm_return_if_fail(book != NULL);
        addrcache_set_dirty(book->addressCache, value);
 }
 
@@ -186,7 +186,7 @@ void addrbook_set_dirty(AddressBookFile *book, const gboolean value)
  */
 void addrbook_free_book(AddressBookFile *book)
 {
-       g_return_if_fail(book != NULL);
+       cm_return_if_fail(book != NULL);
 
        /* Clear cache */
        addrcache_free(book->addressCache);
@@ -216,7 +216,7 @@ void addrbook_free_book(AddressBookFile *book)
  */
 static void addrbook_print_book(AddressBookFile *book, FILE *stream)
 {
-       g_return_if_fail(book != NULL);
+       cm_return_if_fail(book != NULL);
 
        fprintf(stream, "AddressBook:\n");
        fprintf(stream, "\tpath : '%s'\n", book->path);
@@ -234,7 +234,7 @@ void addrbook_dump_book(AddressBookFile *book, FILE *stream)
 {
        ItemFolder *folder;
 
-       g_return_if_fail(book != NULL);
+       cm_return_if_fail(book != NULL);
 
        addrbook_print_book(book, stream);
        folder = book->addressCache->rootFolder;
@@ -252,7 +252,7 @@ void addrbook_dump_book(AddressBookFile *book, FILE *stream)
  */
 ItemGroup *addrbook_remove_group(AddressBookFile *book, ItemGroup *group)
 {
-       g_return_val_if_fail(book != NULL, NULL);
+       cm_return_val_if_fail(book != NULL, NULL);
        return addrcache_remove_group(book->addressCache, group);
 }
 
@@ -265,7 +265,7 @@ ItemGroup *addrbook_remove_group(AddressBookFile *book, ItemGroup *group)
  */
 ItemPerson *addrbook_remove_person(AddressBookFile *book, ItemPerson *person)
 {
-       g_return_val_if_fail(book != NULL, NULL);
+       cm_return_val_if_fail(book != NULL, NULL);
        return addrcache_remove_person(book->addressCache, person);
 }
 
@@ -280,7 +280,7 @@ ItemPerson *addrbook_remove_person(AddressBookFile *book, ItemPerson *person)
 ItemEMail *addrbook_person_remove_email(AddressBookFile *book,
                                        ItemPerson *person, ItemEMail *email)
 {
-       g_return_val_if_fail(book != NULL, NULL);
+       cm_return_val_if_fail(book != NULL, NULL);
        return addrcache_person_remove_email(book->addressCache, person, email);
 }
 
@@ -500,8 +500,10 @@ static void addrbook_parse_person(AddressBookFile *book, XMLFile *file)
                value = ((XMLAttr *)attr->data)->value;
                if (!person) 
                        person = addritem_create_item_person();
-               if (strcmp(name, AB_ATTAG_UID) == 0)
+               if (strcmp(name, AB_ATTAG_UID) == 0) {
                        ADDRITEM_ID(person) = g_strdup(value);
+                       person->picture = g_strdup(value);
+               }
                else if (strcmp(name, AB_ATTAG_FIRST_NAME) == 0)
                        person->firstName = g_strdup(value);
                else if (strcmp(name, AB_ATTAG_LAST_NAME) == 0)
@@ -917,10 +919,10 @@ gint addrbook_read_data(AddressBookFile *book)
        XMLFile *file = NULL;
        gchar *fileSpec = NULL;
 
-       g_return_val_if_fail(book != NULL, -1);
+       cm_return_val_if_fail(book != NULL, -1);
 
        /*
-       printf( "...addrbook_read_data :%s:\t:%s:\n", book->fileName,
+       g_print( "...addrbook_read_data :%s:\t:%s:\n", book->fileName,
                addrcache_get_name( book->addressCache ) );
        */
 
@@ -957,13 +959,18 @@ gint addrbook_read_data(AddressBookFile *book)
  * \param lvl  Indent level.
  * \param name Element name.
  */
-static void addrbook_write_elem_s(FILE *fp, gint lvl, gchar *name)
+static int addrbook_write_elem_s(FILE *fp, gint lvl, gchar *name)
 {
        gint i;
        for (i = 0; i < lvl; i++) 
-               fputs("  ", fp);
-       fputs("<", fp);
-       fputs(name, fp);
+               if (fputs("  ", fp) == EOF)
+                       return -1;
+       if (fputs("<", fp) == EOF)
+               return -1;
+       if (fputs(name, fp) == EOF)
+               return -1;
+               
+       return 0;
 }
 
 /**
@@ -972,14 +979,20 @@ static void addrbook_write_elem_s(FILE *fp, gint lvl, gchar *name)
  * \param lvl  Indent level.
  * \param name Element name.
  */
-static void addrbook_write_elem_e(FILE *fp, gint lvl, gchar *name)
+static int addrbook_write_elem_e(FILE *fp, gint lvl, gchar *name)
 {
        gint i;
        for(i = 0; i < lvl; i++)
-               fputs("  ", fp);
-       fputs("</", fp);
-       fputs(name, fp);
-       fputs(">\n", fp);
+               if (fputs("  ", fp) == EOF)
+                       return -1;
+       if (fputs("</", fp) == EOF)
+               return -1;
+       if (fputs(name, fp) == EOF)
+               return -1;
+       if (fputs(">\n", fp) == EOF)
+               return -1;
+               
+       return 0;
 }
 
 /**
@@ -988,15 +1001,27 @@ static void addrbook_write_elem_e(FILE *fp, gint lvl, gchar *name)
  * \param name  Attribute name.
  * \param value Attribute value.
  */
-static void addrbook_write_attr(FILE *fp, gchar *name, gchar *value)
-{
-       fputs(" ", fp);
-       fputs(name, fp);
-       fputs("=\"", fp);
-       xml_file_put_escape_str(fp, value);
-       fputs("\"", fp);
+static int addrbook_write_attr(FILE *fp, gchar *name, gchar *value)
+{
+       if (fputs(" ", fp) == EOF)
+               return -1;
+       if (fputs(name, fp) == EOF)
+               return -1;
+       if (fputs("=\"", fp) == EOF)
+               return -1;
+       if (xml_file_put_escape_str(fp, value) < 0)
+               return -1;
+       if (fputs("\"", fp) == EOF)
+               return -1;
+       
+       return 0;
 }
 
+typedef struct _HashLoopData {
+       FILE *fp;
+       gboolean error;
+} HashLoopData;
+
 /**
  * Write person and associated addresses and attributes to file.
  * file hash table visitor function.
@@ -1005,10 +1030,11 @@ static void addrbook_write_attr(FILE *fp, gchar *name, gchar *value)
  * \param data  File pointer.
  */
 static void addrbook_write_item_person_vis(gpointer key, gpointer value, 
-                                          gpointer data)
+                                          gpointer d)
 {
        AddrItemObject *obj = (AddrItemObject *) value;
-       FILE *fp = (FILE *) data;
+       HashLoopData *data = (HashLoopData *)d;
+       FILE *fp = data->fp;
        GList *node;
 
        if (!obj)
@@ -1016,46 +1042,72 @@ static void addrbook_write_item_person_vis(gpointer key, gpointer value,
        if (ADDRITEM_TYPE(obj) == ITEMTYPE_PERSON) {
                ItemPerson *person = (ItemPerson *) value;
                if (person) {
-                       addrbook_write_elem_s(fp, 1, AB_ELTAG_PERSON);
-                       addrbook_write_attr(fp, AB_ATTAG_UID, ADDRITEM_ID(person));
-                       addrbook_write_attr(fp, AB_ATTAG_FIRST_NAME, person->firstName);
-                       addrbook_write_attr(fp, AB_ATTAG_LAST_NAME, person->lastName);
-                       addrbook_write_attr(fp, AB_ATTAG_NICK_NAME, person->nickName);
-                       addrbook_write_attr(fp, AB_ATTAG_COMMON_NAME, ADDRITEM_NAME(person));
-                       fputs(" >\n", fp);
+                       if (addrbook_write_elem_s(fp, 1, AB_ELTAG_PERSON) < 0)
+                               data->error = TRUE;
+                       if (addrbook_write_attr(fp, AB_ATTAG_UID, ADDRITEM_ID(person)) < 0)
+                               data->error = TRUE;
+                       if (addrbook_write_attr(fp, AB_ATTAG_FIRST_NAME, person->firstName) < 0)
+                               data->error = TRUE;
+                       if (addrbook_write_attr(fp, AB_ATTAG_LAST_NAME, person->lastName) < 0)
+                               data->error = TRUE;
+                       if (addrbook_write_attr(fp, AB_ATTAG_NICK_NAME, person->nickName) < 0)
+                               data->error = TRUE;
+                       if (addrbook_write_attr(fp, AB_ATTAG_COMMON_NAME, ADDRITEM_NAME(person)) < 0)
+                               data->error = TRUE;
+                       if (fputs(" >\n", fp) == EOF)
+                               data->error = TRUE;
 
                        /* Output email addresses */
-                       addrbook_write_elem_s(fp, 2, AB_ELTAG_ADDRESS_LIST);
-                       fputs(">\n", fp);
+                       if (addrbook_write_elem_s(fp, 2, AB_ELTAG_ADDRESS_LIST) < 0)
+                               data->error = TRUE;
+                       if (fputs(">\n", fp) == EOF)
+                               data->error = TRUE;
                        node = person->listEMail;
                        while (node) {
                                ItemEMail *email = node->data;
-                               addrbook_write_elem_s(fp, 3, AB_ELTAG_ADDRESS);
-                               addrbook_write_attr(fp, AB_ATTAG_UID, ADDRITEM_ID(email));
-                               addrbook_write_attr(fp, AB_ATTAG_ALIAS, ADDRITEM_NAME(email));
-                               addrbook_write_attr(fp, AB_ATTAG_EMAIL, email->address);
-                               addrbook_write_attr(fp, AB_ATTAG_REMARKS, email->remarks);
-                               fputs(" />\n", fp);
+                               if (addrbook_write_elem_s(fp, 3, AB_ELTAG_ADDRESS) < 0)
+                                       data->error = TRUE;
+                               if (addrbook_write_attr(fp, AB_ATTAG_UID, ADDRITEM_ID(email)) < 0)
+                                       data->error = TRUE;
+                               if (addrbook_write_attr(fp, AB_ATTAG_ALIAS, ADDRITEM_NAME(email)) < 0)
+                                       data->error = TRUE;
+                               if (addrbook_write_attr(fp, AB_ATTAG_EMAIL, email->address) < 0)
+                                       data->error = TRUE;
+                               if (addrbook_write_attr(fp, AB_ATTAG_REMARKS, email->remarks) < 0)
+                                       data->error = TRUE;
+                               if (fputs(" />\n", fp) == EOF)
+                                       data->error = TRUE;
                                node = g_list_next(node);
                        }
-                       addrbook_write_elem_e(fp, 2, AB_ELTAG_ADDRESS_LIST);
+                       if (addrbook_write_elem_e(fp, 2, AB_ELTAG_ADDRESS_LIST) < 0)
+                               data->error = TRUE;
 
                        /* Output user attributes */
-                       addrbook_write_elem_s(fp, 2, AB_ELTAG_ATTRIBUTE_LIST);
-                       fputs(">\n", fp);
+                       if (addrbook_write_elem_s(fp, 2, AB_ELTAG_ATTRIBUTE_LIST) < 0)
+                               data->error = TRUE;
+                       if (fputs(">\n", fp) == EOF)
+                               data->error = TRUE;
                        node = person->listAttrib;
                        while (node) {
                                UserAttribute *attrib = node->data;
-                               addrbook_write_elem_s(fp, 3, AB_ELTAG_ATTRIBUTE);
-                               addrbook_write_attr(fp, AB_ATTAG_UID, attrib->uid);
-                               addrbook_write_attr(fp, AB_ATTAG_NAME, attrib->name);
-                               fputs(" >", fp);
-                               xml_file_put_escape_str(fp, attrib->value);
-                               addrbook_write_elem_e(fp, 0, AB_ELTAG_ATTRIBUTE);
+                               if (addrbook_write_elem_s(fp, 3, AB_ELTAG_ATTRIBUTE) < 0)
+                                       data->error = TRUE;
+                               if (addrbook_write_attr(fp, AB_ATTAG_UID, attrib->uid) < 0)
+                                       data->error = TRUE;
+                               if (addrbook_write_attr(fp, AB_ATTAG_NAME, attrib->name) < 0)
+                                       data->error = TRUE;
+                               if (fputs(" >", fp) == EOF)
+                                       data->error = TRUE;
+                               if (xml_file_put_escape_str(fp, attrib->value) < 0)
+                                       data->error = TRUE;
+                               if (addrbook_write_elem_e(fp, 0, AB_ELTAG_ATTRIBUTE) < 0)
+                                       data->error = TRUE;
                                node = g_list_next(node);
                        }
-                       addrbook_write_elem_e(fp, 2, AB_ELTAG_ATTRIBUTE_LIST);
-                       addrbook_write_elem_e(fp, 1, AB_ELTAG_PERSON);
+                       if (addrbook_write_elem_e(fp, 2, AB_ELTAG_ATTRIBUTE_LIST) < 0)
+                               data->error = TRUE;
+                       if (addrbook_write_elem_e(fp, 1, AB_ELTAG_PERSON) < 0)
+                               data->error = TRUE;
                }
        }
 }
@@ -1068,10 +1120,12 @@ static void addrbook_write_item_person_vis(gpointer key, gpointer value,
  * \param data  File pointer.
  */
 static void addrbook_write_item_group_vis(gpointer key, gpointer value, 
-                                         gpointer data)
+                                         gpointer d)
 {
        AddrItemObject *obj = (AddrItemObject *) value;
-       FILE *fp = (FILE *) data;
+       HashLoopData *data = (HashLoopData *)d;
+       FILE *fp = data->fp;
+
        GList *node;
 
        if (!obj)
@@ -1079,27 +1133,40 @@ static void addrbook_write_item_group_vis(gpointer key, gpointer value,
        if (ADDRITEM_TYPE(obj) == ITEMTYPE_GROUP) {
                ItemGroup *group = (ItemGroup *) value;
                if (group) {
-                       addrbook_write_elem_s(fp, 1, AB_ELTAG_GROUP);
-                       addrbook_write_attr(fp, AB_ATTAG_UID, ADDRITEM_ID(group));
-                       addrbook_write_attr(fp, AB_ATTAG_NAME, ADDRITEM_NAME(group));
-                       addrbook_write_attr(fp, AB_ATTAG_REMARKS, group->remarks);
-                       fputs(" >\n", fp);
+                       if (addrbook_write_elem_s(fp, 1, AB_ELTAG_GROUP) < 0)
+                               data->error = TRUE;
+                       if (addrbook_write_attr(fp, AB_ATTAG_UID, ADDRITEM_ID(group)) < 0)
+                               data->error = TRUE;
+                       if (addrbook_write_attr(fp, AB_ATTAG_NAME, ADDRITEM_NAME(group)) < 0)
+                               data->error = TRUE;
+                       if (addrbook_write_attr(fp, AB_ATTAG_REMARKS, group->remarks) < 0)
+                               data->error = TRUE;
+                       if (fputs(" >\n", fp) == EOF)
+                               data->error = TRUE;
 
                        /* Output email address links */
-                       addrbook_write_elem_s(fp, 2, AB_ELTAG_MEMBER_LIST);
-                       fputs(">\n", fp);
+                       if (addrbook_write_elem_s(fp, 2, AB_ELTAG_MEMBER_LIST) < 0)
+                               data->error = TRUE;
+                       if (fputs(">\n", fp) == EOF)
+                               data->error = TRUE;
                        node = group->listEMail;
                        while (node) {
                                ItemEMail *email = node->data;
                                ItemPerson *person = (ItemPerson *) ADDRITEM_PARENT(email);
-                               addrbook_write_elem_s(fp, 3, AB_ELTAG_MEMBER);
-                               addrbook_write_attr(fp, AB_ATTAG_PID, ADDRITEM_ID(person));
-                               addrbook_write_attr(fp, AB_ATTAG_EID, ADDRITEM_ID(email));
-                               fputs(" />\n", fp);
+                               if (addrbook_write_elem_s(fp, 3, AB_ELTAG_MEMBER) < 0)
+                                       data->error = TRUE;
+                               if (addrbook_write_attr(fp, AB_ATTAG_PID, ADDRITEM_ID(person)) < 0)
+                                       data->error = TRUE;
+                               if (addrbook_write_attr(fp, AB_ATTAG_EID, ADDRITEM_ID(email)) < 0)
+                                       data->error = TRUE;
+                               if (fputs(" />\n", fp) == EOF)
+                                       data->error = TRUE;
                                node = g_list_next(node);
                        }
-                       addrbook_write_elem_e(fp, 2, AB_ELTAG_MEMBER_LIST);
-                       addrbook_write_elem_e(fp, 1, AB_ELTAG_GROUP);
+                       if (addrbook_write_elem_e(fp, 2, AB_ELTAG_MEMBER_LIST) < 0)
+                               data->error = TRUE;
+                       if (addrbook_write_elem_e(fp, 1, AB_ELTAG_GROUP) < 0)
+                               data->error = TRUE;
                }
        }
 }
@@ -1112,10 +1179,11 @@ static void addrbook_write_item_group_vis(gpointer key, gpointer value,
  * \param data  File pointer.
  */
 static void addrbook_write_item_folder_vis(gpointer key, gpointer value, 
-                                          gpointer data)
+                                          gpointer d)
 {
        AddrItemObject *obj = (AddrItemObject *) value;
-       FILE *fp = (FILE *) data;
+       HashLoopData *data = (HashLoopData *)d;
+       FILE *fp = data->fp;
        GList *node;
 
        if (!obj)
@@ -1123,22 +1191,33 @@ static void addrbook_write_item_folder_vis(gpointer key, gpointer value,
        if (ADDRITEM_TYPE(obj) == ITEMTYPE_FOLDER) {
                ItemFolder *folder = (ItemFolder *) value;
                if (folder) {
-                       addrbook_write_elem_s(fp, 1, AB_ELTAG_FOLDER);
-                       addrbook_write_attr(fp, AB_ATTAG_UID, ADDRITEM_ID(folder));
-                       addrbook_write_attr(fp, AB_ATTAG_NAME, ADDRITEM_NAME(folder));
-                       addrbook_write_attr(fp, AB_ATTAG_REMARKS, folder->remarks);
-                       fputs(" >\n", fp);
-                       addrbook_write_elem_s(fp, 2, AB_ELTAG_ITEM_LIST);
-                       fputs(">\n", fp);
+                       if (addrbook_write_elem_s(fp, 1, AB_ELTAG_FOLDER) < 0)
+                               data->error = TRUE;
+                       if (addrbook_write_attr(fp, AB_ATTAG_UID, ADDRITEM_ID(folder)) < 0)
+                               data->error = TRUE;
+                       if (addrbook_write_attr(fp, AB_ATTAG_NAME, ADDRITEM_NAME(folder)) < 0)
+                               data->error = TRUE;
+                       if (addrbook_write_attr(fp, AB_ATTAG_REMARKS, folder->remarks) < 0)
+                               data->error = TRUE;
+                       if (fputs(" >\n", fp) == EOF)
+                               data->error = TRUE;
+                       if (addrbook_write_elem_s(fp, 2, AB_ELTAG_ITEM_LIST) < 0)
+                               data->error = TRUE;
+                       if (fputs(">\n", fp) == EOF)
+                               data->error = TRUE;
 
                        /* Output persons */
                        node = folder->listPerson;
                        while (node) {
                                ItemPerson *item = node->data;
-                               addrbook_write_elem_s(fp, 3, AB_ELTAG_ITEM);
-                               addrbook_write_attr(fp, AB_ATTAG_TYPE,  AB_ATTAG_VAL_PERSON);
-                               addrbook_write_attr(fp, AB_ATTAG_UID, ADDRITEM_ID(item));
-                               fputs(" />\n", fp);
+                               if (addrbook_write_elem_s(fp, 3, AB_ELTAG_ITEM) < 0)
+                                       data->error = TRUE;
+                               if (addrbook_write_attr(fp, AB_ATTAG_TYPE,  AB_ATTAG_VAL_PERSON) < 0)
+                                       data->error = TRUE;
+                               if (addrbook_write_attr(fp, AB_ATTAG_UID, ADDRITEM_ID(item)) < 0)
+                                       data->error = TRUE;
+                               if (fputs(" />\n", fp) == EOF)
+                                       data->error = TRUE;
                                node = g_list_next(node);
                        }
 
@@ -1146,10 +1225,14 @@ static void addrbook_write_item_folder_vis(gpointer key, gpointer value,
                        node = folder->listGroup;
                        while (node) {
                                ItemGroup *item = node->data;
-                               addrbook_write_elem_s(fp, 3, AB_ELTAG_ITEM);
-                               addrbook_write_attr(fp, AB_ATTAG_TYPE, AB_ATTAG_VAL_GROUP);
-                               addrbook_write_attr(fp, AB_ATTAG_UID, ADDRITEM_ID(item));
-                               fputs(" />\n", fp);
+                               if (addrbook_write_elem_s(fp, 3, AB_ELTAG_ITEM) < 0)
+                                       data->error = TRUE;
+                               if (addrbook_write_attr(fp, AB_ATTAG_TYPE, AB_ATTAG_VAL_GROUP) < 0)
+                                       data->error = TRUE;
+                               if (addrbook_write_attr(fp, AB_ATTAG_UID, ADDRITEM_ID(item)) < 0)
+                                       data->error = TRUE;
+                               if (fputs(" />\n", fp) == EOF)
+                                       data->error = TRUE;
                                node = g_list_next(node);
                        }
 
@@ -1157,14 +1240,20 @@ static void addrbook_write_item_folder_vis(gpointer key, gpointer value,
                        node = folder->listFolder;
                        while (node) {
                                ItemFolder *item = node->data;
-                               addrbook_write_elem_s(fp, 3, AB_ELTAG_ITEM);
-                               addrbook_write_attr(fp, AB_ATTAG_TYPE, AB_ATTAG_VAL_FOLDER);
-                               addrbook_write_attr(fp, AB_ATTAG_UID, ADDRITEM_ID(item));
-                               fputs(" />\n", fp);
+                               if (addrbook_write_elem_s(fp, 3, AB_ELTAG_ITEM) < 0)
+                                       data->error = TRUE;
+                               if (addrbook_write_attr(fp, AB_ATTAG_TYPE, AB_ATTAG_VAL_FOLDER) < 0)
+                                       data->error = TRUE;
+                               if (addrbook_write_attr(fp, AB_ATTAG_UID, ADDRITEM_ID(item)) < 0)
+                                       data->error = TRUE;
+                               if (fputs(" />\n", fp) == EOF)
+                                       data->error = TRUE;
                                node = g_list_next(node);
                        }
-                       addrbook_write_elem_e(fp, 2, AB_ELTAG_ITEM_LIST);
-                       addrbook_write_elem_e(fp, 1, AB_ELTAG_FOLDER);
+                       if (addrbook_write_elem_e(fp, 2, AB_ELTAG_ITEM_LIST) < 0)
+                               data->error = TRUE;
+                       if (addrbook_write_elem_e(fp, 1, AB_ELTAG_FOLDER) < 0)
+                               data->error = TRUE;
                }
        }
 }
@@ -1179,12 +1268,13 @@ static gint addrbook_write_to(AddressBookFile *book, gchar *newFile)
 {
        FILE *fp;
        gchar *fileSpec;
+       HashLoopData data;
 #ifndef DEV_STANDALONE
        PrefFile *pfile;
 #endif
 
-       g_return_val_if_fail(book != NULL, -1);
-       g_return_val_if_fail(newFile != NULL, -1);
+       cm_return_val_if_fail(book != NULL, -1);
+       cm_return_val_if_fail(newFile != NULL, -1);
 
        fileSpec = g_strconcat(book->path, G_DIR_SEPARATOR_S, newFile, NULL);
 
@@ -1193,32 +1283,52 @@ static gint addrbook_write_to(AddressBookFile *book, gchar *newFile)
        fp = g_fopen(fileSpec, "wb");
        g_free(fileSpec);
        if (fp) {
-               fputs("<?xml version=\"1.0\" ?>\n", fp);
+               if (fputs("<?xml version=\"1.0\" ?>\n", fp) == EOF) {
+                       book->retVal = MGU_ERROR_WRITE;
+                       return book->retVal;
+               }
 #else
        pfile = prefs_write_open(fileSpec);
        g_free(fileSpec);
        if (pfile) {
                fp = pfile->fp;
-               fprintf( fp, "<?xml version=\"1.0\" encoding=\"%s\" ?>\n", CS_INTERNAL );
+               if (fprintf( fp, "<?xml version=\"1.0\" encoding=\"%s\" ?>\n", CS_INTERNAL ) < 0)
+                       goto fail;
 #endif
-               addrbook_write_elem_s(fp, 0, AB_ELTAG_ADDRESS_BOOK);
-               addrbook_write_attr(fp, AB_ATTAG_NAME,
-                                   addrcache_get_name(book->addressCache));
-               fputs(" >\n", fp);
+               if (addrbook_write_elem_s(fp, 0, AB_ELTAG_ADDRESS_BOOK) < 0)
+                       goto fail;
+               if (addrbook_write_attr(fp, AB_ATTAG_NAME,
+                                   addrcache_get_name(book->addressCache)) < 0)
+                       goto fail;
+               if (fputs(" >\n", fp) == EOF)
+                       goto fail;
 
                /* Output all persons */
+               data.fp = fp;
+               data.error = FALSE;
+
                g_hash_table_foreach(book->addressCache->itemHash, 
-                                    addrbook_write_item_person_vis, fp);
+                                    addrbook_write_item_person_vis, &data);
+               if (data.error)
+                       goto fail;
 
                /* Output all groups */
                g_hash_table_foreach(book->addressCache->itemHash, 
-                                    addrbook_write_item_group_vis, fp);
+                                    addrbook_write_item_group_vis, &data);
+
+               if (data.error)
+                       goto fail;
 
                /* Output all folders */
                g_hash_table_foreach(book->addressCache->itemHash, 
-                                    addrbook_write_item_folder_vis, fp);
+                                    addrbook_write_item_folder_vis, &data);
+
+               if (data.error)
+                       goto fail;
+
+               if (addrbook_write_elem_e(fp, 0, AB_ELTAG_ADDRESS_BOOK) < 0)
+                       goto fail;
 
-               addrbook_write_elem_e(fp, 0, AB_ELTAG_ADDRESS_BOOK);
                book->retVal = MGU_SUCCESS;
 #ifdef DEV_STANDALONE
                fclose(fp);
@@ -1230,6 +1340,12 @@ static gint addrbook_write_to(AddressBookFile *book, gchar *newFile)
 
        fileSpec = NULL;
        return book->retVal;
+fail:
+       g_warning("error writing AB\n");
+       book->retVal = MGU_ERROR_WRITE;
+       if (pfile)
+               prefs_file_close_revert( pfile );
+       return book->retVal;
 }
 
 /**
@@ -1239,7 +1355,7 @@ static gint addrbook_write_to(AddressBookFile *book, gchar *newFile)
  */
 gint addrbook_save_data(AddressBookFile *book)
 {
-       g_return_val_if_fail(book != NULL, -1);
+       cm_return_val_if_fail(book != NULL, -1);
 
        book->retVal = MGU_NO_FILE;
        if (book->fileName == NULL || *book->fileName == '\0') 
@@ -1291,8 +1407,8 @@ void addrbook_update_address_list(AddressBookFile *book, ItemPerson *person,
        GList *listDelete;
        GList *listGroup;
 
-       g_return_if_fail(book != NULL);
-       g_return_if_fail(person != NULL);
+       cm_return_if_fail(book != NULL);
+       cm_return_if_fail(person != NULL);
 
        /* Get groups where person's existing email addresses are listed */
        listGroup = addrcache_get_group_for_person(book->addressCache, person);
@@ -1307,9 +1423,8 @@ void addrbook_update_address_list(AddressBookFile *book, ItemPerson *person,
                node = listEMail;
                while (node) {
                        ItemEMail *email = node->data;
-                       gchar *addr = g_strdup(email->address);
                        gchar *alias = email->obj.name ;
-                       g_strdown(addr);
+                       gchar *addr = g_utf8_strdown(email->address, -1);
                        if (!g_hash_table_lookup(hashEMail, addr)) {
                                g_hash_table_insert(hashEMail, addr, email);
                        }
@@ -1336,9 +1451,8 @@ void addrbook_update_address_list(AddressBookFile *book, ItemPerson *person,
                                if (ADDRITEM_PARENT(emailGrp) == ADDRITEM_OBJECT(person)) {
                                        /* Found an email address for this person */
                                        ItemEMail *emailNew = NULL;
-                                       gchar *addr = g_strdup(emailGrp->address);
                                        gchar *alias = emailGrp->obj.name;
-                                       g_strdown(addr);
+                                       gchar *addr = g_utf8_strdown(emailGrp->address, -1);
                                        emailNew = (ItemEMail *)
                                                g_hash_table_lookup(hashEMail, addr);
                                        g_free( addr );
@@ -1448,7 +1562,7 @@ ItemPerson *addrbook_add_address_list(AddressBookFile *book, ItemFolder *folder,
        ItemFolder *f = folder;
        GList *node;
 
-       g_return_val_if_fail(book != NULL, NULL);
+       cm_return_val_if_fail(book != NULL, NULL);
 
        if (!f) 
                f = book->addressCache->rootFolder;
@@ -1512,7 +1626,7 @@ GList *addrbook_get_available_email_list(AddressBookFile *book, ItemGroup *group
        GList *list = NULL;
        GHashTable *table;
 
-       g_return_val_if_fail(book != NULL, NULL);
+       cm_return_val_if_fail(book != NULL, NULL);
 
        /* Load hash table with group email entries */
        table = g_hash_table_new(g_str_hash, g_str_equal);
@@ -1557,8 +1671,8 @@ void addrbook_update_group_list(AddressBookFile *book, ItemGroup *group,
 {
        GList *oldData;
 
-       g_return_if_fail(book != NULL);
-       g_return_if_fail(group != NULL);
+       cm_return_if_fail(book != NULL);
+       cm_return_if_fail(group != NULL);
 
        addrcache_set_dirty(book->addressCache, TRUE);
 
@@ -1588,7 +1702,7 @@ ItemGroup *addrbook_add_group_list(AddressBookFile *book, ItemFolder *folder,
        ItemGroup *group = NULL;
        ItemFolder *f = folder;
 
-       g_return_val_if_fail(book != NULL, NULL);
+       cm_return_val_if_fail(book != NULL, NULL);
 
        if (!f)
                f = book->addressCache->rootFolder;
@@ -1609,7 +1723,7 @@ ItemGroup *addrbook_add_group_list(AddressBookFile *book, ItemFolder *folder,
  */
 ItemFolder *addrbook_add_new_folder(AddressBookFile *book, ItemFolder *parent)
 {
-       g_return_val_if_fail(book != NULL, NULL);
+       cm_return_val_if_fail(book != NULL, NULL);
        return addrcache_add_new_folder( book->addressCache, parent );
 }
 
@@ -1628,8 +1742,8 @@ void addrbook_update_attrib_list(AddressBookFile *book, ItemPerson *person,
        GList *node;
        GList *oldData;
 
-       g_return_if_fail(book != NULL);
-       g_return_if_fail(person != NULL);
+       cm_return_if_fail(book != NULL);
+       cm_return_if_fail(person != NULL);
 
        /* Remember old list */
        oldData = person->listAttrib;
@@ -1662,8 +1776,8 @@ void addrbook_update_attrib_list(AddressBookFile *book, ItemPerson *person,
 void addrbook_add_attrib_list( AddressBookFile *book, ItemPerson *person, GList *listAttrib ) {
        GList *node;
 
-       g_return_if_fail( book != NULL );
-       g_return_if_fail( person != NULL );
+       cm_return_if_fail( book != NULL );
+       cm_return_if_fail( person != NULL );
 
        node = listAttrib;
        while( node ) {
@@ -1696,14 +1810,14 @@ GList *addrbook_get_bookfile_list(AddressBookFile *book) {
        long int val, maxval;
        GList *fileList = NULL;
 
-       g_return_val_if_fail(book != NULL, NULL);
+       cm_return_val_if_fail(book != NULL, NULL);
 
        if (book->path == NULL || *book->path == '\0') {
                book->retVal = MGU_NO_PATH;
                return NULL;
        }
 
-       strcpy(buf, book->path);
+       strncpy(buf, book->path, WORK_BUFLEN);
        len = strlen(buf);
        if (len > 0) {
                if (buf[len-1] != G_DIR_SEPARATOR) {
@@ -1713,7 +1827,7 @@ GList *addrbook_get_bookfile_list(AddressBookFile *book) {
        }
 
        adbookdir = g_strdup(buf);
-       strcat(buf, ADDRBOOK_PREFIX);
+       strncat(buf, ADDRBOOK_PREFIX, WORK_BUFLEN);
 
        if( ( dir = g_dir_open( adbookdir, 0, NULL ) ) == NULL ) {
                book->retVal = MGU_OPEN_DIRECTORY;
@@ -1731,9 +1845,9 @@ GList *addrbook_get_bookfile_list(AddressBookFile *book) {
                gint i;
                gboolean flg;
 
-               strcpy(buf, adbookdir);
-               strcat( buf, dir_name );
-               stat(buf, &statbuf);
+               strncpy(buf, adbookdir, WORK_BUFLEN);
+               strncat(buf, dir_name, WORK_BUFLEN);
+               g_stat(buf, &statbuf);
                if (S_ISREG(statbuf.st_mode)) {
                        if (strncmp(
                                dir_name,
@@ -1839,7 +1953,7 @@ static void addrbook_chkparse_attribute(AddressBookFile *book, XMLFile *file)
        attr = xml_get_current_tag_attr(file);
        /* addrbook_show_attribs( attr ); */
        element = xml_get_element(file);
-       /* printf( "\t\tattrib value : %s\n", element ); */
+       /* g_print( "\t\tattrib value : %s\n", element ); */
 }
 
 /**
@@ -2036,7 +2150,7 @@ gint addrbook_test_read_file(AddressBookFile *book, gchar *fileName)
        XMLFile *file = NULL;
        gchar *fileSpec = NULL;
 
-       g_return_val_if_fail(book != NULL, -1);
+       cm_return_val_if_fail(book != NULL, -1);
 
        fileSpec = g_strconcat(book->path, G_DIR_SEPARATOR_S, fileName, NULL);
        book->retVal = MGU_OPEN_FILE;
@@ -2045,7 +2159,7 @@ gint addrbook_test_read_file(AddressBookFile *book, gchar *fileName)
        if (file) {
                book->retVal = MGU_BAD_FORMAT;
                if (setjmp(book->jumper)) {
-                       /* printf( "Caught Ya!!!\n" ); */
+                       /* g_print( "Caught Ya!!!\n" ); */
                        xml_close_file(file);
                        return book->retVal;
                }
@@ -2067,13 +2181,13 @@ gint addrbook_test_read_file(AddressBookFile *book, gchar *fileName)
  */
 GList *addrbook_get_all_persons(AddressBookFile *book)
 {
-       g_return_val_if_fail(book != NULL, NULL);
+       cm_return_val_if_fail(book != NULL, NULL);
        return addrcache_get_all_persons(book->addressCache);
 }
 
 GList *addrbook_get_all_groups(AddressBookFile *book)
 {
-       g_return_val_if_fail(book != NULL, NULL);
+       cm_return_val_if_fail(book != NULL, NULL);
        return addrcache_get_all_groups(book->addressCache);
 }
 
@@ -2094,7 +2208,7 @@ ItemPerson *addrbook_add_contact(AddressBookFile *book, ItemFolder *folder,
 {
        ItemPerson *person;
 
-       g_return_val_if_fail(book != NULL, NULL);
+       cm_return_val_if_fail(book != NULL, NULL);
        person = addrcache_add_contact(
                        book->addressCache, folder, name, address, remarks );
        return person;
@@ -2121,6 +2235,19 @@ gchar *addrbook_guess_next_file(AddressBookFile *book)
        return newFile;
 }
 
+void addrbook_delete_book_file(AddressBookFile *book)
+{
+       gchar *book_path;
+       
+       if (!book->path || !book->fileName)
+               return;
+       
+       book_path = g_strconcat(book->path, G_DIR_SEPARATOR_S,
+                               book->fileName, NULL);
+       claws_unlink(book_path);
+       g_free(book_path);
+}
+
 /*
 * End of Source.
 */