xref: /minix3/minix/lib/libhgfs/rpc.c (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1433d6423SLionel Sambuc /* Part of libhgfs - (c) 2009, D.C. van Moolenbroek */
2433d6423SLionel Sambuc 
3433d6423SLionel Sambuc #include "inc.h"
4433d6423SLionel Sambuc 
5433d6423SLionel Sambuc char rpc_buf[RPC_BUF_SIZE];
6433d6423SLionel Sambuc char *rpc_ptr;
7433d6423SLionel Sambuc 
8433d6423SLionel Sambuc static struct channel rpc_chan;
9433d6423SLionel Sambuc 
10433d6423SLionel Sambuc /*===========================================================================*
11433d6423SLionel Sambuc  *				rpc_open				     *
12433d6423SLionel Sambuc  *===========================================================================*/
rpc_open(void)13433d6423SLionel Sambuc int rpc_open(void)
14433d6423SLionel Sambuc {
15433d6423SLionel Sambuc /* Open a HGFS RPC backdoor channel to the VMware host, and make sure that it
16433d6423SLionel Sambuc  * is working. Return OK upon success, or a negative error code otherwise; in
17433d6423SLionel Sambuc  * particular, return EAGAIN if shared folders are disabled.
18433d6423SLionel Sambuc  */
19433d6423SLionel Sambuc   int r;
20433d6423SLionel Sambuc 
21433d6423SLionel Sambuc   if ((r = channel_open(&rpc_chan, CH_OUT)) != OK)
22433d6423SLionel Sambuc 	return r;
23433d6423SLionel Sambuc 
24433d6423SLionel Sambuc   r = rpc_test();
25433d6423SLionel Sambuc 
26433d6423SLionel Sambuc   if (r != OK)
27433d6423SLionel Sambuc 	channel_close(&rpc_chan);
28433d6423SLionel Sambuc 
29433d6423SLionel Sambuc   return r;
30433d6423SLionel Sambuc }
31433d6423SLionel Sambuc 
32433d6423SLionel Sambuc /*===========================================================================*
33433d6423SLionel Sambuc  *				rpc_query				     *
34433d6423SLionel Sambuc  *===========================================================================*/
rpc_query(void)35433d6423SLionel Sambuc int rpc_query(void)
36433d6423SLionel Sambuc {
37433d6423SLionel Sambuc /* Send a HGFS RPC query over the backdoor channel. Return OK upon success, or
38433d6423SLionel Sambuc  * a negative error code otherwise; EAGAIN is returned if shared folders are
39433d6423SLionel Sambuc  * disabled. In general, we make the assumption that the sender (= VMware)
40433d6423SLionel Sambuc  * speaks the protocol correctly. Hence, the callers of this function do not
41433d6423SLionel Sambuc  * check for lengths.
42433d6423SLionel Sambuc  */
43*0a6a1f1dSLionel Sambuc   int r, len, err;
44433d6423SLionel Sambuc 
45433d6423SLionel Sambuc   len = RPC_LEN;
46433d6423SLionel Sambuc 
47433d6423SLionel Sambuc   /* A more robust version of this call could reopen the channel and
48433d6423SLionel Sambuc    * retry the request upon low-level failure.
49433d6423SLionel Sambuc    */
50433d6423SLionel Sambuc   r = channel_send(&rpc_chan, rpc_buf, len);
51433d6423SLionel Sambuc   if (r < 0) return r;
52433d6423SLionel Sambuc 
53433d6423SLionel Sambuc   r = channel_recv(&rpc_chan, rpc_buf, sizeof(rpc_buf));
54433d6423SLionel Sambuc   if (r < 0) return r;
55433d6423SLionel Sambuc   if (r < 2 || (len > 2 && r < 10)) return EIO;
56433d6423SLionel Sambuc 
57433d6423SLionel Sambuc   RPC_RESET;
58433d6423SLionel Sambuc 
59433d6423SLionel Sambuc   if (RPC_NEXT8 != '1') return EAGAIN;
60433d6423SLionel Sambuc   if (RPC_NEXT8 != ' ') return EAGAIN;
61433d6423SLionel Sambuc 
62433d6423SLionel Sambuc   if (len <= 2) return OK;
63433d6423SLionel Sambuc 
64*0a6a1f1dSLionel Sambuc   RPC_ADVANCE(sizeof(u32_t)); /* Skip over id field. */
65433d6423SLionel Sambuc   err = RPC_NEXT32;
66433d6423SLionel Sambuc 
67433d6423SLionel Sambuc   return error_convert(err);
68433d6423SLionel Sambuc }
69433d6423SLionel Sambuc 
70433d6423SLionel Sambuc /*===========================================================================*
71433d6423SLionel Sambuc  *				rpc_test				     *
72433d6423SLionel Sambuc  *===========================================================================*/
rpc_test(void)73433d6423SLionel Sambuc int rpc_test(void)
74433d6423SLionel Sambuc {
75433d6423SLionel Sambuc /* Test whether HGFS communication is working. Return OK on success, EAGAIN if
76433d6423SLionel Sambuc  * shared folders are disabled, or another negative error code upon error.
77433d6423SLionel Sambuc  */
78433d6423SLionel Sambuc 
79433d6423SLionel Sambuc   RPC_RESET;
80433d6423SLionel Sambuc   RPC_NEXT8 = 'f';
81433d6423SLionel Sambuc   RPC_NEXT8 = ' ';
82433d6423SLionel Sambuc 
83433d6423SLionel Sambuc   return rpc_query();
84433d6423SLionel Sambuc }
85433d6423SLionel Sambuc 
86433d6423SLionel Sambuc /*===========================================================================*
87433d6423SLionel Sambuc  *				rpc_close				     *
88433d6423SLionel Sambuc  *===========================================================================*/
rpc_close(void)89433d6423SLionel Sambuc void rpc_close(void)
90433d6423SLionel Sambuc {
91433d6423SLionel Sambuc /* Close the HGFS RPC backdoor channel.
92433d6423SLionel Sambuc  */
93433d6423SLionel Sambuc 
94433d6423SLionel Sambuc   channel_close(&rpc_chan);
95433d6423SLionel Sambuc }
96