freetds AT lists.ibiblio.org
Subject: FreeTDS Development Group
List archive
Re: [freetds] ct_config set CS_IFILE property is not working?
- From: Dariusz Ostolski <dariusz.ostolski AT gmail.com>
- To: FreeTDS Development Group <freetds AT lists.ibiblio.org>
- Cc: "James K. Lowden" <jklowden AT freetds.org>
- Subject: Re: [freetds] ct_config set CS_IFILE property is not working?
- Date: Wed, 11 Jan 2012 23:11:54 +0100
Hello,
On -10.01.-28163 20:59, James K. Lowden wrote:
On Tue, 3 Jan 2012 09:07:31 +0100Thank You for your answer.
dariusz ostolski<dariusz.ostolski AT gmail.com> wrote:
1. Can You confirm that I cannot set custom path to interfaces fileYes. The FreeTDS function supports only three properties, CS_IFILE
using ct_config?
not among them.
2. What alternatives do I have? I don't want to modify $SYBASEUSTL. There's a static constant src/tds/config.c::interfaces_path.
environment variable and I wouldn't like to use any function outside
ct library?
Add to the case statement in ct_config, diddle just a bit with the
logic around config.c:1095:
It should be by context so I prepared a patch that should work on a context.
I'm sending it to You to have a look at it. Unfortunately I had some issues
when I was preparing this patch. My first mistake was downloading packaged tgz
with sources(freetds-stable which seem to be 0-91) and making all changes on
this packaged sources. To be able to easily produce a patch I've got an idea of checkouting
a branch and use cvs diff, but it seems that tgz was produced from different branch(or maybe a tag).
My cvs command was:
cvs -z3 -d:pserver:anonymous AT freetds.cvs.sourceforge.net:/cvsroot/freetds co -r branch-0.91 freetds
so the patch is the merge of some files from this branch and what was in the freetds-stable.tgz.
If You could point correct tag/branch then I'll be able to merge and produce correct patch. Nevertheless
Im sending it to You to have look(first review), any feedback welcome.
Regards,
Darek
? csifile.patch
Index: include/tds.h
===================================================================
RCS file: /cvsroot/freetds/freetds/include/tds.h,v
retrieving revision 1.352
diff -u -w -r1.352 tds.h
--- include/tds.h 30 Mar 2011 11:29:34 -0000 1.352
+++ include/tds.h 11 Jan 2012 21:54:37 -0000
@@ -21,12 +21,15 @@
#ifndef _tds_h_
#define _tds_h_
-/* $Id: tds.h,v 1.352 2011/03/30 11:29:34 freddy77 Exp $ */
+/* $Id: tds.h,v 1.352.2.4 2011/08/12 16:29:36 freddy77 Exp $ */
#include <stdarg.h>
#include <stdio.h>
#include <time.h>
+#if HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif /* HAVE_NET_INET_IN_H */
#if HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif /* HAVE_ARPA_INET_H */
@@ -812,6 +815,8 @@
#define TDS_STR_ENCRYPTION_REQUIRE "require"
/* Defines to enable optional GSSAPI delegation */
#define TDS_GSSAPI_DELEGATION "enable gssapi delegation"
+/* Kerberos realm name */
+#define TDS_STR_REALM "realm"
/* TODO do a better check for alignment than this */
@@ -861,6 +866,7 @@
TDS_INT connect_timeout;
DSTR client_host_name;
DSTR server_host_name;
+ DSTR server_realm_name; /**< server realm name (in freetds.conf) */
DSTR app_name;
DSTR user_name; /**< account for login */
DSTR password; /**< password of account login */
@@ -1270,6 +1276,8 @@
struct tds_context
{
+ /* path to alternate location of interfaces file */
+ TDS_CHAR *interfaces;
TDSLOCALE *locale;
void *parent;
/* handlers */
@@ -1309,6 +1317,7 @@
unsigned int broken_dates:1;
unsigned int emul_little_endian:1;
unsigned int use_iconv:1;
+ unsigned int tds71rev1:1;
unsigned char *in_buf; /**< input buffer */
unsigned char *out_buf; /**< output buffer */
@@ -1397,9 +1406,9 @@
const TDS_COMPILETIME_SETTINGS *tds_get_compiletime_settings(void);
typedef void (*TDSCONFPARSE) (const char *option, const char *value, void *param);
int tds_read_conf_section(FILE * in, const char *section, TDSCONFPARSE tds_conf_parse, void *parse_param);
-int tds_read_conf_file(TDSCONNECTION * connection, const char *server);
+int tds_read_conf_file(TDSCONNECTION * connection, const char *server, const char *interfaces);
void tds_parse_conf_section(const char *option, const char *value, void *param);
-TDSCONNECTION *tds_read_config_info(TDSSOCKET * tds, TDSLOGIN * login, TDSLOCALE * locale);
+TDSCONNECTION *tds_read_config_info(TDSSOCKET * tds, TDSLOGIN * login, TDSLOCALE * locale, TDS_CHAR *interfaces);
void tds_fix_connection(TDSCONNECTION * connection);
TDS_USMALLINT tds_config_verstr(const char *tdsver, TDSCONNECTION * connection);
int tds_lookup_host(const char *servername, char *ip);
@@ -1416,6 +1425,8 @@
/*@observer@*/ const char *tds_prtype(int token);
int tds_get_varint_size(TDSSOCKET * tds, int datatype);
int tds_get_cardinal_type(int datatype, int usertype);
+int tds_config_set_ctxt_interfaces_file(TDSCONTEXT *ctxt, void *buffer, size_t buflen);
+int tds_config_get_ctxt_interfaces_file(TDSCONTEXT *ctxt, void *buffer, size_t buflen, int *outlen);
@@ -1617,6 +1628,15 @@
#endif
/* bulk.c */
+
+/** bcp direction */
+enum tds_bcp_directions
+{
+ TDS_BCP_IN = 1,
+ TDS_BCP_OUT = 2,
+ TDS_BCP_QUERYOUT = 3
+};
+
typedef struct tds_bcpinfo
{
const char *hint;
Index: src/ctlib/ct.c
===================================================================
RCS file: /cvsroot/freetds/freetds/src/ctlib/ct.c,v
retrieving revision 1.207
diff -u -w -r1.207 ct.c
--- src/ctlib/ct.c 5 Oct 2010 08:36:36 -0000 1.207
+++ src/ctlib/ct.c 11 Jan 2012 21:54:38 -0000
@@ -266,7 +266,6 @@
ctx->tds_ctx->msg_handler = _ct_handle_server_message;
ctx->tds_ctx->err_handler = _ct_handle_client_message;
-
return CS_SUCCEED;
}
@@ -610,7 +609,7 @@
if (!(con->tds_socket = tds_alloc_socket(ctx->tds_ctx, 512)))
return CS_FAIL;
tds_set_parent(con->tds_socket, (void *) con);
- if (!(connection = tds_read_config_info(con->tds_socket, con->tds_login, ctx->tds_ctx->locale))) {
+ if (!(connection = tds_read_config_info(con->tds_socket, con->tds_login, ctx->tds_ctx->locale, ctx->tds_ctx->interfaces))) {
tds_free_socket(con->tds_socket);
con->tds_socket = NULL;
return CS_FAIL;
@@ -2380,6 +2379,41 @@
}
+static CS_RETCODE
+_ct_set_ifile(CS_CONTEXT * ctx, CS_VOID * buffer, CS_INT buflen)
+{
+
+ if ( buflen==CS_UNUSED ) {
+ return CS_FAIL;
+ }
+
+ if ( buflen==CS_NULLTERM ) {
+ buflen = strlen(buffer);
+ }
+
+ if ( tds_config_set_ctxt_interfaces_file(ctx->tds_ctx, buffer, buflen)==TDS_SUCCEED ) {
+ return CS_SUCCEED;
+ }
+ return CS_FAIL;
+}
+
+static CS_RETCODE
+_ct_get_ifile(CS_CONTEXT * ctx, CS_VOID * buffer, CS_INT buflen, CS_INT * outlen)
+{
+ if ( buflen==CS_UNUSED ) {
+ return CS_FAIL;
+ }
+
+ if ( buflen==CS_NULLTERM ) {
+ return CS_FAIL;
+ }
+
+ if ( tds_config_get_ctxt_interfaces_file(ctx->tds_ctx, buffer, buflen, outlen)==TDS_SUCCEED ) {
+ return CS_SUCCEED;
+ }
+ return CS_FAIL;
+}
+
CS_RETCODE
ct_config(CS_CONTEXT * ctx, CS_INT action, CS_INT property, CS_VOID * buffer, CS_INT buflen, CS_INT * outlen)
{
@@ -2392,6 +2426,21 @@
CS_GET ? "CS_GET" : CS_SET ? "CS_SET" : CS_SUPPORTED ? "CS_SUPPORTED" : "CS_CLEAR", property);
switch (property) {
+ case CS_IFILE: {
+ ret = CS_FAIL;
+ switch (action) {
+ case CS_SET:
+ ret = _ct_set_ifile(ctx, buffer, buflen);
+ break;
+ case CS_GET:
+ ret = _ct_get_ifile(ctx, buffer, buflen, outlen);
+ break;
+ default:
+ ret = CS_FAIL;
+ }
+ }
+ break;
+
case CS_EXPOSE_FMTS:
switch (action) {
case CS_SUPPORTED:
Index: src/odbc/connectparams.c
===================================================================
RCS file: /cvsroot/freetds/freetds/src/odbc/connectparams.c,v
retrieving revision 1.88
diff -u -w -r1.88 connectparams.c
--- src/odbc/connectparams.c 9 Nov 2010 15:46:42 -0000 1.88
+++ src/odbc/connectparams.c 11 Jan 2012 21:54:38 -0000
@@ -161,7 +161,7 @@
if (myGetPrivateProfileString(DSN, odbc_param_Servername, tmp) > 0) {
freetds_conf_less = 0;
tds_dstr_copy(&connection->server_name, tmp);
- tds_read_conf_file(connection, tmp);
+ tds_read_conf_file(connection, tmp, NULL);
if (myGetPrivateProfileString(DSN, odbc_param_Server, tmp) > 0) {
odbc_errs_add(errs, "HY000", "You cannot specify both SERVERNAME and SERVER");
return 0;
@@ -330,7 +330,7 @@
}
if (!cfgs) {
tds_dstr_dup(&connection->server_name, &value);
- tds_read_conf_file(connection, tds_dstr_cstr(&value));
+ tds_read_conf_file(connection, tds_dstr_cstr(&value), NULL);
cfgs = CFG_SERVERNAME;
p = connect_string;
continue;
Index: src/tds/config.c
===================================================================
RCS file: /cvsroot/freetds/freetds/src/tds/config.c,v
retrieving revision 1.162
diff -u -w -r1.162 config.c
--- src/tds/config.c 9 Nov 2010 15:46:42 -0000 1.162
+++ src/tds/config.c 11 Jan 2012 21:54:38 -0000
@@ -88,7 +88,7 @@
static void tds_config_env_tdsport(TDSCONNECTION * connection);
static void tds_config_env_tdshost(TDSCONNECTION * connection);
static int tds_read_conf_sections(FILE * in, const char *server, TDSCONNECTION * connection);
-static int tds_read_interfaces(const char *server, TDSCONNECTION * connection);
+static int tds_read_interfaces(const char *server, TDSCONNECTION * connection, const TDS_CHAR *interfaces);
static int parse_server_name_for_port(TDSCONNECTION * connection, TDSLOGIN * login);
static int tds_lookup_port(const char *portname);
static void tds_config_encryption(const char * value, TDSCONNECTION * connection);
@@ -154,7 +154,7 @@
* integration with various Linux and *BSD distributions.
*/
TDSCONNECTION *
-tds_read_config_info(TDSSOCKET * tds, TDSLOGIN * login, TDSLOCALE * locale)
+tds_read_config_info(TDSSOCKET * tds, TDSLOGIN * login, TDSLOCALE * locale, TDS_CHAR *interfaces)
{
TDSCONNECTION *connection;
char *s;
@@ -187,19 +187,26 @@
/* Read the config files. */
tdsdump_log(TDS_DBG_INFO1, "Attempting to read conf files.\n");
- found = tds_read_conf_file(connection, tds_dstr_cstr(&login->server_name));
+ found = tds_read_conf_file(connection, tds_dstr_cstr(&login->server_name), interfaces);
if (!found) {
if (parse_server_name_for_port(connection, login)) {
- found = tds_read_conf_file(connection, tds_dstr_cstr(&connection->server_name));
+ char ip_addr[256];
+
+ found = tds_read_conf_file(connection, tds_dstr_cstr(&connection->server_name), interfaces);
/* do it again to really override what found in freetds.conf */
- if (found)
+ if (found) {
parse_server_name_for_port(connection, login);
+ } else if (tds_lookup_host(tds_dstr_cstr(&connection->server_name), ip_addr) == TDS_SUCCEED) {
+ tds_dstr_dup(&connection->server_host_name, &connection->server_name);
+ tds_dstr_copy(&connection->ip_addr, ip_addr);
+ found = 1;
+ }
}
}
if (!found) {
/* fallback to interfaces file */
tdsdump_log(TDS_DBG_INFO1, "Failed in reading conf file. Trying interface files.\n");
- if (!tds_read_interfaces(tds_dstr_cstr(&login->server_name), connection)) {
+ if (!tds_read_interfaces(tds_dstr_cstr(&login->server_name), connection, interfaces)) {
tdsdump_log(TDS_DBG_INFO1, "Failed to find [%s] in configuration files; trying '%s' instead.\n",
tds_dstr_cstr(&login->server_name), tds_dstr_cstr(&connection->server_name));
if (tds_dstr_isempty(&connection->ip_addr))
@@ -245,6 +252,7 @@
tdsdump_log(TDS_DBG_INFO1, "\t%20s = %d\n", "text_size", connection->text_size);
tdsdump_log(TDS_DBG_INFO1, "\t%20s = %d\n", "broken_dates", connection->broken_dates);
tdsdump_log(TDS_DBG_INFO1, "\t%20s = %d\n", "emul_little_endian", connection->emul_little_endian);
+ tdsdump_log(TDS_DBG_INFO1, "\t%20s = %s\n", "server_realm_name", tds_dstr_cstr(&connection->server_realm_name));
tdsdump_close();
}
@@ -327,12 +335,17 @@
* configuration for a server
*/
int
-tds_read_conf_file(TDSCONNECTION * connection, const char *server)
+tds_read_conf_file(TDSCONNECTION * connection, const char *server, const char *interfaces)
{
char *path = NULL;
char *eptr = NULL;
int found = 0;
+ if (interfaces) {
+ tdsdump_log(TDS_DBG_INFO1, "Looking for server in file %s.\n", interfaces);
+ found = tds_try_conf_file(interfaces, "set programmatically on a context", server, connection);
+ }
+
if (interf_file) {
found = tds_try_conf_file(interf_file, "set programmatically", server, connection);
}
@@ -615,6 +628,8 @@
tds_dstr_copy(&connection->server_name, value);
} else if (!strcmp(option, TDS_STR_USENTLMV2)) {
connection->use_ntlmv2 = tds_config_boolean(value);
+ } else if (!strcmp(option, TDS_STR_REALM)) {
+ tds_dstr_copy(&connection->server_realm_name, value);
} else {
tdsdump_log(TDS_DBG_INFO1, "UNRECOGNIZED option '%s' ... ignoring.\n", option);
}
@@ -640,6 +655,11 @@
tdsdump_log(TDS_DBG_INFO1, "tds_config_login: %s is %s.\n", "client_charset",
tds_dstr_cstr(&connection->client_charset));
}
+ if (!tds_dstr_isempty(&login->database)) {
+ tds_dstr_dup(&connection->database, &login->database);
+ tdsdump_log(TDS_DBG_INFO1, "tds_config_login: %s is %s.\n", "database_name",
+ tds_dstr_cstr(&connection->database));
+ }
if (!tds_dstr_isempty(&login->client_host_name)) {
tds_dstr_dup(&connection->client_host_name, &login->client_host_name);
}
@@ -1009,7 +1029,7 @@
* @note This function uses only the interfaces file and is deprecated.
*/
static int
-tds_read_interfaces(const char *server, TDSCONNECTION * connection)
+tds_read_interfaces(const char *server, TDSCONNECTION * connection, const TDS_CHAR *interfaces)
{
int found = 0;
@@ -1023,6 +1043,13 @@
}
tdsdump_log(TDS_DBG_INFO1, "Looking for server %s....\n", server);
+ /*
+ * Look for the server in the context if has been set.
+ */
+ if (interfaces) {
+ tdsdump_log(TDS_DBG_INFO1, "Looking for server in file %s.\n", interfaces);
+ found = search_interface_file(connection, "", interfaces, server);
+ }
/*
* Look for the server in the interf_file iff interf_file has been set.
@@ -1207,4 +1234,114 @@
return &settings;
}
+/**
+ *
+ * @param path
+ * @param buffer
+ * @param buflen
+ * @param outlen
+ * @return
+ */
+static int
+tds_config_get_file(const char *path, void *buffer, size_t buflen, int *outlen)
+{
+ int len = 0;
+ if (path) {
+
+ len = strlen(path)+1;
+
+ /* if outlen was given we can inform how big buffer should be allocated */
+ if (outlen) {
+ *outlen = len;
+ }
+
+ if(buffer && buflen>=len) {
+ memcpy(buffer, path, len);
+ return TDS_SUCCEED;
+ }
+ }
+ return TDS_FAIL;
+}
+
+/**
+ * Get the full path to configuration/interface file
+ *
+ * @param ctxt
+ * @param buffer
+ * @param buflen
+ * @param outlen
+ * @return TDS_SUCCEED or TDS_FAIL
+ */
+int
+tds_config_get_ctxt_interfaces_file(TDSCONTEXT *ctxt, void *buffer, size_t buflen, int *outlen)
+{
+ int result = 0;
+ char *path = NULL;
+ char *eptr = NULL;
+
+ if (ctxt && ctxt->interfaces) {
+ return tds_config_get_file(ctxt->interfaces, buffer, buflen, outlen);
+ }
+
+ if (interf_file) {
+ return tds_config_get_file(interf_file, buffer, buflen, outlen);
+ }
+
+ path = getenv("FREETDSCONF");
+ if (path) {
+ return tds_config_get_file(path, buffer, buflen, outlen);
+ }
+
+ eptr = getenv("FREETDS");
+ if (eptr) {
+ if (asprintf(&path, freetds_conf, eptr) >= 0) {
+ result = tds_config_get_file(path, buffer, buflen, outlen);
+ free(path);
+ return result;
+ }
+ }
+
+ path = tds_get_home_file(".freetds.conf");
+ if (path) {
+ result = tds_config_get_file(path, buffer, buflen, outlen);
+ free(path);
+ return result;
+ }
+
+ return tds_config_get_file(FREETDS_SYSCONFFILE, buffer, buflen, outlen);
+}
+
+/**
+ *
+ * @param ctxt
+ * @param buffer
+ * @param buflen
+ * @return
+ */
+int
+tds_config_set_ctxt_interfaces_file(TDSCONTEXT *ctxt, void *buffer, size_t buflen)
+{
+ char *buf = buffer;
+
+ /* Free it if already set */
+ if (ctxt->interfaces) {
+ free(ctxt->interfaces);
+ ctxt->interfaces = NULL;
+ }
+
+ /* If no filename passed, leave it NULL */
+ if ((buflen == 0 ) || (buffer == NULL) || (buf[0] == '\0') ) {
+ return TDS_SUCCEED;
+ }
+
+ /* Set to new value */
+ ctxt->interfaces = calloc(buflen+1, sizeof(char));
+ if ( ctxt->interfaces == NULL ) {
+ return TDS_FAIL;
+ }
+
+ memcpy(ctxt->interfaces, buffer, buflen);
+ return TDS_SUCCEED;
+}
+
/** @} */
Index: src/tds/mem.c
===================================================================
RCS file: /cvsroot/freetds/freetds/src/tds/mem.c,v
retrieving revision 1.208
diff -u -w -r1.208 mem.c
--- src/tds/mem.c 28 Sep 2010 08:20:11 -0000 1.208
+++ src/tds/mem.c 11 Jan 2012 21:54:39 -0000
@@ -53,7 +53,7 @@
#include <dmalloc.h>
#endif
-TDS_RCSID(var, "$Id: mem.c,v 1.208 2010/09/28 08:20:11 freddy77 Exp $");
+TDS_RCSID(var, "$Id: mem.c,v 1.208.2.1 2011/08/12 16:29:36 freddy77 Exp $");
static void tds_free_env(TDSSOCKET * tds);
static void tds_free_compute_results(TDSSOCKET * tds);
@@ -654,6 +654,7 @@
return 1;
}
+
TDSCONTEXT *
tds_alloc_context(void * parent)
{
@@ -682,6 +683,9 @@
if (!context)
return;
+ if(context->interfaces)
+ free(context->interfaces);
+
tds_free_locale(context->locale);
free(context);
}
@@ -827,6 +831,7 @@
tds_dstr_init(&connection->dump_file);
tds_dstr_init(&connection->client_charset);
tds_dstr_init(&connection->instance_name);
+ tds_dstr_init(&connection->server_realm_name);
/* fill in all hardcoded defaults */
if (!tds_dstr_copy(&connection->server_name, TDS_DEF_SERVER))
@@ -1188,6 +1193,7 @@
tds_dstr_free(&connection->password);
tds_dstr_free(&connection->library);
tds_dstr_free(&connection->instance_name);
+ tds_dstr_init(&connection->server_realm_name);
free(connection);
}
-
[freetds] ct_config set CS_IFILE property is not working?,
dariusz ostolski, 01/03/2012
-
Re: [freetds] ct_config set CS_IFILE property is not working?,
James K. Lowden, 01/04/2012
-
Re: [freetds] ct_config set CS_IFILE property is not working?,
Dariusz Ostolski, 01/11/2012
- Re: [freetds] ct_config set CS_IFILE property is not working?, James K. Lowden, 01/11/2012
-
Re: [freetds] ct_config set CS_IFILE property is not working?,
James K. Lowden, 01/16/2012
- Re: [freetds] ct_config set CS_IFILE property is not working?, Dariusz Ostolski, 01/17/2012
-
Re: [freetds] ct_config set CS_IFILE property is not working?,
Dariusz Ostolski, 01/11/2012
-
Re: [freetds] ct_config set CS_IFILE property is not working?,
James K. Lowden, 01/04/2012
Archive powered by MHonArc 2.6.24.