Re: Dreaded "Server SYBASE not found!" question
Frediano Ziglio <[email protected]>
| Newsgroups | gmane.comp.db.tds.freetds |
|---|---|
| Message-ID | <1260692593.5010.59.camel@freddy> |
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 _______________________________________________ FreeTDS mailing list [email protected] http://lists.ibiblio.org/mailman/listinfo/freetds
vedi.diff
(text/x-patch, 7.7 KB)
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" }