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.

git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@18593 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Andreas Köhler
2010-01-31 18:37:28 +00:00
parent 3d64201763
commit ef5a742bf1
17 changed files with 327 additions and 223 deletions

View File

@@ -715,6 +715,9 @@ gnc_xml_be_write_to_file(FileBackend *fbe,
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("");

View File

@@ -150,22 +150,18 @@ gnc_book_dom_tree_create(QofBook *book)
/* 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 @@ write_book_parts(FILE *out, QofBook *book)
if (kvpnode)
{
xmlElemDump(out, NULL, kvpnode);
fprintf(out, "\n");
xmlFreeNode(kvpnode);
if (ferror(out) || fprintf(out, "\n") < 0)
return FALSE;
}
}
return TRUE;
}

View File

@@ -803,16 +803,17 @@ qof_session_load_from_xml_file_v2(FileBackend *fbe, QofBook *book)
/***********************************************************************/
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 @@ write_counts(FILE* out, ...)
* '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");
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 @@ write_counts(FILE* out, ...)
}
va_end(ap);
return success;
}
static gint
@@ -868,10 +878,10 @@ compare_commodity_ids(gconstpointer a, gconstpointer b)
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 @@ write_data_cb (const char *type, gpointer data_p, gpointer be_data_p)
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 @@ write_book(FILE *out, QofBook *book, sixtp_gdv2 *gd)
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 @@ write_commodities(FILE *out, QofBook *book, sixtp_gdv2 *gd)
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 @@ write_commodities(FILE *out, QofBook *book, sixtp_gdv2 *gd)
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 @@ write_commodities(FILE *out, QofBook *book, sixtp_gdv2 *gd)
}
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 @@ write_pricedb(FILE *out, QofBook *book, sixtp_gdv2 *gd)
if (!node)
{
return;
return TRUE;
}
xmlElemDump(out, NULL, node);
fprintf(out, "\n");
xmlFreeNode(node);
if (ferror(out) || fprintf(out, "\n") < 0)
return FALSE;
return TRUE;
}
static int
@@ -1049,27 +1075,30 @@ xml_add_trn_data(Transaction *t, gpointer data)
node = gnc_transaction_dom_tree_create(t);
xmlElemDump(be_data->out, NULL, node);
fprintf(be_data->out, "\n");
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 @@ write_template_transaction_data( FILE *out, QofBook *book, sixtp_gdv2 *gd )
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 @@ write_schedXactions( FILE *out, QofBook *book, sixtp_gdv2 *gd)
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 @@ write_budget (QofInstance *ent, gpointer data)
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 @@ do_write_namespace_cb (const char *type, gpointer data_p, gpointer file_p)
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,14 +1229,13 @@ gnc_book_write_to_xml_filehandle_v2(QofBook *book, FILE *out)
{
QofBackend *be;
sixtp_gdv2 *gd;
gboolean success = TRUE;
if (!out) return FALSE;
write_v2_header (out);
write_counts(out,
"book", 1,
NULL);
if (!write_v2_header(out)
|| !write_counts(out, "book", 1, NULL))
return FALSE;
be = qof_book_get_backend(book);
gd = gnc_sixtp_gdv2_new(book, FALSE, file_rw_feedback, be->percentage);
@@ -1204,12 +1249,12 @@ gnc_book_write_to_xml_filehandle_v2(QofBook *book, FILE *out)
gd->counter.budgets_total = qof_collection_count(
qof_book_get_collection(book, GNC_ID_BUDGET));
write_book(out, book, gd);
fprintf(out, "</" GNC_V2_STRING ">\n\n");
if (!write_book(out, book, gd)
|| fprintf(out, "</" GNC_V2_STRING ">\n\n") < 0)
success = FALSE;
g_free(gd);
return TRUE;
return success;
}
/*
@@ -1222,6 +1267,7 @@ gnc_book_write_accounts_to_xml_filehandle_v2(QofBackend *be, QofBook *book, FILE
Account *root;
int ncom, nacc;
sixtp_gdv2 *gd;
gboolean success = TRUE;
if (!out) return FALSE;
@@ -1231,25 +1277,21 @@ gnc_book_write_accounts_to_xml_filehandle_v2(QofBackend *be, QofBook *book, FILE
table = gnc_book_get_commodity_table(book);
ncom = gnc_commodity_table_get_size(table);
write_v2_header (out);
write_counts(out,
"commodity", ncom,
"account", nacc,
NULL);
if (!write_v2_header(out)
|| !write_counts(out, "commodity", ncom, "account", nacc, NULL))
return FALSE;
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);
write_accounts(out, book, gd);
fprintf(out, "</" GNC_V2_STRING ">\n\n");
if (!write_commodities(out, book, gd)
|| !write_accounts(out, book, gd)
|| fprintf(out, "</" GNC_V2_STRING ">\n\n") < 0)
success = FALSE;
g_free(gd);
return TRUE;
return success;
}
#define BUFLEN 4096
@@ -1407,26 +1449,26 @@ gnc_book_write_to_xml_file_v2(
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 @@ gnc_book_write_accounts_to_xml_file_v2(
const char *filename)
{
FILE *out;
gboolean success = TRUE;
out = g_fopen(filename, "w");
if (out == NULL)
{
return FALSE;
/* 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;
/* Close the output stream */
if (out && fclose(out))
success = 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);
}
gnc_book_write_accounts_to_xml_filehandle_v2 (be, book, out);
write_emacs_trailer(out);
if (fclose(out) != 0)
{
return FALSE;
}
return TRUE;
return success;
}
/***********************************************************************/

View File

@@ -106,9 +106,9 @@ typedef struct
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 @@ gboolean gnc_is_xml_data_file_v2(const gchar *name, gboolean *with_encoding);
/** 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

View File

@@ -45,13 +45,13 @@ static const gchar *emacs_trailer =
"<!-- 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 @@ write_one_account(FILE *out,
gnc_account_dom_tree_create(account, gd && gd->exporting, allow_incompat);
xmlElemDump(out, NULL, accnode);
fprintf(out, "\n");
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);
}

View File

@@ -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 */

View File

@@ -210,11 +210,11 @@ gnc_dom_tree_to_address (xmlNodePtr node, GncAddress *address)
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

View File

@@ -503,16 +503,21 @@ xml_add_billterm (QofInstance *term_p, gpointer out_p)
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 @@ billterm_scrub (QofBook *book)
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

View File

@@ -492,26 +492,30 @@ xml_add_customer (QofInstance * cust_p, gpointer out_p)
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

View File

@@ -417,26 +417,30 @@ xml_add_employee (QofInstance * employee_p, gpointer out_p)
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

View File

@@ -802,6 +802,9 @@ xml_add_entry (QofInstance * entry_p, gpointer out_p)
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 @@ xml_add_entry (QofInstance * entry_p, gpointer out_p)
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

View File

@@ -523,26 +523,30 @@ xml_add_invoice (QofInstance * invoice_p, gpointer out_p)
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

View File

@@ -310,26 +310,30 @@ xml_add_job (QofInstance * job_p, gpointer out_p)
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

View File

@@ -353,26 +353,30 @@ xml_add_order (QofInstance * order_p, gpointer out_p)
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

View File

@@ -208,11 +208,11 @@ gnc_dom_tree_to_owner (xmlNodePtr node, GncOwner *owner, QofBook *book)
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

View File

@@ -466,16 +466,21 @@ xml_add_taxtable (QofInstance * table_p, gpointer out_p)
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 @@ taxtable_scrub (QofBook *book)
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

View File

@@ -436,26 +436,30 @@ xml_add_vendor (QofInstance * vendor_p, gpointer out_p)
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