mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
Merge branch 'guidcpp' of https://github.com/limitedAtonement/gnucash
into guidcpp
This commit is contained in:
commit
1e5b14b54f
@ -260,8 +260,10 @@ gnc_cm_event_handler (QofInstance *entity,
|
|||||||
{
|
{
|
||||||
const GncGUID *guid = qof_entity_get_guid(entity);
|
const GncGUID *guid = qof_entity_get_guid(entity);
|
||||||
#if CM_DEBUG
|
#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,
|
fprintf (stderr, "event_handler: event %d, entity %p, guid %s\n", event_type,
|
||||||
entity, guid_to_string(guid));
|
entity, guidstr);
|
||||||
#endif
|
#endif
|
||||||
add_event (&changes, guid, event_type, TRUE);
|
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 *basename, *original = NULL, *filename, *file_guid;
|
||||||
gchar *sf_extension = NULL, *newstyle_filename = NULL;
|
gchar *sf_extension = NULL, *newstyle_filename = NULL;
|
||||||
const gchar *uri, *guid_string;
|
const gchar *uri;
|
||||||
|
gchar guid_string[GUID_ENCODING_LENGTH+1];
|
||||||
QofBook *book;
|
QofBook *book;
|
||||||
const GncGUID *guid;
|
const GncGUID *guid;
|
||||||
GKeyFile *key_file = NULL;
|
GKeyFile *key_file = NULL;
|
||||||
@ -94,7 +95,7 @@ gnc_state_set_base (const QofSession *session)
|
|||||||
/* Get the book GncGUID */
|
/* Get the book GncGUID */
|
||||||
book = qof_session_get_book(session);
|
book = qof_session_get_book(session);
|
||||||
guid = qof_entity_get_guid(QOF_INSTANCE(book));
|
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))
|
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
|
* modify it in-place; if not, insert the new element into the
|
||||||
* hash. */
|
* hash. */
|
||||||
gnc_numeric* elem = g_hash_table_lookup(hash, guid);
|
gnc_numeric* elem = g_hash_table_lookup(hash, guid);
|
||||||
|
gchar guidstr[GUID_ENCODING_LENGTH+1];
|
||||||
|
guid_to_string_buff(guid, guidstr);
|
||||||
if (!elem)
|
if (!elem)
|
||||||
{
|
{
|
||||||
elem = g_new0(gnc_numeric, 1);
|
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].",
|
g_critical("Oops, the given amount [%s] has the error code %d, at guid [%s].",
|
||||||
gnc_num_dbg_to_string(*amount),
|
gnc_num_dbg_to_string(*amount),
|
||||||
gnc_numeric_check(*amount),
|
gnc_numeric_check(*amount),
|
||||||
guid_to_string(guid));
|
guidstr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (gnc_numeric_check(*elem) != GNC_ERROR_OK)
|
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].",
|
g_critical("Oops, the account's amount [%s] has the error code %d, at guid [%s].",
|
||||||
gnc_num_dbg_to_string(*elem),
|
gnc_num_dbg_to_string(*elem),
|
||||||
gnc_numeric_check(*elem),
|
gnc_numeric_check(*elem),
|
||||||
guid_to_string(guid));
|
guidstr);
|
||||||
return;
|
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)
|
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].",
|
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_num_dbg_to_string(*elem),
|
||||||
gnc_numeric_check(*elem),
|
gnc_numeric_check(*elem),
|
||||||
gnc_num_dbg_to_string(*amount));
|
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. */
|
/* In case anyone wants to see this in the debug log. */
|
||||||
g_debug("Adding to guid [%s] the value [%s]. Value now [%s].",
|
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(*amount),
|
||||||
gnc_num_dbg_to_string(*elem));
|
gnc_num_dbg_to_string(*elem));
|
||||||
}
|
}
|
||||||
|
@ -297,7 +297,7 @@ gnc_is_trans_scm(SCM scm)
|
|||||||
void
|
void
|
||||||
gnc_split_scm_set_account(SCM split_scm, Account *account)
|
gnc_split_scm_set_account(SCM split_scm, Account *account)
|
||||||
{
|
{
|
||||||
const char *guid_string;
|
gchar guid_string[GUID_ENCODING_LENGTH+1];
|
||||||
SCM arg;
|
SCM arg;
|
||||||
|
|
||||||
initialize_scm_functions();
|
initialize_scm_functions();
|
||||||
@ -307,7 +307,7 @@ gnc_split_scm_set_account(SCM split_scm, Account *account)
|
|||||||
if (account == NULL)
|
if (account == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
guid_string = guid_to_string(xaccAccountGetGUID(account));
|
guid_to_string_buff(xaccAccountGetGUID(account), guid_string);
|
||||||
if (guid_string == NULL)
|
if (guid_string == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -657,6 +657,7 @@ gnc_copy_trans_scm_onto_trans_swap_accounts(SCM trans_scm,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
gchar guidstr[GUID_ENCODING_LENGTH+1];
|
||||||
SCM from, to;
|
SCM from, to;
|
||||||
SCM map = SCM_EOL;
|
SCM map = SCM_EOL;
|
||||||
SCM args = 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);
|
args = scm_cons(commit, args);
|
||||||
|
|
||||||
from = scm_from_utf8_string(guid_to_string(guid_1));
|
guid_to_string_buff(guid_1, guidstr);
|
||||||
to = scm_from_utf8_string(guid_to_string(guid_2));
|
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(from, to), map);
|
||||||
map = scm_cons(scm_cons(to, from), 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);
|
kvp_exclude_type (KVP_TYPE_DOUBLE);
|
||||||
|
|
||||||
/* Initialize to a known RNG position */
|
/* Initialize to a known RNG position */
|
||||||
guid_init();
|
|
||||||
srand(1);
|
srand(1);
|
||||||
|
|
||||||
run_tests ();
|
run_tests ();
|
||||||
|
@ -225,8 +225,9 @@ load_single_split( GncSqlBackend* be, GncSqlRow* row )
|
|||||||
/*# -ifempty */
|
/*# -ifempty */
|
||||||
if (pSplit != xaccSplitLookup( &split_guid, be->book ))
|
if (pSplit != xaccSplitLookup( &split_guid, be->book ))
|
||||||
{
|
{
|
||||||
PERR("A malformed split with id %s was found in the dataset.",
|
gchar guidstr[GUID_ENCODING_LENGTH+1];
|
||||||
guid_to_string(qof_instance_get_guid(pSplit)));
|
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);
|
qof_backend_set_error( &be->be, ERR_BACKEND_DATA_CORRUPT);
|
||||||
pSplit = NULL;
|
pSplit = NULL;
|
||||||
}
|
}
|
||||||
@ -305,8 +306,9 @@ load_single_tx( GncSqlBackend* be, GncSqlRow* row )
|
|||||||
|
|
||||||
if (pTx != xaccTransLookup( &tx_guid, be->book ))
|
if (pTx != xaccTransLookup( &tx_guid, be->book ))
|
||||||
{
|
{
|
||||||
PERR("A malformed transaction with id %s was found in the dataset.",
|
gchar guidstr[GUID_ENCODING_LENGTH+1];
|
||||||
guid_to_string(qof_instance_get_guid(pTx)));
|
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);
|
qof_backend_set_error( &be->be, ERR_BACKEND_DATA_CORRUPT);
|
||||||
pTx = NULL;
|
pTx = NULL;
|
||||||
}
|
}
|
||||||
|
@ -588,8 +588,9 @@ billterm_scrub_cb (QofInstance *term_p, gpointer list_p)
|
|||||||
if (t)
|
if (t)
|
||||||
{
|
{
|
||||||
/* Fix up the broken "copy" function */
|
/* Fix up the broken "copy" function */
|
||||||
PWARN("Fixing broken child billterm: %s",
|
gchar guidstr[GUID_ENCODING_LENGTH+1];
|
||||||
guid_to_string(qof_instance_get_guid(QOF_INSTANCE(term))));
|
guid_to_string_buff(qof_instance_get_guid(QOF_INSTANCE(term)),guidstr);
|
||||||
|
PWARN("Fixing broken child billterm: %s", guidstr);
|
||||||
|
|
||||||
gncBillTermBeginEdit(term);
|
gncBillTermBeginEdit(term);
|
||||||
gncBillTermSetType(term, gncBillTermGetType(t));
|
gncBillTermSetType(term, gncBillTermGetType(t));
|
||||||
@ -624,8 +625,9 @@ billterm_scrub_invoices (QofInstance * invoice_p, gpointer ht_p)
|
|||||||
{
|
{
|
||||||
if (billterm_is_grandchild(term))
|
if (billterm_is_grandchild(term))
|
||||||
{
|
{
|
||||||
PWARN("Fixing i-billterm on invoice %s\n",
|
gchar guidstr[GUID_ENCODING_LENGTH+1];
|
||||||
guid_to_string(qof_instance_get_guid(QOF_INSTANCE(invoice))));
|
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);
|
new_bt = billterm_find_senior(term);
|
||||||
gncInvoiceBeginEdit(invoice);
|
gncInvoiceBeginEdit(invoice);
|
||||||
gncInvoiceSetTerms(invoice, new_bt);
|
gncInvoiceSetTerms(invoice, new_bt);
|
||||||
@ -656,9 +658,13 @@ billterm_scrub_cust (QofInstance * cust_p, gpointer ht_p)
|
|||||||
count++;
|
count++;
|
||||||
g_hash_table_insert(ht, term, GINT_TO_POINTER(count));
|
g_hash_table_insert(ht, term, GINT_TO_POINTER(count));
|
||||||
if (billterm_is_grandchild(term))
|
if (billterm_is_grandchild(term))
|
||||||
PWARN("customer %s has grandchild billterm %s\n",
|
{
|
||||||
guid_to_string(qof_instance_get_guid(QOF_INSTANCE(cust))),
|
gchar custstr[GUID_ENCODING_LENGTH+1];
|
||||||
guid_to_string(qof_instance_get_guid(QOF_INSTANCE(term))));
|
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++;
|
count++;
|
||||||
g_hash_table_insert(ht, term, GINT_TO_POINTER(count));
|
g_hash_table_insert(ht, term, GINT_TO_POINTER(count));
|
||||||
if (billterm_is_grandchild(term))
|
if (billterm_is_grandchild(term))
|
||||||
PWARN("vendor %s has grandchild billterm %s\n",
|
{
|
||||||
guid_to_string(qof_instance_get_guid(QOF_INSTANCE(vendor))),
|
gchar vendstr[GUID_ENCODING_LENGTH+1];
|
||||||
guid_to_string(qof_instance_get_guid(QOF_INSTANCE(term))));
|
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))
|
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",
|
PWARN("Fixing refcount on billterm %s (%" G_GINT64_FORMAT " -> %d)\n",
|
||||||
guid_to_string(qof_instance_get_guid(QOF_INSTANCE(term))),
|
termstr, gncBillTermGetRefcount(term), count);
|
||||||
gncBillTermGetRefcount(term), count);
|
|
||||||
gncBillTermSetRefcount(term, count);
|
gncBillTermSetRefcount(term, count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -715,10 +726,11 @@ billterm_scrub (QofBook *book)
|
|||||||
/* destroy the list of "grandchildren" bill terms */
|
/* destroy the list of "grandchildren" bill terms */
|
||||||
for (node = list; node; node = node->next)
|
for (node = list; node; node = node->next)
|
||||||
{
|
{
|
||||||
|
gchar termstr[GUID_ENCODING_LENGTH+1];
|
||||||
term = node->data;
|
term = node->data;
|
||||||
|
|
||||||
PWARN ("deleting grandchild billterm: %s\n",
|
guid_to_string_buff(qof_instance_get_guid(QOF_INSTANCE(term)), termstr);
|
||||||
guid_to_string(qof_instance_get_guid(QOF_INSTANCE(term))));
|
PWARN ("deleting grandchild billterm: %s\n", termstr);
|
||||||
|
|
||||||
/* Make sure the parent has no children */
|
/* Make sure the parent has no children */
|
||||||
parent = gncBillTermGetParent(term);
|
parent = gncBillTermGetParent(term);
|
||||||
@ -770,11 +782,13 @@ GncBillTerm *
|
|||||||
gnc_billterm_xml_find_or_create(QofBook *book, GncGUID *guid)
|
gnc_billterm_xml_find_or_create(QofBook *book, GncGUID *guid)
|
||||||
{
|
{
|
||||||
GncBillTerm *term;
|
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(book, NULL);
|
||||||
g_return_val_if_fail(guid, NULL);
|
g_return_val_if_fail(guid, NULL);
|
||||||
term = gncBillTermLookup(book, guid);
|
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)
|
if (!term)
|
||||||
{
|
{
|
||||||
term = gncBillTermCreate(book);
|
term = gncBillTermCreate(book);
|
||||||
|
@ -740,10 +740,10 @@ gnc_schedXaction_end_handler(gpointer data_for_children,
|
|||||||
if ( sx->template_acct == NULL )
|
if ( sx->template_acct == NULL )
|
||||||
{
|
{
|
||||||
Account *ra = NULL;
|
Account *ra = NULL;
|
||||||
const char *id = NULL;
|
|
||||||
Account *acct = NULL;
|
Account *acct = NULL;
|
||||||
sixtp_gdv2 *sixdata = gdata->parsedata;
|
sixtp_gdv2 *sixdata = gdata->parsedata;
|
||||||
QofBook *book;
|
QofBook *book;
|
||||||
|
gchar guidstr[GUID_ENCODING_LENGTH+1];
|
||||||
|
|
||||||
book = sixdata->book;
|
book = sixdata->book;
|
||||||
|
|
||||||
@ -751,8 +751,7 @@ gnc_schedXaction_end_handler(gpointer data_for_children,
|
|||||||
change re: storing template accounts. */
|
change re: storing template accounts. */
|
||||||
/* Fix: get account with name of our GncGUID from the template
|
/* Fix: get account with name of our GncGUID from the template
|
||||||
accounts. Make that our template_acct pointer. */
|
accounts. Make that our template_acct pointer. */
|
||||||
/* THREAD-UNSAFE */
|
guid_to_string_buff( xaccSchedXactionGetGUID( sx ), guidstr );
|
||||||
id = guid_to_string( xaccSchedXactionGetGUID( sx ) );
|
|
||||||
ra = gnc_book_get_template_root(book);
|
ra = gnc_book_get_template_root(book);
|
||||||
if ( ra == NULL )
|
if ( ra == NULL )
|
||||||
{
|
{
|
||||||
@ -760,15 +759,15 @@ gnc_schedXaction_end_handler(gpointer data_for_children,
|
|||||||
xmlFreeNode( tree );
|
xmlFreeNode( tree );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
acct = gnc_account_lookup_by_name( ra, id );
|
acct = gnc_account_lookup_by_name( ra, guidstr );
|
||||||
if ( acct == NULL )
|
if ( acct == NULL )
|
||||||
{
|
{
|
||||||
g_warning("no template account with name [%s]", id);
|
g_warning("no template account with name [%s]", guidstr);
|
||||||
xmlFreeNode( tree );
|
xmlFreeNode( tree );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
g_debug("template account name [%s] for SX with GncGUID [%s]",
|
g_debug("template account name [%s] for SX with GncGUID [%s]",
|
||||||
xaccAccountGetName( acct ), id );
|
xaccAccountGetName( acct ), guidstr );
|
||||||
|
|
||||||
/* FIXME: free existing template account.
|
/* FIXME: free existing template account.
|
||||||
* HUH????? We only execute this if there isn't
|
* 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))
|
if (taxtable_is_grandchild(table))
|
||||||
{
|
{
|
||||||
PINFO("Fixing i-taxtable on entry %s\n",
|
gchar guidstr[GUID_ENCODING_LENGTH+1];
|
||||||
guid_to_string(qof_instance_get_guid(QOF_INSTANCE(entry))));
|
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);
|
new_tt = taxtable_find_senior(table);
|
||||||
gncEntryBeginEdit(entry);
|
gncEntryBeginEdit(entry);
|
||||||
gncEntrySetInvTaxTable(entry, new_tt);
|
gncEntrySetInvTaxTable(entry, new_tt);
|
||||||
@ -597,8 +598,9 @@ taxtable_scrub_entries (QofInstance * entry_p, gpointer ht_p)
|
|||||||
{
|
{
|
||||||
if (taxtable_is_grandchild(table))
|
if (taxtable_is_grandchild(table))
|
||||||
{
|
{
|
||||||
PINFO("Fixing b-taxtable on entry %s\n",
|
gchar guidstr[GUID_ENCODING_LENGTH+1];
|
||||||
guid_to_string(qof_instance_get_guid(QOF_INSTANCE(entry))));
|
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);
|
new_tt = taxtable_find_senior(table);
|
||||||
gncEntryBeginEdit(entry);
|
gncEntryBeginEdit(entry);
|
||||||
gncEntrySetBillTaxTable(entry, new_tt);
|
gncEntrySetBillTaxTable(entry, new_tt);
|
||||||
@ -656,9 +658,10 @@ taxtable_reset_refcount (gpointer key, gpointer value, gpointer notused)
|
|||||||
|
|
||||||
if (count != gncTaxTableGetRefcount(table) && !gncTaxTableGetInvisible(table))
|
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",
|
PWARN("Fixing refcount on taxtable %s (%" G_GINT64_FORMAT " -> %d)\n",
|
||||||
guid_to_string(qof_instance_get_guid(QOF_INSTANCE(table))),
|
guidstr,gncTaxTableGetRefcount(table), count);
|
||||||
gncTaxTableGetRefcount(table), count);
|
|
||||||
gncTaxTableSetRefcount(table, count);
|
gncTaxTableSetRefcount(table, count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -679,10 +682,11 @@ taxtable_scrub (QofBook *book)
|
|||||||
/* destroy the list of "grandchildren" tax tables */
|
/* destroy the list of "grandchildren" tax tables */
|
||||||
for (node = list; node; node = node->next)
|
for (node = list; node; node = node->next)
|
||||||
{
|
{
|
||||||
|
gchar guidstr[GUID_ENCODING_LENGTH+1];
|
||||||
table = node->data;
|
table = node->data;
|
||||||
|
|
||||||
PINFO ("deleting grandchild taxtable: %s\n",
|
guid_to_string_buff(qof_instance_get_guid(QOF_INSTANCE(table)),guidstr);
|
||||||
guid_to_string(qof_instance_get_guid(QOF_INSTANCE(table))));
|
PINFO ("deleting grandchild taxtable: %s\n", guidstr);
|
||||||
|
|
||||||
/* Make sure the parent has no children */
|
/* Make sure the parent has no children */
|
||||||
parent = gncTaxTableGetParent(table);
|
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");
|
xmlSetProp(val_node, BAD_CAST "type", BAD_CAST "string");
|
||||||
break;
|
break;
|
||||||
case KVP_TYPE_GUID:
|
case KVP_TYPE_GUID:
|
||||||
/* THREAD-UNSAFE */
|
{
|
||||||
add_text_to_node(val_node, "guid",
|
gchar guidstr[GUID_ENCODING_LENGTH+1];
|
||||||
g_strdup(guid_to_string(kvp_value_get_guid(val))));
|
guid_to_string_buff(kvp_value_get_guid(val), guidstr);
|
||||||
|
add_text_to_node(val_node, "guid", guidstr);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case KVP_TYPE_TIMESPEC:
|
case KVP_TYPE_TIMESPEC:
|
||||||
{
|
{
|
||||||
Timespec ts = kvp_value_get_timespec (val);
|
Timespec ts = kvp_value_get_timespec (val);
|
||||||
|
@ -218,7 +218,9 @@ equals_node_val_vs_splits(xmlNodePtr node, const Transaction *trn)
|
|||||||
|
|
||||||
if (!spl_node)
|
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";
|
return "no matching split found";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2177,24 +2177,25 @@ gnc_invoice_save_page (InvoiceWindow *iw,
|
|||||||
GKeyFile *key_file,
|
GKeyFile *key_file,
|
||||||
const gchar *group_name)
|
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,
|
g_key_file_set_string(key_file, group_name, KEY_INVOICE_TYPE,
|
||||||
InvoiceDialogTypeasString(iw->dialog_type));
|
InvoiceDialogTypeasString(iw->dialog_type));
|
||||||
g_key_file_set_string(key_file, group_name, KEY_INVOICE_GUID,
|
g_key_file_set_string(key_file, group_name, KEY_INVOICE_GUID, guidstr);
|
||||||
guid_to_string(&iw->invoice_guid));
|
|
||||||
|
|
||||||
if (gncOwnerGetJob (&(iw->job)))
|
if (gncOwnerGetJob (&(iw->job)))
|
||||||
{
|
{
|
||||||
g_key_file_set_string(key_file, group_name, KEY_OWNER_TYPE,
|
g_key_file_set_string(key_file, group_name, KEY_OWNER_TYPE,
|
||||||
qofOwnerGetType(&iw->job));
|
qofOwnerGetType(&iw->job));
|
||||||
g_key_file_set_string(key_file, group_name, KEY_OWNER_GUID,
|
guid_to_string_buff(gncOwnerGetGUID(&iw->job), guidstr);
|
||||||
guid_to_string(gncOwnerGetGUID(&iw->job)));
|
g_key_file_set_string(key_file, group_name, KEY_OWNER_GUID, guidstr);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
g_key_file_set_string(key_file, group_name, KEY_OWNER_TYPE,
|
g_key_file_set_string(key_file, group_name, KEY_OWNER_TYPE,
|
||||||
qofOwnerGetType(&iw->owner));
|
qofOwnerGetType(&iw->owner));
|
||||||
g_key_file_set_string(key_file, group_name, KEY_OWNER_GUID,
|
guid_to_string_buff(gncOwnerGetGUID(&iw->owner), guidstr);
|
||||||
guid_to_string(gncOwnerGetGUID(&iw->owner)));
|
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
|
You can encode and decode GUIDs and their string representations using the
|
||||||
next two functions.
|
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
|
Return a null-terminated string encoding of @var{guid}. String encodings
|
||||||
of identifiers are hex numbers printed only with the characters @code{0}
|
of identifiers are hex numbers printed only with the characters @code{0}
|
||||||
through @code{9} and @code{a} through @code{f}. The encoding will
|
through @code{9} and @code{a} through @code{f}. The encoding will
|
||||||
always be @code{GUID_ENCODING_LENGTH} characters long. The returned
|
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
|
@end deftypefun
|
||||||
|
|
||||||
@deftypefun {char *} guid_to_string_buff (const GUID * @var{guid}, char * @var{buff})
|
@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
|
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
|
is unique within the scope of all GnuCash entities being managed by the
|
||||||
the current invocation of GnuCash. GnuCash routines should always use
|
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
|
@end deftypefun
|
||||||
|
|
||||||
@deftypefun {void *} xaccLookupEntity (const GUID * @var{guid}, GNCIdType @var{entity_type})
|
@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
|
GUIDs are created by the GUID generator. The API for this generator is
|
||||||
low-level and should not be used by user-code.
|
low-level and should not be used by user-code.
|
||||||
|
|
||||||
@deftypefun void guid_init (void)
|
@deftypefun void guid_replace (GUID * @var{guid})
|
||||||
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})
|
|
||||||
Create a new GUID and store it in @var{guid}. This is a low-level function!
|
Create a new GUID and store it in @var{guid}. This is a low-level function!
|
||||||
GnuCash code should use @code{xaccGUIDNew}.
|
GnuCash code should use @code{xaccGUIDNew}.
|
||||||
@end deftypefun
|
@end deftypefun
|
||||||
|
@ -380,6 +380,7 @@ xaccSchedXactionInit(SchedXaction *sx, QofBook *book)
|
|||||||
{
|
{
|
||||||
Account *ra;
|
Account *ra;
|
||||||
const GncGUID *guid;
|
const GncGUID *guid;
|
||||||
|
gchar guidstr[GUID_ENCODING_LENGTH+1];
|
||||||
|
|
||||||
qof_instance_init_data (&sx->inst, GNC_ID_SCHEDXACTION, book);
|
qof_instance_init_data (&sx->inst, GNC_ID_SCHEDXACTION, book);
|
||||||
|
|
||||||
@ -387,7 +388,8 @@ xaccSchedXactionInit(SchedXaction *sx, QofBook *book)
|
|||||||
sx->template_acct = xaccMallocAccount(book);
|
sx->template_acct = xaccMallocAccount(book);
|
||||||
guid = qof_instance_get_guid( sx );
|
guid = qof_instance_get_guid( sx );
|
||||||
xaccAccountBeginEdit( sx->template_acct );
|
xaccAccountBeginEdit( sx->template_acct );
|
||||||
xaccAccountSetName( sx->template_acct, guid_to_string( guid ));
|
guid_to_string_buff( guid, guidstr );
|
||||||
|
xaccAccountSetName( sx->template_acct, guidstr);
|
||||||
xaccAccountSetCommodity
|
xaccAccountSetCommodity
|
||||||
(sx->template_acct,
|
(sx->template_acct,
|
||||||
gnc_commodity_table_lookup( gnc_commodity_table_get_table(book),
|
gnc_commodity_table_lookup( gnc_commodity_table_get_table(book),
|
||||||
|
@ -1450,8 +1450,10 @@ xaccSplitConvertAmount (const Split *split, const Account * account)
|
|||||||
xaccAccountGetCommodity(xaccSplitGetAccount(osplit));
|
xaccAccountGetCommodity(xaccSplitGetAccount(osplit));
|
||||||
if (!gnc_commodity_equal(to_commodity, split_comm))
|
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.",
|
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(split_comm),
|
||||||
gnc_commodity_get_mnemonic(to_commodity)
|
gnc_commodity_get_mnemonic(to_commodity)
|
||||||
);
|
);
|
||||||
|
@ -971,8 +971,10 @@ xaccTransEqual(const Transaction *ta, const Transaction *tb,
|
|||||||
|
|
||||||
if (!node_b)
|
if (!node_b)
|
||||||
{
|
{
|
||||||
PINFO ("first has split %s and second does not",
|
gchar guidstr[GUID_ENCODING_LENGTH+1];
|
||||||
guid_to_string (xaccSplitGetGUID (split_a)));
|
guid_to_string_buff (xaccSplitGetGUID (split_a),guidstr);
|
||||||
|
|
||||||
|
PINFO ("first has split %s and second does not",guidstr);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -266,9 +266,10 @@ GncBillTerm * gncBillTermCreate (QofBook *book)
|
|||||||
|
|
||||||
void gncBillTermDestroy (GncBillTerm *term)
|
void gncBillTermDestroy (GncBillTerm *term)
|
||||||
{
|
{
|
||||||
|
gchar guidstr[GUID_ENCODING_LENGTH+1];
|
||||||
if (!term) return;
|
if (!term) return;
|
||||||
DEBUG("destroying bill term %s (%p)",
|
guid_to_string_buff(qof_instance_get_guid(&term->inst),guidstr);
|
||||||
guid_to_string(qof_instance_get_guid(&term->inst)), term);
|
DEBUG("destroying bill term %s (%p)", guidstr, term);
|
||||||
qof_instance_set_destroying(term, TRUE);
|
qof_instance_set_destroying(term, TRUE);
|
||||||
qof_instance_set_dirty (&term->inst);
|
qof_instance_set_dirty (&term->inst);
|
||||||
gncBillTermCommitEdit (term);
|
gncBillTermCommitEdit (term);
|
||||||
|
@ -243,7 +243,7 @@ get_random_guid(void)
|
|||||||
GncGUID *ret;
|
GncGUID *ret;
|
||||||
|
|
||||||
ret = g_new(GncGUID, 1);
|
ret = g_new(GncGUID, 1);
|
||||||
guid_new(ret);
|
guid_replace(ret);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -90,7 +90,7 @@ test_customer (void)
|
|||||||
do_test (gncCustomerGetAddr (customer) != NULL, "Addr");
|
do_test (gncCustomerGetAddr (customer) != NULL, "Addr");
|
||||||
do_test (gncCustomerGetShipAddr (customer) != NULL, "ShipAddr");
|
do_test (gncCustomerGetShipAddr (customer) != NULL, "ShipAddr");
|
||||||
|
|
||||||
guid_new (&guid);
|
guid_replace (&guid);
|
||||||
customer = gncCustomerCreate (book);
|
customer = gncCustomerCreate (book);
|
||||||
count++;
|
count++;
|
||||||
gncCustomerSetGUID (customer, &guid);
|
gncCustomerSetGUID (customer, &guid);
|
||||||
|
@ -96,7 +96,7 @@ test_employee (void)
|
|||||||
|
|
||||||
do_test (gncEmployeeGetAddr (employee) != NULL, "Addr");
|
do_test (gncEmployeeGetAddr (employee) != NULL, "Addr");
|
||||||
|
|
||||||
guid_new (&guid);
|
guid_replace (&guid);
|
||||||
employee = gncEmployeeCreate (book);
|
employee = gncEmployeeCreate (book);
|
||||||
count++;
|
count++;
|
||||||
gncEmployeeSetGUID (employee, &guid);
|
gncEmployeeSetGUID (employee, &guid);
|
||||||
|
@ -42,11 +42,12 @@ static void test_null_guid(void)
|
|||||||
GncGUID *gp;
|
GncGUID *gp;
|
||||||
|
|
||||||
g = guid_new_return();
|
g = guid_new_return();
|
||||||
gp = guid_malloc();
|
gp = guid_new();
|
||||||
guid_new(gp);
|
|
||||||
|
|
||||||
do_test(guid_equal(guid_null(), guid_null()), "null guids equal");
|
do_test(guid_equal(guid_null(), guid_null()), "null guids equal");
|
||||||
do_test(!guid_equal(&g, gp), "two guids equal");
|
do_test(!guid_equal(&g, gp), "two guids equal");
|
||||||
|
|
||||||
|
guid_free(gp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -70,7 +71,7 @@ run_test (void)
|
|||||||
for (i = 0; i < NENT; i++)
|
for (i = 0; i < NENT; i++)
|
||||||
{
|
{
|
||||||
ent = g_object_new(QOF_TYPE_INSTANCE, NULL);
|
ent = g_object_new(QOF_TYPE_INSTANCE, NULL);
|
||||||
guid_new(&guid);
|
guid_replace(&guid);
|
||||||
ent = g_object_new(QOF_TYPE_INSTANCE, "guid", &guid, NULL);
|
ent = g_object_new(QOF_TYPE_INSTANCE, "guid", &guid, NULL);
|
||||||
do_test ((NULL == qof_collection_lookup_entity (col, &guid)),
|
do_test ((NULL == qof_collection_lookup_entity (col, &guid)),
|
||||||
"duplicate guid");
|
"duplicate guid");
|
||||||
|
@ -91,7 +91,7 @@ test_job (void)
|
|||||||
|
|
||||||
test_bool_fcn (book, "Active", gncJobSetActive, gncJobGetActive);
|
test_bool_fcn (book, "Active", gncJobSetActive, gncJobGetActive);
|
||||||
|
|
||||||
guid_new (&guid);
|
guid_replace (&guid);
|
||||||
job = gncJobCreate (book);
|
job = gncJobCreate (book);
|
||||||
count++;
|
count++;
|
||||||
gncJobSetGUID (job, &guid);
|
gncJobSetGUID (job, &guid);
|
||||||
|
@ -96,7 +96,7 @@ test_vendor (void)
|
|||||||
|
|
||||||
do_test (gncVendorGetAddr (vendor) != NULL, "Addr");
|
do_test (gncVendorGetAddr (vendor) != NULL, "Addr");
|
||||||
|
|
||||||
guid_new (&guid);
|
guid_replace (&guid);
|
||||||
vendor = gncVendorCreate (book);
|
vendor = gncVendorCreate (book);
|
||||||
count++;
|
count++;
|
||||||
gncVendorSetGUID (vendor, &guid);
|
gncVendorSetGUID (vendor, &guid);
|
||||||
|
@ -974,6 +974,7 @@ test_xaccSplitConvertAmount (void)
|
|||||||
"GNCXX", "", 1000);
|
"GNCXX", "", 1000);
|
||||||
gnc_commodity *gnm = gnc_commodity_new (book, "Gnome, Inc.", "NYSE",
|
gnc_commodity *gnm = gnc_commodity_new (book, "Gnome, Inc.", "NYSE",
|
||||||
"GNM", "", 1000);
|
"GNM", "", 1000);
|
||||||
|
gchar guidstr[GUID_ENCODING_LENGTH+1];
|
||||||
|
|
||||||
Account *acc = xaccMallocAccount (book);
|
Account *acc = xaccMallocAccount (book);
|
||||||
Account *o_acc = xaccMallocAccount (book);
|
Account *o_acc = xaccMallocAccount (book);
|
||||||
@ -991,7 +992,8 @@ test_xaccSplitConvertAmount (void)
|
|||||||
TestErrorStruct check = { loglevel, logdomain, NULL, 0 };
|
TestErrorStruct check = { loglevel, logdomain, NULL, 0 };
|
||||||
GLogFunc oldlogger = g_log_set_default_handler ((GLogFunc)test_null_handler, &check);
|
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 (acc, gnaira);
|
||||||
xaccAccountSetCommodity (o_acc, gnaira);
|
xaccAccountSetCommodity (o_acc, gnaira);
|
||||||
xaccAccountSetCommodity (ya_acc, gnm);
|
xaccAccountSetCommodity (ya_acc, gnm);
|
||||||
|
@ -105,7 +105,7 @@ GList * logged_in_users = NULL;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
auth_user (const char * name, const char *passwd)
|
auth_user (const char * name, const char *passwd, char *buff)
|
||||||
{
|
{
|
||||||
GncGUID *guid;
|
GncGUID *guid;
|
||||||
const char *session_auth_string;
|
const char *session_auth_string;
|
||||||
@ -115,11 +115,11 @@ auth_user (const char * name, const char *passwd)
|
|||||||
*/
|
*/
|
||||||
if (!name || !passwd) return NULL;
|
if (!name || !passwd) return NULL;
|
||||||
|
|
||||||
guid = g_new (GncGUID, 1);
|
guid = guid_new();
|
||||||
guid_new (guid);
|
|
||||||
logged_in_users = g_list_prepend (logged_in_users, guid);
|
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 *user_agent;
|
||||||
const char *auth_string;
|
const char *auth_string;
|
||||||
const char *content_length;
|
const char *content_length;
|
||||||
|
gchar guidstr[GUID_ENCODING_LENGTH+1];
|
||||||
int read_len = 0;
|
int read_len = 0;
|
||||||
int send_accts = 0;
|
int send_accts = 0;
|
||||||
|
|
||||||
@ -301,7 +302,7 @@ main (int argc, char *argv[])
|
|||||||
char *name = NULL, *passwd = NULL;
|
char *name = NULL, *passwd = NULL;
|
||||||
parse_for_login (request_bufp, &name, &passwd);
|
parse_for_login (request_bufp, &name, &passwd);
|
||||||
|
|
||||||
auth_string = auth_user (name, passwd);
|
auth_string = auth_user (name, passwd, guidstr);
|
||||||
if (!auth_string)
|
if (!auth_string)
|
||||||
{
|
{
|
||||||
reject_auth();
|
reject_auth();
|
||||||
|
@ -767,7 +767,7 @@ pcd_save_custom_data(PrintCheckDialog *pcd, const gchar *title)
|
|||||||
multip = pcd_get_custom_multip(pcd);
|
multip = pcd_get_custom_multip(pcd);
|
||||||
|
|
||||||
key_file = g_key_file_new();
|
key_file = g_key_file_new();
|
||||||
guid_new(&guid);
|
guid_replace(&guid);
|
||||||
guid_to_string_buff(&guid, buf);
|
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_GUID, buf);
|
||||||
g_key_file_set_string(key_file, KF_GROUP_TOP, KF_KEY_TITLE, title);
|
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);
|
multip = pcd_get_custom_multip(pcd);
|
||||||
|
|
||||||
key_file = g_key_file_new();
|
key_file = g_key_file_new();
|
||||||
guid_new(&guid);
|
guid_replace(&guid);
|
||||||
guid_to_string_buff(&guid, buf);
|
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_GUID, buf);
|
||||||
g_key_file_set_string(key_file, KF_GROUP_TOP, KF_KEY_TITLE, title);
|
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;
|
GtkWidget *main_vbox;
|
||||||
|
|
||||||
/* Create the ledger */
|
/* Create the ledger */
|
||||||
/* THREAD-UNSAFE */
|
sxed->sxGUIDstr = guid_to_string( xaccSchedXactionGetGUID(sxed->sx) );
|
||||||
sxed->sxGUIDstr = g_strdup( guid_to_string(
|
|
||||||
xaccSchedXactionGetGUID(sxed->sx) ) );
|
|
||||||
sxed->ledger = gnc_ledger_display_template_gl( sxed->sxGUIDstr );
|
sxed->ledger = gnc_ledger_display_template_gl( sxed->sxGUIDstr );
|
||||||
splitreg = gnc_ledger_display_get_split_register( sxed->ledger );
|
splitreg = gnc_ledger_display_get_split_register( sxed->ledger );
|
||||||
|
|
||||||
|
@ -1276,8 +1276,7 @@ schedXact_editor_create_ledger (GncSxEditorDialog2 *sxed)
|
|||||||
GtkWidget *label;
|
GtkWidget *label;
|
||||||
|
|
||||||
/* Create the ledger */
|
/* Create the ledger */
|
||||||
/* THREAD-UNSAFE */
|
sxed->sxGUIDstr = guid_to_string (xaccSchedXactionGetGUID (sxed->sx));
|
||||||
sxed->sxGUIDstr = g_strdup (guid_to_string (xaccSchedXactionGetGUID (sxed->sx)));
|
|
||||||
sxed->ledger = gnc_ledger_display2_template_gl (sxed->sxGUIDstr);
|
sxed->ledger = gnc_ledger_display2_template_gl (sxed->sxGUIDstr);
|
||||||
model = gnc_ledger_display2_get_split_model_register (sxed->ledger);
|
model = gnc_ledger_display2_get_split_model_register (sxed->ledger);
|
||||||
|
|
||||||
|
@ -289,6 +289,7 @@ gbv_create_widget(GncBudgetView *view)
|
|||||||
GtkTreeIter iter;
|
GtkTreeIter iter;
|
||||||
GtkWidget* h_separator;
|
GtkWidget* h_separator;
|
||||||
gchar *state_section;
|
gchar *state_section;
|
||||||
|
gchar guidstr[GUID_ENCODING_LENGTH+1];
|
||||||
|
|
||||||
priv = GNC_BUDGET_VIEW_GET_PRIVATE(view);
|
priv = GNC_BUDGET_VIEW_GET_PRIVATE(view);
|
||||||
vbox = GTK_VBOX(view);
|
vbox = GTK_VBOX(view);
|
||||||
@ -315,7 +316,8 @@ gbv_create_widget(GncBudgetView *view)
|
|||||||
tree_view = gnc_tree_view_account_new(FALSE);
|
tree_view = gnc_tree_view_account_new(FALSE);
|
||||||
gtk_container_add(GTK_CONTAINER(inner_scrolled_window), GTK_WIDGET(tree_view));
|
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_object_set(G_OBJECT(tree_view), "state-section", state_section, NULL);
|
||||||
g_free (state_section);
|
g_free (state_section);
|
||||||
|
|
||||||
@ -487,13 +489,16 @@ void
|
|||||||
gnc_budget_view_delete_budget(GncBudgetView *view)
|
gnc_budget_view_delete_budget(GncBudgetView *view)
|
||||||
{
|
{
|
||||||
GncBudgetViewPrivate *priv;
|
GncBudgetViewPrivate *priv;
|
||||||
|
gchar guidstr[GUID_ENCODING_LENGTH+1];
|
||||||
|
|
||||||
g_return_if_fail(view != NULL);
|
g_return_if_fail(view != NULL);
|
||||||
|
|
||||||
ENTER("view %p", view);
|
ENTER("view %p", view);
|
||||||
|
|
||||||
priv = GNC_BUDGET_VIEW_GET_PRIVATE (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);
|
g_object_set (G_OBJECT (priv->tree_view), "state-section", NULL, NULL);
|
||||||
|
|
||||||
LEAVE(" ");
|
LEAVE(" ");
|
||||||
|
@ -1397,7 +1397,7 @@ gnc_plugin_page_account_tree_cmd_delete_account (GtkAction *action, GncPluginPag
|
|||||||
{
|
{
|
||||||
GList *acct_list, *ptr;
|
GList *acct_list, *ptr;
|
||||||
const GncGUID *guid;
|
const GncGUID *guid;
|
||||||
const gchar *guid_str;
|
gchar guidstr[GUID_ENCODING_LENGTH+1];
|
||||||
|
|
||||||
gnc_set_busy_cursor(NULL, TRUE);
|
gnc_set_busy_cursor(NULL, TRUE);
|
||||||
gnc_suspend_gui_refresh ();
|
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))
|
for (ptr = acct_list; ptr; ptr = g_list_next(ptr))
|
||||||
{
|
{
|
||||||
guid = xaccAccountGetGUID (ptr->data);
|
guid = xaccAccountGetGUID (ptr->data);
|
||||||
guid_str = guid_to_string (guid);
|
guid_to_string_buff (guid, guidstr);
|
||||||
gnc_state_drop_sections_for (guid_str);
|
gnc_state_drop_sections_for (guidstr);
|
||||||
}
|
}
|
||||||
g_list_free(acct_list);
|
g_list_free(acct_list);
|
||||||
|
|
||||||
/* Drop all references from the state file for this account
|
/* Drop all references from the state file for this account
|
||||||
*/
|
*/
|
||||||
guid = xaccAccountGetGUID (account);
|
guid = xaccAccountGetGUID (account);
|
||||||
guid_str = guid_to_string (guid);
|
guid_to_string_buff (guid, guidstr);
|
||||||
gnc_state_drop_sections_for (guid_str);
|
gnc_state_drop_sections_for (guidstr);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Finally, delete the account, any subaccounts it may still
|
* Finally, delete the account, any subaccounts it may still
|
||||||
|
@ -385,16 +385,15 @@ static
|
|||||||
void
|
void
|
||||||
gsr_create_table( GNCSplitReg *gsr )
|
gsr_create_table( GNCSplitReg *gsr )
|
||||||
{
|
{
|
||||||
GtkWidget *register_widget;
|
GtkWidget *register_widget = NULL;
|
||||||
SplitRegister *sr;
|
SplitRegister *sr = NULL;
|
||||||
|
|
||||||
gchar *state_section;
|
Account * account = gnc_ledger_display_leader(gsr->ledger);
|
||||||
const GncGUID * guid;
|
const GncGUID * guid = xaccAccountGetGUID(account);
|
||||||
Account * account;
|
gchar guidstr[GUID_ENCODING_LENGTH+1];
|
||||||
|
gchar *state_section = NULL;
|
||||||
account = gnc_ledger_display_leader(gsr->ledger);
|
guid_to_string_buff(guid, guidstr);
|
||||||
guid = xaccAccountGetGUID(account);
|
state_section = g_strconcat (STATE_SECTION_REG_PREFIX, " ", guidstr, NULL);
|
||||||
state_section = g_strconcat (STATE_SECTION_REG_PREFIX, " ", (gchar*)guid_to_string (guid), NULL);
|
|
||||||
|
|
||||||
ENTER("gsr=%p", gsr);
|
ENTER("gsr=%p", gsr);
|
||||||
|
|
||||||
@ -693,13 +692,14 @@ gnc_split_reg_ld_destroy( GNCLedgerDisplay *ledger )
|
|||||||
{
|
{
|
||||||
GNCSplitReg *gsr = gnc_ledger_display_get_user_data( 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;
|
gchar *state_section;
|
||||||
const GncGUID * guid;
|
|
||||||
Account * account;
|
|
||||||
|
|
||||||
account = gnc_ledger_display_leader(ledger);
|
guid_to_string_buff(guid, guidstr);
|
||||||
guid = xaccAccountGetGUID(account);
|
|
||||||
state_section = g_strconcat (STATE_SECTION_REG_PREFIX, " ",(gchar*)guid_to_string (guid), NULL);
|
state_section = g_strconcat (STATE_SECTION_REG_PREFIX, " ", guidstr, NULL);
|
||||||
|
|
||||||
if (gsr)
|
if (gsr)
|
||||||
{
|
{
|
||||||
|
@ -262,9 +262,17 @@ gsr2_create_table (GNCSplitReg2 *gsr)
|
|||||||
if (ledger_type == LD2_GL && model->type == GENERAL_LEDGER2)
|
if (ledger_type == LD2_GL && model->type == GENERAL_LEDGER2)
|
||||||
state_section = g_strdup (STATE_SECTION_GEN_LEDGER);
|
state_section = g_strdup (STATE_SECTION_GEN_LEDGER);
|
||||||
else if (ledger_type == LD2_SUBACCOUNT)
|
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
|
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,
|
g_object_set (G_OBJECT (view), "state-section", state_section,
|
||||||
"show-column-menu", FALSE, NULL);
|
"show-column-menu", FALSE, NULL);
|
||||||
|
|
||||||
@ -680,31 +688,6 @@ gsr2_redraw_all_cb (GncTreeViewSplitReg *view, gpointer user_data)
|
|||||||
static void
|
static void
|
||||||
gnc_split_reg2_ld_destroy (GNCLedgerDisplay2 *ledger)
|
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);
|
gnc_ledger_display2_set_user_data (ledger, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -309,7 +309,7 @@ static void
|
|||||||
gnc_save_all_state (gpointer session, gpointer unused)
|
gnc_save_all_state (gpointer session, gpointer unused)
|
||||||
{
|
{
|
||||||
QofBook *book;
|
QofBook *book;
|
||||||
const gchar *guid_string;
|
gchar guid_string[GUID_ENCODING_LENGTH+1];
|
||||||
const GncGUID *guid;
|
const GncGUID *guid;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
GKeyFile *keyfile = 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 */
|
/* Store the book's GncGUID in the top level group */
|
||||||
book = qof_session_get_book(session);
|
book = qof_session_get_book(session);
|
||||||
guid = qof_entity_get_guid(QOF_INSTANCE(book));
|
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,
|
g_key_file_set_string(keyfile, STATE_FILE_TOP, STATE_FILE_BOOK_GUID,
|
||||||
guid_string);
|
guid_string);
|
||||||
|
|
||||||
|
@ -284,11 +284,13 @@ static void dump_split_record(split_record record)
|
|||||||
}
|
}
|
||||||
if (record.trans_guid_present)
|
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)
|
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)
|
if (record.log_date_present)
|
||||||
{
|
{
|
||||||
@ -307,7 +309,8 @@ static void dump_split_record(split_record record)
|
|||||||
}
|
}
|
||||||
if (record.acc_guid_present)
|
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)
|
if (record.acc_name_present)
|
||||||
{
|
{
|
||||||
|
@ -75,7 +75,6 @@ qofinclude_HEADERS = \
|
|||||||
qof-gobject.h
|
qof-gobject.h
|
||||||
|
|
||||||
noinst_HEADERS = \
|
noinst_HEADERS = \
|
||||||
md5.h \
|
|
||||||
qofbook-p.h \
|
qofbook-p.h \
|
||||||
qofclass-p.h \
|
qofclass-p.h \
|
||||||
qofevent-p.h \
|
qofevent-p.h \
|
||||||
@ -85,14 +84,6 @@ noinst_HEADERS = \
|
|||||||
qofquerycore-p.h \
|
qofquerycore-p.h \
|
||||||
qofsession-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 += \
|
EXTRA_DIST += \
|
||||||
qofmath128.cpp
|
qofmath128.cpp
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
/********************************************************************\
|
/********************************************************************\
|
||||||
* guid.c -- globally unique ID implementation *
|
* guid.c -- globally unique ID implementation *
|
||||||
* Copyright (C) 2000 Dave Peticolas <peticola@cs.ucdavis.edu> *
|
* 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 *
|
* This program is free software; you can redistribute it and/or *
|
||||||
* modify it under the terms of the GNU General Public License as *
|
* modify it under the terms of the GNU General Public License as *
|
||||||
@ -21,10 +22,8 @@
|
|||||||
* *
|
* *
|
||||||
\********************************************************************/
|
\********************************************************************/
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
# include <config.h>
|
# include <config.h>
|
||||||
@ -51,32 +50,17 @@ extern "C"
|
|||||||
# include <unistd.h>
|
# include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
#include "qof.h"
|
#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
|
using namespace std;
|
||||||
# define P_tmpdir "/tmp"
|
|
||||||
# endif
|
|
||||||
|
|
||||||
/* Constants *******************************************************/
|
typedef boost::uuids::uuid gg;
|
||||||
#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;
|
|
||||||
|
|
||||||
/* This static indicates the debugging module that this .o belongs to. */
|
/* This static indicates the debugging module that this .o belongs to. */
|
||||||
static QofLogModule log_module = QOF_MOD_ENGINE;
|
static QofLogModule log_module = QOF_MOD_ENGINE;
|
||||||
@ -101,12 +85,22 @@ gnc_value_get_guid (const GValue *value)
|
|||||||
return val;
|
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 ***************************************/
|
/* Memory management routines ***************************************/
|
||||||
|
|
||||||
GncGUID *
|
GncGUID *
|
||||||
guid_malloc (void)
|
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
|
void
|
||||||
@ -114,634 +108,128 @@ guid_free (GncGUID *guid)
|
|||||||
{
|
{
|
||||||
if (!guid)
|
if (!guid)
|
||||||
return;
|
return;
|
||||||
|
if (guid == nullguid)
|
||||||
g_slice_free(GncGUID, guid);
|
/*!!Don't delete that!!*/
|
||||||
|
return;
|
||||||
|
delete reinterpret_cast<boost::uuids::uuid*> (guid);
|
||||||
|
guid = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
GncGUID *
|
GncGUID *
|
||||||
guid_copy (const GncGUID *guid)
|
guid_copy (const GncGUID *guid)
|
||||||
{
|
{
|
||||||
GncGUID *copy;
|
const boost::uuids::uuid * old {reinterpret_cast<const boost::uuids::uuid*> (guid)};
|
||||||
|
boost::uuids::uuid * ret {new boost::uuids::uuid (*old)};
|
||||||
g_return_val_if_fail(guid, NULL);
|
return reinterpret_cast<GncGUID*> (ret);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*Takes an allocated guid pointer and constructs it in place*/
|
||||||
void
|
void
|
||||||
guid_init(void)
|
guid_replace (GncGUID *guid)
|
||||||
{
|
{
|
||||||
size_t bytes = 0;
|
static boost::uuids::random_generator gen;
|
||||||
|
boost::uuids::uuid * val {reinterpret_cast<boost::uuids::uuid*> (guid)};
|
||||||
ENTER("");
|
val->boost::uuids::uuid::~uuid ();
|
||||||
|
boost::uuids::uuid temp (gen ());
|
||||||
/* Not needed; taken care of on first malloc.
|
val->swap (temp);
|
||||||
* 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
|
GncGUID *
|
||||||
* Note: P_tmpdir is set to "\" by mingw (Windows) This seems to
|
guid_new (void)
|
||||||
* 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;
|
GncGUID * ret {guid_malloc ()};
|
||||||
const char * dirs[] =
|
guid_replace (ret);
|
||||||
{
|
return ret;
|
||||||
"/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();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
guid_shutdown (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
|
GncGUID
|
||||||
guid_new_return (void)
|
guid_new_return (void)
|
||||||
{
|
{
|
||||||
GncGUID guid;
|
/*we need to construct our value as a boost guid so that
|
||||||
|
it can be deconstructed (in place) in guid_replace*/
|
||||||
guid_new (&guid);
|
boost::uuids::uuid guid;
|
||||||
|
GncGUID * ret {reinterpret_cast<GncGUID*> (&guid)};
|
||||||
return guid;
|
guid_replace (ret);
|
||||||
|
/*return a copy*/
|
||||||
|
return *ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* needs 32 bytes exactly, doesn't print a null char */
|
gchar *
|
||||||
static void
|
|
||||||
encode_md5_data(const unsigned char *data, char *buffer)
|
|
||||||
{
|
|
||||||
size_t count;
|
|
||||||
|
|
||||||
for (count = 0; count < GUID_DATA_SIZE; count++, buffer += 2)
|
|
||||||
sprintf(buffer, "%02x", data[count]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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)
|
|
||||||
{
|
|
||||||
unsigned char n1, n2;
|
|
||||||
size_t count = -1;
|
|
||||||
unsigned char c1, c2;
|
|
||||||
|
|
||||||
if (NULL == data) return FALSE;
|
|
||||||
if (NULL == string) goto badstring;
|
|
||||||
|
|
||||||
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)
|
guid_to_string (const GncGUID * guid)
|
||||||
{
|
{
|
||||||
#ifdef G_THREADS_ENABLED
|
/* We need to malloc here, not 'new' because it will be freed
|
||||||
#ifndef HAVE_GLIB_2_32
|
by the caller which will use free (not delete).*/
|
||||||
static GStaticPrivate guid_buffer_key = G_STATIC_PRIVATE_INIT;
|
gchar * ret {reinterpret_cast<gchar*> (g_malloc (sizeof (gchar)*GUID_ENCODING_LENGTH+1))};
|
||||||
gchar *string;
|
gchar * temp {guid_to_string_buff (guid, ret)};
|
||||||
|
if (!temp){
|
||||||
string = static_cast<gchar*>(g_static_private_get (&guid_buffer_key));
|
g_free (ret);
|
||||||
if (string == NULL)
|
return nullptr;
|
||||||
{
|
|
||||||
string = static_cast<gchar*>(malloc(GUID_ENCODING_LENGTH + 1));
|
|
||||||
g_static_private_set (&guid_buffer_key, string, g_free);
|
|
||||||
}
|
}
|
||||||
#else
|
return ret;
|
||||||
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 *
|
gchar *
|
||||||
guid_to_string_buff(const GncGUID * guid, char *string)
|
guid_to_string_buff (const GncGUID * guid, gchar *str)
|
||||||
{
|
{
|
||||||
if (!string || !guid) return NULL;
|
if (!str || !guid) return NULL;
|
||||||
|
|
||||||
encode_md5_data(guid->data, string);
|
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;
|
||||||
|
|
||||||
string[GUID_ENCODING_LENGTH] = '\0';
|
str[GUID_ENCODING_LENGTH] = '\0';
|
||||||
return &string[GUID_ENCODING_LENGTH];
|
return &str[GUID_ENCODING_LENGTH];
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
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
|
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)
|
if (!guid_1 || !guid_2)
|
||||||
return (memcmp(guid_1, guid_2, GUID_DATA_SIZE) == 0);
|
return false;
|
||||||
else
|
boost::uuids::uuid const * g1 {reinterpret_cast<boost::uuids::uuid const *> (guid_1)};
|
||||||
return FALSE;
|
boost::uuids::uuid const * g2 {reinterpret_cast<boost::uuids::uuid const *> (guid_2)};
|
||||||
|
return *g1 == *g2;
|
||||||
}
|
}
|
||||||
|
|
||||||
gint
|
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)
|
boost::uuids::uuid const * g1 {reinterpret_cast<boost::uuids::uuid const *> (guid_1)};
|
||||||
return 0;
|
boost::uuids::uuid const * g2 {reinterpret_cast<boost::uuids::uuid const *> (guid_2)};
|
||||||
|
if (*g1 < *g2)
|
||||||
/* nothing is always less than something */
|
|
||||||
if (!guid_1 && guid_2)
|
|
||||||
return -1;
|
return -1;
|
||||||
|
if (*g1 == *g2)
|
||||||
if (guid_1 && !guid_2)
|
return 0;
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
return memcmp (guid_1, guid_2, GUID_DATA_SIZE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
guint
|
guint
|
||||||
guid_hash_to_guint (gconstpointer ptr)
|
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)
|
if (!guid)
|
||||||
{
|
{
|
||||||
@ -749,33 +237,21 @@ guid_hash_to_guint (gconstpointer ptr)
|
|||||||
return 0;
|
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 <<= 4;
|
||||||
hash |= guid->data[j];
|
hash |= guidspot;
|
||||||
}
|
}
|
||||||
|
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
gint
|
gint
|
||||||
guid_g_hash_table_equal (gconstpointer guid_a, gconstpointer guid_b)
|
guid_g_hash_table_equal (gconstpointer guid_a, gconstpointer guid_b)
|
||||||
{
|
{
|
||||||
return guid_equal (static_cast<const GncGUID*>(guid_a),
|
return guid_equal (reinterpret_cast<const GncGUID*> (guid_a),
|
||||||
static_cast<const GncGUID*>(guid_b));
|
reinterpret_cast<const GncGUID*> (guid_b));
|
||||||
}
|
}
|
||||||
|
|
||||||
GHashTable *
|
GHashTable *
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
/********************************************************************\
|
/********************************************************************\
|
||||||
* guid.h -- globally unique ID User API *
|
* guid.h -- globally unique ID User API *
|
||||||
* Copyright (C) 2000 Dave Peticolas <peticola@cs.ucdavis.edu> *
|
* 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 *
|
* This program is free software; you can redistribute it and/or *
|
||||||
* modify it under the terms of the GNU General Public License as *
|
* modify it under the terms of the GNU General Public License as *
|
||||||
@ -35,114 +36,96 @@ extern "C"
|
|||||||
/** @addtogroup Entity
|
/** @addtogroup Entity
|
||||||
@{ */
|
@{ */
|
||||||
/** @addtogroup GncGUID
|
/** @addtogroup GncGUID
|
||||||
Globally Unique ID's provide a way to uniquely identify
|
Globally Unique IDs provide a way to uniquely identify
|
||||||
something. A GncGUID is a unique, cryptographically
|
something. A GncGUID is a unique, cryptographically
|
||||||
random 128-bit value. The identifier is so random that
|
random 128-bit value. The identifier is so random that
|
||||||
it is safe to assume that there is no other such item
|
it is safe to assume that there is no other such item
|
||||||
on the planet Earth, and indeed, not even in the Galaxy
|
on the planet Earth, and indeed, not even in the Galaxy
|
||||||
or beyond.
|
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
|
in QOF. In particular, they do not require the use of
|
||||||
other parts of the object subsystem. New GncGUID's are usually
|
other parts of the object subsystem. New GncGUIDs are usually
|
||||||
created by initialising a new entity using qof_instance_init,
|
created by initializing a new entity using qof_instance_init,
|
||||||
rather than calling GncGUID functions directly.
|
rather than calling GncGUID functions directly.
|
||||||
|
|
||||||
@{ */
|
@{ */
|
||||||
/** @file guid.h
|
/** @file guid.h
|
||||||
@brief globally unique ID User API
|
@brief globally unique ID User API
|
||||||
@author Copyright (C) 2000 Dave Peticolas <peticola@cs.ucdavis.edu>
|
@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
|
#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_TYPE_GUID (gnc_guid_get_type())
|
||||||
#define GNC_VALUE_HOLDS_GUID(value) G_VALUE_HOLDS(value, GNC_TYPE_GUID)
|
#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);
|
GType gnc_guid_get_type (void);
|
||||||
const GncGUID* gnc_value_get_guid (const GValue *value);
|
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. */
|
* not including the null terminator. */
|
||||||
#define GUID_ENCODING_LENGTH 32
|
#define GUID_ENCODING_LENGTH 32
|
||||||
|
|
||||||
|
/** Generate a new guid.
|
||||||
/** Initialize the id generator with a variety of random
|
|
||||||
* sources.
|
|
||||||
*
|
*
|
||||||
* @note Only one of guid_init(), guid_init_with_salt() and
|
* @param guid A pointer to an allocated guid data structure. The
|
||||||
* 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
|
|
||||||
* existing value will be replaced with a new value.
|
* 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,
|
/** Generate a new id.
|
||||||
* guid_init() will be called before the id is created.
|
|
||||||
*
|
*
|
||||||
* @return guid A data structure containing a newly allocated GncGUID.
|
* @return guid A data structure containing a copy of a newly constructed GncGUID.
|
||||||
* Caller is responsible for calling guid_free().
|
|
||||||
*/
|
*/
|
||||||
GncGUID guid_new_return (void);
|
GncGUID guid_new_return (void);
|
||||||
|
|
||||||
/** Returns a GncGUID which is guaranteed
|
/** Returns a GncGUID which is guaranteed to never reference any entity.
|
||||||
to never reference any entity. */
|
*
|
||||||
|
* Do not free this value! The same pointer is returned on each call.*/
|
||||||
const GncGUID * guid_null (void);
|
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);
|
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);
|
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);
|
GncGUID *guid_copy (const GncGUID *guid);
|
||||||
|
|
||||||
/** The guid_to_string() routine returns a null-terminated string
|
/** The guid_to_string() routine returns a null-terminated string
|
||||||
* encoding of the id. String encodings of identifiers are hex
|
* encoding of the id. String encodings of identifiers are hex
|
||||||
* numbers printed only with the characters '0' through '9' and
|
* numbers printed only with the characters '0' through '9' and
|
||||||
* 'a' through 'f'. The encoding will always be GUID_ENCODING_LENGTH
|
* 'a' through 'f'. The encoding will always be GUID_ENCODING_LENGTH
|
||||||
* characters long.
|
* characters long (not including the null terminator).
|
||||||
*
|
|
||||||
* XXX This routine is not thread safe and is deprecated. Please
|
|
||||||
* use the routine guid_to_string_buff() instead.
|
|
||||||
*
|
*
|
||||||
* @param guid The guid to print.
|
* @param guid The guid to print.
|
||||||
*
|
*
|
||||||
* @return A pointer to the starting character of the string. The
|
* @return A pointer to the starting character of the string. The
|
||||||
* returned memory is owned by this routine and may not be freed by
|
* returned memory is owned by the calling routine and must be freed
|
||||||
* the caller.
|
* 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
|
/** The guid_to_string_buff() routine puts a null-terminated string
|
||||||
* encoding of the id into the memory pointed at by buff. The
|
* 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.
|
* @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);
|
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.
|
/** Given a string, replace the given guid with the parsed one unless
|
||||||
* The function returns TRUE if the string was a valid 32 character
|
* the given value is null.
|
||||||
* hexadecimal number. This function accepts both upper and lower case
|
* If null is passed as guid or string, false is returned and nothing
|
||||||
* hex digits. If the return value is FALSE, the effect on guid is
|
* is done, otherwise, the function returns true.
|
||||||
* undefined. */
|
* 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);
|
gboolean string_to_guid(const gchar * string, /*@ out @*/ GncGUID * guid);
|
||||||
|
|
||||||
|
|
||||||
|
@ -1568,9 +1568,9 @@ kvp_value_to_string(const KvpValue *val)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case KVP_TYPE_GUID:
|
case KVP_TYPE_GUID:
|
||||||
/* THREAD-UNSAFE */
|
gchar guidstr[GUID_ENCODING_LENGTH+1];
|
||||||
ctmp = guid_to_string(kvp_value_get_guid(val));
|
guid_to_string_buff(kvp_value_get_guid(val),guidstr);
|
||||||
tmp2 = g_strdup_printf("KVP_VALUE_GUID(%s)", ctmp ? ctmp : "");
|
tmp2 = g_strdup_printf("KVP_VALUE_GUID(%s)", guidstr);
|
||||||
return tmp2;
|
return tmp2;
|
||||||
break;
|
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
|
do
|
||||||
{
|
{
|
||||||
guid_new(&priv->guid);
|
guid_replace(&priv->guid);
|
||||||
|
|
||||||
if (NULL == qof_collection_lookup_entity (col, &priv->guid))
|
if (NULL == qof_collection_lookup_entity (col, &priv->guid))
|
||||||
break;
|
break;
|
||||||
@ -691,8 +691,9 @@ qof_instance_print_dirty (const QofInstance *inst, gpointer dummy)
|
|||||||
priv = GET_PRIVATE(inst);
|
priv = GET_PRIVATE(inst);
|
||||||
if (priv->dirty)
|
if (priv->dirty)
|
||||||
{
|
{
|
||||||
printf("%s instance %s is dirty.\n", inst->e_type,
|
gchar guidstr[GUID_ENCODING_LENGTH+1];
|
||||||
guid_to_string(&priv->guid));
|
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));
|
qof_query_printGuidMatch (pdata->options));
|
||||||
for (node = pdata->guids; node; node = node->next)
|
for (node = pdata->guids; node; node = node->next)
|
||||||
{
|
{
|
||||||
/* THREAD-UNSAFE */
|
gchar guidstr[GUID_ENCODING_LENGTH+1];
|
||||||
g_string_append_printf (gs, ", guids: %s",
|
guid_to_string_buff ((GncGUID *) node->data,guidstr);
|
||||||
guid_to_string ((GncGUID *) node->data));
|
g_string_append_printf (gs, ", guids: %s",guidstr);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -263,7 +263,6 @@ qof_init (void)
|
|||||||
#endif
|
#endif
|
||||||
qof_log_init();
|
qof_log_init();
|
||||||
qof_string_cache_init();
|
qof_string_cache_init();
|
||||||
guid_init ();
|
|
||||||
qof_object_initialize ();
|
qof_object_initialize ();
|
||||||
qof_query_init ();
|
qof_query_init ();
|
||||||
qof_book_register ();
|
qof_book_register ();
|
||||||
@ -274,7 +273,6 @@ qof_close(void)
|
|||||||
{
|
{
|
||||||
qof_query_shutdown ();
|
qof_query_shutdown ();
|
||||||
qof_object_shutdown ();
|
qof_object_shutdown ();
|
||||||
guid_shutdown ();
|
|
||||||
qof_finalize_backend_libraries();
|
qof_finalize_backend_libraries();
|
||||||
qof_string_cache_destroy ();
|
qof_string_cache_destroy ();
|
||||||
qof_log_shutdown();
|
qof_log_shutdown();
|
||||||
|
@ -154,15 +154,15 @@ extern "C"
|
|||||||
|
|
||||||
/** \brief Initialise the Query Object Framework
|
/** \brief Initialise the Query Object Framework
|
||||||
|
|
||||||
Use in place of separate init functions (like guid_init()
|
Use in place of separate init functions (like qof_query_init(),
|
||||||
and qof_query_init() etc.) to protect against future changes.
|
etc.) to protect against future changes.
|
||||||
*/
|
*/
|
||||||
void qof_init (void);
|
void qof_init (void);
|
||||||
|
|
||||||
/** \brief Safely close down the Query Object Framework
|
/** \brief Safely close down the Query Object Framework
|
||||||
|
|
||||||
Use in place of separate close / shutdown functions
|
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.
|
against future changes.
|
||||||
*/
|
*/
|
||||||
void qof_close (void);
|
void qof_close (void);
|
||||||
|
@ -47,7 +47,7 @@ static const gchar * suitename {"/qof/gnc-guid"};
|
|||||||
static void test_create_gnc_guid (void){
|
static void test_create_gnc_guid (void){
|
||||||
GncGUID * guid {guid_malloc ()};
|
GncGUID * guid {guid_malloc ()};
|
||||||
g_assert (guid != nullptr);
|
g_assert (guid != nullptr);
|
||||||
guid_new (guid);
|
guid_replace (guid);
|
||||||
/*We apparently don't need to free guid_null (based on its being const)*/
|
/*We apparently don't need to free guid_null (based on its being const)*/
|
||||||
const GncGUID * guidnull {guid_null ()};
|
const GncGUID * guidnull {guid_null ()};
|
||||||
g_assert (!guid_equal (guid, guidnull));
|
g_assert (!guid_equal (guid, guidnull));
|
||||||
@ -58,7 +58,7 @@ static void test_create_gnc_guid (void){
|
|||||||
static void test_gnc_guid_copy (void) {
|
static void test_gnc_guid_copy (void) {
|
||||||
GncGUID * guid {guid_malloc ()};
|
GncGUID * guid {guid_malloc ()};
|
||||||
g_assert (guid != nullptr);
|
g_assert (guid != nullptr);
|
||||||
guid_new (guid);
|
guid_replace (guid);
|
||||||
GncGUID * cp {guid_copy (guid)};
|
GncGUID * cp {guid_copy (guid)};
|
||||||
g_assert (guid_equal (guid, cp));
|
g_assert (guid_equal (guid, cp));
|
||||||
guid_free (cp);
|
guid_free (cp);
|
||||||
@ -69,16 +69,17 @@ static void test_gnc_guid_copy (void) {
|
|||||||
defined in the guid api. We then compare them.*/
|
defined in the guid api. We then compare them.*/
|
||||||
static void test_gnc_guid_to_string (void) {
|
static void test_gnc_guid_to_string (void) {
|
||||||
GncGUID * guid {guid_malloc()};
|
GncGUID * guid {guid_malloc()};
|
||||||
|
gchar guidstrp [GUID_ENCODING_LENGTH+1];
|
||||||
|
gchar guidstrp2[GUID_ENCODING_LENGTH+1];
|
||||||
g_assert (guid != nullptr);
|
g_assert (guid != nullptr);
|
||||||
guid_new (guid);
|
guid_replace (guid);
|
||||||
string message {" using guid_to_string (deprecated): "};
|
string message {" using guid_to_string (deprecated): "};
|
||||||
/*don't free the return value of guid_to_string!*/
|
guid_to_string_buff (guid,guidstrp);
|
||||||
string guidstr {guid_to_string (guid)};
|
string guidstr {guidstrp};
|
||||||
g_assert (guidstr.size () == GUID_ENCODING_LENGTH);
|
g_assert (guidstr.size () == GUID_ENCODING_LENGTH);
|
||||||
message += guidstr;
|
message += guidstr;
|
||||||
g_test_message ("%s", message.c_str ());
|
g_test_message ("%s", message.c_str ());
|
||||||
message = " using guid_to_string_buff: ";
|
message = " using guid_to_string_buff: ";
|
||||||
gchar guidstrp2 [GUID_ENCODING_LENGTH+1];
|
|
||||||
gchar * ret {guid_to_string_buff (guid, guidstrp2)};
|
gchar * ret {guid_to_string_buff (guid, guidstrp2)};
|
||||||
g_assert (ret == guidstrp2 + GUID_ENCODING_LENGTH);
|
g_assert (ret == guidstrp2 + GUID_ENCODING_LENGTH);
|
||||||
string guidstr2 {guidstrp2};
|
string guidstr2 {guidstrp2};
|
||||||
@ -135,7 +136,7 @@ static void test_gnc_guid_roundtrip (void) {
|
|||||||
g_assert (guid1 != nullptr);
|
g_assert (guid1 != nullptr);
|
||||||
GncGUID * guid2 {guid_malloc ()};
|
GncGUID * guid2 {guid_malloc ()};
|
||||||
g_assert (guid2 != nullptr);
|
g_assert (guid2 != nullptr);
|
||||||
guid_new (guid1);
|
guid_replace (guid1);
|
||||||
|
|
||||||
gchar guidstrp [GUID_ENCODING_LENGTH+1];
|
gchar guidstrp [GUID_ENCODING_LENGTH+1];
|
||||||
gchar * temp {guid_to_string_buff (guid1, guidstrp)};
|
gchar * temp {guid_to_string_buff (guid1, guidstrp)};
|
||||||
@ -147,14 +148,52 @@ static void test_gnc_guid_roundtrip (void) {
|
|||||||
guid_free (guid1);
|
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)
|
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 create guid", test_create_gnc_guid);
|
||||||
GNC_TEST_ADD_FUNC (suitename, "gnc copy guid", test_gnc_guid_copy);
|
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 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 equal", test_gnc_guid_equals);
|
||||||
GNC_TEST_ADD_FUNC (suitename, "gnc guid string roundtrip", test_gnc_guid_roundtrip);
|
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_sec = 1;
|
||||||
ts.tv_nsec = 1;
|
ts.tv_nsec = 1;
|
||||||
guid = guid_malloc ();
|
guid = guid_new ();
|
||||||
guid_new (guid);
|
|
||||||
g_date_set_dmy (&gdate, 26, 1, 1957);
|
g_date_set_dmy (&gdate, 26, 1, 1957);
|
||||||
|
|
||||||
kvp_frame_set_gint64( frame, "gint64-type", 100 );
|
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_sec = 1;
|
||||||
test_ts.tv_nsec = 1;
|
test_ts.tv_nsec = 1;
|
||||||
test_str = "abcdefghijklmnop";
|
test_str = "abcdefghijklmnop";
|
||||||
test_guid = guid_malloc();
|
test_guid = guid_new();
|
||||||
guid_new( test_guid );
|
|
||||||
test_frame = kvp_frame_new();
|
test_frame = kvp_frame_new();
|
||||||
|
|
||||||
g_assert( fixture->frame );
|
g_assert( fixture->frame );
|
||||||
@ -223,8 +221,7 @@ test_kvp_frame_set_foo( Fixture *fixture, gconstpointer pData )
|
|||||||
test_gnc_numeric = gnc_numeric_zero();
|
test_gnc_numeric = gnc_numeric_zero();
|
||||||
test_ts.tv_sec = 1;
|
test_ts.tv_sec = 1;
|
||||||
test_ts.tv_nsec = 1;
|
test_ts.tv_nsec = 1;
|
||||||
test_guid = guid_malloc();
|
test_guid = guid_new();
|
||||||
guid_new( test_guid );
|
|
||||||
|
|
||||||
g_assert( fixture->frame );
|
g_assert( fixture->frame );
|
||||||
g_assert( kvp_frame_is_empty( fixture->frame ) );
|
g_assert( kvp_frame_is_empty( fixture->frame ) );
|
||||||
@ -512,8 +509,7 @@ test_kvp_value_copy( void )
|
|||||||
KvpFrame *frame_orig, *frame_copy;
|
KvpFrame *frame_orig, *frame_copy;
|
||||||
|
|
||||||
gnc_numeric_orig = gnc_numeric_zero();
|
gnc_numeric_orig = gnc_numeric_zero();
|
||||||
guid_orig = guid_malloc();
|
guid_orig = guid_new();
|
||||||
guid_new( guid_orig );
|
|
||||||
ts_orig.tv_sec = 1;
|
ts_orig.tv_sec = 1;
|
||||||
ts_orig.tv_nsec = 1;
|
ts_orig.tv_nsec = 1;
|
||||||
list_orig = NULL;
|
list_orig = NULL;
|
||||||
@ -631,8 +627,7 @@ test_kvp_glist_copy( void )
|
|||||||
KvpFrame *frame_orig;
|
KvpFrame *frame_orig;
|
||||||
|
|
||||||
gnc_numeric_orig = gnc_numeric_zero();
|
gnc_numeric_orig = gnc_numeric_zero();
|
||||||
guid_orig = guid_malloc();
|
guid_orig = guid_new();
|
||||||
guid_new( guid_orig );
|
|
||||||
ts_orig.tv_sec = 1;
|
ts_orig.tv_sec = 1;
|
||||||
ts_orig.tv_nsec = 1;
|
ts_orig.tv_nsec = 1;
|
||||||
list_orig = NULL;
|
list_orig = NULL;
|
||||||
@ -703,8 +698,7 @@ test_kvp_glist_compare( void )
|
|||||||
KvpFrame *frame_orig;
|
KvpFrame *frame_orig;
|
||||||
|
|
||||||
gnc_numeric_orig = gnc_numeric_zero();
|
gnc_numeric_orig = gnc_numeric_zero();
|
||||||
guid_orig = guid_malloc();
|
guid_orig = guid_new();
|
||||||
guid_new( guid_orig );
|
|
||||||
ts_orig.tv_sec = 1;
|
ts_orig.tv_sec = 1;
|
||||||
ts_orig.tv_nsec = 1;
|
ts_orig.tv_nsec = 1;
|
||||||
list_orig = NULL;
|
list_orig = NULL;
|
||||||
@ -797,10 +791,8 @@ test_kvp_value_compare( void )
|
|||||||
|
|
||||||
gnc_numeric_orig = gnc_numeric_zero();
|
gnc_numeric_orig = gnc_numeric_zero();
|
||||||
gnc_numeric_copy = gnc_numeric_zero();
|
gnc_numeric_copy = gnc_numeric_zero();
|
||||||
guid_orig = guid_malloc();
|
guid_orig = guid_new();
|
||||||
guid_new( guid_orig );
|
guid_copy = guid_new();
|
||||||
guid_copy = guid_malloc();
|
|
||||||
guid_new( guid_copy );
|
|
||||||
ts_orig.tv_sec = 1;
|
ts_orig.tv_sec = 1;
|
||||||
ts_orig.tv_nsec = 1;
|
ts_orig.tv_nsec = 1;
|
||||||
ts_copy.tv_sec = 2;
|
ts_copy.tv_sec = 2;
|
||||||
@ -988,7 +980,7 @@ test_binary_to_string( void )
|
|||||||
static void
|
static void
|
||||||
test_kvp_value_to_string( void )
|
test_kvp_value_to_string( void )
|
||||||
{
|
{
|
||||||
const gchar *str_tmp;
|
gchar guidstr[GUID_ENCODING_LENGTH+1];
|
||||||
gchar *str_tmp2, *str_tmp3;
|
gchar *str_tmp2, *str_tmp3;
|
||||||
gchar *result;
|
gchar *result;
|
||||||
KvpValue *gint64_value;
|
KvpValue *gint64_value;
|
||||||
@ -1007,8 +999,7 @@ test_kvp_value_to_string( void )
|
|||||||
KvpFrame *frame_orig;
|
KvpFrame *frame_orig;
|
||||||
|
|
||||||
gnc_numeric_orig = gnc_numeric_zero();
|
gnc_numeric_orig = gnc_numeric_zero();
|
||||||
guid_orig = guid_malloc();
|
guid_orig = guid_new();
|
||||||
guid_new( guid_orig );
|
|
||||||
ts_orig.tv_sec = 1;
|
ts_orig.tv_sec = 1;
|
||||||
ts_orig.tv_nsec = 1;
|
ts_orig.tv_nsec = 1;
|
||||||
list_orig = NULL;
|
list_orig = NULL;
|
||||||
@ -1047,8 +1038,8 @@ test_kvp_value_to_string( void )
|
|||||||
|
|
||||||
result = kvp_value_to_string( guid_value );
|
result = kvp_value_to_string( guid_value );
|
||||||
g_assert( result );
|
g_assert( result );
|
||||||
str_tmp = guid_to_string( kvp_value_get_guid( guid_value ) );
|
guid_to_string_buff( kvp_value_get_guid( guid_value ), guidstr);
|
||||||
str_tmp2 = g_strdup_printf("KVP_VALUE_GUID(%s)", str_tmp ? str_tmp : "");
|
str_tmp2 = g_strdup_printf("KVP_VALUE_GUID(%s)", guidstr);
|
||||||
g_assert_cmpstr( result, == , str_tmp2 );
|
g_assert_cmpstr( result, == , str_tmp2 );
|
||||||
g_free( result );
|
g_free( result );
|
||||||
g_free( str_tmp2 );
|
g_free( str_tmp2 );
|
||||||
@ -1093,8 +1084,7 @@ test_kvp_frame_to_string( Fixture *fixture, gconstpointer pData )
|
|||||||
KvpFrame *test_frame;
|
KvpFrame *test_frame;
|
||||||
|
|
||||||
test_gnc_numeric = gnc_numeric_zero();
|
test_gnc_numeric = gnc_numeric_zero();
|
||||||
test_guid = guid_malloc();
|
test_guid = guid_new();
|
||||||
guid_new( test_guid );
|
|
||||||
test_ts.tv_sec = 1;
|
test_ts.tv_sec = 1;
|
||||||
test_ts.tv_nsec = 1;
|
test_ts.tv_nsec = 1;
|
||||||
test_frame = kvp_frame_new();
|
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() );
|
g_assert( qof_entity_get_guid( NULL ) == guid_null() );
|
||||||
|
|
||||||
/* set up */
|
/* set up */
|
||||||
gncGuid = guid_malloc();
|
gncGuid = guid_new();
|
||||||
guid_new( gncGuid );
|
|
||||||
g_assert( QOF_IS_INSTANCE( fixture->inst ) );
|
g_assert( QOF_IS_INSTANCE( fixture->inst ) );
|
||||||
g_assert( gncGuid );
|
g_assert( gncGuid );
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user