📄 connectparams.c
字号:
/* FreeTDS - Library of routines accessing Sybase and Microsoft databases * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Brian Bruns * Copyright (C) 2005 Frediano Ziglio * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */#if HAVE_CONFIG_H#include <config.h>#endif#include <stdarg.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include <sys/stat.h>#include "tdsodbc.h"#include "tdsstring.h"#include "replacements.h"#ifdef DMALLOC#include <dmalloc.h>#endifTDS_RCSID(var, "$Id: connectparams.c,v 1.72 2007/07/01 10:10:52 freddy77 Exp $");#if !HAVE_SQLGETPRIVATEPROFILESTRING/* * Last resort place to check for INI file. This is usually set at compile time * by build scripts. */#ifndef SYS_ODBC_INI#define SYS_ODBC_INI "/etc/odbc.ini"#endif/** * Call this to get the INI file containing Data Source Names. * @note rules for determining the location of ODBC config may be different * then what you expect - at this time they differ from unixODBC * * @return file opened or NULL if error * @retval 1 worked */static FILE *tdoGetIniFileName(void);/** * SQLGetPrivateProfileString * * PURPOSE * * This is an implementation of a common MS API call. This implementation * should only be used if the ODBC sub-system/SDK does not have it. * For example; unixODBC has its own so those using unixODBC should NOT be * using this implementation because unixODBC; * - provides caching of ODBC config data * - provides consistent interpretation of ODBC config data (i.e, location) * * ARGS * * see ODBC documentation * * RETURNS * * see ODBC documentation * * NOTES: * * - the spec is not entirely implemented... consider this a lite version * - rules for determining the location of ODBC config may be different then what you * expect see tdoGetIniFileName(). * */static int SQLGetPrivateProfileString(LPCSTR pszSection, LPCSTR pszEntry, LPCSTR pszDefault, LPSTR pRetBuffer, int nRetBuffer, LPCSTR pszFileName);#endif#if defined(FILENAME_MAX) && FILENAME_MAX < 512#undef FILENAME_MAX#define FILENAME_MAX 512#endifstatic intparse_server(char *server, TDSCONNECTION * connection){ char ip[64]; char *p = (char *) strchr(server, '\\'); if (p) { if (!tds_dstr_copy(&connection->instance_name, p+1)) return 0; *p = 0; } tds_lookup_host(server, ip); if (!tds_dstr_copy(&connection->ip_addr, ip)) return 0; return 1;}/** * Read connection information from given DSN * @param DSN DSN name * @param connection where to store connection info * @return 1 if success 0 otherwhise */intodbc_get_dsn_info(const char *DSN, TDSCONNECTION * connection){ 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_dstr_copy(&connection->server_name, tmp); tds_read_conf_file(connection, 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(&connection->ip_addr, tmp); } tmp[0] = '\0'; if (SQLGetPrivateProfileString(DSN, "Server", "", tmp, FILENAME_MAX, "odbc.ini") > 0) { tds_dstr_copy(&connection->server_name, tmp); if (!address_specified) { if (!parse_server(tmp, connection)) return 0; } } } tmp[0] = '\0'; if (SQLGetPrivateProfileString(DSN, "Port", "", tmp, FILENAME_MAX, "odbc.ini") > 0) { connection->port = atoi(tmp); } tmp[0] = '\0'; if (SQLGetPrivateProfileString(DSN, "TDS_Version", "", tmp, FILENAME_MAX, "odbc.ini") > 0) { tds_config_verstr(tmp, connection); } tmp[0] = '\0'; if (SQLGetPrivateProfileString(DSN, "Language", "", tmp, FILENAME_MAX, "odbc.ini") > 0) { tds_dstr_copy(&connection->language, tmp); } tmp[0] = '\0'; if (tds_dstr_isempty(&connection->database) && SQLGetPrivateProfileString(DSN, "Database", "", tmp, FILENAME_MAX, "odbc.ini") > 0) tds_dstr_copy(&connection->database, tmp); tmp[0] = '\0'; if (SQLGetPrivateProfileString(DSN, "TextSize", "", tmp, FILENAME_MAX, "odbc.ini") > 0) { connection->text_size = atoi(tmp); } tmp[0] = '\0'; if (SQLGetPrivateProfileString(DSN, "PacketSize", "", tmp, FILENAME_MAX, "odbc.ini") > 0) { connection->block_size = atoi(tmp); } return 1;}/** * Parse connection string and fill connection according * @param connect_string connect string * @param connect_string_end connect string end (pointer to char past last) * @param connection where to store connection info * @return 1 if success 0 otherwhise */intodbc_parse_connect_string(const char *connect_string, const char *connect_string_end, TDSCONNECTION * connection){ const char *p, *end; DSTR *dest_s, value; int reparse = 0; /* flag for indicate second parse of string */ char option[16]; 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 or DSN specified */ if (!reparse) { dest_s = &connection->server_name; /* not that safe cast but works -- freddy77 */ if (!parse_server((char *) tds_dstr_cstr(&value), connection)) { tds_dstr_free(&value); return 0; } } } else if (strcasecmp(option, "SERVERNAME") == 0) { if (!reparse) { tds_dstr_dup(&connection->server_name, &value); tds_read_conf_file(connection, 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), connection); reparse = 1; p = connect_string; continue; } } else if (strcasecmp(option, "DATABASE") == 0) { dest_s = &connection->database; } else if (strcasecmp(option, "UID") == 0) { dest_s = &connection->user_name; } else if (strcasecmp(option, "PWD") == 0) { dest_s = &connection->password; } else if (strcasecmp(option, "APP") == 0) { dest_s = &connection->app_name; } else if (strcasecmp(option, "WSID") == 0) { dest_s = &connection->client_host_name; } else if (strcasecmp(option, "LANGUAGE") == 0) { dest_s = &connection->language; } else if (strcasecmp(option, "Port") == 0) { connection->port = atoi(tds_dstr_cstr(&value)); } else if (strcasecmp(option, "TDS_Version") == 0) { tds_config_verstr(tds_dstr_cstr(&value), connection); } else if (strcasecmp(option, "TextSize") == 0) { connection->text_size = atoi(tds_dstr_cstr(&value)); } else if (strcasecmp(option, "PacketSize") == 0) { connection->block_size = atoi(tds_dstr_cstr(&value)); /* TODO "Address" field */ } /* copy to destination */ if (dest_s) { DSTR tmp = *dest_s; *dest_s = value; value = tmp; } p = end; /* handle "" ";.." "};.." cases */ if (p >= connect_string_end) break; if (*p == '}') ++p; ++p; } tds_dstr_free(&value); return p != NULL;}#if !HAVE_SQLGETPRIVATEPROFILESTRING
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -