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

📄 sock.c

📁 嵌入式系统设计与实验教材二源码linux内核移植与编译
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  linux/fs/ncpfs/sock.c * *  Copyright (C) 1992, 1993  Rick Sladkey * *  Modified 1995, 1996 by Volker Lendecke to be usable for ncp *  Modified 1997 Peter Waltenberg, Bill Hawes, David Woodhouse for 2.1 dcache * */#include <linux/config.h>#include <linux/sched.h>#include <linux/errno.h>#include <linux/socket.h>#include <linux/fcntl.h>#include <linux/stat.h>#include <asm/uaccess.h>#include <linux/in.h>#include <linux/net.h>#include <linux/mm.h>#include <linux/netdevice.h>#include <linux/signal.h>#include <net/scm.h>#include <net/sock.h>#include <linux/ipx.h>#include <linux/poll.h>#include <linux/file.h>#include <linux/ncp_fs.h>#ifdef CONFIG_NCPFS_PACKET_SIGNING#include "ncpsign_kernel.h"#endifstatic int _recv(struct socket *sock, unsigned char *ubuf, int size,		 unsigned flags){	struct iovec iov;	struct msghdr msg;	struct scm_cookie scm;	memset(&scm, 0, sizeof(scm));	iov.iov_base = ubuf;	iov.iov_len = size;	msg.msg_name = NULL;	msg.msg_namelen = 0;	msg.msg_control = NULL;	msg.msg_iov = &iov;	msg.msg_iovlen = 1;	return sock->ops->recvmsg(sock, &msg, size, flags, &scm);}static int _send(struct socket *sock, const void *buff, int len){	struct iovec iov;	struct msghdr msg;	struct scm_cookie scm;	int err;	iov.iov_base = (void *) buff;	iov.iov_len = len;	msg.msg_name = NULL;	msg.msg_namelen = 0;	msg.msg_control = NULL;	msg.msg_iov = &iov;	msg.msg_iovlen = 1;	msg.msg_flags = 0;	err = scm_send(sock, &msg, &scm);	if (err < 0) {		return err;	}	err = sock->ops->sendmsg(sock, &msg, len, &scm);	scm_destroy(&scm);	return err;}static int do_ncp_rpc_call(struct ncp_server *server, int size,		struct ncp_reply_header* reply_buf, int max_reply_size){	struct file *file;	struct socket *sock;	int result;	char *start = server->packet;	poll_table wait_table;	int init_timeout, max_timeout;	int timeout;	int retrans;	int major_timeout_seen;	int acknowledge_seen;	int n;	/* We have to check the result, so store the complete header */	struct ncp_request_header request =	*((struct ncp_request_header *) (server->packet));	struct ncp_reply_header reply;	file = server->ncp_filp;	sock = &file->f_dentry->d_inode->u.socket_i;	init_timeout = server->m.time_out;	max_timeout = NCP_MAX_RPC_TIMEOUT;	retrans = server->m.retry_count;	major_timeout_seen = 0;	acknowledge_seen = 0;	for (n = 0, timeout = init_timeout;; n++, timeout <<= 1) {		/*		DDPRINTK("ncpfs: %08lX:%02X%02X%02X%02X%02X%02X:%04X\n",			 htonl(server->m.serv_addr.sipx_network),			 server->m.serv_addr.sipx_node[0],			 server->m.serv_addr.sipx_node[1],			 server->m.serv_addr.sipx_node[2],			 server->m.serv_addr.sipx_node[3],			 server->m.serv_addr.sipx_node[4],			 server->m.serv_addr.sipx_node[5],			 ntohs(server->m.serv_addr.sipx_port));		*/		DDPRINTK("ncpfs: req.typ: %04X, con: %d, "			 "seq: %d",			 request.type,			 (request.conn_high << 8) + request.conn_low,			 request.sequence);		DDPRINTK(" func: %d\n",			 request.function);		result = _send(sock, (void *) start, size);		if (result < 0) {			printk(KERN_ERR "ncp_rpc_call: send error = %d\n", result);			break;		}	      re_select:		poll_initwait(&wait_table);		/* mb() is not necessary because ->poll() will serialize		   instructions adding the wait_table waitqueues in the		   waitqueue-head before going to calculate the mask-retval. */		__set_current_state(TASK_INTERRUPTIBLE);		if (!(sock->ops->poll(file, sock, &wait_table) & POLLIN)) {			int timed_out;			if (timeout > max_timeout) {				/* JEJB/JSP 2/7/94				 * This is useful to see if the system is				 * hanging */				if (acknowledge_seen == 0) {					printk(KERN_WARNING "NCP max timeout\n");				}				timeout = max_timeout;			}			timed_out = !schedule_timeout(timeout);			poll_freewait(&wait_table);			current->state = TASK_RUNNING;			if (signal_pending(current)) {				result = -ERESTARTSYS;				break;			}			if(wait_table.error) {				result = wait_table.error;				break;			}			if (timed_out) {				if (n < retrans)					continue;				if (server->m.flags & NCP_MOUNT_SOFT) {					printk(KERN_WARNING "NCP server not responding\n");					result = -EIO;					break;				}				n = 0;				timeout = init_timeout;				if (init_timeout < max_timeout)					init_timeout <<= 1;				if (!major_timeout_seen) {					printk(KERN_WARNING "NCP server not responding\n");				}				major_timeout_seen = 1;				continue;			}		} else {			poll_freewait(&wait_table);		}		current->state = TASK_RUNNING;		/* Get the header from the next packet using a peek, so keep it		 * on the recv queue.  If it is wrong, it will be some reply		 * we don't now need, so discard it */		result = _recv(sock, (void *) &reply, sizeof(reply),			       MSG_PEEK | MSG_DONTWAIT);		if (result < 0) {			if (result == -EAGAIN) {				DDPRINTK("ncp_rpc_call: bad select ready\n");				goto re_select;			}			if (result == -ECONNREFUSED) {				DPRINTK("ncp_rpc_call: server playing coy\n");				goto re_select;			}			if (result != -ERESTARTSYS) {				printk(KERN_ERR "ncp_rpc_call: recv error = %d\n",				       -result);			}			break;		}		if ((result == sizeof(reply))		    && (reply.type == NCP_POSITIVE_ACK)) {			/* Throw away the packet */			DPRINTK("ncp_rpc_call: got positive acknowledge\n");			_recv(sock, (void *) &reply, sizeof(reply),			      MSG_DONTWAIT);			n = 0;			timeout = max_timeout;			acknowledge_seen = 1;			goto re_select;		}		DDPRINTK("ncpfs: rep.typ: %04X, con: %d, tsk: %d,"			 "seq: %d\n",			 reply.type,			 (reply.conn_high << 8) + reply.conn_low,			 reply.task,			 reply.sequence);		if ((result >= sizeof(reply))		    && (reply.type == NCP_REPLY)		    && ((request.type == NCP_ALLOC_SLOT_REQUEST)			|| ((reply.sequence == request.sequence)			    && (reply.conn_low == request.conn_low)/* seem to get wrong task from NW311 && (reply.task      == request.task) */			    && (reply.conn_high == request.conn_high)))) {			if (major_timeout_seen)				printk(KERN_NOTICE "NCP server OK\n");			break;		}		/* JEJB/JSP 2/7/94		 * we have xid mismatch, so discard the packet and start		 * again.  What a hack! but I can't call recvfrom with		 * a null buffer yet. */		_recv(sock, (void *) &reply, sizeof(reply), MSG_DONTWAIT);		DPRINTK("ncp_rpc_call: reply mismatch\n");		goto re_select;	}	/* 	 * we have the correct reply, so read into the correct place and	 * return it	 */	result = _recv(sock, (void *)reply_buf, max_reply_size, MSG_DONTWAIT);	if (result < 0) {		printk(KERN_WARNING "NCP: notice message: result=%d\n", result);	} else if (result < sizeof(struct ncp_reply_header)) {		printk(KERN_ERR "NCP: just caught a too small read memory size..., "		       "email to NET channel\n");		printk(KERN_ERR "NCP: result=%d\n", result);		result = -EIO;	}	return result;}static int do_tcp_rcv(struct ncp_server *server, void *buffer, size_t len) {	poll_table wait_table;	struct file *file;	struct socket *sock;	int init_timeout;	size_t dataread;	int result = 0;		file = server->ncp_filp;	sock = &file->f_dentry->d_inode->u.socket_i;		dataread = 0;	init_timeout = server->m.time_out * 20;		/* hard-mounted volumes have no timeout, except connection close... */	if (!(server->m.flags & NCP_MOUNT_SOFT))		init_timeout = 0x7FFF0000;	while (len) {		poll_initwait(&wait_table);		/* mb() is not necessary because ->poll() will serialize		   instructions adding the wait_table waitqueues in the		   waitqueue-head before going to calculate the mask-retval. */		__set_current_state(TASK_INTERRUPTIBLE);		if (!(sock->ops->poll(file, sock, &wait_table) & POLLIN)) {			init_timeout = schedule_timeout(init_timeout);			poll_freewait(&wait_table);			current->state = TASK_RUNNING;			if (signal_pending(current)) {				return -ERESTARTSYS;			}			if (!init_timeout) {				return -EIO;			}			if(wait_table.error) {				return wait_table.error;			}		} else {			poll_freewait(&wait_table);		}		current->state = TASK_RUNNING;		result = _recv(sock, buffer, len, MSG_DONTWAIT);

⌨️ 快捷键说明

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