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

📄 comm.c

📁 网络数据管理协议的开发
💻 C
📖 第 1 页 / 共 2 页
字号:
			  header.message);		xdrrec_endofrecord(&connection->xdrs, 1);		return(-1);	}	if (err == NDMP_NO_ERR &&		connection->msginfo.handler->xdr_reply &&		reply)	{		if (!(*connection->msginfo.handler->xdr_reply)(&connection->xdrs,													   reply))		{			Error(LOG_ERR,				  "sending message 0x%x: encoding reply body.\n",				  header.message);			xdrrec_endofrecord(&connection->xdrs, 1);			return(-1);		}	}		xdrrec_endofrecord(&connection->xdrs, 1);	return(0);}voidndmpFreeMessage(NdmpConnection	connectionHandle){	Connection*	connection = (Connection *)connectionHandle;		Debug(DBG_CAT_COMM|DBG_FOC_FLOW,		  "ndmpFreeMessage: message:0x%x\n",		  connection->msginfo.hdr.message);	if (connection->msginfo.handler == 0 ||		connection->msginfo.body == 0)		return;	connection->xdrs.x_op = XDR_FREE;	if (connection->msginfo.hdr.message_type == NDMP_MESSAGE_REQUEST)	{		if (connection->msginfo.handler->xdr_request)			(*connection->msginfo.handler->xdr_request)(&connection->xdrs,														connection->msginfo.body);	}	else	{		if (connection->msginfo.handler->xdr_reply)			(*connection->msginfo.handler->xdr_reply)(&connection->xdrs,													  connection->msginfo.body);	}		(void)free((void*)connection->msginfo.body);	connection->msginfo.body = 0;}/* * ndmpGetFd * * Returns the connection file descriptor. * * Parameters: *   connectionHandle (input) - connection handle * * Returns: *   >=0 - file descriptor. *   -1  - connection not open. */intndmpGetFd(NdmpConnection	connectionHandle){	return(((Connection *)connectionHandle)->sock);}/* * ndmpSetClientData * * This function provides a means for the library client to provide * a pointer to some user data structure that is retrievable by * each message handler via ndmpGetClientData. * * Parameters: *   connectionHandle  (input) - connection handle. *   clientData        (input) - user data pointer. * * Returns: *   void */voidndmpSetClientData(NdmpConnection	connectionHandle,				  void*				clientData){	((Connection *)connectionHandle)->clientData = clientData;}/* * ndmpGetClientData * * This function provides a means for the library client to provide * a pointer to some user data structure that is retrievable by * each message handler via ndmpGetClientData. * * Parameters: *   connectionHandle (input) - connection handle. * * Returns: *   client data pointer. */void*ndmpGetClientData(NdmpConnection	connectionHandle){	return(((Connection *)connectionHandle)->clientData);}/* * ndmpSetVersion *   Sets the NDMP protocol version to be used on the connection. * * Parameters: *   connectionHandle  (input) - connection handle. *   version           (input) - protocol version. * * Returns: *   void */voidndmpSetVersion(NdmpConnection	connectionHandle,			   u_short			version){	((Connection *)connectionHandle)->version = version;}/* * ndmpGetVersion *   Gets the NDMP protocol version in use on the connection. * * Parameters: *   connectionHandle  (input) - connection handle. *   version           (input) - protocol version. * * Returns: *   void */u_shortndmpGetVersion(NdmpConnection	connectionHandle){	return(((Connection *)connectionHandle)->version);}/* * ndmpSetAuthorized *   Mark the connection as either having been authorized or not. * * Parameters: *   connectionHandle  (input) - connection handle. *   authorized        (input) - TRUE or FALSE. * * Returns: *   void */voidndmpSetAuthorized(NdmpConnection	connectionHandle,				  bool_t			authorized){	((Connection *)connectionHandle)->authorized = authorized;}u_longlong_tquadToLongLong(ndmp_u_quad	quad){	u_longlong_t	ull;	ull = ((u_longlong_t)quad.high << 32) +	quad.low;	return(ull);}ndmp_u_quadlongLongToQuad(u_longlong_t	ull){	ndmp_u_quad	quad;	quad.high = (u_long)(ull >> 32);	quad.low  = (u_long)ull;	return(quad);}/* * ndmpCreateMD5Digest *   Creates an MD5 digest * * Parameters: *   digest   (output) - location to store digest. Must be at least 16 bytes. *   password (input)  - password string. *   challenge (input) - 64 bytes of challenge data. * * Returns: *   void */voidndmpCreateMD5Digest(char*	digest,					char*	password,					char*	challenge){	MD5_CTX		context;	char		md5Buf[128];	memset((void*)md5Buf, 0, sizeof(md5Buf));	memcpy((void*)&md5Buf[0], password, strlen(password));	memcpy((void*)&md5Buf[128-strlen(password)],		   password, strlen(password));	memcpy((void*)&md5Buf[128-strlen(password)-64],		   challenge, 64);	MD5Init(&context);	MD5Update(&context, md5Buf, sizeof(md5Buf));	MD5Final(digest, &context);}/************** private functions ****************************************//* * ndmp_readit * * Low level read routine called by the xdrrec library. * * Parameters: *   connection (input) - connection pointer. *   buf        (input) - location to store received data. *   len        (input) - max number of bytes to read. * * Returns: *   >0 - number of bytes received. *   -1 - error. */static intndmp_readit(void*		connectionHandle,			caddr_t		buf,			int			len){	Connection	*connection = (Connection *)connectionHandle;	Debug(DBG_CAT_COMM|DBG_FOC_DETAIL,		  "ndmp_readit: len:%d\n", len);	len = read(connection->sock, buf, len);	if (len <= 0)	{		/* Connection has been closed. */		connection->eof = TRUE;		return(-1);	}	return(len);}/* * ndmp_writeit * * Low level write routine called by the xdrrec library. * * Parameters: *   connection (input) - connection pointer. *   buf        (input) - location to store received data. *   len        (input) - max number of bytes to read. * * Returns: *   >0 - number of bytes sent. *   -1 - error. */static intndmp_writeit(void*		connectionHandle,			 caddr_t	buf,			 int		len){	Connection		*connection = (Connection *)connectionHandle;	register int	n;	register int	cnt;	Debug(DBG_CAT_COMM|DBG_FOC_DETAIL,		  "ndmp_writeit: len:%d\n", len);	for(cnt = len; cnt > 0; cnt -= n, buf += n)	{		if ((n = write(connection->sock, buf, cnt)) < 0)		{			connection->eof = TRUE;			return (-1);		}	}	return(len);}/* * ndmp_recv_msg * * Read the next message. * * Parameters: *   connection (input)  - connection pointer. *   msg        (output) - received message. * * Returns: *   0 - Message successfully received. *   error number - Message related error. *  -1 - Error decoding the message header. */static intndmp_recv_msg(Connection*	connection){	bool_t	(*xdr_func)(XDR*, ...) = 0;	Debug(DBG_CAT_COMM|DBG_FOC_FLOW,		  "ndmp_recv_msg\n");	/* Decode the header. */	connection->xdrs.x_op = XDR_DECODE;	xdrrec_skiprecord(&connection->xdrs);	if (!xdr_ndmp_header(&connection->xdrs, &connection->msginfo.hdr))	{		return(-1);	}	/* Lookup info necessary for processing this message. */	if ((connection->msginfo.handler =		  ndmp_get_handler(connection,						   connection->msginfo.hdr.message)) == 0)	{		Error(LOG_ERR, "message 0x%x not supported.\n",			  connection->msginfo.hdr.message);		return(NDMP_NOT_SUPPORTED_ERR);	}  	connection->msginfo.body		= 0;	if (connection->msginfo.hdr.error != NDMP_NO_ERR)		return(0);		/* Determine body type */	if (connection->msginfo.hdr.message_type == NDMP_MESSAGE_REQUEST)	{		if (connection->msginfo.handler->auth_required &&			!connection->authorized)		{			Error(LOG_ERR,				  "processing request 0x%x: connection not authorized.\n",				  connection->msginfo.hdr.message);			return(NDMP_NOT_AUTHORIZED_ERR);		}				if (connection->msginfo.handler->sizeof_request > 0)		{			xdr_func		= connection->msginfo.handler->xdr_request;			if (xdr_func == 0)			{				Error(LOG_ERR,					  "processing request 0x%x: no xdr function in handler table.\n",					  connection->msginfo.hdr.message);				return(NDMP_NOT_SUPPORTED_ERR);			}						connection->msginfo.body =				(void *)malloc(connection->msginfo.handler->sizeof_request);			if (connection->msginfo.body == 0)			{				Error(LOG_ERR,					  "processing request 0x%x: system call (malloc): %s\n",					  connection->msginfo.hdr.message, strerror(errno));				return(NDMP_NO_MEM_ERR);			}			memset(connection->msginfo.body, 0,				   connection->msginfo.handler->sizeof_request);		}	}	else	{		if (connection->msginfo.handler->sizeof_reply > 0)		{			xdr_func = connection->msginfo.handler->xdr_reply;			if (xdr_func == 0)			{				Error(LOG_ERR,					  "processing reply 0x%x: no xdr function in handler table.\n",					  connection->msginfo.hdr.message);				return(NDMP_NOT_SUPPORTED_ERR);			}			connection->msginfo.body =				(void *)malloc(connection->msginfo.handler->sizeof_reply);			if (connection->msginfo.body == 0)			{				Error(LOG_ERR,					  "processing reply 0x%x: system call (malloc): %s\n",					  connection->msginfo.hdr.message, strerror(errno));				return(NDMP_NO_MEM_ERR);			}			memset(connection->msginfo.body, 0,				   connection->msginfo.handler->sizeof_reply);		}	}	/* Decode message arguments if needed */	if (xdr_func)	{		if (!(*xdr_func)(&connection->xdrs,						 connection->msginfo.body))		{			Error(LOG_ERR,				  "processing message 0x%x: error decoding arguments.\n",				  connection->msginfo.hdr.message);			free(connection->msginfo.body);			connection->msginfo.body = 0;			return(NDMP_XDR_DECODE_ERR);		}	}	return(0);}/* * ndmp_process_messages * * Reads the next message into the stream buffer. * Processes messages until the stream buffer is empty. * * This function processes all data in the stream buffer before returning. * This allows functions like poll() to be used to determine when new  * messages have arrived. If only some of the messages in the stream buffer * were processed and then poll was called, poll() could block waiting for * a message that had already been received and read into the stream buffer. * * This function processes both request and reply messages. * Request messages are dispatched using the appropriate function from the * message handling table. * Only one reply messages may be pending receipt at a time. * A reply message, if received, is placed in connection->msginfo * before returning to the caller. * Errors are reported if a reply is received but not expected or if * more than one reply message is received * * Parameters: *   connection     (input)  - connection pointer. *   reply_expected (output) - TRUE  - a reply message is expected. *                             FALSE - no reply message is expected and *                             an error will be reported if a reply *                             is received. * * Returns: *   2 - 1 or messages successfully processed, error processing reply message. *   1 - 1 or messages successfully processed, reply seen. *   0 - 1 or more messages successfully processed, no reply seen. *  -1 - error; connection no longer established. * * Notes: *   If the peer is generating a large number of requests, a caller *   looking for a reply will be blocked while the requests are handled. *   This is because this function does not return until the stream *   buffer is empty. *   Code needs to be added to allow a return if the stream buffer *   is not empty but there is data available on the socket. This will *   prevent poll() from blocking and prevent a caller looking for a reply *   from getting blocked by a bunch of requests. */static intndmp_process_messages(Connection*	connection,					  bool_t		reply_expected){	MsgInfo		reply_msginfo;	bool_t		reply_read = FALSE;	bool_t		reply_error = FALSE;	int			err;		Debug(DBG_CAT_COMM|DBG_FOC_DETAIL,		  "ndmp_process_messages: reply_expected:%s\n",		  reply_expected == TRUE ? "TRUE" : "FALSE");	memset((void *)&reply_msginfo, 0, sizeof(MsgInfo));	do	{		memset((void *)&connection->msginfo, 0, sizeof(MsgInfo));			if ((err = ndmp_recv_msg(connection)) != NDMP_NO_ERR)		{			if (connection->eof)			{				Debug(DBG_CAT_COMM|DBG_FOC_FLOW,					  "ndmp_process_messages: detected eof\n");				return(-1);			}						if (err < 1)			{				Debug(DBG_CAT_COMM|DBG_FOC_DETAIL,					  "ndmp_process_messages: error decoding header\n");				/*				 * Error occurred decoding the header.				 * Don't send a reply since we don't know the message				 * or if the message was even a request message.				 *				 * To be safe, assume that the message was a reply				 * if a reply was expected. Need to do this to prevent				 * hanging ndmpSendRequest() waiting for a reply. 				 * Don't set reply_read so that the reply will be				 * processed if it received later.				 */				if (reply_read == FALSE)					reply_error = TRUE;				continue;			}						if (connection->msginfo.hdr.message_type != NDMP_MESSAGE_REQUEST)			{				Debug(DBG_CAT_COMM|DBG_FOC_FLOW,					  "ndmp_process_messages: received reply: 0x%x\n",					  connection->msginfo.hdr.message);				if (reply_expected == 0 || reply_read == TRUE)					Error(LOG_ERR, "unexpected reply message: 0x%x.\n",						  connection->msginfo.hdr.message);				ndmpFreeMessage((NdmpConnection)connection);				if (reply_read == FALSE)				{					reply_read = TRUE;					reply_error = TRUE;				}								continue;			}						Debug(DBG_CAT_COMM|DBG_FOC_FLOW,				  "ndmp_process_messages: received request: 0x%x\n",				  connection->msginfo.hdr.message);			ndmpSendReply((NdmpConnection)connection, err, 0);			ndmpFreeMessage((NdmpConnection)connection);			continue;		}					if (connection->msginfo.hdr.message_type != NDMP_MESSAGE_REQUEST)		{			Debug(DBG_CAT_COMM|DBG_FOC_FLOW,				  "ndmp_process_messages: received reply: 0x%x\n",				  connection->msginfo.hdr.message);			if (reply_expected == 0 || reply_read == TRUE)			{				Error(LOG_ERR, "unexpected reply message: 0x%x.\n",					  connection->msginfo.hdr.message);				ndmpFreeMessage((NdmpConnection)connection);				continue;			}						reply_read = TRUE;			reply_msginfo = connection->msginfo;			continue;		}		Debug(DBG_CAT_COMM|DBG_FOC_FLOW,			  "ndmp_process_messages: received request: 0x%x\n",			  connection->msginfo.hdr.message);		/*		 * The following needed to catch an improperly constructed		 * handler table or to deal with an NDMP client that is not		 * conforming to the negotiated protocol version.		 */		if (connection->msginfo.handler->func == 0)		{			Error(LOG_ERR,				  "No handler for message 0x%x\n",				  connection->msginfo.hdr.message);			ndmpSendReply((NdmpConnection)connection, NDMP_NOT_SUPPORTED_ERR, 0);			ndmpFreeMessage((NdmpConnection)connection);			continue;		}		/*		 * Call the handler function.		 * The handler will send any necessary reply.		 */		(*connection->msginfo.handler->func)(connection,											 connection->msginfo.body);		ndmpFreeMessage((NdmpConnection)connection);	} while (xdrrec_eof(&connection->xdrs) == FALSE &&			 connection->eof == FALSE);	Debug(DBG_CAT_COMM|DBG_FOC_DETAIL,		  "ndmp_process_messages: no more messages in stream buffer\n");	if (connection->eof == TRUE)	{		if (reply_msginfo.body)             free(reply_msginfo.body);		return(-1);	}		if (reply_error)	{		if (reply_msginfo.body)             free(reply_msginfo.body);		return(2);	}		if (reply_read)	{		connection->msginfo = reply_msginfo;		return(1);	}		return(0);}/* * ndmp_get_handler * * Return the handler info for the specified NDMP message. * * Parameters: *   message (input) - message number. * * Returns: *   0 - message not found. *   pointer to handler info. */static NdmpMsgHandler*ndmp_get_handler(Connection*	connection,				 ndmp_message	message){	NdmpMsgHandler		*handler;	for (handler = connection->msgHandlerTbl;		 handler->message != 0;		 handler++)	{		if (handler->message == message &&			handler->version == connection->version)			return(handler);    }	return(0);}

⌨️ 快捷键说明

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