Ejemplo n.º 1
0
static int FuseHFS_setxattr(const char *path, const char *name, const char *value,
				  size_t size, int flags, uint32_t position) {
	dprintf("setxattr %s %s %p %lu %02x %u\n", path, name, value, size, flags, position);
	if (_readonly) return -EPERM;
	
	// convert to hfs path
	char *hfspath = mkhfspath(path);
	if (hfspath == NULL) return -ENOENT;
	
	// find file
	hfsdirent ent;
	if (hfs_stat(NULL, hfspath, &ent) == -1) {
		free(hfspath);
		return -ENOENT;
	}
	
	if (strcmp(name, XATTR_FINDERINFO_NAME) == 0) {
		if (size != 32) {
			dprintf("setxattr: finder info is not 32 bytes\n");
			free(hfspath);
			return -ERANGE;
		}
		// write finder info to dirent
		if (ent.flags & HFS_ISDIR) {
			// directory
			ent.u.dir.rect.top =		OSReadBigInt16(value, 0);
			ent.u.dir.rect.left =		OSReadBigInt16(value, 2);
			ent.u.dir.rect.bottom =		OSReadBigInt16(value, 4);
			ent.u.dir.rect.right =		OSReadBigInt16(value, 6);
			ent.fdflags =				OSReadBigInt16(value, 8);
			ent.fdlocation.v =			OSReadBigInt16(value, 10);
			ent.fdlocation.h =			OSReadBigInt16(value, 12);
			ent.u.dir.view =			OSReadBigInt16(value, 14);
			// DXInfo
			((DXInfo*)(ent.u.dir.xinfo))->frScroll.v   = OSReadBigInt16(value, 16);
			((DXInfo*)(ent.u.dir.xinfo))->frScroll.h   = OSReadBigInt16(value, 18);
			((DXInfo*)(ent.u.dir.xinfo))->frOpenChain  = OSReadBigInt32(value, 20);
			((DXInfo*)(ent.u.dir.xinfo))->frUnused     = OSReadBigInt16(value, 24);
			((DXInfo*)(ent.u.dir.xinfo))->frComment    = OSReadBigInt16(value, 26);
			((DXInfo*)(ent.u.dir.xinfo))->frPutAway    = OSReadBigInt32(value, 28);
		} else {
			// regular file
			memcpy(ent.u.file.type, value, 4);
			memcpy(ent.u.file.creator, value+4, 4);
			ent.u.file.type[4] = ent.u.file.type[4] = '\0';
			ent.fdflags       = OSReadBigInt16(value, 8);
			ent.fdlocation.v  = OSReadBigInt16(value, 10);
			ent.fdlocation.h  = OSReadBigInt16(value, 12);
			ent.u.file.window = OSReadBigInt16(value, 14);
			// FXInfo
			((FXInfo*)(ent.u.file.xinfo))->fdIconID    = OSReadBigInt16(value, 16);
			((FXInfo*)(ent.u.file.xinfo))->fdUnused[0] = OSReadBigInt16(value, 18);
			((FXInfo*)(ent.u.file.xinfo))->fdUnused[1] = OSReadBigInt16(value, 20);
			((FXInfo*)(ent.u.file.xinfo))->fdUnused[2] = OSReadBigInt16(value, 22);
			((FXInfo*)(ent.u.file.xinfo))->fdUnused[3] = OSReadBigInt16(value, 24);
			((FXInfo*)(ent.u.file.xinfo))->fdComment   = OSReadBigInt16(value, 26);
			((FXInfo*)(ent.u.file.xinfo))->fdPutAway   = OSReadBigInt32(value, 28);
			// bless parent folder if it's a system file
			if ((strcmp(ent.u.file.type, "zsys") == 0) && (strcmp(ent.u.file.creator, "MACS") == 0) && (strcmp(ent.name, "System") == 0)) {
				// bless
				dprintf("setxattr: blessing folder %lu\n", ent.parid);
				hfsvolent volent;
				hfs_vstat(NULL, &volent);
				volent.blessed = ent.parid;
				hfs_vsetattr(NULL, &volent);
			}
		}
		// update file
		hfs_setattr(NULL, hfspath, &ent);
		free(hfspath);
		return 0;
	} else if (strcmp(name, XATTR_RESOURCEFORK_NAME) == 0 && (!(ent.flags & HFS_ISDIR))) {
		// resource fork
		// TODO: how are resource forks truncated?
		hfsfile *fp = hfs_open(NULL, hfspath);
		hfs_setfork(fp, 1);
		hfs_seek(fp, position, SEEK_SET);
		hfs_write(fp, value, size);
		hfs_close(fp);
		// the end
		free(hfspath);
		return 0;
	} else {
		free(hfspath);
		return 0;
	}
	
	free(hfspath);
	return -ENOATTR;
	
}
uint32_t ACCEL_TABLE::count () const {
  return OSReadBigInt16(&count_, 0);
}