1 /*
2 * Copyright 2012 Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 * Paweł Dziepak, pdziepak@quarnos.org
7 */
8
9
10 #include "ReplyBuilder.h"
11
12 #include "NFS4Defs.h"
13 #include "RPCCallbackReply.h"
14
15
ReplyBuilder(uint32 xid)16 ReplyBuilder::ReplyBuilder(uint32 xid)
17 :
18 fStatus(B_OK),
19 fOpCount(0),
20 fReply(RPC::CallbackReply::Create(xid))
21 {
22 _InitHeader();
23 }
24
25
~ReplyBuilder()26 ReplyBuilder::~ReplyBuilder()
27 {
28 delete fReply;
29 }
30
31
32 void
_InitHeader()33 ReplyBuilder::_InitHeader()
34 {
35 fStatusPosition = fReply->Stream().Current();
36 fReply->Stream().AddUInt(0);
37
38 fReply->Stream().AddOpaque(NULL, 0);
39
40 fOpCountPosition = fReply->Stream().Current();
41 fReply->Stream().AddUInt(0);
42
43 }
44
45
46 RPC::CallbackReply*
Reply()47 ReplyBuilder::Reply()
48 {
49 if (fReply == NULL)
50 return NULL;
51
52 fReply->Stream().InsertUInt(fStatusPosition, _HaikuErrorToNFS4(fStatus));
53 fReply->Stream().InsertUInt(fOpCountPosition, fOpCount);
54
55 if (fReply->Stream().Error() == B_OK)
56 return fReply;
57 else
58 return NULL;
59 }
60
61
62 status_t
GetAttr(status_t status,int mask,uint64 size,uint64 change)63 ReplyBuilder::GetAttr(status_t status, int mask, uint64 size, uint64 change)
64 {
65 if (fStatus != B_OK)
66 return B_ERROR;
67
68 fReply->Stream().AddUInt(OpCallbackGetAttr);
69 fReply->Stream().AddUInt(_HaikuErrorToNFS4(fStatus));
70 fStatus = status;
71
72 if (status == B_OK) {
73 uint32 bitmap = 0;
74 if ((mask & CallbackAttrChange) != 0)
75 bitmap |= 1 << FATTR4_CHANGE;
76 if ((mask & CallbackAttrSize) != 0)
77 bitmap |= 1 << FATTR4_SIZE;
78 fReply->Stream().AddUInt(1);
79 fReply->Stream().AddUInt(bitmap);
80
81 XDR::WriteStream str;
82 if ((mask & CallbackAttrChange) != 0)
83 str.AddUHyper(change);
84
85 if ((mask & CallbackAttrSize) != 0)
86 str.AddUHyper(size);
87 fReply->Stream().AddOpaque(str);
88 }
89
90 fOpCount++;
91
92 return B_OK;
93 }
94
95
96 status_t
Recall(status_t status)97 ReplyBuilder::Recall(status_t status)
98 {
99 if (fStatus != B_OK)
100 return B_ERROR;
101
102 fReply->Stream().AddUInt(OpCallbackRecall);
103 fReply->Stream().AddUInt(_HaikuErrorToNFS4(fStatus));
104 fStatus = status;
105
106 fOpCount++;
107
108 return B_OK;
109 }
110
111
112 uint32
_HaikuErrorToNFS4(status_t error)113 ReplyBuilder::_HaikuErrorToNFS4(status_t error)
114 {
115 switch (error) {
116 case B_OK: return NFS4_OK;
117 case B_ENTRY_NOT_FOUND: return NFS4ERR_BADHANDLE;
118 case B_NOT_SUPPORTED: return NFS4ERR_OP_ILLEGAL;
119 default: return NFS4ERR_RESOURCE;
120 }
121 }
122
123