/*
 *  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
 *
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/time.h>
#include <linux/errno.h>
#include <linux/socket.h>
#include <linux/fcntl.h>
#include <linux/stat.h>
#include <linux/string.h>
#include <linux/sched/signal.h>
#include <linux/uaccess.h>
#include <linux/in.h>
#include <linux/net.h>
#include <linux/mm.h>
#include <linux/netdevice.h>
#include <linux/signal.h>
#include <linux/slab.h>
#include <net/scm.h>
#include <net/sock.h>
#include <linux/ipx.h>
#include <linux/poll.h>
#include <linux/file.h>

#include "ncp_fs.h"

#include "ncpsign_kernel.h"

static int _recv(struct socket *sock, void *buf, int size, unsigned flags)
{
	struct msghdr msg = {NULL, };
	struct kvec iov = {buf, size};
	return kernel_recvmsg(sock, &msg, &iov, 1, size, flags);
}

static inline int do_send(struct socket *sock, struct kvec *vec, int count,
			  int len, unsigned flags)
{
	struct msghdr msg = { .msg_flags = flags };
	return kernel_sendmsg(sock, &msg, vec, count, len);
}

static int _send(struct socket *sock, const void *buff, int len)
{
	struct kvec vec;
	vec.iov_base = (void *) buff;
	vec.iov_len = len;
	return do_send(sock, &vec, 1, len, 0);
}

struct ncp_request_reply {
	struct list_head req;
	wait_queue_head_t wq;
	atomic_t refs;
	unsigned char* reply_buf;
	size_t datalen;
	int result;
	enum { RQ_DONE, RQ_INPROGRESS, RQ_QUEUED, RQ_IDLE, RQ_ABANDONED } status;
	struct kvec* tx_ciov;
	size_t tx_totallen;
	size_t tx_iovlen;
	struct kvec tx_iov[3];
	u_int16_t tx_type;
	u_int32_t sign[6];
};

static inline struct ncp_request_reply* ncp_alloc_req(void)
{
	struct ncp_request_reply *req;

	req = kmalloc(sizeof(struct ncp_request_reply), GFP_KERNEL);
	if (!req)
		return NULL;

	init_waitqueue_head(&req->wq);
	atomic_set(&req->refs, (1));
	req->status = RQ_IDLE;

	return req;
}

static void ncp_req_get(struct ncp_request_reply *req)
{
	atomic_inc(&req->refs);
}

static void ncp_req_put(struct ncp_request_reply *req)
{
	if (atomic_dec_and_test(&req->refs))
		kfree(req);
}

void ncp_tcp_data_ready(struct sock *sk)
{
	struct ncp_server *server = sk->sk_user_data;

	server->data_ready(sk);
	schedule_work(&server->rcv.tq);
}

void ncp_tcp_error_report(struct sock *sk)
{
	struct ncp_server *server = sk->sk_user_data;
	
	server->error_report(sk);
	schedule_work(&server->rcv.tq);
}

void ncp_tcp_write_space(struct sock *sk)
{
	struct ncp_server *server = sk->sk_user_data;
	
	/* We do not need any locking: we first set tx.creq, and then we do sendmsg,
	   not vice versa... */
	server->write_space(sk);
	if (server->tx.creq)
		schedule_work(&server->tx.tq);
}

void ncpdgram_timeout_call(unsigned long v)
{
	struct ncp_server *server = (void*)v;
	
	schedule_work(&server->timeout_tq);
}

static inline void ncp_finish_request(struct ncp_server *server, struct ncp_request_reply *req, int result)
{
	req->result = result;
	if (req->status != RQ_ABANDONED)
		memcpy(req->reply_buf, server->rxbuf, req->datalen);
	req->status = RQ_DONE;
	wake_up_all(&req->wq);
	ncp_req_put(req);
}

static void __abort_ncp_connection(struct ncp_server *server)
{
	struct ncp_request_reply *req;

	ncp_invalidate_conn(server);
	del_timer(&server->timeout_tm);
	while (!list_empty(&server->tx.requests)) {
		req = list_entry(server->tx.requests.next, struct ncp_request_reply, req);
		
		list_del_init(&req->req);
		ncp_finish_request(server, req, -EIO);
	}
	req = server->rcv.creq;
	if (req) {
		server->rcv.creq = NULL;
		ncp_finish_request(server, req, -EIO);
		server->rcv.ptr = NULL;
		server->rcv.state = 0;
	}
	req = server->tx.creq;
	if (req) {
		server->tx.creq = NULL;
		ncp_finish_request(server, req, -EIO);
	}
}

static inline int get_conn_number(struct ncp_reply_header *rp)
{
	return rp->conn_low | (rp->conn_high << 8);
}

static inline void __ncp_abort_request(struct ncp_server *server, struct ncp_request_reply *req, int err)
{
	/* If req is done, we got signal, but we also received answer... */
	switch (req->status) {
		case RQ_IDLE:
		case RQ_DONE:
			break;
		case RQ_QUEUED:
			list_del_init(&req->req);
			ncp_finish_request(server, req, err);
			break;
		case RQ_INPROGRESS:
			req->status = RQ_ABANDONED;
			break;
		case RQ_ABANDONED:
			break;
	}
}

static inline void ncp_abort_request(struct ncp_server *server, struct ncp_request_reply *req, int err)
{
	mutex_lock(&server->rcv.creq_mutex);
	__ncp_abort_request(server, req, err);
	mutex_unlock(&server->rcv.creq_mutex);
}

static inline void __ncptcp_abort(struct ncp_server *server)
{
	__abort_ncp_connection(server);
}

static int ncpdgram_send(struct socket *sock, struct ncp_request_reply *req)
{
	struct kvec vec[3];
	/* sock_sendmsg updates iov pointers for us :-( */
	memcpy(vec, req->tx_ciov, req->tx_iovlen * sizeof(vec[0]));
	return do_send(sock, vec, req->tx_iovlen,
		       req->tx_totallen, MSG_DONTWAIT);
}

static void __ncptcp_try_send(struct ncp_server *server)
{
	struct ncp_request_reply *rq;
	struct kvec *iov;
	struct kvec iovc[3];
	int result;

	rq = server->tx.creq;
	if (!rq)
		return;

	/* sock_sendmsg updates iov pointers for us :-( */
	memcpy(iovc, rq->tx_ciov, rq->tx_iovlen * sizeof(iov[0]));
	result = do_send(server->ncp_sock, iovc, rq->tx_iovlen,
			 rq->tx_totallen, MSG_NOSIGNAL | MSG_DONTWAIT);

	if (result == -EAGAIN)
		return;

	if (result < 0) {
		pr_err("tcp: Send failed: %d\n", result);
		__ncp_abort_request(server, rq, result);
		return;
	}
	if (result >= rq->tx_totallen) {
		server->rcv.creq = rq;
		server->tx.creq = NULL;
		return;
	}
	rq->tx_totallen -= result;
	iov = rq->tx_ciov;
	while (iov->iov_len <= result) {
		result -= iov->iov_len;
		iov++;
		rq->tx_iovlen--;
	}
	iov->iov_base += result;
	iov->iov_len -= result;
	rq->tx_ciov = iov;
}

static inline void ncp_init_header(struct ncp_server *server, struct ncp_request_reply *req, struct ncp_request_header *h)
{
	req->status = RQ_INPROGRESS;
	h->conn_low = server->connection;
	h->conn_high = server->connection >> 8;
	h->sequence = ++server->sequence;
}
	
static void ncpdgram_start_request(struct ncp_server *server, struct ncp_request_reply *req)
{
	size_t signlen;
	struct ncp_request_header* h;
	
	req->tx_ciov = req->tx_iov + 1;

	h = req->tx_iov[1].iov_base;
	ncp_init_header(server, req, h);
	signlen = sign_packet(server, req->tx_iov[1].iov_base + sizeof(struct ncp_request_header) - 1, 
			req->tx_iov[1].iov_len - sizeof(struct ncp_request_header) + 1,
			cpu_to_le32(req->tx_totallen), req->sign);
	if (signlen) {
		req->tx_ciov[1].iov_base = req->sign;
		req->tx_ciov[1].iov_len = signlen;
		req->tx_iovlen += 1;
		req->tx_totallen += signlen;
	}
	server->rcv.creq = req;
	server->timeout_last = server->m.time_out;
	server->timeout_retries = server->m.retry_count;
	ncpdgram_send(server->ncp_sock, req);
	mod_timer(&server->timeout_tm, jiffies + server->m.time_out);
}

#define NCP_TCP_XMIT_MAGIC	(0x446D6454)
#define NCP_TCP_XMIT_VERSION	(1)
#define NCP_TCP_RCVD_MAGIC	(0x744E6350)

static void ncptcp_start_request(struct ncp_server *server, struct ncp_request_reply *req)
{
	size_t signlen;
	struct ncp_request_header* h;

	req->tx_ciov = req->tx_iov;
	h = req->tx_iov[1].iov_base;
	ncp_init_header(server, req, h);
	signlen = sign_packet(server, req->tx_iov[1].iov_base + sizeof(struct ncp_request_header) - 1,
			req->tx_iov[1].iov_len - sizeof(struct ncp_request_header) + 1,
			cpu_to_be32(req->tx_totallen + 24), req->sign + 4) + 16;

	req->sign[0] = htonl(NCP_TCP_XMIT_MAGIC);
	req->sign[1] = htonl(req->tx_totallen + signlen);
	req->sign[2] = htonl(NCP_TCP_XMIT_VERSION);
	req->sign[3] = htonl(req->datalen + 8);
	req->tx_iov[0].iov_base = req->sign;
	req->tx_iov[0].iov_len = signlen;
	req->tx_iovlen += 1;
	req->tx_totallen += signlen;

	server->tx.creq = req;
	__ncptcp_try_send(server);
}

static inline void __ncp_start_request(struct ncp_server *server, struct ncp_request_reply *req)
{
	/* we copy the data so that we do not depend on the caller
	   staying alive */
	memcpy(server->txbuf, req->tx_iov[1].iov_base, req->tx_iov[1].iov_len);
	req->tx_iov[1].iov_base = server->txbuf;

	if (server->ncp_sock->type == SOCK_STREAM)
		ncptcp_start_request(server, req);
	else
		ncpdgram_start_request(server, req);
}

static int ncp_add_request(struct ncp_server *server, struct ncp_request_reply *req)
{
	mutex_lock(&server->rcv.creq_mutex);
	if (!ncp_conn_valid(server)) {
		mutex_unlock(&server->rcv.creq_mutex);
		pr_err("tcp: Server died\n");
		return -EIO;
	}
	ncp_req_get(req);
	if (server->tx.creq || server->rcv.creq) {
		req->status = RQ_QUEUED;
		list_add_tail(&req->req, &server->tx.requests);
		mutex_unlock(&server->rcv.creq_mutex);
		return 0;
	}
	__ncp_start_request(server, req);
	mutex_unlock(&server->rcv.creq_mutex);
	return 0;
}

static void __ncp_next_request(struct ncp_server *server)
{
	struct ncp_request_reply *req;

	server->rcv.creq = NULL;
	if (list_empty(&server->tx.requests)) {
		return;
	}
	req = list_entry(server->tx.requests.next, struct ncp_request_reply, req);
	list_del_init(&req->req);
	__ncp_start_request(server, req);
}

static void info_server(struct ncp_server *server, unsigned int id, const void * data, size_t len)
{
	if (server->info_sock) {
		struct kvec iov[2];
		__be32 hdr[2];
	
		hdr[0] = cpu_to_be32(len + 8);
		hdr[1] = cpu_to_be32(id);
	
		iov[0].iov_base = hdr;
		iov[0].iov_len = 8;
		iov[1].iov_base = (void *) data;
		iov[1].iov_len = len;

		do_send(server->info_sock, iov, 2, len + 8, MSG_NOSIGNAL);
	}
}

void ncpdgram_rcv_proc(struct work_struct *work)
{
	struct ncp_server *server =
		container_of(work, struct ncp_server, rcv.tq);
	struct socket* sock;
	
	sock = server->ncp_sock;
	
	while (1) {
		struct ncp_reply_header reply;
		int result;

		result = _recv(sock, &reply, sizeof(reply), MSG_PEEK | MSG_DONTWAIT);
		if (result < 0) {
			break;
		}
		if (result >= sizeof(reply)) {
			struct ncp_request_reply *req;
	
			if (reply.type == NCP_WATCHDOG) {
				unsigned char buf[10];

				if (server->connection != get_conn_number(&reply)) {
					goto drop;
				}
				result = _recv(sock, buf, sizeof(buf), MSG_DONTWAIT);
				if (result < 0) {
					ncp_dbg(1, "recv failed with %d\n", result);
					continue;
				}
				if (result < 10) {
					ncp_dbg(1, "too short (%u) watchdog packet\n", result);
					continue;
				}
				if (buf[9] != '?') {
					ncp_dbg(1, "bad signature (%02X) in watchdog packet\n", buf[9]);
					continue;
				}
				buf[9] = 'Y';
				_send(sock, buf, sizeof(buf));
				continue;
			}
			if (reply.type != NCP_POSITIVE_ACK && reply.type != NCP_REPLY) {
				result = _recv(sock, server->unexpected_packet.data, sizeof(server->unexpected_packet.data), MSG_DONTWAIT);
				if (result < 0) {
					continue;
				}
				info_server(server, 0, server->unexpected_packet.data, result);
				continue;
			}
			mutex_lock(&server->rcv.creq_mutex);
			req = server->rcv.creq;
			if (req && (req->tx_type == NCP_ALLOC_SLOT_REQUEST || (server->sequence == reply.sequence && 
					server->connection == get_conn_number(&reply)))) {
				if (reply.type == NCP_POSITIVE_ACK) {
					server->timeout_retries = server->m.retry_count;
					server->timeout_last = NCP_MAX_RPC_TIMEOUT;
					mod_timer(&server->timeout_tm, jiffies + NCP_MAX_RPC_TIMEOUT);
				} else if (reply.type == NCP_REPLY) {
					result = _recv(sock, server->rxbuf, req->datalen, MSG_DONTWAIT);
#ifdef CONFIG_NCPFS_PACKET_SIGNING
					if (result >= 0 && server->sign_active && req->tx_type != NCP_DEALLOC_SLOT_REQUEST) {
						if (result < 8 + 8) {
							result = -EIO;
						} else {
							unsigned int hdrl;
							
							result -= 8;
							hdrl = sock->sk->sk_family == AF_INET ? 8 : 6;
							if (sign_verify_reply(server, server->rxbuf + hdrl, result - hdrl, cpu_to_le32(result), server->rxbuf + result)) {
								pr_info("Signature violation\n");
								result = -EIO;
							}
						}
					}
#endif
					del_timer(&server->timeout_tm);
				     	server->rcv.creq = NULL;
					ncp_finish_request(server, req, result);
					__ncp_next_request(server);
					mutex_unlock(&server->rcv.creq_mutex);
					continue;
				}
			}
			mutex_unlock(&server->rcv.creq_mutex);
		}
drop:;		
		_recv(sock, &reply, sizeof(reply), MSG_DONTWAIT);
	}
}

static void __ncpdgram_timeout_proc(struct ncp_server *server)
{
	/* If timer is pending, we are processing another request... */
	if (!timer_pending(&server->timeout_tm)) {
		struct ncp_request_reply* req;
		
		req = server->rcv.creq;
		if (req) {
			int timeout;
			
			if (server->m.flags & NCP_MOUNT_SOFT) {
				if (server->timeout_retries-- == 0) {
					__ncp_abort_request(server, req, -ETIMEDOUT);
					return;
				}
			}
			/* Ignore errors */
			ncpdgram_send(server->ncp_sock, req);
			timeout = server->timeout_last << 1;
			if (timeout > NCP_MAX_RPC_TIMEOUT) {
				timeout = NCP_MAX_RPC_TIMEOUT;
			}
			server->timeout_last = timeout;
			mod_timer(&server->timeout_tm, jiffies + timeout);
		}
	}
}

void ncpdgram_timeout_proc(struct work_struct *work)
{
	struct ncp_server *server =
		container_of(work, struct ncp_server, timeout_tq);
	mutex_lock(&server->rcv.creq_mutex);
	__ncpdgram_timeout_proc(server);
	mutex_unlock(&server->rcv.creq_mutex);
}

static int do_tcp_rcv(struct ncp_server *server, void *buffer, size_t len)
{
	int result;
	
	if (buffer) {
		result = _recv(server->ncp_sock, buffer, len, MSG_DONTWAIT);
	} else {
		static unsigned char dummy[1024];
			
		if (len > sizeof(dummy)) {
			len = sizeof(dummy);
		}
		result = _recv(server->ncp_sock, dummy, len, MSG_DONTWAIT);
	}
	if (result < 0) {
		return result;
	}
	if (result > len) {
		pr_err("tcp: bug in recvmsg (%u > %zu)\n", result, len);
		return -EIO;			
	}
	return result;
}	

static int __ncptcp_rcv_proc(struct ncp_server *server)
{
	/* We have to check the result, so store the complete header */
	while (1) {
		int result;
		struct ncp_request_reply *req;
		int datalen;
		int type;

		while (server->rcv.len) {
			result = do_tcp_rcv(server, server->rcv.ptr, server->rcv.len);
			if (result == -EAGAIN) {
				return 0;
			}
			if (result <= 0) {
				req = server->rcv.creq;
				if (req) {
					__ncp_abort_request(server, req, -EIO);
				} else {
					__ncptcp_abort(server);
				}
				if (result < 0) {
					pr_err("tcp: error in recvmsg: %d\n", result);
				} else {
					ncp_dbg(1, "tcp: EOF\n");
				}
				return -EIO;
			}
			if (server->rcv.ptr) {
				server->rcv.ptr += result;
			}
			server->rcv.len -= result;
		}
		switch (server->rcv.state) {
			case 0:
				if (server->rcv.buf.magic != htonl(NCP_TCP_RCVD_MAGIC)) {
					pr_err("tcp: Unexpected reply type %08X\n", ntohl(server->rcv.buf.magic));
					__ncptcp_abort(server);
					return -EIO;
				}
				datalen = ntohl(server->rcv.buf.len) & 0x0FFFFFFF;
				if (datalen < 10) {
					pr_err("tcp: Unexpected reply len %d\n", datalen);
					__ncptcp_abort(server);
					return -EIO;
				}
#ifdef CONFIG_NCPFS_PACKET_SIGNING				
				if (server->sign_active) {
					if (datalen < 18) {
						pr_err("tcp: Unexpected reply len %d\n", datalen);
						__ncptcp_abort(server);
						return -EIO;
					}
					server->rcv.buf.len = datalen - 8;
					server->rcv.ptr = (unsigned char*)&server->rcv.buf.p1;
					server->rcv.len = 8;
					server->rcv.state = 4;
					break;
				}
#endif				
				type = ntohs(server->rcv.buf.type);
#ifdef CONFIG_NCPFS_PACKET_SIGNING				
cont:;				
#endif
				if (type != NCP_REPLY) {
					if (datalen - 8 <= sizeof(server->unexpected_packet.data)) {
						*(__u16*)(server->unexpected_packet.data) = htons(type);
						server->unexpected_packet.len = datalen - 8;

						server->rcv.state = 5;
						server->rcv.ptr = server->unexpected_packet.data + 2;
						server->rcv.len = datalen - 10;
						break;
					}					
					ncp_dbg(1, "tcp: Unexpected NCP type %02X\n", type);
skipdata2:;
					server->rcv.state = 2;
skipdata:;
					server->rcv.ptr = NULL;
					server->rcv.len = datalen - 10;
					break;
				}
				req = server->rcv.creq;
				if (!req) {
					ncp_dbg(1, "Reply without appropriate request\n");
					goto skipdata2;
				}
				if (datalen > req->datalen + 8) {
					pr_err("tcp: Unexpected reply len %d (expected at most %zd)\n", datalen, req->datalen + 8);
					server->rcv.state = 3;
					goto skipdata;
				}
				req->datalen = datalen - 8;
				((struct ncp_reply_header*)server->rxbuf)->type = NCP_REPLY;
				server->rcv.ptr = server->rxbuf + 2;
				server->rcv.len = datalen - 10;
				server->rcv.state = 1;
				break;
#ifdef CONFIG_NCPFS_PACKET_SIGNING				
			case 4:
				datalen = server->rcv.buf.len;
				type = ntohs(server->rcv.buf.type2);
				goto cont;
#endif
			case 1:
				req = server->rcv.creq;
				if (req->tx_type != NCP_ALLOC_SLOT_REQUEST) {
					if (((struct ncp_reply_header*)server->rxbuf)->sequence != server->sequence) {
						pr_err("tcp: Bad sequence number\n");
						__ncp_abort_request(server, req, -EIO);
						return -EIO;
					}
					if ((((struct ncp_reply_header*)server->rxbuf)->conn_low | (((struct ncp_reply_header*)server->rxbuf)->conn_high << 8)) != server->connection) {
						pr_err("tcp: Connection number mismatch\n");
						__ncp_abort_request(server, req, -EIO);
						return -EIO;
					}
				}
#ifdef CONFIG_NCPFS_PACKET_SIGNING				
				if (server->sign_active && req->tx_type != NCP_DEALLOC_SLOT_REQUEST) {
					if (sign_verify_reply(server, server->rxbuf + 6, req->datalen - 6, cpu_to_be32(req->datalen + 16), &server->rcv.buf.type)) {
						pr_err("tcp: Signature violation\n");
						__ncp_abort_request(server, req, -EIO);
						return -EIO;
					}
				}
#endif				
				ncp_finish_request(server, req, req->datalen);
			nextreq:;
				__ncp_next_request(server);
			case 2:
			next:;
				server->rcv.ptr = (unsigned char*)&server->rcv.buf;
				server->rcv.len = 10;
				server->rcv.state = 0;
				break;
			case 3:
				ncp_finish_request(server, server->rcv.creq, -EIO);
				goto nextreq;
			case 5:
				info_server(server, 0, server->unexpected_packet.data, server->unexpected_packet.len);
				goto next;
		}
	}
}

void ncp_tcp_rcv_proc(struct work_struct *work)
{
	struct ncp_server *server =
		container_of(work, struct ncp_server, rcv.tq);

	mutex_lock(&server->rcv.creq_mutex);
	__ncptcp_rcv_proc(server);
	mutex_unlock(&server->rcv.creq_mutex);
}

void ncp_tcp_tx_proc(struct work_struct *work)
{
	struct ncp_server *server =
		container_of(work, struct ncp_server, tx.tq);
	
	mutex_lock(&server->rcv.creq_mutex);
	__ncptcp_try_send(server);
	mutex_unlock(&server->rcv.creq_mutex);
}

static int do_ncp_rpc_call(struct ncp_server *server, int size,
		unsigned char* reply_buf, int max_reply_size)
{
	int result;
	struct ncp_request_reply *req;

	req = ncp_alloc_req();
	if (!req)
		return -ENOMEM;

	req->reply_buf = reply_buf;
	req->datalen = max_reply_size;
	req->tx_iov[1].iov_base = server->packet;
	req->tx_iov[1].iov_len = size;
	req->tx_iovlen = 1;
	req->tx_totallen = size;
	req->tx_type = *(u_int16_t*)server->packet;

	result = ncp_add_request(server, req);
	if (result < 0)
		goto out;

	if (wait_event_interruptible(req->wq, req->status == RQ_DONE)) {
		ncp_abort_request(server, req, -EINTR);
		result = -EINTR;
		goto out;
	}

	result = req->result;

out:
	ncp_req_put(req);

	return result;
}

/*
 * We need the server to be locked here, so check!
 */

static int ncp_do_request(struct ncp_server *server, int size,
		void* reply, int max_reply_size)
{
	int result;

	if (server->lock == 0) {
		pr_err("Server not locked!\n");
		return -EIO;
	}
	if (!ncp_conn_valid(server)) {
		return -EIO;
	}
	{
		sigset_t old_set;
		unsigned long mask, flags;

		spin_lock_irqsave(&current->sighand->siglock, flags);
		old_set = current->blocked;
		if (current->flags & PF_EXITING)
			mask = 0;
		else
			mask = sigmask(SIGKILL);
		if (server->m.flags & NCP_MOUNT_INTR) {
			/* FIXME: This doesn't seem right at all.  So, like,
			   we can't handle SIGINT and get whatever to stop?
			   What if we've blocked it ourselves?  What about
			   alarms?  Why, in fact, are we mucking with the
			   sigmask at all? -- r~ */
			if (current->sighand->action[SIGINT - 1].sa.sa_handler == SIG_DFL)
				mask |= sigmask(SIGINT);
			if (current->sighand->action[SIGQUIT - 1].sa.sa_handler == SIG_DFL)
				mask |= sigmask(SIGQUIT);
		}
		siginitsetinv(&current->blocked, mask);
		recalc_sigpending();
		spin_unlock_irqrestore(&current->sighand->siglock, flags);
		
		result = do_ncp_rpc_call(server, size, reply, max_reply_size);

		spin_lock_irqsave(&current->sighand->siglock, flags);
		current->blocked = old_set;
		recalc_sigpending();
		spin_unlock_irqrestore(&current->sighand->siglock, flags);
	}

	ncp_dbg(2, "do_ncp_rpc_call returned %d\n", result);

	return result;
}

/* ncp_do_request assures that at least a complete reply header is
 * received. It assumes that server->current_size contains the ncp
 * request size
 */
int ncp_request2(struct ncp_server *server, int function, 
		void* rpl, int size)
{
	struct ncp_request_header *h;
	struct ncp_reply_header* reply = rpl;
	int result;

	h = (struct ncp_request_header *) (server->packet);
	if (server->has_subfunction != 0) {
		*(__u16 *) & (h->data[0]) = htons(server->current_size - sizeof(*h) - 2);
	}
	h->type = NCP_REQUEST;
	/*
	 * The server shouldn't know or care what task is making a
	 * request, so we always use the same task number.
	 */
	h->task = 2; /* (current->pid) & 0xff; */
	h->function = function;

	result = ncp_do_request(server, server->current_size, reply, size);
	if (result < 0) {
		ncp_dbg(1, "ncp_request_error: %d\n", result);
		goto out;
	}
	server->completion = reply->completion_code;
	server->conn_status = reply->connection_state;
	server->reply_size = result;
	server->ncp_reply_size = result - sizeof(struct ncp_reply_header);

	result = reply->completion_code;

	if (result != 0)
		ncp_vdbg("completion code=%x\n", result);
out:
	return result;
}

int ncp_connect(struct ncp_server *server)
{
	struct ncp_request_header *h;
	int result;

	server->connection = 0xFFFF;
	server->sequence = 255;

	h = (struct ncp_request_header *) (server->packet);
	h->type = NCP_ALLOC_SLOT_REQUEST;
	h->task		= 2; /* see above */
	h->function	= 0;

	result = ncp_do_request(server, sizeof(*h), server->packet, server->packet_size);
	if (result < 0)
		goto out;
	server->connection = h->conn_low + (h->conn_high * 256);
	result = 0;
out:
	return result;
}

int ncp_disconnect(struct ncp_server *server)
{
	struct ncp_request_header *h;

	h = (struct ncp_request_header *) (server->packet);
	h->type = NCP_DEALLOC_SLOT_REQUEST;
	h->task		= 2; /* see above */
	h->function	= 0;

	return ncp_do_request(server, sizeof(*h), server->packet, server->packet_size);
}

void ncp_lock_server(struct ncp_server *server)
{
	mutex_lock(&server->mutex);
	if (server->lock)
		pr_warn("%s: was locked!\n", __func__);
	server->lock = 1;
}

void ncp_unlock_server(struct ncp_server *server)
{
	if (!server->lock) {
		pr_warn("%s: was not locked!\n", __func__);
		return;
	}
	server->lock = 0;
	mutex_unlock(&server->mutex);
}
