1 #include "common.h"
2 
3 
4 static void init_connect(void);
5 
6 static void
init_connect(void)7 init_connect(void)
8 {
9 	CHKAllocEnv(&odbc_env, "S");
10 	CHKAllocConnect(&odbc_conn, "S");
11 }
12 
13 #ifdef _WIN32
14 #include <odbcinst.h>
15 
16 static char *entry = NULL;
17 
18 static char *
get_entry(const char * key)19 get_entry(const char *key)
20 {
21 	static TCHAR buf[256];
22 
23 	entry = NULL;
24 	if (SQLGetPrivateProfileString(T(odbc_server), T(key), TEXT(""), buf, TDS_VECTOR_SIZE(buf), TEXT("odbc.ini")) > 0)
25 		entry = C(buf);
26 
27 	return entry;
28 }
29 #endif
30 
31 int
main(int argc,char * argv[])32 main(int argc, char *argv[])
33 {
34 	char tmp[1024*4];
35 	SQLSMALLINT len;
36 	int succeeded = 0;
37 	int is_freetds = 1;
38 	int is_ms;
39 	SQLRETURN rc;
40 
41 	if (odbc_read_login_info())
42 		exit(1);
43 
44 	/*
45 	 * prepare our odbcinst.ini
46 	 * is better to do it before connect cause uniODBC cache INIs
47 	 * the name must be odbcinst.ini cause unixODBC accept only this name
48 	 */
49 	if (odbc_driver[0]) {
50 		FILE *f = fopen("odbcinst.ini", "w");
51 
52 		if (f) {
53 			fprintf(f, "[FreeTDS]\nDriver = %s\n", odbc_driver);
54 			fclose(f);
55 			/* force iODBC */
56 			setenv("ODBCINSTINI", "./odbcinst.ini", 1);
57 			setenv("SYSODBCINSTINI", "./odbcinst.ini", 1);
58 			/* force unixODBC (only directory) */
59 			setenv("ODBCSYSINI", ".", 1);
60 		}
61 	}
62 
63 	printf("SQLConnect connect..\n");
64 	odbc_connect();
65 	if (!odbc_driver_is_freetds())
66 		is_freetds = 0;
67 	is_ms = odbc_db_is_microsoft();
68 	odbc_disconnect();
69 	++succeeded;
70 
71 	if (!is_freetds) {
72 		printf("Driver is not FreeTDS, exiting\n");
73 		return 0;
74 	}
75 
76 	/* try connect string with using DSN */
77 	printf("connect string DSN connect..\n");
78 	init_connect();
79 	sprintf(tmp, "DSN=%s;UID=%s;PWD=%s;DATABASE=%s;", odbc_server, odbc_user, odbc_password, odbc_database);
80 	CHKDriverConnect(NULL, T(tmp), SQL_NTS, (SQLTCHAR *) tmp, sizeof(tmp)/sizeof(SQLTCHAR), &len, SQL_DRIVER_NOPROMPT, "SI");
81 	odbc_disconnect();
82 	++succeeded;
83 
84 	/* try connect string using old SERVERNAME specification */
85 	printf("connect string SERVERNAME connect..\n");
86 	printf("odbcinst.ini must be configured with FreeTDS driver..\n");
87 
88 	/* this is expected to work with unixODBC */
89 	init_connect();
90 	sprintf(tmp, "DRIVER=FreeTDS;SERVERNAME=%s;UID=%s;PWD=%s;DATABASE=%s;", odbc_server, odbc_user, odbc_password, odbc_database);
91 	rc = CHKDriverConnect(NULL, T(tmp), SQL_NTS, (SQLTCHAR *) tmp, sizeof(tmp)/sizeof(SQLTCHAR), &len, SQL_DRIVER_NOPROMPT, "SIE");
92 	if (rc == SQL_ERROR) {
93 		printf("Unable to open data source (ret=%d)\n", rc);
94 	} else {
95 		++succeeded;
96 	}
97 	odbc_disconnect();
98 
99 	/* this is expected to work with iODBC
100 	 * (passing shared object name as driver)
101 	 */
102 	if (odbc_driver[0]) {
103 		init_connect();
104 		sprintf(tmp, "DRIVER=%s;SERVERNAME=%s;UID=%s;PWD=%s;DATABASE=%s;", odbc_driver, odbc_server, odbc_user, odbc_password, odbc_database);
105 		rc = CHKDriverConnect(NULL, T(tmp), SQL_NTS, (SQLTCHAR *) tmp, sizeof(tmp)/sizeof(SQLTCHAR), &len, SQL_DRIVER_NOPROMPT, "SIE");
106 		if (rc == SQL_ERROR) {
107 			printf("Unable to open data source (ret=%d)\n", rc);
108 		} else {
109 			++succeeded;
110 		}
111 		odbc_disconnect();
112 	}
113 
114 #ifdef _WIN32
115 	if (get_entry("SERVER")) {
116 		init_connect();
117 		sprintf(tmp, "DRIVER=FreeTDS;SERVER=%s;UID=%s;PWD=%s;DATABASE=%s;", entry, odbc_user, odbc_password, odbc_database);
118 		if (get_entry("TDS_Version"))
119 			sprintf(strchr(tmp, 0), "TDS_Version=%s;", entry);
120 		if (get_entry("Port"))
121 			sprintf(strchr(tmp, 0), "Port=%s;", entry);
122 		rc = CHKDriverConnect(NULL, T(tmp), SQL_NTS, (SQLTCHAR *) tmp, sizeof(tmp)/sizeof(SQLTCHAR), &len, SQL_DRIVER_NOPROMPT, "SIE");
123 		if (rc == SQL_ERROR) {
124 			printf("Unable to open data source (ret=%d)\n", rc);
125 		} else {
126 			++succeeded;
127 		}
128 		odbc_disconnect();
129 	}
130 #endif
131 
132 	if (is_ms) {
133 		char app_name[130];
134 		memset(app_name, 'a', sizeof(app_name));
135 		app_name[sizeof(app_name) - 1] = 0;
136 
137 		/* Try passing very long APP string.
138 		 * The server is supposed to fail the connection if
139 		 * this string is too long, make sure we trucate it.
140 		 */
141 		printf("connect string DSN connect with a long APP..\n");
142 		init_connect();
143 		sprintf(tmp, "DSN=%s;UID=%s;PWD=%s;DATABASE=%s;APP=%s", odbc_server, odbc_user, odbc_password, odbc_database, app_name);
144 		CHKDriverConnect(NULL, T(tmp), SQL_NTS, (SQLTCHAR *) tmp, sizeof(tmp)/sizeof(SQLTCHAR), &len, SQL_DRIVER_NOPROMPT, "SI");
145 		odbc_disconnect();
146 	}
147 
148 	/* at least one should success.. */
149 	if (succeeded < 3) {
150 		ODBC_REPORT_ERROR("Too few successes");
151 		exit(1);
152 	}
153 
154 	printf("Done.\n");
155 	return 0;
156 }
157