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 fReply->Stream().InsertUInt(fStatusPosition, _HaikuErrorToNFS4(fStatus)); 50 fReply->Stream().InsertUInt(fOpCountPosition, fOpCount); 51 52 if (fReply == NULL || fReply->Stream().Error() == B_OK) 53 return fReply; 54 else 55 return NULL; 56 } 57 58 59 status_t 60 ReplyBuilder::GetAttr(status_t status, int mask, uint64 size, uint64 change) 61 { 62 if (fStatus != B_OK) 63 return B_ERROR; 64 65 fReply->Stream().AddUInt(OpCallbackGetAttr); 66 fReply->Stream().AddUInt(_HaikuErrorToNFS4(fStatus)); 67 fStatus = status; 68 69 if (status == B_OK) { 70 uint32 bitmap = 0; 71 if ((mask & CallbackAttrChange) != 0) 72 bitmap |= 1 << FATTR4_CHANGE; 73 if ((mask & CallbackAttrSize) != 0) 74 bitmap |= 1 << FATTR4_SIZE; 75 fReply->Stream().AddUInt(1); 76 fReply->Stream().AddUInt(bitmap); 77 78 XDR::WriteStream str; 79 if ((mask & CallbackAttrChange) != 0) 80 str.AddUHyper(change); 81 82 if ((mask & CallbackAttrSize) != 0) 83 str.AddUHyper(size); 84 fReply->Stream().AddOpaque(str); 85 } 86 87 fOpCount++; 88 89 return B_OK; 90 } 91 92 93 status_t 94 ReplyBuilder::Recall(status_t status) 95 { 96 if (fStatus != B_OK) 97 return B_ERROR; 98 99 fReply->Stream().AddUInt(OpCallbackRecall); 100 fReply->Stream().AddUInt(_HaikuErrorToNFS4(fStatus)); 101 fStatus = status; 102 103 fOpCount++; 104 105 return B_OK; 106 } 107 108 109 uint32 110 ReplyBuilder::_HaikuErrorToNFS4(status_t error) 111 { 112 switch (error) { 113 case B_OK: return NFS4_OK; 114 case B_FILE_NOT_FOUND: return NFS4ERR_BADHANDLE; 115 case B_NOT_SUPPORTED: return NFS4ERR_OP_ILLEGAL; 116 default: return NFS4ERR_RESOURCE; 117 } 118 } 119 120