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

📄 token.c

📁 ncbi源码
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * =========================================================================== * PRODUCTION $Log: token.c,v $ * PRODUCTION Revision 1000.1  2004/04/01 21:01:24  gouriano * PRODUCTION PRODUCTION: UPGRADED [CORE_002] Dev-tree R1.5 * PRODUCTION * =========================================================================== *//* FreeTDS - Library of routines accessing Sybase and Microsoft databases * Copyright (C) 1998-1999  Brian Bruns * * 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. */#include <tds_config.h>#include "tds.h"#include "tdsutil.h"#include "tdsconvert.h"#ifdef DMALLOC#include <dmalloc.h>#endifstatic char  software_version[]   = "$Id: token.c,v 1000.1 2004/04/01 21:01:24 gouriano Exp $";static void *no_unused_var_warn[] = {software_version,                                     no_unused_var_warn};static int tds_process_msg(TDSSOCKET *tds,int marker);static int tds_process_compute_result(TDSSOCKET *tds);static int tds_process_result(TDSSOCKET *tds);static int tds_process_col_name(TDSSOCKET *tds);static int tds_process_col_info(TDSSOCKET *tds);static int tds_process_compute(TDSSOCKET *tds);static int tds_process_row(TDSSOCKET *tds);static int tds_process_param_result(TDSSOCKET *tds);static int tds7_process_result(TDSSOCKET *tds);static int tds_process_param_result_tokens(TDSSOCKET *tds);static void tds_process_dyn_result(TDSSOCKET *tds);static int tds_process_dynamic(TDSSOCKET *tds);static int tds_process_auth(TDSSOCKET *tds);static int tds_get_varint_size(int datatype);static int tds_get_cardinal_type(int datatype);void tds_swap_datatype(int coltype, unsigned char *buf);/*** The following little table is indexed by precision and will** tell us the number of bytes required to store the specified** precision.*/extern const int g__numeric_bytes_per_prec[];/*** tds_process_default_tokens() is a catch all function that is called to** process tokens not known to other tds_process_* routines*/int tds_process_default_tokens(TDSSOCKET *tds, int marker){int order_len;int tok_size;int   more_results;int   cancelled;   tdsdump_log(TDS_DBG_FUNC, "%L inside tds_process_default_tokens() marker is %x\n", marker);   if (!tds->s) {        tdsdump_log(TDS_DBG_FUNC, "%L leaving tds_process_default_tokens() connection dead\n");	tds->state=TDS_DEAD;	return TDS_FAIL;   }   switch(marker) {	case TDS_AUTH_TOKEN:		tds_process_auth(tds);		break;	case TDS_ENV_CHG_TOKEN:      {         tds_process_env_chg(tds);         break;      }      case TDS_DONE_TOKEN:      case TDS_DONEPROC_TOKEN:      case TDS_DONEINPROC_TOKEN:      {         tds_process_end(tds, marker, &more_results, &cancelled);         if (!more_results) tds->state=TDS_COMPLETED;         break;      }      case TDS_124_TOKEN:         tds_get_n(tds,NULL,8);         break;      case TDS_RET_STAT_TOKEN:	tds->has_status=1;	tds->ret_status=tds_get_int(tds);        break;      case TDS_ERR_TOKEN:      case TDS_MSG_TOKEN:      case TDS_EED_TOKEN:         return tds_process_msg(tds,marker);         break;      case TDS_CAP_TOKEN:	 tok_size = tds_get_smallint(tds);         tds_get_n(tds,tds->capabilities,tok_size > TDS_MAX_CAPABILITY ? TDS_MAX_CAPABILITY : tok_size);         break;      case TDS_LOGIN_ACK_TOKEN:         tds_get_n(tds,NULL,tds_get_smallint(tds));         break;      case TDS_ORDER_BY_TOKEN:         order_len = tds_get_smallint(tds);         tds_get_n(tds, NULL, order_len);         /* get the next token which is ROW_TOKEN (209)			tds_get_byte(tds);			if(orderLen > 1)				tds_process_column_row(tds); */         break;      case TDS_168_TOKEN:         tds_process_compute_result(tds);          break;      case TDS_PARAM_TOKEN: 	 tds_unget_byte(tds);	 tds_process_param_result_tokens(tds);         break;         /* 167 is somehow related to compute columns */      case TDS_167_TOKEN:      case TDS_174_TOKEN:          tds_get_n(tds, NULL, tds_get_smallint(tds));         break;      case TDS7_RESULT_TOKEN:         tds7_process_result(tds);          break;      case TDS_RESULT_TOKEN:         tds_process_result(tds);          break;      case TDS_COL_NAME_TOKEN:         tds_process_col_name(tds);          break;      case TDS_COL_INFO_TOKEN:         tds_process_col_info(tds);          break;      case TDS_CMP_ROW_TOKEN:         tds_process_compute(tds);          break;      case TDS_ROW_TOKEN:         tds_process_row(tds);          break;      case TDS5_DYN_TOKEN:      case TDS5_DYNRES_TOKEN:      case TDS5_DYN3_TOKEN:#ifdef NCBI_FTDS   case TDS_COL_INFO_TOKEN2:#endif	 tdsdump_log(TDS_DBG_WARN, "eating token %d\n",marker);         tds_get_n(tds, NULL, tds_get_smallint(tds));         break;      default:	 tdsdump_log(TDS_DBG_ERROR, "Unknown marker: %d(%x)!!\n",marker,(unsigned char)marker);          return TDS_FAIL;   }	   return TDS_SUCCEED;}	/*** tds_process_login_tokens() is called after sending the login packet ** to the server.  It returns the success or failure of the login ** dependent on the protocol version. 4.2 sends an ACK token only when** successful, TDS 5.0 sends it always with a success byte within*/int tds_process_login_tokens(TDSSOCKET *tds){int succeed=0;int marker;int len;unsigned char major_ver, minor_ver;unsigned char ack;#ifdef WORDS_BIGENDIANchar *tmpbuf;#endif	tdsdump_log(TDS_DBG_FUNC, "%L inside tds_process_login_tokens()\n");	/* get_incoming(tds->s); */	do {		marker=tds_get_byte(tds);		switch(marker) {			case TDS_AUTH_TOKEN:				tds_process_auth(tds);				break;			case TDS_LOGIN_ACK_TOKEN:				len = tds_get_smallint(tds);				ack = tds_get_byte(tds);				major_ver = tds_get_byte(tds);				minor_ver = tds_get_byte(tds);				tds_get_n(tds, NULL, len-4);				tds_get_byte(tds);#ifdef WORDS_BIGENDIAN/*				if (major_ver==7) {					tds->broken_dates=1;				}*/#endif/*				tmpbuf = (char *) malloc(len);				tds_get_n(tds, tmpbuf, len);				tdsdump_log(TDS_DBG_INFO1, "%L login ack marker = %d\n%D\n", marker, tmpbuf, len);				free(tmpbuf);*/				/* TDS 5.0 reports 5 on success 6 on failure				** TDS 4.2 reports 1 on success and is not				** present on failure */				if (ack==5 || ack==1) succeed=TDS_SUCCEED;				break;			default:				if (tds_process_default_tokens(tds,marker)==TDS_FAIL)					return TDS_FAIL;				break;		}	} while (marker!=TDS_DONE_TOKEN);	tdsdump_log(TDS_DBG_FUNC, "%L leaving tds_process_login_tokens() returning %d\n",succeed);	return succeed;}static int tds_process_auth(TDSSOCKET *tds){int pdu_size, ntlm_size;char nonce[10];/* char domain[30]; */int where = 0;	pdu_size = tds_get_smallint(tds);	tdsdump_log(TDS_DBG_INFO1, "TDS_AUTH_TOKEN PDU size %d\n", pdu_size);	tds_get_n(tds, NULL, 8); /* NTLMSSP\0 */ 	where += 8;	tds_get_int(tds); /* sequence -> 2 */	where += 4;	tds_get_n(tds, NULL, 4); /* domain len (2 time) */	where += 4;	ntlm_size = tds_get_int(tds); /* size of remainder of ntlmssp packet */	where += 4;	tdsdump_log(TDS_DBG_INFO1, "TDS_AUTH_TOKEN NTLMSSP size %d\n", ntlm_size);	tds_get_n(tds, NULL, 4); /* flags */	where += 4;	tds_get_n(tds, nonce, 8); 	where += 8;	tdsdump_log(TDS_DBG_INFO1, "TDS_AUTH_TOKEN nonce\n");	tdsdump_dump_buf(nonce, 8);	tds_get_n(tds, NULL, 8); 	where += 8;		/*	tds_get_ntstring(tds, domain, 30); 	tdsdump_log(TDS_DBG_INFO1, "TDS_AUTH_TOKEN domain %s\n", domain);	where += strlen(domain);	*/	tds_get_n(tds, NULL, pdu_size - where); 	tdsdump_log(TDS_DBG_INFO1,"%L Draining %d bytes\n", pdu_size - where);	tds7_send_auth(tds, nonce);	return TDS_SUCCEED;}/*** tds_process_result_tokens() is called after submitting a query with** tds_submit_query() and is responsible for calling the routines to** populate tds->res_info if appropriate (some query have no result sets)*/int tds_process_result_tokens(TDSSOCKET *tds){int result=0;int marker;int more_results = 0;int cancelled;int retcode=TDS_NO_MORE_RESULTS;int rc;	if (tds->state==TDS_COMPLETED) {		/* tds_process_row() now eats the end marker and sets		** state to TDS_COMPLETED		*/		return TDS_NO_MORE_RESULTS;	}	/* get_incoming(tds->s); */	do {		marker=tds_get_byte(tds);tdsdump_log(TDS_DBG_INFO1, "%L processing result tokens.  marker is  %x\n", marker);		switch(marker) {      			case TDS_ERR_TOKEN:      			case TDS_MSG_TOKEN:      			case TDS_EED_TOKEN:				rc = tds_process_msg(tds,marker);				/* don't fail until we get a DONE */				if (rc == TDS_ERROR) 					retcode=TDS_FAIL;				break;			case TDS7_RESULT_TOKEN:				if (!result) {					tds7_process_result(tds);					result++;				} else {					tds_unget_byte(tds);					return TDS_SUCCEED;				}				break;			case TDS_RESULT_TOKEN:				if (!result) {					tds_process_result(tds);					result++;				} else {					tds_unget_byte(tds);					return TDS_SUCCEED;				}				break;			case TDS_COL_NAME_TOKEN:				if (!result) {					tds_process_col_name(tds);					result++;				} else {					tds_unget_byte(tds);					return TDS_SUCCEED;				}				break;			case TDS_ROW_TOKEN:				if (!result) {				} else {					tds->res_info->rows_exist=1;					tds_unget_byte(tds);					return TDS_SUCCEED;				}#ifdef NCBI_FTDS             break; /* <-- looks like it should be here (v. soussov) */#endif      			case TDS_RET_STAT_TOKEN:				tds->has_status=1;				tds->ret_status=tds_get_int(tds);				/* return TDS_SUCCEED; */				break;			case TDS5_DYN_TOKEN:				tds->cur_dyn_elem = tds_process_dynamic(tds);				break;      		case TDS5_DYNRES_TOKEN:				tds_process_dyn_result(tds);				break;			case TDS_DONE_TOKEN:			case TDS_DONEPROC_TOKEN:			case TDS_DONEINPROC_TOKEN:				tds_process_end(tds, marker, 						&more_results, 						&cancelled);				break;			default:				if (tds_process_default_tokens(tds, marker)==TDS_FAIL) 					return TDS_FAIL;				break;		}	} while (!is_end_token(marker) || more_results);	tds->state=TDS_COMPLETED;	return retcode;}/* ** tds_process_row_tokens() is called once a result set has been obtained** with tds_process_result_tokens(). It calls tds_process_row() to copy** data into the row buffer.*/int tds_process_row_tokens(TDSSOCKET *tds){int marker;int   more_results;int   cancelled;	if (tds->state==TDS_COMPLETED) {		return TDS_NO_MORE_ROWS;	}	while (1) {		marker=tds_get_byte(tds);        tdsdump_log(TDS_DBG_INFO1, "%L processing row tokens.  marker is  %x\n", marker);		switch(marker) {			case TDS_RESULT_TOKEN:			case TDS7_RESULT_TOKEN:				tds_unget_byte(tds);				return TDS_NO_MORE_ROWS;			case TDS_ROW_TOKEN:				tds_process_row(tds);				return TDS_SUCCEED;			case TDS_DONE_TOKEN:			case TDS_DONEPROC_TOKEN:			case TDS_DONEINPROC_TOKEN:				tds_process_end(tds, marker, 						&more_results, 						&cancelled);				tds->res_info->more_results = more_results;				return TDS_NO_MORE_ROWS;			default:				if (tds_process_default_tokens(tds,marker)==TDS_FAIL)					return TDS_FAIL;				break;		}	} 	return TDS_SUCCEED;}/* ** tds_process_col_name() is one half of the result set under TDS 4.2** it contains all the column names, a TDS_COLINFO_TOKEN should ** immediately follow this token with the datatype/size information** This is a 4.2 only function*/static int tds_process_col_name(TDSSOCKET *tds){int hdrsize, len=0;int col,num_cols=0;struct tmp_col_struct {	char *column_name;	int column_namelen;	struct tmp_col_struct *next;};struct tmp_col_struct *head=NULL, *cur=NULL, *prev;TDSCOLINFO *curcol;TDSRESULTINFO *info;	hdrsize = tds_get_smallint(tds);	/* this is a little messy...TDS 5.0 gives the number of columns	** upfront, while in TDS 4.2, you're expected to figure it out	** by the size of the message. So, I use a link list to get the	** colum names and then allocate the result structure, copy	** and delete the linked list */	while (len<hdrsize) {		prev = cur;		cur = (struct tmp_col_struct *) 			malloc(sizeof (struct tmp_col_struct));		if (prev) prev->next=cur;		if (!head) head = cur;		cur->column_namelen = tds_get_byte(tds);		cur->column_name = (char *) malloc(cur->column_namelen+1);		tds_get_n(tds,cur->column_name, cur->column_namelen);		cur->column_name[cur->column_namelen]='\0';		cur->next=NULL;		len += cur->column_namelen + 1;		num_cols++;	}	/* free results/computes/params etc... */	tds_free_all_results(tds);	tds->res_info = tds_alloc_results(num_cols);	info = tds->res_info;	/* tell the upper layers we are processing results */	tds->state = TDS_PENDING; 

⌨️ 快捷键说明

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