static int parse_server(TDS_ERRS *errs, char *server, TDSLOGIN * login) { char *p = (char *) strchr(server, '\\'); if (p) { if (!tds_dstr_copy(&login->instance_name, p+1)) { odbc_errs_add(errs, "HY001", NULL); return 0; } *p = 0; } else { p = (char *) strchr(server, ','); if (p && atoi(p+1) > 0) { login->port = atoi(p+1); *p = 0; } } if (TDS_SUCCEED(tds_lookup_host_set(server, &login->ip_addrs))) if (!tds_dstr_copy(&login->server_host_name, server)) { odbc_errs_add(errs, "HY001", NULL); return 0; } return 1; }
CS_RETCODE cs_strbuild(CS_CONTEXT * ctx, CS_CHAR * buffer, CS_INT buflen, CS_INT * resultlen, CS_CHAR * text, CS_INT textlen, CS_CHAR * formats, CS_INT formatlen, ...) { va_list ap; TDSRET rc; tdsdump_log(TDS_DBG_FUNC, "cs_strbuild(%p, %p, %d, %p, %p, %d, %p, %d)\n", ctx, buffer, buflen, resultlen, text, textlen, formats, formatlen); va_start(ap, formatlen); rc = tds_vstrbuild(buffer, buflen, resultlen, text, textlen, formats, formatlen, ap); va_end(ap); return TDS_SUCCEED(rc) ? CS_SUCCEED : CS_FAIL; }
/** * tds_read_config_info() will fill the tds connection structure based on configuration * information gathered in the following order: * 1) Program specified in TDSLOGIN structure * 2) The environment variables TDSVER, TDSDUMP, TDSPORT, TDSQUERY, TDSHOST * 3) A config file with the following search order: * a) a readable file specified by environment variable FREETDSCONF * b) a readable file in ~/.freetds.conf * c) a readable file in $prefix/etc/freetds.conf * 3) ~/.interfaces if exists * 4) $SYBASE/interfaces if exists * 5) TDS_DEF_* default values * * .tdsrc and freetds.conf have been added to make the package easier to * integration with various Linux and *BSD distributions. */ TDSLOGIN * tds_read_config_info(TDSSOCKET * tds, TDSLOGIN * login, TDSLOCALE * locale) { TDSLOGIN *connection; char *s; char *path; pid_t pid; int opened = 0, found; struct addrinfo *addrs; /* allocate a new structure with hard coded and build-time defaults */ connection = tds_alloc_login(0); if (!connection || !tds_init_login(connection, locale)) { tds_free_login(connection); return NULL; } s = getenv("TDSDUMPCONFIG"); if (s) { if (*s) { opened = tdsdump_open(s); } else { pid = getpid(); if (asprintf(&path, pid_config_logpath, pid) >= 0) { if (*path) { opened = tdsdump_open(path); } free(path); } } } tdsdump_log(TDS_DBG_INFO1, "Getting connection information for [%s].\n", tds_dstr_cstr(&login->server_name)); /* (The server name is set in login.c.) */ /* Read the config files. */ tdsdump_log(TDS_DBG_INFO1, "Attempting to read conf files.\n"); found = tds_read_conf_file(connection, tds_dstr_cstr(&login->server_name)); if (!found) { if (parse_server_name_for_port(connection, login)) { found = tds_read_conf_file(connection, tds_dstr_cstr(&connection->server_name)); /* do it again to really override what found in freetds.conf */ if (found) { parse_server_name_for_port(connection, login); } else if (TDS_SUCCEED(tds_lookup_host_set(tds_dstr_cstr(&connection->server_name), &connection->ip_addrs))) { if (!tds_dstr_dup(&connection->server_host_name, &connection->server_name)) { tds_free_login(connection); return NULL; } found = 1; } } } if (!found) { /* fallback to interfaces file */ tdsdump_log(TDS_DBG_INFO1, "Failed in reading conf file. Trying interface files.\n"); if (!tds_read_interfaces(tds_dstr_cstr(&login->server_name), connection)) { tdsdump_log(TDS_DBG_INFO1, "Failed to find [%s] in configuration files; trying '%s' instead.\n", tds_dstr_cstr(&login->server_name), tds_dstr_cstr(&connection->server_name)); if (connection->ip_addrs == NULL) tdserror(tds_get_ctx(tds), tds, TDSEINTF, 0); } } /* Override config file settings with environment variables. */ tds_fix_login(connection); /* And finally apply anything from the login structure */ if (!tds_config_login(connection, login)) { tds_free_login(connection); return NULL; } if (opened) { char tmp[128]; tdsdump_log(TDS_DBG_INFO1, "Final connection parameters:\n"); tdsdump_log(TDS_DBG_INFO1, "\t%20s = %s\n", "server_name", tds_dstr_cstr(&connection->server_name)); tdsdump_log(TDS_DBG_INFO1, "\t%20s = %s\n", "server_host_name", tds_dstr_cstr(&connection->server_host_name)); for (addrs = connection->ip_addrs; addrs != NULL; addrs = addrs->ai_next) tdsdump_log(TDS_DBG_INFO1, "\t%20s = %s\n", "ip_addr", tds_addrinfo2str(addrs, tmp, sizeof(tmp))); if (connection->ip_addrs == NULL) tdsdump_log(TDS_DBG_INFO1, "\t%20s = %s\n", "ip_addr", ""); tdsdump_log(TDS_DBG_INFO1, "\t%20s = %s\n", "instance_name", tds_dstr_cstr(&connection->instance_name)); tdsdump_log(TDS_DBG_INFO1, "\t%20s = %d\n", "port", connection->port); tdsdump_log(TDS_DBG_INFO1, "\t%20s = %d\n", "major_version", TDS_MAJOR(connection)); tdsdump_log(TDS_DBG_INFO1, "\t%20s = %d\n", "minor_version", TDS_MINOR(connection)); tdsdump_log(TDS_DBG_INFO1, "\t%20s = %d\n", "block_size", connection->block_size); tdsdump_log(TDS_DBG_INFO1, "\t%20s = %s\n", "language", tds_dstr_cstr(&connection->language)); tdsdump_log(TDS_DBG_INFO1, "\t%20s = %s\n", "server_charset", tds_dstr_cstr(&connection->server_charset)); tdsdump_log(TDS_DBG_INFO1, "\t%20s = %d\n", "connect_timeout", connection->connect_timeout); tdsdump_log(TDS_DBG_INFO1, "\t%20s = %s\n", "client_host_name", tds_dstr_cstr(&connection->client_host_name)); tdsdump_log(TDS_DBG_INFO1, "\t%20s = %s\n", "client_charset", tds_dstr_cstr(&connection->client_charset)); tdsdump_log(TDS_DBG_INFO1, "\t%20s = %d\n", "use_utf16", connection->use_utf16); tdsdump_log(TDS_DBG_INFO1, "\t%20s = %s\n", "app_name", tds_dstr_cstr(&connection->app_name)); tdsdump_log(TDS_DBG_INFO1, "\t%20s = %s\n", "user_name", tds_dstr_cstr(&connection->user_name)); /* tdsdump_log(TDS_DBG_PASSWD, "\t%20s = %s\n", "password", tds_dstr_cstr(&connection->password)); (no such flag yet) */ tdsdump_log(TDS_DBG_INFO1, "\t%20s = %s\n", "library", tds_dstr_cstr(&connection->library)); tdsdump_log(TDS_DBG_INFO1, "\t%20s = %d\n", "bulk_copy", (int)connection->bulk_copy); tdsdump_log(TDS_DBG_INFO1, "\t%20s = %d\n", "suppress_language", (int)connection->suppress_language); tdsdump_log(TDS_DBG_INFO1, "\t%20s = %d\n", "encrypt level", (int)connection->encryption_level); tdsdump_log(TDS_DBG_INFO1, "\t%20s = %d\n", "query_timeout", connection->query_timeout); /* tdsdump_log(TDS_DBG_INFO1, "\t%20s = %s\n", "capabilities", tds_dstr_cstr(&connection->capabilities)); (not null terminated) */ tdsdump_log(TDS_DBG_INFO1, "\t%20s = %s\n", "database", tds_dstr_cstr(&connection->database)); tdsdump_log(TDS_DBG_INFO1, "\t%20s = %s\n", "dump_file", tds_dstr_cstr(&connection->dump_file)); tdsdump_log(TDS_DBG_INFO1, "\t%20s = %x\n", "debug_flags", connection->debug_flags); tdsdump_log(TDS_DBG_INFO1, "\t%20s = %d\n", "text_size", connection->text_size); tdsdump_log(TDS_DBG_INFO1, "\t%20s = %d\n", "emul_little_endian", connection->emul_little_endian); tdsdump_log(TDS_DBG_INFO1, "\t%20s = %s\n", "server_realm_name", tds_dstr_cstr(&connection->server_realm_name)); tdsdump_log(TDS_DBG_INFO1, "\t%20s = %s\n", "server_spn", tds_dstr_cstr(&connection->server_spn)); tdsdump_log(TDS_DBG_INFO1, "\t%20s = %s\n", "cafile", tds_dstr_cstr(&connection->cafile)); tdsdump_log(TDS_DBG_INFO1, "\t%20s = %s\n", "crlfile", tds_dstr_cstr(&connection->crlfile)); tdsdump_log(TDS_DBG_INFO1, "\t%20s = %d\n", "check_ssl_hostname", connection->check_ssl_hostname); tdsdump_log(TDS_DBG_INFO1, "\t%20s = %s\n", "db_filename", tds_dstr_cstr(&connection->db_filename)); tdsdump_log(TDS_DBG_INFO1, "\t%20s = %d\n", "readonly_intent", connection->readonly_intent); tdsdump_close(); } /* * If a dump file has been specified, start logging */ if (!tds_dstr_isempty(&connection->dump_file) && !tdsdump_isopen()) { if (connection->debug_flags) tds_debug_flags = connection->debug_flags; tdsdump_open(tds_dstr_cstr(&connection->dump_file)); } return connection; }
/** * Try to find the IP number and port for a (possibly) logical server name. * * @note This function uses only the interfaces file and is deprecated. */ static int tds_read_interfaces(const char *server, TDSLOGIN * login) { int found = 0; /* read $SYBASE/interfaces */ if (!server || !server[0]) { server = getenv("TDSQUERY"); if (!server || !server[0]) server = "SYBASE"; tdsdump_log(TDS_DBG_INFO1, "Setting server to %s from $TDSQUERY.\n", server); } tdsdump_log(TDS_DBG_INFO1, "Looking for server %s....\n", server); /* * Look for the server in the interf_file iff interf_file has been set. */ if (interf_file) { tdsdump_log(TDS_DBG_INFO1, "Looking for server in file %s.\n", interf_file); found = search_interface_file(login, "", interf_file, server); } /* * if we haven't found the server yet then look for a $HOME/.interfaces file */ if (!found) { char *path = tds_get_home_file(".interfaces"); if (path) { tdsdump_log(TDS_DBG_INFO1, "Looking for server in %s.\n", path); found = search_interface_file(login, "", path, server); free(path); } } /* * if we haven't found the server yet then look in $SYBBASE/interfaces file */ if (!found) { const char *sybase = getenv("SYBASE"); #ifdef __VMS /* We've got to be in unix syntax for later slash-joined concatenation. */ #include <unixlib.h> const char *unixspec = decc$translate_vms(sybase); if ( (int)unixspec != 0 && (int)unixspec != -1 ) sybase = unixspec; #endif if (!sybase || !sybase[0]) sybase = interfaces_path; tdsdump_log(TDS_DBG_INFO1, "Looking for server in %s/interfaces.\n", sybase); found = search_interface_file(login, sybase, "interfaces", server); } /* * If we still don't have the server and port then assume the user * typed an actual server host name. */ if (!found) { int ip_port; const char *env_port; /* * Make a guess about the port number */ if (login->port == 0) { /* * Not set in the [global] section of the * configure file, take a guess. */ ip_port = TDS_DEF_PORT; } else { /* * Preserve setting from the [global] section * of the configure file. */ ip_port = login->port; } if ((env_port = getenv("TDSPORT")) != NULL) { ip_port = tds_lookup_port(env_port); tdsdump_log(TDS_DBG_INFO1, "Setting 'ip_port' to %s from $TDSPORT.\n", env_port); } else tdsdump_log(TDS_DBG_INFO1, "Setting 'ip_port' to %d as a guess.\n", ip_port); /* * look up the host */ if (TDS_SUCCEED(tds_lookup_host_set(server, &login->ip_addrs))) if (!tds_dstr_copy(&login->server_host_name, server)) return 0; if (ip_port) login->port = ip_port; } return found; }
/** * Open and read the file 'file' searching for a logical server * by the name of 'host'. If one is found then lookup * the IP address and port number and store them in 'login' * * \param dir name of base directory for interface file * \param file name of the interface file * \param host logical host to search for * \return 0 if not fount 1 if found */ static int search_interface_file(TDSLOGIN * login, const char *dir, const char *file, const char *host) { char *pathname; char line[255]; char tmp_ip[sizeof(line)]; char tmp_port[sizeof(line)]; char tmp_ver[sizeof(line)]; FILE *in; char *field; int found = 0; int server_found = 0; char *lasts; line[0] = '\0'; tmp_ip[0] = '\0'; tmp_port[0] = '\0'; tmp_ver[0] = '\0'; tdsdump_log(TDS_DBG_INFO1, "Searching interfaces file %s/%s.\n", dir, file); pathname = (char *) malloc(strlen(dir) + strlen(file) + 10); if (!pathname) return 0; /* * create the full pathname to the interface file */ if (file[0] == '\0') { pathname[0] = '\0'; } else { if (dir[0] == '\0') { pathname[0] = '\0'; } else { strcpy(pathname, dir); strcat(pathname, TDS_SDIR_SEPARATOR); } strcat(pathname, file); } /* * parse the interfaces file and find the server and port */ if ((in = fopen(pathname, "r")) == NULL) { tdsdump_log(TDS_DBG_INFO1, "Couldn't open %s.\n", pathname); free(pathname); return 0; } tdsdump_log(TDS_DBG_INFO1, "Interfaces file %s opened.\n", pathname); while (fgets(line, sizeof(line) - 1, in)) { if (line[0] == '#') continue; /* comment */ if (!TDS_ISSPACE(line[0])) { field = strtok_r(line, "\n\t ", &lasts); if (!strcmp(field, host)) { found = 1; tdsdump_log(TDS_DBG_INFO1, "Found matching entry for host %s.\n", host); } else found = 0; } else if (found && TDS_ISSPACE(line[0])) { field = strtok_r(line, "\n\t ", &lasts); if (field != NULL && !strcmp(field, "query")) { field = strtok_r(NULL, "\n\t ", &lasts); /* tcp or tli */ if (!strcmp(field, "tli")) { tdsdump_log(TDS_DBG_INFO1, "TLI service.\n"); field = strtok_r(NULL, "\n\t ", &lasts); /* tcp */ field = strtok_r(NULL, "\n\t ", &lasts); /* device */ field = strtok_r(NULL, "\n\t ", &lasts); /* host/port */ if (strlen(field) >= 18) { sprintf(tmp_port, "%d", hex2num(&field[6]) * 256 + hex2num(&field[8])); sprintf(tmp_ip, "%d.%d.%d.%d", hex2num(&field[10]), hex2num(&field[12]), hex2num(&field[14]), hex2num(&field[16])); tdsdump_log(TDS_DBG_INFO1, "tmp_port = %s. tmp_ip = %s.\n", tmp_port, tmp_ip); } } else { field = strtok_r(NULL, "\n\t ", &lasts); /* ether */ strcpy(tmp_ver, field); field = strtok_r(NULL, "\n\t ", &lasts); /* host */ strcpy(tmp_ip, field); tdsdump_log(TDS_DBG_INFO1, "host field %s.\n", tmp_ip); field = strtok_r(NULL, "\n\t ", &lasts); /* port */ strcpy(tmp_port, field); } /* else */ server_found = 1; } /* if */ } /* else if */ } /* while */ fclose(in); free(pathname); /* * Look up the host and service */ if (server_found) { if (TDS_SUCCEED(tds_lookup_host_set(tmp_ip, &login->ip_addrs))) { struct addrinfo *addrs; if (!tds_dstr_copy(&login->server_host_name, tmp_ip)) return 0; for (addrs = login->ip_addrs; addrs != NULL; addrs = addrs->ai_next) { tdsdump_log(TDS_DBG_INFO1, "Resolved IP as '%s'.\n", tds_addrinfo2str(login->ip_addrs, line, sizeof(line))); } } else { tdsdump_log(TDS_DBG_WARN, "Name resolution failed for IP '%s'.\n", tmp_ip); } if (tmp_port[0]) login->port = tds_lookup_port(tmp_port); if (tmp_ver[0]) tds_config_verstr(tmp_ver, login); } return server_found; } /* search_interface_file() */