/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
 * Author:
 *   JP Rosevear (jpr@helixcode.com)
 *
 * Copyright 2000, Helix Code, Inc.
 */

#include <config.h>
#include <string.h>
#include <fcntl.h>
#ifdef HAVE_DB_185_H
#include <db_185.h>
#else
#ifdef HAVE_DB1_DB_H
#include <db1/db.h>
#else
#include <db.h>
#endif
#endif
#include "md5-utils.h"
#include "e-dbhash.h"

struct _EDbHashPrivate 
{
	DB *db;
};

EDbHash *
e_dbhash_new (const char *filename)
{
	EDbHash *edbh;
	DB *db;

	/* Attempt to open the database */
	db = dbopen (filename, O_RDWR, 0666, DB_HASH, NULL);
	if (db == NULL) {
		db = dbopen (filename, O_RDWR | O_CREAT, 0666, DB_HASH, NULL);

		if (db == NULL)
			return NULL;
	}
	
	edbh = g_new (EDbHash, 1);
	edbh->priv = g_new (EDbHashPrivate, 1);
	edbh->priv->db = db;
	
	return edbh;
}

static void
string_to_dbt(const char *str, DBT *dbt)
{
	dbt->data = (void*)str;
	dbt->size = strlen (str) + 1;
}

void 
e_dbhash_add (EDbHash *edbh, const gchar *key, const gchar *data)
{
	DB *db;
	DBT dkey;
	DBT ddata;
	guchar local_hash[16];

	g_return_if_fail (edbh != NULL);
	g_return_if_fail (edbh->priv != NULL);
	g_return_if_fail (edbh->priv->db != NULL);
	g_return_if_fail (key != NULL);
	g_return_if_fail (data != NULL);

	db = edbh->priv->db;
	
	/* Key dbt */
	string_to_dbt (key, &dkey);

	/* Data dbt */
	md5_get_digest (data, strlen (data), local_hash);
	string_to_dbt (local_hash, &ddata);

	/* Add to database */
	db->put (db, &dkey, &ddata, 0);
}

void 
e_dbhash_remove (EDbHash *edbh, const char *key)
{
	DB *db;
	DBT dkey;
	
	g_return_if_fail (edbh != NULL);
	g_return_if_fail (edbh->priv != NULL);
	g_return_if_fail (key != NULL);

	db = edbh->priv->db;
	
	/* Key dbt */
	string_to_dbt (key, &dkey);

	/* Remove from database */
	db->del (db, &dkey, 0);
}

void 
e_dbhash_foreach_key (EDbHash *edbh, EDbHashFunc func, gpointer user_data)
{
	DB *db;
	DBT dkey;
	DBT ddata;
	int db_error = 0;
	
	g_return_if_fail (edbh != NULL);
	g_return_if_fail (edbh->priv != NULL);
	g_return_if_fail (func != NULL);

	db = edbh->priv->db;

	db_error = db->seq(db, &dkey, &ddata, R_FIRST);

	while (db_error == 0) {
		(*func) ((const char *)dkey.data, user_data);

		db_error = db->seq(db, &dkey, &ddata, R_NEXT);
	}
}

EDbHashStatus
e_dbhash_compare (EDbHash *edbh, const char *key, const char *compare_data)
{
	DB *db;
	DBT dkey;
	DBT ddata;
	guchar compare_hash[16];
	
	g_return_val_if_fail (edbh != NULL, FALSE);
	g_return_val_if_fail (edbh->priv != NULL, FALSE);
	g_return_val_if_fail (key != NULL, FALSE);
	g_return_val_if_fail (compare_hash != NULL, FALSE);

	db = edbh->priv->db;
	
	/* Key dbt */
	string_to_dbt (key, &dkey);

	/* Lookup in database */
	memset (&ddata, 0, sizeof (DBT));
	db->get (db, &dkey, &ddata, 0);
	
	/* Compare */
	if (ddata.data) {
		md5_get_digest (compare_data, strlen (compare_data), compare_hash);
		
		if (memcmp (ddata.data, compare_hash, sizeof (guchar) * 16))
			return E_DBHASH_STATUS_DIFFERENT;
	} else {
		return E_DBHASH_STATUS_NOT_FOUND;
	}
	
	return E_DBHASH_STATUS_SAME;
}

void
e_dbhash_write (EDbHash *edbh)
{
	DB *db;
	
	g_return_if_fail (edbh != NULL);
	g_return_if_fail (edbh->priv != NULL);

	db = edbh->priv->db;
	
	/* Flush database to disk */
	db->sync (db, 0);
}

void 
e_dbhash_destroy (EDbHash *edbh)
{
	DB *db;
	
	g_return_if_fail (edbh != NULL);
	g_return_if_fail (edbh->priv != NULL);

	db = edbh->priv->db;
	
	/* Close datbase */
	db->close (db);
	
	g_free (edbh->priv);
	g_free (edbh);
}


ash-4.17.19'>dependabot/npm_and_yarn/devel/electron6/files/lodash-4.17.19</option>
<option value='dependabot/npm_and_yarn/devel/electron6/files/lodash.merge-4.6.2'>dependabot/npm_and_yarn/devel/electron6/files/lodash.merge-4.6.2</option>
<option value='dependabot/npm_and_yarn/devel/electron6/files/node-fetch-2.6.1'>dependabot/npm_and_yarn/devel/electron6/files/node-fetch-2.6.1</option>
<option value='dependabot/npm_and_yarn/devel/electron6/files/serve-10.1.2'>dependabot/npm_and_yarn/devel/electron6/files/serve-10.1.2</option>
<option value='gnome-3.22'>gnome-3.22</option>
<option value='gnome-3.24'>gnome-3.24</option>
<option value='gnome-3.26'>gnome-3.26</option>
<option value='gnome-3.28'>gnome-3.28</option>
<option value='gnome-3.32'>gnome-3.32</option>
<option value='gnome-3.36'>gnome-3.36</option>
<option value='gstreamer' selected='selected'>gstreamer</option>
<option value='gstreamer-1.16'>gstreamer-1.16</option>
<option value='gstreamer0.10-removal'>gstreamer0.10-removal</option>
<option value='main'>main</option>
<option value='master'>master</option>
<option value='mate-1.16'>mate-1.16</option>
<option value='mate-1.18'>mate-1.18</option>
<option value='mate-1.20'>mate-1.20</option>
<option value='mate-1.22'>mate-1.22</option>
</select> <input type='submit' value='switch'/></form></td></tr>
<tr><td class='sub'>FreeBSD GNOME current development ports (https://github.com/freebsd/freebsd-ports-gnome)</td><td class='sub right'></td></tr></table>
<table class='tabs'><tr><td>
<a href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/about/?h=gstreamer'>about</a><a href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/?h=gstreamer'>summary</a><a href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/refs/?h=gstreamer'>refs</a><a class='active' href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/log/www/firefox/files/patch-jsfun.c?h=gstreamer'>log</a><a href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/tree/www/firefox/files/patch-jsfun.c?h=gstreamer'>tree</a><a href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/commit/www/firefox/files/patch-jsfun.c?h=gstreamer'>commit</a><a href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/diff/www/firefox/files/patch-jsfun.c?h=gstreamer'>diff</a><a href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/stats/www/firefox/files/patch-jsfun.c?h=gstreamer'>stats</a></td><td class='form'><form class='right' method='get' action='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/log/www/firefox/files/patch-jsfun.c'>
<input type='hidden' name='h' value='gstreamer'/><select name='qt'>
<option value='grep'>log msg</option>
<option value='author'>author</option>
<option value='committer'>committer</option>
<option value='range'>range</option>
</select>
<input class='txt' type='search' size='10' name='q' value=''/>
<input type='submit' value='search'/>
</form>
</td></tr></table>
<div class='path'>path: <a href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/log/?h=gstreamer'>root</a>/<a href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/log/www?h=gstreamer'>www</a>/<a href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/log/www/firefox?h=gstreamer'>firefox</a>/<a href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/log/www/firefox/files?h=gstreamer'>files</a>/<a href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/log/www/firefox/files/patch-jsfun.c?h=gstreamer'>patch-jsfun.c</a></div><div class='content'><table class='list nowrap'><tr class='nohover'><th></th><th class='left'>Commit message (<a href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/log/www/firefox/files/patch-jsfun.c?h=gstreamer&amp;showmsg=1'>Expand</a>)</th><th class='left'>Author</th><th class='left'>Age</th><th class='left'>Files</th><th class='left'>Lines</th></tr>