forked from idunham/libdrpc
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrpc.c
156 lines (132 loc) · 3.59 KB
/
rpc.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#include <rpc/rpc.h>
/*
* Functions to compose RPC messages from XDR primitives
*/
bool_t xdr_call_msg_start(
xdr_s_type *xdr,
uint32 prog,
uint32 ver,
uint32 proc,
opaque_auth *cred,
opaque_auth *verf)
{
uint32 vers = RPC_MSG_VERSION;
xdr->x_prog = prog;
xdr->x_proc = proc;
return (XDR_MSG_START(xdr, RPC_MSG_CALL) &&
XDR_SEND_UINT32(xdr, &vers) &&
XDR_SEND_UINT32(xdr, &prog) &&
XDR_SEND_UINT32(xdr, &ver) &&
XDR_SEND_UINT32(xdr, &proc) &&
xdr_send_auth(xdr, cred) &&
xdr_send_auth(xdr, verf));
} // xdr_call_msg_start
bool_t xdr_reply_msg_start(
xdr_s_type *xdr,
opaque_auth *verf)
{
int32 stat = (int32) RPC_MSG_ACCEPTED;
int32 accept = (int32) RPC_ACCEPT_SUCCESS;
return(XDR_MSG_START(xdr, RPC_MSG_REPLY) &&
XDR_SEND_INT32(xdr, &stat) &&
xdr_send_auth(xdr, verf) &&
XDR_SEND_INT32(xdr, &accept));
} // xdr_reply_msg_start
static bool_t xdr_send_accepted_reply_header(
xdr_s_type *xdr,
struct rpc_accepted_reply_header const *accreply)
{
if (!xdr_send_auth(xdr, &accreply->verf))
return FALSE;
if (!XDR_SEND_ENUM(xdr, &accreply->stat))
return FALSE;
switch ((*accreply).stat){
case RPC_PROG_MISMATCH:
if (!XDR_SEND_UINT32(xdr, &accreply->u.versions.low))
return FALSE;
if (!XDR_SEND_UINT32(xdr, &accreply->u.versions.high))
return FALSE;
break;
case RPC_ACCEPT_SUCCESS:
case RPC_PROG_UNAVAIL:
case RPC_PROC_UNAVAIL:
case RPC_GARBAGE_ARGS:
case RPC_SYSTEM_ERR:
case RPC_PROG_LOCKED:
// case ignored
break;
default:
return FALSE;
}
return TRUE;
} /* xdr_send_accepted_reply_header */
static bool_t xdr_send_denied_reply(
xdr_s_type *xdr,
struct rpc_denied_reply const *rejreply)
{
if (!XDR_SEND_ENUM(xdr, &rejreply->stat))
return FALSE;
switch ((*rejreply).stat){
case RPC_MISMATCH:
if (!XDR_SEND_UINT32(xdr, &rejreply->u.versions.low))
return FALSE;
if (!XDR_SEND_UINT32(xdr, &rejreply->u.versions.high))
return FALSE;
break;
case RPC_AUTH_ERROR:
if (!XDR_SEND_ENUM(xdr, &rejreply->u.why))
return FALSE;
break;
default:
return FALSE;
}
return TRUE;
} /* xdr_send_denied_reply */
bool_t xdr_send_reply_header(
xdr_s_type *xdr,
rpc_reply_header const *reply)
{
if (!XDR_SEND_ENUM(xdr, &reply->stat))
return FALSE;
switch ((*reply).stat) {
case RPC_MSG_ACCEPTED:
if (!xdr_send_accepted_reply_header(xdr, &reply->u.ar))
return FALSE;
break;
case RPC_MSG_DENIED:
if (!xdr_send_denied_reply(xdr, &reply->u.dr))
return FALSE;
break;
default:
return FALSE;
}
return TRUE;
} /* xdr_send_reply_header */
#include <stdio.h>
bool_t
xdr_send_auth(xdr_s_type *xdr, const opaque_auth *auth)
{
#define FAILIF(x) do { if (x) return FALSE; } while(0)
switch (sizeof(auth->oa_flavor)) {
case 1:
FAILIF(!XDR_SEND_INT8(xdr, (int8_t *)&auth->oa_flavor));
break;
case 2:
FAILIF(!XDR_SEND_INT16(xdr, (int16_t *)&auth->oa_flavor));
break;
case 4:
FAILIF(!XDR_SEND_INT32(xdr, (int32_t *)&auth->oa_flavor));
break;
default:
return FALSE;
}
return (XDR_SEND_UINT(xdr, (uint32_t *)&auth->oa_length) &&
(auth->oa_length == 0 ||
XDR_SEND_BYTES(xdr, (uint8_t *)auth->oa_base, auth->oa_length)));
}
void xdr_free(xdrproc_t proc, char *objp)
{
XDR x;
x.x_op = XDR_FREE;
(*proc)(&x, objp);
}