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

📄 proc.c

📁 elinux jffs初始版本 具体了解JFFS的文件系统!
💻 C
📖 第 1 页 / 共 3 页
字号:
		lastname_len = 0;		if (ff_lastname > 0)		{			switch (info_level)			{			case 260:				lastname = p + ff_lastname;				lastname_len = resp_data_len - ff_lastname;				ff_resume_key = 0;				break;			case 1:				lastname = p + ff_lastname + 1;				lastname_len = BVAL(p, ff_lastname);				ff_resume_key = 0;				break;			}		}		lastname_len = min(lastname_len, 256);		strncpy(mask, lastname, lastname_len);		mask[lastname_len] = '\0';		/* Now we are ready to parse smb directory entries. */		for (i = 0; i < ff_searchcount; i++)		{			struct smb_dirent *entry = &(cache[entries]);			p = smb_decode_long_dirent(server, p,						   entry, info_level);			DDPRINTK("smb_readdir_long: got %s\n", entry->name);			if ((entry->name[0] == '.')			    && ((entry->name[1] == '\0')				|| ((entry->name[1] == '.')				    && (entry->name[2] == '\0'))))			{				/* ignore . and .. from the server */				continue;			}			if (entries_seen >= fpos)			{				entry->f_pos = entries_seen;				entries += 1;			}			if (entries >= cache_size)			{				goto finished;			}			entries_seen += 1;		}		DPRINTK("received %d entries (eos=%d resume=%d)\n",			ff_searchcount, ff_eos, ff_resume_key);		first = 0;	}      finished:	smb_unlock_server(server);	return entries;}intsmb_proc_readdir(struct smb_server *server, struct inode *dir, int fpos,		 int cache_size, struct smb_dirent *entry){	if (server->protocol >= PROTOCOL_LANMAN2)		return smb_proc_readdir_long(server, dir, fpos, cache_size,					     entry);	else		return smb_proc_readdir_short(server, dir, fpos, cache_size,					      entry);}/* * This version uses the core protocol to get the attribute info. * It works OK with Win 3.11, 95 and NT 3.51, but NOT with NT 4 (bad mtime). */static intsmb_proc_getattr_core(struct inode *dir, const char *name, int len,		      struct smb_dirent *entry){	int result;	char *p;	struct smb_server *server = SMB_SERVER(dir);	char *buf;	smb_lock_server(server);	DDPRINTK("smb_proc_getattr_core: %s\n", name);      retry:	buf = server->packet;	p = smb_setup_header(server, SMBgetatr, 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, SMBgetatr, 10, 0)) < 0)	{		if (smb_retry(server))		{			goto retry;		}		smb_unlock_server(server);		return result;	}	/* N.B. Packet may change after request */	buf = server->packet;	entry->attr = WVAL(buf, smb_vwv0);	entry->f_ctime = entry->f_atime =	    entry->f_mtime = local2utc(DVAL(buf, smb_vwv1));	DDPRINTK("smb_proc_getattr_core: mtime=%ld\n", entry->f_mtime);	entry->f_size = DVAL(buf, smb_vwv3);	smb_unlock_server(server);	return 0;}/* * This version uses the trans2 findfirst to get the attribute info. * It works fine with NT 3.51 and NT 4 (any SP), but not with Win95 (ERRerror). */static intsmb_proc_getattr_ff(struct inode *dir, const char *name, int len,		    struct smb_dirent *entry){	unsigned char *resp_data = NULL;	unsigned char *resp_param = NULL;	int resp_data_len = 0;	int resp_param_len = 0;	char param[SMB_MAXPATHLEN + 1 + 12];	int mask_len;	unsigned char *mask = &(param[12]);	int result;	char *p;	struct smb_server *server = SMB_SERVER(dir);	mask_len = smb_encode_path(server, mask,				   SMB_INOP(dir), name, len) - mask;	mask[mask_len] = 0;	DDPRINTK("smb_proc_getattr_ff: mask=%s\n", mask);	smb_lock_server(server);      retry:	WSET(param, 0, aSYSTEM | aHIDDEN | aDIR);	WSET(param, 2, 1);      /* max count */	WSET(param, 4, 2 + 1);  /* close on end + close after this call */	WSET(param, 6, 1);      /* info level */	DSET(param, 8, 0);	result = smb_trans2_request(server, TRANSACT2_FINDFIRST,				    0, NULL, 12 + mask_len + 1, param,				    &resp_data_len, &resp_data,				    &resp_param_len, &resp_param);	if (result < 0)	{		if (smb_retry(server))		{			DPRINTK("smb_proc_getattr_ff: error=%d, retrying\n",				 result);			goto retry;		}		goto out;	}	if (server->rcls != 0)	{		result = -smb_errno(server->rcls, server->err);		if (result != -ENOENT)			DPRINTK("smb_proc_getattr_ff: rcls=%d, err=%d\n",				 server->rcls, server->err);		goto out;	}	/* Make sure we got enough data ... */	result = -EINVAL;      /* WVAL(resp_param, 2) is ff_searchcount */	if (resp_data_len < 22 || WVAL(resp_param, 2) != 1)	{		DPRINTK("smb_proc_getattr_ff: bad result, len=%d, count=%d\n",			 resp_data_len, WVAL(resp_param, 2));		goto out;	}	/* Decode the response (info level 1, as in smb_decode_long_dirent) */	p = resp_data;	entry->f_ctime = date_dos2unix(WVAL(p, 2), WVAL(p, 0));	entry->f_atime = date_dos2unix(WVAL(p, 6), WVAL(p, 4));	entry->f_mtime = date_dos2unix(WVAL(p, 10), WVAL(p, 8));	entry->f_size = DVAL(p, 12);	entry->attr = WVAL(p, 20);	DDPRINTK("smb_proc_getattr_ff: attr=%x\n", entry->attr);	result = 0;out:	smb_unlock_server(server);	return result;}intsmb_proc_getattr(struct inode *dir, const char *name, int len,		 struct smb_dirent *entry){	struct smb_server *server = SMB_SERVER(dir);        int result;	smb_init_dirent(server, entry);  	/* Use trans2 for NT, use core protocol for others (Win95/3.11/...). 	 * We distinguish NT from Win95 by looking at the capabilities, 	 * in the same way as in Samba 1.9.18p2's reply.c. 	 */	if ((server->protocol >= PROTOCOL_LANMAN2)	    && (server->blkmode & (CAP_NT_SMBS | CAP_STATUS32)))		result = smb_proc_getattr_ff(dir, name, len, entry);	else		result = smb_proc_getattr_core(dir, name, len, entry);	smb_finish_dirent(server, entry);	entry->len = len;	memcpy(entry->name, name, len);	/* entry->name is null terminated from smb_init_dirent */	return result;}intsmb_proc_setattr(struct smb_server *server,                 struct inode *i, struct smb_dirent *new_finfo){	char *p;	char *buf;	int result;	smb_lock_server(server);      retry:	buf = server->packet;	p = smb_setup_header(server, SMBsetatr, 8, 0);	WSET(buf, smb_vwv0, new_finfo->attr);	DSET(buf, smb_vwv1, 0);	DSET(buf, smb_vwv3, 0);	DSET(buf, smb_vwv5, 0);	WSET(buf, smb_vwv7, 0);	*p++ = 4;	p = smb_encode_path(server, p,			    SMB_INOP(i)->dir, SMB_INOP(i)->finfo.name,			    SMB_INOP(i)->finfo.len);	smb_setup_bcc(server, p);	if ((result = smb_request_ok(server, SMBsetatr, 0, 0)) < 0)	{		if (smb_retry(server))		{			goto retry;		}	}	smb_unlock_server(server);	return result;}intsmb_proc_dskattr(struct super_block *super, struct smb_dskattr *attr){	int error;	char *p;	struct smb_server *server = &(SMB_SBP(super)->s_server);	smb_lock_server(server);      retry:	smb_setup_header(server, SMBdskattr, 0, 0);	if ((error = smb_request_ok(server, SMBdskattr, 5, 0)) < 0)	{		if (smb_retry(server))		{			goto retry;		}		smb_unlock_server(server);		return error;	}	p = SMB_VWV(server->packet);	p = smb_decode_word(p, &attr->total);	p = smb_decode_word(p, &attr->allocblocks);	p = smb_decode_word(p, &attr->blocksize);	p = smb_decode_word(p, &attr->free);	smb_unlock_server(server);	return 0;}/*****************************************************************************//*                                                                           *//*  Mount/umount operations.                                                 *//*                                                                           *//*****************************************************************************/struct smb_prots{	enum smb_protocol prot;	const char *name;};/* smb_proc_reconnect: We expect the server to be locked, so that you   can call the routine from within smb_retry. The socket must be   created, like after a user-level socket()-call. It may not be   connected. */intsmb_proc_reconnect(struct smb_server *server){	struct smb_prots prots[] =	{		{PROTOCOL_CORE, "PC NETWORK PROGRAM 1.0"},		{PROTOCOL_COREPLUS, "MICROSOFT NETWORKS 1.03"},#ifdef LANMAN1		{PROTOCOL_LANMAN1, "MICROSOFT NETWORKS 3.0"},		{PROTOCOL_LANMAN1, "LANMAN1.0"},#endif#ifdef LANMAN2		{PROTOCOL_LANMAN2, "LM1.2X002"},#endif#ifdef NT1		{PROTOCOL_NT1, "NT LM 0.12"},		{PROTOCOL_NT1, "NT LANMAN 1.0"},#endif		{-1, NULL}};	char dev[] = "A:";	int i, plength;	int max_xmit = 1024;	/* Space needed for first request. */	int given_max_xmit = server->m.max_xmit;	int result;	byte *p;	if ((result = smb_connect(server)) < 0)	{		DPRINTK("smb_proc_reconnect: could not smb_connect\n");		goto fail;	}	/* Here we assume that the connection is valid */	server->state = CONN_VALID;	if (server->packet != NULL)	{		smb_vfree(server->packet);		server->packet = NULL;		server->packet_size = 0;	}	server->packet = smb_vmalloc(max_xmit);	if (server->packet == NULL)	{		printk("smb_proc_connect: No memory! Bailing out.\n");		result = -ENOMEM;		goto fail;	}	server->packet_size = server->max_xmit = max_xmit;	/*	 * Start with an RFC1002 session request packet.	 */	p = server->packet + 4;	p = smb_name_mangle(p, server->m.server_name);	p = smb_name_mangle(p, server->m.client_name);	smb_encode_smb_length(server->packet,			      (void *) p - (void *) (server->packet));	server->packet[0] = 0x81;	/* SESSION REQUEST */	if (smb_catch_keepalive(server) < 0)	{		printk("smb_proc_connect: could not catch_keepalives\n");	}	if ((result = smb_request(server)) < 0)	{		DPRINTK("smb_proc_connect: Failed to send SESSION REQUEST.\n");		smb_dont_catch_keepalive(server);		goto fail;	}	if (server->packet[0] != 0x82)	{		printk("smb_proc_connect: Did not receive positive response "		       "(err = %x)\n",		       server->packet[0]);		smb_dont_catch_keepalive(server);		result = -EIO;		goto fail;	}	DPRINTK("smb_proc_connect: Passed SESSION REQUEST.\n");	/* Now we are ready to send a SMB Negotiate Protocol packet. */	memset(server->packet, 0, SMB_HEADER_LEN);	plength = 0;	for (i = 0; prots[i].name != NULL; i++)	{		plength += strlen(prots[i].name) + 2;	}	smb_setup_header(server, SMBnegprot, 0, plength);	p = SMB_BUF(server->packet);	for (i = 0; prots[i].name != NULL; i++)	{		*p++ = 2;		strcpy(p, prots[i].name);		p += strlen(prots[i].name) + 1;	}	if ((result = smb_request_ok(server, SMBnegprot, 1, -1)) < 0)	{		DPRINTK("smb_proc_connect: Failure requesting SMBnegprot\n");		smb_dont_catch_keepalive(server);		goto fail;	} else	{		DDPRINTK("smb_proc_connect: Request SMBnegprot..");	}	DDPRINTK("Verified!\n");	p = SMB_VWV(server->packet);	p = smb_decode_word(p, (word *) & i);	server->protocol = prots[i].prot;	DPRINTK("smb_proc_connect: Server wants %s protocol.\n",		prots[i].name);	if (server->protocol >= PROTOCOL_LANMAN1)	{		word passlen = strlen(server->m.password);		word userlen = strlen(server->m.username);#ifdef DEBUG_SMB_PASSWORD		DPRINTK("smb_proc_connect: password = %s\n",			server->m.password);#endif					DPRINTK("smb_proc_connect: usernam = %s\n",			server->m.username);		if (server->protocol >= PROTOCOL_NT1)		{			server->max_xmit = DVAL(server->packet, smb_vwv3 + 1);			server->maxmux = WVAL(server->packet, smb_vwv1 + 1);			server->maxvcs = WVAL(server->packet, smb_vwv2 + 1);			server->blkmode = DVAL(server->packet, smb_vwv9 + 1);			server->sesskey = DVAL(server->packet, smb_vwv7 + 1);		} else		{			server->max_xmit = WVAL(server->packet, smb_vwv2);			server->maxmux = WVAL(server->packet, smb_vwv3);			server->maxvcs = WVAL(server->packet, smb_vwv4);			server->blkmode = WVAL(server->packet, smb_vwv5);			server->sesskey = DVAL(server->packet, smb_vwv6);		}		DPRINTK("smb_proc_connect: blkmode (capabilities) = %x\n",			server->blkmode);		if (server->max_xmit < given_max_xmit)		{			/* We do not distinguish between the client			   requests and the server response. */			given_max_xmit = server->max_xmit;		}		if (server->protocol >= PROTOCOL_NT1)		{			char *workgroup = server->m.domain;			char *OS_id = "Unix";			char *client_id = "ksmbfs";			smb_setup_header(server, SMBsesssetupX, 13,					 5 + userlen + passlen +					 strlen(workgroup) + strlen(OS_id) +					 strlen(client_id));			WSET(server->packet, smb_vwv0, 0x00ff);			WSET(server->packet, smb_vwv1, 0);			WSET(server->packet, smb_vwv2, given_max_xmit);			WSET(server->packet, smb_vwv3, 2);			WSET(server->packet, smb_vwv4, server->pid);			DSET(server->packet, smb_vwv5, server->sesskey);			WSET(server->packet, smb_vwv7, passlen + 1);			WSET(server->packet, smb_vwv8, 0);			WSET(server->packet, smb_vwv9, 0);			p = SMB_BUF(server->packet);			strcpy(p, server->m.password);			p += passlen + 1;			strcpy(p, server->m.username);			p += userlen + 1;			strcpy(p, workgroup);			p += strlen(p) + 1;			strcpy(p, OS_id);			p += strlen(p) + 1;			strcpy(p, client_id);		} else		{			smb_setup_header(server, SMBsesssetupX, 10,					 2 + userlen + passlen);			WSET(server->packet, smb_vwv0, 0x00ff);			WSET(server->packet, smb_vwv1, 0);			WSET(server->packet, smb_vwv2, given_max_xmit);			WSET(server->packet, smb_vwv3, 2);			WSET(server->packet, smb_vwv4, server->pid);			DSET(server->packet, smb_vwv5, server->sesskey);			WSET(server->packet, smb_vwv7, passlen + 1);			WSET(server->packet, smb_vwv8, 0);			WSET(server->packet, smb_vwv9, 0);			p = SMB_BUF(server->packet);			strcpy(p, server->m.password);			p += passlen + 1;			strcpy(p, server->m.username);		}		if ((result = smb_request_ok(server, SMBsesssetupX, 3, 0)) < 0)		{			DPRINTK("smb_proc_connect: SMBsessetupX failed\n");			smb_dont_catch_keepalive(server);			goto fail;		}		smb_decode_word(server->packet + 32, &(server->server_uid));	} else	{		server->max_xmit = 0;		server->maxmux = 0;		server->maxvcs = 0;		server->blkmode = 0;		server->sesskey = 0;	}	/* Fine! We have a connection, send a tcon message. */	smb_setup_header(server, SMBtcon, 0,			 6 + strlen(server->m.service) +			 strlen(server->m.password) + strlen(dev));	p = SMB_BUF(server->packet);	p = smb_encode_ascii(p, server->m.service, strlen(server->m.service));	p = smb_encode_ascii(p, server->m.password, strlen(server->m.password));	p = smb_encode_ascii(p, dev, strlen(dev));	if ((result = smb_request_ok(server, SMBtcon, 2, 0)) < 0)	{		DPRINTK("smb_proc_connect: SMBtcon not verified.\n");		smb_dont_catch_keepalive(server);		goto fail;	}	DDPRINTK("OK! Managed to set up SMBtcon!\n");	p = SMB_VWV(server->packet);	if (server->protocol <= PROTOCOL_COREPLUS)	{		word max_xmit;		p = smb_decode_word(p, &max_xmit);		server->max_xmit = max_xmit;		if (server->max_xmit > given_max_xmit)		{			server->max_xmit = given_max_xmit;		}	} else	{		p += 2;	}	p = smb_decode_word(p, &server->tid);	/* Ok, everything is fine. max_xmit does not include */	/* the TCP-SMB header of 4 bytes. */	server->max_xmit += 4;	DPRINTK("max_xmit = %d, tid = %d\n", server->max_xmit, server->tid);	/* Now make a new packet with the correct size. */	smb_vfree(server->packet);	server->packet = NULL;	server->packet = smb_vmalloc(server->max_xmit);	if (server->packet == NULL)	{		printk("smb_proc_connect: No memory left in end of "		       "connection phase :-(\n");		smb_dont_catch_keepalive(server);		goto fail;	}	server->packet_size = server->max_xmit;	DPRINTK("smb_proc_connect: Normal exit\n");	return 0;      fail:	server->state = CONN_INVALID;	return result;}/* smb_proc_reconnect: server->packet is allocated with   server->max_xmit bytes if and only if we return >= 0 */intsmb_proc_connect(struct smb_server *server){	int result;	smb_lock_server(server);	result = smb_proc_reconnect(server);	if ((result < 0) && (server->packet != NULL))	{		smb_vfree(server->packet);		server->packet = NULL;	}	smb_unlock_server(server);	return result;}intsmb_proc_disconnect(struct smb_server *server){	smb_setup_header_exclusive(server, SMBtdis, 0, 0);	return smb_request_ok_unlock(server, SMBtdis, 0, 0);}

⌨️ 快捷键说明

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