1/* 2 * misc.c 3 * 4 * $Id: misc.c 2613 1999-06-01 15:32:12Z VZ $ 5 * 6 * Miscellaneous functions 7 * 8 * The iODBC driver manager. 9 * 10 * Copyright (C) 1995 by Ke Jin <kejin@empress.com> 11 * 12 * This library is free software; you can redistribute it and/or 13 * modify it under the terms of the GNU Library General Public 14 * License as published by the Free Software Foundation; either 15 * version 2 of the License, or (at your option) any later version. 16 * 17 * This library is distributed in the hope that it will be useful, 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 20 * Library General Public License for more details. 21 * 22 * You should have received a copy of the GNU Library General Public 23 * License along with this library; if not, write to the Free 24 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 25 */ 26 27#include "config.h" 28 29#include "isql.h" 30#include "isqlext.h" 31 32#include <stdio.h> 33#include <unistd.h> 34 35static int 36upper_strneq ( 37 char *s1, 38 char *s2, 39 int n) 40{ 41 int i; 42 char c1, c2; 43 44 for (i = 1; i < n; i++) 45 { 46 c1 = s1[i]; 47 c2 = s2[i]; 48 49 if (c1 >= 'a' && c1 <= 'z') 50 { 51 c1 += ('A' - 'a'); 52 } 53 else if (c1 == '\n') 54 { 55 c1 = '\0'; 56 } 57 58 if (c2 >= 'a' && c2 <= 'z') 59 { 60 c2 += ('A' - 'a'); 61 } 62 else if (c2 == '\n') 63 { 64 c2 = '\0'; 65 } 66 67 if ((c1 - c2) || !c1 || !c2) 68 { 69 break; 70 } 71 } 72 73 return (int) !(c1 - c2); 74} 75 76static char * /* return new position in input str */ 77readtoken ( 78 char *istr, /* old position in input buf */ 79 char *obuf) /* token string ( if "\0", then finished ) */ 80{ 81 char *start = obuf; 82 83 /* Skip leading white space */ 84 while (*istr == ' ' || *istr == '\t') 85 istr++; 86 87 for (; *istr && *istr != '\n'; istr++) 88 { 89 char c, nx; 90 91 c = *(istr); 92 nx = *(istr + 1); 93 94 if (c == ';') 95 { 96 for (; *istr && *istr != '\n'; istr++); 97 break; 98 } 99 *obuf = c; 100 obuf++; 101 102 if (nx == ';' || nx == '=' || c == '=') 103 { 104 istr++; 105 break; 106 } 107 } 108 *obuf = '\0'; 109 110 /* Trim end of token */ 111 for (; obuf > start && (*(obuf - 1) == ' ' || *(obuf - 1) == '\t');) 112 *--obuf = '\0'; 113 114 return istr; 115} 116 117#if !defined(WINDOWS) && !defined(WIN32) && !defined(OS2) 118# include <pwd.h> 119# define UNIX_PWD 120#endif 121 122char * 123_iodbcdm_getinifile (char *buf, int size) 124{ 125 int i, j; 126 char *ptr; 127 128 j = STRLEN ("/odbc.ini") + 1; 129 130 if (size < j) 131 { 132 return NULL; 133 } 134 135#if !defined(UNIX_PWD) 136 137 i = GetWindowsDirectory ((LPSTR) buf, size); 138 139 if (i == 0 || i > size - j) 140 { 141 return NULL; 142 } 143 144 sprintf (buf + i, "/odbc.ini"); 145 146 return buf; 147#else 148 if ((ptr = getenv ("ODBCINI")) != NULL) 149 { 150 strcpy (buf, ptr); 151 return buf; 152 } 153 154 if ((ptr = getenv ("IODBCINI")) != NULL) 155 { 156 strcpy (buf, ptr); 157 return buf; 158 } 159 160 if ((ptr = getenv ("HOME")) == NULL) 161 { 162 ptr = (char *) getpwuid (getuid ()); 163 164 if (ptr == NULL) 165 { 166 return NULL; 167 } 168 169 ptr = ((struct passwd *) ptr)->pw_dir; 170 } 171 172 if (ptr == NULL || *ptr == '\0') 173 { 174 ptr = "/home"; 175 } 176 177 if (size < STRLEN (ptr) + j) 178 { 179 return NULL; 180 } 181 182 sprintf (buf, "%s%s", ptr, "/.odbc.ini"); 183 /* i.e. searching ~/.odbc.ini */ 184#endif 185 186 return buf; 187} 188 189 190/* 191 * read odbc init file to resolve the value of specified 192 * key from named or defaulted dsn section 193 */ 194char * 195_iodbcdm_getkeyvalbydsn ( 196 char *dsn, 197 int dsnlen, 198 char *keywd, 199 char *value, 200 int size) 201{ 202 char buf[1024]; 203 char dsntk[SQL_MAX_DSN_LENGTH + 3] = {'[', '\0'}; 204 char token[1024]; /* large enough */ 205 FILE *file; 206 char pathbuf[1024]; 207 char *path; 208 209#define DSN_NOMATCH 0 210#define DSN_NAMED 1 211#define DSN_DEFAULT 2 212 213 int dsnid = DSN_NOMATCH; 214 int defaultdsn = DSN_NOMATCH; 215 216 if (dsn == NULL || *dsn == 0) 217 { 218 dsn = "default"; 219 dsnlen = STRLEN (dsn); 220 } 221 222 if (dsnlen == SQL_NTS) 223 { 224 dsnlen = STRLEN (dsn); 225 } 226 227 if (dsnlen <= 0 || keywd == NULL || buf == 0 || size <= 0) 228 { 229 return NULL; 230 } 231 232 if (dsnlen > sizeof (dsntk) - 2) 233 { 234 return NULL; 235 } 236 237 value[0] = '\0'; 238 239 STRNCAT (dsntk, dsn, dsnlen); 240 STRCAT (dsntk, "]"); 241 242 dsnlen = dsnlen + 2; 243 244 path = _iodbcdm_getinifile (pathbuf, sizeof (pathbuf)); 245 246 if (path == NULL) 247 { 248 return NULL; 249 } 250 251 file = (FILE *) fopen (path, "r"); 252 253 if (file == NULL) 254 { 255 return NULL; 256 } 257 258 for (;;) 259 { 260 char *str; 261 262 str = fgets (buf, sizeof (buf), file); 263 264 if (str == NULL) 265 { 266 break; 267 } 268 269 if (*str == '[') 270 { 271 if (upper_strneq (str, "[default]", STRLEN ("[default]"))) 272 { 273 /* we only read first dsn default dsn 274 * section (as well as named dsn). 275 */ 276 if (defaultdsn == DSN_NOMATCH) 277 { 278 dsnid = DSN_DEFAULT; 279 defaultdsn = DSN_DEFAULT; 280 } 281 else 282 { 283 dsnid = DSN_NOMATCH; 284 } 285 286 continue; 287 } 288 else if (upper_strneq (str, dsntk, dsnlen)) 289 { 290 dsnid = DSN_NAMED; 291 } 292 else 293 { 294 dsnid = DSN_NOMATCH; 295 } 296 297 continue; 298 } 299 else if (dsnid == DSN_NOMATCH) 300 { 301 continue; 302 } 303 304 str = readtoken (str, token); 305 306 if (upper_strneq (keywd, token, STRLEN (keywd))) 307 { 308 str = readtoken (str, token); 309 310 if (!STREQ (token, "=")) 311 /* something other than = */ 312 { 313 continue; 314 } 315 316 str = readtoken (str, token); 317 318 if (STRLEN (token) > size - 1) 319 { 320 break; 321 } 322 323 STRNCPY (value, token, size); 324 /* copy the value(i.e. next token) to buf */ 325 326 if (dsnid != DSN_DEFAULT) 327 { 328 break; 329 } 330 } 331 } 332 333 fclose (file); 334 335 return (*value) ? value : NULL; 336} 337 338 339char * 340_iodbcdm_getkeyvalinstr ( 341 char *cnstr, 342 int cnlen, 343 char *keywd, 344 char *value, 345 int size) 346{ 347 char token[1024] = {'\0'}; 348 int flag = 0; 349 350 if (cnstr == NULL || value == NULL 351 || keywd == NULL || size < 1) 352 { 353 return NULL; 354 } 355 356 if (cnlen == SQL_NTS) 357 { 358 cnlen = STRLEN (cnstr); 359 } 360 361 if (cnlen <= 0) 362 { 363 return NULL; 364 } 365 366 for (;;) 367 { 368 cnstr = readtoken (cnstr, token); 369 370 if (*token == '\0') 371 { 372 break; 373 } 374 375 if (STREQ (token, ";")) 376 { 377 flag = 0; 378 continue; 379 } 380 381 switch (flag) 382 { 383 case 0: 384 if (upper_strneq (token, keywd, strlen (keywd))) 385 { 386 flag = 1; 387 } 388 break; 389 390 case 1: 391 if (STREQ (token, "=")) 392 { 393 flag = 2; 394 } 395 break; 396 397 case 2: 398 if (size < strlen (token) + 1) 399 { 400 return NULL; 401 } 402 403 STRNCPY (value, token, size); 404 405 return value; 406 407 default: 408 break; 409 } 410 } 411 412 return NULL; 413} 414