1/* 2 * SQLGetTranslator.c 3 * 4 * $Id: SQLGetTranslator.c,v 1.14 2006/01/20 15:58:35 source Exp $ 5 * 6 * These functions intentionally left blank 7 * 8 * The iODBC driver manager. 9 * 10 * Copyright (C) 1996-2006 by OpenLink Software <iodbc@openlinksw.com> 11 * All Rights Reserved. 12 * 13 * This software is released under the terms of either of the following 14 * licenses: 15 * 16 * - GNU Library General Public License (see LICENSE.LGPL) 17 * - The BSD License (see LICENSE.BSD). 18 * 19 * Note that the only valid version of the LGPL license as far as this 20 * project is concerned is the original GNU Library General Public License 21 * Version 2, dated June 1991. 22 * 23 * While not mandated by the BSD license, any patches you make to the 24 * iODBC source code may be contributed back into the iODBC project 25 * at your discretion. Contributions will benefit the Open Source and 26 * Data Access community as a whole. Submissions may be made at: 27 * 28 * http://www.iodbc.org 29 * 30 * 31 * GNU Library Generic Public License Version 2 32 * ============================================ 33 * This library is free software; you can redistribute it and/or 34 * modify it under the terms of the GNU Library General Public 35 * License as published by the Free Software Foundation; only 36 * Version 2 of the License dated June 1991. 37 * 38 * This library is distributed in the hope that it will be useful, 39 * but WITHOUT ANY WARRANTY; without even the implied warranty of 40 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 41 * Library General Public License for more details. 42 * 43 * You should have received a copy of the GNU Library General Public 44 * License along with this library; if not, write to the Free 45 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 46 * 47 * 48 * The BSD License 49 * =============== 50 * Redistribution and use in source and binary forms, with or without 51 * modification, are permitted provided that the following conditions 52 * are met: 53 * 54 * 1. Redistributions of source code must retain the above copyright 55 * notice, this list of conditions and the following disclaimer. 56 * 2. Redistributions in binary form must reproduce the above copyright 57 * notice, this list of conditions and the following disclaimer in 58 * the documentation and/or other materials provided with the 59 * distribution. 60 * 3. Neither the name of OpenLink Software Inc. nor the names of its 61 * contributors may be used to endorse or promote products derived 62 * from this software without specific prior written permission. 63 * 64 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 65 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 66 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 67 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL OPENLINK OR 68 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 69 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 70 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 71 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 72 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 73 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 74 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 75 */ 76 77 78#include <iodbc.h> 79#include <odbcinst.h> 80#include <iodbcadm.h> 81#include <unicode.h> 82 83#include "dlf.h" 84#include "inifile.h" 85#include "misc.h" 86#include "iodbc_error.h" 87 88#if defined (__APPLE__) && !(defined (NO_FRAMEWORKS) || defined (_LP64)) 89#include <Carbon/Carbon.h> 90#endif 91 92#ifndef WIN32 93#include <unistd.h> 94#define CALL_CONFIG_TRANSLATOR(path) \ 95 if ((handle = DLL_OPEN(path)) != NULL) \ 96 { \ 97 if ((pConfigTranslator = (pConfigTranslatorFunc)DLL_PROC(handle, "ConfigTranslator")) != NULL) \ 98 { \ 99 if (pConfigTranslator(hwndParent, pvOption)) \ 100 { \ 101 DLL_CLOSE(handle); \ 102 finish = retcode = TRUE; \ 103 goto done; \ 104 } \ 105 else \ 106 { \ 107 PUSH_ERROR(ODBC_ERROR_GENERAL_ERR); \ 108 DLL_CLOSE(handle); \ 109 retcode = FALSE; \ 110 goto done; \ 111 } \ 112 } \ 113 DLL_CLOSE(handle); \ 114 } 115 116#define CALL_TRSCHOOSE_DIALBOX(path) \ 117 if ((handle = DLL_OPEN(path)) != NULL) \ 118 { \ 119 if ((pTrsChoose = (pTrsChooseFunc)DLL_PROC(handle, "_iodbcdm_trschoose_dialbox")) != NULL) \ 120 ret = pTrsChoose(hwndParent, translator, sizeof(translator), NULL); \ 121 else ret = SQL_NO_DATA; \ 122 DLL_CLOSE(handle); \ 123 } \ 124 else ret = SQL_NO_DATA; 125#endif 126 127extern SQLRETURN _iodbcdm_trschoose_dialbox (HWND, LPSTR, DWORD, int *); 128 129BOOL INSTAPI 130GetTranslator (HWND hwndParent, LPSTR lpszName, WORD cbNameMax, 131 WORD * pcbNameOut, LPSTR lpszPath, WORD cbPathMax, 132 WORD * pcbPathOut, DWORD * pvOption) 133{ 134 pConfigTranslatorFunc pConfigTranslator; 135 pTrsChooseFunc pTrsChoose; 136 BOOL retcode = FALSE, finish = FALSE; 137 PCONFIG pCfg; 138 UWORD configMode; 139 RETCODE ret = SQL_NO_DATA; 140 void *handle; 141 char translator[1024]; 142#if defined (__APPLE__) && !(defined (NO_FRAMEWORKS) || defined (_LP64)) 143 CFStringRef libname = NULL; 144 CFBundleRef bundle; 145 CFURLRef liburl; 146 char name[1024] = { 0 }; 147#endif 148 149 do 150 { 151 /* Load the Admin dialbox function */ 152#if defined (__APPLE__) && !(defined (NO_FRAMEWORKS) || defined (_LP64)) 153 bundle = CFBundleGetBundleWithIdentifier (CFSTR ("org.iodbc.inst")); 154 if (bundle) 155 { 156 /* Search for the iODBCadm library */ 157 liburl = 158 CFBundleCopyResourceURL (bundle, CFSTR ("iODBCadm.bundle"), 159 NULL, NULL); 160 if (liburl 161 && (libname = 162 CFURLCopyFileSystemPath (liburl, kCFURLPOSIXPathStyle))) 163 { 164 CFStringGetCString (libname, name, sizeof (name), 165 kCFStringEncodingASCII); 166 STRCAT (name, "/Contents/MacOS/iODBCadm"); 167 CALL_TRSCHOOSE_DIALBOX (name); 168 } 169 if (liburl) 170 CFRelease (liburl); 171 if (libname) 172 CFRelease (libname); 173 } 174#else 175 CALL_TRSCHOOSE_DIALBOX ("libiodbcadm.so"); 176#endif 177 178 if (ret == SQL_NO_DATA) 179 { 180 if (pcbNameOut) 181 *pcbNameOut = 0; 182 if (pcbPathOut) 183 *pcbPathOut = 0; 184 finish = TRUE; 185 } 186 187 if (ret == SQL_SUCCESS) 188 { 189 STRNCPY (lpszName, translator + STRLEN ("TranslationName="), 190 cbNameMax - 1); 191 if (pcbNameOut) 192 *pcbNameOut = STRLEN (lpszName); 193 194 /* Get it from the user odbcinst file */ 195 wSystemDSN = USERDSN_ONLY; 196 if (!_iodbcdm_cfg_search_init (&pCfg, "odbcinst.ini", TRUE)) 197 { 198 if (!_iodbcdm_cfg_find (pCfg, (char *) lpszName, "Setup")) 199 CALL_CONFIG_TRANSLATOR (pCfg->value); 200 if (!_iodbcdm_cfg_find (pCfg, (char *) lpszName, "Translator")) 201 CALL_CONFIG_TRANSLATOR (pCfg->value); 202 if (!access (lpszName, X_OK)) 203 CALL_CONFIG_TRANSLATOR (lpszName); 204 if (!_iodbcdm_cfg_find (pCfg, "Default", "Setup")) 205 CALL_CONFIG_TRANSLATOR (pCfg->value); 206 if (!_iodbcdm_cfg_find (pCfg, "Default", "Translator")) 207 CALL_CONFIG_TRANSLATOR (pCfg->value); 208 } 209 210 /* Get it from the system odbcinst file */ 211 if (pCfg) 212 { 213 _iodbcdm_cfg_done (pCfg); 214 pCfg = NULL; 215 } 216 wSystemDSN = SYSTEMDSN_ONLY; 217 if (!_iodbcdm_cfg_search_init (&pCfg, "odbcinst.ini", TRUE)) 218 { 219 if (!_iodbcdm_cfg_find (pCfg, (char *) lpszName, "Setup")) 220 CALL_CONFIG_TRANSLATOR (pCfg->value); 221 if (!_iodbcdm_cfg_find (pCfg, (char *) lpszName, "Translator")) 222 CALL_CONFIG_TRANSLATOR (pCfg->value); 223 if (!access (lpszName, X_OK)) 224 CALL_CONFIG_TRANSLATOR (lpszName); 225 if (!_iodbcdm_cfg_find (pCfg, "Default", "Setup")) 226 CALL_CONFIG_TRANSLATOR (pCfg->value); 227 if (!_iodbcdm_cfg_find (pCfg, "Default", "Translator")) 228 CALL_CONFIG_TRANSLATOR (pCfg->value); 229 } 230 231 /* The last ressort, a proxy driver */ 232 CALL_CONFIG_TRANSLATOR ("libtranslator.so"); 233 234 /* Error : ConfigDSN could no be found */ 235 PUSH_ERROR (ODBC_ERROR_LOAD_LIB_FAILED); 236 237 done: 238 STRNCPY (lpszPath, pCfg->fileName, cbPathMax - 1); 239 if (pcbPathOut) 240 *pcbPathOut = STRLEN (lpszPath); 241 _iodbcdm_cfg_done (pCfg); 242 } 243 } 244 while (!finish); 245 246 retcode = TRUE; 247 248 wSystemDSN = USERDSN_ONLY; 249 configMode = ODBC_BOTH_DSN; 250 251 return retcode; 252} 253 254 255BOOL INSTAPI 256SQLGetTranslator (HWND hwnd, 257 LPSTR lpszName, 258 WORD cbNameMax, 259 WORD * pcbNameOut, 260 LPSTR lpszPath, WORD cbPathMax, WORD * pcbPathOut, DWORD * pvOption) 261{ 262 BOOL retcode = FALSE; 263 264 /* Check input parameters */ 265 CLEAR_ERROR (); 266 if (!hwnd) 267 { 268 PUSH_ERROR (ODBC_ERROR_INVALID_HWND); 269 goto quit; 270 } 271 272 if (!lpszName || !lpszPath || cbNameMax < 1 || cbPathMax < 1) 273 { 274 PUSH_ERROR (ODBC_ERROR_INVALID_BUFF_LEN); 275 goto quit; 276 } 277 278 retcode = GetTranslator (hwnd, lpszName, cbNameMax, pcbNameOut, lpszPath, 279 cbPathMax, pcbPathOut, pvOption); 280 281quit: 282 return retcode; 283} 284 285BOOL INSTAPI 286SQLGetTranslatorW (HWND hwnd, 287 LPWSTR lpszName, 288 WORD cbNameMax, 289 WORD FAR * pcbNameOut, 290 LPWSTR lpszPath, 291 WORD cbPathMax, WORD FAR * pcbPathOut, DWORD FAR * pvOption) 292{ 293 char *_name_u8 = NULL; 294 char *_path_u8 = NULL; 295 BOOL retcode = FALSE; 296 297 if (cbNameMax > 0) 298 { 299 if ((_name_u8 = malloc (cbNameMax * UTF8_MAX_CHAR_LEN + 1)) == NULL) 300 { 301 PUSH_ERROR (ODBC_ERROR_OUT_OF_MEM); 302 goto done; 303 } 304 } 305 306 if (cbPathMax > 0) 307 { 308 if ((_path_u8 = malloc (cbPathMax * UTF8_MAX_CHAR_LEN + 1)) == NULL) 309 { 310 PUSH_ERROR (ODBC_ERROR_OUT_OF_MEM); 311 goto done; 312 } 313 } 314 315 retcode = 316 SQLGetTranslator (hwnd, _name_u8, cbNameMax * UTF8_MAX_CHAR_LEN, 317 pcbNameOut, _path_u8, cbPathMax * UTF8_MAX_CHAR_LEN, pcbPathOut, 318 pvOption); 319 320 if (retcode == TRUE) 321 { 322 dm_StrCopyOut2_U8toW (_name_u8, lpszName, cbNameMax, pcbNameOut); 323 dm_StrCopyOut2_U8toW (_path_u8, lpszPath, cbPathMax, pcbPathOut); 324 } 325 326done: 327 MEM_FREE (_name_u8); 328 MEM_FREE (_path_u8); 329 330 return retcode; 331} 332