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

📄 ncplib_kernel.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	}	if (server->ncp_reply_size < 12) {		ncp_unlock_server(server);		return 0xFF;	}	*rsize = server->ncp_reply_size - 12;	ncp_unlock_server(server);	buffer = buffer + sizeof(struct ncp_reply_header);	*rbuf = buffer + 12;	*cnt = WVAL_LH(buffer + 10);	*more = BVAL(buffer + 9);	memcpy(seq, buffer, 9);	return 0;}static intncp_RenameNSEntry(struct ncp_server *server,		  struct inode *old_dir, char *old_name, __le16 old_type,		  struct inode *new_dir, char *new_name){	int result = -EINVAL;	if ((old_dir == NULL) || (old_name == NULL) ||	    (new_dir == NULL) || (new_name == NULL))		goto out;	ncp_init_request(server);	ncp_add_byte(server, 4);	/* subfunction */	ncp_add_byte(server, server->name_space[NCP_FINFO(old_dir)->volNumber]);	ncp_add_byte(server, 1);	/* rename flag */	ncp_add_word(server, old_type);	/* search attributes */	/* source Handle Path */	ncp_add_byte(server, NCP_FINFO(old_dir)->volNumber);	ncp_add_dword(server, NCP_FINFO(old_dir)->dirEntNum);	ncp_add_byte(server, 1);	ncp_add_byte(server, 1);	/* 1 source component */	/* dest Handle Path */	ncp_add_byte(server, NCP_FINFO(new_dir)->volNumber);	ncp_add_dword(server, NCP_FINFO(new_dir)->dirEntNum);	ncp_add_byte(server, 1);	ncp_add_byte(server, 1);	/* 1 destination component */	/* source path string */	ncp_add_pstring(server, old_name);	/* dest path string */	ncp_add_pstring(server, new_name);	result = ncp_request(server, 87);	ncp_unlock_server(server);out:	return result;}int ncp_ren_or_mov_file_or_subdir(struct ncp_server *server,				struct inode *old_dir, char *old_name,				struct inode *new_dir, char *new_name){        int result;        __le16 old_type = cpu_to_le16(0x06);/* If somebody can do it atomic, call me... vandrove@vc.cvut.cz */	result = ncp_RenameNSEntry(server, old_dir, old_name, old_type,	                                   new_dir, new_name);        if (result == 0xFF)	/* File Not Found, try directory */	{		old_type = cpu_to_le16(0x16);		result = ncp_RenameNSEntry(server, old_dir, old_name, old_type,						   new_dir, new_name);	}	if (result != 0x92) return result;	/* All except NO_FILES_RENAMED */	result = ncp_del_file_or_subdir(server, new_dir, new_name);	if (result != 0) return -EACCES;	result = ncp_RenameNSEntry(server, old_dir, old_name, old_type,					   new_dir, new_name);	return result;}	/* We have to transfer to/from user space */intncp_read_kernel(struct ncp_server *server, const char *file_id,	     __u32 offset, __u16 to_read, char *target, int *bytes_read){	char *source;	int result;	ncp_init_request(server);	ncp_add_byte(server, 0);	ncp_add_mem(server, file_id, 6);	ncp_add_be32(server, offset);	ncp_add_be16(server, to_read);	if ((result = ncp_request(server, 72)) != 0) {		goto out;	}	*bytes_read = ncp_reply_be16(server, 0);	source = ncp_reply_data(server, 2 + (offset & 1));	memcpy(target, source, *bytes_read);out:	ncp_unlock_server(server);	return result;}/* There is a problem... egrep and some other silly tools do:	x = mmap(NULL, MAP_PRIVATE, PROT_READ|PROT_WRITE, <ncpfs fd>, 32768);	read(<ncpfs fd>, x, 32768);   Now copying read result by copy_to_user causes pagefault. This pagefault   could not be handled because of server was locked due to read. So we have   to use temporary buffer. So ncp_unlock_server must be done before   copy_to_user (and for write, copy_from_user must be done before    ncp_init_request... same applies for send raw packet ioctl). Because of   file is normally read in bigger chunks, caller provides kmalloced    (vmalloced) chunk of memory with size >= to_read... */intncp_read_bounce(struct ncp_server *server, const char *file_id,	 __u32 offset, __u16 to_read, char __user *target, int *bytes_read,	 void* bounce, __u32 bufsize){	int result;	ncp_init_request(server);	ncp_add_byte(server, 0);	ncp_add_mem(server, file_id, 6);	ncp_add_be32(server, offset);	ncp_add_be16(server, to_read);	result = ncp_request2(server, 72, bounce, bufsize);	ncp_unlock_server(server);	if (!result) {		int len = be16_to_cpu(get_unaligned((__be16*)((char*)bounce + 			  sizeof(struct ncp_reply_header))));		result = -EIO;		if (len <= to_read) {			char* source;			source = (char*)bounce + 			         sizeof(struct ncp_reply_header) + 2 + 			         (offset & 1);			*bytes_read = len;			result = 0;			if (copy_to_user(target, source, len))				result = -EFAULT;		}	}	return result;}intncp_write_kernel(struct ncp_server *server, const char *file_id,		 __u32 offset, __u16 to_write,		 const char *source, int *bytes_written){	int result;	ncp_init_request(server);	ncp_add_byte(server, 0);	ncp_add_mem(server, file_id, 6);	ncp_add_be32(server, offset);	ncp_add_be16(server, to_write);	ncp_add_mem(server, source, to_write);		if ((result = ncp_request(server, 73)) == 0)		*bytes_written = to_write;	ncp_unlock_server(server);	return result;}#ifdef CONFIG_NCPFS_IOCTL_LOCKINGintncp_LogPhysicalRecord(struct ncp_server *server, const char *file_id,	  __u8 locktype, __u32 offset, __u32 length, __u16 timeout){	int result;	ncp_init_request(server);	ncp_add_byte(server, locktype);	ncp_add_mem(server, file_id, 6);	ncp_add_be32(server, offset);	ncp_add_be32(server, length);	ncp_add_be16(server, timeout);	if ((result = ncp_request(server, 0x1A)) != 0)	{		ncp_unlock_server(server);		return result;	}	ncp_unlock_server(server);	return 0;}intncp_ClearPhysicalRecord(struct ncp_server *server, const char *file_id,	  __u32 offset, __u32 length){	int result;	ncp_init_request(server);	ncp_add_byte(server, 0);	/* who knows... lanalyzer says that */	ncp_add_mem(server, file_id, 6);	ncp_add_be32(server, offset);	ncp_add_be32(server, length);	if ((result = ncp_request(server, 0x1E)) != 0)	{		ncp_unlock_server(server);		return result;	}	ncp_unlock_server(server);	return 0;}#endif	/* CONFIG_NCPFS_IOCTL_LOCKING */#ifdef CONFIG_NCPFS_NLS/* This are the NLS conversion routines with inspirations and code parts * from the vfat file system and hints from Petr Vandrovec. */intncp__io2vol(struct ncp_server *server, unsigned char *vname, unsigned int *vlen,		const unsigned char *iname, unsigned int ilen, int cc){	struct nls_table *in = server->nls_io;	struct nls_table *out = server->nls_vol;	unsigned char *vname_start;	unsigned char *vname_end;	const unsigned char *iname_end;	iname_end = iname + ilen;	vname_start = vname;	vname_end = vname + *vlen - 1;	while (iname < iname_end) {		int chl;		wchar_t ec;		if (NCP_IS_FLAG(server, NCP_FLAG_UTF8)) {			int k;			k = utf8_mbtowc(&ec, iname, iname_end - iname);			if (k < 0)				return -EINVAL;			iname += k;		} else {			if (*iname == NCP_ESC) {				int k;				if (iname_end - iname < 5)					goto nospec;				ec = 0;				for (k = 1; k < 5; k++) {					unsigned char nc;					nc = iname[k] - '0';					if (nc >= 10) {						nc -= 'A' - '0' - 10;						if ((nc < 10) || (nc > 15)) {							goto nospec;						}					}					ec = (ec << 4) | nc;				}				iname += 5;			} else {nospec:;							if ( (chl = in->char2uni(iname, iname_end - iname, &ec)) < 0)					return chl;				iname += chl;			}		}		/* unitoupper should be here! */		chl = out->uni2char(ec, vname, vname_end - vname);		if (chl < 0)			return chl;		/* this is wrong... */		if (cc) {			int chi;			for (chi = 0; chi < chl; chi++){				vname[chi] = ncp_toupper(out, vname[chi]);			}		}		vname += chl;	}	*vname = 0;	*vlen = vname - vname_start;	return 0;}intncp__vol2io(struct ncp_server *server, unsigned char *iname, unsigned int *ilen,		const unsigned char *vname, unsigned int vlen, int cc){	struct nls_table *in = server->nls_vol;	struct nls_table *out = server->nls_io;	const unsigned char *vname_end;	unsigned char *iname_start;	unsigned char *iname_end;	unsigned char *vname_cc;	int err;	vname_cc = NULL;	if (cc) {		int i;		/* this is wrong! */		vname_cc = kmalloc(vlen, GFP_KERNEL);		if (!vname_cc)			return -ENOMEM;		for (i = 0; i < vlen; i++)			vname_cc[i] = ncp_tolower(in, vname[i]);		vname = vname_cc;	}	iname_start = iname;	iname_end = iname + *ilen - 1;	vname_end = vname + vlen;	while (vname < vname_end) {		wchar_t ec;		int chl;		if ( (chl = in->char2uni(vname, vname_end - vname, &ec)) < 0) {			err = chl;			goto quit;		}		vname += chl;		/* unitolower should be here! */		if (NCP_IS_FLAG(server, NCP_FLAG_UTF8)) {			int k;			k = utf8_wctomb(iname, ec, iname_end - iname);			if (k < 0) {				err = -ENAMETOOLONG;				goto quit;			}			iname += k;		} else {			if ( (chl = out->uni2char(ec, iname, iname_end - iname)) >= 0) {				iname += chl;			} else {				int k;				if (iname_end - iname < 5) {					err = -ENAMETOOLONG;					goto quit;				}				*iname = NCP_ESC;				for (k = 4; k > 0; k--) {					unsigned char v;										v = (ec & 0xF) + '0';					if (v > '9') {						v += 'A' - '9' - 1;					}					iname[k] = v;					ec >>= 4;				}				iname += 5;			}		}	}	*iname = 0;	*ilen = iname - iname_start;	err = 0;quit:;	if (cc)		kfree(vname_cc);	return err;}#elseintncp__io2vol(unsigned char *vname, unsigned int *vlen,		const unsigned char *iname, unsigned int ilen, int cc){	int i;	if (*vlen <= ilen)		return -ENAMETOOLONG;	if (cc)		for (i = 0; i < ilen; i++) {			*vname = toupper(*iname);			vname++;			iname++;		}	else {		memmove(vname, iname, ilen);		vname += ilen;	}	*vlen = ilen;	*vname = 0;	return 0;}intncp__vol2io(unsigned char *iname, unsigned int *ilen,		const unsigned char *vname, unsigned int vlen, int cc){	int i;	if (*ilen <= vlen)		return -ENAMETOOLONG;	if (cc)		for (i = 0; i < vlen; i++) {			*iname = tolower(*vname);			iname++;			vname++;		}	else {		memmove(iname, vname, vlen);		iname += vlen;	}	*ilen = vlen;	*iname = 0;	return 0;}#endif

⌨️ 快捷键说明

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