Skip to Content.
Sympa Menu

freetds - Re: [freetds] ct_config set CS_IFILE property is not working?

freetds AT lists.ibiblio.org

Subject: FreeTDS Development Group

List archive

Chronological Thread  
  • 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 +0100
dariusz ostolski<dariusz.ostolski AT gmail.com> wrote:

1. Can You confirm that I cannot set custom path to interfaces file
using ct_config?
Yes. The FreeTDS function supports only three properties, CS_IFILE
not among them.
Thank You for your answer.

2. What alternatives do I have? I don't want to modify $SYBASE
environment variable and I wouldn't like to use any function outside
ct library?
USTL. There's a static constant src/tds/config.c::interfaces_path.
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);
 }
 



Archive powered by MHonArc 2.6.24.

Top of Page