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 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 26 ReplyBuilder::~ReplyBuilder() 27 { 28 delete fReply; 29 } 30 31 32 void 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* 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 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 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 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