Esempio n. 1
0
int ncp_symlink(struct inode *dir, struct dentry *dentry, const char *symname) {
	int i,length;
	struct inode *inode;
	char *link;

#ifdef DEBUG
	printk("ncp_symlink(dir=%p,dentry=%p,symname=%s)\n",dir,dentry,symname);
#endif

	if (!(NCP_SERVER(dir)->m.flags & NCP_MOUNT_SYMLINKS))
		return -EPERM;	/* EPERM is returned by VFS if symlink procedure does not exist */

	if ((length=strlen(symname))>NCP_MAX_SYMLINK_SIZE)
		return -EINVAL;

	if ((link=(char *)kmalloc(length+9,GFP_NFS))==NULL)
		return -ENOMEM;

	if (ncp_create_new(dir,dentry,0,aSHARED|aHIDDEN)) {
		kfree(link);
		return -EIO;
	}

	inode=dentry->d_inode;

	((__u32 *)link)[0]=NCP_SYMLINK_MAGIC0;
	((__u32 *)link)[1]=NCP_SYMLINK_MAGIC1;
	memcpy(link+8, symname, length+1); /* including last zero for io2vol */

	/* map to/from server charset, do not touch upper/lower case as
	   symlink can point out of ncp filesystem */
	io2vol(NCP_SERVER(inode), link+8, 0);
	
	if(ncp_write_kernel(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle, 
	    		    0, length+8, link, &i) || i!=length+8) {
		kfree(link);
		return -EIO;
	}

	kfree(link);
	return 0;
}
Esempio n. 2
0
int ncp_symlink(struct inode *dir, struct dentry *dentry, const char *symname) {
	struct inode *inode;
	char *rawlink;
	int length, err, i, outlen;
	int kludge;
	int mode;
	__le32 attr;
	unsigned int hdr;

	DPRINTK("ncp_symlink(dir=%p,dentry=%p,symname=%s)\n",dir,dentry,symname);

	if (ncp_is_nfs_extras(NCP_SERVER(dir), NCP_FINFO(dir)->volNumber))
		kludge = 0;
	else
#ifdef CONFIG_NCPFS_EXTRAS
	if (NCP_SERVER(dir)->m.flags & NCP_MOUNT_SYMLINKS)
		kludge = 1;
	else
#endif
	/* EPERM is returned by VFS if symlink procedure does not exist */
		return -EPERM;
  
	rawlink = kmalloc(NCP_MAX_SYMLINK_SIZE, GFP_KERNEL);
	if (!rawlink)
		return -ENOMEM;

	if (kludge) {
		mode = 0;
		attr = aSHARED | aHIDDEN;
		((__le32 *)rawlink)[0]=NCP_SYMLINK_MAGIC0;
		((__le32 *)rawlink)[1]=NCP_SYMLINK_MAGIC1;
		hdr = 8;
	} else {
		mode = S_IFLNK | S_IRWXUGO;
		attr = 0;
		hdr = 0;
	}			

	length = strlen(symname);
	/* map to/from server charset, do not touch upper/lower case as
	   symlink can point out of ncp filesystem */
	outlen = NCP_MAX_SYMLINK_SIZE - hdr;
	err = ncp_io2vol(NCP_SERVER(dir), rawlink + hdr, &outlen, symname, length, 0);
	if (err)
		goto failfree;

	outlen += hdr;

	err = -EIO;
	if (ncp_create_new(dir,dentry,mode,0,attr)) {
		goto failfree;
	}

	inode=dentry->d_inode;

	if (ncp_make_open(inode, O_WRONLY))
		goto failfree;

	if (ncp_write_kernel(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle, 
			     0, outlen, rawlink, &i) || i!=outlen) {
		goto fail;
	}

	ncp_inode_close(inode);
	ncp_make_closed(inode);
	kfree(rawlink);
	return 0;
fail:;
	ncp_inode_close(inode);
	ncp_make_closed(inode);
failfree:;
	kfree(rawlink);
	return err;
}