r18593 - gnucash/trunk/src - Bug #105669: Add checks to detect errors on write, especially if there no space left on the disk.
Andreas Köhler
andi5 at code.gnucash.org
Sun Jan 31 13:37:28 EST 2010
Author: andi5
Date: 2010-01-31 13:37:28 -0500 (Sun, 31 Jan 2010)
New Revision: 18593
Trac: http://svn.gnucash.org/trac/changeset/18593
Modified:
gnucash/trunk/src/backend/xml/gnc-backend-xml.c
gnucash/trunk/src/backend/xml/gnc-book-xml-v2.c
gnucash/trunk/src/backend/xml/io-gncxml-v2.c
gnucash/trunk/src/backend/xml/io-gncxml-v2.h
gnucash/trunk/src/backend/xml/io-utils.c
gnucash/trunk/src/backend/xml/io-utils.h
gnucash/trunk/src/business/business-core/xml/gnc-address-xml-v2.c
gnucash/trunk/src/business/business-core/xml/gnc-bill-term-xml-v2.c
gnucash/trunk/src/business/business-core/xml/gnc-customer-xml-v2.c
gnucash/trunk/src/business/business-core/xml/gnc-employee-xml-v2.c
gnucash/trunk/src/business/business-core/xml/gnc-entry-xml-v2.c
gnucash/trunk/src/business/business-core/xml/gnc-invoice-xml-v2.c
gnucash/trunk/src/business/business-core/xml/gnc-job-xml-v2.c
gnucash/trunk/src/business/business-core/xml/gnc-order-xml-v2.c
gnucash/trunk/src/business/business-core/xml/gnc-owner-xml-v2.c
gnucash/trunk/src/business/business-core/xml/gnc-tax-table-xml-v2.c
gnucash/trunk/src/business/business-core/xml/gnc-vendor-xml-v2.c
Log:
Bug #105669: Add checks to detect errors on write, especially if there no space left on the disk.
Check the return value of fprintf and use ferror where libraries as
libxml do the write.
The change may not be perfect yet and a review would be nice. Still, it
detects quite a few errors that, without it, slip through and may
destroy valuable data.
Modified: gnucash/trunk/src/backend/xml/gnc-backend-xml.c
===================================================================
--- gnucash/trunk/src/backend/xml/gnc-backend-xml.c 2010-01-31 11:22:24 UTC (rev 18592)
+++ gnucash/trunk/src/backend/xml/gnc-backend-xml.c 2010-01-31 18:37:28 UTC (rev 18593)
@@ -715,6 +715,9 @@
tmp_name ? tmp_name : "(null)",
strerror(errno) ? strerror(errno) : "");
/* already in an error just flow on through */
+ } else {
+ /* Use a generic write error code */
+ qof_backend_set_error(be, ERR_FILEIO_WRITE_ERROR);
}
g_free(tmp_name);
LEAVE("");
Modified: gnucash/trunk/src/backend/xml/gnc-book-xml-v2.c
===================================================================
--- gnucash/trunk/src/backend/xml/gnc-book-xml-v2.c 2010-01-31 11:22:24 UTC (rev 18592)
+++ gnucash/trunk/src/backend/xml/gnc-book-xml-v2.c 2010-01-31 18:37:28 UTC (rev 18593)
@@ -150,22 +150,18 @@
/* same as above, but we write out directly. Only handle the guid
* and slots, everything else is handled elsewhere */
-void
+gboolean
write_book_parts(FILE *out, QofBook *book)
{
xmlNodePtr domnode;
domnode = guid_to_dom_tree(book_id_string, qof_book_get_guid(book));
xmlElemDump(out, NULL, domnode);
- if (fprintf(out, "\n") < 0)
- {
- qof_backend_set_error(qof_book_get_backend(book),
- ERR_FILEIO_WRITE_ERROR);
- xmlFreeNode(domnode);
- return;
- }
xmlFreeNode (domnode);
+ if (ferror(out) || fprintf(out, "\n") < 0)
+ return FALSE;
+
if (qof_book_get_slots(book))
{
xmlNodePtr kvpnode = kvp_frame_to_dom_tree(book_slots_string,
@@ -173,10 +169,14 @@
if (kvpnode)
{
xmlElemDump(out, NULL, kvpnode);
- fprintf(out, "\n");
xmlFreeNode(kvpnode);
+
+ if (ferror(out) || fprintf(out, "\n") < 0)
+ return FALSE;
}
}
+
+ return TRUE;
}
Modified: gnucash/trunk/src/backend/xml/io-gncxml-v2.c
===================================================================
--- gnucash/trunk/src/backend/xml/io-gncxml-v2.c 2010-01-31 11:22:24 UTC (rev 18592)
+++ gnucash/trunk/src/backend/xml/io-gncxml-v2.c 2010-01-31 18:37:28 UTC (rev 18593)
@@ -803,16 +803,17 @@
/***********************************************************************/
-static void
+static gboolean
write_counts(FILE* out, ...)
{
va_list ap;
char *type;
+ gboolean success = TRUE;
va_start(ap, out);
type = va_arg(ap, char *);
- while (type)
+ while (success && type)
{
int amount = va_arg(ap, int);
@@ -832,15 +833,23 @@
* 'type' at some point. */
xmlSetProp(node, BAD_CAST "cd:type", BAD_CAST type);
xmlNodeAddContent(node, BAD_CAST val);
+ g_free(val);
xmlElemDump(out, NULL, node);
- fprintf(out, "\n");
+ xmlFreeNode(node);
- g_free(val);
- xmlFreeNode(node);
+ if (ferror(out) || fprintf(out, "\n") < 0)
+ {
+ success = FALSE;
+ break;
+ }
#else
- fprintf(out, "<%s %s=\"%s\">%d</%s>\n",
- COUNT_DATA_TAG, "cd:type", type, amount, COUNT_DATA_TAG);
+ if (fprintf(out, "<%s %s=\"%s\">%d</%s>\n",
+ COUNT_DATA_TAG, "cd:type", type, amount, COUNT_DATA_TAG) < 0)
+ {
+ success = FALSE;
+ break;
+ }
#endif
}
@@ -849,6 +858,7 @@
}
va_end(ap);
+ return success;
}
static gint
@@ -868,10 +878,10 @@
gnc_commodity_get_mnemonic(cb)));
}
-static void write_pricedb (FILE *out, QofBook *book, sixtp_gdv2 *gd);
-static void write_transactions (FILE *out, QofBook *book, sixtp_gdv2 *gd);
-static void write_template_transaction_data (FILE *out, QofBook *book, sixtp_gdv2 *gd);
-static void write_schedXactions(FILE *out, QofBook *book, sixtp_gdv2 *gd);
+static gboolean write_pricedb (FILE *out, QofBook *book, sixtp_gdv2 *gd);
+static gboolean write_transactions (FILE *out, QofBook *book, sixtp_gdv2 *gd);
+static gboolean write_template_transaction_data (FILE *out, QofBook *book, sixtp_gdv2 *gd);
+static gboolean write_schedXactions(FILE *out, QofBook *book, sixtp_gdv2 *gd);
static void write_budget (QofInstance *ent, gpointer data);
static void
@@ -898,11 +908,11 @@
g_return_if_fail (type && data && be_data);
g_return_if_fail (data->version == GNC_FILE_BACKEND_VERS);
- if (data->write)
+ if (data->write && !ferror(be_data->out))
(data->write)(be_data->out, be_data->book);
}
-static void
+static gboolean
write_book(FILE *out, QofBook *book, sixtp_gdv2 *gd)
{
struct file_backend be_data;
@@ -919,72 +929,79 @@
if (!node)
{
- return;
+ return FALSE;
}
xmlElemDump(out, NULL, node);
- if (fprintf(out, "\n") < 0)
+ xmlFreeNode(node);
+
+ if (ferror(out) || fprintf(out, "\n") < 0)
{
- qof_backend_set_error(qof_book_get_backend(book), ERR_FILEIO_WRITE_ERROR);
- return;
+ return FALSE;
}
- xmlFreeNode(node);
#endif
be_data.out = out;
be_data.book = book;
be_data.gd = gd;
if (fprintf( out, "<%s version=\"%s\">\n", BOOK_TAG, gnc_v2_book_version_string) < 0)
- {
- qof_backend_set_error(qof_book_get_backend(book), ERR_FILEIO_WRITE_ERROR);
- return;
- }
- write_book_parts (out, book);
+ return FALSE;
+ if (!write_book_parts (out, book))
+ return FALSE;
/* gd->counter.{foo}_total fields should have all these totals
already collected. I don't know why we're re-calling all these
functions. */
- write_counts(out,
- "commodity",
- gnc_commodity_table_get_size(
- gnc_book_get_commodity_table(book)),
- "account",
- 1 + gnc_account_n_descendants(gnc_book_get_root_account(book)),
- "transaction",
- gnc_book_count_transactions(book),
- "schedxaction",
- g_list_length(gnc_book_get_schedxactions(book)->sx_list),
- "budget", qof_collection_count(
- qof_book_get_collection(book, GNC_ID_BUDGET)),
- NULL);
+ if (!write_counts(out,
+ "commodity",
+ gnc_commodity_table_get_size(
+ gnc_book_get_commodity_table(book)),
+ "account",
+ 1 + gnc_account_n_descendants(gnc_book_get_root_account(book)),
+ "transaction",
+ gnc_book_count_transactions(book),
+ "schedxaction",
+ g_list_length(gnc_book_get_schedxactions(book)->sx_list),
+ "budget", qof_collection_count(
+ qof_book_get_collection(book, GNC_ID_BUDGET)),
+ NULL))
+ return FALSE;
qof_object_foreach_backend (GNC_FILE_BACKEND, write_counts_cb, &be_data);
- write_commodities(out, book, gd);
- write_pricedb(out, book, gd);
- write_accounts(out, book, gd);
- write_transactions(out, book, gd);
- write_template_transaction_data(out, book, gd);
- write_schedXactions(out, book, gd);
+ if (ferror(out)
+ || !write_commodities(out, book, gd)
+ || !write_pricedb(out, book, gd)
+ || !write_accounts(out, book, gd)
+ || !write_transactions(out, book, gd)
+ || !write_template_transaction_data(out, book, gd)
+ || !write_schedXactions(out, book, gd))
+ return FALSE;
+
qof_collection_foreach(qof_book_get_collection(book, GNC_ID_BUDGET),
write_budget, &be_data);
+ if (ferror(out))
+ return FALSE;
qof_object_foreach_backend (GNC_FILE_BACKEND, write_data_cb, &be_data);
+ if (ferror(out))
+ return FALSE;
if (fprintf( out, "</%s>\n", BOOK_TAG ) < 0)
- {
- qof_backend_set_error(qof_book_get_backend(book), ERR_FILEIO_WRITE_ERROR);
- }
+ return FALSE;
+
+ return TRUE;
}
-void
+gboolean
write_commodities(FILE *out, QofBook *book, sixtp_gdv2 *gd)
{
gnc_commodity_table *tbl;
GList *namespaces;
GList *lp;
+ gboolean success = TRUE;
tbl = gnc_book_get_commodity_table(book);
@@ -994,7 +1011,7 @@
namespaces = g_list_sort(namespaces, compare_namespaces);
}
- for (lp = namespaces; lp; lp = lp->next)
+ for (lp = namespaces; success && lp; lp = lp->next)
{
GList *comms, *lp2;
xmlNodePtr comnode;
@@ -1009,7 +1026,11 @@
continue;
xmlElemDump(out, NULL, comnode);
- fprintf(out, "\n");
+ if (ferror(out) || fprintf(out, "\n") < 0)
+ {
+ success = FALSE;
+ break;
+ }
xmlFreeNode(comnode);
gd->counter.commodities_loaded++;
@@ -1020,9 +1041,11 @@
}
if (namespaces) g_list_free (namespaces);
+
+ return success;
}
-static void
+static gboolean
write_pricedb(FILE *out, QofBook *book, sixtp_gdv2 *gd)
{
xmlNodePtr node;
@@ -1031,13 +1054,16 @@
if (!node)
{
- return;
+ return TRUE;
}
xmlElemDump(out, NULL, node);
- fprintf(out, "\n");
+ xmlFreeNode(node);
- xmlFreeNode(node);
+ if (ferror(out) || fprintf(out, "\n") < 0)
+ return FALSE;
+
+ return TRUE;
}
static int
@@ -1049,27 +1075,30 @@
node = gnc_transaction_dom_tree_create(t);
xmlElemDump(be_data->out, NULL, node);
- fprintf(be_data->out, "\n");
+ xmlFreeNode(node);
- xmlFreeNode(node);
+ if (ferror(be_data->out) || fprintf(be_data->out, "\n") < 0)
+ return -1;
+
be_data->gd->counter.transactions_loaded++;
run_callback(be_data->gd, "transaction");
return 0;
}
-static void
+static gboolean
write_transactions(FILE *out, QofBook *book, sixtp_gdv2 *gd)
{
struct file_backend be_data;
be_data.out = out;
be_data.gd = gd;
- xaccAccountTreeForEachTransaction(gnc_book_get_root_account(book),
- xml_add_trn_data,
- (gpointer) &be_data);
+ return 0 ==
+ xaccAccountTreeForEachTransaction(gnc_book_get_root_account(book),
+ xml_add_trn_data,
+ (gpointer) &be_data);
}
-static void
+static gboolean
write_template_transaction_data( FILE *out, QofBook *book, sixtp_gdv2 *gd )
{
Account *ra;
@@ -1081,14 +1110,18 @@
ra = gnc_book_get_template_root(book);
if ( gnc_account_n_descendants(ra) > 0 )
{
- fprintf( out, "<%s>\n", TEMPLATE_TRANSACTION_TAG );
- write_account_tree( out, ra, gd );
- xaccAccountTreeForEachTransaction( ra, xml_add_trn_data, (gpointer)&be_data );
- fprintf( out, "</%s>\n", TEMPLATE_TRANSACTION_TAG );
+ if (fprintf(out, "<%s>\n", TEMPLATE_TRANSACTION_TAG) < 0
+ || !write_account_tree(out, ra, gd)
+ || xaccAccountTreeForEachTransaction(ra, xml_add_trn_data, (gpointer)&be_data)
+ || fprintf(out, "</%s>\n", TEMPLATE_TRANSACTION_TAG) < 0)
+
+ return FALSE;
}
+
+ return TRUE;
}
-static void
+static gboolean
write_schedXactions( FILE *out, QofBook *book, sixtp_gdv2 *gd)
{
GList *schedXactions;
@@ -1097,20 +1130,23 @@
schedXactions = gnc_book_get_schedxactions(book)->sx_list;
- if ( schedXactions == NULL )
- return;
+ if (schedXactions == NULL)
+ return TRUE;
do
{
tmpSX = schedXactions->data;
node = gnc_schedXaction_dom_tree_create( tmpSX );
xmlElemDump( out, NULL, node );
- fprintf( out, "\n" );
- xmlFreeNode( node );
+ xmlFreeNode(node);
+ if (ferror(out) || fprintf(out, "\n") < 0)
+ return FALSE;
gd->counter.schedXactions_loaded++;
run_callback(gd, "schedXactions");
}
while ( (schedXactions = schedXactions->next) );
+
+ return TRUE;
}
static void
@@ -1120,21 +1156,26 @@
struct file_backend* be = data;
GncBudget *bgt = GNC_BUDGET(ent);
+
+ if (ferror(be->out))
+ return;
+
node = gnc_budget_dom_tree_create(bgt);
xmlElemDump( be->out, NULL, node );
- fprintf( be->out, "\n" );
- xmlFreeNode( node );
+ xmlFreeNode(node);
+ if (ferror(be->out) || fprintf(be->out, "\n") < 0)
+ return;
be->gd->counter.budgets_loaded++;
run_callback(be->gd, "budgets");
}
-void
+gboolean
gnc_xml2_write_namespace_decl (FILE *out, const char *namespace)
{
- g_return_if_fail (namespace);
- fprintf(out, "\n xmlns:%s=\"http://www.gnucash.org/XML/%s\"",
- namespace, namespace);
+ g_return_val_if_fail(namespace, FALSE);
+ return fprintf(out, "\n xmlns:%s=\"http://www.gnucash.org/XML/%s\"",
+ namespace, namespace) >= 0;
}
static void
@@ -1146,36 +1187,41 @@
g_return_if_fail (type && data && out);
g_return_if_fail (data->version == GNC_FILE_BACKEND_VERS);
- if (data->ns)
+ if (data->ns && !ferror(out))
(data->ns)(out);
}
-static void
+static gboolean
write_v2_header (FILE *out)
{
- fprintf(out, "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n");
- fprintf(out, "<" GNC_V2_STRING);
+ if (fprintf(out, "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n") < 0
+ || fprintf(out, "<" GNC_V2_STRING) < 0
- gnc_xml2_write_namespace_decl (out, "gnc");
- gnc_xml2_write_namespace_decl (out, "act");
- gnc_xml2_write_namespace_decl (out, "book");
- gnc_xml2_write_namespace_decl (out, "cd");
- gnc_xml2_write_namespace_decl (out, "cmdty");
- gnc_xml2_write_namespace_decl (out, "price");
- gnc_xml2_write_namespace_decl (out, "slot");
- gnc_xml2_write_namespace_decl (out, "split");
- gnc_xml2_write_namespace_decl (out, "sx");
- gnc_xml2_write_namespace_decl (out, "trn");
- gnc_xml2_write_namespace_decl (out, "ts");
- gnc_xml2_write_namespace_decl (out, "fs");
- gnc_xml2_write_namespace_decl (out, "bgt");
- gnc_xml2_write_namespace_decl (out, "recurrence");
- gnc_xml2_write_namespace_decl (out, "lot");
+ || !gnc_xml2_write_namespace_decl (out, "gnc")
+ || !gnc_xml2_write_namespace_decl (out, "act")
+ || !gnc_xml2_write_namespace_decl (out, "book")
+ || !gnc_xml2_write_namespace_decl (out, "cd")
+ || !gnc_xml2_write_namespace_decl (out, "cmdty")
+ || !gnc_xml2_write_namespace_decl (out, "price")
+ || !gnc_xml2_write_namespace_decl (out, "slot")
+ || !gnc_xml2_write_namespace_decl (out, "split")
+ || !gnc_xml2_write_namespace_decl (out, "sx")
+ || !gnc_xml2_write_namespace_decl (out, "trn")
+ || !gnc_xml2_write_namespace_decl (out, "ts")
+ || !gnc_xml2_write_namespace_decl (out, "fs")
+ || !gnc_xml2_write_namespace_decl (out, "bgt")
+ || !gnc_xml2_write_namespace_decl (out, "recurrence")
+ || !gnc_xml2_write_namespace_decl (out, "lot"))
+ return FALSE;
+
/* now cope with the plugins */
qof_object_foreach_backend (GNC_FILE_BACKEND, do_write_namespace_cb, out);
- fprintf(out, ">\n");
+ if (ferror(out) || fprintf(out, ">\n") < 0)
+ return FALSE;
+
+ return TRUE;
}
gboolean
@@ -1183,15 +1229,14 @@
{
QofBackend *be;
sixtp_gdv2 *gd;
+ gboolean success = TRUE;
if (!out) return FALSE;
- write_v2_header (out);
+ if (!write_v2_header(out)
+ || !write_counts(out, "book", 1, NULL))
+ return FALSE;
- write_counts(out,
- "book", 1,
- NULL);
-
be = qof_book_get_backend(book);
gd = gnc_sixtp_gdv2_new(book, FALSE, file_rw_feedback, be->percentage);
gd->counter.commodities_total =
@@ -1204,12 +1249,12 @@
gd->counter.budgets_total = qof_collection_count(
qof_book_get_collection(book, GNC_ID_BUDGET));
- write_book(out, book, gd);
+ if (!write_book(out, book, gd)
+ || fprintf(out, "</" GNC_V2_STRING ">\n\n") < 0)
+ success = FALSE;
- fprintf(out, "</" GNC_V2_STRING ">\n\n");
-
g_free(gd);
- return TRUE;
+ return success;
}
/*
@@ -1222,6 +1267,7 @@
Account *root;
int ncom, nacc;
sixtp_gdv2 *gd;
+ gboolean success = TRUE;
if (!out) return FALSE;
@@ -1231,25 +1277,21 @@
table = gnc_book_get_commodity_table(book);
ncom = gnc_commodity_table_get_size(table);
- write_v2_header (out);
+ if (!write_v2_header(out)
+ || !write_counts(out, "commodity", ncom, "account", nacc, NULL))
+ return FALSE;
- write_counts(out,
- "commodity", ncom,
- "account", nacc,
- NULL);
-
gd = gnc_sixtp_gdv2_new(book, TRUE, file_rw_feedback, be->percentage);
gd->counter.commodities_total = ncom;
gd->counter.accounts_total = nacc;
- write_commodities(out, book, gd);
+ if (!write_commodities(out, book, gd)
+ || !write_accounts(out, book, gd)
+ || fprintf(out, "</" GNC_V2_STRING ">\n\n") < 0)
+ success = FALSE;
- write_accounts(out, book, gd);
-
- fprintf(out, "</" GNC_V2_STRING ">\n\n");
-
g_free(gd);
- return TRUE;
+ return success;
}
#define BUFLEN 4096
@@ -1407,26 +1449,26 @@
gboolean compress)
{
FILE *out;
+ gboolean success = TRUE;
out = try_gz_open(filename, "w", compress, TRUE);
- if (out == NULL)
- {
- return FALSE;
- }
- gnc_book_write_to_xml_filehandle_v2 (book, out);
+ /* Try to write as much as possible */
+ if (!out
+ || !gnc_book_write_to_xml_filehandle_v2(book, out)
+ || !write_emacs_trailer(out))
+ success = FALSE;
- write_emacs_trailer(out);
+ /* Close the output stream */
+ if (out && fclose(out))
+ success = FALSE;
- if (fclose(out) != 0)
- {
- return FALSE;
- }
+ /* Optionally wait for parallel compression threads */
+ if (out && compress)
+ if (!wait_for_gzip(out))
+ success = FALSE;
- if (compress)
- return wait_for_gzip(out);
-
- return TRUE;
+ return success;
}
/*
@@ -1441,23 +1483,28 @@
const char *filename)
{
FILE *out;
+ gboolean success = TRUE;
out = g_fopen(filename, "w");
- if (out == NULL)
- {
- return FALSE;
- }
- gnc_book_write_accounts_to_xml_filehandle_v2 (be, book, out);
+ /* Try to write as much as possible */
+ if (!out
+ || !gnc_book_write_accounts_to_xml_filehandle_v2 (be, book, out)
+ || !write_emacs_trailer(out))
+ success = FALSE;
- write_emacs_trailer(out);
+ /* Close the output stream */
+ if (out && fclose(out))
+ success = FALSE;
- if (fclose(out) != 0)
- {
- return FALSE;
+ if (!success
+ && qof_backend_get_error(be) == ERR_BACKEND_NO_ERR) {
+
+ /* Use a generic write error code */
+ qof_backend_set_error(be, ERR_FILEIO_WRITE_ERROR);
}
- return TRUE;
+ return success;
}
/***********************************************************************/
Modified: gnucash/trunk/src/backend/xml/io-gncxml-v2.h
===================================================================
--- gnucash/trunk/src/backend/xml/io-gncxml-v2.h 2010-01-31 11:22:24 UTC (rev 18592)
+++ gnucash/trunk/src/backend/xml/io-gncxml-v2.h 2010-01-31 18:37:28 UTC (rev 18593)
@@ -106,9 +106,9 @@
sixtp * (*create_parser) (void);
gboolean (*add_item)(sixtp_gdv2 *, gpointer obj);
int (*get_count) (QofBook *);
- void (*write) (FILE*, QofBook*);
+ gboolean (*write) (FILE*, QofBook*);
void (*scrub) (QofBook *);
- void (*ns) (FILE*);
+ gboolean (*ns) (FILE*);
} GncXmlDataType_t;
/**
@@ -147,7 +147,7 @@
/** Write a name-space declaration for the provided namespace data type
* within the GNC XML namespace at http://www.gnucash.org/XML.
*/
-void gnc_xml2_write_namespace_decl (FILE *out, const char *namespace);
+gboolean gnc_xml2_write_namespace_decl (FILE *out, const char *namespace);
typedef struct
Modified: gnucash/trunk/src/backend/xml/io-utils.c
===================================================================
--- gnucash/trunk/src/backend/xml/io-utils.c 2010-01-31 11:22:24 UTC (rev 18592)
+++ gnucash/trunk/src/backend/xml/io-utils.c 2010-01-31 18:37:28 UTC (rev 18593)
@@ -45,13 +45,13 @@
"<!-- End: -->\n";
-void
+gboolean
write_emacs_trailer(FILE *out)
{
- fprintf(out, "%s", emacs_trailer);
+ return fprintf(out, "%s", emacs_trailer) >= 0;
}
-static void
+static gboolean
write_one_account(FILE *out,
Account *account,
sixtp_gdv2 *gd,
@@ -63,30 +63,43 @@
gnc_account_dom_tree_create(account, gd && gd->exporting, allow_incompat);
xmlElemDump(out, NULL, accnode);
- fprintf(out, "\n");
+ xmlFreeNode(accnode);
- xmlFreeNode(accnode);
+ if (ferror(out) || fprintf(out, "\n") < 0)
+ return FALSE;
+
gd->counter.accounts_loaded++;
run_callback(gd, "account");
+ return TRUE;
}
-void
+gboolean
write_account_tree(FILE *out, Account *root, sixtp_gdv2 *gd)
{
GList *descendants, *node;
gboolean allow_incompat = TRUE;
+ gboolean success = TRUE;
if (allow_incompat)
- write_one_account(out, root, gd, allow_incompat);
+ if (!write_one_account(out, root, gd, allow_incompat))
+ return FALSE;
descendants = gnc_account_get_descendants(root);
for (node = descendants; node; node = g_list_next(node))
- write_one_account(out, node->data, gd, allow_incompat);
+ {
+ if (!write_one_account(out, node->data, gd, allow_incompat))
+ {
+ success = FALSE;
+ break;
+ }
+ }
+
g_list_free(descendants);
+ return success;
}
-void
+gboolean
write_accounts(FILE *out, QofBook *book, sixtp_gdv2 *gd)
{
- write_account_tree(out, gnc_book_get_root_account(book), gd);
+ return write_account_tree(out, gnc_book_get_root_account(book), gd);
}
Modified: gnucash/trunk/src/backend/xml/io-utils.h
===================================================================
--- gnucash/trunk/src/backend/xml/io-utils.h 2010-01-31 11:22:24 UTC (rev 18592)
+++ gnucash/trunk/src/backend/xml/io-utils.h 2010-01-31 18:37:28 UTC (rev 18593)
@@ -30,12 +30,12 @@
#include "io-gncxml-v2.h"
#include "qof.h"
-void write_account_tree(FILE *out, Account *root, sixtp_gdv2 *gd);
-void write_accounts(FILE *out, QofBook *book, sixtp_gdv2 *gd);
-void write_book_parts(FILE *out, QofBook *book);
-void write_commodities(FILE *out, QofBook *book, sixtp_gdv2 *gd);
+gboolean write_account_tree(FILE *out, Account *root, sixtp_gdv2 *gd);
+gboolean write_accounts(FILE *out, QofBook *book, sixtp_gdv2 *gd);
+gboolean write_book_parts(FILE *out, QofBook *book);
+gboolean write_commodities(FILE *out, QofBook *book, sixtp_gdv2 *gd);
-void write_emacs_trailer(FILE *out);
+gboolean write_emacs_trailer(FILE *out);
#endif /* IO_UTILS_H */
Modified: gnucash/trunk/src/business/business-core/xml/gnc-address-xml-v2.c
===================================================================
--- gnucash/trunk/src/business/business-core/xml/gnc-address-xml-v2.c 2010-01-31 11:22:24 UTC (rev 18592)
+++ gnucash/trunk/src/business/business-core/xml/gnc-address-xml-v2.c 2010-01-31 18:37:28 UTC (rev 18593)
@@ -210,11 +210,11 @@
return successful;
}
-static void
+static gboolean
address_ns(FILE *out)
{
- g_return_if_fail(out);
- gnc_xml2_write_namespace_decl(out, "addr");
+ g_return_val_if_fail(out, FALSE);
+ return gnc_xml2_write_namespace_decl(out, "addr");
}
void
Modified: gnucash/trunk/src/business/business-core/xml/gnc-bill-term-xml-v2.c
===================================================================
--- gnucash/trunk/src/business/business-core/xml/gnc-bill-term-xml-v2.c 2010-01-31 11:22:24 UTC (rev 18592)
+++ gnucash/trunk/src/business/business-core/xml/gnc-bill-term-xml-v2.c 2010-01-31 18:37:28 UTC (rev 18593)
@@ -503,16 +503,21 @@
GncBillTerm *term = (GncBillTerm *) term_p;
FILE *out = out_p;
+ if (ferror(out))
+ return;
+
node = billterm_dom_tree_create (term);
xmlElemDump(out, NULL, node);
- fprintf(out, "\n");
xmlFreeNode (node);
+ if (ferror(out) || fprintf(out, "\n") < 0)
+ return;
}
-static void
+static gboolean
billterm_write (FILE *out, QofBook *book)
{
qof_object_foreach (_GNC_MOD_NAME, book, xml_add_billterm, (gpointer) out);
+ return ferror(out) == 0;
}
static gboolean
@@ -707,13 +712,14 @@
g_hash_table_destroy(ht);
}
-static void
+static gboolean
billterm_ns(FILE *out)
{
- g_return_if_fail(out);
- gnc_xml2_write_namespace_decl(out, "billterm");
- gnc_xml2_write_namespace_decl(out, "bt-days");
- gnc_xml2_write_namespace_decl(out, "bt-prox");
+ g_return_val_if_fail(out, FALSE);
+ return
+ gnc_xml2_write_namespace_decl(out, "billterm")
+ && gnc_xml2_write_namespace_decl(out, "bt-days")
+ && gnc_xml2_write_namespace_decl(out, "bt-prox");
}
void
Modified: gnucash/trunk/src/business/business-core/xml/gnc-customer-xml-v2.c
===================================================================
--- gnucash/trunk/src/business/business-core/xml/gnc-customer-xml-v2.c 2010-01-31 11:22:24 UTC (rev 18592)
+++ gnucash/trunk/src/business/business-core/xml/gnc-customer-xml-v2.c 2010-01-31 18:37:28 UTC (rev 18593)
@@ -492,26 +492,30 @@
GncCustomer *cust = (GncCustomer *) cust_p;
FILE *out = out_p;
+ if (ferror(out))
+ return;
if (!customer_should_be_saved (cust))
return;
node = customer_dom_tree_create (cust);
xmlElemDump(out, NULL, node);
- fprintf(out, "\n");
xmlFreeNode (node);
+ if (ferror(out) || fprintf(out, "\n") < 0)
+ return;
}
-static void
+static gboolean
customer_write (FILE *out, QofBook *book)
{
qof_object_foreach (_GNC_MOD_NAME, book, xml_add_customer, (gpointer) out);
+ return ferror(out) == 0;
}
-static void
+static gboolean
customer_ns(FILE *out)
{
- g_return_if_fail(out);
- gnc_xml2_write_namespace_decl(out, "cust");
+ g_return_val_if_fail(out, FALSE);
+ return gnc_xml2_write_namespace_decl(out, "cust");
}
void
Modified: gnucash/trunk/src/business/business-core/xml/gnc-employee-xml-v2.c
===================================================================
--- gnucash/trunk/src/business/business-core/xml/gnc-employee-xml-v2.c 2010-01-31 11:22:24 UTC (rev 18592)
+++ gnucash/trunk/src/business/business-core/xml/gnc-employee-xml-v2.c 2010-01-31 18:37:28 UTC (rev 18593)
@@ -417,26 +417,30 @@
GncEmployee *employee = (GncEmployee *) employee_p;
FILE *out = out_p;
+ if (ferror(out))
+ return;
if (!employee_should_be_saved (employee))
return;
node = employee_dom_tree_create (employee);
xmlElemDump(out, NULL, node);
- fprintf(out, "\n");
xmlFreeNode (node);
+ if (ferror(out) || fprintf(out, "\n") < 0)
+ return;
}
-static void
+static gboolean
employee_write (FILE *out, QofBook *book)
{
qof_object_foreach (_GNC_MOD_NAME, book, xml_add_employee, (gpointer) out);
+ return ferror(out) == 0;
}
-static void
+static gboolean
employee_ns(FILE *out)
{
- g_return_if_fail(out);
- gnc_xml2_write_namespace_decl(out, "employee");
+ g_return_val_if_fail(out, FALSE);
+ return gnc_xml2_write_namespace_decl(out, "employee");
}
void
Modified: gnucash/trunk/src/business/business-core/xml/gnc-entry-xml-v2.c
===================================================================
--- gnucash/trunk/src/business/business-core/xml/gnc-entry-xml-v2.c 2010-01-31 11:22:24 UTC (rev 18592)
+++ gnucash/trunk/src/business/business-core/xml/gnc-entry-xml-v2.c 2010-01-31 18:37:28 UTC (rev 18593)
@@ -802,6 +802,9 @@
GncEntry *entry = (GncEntry *) entry_p;
FILE *out = out_p;
+ if (ferror(out))
+ return;
+
/* Don't save non-attached entries! */
if (!(gncEntryGetOrder (entry) || gncEntryGetInvoice (entry) ||
gncEntryGetBill (entry)))
@@ -809,21 +812,23 @@
node = entry_dom_tree_create (entry);
xmlElemDump(out, NULL, node);
- fprintf(out, "\n");
xmlFreeNode (node);
+ if (ferror(out) || fprintf(out, "\n") < 0)
+ return;
}
-static void
+static gboolean
entry_write (FILE *out, QofBook *book)
{
qof_object_foreach (_GNC_MOD_NAME, book, xml_add_entry, (gpointer) out);
+ return ferror(out) == 0;
}
-static void
+static gboolean
entry_ns(FILE *out)
{
- g_return_if_fail(out);
- gnc_xml2_write_namespace_decl(out, "entry");
+ g_return_val_if_fail(out, FALSE);
+ return gnc_xml2_write_namespace_decl(out, "entry");
}
void
Modified: gnucash/trunk/src/business/business-core/xml/gnc-invoice-xml-v2.c
===================================================================
--- gnucash/trunk/src/business/business-core/xml/gnc-invoice-xml-v2.c 2010-01-31 11:22:24 UTC (rev 18592)
+++ gnucash/trunk/src/business/business-core/xml/gnc-invoice-xml-v2.c 2010-01-31 18:37:28 UTC (rev 18593)
@@ -523,26 +523,30 @@
GncInvoice *invoice = (GncInvoice *) invoice_p;
FILE *out = out_p;
+ if (ferror(out))
+ return;
if (!invoice_should_be_saved (invoice))
return;
node = invoice_dom_tree_create (invoice);
xmlElemDump(out, NULL, node);
- fprintf(out, "\n");
xmlFreeNode (node);
+ if (ferror(out) || fprintf(out, "\n") < 0)
+ return;
}
-static void
+static gboolean
invoice_write (FILE *out, QofBook *book)
{
qof_object_foreach (_GNC_MOD_NAME, book, xml_add_invoice, (gpointer) out);
+ return ferror(out) == 0;
}
-static void
+static gboolean
invoice_ns(FILE *out)
{
- g_return_if_fail(out);
- gnc_xml2_write_namespace_decl(out, "invoice");
+ g_return_val_if_fail(out, FALSE);
+ return gnc_xml2_write_namespace_decl(out, "invoice");
}
void
Modified: gnucash/trunk/src/business/business-core/xml/gnc-job-xml-v2.c
===================================================================
--- gnucash/trunk/src/business/business-core/xml/gnc-job-xml-v2.c 2010-01-31 11:22:24 UTC (rev 18592)
+++ gnucash/trunk/src/business/business-core/xml/gnc-job-xml-v2.c 2010-01-31 18:37:28 UTC (rev 18593)
@@ -310,26 +310,30 @@
GncJob *job = (GncJob *) job_p;
FILE *out = out_p;
+ if (ferror(out))
+ return;
if (!job_should_be_saved (job))
return;
node = job_dom_tree_create (job);
xmlElemDump(out, NULL, node);
- fprintf(out, "\n");
xmlFreeNode (node);
+ if (ferror(out) || fprintf(out, "\n") < 0)
+ return;
}
-static void
+static gboolean
job_write (FILE *out, QofBook *book)
{
qof_object_foreach (_GNC_MOD_NAME, book, xml_add_job, (gpointer) out);
+ return ferror(out) == 0;
}
-static void
+static gboolean
job_ns(FILE *out)
{
- g_return_if_fail(out);
- gnc_xml2_write_namespace_decl(out, "job");
+ g_return_val_if_fail(out, FALSE);
+ return gnc_xml2_write_namespace_decl(out, "job");
}
void
Modified: gnucash/trunk/src/business/business-core/xml/gnc-order-xml-v2.c
===================================================================
--- gnucash/trunk/src/business/business-core/xml/gnc-order-xml-v2.c 2010-01-31 11:22:24 UTC (rev 18592)
+++ gnucash/trunk/src/business/business-core/xml/gnc-order-xml-v2.c 2010-01-31 18:37:28 UTC (rev 18593)
@@ -353,26 +353,30 @@
GncOrder *order = (GncOrder *) order_p;
FILE *out = out_p;
+ if (ferror(out))
+ return;
if (!order_should_be_saved (order))
return;
node = order_dom_tree_create (order);
xmlElemDump(out, NULL, node);
- fprintf(out, "\n");
xmlFreeNode (node);
+ if (ferror(out) || fprintf(out, "\n") < 0)
+ return;
}
-static void
+static gboolean
order_write (FILE *out, QofBook *book)
{
qof_object_foreach (_GNC_MOD_NAME, book, xml_add_order, (gpointer) out);
+ return ferror(out) == 0;
}
-static void
+static gboolean
order_ns(FILE *out)
{
- g_return_if_fail(out);
- gnc_xml2_write_namespace_decl(out, "order");
+ g_return_val_if_fail(out, FALSE);
+ return gnc_xml2_write_namespace_decl(out, "order");
}
void
Modified: gnucash/trunk/src/business/business-core/xml/gnc-owner-xml-v2.c
===================================================================
--- gnucash/trunk/src/business/business-core/xml/gnc-owner-xml-v2.c 2010-01-31 11:22:24 UTC (rev 18592)
+++ gnucash/trunk/src/business/business-core/xml/gnc-owner-xml-v2.c 2010-01-31 18:37:28 UTC (rev 18593)
@@ -208,11 +208,11 @@
return successful;
}
-static void
+static gboolean
owner_ns(FILE *out)
{
- g_return_if_fail(out);
- gnc_xml2_write_namespace_decl(out, "owner");
+ g_return_val_if_fail(out, FALSE);
+ return gnc_xml2_write_namespace_decl(out, "owner");
}
void
Modified: gnucash/trunk/src/business/business-core/xml/gnc-tax-table-xml-v2.c
===================================================================
--- gnucash/trunk/src/business/business-core/xml/gnc-tax-table-xml-v2.c 2010-01-31 11:22:24 UTC (rev 18592)
+++ gnucash/trunk/src/business/business-core/xml/gnc-tax-table-xml-v2.c 2010-01-31 18:37:28 UTC (rev 18593)
@@ -466,16 +466,21 @@
GncTaxTable *table = (GncTaxTable *) table_p;
FILE *out = out_p;
+ if (ferror(out))
+ return;
+
node = taxtable_dom_tree_create (table);
xmlElemDump(out, NULL, node);
- fprintf(out, "\n");
xmlFreeNode (node);
+ if (ferror(out) || fprintf(out, "\n") < 0)
+ return;
}
-static void
+static gboolean
taxtable_write (FILE *out, QofBook *book)
{
qof_object_foreach (_GNC_MOD_NAME, book, xml_add_taxtable, (gpointer) out);
+ return ferror(out) == 0;
}
@@ -659,12 +664,13 @@
g_hash_table_destroy(ht);
}
-static void
+static gboolean
taxtable_ns(FILE *out)
{
- g_return_if_fail(out);
- gnc_xml2_write_namespace_decl(out, "taxtable");
- gnc_xml2_write_namespace_decl(out, "tte");
+ g_return_val_if_fail(out, FALSE);
+ return
+ gnc_xml2_write_namespace_decl(out, "taxtable")
+ && gnc_xml2_write_namespace_decl(out, "tte");
}
void
Modified: gnucash/trunk/src/business/business-core/xml/gnc-vendor-xml-v2.c
===================================================================
--- gnucash/trunk/src/business/business-core/xml/gnc-vendor-xml-v2.c 2010-01-31 11:22:24 UTC (rev 18592)
+++ gnucash/trunk/src/business/business-core/xml/gnc-vendor-xml-v2.c 2010-01-31 18:37:28 UTC (rev 18593)
@@ -436,26 +436,30 @@
GncVendor *vendor = (GncVendor *) vendor_p;
FILE *out = out_p;
+ if (ferror(out))
+ return;
if (!vendor_should_be_saved (vendor))
return;
node = vendor_dom_tree_create (vendor);
xmlElemDump(out, NULL, node);
- fprintf(out, "\n");
xmlFreeNode (node);
+ if (ferror(out) || fprintf(out, "\n") < 0)
+ return;
}
-static void
+static gboolean
vendor_write (FILE *out, QofBook *book)
{
qof_object_foreach (_GNC_MOD_NAME, book, xml_add_vendor, (gpointer) out);
+ return ferror(out) == 0;
}
-static void
+static gboolean
vendor_ns(FILE *out)
{
- g_return_if_fail(out);
- gnc_xml2_write_namespace_decl(out, "vendor");
+ g_return_val_if_fail(out, FALSE);
+ return gnc_xml2_write_namespace_decl(out, "vendor");
}
void
More information about the gnucash-changes
mailing list