00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #if HAVE_CONFIG_H
00021 #include <config.h>
00022 #endif
00023
00024 #if HAVE_ERRNO_H
00025 #include <errno.h>
00026 #endif
00027
00028 #include <assert.h>
00029 #include <ctype.h>
00030 #include <stdio.h>
00031
00032 #if HAVE_STDLIB_H
00033 #include <stdlib.h>
00034 #endif
00035
00036 #if HAVE_STRING_H
00037 #include <string.h>
00038 #endif
00039
00040 #if HAVE_UNISTD_H
00041 #include <unistd.h>
00042 #endif
00043
00044 #if HAVE_NETDB_H
00045 #include <netdb.h>
00046 #endif
00047
00048 #if HAVE_SYS_SOCKET_H
00049 #include <sys/socket.h>
00050 #endif
00051
00052 #if HAVE_SYS_TYPES_H
00053 #include <sys/types.h>
00054 #endif
00055
00056 #if HAVE_NETINET_IN_H
00057 #include <netinet/in.h>
00058 #endif
00059
00060 #if HAVE_ARPA_INET_H
00061 #include <arpa/inet.h>
00062 #endif
00063
00064 #ifdef WIN32
00065 #include <process.h>
00066 #endif
00067
00068 #include "tds.h"
00069 #include "tds_configs.h"
00070 #include "tdsstring.h"
00071 #include "replacements.h"
00072 #ifdef DMALLOC
00073 #include <dmalloc.h>
00074 #endif
00075
00076 TDS_RCSID(var, "$Id: config.c 122952 2008-03-26 21:16:10Z ivanovp $");
00077
00078
00079 static void tds_config_login(TDSCONNECTION * connection, TDSLOGIN * login);
00080 static void tds_config_env_tdsquery(TDSCONNECTION * connection);
00081 static void tds_config_env_tdsdump(TDSCONNECTION * connection);
00082 static void tds_config_env_tdsver(TDSCONNECTION * connection);
00083 static void tds_config_env_tdsport(TDSCONNECTION * connection);
00084 static void tds_config_env_tdshost(TDSCONNECTION * connection);
00085 static int tds_read_conf_sections(FILE * in, const char *server, TDSCONNECTION * connection);
00086 static void tds_parse_conf_section(const char *option, const char *value, void *param);
00087 static void tds_read_interfaces(const char *server, TDSCONNECTION * connection);
00088 static int tds_config_boolean(const char *value);
00089 static int parse_server_name_for_port(TDSCONNECTION * connection, TDSLOGIN * login);
00090 static int tds_lookup_port(const char *portname);
00091
00092 extern int tds_g_append_mode;
00093
00094 static char *interf_file = NULL;
00095
00096 #define TDS_ISSPACE(c) isspace((unsigned char ) (c))
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125 TDSCONNECTION *
00126 tds_read_config_info(TDSSOCKET * tds, TDSLOGIN * login, TDSLOCALE * locale)
00127 {
00128 TDSCONNECTION *connection;
00129 char *s;
00130 char *path;
00131 pid_t pid;
00132 int opened = 0;
00133
00134
00135 connection = tds_alloc_connection(locale);
00136 if (!connection)
00137 return NULL;
00138
00139 s = getenv("TDSDUMPCONFIG");
00140 if (s) {
00141 if (*s) {
00142 opened = tdsdump_open(s);
00143 } else {
00144 pid = getpid();
00145 #if !defined(WIN32) && !defined(DOS32X)
00146 if (asprintf(&path, "/tmp/tdsconfig.log.%d", pid) >= 0) {
00147 #else
00148 if (asprintf(&path, "c:\\tdsconfig.log.%d", pid) >= 0) {
00149 #endif
00150 if (*path) {
00151 opened = tdsdump_open(path);
00152 }
00153 free(path);
00154 }
00155 }
00156 }
00157
00158 tdsdump_log(TDS_DBG_INFO1, "Attempting to read conf files.\n");
00159 if (!tds_read_conf_file(connection, tds_dstr_cstr(&login->server_name))) {
00160
00161 tdsdump_log(TDS_DBG_INFO1, "Failed in reading conf file. Trying interface files.\n");
00162 tds_read_interfaces(tds_dstr_cstr(&login->server_name), connection);
00163 }
00164
00165 if (parse_server_name_for_port(connection, login)) {
00166 tdsdump_log(TDS_DBG_INFO1, "Parsed servername, now %s on %d.\n", tds_dstr_cstr(&connection->server_name), login->port);
00167 }
00168
00169 tds_fix_connection(connection);
00170
00171
00172 tds_config_login(connection, login);
00173
00174 if (opened) {
00175 tdsdump_close();
00176 }
00177 return connection;
00178 }
00179
00180
00181
00182
00183
00184 void
00185 tds_fix_connection(TDSCONNECTION * connection)
00186 {
00187
00188 tds_config_env_tdsver(connection);
00189 tds_config_env_tdsdump(connection);
00190 tds_config_env_tdsport(connection);
00191 tds_config_env_tdsquery(connection);
00192 tds_config_env_tdshost(connection);
00193 }
00194
00195 static int
00196 tds_try_conf_file(const char *path, const char *how, const char *server, TDSCONNECTION * connection)
00197 {
00198 int found = 0;
00199 FILE *in;
00200
00201 if ((in = fopen(path, "r")) != NULL) {
00202 tdsdump_log(TDS_DBG_INFO1, "Found conf file '%s' %s. Reading section '%s'.\n", path, how, server);
00203 found = tds_read_conf_sections(in, server, connection);
00204
00205 if (found) {
00206 tdsdump_log(TDS_DBG_INFO1, "...Success.\n");
00207 } else {
00208 tdsdump_log(TDS_DBG_INFO2, "...'%s' not found.\n", server);
00209 }
00210
00211 fclose(in);
00212 }
00213 return found;
00214 }
00215
00216
00217
00218
00219
00220
00221 static char *
00222 tds_get_home_file(const char *file)
00223 {
00224 char *home, *path;
00225
00226 home = tds_get_homedir();
00227 if (!home)
00228 return NULL;
00229 if (asprintf(&path, "%s" TDS_SDIR_SEPARATOR "%s", home, file) < 0)
00230 path = NULL;
00231 free(home);
00232 return path;
00233 }
00234
00235
00236
00237
00238
00239
00240
00241
00242 int
00243 tds_read_conf_file(TDSCONNECTION * connection, const char *server)
00244 {
00245 char *path = NULL;
00246 char *eptr = NULL;
00247 int found = 0;
00248
00249 if (interf_file) {
00250 found = tds_try_conf_file(interf_file, "set programmatically", server, connection);
00251 }
00252
00253
00254 if (!found) {
00255 path = getenv("FREETDSCONF");
00256 if (path) {
00257 found = tds_try_conf_file(path, "(from $FREETDSCONF)", server, connection);
00258 } else {
00259 tdsdump_log(TDS_DBG_INFO2, "...$FREETDSCONF not set. Trying $FREETDS/etc.\n");
00260 }
00261 }
00262
00263
00264 if (!found) {
00265 eptr = getenv("FREETDS");
00266 if (eptr) {
00267 #if !defined(WIN32) && !defined(DOS32X)
00268 asprintf(&path, "%s/etc/freetds.conf", eptr);
00269 found = tds_try_conf_file(path, "(from $FREETDS/etc)", server, connection);
00270 #else
00271 asprintf(&path, "%s\\freetds.conf", eptr);
00272 found = tds_try_conf_file(path, "(from $FREETDS)", server, connection);
00273 #endif
00274 } else {
00275 tdsdump_log(TDS_DBG_INFO2, "...$FREETDS not set. Trying $HOME.\n");
00276 }
00277 }
00278
00279 if (!found) {
00280 path = tds_get_home_file(".freetds.conf");
00281 if (path) {
00282 found = tds_try_conf_file(path, "(.freetds.conf)", server, connection);
00283 free(path);
00284 } else {
00285 tdsdump_log(TDS_DBG_INFO2, "...Error getting ~/.freetds.conf. Trying %s.\n", FREETDS_SYSCONFFILE);
00286 }
00287 }
00288
00289 if (!found) {
00290 found = tds_try_conf_file(FREETDS_SYSCONFFILE, "(default)", server, connection);
00291 }
00292
00293 return found;
00294 }
00295
00296 static int
00297 tds_read_conf_sections(FILE * in, const char *server, TDSCONNECTION * connection)
00298 {
00299 tds_read_conf_section(in, "global", tds_parse_conf_section, connection);
00300 rewind(in);
00301 return tds_read_conf_section(in, server, tds_parse_conf_section, connection);
00302 }
00303
00304 static int
00305 tds_config_boolean(const char *value)
00306 {
00307 if (!strcmp(value, "yes") || !strcmp(value, "on") || !strcmp(value, "true") || !strcmp(value, "1")) {
00308 tdsdump_log(TDS_DBG_INFO1, "%s is a 'yes/on/true'.\n", value);
00309 return 1;
00310 } else {
00311 tdsdump_log(TDS_DBG_INFO1, "%s is a 'no/off/false'.\n", value);
00312 return 0;
00313 }
00314 }
00315
00316
00317
00318
00319
00320
00321
00322
00323 int
00324 tds_read_conf_section(FILE * in, const char *section, TDSCONFPARSE tds_conf_parse, void *param)
00325 {
00326 char line[256], option[256], value[256];
00327 char *s;
00328 char p;
00329 int i;
00330 int insection = 0;
00331 int found = 0;
00332
00333 tdsdump_log(TDS_DBG_INFO1, "Looking for section %s.\n", section);
00334 while (fgets(line, 256, in)) {
00335 s = line;
00336
00337
00338 while (*s && TDS_ISSPACE(*s))
00339 s++;
00340
00341
00342 if (*s == ';' || *s == '#')
00343 continue;
00344
00345
00346 p = 0;
00347 i = 0;
00348 while (*s && *s != '=') {
00349 if (!TDS_ISSPACE(*s) && TDS_ISSPACE(p))
00350 option[i++] = ' ';
00351 if (!TDS_ISSPACE(*s))
00352 option[i++] = tolower((unsigned char) *s);
00353 p = *s;
00354 s++;
00355 }
00356 option[i] = '\0';
00357
00358
00359 if (*s)
00360 s++;
00361
00362
00363 while (*s && TDS_ISSPACE(*s))
00364 s++;
00365
00366
00367 p = 0;
00368 i = 0;
00369 while (*s && *s != ';' && *s != '#') {
00370 if (!TDS_ISSPACE(*s) && TDS_ISSPACE(p))
00371 value[i++] = ' ';
00372 if (!TDS_ISSPACE(*s))
00373 value[i++] = *s;
00374 p = *s;
00375 s++;
00376 }
00377 value[i] = '\0';
00378
00379 if (!strlen(option))
00380 continue;
00381
00382 if (option[0] == '[') {
00383 s = &option[1];
00384 while (*s) {
00385 if (*s == ']')
00386 *s = '\0';
00387 *s = tolower((unsigned char) *s);
00388 s++;
00389 }
00390 tdsdump_log(TDS_DBG_INFO1, "... Found section %s.\n", &option[1]);
00391
00392 if (!strcasecmp(section, &option[1])) {
00393 tdsdump_log(TDS_DBG_INFO1, "Got a match.\n");
00394 insection = 1;
00395 found = 1;
00396 } else {
00397 insection = 0;
00398 }
00399 } else if (insection) {
00400 tds_conf_parse(option, value, param);
00401 }
00402
00403 }
00404 return found;
00405 }
00406
00407 static void
00408 tds_parse_conf_section(const char *option, const char *value, void *param)
00409 {
00410 TDSCONNECTION *connection = (TDSCONNECTION *) param;
00411 char tmp[256];
00412
00413 tdsdump_log(TDS_DBG_INFO1, "option = '%s' value = '%s'.\n", option, value);
00414
00415 if (!strcmp(option, TDS_STR_VERSION)) {
00416 tds_config_verstr(value, connection);
00417 } else if (!strcmp(option, TDS_STR_BLKSZ)) {
00418 if (atoi(value))
00419 connection->block_size = atoi(value);
00420 } else if (!strcmp(option, TDS_STR_SWAPDT)) {
00421 connection->broken_dates = tds_config_boolean(value);
00422 } else if (!strcmp(option, TDS_STR_SWAPMNY)) {
00423 connection->broken_money = tds_config_boolean(value);
00424 } else if (!strcmp(option, TDS_STR_DUMPFILE)) {
00425 tds_dstr_copy(&connection->dump_file, value);
00426 } else if (!strcmp(option, TDS_STR_DEBUGFLAGS)) {
00427 char *end;
00428 long l;
00429 errno = 0;
00430 l = strtol(value, &end, 0);
00431 if (errno == 0 && *end == 0)
00432 connection->debug_flags = l;
00433 } else if (!strcmp(option, TDS_STR_TIMEOUT) || !strcmp(option, TDS_STR_QUERY_TIMEOUT)) {
00434 if (atoi(value))
00435 connection->query_timeout = atoi(value);
00436 } else if (!strcmp(option, TDS_STR_CONNTIMEOUT)) {
00437 if (atoi(value))
00438 connection->connect_timeout = atoi(value);
00439 } else if (!strcmp(option, TDS_STR_HOST)) {
00440 tdsdump_log(TDS_DBG_INFO1, "Found host entry %s.\n", value);
00441 tds_lookup_host(value, tmp);
00442 tds_dstr_copy(&connection->ip_addr, tmp);
00443 tdsdump_log(TDS_DBG_INFO1, "IP addr is %s.\n", tds_dstr_cstr(&connection->ip_addr));
00444 } else if (!strcmp(option, TDS_STR_PORT)) {
00445 if (atoi(value))
00446 connection->port = atoi(value);
00447 } else if (!strcmp(option, TDS_STR_EMUL_LE)) {
00448 connection->emul_little_endian = tds_config_boolean(value);
00449 } else if (!strcmp(option, TDS_STR_TEXTSZ)) {
00450 if (atoi(value))
00451 connection->text_size = atoi(value);
00452 } else if (!strcmp(option, TDS_STR_CHARSET)) {
00453 tds_dstr_copy(&connection->server_charset, value);
00454 tdsdump_log(TDS_DBG_INFO1, "%s is %s.\n", option, tds_dstr_cstr(&connection->server_charset));
00455 } else if (!strcmp(option, TDS_STR_CLCHARSET)) {
00456 tds_dstr_copy(&connection->client_charset, value);
00457 tdsdump_log(TDS_DBG_INFO1, "tds_config_login: %s is %s.\n", option, tds_dstr_cstr(&connection->client_charset));
00458 } else if (!strcmp(option, TDS_STR_LANGUAGE)) {
00459 tds_dstr_copy(&connection->language, value);
00460 } else if (!strcmp(option, TDS_STR_APPENDMODE)) {
00461 tds_g_append_mode = tds_config_boolean(value);
00462 } else if (!strcmp(option, TDS_STR_INSTANCE)) {
00463 tds_dstr_copy(&connection->instance_name, value);
00464 } else {
00465 tdsdump_log(TDS_DBG_INFO1, "UNRECOGNIZED option '%s'...ignoring.\n", option);
00466 }
00467 }
00468
00469 static void
00470 tds_config_login(TDSCONNECTION * connection, TDSLOGIN * login)
00471 {
00472 if (!tds_dstr_isempty(&login->server_name)) {
00473 tds_dstr_copy(&connection->server_name, tds_dstr_cstr(&login->server_name));
00474 }
00475
00476 connection->major_version = login->major_version;
00477 connection->minor_version = login->minor_version;
00478
00479 if (!tds_dstr_isempty(&login->language)) {
00480 tds_dstr_copy(&connection->language, tds_dstr_cstr(&login->language));
00481 }
00482 if (!tds_dstr_isempty(&login->server_charset)) {
00483 tds_dstr_copy(&connection->server_charset, tds_dstr_cstr(&login->server_charset));
00484 }
00485 if (!tds_dstr_isempty(&login->client_charset)) {
00486 tds_dstr_copy(&connection->client_charset, tds_dstr_cstr(&login->client_charset));
00487 tdsdump_log(TDS_DBG_INFO1, "tds_config_login: %s is %s.\n", "client_charset",
00488 tds_dstr_cstr(&connection->client_charset));
00489 }
00490 if (!tds_dstr_isempty(&login->client_host_name)) {
00491 tds_dstr_copy(&connection->client_host_name, tds_dstr_cstr(&login->client_host_name));
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503 }
00504 if (!tds_dstr_isempty(&login->app_name)) {
00505 tds_dstr_copy(&connection->app_name, tds_dstr_cstr(&login->app_name));
00506 }
00507 if (!tds_dstr_isempty(&login->user_name)) {
00508 tds_dstr_copy(&connection->user_name, tds_dstr_cstr(&login->user_name));
00509 }
00510 if (!tds_dstr_isempty(&login->password)) {
00511
00512 tds_dstr_zero(&connection->password);
00513 tds_dstr_copy(&connection->password, tds_dstr_cstr(&login->password));
00514 }
00515 if (!tds_dstr_isempty(&login->library)) {
00516 tds_dstr_copy(&connection->library, tds_dstr_cstr(&login->library));
00517 }
00518 if (login->encrypted) {
00519 connection->encrypted = 1;
00520 }
00521 if (login->suppress_language) {
00522 connection->suppress_language = 1;
00523 }
00524 if (login->bulk_copy) {
00525 connection->bulk_copy = 1;
00526 }
00527 if (login->block_size) {
00528 connection->block_size = login->block_size;
00529 }
00530 if (login->port) {
00531 connection->port = login->port;
00532 tds_dstr_copy(&connection->instance_name, "");
00533 }
00534 if (login->connect_timeout)
00535 connection->connect_timeout = login->connect_timeout;
00536
00537 if (login->query_timeout)
00538 connection->query_timeout = login->query_timeout;
00539
00540
00541 memcpy(connection->capabilities, login->capabilities, TDS_MAX_CAPABILITY);
00542 }
00543
00544 static void
00545 tds_config_env_tdsquery(TDSCONNECTION * connection)
00546 {
00547 char *s;
00548
00549 if ((s = getenv("TDSQUERY")) != NULL && s[0]) {
00550 tds_dstr_copy(&connection->server_name, s);
00551 tdsdump_log(TDS_DBG_INFO1, "Setting 'server_name' to '%s' from $TDSQUERY.\n", s);
00552 return;
00553 }
00554 if ((s = getenv("DSQUERY")) != NULL && s[0]) {
00555 tds_dstr_copy(&connection->server_name, s);
00556 tdsdump_log(TDS_DBG_INFO1, "Setting 'server_name' to '%s' from $DSQUERY.\n", s);
00557 }
00558 }
00559 static void
00560 tds_config_env_tdsdump(TDSCONNECTION * connection)
00561 {
00562 char *s;
00563 char *path;
00564 pid_t pid = 0;
00565
00566 if ((s = getenv("TDSDUMP"))) {
00567 if (!strlen(s)) {
00568 pid = getpid();
00569 #if !defined(WIN32) && !defined(DOS32X)
00570 if (asprintf(&path, "/tmp/freetds.log.%d", pid) >= 0)
00571 #else
00572 if (asprintf(&path, "c:\\freetds.log.%d", pid) >= 0)
00573 #endif
00574 tds_dstr_set(&connection->dump_file, path);
00575 } else {
00576 tds_dstr_copy(&connection->dump_file, s);
00577 }
00578 tdsdump_log(TDS_DBG_INFO1, "Setting 'dump_file' to '%s' from $TDSDUMP.\n", tds_dstr_cstr(&connection->dump_file));
00579 }
00580 }
00581 static void
00582 tds_config_env_tdsport(TDSCONNECTION * connection)
00583 {
00584 char *s;
00585
00586 if ((s = getenv("TDSPORT"))) {
00587 connection->port = tds_lookup_port(s);
00588 tds_dstr_copy(&connection->instance_name, "");
00589 tdsdump_log(TDS_DBG_INFO1, "Setting 'port' to %s from $TDSPORT.\n", s);
00590 }
00591 return;
00592 }
00593 static void
00594 tds_config_env_tdsver(TDSCONNECTION * connection)
00595 {
00596 char *tdsver;
00597
00598 if ((tdsver = getenv("TDSVER"))) {
00599 tds_config_verstr(tdsver, connection);
00600 tdsdump_log(TDS_DBG_INFO1, "Setting 'tdsver' to %s from $TDSVER.\n", tdsver);
00601
00602 }
00603 return;
00604 }
00605
00606
00607 static void
00608 tds_config_env_tdshost(TDSCONNECTION * connection)
00609 {
00610 char *tdshost;
00611 char tmp[256];
00612
00613 if ((tdshost = getenv("TDSHOST"))) {
00614 tds_lookup_host(tdshost, tmp);
00615 tds_dstr_copy(&connection->ip_addr, tmp);
00616 tdsdump_log(TDS_DBG_INFO1, "Setting 'ip_addr' to %s (%s) from $TDSHOST.\n", tmp, tdshost);
00617
00618 }
00619 return;
00620 }
00621
00622
00623
00624
00625
00626
00627 void
00628 tds_config_verstr(const char *tdsver, TDSCONNECTION * connection)
00629 {
00630 if (!strcmp(tdsver, "42") || !strcmp(tdsver, "4.2")) {
00631 connection->major_version = 4;
00632 connection->minor_version = 2;
00633 return;
00634 } else if (!strcmp(tdsver, "46") || !strcmp(tdsver, "4.6")) {
00635 connection->major_version = 4;
00636 connection->minor_version = 6;
00637 return;
00638 } else if (!strcmp(tdsver, "50") || !strcmp(tdsver, "5.0")) {
00639 connection->major_version = 5;
00640 connection->minor_version = 0;
00641 return;
00642 } else if (!strcmp(tdsver, "70") || !strcmp(tdsver, "7.0")) {
00643 connection->major_version = 7;
00644 connection->minor_version = 0;
00645 return;
00646 } else if (!strcmp(tdsver, "80") || !strcmp(tdsver, "8.0")) {
00647 connection->major_version = 8;
00648 connection->minor_version = 0;
00649 return;
00650 }
00651 }
00652
00653
00654
00655
00656
00657 int
00658 tds_set_interfaces_file_loc(const char *interf)
00659 {
00660
00661 if (interf_file != NULL)
00662 TDS_ZERO_FREE(interf_file);
00663
00664 if ((interf == NULL) || (interf[0] == '\0')) {
00665 return TDS_SUCCEED;
00666 }
00667
00668 if ((interf_file = strdup(interf)) == NULL) {
00669 return TDS_FAIL;
00670 }
00671 return TDS_SUCCEED;
00672 }
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684 void
00685 tds_lookup_host(const char *servername,
00686 char *ip
00687 )
00688 {
00689 struct hostent *host = NULL;
00690 unsigned int ip_addr = 0;
00691
00692
00693 struct hostent result;
00694 char buffer[4096];
00695 int h_errnop;
00696
00697
00698
00699
00700
00701
00702 ip_addr = inet_addr(servername);
00703 if (ip_addr != INADDR_NONE) {
00704 tds_strlcpy(ip, servername, 17);
00705 return;
00706 }
00707
00708 host = tds_gethostbyname_r(servername, &result, buffer, sizeof(buffer), &h_errnop);
00709
00710 ip[0] = '\0';
00711 if (host) {
00712 struct in_addr *ptr = (struct in_addr *) host->h_addr;
00713
00714 tds_inet_ntoa_r(*ptr, ip, 17);
00715 }
00716 }
00717
00718 static int
00719 tds_lookup_port(const char *portname)
00720 {
00721 int num = 0;
00722
00723 if (portname) {
00724 num = atoi(portname);
00725 if (!num) {
00726 char buffer[4096];
00727 struct servent serv_result;
00728 struct servent *service = tds_getservbyname_r(portname, "tcp", &serv_result, buffer, sizeof(buffer));
00729
00730 if (service)
00731 num = ntohs(service->s_port);
00732 }
00733 }
00734 return num;
00735 }
00736
00737
00738 static int
00739 hexdigit(char c)
00740 {
00741 if (c >= 'a' && c <= 'f') {
00742 return c - 'a' + 10;
00743 } else if (c >= 'A' && c <= 'F') {
00744 return c - 'A' + 10;
00745 } else if (c >= '0' && c <= '9') {
00746 return c - '0';
00747 } else {
00748 return 0;
00749 }
00750 }
00751
00752 static int
00753 hex2num(char *hex)
00754 {
00755 return hexdigit(hex[0]) * 16 + hexdigit(hex[1]);
00756 }
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768 static int
00769 search_interface_file(TDSCONNECTION * connection, const char *dir, const char *file, const char *host)
00770 {
00771 char *pathname;
00772 char line[255];
00773 char tmp_ip[sizeof(line)];
00774 char tmp_port[sizeof(line)];
00775 char tmp_ver[sizeof(line)];
00776 FILE *in;
00777 char *field;
00778 int found = 0;
00779 int server_found = 0;
00780 char *lasts;
00781
00782 line[0] = '\0';
00783 tmp_ip[0] = '\0';
00784 tmp_port[0] = '\0';
00785 tmp_ver[0] = '\0';
00786
00787 tdsdump_log(TDS_DBG_INFO1, "Searching interfaces file %s/%s.\n", dir, file);
00788 pathname = (char *) malloc(strlen(dir) + strlen(file) + 10);
00789 if (!pathname)
00790 return 0;
00791
00792
00793
00794
00795 if (file[0] == '\0') {
00796 pathname[0] = '\0';
00797 } else {
00798 if (dir[0] == '\0') {
00799 pathname[0] = '\0';
00800 } else {
00801 strcpy(pathname, dir);
00802 strcat(pathname, TDS_SDIR_SEPARATOR);
00803 }
00804 strcat(pathname, file);
00805 }
00806
00807
00808
00809
00810
00811 if ((in = fopen(pathname, "r")) == NULL) {
00812 tdsdump_log(TDS_DBG_INFO1, "Couldn't open %s.\n", pathname);
00813 free(pathname);
00814 return 0;
00815 }
00816 tdsdump_log(TDS_DBG_INFO1, "Interfaces file %s opened.\n", pathname);
00817
00818 while (fgets(line, sizeof(line) - 1, in)) {
00819 if (line[0] == '#')
00820 continue;
00821
00822 if (!TDS_ISSPACE(line[0])) {
00823 field = strtok_r(line, "\n\t ", &lasts);
00824 if (!strcmp(field, host)) {
00825 found = 1;
00826 tdsdump_log(TDS_DBG_INFO1, "Found matching entry for host %s.\n", host);
00827 } else
00828 found = 0;
00829 } else if (found && TDS_ISSPACE(line[0])) {
00830 field = strtok_r(line, "\n\t ", &lasts);
00831 if (field != NULL && !strcmp(field, "query")) {
00832 field = strtok_r(NULL, "\n\t ", &lasts);
00833 if (!strcmp(field, "tli")) {
00834 tdsdump_log(TDS_DBG_INFO1, "TLI service.\n");
00835 field = strtok_r(NULL, "\n\t ", &lasts);
00836 field = strtok_r(NULL, "\n\t ", &lasts);
00837 field = strtok_r(NULL, "\n\t ", &lasts);
00838 if (strlen(field) >= 18) {
00839 sprintf(tmp_port, "%d", hex2num(&field[6]) * 256 + hex2num(&field[8]));
00840 sprintf(tmp_ip, "%d.%d.%d.%d", hex2num(&field[10]),
00841 hex2num(&field[12]), hex2num(&field[14]), hex2num(&field[16]));
00842 tdsdump_log(TDS_DBG_INFO1, "tmp_port = %s. tmp_ip = %s.\n", tmp_port, tmp_ip);
00843 }
00844 } else {
00845 field = strtok_r(NULL, "\n\t ", &lasts);
00846 strcpy(tmp_ver, field);
00847 field = strtok_r(NULL, "\n\t ", &lasts);
00848 strcpy(tmp_ip, field);
00849 tdsdump_log(TDS_DBG_INFO1, "host field %s.\n", tmp_ip);
00850 field = strtok_r(NULL, "\n\t ", &lasts);
00851 strcpy(tmp_port, field);
00852 }
00853 server_found = 1;
00854 }
00855 }
00856 }
00857 fclose(in);
00858 free(pathname);
00859
00860
00861
00862
00863
00864 if (server_found) {
00865 tds_lookup_host(tmp_ip, line);
00866 tdsdump_log(TDS_DBG_INFO1, "Resolved IP as '%s'.\n", line);
00867 tds_dstr_copy(&connection->ip_addr, line);
00868 if (tmp_port[0])
00869 connection->port = tds_lookup_port(tmp_port);
00870 if (tmp_ver[0])
00871 tds_config_verstr(tmp_ver, connection);
00872 }
00873 return server_found;
00874 }
00875
00876
00877
00878
00879
00880
00881 static void
00882 tds_read_interfaces(const char *server, TDSCONNECTION * connection)
00883 {
00884 int founded = 0;
00885
00886
00887
00888 if (!server || strlen(server) == 0) {
00889 server = getenv("TDSQUERY");
00890 if (!server || strlen(server) == 0) {
00891 server = "SYBASE";
00892 }
00893 tdsdump_log(TDS_DBG_INFO1, "Setting server to %s from $TDSQUERY.\n", server);
00894
00895 }
00896 tdsdump_log(TDS_DBG_INFO1, "Looking for server %s....\n", server);
00897
00898
00899
00900
00901 if (interf_file) {
00902 tdsdump_log(TDS_DBG_INFO1, "Looking for server in file %s.\n", interf_file);
00903 founded = search_interface_file(connection, "", interf_file, server);
00904 }
00905
00906
00907
00908
00909 if (!founded) {
00910 char *path = tds_get_home_file(".interfaces");
00911
00912 if (path) {
00913 tdsdump_log(TDS_DBG_INFO1, "Looking for server in %s.\n", path);
00914 founded = search_interface_file(connection, "", path, server);
00915 free(path);
00916 }
00917 }
00918
00919
00920
00921
00922 if (!founded) {
00923 const char *sybase = getenv("SYBASE");
00924 #ifdef __VMS
00925
00926 #include <unixlib.h>
00927 const char *unixspec = decc$translate_vms(sybase);
00928 if ( (int)unixspec != 0 && (int)unixspec != -1 ) sybase = unixspec;
00929 #endif
00930 if (!sybase || !sybase[0])
00931 #if !defined(WIN32) && !defined(DOS32X)
00932 sybase = "/etc/freetds";
00933 #else
00934 sybase = "c:\\";
00935 #endif
00936 tdsdump_log(TDS_DBG_INFO1, "Looking for server in %s/interfaces.\n", sybase);
00937 founded = search_interface_file(connection, sybase, "interfaces", server);
00938 }
00939
00940
00941
00942
00943
00944 if (!founded) {
00945 char ip_addr[255];
00946 int ip_port;
00947 const char *env_port;
00948
00949
00950
00951
00952
00953 if (connection->port == 0) {
00954
00955
00956
00957
00958 #ifdef TDS50
00959 ip_port = 4000;
00960 #else
00961 ip_port = 1433;
00962 #endif
00963 } else {
00964
00965
00966
00967
00968 ip_port = connection->port;
00969 }
00970 if ((env_port = getenv("TDSPORT")) != NULL) {
00971 ip_port = tds_lookup_port(env_port);
00972 tdsdump_log(TDS_DBG_INFO1, "Setting 'ip_port' to %s from $TDSPORT.\n", env_port);
00973 } else
00974 tdsdump_log(TDS_DBG_INFO1, "Setting 'ip_port' to %d as a guess.\n", ip_port);
00975
00976
00977
00978
00979 tds_lookup_host(server, ip_addr);
00980 if (ip_addr[0])
00981 tds_dstr_copy(&connection->ip_addr, ip_addr);
00982 if (ip_port)
00983 connection->port = ip_port;
00984 }
00985 }
00986
00987
00988
00989
00990
00991
00992 static int
00993 parse_server_name_for_port(TDSCONNECTION * connection, TDSLOGIN * login)
00994 {
00995 char *pSep, *pEnd;
00996 char *server;
00997
00998
00999 server = tds_dstr_cstr(&login->server_name);
01000 pEnd = server + strlen(server);
01001 for (pSep = server; pSep < pEnd; pSep++)
01002 if (*pSep == ':')
01003 break;
01004
01005 if ((pSep < pEnd) && (pSep != server)) {
01006 if (!tds_dstr_copyn(&connection->server_name, server, pSep - server))
01007 return 0;
01008
01009
01010 login->port = connection->port = atoi(pSep + 1);
01011 tds_dstr_copy(&connection->instance_name, "");
01012 *pSep = 0;
01013
01014
01015 {
01016 char tmp[256];
01017
01018 tds_lookup_host(tds_dstr_cstr(&connection->server_name), tmp);
01019 if (!tds_dstr_copy(&connection->ip_addr, tmp))
01020 return 0;
01021 }
01022
01023 return 1;
01024 } else
01025 return 0;
01026 }
01027
01028
01029
01030
01031
01032
01033
01034 const TDS_COMPILETIME_SETTINGS *
01035 tds_get_compiletime_settings(void)
01036 {
01037 static const TDS_COMPILETIME_SETTINGS settings = {
01038 TDS_VERSION_NO, "unknown"
01039 # ifdef MSDBLIB
01040 , 1
01041 # else
01042 , 0
01043 # endif
01044 , -1
01045 # ifdef _REENTRANT
01046 , 1
01047 # else
01048 , 0
01049 # endif
01050 # ifdef HAVE_ICONV
01051 , 1
01052 # else
01053 , 0
01054 # endif
01055 # ifdef TDS46
01056 , "4.6"
01057 # else
01058 # ifdef TDS50
01059 , "5.0"
01060 # else
01061 # ifdef TDS70
01062 , "7.0"
01063 # else
01064 # ifdef TDS80
01065 , "8.0"
01066 # else
01067 , "4.2"
01068 # endif
01069 # endif
01070 # endif
01071 # endif
01072 # ifdef IODBC
01073 , 1
01074 # else
01075 , 0
01076 # endif
01077 # ifdef UNIXODBC
01078 , 1
01079 # else
01080 , 0
01081 # endif
01082 };
01083
01084 assert(settings.tdsver);
01085
01086 return &settings;
01087 }
01088
01089
01090
01091