1 /*
2  *  SQLInstallTranslatorEx.c
3  *
4  *  $Id$
5  *
6  *  These functions intentionally left blank
7  *
8  *  The iODBC driver manager.
9  *
10  *  Copyright (C) 1996-2021 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 "unicode.h"
81 
82 #include "misc.h"
83 #include "inifile.h"
84 #include "iodbc_error.h"
85 
86 #if !defined(WINDOWS) && !defined(WIN32) && !defined(OS2) && !defined(macintosh)
87 # include <pwd.h>
88 # include <unistd.h>
89 # define UNIX_PWD
90 #endif
91 
92 extern BOOL InstallDriverPath (LPSTR lpszPath, WORD cbPathMax,
93     WORD * pcbPathOut, LPSTR envname);
94 extern BOOL InstallDriverPathLength (WORD * pcbPathOut, LPSTR envname);
95 
96 
97 BOOL INSTAPI
SQLInstallTranslatorEx(LPCSTR lpszTranslator,LPCSTR lpszPathIn,LPSTR lpszPathOut,WORD cbPathOutMax,WORD * pcbPathOut,WORD fRequest,LPDWORD lpdwUsageCount)98 SQLInstallTranslatorEx (LPCSTR lpszTranslator, LPCSTR lpszPathIn,
99     LPSTR lpszPathOut, WORD cbPathOutMax, WORD * pcbPathOut, WORD fRequest,
100     LPDWORD lpdwUsageCount)
101 {
102   PCONFIG pCfg = NULL, pOdbcCfg = NULL;
103   BOOL retcode = FALSE;
104 
105   CLEAR_ERROR ();
106 
107   if (lpszPathIn && access (lpszPathIn, R_OK | W_OK | X_OK))
108     {
109       PUSH_ERROR (ODBC_ERROR_INVALID_PATH);
110       goto quit;
111     }
112 
113   switch (fRequest)
114     {
115     case ODBC_INSTALL_INQUIRY:
116       if (lpszPathIn)
117 	{
118 	  if (pcbPathOut)
119 	    *pcbPathOut = STRLEN (lpszPathIn);
120 	  retcode = TRUE;
121 	}
122       else
123 	retcode = InstallDriverPathLength (pcbPathOut, "ODBCTRANSLATORS");
124       goto quit;
125 
126     case ODBC_INSTALL_COMPLETE:
127       break;
128 
129     default:
130       PUSH_ERROR (ODBC_ERROR_INVALID_REQUEST_TYPE);
131       goto quit;
132     }
133 
134   /* Check input parameters */
135   if (!lpszTranslator || !STRLEN (lpszTranslator))
136     {
137       PUSH_ERROR (ODBC_ERROR_INVALID_PARAM_SEQUENCE);
138       goto quit;
139     }
140 
141   if (!lpszPathOut || !cbPathOutMax)
142     {
143       PUSH_ERROR (ODBC_ERROR_INVALID_BUFF_LEN);
144       goto quit;
145     }
146 
147   /* Write the out path */
148   if (!InstallDriverPath (lpszPathOut, cbPathOutMax, pcbPathOut,
149 	  "ODBCTRANSLATORS"))
150     goto quit;
151 
152   /* Else go through user/system odbcinst.ini */
153   switch (configMode)
154     {
155     case ODBC_BOTH_DSN:
156     case ODBC_USER_DSN:
157       wSystemDSN = USERDSN_ONLY;
158       break;
159 
160     case ODBC_SYSTEM_DSN:
161       wSystemDSN = SYSTEMDSN_ONLY;
162       break;
163     }
164 
165   if (_iodbcdm_cfg_search_init (&pCfg, "odbcinst.ini", TRUE))
166     {
167       PUSH_ERROR (ODBC_ERROR_GENERAL_ERR);
168       goto quit;
169     }
170 
171   if (_iodbcdm_cfg_search_init (&pOdbcCfg, "odbc.ini", TRUE))
172     {
173       PUSH_ERROR (ODBC_ERROR_GENERAL_ERR);
174       pOdbcCfg = NULL;
175       goto done;
176     }
177 
178   if (!install_from_string (pCfg, pOdbcCfg, (char *) lpszTranslator, FALSE))
179     {
180       PUSH_ERROR (ODBC_ERROR_INVALID_KEYWORD_VALUE);
181       goto done;
182     }
183 
184   if (_iodbcdm_cfg_commit (pCfg) || _iodbcdm_cfg_commit (pOdbcCfg))
185     {
186       PUSH_ERROR (ODBC_ERROR_GENERAL_ERR);
187       goto done;
188     }
189 
190   retcode = TRUE;
191 
192 done:
193   _iodbcdm_cfg_done (pCfg);
194   if (pOdbcCfg)
195     _iodbcdm_cfg_done (pOdbcCfg);
196 
197 quit:
198   wSystemDSN = USERDSN_ONLY;
199   configMode = ODBC_BOTH_DSN;
200 
201   return retcode;
202 }
203 
204 BOOL INSTAPI
SQLInstallTranslatorExW(LPCWSTR lpszTranslator,LPCWSTR lpszPathIn,LPWSTR lpszPathOut,WORD cbPathOutMax,WORD * pcbPathOut,WORD fRequest,LPDWORD lpdwUsageCount)205 SQLInstallTranslatorExW (LPCWSTR lpszTranslator, LPCWSTR lpszPathIn,
206     LPWSTR lpszPathOut, WORD cbPathOutMax, WORD * pcbPathOut, WORD fRequest,
207     LPDWORD lpdwUsageCount)
208 {
209   char *_translator_u8 = NULL;
210   char *_pathin_u8 = NULL;
211   char *_pathout_u8 = NULL;
212   BOOL retcode = FALSE;
213   int length;
214   SQLWCHAR *ptr;
215   char *ptr_u8;
216 
217   for (length = 0, ptr = (SQLWCHAR *) lpszTranslator; *ptr;
218       length += WCSLEN (ptr) + 1, ptr += WCSLEN (ptr) + 1);
219 
220   if (length > 0)
221     {
222       if ((_translator_u8 = malloc (length * UTF8_MAX_CHAR_LEN + 1)) != NULL)
223 	{
224 	  for (ptr = (SQLWCHAR *) lpszTranslator, ptr_u8 = _translator_u8;
225 	      *ptr; ptr += WCSLEN (ptr) + 1, ptr_u8 += STRLEN (ptr_u8) + 1)
226 	    dm_StrCopyOut2_W2A (ptr, (SQLCHAR *)ptr_u8, WCSLEN (ptr) * UTF8_MAX_CHAR_LEN,
227 		NULL);
228 	  *ptr_u8 = '\0';
229 	}
230     }
231   else
232     _translator_u8 =
233 	(char *) dm_SQL_WtoU8 ((SQLWCHAR *) lpszTranslator, SQL_NTS);
234 
235   if (_translator_u8 == NULL && lpszTranslator)
236     {
237       PUSH_ERROR (ODBC_ERROR_OUT_OF_MEM);
238       goto done;
239     }
240 
241   _pathin_u8 = (char *) dm_SQL_WtoU8 ((SQLWCHAR *) lpszPathIn, SQL_NTS);
242   if (_pathin_u8 == NULL && lpszPathIn)
243     {
244       PUSH_ERROR (ODBC_ERROR_OUT_OF_MEM);
245       goto done;
246     }
247 
248   if (cbPathOutMax > 0)
249     {
250       if ((_pathout_u8 =
251 	      malloc (cbPathOutMax * UTF8_MAX_CHAR_LEN + 1)) == NULL)
252 	{
253 	  PUSH_ERROR (ODBC_ERROR_OUT_OF_MEM);
254 	  goto done;
255 	}
256     }
257 
258   retcode = SQLInstallTranslatorEx (_translator_u8, _pathin_u8,
259       _pathout_u8, cbPathOutMax * UTF8_MAX_CHAR_LEN, pcbPathOut, fRequest,
260       lpdwUsageCount);
261 
262   if (retcode == TRUE)
263     {
264       dm_StrCopyOut2_U8toW ((SQLCHAR *)_pathout_u8, lpszPathOut, cbPathOutMax,
265 	  pcbPathOut);
266     }
267 
268 done:
269   MEM_FREE (_translator_u8);
270   MEM_FREE (_pathin_u8);
271   MEM_FREE (_pathout_u8);
272 
273   return retcode;
274 }
275