NCBI C++ ToolKit
connectparams.c
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
2  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Brian Bruns
3  * Copyright (C) 2005-2011 Frediano Ziglio
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20 
21 #include <config.h>
22 
23 #include <stdarg.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <ctype.h>
28 #include <sys/stat.h>
29 
30 #include <freetds/odbc.h>
31 #include <freetds/string.h>
32 #include "replacements.h"
33 
34 #define ODBC_PARAM(p) static const char odbc_param_##p[] = #p;
36 #undef ODBC_PARAM
37 
38 #ifdef _WIN32
39 #define ODBC_PARAM(p) odbc_param_##p,
40 static const char *odbc_param_names[] = {
42 };
43 #undef ODBC_PARAM
44 #endif
45 
46 #if !HAVE_SQLGETPRIVATEPROFILESTRING
47 
48 /*
49  * Last resort place to check for INI file. This is usually set at compile time
50  * by build scripts.
51  */
52 #ifndef SYS_ODBC_INI
53 #define SYS_ODBC_INI "/etc/odbc.ini"
54 #endif
55 
56 /**
57  * Call this to get the INI file containing Data Source Names.
58  * @note rules for determining the location of ODBC config may be different
59  * then what you expect - at this time they differ from unixODBC
60  *
61  * @return file opened or NULL if error
62  * @retval 1 worked
63  */
64 static FILE *tdoGetIniFileName(void);
65 
66 /**
67  * SQLGetPrivateProfileString
68  *
69  * PURPOSE
70  *
71  * This is an implementation of a common MS API call. This implementation
72  * should only be used if the ODBC sub-system/SDK does not have it.
73  * For example; unixODBC has its own so those using unixODBC should NOT be
74  * using this implementation because unixODBC;
75  * - provides caching of ODBC config data
76  * - provides consistent interpretation of ODBC config data (i.e, location)
77  *
78  * ARGS
79  *
80  * see ODBC documentation
81  *
82  * RETURNS
83  *
84  * see ODBC documentation
85  *
86  * NOTES:
87  *
88  * - the spec is not entirely implemented... consider this a lite version
89  * - rules for determining the location of ODBC config may be different then what you
90  * expect see tdoGetIniFileName().
91  *
92  */
93 #ifndef _WIN32
94 static int SQLGetPrivateProfileString(LPCSTR pszSection, LPCSTR pszEntry, LPCSTR pszDefault, LPSTR pRetBuffer, int nRetBuffer,
95  LPCSTR pszFileName);
96 #endif
97 
98 #endif
99 
100 #if defined(FILENAME_MAX) && FILENAME_MAX < 512
101 #undef FILENAME_MAX
102 #define FILENAME_MAX 512
103 #endif
104 
105 static int
106 parse_server(TDS_ERRS *errs, char *server, TDSLOGIN * login)
107 {
108  char *p = (char *) strchr(server, '\\');
109 
110  if (p) {
111  if (!tds_dstr_copy(&login->instance_name, p+1)) {
112  odbc_errs_add(errs, "HY001", NULL);
113  return 0;
114  }
115  *p = 0;
116  } else {
117  p = (char *) strchr(server, ',');
118  if (p && atoi(p+1) > 0) {
119  login->port = atoi(p+1);
120  *p = 0;
121  }
122  }
123 
125  if (!tds_dstr_copy(&login->server_host_name, server)) {
126  odbc_errs_add(errs, "HY001", NULL);
127  return 0;
128  }
129 
130  return 1;
131 }
132 
133 static int
134 myGetPrivateProfileString(const char *DSN, const char *key, char *buf)
135 {
136  buf[0] = '\0';
137  return SQLGetPrivateProfileString(DSN, key, "", buf, FILENAME_MAX, "odbc.ini");
138 }
139 
140 /**
141  * Read connection information from given DSN
142  * @param DSN DSN name
143  * @param login where to store connection info
144  * @return 1 if success 0 otherwhise
145  */
146 int
147 odbc_get_dsn_info(TDS_ERRS *errs, const char *DSN, TDSLOGIN * login)
148 {
149  char tmp[FILENAME_MAX];
150  int freetds_conf_less = 1;
151 
152  /* use old servername */
153  if (myGetPrivateProfileString(DSN, odbc_param_Servername, tmp) > 0) {
154  freetds_conf_less = 0;
155  if (!tds_dstr_copy(&login->server_name, tmp)) {
156  odbc_errs_add(errs, "HY001", NULL);
157  return 0;
158  }
160  if (myGetPrivateProfileString(DSN, odbc_param_Server, tmp) > 0) {
161  odbc_errs_add(errs, "HY000", "You cannot specify both SERVERNAME and SERVER");
162  return 0;
163  }
164  if (myGetPrivateProfileString(DSN, odbc_param_Address, tmp) > 0) {
165  odbc_errs_add(errs, "HY000", "You cannot specify both SERVERNAME and ADDRESS");
166  return 0;
167  }
168  }
169 
170  /* search for server (compatible with ms one) */
171  if (freetds_conf_less) {
172  int address_specified = 0;
173 
174  if (myGetPrivateProfileString(DSN, odbc_param_Address, tmp) > 0) {
175  address_specified = 1;
176  /* TODO parse like MS */
177 
179  odbc_errs_add(errs, "HY000", "Error parsing ADDRESS attribute");
180  return 0;
181  }
182  }
183  if (myGetPrivateProfileString(DSN, odbc_param_Server, tmp) > 0) {
184  if (!tds_dstr_copy(&login->server_name, tmp)) {
185  odbc_errs_add(errs, "HY001", NULL);
186  return 0;
187  }
188  if (!address_specified) {
189  if (!parse_server(errs, tmp, login))
190  return 0;
191  }
192  }
193  }
194 
195  if (myGetPrivateProfileString(DSN, odbc_param_Port, tmp) > 0)
197 
198  if (myGetPrivateProfileString(DSN, odbc_param_TDS_Version, tmp) > 0)
200 
201  if (myGetPrivateProfileString(DSN, odbc_param_Language, tmp) > 0)
203 
205  && myGetPrivateProfileString(DSN, odbc_param_Database, tmp) > 0)
206  if (!tds_dstr_copy(&login->database, tmp)) {
207  odbc_errs_add(errs, "HY001", NULL);
208  return 0;
209  }
210 
211  if (myGetPrivateProfileString(DSN, odbc_param_TextSize, tmp) > 0)
213 
214  if (myGetPrivateProfileString(DSN, odbc_param_PacketSize, tmp) > 0)
216 
217  if (myGetPrivateProfileString(DSN, odbc_param_ClientCharset, tmp) > 0)
219 
220  if (myGetPrivateProfileString(DSN, odbc_param_DumpFile, tmp) > 0)
222 
223  if (myGetPrivateProfileString(DSN, odbc_param_DumpFileAppend, tmp) > 0)
225 
226  if (myGetPrivateProfileString(DSN, odbc_param_DebugFlags, tmp) > 0)
228 
229  if (myGetPrivateProfileString(DSN, odbc_param_Encryption, tmp) > 0)
231 
232  if (myGetPrivateProfileString(DSN, odbc_param_UseNTLMv2, tmp) > 0)
234 
235  if (myGetPrivateProfileString(DSN, odbc_param_REALM, tmp) > 0)
237 
238  if (myGetPrivateProfileString(DSN, odbc_param_ServerSPN, tmp) > 0)
240 
241  if (myGetPrivateProfileString(DSN, odbc_param_Trusted_Connection, tmp) > 0 && tds_config_boolean(odbc_param_Trusted_Connection, tmp, login)) {
244  }
245 
246  if (myGetPrivateProfileString(DSN, odbc_param_MARS_Connection, tmp) > 0 && tds_config_boolean(odbc_param_MARS_Connection, tmp, login)) {
247  login->mars = 1;
248  }
249 
250  if (myGetPrivateProfileString(DSN, odbc_param_AttachDbFilename, tmp) > 0)
252 
253  return 1;
254 }
255 
256 /**
257  * Swap two DSTR
258  */
259 static void
261 {
262  DSTR tmp = *a;
263  *a = *b;
264  *b = tmp;
265 }
266 
267 /**
268  * Parse connection string and fill login according
269  * @param connect_string connect string
270  * @param connect_string_end connect string end (pointer to char past last)
271  * @param login where to store connection info
272  * @return 1 if success 0 otherwhise
273  */
274 int
275 odbc_parse_connect_string(TDS_ERRS *errs, const char *connect_string, const char *connect_string_end, TDSLOGIN * login,
276  TDS_PARSED_PARAM *parsed_params)
277 {
278  const char *p, *end;
279  DSTR *dest_s, value = DSTR_INITIALIZER;
280  enum { CFG_DSN = 1, CFG_SERVER = 2, CFG_SERVERNAME = 4 };
281  unsigned int cfgs = 0; /* flags for indicate second parse of string */
282  char option[24];
283  int trusted = 0;
284 
285  if (parsed_params)
286  memset(parsed_params, 0, sizeof(*parsed_params)*ODBC_PARAM_SIZE);
287 
288  for (p = connect_string; p < connect_string_end && *p;) {
289  int num_param = -1;
290 
291  dest_s = NULL;
292 
293  /* handle empty options */
294  while (p < connect_string_end && *p == ';')
295  ++p;
296 
297  /* parse option */
298  end = (const char *) memchr(p, '=', connect_string_end - p);
299  if (!end)
300  break;
301 
302  /* account for spaces between ;'s. */
303  while (p < end && *p == ' ')
304  ++p;
305 
306  if ((end - p) >= (int) sizeof(option))
307  option[0] = 0;
308  else {
309  memcpy(option, p, end - p);
310  option[end - p] = 0;
311  }
312 
313  /* parse value */
314  p = end + 1;
315  if (*p == '{') {
316  ++p;
317  /* search "};" */
318  end = p;
319  while ((end = (const char *) memchr(end, '}', connect_string_end - end)) != NULL) {
320  if ((end + 1) != connect_string_end && end[1] == ';')
321  break;
322  ++end;
323  }
324  } else {
325  end = (const char *) memchr(p, ';', connect_string_end - p);
326  }
327  if (!end)
328  end = connect_string_end;
329 
330  if (!tds_dstr_copyn(&value, p, end - p)) {
331  odbc_errs_add(errs, "HY001", NULL);
332  return 0;
333  }
334 
335 #define CHK_PARAM(p) (strcasecmp(option, odbc_param_##p) == 0 && (num_param=ODBC_PARAM_##p) >= 0)
336  if (CHK_PARAM(Server)) {
337  /* error if servername or DSN specified */
338  if ((cfgs & (CFG_DSN|CFG_SERVERNAME)) != 0) {
340  odbc_errs_add(errs, "HY000", "Only one between SERVER, SERVERNAME and DSN can be specified");
341  return 0;
342  }
343  if (!cfgs) {
344  dest_s = &login->server_name;
345  /* not that safe cast but works -- freddy77 */
346  if (!parse_server(errs, (char *) tds_dstr_cstr(&value), login)) {
348  return 0;
349  }
350  cfgs = CFG_SERVER;
351  }
352  } else if (CHK_PARAM(Servername)) {
353  if ((cfgs & (CFG_DSN|CFG_SERVER)) != 0) {
355  odbc_errs_add(errs, "HY000", "Only one between SERVER, SERVERNAME and DSN can be specified");
356  return 0;
357  }
358  if (!cfgs) {
361  cfgs = CFG_SERVERNAME;
362  p = connect_string;
363  continue;
364  }
365  } else if (CHK_PARAM(DSN)) {
366  if ((cfgs & (CFG_SERVER|CFG_SERVERNAME)) != 0) {
368  odbc_errs_add(errs, "HY000", "Only one between SERVER, SERVERNAME and DSN can be specified");
369  return 0;
370  }
371  if (!cfgs) {
372  if (!odbc_get_dsn_info(errs, tds_dstr_cstr(&value), login)) {
374  return 0;
375  }
376  cfgs = CFG_DSN;
377  p = connect_string;
378  continue;
379  }
380  } else if (CHK_PARAM(Database)) {
381  dest_s = &login->database;
382  } else if (CHK_PARAM(UID)) {
383  dest_s = &login->user_name;
384  } else if (CHK_PARAM(PWD)) {
385  dest_s = &login->password;
386  } else if (CHK_PARAM(APP)) {
387  dest_s = &login->app_name;
388  } else if (CHK_PARAM(WSID)) {
389  dest_s = &login->client_host_name;
390  } else if (CHK_PARAM(Language)) {
392  } else if (CHK_PARAM(Port)) {
394  } else if (CHK_PARAM(TDS_Version)) {
396  } else if (CHK_PARAM(TextSize)) {
398  } else if (CHK_PARAM(PacketSize)) {
400  } else if (CHK_PARAM(ClientCharset)
401  || strcasecmp(option, "client_charset") == 0) {
403  } else if (CHK_PARAM(DumpFile)) {
405  } else if (CHK_PARAM(DumpFileAppend)) {
407  } else if (CHK_PARAM(DebugFlags)) {
409  } else if (CHK_PARAM(Encryption)) {
411  } else if (CHK_PARAM(UseNTLMv2)) {
413  } else if (CHK_PARAM(REALM)) {
415  } else if (CHK_PARAM(ServerSPN)) {
417  } else if (CHK_PARAM(Trusted_Connection)) {
419  tdsdump_log(TDS_DBG_INFO1, "trusted %s -> %d\n", tds_dstr_cstr(&value), trusted);
420  num_param = -1;
421  /* TODO odbc_param_Address field */
422  } else if (CHK_PARAM(MARS_Connection)) {
424  login->mars = 1;
425  } else if (CHK_PARAM(AttachDbFilename)) {
426  dest_s = &login->db_filename;
427  } else if (CHK_PARAM(ApplicationIntent)) {
428  const char *readonly_intent;
429 
430  if (strcasecmp(tds_dstr_cstr(&value), "ReadOnly") == 0) {
431  readonly_intent = "yes";
432  } else if (strcasecmp(tds_dstr_cstr(&value), "ReadWrite") == 0) {
433  readonly_intent = "no";
434  } else {
435  tdsdump_log(TDS_DBG_ERROR, "Invalid ApplicationIntent %s\n", tds_dstr_cstr(&value));
436  return 0;
437  }
438 
440  tdsdump_log(TDS_DBG_INFO1, "Application Intent %s\n", readonly_intent);
441  }
442 
443  if (num_param >= 0 && parsed_params) {
444  parsed_params[num_param].p = p;
445  parsed_params[num_param].len = end - p;
446  }
447 
448  /* copy to destination */
449  if (dest_s)
450  odbc_dstr_swap(dest_s, &value);
451 
452  p = end;
453  /* handle "" ";.." "};.." cases */
454  if (p >= connect_string_end)
455  break;
456  if (*p == '}')
457  ++p;
458  ++p;
459  }
460 
461  if (trusted) {
462  if (parsed_params) {
463  parsed_params[ODBC_PARAM_Trusted_Connection].p = "Yes";
464  parsed_params[ODBC_PARAM_Trusted_Connection].len = 3;
465  parsed_params[ODBC_PARAM_UID].p = NULL;
466  parsed_params[ODBC_PARAM_PWD].p = NULL;
467  }
470  }
471 
473  return 1;
474 }
475 
476 #ifdef _WIN32
477 int
478 odbc_build_connect_string(TDS_ERRS *errs, TDS_PARSED_PARAM *params, char **out)
479 {
480  unsigned n;
481  size_t len = 1;
482  char *p;
483 
484  /* compute string size */
485  for (n = 0; n < ODBC_PARAM_SIZE; ++n) {
486  if (params[n].p)
487  len += strlen(odbc_param_names[n]) + params[n].len + 2;
488  }
489 
490  /* allocate */
491  p = tds_new(char, len);
492  if (!p) {
493  odbc_errs_add(errs, "HY001", NULL);
494  return 0;
495  }
496  *out = p;
497 
498  /* build it */
499  for (n = 0; n < ODBC_PARAM_SIZE; ++n) {
500  if (params[n].p)
501  p += sprintf(p, "%s=%.*s;", odbc_param_names[n], (int) params[n].len, params[n].p);
502  }
503  *p = 0;
504  return 1;
505 }
506 #endif
507 
508 #if !HAVE_SQLGETPRIVATEPROFILESTRING
509 
510 #if defined(_WIN32) && !defined(TDS_NO_DM)
511 # error There is something wrong in configuration...
512 #endif
513 
514 typedef struct
515 {
519  int ret_val;
520  int found;
521 }
523 
524 static void
525 tdoParseProfile(const char *option, const char *value, void *param)
526 {
527  ProfileParam *p = (ProfileParam *) param;
528 
529  if (strcasecmp(p->entry, option) == 0) {
530  strlcpy(p->buffer, value, p->buffer_len);
531 
532  p->ret_val = (int) strlen(p->buffer);
533  p->found = 1;
534  }
535 }
536 
537 #if defined(_WIN32) && defined(TDS_NO_DM)
538 int INSTAPI
539 #else
540 static int
541 #endif
542 SQLGetPrivateProfileString(LPCSTR pszSection, LPCSTR pszEntry, LPCSTR pszDefault, LPSTR pRetBuffer, int nRetBuffer,
543  LPCSTR pszFileName)
544 {
545  FILE *hFile;
546  ProfileParam param;
547 
548  tdsdump_log(TDS_DBG_FUNC, "SQLGetPrivateProfileString(%p, %p, %p, %p, %d, %p)\n",
549  pszSection, pszEntry, pszDefault, pRetBuffer, nRetBuffer, pszFileName);
550 
551  if (!pszSection) {
552  /* spec says return list of all section names - but we will just return nothing */
553  tdsdump_log(TDS_DBG_WARN, "WARNING: Functionality for NULL pszSection not implemented.\n");
554  return 0;
555  }
556 
557  if (!pszEntry) {
558  /* spec says return list of all key names in section - but we will just return nothing */
559  tdsdump_log(TDS_DBG_WARN, "WARNING: Functionality for NULL pszEntry not implemented.\n");
560  return 0;
561  }
562 
563  if (nRetBuffer < 1)
564  tdsdump_log(TDS_DBG_WARN, "WARNING: No space to return a value because nRetBuffer < 1.\n");
565 
566  if (pszFileName && *pszFileName == '/')
567  hFile = fopen(pszFileName, "r");
568  else
569  hFile = tdoGetIniFileName();
570 
571  if (hFile == NULL) {
572  tdsdump_log(TDS_DBG_ERROR, "ERROR: Could not open configuration file\n");
573  return 0;
574  }
575 
576  param.entry = pszEntry;
577  param.buffer = pRetBuffer;
578  param.buffer_len = nRetBuffer;
579  param.ret_val = 0;
580  param.found = 0;
581 
582  pRetBuffer[0] = 0;
583  tds_read_conf_section(hFile, pszSection, tdoParseProfile, &param);
584 
585  if (pszDefault && !param.found) {
586  strlcpy(pRetBuffer, pszDefault, nRetBuffer);
587 
588  param.ret_val = (int) strlen(pRetBuffer);
589  }
590 
591  fclose(hFile);
592  return param.ret_val;
593 }
594 
595 static FILE *
597 {
598  FILE *ret = NULL;
599  char *p;
600  char *fn;
601 
602  /*
603  * First, try the ODBCINI environment variable
604  */
605  if ((p = getenv("ODBCINI")) != NULL)
606  ret = fopen(p, "r");
607 
608  /*
609  * Second, try the HOME environment variable
610  */
611  if (!ret && (p = tds_get_homedir()) != NULL) {
612  fn = NULL;
613  if (asprintf(&fn, "%s/.odbc.ini", p) > 0) {
614  ret = fopen(fn, "r");
615  free(fn);
616  }
617  free(p);
618  }
619 
620  /*
621  * As a last resort, try SYS_ODBC_INI
622  */
623  if (!ret)
624  ret = fopen(SYS_ODBC_INI, "r");
625 
626  return ret;
627 }
628 
629 #endif /* !HAVE_SQLGETPRIVATEPROFILESTRING */
630 
631 #ifdef UNIXODBC
632 
633 /*
634  * Begin BIG Hack.
635  *
636  * We need these from odbcinstext.h but it wants to
637  * include <log.h> and <ini.h>, which are not in the
638  * standard include path. XXX smurph
639  * confirmed by unixODBC stuff, odbcinstext.h shouldn't be installed. freddy77
640  */
641 #define INI_MAX_LINE 1000
642 #define INI_MAX_OBJECT_NAME INI_MAX_LINE
643 #define INI_MAX_PROPERTY_NAME INI_MAX_LINE
644 #define INI_MAX_PROPERTY_VALUE INI_MAX_LINE
645 
646 #define ODBCINST_PROMPTTYPE_LABEL 0 /* readonly */
647 #define ODBCINST_PROMPTTYPE_TEXTEDIT 1
648 #define ODBCINST_PROMPTTYPE_LISTBOX 2
649 #define ODBCINST_PROMPTTYPE_COMBOBOX 3
650 #define ODBCINST_PROMPTTYPE_FILENAME 4
651 #define ODBCINST_PROMPTTYPE_HIDDEN 5
652 
653 typedef struct tODBCINSTPROPERTY
654 {
655  struct tODBCINSTPROPERTY *pNext; /* pointer to next property, NULL if last property */
656 
657  char szName[INI_MAX_PROPERTY_NAME + 1]; /* property name */
658  char szValue[INI_MAX_PROPERTY_VALUE + 1]; /* property value */
659  int nPromptType; /* PROMPTTYPE_TEXTEDIT, PROMPTTYPE_LISTBOX, PROMPTTYPE_COMBOBOX, PROMPTTYPE_FILENAME */
660  char **aPromptData; /* array of pointers terminated with a NULL value in array. */
661  char *pszHelp; /* help on this property (driver setups should keep it short) */
662  void *pWidget; /* CALLER CAN STORE A POINTER TO ? HERE */
663  int bRefresh; /* app should refresh widget ie Driver Setup has changed aPromptData or szValue */
664  void *hDLL; /* for odbcinst internal use... only first property has valid one */
665 }
666 ODBCINSTPROPERTY, *HODBCINSTPROPERTY;
667 
668 /*
669  * End BIG Hack.
670  */
671 
672 int ODBCINSTGetProperties(HODBCINSTPROPERTY hLastProperty);
673 
674 static const char *const aTDSver[] = {
675  "",
676  "4.2",
677  "5.0",
678  "7.0",
679  "7.1",
680  "7.2",
681  "7.3",
682  "7.4",
683  NULL
684 };
685 
686 static const char *const aLanguage[] = {
687  "us_english",
688  NULL
689 };
690 
691 static const char *const aEncryption[] = {
695  NULL
696 };
697 
698 static const char *const aBoolean[] = {
699  "Yes",
700  "No",
701  NULL
702 };
703 
704 /*
705 static const char *aAuth[] = {
706  "Server",
707  "Domain",
708  "Both",
709  NULL
710 };
711 */
712 
713 static HODBCINSTPROPERTY
714 addProperty(HODBCINSTPROPERTY hLastProperty)
715 {
716  hLastProperty->pNext = (HODBCINSTPROPERTY) calloc(1, sizeof(ODBCINSTPROPERTY));
717  hLastProperty = hLastProperty->pNext;
718  return hLastProperty;
719 }
720 
721 static HODBCINSTPROPERTY
722 definePropertyString(HODBCINSTPROPERTY hLastProperty, const char *name, const char *value, const char *comment)
723 {
724  hLastProperty = addProperty(hLastProperty);
725  hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT;
726  strlcpy(hLastProperty->szName, name, INI_MAX_PROPERTY_NAME);
727  strlcpy(hLastProperty->szValue, value, INI_MAX_PROPERTY_VALUE);
728  hLastProperty->pszHelp = (char *) strdup(comment);
729  return hLastProperty;
730 }
731 
732 static HODBCINSTPROPERTY
733 definePropertyBoolean(HODBCINSTPROPERTY hLastProperty, const char *name, const char *value, const char *comment)
734 {
735  hLastProperty = addProperty(hLastProperty);
736  hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_LISTBOX;
737  hLastProperty->aPromptData = malloc(sizeof(aBoolean));
738  memcpy(hLastProperty->aPromptData, aBoolean, sizeof(aBoolean));
739  strlcpy(hLastProperty->szName, name, INI_MAX_PROPERTY_NAME);
740  strlcpy(hLastProperty->szValue, value, INI_MAX_PROPERTY_VALUE);
741  hLastProperty->pszHelp = (char *) strdup(comment);
742  return hLastProperty;
743 }
744 
745 static HODBCINSTPROPERTY
746 definePropertyHidden(HODBCINSTPROPERTY hLastProperty, const char *name, const char *value, const char *comment)
747 {
748  hLastProperty = addProperty(hLastProperty);
749  hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_HIDDEN;
750  strlcpy(hLastProperty->szName, name, INI_MAX_PROPERTY_NAME);
751  strlcpy(hLastProperty->szValue, value, INI_MAX_PROPERTY_VALUE);
752  hLastProperty->pszHelp = (char *) strdup(comment);
753  return hLastProperty;
754 }
755 
756 static HODBCINSTPROPERTY
757 definePropertyList(HODBCINSTPROPERTY hLastProperty, const char *name, const char *value, const void *list, int size, const char *comment)
758 {
759  hLastProperty = addProperty(hLastProperty);
760  hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_LISTBOX;
761  hLastProperty->aPromptData = malloc(size);
762  memcpy(hLastProperty->aPromptData, list, size);
763  strlcpy(hLastProperty->szName, name, INI_MAX_PROPERTY_NAME);
764  strlcpy(hLastProperty->szValue, value, INI_MAX_PROPERTY_VALUE);
765  hLastProperty->pszHelp = (char *) strdup(comment);
766  return hLastProperty;
767 }
768 
769 int
770 ODBCINSTGetProperties(HODBCINSTPROPERTY hLastProperty)
771 {
772  hLastProperty = definePropertyString(hLastProperty, odbc_param_Servername, "",
773  "Name of FreeTDS connection to connect to.\n"
774  "This server name refer to entry in freetds.conf file, not real server name.\n"
775  "This property cannot be used with Server property.");
776 
777  hLastProperty = definePropertyString(hLastProperty, odbc_param_Server, "",
778  "Name of server to connect to.\n"
779  "This should be the name of real server.\n"
780  "This property cannot be used with Servername property.");
781 
782  hLastProperty = definePropertyString(hLastProperty, odbc_param_Address, "",
783  "The hostname or ip address of the server.");
784 
785  hLastProperty = definePropertyString(hLastProperty, odbc_param_Port, "1433",
786  "TCP/IP Port to connect to.");
787 
788  hLastProperty = definePropertyString(hLastProperty, odbc_param_Database, "",
789  "Default database.");
790 
791  hLastProperty = definePropertyList(hLastProperty, odbc_param_TDS_Version, "4.2", (void*) aTDSver, sizeof(aTDSver),
792  "The TDS protocol version.\n"
793  " 4.2 MSSQL 6.5 or Sybase < 10.x\n"
794  " 5.0 Sybase >= 10.x\n"
795  " 7.0 MSSQL 7\n"
796  " 7.1 MSSQL 2000\n"
797  " 7.2 MSSQL 2005\n"
798  " 7.3 MSSQL 2008\n"
799  " 7.4 MSSQL 2012 or 2014"
800  );
801 
802  hLastProperty = definePropertyList(hLastProperty, odbc_param_Language, "us_english", (void*) aLanguage, sizeof(aLanguage),
803  "The default language setting.");
804 
805  hLastProperty = definePropertyHidden(hLastProperty, odbc_param_TextSize, "",
806  "Text datatype limit.");
807 
808  /* ??? in odbc.ini ??? */
809 /*
810  hLastProperty = definePropertyString(hLastProperty, odbc_param_UID, "",
811  "User ID (Beware of security issues).");
812 
813  hLastProperty = definePropertyString(hLastProperty, odbc_param_PWD, "",
814  "Password (Beware of security issues).");
815 */
816 
817 /*
818  hLastProperty = definePropertyList(hLastProperty, odbc_param_Authentication, "Server", aAuth, sizeof(aAuth),
819  "The server authentication mechanism.");
820 
821  hLastProperty = definePropertyString(hLastProperty, odbc_param_Domain, "",
822  "The default domain to use when using Domain Authentication.");
823 */
824 
825  hLastProperty = definePropertyString(hLastProperty, odbc_param_PacketSize, "",
826  "Size of network packets.");
827 
828  hLastProperty = definePropertyString(hLastProperty, odbc_param_ClientCharset, "",
829  "The client character set name to convert application characters to UCS-2 in TDS 7.0 and higher.");
830 
831  hLastProperty = definePropertyString(hLastProperty, odbc_param_DumpFile, "",
832  "Specifies the location of a tds dump file and turns on logging.");
833 
834  hLastProperty = definePropertyBoolean(hLastProperty, odbc_param_DumpFileAppend, "",
835  "Appends dump file instead of overwriting it. Useful for debugging when many processes are active.");
836 
837  hLastProperty = definePropertyString(hLastProperty, odbc_param_DebugFlags, "",
838  "Sets granularity of logging. A set of bit that specify levels and informations. See table below for bit specification.");
839 
840  hLastProperty = definePropertyList(hLastProperty, odbc_param_Encryption, TDS_STR_ENCRYPTION_OFF, aEncryption, sizeof(aEncryption),
841  "The encryption method.");
842 
843  return 1;
844 }
845 
846 #endif
std::ofstream out("events_result.xml")
main entry point for tests
static const char * PWD
Definition: common.c:39
void odbc_errs_add(struct _sql_errors *errs, const char *sqlstate, const char *msg)
add an error to list
Definition: error.c:382
#define ODBC_PARAM_LIST
Definition: odbc.h:498
@ ODBC_PARAM_Trusted_Connection
Definition: odbc.h:528
@ ODBC_PARAM_PWD
Definition: odbc.h:528
@ ODBC_PARAM_SIZE
Definition: odbc.h:529
@ ODBC_PARAM_UID
Definition: odbc.h:528
#define TDS_STR_DUMPFILE
Definition: tds.h:512
#define tds_new(type, n)
Definition: tds.h:1392
#define TDS_STR_READONLY_INTENT
Definition: tds.h:555
#define TDS_STR_PORT
Definition: tds.h:520
#define TDS_FAILED(rc)
Definition: tds.h:206
#define TDS_STR_CLCHARSET
Definition: tds.h:525
#define TDS_STR_VERSION
Definition: tds.h:509
#define tdsdump_log
Definition: tds.h:1561
#define TDS_DBG_INFO1
Definition: tds.h:900
#define TDS_DBG_WARN
Definition: tds.h:902
#define TDS_STR_ENCRYPTION_REQUEST
Definition: tds.h:538
#define TDS_STR_BLKSZ
Definition: tds.h:510
#define TDS_STR_ENCRYPTION_OFF
Definition: tds.h:537
#define TDS_STR_DEBUGFLAGS
Definition: tds.h:514
#define TDS_STR_ENCRYPTION
Definition: tds.h:533
#define TDS_STR_APPENDMODE
Definition: tds.h:528
#define TDS_STR_USENTLMV2
Definition: tds.h:534
#define TDS_DBG_ERROR
Definition: tds.h:903
#define TDS_STR_TEXTSZ
Definition: tds.h:521
#define TDS_STR_LANGUAGE
Definition: tds.h:527
#define TDS_STR_REALM
Definition: tds.h:543
#define TDS_STR_DBFILENAME
Definition: tds.h:553
#define TDS_SUCCEED(rc)
Definition: tds.h:207
#define TDS_STR_SPN
Definition: tds.h:545
#define TDS_STR_ENCRYPTION_REQUIRE
Definition: tds.h:539
#define TDS_DBG_FUNC
Definition: tds.h:898
static int myGetPrivateProfileString(const char *DSN, const char *key, char *buf)
int odbc_get_dsn_info(TDS_ERRS *errs, const char *DSN, TDSLOGIN *login)
Read connection information from given DSN.
#define CHK_PARAM(p)
int odbc_parse_connect_string(TDS_ERRS *errs, const char *connect_string, const char *connect_string_end, TDSLOGIN *login, TDS_PARSED_PARAM *parsed_params)
Parse connection string and fill login according.
static FILE * tdoGetIniFileName(void)
Call this to get the INI file containing Data Source Names.
static void tdoParseProfile(const char *option, const char *value, void *param)
static void odbc_dstr_swap(DSTR *a, DSTR *b)
Swap two DSTR.
static int parse_server(TDS_ERRS *errs, char *server, TDSLOGIN *login)
static int SQLGetPrivateProfileString(LPCSTR pszSection, LPCSTR pszEntry, LPCSTR pszDefault, LPSTR pRetBuffer, int nRetBuffer, LPCSTR pszFileName)
SQLGetPrivateProfileString.
#define SYS_ODBC_INI
Definition: connectparams.c:53
static char tmp[3200]
Definition: utf8.c:42
#define asprintf
Definition: replacements.h:54
#define strlcpy(d, s, l)
Definition: replacements.h:80
char * LPSTR
Definition: sqlfront.h:34
const char * LPCSTR
Definition: sqlfront.h:39
#define option
static TDSLOGIN * login
Definition: dataread.c:31
#define tds_read_conf_file
#define tds_lookup_host_set
#define tds_read_conf_section
#define tds_parse_conf_section
#define tds_config_boolean
#define tds_get_homedir
#define NULL
Definition: ncbistd.hpp:225
#define FILENAME_MAX
Definition: ncbifile.hpp:94
static const char * tds_dstr_cstr(DSTR *s)
Returns a C version (NUL terminated string) of dstr.
Definition: string.h:66
#define tds_dstr_empty(s)
Make a string empty.
Definition: string.h:79
#define DSTR_INITIALIZER
Initializer, used to initialize string like in the following example.
Definition: string.h:37
DSTR * tds_dstr_copyn(DSTR *s, const char *src, size_t length) TDS_WUR
Set string to a given buffer of characters.
Definition: tdsstring.c:78
void tds_dstr_free(DSTR *s)
free string
Definition: tdsstring.c:63
DSTR * tds_dstr_copy(DSTR *s, const char *src) TDS_WUR
copy a string from another
Definition: tdsstring.c:123
static int tds_dstr_isempty(DSTR *s)
test if string is empty
Definition: string.h:48
unsigned int
A callback function used to compare two keys in a database.
Definition: types.hpp:1210
char * buf
yy_size_t n
int len
const struct ncbi::grid::netcache::search::fields::SIZE size
const struct ncbi::grid::netcache::search::fields::KEY key
const GenericPointer< typename T::ValueType > T2 value
Definition: pointer.h:1227
#define strdup
Definition: ncbi_ansi_ext.h:70
#define strcasecmp
unsigned int a
Definition: ncbi_localip.c:102
#define INSTAPI
Definition: odbcinst.h:154
size_t len
Definition: odbc.h:540
const char * p
Definition: odbc.h:539
Structure to hold a string.
Definition: tds.h:116
Definition: tds.h:584
DSTR database
Definition: tds.h:611
DSTR user_name
account for login
Definition: tds.h:601
struct addrinfo * ip_addrs
ip(s) of server
Definition: tds.h:613
DSTR password
password of account login
Definition: tds.h:602
DSTR db_filename
database filename to attach (MSSQL)
Definition: tds.h:596
DSTR client_host_name
Definition: tds.h:592
DSTR server_name
server name (in freetds.conf)
Definition: tds.h:585
DSTR instance_name
Definition: tds.h:615
DSTR server_host_name
Definition: tds.h:593
unsigned int mars
Definition: tds.h:630
int port
port of database service
Definition: tds.h:586
DSTR app_name
Definition: tds.h:600
void free(voidpf ptr)
voidp malloc(uInt size)
voidp calloc(uInt items, uInt size)
Modified on Fri Sep 20 14:58:29 2024 by modify_doxy.py rev. 669887