⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ioctl.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
				return -EACCES;			}			if (server->root_setuped) return -EBUSY;			if (copy_from_user(&sr, argp, sizeof(sr)))				return -EFAULT;			if (sr.volNumber < 0) {				server->m.mounted_vol[0] = 0;				vnum = NCP_NUMBER_OF_VOLUMES;				de = 0;				dosde = 0;			} else if (sr.volNumber >= NCP_NUMBER_OF_VOLUMES) {				return -EINVAL;			} else if (ncp_mount_subdir(server, sr.volNumber,						sr.namespace, sr.dirEntNum,						&vnum, &de, &dosde)) {				return -ENOENT;			}						dentry = inode->i_sb->s_root;			server->root_setuped = 1;			if (dentry) {				struct inode* inode = dentry->d_inode;								if (inode) {					NCP_FINFO(inode)->volNumber = vnum;					NCP_FINFO(inode)->dirEntNum = de;					NCP_FINFO(inode)->DosDirNum = dosde;				} else					DPRINTK("ncpfs: s_root->d_inode==NULL\n");			} else				DPRINTK("ncpfs: s_root==NULL\n");			return 0;		}#ifdef CONFIG_NCPFS_PACKET_SIGNING		case NCP_IOC_SIGN_INIT:		if ((file_permission(filp, MAY_WRITE) != 0)		    && (current->uid != server->m.mounted_uid))		{			return -EACCES;		}		if (argp) {			if (server->sign_wanted)			{				struct ncp_sign_init sign;				if (copy_from_user(&sign, argp, sizeof(sign)))					return -EFAULT;				memcpy(server->sign_root,sign.sign_root,8);				memcpy(server->sign_last,sign.sign_last,16);				server->sign_active = 1;			}			/* ignore when signatures not wanted */		} else {			server->sign_active = 0;		}		return 0;				        case NCP_IOC_SIGN_WANTED:		if ((file_permission(filp, MAY_READ) != 0)		    && (current->uid != server->m.mounted_uid))		{			return -EACCES;		}		                if (put_user(server->sign_wanted, (int __user *)argp))			return -EFAULT;                return 0;	case NCP_IOC_SET_SIGN_WANTED:		{			int newstate;			if ((file_permission(filp, MAY_WRITE) != 0)			    && (current->uid != server->m.mounted_uid))			{				return -EACCES;			}			/* get only low 8 bits... */			if (get_user(newstate, (unsigned char __user *)argp))				return -EFAULT;			if (server->sign_active) {				/* cannot turn signatures OFF when active */				if (!newstate) return -EINVAL;			} else {				server->sign_wanted = newstate != 0;			}			return 0;		}#endif /* CONFIG_NCPFS_PACKET_SIGNING */#ifdef CONFIG_NCPFS_IOCTL_LOCKING	case NCP_IOC_LOCKUNLOCK:		if ((file_permission(filp, MAY_WRITE) != 0)		    && (current->uid != server->m.mounted_uid))		{			return -EACCES;		}		{			struct ncp_lock_ioctl	 rqdata;			int result;			if (copy_from_user(&rqdata, argp, sizeof(rqdata)))				return -EFAULT;			if (rqdata.origin != 0)				return -EINVAL;			/* check for cmd */			switch (rqdata.cmd) {				case NCP_LOCK_EX:				case NCP_LOCK_SH:						if (rqdata.timeout == 0)							rqdata.timeout = NCP_LOCK_DEFAULT_TIMEOUT;						else if (rqdata.timeout > NCP_LOCK_MAX_TIMEOUT)							rqdata.timeout = NCP_LOCK_MAX_TIMEOUT;						break;				case NCP_LOCK_LOG:						rqdata.timeout = NCP_LOCK_DEFAULT_TIMEOUT;	/* has no effect */				case NCP_LOCK_CLEAR:						break;				default:						return -EINVAL;			}			/* locking needs both read and write access */			if ((result = ncp_make_open(inode, O_RDWR)) != 0)			{				return result;			}			result = -EIO;			if (!ncp_conn_valid(server))				goto outrel;			result = -EISDIR;			if (!S_ISREG(inode->i_mode))				goto outrel;			if (rqdata.cmd == NCP_LOCK_CLEAR)			{				result = ncp_ClearPhysicalRecord(NCP_SERVER(inode),							NCP_FINFO(inode)->file_handle, 							rqdata.offset,							rqdata.length);				if (result > 0) result = 0;	/* no such lock */			}			else			{				int lockcmd;				switch (rqdata.cmd)				{					case NCP_LOCK_EX:  lockcmd=1; break;					case NCP_LOCK_SH:  lockcmd=3; break;					default:	   lockcmd=0; break;				}				result = ncp_LogPhysicalRecord(NCP_SERVER(inode),							NCP_FINFO(inode)->file_handle,							lockcmd,							rqdata.offset,							rqdata.length,							rqdata.timeout);				if (result > 0) result = -EAGAIN;			}outrel:						ncp_inode_close(inode);			return result;		}#endif	/* CONFIG_NCPFS_IOCTL_LOCKING */#ifdef CONFIG_COMPAT	case NCP_IOC_GETOBJECTNAME_32:		if (current->uid != server->m.mounted_uid) {			return -EACCES;		}		{			struct compat_ncp_objectname_ioctl user;			size_t outl;			if (copy_from_user(&user, argp, sizeof(user)))				return -EFAULT;			user.auth_type = server->auth.auth_type;			outl = user.object_name_len;			user.object_name_len = server->auth.object_name_len;			if (outl > user.object_name_len)				outl = user.object_name_len;			if (outl) {				if (copy_to_user(compat_ptr(user.object_name),						 server->auth.object_name,						 outl)) return -EFAULT;			}			if (copy_to_user(argp, &user, sizeof(user)))				return -EFAULT;			return 0;		}#endif	case NCP_IOC_GETOBJECTNAME:		if (current->uid != server->m.mounted_uid) {			return -EACCES;		}		{			struct ncp_objectname_ioctl user;			size_t outl;			if (copy_from_user(&user, argp, sizeof(user)))				return -EFAULT;			user.auth_type = server->auth.auth_type;			outl = user.object_name_len;			user.object_name_len = server->auth.object_name_len;			if (outl > user.object_name_len)				outl = user.object_name_len;			if (outl) {				if (copy_to_user(user.object_name,						 server->auth.object_name,						 outl)) return -EFAULT;			}			if (copy_to_user(argp, &user, sizeof(user)))				return -EFAULT;			return 0;		}#ifdef CONFIG_COMPAT	case NCP_IOC_SETOBJECTNAME_32:#endif	case NCP_IOC_SETOBJECTNAME:		if (current->uid != server->m.mounted_uid) {			return -EACCES;		}		{			struct ncp_objectname_ioctl user;			void* newname;			void* oldname;			size_t oldnamelen;			void* oldprivate;			size_t oldprivatelen;#ifdef CONFIG_COMPAT			if (cmd == NCP_IOC_SETOBJECTNAME_32) {				struct compat_ncp_objectname_ioctl user32;				if (copy_from_user(&user32, argp, sizeof(user32)))					return -EFAULT;				user.auth_type = user32.auth_type;				user.object_name_len = user32.object_name_len;				user.object_name = compat_ptr(user32.object_name);			} else#endif			if (copy_from_user(&user, argp, sizeof(user)))				return -EFAULT;			if (user.object_name_len > NCP_OBJECT_NAME_MAX_LEN)				return -ENOMEM;			if (user.object_name_len) {				newname = kmalloc(user.object_name_len, GFP_USER);				if (!newname)					return -ENOMEM;				if (copy_from_user(newname, user.object_name, user.object_name_len)) {					kfree(newname);					return -EFAULT;				}			} else {				newname = NULL;			}			/* enter critical section */			/* maybe that kfree can sleep so do that this way */			/* it is at least more SMP friendly (in future...) */			oldname = server->auth.object_name;			oldnamelen = server->auth.object_name_len;			oldprivate = server->priv.data;			oldprivatelen = server->priv.len;			server->auth.auth_type = user.auth_type;			server->auth.object_name_len = user.object_name_len;			server->auth.object_name = newname;			server->priv.len = 0;			server->priv.data = NULL;			/* leave critical section */			kfree(oldprivate);			kfree(oldname);			return 0;		}#ifdef CONFIG_COMPAT	case NCP_IOC_GETPRIVATEDATA_32:#endif	case NCP_IOC_GETPRIVATEDATA:		if (current->uid != server->m.mounted_uid) {			return -EACCES;		}		{			struct ncp_privatedata_ioctl user;			size_t outl;#ifdef CONFIG_COMPAT			if (cmd == NCP_IOC_GETPRIVATEDATA_32) {				struct compat_ncp_privatedata_ioctl user32;				if (copy_from_user(&user32, argp, sizeof(user32)))					return -EFAULT;				user.len = user32.len;				user.data = compat_ptr(user32.data);			} else#endif			if (copy_from_user(&user, argp, sizeof(user)))				return -EFAULT;			outl = user.len;			user.len = server->priv.len;			if (outl > user.len) outl = user.len;			if (outl) {				if (copy_to_user(user.data,						 server->priv.data,						 outl)) return -EFAULT;			}#ifdef CONFIG_COMPAT			if (cmd == NCP_IOC_GETPRIVATEDATA_32) {				struct compat_ncp_privatedata_ioctl user32;				user32.len = user.len;				user32.data = (unsigned long) user.data;				if (copy_to_user(argp, &user32, sizeof(user32)))					return -EFAULT;			} else#endif			if (copy_to_user(argp, &user, sizeof(user)))				return -EFAULT;			return 0;		}#ifdef CONFIG_COMPAT	case NCP_IOC_SETPRIVATEDATA_32:#endif	case NCP_IOC_SETPRIVATEDATA:		if (current->uid != server->m.mounted_uid) {			return -EACCES;		}		{			struct ncp_privatedata_ioctl user;			void* new;			void* old;			size_t oldlen;#ifdef CONFIG_COMPAT			if (cmd == NCP_IOC_SETPRIVATEDATA_32) {				struct compat_ncp_privatedata_ioctl user32;				if (copy_from_user(&user32, argp, sizeof(user32)))					return -EFAULT;				user.len = user32.len;				user.data = compat_ptr(user32.data);			} else#endif			if (copy_from_user(&user, argp, sizeof(user)))				return -EFAULT;			if (user.len > NCP_PRIVATE_DATA_MAX_LEN)				return -ENOMEM;			if (user.len) {				new = kmalloc(user.len, GFP_USER);				if (!new)					return -ENOMEM;				if (copy_from_user(new, user.data, user.len)) {					kfree(new);					return -EFAULT;				}			} else {				new = NULL;			}			/* enter critical section */			old = server->priv.data;			oldlen = server->priv.len;			server->priv.len = user.len;			server->priv.data = new;			/* leave critical section */			kfree(old);			return 0;		}#ifdef CONFIG_NCPFS_NLS	case NCP_IOC_SETCHARSETS:		return ncp_set_charsets(server, argp);			case NCP_IOC_GETCHARSETS:		return ncp_get_charsets(server, argp);#endif /* CONFIG_NCPFS_NLS */	case NCP_IOC_SETDENTRYTTL:		if ((file_permission(filp, MAY_WRITE) != 0) &&				 (current->uid != server->m.mounted_uid))			return -EACCES;		{			u_int32_t user;			if (copy_from_user(&user, argp, sizeof(user)))				return -EFAULT;			/* 20 secs at most... */			if (user > 20000)				return -EINVAL;			user = (user * HZ) / 1000;			server->dentry_ttl = user;			return 0;		}			case NCP_IOC_GETDENTRYTTL:		{			u_int32_t user = (server->dentry_ttl * 1000) / HZ;			if (copy_to_user(argp, &user, sizeof(user)))				return -EFAULT;			return 0;		}	}	return -EINVAL;}#ifdef CONFIG_COMPATlong ncp_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg){	struct inode *inode = file->f_path.dentry->d_inode;	int ret;	lock_kernel();	arg = (unsigned long) compat_ptr(arg);	ret = ncp_ioctl(inode, file, cmd, arg);	unlock_kernel();	return ret;}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -