freetds AT lists.ibiblio.org
Subject: FreeTDS Development Group
List archive
Re: [freetds] Dreaded "Server SYBASE not found!" question
- From: Frediano Ziglio <freddy77 AT gmail.com>
- To: FreeTDS Development Group <freetds AT lists.ibiblio.org>
- Subject: Re: [freetds] Dreaded "Server SYBASE not found!" question
- Date: Sun, 13 Dec 2009 09:23:13 +0100
Il giorno sab, 12/12/2009 alle 12.42 -0500, James K. Lowden ha scritto:
> Nelson, Erik - 2 wrote:
> > There's an outstanding todo in login.c to open the log file prior to
> > tds_set_server() where "SYBASE" is being set in to
> > connection->server_name, but it's not at all clear why the server
> > name/IP aren't being set correctly since the server info is clearly
> > being found in freetds.conf.
> ...
> > [Hiruko] found in "/modleng/usr/etc/odbc.ini"
> > found this section:
> > [Hiruko]
> > Driver = FreeTDS
> > Description = DataDirect 5.1 SQL Server Wire Protocol
> > Servername = Hiruko
> > Server = Hiruko
> > Port = 1433
>
> Server and Servername cannot be in the same section. One overrides the
> other.
>
> This highlights a more general question, for which I'd like to hear
> suggestions (and/or see a patch!) from anyone who's interested.
>
> We have two mutually exclusive attributes in our configuration files. In
> odbc.ini we have server/servername; in freetds.conf we have port/instance.
> These inevitably trip up some people, probably a lot more than write to
> the list, who over-specify the sever. What to do?
>
> One solution is to die noisily with err(3) when invalid combinations are
> found for the requested server. (Also, perhaps warnings writting to
> stderr for any other configuration problems e.g. invalid property names).
>
>
> A second way is to document the conflict clearly and have a careful
> override policy. I started working on that, but I'm not satisfied. It
> reminded me of something one of the Bell Labs guys said about writing
> early UNIX man pages: sometimes the documented behavior was so
> embarrassing that it motivated them to fix it.
>
I would suggest a proper error using correct way (that is no stderr).
> Another solution is to eliminate the "other" name.
>
> For odbc.ini, we could eliminate "servername". Instead, "server" would
> first be looked up in freetds.conf, if it exists. If nothing is found,
> then "server" would be treated as a DNS name. This is consistent with how
> a servername is treated during a db-lib/ct-lib lookup.
Although this breaks compatibility I'd agree. I see not that difference
between two terms.
> For freetds.conf, we could eliminate "instance" and always use "port". If
> "port" is a number, it's a port; if "port" is a string, it's a named
> instance. Or, always treat "port" as a potential named instance,
> interrogate the server, and revert to a number only if the server refuses
> to reply with a valid port. (I'm tempted to keep "instance" and eliminate
> "port" instead, but I'm held back, perhaps wrongly, by tradition. And I
> wonder whether you can name your instance "80"?)
>
And what about port is a port specified in /etc/services ?
Personally I would eliminate both and use "compressed" syntax like
"server:port" or "server\instance". This for two reason:
- is already supported by libTDS
- is compatible with ODBC and the way you specify this in DSN
configuration.
> I tend to favor "die early and often": if the configuration file is
> invalid, complain and stop. But, particularly in web environments (and
> given the way TDSDUMP logging works), it can be hard to diagnose why the
> server connection failed.
>
If upper layer do not read correctly error is not my problem.
> I *also* think it's better to make mistakes less likely by eliminating
> opportunities.
>
I think first step is eliminate confusion refusing to even try to
connect if both specified (server/servername and/or port/instance).
> Suggestions?
>
As a start see attached patch
freddy77
Index: include/tds.h
===================================================================
RCS file: /cvs/freetds/freetds/include/tds.h,v
retrieving revision 1.323
diff -U 10 -r1.323 tds.h
--- include/tds.h 26 Nov 2009 09:47:41 -0000 1.323
+++ include/tds.h 13 Dec 2009 08:13:56 -0000
@@ -280,21 +280,22 @@
* TDSERRNO is emitted by libtds to the client library's error handler
* (which may in turn call the client's error handler).
* These match the db-lib msgno, because the same values have the same meaning
* in db-lib and ODBC. ct-lib maps them to ct-lib numbers (todo).
*/
typedef enum { TDSEOK = TDS_SUCCEED,
TDSEICONVIU = 2400,
TDSEICONVAVAIL = 2401,
TDSEICONVO = 2402,
TDSEICONVI = 2403,
- TDSEICONV2BIG = 2404,
+ TDSEICONV2BIG = 2404,
+ TDSEPORTINSTANCE = 2500,
TDSESYNC = 20001,
TDSEFCON = 20002,
TDSETIME = 20003,
TDSEREAD = 20004,
TDSEWRIT = 20006,
TDSESOCK = 20008,
TDSECONN = 20009,
TDSEMEM = 20010,
TDSEINTF = 20012, /* Server name not found in interface file */
TDSEUHST = 20013, /* Unknown host machine name. */
Index: src/tds/config.c
===================================================================
RCS file: /cvs/freetds/freetds/src/tds/config.c,v
retrieving revision 1.151
diff -U 10 -r1.151 config.c
--- src/tds/config.c 26 Nov 2009 09:47:41 -0000 1.151
+++ src/tds/config.c 13 Dec 2009 08:13:56 -0000
@@ -619,24 +619,22 @@
}
if (login->suppress_language) {
connection->suppress_language = 1;
}
if (login->bulk_copy) {
connection->bulk_copy = 1;
}
if (login->block_size) {
connection->block_size = login->block_size;
}
- if (login->port) {
+ if (login->port)
connection->port = login->port;
- tds_dstr_copy(&connection->instance_name, "");
- }
if (login->connect_timeout)
connection->connect_timeout = login->connect_timeout;
if (login->query_timeout)
connection->query_timeout = login->query_timeout;
/* copy other info not present in configuration file */
memcpy(connection->capabilities, login->capabilities, TDS_MAX_CAPABILITY);
}
@@ -1029,25 +1027,21 @@
/*
* Make a guess about the port number
*/
if (connection->port == 0) {
/*
* Not set in the [global] section of the
* configure file, take a guess.
*/
-#ifdef TDS50
- ip_port = 4000;
-#else
- ip_port = 1433;
-#endif
+ ip_port = TDS_DEF_PORT;
} else {
/*
* Preserve setting from the [global] section
* of the configure file.
*/
ip_port = connection->port;
}
if ((env_port = getenv("TDSPORT")) != NULL) {
ip_port = tds_lookup_port(env_port);
tdsdump_log(TDS_DBG_INFO1, "Setting 'ip_port' to %s from $TDSPORT.\n", env_port);
@@ -1080,28 +1074,26 @@
const char *pSep;
const char *server;
/* seek the ':' in login server_name */
server = tds_dstr_cstr(&login->server_name);
pSep = strrchr(server, ':');
if (pSep && pSep != server) { /* yes, i found it! */
/* modify connection-> && login->server_name & ->port */
login->port = connection->port = atoi(pSep + 1);
- tds_dstr_copy(&connection->instance_name, "");
} else {
/* handle instance name */
pSep = strrchr(server, '\\');
if (!pSep || pSep == server)
return 0;
- login->port = connection->port = 0;
tds_dstr_copy(&connection->instance_name, pSep + 1);
}
tds_dstr_setlen(&login->server_name, pSep - server);
if (!tds_dstr_dup(&connection->server_name, &login->server_name))
return 0;
return 1;
}
Index: src/tds/login.c
===================================================================
RCS file: /cvs/freetds/freetds/src/tds/login.c,v
retrieving revision 1.191
diff -U 10 -r1.191 login.c
--- src/tds/login.c 2 Dec 2009 22:58:21 -0000 1.191
+++ src/tds/login.c 13 Dec 2009 08:13:56 -0000
@@ -420,20 +420,25 @@
tdserror(tds->tds_ctx, tds, TDSEUHST, 0 );
tdsdump_log(TDS_DBG_ERROR, "IP address pointer is empty\n");
if (!tds_dstr_isempty(&connection->server_name)) {
tdsdump_log(TDS_DBG_ERROR, "Server %s not found!\n", tds_dstr_cstr(&connection->server_name));
} else {
tdsdump_log(TDS_DBG_ERROR, "No server specified!\n");
}
return TDSECONN;
}
+ if (connection->port && !tds_dstr_isempty(&connection->instance_name)) {
+ tdserror(tds->tds_ctx, tds, TDSEPORTINSTANCE, 0);
+ return TDSECONN;
+ }
+
if (!IS_TDS50(tds) && !tds_dstr_isempty(&connection->instance_name))
connection->port = tds7_get_instance_port(tds_dstr_cstr(&connection->ip_addr), tds_dstr_cstr(&connection->instance_name));
if (connection->port < 1) {
tdsdump_log(TDS_DBG_ERROR, "invalid port number\n");
return TDSECONN;
}
memcpy(tds->capabilities, connection->capabilities, TDS_MAX_CAPABILITY);
Index: src/tds/mem.c
===================================================================
RCS file: /cvs/freetds/freetds/src/tds/mem.c,v
retrieving revision 1.193
diff -U 10 -r1.193 mem.c
--- src/tds/mem.c 26 Nov 2009 09:47:41 -0000 1.193
+++ src/tds/mem.c 13 Dec 2009 08:13:57 -0000
@@ -806,21 +806,20 @@
tds_dstr_init(&connection->ip_addr);
tds_dstr_init(&connection->database);
tds_dstr_init(&connection->dump_file);
tds_dstr_init(&connection->client_charset);
tds_dstr_init(&connection->instance_name);
/* fill in all hardcoded defaults */
if (!tds_dstr_copy(&connection->server_name, TDS_DEF_SERVER))
goto Cleanup;
connection->tds_version = TDS_DEFAULT_VERSION;
- connection->port = TDS_DEF_PORT;
connection->block_size = 0;
/* TODO use system default ?? */
if (!tds_dstr_copy(&connection->client_charset, "ISO-8859-1"))
goto Cleanup;
if (locale) {
if (locale->language)
if (!tds_dstr_copy(&connection->language, locale->language))
goto Cleanup;
if (locale->server_charset)
if (!tds_dstr_copy(&connection->server_charset, locale->server_charset))
Index: src/tds/util.c
===================================================================
RCS file: /cvs/freetds/freetds/src/tds/util.c,v
retrieving revision 1.87
diff -U 10 -r1.87 util.c
--- src/tds/util.c 25 Aug 2009 14:25:35 -0000 1.87
+++ src/tds/util.c 13 Dec 2009 08:13:57 -0000
@@ -248,20 +248,21 @@
static const TDS_ERROR_MESSAGE tds_error_messages[] =
{ { TDSEICONVIU, EXCONVERSION, "Buffer exhausted converting characters from client into server's character set" }
, { TDSEICONVAVAIL, EXCONVERSION, "Character set conversion is not available between client character set '%.*s' and "
"server character set '%.*s'" }
, { TDSEICONVO, EXCONVERSION, "Error converting characters into server's character set. Some character(s) could "
"not be converted" }
, { TDSEICONVI, EXCONVERSION, "Some character(s) could not be converted into client's character set. "
"Unconverted bytes were changed to question marks ('?')" }
, { TDSEICONV2BIG, EXCONVERSION, "Some character(s) could not be converted into client's character set" }
+ , { TDSEPORTINSTANCE, EXCOMM, "Both port and instance specified" }
, { TDSERPND, EXPROGRAM, "Attempt to initiate a new Adaptive Server operation with results pending" }
, { TDSEBTOK, EXCOMM, "Bad token from the server: Datastream processing out of sync" }
, { TDSECAP, EXCOMM, "DB-Library capabilities not accepted by the Server" }
, { TDSECAPTYP, EXCOMM, "Unexpected capability type in CAPABILITY datastream" }
, { TDSECLOS, EXCOMM, "Error in closing network connection" }
, { TDSECONN, EXCOMM, "Unable to connect: Adaptive Server is unavailable or does not exist" }
, { TDSEEUNR, EXCOMM, "Unsolicited event notification received" }
, { TDSEFCON, EXCOMM, "Adaptive Server connection failed" }
, { TDSENEG, EXCOMM, "Negotiated login attempt failed" }
, { TDSEOOB, EXCOMM, "Error in sending out-of-band data to the server" }
-
[freetds] Dreaded "Server SYBASE not found!" question,
Nelson, Erik - 2, 12/11/2009
- Re: [freetds] Dreaded "Server SYBASE not found!" question [SOLVED], Nelson, Erik - 2, 12/11/2009
-
Re: [freetds] Dreaded "Server SYBASE not found!" question,
James K. Lowden, 12/12/2009
- Re: [freetds] Dreaded "Server SYBASE not found!" question, Frediano Ziglio, 12/13/2009
- Re: [freetds] Dreaded "Server SYBASE not found!" question, Frediano Ziglio, 12/16/2009
Archive powered by MHonArc 2.6.24.