]> granicus.if.org Git - postgresql/blob - src/interfaces/odbc/drvconn.c
Version 06-30-0248
[postgresql] / src / interfaces / odbc / drvconn.c
1
2 /* Module:          drvconn.c
3  *
4  * Description:     This module contains only routines related to 
5  *                  implementing SQLDriverConnect.
6  *
7  * Classes:         n/a
8  *
9  * API functions:   SQLDriverConnect
10  *
11  * Comments:        See "notice.txt" for copyright and license information.
12  *
13  */
14
15 #ifdef HAVE_CONFIG_H
16 #include <config.h>
17 #endif
18
19 #include <stdio.h>
20 #include <stdlib.h>
21
22 #include "psqlodbc.h"
23 #include "connection.h"
24
25 #ifdef UNIX
26 #include <sys/types.h>
27 #include <sys/socket.h>
28 #define NEAR
29 #else
30 #include <winsock.h>
31 #include <sqlext.h>
32 #endif
33
34 #include <string.h>
35
36 #ifdef UNIX
37 #define stricmp(s1,s2)  strcasecmp(s1,s2)
38 #define strnicmp(s1,s2,n)       strncasecmp(s1,s2,n)
39 #else
40 #include <windows.h>
41 #include <windowsx.h>
42 #include <odbcinst.h>
43 #include "resource.h"
44 #endif
45
46 #ifndef TRUE
47 #define TRUE    (BOOL)1
48 #endif
49 #ifndef FALSE
50 #define FALSE   (BOOL)0
51 #endif
52
53 #include "dlg_specific.h"
54
55 /* prototypes */
56 void dconn_get_connect_attributes(UCHAR FAR *connect_string, ConnInfo *ci);
57
58 #ifndef UNIX    /* should be something like ifdef WINDOWS */
59 BOOL FAR PASCAL dconn_FDriverConnectProc(HWND hdlg, UINT wMsg, WPARAM wParam, LPARAM lParam);
60 RETCODE dconn_DoDialog(HWND hwnd, ConnInfo *ci);
61
62 extern HINSTANCE NEAR s_hModule;               /* Saved module handle. */
63 #endif
64
65 extern GLOBAL_VALUES globals;
66
67
68 RETCODE SQL_API SQLDriverConnect(
69                                  HDBC      hdbc,
70                                  HWND      hwnd,
71                                  UCHAR FAR *szConnStrIn,
72                                  SWORD     cbConnStrIn,
73                                  UCHAR FAR *szConnStrOut,
74                                  SWORD     cbConnStrOutMax,
75                                  SWORD FAR *pcbConnStrOut,
76                                  UWORD     fDriverCompletion)
77 {
78 char *func = "SQLDriverConnect";
79 ConnectionClass *conn = (ConnectionClass *) hdbc;
80 ConnInfo *ci;
81 RETCODE dialog_result;
82 char connStrIn[MAX_CONNECT_STRING];
83 char connStrOut[MAX_CONNECT_STRING];
84 int retval;
85 char password_required = FALSE;
86
87         if ( ! conn) {
88                 CC_log_error(func, "", NULL);
89                 return SQL_INVALID_HANDLE;
90         }
91
92         make_string(szConnStrIn, cbConnStrIn, connStrIn);
93
94         mylog("**** SQLDriverConnect: fDriverCompletion=%d, connStrIn='%s'\n", fDriverCompletion, connStrIn);
95         qlog("conn=%u, SQLDriverConnect( in)='%s', fDriverCompletion=%d\n", conn, connStrIn, fDriverCompletion);
96
97         ci = &(conn->connInfo);
98
99         //      Parse the connect string and fill in conninfo for this hdbc.
100         dconn_get_connect_attributes(connStrIn, ci);
101
102         //      If the ConnInfo in the hdbc is missing anything,
103         //      this function will fill them in from the registry (assuming
104         //      of course there is a DSN given -- if not, it does nothing!)
105         getDSNinfo(ci, CONN_DONT_OVERWRITE);
106
107         //      Fill in any default parameters if they are not there.
108         getDSNdefaults(ci);
109
110 dialog:
111         ci->focus_password = password_required;
112
113         switch(fDriverCompletion) {
114 #ifndef UNIX    /* again should be ifdef WINDOWS like */
115         case SQL_DRIVER_PROMPT:
116                 dialog_result = dconn_DoDialog(hwnd, ci);
117                 if(dialog_result != SQL_SUCCESS) {
118                         return dialog_result;
119                 }
120                 break;
121
122         case SQL_DRIVER_COMPLETE_REQUIRED:
123
124                 /*      Fall through */
125
126         case SQL_DRIVER_COMPLETE:
127
128                 /* Password is not a required parameter. */
129                 if( ci->username[0] == '\0' ||
130                         ci->server[0] == '\0' ||
131                         ci->database[0] == '\0' ||
132                         ci->port[0] == '\0' ||
133                         password_required) { 
134
135                         dialog_result = dconn_DoDialog(hwnd, ci);
136                         if(dialog_result != SQL_SUCCESS) {
137                                 return dialog_result;
138                         }
139                 }
140                 break;
141 #else
142         case SQL_DRIVER_PROMPT:
143         case SQL_DRIVER_COMPLETE:
144         case SQL_DRIVER_COMPLETE_REQUIRED:
145 #endif
146         case SQL_DRIVER_NOPROMPT:
147                 break;
148         }
149
150         /*      Password is not a required parameter unless authentication asks for it.
151                 For now, I think its better to just let the application ask over and over until
152                 a password is entered (the user can always hit Cancel to get out)
153         */
154         if( ci->username[0] == '\0' ||
155                 ci->server[0] == '\0' ||
156                 ci->database[0] == '\0' || 
157                 ci->port[0] == '\0') {
158 //              (password_required && ci->password[0] == '\0'))
159
160                 return SQL_NO_DATA_FOUND;
161         }
162
163         if(szConnStrOut) {
164
165                 /*      Return the completed string to the caller.
166                         Only construct the connect string if a dialog was put up,
167                         otherwise, just copy the connection input string to the output.
168                 */
169                 makeConnectString(connStrOut, ci);
170
171                 if(pcbConnStrOut) {
172                         *pcbConnStrOut = strlen(connStrOut);
173                 }
174                 strncpy_null(szConnStrOut, connStrOut, cbConnStrOutMax);
175         }
176
177         mylog("szConnStrOut = '%s'\n", szConnStrOut);
178         qlog("conn=%u, SQLDriverConnect(out)='%s'\n", conn, szConnStrOut);
179
180         // do the actual connect
181         retval = CC_connect(conn, password_required);
182         if (retval < 0) {               /* need a password */
183                 if (fDriverCompletion == SQL_DRIVER_NOPROMPT) {
184                         CC_log_error(func, "Need password but Driver_NoPrompt", conn);
185                         return SQL_ERROR;       /* need a password but not allowed to prompt so error */
186                 }
187                 else {
188 #ifndef UNIX
189                         password_required = TRUE;
190                         goto dialog;
191 #else
192                         return SQL_ERROR;       /* until a better solution is found. */
193 #endif
194                 }
195         }
196         else if (retval == 0) {
197                 //      error msg filled in above
198                 CC_log_error(func, "Error from CC_Connect", conn);
199                 return SQL_ERROR;
200         }
201
202         mylog("SQLDRiverConnect: returning success\n");
203         return SQL_SUCCESS;
204 }
205
206 #ifndef UNIX    /* yet another candidate for ifdef WINDOWS */
207 RETCODE dconn_DoDialog(HWND hwnd, ConnInfo *ci)
208 {
209 int dialog_result;
210
211 mylog("dconn_DoDialog: ci = %u\n", ci);
212
213         if(hwnd) {
214                 dialog_result = DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_CONFIG),
215                                                                         hwnd, dconn_FDriverConnectProc, (LPARAM) ci);
216                 if(!dialog_result || (dialog_result == -1)) {
217                         return SQL_NO_DATA_FOUND;
218                 } else {
219                         return SQL_SUCCESS;
220                 }
221         }
222
223         return SQL_ERROR;
224 }
225
226
227 BOOL FAR PASCAL dconn_FDriverConnectProc(
228                                          HWND    hdlg,
229                                          UINT    wMsg,
230                                          WPARAM  wParam,
231                                          LPARAM  lParam)
232 {
233 ConnInfo *ci;
234
235         switch (wMsg) {
236         case WM_INITDIALOG:
237                 ci = (ConnInfo *) lParam;               
238
239                 /*      Change the caption for the setup dialog */
240                 SetWindowText(hdlg, "PostgreSQL Connection");
241
242                 SetWindowText(GetDlgItem(hdlg, IDC_DATASOURCE), "Connection");
243
244                 /*      Hide the DSN and description fields */
245                 ShowWindow(GetDlgItem(hdlg, IDC_DSNAMETEXT), SW_HIDE);
246                 ShowWindow(GetDlgItem(hdlg, IDC_DSNAME), SW_HIDE);
247                 ShowWindow(GetDlgItem(hdlg, IDC_DESCTEXT), SW_HIDE);
248                 ShowWindow(GetDlgItem(hdlg, IDC_DESC), SW_HIDE);
249
250                 SetWindowLong(hdlg, DWL_USER, lParam);// Save the ConnInfo for the "OK"
251
252                 SetDlgStuff(hdlg, ci);
253
254                 if (ci->database[0] == '\0')            
255                         ;       /* default focus */
256                 else if (ci->server[0] == '\0')
257                         SetFocus(GetDlgItem(hdlg, IDC_SERVER));
258                 else if (ci->port[0] == '\0')
259                         SetFocus(GetDlgItem(hdlg, IDC_PORT));
260                 else if (ci->username[0] == '\0')
261                         SetFocus(GetDlgItem(hdlg, IDC_USER));
262                 else if (ci->focus_password)
263                         SetFocus(GetDlgItem(hdlg, IDC_PASSWORD));
264
265
266                 break; 
267
268         case WM_COMMAND:
269                 switch (GET_WM_COMMAND_ID(wParam, lParam)) {
270                 case IDOK:
271
272                         ci = (ConnInfo *) GetWindowLong(hdlg, DWL_USER);
273
274                         GetDlgStuff(hdlg, ci);
275
276
277                 case IDCANCEL:
278                         EndDialog(hdlg, GET_WM_COMMAND_ID(wParam, lParam) == IDOK);
279                         return TRUE;
280
281                 case IDC_DRIVER:
282
283                         DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_OPTIONS_DRV),
284                                                                         hdlg, driver_optionsProc, (LPARAM) NULL);
285
286
287                         break;
288
289                 case IDC_DATASOURCE:
290
291                         ci = (ConnInfo *) GetWindowLong(hdlg, DWL_USER);
292                         DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_OPTIONS_DS),
293                                                                         hdlg, ds_optionsProc, (LPARAM) ci);
294
295                         break;
296                 }
297         }
298
299         return FALSE;
300 }
301
302 #endif  /* ! UNIX */
303
304 void dconn_get_connect_attributes(UCHAR FAR *connect_string, ConnInfo *ci)
305 {
306 char *our_connect_string;
307 char *pair, *attribute, *value, *equals;
308 char *strtok_arg;
309
310         memset(ci, 0, sizeof(ConnInfo));
311
312         our_connect_string = strdup(connect_string);
313         strtok_arg = our_connect_string;
314
315         mylog("our_connect_string = '%s'\n", our_connect_string);
316
317         while(1) {
318                 pair = strtok(strtok_arg, ";");
319                 if(strtok_arg) {
320                         strtok_arg = 0;
321                 }
322                 if(!pair) {
323                         break;
324                 }
325
326                 equals = strchr(pair, '=');
327                 if ( ! equals)
328                         continue;
329
330                 *equals = '\0';
331                 attribute = pair;               //      ex. DSN
332                 value = equals + 1;             //      ex. 'CEO co1'
333
334                 mylog("attribute = '%s', value = '%s'\n", attribute, value);
335
336                 if( !attribute || !value)
337                         continue;          
338
339                 //      Copy the appropriate value to the conninfo 
340                 copyAttributes(ci, attribute, value);
341
342         }
343
344
345         free(our_connect_string);
346 }
347