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

📄 proc.c

📁 elinux jffs初始版本 具体了解JFFS的文件系统!
💻 C
📖 第 1 页 / 共 3 页
字号:
	smb_setup_header_exclusive(server, SMBread, 5, 0);	buf = server->packet;	WSET(buf, smb_vwv0, finfo->fileid);	WSET(buf, smb_vwv1, count);	DSET(buf, smb_vwv2, offset);	WSET(buf, smb_vwv4, 0);	if ((error = smb_request_ok(server, SMBread, 5, -1)) < 0)	{		smb_unlock_server(server);		return error;	}	returned_count = WVAL(server->packet, smb_vwv0);	smb_decode_data(SMB_BUF(server->packet), data, &data_len, fs);	smb_unlock_server(server);	if (returned_count != data_len)	{		printk("smb_proc_read: Warning, returned_count != data_len\n");		printk("smb_proc_read: ret_c=%d, data_len=%d\n",		       returned_count, data_len);	}	return data_len;}intsmb_proc_write(struct smb_server *server, struct smb_dirent *finfo,	       off_t offset, int count, const char *data){	int res = 0;	char *buf;	byte *p;	p = smb_setup_header_exclusive(server, SMBwrite, 5, count + 3);	buf = server->packet;	WSET(buf, smb_vwv0, finfo->fileid);	WSET(buf, smb_vwv1, count);	DSET(buf, smb_vwv2, offset);	WSET(buf, smb_vwv4, 0);	*p++ = 1;	WSET(p, 0, count);	memcpy_fromfs(p + 2, data, count);	if ((res = smb_request_ok(server, SMBwrite, 1, 0)) >= 0)	{		res = WVAL(server->packet, smb_vwv0);	}	smb_unlock_server(server);	return res;}intsmb_proc_create(struct inode *dir, const char *name, int len,		word attr, time_t ctime){	int error;	char *p;	struct smb_server *server = SMB_SERVER(dir);	char *buf;	__u16 fileid;	smb_lock_server(server);      retry:	buf = server->packet;	p = smb_setup_header(server, SMBcreate, 3, 0);	WSET(buf, smb_vwv0, attr);	DSET(buf, smb_vwv1, utc2local(ctime));	*p++ = 4;	p = smb_encode_path(server, p, SMB_INOP(dir), name, len);	smb_setup_bcc(server, p);	if ((error = smb_request_ok(server, SMBcreate, 1, 0)) < 0)	{		if (smb_retry(server))		{			goto retry;		}		smb_unlock_server(server);		return error;	}	fileid = WVAL(server->packet, smb_vwv0);	smb_unlock_server(server);	smb_proc_close(server, fileid, CURRENT_TIME);	return 0;}intsmb_proc_mv(struct inode *odir, const char *oname, const int olen,	    struct inode *ndir, const char *nname, const int nlen){	char *p;	struct smb_server *server = SMB_SERVER(odir);	int result;	smb_lock_server(server);      retry:	p = smb_setup_header(server, SMBmv, 1, 0);	WSET(server->packet, smb_vwv0, aSYSTEM | aHIDDEN);	*p++ = 4;	p = smb_encode_path(server, p, SMB_INOP(odir), oname, olen);	*p++ = 4;	p = smb_encode_path(server, p, SMB_INOP(ndir), nname, nlen);	smb_setup_bcc(server, p);	if ((result = smb_request_ok(server, SMBmv, 0, 0)) < 0)	{		if (smb_retry(server))		{			goto retry;		}	}	smb_unlock_server(server);	return result;}intsmb_proc_mkdir(struct inode *dir, const char *name, const int len){	char *p;	int result;	struct smb_server *server = SMB_SERVER(dir);	smb_lock_server(server);      retry:	p = smb_setup_header(server, SMBmkdir, 0, 0);	*p++ = 4;	p = smb_encode_path(server, p, SMB_INOP(dir), name, len);	smb_setup_bcc(server, p);	if ((result = smb_request_ok(server, SMBmkdir, 0, 0)) < 0)	{		if (smb_retry(server))		{			goto retry;		}	}	smb_unlock_server(server);	return result;}intsmb_proc_rmdir(struct inode *dir, const char *name, const int len){	char *p;	int result;	struct smb_server *server = SMB_SERVER(dir);	smb_lock_server(server);      retry:	p = smb_setup_header(server, SMBrmdir, 0, 0);	*p++ = 4;	p = smb_encode_path(server, p, SMB_INOP(dir), name, len);	smb_setup_bcc(server, p);	if ((result = smb_request_ok(server, SMBrmdir, 0, 0)) < 0)	{		if (smb_retry(server))		{			goto retry;		}	}	smb_unlock_server(server);	return result;}intsmb_proc_unlink(struct inode *dir, const char *name, const int len){	char *p;	struct smb_server *server = SMB_SERVER(dir);	int result;	smb_lock_server(server);      retry:	p = smb_setup_header(server, SMBunlink, 1, 0);	WSET(server->packet, smb_vwv0, aSYSTEM | aHIDDEN);	*p++ = 4;	p = smb_encode_path(server, p, SMB_INOP(dir), name, len);	smb_setup_bcc(server, p);	if ((result = smb_request_ok(server, SMBunlink, 0, 0)) < 0)	{		if (smb_retry(server))		{			goto retry;		}	}	smb_unlock_server(server);	return result;}intsmb_proc_trunc(struct smb_server *server, word fid, dword length){	char *p;	char *buf;	int result;	smb_lock_server(server);      retry:	buf = server->packet;	p = smb_setup_header(server, SMBwrite, 5, 0);	WSET(buf, smb_vwv0, fid);	WSET(buf, smb_vwv1, 0);	DSET(buf, smb_vwv2, length);	WSET(buf, smb_vwv4, 0);	p = smb_encode_ascii(p, "", 0);	smb_setup_bcc(server, p);	if ((result = smb_request_ok(server, SMBwrite, 1, 0)) < 0)	{		if (smb_retry(server))		{			goto retry;		}	}	smb_unlock_server(server);	return result;}static voidsmb_init_dirent(struct smb_server *server, struct smb_dirent *entry){	memset(entry, 0, sizeof(struct smb_dirent));	entry->f_nlink = 1;	entry->f_uid = server->m.uid;	entry->f_gid = server->m.gid;	entry->f_blksize = 512;}static voidsmb_finish_dirent(struct smb_server *server, struct smb_dirent *entry){	if ((entry->attr & aDIR) != 0)	{		entry->f_mode = server->m.dir_mode;		entry->f_size = 512;	} else	{		entry->f_mode = server->m.file_mode;	}	if (entry->attr & aRONLY)		entry->f_mode &= ~0222;	if ((entry->f_blksize != 0) && (entry->f_size != 0))	{		entry->f_blocks =		    (entry->f_size - 1) / entry->f_blksize + 1;	} else	{		entry->f_blocks = 0;	}	return;}voidsmb_init_root_dirent(struct smb_server *server, struct smb_dirent *entry){	smb_init_dirent(server, entry);	entry->attr = aDIR;	entry->f_ino = 1;	smb_finish_dirent(server, entry);}static char *smb_decode_dirent(struct smb_server *server, char *p, struct smb_dirent *entry){	smb_init_dirent(server, entry);	p += SMB_STATUS_SIZE;	/* reserved (search_status) */	entry->attr = BVAL(p, 0);	entry->f_mtime = entry->f_atime = entry->f_ctime =	    date_dos2unix(WVAL(p, 1), WVAL(p, 3));	entry->f_size = DVAL(p, 5);	entry->len = strlen(p + 9);	if (entry->len > 12)	{		entry->len = 12;	}	memcpy(entry->name, p + 9, entry->len);	entry->name[entry->len] = '\0';	while (entry->len > 2)	{		/* Pathworks fills names with spaces */		entry->len -= 1;		if (entry->name[entry->len] == ' ')		{			entry->name[entry->len] = '\0';		}	}	switch (server->case_handling)	{	case CASE_UPPER:		str_upper(entry->name);		break;	case CASE_LOWER:		str_lower(entry->name);		break;	default:		break;	}	DPRINTK("smb_decode_dirent: name = %s\n", entry->name);	smb_finish_dirent(server, entry);	return p + 22;}/* This routine is used to read in directory entries from the network.   Note that it is for short directory name seeks, i.e.: protocol <   PROTOCOL_LANMAN2 */static intsmb_proc_readdir_short(struct smb_server *server, struct inode *dir, int fpos,		       int cache_size, struct smb_dirent *entry){	char *p;	char *buf;	int error;	int result;	int i;	int first, total_count;	struct smb_dirent *current_entry;	word bcc;	word count;	char status[SMB_STATUS_SIZE];	int entries_asked = (server->max_xmit - 100) / SMB_DIRINFO_SIZE;	DPRINTK("SMB call  readdir %d @ %d\n", cache_size, fpos);	smb_lock_server(server);      retry:	buf = server->packet;	first = 1;	total_count = 0;	current_entry = entry;	while (1)	{		if (first == 1)		{			p = smb_setup_header(server, SMBsearch, 2, 0);			WSET(buf, smb_vwv0, entries_asked);			WSET(buf, smb_vwv1, aDIR);			*p++ = 4;			p = smb_encode_path(server, p, SMB_INOP(dir), "*.*", 3);			*p++ = 5;			WSET(p, 0, 0);			p += 2;		} else		{			p = smb_setup_header(server, SMBsearch, 2, 0);			WSET(buf, smb_vwv0, entries_asked);			WSET(buf, smb_vwv1, aDIR);			p = smb_encode_ascii(p, "", 0);			*p++ = 5;			WSET(p, 0, SMB_STATUS_SIZE);			p += 2;			memcpy(p, status, SMB_STATUS_SIZE);			p += SMB_STATUS_SIZE;		}		smb_setup_bcc(server, p);		if ((error = smb_request_ok(server, SMBsearch, 1, -1)) < 0)		{			if ((server->rcls == ERRDOS)			    && (server->err == ERRnofiles))			{				result = total_count - fpos;				goto unlock_return;			} else			{				if (smb_retry(server))				{					goto retry;				}				result = error;				goto unlock_return;			}		}		p = SMB_VWV(server->packet);		p = smb_decode_word(p, &count);		p = smb_decode_word(p, &bcc);		first = 0;		if (count <= 0)		{			result = total_count - fpos;			goto unlock_return;		}		if (bcc != count * SMB_DIRINFO_SIZE + 3)		{			result = -EIO;			goto unlock_return;		}		p += 3;		/* Skipping VBLOCK header				   (5, length lo, length hi). */		/* Read the last entry into the status field. */		memcpy(status,		       SMB_BUF(server->packet) + 3 +		       (count - 1) * SMB_DIRINFO_SIZE,		       SMB_STATUS_SIZE);		/* Now we are ready to parse smb directory entries. */		for (i = 0; i < count; i++)		{			if (total_count < fpos)			{				p += SMB_DIRINFO_SIZE;				DDPRINTK("smb_proc_readdir: skipped entry.\n");				DDPRINTK("                  total_count = %d\n"					 "                i = %d, fpos = %d\n",					 total_count, i, fpos);			} else if (total_count >= fpos + cache_size)			{				result = total_count - fpos;				goto unlock_return;			} else			{				p = smb_decode_dirent(server, p,						      current_entry);				current_entry->f_pos = total_count;				DDPRINTK("smb_proc_readdir: entry->f_pos = "					 "%lu\n", entry->f_pos);				current_entry += 1;			}			total_count += 1;		}	}      unlock_return:	smb_unlock_server(server);	return result;}/* interpret a long filename structure - this is mostly guesses at the   moment.  The length of the structure is returned.  The structure of   a long filename depends on the info level. 260 is used by NT and 2   is used by OS/2. */static char *smb_decode_long_dirent(struct smb_server *server, char *p,		       struct smb_dirent *entry, int level){	char *result;	smb_init_dirent(server, entry);	switch (level)	{		/* We might add more levels later... */	case 1:		entry->len = BVAL(p, 26);		strncpy(entry->name, p + 27, entry->len);		entry->name[entry->len] = '\0';		entry->f_size = DVAL(p, 16);		entry->attr = BVAL(p, 24);		entry->f_ctime = date_dos2unix(WVAL(p, 6), WVAL(p, 4));		entry->f_atime = date_dos2unix(WVAL(p, 10), WVAL(p, 8));		entry->f_mtime = date_dos2unix(WVAL(p, 14), WVAL(p, 12));		result = p + 28 + BVAL(p, 26);		break;	default:		DPRINTK("Unknown long filename format %d\n", level);		result = p + WVAL(p, 0);	}	switch (server->case_handling)	{	case CASE_UPPER:		str_upper(entry->name);		break;	case CASE_LOWER:		str_lower(entry->name);		break;	default:		break;	}	smb_finish_dirent(server, entry);	return result;}intsmb_proc_readdir_long(struct smb_server *server, struct inode *dir, int fpos,		      int cache_size, struct smb_dirent *cache){	/* NT uses 260, OS/2 uses 2. Both accept 1. */	const int info_level = 1;	const int max_matches = 512;	char *p;	char *lastname;	int lastname_len;	int i;	int first, entries, entries_seen;	unsigned char *resp_data = NULL;	unsigned char *resp_param = NULL;	int resp_data_len = 0;	int resp_param_len = 0;	__u16 command;	int result;	int ff_resume_key = 0;	int ff_searchcount = 0;	int ff_eos = 0;	int ff_lastname = 0;	int ff_dir_handle = 0;	int loop_count = 0;	char param[SMB_MAXPATHLEN + 2 + 12];	int mask_len;	unsigned char *mask = &(param[12]);	mask_len = smb_encode_path(server, mask,				   SMB_INOP(dir), "*", 1) - mask;	mask[mask_len] = 0;	mask[mask_len + 1] = 0;	DPRINTK("smb_readdir_long cache=%d, fpos=%d, mask=%s\n",		cache_size, fpos, mask);	smb_lock_server(server);      retry:	first = 1;	entries = 0;	entries_seen = 2;	while (ff_eos == 0)	{		loop_count += 1;		if (loop_count > 200)		{			printk("smb_proc_readdir_long: "			       "Looping in FIND_NEXT??\n");			break;		}		if (first != 0)		{			command = TRANSACT2_FINDFIRST;			WSET(param, 0, aSYSTEM | aHIDDEN | aDIR);			WSET(param, 2, max_matches);	/* max count */			WSET(param, 4, 8 + 4 + 2);	/* resume required +							   close on end +							   continue */			WSET(param, 6, info_level);			DSET(param, 8, 0);		} else		{			command = TRANSACT2_FINDNEXT;			DPRINTK("hand=0x%X resume=%d ff_lastname=%d mask=%s\n",			     ff_dir_handle, ff_resume_key, ff_lastname, mask);			WSET(param, 0, ff_dir_handle);			WSET(param, 2, max_matches);	/* max count */			WSET(param, 4, info_level);			DSET(param, 6, ff_resume_key);	/* ff_resume_key */			WSET(param, 10, 8 + 4 + 2);	/* resume required +							   close on end +							   continue */#ifdef CONFIG_SMB_WIN95			/* Windows 95 is not able to deliver answers			   to FIND_NEXT fast enough, so sleep 0.2 seconds */			current->timeout = jiffies + HZ / 5;			current->state = TASK_INTERRUPTIBLE;			schedule();			current->timeout = 0;#endif		}		result = smb_trans2_request(server, command,					    0, NULL, 12 + mask_len + 2, param,					    &resp_data_len, &resp_data,					    &resp_param_len, &resp_param);		if (result < 0)		{			if (smb_retry(server))			{				goto retry;			}			DPRINTK("smb_proc_readdir_long: "				"got error from trans2_request\n");			break;		}		if (server->rcls != 0)		{			result = -EIO;			break;		}		/* parse out some important return info */		if (first != 0)		{			ff_dir_handle = WVAL(resp_param, 0);			ff_searchcount = WVAL(resp_param, 2);			ff_eos = WVAL(resp_param, 4);			ff_lastname = WVAL(resp_param, 8);		} else		{			ff_searchcount = WVAL(resp_param, 0);			ff_eos = WVAL(resp_param, 2);			ff_lastname = WVAL(resp_param, 6);		}		if (ff_searchcount == 0)		{			break;		}		/* point to the data bytes */		p = resp_data;		/* we might need the lastname for continuations */		lastname = "";

⌨️ 快捷键说明

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