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.