Example #1
0
void
pool_user_destroy(TDS_POOL * pool)
{
	while (dlist_user_first(&pool->users))
		pool_free_user(pool, dlist_user_first(&pool->users));
	while (dlist_user_first(&pool->waiters))
		pool_free_user(pool, dlist_user_first(&pool->waiters));

	tds_free_context(pool->ctx);
	pool->ctx = NULL;
}
Example #2
0
/* Note that this always suceeds */
int
try_tds_logout(TDSLOGIN * login, TDSSOCKET * tds, int verbose)
{
	if (verbose) {
		fprintf(stdout, "Entered tds_try_logout()\n");
	}
	tds_free_socket(tds);
	tds_free_login(login);
	tds_free_context(test_context);
	test_context = NULL;
	return TDS_SUCCEED;
}
Example #3
0
CS_RETCODE
cs_ctx_drop(CS_CONTEXT * ctx)
{
	tdsdump_log(TDS_DBG_FUNC, "cs_ctx_drop(%p)\n", ctx);

	if (ctx) {
		_ct_diag_clearmsg(ctx, CS_ALLMSG_TYPE);
		free(ctx->userdata);
		if (ctx->tds_ctx)
			tds_free_context(ctx->tds_ctx);
		free(ctx);
	}
	return CS_SUCCEED;
}
Example #4
0
	void CloseDB()
	{
		if (sock)
		{
			tds_free_socket(sock);
			sock = NULL;
		}
		if (context)
		{
			tds_free_context(context);
			context = NULL;
		}
		if (login)
		{
			tds_free_login(login);
			login = NULL;
		}
	}
Example #5
0
static int mssql_disconnect(void)
{
	if (tds) {
		tds_free_socket(tds);
		tds = NULL;
	}

	if (context) {
		tds_free_context(context);
		context = NULL;
	}

	if (login) {
		tds_free_login(login);
		login = NULL;
	}

	connected = 0;

	return 0;
}
Example #6
0
// close database  
bool TdsDatabaseLayer::Close()
{
  //puts("Resetting error codes");
  ResetErrorCodes();

  //puts("Closing result sets");
  CloseResultSets();
  //puts("Closing statements");
  CloseStatements();

  if (m_pDatabase != NULL)
  {
    //puts("Freeing socket");
	  tds_free_socket(m_pDatabase);
    m_pDatabase = NULL;
  }
  if (m_pLogin != NULL)
  {
    //puts("Freeing login");
  	tds_free_login(m_pLogin);
    m_pLogin = NULL;
  }
  if (m_pContext != NULL)
  {
    // Remove the context (and this databaselayer) from the lookup map
    //  used by the error handler
    //puts("Removing TDS layer from hash");
    TdsDatabaseLayer::RemoveTdsLayer(m_pContext);

    // Free the context
    //puts("Freeing context");
	  tds_free_context(m_pContext);
  	m_pContext = NULL;
  }

  return true;
}
Example #7
0
int
main(int argc, char **argv)
{
	/* the conversion pair matrix */
	typedef struct
	{
		int srctype;
		int desttype;
		int yn;
	}
	ANSWER;
	const static ANSWER answers[] = {
#	include "tds_willconvert.h"
	};

	/* some default inputs */
	static const int bit_input = 1;

	/* timing variables to compute performance */
	struct timeval start, end;
	double starttime, endtime;

	int i, j, iterations = 0, result;

	TDS_CHAR *src = NULL;
	TDS_UINT srclen;
	CONV_RESULT cr;

	TDS_NUMERIC numeric;
	TDS_MONEY money;
	TDS_MONEY4 money4;
	TDS_DATETIME datetime;
	TDS_DATETIME4 datetime4;

	TDS_TINYINT tds_tinyint;
	TDS_SMALLINT tds_smallint;
	TDS_INT tds_int;
	TDS_INT8 tds_int8;

	TDS_REAL tds_real;
	TDS_FLOAT tds_float;

	if (argc > 1) {
		iterations = atoi(argv[1]);
		printf("Computing %d iterations\n", iterations);
	}

	ctx = tds_alloc_context(NULL);
	assert(ctx);
	if (ctx->locale && !ctx->locale->date_fmt) {
		/* set default in case there's no locale file */
		ctx->locale->date_fmt = tds_strdup(STD_DATETIME_FMT);
	}


	/*
	 * Test every possible conversion pair
	 */
	for (i = 0; i < sizeof(answers) / sizeof(ANSWER); i++) {
		if (!answers[i].yn)
			continue;	/* don't attempt nonconvertible types */

		if (answers[i].srctype == answers[i].desttype)
			continue;	/* don't attempt same types */

		cr.n.precision = 8;
		cr.n.scale = 2;

		switch (answers[i].srctype) {
		case SYBCHAR:
		case SYBVARCHAR:
		case SYBTEXT:
		case SYBBINARY:
		case SYBVARBINARY:
		case SYBIMAGE:
			switch (answers[i].desttype) {
			case SYBCHAR:
			case SYBVARCHAR:
			case SYBTEXT:
			case SYBDATETIME:
			case SYBDATETIME4:
				src = "Jan  1, 1999";
				break;
			case SYBBINARY:
			case SYBIMAGE:
				src = "0xbeef";
				break;
			case SYBINT1:
			case SYBINT2:
			case SYBINT4:
			case SYBINT8:
				src = "255";
				break;
			case SYBFLT8:
			case SYBREAL:
			case SYBNUMERIC:
			case SYBDECIMAL:
			case SYBMONEY:
			case SYBMONEY4:
				src = "1999.25";
				cr.n.precision = 8;
				cr.n.scale = 2;
				break;
			case SYBBIT:
			default:
				src = "1";
				break;
			}
			assert(src);
			srclen = strlen(src);
			break;
		case SYBINT1:
			src = (char *) &tds_tinyint;
			srclen = sizeof(tds_tinyint);
			break;
		case SYBINT2:
			src = (char *) &tds_smallint;
			srclen = sizeof(tds_smallint);
			break;
		case SYBINT4:
			src = (char *) &tds_int;
			srclen = sizeof(tds_int);
			break;
		case SYBINT8:
			src = (char *) &tds_int8;
			srclen = sizeof(tds_int8);
			break;
		case SYBFLT8:
			tds_float = 3.14159;
			src = (char *) &tds_float;
			srclen = sizeof(tds_float);
			break;
		case SYBREAL:
			tds_real = 3.14159;
			src = (char *) &tds_real;
			srclen = sizeof(tds_real);
			break;
		case SYBNUMERIC:
		case SYBDECIMAL:
			src = (char *) &numeric;
			srclen = sizeof(numeric);
			break;
		case SYBMONEY:
			src = (char *) &money;
			srclen = sizeof(money);
			break;
		case SYBMONEY4:
			src = (char *) &money4;
			srclen = sizeof(money4);
			break;
		case SYBBIT:
			src = (char *) &bit_input;
			srclen = sizeof(bit_input);
			break;
		case SYBDATETIME:
			src = (char *) &datetime;
			srclen = sizeof(datetime);
			break;
		case SYBDATETIME4:
			src = (char *) &datetime4;
			srclen = sizeof(datetime4);
			break;
		/*****  not defined yet
			case SYBBOUNDARY:
			case SYBSENSITIVITY:
				fprintf (stderr, "type %d not supported\n", answers[i].srctype );
				continue;
				break;
		*****/
		default:
			fprintf(stderr, "no such type %d\n", answers[i].srctype);
			return -1;
		}

		/* 
		 * Now at last do the conversion
		 */

		result = tds_convert(ctx, answers[i].srctype, src, srclen, answers[i].desttype, &cr);
		free_convert(answers[i].desttype, &cr);

		if (result < 0) {
			if (result == TDS_CONVERT_NOAVAIL)	/* tds_willconvert returned true, but it lied. */
				fprintf(stderr, "Conversion not yet implemented:\n\t");

			fprintf(stderr, "failed (%d) to convert %d (%s, %d bytes) : %d (%s).\n",
				result,
				answers[i].srctype, tds_prtype(answers[i].srctype), srclen,
				answers[i].desttype, tds_prtype(answers[i].desttype));

			if (result != TDS_CONVERT_NOAVAIL)
				return result;
		}

		printf("converted %d (%s, %d bytes) : %d (%s, %d bytes).\n",
		       answers[i].srctype, tds_prtype(answers[i].srctype), srclen,
		       answers[i].desttype, tds_prtype(answers[i].desttype), result);

		/* 
		 * In the first iteration, start with varchar -> others.  
		 * By saving the output, we initialize subsequent inputs.
		 */

		switch (answers[i].desttype) {
		case SYBNUMERIC:
		case SYBDECIMAL:
			numeric = cr.n;
			break;
		case SYBMONEY:
			money = cr.m;
			break;
		case SYBMONEY4:
			money4 = cr.m4;
			break;
		case SYBDATETIME:
			datetime = cr.dt;
			break;
		case SYBDATETIME4:
			datetime4 = cr.dt4;
			break;
		case SYBINT1:
			tds_tinyint = cr.ti;
			break;
		case SYBINT2:
			tds_smallint = cr.si;
			break;
		case SYBINT4:
			tds_int = cr.i;
			break;
		case SYBINT8:
			tds_int8 = cr.bi;
			break;
		default:
			break;
		}

		/*
		 * If an iteration count was passed on the command line (not by "make check")
		 * run the conversion N times and print the conversions per second.
		 */
		result = gettimeofday(&start, NULL);
		starttime = (double) start.tv_sec + (double) start.tv_usec * 0.000001;

		for (j = 0; result >= 0 && j < iterations; j++) {
			result = tds_convert(ctx, answers[i].srctype, src, srclen, answers[i].desttype, &cr);
			free_convert(answers[i].desttype, &cr);
		}
		if (result < 0)
			continue;

		result = gettimeofday(&end, NULL);
		endtime = (double) end.tv_sec + (double) end.tv_usec * 0.000001;

		if (endtime != starttime) {
			printf("%9.0f iterations/second converting %13s => %s.\n",
				j / (endtime - starttime), tds_prtype(answers[i].srctype), tds_prtype(answers[i].desttype));
		}

	}
	tds_free_context(ctx);

	return g_result;
}
Example #8
0
// Connect to the server
bool TdsDatabaseLayer::Connect()
{
	m_pLogin = tds_alloc_login();
	if (m_pLogin == NULL)
  {
		//fprintf(stderr, "tds_alloc_login() failed.\n");
    SetError(DATABASE_LAYER_ERROR, wxT("Failed to allocate login"));
    // Reset the variables so there are not mistaken as initialized
    m_pDatabase = NULL;
    m_pLogin = NULL;
    if (m_pContext)
    {
      tds_free_context(m_pContext);
      m_pContext = NULL;
    }
    ThrowDatabaseException();
		return false;
	}
  wxCharBuffer serverBuffer = ConvertToUnicodeStream(m_strServer);
  tds_set_server(m_pLogin, serverBuffer);
  wxCharBuffer loginBuffer = ConvertToUnicodeStream(m_strLogin);
	tds_set_user(m_pLogin, loginBuffer);
  wxCharBuffer passwordBuffer = ConvertToUnicodeStream(m_strPassword);
	tds_set_passwd(m_pLogin, passwordBuffer);
	tds_set_app(m_pLogin, "DatabaseLayer");
	tds_set_library(m_pLogin, "TDS-Library");
	tds_set_client_charset(m_pLogin, "UTF-8");
  switch (m_nTdsVersion)
  {
    case TDS_42:
      tds_set_version(m_pLogin, 4, 2);
      break;
    case TDS_46:
      tds_set_version(m_pLogin, 4, 6);
      break;
    case TDS_50:
      tds_set_version(m_pLogin, 5, 0);
      break;
    case TDS_70:
      tds_set_version(m_pLogin, 7, 0);
      break;
    case TDS_80:
      tds_set_version(m_pLogin, 8, 0);
      break;
    default:
      tds_set_version(m_pLogin, 0, 0);
      break;
  };
  
	m_pContext = tds_alloc_context(NULL);
  if (m_pContext == NULL)
  {
    //fprintf(stderr, "tds_alloc_context() failed.\n");
    SetError(DATABASE_LAYER_ERROR, wxT("Failed to allocate context"));
    // Reset the variables so there are not mistaken as initialized
    m_pDatabase = NULL;
    if (m_pLogin)
    {
      tds_free_login(m_pLogin);
      m_pLogin = NULL;
    }
    if (m_pContext)
    {
      tds_free_context(m_pContext);
      m_pContext = NULL;
    }
    ThrowDatabaseException();
    return false;
  }
	m_pContext->msg_handler = tsql_handle_message;
	m_pContext->err_handler = tsql_handle_error;

  // Add the context (and this databaselayer) from the lookup map
  //  used by the error handler
  TdsDatabaseLayer::AddTdsLayer(m_pContext, this);

  m_pDatabase = tds_alloc_socket(m_pContext, 512);
  if (m_pDatabase == NULL)
  {
    //fprintf(stderr, "tds_alloc_socket() failed.\n");
    SetError(DATABASE_LAYER_ERROR, wxT("Failed to allocate socket"));
    // Reset the variables so there are not mistaken as initialized
    m_pDatabase = NULL;
    if (m_pLogin)
    {
      tds_free_login(m_pLogin);
      m_pLogin = NULL;
    }
    if (m_pContext)
    {
      tds_free_context(m_pContext);
      m_pContext = NULL;
    }
    ThrowDatabaseException();
    return false;
  }
	tds_set_parent(m_pDatabase, NULL);

	TDSCONNECTION* pConnection = tds_read_config_info(NULL, m_pLogin, m_pContext->locale);
	if (!pConnection || tds_connect(m_pDatabase, pConnection) == TDS_FAIL)
  {
		if (pConnection)
    {
			tds_free_socket(m_pDatabase);
			//m_pDatabase = NULL;
			tds_free_connection(pConnection);
		}
		//fprintf(stderr, "tds_connect() failed\n");
    if (GetErrorCode() == DATABASE_LAYER_OK)
    {
      SetError(DATABASE_LAYER_ERROR, wxT("Database connection failed"));
    }
    // Reset the variables so there are not mistaken as initialized
    m_pDatabase = NULL;
    if (m_pLogin)
    {
      tds_free_login(m_pLogin);
      m_pLogin = NULL;
    }
    if (m_pContext)
    {
      tds_free_context(m_pContext);
      m_pContext = NULL;
    }
    ThrowDatabaseException();
		return false;
	}
	tds_free_connection(pConnection);

  return true;
}
Example #9
0
int
main(int argc, char **argv)
{
    TDSCONTEXT *ctx;
    TDSSOCKET *tds;
    TDSLOGIN *login;
    TDSRESULTINFO *resinfo;

    if (argc < 2 || atoi(argv[1]) <= 0) {
        fprintf(stderr, "syntax: %s <port>\n", argv[0]);
        return 1;
    }

    ctx = tds_alloc_context(NULL);
    tds = tds_listen(ctx, atoi(argv[1]));
    if (!tds)
        return 1;
    /* get_incoming(tds->s); */
    login = tds_alloc_read_login(tds);
    if (!login) {
        fprintf(stderr, "Error reading login\n");
        exit(1);
    }
    dump_login(login);
    if (!strcmp(tds_dstr_cstr(&login->user_name), "guest") && !strcmp(tds_dstr_cstr(&login->password), "sybase")) {
        tds->out_flag = TDS_REPLY;
        tds_env_change(tds, TDS_ENV_DATABASE, "master", "pubs2");
        tds_send_msg(tds, 5701, 2, 10, "Changed database context to 'pubs2'.", "JDBC", "ZZZZZ", 1);
        if (!login->suppress_language) {
            tds_env_change(tds, TDS_ENV_LANG, NULL, "us_english");
            tds_send_msg(tds, 5703, 1, 10, "Changed language setting to 'us_english'.", "JDBC", "ZZZZZ", 1);
        }
        tds_env_change(tds, TDS_ENV_PACKSIZE, NULL, "512");
        /* TODO set mssql if tds7+ */
        tds_send_login_ack(tds, "sql server");
        if (IS_TDS50(tds))
            tds_send_capabilities_token(tds);
        tds_send_done_token(tds, 0, 1);
    } else {
        /* send nack before exiting */
        exit(1);
    }
    tds_flush_packet(tds);
    tds_free_login(login);
    login = NULL;
    /* printf("incoming packet %d\n", tds_read_packet(tds)); */
    printf("query : %s\n", tds_get_generic_query(tds));
    tds->out_flag = TDS_REPLY;
    resinfo = tds_alloc_results(1);
    resinfo->columns[0]->column_type = SYBVARCHAR;
    resinfo->columns[0]->column_size = 30;
    strcpy(resinfo->columns[0]->column_name, "name");
    resinfo->columns[0]->column_namelen = 4;
    resinfo->current_row = (TDS_UCHAR*) "pubs2";
    resinfo->columns[0]->column_data = resinfo->current_row;
    tds_send_result(tds, resinfo);
    tds_send_control_token(tds, 1);
    tds_send_row(tds, resinfo);
    tds_send_done_token(tds, 16, 1);
    tds_flush_packet(tds);
    sleep(30);

    tds_free_results(resinfo);
    tds_free_socket(tds);
    tds_free_context(ctx);

    return 0;
}
Example #10
0
int
main(int argc, char **argv)
{
	int srctype;
	int desttype;

	/* some default inputs */
	static const int bit_input = 1;

	/* timing variables to compute performance */
	struct timeval start, end;
	double starttime, endtime;

	int i, j, iterations = 0, result;

	TDS_CHAR *src = NULL;
	TDS_UINT srclen;
	CONV_RESULT cr;

	TDS_NUMERIC numeric;
	TDS_MONEY money;
	TDS_MONEY4 money4;
	TDS_DATETIME datetime;
	TDS_DATETIME4 datetime4;
	TDS_DATETIMEALL dta;
	TDS_DATE date;
	TDS_TIME time;
	TDS_BIGDATETIME bigdatetime;
	TDS_BIGTIME bigtime;

	TDS_TINYINT tds_tinyint;
	TDS_SMALLINT tds_smallint;
	TDS_INT tds_int;
	TDS_INT8 tds_int8;
	TDS_USMALLINT tds_usmallint;
	TDS_UINT tds_uint;
	TDS_UINT8 tds_uint8;

	TDS_REAL tds_real;
	TDS_FLOAT tds_float;

	TDS_UNIQUE tds_unique;

	if (argc > 1) {
		iterations = atoi(argv[1]);
		printf("Computing %d iterations\n", iterations);
	}

	setbuf(stdout, NULL);
	setbuf(stderr, NULL);

	ctx = tds_alloc_context(NULL);
	assert(ctx);
	if (ctx->locale && !ctx->locale->date_fmt) {
		/* set default in case there's no locale file */
		ctx->locale->date_fmt = strdup(STD_DATETIME_FMT);
	}


	/*
	 * Test every possible conversion pair
	 */
	for (i = 0; i < 0x10000; i++) {
		srctype  = i >> 8;
		desttype = i & 0xff;
		srctype = (srctype + SYBCHAR) & 0xff;

		if (!tds_willconvert(srctype, desttype)) {
			/* pass a CONV_RESULT as input for make sure size and alignment is enough
			 * for all types */
			CONV_RESULT src;

			memset(&src, 0, sizeof(src));
			result = tds_convert(ctx, srctype, (const TDS_CHAR *) &src, 4, desttype, &cr);
			if (result >= 0)
				free_convert(desttype, &cr);
			if (result != TDS_CONVERT_NOAVAIL) {
				printf("NOT EXPECTED: converted %d (%s, %d bytes) : %d (%s, %d bytes).\n",
				       srctype, tds_prtype(srctype), srclen,
				       desttype, tds_prtype(desttype), result);
				exit(1);
			}
			continue;	/* don't attempt nonconvertible types */
		}

		if (srctype == desttype)
			continue;	/* don't attempt same types */

		/* valid types should have a name ! */
		assert(tds_prtype(srctype)[0] != 0);
		assert(tds_prtype(desttype)[0] != 0);

		cr.n.precision = 8;
		cr.n.scale = 2;

		switch (srctype) {
		case SYBCHAR:
		case SYBVARCHAR:
		case SYBTEXT:
		case SYBBINARY:
		case SYBVARBINARY:
		case SYBIMAGE:
		case SYBLONGBINARY:
		case XSYBBINARY:
		case XSYBVARBINARY:
		case XSYBCHAR:
		case XSYBVARCHAR:
			switch (desttype) {
			case SYBCHAR:
			case SYBVARCHAR:
			case SYBTEXT:
			case SYBDATETIME:
			case SYBDATETIME4:
				src = "Jan  1, 1999";
				break;
			case SYBMSDATE:
			case SYBMSDATETIME2:
			case SYBMSDATETIMEOFFSET:
			case SYBDATE:
				src = "2012-11-27";
				break;
			case SYBMSTIME:
			case SYBTIME:
				src = "15:27:12";
				break;
			case SYB5BIGTIME:
				src = "15:27:12.327862";
				break;
			case SYB5BIGDATETIME:
				src = "2015-09-12 21:48:12.638161";
				break;
			case SYBBINARY:
			case SYBIMAGE:
				src = "0xbeef";
				break;
			case SYBINT1:
			case SYBINT2:
			case SYBINT4:
			case SYBINT8:
			case SYBUINT1:
			case SYBUINT2:
			case SYBUINT4:
			case SYBUINT8:
				src = "255";
				break;
			case SYBFLT8:
			case SYBREAL:
			case SYBNUMERIC:
			case SYBDECIMAL:
			case SYBMONEY:
			case SYBMONEY4:
				src = "1999.25";
				cr.n.precision = 8;
				cr.n.scale = 2;
				break;
			case SYBUNIQUE:
				src = "A8C60F70-5BD4-3E02-B769-7CCCCA585DCC";
				break;
			case SYBBIT:
			default:
				src = "1";
				break;
			}
			assert(src);
			srclen = strlen(src);
			break;
		case SYBINT1:
		case SYBUINT1:
			src = (char *) &tds_tinyint;
			srclen = sizeof(tds_tinyint);
			break;
		case SYBINT2:
			src = (char *) &tds_smallint;
			srclen = sizeof(tds_smallint);
			break;
		case SYBINT4:
			src = (char *) &tds_int;
			srclen = sizeof(tds_int);
			break;
		case SYBINT8:
			src = (char *) &tds_int8;
			srclen = sizeof(tds_int8);
			break;
		case SYBUINT2:
			src = (char *) &tds_usmallint;
			srclen = sizeof(tds_usmallint);
			break;
		case SYBUINT4:
			src = (char *) &tds_uint;
			srclen = sizeof(tds_uint);
			break;
		case SYBUINT8:
			src = (char *) &tds_uint8;
			srclen = sizeof(tds_uint8);
			break;
		case SYBFLT8:
			tds_float = 3.14159;
			src = (char *) &tds_float;
			srclen = sizeof(tds_float);
			break;
		case SYBREAL:
			tds_real = (TDS_REAL) 3.14159;
			src = (char *) &tds_real;
			srclen = sizeof(tds_real);
			break;
		case SYBNUMERIC:
		case SYBDECIMAL:
			src = (char *) &numeric;
			srclen = sizeof(numeric);
			break;
		case SYBMONEY:
			src = (char *) &money;
			srclen = sizeof(money);
			break;
		case SYBMONEY4:
			src = (char *) &money4;
			srclen = sizeof(money4);
			break;
		case SYBBIT:
		case SYBBITN:
			src = (char *) &bit_input;
			srclen = sizeof(bit_input);
			break;
		case SYBDATETIME:
			src = (char *) &datetime;
			srclen = sizeof(datetime);
			break;
		case SYBDATETIME4:
			src = (char *) &datetime4;
			srclen = sizeof(datetime4);
			break;
		case SYBDATE:
			src = (char *) &date;
			srclen = sizeof(date);
			break;
		case SYBTIME:
			src = (char *) &time;
			srclen = sizeof(time);
			break;
		case SYB5BIGTIME:
			src = (char *) &bigtime;
			srclen = sizeof(bigtime);
			break;
		case SYB5BIGDATETIME:
			src = (char *) &bigdatetime;
			srclen = sizeof(bigdatetime);
			break;
		case SYBUNIQUE:
			src = (char *) &tds_unique;
			srclen = sizeof(tds_unique);
			break;
		case SYBMSTIME:
		case SYBMSDATE:
		case SYBMSDATETIME2:
		case SYBMSDATETIMEOFFSET:
			src = (char *) &dta;
			srclen = sizeof(dta);
			break;
		/*****  not defined yet
			case SYBBOUNDARY:
			case SYBSENSITIVITY:
				fprintf (stderr, "type %d not supported\n", srctype );
				continue;
				break;
		*****/
		default:
			fprintf(stderr, "no such type %d (%s)\n", srctype, tds_prtype(srctype));
			return -1;
		}

		/* 
		 * Now at last do the conversion
		 */

		result = tds_convert(ctx, srctype, src, srclen, desttype, &cr);
		if (result >= 0)
			free_convert(desttype, &cr);

		if (result < 0) {
			if (result == TDS_CONVERT_NOAVAIL)	/* tds_willconvert returned true, but it lied. */
				fprintf(stderr, "Conversion not yet implemented:\n\t");

			fprintf(stderr, "failed (%d) to convert %d (%s, %d bytes) : %d (%s).\n",
				result,
				srctype, tds_prtype(srctype), srclen,
				desttype, tds_prtype(desttype));

			if (result == TDS_CONVERT_NOAVAIL)
				exit(1);
		}

		printf("converted %d (%s, %d bytes) -> %d (%s, %d bytes).\n",
		       srctype, tds_prtype(srctype), srclen,
		       desttype, tds_prtype(desttype), result);

		/* 
		 * In the first iteration, start with varchar -> others.  
		 * By saving the output, we initialize subsequent inputs.
		 */

		switch (desttype) {
		case SYBNUMERIC:
		case SYBDECIMAL:
			numeric = cr.n;
			break;
		case SYBMONEY:
			money = cr.m;
			break;
		case SYBMONEY4:
			money4 = cr.m4;
			break;
		case SYBDATETIME:
			datetime = cr.dt;
			break;
		case SYBDATETIME4:
			datetime4 = cr.dt4;
			break;
		case SYBDATE:
			date = cr.date;
			break;
		case SYBTIME:
			time = cr.time;
			break;
		case SYBMSDATETIME2:
			dta = cr.dta;
			break;
		case SYB5BIGTIME:
			bigtime = cr.bigtime;
			break;
		case SYB5BIGDATETIME:
			bigdatetime = cr.bigdatetime;
			break;
		case SYBINT1:
		case SYBUINT1:
			tds_tinyint = cr.ti;
			break;
		case SYBINT2:
			tds_smallint = cr.si;
			break;
		case SYBINT4:
			tds_int = cr.i;
			break;
		case SYBINT8:
			tds_int8 = cr.bi;
			break;
		case SYBUINT2:
			tds_usmallint = cr.usi;
			break;
		case SYBUINT4:
			tds_uint = cr.ui;
			break;
		case SYBUINT8:
			tds_uint8 = cr.ubi;
			break;
		case SYBUNIQUE:
			tds_unique = cr.u;
			break;
		default:
			break;
		}

		/*
		 * If an iteration count was passed on the command line (not by "make check")
		 * run the conversion N times and print the conversions per second.
		 */
		result = gettimeofday(&start, NULL);
		starttime = (double) start.tv_sec + (double) start.tv_usec * 0.000001;

		for (j = 0; result >= 0 && j < iterations; j++) {
			result = tds_convert(ctx, srctype, src, srclen, desttype, &cr);
			if (result >= 0)
				free_convert(desttype, &cr);
		}
		if (result < 0)
			continue;

		result = gettimeofday(&end, NULL);
		endtime = (double) end.tv_sec + (double) end.tv_usec * 0.000001;

		if (endtime != starttime) {
			printf("%9.0f iterations/second converting %13s => %s.\n",
				j / (endtime - starttime), tds_prtype(srctype), tds_prtype(desttype));
		}

	}
	tds_free_context(ctx);

	return g_result;
}