static int tds_read_conf_sections(FILE * in, const char *server, TDSLOGIN * login) { DSTR default_instance; int default_port; int found; tds_read_conf_section(in, "global", tds_parse_conf_section, login); if (!server[0]) return 0; rewind(in); tds_dstr_init(&default_instance); tds_dstr_dup(&default_instance, &login->instance_name); default_port = login->port; found = tds_read_conf_section(in, server, tds_parse_conf_section, login); /* * If both instance and port are specified and neither one came from the default, it's an error * TODO: If port/instance is specified in the non-default, it has priority over the default setting. * TODO: test this. */ if (!tds_dstr_isempty(&login->instance_name) && login->port && !(!tds_dstr_isempty(&default_instance) || default_port)) { tdsdump_log(TDS_DBG_ERROR, "error: cannot specify both port %d and instance %s.\n", login->port, tds_dstr_cstr(&login->instance_name)); /* tdserror(tds_get_ctx(tds), tds, TDSEPORTINSTANCE, 0); */ } tds_dstr_free(&default_instance); return found; }
static int tds_config_login(TDSLOGIN * connection, TDSLOGIN * login) { DSTR *res = &login->server_name; if (!tds_dstr_isempty(&login->server_name)) { if (1 || tds_dstr_isempty(&connection->server_name)) res = tds_dstr_dup(&connection->server_name, &login->server_name); } if (login->tds_version) connection->tds_version = login->tds_version; if (res && !tds_dstr_isempty(&login->language)) { res = tds_dstr_dup(&connection->language, &login->language); } if (res && !tds_dstr_isempty(&login->server_charset)) { res = tds_dstr_dup(&connection->server_charset, &login->server_charset); } if (res && !tds_dstr_isempty(&login->client_charset)) { res = tds_dstr_dup(&connection->client_charset, &login->client_charset); tdsdump_log(TDS_DBG_INFO1, "tds_config_login: %s is %s.\n", "client_charset", tds_dstr_cstr(&connection->client_charset)); } if (!login->use_utf16) connection->use_utf16 = login->use_utf16; if (res && !tds_dstr_isempty(&login->database)) { res = tds_dstr_dup(&connection->database, &login->database); tdsdump_log(TDS_DBG_INFO1, "tds_config_login: %s is %s.\n", "database_name", tds_dstr_cstr(&connection->database)); } if (res && !tds_dstr_isempty(&login->client_host_name)) { res = tds_dstr_dup(&connection->client_host_name, &login->client_host_name); } if (res && !tds_dstr_isempty(&login->app_name)) { res = tds_dstr_dup(&connection->app_name, &login->app_name); } if (res && !tds_dstr_isempty(&login->user_name)) { res = tds_dstr_dup(&connection->user_name, &login->user_name); } if (res && !tds_dstr_isempty(&login->password)) { /* for security reason clear memory */ tds_dstr_zero(&connection->password); res = tds_dstr_dup(&connection->password, &login->password); } if (res && !tds_dstr_isempty(&login->library)) { res = tds_dstr_dup(&connection->library, &login->library); } if (login->encryption_level) { connection->encryption_level = login->encryption_level; } if (login->suppress_language) { connection->suppress_language = 1; } if (login->bulk_copy) { connection->bulk_copy = 1; } if (login->block_size) { connection->block_size = login->block_size; } if (login->port) connection->port = login->port; if (login->connect_timeout) connection->connect_timeout = login->connect_timeout; if (login->query_timeout) connection->query_timeout = login->query_timeout; if (!login->check_ssl_hostname) connection->check_ssl_hostname = login->check_ssl_hostname; if (res && !tds_dstr_isempty(&login->db_filename)) { res = tds_dstr_dup(&connection->db_filename, &login->db_filename); } /* copy other info not present in configuration file */ connection->capabilities = login->capabilities; if (login->readonly_intent) connection->readonly_intent = login->readonly_intent; connection->use_new_password = login->use_new_password; if (res) res = tds_dstr_dup(&connection->new_password, &login->new_password); return res != NULL; }
/** * 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; }
static void tds_config_login(TDSLOGIN * connection, TDSLOGIN * login) { if (!tds_dstr_isempty(&login->server_name)) { if (1 || tds_dstr_isempty(&connection->server_name)) tds_dstr_dup(&connection->server_name, &login->server_name); } if (login->tds_version) connection->tds_version = login->tds_version; if (!tds_dstr_isempty(&login->language)) { tds_dstr_dup(&connection->language, &login->language); } if (!tds_dstr_isempty(&login->server_charset)) { tds_dstr_dup(&connection->server_charset, &login->server_charset); } if (!tds_dstr_isempty(&login->client_charset)) { tds_dstr_dup(&connection->client_charset, &login->client_charset); tdsdump_log(TDS_DBG_INFO1, "tds_config_login: %s is %s.\n", "client_charset", tds_dstr_cstr(&connection->client_charset)); } if (!tds_dstr_isempty(&login->database)) { tds_dstr_dup(&connection->database, &login->database); tdsdump_log(TDS_DBG_INFO1, "tds_config_login: %s is %s.\n", "database_name", tds_dstr_cstr(&connection->database)); } if (!tds_dstr_isempty(&login->client_host_name)) { tds_dstr_dup(&connection->client_host_name, &login->client_host_name); } if (!tds_dstr_isempty(&login->app_name)) { tds_dstr_dup(&connection->app_name, &login->app_name); } if (!tds_dstr_isempty(&login->user_name)) { tds_dstr_dup(&connection->user_name, &login->user_name); } if (!tds_dstr_isempty(&login->password)) { /* for security reason clear memory */ tds_dstr_zero(&connection->password); tds_dstr_dup(&connection->password, &login->password); } if (!tds_dstr_isempty(&login->library)) { tds_dstr_dup(&connection->library, &login->library); } if (login->encryption_level) { connection->encryption_level = login->encryption_level; } if (login->suppress_language) { connection->suppress_language = 1; } if (login->bulk_copy) { connection->bulk_copy = 1; } if (login->block_size) { connection->block_size = login->block_size; } if (login->port) connection->port = login->port; if (login->connect_timeout) connection->connect_timeout = login->connect_timeout; if (login->query_timeout) connection->query_timeout = login->query_timeout; /* copy other info not present in configuration file */ connection->capabilities = login->capabilities; }
/** * Initialize BCP information. * Query structure of the table to server. * \tds * \param bcpinfo BCP information to initialize. Structure should be allocate * and table name and direction should be already set. */ TDSRET tds_bcp_init(TDSSOCKET *tds, TDSBCPINFO *bcpinfo) { TDSRESULTINFO *resinfo; TDSRESULTINFO *bindinfo = NULL; TDSCOLUMN *curcol; TDS_INT result_type; int i; TDSRET rc; const char *fmt; /* FIXME don't leave state in processing state */ /* TODO quote tablename if needed */ if (bcpinfo->direction != TDS_BCP_QUERYOUT) fmt = "SET FMTONLY ON select * from %s SET FMTONLY OFF"; else fmt = "SET FMTONLY ON %s SET FMTONLY OFF"; if (TDS_FAILED(rc=tds_submit_queryf(tds, fmt, bcpinfo->tablename))) /* TODO return an error ?? */ /* Attempt to use Bulk Copy with a non-existent Server table (might be why ...) */ return rc; /* TODO possibly stop at ROWFMT and copy before going to idle */ /* TODO check what happen if table is not present, cleanup on error */ while ((rc = tds_process_tokens(tds, &result_type, NULL, TDS_TOKEN_RESULTS)) == TDS_SUCCESS) continue; if (TDS_FAILED(rc)) return rc; /* copy the results info from the TDS socket */ if (!tds->res_info) return TDS_FAIL; resinfo = tds->res_info; if ((bindinfo = tds_alloc_results(resinfo->num_cols)) == NULL) { rc = TDS_FAIL; goto cleanup; } bindinfo->row_size = resinfo->row_size; /* Copy the column metadata */ rc = TDS_FAIL; for (i = 0; i < bindinfo->num_cols; i++) { curcol = bindinfo->columns[i]; /* * TODO use memcpy ?? * curcol and resinfo->columns[i] are both TDSCOLUMN. * Why not "curcol = resinfo->columns[i];"? Because the rest of TDSCOLUMN (below column_timestamp) * isn't being used. Perhaps this "upper" part of TDSCOLUMN should be a substructure. * Or, see if the "lower" part is unused (and zeroed out) at this point, and just do one assignment. */ curcol->funcs = resinfo->columns[i]->funcs; curcol->column_type = resinfo->columns[i]->column_type; curcol->column_usertype = resinfo->columns[i]->column_usertype; curcol->column_flags = resinfo->columns[i]->column_flags; if (curcol->column_varint_size == 0) curcol->column_cur_size = resinfo->columns[i]->column_cur_size; else curcol->column_cur_size = -1; curcol->column_size = resinfo->columns[i]->column_size; curcol->column_varint_size = resinfo->columns[i]->column_varint_size; curcol->column_prec = resinfo->columns[i]->column_prec; curcol->column_scale = resinfo->columns[i]->column_scale; curcol->on_server.column_type = resinfo->columns[i]->on_server.column_type; curcol->on_server.column_size = resinfo->columns[i]->on_server.column_size; curcol->char_conv = resinfo->columns[i]->char_conv; if (!tds_dstr_dup(&curcol->column_name, &resinfo->columns[i]->column_name)) goto cleanup; if (!tds_dstr_dup(&curcol->table_column_name, &resinfo->columns[i]->table_column_name)) goto cleanup; curcol->column_nullable = resinfo->columns[i]->column_nullable; curcol->column_identity = resinfo->columns[i]->column_identity; curcol->column_timestamp = resinfo->columns[i]->column_timestamp; memcpy(curcol->column_collation, resinfo->columns[i]->column_collation, 5); if (is_numeric_type(curcol->column_type)) { curcol->bcp_column_data = tds_alloc_bcp_column_data(sizeof(TDS_NUMERIC)); ((TDS_NUMERIC *) curcol->bcp_column_data->data)->precision = curcol->column_prec; ((TDS_NUMERIC *) curcol->bcp_column_data->data)->scale = curcol->column_scale; } else if (bcpinfo->bind_count != 0 /* ctlib */ && is_blob_col(curcol)) { curcol->bcp_column_data = tds_alloc_bcp_column_data(0); } else { curcol->bcp_column_data = tds_alloc_bcp_column_data(MAX(curcol->column_size,curcol->on_server.column_size)); } if (!curcol->bcp_column_data) goto cleanup; } if (!IS_TDS7_PLUS(tds->conn)) { bindinfo->current_row = (unsigned char*) malloc(bindinfo->row_size); if (!bindinfo->current_row) goto cleanup; bindinfo->row_free = tds_bcp_row_free; } if (bcpinfo->identity_insert_on) { rc = tds_submit_queryf(tds, "set identity_insert %s on", bcpinfo->tablename); if (TDS_FAILED(rc)) goto cleanup; /* TODO use tds_process_simple_query */ while ((rc = tds_process_tokens(tds, &result_type, NULL, TDS_TOKEN_RESULTS)) == TDS_SUCCESS) { } if (rc != TDS_NO_MORE_RESULTS) goto cleanup; } bcpinfo->bindinfo = bindinfo; bcpinfo->bind_count = 0; return TDS_SUCCESS; cleanup: tds_free_results(bindinfo); return rc; }