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; }
/** * Parse a DSN string which is delimited with NULs instead of semicolons. * This uses odbc_parse_connect_string() internally, and also adds support * for parsing the DSN and driver * \param attribs 0-delimited string, with \0\0 terminator * \param di where to store the results */ static void parse_wacky_dsn_string(LPCSTR attribs, DSNINFO * di) { LPCSTR str; char *build; /* for each field... */ for (str = attribs; *str; str += strlen(str) + 1) { if (!strncasecmp(str, "DSN=", 4)) { tds_dstr_copy(&di->origdsn, str + 4); tds_dstr_copy(&di->dsn, str + 4); } } /* allocate space for a ;-delimited version */ build = (char *) malloc(str - attribs); /* copy the fields into the new buffer with ;'s */ *build = '\0'; for (str = attribs; *str; str += strlen(str) + 1) { if (*build) strcat(build, ";"); strcat(build, str); } /* let odbc_parse_connect_string() parse the ;-delimited version */ odbc_parse_connect_string(NULL, build, build + strlen(build), di->login, NULL); }
static void tds_config_env_tdsquery(TDSCONNECTINFO * connect_info) { char *s; if ((s = getenv("TDSQUERY")) != NULL && s[0]) { tds_dstr_copy(&connect_info->server_name, s); tdsdump_log(TDS_DBG_INFO1, "%L Setting 'server_name' to '%s' from $TDSQUERY.\n", s); return; } if ((s = getenv("DSQUERY")) != NULL && s[0]) { tds_dstr_copy(&connect_info->server_name, s); tdsdump_log(TDS_DBG_INFO1, "%L Setting 'server_name' to '%s' from $DSQUERY.\n", s); } }
/** * Check the server name to find port info first * return 1 when found, else 0 * Warning: connect_info-> & login-> are all modified when needed */ static int parse_server_name_for_port(TDSCONNECTINFO * connect_info, TDSLOGIN * login) { char *pSep, *pEnd; char *server; /* seek the ':' in login server_name */ server = tds_dstr_cstr(&login->server_name); pEnd = server + strlen(server); for (pSep = server; pSep < pEnd; pSep++) if (*pSep == ':') break; if ((pSep < pEnd) && (pSep != server)) { /* yes, i found it! */ if (!tds_dstr_copyn(&connect_info->server_name, server, pSep - server)) /* end the server_name before the ':' */ return 0; /* FALSE */ /* modify connect_info-> && login->server_name & ->port */ login->port = connect_info->port = atoi(pSep + 1); *pSep = 0; /* connect_info->ip_addr needed */ { char tmp[256]; tds_lookup_host(tds_dstr_cstr(&connect_info->server_name), tmp); if (!tds_dstr_copy(&connect_info->ip_addr, tmp)) return 0; /* FALSE */ } return 1; /* TRUE */ } else return 0; /* FALSE */ }
/** * set a string from another buffer. * The string will use the supplied buffer (it not copy the string), * so it should be a pointer returned by malloc. * @param s dynamic string * @param src source buffer * @return string copied or NULL on memory error */ DSTR* tds_dstr_set(DSTR * s, char *src) { DSTR *res = tds_dstr_copy(s, src); if (TDS_LIKELY(res != NULL)) free(src); return res; }
static void tds_config_env_tdsport(TDSLOGIN * login) { char *s; if ((s = getenv("TDSPORT"))) { login->port = tds_lookup_port(s); tds_dstr_copy(&login->instance_name, ""); tdsdump_log(TDS_DBG_INFO1, "Setting 'port' to %s from $TDSPORT.\n", s); } return; }
/* TDSHOST env var, [email protected] 01/21/02 */ static void tds_config_env_tdshost(TDSCONNECTINFO * connect_info) { char *tdshost; char tmp[256]; if ((tdshost = getenv("TDSHOST"))) { tds_lookup_host(tdshost, tmp); tds_dstr_copy(&connect_info->ip_addr, tmp); tdsdump_log(TDS_DBG_INFO1, "%L Setting 'ip_addr' to %s (%s) from $TDSHOST.\n", tmp, tdshost); } return; }
/* * pool_mbr_login open a single pool login, to be call at init time or * to reconnect. */ static TDSSOCKET * pool_mbr_login(TDS_POOL * pool) { TDSCONTEXT *context; TDSLOGIN *login; TDSSOCKET *tds; TDSLOGIN *connection; char hostname[MAXHOSTNAMELEN]; login = tds_alloc_login(1); if (gethostname(hostname, MAXHOSTNAMELEN) < 0) strlcpy(hostname, "tdspool", MAXHOSTNAMELEN); if (!tds_set_passwd(login, pool->password) || !tds_set_user(login, pool->user) || !tds_set_app(login, "tdspool") || !tds_set_host(login, hostname) || !tds_set_library(login, "TDS-Library") || !tds_set_server(login, pool->server) || !tds_set_client_charset(login, "iso_1") || !tds_set_language(login, "us_english")) { tds_free_login(login); return NULL; } if (pool->database && strlen(pool->database)) { if (!tds_dstr_copy(&login->database, pool->database)) { tds_free_login(login); return NULL; } } context = tds_alloc_context(NULL); tds = tds_alloc_socket(context, 512); connection = tds_read_config_info(tds, login, context->locale); if (!connection || TDS_FAILED(tds_connect_and_login(tds, connection))) { tds_free_socket(tds); tds_free_login(connection); /* what to do? */ fprintf(stderr, "Could not open connection to server %s\n", pool->server); return NULL; } tds_free_login(connection); if (pool->database && strlen(pool->database)) { if (strcasecmp(tds->conn->env.database, pool->database) != 0) { fprintf(stderr, "changing database failed\n"); return NULL; } } return tds; }
/** * Check the server name to find port info first * Warning: connection-> & login-> are all modified when needed * \return 1 when found, else 0 */ static int parse_server_name_for_port(TDSLOGIN * connection, TDSLOGIN * login) { const char *pSep; const char *server; /* seek the ':' in login server_name */ server = tds_dstr_cstr(&login->server_name); /* IPv6 address can be quoted */ if (server[0] == '[') { pSep = strstr(server, "]:"); if (pSep) ++pSep; } else { pSep = strrchr(server, ':'); } if (pSep && pSep != server) { /* yes, i found it! */ /* modify connection-> && login->server_name & ->port */ login->port = connection->port = atoi(pSep + 1); tds_dstr_copy(&connection->instance_name, ""); } else { /* handle instance name */ pSep = strrchr(server, '\\'); if (!pSep || pSep == server) return 0; tds_dstr_copy(&connection->instance_name, pSep + 1); connection->port = 0; } if (!tds_dstr_copyn(&connection->server_name, server, pSep - server)) return 0; return 1; }
static void tds_config_env_tdsdump(TDSLOGIN * login) { char *s; char *path; pid_t pid = 0; if ((s = getenv("TDSDUMP"))) { if (!strlen(s)) { pid = getpid(); if (asprintf(&path, pid_logpath, pid) >= 0) tds_dstr_set(&login->dump_file, path); } else { tds_dstr_copy(&login->dump_file, s); } tdsdump_log(TDS_DBG_INFO1, "Setting 'dump_file' to '%s' from $TDSDUMP.\n", tds_dstr_cstr(&login->dump_file)); } }
static void tds_config_env_tdsdump(TDSCONNECTINFO * connect_info) { char *s; char *path; pid_t pid = 0; if ((s = getenv("TDSDUMP"))) { if (!strlen(s)) { pid = getpid(); if (asprintf(&path, "/tmp/freetds.log.%d", pid) >= 0) tds_dstr_set(&connect_info->dump_file, path); } else { tds_dstr_copy(&connect_info->dump_file, s); } tdsdump_log(TDS_DBG_INFO1, "%L Setting 'dump_file' to '%s' from $TDSDUMP.\n", connect_info->dump_file); } }
/* TDSHOST env var, [email protected] 01/21/02 */ static void tds_config_env_tdshost(TDSLOGIN * login) { const char *tdshost; char tmp[128]; struct tds_addrinfo *addrs; if (!(tdshost = getenv("TDSHOST"))) return; if (TDS_FAILED(tds_lookup_host_set(tdshost, &login->ip_addrs))) { tdsdump_log(TDS_DBG_WARN, "Name resolution failed for '%s' from $TDSHOST.\n", tdshost); return; } tds_dstr_copy(&login->server_host_name, tdshost); for (addrs = login->ip_addrs; addrs != NULL; addrs = addrs->ai_next) { tdsdump_log(TDS_DBG_INFO1, "Setting IP Address to %s (%s) from $TDSHOST.\n", tds_addrinfo2str(addrs, tmp, sizeof(tmp)), tdshost); } }
static TDSRET set_result_column(TDSSOCKET * tds, TDSCOLUMN * curcol, const char name[], const struct col_t *pvalue) { assert(curcol && pvalue); assert(name); curcol->column_usertype = pvalue->type; curcol->column_nullable = true; curcol->column_writeable = false; curcol->column_identity = false; tds_set_column_type(tds->conn, curcol, pvalue->type); /* sets "cardinal" type */ curcol->column_timestamp = (curcol->column_type == SYBBINARY && curcol->column_usertype == TDS_UT_TIMESTAMP); #if 0 curcol->funcs->get_info(tds, curcol); #endif curcol->on_server.column_size = curcol->column_size; if (!tds_dstr_copy(&curcol->column_name, name)) return TDS_FAIL; tdsdump_log(TDS_DBG_INFO1, "tds7_get_data_info: \n" "\tcolname = %s\n" "\ttype = %d (%s)\n" "\tserver's type = %d (%s)\n" "\tcolumn_varint_size = %d\n" "\tcolumn_size = %d (%d on server)\n", tds_dstr_cstr(&curcol->column_name), curcol->column_type, tds_prtype(curcol->column_type), curcol->on_server.column_type, tds_prtype(curcol->on_server.column_type), curcol->column_varint_size, curcol->column_size, curcol->on_server.column_size); return TDS_SUCCESS; }
/** * Read connection information from given DSN * @param DSN DSN name * @param login where to store connection info * @return 1 if success 0 otherwhise */ int odbc_get_dsn_info(TDS_ERRS *errs, const char *DSN, TDSLOGIN * login) { char tmp[FILENAME_MAX]; int freetds_conf_less = 1; /* use old servername */ if (myGetPrivateProfileString(DSN, odbc_param_Servername, tmp) > 0) { freetds_conf_less = 0; if (!tds_dstr_copy(&login->server_name, tmp)) { odbc_errs_add(errs, "HY001", NULL); return 0; } tds_read_conf_file(login, tmp); if (myGetPrivateProfileString(DSN, odbc_param_Server, tmp) > 0) { odbc_errs_add(errs, "HY000", "You cannot specify both SERVERNAME and SERVER"); return 0; } if (myGetPrivateProfileString(DSN, odbc_param_Address, tmp) > 0) { odbc_errs_add(errs, "HY000", "You cannot specify both SERVERNAME and ADDRESS"); return 0; } } /* search for server (compatible with ms one) */ if (freetds_conf_less) { int address_specified = 0; if (myGetPrivateProfileString(DSN, odbc_param_Address, tmp) > 0) { address_specified = 1; /* TODO parse like MS */ if (TDS_FAILED(tds_lookup_host_set(tmp, &login->ip_addrs))) { odbc_errs_add(errs, "HY000", "Error parsing ADDRESS attribute"); return 0; } } if (myGetPrivateProfileString(DSN, odbc_param_Server, tmp) > 0) { if (!tds_dstr_copy(&login->server_name, tmp)) { odbc_errs_add(errs, "HY001", NULL); return 0; } if (!address_specified) { if (!parse_server(errs, tmp, login)) return 0; } } } if (myGetPrivateProfileString(DSN, odbc_param_Port, tmp) > 0) tds_parse_conf_section(TDS_STR_PORT, tmp, login); if (myGetPrivateProfileString(DSN, odbc_param_TDS_Version, tmp) > 0) tds_parse_conf_section(TDS_STR_VERSION, tmp, login); if (myGetPrivateProfileString(DSN, odbc_param_Language, tmp) > 0) tds_parse_conf_section(TDS_STR_LANGUAGE, tmp, login); if (tds_dstr_isempty(&login->database) && myGetPrivateProfileString(DSN, odbc_param_Database, tmp) > 0) if (!tds_dstr_copy(&login->database, tmp)) { odbc_errs_add(errs, "HY001", NULL); return 0; } if (myGetPrivateProfileString(DSN, odbc_param_TextSize, tmp) > 0) tds_parse_conf_section(TDS_STR_TEXTSZ, tmp, login); if (myGetPrivateProfileString(DSN, odbc_param_PacketSize, tmp) > 0) tds_parse_conf_section(TDS_STR_BLKSZ, tmp, login); if (myGetPrivateProfileString(DSN, odbc_param_ClientCharset, tmp) > 0) tds_parse_conf_section(TDS_STR_CLCHARSET, tmp, login); if (myGetPrivateProfileString(DSN, odbc_param_DumpFile, tmp) > 0) tds_parse_conf_section(TDS_STR_DUMPFILE, tmp, login); if (myGetPrivateProfileString(DSN, odbc_param_DumpFileAppend, tmp) > 0) tds_parse_conf_section(TDS_STR_APPENDMODE, tmp, login); if (myGetPrivateProfileString(DSN, odbc_param_DebugFlags, tmp) > 0) tds_parse_conf_section(TDS_STR_DEBUGFLAGS, tmp, login); if (myGetPrivateProfileString(DSN, odbc_param_Encryption, tmp) > 0) tds_parse_conf_section(TDS_STR_ENCRYPTION, tmp, login); if (myGetPrivateProfileString(DSN, odbc_param_UseNTLMv2, tmp) > 0) tds_parse_conf_section(TDS_STR_USENTLMV2, tmp, login); if (myGetPrivateProfileString(DSN, odbc_param_REALM, tmp) > 0) tds_parse_conf_section(TDS_STR_REALM, tmp, login); if (myGetPrivateProfileString(DSN, odbc_param_ServerSPN, tmp) > 0) tds_parse_conf_section(TDS_STR_SPN, tmp, login); if (myGetPrivateProfileString(DSN, odbc_param_Trusted_Connection, tmp) > 0 && tds_config_boolean(odbc_param_Trusted_Connection, tmp, login)) { tds_dstr_empty(&login->user_name); tds_dstr_empty(&login->password); } if (myGetPrivateProfileString(DSN, odbc_param_MARS_Connection, tmp) > 0 && tds_config_boolean(odbc_param_MARS_Connection, tmp, login)) { login->mars = 1; } if (myGetPrivateProfileString(DSN, odbc_param_AttachDbFilename, tmp) > 0) tds_parse_conf_section(TDS_STR_DBFILENAME, tmp, login); return 1; }
/** * Callback function for the DSN Configuration dialog * \param hDlg identifies the dialog * \param message what happened to the dialog * \param wParam varies with message * \param lParam pointer to DSNINFO struct */ static BOOL CALLBACK DSNDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { DSNINFO *di; char tmp[100]; const char *pstr; int major, minor, i; static const char *protocols[] = { "TDS 4.2", "TDS 4.6", "TDS 5.0", "TDS 7.0", "TDS 7.1", "TDS 7.2", "TDS 7.3", NULL }; switch (message) { case WM_INITDIALOG: /* lParam points to the DSNINFO */ di = (DSNINFO *) lParam; SetWindowUserData(hDlg, lParam); /* Stuff legal protocol names into IDC_PROTOCOL */ for (i = 0; protocols[i]; i++) { SendDlgItemMessage(hDlg, IDC_PROTOCOL, CB_ADDSTRING, 0, (LPARAM) protocols[i]); } /* copy info from DSNINFO to the dialog */ SendDlgItemMessage(hDlg, IDC_DSNNAME, WM_SETTEXT, 0, (LPARAM) tds_dstr_cstr(&di->dsn)); sprintf(tmp, "TDS %d.%d", TDS_MAJOR(di->login), TDS_MINOR(di->login)); SendDlgItemMessage(hDlg, IDC_PROTOCOL, CB_SELECTSTRING, -1, (LPARAM) tmp); SendDlgItemMessage(hDlg, IDC_ADDRESS, WM_SETTEXT, 0, (LPARAM) tds_dstr_cstr(&di->login->server_name)); sprintf(tmp, "%u", di->login->port); SendDlgItemMessage(hDlg, IDC_PORT, WM_SETTEXT, 0, (LPARAM) tmp); SendDlgItemMessage(hDlg, IDC_DATABASE, WM_SETTEXT, 0, (LPARAM) tds_dstr_cstr(&di->login->database)); return TRUE; case WM_COMMAND: /* Dialog's user data points to DSNINFO */ di = (DSNINFO *) GetWindowUserData(hDlg); /* The wParam indicates which button was pressed */ if (LOWORD(wParam) == IDCANCEL) { EndDialog(hDlg, FALSE); return TRUE; } else if (LOWORD(wParam) != IDOK) { /* Anything but IDCANCEL or IDOK is handled elsewhere */ break; } /* If we get here, then the user hit the [OK] button */ /* get values from dialog */ SendDlgItemMessage(hDlg, IDC_DSNNAME, WM_GETTEXT, sizeof tmp, (LPARAM) tmp); tds_dstr_copy(&di->dsn, tmp); SendDlgItemMessage(hDlg, IDC_PROTOCOL, WM_GETTEXT, sizeof tmp, (LPARAM) tmp); minor = 0; if (sscanf(tmp, "%*[^0-9]%d.%d", &major, &minor) > 1) { if (major == 8 && minor == 0) { major = 7; minor = 1; } di->login->tds_version = (major << 8) | minor; } SendDlgItemMessage(hDlg, IDC_ADDRESS, WM_GETTEXT, sizeof tmp, (LPARAM) tmp); tds_dstr_copy(&di->login->server_name, tmp); SendDlgItemMessage(hDlg, IDC_PORT, WM_GETTEXT, sizeof tmp, (LPARAM) tmp); di->login->port = atoi(tmp); SendDlgItemMessage(hDlg, IDC_DATABASE, WM_GETTEXT, sizeof tmp, (LPARAM) tmp); tds_dstr_copy(&di->login->database, tmp); /* validate */ SendDlgItemMessage(hDlg, IDC_HINT, WM_SETTEXT, 0, (LPARAM) "VALIDATING... please be patient"); pstr = validate(di); if (pstr != NULL) { SendDlgItemMessage(hDlg, IDC_HINT, WM_SETTEXT, 0, (LPARAM) pstr); return TRUE; } SendDlgItemMessage(hDlg, IDC_HINT, WM_SETTEXT, 0, (LPARAM) ""); /* No problems -- we're done */ EndDialog(hDlg, TRUE); return TRUE; } return FALSE; }
/** * 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; }
/* ========================= search_interface_file() ========================= * * Def: 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 'ip_addr', and * 'ip_port'. * * Ret: void * * =========================================================================== */ static int search_interface_file(TDSCONNECTINFO * connect_info, const char *dir, /* (I) Name of base directory for interface file */ const char *file, /* (I) Name of the interface file */ const char *host /* (I) Logical host to search for */ ) { 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, "%L 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, "/"); } strcat(pathname, file); } /* * * parse the interfaces file and find the server and port */ if ((in = fopen(pathname, "r")) == NULL) { tdsdump_log(TDS_DBG_INFO1, "%L Couldn't open %s.\n", pathname); free(pathname); return 0; } tdsdump_log(TDS_DBG_INFO1, "%L 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, "%L 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, "%L 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, "%L tmp_port = %d.mtp_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, "%L 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) { tds_lookup_host(tmp_ip, line); tdsdump_log(TDS_DBG_INFO1, "%L Resolved IP as '%s'.\n", line); tds_dstr_copy(&connect_info->ip_addr, line); if (tmp_port[0]) connect_info->port = tds_lookup_port(tmp_port); if (tmp_ver[0]) tds_config_verstr(tmp_ver, connect_info); } return server_found; } /* search_interface_file() */
SQLRETURN SQL_API SQLGetDiagField(SQLSMALLINT handleType, SQLHANDLE handle, SQLSMALLINT numRecord, SQLSMALLINT diagIdentifier, SQLPOINTER buffer, SQLSMALLINT cbBuffer, SQLSMALLINT FAR * pcbBuffer) { SQLRETURN result = SQL_SUCCESS; struct _sql_errors *errs = NULL; const char *msg; SQLINTEGER odbc_ver = SQL_OV_ODBC2; int cplen; TDS_STMT *stmt = NULL; TDS_DBC *dbc = NULL; TDS_ENV *env = NULL; char tmp[16]; if (cbBuffer < 0) return SQL_ERROR; if (!handle) return SQL_INVALID_HANDLE; switch (handleType) { case SQL_HANDLE_STMT: stmt = ((TDS_STMT *) handle); dbc = stmt->dbc; env = dbc->env; errs = &stmt->errs; break; case SQL_HANDLE_DBC: dbc = ((TDS_DBC *) handle); env = dbc->env; errs = &dbc->errs; break; case SQL_HANDLE_ENV: env = ((TDS_ENV *) handle); errs = &env->errs; break; default: return SQL_INVALID_HANDLE; } odbc_ver = env->attr.odbc_version; /* header (numRecord ignored) */ switch (diagIdentifier) { case SQL_DIAG_DYNAMIC_FUNCTION: if (handleType != SQL_HANDLE_STMT) return SQL_ERROR; /* TODO */ return odbc_set_string(buffer, cbBuffer, pcbBuffer, "", 0); case SQL_DIAG_DYNAMIC_FUNCTION_CODE: *(SQLINTEGER *) buffer = 0; return SQL_SUCCESS; case SQL_DIAG_NUMBER: *(SQLINTEGER *) buffer = errs->num_errors; return SQL_SUCCESS; case SQL_DIAG_RETURNCODE: *(SQLRETURN *) buffer = errs->lastrc; return SQL_SUCCESS; case SQL_DIAG_CURSOR_ROW_COUNT: if (handleType != SQL_HANDLE_STMT) return SQL_ERROR; /* TODO */ *(SQLINTEGER *) buffer = 0; return SQL_SUCCESS; case SQL_DIAG_ROW_COUNT: if (handleType != SQL_HANDLE_STMT) return SQL_ERROR; return _SQLRowCount((SQLHSTMT) handle, (SQLINTEGER FAR *) buffer); } if (numRecord > errs->num_errors) return SQL_NO_DATA_FOUND; if (numRecord <= 0) return SQL_ERROR; --numRecord; switch (diagIdentifier) { case SQL_DIAG_ROW_NUMBER: *(SQLINTEGER *) buffer = SQL_ROW_NUMBER_UNKNOWN; break; case SQL_DIAG_CLASS_ORIGIN: case SQL_DIAG_SUBCLASS_ORIGIN: if (odbc_ver == SQL_OV_ODBC2) result = odbc_set_string(buffer, cbBuffer, pcbBuffer, "ISO 9075", -1); else result = odbc_set_string(buffer, cbBuffer, pcbBuffer, "ODBC 3.0", -1); break; case SQL_DIAG_COLUMN_NUMBER: *(SQLINTEGER *) buffer = SQL_COLUMN_NUMBER_UNKNOWN; break; #ifdef SQL_DIAG_SS_MSGSTATE case SQL_DIAG_SS_MSGSTATE: if (errs->errs[numRecord].msgstate == 0) return SQL_ERROR; else *(SQLINTEGER *) buffer = errs->errs[numRecord].msgstate; break; #endif #ifdef SQL_DIAG_SS_LINE case SQL_DIAG_SS_LINE: if (errs->errs[numRecord].linenum == 0) return SQL_ERROR; else *(SQLUSMALLINT *) buffer = errs->errs[numRecord].linenum; break; #endif case SQL_DIAG_CONNECTION_NAME: if (dbc && dbc->tds_socket && dbc->tds_socket->spid > 0) cplen = sprintf(tmp, "%d", dbc->tds_socket->spid); else cplen = 0; result = odbc_set_string(buffer, cbBuffer, pcbBuffer, tmp, cplen); break; case SQL_DIAG_MESSAGE_TEXT: msg = errs->errs[numRecord].msg; result = odbc_set_string(buffer, cbBuffer, pcbBuffer, msg, -1); break; case SQL_DIAG_NATIVE: *(SQLINTEGER *) buffer = errs->errs[numRecord].native; break; case SQL_DIAG_SERVER_NAME: msg = ""; switch (handleType) { case SQL_HANDLE_ENV: break; case SQL_HANDLE_DBC: msg = tds_dstr_cstr(&dbc->server); break; case SQL_HANDLE_STMT: msg = tds_dstr_cstr(&stmt->dbc->server); /* if dbc->server is not initialized, init it * from the errs structure */ if (!msg[0] && errs->errs[numRecord].server) { tds_dstr_copy(&stmt->dbc->server, errs->errs[numRecord].server); msg = errs->errs[numRecord].server; } break; } result = odbc_set_string(buffer, cbBuffer, pcbBuffer, msg, -1); break; case SQL_DIAG_SQLSTATE: if (odbc_ver == SQL_OV_ODBC3) msg = errs->errs[numRecord].state3; else msg = errs->errs[numRecord].state2; result = odbc_set_string(buffer, cbBuffer, pcbBuffer, msg, 5); break; default: return SQL_ERROR; } return result; }
/** * Parse connection string and fill connect_info according * @param connect_string connect string * @param connect_string_end connect string end (pointer to char past last) * @param connect_info where to store connection info * @return 1 if success 0 otherwhise */ int odbc_parse_connect_string(const char *connect_string, const char *connect_string_end, TDSCONNECTINFO * connect_info) { const char *p, *end; DSTR *dest_s, value; int reparse = 0; /* flag for indicate second parse of string */ char option[16]; char tmp[256]; tds_dstr_init(&value); for (p = connect_string; p && *p;) { dest_s = NULL; /* parse option */ end = (const char *) memchr(p, '=', connect_string_end - p); if (!end) break; /* account for spaces between ;'s. */ while (p < end && *p == ' ') ++p; if ((end - p) >= (int) sizeof(option)) option[0] = 0; else { memcpy(option, p, end - p); option[end - p] = 0; } /* parse value */ p = end + 1; if (*p == '{') { ++p; /* search "};" */ end = p; while ((end = (const char *) memchr(end, '}', connect_string_end - end)) != NULL) { if ((end + 1) != connect_string_end && end[1] == ';') break; ++end; } } else { end = (const char *) memchr(p, ';', connect_string_end - p); } if (!end) end = connect_string_end; if (!tds_dstr_copyn(&value, p, end - p)) return 0; if (strcasecmp(option, "SERVER") == 0) { /* ignore if servername specified */ if (!reparse) { dest_s = &connect_info->server_name; tds_lookup_host(tds_dstr_cstr(&value), tmp); if (!tds_dstr_copy(&connect_info->ip_addr, tmp)) { tds_dstr_free(&value); return 0; } } } else if (strcasecmp(option, "SERVERNAME") == 0) { if (!reparse) { tds_read_conf_file(connect_info, tds_dstr_cstr(&value)); reparse = 1; p = connect_string; continue; } } else if (strcasecmp(option, "DSN") == 0) { if (!reparse) { odbc_get_dsn_info(tds_dstr_cstr(&value), connect_info); reparse = 1; p = connect_string; continue; } } else if (strcasecmp(option, "DATABASE") == 0) { dest_s = &connect_info->database; } else if (strcasecmp(option, "UID") == 0) { dest_s = &connect_info->user_name; } else if (strcasecmp(option, "PWD") == 0) { dest_s = &connect_info->password; } else if (strcasecmp(option, "APP") == 0) { dest_s = &connect_info->app_name; } else if (strcasecmp(option, "WSID") == 0) { dest_s = &connect_info->host_name; } else if (strcasecmp(option, "LANGUAGE") == 0) { dest_s = &connect_info->language; } else if (strcasecmp(option, "Port") == 0) { connect_info->port = atoi(tds_dstr_cstr(&value)); } else if (strcasecmp(option, "TDS_Version") == 0) { tds_config_verstr(tds_dstr_cstr(&value), connect_info); } else if (strcasecmp(option, "Domain") == 0) { dest_s = &connect_info->default_domain; } else if (strcasecmp(option, "TextSize") == 0) { connect_info->text_size = atoi(tds_dstr_cstr(&value)); } else if (strcasecmp(option, "PacketSize") == 0) { connect_info->block_size = atoi(tds_dstr_cstr(&value)); /* TODO "Address" field */ } /* copy to destination */ if (dest_s) { tds_dstr_set(dest_s, tds_dstr_cstr(&value)); tds_dstr_init(&value); } p = end; /* handle "" ";.." "};.." cases */ if (p >= connect_string_end) break; if (*p == '}') ++p; ++p; } tds_dstr_free(&value); return p != NULL; }
static void tds_config_login(TDSCONNECTINFO * connect_info, TDSLOGIN * login) { if (!tds_dstr_isempty(&login->server_name)) { tds_dstr_copy(&connect_info->server_name, tds_dstr_cstr(&login->server_name)); } if (login->major_version || login->minor_version) { connect_info->major_version = login->major_version; connect_info->minor_version = login->minor_version; } if (!tds_dstr_isempty(&login->language)) { tds_dstr_copy(&connect_info->language, tds_dstr_cstr(&login->language)); } if (!tds_dstr_isempty(&login->server_charset)) { tds_dstr_copy(&connect_info->server_charset, tds_dstr_cstr(&login->server_charset)); } if (!tds_dstr_isempty(&login->client_charset)) { tds_dstr_copy(&connect_info->client_charset, tds_dstr_cstr(&login->client_charset)); tdsdump_log(TDS_DBG_INFO1, "%L tds_config_login:%d: %s is %s.\n", __LINE__, "client_charset", connect_info->client_charset); } if (!tds_dstr_isempty(&login->host_name)) { tds_dstr_copy(&connect_info->host_name, tds_dstr_cstr(&login->host_name)); /* DBSETLHOST and it's equivilants are commentary fields * ** they don't affect connect_info->ip_addr (the server) but they show * ** up in an sp_who as the *clients* hostname. (bsb, 11/10) */ /* should work with IP (mlilback, 11/7/01) */ /* * if (connect_info->ip_addr) free(connect_info->ip_addr); * connect_info->ip_addr = calloc(sizeof(char),18); * tds_lookup_host(connect_info->host_name, NULL, connect_info->ip_addr, NULL); */ } if (!tds_dstr_isempty(&login->app_name)) { tds_dstr_copy(&connect_info->app_name, tds_dstr_cstr(&login->app_name)); } if (!tds_dstr_isempty(&login->user_name)) { tds_dstr_copy(&connect_info->user_name, tds_dstr_cstr(&login->user_name)); } if (!tds_dstr_isempty(&login->password)) { /* for security reason clear memory */ tds_dstr_zero(&connect_info->password); tds_dstr_copy(&connect_info->password, tds_dstr_cstr(&login->password)); } if (!tds_dstr_isempty(&login->library)) { tds_dstr_copy(&connect_info->library, tds_dstr_cstr(&login->library)); } if (login->encrypted) { connect_info->encrypted = 1; } if (login->suppress_language) { connect_info->suppress_language = 1; } if (login->bulk_copy) { connect_info->bulk_copy = 1; } if (login->block_size) { connect_info->block_size = login->block_size; } if (login->port) { connect_info->port = login->port; } if (login->connect_timeout) connect_info->connect_timeout = login->connect_timeout; /* copy other info not present in configuration file */ connect_info->query_timeout = login->query_timeout; connect_info->longquery_timeout = login->longquery_timeout; connect_info->longquery_func = login->longquery_func; connect_info->longquery_param = login->longquery_param; memcpy(connect_info->capabilities, login->capabilities, TDS_MAX_CAPABILITY); }
static void tds_parse_conf_section(const char *option, const char *value, void *param) { TDSCONNECTINFO *connect_info = (TDSCONNECTINFO *) param; char tmp[256]; tdsdump_log(TDS_DBG_INFO1, "%L option = '%s' value = '%s'.\n", option, value); if (!strcmp(option, TDS_STR_VERSION)) { tds_config_verstr(value, connect_info); } else if (!strcmp(option, TDS_STR_BLKSZ)) { if (atoi(value)) connect_info->block_size = atoi(value); } else if (!strcmp(option, TDS_STR_SWAPDT)) { connect_info->broken_dates = tds_config_boolean(value); } else if (!strcmp(option, TDS_STR_SWAPMNY)) { connect_info->broken_money = tds_config_boolean(value); } else if (!strcmp(option, TDS_STR_TRYSVR)) { connect_info->try_server_login = tds_config_boolean(value); } else if (!strcmp(option, TDS_STR_TRYDOM)) { connect_info->try_domain_login = tds_config_boolean(value); } else if (!strcmp(option, TDS_STR_DOMAIN)) { tds_dstr_copy(&connect_info->default_domain, value); } else if (!strcmp(option, TDS_STR_XDOMAUTH)) { connect_info->xdomain_auth = tds_config_boolean(value); } else if (!strcmp(option, TDS_STR_DUMPFILE)) { tds_dstr_copy(&connect_info->dump_file, value); } else if (!strcmp(option, TDS_STR_DEBUGLVL)) { if (atoi(value)) connect_info->debug_level = atoi(value); } else if (!strcmp(option, TDS_STR_TIMEOUT)) { if (atoi(value)) connect_info->timeout = atoi(value); } else if (!strcmp(option, TDS_STR_CONNTMOUT)) { if (atoi(value)) connect_info->connect_timeout = atoi(value); } else if (!strcmp(option, TDS_STR_HOST)) { tdsdump_log(TDS_DBG_INFO1, "%L Found host entry %s.\n", value); tds_lookup_host(value, tmp); tds_dstr_copy(&connect_info->ip_addr, tmp); tdsdump_log(TDS_DBG_INFO1, "%L IP addr is %s.\n", connect_info->ip_addr); } else if (!strcmp(option, TDS_STR_PORT)) { if (atoi(value)) connect_info->port = atoi(value); } else if (!strcmp(option, TDS_STR_EMUL_LE)) { connect_info->emul_little_endian = tds_config_boolean(value); } else if (!strcmp(option, TDS_STR_TEXTSZ)) { if (atoi(value)) connect_info->text_size = atoi(value); } else if (!strcmp(option, TDS_STR_CHARSET)) { tds_dstr_copy(&connect_info->server_charset, value); tdsdump_log(TDS_DBG_INFO1, "%L %s is %s.\n", option, connect_info->server_charset); } else if (!strcmp(option, TDS_STR_CLCHARSET)) { tds_dstr_copy(&connect_info->client_charset, value); tdsdump_log(TDS_DBG_INFO1, "%L tds_config_login:%d: %s is %s.\n", __LINE__, option, connect_info->client_charset); } else if (!strcmp(option, TDS_STR_LANGUAGE)) { tds_dstr_copy(&connect_info->language, value); } else if (!strcmp(option, TDS_STR_APPENDMODE)) { tds_g_append_mode = tds_config_boolean(value); } else { tdsdump_log(TDS_DBG_INFO1, "UNRECOGNIZED option '%s'...ignoring.\n", option); fprintf(stderr, "FreeTDS: %s:%d: ignoring unrecognized option '%s'\n", __FILE__, __LINE__, option); } }
/** * 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 void tds_read_interfaces(const char *server, TDSCONNECTINFO * connect_info) { int founded = 0; /* read $SYBASE/interfaces */ if (!server || strlen(server) == 0) { server = getenv("TDSQUERY"); if (!server || strlen(server) == 0) { server = "SYBASE"; } tdsdump_log(TDS_DBG_INFO1, "%L Setting server to %s from $TDSQUERY.\n", server); } tdsdump_log(TDS_DBG_INFO1, "%L 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, "%L Looking for server in file %s.\n", interf_file); founded = search_interface_file(connect_info, "", interf_file, server); } /* * if we haven't found the server yet then look for a $HOME/.interfaces file */ if (!founded) { char *path = tds_get_home_file(".interfaces"); if (path) { tdsdump_log(TDS_DBG_INFO1, "%L Looking for server in %s.\n", path); founded = search_interface_file(connect_info, "", path, server); free(path); } } /* * if we haven't found the server yet then look in $SYBBASE/interfaces file */ if (!founded) { const char *sybase = getenv("SYBASE"); if (!sybase || !sybase[0]) sybase = "/etc/freetds"; tdsdump_log(TDS_DBG_INFO1, "%L Looking for server in %s/interfaces.\n", sybase); founded = search_interface_file(connect_info, sybase, "interfaces", server); } /* * If we still don't have the server and port then assume the user * typed an actual server name. */ if (!founded) { char ip_addr[255]; int ip_port; const char *env_port; /* * Make a guess about the port number */ #ifdef TDS50 ip_port = 4000; #else ip_port = 1433; #endif if ((env_port = getenv("TDSPORT")) != NULL) { ip_port = tds_lookup_port(env_port); tdsdump_log(TDS_DBG_INFO1, "%L Setting 'ip_port' to %s from $TDSPORT.\n", env_port); } else tdsdump_log(TDS_DBG_INFO1, "%L Setting 'ip_port' to %d as a guess.\n", ip_port); /* * lookup the host */ tds_lookup_host(server, ip_addr); if (ip_addr[0]) tds_dstr_copy(&connect_info->ip_addr, ip_addr); if (ip_port) connect_info->port = ip_port; } }
/** * 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() */
/** * Read connection information from given DSN * @param DSN DSN name * @param connect_info where to store connection info * @return 1 if success 0 otherwhise */ int odbc_get_dsn_info(const char *DSN, TDSCONNECTINFO * connect_info) { char tmp[FILENAME_MAX]; int freetds_conf_less = 1; int address_specified = 0; /* use old servername */ tmp[0] = '\0'; if (SQLGetPrivateProfileString(DSN, "Servername", "", tmp, FILENAME_MAX, "odbc.ini") > 0) { freetds_conf_less = 0; tds_read_conf_file(connect_info, tmp); } /* search for server (compatible with ms one) */ if (freetds_conf_less) { tmp[0] = '\0'; if (SQLGetPrivateProfileString(DSN, "Address", "", tmp, FILENAME_MAX, "odbc.ini") > 0) { address_specified = 1; /* TODO parse like MS */ tds_lookup_host(tmp, tmp); tds_dstr_copy(&connect_info->ip_addr, tmp); } tmp[0] = '\0'; if (SQLGetPrivateProfileString(DSN, "Server", "", tmp, FILENAME_MAX, "odbc.ini") > 0) { tds_dstr_copy(&connect_info->server_name, tmp); if (!address_specified) { tds_lookup_host(tds_dstr_cstr(&connect_info->server_name), tmp); tds_dstr_copy(&connect_info->ip_addr, tmp); } } } tmp[0] = '\0'; if (SQLGetPrivateProfileString(DSN, "Port", "", tmp, FILENAME_MAX, "odbc.ini") > 0) { connect_info->port = atoi(tmp); } tmp[0] = '\0'; if (SQLGetPrivateProfileString(DSN, "TDS_Version", "", tmp, FILENAME_MAX, "odbc.ini") > 0) { tds_config_verstr(tmp, connect_info); } tmp[0] = '\0'; if (SQLGetPrivateProfileString(DSN, "Language", "", tmp, FILENAME_MAX, "odbc.ini") > 0) { tds_dstr_copy(&connect_info->language, tmp); } tmp[0] = '\0'; if (SQLGetPrivateProfileString(DSN, "Database", "", tmp, FILENAME_MAX, "odbc.ini") > 0) { tds_dstr_copy(&connect_info->database, tmp); } #if 0 tmp[0] = '\0'; if (SQLGetPrivateProfileString(DSN, "Authentication", "Server", tmp, FILENAME_MAX, "odbc.ini") > 0) { if (!strcasecmp(tmp, "Server")) { connect_info->try_domain_login = 0; connect_info->try_server_login = 1; } else if (!strcasecmp(tmp, "Domain")) { connect_info->try_domain_login = 1; connect_info->try_server_login = 0; } else if (!strcasecmp(tmp, "Both")) { connect_info->try_server_login = 1; connect_info->try_domain_login = 1; } else { /* default to server authentication */ connect_info->try_domain_login = 0; connect_info->try_server_login = 1; } } #endif tmp[0] = '\0'; if (SQLGetPrivateProfileString(DSN, "Domain", "", tmp, FILENAME_MAX, "odbc.ini") > 0) { tds_dstr_copy(&connect_info->default_domain, tmp); } tmp[0] = '\0'; if (SQLGetPrivateProfileString(DSN, "TextSize", "", tmp, FILENAME_MAX, "odbc.ini") > 0) { connect_info->text_size = atoi(tmp); } tmp[0] = '\0'; if (SQLGetPrivateProfileString(DSN, "PacketSize", "", tmp, FILENAME_MAX, "odbc.ini") > 0) { connect_info->block_size = atoi(tmp); } return 1; }
/* Also used to scan ODBC.INI entries */ void tds_parse_conf_section(const char *option, const char *value, void *param) { TDSLOGIN *login = (TDSLOGIN *) param; void *s = param; tdsdump_log(TDS_DBG_INFO1, "\t%s = '%s'\n", option, value); if (!strcmp(option, TDS_STR_VERSION)) { tds_config_verstr(value, login); } else if (!strcmp(option, TDS_STR_BLKSZ)) { int val = atoi(value); if (val >= 512 && val < 65536) login->block_size = val; } else if (!strcmp(option, TDS_STR_SWAPDT)) { /* this option is deprecated, just check value for compatibility */ tds_config_boolean(option, value, login); } else if (!strcmp(option, TDS_GSSAPI_DELEGATION)) { /* gssapi flag addition */ login->gssapi_use_delegation = tds_config_boolean(option, value, login); } else if (!strcmp(option, TDS_STR_DUMPFILE)) { s = tds_dstr_copy(&login->dump_file, value); } else if (!strcmp(option, TDS_STR_DEBUGFLAGS)) { char *end; long flags; flags = strtol(value, &end, 0); if (*value != '\0' && *end == '\0' && flags != LONG_MIN && flags != LONG_MAX) login->debug_flags = flags; } else if (!strcmp(option, TDS_STR_TIMEOUT) || !strcmp(option, TDS_STR_QUERY_TIMEOUT)) { if (atoi(value)) login->query_timeout = atoi(value); } else if (!strcmp(option, TDS_STR_CONNTIMEOUT)) { if (atoi(value)) login->connect_timeout = atoi(value); } else if (!strcmp(option, TDS_STR_HOST)) { char tmp[128]; struct addrinfo *addrs; if (TDS_FAILED(tds_lookup_host_set(value, &login->ip_addrs))) { tdsdump_log(TDS_DBG_WARN, "Found host entry %s however name resolution failed. \n", value); return; } tdsdump_log(TDS_DBG_INFO1, "Found host entry %s \n", value); s = tds_dstr_copy(&login->server_host_name, value); for (addrs = login->ip_addrs; addrs != NULL; addrs = addrs->ai_next) tdsdump_log(TDS_DBG_INFO1, "IP addr is %s.\n", tds_addrinfo2str(addrs, tmp, sizeof(tmp))); } else if (!strcmp(option, TDS_STR_PORT)) { if (atoi(value)) login->port = atoi(value); } else if (!strcmp(option, TDS_STR_EMUL_LE)) { login->emul_little_endian = tds_config_boolean(option, value, login); } else if (!strcmp(option, TDS_STR_TEXTSZ)) { if (atoi(value)) login->text_size = atoi(value); } else if (!strcmp(option, TDS_STR_CHARSET)) { s = tds_dstr_copy(&login->server_charset, value); tdsdump_log(TDS_DBG_INFO1, "%s is %s.\n", option, tds_dstr_cstr(&login->server_charset)); } else if (!strcmp(option, TDS_STR_CLCHARSET)) { s = tds_dstr_copy(&login->client_charset, value); tdsdump_log(TDS_DBG_INFO1, "tds_parse_conf_section: %s is %s.\n", option, tds_dstr_cstr(&login->client_charset)); } else if (!strcmp(option, TDS_STR_USE_UTF_16)) { login->use_utf16 = tds_config_boolean(option, value, login); } else if (!strcmp(option, TDS_STR_LANGUAGE)) { s = tds_dstr_copy(&login->language, value); } else if (!strcmp(option, TDS_STR_APPENDMODE)) { tds_g_append_mode = tds_config_boolean(option, value, login); } else if (!strcmp(option, TDS_STR_INSTANCE)) { s = tds_dstr_copy(&login->instance_name, value); } else if (!strcmp(option, TDS_STR_ENCRYPTION)) { tds_config_encryption(value, login); } else if (!strcmp(option, TDS_STR_ASA_DATABASE)) { s = tds_dstr_copy(&login->server_name, value); } else if (!strcmp(option, TDS_STR_USENTLMV2)) { login->use_ntlmv2 = tds_config_boolean(option, value, login); } else if (!strcmp(option, TDS_STR_USELANMAN)) { login->use_lanman = tds_config_boolean(option, value, login); } else if (!strcmp(option, TDS_STR_REALM)) { s = tds_dstr_copy(&login->server_realm_name, value); } else if (!strcmp(option, TDS_STR_SPN)) { s = tds_dstr_copy(&login->server_spn, value); } else if (!strcmp(option, TDS_STR_CAFILE)) { s = tds_dstr_copy(&login->cafile, value); } else if (!strcmp(option, TDS_STR_CRLFILE)) { s = tds_dstr_copy(&login->crlfile, value); } else if (!strcmp(option, TDS_STR_CHECKSSLHOSTNAME)) { login->check_ssl_hostname = tds_config_boolean(option, value, login); } else if (!strcmp(option, TDS_STR_DBFILENAME)) { s = tds_dstr_copy(&login->db_filename, value); } else if (!strcmp(option, TDS_STR_DATABASE)) { s = tds_dstr_copy(&login->database, value); } else if (!strcmp(option, TDS_STR_READONLY_INTENT)) { login->readonly_intent = tds_config_boolean(option, value, login); tdsdump_log(TDS_DBG_FUNC, "Setting ReadOnly Intent to '%s'.\n", value); } else { tdsdump_log(TDS_DBG_INFO1, "UNRECOGNIZED option '%s' ... ignoring.\n", option); } if (!s) login->valid_configuration = 0; }
/** * Callback function for the DSN Configuration dialog * \param hDlg identifies the dialog * \param message what happened to the dialog * \param wParam varies with message * \param lParam pointer to TDSLOGIN struct */ static BOOL CALLBACK LoginDlgProc(HWND hDlg, UINT message, WPARAM wParam, /* */ LPARAM lParam) { TDSLOGIN *login; char tmp[100]; switch (message) { case WM_INITDIALOG: /* lParam points to the TDSLOGIN */ login = (TDSLOGIN *) lParam; SetWindowUserData(hDlg, lParam); /* copy info from TDSLOGIN to the dialog */ SendDlgItemMessage(hDlg, IDC_LOGINSERVER, WM_SETTEXT, 0, (LPARAM) tds_dstr_cstr(&login->server_name)); SendDlgItemMessage(hDlg, IDC_LOGINUID, WM_SETTEXT, 0, (LPARAM) tds_dstr_cstr(&login->user_name)); SendDlgItemMessage(hDlg, IDC_LOGINUID, EM_LIMITTEXT, sizeof(tmp) - 1, 0); SendDlgItemMessage(hDlg, IDC_LOGINPWD, WM_SETTEXT, 0, (LPARAM) tds_dstr_cstr(&login->password)); SendDlgItemMessage(hDlg, IDC_LOGINPWD, EM_LIMITTEXT, sizeof(tmp) - 1, 0); SendDlgItemMessage(hDlg, IDC_LOGINDUMP, BM_SETCHECK, !tds_dstr_isempty(&login->dump_file), 0L); /* adjust label of logging checkbox */ SendDlgItemMessage(hDlg, IDC_LOGINDUMP, WM_SETTEXT, 0, (LPARAM) "\"FreeTDS.log\" on desktop"); return TRUE; case WM_COMMAND: /* Dialog's user data points to TDSLOGIN */ login = (TDSLOGIN *) GetWindowUserData(hDlg); /* The wParam indicates which button was pressed */ if (LOWORD(wParam) == IDCANCEL) { EndDialog(hDlg, FALSE); return TRUE; } else if (LOWORD(wParam) != IDOK) { /* Anything but IDCANCEL or IDOK is handled elsewhere */ break; } /* If we get here, then the user hit the [OK] button */ /* get values from dialog */ SendDlgItemMessage(hDlg, IDC_LOGINUID, WM_GETTEXT, sizeof tmp, (LPARAM) tmp); tds_dstr_copy(&login->user_name, tmp); SendDlgItemMessage(hDlg, IDC_LOGINPWD, WM_GETTEXT, sizeof tmp, (LPARAM) tmp); tds_dstr_copy(&login->password, tmp); if (SendDlgItemMessage(hDlg, IDC_LOGINDUMP, BM_GETCHECK, 0, 0)) { char * filename = get_desktop_file("FreeTDS.log"); if (filename) { tds_dstr_copy(&login->dump_file, filename); free(filename); } } else { tds_dstr_copy(&login->dump_file, ""); } /* And we're done */ EndDialog(hDlg, TRUE); return TRUE; } return FALSE; }