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

Go to the SVN repository for this file.

Go to the SVN repository for this file.

Go to the SVN repository for this file.

Go to the SVN repository for this file.

Go to the SVN repository for this file.

Go to the SVN repository for this file.

Go to the SVN repository for this file.

Go to the SVN repository for this file.

Go to the SVN repository for 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) 2006, 2007, 2008, 2009, 2010, 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 
26 #if HAVE_ERRNO_H
27 #include <errno.h>
28 #endif /* HAVE_ERRNO_H */
29 
30 #include <assert.h>
31 #include <ctype.h>
32 
33 #if HAVE_STDLIB_H
34 #include <stdlib.h>
35 #endif /* HAVE_STDLIB_H */
36 
37 #if HAVE_LIMITS_H
38 #include <limits.h>
39 #endif
40 
41 #if HAVE_STRING_H
42 #include <string.h>
43 #endif /* HAVE_STRING_H */
44 
45 #if HAVE_UNISTD_H
46 #include <unistd.h>
47 #endif /* HAVE_UNISTD_H */
48 
49 #if HAVE_NETDB_H
50 #include <netdb.h>
51 #endif /* HAVE_NETDB_H */
52 
53 #if HAVE_SYS_SOCKET_H
54 #include <sys/socket.h>
55 #endif /* HAVE_SYS_SOCKET_H */
56 
57 #if HAVE_SYS_TYPES_H
58 #include <sys/types.h>
59 #endif /* HAVE_SYS_TYPES_H */
60 
61 #if HAVE_NETINET_IN_H
62 #include <netinet/in.h>
63 #endif /* HAVE_NETINET_IN_H */
64 
65 #if HAVE_ARPA_INET_H
66 #include <arpa/inet.h>
67 #endif /* HAVE_ARPA_INET_H */
68 
69 #ifdef _WIN32
70 #include <process.h>
71 #endif
72 
73 #include <freetds/tds.h>
74 #include <freetds/configs.h>
75 #include <freetds/string.h>
76 #include "replacements.h"
77 
78 static int tds_config_login(TDSLOGIN * connection, TDSLOGIN * login);
80 static void tds_config_env_tdsver(TDSLOGIN * login);
83 static int tds_read_conf_sections(FILE * in, const char *server, TDSLOGIN * login);
84 static int tds_read_interfaces(const char *server, TDSLOGIN * login);
85 static int parse_server_name_for_port(TDSLOGIN * connection, TDSLOGIN * login);
86 static int tds_lookup_port(const char *portname);
87 static void tds_config_encryption(const char * value, TDSLOGIN * login);
88 
89 static char *interf_file = NULL;
90 
91 #define TDS_ISSPACE(c) isspace((unsigned char ) (c))
92 
93  const char STD_DATETIME_FMT[] = "%Y-%m-%d %H:%M:%S.%z";
94 #if !defined(_WIN32) && !defined(DOS32X)
95 static const char pid_config_logpath[] = "/tmp/tdsconfig.log.%d";
96 static const char freetds_conf[] = "%s/etc/freetds.conf";
97 static const char location[] = "(from $FREETDS/etc)";
98 static const char pid_logpath[] = "/tmp/freetds.log.%d";
99 static const char interfaces_path[] = "/etc/freetds";
100 #else
101 static const char pid_config_logpath[] = "c:\\tdsconfig.log.%d";
102 static const char freetds_conf [] = "%s\\freetds.conf";
103 static const char location[] = "(from $FREETDS)";
104 static const char pid_logpath[] = "c:\\freetds.log.%d";
105 static const char interfaces_path[] = "c:\\";
106 #endif
107 
108 /**
109  * \ingroup libtds
110  * \defgroup config Configuration
111  * Handle reading of configuration
112  */
113 
114 /**
115  * \addtogroup config
116  * @{
117  */
118 
119 /**
120  * tds_read_config_info() will fill the tds connection structure based on configuration
121  * information gathered in the following order:
122  * 1) Program specified in TDSLOGIN structure
123  * 2) The environment variables TDSVER, TDSDUMP, TDSPORT, TDSQUERY, TDSHOST
124  * 3) A config file with the following search order:
125  * a) a readable file specified by environment variable FREETDSCONF
126  * b) a readable file in ~/.freetds.conf
127  * c) a readable file in $prefix/etc/freetds.conf
128  * 3) ~/.interfaces if exists
129  * 4) $SYBASE/interfaces if exists
130  * 5) TDS_DEF_* default values
131  *
132  * .tdsrc and freetds.conf have been added to make the package easier to
133  * integration with various Linux and *BSD distributions.
134  */
135 TDSLOGIN *
137 {
138  TDSLOGIN *connection;
139  char *s;
140  char *path;
141  pid_t pid;
142  int opened = 0, found;
143  struct addrinfo *addrs;
144 
145  /* allocate a new structure with hard coded and build-time defaults */
146  connection = tds_alloc_login(0);
147  if (!connection || !tds_init_login(connection, locale)) {
148  tds_free_login(connection);
149  return NULL;
150  }
151 
152  s = getenv("TDSDUMPCONFIG");
153  if (s) {
154  if (*s) {
155  opened = tdsdump_open(s);
156  } else {
157  pid = getpid();
158  if (asprintf(&path, pid_config_logpath, pid) >= 0) {
159  if (*path) {
160  opened = tdsdump_open(path);
161  }
162  free(path);
163  }
164  }
165  }
166 
167  tdsdump_log(TDS_DBG_INFO1, "Getting connection information for [%s].\n",
168  tds_dstr_cstr(&login->server_name)); /* (The server name is set in login.c.) */
169 
170  /* Read the config files. */
171  tdsdump_log(TDS_DBG_INFO1, "Attempting to read conf files.\n");
172  found = tds_read_conf_file(connection, tds_dstr_cstr(&login->server_name));
173  if (!found) {
174  if (parse_server_name_for_port(connection, login)) {
175 
176  found = tds_read_conf_file(connection, tds_dstr_cstr(&connection->server_name));
177  /* do it again to really override what found in freetds.conf */
178  if (found) {
179  parse_server_name_for_port(connection, login);
180  } else if (TDS_SUCCEED(tds_lookup_host_set(tds_dstr_cstr(&connection->server_name), &connection->ip_addrs))) {
181  if (!tds_dstr_dup(&connection->server_host_name, &connection->server_name)) {
182  tds_free_login(connection);
183  return NULL;
184  }
185  found = 1;
186  }
187  }
188  }
189  if (!found) {
190  /* fallback to interfaces file */
191  tdsdump_log(TDS_DBG_INFO1, "Failed in reading conf file. Trying interface files.\n");
192  if (!tds_read_interfaces(tds_dstr_cstr(&login->server_name), connection)) {
193  tdsdump_log(TDS_DBG_INFO1, "Failed to find [%s] in configuration files; trying '%s' instead.\n",
195  if (connection->ip_addrs == NULL)
197  }
198  }
199 
200  /* Override config file settings with environment variables. */
201  tds_fix_login(connection);
202 
203  /* And finally apply anything from the login structure */
204  if (!tds_config_login(connection, login)) {
205  tds_free_login(connection);
206  return NULL;
207  }
208 
209  if (opened) {
210  char tmp[128];
211 
212  tdsdump_log(TDS_DBG_INFO1, "Final connection parameters:\n");
213  tdsdump_log(TDS_DBG_INFO1, "\t%20s = %s\n", "server_name", tds_dstr_cstr(&connection->server_name));
214  tdsdump_log(TDS_DBG_INFO1, "\t%20s = %s\n", "server_host_name", tds_dstr_cstr(&connection->server_host_name));
215 
216  for (addrs = connection->ip_addrs; addrs != NULL; addrs = addrs->ai_next)
217  tdsdump_log(TDS_DBG_INFO1, "\t%20s = %s\n", "ip_addr", tds_addrinfo2str(addrs, tmp, sizeof(tmp)));
218 
219  if (connection->ip_addrs == NULL)
220  tdsdump_log(TDS_DBG_INFO1, "\t%20s = %s\n", "ip_addr", "");
221 
222  tdsdump_log(TDS_DBG_INFO1, "\t%20s = %s\n", "instance_name", tds_dstr_cstr(&connection->instance_name));
223  tdsdump_log(TDS_DBG_INFO1, "\t%20s = %d\n", "port", connection->port);
224  tdsdump_log(TDS_DBG_INFO1, "\t%20s = %d\n", "major_version", TDS_MAJOR(connection));
225  tdsdump_log(TDS_DBG_INFO1, "\t%20s = %d\n", "minor_version", TDS_MINOR(connection));
226  tdsdump_log(TDS_DBG_INFO1, "\t%20s = %d\n", "block_size", connection->block_size);
227  tdsdump_log(TDS_DBG_INFO1, "\t%20s = %s\n", "language", tds_dstr_cstr(&connection->language));
228  tdsdump_log(TDS_DBG_INFO1, "\t%20s = %s\n", "server_charset", tds_dstr_cstr(&connection->server_charset));
229  tdsdump_log(TDS_DBG_INFO1, "\t%20s = %d\n", "connect_timeout", connection->connect_timeout);
230  tdsdump_log(TDS_DBG_INFO1, "\t%20s = %s\n", "client_host_name", tds_dstr_cstr(&connection->client_host_name));
231  tdsdump_log(TDS_DBG_INFO1, "\t%20s = %s\n", "client_charset", tds_dstr_cstr(&connection->client_charset));
232  tdsdump_log(TDS_DBG_INFO1, "\t%20s = %d\n", "use_utf16", connection->use_utf16);
233  tdsdump_log(TDS_DBG_INFO1, "\t%20s = %s\n", "app_name", tds_dstr_cstr(&connection->app_name));
234  tdsdump_log(TDS_DBG_INFO1, "\t%20s = %s\n", "user_name", tds_dstr_cstr(&connection->user_name));
235  /* tdsdump_log(TDS_DBG_PASSWD, "\t%20s = %s\n", "password", tds_dstr_cstr(&connection->password));
236  (no such flag yet) */
237  tdsdump_log(TDS_DBG_INFO1, "\t%20s = %s\n", "library", tds_dstr_cstr(&connection->library));
238  tdsdump_log(TDS_DBG_INFO1, "\t%20s = %d\n", "bulk_copy", (int)connection->bulk_copy);
239  tdsdump_log(TDS_DBG_INFO1, "\t%20s = %d\n", "suppress_language", (int)connection->suppress_language);
240  tdsdump_log(TDS_DBG_INFO1, "\t%20s = %d\n", "encrypt level", (int)connection->encryption_level);
241  tdsdump_log(TDS_DBG_INFO1, "\t%20s = %d\n", "query_timeout", connection->query_timeout);
242  /* tdsdump_log(TDS_DBG_INFO1, "\t%20s = %s\n", "capabilities", tds_dstr_cstr(&connection->capabilities));
243  (not null terminated) */
244  tdsdump_log(TDS_DBG_INFO1, "\t%20s = %s\n", "database", tds_dstr_cstr(&connection->database));
245  tdsdump_log(TDS_DBG_INFO1, "\t%20s = %s\n", "dump_file", tds_dstr_cstr(&connection->dump_file));
246  tdsdump_log(TDS_DBG_INFO1, "\t%20s = %x\n", "debug_flags", connection->debug_flags);
247  tdsdump_log(TDS_DBG_INFO1, "\t%20s = %d\n", "text_size", connection->text_size);
248  tdsdump_log(TDS_DBG_INFO1, "\t%20s = %d\n", "emul_little_endian", connection->emul_little_endian);
249  tdsdump_log(TDS_DBG_INFO1, "\t%20s = %s\n", "server_realm_name", tds_dstr_cstr(&connection->server_realm_name));
250  tdsdump_log(TDS_DBG_INFO1, "\t%20s = %s\n", "server_spn", tds_dstr_cstr(&connection->server_spn));
251  tdsdump_log(TDS_DBG_INFO1, "\t%20s = %s\n", "cafile", tds_dstr_cstr(&connection->cafile));
252  tdsdump_log(TDS_DBG_INFO1, "\t%20s = %s\n", "crlfile", tds_dstr_cstr(&connection->crlfile));
253  tdsdump_log(TDS_DBG_INFO1, "\t%20s = %d\n", "check_ssl_hostname", connection->check_ssl_hostname);
254  tdsdump_log(TDS_DBG_INFO1, "\t%20s = %s\n", "db_filename", tds_dstr_cstr(&connection->db_filename));
255  tdsdump_log(TDS_DBG_INFO1, "\t%20s = %d\n", "readonly_intent", connection->readonly_intent);
256 #ifdef HAVE_OPENSSL
257  tdsdump_log(TDS_DBG_INFO1, "\t%20s = %s\n", "openssl_ciphers", tds_dstr_cstr(&connection->openssl_ciphers));
258 #endif
259 
260  tdsdump_close();
261  }
262 
263  /*
264  * If a dump file has been specified, start logging
265  */
266  if (!tds_dstr_isempty(&connection->dump_file) && !tdsdump_isopen()) {
267  if (connection->debug_flags)
268  tds_debug_flags = connection->debug_flags;
269  tdsdump_open(tds_dstr_cstr(&connection->dump_file));
270  }
271 
272  return connection;
273 }
274 
275 /**
276  * Fix configuration after reading it.
277  * Currently this read some environment variables and replace some options.
278  */
279 void
281 {
282  /* Now check the environment variables */
287 }
288 
289 static int
290 tds_try_conf_file(const char *path, const char *how, const char *server, TDSLOGIN * login)
291 {
292  int found = 0;
293  FILE *in;
294 
295  if ((in = fopen(path, "r")) == NULL) {
296  tdsdump_log(TDS_DBG_INFO1, "Could not open '%s' (%s).\n", path, how);
297  return found;
298  }
299 
300  tdsdump_log(TDS_DBG_INFO1, "Found conf file '%s' %s.\n", path, how);
301  found = tds_read_conf_sections(in, server, login);
302 
303  if (found) {
304  tdsdump_log(TDS_DBG_INFO1, "Success: [%s] defined in %s.\n", server, path);
305  } else {
306  tdsdump_log(TDS_DBG_INFO2, "[%s] not found.\n", server);
307  }
308 
309  fclose(in);
310 
311  return found;
312 }
313 
314 
315 /**
316  * Return filename from HOME directory
317  * @return allocated string or NULL if error
318  */
319 static char *
321 {
322  char *home, *path;
323 
324  home = tds_get_homedir();
325  if (!home)
326  return NULL;
327  if (asprintf(&path, "%s/%s", home, file) < 0)
328  path = NULL;
329  free(home);
330  return path;
331 }
332 
333 /**
334  * Read configuration info for given server
335  * return 0 on error
336  * @param login where to store configuration
337  * @param server section of file configuration that hold
338  * configuration for a server
339  */
340 int
341 tds_read_conf_file(TDSLOGIN * login, const char *server)
342 {
343  char *path = NULL;
344  char *eptr = NULL;
345  int found = 0;
346 
347  if (interf_file) {
348  found = tds_try_conf_file(interf_file, "set programmatically", server, login);
349  }
350 
351  /* FREETDSCONF env var, pkleef@openlinksw.com 01/21/02 */
352  if (!found) {
353  path = getenv("FREETDSCONF");
354  if (path) {
355  found = tds_try_conf_file(path, "(from $FREETDSCONF)", server, login);
356  } else {
357  tdsdump_log(TDS_DBG_INFO2, "... $FREETDSCONF not set. Trying $FREETDS/etc.\n");
358  }
359  }
360 
361  /* FREETDS env var, Bill Thompson 16/07/03 */
362  if (!found) {
363  eptr = getenv("FREETDS");
364  if (eptr) {
365  if (asprintf(&path, freetds_conf, eptr) >= 0) {
366  found = tds_try_conf_file(path, location, server, login);
367  free(path);
368  }
369  } else {
370  tdsdump_log(TDS_DBG_INFO2, "... $FREETDS not set. Trying $HOME.\n");
371  }
372  }
373 
374  if (!found) {
375  path = tds_get_home_file(".freetds.conf");
376  if (path) {
377  found = tds_try_conf_file(path, "(.freetds.conf)", server, login);
378  free(path);
379  } else {
380  tdsdump_log(TDS_DBG_INFO2, "... Error getting ~/.freetds.conf. Trying %s.\n", FREETDS_SYSCONFFILE);
381  }
382  }
383 
384  if (!found) {
385  found = tds_try_conf_file(FREETDS_SYSCONFFILE, "(default)", server, login);
386  }
387 
388  return found;
389 }
390 
391 static int
392 tds_read_conf_sections(FILE * in, const char *server, TDSLOGIN * login)
393 {
394  DSTR default_instance = DSTR_INITIALIZER;
395  int default_port;
396 
397  int found;
398 
400 
401  if (!server[0])
402  return 0;
403  rewind(in);
404 
405  if (!tds_dstr_dup(&default_instance, &login->instance_name))
406  return 0;
407  default_port = login->port;
408 
410  if (!login->valid_configuration) {
411  tds_dstr_free(&default_instance);
412  return 0;
413  }
414 
415  /*
416  * If both instance and port are specified and neither one came from the default, it's an error
417  * TODO: If port/instance is specified in the non-default, it has priority over the default setting.
418  * TODO: test this.
419  */
421  !(!tds_dstr_isempty(&default_instance) || default_port)) {
422  tdsdump_log(TDS_DBG_ERROR, "error: cannot specify both port %d and instance %s.\n",
424  /* tdserror(tds_get_ctx(tds), tds, TDSEPORTINSTANCE, 0); */
425  }
426  tds_dstr_free(&default_instance);
427  return found;
428 }
429 
430 static const struct {
431  char value[7];
432  unsigned char to_return;
433 } boolean_values[] = {
434  { "yes", 1 },
435  { "no", 0 },
436  { "on", 1 },
437  { "off", 0 },
438  { "true", 1 },
439  { "false", 0 }
440 };
441 
442 int
443 tds_parse_boolean(const char *value, int default_value)
444 {
445  int p;
446 
447  for (p = 0; p < TDS_VECTOR_SIZE(boolean_values); ++p) {
449  return boolean_values[p].to_return;
450  }
451  return default_value;
452 }
453 
454 int
455 tds_config_boolean(const char *option, const char *value, TDSLOGIN *login)
456 {
457  int ret = tds_parse_boolean(value, -1);
458  if (ret >= 0)
459  return ret;
460 
461  tdsdump_log(TDS_DBG_ERROR, "UNRECOGNIZED option value '%s' for boolean setting '%s'!\n",
462  value, option);
464  return 0;
465 }
466 
467 static void
469 {
471 
473  ;
478  else {
479  tdsdump_log(TDS_DBG_ERROR, "UNRECOGNIZED option value '%s' for '%s' setting!\n",
481  tdsdump_log(TDS_DBG_ERROR, "Valid settings are: ('%s', '%s', '%s')\n",
483  lvl = TDS_ENCRYPTION_REQUIRE; /* Assuming "require" is safer than "no" */
485  }
486 
487  login->encryption_level = lvl;
488 }
489 
490 /**
491  * Read a section of configuration file (INI style file)
492  * @param in configuration file
493  * @param section section to read
494  * @param tds_conf_parse callback that receive every entry in section
495  * @param param parameter to pass to callback function
496  */
497 int
498 tds_read_conf_section(FILE * in, const char *section, TDSCONFPARSE tds_conf_parse, void *param)
499 {
500  char line[256], *value;
501 #define option line
502  char *s;
503  char p;
504  int i;
505  int insection = 0;
506  int found = 0;
507 
508  tdsdump_log(TDS_DBG_INFO1, "Looking for section %s.\n", section);
509  while (fgets(line, sizeof(line), in)) {
510  s = line;
511 
512  /* skip leading whitespace */
513  while (*s && TDS_ISSPACE(*s))
514  s++;
515 
516  /* skip it if it's a comment line */
517  if (*s == ';' || *s == '#')
518  continue;
519 
520  /* read up to the = ignoring duplicate spaces */
521  p = 0;
522  i = 0;
523  while (*s && *s != '=') {
524  if (!TDS_ISSPACE(*s)) {
525  if (TDS_ISSPACE(p))
526  option[i++] = ' ';
527  option[i++] = tolower((unsigned char) *s);
528  }
529  p = *s;
530  s++;
531  }
532 
533  /* skip if empty option */
534  if (!i)
535  continue;
536 
537  /* skip the = */
538  if (*s)
539  s++;
540 
541  /* terminate the option, must be done after skipping = */
542  option[i] = '\0';
543 
544  /* skip leading whitespace */
545  while (*s && TDS_ISSPACE(*s))
546  s++;
547 
548  /* read up to a # ; or null ignoring duplicate spaces */
549  value = s;
550  p = 0;
551  i = 0;
552  while (*s && *s != ';' && *s != '#') {
553  if (!TDS_ISSPACE(*s)) {
554  if (TDS_ISSPACE(p))
555  value[i++] = ' ';
556  value[i++] = *s;
557  }
558  p = *s;
559  s++;
560  }
561  value[i] = '\0';
562 
563  if (option[0] == '[') {
564  s = strchr(option, ']');
565  if (s)
566  *s = '\0';
567  tdsdump_log(TDS_DBG_INFO1, "\tFound section %s.\n", &option[1]);
568 
569  if (!strcasecmp(section, &option[1])) {
570  tdsdump_log(TDS_DBG_INFO1, "Got a match.\n");
571  insection = 1;
572  found = 1;
573  } else {
574  insection = 0;
575  }
576  } else if (insection) {
577  tds_conf_parse(option, value, param);
578  }
579 
580  }
581  tdsdump_log(TDS_DBG_INFO1, "\tReached EOF\n");
582  return found;
583 #undef option
584 }
585 
586 /* Also used to scan ODBC.INI entries */
587 void
588 tds_parse_conf_section(const char *option, const char *value, void *param)
589 {
590  TDSLOGIN *login = (TDSLOGIN *) param;
591  void *s = param;
592 
593  tdsdump_log(TDS_DBG_INFO1, "\t%s = '%s'\n", option, value);
594 
595  if (!strcmp(option, TDS_STR_VERSION)) {
597  } else if (!strcmp(option, TDS_STR_BLKSZ)) {
598  int val = atoi(value);
599  if (val >= 512 && val < 65536)
600  login->block_size = val;
601  } else if (!strcmp(option, TDS_STR_SWAPDT)) {
602  /* this option is deprecated, just check value for compatibility */
604  } else if (!strcmp(option, TDS_GSSAPI_DELEGATION)) {
605  /* gssapi flag addition */
607  } else if (!strcmp(option, TDS_STR_DUMPFILE)) {
609  } else if (!strcmp(option, TDS_STR_DEBUGFLAGS)) {
610  char *end;
611  long flags;
612  flags = strtol(value, &end, 0);
613  if (*value != '\0' && *end == '\0' && flags > INT_MIN
614  && flags < INT_MAX)
615  login->debug_flags = (int) flags;
617  if (atoi(value))
618  login->query_timeout = atoi(value);
619  } else if (!strcmp(option, TDS_STR_CONNTIMEOUT)) {
620  if (atoi(value))
621  login->connect_timeout = atoi(value);
622  } else if (!strcmp(option, TDS_STR_HOST)) {
623  char tmp[128];
624  struct addrinfo *addrs;
625 
627  tdsdump_log(TDS_DBG_WARN, "Found host entry %s however name resolution failed. \n", value);
628  return;
629  }
630 
631  tdsdump_log(TDS_DBG_INFO1, "Found host entry %s \n", value);
633  for (addrs = login->ip_addrs; addrs != NULL; addrs = addrs->ai_next)
634  tdsdump_log(TDS_DBG_INFO1, "IP addr is %s.\n", tds_addrinfo2str(addrs, tmp, sizeof(tmp)));
635 
636  } else if (!strcmp(option, TDS_STR_PORT)) {
637  if (atoi(value))
638  login->port = atoi(value);
639  } else if (!strcmp(option, TDS_STR_EMUL_LE)) {
641  } else if (!strcmp(option, TDS_STR_TEXTSZ)) {
642  if (atoi(value))
643  login->text_size = atoi(value);
644  } else if (!strcmp(option, TDS_STR_CHARSET)) {
647  } else if (!strcmp(option, TDS_STR_CLCHARSET)) {
649  tdsdump_log(TDS_DBG_INFO1, "tds_parse_conf_section: %s is %s.\n", option, tds_dstr_cstr(&login->client_charset));
650  } else if (!strcmp(option, TDS_STR_USE_UTF_16)) {
652  } else if (!strcmp(option, TDS_STR_LANGUAGE)) {
654  } else if (!strcmp(option, TDS_STR_APPENDMODE)) {
656  } else if (!strcmp(option, TDS_STR_INSTANCE)) {
658  } else if (!strcmp(option, TDS_STR_ENCRYPTION)) {
660  } else if (!strcmp(option, TDS_STR_ASA_DATABASE)) {
662  } else if (!strcmp(option, TDS_STR_USENTLMV2)) {
664  } else if (!strcmp(option, TDS_STR_USELANMAN)) {
666  } else if (!strcmp(option, TDS_STR_REALM)) {
668  } else if (!strcmp(option, TDS_STR_SPN)) {
670  } else if (!strcmp(option, TDS_STR_CAFILE)) {
672  } else if (!strcmp(option, TDS_STR_CRLFILE)) {
674  } else if (!strcmp(option, TDS_STR_CHECKSSLHOSTNAME)) {
676  } else if (!strcmp(option, TDS_STR_DBFILENAME)) {
678  } else if (!strcmp(option, TDS_STR_DATABASE)) {
680  } else if (!strcmp(option, TDS_STR_READONLY_INTENT)) {
682  tdsdump_log(TDS_DBG_FUNC, "Setting ReadOnly Intent to '%s'.\n", value);
683  } else if (!strcmp(option, TLS_STR_OPENSSL_CIPHERS)) {
685  } else {
686  tdsdump_log(TDS_DBG_INFO1, "UNRECOGNIZED option '%s' ... ignoring.\n", option);
687  }
688 
689  if (login != NULL && s == NULL)
691 }
692 
693 static int
695 {
696  DSTR *res = &login->server_name;
697 
699  if (1 || tds_dstr_isempty(&connection->server_name))
700  res = tds_dstr_dup(&connection->server_name, &login->server_name);
701  }
702  if (login->tds_version)
703  connection->tds_version = login->tds_version;
704  if (res && !tds_dstr_isempty(&login->language)) {
705  res = tds_dstr_dup(&connection->language, &login->language);
706  }
707  if (res && !tds_dstr_isempty(&login->server_charset)) {
708  res = tds_dstr_dup(&connection->server_charset, &login->server_charset);
709  }
710  if (res && !tds_dstr_isempty(&login->client_charset)) {
711  res = tds_dstr_dup(&connection->client_charset, &login->client_charset);
712  tdsdump_log(TDS_DBG_INFO1, "tds_config_login: %s is %s.\n", "client_charset",
713  tds_dstr_cstr(&connection->client_charset));
714  }
715  if (!login->use_utf16)
716  connection->use_utf16 = login->use_utf16;
717  if (res && !tds_dstr_isempty(&login->database)) {
718  res = tds_dstr_dup(&connection->database, &login->database);
719  tdsdump_log(TDS_DBG_INFO1, "tds_config_login: %s is %s.\n", "database_name",
720  tds_dstr_cstr(&connection->database));
721  }
722  if (res && !tds_dstr_isempty(&login->client_host_name)) {
723  res = tds_dstr_dup(&connection->client_host_name, &login->client_host_name);
724  }
725  if (res && !tds_dstr_isempty(&login->app_name)) {
726  res = tds_dstr_dup(&connection->app_name, &login->app_name);
727  }
728  if (res && !tds_dstr_isempty(&login->user_name)) {
729  res = tds_dstr_dup(&connection->user_name, &login->user_name);
730  }
731  if (res && !tds_dstr_isempty(&login->password)) {
732  /* for security reason clear memory */
733  tds_dstr_zero(&connection->password);
734  res = tds_dstr_dup(&connection->password, &login->password);
735  }
736  if (res && !tds_dstr_isempty(&login->library)) {
737  res = tds_dstr_dup(&connection->library, &login->library);
738  }
739  if (login->encryption_level) {
740  connection->encryption_level = login->encryption_level;
741  }
742  if (login->suppress_language) {
743  connection->suppress_language = 1;
744  }
745  if (!login->bulk_copy) {
746  connection->bulk_copy = 0;
747  }
748  if (login->block_size) {
749  connection->block_size = login->block_size;
750  }
751  if (login->port)
752  connection->port = login->port;
753  if (login->connect_timeout)
754  connection->connect_timeout = login->connect_timeout;
755 
756  if (login->query_timeout)
757  connection->query_timeout = login->query_timeout;
758 
761 
762  if (res && !tds_dstr_isempty(&login->db_filename)) {
763  res = tds_dstr_dup(&connection->db_filename, &login->db_filename);
764  }
765 
766  if (res && !tds_dstr_isempty(&login->openssl_ciphers)) {
767  res = tds_dstr_dup(&connection->openssl_ciphers, &login->openssl_ciphers);
768  }
769 
770  /* copy other info not present in configuration file */
771  connection->capabilities = login->capabilities;
772 
773  if (login->readonly_intent)
774  connection->readonly_intent = login->readonly_intent;
775  connection->use_new_password = login->use_new_password;
776  if (res)
777  res = tds_dstr_dup(&connection->new_password, &login->new_password);
778 
779  return res != NULL;
780 }
781 
782 static int
784 {
785  char *s;
786  char *path;
787  pid_t pid = 0;
788 
789  if ((s = getenv("TDSDUMP"))) {
790  if (!strlen(s)) {
791  pid = getpid();
792  if (asprintf(&path, pid_logpath, pid) < 0)
793  return 0;
794  if (!tds_dstr_set(&login->dump_file, path)) {
795  free(path);
796  return 0;
797  }
798  } else {
799  if (!tds_dstr_copy(&login->dump_file, s))
800  return 0;
801  }
802  tdsdump_log(TDS_DBG_INFO1, "Setting 'dump_file' to '%s' from $TDSDUMP.\n", tds_dstr_cstr(&login->dump_file));
803  }
804  return 1;
805 }
806 static void
808 {
809  char *s;
810 
811  if ((s = getenv("TDSPORT"))) {
812  login->port = tds_lookup_port(s);
814  tdsdump_log(TDS_DBG_INFO1, "Setting 'port' to %s from $TDSPORT.\n", s);
815  }
816  return;
817 }
818 static void
820 {
821  char *tdsver;
822 
823  if ((tdsver = getenv("TDSVER"))) {
824  TDS_USMALLINT *pver = tds_config_verstr(tdsver, login);
825  tdsdump_log(TDS_DBG_INFO1, "TDS version %sset to %s from $TDSVER.\n", (pver? "":"not "), tdsver);
826 
827  }
828  return;
829 }
830 
831 /* TDSHOST env var, pkleef@openlinksw.com 01/21/02 */
832 static int
834 {
835  const char *tdshost;
836  char tmp[128];
837  struct addrinfo *addrs;
838 
839  if (!(tdshost = getenv("TDSHOST")))
840  return 1;
841 
842  if (TDS_FAILED(tds_lookup_host_set(tdshost, &login->ip_addrs))) {
843  tdsdump_log(TDS_DBG_WARN, "Name resolution failed for '%s' from $TDSHOST.\n", tdshost);
844  return 0;
845  }
846 
847  if (!tds_dstr_copy(&login->server_host_name, tdshost))
848  return 0;
849  for (addrs = login->ip_addrs; addrs != NULL; addrs = addrs->ai_next) {
850  tdsdump_log(TDS_DBG_INFO1, "Setting IP Address to %s (%s) from $TDSHOST.\n",
851  tds_addrinfo2str(addrs, tmp, sizeof(tmp)), tdshost);
852  }
853  return 1;
854 }
855 #define TDS_FIND(k,b,c) tds_find(k, b, sizeof(b)/sizeof(b[0]), sizeof(b[0]), c)
856 
857 
858 static void *
859 tds_find(const void *key, const void *base, size_t nelem, size_t width,
860  int (*compar)(const void *, const void *))
861 {
862  size_t i;
863  for (i=0; i < nelem; i++) {
864  char *p = (char*)base + width * i;
865  if (0 == compar(key, p)) {
866  return p;
867  }
868  }
869  return NULL;
870 }
871 
873 {
874  const char name[6];
876 };
877 
878 static int
879 tds_vernanme_cmp(const void *key, const void *pelem)
880 {
881  return strcmp((const char *)key, ((const struct tdsvername_t *)pelem)->name);
882 }
883 
884 /**
885  * Set TDS version from given string
886  * @param tdsver tds string version
887  * @param login where to store information
888  * @return as encoded hex value: high nybble major, low nybble minor.
889  */
891 tds_config_verstr(const char *tdsver, TDSLOGIN * login)
892 {
893  static const struct tdsvername_t tds_versions[] =
894  { { "0", 0x000 }
895  , {"auto", 0x000 }
896  , { "4.2", 0x402 }
897  , { "4.2", 0x402 }
898  , { "46", 0x406 }
899  , { "4.6", 0x406 }
900  , { "50", 0x500 }
901  , { "5.0", 0x500 }
902  , { "70", 0x700 }
903  , { "7.0", 0x700 }
904  , { "80", 0x701 }
905  , { "8.0", 0x701 }
906  , { "7.1", 0x701 }
907  , { "7.2", 0x702 }
908  , { "7.3", 0x703 }
909  , { "7.4", 0x704 }
910  };
911  const struct tdsvername_t *pver;
912 
913  if (!login) {
914  assert(login);
915  return NULL;
916  }
917 
918  if ((pver = (const struct tdsvername_t *) TDS_FIND(tdsver, tds_versions, tds_vernanme_cmp)) == NULL) {
919  tdsdump_log(TDS_DBG_INFO1, "error: no such version: %s\n", tdsver);
920  return NULL;
921  }
922 
923  login->tds_version = pver->version;
924  tdsdump_log(TDS_DBG_INFO1, "Setting tds version to %s (0x%0x).\n", tdsver, pver->version);
925 
926  return &login->tds_version;
927 }
928 
929 /**
930  * Set the full name of interface file
931  * @param interf file name
932  */
933 TDSRET
934 tds_set_interfaces_file_loc(const char *interf)
935 {
936  /* Free it if already set */
937  if (interf_file != NULL)
939  /* If no filename passed, leave it NULL */
940  if ((interf == NULL) || (interf[0] == '\0')) {
941  return TDS_SUCCESS;
942  }
943  /* Set to new value */
944  if ((interf_file = strdup(interf)) == NULL) {
945  return TDS_FAIL;
946  }
947  return TDS_SUCCESS;
948 }
949 
950 /**
951  * Get the IP address for a hostname. Store server's IP address
952  * in the string 'ip' in dotted-decimal notation. (The "hostname" might itself
953  * be a dotted-decimal address.
954  *
955  * If we can't determine the IP address then 'ip' will be set to empty
956  * string.
957  */
958 /* TODO callers seem to set always connection info... change it */
959 struct addrinfo *
960 tds_lookup_host(const char *servername) /* (I) name of the server */
961 {
962  struct addrinfo hints, *addr = NULL;
963  assert(servername != NULL);
964 
965  memset(&hints, '\0', sizeof(hints));
966  hints.ai_family = AF_UNSPEC;
967  hints.ai_socktype = SOCK_STREAM;
968 
969 #ifdef AI_ADDRCONFIG
970  hints.ai_flags |= AI_ADDRCONFIG;
971 #endif
972 
973  if (getaddrinfo(servername, NULL, &hints, &addr))
974  return NULL;
975  return addr;
976 }
977 
978 TDSRET
979 tds_lookup_host_set(const char *servername, struct addrinfo **addr)
980 {
981  struct addrinfo *newaddr;
982  assert(servername != NULL && addr != NULL);
983 
984  if ((newaddr = tds_lookup_host(servername)) != NULL) {
985  if (*addr != NULL)
986  freeaddrinfo(*addr);
987  *addr = newaddr;
988  return TDS_SUCCESS;
989  }
990  return TDS_FAIL;
991 }
992 
993 /**
994  * Given a portname lookup the port.
995  *
996  * If we can't determine the port number then return 0.
997  */
998 static int
999 tds_lookup_port(const char *portname)
1000 {
1001  int num = atoi(portname);
1002  if (!num)
1003  num = tds_getservice(portname);
1004  return num;
1005 }
1006 
1007 /* TODO same code in convert.c ?? */
1008 static int
1009 hexdigit(int c)
1010 {
1011  if (c >= '0' && c <= '9')
1012  return c - '0';
1013  /* ascii optimization, 'A' -> 'a', 'a' -> 'a' */
1014  c |= 0x20;
1015  if (c >= 'a' && c <= 'f')
1016  return c - 'a' + 10;
1017  return 0; /* bad hex digit */
1018 }
1019 
1020 static int
1021 hex2num(char *hex)
1022 {
1023  return hexdigit(hex[0]) * 16 + hexdigit(hex[1]);
1024 }
1025 
1026 /**
1027  * Open and read the file 'file' searching for a logical server
1028  * by the name of 'host'. If one is found then lookup
1029  * the IP address and port number and store them in 'login'
1030  *
1031  * \param dir name of base directory for interface file
1032  * \param file name of the interface file
1033  * \param host logical host to search for
1034  * \return 0 if not fount 1 if found
1035  */
1036 static int
1037 search_interface_file(TDSLOGIN * login, const char *dir, const char *file, const char *host)
1038 {
1039  char *pathname;
1040  char line[255];
1041  char tmp_ip[sizeof(line)];
1042  char tmp_port[sizeof(line)];
1043  char tmp_ver[sizeof(line)];
1044  FILE *in;
1045  char *field;
1046  int found = 0;
1047  int server_found = 0;
1048  char *lasts;
1049 
1050  line[0] = '\0';
1051  tmp_ip[0] = '\0';
1052  tmp_port[0] = '\0';
1053  tmp_ver[0] = '\0';
1054 
1055  tdsdump_log(TDS_DBG_INFO1, "Searching interfaces file %s/%s.\n", dir, file);
1056  pathname = tds_new(char, strlen(dir) + strlen(file) + 10);
1057  if (!pathname)
1058  return 0;
1059 
1060  /*
1061  * create the full pathname to the interface file
1062  */
1063  if (file[0] == '\0') {
1064  pathname[0] = '\0';
1065  } else {
1066  if (dir[0] == '\0') {
1067  pathname[0] = '\0';
1068  } else {
1069  strcpy(pathname, dir);
1070  strcat(pathname, TDS_SDIR_SEPARATOR);
1071  }
1072  strcat(pathname, file);
1073  }
1074 
1075 
1076  /*
1077  * parse the interfaces file and find the server and port
1078  */
1079  if ((in = fopen(pathname, "r")) == NULL) {
1080  tdsdump_log(TDS_DBG_INFO1, "Couldn't open %s.\n", pathname);
1081  free(pathname);
1082  return 0;
1083  }
1084  tdsdump_log(TDS_DBG_INFO1, "Interfaces file %s opened.\n", pathname);
1085 
1086  while (fgets(line, sizeof(line) - 1, in)) {
1087  if (line[0] == '#')
1088  continue; /* comment */
1089 
1090  if (!TDS_ISSPACE(line[0])) {
1091  field = strtok_r(line, "\n\t ", &lasts);
1092  if (!strcmp(field, host)) {
1093  found = 1;
1094  tdsdump_log(TDS_DBG_INFO1, "Found matching entry for host %s.\n", host);
1095  } else
1096  found = 0;
1097  } else if (found && TDS_ISSPACE(line[0])) {
1098  field = strtok_r(line, "\n\t ", &lasts);
1099  if (field != NULL && !strcmp(field, "query")) {
1100  field = strtok_r(NULL, "\n\t ", &lasts); /* tcp or tli */
1101  if (!strcmp(field, "tli")) {
1102  tdsdump_log(TDS_DBG_INFO1, "TLI service.\n");
1103  field = strtok_r(NULL, "\n\t ", &lasts); /* tcp */
1104  field = strtok_r(NULL, "\n\t ", &lasts); /* device */
1105  field = strtok_r(NULL, "\n\t ", &lasts); /* host/port */
1106  if (strlen(field) >= 18) {
1107  sprintf(tmp_port, "%d", hex2num(&field[6]) * 256 + hex2num(&field[8]));
1108  sprintf(tmp_ip, "%d.%d.%d.%d", hex2num(&field[10]),
1109  hex2num(&field[12]), hex2num(&field[14]), hex2num(&field[16]));
1110  tdsdump_log(TDS_DBG_INFO1, "tmp_port = %s. tmp_ip = %s.\n", tmp_port, tmp_ip);
1111  }
1112  } else {
1113  field = strtok_r(NULL, "\n\t ", &lasts); /* ether */
1114  strcpy(tmp_ver, field);
1115  field = strtok_r(NULL, "\n\t ", &lasts); /* host */
1116  strcpy(tmp_ip, field);
1117  tdsdump_log(TDS_DBG_INFO1, "host field %s.\n", tmp_ip);
1118  field = strtok_r(NULL, "\n\t ", &lasts); /* port */
1119  strcpy(tmp_port, field);
1120  } /* else */
1121  server_found = 1;
1122  } /* if */
1123  } /* else if */
1124  } /* while */
1125  fclose(in);
1126  free(pathname);
1127 
1128 
1129  /*
1130  * Look up the host and service
1131  */
1132  if (server_found) {
1133 
1134  if (TDS_SUCCEED(tds_lookup_host_set(tmp_ip, &login->ip_addrs))) {
1135  struct addrinfo *addrs;
1136  if (!tds_dstr_copy(&login->server_host_name, tmp_ip))
1137  return 0;
1138  for (addrs = login->ip_addrs; addrs != NULL; addrs = addrs->ai_next) {
1139  tdsdump_log(TDS_DBG_INFO1, "Resolved IP as '%s'.\n",
1140  tds_addrinfo2str(login->ip_addrs, line, sizeof(line)));
1141  }
1142  } else {
1143  tdsdump_log(TDS_DBG_WARN, "Name resolution failed for IP '%s'.\n", tmp_ip);
1144  }
1145 
1146  if (tmp_port[0])
1147  login->port = tds_lookup_port(tmp_port);
1148  if (tmp_ver[0])
1149  tds_config_verstr(tmp_ver, login);
1150  }
1151  return server_found;
1152 } /* search_interface_file() */
1153 
1154 /**
1155  * Try to find the IP number and port for a (possibly) logical server name.
1156  *
1157  * @note This function uses only the interfaces file and is deprecated.
1158  */
1159 static int
1160 tds_read_interfaces(const char *server, TDSLOGIN * login)
1161 {
1162  int found = 0;
1163 
1164  /* read $SYBASE/interfaces */
1165 
1166  if (!server || !server[0]) {
1167  server = getenv("TDSQUERY");
1168  if (!server || !server[0])
1169  server = "SYBASE";
1170  tdsdump_log(TDS_DBG_INFO1, "Setting server to %s from $TDSQUERY.\n", server);
1171 
1172  }
1173  tdsdump_log(TDS_DBG_INFO1, "Looking for server %s....\n", server);
1174 
1175  /*
1176  * Look for the server in the interf_file iff interf_file has been set.
1177  */
1178  if (interf_file) {
1179  tdsdump_log(TDS_DBG_INFO1, "Looking for server in file %s.\n", interf_file);
1180  found = search_interface_file(login, "", interf_file, server);
1181  }
1182 
1183  /*
1184  * if we haven't found the server yet then look for a $HOME/.interfaces file
1185  */
1186  if (!found) {
1187  char *path = tds_get_home_file(".interfaces");
1188 
1189  if (path) {
1190  tdsdump_log(TDS_DBG_INFO1, "Looking for server in %s.\n", path);
1191  found = search_interface_file(login, "", path, server);
1192  free(path);
1193  }
1194  }
1195 
1196  /*
1197  * if we haven't found the server yet then look in $SYBBASE/interfaces file
1198  */
1199  if (!found) {
1200  const char *sybase = getenv("SYBASE");
1201 #ifdef __VMS
1202  /* We've got to be in unix syntax for later slash-joined concatenation. */
1203  #include <unixlib.h>
1204  const char *unixspec = decc$translate_vms(sybase);
1205  if ( (int)unixspec != 0 && (int)unixspec != -1 ) sybase = unixspec;
1206 #endif
1207  if (!sybase || !sybase[0])
1208  sybase = interfaces_path;
1209 
1210  tdsdump_log(TDS_DBG_INFO1, "Looking for server in %s/interfaces.\n", sybase);
1211  found = search_interface_file(login, sybase, "interfaces", server);
1212  }
1213 
1214  /*
1215  * If we still don't have the server and port then assume the user
1216  * typed an actual server host name.
1217  */
1218  if (!found) {
1219  int ip_port;
1220  const char *env_port;
1221 
1222  /*
1223  * Make a guess about the port number
1224  */
1225 
1226  if (login->port == 0) {
1227  /*
1228  * Not set in the [global] section of the
1229  * configure file, take a guess.
1230  */
1231  ip_port = TDS_DEF_PORT;
1232  } else {
1233  /*
1234  * Preserve setting from the [global] section
1235  * of the configure file.
1236  */
1237  ip_port = login->port;
1238  }
1239  if ((env_port = getenv("TDSPORT")) != NULL) {
1240  ip_port = tds_lookup_port(env_port);
1241  tdsdump_log(TDS_DBG_INFO1, "Setting 'ip_port' to %s from $TDSPORT.\n", env_port);
1242  } else
1243  tdsdump_log(TDS_DBG_INFO1, "Setting 'ip_port' to %d as a guess.\n", ip_port);
1244 
1245  /*
1246  * look up the host
1247  */
1248 
1250  if (!tds_dstr_copy(&login->server_host_name, server))
1251  return 0;
1252 
1253  if (ip_port)
1254  login->port = ip_port;
1255  }
1256 
1257  return found;
1258 }
1259 
1260 /**
1261  * Check the server name to find port info first
1262  * Warning: connection-> & login-> are all modified when needed
1263  * \return 1 when found, else 0
1264  */
1265 static int
1267 {
1268  const char *pSep;
1269  const char *server;
1270 
1271  /* seek the ':' in login server_name */
1272  server = tds_dstr_cstr(&login->server_name);
1273 
1274  /* IPv6 address can be quoted */
1275  if (server[0] == '[') {
1276  pSep = strstr(server, "]:");
1277  if (pSep)
1278  ++pSep;
1279  } else {
1280  pSep = strrchr(server, ':');
1281  }
1282 
1283  if (pSep && pSep != server) { /* yes, i found it! */
1284  /* modify connection-> && login->server_name & ->port */
1285  login->port = connection->port = atoi(pSep + 1);
1286  tds_dstr_empty(&connection->instance_name);
1287  } else {
1288  /* handle instance name */
1289  pSep = strrchr(server, '\\');
1290  if (!pSep || pSep == server)
1291  return 0;
1292 
1293  if (!tds_dstr_copy(&connection->instance_name, pSep + 1))
1294  return 0;
1295  connection->port = 0;
1296  }
1297 
1298  if (!tds_dstr_copyn(&connection->server_name, server, pSep - server))
1299  return 0;
1300 
1301  return 1;
1302 }
1303 
1304 /**
1305  * Return a structure capturing the compile-time settings provided to the
1306  * configure script.
1307  */
1308 
1311 {
1312  static const TDS_COMPILETIME_SETTINGS settings = {
1315  , "unknown" /* need fancy script in makefile */
1316 # ifdef MSDBLIB
1317  , 1
1318 # else
1319  , 0
1320 # endif
1321 # ifdef TDS_SYBASE_COMPAT
1322  , 1
1323 # else
1324  , 0
1325 # endif
1326 # ifdef _REENTRANT
1327  , 1
1328 # else
1329  , 0
1330 # endif
1331 # ifdef HAVE_ICONV
1332  , 1
1333 # else
1334  , 0
1335 # endif
1336 # ifdef TDS42
1337  , "4.2"
1338 # elif TDS46
1339  , "4.6"
1340 # elif TDS50
1341  , "5.0"
1342 # elif TDS70
1343  , "7.0"
1344 # elif TDS71
1345  , "7.1"
1346 # elif TDS72
1347  , "7.2"
1348 # elif TDS73
1349  , "7.3"
1350 # elif TDS74
1351  , "7.4"
1352 # else
1353  , "auto"
1354 # endif
1355 # ifdef IODBC
1356  , 1
1357 # else
1358  , 0
1359 # endif
1360 # ifdef UNIXODBC
1361  , 1
1362 # else
1363  , 0
1364 # endif
1365 # ifdef HAVE_OPENSSL
1366  , 1
1367 # else
1368  , 0
1369 # endif
1370 # ifdef HAVE_GNUTLS
1371  , 1
1372 # else
1373  , 0
1374 # endif
1375 # if ENABLE_ODBC_MARS
1376  , 1
1377 # else
1378  , 0
1379 # endif
1380  };
1381 
1382  assert(settings.tdsver);
1383 
1384  return &settings;
1385 }
1386 
1387 /** @} */
static TDSSOCKET * tds
Definition: collations.c:37
static const char pid_config_logpath[]
Definition: config.c:95
const char STD_DATETIME_FMT[]
Definition: config.c:93
static const char freetds_conf[]
Definition: config.c:96
static const char pid_logpath[]
Definition: config.c:98
static const char location[]
Definition: config.c:97
#define TDS_ISSPACE(c)
Definition: config.c:91
static const char interfaces_path[]
Definition: config.c:99
char value[7]
Definition: config.c:431
static char * interf_file
Definition: config.c:89
#define option
unsigned char to_return
Definition: config.c:432
#define FREETDS_SYSCONFFILE
Definition: configs.h:39
static uch flags
static TDSLOGIN * login
Definition: dataread.c:31
#define NULL
Definition: ncbistd.hpp:225
int tds_read_conf_file(TDSLOGIN *login, const char *server)
Read configuration info for given server return 0 on error.
Definition: config.c:341
TDSRET tds_lookup_host_set(const char *servername, struct addrinfo **addr)
Definition: config.c:979
static int tds_vernanme_cmp(const void *key, const void *pelem)
Definition: config.c:879
static int hex2num(char *hex)
Definition: config.c:1021
static int tds_try_conf_file(const char *path, const char *how, const char *server, TDSLOGIN *login)
Definition: config.c:290
void tds_parse_conf_section(const char *option, const char *value, void *param)
Definition: config.c:588
static void tds_config_encryption(const char *value, TDSLOGIN *login)
Definition: config.c:468
static int tds_lookup_port(const char *portname)
Given a portname lookup the port.
Definition: config.c:999
TDSRET tds_set_interfaces_file_loc(const char *interf)
Set the full name of interface file.
Definition: config.c:934
int tds_read_conf_section(FILE *in, const char *section, TDSCONFPARSE tds_conf_parse, void *param)
Read a section of configuration file (INI style file)
Definition: config.c:498
static int tds_read_interfaces(const char *server, TDSLOGIN *login)
Try to find the IP number and port for a (possibly) logical server name.
Definition: config.c:1160
static void tds_config_env_tdsver(TDSLOGIN *login)
Definition: config.c:819
const TDS_COMPILETIME_SETTINGS * tds_get_compiletime_settings(void)
Return a structure capturing the compile-time settings provided to the configure script.
Definition: config.c:1310
static int tds_config_env_tdsdump(TDSLOGIN *login)
Definition: config.c:783
static const struct @977 boolean_values[]
static int tds_config_login(TDSLOGIN *connection, TDSLOGIN *login)
Definition: config.c:694
TDSLOGIN * tds_read_config_info(TDSSOCKET *tds, TDSLOGIN *login, TDSLOCALE *locale)
tds_read_config_info() will fill the tds connection structure based on configuration information gath...
Definition: config.c:136
static void tds_config_env_tdsport(TDSLOGIN *login)
Definition: config.c:807
static int hexdigit(int c)
Definition: config.c:1009
struct addrinfo * tds_lookup_host(const char *servername)
Get the IP address for a hostname.
Definition: config.c:960
int tds_config_boolean(const char *option, const char *value, TDSLOGIN *login)
Definition: config.c:455
int tds_parse_boolean(const char *value, int default_value)
Definition: config.c:443
static int tds_read_conf_sections(FILE *in, const char *server, TDSLOGIN *login)
Definition: config.c:392
static int parse_server_name_for_port(TDSLOGIN *connection, TDSLOGIN *login)
Check the server name to find port info first Warning: connection-> & login-> are all modified when n...
Definition: config.c:1266
static void * tds_find(const void *key, const void *base, size_t nelem, size_t width, int(*compar)(const void *, const void *))
Definition: config.c:859
static int tds_config_env_tdshost(TDSLOGIN *login)
Definition: config.c:833
static int search_interface_file(TDSLOGIN *login, const char *dir, const char *file, const char *host)
Open and read the file 'file' searching for a logical server by the name of 'host'.
Definition: config.c:1037
#define TDS_FIND(k, b, c)
Definition: config.c:855
void tds_fix_login(TDSLOGIN *login)
Fix configuration after reading it.
Definition: config.c:280
TDS_USMALLINT * tds_config_verstr(const char *tdsver, TDSLOGIN *login)
Set TDS version from given string.
Definition: config.c:891
static char * tds_get_home_file(const char *file)
Return filename from HOME directory.
Definition: config.c:320
static const char * tds_dstr_cstr(DSTR *s)
Returns a C version (NUL terminated string) of dstr.
Definition: string.h:66
void tds_dstr_zero(DSTR *s)
clear all string filling with zeroes (mainly for security reason)
Definition: tdsstring.c:56
#define tds_dstr_empty(s)
Make a string empty.
Definition: string.h:79
DSTR * tds_dstr_dup(DSTR *s, const DSTR *src) TDS_WUR
Duplicate a string from another dynamic string.
Definition: tdsstring.c:135
#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
DSTR * tds_dstr_set(DSTR *s, char *src) TDS_WUR
set a string from another buffer.
Definition: tdsstring.c:108
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
#define TDS_VERSION_NO
Definition: version.h:25
FILE * file
int i
static void hex(unsigned char c)
Definition: mdb_dump.c:56
const struct ncbi::grid::netcache::search::fields::KEY key
int strcmp(const char *str1, const char *str2)
Definition: odbc_utils.hpp:160
#define strdup
Definition: ncbi_ansi_ext.h:70
#define strcasecmp
int tolower(Uchar c)
Definition: ncbictype.hpp:72
std::istream & in(std::istream &in_, double &x_)
static char tmp[2048]
Definition: utf8.c:42
static char * locale
Definition: pcregrep.c:149
#define tds_free_login
#define tdsdump_isopen
#define tds_init_login
#define tds_alloc_login
#define tds_g_append_mode
#define tds_getservice
#define tds_addrinfo2str
#define tdsdump_open
#define tdsdump_close
#define tds_debug_flags
#define tdserror
#define tds_get_homedir
#define asprintf
Definition: replacements.h:54
#define strtok_r
Definition: replacements.h:68
#define getaddrinfo(n, s, h, r)
Definition: replacements.h:99
#define addrinfo
Definition: replacements.h:98
#define freeaddrinfo(a)
Definition: replacements.h:101
#define strcat(s, k)
#define assert(x)
Definition: srv_diag.hpp:58
A structure to hold all the compile-time settings.
Definition: tds.h:95
const char * tdsver
Definition: tds.h:103
Structure to hold a string.
Definition: tds.h:116
Definition: tds.h:584
unsigned int use_ntlmv2
Definition: tds.h:628
unsigned int use_new_password
Definition: tds.h:632
TDS_INT query_timeout
Definition: tds.h:608
DSTR crlfile
certificate revocation file
Definition: tds.h:598
unsigned int check_ssl_hostname
Definition: tds.h:634
DSTR server_realm_name
server realm name (in freetds.conf)
Definition: tds.h:594
DSTR database
Definition: tds.h:611
DSTR client_charset
Definition: tds.h:610
DSTR user_name
account for login
Definition: tds.h:601
TDS_INT connect_timeout
Definition: tds.h:591
unsigned int gssapi_use_delegation
Definition: tds.h:627
DSTR password
password of account login
Definition: tds.h:602
DSTR db_filename
database filename to attach (MSSQL)
Definition: tds.h:596
TDS_CAPABILITIES capabilities
Definition: tds.h:609
unsigned int readonly_intent
Definition: tds.h:635
TDS_TINYINT encryption_level
Definition: tds.h:606
DSTR client_host_name
Definition: tds.h:592
DSTR dump_file
Definition: tds.h:616
unsigned int valid_configuration
Definition: tds.h:633
DSTR server_name
server name (in freetds.conf)
Definition: tds.h:585
DSTR instance_name
Definition: tds.h:615
struct addrinfo * ip_addrs
ip(s) of server
Definition: tds.h:613
DSTR server_charset
charset of server e.g.
Definition: tds.h:590
DSTR language
Definition: tds.h:589
int debug_flags
Definition: tds.h:617
TDS_USMALLINT tds_version
TDS version.
Definition: tds.h:587
DSTR new_password
new password to set (TDS 7.2+)
Definition: tds.h:603
unsigned int use_utf16
Definition: tds.h:631
unsigned int use_lanman
Definition: tds.h:629
unsigned int suppress_language
Definition: tds.h:625
int text_size
Definition: tds.h:618
DSTR server_host_name
Definition: tds.h:593
unsigned int emul_little_endian
Definition: tds.h:626
DSTR openssl_ciphers
Definition: tds.h:599
unsigned int bulk_copy
if bulk copy should be enabled
Definition: tds.h:624
DSTR cafile
certificate authorities file
Definition: tds.h:597
DSTR server_spn
server SPN (in freetds.conf)
Definition: tds.h:595
int port
port of database service
Definition: tds.h:586
int block_size
Definition: tds.h:588
DSTR library
Definition: tds.h:605
DSTR app_name
Definition: tds.h:600
Information for a server connection.
Definition: tds.h:1211
TDS_USMALLINT version
Definition: config.c:875
const char name[6]
Definition: config.c:874
#define FREETDS_SYSCONFDIR
Definition: sysconfdir.h:2
#define TDS_SDIR_SEPARATOR
Main include file for libtds.
#define TDS_FAIL
Definition: tds.h:204
#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 TDS_STR_INSTANCE
Definition: tds.h:530
#define TDS_MINOR(x)
Definition: tds.h:1715
#define tdsdump_log
Definition: tds.h:1561
#define TDS_DBG_INFO2
Definition: tds.h:899
#define TDS_STR_CHECKSSLHOSTNAME
Definition: tds.h:551
#define TDS_DEF_PORT
Definition: tds.h:505
#define TDS_DBG_INFO1
Definition: tds.h:900
#define TDS_DBG_WARN
Definition: tds.h:902
#define TDS_MAJOR(x)
Definition: tds.h:1714
#define TDS_STR_CRLFILE
Definition: tds.h:549
void(* TDSCONFPARSE)(const char *option, const char *value, void *param)
Definition: tds.h:1304
#define TDS_STR_ASA_DATABASE
Definition: tds.h:531
#define TDS_STR_ENCRYPTION_REQUEST
Definition: tds.h:538
#define TLS_STR_OPENSSL_CIPHERS
Definition: tds.h:557
@ TDSEINTF
Definition: tds.h:311
#define TDS_STR_BLKSZ
Definition: tds.h:510
#define TDS_VECTOR_SIZE(x)
Definition: tds.h:360
#define TDS_STR_ENCRYPTION_OFF
Definition: tds.h:537
#define TDS_STR_EMUL_LE
Definition: tds.h:523
#define TDS_STR_DEBUGFLAGS
Definition: tds.h:514
#define TDS_STR_ENCRYPTION
Definition: tds.h:533
#define TDS_STR_DATABASE
Definition: tds.h:532
#define TDS_STR_SWAPDT
Definition: tds.h:511
#define TDS_STR_USELANMAN
Definition: tds.h:535
#define TDS_STR_CONNTIMEOUT
Definition: tds.h:517
int TDSRET
Definition: tds.h:201
#define TDS_STR_APPENDMODE
Definition: tds.h:528
@ TDS_ENCRYPTION_REQUEST
Definition: tds.h:356
@ TDS_ENCRYPTION_OFF
Definition: tds.h:356
@ TDS_ENCRYPTION_REQUIRE
Definition: tds.h:356
#define TDS_STR_USENTLMV2
Definition: tds.h:534
tds_sysdep_uint16_type TDS_USMALLINT
Definition: tds.h:148
#define TDS_STR_TIMEOUT
Definition: tds.h:515
#define TDS_DBG_ERROR
Definition: tds.h:903
#define TDS_GSSAPI_DELEGATION
Definition: tds.h:541
#define TDS_SUCCESS
Definition: tds.h:203
#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_ZERO_FREE(x)
Definition: tds.h:359
#define tds_get_ctx(tds)
Definition: tds.h:1294
#define TDS_STR_CAFILE
Definition: tds.h:547
#define TDS_STR_CHARSET
Definition: tds.h:524
#define TDS_STR_SPN
Definition: tds.h:545
#define TDS_STR_QUERY_TIMEOUT
Definition: tds.h:516
#define TDS_STR_ENCRYPTION_REQUIRE
Definition: tds.h:539
#define TDS_STR_HOST
Definition: tds.h:519
#define TDS_DBG_FUNC
Definition: tds.h:898
#define TDS_STR_USE_UTF_16
Definition: tds.h:526
enum tds_encryption_level TDS_ENCRYPTION_LEVEL
void free(voidpf ptr)
Modified on Tue Apr 09 07:56:49 2024 by modify_doxy.py rev. 669887
Modified on Wed Apr 10 07:32:12 2024 by modify_doxy.py rev. 669887
Modified on Thu Apr 11 15:04:27 2024 by modify_doxy.py rev. 669887
Modified on Fri Apr 12 17:16:26 2024 by modify_doxy.py rev. 669887
Modified on Sat Apr 13 11:44:51 2024 by modify_doxy.py rev. 669887
Modified on Sun Apr 14 05:25:33 2024 by modify_doxy.py rev. 669887
Modified on Tue Apr 16 20:08:44 2024 by modify_doxy.py rev. 669887
Modified on Wed Apr 17 13:08:47 2024 by modify_doxy.py rev. 669887
Modified on Sat Apr 20 12:16:09 2024 by modify_doxy.py rev. 669887
Modified on Sun Apr 21 03:39:26 2024 by modify_doxy.py rev. 669887