void cmd_setattr()

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);
}