in hfs/hfs.c [269:320]
void cmd_setattr(Volume* volume, int argc, const char *argv[]) {
HFSPlusCatalogRecord* record;
if(argc < 4) {
printf("Not enough arguments: setattr <path> <attribute-name> <attribute-value>");
return;
}
record = getRecordFromPath(argv[1], volume, NULL, NULL);
if(record != NULL) {
HFSCatalogNodeID id;
uint8_t* data;
size_t size;
if(record->recordType == kHFSPlusFileRecord)
id = ((HFSPlusCatalogFile*)record)->fileID;
else
id = ((HFSPlusCatalogFolder*)record)->folderID;
// Note: this doesn't handle embedded nulls, string encodings, etc.
size_t dataLen = strlen(argv[3]);
if (dataLen == 0) {
// Handle the empty string gracefully.
dataLen = 1;
}
if((dataLen & 0x1) == 0x1) {
// HFS record sizes must be even. Pad the given data with one 0 to
// maintain this invariant. Note that macOS `xattr` appears to do
// this silently.
dataLen += 1;
}
data = malloc(sizeof(uint8_t) * (dataLen));
memset(data, 0, dataLen);
memcpy(data, argv[3], strlen(argv[3]));
ASSERT(setAttribute(volume, id, argv[2], data, dataLen), "setAttribute");
} else {
printf("No such file or directory\n");
}
if(record->recordType == kHFSPlusFolderRecord) {
((HFSPlusCatalogFolder*)record)->flags |= kHFSHasAttributesMask;
} else if(record->recordType == kHFSPlusFileRecord) {
((HFSPlusCatalogFile*)record)->flags |= kHFSHasAttributesMask;
} else {
printf("unknown record type %x\n", record->recordType);
}
updateCatalog(volume, record);
free(record);
}