Esempio n. 1
0
static int FuseHFS_setcrtime (const char *path, const struct timespec *tv) {
	dprintf("setcrtime %s\n", path);
	if (_readonly) return -EPERM;
	
	// convert to hfs path
	char *hfspath = mkhfspath(path);
	if (hfspath == NULL) return -ENOENT;
	int err;
	
	// get file info
	hfsdirent ent;
	
	if (hfs_stat(NULL, hfspath, &ent) == 0) {
		ent.crdate = tv->tv_sec;
		err = hfs_setattr(NULL, hfspath, &ent);
		free(hfspath);
		if (!err) return 0;
		perror("hfs_setattr");
		return -errno;
	}
	
	free(hfspath);
	perror("hfs_stat");
	return -errno;
}
Esempio n. 2
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;
	
}
Esempio n. 3
0
int
make_desktop(hfsvol *vol, int end)
/* hfsvol  *vol;				   Mac volume */
{
	hfsfile		*hfp;			/* Mac file */
	hfsdirent	ent;			/* Mac finderinfo */
	unsigned short	clps;			/* clump size */
	unsigned short	blks;			/* blocks in a clump */
	unsigned char	*blk;			/* user data */
	int		i;

	/* set up default directory entries - not all these fields
	   are needed, but we'll set them up anyway ... */
	ent.rsize = 0;				/* resource size == 0 */
	strcpy(ent.creator, DBFC);		/* creator */
	strcpy(ent.type, DBT);			/* type */
	ent.crdate = ent.mddate = time(0);	/* date is now */
	ent.fdflags = HFS_FNDR_ISINVISIBLE;	/* invisible files */

	/* clear the DB file */
	blk = hce->hfs_ce + hce->hfs_ce_size*HFS_BLOCKSZ;
	blks = hce->hfs_dt_size;
	clps = blks*HFS_BLOCKSZ;

	memset(blk, 0, clps);

	/* create "Desktop DB" (if it doesn't exist) */
	if(hfs_create(vol, DB, ent.type, ent.creator) == 0)
	{
	    /* DB file size from hce_mem info */
	    /* set up "Desktop DB" data - following found by od'ing
	       the "Desktop DB" file */
	    d_putw(blk+8, 0x100);
	    d_putw(blk+10, 0x3);

	    d_putw(blk+32, 0x200);
	    d_putw(blk+34, 0x25);

	    d_putl(blk+36, blks);
	    d_putl(blk+40, blks - 1);

	    d_putw(blk+48, clps);
	    d_putw(blk+50, 0xff);

	    d_putw(blk+120, 0x20a);
	    d_putw(blk+122, 0x100);

	    d_putw(blk+248, 0x8000);

	    d_putl(blk+504, 0x1f800f8);
	    d_putl(blk+508, 0x78000e);

	    /* entries for "Desktop DB" */
	    ent.dsize = clps;			/* size = clump size */
	
	    /* open file */
	    if((hfp = hfs_open(vol, DB)) == 0)
		err(1, hfs_error);

	    /* "write" file */
	    write_fork(hfp, clps);

	    /* set DB file attributes */
	    if (hfs_fsetattr(hfp, &ent) < 0)
		err(1, hfs_error);

	    /* find the real start of the file */
	    end += hce->hfs_ce_size;

	    /* close DB file */
	    if (hfs_close(hfp, end, 0) < 0)
		err(1, hfs_error);
	}
	else
	{
	    /* if it already exists, then make sure it has the correct
	       type/creator and flags */
	    if(hfs_setattr(vol, DB, &ent) < 0)
		err(1, hfs_error);
	}

	/* setup "Desktop DF" file as an empty file */
	strcpy(ent.type, DFT);			/* type */
	ent.dsize = 0;				/* empty */

	/* create DF file (if it doesn't exist) - no need to open it */
	hfs_create(vol, DF, ent.type, ent.creator);

	/* set DB file attributes */
	if (hfs_setattr(vol, DF, &ent) < 0)
	    err(1, hfs_error);
	return 0;
}