1/* 2 * misc.c 3 * 4 * $Id: misc.c,v 1.23 2006/07/10 13:49:29 source Exp $ 5 * 6 * Miscellaneous functions 7 * 8 * The iODBC driver manager. 9 * 10 * Copyright (C) 1995 by Ke Jin <kejin@empress.com> 11 * Copyright (C) 1996-2006 by OpenLink Software <iodbc@openlinksw.com> 12 * All Rights Reserved. 13 * 14 * This software is released under the terms of either of the following 15 * licenses: 16 * 17 * - GNU Library General Public License (see LICENSE.LGPL) 18 * - The BSD License (see LICENSE.BSD). 19 * 20 * Note that the only valid version of the LGPL license as far as this 21 * project is concerned is the original GNU Library General Public License 22 * Version 2, dated June 1991. 23 * 24 * While not mandated by the BSD license, any patches you make to the 25 * iODBC source code may be contributed back into the iODBC project 26 * at your discretion. Contributions will benefit the Open Source and 27 * Data Access community as a whole. Submissions may be made at: 28 * 29 * http://www.iodbc.org 30 * 31 * 32 * GNU Library Generic Public License Version 2 33 * ============================================ 34 * This library is free software; you can redistribute it and/or 35 * modify it under the terms of the GNU Library General Public 36 * License as published by the Free Software Foundation; only 37 * Version 2 of the License dated June 1991. 38 * 39 * This library is distributed in the hope that it will be useful, 40 * but WITHOUT ANY WARRANTY; without even the implied warranty of 41 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 42 * Library General Public License for more details. 43 * 44 * You should have received a copy of the GNU Library General Public 45 * License along with this library; if not, write to the Free 46 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 47 * 48 * 49 * The BSD License 50 * =============== 51 * Redistribution and use in source and binary forms, with or without 52 * modification, are permitted provided that the following conditions 53 * are met: 54 * 55 * 1. Redistributions of source code must retain the above copyright 56 * notice, this list of conditions and the following disclaimer. 57 * 2. Redistributions in binary form must reproduce the above copyright 58 * notice, this list of conditions and the following disclaimer in 59 * the documentation and/or other materials provided with the 60 * distribution. 61 * 3. Neither the name of OpenLink Software Inc. nor the names of its 62 * contributors may be used to endorse or promote products derived 63 * from this software without specific prior written permission. 64 * 65 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 66 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 67 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 68 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL OPENLINK OR 69 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 70 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 71 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 72 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 73 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 74 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 75 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 76 */ 77 78#include <iodbc.h> 79 80#include <sql.h> 81#include <sqlext.h> 82#include <odbcinst.h> 83 84#include <stdio.h> 85#include <stdlib.h> 86#include <unistd.h> 87 88#include <unicode.h> 89 90#include <fcntl.h> 91#include <sys/stat.h> 92 93#include "herr.h" 94#include "misc.h" 95#include "iodbc_misc.h" 96 97#ifdef _MAC 98#include <getfpn.h> 99#endif /* _MAC */ 100 101 102/* 103 * Parse a configuration from string (internal) 104 */ 105int 106_iodbcdm_cfg_parse_str_Internal (PCONFIG pconfig, char *str) 107{ 108 char *s; 109 int count; 110 111 /* init image */ 112 _iodbcdm_cfg_freeimage (pconfig); 113 if (str == NULL) 114 { 115 /* NULL string is ok */ 116 return 0; 117 } 118 s = pconfig->image = strdup (str); 119 120 /* Add [ODBC] section */ 121 if (_iodbcdm_cfg_storeentry (pconfig, "ODBC", NULL, NULL, NULL, 0) == -1) 122 return -1; 123 124 for (count = 0; *s; count++) 125 { 126 char *keywd = NULL, *value; 127 char *cp, *n; 128 129 /* 130 * Extract KEY=VALUE upto first ';' 131 */ 132 for (cp = s; *cp && *cp != ';'; cp++) 133 { 134 if (*cp == '{') 135 { 136 for (cp++; *cp && *cp != '}'; cp++) 137 ; 138 } 139 } 140 141 /* 142 * Store start of next token if available in n and terminate string 143 */ 144 if (*cp) 145 { 146 *cp = 0; 147 n = cp + 1; 148 } 149 else 150 n = cp; 151 152 /* 153 * Find '=' in string 154 */ 155 for (cp = s; *cp && *cp != '='; cp++) 156 ; 157 158 if (*cp) 159 { 160 *cp++ = 0; 161 keywd = s; 162 value = cp; 163 } 164 else if (count == 0) 165 { 166 /* 167 * Handle missing DSN=... from the beginning of the string, e.g.: 168 * 'dsn_ora7;UID=scott;PWD=tiger' 169 */ 170 keywd = "DSN"; 171 value = s; 172 } 173 174 if (keywd != NULL) 175 { 176 /* store entry */ 177 if (_iodbcdm_cfg_storeentry (pconfig, NULL, 178 keywd, value, NULL, 0) == -1) 179 return -1; 180 } 181 182 /* 183 * Continue with next token 184 */ 185 s = n; 186 } 187 188 /* we're done */ 189 pconfig->flags |= CFG_VALID; 190 pconfig->dirty = 1; 191 return 0; 192} 193 194 195/* 196 * Initialize a configuration from string 197 */ 198int 199_iodbcdm_cfg_init_str (PCONFIG *ppconf, void *str, int size, int wide) 200{ 201 PCONFIG pconfig; 202 203 *ppconf = NULL; 204 205 /* init config */ 206 if ((pconfig = (PCONFIG) calloc (1, sizeof (TCONFIG))) == NULL) 207 return -1; 208 209 /* parse */ 210 if (_iodbcdm_cfg_parse_str (pconfig, str, size, wide) == -1) 211 { 212 _iodbcdm_cfg_done (pconfig); 213 return -1; 214 } 215 216 /* we're done */ 217 *ppconf = pconfig; 218 return 0; 219} 220 221 222/* 223 * Parse a configuration from string 224 */ 225int 226_iodbcdm_cfg_parse_str (PCONFIG pconfig, void *str, int size, int wide) 227{ 228 int ret; 229 char *_str; 230 231 _str = wide ? (char *) dm_SQL_WtoU8 (str, size) : str; 232 233 ret = _iodbcdm_cfg_parse_str_Internal (pconfig, _str); 234 235 if (wide) 236 MEM_FREE (_str); 237 238 return ret; 239} 240 241 242#define CATBUF(buf, str, buf_sz) \ 243 do { \ 244 if (_iodbcdm_strlcat (buf, str, buf_sz) >= buf_sz) \ 245 return -1; \ 246 } while (0) 247 248int 249_iodbcdm_cfg_to_string (PCONFIG pconfig, char *section, 250 char *buf, size_t buf_sz) 251{ 252 BOOL atsection; 253 254 if (_iodbcdm_cfg_rewind (pconfig) == -1) 255 return -1; 256 257 atsection = FALSE; 258 buf[0] = '\0'; 259 while (_iodbcdm_cfg_nextentry (pconfig) == 0) 260 { 261 if (atsection) 262 { 263 if (_iodbcdm_cfg_section (pconfig)) 264 break; 265 else if (_iodbcdm_cfg_define (pconfig)) 266 { 267 if (buf[0] != '\0') 268 CATBUF (buf, ";", buf_sz); 269 CATBUF (buf, pconfig->id, buf_sz); 270 CATBUF (buf, "=", buf_sz); 271 CATBUF (buf, pconfig->value, buf_sz); 272 } 273 } 274 else if (_iodbcdm_cfg_section (pconfig) && 275 !strcasecmp (pconfig->section, section)) 276 atsection = TRUE; 277 } 278 return 0; 279} 280