示例#1
0
int appledouble_truncate(struct afp_volume * volume, const char * path, int offset)
{

	char * newpath;
	int resource = extra_translate(volume, path, &newpath);
	struct afp_file_info fp;
	int ret;
	int dirid;
	char basename[AFP_MAX_PATH];

	switch(resource) {
		case AFP_META_RESOURCE:

			get_dirid(volume,newpath,basename,&dirid);

			ret=afp_openfork(volume,1,dirid,O_WRONLY,
				basename,&fp);

			ret=ll_zero_file(volume,fp.forkid,0);
			if (ret<0) {
				afp_closefork(volume,fp.forkid);
				remove_opened_fork(volume,fp);
				free(newpath);
				return ret;
			}
			afp_closefork(volume,fp.forkid);
			remove_opened_fork(volume,fp);

			return 1;
		case AFP_META_APPLEDOUBLE:
			free(newpath);
			return -EISDIR;
		case AFP_META_FINDERINFO:
			free(newpath);
			return 1;
		case AFP_META_COMMENT:
			free(newpath);
			return 1;
		case AFP_META_SERVER_ICON:
			free(newpath);
			return -EPERM;
	}
	return 0;
}
示例#2
0
文件: midlevel.c 项目: 007/afpfs-ng
int ml_truncate(struct afp_volume * vol, const char * path, off_t offset)
{
	int ret=0;
	char converted_path[AFP_MAX_PATH];
	struct afp_file_info *fp;
	int flags;

	if (convert_path_to_afp(vol->server->path_encoding,
		converted_path,(char *) path,AFP_MAX_PATH))
		return -EINVAL;

	/* The approach here is to get the forkid by calling ml_open()
	   (and not afp_openfork).  Note the fake afp_file_info used
	   just to grab this forkid. */

	if (invalid_filename(vol->server,converted_path)) 
		return -ENAMETOOLONG;

	if (volume_is_readonly(vol))
		return -EACCES;

	ret=appledouble_truncate(vol,path,offset);
	if (ret<0) return ret;
	if (ret==1) return 0;

	/* Here, we're going to use the untranslated path since it is
	   translated through the ml_open() */

	flags=O_WRONLY;
	if ((ml_open(vol,path,flags,&fp))) {
		return ret;
	};

	if ((ret=ll_zero_file(vol,fp->forkid,0)))
		goto out;

	afp_closefork(vol,fp->forkid);
	remove_opened_fork(vol, fp);
	free(fp);

out:
	return -ret;
}
示例#3
0
文件: midlevel.c 项目: 007/afpfs-ng
int ml_close(struct afp_volume * volume, const char * path, 
	struct afp_file_info * fp)
{

	int ret=0;
	char converted_path[AFP_MAX_PATH];

	if (convert_path_to_afp(volume->server->path_encoding,
		converted_path, (char *) path,AFP_MAX_PATH)) {
		return -EINVAL;
	}
 
	if (invalid_filename(volume->server,converted_path)) 
		return -ENAMETOOLONG;

	/* The logic here is that if we don't have an fp anymore, then the
	   fork must already be closed. */
	if (!fp) 
		return EBADF;

	if (fp->icon) {
		free(fp->icon);
	}
	if (fp->resource) {
		return appledouble_close(volume,fp);
	}

	switch(afp_closefork(volume,fp->forkid)) {
		case kFPNoErr:
			break;
		default:
		case kFPParamErr:
		case kFPMiscErr:
			ret=EIO;
			goto error;
	}
	remove_opened_fork(volume, fp);
		
error:
	return ret;
}
示例#4
0
文件: midlevel.c 项目: 007/afpfs-ng
int ml_readlink(struct afp_volume * vol, const char * path, 
	char *buf, size_t size)
{
	int rc,ret;
	struct afp_file_info fp;
	struct afp_rx_buffer buffer;
	char basename[AFP_MAX_PATH];
	char converted_path[AFP_MAX_PATH];
	unsigned int dirid;
	char link_path[AFP_MAX_PATH];

	memset(buf,0,size);
	memset(link_path,0,AFP_MAX_PATH);

	buffer.data=link_path;
	buffer.maxsize=size;
	buffer.size=0;

	if (convert_path_to_afp(vol->server->path_encoding,
		converted_path,(char *) path,AFP_MAX_PATH)) {
		return -EINVAL;
	}

	get_dirid(vol, converted_path, basename, &dirid);

	/* Open the fork */
	rc=afp_openfork(vol,0, dirid, 
		AFP_OPENFORK_ALLOWWRITE|AFP_OPENFORK_ALLOWREAD,
		basename,&fp);
	switch (rc) {
	case kFPAccessDenied:
		ret=EACCES;
		goto error;
	case kFPObjectNotFound:
		ret=ENOENT;
		goto error;
	case kFPObjectLocked:
		ret=EROFS;
		goto error;
	case kFPObjectTypeErr:
		ret=EISDIR;
		goto error;
	case kFPParamErr:
		ret=EACCES;
		goto error;
	case kFPTooManyFilesOpen:
		ret=EMFILE;
		goto error;
	case kFPVolLocked:
	case kFPDenyConflict:
	case kFPMiscErr:
	case kFPBitmapErr:
	case 0:
		ret=0;
		break;
	case -1:
	default:
		ret=EFAULT;
		goto error;
	}

	add_opened_fork(vol, &fp);

	/* Read the name of the file from it */
	if (vol->server->using_version->av_number < 30)
		rc=afp_read(vol, fp.forkid,0,size,&buffer);
	else 
		rc=afp_readext(vol, fp.forkid,0,size,&buffer);

	switch(rc) {
	case kFPAccessDenied:
		ret=EACCES;
		goto error;
	case kFPLockErr:
		ret=EBUSY;
		goto error;
	case kFPMiscErr:
	case kFPParamErr:
		ret=EIO;
		goto error;
	case kFPEOFErr:
	case kFPNoErr:
		break;
	}

	switch(afp_closefork(vol,fp.forkid)) {
	case kFPNoErr:
		break;
	default:
	case kFPParamErr:
	case kFPMiscErr:
		ret=EIO;
		goto error;
	}

	remove_opened_fork(vol, &fp);

	/* Convert the name back precomposed UTF8 */
	convert_path_to_unix(vol->server->path_encoding,
		buf,(char *) link_path,AFP_MAX_PATH);

	return 0;
	
error:
	return -ret;
}
示例#5
0
文件: midlevel.c 项目: 007/afpfs-ng
int ml_symlink(struct afp_volume *vol, const char * path1, const char * path2) 
{

	int ret;
	struct afp_file_info fp;
	uint64_t written;
	int rc;
	unsigned int dirid2;
	char basename2[AFP_MAX_PATH];
	char converted_path1[AFP_MAX_PATH];
	char converted_path2[AFP_MAX_PATH];

	if (vol->server->using_version->av_number<30) {
		/* No symlinks for AFP 2.x. */
		ret=ENOSYS;
		goto error;
	}
	/* Yes, you can create symlinks for AFP >=30.  Tested with 10.3.2 */

	if (convert_path_to_afp(vol->server->path_encoding,
		converted_path1,(char *) path1,AFP_MAX_PATH))
		return -EINVAL;

	if (convert_path_to_afp(vol->server->path_encoding,
		converted_path2,(char *) path2,AFP_MAX_PATH))
		return -EINVAL;

	if (volume_is_readonly(vol))
		return -EACCES;

	ret=appledouble_symlink(vol,path1,path2);
	if (ret<0) return ret;
	if (ret==1) return 0;

	get_dirid(vol,converted_path2,basename2,&dirid2 );

	/* 1. create the file */
	rc=afp_createfile(vol,kFPHardCreate,dirid2,basename2);
	switch (rc) {
	case kFPAccessDenied:
		ret=EACCES;
		goto error;
	case kFPDiskFull:
		ret=ENOSPC;
		goto error;
	case kFPObjectExists:
		ret=EEXIST;
		goto error;
	case kFPObjectNotFound:
		ret=ENOENT;
		goto error;
	case kFPFileBusy:
	case kFPVolLocked:
		ret=EBUSY;
		goto error;
	case kFPNoErr:
		ret=0;
		break;
	default:
	case kFPParamErr:
	case kFPMiscErr:
		ret=EIO;
		goto error;
	}

	/* Open the fork */
	rc=afp_openfork(vol,0,
		dirid2,
		AFP_OPENFORK_ALLOWWRITE|AFP_OPENFORK_ALLOWREAD,
		basename2,&fp);
	switch (ret) {
	case kFPAccessDenied:
		ret=EACCES;
		goto error;
	case kFPObjectNotFound:
		ret=ENOENT;
		goto error;
	case kFPObjectLocked:
		ret=EROFS;
		goto error;
	case kFPObjectTypeErr:
		ret=EISDIR;
		goto error;
	case kFPParamErr:
		ret=EACCES;
		goto error;
	case kFPTooManyFilesOpen:
		ret=EMFILE;
		goto error;
	case 0:
		ret=0;
		break;
	case kFPVolLocked:
	case kFPDenyConflict:
	case kFPMiscErr:
	case kFPBitmapErr:
	case -1:
	default:
		ret=EFAULT;
		goto error;
	}

	add_opened_fork(vol, &fp);

	/* Write the name of the file to it */

	rc=afp_writeext(vol,fp.forkid,0,strlen(converted_path1),
		converted_path1,&written);

	switch(afp_closefork(vol,fp.forkid)) {
	case kFPNoErr:
		break;
	default:
	case kFPParamErr:
	case kFPMiscErr:
		ret=EIO;
		goto error;
	}

	remove_opened_fork(vol, &fp);

	/* And now for the undocumented magic */
	memset(&fp.finderinfo,0,32);
	fp.finderinfo[0]='s';
	fp.finderinfo[1]='l';
	fp.finderinfo[2]='n';
	fp.finderinfo[3]='k';
	fp.finderinfo[4]='r';
	fp.finderinfo[5]='h';
	fp.finderinfo[6]='a';
	fp.finderinfo[7]='p';

	rc=afp_setfiledirparms(vol,dirid2,basename2,
		kFPFinderInfoBit, &fp);
	switch (rc) {
	case kFPAccessDenied:
		ret=EPERM;
		goto error;
	case kFPBitmapErr:
		/* This is the case where it isn't supported */
		ret=ENOSYS;
		goto error;
	case kFPObjectNotFound:
		ret=ENOENT;
		goto error;
	case 0:
		ret=0;
		break;
	case kFPMiscErr:
	case kFPObjectTypeErr:
	case kFPParamErr:
	default:
		ret=EIO;
		goto error;
	}
error:
	return -ret;
};