⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sql.c

📁 此dns服务器是在mydns基础上改写
💻 C
字号:
/**************************************************************************************************	$Id: sql.c,v 1.22 2005/04/20 16:40:25 bboy Exp $	Copyright (C) 2002-2005  Don Moore <bboy@bboy.net>	This program is free software; you can redistribute it and/or modify	it under the terms of the GNU General Public License as published by	the Free Software Foundation; either version 2 of the License, or	(at Your option) any later version.	This program 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 General Public License for more details.	You should have received a copy of the GNU General Public License	along with this program; if not, write to the Free Software	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA**************************************************************************************************/#include "mydns.h"SQL *sql;															/* Global SQL connection information *//* Saved connection information for reconnecting */static char *_sql_user = NULL;static char *_sql_password = NULL;static char *_sql_host = NULL;static char *_sql_database = NULL;/**************************************************************************************************	SQL_OPEN	Connect to the database.  Errors fatal.**************************************************************************************************/voidsql_open(char *user, char *password, char *host, char *database){	char *portp = NULL;	unsigned int port = 0;	if (host && (portp = strchr(host, ':')))	{		port = atoi(portp + 1);		*portp = '\0';	}	/* Save connection information so that we can reconnect if necessary */	if (_sql_user) Free(_sql_user);	if (_sql_password) Free(_sql_password);	if (_sql_host) Free(_sql_host);	if (_sql_database) Free(_sql_database);	_sql_user = user ? strdup(user) : NULL;	_sql_password = password ? strdup(password) : NULL;	_sql_host = host ? strdup(host) : NULL;	_sql_database = database ? strdup(database) : NULL;#if USE_PGSQL	sql = PQsetdbLogin(host, portp, NULL, NULL, database, user, password);	if (PQstatus(sql) == CONNECTION_BAD)	{		char *errmsg = PQerrorMessage(sql), *c, out[512];		/* Save the first error message so that the user gets the error message they "expect" */		for (c = errmsg; *c; c++)			if (*c == '\r' || *c == '\n')				*c = ' ';		strtrim(errmsg);		snprintf(out, sizeof(out), "%s %s: %s (errno=%d)",					_("Error connecting to PostgreSQL server at"), host, errmsg, errno);		if (sql)			PQfinish(sql);		/* Try login via UNIX socket before failing, per Lee Brotherston <lee@nerds.org.uk> */		sql = PQsetdbLogin(NULL, NULL, NULL, NULL, database, user, password);		if (PQstatus(sql) == CONNECTION_BAD)			Errx("%s", out);	}#else	sql = NULL;	if (!(sql = mysql_init(NULL)))		Err(_("Unable to allocate MySQL data structure"));#if MYSQL_VERSION_ID > 32349	mysql_options(sql, MYSQL_READ_DEFAULT_GROUP, "client");#endif	if (!(mysql_real_connect(sql, host, user, password, database, port, NULL, 0)))		ErrSQL(sql, _("Error connecting to MySQL server at %s"), host);#endif	if (portp)		*portp = ':';}/*--- sql_open() --------------------------------------------------------------------------------*//**************************************************************************************************	SQL_REOPEN	Attempt to close and reopen the database connection.**************************************************************************************************/voidsql_reopen(void){	SQL *new_sql = NULL;	char *portp = NULL;	unsigned int port = 0;	if (_sql_host && (portp = strchr(_sql_host, ':')))	{		port = atoi(portp + 1);		*portp = '\0';	}#if USE_PGSQL	new_sql = PQsetdbLogin(_sql_host, portp, NULL, NULL, _sql_database, _sql_user, _sql_password);	if (PQstatus(new_sql) == CONNECTION_BAD)	{		if (new_sql)			PQfinish(new_sql);		/* Try login via UNIX socket before failing, per Lee Brotherston <lee@nerds.org.uk> */		new_sql = PQsetdbLogin(NULL, NULL, NULL, NULL, _sql_database, _sql_user, _sql_password);		if (PQstatus(new_sql) == CONNECTION_BAD)		{			if (new_sql)				PQfinish(new_sql);			return;		}	}#else	if (!(new_sql = mysql_init(NULL)))		return;#if MYSQL_VERSION_ID > 32349	mysql_options(new_sql, MYSQL_READ_DEFAULT_GROUP, "client");#endif	if (!(mysql_real_connect(new_sql, _sql_host, _sql_user, _sql_password, _sql_database, port, NULL, 0)))	{		mysql_close(new_sql);		return;	}#endif	sql_close(sql);	sql = new_sql;	if (portp)		*portp = ':';}/*--- sql_reopen() ------------------------------------------------------------------------------*//**************************************************************************************************	SQL_ISTABLE	Returns 1 if the specified table exists in the current database, or 0 if it does not.**************************************************************************************************/intsql_istable(SQL *sqlConn, const char *tablename){	unsigned char *xtablename;#if !USE_PGSQL	SQL_RES *res;#endif	int rv = 0;	if (!(xtablename = calloc(strlen(tablename) * 2 + 1, sizeof(unsigned char))))		Err(_("out of memory"));	sql_escstr(sqlConn, xtablename, (uchar *)tablename, strlen(tablename));#if USE_PGSQL	if (sql_count(sqlConn, "SELECT COUNT(*) FROM pg_class"		 " WHERE (relkind='r' OR relkind='v') AND relname='%s'", xtablename) > 0)		rv = 1;#else	if ((res = sql_queryf(sqlConn, "SHOW TABLES LIKE '%s'", xtablename)))	{		if (sql_num_rows(res) > 0)			rv = 1;		sql_free(res);	}#endif	Free(xtablename);	return (rv);}/*--- sql_istable() -----------------------------------------------------------------------------*//**************************************************************************************************	SQL_ISCOLUMN	Returns 1 if the specified column exists in the current database, or 0 if it does not.**************************************************************************************************/intsql_iscolumn(SQL *sqlConn, const char *tablename, const char *columnname){	unsigned char *xtablename, *xcolumnname;#if !USE_PGSQL	SQL_RES *res;#endif	int rv = 0;	if (!(xtablename = calloc(strlen(tablename) * 2 + 1, sizeof(unsigned char))))		Err(_("out of memory"));	if (!(xcolumnname = calloc(strlen(columnname) * 2 + 1, sizeof(unsigned char))))		Err(_("out of memory"));	sql_escstr(sqlConn, xtablename, (uchar *)tablename, strlen(tablename));	sql_escstr(sqlConn, xcolumnname, (uchar *)columnname, strlen(columnname));#if USE_PGSQL	if (sql_count(sqlConn,			"SELECT COUNT(*)"			" FROM pg_class,pg_attribute"			" WHERE (relkind='r' OR relkind='v')"			" AND relname='%s'"			" AND attrelid=oid"			" AND attname='%s'", xtablename, xcolumnname) > 0)		rv = 1;#else	if ((res = sql_queryf(sqlConn, "SHOW COLUMNS FROM %s LIKE '%s'", xtablename, xcolumnname)))	{		if (sql_num_rows(res) > 0)			rv = 1;		sql_free(res);	}#endif	Free(xtablename);	Free(xcolumnname);	return (rv);}/*--- sql_iscolumn() ----------------------------------------------------------------------------*//**************************************************************************************************	_SQL_CLOSE**************************************************************************************************/void_sql_close(SQL *sqlConn){#if USE_PGSQL	PQfinish(sqlConn);#else	mysql_close(sqlConn);#endif}/*--- _sql_close() ------------------------------------------------------------------------------*//**************************************************************************************************	SQL_NRQUERY	Issues an SQL query that does not return a result.  Returns 0 on success, -1 on error.**************************************************************************************************/intsql_nrquery(SQL *sqlConn, const char *query, size_t querylen){#if USE_PGSQL	{		ExecStatusType q_rv = PGRES_COMMAND_OK;		PGresult *result = NULL;		result = PQexec(sqlConn, query);		q_rv = PQresultStatus(result);		if (q_rv == PGRES_COMMAND_OK)		{			PQclear(result);			return (0);		}		else		{			/* WarnSQL(sqlConn, _("%s: error during query"), PQresStatus(PQresultStatus(result))); */			PQclear(result);			return (-1);		}	}#else	if (mysql_real_query(sqlConn, query, querylen))		return (-1);#endif	return (0);}/*--- sql_nrquery() -----------------------------------------------------------------------------*//**************************************************************************************************	SQL_QUERY	Returns a query's result, or NULL on error.**************************************************************************************************/SQL_RES *sql_query(SQL *sqlConn, const char *query, size_t querylen){	SQL_RES *res = NULL;#if USE_PGSQL	{		ExecStatusType q_rv = PGRES_COMMAND_OK;		PGresult *result = NULL;		result = PQexec(sqlConn, query);		q_rv = PQresultStatus(result);		if (q_rv == PGRES_TUPLES_OK)		{			if (!(res = malloc(sizeof(SQL_RES))))			{				PQclear(result);				return (NULL);			}			res->result = result;			res->tuples = PQntuples(result);			res->fields = PQnfields(result);			res->current_tuple = 0;			if (!(res->current_row = malloc(res->fields * sizeof(unsigned char *))))			{				Free(res);				PQclear(result);				return (NULL);			}		}		else if (q_rv == PGRES_COMMAND_OK)		{			PQclear(result);			return (NULL);		}		else		{			/* WarnSQL(sqlConn, _("%s: error during query"), PQresStatus(PQresultStatus(result))); */			PQclear(result);			return (NULL);		}	}#else	if (mysql_real_query(sqlConn, query, querylen) || !(res = mysql_store_result(sqlConn)))		return (NULL);#endif	return (res);}/*--- sql_query() -------------------------------------------------------------------------------*//**************************************************************************************************	SQL_QUERYF	Like sql_query, but accepts varargs format.**************************************************************************************************/SQL_RES *sql_queryf(SQL *sqlConn, const char *fmt, ...){	va_list ap;	char buf[DNS_QUERYBUFSIZ];	size_t buflen;	va_start(ap, fmt);	buflen = vsnprintf(buf, sizeof(buf), fmt, ap);	va_end(ap);	return sql_query(sqlConn, buf, buflen);}/*--- sql_queryf() ------------------------------------------------------------------------------*//**************************************************************************************************	SQL_COUNT	Provided a statement like "SELECT COUNT(*)..." returns the count returned, or -1 if an error	occurred.**************************************************************************************************/longsql_count(SQL *sqlConn, const char *fmt, ...){	va_list ap;	char buf[DNS_QUERYBUFSIZ];	size_t buflen;	SQL_RES *res = NULL;	long rv = 0;	va_start(ap, fmt);	buflen = vsnprintf(buf, sizeof(buf), fmt, ap);	va_end(ap);	if (!(res = sql_query(sqlConn, buf, buflen)))		return (-1);	if (sql_num_rows(res))#if USE_PGSQL		rv = atol(PQgetvalue(res->result, 0, 0));#else	{		MYSQL_ROW row;		if ((row = mysql_fetch_row(res)))			rv = atol(row[0]);	}#endif	sql_free(res);	return (rv);}/*--- sql_count() -------------------------------------------------------------------------------*//**************************************************************************************************	SQL_NUM_ROWS	Returns the number of rows in a result set.**************************************************************************************************/longsql_num_rows(SQL_RES *res){#if USE_PGSQL	return res->tuples;#else	return mysql_num_rows(res);#endif}/*--- sql_num_rows() ----------------------------------------------------------------------------*//**************************************************************************************************	SQL_GETROW	Returns the next row from the result, or NULL if no more rows exist.**************************************************************************************************/SQL_ROWsql_getrow(SQL_RES *res){#if USE_PGSQL	register int n;	if (res->current_tuple >= res->tuples)		return (NULL);	for (n = 0; n < res->fields; n++)		res->current_row[n] = PQgetvalue(res->result, res->current_tuple, n);	res->current_tuple++;	return (res->current_row);#else	return mysql_fetch_row(res);#endif}/*--- sql_getrow() ------------------------------------------------------------------------------*//**************************************************************************************************	SQL_ESCSTR	Escapes a string to make it suitable for an SQL query.**************************************************************************************************/voidsql_escstr(SQL *sqlConn, char *dest, char *src, size_t srclen){#if USE_PGSQL	PQescapeString(dest, src, srclen);#else	mysql_real_escape_string(sqlConn, dest, src, srclen);#endif}/*--- sql_escstr() ------------------------------------------------------------------------------*//**************************************************************************************************	_SQL_FREE	Free an SQL result.**************************************************************************************************/void_sql_free(SQL_RES *res){#if USE_PGSQL	Free(res->current_row);	PQclear(res->result);	Free(res);#else	mysql_free_result(res);#endif}/*--- _sql_free() -------------------------------------------------------------------------------*//* vi:set ts=3: */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -