Re: FreeTDS & Sybase SQL Anywhere 11

Frediano Ziglio <[email protected]>
Newsgroups gmane.comp.db.tds.freetds
Message-ID <[email protected]>
2009/12/21 Michal Seliga <[email protected]>:
>
>
> On 21. 12. 2009 10:58, Frediano Ziglio wrote:
>> 2009/12/21 Michal Seliga <[email protected]>:
>>>
>>>
>>> On 19. 12. 2009 4:56, James K. Lowden wrote:
>>>> Michal Seliga wrote:
>>>>>
>>>>> - always when i close database connection server reports:
>>>>> Connection terminated abnormally
>>>>> Disconnected TCPIP client's AppInfo: HOST=visibuntu;PID=1906
>>>>> however freetds & odbc don't seem to detect any problem (according to
>>>>> logs)
>>>>
>>>> Which API are you using?  Does it happen with bsqldb/bsqlodbc/tsql/sqsh?
>>>  yes, with tsql it happens too
>>>> A TDSDUMP log of the session would help.  If all applications produce the
>>>> same error, a tcpdump(8) log might be helpful, too, but don't post that
>>>> until we know we need it.
>>>  tdsdump is attached (freetds.log.gz)
>>>  if it will come to tcpdump please write me what you want me to set, i saw it
>>> has really lot of switches....
>> ...
>>
>> Mmm.. you login and after 2 seconds close tsql, right ??
> right, but its only for test to have log short. it happens also when i do some
> actions in session
>

Please try this patch (apply to CVS HEAD). I cannot test it (my server
does not detect this problem).

freddy77

>> Probably ASA 11 wants the LOGOUT token which we don't send. I would
>> add a tds_disconnect which would send TDS_LOGOUT token and that close
>> connection. I noted that we have
>> - tds_connect_and_login (login.c) which connect and manage login
>> - tds_connect (net.c) which is a small tds_open_socket wrapper
>> - tds_close_socket (net.c) which disconnect socket
>> - tds_open_socket (net.c) which connect the socket
>> Perhaps tds_disconnect is a bad name... a tds_logout is better but we
>> would probably like to have a symmetric tds_login.
>> tds_connect_and_login calls tds_send_login, tds7_send_login and
>> tds8_do_login but are all static function. Perhaps a
>> tds_logout_and_disconnect would be a perfect name. This function
>> should be called before every tds_free_socket function.
>>
>> freddy77
>> _______________________________________________
>> FreeTDS mailing list
>> [email protected]
>> http://lists.ibiblio.org/mailman/listinfo/freetds
> _______________________________________________
> FreeTDS mailing list
> [email protected]
> http://lists.ibiblio.org/mailman/listinfo/freetds
>

_______________________________________________
FreeTDS mailing list
[email protected]
http://lists.ibiblio.org/mailman/listinfo/freetds
vedi.diff (application/octet-stream, 3.5 KB)
Index: include/tds.h
===================================================================
RCS file: /cvs/freetds/freetds/include/tds.h,v
retrieving revision 1.323
diff -u -1 -0 -p -r1.323 tds.h
--- include/tds.h	26 Nov 2009 09:47:41 -0000	1.323
+++ include/tds.h	21 Dec 2009 11:33:50 -0000
@@ -1473,20 +1473,21 @@ void tds_set_bulk(TDSLOGIN * tds_login, 
 void tds_set_user(TDSLOGIN * tds_login, const char *username);
 void tds_set_app(TDSLOGIN * tds_login, const char *application);
 void tds_set_host(TDSLOGIN * tds_login, const char *hostname);
 void tds_set_library(TDSLOGIN * tds_login, const char *library);
 void tds_set_server(TDSLOGIN * tds_login, const char *server);
 void tds_set_client_charset(TDSLOGIN * tds_login, const char *charset);
 void tds_set_language(TDSLOGIN * tds_login, const char *language);
 void tds_set_version(TDSLOGIN * tds_login, TDS_TINYINT major_ver, TDS_TINYINT minor_ver);
 void tds_set_capabilities(TDSLOGIN * tds_login, unsigned char *capabilities, int size);
 int tds_connect_and_login(TDSSOCKET * tds, TDSCONNECTION * connection);
+int tds_logout_and_disconnect(TDSSOCKET * tds);
 
 /* query.c */
 int tds_submit_query(TDSSOCKET * tds, const char *query);
 int tds_submit_query_params(TDSSOCKET * tds, const char *query, TDSPARAMINFO * params);
 int tds_submit_queryf(TDSSOCKET * tds, const char *queryf, ...);
 int tds_submit_prepare(TDSSOCKET * tds, const char *query, const char *id, TDSDYNAMIC ** dyn_out, TDSPARAMINFO * params);
 int tds_submit_execdirect(TDSSOCKET * tds, const char *query, TDSPARAMINFO * params);
 int tds_submit_execute(TDSSOCKET * tds, TDSDYNAMIC * dyn);
 int tds_send_cancel(TDSSOCKET * tds);
 const char *tds_next_placeholder(const char *start);
Index: src/apps/tsql.c
===================================================================
RCS file: /cvs/freetds/freetds/src/apps/tsql.c,v
retrieving revision 1.130
diff -u -1 -0 -p -r1.130 tsql.c
--- src/apps/tsql.c	5 Dec 2009 20:25:31 -0000	1.130
+++ src/apps/tsql.c	21 Dec 2009 11:33:50 -0000
@@ -846,17 +846,18 @@ main(int argc, char **argv)
 			tsql_add_history(s);
 			strcpy(mybuf + buflen, s);
 			/* preserve line numbering for the parser */
 			strcat(mybuf + buflen, "\n");
 			buflen += strlen(mybuf + buflen);
 		}
 	}
 
 	/* close up shop */
 	free(mybuf);
+	tds_logout_and_disconnect(tds);
 	tds_free_socket(tds);
 	tds_free_login(login);
 	tds_free_context(context);
 	DONESOCKET();
 
 	return 0;
 }
Index: src/tds/login.c
===================================================================
RCS file: /cvs/freetds/freetds/src/tds/login.c,v
retrieving revision 1.191
diff -u -1 -0 -p -r1.191 login.c
--- src/tds/login.c	2 Dec 2009 22:58:21 -0000	1.191
+++ src/tds/login.c	21 Dec 2009 11:33:50 -0000
@@ -488,20 +488,34 @@ tds_connect_and_login(TDSSOCKET * tds, T
 
 		if (tds_process_simple_query(tds) != TDS_SUCCEED)
 			return TDS_FAIL;
 	}
 
 	tds->query_timeout = connection->query_timeout;
 	tds->connection = NULL;
 	return TDS_SUCCEED;
 }
 
+int
+tds_logout_and_disconnect(TDSSOCKET *tds)
+{
+	if (IS_TDS50(tds) && tds_set_state(tds, TDS_QUERYING) == TDS_QUERYING) {
+		tds_put_byte(tds, TDS_LOGOUT_TOKEN);
+		tds_put_byte(tds, 0);
+		tds_flush_packet(tds);
+	}
+	
+	if (tds_close_socket(tds) < 0)
+		return TDS_FAIL;
+	return TDS_SUCCEED;
+}
+
 static int
 tds_put_login_string(TDSSOCKET * tds, const char *buf, int n)
 {
 	const int buf_len = buf ? (int)strlen(buf) : 0;
 	return tds_put_buf(tds, (const unsigned char *) buf, n, buf_len);
 }
 
 static int
 tds_send_login(TDSSOCKET * tds, TDSCONNECTION * connection)
 {
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.