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

📄 sql_sybase.c

📁 RADIUS认证协议
💻 C
📖 第 1 页 / 共 2 页
字号:
static int sql_select_query(SQLSOCK *sqlsocket, SQL_CONFIG *config, char *querystr) {	rlm_sql_sybase_sock *sybase_sock = sqlsocket->conn;	CS_RETCODE	ret, results_ret;	CS_INT		result_type;	CS_DATAFMT	descriptor;	int		colcount,i;	char		**rowdata;	if (config->sqltrace)		DEBUG(querystr);	 if (sybase_sock->connection == NULL) {		radlog(L_ERR, "Socket not connected");		return -1;	}	if (ct_cmd_alloc(sybase_sock->connection, &sybase_sock->command) != CS_SUCCEED) {		radlog(L_ERR,"rlm_sql_sybase(sql_select_query): Unable to allocate command structure (ct_cmd_alloc())\n%s",				sql_error(sqlsocket, config));		return -1;	}	if (ct_command(sybase_sock->command, CS_LANG_CMD, querystr, CS_NULLTERM, CS_UNUSED) != CS_SUCCEED) {		radlog(L_ERR,"rlm_sql_sybase(sql_select_query): Unable to initiate command structure (ct_command())\n%s",				sql_error(sqlsocket, config));		return -1;	}	if (ct_send(sybase_sock->command) != CS_SUCCEED) {		radlog(L_ERR,"rlm_sql_sybase(sql_select_query): Unable to send command (ct_send())\n%s",				sql_error(sqlsocket, config));		return -1;	}	results_ret = ct_results(sybase_sock->command, &result_type);	switch (results_ret) {	case CS_SUCCEED:		switch (result_type) {		case CS_ROW_RESULT:		/*		** Houston, we have a row.		**		** We set up a target buffer for the results data, and		** associate the buffer with the results, but the actual		** fetching takes place in sql_fetch_row. The layer above		** MUST call sql_fetch_row and/or sql_finish_select_query		** or this socket will be unusable and may cause segfaults		** if reused later on.		*/			/*			** Set up the DATAFMT structure that describes our target array			** and tells sybase what we want future ct_fetch calls to do.			*/			descriptor.datatype = CS_CHAR_TYPE; 	/* The target buffer is a string */			descriptor.format = CS_FMT_NULLTERM;	/* Null termination please */			descriptor.maxlength = MAX_DATASTR_LEN;	/* The string arrays are this large */			descriptor.count = 1;			/* Fetch one row of data */			descriptor.locale = NULL;		/* Don't do NLS stuff */			colcount = sql_num_fields(sqlsocket, config); /* Get number of elements in row result */			rowdata=(char **)rad_malloc(sizeof(char *) * (colcount+1));	/* Space for pointers */			memset(rowdata, 0, (sizeof(char *) * colcount+1));  /* NULL-pad the pointers */			for (i=0; i < colcount; i++) {                        	rowdata[i]=rad_malloc((MAX_DATASTR_LEN * sizeof(char))+1); /* Space to hold the result data */				/* Associate the target buffer with the data */				if (ct_bind(sybase_sock->command, i+1, &descriptor, rowdata[i], NULL, NULL) != CS_SUCCEED) {					radlog(L_ERR,"rlm_sql_sybase(sql_select_query): ct_bind() failed)\n%s",							sql_error(sqlsocket, config));					return -1;				}			}			rowdata[i]=NULL; /* Terminate the array */			sybase_sock->results=rowdata;			break;		case CS_CMD_SUCCEED:		case CS_CMD_DONE:			radlog(L_ERR,"rlm_sql_sybase(sql_select_query): Query returned no data");			break;		default:			radlog(L_ERR,"rlm_sql_sybase(sql_select_query): Unexpected result type from query\n%s",					 sql_error(sqlsocket, config));			sql_finish_select_query(sqlsocket, config);			return -1;			break;		}		break;	case CS_FAIL:		/*		** Serious failure, sybase requires us to cancel		** the results and maybe even close the connection.		*/		radlog(L_ERR,"rlm_sql_sybase(sql_select_query): Failure retrieving query results\n%s"				, sql_error(sqlsocket, config));		if ((ret = ct_cancel(NULL, sybase_sock->command, CS_CANCEL_ALL)) == CS_FAIL) {			radlog(L_ERR,"rlm_sql_sybase(sql_select_query): cleaning up.");			ct_close(sybase_sock->connection, CS_FORCE_CLOSE);			sql_close(sqlsocket, config);		}		return -1;		break;	default:		radlog(L_ERR,"rlm_sql_sybase(sql_select_query): Unexpected return value from ct_results()\n%s",				sql_error(sqlsocket, config));		return -1;		break;	}	return 0;}/************************************************************************* * *	Function: sql_store_result * *	Purpose: database specific store_result function. Returns a result *               set for the query. * *************************************************************************/static int sql_store_result(SQLSOCK *sqlsocket, SQL_CONFIG *config) {	/*	** Not needed for Sybase, code that may have gone here is	** in sql_select_query and sql_fetch_row	*/	return 0;}/************************************************************************* * *	Function: sql_num_fields * *	Purpose: database specific num_fields function. Returns number *               of columns from query * *************************************************************************/static int sql_num_fields(SQLSOCK *sqlsocket, SQL_CONFIG *config) {	rlm_sql_sybase_sock *sybase_sock = sqlsocket->conn;	int	num;	if (ct_res_info(sybase_sock->command, CS_NUMDATA, (CS_INT *)&num, CS_UNUSED, NULL) != CS_SUCCEED) {		radlog(L_ERR,"rlm_sql_sybase(sql_num_fields): error retrieving column count: %s",			sql_error(sqlsocket, config));		return -1;	}	return num;}/************************************************************************* * *	Function: sql_num_rows * *	Purpose: database specific num_rows. Returns number of rows in *               query * *************************************************************************/static int sql_num_rows(SQLSOCK *sqlsocket, SQL_CONFIG *config) {	rlm_sql_sybase_sock *sybase_sock = sqlsocket->conn;	int	num;	if (ct_res_info(sybase_sock->command, CS_ROW_COUNT, (CS_INT *)&num, CS_UNUSED, NULL) != CS_SUCCEED) {		radlog(L_ERR,"rlm_sql_sybase(sql_num_rows): error retrieving row count: %s",			sql_error(sqlsocket, config));		return -1;	}	return num;}/************************************************************************* * *	Function: sql_fetch_row * *	Purpose: database specific fetch_row. Returns a SQL_ROW struct *               with all the data for the query in 'sqlsocket->row'. Returns *		 0 on success, -1 on failure, SQL_DOWN if 'database is down'. * *************************************************************************/int sql_fetch_row(SQLSOCK *sqlsocket, SQL_CONFIG *config) {	rlm_sql_sybase_sock *sybase_sock = sqlsocket->conn;	CS_INT		ret, count;	sqlsocket->row = NULL;	ret = ct_fetch(sybase_sock->command, CS_UNUSED, CS_UNUSED, CS_UNUSED, &count);	switch (ret) {	case CS_FAIL:		/*		** Serious failure, sybase requires us to cancel		** the results and maybe even close the connection.		*/		radlog(L_ERR,"rlm_sql_sybase(sql_fetch_row): Failure fething row data\n%s"				, sql_error(sqlsocket, config));		if ((ret = ct_cancel(NULL, sybase_sock->command, CS_CANCEL_ALL)) == CS_FAIL) {			radlog(L_ERR,"rlm_sql_sybase(sql_fetch_row): cleaning up.");			ct_close(sybase_sock->connection, CS_FORCE_CLOSE);			sql_close(sqlsocket, config);		}		return SQL_DOWN;		break;	case CS_END_DATA:		return 0;		break;	case CS_SUCCEED:		sqlsocket->row = sybase_sock->results;		return 0;		break;	case CS_ROW_FAIL:		radlog(L_ERR,"rlm_sql_sybase(sql_fetch_row): Recoverable failure fething row data, try again perhaps?");		return -1;	default:		radlog(L_ERR,"rlm_sql_sybase(sql_fetch_row): Unexpected returncode from ct_fetch");		return -1;		break;	}}/************************************************************************* * *	Function: sql_free_result * *	Purpose: database specific free_result. Frees memory allocated *               for a result set * *************************************************************************/static int sql_free_result(SQLSOCK *sqlsocket, SQL_CONFIG *config) {	/*	** Not implemented, never called from rlm_sql anyway	** result buffer is freed in the finish_query functions.	*/	return 0;}/************************************************************************* * *	Function: sql_error * *	Purpose: database specific error. Returns error associated with *               connection * *************************************************************************/static char *sql_error(SQLSOCK *sqlsocket, SQL_CONFIG *config) {	static char	msg='\0';/*	static char	msgbuf[2048];	rlm_sql_sybase_sock *sybase_sock = sqlsocket->conn;	CS_INT		msgcount;	CS_CLIENTMSG	cmsg;	CS_SERVERMSG	smsg;	int		i;	char		ctempbuf[2][512];	char		stempbuf[2][512];	msgbuf[0]=(char)NULL;	ctempbuf[0][0]=(char)NULL;	ctempbuf[1][0]=(char)NULL;	stempbuf[0][0]=(char)NULL;	stempbuf[1][0]=(char)NULL;	if (ct_diag(sybase_sock->connection, CS_STATUS, CS_CLIENTMSG_TYPE, CS_UNUSED, &msgcount) != CS_SUCCEED) {		radlog(L_ERR,"rlm_sql_sybase(sql_error): Failed to get number of pending Client messages");		return msgbuf;	}	radlog(L_ERR,"rlm_sql_sybase(sql_error): Number of pending Client messages: %d", (int)msgcount);	for (i=1; i<=msgcount; i++) {		if (ct_diag(sybase_sock->connection, CS_GET, CS_CLIENTMSG_TYPE, (CS_INT)i, &cmsg) != CS_SUCCEED) {			radlog(L_ERR,"rlm_sql_sybase(sql_error): Failed to retrieve pending Client message");			return msgbuf;		}		sprintf(ctempbuf[i-1],"rlm_sql_sybase: Client Library Error: severity(%ld) number(%ld) origin(%ld) layer(%ld):\n%s",				(long)CS_SEVERITY(cmsg.severity),				(long)CS_NUMBER(cmsg.msgnumber),				(long)CS_ORIGIN(cmsg.msgnumber),				(long)CS_LAYER(cmsg.msgnumber),				cmsg.msgstring);	}	if (ct_diag(sybase_sock->connection, CS_STATUS, CS_SERVERMSG_TYPE, CS_UNUSED, &msgcount) != CS_SUCCEED) {		radlog(L_ERR,"rlm_sql_sybase(sql_error): Failed to get number of pending Server messages");		return msgbuf;	}	radlog(L_ERR,"rlm_sql_sybase(sql_error): Number of pending Server messages: %d", (int)msgcount);	for (i=1; i<=msgcount; i++) {		if (ct_diag(sybase_sock->connection, CS_GET, CS_SERVERMSG_TYPE, (CS_INT)i, &smsg) != CS_SUCCEED) {			radlog(L_ERR,"rlm_sql_sybase(sql_error): Failed to retrieve pending Server message");			return msgbuf;		}		sprintf(stempbuf[i-1],"rlm_sql_sybase: Server message: severity(%ld) number(%ld) origin(%ld) layer(%ld):\n%s",				(long)CS_SEVERITY(cmsg.severity),				(long)CS_NUMBER(cmsg.msgnumber),				(long)CS_ORIGIN(cmsg.msgnumber),				(long)CS_LAYER(cmsg.msgnumber),				cmsg.msgstring);	}	sprintf(msgbuf,"%s || %s || %s || %s", ctempbuf[1], ctempbuf[2], stempbuf[1], stempbuf[2]);	return msgbuf;*/	return &msg;}/************************************************************************* * *	Function: sql_close * *	Purpose: database specific close. Closes an open database *               connection and cleans up any open handles. * *************************************************************************/static int sql_close(SQLSOCK *sqlsocket, SQL_CONFIG *config) {/*	rlm_sql_oracle_sock *oracle_sock = sqlsocket->conn;	if (oracle_sock->conn) {		OCILogoff (oracle_sock->conn, oracle_sock->errHandle);	}	if (oracle_sock->queryHandle) {		OCIHandleFree((dvoid *)oracle_sock->queryHandle, (ub4) OCI_HTYPE_STMT);	}	if (oracle_sock->errHandle) {		OCIHandleFree((dvoid *)oracle_sock->errHandle, (ub4) OCI_HTYPE_ERROR);	}	if (oracle_sock->env) {		OCIHandleFree((dvoid *)oracle_sock->env, (ub4) OCI_HTYPE_ENV);	}	oracle_sock->conn = NULL;*/	return 0;}/************************************************************************* * *	Function: sql_finish_query * *	Purpose: End the query, such as freeing memory * *************************************************************************/static int sql_finish_query(SQLSOCK *sqlsocket, SQL_CONFIG *config){	rlm_sql_sybase_sock *sybase_sock = sqlsocket->conn;	ct_cancel(NULL, sybase_sock->command, CS_CANCEL_ALL);	if (ct_cmd_drop(sybase_sock->command) != CS_SUCCEED) {		radlog(L_ERR,"rlm_sql_sybase(sql_finish_query): Freeing command structure failed.");		return -1;	}	return 0;}/************************************************************************* * *	Function: sql_finish_select_query * *	Purpose: End the select query, such as freeing memory or result * *************************************************************************/static int sql_finish_select_query(SQLSOCK *sqlsocket, SQL_CONFIG *config) {	rlm_sql_sybase_sock *sybase_sock = sqlsocket->conn;	int	i=0;	ct_cancel(NULL, sybase_sock->command, CS_CANCEL_ALL);	if (ct_cmd_drop(sybase_sock->command) != CS_SUCCEED) {		radlog(L_ERR,"rlm_sql_sybase(sql_finish_select_query): Freeing command structure failed.");		return -1;	}        if (sybase_sock->results) {                while(sybase_sock->results[i]) free(sybase_sock->results[i++]);                free(sybase_sock->results);                sybase_sock->results=NULL;        }	return 0;}/************************************************************************* * *	Function: sql_affected_rows * *	Purpose: Return the number of rows affected by the query (update, *               or insert) * *************************************************************************/static int sql_affected_rows(SQLSOCK *sqlsocket, SQL_CONFIG *config) {	return sql_num_rows(sqlsocket, config);}/* Exported to rlm_sql */rlm_sql_module_t rlm_sql_sybase = {	"rlm_sql_sybase",	sql_init_socket,	sql_destroy_socket,	sql_query,	sql_select_query,	sql_store_result,	sql_num_fields,	sql_num_rows,	sql_fetch_row,	sql_free_result,	sql_error,	sql_close,	sql_finish_query,	sql_finish_select_query,	sql_affected_rows};

⌨️ 快捷键说明

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