mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
Merge branch 'guidcpp'
Incorporate Aaron Laws's reimplementation of gncguid with boost::guid.
This commit is contained in:
commit
d20dcb4648
@ -426,7 +426,6 @@ src/import-export/qif-imp/gncmod-qif-import.c
|
||||
src/import-export/qif/qif-context.c
|
||||
src/import-export/qif/qif-file.c
|
||||
src/import-export/qif/qif-objects.c
|
||||
src/libqof/qof/md5.c
|
||||
src/plugins/bi_import/dialog-bi-import-gui.c
|
||||
src/plugins/bi_import/dialog-bi-import-helper.c
|
||||
src/plugins/bi_import/dialog-bi-import.c
|
||||
|
@ -260,8 +260,10 @@ gnc_cm_event_handler (QofInstance *entity,
|
||||
{
|
||||
const GncGUID *guid = qof_entity_get_guid(entity);
|
||||
#if CM_DEBUG
|
||||
gchar guidstr[GUID_ENCODING_LENGTH+1];
|
||||
guid_to_string_buff (guid, guidstr);
|
||||
fprintf (stderr, "event_handler: event %d, entity %p, guid %s\n", event_type,
|
||||
entity, guid_to_string(guid));
|
||||
entity, guidstr);
|
||||
#endif
|
||||
add_event (&changes, guid, event_type, TRUE);
|
||||
|
||||
|
@ -71,7 +71,8 @@ gnc_state_set_base (const QofSession *session)
|
||||
{
|
||||
gchar *basename, *original = NULL, *filename, *file_guid;
|
||||
gchar *sf_extension = NULL, *newstyle_filename = NULL;
|
||||
const gchar *uri, *guid_string;
|
||||
const gchar *uri;
|
||||
gchar guid_string[GUID_ENCODING_LENGTH+1];
|
||||
QofBook *book;
|
||||
const GncGUID *guid;
|
||||
GKeyFile *key_file = NULL;
|
||||
@ -94,7 +95,7 @@ gnc_state_set_base (const QofSession *session)
|
||||
/* Get the book GncGUID */
|
||||
book = qof_session_get_book(session);
|
||||
guid = qof_entity_get_guid(QOF_INSTANCE(book));
|
||||
guid_string = guid_to_string(guid);
|
||||
guid_to_string_buff(guid, guid_string);
|
||||
|
||||
if (gnc_uri_is_file_uri (uri))
|
||||
{
|
||||
|
@ -1490,6 +1490,8 @@ static void add_to_hash_amount(GHashTable* hash, const GncGUID* guid, const gnc_
|
||||
* modify it in-place; if not, insert the new element into the
|
||||
* hash. */
|
||||
gnc_numeric* elem = g_hash_table_lookup(hash, guid);
|
||||
gchar guidstr[GUID_ENCODING_LENGTH+1];
|
||||
guid_to_string_buff(guid, guidstr);
|
||||
if (!elem)
|
||||
{
|
||||
elem = g_new0(gnc_numeric, 1);
|
||||
@ -1503,7 +1505,7 @@ static void add_to_hash_amount(GHashTable* hash, const GncGUID* guid, const gnc_
|
||||
g_critical("Oops, the given amount [%s] has the error code %d, at guid [%s].",
|
||||
gnc_num_dbg_to_string(*amount),
|
||||
gnc_numeric_check(*amount),
|
||||
guid_to_string(guid));
|
||||
guidstr);
|
||||
return;
|
||||
}
|
||||
if (gnc_numeric_check(*elem) != GNC_ERROR_OK)
|
||||
@ -1511,7 +1513,7 @@ static void add_to_hash_amount(GHashTable* hash, const GncGUID* guid, const gnc_
|
||||
g_critical("Oops, the account's amount [%s] has the error code %d, at guid [%s].",
|
||||
gnc_num_dbg_to_string(*elem),
|
||||
gnc_numeric_check(*elem),
|
||||
guid_to_string(guid));
|
||||
guidstr);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1527,7 +1529,7 @@ static void add_to_hash_amount(GHashTable* hash, const GncGUID* guid, const gnc_
|
||||
if (gnc_numeric_check(*elem) != GNC_ERROR_OK)
|
||||
{
|
||||
g_critical("Oops, after addition at guid [%s] the resulting amount [%s] has the error code %d; added amount = [%s].",
|
||||
guid_to_string(guid),
|
||||
guidstr,
|
||||
gnc_num_dbg_to_string(*elem),
|
||||
gnc_numeric_check(*elem),
|
||||
gnc_num_dbg_to_string(*amount));
|
||||
@ -1536,7 +1538,7 @@ static void add_to_hash_amount(GHashTable* hash, const GncGUID* guid, const gnc_
|
||||
|
||||
/* In case anyone wants to see this in the debug log. */
|
||||
g_debug("Adding to guid [%s] the value [%s]. Value now [%s].",
|
||||
guid_to_string(guid),
|
||||
guidstr,
|
||||
gnc_num_dbg_to_string(*amount),
|
||||
gnc_num_dbg_to_string(*elem));
|
||||
}
|
||||
|
@ -297,7 +297,7 @@ gnc_is_trans_scm(SCM scm)
|
||||
void
|
||||
gnc_split_scm_set_account(SCM split_scm, Account *account)
|
||||
{
|
||||
const char *guid_string;
|
||||
gchar guid_string[GUID_ENCODING_LENGTH+1];
|
||||
SCM arg;
|
||||
|
||||
initialize_scm_functions();
|
||||
@ -307,7 +307,7 @@ gnc_split_scm_set_account(SCM split_scm, Account *account)
|
||||
if (account == NULL)
|
||||
return;
|
||||
|
||||
guid_string = guid_to_string(xaccAccountGetGUID(account));
|
||||
guid_to_string_buff(xaccAccountGetGUID(account), guid_string);
|
||||
if (guid_string == NULL)
|
||||
return;
|
||||
|
||||
@ -657,6 +657,7 @@ gnc_copy_trans_scm_onto_trans_swap_accounts(SCM trans_scm,
|
||||
}
|
||||
else
|
||||
{
|
||||
gchar guidstr[GUID_ENCODING_LENGTH+1];
|
||||
SCM from, to;
|
||||
SCM map = SCM_EOL;
|
||||
SCM args = SCM_EOL;
|
||||
@ -668,8 +669,10 @@ gnc_copy_trans_scm_onto_trans_swap_accounts(SCM trans_scm,
|
||||
|
||||
args = scm_cons(commit, args);
|
||||
|
||||
from = scm_from_utf8_string(guid_to_string(guid_1));
|
||||
to = scm_from_utf8_string(guid_to_string(guid_2));
|
||||
guid_to_string_buff(guid_1, guidstr);
|
||||
from = scm_from_utf8_string(guidstr);
|
||||
guid_to_string_buff(guid_2, guidstr);
|
||||
to = scm_from_utf8_string(guidstr);
|
||||
|
||||
map = scm_cons(scm_cons(from, to), map);
|
||||
map = scm_cons(scm_cons(to, from), map);
|
||||
|
@ -103,7 +103,6 @@ main_helper (void *closure, int argc, char **argv)
|
||||
kvp_exclude_type (KVP_TYPE_DOUBLE);
|
||||
|
||||
/* Initialize to a known RNG position */
|
||||
guid_init();
|
||||
srand(1);
|
||||
|
||||
run_tests ();
|
||||
|
@ -225,10 +225,11 @@ load_single_split( GncSqlBackend* be, GncSqlRow* row )
|
||||
/*# -ifempty */
|
||||
if (pSplit != xaccSplitLookup( &split_guid, be->book ))
|
||||
{
|
||||
PERR("A malformed split with id %s was found in the dataset.",
|
||||
guid_to_string(qof_instance_get_guid(pSplit)));
|
||||
qof_backend_set_error( &be->be, ERR_BACKEND_DATA_CORRUPT);
|
||||
pSplit = NULL;
|
||||
gchar guidstr[GUID_ENCODING_LENGTH+1];
|
||||
guid_to_string_buff(qof_instance_get_guid(pSplit), guidstr);
|
||||
PERR("A malformed split with id %s was found in the dataset.", guidstr);
|
||||
qof_backend_set_error( &be->be, ERR_BACKEND_DATA_CORRUPT);
|
||||
pSplit = NULL;
|
||||
}
|
||||
return pSplit;
|
||||
}
|
||||
@ -305,10 +306,11 @@ load_single_tx( GncSqlBackend* be, GncSqlRow* row )
|
||||
|
||||
if (pTx != xaccTransLookup( &tx_guid, be->book ))
|
||||
{
|
||||
PERR("A malformed transaction with id %s was found in the dataset.",
|
||||
guid_to_string(qof_instance_get_guid(pTx)));
|
||||
qof_backend_set_error( &be->be, ERR_BACKEND_DATA_CORRUPT);
|
||||
pTx = NULL;
|
||||
gchar guidstr[GUID_ENCODING_LENGTH+1];
|
||||
guid_to_string_buff(qof_instance_get_guid(pTx), guidstr);
|
||||
PERR("A malformed transaction with id %s was found in the dataset.", guidstr);
|
||||
qof_backend_set_error( &be->be, ERR_BACKEND_DATA_CORRUPT);
|
||||
pTx = NULL;
|
||||
}
|
||||
|
||||
return pTx;
|
||||
|
@ -588,8 +588,9 @@ billterm_scrub_cb (QofInstance *term_p, gpointer list_p)
|
||||
if (t)
|
||||
{
|
||||
/* Fix up the broken "copy" function */
|
||||
PWARN("Fixing broken child billterm: %s",
|
||||
guid_to_string(qof_instance_get_guid(QOF_INSTANCE(term))));
|
||||
gchar guidstr[GUID_ENCODING_LENGTH+1];
|
||||
guid_to_string_buff(qof_instance_get_guid(QOF_INSTANCE(term)),guidstr);
|
||||
PWARN("Fixing broken child billterm: %s", guidstr);
|
||||
|
||||
gncBillTermBeginEdit(term);
|
||||
gncBillTermSetType(term, gncBillTermGetType(t));
|
||||
@ -624,8 +625,9 @@ billterm_scrub_invoices (QofInstance * invoice_p, gpointer ht_p)
|
||||
{
|
||||
if (billterm_is_grandchild(term))
|
||||
{
|
||||
PWARN("Fixing i-billterm on invoice %s\n",
|
||||
guid_to_string(qof_instance_get_guid(QOF_INSTANCE(invoice))));
|
||||
gchar guidstr[GUID_ENCODING_LENGTH+1];
|
||||
guid_to_string_buff(qof_instance_get_guid(QOF_INSTANCE(invoice)),guidstr);
|
||||
PWARN("Fixing i-billterm on invoice %s\n", guidstr);
|
||||
new_bt = billterm_find_senior(term);
|
||||
gncInvoiceBeginEdit(invoice);
|
||||
gncInvoiceSetTerms(invoice, new_bt);
|
||||
@ -656,9 +658,13 @@ billterm_scrub_cust (QofInstance * cust_p, gpointer ht_p)
|
||||
count++;
|
||||
g_hash_table_insert(ht, term, GINT_TO_POINTER(count));
|
||||
if (billterm_is_grandchild(term))
|
||||
PWARN("customer %s has grandchild billterm %s\n",
|
||||
guid_to_string(qof_instance_get_guid(QOF_INSTANCE(cust))),
|
||||
guid_to_string(qof_instance_get_guid(QOF_INSTANCE(term))));
|
||||
{
|
||||
gchar custstr[GUID_ENCODING_LENGTH+1];
|
||||
gchar termstr[GUID_ENCODING_LENGTH+1];
|
||||
guid_to_string_buff(qof_instance_get_guid(QOF_INSTANCE(cust)),custstr);
|
||||
guid_to_string_buff(qof_instance_get_guid(QOF_INSTANCE(term)),termstr);
|
||||
PWARN("customer %s has grandchild billterm %s\n", custstr,termstr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -677,9 +683,13 @@ billterm_scrub_vendor (QofInstance * vendor_p, gpointer ht_p)
|
||||
count++;
|
||||
g_hash_table_insert(ht, term, GINT_TO_POINTER(count));
|
||||
if (billterm_is_grandchild(term))
|
||||
PWARN("vendor %s has grandchild billterm %s\n",
|
||||
guid_to_string(qof_instance_get_guid(QOF_INSTANCE(vendor))),
|
||||
guid_to_string(qof_instance_get_guid(QOF_INSTANCE(term))));
|
||||
{
|
||||
gchar vendstr[GUID_ENCODING_LENGTH+1];
|
||||
gchar termstr[GUID_ENCODING_LENGTH+1];
|
||||
guid_to_string_buff(qof_instance_get_guid(QOF_INSTANCE(vendor)),vendstr);
|
||||
guid_to_string_buff(qof_instance_get_guid(QOF_INSTANCE(term)),termstr);
|
||||
PWARN("vendor %s has grandchild billterm %s\n", vendstr, termstr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -691,9 +701,10 @@ billterm_reset_refcount (gpointer key, gpointer value, gpointer notused)
|
||||
|
||||
if (count != gncBillTermGetRefcount(term) && !gncBillTermGetInvisible(term))
|
||||
{
|
||||
gchar termstr[GUID_ENCODING_LENGTH+1];
|
||||
guid_to_string_buff(qof_instance_get_guid(QOF_INSTANCE(term)),termstr);
|
||||
PWARN("Fixing refcount on billterm %s (%" G_GINT64_FORMAT " -> %d)\n",
|
||||
guid_to_string(qof_instance_get_guid(QOF_INSTANCE(term))),
|
||||
gncBillTermGetRefcount(term), count);
|
||||
termstr, gncBillTermGetRefcount(term), count);
|
||||
gncBillTermSetRefcount(term, count);
|
||||
}
|
||||
}
|
||||
@ -715,10 +726,11 @@ billterm_scrub (QofBook *book)
|
||||
/* destroy the list of "grandchildren" bill terms */
|
||||
for (node = list; node; node = node->next)
|
||||
{
|
||||
gchar termstr[GUID_ENCODING_LENGTH+1];
|
||||
term = node->data;
|
||||
|
||||
PWARN ("deleting grandchild billterm: %s\n",
|
||||
guid_to_string(qof_instance_get_guid(QOF_INSTANCE(term))));
|
||||
guid_to_string_buff(qof_instance_get_guid(QOF_INSTANCE(term)), termstr);
|
||||
PWARN ("deleting grandchild billterm: %s\n", termstr);
|
||||
|
||||
/* Make sure the parent has no children */
|
||||
parent = gncBillTermGetParent(term);
|
||||
@ -770,11 +782,13 @@ GncBillTerm *
|
||||
gnc_billterm_xml_find_or_create(QofBook *book, GncGUID *guid)
|
||||
{
|
||||
GncBillTerm *term;
|
||||
gchar guidstr[GUID_ENCODING_LENGTH+1];
|
||||
|
||||
guid_to_string_buff(guid, guidstr);
|
||||
g_return_val_if_fail(book, NULL);
|
||||
g_return_val_if_fail(guid, NULL);
|
||||
term = gncBillTermLookup(book, guid);
|
||||
DEBUG("looking for billterm %s, found %p", guid_to_string(guid), term);
|
||||
DEBUG("looking for billterm %s, found %p", guidstr, term);
|
||||
if (!term)
|
||||
{
|
||||
term = gncBillTermCreate(book);
|
||||
|
@ -740,10 +740,10 @@ gnc_schedXaction_end_handler(gpointer data_for_children,
|
||||
if ( sx->template_acct == NULL )
|
||||
{
|
||||
Account *ra = NULL;
|
||||
const char *id = NULL;
|
||||
Account *acct = NULL;
|
||||
sixtp_gdv2 *sixdata = gdata->parsedata;
|
||||
QofBook *book;
|
||||
gchar guidstr[GUID_ENCODING_LENGTH+1];
|
||||
|
||||
book = sixdata->book;
|
||||
|
||||
@ -751,8 +751,7 @@ gnc_schedXaction_end_handler(gpointer data_for_children,
|
||||
change re: storing template accounts. */
|
||||
/* Fix: get account with name of our GncGUID from the template
|
||||
accounts. Make that our template_acct pointer. */
|
||||
/* THREAD-UNSAFE */
|
||||
id = guid_to_string( xaccSchedXactionGetGUID( sx ) );
|
||||
guid_to_string_buff( xaccSchedXactionGetGUID( sx ), guidstr );
|
||||
ra = gnc_book_get_template_root(book);
|
||||
if ( ra == NULL )
|
||||
{
|
||||
@ -760,15 +759,15 @@ gnc_schedXaction_end_handler(gpointer data_for_children,
|
||||
xmlFreeNode( tree );
|
||||
return FALSE;
|
||||
}
|
||||
acct = gnc_account_lookup_by_name( ra, id );
|
||||
acct = gnc_account_lookup_by_name( ra, guidstr );
|
||||
if ( acct == NULL )
|
||||
{
|
||||
g_warning("no template account with name [%s]", id);
|
||||
g_warning("no template account with name [%s]", guidstr);
|
||||
xmlFreeNode( tree );
|
||||
return FALSE;
|
||||
}
|
||||
g_debug("template account name [%s] for SX with GncGUID [%s]",
|
||||
xaccAccountGetName( acct ), id );
|
||||
xaccAccountGetName( acct ), guidstr );
|
||||
|
||||
/* FIXME: free existing template account.
|
||||
* HUH????? We only execute this if there isn't
|
||||
|
@ -576,8 +576,9 @@ taxtable_scrub_entries (QofInstance * entry_p, gpointer ht_p)
|
||||
{
|
||||
if (taxtable_is_grandchild(table))
|
||||
{
|
||||
PINFO("Fixing i-taxtable on entry %s\n",
|
||||
guid_to_string(qof_instance_get_guid(QOF_INSTANCE(entry))));
|
||||
gchar guidstr[GUID_ENCODING_LENGTH+1];
|
||||
guid_to_string_buff(qof_instance_get_guid(QOF_INSTANCE(entry)),guidstr);
|
||||
PINFO("Fixing i-taxtable on entry %s\n",guidstr);
|
||||
new_tt = taxtable_find_senior(table);
|
||||
gncEntryBeginEdit(entry);
|
||||
gncEntrySetInvTaxTable(entry, new_tt);
|
||||
@ -597,8 +598,9 @@ taxtable_scrub_entries (QofInstance * entry_p, gpointer ht_p)
|
||||
{
|
||||
if (taxtable_is_grandchild(table))
|
||||
{
|
||||
PINFO("Fixing b-taxtable on entry %s\n",
|
||||
guid_to_string(qof_instance_get_guid(QOF_INSTANCE(entry))));
|
||||
gchar guidstr[GUID_ENCODING_LENGTH+1];
|
||||
guid_to_string_buff(qof_instance_get_guid(QOF_INSTANCE(entry)),guidstr);
|
||||
PINFO("Fixing b-taxtable on entry %s\n",guidstr);
|
||||
new_tt = taxtable_find_senior(table);
|
||||
gncEntryBeginEdit(entry);
|
||||
gncEntrySetBillTaxTable(entry, new_tt);
|
||||
@ -656,9 +658,10 @@ taxtable_reset_refcount (gpointer key, gpointer value, gpointer notused)
|
||||
|
||||
if (count != gncTaxTableGetRefcount(table) && !gncTaxTableGetInvisible(table))
|
||||
{
|
||||
gchar guidstr[GUID_ENCODING_LENGTH+1];
|
||||
guid_to_string_buff(qof_instance_get_guid(QOF_INSTANCE(table)),guidstr);
|
||||
PWARN("Fixing refcount on taxtable %s (%" G_GINT64_FORMAT " -> %d)\n",
|
||||
guid_to_string(qof_instance_get_guid(QOF_INSTANCE(table))),
|
||||
gncTaxTableGetRefcount(table), count);
|
||||
guidstr,gncTaxTableGetRefcount(table), count);
|
||||
gncTaxTableSetRefcount(table, count);
|
||||
}
|
||||
}
|
||||
@ -679,10 +682,11 @@ taxtable_scrub (QofBook *book)
|
||||
/* destroy the list of "grandchildren" tax tables */
|
||||
for (node = list; node; node = node->next)
|
||||
{
|
||||
gchar guidstr[GUID_ENCODING_LENGTH+1];
|
||||
table = node->data;
|
||||
|
||||
PINFO ("deleting grandchild taxtable: %s\n",
|
||||
guid_to_string(qof_instance_get_guid(QOF_INSTANCE(table))));
|
||||
guid_to_string_buff(qof_instance_get_guid(QOF_INSTANCE(table)),guidstr);
|
||||
PINFO ("deleting grandchild taxtable: %s\n", guidstr);
|
||||
|
||||
/* Make sure the parent has no children */
|
||||
parent = gncTaxTableGetParent(table);
|
||||
|
@ -308,10 +308,12 @@ add_kvp_value_node(xmlNodePtr node, gchar *tag, kvp_value* val)
|
||||
xmlSetProp(val_node, BAD_CAST "type", BAD_CAST "string");
|
||||
break;
|
||||
case KVP_TYPE_GUID:
|
||||
/* THREAD-UNSAFE */
|
||||
add_text_to_node(val_node, "guid",
|
||||
g_strdup(guid_to_string(kvp_value_get_guid(val))));
|
||||
{
|
||||
gchar guidstr[GUID_ENCODING_LENGTH+1];
|
||||
guid_to_string_buff(kvp_value_get_guid(val), guidstr);
|
||||
add_text_to_node(val_node, "guid", guidstr);
|
||||
break;
|
||||
}
|
||||
case KVP_TYPE_TIMESPEC:
|
||||
{
|
||||
Timespec ts = kvp_value_get_timespec (val);
|
||||
|
@ -218,7 +218,9 @@ equals_node_val_vs_splits(xmlNodePtr node, const Transaction *trn)
|
||||
|
||||
if (!spl_node)
|
||||
{
|
||||
g_print( "Split GUID %s", guid_to_string(xaccSplitGetGUID(spl_mark)) );
|
||||
gchar guidstr[GUID_ENCODING_LENGTH+1];
|
||||
guid_to_string_buff(xaccSplitGetGUID(spl_mark),guidstr);
|
||||
g_print( "Split GUID %s", guidstr );
|
||||
return "no matching split found";
|
||||
}
|
||||
|
||||
|
@ -2177,24 +2177,25 @@ gnc_invoice_save_page (InvoiceWindow *iw,
|
||||
GKeyFile *key_file,
|
||||
const gchar *group_name)
|
||||
{
|
||||
gchar guidstr[GUID_ENCODING_LENGTH+1];
|
||||
guid_to_string_buff(&iw->invoice_guid, guidstr);
|
||||
g_key_file_set_string(key_file, group_name, KEY_INVOICE_TYPE,
|
||||
InvoiceDialogTypeasString(iw->dialog_type));
|
||||
g_key_file_set_string(key_file, group_name, KEY_INVOICE_GUID,
|
||||
guid_to_string(&iw->invoice_guid));
|
||||
g_key_file_set_string(key_file, group_name, KEY_INVOICE_GUID, guidstr);
|
||||
|
||||
if (gncOwnerGetJob (&(iw->job)))
|
||||
{
|
||||
g_key_file_set_string(key_file, group_name, KEY_OWNER_TYPE,
|
||||
qofOwnerGetType(&iw->job));
|
||||
g_key_file_set_string(key_file, group_name, KEY_OWNER_GUID,
|
||||
guid_to_string(gncOwnerGetGUID(&iw->job)));
|
||||
guid_to_string_buff(gncOwnerGetGUID(&iw->job), guidstr);
|
||||
g_key_file_set_string(key_file, group_name, KEY_OWNER_GUID, guidstr);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_key_file_set_string(key_file, group_name, KEY_OWNER_TYPE,
|
||||
qofOwnerGetType(&iw->owner));
|
||||
g_key_file_set_string(key_file, group_name, KEY_OWNER_GUID,
|
||||
guid_to_string(gncOwnerGetGUID(&iw->owner)));
|
||||
guid_to_string_buff(gncOwnerGetGUID(&iw->owner), guidstr);
|
||||
g_key_file_set_string(key_file, group_name, KEY_OWNER_GUID, guidstr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -287,12 +287,12 @@ Return the @code{memcmp} of the two GUID's.
|
||||
You can encode and decode GUIDs and their string representations using the
|
||||
next two functions.
|
||||
|
||||
@deftypefun {const char *} guid_to_string (const GUID * @var{guid})
|
||||
@deftypefun {gchar *} guid_to_string (const GUID * @var{guid})
|
||||
Return a null-terminated string encoding of @var{guid}. String encodings
|
||||
of identifiers are hex numbers printed only with the characters @code{0}
|
||||
through @code{9} and @code{a} through @code{f}. The encoding will
|
||||
always be @code{GUID_ENCODING_LENGTH} characters long. The returned
|
||||
string must NOT be freed when no longer needed.
|
||||
string must be freed when no longer needed using g_free.
|
||||
@end deftypefun
|
||||
|
||||
@deftypefun {char *} guid_to_string_buff (const GUID * @var{guid}, char * @var{buff})
|
||||
@ -353,7 +353,7 @@ entities such as Accounts and Transactions.
|
||||
Generate a new guid. This function is guaranteed to return a guid that
|
||||
is unique within the scope of all GnuCash entities being managed by the
|
||||
the current invocation of GnuCash. GnuCash routines should always use
|
||||
this function and not @code{guid_new}!
|
||||
this function and not @code{guid_replace}!
|
||||
@end deftypefun
|
||||
|
||||
@deftypefun {void *} xaccLookupEntity (const GUID * @var{guid}, GNCIdType @var{entity_type})
|
||||
@ -378,23 +378,7 @@ entity is not changed in any way.
|
||||
GUIDs are created by the GUID generator. The API for this generator is
|
||||
low-level and should not be used by user-code.
|
||||
|
||||
@deftypefun void guid_init (void)
|
||||
Initialize the GUID generator with a variety of random sources including
|
||||
common system files and /dev/random.
|
||||
@end deftypefun
|
||||
|
||||
@deftypefun void guid_init_with_salt (const void * @var{salt}, size_t @var{salt_len})
|
||||
Initialize the GUID generator with guid_init() and with the given
|
||||
sequence of arbitrary binary data.
|
||||
@end deftypefun
|
||||
|
||||
@deftypefun void guid_init_only_salt (const void * @var{salt}, size_t @var{salt_len})
|
||||
Initialize the GUID generator using only the given sequence of arbitrary
|
||||
binary data. This provides a way to reliably obtain a given sequence of
|
||||
GUIDs.
|
||||
@end deftypefun
|
||||
|
||||
@deftypefun void guid_new (GUID * @var{guid})
|
||||
@deftypefun void guid_replace (GUID * @var{guid})
|
||||
Create a new GUID and store it in @var{guid}. This is a low-level function!
|
||||
GnuCash code should use @code{xaccGUIDNew}.
|
||||
@end deftypefun
|
||||
|
@ -380,6 +380,7 @@ xaccSchedXactionInit(SchedXaction *sx, QofBook *book)
|
||||
{
|
||||
Account *ra;
|
||||
const GncGUID *guid;
|
||||
gchar guidstr[GUID_ENCODING_LENGTH+1];
|
||||
|
||||
qof_instance_init_data (&sx->inst, GNC_ID_SCHEDXACTION, book);
|
||||
|
||||
@ -387,7 +388,8 @@ xaccSchedXactionInit(SchedXaction *sx, QofBook *book)
|
||||
sx->template_acct = xaccMallocAccount(book);
|
||||
guid = qof_instance_get_guid( sx );
|
||||
xaccAccountBeginEdit( sx->template_acct );
|
||||
xaccAccountSetName( sx->template_acct, guid_to_string( guid ));
|
||||
guid_to_string_buff( guid, guidstr );
|
||||
xaccAccountSetName( sx->template_acct, guidstr);
|
||||
xaccAccountSetCommodity
|
||||
(sx->template_acct,
|
||||
gnc_commodity_table_lookup( gnc_commodity_table_get_table(book),
|
||||
|
@ -1450,8 +1450,10 @@ xaccSplitConvertAmount (const Split *split, const Account * account)
|
||||
xaccAccountGetCommodity(xaccSplitGetAccount(osplit));
|
||||
if (!gnc_commodity_equal(to_commodity, split_comm))
|
||||
{
|
||||
gchar guidstr[GUID_ENCODING_LENGTH+1];
|
||||
guid_to_string_buff(xaccSplitGetGUID(osplit),guidstr);
|
||||
PERR("The split's (%s) amount can't be converted from %s into %s.",
|
||||
guid_to_string(xaccSplitGetGUID(osplit)),
|
||||
guidstr,
|
||||
gnc_commodity_get_mnemonic(split_comm),
|
||||
gnc_commodity_get_mnemonic(to_commodity)
|
||||
);
|
||||
|
@ -971,8 +971,10 @@ xaccTransEqual(const Transaction *ta, const Transaction *tb,
|
||||
|
||||
if (!node_b)
|
||||
{
|
||||
PINFO ("first has split %s and second does not",
|
||||
guid_to_string (xaccSplitGetGUID (split_a)));
|
||||
gchar guidstr[GUID_ENCODING_LENGTH+1];
|
||||
guid_to_string_buff (xaccSplitGetGUID (split_a),guidstr);
|
||||
|
||||
PINFO ("first has split %s and second does not",guidstr);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -266,9 +266,10 @@ GncBillTerm * gncBillTermCreate (QofBook *book)
|
||||
|
||||
void gncBillTermDestroy (GncBillTerm *term)
|
||||
{
|
||||
gchar guidstr[GUID_ENCODING_LENGTH+1];
|
||||
if (!term) return;
|
||||
DEBUG("destroying bill term %s (%p)",
|
||||
guid_to_string(qof_instance_get_guid(&term->inst)), term);
|
||||
guid_to_string_buff(qof_instance_get_guid(&term->inst),guidstr);
|
||||
DEBUG("destroying bill term %s (%p)", guidstr, term);
|
||||
qof_instance_set_destroying(term, TRUE);
|
||||
qof_instance_set_dirty (&term->inst);
|
||||
gncBillTermCommitEdit (term);
|
||||
|
@ -243,7 +243,7 @@ get_random_guid(void)
|
||||
GncGUID *ret;
|
||||
|
||||
ret = g_new(GncGUID, 1);
|
||||
guid_new(ret);
|
||||
guid_replace(ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -90,7 +90,7 @@ test_customer (void)
|
||||
do_test (gncCustomerGetAddr (customer) != NULL, "Addr");
|
||||
do_test (gncCustomerGetShipAddr (customer) != NULL, "ShipAddr");
|
||||
|
||||
guid_new (&guid);
|
||||
guid_replace (&guid);
|
||||
customer = gncCustomerCreate (book);
|
||||
count++;
|
||||
gncCustomerSetGUID (customer, &guid);
|
||||
|
@ -96,7 +96,7 @@ test_employee (void)
|
||||
|
||||
do_test (gncEmployeeGetAddr (employee) != NULL, "Addr");
|
||||
|
||||
guid_new (&guid);
|
||||
guid_replace (&guid);
|
||||
employee = gncEmployeeCreate (book);
|
||||
count++;
|
||||
gncEmployeeSetGUID (employee, &guid);
|
||||
|
@ -42,11 +42,12 @@ static void test_null_guid(void)
|
||||
GncGUID *gp;
|
||||
|
||||
g = guid_new_return();
|
||||
gp = guid_malloc();
|
||||
guid_new(gp);
|
||||
gp = guid_new();
|
||||
|
||||
do_test(guid_equal(guid_null(), guid_null()), "null guids equal");
|
||||
do_test(!guid_equal(&g, gp), "two guids equal");
|
||||
|
||||
guid_free(gp);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -70,7 +71,7 @@ run_test (void)
|
||||
for (i = 0; i < NENT; i++)
|
||||
{
|
||||
ent = g_object_new(QOF_TYPE_INSTANCE, NULL);
|
||||
guid_new(&guid);
|
||||
guid_replace(&guid);
|
||||
ent = g_object_new(QOF_TYPE_INSTANCE, "guid", &guid, NULL);
|
||||
do_test ((NULL == qof_collection_lookup_entity (col, &guid)),
|
||||
"duplicate guid");
|
||||
|
@ -91,7 +91,7 @@ test_job (void)
|
||||
|
||||
test_bool_fcn (book, "Active", gncJobSetActive, gncJobGetActive);
|
||||
|
||||
guid_new (&guid);
|
||||
guid_replace (&guid);
|
||||
job = gncJobCreate (book);
|
||||
count++;
|
||||
gncJobSetGUID (job, &guid);
|
||||
|
@ -96,7 +96,7 @@ test_vendor (void)
|
||||
|
||||
do_test (gncVendorGetAddr (vendor) != NULL, "Addr");
|
||||
|
||||
guid_new (&guid);
|
||||
guid_replace (&guid);
|
||||
vendor = gncVendorCreate (book);
|
||||
count++;
|
||||
gncVendorSetGUID (vendor, &guid);
|
||||
|
@ -974,6 +974,7 @@ test_xaccSplitConvertAmount (void)
|
||||
"GNCXX", "", 1000);
|
||||
gnc_commodity *gnm = gnc_commodity_new (book, "Gnome, Inc.", "NYSE",
|
||||
"GNM", "", 1000);
|
||||
gchar guidstr[GUID_ENCODING_LENGTH+1];
|
||||
|
||||
Account *acc = xaccMallocAccount (book);
|
||||
Account *o_acc = xaccMallocAccount (book);
|
||||
@ -991,7 +992,8 @@ test_xaccSplitConvertAmount (void)
|
||||
TestErrorStruct check = { loglevel, logdomain, NULL, 0 };
|
||||
GLogFunc oldlogger = g_log_set_default_handler ((GLogFunc)test_null_handler, &check);
|
||||
|
||||
check.msg = g_strdup_printf ("[xaccSplitConvertAmount()] The split's (%s) amount can't be converted from GNCXX into GNM.", guid_to_string(xaccSplitGetGUID(o_split)));
|
||||
guid_to_string_buff(xaccSplitGetGUID(o_split), guidstr);
|
||||
check.msg = g_strdup_printf ("[xaccSplitConvertAmount()] The split's (%s) amount can't be converted from GNCXX into GNM.", guidstr);
|
||||
xaccAccountSetCommodity (acc, gnaira);
|
||||
xaccAccountSetCommodity (o_acc, gnaira);
|
||||
xaccAccountSetCommodity (ya_acc, gnm);
|
||||
|
@ -105,7 +105,7 @@ GList * logged_in_users = NULL;
|
||||
*/
|
||||
|
||||
static const char *
|
||||
auth_user (const char * name, const char *passwd)
|
||||
auth_user (const char * name, const char *passwd, char *buff)
|
||||
{
|
||||
GncGUID *guid;
|
||||
const char *session_auth_string;
|
||||
@ -115,11 +115,11 @@ auth_user (const char * name, const char *passwd)
|
||||
*/
|
||||
if (!name || !passwd) return NULL;
|
||||
|
||||
guid = g_new (GncGUID, 1);
|
||||
guid_new (guid);
|
||||
guid = guid_new();
|
||||
logged_in_users = g_list_prepend (logged_in_users, guid);
|
||||
session_auth_string = guid_to_string (guid); /* THREAD UNSAFE */
|
||||
return session_auth_string;
|
||||
|
||||
guid_to_string_buffer (guid, buff);
|
||||
return buff;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -244,6 +244,7 @@ main (int argc, char *argv[])
|
||||
const char *user_agent;
|
||||
const char *auth_string;
|
||||
const char *content_length;
|
||||
gchar guidstr[GUID_ENCODING_LENGTH+1];
|
||||
int read_len = 0;
|
||||
int send_accts = 0;
|
||||
|
||||
@ -301,7 +302,7 @@ main (int argc, char *argv[])
|
||||
char *name = NULL, *passwd = NULL;
|
||||
parse_for_login (request_bufp, &name, &passwd);
|
||||
|
||||
auth_string = auth_user (name, passwd);
|
||||
auth_string = auth_user (name, passwd, guidstr);
|
||||
if (!auth_string)
|
||||
{
|
||||
reject_auth();
|
||||
|
@ -767,7 +767,7 @@ pcd_save_custom_data(PrintCheckDialog *pcd, const gchar *title)
|
||||
multip = pcd_get_custom_multip(pcd);
|
||||
|
||||
key_file = g_key_file_new();
|
||||
guid_new(&guid);
|
||||
guid_replace(&guid);
|
||||
guid_to_string_buff(&guid, buf);
|
||||
g_key_file_set_string(key_file, KF_GROUP_TOP, KF_KEY_GUID, buf);
|
||||
g_key_file_set_string(key_file, KF_GROUP_TOP, KF_KEY_TITLE, title);
|
||||
|
@ -767,7 +767,7 @@ pcd_save_custom_data(PrintCheckDialog *pcd, const gchar *title)
|
||||
multip = pcd_get_custom_multip(pcd);
|
||||
|
||||
key_file = g_key_file_new();
|
||||
guid_new(&guid);
|
||||
guid_replace(&guid);
|
||||
guid_to_string_buff(&guid, buf);
|
||||
g_key_file_set_string(key_file, KF_GROUP_TOP, KF_KEY_GUID, buf);
|
||||
g_key_file_set_string(key_file, KF_GROUP_TOP, KF_KEY_TITLE, title);
|
||||
|
@ -1285,9 +1285,7 @@ schedXact_editor_create_ledger( GncSxEditorDialog *sxed )
|
||||
GtkWidget *main_vbox;
|
||||
|
||||
/* Create the ledger */
|
||||
/* THREAD-UNSAFE */
|
||||
sxed->sxGUIDstr = g_strdup( guid_to_string(
|
||||
xaccSchedXactionGetGUID(sxed->sx) ) );
|
||||
sxed->sxGUIDstr = guid_to_string( xaccSchedXactionGetGUID(sxed->sx) );
|
||||
sxed->ledger = gnc_ledger_display_template_gl( sxed->sxGUIDstr );
|
||||
splitreg = gnc_ledger_display_get_split_register( sxed->ledger );
|
||||
|
||||
|
@ -1276,8 +1276,7 @@ schedXact_editor_create_ledger (GncSxEditorDialog2 *sxed)
|
||||
GtkWidget *label;
|
||||
|
||||
/* Create the ledger */
|
||||
/* THREAD-UNSAFE */
|
||||
sxed->sxGUIDstr = g_strdup (guid_to_string (xaccSchedXactionGetGUID (sxed->sx)));
|
||||
sxed->sxGUIDstr = guid_to_string (xaccSchedXactionGetGUID (sxed->sx));
|
||||
sxed->ledger = gnc_ledger_display2_template_gl (sxed->sxGUIDstr);
|
||||
model = gnc_ledger_display2_get_split_model_register (sxed->ledger);
|
||||
|
||||
|
@ -289,6 +289,7 @@ gbv_create_widget(GncBudgetView *view)
|
||||
GtkTreeIter iter;
|
||||
GtkWidget* h_separator;
|
||||
gchar *state_section;
|
||||
gchar guidstr[GUID_ENCODING_LENGTH+1];
|
||||
|
||||
priv = GNC_BUDGET_VIEW_GET_PRIVATE(view);
|
||||
vbox = GTK_VBOX(view);
|
||||
@ -315,7 +316,8 @@ gbv_create_widget(GncBudgetView *view)
|
||||
tree_view = gnc_tree_view_account_new(FALSE);
|
||||
gtk_container_add(GTK_CONTAINER(inner_scrolled_window), GTK_WIDGET(tree_view));
|
||||
|
||||
state_section = g_strjoin(" ", STATE_SECTION_PREFIX, guid_to_string(&priv->key), NULL);
|
||||
guid_to_string_buff(&priv->key, guidstr);
|
||||
state_section = g_strjoin(" ", STATE_SECTION_PREFIX, guidstr, NULL);
|
||||
g_object_set(G_OBJECT(tree_view), "state-section", state_section, NULL);
|
||||
g_free (state_section);
|
||||
|
||||
@ -487,13 +489,16 @@ void
|
||||
gnc_budget_view_delete_budget(GncBudgetView *view)
|
||||
{
|
||||
GncBudgetViewPrivate *priv;
|
||||
gchar guidstr[GUID_ENCODING_LENGTH+1];
|
||||
|
||||
g_return_if_fail(view != NULL);
|
||||
|
||||
ENTER("view %p", view);
|
||||
|
||||
priv = GNC_BUDGET_VIEW_GET_PRIVATE (view);
|
||||
gnc_state_drop_sections_for (guid_to_string (&priv->key));
|
||||
|
||||
guid_to_string_buff(&priv->key, guidstr);
|
||||
gnc_state_drop_sections_for (guidstr);
|
||||
g_object_set (G_OBJECT (priv->tree_view), "state-section", NULL, NULL);
|
||||
|
||||
LEAVE(" ");
|
||||
|
@ -1397,7 +1397,7 @@ gnc_plugin_page_account_tree_cmd_delete_account (GtkAction *action, GncPluginPag
|
||||
{
|
||||
GList *acct_list, *ptr;
|
||||
const GncGUID *guid;
|
||||
const gchar *guid_str;
|
||||
gchar guidstr[GUID_ENCODING_LENGTH+1];
|
||||
|
||||
gnc_set_busy_cursor(NULL, TRUE);
|
||||
gnc_suspend_gui_refresh ();
|
||||
@ -1435,16 +1435,16 @@ gnc_plugin_page_account_tree_cmd_delete_account (GtkAction *action, GncPluginPag
|
||||
for (ptr = acct_list; ptr; ptr = g_list_next(ptr))
|
||||
{
|
||||
guid = xaccAccountGetGUID (ptr->data);
|
||||
guid_str = guid_to_string (guid);
|
||||
gnc_state_drop_sections_for (guid_str);
|
||||
guid_to_string_buff (guid, guidstr);
|
||||
gnc_state_drop_sections_for (guidstr);
|
||||
}
|
||||
g_list_free(acct_list);
|
||||
|
||||
/* Drop all references from the state file for this account
|
||||
*/
|
||||
guid = xaccAccountGetGUID (account);
|
||||
guid_str = guid_to_string (guid);
|
||||
gnc_state_drop_sections_for (guid_str);
|
||||
guid_to_string_buff (guid, guidstr);
|
||||
gnc_state_drop_sections_for (guidstr);
|
||||
|
||||
/*
|
||||
* Finally, delete the account, any subaccounts it may still
|
||||
|
@ -385,16 +385,15 @@ static
|
||||
void
|
||||
gsr_create_table( GNCSplitReg *gsr )
|
||||
{
|
||||
GtkWidget *register_widget;
|
||||
SplitRegister *sr;
|
||||
GtkWidget *register_widget = NULL;
|
||||
SplitRegister *sr = NULL;
|
||||
|
||||
gchar *state_section;
|
||||
const GncGUID * guid;
|
||||
Account * account;
|
||||
|
||||
account = gnc_ledger_display_leader(gsr->ledger);
|
||||
guid = xaccAccountGetGUID(account);
|
||||
state_section = g_strconcat (STATE_SECTION_REG_PREFIX, " ", (gchar*)guid_to_string (guid), NULL);
|
||||
Account * account = gnc_ledger_display_leader(gsr->ledger);
|
||||
const GncGUID * guid = xaccAccountGetGUID(account);
|
||||
gchar guidstr[GUID_ENCODING_LENGTH+1];
|
||||
gchar *state_section = NULL;
|
||||
guid_to_string_buff(guid, guidstr);
|
||||
state_section = g_strconcat (STATE_SECTION_REG_PREFIX, " ", guidstr, NULL);
|
||||
|
||||
ENTER("gsr=%p", gsr);
|
||||
|
||||
@ -693,13 +692,14 @@ gnc_split_reg_ld_destroy( GNCLedgerDisplay *ledger )
|
||||
{
|
||||
GNCSplitReg *gsr = gnc_ledger_display_get_user_data( ledger );
|
||||
|
||||
Account * account = gnc_ledger_display_leader(ledger);
|
||||
const GncGUID * guid = xaccAccountGetGUID(account);
|
||||
gchar guidstr[GUID_ENCODING_LENGTH+1];
|
||||
gchar *state_section;
|
||||
const GncGUID * guid;
|
||||
Account * account;
|
||||
|
||||
account = gnc_ledger_display_leader(ledger);
|
||||
guid = xaccAccountGetGUID(account);
|
||||
state_section = g_strconcat (STATE_SECTION_REG_PREFIX, " ",(gchar*)guid_to_string (guid), NULL);
|
||||
guid_to_string_buff(guid, guidstr);
|
||||
|
||||
state_section = g_strconcat (STATE_SECTION_REG_PREFIX, " ", guidstr, NULL);
|
||||
|
||||
if (gsr)
|
||||
{
|
||||
|
@ -262,9 +262,17 @@ gsr2_create_table (GNCSplitReg2 *gsr)
|
||||
if (ledger_type == LD2_GL && model->type == GENERAL_LEDGER2)
|
||||
state_section = g_strdup (STATE_SECTION_GEN_LEDGER);
|
||||
else if (ledger_type == LD2_SUBACCOUNT)
|
||||
state_section = g_strconcat (STATE_SECTION_REG_PREFIX, " ", (gchar*)guid_to_string (guid), " w/subaccounts", NULL);
|
||||
{
|
||||
gchar guidstr[GUID_ENCODING_LENGTH+1];
|
||||
guid_to_string_buff (guid, guidstr);
|
||||
state_section = g_strconcat (STATE_SECTION_REG_PREFIX, " ", guidstr, " w/subaccounts", NULL);
|
||||
}
|
||||
else
|
||||
state_section = g_strconcat (STATE_SECTION_REG_PREFIX, " ", (gchar*)guid_to_string (guid), NULL);
|
||||
{
|
||||
gchar guidstr[GUID_ENCODING_LENGTH+1];
|
||||
guid_to_string_buff (guid, guidstr);
|
||||
state_section = g_strconcat (STATE_SECTION_REG_PREFIX, " ", guidstr, NULL);
|
||||
}
|
||||
g_object_set (G_OBJECT (view), "state-section", state_section,
|
||||
"show-column-menu", FALSE, NULL);
|
||||
|
||||
@ -680,31 +688,6 @@ gsr2_redraw_all_cb (GncTreeViewSplitReg *view, gpointer user_data)
|
||||
static void
|
||||
gnc_split_reg2_ld_destroy (GNCLedgerDisplay2 *ledger)
|
||||
{
|
||||
GNCSplitReg2 *gsr = gnc_ledger_display2_get_user_data (ledger);
|
||||
|
||||
gchar *state_key;
|
||||
const GncGUID * guid;
|
||||
Account * account;
|
||||
|
||||
account = gnc_ledger_display2_leader (ledger);
|
||||
guid = xaccAccountGetGUID (account);
|
||||
state_key = (gchar*)guid_to_string (guid);
|
||||
|
||||
if (gsr)
|
||||
{
|
||||
GncTreeModelSplitReg *model;
|
||||
|
||||
model = gnc_ledger_display2_get_split_model_register (ledger);
|
||||
|
||||
/*FIXME This may not be required
|
||||
if (model && model->table)
|
||||
gnc_table_save_state (model->table, state_key);
|
||||
*/
|
||||
/*
|
||||
* Don't destroy the window here any more. The register no longer
|
||||
* owns it.
|
||||
*/
|
||||
}
|
||||
gnc_ledger_display2_set_user_data (ledger, NULL);
|
||||
}
|
||||
|
||||
|
@ -309,7 +309,7 @@ static void
|
||||
gnc_save_all_state (gpointer session, gpointer unused)
|
||||
{
|
||||
QofBook *book;
|
||||
const gchar *guid_string;
|
||||
gchar guid_string[GUID_ENCODING_LENGTH+1];
|
||||
const GncGUID *guid;
|
||||
GError *error = NULL;
|
||||
GKeyFile *keyfile = NULL;
|
||||
@ -338,7 +338,7 @@ gnc_save_all_state (gpointer session, gpointer unused)
|
||||
/* Store the book's GncGUID in the top level group */
|
||||
book = qof_session_get_book(session);
|
||||
guid = qof_entity_get_guid(QOF_INSTANCE(book));
|
||||
guid_string = guid_to_string(guid);
|
||||
guid_to_string_buff(guid, guid_string);
|
||||
g_key_file_set_string(keyfile, STATE_FILE_TOP, STATE_FILE_BOOK_GUID,
|
||||
guid_string);
|
||||
|
||||
|
@ -43,7 +43,6 @@
|
||||
#include "gnc-prefs.h"
|
||||
#include "gnc-ui.h"
|
||||
#include "gnc-plugin-aqbanking.h"
|
||||
#include "md5.h"
|
||||
#include "qof.h"
|
||||
|
||||
#if GWENHYWFAR_VERSION_INT >= 39921
|
||||
@ -1492,10 +1491,10 @@ checkcert_cb(GWEN_GUI *gwen_gui, const GWEN_SSLCERTDESCR *cert,
|
||||
{
|
||||
GncGWENGui *gui = GETDATA_GUI(gwen_gui);
|
||||
const gchar *hash, *status;
|
||||
struct md5_ctx md5_context;
|
||||
GChecksum *gcheck = g_checksum_new (G_CHECKSUM_MD5);
|
||||
gchar cert_hash[16];
|
||||
gchar *cert_hash_hex;
|
||||
gint retval, i;
|
||||
gsize hashlen = 0;
|
||||
|
||||
g_return_val_if_fail(gui && gui->accepted_certs, -1);
|
||||
|
||||
@ -1504,25 +1503,19 @@ checkcert_cb(GWEN_GUI *gwen_gui, const GWEN_SSLCERTDESCR *cert,
|
||||
hash = GWEN_SslCertDescr_GetFingerPrint(cert);
|
||||
status = GWEN_SslCertDescr_GetStatusText(cert);
|
||||
|
||||
/* Operate on an md5sum of the pair of hash and status */
|
||||
md5_init_ctx(&md5_context);
|
||||
md5_process_bytes(hash, strlen(hash), &md5_context);
|
||||
md5_process_bytes(status, strlen(status), &md5_context);
|
||||
md5_finish_ctx(&md5_context, cert_hash);
|
||||
g_checksum_update (gcheck, hash, strlen (hash));
|
||||
g_checksum_update (gcheck, status, strlen (status));
|
||||
|
||||
/* Did we get the permanently accepted certs from AqBanking? */
|
||||
if (gui->permanently_accepted_certs)
|
||||
{
|
||||
/* Generate a hex string of the cert_hash for usage by AqBanking cert store */
|
||||
cert_hash_hex = g_new0(gchar, 33);
|
||||
for (i = 0; i < 16; i++)
|
||||
g_snprintf(cert_hash_hex + 2 * i, 3, "%02X", (unsigned char)cert_hash[i]);
|
||||
|
||||
retval = GWEN_DB_GetIntValue(gui->permanently_accepted_certs, cert_hash_hex, 0, -1);
|
||||
g_free(cert_hash_hex);
|
||||
retval = GWEN_DB_GetIntValue(gui->permanently_accepted_certs,
|
||||
g_checksum_get_string (gcheck), 0, -1);
|
||||
if (retval == 0)
|
||||
{
|
||||
/* Certificate is marked as accepted in AqBanking's cert store */
|
||||
g_checksum_free (gcheck);
|
||||
LEAVE("Certificate accepted by AqBanking's permanent cert store");
|
||||
return 0;
|
||||
}
|
||||
@ -1532,6 +1525,10 @@ checkcert_cb(GWEN_GUI *gwen_gui, const GWEN_SSLCERTDESCR *cert,
|
||||
g_warning("Can't check permanently accepted certs from invalid AqBanking cert store.");
|
||||
}
|
||||
|
||||
g_checksum_get_digest (gcheck, cert_hash, &hashlen);
|
||||
g_checksum_free (gcheck);
|
||||
g_assert (hashlen <= sizeof (cert_hash));
|
||||
|
||||
if (g_hash_table_lookup(gui->accepted_certs, cert_hash))
|
||||
{
|
||||
/* Certificate has been accepted by Gnucash before */
|
||||
|
@ -284,11 +284,13 @@ static void dump_split_record(split_record record)
|
||||
}
|
||||
if (record.trans_guid_present)
|
||||
{
|
||||
DEBUG("Transaction GncGUID: %s", guid_to_string (&(record.trans_guid)));
|
||||
guid_to_string_buff(&record.trans_guid, string_buf);
|
||||
DEBUG("Transaction GncGUID: %s", string_buf);
|
||||
}
|
||||
if (record.split_guid_present)
|
||||
{
|
||||
DEBUG("Split GncGUID: %s", guid_to_string (&(record.split_guid)));
|
||||
guid_to_string_buff(&record.split_guid, string_buf);
|
||||
DEBUG("Split GncGUID: %s", string_buf);
|
||||
}
|
||||
if (record.log_date_present)
|
||||
{
|
||||
@ -307,7 +309,8 @@ static void dump_split_record(split_record record)
|
||||
}
|
||||
if (record.acc_guid_present)
|
||||
{
|
||||
DEBUG("Account GncGUID: %s", guid_to_string (&(record.acc_guid)));
|
||||
guid_to_string_buff(&record.trans_guid, string_buf);
|
||||
DEBUG("Account GncGUID: %s", string_buf);
|
||||
}
|
||||
if (record.acc_name_present)
|
||||
{
|
||||
|
@ -75,7 +75,6 @@ qofinclude_HEADERS = \
|
||||
qof-gobject.h
|
||||
|
||||
noinst_HEADERS = \
|
||||
md5.h \
|
||||
qofbook-p.h \
|
||||
qofclass-p.h \
|
||||
qofevent-p.h \
|
||||
@ -84,14 +83,6 @@ noinst_HEADERS = \
|
||||
qofquery-p.h \
|
||||
qofquerycore-p.h \
|
||||
qofsession-p.h
|
||||
|
||||
# Must compile md5.c without strict aliasing, otherwise function md5_finish_ctx
|
||||
# gets "dereferencing type-punned pointer will break strict-aliasing rules"
|
||||
noinst_LTLIBRARIES = libmd5.la
|
||||
libmd5_la_SOURCES = md5.c
|
||||
libmd5_la_CFLAGS = ${AM_CFLAGS} -fno-strict-aliasing
|
||||
|
||||
libgnc_qof_la_LIBADD += libmd5.la
|
||||
|
||||
EXTRA_DIST += \
|
||||
qofmath128.cpp
|
||||
|
@ -1,6 +1,7 @@
|
||||
/********************************************************************\
|
||||
* guid.c -- globally unique ID implementation *
|
||||
* Copyright (C) 2000 Dave Peticolas <peticola@cs.ucdavis.edu> *
|
||||
* Copyright (C) 2014 Aaron Laws <dartmetrash@gmail.com> *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License as *
|
||||
@ -21,10 +22,8 @@
|
||||
* *
|
||||
\********************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
@ -51,32 +50,17 @@ extern "C"
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
#include "qof.h"
|
||||
#include "md5.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#include <boost/uuid/uuid.hpp>
|
||||
#include <boost/uuid/uuid_generators.hpp>
|
||||
#include <boost/uuid/uuid_io.hpp>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
# ifndef P_tmpdir
|
||||
# define P_tmpdir "/tmp"
|
||||
# endif
|
||||
using namespace std;
|
||||
|
||||
/* Constants *******************************************************/
|
||||
#define DEBUG_GUID 0
|
||||
#define BLOCKSIZE 4096
|
||||
#ifdef G_PLATFORM_WIN32
|
||||
/* Win32 has a smaller pool of random bits, but the displayed warning confuses
|
||||
* really a lot of people. Hence, I think we'd better switch off this warning
|
||||
* for this particular known case. */
|
||||
# define THRESHOLD 1500
|
||||
#else
|
||||
# define THRESHOLD (2 * BLOCKSIZE)
|
||||
#endif
|
||||
|
||||
|
||||
/* Static global variables *****************************************/
|
||||
static gboolean guid_initialized = FALSE;
|
||||
static struct md5_ctx guid_context;
|
||||
typedef boost::uuids::uuid gg;
|
||||
|
||||
/* This static indicates the debugging module that this .o belongs to. */
|
||||
static QofLogModule log_module = QOF_MOD_ENGINE;
|
||||
@ -101,12 +85,22 @@ gnc_value_get_guid (const GValue *value)
|
||||
return val;
|
||||
}
|
||||
|
||||
static GncGUID * nullguid {reinterpret_cast<GncGUID*> (new boost::uuids::uuid{{0}})};
|
||||
|
||||
/*It looks like we are expected to provide the same pointer every time from this function*/
|
||||
const GncGUID *
|
||||
guid_null (void)
|
||||
{
|
||||
return nullguid;
|
||||
}
|
||||
|
||||
/* Memory management routines ***************************************/
|
||||
|
||||
GncGUID *
|
||||
guid_malloc (void)
|
||||
{
|
||||
return g_slice_new(GncGUID);
|
||||
/*Note, the Boost uuid is a POD, so its constructor is trivial*/
|
||||
return reinterpret_cast<GncGUID*> (new boost::uuids::uuid);
|
||||
}
|
||||
|
||||
void
|
||||
@ -114,634 +108,128 @@ guid_free (GncGUID *guid)
|
||||
{
|
||||
if (!guid)
|
||||
return;
|
||||
|
||||
g_slice_free(GncGUID, guid);
|
||||
if (guid == nullguid)
|
||||
/*!!Don't delete that!!*/
|
||||
return;
|
||||
delete reinterpret_cast<boost::uuids::uuid*> (guid);
|
||||
guid = nullptr;
|
||||
}
|
||||
|
||||
|
||||
GncGUID *
|
||||
guid_copy (const GncGUID *guid)
|
||||
{
|
||||
GncGUID *copy;
|
||||
|
||||
g_return_val_if_fail(guid, NULL);
|
||||
copy = guid_malloc();
|
||||
*copy = *guid;
|
||||
return copy;
|
||||
}
|
||||
|
||||
const GncGUID *
|
||||
guid_null(void)
|
||||
{
|
||||
static int null_inited = 0;
|
||||
static GncGUID null_guid;
|
||||
|
||||
if (!null_inited)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < GUID_DATA_SIZE; i++)
|
||||
null_guid.data[i] = '\0';
|
||||
|
||||
null_inited = 1;
|
||||
}
|
||||
|
||||
return &null_guid;
|
||||
}
|
||||
|
||||
/* Function implementations ****************************************/
|
||||
|
||||
/* This code is based on code in md5.c in GNU textutils. */
|
||||
static size_t
|
||||
init_from_stream(FILE *stream, size_t max_size)
|
||||
{
|
||||
char buffer[BLOCKSIZE + 72];
|
||||
size_t sum, block_size, total;
|
||||
|
||||
ENTER("");
|
||||
|
||||
if (max_size <= 0)
|
||||
{
|
||||
LEAVE("max_size is 0 or less, skipping stream");
|
||||
return 0;
|
||||
}
|
||||
|
||||
total = 0;
|
||||
|
||||
/* Iterate over file contents. */
|
||||
while (1)
|
||||
{
|
||||
/* We read the file in blocks of BLOCKSIZE bytes. One call of the
|
||||
* computation function processes the whole buffer so that with the
|
||||
* next round of the loop another block can be read. */
|
||||
size_t n;
|
||||
sum = 0;
|
||||
|
||||
if (max_size < BLOCKSIZE)
|
||||
block_size = max_size;
|
||||
else
|
||||
block_size = BLOCKSIZE;
|
||||
|
||||
/* Read block. Take care for partial reads. */
|
||||
do
|
||||
{
|
||||
n = fread (buffer + sum, 1, block_size - sum, stream);
|
||||
|
||||
sum += n;
|
||||
}
|
||||
while (sum < block_size && n != 0);
|
||||
|
||||
max_size -= sum;
|
||||
|
||||
if (n == 0 && ferror (stream))
|
||||
{
|
||||
LEAVE("error while reading stream");
|
||||
return total;
|
||||
}
|
||||
|
||||
/* If end of file or max_size is reached, end the loop. */
|
||||
if ((n == 0) || (max_size == 0))
|
||||
break;
|
||||
|
||||
/* Process buffer with BLOCKSIZE bytes. Note that
|
||||
* BLOCKSIZE % 64 == 0 */
|
||||
md5_process_block (buffer, BLOCKSIZE, &guid_context);
|
||||
|
||||
total += sum;
|
||||
}
|
||||
|
||||
/* Add the last bytes if necessary. */
|
||||
if (sum > 0)
|
||||
{
|
||||
md5_process_bytes (buffer, sum, &guid_context);
|
||||
total += sum;
|
||||
}
|
||||
|
||||
LEAVE("");
|
||||
return total;
|
||||
}
|
||||
|
||||
static size_t
|
||||
init_from_file(const char *filename, size_t max_size)
|
||||
{
|
||||
struct stat stats;
|
||||
size_t total = 0;
|
||||
size_t file_bytes;
|
||||
FILE *fp;
|
||||
|
||||
ENTER("filename: %s", filename);
|
||||
|
||||
memset(&stats, 0, sizeof(stats));
|
||||
if (g_stat(filename, &stats) != 0)
|
||||
{
|
||||
LEAVE("unable to read file stats on %s", filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
md5_process_bytes(&stats, sizeof(stats), &guid_context);
|
||||
total += sizeof(stats);
|
||||
|
||||
if (max_size <= 0)
|
||||
{
|
||||
LEAVE("no bytes in file %s", filename);
|
||||
return total;
|
||||
}
|
||||
|
||||
fp = g_fopen (filename, "r");
|
||||
if (fp == NULL)
|
||||
{
|
||||
LEAVE("unable to open file %s", filename);
|
||||
return total;
|
||||
}
|
||||
|
||||
file_bytes = init_from_stream(fp, max_size);
|
||||
|
||||
#ifdef HAVE_SCANF_LLD
|
||||
PINFO ("guid_init got %" G_GUINT64_FORMAT " bytes from %s",
|
||||
(guint64) file_bytes,
|
||||
filename);
|
||||
#else
|
||||
PINFO ("guid_init got %lu bytes from %s", (unsigned long int) file_bytes,
|
||||
filename);
|
||||
#endif
|
||||
|
||||
total += file_bytes;
|
||||
|
||||
fclose(fp);
|
||||
|
||||
LEAVE("file %s processed successfully", filename);
|
||||
return total;
|
||||
}
|
||||
|
||||
static size_t
|
||||
init_from_dir(const char *dirname, unsigned int max_files)
|
||||
{
|
||||
char filename[1024];
|
||||
const gchar *de;
|
||||
struct stat stats;
|
||||
size_t total;
|
||||
int result;
|
||||
GDir *dir;
|
||||
|
||||
ENTER("dirname: %s", dirname);
|
||||
if (max_files <= 0)
|
||||
{
|
||||
LEAVE("max_files is 0 or less, skipping directory %s", dirname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
dir = g_dir_open(dirname, 0, NULL);
|
||||
if (dir == NULL)
|
||||
{
|
||||
LEAVE("unable to open directory %s", dirname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
total = 0;
|
||||
|
||||
do
|
||||
{
|
||||
de = g_dir_read_name(dir);
|
||||
if (de == NULL)
|
||||
break;
|
||||
|
||||
md5_process_bytes(de, strlen(de), &guid_context);
|
||||
total += strlen(de);
|
||||
|
||||
result = g_snprintf(filename, sizeof(filename),
|
||||
"%s/%s", dirname, de);
|
||||
if ((result < 0) || (result >= (int)sizeof(filename)))
|
||||
continue;
|
||||
|
||||
memset(&stats, 0, sizeof(stats));
|
||||
if (g_stat(filename, &stats) != 0)
|
||||
continue;
|
||||
md5_process_bytes(&stats, sizeof(stats), &guid_context);
|
||||
total += sizeof(stats);
|
||||
|
||||
max_files--;
|
||||
}
|
||||
while (max_files > 0);
|
||||
|
||||
g_dir_close(dir);
|
||||
|
||||
LEAVE("");
|
||||
return total;
|
||||
}
|
||||
|
||||
static size_t
|
||||
init_from_time(void)
|
||||
{
|
||||
size_t total;
|
||||
time64 time;
|
||||
#ifdef HAVE_SYS_TIMES_H
|
||||
clock_t clocks;
|
||||
struct tms tms_buf;
|
||||
#endif
|
||||
|
||||
ENTER("");
|
||||
|
||||
total = 0;
|
||||
|
||||
time = gnc_time (NULL);
|
||||
md5_process_bytes(&time, sizeof(time), &guid_context);
|
||||
total += sizeof(time);
|
||||
|
||||
#ifdef HAVE_SYS_TIMES_H
|
||||
clocks = times(&tms_buf);
|
||||
md5_process_bytes(&clocks, sizeof(clocks), &guid_context);
|
||||
md5_process_bytes(&tms_buf, sizeof(tms_buf), &guid_context);
|
||||
total += sizeof(clocks) + sizeof(tms_buf);
|
||||
#endif
|
||||
|
||||
LEAVE("");
|
||||
return total;
|
||||
}
|
||||
|
||||
static size_t
|
||||
init_from_int(int val)
|
||||
{
|
||||
ENTER("");
|
||||
md5_process_bytes(&val, sizeof(val), &guid_context);
|
||||
LEAVE("");
|
||||
return sizeof(int);
|
||||
}
|
||||
|
||||
static size_t
|
||||
init_from_buff(unsigned char * buf, size_t buflen)
|
||||
{
|
||||
ENTER("");
|
||||
md5_process_bytes(buf, buflen, &guid_context);
|
||||
LEAVE("");
|
||||
return buflen;
|
||||
const boost::uuids::uuid * old {reinterpret_cast<const boost::uuids::uuid*> (guid)};
|
||||
boost::uuids::uuid * ret {new boost::uuids::uuid (*old)};
|
||||
return reinterpret_cast<GncGUID*> (ret);
|
||||
}
|
||||
|
||||
/*Takes an allocated guid pointer and constructs it in place*/
|
||||
void
|
||||
guid_init(void)
|
||||
guid_replace (GncGUID *guid)
|
||||
{
|
||||
size_t bytes = 0;
|
||||
|
||||
ENTER("");
|
||||
|
||||
/* Not needed; taken care of on first malloc.
|
||||
* guid_memchunk_init(); */
|
||||
|
||||
md5_init_ctx(&guid_context);
|
||||
|
||||
/* entropy pool
|
||||
* FIXME /dev/urandom doesn't exist on Windows. We should
|
||||
* use the Windows native CryptGenRandom or RtlGenRandom
|
||||
* functions. See
|
||||
* http://en.wikipedia.org/wiki/CryptGenRandom */
|
||||
bytes += init_from_file ("/dev/urandom", 512);
|
||||
|
||||
/* files
|
||||
* FIXME none of these directories make sense on
|
||||
* Windows. We should figure out some proper
|
||||
* alternatives there. */
|
||||
{
|
||||
const char * files[] =
|
||||
{
|
||||
"/etc/passwd",
|
||||
"/proc/loadavg",
|
||||
"/proc/meminfo",
|
||||
"/proc/net/dev",
|
||||
"/proc/rtc",
|
||||
"/proc/self/environ",
|
||||
"/proc/self/stat",
|
||||
"/proc/stat",
|
||||
"/proc/uptime",
|
||||
NULL
|
||||
};
|
||||
int i;
|
||||
|
||||
for (i = 0; files[i] != NULL; i++)
|
||||
bytes += init_from_file(files[i], BLOCKSIZE);
|
||||
}
|
||||
|
||||
/* directories
|
||||
* Note: P_tmpdir is set to "\" by mingw (Windows) This seems to
|
||||
* trigger unwanted network access attempts (see bug #521817).
|
||||
* So on Windows we explicitly set the temporary directory.
|
||||
* FIXME other than "c:/temp" none of these directories make sense on
|
||||
* Windows. We should figure out some proper
|
||||
* alternatives there. */
|
||||
{
|
||||
const char * dirname;
|
||||
const char * dirs[] =
|
||||
{
|
||||
"/proc",
|
||||
#ifndef G_OS_WIN32
|
||||
P_tmpdir,
|
||||
#else
|
||||
"c:/temp",
|
||||
#endif
|
||||
"/var/lock",
|
||||
"/var/log",
|
||||
"/var/mail",
|
||||
"/var/spool/mail",
|
||||
"/var/run",
|
||||
NULL
|
||||
};
|
||||
int i;
|
||||
|
||||
for (i = 0; dirs[i] != NULL; i++)
|
||||
bytes += init_from_dir(dirs[i], 32);
|
||||
|
||||
dirname = g_get_home_dir();
|
||||
if (dirname != NULL)
|
||||
bytes += init_from_dir(dirname, 32);
|
||||
}
|
||||
|
||||
/* process and parent ids */
|
||||
{
|
||||
#ifdef HAVE_UNISTD_H
|
||||
pid_t pid;
|
||||
|
||||
pid = getpid();
|
||||
md5_process_bytes(&pid, sizeof(pid), &guid_context);
|
||||
bytes += sizeof(pid);
|
||||
|
||||
#ifdef HAVE_GETPPID
|
||||
pid = getppid();
|
||||
md5_process_bytes(&pid, sizeof(pid), &guid_context);
|
||||
bytes += sizeof(pid);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
/* user info */
|
||||
{
|
||||
#ifdef HAVE_GETUID
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
char *s;
|
||||
|
||||
s = getlogin();
|
||||
if (s != NULL)
|
||||
{
|
||||
md5_process_bytes(s, strlen(s), &guid_context);
|
||||
bytes += strlen(s);
|
||||
}
|
||||
|
||||
uid = getuid();
|
||||
md5_process_bytes(&uid, sizeof(uid), &guid_context);
|
||||
bytes += sizeof(uid);
|
||||
|
||||
gid = getgid();
|
||||
md5_process_bytes(&gid, sizeof(gid), &guid_context);
|
||||
bytes += sizeof(gid);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* host info */
|
||||
{
|
||||
#ifdef HAVE_GETHOSTNAME
|
||||
char string[1024];
|
||||
|
||||
memset(string, 0, sizeof(string));
|
||||
gethostname(string, sizeof(string));
|
||||
md5_process_bytes(string, sizeof(string), &guid_context);
|
||||
bytes += sizeof(string);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* plain old random */
|
||||
{
|
||||
int n, i;
|
||||
|
||||
srand((unsigned int) gnc_time (NULL));
|
||||
|
||||
for (i = 0; i < 32; i++)
|
||||
{
|
||||
n = rand();
|
||||
|
||||
md5_process_bytes(&n, sizeof(n), &guid_context);
|
||||
bytes += sizeof(n);
|
||||
}
|
||||
}
|
||||
|
||||
/* time in secs and clock ticks */
|
||||
bytes += init_from_time();
|
||||
|
||||
PINFO ("got %" G_GUINT64_FORMAT " bytes", (guint64) bytes);
|
||||
|
||||
if (bytes < THRESHOLD)
|
||||
PWARN("only got %" G_GUINT64_FORMAT " bytes.\n"
|
||||
"The identifiers might not be very random.\n",
|
||||
(guint64)bytes);
|
||||
|
||||
guid_initialized = TRUE;
|
||||
LEAVE();
|
||||
static boost::uuids::random_generator gen;
|
||||
boost::uuids::uuid * val {reinterpret_cast<boost::uuids::uuid*> (guid)};
|
||||
val->boost::uuids::uuid::~uuid ();
|
||||
boost::uuids::uuid temp (gen ());
|
||||
val->swap (temp);
|
||||
}
|
||||
|
||||
void
|
||||
guid_shutdown (void)
|
||||
GncGUID *
|
||||
guid_new (void)
|
||||
{
|
||||
}
|
||||
|
||||
#define GUID_PERIOD 5000
|
||||
|
||||
void
|
||||
guid_new(GncGUID *guid)
|
||||
{
|
||||
static int counter = 0;
|
||||
struct md5_ctx ctx;
|
||||
|
||||
if (guid == NULL)
|
||||
return;
|
||||
|
||||
if (!guid_initialized)
|
||||
guid_init();
|
||||
|
||||
/* make the id */
|
||||
ctx = guid_context;
|
||||
md5_finish_ctx(&ctx, guid->data);
|
||||
|
||||
/* update the global context */
|
||||
init_from_time();
|
||||
|
||||
/* Make it a little extra salty. I think init_from_time was buggy,
|
||||
* or something, since duplicate id's actually happened. Or something
|
||||
* like that. I think this is because init_from_time kept returning
|
||||
* the same values too many times in a row. So we'll do some 'block
|
||||
* chaining', and feed in the old guid as new random data.
|
||||
*
|
||||
* Anyway, I think the whole fact that I saw a bunch of duplicate
|
||||
* id's at one point, but can't reproduce the bug is rather alarming.
|
||||
* Something must be broken somewhere, and merely adding more salt
|
||||
* is just hiding the problem, not fixing it.
|
||||
*/
|
||||
init_from_int (433781 * counter);
|
||||
init_from_buff (guid->data, GUID_DATA_SIZE);
|
||||
|
||||
if (counter == 0)
|
||||
{
|
||||
FILE *fp;
|
||||
|
||||
fp = g_fopen ("/dev/urandom", "r");
|
||||
if (fp == NULL)
|
||||
return;
|
||||
|
||||
init_from_stream(fp, 32);
|
||||
|
||||
fclose(fp);
|
||||
|
||||
counter = GUID_PERIOD;
|
||||
}
|
||||
|
||||
counter--;
|
||||
GncGUID * ret {guid_malloc ()};
|
||||
guid_replace (ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
GncGUID
|
||||
guid_new_return(void)
|
||||
guid_new_return (void)
|
||||
{
|
||||
GncGUID guid;
|
||||
|
||||
guid_new (&guid);
|
||||
|
||||
return guid;
|
||||
/*we need to construct our value as a boost guid so that
|
||||
it can be deconstructed (in place) in guid_replace*/
|
||||
boost::uuids::uuid guid;
|
||||
GncGUID * ret {reinterpret_cast<GncGUID*> (&guid)};
|
||||
guid_replace (ret);
|
||||
/*return a copy*/
|
||||
return *ret;
|
||||
}
|
||||
|
||||
/* needs 32 bytes exactly, doesn't print a null char */
|
||||
static void
|
||||
encode_md5_data(const unsigned char *data, char *buffer)
|
||||
gchar *
|
||||
guid_to_string (const GncGUID * guid)
|
||||
{
|
||||
size_t count;
|
||||
|
||||
for (count = 0; count < GUID_DATA_SIZE; count++, buffer += 2)
|
||||
sprintf(buffer, "%02x", data[count]);
|
||||
/* We need to malloc here, not 'new' because it will be freed
|
||||
by the caller which will use free (not delete).*/
|
||||
gchar * ret {reinterpret_cast<gchar*> (g_malloc (sizeof (gchar)*GUID_ENCODING_LENGTH+1))};
|
||||
gchar * temp {guid_to_string_buff (guid, ret)};
|
||||
if (!temp){
|
||||
g_free (ret);
|
||||
return nullptr;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* returns true if the first 32 bytes of buffer encode
|
||||
* a hex number. returns false otherwise. Decoded number
|
||||
* is packed into data in little endian order. */
|
||||
static gboolean
|
||||
decode_md5_string(const gchar *string, unsigned char *data)
|
||||
gchar *
|
||||
guid_to_string_buff (const GncGUID * guid, gchar *str)
|
||||
{
|
||||
unsigned char n1, n2;
|
||||
size_t count = -1;
|
||||
unsigned char c1, c2;
|
||||
if (!str || !guid) return NULL;
|
||||
|
||||
if (NULL == data) return FALSE;
|
||||
if (NULL == string) goto badstring;
|
||||
boost::uuids::uuid const & tempg = *reinterpret_cast<boost::uuids::uuid const *> (guid);
|
||||
unsigned destspot {0};
|
||||
string const & val {to_string (tempg)};
|
||||
for (auto val_char : val)
|
||||
if (val_char != '-')
|
||||
str [destspot++] = val_char;
|
||||
|
||||
for (count = 0; count < GUID_DATA_SIZE; count++)
|
||||
{
|
||||
/* check for a short string e.g. null string ... */
|
||||
if ((0 == string[2*count]) || (0 == string[2*count+1])) goto badstring;
|
||||
|
||||
c1 = tolower(string[2 * count]);
|
||||
if (!isxdigit(c1)) goto badstring;
|
||||
|
||||
c2 = tolower(string[2 * count + 1]);
|
||||
if (!isxdigit(c2)) goto badstring;
|
||||
|
||||
if (isdigit(c1))
|
||||
n1 = c1 - '0';
|
||||
else
|
||||
n1 = c1 - 'a' + 10;
|
||||
|
||||
if (isdigit(c2))
|
||||
n2 = c2 - '0';
|
||||
else
|
||||
n2 = c2 - 'a' + 10;
|
||||
|
||||
data[count] = (n1 << 4) | n2;
|
||||
}
|
||||
return TRUE;
|
||||
|
||||
badstring:
|
||||
for (count = 0; count < GUID_DATA_SIZE; count++)
|
||||
{
|
||||
data[count] = 0;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Allocate the key */
|
||||
|
||||
const char *
|
||||
guid_to_string(const GncGUID * guid)
|
||||
{
|
||||
#ifdef G_THREADS_ENABLED
|
||||
#ifndef HAVE_GLIB_2_32
|
||||
static GStaticPrivate guid_buffer_key = G_STATIC_PRIVATE_INIT;
|
||||
gchar *string;
|
||||
|
||||
string = static_cast<gchar*>(g_static_private_get (&guid_buffer_key));
|
||||
if (string == NULL)
|
||||
{
|
||||
string = static_cast<gchar*>(malloc(GUID_ENCODING_LENGTH + 1));
|
||||
g_static_private_set (&guid_buffer_key, string, g_free);
|
||||
}
|
||||
#else
|
||||
static GPrivate guid_buffer_key = G_PRIVATE_INIT(g_free);
|
||||
gchar *string;
|
||||
|
||||
string = static_cast<char*>(g_private_get (&guid_buffer_key));
|
||||
if (string == NULL)
|
||||
{
|
||||
string = static_cast<char*>(malloc(GUID_ENCODING_LENGTH + 1));
|
||||
g_private_set (&guid_buffer_key, string);
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
static char string[64];
|
||||
#endif
|
||||
|
||||
encode_md5_data(guid->data, string);
|
||||
string[GUID_ENCODING_LENGTH] = '\0';
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
char *
|
||||
guid_to_string_buff(const GncGUID * guid, char *string)
|
||||
{
|
||||
if (!string || !guid) return NULL;
|
||||
|
||||
encode_md5_data(guid->data, string);
|
||||
|
||||
string[GUID_ENCODING_LENGTH] = '\0';
|
||||
return &string[GUID_ENCODING_LENGTH];
|
||||
str[GUID_ENCODING_LENGTH] = '\0';
|
||||
return &str[GUID_ENCODING_LENGTH];
|
||||
}
|
||||
|
||||
gboolean
|
||||
string_to_guid(const char * string, GncGUID * guid)
|
||||
string_to_guid (const char * str, GncGUID * guid)
|
||||
{
|
||||
return decode_md5_string(string, (guid != NULL) ? guid->data : NULL);
|
||||
if (!guid || !str)
|
||||
return false;
|
||||
|
||||
try
|
||||
{
|
||||
static boost::uuids::string_generator strgen;
|
||||
boost::uuids::uuid * converted {reinterpret_cast<boost::uuids::uuid*> (guid)};
|
||||
new (converted) boost::uuids::uuid (strgen (str));
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
gboolean
|
||||
guid_equal(const GncGUID *guid_1, const GncGUID *guid_2)
|
||||
guid_equal (const GncGUID *guid_1, const GncGUID *guid_2)
|
||||
{
|
||||
if (guid_1 && guid_2)
|
||||
return (memcmp(guid_1, guid_2, GUID_DATA_SIZE) == 0);
|
||||
else
|
||||
return FALSE;
|
||||
if (!guid_1 || !guid_2)
|
||||
return false;
|
||||
boost::uuids::uuid const * g1 {reinterpret_cast<boost::uuids::uuid const *> (guid_1)};
|
||||
boost::uuids::uuid const * g2 {reinterpret_cast<boost::uuids::uuid const *> (guid_2)};
|
||||
return *g1 == *g2;
|
||||
}
|
||||
|
||||
gint
|
||||
guid_compare(const GncGUID *guid_1, const GncGUID *guid_2)
|
||||
guid_compare (const GncGUID *guid_1, const GncGUID *guid_2)
|
||||
{
|
||||
if (guid_1 == guid_2)
|
||||
return 0;
|
||||
|
||||
/* nothing is always less than something */
|
||||
if (!guid_1 && guid_2)
|
||||
boost::uuids::uuid const * g1 {reinterpret_cast<boost::uuids::uuid const *> (guid_1)};
|
||||
boost::uuids::uuid const * g2 {reinterpret_cast<boost::uuids::uuid const *> (guid_2)};
|
||||
if (*g1 < *g2)
|
||||
return -1;
|
||||
|
||||
if (guid_1 && !guid_2)
|
||||
return 1;
|
||||
|
||||
return memcmp (guid_1, guid_2, GUID_DATA_SIZE);
|
||||
if (*g1 == *g2)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
guint
|
||||
guid_hash_to_guint (gconstpointer ptr)
|
||||
{
|
||||
const GncGUID *guid = static_cast<const GncGUID*>(ptr);
|
||||
const boost::uuids::uuid * guid = reinterpret_cast<const boost::uuids::uuid*> (ptr);
|
||||
|
||||
if (!guid)
|
||||
{
|
||||
@ -749,33 +237,21 @@ guid_hash_to_guint (gconstpointer ptr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (sizeof(guint) <= sizeof(guid->data))
|
||||
guint hash {0};
|
||||
unsigned retspot {0};
|
||||
for (auto guidspot : *guid)
|
||||
{
|
||||
const guint* ptr_data = (const guint *) guid->data;
|
||||
return (*ptr_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
guint hash = 0;
|
||||
unsigned int i, j;
|
||||
|
||||
for (i = 0, j = 0; i < sizeof(guint); i++, j++)
|
||||
{
|
||||
if (j == GUID_DATA_SIZE) j = 0;
|
||||
|
||||
hash <<= 4;
|
||||
hash |= guid->data[j];
|
||||
}
|
||||
|
||||
return hash;
|
||||
hash <<= 4;
|
||||
hash |= guidspot;
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
gint
|
||||
guid_g_hash_table_equal (gconstpointer guid_a, gconstpointer guid_b)
|
||||
{
|
||||
return guid_equal (static_cast<const GncGUID*>(guid_a),
|
||||
static_cast<const GncGUID*>(guid_b));
|
||||
return guid_equal (reinterpret_cast<const GncGUID*> (guid_a),
|
||||
reinterpret_cast<const GncGUID*> (guid_b));
|
||||
}
|
||||
|
||||
GHashTable *
|
||||
@ -798,7 +274,7 @@ gnc_string_to_guid (const GValue *src, GValue *dest)
|
||||
as_string = g_value_get_string (src);
|
||||
|
||||
guid = g_new0 (GncGUID, 1);
|
||||
string_to_guid(as_string, guid);
|
||||
string_to_guid (as_string, guid);
|
||||
|
||||
g_value_take_boxed (dest, guid);
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
/********************************************************************\
|
||||
* guid.h -- globally unique ID User API *
|
||||
* Copyright (C) 2000 Dave Peticolas <peticola@cs.ucdavis.edu> *
|
||||
* 2014 Aaron Laws <dartmetrash@gmail.com> *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License as *
|
||||
@ -35,114 +36,96 @@ extern "C"
|
||||
/** @addtogroup Entity
|
||||
@{ */
|
||||
/** @addtogroup GncGUID
|
||||
Globally Unique ID's provide a way to uniquely identify
|
||||
some thing. A GncGUID is a unique, cryptographically
|
||||
Globally Unique IDs provide a way to uniquely identify
|
||||
something. A GncGUID is a unique, cryptographically
|
||||
random 128-bit value. The identifier is so random that
|
||||
it is safe to assume that there is no other such item
|
||||
on the planet Earth, and indeed, not even in the Galaxy
|
||||
or beyond.
|
||||
|
||||
QOF GncGUID's can be used independently of any other subsystem
|
||||
QOF GncGUIDs can be used independently of any other subsystem
|
||||
in QOF. In particular, they do not require the use of
|
||||
other parts of the object subsystem. New GncGUID's are usually
|
||||
created by initialising a new entity using qof_instance_init,
|
||||
other parts of the object subsystem. New GncGUIDs are usually
|
||||
created by initializing a new entity using qof_instance_init,
|
||||
rather than calling GncGUID functions directly.
|
||||
|
||||
@{ */
|
||||
/** @file guid.h
|
||||
@brief globally unique ID User API
|
||||
@author Copyright (C) 2000 Dave Peticolas <peticola@cs.ucdavis.edu>
|
||||
Copyright 2014 Aaron Laws <dartmetrash@gmail.com>
|
||||
*/
|
||||
|
||||
/** The type used to store guids */
|
||||
#define GUID_DATA_SIZE 16
|
||||
typedef union GNC_INTERNAL_GUID
|
||||
{
|
||||
guchar data[GUID_DATA_SIZE];
|
||||
|
||||
gint __align_me; /* this just ensures that GUIDs are 32-bit
|
||||
* aligned on systems that need them to be. */
|
||||
} GncGUID;
|
||||
|
||||
|
||||
#define GNC_TYPE_GUID (gnc_guid_get_type())
|
||||
#define GNC_VALUE_HOLDS_GUID(value) G_VALUE_HOLDS(value, GNC_TYPE_GUID)
|
||||
|
||||
/** The type used to store guids */
|
||||
typedef struct _gncGuid {
|
||||
unsigned char reserved[GUID_DATA_SIZE];
|
||||
} GncGUID;
|
||||
|
||||
GType gnc_guid_get_type (void);
|
||||
const GncGUID* gnc_value_get_guid (const GValue *value);
|
||||
|
||||
/** number of characters needed to encode a guid as a string
|
||||
/** Number of characters needed to encode a guid as a string
|
||||
* not including the null terminator. */
|
||||
#define GUID_ENCODING_LENGTH 32
|
||||
|
||||
|
||||
/** Initialize the id generator with a variety of random
|
||||
* sources.
|
||||
/** Generate a new guid.
|
||||
*
|
||||
* @note Only one of guid_init(), guid_init_with_salt() and
|
||||
* guid_init_only_salt() should be called. Calling any
|
||||
* initialization function a second time will reset the generator and
|
||||
* erase the effect of the first call.
|
||||
*/
|
||||
void guid_init(void);
|
||||
|
||||
/** Release the memory chunk associated with gui storage. Use this
|
||||
* only when shutting down the program, as it invalidates *all*
|
||||
* GUIDs at once. */
|
||||
void guid_shutdown (void);
|
||||
|
||||
/** Generate a new id. If no initialization function has been called,
|
||||
* guid_init() will be called before the id is created.
|
||||
*
|
||||
* @param guid A pointer to an existing guid data structure. The
|
||||
* @param guid A pointer to an allocated guid data structure. The
|
||||
* existing value will be replaced with a new value.
|
||||
*
|
||||
* This routine uses the md5 algorithm to build strong random guids.
|
||||
* Note that while guid's are generated randomly, the odds of this
|
||||
* routine returning a non-unique id are astronomically small.
|
||||
* (Literally astronomically: If you had Cray's on every solar
|
||||
* system in the universe running for the entire age of the universe,
|
||||
* you'd still have less than a one-in-a-million chance of coming up
|
||||
* with a duplicate id. 2^128 == 10^38 is a really really big number.)
|
||||
*/
|
||||
void guid_new(GncGUID *guid);
|
||||
void guid_replace (GncGUID *guid);
|
||||
|
||||
/** Generate a new id. If no initialization function has been called,
|
||||
* guid_init() will be called before the id is created.
|
||||
/** Generate a new id.
|
||||
*
|
||||
* @return guid A data structure containing a newly allocated GncGUID.
|
||||
* Caller is responsible for calling guid_free().
|
||||
* @return guid A data structure containing a copy of a newly constructed GncGUID.
|
||||
*/
|
||||
GncGUID guid_new_return(void);
|
||||
GncGUID guid_new_return (void);
|
||||
|
||||
/** Returns a GncGUID which is guaranteed
|
||||
to never reference any entity. */
|
||||
/** Returns a GncGUID which is guaranteed to never reference any entity.
|
||||
*
|
||||
* Do not free this value! The same pointer is returned on each call.*/
|
||||
const GncGUID * guid_null (void);
|
||||
|
||||
/** Efficiently allocate & free memory for GUIDs */
|
||||
/**
|
||||
* Allocate memory for a GUID. This does not construct a GUID. In other words,
|
||||
* the returned pointer has not necessarily been initialized. The returned
|
||||
* pointer must be freed with * guid_free.
|
||||
*/
|
||||
GncGUID * guid_malloc (void);
|
||||
|
||||
/* Return a guid set to all zero's */
|
||||
/**
|
||||
* Allocate and construct a new GUID. The returned pointer must be
|
||||
* released with guid_free.
|
||||
*/
|
||||
GncGUID * guid_new (void);
|
||||
|
||||
/*Free the guid pointed to. Do not use this guid any more.*/
|
||||
void guid_free (GncGUID *guid);
|
||||
|
||||
/**
|
||||
* Returns a newly allocated GncGUID that matches the passed-in GUID.
|
||||
* The returned pointer must be freed using guid_free.
|
||||
*/
|
||||
GncGUID *guid_copy (const GncGUID *guid);
|
||||
|
||||
/** The guid_to_string() routine returns a null-terminated string
|
||||
* encoding of the id. String encodings of identifiers are hex
|
||||
* numbers printed only with the characters '0' through '9' and
|
||||
* 'a' through 'f'. The encoding will always be GUID_ENCODING_LENGTH
|
||||
* characters long.
|
||||
*
|
||||
* XXX This routine is not thread safe and is deprecated. Please
|
||||
* use the routine guid_to_string_buff() instead.
|
||||
* characters long (not including the null terminator).
|
||||
*
|
||||
* @param guid The guid to print.
|
||||
*
|
||||
* @return A pointer to the starting character of the string. The
|
||||
* returned memory is owned by this routine and may not be freed by
|
||||
* the caller.
|
||||
* returned memory is owned by the calling routine and must be freed
|
||||
* using g_free.
|
||||
*/
|
||||
const gchar * guid_to_string (const GncGUID * guid);
|
||||
gchar * guid_to_string (const GncGUID * guid);
|
||||
|
||||
/** The guid_to_string_buff() routine puts a null-terminated string
|
||||
* encoding of the id into the memory pointed at by buff. The
|
||||
@ -155,16 +138,21 @@ const gchar * guid_to_string (const GncGUID * guid);
|
||||
*
|
||||
* @param buff The buffer to print it into.
|
||||
*
|
||||
* @return A pointer to the terminating null character of the string.
|
||||
* @return A pointer to the terminating null character of the string,
|
||||
* or, if no copy took place, NULL.
|
||||
*/
|
||||
gchar * guid_to_string_buff (const GncGUID * guid, /*@ out @*/ gchar *buff);
|
||||
|
||||
|
||||
/** Given a string, decode the id into the guid if guid is non-NULL.
|
||||
* The function returns TRUE if the string was a valid 32 character
|
||||
* hexadecimal number. This function accepts both upper and lower case
|
||||
* hex digits. If the return value is FALSE, the effect on guid is
|
||||
* undefined. */
|
||||
/** Given a string, replace the given guid with the parsed one unless
|
||||
* the given value is null.
|
||||
* If null is passed as guid or string, false is returned and nothing
|
||||
* is done, otherwise, the function returns true.
|
||||
* This function accepts both uppor and lower case hex digits. If
|
||||
* letters outside the range of [a-fA-F] are passed, they are silently
|
||||
* replaced. If non-alphanumeric digits are given, this function will
|
||||
* either return false or replace those values with others.
|
||||
*/
|
||||
gboolean string_to_guid(const gchar * string, /*@ out @*/ GncGUID * guid);
|
||||
|
||||
|
||||
|
@ -1568,9 +1568,9 @@ kvp_value_to_string(const KvpValue *val)
|
||||
break;
|
||||
|
||||
case KVP_TYPE_GUID:
|
||||
/* THREAD-UNSAFE */
|
||||
ctmp = guid_to_string(kvp_value_get_guid(val));
|
||||
tmp2 = g_strdup_printf("KVP_VALUE_GUID(%s)", ctmp ? ctmp : "");
|
||||
gchar guidstr[GUID_ENCODING_LENGTH+1];
|
||||
guid_to_string_buff(kvp_value_get_guid(val),guidstr);
|
||||
tmp2 = g_strdup_printf("KVP_VALUE_GUID(%s)", guidstr);
|
||||
return tmp2;
|
||||
break;
|
||||
|
||||
|
@ -1,445 +0,0 @@
|
||||
/* md5.c - Functions to compute MD5 message digest of files or memory blocks
|
||||
according to the definition of MD5 in RFC 1321 from April 1992.
|
||||
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
|
||||
NOTE: The canonical source of this file is maintained with the GNU C
|
||||
Library. Bugs can be reported to bug-glibc@prep.ai.mit.edu.
|
||||
|
||||
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, or (at your option) any
|
||||
later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
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. */
|
||||
|
||||
/* Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#if STDC_HEADERS || defined _LIBC
|
||||
# include <stdlib.h>
|
||||
# include <string.h>
|
||||
#else
|
||||
# ifndef HAVE_MEMCPY
|
||||
#include <string.h>
|
||||
/* # define memcpy(d, s, n) bcopy ((s), (d), (n)) */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include "md5.h"
|
||||
|
||||
#ifdef _LIBC
|
||||
# include <endian.h>
|
||||
# if __BYTE_ORDER == __BIG_ENDIAN
|
||||
# define WORDS_BIGENDIAN 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
# define SWAP(n) \
|
||||
(((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24))
|
||||
#else
|
||||
# define SWAP(n) (n)
|
||||
#endif
|
||||
|
||||
|
||||
/* This array contains the bytes used to pad the buffer to the next
|
||||
64-byte boundary. (RFC 1321, 3.1: Step 1) */
|
||||
static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ };
|
||||
|
||||
|
||||
/* Initialize structure containing state of computation.
|
||||
(RFC 1321, 3.3: Step 3) */
|
||||
void
|
||||
md5_init_ctx (ctx)
|
||||
struct md5_ctx *ctx;
|
||||
{
|
||||
ctx->A = 0x67452301;
|
||||
ctx->B = 0xefcdab89;
|
||||
ctx->C = 0x98badcfe;
|
||||
ctx->D = 0x10325476;
|
||||
|
||||
ctx->total[0] = ctx->total[1] = 0;
|
||||
ctx->buflen = 0;
|
||||
}
|
||||
|
||||
/* Put result from CTX in first 16 bytes following RESBUF. The result
|
||||
must be in little endian byte order.
|
||||
|
||||
IMPORTANT: On some systems it is required that RESBUF is correctly
|
||||
aligned for a 32 bits value. */
|
||||
void *
|
||||
md5_read_ctx (ctx, resbuf)
|
||||
const struct md5_ctx *ctx;
|
||||
void *resbuf;
|
||||
{
|
||||
((md5_uint32 *) resbuf)[0] = SWAP (ctx->A);
|
||||
((md5_uint32 *) resbuf)[1] = SWAP (ctx->B);
|
||||
((md5_uint32 *) resbuf)[2] = SWAP (ctx->C);
|
||||
((md5_uint32 *) resbuf)[3] = SWAP (ctx->D);
|
||||
|
||||
return resbuf;
|
||||
}
|
||||
|
||||
/* Process the remaining bytes in the internal buffer and the usual
|
||||
prolog according to the standard and write the result to RESBUF.
|
||||
|
||||
IMPORTANT: On some systems it is required that RESBUF is correctly
|
||||
aligned for a 32 bits value. */
|
||||
void *
|
||||
md5_finish_ctx (ctx, resbuf)
|
||||
struct md5_ctx *ctx;
|
||||
void *resbuf;
|
||||
{
|
||||
/* Take yet unprocessed bytes into account. */
|
||||
md5_uint32 bytes = ctx->buflen;
|
||||
size_t pad;
|
||||
|
||||
/* Now count remaining bytes. */
|
||||
ctx->total[0] += bytes;
|
||||
if (ctx->total[0] < bytes)
|
||||
++ctx->total[1];
|
||||
|
||||
pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes;
|
||||
memcpy (&ctx->buffer[bytes], fillbuf, pad);
|
||||
|
||||
/* Put the 64-bit file length in *bits* at the end of the buffer. */
|
||||
*(md5_uint32 *) &ctx->buffer[bytes + pad] = SWAP (ctx->total[0] << 3);
|
||||
*(md5_uint32 *) &ctx->buffer[bytes + pad + 4] = SWAP ((ctx->total[1] << 3) |
|
||||
(ctx->total[0] >> 29));
|
||||
|
||||
/* Process last bytes. */
|
||||
md5_process_block (ctx->buffer, bytes + pad + 8, ctx);
|
||||
|
||||
return md5_read_ctx (ctx, resbuf);
|
||||
}
|
||||
|
||||
/* Compute MD5 message digest for bytes read from STREAM. The
|
||||
resulting message digest number will be written into the 16 bytes
|
||||
beginning at RESBLOCK. */
|
||||
int
|
||||
md5_stream (stream, resblock)
|
||||
FILE *stream;
|
||||
void *resblock;
|
||||
{
|
||||
/* Important: BLOCKSIZE must be a multiple of 64. */
|
||||
#define BLOCKSIZE 4096
|
||||
struct md5_ctx ctx;
|
||||
char buffer[BLOCKSIZE + 72];
|
||||
size_t sum;
|
||||
|
||||
/* Initialize the computation context. */
|
||||
md5_init_ctx (&ctx);
|
||||
|
||||
/* Iterate over full file contents. */
|
||||
while (1)
|
||||
{
|
||||
/* We read the file in blocks of BLOCKSIZE bytes. One call of the
|
||||
computation function processes the whole buffer so that with the
|
||||
next round of the loop another block can be read. */
|
||||
size_t n;
|
||||
sum = 0;
|
||||
|
||||
/* Read block. Take care for partial reads. */
|
||||
do
|
||||
{
|
||||
n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream);
|
||||
|
||||
sum += n;
|
||||
}
|
||||
while (sum < BLOCKSIZE && n != 0);
|
||||
if (n == 0 && ferror (stream))
|
||||
return 1;
|
||||
|
||||
/* If end of file is reached, end the loop. */
|
||||
if (n == 0)
|
||||
break;
|
||||
|
||||
/* Process buffer with BLOCKSIZE bytes. Note that
|
||||
BLOCKSIZE % 64 == 0
|
||||
*/
|
||||
md5_process_block (buffer, BLOCKSIZE, &ctx);
|
||||
}
|
||||
|
||||
/* Add the last bytes if necessary. */
|
||||
if (sum > 0)
|
||||
md5_process_bytes (buffer, sum, &ctx);
|
||||
|
||||
/* Construct result in desired memory. */
|
||||
md5_finish_ctx (&ctx, resblock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The
|
||||
result is always in little endian byte order, so that a byte-wise
|
||||
output yields to the wanted ASCII representation of the message
|
||||
digest. */
|
||||
void *
|
||||
md5_buffer (buffer, len, resblock)
|
||||
const char *buffer;
|
||||
size_t len;
|
||||
void *resblock;
|
||||
{
|
||||
struct md5_ctx ctx;
|
||||
|
||||
/* Initialize the computation context. */
|
||||
md5_init_ctx (&ctx);
|
||||
|
||||
/* Process whole buffer but last len % 64 bytes. */
|
||||
md5_process_bytes (buffer, len, &ctx);
|
||||
|
||||
/* Put result in desired memory area. */
|
||||
return md5_finish_ctx (&ctx, resblock);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
md5_process_bytes (buffer, len, ctx)
|
||||
const void *buffer;
|
||||
size_t len;
|
||||
struct md5_ctx *ctx;
|
||||
{
|
||||
#define NUM_MD5_WORDS 1024
|
||||
size_t add = 0;
|
||||
|
||||
/* When we already have some bits in our internal buffer concatenate
|
||||
both inputs first. */
|
||||
if (ctx->buflen != 0)
|
||||
{
|
||||
size_t left_over = ctx->buflen;
|
||||
|
||||
add = 128 - left_over > len ? len : 128 - left_over;
|
||||
|
||||
memcpy (&ctx->buffer[left_over], buffer, add);
|
||||
ctx->buflen += add;
|
||||
|
||||
if (left_over + add > 64)
|
||||
{
|
||||
md5_process_block (ctx->buffer, (left_over + add) & ~63, ctx);
|
||||
/* The regions in the following copy operation cannot overlap. */
|
||||
memcpy (ctx->buffer, &ctx->buffer[(left_over + add) & ~63],
|
||||
(left_over + add) & 63);
|
||||
ctx->buflen = (left_over + add) & 63;
|
||||
}
|
||||
|
||||
buffer = (const char *) buffer + add;
|
||||
len -= add;
|
||||
}
|
||||
|
||||
/* Process available complete blocks. */
|
||||
if (len > 64)
|
||||
{
|
||||
if ((add & 3) == 0) /* buffer is still 32-bit aligned */
|
||||
{
|
||||
md5_process_block (buffer, len & ~63, ctx);
|
||||
buffer = (const char *) buffer + (len & ~63);
|
||||
}
|
||||
else /* buffer is not 32-bit aligned */
|
||||
{
|
||||
md5_uint32 md5_buffer[NUM_MD5_WORDS];
|
||||
size_t num_bytes;
|
||||
size_t buf_bytes;
|
||||
|
||||
num_bytes = len & ~63;
|
||||
while (num_bytes > 0)
|
||||
{
|
||||
buf_bytes = (num_bytes < sizeof(md5_buffer)) ?
|
||||
num_bytes : sizeof(md5_buffer);
|
||||
memcpy (md5_buffer, buffer, buf_bytes);
|
||||
md5_process_block (md5_buffer, buf_bytes, ctx);
|
||||
num_bytes -= buf_bytes;
|
||||
buffer = (const char *) buffer + buf_bytes;
|
||||
}
|
||||
}
|
||||
|
||||
len &= 63;
|
||||
}
|
||||
|
||||
/* Move remaining bytes in internal buffer. */
|
||||
if (len > 0)
|
||||
{
|
||||
memcpy (ctx->buffer, buffer, len);
|
||||
ctx->buflen = len;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* These are the four functions used in the four steps of the MD5 algorithm
|
||||
and defined in the RFC 1321. The first function is a little bit optimized
|
||||
(as found in Colin Plumbs public domain implementation). */
|
||||
/* #define FF(b, c, d) ((b & c) | (~b & d)) */
|
||||
#define FF(b, c, d) (d ^ (b & (c ^ d)))
|
||||
#define FG(b, c, d) FF (d, b, c)
|
||||
#define FH(b, c, d) (b ^ c ^ d)
|
||||
#define FI(b, c, d) (c ^ (b | ~d))
|
||||
|
||||
/* Process LEN bytes of BUFFER, accumulating context into CTX.
|
||||
It is assumed that LEN % 64 == 0. */
|
||||
|
||||
void
|
||||
md5_process_block (buffer, len, ctx)
|
||||
const void *buffer;
|
||||
size_t len;
|
||||
struct md5_ctx *ctx;
|
||||
{
|
||||
md5_uint32 correct_words[16];
|
||||
const md5_uint32 *words = buffer;
|
||||
size_t nwords = len / sizeof (md5_uint32);
|
||||
const md5_uint32 *endp = words + nwords;
|
||||
md5_uint32 A = ctx->A;
|
||||
md5_uint32 B = ctx->B;
|
||||
md5_uint32 C = ctx->C;
|
||||
md5_uint32 D = ctx->D;
|
||||
|
||||
/* First increment the byte count. RFC 1321 specifies the possible
|
||||
length of the file up to 2^64 bits. Here we only compute the
|
||||
number of bytes. Do a double word increment. */
|
||||
ctx->total[0] += len;
|
||||
if (ctx->total[0] < len)
|
||||
++ctx->total[1];
|
||||
|
||||
/* Process all bytes in the buffer with 64 bytes in each round of
|
||||
the loop. */
|
||||
while (words < endp)
|
||||
{
|
||||
md5_uint32 *cwp = correct_words;
|
||||
md5_uint32 A_save = A;
|
||||
md5_uint32 B_save = B;
|
||||
md5_uint32 C_save = C;
|
||||
md5_uint32 D_save = D;
|
||||
|
||||
/* First round: using the given function, the context and a constant
|
||||
the next context is computed. Because the algorithms processing
|
||||
unit is a 32-bit word and it is determined to work on words in
|
||||
little endian byte order we perhaps have to change the byte order
|
||||
before the computation. To reduce the work for the next steps
|
||||
we store the swapped words in the array CORRECT_WORDS. */
|
||||
|
||||
#define OP(a, b, c, d, s, T) \
|
||||
do \
|
||||
{ \
|
||||
a += FF (b, c, d) + (*cwp++ = SWAP (*words)) + T; \
|
||||
++words; \
|
||||
CYCLIC (a, s); \
|
||||
a += b; \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/* It is unfortunate that C does not provide an operator for
|
||||
cyclic rotation. Hope the C compiler is smart enough. */
|
||||
#define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s)))
|
||||
|
||||
/* Before we start, one word to the strange constants.
|
||||
They are defined in RFC 1321 as
|
||||
|
||||
T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64
|
||||
*/
|
||||
|
||||
/* Round 1. */
|
||||
OP (A, B, C, D, 7, 0xd76aa478);
|
||||
OP (D, A, B, C, 12, 0xe8c7b756);
|
||||
OP (C, D, A, B, 17, 0x242070db);
|
||||
OP (B, C, D, A, 22, 0xc1bdceee);
|
||||
OP (A, B, C, D, 7, 0xf57c0faf);
|
||||
OP (D, A, B, C, 12, 0x4787c62a);
|
||||
OP (C, D, A, B, 17, 0xa8304613);
|
||||
OP (B, C, D, A, 22, 0xfd469501);
|
||||
OP (A, B, C, D, 7, 0x698098d8);
|
||||
OP (D, A, B, C, 12, 0x8b44f7af);
|
||||
OP (C, D, A, B, 17, 0xffff5bb1);
|
||||
OP (B, C, D, A, 22, 0x895cd7be);
|
||||
OP (A, B, C, D, 7, 0x6b901122);
|
||||
OP (D, A, B, C, 12, 0xfd987193);
|
||||
OP (C, D, A, B, 17, 0xa679438e);
|
||||
OP (B, C, D, A, 22, 0x49b40821);
|
||||
|
||||
/* For the second to fourth round we have the possibly swapped words
|
||||
in CORRECT_WORDS. Redefine the macro to take an additional first
|
||||
argument specifying the function to use. */
|
||||
#undef OP
|
||||
#define OP(f, a, b, c, d, k, s, T) \
|
||||
do \
|
||||
{ \
|
||||
a += f (b, c, d) + correct_words[k] + T; \
|
||||
CYCLIC (a, s); \
|
||||
a += b; \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/* Round 2. */
|
||||
OP (FG, A, B, C, D, 1, 5, 0xf61e2562);
|
||||
OP (FG, D, A, B, C, 6, 9, 0xc040b340);
|
||||
OP (FG, C, D, A, B, 11, 14, 0x265e5a51);
|
||||
OP (FG, B, C, D, A, 0, 20, 0xe9b6c7aa);
|
||||
OP (FG, A, B, C, D, 5, 5, 0xd62f105d);
|
||||
OP (FG, D, A, B, C, 10, 9, 0x02441453);
|
||||
OP (FG, C, D, A, B, 15, 14, 0xd8a1e681);
|
||||
OP (FG, B, C, D, A, 4, 20, 0xe7d3fbc8);
|
||||
OP (FG, A, B, C, D, 9, 5, 0x21e1cde6);
|
||||
OP (FG, D, A, B, C, 14, 9, 0xc33707d6);
|
||||
OP (FG, C, D, A, B, 3, 14, 0xf4d50d87);
|
||||
OP (FG, B, C, D, A, 8, 20, 0x455a14ed);
|
||||
OP (FG, A, B, C, D, 13, 5, 0xa9e3e905);
|
||||
OP (FG, D, A, B, C, 2, 9, 0xfcefa3f8);
|
||||
OP (FG, C, D, A, B, 7, 14, 0x676f02d9);
|
||||
OP (FG, B, C, D, A, 12, 20, 0x8d2a4c8a);
|
||||
|
||||
/* Round 3. */
|
||||
OP (FH, A, B, C, D, 5, 4, 0xfffa3942);
|
||||
OP (FH, D, A, B, C, 8, 11, 0x8771f681);
|
||||
OP (FH, C, D, A, B, 11, 16, 0x6d9d6122);
|
||||
OP (FH, B, C, D, A, 14, 23, 0xfde5380c);
|
||||
OP (FH, A, B, C, D, 1, 4, 0xa4beea44);
|
||||
OP (FH, D, A, B, C, 4, 11, 0x4bdecfa9);
|
||||
OP (FH, C, D, A, B, 7, 16, 0xf6bb4b60);
|
||||
OP (FH, B, C, D, A, 10, 23, 0xbebfbc70);
|
||||
OP (FH, A, B, C, D, 13, 4, 0x289b7ec6);
|
||||
OP (FH, D, A, B, C, 0, 11, 0xeaa127fa);
|
||||
OP (FH, C, D, A, B, 3, 16, 0xd4ef3085);
|
||||
OP (FH, B, C, D, A, 6, 23, 0x04881d05);
|
||||
OP (FH, A, B, C, D, 9, 4, 0xd9d4d039);
|
||||
OP (FH, D, A, B, C, 12, 11, 0xe6db99e5);
|
||||
OP (FH, C, D, A, B, 15, 16, 0x1fa27cf8);
|
||||
OP (FH, B, C, D, A, 2, 23, 0xc4ac5665);
|
||||
|
||||
/* Round 4. */
|
||||
OP (FI, A, B, C, D, 0, 6, 0xf4292244);
|
||||
OP (FI, D, A, B, C, 7, 10, 0x432aff97);
|
||||
OP (FI, C, D, A, B, 14, 15, 0xab9423a7);
|
||||
OP (FI, B, C, D, A, 5, 21, 0xfc93a039);
|
||||
OP (FI, A, B, C, D, 12, 6, 0x655b59c3);
|
||||
OP (FI, D, A, B, C, 3, 10, 0x8f0ccc92);
|
||||
OP (FI, C, D, A, B, 10, 15, 0xffeff47d);
|
||||
OP (FI, B, C, D, A, 1, 21, 0x85845dd1);
|
||||
OP (FI, A, B, C, D, 8, 6, 0x6fa87e4f);
|
||||
OP (FI, D, A, B, C, 15, 10, 0xfe2ce6e0);
|
||||
OP (FI, C, D, A, B, 6, 15, 0xa3014314);
|
||||
OP (FI, B, C, D, A, 13, 21, 0x4e0811a1);
|
||||
OP (FI, A, B, C, D, 4, 6, 0xf7537e82);
|
||||
OP (FI, D, A, B, C, 11, 10, 0xbd3af235);
|
||||
OP (FI, C, D, A, B, 2, 15, 0x2ad7d2bb);
|
||||
OP (FI, B, C, D, A, 9, 21, 0xeb86d391);
|
||||
|
||||
/* Add the starting values of the context. */
|
||||
A += A_save;
|
||||
B += B_save;
|
||||
C += C_save;
|
||||
D += D_save;
|
||||
}
|
||||
|
||||
/* Put checksum in context given as argument. */
|
||||
ctx->A = A;
|
||||
ctx->B = B;
|
||||
ctx->C = C;
|
||||
ctx->D = D;
|
||||
}
|
@ -1,163 +0,0 @@
|
||||
/* md5.h - Declaration of functions and data types used for MD5 sum
|
||||
computing library functions.
|
||||
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
|
||||
NOTE: The canonical source of this file is maintained with the GNU C
|
||||
Library. Bugs can be reported to bug-glibc@prep.ai.mit.edu.
|
||||
|
||||
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, or (at your option) any
|
||||
later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
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. */
|
||||
|
||||
#ifndef _MD5_H
|
||||
#define _MD5_H 1
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#if defined HAVE_LIMITS_H || _LIBC
|
||||
# include <limits.h>
|
||||
#endif
|
||||
|
||||
/* The following contortions are an attempt to use the C preprocessor
|
||||
to determine an unsigned integral type that is 32 bits wide. An
|
||||
alternative approach is to use autoconf's AC_CHECK_SIZEOF macro, but
|
||||
doing that would require that the configure script compile and *run*
|
||||
the resulting executable. Locally running cross-compiled executables
|
||||
is usually not possible. */
|
||||
|
||||
#ifdef _LIBC
|
||||
# include <sys/types.h>
|
||||
typedef u_int32_t md5_uint32;
|
||||
#else
|
||||
# if defined __STDC__ && __STDC__
|
||||
# define UINT_MAX_32_BITS 4294967295U
|
||||
# else
|
||||
# define UINT_MAX_32_BITS 0xFFFFFFFF
|
||||
# endif
|
||||
|
||||
/* If UINT_MAX isn't defined, assume it's a 32-bit type.
|
||||
This should be valid for all systems GNU cares about because
|
||||
that doesn't include 16-bit systems, and only modern systems
|
||||
(that certainly have <limits.h>) have 64+-bit integral types. */
|
||||
|
||||
# ifndef UINT_MAX
|
||||
# define UINT_MAX UINT_MAX_32_BITS
|
||||
# endif
|
||||
|
||||
# if UINT_MAX == UINT_MAX_32_BITS
|
||||
typedef unsigned int md5_uint32;
|
||||
# else
|
||||
# if USHRT_MAX == UINT_MAX_32_BITS
|
||||
typedef unsigned short md5_uint32;
|
||||
# else
|
||||
# if ULONG_MAX == UINT_MAX_32_BITS
|
||||
typedef unsigned long md5_uint32;
|
||||
# else
|
||||
/* The following line is intended to evoke an error.
|
||||
Using #error is not portable enough. */
|
||||
"Cannot determine unsigned 32-bit data type."
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#undef __P
|
||||
#if defined (__STDC__) && __STDC__
|
||||
#define __P(x) x
|
||||
#else
|
||||
#define __P(x) ()
|
||||
#endif
|
||||
|
||||
/* Structure to save state of computation between the single steps. */
|
||||
struct md5_ctx
|
||||
{
|
||||
md5_uint32 A;
|
||||
md5_uint32 B;
|
||||
md5_uint32 C;
|
||||
md5_uint32 D;
|
||||
|
||||
md5_uint32 total[2];
|
||||
md5_uint32 buflen;
|
||||
char buffer[128];
|
||||
};
|
||||
|
||||
/*
|
||||
* The following three functions are build up the low level used in
|
||||
* the functions `md5_stream' and `md5_buffer'.
|
||||
*/
|
||||
|
||||
/* Initialize structure containing state of computation.
|
||||
(RFC 1321, 3.3: Step 3) */
|
||||
extern void md5_init_ctx __P ((struct md5_ctx *ctx));
|
||||
|
||||
|
||||
/* Starting with the result of former calls of this function (or the
|
||||
initialization function update the context for the next LEN bytes
|
||||
starting at BUFFER.
|
||||
|
||||
It is necessary that LEN is a multiple of 64!!!
|
||||
|
||||
IMPORTANT: On some systems it is required that buffer be 32-bit
|
||||
aligned. */
|
||||
extern void md5_process_block __P ((const void *buffer, size_t len,
|
||||
struct md5_ctx *ctx));
|
||||
|
||||
/* Starting with the result of former calls of this function (or the
|
||||
initialization function) update the context for the next LEN bytes
|
||||
starting at BUFFER.
|
||||
|
||||
It is NOT required that LEN is a multiple of 64.
|
||||
|
||||
IMPORTANT: On some systems it is required that buffer be 32-bit
|
||||
aligned. */
|
||||
extern void md5_process_bytes __P ((const void *buffer, size_t len,
|
||||
struct md5_ctx *ctx));
|
||||
|
||||
/* Process the remaining bytes in the buffer and put result from CTX
|
||||
in first 16 bytes following RESBUF. The result is always in little
|
||||
endian byte order, so that a byte-wise output yields to the wanted
|
||||
ASCII representation of the message digest.
|
||||
|
||||
IMPORTANT: On some systems it is required that RESBUF be correctly
|
||||
aligned for a 32 bits value. */
|
||||
extern void *md5_finish_ctx __P ((struct md5_ctx *ctx, void *resbuf));
|
||||
|
||||
|
||||
/* Put result from CTX in first 16 bytes following RESBUF. The result is
|
||||
always in little endian byte order, so that a byte-wise output yields
|
||||
to the wanted ASCII representation of the message digest.
|
||||
|
||||
IMPORTANT: On some systems it is required that RESBUF be correctly
|
||||
aligned for a 32 bits value. */
|
||||
extern void *md5_read_ctx __P ((const struct md5_ctx *ctx, void *resbuf));
|
||||
|
||||
|
||||
/* Compute MD5 message digest for bytes read from STREAM. The
|
||||
resulting message digest number will be written into the 16 bytes
|
||||
beginning at RESBLOCK.
|
||||
|
||||
IMPORTANT: On some systems it is required that resblock be 32-bit
|
||||
aligned. */
|
||||
extern int md5_stream __P ((FILE *stream, void *resblock));
|
||||
|
||||
|
||||
/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The
|
||||
result is always in little endian byte order, so that a byte-wise
|
||||
output yields to the wanted ASCII representation of the message
|
||||
digest.
|
||||
|
||||
IMPORTANT: On some systems it is required that buffer and resblock
|
||||
be correctly 32-bit aligned. */
|
||||
extern void *md5_buffer __P ((const char *buffer, size_t len, void *resblock));
|
||||
|
||||
#endif
|
@ -303,7 +303,7 @@ qof_instance_init_data (QofInstance *inst, QofIdType type, QofBook *book)
|
||||
|
||||
do
|
||||
{
|
||||
guid_new(&priv->guid);
|
||||
guid_replace(&priv->guid);
|
||||
|
||||
if (NULL == qof_collection_lookup_entity (col, &priv->guid))
|
||||
break;
|
||||
@ -691,8 +691,9 @@ qof_instance_print_dirty (const QofInstance *inst, gpointer dummy)
|
||||
priv = GET_PRIVATE(inst);
|
||||
if (priv->dirty)
|
||||
{
|
||||
printf("%s instance %s is dirty.\n", inst->e_type,
|
||||
guid_to_string(&priv->guid));
|
||||
gchar guidstr[GUID_ENCODING_LENGTH+1];
|
||||
guid_to_string_buff(&priv->guid, guidstr);
|
||||
printf("%s instance %s is dirty.\n", inst->e_type, guidstr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1779,9 +1779,9 @@ qof_query_printValueForParam (QofQueryPredData *pd, GString * gs)
|
||||
qof_query_printGuidMatch (pdata->options));
|
||||
for (node = pdata->guids; node; node = node->next)
|
||||
{
|
||||
/* THREAD-UNSAFE */
|
||||
g_string_append_printf (gs, ", guids: %s",
|
||||
guid_to_string ((GncGUID *) node->data));
|
||||
gchar guidstr[GUID_ENCODING_LENGTH+1];
|
||||
guid_to_string_buff ((GncGUID *) node->data,guidstr);
|
||||
g_string_append_printf (gs, ", guids: %s",guidstr);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -263,7 +263,6 @@ qof_init (void)
|
||||
#endif
|
||||
qof_log_init();
|
||||
qof_string_cache_init();
|
||||
guid_init ();
|
||||
qof_object_initialize ();
|
||||
qof_query_init ();
|
||||
qof_book_register ();
|
||||
@ -274,7 +273,6 @@ qof_close(void)
|
||||
{
|
||||
qof_query_shutdown ();
|
||||
qof_object_shutdown ();
|
||||
guid_shutdown ();
|
||||
qof_finalize_backend_libraries();
|
||||
qof_string_cache_destroy ();
|
||||
qof_log_shutdown();
|
||||
|
@ -154,15 +154,15 @@ extern "C"
|
||||
|
||||
/** \brief Initialise the Query Object Framework
|
||||
|
||||
Use in place of separate init functions (like guid_init()
|
||||
and qof_query_init() etc.) to protect against future changes.
|
||||
Use in place of separate init functions (like qof_query_init(),
|
||||
etc.) to protect against future changes.
|
||||
*/
|
||||
void qof_init (void);
|
||||
|
||||
/** \brief Safely close down the Query Object Framework
|
||||
|
||||
Use in place of separate close / shutdown functions
|
||||
(like guid_shutdown(), qof_query_shutdown() etc.) to protect
|
||||
(like qof_query_shutdown(), etc.) to protect
|
||||
against future changes.
|
||||
*/
|
||||
void qof_close (void);
|
||||
|
@ -47,7 +47,7 @@ static const gchar * suitename {"/qof/gnc-guid"};
|
||||
static void test_create_gnc_guid (void){
|
||||
GncGUID * guid {guid_malloc ()};
|
||||
g_assert (guid != nullptr);
|
||||
guid_new (guid);
|
||||
guid_replace (guid);
|
||||
/*We apparently don't need to free guid_null (based on its being const)*/
|
||||
const GncGUID * guidnull {guid_null ()};
|
||||
g_assert (!guid_equal (guid, guidnull));
|
||||
@ -58,7 +58,7 @@ static void test_create_gnc_guid (void){
|
||||
static void test_gnc_guid_copy (void) {
|
||||
GncGUID * guid {guid_malloc ()};
|
||||
g_assert (guid != nullptr);
|
||||
guid_new (guid);
|
||||
guid_replace (guid);
|
||||
GncGUID * cp {guid_copy (guid)};
|
||||
g_assert (guid_equal (guid, cp));
|
||||
guid_free (cp);
|
||||
@ -69,16 +69,17 @@ static void test_gnc_guid_copy (void) {
|
||||
defined in the guid api. We then compare them.*/
|
||||
static void test_gnc_guid_to_string (void) {
|
||||
GncGUID * guid {guid_malloc()};
|
||||
gchar guidstrp [GUID_ENCODING_LENGTH+1];
|
||||
gchar guidstrp2[GUID_ENCODING_LENGTH+1];
|
||||
g_assert (guid != nullptr);
|
||||
guid_new (guid);
|
||||
guid_replace (guid);
|
||||
string message {" using guid_to_string (deprecated): "};
|
||||
/*don't free the return value of guid_to_string!*/
|
||||
string guidstr {guid_to_string (guid)};
|
||||
guid_to_string_buff (guid,guidstrp);
|
||||
string guidstr {guidstrp};
|
||||
g_assert (guidstr.size () == GUID_ENCODING_LENGTH);
|
||||
message += guidstr;
|
||||
g_test_message ("%s", message.c_str ());
|
||||
message = " using guid_to_string_buff: ";
|
||||
gchar guidstrp2 [GUID_ENCODING_LENGTH+1];
|
||||
gchar * ret {guid_to_string_buff (guid, guidstrp2)};
|
||||
g_assert (ret == guidstrp2 + GUID_ENCODING_LENGTH);
|
||||
string guidstr2 {guidstrp2};
|
||||
@ -135,7 +136,7 @@ static void test_gnc_guid_roundtrip (void) {
|
||||
g_assert (guid1 != nullptr);
|
||||
GncGUID * guid2 {guid_malloc ()};
|
||||
g_assert (guid2 != nullptr);
|
||||
guid_new (guid1);
|
||||
guid_replace (guid1);
|
||||
|
||||
gchar guidstrp [GUID_ENCODING_LENGTH+1];
|
||||
gchar * temp {guid_to_string_buff (guid1, guidstrp)};
|
||||
@ -147,14 +148,52 @@ static void test_gnc_guid_roundtrip (void) {
|
||||
guid_free (guid1);
|
||||
}
|
||||
|
||||
/**
|
||||
* guid_replace should put a newly generated guid into the parameter. In
|
||||
* this test, we ensure that the first "new" guid doesn't match a subsequent
|
||||
* "new" guid in the same memory location.
|
||||
*/
|
||||
static void test_gnc_guid_replace (void)
|
||||
{
|
||||
GncGUID * guid1 {guid_malloc ()};
|
||||
|
||||
guid_replace (guid1);
|
||||
GncGUID * guid2 {guid_copy (guid1)};
|
||||
guid_replace (guid1);
|
||||
g_assert (! guid_equal (guid1, guid2));
|
||||
|
||||
guid_free (guid2);
|
||||
guid_free (guid1);
|
||||
}
|
||||
|
||||
/**
|
||||
* We create a bogus guid and ensure that it doesn't get parsed successfully,
|
||||
* then we pass in a good GUID from string and ensure that the function returns true.
|
||||
*/
|
||||
static void test_gnc_guid_from_string (void) {
|
||||
GncGUID * guid {guid_malloc ()};
|
||||
const char * bogus {"01-23-45-6789a.cDeF0123z56789abcdef"};
|
||||
|
||||
/* string_to_guid should return false if either parameter is null*/
|
||||
g_assert (!string_to_guid (nullptr, guid));
|
||||
g_assert (!string_to_guid (bogus, nullptr));
|
||||
|
||||
g_assert (!string_to_guid (bogus, guid));
|
||||
|
||||
const char * good {"0123456789abcdef1234567890abcdef"};
|
||||
g_assert (string_to_guid (good, guid));
|
||||
|
||||
guid_free (guid);
|
||||
}
|
||||
|
||||
void test_suite_gnc_guid (void)
|
||||
{
|
||||
guid_init ();
|
||||
GNC_TEST_ADD_FUNC (suitename, "gnc create guid", test_create_gnc_guid);
|
||||
GNC_TEST_ADD_FUNC (suitename, "gnc copy guid", test_gnc_guid_copy);
|
||||
GNC_TEST_ADD_FUNC (suitename, "gnc guid to string", test_gnc_guid_to_string);
|
||||
GNC_TEST_ADD_FUNC (suitename, "gnc guid equal", test_gnc_guid_equals);
|
||||
GNC_TEST_ADD_FUNC (suitename, "gnc guid string roundtrip", test_gnc_guid_roundtrip);
|
||||
guid_shutdown ();
|
||||
GNC_TEST_ADD_FUNC (suitename, "gnc guid from string", test_gnc_guid_from_string);
|
||||
GNC_TEST_ADD_FUNC (suitename, "gnc guid replace", test_gnc_guid_replace);
|
||||
}
|
||||
|
||||
|
@ -101,8 +101,7 @@ populate_frame (KvpFrame *frame)
|
||||
|
||||
ts.tv_sec = 1;
|
||||
ts.tv_nsec = 1;
|
||||
guid = guid_malloc ();
|
||||
guid_new (guid);
|
||||
guid = guid_new ();
|
||||
g_date_set_dmy (&gdate, 26, 1, 1957);
|
||||
|
||||
kvp_frame_set_gint64( frame, "gint64-type", 100 );
|
||||
@ -163,8 +162,7 @@ test_kvp_frame_copy( Fixture *fixture, gconstpointer pData )
|
||||
test_ts.tv_sec = 1;
|
||||
test_ts.tv_nsec = 1;
|
||||
test_str = "abcdefghijklmnop";
|
||||
test_guid = guid_malloc();
|
||||
guid_new( test_guid );
|
||||
test_guid = guid_new();
|
||||
test_frame = kvp_frame_new();
|
||||
|
||||
g_assert( fixture->frame );
|
||||
@ -223,8 +221,7 @@ test_kvp_frame_set_foo( Fixture *fixture, gconstpointer pData )
|
||||
test_gnc_numeric = gnc_numeric_zero();
|
||||
test_ts.tv_sec = 1;
|
||||
test_ts.tv_nsec = 1;
|
||||
test_guid = guid_malloc();
|
||||
guid_new( test_guid );
|
||||
test_guid = guid_new();
|
||||
|
||||
g_assert( fixture->frame );
|
||||
g_assert( kvp_frame_is_empty( fixture->frame ) );
|
||||
@ -512,8 +509,7 @@ test_kvp_value_copy( void )
|
||||
KvpFrame *frame_orig, *frame_copy;
|
||||
|
||||
gnc_numeric_orig = gnc_numeric_zero();
|
||||
guid_orig = guid_malloc();
|
||||
guid_new( guid_orig );
|
||||
guid_orig = guid_new();
|
||||
ts_orig.tv_sec = 1;
|
||||
ts_orig.tv_nsec = 1;
|
||||
list_orig = NULL;
|
||||
@ -631,8 +627,7 @@ test_kvp_glist_copy( void )
|
||||
KvpFrame *frame_orig;
|
||||
|
||||
gnc_numeric_orig = gnc_numeric_zero();
|
||||
guid_orig = guid_malloc();
|
||||
guid_new( guid_orig );
|
||||
guid_orig = guid_new();
|
||||
ts_orig.tv_sec = 1;
|
||||
ts_orig.tv_nsec = 1;
|
||||
list_orig = NULL;
|
||||
@ -703,8 +698,7 @@ test_kvp_glist_compare( void )
|
||||
KvpFrame *frame_orig;
|
||||
|
||||
gnc_numeric_orig = gnc_numeric_zero();
|
||||
guid_orig = guid_malloc();
|
||||
guid_new( guid_orig );
|
||||
guid_orig = guid_new();
|
||||
ts_orig.tv_sec = 1;
|
||||
ts_orig.tv_nsec = 1;
|
||||
list_orig = NULL;
|
||||
@ -797,10 +791,8 @@ test_kvp_value_compare( void )
|
||||
|
||||
gnc_numeric_orig = gnc_numeric_zero();
|
||||
gnc_numeric_copy = gnc_numeric_zero();
|
||||
guid_orig = guid_malloc();
|
||||
guid_new( guid_orig );
|
||||
guid_copy = guid_malloc();
|
||||
guid_new( guid_copy );
|
||||
guid_orig = guid_new();
|
||||
guid_copy = guid_new();
|
||||
ts_orig.tv_sec = 1;
|
||||
ts_orig.tv_nsec = 1;
|
||||
ts_copy.tv_sec = 2;
|
||||
@ -988,7 +980,7 @@ test_binary_to_string( void )
|
||||
static void
|
||||
test_kvp_value_to_string( void )
|
||||
{
|
||||
const gchar *str_tmp;
|
||||
gchar guidstr[GUID_ENCODING_LENGTH+1];
|
||||
gchar *str_tmp2, *str_tmp3;
|
||||
gchar *result;
|
||||
KvpValue *gint64_value;
|
||||
@ -1007,8 +999,7 @@ test_kvp_value_to_string( void )
|
||||
KvpFrame *frame_orig;
|
||||
|
||||
gnc_numeric_orig = gnc_numeric_zero();
|
||||
guid_orig = guid_malloc();
|
||||
guid_new( guid_orig );
|
||||
guid_orig = guid_new();
|
||||
ts_orig.tv_sec = 1;
|
||||
ts_orig.tv_nsec = 1;
|
||||
list_orig = NULL;
|
||||
@ -1047,8 +1038,8 @@ test_kvp_value_to_string( void )
|
||||
|
||||
result = kvp_value_to_string( guid_value );
|
||||
g_assert( result );
|
||||
str_tmp = guid_to_string( kvp_value_get_guid( guid_value ) );
|
||||
str_tmp2 = g_strdup_printf("KVP_VALUE_GUID(%s)", str_tmp ? str_tmp : "");
|
||||
guid_to_string_buff( kvp_value_get_guid( guid_value ), guidstr);
|
||||
str_tmp2 = g_strdup_printf("KVP_VALUE_GUID(%s)", guidstr);
|
||||
g_assert_cmpstr( result, == , str_tmp2 );
|
||||
g_free( result );
|
||||
g_free( str_tmp2 );
|
||||
@ -1093,8 +1084,7 @@ test_kvp_frame_to_string( Fixture *fixture, gconstpointer pData )
|
||||
KvpFrame *test_frame;
|
||||
|
||||
test_gnc_numeric = gnc_numeric_zero();
|
||||
test_guid = guid_malloc();
|
||||
guid_new( test_guid );
|
||||
test_guid = guid_new();
|
||||
test_ts.tv_sec = 1;
|
||||
test_ts.tv_nsec = 1;
|
||||
test_frame = kvp_frame_new();
|
||||
|
@ -97,8 +97,7 @@ test_instance_set_get_guid( Fixture *fixture, gconstpointer pData )
|
||||
g_assert( qof_entity_get_guid( NULL ) == guid_null() );
|
||||
|
||||
/* set up */
|
||||
gncGuid = guid_malloc();
|
||||
guid_new( gncGuid );
|
||||
gncGuid = guid_new();
|
||||
g_assert( QOF_IS_INSTANCE( fixture->inst ) );
|
||||
g_assert( gncGuid );
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user