text:
/*
 * BP-NmapDB.cc
 *
 *  Created on: Mar 14, 2010
 *      Author: Jason Medeiros
 */

#include "../../../include/BP-Main.h"

/*
 * Using Search Functions:
 * ----------------------------------------------------
 * Each search function has a min, and max parameter.  Searching is done by
 * building a SQL query that basically matches all min/max items set in the
 * structures provided.  Min uses "<" operator, and Max uses ">" operator.
 * The like parameter matches using the "LIKE" keyword, and the equal parameter
 * matches with the "=" operator.  NULL parameters are not processed.  Like parameters
 * only work on character entries.
 */

// search the portstats database table
P_BP_NMAPDB_RESULTS BP_NDBSearchPortStats
(
		P_BP_MYSQL_SESSION       mysql_db,
		P_BP_NMAPDB_PORTSTATS    min,
		P_BP_NMAPDB_PORTSTATS    max,
		P_BP_NMAPDB_PORTSTATS    like,
		P_BP_NMAPDB_PORTSTATS    equal,
		size_t limitBottom, size_t limitTop
)
{
	if(!mysql_db)
		return NULL;

	// query parts
	char * select_part = NULL;
	char * min_part    = NULL;
	char * max_part    = NULL;
	char * like_part   = NULL;
	char * equal_part  = NULL;

	// final query when built
	char *final_query  = NULL;

	// ------------------- Min --------------------------------
	if(min)
	{
		// create string to hold the min part of the query
		min_part = (char *) bpcalloc(sizeof(BP_NMAPDB_PORTSTATS)*3, 1);

		// add date to query
		if(bpstrlen(min->d))
			snprintf(&min_part[bpstrlen(min_part)], sizeof(min->d)-1+40, " d < \"%s\" AND ", min->d);

		// add time to query
		if(bpstrlen(min->t))
			snprintf(&min_part[bpstrlen(min_part)], sizeof(min->d)-1+40, " t < \"%s\" AND ", min->t);

		// add hostid to query
		if(min->hostid > 0)
			snprintf(&min_part[bpstrlen(min_part)], 40, " hostid < \"%d\" AND ", min->hostid);

		// add target_ip to query
		if(bpstrlen(min->target_ip))
			snprintf(&min_part[bpstrlen(min_part)], sizeof(min->target_ip)-1+40, " target_ip < \"%s\" AND ", min->target_ip);

		// add port to query
		if(min->port > 0)
			snprintf(&min_part[bpstrlen(min_part)], 40, " port < \"%d\" AND ", min->port);

		// add protocol to query
		if(bpstrlen(min->protocol))
			snprintf(&min_part[bpstrlen(min_part)], sizeof(min->protocol)-1+40, " protocol < \"%s\" AND ", min->protocol);

		// add service to query
		if(bpstrlen(min->service))
			snprintf(&min_part[bpstrlen(min_part)], sizeof(min->service)-1+40, " service < \"%s\" AND ", min->service);

		// add state to query
		if(bpstrlen(min->state))
			snprintf(&min_part[bpstrlen(min_part)], sizeof(min->state)-1+40, " state < \"%s\" AND ", min->state);

		// add full version to query
		if(bpstrlen(min->fullversion))
			snprintf(&min_part[bpstrlen(min_part)], sizeof(min->fullversion)-1+40, " fullversion < \"%s\" AND ", min->fullversion);

		// add scannerid
		if(min->scannerid > 0)
			snprintf(&min_part[bpstrlen(min_part)], 40, " scannerid < \"%d\" AND ", min->scannerid);

		// add runid to query
		if(min->runid > 0)
			snprintf(&min_part[bpstrlen(min_part)], 40, " runid < \"%d\" AND ", min->runid);

		// add rec_id to query
		if(min->rec_id > 0)
			snprintf(&min_part[bpstrlen(min_part)], 40, " rec_id < \"%d\" AND ", min->rec_id);

	}

	// ------------------- Max --------------------------------
	if(max)
	{
		// create string to hold the min part of the query
		max_part = (char *) bpcalloc(sizeof(BP_NMAPDB_PORTSTATS)*3, 1);

		// add date to query
		if(bpstrlen(max->d))
			snprintf(&max_part[bpstrlen(max_part)], sizeof(max->d)-1+40, " d > \"%s\" AND ", max->d);

		// add time to query
		if(bpstrlen(max->t))
			snprintf(&max_part[bpstrlen(max_part)], sizeof(max->d)-1+40, " t > \"%s\" AND ", max->t);

		// add hostid to query
		if(max->hostid > 0)
			snprintf(&max_part[bpstrlen(max_part)], 40, " hostid > \"%d\" AND ", max->hostid);

		// add target_ip to query
		if(bpstrlen(max->target_ip))
			snprintf(&max_part[bpstrlen(max_part)], sizeof(max->target_ip)-1+40, " target_ip > \"%s\" AND ", max->target_ip);

		// add port to query
		if(max->port > 0)
			snprintf(&max_part[bpstrlen(max_part)], 40, " port > \"%d\" AND ", max->port);

		// add protocol to query
		if(bpstrlen(max->protocol))
			snprintf(&max_part[bpstrlen(max_part)], sizeof(max->protocol)-1+40, " protocol > \"%s\" AND ", max->protocol);

		// add service to query
		if(bpstrlen(max->service))
			snprintf(&max_part[bpstrlen(max_part)], sizeof(max->service)-1+40, " service > \"%s\" AND ", max->service);

		// add state to query
		if(bpstrlen(max->state))
			snprintf(&max_part[bpstrlen(max_part)], sizeof(max->state)-1+40, " state > \"%s\" AND ", max->state);

		// add full version to query
		if(bpstrlen(max->fullversion))
			snprintf(&max_part[bpstrlen(max_part)], sizeof(max->fullversion)-1+40, " fullversion > \"%s\" AND ", max->fullversion);

		// add scannerid
		if(max->scannerid > 0)
			snprintf(&max_part[bpstrlen(max_part)], 40, " scannerid > \"%d\" AND ", max->scannerid);

		// add runid to query
		if(max->runid > 0)
			snprintf(&max_part[bpstrlen(max_part)], 40, " runid > \"%d\" AND ", max->runid);

		// add rec_id to query
		if(max->rec_id > 0)
			snprintf(&max_part[bpstrlen(max_part)], 40, " rec_id > \"%d\" AND ", max->rec_id);

	}

	// ------------------- Like --------------------------------
	if(like)
	{
		// create string to hold the min part of the query
		like_part = (char *) bpcalloc(sizeof(BP_NMAPDB_PORTSTATS)*3, 1);

		// add date to query
		if(bpstrlen(like->d))
			snprintf(&like_part[bpstrlen(like_part)], sizeof(like->d)-1+40, " d like \"%%%s%%\" AND ", like->d);

		// add time to query
		if(bpstrlen(like->t))
			snprintf(&like_part[bpstrlen(like_part)], sizeof(like->d)-1+40, " t like \"%%%s%%\" AND ", like->t);

		// add hostid to query
		if(like->hostid > 0)
			snprintf(&like_part[bpstrlen(like_part)], 40, " hostid like \"%%%d%%\" AND ", like->hostid);

		// add target_ip to query
		if(bpstrlen(like->target_ip))
			snprintf(&like_part[bpstrlen(like_part)], sizeof(like->target_ip)-1+40, " target_ip like \"%%%s%%\" AND ", like->target_ip);

		// add port to query
		if(like->port > 0)
			snprintf(&like_part[bpstrlen(like_part)], 40, " port like \"%%%d%%\" AND ", like->port);

		// add protocol to query
		if(bpstrlen(like->protocol))
			snprintf(&like_part[bpstrlen(like_part)], sizeof(like->protocol)-1+40, " protocol like \"%%%s%%\" AND ", like->protocol);

		// add service to query
		if(bpstrlen(like->service))
			snprintf(&like_part[bpstrlen(like_part)], sizeof(like->service)-1+40, " service like \"%%%s%%\" AND ", like->service);

		// add state to query
		if(bpstrlen(like->state))
			snprintf(&like_part[bpstrlen(like_part)], sizeof(like->state)-1+40, " state like \"%%%s%%\" AND ", like->state);

		// add full version to query
		if(bpstrlen(like->fullversion))
			snprintf(&like_part[bpstrlen(like_part)], sizeof(like->fullversion)-1+40, " fullversion like \"%%%s%%\" AND ", like->fullversion);

		// add scannerid
		if(like->scannerid > 0)
			snprintf(&like_part[bpstrlen(like_part)], 40, " scannerid like \"%%%d%%\" AND ", like->scannerid);

		// add runid to query
		if(like->runid > 0)
			snprintf(&like_part[bpstrlen(like_part)], 40, " runid like \"%%%d%%\" AND ", like->runid);

		// add rec_id to query
		if(like->rec_id > 0)
			snprintf(&like_part[bpstrlen(like_part)], 40, " rec_id like \"%%%d%%\" AND ", like->rec_id);

	}

	// ------------------- Equal --------------------------------
	if(equal)
	{

		// create string to hold the min part of the query
		equal_part = (char *) bpcalloc(sizeof(BP_NMAPDB_PORTSTATS)*3, 1);

		// add date to query
		if(bpstrlen(equal->d))
			snprintf(&equal_part[bpstrlen(equal_part)], sizeof(equal->d)-1+40, " d = \"%s\" AND ", equal->d);

		// add time to query
		if(bpstrlen(equal->t))
			snprintf(&equal_part[bpstrlen(equal_part)], sizeof(equal->d)-1+40, " t = \"%s\" AND ", equal->t);

		// add hostid to query
		if(equal->hostid > 0)
			snprintf(&equal_part[bpstrlen(equal_part)], 40, " hostid = \"%d\" AND ", equal->hostid);

		// add target_ip to query
		if(bpstrlen(equal->target_ip))
			snprintf(&equal_part[bpstrlen(equal_part)], sizeof(equal->target_ip)-1+40, " target_ip = \"%s\" AND ", equal->target_ip);

		// add port to query
		if(equal->port > 0)
			snprintf(&equal_part[bpstrlen(equal_part)], 40, " port = \"%d\" AND ", equal->port);

		// add protocol to query
		if(bpstrlen(equal->protocol))
			snprintf(&equal_part[bpstrlen(equal_part)], sizeof(equal->protocol)-1+40, " protocol = \"%s\" AND ", equal->protocol);

		// add service to query
		if(bpstrlen(equal->service))
			snprintf(&equal_part[bpstrlen(equal_part)], sizeof(equal->service)-1+40, " service = \"%s\" AND ", equal->service);

		// add state to query
		if(bpstrlen(equal->state))
			snprintf(&equal_part[bpstrlen(equal_part)], sizeof(equal->state)-1+40, " state = \"%s\" AND ", equal->state);

		// add full version to query
		if(bpstrlen(equal->fullversion))
			snprintf(&equal_part[bpstrlen(equal_part)], sizeof(equal->fullversion)-1+40, " fullversion = \"%s\" AND ", equal->fullversion);

		// add scannerid
		if(equal->scannerid > 0)
			snprintf(&equal_part[bpstrlen(equal_part)], 40, " scannerid = \"%d\" AND ", equal->scannerid);

		// add runid to query
		if(equal->runid > 0)
			snprintf(&equal_part[bpstrlen(equal_part)], 40, " runid = \"%d\" AND ", equal->runid);

		// add rec_id to query
		if(equal->rec_id > 0)
			snprintf(&equal_part[bpstrlen(equal_part)], 40, " rec_id = \"%d\" AND ", equal->rec_id);

	}

	// ---------------- Run Query --------------------------------

	// query parts
	select_part = "select * from portstat ";

	// max length variable
	size_t max_len = bpstrlen(select_part);

	if(min_part)
		max_len += bpstrlen(min_part);

	if(max_part)
		max_len += bpstrlen(max_part);

	if(like_part)
		max_len += bpstrlen(like_part);

	if(equal_part)
		max_len += bpstrlen(equal_part);

	// allocate space for final query (2x max for paranoia)
	final_query = (char *) bpcalloc(max_len * 2, 1);

	// implement select path
	snprintf(&final_query[bpstrlen(final_query)], max_len * 2 -1, "%s", select_part);

	// add where if necessary
	if(min_part || max_part || like_part || equal_part)
		snprintf(&final_query[bpstrlen(final_query)], max_len * 2 -1, " WHERE ");

	if(min_part)
		snprintf(&final_query[bpstrlen(final_query)], max_len * 2 -1, "%s", min_part);

	if(max_part)
		snprintf(&final_query[bpstrlen(final_query)], max_len * 2 -1, "%s", max_part);

	if(like_part)
		snprintf(&final_query[bpstrlen(final_query)], max_len * 2 -1, "%s", like_part);

	if(equal_part)
		snprintf(&final_query[bpstrlen(final_query)], max_len * 2 -1, "%s", equal_part);

	// add terminating 1=1 to last AND if necessary
	if(min_part || max_part || like_part || equal_part)
		snprintf(&final_query[bpstrlen(final_query)], max_len * 2 -1, " 1=1 ");

	// -------------- Resolve Query in Database -------------------------------

	// MySQL Query Bindings
	// Use With null terminated strings only, results are accessed through struct MYSQL pointer
	if(BP_MySQLQuery(mysql_db, final_query))
		return NULL;

	// Returns stored results after a query, NULL on failure
	P_BP_MYSQL_RESULT result = BP_MySQLStoreResult(mysql_db);

	// Returns a result set from a query
	MYSQL_ROW row = (MYSQL_ROW) NULL;

	// array of ports
	BP_NMAPDB_PORTSTATS * portstats_array = NULL;

	// size index
	size_t i = 0;
	size_t x = 0;

	// recover results from the database
	for(
			i = 0;
			row = BP_MySQLFetchRow(result);
			i++
	)
	{

		// set mysql row index to 0 on loop
		x=0;

		// allocate space for the array
		portstats_array = (BP_NMAPDB_PORTSTATS *) bprealloc(portstats_array, sizeof(BP_NMAPDB_PORTSTATS) * (i+1));

		// copy in date
		strncpy( portstats_array[i].d, row[x], sizeof( portstats_array[i].d ) -1);
		x++;

		// copy in time
		strncpy( portstats_array[i].t, row[x], sizeof( portstats_array[i].t ) -1);
		x++;

		// copy in host id
		portstats_array[i].hostid = atoi(row[x]);
		x++;

		// copy in target ip
		strncpy( portstats_array[i].target_ip, row[x], sizeof( portstats_array[i].target_ip ) -1);
		x++;

		// copy in port
		portstats_array[i].port = atoi(row[x]);
		x++;

		// copy in protocol
		strncpy( portstats_array[i].protocol, row[x], sizeof( portstats_array[i].protocol ) -1);
		x++;

		// copy in service
		strncpy( portstats_array[i].service, row[x], sizeof( portstats_array[i].service ) -1);
		x++;

		// copy in state
		strncpy( portstats_array[i].state, row[x], sizeof( portstats_array[i].state ) -1);
		x++;

		// copy in fullversion
		strncpy( portstats_array[i].fullversion, row[x], sizeof( portstats_array[i].fullversion ) -1);
		x++;

		// copy in scannerid
		portstats_array[i].scannerid = atoi(row[x]);
		x++;

		// copy in runid
		portstats_array[i].runid = atoi(row[x]);
		x++;

		// copy in port
		portstats_array[i].rec_id = atoi(row[x]);

		// -- loop to next record --

	}

	// ---------------- Create Returnable Structure -------------

	// if the portstats array structure is filled out, we have a proper result and can
	// populate return values.
	P_BP_NMAPDB_RESULTS final_data = NULL;
	if(portstats_array)
	{

		// opaque result data
		final_data = (P_BP_NMAPDB_RESULTS) bpcalloc(sizeof(BP_NMAPDB_RESULTS), 1);

		// save query
		final_data->query = bpstrndup(final_query, 4096);

		// save opaque data as porstats_array
		final_data->opaque_data = (void *) portstats_array;

		// set type to portstat
		final_data->type = BP_NMAPDB_RESULT_PORTSTATS;

		// set record count to i + 1
		final_data->record_count = i+1;

	}
	// ---------------- Free Allocated Data ----------------------

	if(min_part)
		bpfree(min_part);

	if(max_part)
		bpfree(max_part);

	if(like_part)
		bpfree(like_part);

	if(equal_part)
		bpfree(equal_part);

	if(final_query)
		bpfree(final_query);

	// return the final filled out data structure
	return final_data;
}

// search the hoststats database table
P_BP_NMAPDB_RESULTS BP_NDBSearchHostStats(
		P_BP_MYSQL_SESSION mysql_db,
		P_BP_NMAPDB_HOSTSTATS    min,
		P_BP_NMAPDB_HOSTSTATS    max,
		P_BP_NMAPDB_HOSTSTATS    like,
		P_BP_NMAPDB_HOSTSTATS    equal,
		size_t limitBottom, size_t limitTop
)
{

	if(!mysql_db)
		return NULL;

	// query parts
	char * select_part = NULL;
	char * min_part    = NULL;
	char * max_part    = NULL;
	char * like_part   = NULL;
	char * equal_part  = NULL;

	// final query when built
	char *final_query  = NULL;

	// ------------------- Min --------------------------------
	if(min)
	{

		// create string to hold the min part of the query
		min_part = (char *) bpcalloc(sizeof(BP_NMAPDB_HOSTSTATS)*3, 1);

		// add hostid to query
		if(min->hostid)
			snprintf(&min_part[bpstrlen(min_part)], 40, " hostid < \"%d\" AND ", min->hostid);

		// add ip to query
		if(bpstrlen(min->ip))
			snprintf(&min_part[bpstrlen(min_part)], sizeof(min->ip)-1+40, " ip < \"%s\" AND ", min->ip);

		// add user to query
		if(bpstrlen(min->user))
			snprintf(&min_part[bpstrlen(min_part)], sizeof(min->user)-1+40, " user < \"%s\" AND ", min->user);

		// add userid to query
		if(min->userid)
			snprintf(&min_part[bpstrlen(min_part)], 40, " userid < \"%d\" AND ", min->userid);

		// add date to query
		if(bpstrlen(min->d))
			snprintf(&min_part[bpstrlen(min_part)], sizeof(min->d)-1+40, " d < \"%s\" AND ", min->d);

		// add time to query
		if(bpstrlen(min->t))
			snprintf(&min_part[bpstrlen(min_part)], sizeof(min->t)-1+40, " t < \"%s\" AND ", min->t);

		// add open_ports to query
		if(min->open_ports)
			snprintf(&min_part[bpstrlen(min_part)], 40, " open_ports < \"%d\" AND ", min->open_ports);

		// add ports_scanned to query
		if(min->ports_scanned)
			snprintf(&min_part[bpstrlen(min_part)], 40, " ports_scanned < \"%d\" AND ", min->ports_scanned);

		// add runid to query
		if(min->runid)
			snprintf(&min_part[bpstrlen(min_part)], 40, " runid < \"%d\" AND ", min->runid);

		// add scanner_id to query
		if(min->scanner_id)
			snprintf(&min_part[bpstrlen(min_part)], 40, " scanner_id < \"%d\" AND ", min->scanner_id);

		// add rec_id to query
		if(min->userid)
			snprintf(&min_part[bpstrlen(min_part)], 40, " rec_id < \"%d\" AND ", min->rec_id);

	}

	// ------------------- Max --------------------------------
	if(max)
	{
		// create string to hold the min part of the query
		max_part = (char *) bpcalloc(sizeof(BP_NMAPDB_HOSTSTATS)*3, 1);

		// add hostid to query
		if(max->hostid)
			snprintf(&max_part[bpstrlen(max_part)], 40, " hostid > \"%d\" AND ", max->hostid);

		// add ip to query
		if(bpstrlen(max->ip))
			snprintf(&max_part[bpstrlen(max_part)], sizeof(max->ip)-1+40, " ip > \"%s\" AND ", max->ip);

		// add user to query
		if(bpstrlen(max->user))
			snprintf(&max_part[bpstrlen(max_part)], sizeof(max->user)-1+40, " user > \"%s\" AND ", max->user);

		// add userid to query
		if(max->userid)
			snprintf(&max_part[bpstrlen(max_part)], 40, " userid > \"%d\" AND ", max->userid);

		// add date to query
		if(bpstrlen(max->d))
			snprintf(&max_part[bpstrlen(max_part)], sizeof(max->d)-1+40, " d > \"%s\" AND ", max->d);

		// add time to query
		if(bpstrlen(max->t))
			snprintf(&max_part[bpstrlen(max_part)], sizeof(max->t)-1+40, " t > \"%s\" AND ", max->t);

		// add open_ports to query
		if(max->open_ports)
			snprintf(&max_part[bpstrlen(max_part)], 40, " open_ports > \"%d\" AND ", max->open_ports);

		// add ports_scanned to query
		if(max->ports_scanned)
			snprintf(&max_part[bpstrlen(max_part)], 40, " ports_scanned > \"%d\" AND ", max->ports_scanned);

		// add runid to query
		if(max->runid)
			snprintf(&max_part[bpstrlen(max_part)], 40, " runid > \"%d\" AND ", max->runid);

		// add scanner_id to query
		if(max->scanner_id)
			snprintf(&max_part[bpstrlen(max_part)], 40, " scanner_id > \"%d\" AND ", max->scanner_id);

		// add rec_id to query
		if(max->userid)
			snprintf(&max_part[bpstrlen(max_part)], 40, " rec_id > \"%d\" AND ", max->rec_id);

	}

	// ------------------- Like --------------------------------
	if(like)
	{
		// create string to hold the min part of the query
		like_part = (char *) bpcalloc(sizeof(BP_NMAPDB_HOSTSTATS)*3, 1);

		// add hostid to query
		if(like->hostid)
			snprintf(&like_part[bpstrlen(like_part)], 40, " hostid like \"%%%d%%\" AND ", like->hostid);

		// add ip to query
		if(bpstrlen(like->ip))
			snprintf(&like_part[bpstrlen(like_part)], sizeof(like->ip)-1+40, " ip like \"%%%s%%\" AND ", like->ip);

		// add user to query
		if(bpstrlen(like->user))
			snprintf(&like_part[bpstrlen(like_part)], sizeof(like->user)-1+40, " user like \"%%%s%%\" AND ", like->user);

		// add userid to query
		if(like->userid)
			snprintf(&like_part[bpstrlen(like_part)], 40, " userid like \"%%%d%%\" AND ", like->userid);

		// add date to query
		if(bpstrlen(like->d))
			snprintf(&like_part[bpstrlen(like_part)], sizeof(like->d)-1+40, " d like \"%%%s%%\" AND ", like->d);

		// add time to query
		if(bpstrlen(like->t))
			snprintf(&like_part[bpstrlen(like_part)], sizeof(like->t)-1+40, " t like \"%%%s%%\" AND ", like->t);

		// add open_ports to query
		if(like->open_ports)
			snprintf(&like_part[bpstrlen(like_part)], 40, " open_ports like \"%%%d%%\" AND ", like->open_ports);

		// add ports_scanned to query
		if(like->ports_scanned)
			snprintf(&like_part[bpstrlen(like_part)], 40, " ports_scanned like \"%%%d%%\" AND ", like->ports_scanned);

		// add runid to query
		if(like->runid)
			snprintf(&like_part[bpstrlen(like_part)], 40, " runid like \"%%%d%%\" AND ", like->runid);

		// add scanner_id to query
		if(like->scanner_id)
			snprintf(&like_part[bpstrlen(like_part)], 40, " scanner_id like \"%%%d%%\" AND ", like->scanner_id);

		// add rec_id to query
		if(like->userid)
			snprintf(&like_part[bpstrlen(like_part)], 40, " rec_id like \"%%%d%%\" AND ", like->rec_id);

	}

	// ------------------- Equal --------------------------------
	if(equal)
	{

		// create string to hold the min part of the query
		equal_part = (char *) bpcalloc(sizeof(BP_NMAPDB_HOSTSTATS)*3, 1);

		// add hostid to query
		if(equal->hostid)
			snprintf(&equal_part[bpstrlen(equal_part)], 40, " hostid = \"%d\" AND ", equal->hostid);

		// add ip to query
		if(bpstrlen(equal->ip))
			snprintf(&equal_part[bpstrlen(equal_part)], sizeof(equal->ip)-1+40, " ip = \"%s\" AND ", equal->ip);

		// add user to query
		if(bpstrlen(equal->user))
			snprintf(&equal_part[bpstrlen(equal_part)], sizeof(equal->user)-1+40, " user = \"%s\" AND ", equal->user);

		// add userid to query
		if(equal->userid)
			snprintf(&equal_part[bpstrlen(equal_part)], 40, " userid = \"%d\" AND ", equal->userid);

		// add date to query
		if(bpstrlen(equal->d))
			snprintf(&equal_part[bpstrlen(equal_part)], sizeof(equal->d)-1+40, " d = \"%s\" AND ", equal->d);

		// add time to query
		if(bpstrlen(equal->t))
			snprintf(&equal_part[bpstrlen(equal_part)], sizeof(equal->t)-1+40, " t = \"%s\" AND ", equal->t);

		// add open_ports to query
		if(equal->open_ports)
			snprintf(&equal_part[bpstrlen(equal_part)], 40, " open_ports = \"%d\" AND ", equal->open_ports);

		// add ports_scanned to query
		if(equal->ports_scanned)
			snprintf(&equal_part[bpstrlen(equal_part)], 40, " ports_scanned = \"%d\" AND ", equal->ports_scanned);

		// add runid to query
		if(equal->runid)
			snprintf(&equal_part[bpstrlen(equal_part)], 40, " runid = \"%d\" AND ", equal->runid);

		// add scanner_id to query
		if(equal->scanner_id)
			snprintf(&equal_part[bpstrlen(equal_part)], 40, " scanner_id = \"%d\" AND ", equal->scanner_id);

		// add rec_id to query
		if(equal->userid)
			snprintf(&equal_part[bpstrlen(equal_part)], 40, " rec_id = \"%d\" AND ", equal->rec_id);

	}

	// ---------------- Run Query --------------------------------

	// query parts
	select_part = "select * from hoststats ";

	// max length variable
	size_t max_len = bpstrlen(select_part);

	if(min_part)
		max_len += bpstrlen(min_part);

	if(max_part)
		max_len += bpstrlen(max_part);

	if(like_part)
		max_len += bpstrlen(like_part);

	if(equal_part)
		max_len += bpstrlen(equal_part);

	// allocate space for final query (2x max for paranoia)
	final_query = (char *) bpcalloc(max_len * 2, 1);

	// implement select path
	snprintf(&final_query[bpstrlen(final_query)], max_len * 2 -1, "%s", select_part);

	// add where if necessary
	if(min_part || max_part || like_part || equal_part)
		snprintf(&final_query[bpstrlen(final_query)], max_len * 2 -1, " WHERE ");

	if(min_part)
		snprintf(&final_query[bpstrlen(final_query)], max_len * 2 -1, "%s", min_part);

	if(max_part)
		snprintf(&final_query[bpstrlen(final_query)], max_len * 2 -1, "%s", max_part);

	if(like_part)
		snprintf(&final_query[bpstrlen(final_query)], max_len * 2 -1, "%s", like_part);

	if(equal_part)
		snprintf(&final_query[bpstrlen(final_query)], max_len * 2 -1, "%s", equal_part);

	// add terminating 1=1 to last AND if necessary
	if(min_part || max_part || like_part || equal_part)
		snprintf(&final_query[bpstrlen(final_query)], max_len * 2 -1, " 1=1 ");

	// -------------- Resolve Query in Database -------------------------------

	// MySQL Query Bindings
	// Use With null terminated strings only, results are accessed through struct MYSQL pointer
	if(BP_MySQLQuery(mysql_db, final_query))
		return NULL;

	// Returns stored results after a query, NULL on failure
	P_BP_MYSQL_RESULT result = BP_MySQLStoreResult(mysql_db);

	// Returns a result set from a query
	MYSQL_ROW row = (MYSQL_ROW) NULL;

	// array of ports
	BP_NMAPDB_HOSTSTATS * hoststats_array = NULL;

	// size index
	size_t i = 0;
	size_t x = 0;

	// recover results from the database
	for(
			i = 0;
			row = BP_MySQLFetchRow(result);
			i++
	)
	{

		// set mysql row index to 0 on loop
		x=0;

		// allocate space for the array
		hoststats_array = (BP_NMAPDB_HOSTSTATS *) bprealloc(hoststats_array, sizeof(BP_NMAPDB_HOSTSTATS) * (i+1));

		// copy in host id
		hoststats_array[i].hostid = atoi(row[x]);
		x++;

		// copy in ip
		strncpy( hoststats_array[i].ip, row[x], sizeof( hoststats_array[i].ip) -1);
		x++;

		// copy in user
		strncpy( hoststats_array[i].user, row[x], sizeof( hoststats_array[i].user) -1);
		x++;

		// copy in hostid
		hoststats_array[i].hostid = atoi(row[x]);
		x++;

		// copy in date (d)
		strncpy( hoststats_array[i].d, row[x], sizeof( hoststats_array[i].d) -1);
		x++;

		// copy in time (t)
		strncpy( hoststats_array[i].t, row[x], sizeof( hoststats_array[i].t) -1);
		x++;

		// copy in open_ports
		hoststats_array[i].open_ports = atoi(row[x]);
		x++;

		// copy in ports_scanned
		hoststats_array[i].ports_scanned = atoi(row[x]);
		x++;

		// copy in runid
		hoststats_array[i].runid = atoi(row[x]);
		x++;

		// copy in scanner_id
		hoststats_array[i].scanner_id = atoi(row[x]);
		x++;

		// copy in rec_id
		hoststats_array[i].rec_id = atoi(row[x]);
		x++;

		// -- loop to next record --

	}

	// ---------------- Create Returnable Structure -------------

	// if the portstats array structure is filled out, we have a proper result and can
	// populate return values.
	P_BP_NMAPDB_RESULTS final_data = NULL;
	if(hoststats_array)
	{

		// opaque result data
		final_data = (P_BP_NMAPDB_RESULTS) bpcalloc(sizeof(BP_NMAPDB_RESULTS), 1);

		// save query
		final_data->query = bpstrndup(final_query, 4096);

		// save opaque data as porstats_array
		final_data->opaque_data = (void *) hoststats_array;

		// set type to hoststat
		final_data->type = BP_NMAPDB_RESULT_HOSTSTATS;

		// set record count to i + 1
		final_data->record_count = i+1;

	}
	// ---------------- Free Allocated Data ----------------------

	if(min_part)
		bpfree(min_part);

	if(max_part)
		bpfree(max_part);

	if(like_part)
		bpfree(like_part);

	if(equal_part)
		bpfree(equal_part);

	if(final_query)
		bpfree(final_query);

	// return the final filled out data structure
	return final_data;

}

// search the targets database table
P_BP_NMAPDB_RESULTS BP_NDBSearchTargets(
		P_BP_MYSQL_SESSION mysql_db,
		P_NMAPDB_TARGETS         min,
		P_NMAPDB_TARGETS         max,
		P_NMAPDB_TARGETS         like,
		P_NMAPDB_TARGETS         equal,
		size_t limitBottom, size_t limitTop
)
{

	if(!mysql_db)
		return NULL;

	// query parts
	char * select_part = NULL;
	char * min_part    = NULL;
	char * max_part    = NULL;
	char * like_part   = NULL;
	char * equal_part  = NULL;

	// final query when built
	char *final_query  = NULL;

	// ------------------- Min --------------------------------
	if(min)
	{
		// create string to hold the min part of the query
		min_part = (char *) bpcalloc(sizeof(BP_NMAPDB_TARGETS)*3, 1);

		// add host to query
		if(bpstrlen(min->host))
			snprintf(&min_part[bpstrlen(min_part)], sizeof(min->host)-1+40, " host < \"%s\" AND ", min->host);

		// add date to query
		if(bpstrlen(min->d))
			snprintf(&min_part[bpstrlen(min_part)], sizeof(min->d)-1+40, " d < \"%s\" AND ", min->d);

		// add time to query
		if(bpstrlen(min->t))
			snprintf(&min_part[bpstrlen(min_part)], sizeof(min->d)-1+40, " t < \"%s\" AND ", min->t);

		// add ip to query
		if(bpstrlen(min->ip))
			snprintf(&min_part[bpstrlen(min_part)], sizeof(min->ip)-1+40, " ip < \"%s\" AND ", min->ip);

		// add ipnum to query
		if(min->ipnum)
			snprintf(&min_part[bpstrlen(min_part)], 40, " ipnum < \"%d\" AND ", min->ipnum);

		// add mac to query
		if(bpstrlen(min->mac))
			snprintf(&min_part[bpstrlen(min_part)], sizeof(min->mac)-1+40, " mac < \"%s\" AND ", min->mac);

		// add macvendor to query
		if(bpstrlen(min->macvendor))
			snprintf(&min_part[bpstrlen(min_part)], sizeof(min->mac)-1+40, " macvendor < \"%s\" AND ", min->macvendor);

		// add flag to query
		if(min->flag)
			snprintf(&min_part[bpstrlen(min_part)], 40, " flag < \"%d\" AND ", min->flag);

		// add ipnum to query
		if(min->hostid)
			snprintf(&min_part[bpstrlen(min_part)], 40, " hostid < \"%d\" AND ", min->hostid);

		// add description to query
		if(bpstrlen(min->description))
			snprintf(&min_part[bpstrlen(min_part)], sizeof(min->description)-1+40, " description < \"%s\" AND ", min->description);

		// add os_guessed to query
		if(bpstrlen(min->os_guessed))
			snprintf(&min_part[bpstrlen(min_part)], sizeof(min->os_guessed)-1+40, " os_guessed < \"%s\" AND ", min->os_guessed);

		// add os_known to query
		if(bpstrlen(min->os_known))
			snprintf(&min_part[bpstrlen(min_part)], sizeof(min->os_known)-1+40, " os_known < \"%s\" AND ", min->os_known);

		// add macvendor to query
		if(bpstrlen(min->fingerprint))
			snprintf(&min_part[bpstrlen(min_part)], sizeof(min->fingerprint)-1+40, " fingerprint < \"%s\" AND ", min->fingerprint);

		// add rec_id to query
		if(min->rec_id)
			snprintf(&min_part[bpstrlen(min_part)], 40, " rec_id < \"%d\" AND ", min->rec_id);

	}

	// ------------------- Max --------------------------------
	if(max)
	{
		// create string to hold the min part of the query
		max_part = (char *) bpcalloc(sizeof(BP_NMAPDB_TARGETS)*3, 1);

		// add host to query
		if(bpstrlen(max->host))
			snprintf(&max_part[bpstrlen(max_part)], sizeof(max->host)-1+40, " host > \"%s\" AND ", max->host);

		// add date to query
		if(bpstrlen(max->d))
			snprintf(&max_part[bpstrlen(max_part)], sizeof(max->d)-1+40, " d > \"%s\" AND ", max->d);

		// add time to query
		if(bpstrlen(max->t))
			snprintf(&max_part[bpstrlen(max_part)], sizeof(max->d)-1+40, " t > \"%s\" AND ", max->t);

		// add ip to query
		if(bpstrlen(max->ip))
			snprintf(&max_part[bpstrlen(max_part)], sizeof(max->ip)-1+40, " ip > \"%s\" AND ", max->ip);

		// add ipnum to query
		if(max->ipnum)
			snprintf(&max_part[bpstrlen(max_part)], 40, " ipnum > \"%d\" AND ", max->ipnum);

		// add mac to query
		if(bpstrlen(max->mac))
			snprintf(&max_part[bpstrlen(max_part)], sizeof(max->mac)-1+40, " mac > \"%s\" AND ", max->mac);

		// add macvendor to query
		if(bpstrlen(max->macvendor))
			snprintf(&max_part[bpstrlen(max_part)], sizeof(max->mac)-1+40, " macvendor > \"%s\" AND ", max->macvendor);

		// add flag to query
		if(max->flag)
			snprintf(&max_part[bpstrlen(max_part)], 40, " flag > \"%d\" AND ", max->flag);

		// add ipnum to query
		if(max->hostid)
			snprintf(&max_part[bpstrlen(max_part)], 40, " hostid > \"%d\" AND ", max->hostid);

		// add description to query
		if(bpstrlen(max->description))
			snprintf(&max_part[bpstrlen(max_part)], sizeof(max->description)-1+40, " description > \"%s\" AND ", max->description);

		// add os_guessed to query
		if(bpstrlen(max->os_guessed))
			snprintf(&max_part[bpstrlen(max_part)], sizeof(max->os_guessed)-1+40, " os_guessed > \"%s\" AND ", max->os_guessed);

		// add os_known to query
		if(bpstrlen(max->os_known))
			snprintf(&max_part[bpstrlen(max_part)], sizeof(max->os_known)-1+40, " os_known > \"%s\" AND ", max->os_known);

		// add macvendor to query
		if(bpstrlen(max->fingerprint))
			snprintf(&max_part[bpstrlen(max_part)], sizeof(max->fingerprint)-1+40, " fingerprint > \"%s\" AND ", max->fingerprint);

		// add rec_id to query
		if(max->rec_id)
			snprintf(&max_part[bpstrlen(max_part)], 40, " rec_id > \"%d\" AND ", max->rec_id);

	}

	// ------------------- Like --------------------------------
	if(like)
	{
		// create string to hold the min part of the query
		like_part = (char *) bpcalloc(sizeof(BP_NMAPDB_TARGETS)*3, 1);

		// add host to query
		if(bpstrlen(like->host))
			snprintf(&like_part[bpstrlen(like_part)], sizeof(like->host)-1+40, " host like \"%%%s%%\" AND ", like->host);

		// add date to query
		if(bpstrlen(like->d))
			snprintf(&like_part[bpstrlen(like_part)], sizeof(like->d)-1+40, " d like \"%%%s%%\" AND ", like->d);

		// add time to query
		if(bpstrlen(like->t))
			snprintf(&like_part[bpstrlen(like_part)], sizeof(like->d)-1+40, " t like \"%%%s%%\" AND ", like->t);

		// add ip to query
		if(bpstrlen(like->ip))
			snprintf(&like_part[bpstrlen(like_part)], sizeof(like->ip)-1+40, " ip like \"%%%s%%\" AND ", like->ip);

		// add ipnum to query
		if(like->ipnum)
			snprintf(&like_part[bpstrlen(like_part)], 40, " ipnum like \"%%%d%%\" AND ", like->ipnum);

		// add mac to query
		if(bpstrlen(like->mac))
			snprintf(&like_part[bpstrlen(like_part)], sizeof(like->mac)-1+40, " mac like \"%%%s%%\" AND ", like->mac);

		// add macvendor to query
		if(bpstrlen(like->macvendor))
			snprintf(&like_part[bpstrlen(like_part)], sizeof(like->mac)-1+40, " macvendor like \"%%%s%%\" AND ", like->macvendor);

		// add flag to query
		if(like->flag)
			snprintf(&like_part[bpstrlen(like_part)], 40, " flag like \"%%%d%%\" AND ", like->flag);

		// add ipnum to query
		if(like->hostid)
			snprintf(&like_part[bpstrlen(like_part)], 40, " hostid like \"%%%d%%\" AND ", like->hostid);

		// add description to query
		if(bpstrlen(like->description))
			snprintf(&like_part[bpstrlen(like_part)], sizeof(like->description)-1+40, " description like \"%%%s%%\" AND ", like->description);

		// add os_guessed to query
		if(bpstrlen(like->os_guessed))
			snprintf(&like_part[bpstrlen(like_part)], sizeof(like->os_guessed)-1+40, " os_guessed like \"%%%s%%\" AND ", like->os_guessed);

		// add os_known to query
		if(bpstrlen(like->os_known))
			snprintf(&like_part[bpstrlen(like_part)], sizeof(like->os_known)-1+40, " os_known like \"%%%s%%\" AND ", like->os_known);

		// add macvendor to query
		if(bpstrlen(like->fingerprint))
			snprintf(&like_part[bpstrlen(like_part)], sizeof(like->fingerprint)-1+40, " fingerprint like \"%%%s%%\" AND ", like->fingerprint);

		// add rec_id to query
		if(like->rec_id)
			snprintf(&like_part[bpstrlen(like_part)], 40, " rec_id like \"%%%d%%\" AND ", like->rec_id);

	}

	// ------------------- Equal --------------------------------
	if(equal)
	{

		// create string to hold the min part of the query
		equal_part = (char *) bpcalloc(sizeof(BP_NMAPDB_TARGETS)*3, 1);

		// add host to query
		if(bpstrlen(equal->host))
			snprintf(&equal_part[bpstrlen(equal_part)], sizeof(equal->host)-1+40, " host = \"%s\" AND ", equal->host);

		// add date to query
		if(bpstrlen(equal->d))
			snprintf(&equal_part[bpstrlen(equal_part)], sizeof(equal->d)-1+40, " d = \"%s\" AND ", equal->d);

		// add time to query
		if(bpstrlen(equal->t))
			snprintf(&equal_part[bpstrlen(equal_part)], sizeof(equal->d)-1+40, " t = \"%s\" AND ", equal->t);

		// add ip to query
		if(bpstrlen(equal->ip))
			snprintf(&equal_part[bpstrlen(equal_part)], sizeof(equal->ip)-1+40, " ip = \"%s\" AND ", equal->ip);

		// add ipnum to query
		if(equal->ipnum)
			snprintf(&equal_part[bpstrlen(equal_part)], 40, " ipnum = \"%d\" AND ", equal->ipnum);

		// add mac to query
		if(bpstrlen(equal->mac))
			snprintf(&equal_part[bpstrlen(equal_part)], sizeof(equal->mac)-1+40, " mac = \"%s\" AND ", equal->mac);

		// add macvendor to query
		if(bpstrlen(equal->macvendor))
			snprintf(&equal_part[bpstrlen(equal_part)], sizeof(equal->mac)-1+40, " macvendor = \"%s\" AND ", equal->macvendor);

		// add flag to query
		if(equal->flag)
			snprintf(&equal_part[bpstrlen(equal_part)], 40, " flag = \"%d\" AND ", equal->flag);

		// add ipnum to query
		if(equal->hostid)
			snprintf(&equal_part[bpstrlen(equal_part)], 40, " hostid = \"%d\" AND ", equal->hostid);

		// add description to query
		if(bpstrlen(equal->description))
			snprintf(&equal_part[bpstrlen(equal_part)], sizeof(equal->description)-1+40, " description = \"%s\" AND ", equal->description);

		// add os_guessed to query
		if(bpstrlen(equal->os_guessed))
			snprintf(&equal_part[bpstrlen(equal_part)], sizeof(equal->os_guessed)-1+40, " os_guessed = \"%s\" AND ", equal->os_guessed);

		// add os_known to query
		if(bpstrlen(equal->os_known))
			snprintf(&equal_part[bpstrlen(equal_part)], sizeof(equal->os_known)-1+40, " os_known = \"%s\" AND ", equal->os_known);

		// add macvendor to query
		if(bpstrlen(equal->fingerprint))
			snprintf(&equal_part[bpstrlen(equal_part)], sizeof(equal->fingerprint)-1+40, " fingerprint = \"%s\" AND ", equal->fingerprint);

		// add rec_id to query
		if(equal->rec_id)
			snprintf(&equal_part[bpstrlen(equal_part)], 40, " rec_id = \"%d\" AND ", equal->rec_id);

	}

	// ---------------- Run Query --------------------------------

	// query parts
	select_part = "select * from targets ";

	// max length variable
	size_t max_len = bpstrlen(select_part);

	if(min_part)
		max_len += bpstrlen(min_part);

	if(max_part)
		max_len += bpstrlen(max_part);

	if(like_part)
		max_len += bpstrlen(like_part);

	if(equal_part)
		max_len += bpstrlen(equal_part);

	// allocate space for final query (2x max for paranoia)
	final_query = (char *) bpcalloc(max_len * 2, 1);

	// implement select path
	snprintf(&final_query[bpstrlen(final_query)], max_len * 2 -1, "%s", select_part);

	// add where if necessary
	if(min_part || max_part || like_part || equal_part)
		snprintf(&final_query[bpstrlen(final_query)], max_len * 2 -1, " WHERE ");

	if(min_part)
		snprintf(&final_query[bpstrlen(final_query)], max_len * 2 -1, "%s", min_part);

	if(max_part)
		snprintf(&final_query[bpstrlen(final_query)], max_len * 2 -1, "%s", max_part);

	if(like_part)
		snprintf(&final_query[bpstrlen(final_query)], max_len * 2 -1, "%s", like_part);

	if(equal_part)
		snprintf(&final_query[bpstrlen(final_query)], max_len * 2 -1, "%s", equal_part);

	// add terminating 1=1 to last AND if necessary
	if(min_part || max_part || like_part || equal_part)
		snprintf(&final_query[bpstrlen(final_query)], max_len * 2 -1, " 1=1 ");

	// -------------- Resolve Query in Database -------------------------------

	// MySQL Query Bindings
	// Use With null terminated strings only, results are accessed through struct MYSQL pointer
	if(BP_MySQLQuery(mysql_db, final_query))
		return NULL;

	// Returns stored results after a query, NULL on failure
	P_BP_MYSQL_RESULT result = BP_MySQLStoreResult(mysql_db);

	// Returns a result set from a query
	MYSQL_ROW row = (MYSQL_ROW) NULL;

	// array of ports
	BP_NMAPDB_TARGETS * targets_array = NULL;

	// size index
	size_t i = 0;
	size_t x = 0;

	// recover results from the database
	for(
			i = 0;
			row = BP_MySQLFetchRow(result);
			i++
	)
	{

		// set mysql row index to 0 on loop
		x=0;

		// allocate space for the array
		targets_array = (BP_NMAPDB_TARGETS *) bprealloc(targets_array, sizeof(BP_NMAPDB_TARGETS) * (i+1));

		// copy in host id
		targets_array[i].hostid = atoi(row[x]);
		x++;

		// copy in host
		strncpy( targets_array[i].host, row[x], sizeof( targets_array[i].host ) -1);
		x++;

		// copy in date (d)
		strncpy( targets_array[i].d, row[x], sizeof( targets_array[i].d ) -1);
		x++;

		// copy in time (t)
		strncpy( targets_array[i].t, row[x], sizeof( targets_array[i].t ) -1);
		x++;

		// copy in ip
		strncpy( targets_array[i].ip, row[x], sizeof( targets_array[i].ip ) -1);
		x++;

		// copy in ipnum
		targets_array[i].ipnum = atoi(row[x]);
		x++;

		// copy in mac
		strncpy( targets_array[i].mac, row[x], sizeof( targets_array[i].mac ) -1);
		x++;

		// copy in macvendor
		strncpy( targets_array[i].macvendor, row[x], sizeof( targets_array[i].macvendor ) -1);
		x++;

		// copy in flag
		targets_array[i].flag = atoi(row[x]);
		x++;

		// copy in descripton
		strncpy( targets_array[i].description, row[x], sizeof( targets_array[i].description ) -1);
		x++;

		// copy in os_guessed
		strncpy( targets_array[i].os_guessed, row[x], sizeof( targets_array[i].os_guessed ) -1);
		x++;

		// copy in os_known
		strncpy( targets_array[i].os_known, row[x], sizeof( targets_array[i].os_known ) -1);
		x++;

		// copy in fingerprint
		strncpy( targets_array[i].fingerprint, row[x], sizeof( targets_array[i].fingerprint ) -1);
		x++;

		// copy in rec_id
		targets_array[i].rec_id = atoi(row[x]);
		x++;

		// -- loop to next record --

	}

	// ---------------- Create Returnable Structure -------------

	// if the portstats array structure is filled out, we have a proper result and can
	// populate return values.
	P_BP_NMAPDB_RESULTS final_data = NULL;
	if(targets_array)
	{

		// opaque result data
		final_data = (P_BP_NMAPDB_RESULTS) bpcalloc(sizeof(BP_NMAPDB_RESULTS), 1);

		// save query
		final_data->query = bpstrndup(final_query, 4096);

		// save opaque data as targets_array
		final_data->opaque_data = (void *) targets_array;

		// set type to portstat
		final_data->type = BP_NMAPDB_RESULT_TARGETS;

		// set record count to i + 1
		final_data->record_count = i+1;

	}
	// ---------------- Free Allocated Data ----------------------

	if(min_part)
		bpfree(min_part);

	if(max_part)
		bpfree(max_part);

	if(like_part)
		bpfree(like_part);

	if(equal_part)
		bpfree(equal_part);

	if(final_query)
		bpfree(final_query);

	// return the final filled out data structure
	return final_data;

}

// search the scanners database table
P_BP_NMAPDB_RESULTS BP_NDBSearchScanners(
		P_BP_MYSQL_SESSION mysql_db,
		P_BP_NMAPDB_SCANNERS     min,
		P_BP_NMAPDB_SCANNERS     max,
		P_BP_NMAPDB_SCANNERS     like,
		P_BP_NMAPDB_SCANNERS     equal,
		size_t limitBottom, size_t limitTop
)
{
	if(!mysql_db)
		return NULL;

	// query parts
	char * select_part = NULL;
	char * min_part    = NULL;
	char * max_part    = NULL;
	char * like_part   = NULL;
	char * equal_part  = NULL;

	// final query when built
	char *final_query  = NULL;

	// ------------------- Min --------------------------------
	if(min)
	{
		// create string to hold the min part of the query
		min_part = (char *) bpcalloc(sizeof(BP_NMAPDB_SCANNERS)*3, 1);

		// add scanner to query
		if(bpstrlen(min->scanner))
			snprintf(&min_part[bpstrlen(min_part)], sizeof(min->scanner)-1+40, " scanner < \"%s\" AND ", min->scanner);

		// add scanner_ip to query
		if(bpstrlen(min->scanner_ip))
			snprintf(&min_part[bpstrlen(min_part)], sizeof(min->scanner_ip)-1+40, " scanner_ip < \"%s\" AND ", min->scanner_ip);

		// add description to query
		if(bpstrlen(min->description))
			snprintf(&min_part[bpstrlen(min_part)], sizeof(min->description)-1+40, " description < \"%s\" AND ", min->description);

		// add date to query
		if(bpstrlen(min->d))
			snprintf(&min_part[bpstrlen(min_part)], sizeof(min->d)-1+40, " d < \"%s\" AND ", min->d);

		// add time to query
		if(bpstrlen(min->t))
			snprintf(&min_part[bpstrlen(min_part)], sizeof(min->t)-1+40, " t < \"%s\" AND ", min->t);

		// add flag to query
		if(min->flag)
			snprintf(&min_part[bpstrlen(min_part)], 40, " flag < \"%d\" AND ", min->flag);

		// add scanner_id to query
		if(min->scanner_id)
			snprintf(&min_part[bpstrlen(min_part)], 40, " scanner_id < \"%d\" AND ", min->scanner_id);

		// add rec_id to query
		if(min->rec_id)
			snprintf(&min_part[bpstrlen(min_part)], 40, " rec_id < \"%d\" AND ", min->rec_id);

	}

	// ------------------- Max --------------------------------
	if(max)
	{
		// create string to hold the min part of the query
		max_part = (char *) bpcalloc(sizeof(BP_NMAPDB_SCANNERS)*3, 1);

		// add scanner to query
		if(bpstrlen(max->scanner))
			snprintf(&max_part[bpstrlen(max_part)], sizeof(max->scanner)-1+40, " scanner > \"%s\" AND ", max->scanner);

		// add scanner_ip to query
		if(bpstrlen(max->scanner_ip))
			snprintf(&max_part[bpstrlen(max_part)], sizeof(max->scanner_ip)-1+40, " scanner_ip > \"%s\" AND ", max->scanner_ip);

		// add description to query
		if(bpstrlen(max->description))
			snprintf(&max_part[bpstrlen(max_part)], sizeof(max->description)-1+40, " description > \"%s\" AND ", max->description);

		// add date to query
		if(bpstrlen(max->d))
			snprintf(&max_part[bpstrlen(max_part)], sizeof(max->d)-1+40, " d > \"%s\" AND ", max->d);

		// add time to query
		if(bpstrlen(max->t))
			snprintf(&max_part[bpstrlen(max_part)], sizeof(max->t)-1+40, " t > \"%s\" AND ", max->t);

		// add flag to query
		if(max->flag)
			snprintf(&max_part[bpstrlen(max_part)], 40, " flag > \"%d\" AND ", max->flag);

		// add scanner_id to query
		if(max->scanner_id)
			snprintf(&max_part[bpstrlen(max_part)], 40, " scanner_id > \"%d\" AND ", max->scanner_id);

		// add rec_id to query
		if(max->rec_id)
			snprintf(&max_part[bpstrlen(max_part)], 40, " rec_id > \"%d\" AND ", max->rec_id);

	}

	// ------------------- Like --------------------------------
	if(like)
	{
		// create string to hold the min part of the query
		like_part = (char *) bpcalloc(sizeof(BP_NMAPDB_SCANNERS)*3, 1);

		// add scanner to query
		if(bpstrlen(like->scanner))
			snprintf(&like_part[bpstrlen(like_part)], sizeof(like->scanner)-1+40, " scanner like \"%%%s%%\" AND ", like->scanner);

		// add scanner_ip to query
		if(bpstrlen(like->scanner_ip))
			snprintf(&like_part[bpstrlen(like_part)], sizeof(like->scanner_ip)-1+40, " scanner_ip like \"%%%s%%\" AND ", like->scanner_ip);

		// add description to query
		if(bpstrlen(like->description))
			snprintf(&like_part[bpstrlen(like_part)], sizeof(like->description)-1+40, " description like \"%%%s%%\" AND ", like->description);

		// add date to query
		if(bpstrlen(like->d))
			snprintf(&like_part[bpstrlen(like_part)], sizeof(like->d)-1+40, " d like \"%%%s%%\" AND ", like->d);

		// add time to query
		if(bpstrlen(like->t))
			snprintf(&like_part[bpstrlen(like_part)], sizeof(like->t)-1+40, " t like \"%%%s%%\" AND ", like->t);

		// add flag to query
		if(like->flag)
			snprintf(&like_part[bpstrlen(like_part)], 40, " flag like \"%%%d%%\" AND ", like->flag);

		// add scanner_id to query
		if(like->scanner_id)
			snprintf(&like_part[bpstrlen(like_part)], 40, " scanner_id like \"%%%d%%\" AND ", like->scanner_id);

		// add rec_id to query
		if(like->rec_id)
			snprintf(&like_part[bpstrlen(like_part)], 40, " rec_id like \"%%%d%%\" AND ", like->rec_id);

	}

	// ------------------- Equal --------------------------------
	if(equal)
	{

		// create string to hold the like part of the query
		equal_part = (char *) bpcalloc(sizeof(BP_NMAPDB_SCANNERS)*3, 1);

		// add scanner to query
		if(bpstrlen(equal->scanner))
			snprintf(&equal_part[bpstrlen(equal_part)], sizeof(equal->scanner)-1+40, " scanner = \"%s\" AND ", equal->scanner);

		// add scanner_ip to query
		if(bpstrlen(equal->scanner_ip))
			snprintf(&equal_part[bpstrlen(equal_part)], sizeof(equal->scanner_ip)-1+40, " scanner_ip = \"%s\" AND ", equal->scanner_ip);

		// add description to query
		if(bpstrlen(equal->description))
			snprintf(&equal_part[bpstrlen(equal_part)], sizeof(equal->description)-1+40, " description = \"%s\" AND ", equal->description);

		// add date to query
		if(bpstrlen(equal->d))
			snprintf(&equal_part[bpstrlen(equal_part)], sizeof(equal->d)-1+40, " d = \"%s\" AND ", equal->d);

		// add time to query
		if(bpstrlen(equal->t))
			snprintf(&equal_part[bpstrlen(equal_part)], sizeof(equal->t)-1+40, " t = \"%s\" AND ", equal->t);

		// add flag to query
		if(equal->flag)
			snprintf(&equal_part[bpstrlen(equal_part)], 40, " flag = \"%d\" AND ", equal->flag);

		// add scanner_id to query
		if(equal->scanner_id)
			snprintf(&equal_part[bpstrlen(equal_part)], 40, " scanner_id = \"%d\" AND ", equal->scanner_id);

		// add rec_id to query
		if(equal->rec_id)
			snprintf(&equal_part[bpstrlen(equal_part)], 40, " rec_id = \"%d\" AND ", equal->rec_id);

	}

	// ---------------- Run Query --------------------------------

	// query parts
	select_part = "select * from scanners ";

	// max length variable
	size_t max_len = bpstrlen(select_part);

	if(min_part)
		max_len += bpstrlen(min_part);

	if(max_part)
		max_len += bpstrlen(max_part);

	if(like_part)
		max_len += bpstrlen(like_part);

	if(equal_part)
		max_len += bpstrlen(equal_part);

	// allocate space for final query (2x max for paranoia)
	final_query = (char *) bpcalloc(max_len * 2, 1);

	// implement select path
	snprintf(&final_query[bpstrlen(final_query)], max_len * 2 -1, "%s", select_part);

	// add where if necessary
	if(min_part || max_part || like_part || equal_part)
		snprintf(&final_query[bpstrlen(final_query)], max_len * 2 -1, " WHERE ");

	if(min_part)
		snprintf(&final_query[bpstrlen(final_query)], max_len * 2 -1, "%s", min_part);

	if(max_part)
		snprintf(&final_query[bpstrlen(final_query)], max_len * 2 -1, "%s", max_part);

	if(like_part)
		snprintf(&final_query[bpstrlen(final_query)], max_len * 2 -1, "%s", like_part);

	if(equal_part)
		snprintf(&final_query[bpstrlen(final_query)], max_len * 2 -1, "%s", equal_part);

	// add terminating 1=1 to last AND if necessary
	if(min_part || max_part || like_part || equal_part)
		snprintf(&final_query[bpstrlen(final_query)], max_len * 2 -1, " 1=1 ");

	// -------------- Resolve Query in Database -------------------------------

	// MySQL Query Bindings
	// Use With null terminated strings only, results are accessed through struct MYSQL pointer
	if(BP_MySQLQuery(mysql_db, final_query))
		return NULL;

	// Returns stored results after a query, NULL on failure
	P_BP_MYSQL_RESULT result = BP_MySQLStoreResult(mysql_db);

	// Returns a result set from a query
	MYSQL_ROW row = (MYSQL_ROW) NULL;

	// array of scanners
	BP_NMAPDB_SCANNERS * scanners_array = NULL;

	// size index
	size_t i = 0;
	size_t x = 0;

	// recover results from the database
	for(
			i = 0;
			row = BP_MySQLFetchRow(result);
			i++
	)
	{

		// set mysql row index to 0 on loop
		x=0;

		// allocate space for the array
		scanners_array = (BP_NMAPDB_SCANNERS *) bprealloc(scanners_array, sizeof(BP_NMAPDB_SCANNERS) * (i+1));

		// copy in scanner
		strncpy( scanners_array[i].scanner, row[x], sizeof( scanners_array[i].scanner ) -1);
		x++;

		// copy in scanner_ip
		strncpy( scanners_array[i].scanner_ip, row[x], sizeof( scanners_array[i].scanner_ip ) -1);
		x++;

		// copy in description
		strncpy( scanners_array[i].description, row[x], sizeof( scanners_array[i].description ) -1);
		x++;

		// copy in date (d)
		strncpy( scanners_array[i].d, row[x], sizeof( scanners_array[i].d ) -1);
		x++;

		// copy in time (t)
		strncpy( scanners_array[i].t, row[x], sizeof( scanners_array[i].t ) -1);
		x++;

		// copy in flag
		scanners_array[i].flag = atoi(row[x]);
		x++;

		// copy in scanner_id
		scanners_array[i].scanner_id = atoi(row[x]);
		x++;

		// copy in rec_id
		scanners_array[i].rec_id = atoi(row[x]);
		x++;

		// -- loop to next record --

	}

	// ---------------- Create Returnable Structure -------------

	// if the scanners array structure is filled out, we have a proper result and can
	// populate return values.
	P_BP_NMAPDB_RESULTS final_data = NULL;
	if(scanners_array)
	{

		// opaque result data
		final_data = (P_BP_NMAPDB_RESULTS) bpcalloc(sizeof(BP_NMAPDB_RESULTS), 1);

		// save query
		final_data->query = bpstrndup(final_query, 4096);

		// save opaque data as porstats_array
		final_data->opaque_data = (void *) scanners_array;

		// set type to portstat
		final_data->type = BP_NMAPDB_RESULT_SCANNERS;

		// set record count to i + 1
		final_data->record_count = i+1;

	}
	// ---------------- Free Allocated Data ----------------------

	if(min_part)
		bpfree(min_part);

	if(max_part)
		bpfree(max_part);

	if(like_part)
		bpfree(like_part);

	if(equal_part)
		bpfree(equal_part);

	if(final_query)
		bpfree(final_query);

	// return the final filled out data structure
	return final_data;

}

// search the run list database table
P_BP_NMAPDB_RESULTS BP_NDBSearchRunlist(
		P_BP_MYSQL_SESSION mysql_db,
		P_BP_NMAPDB_RUNLIST      min,
		P_BP_NMAPDB_RUNLIST      max,
		P_BP_NMAPDB_RUNLIST      like,
		P_BP_NMAPDB_RUNLIST      equal,
		size_t limitBottom, size_t limitTop
)
{
	if(!mysql_db)
		return NULL;

	// query parts
	char * select_part = NULL;
	char * min_part    = NULL;
	char * max_part    = NULL;
	char * like_part   = NULL;
	char * equal_part  = NULL;

	// final query when built
	char *final_query  = NULL;

	// ------------------- Min --------------------------------
	if(min)
	{
		// create string to hold the min part of the query
		min_part = (char *) bpcalloc(sizeof(BP_NMAPDB_RUNLIST)*3, 1);

		// add date (d) to query
		if(bpstrlen(min->d))
			snprintf(&min_part[bpstrlen(min_part)], sizeof(min->d)-1+40, " d < \"%s\" AND ", min->d);

		// add time (t) to query
		if(bpstrlen(min->t))
			snprintf(&min_part[bpstrlen(min_part)], sizeof(min->t)-1+40, " t < \"%s\" AND ", min->t);

		// add run_type to query
		if(min->run_type)
			snprintf(&min_part[bpstrlen(min_part)], 40, " run_type < \"%d\" AND ", min->run_type);

		// add user to query
		if(bpstrlen(min->user))
			snprintf(&min_part[bpstrlen(min_part)], sizeof(min->user)-1+40, " user < \"%s\" AND ", min->user);

		// add userid to query
		if(min->userid)
			snprintf(&min_part[bpstrlen(min_part)], 40, " userid < \"%d\" AND ", min->userid);

		// add host to query
		if(bpstrlen(min->host))
			snprintf(&min_part[bpstrlen(min_part)], sizeof(min->host)-1+40, " user < \"%s\" AND ", min->host);

		// add host_ip to query
		if(bpstrlen(min->host_ip))
			snprintf(&min_part[bpstrlen(min_part)], sizeof(min->user)-1+40, " host_ip < \"%s\" AND ", min->host_ip);

		// add numscanned to query
		if(min->numscanned)
			snprintf(&min_part[bpstrlen(min_part)], 40, " numscanned < \"%d\" AND ", min->numscanned);

		// add userid to query
		if(min->numup)
			snprintf(&min_part[bpstrlen(min_part)], 40, " numup < \"%d\" AND ", min->numup);

		// add runid to query
		if(min->runid)
			snprintf(&min_part[bpstrlen(min_part)], 40, " runid < \"%d\" AND ", min->runid);

		// add rec_id to query
		if(min->rec_id)
			snprintf(&min_part[bpstrlen(min_part)], 40, " rec_id < \"%d\" AND ", min->rec_id);

	}

	// ------------------- Max --------------------------------
	if(max)
	{
		// create string to hold the min part of the query
		max_part = (char *) bpcalloc(sizeof(BP_NMAPDB_RUNLIST)*3, 1);

		// add date (d) to query
		if(bpstrlen(max->d))
			snprintf(&max_part[bpstrlen(max_part)], sizeof(max->d)-1+40, " d > \"%s\" AND ", max->d);

		// add time (t) to query
		if(bpstrlen(max->t))
			snprintf(&max_part[bpstrlen(max_part)], sizeof(max->t)-1+40, " t > \"%s\" AND ", max->t);

		// add run_type to query
		if(max->run_type)
			snprintf(&max_part[bpstrlen(max_part)], 40, " run_type > \"%d\" AND ", max->run_type);

		// add user to query
		if(bpstrlen(max->user))
			snprintf(&max_part[bpstrlen(max_part)], sizeof(max->user)-1+40, " user > \"%s\" AND ", max->user);

		// add userid to query
		if(max->userid)
			snprintf(&max_part[bpstrlen(max_part)], 40, " userid > \"%d\" AND ", max->userid);

		// add host to query
		if(bpstrlen(max->host))
			snprintf(&max_part[bpstrlen(max_part)], sizeof(max->host)-1+40, " user > \"%s\" AND ", max->host);

		// add host_ip to query
		if(bpstrlen(max->host_ip))
			snprintf(&max_part[bpstrlen(max_part)], sizeof(max->user)-1+40, " host_ip > \"%s\" AND ", max->host_ip);

		// add numscanned to query
		if(max->numscanned)
			snprintf(&max_part[bpstrlen(max_part)], 40, " numscanned > \"%d\" AND ", max->numscanned);

		// add userid to query
		if(max->numup)
			snprintf(&max_part[bpstrlen(max_part)], 40, " numup > \"%d\" AND ", max->numup);

		// add runid to query
		if(max->runid)
			snprintf(&max_part[bpstrlen(max_part)], 40, " runid > \"%d\" AND ", max->runid);

		// add rec_id to query
		if(max->rec_id)
			snprintf(&max_part[bpstrlen(max_part)], 40, " rec_id > \"%d\" AND ", max->rec_id);

	}

	// ------------------- Like --------------------------------
	if(like)
	{
		// create string to hold the min part of the query
		like_part = (char *) bpcalloc(sizeof(BP_NMAPDB_RUNLIST)*3, 1);

		// add date (d) to query
		if(bpstrlen(like->d))
			snprintf(&like_part[bpstrlen(like_part)], sizeof(like->d)-1+40, " d like \"%%%s%%\" AND ", like->d);

		// add time (t) to query
		if(bpstrlen(like->t))
			snprintf(&like_part[bpstrlen(like_part)], sizeof(like->t)-1+40, " t like \"%%%s%%\" AND ", like->t);

		// add run_type to query
		if(like->run_type)
			snprintf(&like_part[bpstrlen(like_part)], 40, " run_type like \"%%%d%%\" AND ", like->run_type);

		// add user to query
		if(bpstrlen(like->user))
			snprintf(&like_part[bpstrlen(like_part)], sizeof(like->user)-1+40, " user like \"%%%s%%\" AND ", like->user);

		// add userid to query
		if(like->userid)
			snprintf(&like_part[bpstrlen(like_part)], 40, " userid like \"%%%d%%\" AND ", like->userid);

		// add host to query
		if(bpstrlen(like->host))
			snprintf(&like_part[bpstrlen(like_part)], sizeof(like->host)-1+40, " user like \"%%%s%%\" AND ", like->host);

		// add host_ip to query
		if(bpstrlen(like->host_ip))
			snprintf(&like_part[bpstrlen(like_part)], sizeof(like->user)-1+40, " host_ip like \"%%%s%%\" AND ", like->host_ip);

		// add numscanned to query
		if(like->numscanned)
			snprintf(&like_part[bpstrlen(like_part)], 40, " numscanned like \"%%%d%%\" AND ", like->numscanned);

		// add userid to query
		if(like->numup)
			snprintf(&like_part[bpstrlen(like_part)], 40, " numup like \"%%%d%%\" AND ", like->numup);

		// add runid to query
		if(like->runid)
			snprintf(&like_part[bpstrlen(like_part)], 40, " runid like \"%%%d%%\" AND ", like->runid);

		// add rec_id to query
		if(like->rec_id)
			snprintf(&like_part[bpstrlen(like_part)], 40, " rec_id like \"%%%d%%\" AND ", like->rec_id);

	}

	// ------------------- Equal --------------------------------
	if(equal)
	{

		// create string to hold the min part of the query
		equal_part = (char *) bpcalloc(sizeof(BP_NMAPDB_RUNLIST)*3, 1);

		// add date (d) to query
		if(bpstrlen(equal->d))
			snprintf(&equal_part[bpstrlen(equal_part)], sizeof(equal->d)-1+40, " d = \"%s\" AND ", equal->d);

		// add time (t) to query
		if(bpstrlen(equal->t))
			snprintf(&equal_part[bpstrlen(equal_part)], sizeof(equal->t)-1+40, " t = \"%s\" AND ", equal->t);

		// add run_type to query
		if(equal->run_type)
			snprintf(&equal_part[bpstrlen(equal_part)], 40, " run_type = \"%d\" AND ", equal->run_type);

		// add user to query
		if(bpstrlen(equal->user))
			snprintf(&equal_part[bpstrlen(equal_part)], sizeof(equal->user)-1+40, " user = \"%s\" AND ", equal->user);

		// add userid to query
		if(equal->userid)
			snprintf(&equal_part[bpstrlen(equal_part)], 40, " userid = \"%d\" AND ", equal->userid);

		// add host to query
		if(bpstrlen(equal->host))
			snprintf(&equal_part[bpstrlen(equal_part)], sizeof(equal->host)-1+40, " user = \"%s\" AND ", equal->host);

		// add host_ip to query
		if(bpstrlen(equal->host_ip))
			snprintf(&equal_part[bpstrlen(equal_part)], sizeof(equal->user)-1+40, " host_ip = \"%s\" AND ", equal->host_ip);

		// add numscanned to query
		if(equal->numscanned)
			snprintf(&equal_part[bpstrlen(equal_part)], 40, " numscanned = \"%d\" AND ", equal->numscanned);

		// add userid to query
		if(equal->numup)
			snprintf(&equal_part[bpstrlen(equal_part)], 40, " numup = \"%d\" AND ", equal->numup);

		// add runid to query
		if(equal->runid)
			snprintf(&equal_part[bpstrlen(equal_part)], 40, " runid = \"%d\" AND ", equal->runid);

		// add rec_id to query
		if(equal->rec_id)
			snprintf(&equal_part[bpstrlen(equal_part)], 40, " rec_id = \"%d\" AND ", equal->rec_id);

	}

	// ---------------- Run Query --------------------------------

	// query parts
	select_part = "select * from runlist ";

	// max length variable
	size_t max_len = bpstrlen(select_part);

	if(min_part)
		max_len += bpstrlen(min_part);

	if(max_part)
		max_len += bpstrlen(max_part);

	if(like_part)
		max_len += bpstrlen(like_part);

	if(equal_part)
		max_len += bpstrlen(equal_part);

	// allocate space for final query (2x max for paranoia)
	final_query = (char *) bpcalloc(max_len * 2, 1);

	// implement select path
	snprintf(&final_query[bpstrlen(final_query)], max_len * 2 -1, "%s", select_part);

	// add where if necessary
	if(min_part || max_part || like_part || equal_part)
		snprintf(&final_query[bpstrlen(final_query)], max_len * 2 -1, " WHERE ");

	if(min_part)
		snprintf(&final_query[bpstrlen(final_query)], max_len * 2 -1, "%s", min_part);

	if(max_part)
		snprintf(&final_query[bpstrlen(final_query)], max_len * 2 -1, "%s", max_part);

	if(like_part)
		snprintf(&final_query[bpstrlen(final_query)], max_len * 2 -1, "%s", like_part);

	if(equal_part)
		snprintf(&final_query[bpstrlen(final_query)], max_len * 2 -1, "%s", equal_part);

	// add terminating 1=1 to last AND if necessary
	if(min_part || max_part || like_part || equal_part)
		snprintf(&final_query[bpstrlen(final_query)], max_len * 2 -1, " 1=1 ");

	// -------------- Resolve Query in Database -------------------------------

	// MySQL Query Bindings
	// Use With null terminated strings only, results are accessed through struct MYSQL pointer
	if(BP_MySQLQuery(mysql_db, final_query))
		return NULL;

	// Returns stored results after a query, NULL on failure
	P_BP_MYSQL_RESULT result = BP_MySQLStoreResult(mysql_db);

	// Returns a result set from a query
	MYSQL_ROW row = (MYSQL_ROW) NULL;

	// array of ports
	BP_NMAPDB_RUNLIST * runlist_array = NULL;

	// size index
	size_t i = 0;
	size_t x = 0;

	// recover results from the database
	for(
			i = 0;
			row = BP_MySQLFetchRow(result);
			i++
	)
	{

		// set mysql row index to 0 on loop
		x=0;

		// allocate space for the array
		runlist_array = (BP_NMAPDB_RUNLIST *) bprealloc(runlist_array, sizeof(BP_NMAPDB_RUNLIST) * (i+1));

		// copy in date (d)
		strncpy( runlist_array[i].d, row[x], sizeof( runlist_array[i].d ) -1);
		x++;

		// copy in time (t)
		strncpy( runlist_array[i].t, row[x], sizeof( runlist_array[i].t ) -1);
		x++;

		// copy in run_type
		runlist_array[i].run_type = atoi(row[x]);
		x++;

		// copy in user
		strncpy( runlist_array[i].user, row[x], sizeof( runlist_array[i].user ) -1);
		x++;

		// copy in userid
		runlist_array[i].userid = atoi(row[x]);
		x++;

		// copy in host
		strncpy( runlist_array[i].host, row[x], sizeof( runlist_array[i].host ) -1);
		x++;

		// copy in host_ip
		strncpy( runlist_array[i].host_ip, row[x], sizeof( runlist_array[i].host_ip ) -1);
		x++;

		// copy in numscanned
		runlist_array[i].numscanned = atoi(row[x]);
		x++;

		// copy in numup
		runlist_array[i].numup = atoi(row[x]);
		x++;

		// copy in runid
		runlist_array[i].runid = atoi(row[x]);
		x++;

		// copy in rec_id
		runlist_array[i].rec_id = atoi(row[x]);
		x++;

		// -- loop to next record --

	}

	// ---------------- Create Returnable Structure -------------

	// if the portstats array structure is filled out, we have a proper result and can
	// populate return values.
	P_BP_NMAPDB_RESULTS final_data = NULL;
	if(runlist_array)
	{

		// opaque result data
		final_data = (P_BP_NMAPDB_RESULTS) bpcalloc(sizeof(BP_NMAPDB_RESULTS), 1);

		// save query
		final_data->query = bpstrndup(final_query, 4096);

		// save opaque data as porstats_array
		final_data->opaque_data = (void *) runlist_array;

		// set type to portstat
		final_data->type = BP_NMAPDB_RESULT_RUNLIST;

		// set record count to i + 1
		final_data->record_count = i+1;

	}
	// ---------------- Free Allocated Data ----------------------

	if(min_part)
		bpfree(min_part);

	if(max_part)
		bpfree(max_part);

	if(like_part)
		bpfree(like_part);

	if(equal_part)
		bpfree(equal_part);

	if(final_query)
		bpfree(final_query);

	// return the final filled out data structure
	return final_data;

}

// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// %%%%%%%%%%%% VISUALIZATION FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

// This function autodetects a result type and prints out the result.
int BP_NDBVisualizeResults(P_BP_NMAPDB_RESULTS result, size_t displayQuery)
{

	// make sure we have a result structure
	if(!result)
		return ERR_FAILURE;

	if(!result->opaque_data || !result->record_count)
		return ERR_FAILURE;

	size_t i = 0;

	// temporary pointers used for indexing through opaque result data
	BP_NMAPDB_RUNLIST   *tmp_runlist   = NULL;
	BP_NMAPDB_SCANNERS  *tmp_scanners  = NULL;
	BP_NMAPDB_TARGETS   *tmp_targets   = NULL;
	BP_NMAPDB_HOSTSTATS *tmp_hoststats = NULL;
	BP_NMAPDB_PORTSTATS *tmp_portstats = NULL;

	// switch to process data types
	switch(result->type)
	{
		case BP_NMAPDB_RESULT_RUNLIST:

			printf("\n [+] Runlist NmapDB Information: %u total records", result->record_count);

			// set opaque data as *structure
			tmp_runlist = (P_BP_NMAPDB_RUNLIST) result->opaque_data;

			// display individual data
			for(i = 0; i < result->record_count; i++)
				 BP_NDBVisualizeRunlist(&tmp_runlist[i]);

			break;

		case BP_NMAPDB_RESULT_SCANNERS:

			printf("\n [+] Scanners NmapDB Information: %u total records", result->record_count);

			// set opaque data as *structure
			tmp_scanners = (P_BP_NMAPDB_SCANNERS) result->opaque_data;

			// display individual data
			for(i = 0; i < result->record_count; i++)
				 BP_NDBVisualizeScanners(&tmp_scanners[i]);

			break;

		case BP_NMAPDB_RESULT_TARGETS:

			printf("\n [+] Targets NmapDB Information: %u total records", result->record_count);

			// set opaque data as *structure
			tmp_scanners = (P_BP_NMAPDB_SCANNERS) result->opaque_data;

			// display individual data
			for(i = 0; i < result->record_count; i++)
				 BP_NDBVisualizeTargets(&tmp_targets[i]);

			break;

		case BP_NMAPDB_RESULT_HOSTSTATS:

			printf("\n [+] Host Stats NmapDB Information: %u total records", result->record_count);

			// set opaque data as *structure
			tmp_hoststats = (P_BP_NMAPDB_HOSTSTATS) result->opaque_data;

			// display individual data
			for(i = 0; i < result->record_count; i++)
				 BP_NDBVisualizeHostStats(&tmp_hoststats[i]);

			break;

		case BP_NMAPDB_RESULT_PORTSTATS:

			printf("\n [+] Port Stats NmapDB Information: %u total records", result->record_count);

			// set opaque data as *structure
			tmp_portstats = (P_BP_NMAPDB_PORTSTATS) result->opaque_data;

			// display individual data
			for(i = 0; i < result->record_count; i++)
				BP_NDBVisualzePortStats(&tmp_portstats[i]);

			break;

		default:
			return ERR_FAILURE;
	}

	return ERR_SUCCESS;
}

// Visualizer for P_BP_NMAPDB_PORTSTATS structure
int BP_NDBVisualzePortStats(P_BP_NMAPDB_PORTSTATS data)
{
	if(!data)
		return ERR_FAILURE;

	printf("\n\tP_BP_NMAPDB_PORTSTATS: %p", data);
	printf("\n\t  ->d (date):     %s", data->d);
	printf("\n\t  ->t (time):     %s", data->t);
	printf("\n\t  ->hostid        %u", data->hostid);
	printf("\n\t  ->target_ip:    %s", data->target_ip);
	printf("\n\t  ->port:         %u", data->port);
	printf("\n\t  ->protocol:     %s", data->protocol);
	printf("\n\t  ->service:      %s", data->service);
	printf("\n\t  ->state:        %s", data->state);
	printf("\n\t  ->fullversion:  %s", data->fullversion);
	printf("\n\t  ->scannerid:    %u", data->scannerid);
	printf("\n\t  ->runid:        %u", data->runid);
	printf("\n\t  ->rec_id:       %u", data->rec_id);
	printf("\n");

	return ERR_SUCCESS;
}

// Visualizer for P_BP_NMAPDB_HOSTSTATS structure
int BP_NDBVisualizeHostStats(P_BP_NMAPDB_HOSTSTATS data)
{
	if(!data)
		return ERR_FAILURE;

	printf("\n\tP_BP_NMAPDB_HOSTSTATS: %p", data);
	printf("\n\t  ->hostid         %u", data->hostid);
	printf("\n\t  ->ip:            %s", data->ip);
	printf("\n\t  ->user:          %s", data->user);
	printf("\n\t  ->userid:        %u", data->userid);
	printf("\n\t  ->d (date):      %s", data->d);
	printf("\n\t  ->t (time):      %s", data->t);
	printf("\n\t  ->open_ports:    %u", data->open_ports);
	printf("\n\t  ->ports_scanned: %u", data->ports_scanned);
	printf("\n\t  ->runid:         %u", data->runid);
	printf("\n\t  ->scanner_id:    %u", data->scanner_id);
	printf("\n\t  ->rec_id:        %u", data->rec_id);
	printf("\n");

	return ERR_SUCCESS;
}

// Visualizer for P_NMAPDB_TARGETS structure
int BP_NDBVisualizeTargets(P_NMAPDB_TARGETS data)
{

	if(!data)
		return ERR_FAILURE;

	printf("\n\tP_BP_NMAPDB_TARGETS: %p", data);
	printf("\n\t  ->host:        %s", data->host);
	printf("\n\t  ->d (date):    %s", data->d);
	printf("\n\t  ->t (time):    %s", data->t);
	printf("\n\t  ->ip :         %s", data->ip);
	printf("\n\t  ->ipnum:       %u", data->ipnum);
	printf("\n\t  ->mac:         %s", data->mac);
	printf("\n\t  ->macvendor:   %s", data->macvendor);
	printf("\n\t  ->flag:        %u", data->flag);
	printf("\n\t  ->hostid:      %u", data->hostid);
	printf("\n\t  ->description: %s", data->description);
	printf("\n\t  ->os_guessed:  %s", data->os_guessed);
	printf("\n\t  ->os_known:    %s", data->os_known);
	printf("\n\t  ->fingerprint: %s", data->fingerprint);
	printf("\n\t  ->rec_id:      %u", data->rec_id);
	printf("\n");

	return ERR_SUCCESS;

}

// Visualizer for P_BP_NMAPDB_SCANNERS structure
int BP_NDBVisualizeScanners(P_BP_NMAPDB_SCANNERS data)
{

	if(!data)
		return ERR_FAILURE;

	printf("\n\tP_BP_NMAPDB_SCANNERS: %p", data);
	printf("\n\t  ->scanner:     %s", data->scanner);
	printf("\n\t  ->scanner_ip:  %s", data->scanner);
	printf("\n\t  ->description: %s", data->description);
	printf("\n\t  ->d (date):    %s", data->d);
	printf("\n\t  ->t (time):    %s", data->t);
	printf("\n\t  ->flag:        %u", data->flag);
	printf("\n\t  ->scanner_id:  %u", data->scanner_id);
	printf("\n\t  ->rec_id:      %u", data->rec_id);
	printf("\n");

	return ERR_SUCCESS;

}

// Visualizer for P_BP_NMAPDB_RUNLIST structure
int BP_NDBVisualizeRunlist(P_BP_NMAPDB_RUNLIST data)
{

	if(!data)
		return ERR_FAILURE;

	printf("\n\tP_BP_NMAPDB_RUNLIST: %p", data);
	printf("\n\t  ->d (date):   %s", data->d);
	printf("\n\t  ->t (time):   %s", data->t);
	printf("\n\t  ->run_type:   %u", data->run_type);
	printf("\n\t  ->user:       %s", data->user);
	printf("\n\t  ->userid:     %u", data->userid);
	printf("\n\t  ->host:       %s", data->host);
	printf("\n\t  ->host_ip:    %s", data->host_ip);
	printf("\n\t  ->numscanned: %u", data->numscanned);
	printf("\n\t  ->numup:      %u", data->numup);
	printf("\n\t  ->runid:      %u", data->runid);
	printf("\n\t  ->rec_id:     %u", data->rec_id);
	printf("\n");

	return ERR_SUCCESS;

}


text:
Breesing Through Camp
Quarterback gives training camp update
New Orleans Saints QB Drew Brees met with the media following Wednesday morning's practice. During the time, he discussed topics such as his backups, going against a Gregg Williams defense as well as the competitiveness at these workouts, below is a transcript.
How much time do you have to tutor the guys who are trying to be your backups? How much advice do you give them?
"I try to help those guys out as much as I can. Patrick Ramsey has been here for a week. Trying to learn this offense and trying to come in to this system on this stage is very difficult, especially with all of the looks that we see defensively. It's not only learning your offense, and all of the personnel, but also how you are going to attack the defense that you are going up against. That makes it very difficult for him, and also for the young guys that we have coming in. The guys fresh out of college, like Sean Canfield and guys like Chase Daniel who just started the season last year. They haven't gone through a training camp with us either. You have three guys who have their first training camp here. It's definitely an adjustment and a learning experience for them. For me, I enjoy being able to talk about the offense, the system, the personnel, and my thought process on a lot of things. It kind of re-emphasizes to me the important things and the step-by-step process that allows us to be successful as an offense. For me as a quarterback, to review just that mindset that I am taking on every play, my checklist, I think it is beneficial for both sides."
What do you make of all of the Brett Favre talk again?
"I am sure there is going to be a lot of speculation. Haven't we all seen it before? I'm not going to believe it until he doesn't walk out of the tunnel on September 9th."
How have people looked to you in the past as a symbol for the city? How has the oil spill affected the optimism after the win?
"Here we are, almost five years post (Hurricane) Katrina and a lot of us were brought in six months post-Katrina. The last four seasons, I feel like there has been a very special bond formed between our fans, our city, the Gulf Coast, and the Saints. I feel like this organization claims not only this area, but Mississippi, Alabama, and the Florida Panhandle. When you look at what's happened now with the oil spill, how it's really affected the entire region, we take that as a big responsibility on ourselves to be a part of that process, that renewing process the clean-up process of the coastal wetlands, and whatever we can do to bring people hope, to reach out and put a smile on their face in some difficult times."
What are you going to do this season to do that?
"Win football games, number one. Obviously there are guys that do things in the community whether it's through their foundations or just lending a helping hand. There are plenty of things that we will be doing."
After the success last year, how does facing Gregg Williams and this defense help you every day?
"You figure you are seeing every different defensive look that you can see. By the time games roll around, you feel like there is nothing you can see that you haven't from our defense. Our defense plays it so well, and they do such a good job of taking the football away, so there is a constant emphasis on taking care of the football. They are talking about taking it away, so that helps us. Plus, it's just competitive. Everybody is fighting for jobs out here, fighting for a key role on this team and that's what excites us all. The guys that are going to be out there on Sunday are the guys that earned positions."
*How about going against him? He is pretty animated out there. Do you appreciate his competitiveness? *
"Absolutely. Everybody has personality. Each guy is different. Just like Sean has his mannerisms, the things does he does, Gregg Williams has some. Joe Vitt has his. Pete Carmichael, our offensive coordinator, has his. You've got to keep it light and try to have fun out here as much as possible through the sweat, the soreness, and the grind. You understand, these are the times where you really come together as a team. This is critical. As hard as this is, it's a critical component to your success later on."
What are your thoughts on the competition between Alex Brown and Jimmy Wilkerson?
"I think this guy (Brown) has been a great addition to our team. He fits in well with his character and leadership qualities. He's a pretty good football player too, so we are happy to have him. He knows that he is going to have to earn everything he is going to get out there. It's very competitive, but we like it that way because it brings out the best in everyone."
You said that you wanted the same level of competitiveness that you saw last year…
"Absolutely, that's the way that you get better."
Have you seen that?
"Yes. It's the only way that you get better; it's how you get the best out of people. Put them in tough situations every day, and make it so they're used to that. Put guys in positions where being comfortable makes them comfortable. In other words, if you are always competing and are always put in tough situations, you always have to fight through, and then the games almost seem easy because you have so much invested and you know how hard you have worked. It just prepares you."
Can you talk about having (Marques) Colston back?
"It's awesome. That's the big man. He's a big part of what we do offensively and I'm glad to have him back. Plus, we have a group of young receivers that have been running, so to have him out there now as a complement to Lance Moore, Devery (Henderson), and as soon as (Robert) Meachem gets back, I'm happy to have our core group back together."
With heavy focus on the special teams, how much easier does having good punt returners out there make your job?
"It's big whenever you have guys that can give you extra field position, an extra ten yards, someone who can get the ball to the 40, 50, or in to the opponent's territory. When you have that starting point as an offense, not only does it give you a shorter field, but the momentum shift, the emotional lift, when you are on the sideline and a guy gets a big return, there is an extra spring in your step. Now you just think, 'We're going to score points no matter what.' It's big when you have those guys. Also, kick return. I feel like Courtney Roby is one of the best in the league. I feel like he did a great job last year. Pierre Thomas, when he had to step in and do it, he was the one that returned the ball out to the 40 in the NFC Championship game. That's critical when you have guys that can do that."
Additional New Orleans Saints players removed from Covid-19 list for Week 17 vs. Carolina Panthers
Center Erik McCoy added to the Covid-19 list
Taysom Hill, Demario Davis among group of New Orleans Saints players removed from Covid-19 list
Safety Marcus Williams added to the Covid-19 list
New Orleans Saints make roster moves ahead of Monday's game vs. Miami | 2021 NFL Week 16
Linebacker Kwon Alexander placed on Covid-19 reserve list
New Orleans Saints defensive end Cameron Jordan named NFC Defensive Player of the Week
Jordan had two sacks, forced fumble as Saints shut out Buccaneers
New Orleans Saints Terron Armstead continues to hold top Pro Bowl voting spot among NFC tackles
Armstead has tallied 82,555 fan votes
Cameron Jordan named New Orleans Saints nominee for Art Rooney Sportsmanship Award
Jordan was nominated by the New Orleans Saints for exhibiting stellar sportsmanship
Cameron Jordan named New Orleans Saints Man of the Year for second time
Standout defensive end team nominee for 2021 NFL Walter Payton Man of the Year Award
New Orleans Saints veteran Terron Armstead remains atop Pro Bowl voting among tackles

redpajama_set_name: RedPajamaCommonCrawl


This Primary Art online resource shows how to create 3 themed murals. Targeted at 9 – 11 year olds, many of the activities could be used with younger and slightly older children.
Tux Paint is a free, award-winning drawing program for children ages 3 to 12 (for example, key stages 1 and 2). It combines an easy-to-use interface, fun sound effects, and an encouraging cartoon mascot who guides children as they use the program.


text:
THERAPIST SHARES The 4 Step Process For CURING LONELINESS & Finding HAPPINESS| Kati Morton & Lewis H
August 7, 2020 Matthew Brewin
Kati Morton is a clinical psychologist, a licensed marriage and family therapist, and a viral YouTube personality whose mission is to decrease the stigma around mental health issues. Kati runs a private practice in Santa Monica, CA, and over the past eight years, Kati has leveraged social media to share mental health information worldwide through video.
Kati is well known for her YouTube channel which now has over 948 thousand subscribers, over 74.5 million views! In addition to her YouTube channel and strong presence on social media, she has made several TV appearances and appeared in Europe's highest circulated magazine, Glamour UK.
Kati's first book, Are u ok?: A Guide to Caring for Your Mental Health, is a mental health guide for millennials. She's also the host of the new podcast Ask Kati Anything where she answers all of your questions about anxiety, depression, insecurity, self-doubt, and more. Her passion is to increase awareness about mental health, and she hopes by doing this, the global community can push for better services worldwide and remove the stigma associated with getting help.
It was such a joy talking with Kati, and we cover so much wisdom in this important interview. Please share this episode with someone who needs to hear it! And remember: You don't have to sit in loneliness, depression, and anxiety all by yourself. There is nothing braver than asking for help.
Join me on Episode 989 to learn how to defeat loneliness and learn to love yourself with Kati Morton!
← Tea with GaryVee 054 – Friday 9:00am ET | 8-7-2020
How to Use INSTAGRAM to 10x Your BUSINESS! | #InstagramLive →
THIS Is The Easiest Way To Make Money With Affiliate Marketing
Grant Cardone's Biggest Secret
How To CURE DISEASE & BOOST Your IMMUNE SYSTEM (Stay Healthy Until 105 By Doing This)| Dr.Gundry
May 30, 2020 Matthew Brewin


Some think it's hard to lower car insurance rates. More times than likely, if you have a car, your car insurance is a big part of your budget. With families who have more than one driver in the house, the price goes up more. Even more so for those with bad credit or an imperfect driving record.
Car insurance premiums too high? According to Consumer Reports, there are ways to obtain lower car insurance rates and receive the coverage you need.
The first way is to pick an insurer with a top rating.
Tobie Stranger, Money Editor at Consumer Reports, says not to be short-sighted. He says it's not always about getting the lowest premium on your insurance. You want to be sure that the company you go through will pay your claim as soon as possible. Also, that you receive proper service from said company.
Afterwards, make sure that you have the right deductible. Though a higher deductible makes for less money on your premium per month, you will have to pay more money when you have a claim in place.
Stranger says that if you go this route, be sure to have enough money to pay your deductible in case of an accident.
There are ways to lower your rates if you are a driver with low-risk behaviors. Asking for discounts can help to lower your payments. There are discounts for those who use their car for short commutes. Also, teen drivers who are taking drivers training courses.
If your credit score is good, it can help save you some money on your insurance.
Bundling your policies can be very beneficial. Getting your home and auto insurance from the same company can mean for a big discount.
Some people think that if they stay with the same insurance company, that over time they will receive some benefit from being loyal. Those at Consumer Reports say that shopping can help to save a lot of money. For more information, visit ConsumerReports.org.


Michelle Keegan, Lydia Bright and Amy Willerton are all fans and now the celeb-loved brand Fashion Union is seeking to reach out to the few who are unaware of their expanding empire.
The affordable fast-fashion brand has launched its very first campaign video to be aired on UK TV debuting today.
It will showcase the label's AW14 collection as modelled by Billie Brown and Lottie Richman whose faces will soon be recognisable across the country.
Designed in-house Fashion Union's latest range will offer a variety of pastel cocoon coats, metallic skirts, folktale dresses and statement satchels.
The new collection is said to be defined by Fashion Union's continued support for homegrown talent with much of the collection being designed in Manchester by the brand's growing creative design team.
The TV campaign comes as part of the label's expansion plans for 2014 and 2015.
In the behind the scenes video managing director of Fashion Union Pawan Khosla says that he hopes that the brand can offer something unique to the industry.
Director of the campaign video, Simon Mulvaney says that the brand offers style for the fashion conscious on a budget.
Fashion Union is offering MailOnline readers an exclusive discount when they shop online.
Simply enter MAIL25 at the checkout to receive 25 per cent off your order.
The code is valid from September 10-24. Usual terms and conditions apply. Not for use on sale items or with any other code or discount.
Despite it's affordable price tag the brand is fast becoming a go-to fashion for many celebrities.
Boasting fans from Michelle Keegan and Rosie Fortescue to Laura Whitmore, Zoe Hardman, Lydia Bright, Diana Vickers, Chloe Sims and Tamera Foster, Fashion Union has established itself among the celebrity circle.


Elysian Records mainstays Lazy Boyz have been regulars on Your EDM in the past, pushing out a number of quality trap tunes in the year and a half they have been active. However, the group recently made an announcement, stating that they were done and all three members were leaving in order to focus on their solo careers. But, like a phoenix rising from the ashes, this break-up has luckily spawned a brand new project from one of the members that is sure to make some serious waves in the bass music community.
Departures is the start of a new musical journey for former Lazy Boyz founder Aaron Michaels that will focus on emotion-laden tunes that still hit and sound hard. This isn't an easy feat to accomplish and should be seen as a testament to Aaron's prowess in the studio. Your EDM has the pleasure of premiering Departures's debut track, appropriately titled "Back Here Again." Out via MMXC, it features a massive dubstep-influenced sound that will surely please fans of Lazy Boyz, and bass music in general.
The track kicks off with a few dark piano chords, working to set the mood before some male vocals take over. Pushing the track forward is a simple yet extremely effective 'plucking' synth that can be heard in the background, which brings a surprising amount of energy while working as an extended build-up. Departures holds nothing back, combining a hefty sub with what sound like metal-esque guitar riffs, which together to create an extremely heavy atmosphere. Layers of wonky horns also appear at the drop, introducing some brighter sounds to the mix that add a bit of variation and vigor to the song while still retaining the dark feel "Back Here Again" manages to curate.
While we're sad to see Lazy Boyz go, the future seems bright for Departures. He is surely an artist to keep an eye on as we can only expect things bigger and better things from here on out; this is undoubtedly going to be an impressive project. Stream the track below and click HERE to download "Back Here Again" for free!


text:
Q: Using If...Else vs If() Does cleanliness trump performance here:
Version 1:
Function MyFunc(ByVal param as String) As String
    Dim returnValue as String
    If param Is Nothing Then
        returnValue = "foo"
    Else
        returnValue = param
    return returnValue

Version 2:
Function MyFunc(ByVal param as String) As String
    return If(param,"foo")

Version 1 deals directly with unboxed Strings.  Version 2 deals with all boxed Objects. [If() takes a TestExpression as Object, a FalsePart as Object and returns an Object]
[can't add comments]
COMMENT:  ja72, fixed my naming.
COMMENT:  Marc, so you would go with Version 2?

A: I think clarity trumps anything.
The If(obj1,obj2) function is the null coalescing operator of VB.NET. It functions the same as obj1 ?? obj2 in C#. As such, everyone should know what it means, and it should be used where conciseness is important.
Although the If/Else statement is clean, simple, and obvious, in this particular case, I would favor the If function.

A: The compiler would optimize these two to the same code or nearly the same depending on the optimization level (See project properties).
Write two methods this way, compile them and use Reflector to look into the VB.Net decompiled code (or even MSIL) and you will see that there is very little (some billionth of a second) or none difference in exectuion.
Compiler optimizations generally handle normal patterns that allows you to write if-statements and loops in different ways. For instance in .Net for, foreach, while, do, etc do not actually exist. They are language specific features that are compiled down to goto-statement logic in the assembly level. Use Reflector to look at a few of these and you'll learn a lot! :)
Note that it is possible to write bad code that the compiler can't optimize to its "best state", and it is even possible to do better than the compiler. Understanding .Net assembly and MSIL means understanding the compiler better.

A: Really? I don't think this function is going to be a bottleneck in any application, and so just go with brevity/clarity.
I would recommend:
Public Function TXV(ByVal param As String) As String
    Return If(param Is Nothing, "foo", param)
End Function

and make sure the function returns a string (to keep type safety). BTW, why is your Function called MySub ? Shouldn't it be MyFunc ?

A: I believe that these two implementations are nearly the same, I would use the second one because it's shorter.

A: Since I come from a C background, I would opt for the ternary operator most times where it is clear what is happening - in a case like this where there is repetition and it can be idiomatic.  Similarly in T-SQL where you can use COALESCE(a, b, c, d, e) to avoid having a bunch of conditionals and simply take the first non-null value - this is idiomatic and easily read.
Beware that the old IIf function is different from the new If operator, so while the new one properly handles side-effects and short-circuits, it's only one character away from a completely different behavior which people have long been wary of.
http://secretgeek.net/iif_function.asp
http://visualbasic.about.com/od/usingvbnet/a/ifop.htm
I don't think it's going to matter in terms of performance, because the optimizer is pretty good about these kind of transforms.

redpajama_set_name: RedPajamaStackExchange


Evergreen has added around 6,000 TEU in extra capacity to its China to Europe service that it operates as part of the Ocean Alliance. Credit: facebook.com/evergreenmarinecorp.
Taiwanese container ship operator Evergreen has added its second and third ultra-large container ships to its fleet with the delivery of the Ever Gifted and Ever Grade from the Japanese shipyard at Imabari.
The two sister ships will join the Ever Golden in the China-Europe-Mediterranean (CEM) trades operated by the Ocean Alliance. All three vessels have a nominal capacity of 20,150 twenty-foot equivalent units (TEU). The 400-meter-long ships have power-points for 1,300 reefer containers and will offer significant economies of scale to the line.
The ships will operate as part of the CEM service out of North China, via Shanghai, Colombo and the Suez Canal to the Mediterranean, Felixstowe, Rotterdam and Hamburg.
The new ships are part of an 11-vessel order of similar ships contracted by Evergreen from Japan's Imabari yard in 2015, with the remaining ships expected to be delivered over the course of this year.
Evergreen is a member of the 323-vessel Ocean Alliance, which was formed in the spring of 2017. The alliance includes French line CMA CGM, COSCO Container Lines, and Orient and Overseas Container Lines.
Singapore-based Synergy Group will manage the new vessels. Synergy manages over 200 ships in its fleet, which range from container ships to very large ethane carriers.


text:
Open Form
Humanity Mag
#MODELCITIZEN
Text by CATHERINE WAGLEY Portrait by STEFAN KOCEV	Film	Most Read Film
The film Machete was a joke from the start. It began as a trailer with no movie to go with it, made as part of Quentin Tarantino and Robert Rodriguez's double-feature Grindhouse, a movie about bad movies. Then, when Rodriguez decided to make his farce into a real film, a comedy about border issues centered on a Mexican-American super killer, he chose as his star a guy who'd stumbled into movies accidentally.
Danny Trejo, a born-and-raised Angeleno with long dark hair, a gravelly voice and a distinctive weathered face, would be "Machete." And he would be quite good at it: He'd take low-riders on spins, use knives to fight off gun-toting villains and get the girl despite the odds. At 66, he would go from supporting actor to leading man.
"My mom was calling me Machete before she passed," remembers Trejo. He's sitting in his backyard in the San Fernando Valley, a few yards away from his prized avocado tree. He's wearing boots and black pants, but he's just taken off his shirt for a photo shoot—the photographer wanted to see the tattoo on his chest, of a woman wearing a sombrero. Nearby, there's an oblong swimming pool with a machete tiled into the bottom of it. He laughs about that.
"I was in France," he says. "Max, my assistant, he put that big machete down there." It was meant to be funny. The oversized machete-shaped decorations on top of his garage are meant to be funny too. "I love it," Trejo says of the machete joke. Three of his five dogs gallivant around the yard, and the smallest jumps up to rest his paws on Trejo's lap. "That's John Wesley Harding," he says of the dog. "The meanest cowboy in all the world."
Trejo, who refers to himself as a drug counselor rather than an actor, was born in 1944 and grew up on Temple and Figueroa, near downtown L.A. He had a rough youth. He developed a drug habit early and participated in a string of armed robberies, going in and out of prison several times before landing in San Quentin on drug charges. While there, he fell in with a group of men in on murder charges. For a price, they would protect newcomers from the inevitable dangers of prison life. "Prison is the only place in the world where there's only two types of people: There's predator and there's prey," says Trejo. He learned to be a predator with a business plan.
In 1968, he and two friends were involved in a prison riot. A sergeant was hurt, as was a civilian. While in solitary confinement, sure he would receive a death sentence, Trejo prayed. "God, if you let me die with dignity," he remembers saying, "I'll say your name every day and do whatever I can for my fellow man." But charges were never pressed. "One thousand guys on the yard and they couldn't get a single witness," Trejo chuckles. "I thought it would be a couple of years before I'd be dead. It's been 46 years now."
He was released in 1969 and started working as a drug and alcohol counselor a few years later. In the mid-1980s, he went to visit the set of Runaway Train to check up on a kid he was counseling who was working as a PA on that set. While there, he ran into an old prison friend turned screenwriter, Eddie Bunker, and before he knew it, he had a small role in the film.
"And I just kept getting job after job. I found that if you're pleasant, people tend to gravitate toward you," he explains. "The first five years of my career, I was just 'Inmate Number 1,' 'Bad Guy 5,' 'Tattooed Guy.' I didn't know what typecasting even was."
He remembers being on a particular set and having a director pull him aside. " 'Danny,' the director said, 'I want you to hold this shotgun and kick in this door. It's a robbery. You're going to rob a poker game.' " Trejo kicked in the door, taking out a stuntwoman and a "big hillbilly" before the director yelled, "Cut."
"My god, Danny, where did you study?" the director asked.
"Vons, Safeway," Trejo answered. It had all come back to him immediately, the adrenaline rush and the performance of being the robber in real life.
By the mid-1990s, Trejo began to receive speaking parts. He appeared as Navajas in Desperado and a thug called Razor Charlie in From Dusk Till Dawn. Still, even after his movie career started taking off, he says he had no aspirations as an actor.
"I still work for Western Pacific Med Corp. That's my real job. I still work with addicts and alcoholics," he says. "Let me tell you what that did for me," he continues, referring to his acting breakthroughs. "My passion is talking to young kids in trouble. Well, the trouble with talking with kids is that first you have to get their attention, which is impossible because they have none. And then you have to keep their attention, which is impossible because of number one: They have none." Now, he goes to schools and kids listen. "Not Danny Trejo, that's not who they're listening to, but the guy from Spy Kids, the guy from Desperado, the guy from any movie they've seen."
All the assistants who live in his house, who have been coming out to feed the dogs and who take care of business when Trejo's traveling, are former addicts he's counseled. Today, his 27-year-old son Gilbert is in town and the two are driving down into Hollywood to take a meeting at the American Film Institute about a script Gilbert wrote, a strange spin on Michelangelo Antonioni's Blow-Up and Brian De Palma's Blow Out. Trejo's most recent project was a PSA for the Friends of Animals, for which he wore a full-body dog suit and played "T-Bone." He'll sign autographs in Canada later this week.
"I'm blessed," says Trejo, recalling something Eddie Bunker told him: "The whole world can think you're a movie star, but you can't."
VISIT CITIZENSOFHUMANITY.COM
A Special Recipe by Travis Lett
The chef behind wildly popular restaurant Gjelina shares a favorite recipe.
Sales & Press Contact
Humanity Stockist
My Preference
HUMANITY by Citizens of Humanity
© 2019 Citizen of Humanity. All rights reserved.