1*b4b3f69fSMashijams /* 2*b4b3f69fSMashijams * Copyright 2022, Raghav Sharma, raghavself28@gmail.com 3*b4b3f69fSMashijams * Distributed under the terms of the MIT License. 4*b4b3f69fSMashijams */ 5*b4b3f69fSMashijams 6*b4b3f69fSMashijams 7*b4b3f69fSMashijams #include "ShortAttribute.h" 8*b4b3f69fSMashijams 9*b4b3f69fSMashijams 10*b4b3f69fSMashijams ShortAttribute::ShortAttribute(Inode* inode) 11*b4b3f69fSMashijams : 12*b4b3f69fSMashijams fInode(inode), 13*b4b3f69fSMashijams fName(NULL) 14*b4b3f69fSMashijams { 15*b4b3f69fSMashijams fHeader = (AShortFormHeader*)(DIR_AFORK_PTR(fInode->Buffer(), 16*b4b3f69fSMashijams fInode->CoreInodeSize(), fInode->ForkOffset())); 17*b4b3f69fSMashijams 18*b4b3f69fSMashijams fLastEntryOffset = 0; 19*b4b3f69fSMashijams } 20*b4b3f69fSMashijams 21*b4b3f69fSMashijams 22*b4b3f69fSMashijams ShortAttribute::~ShortAttribute() 23*b4b3f69fSMashijams { 24*b4b3f69fSMashijams } 25*b4b3f69fSMashijams 26*b4b3f69fSMashijams 27*b4b3f69fSMashijams uint32 28*b4b3f69fSMashijams ShortAttribute::_DataLength(AShortFormEntry* entry) 29*b4b3f69fSMashijams { 30*b4b3f69fSMashijams return entry->namelen + entry->valuelen; 31*b4b3f69fSMashijams } 32*b4b3f69fSMashijams 33*b4b3f69fSMashijams 34*b4b3f69fSMashijams AShortFormEntry* 35*b4b3f69fSMashijams ShortAttribute::_FirstEntry() 36*b4b3f69fSMashijams { 37*b4b3f69fSMashijams return (AShortFormEntry*) ((char*) fHeader + sizeof(AShortFormHeader)); 38*b4b3f69fSMashijams } 39*b4b3f69fSMashijams 40*b4b3f69fSMashijams 41*b4b3f69fSMashijams status_t 42*b4b3f69fSMashijams ShortAttribute::Open(const char* name, int openMode, attr_cookie** _cookie) 43*b4b3f69fSMashijams { 44*b4b3f69fSMashijams TRACE("ShortAttribute::Open\n"); 45*b4b3f69fSMashijams status_t status; 46*b4b3f69fSMashijams 47*b4b3f69fSMashijams size_t length = strlen(name); 48*b4b3f69fSMashijams status = Lookup(name, &length); 49*b4b3f69fSMashijams if (status < B_OK) 50*b4b3f69fSMashijams return status; 51*b4b3f69fSMashijams 52*b4b3f69fSMashijams attr_cookie* cookie = new(std::nothrow) attr_cookie; 53*b4b3f69fSMashijams if (cookie == NULL) 54*b4b3f69fSMashijams return B_NO_MEMORY; 55*b4b3f69fSMashijams 56*b4b3f69fSMashijams fName = name; 57*b4b3f69fSMashijams 58*b4b3f69fSMashijams // initialize the cookie 59*b4b3f69fSMashijams strlcpy(cookie->name, fName, B_ATTR_NAME_LENGTH); 60*b4b3f69fSMashijams cookie->open_mode = openMode; 61*b4b3f69fSMashijams cookie->create = false; 62*b4b3f69fSMashijams 63*b4b3f69fSMashijams *_cookie = cookie; 64*b4b3f69fSMashijams return B_OK; 65*b4b3f69fSMashijams } 66*b4b3f69fSMashijams 67*b4b3f69fSMashijams 68*b4b3f69fSMashijams status_t 69*b4b3f69fSMashijams ShortAttribute::Stat(attr_cookie* cookie, struct stat& stat) 70*b4b3f69fSMashijams { 71*b4b3f69fSMashijams TRACE("Short Attribute : Stat\n"); 72*b4b3f69fSMashijams 73*b4b3f69fSMashijams fName = cookie->name; 74*b4b3f69fSMashijams 75*b4b3f69fSMashijams size_t namelength = strlen(fName); 76*b4b3f69fSMashijams 77*b4b3f69fSMashijams // check if this attribute exists 78*b4b3f69fSMashijams status_t status = Lookup(fName, &namelength); 79*b4b3f69fSMashijams if (status != B_OK) 80*b4b3f69fSMashijams return status; 81*b4b3f69fSMashijams 82*b4b3f69fSMashijams // We have valid attribute entry to stat 83*b4b3f69fSMashijams stat.st_type = B_XATTR_TYPE; 84*b4b3f69fSMashijams stat.st_size = _DataLength(fEntry); 85*b4b3f69fSMashijams 86*b4b3f69fSMashijams return B_OK; 87*b4b3f69fSMashijams } 88*b4b3f69fSMashijams 89*b4b3f69fSMashijams 90*b4b3f69fSMashijams status_t 91*b4b3f69fSMashijams ShortAttribute::Read(attr_cookie* cookie, off_t pos, uint8* buffer, size_t* length) 92*b4b3f69fSMashijams { 93*b4b3f69fSMashijams TRACE("Short Attribute : Read\n"); 94*b4b3f69fSMashijams 95*b4b3f69fSMashijams if (pos < 0) 96*b4b3f69fSMashijams return B_BAD_VALUE; 97*b4b3f69fSMashijams 98*b4b3f69fSMashijams fName = cookie->name; 99*b4b3f69fSMashijams 100*b4b3f69fSMashijams size_t namelength = strlen(fName); 101*b4b3f69fSMashijams 102*b4b3f69fSMashijams status_t status = Lookup(fName, &namelength); 103*b4b3f69fSMashijams 104*b4b3f69fSMashijams uint32 lengthToRead = 0; 105*b4b3f69fSMashijams 106*b4b3f69fSMashijams if (pos + *length > fEntry->valuelen) 107*b4b3f69fSMashijams lengthToRead = fEntry->valuelen - pos; 108*b4b3f69fSMashijams else 109*b4b3f69fSMashijams lengthToRead = *length; 110*b4b3f69fSMashijams 111*b4b3f69fSMashijams char* ptrToOffset = (char*) fHeader + sizeof(AShortFormHeader) 112*b4b3f69fSMashijams + 3 * sizeof(uint8) + fEntry->namelen; 113*b4b3f69fSMashijams 114*b4b3f69fSMashijams memcpy(buffer, ptrToOffset, lengthToRead); 115*b4b3f69fSMashijams 116*b4b3f69fSMashijams *length = lengthToRead; 117*b4b3f69fSMashijams 118*b4b3f69fSMashijams return B_OK; 119*b4b3f69fSMashijams } 120*b4b3f69fSMashijams 121*b4b3f69fSMashijams 122*b4b3f69fSMashijams status_t 123*b4b3f69fSMashijams ShortAttribute::GetNext(char* name, size_t* nameLength) 124*b4b3f69fSMashijams { 125*b4b3f69fSMashijams TRACE("Short Attribute : GetNext\n"); 126*b4b3f69fSMashijams 127*b4b3f69fSMashijams AShortFormEntry* entry = _FirstEntry(); 128*b4b3f69fSMashijams uint16 curOffset = 1; 129*b4b3f69fSMashijams for (int i = 0; i < fHeader->count; i++) { 130*b4b3f69fSMashijams if (curOffset > fLastEntryOffset) { 131*b4b3f69fSMashijams 132*b4b3f69fSMashijams fLastEntryOffset = curOffset; 133*b4b3f69fSMashijams 134*b4b3f69fSMashijams char* PtrToOffset = (char*)entry + 3 * sizeof(uint8); 135*b4b3f69fSMashijams 136*b4b3f69fSMashijams memcpy(name, PtrToOffset, entry->namelen); 137*b4b3f69fSMashijams name[entry->namelen] = '\0'; 138*b4b3f69fSMashijams *nameLength = entry->namelen + 1; 139*b4b3f69fSMashijams TRACE("Entry found name : %s, namelength : %ld", name, *nameLength); 140*b4b3f69fSMashijams return B_OK; 141*b4b3f69fSMashijams } 142*b4b3f69fSMashijams entry = (AShortFormEntry*)((char*)entry + 3 * sizeof(uint8) + _DataLength(entry)); 143*b4b3f69fSMashijams curOffset += 3 * sizeof(uint8) + _DataLength(entry); 144*b4b3f69fSMashijams } 145*b4b3f69fSMashijams 146*b4b3f69fSMashijams return B_ENTRY_NOT_FOUND; 147*b4b3f69fSMashijams } 148*b4b3f69fSMashijams 149*b4b3f69fSMashijams 150*b4b3f69fSMashijams status_t 151*b4b3f69fSMashijams ShortAttribute::Lookup(const char* name, size_t* nameLength) 152*b4b3f69fSMashijams { 153*b4b3f69fSMashijams TRACE("Short Attribute : Lookup\n"); 154*b4b3f69fSMashijams 155*b4b3f69fSMashijams AShortFormEntry* entry = _FirstEntry(); 156*b4b3f69fSMashijams 157*b4b3f69fSMashijams int status; 158*b4b3f69fSMashijams 159*b4b3f69fSMashijams for (int i = 0; i < fHeader->count; i++) { 160*b4b3f69fSMashijams char* PtrToOffset = (char*)entry + 3 * sizeof(uint8); 161*b4b3f69fSMashijams status = strncmp(name, PtrToOffset, *nameLength); 162*b4b3f69fSMashijams if (status == 0) { 163*b4b3f69fSMashijams fEntry = entry; 164*b4b3f69fSMashijams return B_OK; 165*b4b3f69fSMashijams } 166*b4b3f69fSMashijams entry = (AShortFormEntry*)((char*)entry + 3 * sizeof(uint8) + _DataLength(entry)); 167*b4b3f69fSMashijams } 168*b4b3f69fSMashijams 169*b4b3f69fSMashijams return B_ENTRY_NOT_FOUND; 170*b4b3f69fSMashijams } 171