2 * linux/fs/ncpfs/sock.c
4 * Copyright (C) 1992, 1993 Rick Sladkey
6 * Modified 1995, 1996 by Volker Lendecke to be usable for ncp
7 * Modified 1997 Peter Waltenberg, Bill Hawes, David Woodhouse for 2.1 dcache
12 #include <linux/time.h>
13 #include <linux/errno.h>
14 #include <linux/socket.h>
15 #include <linux/fcntl.h>
16 #include <linux/stat.h>
17 #include <linux/string.h>
18 #include <asm/uaccess.h>
20 #include <linux/net.h>
22 #include <linux/netdevice.h>
23 #include <linux/signal.h>
24 #include <linux/slab.h>
27 #include <linux/ipx.h>
28 #include <linux/poll.h>
29 #include <linux/file.h>
31 #include <linux/ncp_fs.h>
33 #include "ncpsign_kernel.h"
35 static int _recv(struct socket
*sock
, void *buf
, int size
, unsigned flags
)
37 struct msghdr msg
= {NULL
, };
38 struct kvec iov
= {buf
, size
};
39 return kernel_recvmsg(sock
, &msg
, &iov
, 1, size
, flags
);
42 static inline int do_send(struct socket
*sock
, struct kvec
*vec
, int count
,
43 int len
, unsigned flags
)
45 struct msghdr msg
= { .msg_flags
= flags
};
46 return kernel_sendmsg(sock
, &msg
, vec
, count
, len
);
49 static int _send(struct socket
*sock
, const void *buff
, int len
)
52 vec
.iov_base
= (void *) buff
;
54 return do_send(sock
, &vec
, 1, len
, 0);
57 struct ncp_request_reply
{
61 unsigned char* reply_buf
;
64 enum { RQ_DONE
, RQ_INPROGRESS
, RQ_QUEUED
, RQ_IDLE
, RQ_ABANDONED
} status
;
68 struct kvec tx_iov
[3];
73 static inline struct ncp_request_reply
* ncp_alloc_req(void)
75 struct ncp_request_reply
*req
;
77 req
= kmalloc(sizeof(struct ncp_request_reply
), GFP_KERNEL
);
81 init_waitqueue_head(&req
->wq
);
82 atomic_set(&req
->refs
, (1));
83 req
->status
= RQ_IDLE
;
88 static void ncp_req_get(struct ncp_request_reply
*req
)
90 atomic_inc(&req
->refs
);
93 static void ncp_req_put(struct ncp_request_reply
*req
)
95 if (atomic_dec_and_test(&req
->refs
))
99 void ncp_tcp_data_ready(struct sock
*sk
, int len
)
101 struct ncp_server
*server
= sk
->sk_user_data
;
103 server
->data_ready(sk
, len
);
104 schedule_work(&server
->rcv
.tq
);
107 void ncp_tcp_error_report(struct sock
*sk
)
109 struct ncp_server
*server
= sk
->sk_user_data
;
111 server
->error_report(sk
);
112 schedule_work(&server
->rcv
.tq
);
115 void ncp_tcp_write_space(struct sock
*sk
)
117 struct ncp_server
*server
= sk
->sk_user_data
;
119 /* We do not need any locking: we first set tx.creq, and then we do sendmsg,
121 server
->write_space(sk
);
123 schedule_work(&server
->tx
.tq
);
126 void ncpdgram_timeout_call(unsigned long v
)
128 struct ncp_server
*server
= (void*)v
;
130 schedule_work(&server
->timeout_tq
);
133 static inline void ncp_finish_request(struct ncp_server
*server
, struct ncp_request_reply
*req
, int result
)
135 req
->result
= result
;
136 if (req
->status
!= RQ_ABANDONED
)
137 memcpy(req
->reply_buf
, server
->rxbuf
, req
->datalen
);
138 req
->status
= RQ_DONE
;
139 wake_up_all(&req
->wq
);
143 static void __abort_ncp_connection(struct ncp_server
*server
)
145 struct ncp_request_reply
*req
;
147 ncp_invalidate_conn(server
);
148 del_timer(&server
->timeout_tm
);
149 while (!list_empty(&server
->tx
.requests
)) {
150 req
= list_entry(server
->tx
.requests
.next
, struct ncp_request_reply
, req
);
152 list_del_init(&req
->req
);
153 ncp_finish_request(server
, req
, -EIO
);
155 req
= server
->rcv
.creq
;
157 server
->rcv
.creq
= NULL
;
158 ncp_finish_request(server
, req
, -EIO
);
159 server
->rcv
.ptr
= NULL
;
160 server
->rcv
.state
= 0;
162 req
= server
->tx
.creq
;
164 server
->tx
.creq
= NULL
;
165 ncp_finish_request(server
, req
, -EIO
);
169 static inline int get_conn_number(struct ncp_reply_header
*rp
)
171 return rp
->conn_low
| (rp
->conn_high
<< 8);
174 static inline void __ncp_abort_request(struct ncp_server
*server
, struct ncp_request_reply
*req
, int err
)
176 /* If req is done, we got signal, but we also received answer... */
177 switch (req
->status
) {
182 list_del_init(&req
->req
);
183 ncp_finish_request(server
, req
, err
);
186 req
->status
= RQ_ABANDONED
;
193 static inline void ncp_abort_request(struct ncp_server
*server
, struct ncp_request_reply
*req
, int err
)
195 mutex_lock(&server
->rcv
.creq_mutex
);
196 __ncp_abort_request(server
, req
, err
);
197 mutex_unlock(&server
->rcv
.creq_mutex
);
200 static inline void __ncptcp_abort(struct ncp_server
*server
)
202 __abort_ncp_connection(server
);
205 static int ncpdgram_send(struct socket
*sock
, struct ncp_request_reply
*req
)
208 /* sock_sendmsg updates iov pointers for us :-( */
209 memcpy(vec
, req
->tx_ciov
, req
->tx_iovlen
* sizeof(vec
[0]));
210 return do_send(sock
, vec
, req
->tx_iovlen
,
211 req
->tx_totallen
, MSG_DONTWAIT
);
214 static void __ncptcp_try_send(struct ncp_server
*server
)
216 struct ncp_request_reply
*rq
;
221 rq
= server
->tx
.creq
;
225 /* sock_sendmsg updates iov pointers for us :-( */
226 memcpy(iovc
, rq
->tx_ciov
, rq
->tx_iovlen
* sizeof(iov
[0]));
227 result
= do_send(server
->ncp_sock
, iovc
, rq
->tx_iovlen
,
228 rq
->tx_totallen
, MSG_NOSIGNAL
| MSG_DONTWAIT
);
230 if (result
== -EAGAIN
)
234 printk(KERN_ERR
"ncpfs: tcp: Send failed: %d\n", result
);
235 __ncp_abort_request(server
, rq
, result
);
238 if (result
>= rq
->tx_totallen
) {
239 server
->rcv
.creq
= rq
;
240 server
->tx
.creq
= NULL
;
243 rq
->tx_totallen
-= result
;
245 while (iov
->iov_len
<= result
) {
246 result
-= iov
->iov_len
;
250 iov
->iov_base
+= result
;
251 iov
->iov_len
-= result
;
255 static inline void ncp_init_header(struct ncp_server
*server
, struct ncp_request_reply
*req
, struct ncp_request_header
*h
)
257 req
->status
= RQ_INPROGRESS
;
258 h
->conn_low
= server
->connection
;
259 h
->conn_high
= server
->connection
>> 8;
260 h
->sequence
= ++server
->sequence
;
263 static void ncpdgram_start_request(struct ncp_server
*server
, struct ncp_request_reply
*req
)
266 struct ncp_request_header
* h
;
268 req
->tx_ciov
= req
->tx_iov
+ 1;
270 h
= req
->tx_iov
[1].iov_base
;
271 ncp_init_header(server
, req
, h
);
272 signlen
= sign_packet(server
, req
->tx_iov
[1].iov_base
+ sizeof(struct ncp_request_header
) - 1,
273 req
->tx_iov
[1].iov_len
- sizeof(struct ncp_request_header
) + 1,
274 cpu_to_le32(req
->tx_totallen
), req
->sign
);
276 req
->tx_ciov
[1].iov_base
= req
->sign
;
277 req
->tx_ciov
[1].iov_len
= signlen
;
279 req
->tx_totallen
+= signlen
;
281 server
->rcv
.creq
= req
;
282 server
->timeout_last
= server
->m
.time_out
;
283 server
->timeout_retries
= server
->m
.retry_count
;
284 ncpdgram_send(server
->ncp_sock
, req
);
285 mod_timer(&server
->timeout_tm
, jiffies
+ server
->m
.time_out
);
288 #define NCP_TCP_XMIT_MAGIC (0x446D6454)
289 #define NCP_TCP_XMIT_VERSION (1)
290 #define NCP_TCP_RCVD_MAGIC (0x744E6350)
292 static void ncptcp_start_request(struct ncp_server
*server
, struct ncp_request_reply
*req
)
295 struct ncp_request_header
* h
;
297 req
->tx_ciov
= req
->tx_iov
;
298 h
= req
->tx_iov
[1].iov_base
;
299 ncp_init_header(server
, req
, h
);
300 signlen
= sign_packet(server
, req
->tx_iov
[1].iov_base
+ sizeof(struct ncp_request_header
) - 1,
301 req
->tx_iov
[1].iov_len
- sizeof(struct ncp_request_header
) + 1,
302 cpu_to_be32(req
->tx_totallen
+ 24), req
->sign
+ 4) + 16;
304 req
->sign
[0] = htonl(NCP_TCP_XMIT_MAGIC
);
305 req
->sign
[1] = htonl(req
->tx_totallen
+ signlen
);
306 req
->sign
[2] = htonl(NCP_TCP_XMIT_VERSION
);
307 req
->sign
[3] = htonl(req
->datalen
+ 8);
308 req
->tx_iov
[0].iov_base
= req
->sign
;
309 req
->tx_iov
[0].iov_len
= signlen
;
311 req
->tx_totallen
+= signlen
;
313 server
->tx
.creq
= req
;
314 __ncptcp_try_send(server
);
317 static inline void __ncp_start_request(struct ncp_server
*server
, struct ncp_request_reply
*req
)
319 /* we copy the data so that we do not depend on the caller
321 memcpy(server
->txbuf
, req
->tx_iov
[1].iov_base
, req
->tx_iov
[1].iov_len
);
322 req
->tx_iov
[1].iov_base
= server
->txbuf
;
324 if (server
->ncp_sock
->type
== SOCK_STREAM
)
325 ncptcp_start_request(server
, req
);
327 ncpdgram_start_request(server
, req
);
330 static int ncp_add_request(struct ncp_server
*server
, struct ncp_request_reply
*req
)
332 mutex_lock(&server
->rcv
.creq_mutex
);
333 if (!ncp_conn_valid(server
)) {
334 mutex_unlock(&server
->rcv
.creq_mutex
);
335 printk(KERN_ERR
"ncpfs: tcp: Server died\n");
339 if (server
->tx
.creq
|| server
->rcv
.creq
) {
340 req
->status
= RQ_QUEUED
;
341 list_add_tail(&req
->req
, &server
->tx
.requests
);
342 mutex_unlock(&server
->rcv
.creq_mutex
);
345 __ncp_start_request(server
, req
);
346 mutex_unlock(&server
->rcv
.creq_mutex
);
350 static void __ncp_next_request(struct ncp_server
*server
)
352 struct ncp_request_reply
*req
;
354 server
->rcv
.creq
= NULL
;
355 if (list_empty(&server
->tx
.requests
)) {
358 req
= list_entry(server
->tx
.requests
.next
, struct ncp_request_reply
, req
);
359 list_del_init(&req
->req
);
360 __ncp_start_request(server
, req
);
363 static void info_server(struct ncp_server
*server
, unsigned int id
, const void * data
, size_t len
)
365 if (server
->info_sock
) {
369 hdr
[0] = cpu_to_be32(len
+ 8);
370 hdr
[1] = cpu_to_be32(id
);
372 iov
[0].iov_base
= hdr
;
374 iov
[1].iov_base
= (void *) data
;
375 iov
[1].iov_len
= len
;
377 do_send(server
->info_sock
, iov
, 2, len
+ 8, MSG_NOSIGNAL
);
381 void ncpdgram_rcv_proc(struct work_struct
*work
)
383 struct ncp_server
*server
=
384 container_of(work
, struct ncp_server
, rcv
.tq
);
387 sock
= server
->ncp_sock
;
390 struct ncp_reply_header reply
;
393 result
= _recv(sock
, &reply
, sizeof(reply
), MSG_PEEK
| MSG_DONTWAIT
);
397 if (result
>= sizeof(reply
)) {
398 struct ncp_request_reply
*req
;
400 if (reply
.type
== NCP_WATCHDOG
) {
401 unsigned char buf
[10];
403 if (server
->connection
!= get_conn_number(&reply
)) {
406 result
= _recv(sock
, buf
, sizeof(buf
), MSG_DONTWAIT
);
408 DPRINTK("recv failed with %d\n", result
);
412 DPRINTK("too short (%u) watchdog packet\n", result
);
416 DPRINTK("bad signature (%02X) in watchdog packet\n", buf
[9]);
420 _send(sock
, buf
, sizeof(buf
));
423 if (reply
.type
!= NCP_POSITIVE_ACK
&& reply
.type
!= NCP_REPLY
) {
424 result
= _recv(sock
, server
->unexpected_packet
.data
, sizeof(server
->unexpected_packet
.data
), MSG_DONTWAIT
);
428 info_server(server
, 0, server
->unexpected_packet
.data
, result
);
431 mutex_lock(&server
->rcv
.creq_mutex
);
432 req
= server
->rcv
.creq
;
433 if (req
&& (req
->tx_type
== NCP_ALLOC_SLOT_REQUEST
|| (server
->sequence
== reply
.sequence
&&
434 server
->connection
== get_conn_number(&reply
)))) {
435 if (reply
.type
== NCP_POSITIVE_ACK
) {
436 server
->timeout_retries
= server
->m
.retry_count
;
437 server
->timeout_last
= NCP_MAX_RPC_TIMEOUT
;
438 mod_timer(&server
->timeout_tm
, jiffies
+ NCP_MAX_RPC_TIMEOUT
);
439 } else if (reply
.type
== NCP_REPLY
) {
440 result
= _recv(sock
, server
->rxbuf
, req
->datalen
, MSG_DONTWAIT
);
441 #ifdef CONFIG_NCPFS_PACKET_SIGNING
442 if (result
>= 0 && server
->sign_active
&& req
->tx_type
!= NCP_DEALLOC_SLOT_REQUEST
) {
443 if (result
< 8 + 8) {
449 hdrl
= sock
->sk
->sk_family
== AF_INET
? 8 : 6;
450 if (sign_verify_reply(server
, server
->rxbuf
+ hdrl
, result
- hdrl
, cpu_to_le32(result
), server
->rxbuf
+ result
)) {
451 printk(KERN_INFO
"ncpfs: Signature violation\n");
457 del_timer(&server
->timeout_tm
);
458 server
->rcv
.creq
= NULL
;
459 ncp_finish_request(server
, req
, result
);
460 __ncp_next_request(server
);
461 mutex_unlock(&server
->rcv
.creq_mutex
);
465 mutex_unlock(&server
->rcv
.creq_mutex
);
468 _recv(sock
, &reply
, sizeof(reply
), MSG_DONTWAIT
);
472 static void __ncpdgram_timeout_proc(struct ncp_server
*server
)
474 /* If timer is pending, we are processing another request... */
475 if (!timer_pending(&server
->timeout_tm
)) {
476 struct ncp_request_reply
* req
;
478 req
= server
->rcv
.creq
;
482 if (server
->m
.flags
& NCP_MOUNT_SOFT
) {
483 if (server
->timeout_retries
-- == 0) {
484 __ncp_abort_request(server
, req
, -ETIMEDOUT
);
489 ncpdgram_send(server
->ncp_sock
, req
);
490 timeout
= server
->timeout_last
<< 1;
491 if (timeout
> NCP_MAX_RPC_TIMEOUT
) {
492 timeout
= NCP_MAX_RPC_TIMEOUT
;
494 server
->timeout_last
= timeout
;
495 mod_timer(&server
->timeout_tm
, jiffies
+ timeout
);
500 void ncpdgram_timeout_proc(struct work_struct
*work
)
502 struct ncp_server
*server
=
503 container_of(work
, struct ncp_server
, timeout_tq
);
504 mutex_lock(&server
->rcv
.creq_mutex
);
505 __ncpdgram_timeout_proc(server
);
506 mutex_unlock(&server
->rcv
.creq_mutex
);
509 static int do_tcp_rcv(struct ncp_server
*server
, void *buffer
, size_t len
)
514 result
= _recv(server
->ncp_sock
, buffer
, len
, MSG_DONTWAIT
);
516 static unsigned char dummy
[1024];
518 if (len
> sizeof(dummy
)) {
521 result
= _recv(server
->ncp_sock
, dummy
, len
, MSG_DONTWAIT
);
527 printk(KERN_ERR
"ncpfs: tcp: bug in recvmsg (%u > %Zu)\n", result
, len
);
533 static int __ncptcp_rcv_proc(struct ncp_server
*server
)
535 /* We have to check the result, so store the complete header */
538 struct ncp_request_reply
*req
;
542 while (server
->rcv
.len
) {
543 result
= do_tcp_rcv(server
, server
->rcv
.ptr
, server
->rcv
.len
);
544 if (result
== -EAGAIN
) {
548 req
= server
->rcv
.creq
;
550 __ncp_abort_request(server
, req
, -EIO
);
552 __ncptcp_abort(server
);
555 printk(KERN_ERR
"ncpfs: tcp: error in recvmsg: %d\n", result
);
557 DPRINTK(KERN_ERR
"ncpfs: tcp: EOF\n");
561 if (server
->rcv
.ptr
) {
562 server
->rcv
.ptr
+= result
;
564 server
->rcv
.len
-= result
;
566 switch (server
->rcv
.state
) {
568 if (server
->rcv
.buf
.magic
!= htonl(NCP_TCP_RCVD_MAGIC
)) {
569 printk(KERN_ERR
"ncpfs: tcp: Unexpected reply type %08X\n", ntohl(server
->rcv
.buf
.magic
));
570 __ncptcp_abort(server
);
573 datalen
= ntohl(server
->rcv
.buf
.len
) & 0x0FFFFFFF;
575 printk(KERN_ERR
"ncpfs: tcp: Unexpected reply len %d\n", datalen
);
576 __ncptcp_abort(server
);
579 #ifdef CONFIG_NCPFS_PACKET_SIGNING
580 if (server
->sign_active
) {
582 printk(KERN_ERR
"ncpfs: tcp: Unexpected reply len %d\n", datalen
);
583 __ncptcp_abort(server
);
586 server
->rcv
.buf
.len
= datalen
- 8;
587 server
->rcv
.ptr
= (unsigned char*)&server
->rcv
.buf
.p1
;
589 server
->rcv
.state
= 4;
593 type
= ntohs(server
->rcv
.buf
.type
);
594 #ifdef CONFIG_NCPFS_PACKET_SIGNING
597 if (type
!= NCP_REPLY
) {
598 if (datalen
- 8 <= sizeof(server
->unexpected_packet
.data
)) {
599 *(__u16
*)(server
->unexpected_packet
.data
) = htons(type
);
600 server
->unexpected_packet
.len
= datalen
- 8;
602 server
->rcv
.state
= 5;
603 server
->rcv
.ptr
= server
->unexpected_packet
.data
+ 2;
604 server
->rcv
.len
= datalen
- 10;
607 DPRINTK("ncpfs: tcp: Unexpected NCP type %02X\n", type
);
609 server
->rcv
.state
= 2;
611 server
->rcv
.ptr
= NULL
;
612 server
->rcv
.len
= datalen
- 10;
615 req
= server
->rcv
.creq
;
617 DPRINTK(KERN_ERR
"ncpfs: Reply without appropriate request\n");
620 if (datalen
> req
->datalen
+ 8) {
621 printk(KERN_ERR
"ncpfs: tcp: Unexpected reply len %d (expected at most %Zd)\n", datalen
, req
->datalen
+ 8);
622 server
->rcv
.state
= 3;
625 req
->datalen
= datalen
- 8;
626 ((struct ncp_reply_header
*)server
->rxbuf
)->type
= NCP_REPLY
;
627 server
->rcv
.ptr
= server
->rxbuf
+ 2;
628 server
->rcv
.len
= datalen
- 10;
629 server
->rcv
.state
= 1;
631 #ifdef CONFIG_NCPFS_PACKET_SIGNING
633 datalen
= server
->rcv
.buf
.len
;
634 type
= ntohs(server
->rcv
.buf
.type2
);
638 req
= server
->rcv
.creq
;
639 if (req
->tx_type
!= NCP_ALLOC_SLOT_REQUEST
) {
640 if (((struct ncp_reply_header
*)server
->rxbuf
)->sequence
!= server
->sequence
) {
641 printk(KERN_ERR
"ncpfs: tcp: Bad sequence number\n");
642 __ncp_abort_request(server
, req
, -EIO
);
645 if ((((struct ncp_reply_header
*)server
->rxbuf
)->conn_low
| (((struct ncp_reply_header
*)server
->rxbuf
)->conn_high
<< 8)) != server
->connection
) {
646 printk(KERN_ERR
"ncpfs: tcp: Connection number mismatch\n");
647 __ncp_abort_request(server
, req
, -EIO
);
651 #ifdef CONFIG_NCPFS_PACKET_SIGNING
652 if (server
->sign_active
&& req
->tx_type
!= NCP_DEALLOC_SLOT_REQUEST
) {
653 if (sign_verify_reply(server
, server
->rxbuf
+ 6, req
->datalen
- 6, cpu_to_be32(req
->datalen
+ 16), &server
->rcv
.buf
.type
)) {
654 printk(KERN_ERR
"ncpfs: tcp: Signature violation\n");
655 __ncp_abort_request(server
, req
, -EIO
);
660 ncp_finish_request(server
, req
, req
->datalen
);
662 __ncp_next_request(server
);
665 server
->rcv
.ptr
= (unsigned char*)&server
->rcv
.buf
;
666 server
->rcv
.len
= 10;
667 server
->rcv
.state
= 0;
670 ncp_finish_request(server
, server
->rcv
.creq
, -EIO
);
673 info_server(server
, 0, server
->unexpected_packet
.data
, server
->unexpected_packet
.len
);
679 void ncp_tcp_rcv_proc(struct work_struct
*work
)
681 struct ncp_server
*server
=
682 container_of(work
, struct ncp_server
, rcv
.tq
);
684 mutex_lock(&server
->rcv
.creq_mutex
);
685 __ncptcp_rcv_proc(server
);
686 mutex_unlock(&server
->rcv
.creq_mutex
);
689 void ncp_tcp_tx_proc(struct work_struct
*work
)
691 struct ncp_server
*server
=
692 container_of(work
, struct ncp_server
, tx
.tq
);
694 mutex_lock(&server
->rcv
.creq_mutex
);
695 __ncptcp_try_send(server
);
696 mutex_unlock(&server
->rcv
.creq_mutex
);
699 static int do_ncp_rpc_call(struct ncp_server
*server
, int size
,
700 unsigned char* reply_buf
, int max_reply_size
)
703 struct ncp_request_reply
*req
;
705 req
= ncp_alloc_req();
709 req
->reply_buf
= reply_buf
;
710 req
->datalen
= max_reply_size
;
711 req
->tx_iov
[1].iov_base
= server
->packet
;
712 req
->tx_iov
[1].iov_len
= size
;
714 req
->tx_totallen
= size
;
715 req
->tx_type
= *(u_int16_t
*)server
->packet
;
717 result
= ncp_add_request(server
, req
);
721 if (wait_event_interruptible(req
->wq
, req
->status
== RQ_DONE
)) {
722 ncp_abort_request(server
, req
, -EINTR
);
727 result
= req
->result
;
736 * We need the server to be locked here, so check!
739 static int ncp_do_request(struct ncp_server
*server
, int size
,
740 void* reply
, int max_reply_size
)
744 if (server
->lock
== 0) {
745 printk(KERN_ERR
"ncpfs: Server not locked!\n");
748 if (!ncp_conn_valid(server
)) {
749 printk(KERN_ERR
"ncpfs: Connection invalid!\n");
754 unsigned long mask
, flags
;
756 spin_lock_irqsave(¤t
->sighand
->siglock
, flags
);
757 old_set
= current
->blocked
;
758 if (current
->flags
& PF_EXITING
)
761 mask
= sigmask(SIGKILL
);
762 if (server
->m
.flags
& NCP_MOUNT_INTR
) {
763 /* FIXME: This doesn't seem right at all. So, like,
764 we can't handle SIGINT and get whatever to stop?
765 What if we've blocked it ourselves? What about
766 alarms? Why, in fact, are we mucking with the
767 sigmask at all? -- r~ */
768 if (current
->sighand
->action
[SIGINT
- 1].sa
.sa_handler
== SIG_DFL
)
769 mask
|= sigmask(SIGINT
);
770 if (current
->sighand
->action
[SIGQUIT
- 1].sa
.sa_handler
== SIG_DFL
)
771 mask
|= sigmask(SIGQUIT
);
773 siginitsetinv(¤t
->blocked
, mask
);
775 spin_unlock_irqrestore(¤t
->sighand
->siglock
, flags
);
777 result
= do_ncp_rpc_call(server
, size
, reply
, max_reply_size
);
779 spin_lock_irqsave(¤t
->sighand
->siglock
, flags
);
780 current
->blocked
= old_set
;
782 spin_unlock_irqrestore(¤t
->sighand
->siglock
, flags
);
785 DDPRINTK("do_ncp_rpc_call returned %d\n", result
);
790 /* ncp_do_request assures that at least a complete reply header is
791 * received. It assumes that server->current_size contains the ncp
794 int ncp_request2(struct ncp_server
*server
, int function
,
797 struct ncp_request_header
*h
;
798 struct ncp_reply_header
* reply
= rpl
;
801 h
= (struct ncp_request_header
*) (server
->packet
);
802 if (server
->has_subfunction
!= 0) {
803 *(__u16
*) & (h
->data
[0]) = htons(server
->current_size
- sizeof(*h
) - 2);
805 h
->type
= NCP_REQUEST
;
807 * The server shouldn't know or care what task is making a
808 * request, so we always use the same task number.
810 h
->task
= 2; /* (current->pid) & 0xff; */
811 h
->function
= function
;
813 result
= ncp_do_request(server
, server
->current_size
, reply
, size
);
815 DPRINTK("ncp_request_error: %d\n", result
);
818 server
->completion
= reply
->completion_code
;
819 server
->conn_status
= reply
->connection_state
;
820 server
->reply_size
= result
;
821 server
->ncp_reply_size
= result
- sizeof(struct ncp_reply_header
);
823 result
= reply
->completion_code
;
826 PPRINTK("ncp_request: completion code=%x\n", result
);
831 int ncp_connect(struct ncp_server
*server
)
833 struct ncp_request_header
*h
;
836 server
->connection
= 0xFFFF;
837 server
->sequence
= 255;
839 h
= (struct ncp_request_header
*) (server
->packet
);
840 h
->type
= NCP_ALLOC_SLOT_REQUEST
;
841 h
->task
= 2; /* see above */
844 result
= ncp_do_request(server
, sizeof(*h
), server
->packet
, server
->packet_size
);
847 server
->connection
= h
->conn_low
+ (h
->conn_high
* 256);
853 int ncp_disconnect(struct ncp_server
*server
)
855 struct ncp_request_header
*h
;
857 h
= (struct ncp_request_header
*) (server
->packet
);
858 h
->type
= NCP_DEALLOC_SLOT_REQUEST
;
859 h
->task
= 2; /* see above */
862 return ncp_do_request(server
, sizeof(*h
), server
->packet
, server
->packet_size
);
865 void ncp_lock_server(struct ncp_server
*server
)
867 mutex_lock(&server
->mutex
);
869 printk(KERN_WARNING
"ncp_lock_server: was locked!\n");
873 void ncp_unlock_server(struct ncp_server
*server
)
876 printk(KERN_WARNING
"ncp_unlock_server: was not locked!\n");
880 mutex_unlock(&server
->mutex
);