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 16ReplyBuilder::ReplyBuilder(uint32 xid) 17 : 18 fStatus(B_OK), 19 fOpCount(0), 20 fReply(RPC::CallbackReply::Create(xid)) 21{ 22 _InitHeader(); 23} 24 25 26ReplyBuilder::~ReplyBuilder() 27{ 28 delete fReply; 29} 30 31 32void 33ReplyBuilder::_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 46RPC::CallbackReply* 47ReplyBuilder::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 62status_t 63ReplyBuilder::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 96status_t 97ReplyBuilder::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 112uint32 113ReplyBuilder::_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