xref: /minix3/minix/lib/libhgfs/rpc.c (revision 433d6423c39e34ec4b79c950597bb2d236f886be)
1 /* Part of libhgfs - (c) 2009, D.C. van Moolenbroek */
2 
3 #include "inc.h"
4 
5 char rpc_buf[RPC_BUF_SIZE];
6 char *rpc_ptr;
7 
8 static struct channel rpc_chan;
9 
10 /*===========================================================================*
11  *				rpc_open				     *
12  *===========================================================================*/
13 int rpc_open(void)
14 {
15 /* Open a HGFS RPC backdoor channel to the VMware host, and make sure that it
16  * is working. Return OK upon success, or a negative error code otherwise; in
17  * particular, return EAGAIN if shared folders are disabled.
18  */
19   int r;
20 
21   if ((r = channel_open(&rpc_chan, CH_OUT)) != OK)
22 	return r;
23 
24   r = rpc_test();
25 
26   if (r != OK)
27 	channel_close(&rpc_chan);
28 
29   return r;
30 }
31 
32 /*===========================================================================*
33  *				rpc_query				     *
34  *===========================================================================*/
35 int rpc_query(void)
36 {
37 /* Send a HGFS RPC query over the backdoor channel. Return OK upon success, or
38  * a negative error code otherwise; EAGAIN is returned if shared folders are
39  * disabled. In general, we make the assumption that the sender (= VMware)
40  * speaks the protocol correctly. Hence, the callers of this function do not
41  * check for lengths.
42  */
43   int r, len, id, err;
44 
45   len = RPC_LEN;
46 
47   /* A more robust version of this call could reopen the channel and
48    * retry the request upon low-level failure.
49    */
50   r = channel_send(&rpc_chan, rpc_buf, len);
51   if (r < 0) return r;
52 
53   r = channel_recv(&rpc_chan, rpc_buf, sizeof(rpc_buf));
54   if (r < 0) return r;
55   if (r < 2 || (len > 2 && r < 10)) return EIO;
56 
57   RPC_RESET;
58 
59   if (RPC_NEXT8 != '1') return EAGAIN;
60   if (RPC_NEXT8 != ' ') return EAGAIN;
61 
62   if (len <= 2) return OK;
63 
64   id = RPC_NEXT32;
65   err = RPC_NEXT32;
66 
67   return error_convert(err);
68 }
69 
70 /*===========================================================================*
71  *				rpc_test				     *
72  *===========================================================================*/
73 int rpc_test(void)
74 {
75 /* Test whether HGFS communication is working. Return OK on success, EAGAIN if
76  * shared folders are disabled, or another negative error code upon error.
77  */
78 
79   RPC_RESET;
80   RPC_NEXT8 = 'f';
81   RPC_NEXT8 = ' ';
82 
83   return rpc_query();
84 }
85 
86 /*===========================================================================*
87  *				rpc_close				     *
88  *===========================================================================*/
89 void rpc_close(void)
90 {
91 /* Close the HGFS RPC backdoor channel.
92  */
93 
94   channel_close(&rpc_chan);
95 }
96